summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/attr-ini.lua853
-rw-r--r--tex/context/base/attr-ini.tex163
-rw-r--r--tex/context/base/back-ini.lua75
-rw-r--r--tex/context/base/back-ini.tex896
-rw-r--r--tex/context/base/back-pdf.lua189
-rw-r--r--tex/context/base/back-pdf.tex3226
-rw-r--r--tex/context/base/bibl-bib.lua233
-rw-r--r--tex/context/base/bibl-bib.tex29
-rw-r--r--tex/context/base/bibl-tst.lua21
-rw-r--r--tex/context/base/catc-act.tex61
-rw-r--r--tex/context/base/catc-ctx.tex207
-rw-r--r--tex/context/base/catc-def.tex142
-rw-r--r--tex/context/base/catc-ini.lua28
-rw-r--r--tex/context/base/catc-ini.mkii229
-rw-r--r--tex/context/base/catc-ini.mkiv255
-rw-r--r--tex/context/base/catc-sym.tex (renamed from tex/context/base/syst-chr.tex)111
-rw-r--r--tex/context/base/char-cmp.lua2
-rw-r--r--tex/context/base/char-def.lua1248
-rw-r--r--tex/context/base/char-enc.lua (renamed from tex/context/base/char-syn.lua)23
-rw-r--r--tex/context/base/char-enc.tex18
-rw-r--r--tex/context/base/char-ini.lua619
-rw-r--r--tex/context/base/char-ini.tex40
-rw-r--r--tex/context/base/char-map.lua19
-rw-r--r--tex/context/base/char-utf.lua146
-rw-r--r--tex/context/base/char-utf.tex26
-rw-r--r--tex/context/base/chem-ini.lua74
-rw-r--r--tex/context/base/chem-ini.mkiv42
-rw-r--r--tex/context/base/chem-str-test.tex560
-rw-r--r--tex/context/base/chem-str.lua488
-rw-r--r--tex/context/base/chem-str.mkiv526
-rw-r--r--tex/context/base/colo-ext.mkii (renamed from tex/context/base/colo-ext.tex)2
-rw-r--r--tex/context/base/colo-ext.mkiv57
-rw-r--r--tex/context/base/colo-hex.mkii115
-rw-r--r--tex/context/base/colo-hex.mkiv115
-rw-r--r--tex/context/base/colo-hex.tex120
-rw-r--r--tex/context/base/colo-ini.lua181
-rw-r--r--tex/context/base/colo-ini.mkii922
-rw-r--r--tex/context/base/colo-ini.mkiv983
-rw-r--r--tex/context/base/colo-ini.tex1051
-rw-r--r--tex/context/base/colo-run.tex3
-rw-r--r--tex/context/base/cont-cs.tex10
-rw-r--r--tex/context/base/cont-de.tex10
-rw-r--r--tex/context/base/cont-en.tex8
-rw-r--r--tex/context/base/cont-fil.tex2
-rw-r--r--tex/context/base/cont-fr.tex10
-rw-r--r--tex/context/base/cont-gb.tex10
-rw-r--r--tex/context/base/cont-it.tex10
-rw-r--r--tex/context/base/cont-log.tex71
-rw-r--r--tex/context/base/cont-new.mkiv88
-rw-r--r--tex/context/base/cont-new.tex100
-rw-r--r--tex/context/base/cont-nl.tex10
-rw-r--r--tex/context/base/cont-old.tex2
-rw-r--r--tex/context/base/cont-pe.tex10
-rw-r--r--tex/context/base/cont-ro.tex10
-rw-r--r--tex/context/base/cont-sys.ori9
-rw-r--r--tex/context/base/cont-usr.ori2
-rw-r--r--tex/context/base/context-base.lmx38
-rw-r--r--tex/context/base/context-characters.lmx66
-rw-r--r--tex/context/base/context-debug.lmx66
-rw-r--r--tex/context/base/context-error.lmx46
-rw-r--r--tex/context/base/context-fonttest.lmx47
-rw-r--r--tex/context/base/context-help.lmx88
-rw-r--r--tex/context/base/context-timing.lmx52
-rw-r--r--tex/context/base/context.css15
-rw-r--r--tex/context/base/context.mkii198
-rw-r--r--tex/context/base/context.mkiv422
-rw-r--r--tex/context/base/context.rme85
-rw-r--r--tex/context/base/context.tex15
-rw-r--r--tex/context/base/core-bar.tex2
-rw-r--r--tex/context/base/core-blk.tex130
-rw-r--r--tex/context/base/core-box.tex3
-rw-r--r--tex/context/base/core-buf.lua194
-rw-r--r--tex/context/base/core-buf.mkii326
-rw-r--r--tex/context/base/core-buf.mkiv308
-rw-r--r--tex/context/base/core-buf.tex250
-rw-r--r--tex/context/base/core-con.lua281
-rw-r--r--tex/context/base/core-con.mkii775
-rw-r--r--tex/context/base/core-con.mkiv831
-rw-r--r--tex/context/base/core-con.tex744
-rw-r--r--tex/context/base/core-ctx.lua41
-rw-r--r--tex/context/base/core-ctx.mkii2
-rw-r--r--tex/context/base/core-ctx.mkiv3
-rw-r--r--tex/context/base/core-ctx.tex22
-rw-r--r--tex/context/base/core-dat.tex66
-rw-r--r--tex/context/base/core-def.mkii77
-rw-r--r--tex/context/base/core-def.mkiv74
-rw-r--r--tex/context/base/core-def.tex27
-rw-r--r--tex/context/base/core-des.tex7
-rw-r--r--tex/context/base/core-env.mkii (renamed from tex/context/base/core-new.tex)339
-rw-r--r--tex/context/base/core-env.mkiv472
-rw-r--r--tex/context/base/core-fig.tex4
-rw-r--r--tex/context/base/core-fil.tex56
-rw-r--r--tex/context/base/core-fld.mkii (renamed from tex/context/base/core-fld.tex)4
-rw-r--r--tex/context/base/core-fld.mkiv1079
-rw-r--r--tex/context/base/core-fnt.mkii (renamed from tex/context/base/core-fnt.tex)4
-rw-r--r--tex/context/base/core-fnt.mkiv498
-rw-r--r--tex/context/base/core-gen.tex137
-rw-r--r--tex/context/base/core-grd.tex2
-rw-r--r--tex/context/base/core-inc.lua608
-rw-r--r--tex/context/base/core-inc.mkii95
-rw-r--r--tex/context/base/core-inc.mkiv12
-rw-r--r--tex/context/base/core-inc.tex18
-rw-r--r--tex/context/base/core-ini.tex2
-rw-r--r--tex/context/base/core-ins.tex42
-rw-r--r--tex/context/base/core-int.mkii (renamed from tex/context/base/core-int.tex)144
-rw-r--r--tex/context/base/core-int.mkiv2036
-rw-r--r--tex/context/base/core-itm.tex36
-rw-r--r--tex/context/base/core-job.lua154
-rw-r--r--tex/context/base/core-job.mkii316
-rw-r--r--tex/context/base/core-job.mkiv333
-rw-r--r--tex/context/base/core-job.tex368
-rw-r--r--tex/context/base/core-lme.tex2
-rw-r--r--tex/context/base/core-lnt.tex2
-rw-r--r--tex/context/base/core-lst.tex3
-rw-r--r--tex/context/base/core-mak.tex2
-rw-r--r--tex/context/base/core-mar.tex5
-rw-r--r--tex/context/base/core-mat.tex60
-rw-r--r--tex/context/base/core-mis.mkii (renamed from tex/context/base/core-mis.tex)235
-rw-r--r--tex/context/base/core-mis.mkiv2606
-rw-r--r--tex/context/base/core-nav.mkii (renamed from tex/context/base/core-nav.tex)2
-rw-r--r--tex/context/base/core-nav.mkiv425
-rw-r--r--tex/context/base/core-not.tex8
-rw-r--r--tex/context/base/core-num.tex2
-rw-r--r--tex/context/base/core-obj.lua7
-rw-r--r--tex/context/base/core-obj.mkii309
-rw-r--r--tex/context/base/core-obj.mkiv220
-rw-r--r--tex/context/base/core-obj.tex365
-rw-r--r--tex/context/base/core-par.tex2
-rw-r--r--tex/context/base/core-pgr.tex12
-rw-r--r--tex/context/base/core-pos.lua4
-rw-r--r--tex/context/base/core-pos.mkii759
-rw-r--r--tex/context/base/core-pos.mkiv789
-rw-r--r--tex/context/base/core-pos.tex767
-rw-r--r--tex/context/base/core-ref.lua106
-rw-r--r--tex/context/base/core-ref.mkii90
-rw-r--r--tex/context/base/core-ref.mkiv107
-rw-r--r--tex/context/base/core-ref.tex261
-rw-r--r--tex/context/base/core-reg.lua186
-rw-r--r--tex/context/base/core-reg.mkii33
-rw-r--r--tex/context/base/core-reg.mkiv40
-rw-r--r--tex/context/base/core-reg.tex55
-rw-r--r--tex/context/base/core-rul.lua1
-rw-r--r--tex/context/base/core-rul.mkii3562
-rw-r--r--tex/context/base/core-rul.mkiv3635
-rw-r--r--tex/context/base/core-rul.tex3590
-rw-r--r--tex/context/base/core-sec.mkiv2621
-rw-r--r--tex/context/base/core-sec.tex (renamed from tex/context/base/core-sec.mkii)62
-rw-r--r--tex/context/base/core-snc.tex4
-rw-r--r--tex/context/base/core-spa.lua1979
-rw-r--r--tex/context/base/core-spa.mkii4648
-rw-r--r--tex/context/base/core-spa.mkiv4168
-rw-r--r--tex/context/base/core-spa.tex4637
-rw-r--r--tex/context/base/core-stg.tex4
-rw-r--r--tex/context/base/core-syn.lua127
-rw-r--r--tex/context/base/core-syn.mkii28
-rw-r--r--tex/context/base/core-syn.mkiv34
-rw-r--r--tex/context/base/core-syn.tex42
-rw-r--r--tex/context/base/core-sys.mkii384
-rw-r--r--tex/context/base/core-sys.mkiv373
-rw-r--r--tex/context/base/core-sys.tex401
-rw-r--r--tex/context/base/core-trf.tex28
-rw-r--r--tex/context/base/core-two.lua20
-rw-r--r--tex/context/base/core-two.mkii65
-rw-r--r--tex/context/base/core-two.mkiv77
-rw-r--r--tex/context/base/core-two.tex103
-rw-r--r--tex/context/base/core-uti.lua253
-rw-r--r--tex/context/base/core-uti.mkii305
-rw-r--r--tex/context/base/core-uti.mkiv95
-rw-r--r--tex/context/base/core-uti.tex382
-rw-r--r--tex/context/base/core-var.tex568
-rw-r--r--tex/context/base/core-ver.mkii1124
-rw-r--r--tex/context/base/core-ver.mkiv1084
-rw-r--r--tex/context/base/core-ver.tex1120
-rw-r--r--tex/context/base/core-vis.tex32
-rw-r--r--tex/context/base/data-aux.lua57
-rw-r--r--tex/context/base/data-bin.lua26
-rw-r--r--tex/context/base/data-con.lua122
-rw-r--r--tex/context/base/data-crl.lua58
-rw-r--r--tex/context/base/data-ctx.lua29
-rw-r--r--tex/context/base/data-gen.lua9
-rw-r--r--tex/context/base/data-inp.lua15
-rw-r--r--tex/context/base/data-kps.lua101
-rw-r--r--tex/context/base/data-lst.lua58
-rw-r--r--tex/context/base/data-lua.lua55
-rw-r--r--tex/context/base/data-out.lua10
-rw-r--r--tex/context/base/data-pre.lua90
-rw-r--r--tex/context/base/data-res.lua2029
-rw-r--r--tex/context/base/data-tex.lua220
-rw-r--r--tex/context/base/data-tmf.lua72
-rw-r--r--tex/context/base/data-tmp.lua174
-rw-r--r--tex/context/base/data-tre.lua43
-rw-r--r--tex/context/base/data-use.lua127
-rw-r--r--tex/context/base/data-zip.lua241
-rw-r--r--tex/context/base/enco-cyr.tex2
-rw-r--r--tex/context/base/enco-def.tex6
-rw-r--r--tex/context/base/enco-fpl.tex2
-rw-r--r--tex/context/base/enco-ini.mkii1125
-rw-r--r--tex/context/base/enco-ini.mkiv583
-rw-r--r--tex/context/base/enco-ini.tex1228
-rw-r--r--tex/context/base/enco-mis.tex37
-rw-r--r--tex/context/base/enco-pfr.mkii20
-rw-r--r--tex/context/base/enco-pfr.mkiv22
-rw-r--r--tex/context/base/enco-pfr.tex18
-rw-r--r--tex/context/base/enco-run.tex52
-rw-r--r--tex/context/base/enco-t5.tex4
-rw-r--r--tex/context/base/enco-utf.tex3126
-rw-r--r--tex/context/base/enco-x5.tex34
-rw-r--r--tex/context/base/filt-ini.tex62
-rw-r--r--tex/context/base/font-afm.lua344
-rw-r--r--tex/context/base/font-bfm.tex2
-rw-r--r--tex/context/base/font-chi.tex2
-rw-r--r--tex/context/base/font-chk.lua80
-rw-r--r--tex/context/base/font-cid.lua143
-rw-r--r--tex/context/base/font-col.lua98
-rw-r--r--tex/context/base/font-col.mkiv (renamed from tex/context/base/font-col.tex)4
-rw-r--r--tex/context/base/font-ctx.lua387
-rw-r--r--tex/context/base/font-def.lua624
-rw-r--r--tex/context/base/font-dum.lua113
-rw-r--r--tex/context/base/font-enc.lua16
-rw-r--r--tex/context/base/font-ext.lua304
-rw-r--r--tex/context/base/font-fbk.lua102
-rw-r--r--tex/context/base/font-ini.lua53
-rw-r--r--tex/context/base/font-ini.mkii671
-rw-r--r--tex/context/base/font-ini.mkiv2513
-rw-r--r--tex/context/base/font-jap.tex2
-rw-r--r--tex/context/base/font-log.lua53
-rw-r--r--tex/context/base/font-map.lua32
-rw-r--r--tex/context/base/font-mis.lua91
-rw-r--r--tex/context/base/font-ota.lua320
-rw-r--r--tex/context/base/font-otb.lua364
-rw-r--r--tex/context/base/font-otc.lua238
-rw-r--r--tex/context/base/font-otd.lua78
-rw-r--r--tex/context/base/font-otf.lua5965
-rw-r--r--tex/context/base/font-oti.lua57
-rw-r--r--tex/context/base/font-otn.lua2496
-rw-r--r--tex/context/base/font-otp.lua420
-rw-r--r--tex/context/base/font-ott.lua935
-rw-r--r--tex/context/base/font-pat.lua53
-rw-r--r--tex/context/base/font-run.tex3
-rw-r--r--tex/context/base/font-syn.lua417
-rw-r--r--tex/context/base/font-tfm.lua977
-rw-r--r--tex/context/base/font-tra.mkiv113
-rw-r--r--tex/context/base/font-uni.mkii (renamed from tex/context/base/font-uni.tex)47
-rw-r--r--tex/context/base/font-uni.mkiv26
-rw-r--r--tex/context/base/font-unk.mkii (renamed from tex/context/base/font-unk.tex)4
-rw-r--r--tex/context/base/font-unk.mkiv162
-rw-r--r--tex/context/base/font-vf.lua72
-rw-r--r--tex/context/base/font-xtx.lua115
-rw-r--r--tex/context/base/font-xtx.tex357
-rw-r--r--tex/context/base/hand-ini.mkii91
-rw-r--r--tex/context/base/hand-ini.mkiv2
-rw-r--r--tex/context/base/hand-ini.tex18
-rw-r--r--tex/context/base/java-ini.mkii (renamed from tex/context/base/java-ini.tex)67
-rw-r--r--tex/context/base/java-ini.mkiv688
-rw-r--r--tex/context/base/l-aux.lua128
-rw-r--r--tex/context/base/l-boolean.lua17
-rw-r--r--tex/context/base/l-dimen.lua13
-rw-r--r--tex/context/base/l-dir.lua447
-rw-r--r--tex/context/base/l-file.lua142
-rw-r--r--tex/context/base/l-io.lua211
-rw-r--r--tex/context/base/l-lpeg.lua58
-rw-r--r--tex/context/base/l-math.lua30
-rw-r--r--tex/context/base/l-md5.lua78
-rw-r--r--tex/context/base/l-number.lua27
-rw-r--r--tex/context/base/l-os.lua88
-rw-r--r--tex/context/base/l-set.lua87
-rw-r--r--tex/context/base/l-string.lua270
-rw-r--r--tex/context/base/l-table.lua328
-rw-r--r--tex/context/base/l-unicode.lua79
-rw-r--r--tex/context/base/l-url.lua54
-rw-r--r--tex/context/base/l-utils.lua62
-rw-r--r--tex/context/base/l-xml.lua134
-rw-r--r--tex/context/base/lang-alt.tex5
-rw-r--r--tex/context/base/lang-ana.tex6
-rw-r--r--tex/context/base/lang-ara.tex5
-rw-r--r--tex/context/base/lang-art.tex6
-rw-r--r--tex/context/base/lang-bal.tex6
-rw-r--r--tex/context/base/lang-cel.tex6
-rw-r--r--tex/context/base/lang-chi.tex6
-rw-r--r--tex/context/base/lang-cjk.tex328
-rw-r--r--tex/context/base/lang-ctx.tex37
-rw-r--r--tex/context/base/lang-cyr.tex14
-rw-r--r--tex/context/base/lang-dis.tex8
-rw-r--r--tex/context/base/lang-frq.tex4
-rw-r--r--tex/context/base/lang-ger.tex44
-rw-r--r--tex/context/base/lang-grk.tex9
-rw-r--r--tex/context/base/lang-ind.tex2
-rw-r--r--tex/context/base/lang-ini.lua131
-rw-r--r--tex/context/base/lang-ini.mkii588
-rw-r--r--tex/context/base/lang-ini.mkiv565
-rw-r--r--tex/context/base/lang-ini.tex692
-rw-r--r--tex/context/base/lang-ita.tex57
-rw-r--r--tex/context/base/lang-jap.tex5
-rw-r--r--tex/context/base/lang-lab.mkii (renamed from tex/context/base/lang-lab.tex)55
-rw-r--r--tex/context/base/lang-lab.mkiv266
-rw-r--r--tex/context/base/lang-mis.tex6
-rw-r--r--tex/context/base/lang-sla.tex23
-rw-r--r--tex/context/base/lang-spa.tex2
-rw-r--r--tex/context/base/lang-spe.mkii (renamed from tex/context/base/lang-spe.tex)44
-rw-r--r--tex/context/base/lang-spe.mkiv111
-rw-r--r--tex/context/base/lang-ura.tex6
-rw-r--r--tex/context/base/lang-url.lua10
-rw-r--r--tex/context/base/lang-url.mkii74
-rw-r--r--tex/context/base/lang-url.mkiv50
-rw-r--r--tex/context/base/lang-url.tex70
-rw-r--r--tex/context/base/lang-vn.tex5
-rw-r--r--tex/context/base/luat-bas.tex64
-rw-r--r--tex/context/base/luat-cbk.lua13
-rw-r--r--tex/context/base/luat-cnf.lua114
-rw-r--r--tex/context/base/luat-cod.tex161
-rw-r--r--tex/context/base/luat-crl.lua53
-rw-r--r--tex/context/base/luat-dum.lua60
-rw-r--r--tex/context/base/luat-env.lua304
-rw-r--r--tex/context/base/luat-env.tex172
-rw-r--r--tex/context/base/luat-exe.lua13
-rw-r--r--tex/context/base/luat-fio.lua81
-rw-r--r--tex/context/base/luat-ini.lua129
-rw-r--r--tex/context/base/luat-ini.tex222
-rw-r--r--tex/context/base/luat-inp.lua2300
-rw-r--r--tex/context/base/luat-iop.lua18
-rw-r--r--tex/context/base/luat-kps.lua102
-rw-r--r--tex/context/base/luat-lib.lua174
-rw-r--r--tex/context/base/luat-lib.tex86
-rw-r--r--tex/context/base/luat-log.lua155
-rw-r--r--tex/context/base/luat-lua.lua2
-rw-r--r--tex/context/base/luat-run.lua69
-rw-r--r--tex/context/base/luat-soc.lua11
-rw-r--r--tex/context/base/luat-sta.lua44
-rw-r--r--tex/context/base/luat-sto.lua134
-rw-r--r--tex/context/base/luat-tex.lua588
-rw-r--r--tex/context/base/luat-tmp.lua433
-rw-r--r--tex/context/base/luat-tre.lua45
-rw-r--r--tex/context/base/luat-uni.lua21
-rw-r--r--tex/context/base/luat-uni.tex33
-rw-r--r--tex/context/base/luat-zip.lua249
-rw-r--r--tex/context/base/lxml-ent.lua115
-rw-r--r--tex/context/base/lxml-ini.lua588
-rw-r--r--tex/context/base/lxml-ini.tex71
-rw-r--r--tex/context/base/lxml-mis.lua106
-rw-r--r--tex/context/base/lxml-pth.lua1555
-rw-r--r--tex/context/base/lxml-tab.lua783
-rw-r--r--tex/context/base/m-arabtex.tex2
-rw-r--r--tex/context/base/m-chemic.mkii21
-rw-r--r--tex/context/base/m-chemic.mkiv19
-rw-r--r--tex/context/base/m-chemic.tex10
-rw-r--r--tex/context/base/m-database.tex2
-rw-r--r--tex/context/base/m-educat.tex33
-rw-r--r--tex/context/base/m-gamma.tex230
-rw-r--r--tex/context/base/m-mkii.mkiv21
-rw-r--r--tex/context/base/m-newmat.tex14
-rw-r--r--tex/context/base/m-pictex.tex11
-rw-r--r--tex/context/base/m-subsub.tex47
-rw-r--r--tex/context/base/m-timing.tex197
-rw-r--r--tex/context/base/m-track.tex5
-rw-r--r--tex/context/base/m-translate.tex6
-rw-r--r--tex/context/base/m-visual.tex1
-rw-r--r--tex/context/base/math-ali.mkiv1059
-rw-r--r--tex/context/base/math-ams.tex4
-rw-r--r--tex/context/base/math-arr.mkii391
-rw-r--r--tex/context/base/math-arr.mkiv (renamed from tex/context/base/math-ext.tex)22
-rw-r--r--tex/context/base/math-def.mkiv338
-rw-r--r--tex/context/base/math-del.mkiv63
-rw-r--r--tex/context/base/math-dim.lua310
-rw-r--r--tex/context/base/math-dis.mkiv20
-rw-r--r--tex/context/base/math-ext.lua143
-rw-r--r--tex/context/base/math-for.mkiv73
-rw-r--r--tex/context/base/math-frc.mkii66
-rw-r--r--tex/context/base/math-frc.mkiv209
-rw-r--r--tex/context/base/math-ini.lua637
-rw-r--r--tex/context/base/math-ini.mkii679
-rw-r--r--tex/context/base/math-ini.mkiv544
-rw-r--r--tex/context/base/math-ini.tex688
-rw-r--r--tex/context/base/math-inl.mkiv357
-rw-r--r--tex/context/base/math-int.mkiv87
-rw-r--r--tex/context/base/math-lbr.tex8
-rw-r--r--tex/context/base/math-map.lua365
-rw-r--r--tex/context/base/math-mis.tex49
-rw-r--r--tex/context/base/math-noa.lua336
-rw-r--r--tex/context/base/math-pln.mkii (renamed from tex/context/base/math-pln.tex)155
-rw-r--r--tex/context/base/math-pln.mkiv298
-rw-r--r--tex/context/base/math-run.mkii (renamed from tex/context/base/math-run.tex)2
-rw-r--r--tex/context/base/math-scr.mkiv215
-rw-r--r--tex/context/base/math-tex.tex23
-rw-r--r--tex/context/base/math-tim.tex106
-rw-r--r--tex/context/base/math-vfu.lua1534
-rw-r--r--tex/context/base/meta-ini.mkii91
-rw-r--r--tex/context/base/meta-ini.mkiv431
-rw-r--r--tex/context/base/meta-pdf.lua737
-rw-r--r--tex/context/base/meta-pdf.mkii936
-rw-r--r--tex/context/base/meta-pdf.mkiv833
-rw-r--r--tex/context/base/meta-pdf.tex1020
-rw-r--r--tex/context/base/meta-pdh.lua630
-rw-r--r--tex/context/base/meta-tex.mkii2
-rw-r--r--tex/context/base/metatex.tex145
-rw-r--r--tex/context/base/mlib-ctx.lua16
-rw-r--r--tex/context/base/mlib-pdf.lua209
-rw-r--r--tex/context/base/mlib-pdf.tex6
-rw-r--r--tex/context/base/mlib-pps.lua177
-rw-r--r--tex/context/base/mlib-pps.tex16
-rw-r--r--tex/context/base/mlib-run.lua161
-rw-r--r--tex/context/base/mtx-context-arrange.tex105
-rw-r--r--tex/context/base/mtx-context-combine.tex146
-rw-r--r--tex/context/base/mtx-context-ideas.tex54
-rw-r--r--tex/context/base/mtx-context-listing.tex76
-rw-r--r--tex/context/base/mtx-context-timing.tex46
-rw-r--r--tex/context/base/mult-chk.lua66
-rw-r--r--tex/context/base/mult-chk.mkii26
-rw-r--r--tex/context/base/mult-chk.mkiv103
-rw-r--r--tex/context/base/mult-de.tex57
-rw-r--r--tex/context/base/mult-def.lua270
-rw-r--r--tex/context/base/mult-def.tex10
-rw-r--r--tex/context/base/mult-en.tex57
-rw-r--r--tex/context/base/mult-fr.tex57
-rw-r--r--tex/context/base/mult-his.tex19
-rw-r--r--tex/context/base/mult-ini.lua31
-rw-r--r--tex/context/base/mult-ini.mkii15
-rw-r--r--tex/context/base/mult-ini.mkiv34
-rw-r--r--tex/context/base/mult-it.tex57
-rw-r--r--tex/context/base/mult-mcs.tex198
-rw-r--r--tex/context/base/mult-mde.tex198
-rw-r--r--tex/context/base/mult-men.tex198
-rw-r--r--tex/context/base/mult-mes.lua2005
-rw-r--r--tex/context/base/mult-mfr.tex198
-rw-r--r--tex/context/base/mult-mit.tex198
-rw-r--r--tex/context/base/mult-mnl.tex198
-rw-r--r--tex/context/base/mult-mno.tex198
-rw-r--r--tex/context/base/mult-mpe.tex198
-rw-r--r--tex/context/base/mult-mro.tex198
-rw-r--r--tex/context/base/mult-nl.tex57
-rw-r--r--tex/context/base/mult-ro.tex57
-rw-r--r--tex/context/base/mult-sys.tex116
-rw-r--r--tex/context/base/node-dum.lua24
-rw-r--r--tex/context/base/node-ext.lua30
-rw-r--r--tex/context/base/node-fin.lua363
-rw-r--r--tex/context/base/node-fin.tex78
-rw-r--r--tex/context/base/node-fnt.lua206
-rw-r--r--tex/context/base/node-ini.lua1254
-rw-r--r--tex/context/base/node-ini.tex59
-rw-r--r--tex/context/base/node-inj.lua608
-rw-r--r--tex/context/base/node-par.lua2
-rw-r--r--tex/context/base/node-par.tex6
-rw-r--r--tex/context/base/node-pro.lua155
-rw-r--r--tex/context/base/node-res.lua110
-rw-r--r--tex/context/base/node-seq.lua47
-rw-r--r--tex/context/base/node-ser.lua274
-rw-r--r--tex/context/base/node-shp.lua66
-rw-r--r--tex/context/base/node-tex.lua54
-rw-r--r--tex/context/base/node-tra.lua399
-rw-r--r--tex/context/base/node-tsk.lua113
-rw-r--r--tex/context/base/node-tst.lua108
-rw-r--r--tex/context/base/norm-alo.tex36
-rw-r--r--tex/context/base/norm-ctx.tex16
-rw-r--r--tex/context/base/norm-etx.tex79
-rw-r--r--tex/context/base/norm-ltx.tex177
-rw-r--r--tex/context/base/norm-ptx.tex130
-rw-r--r--tex/context/base/norm-tex.tex351
-rw-r--r--tex/context/base/norm-xtx.tex (renamed from tex/context/base/sort-def.mkiv)14
-rw-r--r--tex/context/base/page-app.tex4
-rw-r--r--tex/context/base/page-bck.mkii (renamed from tex/context/base/page-bck.tex)46
-rw-r--r--tex/context/base/page-bck.mkiv521
-rw-r--r--tex/context/base/page-flt.tex460
-rw-r--r--tex/context/base/page-flw.tex4
-rw-r--r--tex/context/base/page-imp.tex29
-rw-r--r--tex/context/base/page-ini.mkii (renamed from tex/context/base/page-ini.tex)553
-rw-r--r--tex/context/base/page-ini.mkiv1549
-rw-r--r--tex/context/base/page-lay.tex5
-rw-r--r--tex/context/base/page-lin.lua299
-rw-r--r--tex/context/base/page-lin.mkii2
-rw-r--r--tex/context/base/page-lin.mkiv16
-rw-r--r--tex/context/base/page-log.tex34
-rw-r--r--tex/context/base/page-lyr.tex8
-rw-r--r--tex/context/base/page-mak.tex9
-rw-r--r--tex/context/base/page-mar.tex10
-rw-r--r--tex/context/base/page-mis.tex268
-rw-r--r--tex/context/base/page-mul.tex8
-rw-r--r--tex/context/base/page-not.tex2
-rw-r--r--tex/context/base/page-num.tex15
-rw-r--r--tex/context/base/page-one.mkii (renamed from tex/context/base/page-one.tex)4
-rw-r--r--tex/context/base/page-one.mkiv662
-rw-r--r--tex/context/base/page-par.tex4
-rw-r--r--tex/context/base/page-plg.tex4
-rw-r--r--tex/context/base/page-run.tex2
-rw-r--r--tex/context/base/page-set.tex24
-rw-r--r--tex/context/base/page-sid.tex4
-rw-r--r--tex/context/base/page-spr.tex2
-rw-r--r--tex/context/base/page-str.tex6
-rw-r--r--tex/context/base/page-txt.mkii (renamed from tex/context/base/page-txt.tex)6
-rw-r--r--tex/context/base/page-txt.mkiv808
-rw-r--r--tex/context/base/ppchtex.mkii (renamed from tex/context/base/ppchtex.tex)41
-rw-r--r--tex/context/base/ppchtex.mkiv3359
-rw-r--r--tex/context/base/prop-ini.mkii (renamed from tex/context/base/prop-ini.tex)23
-rw-r--r--tex/context/base/prop-ini.mkiv150
-rw-r--r--tex/context/base/prop-lay.mkii99
-rw-r--r--tex/context/base/prop-lay.mkiv109
-rw-r--r--tex/context/base/prop-lay.tex105
-rw-r--r--tex/context/base/prop-mis.mkii34
-rw-r--r--tex/context/base/prop-mis.mkiv34
-rw-r--r--tex/context/base/prop-mis.tex53
-rw-r--r--tex/context/base/prop-run.tex39
-rw-r--r--tex/context/base/regi-ini.lua88
-rw-r--r--tex/context/base/regi-ini.mkii167
-rw-r--r--tex/context/base/regi-ini.mkiv54
-rw-r--r--tex/context/base/regi-ini.tex182
-rw-r--r--tex/context/base/regi-syn.tex2
-rw-r--r--tex/context/base/regi-utf.tex12
-rw-r--r--tex/context/base/s-fnt-01.tex4
-rw-r--r--tex/context/base/s-fnt-10.tex100
-rw-r--r--tex/context/base/s-fnt-11.tex61
-rw-r--r--tex/context/base/s-fnt-20.tex140
-rw-r--r--tex/context/base/s-fnt-21.tex46
-rw-r--r--tex/context/base/s-fnt-23.tex272
-rw-r--r--tex/context/base/s-fnt-24.tex83
-rw-r--r--tex/context/base/s-fnt-25.tex162
-rw-r--r--tex/context/base/s-fnt-30.tex42
-rw-r--r--tex/context/base/s-pre-60.tex46
-rw-r--r--tex/context/base/s-pre-61.tex14
-rw-r--r--tex/context/base/s-pre-62.tex20
-rw-r--r--tex/context/base/s-pre-66.tex133
-rw-r--r--tex/context/base/s-pre-71.tex8
-rw-r--r--tex/context/base/s-reg-01.tex50
-rw-r--r--tex/context/base/scrp-cjk.lua576
-rw-r--r--tex/context/base/scrp-ini.lua386
-rw-r--r--tex/context/base/scrp-ini.tex91
-rw-r--r--tex/context/base/sort-def.mkii450
-rw-r--r--tex/context/base/sort-def.tex432
-rw-r--r--tex/context/base/sort-ini.lua135
-rw-r--r--tex/context/base/sort-ini.mkii16
-rw-r--r--tex/context/base/sort-ini.mkiv8
-rw-r--r--tex/context/base/sort-ini.tex32
-rw-r--r--tex/context/base/sort-lan.lua19
-rw-r--r--tex/context/base/sort-lan.mkii203
-rw-r--r--tex/context/base/sort-lan.mkiv16
-rw-r--r--tex/context/base/sort-lan.tex189
-rw-r--r--tex/context/base/spec-def.mkii20
-rw-r--r--tex/context/base/spec-def.mkiv23
-rw-r--r--tex/context/base/spec-def.tex8
-rw-r--r--tex/context/base/spec-dpx.tex4
-rw-r--r--tex/context/base/spec-fdf.mkii146
-rw-r--r--tex/context/base/spec-fdf.mkiv31
-rw-r--r--tex/context/base/spec-fdf.tex205
-rw-r--r--tex/context/base/spec-ini.tex154
-rw-r--r--tex/context/base/spec-mis.tex26
-rw-r--r--tex/context/base/spec-pdf.lua67
-rw-r--r--tex/context/base/spec-tpd.mkii18
-rw-r--r--tex/context/base/spec-tpd.mkiv37
-rw-r--r--tex/context/base/spec-tpd.tex40
-rw-r--r--tex/context/base/spec-var.tex2
-rw-r--r--tex/context/base/strc-bkm.lua133
-rw-r--r--tex/context/base/strc-bkm.tex90
-rw-r--r--tex/context/base/strc-blk.lua (renamed from tex/context/base/core-blk.lua)56
-rw-r--r--tex/context/base/strc-blk.tex (renamed from tex/context/base/core-blk.mkiv)17
-rw-r--r--tex/context/base/strc-def.tex302
-rw-r--r--tex/context/base/strc-des.lua9
-rw-r--r--tex/context/base/strc-des.tex1018
-rw-r--r--tex/context/base/strc-doc.lua569
-rw-r--r--tex/context/base/strc-doc.tex166
-rw-r--r--tex/context/base/strc-flt.lua9
-rw-r--r--tex/context/base/strc-flt.tex2173
-rw-r--r--tex/context/base/strc-ini.lua276
-rw-r--r--tex/context/base/strc-ini.tex88
-rw-r--r--tex/context/base/strc-itm.lua24
-rw-r--r--tex/context/base/strc-itm.tex1195
-rw-r--r--tex/context/base/strc-lst.lua392
-rw-r--r--tex/context/base/strc-lst.tex944
-rw-r--r--tex/context/base/strc-mar.lua18
-rw-r--r--tex/context/base/strc-mar.tex493
-rw-r--r--tex/context/base/strc-mat.lua51
-rw-r--r--tex/context/base/strc-mat.tex933
-rw-r--r--tex/context/base/strc-not.lua248
-rw-r--r--tex/context/base/strc-not.tex1154
-rw-r--r--tex/context/base/strc-num.lua457
-rw-r--r--tex/context/base/strc-num.tex440
-rw-r--r--tex/context/base/strc-pag.lua206
-rw-r--r--tex/context/base/strc-pag.tex506
-rw-r--r--tex/context/base/strc-prc.lua9
-rw-r--r--tex/context/base/strc-prc.tex84
-rw-r--r--tex/context/base/strc-ref.lua875
-rw-r--r--tex/context/base/strc-ref.tex1905
-rw-r--r--tex/context/base/strc-reg.lua578
-rw-r--r--tex/context/base/strc-reg.tex907
-rw-r--r--tex/context/base/strc-ren.tex467
-rw-r--r--tex/context/base/strc-sbe.tex137
-rw-r--r--tex/context/base/strc-sec.tex667
-rw-r--r--tex/context/base/strc-syn.lua185
-rw-r--r--tex/context/base/strc-syn.tex392
-rw-r--r--tex/context/base/strc-xml.tex87
-rw-r--r--tex/context/base/supp-box.tex357
-rw-r--r--tex/context/base/supp-dir.mkii41
-rw-r--r--tex/context/base/supp-dir.mkiv21
-rw-r--r--tex/context/base/supp-dir.tex70
-rw-r--r--tex/context/base/supp-eps.tex2
-rw-r--r--tex/context/base/supp-fil.lua49
-rw-r--r--tex/context/base/supp-fil.mkii621
-rw-r--r--tex/context/base/supp-fil.mkiv616
-rw-r--r--tex/context/base/supp-fil.tex655
-rw-r--r--tex/context/base/supp-fun.tex10
-rw-r--r--tex/context/base/supp-ini.tex18
-rw-r--r--tex/context/base/supp-lan.tex4
-rw-r--r--tex/context/base/supp-mat.tex13
-rw-r--r--tex/context/base/supp-mis.tex3
-rw-r--r--tex/context/base/supp-mpe.tex2
-rw-r--r--tex/context/base/supp-mps.tex24
-rw-r--r--tex/context/base/supp-mrk.tex27
-rw-r--r--tex/context/base/supp-num.tex31
-rw-r--r--tex/context/base/supp-pat.tex6
-rw-r--r--tex/context/base/supp-pdf.tex2
-rw-r--r--tex/context/base/supp-ran.lua46
-rw-r--r--tex/context/base/supp-ran.mkii (renamed from tex/context/base/supp-ran.tex)76
-rw-r--r--tex/context/base/supp-ran.mkiv30
-rw-r--r--tex/context/base/supp-spe.tex94
-rw-r--r--tex/context/base/supp-tpi.tex6
-rw-r--r--tex/context/base/supp-vis.tex48
-rw-r--r--tex/context/base/symb-ini.tex42
-rw-r--r--tex/context/base/symb-jmn.tex1
-rw-r--r--tex/context/base/symb-mis.tex7
-rw-r--r--tex/context/base/syst-aux.tex6841
-rw-r--r--tex/context/base/syst-cat.mkii61
-rw-r--r--tex/context/base/syst-cat.mkiv124
-rw-r--r--tex/context/base/syst-cat.tex517
-rw-r--r--tex/context/base/syst-con.lua28
-rw-r--r--tex/context/base/syst-con.mkii109
-rw-r--r--tex/context/base/syst-con.mkiv132
-rw-r--r--tex/context/base/syst-con.tex144
-rw-r--r--tex/context/base/syst-etx.tex298
-rw-r--r--tex/context/base/syst-ext.tex165
-rw-r--r--tex/context/base/syst-fnt.mkii46
-rw-r--r--tex/context/base/syst-fnt.mkiv46
-rw-r--r--tex/context/base/syst-fnt.tex43
-rw-r--r--tex/context/base/syst-gen.tex358
-rw-r--r--tex/context/base/syst-ini.tex879
-rw-r--r--tex/context/base/syst-lua.lua91
-rw-r--r--tex/context/base/syst-lua.tex37
-rw-r--r--tex/context/base/syst-mtx.tex80
-rw-r--r--tex/context/base/syst-new.tex21
-rw-r--r--tex/context/base/syst-omg.tex79
-rw-r--r--tex/context/base/syst-pdt.tex50
-rw-r--r--tex/context/base/syst-pln.tex510
-rw-r--r--tex/context/base/syst-prm.tex227
-rw-r--r--tex/context/base/syst-rtp.tex22
-rw-r--r--tex/context/base/syst-str.mkii7
-rw-r--r--tex/context/base/syst-str.mkiv9
-rw-r--r--tex/context/base/syst-str.tex40
-rw-r--r--tex/context/base/syst-var.tex18
-rw-r--r--tex/context/base/syst-xtx.tex36
-rw-r--r--tex/context/base/tabl-ltb.tex (renamed from tex/context/base/core-ltb.tex)4
-rw-r--r--tex/context/base/tabl-ntb.mkii (renamed from tex/context/base/core-ntb.tex)47
-rw-r--r--tex/context/base/tabl-ntb.mkiv1571
-rw-r--r--tex/context/base/tabl-nte.tex107
-rw-r--r--tex/context/base/tabl-pln.tex91
-rw-r--r--tex/context/base/tabl-tab.tex (renamed from tex/context/base/core-tab.tex)44
-rw-r--r--tex/context/base/tabl-tbl.tex (renamed from tex/context/base/core-tbl.tex)59
-rw-r--r--tex/context/base/tabl-tsp.tex (renamed from tex/context/base/core-tsp.tex)8
-rw-r--r--tex/context/base/task-ini.lua45
-rw-r--r--tex/context/base/task-ini.tex22
-rw-r--r--tex/context/base/thrd-ran.tex4
-rw-r--r--tex/context/base/thrd-tab.tex50
-rw-r--r--tex/context/base/thrd-trg.tex9
-rw-r--r--tex/context/base/toks-ini.lua43
-rw-r--r--tex/context/base/toks-ini.tex6
-rw-r--r--tex/context/base/trac-deb.lua (renamed from tex/context/base/luat-deb.lua)70
-rw-r--r--tex/context/base/trac-deb.tex (renamed from tex/context/base/luat-deb.tex)24
-rw-r--r--tex/context/base/trac-inf.lua149
-rw-r--r--tex/context/base/trac-lmx.lua (renamed from tex/context/base/luat-lmx.lua)79
-rw-r--r--tex/context/base/trac-lmx.tex (renamed from tex/context/base/luat-lmx.tex)10
-rw-r--r--tex/context/base/trac-log.lua285
-rw-r--r--tex/context/base/trac-tim.lua163
-rw-r--r--tex/context/base/trac-tra.lua (renamed from tex/context/base/luat-tra.lua)98
-rw-r--r--tex/context/base/type-cow.tex4
-rw-r--r--tex/context/base/type-gyr.tex252
-rw-r--r--tex/context/base/type-ini.mkii (renamed from tex/context/base/type-ini.tex)170
-rw-r--r--tex/context/base/type-ini.mkiv705
-rw-r--r--tex/context/base/type-mac.mkii220
-rw-r--r--tex/context/base/type-mac.mkiv220
-rw-r--r--tex/context/base/type-mac.tex434
-rw-r--r--tex/context/base/type-map.tex48
-rw-r--r--tex/context/base/type-one.tex494
-rw-r--r--tex/context/base/type-otf.mkii535
-rw-r--r--tex/context/base/type-otf.mkiv628
-rw-r--r--tex/context/base/type-otf.tex739
-rw-r--r--tex/context/base/type-siz.mkii583
-rw-r--r--tex/context/base/type-siz.mkiv375
-rw-r--r--tex/context/base/type-siz.tex688
-rw-r--r--tex/context/base/type-syn.tex1
-rw-r--r--tex/context/base/type-tmf.tex103
-rw-r--r--tex/context/base/type-win.tex120
-rw-r--r--tex/context/base/type-xtx.tex2
-rw-r--r--tex/context/base/typo-brk.lua186
-rw-r--r--tex/context/base/typo-brk.tex77
-rw-r--r--tex/context/base/typo-cap.lua203
-rw-r--r--tex/context/base/typo-cap.tex214
-rw-r--r--tex/context/base/typo-ini.tex2
-rw-r--r--tex/context/base/typo-krn.lua218
-rw-r--r--tex/context/base/typo-krn.tex59
-rw-r--r--tex/context/base/typo-mir.lua409
-rw-r--r--tex/context/base/typo-mir.tex144
-rw-r--r--tex/context/base/typo-spa.lua149
-rw-r--r--tex/context/base/typo-spa.tex69
-rw-r--r--tex/context/base/unic-035.tex32
-rw-r--r--tex/context/base/unic-exp.tex4
-rw-r--r--tex/context/base/unic-ini.mkii10
-rw-r--r--tex/context/base/unic-ini.mkiv19
-rw-r--r--tex/context/base/verb-c.tex2
-rw-r--r--tex/context/base/verb-eif.tex24
-rw-r--r--tex/context/base/verb-ini.tex2
-rw-r--r--tex/context/base/verb-js.tex18
-rw-r--r--tex/context/base/verb-jv.tex50
-rw-r--r--tex/context/base/verb-lua.lua10
-rw-r--r--tex/context/base/verb-mp.lua6
-rw-r--r--tex/context/base/verb-mp.tex2
-rw-r--r--tex/context/base/verb-pas.tex6
-rw-r--r--tex/context/base/verb-pl.tex58
-rw-r--r--tex/context/base/verb-sql.tex2
-rw-r--r--tex/context/base/verb-tex.lua6
-rw-r--r--tex/context/base/verb-tex.tex2
-rw-r--r--tex/context/base/verb-xml.tex2
-rw-r--r--tex/context/base/x-calcmath.lua191
-rw-r--r--tex/context/base/x-cals.mkiv15
-rw-r--r--tex/context/base/x-chemml.mkiv2
-rw-r--r--tex/context/base/x-ct.mkiv2
-rw-r--r--tex/context/base/x-fo.tex8
-rw-r--r--tex/context/base/x-mathml.lua77
-rw-r--r--tex/context/base/x-mathml.mkiv88
-rw-r--r--tex/context/base/x-newcml.tex8
-rw-r--r--tex/context/base/x-newmme.tex4
-rw-r--r--tex/context/base/x-newmml.mkii23
-rw-r--r--tex/context/base/x-newmml.tex2
-rw-r--r--tex/context/base/x-newmmo.tex2
-rw-r--r--tex/context/base/x-newpml.tex2
-rw-r--r--tex/context/base/x-set-02.tex11
-rw-r--r--tex/context/base/x-set-11.mkii2
-rw-r--r--tex/context/base/x-set-11.mkiv2
-rw-r--r--tex/context/base/x-set-11.tex2
-rw-r--r--tex/context/base/xetx-chr.tex1167
-rw-r--r--tex/context/base/xetx-cls.tex378
-rw-r--r--tex/context/base/xetx-ini.tex132
-rw-r--r--tex/context/base/xetx-utf.tex1989
-rw-r--r--tex/context/base/xtag-cml.tex2
-rw-r--r--tex/context/base/xtag-ent.tex2
-rw-r--r--tex/context/base/xtag-exp.tex6
-rw-r--r--tex/context/base/xtag-ext.tex4
-rw-r--r--tex/context/base/xtag-hyp.tex6
-rw-r--r--tex/context/base/xtag-ini.mkii6
-rw-r--r--tex/context/base/xtag-ini.mkiv2
-rw-r--r--tex/context/base/xtag-ini.tex24
-rw-r--r--tex/context/base/xtag-map.tex4
-rw-r--r--tex/context/base/xtag-mmc.tex8
-rw-r--r--tex/context/base/xtag-mml.tex8
-rw-r--r--tex/context/base/xtag-mmp.tex31
-rw-r--r--tex/context/base/xtag-pml.tex3
-rw-r--r--tex/context/base/xtag-pmu.tex4
-rw-r--r--tex/context/base/xtag-pre.tex4
-rw-r--r--tex/context/base/xtag-prs.tex2
-rw-r--r--tex/context/base/xtag-raw.tex6
-rw-r--r--tex/context/base/xtag-rng.tex14
-rw-r--r--tex/context/base/xtag-run.tex4
-rw-r--r--tex/context/base/xtag-stk.tex4
-rw-r--r--tex/context/base/xtag-utf.tex6
-rw-r--r--tex/context/bib/bibl-apa-fr.tex2
-rw-r--r--tex/context/bib/bibl-apa.tex6
-rw-r--r--tex/context/bib/t-bib.mkii5
-rw-r--r--tex/context/bib/t-bib.mkiv64
-rw-r--r--tex/context/bib/t-bib.tex74
-rw-r--r--tex/context/config/cont-usr.tex2
-rw-r--r--tex/context/interface/cont-cs.xml32
-rw-r--r--tex/context/interface/cont-cz.xml10033
-rw-r--r--tex/context/interface/cont-de.xml32
-rw-r--r--tex/context/interface/cont-en.xml32
-rw-r--r--tex/context/interface/cont-fr.xml32
-rw-r--r--tex/context/interface/cont-it.xml32
-rw-r--r--tex/context/interface/cont-nl.xml32
-rw-r--r--tex/context/interface/cont-pe.xml32
-rw-r--r--tex/context/interface/cont-ro.xml32
-rw-r--r--tex/context/interface/keys-cs.xml57
-rw-r--r--tex/context/interface/keys-de.xml57
-rw-r--r--tex/context/interface/keys-en.xml57
-rw-r--r--tex/context/interface/keys-fr.xml57
-rw-r--r--tex/context/interface/keys-it.xml57
-rw-r--r--tex/context/interface/keys-nl.xml57
-rw-r--r--tex/context/interface/keys-pe.xml57
-rw-r--r--tex/context/interface/keys-ro.xml57
-rw-r--r--tex/context/interface/t-bib.xml3
-rw-r--r--tex/context/patterns/lang-de.hyp4
-rw-r--r--tex/context/patterns/lang-de.pat5446
-rw-r--r--tex/context/patterns/lang-de.rme8
-rw-r--r--tex/context/patterns/lang-deo.hyp4
-rw-r--r--tex/context/patterns/lang-deo.pat5446
-rw-r--r--tex/context/patterns/lang-deo.rme8
-rw-r--r--tex/context/patterns/lang-uk.hyp8
-rw-r--r--tex/context/patterns/lang-uk.pat1905
-rw-r--r--tex/context/patterns/lang-uk.rme70
-rw-r--r--tex/context/test/context-test.tex27
-rw-r--r--tex/context/user/cont-sys.rme9
-rw-r--r--tex/generic/context/luatex-basics.tex21
-rw-r--r--tex/generic/context/luatex-fonts-merged.lua11070
-rw-r--r--tex/generic/context/luatex-fonts.lua139
-rw-r--r--tex/generic/context/luatex-fonts.tex139
-rw-r--r--tex/generic/context/luatex-mplib.lua469
-rw-r--r--tex/generic/context/luatex-mplib.tex118
-rw-r--r--tex/generic/context/luatex-plain.tex25
-rw-r--r--tex/generic/context/luatex-test.tex47
-rw-r--r--tex/generic/context/ppchtex.noc4
801 files changed, 161753 insertions, 74798 deletions
diff --git a/tex/context/base/attr-ini.lua b/tex/context/base/attr-ini.lua
index 204cabce1..3b2ed7791 100644
--- a/tex/context/base/attr-ini.lua
+++ b/tex/context/base/attr-ini.lua
@@ -6,146 +6,23 @@ if not modules then modules = { } end modules ['attr-ini'] = {
license = "see context related readme files"
}
--- todo: document this
-
--- nb: attributes: color etc is much slower than normal (marks + literals) but ...
--- nb. too many "0 g"s
-
---
--- nodes
---
-
-nodes = nodes or { }
-
-local format, concat, texsprint = string.format, table.concat, tex.sprint
-
--- This is not the most ideal place, but it will do. Maybe we need to move
--- attributes to node-att.lua.
-
-do
-
- -- just for testing
-
- local reserved = { }
-
- function nodes.register(n)
- reserved[#reserved+1] = n
- end
-
- function nodes.cleanup_reserved(nofboxes) -- todo
- local nr, free = #reserved, node.free
- for i=1,nr do
- free(reserved[i])
- end
- local nl, tb, flush = 0, tex.box, node.flush_list
- if nofboxes then
- for i=1,nofboxes do
- local l = tb[i]
- if l then
- free(tb[i])
- nl = nl + 1
- end
- end
- end
- reserved = { }
- return nr, nl, nofboxes
- end
-
-end
+-- this module is being reconstructed
-do
-
- local pdfliteral = node.new("whatsit",8) pdfliteral.next, pdfliteral.prev = nil, nil pdfliteral.mode = 1
- local disc = node.new("disc") disc.next, disc.prev = nil, nil
- local kern = node.new("kern",1) kern.next, kern.prev = nil, nil
- local penalty = node.new("penalty") penalty.next, penalty.prev = nil, nil
- local glue = node.new("glue") glue.next, glue.prev = nil, nil
- local glue_spec = node.new("glue_spec")
- local glyph = node.new("glyph",0) glyph.next, glyph.prev = nil, nil
- local textdir = node.new("whatsit",7) textdir.next, textdir.prev = nil, nil
-
- nodes.register(pdfliteral)
- nodes.register(disc)
- nodes.register(kern)
- nodes.register(penalty)
- nodes.register(glue)
- nodes.register(glue_spec)
- nodes.register(glyph)
- nodes.register(textdir)
-
- local copy = node.copy
-
- function nodes.glyph(fnt,chr)
- local n = copy(glyph)
- if fnt then n.font = fnt end
- if chr then n.char = chr end
- return n
- end
- function nodes.penalty(p)
- local n = copy(penalty)
- n.penalty = p
- return n
- end
- function nodes.kern(k)
- local n = copy(kern)
- n.kern = k
- return n
- end
- function nodes.glue(width,stretch,shrink)
- local n = copy(glue)
- local s = copy(glue_spec)
- s.width, s.stretch, s.shrink = width, stretch, shrink
- n.spec = s
- return n
- end
- function nodes.glue_spec(width,stretch,shrink)
- local s = copy(glue_spec)
- s.width, s.stretch, s.shrink = width, stretch, shrink
- return s
- end
- function nodes.disc()
- return copy(disc)
- end
- function nodes.pdfliteral(str)
- local t = copy(pdfliteral)
- t.data = str
- return t
- end
- function nodes.textdir(dir)
- local t = copy(textdir)
- t.dir = dir
- return t
- end
-
-end
-
-function tex.node_mem_status()
- -- todo: lpeg
- local s = status.node_mem_usage
- local t = { }
- for n, tag in s:gmatch("(%d+) ([a-z_]+)") do
- t[tag] = n
- end
- return t
-end
-
---
--- attributes
---
+local type = type
+local format, gmatch = string.format, string.gmatch
+local concat = table.concat
+local texsprint = tex.sprint
-attributes = attributes or { }
+local ctxcatcodes = tex.ctxcatcodes
-attributes.names = attributes.names or { }
-attributes.numbers = attributes.numbers or { }
-attributes.list = attributes.list or { }
+-- todo: document this
-input.storage.register(false, "attributes/names", attributes.names, "attributes.names")
-input.storage.register(false, "attributes/numbers", attributes.numbers, "attributes.numbers")
-input.storage.register(false, "attributes/list", attributes.list, "attributes.list")
+-- nb: attributes: color etc is much slower than normal (marks + literals) but ...
+-- nb. too many "0 g"s
-function attributes.define(name,number)
- attributes.numbers[name], attributes.names[number], attributes.list[number] = number, name, { }
-end
+nodes = nodes or { }
+states = states or { }
+shipouts = shipouts or { }
-- We can distinguish between rules and glyphs but it's not worth the trouble. A
-- first implementation did that and while it saves a bit for glyphs and rules, it
@@ -156,342 +33,6 @@ end
-- i will do the resource stuff later, when we have an interface to pdf (ok, i can
-- fake it with tokens but it will take some coding
-function totokens(str)
- local t = { }
---~ for c in string.bytes(str) do
- for c in str:bytes() do
- t[#t+1] = { 12, c }
- end
- return t
-end
-
--- temp hack, will be proper driver stuff
-
-backends = backends or { }
-backends.pdf = backends.pdf or { }
-backend = backend or backends.pdf
-
-do
-
- local pdfliteral, register = nodes.pdfliteral, nodes.register
-
- function backends.pdf.literal(str)
- local t = pdfliteral(str)
- register(t)
- return t
- end
-
-end
-
--- shipouts
-
-shipouts = shipouts or { }
-
-do
-
- local pairs = pairs -- in theory faster
-
- local hlist, vlist = node.id('hlist'), node.id('vlist')
-
- local has_attribute = node.has_attribute
-
- nodes.trigger = nodes.trigger or false
- nodes.triggering = nodes.triggering or false
-
- -- we used to do the main processor loop here and call processor for each node
- -- but eventually this was too much a slow down (1 sec on 23 for 120 pages mk)
- -- so that we moved looping to the processor itself; this may lead to a bit of
- -- duplicate code once that we have more state handlers
-
- local starttiming, stoptiming = input.starttiming, input.stoptiming
- local trigger, numbers = nodes.trigger, attributes.numbers
-
- local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer
- starttiming(attributes)
- local done, used, ok = false, nil, false
- local name = plugin.name
- local attribute = numbers[name]
- local namespace = plugin.namespace
- if namespace.enabled then
- local processor = plugin.processor
- if processor then
- local initializer = plugin.initializer
- local resolver = plugin.resolver
- local inheritance = (resolver and resolver()) or -1
- if initializer then
- initializer(namespace,attribute,head)
- end
- head, ok = processor(namespace,attribute,head,inheritance)
- if ok then
- local finalizer = plugin.finalizer
- if finalizer then
- head, ok, used = finalizer(namespace,attribute,head)
- if used then
- local flusher = plugin.flusher
- if flusher then
- local h, d = flusher(namespace,attribute,head,used)
- head = h
- end
- end
- end
- done = true
- end
- end
- end
- stoptiming(attributes)
- return head, done
- end
-
- nodes.process_attribute = process_attribute
-
- function nodes.install_attribute_handler(plugin)
- return function(head)
- return process_attribute(head,plugin)
- end
- end
-
-end
-
---
--- generic handlers
---
-
-states = { }
-
-do
-
- local glyph, glue, rule, whatsit, hlist, vlist = node.id('glyph'), node.id('glue'), node.id('rule'), node.id('whatsit'), node.id('hlist'), node.id('vlist')
-
- local has_attribute, copy = node.has_attribute, node.copy
-
- local current, current_selector, used, done = 0, 0, { }, false
-
- function states.initialize(what, attribute, stack)
- current, current_selector, used, done = 0, 0, { }, false
- end
-
- local function insert(n,stack,previous,head) -- there is a helper, we need previous because we are not slided
- if n then
- if type(n) == "function" then
- n = n()
- end
- n = copy(n)
- n.next = stack
- if previous then
- previous.next = n
- else
- head = n
- end
- previous = n
- end
- return stack, head
- end
-
- function states.finalize(namespace,attribute,head) -- is this one ok?
- if current > 0 then
- local nn = namespace.none
- if nn then
- local id = head.id
- if id == hlist or id == vlist then
- local list = head.list
- if list then
- local _, h = insert(nn,list,nil,list)
- head.list = h
- end
- else
- stack, head = insert(nn,head,nil,head)
- end
- return head, true, true
- end
- end
- return head, false, false
- end
-
- local function process(namespace,attribute,head,inheritance,default) -- one attribute
- local trigger = namespace.triggering and nodes.triggering and nodes.trigger
- local stack, previous, done = head, nil, false
- local nsdata, nsreviver, nsnone = namespace.data, namespace.reviver, namespace.none
- while stack do
- local id = stack.id
- -- if id == glyph or (id == whatsit and stack.subtype == 8) or id == rule or (id == glue and stack.leader) then -- or disc
- if id == glyph or id == rule or (id == glue and stack.leader) then -- or disc
- local c = has_attribute(stack,attribute)
- if c then
- if default and c == inheritance then
- if current ~= default then
- local data = nsdata[default] or nsreviver(default)
- stack, head = insert(data,stack,previous,head)
- current, done, used[default] = default, true, true
- end
- elseif current ~= c then
- local data = nsdata[c] or nsreviver(c)
- stack, head = insert(data,stack,previous,head)
- current, done, used[c] = c, true, true
- end
- if id == glue then --leader
- -- same as *list
- local content = stack.leader
- if content then
- local ok = false
- if trigger and has_attribute(stack,trigger) then
- local outer = has_attribute(stack,attribute)
- if outer ~= inheritance then
- stack.leader, ok = process(namespace,attribute,content,inheritance,outer)
- else
- stack.leader, ok = process(namespace,attribute,content,inheritance,default)
- end
- else
- stack.leader, ok = process(namespace,attribute,content,inheritance,default)
- end
- done = done or ok
- end
- end
- elseif default and inheritance then
- if current ~= default then
- local data = nsdata[default] or nsreviver(default)
- stack, head = insert(data,stack,previous,head)
- current, done, used[default] = default, true, true
- end
- elseif current > 0 then
- stack, head = insert(nsnone,stack,previous,head)
- current, done, used[0] = 0, true, true
- end
- elseif id == hlist or id == vlist then
- local content = stack.list
- if content then
- local ok = false
- if trigger and has_attribute(stack,trigger) then
- local outer = has_attribute(stack,attribute)
- if outer ~= inheritance then
- stack.list, ok = process(namespace,attribute,content,inheritance,outer)
- else
- stack.list, ok = process(namespace,attribute,content,inheritance,default)
- end
- else
- stack.list, ok = process(namespace,attribute,content,inheritance,default)
- end
- done = done or ok
- end
- end
- previous = stack
- stack = stack.next
- end
- return head, done
- end
-
- states.process = process
-
- -- we can force a selector, e.g. document wide color spaces, saves a little
- -- watch out, we need to check both the selector state (like colorspace) and
- -- the main state (like color), otherwise we get into troubles when a selector
- -- state changes while the main state stays the same (like two glyphs following
- -- each other with the same color but different color spaces e.g. \showcolor)
-
- local function selective(namespace,attribute,head,inheritance,default) -- two attributes
- local trigger = namespace.triggering and nodes.triggering and nodes.trigger
- local stack, previous, done = head, nil, false
- -- local nsselector, nsforced, nsselector = namespace.default, namespace.forced, namespace.selector
- local nsforced, nsselector = namespace.forced, namespace.selector
- local nsdata, nsreviver, nsnone = namespace.data, namespace.reviver, namespace.none
- while stack do
- local id = stack.id
- -- if id == glyph or (id == whatsit and stack.subtype == 8) or id == rule or (id == glue and stack.leader) then -- or disc
- if id == glyph or id == rule or (id == glue and stack.leader) then -- or disc
- local c = has_attribute(stack,attribute)
- if c then
- if default and c == inheritance then
- if current ~= default then
- local data = nsdata[default] or nsreviver(default)
- stack, head = insert(data[nsforced or has_attribute(stack,nsselector) or nsselector],stack,previous,head)
- current, done, used[default] = default, true, true
- end
- else
- local s = has_attribute(stack,nsselector)
- if current ~= c or current_selector ~= s then
- local data = nsdata[c] or nsreviver(c)
- stack, head = insert(data[nsforced or has_attribute(stack,nsselector) or nsselector],stack,previous,head)
- current, current_selector, done, used[c] = c, s, true, true
- end
- end
- elseif default and inheritance then
- if current ~= default then
- local data = nsdata[default] or nsreviver(default)
- stack, head = insert(data[nsforced or has_attribute(stack,nsselector) or nsselector],stack,previous,head)
- current, done, used[default] = default, true, true
- end
- elseif current > 0 then
- stack, head = insert(nsnone,stack,previous,head)
- current, current_selector, done, used[0] = 0, 0, true, true
- end
- if id == glue then -- leader
- -- same as *list
- local content = stack.leader
- if content then
- local ok = false
- if trigger and has_attribute(stack,trigger) then
- local outer = has_attribute(stack,attribute)
- if outer ~= inheritance then
- stack.leader, ok = selective(namespace,attribute,content,inheritance,outer)
- else
- stack.leader, ok = selective(namespace,attribute,content,inheritance,default)
- end
- else
- stack.leader, ok = selective(namespace,attribute,content,inheritance,default)
- end
- done = done or ok
- end
- end
- elseif id == hlist or id == vlist then
- local content = stack.list
- if content then
- local ok = false
- if trigger and has_attribute(stack,trigger) then
- local outer = has_attribute(stack,attribute)
- if outer ~= inheritance then
- stack.list, ok = selective(namespace,attribute,content,inheritance,outer)
- else
- stack.list, ok = selective(namespace,attribute,content,inheritance,default)
- end
- else
- stack.list, ok = selective(namespace,attribute,content,inheritance,default)
- end
- done = done or ok
- end
- end
- previous = stack
- stack = stack.next
- end
- return head, done
- end
-
- states.selective = selective
-
-end
-
-states = states or { }
-states.collected = states.collected or { }
-
-input.storage.register(false,"states/collected", states.collected, "states.collected")
-
-function states.collect(str)
- local collected = states.collected
- collected[#collected+1] = str
-end
-
-function states.flush()
- local collected = states.collected
- if #collected > 0 then
- for i=1,#collected do
- texsprint(tex.ctxcatcodes,collected[i]) -- we're in context mode anyway
- end
- states.collected = { }
- end
-end
-
-function states.check()
- texio.write_nl(concat(states.collected,"\n"))
-end
-
--
-- colors
--
@@ -500,21 +41,9 @@ end
-- at the tex end add 0, 1, 2, but this is not faster and less
-- flexible (since sometimes we freeze color attribute values at
-- the lua end of the game
-
+--
-- we also need to store the colorvalues because we need then in mp
-
-colors = colors or { }
-colors.data = colors.data or { }
-colors.values = colors.values or { }
-colors.registered = colors.registered or { }
-colors.enabled = true
-colors.weightgray = true
-colors.attribute = 0
-colors.selector = 0
-colors.default = 1
-colors.main = nil
-colors.triggering = true
-
+--
-- This is a compromis between speed and simplicity. We used to store the
-- values and data in one array, which made in neccessary to store the
-- converters that need node constructor into strings and evaluate them
@@ -526,21 +55,33 @@ colors.triggering = true
-- colors.strings[color] = "return colors." .. colorspace .. "(" .. concat({...},",") .. ")"
-- end
--
--- input.storage.register(true,"colors/data", colors.strings, "colors.data") -- evaluated
+-- storage.register("colors/data", colors.strings, "colors.data") -- evaluated
--
-- We assume that only processcolors are defined in the format.
-input.storage.register(false,"colors/values", colors.values, "colors.values")
-input.storage.register(false,"colors/registered", colors.registered, "colors.registered")
+colors = colors or { }
+colors.data = colors.data or { }
+colors.values = colors.values or { }
+colors.registered = colors.registered or { }
+colors.enabled = true
+colors.weightgray = true
+colors.attribute = 0
+colors.selector = 0
+colors.default = 1
+colors.main = nil
+colors.triggering = true
+
+storage.register("colors/values", colors.values, "colors.values")
+storage.register("colors/registered", colors.registered, "colors.registered")
-colors.stamps = {
+local templates = {
rgb = "r:%s:%s:%s",
cmyk = "c:%s:%s:%s:%s",
gray = "s:%s",
spot = "p:%s:%s:%s:%s"
}
-colors.models = {
+local models = {
all = 1,
gray = 2,
rgb = 3,
@@ -549,158 +90,146 @@ colors.models = {
colors.model = "all"
-do
+local data = colors.data
+local values = colors.values
+local registered = colors.registered
- local min = math.min
- local max = math.max
+local numbers = attributes.numbers
+local list = attributes.list
- local function rgbdata(r,g,b) -- dodo: backends.pdf.rgbdata
- return backends.pdf.literal(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b))
- end
+local min = math.min
+local max = math.max
- local function cmykdata(c,m,y,k)
- return backends.pdf.literal(format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k))
- end
+local nodeinjections = backends.nodeinjections
+local codeinjections = backends.codeinjections
+local registrations = backends.registrations
- local function graydata(s)
- return backends.pdf.literal(format("%s g %s G",s,s))
- end
-
- local function spotdata(n,f,d,p)
- if type(p) == "string" then
- p = p:gsub(","," ") -- brr misuse of spot
- end
- return backends.pdf.literal(format("/%s cs /%s CS %s SCN %s scn",n,n,p,p))
- end
+local function rgbtocmyk(r,g,b) -- we could reduce
+ return 1-r, 1-g, 1-b, 0
+end
- local function rgbtocmyk(r,g,b) -- we could reduce
- return 1-r, 1-g, 1-b, 0
- end
+local function cmyktorgb(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 cmyktorgb(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)
+local function rgbtogray(r,g,b)
+ if colors.weightgray then
+ return .30*r+.59*g+.11*b
+ else
+ return r/3+g/3+b/3
end
+end
- local function rgbtogray(r,g,b)
- if colors.weightgray then
- return .30*r+.59*g+.11*b
- else
- return r/3+g/3+b/3
- end
- end
+local function cmyktogray(c,m,y,k)
+ return rgbtogray(cmyktorgb(c,m,y,k))
+end
- local function cmyktogray(c,m,y,k)
- return rgbtogray(cmyktorgb(c,m,y,k))
- end
+colors.rgbtocmyk = rgbtocmyk
+colors.rgbtogray = rgbtogray
+colors.cmyktorgb = cmyktorgb
+colors.cmyktogray = cmyktogray
- colors.rgbtocmyk = rgbtocmyk
- colors.rgbtogray = rgbtogray
- colors.cmyktorgb = cmyktorgb
- colors.cmyktogray = cmyktogray
+-- we can share some *data by using s, rgb and cmyk hashes, but
+-- normally the amount of colors is not that large; storing the
+-- components costs a bit of extra runtime, but we expect to gain
+-- some back because we have them at hand; the number indicates the
+-- default color space
- -- we can share some *data by using s, rgb and cmyk hashes, but
- -- normally the amount of colors is not that large; storing the
- -- components costs a bit of extra runtime, but we expect to gain
- -- some back because we have them at hand; the number indicates the
- -- default color space
+function colors.gray(s)
+ return { 2, s, s, s, s, 0, 0, 0, 1-s }
+end
- function colors.gray(s)
- return { 2, s, s, s, s, 0, 0, 0, 1-s }
- end
+function colors.rgb(r,g,b)
+ local s = rgbtogray(r,g,b)
+ local c, m, y, k = rgbtocmyk(r,g,b)
+ return { 3, s, r, g, b, c, m, y, k }
+end
- function colors.rgb(r,g,b)
- local s = rgbtogray(r,g,b)
- local c, m, y, k = rgbtocmyk(r,g,b)
- return { 3, s, r, g, b, c, m, y, k }
- end
+function colors.cmyk(c,m,y,k)
+ local s = cmyktogray(c,m,y,k)
+ local r, g, b = cmyktorgb(c,m,y,k)
+ return { 4, s, r, g, b, c, m, y, k }
+end
- function colors.cmyk(c,m,y,k)
- local s = cmyktogray(c,m,y,k)
- local r, g, b = cmyktorgb(c,m,y,k)
- return { 4, s, r, g, b, c, m, y, k }
- end
+--~ function colors.spot(parent,f,d,p)
+--~ return { 5, .5, .5, .5, .5, 0, 0, 0, .5, parent, f, d, p }
+--~ end
- --~ function colors.spot(parent,f,d,p)
- --~ return { 5, .5, .5, .5, .5, 0, 0, 0, .5, parent, f, d, p }
- --~ end
-
- function colors.spot(parent,f,d,p)
- if type(p) == "number" then
- local n = attributes.list[attributes.numbers.color][parent] -- hard coded ref to color number
- if n then
- local v = colors.values[n]
- if v then
- -- the via cmyk hack is dirty, but it scales better
- local c, m, y, k = p*v[6], p*v[7], p*v[8], p*v[8]
- local r, g, b = cmyktorgb(c,m,y,k)
- local s = cmyktogray(c,m,y,k)
- return { 5, s, r, g, b, c, m, y, k, parent, f, d, p }
- end
+function colors.spot(parent,f,d,p)
+ if type(p) == "number" then
+ local n = list[numbers.color][parent] -- hard coded ref to color number
+ if n then
+ local v = values[n]
+ if v then
+ -- the via cmyk hack is dirty, but it scales better
+ local c, m, y, k = p*v[6], p*v[7], p*v[8], p*v[8]
+ local r, g, b = cmyktorgb(c,m,y,k)
+ local s = cmyktogray(c,m,y,k)
+ return { 5, s, r, g, b, c, m, y, k, parent, f, d, p }
end
- else
- -- todo, multitone (maybe p should be a table)
end
- return { 5, .5, .5, .5, .5, 0, 0, 0, .5, parent, f, d, p }
+ else
+ -- todo, multitone (maybe p should be a table)
end
+ return { 5, .5, .5, .5, .5, 0, 0, 0, .5, parent, f, d, p }
+end
- function colors.reviver(n)
- local d = colors.data[n]
- if not d then
- local v = colors.values[n]
- if not v then
- local gray = graydata(0)
+function colors.reviver(n)
+ local d = data[n]
+ if not d then
+ local v = values[n]
+ if not v then
+ local gray = nodeinjections.graycolor(0)
+ d = { gray, gray, gray, gray }
+ logs.report("attributes","unable to revive color %s",n or "?")
+ else
+ local kind, gray, rgb, cmyk = v[1], nodeinjections.graycolor(v[2]), nodeinjections.rgbcolor(v[3],v[4],v[5]), nodeinjections.cmykcolor(v[6],v[7],v[8],v[9])
+ if kind == 2 then
d = { gray, gray, gray, gray }
- logs.report("attributes","unable to revive color %s",n or "?")
- else
- local kind, gray, rgb, cmyk = v[1], graydata(v[2]), rgbdata(v[3],v[4],v[5]), cmykdata(v[6],v[7],v[8],v[9])
- if kind == 2 then
- d = { gray, gray, gray, gray }
- elseif kind == 3 then
- d = { rgb, gray, rgb, cmyk }
- elseif kind == 4 then
- d = { cmyk, gray, rgb, cmyk }
- elseif kind == 5 then
- local spot = spotdata(v[10],v[11],v[12],v[13])
- d = { spot, gray, rgb, cmyk }
- end
+ elseif kind == 3 then
+ d = { rgb, gray, rgb, cmyk }
+ elseif kind == 4 then
+ d = { cmyk, gray, rgb, cmyk }
+ elseif kind == 5 then
+ local spot = nodeinjections.spotcolor(v[10],v[11],v[12],v[13])
+ d = { spot, gray, rgb, cmyk }
end
- colors.data[n] = d
end
- return d
+ data[n] = d
end
+ return d
+end
- function colors.filter(n)
- return concat(colors.data[n],":",5)
- end
-
- colors.none = graydata(0)
-
+function colors.filter(n)
+ return concat(data[n],":",5)
end
+colors.none = nodeinjections.graycolor(0)
+
function colors.setmodel(attribute,name)
colors.model = name
- colors.selector = attributes.numbers[attribute]
- colors.default = colors.models[name] or 1
+ colors.selector = numbers[attribute]
+ colors.default = models[name] or 1
return colors.default
end
function colors.register(attribute, name, colorspace, ...) -- passing 9 vars is faster
- local stamp = format(colors.stamps[colorspace], ...)
- local color = colors.registered[stamp]
+ local stamp = format(templates[colorspace],...)
+ local color = registered[stamp]
if not color then
- color = #colors.values+1
- colors.values[color] = colors[colorspace](...)
- colors.registered[stamp] = color
+ color = #values+1
+ values[color] = colors[colorspace](...)
+ registered[stamp] = color
colors.reviver(color)
end
if name then
- attributes.list[attributes.numbers[attribute]][name] = color -- not grouped, so only global colors
+ list[numbers[attribute]][name] = color -- not grouped, so only global colors
end
- return colors.registered[stamp]
+ return registered[stamp]
end
function colors.value(id)
- return colors.values[id]
+ return values[id]
end
shipouts.handle_color = nodes.install_attribute_handler {
@@ -709,7 +238,7 @@ shipouts.handle_color = nodes.install_attribute_handler {
initializer = states.initialize,
finalizer = states.finalize,
processor = states.selective,
- resolver = function(...) return colors.main end,
+ resolver = function() return colors.main end,
}
-- transparencies
@@ -722,51 +251,56 @@ transparencies.registered = transparencies.registered or { }
transparencies.data = transparencies.data or { }
transparencies.values = transparencies.values or { }
transparencies.enabled = false
-transparencies.template = "%s:%s"
transparencies.triggering = true
-input.storage.register(false, "transparencies/registered", transparencies.registered, "transparencies.registered")
-input.storage.register(false, "transparencies/values", transparencies.values, "transparencies.values")
+storage.register("transparencies/registered", transparencies.registered, "transparencies.registered")
+storage.register("transparencies/values", transparencies.values, "transparencies.values")
-function transparencies.reference(n)
- return backends.pdf.literal(format("/Tr%s gs",n))
+local registered = transparencies.registered
+local data = transparencies.data
+local values = transparencies.values
+local template = "%s:%s"
+
+local function reference(n)
+ reference = nodeinjections.transparency
+ return reference(n)
end
function transparencies.register(name,a,t)
- local stamp = format(transparencies.template,a,t)
- local n = transparencies.registered[stamp]
+ local stamp = format(template,a,t)
+ local n = registered[stamp]
if not n then
- n = #transparencies.data+1
- transparencies.data[n] = transparencies.reference(n)
- transparencies.values[n] = { a, t }
- transparencies.registered[stamp] = n
- states.collect(format("\\presetPDFtransparencybynumber{%s}{%s}{%s}",n,a,t)) -- too many, but experimental anyway
+ n = #data+1
+ data[n] = reference(n)
+ values[n] = { a, t }
+ registered[stamp] = n
+ registrations.transparency(n,a,t)
end
- return transparencies.registered[stamp]
+ return registered[stamp]
end
function transparencies.reviver(n)
- local d = transparencies.data[n]
+ local d = data[n]
if not d then
- local v = transparencies.values[n]
+ local v = values[n]
if not v then
- d = transparencies.reference(0)
+ d = reference(0)
logs.report("attributes","unable to revive transparency %s",n or "?")
else
- d = transparencies.reference(n)
- states.collect(format("\\presetPDFtransparencybynumber{%s}{%s}{%s}",n,v[1],v[2]))
+ d = reference(n)
+ registrations.transparency(n,v[1],v[2])
end
- transparencies.data[n] = d
+ data[n] = d
end
return d
end
-- check if there is an identity
-transparencies.none = transparencies.reference(0) -- for the moment the pdf backend does this
+transparencies.none = reference(0) -- for the moment the pdf backend does this
function transparencies.value(id)
- return transparencies.values[id]
+ return values[id]
end
shipouts.handle_transparency = nodes.install_attribute_handler {
@@ -783,8 +317,8 @@ overprints = overprints or { }
overprints.data = overprints.data or { }
overprints.enabled = false
-overprints.data[1] = backends.pdf.literal(format("/GSoverprint gs"))
-overprints.data[2] = backends.pdf.literal(format("/GSknockout gs"))
+overprints.data[1] = nodeinjections.overprint()
+overprints.data[2] = nodeinjections.knockout()
overprints.none = overprints.data[2]
@@ -793,12 +327,14 @@ overprints.registered = {
knockout = 2,
}
---~ input.storage.register(false, "overprints/registered", overprints.registered, "overprints.registered")
---~ input.storage.register(false, "overprints/data", overprints.data, "overprints.data")
+--~ storage.register("overprints/registered", overprints.registered, "overprints.registered")
+--~ storage.register("overprints/data", overprints.data, "overprints.data")
+
+local data = overprints.data
+local registered = overprints.registered
function overprints.register(stamp)
--- states.collect(texsprint(tex.ctxcatcodes,"\\initializePDFoverprint")) -- to be testd
- return overprints.registered[stamp] or overprints.registered.overprint
+ return registered[stamp] or registered.overprint
end
shipouts.handle_overprint = nodes.install_attribute_handler {
@@ -815,8 +351,8 @@ negatives = negatives or { }
negatives.data = negatives.data or { }
negatives.enabled = false
-negatives.data[1] = backends.pdf.literal(format("/GSpositive gs"))
-negatives.data[2] = backends.pdf.literal(format("/GSnegative gs"))
+negatives.data[1] = nodeinjections.positive()
+negatives.data[2] = nodeinjections.negative()
negatives.none = negatives.data[1]
@@ -826,7 +362,6 @@ negatives.registered = {
}
function negatives.register(stamp)
--- states.collect(texsprint(tex.ctxcatcodes,"\\initializePDFnegative")) -- to be testd
return negatives.registered[stamp] or negatives.registered.positive
end
@@ -838,7 +373,7 @@ shipouts.handle_negative = nodes.install_attribute_handler {
processor = states.process,
}
--- effects
+-- effects -- can be optimized
effects = effects or { }
effects.data = effects.data or { }
@@ -846,8 +381,8 @@ effects.registered = effects.registered or { }
effects.enabled = false
effects.stamp = "%s:%s:%s"
-input.storage.register(false, "effects/registered", effects.registered, "effects.registered")
-input.storage.register(false, "effects/data", effects.data, "effects.data")
+storage.register("effects/registered", effects.registered, "effects.registered")
+storage.register("effects/data", effects.data, "effects.data")
function effects.register(effect,stretch,rulethickness)
local stamp = format(effects.stamp,effect,stretch,rulethickness)
@@ -856,27 +391,18 @@ function effects.register(effect,stretch,rulethickness)
n = #effects.data+1
effects.data[n] = effects.reference(effect,stretch,rulethickness)
effects.registered[stamp] = n
- -- states.collect("") -- nothing
end
return effects.registered[stamp]
end
-backends.pdf.effects = {
- normal = 0,
- inner = 0,
- outer = 1,
- both = 2,
- hidden = 3,
-}
+-- valid effects: normal inner outer both hidden
function effects.reference(effect,stretch,rulethickness)
- -- always, no zero test (removed)
- rulethickness = number.dimenfactors["bp"]*rulethickness
- effect = backends.pdf.effects[effect] or backends.pdf.effects['normal']
- return backends.pdf.literal(format("%s Tc %s w %s Tr",stretch,rulethickness,effect)) -- watch order
+ effects.reference = nodeinjections.effect
+ return nodeinjections.effect(stretch,rulethickness,effect)
end
-effects.none = effects.reference(0,0,0) -- faster: backends.pdf.literal("0 Tc 0 w 0 Tr")
+effects.none = effects.reference(0,0,0)
shipouts.handle_effect = nodes.install_attribute_handler {
name = "effect",
@@ -891,15 +417,18 @@ shipouts.handle_effect = nodes.install_attribute_handler {
viewerlayers = viewerlayers or { }
viewerlayers.data = viewerlayers.data or { }
viewerlayers.registered = viewerlayers.registered or { }
-viewerlayers.stamp = "%s"
viewerlayers.enabled = false
-input.storage.register(false, "viewerlayers/registered", viewerlayers.registered, "viewerlayers.registered")
---~ input.storage.register(false, "viewerlayers/data", viewerlayers.data, "viewerlayers.data")
+storage.register("viewerlayers/registered", viewerlayers.registered, "viewerlayers.registered")
+--~ storage.register("viewerlayers/data", viewerlayers.data, "viewerlayers.data")
+
+local data = viewerlayers.data
+local registered = viewerlayers.registered
+local template = "%s"
local somedone = false
local somedata = { }
-local nonedata = backends.pdf.literal("EMC")
+local nonedata = nodeinjections.stoplayer()
function viewerlayers.none() -- no local
if somedone then
@@ -914,8 +443,8 @@ local function some(name)
local sd = somedata[name]
if not sd then
sd = {
- backends.pdf.literal(format("EMC /OC /%s BDC",name)),
- backends.pdf.literal(format( "/OC /%s BDC",name)),
+ nodeinjections.switchlayer(name),
+ nodeinjections.startlayer(name),
}
somedata[name] = sd
end
@@ -933,14 +462,14 @@ local function initializer(...)
end
viewerlayers.register = function(name)
- local stamp = format(viewerlayers.stamp,name)
- local n = viewerlayers.registered[stamp]
+ local stamp = format(template,name)
+ local n = registered[stamp]
if not n then
- n = #viewerlayers.data + 1
- viewerlayers.data[n] = function() return some(name) end
- viewerlayers.registered[stamp] = n
+ n = #data + 1
+ data[n] = function() return some(name) end -- slow but for the moment we don't store things in the format
+ registered[stamp] = n
end
- return viewerlayers.registered[stamp]
+ return registered[stamp] -- == n
end
shipouts.handle_viewerlayer = nodes.install_attribute_handler {
@@ -950,5 +479,3 @@ shipouts.handle_viewerlayer = nodes.install_attribute_handler {
finalizer = states.finalize,
processor = states.process,
}
-
---~ nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer", nil, "notail")
diff --git a/tex/context/base/attr-ini.tex b/tex/context/base/attr-ini.tex
index c9e4110e5..3997d546b 100644
--- a/tex/context/base/attr-ini.tex
+++ b/tex/context/base/attr-ini.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Attribute Macros / initialization}
+\writestatus{loading}{ConTeXt Attribute Macros / Initialization}
%D Although it's still somewhat experimental, here we introduce code
%D related to attributes.
@@ -20,63 +20,21 @@
\registerctxluafile{attr-ini}{1.001}
-\newcount\attdefcounter
-
-% \def\newattribute#1%
-% {\global\advance\attdefcounter\plusone
-% \global\attributedef#1\attdefcounter
-% \ctxlua{attributes.define("\strippedcsname#1",\number\attdefcounter)}}
-
-% \newattribute\statusattribute
-% \newattribute\colorattribute
-% \newattribute\skipattribute
-% \newattribute\penaltyattribute
-
-\newtoks \attributesresetlist
-
-\def\defineattribute[#1]% alternatively we can let lua do the housekeeping
- {\global\advance\attdefcounter\plusone
- \expandafter \xdef\csname :attr:#1\endcsname{\number\attdefcounter}%
- \global\expandafter\attributedef\csname @attr@#1\endcsname \attdefcounter
- \writestatus\m!systems{defining attribute #1 with number \the\attdefcounter}%
- \appendetoks\csname @attr@#1\endcsname\minusone\to\attributesresetlist
- \ctxlua{attributes.define("#1",\number\attdefcounter)}}
-
-% expandable so we can \edef them for speed
-
-\def\dosetattribute#1#2{\csname @attr@#1\endcsname#2\relax}
-\def\doresetattribute#1{\csname @attr@#1\endcsname\minusone}
-\def\dogetattribute #1{\number\csname @attr@#1\endcsname}
-\def\dogetattributeid#1{\csname :attr:#1\endcsname}
-
-\let\dompattribute\gobbletwoarguments
-
-\defineattribute[mark]
-% \defineattribute[status] % used ? maybe combine with
-\defineattribute[state]
-\defineattribute[trigger] % feature inheritance
-\defineattribute[skip]
-\defineattribute[penalty]
-
-\startruntimectxluacode
- nodes.trigger = \dogetattributeid{trigger}
-\stopruntimectxluacode
-
-% \defineattribute[ignore]
+\definesystemattribute[state]
+\definesystemattribute[skip]
+\definesystemattribute[penalty]
+\definesystemattribute[colormodel][global] % no reset
+\definesystemattribute[color]
+\definesystemattribute[transparency]
+\definesystemattribute[overprint]
+\definesystemattribute[negative]
+\definesystemattribute[effect]
+\definesystemattribute[viewerlayer]
+
+% \definesystemattribute[ignore]
%
% \edef\startignorecontent{\dosetattribute{ignore}\plusone}
% \edef\stopignorecontent {\doresetattribute{ignore}}
-%
-% \startruntimectxluacode
-% nodes.ignore = \dogetattributeid{ignore}
-% \stopruntimectxluacode
-
-% \dosetattribute{status}{1}
-
-% temp here / will be indirect ! just for testing
-
-\defineattribute[colormodel]
-\defineattribute[color]
% todo: no need for 'color' argument, we can set that once at startup; currently
% a bit inconsistent
@@ -106,8 +64,6 @@
% transparency
-\defineattribute[transparency]
-
\def\registertransparency#1#2#3%
{\setevalue{(ts:#1)}{\dosetattribute{transparency}{\ctxlua{tex.print(transparencies.register(#2,#3))}}}}
@@ -123,8 +79,6 @@
% overprint
-\defineattribute[overprint]
-
\def\registeroverprint#1#2%
{\setevalue{(os:#1)}{\dosetattribute{overprint}{\ctxlua{tex.print(overprints.register('#2'))}}}}
@@ -139,8 +93,6 @@
% negative
-\defineattribute[negative]
-
\def\registernegative#1#2%
{\setevalue{(ns:#1)}{\dosetattribute{negative}{\ctxlua{tex.print(negatives.register('#2'))}}}}
@@ -155,8 +107,6 @@
% effect
-\defineattribute[effect]
-
\def\registereffect#1#2#3% #2=stretch #3=rulethickness
{\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}%
{\dosetattribute{effect}{\ctxlua{tex.print(effects.register('#1',#2,\number\dimexpr#3\relax))}}}}
@@ -176,90 +126,25 @@
% viewerlayers
-\defineattribute[viewerlayer]
+% \def\registerviewerlayer#1#2% global !
+% {\setxvalue{(vl:#1)}{\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}}
+%
+% \setevalue{(vl:)}{\doresetattribute{viewerlayer}}
+%
+% needs to work over stopitemize grouping etc
+
+\def\registerviewerlayer#1#2% global !
+ {\setxvalue{(vl:#1)}{\global\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}}
-\def\registerviewerlayer#1#2%
- {\setevalue{(vl:#1)}{\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}}
+\setevalue{(vl:)}{\global\doresetattribute{viewerlayer}}
-\setevalue{(vl:)}{\doresetattribute{viewerlayer}}
+%
\def\dotriggerviewerlayer
{\ctxlua{viewerlayers.enabled=true}%
\gdef\dotriggerviewerlayer##1{\csname(vl:##1)\endcsname}%
\dotriggerviewerlayer}
-% ugly solution for backend handling
-
-% \def\shipout
-% {%\writestatus{SHIPOUT}{CALLED AT PAGE \realfolio}%
-% \dowithnextbox
-% {\ctxlua{callbacks.push('hpack_filter',nodes.process_page)}%
-% %\writestatus{SHIPOUT}{START PACKAGING}%
-% \setbox\nextbox\hbox{\box\nextbox}%
-% %\writestatus{SHIPOUT}{STOP PACKAGING}%
-% \ctxlua{callbacks.pop('hpack_filter')}%
-% \primitive\shipout\box\nextbox}}
-
-% \def\shipout
-% {\dowithnextbox
-% {\ctxlua{nodes.process_page(tex.box[\number\nextbox])}%
-% \primitive\shipout\box\nextbox}}
-
-% Objects are processed indepently \unknown\ actually we may need a proper callback.
-
-\newbox\finalizedshipoutbox
-
-\def\finalizeobjectbox#1{\ctxlua{nodes.process_page(tex.box[\number#1])}}
-
-\def\finalizeshipoutbox#1% % hack till we have access to pdf backend
- {\global\setbox\finalizedshipoutbox\hbox{#1}%
- \finalizeobjectbox\finalizedshipoutbox
- \hbox{\ctxlua{states.flush()}\box\finalizedshipoutbox}}
-
-\let\normalshipout\shipout
-
-% tricky stuff:
-
-\newcount\attributeboxcount
-
-\edef\startinheritattributes{\dosetattribute {trigger}{1}}
-\edef\stopinheritattributes {\doresetattribute{trigger}}
-
-\def\doattributedcopy {\afterassignment\dodoattributedcopy\attributeboxcount}
-\def\doattributedbox {\afterassignment\dodoattributedbox \attributeboxcount}
-
-\def\dodoattributedcopy
- {\startinheritattributes
- \ifvbox\attributeboxcount
- \vbox{\unvcopy\attributeboxcount}%
- \else
- \hbox{\unhcopy\attributeboxcount}%
- \fi
- \stopinheritattributes}
-
-\def\dodoattributedbox
- {\startinheritattributes
- \ifvbox\attributeboxcount
- \vbox{\unvbox\attributeboxcount}%
- \else
- \hbox{\unhbox\attributeboxcount}%
- \fi
- \stopinheritattributes}
-
-\def\enableattributeinheritance
- {\ctxlua{nodes.triggering=true}%
- \let\attributedcopy\doattributedcopy
- \let\attributedbox \doattributedbox}
-
-\def\disableattributeinheritance
- {\ctxlua{nodes.triggering=false}%
- \let\attributedcopy\copy
- \let\attributedbox \box}
-
-\disableattributeinheritance
-
-% \enableattributeinheritance % will become default
-
\protect \endinput
% test case
diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua
new file mode 100644
index 000000000..0a11c2ef7
--- /dev/null
+++ b/tex/context/base/back-ini.lua
@@ -0,0 +1,75 @@
+if not modules then modules = { } end modules ['back-ini'] = {
+ version = 1.001,
+ comment = "companion to back-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+backends = backends or { }
+
+local function nothing() return nil end
+
+backends.nodeinjections = {
+ rgbcolor = nothing,
+ cmykcolor = nothing,
+ graycolor = nothing,
+ spotcolor = nothing,
+ transparency = nothing,
+ overprint = nothing,
+ knockout = nothing,
+ positive = nothing,
+ negative = nothing,
+ effect = nothing,
+ startlayer = nothing,
+ stoplayer = nothing,
+ switchlayer = nothing,
+}
+
+backends.codeinjections = {
+ insertmovie = nothing,
+}
+
+backends.registrations = {
+ grayspotcolor = nothing,
+ rgbspotcolor = nothing,
+ cmykspotcolor = nothing,
+ grayindexcolor = nothing,
+ rgbindexcolor = nothing,
+ cmykindexcolor = nothing,
+ spotcolorname = nothing,
+ transparency = nothing,
+}
+
+local nodeinjections = backends.nodeinjections
+local codeinjections = backends.codeinjections
+local registrations = backends.registrations
+
+backends.current = "unknown"
+
+function backends.install(what)
+ if type(what) == "string" then
+ backends.current = what
+ what = backends[what]
+ if what then
+ local wi = what.nodeinjections
+ if wi then
+ for k, v in next, wi do
+ nodeinjections[k] = v
+ end
+ end
+ local wi = what.codeinjections
+ if wi then
+ for k, v in next, wi do
+ codeinjections[k] = v
+ end
+ end
+ local wi = what.registrations
+ if wi then
+ for k, v in next, wi do
+ registrations[k] = v
+ end
+ end
+ end
+ end
+end
diff --git a/tex/context/base/back-ini.tex b/tex/context/base/back-ini.tex
new file mode 100644
index 000000000..a60b6a329
--- /dev/null
+++ b/tex/context/base/back-ini.tex
@@ -0,0 +1,896 @@
+%D \module
+%D [ file=back-ini,
+%D version=2009.04.15,
+%D title=\CONTEXT\ Backend Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Backend Macros / Initialization}
+
+\registerctxluafile{back-ini}{1.001}
+
+%D We currently have a curious mix between tex and lua backend
+%D handling but eventually most will move to lua.
+
+\unprotect
+
+%D Right from the start \CONTEXT\ had a backend system based on
+%D runtime pluggable code. As most backend issues involved specials
+%D and since postprocessors had not that much in common, we ended up
+%D with a system where we could switch backend as well as output code
+%D for multiple backends at the same time.
+%D
+%D Because \LUATEX\ has the backend built in, and since some backend
+%D issues have been moved to the frontend I decided to provide new
+%D backend code for \MKIV, starting with what was actually used.
+%D
+%D At this moment \DVI\ is no longer used for advanced document
+%D output and we therefore dropped support for this format. Future
+%D versions might support more backends again, but this has a low
+%D priority.
+%D
+%D The big question is: what is to be considered a backend issue and
+%D what not. For the moment we treat image inclusion, object reuse,
+%D position tracking and color as frontend issues, if only because we
+%D deal with them via \LUA\ code and as such we don't depend too much
+%D on macro calls that need to inject code for the backend.
+%D
+%D Not everything here makes sense and the content of this file will
+%D definitely change.
+
+%D We use a couple of (global) variables because it saves us the
+%D trouble of dealing with arguments.
+
+\letempty \@@DriverFieldName
+\letempty \@@DriverFieldWidth
+\letempty \@@DriverFieldHeight
+\letempty \@@DriverFieldDefault
+\letempty \@@DriverFieldNumber
+\letempty \@@DriverFieldNumber
+\letempty \@@DriverFieldStyle
+\letempty \@@DriverFieldColor
+\letempty \@@DriverFieldBackgroundColor
+\letempty \@@DriverFieldFrameColor
+\letempty \@@DriverFieldLayer
+\letempty \@@DriverFieldOption
+\letempty \@@DriverFieldAlign
+\letempty \@@DriverFieldClickIn
+\letempty \@@DriverFieldClickOut
+\letempty \@@DriverFieldRegionIn
+\letempty \@@DriverFieldRegionOut
+\letempty \@@DriverFieldAfterKey
+\letempty \@@DriverFieldFormat
+\letempty \@@DriverFieldValidate
+\letempty \@@DriverFieldCalculate
+\letempty \@@DriverFieldFocusIn
+\letempty \@@DriverFieldFocusOut
+
+\letempty \@@DriverCommentLayer
+\letempty \@@DriverAttachmentLayer
+
+\letempty \@@DriverImageBox
+\letempty \@@DriverImageOptions
+\letempty \@@DriverImageWidth
+\letempty \@@DriverImageHeight
+\letempty \@@DriverImageFile
+\letempty \@@DriverImageLabel
+\letempty \@@DriverImageType
+\letempty \@@DriverImageMethod
+\letempty \@@DriverImagePage
+
+\newif\ifcollectreferenceactions
+
+%D \macros
+%D {dostartgraymode,dostopgraymode,
+%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,dostopcolormode}
+%D
+%D Switching to and from color can be done in two ways:
+%D
+%D \startitemize[packed,n]
+%D \item insert driver specific commands
+%D \item pass instructions to the output device
+%D \stopitemize
+%D
+%D The first approach is more general and lays the
+%D responsibility at the driver side. Probably due to the fact
+%D that \TEX\ does not directly support color, we have been
+%D confronted for the last few years with changing special
+%D definitions. The need for support depends on how a macro
+%D package handles colored text that crosses the page boundary.
+%D Again, there are two approaches.
+%D
+%D \startitemize[packed,n]
+%D \item let \TEX\ do the job
+%D \item let the driver handle things
+%D \stopitemize
+%D
+%D The first approach is as driver independant as possible and
+%D can easily be accomplished by using \TEX's mark mechanism.
+%D In \CONTEXT\ we follow this approach. More and more, drivers
+%D are starting to support color, including stacking them.
+%D
+%D Colors as well as grayscales can be represented in scales
+%D from~0 to~1. When drivers use values in the range 0..255,
+%D this value has to be adapted in the translation process.
+%D Technically it's possible to get a grayscale from combining
+%D colors. In the \cap{RGB} color system, a color with Red,
+%D Green and Blue components of 0.80 show the same gray as a
+%D Gray Scale specified 0.80. The \cap{CMYK} color system
+%D supports a Black component apart from Cyan, Magenta and
+%D Yellow.
+%D
+%D Depending on the target format, color support differs from
+%D gray support. PostScript for example offers different
+%D operators for setting gray and color. This is because
+%D printing something using three colors is someting else than
+%D printing with just black.
+%D
+%D In \CONTEXT\ we have implemented a color subsystem that
+%D supports the use of well defined colors that, when printed
+%D in black and white, still can be distinguished. This
+%D approach enables us to serve both printed and electronic
+%D versions, using colored text and illustrations. More on the
+%D fundamentals of this topic can be found in the \cap{MAPS} of
+%D the Dutch User Group, 14 (95.1).
+%D
+%D To satisfy all those needs, we define four specials which
+%D supply enough information for drivers to act upon. We
+%D could have used more general commands with the keywords
+%D 'rgb' and 'gray', but because these specials are used often,
+%D we prefer the more direct and shorter alternative.
+%D
+%D We start with the installation of color and grayscale
+%D specials. The values are in the range 0..1 (e.g. 0.25).
+%D
+%D \starttyping
+%D \dostartgraymode {gray} ... \dostopgraymode
+%D \dostartrgbcolormode {red} {green} {blue} ... \dostopcolormode
+%D \dostartcmykcolormode {cyan} {magenta} {yellow} {black} ... \dostopcolormode
+%D \dostartgraycolormode {gray} ... \dostopcolormode
+%D \stoptyping
+%D
+%D Because we can expect conflicts between drivers, we
+%D implement them as category \type{or}. In previous versions
+%D of \DVIPSONE\ the use of their color||specials did not
+%D interfere with the PostScript ones, but recent versions do.
+
+\let \dostartgraymode \gobbleoneargument
+\let \dostopgraymode \donothing
+\let \dostartrgbcolormode \gobblethreearguments
+\let \dostartcmykcolormode \gobblefourarguments
+\let \dostartgraycolormode \gobbleoneargument
+\let \dostopcolormode \donothing
+\let \dostartspotcolormode \gobbletwoarguments
+\let \doregisterrgbspotcolor \gobblesevenarguments
+\let \doregistercmykspotcolor \gobbleeightarguments
+\let \doregistergrayspotcolor \gobblefourarguments
+\let \doregisterrgbindexcolor \gobblesevenarguments
+\let \doregistercmykindexcolor \gobbleeightarguments
+\let \doregistergrayindexcolor \gobblefourarguments
+\let \doregisterspotcolorname \gobbletwoarguments
+\let \dostartnonecolormode \donothing
+\let \doregisternonecolor \donothing
+
+%D \macros
+%D {doinsertsoundtrack}
+%D
+%D Sounds are (for the moment) just files with
+%D associated options.
+%D
+%D \starttyping
+%D \doinsertsoundtrack {file} {label} {options}
+%D \stoptyping
+
+\let \doinsertsoundtrack \gobblethreearguments
+
+%D \macros
+%D {dostartrotation,dostoprotation,
+%D dostartscaling,dostopscaling,
+%D dostartmirroring,dostopmirroring,
+%D dostartnegative,dostopnegative}
+%D dostartoverprint,dostopoverprint}
+%D
+%D We support a couple of transformations and renderings:
+%D
+%D \starttyping
+%D \dostartrotation {angle} ... \dostoprotation
+%D \dostartscaling {x} {y} ... \dostopscaling
+%D \dostartmirroring {x} {y} ... \dostopmirroring
+%D \stoptyping
+
+\let \dostartrotation \gobbleoneargument
+\let \dostoprotation \donothing
+\let \dostartscaling \gobbletwoarguments
+\let \dostopscaling \donothing
+\let \dostartmirroring \donothing
+\let \dostopmirroring \donothing
+
+\let \dostartnegative \donothing
+\let \dostopnegative \donothing
+\let \dostartoverprint \donothing
+\let \dostopoverprint \donothing
+
+%D The following two specials are used in for instance \type
+%D {\vadjust}'d margin material inside colored paragraphs.
+
+\let \dostartgraphicgroup \donothing
+\let \dostopgraphicgroup \donothing
+
+%D \macros
+%D {doselectfirstpaperbin,
+%D doselectsecondpaperbin}
+%D
+%D Here are some very printer||specific ones. No further
+%D comment.
+
+\let \doselectfirstpaperbin \donothing
+\let \doselectsecondpaperbin \donothing
+
+%D \macros
+%D {doovalbox}
+%D
+%D When we look at the implementation, this is a complicated
+%D one. There are seven arguments.
+%D
+%D \starttyping
+%D \doovalbox {w} {h} {d} {linewidth} {radius} {stroke} {fill} {variant}
+%D \stoptyping
+%D
+%D This command has to return a \type{\vbox} which can be used
+%D to lay over another one (with text). The radius is in
+%D degrees, the stroke and fill are~\type{1} (true) of~\type{0}
+%D (false).
+
+\let \doovalbox \gobbleeightarguments
+
+%D \macros
+%D {dostartclipping,dostopclipping}
+%D
+%D Clipping is implemented in such a way that an arbitrary code
+%D can be fed.
+%D
+%D \starttyping
+%D \dostartclipping {pathname} {width} {height}
+%D \dostopclipping
+%D \stoptyping
+
+\let \dostartclipping \gobblethreearguments
+\let \dostopclipping \donothing
+
+%D \macros
+%D {dosetupidentity}
+%D
+%D We can declare some characteristics of the document with
+%D
+%D \starttyping
+%D \dosetupidentity {title} {subject} {author} {creator} {date} {keys}
+%D \stoptyping
+%D
+%D All data is in string format.
+
+\let \dosetupidentity \gobblesixarguments
+
+%D \macros
+%D {dosetuppaper}
+%D
+%D This special can be used to tell the driver what page size
+%D to use. The special takes three arguments.
+%D
+%D \starttyping
+%D \dosetuppaper {type} {width} {height}
+%D \stoptyping
+%D
+%D The type is one of the common identifiers, like A4, A5 or
+%D B2.
+
+\let \dosetuppaper \gobblethreearguments
+
+%D \macros
+%D {dosetupprinter}
+%D
+%D Some drivers enable the user to specify the paper type
+%D used and/or page dimensions to be taken into account.
+%D
+%D \starttyping
+%D \dosetupprinter {type} {hoffset} {voffset} {width} {height}
+%D \stoptyping
+%D
+%D The first argument is one of \type{letter}, \type{legal},
+%D \type{A4}, \type{A5} etc. The dimensions are in
+%D basepoints.
+
+\let \dosetupprinter \gobblefourarguments
+
+%D \macros
+%D {dosetupopenaction, dosetupclosaction,
+%D dosetupopenpageaction, dosetupclospageaction,
+%D dosetupinteraction,
+%D dosetupscreen,
+%D dosetupviewmode}
+%D
+%D Here come some obscure interactive commands. Probably the
+%D specs will change with the development of the macros that
+%D use them.
+%D
+%D The first ones can be used to set up the interaction.
+%D
+%D \starttyping
+%D \dosetupinteraction
+%D \stoptyping
+%D
+%D Normally this command does nothing but giving a message
+%D that some scheme is supported.
+%D
+%D \starttyping
+%D \dosetupstartaction
+%D \dosetupstopaction
+%D \stoptyping
+%D
+%D These two setup the actions to be executed when the document
+%D is opened and closed.
+%D
+%D The next commands sets up the page and screen. They are
+%D kind of related.
+%D
+%D \starttyping
+%D \dosetuppage {hoffset} {voffset} {width} {height} {options}
+%D \dosetupscreen {hoffset} {voffset} {width} {height} {options}
+%D \stoptyping
+%D
+%D The first four arguments are in points. Option~1 results in a
+%D full screen launch.
+%D
+%D \starttyping
+%D \dosetuppageview {keyword}
+%D \stoptyping
+%D
+%D For the moment we only support \type{fit}.
+
+\let \dosetupinteraction \donothing
+\let \dosetupopenaction \donothing
+\let \dosetupscreen \gobblefourarguments
+\let \dosetuppageview \gobbleoneargument
+\let \dosetupcloseaction \donothing
+\let \dosetupopenpageaction \donothing
+\let \dosetupclosepageaction \donothing
+\let \dosetuprenderingopenpageaction \donothing
+\let \dosetuprenderingclosepageaction \donothing
+\let \dosetupcropbox \gobblefourarguments
+\let \dosetuptrimbox \gobblefourarguments
+\let \dosetupartbox \gobblefourarguments
+\let \dosetupbleedbox \gobblefourarguments
+
+%D \macros
+%D {dostarthide,
+%D dostophide}
+%D
+%D Not every part of the screen is suitable for paper. Menus
+%D for instance have no meaning on an non||interactive medium.
+%D These elements are hidden by means of:
+%D
+%D \starttyping
+%D \dostarthide .. \dostophide
+%D \stoptyping
+
+\let \dostarthide \donothing
+\let \dostophide \donothing
+
+%D \macros
+%D {dostartgotolocation, dostopgotolocation,
+%D dostartgotorealpage, dostopgotorealpage}
+%D
+%D When we want to support hypertext buttons, again we have
+%D to deal with two concepts.
+%D
+%D \startitemize[packed,n]
+%D \item let \TEX\ highlight the text
+%D \item let the driver show us where to click
+%D \stopitemize
+%D
+%D The first approach is the most secure one. It gives us
+%D complete control over the visual appearance of hyper
+%D buttons. The second alternative lets the driver guess what
+%D part of the text needs highlighting. As long as we deal with
+%D not too complicated textual buttons, this is no problem.
+%D It's even a bit more efficient when we take long mid
+%D paragraph active regions into account. When we let \TEX\
+%D handle active sentences {\em for instance marked like this
+%D one}, we have to take care of line- and pagebreaks ourselve.
+%D However, it's no trivial matter to let a driver find out
+%D where things begin and end. Because most hyperlinks can be
+%D found in tables of contents and registers, the saving in
+%D terms of bytes can be neglected and the first approach is a
+%D clear winner.
+%D
+%D The most convenient way of cross||referencing is using named
+%D destinations. A more simple scheme is using page numbers as
+%D destinations. Because the latter alternative can often be
+%D implemented more efficient, and because we cannot be sure
+%D what scheme a driver supports, we always have to supply a
+%D pagenumber, even when we use named destinations.
+%D
+%D To enable a driver to find out what to make active, we have
+%D to provide begin and endpoints, so like with color, we use
+%D pairs of specials. The first scheme can be satisfied with
+%D proper dimensions of the areas to be made active.
+%D
+%D The interactive real work is done by the following four
+%D specials. The reason for providing the first one with both
+%D a label and a number, is a result of the quite poor
+%D implementation of \type{pdfmarks} in version 1.0 of
+%D Acrobat. Because only pagenumbers were supported as
+%D destination, we had to provide both labels (\DVIWINDO) and
+%D pagenumbers (\PDF). Some drivers use start stop pairs.
+%D
+%D \starttyping
+%D \dostartgotolocation {w} {h} {url} {file} {label} {page}
+%D \dostartgotorealpage {w} {h} {url} {file} {page}
+%D \stoptyping
+%D
+%D Their counterparts are:
+%D
+%D \starttyping
+%D \dostopgotolocation
+%D \dostopgotorealpage
+%D \stoptyping
+%D
+%D The internal alternative is used for system||generated
+%D links, the external one for user||generated links. The
+%D Uniform Resource Locator can be used to let the reader
+%D surf the net.
+
+\let \dostartgotolocation \gobblesixarguments
+\let \dostopgotolocation \donothing
+\let \dostartgotorealpage \gobblefourarguments
+\let \dostopgotorealpage \donothing
+
+%D One may wonder why jumps to page and location are not
+%D combined. By splitting them, we enable macro||packages to
+%D force the prefered alternative, while on the other hand
+%D drivers can pick up the alternative desired most.
+
+%D \macros
+%D {dostartgotoJS, doflushJSpreamble}
+%D
+%D Rather special is the option to include and execute
+%D JavaScript code. This is a typical \PDF\ option.
+%D
+%D \starttyping
+%D \dostartgotoJS {w} {h} {script}
+%D \stoptyping
+%D
+%D This not so standard \TEX\ feature should be used with
+%D care. Preamble scripts are flushed by
+%D
+%D \doflushJSpreamble {script}
+
+\let \dostartgotoJS \gobblethreearguments
+\let \dostopgotoJS \donothing
+\let \doflushJSpreamble \gobbleoneargument
+
+%D \macros
+%D {dostartthisislocation, dostopthisislocation,
+%D dostartthisisrealpage, dostopthisisrealpage}
+%D
+%D Before we can goto some location or page, we have to tell
+%D the system where it can be found. Because some drivers
+%D follow the \SGML\ approach of begin||end tags, we have to
+%D support pairs. A possible extension to this scheme is
+%D supplying coordinates for viewing the text.
+%D
+%D The opposite commands of \type{\dogotosomething} have only
+%D one argument:
+%D
+%D \starttyping
+%D \dostartthisislocation {label}
+%D \dostartthisisrealpage {page}
+%D \stoptyping
+%D
+%D These commands are accompanied by:
+%D
+%D \starttyping
+%D \dostopthisislocation
+%D \dostopthisisrealpage
+%D \stoptyping
+%D
+%D As with all interactive commands's they are installed as
+%D \type{and} category specials.
+
+\let \dostartthisislocation \gobbleoneargument
+\let \dostopthisislocation \donothing
+\let \dostartthisisrealpage \gobbleoneargument
+\let \dostopthisisrealpage \donothing
+
+%D In \CONTEXT\ we don't use the \type{\stopsomething}
+%D macros because we let \TEX\ take care of typographic
+%D issues.
+
+%D \macros
+%D {doresetgotowhereever}
+%D
+%D These and others need:
+
+\let \doresetgotowhereever \donothing
+
+%D \macros
+%D {dostartexecutecommand, dostopexecutecommand}
+%D
+%D The actual behavior of the next pair of commands depends
+%D much on the viewing engine. Therefore one cannot depend
+%D too much on their support.
+%D
+%D \starttyping
+%D \dostartexecutecommand {w} {h} {command} {options}
+%D \stoptyping
+%D
+%D At least the next commands are supported (more examples
+%D can be found in \type {spec-fdf.tex}:
+%D
+%D \startlinecorrection\setupalign[middle]\leavevmode
+%D \starttable[|l|l|]
+%D \HL
+%D \NC \bf command \NC \bf action \NC\SR
+%D \HL
+%D \NC first \NC go to the first page \NC\FR
+%D \NC previous \NC go to the previous page \NC\MR
+%D \NC next \NC go to the next page \NC\MR
+%D \NC last \NC go to the last page \NC\MR
+%D \NC backward \NC go back to the link list \NC\MR
+%D \NC forward \NC go forward in the link list \NC\MR
+%D \NC print \NC enter print mode \NC\MR
+%D \NC exit \NC exit viewer \NC\MR
+%D \NC close \NC close document \NC\MR
+%D \NC enter \NC enter viewer \NC\MR
+%D \NC help \NC show help on the viewer \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D Options are to be passed as a comma separated list of
+%D assignments.
+
+\let \dostartexecutecommand \gobblefourarguments
+\let \dostopexecutecommand \donothing
+
+%D \macros
+%D {dostartobject,
+%D dostopobject,
+%D doresetobjects,
+%D doinsertobject}
+%D
+%D Reuse of object can reduce the output filesize
+%D considerably. Reusable objects are implemented with:
+%D
+%D \starttyping
+%D \dostartobject{class}{name}{width}{height}{depth}
+%D some typeset material
+%D \dostopobject
+%D \stoptyping
+%D
+%D \starttyping
+%D \doinsertobject{class}{name}
+%D \stoptyping
+%D
+%D The savings can be huge in interactive texts. The next macro needs
+%D to be called after a graphic is inserted (in order to clean up
+%D global references).
+%D
+%D \starttyping
+%D \doresetobjects
+%D \stoptyping
+
+\let \dostartobject \gobblefourarguments
+\let \dostopobject \donothing
+\let \doinsertobject \gobbletwoarguments
+\let \doresetobjects \donothing
+
+%D \macros
+%D {doregisterfigure, doregisterfigurecolor}
+%D
+%D Images can be objects as well and it's up to the driver to
+%D handle this. Alternative images are also up to the driver,
+%D and the next macro tells the driver that the previous image
+%D is somehow followed by another and that both have to be
+%D handled together. This is a rather fuzzy model, but for the
+%D moment it suits its purpose: low res screen versions combined
+%D with high res printable ones.
+
+\let \doregisterfigure \gobbletwoarguments
+\let \doregisterfigurecolor \gobbleoneargument
+
+% %D \macros
+% %D {dogetobjectreference}
+% %D
+% %D For very special purposes, one can ask for the internal
+% %D reference to the object. Beware!
+%
+% \let \dogetobjectreference \gobblethreearguments
+%
+% %D The first argument is the name, the second a macro that
+% %D gets the associated value.
+
+%D \macros
+%D {dostartrunprogram, dostoprunprogram,
+%D dostartgotoprofile, dostopgotoprofile,
+%D dobeginofprofile,
+%D doendofprofile}
+%D
+%D These specials are still experimental. They are not yet
+%D supported by the programs the way they should be.
+%D
+%D {\em --- still undocumented ---}
+
+\let \dostartrunprogram \gobblefourarguments
+\let \dostoprunprogram \donothing
+\let \dostartgotoprofile \gobblethreearguments
+\let \dostopgotoprofile \donothing
+\let \dobeginofprofile \gobblefourarguments
+\let \doendofprofile \donothing
+
+%D \macros
+%D {doinsertbookmark}
+%D
+%D Bookmarks, that is viewer generated tables of contents, are
+%D a strange phenomena, mainly because \TEX\ can provide
+%D whatever kind of table in much better quality.
+
+\let \doinsertbookmark \gobblefourarguments
+
+%D This special is called as:
+%D
+%D \starttyping
+%D \doinstallbookmark {level} {nofsubentries} {text} {page} {open}
+%D \stoptyping
+%D
+%D This definition is very \PDF\ oriented, so for more
+%D information we kindly refer to the \PDF\ manuals.
+
+%D \macros
+%D {dosetpagetransition}
+%D
+%D In presentations, fancy page transitions can, at least for a
+%D short moment, let the audience focus at the screen. Like the
+%D previous one, this special is very \PDF.
+%D
+%D \starttyping
+%D \dosetpagetransition{dissolve}{0}
+%D \stoptyping
+%D
+%D Transitions have symbolic names, like dissolve, box, split,
+%D blinds, wipe and glitter. The second argument determines
+%D the wait time (unless zero).
+
+\let \dosetpagetransition \gobbletwoarguments
+
+%D \macros
+%D {dopresettextfield,dopresetlinefield,
+%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield,
+%D dopresetbuttonfield,dopresetcheckfield,
+%D dopresetradiofield,dopresetradiorecord}
+%D
+%D The special drivers are programmed independant from their
+%D calling macros are thereby use the standard \TEX\ way of
+%D passing parameters. Unfortunately fields often have more
+%D than nine characteristics, so we pack some arguments in one.
+%D
+%D \starttyping
+%D \dopresettextfield / \dopresetlinefield
+%D {name} {width} {height} {default} {length}
+%D {style,color} {options} {alignment} {actions}
+%D
+%D \dopresetchoicefield / \dopresetpopupfield / \dopresetcombofield
+%D {name} {width} {height} {default}
+%D {style,color} {options} {values} {actions}
+%D
+%D \dopresetpushfield
+%D {name} {width} {height} {default}
+%D {options} {values} {actions}
+%D
+%D \dopresetcheckfield
+%D {name} {width} {height} {default}
+%D {options} {values} {actions}
+%D
+%D \dopresetradiofield
+%D {name} {width} {height} {default}
+%D {options} {parent} {values} {actions}
+%D
+%D \dopresetradiorecord
+%D {name} {top} {options} {kids} {actions}
+%D \stoptyping
+
+\let \dopresetlinefield \gobbleninearguments
+\let \dopresettextfield \gobbleninearguments
+\let \dopresetchoicefield \gobbleeightarguments
+\let \dopresetpopupfield \gobbleeightarguments
+\let \dopresetcombofield \gobbleeightarguments
+\let \dopresetpushfield \gobblesevenarguments
+\let \dopresetcheckfield \gobblesevenarguments
+\let \dopresetradiofield \gobbleeightarguments
+\let \dopresetradiorecord \gobblefourarguments
+
+%D \macros
+%D {dodefinefieldset,dogetfieldset,doiffieldset}
+%D
+%D Field sets, used in resetting and submitting, are handled
+%D by:
+
+\let \dodefinefieldset \gobbletwoarguments
+\let \dogetfieldset \gobbleoneargument
+\let \doiffieldset \gobbletwoarguments
+
+%D \macros
+%D {dosetfieldstatus}
+%D
+%D For practical reasons we set some field characteristics
+%D using:
+%D
+%D \starttyping
+%D \dosetfieldstatus {mode} {parent} {kids} {root}
+%D \stoptyping
+
+\let \dosetfieldstatus \gobblefourarguments
+
+%D with:
+
+\def\fieldlonermode {0} % no \chardef here
+\def\fieldparentmode{1} % no \chardef here
+\def\fieldchildmode {2} % no \chardef here
+\def\fieldcopymode {3} % no \chardef here
+
+%D \macros
+%D {doregistercalculationset}
+%D
+%D We can define a calculation order list with:
+%D
+%D \starttyping
+%D \doregistercalculationset {set identifier}
+%D \stoptyping
+
+\let \doregistercalculationset \gobbleoneargument
+
+%D \macros
+%D {doinsertcomment, doflushcomments}
+%D
+%D Not so much out of need, but to be complete, we also
+%D implement text annotations, so called comment:
+%D
+%D \starttyping
+%D \doinsertcomment
+%D {title} {width} {height} {color} {open} {symbol} {collect} {data}
+%D \stoptyping
+%D
+%D When enables, comments can be collected and flushed:
+%D
+%D \starttyping
+%D \doflushcomments
+%D \stoptyping
+
+\let \doinsertcomment \gobbleeightarguments
+\let \doflushcomments \donothing
+
+%D \macros
+%D {dostarttransparency,dostoptransparency}
+%D
+%D \starttyping
+%D \dostarttransparency{fraction}{type}
+%D \dostoptransparency
+%D \stoptyping
+%D
+%D Although in \CONTEXT\ transparency is closely integrated
+%D in the color drivers, in the end it is an independent
+%D feature.
+
+\let \dostarttransparency \gobbletwoarguments
+\let \dostoptransparency \donothing
+
+%D \macros
+%D {doattachfile}
+%D
+%D \starttyping
+%D \doattachfile{title}{width}{height}{depth}{color}{symbol}{filename}{source}
+%D \stoptyping
+
+\let \doattachfile \gobbleeightarguments
+
+%D Experimental (properties):
+
+\let \dostartviewerlayer \gobbleoneargument
+\let \dostopviewerlayer \donothing
+\let \dodefineviewerlayer \gobblefivearguments
+\let \domakeviewerlayerlist \gobbleoneargument
+
+\let \doinsertrenderingwindow \gobblefourarguments
+\let \doinsertrendering \gobblefourarguments
+\let \doinsertrenderingobject \gobblefourarguments
+\let \doinsertrenderingobject \gobblefourarguments
+
+\let \dostartfonteffect \gobblethreearguments
+\let \dostopfonteffect \donothing
+
+%D From now on, mapfile loading is also a special; we assume the
+%D more or less standard dvips syntax.
+
+\let \doresetmapfilelist \donothing
+\let \doloadmapfile \gobbletwoarguments % + - = | filename
+\let \doloadmapline \gobbletwoarguments % + - = | fileline
+
+%D \macros
+%D {ifusepagedestinations}
+%D
+%D In \PDF\ version 1.0 only page references were supported,
+%D while in \DVIWINDO\ 1.N only named references were accepted.
+%D Therefore \CONTEXT\ supports both methods of referencing. In
+%D \PDF\ version 1.1 named destinations arrived. Lack of
+%D continuous support of version 1.1 viewers for \MSDOS\
+%D therefore sometimes forces us to prefer page references. As
+%D a bonus, they are faster too and have no limitations. How
+%D fortunate we were having both mechanisms available when the
+%D version 3.0 (\PDF\ version 1.2) viewers proved to be too
+%D bugged to support named destinations.
+
+\newif\ifusepagedestinations
+
+%D \macros
+%D {ifhighlighthyperlinks}
+%D
+%D The next switch can be used to make user hyperlinks are
+%D not highlighted when clicked on.
+
+\newif\ifhighlighthyperlinks
+
+%D \macros
+%D {ifgotonewwindow}
+%D
+%D To make the {\em goto previous jump} feature more
+%D convenient when using more than one file, it makes sense
+%D to force the viewer to open a new window for each file
+%D opened.
+
+\newif\ifgotonewwindow
+
+%D \macros
+%D {jobsuffix}
+%D
+%D By default, \TEX\ produces \DVI\ files which can be
+%D converted to other filetypes. Sometimes it is handy to
+%D know what the target file will be. In other driver
+%D modules we wil set \type {\jobsuffix} to \type {pdf}.
+
+% this will become a mode
+
+\def\jobsuffix{pdf}
+
+\ifdefined\resetsystemmode \else
+ \let\setsystemmode \gobbleoneargument
+ \let\resetsystemmode\gobbleoneargument
+\fi
+
+\def\setjobsuffix#1%
+ {\resetsystemmode\jobsuffix
+ \edef\jobsuffix{#1}%
+ \setsystemmode\jobsuffix}
+
+%D \macros
+%D {everyresetspecials}
+%D
+%D Now what will this one do? We'll see in a few lines.
+
+\newtoks\everyresetspecials
+
+\appendtoksonce
+ \ifdefined\setjobsuffix\setjobsuffix{pdf}\fi
+\to \everyresetspecials
+
+\def\defineoutput{\dodoubleargument\dodefineoutput}
+
+\def\usespecials [#1]{}
+\def\dodefineoutput[#1][#2]{}
+\def\setupoutput [#1]{}
+
+\protect \endinput
diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua
new file mode 100644
index 000000000..2488db7f7
--- /dev/null
+++ b/tex/context/base/back-pdf.lua
@@ -0,0 +1,189 @@
+if not modules then modules = { } end modules ['back-pdf'] = {
+ version = 1.001,
+ comment = "companion to back-pdf.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>This module implements a couple of cleanup methods. We need these
+in order to meet the <l n='pdf'/> specification. Watch the double
+parenthesis; they are needed because otherwise we would pass more
+than one argument to <l n='tex'/>.</p>
+--ldx]]--
+
+local type, next = type, next
+local char, byte, format, gsub = string.char, string.byte, string.format, string.gsub
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+local texsprint, texwrite = tex.sprint, tex.write
+
+ctxcatcodes = tex.ctxcatcodes
+
+pdf = pdf or { } -- global
+
+backends.pdf = pdf -- registered
+
+function pdf.cleandestination(str)
+ texsprint((gsub(str,"[%/%#%<%>%[%]%(%)%-%s]+","-")))
+end
+
+function pdf.cleandestination(str)
+ texsprint((gsub(str,"[%/%#%<%>%[%]%(%)%-%s]+","-")))
+end
+
+function pdf.sanitizedstring(str)
+ texsprint((gsub(str,"([\\/#<>%[%]%(%)])","\\%1")))
+end
+
+function pdf.hexify(str)
+ texwrite("feff")
+ for b in utfvalues(str) do
+ if b < 0x10000 then
+ texwrite(format("%04x",b))
+ else
+ texwrite(format("%04x%04x",b/1024+0xD800,b%1024+0xDC00))
+ end
+ end
+end
+
+function pdf.utf8to16(s,offset) -- derived from j. sauter's post on the list
+ offset = (offset and 0x110000) or 0 -- so, only an offset when true
+ texwrite(char(offset+254,offset+255))
+ for c in utfvalues(s) do
+ if c < 0x10000 then
+ texwrite(char(offset+c/256,offset+c%256))
+ else
+ c = c - 0x10000
+ local c1, c2 = c / 1024 + 0xD800, c % 1024 + 0xDC00
+ texwrite(char(offset+c1/256,offset+c1%256,offset+c2/256,offset+c2%256))
+ end
+ end
+end
+
+pdf.nodeinjections = pdf.nodeinjections or { } -- we hash elsewhere
+pdf.codeinjections = pdf.codeinjections or { } -- we hash elsewhere
+pdf.registrations = pdf.registrations or { } -- we hash elsewhere
+
+local pdfliteral, register = nodes.pdfliteral, nodes.register
+
+local nodeinjections = pdf.nodeinjections
+local codeinjections = pdf.codeinjections
+local registrations = pdf.registrations
+
+function nodeinjections.rgbcolor(r,g,b)
+ return register(pdfliteral(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b)))
+end
+
+function nodeinjections.cmykcolor(c,m,y,k)
+ return register(pdfliteral(format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k)))
+end
+
+function nodeinjections.graycolor(s)
+ return register(pdfliteral(format("%s g %s G",s,s)))
+end
+
+function nodeinjections.spotcolor(n,f,d,p)
+ if type(p) == "string" then
+ p = p:gsub(","," ") -- brr misuse of spot
+ end
+ return register(pdfliteral(format("/%s cs /%s CS %s SCN %s scn",n,n,p,p)))
+end
+
+function nodeinjections.transparency(n)
+ return register(pdfliteral(format("/Tr%s gs",n)))
+end
+
+function nodeinjections.overprint()
+ return register(pdfliteral("/GSoverprint gs"))
+end
+
+function nodeinjections.knockout()
+ return register(pdfliteral("/GSknockout gs"))
+end
+
+function nodeinjections.positive()
+ return register(pdfliteral("/GSpositive gs"))
+end
+
+function nodeinjections.negative()
+ return register(pdfliteral("/GSnegative gs"))
+end
+
+local effects = {
+ normal = 0,
+ inner = 0,
+ outer = 1,
+ both = 2,
+ hidden = 3,
+}
+
+function nodeinjections.effect(stretch,rulethickness,effect)
+ -- always, no zero test (removed)
+ rulethickness = number.dimenfactors["bp"]*rulethickness
+ effect = effects[effect] or effects['normal']
+ return register(pdfliteral(format("%s Tc %s w %s Tr",stretch,rulethickness,effect))) -- watch order
+end
+
+function nodeinjections.startlayer(name)
+ return register(pdfliteral(format("/OC /%s BDC",name)))
+end
+
+function nodeinjections.stoplayer()
+ return register(pdfliteral("EMC"))
+end
+
+function nodeinjections.switchlayer(name)
+ return register(pdfliteral(format("EMC /OC /%s BDC",name)))
+end
+
+-- code
+
+function codeinjections.insertmovie(spec) -- width, height, factor, repeat, controls, preview, label, foundname
+ local width, height = spec.width, spec.height
+ local options, actions = "", ""
+ if spec["repeat"] then
+ actions = actions .. "/Mode /Repeat "
+ end
+ if spec.controls then
+ actions = actions .. "/ShowControls true "
+ else
+ actions = actions .. "/ShowControls false "
+ end
+ if spec.preview then
+ options = options .. "/Poster true "
+ end
+ if actions ~= "" then
+ actions= "/A <<" .. actions .. ">>"
+ end
+ return format( -- todo: doPDFannotation
+ "\\doPDFannotation{%ssp}{%ssp}{/Subtype /Movie /Border [0 0 0] /T (movie %s) /Movie << /F (%s) /Aspect [%s %s] %s>> %s}",
+ width, height, spec.label, spec.foundname, factor * width, factor * height, options, actions
+ )
+end
+
+local s_template_g = "\\dodoPDFregistergrayspotcolor{%s}{%s}{%s}{%s}{%s}" -- n f d p s (p can go away)
+local s_template_r = "\\dodoPDFregisterrgbspotcolor {%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p r g b
+local s_template_c = "\\dodoPDFregistercmykspotcolor{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p c m y k
+local m_template_g = "\\doPDFregistergrayindexcolor{%s}{%s}{%s}{%s}{%s}" -- n f d p s (p can go away)
+local m_template_r = "\\doPDFregisterrgbindexcolor {%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p r g b
+local m_template_c = "\\doPDFregistercmykindexcolor{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p c m y k
+local s_template_e = "\\doPDFregisterspotcolorname{%s}{%s}" -- name, e -- todo in new backend: gsub(e," ","#20")
+local t_template = "\\presetPDFtransparencybynumber{%s}{%s}{%s}" -- n, a, t
+
+function registrations.grayspotcolor (n,f,d,p,s) states.collect(format(s_template_g,n,f,d,p,s)) end
+function registrations.rgbspotcolor (n,f,d,p,r,g,b) states.collect(format(s_template_r,n,f,d,p,r,g,b)) end
+function registrations.cmykspotcolor (n,f,d,p,c,m,y,k) states.collect(format(s_template_c,n,f,d,p,c,m,y,k)) end
+function registrations.grayindexcolor(n,f,d,p,s) states.collect(format(m_template_g,n,f,d,p,s)) end
+function registrations.rgbindexcolor (n,f,d,p,r,g,b) states.collect(format(m_template_r,n,f,d,p,r,g,b)) end
+function registrations.cmykindexcolor(n,f,d,p,c,m,y,k) states.collect(format(m_template_c,n,f,d,p,c,m,y,k)) end
+function registrations.spotcolorname (name,e) states.collect(format(s_template_e,name,e)) end -- texsprint(ctxcatcodes,format(s_template_e,name,e))
+function registrations.transparency (n,a,t) states.collect(format(t_template ,n,a,t)) end -- too many, but experimental anyway
+
+-- eventually we need to load this runtime
+--
+-- backends.install((environment and environment.arguments and environment.arguments.backend) or "pdf")
+--
+-- but now we need to force this as we also load the pdf tex part which hooks into all kind of places
+
+backends.install("pdf")
diff --git a/tex/context/base/back-pdf.tex b/tex/context/base/back-pdf.tex
new file mode 100644
index 000000000..b7de1051f
--- /dev/null
+++ b/tex/context/base/back-pdf.tex
@@ -0,0 +1,3226 @@
+%D \module
+%D [ file=back-pdf,
+%D version=2009.04.15,
+%D title=\CONTEXT\ Backend Macros,
+%D subtitle=\PDF,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Backend Macros / PDF}
+
+\registerctxluafile{back-pdf}{1.001}
+
+\unprotect
+
+%D When dealing with resources, we share the resource dictionaries
+%D between all xforms. This is inefficent in the sense that when no
+%D resources are used, redundant entries take space, but on the other
+%D hand we save redundant dictionaries so it's a nice compromise. Maybe
+%D that in \LUATEX\ I will reimplement most of the code here anyway.
+
+%D Initialization of fields is tricky. If a field has no
+%D value, it is kind of not there. If ResetForm is used, the
+%D default is assigned, but pushbuttons are spoiled. Adding a
+%D \type {/MK} dictionary helps, but gives ugly down
+%D appearances (displaced with background). What a mess.
+%D Also, in order to get at least something, the \type {/AS}
+%D key should be provided.
+
+%D A couple of variables:
+
+\newtoks \everybackendshipout
+\newtoks \everylastbackendshipout
+
+\let\lastPDFaction\empty
+
+\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi
+\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi
+\ifdefined\everygoto \else \newtoks\everygoto \fi
+\ifdefined\everysetfield \else \newtoks\everysetfield \fi
+
+%D A few helpers:
+
+\let\PDFcode \pdfliteral
+\def\PDFcontentcode{\pdfliteral}
+\def\PDFdirectcode {\pdfliteral direct}
+
+%D \macros
+%D {PDFobjref}
+%D
+%D Just a shortcut.
+
+% Watch out, \def\PDFobjref#1{\purenumber#1 0 R} also works, but not when
+% #1 == \the\whatever
+
+\def\PDFobjref#1{\purenumber{#1} 0 R}
+
+%D \macros
+%D {PDFswapdir}
+
+\let\PDFswapdir\empty \def\PDFswapdir{\ifcase\inlinedirection\or\or-\fi}
+
+% the pdf spec changed cq. viewers started behaving differently / 5+
+
+\chardef\overcomePDFpage\plusone % page numbers/ beware: optimizers remove this one
+\chardef\overcomePDFpage\plustwo % page:number
+\chardef\overcomePDFpage\plusthree % pdftex page ref feature
+
+%D \macros
+%D {setPDFdestination}
+%D
+%D \PDF\ destinations should obey the specifications laid down
+%D in the \PDF\ reference manual. The next macro strips illegal
+%D characters from the destination name.
+
+\def\setPDFdestination #1{\xdef\PDFdestination{\ctxlua{pdf.cleandestination("\luaescapestring{#1}")}}}
+\def\hexifiedPDFstring #1{\ctxlua{pdf.hexify("\luaescapestring{#1}")}}
+\def\sanitizePDFencoding#1\to#2{\xdef#2{\ctxlua{pdf.hexify("\luaescapestring{#1}")}}}
+
+%D
+
+\def\appendtopdfpageresources #1{\normalexpanded{\global\pdfpageresources{#1\the\pdfpageresources}}}
+\def\appendtopdfpageattributes #1{\normalexpanded{\global\pdfpageattr {#1\the\pdfpageattr }}}
+\def\appendtopdfpagesattributes#1{\normalexpanded{\global\pdfpagesattr {#1\the\pdfpagesattr }}}
+\def\appendtopdfcatalog {\pdfcatalog}
+\def\appendtopdfinfo {\pdfinfo}
+
+\def\resetpdfpageattributes{\global\pdfpageattr\emptytoks}
+\def\resetpdfpageresources {\global\pdfpageresources\emptytoks}
+
+%D Due to the fact that \PDFTEX\ has a different concept of
+%D page attributes, we need:
+
+\appendtoksonce
+ \resetpdfpageattributes
+ \resetpdfpageresources
+\to \everyaftershipout
+
+%D \macros
+%D {insertpdfaction,
+%D insertpdfannotation,
+%D insertpdfannotationobject,
+%D createpdfdictionaryobject,
+%D createpdfarrayobject,
+%D defaultobjectreference,
+%D doPDFgetobjectreference}
+%D
+%D This module deals with \PDF\ support, including fill||in
+%D forms. Before we present the largely unreadable bunch of
+%D macros, we introduce the here||not||defined low level
+%D interface macros. These must be provided by the special
+%D drivers \type{pdf} (\ACROBAT) and \type{tpd} (\PDFTEX).
+%D
+%D \starttyping
+%D \insertpdfaction #1#2#3 width height action
+%D \insertpdfannotation #1#2#3 width height data
+%D \createpdfannotationobject #1#2#3#4#5 class name width height data
+%D \createpdfdictionaryobject #1#2#3 class name data
+%D \createpdfarrayobject #1#2#3 class name data
+%D
+%D \defaultobjectreference #1#2 class name
+%D \doPDFgetobjectreference #1#2#3 class name \PDFobjectreference
+%D \doPDFgetobjectpagereference #1#2#3 class name \PDFobjectreference
+%D \stoptyping
+%D
+%D The keywords reflect their use. For the moment we stick to
+%D keywords, because that way at we get an indication of what
+%D we're doing.
+
+\def\createpdfdictionaryobject#1#2#3%
+ {\flushatshipout
+ {\immediate\pdfobj{<< #3 >>}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastobj}}}
+
+\def\createpdfarrayobject#1#2#3%
+ {\flushatshipout
+ {\immediate\pdfobj{[ #3 ]}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastobj}}}
+
+\def\createpdfannotationobject#1#2#3#4#5%
+ {\insertpdfannotation{#3}{#4}{#5}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastannot}}
+
+\def\createpdfactionobject#1#2#3#4#5%
+ {\insertpdfaction{#3}{#4}{#5}%
+ \dosetobjectreference{#1}{#2}{\the\pdflastannot}}
+
+%D \macros
+%D {insertpdfaction,insertpdfannotation,ifsharePDFactions}
+%D
+%D Next we handle annotations. All link annotations are
+%D implemented using the action dictionary. This enables us to
+%D use multiple actions. The second macro is for instance
+%D used for movie inclusion.
+
+\newif\ifsharePDFactions \sharePDFactionstrue
+
+\def\insertpdfaction#1#2#3%
+ {\xdef\lastPDFcontent{#3}%
+ \ifcollectreferenceactions
+ \global\let\lastPDFaction\lastPDFcontent
+ \else
+ \ifsharePDFactions
+ \ifcase\similarreference\relax
+ \xdef\lastPDFaction{<<\lastPDFcontent>>}%
+ \or
+ \immediate\pdfobj{<<\lastPDFcontent>>}%
+ \xdef\lastPDFaction{\PDFobjref\pdflastobj}%
+ \else
+ % leave \lastPDFaction untouched
+ \fi
+ \else
+ \xdef\lastPDFaction{<<\lastPDFcontent>>}%
+ \fi
+ \pdfannot
+ width #1 height #2 depth \zeropoint
+ {/Subtype /Link
+ /Border [0 0 0]
+ \ifhighlighthyperlinks \else /H /N \fi
+ /A \lastPDFaction}%
+ \fi}
+
+\def\insertpdfannotation#1#2#3%
+ {\pdfannot width #1 height #2 depth \zeropoint{#3}}
+
+%D \macros
+%D {doPDFbookmark}
+%D
+%D Well, isn't the next one ugly? Thanks to the \PDF\
+%D standard.
+
+\def\doPDFbookmark#1#2#3#4#5% to be renamed
+ {\doPDFgetpagereference{#4}\PDFobjectreference
+ \pdfoutline
+ user {<</S /GoTo /D [\PDFobjectreference\space\PDFpageviewwrd]>>}%
+ \ifcase#2 \else count \ifcase#5-\fi#2 \fi
+ {#3}}
+
+%D For special (\METAPOST) effects, we need to build
+%D resource dictionaries. Here is the framework.
+
+\let\docuPDFextgstates \empty
+\let\docuPDFcolorspaces\empty
+\let\docuPDFshades \empty
+
+\def\checkPDFextgstates
+ {\ifx\docuPDFextgstates\empty \else
+ \ifnum\realpageno=\lastpage\relax
+ \createpdfdictionaryobject{FDF}{docuextgstates}{\docuPDFextgstates}%
+ \fi
+ \doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference
+ \appendtopdfpageresources{/ExtGState \PDFobjectreference}%
+ \fi}
+
+\def\checkPDFcolorspaces
+ {\ifx\docuPDFcolorspaces\empty \else
+ \ifnum\realpageno=\lastpage\relax
+ \createpdfdictionaryobject{FDF}{colorspaces}{\docuPDFcolorspaces}%
+ \fi
+ \doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference
+ \appendtopdfpageresources{/ColorSpace \PDFobjectreference}%
+ \fi}
+
+\def\checkPDFshades
+ {\ifx\docuPDFshades\empty \else
+ \ifnum\realpageno=\lastpage\relax
+ \createpdfdictionaryobject{FDF}{docushades}{\docuPDFshades}%
+ \fi
+ \doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference
+ \appendtopdfpageresources{/Shading \PDFobjectreference}%
+ \fi}
+
+\def\appendtoPDFdocumentextgstates #1{\xdef\docuPDFextgstates {\docuPDFextgstates \space#1}}
+\def\appendtoPDFdocumentcolorspaces#1{\xdef\docuPDFcolorspaces{\docuPDFcolorspaces\space#1}}
+\def\appendtoPDFdocumentshades #1{\xdef\docuPDFshades {\docuPDFshades \space#1}}
+
+%D Page actions:
+
+\let\lastpdfopenaction \empty
+\let\lastpdfcloseaction\empty
+
+\def\dosetupopenaction {\appendtopdfcatalog{/OpenAction <<\lastPDFaction>>}}
+\def\dosetupcloseaction{\appendtopdfcatalog{/CloseAction <<\lastPDFaction>>}}
+
+\def\dosetupopenpageaction {\glet\lastpdfopenaction \lastPDFaction}
+\def\dosetupclosepageaction{\glet\lastpdfcloseaction\lastPDFaction}
+
+\def\checkPDFpageactions
+ {\iflocation % important since direct
+ \donefalse
+ \ifx\lastpdfopenaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi
+ \ifx\lastpdfcloseaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi
+ \ifdone
+ \appendtopdfpageattributes
+ {/AA <<\if!!donea/O <<\lastpdfopenaction >> \fi
+ \if!!doneb/C <<\lastpdfcloseaction>> \fi>>}%
+ \fi
+ \glet\lastpdfopenaction \empty
+ \glet\lastpdfcloseaction\empty
+ \fi}
+
+%D \macros
+%D {ifPDFstrokecolor}
+%D
+%D We can reduce the filesize a bit by setting the next switch
+%D to false. The amount of reduction depends on the use of
+%D color, but don't expect more than a few percent. Zip
+%D compression is already rather efficient in itself.
+
+\newif\ifPDFstrokecolor \PDFstrokecolortrue
+
+%D When submitting forms, we need to communicate the format.
+
+\chardef\submitoutputformat=0 % 0=unknown 1=HTML 2=FDF 3=XML
+
+\def\setsubmitoutputformat#1%
+ {\doifinsetelse{#1}{FDF,fdf}
+ {\chardef\submitoutputformat2}
+ {\doifinsetelse{#1}{XML,xml}
+ {\chardef\submitoutputformat3}
+ {\chardef\submitoutputformat1}}%
+ \relax}
+
+%D Handy to have this available asap:
+
+\ifdefined\everyPDFxform \newtoks\everyPDFxform \fi
+\ifdefined\everyPDFximage \newtoks\everyPDFximage \fi
+
+% once we can be sure that the latest versions of pdftex are
+% available we can use:
+%
+% \pdfobj reserveobjnum \edef\one{\the\pdflastobj}
+% \pdfobj reserveobjnum \edef\two{\the\pdflastobj}
+%
+% \pdfobj useobjnum \one {x}
+% \pdfobj useobjnum \two {x}
+%
+% we then can rewrite part of spec-fdf because the other drivers
+% already support symbolic references
+
+%D \macros
+%D {jobsuffix}
+%D
+%D Being one of the first typographical systems able to support
+%D advances \PDF\ support, \TEX\ is also one of the first
+%D systems to produce high quality \PDF\ code directly. Thanks
+%D to Han The Thanh c.s. the \TEX\ community can leap forward
+%D once again.
+%D
+%D One important characteristic of \PDFTEX\ is that is can
+%D produce standard \DVI\ code as well as \PDF\ code. This
+%D enables us to use one format file to support both output
+%D formats.
+
+%D All modules in this group use specials to tell drivers what
+%D non||\TEX\ actions to take. Because from the \TEX\ point of
+%D view, there is no difference between \DVI\ and \PDF, we
+%D therefore only have to bend the \DVI\ driver support into
+%D \PDF\ support. Technically spoken, specials no longer serve
+%D a purpose, except from ending up as comment in the \PDF\
+%D file.
+%D
+%D Before we continue we need to make sure if indeed those
+%D \PDFTEX\ primitives are permitted. If no primitives are
+%D available, we just stop reading any further.
+
+\pdfoutput = 1
+\pdfhorigin = 1 true in
+\pdfvorigin = 1 true in
+\pdfimageresolution = 300
+\pdfpkresolution = 600
+\pdfdecimaldigits = 10
+\pdfinclusionerrorlevel = 0
+\pdfminorversion = 5
+%pdfuniqueresname = 1
+
+\def\PDFversion{1.\number\pdfminorversion}
+
+%D For some internal testing we need to know the output
+%D suffix.
+
+\setjobsuffix{pdf}
+
+%D \macros
+%D {dosetuppaper}
+%D
+%D If we don't set the paper size, \PDFTEX\ will certainly do
+%D it in a way we don't want, therefore we need:
+
+\def\dosetuppaper#1#2#3%
+ {\global\pdfpagewidth #2\relax
+ \global\pdfpageheight#3\relax}
+
+%D \macros
+%D {doloadmapfile,doloadmapline,doresetmapfilelist}
+
+\def\doresetmapfilelist
+ {\global\let\doresetmapfilelist\relax
+ \pdfmapfile{original-empty.map}}
+
+\def\doloadmapfile #1#2{\pdfmapfile{#1#2}}
+\def\doloadmapline #1#2{\pdfmapline{#1#2}}
+
+%D nasty but needed
+
+\appendtoksonce \loadallfontmapfiles \to \everyPDFximage
+\appendtoksonce \loadallfontmapfiles \to \everyPDFxform
+
+%D left overs:
+
+ \let\currentmovie\s!unknown
+
+ \def\doPDFinsertmov
+ {\bgroup
+ \xdef\currentmovie{\@@DriverImageLabel}%
+ \PointsToBigPoints\@@DriverImageWidth \width
+ \PointsToBigPoints\@@DriverImageHeight\height
+ \let\pdf@@options\empty
+ \let\pdf@@actions\empty
+ \donefalse
+ \expanded{\processallactionsinset[\@@DriverImageOptions]}
+ [\v!controls=>\donetrue,
+ \v!repeat=>\edef\pdf@@actions{\pdf@@actions /Mode /Repeat },
+ \v!preview=>\edef\pdf@@options{\pdf@@options /Poster true }]%
+ \edef\pdf@@actions{\pdf@@actions /ShowControls \ifdone true\else false\fi}%
+ \insertpdfannotation\@@DriverImageWidth\@@DriverImageHeight
+ {/Subtype /Movie
+ /Border [0 0 0]
+ /T (movie \currentmovie)
+ /Movie << /F (\@@DriverImageFile) /Aspect [\width\space\height] \pdf@@options >>
+ /A << \pdf@@actions >>}%
+ \egroup}
+
+%D \macros
+%D {doinsertsoundtrack}
+%D
+%D We use numbers instead of labels to keep track of sounds.
+
+\let\currentsound\s!unknown
+
+\def\doinsertsoundtrack#1#2#3%
+ {\bgroup
+ \xdef\currentsound{#2}%
+ \let\pdf@@actions\empty
+ \@EA\processallactionsinset\@EA
+ [#3]
+ [\v!repeat=>\edef\pdf@@actions{\pdf@@actions /Mode /Repeat }]%
+ \collectdriverresource
+ %\flushatshipout % since it can be buried in a chained box
+ {\insertpdfannotation{0pt}{0pt}
+ {/Subtype /Movie
+ /Border [0 0 0]
+ /T (sound \currentsound)
+ /Movie <</F (#1)>>%
+ \ifx\pdf@@actions\empty\else/A << \pdf@@actions >>\fi}}%
+ \egroup}
+
+%D \macros
+%D {doPDFattachfile}
+
+\def\doPDFfilestreamobject#1#2#3#4%
+ {}
+
+\def\doPDFfilestreamidentifier#1%
+ {0}
+
+\def\doPDFgetfilestreamreference#1#2%
+ {0 0 R}
+
+\def\doattachfile#1#2#3#4#5#6#7#8%
+ {\bgroup % title width height color symbol file
+ \edefconvertedargument\PDFfile{#8}%
+ % beware: the symbol may (indirectly) use the file
+ % reference when typesetting the object number;
+ \presetPDFsymbolappearance{#5}{#6}{#2}{#3}{#4}% sets width/height
+ \startPDFsymbolappearance
+ \doPDFembedfile\PDFfile{#7}{#8}%
+ \doPDFgetembeddedfilereference\PDFfile\PDFobjectreference
+ \setFDFlayer\@@DriverAttachmentLayer
+ \insertpdfannotation{\width}{\totalheight}
+ {/Subtype /FileAttachment
+ /FS \PDFobjectreference\space
+ /Contents (#1)
+ \PDFsymbol
+ \FDFlayer
+ \PDFattributes}%
+ \stopPDFsymbolappearance
+ \egroup}
+
+% semi-public
+
+\def\doPDFembedfile#1#2#3% symbolic name | filename | user name
+ {\edefconvertedargument\PDFfile{#1}%
+ \doifnotflagged{a:\PDFfile}%
+ {\doPDFfilestreamobject{PDFEF}{\PDFfile}{#2}{#3}%
+ \doglobal\setflag{a:\PDFfile}}}
+
+\def\doPDFgetembeddedfilereference#1#2%
+ {\edefconvertedargument\PDFfile{#1}%
+ \doPDFgetobjectreference{PDFEF}\PDFfile#2}
+
+\def\doPDFgetembeddedfilestreamreference#1#2%
+ {\edefconvertedargument\PDFfile{#1}%
+ \doPDFgetfilestreamreference\PDFfile#2} % == \doPDFgetobjectreference{PDFFS}\PDFfile#2
+
+% requested by Jens-Uwe Morawski: permits usage of pdftosrc
+% in viewers that don't support attachments:
+%
+% \definesymbol
+% [ObjectNumber]
+% % [object number {\PDFattachmentnumber[xx]}] % named
+% [object number \PDFattachmentnumber] % current
+%
+% \useattachment[test][xx][test.tex]
+% \setupattachments[symbol=ObjectNumber]
+% \attachment[test]
+
+\def\PDFattachmentnumber
+ {\dosingleargument\doPDFattachmentnumber}
+
+\def\doPDFattachmentnumber[#1]%
+ {\iffirstargument
+ \doPDFfilestreamidentifier{#1}%
+ \else
+ \doPDFfilestreamidentifier\PDFfile
+ \fi}
+
+%D \macros
+%D {...}
+%D
+%D Rather preliminary. We have to wait till the complete specs
+%D show up. As usual, we cannot really check it (Acrobat 6.0
+%D has a bug that inhibits us to make a test file). Half a day
+%D of testing made clear that trying to control the plugin fails
+%D in most cases (we need plugin specs -). We also miss a feature
+%D to let acrobat wait with proceeding (action processing) till
+%D the media clip is ready.
+
+% aiff audio/aiff
+% au audio/basic
+% avi video/avi
+% mid audio/midi
+% mov video/quicktime
+% mp3 audio/x-mp3 (mpeg)
+% mp4 audio/mp4
+% mp4 video/mp4
+% mpeg video/mpeg
+% smil application/smil
+% swf application/x-shockwave-flash
+
+% beware, this is preliminary code, should be improved
+
+\def\PDFrenderingspecs#1{\executeifdefined{PDFMR:#1}\empty}
+
+\def\PDFexecutestartrendering {/Rendition /OP 0 \PDFrenderingspecs\argumentA}
+\def\PDFexecutestoprendering {/Rendition /OP 1 \PDFrenderingspecs\argumentA}
+\def\PDFexecutepauserendering {/Rendition /OP 2 \PDFrenderingspecs\argumentA}
+\def\PDFexecuteresumerendering {/Rendition /OP 3 \PDFrenderingspecs\argumentA}
+
+% todo : sub files
+%
+% \doPDFembedfile{pier-39.png}{pier-39.png}{pier-39.png}%
+% \doPDFgetembeddedfilestreamreference{pier-39.png}\xPDFobjectreference
+% \edef\xxxx{/RF [(pier-39.png) \xPDFobjectreference]}%
+
+% todo: alternative renderings
+%
+% object_1 -> <</Type /Rendition /S /MR /C << /Type /MediaClip ... >> >>
+% object_2 -> <</Type /Rendition /S /MR /C << /Type /MediaClip ... >> >>
+% rendering -> <</Type /Rendition /S /MS [objref_1 objref_2]>>
+
+\def\doinsertrendering#1#2#3#4% tag mime file options
+ {\ifundefined{PDFMR:#1}%
+ \doifinstringelse{://}{#3}\donetrue\donefalse % evt url as keyword
+ \createpdfdictionaryobject{PDFMF}{#1}
+ {/Type /Rendition
+ /S /MR
+ % does not work: /SP << /Type /MediaScreenParam /BE << /B [1 0 0] /O 0.5 >> >>
+ /C << /Type /MediaClip
+ /S /MCD
+ /N (#1)
+ /Alt [() (file not found)] % language id + message
+ /D << /Type /Filespec
+ /F (#3)
+ \ifdone/FS /URL\fi >>
+ /CT (#2) >>}%
+ % common code
+ \doifobjectreferencefoundelse{PDFMS}{#1}
+ {\doPDFgetobjectreference{PDFMS}{#1}\PDFobjectreferenceB}
+ {\doPDFgetobjectreference{PDFMU}{#1}\PDFobjectreferenceB}%
+ \doPDFgetobjectreference{PDFMF}{#1}\PDFobjectreferenceA
+ \setxvalue{PDFMR:#1}% needed /AA actions in /Screen
+ {/R \PDFobjectreferenceA
+ /AN \PDFobjectreferenceB}%
+ \doifobjectreferencefoundelse{PDFMS}{#1}\donothing
+ {\dodoinsertrenderingwindow{PDFMU}{#1}\zeropoint\zeropoint{#4}}%
+ \fi}
+
+\def\doinsertrenderingobject#1#2#3#4% tag class objectname options
+ {\ifundefined{PDFMR:#1}%
+ \doPDFgetobjectreference{#2}{#3}\PDFobjectreference
+ \createpdfdictionaryobject{PDFMF}{#1}
+ {/Type /Rendition
+ /S /MR
+ /C << /Type /MediaClip
+ /S /MCD
+ /N (#1)
+ /D \PDFobjectreference>>}%
+ % common code
+ \doifobjectreferencefoundelse{PDFMS}{#1}
+ {\doPDFgetobjectreference{PDFMS}{#1}\PDFobjectreferenceB}
+ {\doPDFgetobjectreference{PDFMU}{#1}\PDFobjectreferenceB}%
+ \doPDFgetobjectreference{PDFMF}{#1}\PDFobjectreferenceA
+ \setxvalue{PDFMR:#1}% needed /AA actions in /Screen
+ {/R \PDFobjectreferenceA
+ /AN \PDFobjectreferenceB}%
+ \doifobjectreferencefoundelse{PDFMS}{#1}\donothing
+ {\dodoinsertrenderingwindow{PDFMU}{#1}\zeropoint\zeropoint{#4}}%
+ \fi}
+
+\def\doinsertrenderingwindow
+ {\dodoinsertrenderingwindow{PDFMS}}
+
+\def\dodoinsertrenderingwindow#1#2#3#4#5%
+ {\vbox to #4 \bgroup
+ \checkPDFscreenactions{#2}{#5}%
+ \doPDFgetobjectpagereference{PDFMF}{#2}\PDFobjectreferenceA
+ \doPDFgetobjectreference {PDFMF}{#2}\PDFobjectreferenceB
+ \vss
+ \hbox to #3 \bgroup
+ \createpdfannotationobject{#1}{#2}{#3}{#4}
+ {/Subtype /Screen
+ /P \PDFobjectreferenceA
+ /A \PDFobjectreferenceB
+ \PDFattributes
+ /Border [0 0 0]}%
+ \hss
+ \egroup
+ \egroup}
+
+\global\let\PDFrenderingopenpageaction \empty
+\global\let\PDFrenderingclosepageaction\empty
+
+\def\checkPDFscreenactions#1#2%
+ {\let\PDFattributes\empty
+ \iflocation % important since direct -)
+ % the action can either (already) be set by the window handler
+ % or (normally when no window [i.e a zero dimensions one] is present) by keyword
+ \doifinset\v!auto{#2}
+ {% brrr, here instead of in navigation module, must move and become special
+ % now two sided dependency
+ \let\checkrendering\gobbleoneargument
+ \ifx\PDFrenderingopenpageaction \empty
+ \handlereferenceactions{\v!StartRendering{#1}}\dosetuprenderingopenpageaction
+ \fi
+ \ifx\PDFrenderingclosepageaction\empty
+ \handlereferenceactions{\v!StopRendering {#1}}\dosetuprenderingclosepageaction
+ \fi
+ }%
+ \donefalse
+ \ifx\PDFrenderingopenpageaction \empty\!!doneafalse\else\donetrue\!!doneatrue\fi
+ \ifx\PDFrenderingclosepageaction\empty\!!donebfalse\else\donetrue\!!donebtrue\fi
+ \ifdone
+ \edef\PDFattributes
+ {/AA <<\if!!donea/PO <<\PDFrenderingopenpageaction >> \fi
+ \if!!doneb/PC <<\PDFrenderingclosepageaction>> \fi>>}%
+ \fi
+ \global\let\PDFrenderingopenpageaction \empty
+ \global\let\PDFrenderingclosepageaction\empty
+ \fi}
+
+\def\dosetuprenderingopenpageaction {\global\let\PDFrenderingopenpageaction \lastPDFaction}
+\def\dosetuprenderingclosepageaction{\global\let\PDFrenderingclosepageaction\lastPDFaction}
+
+%D For the moment we don't test for alternatives that
+%D themselves have alternatives, especially cylcic
+%D dependencies.
+
+% \def\pdfimmediateximage{\immediate\pdfximage}
+%
+% \def\checkpdfimageattributes
+% {\ifx\PDFfigurereference\empty
+% \global\let\pdfimageattributes\empty
+% \else
+% \immediate\pdfobj
+% {[ << /Image \PDFobjref\PDFfigurereference
+% /DefaultForPrinting true >> ]}%
+% \xdef\pdfimageattributes
+% {attr {/Alternates \PDFobjref\pdflastobj}}%
+% \fi}
+%
+% \global\let\PDFimagecolorreference\empty
+%
+% \def\checkpdfimagecolorspecs
+% {\ifx\pdflastximagecolordepth \undefined
+% \global\let\pdfimagecolorspecs\empty
+% \else\ifx\PDFimagecolorreference\empty
+% \global\let\pdfimagecolorspecs\empty
+% \else
+% \xdef\pdfimagecolorspecs{colorspace \PDFimagecolorreference\space}%
+% \fi\fi
+% \global\let\PDFimagecolorreference\empty}
+
+%D \macros
+%D {doregisterfigure}
+%D
+%D Here is the fuzzy, very special dependant figure
+%D registration special. We need to refer to the innermost
+%D object (ximage).
+
+ \def\doregisterfigure#1#2%
+ {\doifundefined{IM::#1::#2}
+ {\setxvalue{IM::#1::#2}{\the\pdflastximage}}%
+ \xdef\PDFfigurereference{\getvalue{IM::#1::#2}}}
+
+%D \macros
+%D {doovalbox}
+%D
+%D Drawing frames with round corners is inherited from the
+%D main module.
+%D
+%D For drawing ovals we use quite raw \PDF\ code. The next
+%D implementation does not differ that much from the one
+%D implemented in the \POSTSCRIPT\ driver.
+
+\def\doPDFovalcalc#1#2#3%
+ {\PointsToBigPoints{\dimexpr#1+#2\relax}#3}
+
+\def\doovalbox#1#2#3#4#5#6#7#8% todo: \scratchdimen/\scatchbox
+ {\forcecolorhack
+ \bgroup
+ \dimen0=#4\divide\dimen0 \plustwo
+ \doPDFovalcalc{0pt}{+\dimen0}\xmin
+ \doPDFovalcalc{#1}{-\dimen0}\xmax
+ \doPDFovalcalc{#2}{-\dimen0}\ymax
+ \doPDFovalcalc{-#3}{+\dimen0}\ymin
+ \advance\dimen0 by #5%
+ \doPDFovalcalc{0pt}{+\dimen0}\xxmin
+ \doPDFovalcalc{#1}{-\dimen0}\xxmax
+ \doPDFovalcalc{#2}{-\dimen0}\yymax
+ \doPDFovalcalc{-#3}{+\dimen0}\yymin
+ \doPDFovalcalc{#4}{\zeropoint}\stroke
+ \doPDFovalcalc{#5}{\zeropoint}\radius
+ \edef\dostroke{#6}%
+ \edef\dofill{#7}%
+ \edef\mode{\number#8 \space}%
+ % no \ifcase, else \relax in pdfcode
+ \setbox\scratchbox\hbox
+ {\ifnum\dostroke\dofill>\zerocount
+ \ifPDFstrokecolor\else\ifnum\dostroke=\plusone
+ \writestatus\m!colors{pdf stroke color will fail}\wait
+ \fi\fi
+ \PDFcode
+ {q
+ \stroke\space w
+ \ifcase\mode
+ \xxmin\space \ymin \space m
+ \xxmax\space \ymin \space l
+ \xmax \space \ymin \space \xmax \space \yymin\space y
+ \xmax \space \yymax\space l
+ \xmax \space \ymax \space \xxmax\space \ymax \space y
+ \xxmin\space \ymax \space l
+ \xmin \space \ymax \space \xmin \space \yymax\space y
+ \xmin \space \yymin\space l
+ \xmin \space \ymin \space \xxmin\space \ymin \space y
+ h
+ \or % 1
+ \xxmin\space \ymin \space m
+ \xxmax\space \ymin \space l
+ \xmax \space \ymin \space \xmax \space \yymin\space y
+ \xmax \space \ymax \space l
+ \xmin \space \ymax \space l
+ \xmin \space \yymin\space l
+ \xmin \space \ymin \space \xxmin\space \ymin \space y
+ h
+ \or % 2
+ \xxmin\space \ymin \space m
+ \xmax \space \ymin \space l
+ \xmax \space \ymax \space l
+ \xxmin\space \ymax \space l
+ \xmin \space \ymax \space \xmin \space \yymax\space y
+ \xmin \space \yymin\space l
+ \xmin \space \ymin \space \xxmin\space \ymin \space y
+ h
+ \or % 3
+ \xmin \space \ymin \space m
+ \xmax \space \ymin \space l
+ \xmax \space \yymax\space l
+ \xmax \space \ymax \space \xxmax\space \ymax \space y
+ \xxmin\space \ymax \space l
+ \xmin \space \ymax \space \xmin \space \yymax\space y
+ \xmin \space \ymin \space l
+ h
+ \or % 4
+ \xmin \space \ymin \space m
+ \xxmax\space \ymin \space l
+ \xmax \space \ymin \space \xmax \space \yymin\space y
+ \xmax \space \yymax\space l
+ \xmax \space \ymax \space \xxmax\space \ymax \space y
+ \xmin \space \ymax \space l
+ \xmin \space \ymin\space l
+ h
+ \or % 5
+ \xmin \space \ymin \space m
+ \xmax \space \ymin \space l
+ \xmax \space \yymax\space l
+ \xmax \space \ymax \space \xxmax\space \ymax \space y
+ \xmin \space \ymax \space l
+ \xmin \space \ymin \space l
+ h
+ \or % 6
+ \xmin \space \ymin \space m
+ \xxmax\space \ymin \space l
+ \xmax \space \ymin \space \xmax \space \yymin\space y
+ \xmax \space \ymax \space l
+ \xmin \space \ymax \space l
+ \xmin \space \ymin \space l
+ h
+ \or
+ \xxmin\space \ymin \space m
+ \xmax \space \ymin \space l
+ \xmax \space \ymax \space l
+ \xmin \space \ymax \space l
+ \xmin \space \yymin\space l
+ \xmin \space \ymin \space \xxmin\space \ymin \space y
+ h
+ \or
+ \xmin \space \ymin \space m
+ \xmax \space \ymin \space l
+ \xmax \space \ymax \space l
+ \xxmin\space \ymax \space l
+ \xmin \space \ymax \space \xmin \space \yymax\space y
+ \xmin \space \ymin \space l
+ h
+ \or % 9 top open
+ \xmin \space \ymax \space m
+ \xmin \space \yymin\space l
+ \xmin \space \ymin \space \xxmin\space \ymin \space y
+ \xxmax\space \ymin \space l
+ \xmax \space \ymin \space \xmax \space \yymin\space y
+ \xmax \space \ymax \space l
+ \or % 10 right open
+ \xmax \space \ymax \space m
+ \xxmin\space \ymax \space l
+ \xmin \space \ymax \space \xmin \space \yymax\space y
+ \xmin \space \yymin\space l
+ \xmin \space \ymin \space \xxmin\space \ymin \space y
+ \xmax\space \ymin \space l
+ \or % 11 bottom open
+ \xmax \space \ymin \space m
+ \xmax \space \yymax\space l
+ \xmax \space \ymax \space \xxmax \space \ymax\space y
+ \xxmin\space \ymax \space l
+ \xmin \space \ymax \space \xmin \space \yymax\space y
+ \xmin \space \ymin \space l
+ \or % 12 left open
+ \xmin \space \ymax \space m
+ \xxmax\space \ymax \space l
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \xmax \space \yymin\space l
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \xmin \space \ymin \space l
+ \or % 13
+ \xmin \space \ymax \space m
+ \xxmax\space \ymax \space l
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \xmax\space \ymin \space l
+ \or % 14
+ \xmax \space \ymax \space m
+ \xmax \space \yymin\space l
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \xmin \space \ymin \space l
+ \or % 15
+ \xmax \space \ymin \space m
+ \xxmin\space \ymin \space l
+ \xmin \space \ymin \space \xmin \space \yymin\space y
+ \xmin \space \ymax \space l
+ \or % 16
+ \xmin \space \ymin \space m
+ \xmin \space \yymax\space l
+ \xmin \space \ymax \space \xxmin\space \ymax \space y
+ \xmax \space \ymax \space l
+ \or % 17
+ \xxmax\space \ymax \space m
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \or % 18
+ \xmax \space \yymin\space m
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \or % 19
+ \xxmin\space \ymin \space m
+ \xmin \space \ymin \space \xmin \space \yymin\space y
+ \or % 20
+ \xmin \space \yymax\space m
+ \xmin \space \ymax \space \xxmin\space \ymax \space y
+ \or % 21
+ \xxmax\space \ymax \space m
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \xmin \space \yymax\space m
+ \xmin \space \ymax \space \xxmin\space \ymax \space y
+ \or % 22
+ \xxmax\space \ymax \space m
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \xmax \space \yymin\space m
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \or % 23
+ \xmax \space \yymin\space m
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \xxmin\space \ymin \space m
+ \xmin \space \ymin \space \xmin \space \yymin\space y
+ \or % 24
+ \xxmin\space \ymin \space m
+ \xmin \space \ymin \space \xmin \space \yymin\space y
+ \xmin \space \yymax\space m
+ \xmin \space \ymax \space \xxmin\space \ymax \space y
+ \or % 25
+ \xxmax\space \ymax \space m
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \xmax \space \yymin\space m
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \xxmin\space \ymin \space m
+ \xmin \space \ymin \space \xmin \space \yymin\space y
+ \xmin \space \yymax\space m
+ \xmin \space \ymax \space \xxmin\space \ymax \space y
+ \or % 26
+ \xmax \space \yymin\space m
+ \xmax \space \ymin \space \xxmax\space \ymin \space y
+ \xmin \space \yymax\space m
+ \xmin \space \ymax \space \xxmin\space \ymax \space y
+ \or % 27
+ \xxmax\space \ymax \space m
+ \xmax \space \ymax \space \xmax \space \yymax\space y
+ \xxmin\space \ymin \space m
+ \xmin \space \ymin \space \xmin \space \yymin\space y
+ \or % 28
+ \fi
+ \ifnum\mode>8
+ S
+ \else
+ \ifnum\dostroke=\plusone S \fi
+ \ifnum\dofill =\plusone f \fi
+ \fi
+ Q}%
+ \fi}%
+ \wd\scratchbox#1\ht\scratchbox#2\dp\scratchbox#3\box\scratchbox
+ \egroup}
+
+%D \macros
+%D {dostartgraymode,dostopgraymode,
+%D dostartrgbcolormode,dostartcmykcolormode,dostartgraycolormode,
+%D dostopcolormode,
+%D dostartrotation,dostoprotation,
+%D dostartscaling,dostopscaling,
+%D dostartmirroring,dostopmirroring,
+%D dostartnegative,dostopnegative,
+%D dostartoverprint,dostopoverprint}
+
+\def\dostartrotation#1% grouped
+ {\setcalculatedcos\cos{#1}%
+ \setcalculatedsin\sin{#1}%
+ \forcecolorhack
+ \PDFcode{q \cos\space\sin\space\negated\sin\space\cos\space0 0 cm}}
+
+\def\dostoprotation
+ {\PDFcode{Q}}
+
+\def\@@PDFzeroscale{.0001}
+
+\def\dostartscaling#1#2% the test is needed because acrobat is bugged!
+ {\forcecolorhack
+ \PDFcode{q \ifdim#1\points=\zeropoint\@@PDFzeroscale\else#1\fi\space 0 0
+ \ifdim#2\points=\zeropoint\@@PDFzeroscale\else#2\fi\space 0 0 cm}}
+
+\def\dostopscaling
+ {\PDFcode{Q}}
+
+\def\dostartmirroring{\PDFcode{-1 0 0 1 0 0 cm}}
+\def\dostopmirroring {\PDFcode{-1 0 0 1 0 0 cm}}
+
+\def\dostartnegative {\ifdefined\initializePDFnegative \initializePDFnegative \PDFcode{/GSnegative gs}\fi}
+\def\dostopnegative {\ifdefined\initializePDFnegative \initializePDFnegative \PDFcode{/GSpositive gs}\fi}
+\def\dostartoverprint{\ifdefined\initializePDFoverprint\initializePDFoverprint\PDFcode{/GSoverprint gs}\fi}
+\def\dostopoverprint {\ifdefined\initializePDFoverprint\initializePDFoverprint\PDFcode{/GSknockout gs}\fi} % wrong
+
+%D \macros
+%D {doPDFstartgraymode,doPDFstopgraymode,
+%D doPDFstartrgbcolormode,doPDFstartcmykcolormode,doPDFstartgraycolormode,
+%D doPDFstopcolormode}
+%D
+%D In \PDF\ there are two color states, one for strokes and one
+%D for fills. This means that we have to set the color in a
+%D rather redundant looking way. Unfortunately this makes the
+%D \PDF\ file much larger than needed. We can save few bytes
+%D by not setting the stroke color. Due to zip compression we
+%D only save a few percent.
+
+\def\dostartgraymode #1{\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}}
+\def\dostopgraymode {\PDFcode{0 g\ifPDFstrokecolor\space 0 G\fi}}
+\def\dostartrgbcolormode #1#2#3{\PDFcode{#1 #2 #3 rg\ifPDFstrokecolor\space#1 #2 #3 RG\fi}}
+\def\dostartcmykcolormode#1#2#3#4{\PDFcode{#1 #2 #3 #4 k\ifPDFstrokecolor\space#1 #2 #3 #4 K\fi}}
+\def\dostartgraycolormode #1{\PDFcode{#1 g\ifPDFstrokecolor\space#1 G\fi}}
+\def\dostopcolormode {\PDFcode{0 g\ifPDFstrokecolor\space0 G\fi}}
+
+\def\dostartspotcolormode#1#2% redefining spotcolors is not possible anyway
+ {\ifundefined{pdf:scs:#2}%
+ \bgroup
+ \getcommacommandsize[#2]%
+ \ifcase\commalistsize\or
+ \setxvalue{pdf:scs:#2}{#2 SCN #2 scn}% \setxvalue{pdf:scs:#2}{#2 SC #2 sc}%
+ \else
+ \let\PDFspotcolorspecs\empty
+ \def\dospotcolorcommand##1{\edef\PDFspotcolorspecs{\PDFspotcolorspecs##1\space}}%
+ \processcommacommand[#2]\dospotcolorcommand
+ \setxvalue{pdf:scs:#2}{\PDFspotcolorspecs SCN \PDFspotcolorspecs scn}%
+ \fi
+ \egroup
+ \fi
+ \PDFcode{/#1 cs /#1 CS \PDFgetspotcolorspec{#2}}}
+
+\def\PDFgetspotcolorspec#1%
+ {\executeifdefined{pdf:scs:#1}\empty} % better no default than one with too less args
+
+\def\dostartnonecolormode
+ {\PDFcode{/None CS 1 SC /None cs 1 sc}}
+
+%D We need to register the spot colors and their fallbacks.
+
+% we cannot use /DeviceN since GS <=7.21 breaks on it
+% and Jaws does not handle it at all {[/DeviceN [/All|/None]
+% /Device#2 \PDFobjref\pdflastobj]} so we use separation
+% colors that work and print ok
+
+\def\doPDFregistersomespotcolor#1#2#3#4% implemented in the driver
+ {\writestatus\m!systems{missing spot color definition}\wait}
+
+\def\doregisternonecolor % internal command
+ {\doregistergrayspotcolor{None}{1}%
+ \globallet\doregisternonecolor\relax}
+
+\def\dodoPDFregisterrgbspotcolor#1#2#3#4#5#6#7% name noffractions names p's r g b
+ {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{RGB}{0.0 1.0 0.0 1.0 0.0 1.0}%
+ {\ifcase#2\or dup #5 mul exch dup #6 mul exch #7 mul\else#5 #6 #7\fi}}
+
+\def\dodoPDFregistercmykspotcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k
+ {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{CMYK}{0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0}%
+ {\ifcase#2\or dup #5 mul exch dup #6 mul exch dup #7 mul exch #8 mul\else #5 #6 #7 #8\fi}}
+
+\def\dodoPDFregistergrayspotcolor#1#2#3#4#5% name noffractions names p's s
+ {\doPDFregistersomespotcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}%
+ {\ifcase#2\or #5 mul\else #5\fi}}
+
+\def\doregisterrgbspotcolor#1#2#3#4#5#6#7% name noffractions names p's r g b
+ {\ifRGBsupported
+ \dodoPDFregisterrgbspotcolor{#1}{#2}{#3}{#4}{#5}{#6}{#7}%
+ \else
+ \edef\@@cl@@r{#5}\edef\@@cl@@g{#6}\edef\@@cl@@b{#7}%
+ \ifCMYKsupported
+ \convertRGBtoCMYK\@@cl@@r\@@cl@@g\@@cl@@b
+ \dodoPDFregistercmykspotcolor{#1}{#2}{#3}{#4}\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k
+ \else
+ \convertRGBtoGRAY\@@cl@@r\@@cl@@g\@@cl@@b
+ \dodoPDFregistergrayspotcolor{#1}{#2}{#3}{#4}\@@cl@@s
+ \fi
+ \fi}
+
+\def\doregistercmykspotcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k
+ {\ifCMYKsupported
+ \dodoPDFregistercmykspotcolor{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+ \else
+ \edef\@@cl@@c{#5}\edef\@@cl@@m{#6}\edef\@@cl@@y{#7}\edef\@@cl@@k{#8}%
+ \ifRGBsupported
+ \convertCMYKtoRGB\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k
+ \dodoPDFregisterrgbspotcolor{#1}{#2}{#3}{#4}\@@cl@@r\@@cl@@g\@@cl@@b
+ \else
+ \convertCMYKtoGRAY\@@cl@@c\@@cl@@m\@@cl@@y\@@cl@@k
+ \dodoPDFregistergrayspotcolor{#1}{#2}{#3}{#4}\@@cl@@s
+ \fi
+ \fi}
+
+\def\doregistergrayspotcolor{\dodoPDFregistergrayspotcolor}
+
+%D New and very experimental.
+
+\def\doregistercmykindexcolor#1#2#3#4#5#6#7#8% name noffractions names p's c m y k
+ {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{CMYK}{0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0}%
+ {dup #5 mul exch dup #6 mul exch dup #7 mul exch #8 mul}}
+
+\def\doregisterrgbindexcolor#1#2#3#4#5#6#7% name noffractions names p's r g b
+ {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{RGB}{0.0 1.0 0.0 1.0 0.0 1.0}%
+ {dup #5 mul exch dup #6 mul exch #7 mul}}
+
+\def\doregistergrayindexcolor#1#2#3#4#5% name noffractions names p's s
+ {\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}%
+ {pop}}
+
+\let\checkpredefinedcolor\predefineindexcolor % we need an index in order to negate bitmaps
+
+\def\doregisterfigurecolor#1% always an index color
+ {\dogetobjectreference{PDFIX}{\internalspotcolorname{#1}}\PDFimagecolorreference}
+
+\def\doregisterspotcolorname#1#2% no need for escape in luatex
+ {\bgroup
+ \let\ascii\empty
+ \def\docommand##1%
+ {\edef\ascii{\ascii
+ \ifx\nexthandledtoken\space
+ \letterhash20%
+ \else\ifx\nexthandledtoken\blankspace
+ \letterhash20%
+ \else
+ ##1%
+ \fi\fi}}%
+ \expanded{\handletokens#2}\with\docommand
+ \letgvalue{@@pdf@@scn@@#1}\ascii
+ \egroup}
+
+\def\doPDFregistersomespotcolor#1#2#3#4#5#6#7% name fractions names p's space domain function
+ {\bgroup
+ \let\spotpops\empty
+ \ifcase#2\or
+ %def\PDFspotcolornames{/Separation /#1}%
+ \edef\PDFspotcolornames{/Separation /\executeifdefined{@@pdf@@scn@@#1}{#1}}%
+ \def\PDFspotcolordomain{0.0 1.0}%
+ \else
+ \dorecurse{#2}{\edef\spotpops{\spotpops pop }}%
+ \let\PDFspotcolornames \empty
+ \let\PDFspotcolordomain\empty
+ \def\dospotcolorcommand##1%
+ {\edef\PDFspotcolornames {\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}%
+ \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}%
+ \processcommacommand[#3]\dospotcolorcommand
+ \edef\PDFspotcolornames{/DeviceN [\PDFspotcolornames]}%
+ \fi
+ \immediate \pdfobj stream attr
+ {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}%
+ \immediate \pdfobj
+ {[\PDFspotcolornames\space /Device#5 \PDFobjref\pdflastobj]}%
+ \dosetobjectreference{PDFCS}{#1}{\the\pdflastobj}%
+ \appendtoPDFdocumentcolorspaces{/#1 \PDFobjref\pdflastobj}%
+ \egroup}
+
+%D New and very experimental.
+
+\def\doPDFregistersomeindexcolor#1#2#3#4#5#6#7% name fractions names p's space domain function
+ {\bgroup
+ \let\spotpops\empty
+ \dorecurse{#2}{\edef\spotpops{\spotpops exch pop\space}}%
+ \let\PDFspotcolornames \empty
+ \let\PDFspotcolordomain\empty
+ \def\docommand##1%
+ {%\edef\PDFspotcolornames {\PDFspotcolornames/##1\space}%
+ \edef\PDFspotcolornames{\PDFspotcolornames/\executeifdefined{@@pdf@@scn@@##1}{##1}\space}%
+ \edef\PDFspotcolordomain{\PDFspotcolordomain 0.0 1.0\space}}%
+ \processcommacommand[#3,None]\docommand
+ \let\PDFcolorindexvector\empty
+ \def\docommand##1%
+ {\scratchdimen##1\points
+ \scratchdimen\recurselevel\scratchdimen
+ \scratchcounter\scratchdimen
+ \divide\scratchcounter \maxcard
+ \edef\PDFcolorindexvector{\PDFcolorindexvector\uchexnumbers\scratchcounter}}%
+ %\dostepwiserecurse\zerocount{255}\plusone
+ \dostepwiserecurse{255}\zerocount\minusone % we need to negate
+ {\rawprocesscommacommand[#4,1]\docommand
+ \xdef\PDFcolorindexvector{\PDFcolorindexvector\space}}%
+ \immediate \pdfobj stream attr
+ {/FunctionType 4 /Domain [\PDFspotcolordomain] /Range [#6]}{{\spotpops#7}}%
+ \immediate \pdfobj
+ {[/Indexed
+ [/DeviceN [\PDFspotcolornames] /Device#5 \the\pdflastobj\space0 R] %
+ 255 <\PDFcolorindexvector>]}%
+ \dosetobjectreference{PDFIX}{#1}{\the\pdflastobj}%
+ \appendtoPDFdocumentcolorspaces{/#1_INDEXED \the\pdflastobj\space0 R}%
+ \egroup}
+
+%D \macros
+%D {dostarttransparency,dostoptransparency}
+%D
+%D For transparency, we need to implement a couple of
+%D auxiliary macros. If needed, we will generalize them later.
+
+\def\@@PDT{@PDT@}
+
+\ifx\PDFcurrenttransparency\undefined
+ \newcount\PDFcurrenttransparency \PDFcurrenttransparency=0 % -1
+\fi
+
+\def\assignPDFtransparency#1#2%
+ {\edef\PDFtransparencyidentifier{/Tr#1}%
+ \edef\PDFtransparencyreference{\PDFobjref{#2}}}
+
+\def\presetPDFtransparency#1#2%
+ {\initializePDFtransparency
+ \executeifdefined{\@@PDT#1:#2}{\dopresetPDFtransparency{#1}{#2}}}
+
+\def\dopresetPDFtransparency#1#2%
+ {\global\advance\PDFcurrenttransparency \plusone
+ \immediate\pdfobj{\PDFtransparancydictionary{#1}{#2}{}}%
+ \edef\PDFtransparencyidentifier{/Tr\the\PDFcurrenttransparency}%
+ \edef\PDFtransparencyreference {\PDFobjref\pdflastobj}%
+ \setxvalue{\@@PDT#1:#2}%
+ {\noexpand\assignPDFtransparency{\the\PDFcurrenttransparency}{\the\pdflastobj}}%
+ \appendtoPDFdocumentextgstates
+ {\PDFtransparencyidentifier\space
+ \PDFtransparencyreference\space}}
+
+\def\initializePDFtransparency
+ {\immediate\pdfobj{\PDFtransparancydictionary{1}{1}{/AIS false}}%
+ \xdef\PDFtransparencyresetidentifier{/Tr0}%
+ \xdef\PDFtransparencyresetreference{\PDFobjref\pdflastobj}%
+ \setxvalue{\@@PDT0:0}%
+ {\noexpand\assignPDFtransparency{0}{\the\pdflastobj}}%
+ \appendtoPDFdocumentextgstates
+ {\PDFtransparencyresetidentifier\space
+ \PDFtransparencyresetreference\space}%
+ \global\let\initializePDFtransparency\relax}
+
+%D Transparency support:
+
+\def\PDFtransparancydictionary#1#2#3% type fraction extras
+ {<</Type /ExtGState
+ /ca #2 /CA #2
+ /BM /\ifcase#1 Normal\or Normal\or Multiply\or Screen\or
+ Overlay\or SoftLight\or HardLight\or ColorDodge\or
+ ColorBurn\or Darken\or Lighten\or Difference\or
+ Exclusion\else Compatible\fi
+ #3>>}
+
+\def\dodoPDFstarttransparency#1#2%
+ {\presetPDFtransparency{#1}{#2}%
+ \PDFcode{\PDFtransparencyidentifier\space gs }}
+
+\def\dodoPDFstoptransparency
+ {\PDFcode{/Tr0 gs }}
+
+\def\dostarttransparency
+ {\global\let\dostarttransparency\dodoPDFstarttransparency
+ \global\let\dostoptransparency \dodoPDFstoptransparency
+ \initializetransparency
+ \dostarttransparency}
+
+% This is tricky: because a text stream is handled before
+% the page body is built, we can run into stops that will
+% match an outer start; however, the stop is needed in case
+% of a text color: [text color text] [other color text] on a
+% first page combined with color splitting will go wrong if
+% we stick to the relaxing method.
+
+% \def\dostoptransparency
+% {\initializetransparency
+% \dodoPDFstoptransparency}
+
+%D These use:
+
+\let\initializetransparency\relax
+
+\let\PDFtransparencyresetreference \empty
+\let\PDFtransparencyresetidentifier\empty
+
+\let\PDFtransparencyreference \empty
+\let\PDFtransparencyidentifier\empty
+
+%D New trickery:
+
+\def\dostartgraphicgroup{\PDFcode{q}}
+\def\dostopgraphicgroup {\PDFcode{Q}}
+
+%D \macros
+%D {dostartclipping,dostopclipping}
+%D
+%D Clipping in \PDFTEX\ is rather trivial. We can even hook
+%D in \METAPOST\ without problems.
+
+\def\dostartclipping#1#2#3%
+ {\PointsToBigPoints{#2}\width
+ \PointsToBigPoints{#3}\height
+ \grabMPclippath{#1}{1}\width\height
+ {0 0 m \width\space 0 l \width \height l 0 \height l}%
+ \pdfliteral % PDFcode ?
+ {q 0 w \MPclippath\space W n}}
+
+\def\dostopclipping
+ {\pdfliteral{Q n}} % PDFcode
+
+%D \macros
+%D {dosetupinteraction}
+%D
+%D Nothing special is needed to enable \PDF\ commands and
+%D interaction. We stick with a message.
+
+\def\dosetupinteraction
+ {\showmessage\m!interactions{21}{pdftex}}
+
+%D \macros
+%D {doresetgotowhereever,
+%D dostartthisisrealpage,dostartthisislocation,
+%D dostartgotorealpage,dostartgotolocation,dostartgotoJS}
+%D
+%D The interactions macros are the core of this module. We
+%D support both page destinations and named ones. We don't
+%D need the \type{\stop}||alternatives. We also don't need
+%D to set the special that sets the real page number.
+
+%D In the goto specials we took care of secondary references.
+%D Here we define the macros used.
+
+\def\doresetgotowhereever
+ {\global\let\secondaryPDFreferences\empty}
+
+\doresetgotowhereever % just to be sure
+
+% we can (in etex) share more by testing on this
+
+\def\savesecondaryPDFreference#1%
+ {\@EA\xdef\csname PDF-SR:\the\nofsecondaryreferences\endcsname{#1}}
+
+\def\savesecondaryPDFreference % #1 == \action
+ {\global\@EA\let\csname PDF-SR:\the\nofsecondaryreferences\endcsname}
+
+% test should happen in core-ref
+
+\def\getsecondaryPDFreferences
+ {\ifcase\nofsecondaryreferences\else
+ \ifcsname PDF-SR:\the\nofsecondaryreferences\endcsname
+ \xdef\secondaryPDFreferences{/Next <<\csname PDF-SR:\the\nofsecondaryreferences\endcsname\space\secondaryPDFreferences>>}%
+ \fi
+ \global\advance\nofsecondaryreferences \minusone
+ \expandafter\getsecondaryPDFreferences
+ \fi}
+
+%D \macros
+%D {dostartthisislocation}
+%D
+%D Next we define the macros that deal with hyperreferencing,
+%D graphic inclusion and general document features. These are
+%D the olderst ones. I won't comment much because one needs
+%D knowledge of \PDF\ itself, and explaning \PDF\ is beyond
+%D this documentation.
+
+\def\dostartthisislocation#1%
+ {\bgroup
+ \setPDFdestination{#1}%
+ \ifx\PDFdestination\empty \else
+ \pdfdest name {\PDFdestination}\PDFpageviewkey
+ \fi
+ \egroup}
+
+\def\locationfilesuffix{pdf}
+
+\def\dostartgotolocation#1#2#3#4#5#6%
+ {\bgroup
+ \doifelsenothing{#3}
+ {\setPDFdestination{#5}%
+ \doifelsenothing\PDFdestination
+ {\let\action\empty}
+ {\doifelsenothing{#4}
+ {\let\PDFfile\empty}
+ {\expanded{\beforesplitstring#4}\at.\to\PDFfile
+ \doifparentfileelse\PDFfile % {#4}
+ {\let\PDFfile\empty}
+ %{\setreferencefilename#4.\locationfilesuffix\to\PDFfile
+ {\@EA\setreferencefilename\PDFfile.\locationfilesuffix\to\PDFfile
+ \edef\PDFfile
+ {R /F (\PDFfile)\ifgotonewwindow\space/NewWindow true \fi}}}%
+ \edef\action%
+ {/S /GoTo\PDFfile\space /D (\PDFdestination)}}}
+ {\doifelsenothing{#4}
+ {\let\PDFfile\empty
+ \let\PDFdestination\empty}
+ {\setreferencefilename/#4\to\PDFfile
+ \setPDFdestination{#5}%
+ \doifsomething\PDFdestination
+ {\edef\PDFdestination{\letterhash\PDFdestination}}}%
+ \edef\action{/S /URI /URI (#3\PDFfile\PDFdestination)}}%
+ \ifx\action\empty\else
+ \ifsecondaryreference
+ \savesecondaryPDFreference\action
+ \else
+ \getsecondaryPDFreferences
+ \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}%
+ \fi
+ \fi
+ \egroup}
+
+\def\PDFgotonewwindow{\ifgotonewwindow\space/NewWindow true \fi}
+
+% optimization in tpd driver
+%
+% \edef\PDFdestination{(page:\the\scratchcounter)}%
+%
+% ==>
+%
+% \advance\scratchcounter 1
+% \edef\PDFdestination{[\pdfpageref \PDFobjref\scratchcounter\PDFpageviewwrd]}%
+%
+% \doPDFgetpagedestination#1#2% pagenumber macro % % fuzzy hack
+
+\def\dostartgotorealpage#1#2#3#4#5% watch the R append trick
+ {\bgroup
+ \doifelsenothing{#3}% #1 = url
+ {\scratchcounter0#5\relax
+ \ifnum\scratchcounter>0
+ \doifelsenothing{#4}
+ {\let\PDFfile\empty}
+ {\expanded{\beforesplitstring#4}\at.\to\PDFfile
+ \doifparentfileelse\PDFfile % {#4}
+ {\let\PDFfile\empty}
+ %{\setreferencefilename#4.\locationfilesuffix\to\PDFfile
+ {\@EA\setreferencefilename\PDFfile.\locationfilesuffix\to\PDFfile
+ \edef\PDFfile{R /F (\PDFfile)\PDFgotonewwindow}}}%
+ \ifx\PDFfile\empty
+ \ifcase\overcomePDFpage
+ \or % pdf starts numbering at zero
+ \advance\scratchcounter \minusone
+ \edef\PDFdestination{[\the\scratchcounter\space\PDFpageviewwrd]}%
+ \or % pdf starts numbering at zero
+ \advance\scratchcounter \minusone
+ \edef\PDFdestination{(page:\the\scratchcounter)}%
+ \or % pdftex starts numbering at one
+ \edef\PDFdestination{[\pdfpageref\scratchcounter\space0 R \PDFpageviewwrd]}%
+ \fi
+ \else % across files it's a page number / pdf starts numbering at zero
+ \advance\scratchcounter \minusone
+ \edef\PDFdestination{[\the\scratchcounter\space\PDFpageviewwrd]}%
+ \fi
+ \edef\action{/S /GoTo\PDFfile\space /D \PDFdestination}%
+ \else
+ \let\action\empty
+ \fi}
+ {\doifelsenothing{#4}
+ {\let\PDFfile\empty}
+ {\setreferencefilename/#4\to\PDFfile}%
+ \edef\action{/S /URI /URI (#3\PDFfile)}}%
+ \ifx\action\empty\else
+ \ifsecondaryreference
+ \savesecondaryPDFreference\action
+ \else
+ \getsecondaryPDFreferences
+ \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}%
+ \fi
+ \fi
+ \egroup}
+
+\let\lastfakedPDFpage\!!zerocount
+
+\def\fakePDFpagedestination % as in pdf, we start numbering at zero
+ {\iflocation \ifarrangingpages \ifnum\overcomePDFpage=\plustwo \else
+ \ifnum\lastfakedPDFpage<\realpageno
+ \bgroup
+ \xdef\lastfakedPDFpage{\realfolio}%
+ \advance\realpageno \minusone % is \expanded needed ?
+ \normalexpanded{\noexpand\pdfdest name {page:\realfolio}\PDFpageviewkey}%
+ \egroup
+ \fi
+ \fi \fi \fi}
+
+\def\dostartgotoJS#1#2#3%
+ {\bgroup
+ \doPSsanitizeJScode#3\to\sanitizedJScode
+ \edef\action{/S /JavaScript /JS (\sanitizedJScode)}%
+ \ifsecondaryreference
+ \savesecondaryPDFreference\action
+ \else
+ \getsecondaryPDFreferences
+ \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}%
+ \fi
+ \egroup}
+
+%D When going to a location, we obey the time and space saving
+%D boolean \type{\ifusepagedestination}. Named destinations are
+%D stripped and made robust. This all happens in the macros
+%D called for.
+
+%D \macros
+%D {doflushJSpreamble}
+%D
+%D It does not make sense to duplicate common \JAVASCRIPT\
+%D functions, and therefore they can be predefined and must be
+%D output separately. Currently this special is not shared
+%D with the \ACROBAT\ one, simply because \DISTILLER\ does not
+%D yet support something \type{\pdfnames}.
+
+% \oneJSpreamblefalse % buggy in acrobat
+
+\def\doflushJSpreamble#1%
+ {\bgroup
+ \let\compositeJScode\empty
+ \def\docommand##1%
+ {\edef\sanitizedJScode{\getJSpreamble{##1}}%
+ \@EA\doPSsanitizeJScode\sanitizedJScode\to\sanitizedJScode
+ \immediate\pdfobj {<< /S /JavaScript /JS (\sanitizedJScode) >>}%
+ \edef\compositeJScode
+ {\compositeJScode\space (##1) \PDFobjref\pdflastobj}}%
+ \processcommalist[#1]\docommand
+ \immediate\pdfobj{<< /Names [ \compositeJScode ] >>}%
+ \pdfnames{/JavaScript \PDFobjref\pdflastobj}%
+ \egroup}
+
+%D \macros
+%D {dostarthide,dostophide}
+%D
+%D Hiding parts of the document for printing is not yet
+%D supported by \PDF\ and therefore \PDFTEX.
+
+\let\dostarthide\donothing
+\let\dostophide \donothing
+
+%D \macros
+%D {doPDFsetupscreen,doPDFsetupidentity}
+%D
+%D Opposite to \DVI\ drivers, \PDF\ ones must know which what
+%D page dimensions they are dealing. We also use the
+%D opportunity to launch full screen (1) or show bookmarks (2).
+%D
+%D Setting of the screen boundingbox involves some
+%D calculations. Here we also take care of (non) full screen
+%D startup. The dimensions are rounded. Because \PDFTEX\ and
+%D \ACROBAT\ handle setting the page dimensions in a
+%D different way, we do not share this special.
+
+\def\dosetupscreen{\doPDFsetupscreen\pdfpageheight}
+
+\let\currentPDFpagemode \empty % document catalog
+\let\currentPDFviewerprefs\empty % document catalog
+
+\let\currentPDFcropbox \empty % page attributes
+\let\currentPDFbleedbox \empty % page attributes
+\let\currentPDFartbox \empty % page attributes
+\let\currentPDFtrimbox \empty % page attributes
+
+\def\doPDFsetupscreen#1#2#3#4#5#6% watch the extra argument
+ {\bgroup
+ \xdef\currentPDFpagemode
+ {\ifnum#6=4
+ /PageLayout /TwoColumnRight
+ \else
+ /PageMode \ifcase#6
+ /UseNone\or/FullScreen\or/UseOutlines\else/UseNone\fi
+ \fi}%
+ \xdef\currentPDFviewerprefs % space after #6 needed, else \relax
+ {\ifcase#6 \or\or\else /ViewerPreferences << /FitWindow true >>\fi}%
+ \egroup}
+
+\def\addPDFdocumentinfo
+ {\appendtopdfcatalog{\currentPDFpagemode\currentPDFviewerprefs}%
+ \appendtopdfcatalog{/Version \ifdim\PDFversion00\points>100\points 1.\fi\PDFversion}%
+ \appendtopdfinfo{/Trapped /False}%
+ \appendtopdfinfo{/ConTeXt.Version (\contextversion)}%
+ \appendtopdfinfo{/ConTeXt.Time (\number\normalyear.\twodigits\normalmonth.\twodigits\normalday\space \twodigits\currenthour:\twodigits\currentminute)}%
+ \appendtopdfinfo{/ConTeXt.Jobname (\jobname)}%
+ \appendtopdfinfo{/ConTeXt.Url (www.pragma-ade.com)}%
+ \glet\addPDFdocumentinfo\relax}
+
+\def\PDFversion{1.5}
+
+\appendtoksonce
+ \def\PDFversion{1.5}%
+\to \everyresetspecials
+
+\def\doPDFsetupwhateverbox#1#2#3#4#5#6% watch the extra arguments
+ {\bgroup
+ \!!widtha \dimexpr#5+#3\relax
+ \!!heightb\dimexpr#2-#4\relax
+ \!!heighta\dimexpr\!!heightb-#6\relax
+ % sometimes whole values give better results
+ % \PointsToWholeBigPoints{#3}\left
+ % \PointsToWholeBigPoints\!!heighta\bottom
+ % \PointsToWholeBigPoints\!!widtha \width
+ % \PointsToWholeBigPoints\!!heightb\height
+ % but since pdf/x does not round when checking if
+ % the boxes fit inside the media box ...
+ \PointsToBigPoints{#3}\left
+ \PointsToBigPoints\!!heighta\bottom
+ \PointsToBigPoints\!!widtha \width
+ \PointsToBigPoints\!!heightb\height
+ \xdef#1{[\left\space\bottom\space\width\space\height]}%
+ \egroup}
+
+\gdef\currentPDFtrimbox{\currentPDFcropbox} % default, needed for pdf/x
+
+\def\dosetupartbox {\doPDFsetupwhateverbox\currentPDFartbox \pdfpageheight}
+\def\dosetupcropbox {\doPDFsetupwhateverbox\currentPDFcropbox \pdfpageheight}
+\def\dosetupbleedbox{\doPDFsetupwhateverbox\currentPDFbleedbox\pdfpageheight}
+\def\dosetuptrimbox {\doPDFsetupwhateverbox\currentPDFtrimbox \pdfpageheight}
+
+\def\flushPDFpageboxes
+ {\edef\currentPDFtrimbox{\currentPDFtrimbox}%
+ \ifx\currentPDFartbox \empty\else\appendtopdfpageattributes{/ArtBox \currentPDFartbox }\fi
+ \ifx\currentPDFcropbox \empty\else\appendtopdfpageattributes{/CropBox \currentPDFcropbox }\fi
+ \ifx\currentPDFbleedbox\empty\else\appendtopdfpageattributes{/BleedBox \currentPDFbleedbox}\fi
+ \ifx\currentPDFtrimbox \empty\else\appendtopdfpageattributes{/TrimBox \currentPDFtrimbox }\fi}
+
+%D \macros
+%D {dostartexecutecommand}
+%D
+%D \PDF\ viewers enable us to navigate using menus and shortcut
+%D keys. These navigational tools can also be accessed by using
+%D annotations. The next special takes care of inserting them.
+%D
+%D At the cost of much auxiliary placeholders, we can pretty
+%D fast convert the command asked for. This is how the \PDF\
+%D code looks like.
+
+\def\PDFmoviecode#1#2#3%
+ {/Movie
+ /T (\ifcase#1movie \else sound \fi\ifx\argumentA\empty#2\else\argumentA\fi)
+ /Operation /\ifcase#3Play\or Stop\or Pause\or Resume\fi\space}
+
+\def\PDFexecutestartmovie {\PDFmoviecode0\currentmovie0}
+\def\PDFexecutestopmovie {\PDFmoviecode0\currentmovie1}
+\def\PDFexecutepausemovie {\PDFmoviecode0\currentmovie2}
+\def\PDFexecuteresumemovie {\PDFmoviecode0\currentmovie3}
+
+\def\PDFexecutestartsound {\PDFmoviecode1\currentsound0}
+\def\PDFexecutestopsound {\PDFmoviecode1\currentsound1}
+\def\PDFexecutepausesound {\PDFmoviecode1\currentsound2}
+\def\PDFexecuteresumesound {\PDFmoviecode1\currentsound3}
+
+\def\PDFformcode#1%
+ {\doiffieldset{#1}{/Field [\dogetfieldset{#1}]}}
+
+% bit 3 = html
+% bit 6 = xml
+% bit 4 = get
+
+\ifx\PDFsubmitfiller\undefined \let\PDFsubmitfiller\empty \fi
+
+\chardef\PDFformmethod=1 % 0=GET 1=POST
+
+\def\PDFformflag#1#2{\ifcase\PDFformmethod#1\else#2\fi}
+
+\def\PDFexecuteimportform {/Named /N /AcroForm:ImportFDF}
+\def\PDFexecuteexportform {/Named /N /AcroForm:ExportFDF}
+\def\PDFexecuteresetform {/ResetForm \PDFformcode\argumentA}
+\def\PDFexecutesubmitform {/SubmitForm \PDFformcode\argumentB
+ /Flags \ifcase\submitoutputformat\space
+ \PDFformflag{12} {4} % 0=unknown
+ \or \PDFformflag{12} {4} % 1=HTML
+ \or \PDFformflag {8} {0} % 2=FDF
+ \or \PDFformflag{40}{32} % 3=XML
+ \else \PDFformflag{12} {4} % ?=unknown
+ \fi
+ /F (\argumentA)\PDFsubmitfiller}
+
+% urifill permits url substitution
+
+\def\PDFexecutehide {/Hide /T (\argumentA) /H true}
+\def\PDFexecuteshow {/Hide /T (\argumentA) /H false}
+
+\def\PDFexecutefirst {/Named /N /FirstPage}
+\def\PDFexecuteprevious {/Named /N /PrevPage}
+\def\PDFexecutenext {/Named /N /NextPage}
+\def\PDFexecutelast {/Named /N /LastPage}
+\def\PDFexecutebackward {/Named /N /GoBack}
+\def\PDFexecuteforward {/Named /N /GoForward}
+\def\PDFexecuteprint {/Named /N /Print}
+\def\PDFexecuteexit {/Named /N /Quit}
+\def\PDFexecuteclose {/Named /N /Close}
+\def\PDFexecutesave {/Named /N /Save}
+\def\PDFexecutesavenamed {/Named /N /SaveAs}
+\def\PDFexecuteopennamed {/Named /N /Open}
+\def\PDFexecutehelp {/Named /N /HelpUserGuide}
+\def\PDFexecutetoggle {/Named /N /FullScreen}
+\def\PDFexecutesearch {/Named /N /Find}
+\def\PDFexecutesearchagain {/Named /N /FindAgain}
+\def\PDFexecutegotopage {/Named /N /GoToPage}
+\def\PDFexecutequery {/Named /N /AcroSrch:Query}
+\def\PDFexecutequeryagain {/Named /N /AcroSrch:NextHit}
+\def\PDFexecutefitwidth {/Named /N /FitWidth}
+\def\PDFexecutefitheight {/Named /N /FitHeight}
+
+\let\PDFobjectclass\empty
+\let\PDFobjectname \empty
+
+\def\dostartexecutecommand#1#2#3#4%
+ {\doifdefined{PDFexecute#3}
+ {\bgroup
+ \edef\argument{#4}%
+ \ifx\argument\empty
+ \let\argumentA\empty
+ \let\argumentB\empty
+ \else
+ \@EA\dogetcommalistelement\@EA1\@EA\from#4\to\argumentA
+ \@EA\dogetcommalistelement\@EA2\@EA\from#4\to\argumentB
+ \fi
+ \edef\action%
+ {/S \getvalue{PDFexecute#3}}%
+ \ifsecondaryreference
+ \savesecondaryPDFreference\action
+ \else
+ \getsecondaryPDFreferences
+% \ifx\PDFobjectclass\empty
+% \let\next\insertpdfaction
+% \else
+% \edef\next{\createpdfactionobject{\PDFobjectclass}{\PDFobjectname}}%
+% \globalletempty\PDFobjectclass
+% \globalletempty\PDFobjectname
+% \fi
+% \next
+ \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}%
+ \fi
+ \egroup}}
+
+%D \macros
+%D {dosetupidentity}
+%D
+%D Documents can be tagged with an application accessible title
+%D and subtitle, the authorname, a date, the creator, keywords
+%D etc. For the moment \PDFTEX\ only supports the first three
+%D of these.
+
+\def\dosetupidentity#1#2#3#4#5#6%
+ {\normalexpanded{\noexpand\appendtopdfinfo
+ {/Title <\hexifiedPDFstring{#1}>
+ /Subject <\hexifiedPDFstring{#2}>
+ /Author <\hexifiedPDFstring{#3}>
+ /Creator <\hexifiedPDFstring{#4}>
+ /ModDate (#4)
+ /ID (\jobname.#5) % needed for pdf/x
+ /Keywords <\hexifiedPDFstring{#6}>}}}
+
+%D \macros
+%D {dostartrunprogam}
+%D
+%D We can run a program form within a document, although this
+%D feature is rather weak, due to path problems and buggy
+%D argument passing.
+
+\def\dostartrunprogram#1#2#3#4% new: #3 => #3#4
+ {\bgroup
+ %\edef\string{#3}%
+ %\@EA\beforesplitstring\string\at{ }\to\program
+ %\@EA\aftersplitstring \string\at{ }\to\parameters
+ %\edef\action%
+ % {/S /Launch /F (\program) /P (\parameters) /D (.)}%
+ \edef\action
+ {/S /Launch /F (#3) /P (#4) /D (.)}%
+ \ifsecondaryreference
+ \savesecondaryPDFreference\action
+ \else
+ \getsecondaryPDFreferences
+ \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}%
+ \fi
+ \egroup}
+
+%D \macros
+%D {dostartgotoprofile, dostopgotoprofile,
+%D dobeginofprofile, doendofprofile}
+%D
+%D \CONTEXT\ user profiles and version control fall back on
+%D \PDF\ article threads. Unfortunately one cannot influence
+%D the view yet in an (for me) acceptable way.
+
+\def\dostartgotoprofile#1#2#3% to be done: file
+ {\bgroup
+ \setPDFdestination{#3}%
+ \doifsomething\PDFdestination
+ {\edef\action
+ {/S /Thread /D (\PDFdestination)}%
+ \ifsecondaryreference
+ \savesecondaryPDFreference\action
+ \else
+ \getsecondaryPDFreferences
+ \insertpdfaction{\PDFswapdir#1}{#2}{\action \secondaryPDFreferences}%
+ \fi}%
+ \egroup}
+
+%D Some day, I'll reimplement threading in a useful way.
+%D Currently the viewers handle threads rather diffuse.
+
+\def\dobeginofprofile#1#2#3#4%
+ {\setPDFdestination{#1}%
+ \doifsomething\PDFdestination
+ {\pdfthread
+ width #2 height #3
+ attr {/Title (\PDFdestination)} % can be omitted
+ name {\PDFdestination}}}
+
+\def\doendofprofile
+ {}
+
+%D \macros
+%D {doinsertbookmark}
+%D
+%D In \PDF\ bookmarks are the building blocks of a viewer
+%D provided sort of table of contents. \TEX\ has to provide
+%D the entry as well as the number of child entries. Strings
+%D need to be sanatized as good as possible to suit the default
+%D encoding. In \CONTEXT\ users can overrule this string by
+%D supplying an alternative one. Look at the macro called for
+%D to see how funny these bookmarks are defined.
+
+\def\doinsertbookmark#1#2#3#4#5% level sublevels text page open=1
+ {\bgroup
+ \doPDFgetpagereference{#4}\PDFobjectreference
+ \pdfoutline
+ user {<</S /GoTo /D [\PDFobjectreference\space\PDFpageviewwrd]>>}%
+ \ifcase#2 \else count \ifcase#5-\fi#2 \fi
+% {<\hexifiedPDFstring{#3}>}% goes wrong
+ {<#3>}%
+ \egroup}
+
+%D \macros
+%D {dostartobject,dostopobject,doinsertobject}
+%D
+%D Due to \PDF's object oriented character, we can include and
+%D reuse objects. These can be compared with \TEX's boxes. The
+%D \TEX\ counterpart is defined in the module \type{spec-dvi}.
+%D We don't use the dimensions here.
+%D
+%D The next solution is not that beautiful. Because objects are
+%D containers for whatever kind of content, graphics can be
+%D part of this content, and a graphic object can be part of
+%D the more general type. In practice this means that an ximage
+%D would be embedded in an xform, which in itself is not that
+%D big a problem, apart from a few bytes overhead. However, for
+%D reasons unknown to me alternative images must be pure
+%D ximages |<|indeed, somehow one cannot use a vector graphic
+%D as alternative|>| that are not embedded into forms, so this
+%D is why the object handler treats them different. This
+%D implies knowledge of the calling routines, especially the
+%D \type{FIG} trigger, that signals that we just embedded an
+%D image. Alternatively I could have introduced a dual object
+%D system, but the overhead in duplicate specials is currently
+%D not what we want. I'd rather implement a more mature
+%D object support system from scratch.
+
+\let\currentPDFresources\empty
+\let\PDFimageattributes \empty
+\let\PDFfigurereference \empty
+\let\PDFimagereference \empty
+
+\def\dostartobject#1#2#3#4#5%
+ {\bgroup
+ \setbox\nextbox\vbox\bgroup
+ \def\dodostopobject
+ {\egroup
+ \ifx\PDFimagereference\empty
+ % We also flush page resources, since shared
+ % resources end up there; otherwise transparencies
+ % won't work in xforms; some day I will optimize
+ % this.
+ \the\everyPDFxform
+ \finalizeobjectbox\nextbox
+ \immediate\pdfxform
+ resources {\currentPDFresources\the\pdfpageresources}%
+ \nextbox
+ \global\let\currentPDFresources\empty
+ \dosetobjectreference{#1}{#2}{\the\pdflastxform}%
+ \else
+ \dosetobjectreference{#1}{#2}{-\PDFimagereference}%
+ \global\let\PDFimagereference\empty
+ \fi}}
+
+\def\dostopobject
+ {\dodostopobject
+ \egroup}
+
+\def\doresetobjects
+ {\global\let\PDFimagereference\empty}
+
+\def\doinsertobject#1#2%
+ {\bgroup
+ \doifobjectreferencefoundelse{#1}{#2}
+ {\dogetobjectreference{#1}{#2}\PDFobjectreference
+ \ifnum\PDFobjectreference<0
+ \@EA\@EA\@EA\pdfrefximage\@EA\gobbleoneargument\PDFobjectreference
+ \else
+ \pdfrefxform\PDFobjectreference
+ \fi}%
+ {}%
+ \egroup}
+
+\appendtoksonce
+ \collectPDFresources
+ \global\let\currentPDFresources\collectedPDFresources
+\to \everyPDFxform
+
+%D \macros
+%D {dosetpagetransition}
+%D
+%D Page transitions only make sence in presentations. They are
+%D passed as raw \PDF\ code to the page object. Take a look
+%D at the implementation to get an impression of the rubish
+%D passed on.
+%D
+%D This array holds a reasonable selection of transitions
+%D (watch out: \type{replace} is not in this list). Most of
+%D the transitions look awful anyway. By the way, \CONTEXT\ is
+%D able to select transitions randomly.
+
+\def\pagetransitions
+ {{split,in,vertical},{split,in,horizontal},
+ {split,out,vertical},{split,out,horizontal},
+ {blinds,horizontal},{blinds,vertical},
+ {box,in},{box,out},
+ {wipe,east},{wipe,west},{wipe,north},{wipe,south},
+ dissolve,
+ {glitter,east},{glitter,south},
+ {fly,in,east},{fly,in,west},{fly,in,north},{fly,in,south},
+ {fly,out,east},{fly,out,west},{fly,out,north},{fly,out,south},
+ {push,east},{push,west},{push,north},{push,south},
+ {cover,east},{cover,west},{cover,north},{cover,south},
+ {uncover,east},{uncover,west},{uncover,north},{uncover,south},
+ fade}
+
+%D Again, we use macros as placeholders for \PDF\ key||value
+%D pairs.
+
+\def\PDFpagesplit {/S /Split }
+\def\PDFpageblinds {/S /Blinds }
+\def\PDFpagebox {/S /Box }
+\def\PDFpagewipe {/S /Wipe }
+\def\PDFpagedissolve {/S /Dissolve }
+\def\PDFpageglitter {/S /Glitter }
+\def\PDFpagereplace {/S /R }
+
+\def\PDFpagefly {/S /Fly } % 1.5
+\def\PDFpagepush {/S /Push } % 1.5
+\def\PDFpagecover {/S /Cover } % 1.5
+\def\PDFpageuncover {/S /Uncover } % 1.5
+\def\PDFpagefade {/S /Fade } % 1.5
+
+\def\PDFpagehorizontal {/Dm /H }
+\def\PDFpagevertical {/Dm /V }
+\def\PDFpagein {/M /I }
+\def\PDFpageout {/M /O }
+\def\PDFpageeast {/Di 0 }
+\def\PDFpagenorth {/Di 90 }
+\def\PDFpagewest {/Di 180 }
+\def\PDFpagesouth {/Di 270 }
+
+\def\dodoPDFsetpagetransition#1%
+ {\doifdefined{PDFpage#1}
+ {\edef\PDFpagetransitions{\PDFpagetransitions\getvalue{PDFpage#1}}}}
+
+\def\dosetpagetransition#1#2%
+ {\let\PDFpagetransitions\empty
+ \processcommalist[#1]\dodoPDFsetpagetransition
+ \appendtopdfpageattributes
+ %{\ifnum#2>0 /Dur #2 \fi
+ {\ifnum0<0#2 /Dur #2 \fi
+ \ifx\PDFpagetransitions\empty\else/Trans <<\PDFpagetransitions>>\fi}}
+
+%D The expansion is needed because else the \type{\pdfpageattr}
+%D token list flushes an unexpanded \type{\csname}. The
+%D \type{\global} is needed because the assignment can take
+%D place deeply buried (for instance in the \type{\shipout}
+%D box.
+
+%D \macros
+%D {doinsertcomment, doflushcomments}
+%D
+%D Text annotation, or comments, are provided too:
+
+%D \macros
+%D {dopresetlinefield,dopresettextfield,
+%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield,
+%D dopresetpushfield,dopresetcheckfield,
+%D dopresetradiofield,dopresetradiorecord}
+%D
+%D \PDF\ offers extensive field support. The next bunch of
+%D definitions map the specials.
+
+%D \macros
+%D {dodefinefieldset,dogetfieldset,doiffieldset}
+%D
+%D Field sets, needed for reset and submit handling, are
+%D taken care of by:
+
+%D The next section of this module is dedicated to form
+%D support. These macros are complicated by the fact that
+%D cloning is possible.
+
+%D \macros
+%D {FDFflag...,FDFplus...}
+%D
+%D The \type{/FT} key determines the type of field: text,
+%D button or choice. The latter two come in several disguises,
+%D which are set by flipping bits in the \type{/Ff}. Other bits
+%D are used to set states. Personally I hate this bitty way of
+%D doing things. The next six bit determine the field sub type:
+
+\def\FDFflagMultiLine {4096} % 13
+\def\FDFflagNoToggleToOff {16384} % 15
+\def\FDFflagRadio {32768} % 16
+\def\FDFflagPushButton {65536} % 17
+\def\FDFflagPopUp {131072} % 18
+\def\FDFflagEdit {262144} % 19
+
+% bugged anyway, so we need to drop it:
+
+\def\FDFflagRadiosInUnison {33554432} % 26
+
+%D A few more (pdf 1.4) flags, what the spell check one: for
+%D obscure reasons for Adobe downward compatibility means
+%D enabling features that harm old applications like testing.
+
+\def\FDFflagDoNotSpellCheck {4194304} % 23
+\def\FDFflagDoNotScroll {8388608} % 24
+
+%D The next bits (watch how strange the bits are organized)
+%D take care of the states:
+
+\def\FDFflagReadOnly {1} % 1
+\def\FDFflagRequired {2} % 2
+\def\FDFflagNoExport {4} % 3
+\def\FDFflagPassword {8192} % 14
+\def\FDFflagSort {524288} % 20
+\def\FDFflagFileSelect {1048576} % 21
+
+%D There is a second, again bitset oriented, \type{/F} flag:
+
+\def\FDFplusInvisible {1} % 1
+\def\FDFplusHidden {2} % 2
+\def\FDFplusPrintable {4} % 3
+
+%def\FDFplusNoView {32} % 6
+%def\FDFplusToggleNoView {256} % 9
+
+\def\FDFplusAutoView {256} % {288} % 6+9
+
+%D \macros
+%D {setFDFswitches}
+%D
+%D The non||type bits are mapped onto user||interface
+%D swithes, to be used later on:
+
+\def\@@FDFflag{FDFflag}
+\def\@@FDFplus{FDFplus}
+
+\letvalue {\@@FDFflag\v!readonly}=\FDFflagReadOnly
+\letvalue {\@@FDFflag\v!required}=\FDFflagRequired
+\letvalue {\@@FDFflag\v!protected}=\FDFflagPassword
+\letvalue {\@@FDFflag\v!sorted}=\FDFflagSort
+\letvalue {\@@FDFflag\v!unavailable}=\FDFflagNoExport
+\letvalue {\@@FDFflag\v!nocheck}=\FDFflagDoNotSpellCheck
+\letvalue {\@@FDFflag\v!fixed}=\FDFflagDoNotScroll
+\letvalue {\@@FDFflag\v!file}=\FDFflagFileSelect
+
+\letvalue {\@@FDFplus\v!hidden}=\FDFplusHidden
+\letvalue {\@@FDFplus\v!printable}=\FDFplusPrintable
+
+\letvalue {\@@FDFplus\v!auto}=\FDFplusAutoView
+
+%D A set of switches is collected into the flags we mentioned
+%D before by the next macro (we don't handle negations yet,
+%D but do take care of redundancy):
+
+\def\FDFflag{0}
+\def\FDFplus{0}
+
+\def\setFDFswitches[#1]%
+ {\bgroup
+ \!!counta\zerocount
+ \!!countb\zerocount
+ \def\docommand##1%
+ {\doifsomething{##1}
+ {\advance\!!counta 0\getvalue{\@@FDFflag##1}%
+ \setvalue{\@@FDFflag##1}{0}%
+ \advance\!!countb 0\getvalue{\@@FDFplus##1}%
+ \setvalue{\@@FDFplus##1}{0}}}%
+ \processcommacommand[#1]\docommand
+ \xdef\FDFflag{\the\!!counta}%
+ \xdef\FDFplus{\the\!!countb}%
+ \egroup}
+
+%D \macros
+%D {setFDFvalues}
+%D
+%D Menu items are passed as an array of \type{(string)}'s and
+%D the content of this array is build with:
+
+\let\FDFvalues \empty
+\let\FDFfirstvalues \empty
+\let\FDFsecondvalues\empty
+\let\FDFkidlist \empty
+\let\FDFdefaultindex\!!zerocount
+\let\FDFdefaultvalue\empty
+
+% Why do we need to tweak this mechanism each time acrobat updates ...
+% it would make sense to have version specific sections in pdf files
+% since my guess is that it never will be done right since each year
+% new programmers have new ideas about what is supposed to happen with
+% kids. So .. best is not to trust this feature esp not for radio
+% widgets. (new flags, different interpretation of AS etc etc)
+
+\def\setFDFvalues[#1][#2]% #1 = list (item=>value) #2 = default
+ {\let\FDFvalues \empty
+ %when radio opt works ok
+ %\let\FDFfirstvalues \empty
+ %\let\FDFsecondvalues\empty
+ \let\FDFkidlist \empty
+ %\let\FDFdefaultindex\!!zerocount
+ %\let\FDFdefaultvalue\empty
+ %\scratchcounter\zerocount
+ \def\dodocommand##1=>##2=>##3\end
+ {\addtocommalist{##1}\FDFkidlist
+ %\edef\FDFfirstvalues{\FDFfirstvalues(##1)}%
+ %\doif{##1}{#2}{\edef\FDFdefaultindex{\the\scratchcounter}}%
+ %\advance\scratchcounter\plusone
+ \doifelsenothing{##2}
+ {\doif{##1}{#2}{\edef\FDFdefaultvalue{##1}}%
+ %\edef\FDFsecondvalues{\FDFsecondvalues(##1)}%
+ \edef\FDFvalues{\FDFvalues [(##1)(##1)] }}
+ {\doif{##1}{#2}{\edef\FDFdefaultvalue{##2}}%
+ %\edef\FDFsecondvalues{\FDFsecondvalues(##2)}%
+ \edef\FDFvalues{\FDFvalues [(##2)(##1)] }}}% ! ##1 is shown
+ \def\docommand##1%
+ {\dodocommand##1=>=>\end}%
+ \expanded{\processcommalist[#1]}\docommand}
+
+%D This macro accepts comma separated \type{visual=>result}
+%D pairs.
+
+%D \macros
+%D {setFDFalignment}
+%D
+%D Text and line fields can be entered and showed in three
+%D alternative alingments, indicated by a digit:
+
+\def\FDFalign{0}
+
+\def\setFDFalignment[#1]%
+ {\processaction
+ [#1]
+ [ \v!left=>\edef\FDFalign{2}, % raggedleft
+ \v!middle=>\edef\FDFalign{1}, % raggedcenter
+ \v!right=>\edef\FDFalign{0}]} % raggedright
+
+%D \macros
+%D {setFDFattributes}
+%D
+%D The weak part of (at least version 2.1 \PDF) is that only
+%D default fonts are handled well. Another restriction is that
+%D the encoding vector must be the standard \PDF\ document one.
+%D Although the \PDF\ reference explictly states that one could
+%D use the normal text operators, leading is not yet handled.
+%D
+%D For the moment the current \CONTEXT\ font is mapped onto
+%D one best suitable default font. The color attribute is
+%D less problematic and is directly derived from the \CONTEXT\
+%D color.
+
+\def\FDFattributes{/Helv 12 Tf 0 g 14.4 TL}
+
+\def\FDFrm {TiRo} \def\FDFss {Helv} \def\FDFtt {Cour}
+\def\FDFrmtf{TiRo} \def\FDFsstf{Helv} \def\FDFtttf{Cour}
+\def\FDFrmbf{TiBo} \def\FDFssbf{HeBo} \def\FDFttbf{CoBo}
+\def\FDFrmit{TiIt} \def\FDFssit{HeOb} \def\FDFttit{CoOb}
+\def\FDFrmsl{TiIt} \def\FDFsssl{HeOb} \def\FDFttsl{CoOb}
+\def\FDFrmbi{TiBI} \def\FDFssbi{HeBO} \def\FDFttbi{CoBO}
+\def\FDFrmbs{TiBI} \def\FDFssbs{HeBO} \def\FDFttbs{CoBO}
+
+\let\FDFusedfonts=\FDFsstf
+
+\def\setFDFattributes[#1,#2,#3,#4]% style, color, backgroundcolor, framecolor
+ {\bgroup % nog interlinie: n TL
+ \setbox\scratchbox\hbox
+ \bgroup
+ \doconvertfont{#1}{}%
+ \PointsToBigPoints\bodyfontsize\size % x/xx, so better the actual size
+ \doifdefinedelse{FDF\fontstyle\fontalternative}
+ {\xdef\FDFattributes{\getvalue{FDF\fontstyle\fontalternative}}}
+ {\doifdefinedelse{FDF\fontstyle}
+ {\xdef\FDFattributes{\getvalue{FDF\fontstyle}}}
+ {\xdef\FDFattributes{\FDFrm}}}%
+ \doglobal\addtocommalist\FDFattributes\FDFusedfonts
+ \xdef\FDFattributes% move up with "x.y Ts"
+ {/\FDFattributes\space\size\space Tf\space\PDFcolor{#2}}%
+ \doifelsenothing{#3}
+ {\global\let\FDFsurroundings\empty}
+ {\xdef\FDFsurroundings{/BG \FDFcolor{#3}}}%
+ \doifsomething{#4}
+ {\xdef\FDFsurroundings{\FDFsurroundings\space /BC \FDFcolor{#4}}}%
+ \ifx\FDFsurroundings\empty \else
+ \xdef\FDFsurroundings{/MK << \FDFsurroundings\space>>}%
+ \fi
+ \egroup
+ \egroup}
+
+%D \macros
+%D {setFDFactions}
+%D
+%D Depending on the type of the field, one can assign
+%D \JAVASCRIPT\ code to a mouse event or keystroke. The next
+%D preparation macro shows what events are handled.
+
+\let\FDFactions\empty
+
+\def\setFDFactions[#1,#2,#3,#4,#5,#6,#7,#8,%
+ {\global\let\FDFactions\empty
+ \setFDFaction D#1% mousedown
+ \setFDFaction U#2% mouseup
+ \setFDFaction E#3% enterregion
+ \setFDFaction X#4% exitregion
+ \setFDFaction K#5% afterkeystroke
+ \setFDFaction F#6% formatresult
+ \setFDFaction V#7% validateresult
+ \setFDFaction C#8% calculatewhatever
+ \setFDFactionsmore}
+
+\def\setFDFactionsmore#1,#2]%
+ {\setFDFaction{Fo}#1% focusin
+ \setFDFaction{Bl}#2% focusout % was I (now pdf ref manual explicitly talks about lowercase l)
+ \ifx\FDFactions\empty\else
+ \xdef\FDFactions{/AA << \FDFactions >>}% since 1.3 no longer inherited
+ \fi}
+
+% todo, when new var scheme is implemented
+%
+% \setFDFaction{PO}\@@DriverFieldPageOpen
+% \setFDFaction{PC}\@@DriverFieldPageClose
+% \setFDFaction{PV}\@@DriverFieldPageVisible
+% \setFDFaction{PI}\@@DriverFieldPageInVisible
+
+%D The event handler becomes something:
+%D
+%D \starttyping
+%D /AA << /D << /S ... >> ... /C << /S ... >>
+%D /A << /S /JavaScript /JS (...) >>
+%D \stoptyping
+
+\def\setFDFaction#1#2%
+ {\bgroup
+ \def\docommand{\xdef\FDFactions{\FDFactions /#1 << \lastPDFaction >> }}%
+ \@EA\handlereferenceactions\@EA{#2}\docommand % one level expansion
+ \egroup}
+
+%D \macros
+%D {testFDFactions}
+%D
+%D This rather confusion prone series of script can be tested
+%D with:
+%D
+%D \starttyping
+%D \testFDFactions
+%D \stoptyping
+%D
+%D which simply redefined the previous macro to one that prints
+%D a message to the console.
+
+\def\testFDFactions
+ {\def\setFDFaction##1##2%
+ {\doPSsanitizeJScode console.show();console.println("executing:##1"); \to\sanitizedJScode
+ \edef\FDFactions{\FDFactions /##1 << /S /JavaScript /JS (\sanitizedJScode) >> }}}
+
+%D \macros
+%D {doregistercalculationset}
+%D
+%D There is at most one calculation order list, which defines
+%D the order in which fields are calculated. The calculation
+%D order is defined using:
+
+\let\PDFcalculationset\empty
+
+\def\doregistercalculationset#1%
+ {\def\PDFcalculationset{#1}}
+
+%D \macros
+%D {registerFDFobject,everylastshipout}
+%D
+%D Officially one needs to embed some general datastructures
+%D that tell the viewer what fields are present in the file, as
+%D well as what resources they use. The next mechanism does that
+%D job automatically when one registers the field.
+
+\def\flushFDFnames
+ {\ifx\FDFcollection\empty\else
+ \defineFDFfonts
+ \createpdfarrayobject{FDF}{local:fields}{\FDFcollection}%
+ \doPDFgetobjectreference{FDF}{local:fields}\PDFobjectreference
+ % The /NeedAppearances is pretty important because
+ % otherwise Acrobat 5 blows up on cloned radio widgets
+ \createpdfdictionaryobject{FDF}{local:acroform}
+ {/Fields \PDFobjectreference\space
+ /NeedAppearances true
+ \doiffieldset\PDFcalculationset{/CO [\dogetfieldset\PDFcalculationset]}
+ /DR << /Font << \FDFfonts >> >>
+ /DA (/Helv 10 Tf 0 g)}%
+ \doPDFgetobjectreference{FDF}{local:acroform}\PDFobjectreference
+ \appendtopdfcatalog
+ {/AcroForm \PDFobjectreference}%
+ \global\let\FDFcollection\empty
+ \global\let\flushFDFnames\relax
+ \fi}
+
+\let\FDFcollection\empty
+
+\def\registerFDFobject#1%
+ {\ifx\flushFDFnames\relax
+ \writestatus{FDF}{second run needed for field list (#1)}%
+ \fi
+ \doPDFgetobjectreference{FDF}{#1}\PDFobjectreference
+ \xdef\FDFcollection{\FDFcollection\space\PDFobjectreference}}
+
+\appendtoksonce \flushFDFnames \to \everylastshipout % test \everybye / was \prependtoksonce
+
+%D \macros
+%D {defineFDFfonts}
+%D
+%D Another datastruture concerns the fonts used. We only
+%D define the fonts we use.
+
+\def\defineFDFfonts
+ {\let\FDFfonts\empty
+ \processcommacommand[\FDFusedfonts]\defineFDFfont}
+
+\def\defineFDFfont#1%
+ {\createpdfdictionaryobject{FDF}{local:#1}
+ {/Type /Font
+ /Subtype /Type1
+ /Name /#1
+ /BaseFont /\getvalue{FDFname#1}}%
+ \doPDFgetobjectreference{FDF}{local:#1}\PDFobjectreference
+ \edef\FDFfonts{\FDFfonts \space/#1 \PDFobjectreference}}
+
+%D Another list of constants:
+
+\def\FDFnameTiRo {Times-Roman}
+\def\FDFnameTiBo {Times-Bold}
+\def\FDFnameTiIt {Times-Italic}
+\def\FDFnameTiBI {Times-BoldItalic}
+\def\FDFnameHelv {Helvetica}
+\def\FDFnameHeBo {Helvetica-Bold}
+\def\FDFnameHeOb {Helvetica-Oblique}
+\def\FDFnameHeBO {Helvetica-BoldOblique}
+\def\FDFnameCour {Courier}
+\def\FDFnameCoBo {Courier-Bold}
+\def\FDFnameCoOb {Courier-Oblique}
+\def\FDFnameCoBO {Courier-BoldOblique}
+
+%D \macros
+%D {currentFDFmode,currentFDFparent,currentFDFkids,currenrFDFroot}
+%D
+%D There are three more quasi global interfacing variables
+%D that need to be set.
+
+\let\currentFDFmode \fieldlonermode
+\let\currentFDFkids \empty
+\let\currentFDFparent\empty
+\let\currentFDFroot \empty
+
+%D \macros
+%D {dosetfieldstatus}
+%D
+%D And here comes the special that deals with them.
+
+\def\dosetfieldstatus#1#2#3#4%
+ {\chardef\currentFDFmode #1%
+ \edef\currentFDFparent {#2}%
+ \edef\currentFDFkids {#3}%
+ \edef\currentFDFroot {#4}}
+
+%D We already dealt with the encoding vector. Conversion from
+%D \TEX\ \ASCII\ encoding to the other one, is accomplished by
+%D the next few macros. Wach out: we don't group here.
+
+\appendtoksonce
+ \simplifycommands
+\to \everysetfield
+
+%D \macros
+%D {doPDFinsertcomment}
+%D
+%D An example its use is the next special, one that deals with
+%D text annotations.
+
+\newcounter\nofFDFcomments
+
+\newif\ifPDFpopupcomments \PDFpopupcommentstrue
+
+\def\doflushcomments
+ {\box\PDFsymbolbox}
+
+\long\def\doinsertcomment#1#2#3#4#5#6#7#8% % \@@DriverCommentLayer set otherwise
+ {\bgroup % title width height color open symbol collect data
+ \presetPDFsymbolappearance{#4}{#6}{#2}{#3}\!!zeropoint% sets width/height
+ \doifelsenothing{#1}
+ {\let\PDFidentifier\empty}
+ {\sanitizePDFencoding#1\to\PDFcommenttitle
+ \def\PDFidentifier{/T <\PDFcommenttitle>}}%
+ \sanitizePDFencoding#8\to\PDFdata
+ \setFDFlayer\@@DriverCommentLayer
+ \startPDFsymbolappearance
+ \ifPDFpopupcomments
+ \doglobal\increment\nofFDFcomments
+ \doifobjectreferencefoundelse{FDF}{c:\nofFDFcomments}
+ {\doPDFgetobjectreference{FDF}{c:\nofFDFcomments}\PDFobjectreference
+ \donetrue}
+ \donefalse
+ \ifdone
+ \setbox\scratchbox\hbox
+ {\createpdfannotationobject{FDF}{c::\nofFDFcomments}{#2}{#3}% text window, size does not work
+ {/Subtype /Popup
+ /Parent \PDFobjectreference}}%
+ \ifcase#7\relax
+ \vbox to \height{\forgetall\vskip#3\box\scratchbox\vss}%
+ \else % incredible trial and error hack
+ % it's quite a mess, the annot width cannot be set, well, it can
+ % but the appearance and text sizes get mixed up
+% \setbox\scratchbox\vbox to \height{\forgetall\vskip#3\box\scratchbox\vss}%
+% \global\setbox\PDFsymbolbox\vbox
+% {\hsize#2%
+% \forgetall
+% \vsmash{\box\PDFsymbolbox}
+% \box\scratchbox}%
+ % this may change when acrobat gets less bugged
+ \setbox\scratchbox\vbox to #3{\forgetall\vss\box\scratchbox}%
+ \wd\scratchbox#2%
+ \global\setbox\PDFsymbolbox\vbox
+ {\startoverlay{\box\PDFsymbolbox}{\box\scratchbox}\stopoverlay}%
+ \fi
+ \fi
+ % generic
+ \doifobjectreferencefoundelse{FDF}{c::\nofFDFcomments}
+ {\doPDFgetobjectreference{FDF}{c::\nofFDFcomments}\PDFobjectreference
+ \donetrue}
+ \donefalse
+ \createpdfannotationobject{FDF}{c:\nofFDFcomments}{\width}{\height}
+ {/Subtype /Text
+ \ifcase#5 \else/Open true\fi
+ % pdftex (efficient)
+ % \ifdone /Popup \PDFobjref\pdflastannot\fi
+ % generic (less efficient)
+ \ifdone /Popup \PDFobjectreference\fi
+ /Contents <\PDFdata>
+ \PDFidentifier
+ \FDFlayer
+ \PDFsymbol
+ \PDFattributes}%
+ \else
+ \insertpdfannotation{#2}{#3}
+ {/Subtype /Text
+ \ifcase#5 \else/Open true\fi
+ /Contents <\PDFdata>
+ \FDFlayer
+ \PDFsymbol
+ \PDFidentifier
+ \PDFattributes}%
+ \fi
+ \stopPDFsymbolappearance
+ \egroup}
+
+% symbols with a reasonable default of 18/24 pt
+
+\newbox\PDFsymbolbox
+
+\def\PDFsymbolNew {/Insert}
+\def\PDFsymbolBalloon {/Comment}
+\def\PDFsymbolAddition {/NewParagraph}
+\def\PDFsymbolHelp {/Help}
+\def\PDFsymbolParagraph {/Paragraph}
+\def\PDFsymbolKey {/Key }
+
+\def\PDFsymbolGraph {/Graph}
+\def\PDFsymbolPaperclip {/Paperclip}
+\def\PDFsymbolAttachment{/Attachment}
+\def\PDFsymbolTag {/Tag}
+
+\def\startPDFsymbolappearance
+ {\setbox\scratchbox\vbox to \totalheight \bgroup \vfill}
+
+\def\stopPDFsymbolappearance
+ {\egroup
+ \setbox\scratchbox\hbox{\lower\depth\box\scratchbox}%
+ \wd\scratchbox\width
+ \ht\scratchbox\height
+ \dp\scratchbox\depth
+ \box\scratchbox}
+
+\def\presetPDFsymbolappearance#1#2#3#4#5% symbol color width height depth
+ {\doifelsenothing{#1}
+ {\let\PDFattributes\empty}
+ {\def\PDFattributes{/C \FDFcolor{#1}}}%
+ \scratchdimen#3\edef\width {\the\scratchdimen}%
+ \scratchdimen#4\edef\height{\the\scratchdimen}%
+ \scratchdimen#5\edef\depth {\the\scratchdimen}%
+ \advance\scratchdimen\height\edef\totalheight{\the\scratchdimen}%
+ \doifelsenothing{#2}
+ {\let\PDFsymbol\empty}
+ {\ifundefined{PDFsymbol#2}%
+ \getfromcommacommand[#2][1]\let\PDFsymbolnormalsymbol\commalistelement
+ \getfromcommacommand[#2][2]\let\PDFsymboldownsymbol \commalistelement
+ \doifsymboldefinedelse\PDFsymbolnormalsymbol
+ {\doifsymboldefinedelse\PDFsymboldownsymbol
+ {\dopresetPDFsymbolappearance
+ \PDFsymbolnormalsymbol\PDFsymboldownsymbol}
+ {\dopresetPDFsymbolappearance
+ \PDFsymbolnormalsymbol\PDFsymbolnormalsymbol}}
+ {\doifsymboldefinedelse\PDFsymboldownsymbol
+ {\dopresetPDFsymbolappearance
+ \PDFsymboldownsymbol\PDFsymboldownsymbol}
+ {\let\PDFsymbol\empty}}%
+ \else
+ \def\PDFsymbol{/Name \getvalue{PDFsymbol#2} }%
+ \fi}}
+
+\def\dopresetPDFsymbolappearance#1#2%
+ {\dopresetfieldsymbol{#1}%
+ \dopresetfieldsymbol{#2}%
+ \setbox\scratchbox\hbox{\symbol[#1]}%
+ \edef\width {\the\wd\scratchbox}%
+ \edef\height{\the\ht\scratchbox}%
+ \edef\depth {\the\dp\scratchbox}%
+ \scratchdimen\height \advance\scratchdimen\depth
+ \edef\totalheight{\the\scratchdimen}%
+ \doPDFgetobjectreference{SYM}{#1}\FDFsymbolNappearance
+ \doPDFgetobjectreference{SYM}{#2}\FDFsymbolDappearance
+ \edef\PDFsymbol
+ {/AP <</N \FDFsymbolNappearance /D \FDFsymbolDappearance>>}}
+
+%D Hooked into \CONTEXT, this special supports
+%D
+%D \starttyping
+%D \startcomment
+%D hello beautiful\\world
+%D \stopcomment
+%D
+%D \startcomment[hello]
+%D de \'e\'erste keer
+%D the f\'irst time
+%D \stopcommen
+%D
+%D \startcommentaar[hallo][color=green,width=4cm,height=3cm]
+%D first
+%D
+%D second
+%D \stopcommentaar
+%D \stoptyping
+%D
+%D So, special characters, forced linebreaks using \type{\\}
+%D and \type{\par} are handled in the appropriate way.
+
+%D \macros
+%D {dosetuppageview}
+%D
+%D Because this command will seldom be called, we can permit
+%D slow action processing. We need three settings, one for
+%D direct \PDF\ inclusion, the other as \PDFTEX\ keyword, an
+%D a last one for form. All determine in what way the
+%D screen is adapted when going to a destination. Watch the
+%D space.
+
+\def\PDFpageviewkey{fit}
+\def\PDFpageviewwrd{/Fit}
+\def\PDFpageview {/View [\PDFpageviewwrd] }
+\def\PDFpagexyzspec{0 0 0} % hack, pdftex does handle this
+\let\PDFpagexyzspec\empty % hack, pdftex does not accept spec
+
+\def\dosetuppageview#1% watch the v-h swapping here
+ {\processaction
+ [#1]
+ [ \v!fit=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit},
+ \v!width=>\def\PDFpageviewkey {fith}\def\PDFpageviewwrd{/FitH},
+ \v!height=>\def\PDFpageviewkey {fitv}\def\PDFpageviewwrd{/FitV},
+ \v!minwidth=>\def\PDFpageviewkey{fitbh}\def\PDFpageviewwrd{/FitBH},
+ \v!minheight=>\def\PDFpageviewkey{fitbv}\def\PDFpageviewwrd{/FitBV},
+ \v!standard=>\def\PDFpageviewkey{xyz \PDFpagexyzspec}\def\PDFpageviewwrd{/XYZ \PDFpagexyzspec},
+ \s!unknown=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit}]%
+ \edef\PDFpageview{/View [\PDFpageviewwrd]}}
+
+%D \macros
+%D {setFDFkids}
+%D
+%D Clones as well as radiofields (which themselves can have
+%D cloned components) need a list of kids. The next macro
+%D builds one.
+
+\def\setFDFkids[#1][#2]% tag commalist
+ {\let\FDFkids\empty
+ \def\docommand##1%
+ {\doPDFgetobjectreference{FDF}{#1##1}\PDFobjectreference
+ \edef\FDFkids{\FDFkids\PDFobjectreference\space}}%
+ \@EA\processcommalist\@EA[#2]\docommand
+ \ifx\FDFkids\empty\else\edef\FDFkids{/Kids [\FDFkids]}\fi}
+
+%D \macros
+%D {dopresetlinefield,dopresettextfield,
+%D dopresetchoicefield,dopresetpopupfield,dopresetcombofield,
+%D dopresetpushfield,dopresetcheckfield,
+%D dopresetfield,dopresetradiorecord}
+%D
+%D I would say: read the \PDF\ reference manual first and see
+%D what happens here next. Lucky us that they have so much in
+%D common.
+
+\def\dopresetlinefield#1#2#3#4#5#6#7#8#9%
+ {\bgroup
+ \setFDFlayer\@@DriverFieldLayer
+ \setFDFswitches[#7]%
+ \setFDFattributes[#6]%
+ \setFDFalignment[#8]%
+ \setFDFactions[#9]%
+ \edef\FDFtext{\hexifiedPDFstring{#4}}%
+ \ifcase\currentFDFmode
+ \createpdfannotationobject{FDF}{#1}{#2}{#3}
+ {/Subtype /Widget /T (#1) /FT /Tx
+ /MaxLen \ifcase0#5 1000 \else#5 \fi
+ %/DV (#4) /V (#4) % value added
+ /DV <\FDFtext> /V <\FDFtext>
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ /DA (\FDFattributes)
+ \FDFlayer\space
+ \FDFsurroundings\space
+ /Q \FDFalign\space
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ \setFDFkids[kids:][\currentFDFkids]%
+ \createpdfdictionaryobject{FDF}{#1}
+ {/T (#1) /FT /Tx
+ /MaxLen \ifcase0#5 1000 \else#5 \fi
+ \FDFkids\space
+ %/DV (#4) /V (#4) % value added
+ /DV <\FDFtext> /V <\FDFtext>
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ /DA (\FDFattributes)
+ \FDFlayer\space
+ \FDFsurroundings\space
+ /Q \FDFalign\space
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ /DA (\FDFattributes)
+ \FDFlayer\space
+ \FDFsurroundings\space
+ /Q \FDFalign\space
+ \FDFactions}%
+ \or
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference
+ /F \FDFplus
+ \FDFactions}%
+ \fi
+ \egroup}
+
+\def\dopresettextfield#1#2#3#4#5#6#7#8#9%
+ {\dopresetlinefield{#1}{#2}{#3}{#4}{#5}{#6}{MultiLine,#7}{#8}{#9}}
+
+\def\dopresetchoicefield#1#2#3#4#5#6#7#8%
+ {\bgroup
+ \setFDFlayer\@@DriverFieldLayer
+ \setFDFswitches[#6]%
+ \setFDFattributes[#5]%
+ \setFDFvalues[#7][#4]%
+ \setFDFactions[#8]%
+ \ifcase\currentFDFmode
+ \createpdfannotationobject{FDF}{#1}{#2}{#3}
+ {/Subtype /Widget
+ /T (#1) /FT /Ch
+ /DV (#4) /V (#4)
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ /DA (\FDFattributes)
+ \FDFlayer\space
+ \FDFsurroundings\space
+ /Opt [\FDFvalues]
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ \setFDFkids[kids:][\currentFDFkids]%
+ \createpdfdictionaryobject{FDF}{#1}
+ {/T (#1) /FT /Ch
+ \FDFkids\space
+ /DV (#4) /V (#4)
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ /DA (\FDFattributes)
+ \FDFlayer\space
+ \FDFsurroundings\space
+ /Opt [\FDFvalues]
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ /DA (\FDFattributes)
+ \FDFlayer\space
+ \FDFsurroundings\space
+ \FDFactions}%
+ \or
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference
+ /F \FDFplus
+ \FDFactions}%
+ \fi
+ \egroup}
+
+\def\dopresetpopupfield#1#2#3#4#5#6#7#8%
+ {\dopresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,#6}{#7}{#8}}
+
+\def\dopresetcombofield#1#2#3#4#5#6#7#8%
+ {\dopresetchoicefield{#1}{#2}{#3}{#4}{#5}{PopUp,Edit,#6}{#7}{#8}}
+
+\newif\ifFDFvalues
+
+\def\doFDFpresetpushcheckfield#1#2#3#4#5#6#7#8% in acro<5 (\FDFdefault)
+ {\bgroup % in acro>5 /\FDFdefault
+ \setFDFlayer\@@DriverFieldLayer
+ \ifcase#8\relax\FDFvaluesfalse\else\FDFvaluestrue\fi
+ \setFDFswitches[#5]%
+ \setFDFactions[#7]%
+ \doifelse{#4}{1}
+ {\def\FDFdefault{On}}
+ {\def\FDFdefault{Off}}%
+ \ifcase\currentFDFmode
+ \doFDFappearance{On}{#6}{#8}%
+ \createpdfannotationobject{FDF}{#1}{#2}{#3}
+ {/Subtype /Widget /T (#1) /FT /Btn
+ \ifFDFvalues
+ /DV /\FDFdefault\space
+ /V /\FDFdefault\space
+ /AS /\FDFdefault\space
+ \fi
+ \FDFlayer
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ \FDFlayer\space
+ \FDFappearance\space
+% /IF << /SW /N >> % strange, only works for stupid buttons
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or % no appearance and layer ?
+ \setFDFkids[kids:][\currentFDFkids]%
+ \createpdfdictionaryobject{FDF}{#1}
+ {/T (#1) /FT /Btn
+ \FDFkids\space
+ \ifFDFvalues
+ /DV /\FDFdefault\space
+ /V /\FDFdefault\space
+ /AS /\FDFdefault\space
+ \fi
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ \doFDFappearance{On}{#6}{#8}%
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference\space
+ \ifFDFvalues
+ /DV /\FDFdefault\space
+ /V /\FDFdefault\space
+ /AS /\FDFdefault\space
+ \fi
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ \FDFlayer\space
+ \FDFappearance\space
+ \FDFactions}%
+ \or
+ \doFDFappearance{On}{#6}{#8}%
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference\space
+ /F \FDFplus\space
+ \ifFDFvalues
+ /DV /\FDFdefault\space
+ /V /\FDFdefault\space
+ /AS /\FDFdefault\space
+ \fi
+ \FDFlayer\space
+ \FDFappearance
+ \FDFactions}%
+ \fi
+ \egroup}
+
+\def\dopresetpushfield#1#2#3#4#5#6#7%
+ {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{PushButton,#5}{#6}{#7}{0}}
+
+\def\dopresetcheckfield#1#2#3#4#5#6#7%
+ {\doFDFpresetpushcheckfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{1}}
+
+\def\dopresetradiofield#1#2#3#4#5#6#7#8%
+ {\bgroup
+ \setFDFlayer\@@DriverFieldLayer
+ \FDFvaluestrue
+ \setFDFswitches[#5]%
+ \setFDFactions[#8]%
+ \doifelsenothing{#4}
+ {\def\FDFdefault{Off}}
+ {\def\FDFdefault{#4}}%
+ \@EA\aftersplitstring\FDFdefault\at=>\to\FDFdefaultvalue
+ \ifx\FDFdefaultvalue\empty\else\let\FDFdefault\FDFdefaultvalue\fi
+ \ifcase\currentFDFmode
+ \doFDFappearance{#1}{#7}{1}%
+ \doPDFgetobjectreference{FDF}{#6}\PDFobjectreference
+ \createpdfannotationobject{FDF}{#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference\space
+ /F \FDFplus\space
+ /AS /\FDFdefault\space
+ \FDFlayer\space
+ \FDFappearance\space
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ \setFDFkids[kids:][\currentFDFkids]%
+ \doPDFgetobjectreference{FDF}{#6}\PDFobjectreference
+ \createpdfdictionaryobject{FDF}{#1}
+ {/Parent \PDFobjectreference\space
+ \FDFkids\space
+ /F \FDFplus\space
+ \FDFactions}%
+ \registerFDFobject{#1}%
+ \or
+ %\doFDFappearance{#1}{#7}{1}%
+ \doFDFappearance{\currentFDFparent}{#7}{1}%
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue % nb
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference\space
+ /AS /\FDFdefault\space
+ /F \FDFplus\space
+ \FDFlayer\space
+ \FDFappearance\space
+ \FDFactions}%
+ \or
+ %\doFDFappearance{#1}{#7}{1}%
+ \doFDFappearance{\currentFDFparent}{#7}{1}%
+ \doPDFgetobjectreference{FDF}\currentFDFparent\PDFobjectreference
+ %\global\objectreferencingtrue
+ \createpdfannotationobject{FDF}{kids:#1}{#2}{#3}
+ {/Subtype /Widget
+ /Parent \PDFobjectreference\space
+ /AS /\FDFdefault\space
+ /F \FDFplus\space
+ \FDFlayer\space
+ \FDFappearance\space
+ \FDFactions}%
+ \fi
+ \egroup}
+
+% Beware, RadiosInUnison is really needed in the pre 1.5/6 time this
+% was the default but out of a sudden it's no longer the case. Also
+% the NoToggleToOff interferes with kids of kids and both it will
+% break older documents, i.e. so much for pdf as standard. With
+% features like widgets we can probably best wait till adobe tools
+% themselves support it because that's probably the moment that
+% functionality gets frozen/becomes definitive. Actually, acrobat
+% flattens the kids tree, so that's yet another situation. The
+% interesting thing is that it worked ok in acrobat 2/3 but got bugged
+% in later versions. [The rationale is in html compatibility, which
+% seems to be more important than compatibility of documents, which in
+% turn renders acrobat useless for forms.] Anyway, synchronization is
+% broken or not depending on the combination pdfversion/acrobatversion.
+
+\def\dopresetradiorecord#1#2#3#4#5%
+ {\bgroup
+ % < pdf 1.5 (1.5 was broken)
+ % \setFDFswitches[Radio,NoToggleToOff,RadiosInUnison,#3]%
+ % > pdf 1.5
+ \setFDFswitches[Radio,RadiosInUnison,#3]%
+ % older, else fatal error
+ % \setFDFkids[#4][]%
+ % newer
+ \setFDFvalues[#4][#2]% inits kidlist
+ \expanded{\setFDFkids[][\FDFkidlist]}%
+ %
+ \setFDFactions[#5]%
+ \createpdfdictionaryobject{FDF}{#1}
+ {%/Subtype /Widget
+ /FT /Btn /T (#1) /Rect [0 0 0 0]
+ % used to be this
+ % /V (#2)
+ % then this
+ % /DV (#2)
+ % since this bomded in 5
+ % /V (#2)
+ % and now finally this works
+ /H /N
+ % /opt is buggy in 5.05, only works once, sigh
+ %\ifx\FDFfirstvalues\FDFsecondvalues
+ /V /#2
+ %\else
+ % /V /\FDFdefaultindex\space
+ % /Opt [\FDFsecondvalues]
+ %\fi
+ /Ff \FDFflag\space
+ /F \FDFplus\space
+ \FDFkids\space
+ \FDFactions}%
+ \egroup}
+
+%D At the cost of some more references, we can save bytes,
+%D by sharing appearance dictionaries. This code needs more
+%D documentation. Surprise:
+
+\def\dodoFDFappearance#1#2%
+ {\ifx#2\empty\else
+ \dogetcommacommandelement1\from#2\to\commalistelement
+ \ifx\commalistelement\empty\else
+ \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference
+ \edef\N{\ifFDFvalues\N /#1 \fi\PDFobjectreference\space}%
+ \fi
+ \dogetcommacommandelement2\from#2\to\commalistelement
+ \ifx\commalistelement\empty\else
+ \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference
+ \edef\R{\ifFDFvalues\R /#1 \fi\PDFobjectreference\space}%
+ \fi
+ \dogetcommacommandelement3\from#2\to\commalistelement
+ \ifx\commalistelement\empty\else
+ \doPDFgetobjectreference{SYM}\commalistelement\PDFobjectreference
+ \edef\D{\ifFDFvalues\D /#1 \fi\PDFobjectreference\space}%
+ \def\FDFappearance{/H /P }%
+ \fi
+ \fi}
+
+\def\redoFDFappearance#1%
+ {\ifx#1\empty\else
+ \dogetcommacommandelement3\from#1\to\commalistelement
+ \ifx\commalistelement\empty\else
+ \def\FDFappearance{/H /P }%
+ \fi
+ \fi}
+
+\def\doFDFappearance#1#2#3%
+ {\ifcase#3\relax % push only field
+ \edef\yes{#2}%
+ \let\no\empty
+ \else % on / off field
+ \dogetcommacommandelement1\from#2,\to\yes
+ \dogetcommacommandelement2\from#2,\to\no
+ \fi
+ \def\FDFappearance{/H /N}%
+ \doifobjectfoundelse{FDF}{ap:#1:\yes:\no}
+ {\redoFDFappearance\yes
+ \redoFDFappearance\no}
+ {\presetobject{FDF}{ap:#1:\yes:\no}% funny hack
+ \let\N\empty\let\R\empty\let\D\empty
+ \dodoFDFappearance{#1}\yes
+ \dodoFDFappearance{Off}\no
+ \createpdfdictionaryobject{FDF}{ap:#1:\yes:\no}
+ {\ifx\N\empty\else/N \ifFDFvalues<<\N>>\else\N\fi\fi
+ \ifx\R\empty\else/R \ifFDFvalues<<\R>>\else\R\fi\fi
+ \ifx\D\empty\else/D \ifFDFvalues<<\D>>\else\D\fi\fi}}%
+ \doPDFgetobjectreference{FDF}{ap:#1:\yes:\no}\PDFobjectreference
+ \edef\FDFappearance{\FDFappearance /AP \PDFobjectreference}}
+
+\def\doFDFdefault#1#2%
+ {\doifelse{#2}{1}{\def\FDFdefault{On}}{\def\FDFdefault{Off}}}
+
+%D Layer support:
+
+\def\setFDFlayer#1% todo : \ifx\PDFobjectreference\noPDFobjectreference ipv found
+ {\letempty\FDFlayer
+ \doifsomething{#1}%
+ {\checkproperty[#1]% == \dodocheckproperty\@@DriverFieldLayer
+ \doifobjectreferencefoundelse{PDLN}{#1}
+ {\doPDFgetobjectreference{PDLN}{#1}\!!stringa % we need to avoid a clash with other macros
+ \edef\FDFlayer{/OC \!!stringa}}%
+ \donothing}}
+
+%D The three appearances {\em normal}, \type{roll over} and
+%D \type{push down} are passed as comma separated triplets,
+%D that is, the second argument can look like:
+%D
+%D \starttyping
+%D {yes,ok,fine},{no,rubish,awful}
+%D \stoptyping
+
+%D \macros
+%D {dodefinefieldset,dogetfieldset,doiffieldset}
+%D
+%D Field sets, the ones we use in submitting and resetting
+%D fields, are implemented using the next low level specials:
+%D
+%D \starttyping
+%D \doFDFdefinefieldset{TAG}{name,name,...}
+%D \doFDFgetfieldset{TAG}
+%D \doiffieldset{TAG}{sequence}
+%D \stoptyping
+
+\def\dodefinefieldset#1#2% tag commalist
+ {\let\FDFfieldset\empty
+ \def\docommand##1%
+ {\doPDFgetobjectreference{FDF}{##1}\PDFobjectreference
+ \edef\FDFfieldset{\FDFfieldset\PDFobjectreference\space}}%
+ \processcommacommand[#2]\docommand % nb: command
+ \setevalue{FDF:set:#1}{\FDFfieldset}}
+
+\def\dogetfieldset#1%
+ {\getvalue{FDF:set:#1}}
+
+\def\doiffieldset#1#2%
+ {\ifundefined{FDF:set:#1}\else#2\fi}
+
+%D \macros
+%D {defaultobjectreference,doPDFgetobjectreference}
+%D
+%D Because in \PDFTEX\ we have to construct the object
+%D references \type{N 0 R}, we can default to the non existing
+%D zero object number.
+
+\def\defaultobjectreference#1#2%
+ {0}
+
+\def\doPDFgetobjectreference#1#2#3%
+ {\dogetobjectreference{#1}{#2}#3%
+ \edef#3{\ifx#3\empty null\else\PDFobjref{#3}\fi}}
+
+\def\doPDFgetobjectnumber#1#2#3%
+ {\dogetobjectreference{#1}{#2}#3%
+ \edef#3{\ifx#3\empty 0\else#3\fi}}
+
+\def\doPDFgetobjectpage#1#2#3%
+ {\dogetobjectreferencepage{#1}{#2}#3%
+ \ifx#3\empty\def#3{1}\fi}
+
+\def\doPDFgetobjectpagereference#1#2#3%
+ {\dogetobjectreferencepage{#1}{#2}#3%
+ \ifx#3\empty
+ \doPDFgetpagereference\realfolio#3%
+ \else
+ \doPDFgetpagereference#3#3% we assume that #3 gets expanded
+ \fi}
+
+\def\doPDFgetpagereference#1#2% number macro
+ {\edef#2{\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi}}
+
+\def\thePDFpagereference#1#2% number macro
+ {\ifnum#1>\zerocount\PDFobjref{\pdfpageref#1}\else null\fi}
+
+%D \macros
+%D {initializePDFnegative,initializePDFoverprint}
+%D
+%D Here follow some rather obscure macros. They will only
+%D come into action when one wants negated output.
+
+\def\initializePDFnegative
+ {\immediate\pdfobj stream attr {/FunctionType 4 /Range [0 1] /Domain [0 1]} {{1 exch sub}}%
+ \immediate\pdfobj{<</Type /ExtGState /TR \PDFobjref\pdflastobj>>}%
+ \appendtoPDFdocumentextgstates{/GSnegative \PDFobjref\pdflastobj}%
+ \immediate\pdfobj{<</Type /ExtGState /TR /Identity>>}%
+ \appendtoPDFdocumentextgstates{/GSpositive \PDFobjref\pdflastobj}%
+ \global\let\initializePDFnegative\relax}
+
+\def\initializePDFoverprint
+ {\immediate\pdfobj{<</Type /ExtGState /OP false /OPM 0>>}% /op defaults to /OP
+ \appendtoPDFdocumentextgstates{/GSknockout \PDFobjref\pdflastobj}%
+ \immediate\pdfobj{<</Type /ExtGState /OP true /OPM 1>>}% /op defaults to /OP
+ \edef\PDFobjectreferenceB{\the\pdflastobj}%
+ \appendtoPDFdocumentextgstates{/GSoverprint \PDFobjref\pdflastobj}%
+ \global\let\initializePDFoverprint\relax}
+
+%D File embedding. Storing the stream identifier is needed
+%D to get access to the number. When typeset, the user can
+%D feed this number to \type {pdftosrc} and filter the
+%D file from the \PDF\ file.
+
+\let\PDFlaststreamobject \s!unknown
+%def\PDFlaststreamreference{0 0 R}
+
+\def\doPDFfilestreamobject#1#2#3#4%
+ {\immediate\pdfobj stream file{#4}%
+ \edef\PDFlaststreamobject{\the\pdflastobj}%
+ \dosetobjectreference{PDFFS}{#2}{\PDFlaststreamobject}%
+ \createpdfdictionaryobject{#1}{#2}{/Type /Filespec /F (#3) /EF <</F \PDFobjref\PDFlaststreamobject>>}}
+
+\def\doPDFgetfilestreamreference#1#2%
+ {\doPDFgetobjectreference{PDFFS}{#1}#2}
+
+\def\doPDFfilestreamidentifier#1%
+ {\doifsomething{#1}
+ {\doPDFgetfilestreamreference{#1}\PDFobjectreference
+ \@EA\beforesplitstring\PDFobjectreference\at{ }\to\PDFlaststreamobject
+ \PDFlaststreamobject}}
+
+% MP ?
+
+ \def\setMPPDFobject#1#2% resources boxnumber
+ {\the\everyPDFxform
+ \finalizeobjectbox{#2}%
+ \immediate\pdfxform resources{#1}#2%
+ \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}}
+
+ \let\getMPPDFobject\relax
+
+ \def\doinsertMPfile#1%
+ {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}}
+
+%D Even newer trickery:
+
+% resource -> prop -> mc's -> OCG|OCMD (nested)
+% ocg:
+% /Intent/Design
+% ocmd
+% /P /AllOn
+% kan zelf ocmd bevatten
+
+\let\PDFtextlayers\empty
+\let\PDFpagelayers\empty
+\let\PDFhidelayers\empty
+\let\PDFvidelayers\empty
+
+\def\dostartlayer#1{\PDFcode{/OC /#1 BDC}}
+\def\dostoplayer {\PDFcode {EMC}}
+
+\def\dodefineviewerlayer#1#2#3#4#5% tag title visible type printable
+ {\createpdfdictionaryobject{PDLN}{#1}
+ {/Type /OCG
+ \ifcase#4 \or
+ /Intent /Design % disable layer hiding by user
+ \fi
+ \ifnum#5=\zerocount
+ /Usage << /Print << /PrintState /OFF >> >> % printable or not
+ \fi
+ /Name (#2)}%
+ \doPDFgetobjectreference{PDLN}{#1}\PDFobjectreference
+ \xdef\PDFtextlayers{\PDFtextlayers\space\PDFobjectreference}%
+ \doifelse{#3}\v!start
+ {\xdef\PDFvidelayers{\PDFvidelayers\space\PDFobjectreference}}%
+ {\xdef\PDFhidelayers{\PDFhidelayers\space\PDFobjectreference}}%
+ \createpdfdictionaryobject{PDLD}{#1}
+ {/Type /OCMD
+ /OCGs [\PDFobjectreference]}%
+ \doPDFgetobjectreference{PDLD}{#1}\PDFobjectreference
+ \xdef\PDFpagelayers{\PDFpagelayers\space /#1 \PDFobjectreference}}
+
+\def\flushPDFtextlayers
+ {\ifx\PDFtextlayers\empty \else
+ \driverreferenced \createpdfarrayobject{PDF}{textlayers}{\PDFtextlayers}%
+ \doPDFgetobjectreference{PDF}{textlayers}\!!stringa
+ \ifx\PDFvidelayers\empty
+ \def\!!stringb{[null]}%
+ \else
+ \driverreferenced \createpdfarrayobject{PDF}{videlayers}{\PDFvidelayers}%
+ \doPDFgetobjectreference{PDF}{videlayers}\!!stringb
+ \fi
+ \ifx\PDFhidelayers\empty
+ \def\!!stringc{[null]}%
+ \else
+ \driverreferenced \createpdfarrayobject{PDF}{hidelayers}{\PDFhidelayers}%
+ \doPDFgetobjectreference{PDF}{hidelayers}\!!stringc
+ \fi
+ \appendtopdfcatalog
+ {/OCProperties
+ << % display in menu
+ /D << /Order \!!stringa
+ /ON \!!stringb
+ /OFF \!!stringc >>
+ % used properties
+ /OCGs \!!stringa >>}%
+ \globallet\flushPDFtextlayers\relax
+ \fi}
+
+\def\flushPDFpagelayers
+ {\ifx\PDFpagelayers\empty \else
+ \appendtopdfpageresources{/Properties <<\PDFpagelayers>>}%
+ \fi}
+
+\def\PDFlayeractionlist{null}
+
+\def\PDFexecutehidelayer {/SetOCGState /State [/OFF \PDFlayeractionlist]}
+\def\PDFexecutevidelayer {/SetOCGState /State [/ON \PDFlayeractionlist]}
+\def\PDFexecutetogglelayer {/SetOCGState /State [/Toggle \PDFlayeractionlist]}
+
+\def\domakeviewerlayerlist#1%
+ {\bgroup
+ \globallet\PDFlayeractionlist\empty
+ \def\docommand##1%
+ {\doPDFgetobjectreference{PDLN}{##1}\PDFobjectreference
+ \xdef\PDFlayeractionlist{\PDFlayeractionlist\space\PDFobjectreference}}%
+ \processcommalist[#1]\docommand
+ \egroup}
+
+%D Something rather pdf dependent:
+
+% #1 => 1=fill 2=stroke 3=strokedfill 4=invisible
+% #2 => linewidth
+% #3 => spacing (beware, one needs to set the hsize as well)
+
+\def\dostartfonteffect#1#2#3%
+ {\ifdim#2>\zeropoint
+ \PointsToBigPoints{#2}\ascii
+ \PDFcode{\ascii\space w}%
+ \fi
+ \ifdim#3\points=\onepoint\else
+ \scratchdimen#3\points
+ \PDFcode{\withoutpt{\the\scratchdimen}\space Tc}%
+ \fi
+ \PDFcode{\purenumber#1 Tr}}
+
+\def\dostopfonteffect
+ {\PDFcode{1 w 0 Tc 0 Tr}}
+
+%D Handy for the \METAPOST\ to \PDF\ converter:
+
+\appendtoksonce
+ \collectPDFresources
+ \global\let\currentPDFresources\collectedPDFresources
+\to \everyPDFxform
+
+\let\collectedPDFresources\empty
+
+\def\collectPDFresources % suboptimal
+ {\doifobjectreferencefoundelse{FDF}{docushades} % redundant, we have an reserved object now
+ {\doPDFgetobjectreference{FDF}{docushades}\PDFobjectreference
+ \xdef\collectedPDFresources{\collectedPDFresources/Shading \PDFobjectreference}}\donothing
+ \doifobjectreferencefoundelse{FDF}{docuextgstates}
+ {\doPDFgetobjectreference{FDF}{docuextgstates}\PDFobjectreference
+ \xdef\collectedPDFresources{\collectedPDFresources/ExtGState \PDFobjectreference}}\donothing
+ \doifobjectreferencefoundelse{FDF}{colorspaces}
+ {\doPDFgetobjectreference{FDF}{colorspaces}\PDFobjectreference
+ \xdef\collectedPDFresources{\collectedPDFresources/ColorSpace \PDFobjectreference}}\donothing
+ \global\let\collectPDFresources\relax}
+
+\appendtoks
+ \flushPDFpagelayers
+ \flushJSpreamble
+ \flushJSpreamble
+ \checkPDFextgstates
+ \checkPDFcolorspaces
+ \checkPDFshades
+ \checkPDFpageactions
+ \fakePDFpagedestination
+ \flushPDFpageboxes
+ \addPDFdocumentinfo
+\to \everybackendshipout
+
+\appendtoks
+ \flushPDFtextlayers
+ \finalflushJSpreamble
+\to \everylastbackendshipout
+
+%D Temporary hack:
+
+\def\TransparencyHack % png: /CS /DeviceRGB /I true
+ {\appendtoksonce
+ \appendtopdfpageattributes{/Group << /S /Transparency /I true /K true>>}%
+ \to \everyPDFxform
+ \appendtoksonce
+ \appendtopdfpageattributes{/Group << /S /Transparency /I true /K true>>}%
+ \to \everyshipout}
+
+\protect \endinput
diff --git a/tex/context/base/bibl-bib.lua b/tex/context/base/bibl-bib.lua
new file mode 100644
index 000000000..028202ec2
--- /dev/null
+++ b/tex/context/base/bibl-bib.lua
@@ -0,0 +1,233 @@
+if not modules then modules = { } end modules ['bibl-bib'] = {
+ version = 1.001,
+ comment = "this module is the basis for the lxml-* ones",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>This is a prelude to integrated bibliography support. This file just loads
+bibtex files and converts them to xml so that the we access the content
+in a convenient way. Actually handling the data takes place elsewhere.</p>
+--ldx]]--
+
+local lower, format = string.lower, string.format
+local next = next
+
+bibtex = bibtex or { }
+
+bibtex.size = 0
+bibtex.definitions = 0
+bibtex.shortcuts = 0
+
+local shortcuts = { }
+local data = { }
+local entries
+
+local function do_shortcut(tag,key,value)
+ bibtex.shortcuts = bibtex.shortcuts + 1
+ if lower(tag) == "@string" then
+ shortcuts[key] = value
+ end
+end
+
+local function do_definition(tag,key,tab) -- maybe check entries here (saves memory)
+ if not entries or entries[key] then
+ bibtex.definitions = bibtex.definitions + 1
+ local t = { }
+ for i=1,#tab,2 do
+ t[tab[i]] = tab[i+1]
+ end
+ local p = data[tag]
+ if not p then
+ data[tag] = { [key] = t }
+ else
+ p[key] = t
+ end
+ end
+end
+
+local function resolve(s)
+ return shortcuts[s] or ""
+end
+
+local percent = lpeg.P("%")
+local start = lpeg.P("@")
+local comma = lpeg.P(",")
+local hash = lpeg.P("#")
+local escape = lpeg.P("\\")
+local single = lpeg.P("'")
+local double = lpeg.P('"')
+local left = lpeg.P('{')
+local right = lpeg.P('}')
+local both = left + right
+local lineending = lpeg.S("\n\r")
+local space = lpeg.S(" \t\n\r\f")
+local spacing = space^0
+local equal = lpeg.P("=")
+local collapsed = (space^1)/ " "
+
+local function add(a,b) if b then return a..b else return a end end
+
+local keyword = lpeg.C((lpeg.R("az","AZ","09") + lpeg.S("@_:-"))^1) -- lpeg.C((1-space)^1)
+local s_quoted = ((escape*single) + collapsed + (1-single))^0
+local d_quoted = ((escape*double) + collapsed + (1-double))^0
+local balanced = lpeg.P {
+ [1] = ((escape * (left+right)) + (1 - (left+right)) + lpeg.V(2))^0,
+ [2] = left * lpeg.V(1) * right
+}
+
+local s_value = (single/"") * s_quoted * (single/"")
+local d_value = (double/"") * d_quoted * (double/"")
+local b_value = (left /"") * balanced * (right /"")
+local r_value = keyword/resolve
+
+local somevalue = s_value + d_value + b_value + r_value
+local value = lpeg.Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0))
+
+local assignment = spacing * keyword * spacing * equal * spacing * value * spacing
+local shortcut = keyword * spacing * left * spacing * (assignment * comma^0)^0 * spacing * right
+local definition = keyword * spacing * left * spacing * keyword * comma * lpeg.Ct((assignment * comma^0)^0) * spacing * right
+local comment = keyword * spacing * left * (1-right)^0 * spacing * right
+local forget = percent^1 * (1-lineending)^0
+
+-- todo \%
+
+local grammar = (space + forget + shortcut/do_shortcut + definition/do_definition + comment + 1)^0
+
+function bibtex.convert(session,content)
+ statistics.starttiming(bibtex)
+ data, shortcuts, entries = session.data, session.shortcuts, session.entries
+ -- session.size = session.size + #content
+ bibtex.size = bibtex.size + #content
+ grammar:match(content or "")
+ statistics.stoptiming(bibtex)
+end
+
+function bibtex.load(session,filename)
+ local filename = resolvers.find_file(filename,"bib")
+ if filename ~= "" then
+ bibtex.convert(session,io.loaddata(filename) or "")
+ end
+end
+
+function bibtex.new()
+ return {
+ data = { },
+ shortcuts = { },
+ xml = xml.convert("<?xml version='1.0' standalone='yes'?>\n<bibtex></bibtex>"),
+ size = 0,
+ entries = nil,
+ }
+end
+
+local escaped_pattern = xml.escaped_pattern
+
+function bibtex.toxml(session)
+ -- we can always speed this up if needed
+ -- format slows down things a bit but who cares
+ statistics.starttiming(bibtex)
+ local result = { }
+ local entries = session.entries
+ result[#result+1] = format("<?xml version='1.0' standalone='yes'?>")
+ result[#result+1] = format("<bibtex>")
+ for id, categories in next, session.data do
+ result[#result+1] = format(" <c n='%s'>",id)
+ for name, entry in next, categories do
+ if not entries or entries[name] then
+ result[#result+1] = format(" <e n='%s'>",name)
+ for key, value in next, entry do
+ value = escaped_pattern:match(value)
+ if value ~= "" then
+ result[#result+1] = format(" <v n='%s'>%s</v>",key,value)
+ end
+ end
+ result[#result+1] = format(" </e>")
+ end
+ end
+ result[#result+1] = format(" </c>")
+ end
+ result[#result+1] = format("</bibtex>")
+ session.xml = xml.convert(table.concat(result,"\n"))
+ statistics.stoptiming(bibtex)
+end
+
+statistics.register("bibtex load time", function()
+ local size = bibtex.size
+ if size > 0 then
+ return format("%s seconds (%s bytes, %s definitions, %s shortcuts)",
+ statistics.elapsedtime(bibtex),size,bibtex.definitions,bibtex.shortcuts)
+ else
+ return nil
+ end
+end)
+
+--~ str = [[
+--~ @COMMENT { CRAP }
+--~ @STRING{ hans = "h a n s" }
+--~ @STRING{ taco = "t a c o" }
+--~ @SOMETHING{ key1, abc = "t a c o" , def = "h a n s" }
+--~ @SOMETHING{ key2, abc = hans # taco }
+--~ @SOMETHING{ key3, abc = "hans" # taco }
+--~ @SOMETHING{ key4, abc = hans # "taco" }
+--~ @SOMETHING{ key5, abc = hans # taco # "hans" # "taco"}
+--~ @SOMETHING{ key6, abc = {oeps {oeps} oeps} }
+--~ ]]
+
+--~ local session = bibtex.new()
+--~ bibtex.convert(session,str)
+--~ bibtex.toxml(session)
+--~ print(session.size,statistics.elapsedtime(bibtex))
+
+--~ local session = bibtex.new()
+--~ bibtex.load(session,"IEEEabrv.bib")
+--~ bibtex.load(session,"IEEEfull.bib")
+--~ bibtex.load(session,"IEEEexample.bib")
+--~ bibtex.toxml(session)
+--~ print(session.size,statistics.elapsedtime(bibtex))
+
+--~ local session = bibtex.new()
+--~ bibtex.load(session,"gut.bib")
+--~ bibtex.load(session,"komoedie.bib")
+--~ bibtex.load(session,"texbook1.bib")
+--~ bibtex.load(session,"texbook2.bib")
+--~ bibtex.load(session,"texbook3.bib")
+--~ bibtex.load(session,"texgraph.bib")
+--~ bibtex.load(session,"texjourn.bib")
+--~ bibtex.load(session,"texnique.bib")
+--~ bibtex.load(session,"tugboat.bib")
+--~ bibtex.toxml(session)
+--~ print(session.size,statistics.elapsedtime(bibtex))
+
+--~ print(table.serialize(session.data))
+--~ print(table.serialize(session.shortcuts))
+--~ print(xml.serialize(session.xml))
+
+-- this will move:
+
+if commands then
+
+ local sessions = { }
+
+ function commands.definebibtexsession(name)
+ sessions[name] = bibtex.new()
+ end
+ function commands.preparebibtexsession(name)
+ bibtex.toxml(sessions[name])
+ lxml.register("bibtex:"..name,sessions[name].xml)
+ end
+ function commands.registerbibtexfile(name,filename)
+ bibtex.load(sessions[name],filename)
+ end
+ function commands.registerbibtexentry(name,entry)
+ local session = sessions[name]
+ local entries = session.entries
+ if not entries then
+ session.entries = { [entry] = true }
+ else
+ entries[entry] = true
+ end
+ end
+
+end
diff --git a/tex/context/base/bibl-bib.tex b/tex/context/base/bibl-bib.tex
new file mode 100644
index 000000000..51db67ed7
--- /dev/null
+++ b/tex/context/base/bibl-bib.tex
@@ -0,0 +1,29 @@
+%D \module
+%D [ file=bibl-bib,
+%D version=2007.08.17,
+%D title=\CONTEXT\ Bibliography Support,
+%D subtitle=Initialization,
+%D author=Hans Hagen \& Taco Hoekwater,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Bibliography Support / BibTeX}
+
+\registerctxluafile{bibl-bib}{1.001}
+
+\unprotect
+
+\def\definebibtexsession [#1]{\ctxlua{commands.definebibtexsession("#1")}}
+\def\preparebibtexsession [#1]{\ctxlua{commands.preparebibtexsession("#1")}}
+\def\registerbibtexfile {\dodoubleargument\doregisterbibtexfile}
+\def\doregisterbibtexfile [#1][#2]{\ctxlua{commands.registerbibtexfile("#1","#2")}} % also the fast one
+\def\registerbibtexentry {\dodoubleargument\doregisterbibtexentry}
+\def\doregisterbibtexentry [#1][#2]{\ctxlua{commands.registerbibtexentry("#1","#2")}} % also the fast one
+\def\applytobibtexsession {\dodoubleargument\doapplytobibtexsession}
+\def\doapplytobibtexsession[#1][#2]{\xmlprocessregistered{bibtex:#1}{#2}{#2}}
+
+\protect \endinput
diff --git a/tex/context/base/bibl-tst.lua b/tex/context/base/bibl-tst.lua
new file mode 100644
index 000000000..a1b85b0f7
--- /dev/null
+++ b/tex/context/base/bibl-tst.lua
@@ -0,0 +1,21 @@
+dofile("bibl-bib.lua")
+
+local session = bibtex.new()
+
+bibtex.load(session,"gut.bib")
+bibtex.load(session,"komoedie.bib")
+bibtex.load(session,"texbook1.bib")
+bibtex.load(session,"texbook2.bib")
+bibtex.load(session,"texbook3.bib")
+bibtex.load(session,"texgraph.bib")
+bibtex.load(session,"texjourn.bib")
+bibtex.load(session,"texnique.bib")
+bibtex.load(session,"tugboat.bib")
+bibtex.toxml(session)
+
+print(bibtex.size,statistics.elapsedtime(bibtex))
+
+--~ print(table.serialize(session.data))
+--~ print(table.serialize(session.shortcuts))
+--~ print(xml.serialize(session.xml))
+
diff --git a/tex/context/base/catc-act.tex b/tex/context/base/catc-act.tex
new file mode 100644
index 000000000..5aecb2493
--- /dev/null
+++ b/tex/context/base/catc-act.tex
@@ -0,0 +1,61 @@
+%D \module
+%D [ file=catc-act,
+%D version=2006.09.18,
+%D title=\CONTEXT\ Catcode Macros,
+%D subtitle=Default Catcode Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 deals with some active character handling. Use
+%D with care.
+
+%D \macros
+%D {installactivecharacter}
+
+\def\installactivecharacter#1 %
+ {\edef\temp{\detokenize{#1}}%
+ \cctcounterc\expandafter`\temp\relax % relax needed
+ \expandafter\startextendcatcodetable
+ \expandafter\ctxcatcodes\expandafter\catcode\the\cctcounterc=13
+ \stopextendcatcodetable
+ \letcatcodecommand \ctxcatcodes \cctcounterc \temp \relax
+ \ifnum\currentcatcodetable=\ctxcatcodes \setcatcodetable\ctxcatcodes \fi}
+
+%D \macros
+%D {defineactivecharacter}
+%D
+%D Use this one with care, esp in combination with catcode
+%D vectors. There are better ways now.
+
+\chardef\activehackcode=`~
+
+\def\defineactivecharacter #1#2 #3%
+ {\cctcounterc\uccode\activehackcode
+ \if#1"\uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1#2}\empty #1#2\else
+ \uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1#2}\empty`#1#2\fi
+ \catcode\uccode\activehackcode13
+ \uppercase{\def\next{~}}%
+ \uccode\activehackcode\cctcounterc
+ \expandafter\expandafter\expandafter\def\expandafter\next\expandafter
+ {\expandafter\dohandleactivecharacter\next{#3}}}
+
+\chardef\activecharactermode\plusone % overloading still backward compatible
+
+\def\dodohandleactivecharacter#1#2{#2}
+\def\donthandleactivecharacter#1#2{\noexpand#1}
+
+\def\dohandleactivecharacter
+ {\ifcase\activecharactermode
+ \expandafter\donthandleactivecharacter
+ \else
+ \expandafter\dodohandleactivecharacter
+ \fi}
+
+\def\makecharacteractive #1 {\catcode`#1\active}
+
+\endinput
diff --git a/tex/context/base/catc-ctx.tex b/tex/context/base/catc-ctx.tex
new file mode 100644
index 000000000..028ae496c
--- /dev/null
+++ b/tex/context/base/catc-ctx.tex
@@ -0,0 +1,207 @@
+%D \module
+%D [ file=catc-cys,
+%D version=2006.09.18,
+%D title=\CONTEXT\ Catcode Macros,
+%D subtitle=Extra Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 prefer to define relevant catcode tables in this file instead
+%D of everywhere around.
+
+\ifx\ctxcatcodes \undefined \newcatcodetable \ctxcatcodes \fi
+\ifx\mthcatcodes \undefined \newcatcodetable \mthcatcodes \fi % math, not used, too tricky
+\ifx\xmlcatcodesn\undefined \newcatcodetable \xmlcatcodesn \fi % normal
+\ifx\xmlcatcodese\undefined \newcatcodetable \xmlcatcodese \fi % entitle
+\ifx\xmlcatcodesr\undefined \newcatcodetable \xmlcatcodesr \fi % reduce
+\ifx\typcatcodesa\undefined \newcatcodetable \typcatcodesa \fi % { }
+\ifx\typcatcodesb\undefined \newcatcodetable \typcatcodesb \fi % < >
+
+\startcatcodetable \ctxcatcodes
+ \catcode`\^^I = 10
+ \catcode`\^^M = 5
+ % \catcode`\^^J = 10 % new
+ \catcode`\^^L = 5
+ \catcode`\ = 10
+ \catcode`\^^Z = 9
+ \catcode`\\ = 0
+ \catcode`\{ = 1
+ \catcode`\} = 2
+ \catcode`\$ = 3
+ \catcode`\& = 4
+ \catcode`\# = 6
+ \catcode`\^ = 7
+ \catcode`\_ = 8
+ \catcode`\% = 14
+ \catcode`\~ = 13
+ \catcode`\| = 13
+\stopcatcodetable
+
+\startcatcodetable \prtcatcodes
+ \catcode`\^^I = 10
+ \catcode`\^^M = 5
+ \catcode`\^^L = 5
+ \catcode`\ = 10
+ \catcode`\^^Z = 9
+ \catcode`\\ = 0
+ \catcode`\{ = 1
+ \catcode`\} = 2
+ \catcode`\$ = 3
+ \catcode`\& = 4
+ \catcode`\# = 6
+ \catcode`\^ = 7
+ \catcode`\_ = 8
+ \catcode`\% = 14
+ \catcode`\@ = 11
+ \catcode`\! = 11
+ \catcode`\? = 11
+ \catcode`\~ = 13
+ \catcode`\| = 13
+\stopcatcodetable
+
+\startcatcodetable \mthcatcodes
+ \catcode`\^^I = 10
+ \catcode`\^^M = 5
+ %\catcode`\^^J = 10 % new
+ \catcode`\^^L = 5
+ \catcode`\ = 10
+ \catcode`\^^Z = 9
+ \catcode`\\ = 0
+ \catcode`\{ = 1
+ \catcode`\} = 2
+ \catcode`\$ = 3
+ \catcode`\& = 4
+ \catcode`\# = 6
+ \catcode`\^ = 7
+ \catcode`\_ = 8
+ \catcode`\% = 14
+ %\catcode`\~ = 13
+ %\catcode`\| = 13
+\stopcatcodetable
+
+\startcatcodetable \xmlcatcodesn
+ \catcode`\^^I = 10 % ascii tab is a blank space
+ \catcode`\^^M = 5 % ascii return is end-line
+ \catcode`\^^L = 5 % ascii form-feed
+ \catcode`\ = 10 % ascii space is blank space
+ \catcode`\^^Z = 9 % ascii eof is ignored
+ \catcode`\& = 13 % entity
+ \catcode`\< = 13 % element
+ \catcode`\> = 12
+ \catcode`\" = 12 % probably not needed any more
+ \catcode`\/ = 12 % probably not needed any more
+ \catcode`\' = 12 % probably not needed any more
+ \catcode`\~ = 12 % probably not needed any more
+ \catcode`\# = 12 % probably not needed any more
+ \catcode`\\ = 12 % probably not needed any more
+\stopcatcodetable
+
+\startcatcodetable \xmlcatcodese
+ \catcode`\^^I = 10 % ascii tab is a blank space
+ \catcode`\^^M = 5 % ascii return is end-line
+ \catcode`\^^L = 5 % ascii form-feed
+ \catcode`\ = 10 % ascii space is blank space
+ \catcode`\^^Z = 9 % ascii eof is ignored
+ \catcode`\& = 13 % entity
+ \catcode`\< = 13 % element
+ \catcode`\> = 12
+ \catcode`\# = 13
+ \catcode`\$ = 13
+ \catcode`\% = 13
+ \catcode`\\ = 13
+ \catcode`\^ = 13
+ \catcode`\_ = 13
+ \catcode`\{ = 13
+ \catcode`\} = 13
+ \catcode`\| = 13
+ \catcode`\~ = 13
+\stopcatcodetable
+
+\startcatcodetable \xmlcatcodesr
+ \catcode`\^^I = 10 % ascii tab is a blank space
+ \catcode`\^^M = 5 % ascii return is end-line
+ \catcode`\^^L = 5 % ascii form-feed
+ \catcode`\ = 10 % ascii space is blank space
+ \catcode`\^^Z = 9 % ascii eof is ignored
+ \catcode`\& = 13 % entity
+ \catcode`\< = 13 % element
+ \catcode`\> = 12
+ \catcode`\# = 13
+ \catcode`\$ = 13
+ \catcode`\% = 13
+ \catcode`\\ = 13
+ \catcode`\^ = 13
+ \catcode`\_ = 13
+ \catcode`\{ = 13
+ \catcode`\} = 13
+ \catcode`\| = 13
+ \catcode`\~ = 13
+\stopcatcodetable
+
+\startcatcodetable \typcatcodesa
+ \catcode`\^^I = 12
+ \catcode`\^^M = 12
+ \catcode`\^^L = 12
+ \catcode`\ = 12
+ \catcode`\^^Z = 12
+ \catcode`\{ = 1
+ \catcode`\} = 2
+\stopcatcodetable
+
+\startcatcodetable \typcatcodesb
+ \catcode`\^^I = 12
+ \catcode`\^^M = 12
+ \catcode`\^^L = 12
+ \catcode`\ = 12
+ \catcode`\^^Z = 12
+ \catcode`\< = 1
+ \catcode`\> = 2
+\stopcatcodetable
+
+\letcatcodecommand \ctxcatcodes `\| \relax
+\letcatcodecommand \ctxcatcodes `\~ \relax
+
+%letcatcodecommand \prtcatcodes `\| \relax % falls back on ctx
+%letcatcodecommand \prtcatcodes `\~ \relax % falls back on ctx
+
+\letcatcodecommand \xmlcatcodesn `\& \relax
+\letcatcodecommand \xmlcatcodesn `\< \relax
+
+\letcatcodecommand \xmlcatcodese `\& \relax
+\letcatcodecommand \xmlcatcodese `\< \relax
+
+\letcatcodecommand \xmlcatcodesr `\& \relax
+\letcatcodecommand \xmlcatcodesr `\< \relax
+
+\letcatcodecommand \xmlcatcodese `\# \relax
+\letcatcodecommand \xmlcatcodese `\$ \relax
+\letcatcodecommand \xmlcatcodese `\% \relax
+\letcatcodecommand \xmlcatcodese `\\ \relax
+\letcatcodecommand \xmlcatcodese `\^ \relax
+\letcatcodecommand \xmlcatcodese `\_ \relax
+\letcatcodecommand \xmlcatcodese `\{ \relax
+\letcatcodecommand \xmlcatcodese `\} \relax
+\letcatcodecommand \xmlcatcodese `\| \relax
+\letcatcodecommand \xmlcatcodese `\~ \relax
+
+\letcatcodecommand \xmlcatcodesr `\# \relax
+\letcatcodecommand \xmlcatcodesr `\$ \relax
+\letcatcodecommand \xmlcatcodesr `\% \relax
+\letcatcodecommand \xmlcatcodesr `\\ \relax
+\letcatcodecommand \xmlcatcodesr `\^ \relax
+\letcatcodecommand \xmlcatcodesr `\_ \relax
+\letcatcodecommand \xmlcatcodesr `\{ \relax
+\letcatcodecommand \xmlcatcodesr `\} \relax
+\letcatcodecommand \xmlcatcodesr `\| \relax
+\letcatcodecommand \xmlcatcodesr `\~ \relax
+
+ \catcodetable \ctxcatcodes
+\let\defaultcatcodetable\ctxcatcodes
+\let\xmlcatcodes \xmlcatcodesn
+
+\endinput
diff --git a/tex/context/base/catc-def.tex b/tex/context/base/catc-def.tex
new file mode 100644
index 000000000..0346f6dae
--- /dev/null
+++ b/tex/context/base/catc-def.tex
@@ -0,0 +1,142 @@
+%D \module
+%D [ file=catc-def,
+%D version=2006.09.18,
+%D title=\CONTEXT\ Catcode Macros,
+%D subtitle=Default Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 following catcode tables are rather \CONTEXT\ independent.
+
+\ifx\nilcatcodes \undefined \newcatcodetable \nilcatcodes \fi
+\ifx\texcatcodes \undefined \newcatcodetable \texcatcodes \fi
+\ifx\luacatcodes \undefined \newcatcodetable \luacatcodes \fi
+\ifx\notcatcodes \undefined \newcatcodetable \notcatcodes \fi
+\ifx\vrbcatcodes \undefined \newcatcodetable \vrbcatcodes \fi
+\ifx\prtcatcodes \undefined \newcatcodetable \prtcatcodes \fi
+
+\startcatcodetable \nilcatcodes
+ \catcode`\^^I = 10 % ascii tab is a blank space
+ \catcode`\^^M = 5 % ascii return is end-line
+ \catcode`\^^L = 5 % ascii form-feed
+ \catcode`\ = 10 % ascii space is blank space
+ \catcode`\^^Z = 9 % ascii eof is ignored
+\stopcatcodetable
+
+\startcatcodetable \texcatcodes
+ \catcode`\^^I = 10
+ \catcode`\^^M = 5
+ \catcode`\^^L = 5
+ \catcode`\ = 10
+ \catcode`\^^Z = 9
+ \catcode`\\ = 0
+ \catcode`\{ = 1
+ \catcode`\} = 2
+ \catcode`\$ = 3
+ \catcode`\& = 4
+ \catcode`\# = 6
+ \catcode`\^ = 7
+ \catcode`\_ = 8
+ \catcode`\% = 14
+\stopcatcodetable
+
+\startcatcodetable \luacatcodes
+ \catcode`\^^I = 12 % ascii tab is a blank space
+ \catcode`\^^M = 12 % ascii return is end-line
+ \catcode`\^^L = 12 % ascii form-feed
+ \catcode`\ = 12 % ascii space is blank space
+ \catcode`\^^Z = 9 % ascii eof is ignored
+ \catcode`\\ = 0
+ \catcode`\% = 12
+ \catcode`\# = 12
+ \catcode`\_ = 12
+ \catcode`\^ = 12
+ \catcode`\& = 12
+ \catcode`\| = 12
+ \catcode`\{ = 12
+ \catcode`\} = 12
+ \catcode`\~ = 12
+ \catcode`\$ = 12
+\stopcatcodetable
+
+\startcatcodetable \notcatcodes
+ \catcode`\^^I = 10 % ascii tab is a blank space
+ \catcode`\^^M = 5 % ascii return is end-line
+ \catcode`\^^L = 5 % ascii form-feed
+ \catcode`\ = 10 % ascii space is blank space
+ \catcode`\^^Z = 9 % ascii eof is ignored
+ \catcode`\~ = 12
+ \catcode`\# = 12 % probably too much, in principle
+ \catcode`\$ = 12 % nilcatcodes would be ok too
+ \catcode`\% = 12
+ \catcode`\^ = 12
+ \catcode`\& = 12
+ \catcode`\_ = 12
+ \catcode`\< = 12
+ \catcode`\> = 12
+ \catcode`\{ = 12
+ \catcode`\} = 12
+ \catcode`\" = 12
+ \catcode`\' = 12
+ \catcode`\/ = 12
+ \catcode`\\ = 12
+ \catcode`\| = 12
+\stopcatcodetable
+
+\startcatcodetable \vrbcatcodes % probably less needed
+ \catcode`\^^I = 12
+ \catcode`\^^M = 12
+ \catcode`\^^L = 12
+ \catcode`\ = 12
+ \catcode`\^^Z = 12
+\stopcatcodetable
+
+\startcatcodetable \prtcatcodes
+ \catcode`\^^I = 10
+ \catcode`\^^M = 5
+ \catcode`\^^L = 5
+ \catcode`\ = 10
+ \catcode`\^^Z = 9
+ \catcode`\\ = 0
+ \catcode`\{ = 1
+ \catcode`\} = 2
+ \catcode`\$ = 3
+ \catcode`\& = 4
+ \catcode`\# = 6
+ \catcode`\^ = 7
+ \catcode`\_ = 8
+ \catcode`\% = 14
+ \catcode`\@ = 11
+ \catcode`\! = 11
+ \catcode`\? = 11
+ \catcode`\~ = 13
+ \catcode`\| = 13
+\stopcatcodetable
+
+%D Because some characters have a special meaning, we provide
+%D shortcuts to their character representation.
+
+\chardef\%=`\%
+\chardef\&=`\&
+\chardef\#=`\#
+\chardef\$=`\$
+\chardef\{=`\{
+\chardef\}=`\}
+\chardef\\=`\\
+\chardef\^=`\^
+\chardef\_=`\_ % but way too wide in lm, so ... until that's fixed:
+
+%def\_{\leavevmode \kern.06em \vbox{\hrule width.3em}}
+\def\_{\dontleavehmode \kern.06em \vbox{\hrule width.3em}}
+
+%D From now on we can use the protection mechanisms.
+
+\def\unprotect {\pushcatcodetable\setcatcodetable\prtcatcodes}
+\def\protect {\popcatcodetable}
+
+\endinput
diff --git a/tex/context/base/catc-ini.lua b/tex/context/base/catc-ini.lua
new file mode 100644
index 000000000..e1558b459
--- /dev/null
+++ b/tex/context/base/catc-ini.lua
@@ -0,0 +1,28 @@
+if not modules then modules = { } end modules ['catc-ini'] = {
+ version = 1.001,
+ comment = "companion to catc-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+catcodes = catcodes or { }
+catcodes.numbers = catcodes.numbers or { }
+catcodes.names = catcodes.names or { }
+
+storage.register("catcodes/numbers", catcodes.numbers, "catcodes.numbers")
+storage.register("catcodes/names", catcodes.names, "catcodes.names")
+
+-- this only happens at initime
+
+function catcodes.register(name,number)
+ catcodes.numbers[name] = number
+ catcodes.names[number] = name
+ tex[name] = number
+end
+
+-- this only happens at runtime
+
+for k, v in next, catcodes.numbers do
+ tex[k] = v
+end
diff --git a/tex/context/base/catc-ini.mkii b/tex/context/base/catc-ini.mkii
new file mode 100644
index 000000000..60b7528dd
--- /dev/null
+++ b/tex/context/base/catc-ini.mkii
@@ -0,0 +1,229 @@
+%D \module
+%D [ file=catc-ini,
+%D version=2006.09.18,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Catcode Handling,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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've split the functionality of syst-cat.* over more files
+%D now so that we can load more selectively.
+
+%D A long standing wish has been the availability of catcode
+%D arrays. Because traditional \TEX\ does ot provide this we
+%D implement a fake method in the Mark II file.
+
+\ifx\zerocount\undefined \chardef \zerocount= 0 \fi
+\ifx\plusone \undefined \chardef \plusone = 1 \fi
+\ifx\minusone \undefined \newcount\minusone \minusone =-1 \fi
+
+\newif \ifrecatcodeuppercharacters % only used in good old tex
+
+% \newcount\cctdefcounter \cctdefcounter\plusone % 0 = signal
+\newcount\cctdefcounter \cctdefcounter\zerocount % 0 = signal, so advance before allocate
+
+\newcount\cctcountera
+\newcount\cctcounterb
+\newcount\cctcounterc
+
+\def\newcatcodetable#1%
+ {\global\advance\cctdefcounter\plusone
+ \global\mathchardef#1\cctdefcounter
+ \expandafter\xdef\csname @@ccn:\number\cctdefcounter\endcsname{\string#1}% logging
+ \expandafter\newtoks\csname @@cct:\number\cctdefcounter\endcsname}
+
+\mathchardef\currentcatcodetable\zerocount
+
+\newtoks \setdefaultlowercatcodes
+\newtoks \setdefaultuppercatcodes
+
+\def\next#1% we don't have a proper loop defined yet
+ {\edef\nextnext{#1{\the#1\catcode\the\cctcountera\space\ifnum\catcode\cctcountera=11 11\else12\fi}}%
+ \nextnext\ifnum\cctcountera<\cctcounterb \advance\cctcountera\plusone \expandafter\next\expandafter#1\fi}
+
+\cctcountera 0 \cctcounterb 127 \next\setdefaultlowercatcodes
+\cctcountera 128 \cctcounterb 255 \next\setdefaultuppercatcodes
+
+\recatcodeuppercharactersfalse
+
+\def\catcodetable#1%
+ {\mathchardef\currentcatcodetable#1%
+ \the\setdefaultlowercatcodes
+ \ifrecatcodeuppercharacters\the\setdefaultuppercatcodes\fi
+ \the\csname @@cct:\number#1\endcsname}
+
+\long\def\startcatcodetable#1#2\stopcatcodetable
+ {\global\csname @@cct:\number#1\endcsname{#2}}
+
+\long\def\startextendcatcodetable#1#2\stopextendcatcodetable
+ {\global\csname @@cct:\number#1\endcsname\expandafter{\the\csname @@cct:\number#1\endcsname#2}}
+
+%D The next command can be defined in a cleaner way in the
+%D Mk IV file but we want to have a fast one with a minimal
+%D chance for interference.
+
+\chardef\activehackcode=`\~
+
+%D Once a catcode is assigned, the next assignments will happen faster.
+
+% (expandable) let
+
+\def\letcatcodecommand {\afterassignment\letcatcodecommanda\cctcountera}
+\def\letcatcodecommanda{\afterassignment\letcatcodecommandb\cctcounterb}
+
+\def\letcatcodecommandb % each time
+ {\ifcsname CCL:\number\cctcountera:\number\cctcounterb\endcsname
+ \csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \else
+ \expandafter\letcatcodecommandc
+ \fi}
+
+\def\letcatcodecommandc % only first time
+ {\expandafter\gdef\csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname\expandafter
+ {\expandafter\let\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname}%
+ \reinstatecatcodecommanda
+ \csname CCL:\number\cctcountera:\number\cctcounterb\endcsname}
+
+% expandable def
+
+\def\defcatcodecommand {\afterassignment\defcatcodecommanda\cctcountera}
+\def\defcatcodecommanda{\afterassignment\defcatcodecommandb\cctcounterb}
+
+\def\defcatcodecommandb % each time
+ {\ifcsname CCD:\number\cctcountera:\number\cctcounterb\endcsname
+ \csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \else
+ \expandafter\defcatcodecommandc
+ \fi}
+
+\def\defcatcodecommandc % only first time
+ {\expandafter\gdef\csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \expandafter##\expandafter1\expandafter
+ {\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}%
+ \reinstatecatcodecommanda
+ \csname CCD:\number\cctcountera:\number\cctcounterb\endcsname}
+
+% un expandable def (e.g. used for discretionaries)
+
+\def\uedcatcodecommand {\afterassignment\uedcatcodecommanda\cctcountera}
+\def\uedcatcodecommanda{\afterassignment\uedcatcodecommandb\cctcounterb}
+
+\def\uedcatcodecommandb % each time
+ {\ifcsname CCU:\number\cctcountera:\number\cctcounterb\endcsname
+ \csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \else
+ \expandafter\uedcatcodecommandc
+ \fi}
+
+\def\uedcatcodecommandc % only first time
+ {\expandafter\gdef\csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \expandafter##\expandafter1\expandafter
+ {\expandafter\unexpanded\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}%
+ \reinstatecatcodecommanda
+ \csname CCU:\number\cctcountera:\number\cctcounterb\endcsname}
+
+\def\reinstatecatcodecommand{\afterassignment\reinstatecatcodecommanda\cctcounterb}
+
+\def\reinstatecatcodecommanda % can be used when a direct definition has been done
+ {\bgroup % and the selector has been lost
+ \uccode\activehackcode\cctcounterb
+ \catcode\uccode\activehackcode13
+ \uppercase{\xdef~{\noexpand\catcodecommand{\number\cctcounterb}}}%
+ \egroup}
+
+\chardef\defaultcatcodetable\zerocount
+
+\def\catcodecommand#1%
+ {\csname CCC:\number
+ \ifcsname CCC:\number\currentcatcodetable:\number#1\endcsname
+ \currentcatcodetable \else \defaultcatcodetable
+ \fi
+ :\number#1\endcsname}
+
+%D \macros
+%D {restorecatcodes,
+%D beginrestorecatcodes,endrestorecatcodes}
+%D
+%D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we
+%D use only one auxiliary file, which deals with tables of
+%D contents, registers, two pass tracking, references etc. This
+%D file, as well as files concerning graphics, is processed when
+%D needed, which can be in the mid of typesetting verbatim.
+%D However, when reading in data in verbatim mode, we should
+%D temporary restore the normal \CATCODES, and that's exactly
+%D what the next macros do. Saving the catcodes can be
+%D disabled by saying \type{\localcatcodestrue}.
+
+\let\savedcatcodetable\relax
+
+\newcount\catcoderestorelevel
+
+\def\pushcatcodetable
+ {\advance\catcoderestorelevel\plusone
+ \tracepushcatcodetable
+ \expandafter\mathchardef\csname scct:\number\catcoderestorelevel\endcsname\currentcatcodetable}
+
+\def\popcatcodetable
+ {\ifcase\catcoderestorelevel
+ \immediate\write16{}%
+ \immediate\write16{Fatal error: catcode push/pop mismatch. Fix this!}\wait\end
+ \immediate\write16{}%
+ \else
+ \expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname
+ \tracepopcatcodetable
+ \advance\catcoderestorelevel\minusone
+ \fi}
+
+\def\restorecatcodes % takes previous level
+ {\ifnum\catcoderestorelevel>\plusone
+ \expandafter\catcodetable\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname
+ \fi}
+
+\newtoks\everycatcodetable
+
+\def\setcatcodetable#1%
+ {\catcodetable#1%
+ \the\everycatcodetable
+ \tracesetcatcodetable}
+
+\def\dotracecatcodetable#1{\immediate\write16{[#1]}}
+
+\def\tracecatcodetables
+ {\def\tracesetcatcodetable {\dotracecatcodetable{set \catcodetablename\space at \number\catcoderestorelevel}}%
+ \def\tracepushcatcodetable{\dotracecatcodetable{push \catcodetablename\space from \catcodetableprev\space at \number\catcoderestorelevel}}%
+ \def\tracepopcatcodetable {\dotracecatcodetable{pop \catcodetablename\space to \catcodetableprev\space at \number\catcoderestorelevel}}}
+
+\def\catcodetableprev
+ {\ifnum\numexpr\catcoderestorelevel-1\relax>\zerocount
+ \csname @@ccn:\number\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname\endcsname
+ \else
+ -%
+ \fi}
+
+\def\catcodetablename
+ {\ifnum\currentcatcodetable>\zerocount
+ \csname @@ccn:\number\currentcatcodetable\endcsname
+ \else
+ -%
+ \fi}
+
+\ifx\empty\undefined \def\empty{} \fi
+
+\let\tracesetcatcodetable \empty
+\let\tracepushcatcodetable\empty
+\let\tracepopcatcodetable \empty
+
+\def\beginrestorecatcodes{\pushcatcodetable}
+\def\endrestorecatcodes {\popcatcodetable}
+
+%D Handy for debugging:
+
+% \tracecatcodetables
+
+\endinput
+
diff --git a/tex/context/base/catc-ini.mkiv b/tex/context/base/catc-ini.mkiv
new file mode 100644
index 000000000..085b82005
--- /dev/null
+++ b/tex/context/base/catc-ini.mkiv
@@ -0,0 +1,255 @@
+%D \module
+%D [ file=catc-ini,
+%D version=2006.09.18,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Catcode Handling,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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've split the functionality of syst-cat.* over more files
+%D now so that we can load more selectively.
+
+\registerctxluafile{catc-ini} {1.001}
+
+%D A long standing wish has been the availability of catcode
+%D arrays. Because traditional \TEX\ does not provide this we
+%D implement a fake method in the \MKII\ file. There is some
+%D overlap in code with \MKII\ but we take that for granted.
+
+\ifx\zerocount\undefined \chardef \zerocount= 0 \fi
+\ifx\plusone \undefined \chardef \plusone = 1 \fi
+\ifx\minusone \undefined \newcount\minusone \minusone =-1 \fi
+
+\ifx\gobbleoneargument\undefined \long\def\gobbleoneargument#1{} \fi
+
+\newif \ifrecatcodeuppercharacters % only used in good old tex
+
+\newcount\cctdefcounter \cctdefcounter\zerocount % 0 = signal, so advance before allocate
+
+\newcount\cctcountera
+\newcount\cctcounterb
+\newcount\cctcounterc
+
+\def\newcatcodetable#1%
+ {\global\advance\cctdefcounter\plusone
+ \expandafter\xdef\csname @@ccn:\number\cctdefcounter\endcsname{\string#1}% logging
+ \global\mathchardef#1\cctdefcounter
+ \ctxlua{catcodes.register("\expandafter\gobbleoneargument\string#1",\number#1)}%
+ % we have two ways to access catcodetable numbers
+ \startruntimectxluacode tex.\expandafter\gobbleoneargument\string#1 = \number#1 ;\stopruntimectxluacode}
+
+\newcatcodetable \scratchcatcodes \initcatcodetable\scratchcatcodes
+
+\newtoks \setdefaultcatcodes
+
+\setdefaultcatcodes
+ {\catcode`\\ 12
+ \catcode`\^^M 12
+ \catcode`\ 12
+ \catcode`\% 12
+ \catcode127 12 }
+
+\long\def\startcatcodetable#1#2\stopcatcodetable
+ {\bgroup
+ \catcodetable\scratchcatcodes
+ \the\setdefaultcatcodes
+ #2%
+ \savecatcodetable#1\relax
+ \egroup}
+
+\newcatcodetable\dummycatcodes
+
+\long\def\startextendcatcodetable#1#2\stopextendcatcodetable
+ {\bgroup
+ \catcodetable#1\relax
+ \globaldefs\plusone
+ #2%
+ \globaldefs\zerocount
+ \egroup}
+
+% ==
+%
+% \long\def\startextendcatcodetable#1#2\stopextendcatcodetable
+% {\bgroup
+% \scratchcounter\the\catcodetable
+% \catcodetable #1 #2
+% \catcodetable\scratchcounter
+% \egroup}
+
+\def\letcatcodecommand
+ {\afterassignment\letcatcodecommanda\cctcountera}
+
+\def\letcatcodecommanda
+ {\afterassignment\letcatcodecommandb\cctcounterb}
+
+\let\currentcatcodetable\catcodetable
+
+%D The next command can be defined in a cleaner way in the
+%D Mk IV file but we want to have a fast one with a minimal
+%D chance for interference.
+
+\chardef\activehackcode=`\~
+
+%D Once a catcode is assigned, the next assignments will happen faster.
+
+% (expandable) let
+
+\def\letcatcodecommand {\afterassignment\letcatcodecommanda\cctcountera}
+\def\letcatcodecommanda{\afterassignment\letcatcodecommandb\cctcounterb}
+
+\def\letcatcodecommandb % each time
+ {\ifcsname CCL:\number\cctcountera:\number\cctcounterb\endcsname
+ \csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \else
+ \expandafter\letcatcodecommandc
+ \fi}
+
+\def\letcatcodecommandc % only first time
+ {\expandafter\gdef\csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname\expandafter
+ {\expandafter\let\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname}%
+ \reinstatecatcodecommanda
+ \csname CCL:\number\cctcountera:\number\cctcounterb\endcsname}
+
+% expandable def
+
+\def\defcatcodecommand {\afterassignment\defcatcodecommanda\cctcountera}
+\def\defcatcodecommanda{\afterassignment\defcatcodecommandb\cctcounterb}
+
+\def\defcatcodecommandb % each time
+ {\ifcsname CCD:\number\cctcountera:\number\cctcounterb\endcsname
+ \csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \else
+ \expandafter\defcatcodecommandc
+ \fi}
+
+\def\defcatcodecommandc % only first time
+ {\expandafter\gdef\csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \expandafter##\expandafter1\expandafter
+ {\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}%
+ \reinstatecatcodecommanda
+ \csname CCD:\number\cctcountera:\number\cctcounterb\endcsname}
+
+% unexpandable def (e.g. used for discretionaries)
+
+\def\uedcatcodecommand {\afterassignment\uedcatcodecommanda\cctcountera}
+\def\uedcatcodecommanda{\afterassignment\uedcatcodecommandb\cctcounterb}
+
+\def\uedcatcodecommandb % each time
+ {\ifcsname CCU:\number\cctcountera:\number\cctcounterb\endcsname
+ \csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \else
+ \expandafter\uedcatcodecommandc
+ \fi}
+
+\def\uedcatcodecommandc % only first time
+ {\expandafter\gdef\csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
+ \expandafter##\expandafter1\expandafter
+ {\expandafter\unexpanded\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}%
+ \reinstatecatcodecommanda
+ \csname CCU:\number\cctcountera:\number\cctcounterb\endcsname}
+
+\def\reinstatecatcodecommand{\afterassignment\reinstatecatcodecommanda\cctcounterb}
+
+\def\reinstatecatcodecommanda % can be used when a direct definition has been done
+ {\bgroup % and the selector has been lost
+ \uccode\activehackcode\cctcounterb
+ \catcode\uccode\activehackcode13
+ \uppercase{\xdef~{\noexpand\catcodecommand{\number\cctcounterb}}}%
+ \egroup}
+
+\chardef\defaultcatcodetable\zerocount
+
+\def\catcodecommand#1%
+ {\csname CCC:\number
+ \ifcsname CCC:\number\currentcatcodetable:\number#1\endcsname
+ \currentcatcodetable \else \defaultcatcodetable
+ \fi
+ :\number#1\endcsname}
+
+%D \macros
+%D {restorecatcodes,
+%D beginrestorecatcodes,endrestorecatcodes}
+%D
+%D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we
+%D use only one auxiliary file, which deals with tables of
+%D contents, registers, two pass tracking, references etc. This
+%D file, as well as files concerning graphics, is processed when
+%D needed, which can be in the mid of typesetting verbatim.
+%D However, when reading in data in verbatim mode, we should
+%D temporary restore the normal \CATCODES, and that's exactly
+%D what the next macros do. Saving the catcodes can be
+%D disabled by saying \type{\localcatcodestrue}.
+
+\let\savedcatcodetable\relax
+
+\newcount\catcoderestorelevel
+
+\def\pushcatcodetable
+ {\advance\catcoderestorelevel\plusone
+ \tracepushcatcodetable
+ \expandafter\mathchardef\csname scct:\number\catcoderestorelevel\endcsname\currentcatcodetable}
+
+\def\popcatcodetable
+ {\ifcase\catcoderestorelevel
+ \immediate\write16{}%
+ \immediate\write16{Fatal error: catcode push/pop mismatch. Fix this!}\wait\end
+ \immediate\write16{}%
+ \else
+ \expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname
+ \tracepopcatcodetable
+ \advance\catcoderestorelevel\minusone
+ \fi}
+
+\def\restorecatcodes % takes previous level
+ {\ifnum\catcoderestorelevel>\plusone
+ \expandafter\catcodetable\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname
+ \fi}
+
+\newtoks\everycatcodetable
+
+\def\setcatcodetable#1%
+ {\catcodetable#1%
+ \the\everycatcodetable
+ \tracesetcatcodetable}
+
+\def\dotracecatcodetable#1{\immediate\write16{[#1]}}
+
+\def\tracecatcodetables
+ {\def\tracesetcatcodetable {\dotracecatcodetable{set \catcodetablename\space at \number\catcoderestorelevel}}%
+ \def\tracepushcatcodetable{\dotracecatcodetable{push \catcodetablename\space from \catcodetableprev\space at \number\catcoderestorelevel}}%
+ \def\tracepopcatcodetable {\dotracecatcodetable{pop \catcodetablename\space to \catcodetableprev\space at \number\catcoderestorelevel}}}
+
+\def\catcodetableprev
+ {\ifnum\numexpr\catcoderestorelevel-1\relax>\zerocount
+ \csname @@ccn:\number\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname\endcsname
+ \else
+ -%
+ \fi}
+
+\def\catcodetablename
+ {\ifnum\currentcatcodetable>\zerocount
+ \csname @@ccn:\number\currentcatcodetable\endcsname
+ \else
+ -%
+ \fi}
+
+\ifx\empty\undefined \def\empty{} \fi
+
+\let\tracesetcatcodetable \empty
+\let\tracepushcatcodetable\empty
+\let\tracepopcatcodetable \empty
+
+\def\beginrestorecatcodes{\pushcatcodetable}
+\def\endrestorecatcodes {\popcatcodetable}
+
+%D Handy for debugging:
+
+% \tracecatcodetables
+
+\endinput
+
diff --git a/tex/context/base/syst-chr.tex b/tex/context/base/catc-sym.tex
index 085d7429f..49d94815c 100644
--- a/tex/context/base/syst-chr.tex
+++ b/tex/context/base/catc-sym.tex
@@ -1,11 +1,11 @@
%D \module
-%D [ file=syst-chr,
+%D [ file=catc-sym,
%D version=1997.01.03, % moved code
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Character Related Things,
+%D title=\CONTEXT\ Catcode Macros,
+%D subtitle=Some Handy Constants,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%D copyright=\PRAGMA]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
@@ -53,30 +53,15 @@
.egroup
-%D \macros % check this one
-%D {setcatcodes,uncatcodespecials,
-%D uncatcodecharacters,uncatcodespacetokens,
-%D setnaturalcatcodes,
-%D setverbosecscharacters}
+%D \macros
+%D {uncatcodespecials,setnaturalcatcodes,setnormalcatcodes,
+%D uncatcodecharacters,uncatcodeallcharacters,
+%D uncatcodespacetokens}
%D
-%D As its name says, \type{\uncatcodecharacters} resets the
-%D \CATCODE\ of characters. When we use an upper bound of
-%D 127 or 255, depending in \type{\ifeightbitcharacters}. By
-%D counting down, we only have to use one counter. The
-%D macro \type{\setcatcodes} can be uses to set alternative
-%D values. The macro \type{\resetspecialcharacters} resets
-%D characters with special meanings. This macro is not used
-%D in the verbatim macros, but is best defined in this module.
-
-\newtoks\everycommoncatcodes % gone
-\newtoks\everynaturalcatcodes % gone
-\newtoks\everynormalcatcodes % gone
-
-\def\uncatcodespacetokens
- {\catcode`\ =\@@space
- \catcode`\^^L=\@@ignore
- \catcode`\^^M=\@@endofline
- \catcode`\^^?=\@@ignore}
+%D The following macros are more or less replaced by switching
+%D to a catcode table (which we simulate in \MKII) but we keep
+%D them for convenience and compatibility. Some old engine code
+%D has been removed.
\def\uncatcodespecials {\setcatcodetable\nilcatcodes \uncatcodespacetokens}
\def\setnaturalcatcodes {\setcatcodetable\nilcatcodes}
@@ -84,48 +69,50 @@
\def\uncatcodecharacters {\setcatcodetable\nilcatcodes} % was fast version, gone now
\def\uncatcodeallcharacters{\setcatcodetable\nilcatcodes} % was slow one, with restore
+\def\uncatcodespacetokens
+ {\catcode`\ =\@@space
+ \catcode`\^^L=\@@ignore
+ \catcode`\^^M=\@@endofline
+ \catcode`\^^?=\@@ignore}
+
+%D \macros
+%D {setverbosecharacter,setverbosecscharacters}
+%D
%D Next follows a definition that lets some shortcuts expand to
-%D themselves.
+%D themselves. This macro is meant for \POSTSCRIPT\ and \PDF\
+%D code passed on to the backend.
+
+\newtoks\everyverbosechacters
\def\setverbosecscharacter#1%
{\edef#1{\string#1}}
-\bgroup \catcode`\|=13 \catcode`\~=13
-
-\gdef\setverbosecscharacters % temporary hack
- {\setverbosecscharacter |\setverbosecscharacter ~% context specific
- \setverbosecscharacter\|\setverbosecscharacter\~%
- \setverbosecscharacter\:\setverbosecscharacter\;%
- \setverbosecscharacter\+\setverbosecscharacter\-%
- \setverbosecscharacter\[\setverbosecscharacter\]%
- \setverbosecscharacter\.\setverbosecscharacter\\%
- \setverbosecscharacter\)\setverbosecscharacter\(%
- \setverbosecscharacter\0\setverbosecscharacter\1%
- \setverbosecscharacter\2\setverbosecscharacter\3%
- \setverbosecscharacter\4\setverbosecscharacter\5%
- \setverbosecscharacter\6\setverbosecscharacter\7%
- \setverbosecscharacter\8\setverbosecscharacter\9%
- \setverbosecscharacter\n\setverbosecscharacter\s%
- \setverbosecscharacter\/}
-
-\egroup
+\def\setverbosecscharacters
+ {\the\everyverbosechacters}
-%D \macros
-%D {frenchspacing,nonfrenchspacing}
-%D
-%D This code should move.
-
-\def\setfrenchspacing#1%
- {\sfcode`\.#1 \sfcode`\,#1\relax
- \sfcode`\?#1 \sfcode`\!#1\relax
- \sfcode`\:#1 \sfcode`\;#1\relax}
+\bgroup
-\def\frenchspacing
- {\setfrenchspacing{1000}}
+ % if used often we can move the code inline
+
+ \catcode`\|=\@@active
+ \catcode`\~=\@@active
+
+ \global \everyverbosechacters =
+ {\setverbosecscharacter |\setverbosecscharacter ~% context specific
+ \setverbosecscharacter\|\setverbosecscharacter\~%
+ \setverbosecscharacter\:\setverbosecscharacter\;%
+ \setverbosecscharacter\+\setverbosecscharacter\-%
+ \setverbosecscharacter\[\setverbosecscharacter\]%
+ \setverbosecscharacter\.\setverbosecscharacter\\%
+ \setverbosecscharacter\)\setverbosecscharacter\(%
+ \setverbosecscharacter\0\setverbosecscharacter\1%
+ \setverbosecscharacter\2\setverbosecscharacter\3%
+ \setverbosecscharacter\4\setverbosecscharacter\5%
+ \setverbosecscharacter\6\setverbosecscharacter\7%
+ \setverbosecscharacter\8\setverbosecscharacter\9%
+ \setverbosecscharacter\n\setverbosecscharacter\s%
+ \setverbosecscharacter\/}
-\def\resetfrenchspacing
- {\sfcode`\.3000 \sfcode`\,1250
- \sfcode`\?3000 \sfcode`\!3000
- \sfcode`\:2000 \sfcode`\;1500 }
+\egroup
\protect \endinput
diff --git a/tex/context/base/char-cmp.lua b/tex/context/base/char-cmp.lua
index e995f510f..bd3360499 100644
--- a/tex/context/base/char-cmp.lua
+++ b/tex/context/base/char-cmp.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['char-cmp'] = {
license = "see context related readme files"
}
+local utf = unicode.utf8
+
characters = characters or { }
characters.uncomposed = characters.uncomposed or { }
diff --git a/tex/context/base/char-def.lua b/tex/context/base/char-def.lua
index 701eadfe6..1c7c25944 100644
--- a/tex/context/base/char-def.lua
+++ b/tex/context/base/char-def.lua
@@ -1,11 +1,18 @@
if not modules then modules = { } end modules ['char-def'] = {
version = 1.001,
- comment = "much (but not all) data is derived from unicode tables",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
+--[[
+The first version of this table was generated from unicode tables
+but after that was mostly updated manual using data present in
+ConTeXt and elsewhere. I did my best to make this table as complete
+as needed for proper use in ConTeXt MkIV. All errors are mine. If
+you find an error or ommision, just let me know.
+]]--
+
characters = characters or { }
characters.data={
@@ -259,6 +266,7 @@ characters.data={
contextname="quotedbl",
description="QUOTATION MARK",
direction="on",
+ mathclass="default",
linebreak="qu",
unicodeslot=0x0022,
},
@@ -275,6 +283,7 @@ characters.data={
adobename="dollar",
category="sc",
cjkwd="na",
+ contextname="textdollar",
description="DOLLAR SIGN",
direction="et",
linebreak="pr",
@@ -303,9 +312,11 @@ characters.data={
adobename="quotesingle",
category="po",
cjkwd="na",
+ contextname="quotesingle",
description="APOSTROPHE",
direction="on",
linebreak="qu",
+ mathclass="default",
unicodeslot=0x0027,
},
{
@@ -340,6 +351,7 @@ characters.data={
direction="on",
linebreak="al",
mathclass="binary",
+ mathname="ast",
unicodeslot=0x002A,
},
{
@@ -360,6 +372,10 @@ characters.data={
direction="cs",
linebreak="is",
mathclass="punctuation",
+ mathspec={
+ { class="punctuation", name="textcomma" },
+ { class="ord", name="mathcomma" },
+ },
unicodeslot=0x002C,
},
{
@@ -369,7 +385,7 @@ characters.data={
description="HYPHEN-MINUS",
direction="es",
linebreak="hy",
- mathclass="binary",
+ mathsymbol=0x2212,
unicodeslot=0x002D,
},
{
@@ -379,17 +395,23 @@ characters.data={
description="FULL STOP",
direction="cs",
linebreak="is",
- mathclass="punctuation",
+ mathclass="ord",
+ mathspec={
+ { class="ord", name="mathperiod" },
+ { class="punctuation", name="textperiod" },
+ { class="punctuation", name="ldotp" },
+ },
unicodeslot=0x002E,
},
{
adobename="slash",
category="po",
cjkwd="na",
+ contextname="textslash",
description="SOLIDUS",
direction="cs",
linebreak="sy",
- mathclass="binary",
+ mathsymbol=0x2044,
unicodeslot=0x002F,
},
{
@@ -500,6 +522,7 @@ characters.data={
direction="cs",
linebreak="is",
mathclass="punctuation",
+ mathname="colon",
unicodeslot=0x003A,
},
{
@@ -860,6 +883,7 @@ characters.data={
direction="on",
linebreak="op",
mathclass="open",
+ mathname="lbracket",
mirror=0x005D,
unicodeslot=0x005B,
},
@@ -871,7 +895,8 @@ characters.data={
description="REVERSE SOLIDUS",
direction="on",
linebreak="pr",
- mathclass="binary",
+ mathclass="nothing",
+ mathname="backslash",
unicodeslot=0x005C,
},
{
@@ -882,6 +907,7 @@ characters.data={
direction="on",
linebreak="cl",
mathclass="close",
+ mathname="rbracket",
mirror=0x005B,
unicodeslot=0x005D,
},
@@ -894,8 +920,6 @@ characters.data={
direction="on",
linebreak="al",
mathclass="accent",
- mathname="widehat",
- mathstretch="h",
unicodeslot=0x005E,
},
{
@@ -914,6 +938,8 @@ characters.data={
cjkwd="na",
contextname="textgrave",
description="GRAVE ACCENT",
+ mathclass="accent",
+ mathname="grave",
direction="on",
linebreak="al",
unicodeslot=0x0060,
@@ -1010,6 +1036,7 @@ characters.data={
adobename="i",
category="ll",
cjkwd="na",
+ contextname="idotaccent",
description="LATIN SMALL LETTER I",
direction="l",
linebreak="al",
@@ -1213,7 +1240,7 @@ characters.data={
direction="on",
linebreak="op",
mathclass="open",
- mathname=false, -- "lbrace",
+ mathname="lbrace", -- was false
mirror=0x007D,
unicodeslot=0x007B,
},
@@ -1225,8 +1252,14 @@ characters.data={
description="VERTICAL LINE",
direction="on",
linebreak="ba",
- mathclass="binary",
- mathname="bar",
+ mathspec={
+-- { class="binary", name="bar" },
+ { class="nothing", name="arrowvert" },
+ { class="delimiter", name="vert" },
+ { class="open", name="lvert" },
+ { class="close", name="rvert" },
+ { class="relation", name="mid" },
+ },
unicodeslot=0x007C,
},
{
@@ -1238,7 +1271,7 @@ characters.data={
direction="on",
linebreak="cl",
mathclass="close",
- mathname=false, -- "rbrace",
+ mathname="rbrace", -- was false
mirror=0x007B,
unicodeslot=0x007D,
},
@@ -1250,9 +1283,6 @@ characters.data={
description="TILDE",
direction="on",
linebreak="al",
- mathclass="accent",
- mathname="widetilde",
- mathstretch="h",
unicodeslot=0x007E,
},
{
@@ -1543,6 +1573,8 @@ characters.data={
description="YEN SIGN",
direction="et",
linebreak="pr",
+ mathclass="nothing",
+ mathname="yen",
unicodeslot=0x00A5,
},
{
@@ -1563,6 +1595,8 @@ characters.data={
description="SECTION SIGN",
direction="on",
linebreak="ai",
+ mathclass="box",
+ mathname="S",
unicodeslot=0x00A7,
},
{
@@ -1573,6 +1607,8 @@ characters.data={
description="DIAERESIS",
direction="on",
linebreak="ai",
+ mathclass="accent",
+ mathname="ddot",
specials={ "compat", 0x0020, 0x0308 },
unicodeslot=0x00A8,
},
@@ -1614,8 +1650,10 @@ characters.data={
description="NOT SIGN",
direction="on",
linebreak="al",
- mathclass="ord",
- mathname="lnot",
+ mathspec={
+ { class="ord", name="lnot" },
+ { class="ord", name="neg" },
+ },
unicodeslot=0x00AC,
},
{
@@ -1645,6 +1683,8 @@ characters.data={
description="MACRON",
direction="on",
linebreak="al",
+ mathclass="accent",
+ mathname="bar",
specials={ "compat", 0x0020, 0x0304 },
unicodeslot=0x00AF,
},
@@ -1698,6 +1738,8 @@ characters.data={
description="ACUTE ACCENT",
direction="on",
linebreak="bb",
+ mathclass="accent",
+ mathname="acute",
specials={ "compat", 0x0020, 0x0301 },
unicodeslot=0x00B4,
},
@@ -1720,6 +1762,8 @@ characters.data={
description="PILCROW SIGN",
direction="on",
linebreak="ai",
+ mathclass="box",
+ mathname="P",
unicodeslot=0x00B6,
},
{
@@ -1731,6 +1775,7 @@ characters.data={
direction="on",
linebreak="ai",
mathclass="binary",
+ mathname="centerdot",
unicodeslot=0x00B7,
},
{
@@ -2402,10 +2447,12 @@ characters.data={
adobename="eth",
category="ll",
cjkwd="a",
- contextname="eth",
+ --~ contextname="eth", -- AM: Should this be defined in text mode?
description="LATIN SMALL LETTER ETH",
direction="l",
linebreak="al",
+ mathclass="ord",
+ mathname="eth",
uccode=0x00D0,
unicodeslot=0x00F0,
},
@@ -3071,6 +3118,8 @@ characters.data={
description="LATIN SMALL LETTER H WITH STROKE",
direction="l",
linebreak="al",
+ mathclass="ord",
+ mathname="hbar",
shcode=0x0068,
uccode=0x0126,
unicodeslot=0x0127,
@@ -7108,6 +7157,8 @@ characters.data={
description="MODIFIER LETTER CIRCUMFLEX ACCENT",
direction="on",
linebreak="al",
+ mathclass="accent",
+ mathname="hat",
specials={ "compat", 0x0020, 0x0302 },
unicodeslot=0x02C6,
},
@@ -7119,6 +7170,8 @@ characters.data={
description="CARON",
direction="on",
linebreak="ai",
+ mathclass="accent",
+ mathname="check",
specials={ "compat", 0x0020, 0x030C },
unicodeslot=0x02C7,
},
@@ -7247,6 +7300,8 @@ characters.data={
description="BREVE",
direction="on",
linebreak="ai",
+ mathclass="accent",
+ mathname="breve",
specials={ "compat", 0x0020, 0x0306 },
unicodeslot=0x02D8,
},
@@ -7258,6 +7313,8 @@ characters.data={
description="DOT ABOVE",
direction="on",
linebreak="ai",
+ mathclass="accent",
+ mathname="dot",
specials={ "compat", 0x0020, 0x0307 },
unicodeslot=0x02D9,
},
@@ -7269,6 +7326,8 @@ characters.data={
description="RING ABOVE",
direction="on",
linebreak="ai",
+ mathclass="accent",
+ mathname="mathring",
specials={ "compat", 0x0020, 0x030A },
unicodeslot=0x02DA,
},
@@ -7290,6 +7349,8 @@ characters.data={
description="SMALL TILDE",
direction="on",
linebreak="al",
+ mathclass="accent",
+ mathname="tilde",
specials={ "compat", 0x0020, 0x0303 },
unicodeslot=0x02DC,
},
@@ -7572,6 +7633,7 @@ characters.data={
description="COMBINING CIRCUMFLEX ACCENT",
direction="nsm",
linebreak="cm",
+ mathstretch="h",
unicodeslot=0x0302,
},
{
@@ -7581,6 +7643,7 @@ characters.data={
description="COMBINING TILDE",
direction="nsm",
linebreak="cm",
+ mathstretch="h",
unicodeslot=0x0303,
},
{
@@ -7836,6 +7899,7 @@ characters.data={
adobename="dotbelowcomb",
category="mn",
cjkwd="a",
+ contextname="textbottomdot",
description="COMBINING DOT BELOW",
direction="nsm",
linebreak="cm",
@@ -7860,6 +7924,7 @@ characters.data={
{
category="mn",
cjkwd="a",
+ contextname="textbottomcomma",
description="COMBINING COMMA BELOW",
direction="nsm",
linebreak="cm",
@@ -8007,6 +8072,8 @@ characters.data={
description="COMBINING LONG SOLIDUS OVERLAY",
direction="nsm",
linebreak="cm",
+ mathclass="relation",
+ mathname="not",
unicodeslot=0x0338,
},
{
@@ -8642,8 +8709,6 @@ characters.data={
direction="l",
lccode=0x03B1,
linebreak="al",
- mathclass="variable",
- mathname="Alpha",
unicodeslot=0x0391,
},
[0x0392]={
@@ -8655,8 +8720,6 @@ characters.data={
direction="l",
lccode=0x03B2,
linebreak="al",
- mathclass="variable",
- mathname="Beta",
unicodeslot=0x0392,
},
[0x0393]={
@@ -8668,8 +8731,6 @@ characters.data={
direction="l",
lccode=0x03B3,
linebreak="al",
- mathclass="variable",
- mathname="Gamma",
unicodeslot=0x0393,
},
[0x0394]={
@@ -8680,8 +8741,6 @@ characters.data={
direction="l",
lccode=0x03B4,
linebreak="al",
- mathclass="variable",
- mathname="Delta",
unicodeslot=0x0394,
},
[0x0395]={
@@ -8693,8 +8752,6 @@ characters.data={
direction="l",
lccode=0x03B5,
linebreak="al",
- mathclass="variable",
- mathname="Epsilon",
unicodeslot=0x0395,
},
[0x0396]={
@@ -8706,8 +8763,6 @@ characters.data={
direction="l",
lccode=0x03B6,
linebreak="al",
- mathclass="variable",
- mathname="Zeta",
unicodeslot=0x0396,
},
[0x0397]={
@@ -8719,8 +8774,6 @@ characters.data={
direction="l",
lccode=0x03B7,
linebreak="al",
- mathclass="variable",
- mathname="Eta",
unicodeslot=0x0397,
},
[0x0398]={
@@ -8732,8 +8785,6 @@ characters.data={
direction="l",
lccode=0x03B8,
linebreak="al",
- mathclass="variable",
- mathname="Theta",
unicodeslot=0x0398,
},
[0x0399]={
@@ -8745,8 +8796,6 @@ characters.data={
direction="l",
lccode=0x03B9,
linebreak="al",
- mathclass="variable",
- mathname="Iota",
unicodeslot=0x0399,
},
[0x039A]={
@@ -8758,8 +8807,6 @@ characters.data={
direction="l",
lccode=0x03BA,
linebreak="al",
- mathclass="variable",
- mathname="Kappa",
unicodeslot=0x039A,
},
[0x039B]={
@@ -8771,8 +8818,6 @@ characters.data={
direction="l",
lccode=0x03BB,
linebreak="al",
- mathclass="variable",
- mathname="Lambda",
unicodeslot=0x039B,
},
[0x039C]={
@@ -8784,8 +8829,6 @@ characters.data={
direction="l",
lccode=0x03BC,
linebreak="al",
- mathclass="variable",
- mathname="Mu",
unicodeslot=0x039C,
},
[0x039D]={
@@ -8797,8 +8840,6 @@ characters.data={
direction="l",
lccode=0x03BD,
linebreak="al",
- mathclass="variable",
- mathname="Nu",
unicodeslot=0x039D,
},
[0x039E]={
@@ -8810,8 +8851,6 @@ characters.data={
direction="l",
lccode=0x03BE,
linebreak="al",
- mathclass="variable",
- mathname="Xi",
unicodeslot=0x039E,
},
[0x039F]={
@@ -8823,8 +8862,6 @@ characters.data={
direction="l",
lccode=0x03BF,
linebreak="al",
- mathclass="variable",
- mathname="Omicron",
unicodeslot=0x039F,
},
[0x03A0]={
@@ -8836,8 +8873,6 @@ characters.data={
direction="l",
lccode=0x03C0,
linebreak="al",
- mathclass="variable",
- mathname="Pi",
unicodeslot=0x03A0,
},
[0x03A1]={
@@ -8849,8 +8884,6 @@ characters.data={
direction="l",
lccode=0x03C1,
linebreak="al",
- mathclass="variable",
- mathname="Rho",
unicodeslot=0x03A1,
},
[0x03A3]={
@@ -8862,8 +8895,6 @@ characters.data={
direction="l",
lccode=0x03C3,
linebreak="al",
- mathclass="variable",
- mathname="Sigma",
unicodeslot=0x03A3,
},
[0x03A4]={
@@ -8875,8 +8906,6 @@ characters.data={
direction="l",
lccode=0x03C4,
linebreak="al",
- mathclass="variable",
- mathname="Tau",
unicodeslot=0x03A4,
},
[0x03A5]={
@@ -8888,8 +8917,6 @@ characters.data={
direction="l",
lccode=0x03C5,
linebreak="al",
- mathclass="variable",
- mathname="Upsilon",
unicodeslot=0x03A5,
},
[0x03A6]={
@@ -8901,8 +8928,6 @@ characters.data={
direction="l",
lccode=0x03C6,
linebreak="al",
- mathclass="variable",
- mathname="Phi",
unicodeslot=0x03A6,
},
[0x03A7]={
@@ -8914,8 +8939,6 @@ characters.data={
direction="l",
lccode=0x03C7,
linebreak="al",
- mathclass="variable",
- mathname="Chi",
unicodeslot=0x03A7,
},
[0x03A8]={
@@ -8927,8 +8950,6 @@ characters.data={
direction="l",
lccode=0x03C8,
linebreak="al",
- mathclass="variable",
- mathname="Psi",
unicodeslot=0x03A8,
},
[0x03A9]={
@@ -8939,8 +8960,6 @@ characters.data={
direction="l",
lccode=0x03C9,
linebreak="al",
- mathclass="variable",
- mathname="Omega",
unicodeslot=0x03A9,
},
[0x03AA]={
@@ -9034,8 +9053,6 @@ characters.data={
description="GREEK SMALL LETTER ALPHA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="alpha",
uccode=0x0391,
unicodeslot=0x03B1,
},
@@ -9047,8 +9064,6 @@ characters.data={
description="GREEK SMALL LETTER BETA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="beta",
uccode=0x0392,
unicodeslot=0x03B2,
},
@@ -9060,8 +9075,6 @@ characters.data={
description="GREEK SMALL LETTER GAMMA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="gamma",
uccode=0x0393,
unicodeslot=0x03B3,
},
@@ -9073,8 +9086,6 @@ characters.data={
description="GREEK SMALL LETTER DELTA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="delta",
uccode=0x0394,
unicodeslot=0x03B4,
},
@@ -9086,8 +9097,6 @@ characters.data={
description="GREEK SMALL LETTER EPSILON",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="epsilon",
uccode=0x0395,
unicodeslot=0x03B5,
},
@@ -9099,8 +9108,6 @@ characters.data={
description="GREEK SMALL LETTER ZETA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="zeta",
uccode=0x0396,
unicodeslot=0x03B6,
},
@@ -9112,8 +9119,6 @@ characters.data={
description="GREEK SMALL LETTER ETA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="eta",
uccode=0x0397,
unicodeslot=0x03B7,
},
@@ -9125,8 +9130,6 @@ characters.data={
description="GREEK SMALL LETTER THETA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="theta",
uccode=0x0398,
unicodeslot=0x03B8,
},
@@ -9138,8 +9141,6 @@ characters.data={
description="GREEK SMALL LETTER IOTA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="iota",
uccode=0x0399,
unicodeslot=0x03B9,
},
@@ -9151,8 +9152,6 @@ characters.data={
description="GREEK SMALL LETTER KAPPA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="kappa",
uccode=0x039A,
unicodeslot=0x03BA,
},
@@ -9164,8 +9163,6 @@ characters.data={
description="GREEK SMALL LETTER LAMDA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="lambda",
uccode=0x039B,
unicodeslot=0x03BB,
},
@@ -9176,8 +9173,6 @@ characters.data={
description="GREEK SMALL LETTER MU",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="mu",
uccode=0x039C,
unicodeslot=0x03BC,
},
@@ -9189,8 +9184,6 @@ characters.data={
description="GREEK SMALL LETTER NU",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="nu",
uccode=0x039D,
unicodeslot=0x03BD,
},
@@ -9202,8 +9195,6 @@ characters.data={
description="GREEK SMALL LETTER XI",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="xi",
uccode=0x039E,
unicodeslot=0x03BE,
},
@@ -9215,8 +9206,6 @@ characters.data={
description="GREEK SMALL LETTER OMICRON",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="omicron",
uccode=0x039F,
unicodeslot=0x03BF,
},
@@ -9228,8 +9217,6 @@ characters.data={
description="GREEK SMALL LETTER PI",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="pi",
uccode=0x03A0,
unicodeslot=0x03C0,
},
@@ -9241,8 +9228,6 @@ characters.data={
description="GREEK SMALL LETTER RHO",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="rho",
uccode=0x03A1,
unicodeslot=0x03C1,
},
@@ -9253,8 +9238,6 @@ characters.data={
description="GREEK SMALL LETTER FINAL SIGMA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="varsigma",
uccode=0x03A3,
unicodeslot=0x03C2,
},
@@ -9266,8 +9249,6 @@ characters.data={
description="GREEK SMALL LETTER SIGMA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="sigma",
uccode=0x03A3,
unicodeslot=0x03C3,
},
@@ -9279,8 +9260,6 @@ characters.data={
description="GREEK SMALL LETTER TAU",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="tau",
uccode=0x03A4,
unicodeslot=0x03C4,
},
@@ -9292,8 +9271,6 @@ characters.data={
description="GREEK SMALL LETTER UPSILON",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="upsilon",
uccode=0x03A5,
unicodeslot=0x03C5,
},
@@ -9305,8 +9282,6 @@ characters.data={
description="GREEK SMALL LETTER PHI",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="varphi",
uccode=0x03A6,
unicodeslot=0x03C6,
},
@@ -9318,8 +9293,6 @@ characters.data={
description="GREEK SMALL LETTER CHI",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="chi",
uccode=0x03A7,
unicodeslot=0x03C7,
},
@@ -9331,8 +9304,6 @@ characters.data={
description="GREEK SMALL LETTER PSI",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="psi",
uccode=0x03A8,
unicodeslot=0x03C8,
},
@@ -9344,8 +9315,6 @@ characters.data={
description="GREEK SMALL LETTER OMEGA",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="omega",
uccode=0x03A9,
unicodeslot=0x03C9,
},
@@ -9425,8 +9394,6 @@ characters.data={
description="GREEK THETA SYMBOL",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="vartheta",
specials={ "compat", 0x03B8 },
uccode=0x0398,
unicodeslot=0x03D1,
@@ -9463,8 +9430,6 @@ characters.data={
description="GREEK PHI SYMBOL",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="phi",
specials={ "compat", 0x03C6 },
uccode=0x03A6,
unicodeslot=0x03D5,
@@ -9476,8 +9441,6 @@ characters.data={
description="GREEK PI SYMBOL",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="varpi",
specials={ "compat", 0x03C0 },
uccode=0x03A0,
unicodeslot=0x03D6,
@@ -9529,6 +9492,8 @@ characters.data={
direction="l",
lccode=0x03DD,
linebreak="al",
+ mathclass="variable",
+ mathname="digamma",
unicodeslot=0x03DC,
},
[0x03DD]={
@@ -9692,6 +9657,8 @@ characters.data={
direction="l",
linebreak="al",
specials={ "compat", 0x03BA },
+ mathclass="ord",
+ mathname="varkappa",
uccode=0x039A,
unicodeslot=0x03F0,
},
@@ -9701,8 +9668,6 @@ characters.data={
description="GREEK RHO SYMBOL",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="varrho",
specials={ "compat", 0x03C1 },
uccode=0x03A1,
unicodeslot=0x03F1,
@@ -9739,8 +9704,6 @@ characters.data={
description="GREEK LUNATE EPSILON SYMBOL",
direction="l",
linebreak="al",
- mathclass="variable",
- mathname="varepsilon",
specials={ "compat", 0x03B5 },
uccode=0x0395,
unicodeslot=0x03F5,
@@ -9750,6 +9713,8 @@ characters.data={
description="GREEK REVERSED LUNATE EPSILON SYMBOL",
direction="on",
linebreak="al",
+ mathclass="variable",
+ mathname="backepsilon",
unicodeslot=0x03F6,
},
[0x03F7]={
@@ -48951,6 +48916,10 @@ characters.data={
description="DAGGER",
direction="on",
linebreak="ai",
+ mathspec={
+ { class="binary", name="dagger" },
+ { class="box", name="dag" },
+ },
unicodeslot=0x2020,
},
[0x2021]={
@@ -48961,6 +48930,10 @@ characters.data={
description="DOUBLE DAGGER",
direction="on",
linebreak="ai",
+ mathspec={
+ { class="binary", name="ddagger" },
+ { class="box", name="ddag" },
+ },
unicodeslot=0x2021,
},
[0x2022]={
@@ -49010,6 +48983,8 @@ characters.data={
description="HORIZONTAL ELLIPSIS",
direction="on",
linebreak="in",
+ mathclass="inner",
+ mathname="ldots",
specials={ "compat", 0x002E, 0x002E, 0x002E },
unicodeslot=0x2026,
},
@@ -49106,6 +49081,8 @@ characters.data={
description="PRIME",
direction="et",
linebreak="po",
+ mathclass="nothing",
+ mathname="prime",
unicodeslot=0x2032,
},
[0x2033]={
@@ -49248,9 +49225,14 @@ characters.data={
[0x2044]={
adobename="fraction",
category="sm",
+ contextname="textfraction",
description="FRACTION SLASH",
direction="cs",
linebreak="is",
+ mathspec={
+ { class="binary", name="slash" },
+ { class="close", name="solidus" },
+ },
unicodeslot=0x2044,
},
[0x2045]={
@@ -50024,6 +50006,8 @@ characters.data={
description="COMBINING RIGHT ARROW ABOVE",
direction="nsm",
linebreak="cm",
+ mathclass="accent",
+ mathname="vec",
unicodeslot=0x20D7,
},
[0x20D8]={
@@ -50066,6 +50050,10 @@ characters.data={
description="COMBINING ENCLOSING CIRCLE",
direction="nsm",
linebreak="cm",
+ mathspec={
+ { class="default",name="bigcircle" },
+ { class="binary",name="bigcircle" },
+ },
unicodeslot=0x20DD,
},
[0x20DE]={
@@ -50073,6 +50061,8 @@ characters.data={
description="COMBINING ENCLOSING SQUARE",
direction="nsm",
linebreak="cm",
+ mathclass="default",
+ mathname="bigsquare",
unicodeslot=0x20DE,
},
[0x20DF]={
@@ -50080,6 +50070,8 @@ characters.data={
description="COMBINING ENCLOSING DIAMOND",
direction="nsm",
linebreak="cm",
+ mathclass="default",
+ mathname="bigdiamond",
unicodeslot=0x20DF,
},
[0x20E0]={
@@ -50150,6 +50142,7 @@ characters.data={
description="COMBINING WIDE BRIDGE ABOVE",
direction="nsm",
linebreak="cm",
+ mathclass="accent",
unicodeslot=0x20E9,
},
[0x20EA]={
@@ -50224,6 +50217,7 @@ characters.data={
category="so",
cjkwd="a",
description="DEGREE CELSIUS",
+ contextname="textcelsius",
direction="on",
linebreak="po",
specials={ "compat", 0x00B0, 0x0043 },
@@ -50342,7 +50336,7 @@ characters.data={
description="BLACK-LETTER CAPITAL I",
direction="l",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="Im",
specials={ "font", 0x0049 },
unicodeslot=0x2111,
@@ -50362,7 +50356,7 @@ characters.data={
description="SCRIPT SMALL L",
direction="l",
linebreak="ai",
- mathclass="variable",
+ mathclass="default",
mathname="ell",
specials={ "font", 0x006C },
unicodeslot=0x2113,
@@ -50397,6 +50391,7 @@ characters.data={
},
[0x2117]={
category="so",
+ contextname="textcircledP",
description="SOUND RECORDING COPYRIGHT",
direction="on",
linebreak="al",
@@ -50408,7 +50403,7 @@ characters.data={
description="SCRIPT CAPITAL P",
direction="on",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="wp",
unicodeslot=0x2118,
},
@@ -50446,7 +50441,7 @@ characters.data={
description="BLACK-LETTER CAPITAL R",
direction="l",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="Re",
specials={ "font", 0x0052 },
unicodeslot=0x211C,
@@ -50523,6 +50518,7 @@ characters.data={
},
[0x2125]={
category="so",
+ contextname="textounce",
description="OUNCE SIGN",
direction="on",
linebreak="al",
@@ -50533,17 +50529,19 @@ characters.data={
category="lu",
cjkwd="a",
description="OHM SIGN",
+ contextname="textohm",
direction="l",
- lccode=0x03C9,
+ lccode=0x03C9, --AM: Not sure?
linebreak="al",
mathclass="variable",
- mathname="Omega", --AM: Should we do this or does specials take care of it
+ mathname="ohm", --AM: Should we do this or does specials take care of it
specials={ "char", 0x03A9 },
unicodeslot=0x2126,
},
[0x2127]={
category="so",
description="INVERTED OHM SIGN",
+ contextname="textmho",
direction="on",
linebreak="al",
mathclass="variable",
@@ -50569,6 +50567,7 @@ characters.data={
category="lu",
description="KELVIN SIGN",
direction="l",
+ contextname="textkelvin",
lccode=0x006B,
linebreak="al",
specials={ "char", 0x004B },
@@ -50579,6 +50578,7 @@ characters.data={
cjkwd="a",
description="ANGSTROM SIGN",
direction="l",
+ contextname="textAngstrom",
lccode=0x00E5,
linebreak="ai",
mathclass="variable",
@@ -50640,6 +50640,8 @@ characters.data={
direction="l",
lccode=0x214E,
linebreak="al",
+ mathclass="ord",
+ mathname="Finv",
unicodeslot=0x2132,
},
[0x2133]={
@@ -50664,7 +50666,7 @@ characters.data={
description="ALEF SYMBOL",
direction="l",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="aleph",
specials={ "compat", 0x05D0 },
unicodeslot=0x2135,
@@ -50674,6 +50676,8 @@ characters.data={
description="BET SYMBOL",
direction="l",
linebreak="al",
+ mathclass="ord",
+ mathname="beth",
specials={ "compat", 0x05D1 },
unicodeslot=0x2136,
},
@@ -50682,6 +50686,8 @@ characters.data={
description="GIMEL SYMBOL",
direction="l",
linebreak="al",
+ mathclass="ord",
+ mathname="gimel",
specials={ "compat", 0x05D2 },
unicodeslot=0x2137,
},
@@ -50690,6 +50696,8 @@ characters.data={
description="DALET SYMBOL",
direction="l",
linebreak="al",
+ mathclass="ord",
+ mathname="daleth",
specials={ "compat", 0x05D3 },
unicodeslot=0x2138,
},
@@ -50761,6 +50769,8 @@ characters.data={
description="TURNED SANS-SERIF CAPITAL G",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="Game",
unicodeslot=0x2141,
},
[0x2142]={
@@ -50829,6 +50839,8 @@ characters.data={
description="DOUBLE-STRUCK ITALIC SMALL J",
direction="l",
linebreak="al",
+ mathclass="nothing",
+ mathname="imaginaryj",
specials={ "font", 0x006A },
unicodeslot=0x2149,
},
@@ -51382,8 +51394,12 @@ characters.data={
description="LEFTWARDS ARROW",
direction="on",
linebreak="ai",
- mathclass="relation",
- mathname="leftarrow",
+ mathspec={
+ { class="relation", name="leftarrow" },
+ { class="relation", name="gets" },
+ { class="under", name="underleftarrow" },
+ { class="over", name="overleftarrow" },
+ },
mathstretch="h",
unicodeslot=0x2190,
},
@@ -51395,7 +51411,7 @@ characters.data={
direction="on",
linebreak="ai",
mathclass="relation",
- mathname="uparraow",
+ mathname="uparrow",
unicodeslot=0x2191,
},
[0x2192]={
@@ -51405,9 +51421,12 @@ characters.data={
description="RIGHTWARDS ARROW",
direction="on",
linebreak="ai",
- mathclass="relation",
- mathfiller="rightarrowfill",
- mathname="rightarrow",
+ mathspec={
+ { class="relation",name="rightarrow" },
+ { class="relation",name="to" },
+ { class="under", name="underrightarrow" },
+ { class="over", name="overrightarrow" },
+ },
mathstretch="h",
unicodeslot=0x2192,
},
@@ -51489,6 +51508,8 @@ characters.data={
description="LEFTWARDS ARROW WITH STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nleftarrow",
specials={ "char", 0x2190, 0x0338 },
unicodeslot=0x219A,
},
@@ -51497,6 +51518,8 @@ characters.data={
description="RIGHTWARDS ARROW WITH STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nrightarrow",
specials={ "char", 0x2192, 0x0338 },
unicodeslot=0x219B,
},
@@ -51519,6 +51542,8 @@ characters.data={
description="LEFTWARDS TWO HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="twoheadleftarrow",
unicodeslot=0x219E,
},
[0x219F]={
@@ -51526,6 +51551,8 @@ characters.data={
description="UPWARDS TWO HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="twoheadupleftarrow",
unicodeslot=0x219F,
},
[0x21A0]={
@@ -51533,6 +51560,8 @@ characters.data={
description="RIGHTWARDS TWO HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="twoheadrightarrow",
unicodeslot=0x21A0,
},
[0x21A1]={
@@ -51540,6 +51569,8 @@ characters.data={
description="DOWNWARDS TWO HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="twoheaddownleftarrow",
unicodeslot=0x21A1,
},
[0x21A2]={
@@ -51547,6 +51578,8 @@ characters.data={
description="LEFTWARDS ARROW WITH TAIL",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftarrowtail",
unicodeslot=0x21A2,
},
[0x21A3]={
@@ -51554,6 +51587,8 @@ characters.data={
description="RIGHTWARDS ARROW WITH TAIL",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightarrowtail",
unicodeslot=0x21A3,
},
[0x21A4]={
@@ -51575,6 +51610,9 @@ characters.data={
description="RIGHTWARDS ARROW FROM BAR",
direction="on",
linebreak="al",
+ fallback=[[\mapstochar\rightarrow]],
+ mathclass="relation",
+ mathname="mapsto",
unicodeslot=0x21A6,
},
[0x21A7]={
@@ -51597,6 +51635,9 @@ characters.data={
description="LEFTWARDS ARROW WITH HOOK",
direction="on",
linebreak="al",
+ fallback=[[\leftarrow\joinrel\rhook]],
+ mathclass="relation",
+ mathname="hookleftarrow",
unicodeslot=0x21A9,
},
[0x21AA]={
@@ -51604,6 +51645,9 @@ characters.data={
description="RIGHTWARDS ARROW WITH HOOK",
direction="on",
linebreak="al",
+ fallback=[[\lhook\joinrel\rightarrow]],
+ mathclass="relation",
+ mathname="hookrightarrow",
unicodeslot=0x21AA,
},
[0x21AB]={
@@ -51611,6 +51655,8 @@ characters.data={
description="LEFTWARDS ARROW WITH LOOP",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="looparrowleft",
unicodeslot=0x21AB,
},
[0x21AC]={
@@ -51618,6 +51664,8 @@ characters.data={
description="RIGHTWARDS ARROW WITH LOOP",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="looparrowright",
unicodeslot=0x21AC,
},
[0x21AD]={
@@ -51625,6 +51673,8 @@ characters.data={
description="LEFT RIGHT WAVE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftrightsquigarrow",
unicodeslot=0x21AD,
},
[0x21AE]={
@@ -51632,6 +51682,8 @@ characters.data={
description="LEFT RIGHT ARROW WITH STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nleftrightarrow",
specials={ "char", 0x2194, 0x0338 },
unicodeslot=0x21AE,
},
@@ -51647,6 +51699,8 @@ characters.data={
description="UPWARDS ARROW WITH TIP LEFTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Lsh",
unicodeslot=0x21B0,
},
[0x21B1]={
@@ -51654,6 +51708,8 @@ characters.data={
description="UPWARDS ARROW WITH TIP RIGHTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Rsh",
unicodeslot=0x21B1,
},
[0x21B2]={
@@ -51661,6 +51717,8 @@ characters.data={
description="DOWNWARDS ARROW WITH TIP LEFTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dlsh", -- from mathabx
unicodeslot=0x21B2,
},
[0x21B3]={
@@ -51668,6 +51726,8 @@ characters.data={
description="DOWNWARDS ARROW WITH TIP RIGHTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="drsh", -- from mathabx
unicodeslot=0x21B3,
},
[0x21B4]={
@@ -51679,6 +51739,7 @@ characters.data={
},
[0x21B5]={
adobename="carriagereturn",
+ contextname="carriagereturn",
category="so",
description="DOWNWARDS ARROW WITH CORNER LEFTWARDS",
direction="on",
@@ -51690,6 +51751,8 @@ characters.data={
description="ANTICLOCKWISE TOP SEMICIRCLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="curvearrowleft",
unicodeslot=0x21B6,
},
[0x21B7]={
@@ -51697,6 +51760,8 @@ characters.data={
description="CLOCKWISE TOP SEMICIRCLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="curvearrowright",
unicodeslot=0x21B7,
},
[0x21B8]={
@@ -51720,6 +51785,8 @@ characters.data={
description="ANTICLOCKWISE OPEN CIRCLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="circlearrowright",
unicodeslot=0x21BA,
},
[0x21BB]={
@@ -51727,6 +51794,8 @@ characters.data={
description="CLOCKWISE OPEN CIRCLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="circlearrowleft",
unicodeslot=0x21BB,
},
[0x21BC]={
@@ -51734,6 +51803,8 @@ characters.data={
description="LEFTWARDS HARPOON WITH BARB UPWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftharpoonup",
unicodeslot=0x21BC,
},
[0x21BD]={
@@ -51741,6 +51812,8 @@ characters.data={
description="LEFTWARDS HARPOON WITH BARB DOWNWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftharpoondown",
unicodeslot=0x21BD,
},
[0x21BE]={
@@ -51748,6 +51821,10 @@ characters.data={
description="UPWARDS HARPOON WITH BARB RIGHTWARDS",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation", name="upharpoonright" },
+ { class="relation", name="restriction" },
+ },
unicodeslot=0x21BE,
},
[0x21BF]={
@@ -51755,6 +51832,8 @@ characters.data={
description="UPWARDS HARPOON WITH BARB LEFTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="upharpoonleft",
unicodeslot=0x21BF,
},
[0x21C0]={
@@ -51762,6 +51841,8 @@ characters.data={
description="RIGHTWARDS HARPOON WITH BARB UPWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightharpoonup",
unicodeslot=0x21C0,
},
[0x21C1]={
@@ -51769,6 +51850,8 @@ characters.data={
description="RIGHTWARDS HARPOON WITH BARB DOWNWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightharpoondown",
unicodeslot=0x21C1,
},
[0x21C2]={
@@ -51776,6 +51859,8 @@ characters.data={
description="DOWNWARDS HARPOON WITH BARB RIGHTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="downharpoonright",
unicodeslot=0x21C2,
},
[0x21C3]={
@@ -51783,6 +51868,8 @@ characters.data={
description="DOWNWARDS HARPOON WITH BARB LEFTWARDS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="downharpoonleft",
unicodeslot=0x21C3,
},
[0x21C4]={
@@ -51790,6 +51877,8 @@ characters.data={
description="RIGHTWARDS ARROW OVER LEFTWARDS ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightleftarrows",
unicodeslot=0x21C4,
},
[0x21C5]={
@@ -51797,6 +51886,8 @@ characters.data={
description="UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="updownarrows",
unicodeslot=0x21C5,
},
[0x21C6]={
@@ -51804,6 +51895,8 @@ characters.data={
description="LEFTWARDS ARROW OVER RIGHTWARDS ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftrightarrows",
unicodeslot=0x21C6,
},
[0x21C7]={
@@ -51811,6 +51904,8 @@ characters.data={
description="LEFTWARDS PAIRED ARROWS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftleftarrows",
unicodeslot=0x21C7,
},
[0x21C8]={
@@ -51818,6 +51913,8 @@ characters.data={
description="UPWARDS PAIRED ARROWS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="upuparrows",
unicodeslot=0x21C8,
},
[0x21C9]={
@@ -51825,6 +51922,8 @@ characters.data={
description="RIGHTWARDS PAIRED ARROWS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightrightarrows",
unicodeslot=0x21C9,
},
[0x21CA]={
@@ -51832,6 +51931,8 @@ characters.data={
description="DOWNWARDS PAIRED ARROWS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="downdownarrows",
unicodeslot=0x21CA,
},
[0x21CB]={
@@ -51839,6 +51940,8 @@ characters.data={
description="LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftrightharpoons",
unicodeslot=0x21CB,
},
[0x21CC]={
@@ -51846,6 +51949,8 @@ characters.data={
description="RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightleftharpoons",
unicodeslot=0x21CC,
},
[0x21CD]={
@@ -51853,6 +51958,8 @@ characters.data={
description="LEFTWARDS DOUBLE ARROW WITH STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nLeftarrow",
specials={ "char", 0x21D0, 0x0338 },
unicodeslot=0x21CD,
},
@@ -51861,6 +51968,8 @@ characters.data={
description="LEFT RIGHT DOUBLE ARROW WITH STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nLeftrightarrow",
specials={ "char", 0x21D4, 0x0338 },
unicodeslot=0x21CE,
},
@@ -51869,6 +51978,8 @@ characters.data={
description="RIGHTWARDS DOUBLE ARROW WITH STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nRightarrow",
specials={ "char", 0x21D2, 0x0338 },
unicodeslot=0x21CF,
},
@@ -51888,6 +51999,8 @@ characters.data={
description="UPWARDS DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Uparrow",
unicodeslot=0x21D1,
},
[0x21D2]={
@@ -51907,6 +52020,8 @@ characters.data={
description="DOWNWARDS DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Downarrow",
unicodeslot=0x21D3,
},
[0x21D4]={
@@ -51925,6 +52040,8 @@ characters.data={
description="UP DOWN DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Updownarrow",
unicodeslot=0x21D5,
},
[0x21D6]={
@@ -51932,6 +52049,8 @@ characters.data={
description="NORTH WEST DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Nwarrow",
unicodeslot=0x21D6,
},
[0x21D7]={
@@ -51939,6 +52058,8 @@ characters.data={
description="NORTH EAST DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Nearrow",
unicodeslot=0x21D7,
},
[0x21D8]={
@@ -51946,6 +52067,8 @@ characters.data={
description="SOUTH EAST DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Searrow",
unicodeslot=0x21D8,
},
[0x21D9]={
@@ -51953,6 +52076,8 @@ characters.data={
description="SOUTH WEST DOUBLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Swarrow",
unicodeslot=0x21D9,
},
[0x21DA]={
@@ -51960,6 +52085,8 @@ characters.data={
description="LEFTWARDS TRIPLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Lleftarrow",
unicodeslot=0x21DA,
},
[0x21DB]={
@@ -51967,6 +52094,8 @@ characters.data={
description="RIGHTWARDS TRIPLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Rrightarrow",
unicodeslot=0x21DB,
},
[0x21DC]={
@@ -51974,6 +52103,8 @@ characters.data={
description="LEFTWARDS SQUIGGLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftsquigarrow",
unicodeslot=0x21DC,
},
[0x21DD]={
@@ -51981,6 +52112,10 @@ characters.data={
description="RIGHTWARDS SQUIGGLE ARROW",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation",name="rightsquigarrow" },
+ { class="relation",name="leadsto" },
+ },
unicodeslot=0x21DD,
},
[0x21DE]={
@@ -52002,6 +52137,8 @@ characters.data={
description="LEFTWARDS DASHED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dashleftarrow",
unicodeslot=0x21E0,
},
[0x21E1]={
@@ -52009,6 +52146,8 @@ characters.data={
description="UPWARDS DASHED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dashuparrow",
unicodeslot=0x21E1,
},
[0x21E2]={
@@ -52016,6 +52155,10 @@ characters.data={
description="RIGHTWARDS DASHED ARROW",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation", name="dashrightarrow" } ,
+ { class="relation", name="dasharrow" } ,
+ },
unicodeslot=0x21E2,
},
[0x21E3]={
@@ -52023,6 +52166,8 @@ characters.data={
description="DOWNWARDS DASHED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dashdownarrow",
unicodeslot=0x21E3,
},
[0x21E4]={
@@ -52206,6 +52351,8 @@ characters.data={
description="LEFTWARDS OPEN-HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftarrowtriangle",
unicodeslot=0x21FD,
},
[0x21FE]={
@@ -52213,6 +52360,8 @@ characters.data={
description="RIGHTWARDS OPEN-HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rightarrowtriangle",
unicodeslot=0x21FE,
},
[0x21FF]={
@@ -52220,6 +52369,8 @@ characters.data={
description="LEFT RIGHT OPEN-HEADED ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leftrightarrowtriangle",
unicodeslot=0x21FF,
},
[0x2200]={
@@ -52238,6 +52389,8 @@ characters.data={
description="COMPLEMENT",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="complement",
unicodeslot=0x2201,
},
[0x2202]={
@@ -52247,7 +52400,7 @@ characters.data={
description="PARTIAL DIFFERENTIAL",
direction="on",
linebreak="ai",
- mathclass="variable",
+ mathclass="default",
mathname="partial",
unicodeslot=0x2202,
},
@@ -52267,6 +52420,8 @@ characters.data={
description="THERE DOES NOT EXIST",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="nexists",
specials={ "char", 0x2203, 0x0338 },
unicodeslot=0x2204,
},
@@ -52276,7 +52431,7 @@ characters.data={
description="EMPTY SET",
direction="on",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="emptyset",
unicodeslot=0x2205,
},
@@ -52295,8 +52450,6 @@ characters.data={
description="NABLA",
direction="on",
linebreak="ai",
- mathclass="variable",
- mathname="nabla",
unicodeslot=0x2207,
},
[0x2208]={
@@ -52307,7 +52460,7 @@ characters.data={
direction="on",
linebreak="ai",
mathclass="relation",
- mathname=false, -- in
+ mathname="in",
mirror=0x220B,
unicodeslot=0x2208,
},
@@ -52317,9 +52470,9 @@ characters.data={
description="NOT AN ELEMENT OF",
direction="on",
linebreak="al",
- mathclass="relation",
- mathname="ni",
mirror=0x220C,
+ mathclass="relation",
+ mathname="nin",
specials={ "char", 0x2208, 0x0338 },
unicodeslot=0x2209,
},
@@ -52338,6 +52491,10 @@ characters.data={
description="CONTAINS AS MEMBER",
direction="on",
linebreak="ai",
+ mathspec={
+ { class="relation", name="ni" },
+ { class="relation", name="owns" },
+ },
mirror=0x2208,
unicodeslot=0x220B,
},
@@ -52348,6 +52505,10 @@ characters.data={
linebreak="al",
mirror=0x2209,
specials={ "char", 0x220B, 0x0338 },
+ mathspec={
+ { class="relation", name="nni" },
+ { class="relation", name="nowns" },
+ },
unicodeslot=0x220C,
},
[0x220D]={
@@ -52376,12 +52537,12 @@ characters.data={
mathname="prod",
unicodeslot=0x220F,
},
- [0x2210]={
+[0x2210]={
category="sm",
description="N-ARY COPRODUCT",
direction="on",
linebreak="al",
- mathclass="relation",
+ mathclass="limop",
mathname="coprod",
unicodeslot=0x2210,
},
@@ -52419,6 +52580,8 @@ characters.data={
description="DOT PLUS",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="dotplus",
unicodeslot=0x2214,
},
[0x2215]={
@@ -52427,16 +52590,22 @@ characters.data={
description="DIVISION SLASH",
direction="on",
linebreak="ai",
+ --~ mathclass="ord",
+ --~ mathname="diagup",
mirror=0x29F5,
unicodeslot=0x2215,
},
+ -- AM: diagup and diagdown are mapped to 2215 and 2216 by Tralics,
+ -- but ams uses different symbols for setminus and diagdown.
[0x2216]={
category="sm",
description="SET MINUS",
direction="on",
linebreak="al",
- mathclass="binary",
- mathname="setminus",
+ mathspec={
+ { class="binary", name="setminus" },
+ --~ { class="ord", name="diagdown" },
+ },
unicodeslot=0x2216,
},
[0x2217]={
@@ -52474,6 +52643,8 @@ characters.data={
description="SQUARE ROOT",
direction="on",
linebreak="ai",
+ mathclass="radical",
+ mathname="surd",
unicodeslot=0x221A,
},
[0x221B]={
@@ -52508,7 +52679,7 @@ characters.data={
description="INFINITY",
direction="on",
linebreak="ai",
- mathclass="variable",
+ mathclass="default",
mathname="infty",
unicodeslot=0x221E,
},
@@ -52518,6 +52689,8 @@ characters.data={
cjkwd="a",
description="RIGHT ANGLE",
direction="on",
+ mathclass="ord",
+ mathname="rightangle",
linebreak="ai",
unicodeslot=0x221F,
},
@@ -52556,6 +52729,8 @@ characters.data={
description="DIVIDES",
direction="on",
linebreak="ai",
+ mathclass="binary",
+ mathname="divides",
unicodeslot=0x2223,
},
[0x2224]={
@@ -52564,6 +52739,10 @@ characters.data={
direction="on",
linebreak="al",
specials={ "char", 0x2223, 0x0338 },
+ mathspec={
+ { class="binary", name="ndivides", },
+ { class="relation", name="nmid", },
+ },
unicodeslot=0x2224,
},
[0x2225]={
@@ -52572,8 +52751,13 @@ characters.data={
description="PARALLEL TO",
direction="on",
linebreak="ai",
- mathclass="relation",
- mathname="parallel",
+ mathspec={
+ { class="relation", name="parallel" },
+ { class="delimiter", name="Vert" },
+ { class="nothing", name="Arrowvert" },
+ { class="open", name="lVert" },
+ { class="close", name="rVert" },
+ },
unicodeslot=0x2225,
},
[0x2226]={
@@ -52581,6 +52765,8 @@ characters.data={
description="NOT PARALLEL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nparallel",
specials={ "char", 0x2225, 0x0338 },
unicodeslot=0x2226,
},
@@ -52591,8 +52777,10 @@ characters.data={
description="LOGICAL AND",
direction="on",
linebreak="ai",
- mathclass="limop",
- mathname="wedge",
+ mathspec={
+ { class="binary", name="wedge" },
+ { class="binary", name="land" },
+ },
unicodeslot=0x2227,
},
[0x2228]={
@@ -52602,8 +52790,10 @@ characters.data={
description="LOGICAL OR",
direction="on",
linebreak="ai",
- mathclass="limop",
- mathname="vee",
+ mathspec={
+ { class="bin",name="vee" },
+ { class="bin",name="lor" },
+ },
unicodeslot=0x2228,
},
[0x2229]={
@@ -52613,7 +52803,7 @@ characters.data={
description="INTERSECTION",
direction="on",
linebreak="ai",
- mathclass="limop",
+ mathclass="binary",
mathname="cap",
unicodeslot=0x2229,
},
@@ -52624,7 +52814,7 @@ characters.data={
description="UNION",
direction="on",
linebreak="ai",
- mathclass="limop",
+ mathclass="binary",
mathname="cup",
unicodeslot=0x222A,
},
@@ -52635,8 +52825,10 @@ characters.data={
description="INTEGRAL",
direction="on",
linebreak="ai",
- mathclass="limop",
- mathname="intop",
+ mathspec={
+ { class="nothing", name="intop" },
+ { class="limop" , name="int" },
+ },
unicodeslot=0x222B,
},
[0x222C]={
@@ -52646,6 +52838,10 @@ characters.data={
direction="on",
linebreak="ai",
specials={ "compat", 0x222B, 0x222B },
+ mathspec={
+ { class="nothing", name="iintop" },
+ { class="limop" , name="iint" },
+ },
unicodeslot=0x222C,
},
[0x222D]={
@@ -52654,6 +52850,10 @@ characters.data={
direction="on",
linebreak="al",
specials={ "compat", 0x222B, 0x222B, 0x222B },
+ mathspec={
+ { class="nothing", name="iiintop" },
+ { class="limop" , name="iiint" },
+ },
unicodeslot=0x222D,
},
[0x222E]={
@@ -52662,6 +52862,8 @@ characters.data={
description="CONTOUR INTEGRAL",
direction="on",
linebreak="ai",
+ mathclass="limop",
+ mathname="oint",
unicodeslot=0x222E,
},
[0x222F]={
@@ -52669,6 +52871,8 @@ characters.data={
description="SURFACE INTEGRAL",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="oiint",
specials={ "compat", 0x222E, 0x222E },
unicodeslot=0x222F,
},
@@ -52677,6 +52881,8 @@ characters.data={
description="VOLUME INTEGRAL",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="oiiint",
specials={ "compat", 0x222E, 0x222E, 0x222E },
unicodeslot=0x2230,
},
@@ -52685,6 +52891,8 @@ characters.data={
description="CLOCKWISE INTEGRAL",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="intclockwise",
unicodeslot=0x2231,
},
[0x2232]={
@@ -52692,6 +52900,8 @@ characters.data={
description="CLOCKWISE CONTOUR INTEGRAL",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="ointclockwise",
unicodeslot=0x2232,
},
[0x2233]={
@@ -52699,6 +52909,8 @@ characters.data={
description="ANTICLOCKWISE CONTOUR INTEGRAL",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="ointctrclockwise",
unicodeslot=0x2233,
},
[0x2234]={
@@ -52708,6 +52920,8 @@ characters.data={
description="THEREFORE",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="therefore",
unicodeslot=0x2234,
},
[0x2235]={
@@ -52716,6 +52930,8 @@ characters.data={
description="BECAUSE",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="because",
unicodeslot=0x2235,
},
[0x2236]={
@@ -52734,6 +52950,8 @@ characters.data={
description="PROPORTION",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="squaredots",
unicodeslot=0x2237,
},
[0x2238]={
@@ -52741,6 +52959,8 @@ characters.data={
description="DOT MINUS",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="dotminus",
unicodeslot=0x2238,
},
[0x2239]={
@@ -52748,6 +52968,8 @@ characters.data={
description="EXCESS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="minuscolon",
unicodeslot=0x2239,
},
[0x223A]={
@@ -52782,6 +53004,8 @@ characters.data={
description="REVERSED TILDE",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="backsim",
mirror=0x223C,
unicodeslot=0x223D,
},
@@ -52804,6 +53028,8 @@ characters.data={
description="WREATH PRODUCT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="wr",
unicodeslot=0x2240,
},
[0x2241]={
@@ -52811,6 +53037,8 @@ characters.data={
description="NOT TILDE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nsim",
specials={ "char", 0x223C, 0x0338 },
unicodeslot=0x2241,
},
@@ -52819,6 +53047,8 @@ characters.data={
description="MINUS TILDE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="eqsim",
unicodeslot=0x2242,
},
[0x2243]={
@@ -52837,6 +53067,8 @@ characters.data={
direction="on",
linebreak="al",
specials={ "char", 0x2243, 0x0338 },
+ mathclass="relation",
+ mathname="nsimeq",
unicodeslot=0x2244,
},
[0x2245]={
@@ -52845,8 +53077,10 @@ characters.data={
description="APPROXIMATELY EQUAL TO",
direction="on",
linebreak="al",
- mathclass="relation",
- mathname="approxeq",
+ mathspec={
+ { class="relation", name="approxEq"},
+ { class="relation", name="cong"},
+ },
unicodeslot=0x2245,
},
[0x2246]={
@@ -52854,6 +53088,10 @@ characters.data={
description="APPROXIMATELY BUT NOT ACTUALLY EQUAL TO",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation", name="napproxEq"},
+ { class="relation", name="ncong"},
+ },
unicodeslot=0x2246,
},
[0x2247]={
@@ -52861,6 +53099,8 @@ characters.data={
description="NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="approxnEq",
specials={ "char", 0x2245, 0x0338 },
unicodeslot=0x2247,
},
@@ -52880,6 +53120,8 @@ characters.data={
description="NOT ALMOST EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="napprox",
specials={ "char", 0x2248, 0x0338 },
unicodeslot=0x2249,
},
@@ -52887,6 +53129,8 @@ characters.data={
category="sm",
description="ALMOST EQUAL OR EQUAL TO",
direction="on",
+ mathclass="relation",
+ mathname="approxeq",
linebreak="al",
unicodeslot=0x224A,
},
@@ -52904,7 +53148,6 @@ characters.data={
direction="on",
linebreak="ai",
mathclass="relation",
- mathname="equiv",
unicodeslot=0x224C,
},
[0x224D]={
@@ -52912,6 +53155,8 @@ characters.data={
description="EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="asymp",
unicodeslot=0x224D,
},
[0x224E]={
@@ -52919,6 +53164,8 @@ characters.data={
description="GEOMETRICALLY EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Bumpeq",
unicodeslot=0x224E,
},
[0x224F]={
@@ -52940,6 +53187,10 @@ characters.data={
description="GEOMETRICALLY EQUAL TO",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation", name="doteqdot" },
+ { class="relation", name="Doteq" },
+ },
unicodeslot=0x2251,
},
[0x2252]={
@@ -52949,6 +53200,8 @@ characters.data={
direction="on",
linebreak="ai",
mirror=0x2253,
+ mathclass="relation",
+ mathname="fallingdotseq",
unicodeslot=0x2252,
},
[0x2253]={
@@ -52957,6 +53210,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x2252,
+ mathclass="relation",
+ mathname="risingdotseq",
unicodeslot=0x2253,
},
[0x2254]={
@@ -52965,6 +53220,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x2255,
+ mathclass="relation",
+ mathname="colonequals",
unicodeslot=0x2254,
},
[0x2255]={
@@ -52973,6 +53230,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x2254,
+ mathclass="relation",
+ mathname="equalscolon",
unicodeslot=0x2255,
},
[0x2256]={
@@ -52980,6 +53239,8 @@ characters.data={
description="RING IN EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="eqcirc",
unicodeslot=0x2256,
},
[0x2257]={
@@ -52987,6 +53248,8 @@ characters.data={
description="RING EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="circeq",
unicodeslot=0x2257,
},
[0x2258]={
@@ -53004,13 +53267,15 @@ characters.data={
linebreak="al",
unicodeslot=0x2259,
mathclass="relation",
- mathname="wedgeq",
+ mathname="wedgeeq",
},
[0x225A]={
category="sm",
description="EQUIANGULAR TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="veeeq",
unicodeslot=0x225A,
},
[0x225B]={
@@ -53018,6 +53283,8 @@ characters.data={
description="STAR EQUALS",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="stareq",
unicodeslot=0x225B,
},
[0x225C]={
@@ -53034,6 +53301,8 @@ characters.data={
description="EQUAL TO BY DEFINITION",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="definedeq",
unicodeslot=0x225D,
},
[0x225E]={
@@ -53041,6 +53310,8 @@ characters.data={
description="MEASURED BY",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="measuredeq",
unicodeslot=0x225E,
},
[0x225F]={
@@ -53048,6 +53319,8 @@ characters.data={
description="QUESTIONED EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="questionedeq",
unicodeslot=0x225F,
},
[0x2260]={
@@ -53056,10 +53329,11 @@ characters.data={
cjkwd="a",
description="NOT EQUAL TO",
direction="on",
- fallback=[[\not=]],
linebreak="ai",
- mathclass="relation",
- mathname="neq",
+ mathspec={
+ { class="relation", name="neq" },
+ { class="relation", name="ne" },
+ },
specials={ "char", 0x003D, 0x0338 },
unicodeslot=0x2260,
},
@@ -53079,6 +53353,8 @@ characters.data={
description="NOT IDENTICAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nequiv",
specials={ "char", 0x2261, 0x0338 },
unicodeslot=0x2262,
},
@@ -53096,8 +53372,10 @@ characters.data={
description="LESS-THAN OR EQUAL TO",
direction="on",
linebreak="ai",
- mathclass="relation",
- mathname="leq",
+ mathspec={
+ { class="relation", name="leq" },
+ { class="relation", name="le" },
+ },
mirror=0x2265,
unicodeslot=0x2264,
},
@@ -53108,8 +53386,10 @@ characters.data={
description="GREATER-THAN OR EQUAL TO",
direction="on",
linebreak="ai",
- mathclass="relation",
- mathname="geq",
+ mathspec={
+ { class="relation", name="geq" },
+ { class="relation", name="ge" },
+ },
mirror=0x2264,
unicodeslot=0x2265,
},
@@ -53119,6 +53399,8 @@ characters.data={
description="LESS-THAN OVER EQUAL TO",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="leqq",
mirror=0x2267,
unicodeslot=0x2266,
},
@@ -53128,6 +53410,8 @@ characters.data={
description="GREATER-THAN OVER EQUAL TO",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="geqq",
mirror=0x2266,
unicodeslot=0x2267,
},
@@ -53136,6 +53420,8 @@ characters.data={
description="LESS-THAN BUT NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lneqq",
mirror=0x2269,
unicodeslot=0x2268,
},
@@ -53144,6 +53430,8 @@ characters.data={
description="GREATER-THAN BUT NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gneqq",
mirror=0x2268,
unicodeslot=0x2269,
},
@@ -53174,6 +53462,8 @@ characters.data={
description="BETWEEN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="between",
unicodeslot=0x226C,
},
[0x226D]={
@@ -53181,6 +53471,8 @@ characters.data={
description="NOT EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nasymp",
specials={ "char", 0x224D, 0x0338 },
unicodeslot=0x226D,
},
@@ -53190,6 +53482,8 @@ characters.data={
description="NOT LESS-THAN",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="nless",
mirror=0x226F,
specials={ "char", 0x003C, 0x0338 },
unicodeslot=0x226E,
@@ -53200,6 +53494,8 @@ characters.data={
description="NOT GREATER-THAN",
direction="on",
linebreak="ai",
+ mathclass="relation",
+ mathname="ngtr",
mirror=0x226E,
specials={ "char", 0x003E, 0x0338 },
unicodeslot=0x226F,
@@ -53209,6 +53505,8 @@ characters.data={
description="NEITHER LESS-THAN NOR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nleq",
mirror=0x2271,
specials={ "char", 0x2264, 0x0338 },
unicodeslot=0x2270,
@@ -53218,6 +53516,8 @@ characters.data={
description="NEITHER GREATER-THAN NOR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ngeq",
mirror=0x2270,
specials={ "char", 0x2265, 0x0338 },
unicodeslot=0x2271,
@@ -53227,6 +53527,8 @@ characters.data={
description="LESS-THAN OR EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lesssim",
mirror=0x2273,
unicodeslot=0x2272,
},
@@ -53235,6 +53537,8 @@ characters.data={
description="GREATER-THAN OR EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gtrsim",
mirror=0x2272,
unicodeslot=0x2273,
},
@@ -53243,6 +53547,8 @@ characters.data={
description="NEITHER LESS-THAN NOR EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nlesssim",
mirror=0x2275,
specials={ "char", 0x2272, 0x0338 },
unicodeslot=0x2274,
@@ -53252,6 +53558,8 @@ characters.data={
description="NEITHER GREATER-THAN NOR EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ngtrsim",
mirror=0x2274,
specials={ "char", 0x2273, 0x0338 },
unicodeslot=0x2275,
@@ -53261,6 +53569,8 @@ characters.data={
description="LESS-THAN OR GREATER-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lessgtr",
mirror=0x2277,
unicodeslot=0x2276,
},
@@ -53269,6 +53579,8 @@ characters.data={
description="GREATER-THAN OR LESS-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gtrless",
mirror=0x2276,
unicodeslot=0x2277,
},
@@ -53277,6 +53589,8 @@ characters.data={
description="NEITHER LESS-THAN NOR GREATER-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nlessgtr",
mirror=0x2279,
specials={ "char", 0x2276, 0x0338 },
unicodeslot=0x2278,
@@ -53286,6 +53600,8 @@ characters.data={
description="NEITHER GREATER-THAN NOR LESS-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ngtrless",
mirror=0x2278,
specials={ "char", 0x2277, 0x0338 },
unicodeslot=0x2279,
@@ -53315,6 +53631,8 @@ characters.data={
description="PRECEDES OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="preccurlyeq",
mirror=0x227D,
unicodeslot=0x227C,
},
@@ -53323,6 +53641,8 @@ characters.data={
description="SUCCEEDS OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succcurlyeq",
mirror=0x227C,
unicodeslot=0x227D,
},
@@ -53331,6 +53651,8 @@ characters.data={
description="PRECEDES OR EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="precsim",
mirror=0x227F,
unicodeslot=0x227E,
},
@@ -53339,6 +53661,8 @@ characters.data={
description="SUCCEEDS OR EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succsim",
mirror=0x227E,
unicodeslot=0x227F,
},
@@ -53347,6 +53671,8 @@ characters.data={
description="DOES NOT PRECEDE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nprec",
mirror=0x2281,
specials={ "char", 0x227A, 0x0338 },
unicodeslot=0x2280,
@@ -53356,6 +53682,8 @@ characters.data={
description="DOES NOT SUCCEED",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nsucc",
mirror=0x2280,
specials={ "char", 0x227B, 0x0338 },
unicodeslot=0x2281,
@@ -53368,7 +53696,7 @@ characters.data={
direction="on",
linebreak="ai",
mathclass="relation",
- mathname="subset",
+ mathname="subset", -- Subset
mirror=0x2283,
unicodeslot=0x2282,
},
@@ -53390,7 +53718,8 @@ characters.data={
description="NOT A SUBSET OF",
direction="on",
fallback=[[\not\subset]],
--- mathclass="relation",
+ mathclass="relation",
+ mathname="nsubset",
linebreak="al",
mirror=0x2285,
specials={ "char", 0x2282, 0x0338 },
@@ -53403,6 +53732,7 @@ characters.data={
fallback=[[\not\supset]],
linebreak="al",
mathclass="relation",
+ mathname="nsupset",
mirror=0x2284,
specials={ "char", 0x2283, 0x0338 },
unicodeslot=0x2285,
@@ -53436,6 +53766,8 @@ characters.data={
description="NEITHER A SUBSET OF NOR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nsubseteq",
mirror=0x2289,
specials={ "char", 0x2286, 0x0338 },
unicodeslot=0x2288,
@@ -53445,6 +53777,8 @@ characters.data={
description="NEITHER A SUPERSET OF NOR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nsupseteq",
mirror=0x2288,
specials={ "char", 0x2287, 0x0338 },
unicodeslot=0x2289,
@@ -53454,6 +53788,8 @@ characters.data={
description="SUBSET OF WITH NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="subsetneq",
mirror=0x228B,
unicodeslot=0x228A,
},
@@ -53462,6 +53798,8 @@ characters.data={
description="SUPERSET OF WITH NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="supsetneq",
mirror=0x228A,
unicodeslot=0x228B,
},
@@ -53484,6 +53822,8 @@ characters.data={
description="MULTISET UNION",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="uplus",
unicodeslot=0x228E,
},
[0x228F]={
@@ -53491,6 +53831,8 @@ characters.data={
description="SQUARE IMAGE OF",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="sqsubset",
mirror=0x2290,
unicodeslot=0x228F,
},
@@ -53499,6 +53841,8 @@ characters.data={
description="SQUARE ORIGINAL OF",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="sqsupset",
mirror=0x228F,
unicodeslot=0x2290,
},
@@ -53507,6 +53851,8 @@ characters.data={
description="SQUARE IMAGE OF OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="sqsubseteq",
mirror=0x2292,
unicodeslot=0x2291,
},
@@ -53515,6 +53861,8 @@ characters.data={
description="SQUARE ORIGINAL OF OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="sqsupseteq",
mirror=0x2291,
unicodeslot=0x2292,
},
@@ -53523,7 +53871,7 @@ characters.data={
description="SQUARE CAP",
direction="on",
linebreak="al",
- mathclass="relation",
+ mathclass="binary",
mathname="sqcap",
unicodeslot=0x2293,
},
@@ -53532,7 +53880,7 @@ characters.data={
description="SQUARE CUP",
direction="on",
linebreak="al",
- mathclass="relation",
+ mathclass="binary",
mathname="sqcup",
unicodeslot=0x2294,
},
@@ -53591,6 +53939,8 @@ characters.data={
description="CIRCLED RING OPERATOR",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="circledcirc",
unicodeslot=0x229A,
},
[0x229B]={
@@ -53598,6 +53948,8 @@ characters.data={
description="CIRCLED ASTERISK OPERATOR",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="circledast",
unicodeslot=0x229B,
},
[0x229C]={
@@ -53605,6 +53957,8 @@ characters.data={
description="CIRCLED EQUALS",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="circledequals",
unicodeslot=0x229C,
},
[0x229D]={
@@ -53612,6 +53966,8 @@ characters.data={
description="CIRCLED DASH",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="circleddash",
unicodeslot=0x229D,
},
[0x229E]={
@@ -53619,6 +53975,8 @@ characters.data={
description="SQUARED PLUS",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="boxplus",
unicodeslot=0x229E,
},
[0x229F]={
@@ -53626,6 +53984,8 @@ characters.data={
description="SQUARED MINUS",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="boxminus",
unicodeslot=0x229F,
},
[0x22A0]={
@@ -53633,6 +53993,8 @@ characters.data={
description="SQUARED TIMES",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="boxtimes",
unicodeslot=0x22A0,
},
[0x22A1]={
@@ -53640,6 +54002,8 @@ characters.data={
description="SQUARED DOT OPERATOR",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="boxdot",
unicodeslot=0x22A1,
},
[0x22A2]={
@@ -53647,6 +54011,8 @@ characters.data={
description="RIGHT TACK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="vdash",
mirror=0x22A3,
unicodeslot=0x22A2,
},
@@ -53655,6 +54021,8 @@ characters.data={
description="LEFT TACK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dashv",
mirror=0x22A2,
unicodeslot=0x22A3,
},
@@ -53663,8 +54031,8 @@ characters.data={
description="DOWN TACK",
direction="on",
linebreak="al",
- mathclass="variable",
- mathname="bot",
+ mathclass="default",
+ mathname="top",
unicodeslot=0x22A4,
},
[0x22A5]={
@@ -53674,8 +54042,10 @@ characters.data={
description="UP TACK",
direction="on",
linebreak="ai",
- mathclass="variable",
- mathname="top",
+ mathspec={
+ { class="default", name="bot" },
+ { class="relation", name="perp" },
+ },
unicodeslot=0x22A5,
},
[0x22A6]={
@@ -53691,6 +54061,9 @@ characters.data={
description="MODELS",
direction="on",
linebreak="al",
+ fallback=[[\mathrel|\joinrel=]],
+ mathclass="relation",
+ mathname="models",
unicodeslot=0x22A7,
},
[0x22A8]={
@@ -53699,6 +54072,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x2AE4,
+ mathclass="relation",
+ mathname="vDash",
unicodeslot=0x22A8,
},
[0x22A9]={
@@ -53707,6 +54082,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x2AE3,
+ mathclass="relation",
+ mathname="Vdash",
unicodeslot=0x22A9,
},
[0x22AA]={
@@ -53714,6 +54091,8 @@ characters.data={
description="TRIPLE VERTICAL BAR RIGHT TURNSTILE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Vvdash",
unicodeslot=0x22AA,
},
[0x22AB]={
@@ -53722,6 +54101,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x2AE5,
+ mathclass="relation",
+ mathname="VDash",
unicodeslot=0x22AB,
},
[0x22AC]={
@@ -53729,6 +54110,8 @@ characters.data={
description="DOES NOT PROVE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nvdash",
specials={ "char", 0x22A2, 0x0338 },
unicodeslot=0x22AC,
},
@@ -53737,6 +54120,8 @@ characters.data={
description="NOT TRUE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nvDash",
specials={ "char", 0x22A8, 0x0338 },
unicodeslot=0x22AD,
},
@@ -53745,6 +54130,8 @@ characters.data={
description="DOES NOT FORCE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nVdash",
specials={ "char", 0x22A9, 0x0338 },
unicodeslot=0x22AE,
},
@@ -53753,6 +54140,8 @@ characters.data={
description="NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nVDash",
specials={ "char", 0x22AB, 0x0338 },
unicodeslot=0x22AF,
},
@@ -53777,6 +54166,8 @@ characters.data={
description="NORMAL SUBGROUP OF",
direction="on",
linebreak="al",
+ mathclass="bin",
+ mathname="triangleleft",
mirror=0x22B3,
unicodeslot=0x22B2,
},
@@ -53785,6 +54176,8 @@ characters.data={
description="CONTAINS AS NORMAL SUBGROUP",
direction="on",
linebreak="al",
+ mathclass="bin",
+ mathname="triangleright",
mirror=0x22B2,
unicodeslot=0x22B3,
},
@@ -53825,6 +54218,8 @@ characters.data={
description="MULTIMAP",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="multimap",
unicodeslot=0x22B8,
},
[0x22B9]={
@@ -53839,6 +54234,8 @@ characters.data={
description="INTERCALATE",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="intercal",
unicodeslot=0x22BA,
},
[0x22BB]={
@@ -53846,6 +54243,8 @@ characters.data={
description="XOR",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="veebar",
unicodeslot=0x22BB,
},
[0x22BC]={
@@ -53853,6 +54252,8 @@ characters.data={
description="NAND",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="barwedge",
unicodeslot=0x22BC,
},
[0x22BD]={
@@ -53928,8 +54329,10 @@ characters.data={
description="DOT OPERATOR",
direction="on",
linebreak="al",
- mathclass="binary",
- mathname="cdot",
+ mathspec={
+ { class="binary", name="cdot" },
+ { class="punctuation", name="cdotp" },
+ },
unicodeslot=0x22C5,
},
[0x22C6]={
@@ -53946,6 +54349,8 @@ characters.data={
description="DIVISION TIMES",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="divideontimes",
unicodeslot=0x22C7,
},
[0x22C8]={
@@ -53953,6 +54358,11 @@ characters.data={
description="BOWTIE",
direction="on",
linebreak="al",
+ fallback=[[\mathrel\triangleright\joinrel\mathrel\triangleleft]],
+ mathspec={
+ { class="relation", name="bowtie" },
+ { class="relation", name="Join" }, -- AM: Maybe wrong
+ },
unicodeslot=0x22C8,
},
[0x22C9]={
@@ -53960,6 +54370,8 @@ characters.data={
description="LEFT NORMAL FACTOR SEMIDIRECT PRODUCT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="ltimes",
mirror=0x22CA,
unicodeslot=0x22C9,
},
@@ -53968,6 +54380,8 @@ characters.data={
description="RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="rtimes",
mirror=0x22C9,
unicodeslot=0x22CA,
},
@@ -53976,6 +54390,8 @@ characters.data={
description="LEFT SEMIDIRECT PRODUCT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="leftthreetimes",
mirror=0x22CC,
unicodeslot=0x22CB,
},
@@ -53984,6 +54400,8 @@ characters.data={
description="RIGHT SEMIDIRECT PRODUCT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="rightthreetimes",
mirror=0x22CB,
unicodeslot=0x22CC,
},
@@ -54000,6 +54418,8 @@ characters.data={
description="CURLY LOGICAL OR",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="curlyvee",
unicodeslot=0x22CE,
},
[0x22CF]={
@@ -54007,6 +54427,8 @@ characters.data={
description="CURLY LOGICAL AND",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="curlywedge",
unicodeslot=0x22CF,
},
[0x22D0]={
@@ -54014,6 +54436,8 @@ characters.data={
description="DOUBLE SUBSET",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Subset",
mirror=0x22D1,
unicodeslot=0x22D0,
},
@@ -54022,6 +54446,8 @@ characters.data={
description="DOUBLE SUPERSET",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Supset",
mirror=0x22D0,
unicodeslot=0x22D1,
},
@@ -54030,6 +54456,10 @@ characters.data={
description="DOUBLE INTERSECTION",
direction="on",
linebreak="al",
+ mathspec={
+ { class="binary", name="Cap" },
+ { class="binary", name="doublecap"},
+ },
unicodeslot=0x22D2,
},
[0x22D3]={
@@ -54037,6 +54467,10 @@ characters.data={
description="DOUBLE UNION",
direction="on",
linebreak="al",
+ mathspec={
+ { class="binary", name="Cup" },
+ { class="binary", name="doublecup"},
+ },
unicodeslot=0x22D3,
},
[0x22D4]={
@@ -54044,6 +54478,8 @@ characters.data={
description="PITCHFORK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="pitchfork",
unicodeslot=0x22D4,
},
[0x22D5]={
@@ -54058,6 +54494,8 @@ characters.data={
description="LESS-THAN WITH DOT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="lessdot",
mirror=0x22D7,
unicodeslot=0x22D6,
},
@@ -54066,6 +54504,8 @@ characters.data={
description="GREATER-THAN WITH DOT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="gtrdot",
mirror=0x22D6,
unicodeslot=0x22D7,
},
@@ -54074,6 +54514,10 @@ characters.data={
description="VERY MUCH LESS-THAN",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation", name="lll"},
+ { class="relation", name="llless"},
+ },
mirror=0x22D9,
unicodeslot=0x22D8,
},
@@ -54082,6 +54526,10 @@ characters.data={
description="VERY MUCH GREATER-THAN",
direction="on",
linebreak="al",
+ mathspec={
+ { class="relation", name="ggg"},
+ { class="relation", name="gggtr"},
+ },
mirror=0x22D8,
unicodeslot=0x22D9,
},
@@ -54091,6 +54539,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x22DB,
+ mathclass="relation",
+ mathname="lesseqgtr",
unicodeslot=0x22DA,
},
[0x22DB]={
@@ -54099,6 +54549,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x22DA,
+ mathclass="relation",
+ mathname="gtreqless",
unicodeslot=0x22DB,
},
[0x22DC]={
@@ -54106,6 +54558,8 @@ characters.data={
description="EQUAL TO OR LESS-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="eqless",
mirror=0x22DD,
unicodeslot=0x22DC,
},
@@ -54114,6 +54568,8 @@ characters.data={
description="EQUAL TO OR GREATER-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="eqgtr",
mirror=0x22DC,
unicodeslot=0x22DD,
},
@@ -54123,6 +54579,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x22DF,
+ mathclass="relation",
+ mathname="curlyeqprec",
unicodeslot=0x22DE,
},
[0x22DF]={
@@ -54131,6 +54589,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x22DE,
+ mathclass="relation",
+ mathname="curlyeqsucc",
unicodeslot=0x22DF,
},
[0x22E0]={
@@ -54139,6 +54599,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x22E1,
+ mathclass="relation",
+ mathname="npreccurlyeq",
specials={ "char", 0x227C, 0x0338 },
unicodeslot=0x22E0,
},
@@ -54148,6 +54610,8 @@ characters.data={
direction="on",
linebreak="al",
mirror=0x22E0,
+ mathclass="relation",
+ mathname="nsucccurlyeq",
specials={ "char", 0x227D, 0x0338 },
unicodeslot=0x22E1,
},
@@ -54156,6 +54620,8 @@ characters.data={
description="NOT SQUARE IMAGE OF OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nsqsubseteq",
mirror=0x22E3,
specials={ "char", 0x2291, 0x0338 },
unicodeslot=0x22E2,
@@ -54165,6 +54631,8 @@ characters.data={
description="NOT SQUARE ORIGINAL OF OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nsqsupseteq",
mirror=0x22E2,
specials={ "char", 0x2292, 0x0338 },
unicodeslot=0x22E3,
@@ -54174,6 +54642,8 @@ characters.data={
description="SQUARE IMAGE OF OR NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="sqsubsetneq",
mirror=0x22E5,
unicodeslot=0x22E4,
},
@@ -54182,6 +54652,8 @@ characters.data={
description="SQUARE ORIGINAL OF OR NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="sqsupsetneq",
mirror=0x22E4,
unicodeslot=0x22E5,
},
@@ -54190,6 +54662,8 @@ characters.data={
description="LESS-THAN BUT NOT EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lnsim",
mirror=0x22E7,
unicodeslot=0x22E6,
},
@@ -54198,6 +54672,8 @@ characters.data={
description="GREATER-THAN BUT NOT EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gnsim",
mirror=0x22E6,
unicodeslot=0x22E7,
},
@@ -54206,6 +54682,8 @@ characters.data={
description="PRECEDES BUT NOT EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="precnsim",
mirror=0x22E9,
unicodeslot=0x22E8,
},
@@ -54214,6 +54692,8 @@ characters.data={
description="SUCCEEDS BUT NOT EQUIVALENT TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succnsim",
mirror=0x22E8,
unicodeslot=0x22E9,
},
@@ -54222,6 +54702,8 @@ characters.data={
description="NOT NORMAL SUBGROUP OF",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ntriangleright",
mirror=0x22EB,
specials={ "char", 0x22B2, 0x0338 },
unicodeslot=0x22EA,
@@ -54231,6 +54713,8 @@ characters.data={
description="DOES NOT CONTAIN AS NORMAL SUBGROUP",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ntriangleleft",
mirror=0x22EA,
specials={ "char", 0x22B3, 0x0338 },
unicodeslot=0x22EB,
@@ -54240,6 +54724,8 @@ characters.data={
description="NOT NORMAL SUBGROUP OF OR EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ntrianglelefteq",
mirror=0x22ED,
specials={ "char", 0x22B4, 0x0338 },
unicodeslot=0x22EC,
@@ -54249,6 +54735,8 @@ characters.data={
description="DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="ntrianglerighteq",
mirror=0x22EC,
specials={ "char", 0x22B5, 0x0338 },
unicodeslot=0x22ED,
@@ -54258,6 +54746,8 @@ characters.data={
description="VERTICAL ELLIPSIS",
direction="on",
linebreak="al",
+ mathclass="inner",
+ mathname="vdots",
unicodeslot=0x22EE,
},
[0x22EF]={
@@ -54265,6 +54755,8 @@ characters.data={
description="MIDLINE HORIZONTAL ELLIPSIS",
direction="on",
linebreak="al",
+ mathclass="inner",
+ mathname="cdots",
unicodeslot=0x22EF,
},
[0x22F0]={
@@ -54272,6 +54764,8 @@ characters.data={
description="UP RIGHT DIAGONAL ELLIPSIS",
direction="on",
linebreak="al",
+ mathclass="inner",
+ mathname="udots",
mirror=0x22F1,
unicodeslot=0x22F0,
},
@@ -54280,6 +54774,8 @@ characters.data={
description="DOWN RIGHT DIAGONAL ELLIPSIS",
direction="on",
linebreak="al",
+ mathclass="inner",
+ mathname="ddots",
mirror=0x22F0,
unicodeslot=0x22F1,
},
@@ -54396,6 +54892,8 @@ characters.data={
description="DIAMETER SIGN",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="varnothing",
unicodeslot=0x2300,
},
[0x2301]={
@@ -54453,6 +54951,8 @@ characters.data={
description="LEFT CEILING",
direction="on",
linebreak="al",
+ mathclass="open",
+ mathname="lceil",
mirror=0x2309,
unicodeslot=0x2308,
},
@@ -54461,6 +54961,8 @@ characters.data={
description="RIGHT CEILING",
direction="on",
linebreak="al",
+ mathclass="close",
+ mathname="rceil",
mirror=0x2308,
unicodeslot=0x2309,
},
@@ -54469,6 +54971,8 @@ characters.data={
description="LEFT FLOOR",
direction="on",
linebreak="al",
+ mathclass="open",
+ mathname="lfloor",
mirror=0x230B,
unicodeslot=0x230A,
},
@@ -54477,6 +54981,8 @@ characters.data={
description="RIGHT FLOOR",
direction="on",
linebreak="al",
+ mathclass="close",
+ mathname="rfloor",
mirror=0x230A,
unicodeslot=0x230B,
},
@@ -54599,6 +55105,8 @@ characters.data={
description="TOP LEFT CORNER",
direction="on",
linebreak="al",
+ mathclass="open",
+ mathname="ulcorner",
unicodeslot=0x231C,
},
[0x231D]={
@@ -54606,6 +55114,8 @@ characters.data={
description="TOP RIGHT CORNER",
direction="on",
linebreak="al",
+ mathclass="close",
+ mathname="urcorner",
unicodeslot=0x231D,
},
[0x231E]={
@@ -54613,6 +55123,8 @@ characters.data={
description="BOTTOM LEFT CORNER",
direction="on",
linebreak="al",
+ mathclass="open",
+ mathname="llcorner",
unicodeslot=0x231E,
},
[0x231F]={
@@ -54620,6 +55132,8 @@ characters.data={
description="BOTTOM RIGHT CORNER",
direction="on",
linebreak="al",
+ mathclass="close",
+ mathname="lrcorner",
unicodeslot=0x231F,
},
[0x2320]={
@@ -54643,6 +55157,8 @@ characters.data={
description="FROWN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="frown",
unicodeslot=0x2322,
},
[0x2323]={
@@ -54650,6 +55166,8 @@ characters.data={
description="SMILE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="smile",
unicodeslot=0x2323,
},
[0x2324]={
@@ -55645,6 +56163,8 @@ characters.data={
description="UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION",
direction="on",
linebreak="al",
+ mathclass="open",
+ mathname="lmoustache",
unicodeslot=0x23B0,
},
[0x23B1]={
@@ -55652,6 +56172,8 @@ characters.data={
description="UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION",
direction="on",
linebreak="al",
+ mathclass="close",
+ mathname="rmoustache",
unicodeslot=0x23B1,
},
[0x23B2]={
@@ -55953,6 +56475,8 @@ characters.data={
description="TOP PARENTHESIS",
direction="on",
linebreak="al",
+ mathclass="topaccent",
+ mathname="overparent",
unicodeslot=0x23DC,
},
[0x23DD]={
@@ -55960,6 +56484,8 @@ characters.data={
description="BOTTOM PARENTHESIS",
direction="on",
linebreak="al",
+ mathclass="botaccent",
+ mathname="underparent",
unicodeslot=0x23DD,
},
[0x23DE]={
@@ -55967,6 +56493,8 @@ characters.data={
description="TOP CURLY BRACKET",
direction="on",
linebreak="al",
+ mathclass="topaccent",
+ mathname="overbrace",
unicodeslot=0x23DE,
},
[0x23DF]={
@@ -55974,6 +56502,8 @@ characters.data={
description="BOTTOM CURLY BRACKET",
direction="on",
linebreak="al",
+ mathclass="botaccent",
+ mathname="underbrace",
unicodeslot=0x23DF,
},
[0x23E0]={
@@ -55981,6 +56511,7 @@ characters.data={
description="TOP TORTOISE SHELL BRACKET",
direction="on",
linebreak="al",
+ mathclass="accent",
unicodeslot=0x23E0,
},
[0x23E1]={
@@ -55988,6 +56519,7 @@ characters.data={
description="BOTTOM TORTOISE SHELL BRACKET",
direction="on",
linebreak="al",
+ mathclass="accent",
unicodeslot=0x23E1,
},
[0x23E2]={
@@ -57333,6 +57865,8 @@ characters.data={
direction="l",
lccode=0x24E1,
linebreak="ai",
+ mathclass="ord",
+ mathname="circledR",
specials={ "circle", 0x0052 },
unicodeslot=0x24C7,
},
@@ -57343,6 +57877,8 @@ characters.data={
direction="l",
lccode=0x24E2,
linebreak="ai",
+ mathclass="ord",
+ mathname="circledS",
specials={ "circle", 0x0053 },
unicodeslot=0x24C8,
},
@@ -59168,6 +59704,10 @@ characters.data={
description="WHITE SQUARE",
direction="on",
linebreak="ai",
+ mathspec={
+ { class="ord", name="square" },
+ { class="ord", name="Box" },
+ },
unicodeslot=0x25A1,
},
[0x25A2]={
@@ -59175,6 +59715,8 @@ characters.data={
description="WHITE SQUARE WITH ROUNDED CORNERS",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="blacksquare",
unicodeslot=0x25A2,
},
[0x25A3]={
@@ -59307,8 +59849,10 @@ characters.data={
description="WHITE UP-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="ord",
- mathname="triangle",
+ mathspec={
+ { class="ord", name="triangle" },
+ { class="binary", name="bigtriangleup" },
+ },
unicodeslot=0x25B3,
},
[0x25B4]={
@@ -59385,6 +59929,8 @@ characters.data={
description="WHITE DOWN-POINTING TRIANGLE",
direction="on",
linebreak="ai",
+ mathclass="binary",
+ mathname="bigtriangledown",
unicodeslot=0x25BD,
},
[0x25BE]={
@@ -59483,6 +60029,8 @@ characters.data={
description="LOZENGE",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="lozenge",
unicodeslot=0x25CA,
},
[0x25CB]={
@@ -59757,6 +60305,8 @@ characters.data={
description="LARGE CIRCLE",
direction="on",
linebreak="ai",
+ mathclass="binary",
+ mathname="bigcirc",
unicodeslot=0x25EF,
},
[0x25F0]={
@@ -59912,6 +60462,8 @@ characters.data={
description="BLACK STAR",
direction="on",
linebreak="ai",
+ mathclass="ord",
+ mathname="bigstar",
unicodeslot=0x2605,
},
[0x2606]={
@@ -60566,6 +61118,8 @@ characters.data={
description="BLACK SPADE SUIT",
direction="on",
linebreak="ai",
+ mathclass="default",
+ mathname="spadesuit",
unicodeslot=0x2660,
},
[0x2661]={
@@ -60574,6 +61128,8 @@ characters.data={
description="WHITE HEART SUIT",
direction="on",
linebreak="ai",
+ mathclass="default",
+ mathname="heartsuit",
unicodeslot=0x2661,
},
[0x2662]={
@@ -60581,6 +61137,8 @@ characters.data={
description="WHITE DIAMOND SUIT",
direction="on",
linebreak="al",
+ mathclass="default",
+ mathname="diamondsuit",
unicodeslot=0x2662,
},
[0x2663]={
@@ -60590,6 +61148,8 @@ characters.data={
description="BLACK CLUB SUIT",
direction="on",
linebreak="ai",
+ mathclass="default",
+ mathname="clubsuit",
unicodeslot=0x2663,
},
[0x2664]={
@@ -60672,6 +61232,8 @@ characters.data={
description="MUSIC FLAT SIGN",
direction="on",
linebreak="ai",
+ mathclass="default",
+ mathname="flat",
unicodeslot=0x266D,
},
[0x266E]={
@@ -60679,6 +61241,8 @@ characters.data={
description="MUSIC NATURAL SIGN",
direction="on",
linebreak="al",
+ mathclass="default",
+ mathname="natural",
unicodeslot=0x266E,
},
[0x266F]={
@@ -60687,6 +61251,8 @@ characters.data={
description="MUSIC SHARP SIGN",
direction="on",
linebreak="ai",
+ mathclass="default",
+ mathname="sharp",
unicodeslot=0x266F,
},
[0x2670]={
@@ -61247,6 +61813,8 @@ characters.data={
description="CHECK MARK",
direction="on",
linebreak="al",
+ mathclass="nothing",
+ mathname="checkmark",
unicodeslot=0x2713,
},
[0x2714]={
@@ -61338,6 +61906,8 @@ characters.data={
description="MALTESE CROSS",
direction="on",
linebreak="al",
+ mathclass="nothing",
+ mathname="maltese",
unicodeslot=0x2720,
},
[0x2721]={
@@ -62631,6 +63201,8 @@ characters.data={
description="MATHEMATICAL LEFT WHITE SQUARE BRACKET",
direction="on",
linebreak="op",
+ mathclass="open",
+ mathname="llbracket",
mirror=0x27E7,
unicodeslot=0x27E6,
},
@@ -62640,6 +63212,8 @@ characters.data={
description="MATHEMATICAL RIGHT WHITE SQUARE BRACKET",
direction="on",
linebreak="cl",
+ mathclass="close",
+ mathname="rrbracket",
mirror=0x27E6,
unicodeslot=0x27E7,
},
@@ -62649,6 +63223,8 @@ characters.data={
description="MATHEMATICAL LEFT ANGLE BRACKET",
direction="on",
linebreak="op",
+ mathclass="open",
+ mathname="langle",
mirror=0x27E9,
unicodeslot=0x27E8,
},
@@ -62658,6 +63234,8 @@ characters.data={
description="MATHEMATICAL RIGHT ANGLE BRACKET",
direction="on",
linebreak="cl",
+ mathclass="close",
+ mathname="rangle",
mirror=0x27E8,
unicodeslot=0x27E9,
},
@@ -62667,6 +63245,8 @@ characters.data={
description="MATHEMATICAL LEFT DOUBLE ANGLE BRACKET",
direction="on",
linebreak="op",
+ mathclass="open",
+ mathname="llangle",
mirror=0x27EB,
unicodeslot=0x27EA,
},
@@ -62676,6 +63256,8 @@ characters.data={
description="MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET",
direction="on",
linebreak="cl",
+ mathclass="close",
+ mathname="rrangle",
mirror=0x27EA,
unicodeslot=0x27EB,
},
@@ -62719,6 +63301,9 @@ characters.data={
description="LONG LEFTWARDS ARROW",
direction="on",
linebreak="al",
+ fallback=[[\leftarrow\joinrel\relbar]],
+ mathclass="relation",
+ mathname="longleftarrow",
unicodeslot=0x27F5,
},
[0x27F6]={
@@ -62726,6 +63311,9 @@ characters.data={
description="LONG RIGHTWARDS ARROW",
direction="on",
linebreak="al",
+ fallback=[[\relbar\joinrel\rightarrow]],
+ mathclass="relation",
+ mathname="longrightarrow",
unicodeslot=0x27F6,
},
[0x27F7]={
@@ -62733,6 +63321,9 @@ characters.data={
description="LONG LEFT RIGHT ARROW",
direction="on",
linebreak="al",
+ fallback=[[\leftarrow\joinrel\rightarrow]],
+ mathclass="relation",
+ mathname="longleftrightarrow",
unicodeslot=0x27F7,
},
[0x27F8]={
@@ -62740,6 +63331,9 @@ characters.data={
description="LONG LEFTWARDS DOUBLE ARROW",
direction="on",
linebreak="al",
+ fallback=[[\Leftarrow\joinrel\Relbar]],
+ mathclass="relation",
+ mathname="Longleftarrow",
unicodeslot=0x27F8,
},
[0x27F9]={
@@ -62747,6 +63341,9 @@ characters.data={
description="LONG RIGHTWARDS DOUBLE ARROW",
direction="on",
linebreak="al",
+ fallback=[[\Relbar\joinrel\Rightarrow]],
+ mathclass="relation",
+ mathname="Longrightarrow",
unicodeslot=0x27F9,
},
[0x27FA]={
@@ -62754,6 +63351,9 @@ characters.data={
description="LONG LEFT RIGHT DOUBLE ARROW",
direction="on",
linebreak="al",
+ fallback=[[\Leftarrow\joinrel\Rightarrow]],
+ mathclass="relation",
+ mathname="Longleftrightarrow",
unicodeslot=0x27FA,
},
[0x27FB]={
@@ -62761,6 +63361,9 @@ characters.data={
description="LONG LEFTWARDS ARROW FROM BAR",
direction="on",
linebreak="al",
+ fallback=[[\longleftarrow\mapstochar]], -- untested
+ mathclass="relation",
+ mathname="longmapsfrom",
unicodeslot=0x27FB,
},
[0x27FC]={
@@ -62768,6 +63371,9 @@ characters.data={
description="LONG RIGHTWARDS ARROW FROM BAR",
direction="on",
linebreak="al",
+ fallback=[[\mapstochar\longrightarrow]],
+ mathclass="relation",
+ mathname="longmapsto",
unicodeslot=0x27FC,
},
[0x27FD]={
@@ -62775,6 +63381,8 @@ characters.data={
description="LONG LEFTWARDS DOUBLE ARROW FROM BAR",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Longmapsfrom",
unicodeslot=0x27FD,
},
[0x27FE]={
@@ -62782,6 +63390,8 @@ characters.data={
description="LONG RIGHTWARDS DOUBLE ARROW FROM BAR",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Longmapsto",
unicodeslot=0x27FE,
},
[0x27FF]={
@@ -62789,6 +63399,8 @@ characters.data={
description="LONG RIGHTWARDS SQUIGGLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="longrightsquigarrow",
unicodeslot=0x27FF,
},
[0x2800]={
@@ -64630,6 +65242,8 @@ characters.data={
description="LEFTWARDS DOUBLE ARROW FROM BAR",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Mapsfrom",
unicodeslot=0x2906,
},
[0x2907]={
@@ -64637,6 +65251,8 @@ characters.data={
description="RIGHTWARDS DOUBLE ARROW FROM BAR",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Mapsto",
unicodeslot=0x2907,
},
[0x2908]={
@@ -64658,6 +65274,8 @@ characters.data={
description="UPWARDS TRIPLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Uuparrow",
unicodeslot=0x290A,
},
[0x290B]={
@@ -64665,6 +65283,8 @@ characters.data={
description="DOWNWARDS TRIPLE ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="Ddownarrow",
unicodeslot=0x290B,
},
[0x290C]={
@@ -64672,6 +65292,8 @@ characters.data={
description="LEFTWARDS DOUBLE DASH ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dashedleftarrow",
unicodeslot=0x290C,
},
[0x290D]={
@@ -64679,6 +65301,8 @@ characters.data={
description="RIGHTWARDS DOUBLE DASH ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dashedrightarrow",
unicodeslot=0x290D,
},
[0x290E]={
@@ -64707,6 +65331,8 @@ characters.data={
description="RIGHTWARDS ARROW WITH DOTTED STEM",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="dottedrightarrow",
unicodeslot=0x2911,
},
[0x2912]={
@@ -64742,6 +65368,8 @@ characters.data={
description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="twoheadrightarrowtail",
unicodeslot=0x2916,
},
[0x2917]={
@@ -64749,6 +65377,7 @@ characters.data={
description="RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE",
direction="on",
linebreak="al",
+ mathclass="relation",
unicodeslot=0x2917,
},
[0x2918]={
@@ -64819,6 +65448,8 @@ characters.data={
description="NORTH WEST AND SOUTH EAST ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="nwsearrow",
unicodeslot=0x2921,
},
[0x2922]={
@@ -64826,6 +65457,8 @@ characters.data={
description="NORTH EAST AND SOUTH WEST ARROW",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="neswarrow",
unicodeslot=0x2922,
},
[0x2923]={
@@ -64833,6 +65466,8 @@ characters.data={
description="NORTH WEST ARROW WITH HOOK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lhooknwarrow",
unicodeslot=0x2923,
},
[0x2924]={
@@ -64840,6 +65475,8 @@ characters.data={
description="NORTH EAST ARROW WITH HOOK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rhooknearrow",
unicodeslot=0x2924,
},
[0x2925]={
@@ -64847,6 +65484,8 @@ characters.data={
description="SOUTH EAST ARROW WITH HOOK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lhooksearrow",
unicodeslot=0x2925,
},
[0x2926]={
@@ -64854,6 +65493,8 @@ characters.data={
description="SOUTH WEST ARROW WITH HOOK",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rhookswarrow",
unicodeslot=0x2926,
},
[0x2927]={
@@ -66272,6 +66913,8 @@ characters.data={
description="BLACK LOZENGE",
direction="on",
linebreak="al",
+ mathclass="ord",
+ mathname="blacklozenge",
unicodeslot=0x29EB,
},
[0x29EC]={
@@ -66431,6 +67074,8 @@ characters.data={
description="N-ARY CIRCLED PLUS OPERATOR",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="bigoplus",
unicodeslot=0x2A01,
},
[0x2A02]={
@@ -66438,6 +67083,8 @@ characters.data={
description="N-ARY CIRCLED TIMES OPERATOR",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="bigotimes",
unicodeslot=0x2A02,
},
[0x2A03]={
@@ -66445,6 +67092,8 @@ characters.data={
description="N-ARY UNION OPERATOR WITH DOT",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="bigodot",
unicodeslot=0x2A03,
},
[0x2A04]={
@@ -66452,6 +67101,8 @@ characters.data={
description="N-ARY UNION OPERATOR WITH PLUS",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="biguplus",
unicodeslot=0x2A04,
},
[0x2A05]={
@@ -66459,6 +67110,8 @@ characters.data={
description="N-ARY SQUARE INTERSECTION OPERATOR",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="bigsqcap",
unicodeslot=0x2A05,
},
[0x2A06]={
@@ -66466,6 +67119,8 @@ characters.data={
description="N-ARY SQUARE UNION OPERATOR",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="bigsqcup",
unicodeslot=0x2A06,
},
[0x2A07]={
@@ -66487,6 +67142,8 @@ characters.data={
description="N-ARY TIMES OPERATOR",
direction="on",
linebreak="al",
+ mathclass="limop",
+ mathname="bigtimes",
unicodeslot=0x2A09,
},
[0x2A0A]={
@@ -66874,6 +67531,8 @@ characters.data={
description="AMALGAMATION OR COPRODUCT",
direction="on",
linebreak="al",
+ mathclass="binary",
+ mathname="amalg",
unicodeslot=0x2A3F,
},
[0x2A40]={
@@ -67315,6 +67974,8 @@ characters.data={
description="LESS-THAN OR SLANTED EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="leqslant",
mirror=0x2A7E,
unicodeslot=0x2A7D,
},
@@ -67323,6 +67984,8 @@ characters.data={
description="GREATER-THAN OR SLANTED EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="geqslant",
mirror=0x2A7D,
unicodeslot=0x2A7E,
},
@@ -67379,6 +68042,8 @@ characters.data={
description="LESS-THAN OR APPROXIMATE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lessapprox",
unicodeslot=0x2A85,
},
[0x2A86]={
@@ -67386,6 +68051,8 @@ characters.data={
description="GREATER-THAN OR APPROXIMATE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gtrapprox",
unicodeslot=0x2A86,
},
[0x2A87]={
@@ -67393,6 +68060,8 @@ characters.data={
description="LESS-THAN AND SINGLE-LINE NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lneq",
unicodeslot=0x2A87,
},
[0x2A88]={
@@ -67400,6 +68069,8 @@ characters.data={
description="GREATER-THAN AND SINGLE-LINE NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="rneq",
unicodeslot=0x2A88,
},
[0x2A89]={
@@ -67407,6 +68078,8 @@ characters.data={
description="LESS-THAN AND NOT APPROXIMATE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lnapprox",
unicodeslot=0x2A89,
},
[0x2A8A]={
@@ -67414,6 +68087,8 @@ characters.data={
description="GREATER-THAN AND NOT APPROXIMATE",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gnapprox",
unicodeslot=0x2A8A,
},
[0x2A8B]={
@@ -67421,6 +68096,8 @@ characters.data={
description="LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="lesseqqgtr",
mirror=0x2A8C,
unicodeslot=0x2A8B,
},
@@ -67429,6 +68106,8 @@ characters.data={
description="GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="gtreqqless",
mirror=0x2A8B,
unicodeslot=0x2A8C,
},
@@ -67497,6 +68176,8 @@ characters.data={
description="SLANTED EQUAL TO OR LESS-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="eqslantless",
mirror=0x2A96,
unicodeslot=0x2A95,
},
@@ -67505,6 +68186,8 @@ characters.data={
description="SLANTED EQUAL TO OR GREATER-THAN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="eqslantgtr",
mirror=0x2A95,
unicodeslot=0x2A96,
},
@@ -67717,6 +68400,8 @@ characters.data={
description="PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="precneq",
unicodeslot=0x2AB1,
},
[0x2AB2]={
@@ -67724,6 +68409,8 @@ characters.data={
description="SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succneq",
unicodeslot=0x2AB2,
},
[0x2AB3]={
@@ -67731,6 +68418,8 @@ characters.data={
description="PRECEDES ABOVE EQUALS SIGN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="preceqq",
mirror=0x2AB4,
unicodeslot=0x2AB3,
},
@@ -67739,6 +68428,8 @@ characters.data={
description="SUCCEEDS ABOVE EQUALS SIGN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succeqq",
mirror=0x2AB3,
unicodeslot=0x2AB4,
},
@@ -67747,6 +68438,8 @@ characters.data={
description="PRECEDES ABOVE NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="precneqq",
unicodeslot=0x2AB5,
},
[0x2AB6]={
@@ -67754,6 +68447,8 @@ characters.data={
description="SUCCEEDS ABOVE NOT EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succneqq",
unicodeslot=0x2AB6,
},
[0x2AB7]={
@@ -67761,6 +68456,8 @@ characters.data={
description="PRECEDES ABOVE ALMOST EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="precapprox",
unicodeslot=0x2AB7,
},
[0x2AB8]={
@@ -67768,6 +68465,8 @@ characters.data={
description="SUCCEEDS ABOVE ALMOST EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succapprox",
unicodeslot=0x2AB8,
},
[0x2AB9]={
@@ -67775,6 +68474,8 @@ characters.data={
description="PRECEDES ABOVE NOT ALMOST EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="precnapprox",
unicodeslot=0x2AB9,
},
[0x2ABA]={
@@ -67782,6 +68483,8 @@ characters.data={
description="SUCCEEDS ABOVE NOT ALMOST EQUAL TO",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="succnapprox",
unicodeslot=0x2ABA,
},
[0x2ABB]={
@@ -67869,6 +68572,8 @@ characters.data={
description="SUBSET OF ABOVE EQUALS SIGN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="subseteqq",
mirror=0x2AC6,
unicodeslot=0x2AC5,
},
@@ -67877,6 +68582,8 @@ characters.data={
description="SUPERSET OF ABOVE EQUALS SIGN",
direction="on",
linebreak="al",
+ mathclass="relation",
+ mathname="supseteqq",
mirror=0x2AC5,
unicodeslot=0x2AC6,
},
@@ -67912,6 +68619,8 @@ characters.data={
category="sm",
description="SUBSET OF ABOVE NOT EQUAL TO",
direction="on",
+ mathclass="relation",
+ mathname="subsetneqq",
linebreak="al",
unicodeslot=0x2ACB,
},
@@ -67919,6 +68628,8 @@ characters.data={
category="sm",
description="SUPERSET OF ABOVE NOT EQUAL TO",
direction="on",
+ mathclass="relation",
+ mathname="supsetneqq",
linebreak="al",
unicodeslot=0x2ACC,
},
@@ -74873,6 +75584,8 @@ characters.data={
direction="on",
linebreak="op",
mirror=0x3015,
+ mathclass="open",
+ mathname="lgroup",
unicodeslot=0x3014,
},
[0x3015]={
@@ -74882,6 +75595,8 @@ characters.data={
direction="on",
linebreak="cl",
mirror=0x3014,
+ mathclass="close",
+ mathname="rgroup",
unicodeslot=0x3015,
},
[0x3016]={
@@ -83044,18 +83759,11 @@ characters.data={
[0x3400]={
category="lo",
cjkwd="w",
- description="<CJK Ideograph Extension A, First>",
+ description="<CJK Ideograph Extension A>",
direction="l",
linebreak="id",
unicodeslot=0x3400,
- },
- [0x4DB5]={
- category="lo",
- cjkwd="w",
- description="<CJK Ideograph Extension A, Last>",
- direction="l",
- linebreak="id",
- unicodeslot=0x4DB5,
+ range= 0x4DB5,
},
[0x4DC0]={
category="so",
@@ -83508,17 +84216,11 @@ characters.data={
[0x4E00]={
category="lo",
cjkwd="w",
- description="<CJK Ideograph, First>",
+ description="<CJK Ideograph>",
direction="l",
linebreak="id",
unicodeslot=0x4E00,
- },
- [0x9FBB]={
- category="lo",
- cjkwd="w",
- description="<CJK Ideograph, Last>",
- linebreak="id",
- unicodeslot=0x9FBB,
+ range=0x9FBB,
},
[0xA000]={
category="lo",
@@ -94186,18 +94888,11 @@ characters.data={
[0xAC00]={
category="lo",
cjkwd="w",
- description="<Hangul Syllable, First>",
+ description="<Hangul Syllable>",
direction="l",
linebreak="h2",
unicodeslot=0xAC00,
- },
- [0xD7A3]={
- category="lo",
- cjkwd="w",
- description="<Hangul Syllable, Last>",
- direction="l",
- linebreak="h3",
- unicodeslot=0xD7A3,
+ range=0xD7A3,
},
[0xD800]={
category="cs",
@@ -104026,7 +104721,7 @@ characters.data={
description="PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET",
direction="on",
linebreak="op",
- mathfiller="downbracefill",
+ mathfiller="downbracefill", -- funny, chinese, no math, wrong but for the moment we need it for buggy mathml
specials={ "vertical", 0x007B },
unicodeslot=0xFE37,
},
@@ -104036,7 +104731,7 @@ characters.data={
description="PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET",
direction="on",
linebreak="cl",
- mathfiller="upbracefill",
+ mathfiller="upbracefill", -- funny, chinese, no math, wrong but for the moment we need it for buggy mathml
specials={ "vertical", 0x007D },
unicodeslot=0xFE38,
},
@@ -113814,6 +114509,8 @@ characters.data={
description="CUNEIFORM SIGN ARAD TIMES KUR",
direction="l",
linebreak="al",
+ mathclass="ord",
+ mathname="backprime",
unicodeslot=0x12035,
},
[0x12036]={
@@ -130026,7 +130723,7 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL DOTLESS I",
direction="l",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="imath",
specials={ "font", 0x0131 },
unicodeslot=0x1D6A4,
@@ -130036,7 +130733,7 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL DOTLESS J",
direction="l",
linebreak="al",
- mathclass="variable",
+ mathclass="default",
mathname="jmath",
specials={ "font", 0x0237 },
unicodeslot=0x1D6A5,
@@ -130510,6 +131207,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL ALPHA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Alpha",
specials={ "font", 0x0391 },
unicodeslot=0x1D6E2,
},
@@ -130518,6 +131217,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL BETA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Beta",
specials={ "font", 0x0392 },
unicodeslot=0x1D6E3,
},
@@ -130526,6 +131227,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL GAMMA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Gamma",
specials={ "font", 0x0393 },
unicodeslot=0x1D6E4,
},
@@ -130534,6 +131237,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL DELTA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Delta",
specials={ "font", 0x0394 },
unicodeslot=0x1D6E5,
},
@@ -130542,6 +131247,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL EPSILON",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Epsilon",
specials={ "font", 0x0395 },
unicodeslot=0x1D6E6,
},
@@ -130550,6 +131257,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL ZETA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Zeta",
specials={ "font", 0x0396 },
unicodeslot=0x1D6E7,
},
@@ -130558,6 +131267,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL ETA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Eta",
specials={ "font", 0x0397 },
unicodeslot=0x1D6E8,
},
@@ -130566,6 +131277,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL THETA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Theta",
specials={ "font", 0x0398 },
unicodeslot=0x1D6E9,
},
@@ -130574,6 +131287,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL IOTA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Iota",
specials={ "font", 0x0399 },
unicodeslot=0x1D6EA,
},
@@ -130582,6 +131297,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL KAPPA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Kappa",
specials={ "font", 0x039A },
unicodeslot=0x1D6EB,
},
@@ -130590,6 +131307,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL LAMDA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Lambda",
specials={ "font", 0x039B },
unicodeslot=0x1D6EC,
},
@@ -130598,6 +131317,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL MU",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Mu",
specials={ "font", 0x039C },
unicodeslot=0x1D6ED,
},
@@ -130606,6 +131327,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL NU",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Nu",
specials={ "font", 0x039D },
unicodeslot=0x1D6EE,
},
@@ -130614,6 +131337,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL XI",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Xi",
specials={ "font", 0x039E },
unicodeslot=0x1D6EF,
},
@@ -130622,6 +131347,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL OMICRON",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Omicron",
specials={ "font", 0x039F },
unicodeslot=0x1D6F0,
},
@@ -130630,6 +131357,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL PI",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Pi",
specials={ "font", 0x03A0 },
unicodeslot=0x1D6F1,
},
@@ -130638,6 +131367,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL RHO",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Rho",
specials={ "font", 0x03A1 },
unicodeslot=0x1D6F2,
},
@@ -130646,6 +131377,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL THETA SYMBOL",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="varTheta",
specials={ "font", 0x03F4 },
unicodeslot=0x1D6F3,
},
@@ -130654,6 +131387,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL SIGMA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Sigma",
specials={ "font", 0x03A3 },
unicodeslot=0x1D6F4,
},
@@ -130662,6 +131397,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL TAU",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Tau",
specials={ "font", 0x03A4 },
unicodeslot=0x1D6F5,
},
@@ -130670,6 +131407,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL UPSILON",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Upsilon",
specials={ "font", 0x03A5 },
unicodeslot=0x1D6F6,
},
@@ -130678,6 +131417,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL PHI",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Phi",
specials={ "font", 0x03A6 },
unicodeslot=0x1D6F7,
},
@@ -130686,6 +131427,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL CHI",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Chi",
specials={ "font", 0x03A7 },
unicodeslot=0x1D6F8,
},
@@ -130694,6 +131437,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL PSI",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Psi",
specials={ "font", 0x03A8 },
unicodeslot=0x1D6F9,
},
@@ -130702,6 +131447,8 @@ characters.data={
description="MATHEMATICAL ITALIC CAPITAL OMEGA",
direction="l",
linebreak="al",
+ mathclass="variable",
+ mathname="Omega",
specials={ "font", 0x03A9 },
unicodeslot=0x1D6FA,
},
@@ -130710,6 +131457,8 @@ characters.data={
description="MATHEMATICAL ITALIC NABLA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="nabla",
specials={ "font", 0x2207 },
unicodeslot=0x1D6FB,
},
@@ -130718,6 +131467,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL ALPHA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="alpha",
specials={ "font", 0x03B1 },
unicodeslot=0x1D6FC,
},
@@ -130726,6 +131477,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL BETA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="beta",
specials={ "font", 0x03B2 },
unicodeslot=0x1D6FD,
},
@@ -130734,6 +131487,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL GAMMA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="gamma",
specials={ "font", 0x03B3 },
unicodeslot=0x1D6FE,
},
@@ -130742,6 +131497,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL DELTA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="delta",
specials={ "font", 0x03B4 },
unicodeslot=0x1D6FF,
},
@@ -130750,6 +131507,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL EPSILON",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="varepsilon",
specials={ "font", 0x03B5 },
unicodeslot=0x1D700,
},
@@ -130758,6 +131517,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL ZETA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="zeta",
specials={ "font", 0x03B6 },
unicodeslot=0x1D701,
},
@@ -130766,6 +131527,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL ETA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="eta",
specials={ "font", 0x03B7 },
unicodeslot=0x1D702,
},
@@ -130774,6 +131537,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL THETA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="theta",
specials={ "font", 0x03B8 },
unicodeslot=0x1D703,
},
@@ -130782,6 +131547,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL IOTA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="iota",
specials={ "font", 0x03B9 },
unicodeslot=0x1D704,
},
@@ -130790,6 +131557,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL KAPPA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="kappa",
specials={ "font", 0x03BA },
unicodeslot=0x1D705,
},
@@ -130798,6 +131567,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL LAMDA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="lambda",
specials={ "font", 0x03BB },
unicodeslot=0x1D706,
},
@@ -130806,6 +131577,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL MU",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="mu",
specials={ "font", 0x03BC },
unicodeslot=0x1D707,
},
@@ -130814,6 +131587,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL NU",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="nu",
specials={ "font", 0x03BD },
unicodeslot=0x1D708,
},
@@ -130822,6 +131597,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL XI",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="xi",
specials={ "font", 0x03BE },
unicodeslot=0x1D709,
},
@@ -130830,6 +131607,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL OMICRON",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="omicron",
specials={ "font", 0x03BF },
unicodeslot=0x1D70A,
},
@@ -130838,6 +131617,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL PI",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="pi",
specials={ "font", 0x03C0 },
unicodeslot=0x1D70B,
},
@@ -130846,6 +131627,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL RHO",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="rho",
specials={ "font", 0x03C1 },
unicodeslot=0x1D70C,
},
@@ -130854,6 +131637,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL FINAL SIGMA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="varsigma",
specials={ "font", 0x03C2 },
unicodeslot=0x1D70D,
},
@@ -130862,6 +131647,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL SIGMA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="sigma",
specials={ "font", 0x03C3 },
unicodeslot=0x1D70E,
},
@@ -130870,6 +131657,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL TAU",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="tau",
specials={ "font", 0x03C4 },
unicodeslot=0x1D70F,
},
@@ -130878,6 +131667,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL UPSILON",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="upsilon",
specials={ "font", 0x03C5 },
unicodeslot=0x1D710,
},
@@ -130886,6 +131677,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL PHI",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="varphi",
specials={ "font", 0x03C6 },
unicodeslot=0x1D711,
},
@@ -130894,6 +131687,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL CHI",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="chi",
specials={ "font", 0x03C7 },
unicodeslot=0x1D712,
},
@@ -130902,6 +131697,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL PSI",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="psi",
specials={ "font", 0x03C8 },
unicodeslot=0x1D713,
},
@@ -130910,6 +131707,8 @@ characters.data={
description="MATHEMATICAL ITALIC SMALL OMEGA",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="omega",
specials={ "font", 0x03C9 },
unicodeslot=0x1D714,
},
@@ -130926,6 +131725,8 @@ characters.data={
description="MATHEMATICAL ITALIC EPSILON SYMBOL",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="epsilon",
specials={ "font", 0x03F5 },
unicodeslot=0x1D716,
},
@@ -130934,6 +131735,8 @@ characters.data={
description="MATHEMATICAL ITALIC THETA SYMBOL",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="vartheta",
specials={ "font", 0x03D1 },
unicodeslot=0x1D717,
},
@@ -130942,6 +131745,8 @@ characters.data={
description="MATHEMATICAL ITALIC KAPPA SYMBOL",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="varkappa",
specials={ "font", 0x03F0 },
unicodeslot=0x1D718,
},
@@ -130950,6 +131755,8 @@ characters.data={
description="MATHEMATICAL ITALIC PHI SYMBOL",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="phi",
specials={ "font", 0x03D5 },
unicodeslot=0x1D719,
},
@@ -130958,6 +131765,8 @@ characters.data={
description="MATHEMATICAL ITALIC RHO SYMBOL",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="varrho",
specials={ "font", 0x03F1 },
unicodeslot=0x1D71A,
},
@@ -130966,6 +131775,8 @@ characters.data={
description="MATHEMATICAL ITALIC PI SYMBOL",
direction="l",
linebreak="al",
+ mathclass="default",
+ mathname="varpi",
specials={ "font", 0x03D6 },
unicodeslot=0x1D71B,
},
@@ -132780,18 +133591,11 @@ characters.data={
[0x20000]={
category="lo",
cjkwd="w",
- description="<CJK Ideograph Extension B, First>",
+ description="<CJK Ideograph Extension B>",
direction="l",
linebreak="id",
unicodeslot=0x20000,
- },
- [0x2A6D6]={
- category="lo",
- cjkwd="w",
- description="<CJK Ideograph Extension B, Last>",
- direction="l",
- linebreak="id",
- unicodeslot=0x2A6D6,
+ range=0x2A6D6,
},
[0x2F800]={
category="lo",
diff --git a/tex/context/base/char-syn.lua b/tex/context/base/char-enc.lua
index a779e1a58..a4e5ac77d 100644
--- a/tex/context/base/char-syn.lua
+++ b/tex/context/base/char-enc.lua
@@ -8,6 +8,8 @@ if not modules then modules = { } end modules ['char-syn'] = {
-- thanks to tex4ht for these mappings
+characters = characters or { }
+
characters.synonyms = {
angle = 0x2220,
anticlockwise = 0x21BA,
@@ -138,3 +140,24 @@ characters.synonyms = {
uprise = 0x22CF,
Yen = 0x00A5,
}
+
+if not characters.enccodes then
+
+ local enccodes = { }
+
+ for unicode, data in next, characters.data do
+ local encname = data.adobename or data.contextname
+ if encname then
+ enccodes[encname] = unicode
+ end
+ end
+
+ for name, unicode in next, characters.synonyms do
+ if not enccodes[name] then enccodes[name] = unicode end
+ end
+
+ characters.enccodes = enccodes
+
+end
+
+storage.register("characters.enccodes", characters.enccodes, "characters.enccodes")
diff --git a/tex/context/base/char-enc.tex b/tex/context/base/char-enc.tex
new file mode 100644
index 000000000..9fe9a363b
--- /dev/null
+++ b/tex/context/base/char-enc.tex
@@ -0,0 +1,18 @@
+%D \module
+%D [ file=char-enc,
+%D version=2006.08.20,
+%D title=\CONTEXT\ Character Support,
+%D subtitle=Encodings,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 Character Support / Encodings}
+
+\registerctxluafile{char-enc}{1.001}
+
+\endinput
diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua
index 0dd7a266a..974366b7a 100644
--- a/tex/context/base/char-ini.lua
+++ b/tex/context/base/char-ini.lua
@@ -9,202 +9,238 @@ if not modules then modules = { } end modules ['char-ini'] = {
tex = tex or { }
xml = xml or { }
-local format, texsprint, utfchar, utfbyte, concat = string.format, tex.sprint, unicode.utf8.char, unicode.utf8.byte, table.concat
+local utf = unicode.utf8
+
+local utfchar, utfbyte = utf.char, utf.byte
+local concat = table.concat
+local next, tonumber = next, tonumber
+local texsprint, texprint = tex.sprint, tex.print
+local format, lower, gsub, match, gmatch = string.format, string.lower, string.gsub, string.match, string.match, string.gmatch
+
+local ctxcatcodes = tex.ctxcatcodes
+local texcatcodes = tex.texcatcodes
--[[ldx--
<p>This module implements some methods and creates additional datastructured
from the big character table that we use for all kind of purposes:
<type>char-def.lua</type>.</p>
+
+<p>We assume that at this point <type>characters.data</type> is already
+loaded!</p>
--ldx]]--
-characters = characters or { }
-characters.data = characters.data or { }
-characters.synonyms = characters.synonyms or { }
-characters.context = characters.context or { }
-
-characters.blocks={
- ["aegeannumbers"] = { 0x10100, 0x1013F, "Aegean Numbers" },
- ["alphabeticpresentationforms"] = { 0xFB00, 0xFB4F, "Alphabetic Presentation Forms" },
- ["ancientgreekmusicalnotation"] = { 0x1D200, 0x1D24F, "Ancient Greek Musical Notation" },
- ["ancientgreeknumbers"] = { 0x10140, 0x1018F, "Ancient Greek Numbers" },
- ["ancientsymbols"] = { 0x10190, 0x101CF, "Ancient Symbols" },
- ["arabic"] = { 0x0600, 0x06FF, "Arabic" },
- ["arabicpresentationformsa"] = { 0xFB50, 0xFDFF, "Arabic Presentation Forms-A" },
- ["arabicpresentationformsb"] = { 0xFE70, 0xFEFF, "Arabic Presentation Forms-B" },
- ["arabicsupplement"] = { 0x0750, 0x077F, "Arabic Supplement" },
- ["armenian"] = { 0x0530, 0x058F, "Armenian" },
- ["arrows"] = { 0x2190, 0x21FF, "Arrows" },
- ["balinese"] = { 0x1B00, 0x1B7F, "Balinese" },
- ["basiclatin"] = { 0x0000, 0x007F, "Basic Latin" },
- ["bengali"] = { 0x0980, 0x09FF, "Bengali" },
- ["blockelements"] = { 0x2580, 0x259F, "Block Elements" },
- ["bopomofo"] = { 0x3100, 0x312F, "Bopomofo" },
- ["bopomofoextended"] = { 0x31A0, 0x31BF, "Bopomofo Extended" },
- ["boxdrawing"] = { 0x2500, 0x257F, "Box Drawing" },
- ["braillepatterns"] = { 0x2800, 0x28FF, "Braille Patterns" },
- ["buginese"] = { 0x1A00, 0x1A1F, "Buginese" },
- ["buhid"] = { 0x1740, 0x175F, "Buhid" },
- ["byzantinemusicalsymbols"] = { 0x1D000, 0x1D0FF, "Byzantine Musical Symbols" },
- ["carian"] = { 0x102A0, 0x102DF, "Carian" },
- ["cham"] = { 0xAA00, 0xAA5F, "Cham" },
- ["cherokee"] = { 0x13A0, 0x13FF, "Cherokee" },
- ["cjkcompatibility"] = { 0x3300, 0x33FF, "CJK Compatibility" },
- ["cjkcompatibilityforms"] = { 0xFE30, 0xFE4F, "CJK Compatibility Forms" },
- ["cjkcompatibilityideographs"] = { 0xF900, 0xFAFF, "CJK Compatibility Ideographs" },
+characters = characters or { }
+characters.data = characters.data or { }
+
+local data = characters.data
+
+if not characters.ranges then
+ characters.ranges = { }
+ for k, v in next, data do
+ characters.ranges[#characters.ranges+1] = k
+ end
+end
+
+storage.register("characters/ranges",characters.ranges,"characters.ranges")
+
+local ranges = characters.ranges
+
+setmetatable(data, {
+ __index = function(t,k)
+ for r=1,#ranges do
+ local rr = ranges[r] -- first in range
+ if k > rr and k <= data[rr].range then
+ t[k] = t[rr]
+ return t[k]
+ end
+ end
+ return nil
+ end
+})
+
+characters.blocks = {
+ ["aegeannumbers"] = { 0x10100, 0x1013F, "Aegean Numbers" },
+ ["alphabeticpresentationforms"] = { 0x0FB00, 0x0FB4F, "Alphabetic Presentation Forms" },
+ ["ancientgreekmusicalnotation"] = { 0x1D200, 0x1D24F, "Ancient Greek Musical Notation" },
+ ["ancientgreeknumbers"] = { 0x10140, 0x1018F, "Ancient Greek Numbers" },
+ ["ancientsymbols"] = { 0x10190, 0x101CF, "Ancient Symbols" },
+ ["arabic"] = { 0x00600, 0x006FF, "Arabic" },
+ ["arabicpresentationformsa"] = { 0x0FB50, 0x0FDFF, "Arabic Presentation Forms-A" },
+ ["arabicpresentationformsb"] = { 0x0FE70, 0x0FEFF, "Arabic Presentation Forms-B" },
+ ["arabicsupplement"] = { 0x00750, 0x0077F, "Arabic Supplement" },
+ ["armenian"] = { 0x00530, 0x0058F, "Armenian" },
+ ["arrows"] = { 0x02190, 0x021FF, "Arrows" },
+ ["balinese"] = { 0x01B00, 0x01B7F, "Balinese" },
+ ["basiclatin"] = { 0x00000, 0x0007F, "Basic Latin" },
+ ["bengali"] = { 0x00980, 0x009FF, "Bengali" },
+ ["blockelements"] = { 0x02580, 0x0259F, "Block Elements" },
+ ["bopomofo"] = { 0x03100, 0x0312F, "Bopomofo" },
+ ["bopomofoextended"] = { 0x031A0, 0x031BF, "Bopomofo Extended" },
+ ["boxdrawing"] = { 0x02500, 0x0257F, "Box Drawing" },
+ ["braillepatterns"] = { 0x02800, 0x028FF, "Braille Patterns" },
+ ["buginese"] = { 0x01A00, 0x01A1F, "Buginese" },
+ ["buhid"] = { 0x01740, 0x0175F, "Buhid" },
+ ["byzantinemusicalsymbols"] = { 0x1D000, 0x1D0FF, "Byzantine Musical Symbols" },
+ ["carian"] = { 0x102A0, 0x102DF, "Carian" },
+ ["cham"] = { 0x0AA00, 0x0AA5F, "Cham" },
+ ["cherokee"] = { 0x013A0, 0x013FF, "Cherokee" },
+ ["cjkcompatibility"] = { 0x03300, 0x033FF, "CJK Compatibility" },
+ ["cjkcompatibilityforms"] = { 0x0FE30, 0x0FE4F, "CJK Compatibility Forms" },
+ ["cjkcompatibilityideographs"] = { 0x0F900, 0x0FAFF, "CJK Compatibility Ideographs" },
["cjkcompatibilityideographssupplement"] = { 0x2F800, 0x2FA1F, "CJK Compatibility Ideographs Supplement" },
- ["cjkradicalssupplement"] = { 0x2E80, 0x2EFF, "CJK Radicals Supplement" },
- ["cjkstrokes"] = { 0x31C0, 0x31EF, "CJK Strokes" },
- ["cjksymbolsandpunctuation"] = { 0x3000, 0x303F, "CJK Symbols and Punctuation" },
- ["cjkunifiedideographs"] = { 0x4E00, 0x9FFF, "CJK Unified Ideographs" },
- ["cjkunifiedideographsextensiona"] = { 0x3400, 0x4DBF, "CJK Unified Ideographs Extension A" },
- ["cjkunifiedideographsextensionb"] = { 0x20000, 0x2A6DF, "CJK Unified Ideographs Extension B" },
- ["combiningdiacriticalmarks"] = { 0x0300, 0x036F, "Combining Diacritical Marks" },
- ["combiningdiacriticalmarksforsymbols"] = { 0x20D0, 0x20FF, "Combining Diacritical Marks for Symbols" },
- ["combiningdiacriticalmarkssupplement"] = { 0x1DC0, 0x1DFF, "Combining Diacritical Marks Supplement" },
- ["combininghalfmarks"] = { 0xFE20, 0xFE2F, "Combining Half Marks" },
- ["controlpictures"] = { 0x2400, 0x243F, "Control Pictures" },
- ["coptic"] = { 0x2C80, 0x2CFF, "Coptic" },
- ["countingrodnumerals"] = { 0x1D360, 0x1D37F, "Counting Rod Numerals" },
- ["cuneiform"] = { 0x12000, 0x123FF, "Cuneiform" },
- ["cuneiformnumbersandpunctuation"] = { 0x12400, 0x1247F, "Cuneiform Numbers and Punctuation" },
- ["currencysymbols"] = { 0x20A0, 0x20CF, "Currency Symbols" },
- ["cypriotsyllabary"] = { 0x10800, 0x1083F, "Cypriot Syllabary" },
- ["cyrillic"] = { 0x0400, 0x04FF, "Cyrillic" },
- ["cyrillicextendeda"] = { 0x2DE0, 0x2DFF, "Cyrillic Extended-A" },
- ["cyrillicextendedb"] = { 0xA640, 0xA69F, "Cyrillic Extended-B" },
- ["cyrillicsupplement"] = { 0x0500, 0x052F, "Cyrillic Supplement" },
- ["deseret"] = { 0x10400, 0x1044F, "Deseret" },
- ["devanagari"] = { 0x0900, 0x097F, "Devanagari" },
- ["dingbats"] = { 0x2700, 0x27BF, "Dingbats" },
- ["dominotiles"] = { 0x1F030, 0x1F09F, "Domino Tiles" },
- ["enclosedalphanumerics"] = { 0x2460, 0x24FF, "Enclosed Alphanumerics" },
- ["enclosedcjklettersandmonths"] = { 0x3200, 0x32FF, "Enclosed CJK Letters and Months" },
- ["ethiopic"] = { 0x1200, 0x137F, "Ethiopic" },
- ["ethiopicextended"] = { 0x2D80, 0x2DDF, "Ethiopic Extended" },
- ["ethiopicsupplement"] = { 0x1380, 0x139F, "Ethiopic Supplement" },
- ["generalpunctuation"] = { 0x2000, 0x206F, "General Punctuation" },
- ["geometricshapes"] = { 0x25A0, 0x25FF, "Geometric Shapes" },
- ["georgian"] = { 0x10A0, 0x10FF, "Georgian" },
- ["georgiansupplement"] = { 0x2D00, 0x2D2F, "Georgian Supplement" },
- ["glagolitic"] = { 0x2C00, 0x2C5F, "Glagolitic" },
- ["gothic"] = { 0x10330, 0x1034F, "Gothic" },
- ["greekandcoptic"] = { 0x0370, 0x03FF, "Greek and Coptic" },
- ["greekextended"] = { 0x1F00, 0x1FFF, "Greek Extended" },
- ["gujarati"] = { 0x0A80, 0x0AFF, "Gujarati" },
- ["gurmukhi"] = { 0x0A00, 0x0A7F, "Gurmukhi" },
- ["halfwidthandfullwidthforms"] = { 0xFF00, 0xFFEF, "Halfwidth and Fullwidth Forms" },
- ["hangulcompatibilityjamo"] = { 0x3130, 0x318F, "Hangul Compatibility Jamo" },
- ["hanguljamo"] = { 0x1100, 0x11FF, "Hangul Jamo" },
- ["hangulsyllables"] = { 0xAC00, 0xD7AF, "Hangul Syllables" },
- ["hanunoo"] = { 0x1720, 0x173F, "Hanunoo" },
- ["hebrew"] = { 0x0590, 0x05FF, "Hebrew" },
- ["highprivateusesurrogates"] = { 0xDB80, 0xDBFF, "High Private Use Surrogates" },
- ["highsurrogates"] = { 0xD800, 0xDB7F, "High Surrogates" },
- ["hiragana"] = { 0x3040, 0x309F, "Hiragana" },
- ["ideographicdescriptioncharacters"] = { 0x2FF0, 0x2FFF, "Ideographic Description Characters" },
- ["ipaextensions"] = { 0x0250, 0x02AF, "IPA Extensions" },
- ["kanbun"] = { 0x3190, 0x319F, "Kanbun" },
- ["kangxiradicals"] = { 0x2F00, 0x2FDF, "Kangxi Radicals" },
- ["kannada"] = { 0x0C80, 0x0CFF, "Kannada" },
- ["katakana"] = { 0x30A0, 0x30FF, "Katakana" },
- ["katakanaphoneticextensions"] = { 0x31F0, 0x31FF, "Katakana Phonetic Extensions" },
- ["kayahli"] = { 0xA900, 0xA92F, "Kayah Li" },
- ["kharoshthi"] = { 0x10A00, 0x10A5F, "Kharoshthi" },
- ["khmer"] = { 0x1780, 0x17FF, "Khmer" },
- ["khmersymbols"] = { 0x19E0, 0x19FF, "Khmer Symbols" },
- ["lao"] = { 0x0E80, 0x0EFF, "Lao" },
- ["latinextendeda"] = { 0x0100, 0x017F, "Latin Extended-A" },
- ["latinextendedadditional"] = { 0x1E00, 0x1EFF, "Latin Extended Additional" },
- ["latinextendedb"] = { 0x0180, 0x024F, "Latin Extended-B" },
- ["latinextendedc"] = { 0x2C60, 0x2C7F, "Latin Extended-C" },
- ["latinextendedd"] = { 0xA720, 0xA7FF, "Latin Extended-D" },
- ["latinsupplement"] = { 0x0080, 0x00FF, "Latin-1 Supplement" },
- ["lepcha"] = { 0x1C00, 0x1C4F, "Lepcha" },
- ["letterlikesymbols"] = { 0x2100, 0x214F, "Letterlike Symbols" },
- ["limbu"] = { 0x1900, 0x194F, "Limbu" },
- ["linearbideograms"] = { 0x10080, 0x100FF, "Linear B Ideograms" },
- ["linearbsyllabary"] = { 0x10000, 0x1007F, "Linear B Syllabary" },
- ["lowsurrogates"] = { 0xDC00, 0xDFFF, "Low Surrogates" },
- ["lycian"] = { 0x10280, 0x1029F, "Lycian" },
- ["lydian"] = { 0x10920, 0x1093F, "Lydian" },
- ["mahjongtiles"] = { 0x1F000, 0x1F02F, "Mahjong Tiles" },
- ["malayalam"] = { 0x0D00, 0x0D7F, "Malayalam" },
- ["mathematicalalphanumericsymbols"] = { 0x1D400, 0x1D7FF, "Mathematical Alphanumeric Symbols" },
- ["mathematicaloperators"] = { 0x2200, 0x22FF, "Mathematical Operators" },
- ["miscellaneousmathematicalsymbolsa"] = { 0x27C0, 0x27EF, "Miscellaneous Mathematical Symbols-A" },
- ["miscellaneousmathematicalsymbolsb"] = { 0x2980, 0x29FF, "Miscellaneous Mathematical Symbols-B" },
- ["miscellaneoussymbols"] = { 0x2600, 0x26FF, "Miscellaneous Symbols" },
- ["miscellaneoussymbolsandarrows"] = { 0x2B00, 0x2BFF, "Miscellaneous Symbols and Arrows" },
- ["miscellaneoustechnical"] = { 0x2300, 0x23FF, "Miscellaneous Technical" },
- ["modifiertoneletters"] = { 0xA700, 0xA71F, "Modifier Tone Letters" },
- ["mongolian"] = { 0x1800, 0x18AF, "Mongolian" },
- ["musicalsymbols"] = { 0x1D100, 0x1D1FF, "Musical Symbols" },
- ["myanmar"] = { 0x1000, 0x109F, "Myanmar" },
- ["newtailue"] = { 0x1980, 0x19DF, "New Tai Lue" },
- ["nko"] = { 0x07C0, 0x07FF, "NKo" },
- ["numberforms"] = { 0x2150, 0x218F, "Number Forms" },
- ["ogham"] = { 0x1680, 0x169F, "Ogham" },
- ["olchiki"] = { 0x1C50, 0x1C7F, "Ol Chiki" },
- ["olditalic"] = { 0x10300, 0x1032F, "Old Italic" },
- ["oldpersian"] = { 0x103A0, 0x103DF, "Old Persian" },
- ["opticalcharacterrecognition"] = { 0x2440, 0x245F, "Optical Character Recognition" },
- ["oriya"] = { 0x0B00, 0x0B7F, "Oriya" },
- ["osmanya"] = { 0x10480, 0x104AF, "Osmanya" },
- ["phagspa"] = { 0xA840, 0xA87F, "Phags-pa" },
- ["phaistosdisc"] = { 0x101D0, 0x101FF, "Phaistos Disc" },
- ["phoenician"] = { 0x10900, 0x1091F, "Phoenician" },
- ["phoneticextensions"] = { 0x1D00, 0x1D7F, "Phonetic Extensions" },
- ["phoneticextensionssupplement"] = { 0x1D80, 0x1DBF, "Phonetic Extensions Supplement" },
- ["privateusearea"] = { 0xE000, 0xF8FF, "Private Use Area" },
- ["rejang"] = { 0xA930, 0xA95F, "Rejang" },
- ["runic"] = { 0x16A0, 0x16FF, "Runic" },
- ["saurashtra"] = { 0xA880, 0xA8DF, "Saurashtra" },
- ["shavian"] = { 0x10450, 0x1047F, "Shavian" },
- ["sinhala"] = { 0x0D80, 0x0DFF, "Sinhala" },
- ["smallformvariants"] = { 0xFE50, 0xFE6F, "Small Form Variants" },
- ["spacingmodifierletters"] = { 0x02B0, 0x02FF, "Spacing Modifier Letters" },
- ["specials"] = { 0xFFF0, 0xFFFF, "Specials" },
- ["sundanese"] = { 0x1B80, 0x1BBF, "Sundanese" },
- ["superscriptsandsubscripts"] = { 0x2070, 0x209F, "Superscripts and Subscripts" },
- ["supplementalarrowsa"] = { 0x27F0, 0x27FF, "Supplemental Arrows-A" },
- ["supplementalarrowsb"] = { 0x2900, 0x297F, "Supplemental Arrows-B" },
- ["supplementalmathematicaloperators"] = { 0x2A00, 0x2AFF, "Supplemental Mathematical Operators" },
- ["supplementalpunctuation"] = { 0x2E00, 0x2E7F, "Supplemental Punctuation" },
- ["supplementaryprivateuseareaa"] = { 0xF0000, 0xFFFFF, "Supplementary Private Use Area-A" },
- ["supplementaryprivateuseareab"] = { 0x100000, 0x10FFFF, "Supplementary Private Use Area-B" },
- ["sylotinagri"] = { 0xA800, 0xA82F, "Syloti Nagri" },
- ["syriac"] = { 0x0700, 0x074F, "Syriac" },
- ["tagalog"] = { 0x1700, 0x171F, "Tagalog" },
- ["tagbanwa"] = { 0x1760, 0x177F, "Tagbanwa" },
- ["tags"] = { 0xE0000, 0xE007F, "Tags" },
- ["taile"] = { 0x1950, 0x197F, "Tai Le" },
- ["taixuanjingsymbols"] = { 0x1D300, 0x1D35F, "Tai Xuan Jing Symbols" },
- ["tamil"] = { 0x0B80, 0x0BFF, "Tamil" },
- ["telugu"] = { 0x0C00, 0x0C7F, "Telugu" },
- ["thaana"] = { 0x0780, 0x07BF, "Thaana" },
- ["thai"] = { 0x0E00, 0x0E7F, "Thai" },
- ["tibetan"] = { 0x0F00, 0x0FFF, "Tibetan" },
- ["tifinagh"] = { 0x2D30, 0x2D7F, "Tifinagh" },
- ["ugaritic"] = { 0x10380, 0x1039F, "Ugaritic" },
- ["unifiedcanadianaboriginalsyllabics"] = { 0x1400, 0x167F, "Unified Canadian Aboriginal Syllabics" },
- ["vai"] = { 0xA500, 0xA63F, "Vai" },
- ["variationselectors"] = { 0xFE00, 0xFE0F, "Variation Selectors" },
- ["variationselectorssupplement"] = { 0xE0100, 0xE01EF, "Variation Selectors Supplement" },
- ["verticalforms"] = { 0xFE10, 0xFE1F, "Vertical Forms" },
- ["yijinghexagramsymbols"] = { 0x4DC0, 0x4DFF, "Yijing Hexagram Symbols" },
- ["yiradicals"] = { 0xA490, 0xA4CF, "Yi Radicals" },
- ["yisyllables"] = { 0xA000, 0xA48F, "Yi Syllables" },
+ ["cjkradicalssupplement"] = { 0x02E80, 0x02EFF, "CJK Radicals Supplement" },
+ ["cjkstrokes"] = { 0x031C0, 0x031EF, "CJK Strokes" },
+ ["cjksymbolsandpunctuation"] = { 0x03000, 0x0303F, "CJK Symbols and Punctuation" },
+ ["cjkunifiedideographs"] = { 0x04E00, 0x09FFF, "CJK Unified Ideographs" },
+ ["cjkunifiedideographsextensiona"] = { 0x03400, 0x04DBF, "CJK Unified Ideographs Extension A" },
+ ["cjkunifiedideographsextensionb"] = { 0x20000, 0x2A6DF, "CJK Unified Ideographs Extension B" },
+ ["combiningdiacriticalmarks"] = { 0x00300, 0x0036F, "Combining Diacritical Marks" },
+ ["combiningdiacriticalmarksforsymbols"] = { 0x020D0, 0x020FF, "Combining Diacritical Marks for Symbols" },
+ ["combiningdiacriticalmarkssupplement"] = { 0x01DC0, 0x01DFF, "Combining Diacritical Marks Supplement" },
+ ["combininghalfmarks"] = { 0x0FE20, 0x0FE2F, "Combining Half Marks" },
+ ["controlpictures"] = { 0x02400, 0x0243F, "Control Pictures" },
+ ["coptic"] = { 0x02C80, 0x02CFF, "Coptic" },
+ ["countingrodnumerals"] = { 0x1D360, 0x1D37F, "Counting Rod Numerals" },
+ ["cuneiform"] = { 0x12000, 0x123FF, "Cuneiform" },
+ ["cuneiformnumbersandpunctuation"] = { 0x12400, 0x1247F, "Cuneiform Numbers and Punctuation" },
+ ["currencysymbols"] = { 0x020A0, 0x020CF, "Currency Symbols" },
+ ["cypriotsyllabary"] = { 0x10800, 0x1083F, "Cypriot Syllabary" },
+ ["cyrillic"] = { 0x00400, 0x004FF, "Cyrillic" },
+ ["cyrillicextendeda"] = { 0x02DE0, 0x02DFF, "Cyrillic Extended-A" },
+ ["cyrillicextendedb"] = { 0x0A640, 0x0A69F, "Cyrillic Extended-B" },
+ ["cyrillicsupplement"] = { 0x00500, 0x0052F, "Cyrillic Supplement" },
+ ["deseret"] = { 0x10400, 0x1044F, "Deseret" },
+ ["devanagari"] = { 0x00900, 0x0097F, "Devanagari" },
+ ["dingbats"] = { 0x02700, 0x027BF, "Dingbats" },
+ ["dominotiles"] = { 0x1F030, 0x1F09F, "Domino Tiles" },
+ ["enclosedalphanumerics"] = { 0x02460, 0x024FF, "Enclosed Alphanumerics" },
+ ["enclosedcjklettersandmonths"] = { 0x03200, 0x032FF, "Enclosed CJK Letters and Months" },
+ ["ethiopic"] = { 0x01200, 0x0137F, "Ethiopic" },
+ ["ethiopicextended"] = { 0x02D80, 0x02DDF, "Ethiopic Extended" },
+ ["ethiopicsupplement"] = { 0x01380, 0x0139F, "Ethiopic Supplement" },
+ ["generalpunctuation"] = { 0x02000, 0x0206F, "General Punctuation" },
+ ["geometricshapes"] = { 0x025A0, 0x025FF, "Geometric Shapes" },
+ ["georgian"] = { 0x010A0, 0x010FF, "Georgian" },
+ ["georgiansupplement"] = { 0x02D00, 0x02D2F, "Georgian Supplement" },
+ ["glagolitic"] = { 0x02C00, 0x02C5F, "Glagolitic" },
+ ["gothic"] = { 0x10330, 0x1034F, "Gothic" },
+ ["greekandcoptic"] = { 0x00370, 0x003FF, "Greek and Coptic" },
+ ["greekextended"] = { 0x01F00, 0x01FFF, "Greek Extended" },
+ ["gujarati"] = { 0x00A80, 0x00AFF, "Gujarati" },
+ ["gurmukhi"] = { 0x00A00, 0x00A7F, "Gurmukhi" },
+ ["halfwidthandfullwidthforms"] = { 0x0FF00, 0x0FFEF, "Halfwidth and Fullwidth Forms" },
+ ["hangulcompatibilityjamo"] = { 0x03130, 0x0318F, "Hangul Compatibility Jamo" },
+ ["hanguljamo"] = { 0x01100, 0x011FF, "Hangul Jamo" },
+ ["hangulsyllables"] = { 0x0AC00, 0x0D7AF, "Hangul Syllables" },
+ ["hanunoo"] = { 0x01720, 0x0173F, "Hanunoo" },
+ ["hebrew"] = { 0x00590, 0x005FF, "Hebrew" },
+ ["highprivateusesurrogates"] = { 0x0DB80, 0x0DBFF, "High Private Use Surrogates" },
+ ["highsurrogates"] = { 0x0D800, 0x0DB7F, "High Surrogates" },
+ ["hiragana"] = { 0x03040, 0x0309F, "Hiragana" },
+ ["ideographicdescriptioncharacters"] = { 0x02FF0, 0x02FFF, "Ideographic Description Characters" },
+ ["ipaextensions"] = { 0x00250, 0x02AF, "IPA Extensions" },
+ ["kanbun"] = { 0x03190, 0x0319F, "Kanbun" },
+ ["kangxiradicals"] = { 0x02F00, 0x02FDF, "Kangxi Radicals" },
+ ["kannada"] = { 0x00C80, 0x00CFF, "Kannada" },
+ ["katakana"] = { 0x030A0, 0x030FF, "Katakana" },
+ ["katakanaphoneticextensions"] = { 0x031F0, 0x031FF, "Katakana Phonetic Extensions" },
+ ["kayahli"] = { 0x0A900, 0x0A92F, "Kayah Li" },
+ ["kharoshthi"] = { 0x10A00, 0x10A5F, "Kharoshthi" },
+ ["khmer"] = { 0x01780, 0x017FF, "Khmer" },
+ ["khmersymbols"] = { 0x019E0, 0x019FF, "Khmer Symbols" },
+ ["lao"] = { 0x00E80, 0x00EFF, "Lao" },
+ ["latinextendeda"] = { 0x00100, 0x0017F, "Latin Extended-A" },
+ ["latinextendedadditional"] = { 0x01E00, 0x01EFF, "Latin Extended Additional" },
+ ["latinextendedb"] = { 0x00180, 0x0024F, "Latin Extended-B" },
+ ["latinextendedc"] = { 0x02C60, 0x02C7F, "Latin Extended-C" },
+ ["latinextendedd"] = { 0x0A720, 0x0A7FF, "Latin Extended-D" },
+ ["latinsupplement"] = { 0x00080, 0x000FF, "Latin-1 Supplement" },
+ ["lepcha"] = { 0x01C00, 0x01C4F, "Lepcha" },
+ ["letterlikesymbols"] = { 0x02100, 0x0214F, "Letterlike Symbols" },
+ ["limbu"] = { 0x01900, 0x0194F, "Limbu" },
+ ["linearbideograms"] = { 0x10080, 0x100FF, "Linear B Ideograms" },
+ ["linearbsyllabary"] = { 0x10000, 0x1007F, "Linear B Syllabary" },
+ ["lowsurrogates"] = { 0x0DC00, 0x0DFFF, "Low Surrogates" },
+ ["lycian"] = { 0x10280, 0x1029F, "Lycian" },
+ ["lydian"] = { 0x10920, 0x1093F, "Lydian" },
+ ["mahjongtiles"] = { 0x1F000, 0x1F02F, "Mahjong Tiles" },
+ ["malayalam"] = { 0x00D00, 0x00D7F, "Malayalam" },
+ ["mathematicalalphanumericsymbols"] = { 0x1D400, 0x1D7FF, "Mathematical Alphanumeric Symbols" },
+ ["mathematicaloperators"] = { 0x02200, 0x022FF, "Mathematical Operators" },
+ ["miscellaneousmathematicalsymbolsa"] = { 0x027C0, 0x027EF, "Miscellaneous Mathematical Symbols-A" },
+ ["miscellaneousmathematicalsymbolsb"] = { 0x02980, 0x029FF, "Miscellaneous Mathematical Symbols-B" },
+ ["miscellaneoussymbols"] = { 0x02600, 0x026FF, "Miscellaneous Symbols" },
+ ["miscellaneoussymbolsandarrows"] = { 0x02B00, 0x02BFF, "Miscellaneous Symbols and Arrows" },
+ ["miscellaneoustechnical"] = { 0x02300, 0x023FF, "Miscellaneous Technical" },
+ ["modifiertoneletters"] = { 0x0A700, 0x0A71F, "Modifier Tone Letters" },
+ ["mongolian"] = { 0x01800, 0x018AF, "Mongolian" },
+ ["musicalsymbols"] = { 0x1D100, 0x1D1FF, "Musical Symbols" },
+ ["myanmar"] = { 0x01000, 0x0109F, "Myanmar" },
+ ["newtailue"] = { 0x01980, 0x019DF, "New Tai Lue" },
+ ["nko"] = { 0x007C0, 0x007FF, "NKo" },
+ ["numberforms"] = { 0x02150, 0x0218F, "Number Forms" },
+ ["ogham"] = { 0x01680, 0x0169F, "Ogham" },
+ ["olchiki"] = { 0x01C50, 0x01C7F, "Ol Chiki" },
+ ["olditalic"] = { 0x10300, 0x1032F, "Old Italic" },
+ ["oldpersian"] = { 0x103A0, 0x103DF, "Old Persian" },
+ ["opticalcharacterrecognition"] = { 0x02440, 0x0245F, "Optical Character Recognition" },
+ ["oriya"] = { 0x00B00, 0x00B7F, "Oriya" },
+ ["osmanya"] = { 0x10480, 0x104AF, "Osmanya" },
+ ["phagspa"] = { 0x0A840, 0x0A87F, "Phags-pa" },
+ ["phaistosdisc"] = { 0x101D0, 0x101FF, "Phaistos Disc" },
+ ["phoenician"] = { 0x10900, 0x1091F, "Phoenician" },
+ ["phoneticextensions"] = { 0x01D00, 0x01D7F, "Phonetic Extensions" },
+ ["phoneticextensionssupplement"] = { 0x01D80, 0x01DBF, "Phonetic Extensions Supplement" },
+ ["privateusearea"] = { 0x0E000, 0x0F8FF, "Private Use Area" },
+ ["rejang"] = { 0x0A930, 0x0A95F, "Rejang" },
+ ["runic"] = { 0x016A0, 0x016FF, "Runic" },
+ ["saurashtra"] = { 0x0A880, 0x0A8DF, "Saurashtra" },
+ ["shavian"] = { 0x10450, 0x1047F, "Shavian" },
+ ["sinhala"] = { 0x00D80, 0x00DFF, "Sinhala" },
+ ["smallformvariants"] = { 0x0FE50, 0x0FE6F, "Small Form Variants" },
+ ["spacingmodifierletters"] = { 0x002B0, 0x002FF, "Spacing Modifier Letters" },
+ ["specials"] = { 0x0FFF0, 0x0FFFF, "Specials" },
+ ["sundanese"] = { 0x01B80, 0x01BBF, "Sundanese" },
+ ["superscriptsandsubscripts"] = { 0x02070, 0x0209F, "Superscripts and Subscripts" },
+ ["supplementalarrowsa"] = { 0x027F0, 0x027FF, "Supplemental Arrows-A" },
+ ["supplementalarrowsb"] = { 0x02900, 0x0297F, "Supplemental Arrows-B" },
+ ["supplementalmathematicaloperators"] = { 0x02A00, 0x02AFF, "Supplemental Mathematical Operators" },
+ ["supplementalpunctuation"] = { 0x02E00, 0x02E7F, "Supplemental Punctuation" },
+ ["supplementaryprivateuseareaa"] = { 0xF0000, 0xFFFFF, "Supplementary Private Use Area-A" },
+ ["supplementaryprivateuseareab"] = { 0x100000,0x10FFFF,"Supplementary Private Use Area-B" },
+ ["sylotinagri"] = { 0x0A800, 0x0A82F, "Syloti Nagri" },
+ ["syriac"] = { 0x00700, 0x0074F, "Syriac" },
+ ["tagalog"] = { 0x01700, 0x0171F, "Tagalog" },
+ ["tagbanwa"] = { 0x01760, 0x0177F, "Tagbanwa" },
+ ["tags"] = { 0xE0000, 0xE007F, "Tags" },
+ ["taile"] = { 0x01950, 0x0197F, "Tai Le" },
+ ["taixuanjingsymbols"] = { 0x1D300, 0x1D35F, "Tai Xuan Jing Symbols" },
+ ["tamil"] = { 0x00B80, 0x00BFF, "Tamil" },
+ ["telugu"] = { 0x00C00, 0x00C7F, "Telugu" },
+ ["thaana"] = { 0x00780, 0x007BF, "Thaana" },
+ ["thai"] = { 0x00E00, 0x00E7F, "Thai" },
+ ["tibetan"] = { 0x00F00, 0x00FFF, "Tibetan" },
+ ["tifinagh"] = { 0x02D30, 0x02D7F, "Tifinagh" },
+ ["ugaritic"] = { 0x10380, 0x1039F, "Ugaritic" },
+ ["unifiedcanadianaboriginalsyllabics"] = { 0x01400, 0x0167F, "Unified Canadian Aboriginal Syllabics" },
+ ["vai"] = { 0x0A500, 0x0A63F, "Vai" },
+ ["variationselectors"] = { 0x0FE00, 0x0FE0F, "Variation Selectors" },
+ ["variationselectorssupplement"] = { 0xE0100, 0xE01EF, "Variation Selectors Supplement" },
+ ["verticalforms"] = { 0x0FE10, 0x0FE1F, "Vertical Forms" },
+ ["yijinghexagramsymbols"] = { 0x04DC0, 0x04DFF, "Yijing Hexagram Symbols" },
+ ["yiradicals"] = { 0x0A490, 0x0A4CF, "Yi Radicals" },
+ ["yisyllables"] = { 0x0A000, 0x0A48F, "Yi Syllables" },
}
function characters.getrange(name)
- local tag = name:lower()
- tag = name:gsub("[^a-z]", "")
+ local tag = lower(name)
+ tag = gsub(name,"[^a-z]", "")
local range = characters.blocks[tag]
if range then
return range[1], range[2], range[3]
end
- name = name:gsub('"',"0x") -- goodie: tex hex notation
- local start, stop = name:match("^(.-)[%-%:](.-)$")
+ name = gsub(name,'"',"0x") -- goodie: tex hex notation
+ local start, stop = match(name,"^(.-)[%-%:](.-)$")
if start and stop then
start, stop = tonumber(start,16) or tonumber(start), tonumber(stop,16) or tonumber(stop)
if start and stop then
@@ -252,7 +288,16 @@ characters.categories = {
--~ characters: ll lm lo lt lu mn nl no pc pd pe pf pi po ps sc sk sm so
characters.is_character = table.tohash {
- "ll","lm","lo","lt","lu","mn","nl","no","pc","pd","pe","pf","pi","po","ps","sc","sk","sm","so"
+ "lu","ll","lt","lm","lo",
+ "nd","nl","no",
+ "mn",
+ "nl","no",
+ "pc","pd","ps","pe","pi","pf","po",
+ "sm","sc","sk","so"
+}
+
+characters.is_letter = table.tohash {
+ "ll","lm","lo","lt","lu"
}
characters.is_command = table.tohash {
@@ -296,34 +341,23 @@ function table.set_empty_metatable(t)
setmetatable(t,_empty_table_)
end
-table.set_empty_metatable(characters.data)
+table.set_empty_metatable(data)
--[[ldx--
<p>At this point we assume that the big data table is loaded. From this
table we derive a few more.</p>
--ldx]]--
--- used ?
-
-characters.unicodes = characters.unicodes or { }
-characters.utfcodes = characters.utfcodes or { }
-characters.enccodes = characters.enccodes or { }
-characters.fallbacks = characters.fallbacks or { }
-characters.directions = characters.directions or { }
-
-function characters.context.rehash()
- local unicodes, utfcodes, enccodes, fallbacks, directions = characters.unicodes, characters.utfcodes, characters.enccodes, characters.fallbacks, characters.directions
- for k,v in pairs(characters.data) do
- local contextname, adobename, specials = v.contextname, v.adobename, v.specials
- if contextname then
- local slot = v.unicodeslot
- unicodes[contextname] = slot
- utfcodes[contextname] = utfchar(slot)
- end
- local encname = adobename or contextname
- if encname then
- enccodes[encname] = k
- end
+if not characters.fallbacks then
+
+ characters.fallbacks = { }
+ characters.directions = { }
+
+ local fallbacks = characters.fallbacks
+ local directions = characters.directions
+
+ for k,v in next, data do
+ local specials = v.specials
if specials and specials[1] == "compat" and specials[2] == 0x0020 and specials[3] then
local s = specials[3]
fallbacks[k] = s
@@ -331,101 +365,92 @@ function characters.context.rehash()
end
directions[k] = v.direction
end
- for name,code in pairs(characters.synonyms) do
- if not enccodes[name] then enccodes[name] = code end
- end
-end
--- maybe some day, no significate speed up now
+end
---~ input.storage.register(false, "characters.unicodes", characters.unicodes, "characters.unicodes")
---~ input.storage.register(false, "characters.utfcodes", characters.utfcodes, "characters.utfcodes")
---~ input.storage.register(false, "characters.enccodes", characters.enccodes, "characters.enccodes")
---~ input.storage.register(false, "characters.fallbacks", characters.fallbacks, "characters.fallbacks")
---~ input.storage.register(false, "characters.directions", characters.directions, "characters.directions")
+storage.register("characters.fallbacks", characters.fallbacks, "characters.fallbacks")
+storage.register("characters.directions", characters.directions, "characters.directions")
--[[ldx--
<p>The <type>context</type> namespace is used to store methods and data
which is rather specific to <l n='context'/>.</p>
--ldx]]--
-function characters.context.show(n)
- local n = characters.number(n)
- local d = characters.data[n]
- if d then
- local function entry(label,name)
- texsprint(tex.ctxcatcodes,format("\\NC %s\\NC %s\\NC\\NR",label,characters.valid(d[name])))
- end
- texsprint(tex.ctxcatcodes,"\\starttabulate[|Tl|Tl|]")
- entry("unicode index" , "unicodeslot")
- entry("context name" , "contextname")
- entry("adobe name" , "adobename")
- entry("category" , "category")
- entry("description" , "description")
- entry("uppercase code", "uccode")
- entry("lowercase code", "lccode")
- entry("specials" , "specials")
- texsprint(tex.ctxcatcodes,"\\stoptabulate ")
- end
-end
-
--[[ldx--
<p>Instead of using a <l n='tex'/> file to define the named glyphs, we
use the table. After all, we have this information available anyway.</p>
--ldx]]--
function characters.makeactive(n,name) -- let ?
- texsprint(tex.ctxcatcodes,format("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name))
+ texsprint(ctxcatcodes,format("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name))
end
function tex.uprint(n)
- texsprint(tex.ctxcatcodes,utfchar(n))
+ texsprint(ctxcatcodes,utfchar(n))
end
-function characters.context.define(tobelettered, tobeactivated)
- local unicodes, utfcodes = characters.unicodes, characters.utfcodes
- local tc = tex.ctxcatcodes
- local is_character, is_command = characters.is_character, characters.is_command
+local template_a = "\\startextendcatcodetable{%s}\\chardef\\l=11\\chardef\\a=13\\let\\c\\catcode%s\\let\\a\\undefined\\let\\l\\undefined\\let\\c\\undefined\\stopextendcatcodetable"
+local template_b = "\\chardef\\l=11\\chardef\\a=13\\let\\c\\catcode%s\\let\\a\\undefined\\let\\l\\undefined\\let\\c\\undefined"
+
+-- we need a function for setting the codes ....
+
+function characters.define(tobelettered, tobeactivated) -- catcodetables
+ local is_character, is_command, is_letter = characters.is_character, characters.is_command, characters.is_letter
local lettered, activated = { }, { }
- for u, chr in pairs(characters.data) do
+ for u, chr in next, data do
+ -- we can use a macro instead of direct settings
local fallback = chr.fallback
if fallback then
- texsprint("{\\catcode"..u.."=13\\unexpanded\\gdef "..utfchar(u).."{\\checkedchar{"..u.."}{"..fallback.."}}}")
- activated[#activated+1] = "\\c"..u.."=".."13"
+ texprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\checkedchar{",u,"}{",fallback,"}}}")
+ activated[#activated+1] = "\\c"..u.."\\a"
else
local contextname = chr.contextname
local category = chr.category
if contextname then
if is_character[category] then
-- by this time, we're still in normal catcode mode
+ -- subtle: not "\\",contextname but "\\"..contextname
if chr.unicodeslot < 128 then
- texsprint(tc, "\\chardef\\" .. contextname .. "=" .. u) -- unicodes[contextname])
+ texprint(ctxcatcodes, "\\chardef\\"..contextname,"=",u)
else
- texsprint(tc, "\\let\\" .. contextname .. "=" .. utfchar(u)) -- utfcodes[contextname])
- lettered[#lettered+1] = "\\c"..u.."=".."11"
+ texprint(ctxcatcodes, "\\let\\"..contextname,"=",utfchar(u))
+ if is_letter[category] then
+ lettered[#lettered+1] = "\\c"..u.."\\l"
+ end
end
elseif is_command[category] then
- texsprint("{\\catcode"..u.."=13\\unexpanded\\gdef "..utfchar(u).."{\\"..contextname.."}}")
- activated[#activated+1] = "\\c"..u.."=".."13"
+ texprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\"..contextname,"}}")
+ activated[#activated+1] = "\\c"..u.."\\a"
end
- else
- if is_character[category] then
- if u >= 128 and u <= 65536 then
- lettered[#lettered+1] = "\\c"..u.."=".."11"
- end
+ elseif is_letter[category] then
+ if u >= 128 and u <= 65536 then -- catch private mess
+ lettered[#lettered+1] = "\\c"..u.."\\l"
end
end
end
+ if chr.range then
+ lettered[#lettered+1] = format('\\dofastrecurse{"%05X}{"%05X}{1}{\\c\\fastrecursecounter\\l}',u,chr.range)
+ end
end
- lettered[#lettered+1] = "\\c"..0x200C.."=".."11" -- non-joiner
- lettered[#lettered+1] = "\\c"..0x200D.."=".."11" -- joiner
- lettered = concat(lettered)
- for _, i in ipairs(tobelettered or { }) do
- texsprint(tc,format("\\startextendcatcodetable{%s}\\let\\c\\catcode%s\\stopextendcatcodetable",i,lettered))
+ -- if false then
+ lettered[#lettered+1] = "\\c"..0x200C.."\\l" -- non-joiner
+ lettered[#lettered+1] = "\\c"..0x200D.."\\l" -- joiner
+ -- fi
+ if tobelettered then
+ lettered = concat(lettered)
+ if true then
+ texsprint(ctxcatcodes,format(template_b,lettered))
+ else
+ for l=1,#tobelettered do
+ texsprint(ctxcatcodes,format(template_a,tobelettered[l],lettered))
+ end
+ end
end
- activated = concat(activated)
- for _, i in ipairs(tobeactivated or { } ) do
- texsprint(tc,format("\\startextendcatcodetable{%s}\\let\\c\\catcode%s\\stopextendcatcodetable",i,activated))
+ if tobeactivated then
+ activated = concat(activated)
+ for a=1,#tobeactivated do
+ texsprint(ctxcatcodes,format(template_a,tobeactivated[a],activated))
+ end
end
end
@@ -439,15 +464,22 @@ end
<p>Setting the lccodes is also done in a loop over the data table.</p>
--ldx]]--
+-- we need a function ...
+
function characters.setcodes()
- local tc = tex.ctxcatcodes
- for code, chr in pairs(characters.data) do
+ for code, chr in next, data do
local cc = chr.category
if cc == 'll' or cc == 'lu' or cc == 'lt' then
local lc, uc = chr.lccode, chr.uccode
if not lc then chr.lccode, lc = code, code end
if not uc then chr.uccode, uc = code, code end
- texsprint(tc, format("\\setcclcuc %i %i %i ",code,lc,uc))
+ texsprint(ctxcatcodes,format("\\setcclcuc{%i}{%i}{%i}",code,lc,uc))
+ end
+ if cc == "lu" then
+ texprint(ctxcatcodes,"\\sfcode ",code,"999 ")
+ end
+ if cc == "lo" and chr.range then
+ texsprint(ctxcatcodes,format('\\dofastrecurse{"%05X}{"%05X}{1}{\\setcclcucself\\fastrecursecounter}',code,chr.range))
end
end
end
@@ -480,21 +512,12 @@ end
characters.valid = characters.is_valid
--[[ldx--
-<p>The next method is used when constructing the main table, although nowadays
-we do this in one step. The index can be a string or a number.</p>
---ldx]]--
-
-function characters.define(c)
- characters.data[characters.number(c.unicodeslot)] = c
-end
-
---[[ldx--
<p></p>
--ldx]]--
-- set a table entry; index is number (can be different from unicodeslot)
function characters.set(n, c)
- characters.data[characters.number(n)] = c
+ data[characters.number(n)] = c
end
--[[ldx--
@@ -503,7 +526,7 @@ can be different (not likely).</p>
--ldx]]--
function characters.get(n)
- return characters.data[characters.number(n)]
+ return data[characters.number(n)]
end
--[[ldx--
@@ -512,43 +535,43 @@ to the checking.</p>
--ldx]]--
function characters.hexindex(n)
- return format("%04X", characters.valid(characters.data[characters.number(n)].unicodeslot))
+ return format("%04X", characters.valid(data[characters.number(n)].unicodeslot))
end
function characters.contextname(n)
- return characters.valid(characters.data[characters.number(n)].contextname)
+ return characters.valid(data[characters.number(n)].contextname)
end
function characters.adobename(n)
- return characters.valid(characters.data[characters.number(n)].adobename)
+ return characters.valid(data[characters.number(n)].adobename)
end
function characters.description(n)
- return characters.valid(characters.data[characters.number(n)].description)
+ return characters.valid(data[characters.number(n)].description)
end
function characters.category(n)
- return characters.valid(characters.data[characters.number(n)].category)
+ return characters.valid(data[characters.number(n)].category)
end
--[[ldx--
<p>Requesting lower and uppercase codes:</p>
--ldx]]--
-function characters.uccode(n) return characters.data[n].uccode or n end
-function characters.lccode(n) return characters.data[n].lccode or n end
+function characters.uccode(n) return data[n].uccode or n end
+function characters.lccode(n) return data[n].lccode or n end
function characters.flush(n)
- local c = characters.data[n]
+ local c = data[n]
if c and c.contextname then
- texsprint(tex.texcatcodes, "\\"..c.contextname)
+ texsprint(texcatcodes, "\\"..c.contextname)
else
- texsprint(unicode.utf8.char(n))
+ texsprint(utfchar(n))
end
end
function characters.shape(n)
- local shcode = characters.data[n].shcode
+ local shcode = data[n].shcode
if not shcode then
return n, nil
elseif type(shcode) == "table" then
@@ -564,43 +587,29 @@ end
function characters.is_of_category(token,category)
if type(token) == "string" then
- return characters.data[utfbyte(token)].category == category
+ return data[utfbyte(token)].category == category
else
- return characters.data[token].category == category
+ return data[token].category == category
end
end
function characters.i_is_of_category(i,category) -- by index (number)
- local cd = characters.data[i]
+ local cd = data[i]
return cd and cd.category == category
end
function characters.n_is_of_category(n,category) -- by name (string)
- local cd = characters.data[utfbyte(n)]
+ local cd = data[utfbyte(n)]
return cd and cd.category == category
end
---[[ldx--
-<p>The following code is kind of messy. It is used to generate the right
-unicode reference tables.</p>
---ldx]]--
-
-function characters.setpdfunicodes()
---~ local tc = tex.ctxcatcodes
---~ for _,v in pairs(characters.data) do
---~ if v.adobename then
---~ texsprint(tc,format("\\pdfglyphtounicode{%s}{%04X}", v.adobename, v.unicodeslot))
---~ end
---~ end
-end
-
-- xml support
characters.active_offset = 0x10000
xml.entities = xml.entities or { }
-input.storage.register(false,"xml/entities",xml.entities,"xml.entities") -- this will move to lxml
+storage.register("xml/entities",xml.entities,"xml.entities") -- this will move to lxml
function characters.remapentity(chr,slot)
texsprint(format("{\\catcode%s=13\\xdef%s{\\string%s}}",slot,utfchar(slot),chr))
diff --git a/tex/context/base/char-ini.tex b/tex/context/base/char-ini.tex
index ba1ecf15b..b79e44857 100644
--- a/tex/context/base/char-ini.tex
+++ b/tex/context/base/char-ini.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=char-ini,
%D version=2006.08.20,
-%D title=\CONTEXT\ Character Macros,
-%D subtitle=Character Support (Initialization),
+%D title=\CONTEXT\ Character Support,
+%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,14 +11,12 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Character Support (initialization)}
+\writestatus{loading}{ConTeXt Character Support / Initialization}
\registerctxluafile{char-def}{1.001} % let's load this one first
\registerctxluafile{char-ini}{1.001}
\registerctxluafile{char-cmp}{1.001} % maybe we will load this someplace else
-\registerctxluafile{char-tok}{1.001} % maybe we will load this someplace else
-\registerctxluafile{char-map}{1.001}
-\registerctxluafile{char-syn}{1.001}
+\registerctxluafile{char-map}{1.001} % maybe we will load this someplace else
\unprotect
@@ -31,18 +29,15 @@
\def\checkedchar {\relax\ifmmode\expandafter\checkedmathchar\else\expandafter\checkedtextchar\fi} % #1#2
\def\checkedmathchar#1#2{#2}
\def\checkedtextchar #1{\iffontchar\font#1 \expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi{\char#1}}
-\def\setcclcuc #1 #2 #3 {\global\catcode#1=11 \global\lccode #1=#2 \global\uccode #1=#3 }
%D The codes are stored in the format, so we don't need to reinitialize
-%D them (unless of course we have adapted the table).
+%D them (unless of course we have adapted the table). It is on the agenda
+%D to do this with \type {tex.lccode} cum suis once they're available.
-\ctxlua{characters.setcodes()}
+\def\setcclcuc#1#2#3{\global\catcode#1=11 \global\lccode #1=#2 \global\uccode #1=#3 }
+\def\setcclcucself#1{\global\catcode#1=11 \global\lccode #1=#1 \global\uccode #1=#1 }
-% obsolete
-%
-% \startruntimeluacode
-% \ctxlua{characters.setpdfunicodes()}% pdftounicode mappings can only be done runtime
-% \stopruntimeluacode
+\ctxlua{characters.setcodes()}
%D There may be a problem with the turkisch patterns. By now it's taken care of in
%D ctxtools (thanks to Mojca). There seems to be a bug in the patterns (^^11 refers
@@ -51,16 +46,8 @@
% \setcclcuc "201C "201C "201C
% \setcclcuc "201D "201D "201D
-% definitions
-
-\startruntimectxluacode
- characters.context.rehash()
-\stopruntimectxluacode
-
-% \ctxlua{characters.context.rehash()}
-
\ctxlua {
- characters.context.define(
+ characters.define(
{ % letter catcodes
\number\texcatcodes,
\number\ctxcatcodes,
@@ -85,10 +72,3 @@
}
\protect \endinput
-
-% \ctxlua{characters.context.show(123)}
-% \ctxlua{characters.context.show(0x7B)}
-% \ctxlua{characters.context.show("7B")}
-
-% \dostepwiserecurse{`A}{`Z}{1}
-% {\ctxlua{characters.context.show(\recurselevel)}}
diff --git a/tex/context/base/char-map.lua b/tex/context/base/char-map.lua
index e463158c5..0d8422bc2 100644
--- a/tex/context/base/char-map.lua
+++ b/tex/context/base/char-map.lua
@@ -1,15 +1,12 @@
--- filename : char-map.lua
--- comment : companion to char-def.tex (in ConTeXt)
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
--- remark : derived from 'specialcasing.txt', se Arthurs comments in char-map.txt
-
-
-if not versions then versions = { } end versions['char-map'] = 1.001
-if not characters then characters = { } end
+if not modules then modules = { } end modules ['char-map'] = {
+ version = 1.001,
+ comment = "companion to char-ini.tex",
+ author = "Hans Hagen & Arthur Reutenauer",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+characters = characters or { }
characters.casemap={
[0x0049]={
diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua
index 273923c36..7dd5d914f 100644
--- a/tex/context/base/char-utf.lua
+++ b/tex/context/base/char-utf.lua
@@ -1,6 +1,6 @@
if not modules then modules = { } end modules ['char-utf'] = {
version = 1.001,
- comment = "companion to char-ini.tex",
+ comment = "companion to char-utf.tex",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
@@ -19,9 +19,11 @@ in special kinds of output (for instance <l n='pdf'/>).</p>
over a string.</p>
--ldx]]--
-local concat = table.concat
+local utf = unicode.utf8
+local concat, gmatch = table.concat, string.gmatch
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
-utf = utf or unicode.utf8
+local ctxcatcodes = tex.ctxcatcodes
characters = characters or { }
characters.graphemes = characters.graphemes or { }
@@ -38,17 +40,12 @@ local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub
--[[ldx--
<p>It only makes sense to collapse at runtime, since we don't expect
-source code to depend on collapsing:</p>
-
-<typing>
-characters.filters.utf.collapsing = true
-input.filters.utf_translator = characters.filters.utf.collapse
-</typing>
+source code to depend on collapsing.</p>
--ldx]]--
function utffilters.initialize()
if utffilters.collapsing and not utffilters.initialized then
- for k,v in pairs(characters.data) do
+ for k,v in next, characters.data do
-- using vs and first testing for length is faster (.02->.01 s)
local vs = v.specials
if vs and #vs == 3 and vs[1] == 'char' then
@@ -86,7 +83,7 @@ function utffilters.collapse(str) -- old one
utffilters.initialize()
end
local tokens, first, done = { }, false, false
- for second in str:utfcharacters() do
+ for second in utfcharacters(str) do
local cgf = graphemes[first]
if cgf and cgf[second] then
first, done = cgf[second], true
@@ -132,7 +129,7 @@ utffilters.private = {
local low = utffilters.private.low
local high = utffilters.private.high
local escapes = utffilters.private.escapes
-local special = "~#$%^&_{}\\"
+local special = "~#$%^&_{}\\|"
function utffilters.private.set(ch)
local cb
@@ -154,7 +151,7 @@ function utffilters.private.escape(str) return utfgsub(str,"(.)", escapes) end
local set = utffilters.private.set
-for ch in special:gmatch(".") do set(ch) end
+for ch in gmatch(special,".") do set(ch) end
--[[ldx--
<p>We get a more efficient variant of this when we integrate
@@ -186,7 +183,7 @@ function utffilters.collapse(str) -- not really tested (we could preallocate a t
cf.initialize()
end
local tokens, first, done, n = { }, false, false, 0
- for second in str:utfcharacters() do
+ for second in utfcharacters(str) do
if done then
local crs = cr[second]
if crs then
@@ -208,7 +205,7 @@ function utffilters.collapse(str) -- not really tested (we could preallocate a t
else
local crs = cr[second]
if crs then
- for s in str:utfcharacters() do
+ for s in utfcharacters(str) do
if n == 1 then
break
else
@@ -222,7 +219,7 @@ function utffilters.collapse(str) -- not really tested (we could preallocate a t
else
local cgf = graphemes[first]
if cgf and cgf[second] then
- for s in str:utfcharacters() do
+ for s in utfcharacters(str) do
if n == 1 then
break
else
@@ -248,120 +245,29 @@ function utffilters.collapse(str) -- not really tested (we could preallocate a t
end
--[[ldx--
-<p>In the beginning of <l n='luatex'/> we experimented with a sequence
-of filters so that we could manipulate the input stream. However, since
-this is a partial solution (not taking macro expansion into account)
-and since it may interfere with non-text, we will not use this feature
-by default.</p>
-
-<typing>
-utffilters.collapsing = true
-characters.filters.append(utffilters.collapse)
-characters.filters.activated = true
-callback.register('process_input_buffer', characters.filters.process)
-</typing>
-
-<p>The following helper functions may disappear (or become optional)
-in the future. Well, they are now.</p>
+<p>Next we implement some commands that are used in the user interface.</p>
--ldx]]--
---[[obsolete--
-
-characters.filters.sequences = characters.filters.sequences or { }
-characters.filters.activated = false
-
-function characters.filters.append(name)
- table.insert(characters.filters.sequences,name)
-end
-
-function characters.filters.prepend(name)
- table.insert(characters.filters.sequences,1,name)
-end
-
-function characters.filters.remove(name)
- for k,v in ipairs(characters.filters.sequences) do
- if v == name then
- table.remove(characters.filters.sequences,k)
- end
- end
-end
-
-function characters.filters.replace(name_1,name_2)
- for k,v in ipairs(characters.filters.sequences) do
- if v == name_1 then
- characters.filters.sequences[k] = name_2
- break
- end
- end
-end
-
-function characters.filters.insert_before(name_1,name_2)
- for k,v in ipairs(characters.filters.sequences) do
- if v == name_1 then
- table.insert(characters.filters.sequences,k,name_2)
- break
- end
- end
-end
+commands = commands or { }
-function characters.filters.insert_after(name_1,name_2)
- for k,v in ipairs(characters.filters.sequences) do
- if v == name_1 then
- table.insert(characters.filters.sequences,k+1,name_2)
- break
- end
- end
+function commands.uchar(first,second)
+ tex.sprint(ctxcatcodes,utfchar(first*256+second))
end
-function characters.filters.list(separator)
- concat(characters.filters.sequences,seperator or ' ')
-end
-
-function characters.filters.process(str)
- if characters.filters.activated then
- for _,v in ipairs(characters.filters.sequences) do
- str = v(str)
- end
- return str
- else
- return nil -- luatex callback optimalisation
- end
-end
-
---obsolete]]--
-
--[[ldx--
-<p>The following code is no longer needed and replaced by token
-collectors somehwere else.</p>
+<p>A few helpers (used to be <t>luat-uni<t/>).</p>
--ldx]]--
---[[obsolete--
-
-characters.filters.collector = { }
-characters.filters.collector.data = { }
-characters.filters.collector.collecting = false
-
-function characters.filters.collector.reset()
- characters.filters.collector.data = { }
-end
-
-function characters.filters.collector.flush(separator)
- tex.sprint(concat(characters.filters.collector.data,separator))
-end
-
-function characters.filters.collector.prune(n)
- for i=1,n do
- table.remove(characters.filters.collector.data,-1)
+function utf.split(str)
+ local t = { }
+ for snippet in utfcharacters(str) do
+ t[#t+1] = snippet
end
+ return t
end
-function characters.filters.collector.numerate(str)
- if characters.filters.collector.collecting then
- table.insert(characters.filters.collector.data,(unicode.utf8.gsub(str,"(.)", function(c)
- return ("0x%04X "):format(unicode.utf8.byte(c))
- end)))
+function utf.each(str,fnc)
+ for snippet in utfcharacters(str) do
+ fnc(snippet)
end
- return str
end
-
---obsolete]]--
diff --git a/tex/context/base/char-utf.tex b/tex/context/base/char-utf.tex
index 2e7156962..d21cd842c 100644
--- a/tex/context/base/char-utf.tex
+++ b/tex/context/base/char-utf.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=char-utf,
%D version=2006.12.05,
-%D title=\CONTEXT\ Lua Macros,
-%D subtitle=Unicode Support (UTF),
+%D title=\CONTEXT\ Character Support,
+%D subtitle=Unicode UTF,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Unicode Support (utf)}
+\writestatus{loading}{ConTeXt Character Support / Unicode UTF}
%D After a bit of experimenting we reached a clean state where \UTF\
%D 8, 16 and 32 were supported as well as collapsing (combining
@@ -31,28 +31,10 @@
\appendtoks
\ctxlua {
characters.filters.utf.collapsing = true
- input.filters.utf_translator = characters.filters.utf.collapse
+ resolvers.install_text_filter('utf',characters.filters.utf.collapse)
}%
\to \everyjob
-% %D This is a hack, and only meant for special situations. We don't
-% %D support this in for instance verbatim. The active characters map
-% %D onto the \CONTEXT\ names and font handling etc. is up to the user.
-%
-% %D This feature is obsolete.
-%
-% \registerctxluafile{char-act}{1.001}
-%
-% \def\enableactiveutf {\ctxlua{characters.active.enable()}}
-% \def\disableactiveutf{\ctxlua{characters.active.disable()}}
-% \def\testactiveutf #1{\ctxlua{characters.active.test("#1")}}
-
-%D Usage:
-%D
-%D \starttyping
-%D \enableactiveutf \testactiveutf{eacute}
-%D \stoptyping
-
%D The next one influences input parsing.
%D
%D \starttyping
diff --git a/tex/context/base/chem-ini.lua b/tex/context/base/chem-ini.lua
new file mode 100644
index 000000000..27b734840
--- /dev/null
+++ b/tex/context/base/chem-ini.lua
@@ -0,0 +1,74 @@
+if not modules then modules = { } end modules ['chem-ini'] = {
+ version = 1.001,
+ comment = "companion to chem-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, texsprint = string.format, tex.sprint
+
+local trace_molecules = false trackers.register("chemistry.molecules", function(v) trace_molecules = v end)
+
+local ctxcatcodes = tex.ctxcatcodes
+
+chemicals = chemicals or { }
+
+--[[
+<p>The next code is an adaptation of code from Wolfgang Schuster
+as posted on the mailing list. This version supports nested
+braces and unbraced integers as scripts. We could consider
+spaces as terminals for them but first let collect a bunch
+of input then.</p>
+]]--
+
+-- some lpeg, maybe i'll make an syst-lpg module
+
+local lowercase = lpeg.R("az")
+local uppercase = lpeg.R("AZ")
+local backslash = lpeg.P("\\")
+local csname = backslash * lpeg.P(1) * (1-backslash)^0
+local plus = lpeg.P("+") / "\\textplus "
+local minus = lpeg.P("-") / "\\textminus "
+local digit = lpeg.R("09")
+local sign = plus + minus
+local cardinal = digit^1
+local integer = sign^0 * cardinal
+
+local leftbrace = lpeg.P("{")
+local rightbrace = lpeg.P("}")
+local nobrace = 1 - (leftbrace + rightbrace)
+local nested = lpeg.P { leftbrace * (csname + sign + nobrace + lpeg.V(1))^0 * rightbrace }
+local any = lpeg.P(1)
+
+local subscript = lpeg.P("_")
+local superscript = lpeg.P("^")
+local somescript = subscript + superscript
+
+--~ local content = lpeg.Cs(nested + integer + sign + any)
+local content = lpeg.Cs(csname + nested + sign + any)
+
+-- could be made more efficient
+
+local lowhigh = lpeg.Cc("\\lohi{%s}{%s}") * subscript * content * superscript * content / format
+local highlow = lpeg.Cc("\\hilo{%s}{%s}") * superscript * content * subscript * content / format
+local low = lpeg.Cc("\\low{%s}") * subscript * content / format
+local high = lpeg.Cc("\\high{%s}") * superscript * content / format
+local justtext = (1 - somescript)^1
+local parser = lpeg.Cs((csname + lowhigh + highlow + low + high + sign + any)^0)
+
+chemicals.moleculeparser = parser -- can be used to avoid functioncall
+
+function chemicals.molecule(str)
+ return parser:match(str)
+end
+
+function commands.molecule(str)
+ if trace_molecules then
+ local rep = parser:match(str)
+ logs.report("chemistry", "molecule %s => %s",str,rep)
+ texsprint(ctxcatcodes,rep)
+ else
+ texsprint(ctxcatcodes,parser:match(str))
+ end
+end
diff --git a/tex/context/base/chem-ini.mkiv b/tex/context/base/chem-ini.mkiv
new file mode 100644
index 000000000..b28e73e42
--- /dev/null
+++ b/tex/context/base/chem-ini.mkiv
@@ -0,0 +1,42 @@
+%D \module
+%D [ file=chem-ini,
+%D version=2008.03.06,
+%D subtitle=Chemistry,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Chemistry Macros / Initialization} % might become Inline
+
+\registerctxluafile{chem-ini}{1.001}
+
+\unprotect
+
+%D \macros
+%D {\molecule}
+%D
+%D Quick and dirty:
+%D
+%D \starttyping
+%D \def\molecule#1{$\enablesupersub\tf#1$}
+%D \stoptyping
+%D
+%D Using \LUA:
+%D
+%D \startbuffer
+%D \molecule{H_2SO_4^-2}
+%D \molecule{H_2SO_4^{-2}}
+%D \molecule{H_2SO_4^{-2{x}}}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\molecule#1{\ctxlua{commands.molecule(\!!bs#1\!!es)}}
+
+\protect \endinput
+
+
diff --git a/tex/context/base/chem-str-test.tex b/tex/context/base/chem-str-test.tex
new file mode 100644
index 000000000..fd6a8227a
--- /dev/null
+++ b/tex/context/base/chem-str-test.tex
@@ -0,0 +1,560 @@
+% Beware, integrated ppchtex support is incomplete and under
+% construction so when you depend on the full functionality
+% you need to use the module!
+%
+% For testing new functionality:
+%
+% \startMPextensions
+% input "mp-chem.mp" ;
+% \stopMPextensions
+% \startluacode
+% dofile(resolvers.find_file("chem-str.lua","tex"))
+% \stopluacode
+% \setbox\scratchbox\hbox{\startMPcode\stopMPcode}
+
+\enabletrackers[chemistry.structure]
+
+\starttext
+
+\defineprocessor[ch:r][color=red]
+\defineprocessor[ch:g][color=green]
+\defineprocessor[ch:b][color=blue]
+
+\setupchemical[frame=on,offset=3pt]
+
+\startbuffer[test-set]
+
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV1,B] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV2,B] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV3,B] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV4,B] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV5,B] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,MOV6,B] \stopchemical \quad
+
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,AU] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,AD] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,EB] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,DB] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,ER] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,DR] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,BR] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,SB] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,-SB] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,+SB] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,C] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CC] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CD] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,CCD] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,SR] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,-SR] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,+SR] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,RD] \stopchemical \quad
+
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,SB,Z] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RZ] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,+R,+RZ] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,-R,-RZ] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,RB,RZ] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,+RB,+RZ][a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,-RB,-RZ][a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RT] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RTT] [a,b,c,d,e,f] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RBT] [a,b,c,d,e,f] \stopchemical \quad
+
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RN] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RTN] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RBN] \stopchemical \quad
+
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,B,R,RN] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT1,B,R,RN] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT2,B,R,RN] \stopchemical \quad
+ \dontleavehmode \startchemical \chemical[\ChemicalKind,ROT3,B,R,RN] \stopchemical \quad
+
+\stopbuffer
+
+\dontcomplain
+
+% \startTEXpage
+
+\setupchemicalframed[frame=on]
+
+% \startTEXpage
+% \noindent \startchemical \chemical[THREE, B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT1,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT2,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT3,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT4,B,R,RZ][RZ_1,RZ_2,RZ_3]\stopchemical
+
+% \noindent \startchemical \chemical[THREE, B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3]\stopchemical
+
+% \noindent \startchemical \chemical[THREE, B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3]\stopchemical
+% \stopTEXpage
+
+% \startTEXpage
+% \noindent \startchemical \chemical[SIX,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[SIX,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[SIX,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[SIX,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \stopTEXpage
+
+% \startTEXpage
+% \noindent \startchemical \chemical[FIVE,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[FIVE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[FIVE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FIVE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \stopTEXpage
+
+% \startTEXpage
+% \noindent \startchemical \chemical[FOUR,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[FOUR,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[FOUR,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[FOUR,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \stopTEXpage
+
+% \startTEXpage
+% \noindent \startchemical \chemical[THREE,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[THREE,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6]\stopchemical
+
+% \noindent \startchemical \chemical[THREE,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \noindent \startchemical \chemical[THREE,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6]\stopchemical
+% \stopTEXpage
+
+% \startTEXpage
+% \noindent \startchemical \chemical[EIGHT,ROT1,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT2,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT3,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT4,B, R, RZ, AU][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6,RZ_7,RZ_8]\stopchemical
+
+% \noindent \startchemical \chemical[EIGHT,ROT1,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT2,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT3,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT4,B,-R,-RZ][-RZ_1,-RZ_2,-RZ_3,-RZ_4,-RZ_5,-RZ_6,-RZ_7,-RZ_8]\stopchemical
+
+% \noindent \startchemical \chemical[EIGHT,ROT1,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT2,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT3,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical
+% \noindent \startchemical \chemical[EIGHT,ROT4,B,+R,+RZ][+RZ_1,+RZ_2,+RZ_3,+RZ_4,+RZ_5,+RZ_6,+RZ_7,+RZ_8]\stopchemical
+% \stopTEXpage
+
+% \enabletrackers[chemistry.molecules]
+
+% \startchemicalformula
+% \chemical{S}
+% \chemical{+}
+% \chemical{O_2}
+% \chemical{GIVES}
+% \chemical{\+{4}{S}}
+% \chemical{\+{4}{S}\-{2}{O_2}}
+% \chemical{\-{2}{O_2}}
+% \stopchemicalformula
+
+% \startformula
+% \chemical{S}
+% \chemical{+}
+% \chemical{O_2}
+% \chemical{GIVES}
+% \chemical{\+{4}{S}}
+% \chemical{\+{4}{S}\-{2}{O_2}}
+% \chemical{\-{2}{O_2}}
+% \stopformula
+
+
+\startTEXpage[offset=2cm]
+
+\startchemical[width=fit,size=small,scale=small,frame=on]
+ \chemical[SIX,B]
+\stopchemical
+
+% \startchemical[width=fit,size=small,scale=small,frame=on]
+% \chemical[ONE,SB258]
+% \stopchemical
+
+% \startchemical[width=fit,size=small,scale=small,frame=on]
+% \chemical[ONE,ROT3,SB258]
+% \stopchemical
+
+% \startchemical[width=fit,size=small,scale=small,frame=on]
+% \chemical[FIVE,ROT3,SB34,+SB2,-SB5,Z345,DR35,SR4,CRZ35,SUB1,ONE,SB258,Z0,Z28][C,N,C,O,O,CH,COOC_2H_5,COOC_2H_5]
+% \stopchemical
+
+% \startchemical[scale=small,width=8000,height=8000,frame=on]
+% \chemical[SIX,SB2356,DB14,Z2346,SR36,RZ36] [C,N,C,C,H,H_2]
+% \chemical[PB:Z1,ONE,Z0,DIR8,Z0,SB24,DB7,Z27,PE][C,C,CH_3,O]
+% \chemical[PB:Z5,ONE,Z0,DIR6,Z0,SB24,DB7,Z47,PE][C,C,H_3C,O]
+% \chemical[SR24,RZ24] [CH_3,H_3C]
+% \stopchemical
+
+% \startchemical[scale=small,width=6000,height=6000,frame=on]
+% \chemical[SIX,SB2356,DB14,Z,SR36,RZ36,SR1245,RZ24][C,C,N,C,C,C,H,H_2,CH_3,H_3C]
+% \chemical[PB:RZ1,ONE,Z0,SB2,DB7,Z27,PE][C,CH_3,O]
+% \chemical[PB:RZ5,ONE,Z0,SB4,DB7,Z47,PE][C,H_3C,O]
+% \stopchemical
+
+% \startchemical[width=fit,size=small,scale=small,frame=on]
+% \chemical
+% [SIX,B,C,ADJ1,FIVE,ROT3,SB34,+SB2,-SB5,Z345,DR35,SR4,CRZ35,SUB1,ONE,OFF1,SB258,Z0,Z28]
+% [C,N,C,O,O,CH,COOC_2H_5,COOC_2H_5]
+% \stopchemical
+
+% \startchemical[width=fit,height=fit,frame=on,scale=small]
+% \chemical
+% [ONE,SB15,DB7,Z057,3OFF1,MOV1,Z0,3OFF1,MOV1,
+% Z017,SB1357,MOV3,Z0,MOV3,SB1357,Z013,3OFF5,
+% MOV5,Z0,3OFF5,SB5,Z5]
+% [C,H_2N,NH,(CH_2)_3,C,COOH,H,\SL{NH},C,COOH,H,
+% (CH_2)_2,HOOC]
+% \stopchemical
+
+% \startchemical[width=fit,height=fit,frame=on,scale=small]
+% \chemical
+% [ONE,SB15,DB7,Z057,3OFF1,MOV1,Z0,3OFF1,MOV1,Z017,SB1357,MOV3,Z0,MOV3,SB1357,Z013,3OFF5,MOV5,Z0,3OFF5,SB5,Z5]
+% [C,H_2N,NH,(CH_2)_3,C,COOH,H,\SL{NH},C,COOH,H,(CH_2)_2,HOOC]
+% \stopchemical
+
+% \startchemical
+% \chemical[ONE,Z0,DB,Z][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8]
+% \stopchemical
+
+% \startchemical
+% \chemical[ONE,Z0,SB,Z][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8]
+% \stopchemical
+
+% \startchemical
+% \chemical[ONE,Z0,DB,CZ][C_0,C_1,C_1,C_3,C_4,C_5,C_6,C_7,C_8]
+% \stopchemical
+
+% \startchemical
+% [width=fit,top=2000,bottom=2000,
+% scale=small,size=small]%
+% \chemical
+% [ONE,
+% SAVE,
+% Z0,SB731,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1,
+% RESTORE,
+% SAVE,
+% SUB4,ONE,Z0,SB3,SB1,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1,
+% RESTORE,
+% SUB2,ONE,Z0,SB7,SB1,MOV1,Z0,SB1,MOV1,Z0,DB8,CZ8,SB1,Z1]
+% [\SR{HC},O,C,O,C_{19}H_{39},
+% \SR{H_{2}C},O,C,O,C_{17}H_{29},
+% \SR{H_{2}C},O,C,O,C_{21}H_{41}]
+% \stopchemical
+
+% \chemical[width=fit,height=fit,frame=on,scale=small]
+% [ONE,Z0,MOV7,SB1357,Z017,3OFF5,MOV5,Z0,3OFF5,MOV5,SB15,DB7,Z057,MOV0,MOV3,SB1357,Z013,MOV5,3OFF5,Z0,6OFF5,SB5,Z5]
+% [\SL{NH},C,COOH,H,(CH_2)_3,C,H_2H,NH,C,COOH,H,(CH_2)_2,HOOC]
+% \stopchemical
+
+% \chemical[width=fit,height=fit,frame=on,scale=small]
+% [ONE,Z0,MOV7,SB1357,Z017,3OFF5,MOV5,Z0,3OFF5,MOV5,SB15,DB7,Z057,MOV0,MOV3,SB1357,Z013,MOV5,3OFF5,Z0,6OFF5,SB5,Z5]
+% [\SL{NH},C,COOH,H,(CH_2)_3,C,H_2H,NH,C,COOH,H,(CH_2)_2,HOOC]
+% \stopchemical
+
+% \startchemical[width=fit,top=1500,bottom=3500]
+% \chemical[ONE,Z0,DB1,SB3,SB7,Z7,MOV1,Z0,SB3,SB7,Z3,Z7,MOV0,SUB2,SIX,B,R6,C][C,H,C,H,H]
+% \chemical[ONE,Z0,DB1,SB3,SB7,Z7,MOV1,Z0,SB3,SB7,Z3,Z7,MOV0,SUB2,SIX,B,R6,C][C,H,C,H,H]
+% \bottext{styreen}
+% \stopchemical
+
+% \startchemical
+% \chemical[SPACE,PLUS,SPACE]
+% \stopchemical
+% \startchemical[right=600]
+% \chemical[ONE,CZ0][3CH_{3}OH]
+% \stopchemical
+% \startchemical
+% \chemical[SPACE,GIVES,SPACE,SPACE][H^+/H_2O]
+% \stopchemical
+% \startchemical
+% \chemical
+% [ONE,
+% SAVE,
+% Z0,SB7,SB3,SB1,Z1,
+% RESTORE,
+% SAVE,
+% SUB4,ONE,Z0,SB3,SB1,Z1,
+% RESTORE,
+% SUB2,ONE,Z0,SB7,SB1,Z1]
+% [\SR{HC},OH,
+% \SR{H_{2}C},OH,
+% \SR{H_{2}C},OH]
+% \stopchemical
+% \startchemical
+% \chemical[SPACE,PLUS,SPACE]
+% \stopchemical
+
+% \startchemical
+% \chemical
+% [ONE,
+% SAVE,
+% Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1,
+% RESTORE,
+% SAVE,
+% SUB4,ONE,Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1,
+% RESTORE,
+% SUB2,ONE,Z0,DB8,CZ8,SB1,SB5,Z5,MOV1,Z0,SB1,Z1]
+% [C,O,C_{19}H_{39},O,CH_{3},
+% C,O,C_{17}H_{29},O,CH_{3},
+% C,O,C_{21}H_{41},O,CH_{3}]
+% \stopchemical
+
+% \startchemical[height=4500,bottom=2500]
+% \bottext{$\beta$-D-Fructopyranose}
+% \chemical[SIX,FRONT,BB,B1236,+SB4,-SB5,Z5,+R12346,+RZ12346,-R12346,-RZ12346][Z_0,+R_1,+R_2,+R_3,+R_4,+R_6,-R_1,-R_2,-R_3,-R_4,-R_6]
+% \stopchemical
+
+% \startchemical[height=4500,bottom=2500]
+% \chemical[SIX,FRONT,BB,B]
+% \stopchemical
+
+% \startchemical
+% [width=fit,height=fit,frame=on]
+% \chemical
+% [SIX,DB135,SB246,Z,SR6,RZ6][C,C,N,\SR{HC},N,C,NH_2]
+% \chemical
+% [SIX,MOV1,DB1,SB23,SS6,Z1..3,SR3,RZ3][N,\SL{CH},N,H]
+% \stopchemical
+
+% \startchemical \chemical[SIX,B,R,RZ1=a] \stopchemical
+% \startchemical \chemical[SIX,B,R,RZ1..3=a] \stopchemical
+% \startchemical \chemical[SIX,B,R,RZ135=a] \stopchemical
+% \startchemical \chemical[SIX,B,R,RZ] [a] \stopchemical
+% \startchemical \chemical[SIX,B,R,RZ] [a,b] \stopchemical
+% \startchemical \chemical[SIX,B,R,RZ=a] \stopchemical
+
+% \definechemical[molecule]
+% {\chemical
+% [ONE,Z0,SB1357,
+% SAVE,SUB2,SIX,B,R6,C,RESTORE,
+% MOV1,Z0,SB137,MOV1,Z0,SB37,MOV1]
+% [C,C,C]}
+
+% \startchemical[width=fit,height=fit]
+% \chemical[molecule,molecule,molecule]
+% \stopchemical
+
+% \definechemical[molecule]
+% {\chemical
+% [ONE,Z0,SB1357,
+% SAVE,SUB2,SIX,B,R6,C,RESTORE,
+% MOV1,Z0,SB137,MOV1,Z0,SB37,MOV1]}
+
+% \startchemical[width=fit,height=fit]
+% \chemical[molecule,molecule,molecule][A,B,C,D,E,F,G,H,I]
+% \stopchemical
+
+\stopTEXpage
+
+% \noindent \startchemical
+% \chemical[SIX,B1..3]
+% \stopchemical
+
+% \noindent \startchemical[width=fit,height=fit] % auto5 ipb off5
+% \chemical[SIX,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]
+% \stopchemical
+% \noindent \startchemical[width=fit,height=fit] % auto5 ipb off5
+% \chemical[SIX,ROT1,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]
+% \stopchemical
+% \startchemical[width=fit,height=fit] % auto5 ipb off5
+% \chemical[SIX,ROT2,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]
+% \stopchemical
+% \startchemical[width=fit,height=fit] % auto5 ipb off5
+% \chemical[SIX,ROT3,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]
+% \stopchemical
+% \startchemical[width=fit,height=fit] % auto5 ipb off5
+% \chemical[SIX,ROT4,B,C,R,RZ][RZ_1,RZ_2,RZ_3,RZ_4,RZ_5,RZ_6]
+% \stopchemical
+
+% \startchemical[width=fit,height=fit,axis=on] % auto5 ipb off5
+% \chemical[SIX,B,C,R6,PB:RZ6,ONE,CZ0,OE1,SB5,MOV5,CZ0,OFF5,OE5,PE][CH,CH_2]
+% \stopchemical
+
+% \dontleavehmode \startchemical \chemical[SIX,B,R,RZ][1,2,3,4,5,6,] \stopchemical
+
+% \start
+% \setupchemicalframed[frame=off]
+% \dontleavehmode \startchemical[scale=medium,style=slanted,color=red,rulecolor=green,left=2000,right=4000,top=2000,bottom=2000,axis=on] \chemical[SIX,B,R,RZ][1,2,3,4,5,6,] \stopchemical
+
+% \dontleavehmode
+% \startchemical[width=fit,height=fit]
+% \chemical[SIX,B][1,2,3,4,5,6]
+% \start
+% \setupchemical[rulecolor=red]
+% \chemical[SIX,R][1,2,3,4,5,6]
+% \stop
+% \chemical[SIX,RZ][1,2,3,4,5,6]
+% \stopchemical
+% \stop
+
+% \stopTEXpage
+
+% \stoptext
+
+% \startTEXpage
+
+% \dontleavehmode \startchemical \chemical[ONE,SB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,DB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,TB,Z0,Z][0,1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,EP,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,ES,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,ED,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,ET,Z0][0] \stopchemical \quad
+
+
+% \dontleavehmode \startchemical \chemical[ONE,SD,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,LDD,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,RDD,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,HB,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,BB,Z0][0] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,OE,Z0][0] \stopchemical \quad
+
+
+% \dontleavehmode \startchemical \chemical[ONE,SB,Z] [1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,CZ][1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,ZT][a,b,c,d,e,f,g,h] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,ZN][1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,ZBT][1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,ZBN][1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,ZTT][1,2,3,4,5,6,7,8] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,ZTN][1,2,3,4,5,6,7,8] \stopchemical \quad
+
+% \dontleavehmode \startchemical \chemical[ONE,SB,MOV1,SB] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[ONE,SB,MOV1,SB,MOV3,SB] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,MOV1,B] \stopchemical \quad
+
+
+% \dontleavehmode \startchemical \chemical[ONE,SB,Z0,Z][0,1,2,3,4,5,6] \stopchemical \quad
+% \stopTEXpage
+
+
+% \dorecurse{1000}{\dontleavehmode \startchemical \chemical[SIX,B,R,RZ][a,b,c,d,e,f] \stopchemical \quad}
+
+% \dontleavehmode \startchemical \chemical[SIX,B,R,RT] [a,b,c,d,e,f] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,R,RTT] [a,b,c,d,e,f] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,R,RBT] [a,b,c,d,e,f] \stopchemical \quad
+
+% \dontleavehmode \startchemical \chemical[SIX,B,R,+R,-R] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B1..4] \stopchemical \quad
+
+% \dontleavehmode \startchemical \chemical[SIX,B,ZN] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,ZT][A,B,C,D,E,F] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,R,AU] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,R,AD] \stopchemical \quad
+
+% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,SIX,B] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,FIVE,ROT1,B] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,FOUR,B] \stopchemical \quad
+% \dontleavehmode \startchemical \chemical[SIX,B,ADJ1,THREE,B] \stopchemical \quad
+
+% \definechemical[sixring]
+% {\chemical[SIX,B,R]}
+
+% \startchemical[frame=on,width=6000]
+% \chemical[sixring,RZ][A,B,C,D,E,F]
+% \stopchemical
+
+% \definechemical[test]
+% {\chemical[SIX,SB,Z][A,B,C,D,E,F]}
+
+% \startchemical
+% \chemical[SIX,SB,Z,ADJ1,test,ADJ1,SIX,SB,Z][a,b,c,d,e,f,g,h,j,k,l,m,P,Q,R,S,T,U,W]
+% \chemical[ADJ1,SIX,SB,Z][1,2,3,4,5,6]
+% \stopchemical
+
+% \definechemical[test]{\chemical[SIX,SB,Z]}
+
+% \startchemical
+% \chemical[SIX,SB,Z,ADJ1,test,ADJ1,SIX,SB,Z][a,b,c,d,e,f,g,h,j,k,l,m,P,Q,R,S,T,U,W]
+% \chemical[ADJ1,SIX,SB,Z][1,2,3,4,5,6]
+% \stopchemical
+
+% \startchemical
+% \chemical[ADJ1,SIX,SB,Z][a_1,a_2,a_3,a_4,a_5,\ominus]
+% \stopchemical
+
+% \startchemical
+% \chemical[SIX,SB,Z,SAVE,ADJ1,SIX,SB,Z,ADJ1,SIX,SB,Z,RESTORE,ADJ3,SIX,SB,Z][1,2,3,4,5,6,a,b,c,d,e,f,A,B,C,D,E,F,!,!,!,!,!,!]
+% \stopchemical
+
+% $$
+% \startchemical
+% \chemical[OPENCOMPLEX]
+% \stopchemical
+% \startchemical
+% \chemical[SIX,SB,Z][1,2,3,4,5,6]
+% \stopchemical
+% \startchemical
+% \chemical[SPACE,GIVES,SPACE][a,b]
+% \stopchemical
+% \startchemical
+% \chemical[SIX,SB,Z][1,2,3,4,5,6]
+% \stopchemical
+% \startchemical
+% \chemical[CLOSECOMPLEX]
+% \stopchemical
+% $$
+
+% \stoptext
+
+% \page
+
+% \def\ChemicalKind{SIX} \getbuffer[test-set]
+% \def\ChemicalKind{FIVE} \getbuffer[test-set]
+% \def\ChemicalKind{FOUR} \getbuffer[test-set]
+% \def\ChemicalKind{THREE} \getbuffer[test-set]
+
+% \startchemical
+% \chemical[SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f]
+% \chemical[MOV1,SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f]
+% \chemical[MOV3,SIX,SB,C135,SR,Z0,Z,RZ][X,ch:r->A,ch:g->B,ch:b->C,D,E,F,a,b,c,d,e,f]
+% \stopchemical
+
+\stoptext
diff --git a/tex/context/base/chem-str.lua b/tex/context/base/chem-str.lua
new file mode 100644
index 000000000..8ab48fca2
--- /dev/null
+++ b/tex/context/base/chem-str.lua
@@ -0,0 +1,488 @@
+if not modules then modules = { } end modules ['chem-str'] = {
+ version = 1.001,
+ comment = "companion to chem-str.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This module in incomplete and experimental.
+
+-- We can push snippets into an mp instance.
+
+local trace_structure = false trackers.register("chemistry.structure", function(v) trace_structure = v end)
+local trace_textstack = false trackers.register("chemistry.textstack", function(v) trace_textstack = v end)
+
+local format, gmatch, match, lower, gsub = string.format, string.gmatch, string.match, string.lower, string.gsub
+local concat, insert, remove = table.concat, table.insert, table.remove
+local apply = structure.processors.apply
+local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes
+
+local variables = interfaces.variables
+
+chemicals = chemicals or { }
+
+chemicals.instance = "metafun" -- "ppchtex"
+chemicals.format = "metafun"
+chemicals.structures = 0
+
+local remapper = {
+ ["+"] = "p",
+ ["-"] = "m",
+}
+
+local common_keys = {
+ b = "line", eb = "line", db = "line", er = "line", dr = "line", br = "line",
+ sb = "line", msb = "line", psb = "line",
+ r = "line", pr = "line", mr = "line",
+ au = "line", ad = "line",
+ rb = "line", mrb = "line", prb = "line",
+ rd = "line", mrd = "line", prd = "line",
+ sr = "line", msr = "line", psr = "line",
+ c = "line", cc = "line", cd = "line", ccd = "line",
+ rn = "number", rtn = "number", rbn = "number",
+ s = "line", ss = "line", pss = "line", mss = "line",
+ mid = "fixed", mids = "fixed", midz = "text",
+ z = "text", rz = "text", mrz = "text", prz = "text", crz = "text",
+ rt = "text", rtt = "text", rbt = "text", zt = "text", zn = "number",
+ mov = "transform", rot = "transform", adj = "transform", dir = "transform", sub = "transform",
+}
+
+local front_keys = {
+ b = "line", bb= "line",
+ sb = "line", msb = "line", psb = "line",
+ r = "line", pr = "line", mr = "line",
+ z = "text", mrz = "text", prz = "text",
+}
+
+local one_keys = {
+ sb = "line", db = "line", tb = "line",
+ ep = "line", es = "line", ed = "line", et = "line",
+ sd = "line", ldd = "line", rdd = "line",
+ hb = "line", bb = "line", oe = "line",
+ z = "text", cz = "text", zt = "text", zn = "number",
+ zbt = "text", zbn = "number", ztt = "text", ztn = "number",
+ mov = "transform", sub = "transform", dir = "transform", off = "transform",
+}
+
+local front_align = {
+ mrz = { { "b","b","b","b","b","b" } },
+ prz = { { "t","t","t","t","t","t" } },
+}
+
+local syntax = {
+ one = {
+ n = 1, max = 8, keys = one_keys,
+ align = {
+ z = { { "r", "r_b", "b", "l_b", "l", "l_t", "t", "r_t" } },
+--~ z = { { "r", "r", "b", "l", "l", "l", "t", "r" } },
+ }
+ },
+ three = {
+ n = 3, max = 3, keys = common_keys,
+ align = {
+ mrz = { { "r","b","l" }, { "b","l","t" }, { "l","t","r" }, { "t","r","b" } },
+ rz = { { "r","l_b","l_t" }, { "b","l_t","r_t" }, { "l","r_t","r_b" }, { "t","r_b","l_b" } },
+ prz = { { "r","l","t" }, { "b","t","r" }, { "l","r","b" }, { "t","b","l" } },
+ }
+ },
+ four = {
+ n = 4, max = 4, keys = common_keys,
+ align = {
+ mrz = { { "t","r","b","l" }, { "r","b","l","t" }, { "b","l","t","r" }, { "l","t","r","b" } },
+ rz = { { "r_t","r_b","l_b","l_t" }, { "r_b","l_b","l_t","r_t" }, { "l_b","l_t","r_t","r_b" }, { "l_t","r_t","r_b","l_b" } },
+ prz = { { "r","b","l","t" }, { "b","l","t","r" }, { "l","t","r","b" }, { "t","r","b","l" } },
+ }
+ },
+ five = {
+ n = 5, max = 5, keys = common_keys,
+ align = {
+ mrz = { { "t","r","b","b","l" }, { "r","b","l","l","t" }, { "b","l","t","r","r" }, { "l","t","r","r","b" } },
+ rz = { { "r","r","b","l","t" }, { "b","b","l","t","r" }, { "l","l","t","r","b" }, { "t","t","r","b","l" } },
+ prz = { { "r","b","l","t","t" }, { "b","l","t","r","r" }, { "l","t","r","b","b" }, { "t","r","b","l","l" } },
+ }
+ },
+ six = {
+ n = 6, max = 6, keys = common_keys,
+ align = {
+ mrz = { { "t","t","r","b","b","l" }, { "r","b","b","l","t","t" }, { "b","b","l","t","t","r" }, { "l","t","t","r","b","b" } },
+ rz = { { "r","r","b","l","l","t" }, { "b","b","l","t","t","r" }, { "l","l","t","r","r","b" }, { "t","t","r","b","b","l" } },
+ prz = { { "r","b","l","l","t","r" }, { "b","l","t","t","r","b" }, { "l","t","r","r","b","l" }, { "t","r","b","b","l","t" } },
+ }
+ },
+ eight = {
+ n = 8, max = 8, keys = common_keys,
+ align = { -- todo
+ mrz = { { "t","r","r","b","b","l","l","t" }, { "r","b","b","l","l","t","t","r" }, { "b","l","l","t","t","r","r","b" }, { "l","t","t","r","r","b","b","l" } },
+ rz = { { "r","r","b","b","l","l","t","t" }, { "b","b","l","l","t","t","r","r" }, { "l","l","t","t","r","r","b","b" }, { "t","t","r","r","b","b","l","l" } },
+ prz = { { "r","b","b","l","l","t","t","r" }, { "b","l","l","t","t","r","r","b" }, { "l","t","t","r","r","b","b","l" }, { "t","r","r","b","b","l","l","t" } },
+ }
+ },
+ five_front = {
+ n = -5, max = 5, keys = front_keys, align = front_align,
+ },
+ six_front = {
+ n = -6, max = 6, keys = front_keys, align = front_align,
+ },
+ pb = { direct = 'chem_pb ;' },
+ pe = { direct = 'chem_pe ;' },
+ save = { direct = 'chem_save ;' },
+ restore = { direct = 'chem_restore ;' },
+ space = { direct = 'chem_symbol("\\chemicalsymbol[space]") ;' },
+ plus = { direct = 'chem_symbol("\\chemicalsymbol[plus]") ;' },
+ minus = { direct = 'chem_symbol("\\chemicalsymbol[minus]") ;' },
+ gives = { direct = 'chem_symbol("\\chemicalsymbol[gives]{%s}{%s}") ;', arguments = 2 },
+ equilibrium = { direct = 'chem_symbol("\\chemicalsymbol[equilibrium]{%s}{%s}") ;', arguments = 2 },
+ mesomeric = { direct = 'chem_symbol("\\chemicalsymbol[mesomeric]{%s}{%s}") ;', arguments = 2 },
+ opencomplex = { direct = 'chem_symbol("\\chemicalsymbol[opencomplex]") ;' },
+ closecomplex = { direct = 'chem_symbol("\\chemicalsymbol[closecomplex]") ;' },
+}
+
+local definitions = { }
+
+function chemicals.undefine(name)
+ definitions[name] = nil
+end
+
+function chemicals.define(name,spec,text)
+ local dn = definitions[name]
+ if not dn then dn = { } definitions[name] = dn end
+ dn[#dn+1] = {
+ spec = aux.settings_to_array(lower(spec)),
+ text = aux.settings_to_array(text),
+ }
+end
+
+local metacode, kind, keys, bonds, max, txt, textsize, rot, pstack
+local molecule = chemicals.molecule -- or use chemicals.moleculeparser:match(...)
+
+local function fetch(txt)
+ local st = stack[txt]
+ local t = st.text[st.n]
+--~ st.n = st.n + 1
+ while not t and txt > 1 do
+ txt = txt - 1
+ st = stack[txt]
+ t = st.text[st.n]
+--~ st.n = st.n + 1
+ end
+ if t then
+ if trace_textstack then
+ logs.report("chemical", "fetching from stack %s slot %s: %s",txt,st.n,t)
+ end
+st.n = st.n + 1
+ end
+ return txt, t
+end
+
+local digit = lpeg.R("09")/tonumber
+local colon = lpeg.P(":")
+local equal = lpeg.P("=")
+local other = 1 - digit - colon - equal
+local remapped = lpeg.S("+-") / remapper
+local operation = lpeg.Cs((remapped^0 * other)^1)
+local amount = digit
+local single = digit
+local special = (colon * lpeg.C(other^1)) + lpeg.Cc("")
+local range = digit * lpeg.P("..") * digit
+local set = lpeg.Ct(digit^2)
+local text = (equal * lpeg.C(lpeg.P(1)^0)) + lpeg.Cc(false)
+local pattern =
+ (amount + lpeg.Cc(1)) *
+ operation *
+ special * (
+ range * lpeg.Cc(false) * text +
+ lpeg.Cc(false) * lpeg.Cc(false) * set * text +
+ single * lpeg.Cc(false) * lpeg.Cc(false) * text +
+ lpeg.Cc(false) * lpeg.Cc(false) * lpeg.Cc(false) * text
+ )
+
+--~ local n, operation, index, upto, set, text = pattern:match("RZ1357")
+
+--~ print(pattern:match("RZ=x")) 1 RZ false false false x
+--~ print(pattern:match("RZ1=x")) 1 RZ 1 false false x
+--~ print(pattern:match("RZ1..3=x")) 1 RZ 1 3 false x
+--~ print(pattern:match("RZ13=x")) 1 RZ false false table x
+
+local function process(spec,text,n,rulethickness,rulecolor,offset)
+ insert(stack,{ spec=spec, text=text, n=n })
+ local txt = #stack
+ for i=1,#spec do
+ local s = spec[i]
+ local d = definitions[s]
+ if d then
+ for i=1,#d do
+ local di = d[i]
+ process(di.spec,di.text,1,rulethickness,rulecolor)
+ end
+ else
+ local rep, operation, special, index, upto, set, text = pattern:match(s)
+ if operation == "pb" then
+ insert(pstack,kind)
+ metacode[#metacode+1] = syntax.pb.direct
+ if keys[special] == "text" and index then
+ if keys["c"..special] == "text" then -- can be option: auto ...
+ metacode[#metacode+1] = format('chem_c%s(%s,%s,"");',special,bonds,index)
+ else
+ metacode[#metacode+1] = format('chem_%s(%s,%s,"");',special,bonds,index)
+ end
+ end
+ elseif operation == "save" then
+ insert(pstack,kind)
+ metacode[#metacode+1] = syntax.save.direct
+ elseif operation == "pe" or operation == "restore" then
+ kind = remove(pstack)
+ local ss = syntax[kind]
+ local prev = bonds or 6
+ keys, bonds, max, rot = ss.keys, ss.n, ss.max, 1
+ metacode[#metacode+1] = syntax[operation].direct
+ metacode[#metacode+1] = format("chem_set(%s,%s) ;",prev,bonds)
+ elseif operation == "front" then
+ if syntax[kind .. "_front"] then
+ kind = kind .. "_front"
+ local ss = syntax[kind]
+ local prev = bonds or 6
+ keys, bonds, max, rot = ss.keys, ss.n, ss.max, 1
+ metacode[#metacode+1] = format("chem_set(%s,%s) ;",prev,bonds)
+ end
+ elseif operation then
+ local ss = syntax[operation]
+ if ss then
+ local ds = ss.direct
+ if ds then
+ local sa = ss.arguments
+ if sa == 1 then
+ local one ; txt, one = fetch(txt)
+ metacode[#metacode+1] = format(ds,one or "")
+ elseif sa ==2 then
+ local one ; txt, one = fetch(txt)
+ local two ; txt, two = fetch(txt)
+ metacode[#metacode+1] = format(ds,one or "",two or "")
+ else
+ metacode[#metacode+1] = ds
+ end
+ elseif ss.keys then
+ local prev = bonds or 6
+ kind, keys, bonds, max, rot = s, ss.keys, ss.n, ss.max, 1
+ metacode[#metacode+1] = format("chem_set(%s,%s) ;",prev,bonds)
+ end
+ else
+ local what = keys[operation]
+ if what == "line" then
+ if set then
+ for i=1,#set do
+ local si = set[i]
+ metacode[#metacode+1] = format("chem_%s(%s,%s,%s,%s,%s);",operation,bonds,si,si,rulethickness,rulecolor)
+ end
+ elseif upto then
+ metacode[#metacode+1] = format("chem_%s(%s,%s,%s,%s,%s);",operation,bonds,index,upto,rulethickness,rulecolor)
+ elseif index then
+ metacode[#metacode+1] = format("chem_%s(%s,%s,%s,%s,%s);",operation,bonds,index,index,rulethickness,rulecolor)
+ else
+ metacode[#metacode+1] = format("chem_%s(%s,%s,%s,%s,%s);",operation,bonds,1,max,rulethickness,rulecolor)
+ end
+ elseif what == "number" then
+ if set then
+ for i=1,#set do
+ local si = set[i]
+ metacode[#metacode+1] = format('chem_%s(%s,%s,"\\dochemicaltext{%s}");',operation,bonds,si,si)
+ end
+ elseif upto then
+ for i=index,upto do
+ local si = set[i]
+ metacode[#metacode+1] = format('chem_%s(%s,%s,"\\dochemicaltext{%s}");',operation,bonds,si,si)
+ end
+ elseif index then
+ metacode[#metacode+1] = format('chem_%s(%s,%s,"\\dochemicaltext{%s}");',operation,bonds,index,index)
+ else
+ for i=1,max do
+ metacode[#metacode+1] = format('chem_%s(%s,%s,"\\dochemicaltext{%s}");',operation,bonds,i,i)
+ end
+ end
+ elseif what == "text" then
+ local align = syntax[kind].align
+ align = align and align[operation]
+ align = align and align[rot]
+ if set then
+ for i=1,#set do
+ local si = set[i]
+ local t = text
+ if not t then txt, t = fetch(txt) end
+ if t then
+ local a = align and align[si]
+ if a then a = "." .. a else a = "" end
+ metacode[#metacode+1] = format('chem_%s%s(%s,%s,"\\dochemicaltext{%s}");',operation,a,bonds,si,molecule(apply(t)))
+ end
+ end
+ elseif upto then
+ for i=index,upto do
+ local t = text
+ if not t then txt, t = fetch(txt) end
+ if t then
+ local s = align and align[i]
+ if s then s = "." .. s else s = "" end
+ metacode[#metacode+1] = format('chem_%s%s(%s,%s,"\\dochemicaltext{%s}");',operation,s,bonds,i,molecule(apply(t)))
+ end
+ end
+ elseif index == 0 then
+ local t = text
+ if not t then txt, t = fetch(txt) end
+ if t then
+ metacode[#metacode+1] = format('chem_%s_zero("\\dochemicaltext{%s}");',operation,molecule(apply(t)))
+ end
+ elseif index then
+ local t = text
+ if not t then txt, t = fetch(txt) end
+ if t then
+ local s = align and align[index]
+ if s then s = "." .. s else s = "" end
+ metacode[#metacode+1] = format('chem_%s%s(%s,%s,"\\dochemicaltext{%s}");',operation,s,bonds,index,molecule(apply(t)))
+ end
+ else
+ for i=1,max do
+ local t = text
+ if not t then txt, t = fetch(txt) end
+ if t then
+ local s = align and align[i]
+ if s then s = "." .. s else s = "" end
+ metacode[#metacode+1] = format('chem_%s%s(%s,%s,"\\dochemicaltext{%s}");',operation,s,bonds,i,molecule(apply(t)))
+ end
+ end
+ end
+ elseif what == "transform" then
+ if index then
+ for r=1,rep do
+ metacode[#metacode+1] = format('chem_%s(%s,%s);',operation,bonds,index)
+ end
+ if operation == "rot" then
+ rot = index
+ end
+ end
+ elseif what == "fixed" then
+ metacode[#metacode+1] = format("chem_%s(%s,%s,%s);",operation,bonds,rulethickness,rulecolor)
+ end
+ end
+ end
+ end
+ end
+ remove(stack)
+end
+
+-- the size related values are somewhat special but we want to be
+-- compatible
+--
+-- maybe we should default to fit
+--
+-- rulethickness in points
+
+function chemicals.start(settings)
+ chemicals.structures = chemicals.structures + 1
+ local textsize, rulethickness, rulecolor = settings.size, settings.rulethickness, settings.rulecolor
+ local width, height, scale, offset = settings.width or 0, settings.height or 0, settings.scale or "medium", settings.offset or 0
+ local l, r, t, b = settings.left or 0, settings.right or 0, settings.top or 0, settings.bottom or 0
+ if scale == variables.small then
+ scale = 500
+ elseif scale == variables.medium or scale == 0 then
+ scale = 625
+ elseif scale == variables.big then
+ scale = 750
+ else
+ scale = tonumber(scale)
+ if not scale or scale == 0 then
+ scale = 750
+ elseif scale < 500 then
+ scale = 500
+ end
+ end
+ if width == variables.fit then
+ width = true
+ else
+ width = tonumber(width) or 0
+ if l == 0 then
+ if r == 0 then
+ l = (width == 0 and 2000) or width/2
+ r = l
+ elseif width ~= 0 then
+ l = width - r
+ end
+ elseif r == 0 and width ~= 0 then
+ r = width - l
+ end
+ width = false
+ end
+ if height == variables.fit then
+ height = true
+ else
+ height = tonumber(height) or 0
+ if t == 0 then
+ if b == 0 then
+ t = (height == 0 and 2000) or height/2
+ b = t
+ elseif height ~= 0 then
+ t = height - b
+ end
+ elseif b == 0 and height ~= 0 then
+ b = height - t
+ end
+ height = false
+ end
+ scale = 0.75 * scale/625
+ metacode = { format("chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ;",
+ chemicals.structures,
+ l/25, r/25, t/25, b/25, scale,
+ tostring(settings.axis == variables.on), tostring(width), tostring(height), tostring(offset)
+ ) }
+ kind, keys, bonds, stack, rot, pstack = "six", { }, 6, { }, 1, { }
+end
+
+function chemicals.stop()
+ metacode[#metacode+1] = "chem_stop_structure ;"
+ local mpcode = concat(metacode,"\n")
+ if trace_structure then
+ logs.report("chemical", "metapost code:\n%s", mpcode)
+ end
+ metapost.graphic(chemicals.instance,chemicals.format,mpcode,"")
+ metacode = nil
+end
+
+function chemicals.component(spec,text,settings)
+ rulethickness, rulecolor, offset = settings.rulethickness, settings.rulecolor
+ local spec = aux.settings_to_array(lower(spec))
+ local text = aux.settings_to_array(text)
+ metacode[#metacode+1] = "chem_start_component ;"
+ process(spec,text,1,rulethickness,rulecolor)
+ metacode[#metacode+1] = "chem_stop_component ;"
+end
+
+local inline = {
+ ["single"] = "\\chemicalsinglebond", ["-"] = "\\chemicalsinglebond",
+ ["double"] = "\\chemicaldoublebond", ["--"] = "\\chemicaldoublebond",
+ ["triple"] = "\\chemicaltriplebond", ["---"] = "\\chemicaltriplebond",
+ ["gives"] = "\\chemicalgives", ["->"] = "\\chemicalgives",
+ ["equilibrium"] = "\\chemicalequilibrium", ["<->"] = "\\chemicalequilibrium",
+ ["mesomeric"] = "\\chemicalmesomeric", ["<>"] = "\\chemicalmesomeric",
+ ["plus"] = "\\chemicalsplus", ["+"] = "\\chemicalsplus",
+ ["minus"] = "\\chemicalsminus",
+ ["space"] = "\\chemicalsspace",
+}
+
+-- todo: top / bottom
+
+function chemicals.inline(spec)
+ local spec = aux.settings_to_array(spec)
+ for i=1,#spec do
+ local s = spec[i]
+ local inl = inline[lower(s)]
+ if inl then
+ texsprint(ctxcatcodes,inl)
+ else
+ texsprint(ctxcatcodes,format("\\chemicalinline{%s}",molecule(s)))
+ end
+ end
+end
+
+statistics.register("chemical formulas", function()
+ if chemicals.structures > 0 then
+ return format("%s chemical structure formulas",chemicals.structures) -- no timing needed, part of metapost
+ end
+end)
diff --git a/tex/context/base/chem-str.mkiv b/tex/context/base/chem-str.mkiv
new file mode 100644
index 000000000..29c6fe939
--- /dev/null
+++ b/tex/context/base/chem-str.mkiv
@@ -0,0 +1,526 @@
+%D \module
+%D [ file=chem-ini,
+%D version=2009.05.13,
+%D subtitle=Chemistry,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 in incomplete and experimental. Eventually this code
+%D will replace \PPCHTEX.
+
+\writestatus{loading}{ConTeXt Chemistry Macros / Structure}
+
+\registerctxluafile{chem-str}{1.001}
+
+% We have a slightly different interface. This is unchanged:
+%
+% \startchemical[axis=on]
+% \chemical[SIX,ROT2,B,R6,SUB1,FIVE,ROT1,B][1]
+% \stopchemical
+%
+% Here we use chemicalformula instead, so no longer a mix:
+%
+% \startchemicalformula
+% \chemical{H_2}{top}{bottom}
+% \chemical{PLUS}{top}{bottom}
+% \chemical{O}{top}{bottom}
+% \chemical{GIVES}{top}{bottom}
+% \chemical{H_2O}{top}{bottom}
+% \stopchemicalformula
+%
+% \startchemicalformula
+% \chemical{H_2}
+% \chemical{PLUS}
+% \chemical{O}
+% \chemical{GIVES}
+% \chemical{H_2O}
+% \stopchemicalformula
+%
+% The inline variant has only one argument:
+%
+% \chemical{H_2,PLUS,O,GIVES,H_2O}
+
+% todo: seven | eight | frontsix | fontfive | carbon | newmans | chair
+
+\unprotect
+
+\def\setupchemical
+ {\dosingleempty\dosetupchemical}
+
+\def\dosetupchemical
+ {\getparameters[\??cm]}
+
+\let\setupchemicals\setupchemical
+
+\def\setupchemicalframed
+ {\dosingleempty\dosetupchemicalframed}
+
+\def\dosetupchemicalframed
+ {\getparameters[\??cm:\c!frame]}
+
+\def\chemicalparameter#1{\csname\??cm#1\endcsname}
+
+\def\definechemical
+ {\dosingleargument\dodefinechemical} % global
+
+\def\dodefinechemical[#1]#2%
+ {\startnointerference
+ \ctxlua{chemicals.undefine("#1")}%
+ \def\chemical{\dodoubleempty\dostructurechemical}%
+ \def\dostructurechemical[##1][##2]{\ctxlua{chemicals.define("#1",\!!bs##1\!!es,\!!bs\detokenize{##2}\!!es)}}%
+ #2% flush
+ \stopnointerference}
+
+\def\definechemicalsymbol
+ {\dodoubleempty\dodefinechemicalsymbol}
+
+\def\dodefinechemicalsymbol[#1][#2]%
+ {\setvalue{\??cm::#1}{#2}}
+
+\def\chemicalsymbol[#1]%
+ {\getvalue{\??cm::#1}}
+
+% size (small medium big)
+
+\def\dosetchemicaltext
+ {\dosetfontattribute \??cm\c!style
+ \dosetcolorattribute\??cm\c!color}
+
+\def\dochemicaltext#1%
+ {\dosetchemicaltext\strut#1} % maybe also \setstrut
+
+\edef\chemicaltoplocation{t}
+\edef\chemicalbotlocation{b}
+
+\def\dochemicaltext#1% in ppchtex we had a more clever alignment
+ {\dosetchemicaltext\strut#1} % maybe also \setstrut
+
+\newconditional\indisplaychemical
+
+\unexpanded\def\startchemical
+ {\dosingleempty\dostartchemical}
+
+\setvalue{\??cm:\c!size:\v!small }{\txx}
+\setvalue{\??cm:\c!size:\v!medium}{\tx}
+\setvalue{\??cm:\c!size:\v!big }{}
+
+\newtoks \everychemical
+\newtoks \everystructurechemical
+\newtoks \withchemicalbox
+\newbox \chemicalbox
+\newconditional\somechemicaltext
+\newdimen \chemicalwidth
+\newdimen \chemicalheight
+\newdimen \chemicaldepth
+
+\def\dostartchemical[#1]%
+ {\ifmmode\vcenter\else\vbox\fi
+ \bgroup
+ \dontcomplain
+ \settrue\indisplaychemical
+ \forgetall
+ \getparameters[\??cm][#1]%
+ \the\everystructurechemical
+ \setbox\chemicalbox\hbox\bgroup
+ \ctxlua{chemicals.start {
+ width = "\chemicalparameter\c!width",
+ height = "\chemicalparameter\c!height",
+ left = \chemicalparameter\c!left,
+ right = \chemicalparameter\c!right,
+ top = \chemicalparameter\c!top,
+ bottom = \chemicalparameter\c!bottom,
+ scale = "\chemicalparameter\c!scale",
+ axis = "\chemicalparameter\c!axis",
+ offset = "\the\dimexpr.25em\relax",
+ } }%
+ \startnointerference}
+
+\unexpanded\def\stopchemical
+ {\stopnointerference
+ \ctxlua{chemicals.stop()}%
+ \egroup
+ \chemicalwidth \wd\chemicalbox
+ \chemicalheight\ht\chemicalbox
+ \chemicaldepth \dp\chemicalbox
+ \the\withchemicalbox
+ \doifelsenothing{\chemicalparameter\c!frame}\handlechemicalframednop\handlechemicalframedyes
+ \egroup}
+
+\def\handlechemicalframedyes
+ {\localframed%
+ [\??cm:\c!frame]%
+ [\c!frame=\chemicalparameter\c!frame,\c!align=\v!normal,\c!strut=\v!no]{\vbox{\box\chemicalbox\vss}}} % remove depth
+
+\def\handlechemicalframednop
+ {\localframed%
+ [\??cm:\c!frame]%
+ [\c!align=\v!normal,\c!strut=\v!no]{\vbox{\box\chemicalbox\vss}}} % remove depth
+
+\let\startstructurechemical\startchemical
+\let\stopstructurechemical \stopchemical
+
+\unexpanded\def\structurechemical
+ {\dotripleempty\dostructurechemical}
+
+\appendtoks
+ \let\chemical\structurechemical
+\to\everystructurechemical
+
+\def\dostructurechemical
+ {\ifthirdargument
+ \expandafter\dostructurechemicalthree
+ \else
+ \expandafter\dostructurechemicaltwo
+ \fi}
+
+\def\dostructurechemicalthree[#1][#2][#3]%
+ {\writestatus\m!chemicals{hyperlinked chemicals not yet supported}% todo reference, for the moment ignored
+ \ctxlua{chemicals.component(\!!bs#2\!!es, \!!bs\detokenize{#3}\!!es, { % maybe also pass first two args this way
+ rulethickness = "\the\dimexpr\chemicalparameter\c!rulethickness\relax", % todo: scaled points
+ rulecolor = "\MPcolor{\chemicalparameter\c!rulecolor}" % we can precalculate this for speedup
+ } ) }%
+ \ignorespaces}
+
+\def\dostructurechemicaltwo[#1][#2]%
+ {\ctxlua{chemicals.component(\!!bs#1\!!es,\!!bs\detokenize{#2}\!!es, { % maybe also pass first two args this way
+ rulethickness = "\the\dimexpr\chemicalparameter\c!rulethickness\relax", % todo: scaled points
+ rulecolor = "\MPcolor{\chemicalparameter\c!rulecolor}" % we can precalculate this for speedup
+ } ) }%
+ \ignorespaces}
+
+\appendtoks
+ \setbox\chemicalbox\hbox{\raise\MPlly\onebasepoint\box\chemicalbox}%
+ \chemicalwidth \wd\chemicalbox
+ \chemicalheight\ht\chemicalbox
+ \chemicaldepth \dp\chemicalbox
+\to \withchemicalbox
+
+% kind of compatible, but text sizes instead of math sizes (i.e. tx is larger than scriptsize)
+
+\appendtoks
+ \edef\chemicalbodyfont{\chemicalparameter\c!bodyfont}%
+ \doifnot\chemicalbodyfont\fontbody{\switchtobodyfont[\chemicalbodyfont]}% \fontbody is not expanded (yet)
+ \getvalue{\??cm:\c!size:\chemicalparameter\c!size}%
+% \to \everystructurechemical
+\to \everychemical
+
+\def\chemicaltoptext#1{\global\settrue\somechemicaltext\gdef\thetoptext{#1}\ignorespaces}
+\def\chemicalbottext#1{\global\settrue\somechemicaltext\gdef\thebottext{#1}\ignorespaces}
+\def\chemicalmidtext#1{\global\settrue\somechemicaltext\gdef\themidtext{#1}\ignorespaces}
+
+\appendtoks
+ \let\toptext\chemicaltoptext \glet\thetoptext\empty
+ \let\bottext\chemicalbottext \glet\thebottext\empty
+ \let\midtext\chemicalmidtext \glet\themidtext\empty
+ \global\setfalse\somechemicaltext
+\to \everystructurechemical
+
+\def\doaddchemicaltexts
+ {\setbox2\hbox to \chemicalwidth{\strut\hss\hbox{\strut\themidtext}\hss}%
+ \setbox4\hbox to \chemicalwidth{\strut\hss\hbox{\strut\thetoptext}\hss}%
+ \setbox6\hbox to \chemicalwidth{\strut\hss\hbox{\strut\thebottext}\hss}%
+ \setbox\chemicalbox\hbox \bgroup
+ \box\chemicalbox
+ \hskip-\chemicalwidth
+ \raise\chemicalheight\hbox{\lower\ht4\box4}%
+ \hskip-\chemicalwidth
+ \lower.5\dimexpr\ht2-\dp2\relax\box2%
+ \hskip-\chemicalwidth
+ \lower\chemicaldepth \hbox{\raise\dp6\box6}%
+ \hss
+ \egroup} % text on top of chemicals
+
+\appendtoks
+ \ifconditional\somechemicaltext
+ \doaddchemicaltexts
+ \chemicalwidth \wd\chemicalbox
+ \chemicalheight\ht\chemicalbox
+ \chemicaldepth \dp\chemicalbox
+ \fi
+\to \withchemicalbox
+
+% todo: enspace or emspace
+
+\definechemicalsymbol[space] [\enspace\quad\enspace]
+\definechemicalsymbol[plus] [\enspace+\enspace]
+\definechemicalsymbol[minus] [\enspace-\enspace]
+\definechemicalsymbol[gives] [\dochemicalarrow\xrightarrow]
+\definechemicalsymbol[equilibrium] [\dochemicalarrow\xrightoverleftarrow]
+\definechemicalsymbol[mesomeric] [\dochemicalarrow\xleftrightarrow]
+\definechemicalsymbol[opencomplex] [\mathematics{\Bigg[}] % not yet ok
+\definechemicalsymbol[closecomplex][\mathematics{\Bigg]}] % not yet ok
+
+\definechemicalsymbol[SPACE] [{\chemicalsymbol[space]}]
+\definechemicalsymbol[PLUS] [{\chemicalsymbol[plus]}]
+\definechemicalsymbol[MINUS] [{\chemicalsymbol[minus]}]
+\definechemicalsymbol[GIVES] [{\chemicalsymbol[gives]}]
+\definechemicalsymbol[EQUILIBRIUM] [{\chemicalsymbol[equilibrium]}]
+\definechemicalsymbol[MESOMERIC] [{\chemicalsymbol[mesomeric]}]
+\definechemicalsymbol[OPENCOMPLEX] [{\chemicalsymbol[opencomplex]}]
+\definechemicalsymbol[CLOSECOMPLEX][{\chemicalsymbol[closecomplex]}]
+
+\def\dochemicalarrow#1#2#3%
+ {\enspace
+ \mathematics{#1%
+ {\strut\hbox \!!spread 2em{\hss\ctxlua{chemicals.inline(\!!bs#2\!!es)}\hss}}%
+ {\strut\hbox \!!spread 2em{\hss\ctxlua{chemicals.inline(\!!bs#3\!!es)}\hss}}}%
+ \enspace}
+
+% special macros (probably needs some more work)
+
+\def\dochemicaltop#1#2#3#4%
+ {\begingroup
+ \setbox0\hbox{\tx\setstrut\strut#3}%
+ \setbox2\hbox{\setstrut\strut\molecule{#4}}%
+ \setbox0\hbox{\raise\dimexpr\dp0+\ht2\relax\hbox to \wd2{#1\box0#2}}%
+ \smashbox0
+ \hbox{\box0\box2}%
+ \endgroup}%
+
+\def\dochemicalbottom#1#2#3#4%
+ {\begingroup
+ \setbox0\hbox{\tx\setstrut\strut#3}%
+ \setbox2\hbox{\setstrut\strut#4}%
+ \setbox0\hbox{\lower\dimexpr\dp2+\ht0\relax\hbox to \wd2{#1\box0#2}}%
+ \smashbox0
+ \hbox{\box0\box2}%
+ \endgroup}%
+
+\unexpanded\def\chemicalleft#1#2%
+ {\begingroup
+ \hbox{\llap{\tx\setstrut\strut#1}\setstrut\strut#2}%
+ \endgroup}%
+
+\unexpanded\def\chemicalright#1#2%
+ {\begingroup
+ \hbox{\setstrut\strut#2\rlap{\tx\setstrut\strut#1}}%
+ \endgroup}%
+
+\unexpanded\def\chemicaltop {\dochemicaltop \hss \hss }
+\unexpanded\def\chemicallefttop {\dochemicaltop \relax \hss }
+\unexpanded\def\chemicalrighttop {\dochemicaltop \hss \relax}
+\unexpanded\def\chemicalbottom {\dochemicalbottom \hss \hss }
+\unexpanded\def\chemicalleftbottom {\dochemicalbottom \relax \hss }
+\unexpanded\def\chemicalrightbottom {\dochemicalbottom \hss \relax}
+
+\unexpanded\def\chemicaltopleft #1{\chemicalleft {\chemicalrighttop {#1}{}}}
+\unexpanded\def\chemicalbottomleft #1{\chemicalleft {\chemicalrightbottom{#1}{}}}
+\unexpanded\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}}
+\unexpanded\def\chemicalbottomright #1{\chemicalright{\chemicalleftbottom {#1}{}}}
+
+\unexpanded\def\chemicalcentered #1{\setbox\scratchbox\hbox{C}\hbox to \wd\scratchbox{\setstrut\strut\hss#1\hss}}
+\unexpanded\def\chemicalleftcentered #1{\setbox\scratchbox\hbox{C}\hbox to \wd\scratchbox{\setstrut\strut #1\hss}}
+\unexpanded\def\chemicalrightcentered#1{\setbox\scratchbox\hbox{C}\hbox to \wd\scratchbox{\setstrut\strut\hss#1}}
+
+\let\chemicalsmashedmiddle\chemicalcentered
+\let\chemicalsmashedleft \chemicalleftcentered
+\let\chemicalsmashedright \chemicalrightcentered
+
+\unexpanded\def\chemicaloxidation#1#2#3%
+ {\chemicaltop{\txx\ifcase#2\relax0\else#1\uppercase\expandafter{\romannumeral#2}\fi}{#3}}
+
+\unexpanded\def\chemicaloxidationplus {\dotriplegroupempty\chemicaloxidation{\textplus }} % {} needed!
+\unexpanded\def\chemicaloxidationminus{\dotriplegroupempty\chemicaloxidation{\textminus}} % {} needed!
+\unexpanded\def\chemicalforeveropen {\dotriplegroupempty\chemicalleft {$\big[$}} % {} needed!
+\unexpanded\def\chemicalforeverclose {\dotriplegroupempty\chemicalright {$\big]$}} % {} needed!
+\unexpanded\def\chemicaloxidationone {\chemicaloxidation\relax1}
+\unexpanded\def\chemicaloxidationtwo {\chemicaloxidation\relax2}
+\unexpanded\def\chemicaloxidationthree{\chemicaloxidation\relax3}
+\unexpanded\def\chemicaloxidationfour {\chemicaloxidation\relax4}
+\unexpanded\def\chemicaloxidationfive {\chemicaloxidation\relax5}
+\unexpanded\def\chemicaloxidationsix {\chemicaloxidation\relax6}
+\unexpanded\def\chemicaloxidationseven{\chemicaloxidation\relax7}
+
+\appendtoks
+ \let \+\chemicaloxidationplus
+ \let \-\chemicaloxidationminus
+ \let \[\chemicalforeveropen
+ \let \]\chemicalforeverclose
+ \let \1\chemicaloxidationone
+ \let \2\chemicaloxidationtwo
+ \let \3\chemicaloxidationthree
+ \let \4\chemicaloxidationfour
+ \let \5\chemicaloxidationfive
+ \let \6\chemicaloxidationsix
+ \let \7\chemicaloxidationseven
+ \let \X\chemicaltighttext
+ \let \T\chemicaltop
+ \let \B\chemicalbottom
+ \let \L\chemicalleft
+ \let\LC\chemicalleftcentered
+ \let \R\chemicalright
+ \let\RC\chemicalrightcentered
+ \let\TL\chemicaltopleft
+ \let\BL\chemicalbottomleft
+ \let\TR\chemicaltopright
+ \let\BR\chemicalbottomright
+ \let\LT\chemicallefttop
+ \let\LB\chemicalleftbottom
+ \let\RT\chemicalrighttop
+ \let\RB\chemicalrightbottom
+ \let\SL\chemicalsmashedleft
+ \let\SM\chemicalsmashedmiddle
+ \let\SR\chemicalsmashedright
+\to \everychemical
+
+\appendtoks
+ \the\everychemical
+\to \everystructurechemical
+
+% inline
+
+\unexpanded\def\chemical
+ {\ifinformula
+ \expandafter\displaychemical
+ \else
+ \expandafter\inlinechemical
+ \fi}
+
+\def\displaychemical
+ {\dotriplegroupempty\dodisplaychemical}
+
+\def\dodisplaychemical#1#2#3% todo:
+ {\the\everychemical \everychemical\emptytoks
+ \quad
+ \vcenter\bgroup
+ \ifthirdargument
+ \ifsecondargument
+ \halign{&\hss##\hss\cr#2\cr\molecule{#1}\cr#3\cr}%
+ \else
+ \halign{&\hss##\hss\cr\molecule{#1}\cr#2\cr}%
+ \fi
+ \else
+ \hbox{\molecule{#1}}%
+ \fi
+ \egroup
+ \quad}
+
+\def\inlinechemical#1%
+ {\dontleavehmode\hbox{\ctxlua{chemicals.inline(\!!bs#1\!!es)}}}
+
+\def\chemicalbondrule{\hbox{\vrule\!!height.75ex\!!depth-\dimexpr.75ex-\linewidth\relax\!!width1em\relax}}
+
+\definechemicalsymbol[i:space] [\enspace\quad\enspace]
+\definechemicalsymbol[i:plus] [\enspace\mathematics{+}\enspace]
+\definechemicalsymbol[i:minus] [\enspace\mathematics{-}\enspace]
+\definechemicalsymbol[i:gives] [\enspace\mathematics{\xrightarrow{}{}}\enspace]
+\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightpverleftarrow{}{}}\enspace]
+\definechemicalsymbol[i:mesomeric] [\enspace\mathematics{\xleftrightarrow{}{}}\enspace]
+\definechemicalsymbol[i:single] [\chemicalbondrule]
+\definechemicalsymbol[i:tripple] [\hbox{\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
+\definechemicalsymbol[i:double] [\hbox{\chemicalbondrule\hskip-1em\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
+
+\def\chemicalsinglebond {\chemicalsymbol[i:single]}
+\def\chemicaldoublebond {\chemicalsymbol[i:tripple]}
+\def\chemicaltriplebond {\chemicalsymbol[i:double]}
+\def\chemicalgives {\chemicalsymbol[i:gives]}
+\def\chemicalmesomeric {\chemicalsymbol[i:mesomeric]}
+\def\chemicalequilibrium{\chemicalsymbol[i:equilibrium]}
+\def\chemicalsplus {\chemicalsymbol[i:plus]}
+\def\chemicalsminus {\chemicalsymbol[i:minus]}
+\def\chemicalsspace {\chemicalsymbol[i:space]}
+\def\chemicalinline #1{#1}
+
+% display
+
+\newconditional\formulachemicalhastop
+\newconditional\formulachemicalhasbot
+
+\newtoks\formulachemicaltop
+\newtoks\formulachemicalmid
+\newtoks\formulachemicalbot
+
+\newif\ifinchemicalformula
+
+\def\startchemicalformula
+ {\mathortext\vcenter\vbox\bgroup
+ \forgetall
+ \inchemicalformulatrue
+ \the\everychemical
+ \everychemical\emptytoks
+ \formulachemicaltop\emptytoks % not needed
+ \formulachemicalmid\emptytoks % not needed
+ \formulachemicalbot\emptytoks % not needed
+ \let\chemical\formulachemical
+ \setfalse\formulachemicalhastop
+ \setfalse\formulachemicalhasbot }
+
+\def\stopchemicalformula
+ {\tabskip1em\relax
+ \nointerlineskip
+ \ifconditional\formulachemicalhastop
+ \ifconditional\formulachemicalhasbot
+ \halign{&\hss##\hss\cr\the\formulachemicaltop\cr\the\formulachemicalmid\cr\the\formulachemicalbot\cr}%
+ \else
+ \halign{&\hss##\hss\cr\the\formulachemicaltop\cr\the\formulachemicalmid\cr}%
+ \fi
+ \else
+ \ifconditional\formulachemicalhasbot
+ \halign{&\hss##\hss\cr\the\formulachemicalmid\cr\the\formulachemicalbot\cr}%
+ \else
+ \halign{&\hss##\hss\cr\the\formulachemicalmid\cr}%
+ \fi
+ \fi
+ \egroup}
+
+\unexpanded\def\formulachemical
+ {\relax\dotriplegroupempty\doformulachemical}
+
+\def\doformulachemical#1#2#3%
+ {\ifthirdargument
+ \doifelsenothing{#2}\noformulachemicaltop{\doformulachemicaltop{#2}}%
+ \doifelsenothing{#3}\noformulachemicalbot{\doformulachemicalbot{#3}}%
+ \else\ifsecondargument
+ \noformulachemicaltop
+ \doifelsenothing{#2}\noformulachemicalbot{\doformulachemicalbot{#2}}%
+ \else
+ \noformulachemicaltop
+ \noformulachemicalbot
+ \fi\fi
+ \formulachemicalmid\expandafter{\the\formulachemicalmid\dodochemicalformulamid{#1}&}}
+
+\def\noformulachemicaltop {\formulachemicaltop\expandafter{\the\formulachemicaltop&}}
+\def\noformulachemicalbot {\formulachemicalbot\expandafter{\the\formulachemicalbot&}}
+\def\doformulachemicaltop#1{\formulachemicaltop\expandafter{\the\formulachemicaltop\dodochemicalformulatop{#1}&}\settrue\formulachemicalhastop}
+\def\doformulachemicalbot#1{\formulachemicalbot\expandafter{\the\formulachemicalbot\dodochemicalformulabot{#1}&}\settrue\formulachemicalhasbot}
+
+\def\dodochemicalformulamid#1%
+ {\ifcsname\??cm::\detokenize{#1}\endcsname\csname\??cm::\detokenize{#1}\expandafter\endcsname\else\molecule{#1}\fi{}{}}
+
+\def\dodochemicalformulatop#1{\strut#1}
+\def\dodochemicalformulabot#1{\strut#1}
+
+% gone: state option resolution offset (now frame offset) alternative
+
+\setupchemicalframed
+ [\c!align=\v!normal,
+ \c!strut=\v!no,
+ \c!offset=\v!overlay,
+ \c!frame=off]
+
+\setupchemical
+ [\c!frame=,
+ \c!width=0,
+ \c!height=0,
+ \c!left=0,
+ \c!right=0,
+ \c!top=0,
+ \c!bottom=0,
+ \c!bodyfont=\the\bodyfontsize,
+ \c!scale=\v!medium,
+ \c!size=\v!medium,
+ \c!textsize=\v!big,
+ \c!axis=\v!off,
+ \c!style=\rm,
+ \c!location=,
+ \c!color=,
+ \c!rulethickness=\linewidth,
+ \c!rulecolor=,
+ \c!factor=1]
+
+\protect \endinput
diff --git a/tex/context/base/colo-ext.tex b/tex/context/base/colo-ext.mkii
index 33e87459d..06facd34e 100644
--- a/tex/context/base/colo-ext.tex
+++ b/tex/context/base/colo-ext.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Color Macros / extras}
+\writestatus{loading}{ConTeXt Color Macros / Extras}
\unprotect
diff --git a/tex/context/base/colo-ext.mkiv b/tex/context/base/colo-ext.mkiv
new file mode 100644
index 000000000..06facd34e
--- /dev/null
+++ b/tex/context/base/colo-ext.mkiv
@@ -0,0 +1,57 @@
+%D \module
+%D [ file=colo-ext, % mostof thsi code used to be in colo-ini.tex
+%D version=1997.04.01,
+%D title=\CONTEXT\ Color Macros,
+%D subtitle=Extras,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Color Macros / Extras}
+
+\unprotect
+
+%D \macros
+%D {negatecolorcomponent, negativecolorbox}
+%D
+%D Sometimes, especially when we deal with typesetting
+%D devices, we want to reverse the color scheme. Instead of
+%D recalculating all those colors, we use a quick and dirty
+%D approach:
+%D
+%D \starttyping
+%D \negativecolorbox0
+%D \stoptyping
+%D
+%D will negate the colors in box zero.
+
+\def\negatecolorbox#1%
+ {\setbox#1\hbox
+ {\dostartnegative
+ \localstartcolor[white]\vrule\!!height\ht#1\!!depth\dp#1\!!width\wd#1\localstopcolor
+ \hskip-\wd#1%
+ \box#1%
+ \dostopnegative}}
+
+%D There are in principle two ways to handle overprint: bound to colors
+%D or independent. For the moment we only support independent overprint
+%D handling. Here we deal with a per-document setting.
+
+\setupcolors
+ [\c!overprint=\v!no]
+
+\def\starttextoverprint
+ {\doifelse\@@cloverprint\v!yes
+ {\let\stoptextoverprint\dostopoverprint\dostartoverprint}
+ {\let\stoptextoverprint\donothing}}
+
+\let\stoptextoverprint\donothing
+
+\appendtoks \starttextoverprint \to \everystarttextproperties
+\appendtoks \stoptextoverprint \to \everystoptextproperties
+
+\protect \endinput
diff --git a/tex/context/base/colo-hex.mkii b/tex/context/base/colo-hex.mkii
new file mode 100644
index 000000000..dac2e46d0
--- /dev/null
+++ b/tex/context/base/colo-hex.mkii
@@ -0,0 +1,115 @@
+%D \module
+%D [ file=colo-hex,
+%D version=2004.06.23,
+%D title=\CONTEXT\ Color Macros,
+%D subtitle=Hex Colors,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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\dodododefinecolor\undefined \else
+ \endinput
+\fi
+
+\writestatus{loading}{ConTeXt Color Macros / Hexadecimal}
+
+% \edef\testcolor{\string#FFC0C0}
+% \edef\testcolor{\string#55}
+%
+% \setupcolors[state=start]
+%
+% \expanded{\definecolor[thehexcolor][\hexcolorspec\testcolor]}
+%
+% \checkhexcolor[\testcolor]
+%
+% \definecolor[thehexcolor][\testcolor]
+%
+% \starttext
+%
+% test \color[thehexcolor]{rood}
+% test \color[red]{rood}
+% test \color[\testcolor]{rood}
+%
+% \stoptext
+
+\unprotect
+
+\newdimen\hexcolorfraction \hexcolorfraction=\dimexpr(1pt/256)
+
+\chardef\hexcolorprefix=`#
+
+\def\hexcolorspec #1{\expandafter\dohexcolorspec #1\empty\empty\empty\empty\relax}
+\def\hexcolorpattern#1{\expandafter\dohexcolorpattern#1\empty\empty\empty\empty\relax}
+
+\ifx\dohexstringtonumber\undefined \def\dohexstringtonumber{"} \fi
+
+\def\hexcolorcomponent#1#2%
+ {\ifnum\dohexstringtonumber#1#2=\zerocount0\else\ifnum\dohexstringtonumber#1#2=\plusone1\else
+ \expandafter\withoutpt\the\dimexpr(\dohexstringtonumber#1#2\hexcolorfraction)%
+ \fi\fi}
+
+\def\dohexcolorspec#1#2#3#4#5#6#7#8\relax
+ {\ifx#4\empty
+ s=\hexcolorcomponent#2#3%
+ \else
+ r=\hexcolorcomponent#2#3,g=\hexcolorcomponent#4#5,b=\hexcolorcomponent#6#7%
+ \fi}
+
+\def\dohexcolorpattern#1#2#3#4#5#6#7#8\relax
+ {0\ifx#4\empty
+ S:\hexcolorcomponent#2#3%
+ \else
+ R:\hexcolorcomponent#2#3:\hexcolorcomponent#4#5:\hexcolorcomponent#6#7%
+ \fi:0:0}
+
+\def\doifhexcolorelse#1%
+ {\expandafter\dodoifhexcolorelse#10\od} % 0 is a dirty trick to catch an empty #1
+
+\def\dodoifhexcolorelse#1#2\od
+ {\ifnum`#1=\hexcolorprefix
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\docheckhexcolor#1%
+ {\doifhexcolorelse{#1}{\doifundefined{#1}{\setxvalue{\??cr#1}{\hexcolorpattern{#1}}}}\donothing}
+
+\def\checkhexcolor[#1]%
+ {\expanded{\docheckhexcolor{#1}}}
+
+\def\colorHpattern{\@EA\hexcolorpattern\@EA{\@EA*\@@cl@@h}} % * == dummy placeholder
+
+\let\dodododefinecolor\dododefinecolor % we will overload this one
+
+\def\dododefinecolor#1#2#3#4[#5][#6]%
+ {\doifhexcolorelse{#6}
+ {\setxvalue{\??cr#5}{\hexcolorpattern{#6}}}
+ {\dodododefinecolor#1#2#3#4[#5][#6]}}
+
+%D For Adam Lindsay and his XeTeX special driver:
+
+% because we intercept the zero condition, the .23pt in 1.23pt will disappear in the
+% ifcase zero part branch
+
+\def\colorhexcomponent#1%
+ {\ifdim#1\points<.005\points
+ 00\else\lchexnumbers{\the\dimexpr(255\dimexpr(#1\points)\relax+.5\points)\relax}%
+ \fi}
+
+% the faster one
+
+\newdimen\hex@color@a \hex@color@a=.005pt
+\newdimen\hex@color@b \hex@color@b=.5pt
+\chardef \hex@color@c =255
+
+\def\colorhexcomponent#1%
+ {\ifdim#1\points<\hex@color@a
+ 00\else\lchexnumbers{\the\dimexpr(#1\points*\hex@color@c+\hex@color@b)\relax}%
+ \fi}
+
+\protect \endinput
diff --git a/tex/context/base/colo-hex.mkiv b/tex/context/base/colo-hex.mkiv
new file mode 100644
index 000000000..b31321b7e
--- /dev/null
+++ b/tex/context/base/colo-hex.mkiv
@@ -0,0 +1,115 @@
+%D \module
+%D [ file=colo-hex,
+%D version=2004.06.23,
+%D title=\CONTEXT\ Color Macros,
+%D subtitle=Hex Colors,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Not yet supported in \MKIV.
+
+\endinput
+
+\writestatus{loading}{ConTeXt Color Macros / Hexadecimal}
+
+% \edef\testcolor{\string#FFC0C0}
+% \edef\testcolor{\string#55}
+%
+% \setupcolors[state=start]
+%
+% \expanded{\definecolor[thehexcolor][\hexcolorspec\testcolor]}
+%
+% \checkhexcolor[\testcolor]
+%
+% \definecolor[thehexcolor][\testcolor]
+%
+% \starttext
+%
+% test \color[thehexcolor]{rood}
+% test \color[red]{rood}
+% test \color[\testcolor]{rood}
+%
+% \stoptext
+
+\unprotect
+
+\newdimen\hexcolorfraction \hexcolorfraction=\dimexpr1pt/256\relax
+
+\chardef\hexcolorprefix=`#
+
+\def\hexcolorspec #1{\expandafter\dohexcolorspec #1\empty\empty\empty\empty\relax}
+\def\hexcolorpattern#1{\expandafter\dohexcolorpattern#1\empty\empty\empty\empty\relax}
+
+\ifx\dohexstringtonumber\undefined \def\dohexstringtonumber{"} \fi
+
+\def\hexcolorcomponent#1#2%
+ {\ifnum\dohexstringtonumber#1#2=\zerocount0\else\ifnum\dohexstringtonumber#1#2=\plusone1\else
+ \expandafter\withoutpt\the\dimexpr(\dohexstringtonumber#1#2\hexcolorfraction)%
+ \fi\fi}
+
+\def\dohexcolorspec#1#2#3#4#5#6#7#8\relax
+ {\ifx#4\empty
+ s=\hexcolorcomponent#2#3%
+ \else
+ r=\hexcolorcomponent#2#3,g=\hexcolorcomponent#4#5,b=\hexcolorcomponent#6#7%
+ \fi}
+
+\def\dohexcolorpattern#1#2#3#4#5#6#7#8\relax
+ {0\ifx#4\empty
+ S:\hexcolorcomponent#2#3%
+ \else
+ R:\hexcolorcomponent#2#3:\hexcolorcomponent#4#5:\hexcolorcomponent#6#7%
+ \fi:0:0}
+
+\def\doifhexcolorelse#1%
+ {\expandafter\dodoifhexcolorelse#10\od} % 0 is a dirty trick to catch an empty #1
+
+\def\dodoifhexcolorelse#1#2\od
+ {\ifnum`#1=\hexcolorprefix
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\docheckhexcolor#1%
+ {\doifhexcolorelse{#1}{\doifundefined{#1}{\setxvalue{\??cr#1}{\hexcolorpattern{#1}}}}\donothing}
+
+\def\checkhexcolor[#1]%
+ {\expanded{\docheckhexcolor{#1}}}
+
+\def\colorHpattern{\@EA\hexcolorpattern\@EA{\@EA*\@@cl@@h}} % * == dummy placeholder
+
+\let\dodododefinecolor\dododefinecolor % we will overload this one
+
+\def\dododefinecolor#1#2#3#4[#5][#6]%
+ {\doifhexcolorelse{#6}
+ {\setxvalue{\??cr#5}{\hexcolorpattern{#6}}}
+ {\dodododefinecolor#1#2#3#4[#5][#6]}}
+
+%D For Adam Lindsay and his XeTeX special driver:
+
+% because we intercept the zero condition, the .23pt in 1.23pt will disappear in the
+% ifcase zero part branch
+
+\def\colorhexcomponent#1%
+ {\ifdim#1\points<.005\points
+ 00\else\lchexnumbers{\the\dimexpr(255\dimexpr(#1\points)\relax+.5\points)\relax}%
+ \fi}
+
+% the faster one
+
+\newdimen\hex@color@a \hex@color@a=.005pt
+\newdimen\hex@color@b \hex@color@b=.5pt
+\chardef \hex@color@c =255
+
+\def\colorhexcomponent#1%
+ {\ifdim#1\points<\hex@color@a
+ 00\else\lchexnumbers{\the\dimexpr(#1\points*\hex@color@c+\hex@color@b)\relax}%
+ \fi}
+
+\protect \endinput
diff --git a/tex/context/base/colo-hex.tex b/tex/context/base/colo-hex.tex
index 8d5c3f86f..7d223c131 100644
--- a/tex/context/base/colo-hex.tex
+++ b/tex/context/base/colo-hex.tex
@@ -1,119 +1,3 @@
-%D \module
-%D [ file=colo-hex,
-%D version=2004.06.23,
-%D title=\CONTEXT\ Color Macros,
-%D subtitle=Hex Colors,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 is just a stub
-\beginLUATEX
- \endinput
-\endLUATEX
-
-\ifx\dodododefinecolor\undefined \else
- \endinput
-\fi
-
-\writestatus{loading}{Context Color Macros / hexadecimal}
-
-% \edef\testcolor{\string#FFC0C0}
-% \edef\testcolor{\string#55}
-%
-% \setupcolors[state=start]
-%
-% \expanded{\definecolor[thehexcolor][\hexcolorspec\testcolor]}
-%
-% \checkhexcolor[\testcolor]
-%
-% \definecolor[thehexcolor][\testcolor]
-%
-% \starttext
-%
-% test \color[thehexcolor]{rood}
-% test \color[red]{rood}
-% test \color[\testcolor]{rood}
-%
-% \stoptext
-
-\unprotect
-
-\newdimen\hexcolorfraction \hexcolorfraction=\dimexpr(1pt/256)
-
-\chardef\hexcolorprefix=`#
-
-\def\hexcolorspec #1{\expandafter\dohexcolorspec #1\empty\empty\empty\empty\relax}
-\def\hexcolorpattern#1{\expandafter\dohexcolorpattern#1\empty\empty\empty\empty\relax}
-
-\ifx\dohexstringtonumber\undefined \def\dohexstringtonumber{"} \fi
-
-\def\hexcolorcomponent#1#2%
- {\ifnum\dohexstringtonumber#1#2=\zerocount0\else\ifnum\dohexstringtonumber#1#2=\plusone1\else
- \expandafter\withoutpt\the\dimexpr(\dohexstringtonumber#1#2\hexcolorfraction)%
- \fi\fi}
-
-\def\dohexcolorspec#1#2#3#4#5#6#7#8\relax
- {\ifx#4\empty
- s=\hexcolorcomponent#2#3%
- \else
- r=\hexcolorcomponent#2#3,g=\hexcolorcomponent#4#5,b=\hexcolorcomponent#6#7%
- \fi}
-
-\def\dohexcolorpattern#1#2#3#4#5#6#7#8\relax
- {0\ifx#4\empty
- S:\hexcolorcomponent#2#3%
- \else
- R:\hexcolorcomponent#2#3:\hexcolorcomponent#4#5:\hexcolorcomponent#6#7%
- \fi:0:0}
-
-\def\doifhexcolorelse#1%
- {\expandafter\dodoifhexcolorelse#10\od} % 0 is a dirty trick to catch an empty #1
-
-\def\dodoifhexcolorelse#1#2\od
- {\ifnum`#1=\hexcolorprefix
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\def\docheckhexcolor#1%
- {\doifhexcolorelse{#1}{\doifundefined{#1}{\setxvalue{\??cr#1}{\hexcolorpattern{#1}}}}\donothing}
-
-\def\checkhexcolor[#1]%
- {\expanded{\docheckhexcolor{#1}}}
-
-\def\colorHpattern{\@EA\hexcolorpattern\@EA{\@EA*\@@cl@@h}} % * == dummy placeholder
-
-\let\dodododefinecolor\dododefinecolor % we will overload this one
-
-\def\dododefinecolor#1#2#3#4[#5][#6]%
- {\doifhexcolorelse{#6}
- {\setxvalue{\??cr#5}{\hexcolorpattern{#6}}}
- {\dodododefinecolor#1#2#3#4[#5][#6]}}
-
-%D For Adam Lindsay and his XeTeX special driver:
-
-% because we intercept the zero condition, the .23pt in 1.23pt will disappear in the
-% ifcase zero part branch
-
-\def\colorhexcomponent#1%
- {\ifdim#1\points<.005\points
- 00\else\lchexnumbers{\the\dimexpr(255\dimexpr(#1\points)\relax+.5\points)\relax}%
- \fi}
-
-% the faster one
-
-\newdimen\hex@color@a \hex@color@a=.005pt
-\newdimen\hex@color@b \hex@color@b=.5pt
-\chardef \hex@color@c =255
-
-\def\colorhexcomponent#1%
- {\ifdim#1\points<\hex@color@a
- 00\else\lchexnumbers{\the\dimexpr(#1\points*\hex@color@c+\hex@color@b)\relax}%
- \fi}
-
-\protect \endinput
+\loadmarkfile{colo-hex}
diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua
index 777c88572..c615aad7f 100644
--- a/tex/context/base/colo-ini.lua
+++ b/tex/context/base/colo-ini.lua
@@ -18,38 +18,20 @@ if not modules then modules = { } end modules ['colo-ini'] = {
-- todo: %s -> %f
-backends = backends or { }
-backends.pdf = backends.pdf or { }
-backend = backends.pdf
+local texsprint = tex.sprint
+local concat =table.concat
+local format, gmatch, gsub, lower = string.format, string.gmatch, string.gsub, string.lower
-local texsprint, format, concat = tex.sprint, string.format, table.concat
-
-local s_template_g = "\\dodoPDFregistergrayspotcolor{%s}{%s}{%s}{%s}{%s}" -- n f d p s (p can go away)
-local s_template_r = "\\dodoPDFregisterrgbspotcolor {%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p r g b
-local s_template_c = "\\dodoPDFregistercmykspotcolor{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p c m y k
-
-function backends.pdf.registergrayspotcolor(n,f,d,p,s) states.collect(s_template_g:format(n,f,d,p,s)) end
-function backends.pdf.registerrgbspotcolor (n,f,d,p,r,g,b) states.collect(s_template_r:format(n,f,d,p,r,g,b)) end
-function backends.pdf.registercmykspotcolor(n,f,d,p,c,m,y,k) states.collect(s_template_c:format(n,f,d,p,c,m,y,k)) end
-
-local m_template_g = "\\doPDFregistergrayindexcolor{%s}{%s}{%s}{%s}{%s}" -- n f d p s (p can go away)
-local m_template_r = "\\doPDFregisterrgbindexcolor {%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p r g b
-local m_template_c = "\\doPDFregistercmykindexcolor{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}" -- n f d p c m y k
-
-function backends.pdf.registergrayindexcolor(n,f,d,p,s) states.collect(m_template_g:format(n,f,d,p,s)) end
-function backends.pdf.registerrgbindexcolor (n,f,d,p,r,g,b) states.collect(m_template_r:format(n,f,d,p,r,g,b)) end
-function backends.pdf.registercmykindexcolor(n,f,d,p,c,m,y,k) states.collect(m_template_c:format(n,f,d,p,c,m,y,k)) end
+ctx = ctx or { }
+ctx.aux = ctx.aux or { }
-local s_template_e = "\\doPDFregisterspotcolorname{%s}{%s}" -- name, e
+local ctxcatcodes = tex.ctxcatcodes
-function backends.pdf.registerspotcolorname(name,e)
- if e and e ~= "" then
- texsprint(tex.ctxcatcodes,format(s_template_e,name,e)) -- todo in new backend: e:gsub(" ","#20")
- end
-end
+local registrations = backends.registrations
-ctx = ctx or { }
-ctx.aux = ctx.aux or { }
+local a_color = attributes.private('color')
+local a_transparency = attributes.private('transparency')
+local a_colorspace = attributes.private('colorspace')
local a_l_c_template = "\\setevalue{(ca:%s)}{%s}" ..
"\\setevalue{(cs:%s)}{\\dosetattribute{color}{%s}}"
@@ -59,10 +41,10 @@ local f_l_c_template = "\\setvalue {(ca:%s)}{\\doinheritca{%s}}" ..
"\\setvalue {(cs:%s)}{\\doinheritcs{%s}}"
local f_g_c_template = "\\setgvalue{(ca:%s)}{\\doinheritca{%s}}" ..
"\\setgvalue{(cs:%s)}{\\doinheritcs{%s}}"
-local r_l_c_template = "\\letbeundefined{(ca:%s)}" ..
- "\\letbeundefined{(cs:%s)}"
-local r_g_c_template = "\\global\\letbeundefined{(ca:%s)}" ..
- "\\global\\letbeundefined{(cs:%s)}"
+local r_l_c_template = "\\localundefine{(ca:%s)}" ..
+ "\\localundefine{(cs:%s)}"
+local r_g_c_template = "\\globalundefine{(ca:%s)}" ..
+ "\\globalundefine{(cs:%s)}"
local a_l_t_template = "\\setevalue{(ta:%s)}{%s}" ..
"\\setevalue{(ts:%s)}{\\dosetattribute{transparency}{%s}}"
@@ -72,68 +54,68 @@ local f_l_t_template = "\\setvalue {(ta:%s)}{\\doinheritta{%s}}" ..
"\\setvalue {(ts:%s)}{\\doinheritts{%s}}"
local f_g_t_template = "\\setgvalue{(ta:%s)}{\\doinheritta{%s}}" ..
"\\setgvalue{(ts:%s)}{\\doinheritts{%s}}"
-local r_l_t_template = "\\letbeundefined{(ta:%s)}" ..
- "\\letbeundefined{(ts:%s)}"
-local r_g_t_template = "\\global\\letbeundefined{(ta:%s)}" ..
- "\\global\\letbeundefined{(ts:%s)}"
+local r_l_t_template = "\\localundefine{(ta:%s)}" ..
+ "\\localundefine{(ts:%s)}"
+local r_g_t_template = "\\globalundefine{(ta:%s)}" ..
+ "\\globalundefine{(ts:%s)}"
function ctx.aux.definecolor(name, ca, global)
if ca and ca > 0 then
if global then
- texsprint(tex.ctxcatcodes,a_g_c_template:format(name, ca, name, ca))
+ texsprint(ctxcatcodes,format(a_g_c_template, name, ca, name, ca))
else
- texsprint(tex.ctxcatcodes,a_l_c_template:format(name, ca, name, ca))
+ texsprint(ctxcatcodes,format(a_l_c_template, name, ca, name, ca))
end
else
if global then
- texsprint(tex.ctxcatcodes,r_g_c_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_g_c_template, name, name))
else
- texsprint(tex.ctxcatcodes,r_l_c_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_l_c_template, name, name))
end
end
end
function ctx.aux.inheritcolor(name, ca, global)
if ca and ca ~= "" then
if global then
- texsprint(tex.ctxcatcodes,f_g_c_template:format(name, ca, name, ca))
+ texsprint(ctxcatcodes,format(f_g_c_template, name, ca, name, ca))
else
- texsprint(tex.ctxcatcodes,f_l_c_template:format(name, ca, name, ca))
+ texsprint(ctxcatcodes,format(f_l_c_template, name, ca, name, ca))
end
else
if global then
- texsprint(tex.ctxcatcodes,r_g_c_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_g_c_template, name, name))
else
- texsprint(tex.ctxcatcodes,r_l_c_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_l_c_template, name, name))
end
end
end
function ctx.aux.definetransparent(name, ta, global)
if ta and ta > 0 then
if global then
- texsprint(tex.ctxcatcodes,a_g_t_template:format(name, ta, name, ta))
+ texsprint(ctxcatcodes,format(a_g_t_template, name, ta, name, ta))
else
- texsprint(tex.ctxcatcodes,a_l_t_template:format(name, ta, name, ta))
+ texsprint(ctxcatcodes,format(a_l_t_template, name, ta, name, ta))
end
else
if global then
- texsprint(tex.ctxcatcodes,r_g_t_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_g_t_template, name, name))
else
- texsprint(tex.ctxcatcodes,r_l_t_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_l_t_template, name, name))
end
end
end
function ctx.aux.inherittransparent(name, ta, global)
if ta and ta ~= "" then
if global then
- texsprint(tex.ctxcatcodes,f_g_t_template:format(name, ta, name, ta))
+ texsprint(ctxcatcodes,format(f_g_t_template, name, ta, name, ta))
else
- texsprint(tex.ctxcatcodes,f_l_t_template:format(name, ta, name, ta))
+ texsprint(ctxcatcodes,format(f_l_t_template, name, ta, name, ta))
end
else
if global then
- texsprint(tex.ctxcatcodes,r_g_t_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_g_t_template, name, name))
else
- texsprint(tex.ctxcatcodes,r_l_t_template:format(name, name))
+ texsprint(ctxcatcodes,format(r_l_t_template, name, name))
end
end
end
@@ -173,13 +155,15 @@ local function registerspotcolor(parent,name,parentnumber,e,f,d,p)
local kind = colors.default -- else problems with shading etc
if kind == 1 then kind = v[1] end
if kind == 2 then -- name noffractions names p's r g b
- backend.registergrayspotcolor(parent,f,d,p,v[2])
+ registrations.grayspotcolor(parent,f,d,p,v[2])
elseif kind == 3 then
- backend.registerrgbspotcolor (parent,f,d,p,v[3],v[4],v[5])
+ registrations.rgbspotcolor (parent,f,d,p,v[3],v[4],v[5])
elseif kind == 4 then
- backend.registercmykspotcolor(parent,f,d,p,v[6],v[7],v[8],v[9])
+ registrations.cmykspotcolor(parent,f,d,p,v[6],v[7],v[8],v[9])
+ end
+ if e and e ~= "" then
+ registrations.spotcolorname(parent,e)
end
- backends.pdf.registerspotcolorname(parent,e)
end
registered[parentnumber] = true
end
@@ -192,11 +176,11 @@ local function registermultitonecolor(parent,name,parentnumber,e,f,d,p) -- same
local kind = colors.default -- else problems with shading etc
if kind == 1 then kind = v[1] end
if kind == 2 then
- backend.registergrayindexcolor(parent,f,d,p,v[2])
+ registrations.grayindexcolor(parent,f,d,p,v[2])
elseif kind == 3 then
- backend.registerrgbindexcolor (parent,f,d,p,v[3],v[4],v[5])
+ registrations.rgbindexcolor (parent,f,d,p,v[3],v[4],v[5])
elseif kind == 4 then
- backend.registercmykindexcolor(parent,f,d,p,v[6],v[7],v[8],v[9])
+ registrations.cmykindexcolor(parent,f,d,p,v[6],v[7],v[8],v[9])
end
end
registered[parentnumber] = true
@@ -227,8 +211,8 @@ function ctx.defineprocesscolor(name,str,global,freeze) -- still inconsistent co
ctx.aux.definetransparent(name, 0, global) -- can be sped up
end
elseif freeze then
- local ca = attributes.list[attributes.numbers['color']] [str]
- local ta = attributes.list[attributes.numbers['transparency']][str]
+ local ca = attributes.list[a_color] [str]
+ local ta = attributes.list[a_transparency][str]
if ca then
ctx.aux.definecolor(name, ca, global)
end
@@ -239,8 +223,8 @@ function ctx.defineprocesscolor(name,str,global,freeze) -- still inconsistent co
ctx.aux.inheritcolor(name, str, global)
ctx.aux.inherittransparent(name, str, global)
-- if global and str ~= "" then -- For Peter Rolf who wants access to the numbers in Lua. (Currently only global is supported.)
- -- attributes.list[attributes.numbers['color']] [name] = attributes.list[attributes.numbers['color']] [str] or -1 -- reset
- -- attributes.list[attributes.numbers['transparency']][name] = attributes.list[attributes.numbers['transparency']][str] or -1 -- reset
+ -- attributes.list[a_color] [name] = attributes.list[a_color] [str] or attributes.unsetvalue -- reset
+ -- attributes.list[a_transparency][name] = attributes.list[a_transparency][str] or attributes.unsetvalue
-- end
end
end
@@ -250,20 +234,11 @@ function ctx.isblack(ca) -- maybe commands
return (cv and cv[2] == 0) or false
end
--- function ctx.aux.colorattribute(name)
--- local al = attributes.list[attributes.numbers['color']]
--- return al[name] or 0
--- end
--- function ctx.aux.transparencyattribute(name)
--- local al = attributes.list[attributes.numbers['transparency']]
--- return al[name] or 0
--- end
-
function ctx.definespotcolor(name,parent,str,global)
if parent == "" or parent:find("=") then
ctx.registerspotcolor(name, parent)
elseif name ~= parent then
- local cp = attributes.list[attributes.numbers['color']][parent]
+ local cp = attributes.list[a_color][parent]
if cp then
local t = str:split_settings()
if t then
@@ -284,7 +259,7 @@ function ctx.definespotcolor(name,parent,str,global)
end
function ctx.registerspotcolor(parent, str)
- local cp = attributes.list[attributes.numbers['color']][parent]
+ local cp = attributes.list[a_color][parent]
if cp then
local e = ""
if str then
@@ -297,7 +272,7 @@ end
function ctx.definemultitonecolor(name,multispec,colorspec,selfspec)
local dd, pp, nn = { }, { }, { }
- for k,v in multispec:gmatch("(%a+)=([^%,]*)") do
+ for k,v in gmatch(multispec,"(%a+)=([^%,]*)") do
dd[#dd+1] = k
pp[#pp+1] = v
nn[#nn+1] = k
@@ -307,9 +282,9 @@ function ctx.definemultitonecolor(name,multispec,colorspec,selfspec)
local nof = #dd
if nof > 0 then
dd, pp, nn = concat(dd,','), concat(pp,','), concat(nn,'_')
- local parent = (nn:lower()):gsub("[^%d%a%.]+","_")
+ local parent = gsub(lower(nn),"[^%d%a%.]+","_")
ctx.defineprocesscolor(parent,colorspec..","..selfspec,true,true)
- local cp = attributes.list[attributes.numbers['color']][parent]
+ local cp = attributes.list[a_color][parent]
if cp then
registerspotcolor (parent, name, cp, "", nof, dd, pp)
registermultitonecolor(parent, name, cp, "", nof, dd, pp)
@@ -362,28 +337,26 @@ end
function ctx.formatcolor(ca,separator)
local cv = colors.value(ca)
if cv then
- local model = cv[1]
+ local c, f, t, model = { }, 13, 13, cv[1]
if model == 2 then
- return tostring(cv[2])
+ f, t = 2, 2
elseif model == 3 then
- return concat(cv,separator,3,5)
+ f, t = 3, 5
elseif model == 4 then
- return concat(cv,separator,6,9)
- else
- return tostring(cv[13])
+ f, t = 6, 9
end
+ for i=f,t do
+ c[#c+1] = format("%0.3f",cv[i])
+ end
+ return concat(c,separator)
else
- return tostring(0)
+ return format("%0.3f",0)
end
end
function ctx.formatgray(ca,separator)
local cv = colors.value(ca)
- if cv then
- return tostring(cv[2])
- else
- return tostring(0)
- end
+ return format("%0.3f",(cv and cv[2]) or 0)
end
function ctx.colorcomponents(ca)
@@ -433,7 +406,7 @@ function ctx.pdfcolor(model,ca,default) -- todo: use gray when no color
else
local n,f,d,p = cv[10],cv[11],cv[12],cv[13]
if type(p) == "string" then
- p = p:gsub(","," ") -- brr misuse of spot
+ p = gsub(p,","," ") -- brr misuse of spot
end
return format("/%s cs /%s CS %s SCN %s scn",n,n,p,p)
end
@@ -519,23 +492,23 @@ end
function ctx.resolvempgraycolor(csa,csb,model,s)
local ca = colors.register('color',nil,'gray',s)
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
end
function ctx.resolvemprgbcolor(csa,csb,model,r,g,b)
local ca = colors.register('color',nil,'rgb',r,g,b)
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
end
function ctx.resolvempcmykcolor(csa,csb,model,c,m,y,k)
local ca = colors.register('color',nil,'cmyk',c,m,y,k)
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
end
function ctx.resolvempspotcolor(csa,csb,model,n,f,d,p)
local ca = colors.register('color',nil,'spot',n,f,d,p)
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
- texsprint(tex.ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csa,ctx.pdfcolorvalue(model,ca)))
+ texsprint(ctxcatcodes,format("\\setxvalue{%s}{%s}",csb,ctx.pdfcolorspace(model,ca)))
end
-- literals needed to inject code in the mp stream, we cannot use attributes there
@@ -544,24 +517,24 @@ end
local intransparency = false
function ctx.pdfrgbliteral(model,r,g,b)
- texsprint(tex.ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'rgb',r,g,b))))
+ texsprint(ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'rgb',r,g,b))))
end
function ctx.pdfcmykliteral(model,c,m,y,k)
- texsprint(tex.ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'cmyk',c,m,y,k))))
+ texsprint(ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'cmyk',c,m,y,k))))
end
function ctx.pdfgrayliteral(model,s)
- texsprint(tex.ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'gray',s))))
+ texsprint(ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'gray',s))))
end
function ctx.pdfspotliteral(model,n,f,d,p)
- texsprint(tex.ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'spot',n,f,d,p)))) -- incorrect
+ texsprint(ctxcatcodes,format("\\pdfliteral{%s}",ctx.pdfcolor(model,colors.register('color',nil,'spot',n,f,d,p)))) -- incorrect
end
function ctx.pdftransparencyliteral(a,t)
intransparency = true
- texsprint(tex.ctxcatcodes,format("\\pdfliteral{/Tr%s gs}",transparencies.register(nil,a,t)))
+ texsprint(ctxcatcodes,format("\\pdfliteral{/Tr%s gs}",transparencies.register(nil,a,t)))
end
function ctx.pdffinishtransparency()
if intransparency then
intransparency = false
- texsprint(tex.ctxcatcodes,"\\pdfliteral{/Tr0 gs}") -- we happen to know this -)
+ texsprint(ctxcatcodes,"\\pdfliteral{/Tr0 gs}") -- we happen to know this -)
end
end
diff --git a/tex/context/base/colo-ini.mkii b/tex/context/base/colo-ini.mkii
index 745bb1679..2d2a7bdaa 100644
--- a/tex/context/base/colo-ini.mkii
+++ b/tex/context/base/colo-ini.mkii
@@ -1,6 +1,6 @@
%D \module
%D [ file=colo-ini,
-%D version=1997.04.01,
+%D version=2007.08.08,
%D title=\CONTEXT\ Color Macros,
%D subtitle=Initialization,
%D author=Hans Hagen,
@@ -11,8 +11,872 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+%D We need to clean this up further but first we hav eto make sure that mkiv
+%D code works ok.
+
+\writestatus{loading}{ConTeXt Color Macros / Initialization}
+
+%D This module implements color. Since \MKII\ and \MKIV\ use a completely
+%D different approach, this module only implements a few generic mechanisms.
+
\unprotect
+\chardef\colorversion=1 % temp, needed for tracing purposes, mkiv transition
+
+%D We use a couple of local registers. That way we don't have
+%D to group when converting colors. By the way, this is not
+%D really faster. We can sqeeze half a second runtime for 50K
+%D switches on a 1G machine, but the macros will become rather
+%D ugly then. To mention one such improvement: no colon
+%D after the key character (.25 sec).
+
+\newdimen\colordimen
+\newcount\colorcount
+
+%D When typesetting for paper, we prefer using the \cap{CMYK}
+%D color space, but for on||screen viewing we prefer \cap{RGB}
+%D (the previous implementation supported only this scheme).
+%D Independant of such specifications, we support some automatic
+%D conversions:
+%D
+%D \startitemize[packed]
+%D \item convert all colors to \cap{RGB}
+%D \item convert all colors to \cap{CMYK}
+%D \item convert all colors to gray scales
+%D \stopitemize
+%D
+%D We also support optimization of colors to gray scales.
+%D
+%D \startitemize[continue]
+%D \item reduce gray colors to gray scales
+%D \item reduce \cap{CMY} components to \cap{K}
+%D \stopitemize
+%D
+%D These options are communicated by means of:
+
+\newif\ifRGBsupported
+\newif\ifCMYKsupported
+\newif\ifSPOTsupported
+\newif\ifpreferGRAY
+\newif\ifGRAYprefered
+\newif\ifreduceCMYK
+\newif\ifconverttoGRAY
+\newif\ifweightGRAY \weightGRAYtrue
+
+\newif\ifconvertMPcolors
+\newif\ifreduceMPcolors
+\newif\ifforcegrayMPcolors
+
+%D The last boolean controls reduction of \cap{CMYK} to
+%D \cap{CMY} colors. When set to true, the black component
+%D is added to the other ones.
+%D
+%D Prefering gray is not the same as converting to gray.
+%D Conversion treats each color components in a different way,
+%D while prefering is just a reduction and thus a
+%D space||saving option.
+
+\newif\iffreezecolors \freezecolorsfalse
+\newif\ifincolor % true if colors enabled
+\newif\iflocalcolor
+
+\let\colorlist \empty
+\let\currentspotcolor \empty
+\let\allspotcolors \empty
+\let\usedspotcolors \empty
+\let\usedcolorchannels\empty
+\let\currentpalet \empty
+
+%D \macros
+%D {definecolor,defineglobalcolor,definenamedcolor,definespotcolor,definemultitonecolor}
+%D
+%D \startbuffer
+%D \definecolor [blue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
+%D \definecolor [yellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m
+%D
+%D \definespotcolor [blue-100] [blue] [p=1]
+%D \definespotcolor [yellow-100] [yellow] [p=1]
+%D
+%D \definemultitonecolor [pdftoolscolor] [blue=.12,yellow=.28] [c=.1,m=.1,y=.3,k=.1]
+%D
+%D \useexternalfigure[demofig][mill.png][object=no]
+%D
+%D \startcombination[4*1]
+%D {\externalfigure[demofig]} {no color}
+%D {\externalfigure[demofig][color=pdftoolscolor]} {indexed duotone}
+%D {\externalfigure[demofig][color=blue-100]} {spot color}
+%D {\externalfigure[demofig][color=yellow-100]} {spot color}
+%D \stopcombination
+%D \stopbuffer
+%D
+%D \getbuffer \typebuffer
+
+\def\definecolor {\dodoubleargument\dodefinecolor}
+\def\defineglobalcolor {\dodoubleargument\dodefineglobalcolor}
+\def\definenamedcolor {\dodoubleargument\dodefinenamedcolor}
+\def\definespotcolor {\dotripleargument\dodefinespotcolor}
+\def\definemultitonecolor{\doquadrupleempty\dodefinemultitonecolor}
+
+% check: registerusedspotcolors
+% check: registerusedcolorchannels
+
+%D \macros
+%D {doifcolorelse, doifcolor}
+%D
+%D Switching to a color is done by means of the following
+%D command. Later on we will explain the use of palets. We
+%D define ourselves a color conditional first.
+
+\ifx\doifcolorelse\undefined
+ \let\doifcolorelse\secondoftwoarguments
+ \let\doifcolor \gobbleoneargument
+\fi
+
+%D \macros
+%D {localstartcolor,localstopcolor}
+%D
+%D Simple color support, that is without nesting, is provided
+%D by:
+
+\ifx\localstartcolor\undefined
+ \let\localstartcolor\undefined
+ \let\localstopcolor \undefined
+\fi
+
+%D \macros
+%D {faststartcolor,faststopcolor}
+%D
+%D No checking for arguments and such:
+
+\ifx\faststartcolor\undefined
+ \def\faststartcolor[#1]{}
+ \def\faststopcolor {}
+\fi
+
+%D These local ones may go away in future versions.
+
+%D \macros
+%D {startcolor,stopcolor}
+%D
+%D The more save method, the one that saves the current color
+%D state and returns to this state afterward, is activated by:
+%D
+%D \showsetup{startcolor}
+
+\ifx\startcolor\undefined
+ \let\startcolor\undefined
+ \let\stopcolor \undefined
+\fi
+
+%D \macros
+%D {startcurrentcolor,stopcurrentcolor}
+
+\def\startcurrentcolor{\startcolor[\outercolorname]}
+\def\stopcurrentcolor {\stopcolor}
+
+%D \macros
+%D {color,graycolor}
+%D
+%D This leaves the simple color command:
+%D
+%D \showsetup{color}
+%D \showsetup{graycolor}
+
+\ifx\color\undefined
+ \def\color [#1]{}
+ \def\graycolor[#1]{}
+ \def\gray {\graycolor}
+\fi
+
+%D \macros
+%D {localstartraster,localstopraster,
+%D startraster,stopraster,raster}
+%D
+%D The previous conversions are not linear and treat each color
+%D component according to human perception curves. Pure gray
+%D (we call them rasters) has equal color components. In
+%D \CONTEXT\ rasters are only used as backgrounds and these
+%D don't cross page boundaries in the way color does. Therefore
+%D we don't need stacks and marks. Just to be compatible with
+%D color support we offer both 'global' and 'local' commands.
+
+\ifx\startraster\undefined
+ \def\startraster [#1]{}
+ \def\stopraster {}
+ \def\raster [#1]{}
+ \def\localstartraster[#1]{}
+ \def\localstopraster {}
+\fi
+
+%D \macros
+%D {colorvalue, grayvalue}
+%D
+%D We can typeset the color components using \type{\colorvalue} and
+%D \type{\grayvalue}. The commands:
+%D
+%D \startbuffer
+%D color value of SomeKindOfRed: \colorvalue{SomeKindOfRed} \crlf
+%D gray value of SomeKindOfRed: \grayvalue{SomeKindOfRed}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D show us:
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+
+\def\colorformatseparator{ }
+
+\ifx\colorvalue\undefined
+ \let\colorvalue\gobbleoneargument
+ \let\grayvalue \gobbleoneargument
+\fi
+
+% check: \currentcolorname
+% check: \outercolorname
+
+%D \macros
+%D {setupcolor}
+%D
+%D Color definitions can be grouped in files with the name:
+%D
+%D \starttyping
+%D \f!colorprefix-identifier.tex
+%D \stoptyping
+%D
+%D where \type{\f!colorprefix} is \unprotect {\tttf \f!colorprefix}.
+%D Loading such a file is done by \protect
+%D
+%D \showsetup{setupcolor}
+%D
+%D Some default colors are specified in \type{colo-rgb.tex},
+%D which is loaded into the format by:
+%D
+%D \starttyping
+%D \setupcolor[rgb]
+%D \stoptyping
+
+\let\colorstyle\empty
+
+\def\setupcolor
+ {\dosingleargument\dosetupcolor}
+
+\def\dosetupcolor[#1]%
+ {\doifnot{#1}\colorstyle
+ {\def\colorstyle{#1}%
+ \processcommalist[#1]\dodosetupcolor}}
+
+\def\dodosetupcolor#1%
+ {\makeshortfilename[\truefilename{\f!colorprefix#1}]%
+ \startreadingfile
+ \readsysfile\shortfilename
+ {\showmessage\m!colors4\colorstyle}
+ {\showmessage\m!colors5\colorstyle}%
+ \stopreadingfile}
+
+\let\usecolors\setupcolor
+
+% check: \chardef\currentcolorchannel=0
+% check: \startcolormode
+% check: \newif\iffilterspotcolor \filterspotcolorfalse
+% check: \newif\ifdoingspotcolor \doingspotcolorfalse
+% check: \registercolorchannel
+
+%D \macros
+%D {definetransparency}
+%D
+%D This command numbers to names:
+
+\def\definetransparency
+ {\dodoubleargument\dodefinetransparency}
+
+\def\setupcolors
+ {\dosingleargument\dosetupcolors}
+
+\def\resetcolorsplitting
+ {\chardef\currentcolorchannel\zerocount
+ \let\currentspotcolor\empty
+ \filterspotcolorfalse}
+
+\def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplit\fi}
+\def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplit-\fi}
+
+\def\setcolorsplitting
+ {\resetsystemmode{\v!color\colorsplitsuffix}%
+ \resetcolorsplitting
+ \processaction
+ [\@@clsplit]
+ [ c=>\chardef\currentcolorchannel1,%
+ m=>\chardef\currentcolorchannel2,%
+ y=>\chardef\currentcolorchannel3,%
+ k=>\chardef\currentcolorchannel4,%
+ r=>\chardef\currentcolorchannel5,%
+ g=>\chardef\currentcolorchannel6,%
+ b=>\chardef\currentcolorchannel7,%
+ s=>\chardef\currentcolorchannel8,%
+ \v!no=>,% \currentcolorchannel0,% all colors
+ \s!default=>,% \currentcolorchannel0,% all colors
+ \s!unknown=>\filterspotcolortrue
+ \edef\currentspotcolor{\commalistelement}]%
+ \setsystemmode{\v!color\colorsplitsuffix}%
+ \iffilterspotcolor \let\@@clrgb\v!no \fi}
+
+\ifx\dosetupcolormodel\undefined
+ \let\dosetupcolormodel\relax
+\fi
+
+\def\dosetupcolors[#1]% some no longer make sense in MkIV
+ {\getparameters[\??cl][#1]%
+ \doifelse\@@clspot\v!yes
+ \SPOTsupportedtrue
+ \SPOTsupportedfalse
+ \doifelsenothing\@@clsplit
+ \resetcolorsplitting
+ \setcolorsplitting
+ \doifelse\@@clreduction\v!yes
+ \reduceCMYKtrue
+ \reduceCMYKfalse
+ \doifelse\@@clexpansion\v!yes
+ \freezecolorstrue
+ \freezecolorsfalse
+ \doifelse\@@clcriterium\v!all
+ \hidesplitcolortrue
+ \hidesplitcolorfalse
+ \doifelse\@@clrgb\v!no
+ {\ifRGBsupported \ifproductionrun\showmessage\m!colors {9}\v!rgb \fi\RGBsupportedfalse \fi}
+ {\ifRGBsupported \else\ifproductionrun\showmessage\m!colors{10}\v!rgb \fi\RGBsupportedtrue \fi}%
+ \doifelse\@@clcmyk\v!no
+ {\ifCMYKsupported \ifproductionrun\showmessage\m!colors {9}\v!cmyk \fi\CMYKsupportedfalse\fi}
+ {\ifCMYKsupported\else\ifproductionrun\showmessage\m!colors{10}\v!cmyk \fi\CMYKsupportedtrue \fi}%
+ \doifelse\@@clmpcmyk\v!no
+ {\ifMPcmykcolors \ifproductionrun\showmessage\m!colors {9}{\v!mp\v!cmyk}\fi\MPcmykcolorsfalse \fi}
+ {\ifMPcmykcolors \else\ifproductionrun\showmessage\m!colors{10}{\v!mp\v!cmyk}\fi\MPcmykcolorstrue \fi}%
+ \doifelse\@@clmpspot\v!no
+ {\ifMPspotcolors \ifproductionrun\showmessage\m!colors {9}{\v!mp\v!spot}\fi\MPspotcolorsfalse \fi}
+ {\ifMPspotcolors \else\ifproductionrun\showmessage\m!colors{10}{\v!mp\v!spot}\fi\MPspotcolorstrue \fi}%
+ \preferGRAYfalse
+ \processaction
+ [\@@clconversion]
+ [ \v!yes=>\preferGRAYtrue,
+ \v!always=>\preferGRAYtrue\RGBsupportedfalse\CMYKsupportedfalse]%
+ \ifRGBsupported
+ \converttoGRAYfalse
+ \forcegrayMPcolorsfalse
+ \else\ifCMYKsupported
+ \converttoGRAYfalse
+ \forcegrayMPcolorsfalse
+ \convertMPcolorstrue
+ \ifreduceCMYK
+ \reduceMPcolorstrue
+ \fi
+ \else
+ \ifconverttoGRAY\else\showmessage\m!colors{11}\empty\fi
+ \converttoGRAYtrue
+ \forcegrayMPcolorstrue
+ \convertMPcolorsfalse
+ \reduceMPcolorsfalse
+ \fi\fi
+ \processaction
+ [\@@clstate]
+ [ \v!global=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
+ \incolortrue\localcolorfalse,
+ \v!local=>\ifincolor\else\showmessage\m!colors2\colorstyle\fi
+ \incolortrue\localcolortrue,
+ \v!start=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
+ \incolortrue\localcolorfalse
+ \let\@@clstate\v!global,
+ \v!stop=>\incolorfalse\localcolorfalse
+ \forcegrayMPcolorstrue]%
+ \dosetupcolormodel
+ \initializemaintextcolor}
+
+%D \macros
+%D {startregistercolor,stopregistercolor,permitcolormode}
+%D
+%D If you only want to register a color, the switch \type
+%D {\ifpermitcolormode} can be used. That way the nested
+%D colors know where to go back to.
+
+\ifx\startregistercolor\undefined
+ \def\startregistercolor[#1]{}
+ \def\stopregistercolor {}
+\fi
+
+%D We use these macros for implementing text colors
+%D (actually, the first application was in foreground
+%D colors).
+%D
+%D \starttyping
+%D \starttextcolor[red]
+%D \dorecurse{10}{\input tufte \color[green]{oeps} \par}
+%D \stoptextcolor
+%D \stoptyping
+%D
+%D This is more efficient than the alternative:
+%D
+%D \starttyping
+%D \setupbackgrounds[text][foregroundcolor=red]
+%D \startregistercolor[red]
+%D \dorecurse{10}{\input tufte \color[green]{oeps} \par}
+%D \stopregistercolor
+%D \stoptyping
+
+\def\maintextcolor {}
+\def\defaulttextcolor {black}
+\def\@@themaintextcolor{themaintextcolor}
+
+\ifx\initializemaintextcolor\undefined
+ \def\starttextcolor [#1]{}
+ \def\stoptextcolor {}
+ \def\initializemaintextcolor {}
+\fi
+
+\ifx\restoretextcolor\undefined % to be redone
+ \let\restoretextcolor \firstofoneargument
+ \let\localstarttextcolor\relax
+ \let\localstoptextcolor \relax
+\fi
+
+%D In this documentation we will not go into too much details
+%D on palets. Curious users can find more information on this
+%D topic in \from[use of color].
+%D
+%D At the moment we implemented color in \CONTEXT\ color
+%D printing was not yet on the desktop. In spite of this lack our
+%D graphics designer made colorfull illustrations. When printed
+%D on a black and white printer, distinctive colors can come
+%D out equally gray. We therefore decided to use only colors
+%D that were distinctive in colors as well as in black and
+%D white print.
+%D
+%D Although none of the graphic packages we used supported
+%D logical colors and global color redefition, we build this
+%D support into \CONTEXT. This enabled us to experiment and
+%D also prepared us for the future.
+
+%D \macros
+%D {definepalet}
+%D
+%D Colors are grouped in palets. The colors in such a palet can
+%D have colorful names, but best is to use names that specify
+%D their use, like {\em important} or {\em danger}. As a sort
+%D of example \CONTEXT\ has some palets predefined,
+%D like:\footnote{At the time I wrote the palet support, I was
+%D reading 'A hort history of time' of S.~Hawkins, so that's
+%D why we stuck to quarks.}
+%D
+%D \starttyping
+%D \definepalet
+%D [alfa]
+%D [ top=rood:7,
+%D bottom=groen:6,
+%D up=blauw:5,
+%D down=cyaan:4,
+%D strange=magenta:3,
+%D charm=geel:2]
+%D \stoptyping
+%D
+%D It's formal definition is:
+%D
+%D \showsetup{definepalet}
+%D
+%D Visualized, such a palet looks like:
+%D
+%D \startbuffer[palet]
+%D \showpalet [alfa] [horizontal,name,number,value]
+%D \stopbuffer
+%D
+%D \startlinecorrection
+%D \getbuffer[palet]
+%D \stoplinecorrection
+%D
+%D This bar shows both the color and gray alternatives of the
+%D palet components (not visible in black and white print).
+%D
+%D When needed, one can copy a palet by saying:
+%D
+%D \starttyping
+%D \definepalet [TEXcolorpretty] [colorpretty]
+%D \stoptyping
+%D
+%D This saves us some typing in for instance the modules that
+%D deal with pretty verbatim typesetting.
+
+\def\definepalet
+ {\dodoubleargument\dodefinepalet}
+
+\def\dodefinepalet[#1][#2]%
+ {\doifassignmentelse{#2}
+ {%\showmessage\m!colors6{#1}%
+ \letvalue{\??pa#1}\empty
+ \setevalue{\??pa\??pa#1}{#2}%
+ \def\dodododefinepalet[##1=##2]%
+ {\doifvaluesomething{\??pa#1}
+ {\setevalue{\??pa#1}{\csname\??pa#1\endcsname,}}%
+ \setevalue{\??pa#1}{\csname\??pa#1\endcsname##1}%
+ \dodefinepaletcolor{#1}{##1}{##2}}%
+ \def\dododefinepalet##1%
+ {\dodododefinepalet[##1]}%
+ \processcommalist[#2]\dododefinepalet}
+ {\doifdefined{\??pa#2}
+ {\expanded{\dodefinepalet[#1][\csname\??pa\??pa#2\endcsname]}}}}
+
+\ifx\dodefinepaletcolor\undefined
+ \let\dodefinepaletcolor\gobblethreearguments
+\fi
+
+\let\paletsize\!!zerocount
+
+\def\getpaletsize[#1]%
+ {\getcommacommandsize[\csname\??pa\??pa#1\endcsname]%
+ \edef\paletsize{\number\commalistsize}}
+
+%D Instead of refering to colors, one can also directly specify
+%D a color:
+%D
+%D \starttyping
+%D \definepalet[test][xx=green]
+%D \definepalet[test][xx={y=.4}]
+%D \stoptyping
+
+%D \macros
+%D {setuppalet}
+%D
+%D Colors are taken from the current palet, if defined.
+%D Setting the current palet is done by:
+%D
+%D \showsetup{setuppalet}
+
+\let\currentpalet\empty
+
+\def\setuppalet
+ {\dosingleempty\dosetuppalet}
+
+\def\dosetuppalet[#1]%
+ {\edef\currentpalet{#1}%
+ \ifx\currentpalet\empty
+ % seems to be a reset
+ \else\ifcsname\??pa\currentpalet\endcsname
+ \edef\currentpalet{#1:}%
+ \else
+ \showmessage\m!colors7\currentpalet
+ \let\currentpalet\empty
+ \fi\fi}
+
+%D \macros
+%D {showpalet}
+%D
+%D The previous visualization was typeset with:
+%D
+%D \typebuffer[palet]
+%D
+%D This commands is defined as:
+%D
+%D \showsetup{showpalet}
+
+\fetchruntimecommand \showpalet {\f!colorprefix\s!run}
+
+%D \macros
+%D {showcolorcomponents}
+%D
+%D \starttyping
+%D \showcolorcomponents[color-1,color-2]
+%D \stoptyping
+
+\fetchruntimecommand \showcolorcomponents {\f!colorprefix\s!run}
+
+%D \macros
+%D {definecolorgroup}
+%D
+%D The naming of the colors in this palet suggests some
+%D ordening, which in turn is suported by color grouping.
+%D
+%D \starttyping
+%D \definecolorgroup
+%D [red]
+%D [1.00:0.90:0.90,
+%D 1.00:0.80:0.80,
+%D 1.00:0.70:0.70,
+%D 1.00:0.55:0.55,
+%D 1.00:0.40:0.40,
+%D 1.00:0.25:0.25,
+%D 1.00:0.15:0.15,
+%D 0.90:0.00:0.00]
+%D \stoptyping
+%D
+%D In such a color group colors are numbered from~$1$ to~$n$.
+%D
+%D \showsetup{definecolorgroup}
+%D
+%D This kind of specification is not only more compact than
+%D defining each color separate, it also loads faster and takes
+%D less bytes.
+
+\def\definecolorgroup
+ {\dotripleempty\dodefinecolorgroup}
+
+\def\dododefinecolorgroupgray [#1][#2:#3]{\definecolor [#1:\the\colorcount][s=#2]}
+\def\dododefinecolorgrouprgb [#1][#2:#3:#4:#5]{\definecolor [#1:\the\colorcount][r=#2,g=#3,b=#4]}
+\def\dododefinecolorgroupcmyk[#1][#2:#3:#4:#5:#6]{\definecolor [#1:\the\colorcount][c=#2,m=#3=,y=#4,k=#5]}
+\def\dododefinecolorgroupspot [#1][#2:#3:#4]{\definespotcolor[#1:\the\colorcount][#2][p=#3]}
+
+\def\dododefinecolorgroup#1#2%
+ {\advance\colorcount\plusone
+ \getvalue{dododefinecolorgroup\currentcolorspace}[#1][#2:0:0:0:0]}
+
+\def\dodefinecolorgroup[#1][#2][#3]% obsolete, just use palets
+ {\ifthirdargument
+ \doifelsenothing{#2}{\let\currentcolorspace\v!rgb}{\def\currentcolorspace{#2}}%
+ \colorcount\zerocount
+ \processcommalist[#3]{\dododefinecolorgroup{#1}}%
+ \else
+ \doifinstringelse{:}{#2}
+ {\definecolorgroup[#1][\v!rgb][#2]}
+ {\doloop
+ {\doifdefinedelse{\??cr#2:\recurselevel}
+ {\setevalue{\??cr#1:\recurselevel}{\csname\??cr#2:\recurselevel\endcsname}}
+ {\exitloop}}}%
+ \fi}
+
+%D \macros
+%D {showcolorgroup}
+%D
+%D We can show the group by:
+%D
+%D \startbuffer
+%D \showcolorgroup [blue] [horizontal,name,number,value]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or in color:
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D which uses:
+%D
+%D \showsetup{showcolorgroup}
+
+\fetchruntimecommand \showcolorgroup {\f!colorprefix\s!run}
+
+%D There are ten predefined color groups, like
+%D \color[green]{\em groen}, \color[red]{\em rood},
+%D \color[blue]{\em blauw}, \color[cyan]{\em cyaan},
+%D \color[magenta]{\em magenta} and \color[yellow]{\em geel}.
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {\hss
+%D \showcolorgroup [red] [vertical,name,number]\hss
+%D \showcolorgroup [green] [vertical,name]\hss
+%D \showcolorgroup [blue] [vertical,name]\hss
+%D \showcolorgroup [cyan] [vertical,name]\hss
+%D \showcolorgroup [magenta][vertical,name]\hss
+%D \showcolorgroup [yellow] [vertical,name]\hss}
+%D \stoplinecorrection
+%D
+%D These groups are used to define palets {\em alfa} upto {\em
+%D zeta}. As long as we don't use colors from the same row, we
+%D get ourselves distinctive palets. By activating such a palet
+%D one gains access to its members {\em top} to {\em charm} (of
+%D course one should use more suitable names than these).
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {\showpalet [alfa] [vertical,name,number]\hss
+%D \showpalet [beta] [vertical,name]\hss
+%D \showpalet [gamma] [vertical,name]\hss
+%D \showpalet [delta] [vertical,name]\hss
+%D \showpalet [epsilon] [vertical,name]\hss
+%D \showpalet [zeta] [vertical,name]}
+%D \stoplinecorrection
+%D
+%D By using the keyword \type {value} the individual color
+%D components are shown too. When printed in color, these
+%D showcases show both the colors and the gray value.
+
+%D \macros
+%D {comparepalet}
+%D
+%D There are some more testing macros available:
+%D
+%D \startbuffer
+%D \comparepalet [alfa]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D shows the palet colors against a background:
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D The formal definition is:
+%D
+%D \showsetup{comparepalet}
+
+\fetchruntimecommand \comparepalet {\f!colorprefix\s!run}
+
+%D \macros
+%D {comparecolorgroup}
+%D
+%D The similar command:
+%D
+%D \startbuffer
+%D \comparecolorgroup [blue]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D shows color groups:
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D this commands are defined as:
+%D
+%D \showsetup{comparecolorgroup}
+
+\fetchruntimecommand \comparecolorgroup {\f!colorprefix\s!run}
+
+%D \macros
+%D {showcolor}
+%D
+%D But let's not forget that we also have the more traditional
+%D non||related colors. These show up after:
+%D
+%D \starttyping
+%D \showcolor [name]
+%D \stoptyping
+%D
+%D Where \type{name} for instance can be \type{rgb}.
+%D
+%D \showsetup{showcolor}
+
+\fetchruntimecommand \showcolor {\f!colorprefix\s!run}
+
+%D It would make sense to put the following code in \type
+%D {colo-mps}, but it it rather low level.
+
+%D \macros
+%D {negatecolorcomponent,negatedcolorcomponent}
+%D
+%D These speak for themselves. See \type {colo-ext} for usage.
+
+\def\negatecolorcomponent#1% #1 = \macro
+ {\scratchdimen\onepoint\advance\scratchdimen-#1\onepoint
+ \ifdim\scratchdimen<\zeropoint\scratchdimen\zeropoint\fi
+ \edef#1{\withoutpt\the\scratchdimen}}
+
+\let\negatedcolorcomponent\firstofoneargument
+
+\def\negatedcolorcomponent#1%
+ {\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint
+ \!!zerocount
+ \else
+ \expandafter\withoutpt\the\dimexpr\onepoint-#1\onepoint\relax
+ \fi}
+
+\def\negatecolorcomponent#1% #1 = \macro
+ {\edef#1{\negatedcolorcomponent{#1}}}
+
+%D \macros
+%D {ifMPgraphics, ifMPcmykcolors, MPcolor}
+%D
+%D A very special macro is \type{\MPcolor}. This one can be
+%D used to pass a \CONTEXT\ color to \METAPOST.
+%D
+%D \starttyping
+%D \MPcolor{my own red}
+%D \stoptyping
+%D
+%D This macro returns a \METAPOST\ triplet \type{(R,G,B)}.
+%D Unless \CMYK\ color support is turned on with \type
+%D {MPcmyk}, only \cap{RGB} colors and gray scales are
+%D supported.
+
+\newif\ifMPcmykcolors % \MPcmykcolorsfalse
+\newif\ifMPspotcolors % \MPspotcolorsfalse
+
+\ifx\MPcolor\undefined
+ \def\MPcolor#1{(0,0,0)}
+\fi
+
+%D \macros
+%D {PDFcolor,FDFcolor}
+%D
+%D Similar alternatives are avaliable for \PDF:
+
+%D For the moment we keep the next downward compatibility
+%D switch, i.e.\ expanded colors. However, predefined colors
+%D and palets are no longer expanded (which is what I wanted
+%D in the first place).
+%D
+%D Well, in case we want to do color separation and use CMYK
+%D colors only, this is dangerous since unwanted remapping may
+%D take place. Especially when we redefine already defined
+%D colors in another color space (e.g. darkgreen is
+%D predefined in RGB color space, so a redefinition in CMYK
+%D coordinates before RGB mode is disabled, would give
+%D unexpected results due to the already frozen color spec.)
+%D
+%D So, from now on, colors are not frozen any more!
+
+\chardef\currentcolorchannel=0
+
+\newif\iffilterspotcolor \filterspotcolorfalse
+\newif\ifdoingspotcolor \doingspotcolorfalse
+
+\def\registercolorchannel#1%
+ {\ifdoingspotcolor \else
+ \global\expandafter\chardef\csname\??cs#1\endcsname\zerocount
+ \fi}
+
+\newif\ifhidesplitcolor \hidesplitcolortrue
+
+%D The next macro is for instance used in figure splitting:
+
+\def\doifseparatingcolorselse
+ {\iffilterspotcolor
+ \@EA\firstoftwoarguments
+ \else\ifcase\currentcolorchannel
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \@EAEAEA\firstoftwoarguments
+ \fi\fi}
+
+\def\doifcolorchannelelse#1%
+ {\doifseparatingcolorselse
+ {\doifelsenothing{#1}
+ \secondoftwoarguments
+ {\doifelse{#1}\@@clsplit
+ \firstoftwoarguments
+ \secondoftwoarguments}}
+ \secondoftwoarguments}
+
+\def\resetcolorseparation
+ {\filterspotcolorfalse
+ \chardef\currentcolorchannel\zerocount}
+
+%D These can be used in selecting specific files (like
+%D figuredatabases).
+
+% we already have:
+%
+% \def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplitsen\fi}
+% \def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplitsen-\fi}
+
+\def\colorchannelprefix{\doifseparatingcolorselse\@@clsplit\empty-}
+\def\colorchannelsuffix{-\doifseparatingcolorselse\@@clsplit\empty}
+
+%D We now define the low level macros:
+
\chardef\colorversion=1
%D Color support is not present in \TEX. Colorful output can
@@ -165,8 +1029,12 @@
\def\dodefineglobalcolor{\dododefinecolor\doglobal\setgvalue\setxvalue1}
\def\dodefinenamedcolor {\dododefinecolor\doglobal\setvalue \setevalue0}
+\let\colorlist\empty % not really used, only for colo-run
+\setfalse\collectcolorsinlist
+\def\collectcolorinlist#1{\doglobal\addtocommalist{#1}\colorlist}
+
\def\dododefinecolor#1#2#3#4[#5][#6]% #2==set(g)value #3==set[e|x]value
- {#1\addtocommalist{#5}\colorlist % optional
+ {\ifconditional\collectcolorsinlist\collectcolorinlist{#5}\fi
\doifassignmentelse{#6}
{\@@resetcolorparameters
\getparameters[\??cl @@][#6]%
@@ -218,7 +1086,7 @@
\def\dodefinespotcolor[#1][#2][#3]% todo: always global
{\doifnot{#1}{#2}
{\@@resetcolorparameters
- \doglobal\addtocommalist{#1}\colorlist % optional
+ \ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi
\edef\@@cl@@n{#2}%
\getparameters[\??cl @@][#3]%
\doifnothing\@@cl@@p{\let\@@cl@@p\!!plusone}%
@@ -312,7 +1180,7 @@
\def\dodefinespotcolor[#1][#2][#3]% todo: always global (REDEFINED)
{\doifnot{#1}{#2}
{\@@resetcolorparameters
- \doglobal\addtocommalist{#1}\colorlist % optional
+ \ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi
\edef\@@cl@@n{#2}%
\getparameters[\??cl @@][#3]%
\doifnothing \@@cl@@p{\let\@@cl@@p\!!plusone}%
@@ -1859,4 +2727,50 @@
\appendtoks \localcolortrue \to \everyshapebox
+%D \macros
+%D {forcecolorhack}
+%D
+%D Awful \unknown
+
+\let\forcecolorhack\relax
+
+%D We default to the colors defined in \module{colo-rgb} and
+%D support both \cap{RGB} and \cap{CMYK} output. As you can
+%D see, color support is turned off by default. Reduction of
+%D gray colors to gray scales is turned on.
+
+\definecolor[black][s=0]
+\definecolor[white][s=1]
+
+\definetransparency [none] [0]
+\definetransparency [normal] [1]
+\definetransparency [multiply] [2]
+\definetransparency [screen] [3]
+\definetransparency [overlay] [4]
+\definetransparency [softlight] [5]
+\definetransparency [hardlight] [6]
+\definetransparency [colordodge] [7]
+\definetransparency [colorburn] [8]
+\definetransparency [darken] [9]
+\definetransparency [lighten] [10]
+\definetransparency [difference] [11]
+\definetransparency [exclusion] [12]
+
+\setupcolors
+ [\c!state=\v!stop,
+ \c!conversion=\v!yes,
+ \c!reduction=\v!no,
+ \c!rgb=\v!yes,
+ \c!cmyk=\v!yes,
+ \c!spot=\v!yes,
+ \c!mp\c!cmyk=\@@clcmyk,
+ \c!mp\c!spot=\@@clspot,
+ \c!expansion=\v!no,
+ \c!textcolor=,
+ \c!split=\v!no,
+ \c!criterium=\v!all]
+
+\setupcolor
+ [\v!rgb]
+
\protect \endinput
diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv
index 7f79cdfad..cf7f2446a 100644
--- a/tex/context/base/colo-ini.mkiv
+++ b/tex/context/base/colo-ini.mkiv
@@ -11,8 +11,874 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+%D We need to clean this up further but first we hav eto make sure that mkiv
+%D code works ok.
+
+\writestatus{loading}{ConTeXt Color Macros / Initialization}
+
+%D This module implements color. Since \MKII\ and \MKIV\ use a completely
+%D different approach, this module only implements a few generic mechanisms.
+
+\registerctxluafile{colo-ini}{1.000}
+
\unprotect
+\chardef\colorversion=1 % temp, needed for tracing purposes, mkiv transition
+
+%D We use a couple of local registers. That way we don't have
+%D to group when converting colors. By the way, this is not
+%D really faster. We can sqeeze half a second runtime for 50K
+%D switches on a 1G machine, but the macros will become rather
+%D ugly then. To mention one such improvement: no colon
+%D after the key character (.25 sec).
+
+\newdimen\colordimen
+\newcount\colorcount
+
+%D When typesetting for paper, we prefer using the \cap{CMYK}
+%D color space, but for on||screen viewing we prefer \cap{RGB}
+%D (the previous implementation supported only this scheme).
+%D Independant of such specifications, we support some automatic
+%D conversions:
+%D
+%D \startitemize[packed]
+%D \item convert all colors to \cap{RGB}
+%D \item convert all colors to \cap{CMYK}
+%D \item convert all colors to gray scales
+%D \stopitemize
+%D
+%D We also support optimization of colors to gray scales.
+%D
+%D \startitemize[continue]
+%D \item reduce gray colors to gray scales
+%D \item reduce \cap{CMY} components to \cap{K}
+%D \stopitemize
+%D
+%D These options are communicated by means of:
+
+\newif\ifRGBsupported
+\newif\ifCMYKsupported
+\newif\ifSPOTsupported
+\newif\ifpreferGRAY
+\newif\ifGRAYprefered
+\newif\ifreduceCMYK
+\newif\ifconverttoGRAY
+\newif\ifweightGRAY \weightGRAYtrue
+
+\newif\ifconvertMPcolors
+\newif\ifreduceMPcolors
+\newif\ifforcegrayMPcolors
+
+%D The last boolean controls reduction of \cap{CMYK} to
+%D \cap{CMY} colors. When set to true, the black component
+%D is added to the other ones.
+%D
+%D Prefering gray is not the same as converting to gray.
+%D Conversion treats each color components in a different way,
+%D while prefering is just a reduction and thus a
+%D space||saving option.
+
+\newif\iffreezecolors \freezecolorsfalse
+\newif\ifincolor % true if colors enabled
+\newif\iflocalcolor
+
+\let\colorlist \empty
+\let\currentspotcolor \empty
+\let\allspotcolors \empty
+\let\usedspotcolors \empty
+\let\usedcolorchannels\empty
+\let\currentpalet \empty
+
+%D \macros
+%D {definecolor,defineglobalcolor,definenamedcolor,definespotcolor,definemultitonecolor}
+%D
+%D \startbuffer
+%D \definecolor [blue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
+%D \definecolor [yellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m
+%D
+%D \definespotcolor [blue-100] [blue] [p=1]
+%D \definespotcolor [yellow-100] [yellow] [p=1]
+%D
+%D \definemultitonecolor [pdftoolscolor] [blue=.12,yellow=.28] [c=.1,m=.1,y=.3,k=.1]
+%D
+%D \useexternalfigure[demofig][mill.png][object=no]
+%D
+%D \startcombination[4*1]
+%D {\externalfigure[demofig]} {no color}
+%D {\externalfigure[demofig][color=pdftoolscolor]} {indexed duotone}
+%D {\externalfigure[demofig][color=blue-100]} {spot color}
+%D {\externalfigure[demofig][color=yellow-100]} {spot color}
+%D \stopcombination
+%D \stopbuffer
+%D
+%D \getbuffer \typebuffer
+
+\def\definecolor {\dodoubleargument\dodefinecolor}
+\def\defineglobalcolor {\dodoubleargument\dodefineglobalcolor}
+\def\definenamedcolor {\dodoubleargument\dodefinenamedcolor}
+\def\definespotcolor {\dotripleargument\dodefinespotcolor}
+\def\definemultitonecolor{\doquadrupleempty\dodefinemultitonecolor}
+
+% check: registerusedspotcolors
+% check: registerusedcolorchannels
+
+%D \macros
+%D {doifcolorelse, doifcolor}
+%D
+%D Switching to a color is done by means of the following
+%D command. Later on we will explain the use of palets. We
+%D define ourselves a color conditional first.
+
+\ifx\doifcolorelse\undefined
+ \let\doifcolorelse\secondoftwoarguments
+ \let\doifcolor \gobbleoneargument
+\fi
+
+%D \macros
+%D {localstartcolor,localstopcolor}
+%D
+%D Simple color support, that is without nesting, is provided
+%D by:
+
+\ifx\localstartcolor\undefined
+ \let\localstartcolor\undefined
+ \let\localstopcolor \undefined
+\fi
+
+%D \macros
+%D {faststartcolor,faststopcolor}
+%D
+%D No checking for arguments and such:
+
+\ifx\faststartcolor\undefined
+ \def\faststartcolor[#1]{}
+ \def\faststopcolor {}
+\fi
+
+%D These local ones may go away in future versions.
+
+%D \macros
+%D {startcolor,stopcolor}
+%D
+%D The more save method, the one that saves the current color
+%D state and returns to this state afterward, is activated by:
+%D
+%D \showsetup{startcolor}
+
+\ifx\startcolor\undefined
+ \let\startcolor\undefined
+ \let\stopcolor \undefined
+\fi
+
+%D \macros
+%D {startcurrentcolor,stopcurrentcolor}
+
+\def\startcurrentcolor{\startcolor[\outercolorname]}
+\def\stopcurrentcolor {\stopcolor}
+
+%D \macros
+%D {color,graycolor}
+%D
+%D This leaves the simple color command:
+%D
+%D \showsetup{color}
+%D \showsetup{graycolor}
+
+\ifx\color\undefined
+ \def\color [#1]{}
+ \def\graycolor[#1]{}
+ \def\gray {\graycolor}
+\fi
+
+%D \macros
+%D {localstartraster,localstopraster,
+%D startraster,stopraster,raster}
+%D
+%D The previous conversions are not linear and treat each color
+%D component according to human perception curves. Pure gray
+%D (we call them rasters) has equal color components. In
+%D \CONTEXT\ rasters are only used as backgrounds and these
+%D don't cross page boundaries in the way color does. Therefore
+%D we don't need stacks and marks. Just to be compatible with
+%D color support we offer both 'global' and 'local' commands.
+
+\ifx\startraster\undefined
+ \def\startraster [#1]{}
+ \def\stopraster {}
+ \def\raster [#1]{}
+ \def\localstartraster[#1]{}
+ \def\localstopraster {}
+\fi
+
+%D \macros
+%D {colorvalue, grayvalue}
+%D
+%D We can typeset the color components using \type{\colorvalue} and
+%D \type{\grayvalue}. The commands:
+%D
+%D \startbuffer
+%D color value of SomeKindOfRed: \colorvalue{SomeKindOfRed} \crlf
+%D gray value of SomeKindOfRed: \grayvalue{SomeKindOfRed}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D show us:
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+
+\def\colorformatseparator{ }
+
+\ifx\colorvalue\undefined
+ \let\colorvalue\gobbleoneargument
+ \let\grayvalue \gobbleoneargument
+\fi
+
+% check: \currentcolorname
+% check: \outercolorname
+
+%D \macros
+%D {setupcolor}
+%D
+%D Color definitions can be grouped in files with the name:
+%D
+%D \starttyping
+%D \f!colorprefix-identifier.tex
+%D \stoptyping
+%D
+%D where \type{\f!colorprefix} is \unprotect {\tttf \f!colorprefix}.
+%D Loading such a file is done by \protect
+%D
+%D \showsetup{setupcolor}
+%D
+%D Some default colors are specified in \type{colo-rgb.tex},
+%D which is loaded into the format by:
+%D
+%D \starttyping
+%D \setupcolor[rgb]
+%D \stoptyping
+
+\let\colorstyle\empty
+
+\def\setupcolor
+ {\dosingleargument\dosetupcolor}
+
+\def\dosetupcolor[#1]%
+ {\doifnot{#1}\colorstyle
+ {\def\colorstyle{#1}%
+ \processcommalist[#1]\dodosetupcolor}}
+
+\def\dodosetupcolor#1%
+ {\makeshortfilename[\truefilename{\f!colorprefix#1}]%
+ \startreadingfile
+ \readsysfile\shortfilename
+ {\showmessage\m!colors4\colorstyle}
+ {\showmessage\m!colors5\colorstyle}%
+ \stopreadingfile}
+
+\let\usecolors\setupcolor
+
+% check: \chardef\currentcolorchannel=0
+% check: \startcolormode
+% check: \newif\iffilterspotcolor \filterspotcolorfalse
+% check: \newif\ifdoingspotcolor \doingspotcolorfalse
+% check: \registercolorchannel
+
+%D \macros
+%D {definetransparency}
+%D
+%D This command numbers to names:
+
+\def\definetransparency
+ {\dodoubleargument\dodefinetransparency}
+
+\def\setupcolors
+ {\dosingleargument\dosetupcolors}
+
+\def\resetcolorsplitting
+ {\chardef\currentcolorchannel\zerocount
+ \let\currentspotcolor\empty
+ \filterspotcolorfalse}
+
+\def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplit\fi}
+\def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplit-\fi}
+
+\def\setcolorsplitting
+ {\resetsystemmode{\v!color\colorsplitsuffix}%
+ \resetcolorsplitting
+ \processaction
+ [\@@clsplit]
+ [ c=>\chardef\currentcolorchannel1,%
+ m=>\chardef\currentcolorchannel2,%
+ y=>\chardef\currentcolorchannel3,%
+ k=>\chardef\currentcolorchannel4,%
+ r=>\chardef\currentcolorchannel5,%
+ g=>\chardef\currentcolorchannel6,%
+ b=>\chardef\currentcolorchannel7,%
+ s=>\chardef\currentcolorchannel8,%
+ \v!no=>,% \currentcolorchannel0,% all colors
+ \s!default=>,% \currentcolorchannel0,% all colors
+ \s!unknown=>\filterspotcolortrue
+ \edef\currentspotcolor{\commalistelement}]%
+ \setsystemmode{\v!color\colorsplitsuffix}%
+ \iffilterspotcolor \let\@@clrgb\v!no \fi}
+
+\ifx\dosetupcolormodel\undefined
+ \let\dosetupcolormodel\relax
+\fi
+
+\def\dosetupcolors[#1]% some no longer make sense in MkIV
+ {\getparameters[\??cl][#1]%
+ \doifelse\@@clspot\v!yes
+ \SPOTsupportedtrue
+ \SPOTsupportedfalse
+ \doifelsenothing\@@clsplit
+ \resetcolorsplitting
+ \setcolorsplitting
+ \doifelse\@@clreduction\v!yes
+ \reduceCMYKtrue
+ \reduceCMYKfalse
+ \doifelse\@@clexpansion\v!yes
+ \freezecolorstrue
+ \freezecolorsfalse
+ \doifelse\@@clcriterium\v!all
+ \hidesplitcolortrue
+ \hidesplitcolorfalse
+ \doifelse\@@clrgb\v!no
+ {\ifRGBsupported \ifproductionrun\showmessage\m!colors {9}\v!rgb \fi\RGBsupportedfalse \fi}
+ {\ifRGBsupported \else\ifproductionrun\showmessage\m!colors{10}\v!rgb \fi\RGBsupportedtrue \fi}%
+ \doifelse\@@clcmyk\v!no
+ {\ifCMYKsupported \ifproductionrun\showmessage\m!colors {9}\v!cmyk \fi\CMYKsupportedfalse\fi}
+ {\ifCMYKsupported\else\ifproductionrun\showmessage\m!colors{10}\v!cmyk \fi\CMYKsupportedtrue \fi}%
+ \doifelse\@@clmpcmyk\v!no
+ {\ifMPcmykcolors \ifproductionrun\showmessage\m!colors {9}{\v!mp\v!cmyk}\fi\MPcmykcolorsfalse \fi}
+ {\ifMPcmykcolors \else\ifproductionrun\showmessage\m!colors{10}{\v!mp\v!cmyk}\fi\MPcmykcolorstrue \fi}%
+ \doifelse\@@clmpspot\v!no
+ {\ifMPspotcolors \ifproductionrun\showmessage\m!colors {9}{\v!mp\v!spot}\fi\MPspotcolorsfalse \fi}
+ {\ifMPspotcolors \else\ifproductionrun\showmessage\m!colors{10}{\v!mp\v!spot}\fi\MPspotcolorstrue \fi}%
+ \preferGRAYfalse
+ \processaction
+ [\@@clconversion]
+ [ \v!yes=>\preferGRAYtrue,
+ \v!always=>\preferGRAYtrue\RGBsupportedfalse\CMYKsupportedfalse]%
+ \ifRGBsupported
+ \converttoGRAYfalse
+ \forcegrayMPcolorsfalse
+ \else\ifCMYKsupported
+ \converttoGRAYfalse
+ \forcegrayMPcolorsfalse
+ \convertMPcolorstrue
+ \ifreduceCMYK
+ \reduceMPcolorstrue
+ \fi
+ \else
+ \ifconverttoGRAY\else\showmessage\m!colors{11}\empty\fi
+ \converttoGRAYtrue
+ \forcegrayMPcolorstrue
+ \convertMPcolorsfalse
+ \reduceMPcolorsfalse
+ \fi\fi
+ \processaction
+ [\@@clstate]
+ [ \v!global=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
+ \incolortrue\localcolorfalse,
+ \v!local=>\ifincolor\else\showmessage\m!colors2\colorstyle\fi
+ \incolortrue\localcolortrue,
+ \v!start=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
+ \incolortrue\localcolorfalse
+ \let\@@clstate\v!global,
+ \v!stop=>\incolorfalse\localcolorfalse
+ \forcegrayMPcolorstrue]%
+ \dosetupcolormodel
+ \initializemaintextcolor}
+
+%D \macros
+%D {startregistercolor,stopregistercolor,permitcolormode}
+%D
+%D If you only want to register a color, the switch \type
+%D {\ifpermitcolormode} can be used. That way the nested
+%D colors know where to go back to.
+
+\ifx\startregistercolor\undefined
+ \def\startregistercolor[#1]{}
+ \def\stopregistercolor {}
+\fi
+
+%D We use these macros for implementing text colors
+%D (actually, the first application was in foreground
+%D colors).
+%D
+%D \starttyping
+%D \starttextcolor[red]
+%D \dorecurse{10}{\input tufte \color[green]{oeps} \par}
+%D \stoptextcolor
+%D \stoptyping
+%D
+%D This is more efficient than the alternative:
+%D
+%D \starttyping
+%D \setupbackgrounds[text][foregroundcolor=red]
+%D \startregistercolor[red]
+%D \dorecurse{10}{\input tufte \color[green]{oeps} \par}
+%D \stopregistercolor
+%D \stoptyping
+
+\def\maintextcolor {}
+\def\defaulttextcolor {black}
+\def\@@themaintextcolor{themaintextcolor}
+
+\ifx\initializemaintextcolor\undefined
+ \def\starttextcolor [#1]{}
+ \def\stoptextcolor {}
+ \def\initializemaintextcolor {}
+\fi
+
+\ifx\restoretextcolor\undefined % to be redone
+ \let\restoretextcolor \firstofoneargument
+ \let\localstarttextcolor\relax
+ \let\localstoptextcolor \relax
+\fi
+
+%D In this documentation we will not go into too much details
+%D on palets. Curious users can find more information on this
+%D topic in \from[use of color].
+%D
+%D At the moment we implemented color in \CONTEXT\ color
+%D printing was not yet on the desktop. In spite of this lack our
+%D graphics designer made colorfull illustrations. When printed
+%D on a black and white printer, distinctive colors can come
+%D out equally gray. We therefore decided to use only colors
+%D that were distinctive in colors as well as in black and
+%D white print.
+%D
+%D Although none of the graphic packages we used supported
+%D logical colors and global color redefition, we build this
+%D support into \CONTEXT. This enabled us to experiment and
+%D also prepared us for the future.
+
+%D \macros
+%D {definepalet}
+%D
+%D Colors are grouped in palets. The colors in such a palet can
+%D have colorful names, but best is to use names that specify
+%D their use, like {\em important} or {\em danger}. As a sort
+%D of example \CONTEXT\ has some palets predefined,
+%D like:\footnote{At the time I wrote the palet support, I was
+%D reading 'A hort history of time' of S.~Hawkins, so that's
+%D why we stuck to quarks.}
+%D
+%D \starttyping
+%D \definepalet
+%D [alfa]
+%D [ top=rood:7,
+%D bottom=groen:6,
+%D up=blauw:5,
+%D down=cyaan:4,
+%D strange=magenta:3,
+%D charm=geel:2]
+%D \stoptyping
+%D
+%D It's formal definition is:
+%D
+%D \showsetup{definepalet}
+%D
+%D Visualized, such a palet looks like:
+%D
+%D \startbuffer[palet]
+%D \showpalet [alfa] [horizontal,name,number,value]
+%D \stopbuffer
+%D
+%D \startlinecorrection
+%D \getbuffer[palet]
+%D \stoplinecorrection
+%D
+%D This bar shows both the color and gray alternatives of the
+%D palet components (not visible in black and white print).
+%D
+%D When needed, one can copy a palet by saying:
+%D
+%D \starttyping
+%D \definepalet [TEXcolorpretty] [colorpretty]
+%D \stoptyping
+%D
+%D This saves us some typing in for instance the modules that
+%D deal with pretty verbatim typesetting.
+
+\def\definepalet
+ {\dodoubleargument\dodefinepalet}
+
+\def\dodefinepalet[#1][#2]%
+ {\doifassignmentelse{#2}
+ {%\showmessage\m!colors6{#1}%
+ \letvalue{\??pa#1}\empty
+ \setevalue{\??pa\??pa#1}{#2}%
+ \def\dodododefinepalet[##1=##2]%
+ {\doifvaluesomething{\??pa#1}
+ {\setevalue{\??pa#1}{\csname\??pa#1\endcsname,}}%
+ \setevalue{\??pa#1}{\csname\??pa#1\endcsname##1}%
+ \dodefinepaletcolor{#1}{##1}{##2}}%
+ \def\dododefinepalet##1%
+ {\dodododefinepalet[##1]}%
+ \processcommalist[#2]\dododefinepalet}
+ {\doifdefined{\??pa#2}
+ {\expanded{\dodefinepalet[#1][\csname\??pa\??pa#2\endcsname]}}}}
+
+\ifx\dodefinepaletcolor\undefined
+ \let\dodefinepaletcolor\gobblethreearguments
+\fi
+
+\let\paletsize\!!zerocount
+
+\def\getpaletsize[#1]%
+ {\getcommacommandsize[\csname\??pa\??pa#1\endcsname]%
+ \edef\paletsize{\number\commalistsize}}
+
+%D Instead of refering to colors, one can also directly specify
+%D a color:
+%D
+%D \starttyping
+%D \definepalet[test][xx=green]
+%D \definepalet[test][xx={y=.4}]
+%D \stoptyping
+
+%D \macros
+%D {setuppalet}
+%D
+%D Colors are taken from the current palet, if defined.
+%D Setting the current palet is done by:
+%D
+%D \showsetup{setuppalet}
+
+\let\currentpalet\empty
+
+\def\setuppalet
+ {\dosingleempty\dosetuppalet}
+
+\def\dosetuppalet[#1]%
+ {\edef\currentpalet{#1}%
+ \ifx\currentpalet\empty
+ % seems to be a reset
+ \else\ifcsname\??pa\currentpalet\endcsname
+ \edef\currentpalet{#1:}%
+ \else
+ \showmessage\m!colors7\currentpalet
+ \let\currentpalet\empty
+ \fi\fi}
+
+%D \macros
+%D {showpalet}
+%D
+%D The previous visualization was typeset with:
+%D
+%D \typebuffer[palet]
+%D
+%D This commands is defined as:
+%D
+%D \showsetup{showpalet}
+
+\fetchruntimecommand \showpalet {\f!colorprefix\s!run}
+
+%D \macros
+%D {showcolorcomponents}
+%D
+%D \starttyping
+%D \showcolorcomponents[color-1,color-2]
+%D \stoptyping
+
+\fetchruntimecommand \showcolorcomponents {\f!colorprefix\s!run}
+
+%D \macros
+%D {definecolorgroup}
+%D
+%D The naming of the colors in this palet suggests some
+%D ordening, which in turn is suported by color grouping.
+%D
+%D \starttyping
+%D \definecolorgroup
+%D [red]
+%D [1.00:0.90:0.90,
+%D 1.00:0.80:0.80,
+%D 1.00:0.70:0.70,
+%D 1.00:0.55:0.55,
+%D 1.00:0.40:0.40,
+%D 1.00:0.25:0.25,
+%D 1.00:0.15:0.15,
+%D 0.90:0.00:0.00]
+%D \stoptyping
+%D
+%D In such a color group colors are numbered from~$1$ to~$n$.
+%D
+%D \showsetup{definecolorgroup}
+%D
+%D This kind of specification is not only more compact than
+%D defining each color separate, it also loads faster and takes
+%D less bytes.
+
+\def\definecolorgroup
+ {\dotripleempty\dodefinecolorgroup}
+
+\def\dododefinecolorgroupgray [#1][#2:#3]{\definecolor [#1:\the\colorcount][s=#2]}
+\def\dododefinecolorgrouprgb [#1][#2:#3:#4:#5]{\definecolor [#1:\the\colorcount][r=#2,g=#3,b=#4]}
+\def\dododefinecolorgroupcmyk[#1][#2:#3:#4:#5:#6]{\definecolor [#1:\the\colorcount][c=#2,m=#3=,y=#4,k=#5]}
+\def\dododefinecolorgroupspot [#1][#2:#3:#4]{\definespotcolor[#1:\the\colorcount][#2][p=#3]}
+
+\def\dododefinecolorgroup#1#2%
+ {\advance\colorcount\plusone
+ \getvalue{dododefinecolorgroup\currentcolorspace}[#1][#2:0:0:0:0]}
+
+\def\dodefinecolorgroup[#1][#2][#3]% obsolete, just use palets
+ {\ifthirdargument
+ \doifelsenothing{#2}{\let\currentcolorspace\v!rgb}{\def\currentcolorspace{#2}}%
+ \colorcount\zerocount
+ \processcommalist[#3]{\dododefinecolorgroup{#1}}%
+ \else
+ \doifinstringelse{:}{#2}
+ {\definecolorgroup[#1][\v!rgb][#2]}
+ {\doloop
+ {\doifdefinedelse{\??cr#2:\recurselevel}
+ {\setevalue{\??cr#1:\recurselevel}{\csname\??cr#2:\recurselevel\endcsname}}
+ {\exitloop}}}%
+ \fi}
+
+%D \macros
+%D {showcolorgroup}
+%D
+%D We can show the group by:
+%D
+%D \startbuffer
+%D \showcolorgroup [blue] [horizontal,name,number,value]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or in color:
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D which uses:
+%D
+%D \showsetup{showcolorgroup}
+
+\fetchruntimecommand \showcolorgroup {\f!colorprefix\s!run}
+
+%D There are ten predefined color groups, like
+%D \color[green]{\em groen}, \color[red]{\em rood},
+%D \color[blue]{\em blauw}, \color[cyan]{\em cyaan},
+%D \color[magenta]{\em magenta} and \color[yellow]{\em geel}.
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {\hss
+%D \showcolorgroup [red] [vertical,name,number]\hss
+%D \showcolorgroup [green] [vertical,name]\hss
+%D \showcolorgroup [blue] [vertical,name]\hss
+%D \showcolorgroup [cyan] [vertical,name]\hss
+%D \showcolorgroup [magenta][vertical,name]\hss
+%D \showcolorgroup [yellow] [vertical,name]\hss}
+%D \stoplinecorrection
+%D
+%D These groups are used to define palets {\em alfa} upto {\em
+%D zeta}. As long as we don't use colors from the same row, we
+%D get ourselves distinctive palets. By activating such a palet
+%D one gains access to its members {\em top} to {\em charm} (of
+%D course one should use more suitable names than these).
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {\showpalet [alfa] [vertical,name,number]\hss
+%D \showpalet [beta] [vertical,name]\hss
+%D \showpalet [gamma] [vertical,name]\hss
+%D \showpalet [delta] [vertical,name]\hss
+%D \showpalet [epsilon] [vertical,name]\hss
+%D \showpalet [zeta] [vertical,name]}
+%D \stoplinecorrection
+%D
+%D By using the keyword \type {value} the individual color
+%D components are shown too. When printed in color, these
+%D showcases show both the colors and the gray value.
+
+%D \macros
+%D {comparepalet}
+%D
+%D There are some more testing macros available:
+%D
+%D \startbuffer
+%D \comparepalet [alfa]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D shows the palet colors against a background:
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D The formal definition is:
+%D
+%D \showsetup{comparepalet}
+
+\fetchruntimecommand \comparepalet {\f!colorprefix\s!run}
+
+%D \macros
+%D {comparecolorgroup}
+%D
+%D The similar command:
+%D
+%D \startbuffer
+%D \comparecolorgroup [blue]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D shows color groups:
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D this commands are defined as:
+%D
+%D \showsetup{comparecolorgroup}
+
+\fetchruntimecommand \comparecolorgroup {\f!colorprefix\s!run}
+
+%D \macros
+%D {showcolor}
+%D
+%D But let's not forget that we also have the more traditional
+%D non||related colors. These show up after:
+%D
+%D \starttyping
+%D \showcolor [name]
+%D \stoptyping
+%D
+%D Where \type{name} for instance can be \type{rgb}.
+%D
+%D \showsetup{showcolor}
+
+\fetchruntimecommand \showcolor {\f!colorprefix\s!run}
+
+%D It would make sense to put the following code in \type
+%D {colo-mps}, but it it rather low level.
+
+%D \macros
+%D {negatecolorcomponent,negatedcolorcomponent}
+%D
+%D These speak for themselves. See \type {colo-ext} for usage.
+
+\def\negatecolorcomponent#1% #1 = \macro
+ {\scratchdimen\onepoint\advance\scratchdimen-#1\onepoint
+ \ifdim\scratchdimen<\zeropoint\scratchdimen\zeropoint\fi
+ \edef#1{\withoutpt\the\scratchdimen}}
+
+\let\negatedcolorcomponent\firstofoneargument
+
+\def\negatedcolorcomponent#1%
+ {\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint
+ \!!zerocount
+ \else
+ \expandafter\withoutpt\the\dimexpr\onepoint-#1\onepoint\relax
+ \fi}
+
+\def\negatecolorcomponent#1% #1 = \macro
+ {\edef#1{\negatedcolorcomponent{#1}}}
+
+%D \macros
+%D {ifMPgraphics, ifMPcmykcolors, MPcolor}
+%D
+%D A very special macro is \type{\MPcolor}. This one can be
+%D used to pass a \CONTEXT\ color to \METAPOST.
+%D
+%D \starttyping
+%D \MPcolor{my own red}
+%D \stoptyping
+%D
+%D This macro returns a \METAPOST\ triplet \type{(R,G,B)}.
+%D Unless \CMYK\ color support is turned on with \type
+%D {MPcmyk}, only \cap{RGB} colors and gray scales are
+%D supported.
+
+\newif\ifMPcmykcolors % \MPcmykcolorsfalse
+\newif\ifMPspotcolors % \MPspotcolorsfalse
+
+\ifx\MPcolor\undefined
+ \def\MPcolor#1{(0,0,0)}
+\fi
+
+%D \macros
+%D {PDFcolor,FDFcolor}
+%D
+%D Similar alternatives are avaliable for \PDF:
+
+%D For the moment we keep the next downward compatibility
+%D switch, i.e.\ expanded colors. However, predefined colors
+%D and palets are no longer expanded (which is what I wanted
+%D in the first place).
+%D
+%D Well, in case we want to do color separation and use CMYK
+%D colors only, this is dangerous since unwanted remapping may
+%D take place. Especially when we redefine already defined
+%D colors in another color space (e.g. darkgreen is
+%D predefined in RGB color space, so a redefinition in CMYK
+%D coordinates before RGB mode is disabled, would give
+%D unexpected results due to the already frozen color spec.)
+%D
+%D So, from now on, colors are not frozen any more!
+
+\chardef\currentcolorchannel=0
+
+\newif\iffilterspotcolor \filterspotcolorfalse
+\newif\ifdoingspotcolor \doingspotcolorfalse
+
+\def\registercolorchannel#1%
+ {\ifdoingspotcolor \else
+ \global\expandafter\chardef\csname\??cs#1\endcsname\zerocount
+ \fi}
+
+\newif\ifhidesplitcolor \hidesplitcolortrue
+
+%D The next macro is for instance used in figure splitting:
+
+\def\doifseparatingcolorselse
+ {\iffilterspotcolor
+ \@EA\firstoftwoarguments
+ \else\ifcase\currentcolorchannel
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \@EAEAEA\firstoftwoarguments
+ \fi\fi}
+
+\def\doifcolorchannelelse#1%
+ {\doifseparatingcolorselse
+ {\doifelsenothing{#1}
+ \secondoftwoarguments
+ {\doifelse{#1}\@@clsplit
+ \firstoftwoarguments
+ \secondoftwoarguments}}
+ \secondoftwoarguments}
+
+\def\resetcolorseparation
+ {\filterspotcolorfalse
+ \chardef\currentcolorchannel\zerocount}
+
+%D These can be used in selecting specific files (like
+%D figuredatabases).
+
+% we already have:
+%
+% \def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplitsen\fi}
+% \def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplitsen-\fi}
+
+\def\colorchannelprefix{\doifseparatingcolorselse\@@clsplit\empty-}
+\def\colorchannelsuffix{-\doifseparatingcolorselse\@@clsplit\empty}
+
+%D We now define the low level macros:
+
\chardef\colorversion=2
% todo: palets in definecolor
@@ -37,8 +903,6 @@
% draw btex test etex withprescript \mptexcolor{blue} ;
% \stopMPpage
-\registerctxluafile{colo-ini}{1.000}
-
\ifx\currentcolormodel\undefined \newcount\currentcolormodel \fi
\def\setcolormodel#1%
@@ -79,28 +943,9 @@
% Since we couple definitions, we could stick to one test. Todo. Same for mpcolor.
-% \def\doactivatecolor#1% : in currentpalet, maybe not, ugly
-% {\ifcsname(cs:\currentpalet#1)\endcsname
-% \csname(cs:\currentpalet#1)\endcsname
-% \csname(ts:\currentpalet#1)\endcsname
-% \else
-% \csname(cs:#1)\endcsname
-% \csname(ts:#1)\endcsname
-% \fi}
-
-% \def\doactivatecolor#1% : in currentpalet, maybe not, ugly
-% {\csname(cs:\ifcsname(cs:\currentpalet#1)\endcsname\currentpalet\fi#1)\endcsname}
-% \csname(ts:\ifcsname(ts:\currentpalet#1)\endcsname\currentpalet\fi#1)\endcsname}
-%
-% more robust test, else we get \relaxed non-colors which may confuse e.g. mpcolor
-
\letvalue{(cs:-}\empty
\letvalue{(ts:-}\empty
-% \def\doactivatecolor#1% : in currentpalet, maybe not, ugly
-% {\csname(cs:\ifcsname(cs:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(cs:#1)\endcsname#1\else-\fi\fi)\endcsname
-% \csname(ts:\ifcsname(ts:\currentpalet#1)\endcsname\currentpalet#1\else\ifcsname(ts:#1)\endcsname#1\else-\fi\fi)\endcsname}
-
\def\doactivatecolor#1% : in currentpalet, maybe not, ugly
{\ifcsname(cs:\currentpalet#1)\endcsname
\csname(cs:\currentpalet#1)\endcsname
@@ -131,29 +976,27 @@
\def\dodefinecolorcommand#1#2%
{\unexpanded#1{#2}{\doactivatecolor{#2}}}
-% todo: \allspotcolors
-
-\def\colorlist % not really used, only for colo-run
- {\ctxlua{tex.sprint(table.concat(table.sortedkeys(attributes.list[attributes.numbers.color]),","))}}
+\let\colorlist\empty % not really used, only for colo-run
+\setfalse\collectcolorsinlist
+\def\collectcolorinlist#1{\doglobal\addtocommalist{#1}\colorlist}
\def\dodefinecolor[#1][#2]%
- {%\addtocommalist{#1}\colorlist
+ {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi
\ctxlua{ctx.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}%
\dodefinecolorcommand\setvalue{#1}}
\def\dodefineglobalcolor[#1][#2]%
- {%\doglobal\addtocommalist{#1}\colorlist
+ {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi
\ctxlua{ctx.defineprocesscolor("#1","#2",true,\iffreezecolors true\else false\fi)}%
\dodefinecolorcommand\setgvalue{#1}}
\def\dodefinenamedcolor[#1][#2]%
- {%\doglobal\addtocommalist{#1}\colorlist
+ {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi
\ctxlua{ctx.defineprocesscolor("#1","#2",false,\iffreezecolors true\else false\fi)}%
\dodefinecolorcommand\setvalue{#1}}
\def\dodefinespotcolor[#1][#2][#3]%
- {%\doglobal\addtocommalist{#1}\colorlist % optional
- \doglobal\addtocommalist{#2}\allspotcolors
+ {\ifconditional\collectcolorsinlist\collectcolorinlist{#1}\fi
\ctxlua{ctx.definespotcolor("#1","#2","#3",true)}%
\dodefinecolorcommand\setxvalue{#1}}
@@ -293,7 +1136,7 @@
\appendtoks \initializemaintextcolor \to \everyjob
-\def\localstarttextcolor{\expanded{\startcolor[\ifx\maintextcolor\empty\defaulttextcolor\else\maintextcolor\fi]}}
+\def\localstarttextcolor{\normalexpanded{\noexpand\startcolor[\ifx\maintextcolor\empty\defaulttextcolor\else\maintextcolor\fi]}}
\let\localstoptextcolor \stopcolor
\let\restoretextcolor \firstofoneargument
@@ -302,11 +1145,14 @@
{\definecolor[\??pa#1:#2][#3]%
\iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{(cs:#1:#2)}{\csname(cs:\??pa#1:#2)\endcsname}%
\iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{(ca:#1:#2)}{\csname(ca:\??pa#1:#2)\endcsname}}
- {\doifdefinedelse{(cs:#3)}% \definepalet[test][xx=green]
- {\iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{(cs:#1:#2)}{\csname(cs:#3)\endcsname}%
- \iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{(ca:#1:#2)}{\csname(ca:#3)\endcsname}}
- {\letvalue{(cs:#1:#2)}\undefined
- \letvalue{(ca:#1:#2)}\undefined}}}
+ {\ifcsname(cs:#3)\endcsname % \definepalet[test][xx=green]
+ \iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{(cs:#1:#2)}{\csname(cs:#3)\endcsname}%
+ \iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{(ca:#1:#2)}{\csname(ca:#3)\endcsname}%
+ \else
+ % not entered when making format
+ \localundefine{(cs:#1:#2)}% \letvalue{(cs:#1:#2)}\undefined
+ \localundefine{(ca:#1:#2)}% \letvalue{(ca:#1:#2)}\undefined
+ \fi}}
\setvalue{(cs:)}{} \setvalue{(ca:)}{0}
\setvalue{(ts:)}{} \setvalue{(ta:)}{0}
@@ -352,7 +1198,25 @@
\presetPDFtransparency{#2}{#3}%
\fi}
-\protect \endinput
+%D \macros
+%D {forcecolorhack}
+%D
+%D We can out this in front of (for instance) a special and so force color
+%D to be applied (only glyphs, rules and leaders are handled).
+%D
+%D \startbuffer
+%D \framed
+%D [background=color,backgroundcolor=yellow,framecolor=red,corner=round]
+%D {test}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+% ignores in attribute handler
+%
+% \def\forcecolorhack{\vrule\!!width\zeropoint\!!height\zeropoint\!!depth\zeropoint}
+
+\def\forcecolorhack{\leaders\hrule\hskip\zeropoint}
% \setupcolors[state=start]
%
@@ -368,3 +1232,48 @@
% \ctxlua{tex.print(ctx.aux.colorattribute("green"))}
% \ctxlua{tex.print(ctx.aux.colorattribute("black"))}
% \stoptext
+
+%D We default to the colors defined in \module{colo-rgb} and
+%D support both \cap{RGB} and \cap{CMYK} output. As you can
+%D see, color support is turned off by default. Reduction of
+%D gray colors to gray scales is turned on.
+
+\definecolor[black][s=0]
+\definecolor[white][s=1]
+
+\definetransparency [none] [0]
+\definetransparency [normal] [1]
+\definetransparency [multiply] [2]
+\definetransparency [screen] [3]
+\definetransparency [overlay] [4]
+\definetransparency [softlight] [5]
+\definetransparency [hardlight] [6]
+\definetransparency [colordodge] [7]
+\definetransparency [colorburn] [8]
+\definetransparency [darken] [9]
+\definetransparency [lighten] [10]
+\definetransparency [difference] [11]
+\definetransparency [exclusion] [12]
+
+\appendtoks
+ \setupcolors[\c!state=\v!start]% later direct
+\to \everyjob
+
+\setupcolors
+ [\c!state=\v!stop, % in mkii: \v!stop
+ \c!conversion=\v!yes,
+ \c!reduction=\v!no,
+ \c!rgb=\v!yes,
+ \c!cmyk=\v!yes,
+ \c!spot=\v!yes,
+ \c!mp\c!cmyk=\@@clcmyk,
+ \c!mp\c!spot=\@@clspot,
+ \c!expansion=\v!no,
+ \c!textcolor=,
+ \c!split=\v!no,
+ \c!criterium=\v!all]
+
+\setupcolor
+ [\v!rgb]
+
+\protect \endinput
diff --git a/tex/context/base/colo-ini.tex b/tex/context/base/colo-ini.tex
deleted file mode 100644
index 0136596a5..000000000
--- a/tex/context/base/colo-ini.tex
+++ /dev/null
@@ -1,1051 +0,0 @@
-%D \module
-%D [ file=colo-ini,
-%D version=2007.08.08,
-%D title=\CONTEXT\ Color Macros,
-%D subtitle=Initialization,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 need to clean this up further but first we hav eto make sure that mkiv
-%D code works ok.
-
-\writestatus{loading}{Context Color Macros / initialization}
-
-%D This module implements color. Since \MKII\ and \MKIV\ use a completely
-%D different approach, this module only implements a few generic mechanisms.
-
-\startmessages dutch library: colors
- title: kleur
- 1: systeem -- is globaal actief
- 2: systeem -- is lokaal actief
- 3: -- is niet gedefinieerd --
- 4: systeem -- wordt geladen
- 5: onbekend systeem --
- 6: palet -- is beschikbaar
- 7: palet -- is niet beschikbaar
- 8: specificatie -- bij -- wordt zwart
- 9: -- kleurruimte wordt niet ondersteund
- 10: -- kleurruimte wordt ondersteund
- 11: kleur wordt vertaald in grijs
- 12: -- is geregistreerd
-\stopmessages
-
-\startmessages english library: colors
- title: color
- 1: system -- is global activated
- 2: system -- is local activated
- 3: -- is not defined --
- 4: system -- is loaded
- 5: unknown system --
- 6: palette -- is available
- 7: palette -- is not available
- 8: specification -- at color -- becomes black
- 9: -- color space is not supported
- 10: -- color space is supported
- 11: color is converted to gray
- 12: -- is registered
-\stopmessages
-
-\startmessages german library: colors
- title: farbe
- 1: system -- ist global aktiviert
- 2: system -- ist lokal aktiviert
- 3: -- ist undefiniert --
- 4: system -- ist geladen
- 5: unbekanntes System --
- 6: palette -- ist verfuegbar
- 7: palette -- ist nicht verfuegbar
- 8: Spezifikation -- bei Farbe -- wird schwarz
- 9: -- Farbraum wird nicht unterstuetzt
- 10: -- Farbraum wird unterstuetzt
- 11: Farbe wird in Grau umgewandelt
- 12: -- is registered
-\stopmessages
-
-\startmessages czech library: colors
- title: barva
- 1: system -- je globalne aktivovana
- 2: system -- je lokalne activovana
- 3: -- neni definovana --
- 4: system -- je nacten
- 5: neznamy system --
- 6: palette -- je k dispozici
- 7: palette -- neni k dispozici
- 8: specifikace -- v barve -- bude cerna
- 9: -- prostor barev neni podporovan
- 10: -- prostor barev je podporovan
- 11: barva je prevedena na sed
- 12: -- is registered
-\stopmessages
-
-\startmessages italian library: colors
- title: colore
- 1: sistema -- attivato globalmente
- 2: sistema -- attivato localmente
- 3: -- non definito --
- 4: sistema -- caricato
- 5: sistema -- sconosciuto
- 6: tavolozza -- resa disponibile
- 7: tavolozza -- non disponibile
- 8: specifica -- del colore -- convertita in nero
- 9: spazio dei colori -- non supportato
- 10: spazio dei colori -- supportato
- 11: il colore ø convertito in grigio
- 12: -- is registered
-\stopmessages
-
-\startmessages norwegian library: colors
- title: farge
- 1: system -- er aktivert globalt
- 2: system -- er aktivert lokalt
- 3: -- er udefinert --
- 4: system -- er lest inn
- 5: ukjent system --
- 6: palett -- er tilgjengelig
- 7: palett -- er ikke tilgjengelig
- 8: spesifikasjon -- for farge -- gir kun svart
- 9: -- fargerom er ikke støttet
- 10: -- fargerom er støttet
- 11: fargen vil bli vist som grø
- 12: -- is registered
-\stopmessages
-
-\startmessages romanian library: colors
- title: culori
- 1: sistem -- este activata global
- 2: sistem -- este activata local
- 3: -- nu este definita --
- 4: sistem -- este incarcata
- 5: sistem -- necunoscuta
- 6: paleta -- este disponibila
- 7: palette -- nu este disponibila
- 8: specificatia -- la culoarea -- devine neagra
- 9: spatiul de culoare -- nu este suportat
- 10: spatiul de culoare -- este suportat
- 11: culoarea este convertita la gri
- 12: -- is registered
-\stopmessages
-
-\startmessages french library: colors
- title: couleurs
- 1: le système -- est globalement activé
- 2: le système -- est localement activé
- 3: -- n'est pas défini --
- 4: le système -- est chargé
- 5: système -- inconnu
- 6: la palette -- est disponible
- 7: le palette -- n'est pas disponible
- 8: la spécification -- de la couleur -- devient noire
- 9: l'espace de couleur -- n'est pas supporté
- 10: -- l'espace de couleur est supporté
- 11: la couleur est convertie en niveau de gris
- 12: -- est enregistré
-\stopmessages
-
-\unprotect
-
-\chardef\colorversion=1 % temp, needed for tracing purposes, mkiv transition
-
-%D We use a couple of local registers. That way we don't have
-%D to group when converting colors. By the way, this is not
-%D really faster. We can sqeeze half a second runtime for 50K
-%D switches on a 1G machine, but the macros will become rather
-%D ugly then. To mention one such improvement: no colon
-%D after the key character (.25 sec).
-
-\newdimen\colordimen
-\newcount\colorcount
-
-%D When typesetting for paper, we prefer using the \cap{CMYK}
-%D color space, but for on||screen viewing we prefer \cap{RGB}
-%D (the previous implementation supported only this scheme).
-%D Independant of such specifications, we support some automatic
-%D conversions:
-%D
-%D \startitemize[packed]
-%D \item convert all colors to \cap{RGB}
-%D \item convert all colors to \cap{CMYK}
-%D \item convert all colors to gray scales
-%D \stopitemize
-%D
-%D We also support optimization of colors to gray scales.
-%D
-%D \startitemize[continue]
-%D \item reduce gray colors to gray scales
-%D \item reduce \cap{CMY} components to \cap{K}
-%D \stopitemize
-%D
-%D These options are communicated by means of:
-
-\newif\ifRGBsupported
-\newif\ifCMYKsupported
-\newif\ifSPOTsupported
-\newif\ifpreferGRAY
-\newif\ifGRAYprefered
-\newif\ifreduceCMYK
-\newif\ifconverttoGRAY
-\newif\ifweightGRAY \weightGRAYtrue
-
-\newif\ifconvertMPcolors
-\newif\ifreduceMPcolors
-\newif\ifforcegrayMPcolors
-
-%D The last boolean controls reduction of \cap{CMYK} to
-%D \cap{CMY} colors. When set to true, the black component
-%D is added to the other ones.
-%D
-%D Prefering gray is not the same as converting to gray.
-%D Conversion treats each color components in a different way,
-%D while prefering is just a reduction and thus a
-%D space||saving option.
-
-\newif\iffreezecolors \freezecolorsfalse
-\newif\ifincolor % true if colors enabled
-\newif\iflocalcolor
-
-\let\colorlist \empty
-\let\currentspotcolor \empty
-\let\allspotcolors \empty
-\let\usedspotcolors \empty
-\let\usedcolorchannels\empty
-\let\currentpalet \empty
-
-%D \macros
-%D {definecolor,defineglobalcolor,definenamedcolor,definespotcolor,definemultitonecolor}
-%D
-%D \startbuffer
-%D \definecolor [blue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
-%D \definecolor [yellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m
-%D
-%D \definespotcolor [blue-100] [blue] [p=1]
-%D \definespotcolor [yellow-100] [yellow] [p=1]
-%D
-%D \definemultitonecolor [pdftoolscolor] [blue=.12,yellow=.28] [c=.1,m=.1,y=.3,k=.1]
-%D
-%D \useexternalfigure[demofig][mill.png][object=no]
-%D
-%D \startcombination[4*1]
-%D {\externalfigure[demofig]} {no color}
-%D {\externalfigure[demofig][color=pdftoolscolor]} {indexed duotone}
-%D {\externalfigure[demofig][color=blue-100]} {spot color}
-%D {\externalfigure[demofig][color=yellow-100]} {spot color}
-%D \stopcombination
-%D \stopbuffer
-%D
-%D \getbuffer \typebuffer
-
-\def\definecolor {\dodoubleargument\dodefinecolor}
-\def\defineglobalcolor {\dodoubleargument\dodefineglobalcolor}
-\def\definenamedcolor {\dodoubleargument\dodefinenamedcolor}
-\def\definespotcolor {\dotripleargument\dodefinespotcolor}
-\def\definemultitonecolor{\doquadrupleempty\dodefinemultitonecolor}
-
-% check: registerusedspotcolors
-% check: registerusedcolorchannels
-
-%D \macros
-%D {doifcolorelse, doifcolor}
-%D
-%D Switching to a color is done by means of the following
-%D command. Later on we will explain the use of palets. We
-%D define ourselves a color conditional first.
-
-\ifx\doifcolorelse\undefined
- \let\doifcolorelse\secondoftwoarguments
- \let\doifcolor \gobbleoneargument
-\fi
-
-%D \macros
-%D {localstartcolor,localstopcolor}
-%D
-%D Simple color support, that is without nesting, is provided
-%D by:
-
-\ifx\localstartcolor\undefined
- \let\localstartcolor\undefined
- \let\localstopcolor \undefined
-\fi
-
-%D \macros
-%D {faststartcolor,faststopcolor}
-%D
-%D No checking for arguments and such:
-
-\ifx\faststartcolor\undefined
- \def\faststartcolor[#1]{}
- \def\faststopcolor {}
-\fi
-
-%D These local ones may go away in future versions.
-
-%D \macros
-%D {startcolor,stopcolor}
-%D
-%D The more save method, the one that saves the current color
-%D state and returns to this state afterward, is activated by:
-%D
-%D \showsetup{startcolor}
-
-\ifx\startcolor\undefined
- \let\startcolor\undefined
- \let\stopcolor \undefined
-\fi
-
-%D \macros
-%D {startcurrentcolor,stopcurrentcolor}
-
-\def\startcurrentcolor{\startcolor[\outercolorname]}
-\def\stopcurrentcolor {\stopcolor}
-
-%D \macros
-%D {color,graycolor}
-%D
-%D This leaves the simple color command:
-%D
-%D \showsetup{color}
-%D \showsetup{graycolor}
-
-\ifx\color\undefined
- \def\color [#1]{}
- \def\graycolor[#1]{}
- \def\gray {\graycolor}
-\fi
-
-%D \macros
-%D {localstartraster,localstopraster,
-%D startraster,stopraster,raster}
-%D
-%D The previous conversions are not linear and treat each color
-%D component according to human perception curves. Pure gray
-%D (we call them rasters) has equal color components. In
-%D \CONTEXT\ rasters are only used as backgrounds and these
-%D don't cross page boundaries in the way color does. Therefore
-%D we don't need stacks and marks. Just to be compatible with
-%D color support we offer both 'global' and 'local' commands.
-
-\ifx\startraster\undefined
- \def\startraster [#1]{}
- \def\stopraster {}
- \def\raster [#1]{}
- \def\localstartraster[#1]{}
- \def\localstopraster {}
-\fi
-
-%D \macros
-%D {colorvalue, grayvalue}
-%D
-%D We can typeset the color components using \type{\colorvalue} and
-%D \type{\grayvalue}. The commands:
-%D
-%D \startbuffer
-%D color value of SomeKindOfRed: \colorvalue{SomeKindOfRed} \crlf
-%D gray value of SomeKindOfRed: \grayvalue{SomeKindOfRed}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D show us:
-%D
-%D \startvoorbeeld
-%D \getbuffer
-%D \stopvoorbeeld
-
-\def\colorformatseparator{ }
-
-\ifx\colorvalue\undefined
- \let\colorvalue\gobbleoneargument
- \let\grayvalue \gobbleoneargument
-\fi
-
-% check: \currentcolorname
-% check: \outercolorname
-
-%D \macros
-%D {setupcolor}
-%D
-%D Color definitions can be grouped in files with the name:
-%D
-%D \starttyping
-%D \f!colorprefix-identifier.tex
-%D \stoptyping
-%D
-%D where \type{\f!colorprefix} is \unprotect {\tttf \f!colorprefix}.
-%D Loading such a file is done by \protect
-%D
-%D \showsetup{setupcolor}
-%D
-%D Some default colors are specified in \type{colo-rgb.tex},
-%D which is loaded into the format by:
-%D
-%D \starttyping
-%D \setupcolor[rgb]
-%D \stoptyping
-
-\let\colorstyle\empty
-
-\def\setupcolor
- {\dosingleargument\dosetupcolor}
-
-\def\dosetupcolor[#1]%
- {\doifnot{#1}\colorstyle
- {\def\colorstyle{#1}%
- \processcommalist[#1]\dodosetupcolor}}
-
-\def\dodosetupcolor#1%
- {\makeshortfilename[\truefilename{\f!colorprefix#1}]%
- \startreadingfile
- \readsysfile\shortfilename
- {\showmessage\m!colors4\colorstyle}
- {\showmessage\m!colors5\colorstyle}%
- \stopreadingfile}
-
-\let\usecolors\setupcolor
-
-% check: \chardef\currentcolorchannel=0
-% check: \startcolormode
-% check: \newif\iffilterspotcolor \filterspotcolorfalse
-% check: \newif\ifdoingspotcolor \doingspotcolorfalse
-% check: \registercolorchannel
-
-%D \macros
-%D {definetransparency}
-%D
-%D This command numbers to names:
-
-\def\definetransparency
- {\dodoubleargument\dodefinetransparency}
-
-\def\setupcolors
- {\dosingleargument\dosetupcolors}
-
-\def\resetcolorsplitting
- {\chardef\currentcolorchannel\zerocount
- \let\currentspotcolor\empty
- \filterspotcolorfalse}
-
-\def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplit\fi}
-\def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplit-\fi}
-
-\def\setcolorsplitting
- {\resetsystemmode{\v!color\colorsplitsuffix}%
- \resetcolorsplitting
- \processaction
- [\@@clsplit]
- [ c=>\chardef\currentcolorchannel1,%
- m=>\chardef\currentcolorchannel2,%
- y=>\chardef\currentcolorchannel3,%
- k=>\chardef\currentcolorchannel4,%
- r=>\chardef\currentcolorchannel5,%
- g=>\chardef\currentcolorchannel6,%
- b=>\chardef\currentcolorchannel7,%
- s=>\chardef\currentcolorchannel8,%
- \v!no=>,% \currentcolorchannel0,% all colors
- \s!default=>,% \currentcolorchannel0,% all colors
- \s!unknown=>\filterspotcolortrue
- \edef\currentspotcolor{\commalistelement}]%
- \setsystemmode{\v!color\colorsplitsuffix}%
- \iffilterspotcolor \let\@@clrgb\v!no \fi}
-
-\ifx\dosetupcolormodel\undefined
- \let\dosetupcolormodel\relax
-\fi
-
-\def\dosetupcolors[#1]% some no longer make sense in MkIV
- {\getparameters[\??cl][#1]%
- \doifelse\@@clspot\v!yes
- \SPOTsupportedtrue
- \SPOTsupportedfalse
- \doifelsenothing\@@clsplit
- \resetcolorsplitting
- \setcolorsplitting
- \doifelse\@@clreduction\v!yes
- \reduceCMYKtrue
- \reduceCMYKfalse
- \doifelse\@@clexpansion\v!yes
- \freezecolorstrue
- \freezecolorsfalse
- \doifelse\@@clcriterium\v!all
- \hidesplitcolortrue
- \hidesplitcolorfalse
- \doifelse\@@clrgb\v!no
- {\ifRGBsupported \showmessage\m!colors {9}\v!rgb\RGBsupportedfalse\fi}
- {\ifRGBsupported\else\showmessage\m!colors{10}\v!rgb\RGBsupportedtrue \fi}%
- \doifelse\@@clcmyk\v!no
- {\ifCMYKsupported \showmessage\m!colors {9}\v!cmyk\CMYKsupportedfalse\fi}
- {\ifCMYKsupported\else\showmessage\m!colors{10}\v!cmyk\CMYKsupportedtrue \fi}%
- \doifelse\@@clmpcmyk\v!no
- {\ifMPcmykcolors \showmessage\m!colors {9}{\v!mp\v!cmyk}\MPcmykcolorsfalse\fi}
- {\ifMPcmykcolors\else\showmessage\m!colors{10}{\v!mp\v!cmyk}\MPcmykcolorstrue \fi}%
- \doifelse\@@clmpspot\v!no
- {\ifMPspotcolors \showmessage\m!colors {9}{\v!mp\v!spot}\MPspotcolorsfalse\fi}
- {\ifMPspotcolors\else\showmessage\m!colors{10}{\v!mp\v!spot}\MPspotcolorstrue \fi}%
- \preferGRAYfalse
- \processaction
- [\@@clconversion]
- [ \v!yes=>\preferGRAYtrue,
- \v!always=>\preferGRAYtrue\RGBsupportedfalse\CMYKsupportedfalse]%
- \ifRGBsupported
- \converttoGRAYfalse
- \forcegrayMPcolorsfalse
- \else\ifCMYKsupported
- \converttoGRAYfalse
- \forcegrayMPcolorsfalse
- \convertMPcolorstrue
- \ifreduceCMYK
- \reduceMPcolorstrue
- \fi
- \else
- \ifconverttoGRAY\else\showmessage\m!colors{11}\empty\fi
- \converttoGRAYtrue
- \forcegrayMPcolorstrue
- \convertMPcolorsfalse
- \reduceMPcolorsfalse
- \fi\fi
- \processaction
- [\@@clstate]
- [ \v!global=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
- \incolortrue\localcolorfalse,
- \v!local=>\ifincolor\else\showmessage\m!colors2\colorstyle\fi
- \incolortrue\localcolortrue,
- \v!start=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
- \incolortrue\localcolorfalse
- \let\@@clstate\v!global,
- \v!stop=>\incolorfalse\localcolorfalse
- \forcegrayMPcolorstrue]%
- \dosetupcolormodel
- \initializemaintextcolor}
-
-%D \macros
-%D {startregistercolor,stopregistercolor,permitcolormode}
-%D
-%D If you only want to register a color, the switch \type
-%D {\ifpermitcolormode} can be used. That way the nested
-%D colors know where to go back to.
-
-\ifx\startregistercolor\undefined
- \def\startregistercolor[#1]{}
- \def\stopregistercolor {}
-\fi
-
-%D We use these macros for implementing text colors
-%D (actually, the first application was in foreground
-%D colors).
-%D
-%D \starttyping
-%D \starttextcolor[red]
-%D \dorecurse{10}{\input tufte \color[green]{oeps} \par}
-%D \stoptextcolor
-%D \stoptyping
-%D
-%D This is more efficient than the alternative:
-%D
-%D \starttyping
-%D \setupbackgrounds[text][foregroundcolor=red]
-%D \startregistercolor[red]
-%D \dorecurse{10}{\input tufte \color[green]{oeps} \par}
-%D \stopregistercolor
-%D \stoptyping
-
-\def\maintextcolor {}
-\def\defaulttextcolor {black}
-\def\@@themaintextcolor{themaintextcolor}
-
-\ifx\initializemaintextcolor\undefined
- \def\starttextcolor [#1]{}
- \def\stoptextcolor {}
- \def\initializemaintextcolor {}
-\fi
-
-\ifx\restoretextcolor\undefined % to be redone
- \let\restoretextcolor \firstofoneargument
- \let\localstarttextcolor\relax
- \let\localstoptextcolor \relax
-\fi
-
-%D In this documentation we will not go into too much details
-%D on palets. Curious users can find more information on this
-%D topic in \from[use of color].
-%D
-%D At the moment we implemented color in \CONTEXT\ color
-%D printing was not yet on the desktop. In spite of this lack our
-%D graphics designer made colorfull illustrations. When printed
-%D on a black and white printer, distinctive colors can come
-%D out equally gray. We therefore decided to use only colors
-%D that were distinctive in colors as well as in black and
-%D white print.
-%D
-%D Although none of the graphic packages we used supported
-%D logical colors and global color redefition, we build this
-%D support into \CONTEXT. This enabled us to experiment and
-%D also prepared us for the future.
-
-%D \macros
-%D {definepalet}
-%D
-%D Colors are grouped in palets. The colors in such a palet can
-%D have colorful names, but best is to use names that specify
-%D their use, like {\em important} or {\em danger}. As a sort
-%D of example \CONTEXT\ has some palets predefined,
-%D like:\footnote{At the time I wrote the palet support, I was
-%D reading 'A hort history of time' of S.~Hawkins, so that's
-%D why we stuck to quarks.}
-%D
-%D \starttyping
-%D \definepalet
-%D [alfa]
-%D [ top=rood:7,
-%D bottom=groen:6,
-%D up=blauw:5,
-%D down=cyaan:4,
-%D strange=magenta:3,
-%D charm=geel:2]
-%D \stoptyping
-%D
-%D It's formal definition is:
-%D
-%D \showsetup{definepalet}
-%D
-%D Visualized, such a palet looks like:
-%D
-%D \startbuffer[palet]
-%D \showpalet [alfa] [horizontal,name,number,value]
-%D \stopbuffer
-%D
-%D \startlinecorrection
-%D \getbuffer[palet]
-%D \stoplinecorrection
-%D
-%D This bar shows both the color and gray alternatives of the
-%D palet components (not visible in black and white print).
-%D
-%D When needed, one can copy a palet by saying:
-%D
-%D \starttyping
-%D \definepalet [TEXcolorpretty] [colorpretty]
-%D \stoptyping
-%D
-%D This saves us some typing in for instance the modules that
-%D deal with pretty verbatim typesetting.
-
-\def\definepalet
- {\dodoubleargument\dodefinepalet}
-
-\def\dodefinepalet[#1][#2]%
- {\doifassignmentelse{#2}
- {%\showmessage\m!colors6{#1}%
- \letvalue{\??pa#1}\empty
- \setevalue{\??pa\??pa#1}{#2}%
- \def\dodododefinepalet[##1=##2]%
- {\doifvaluesomething{\??pa#1}
- {\setevalue{\??pa#1}{\csname\??pa#1\endcsname,}}%
- \setevalue{\??pa#1}{\csname\??pa#1\endcsname##1}%
- \dodefinepaletcolor{#1}{##1}{##2}}%
- \def\dododefinepalet##1%
- {\dodododefinepalet[##1]}%
- \processcommalist[#2]\dododefinepalet}
- {\doifdefined{\??pa#2}
- {\expanded{\dodefinepalet[#1][\csname\??pa\??pa#2\endcsname]}}}}
-
-\ifx\dodefinepaletcolor\undefined
- \let\dodefinepaletcolor\gobblethreearguments
-\fi
-
-\let\paletsize\!!zerocount
-
-\def\getpaletsize[#1]%
- {\getcommacommandsize[\csname\??pa\??pa#1\endcsname]%
- \edef\paletsize{\number\commalistsize}}
-
-%D Instead of refering to colors, one can also directly specify
-%D a color:
-%D
-%D \starttyping
-%D \definepalet[test][xx=green]
-%D \definepalet[test][xx={y=.4}]
-%D \stoptyping
-
-%D \macros
-%D {setuppalet}
-%D
-%D Colors are taken from the current palet, if defined.
-%D Setting the current palet is done by:
-%D
-%D \showsetup{setuppalet}
-
-\let\currentpalet\empty
-
-\def\setuppalet
- {\dosingleempty\dosetuppalet}
-
-\def\dosetuppalet[#1]%
- {\edef\currentpalet{#1}%
- \ifx\currentpalet\empty
- % seems to be a reset
- \else\ifcsname\??pa\currentpalet\endcsname
- \edef\currentpalet{#1:}%
- \else
- \showmessage\m!colors7\currentpalet
- \let\currentpalet\empty
- \fi\fi}
-
-%D \macros
-%D {showpalet}
-%D
-%D The previous visualization was typeset with:
-%D
-%D \typebuffer[palet]
-%D
-%D This commands is defined as:
-%D
-%D \showsetup{showpalet}
-
-\fetchruntimecommand \showpalet {\f!colorprefix\s!run}
-
-%D \macros
-%D {showcolorcomponents}
-%D
-%D \starttyping
-%D \showcolorcomponents[color-1,color-2]
-%D \stoptyping
-
-\fetchruntimecommand \showcolorcomponents {\f!colorprefix\s!run}
-
-%D \macros
-%D {definecolorgroup}
-%D
-%D The naming of the colors in this palet suggests some
-%D ordening, which in turn is suported by color grouping.
-%D
-%D \starttyping
-%D \definecolorgroup
-%D [red]
-%D [1.00:0.90:0.90,
-%D 1.00:0.80:0.80,
-%D 1.00:0.70:0.70,
-%D 1.00:0.55:0.55,
-%D 1.00:0.40:0.40,
-%D 1.00:0.25:0.25,
-%D 1.00:0.15:0.15,
-%D 0.90:0.00:0.00]
-%D \stoptyping
-%D
-%D In such a color group colors are numbered from~$1$ to~$n$.
-%D
-%D \showsetup{definecolorgroup}
-%D
-%D This kind of specification is not only more compact than
-%D defining each color separate, it also loads faster and takes
-%D less bytes.
-
-\def\definecolorgroup
- {\dotripleempty\dodefinecolorgroup}
-
-\def\dododefinecolorgroupgray [#1][#2:#3]{\definecolor [#1:\the\colorcount][s=#2]}
-\def\dododefinecolorgrouprgb [#1][#2:#3:#4:#5]{\definecolor [#1:\the\colorcount][r=#2,g=#3,b=#4]}
-\def\dododefinecolorgroupcmyk[#1][#2:#3:#4:#5:#6]{\definecolor [#1:\the\colorcount][c=#2,m=#3=,y=#4,k=#5]}
-\def\dododefinecolorgroupspot [#1][#2:#3:#4]{\definespotolor[#1:\the\colorcount][#2][p=#3]}
-
-\def\dododefinecolorgroup#1#2%
- {\advance\colorcount\plusone
- \getvalue{dododefinecolorgroup\currentcolorspace}[#1][#2:0:0:0:0]}
-
-\def\dodefinecolorgroup[#1][#2][#3]% obsolete, just use palets
- {\ifthirdargument
- \doifelsenothing{#2}{\let\currentcolorspace\v!rgb}{\def\currentcolorspace{#2}}%
- \colorcount\zerocount
- \processcommalist[#3]{\dododefinecolorgroup{#1}}%
- \else
- \doifinstringelse{:}{#2}
- {\definecolorgroup[#1][\v!rgb][#2]}
- {\doloop
- {\doifdefinedelse{\??cr#2:\recurselevel}
- {\setevalue{\??cr#1:\recurselevel}{\csname\??cr#2:\recurselevel\endcsname}}
- {\exitloop}}}%
- \fi}
-
-%D \macros
-%D {showcolorgroup}
-%D
-%D We can show the group by:
-%D
-%D \startbuffer
-%D \showcolorgroup [blue] [horizontal,name,number,value]
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D or in color:
-%D
-%D \startlinecorrection
-%D \getbuffer
-%D \stoplinecorrection
-%D
-%D which uses:
-%D
-%D \showsetup{showcolorgroup}
-
-\fetchruntimecommand \showcolorgroup {\f!colorprefix\s!run}
-
-%D There are ten predefined color groups, like
-%D \color[green]{\em groen}, \color[red]{\em rood},
-%D \color[blue]{\em blauw}, \color[cyan]{\em cyaan},
-%D \color[magenta]{\em magenta} and \color[yellow]{\em geel}.
-%D
-%D \startlinecorrection
-%D \hbox to \hsize
-%D {\hss
-%D \showcolorgroup [red] [vertical,name,number]\hss
-%D \showcolorgroup [green] [vertical,name]\hss
-%D \showcolorgroup [blue] [vertical,name]\hss
-%D \showcolorgroup [cyan] [vertical,name]\hss
-%D \showcolorgroup [magenta][vertical,name]\hss
-%D \showcolorgroup [yellow] [vertical,name]\hss}
-%D \stoplinecorrection
-%D
-%D These groups are used to define palets {\em alfa} upto {\em
-%D zeta}. As long as we don't use colors from the same row, we
-%D get ourselves distinctive palets. By activating such a palet
-%D one gains access to its members {\em top} to {\em charm} (of
-%D course one should use more suitable names than these).
-%D
-%D \startlinecorrection
-%D \hbox to \hsize
-%D {\showpalet [alfa] [vertical,name,number]\hss
-%D \showpalet [beta] [vertical,name]\hss
-%D \showpalet [gamma] [vertical,name]\hss
-%D \showpalet [delta] [vertical,name]\hss
-%D \showpalet [epsilon] [vertical,name]\hss
-%D \showpalet [zeta] [vertical,name]}
-%D \stoplinecorrection
-%D
-%D By using the keyword \type {value} the individual color
-%D components are shown too. When printed in color, these
-%D showcases show both the colors and the gray value.
-
-%D \macros
-%D {comparepalet}
-%D
-%D There are some more testing macros available:
-%D
-%D \startbuffer
-%D \comparepalet [alfa]
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D shows the palet colors against a background:
-%D
-%D \startlinecorrection
-%D \getbuffer
-%D \stoplinecorrection
-%D
-%D The formal definition is:
-%D
-%D \showsetup{comparepalet}
-
-\fetchruntimecommand \comparepalet {\f!colorprefix\s!run}
-
-%D \macros
-%D {comparecolorgroup}
-%D
-%D The similar command:
-%D
-%D \startbuffer
-%D \comparecolorgroup [blue]
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D shows color groups:
-%D
-%D \startlinecorrection
-%D \getbuffer
-%D \stoplinecorrection
-%D
-%D this commands are defined as:
-%D
-%D \showsetup{comparecolorgroup}
-
-\fetchruntimecommand \comparecolorgroup {\f!colorprefix\s!run}
-
-%D \macros
-%D {showcolor}
-%D
-%D But let's not forget that we also have the more traditional
-%D non||related colors. These show up after:
-%D
-%D \starttyping
-%D \showcolor [name]
-%D \stoptyping
-%D
-%D Where \type{name} for instance can be \type{rgb}.
-%D
-%D \showsetup{showcolor}
-
-\fetchruntimecommand \showcolor {\f!colorprefix\s!run}
-
-%D It would make sense to put the following code in \type
-%D {colo-mps}, but it it rather low level.
-
-%D \macros
-%D {negatecolorcomponent,negatedcolorcomponent}
-%D
-%D These speak for themselves. See \type {colo-ext} for usage.
-
-\def\negatecolorcomponent#1% #1 = \macro
- {\scratchdimen\onepoint\advance\scratchdimen-#1\onepoint
- \ifdim\scratchdimen<\zeropoint\scratchdimen\zeropoint\fi
- \edef#1{\withoutpt\the\scratchdimen}}
-
-\let\negatedcolorcomponent\firstofoneargument
-
-\def\negatedcolorcomponent#1%
- {\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint
- \!!zerocount
- \else
- \expandafter\withoutpt\the\dimexpr\onepoint-#1\onepoint\relax
- \fi}
-
-\def\negatecolorcomponent#1% #1 = \macro
- {\edef#1{\negatedcolorcomponent{#1}}}
-
-%D \macros
-%D {ifMPgraphics, ifMPcmykcolors, MPcolor}
-%D
-%D A very special macro is \type{\MPcolor}. This one can be
-%D used to pass a \CONTEXT\ color to \METAPOST.
-%D
-%D \starttyping
-%D \MPcolor{my own red}
-%D \stoptyping
-%D
-%D This macro returns a \METAPOST\ triplet \type{(R,G,B)}.
-%D Unless \CMYK\ color support is turned on with \type
-%D {MPcmyk}, only \cap{RGB} colors and gray scales are
-%D supported.
-
-\newif\ifMPcmykcolors % \MPcmykcolorsfalse
-\newif\ifMPspotcolors % \MPspotcolorsfalse
-
-\ifx\MPcolor\undefined
- \def\MPcolor#1{(0,0,0)}
-\fi
-
-%D \macros
-%D {PDFcolor,FDFcolor}
-%D
-%D Similar alternatives are avaliable for \PDF:
-
-%D For the moment we keep the next downward compatibility
-%D switch, i.e.\ expanded colors. However, predefined colors
-%D and palets are no longer expanded (which is what I wanted
-%D in the first place).
-%D
-%D Well, in case we want to do color separation and use CMYK
-%D colors only, this is dangerous since unwanted remapping may
-%D take place. Especially when we redefine already defined
-%D colors in another color space (e.g. darkgreen is
-%D predefined in RGB color space, so a redefinition in CMYK
-%D coordinates before RGB mode is disabled, would give
-%D unexpected results due to the already frozen color spec.)
-%D
-%D So, from now on, colors are not frozen any more!
-
-% \appendtoks\setupcolors[\c!expansie=\v!ja]\to\everyjob
-
-\chardef\currentcolorchannel=0
-
-\newif\iffilterspotcolor \filterspotcolorfalse
-\newif\ifdoingspotcolor \doingspotcolorfalse
-
-\def\registercolorchannel#1%
- {\ifdoingspotcolor \else
- \global\expandafter\chardef\csname\??cs#1\endcsname\zerocount
- \fi}
-
-\newif\ifhidesplitcolor \hidesplitcolortrue
-
-%D The next macro is for instance used in figure splitting:
-
-\def\doifseparatingcolorselse
- {\iffilterspotcolor
- \@EA\firstoftwoarguments
- \else\ifcase\currentcolorchannel
- \@EAEAEA\secondoftwoarguments
- \else
- \@EAEAEA\firstoftwoarguments
- \fi\fi}
-
-\def\doifcolorchannelelse#1%
- {\doifseparatingcolorselse
- {\doifelsenothing{#1}
- \secondoftwoarguments
- {\doifelse{#1}\@@clsplit
- \firstoftwoarguments
- \secondoftwoarguments}}
- \secondoftwoarguments}
-
-\def\resetcolorseparation
- {\filterspotcolorfalse
- \chardef\currentcolorchannel\zerocount}
-
-%D These can be used in selecting specific files (like
-%D figuredatabases).
-
-% we already have:
-%
-% \def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplitsen\fi}
-% \def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplitsen-\fi}
-
-\def\colorchannelprefix{\doifseparatingcolorselse\@@clsplit\empty-}
-\def\colorchannelsuffix{-\doifseparatingcolorselse\@@clsplit\empty}
-
-%D We now load the low level macros:
-
-\loadmarkfile{colo-ini}
-
-%D We default to the colors defined in \module{colo-rgb} and
-%D support both \cap{RGB} and \cap{CMYK} output. As you can
-%D see, color support is turned off by default. Reduction of
-%D gray colors to gray scales is turned on.
-
-\definecolor[black][s=0]
-\definecolor[white][s=1]
-
-\definetransparency [none] [0]
-\definetransparency [normal] [1]
-\definetransparency [multiply] [2]
-\definetransparency [screen] [3]
-\definetransparency [overlay] [4]
-\definetransparency [softlight] [5]
-\definetransparency [hardlight] [6]
-\definetransparency [colordodge] [7]
-\definetransparency [colorburn] [8]
-\definetransparency [darken] [9]
-\definetransparency [lighten] [10]
-\definetransparency [difference] [11]
-\definetransparency [exclusion] [12]
-
-\setupcolors
- [\c!state=\v!stop,
- \c!conversion=\v!yes,
- \c!reduction=\v!no,
- \c!rgb=\v!yes,
- \c!cmyk=\v!yes,
- \c!spot=\v!yes,
- \c!mp\c!cmyk=\@@clcmyk,
- \c!mp\c!spot=\@@clspot,
- \c!expansion=\v!no,
- \c!textcolor=,
- \c!split=\v!no,
- \c!criterium=\v!all]
-
-\setupcolor
- [\v!rgb]
-
-\protect \endinput
diff --git a/tex/context/base/colo-run.tex b/tex/context/base/colo-run.tex
index 6313255c3..d94ea9801 100644
--- a/tex/context/base/colo-run.tex
+++ b/tex/context/base/colo-run.tex
@@ -155,8 +155,9 @@
\gdef\doshowcolor[#1]%
{\bgroup
\iffirstargument
- \let\colorlist\empty
+ \let\colorlist\empty % not really used, only for colo-run
\let\colorstyle\empty
+ \settrue\collectcolorsinlist
\setupcolor[#1]%
\fi
\def\rule
diff --git a/tex/context/base/cont-cs.tex b/tex/context/base/cont-cs.tex
index 94235a8b3..f878920aa 100644
--- a/tex/context/base/cont-cs.tex
+++ b/tex/context/base/cont-cs.tex
@@ -26,6 +26,14 @@
\installlanguage [\s!sk] [\c!state=\v!start]
\installlanguage [\s!cs] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-de.tex b/tex/context/base/cont-de.tex
index 95976e815..460ca7eca 100644
--- a/tex/context/base/cont-de.tex
+++ b/tex/context/base/cont-de.tex
@@ -31,6 +31,14 @@
\installlanguage [deo] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-en.tex b/tex/context/base/cont-en.tex
index e3275845c..e2b09ecbe 100644
--- a/tex/context/base/cont-en.tex
+++ b/tex/context/base/cont-en.tex
@@ -35,6 +35,12 @@
\installlanguage [\s!sk] [\c!state=\v!start]
\installlanguage [\s!pl] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+% \prependtoks
+% \the \everysetupdocument
+% \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-fil.tex b/tex/context/base/cont-fil.tex
index a0712a42f..28b6b6f55 100644
--- a/tex/context/base/cont-fil.tex
+++ b/tex/context/base/cont-fil.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context File Synonyms}
+\writestatus{loading}{ConTeXt File Synonyms}
\definefilesynonym [chemie] [chemic]
\definefilesynonym [chemics] [chemic]
diff --git a/tex/context/base/cont-fr.tex b/tex/context/base/cont-fr.tex
index c6cf11ff1..d812b28f9 100644
--- a/tex/context/base/cont-fr.tex
+++ b/tex/context/base/cont-fr.tex
@@ -29,6 +29,14 @@
\installlanguage [\s!nl] [\c!state=\v!start]
\installlanguage [\s!it] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-gb.tex b/tex/context/base/cont-gb.tex
index 6e60cd1bc..99d297425 100644
--- a/tex/context/base/cont-gb.tex
+++ b/tex/context/base/cont-gb.tex
@@ -29,6 +29,14 @@
\installlanguage [\s!nl] [\c!state=\v!start]
\installlanguage [\s!it] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-it.tex b/tex/context/base/cont-it.tex
index d3141a4ae..2141e3bc9 100644
--- a/tex/context/base/cont-it.tex
+++ b/tex/context/base/cont-it.tex
@@ -28,6 +28,14 @@
\installlanguage [\s!es] [\c!state=\v!start]
\installlanguage [\s!it] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-log.tex b/tex/context/base/cont-log.tex
index fb821331d..8419394c4 100644
--- a/tex/context/base/cont-log.tex
+++ b/tex/context/base/cont-log.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context TeX Logos}
+\writestatus{loading}{ConTeXt TeX Logos}
%D The system that is used to typeset this text is called \TEX,
%D typeset with an lowered~E. From te beginning of \TEX,
@@ -228,6 +228,7 @@
\def\pdfTeX {pdf\TeX}
\def\pdfeTeX {pdfe-\TeX}
\def\luaTeX {lua\TeX}
+\def\metaTeX {meta\TeX}
\unexpanded\def\XeTeX {X\lower.5ex\hbox{\kern-.15em\mirror{E}}\kern-.1667em\TeX}
% Better, since lm has a mirrored E (don't ask me why)
@@ -251,41 +252,39 @@
{\setbox\scratchbox\hbox{E}%
\raise\dimexpr\ht\scratchbox+\dp\scratchbox\relax\hbox{\rotate[\c!rotation=180]{\box\scratchbox}}}
-\beginNEWTEX
-
-\unexpanded\def\XeTeX
- {X\lower.5ex
- \hbox
- {\kern-.15em
- \iffontchar\font"018E\relax
- \char"018E%
- \else
- \ifx\fontalternative\c!bf\mirror{E}\else
- \ifx\fontalternative\c!it \@XeTeX@\else
- \ifx\fontalternative\c!sl \@XeTeX@\else
- \ifx\fontalternative\c!bi \@XeTeX@\else
- \ifx\fontalternative\c!bs \@XeTeX@\else
- \mirror{E}\fi\fi\fi\fi\fi
- \fi}%
- \kern-.1667em \TeX}
-
-\endNEWTEX
-
-\beginOLDTEX
-
-\unexpanded\def\XeTeX
- {X\lower.5ex
- \hbox
- {\kern-.15em
- \ifx\fontalternative\c!bf\mirror{E}\else
- \ifx\fontalternative\c!it \@XeTeX@\else
- \ifx\fontalternative\c!sl \@XeTeX@\else
- \ifx\fontalternative\c!bi \@XeTeX@\else
- \ifx\fontalternative\c!bs \@XeTeX@\else
- \mirror{E}\fi\fi\fi\fi\fi}%
- \kern-.1667em \TeX}
-
-\endOLDTEX
+\ifnum\texengine=\pdftexengine
+
+ \unexpanded\def\XeTeX
+ {X\lower.5ex
+ \hbox
+ {\kern-.15em
+ \ifx\fontalternative\c!bf\mirror{E}\else
+ \ifx\fontalternative\c!it \@XeTeX@\else
+ \ifx\fontalternative\c!sl \@XeTeX@\else
+ \ifx\fontalternative\c!bi \@XeTeX@\else
+ \ifx\fontalternative\c!bs \@XeTeX@\else
+ \mirror{E}\fi\fi\fi\fi\fi}%
+ \kern-.1667em \TeX}
+
+\else
+
+ \unexpanded\def\XeTeX
+ {X\lower.5ex
+ \hbox
+ {\kern-.15em
+ \iffontchar\font"018E\relax
+ \char"018E%
+ \else
+ \ifx\fontalternative\c!bf\mirror{E}\else
+ \ifx\fontalternative\c!it \@XeTeX@\else
+ \ifx\fontalternative\c!sl \@XeTeX@\else
+ \ifx\fontalternative\c!bi \@XeTeX@\else
+ \ifx\fontalternative\c!bs \@XeTeX@\else
+ \mirror{E}\fi\fi\fi\fi\fi
+ \fi}%
+ \kern-.1667em \TeX}
+
+\fi
\let\ETEX \eTeX
\let\PDFTEX \pdfTeX
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 20813c37b..9e2ca49c0 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -24,8 +24,32 @@
\unprotect
+% we need to figure this out (to be discussed)
+
+\unexpanded\def\textminus
+ {\char \iffontchar\font"2012 "2012 % figuredash
+ \else\iffontchar\font"2013 "2013 % endash
+ \else\iffontchar\font"2212 "2212 % math minus
+ "002D % hyphen
+ \fi\fi\fi}
+
+\unexpanded\def\textplus
+ {\char"002B } % plus
+
+% \def\registerviewerlayer#1#2% global !
+% {\setxvalue{(vl:#1)}{\global\dosetattribute{viewerlayer}{\ctxlua{tex.print(viewerlayers.register('#2'))}}}}
+
+% \setevalue{(vl:)}{\global\doresetattribute{viewerlayer}}
+
+\let\\=\crlf % till we fixed all styles
+
+% \def\pagedir{\expandafter\gobblethreearguments}
+% \def\bodydir{\expandafter\gobblethreearguments}
+
% we have to make an mkii/mkiv core-not
+\ifx\definestructurecounter\undefined
+
\def\dochecknote % only to be called locally, some bools will become class-ones
{% for the moment no mixed text/endnotes modes, so we use
% \footnoteparameter and not \noteparameter (**)
@@ -79,22 +103,24 @@
\skip \currentnoteins\zeropoint
\fi}
-%
-
-\def\writestatus#1#2{\ctxlua{ctx.writestatus(\!!bs#1\!!es,\!!bs#2\!!es)}}
+\fi
\ifx\clearmarks\undefined
\def\clearmarks {\begingroup\afterassignment\doclearmarks\scratchcounter}
\def\doclearmarks{\normalmarks\scratchcounter{}\endgroup}
\fi
-\def\resetmark#1% we cannot use \normalmarks#1{}
- {\global\@EA\chardef\csname\@@mrk\string#1\endcsname\zerocount
- \@EA\clearmarks\csname\@@prk\string#1\endcsname
- \global\@EA\let\csname\@@trk\string#1\endcsname\empty
- \global\@EA\let\csname\@@frk\string#1\endcsname\empty
- \global\@EA\let\csname\@@brk\string#1\endcsname\empty
- \global\@EA\let\csname\@@crk\string#1\endcsname\empty}
+\ifx\@@trk\undefined \else
+
+ \def\resetmark#1% we cannot use \normalmarks#1{}
+ {\global\@EA\chardef\csname\@@mrk\string#1\endcsname\zerocount
+ \@EA\clearmarks\csname\@@prk\string#1\endcsname
+ \global\@EA\let\csname\@@trk\string#1\endcsname\empty
+ \global\@EA\let\csname\@@frk\string#1\endcsname\empty
+ \global\@EA\let\csname\@@brk\string#1\endcsname\empty
+ \global\@EA\let\csname\@@crk\string#1\endcsname\empty}
+
+\fi
%D Since this can be a showstopper, we report the path at the beginning
%D as well as at the end of a run.
@@ -102,15 +128,26 @@
% \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath())}}
% \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}}
+\startluacode
+ statistics.register("result saved in file", function()
+ return string.format( "%s.%s", "\outputfilename", (tex.pdfoutput>0 and "pdf") or "dvi")
+ end)
+\stopluacode
+
%D For the moment we report some statistics. Later this will become an option,
%D but for now we need this information.
-\def\nomkivstatistics{\ctxlua{function ctx.show_statistics() end}} % for taco
+\def\nomkivstatistics{\ctxlua{statistics.enable = false}} % for taco
\def\resettimer {\ctxlua{environment.starttime = os.clock()}}
\def\elapsedtime {\ctxlua{tex.sprint(os.clock()-environment.starttime)}}
\let\elapsedseconds \elapsedtime
+% we will have a bunch of extra tracers (--dumphash --dumpdelta)
+
+\def\tracersdumphash {\ctxlua{tracers.register_dump_hash(false)}}
+\def\tracersdumpdelta{\ctxlua{tracers.register_dump_hash(true)}}
+
\resettimer
%D For me.
@@ -145,44 +182,33 @@
% texio.write_nl("CREATING "..pth)
% os.execute("mkdir " .. pth)
% end
-% input.output_files = { }
+% resolvers.output_files = { }
% callback.register('find_write_file', function(id,name)
-% input.output_files[name] = file.join(".","tmp","\jobname",name)
-% texio.write_nl("REDIRECTING OUTPUT "..name.. " TO " .. input.output_files[name])
-% return input.output_files[name]
+% resolvers.output_files[name] = file.join(".","tmp","\jobname",name)
+% texio.write_nl("REDIRECTING OUTPUT "..name.. " TO " .. resolvers.output_files[name])
+% return resolvers.output_files[name]
% end)
% callback.register('find_read_file', function(id,name)
% local sname = string.gsub(name,"^\letterpercent./","")
-% if input.output_files[sname] then
-% return input.output_files[name]
+% if resolvers.output_files[sname] then
+% return resolvers.output_files[name]
% elseif string.find(sname,"^\jobname[\letterpercent.\letterpercent-]") then
% local n = file.join(".","tmp","\jobname",sname)
% local f = io.open(n)
% if f then
-% input.output_files[name] = n
+% resolvers.output_files[name] = n
% texio.write_nl("REDIRECTING INPUT "..sname.. " TO " .. n)
% f:close()
% return n
% else
-% return input.findtexfile(name)
+% return resolvers.findtexfile(name)
% end
% else
-% return input.findtexfile(name)
+% return resolvers.findtexfile(name)
% end
% end)
% }
-% The following commands need to be taken care of, e.g. because there is not yet
-% a mkiv module for them. (Currently they're overloaded so we need to redefine them.)
-
-\def\WORD {\groupedcommand{\setcharactercasing[\plusone ]}{}}
-\def\word {\groupedcommand{\setcharactercasing[\plustwo ]}{}}
-\def\Word {\groupedcommand{\setcharactercasing[\plusthree]}{}}
-\def\Words{\groupedcommand{\setcharactercasing[\plusfour]}{}}
-
-\let\WORDS\WORD
-\let\words\word
-
\definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=]
\protect \endinput
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index ee047599b..b8e2a6f95 100644
--- a/tex/context/base/cont-new.tex
+++ b/tex/context/base/cont-new.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2008.10.31 13:58}
+\newcontextversion{2009.05.28 11:23}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
@@ -21,7 +21,7 @@
% it's about time to clean up this file ...
-\writestatus{\m!systems}{beware: some patches loaded from cont-new.tex}
+\writestatus\m!systems{beware: some patches loaded from cont-new.tex}
% \ifx\pdfmapfile \undefined \else \pdfmapfile{ } \fi
@@ -31,13 +31,16 @@
\let\then\relax % \ifnum1>2\then -)
-\def\TransparencyHack % png: /CS /DeviceRGB /I true
- {\appendtoks
- \doPDFpageattribute{/Group << /S /Transparency /I true /K true>>}%
- \to \everyPDFxform
- \appendtoks
- \doPDFpageattribute{/Group << /S /Transparency /I true /K true>>}%
- \to \everyshipout}
+\def\fastscale#1%
+ {\begingroup
+ \ifnum#1=1000\relax
+ \setfalse\scaleboxdone
+ \else
+ \settrue\scaleboxdone
+ \edef\finalscaleboxxscale{\withoutpt\the\dimexpr#1pt/1000\relax}%
+ \let\finalscaleboxyscale\finalscaleboxxscale
+ \fi
+ \dowithnextbox{\doscaleboxindeed\flushnextbox\endgroup}\hbox}
% \setupcaption [figure] [align=flushleft]
% \setupcaption [figure-1] [align=flushleft,leftmargin=10mm]
@@ -96,9 +99,9 @@
% normally one does not want this to happen nested, maybe there
% is more; non public vars btw, will become conditionals
-\appendtoks \writetoregisterfalse \to \everybeforeutilityread
-\appendtoks \writetolistfalse \to \everybeforeutilityread
-\appendtoks \notesenabledfalse \to \everybeforeutilityread
+\ifx\writetoregisterfalse\undefined \else \appendtoks \writetoregisterfalse \to \everybeforeutilityread \fi
+\ifx\writetolistfalse \undefined \else \appendtoks \writetolistfalse \to \everybeforeutilityread \fi
+\ifx\notesenabledfalse \undefined \else \appendtoks \notesenabledfalse \to \everybeforeutilityread \fi
% \setuplabeltext[\s!itemcount1={{I(},{)}}]
% \def\labeledcountervalue#1{\labeltexts{#1}{\countervalue{#1}}}
@@ -515,69 +518,6 @@
\egroup
-% todo : test low level translation (nl->en) and optimize script
-
-% \definestylecollection[mine]
-
-% \definestyleinstance[mine][default][sorry]
-% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
-% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
-% \definestyleinstance[mine][bf][\sl]
-% \definestyleinstance[mine][sl][\tt]
-
-% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}
-
-\definesystemvariable{sx}
-
-\def\definestylecollection
- {\dosingleargument\dodefinestylecollection}
-
-\def\dodefinestylecollection[#1]%
- {\iffirstargument
- \unexpanded\setvalue{#1}{\styleinstance[#1]}%
- \def\docommand##1%
- {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}%
- \processcommacommand[\alternativelist,\s!default]\dodocommand}%
- \processcommacommand[\stylelist,\s!default]\docommand
- \fi}
-
-\def\definestyleinstance
- {\doquadrupleargument\dodefinestyleinstance}
-
-\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
- {\iffirstargument
- \doifundefined{#1}{\definestylecollection[#1]}%
- \fi
- \iffourthargument
- \setvalue{\??sx#1:#2:#3}{#4}%
- \else\ifthirdargument
- \setvalue{\??sx#1::#2}{#3}%
- \else\ifsecondargument
- \letvalue{\??sx#1::#2}\empty
- \fi\fi\fi}
-
-\unexpanded\def\styleinstance[#1]% will be faster
- {%\begingroup\expanded{\infofont[#1:\fontstyle:\fontalternative]}\endgroup
- \executeifdefined{\??sx#1:\fontstyle:\fontalternative}%
- {\executeifdefined{\??sx#1:\fontstyle:\s!default}%
- {\executeifdefined{\??sx#1::\fontalternative}
- {\getvalue {\??sx#1::\s!default}}}}}
-
-% \unexpanded\def\styleinstance[#1]%
-% {\csname\??sx#1%
-% \ifcsname:\fontstyle:\fontalternative\endcsname
-% :\fontstyle:\fontalternative
-% \else\ifcsname:\fontstyle:\s!default\endcsname
-% :\fontstyle:\s!default
-% \else\ifcsname::\fontalternative\endcsname
-% ::\fontalternative
-% \else\ifcsname::\s!default\endcsname
-% ::\s!default
-% \else
-% % nothing, \relax
-% \fi\fi\fi\fi
-% \endcsname}
-
% no, wrong! never!
%
% \def\tightlayer[#1]%
@@ -849,16 +789,6 @@
% externfiguur -> grid =ja|hoogte|diepte|halveregel|passend -> helemaal in details
% stelplaatsblokin -> zijuitlijnen=hoogte|diepte|regel|halveregel|grid -> halveregel in 'details'
-% TODO: TEST FIRST, NO CORRECTION NEEDED IN GRID MODE, EVT OPTION
-
-\def\OTRONEsomeherefloat[#1]% spacing between two successive must be better
- {\baselinecorrection % not really needed in grid mode:
- %\ifgridsnapping \else \baselinecorrection \fi % ! ! ! test test test ! ! ! !
- \doplacefloatbox
- \doinsertfloatinfo
- \dochecknextindentation\??bk
- \dorechecknextindentation}
-
% todo: switch koppelen aan par scheelt pos
% to be documented: \startspread .. \stopspread
diff --git a/tex/context/base/cont-nl.tex b/tex/context/base/cont-nl.tex
index 4635d750d..32b82b01a 100644
--- a/tex/context/base/cont-nl.tex
+++ b/tex/context/base/cont-nl.tex
@@ -29,6 +29,14 @@
\installlanguage [\s!nl] [\c!state=\v!start]
\installlanguage [\s!it] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-old.tex b/tex/context/base/cont-old.tex
index f8b4b6062..360b5f2e6 100644
--- a/tex/context/base/cont-old.tex
+++ b/tex/context/base/cont-old.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Old Macros}
+\writestatus{loading}{ConTeXt Old Macros}
\unprotect
diff --git a/tex/context/base/cont-pe.tex b/tex/context/base/cont-pe.tex
index ab2b30bcd..fdf47d680 100644
--- a/tex/context/base/cont-pe.tex
+++ b/tex/context/base/cont-pe.tex
@@ -32,6 +32,14 @@
\installlanguage [\s!nl] [\c!state=\v!start]
\installlanguage [\s!pe] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-ro.tex b/tex/context/base/cont-ro.tex
index e6b2eadf3..9be9b1162 100644
--- a/tex/context/base/cont-ro.tex
+++ b/tex/context/base/cont-ro.tex
@@ -25,6 +25,14 @@
\installlanguage [\s!de] [\c!state=\v!start]
\installlanguage [\s!ro] [\c!state=\v!start]
-\setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\ifnum\texengine=\luatexengine
+ % will be runtime option: typeface
+ \appendtoks
+ \usetypescript[modern]
+ \setuptypeface[modern]
+ \to \everyjob
+\else
+ \setupencoding[default=ec] \usetypescript[fallback][\defaultencoding] \setupbodyfont[rm,12pt]
+\fi
\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/cont-sys.ori b/tex/context/base/cont-sys.ori
index 335a7d984..11c0141e7 100644
--- a/tex/context/base/cont-sys.ori
+++ b/tex/context/base/cont-sys.ori
@@ -14,8 +14,8 @@
\unprotect
% Speed up typescript loading, but at the cost of much memory:
-%
-% \preloadtypescripts
+
+\preloadtypescripts
% If you want another default font:
%
@@ -121,7 +121,6 @@
% When you have your own fonts installed, you may want to predefine:
%
% \usetypescriptfile[type-buy]
-% \usetypescriptfile [type-gyr]
% Some styles default to Lucida Bright. You can overload
% Lucida by Times cum suis. Watch out, the pos collection
@@ -158,8 +157,8 @@
% Enabling run time \METAPOST\ (also enable \write18 in
% texmf.cnf):
-% \runMPgraphicstrue
-% \runMPTEXgraphicstrue
+\runMPgraphicstrue
+\runMPTEXgraphicstrue
% This saves some runtime, but needs a format, which you can
% make with 'texexec --make --alone metafun'. Make sure that
diff --git a/tex/context/base/cont-usr.ori b/tex/context/base/cont-usr.ori
index dab420e3e..5a3070362 100644
--- a/tex/context/base/cont-usr.ori
+++ b/tex/context/base/cont-usr.ori
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{User Settings}
+\writestatus{loading}{ConTeXt User Settings}
\unprotect
diff --git a/tex/context/base/context-base.lmx b/tex/context/base/context-base.lmx
new file mode 100644
index 000000000..5c96b4979
--- /dev/null
+++ b/tex/context/base/context-base.lmx
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--
+ filename : context-base.xml
+ comment : companion to mtx-server-ctx-startup.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title><?lua pv('title') ?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <?lmx-include context.css ?>
+ </style>
+ </head>
+ <body>
+ <div id="top"><div id="top-one"><div id="top-two">
+ <?lua pv('title') ?>
+ </div></div></div>
+ <div id="left"><div id="left-one"><div id="left-two">
+ <?lua pv('lefttext') ?>
+ </div></div></div>
+ <div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five">
+ <?lua pv('righttext') ?>
+ </div></div></div></div></div></div></div>
+ <div id="main"><div id='main-settings'>
+ <div class='title'><?lua pv('maintext') ?></div>
+ </div></div>
+ <div id="bottom"><div id="bottom-one"><div id="bottom-two">
+ <?lua pv('bottomtext') ?>
+ </div></div></div>
+ </body>
+</html>
diff --git a/tex/context/base/context-characters.lmx b/tex/context/base/context-characters.lmx
index b992d30b8..b2ddee64e 100644
--- a/tex/context/base/context-characters.lmx
+++ b/tex/context/base/context-characters.lmx
@@ -1,35 +1,41 @@
-<!--
- -- filename : comm-deb.xml
- -- comment : companion to comm-xml.tex
- -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
- -- copyright: PRAGMA ADE / ConTeXt Development Team
- -- license : see context related readme files
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ filename : context-characters.lmx
+ comment : companion to context.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
-->
-<html>
- <title><?lua pv('title') ?></title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <style type="text/css">
- <!--
- <?lmx-include context.css ?>
- #type {
- text-align: center ;
- }
- #variable {
- width: 10em ;
- text-align: right ;
- margin-right: 1em ;
- }
- #value {
- text-align: left ;
- }
- -->
- </style>
- <script language="JavaScript">
- <!--
- window.focus();
- -->
- </script>
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <script language="JavaScript">
+ <!--
+ window.focus();
+ -->
+ </script>
+ <title><?lua pv('title') ?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <!--
+ <?lmx-include context.css ?>
+ #type {
+ text-align: center ;
+ }
+ #variable {
+ width: 10em ;
+ text-align: right ;
+ margin-right: 1em ;
+ }
+ #value {
+ text-align: left ;
+ }
+ -->
+ </style>
+ </head>
<body> <!-- onclick="location.reload()" -->
<div id="top"><div id="top-one"><div id="top-two">
<?lua pv('title') ?>
diff --git a/tex/context/base/context-debug.lmx b/tex/context/base/context-debug.lmx
index 593f35672..8ca2573a9 100644
--- a/tex/context/base/context-debug.lmx
+++ b/tex/context/base/context-debug.lmx
@@ -1,36 +1,41 @@
-<!--
- -- filename : comm-deb.xml
- -- comment : companion to comm-xml.tex
- -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
- -- copyright: PRAGMA ADE / ConTeXt Development Team
- -- license : see context related readme files
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ filename : context-debug.lmx
+ comment : companion to context.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
-->
-<html>
- <title><?lua pv('title') ?></title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <style type="text/css">
- <!--
- <?lmx-include context.css ?>
- #type {
- text-align: center ;
- }
- #variable {
- width: 10em ;
- text-align: right ;
- margin-right: 1em ;
- }
- #value {
- text-align: left ;
- }
- -->
- </style>
- <script language="JavaScript">
- <!--
- window.focus();
- -->
- </script>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <script language="JavaScript">
+ <!--
+ window.focus();
+ -->
+ </script>
+ <title><?lua pv('title') ?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <!--
+ <?lmx-include context.css ?>
+ #type {
+ text-align: center ;
+ }
+ #variable {
+ width: 10em ;
+ text-align: right ;
+ margin-right: 1em ;
+ }
+ #value {
+ text-align: left ;
+ }
+ -->
+ </style>
+ </head>
<body>
<div id="top"><div id="top-one"><div id="top-two">
<?lua pv('title') ?>
@@ -41,7 +46,6 @@
<div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five">
<!-- empty -->
</div></div></div></div></div></div></div>
- <div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five"></div></div></div></div></div></div></div>
<div id="main"><div id='main-settings'>
<?lua if tracers.knownlist('scratch') then ?>
<h1>Scratch Variables</h1>
diff --git a/tex/context/base/context-error.lmx b/tex/context/base/context-error.lmx
index df3ad9090..015d74c9f 100644
--- a/tex/context/base/context-error.lmx
+++ b/tex/context/base/context-error.lmx
@@ -1,26 +1,30 @@
-<!--
- -- filename : comm-err.xml
- -- comment : companion to comm-xml.tex
- -- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
- -- copyright: PRAGMA ADE / ConTeXt Development Team
- -- license : see context related readme files
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ filename : context-error.lmx
+ comment : companion to context.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
-->
-<html>
- <title><?lua pv('title')?></title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <style type="text/css">
- <!--
- <?lmx-include context.css ?>
- -->
- </style>
- <script language="JavaScript">
- <!--
- window.focus();
- parent.close();
- -->
- </script>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <script language="JavaScript">
+ <!--
+ window.focus();
+ -->
+ </script>
+ <title><?lua pv('title')?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <!--
+ <?lmx-include context.css ?>
+ -->
+ </style>
+ </head>
<body>
<div id="top"><div id="top-one"><div id="top-two">
<?lua pv('title')?>
@@ -40,7 +44,7 @@
<tr><td>File </td><td>&nbsp;&nbsp;&nbsp;<?lua tv('filename') ?></td></tr>
<tr><td>Line </td><td>&nbsp;&nbsp;&nbsp;<?lua tv('linenumber') ?></td></tr>
</table>
- </br>
+ <br/>
<pre>
<?lua pv('errorcontext')?>
</pre>
diff --git a/tex/context/base/context-fonttest.lmx b/tex/context/base/context-fonttest.lmx
new file mode 100644
index 000000000..b90af179d
--- /dev/null
+++ b/tex/context/base/context-fonttest.lmx
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--
+ filename : context-fonttest.lmx
+ comment : companion to mtx-server-ctx-fonttest.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <script type="text/javascript">
+ <!--
+ window.focus() ;
+ <?lua pv('javascripts')?> ;
+ <?lua pv('javascriptdata')?> ;
+ -->
+ </script>
+ <title><?lua pv('title')?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <?lmx-include context.css ?>
+ </style>
+ </head>
+ <body onLoad="<?lua pv('javascriptinit')?>">
+ <form action="<?lua pv('formaction')?>" name="main-form">
+ <div id="top"><div id="top-one"><div id="top-two">
+ <?lua pv('title')?>
+ </div></div></div>
+ <div id="left"><div id="left-one"><div id="left-two">
+ <?lua pv('status')?>
+ </div></div></div>
+ <div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five">
+ <!-- empty -->
+ </div></div></div></div></div></div></div>
+ <div id="main"><div id="main-settings">
+ <?lua pv('maintext')?>
+ </div></div>
+ <div id="bottom"><div id="bottom-one"><div id="bottom-two">
+ <?lua pv('menu')?>
+ </div></div></div>
+ </form>
+ </body>
+</html>
diff --git a/tex/context/base/context-help.lmx b/tex/context/base/context-help.lmx
new file mode 100644
index 000000000..3c663b0ac
--- /dev/null
+++ b/tex/context/base/context-help.lmx
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--
+ filename : comm-deb.xml
+ comment : companion to comm-xml.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<html>
+ <head>
+ <script language="JavaScript">
+ <!--
+ window.focus();
+ -->
+ </script>
+ <title><?lua pv('title') ?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <!--
+<?lmx-include context.css ?>
+
+#main-left {
+ position: absolute;
+ left: 0% ;
+ top: 0% ;
+ right: 0% ;
+ bottom: 0% ;
+ z-index: 2 ;
+ width: 75% ;
+ height: 100% ;
+ padding: 0% ;
+ margin: 0% ;
+ overflow: auto ;
+ border-style: none ;
+ border-width: 0 ;
+ background-color: <?lua pv('color-background-main-left')?> ;
+}
+#main-right {
+ position: absolute;
+ left: 75% ;
+ top: 0% ;
+ right: 0% ;
+ bottom: 0% ;
+ z-index: 2 ;
+ width: 25% ;
+ height: 100% ;
+ padding: 0% ;
+ margin: 0% ;
+ overflow: auto ;
+ border-style: none ;
+ border-width: 0 ;
+ background-color: <?lua pv('color-background-main-right')?> ;
+}
+#main-common-settings {
+ padding: 1em ;
+}
+
+ -->
+ </style>
+ </head>
+ <body>
+ <div id="top"><div id="top-one"><div id="top-two">
+ <?lua pv('title') ?>
+ </div></div></div>
+ <div id="left"><div id="left-one"><div id="left-two">
+ <!-- empty -->
+ </div></div></div>
+ <div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five">
+ <?lua pv('interfaces') ?>
+ </div></div></div></div></div></div></div>
+ <div id="main"><div id='main-settings'>
+ <div id="main-right"><div id="main-common-settings">
+ <?lua pv('names') ?>
+ </div></div>
+ <div id="main-left"><div id="main-common-settings">
+ <h1><?lua pv('maintitle') ?></h1>
+ <?lua pv('maintext') ?>
+ </div></div>
+ </div></div>
+ <div id="bottom"><div id="bottom-one"><div id="bottom-two">
+ <?lua pv('extra') ?>
+ </div></div></div>
+ </body>
+</html>
diff --git a/tex/context/base/context-timing.lmx b/tex/context/base/context-timing.lmx
new file mode 100644
index 000000000..eea9db822
--- /dev/null
+++ b/tex/context/base/context-timing.lmx
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<!--
+ filename : context-timing.xml
+ comment : companion to mtx-timing.tex
+ author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+ copyright: PRAGMA ADE / ConTeXt Development Team
+ license : see context related readme files
+-->
+
+<!--
+ beware: xhtml, so no comment around css
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <script language="JavaScript">
+ <!--
+ window.focus();
+ -->
+ </script>
+ <title><?lua pv('title')?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <style type="text/css">
+ <?lmx-include context.css ?>
+ </style>
+ </head>
+ <body>
+ <div id="top"><div id="top-one"><div id="top-two">
+ <?lua pv('title')?>
+ </div></div></div>
+ <div id="left"><div id="left-one"><div id="left-two">
+ <!-- empty -->
+ </div></div></div>
+ <div id="right"><div id="right-safari"><div id="right-one"><div id="right-two"><div id="right-three"><div id="right-four"><div id="right-five">
+ <!-- empty -->
+ </div></div></div></div></div></div></div>
+ <div id="main"><div id="main-settings">
+ <?lua pv('graphics')?>
+ </div></div>
+ <div id="bottom"><div id="bottom-one"><div id="bottom-two">
+ <small>
+ <br/> <br/>
+ <?lua pv('parametersmenu')?>
+ <br/>
+ <?lua pv('nodesmenu')?>
+ </small>
+ </div></div></div>
+ </body>
+</html>
diff --git a/tex/context/base/context.css b/tex/context/base/context.css
index ef4a44cea..f332ae242 100644
--- a/tex/context/base/context.css
+++ b/tex/context/base/context.css
@@ -12,6 +12,12 @@ a.dir-view:link, a.dir-view:active, a.dir-view:visited {
color: #FFFFFF ;
text-decoration: underline ;
}
+.valid {
+ color: #00FF00 ;
+}
+.invalid {
+ color: #FF0000 ;
+}
h1, .title {
font-style: normal ;
font-weight: normal ;
@@ -31,6 +37,15 @@ table {
font-size: 12px ;
margin: 0 ;
}
+th {
+ font-weight: bold ;
+ text-align: left ;
+ padding-bottom: 6px ;
+}
+.tc {
+ font-weight: bold ;
+ text-align: left ;
+}
p, li {
max-width: 60em ;
}
diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii
index d58ba7ad7..1a2fa4abb 100644
--- a/tex/context/base/context.mkii
+++ b/tex/context/base/context.mkii
@@ -15,37 +15,46 @@
%D manipulation macros. The first one loads \PLAIN\ \TEX, as
%D minimal as possible.
+\loadcorefile{syst-ini.tex}
+\loadcorefile{norm-tex.tex}
+\loadcorefile{norm-etx.tex}
+\loadcorefile{norm-ptx.tex}
+\loadcorefile{norm-xtx.tex}
+\loadcorefile{norm-ctx.tex}
\loadcorefile{syst-pln.tex}
-\loadcorefile{syst-prm.tex}
-\loadcorefile{syst-cat.tex}
-
-\loadcorefile{syst-etx.tex}
-\loadcorefile{syst-pdt.tex}
-\loadcorefile{syst-omg.tex}
-\loadcorefile{syst-xtx.tex}
-\loadcorefile{syst-mtx.tex}
+\loadmarkfile{catc-ini}
+\loadcorefile{catc-act.tex}
+\loadcorefile{catc-def.tex}
+\loadcorefile{catc-ctx.tex}
+\loadcorefile{catc-sym.tex}
\loadcorefile{syst-gen.tex}
\loadcorefile{syst-ext.tex}
-\loadcorefile{syst-chr.tex}
-\loadcorefile{syst-fnt.tex}
\loadcorefile{syst-new.tex}
-\loadcorefile{syst-con.tex}
-\loadcorefile{syst-var.tex}
-\loadcorefile{syst-str.tex}
-\loadcorefile{syst-rtp.tex}
+\loadmarkfile{syst-con}
+\loadcorefile{thrd-trg.tex} % based on: David Carlisle
+
+\loadmarkfile{syst-fnt}
+\loadmarkfile{syst-str}
+\loadmarkfile{syst-rtp}
+
+\ifnum\texengine=\xetexengine
+ \loadcorefile{xetx-ini.tex}
+ \loadcorefile{xetx-utf.tex}
+ \loadcorefile{xetx-chr.tex}
+ \loadcorefile{xetx-cls.tex}
+\fi
%D To enable selective loading, we say:
-\CONTEXTtrue
+\newif\ifCONTEXT \CONTEXTtrue % will disappear
%D In order to conveniently load files, we need a few
%D support modules.
-\loadcorefile{supp-ini.tex}
-\loadcorefile{supp-fil.tex}
-\loadcorefile{supp-dir.tex}
+\loadmarkfile{supp-fil}
+\loadmarkfile{supp-dir}
%D After this we're ready for the multi||lingual interface
%D modules.
@@ -54,17 +63,13 @@
\loadcorefile{mult-fst.tex}
\loadcorefile{mult-sys.tex}
\loadcorefile{mult-def.tex}
-
-%D We also use some third party macros. These are loaded by
-%D saying:
-
-\loadcorefile{thrd-ran.tex} % based on: Donald Arseneau
-\loadcorefile{thrd-trg.tex} % based on: David Carlisle
+\loadmarkfile{mult-chk}
%D Now we're ready for some general support modules. These
%D modules implement some basic typesetting functionality.
\loadcorefile{core-var.tex}
+\loadmarkfile{core-env}
\loadcorefile{supp-box.tex}
\loadcorefile{supp-mrk.tex}
@@ -72,7 +77,7 @@
\loadcorefile{supp-fun.tex}
%loadcorefile{supp-eps.tex}
\loadcorefile{supp-spe.tex}
-\loadcorefile{supp-ran.tex}
+\loadmarkfile{supp-ran}
%loadcorefile{supp-mps.tex}
\loadmkiifile{supp-mps.tex}
\loadmkiifile{supp-tpi.tex}
@@ -101,7 +106,7 @@
\loadcorefile{core-ins.tex}
\loadcorefile{core-fil.tex}
-\loadcorefile{core-con.tex}
+\loadmarkfile{core-con}
%D We already need some synonyms (patterns). At runtime this
%D file will be reloaded.
@@ -122,43 +127,40 @@
%D The next few modules do what their names state. They
%D load additional definition modules when needed.
-\loadcorefile{regi-ini.tex}
-\loadcorefile{enco-ini.tex}
-\loadcorefile{filt-ini.tex}
-\loadcorefile{hand-ini.tex}
+\loadmarkfile{regi-ini}
\loadcorefile{regi-syn.tex}
-\loadcorefile{lang-ini.tex}
-\loadcorefile{lang-ctx.tex}
-\loadcorefile{lang-dis.tex}
+\loadmarkfile{enco-ini}
+%loadcorefile{filt-ini.tex}
+\loadmarkfile{hand-ini}
+
+\loadmarkfile{lang-ini}
+\loadmarkfile{lang-spe}
+\loadmarkfile{lang-lab}
\loadmarkfile{unic-ini}
\loadcorefile{core-gen.tex}
-\loadcorefile{core-new.tex}
-\loadcorefile{core-uti.tex}
-\loadcorefile{core-two.tex}
+\loadmarkfile{core-uti}
+\loadmarkfile{core-two}
\loadcorefile{core-stg.tex}
-\loadcorefile{spec-mis.tex}
\loadcorefile{spec-ini.tex}
+\loadcorefile{spec-mis.tex}
\loadcorefile{spec-def.tex}
\loadcorefile{spec-var.tex}
-\loadcorefile{colo-ini.tex}
-\loadcorefile{colo-ext.tex}
+\loadmarkfile{colo-ini}
+\loadmarkfile{colo-ext}
%D For the moment we load a lot of languages. In the future
%D we'll have to be more space conservative.
\loadcorefile{lang-mis.tex}
-\loadcorefile{lang-url.tex}
-\loadcorefile{lang-spe.tex}
-\loadcorefile{lang-lab.tex}
+\loadmarkfile{lang-url}
\loadcorefile{lang-ger.tex}
\loadcorefile{lang-ita.tex}
\loadcorefile{lang-sla.tex}
-
\loadcorefile{lang-alt.tex}
\loadcorefile{lang-ana.tex}
\loadcorefile{lang-art.tex}
@@ -167,10 +169,9 @@
\loadcorefile{lang-grk.tex}
\loadcorefile{lang-ind.tex}
\loadcorefile{lang-ura.tex}
-
\loadcorefile{lang-vn.tex}
-
\loadcorefile{lang-ara.tex}
+\loadcorefile{lang-cyr.tex}
%D All kind of symbols are handled in:
@@ -178,43 +179,45 @@
%D Sorting:
-\loadcorefile{sort-ini.tex}
+\loadmarkfile{sort-ini}
%D Next we load some core macro's. These implement the
%D macros' that are seen by the users. The order of loading
%D is important, due to dependancies.
-\loadcorefile{core-spa.tex}
+\loadmarkfile{core-spa}
\loadcorefile{core-grd.tex}
\loadcorefile{core-mar.tex}
-\loadcorefile{core-pos.tex}
+\loadmarkfile{core-pos}
\loadcorefile{core-mak.tex}
\loadcorefile{core-dat.tex}
-\loadcorefile{core-ver.tex}
-\loadcorefile{core-rul.tex}
+\loadmarkfile{core-ver}
+\loadmarkfile{core-rul}
\loadcorefile{core-vis.tex}
\loadcorefile{core-num.tex}
-\loadcorefile{core-tsp.tex}
-\loadcorefile{core-tab.tex}
-\loadcorefile{core-nav.tex}
+\loadcorefile{tabl-pln.tex}
+\loadcorefile{tabl-tab.tex}
+\loadcorefile{tabl-tsp.tex}
+\loadmarkfile{core-nav}
\loadcorefile{core-ref.tex}
-\loadcorefile{core-obj.tex}
+\loadmarkfile{core-obj}
\loadcorefile{core-lst.tex}
\loadcorefile{core-itm.tex}
\loadcorefile{core-des.tex}
-\loadcorefile{core-mat.tex}
+\loadcorefile{core-mat.tex} % should come after math-pln etc
\loadcorefile{core-syn.tex}
-\loadcorefile{core-sys.tex}
+\loadmarkfile{core-sys}
-\loadcorefile{page-ini.tex}
-\loadcorefile{page-bck.tex}
+\loadmarkfile{page-ini}
+\loadmarkfile{page-bck}
\loadcorefile{page-not.tex}
-\loadcorefile{page-one.tex}
+\loadmarkfile{page-one}
\loadcorefile{page-lay.tex}
\loadmkiifile{page-log.tex}
-\loadcorefile{page-txt.tex}
+\loadmarkfile{page-txt}
\loadcorefile{page-sid.tex}
\loadcorefile{page-flt.tex}
+\loadcorefile{page-mis.tex}
\loadcorefile{page-mul.tex}
\loadcorefile{page-set.tex}
\loadcorefile{page-lyr.tex}
@@ -224,19 +227,20 @@
\loadcorefile{page-par.tex}
\loadcorefile{page-mar.tex}
-\loadcorefile{core-job.tex} % why so late?
+\loadmarkfile{core-job} % why so late?
% so far
-\loadmarkfile{core-sec}
+\loadcorefile{core-sec.tex}
\loadcorefile{core-swd.tex}
-\loadcorefile{core-buf.tex}
+\loadmarkfile{core-buf}
\loadcorefile{core-blk.tex}
\loadcorefile{page-imp.tex}
-\loadcorefile{core-tbl.tex}
-\loadcorefile{core-int.tex}
-\loadcorefile{core-ntb.tex}
-\loadcorefile{core-ltb.tex}
+\loadcorefile{tabl-tbl.tex}
+\loadmarkfile{core-int}
+\loadmarkfile{tabl-ntb}
+\loadcorefile{tabl-nte.tex}
+\loadcorefile{tabl-ltb.tex}
%D A few more languages, that have specifics using core
%D functionality:
@@ -246,8 +250,8 @@
%D How about fill||in fields and related stuff?
-\loadcorefile{java-ini.tex}
-\loadcorefile{core-fld.tex}
+\loadmarkfile{java-ini}
+\loadmarkfile{core-fld}
\loadcorefile{core-hlp.tex}
%D Registers can depend on fields, so we load that now.
@@ -260,27 +264,33 @@
%D instead of italian.
\loadmarkfile{font-ini}
-\loadcorefile{font-uni.tex}
+
+\ifnum\texengine=\xetexengine
+ \loadcorefile{font-xtx.tex}
+\fi
+
+\loadmarkfile{font-unk}
+\loadmarkfile{font-uni}
\loadcorefile{font-bfm.tex}
\loadcorefile{enco-pfr.tex}
-\loadcorefile{type-ini.tex}
+\loadmarkfile{type-ini}
\loadcorefile{type-def.tex}
%D Properties. Don't ask.
-\loadcorefile{prop-ini.tex}
-\loadcorefile{prop-lay.tex}
-\loadcorefile{prop-mis.tex}
+\loadmarkfile{prop-ini}
+\loadmarkfile{prop-lay}
+\loadmarkfile{prop-mis}
%D Like languages, fonts, encodings and symbols, \METAPOST\
%D support is also organized in its own class of modules.
\loadmarkfile{meta-ini}
\loadmarkfile{meta-tex}
+\loadmarkfile{meta-pdf}
-\loadcorefile{meta-pdf.tex}
\loadcorefile{meta-pag.tex}
%D Special page handling (maybe even later)
@@ -299,20 +309,21 @@
%D Math.
-\loadcorefile{math-pln.tex}
-\loadcorefile{math-ini.tex}
-\loadcorefile{math-ext.tex}
+\loadmarkfile{math-pln}
+\loadmarkfile{math-ini}
+\loadmarkfile{math-arr}
+\loadmarkfile{math-frc}
%D Now we're ready for more core modules.
-\loadcorefile{core-fnt.tex}
+\loadmarkfile{core-fnt}
\loadcorefile{core-not.tex}
\loadcorefile{core-lnt.tex}
-\loadcorefile{core-mis.tex}
+\loadmarkfile{core-mis}
\loadcorefile{core-trf.tex}
-\loadcorefile{core-inc.tex}
+\loadmarkfile{core-inc}
\loadcorefile{core-fig.tex}
\loadcorefile{core-par.tex}
@@ -330,14 +341,10 @@
\loadcorefile{xtag-ini.tex}
\loadcorefile{xtag-ext.tex}
-\loadcorefile{xtag-prs.tex}
-\loadcorefile{xtag-map.tex}
-\loadcorefile{xtag-stk.tex}
\loadcorefile{xtag-exp.tex}
\loadcorefile{xtag-pre.tex}
\loadcorefile{xtag-xsd.tex}
\loadcorefile{xtag-rng.tex}
-%loadcorefile{xtag-ent.tex}
%D How about this:
@@ -350,14 +357,14 @@
%D This one overloads af few things:
-\loadcorefile{core-ctx.tex}
+\loadmarkfile{core-ctx}
%D Defaults go here (more will be moved to this module
%D later):
\loadcorefile{core-lme.tex}
\loadcorefile{core-ini.tex}
-\loadcorefile{core-def.tex}
+\loadmarkfile{core-def}
%D Preloaded modules (some need xml support):
@@ -374,23 +381,6 @@
%D \item \type{cont-fil}: filename and module synonyms
%D \stopitemize
-\unprotect
-
-\beginLUATEX
- \prependtoks
- \ctxlua{input.starttiming(ctx)}%
- \to \everyjob
- \appendtoks
- \ctxlua{input.stoptiming(ctx)}%
- \to \everyjob
- \appendtoks
- \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath())}}%
- \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}}%
- \to \everydump
-\endLUATEX
-
-\protect
-
% %D Except from english, no hyphenation patterns are loaded
% %D yet. Users can specify their needs in the next module:
%
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index fb130e5ea..b3542fb21 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -11,171 +11,119 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% syst-cat -> catc-ini + vectors
+% spec-* -> special backends for luatex
+
%D First we load the system modules. These implement a lot of
%D manipulation macros. The first one loads \PLAIN\ \TEX, as
%D minimal as possible.
+\loadcorefile{syst-ini.tex}
+\loadcorefile{norm-ctx.tex}
\loadcorefile{syst-pln.tex}
-\loadcorefile{syst-prm.tex}
-\loadmkivfile{luat-env.tex}
+\loadmkivfile{luat-cod.tex}
+\loadmkivfile{luat-bas.tex}
\loadmkivfile{luat-lib.tex}
-\loadcorefile{syst-cat.tex}
-
-\loadcorefile{syst-etx.tex}
-\loadcorefile{syst-pdt.tex}
-\loadcorefile{syst-omg.tex}
-\loadcorefile{syst-xtx.tex}
-\loadcorefile{syst-mtx.tex}
-\loadcorefile{syst-gen.tex}
-\loadcorefile{syst-ext.tex}
-\loadcorefile{syst-chr.tex}
-\loadcorefile{syst-fnt.tex}
-\loadcorefile{syst-new.tex}
-\loadcorefile{syst-con.tex}
-\loadcorefile{syst-var.tex}
-\loadcorefile{syst-str.tex}
-\loadcorefile{syst-rtp.tex}
+\loadmarkfile{catc-ini}
+\loadcorefile{catc-act.tex}
+\loadcorefile{catc-def.tex}
+\loadcorefile{catc-ctx.tex}
+\loadcorefile{catc-sym.tex}
-%D To enable selective loading, we say:
+\newif\ifCONTEXT \CONTEXTtrue % will disappear
-\CONTEXTtrue
+\loadcorefile{syst-aux.tex}
+\loadcorefile{syst-lua.tex}
+\loadmarkfile{syst-con}
-%D In order to conveniently load files, we need a few
-%D support modules.
+\loadmarkfile{syst-fnt}
+\loadmarkfile{syst-str}
+\loadmarkfile{syst-rtp}
-\loadcorefile{supp-ini.tex}
-\loadcorefile{supp-fil.tex}
-\loadcorefile{supp-dir.tex}
-
-%D We need to initialize characters.
+\loadmarkfile{supp-fil}
+\loadmarkfile{supp-dir}
\loadmkivfile{char-ini.tex}
\loadmkivfile{char-utf.tex}
-%D After this we're ready for the multi||lingual interface
-%D modules.
-
\loadmarkfile{mult-ini}
\loadcorefile{mult-fst.tex}
\loadcorefile{mult-sys.tex}
\loadcorefile{mult-def.tex}
+\loadmarkfile{mult-chk}
\loadmkivfile{luat-ini.tex}
-\loadmkivfile{luat-lmx.tex}
-
-\loadmkivfile{luat-uni.tex}
\loadmkivfile{toks-ini.tex}
-\loadmkivfile{attr-ini.tex}
\loadmkivfile{node-ini.tex}
+\loadmkivfile{node-fin.tex}
\loadmkivfile{node-par.tex}
-%D We also use some third party macros. These are loaded by
-%D saying:
+\loadcorefile{core-var.tex}
-\loadcorefile{thrd-ran.tex} % based on: Donald Arseneau
-\loadcorefile{thrd-trg.tex} % based on: David Carlisle
+\loadcorefile{back-ini.tex}
+\loadcorefile{back-pdf.tex}
-%D Now we're ready for some general support modules. These
-%D modules implement some basic typesetting functionality.
+\loadmkivfile{attr-ini.tex}
-\loadcorefile{core-var.tex}
-\loadmkivfile{luat-deb.tex}
+\loadmarkfile{core-env}
+
+\loadmkivfile{trac-lmx.tex}
+\loadmkivfile{trac-deb.tex}
\loadcorefile{supp-box.tex}
-\loadcorefile{supp-mrk.tex}
+
\loadcorefile{supp-vis.tex}
\loadcorefile{supp-fun.tex}
-\loadcorefile{supp-spe.tex}
-\loadcorefile{supp-ran.tex}
+
+\loadmarkfile{supp-ran}
\loadcorefile{supp-mat.tex}
\loadcorefile{supp-ali.tex}
\loadcorefile{supp-num.tex}
-%D The next module deals with language specific typographic
-%D extensions.
-
\loadcorefile{typo-ini.tex}
-%D Verbatim typesetting is implemented in a separate class of
-%D modules. The pretty typesetting modules are loaded at run
-%D time.
-
\loadcorefile{verb-ini.tex}
-%D The following modules are not sequentially dependent,
-%D i.e. they have ugly dependencies, which will be cleaned
-%D up by adding more overloading.
-
-%D When loading the font, color and special modules, we need a
-%D bit more advanced file handling as well as some general
-%D variables, and features, so next we load:
-
\loadcorefile{core-ins.tex}
\loadcorefile{core-fil.tex}
-\loadcorefile{core-con.tex}
-
-%D We already need some synonyms (patterns). At runtime this
-%D file will be reloaded.
+\loadmarkfile{core-con}
\loadcorefile{cont-fil.tex}
-%D \CONTEXT\ does not implement its own table handling. We
-%D just go for the best there is and load \TABLE. Just to be
-%D sure we do it here, before we redefine \type{|}.
-
-\loadcorefile{thrd-tab.tex} % based on: Michael Wichura / will be reimplemented
-
-%D Here comes the last support modules. They take care of
-%D some language specific things.
-
-\loadcorefile{supp-pat.tex}
-
-%D The next few modules do what their names state. They
-%D load additional definition modules when needed.
-
-\loadcorefile{regi-ini.tex}
-\loadcorefile{enco-ini.tex}
-\loadcorefile{filt-ini.tex}
-\loadcorefile{hand-ini.tex}
+\loadmarkfile{regi-ini}
\loadcorefile{regi-syn.tex}
-\loadcorefile{lang-ini.tex}
-\loadcorefile{lang-ctx.tex}
-\loadcorefile{lang-dis.tex}
+\loadmarkfile{enco-ini}
+\loadmarkfile{hand-ini}
-\loadmarkfile{unic-ini}
+\loadmarkfile{lang-ini}
+\loadmarkfile{lang-spe}
+\loadmarkfile{lang-lab}
-% \readfile{lang-url.pat}{}{} % test
+\loadmarkfile{unic-ini}
\loadcorefile{core-gen.tex}
-\loadcorefile{core-new.tex}
-\loadcorefile{core-uti.tex}
-\loadcorefile{core-two.tex}
+\loadmarkfile{core-uti}
+\loadmarkfile{core-two}
\loadcorefile{core-stg.tex}
-\loadcorefile{spec-mis.tex}
-\loadcorefile{spec-ini.tex}
-\loadcorefile{spec-def.tex}
-\loadcorefile{spec-var.tex}
+% \loadcorefile{spec-ini.tex}
+% \loadcorefile{spec-mis.tex}
+% \loadcorefile{spec-def.tex}
+% \loadcorefile{spec-var.tex}
-\loadcorefile{colo-ini.tex}
-\loadcorefile{colo-ext.tex}
-
-%D For the moment we load a lot of languages. In the future
-%D we'll have to be more space conservative.
+\loadmarkfile{colo-ini}
+\loadmarkfile{colo-ext}
\loadcorefile{lang-mis.tex}
-\loadcorefile{lang-url.tex}
-\loadcorefile{lang-spe.tex}
-\loadcorefile{lang-lab.tex}
+\loadmarkfile{lang-url}
\loadcorefile{lang-ger.tex}
\loadcorefile{lang-ita.tex}
\loadcorefile{lang-sla.tex}
-
\loadcorefile{lang-alt.tex}
\loadcorefile{lang-ana.tex}
\loadcorefile{lang-art.tex}
@@ -184,113 +132,118 @@
\loadcorefile{lang-grk.tex}
\loadcorefile{lang-ind.tex}
\loadcorefile{lang-ura.tex}
-
+\loadcorefile{lang-cjk.tex}
\loadcorefile{lang-vn.tex}
-
\loadcorefile{lang-ara.tex}
-
-%D All kind of symbols are handled in:
+\loadcorefile{lang-cyr.tex}
\loadcorefile{symb-ini.tex}
-%D Sorting:
+\loadmarkfile{sort-ini}
-\loadcorefile{sort-ini.tex}
+\loadmarkfile{core-rul}
-%D Next we load some core macro's. These implement the
-%D macros' that are seen by the users. The order of loading
-%D is important, due to dependancies.
+\loadcorefile{lxml-ini}
-\loadcorefile{core-spa.tex}
+\loadcorefile{strc-ini}
+\loadcorefile{strc-doc}
+\loadcorefile{strc-mar}
+\loadcorefile{strc-prc}
+\loadcorefile{strc-sbe}
+\loadcorefile{strc-lst}
+\loadcorefile{strc-sec}
+\loadcorefile{strc-num}
+\loadcorefile{strc-ren}
+\loadcorefile{strc-xml}
+\loadcorefile{strc-pag} % hm, depends on core-num
+\loadcorefile{strc-def} % might happen later
+\loadcorefile{strc-ref}
+\loadcorefile{strc-reg}
+
+\loadcorefile{bibl-bib}
+
+\loadmarkfile{core-spa}
\loadcorefile{core-grd.tex}
-\loadcorefile{core-mar.tex}
-\loadcorefile{core-pos.tex}
+
+\loadmarkfile{core-pos}
\loadcorefile{core-mak.tex}
-\loadcorefile{core-dat.tex}
-\loadcorefile{core-ver.tex}
-\loadcorefile{core-rul.tex}
+\loadmarkfile{core-ver}
+
\loadcorefile{core-vis.tex}
-\loadcorefile{core-num.tex}
-\loadcorefile{core-tsp.tex}
-\loadcorefile{core-tab.tex}
-\loadcorefile{core-nav.tex}
-\loadcorefile{core-ref.tex}
-\loadcorefile{core-obj.tex}
-\loadcorefile{core-lst.tex}
-\loadcorefile{core-itm.tex}
-\loadcorefile{core-des.tex}
-\loadcorefile{core-mat.tex}
-\loadcorefile{core-syn.tex}
-\loadcorefile{core-sys.tex}
-
-\loadcorefile{page-ini.tex}
-\loadcorefile{page-bck.tex}
+\loadmarkfile{core-nav}
+\loadmarkfile{core-obj}
+
+\loadcorefile{strc-itm.tex}
+\loadcorefile{strc-des.tex}
+\loadcorefile{strc-syn.tex}
+
+\loadmarkfile{core-sys}
+
+\loadmarkfile{page-ini}
+\loadmarkfile{page-bck}
\loadcorefile{page-not.tex}
-\loadcorefile{page-one.tex}
+\loadmarkfile{page-one}
\loadcorefile{page-lay.tex}
-\loadcorefile{page-txt.tex}
+\loadmarkfile{page-txt}
\loadcorefile{page-sid.tex}
-\loadcorefile{page-flt.tex}
+
+\loadcorefile{strc-flt.tex}
+
+\loadcorefile{page-mis.tex}
\loadcorefile{page-mul.tex}
\loadcorefile{page-set.tex}
\loadcorefile{page-lyr.tex}
\loadcorefile{page-mak.tex}
-\loadcorefile{page-num.tex}
+
\loadmarkfile{page-lin}
\loadcorefile{page-par.tex}
\loadcorefile{page-mar.tex}
-\loadcorefile{core-job.tex} % why so late?
+\loadmarkfile{core-job} % why so late?
-% so far
+\loadmarkfile{core-buf}
-\loadmarkfile{core-sec}
-\loadcorefile{core-swd.tex}
-\loadcorefile{core-buf.tex}
-\loadcorefile{core-blk.tex}
-\loadcorefile{page-imp.tex}
-\loadcorefile{core-tbl.tex}
-\loadcorefile{core-int.tex}
-\loadcorefile{core-ntb.tex}
-\loadcorefile{core-ltb.tex}
+\loadcorefile{strc-blk.tex}
-%D A few more languages, that have specifics using core
-%D functionality:
+\loadcorefile{page-imp.tex}
-\loadcorefile{lang-chi.tex}
-\loadcorefile{lang-jap.tex}
+\loadmarkfile{core-int}
+\loadcorefile{strc-bkm.tex} % bookmarks
-%D How about fill||in fields and related stuff?
+\loadcorefile{tabl-pln.tex}
+\loadcorefile{thrd-tab.tex}
+\loadcorefile{tabl-tab.tex}
+\loadcorefile{tabl-tbl.tex}
+\loadmarkfile{tabl-ntb}
+\loadcorefile{tabl-nte.tex}
+\loadcorefile{tabl-ltb.tex}
+\loadcorefile{tabl-tsp.tex}
-\loadcorefile{java-ini.tex}
-\loadcorefile{core-fld.tex}
+\loadmarkfile{java-ini}
+\loadmarkfile{core-fld}
\loadcorefile{core-hlp.tex}
-%D Registers can depend on fields, so we load that now.
-
-\loadcorefile{core-reg.tex}
-
-%D Of course we do need fonts. There are no \TFM\ files
-%D loaded yet, so the format file is independant of their
-%D content. Here we also redefine \type{\it} as {\it italic}
-%D instead of italian.
-
+\loadcorefile{char-enc.tex}
\loadmarkfile{font-ini}
-\loadcorefile{font-uni.tex}
-\loadcorefile{font-bfm.tex}
-\loadmkivfile{font-col.tex}
-
-\loadcorefile{type-ini.tex}
+\loadmarkfile{font-unk}
+\loadmarkfile{font-tra}
+\loadmarkfile{font-uni}
+\loadmarkfile{font-col}
+
+\loadcorefile{typo-spa.tex}
+\loadcorefile{typo-krn.tex}
+\loadcorefile{typo-mir.tex}
+\loadcorefile{typo-brk.tex}
+\loadcorefile{typo-cap.tex}
+
+\loadmarkfile{type-ini}
\loadcorefile{type-def.tex}
-%D Properties. Don't ask.
+\loadcorefile{scrp-ini.tex}
-\loadcorefile{prop-ini.tex}
-\loadcorefile{prop-lay.tex}
-\loadcorefile{prop-mis.tex}
-
-%D Like languages, fonts, encodings and symbols, \METAPOST\
-%D support is also organized in its own class of modules.
+\loadmarkfile{prop-ini}
+\loadmarkfile{prop-lay}
+\loadmarkfile{prop-mis}
\loadmkivfile{mlib-ctx.tex}
\loadmkivfile{mlib-pdf.tex}
@@ -298,121 +251,100 @@
\loadmarkfile{meta-ini}
\loadmarkfile{meta-tex}
+\loadmarkfile{meta-pdf}
-\loadcorefile{meta-pdf.tex}
\loadcorefile{meta-pag.tex}
-%D Special page handling (maybe even later)
-
\loadcorefile{page-flw.tex}
\loadcorefile{page-spr.tex}
\loadcorefile{page-plg.tex}
\loadcorefile{page-str.tex}
-%D Hm.
-
\loadcorefile{core-pgr.tex}
\loadcorefile{core-bar.tex}
\loadcorefile{core-snc.tex}
+\loadmarkfile{math-pln}
+\loadmarkfile{math-ini}
+\loadmarkfile{math-for}
+\loadmarkfile{math-def}
+\loadmarkfile{math-ali}
+\loadmarkfile{math-arr}
+\loadmarkfile{math-frc}
+\loadmarkfile{math-scr}
+\loadmarkfile{math-int}
+\loadmarkfile{math-del}
+\loadmarkfile{math-inl}
+\loadmarkfile{math-dis}
+
+\loadcorefile{strc-mat.tex}
-%D Math.
+\loadmarkfile{chem-ini}
+\loadmarkfile{chem-str}
-\loadcorefile{math-pln.tex}
-\loadcorefile{math-ini.tex}
-\loadcorefile{math-ext.tex}
+\loadmarkfile{core-fnt}
-%D Now we're ready for more core modules.
+\loadcorefile{strc-not.tex}
-\loadcorefile{core-fnt.tex}
-\loadcorefile{core-not.tex}
\loadcorefile{core-lnt.tex}
-\loadcorefile{core-mis.tex}
+\loadmarkfile{core-mis}
\loadcorefile{core-trf.tex}
-\loadcorefile{core-inc.tex}
+\loadmarkfile{core-inc}
\loadcorefile{core-fig.tex}
-\loadcorefile{core-par.tex}
\loadcorefile{core-box.tex}
\loadcorefile{page-app.tex}
\loadmarkfile{meta-fig}
-%D Language specific spacing.
-
\loadcorefile{lang-spa.tex}
-%D Only the basic XML parser and remapper are part of the core.
-%D These macros are loaded last since they overload and|/|or
-%D extend previously defined ones.
-
-\loadmkivfile{lxml-ini.tex}
-
\loadcorefile{xtag-ini.tex}
\loadcorefile{xtag-ext.tex}
-\loadcorefile{xtag-prs.tex}
-\loadcorefile{xtag-map.tex}
-\loadcorefile{xtag-stk.tex}
\loadcorefile{xtag-exp.tex}
\loadcorefile{xtag-pre.tex}
\loadcorefile{xtag-xsd.tex}
\loadcorefile{xtag-rng.tex}
-%loadcorefile{xtag-ent.tex}
-
-%D How about this:
\loadcorefile{meta-xml.tex}
-%D \TEX\ related logo's are always typeset in a special way.
-%D Here they come:
-
\loadcorefile{cont-log.tex}
-%D This one overloads af few things:
+\loadcorefile{task-ini.tex}
-\loadcorefile{core-ctx.tex}
-
-%D Defaults go here (more will be moved to this module
-%D later):
+\loadmarkfile{core-ctx}
\loadcorefile{core-lme.tex}
\loadcorefile{core-ini.tex}
-\loadcorefile{core-def.tex}
-
-%D Preloaded modules (some need xml support):
+\loadmarkfile{core-def}
%usemodule[x][res-04] % xml resource libraries
%usemodule[x][res-08] % rlx runtime conversion
-\usemodule[x][res-12] % rli external indentification
-
-%D At run time, a few more files are loaded, like:
-%D
-%D \startitemize[packed]
-%D \item \type{cont-sys}: local (system dependant) defaults
-%D \item \type{cont-old}: substitutes for old (obsolete) macros
-%D \item \type{cont-new}: new macro implementations (for testing)
-%D \item \type{cont-fil}: filename and module synonyms
-%D \stopitemize
+% \usemodule[x][res-12] % rli external indentification
\unprotect
-\beginLUATEX
- \prependtoks
- \ctxlua{input.starttiming(ctx)}%
- \to \everyjob
- \appendtoks
- \ctxlua{input.stoptiming(ctx)}%
- \to \everyjob
- \appendtoks
- \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath())}}%
- \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}}%
- \to \everydump
-\endLUATEX
-
-\protect
-
-% %D Except from english, no hyphenation patterns are loaded
-% %D yet. Users can specify their needs in the next module:
-%
-% \input cont-usr.tex
+\prependtoks
+ \ctxlua{statistics.starttiming(ctx)}%
+\to \everyjob
+\appendtoks
+ \ctxlua{statistics.stoptiming(ctx)}%
+\to \everyjob
+\appendtoks
+ \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath())}}%
+ \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}}%
+\to \everydump
+
+\setupcurrentlanguage[\s!en]
+
+\appendtoks
+ \ctxlua {
+ statistics.report_storage("log")
+ statistics.save_fmt_status("\jobname","\contextversion","context.tex")
+ }%
+\to \everydump
+
+\setsystemmode{experimental} % test with *experimental
+
+\protect \errorstopmode \dump \endinput
diff --git a/tex/context/base/context.rme b/tex/context/base/context.rme
new file mode 100644
index 000000000..1b1e48902
--- /dev/null
+++ b/tex/context/base/context.rme
@@ -0,0 +1,85 @@
+Some Basic information
+----------------------
+
+There are currently three interfaces available:
+
+ cont-en the english version
+ cont-de the german version
+ cont-nl the dutch version
+ cont-cz the czech version
+ cont-ro the romanian version
+ cont-it the italian version
+
+One should compile one of these (or all) into a fmt file.
+When one uses the main file,
+
+ context the undefined version
+
+TeX ask for an interface language as well as a message
+language. Here one has to specify the full name (english,
+german, dutch, etc.) or use the default (enter). The \
+savest way to update the TeX and MetaPost format files
+is to use TeXExec:
+
+texexec --make --alone en nl metafun
+
+In the TeXExec manual you can read how to generate a format
+with specific fonts and patterns.
+
+By default only the english hyphenation patterns are loaded,
+unless more are enabled in:
+
+ cont-usr the typesetting language specifications
+
+Furthermore, users can preset commands etc in the file
+
+ cont-sys a system file loaded at runtime
+
+For questions and remarks on ConTeXt, one can subscribe to
+the list:
+
+ ntg-context@ntg.nl
+
+by sending the message
+
+ subscribe ntg-context
+
+to the list server:
+
+ majordomo@ntg.nl
+
+One can find more info at:
+
+ www.pragma-ade.com
+
+or at the mirror sites mentioned there.
+
+Don't hesitate to ask questions. ConTeXt can do a lot, and
+the manuals are always a bit behind and incomplete. Also take
+a look at the files
+
+ mreadme.pdf
+ minstall.pdf
+ mtexexec.pdf
+ mtexutil.pdf
+
+The teTeX, fpTeX, and 4TeX distributions demonstrate how
+ConTeXt can be integrated in a TeX directory structure.
+
+-------------------------
+
+functionality removed from mkiv:
+
+page-log : layers can do teh same and are more flexible
+core-dat : just use lua for database purposes
+core-swd : this was a temporary solution
+
+functionality changed in mkii and mkiv:
+
+xtag-map : no longer preloaded
+xtag-stk : no longer preloaded
+xtag-prs : no longer preloaded
+
+-------------------------
+
+Hans Hagen, pragma@wxs.nl
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 875779ef4..08ffc3a60 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -13,15 +13,6 @@
\catcode`\{=1 \catcode`\}=2 \catcode`\#=6
-%D For many years \CONTEXT\ supported both good old \TEX\ and \ETEX, but
-%D the time has come (August 2006) to advance, especially now that all
-%D engines provide \ETEX\ functionality and more is on the horizon.
-
-\ifx\eTeXversion\undefined
- \immediate\write16{SORRY CONTEXT NOW NEEDS ETEX}
- \expandafter \end
-\fi
-
%D From the next string (which is set by the script that assembles the
%D distribution) later on we will calculate a number that can be used
%D by use modules to identify the feature level. Starting with version
@@ -29,12 +20,12 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2008.10.31 13:58}
+\edef\contextversion{2009.05.28 11:23}
%D For those who want to use this:
-\def\fmtname {context}
-\def\fmtversion{3.1415926}
+\let\fmtname \contextformat
+\let\fmtversion\contextversion
\let\showcontextbanner\relax
diff --git a/tex/context/base/core-bar.tex b/tex/context/base/core-bar.tex
index 9b7acf17f..5b28afb9d 100644
--- a/tex/context/base/core-bar.tex
+++ b/tex/context/base/core-bar.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Plus Macros / Margin Bars etc}
+\writestatus{loading}{ConTeXt Core Macros / Margin Bars}
\unprotect
diff --git a/tex/context/base/core-blk.tex b/tex/context/base/core-blk.tex
index 8de1099e6..b224bf18e 100644
--- a/tex/context/base/core-blk.tex
+++ b/tex/context/base/core-blk.tex
@@ -13,135 +13,7 @@
% investigate etex's \readline and \scantokens
-\writestatus{loading}{Context Core Macros / Blockmoves}
-
-\startmessages dutch library: textblocks
- title: tekstblokken
- 1: nieuwe versie, tweede run nodig
- 2: wegschrijven blokken naar --
- 3: inlezen blokken uit --
- 4: er is een tweede run nodig
- 5: -- niet verborgen
- 6: -- verborgen en verwerkt
- 7: -- verborgen
- 8: -- gehandhaafd
- 9: -- niet gehandhaafd
- 10: -- geladen en verwerkt
- 11: -- geladen en geplaatst
- 12: -- overgeslagen
-\stopmessages
-
-\startmessages english library: textblocks
- title: textblocks
- 1: new version, second pass needed
- 2: writing blocks to --
- 3: reading blocks from --
- 4: second pass needed
- 5: -- not hidden
- 6: -- hidden and processed
- 7: -- hidden
- 8: -- typeset
- 9: -- not typeset
- 10: -- loaded and processed
- 11: -- loaded and typeset
- 12: -- skipped
-\stopmessages
-
-\startmessages german library: textblocks
- title: textblock
- 1: neue Version, zweiter Durchlauf benoetigt
- 2: schreibe Bloecke zu --
- 3: lese Bloecke von --
- 4: zweiter Durchlauf benoetigt
- 5: -- nicht verborgen
- 6: -- verborgen und verarbeitet
- 7: -- verborgen
- 8: -- gesetzt
- 9: -- nicht gesetzt
- 10: -- geladen und verarbeitet
- 11: -- geladen und gesetzt
- 12: -- ausgelassen
-\stopmessages
-
-\startmessages czech library: textblocks
- title: textovyblok
- 1: nova verze, je treba druhy beh
- 2: zapisuji bloky do --
- 3: ctu bloky z --
- 4: je treba druhy beh
- 5: -- neni skryto
- 6: -- skryto a zpracovano
- 7: -- skryto
- 8: -- vysazeno
- 9: -- nevysazeno
- 10: -- nacteno a zpracovano
- 11: -- nacteno a vysazeno
- 12: -- preskoceno
-\stopmessages
-
-\startmessages italian library: textblocks
- title: blocchi di testo
- 1: nuova versione, seconda passata necessaria
- 2: scrittura dei blocchi su --
- 3: lettura dei blocchi da --
- 4: seconda passata necessaria
- 5: -- non nascosto
- 6: -- nascosto ed elaborato
- 7: -- nascosto
- 8: -- composto
- 9: -- non composto
- 10: -- caricato ed elaborato
- 11: -- caricato e composto
- 12: -- saltato
-\stopmessages
-
-\startmessages norwegian library: textblocks
- title: tekstblokker
- 1: ny versjon, andre gjennomkjøring nødvendig
- 2: skriver blokker til --
- 3: leser blokker fra --
- 4: andre gjennomkjøring nødvendig
- 5: -- ikke skjult
- 6: -- skjult og behandlet
- 7: -- skjult
- 8: -- tegnsatt
- 9: -- ikke tegnsatt
- 10: -- lest inn og behandlet
- 11: -- lest inn og tegnsatt
- 12: -- utelatt
-\stopmessages
-
-\startmessages romanian library: textblocks
- title: blocuri de text
- 1: o noua versiune, este nevoie de inca o trecere
- 2: se scriu blocurile in --
- 3: se citesc blocurile din --
- 4: este nevoie de inca o trecere
- 5: -- nu este ascuns
- 6: -- ascuns si procesat
- 7: -- ascuns
- 8: -- cules
- 9: -- nu este cules
- 10: -- incarcat si procesat
- 11: -- incarcat si cules
- 12: -- sarit peste
-\stopmessages
-
-\startmessages french library: textblocks
- title: blocs de texte
- 1: nouvelle version, une seconde passe est nécessaire
- 2: ecriture des blocs vers --
- 3: lecture des blocs en provenance de --
- 4: seconde passe nécessaire
- 5: -- non caché
- 6: -- caché et traité
- 7: -- caché
- 8: -- composé
- 9: -- non composé
- 10: -- chargé et traité
- 11: -- chargé et composé
- 12: -- sauté
-\stopmessages
+\writestatus{loading}{ConTeXt Core Macros / Blockmoves}
\unprotect
diff --git a/tex/context/base/core-box.tex b/tex/context/base/core-box.tex
index bbcfe451d..97811e78f 100644
--- a/tex/context/base/core-box.tex
+++ b/tex/context/base/core-box.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Boxes}
+\writestatus{loading}{ConTeXt Core Macros / Boxes}
%D This module contains all kind of macros for moving content
%D around. Many macros here come from other modules, but
@@ -274,7 +274,6 @@
\global\ht\collectorbox\scratchdimen
\egroup}
-
%\definecollector[test]
%\setcollector[test]
% [location=rb]
diff --git a/tex/context/base/core-buf.lua b/tex/context/base/core-buf.lua
index a43c33054..389ebde35 100644
--- a/tex/context/base/core-buf.lua
+++ b/tex/context/base/core-buf.lua
@@ -1,17 +1,17 @@
--- filename : core-buf.lua
--- comment : companion to core-buf.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['core-buf'] = {
+ version = 1.001,
+ comment = "companion to core-buf.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-- ctx lua reference model / hooks and such
-- to be optimized
-- redefine buffers.get
-if not versions then versions = { } end versions['core-buf'] = 1.001
-
-if unicode and not utf then utf = unicode.utf8 end
+utf = unicode.utf8
buffers = { }
buffers.data = { }
@@ -22,9 +22,15 @@ buffers.visualizers = { }
-- if needed we can make 'm local
+local utf = unicode.utf8
+
local concat, texsprint, texprint, texwrite = table.concat, tex.sprint, tex.print, tex.write
local utfbyte, utffind, utfgsub = utf.byte, utf.find, utf.gsub
-local byte, sub, find, char, gsub, rep = string.byte, string.sub, string.find, string.char, string.gsub, string.rep
+local byte, sub, find, char, gsub, rep, lower = string.byte, string.sub, string.find, string.char, string.gsub, string.rep, string.lower
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+
+local vrbcatcodes = tex.vrbcatcodes
+local ctxcatcodes = tex.ctxcatcodes
local data, commands, flags, hooks, visualizers = buffers.data, buffers.commands, buffers.flags, buffers.hooks, buffers.visualizers
@@ -132,31 +138,19 @@ function buffers.type(name)
end
end
---~ function buffers.typefile(name) -- keep this one, uses tex reader
---~ local t = input.openfile(name)
---~ local action = buffers.typeline
---~ if t then
---~ local lines = { }
---~ while true do
---~ local str = t.reader()
---~ if str then
---~ lines[#lines+1] = str
---~ else
---~ break
---~ end
---~ end
---~ t.close()
---~ local line, n = 0, 0
---~ local first, last, m = buffers.strip(lines)
---~ for i=first,last do
---~ n, line = action(lines[i], n, m, line)
---~ end
---~ end
---~ end
-
-function buffers.typefile(name)
- local str = io.loaddata(name)
- if str then
+function buffers.loaddata(filename) -- this one might go away
+ -- this will be cleaned up when we have split supp-fil completely
+ -- instead of half-half
+ local ok, str, n = resolvers.loaders.tex(filename)
+ if not str then
+ ok, str, n = resolvers.loaders.tex(file.addsuffix(filename,'tex'))
+ end
+ return str or ""
+end
+
+function buffers.typefile(name) -- still somewhat messy, since name can be be suffixless
+ local str = buffers.loaddata(name)
+ if str and str~= "" then
local lines = str:splitlines()
local line, n, action = 0, 0, buffers.typeline
local first, last, m = buffers.strip(lines)
@@ -192,21 +186,6 @@ function buffers.save(name)
io.savedata(f,b)
end
--- todo, use more locals
-
---~ function buffers.get(name)
---~ local b = data[name]
---~ if b then
---~ if type(b) == "table" then
---~ for i=1,#b do
---~ texprint(b[i])
---~ end
---~ else
---~ string.piecewise(b, " *[\010\013]", texprint) -- hm, can be faster
---~ end
---~ end
---~ end
-
local printer = (lpeg.linebyline/texprint)^0
function buffers.get(name)
@@ -217,17 +196,16 @@ function buffers.get(name)
texprint(b[i])
end
else
- -- b:piecewise(" *[\010\013]", texprint) -- hm, can be faster
printer:match(b)
end
end
end
-function buffers.content(name) -- no print
+local function content(name,separator) -- no print
local b = data[name]
if b then
if type(b) == "table" then
- return concat(b," ")
+ return concat(b,separator or "\n")
else
return b
end
@@ -236,24 +214,30 @@ function buffers.content(name) -- no print
end
end
+buffers.content = content
+
function buffers.collect(names,separator) -- no print
local t = { }
if type(names) == "table" then
for i=1,#names do
- local c = buffers.content(names[i])
+ local c = content(names[i],separator)
if c ~= "" then
t[#t+1] = c
end
end
else
for name in names:gmatch("[^,]+") do
- local c = buffers.content(name)
+ local c = content(name,separator)
if c ~= "" then
t[#t+1] = c
end
end
end
- return concat(t,separator or " ") -- maybe this will change to "\n"
+ return concat(t,separator or "\n") -- "\n" is safer due to comments and such
+end
+
+local function tobyte(c)
+ return " [" .. byte(c) .. "] "
end
function buffers.inspect(name)
@@ -262,17 +246,13 @@ function buffers.inspect(name)
if type(b) == "table" then
for _,v in ipairs(b) do
if v == "" then
- texsprint(tex.ctxcatcodes,"[crlf]\\par ")
+ texsprint(ctxcatcodes,"[crlf]\\par ") -- space ?
else
- texsprint(tex.ctxcatcodes,(b:gsub("(.)",function(c)
- return " [" .. byte(c) .. "] "
- end)) .. "\\par")
+ texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte)),"\\par")
end
end
else
- texsprint(tex.ctxcatcodes,(b:gsub("(.)",function(c)
- return " [" .. byte(c) .. "] "
- end)))
+ texsprint(ctxcatcodes,(gsub(b,"(.)",tobyte)))
end
end
end
@@ -286,7 +266,7 @@ visualizers.mp = { }
visualizers.escapetoken = nil
visualizers.tablength = 7
-visualizers.enabletab = false
+visualizers.enabletab = true -- false
visualizers.enableescape = false
visualizers.obeyspace = true
@@ -299,19 +279,18 @@ end
buffers.currentvisualizer = 'default'
function buffers.setvisualizer(str)
- buffers.currentvisualizer = str:lower()
+ buffers.currentvisualizer = lower(str)
if not visualizers[buffers.currentvisualizer] then
buffers.currentvisualizer = 'default'
end
end
function buffers.doifelsevisualizer(str)
- cs.testcase((str ~= "") and (visualizers[str:lower()] ~= nil))
+ cs.testcase((str ~= "") and (visualizers[lower(str)] ~= nil))
end
-- calling routines, don't change
-
function hooks.flush_line(str,nesting)
str = str:gsub(" *[\n\r]+ *"," ")
local flush_line = visualizers[buffers.currentvisualizer].flush_line
@@ -350,7 +329,12 @@ function hooks.empty_line()
end
function hooks.line(str)
- local empty_line = visualizers[buffers.currentvisualizer].line
+ local line = visualizers[buffers.currentvisualizer].line
+ if visualizers.enabletab then
+ str = string.tabtospace(str,visualizers.tablength)
+ else
+ str = gsub(str,"\t"," ")
+ end
if line then
return line(str)
else
@@ -361,19 +345,19 @@ end
-- defaults
function visualizers.default.flush_line(str)
- texsprint(tex.ctxcatcodes,buffers.escaped(str))
+ texsprint(ctxcatcodes,buffers.escaped(str))
end
function visualizers.default.begin_of_line(n)
- texsprint(tex.ctxcatcodes, commands.begin_of_line_command .. "{" .. n .. "}")
+ texsprint(ctxcatcodes, commands.begin_of_line_command,"{",n,"}")
end
function visualizers.default.end_of_line()
- texsprint(tex.ctxcatcodes,commands.end_of_line_command)
+ texsprint(ctxcatcodes,commands.end_of_line_command)
end
function visualizers.default.empty_line()
- texsprint(tex.ctxcatcodes,commands.empty_line_command)
+ texsprint(ctxcatcodes,commands.empty_line_command)
end
function visualizers.default.line(str)
@@ -418,7 +402,7 @@ function visualizers.flush_nested(str, enable) -- no utf, kind of obsolete mess
end
end
result = result .. "\\char" .. byte(sub(str,i,i)) .. " " .. string.rep("}",nested)
- texsprint(tex.ctxcatcodes,result)
+ texsprint(ctxcatcodes,result)
end
-- handy helpers
@@ -461,14 +445,16 @@ buffers.open_nested = rep("\\char"..byte('<').." ",2)
buffers.close_nested = rep("\\char"..byte('>').." ",2)
function buffers.replace_nested(result)
- return (gsub(result:gsub(buffers.open_nested,"{"),buffers.close_nested,"}"))
+ result = gsub(result,buffers.open_nested, "{")
+ result = gsub(result,buffers.close_nested,"}")
+ return result
end
function buffers.flush_result(result,nested)
if nested then
- texsprint(tex.ctxcatcodes,buffers.replace_nested(concat(result,"")))
+ texsprint(ctxcatcodes,buffers.replace_nested(concat(result,"")))
else
- texsprint(tex.ctxcatcodes,concat(result,""))
+ texsprint(ctxcatcodes,concat(result,""))
end
end
@@ -489,15 +475,6 @@ function buffers.escaped(str)
return (utfgsub(str,"(.)", escaped_token))
end
---~ function buffers.escaped_chr(ch)
---~ local b = utfbyte(ch)
---~ if b == 32 then
---~ return "\\obs "
---~ else
---~ return "\\char" .. b .. " "
---~ end
---~ end
-
function buffers.escaped_chr(ch)
if ch == " " then
return "\\obs "
@@ -506,58 +483,17 @@ function buffers.escaped_chr(ch)
end
end
--- redone
-
---~ function visualizers.default.flush_line(str)
---~ local tc = tex.ctxcatcodes
---~ for u in str:utfcharacters() do
---~ texsprint(tc,escaped_token(u))
---~ end
---~ end
-
---~ local a, z, A, Z, zero, nine = byte("a"), byte("z"), byte("A"), byte("Z"), byte("0"), byte("9")
-
---~ function visualizers.default.flush_line(str)
---~ local tc = tex.ctxcatcodes
---~ for b in str:utfvalues() do
---~ if (b>=a and b<=z) or (b>=A and b<=Z) or (b>=zero and b<=nine) then
---~ texsprint(tc,char(b))
---~ elseif b == 32 then
---~ texsprint(tc,"\\obs ")
---~ else
---~ texsprint(tc,"\\char",b," ")
---~ end
---~ end
---~ end
-
---~ function visualizers.default.flush_line(str)
---~ local tc = tex.ctxcatcodes
---~ local vc = tex.vrbcatcodes
---~ local vs = visualizers.obeyspace
---~ for ch in str:utfcharacters() do
---~ if ch == "{" or ch == "}" then
---~ texsprint(tc,"\\char",ch:byte()," ")
---~ elseif vs and ch == " " then
---~ texsprint(tc,"\\obs ")
---~ else
---~ texsprint(vc,ch)
---~ end
---~ end
---~ end
-
function visualizers.default.flush_line(str)
str = str:gsub(" *[\n\r]+ *"," ")
- local vc = tex.vrbcatcodes
if visualizers.obeyspace then
- local tc = tex.ctxcatcodes
- for c in str:utfcharacters() do
+ for c in utfcharacters(str) do
if c == " " then
- texsprint(tc,"\\obs ")
+ texsprint(ctxcatcodes,"\\obs ")
else
- texsprint(vc,c)
+ texsprint(vrbcatcodes,c)
end
end
else
- texsprint(vc,str)
+ texsprint(vrbcatcodes,str)
end
end
diff --git a/tex/context/base/core-buf.mkii b/tex/context/base/core-buf.mkii
index 206992e9b..9937fae01 100644
--- a/tex/context/base/core-buf.mkii
+++ b/tex/context/base/core-buf.mkii
@@ -11,69 +11,14 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
-
-\def\mkresetbuffer
- {\unlinkfile{\TEXbufferfile\currentbuffer}}
-
-\long\def\mksetbuffer#1%
- {\edef\bufferfilename{\TEXbufferfile{\currentbuffer}}%
- \immediate\openout\tmpblocks\bufferfilename
- \defconvertedargument\ascii{#1}%
- \immediate\write\tmpblocks{\ascii}%
- \immediate\closeout\tmpblocks}
-
-\def\mkstartbuffer#1#2#3#4#5% ook grabben a la mkiv / no, we need to add par anchors
- {\doifelsenothing{#4}
- {\letbeundefined{\e!stop\v!buffer}% % \let\stopbuffer=\relax % \undefined
- \edefconvertedargument\beginofblock{\e!start\v!buffer}%
- \edefconvertedargument\endofblock {\e!stop \v!buffer}%
- \ifcase\buffernestmode
- \let\processnextbufferline\processnextbufferlineB
- \else
- \let\processnextbufferline\processnextbufferlineA
- \fi}
- {\letbeundefined{#4}% \letvalue{#4}=\relax % \undefined
- \@EA\defconvertedargument\@EA\beginofblock\@EA{\csname#3\endcsname}% we could use defconvertedcommand here (no \@EA)
- \@EA\defconvertedargument\@EA\endofblock \@EA{\csname#4\endcsname}% we could use defconvertedcommand here (no \@EA)
- \ifcase\buffernestmode
- \let\processnextbufferline\processnextbufferlineB
- \or
- \let\processnextbufferline\processnextbufferlineB
- \else
- \let\processnextbufferline\processnextbufferlineA
- \fi}%
- \def\closebufferfile
- {\ifsegmentatebuffer
- \immediate\write\tmpblocks{\string\stopbufferparagraph}%
- \fi
- \immediate\closeout\tmpblocks
- #5% \egroup
- \getvalue{#4}}%
- \doifelsenothing{#2}
- {\edef\bufferfilename{\TEXbufferfile\jobname}}%
- {\edef\bufferfilename{\TEXbufferfile{#2}}}%
- \immediate\openout\tmpblocks\bufferfilename
- \ifsegmentatebuffer
- \immediate\write\tmpblocks{\string\startbufferparagraph}%
- \fi
- \newcounter\nestedbufferlevel
- \recatcodeuppercharacterstrue
- \setcatcodetable\vrbcatcodes
- \obeylines
- \copybufferline}
+\writestatus{loading}{ConTeXt Core Macros / Buffers}
-\def\mkdobuffer#1% command
- {\beginrestorecatcodes
- #1%
- \endrestorecatcodes}
+\unprotect
-\def\mkgetbuffer {\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing}
-\def\mktypebuffer{\typefile{\TEXbufferfile{\currentbuffer}}}
+% Helpers:
-% support macros
+\chardef\buffernestmode\plusone % 0: not nested, 1: startbuffer nested, 2: all buffers nested
-% \expandafter \convertargument \gobbleoneargument @ \to \emptybufferline
\edefconvertedargument\emptybufferline{ }
\ifx\tmpblocks\undefined \newwrite\tmpblocks \fi
@@ -133,12 +78,271 @@
{\processnextbufferline{#1}\closebufferfile{\flushbufferline{#1}\copybufferline}}
\egroup
-% kind of obsolete with mkiv
+\newif\ifsegmentatebuffer
+\newif\ifemptybufferline
+
+\def\currentbuffer{\jobname}
-\def\mkstartmemorybuffer
+\def\setcurrentbuffer#1%
+ {\doifelsenothing{#1}{\edef\currentbuffer{\jobname}}{\edef\currentbuffer{#1}}}
+
+\def\resetbuffer
+ {\dosingleempty\doresetbuffer}
+
+\def\doresetbuffer[#1]%
+ {\begingroup
+ \setcurrentbuffer{#1}%
+ \unlinkfile{\TEXbufferfile\currentbuffer}%
+ \endgroup}
+
+\def\dostartbuffer
+ {\bgroup
+ \obeylines % nodig, anders gaat 't fout als direct \starttable (bv)
+ \doquadrupleempty\dodostartbuffer}
+
+\def\dodostartbuffer[#1][#2][#3][#4]% upward compatible
+ {\iffourthargument
+ \def\next{\dododostartbuffer{#1}{#2}{#3}{#4}}%
+ \else
+ \def\next{\dododostartbuffer {}{#1}{#2}{#3}}%
+ \fi
+ \next}
+
+\def\dododostartbuffer#1#2#3#4%
+ {%\showmessage\m!systems{15}{#2}%
+ \doifelsevalue{\??bu#1\c!paragraph}\v!yes
+ {\segmentatebuffertrue} % todo in mkiv
+ {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}}\segmentatebuffertrue\segmentatebufferfalse}%
+ \doifvalue{\??bu#1\c!local}\v!yes
+ {\chardef\buffernestmode\plustwo}% permit nesting
+ \setcurrentbuffer{#2}%
+ \doifelsenothing{#4}
+ {\letbeundefined{\e!stop\v!buffer}% % \let\stopbuffer=\relax % \undefined
+ \edefconvertedargument\beginofblock{\e!start\v!buffer}%
+ \edefconvertedargument\endofblock {\e!stop \v!buffer}%
+ \ifcase\buffernestmode
+ \let\processnextbufferline\processnextbufferlineB
+ \else
+ \let\processnextbufferline\processnextbufferlineA
+ \fi}
+ {\letbeundefined{#4}% \letvalue{#4}=\relax % \undefined
+ \@EA\defconvertedargument\@EA\beginofblock\@EA{\csname#3\endcsname}% we could use defconvertedcommand here (no \@EA)
+ \@EA\defconvertedargument\@EA\endofblock \@EA{\csname#4\endcsname}% we could use defconvertedcommand here (no \@EA)
+ \ifcase\buffernestmode
+ \let\processnextbufferline\processnextbufferlineB
+ \or
+ \let\processnextbufferline\processnextbufferlineB
+ \else
+ \let\processnextbufferline\processnextbufferlineA
+ \fi}%
+ \def\closebufferfile
+ {\ifsegmentatebuffer
+ \immediate\write\tmpblocks{\string\stopbufferparagraph}%
+ \fi
+ \immediate\closeout\tmpblocks
+ \egroup
+ \getvalue{#4}}%
+ \doifelsenothing{#2}
+ {\edef\bufferfilename{\TEXbufferfile\jobname}}%
+ {\edef\bufferfilename{\TEXbufferfile{#2}}}%
+ \immediate\openout\tmpblocks\bufferfilename
+ \ifsegmentatebuffer
+ \immediate\write\tmpblocks{\string\startbufferparagraph}%
+ \fi
+ \newcounter\nestedbufferlevel
+ \recatcodeuppercharacterstrue
+ \setcatcodetable\vrbcatcodes
+ \obeylines
+ \copybufferline}
+
+\letvalue{\e!start\v!buffer}\dostartbuffer
+
+\let\endbuffer\undefined % to please the dep parser
+
+\def\setbuffer
+ {\dosingleempty\dosetbuffer}
+
+\long\def\dosetbuffer[#1]#2\endbuffer % seldom used so we just pass #2
+ {\begingroup
+ \setcurrentbuffer{#1}%
+ \edef\bufferfilename{\TEXbufferfile{\currentbuffer}}%
+ \immediate\openout\tmpblocks\bufferfilename
+ \defconvertedargument\ascii{#2}%
+ \immediate\write\tmpblocks{\ascii}%
+ \immediate\closeout\tmpblocks
+ \endgroup}
+
+\def\setupbuffer
+ {\dodoubleempty\dosetupbuffer}
+
+\def\dosetupbuffer[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??bu#1][#2]%
+ \else
+ \getparameters[\??bu][#1]%
+ \fi}
+
+\def\dodefinebuffer[#1][#2]%
+ {\iffirstargument % else problems
+ \doglobal\increment\nofdefinedbuffers
+ \letvalue{\??bu#1\c!number }\nofdefinedbuffers
+ \letvalue{\??bu#1\c!paragraph}\v!no
+ \setevalue{\e!start#1}{\noexpand\dostartbuffer[#1][def-\nofdefinedbuffers][\e!start#1][\e!stop#1]}%
+ \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}%
+ \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}%
+ \getparameters[\??bu#1][#2]%
+ \fi}
+
+\def\definebuffer
+ {\dodoubleempty\dodefinebuffer}
+
+\def\getbuffer
+ {\dodoubleempty\dogetbuffer}
+
+\def\dogetbuffer[#1][#2]%
+ {\ifsecondargument
+ \dodogetbuffer[#1][#2]%
+ \else
+ \dodogetbuffer[][#1]%
+ \fi}
+
+\def\dogetbufferasis{\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing}%
+
+\def\dodogetbuffer[#1][#2]%
+ {\getvalue{\??bu#1\c!before}%
+ \dobuffer{16}{#2}\dogetbufferasis
+ \getvalue{\??bu#1\c!after}}
+
+\def\typebuffer
+ {\dodoubleempty\dotypebuffer}
+
+\def\dogetfilebuffer{\typefile{\TEXbufferfile{\currentbuffer}}}
+
+\def\dotypebuffer[#1][#2]%
+ {\iffirstargument
+ \dobuffer{17}{#1}\dogetfilebuffer
+ \else
+ \dobuffer{17}{#2}\dogetfilebuffer
+ \fi}
+
+\def\dobuffer#1#2#3%
+ {\doifelsenothing{#2}
+ {\dodobuffer#3\jobname}
+ {\processcommalist[#2]{\dodobuffer#3}}}
+
+\def\dodobuffer#1#2% command name
+ {\pushmacro\currentbuffer
+ \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}%
+ \beginrestorecatcodes
+ #1%
+ \endrestorecatcodes
+ \popmacro\currentbuffer}
+
+\def\processTEXbuffer{\getbuffer} % handy
+
+% seldom used, only in a few projects that demanded more speed
+
+\def\dostartmemorybuffer
{\dosingleempty\dostartmemorybuffer}
\long\def\dostartmemorybuffer[#1]#2\stopbuffer
{\setbuffer[#1]#2\endbuffer}
+\let\dostartfilebuffer\startbuffer
+
+\def\usememorybuffers{\let\startbuffer\dostartmemorybuffer}
+\def\usefilebuffers {\let\startbuffer\dostartfilebuffer}
+
+% this features is soldom used (complex examns where we need to fetch
+% special parts of a text
+%
+% this is not yet supported in mkiv (relatively easy to do but there
+% we don't have the par tags but need to grab 'm
+
+\def\skippedbufferparagraphs{0}
+
+\let\startbufferparagraph\relax
+\let\stopbufferparagraph \par % \relax
+
+\newcount\currentbufferparagraph
+
+\def\getbufferparagraphs
+ {\dodoubleempty\dogetbufferparagraphs}
+
+\def\dosetbufferoffset#1%
+ {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}}
+ {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}}
+ {\currentbufferparagraph \zerocount}%
+ \relax}
+
+\def\dogetbufferparagraphs[#1][#2]%
+ {\iffirstargument
+ \ifsecondargument
+ \dosetbufferoffset{#1}%
+ \doifelse{#2}\v!all
+ {\def\startbufferparagraph{\normalbufferparagraph{#1}}}
+ {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}%
+ \def\stopbufferparagraph{\dostopbufferparagraph{#1}}%
+ \def\next{\getparagraphedbuffer[#1]}%
+ \else
+ \dosetbufferoffset\empty
+ \def\startbufferparagraph{\filterbufferparagraph{}{#1}}%
+ \def\stopbufferparagraph{\dostopbufferparagraph{}}%
+ \def\next{\getparagraphedbuffer[]}%
+ \fi
+ \else
+ \dosetbufferoffset\empty
+ \def\startbufferparagraph{\normalbufferparagraph{}}%
+ \def\stopbufferparagraph{\dostopbufferparagraph{}}%
+ \def\next{\getparagraphedbuffer[]}%
+ \fi
+ \next}
+
+\def\dogetparagraphbuffer{\readjobfile{\TEXbufferfile{\currentbuffer}}\donothing\donothing}
+
+\def\getparagraphedbuffer[#1]%
+ {\dobuffer{16}{#1}\dogetparagraphbuffer}
+
+\def\dostopbufferparagraph#1%
+ {\getvalue{\??bu#1\c!after}\par}
+
+\def\dostartbufferparagraph#1%
+ {\par\getvalue{\??bu#1\c!before}}
+
+\def\normalbufferparagraph
+ {\advance\currentbufferparagraph \plusone
+ \ifnum\currentbufferparagraph>\zerocount
+ \expandafter\dostartbufferparagraph
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\filterbufferparagraph#1#2%
+ {\advance\currentbufferparagraph \plusone
+ \ifcase\currentbufferparagraph
+ \@EA\gobblebufferparagraph
+ \else
+ \doifinsetelse{\the\currentbufferparagraph}{#2}
+ {\@EA\dostartbufferparagraph}
+ {\@EA\fakebufferparagraph}%
+ \fi
+ {#1}}
+
+\long\def\gobblebufferparagraph#1#2\stopbufferparagraph
+ {}
+
+\def\fakebufferparagraph#1%
+ {\bgroup
+ \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}%
+ \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}}
+
+% definitions
+
+\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes]
+
+\setupbuffer
+ [\c!paragraph=\v!no,
+ \c!before=,
+ \c!after=]
+
\protect \endinput
diff --git a/tex/context/base/core-buf.mkiv b/tex/context/base/core-buf.mkiv
index c4f13839d..8b69616b9 100644
--- a/tex/context/base/core-buf.mkiv
+++ b/tex/context/base/core-buf.mkiv
@@ -11,75 +11,80 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% this will become a proper new verbatim module
+\writestatus{loading}{ConTeXt Core Macros / Buffers}
+
+\registerctxluafile{core-buf}{1.001}
+
+\ifdefined\doinitializeverbatim \else% temp hack
+ \ifdefined\mkinitializeverbatim
+ \let\doinitializeverbatim\mkinitializeverbatim
+ \else
+ \def\doinitializeverbatim{\tttf}
+ \fi
+\fi
\unprotect
-\registerctxluafile{core-buf}{1.001}
+\chardef\buffernestmode\plusone % 0: not nested, 1: startbuffer nested, 2: all buffers nested
+
+\newif\ifsegmentatebuffer
+\newif\ifemptybufferline
-\def\mkresetbuffer
- {\ctxlua{buffers.erase("\currentbuffer")}}
+\def\currentbuffer{\jobname}
-\long\def\mksetbuffer#1%
- {\ctxlua{buffers.set("\currentbuffer", \!!bs\detokenize{#1}\!!es)}}
+\def\setcurrentbuffer#1%
+ {\doifelsenothing{#1}{\edef\currentbuffer{\jobname}}{\edef\currentbuffer{#1}}}
-\long\def\mkstartbuffer#1#2#3#4#5%
- {\doifelsenothing{#4}
- {\expanded{\setbuffercapsules{\e!start\v!buffer}{\e!stop\v!buffer}}%
+\def\resetbuffer
+ {\dosingleempty\doresetbuffer}
+
+\def\doresetbuffer[#1]%
+ {\begingroup
+ \setcurrentbuffer{#1}%
+ \ctxlua{buffers.erase("\currentbuffer")}%
+ \endgroup}
+
+\def\dostartbuffer
+ {\bgroup
+ \obeylines % nodig, anders gaat 't fout als direct \starttable (bv)
+ \doquadrupleempty\dodostartbuffer}
+
+\def\dodostartbuffer[#1][#2][#3][#4]% upward compatible
+ {\iffourthargument
+ \def\next{\dododostartbuffer{#1}{#2}{#3}{#4}}%
+ \else
+ \def\next{\dododostartbuffer {}{#1}{#2}{#3}}%
+ \fi
+ \next}
+
+\def\dododostartbuffer#1#2#3#4%
+ {%\showmessage\m!systems{15}{#2}%
+ \doifelsevalue{\??bu#1\c!paragraph}\v!yes
+ {\segmentatebuffertrue} % todo in mkiv
+ {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}}\segmentatebuffertrue\segmentatebufferfalse}%
+ \doifvalue{\??bu#1\c!local}\v!yes
+ {\chardef\buffernestmode\plustwo}% permit nesting
+ \setcurrentbuffer{#2}%
+ \doifelsenothing{#4}
+ {\normalexpanded{\noexpand\setbuffercapsules{\e!start\v!buffer}{\e!stop\v!buffer}}%
\letvalue\bufferstop\relax}
%{\@EA\setbuffercapsules\@EA{\csname#3\@EA\endcsname\@EA}\@EA{\csname#4\endcsname}}% if we strip later
{\setbuffercapsules{#3}{#4}}%
- \expanded{\dodowithbuffer
+ \normalexpanded{\noexpand\dodowithbuffer
{\currentbuffer}
{\bufferstart}
{\bufferstop}
{\donothing}
- {#5% \egroup
+ {\egroup
\noexpand\getvalue{\bufferstop}}}}
-\def\mkdobuffer#1%
- {#1}
-
-\def\mkdoifelsebuffer#1%
- {\ctxlua{buffers.doifelsebuffer("#1")}}
-
-\def\mkgetbuffer
- {\ctxlua{buffers.get("\currentbuffer")}}
-
-% will move
-
-\ifx\mkinitializeverbatim\undefined \def\mkinitializeverbatim{\tttf} \fi
-
-\def\mktypebuffer
- {\mkdotypebuffer{\v!file}{}{\currentbuffer}}
-
-\def\mkprocessbufferverbatim
- {\mkinitializeverbatim
- \ctxlua{buffers.type("\currentbuffer")}}
-
-\def\mkprocessbufferlinesverbatim#1#2#3%
- {#2%
- % todo, set up numbers
- \mkinitializeverbatim
- \ctxlua{buffers.type("\currentbuffer")}
- #3}
-
-\def\mkdotypebuffer#1#2#3% see dodotypefile
- {\mkdoifelsebuffer{#3}
- {\dosometyping{#1}{#2}{#3}\mkprocessbufferverbatim\mkprocessbufferlinesverbatim}
- {\reporttypingerror{#3}}}
-
-% \def\setbuffercapsules#1#2%
-% {\edef\bufferstart{\strippedcsname#1}\edef\bufferstart{\scantextokens\expandafter{\bufferstart}}%
-% \edef\bufferstop {\strippedcsname#2}\edef\bufferstop {\scantextokens\expandafter{\bufferstop }}}
+\letvalue{\e!start\v!buffer}\dostartbuffer
-\def\setbuffercapsules#1#2% \scantextokens not needed (had a reason at some point)
- {\edef\bufferstart{#1}\edef\bufferstart{\scantextokens\expandafter{\bufferstart}}%
- \edef\bufferstop {#2}\edef\bufferstop {\scantextokens\expandafter{\bufferstop }}}
+\let\endbuffer\undefined % to please the dep parser
\def\dowithbuffer#1#2#3% name, startsequence, stopsequence, before, after
{\setbuffercapsules{#2}{#3}%
- \expanded{\dodowithbuffer{#1}{\bufferstart}{\bufferstop}}}
+ \normalexpanded{\noexpand\dodowithbuffer{#1}{\bufferstart}{\bufferstop}}}
\long\def\dodowithbuffer#1#2#3#4#5% name, startsequence, stopsequence, before, after
{#4%
@@ -97,12 +102,105 @@
\nododowithbuffer}%
\dododowithbuffer}
-% kind of redundant in mkiv
+\def\setbuffercapsules#1#2% \scantextokens not needed (had a reason at some point)
+ {\edef\bufferstart{#1}\edef\bufferstart{\scantextokens\expandafter{\bufferstart}}%
+ \edef\bufferstop {#2}\edef\bufferstop {\scantextokens\expandafter{\bufferstop }}}
+
+\def\setbuffer
+ {\dosingleempty\dosetbuffer}
+
+\long\def\dosetbuffer[#1]#2\endbuffer % seldom used so we just pass #2
+ {\begingroup
+ \setcurrentbuffer{#1}%
+ \ctxlua{buffers.set("\currentbuffer", \!!bs\detokenize{#2}\!!es)}%
+ \endgroup}
+
+\def\setupbuffer
+ {\dodoubleempty\dosetupbuffer}
+
+\def\dosetupbuffer[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??bu#1][#2]%
+ \else
+ \getparameters[\??bu][#1]%
+ \fi}
+
+\def\dodefinebuffer[#1][#2]%
+ {\iffirstargument % else problems
+ \doglobal\increment\nofdefinedbuffers
+ \letvalue{\??bu#1\c!number }\nofdefinedbuffers
+ \letvalue{\??bu#1\c!paragraph}\v!no
+ \setevalue{\e!start#1}{\noexpand\dostartbuffer[#1][def-\nofdefinedbuffers][\e!start#1][\e!stop#1]}%
+ \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}%
+ \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}%
+ \getparameters[\??bu#1][#2]%
+ \fi}
+
+\def\definebuffer
+ {\dodoubleempty\dodefinebuffer}
+
+\def\getbuffer
+ {\dodoubleempty\dogetbuffer}
+
+\def\dogetbuffer[#1][#2]%
+ {\ifsecondargument
+ \dodogetbuffer[#1][#2]%
+ \else
+ \dodogetbuffer[][#1]%
+ \fi}
-\let\mkstartmemorybuffer\startbuffer
-\let\mkstartfilebuffer \startbuffer
+\def\dogetbufferasis{\ctxlua{buffers.get("\currentbuffer")}}
-% bonus
+\def\dodogetbuffer[#1][#2]%
+ {\getvalue{\??bu#1\c!before}%
+ \dobuffer{16}{#2}\dogetbufferasis
+ \getvalue{\??bu#1\c!after}}
+
+\def\typebuffer
+ {\dodoubleempty\dotypebuffer}
+
+\def\doprocessbufferverbatim
+ {\doinitializeverbatim
+ \ctxlua{buffers.type("\currentbuffer")}}
+
+\def\doprocessbufferlinesverbatim#1#2#3%
+ {#2%
+ % todo, set up numbers
+ \doinitializeverbatim
+ \ctxlua{buffers.type("\currentbuffer")}
+ #3}
+
+\def\doifelsebuffer#1%
+ {\ctxlua{buffers.doifelsebuffer("#1")}}
+
+\def\dodotypebuffer#1#2#3% see dodotypefile
+ {\doifelsebuffer{#3}
+ {\dosometyping{#1}{#2}{#3}\doprocessbufferverbatim\doprocessbufferlinesverbatim}
+ {\reporttypingerror{#3}}}
+
+\def\dotypefilebuffer{\dodotypebuffer{\v!file}{}{\currentbuffer}}%
+
+\def\dotypebuffer[#1][#2]%
+ {\iffirstargument
+ \dobuffer{17}{#1}\dotypefilebuffer
+ \else
+ \dobuffer{17}{#2}\dotypefilebuffer
+ \fi}
+
+\def\dobuffer#1#2#3%
+ {\doifelsenothing{#2}
+ {\dodobuffer#3\jobname}
+ {\processcommalist[#2]{\dodobuffer#3}}}
+
+\def\dodobuffer#1#2% command name
+ {\pushmacro\currentbuffer
+ \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}%
+ #1%
+ \popmacro\currentbuffer}
+
+\def\processTEXbuffer{\getbuffer} % handy
+
+% extras:
\def\inspectbuffer
{\dosingleempty\doinspectbuffer}
@@ -110,5 +208,107 @@
\def\doinspectbuffer[#1]%
{\setcurrentbuffer{#1}%
\ctxlua{buffers.inspect("\currentbuffer")}}
+
+% seldom used, only in a few projects that demanded more speed
+
+\let\usememorybuffers\relax
+\let\usefilebuffers \relax
+
+% this features is soldom used (complex examns where we need to fetch
+% special parts of a text
+%
+% this is not yet supported in mkiv (relatively easy to do but there
+% we don't have the par tags but need to grab 'm
+
+\def\skippedbufferparagraphs{0}
+
+\let\startbufferparagraph\relax
+\let\stopbufferparagraph \par % \relax
+
+\newcount\currentbufferparagraph
+
+\def\getbufferparagraphs
+ {\dodoubleempty\dogetbufferparagraphs}
+
+\def\dosetbufferoffset#1%
+ {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}}
+ {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}}
+ {\currentbufferparagraph \zerocount}%
+ \relax}
+
+\def\dogetbufferparagraphs[#1][#2]%
+ {\iffirstargument
+ \ifsecondargument
+ \dosetbufferoffset{#1}%
+ \doifelse{#2}\v!all
+ {\def\startbufferparagraph{\normalbufferparagraph{#1}}}
+ {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}%
+ \def\stopbufferparagraph{\dostopbufferparagraph{#1}}%
+ \def\next{\getparagraphedbuffer[#1]}%
+ \else
+ \dosetbufferoffset\empty
+ \def\startbufferparagraph{\filterbufferparagraph{}{#1}}%
+ \def\stopbufferparagraph{\dostopbufferparagraph{}}%
+ \def\next{\getparagraphedbuffer[]}%
+ \fi
+ \else
+ \dosetbufferoffset\empty
+ \def\startbufferparagraph{\normalbufferparagraph{}}%
+ \def\stopbufferparagraph{\dostopbufferparagraph{}}%
+ \def\next{\getparagraphedbuffer[]}%
+ \fi
+ \next}
+
+\def\dotypeparagraphbuffer{\ctxlua{buffers.get("\currentbuffer")}}
+
+\def\getparagraphedbuffer[#1]%
+ {\dobuffer{16}{#1}\dotypeparagraphbuffer}
+
+\def\dostopbufferparagraph#1%
+ {\getvalue{\??bu#1\c!after}\par}
+
+\def\dostartbufferparagraph#1%
+ {\par\getvalue{\??bu#1\c!before}}
+
+\def\normalbufferparagraph
+ {\advance\currentbufferparagraph \plusone
+ \ifnum\currentbufferparagraph>\zerocount
+ \expandafter\dostartbufferparagraph
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\filterbufferparagraph#1#2%
+ {\advance\currentbufferparagraph \plusone
+ \ifcase\currentbufferparagraph
+ \@EA\gobblebufferparagraph
+ \else
+ \doifinsetelse{\the\currentbufferparagraph}{#2}
+ {\@EA\dostartbufferparagraph}
+ {\@EA\fakebufferparagraph}%
+ \fi
+ {#1}}
+
+\long\def\gobblebufferparagraph#1#2\stopbufferparagraph
+ {}
+
+\def\fakebufferparagraph#1%
+ {\bgroup
+ \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}%
+ \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}}
+
+% definitions
+
+\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes]
+
+\setupbuffer
+ [\c!paragraph=\v!no,
+ \c!before=,
+ \c!after=]
+
+% only mkiv:
+
+\def\savebuffer{\dosingleempty\dosavebuffer}
+\def\dosavebuffer[#1]{\ctxlua{buffers.save("#1")}}
\protect \endinput
diff --git a/tex/context/base/core-buf.tex b/tex/context/base/core-buf.tex
deleted file mode 100644
index efc0b7973..000000000
--- a/tex/context/base/core-buf.tex
+++ /dev/null
@@ -1,250 +0,0 @@
-%D \module
-%D [ file=core-buf, % blocks are moved to core-blk
-%D version=2000.01.05,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Buffers,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Buffers}
-
-\unprotect
-
-\let\mkresetbuffer \donothing
-\let\mksetbuffer \gobbleoneargument
-\let\mkstartbuffer \gobblefivearguments
-\let\mkdobuffer \gobbleoneargument
-\let\mkstartmemorybuffer\startbuffer
-\let\mkstartfilebuffer \startbuffer
-\let\mkgetbuffer \donothing
-\let\mktypebuffer \donothing
-
-\chardef\buffernestmode\plusone % 0: not nested, 1: startbuffer nested, 2: all buffers nested
-
-\newif\ifsegmentatebuffer
-\newif\ifemptybufferline
-
-\def\currentbuffer{\jobname}
-
-\def\setcurrentbuffer#1%
- {\doifelsenothing{#1}{\edef\currentbuffer{\jobname}}{\edef\currentbuffer{#1}}}
-
-\def\resetbuffer
- {\dosingleempty\doresetbuffer}
-
-\def\doresetbuffer[#1]%
- {\begingroup
- \setcurrentbuffer{#1}%
- \mkresetbuffer
- \endgroup}
-
-\def\dostartbuffer
- {\bgroup
- \obeylines % nodig, anders gaat 't fout als direct \starttable (bv)
- \doquadrupleempty\dodostartbuffer}
-
-\def\dodostartbuffer[#1][#2][#3][#4]% upward compatible
- {\iffourthargument
- \def\next{\dododostartbuffer{#1}{#2}{#3}{#4}}%
- \else
- \def\next{\dododostartbuffer {}{#1}{#2}{#3}}%
- \fi
- \next}
-
-\def\dododostartbuffer#1#2#3#4%
- {%\showmessage\m!systems{15}{#2}%
- \doifelsevalue{\??bu#1\c!paragraph}\v!yes
- {\segmentatebuffertrue} % todo in mkiv
- {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}}\segmentatebuffertrue\segmentatebufferfalse}%
- \doifvalue{\??bu#1\c!local}\v!yes
- {\chardef\buffernestmode\plustwo}% permit nesting
- \setcurrentbuffer{#2}%
- \mkstartbuffer{#1}{#2}{#3}{#4}{\egroup}}
-
-\letvalue{\e!start\v!buffer}\dostartbuffer
-
-\let\endbuffer\undefined % to please the dep parser
-
-\def\setbuffer
- {\dosingleempty\dosetbuffer}
-
-\def\dosetbuffer[#1]#2\endbuffer % seldom used so we just pass #2
- {\begingroup
- \setcurrentbuffer{#1}%
- \mksetbuffer{#2}%
- \endgroup}
-
-\def\setupbuffer
- {\dodoubleempty\dosetupbuffer}
-
-\def\dosetupbuffer[#1][#2]%
- {\ifsecondargument
- \getparameters[\??bu#1][#2]%
- \else
- \getparameters[\??bu][#1]%
- \fi}
-
-\def\dodefinebuffer[#1][#2]%
- {\iffirstargument % else problems
- \doglobal\increment\nofdefinedbuffers
- \letvalue{\??bu#1\c!number }\nofdefinedbuffers
- \letvalue{\??bu#1\c!paragraph}\v!no
- \setevalue{\e!start#1}{\noexpand\dostartbuffer[#1][def-\nofdefinedbuffers][\e!start#1][\e!stop#1]}%
- \setevalue{\e!get #1}{\noexpand\dogetbuffer [#1][def-\nofdefinedbuffers]}%
- \setevalue{\e!type #1}{\noexpand\dotypebuffer [#1][def-\nofdefinedbuffers]}%
- \getparameters[\??bu#1][#2]%
- \fi}
-
-\def\definebuffer
- {\dodoubleempty\dodefinebuffer}
-
-\def\getbuffer
- {\dodoubleempty\dogetbuffer}
-
-\def\dogetbuffer[#1][#2]%
- {\ifsecondargument
- \dodogetbuffer[#1][#2]%
- \else
- \dodogetbuffer[][#1]%
- \fi}
-
-\def\dodogetbuffer[#1][#2]%
- {\getvalue{\??bu#1\c!before}%
- \dobuffer{16}{#2}\mkgetbuffer
- \getvalue{\??bu#1\c!after}}
-
-\def\typebuffer
- {\dodoubleempty\dotypebuffer}
-
-\def\dotypebuffer[#1][#2]%
- {\iffirstargument
- \dobuffer{17}{#1}\mktypebuffer
- \else
- \dobuffer{17}{#2}\mktypebuffer
- \fi}
-
-\def\dobuffer#1#2#3%
- {\doifelsenothing{#2}
- {\dodobuffer#3\jobname}
- {\processcommalist[#2]{\dodobuffer#3}}}
-
-\def\dodobuffer#1#2% command name
- {\pushmacro\currentbuffer
- \edef\currentbuffer{\ifcsname\??bu#2\c!number\endcsname def-\csname\??bu#2\c!number\endcsname\else#2\fi}%
- \mkdobuffer#1%
- \popmacro\currentbuffer}
-
-\def\processTEXbuffer{\getbuffer} % handy
-
-% seldom used, only in a few projects that demanded more speed
-
-\def\usememorybuffers{\let\startbuffer\mkstartmemorybuffer}
-\def\usefilebuffers {\let\startbuffer\mkstartfilebuffer}
-
-% this features is soldom used (complex examns where we need to fetch
-% special parts of a text
-%
-% this is not yet supported in mkiv (relatively easy to do but there
-% we don't have the par tags but need to grab 'm
-
-\def\skippedbufferparagraphs{0}
-
-\let\startbufferparagraph\relax
-\let\stopbufferparagraph \par % \relax
-
-\newcount\currentbufferparagraph
-
-\def\getbufferparagraphs
- {\dodoubleempty\dogetbufferparagraphs}
-
-\def\dosetbufferoffset#1%
- {\doifnumberelse{\getvalue{\??bu#1\c!paragraph}}
- {\currentbufferparagraph-\getvalue{\??bu#1\c!paragraph}}
- {\currentbufferparagraph \zerocount}%
- \relax}
-
-\def\dogetbufferparagraphs[#1][#2]%
- {\iffirstargument
- \ifsecondargument
- \dosetbufferoffset{#1}%
- \doifelse{#2}\v!all
- {\def\startbufferparagraph{\normalbufferparagraph{#1}}}
- {\def\startbufferparagraph{\filterbufferparagraph{#1}{#2}}}%
- \def\stopbufferparagraph{\dostopbufferparagraph{#1}}%
- \def\next{\getparagraphedbuffer[#1]}%
- \else
- \dosetbufferoffset\empty
- \def\startbufferparagraph{\filterbufferparagraph{}{#1}}%
- \def\stopbufferparagraph{\dostopbufferparagraph{}}%
- \def\next{\getparagraphedbuffer[]}%
- \fi
- \else
- \dosetbufferoffset\empty
- \def\startbufferparagraph{\normalbufferparagraph{}}%
- \def\stopbufferparagraph{\dostopbufferparagraph{}}%
- \def\next{\getparagraphedbuffer[]}%
- \fi
- \next}
-
-\def\getparagraphedbuffer[#1]%
- {\dobuffer{16}{#1}\mkgetbuffer}
-
-\def\dostopbufferparagraph#1%
- {\getvalue{\??bu#1\c!after}\par}
-
-\def\dostartbufferparagraph#1%
- {\par\getvalue{\??bu#1\c!before}}
-
-\def\normalbufferparagraph
- {\advance\currentbufferparagraph \plusone
- \ifnum\currentbufferparagraph>\zerocount
- \expandafter\dostartbufferparagraph
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\def\filterbufferparagraph#1#2%
- {\advance\currentbufferparagraph \plusone
- \ifcase\currentbufferparagraph
- \@EA\gobblebufferparagraph
- \else
- \doifinsetelse{\the\currentbufferparagraph}{#2}
- {\@EA\dostartbufferparagraph}
- {\@EA\fakebufferparagraph}%
- \fi
- {#1}}
-
-\long\def\gobblebufferparagraph#1#2\stopbufferparagraph
- {}
-
-\def\fakebufferparagraph#1%
- {\bgroup
- \def\stopbufferparagraph{\dostopbufferparagraph{#1}\egroup\egroup}%
- \setbox\scratchbox\vbox\bgroup\dostartbufferparagraph{#1}}
-
-% only mkiv
-
-\beginLUATEX
- \def\savebuffer{\dosingleempty\dosavebuffer}
- \def\dosavebuffer[#1]{\ctxlua{buffers.save("#1")}}
-\endLUATEX
-
-% plugins
-
-\loadmarkfile{core-buf}
-
-% definitions
-
-\definebuffer[\v!hiding] \setupbuffer[\v!hiding][\c!local=\v!yes]
-
-\setupbuffer
- [\c!paragraph=\v!no,
- \c!before=,
- \c!after=]
-
-\protect \endinput
diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua
index 20bfef32a..1b1657957 100644
--- a/tex/context/base/core-con.lua
+++ b/tex/context/base/core-con.lua
@@ -14,11 +14,25 @@ slower but look nicer this way.</p>
<p>Some code may move to a module in the language namespace.</p>
--ldx]]--
-local texsprint, floor, mod, format, date, time = tex.sprint, math.floor, math.mod, string.format, os.date, os.time
+local utf = unicode.utf8
+
+local floor, mod, date, time, concat, format = math.floor, math.mod, os.date, os.time, table.concat, string.format
+local texsprint, utfchar = tex.sprint, utf.char
+
+local ctxcatcodes = tex.ctxcatcodes
converters = converters or { }
languages = languages or { }
+--~ ['arabic-digits'] = {
+--~ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664,
+--~ 0x0665, 0x0666, 0x0667, 0x0668, 0x0669
+--~ },
+--~ ['persian-digits'] = {
+--~ 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4,
+--~ 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9
+--~ },
+
languages.counters = {
['**'] = {
0x0061, 0x0062, 0x0063, 0x0064, 0x0065,
@@ -43,12 +57,20 @@ languages.counters = {
0x03A6, 0x03A7, 0x03A8, 0x03A9
},
['arabic'] = {
- 0x0660, 0x0661, 0x0662, 0x0663, 0x0664,
- 0x0665, 0x0666, 0x0667, 0x0668, 0x0669
+ 0x0627, 0x0628, 0x062C, 0x062F, 0x0647,
+ 0x0648, 0x0632, 0x062D, 0x0637, 0x0649,
+ 0x0643, 0x0644, 0x0645, 0x0646, 0x0633,
+ 0x0639, 0x0641, 0x0635, 0x0642, 0x0631,
+ 0x0634, 0x062A, 0x062B, 0x062E, 0x0630,
+ 0x0636, 0x0638, 0x063A,
},
['persian'] = {
- 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4,
- 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9
+ 0x0627, 0x0628, 0x062C, 0x062F, 0x0647,
+ 0x0648, 0x0632, 0x062D, 0x0637, 0x0649,
+ 0x06A9, 0x0644, 0x0645, 0x0646, 0x0633,
+ 0x0639, 0x0641, 0x0635, 0x0642, 0x0631,
+ 0x0634, 0x062A, 0x062B, 0x062E, 0x0630,
+ 0x0636, 0x0638, 0x063A,
},
['thai'] = {
0xE050, 0xE051, 0xE052, 0xE053, 0xE054,
@@ -69,16 +91,34 @@ languages.counters = {
['tibetan'] = {
0x0F20, 0x0F21, 0x0F22, 0x0F23, 0x0F24,
0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29
- }
+ },
+ ['korean'] = {
+ 0x3131, 0x3134, 0x3137, 0x3139, 0x3141,
+ 0x3142, 0x3145, 0x3147, 0x3148, 0x314A,
+ 0x314B, 0x314C, 0x314D, 0x314E
+ },
+ ['korean-parent'] = { -- parenthesed
+ 0x3200, 0x3201, 0x3202, 0x3203, 0x3204,
+ 0x3205, 0x3206, 0x3207, 0x3208, 0x3209,
+ 0x320A, 0x320B, 0x320C, 0x320D
+ },
+ ['korean-circle'] = { -- circled
+ 0x3260, 0x3261, 0x3262, 0x3263, 0x3264,
+ 0x3265, 0x3266, 0x3267, 0x3268, 0x3269,
+ 0x326A, 0x326B, 0x326C, 0x326D
+ },
}
local counters = languages.counters
-counters['gr'] = counters['greek']
-counters['g'] = counters['greek']
-counters['sl'] = counters['slovenian']
+counters['ar'] = counters['arabic']
+counters['gr'] = counters['greek']
+counters['g'] = counters['greek']
+counters['sl'] = counters['slovenian']
+counters['kr'] = counters['korean']
+counters['kr-p'] = counters['korean-parent']
+counters['kr-c'] = counters['korean-circle']
-local utfchar = utf.char
local fallback = utf.byte('0')
function converters.chr(n,m)
@@ -92,7 +132,7 @@ function converters.maxchrs(n,m,cmd)
converters.maxchrs(floor((n-1)/m),m,cmd)
n = (n-1)%m + 1
end
- texsprint(tex.ctxcatcodes, format("%s{%s}",cmd,n))
+ texsprint(ctxcatcodes, format("%s{%s}",cmd,n))
end
function converters.chrs(n,m)
if n > 26 then
@@ -219,3 +259,222 @@ end
function converters.abjadnumerals (n) return texsprint(converters.toabjad(n,false)) end
function converters.abjadnodotnumerals(n) return texsprint(converters.toabjad(n,true)) end
+
+local vector = {
+ normal = {
+ [0] = "○",
+ [1] = "一",
+ [2] = "二",
+ [3] = "三",
+ [4] = "四",
+ [5] = "五",
+ [6] = "六",
+ [7] = "七",
+ [8] = "八",
+ [9] = "九",
+ [10] = "十",
+ [100] = "百",
+ [1000] = "千",
+ [10000] = "万",
+ [100000000] = "亿",
+ },
+ cap = {
+ [0] = "零",
+ [1] = "壹",
+ [2] = "贰",
+ [3] = "叁",
+ [4] = "肆",
+ [5] = "伍",
+ [6] = "陆",
+ [7] = "柒",
+ [8] = "捌",
+ [9] = "玖",
+ [10] = "拾",
+ [100] = "佰",
+ [1000] = "仟",
+ [10000] = "萬",
+ [100000000] = "亿",
+ },
+ all = {
+ [0] = "○",
+ [1] = "一",
+ [2] = "二",
+ [3] = "三",
+ [4] = "四",
+ [5] = "五",
+ [6] = "六",
+ [7] = "七",
+ [8] = "八",
+ [9] = "九",
+ [10] = "十",
+ [20] = "廿",
+ [30] = "卅",
+ [100] = "百",
+ [1000] = "千",
+ [10000] = "万",
+ [100000000] = "亿",
+ }
+}
+
+function tochinese(n,name) -- normal, caps, all
+ local result = { }
+ local vector = vector[name] or vector.normal
+ while true do
+ if n == 0 then
+ break
+ elseif n >= 100000000 then
+ local m = floor(n/100000000)
+ if m > 1 then result[#result+1] = tochinese(m) end
+ result[#result+1] = vector[100000000]
+ n = n % 100000000
+ elseif n >= 10000000 then
+ result[#result+1] = tochinese(floor(n/10000))
+ result[#result+1] = vector[10000]
+ n = n % 10000
+ elseif n >= 1000000 then
+ result[#result+1] = tochinese(floor(n/10000))
+ result[#result+1] = vector[10000]
+ n = n % 10000
+ elseif n >= 100000 then
+ result[#result+1] = tochinese(floor(n/10000))
+ result[#result+1] = vector[10000]
+ n = n % 10000
+ elseif n >= 10000 then
+ local m = floor(n/10000)
+ if m > 1 then result[#result+1] = vector[m] end
+ result[#result+1] = vector[10000]
+ n = n % 10000
+ elseif n >= 1000 then
+ local m = floor(n/1000)
+ if m > 1 then result[#result+1] = vector[m] end
+ result[#result+1] = vector[1000]
+ n = n % 1000
+ elseif n >= 100 then
+ local m = floor(n/100)
+ if m > 1 then result[#result+1] = vector[m] end
+ result[#result+1] = vector[100]
+ n = n % 100
+ elseif n >= 10 then
+ local m = floor(n/10)
+ if vector[m*10] then
+ result[#result+1] = vector[m*10]
+ else
+ result[#result+1] = vector[m]
+ result[#result+1] = vector[10]
+ end
+ n = n % 10
+ else
+ result[#result+1] = vector[n]
+ break
+ end
+ end
+ return concat(result)
+end
+
+--~ for k, v in ipairs { 1,10,15,25,35,45,11,100,111,1111,10000,11111,100000,111111,1111111,11111111,111111111,100000000,1111111111,11111111111,111111111111,1111111111111 } do
+--~ print(v,tochinese(v),tochinese(v,"all"),tochinese(v,"cap"))
+--~ end
+
+function converters.chinesenumerals (n) return texsprint(tochinese(n,"normal")) end
+function converters.chinesecapnumerals(n) return texsprint(tochinese(n,"cap" )) end
+function converters.chineseallnumerals(n) return texsprint(tochinese(n,"all" )) end
+
+--~ Well, since the one asking for this didn't test it the following code is not
+--~ enabled.
+--~
+--~ -- This Lua version is based on a Javascript by Behdad Esfahbod which in turn
+--~ -- is based on GPL'd code by Roozbeh Pournader of the The FarsiWeb Project
+--~ -- Group: http://www.farsiweb.info/jalali/jalali.js.
+--~ --
+--~ -- We start tables at one, I kept it zero based in order to stay close to
+--~ -- the original.
+--~ --
+--~ -- Conversion by Hans Hagen
+--~
+--~ local g_days_in_month = { [0]=31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+--~ local j_days_in_month = { [0]=31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 }
+--~
+--~ local function div(a,b)
+--~ return math.floor(a/b)
+--~ end
+--~
+--~ local function remainder(a,b)
+--~ return a - div(a,b)*b
+--~ end
+--~
+--~ function gregorian_to_jalali(gy,gm,gd)
+--~ local jy, jm, jd, g_day_no, j_day_no, j_np, i
+--~ gy, gm, gd = gy - 1600, gm - 1, gd - 1
+--~ g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400)
+--~ i = 0
+--~ while i < gm do
+--~ g_day_no = g_day_no + g_days_in_month[i]
+--~ i = i + 1
+--~ end
+--~ if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then
+--~ g_day_no = g_day_no + 1
+--~ end
+--~ g_day_no = g_day_no + gd
+--~ j_day_no = g_day_no - 79
+--~ j_np = div(j_day_no,12053)
+--~ j_day_no = remainder(j_day_no,12053)
+--~ jy = 979 + 33*j_np + 4*div(j_day_no,1461)
+--~ j_day_no = remainder(j_day_no,1461)
+--~ if j_day_no >= 366 then
+--~ jy = jy + div((j_day_no-1),365)
+--~ j_day_no = remainder((j_day_no-1),365)
+--~ end
+--~ i = 0
+--~ while i < 11 and j_day_no >= j_days_in_month[i] do
+--~ j_day_no = j_day_no - j_days_in_month[i]
+--~ i = i + 1
+--~ end
+--~ jm = i + 1
+--~ jd = j_day_no + 1
+--~ return jy, jm, jd
+--~ end
+--~
+--~ function jalali_to_gregorian(jy,jm,jd)
+--~ local gy, gm, gd, g_day_no, j_day_no, leap, i
+--~ jy, jm, jd = jy - 979, jm - 1, jd - 1
+--~ j_day_no = 365*jy + div(jy,33)*8 + div((remainder(jy,33)+3),4)
+--~ i = 0
+--~ while i < jm do
+--~ j_day_no = j_day_no + j_days_in_month[i]
+--~ i = i + 1
+--~ end
+--~ j_day_no = j_day_no + jd
+--~ g_day_no = j_day_no + 79
+--~ gy = 1600 + 400*div(g_day_no,146097)
+--~ g_day_no = remainder (g_day_no, 146097)
+--~ leap = 1
+--~ if g_day_no >= 36525 then
+--~ g_day_no = g_day_no - 1
+--~ gy = gy + 100*div(g_day_no,36524)
+--~ g_day_no = remainder (g_day_no, 36524)
+--~ if g_day_no >= 365 then
+--~ g_day_no = g_day_no + 1
+--~ else
+--~ leap = 0
+--~ end
+--~ end
+--~ gy = gy + 4*div(g_day_no,1461)
+--~ g_day_no = remainder (g_day_no, 1461)
+--~ if g_day_no >= 366 then
+--~ leap = 0
+--~ g_day_no = g_day_no - 1
+--~ gy = gy + div(g_day_no, 365)
+--~ g_day_no = remainder(g_day_no, 365)
+--~ end
+--~ i = 0
+--~ while g_day_no >= g_days_in_month[i] + ((i == 1 and leap) or 0) do
+--~ g_day_no = g_day_no - g_days_in_month[i] + ((i == 1 and leap) or 0)
+--~ i = i + 1
+--~ end
+--~ gm = i + 1
+--~ gd = g_day_no + 1
+--~ return gy, gm, gd
+--~ end
+--~
+--~ print(gregorian_to_jalali(2009,02,24))
+--~ print(jalali_to_gregorian(1387,12,06))
diff --git a/tex/context/base/core-con.mkii b/tex/context/base/core-con.mkii
index d9347b475..c39bdd9d4 100644
--- a/tex/context/base/core-con.mkii
+++ b/tex/context/base/core-con.mkii
@@ -2,7 +2,7 @@
%D [ file=core-con,
%D version=1997.26.08,
%D title=\CONTEXT\ Core Macros,
-%D subtitle=Conversion Macros,
+%D subtitle=Conversion,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,8 +11,67 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Conversion}
+
\unprotect
+\ifx\currentlanguage\undefined \let\currentlanguage\empty \fi
+\ifx\labeltext \undefined \let\labeltext\firstofoneargument \fi
+
+%D This module deals with all kind of conversions from numbers
+%D and dates. I considered splitting this module in a support
+%D one and a core one, but to keep things simple as well as
+%D preserve the overview, I decided against splitting.
+
+\let\spr\firstofoneargument % separator
+\let\stp\firstofoneargument % stopper
+
+% cleaner, some day:
+%
+% \def\isolateseparators % etex only, even works with list separator overloading
+% {\unexpanded\def\spr##1{{##1}}%
+% \unexpanded\def\stp##1{{##1}}}
+
+% needed for arab :
+
+\def\isolateseparators % even works with list separator overloading
+ {\def\spr##1{{##1}}%
+ \def\stp##1{{##1}}}
+
+%D \macros
+%D {numbers}
+%D
+%D First we deal with the dummy conversion of numbers using the
+%D \TEX\ primitive \type{\number}. The uppercase alternative is
+%D only there for compatibility with the other conversion
+%D macros. We could do without \type{#1} but this way we get
+%D rid of unwanted braces. For the savety we also define a
+%D non||sence uppercase alternative.
+%D
+%D \showsetup{numbers}
+%D
+%D \starttyping
+%D \def\numbers#1{\number#1}
+%D \def\Numbers#1{\number#1}
+%D \stoptyping
+%D
+%D Due to read ahead, as in \type{[\pagenumber\space]} the space will
+%D disappear, unless we use:
+
+\def\numbers#1{\purenumber{#1}}
+\def\Numbers#1{\purenumber{#1}}
+
+%D \macros
+%D {romannumerals,Romannumerals}
+%D
+%D \TEX\ the program uses a rather tricky conversion from
+%D numbers to their roman counterparts. This conversion could
+%D of course be programmed in \TEX\ itself, but I guess Knuth
+%D found the programming trick worth presenting.
+%D
+%D \showsetup{romannumerals}
+%D \showsetup{Romannumerals}
+
%D When upcasing the result, we just follow the text book rules
%D of expansion. Later on we'll see some more uppercase tricks.
@@ -50,6 +109,24 @@
\uppercase\expandafter{\romannumeral#1#2}%
\fi\fi\fi\fi}
+%D \macros
+%D {character,Character}
+%D
+%D Converting a number into a character can of course only
+%D be done with numbers less or equal to~26. At the cost of
+%D much more macros a faster conversion is possible, using:
+%D
+%D \starttyping
+%D \setvalue{char1}{a} \def\character#1{\getvalue{char#1}}
+%D \stoptyping
+%D
+%D But we prefer a simpel \type{\case}.
+%D
+%D \showsetup{character}
+%D \showsetup{Character}
+
+\def\unknowncharacter{-} % else in lists \relax
+
%D Big case statements but pretty fast:
\def\character#1%
@@ -68,6 +145,38 @@
\unknowncharacter
\fi}
+%D \macros
+%D {characters,Characters}
+%D
+%D Converting large numbers is supported by the next two
+%D macros. This time we just count on: $\cdots$~x, y, z, aa,
+%D ab, ac~$\cdots$.
+%D
+%D \showsetup{characters}
+%D \showsetup{Characters}
+
+%D The fully expandable alternative:
+
+\def\dodoconvertcharacters#1#2#3%
+ {\ifcase#3\else
+ \ifnum#3>#1
+ \expandafter\doconvertcharacters\expandafter#2\expandafter{\the\numexpr(#3+12)/#1-1\relax}%
+ \expandafter#2\expandafter{\the\numexpr#3-((#3+12)/#1-1)*#1\relax}%
+ \else
+ \expandafter#2\expandafter{\number#3}%
+ \fi
+ \fi}
+
+\def\doconvertcharacters{\dodoconvertcharacters{26}}
+
+\def\characters{\doconvertcharacters\character}
+\def\Characters{\doconvertcharacters\Character}
+
+%D \macros
+%D {greeknumerals,Greeknumerals}
+%D
+%D Why should we only honour the romans, and not the greek?
+
\def\greeknumerals#1%
{% no longer needed: \mathematics
{\ifcase#1\unknowncharacter\or
@@ -94,22 +203,115 @@
\unknowncharacter
\fi}}
-%D The fully expandable alternative:
+%D \macros
+%D {oldstylenumerals,oldstyleromannumerals}
+%D
+%D These conversions are dedicated to Frans Goddijn.
-\def\dodoconvertcharacters#1#2#3%
- {\ifcase#3\else
- \ifnum#3>#1
- \expandafter\doconvertcharacters\expandafter#2\expandafter{\the\numexpr(#3+12)/#1-1\relax}%
- \expandafter#2\expandafter{\the\numexpr#3-((#3+12)/#1-1)*#1\relax}%
- \else
- \expandafter#2\expandafter{\number#3}%
- \fi
+\unexpanded\def\oldstylenumerals#1%
+ {{\os\number#1}}
+
+\unexpanded\def\oldstyleromannumerals#1%
+ {{\leftrulefalse\rightrulefalse\ss\txx\boxrulewidth.15ex
+ \ruledhbox spread .15em{\hss\uppercased{\romannumerals{#1}}\hss}}}
+
+%D \macros
+%D {protectconversion}
+%D
+%D The previous two commands are not robust enough to be
+%D passed to \type{\write} en \type{\message}. That's why we
+%D introduce:
+
+\def\protectconversion
+ {\def\doconvertcharacters##1{##1}} % was \relax
+ %{\def\doconvertcharacters##1{\ifcase0##1 0\else##1\fi}} more save
+
+%D \macros
+%D {normaltime,normalyear,normalmonth,normalday}
+%D
+%D The last part of this module is dedicated to converting
+%D dates. Because we want to use as meaningful commands as
+%D possible, and because \TEX\ already uses up some of those,
+%D we save the original meanings.
+
+\savenormalmeaning\time
+\savenormalmeaning\year
+\savenormalmeaning\month
+\savenormalmeaning\day
+
+%D \macros
+%D {month,MONTH}
+%D
+%D Converting the month number into a month name is done
+%D using a case statement, abstact values and the label
+%D mechanism. This way users can easily redefine a label from
+%D for instance german into austrian.
+%D
+%D \starttyping
+%D \setuplabeltext [de] [january=J\"anner]
+%D \stoptyping
+%D
+%D Anyhow, the conversion looks like:
+
+\def\domonthtag#1%
+ {\ifcase#1%
+ \or \v!january \or \v!february \or \v!march \or \v!april
+ \or \v!may \or \v!june \or \v!july \or \v!august
+ \or \v!september \or \v!october \or \v!november \or \v!december
+ \else
+ \v!unknown
\fi}
-\def\doconvertcharacters{\dodoconvertcharacters{26}}
+\def\doconvertmonthlong #1{\labeltext{\domonthtag{#1}}}
+\def\doconvertmonthshort#1{\labeltext{\domonthtag{#1}:\s!mnem}}
-\def\characters{\doconvertcharacters\character}
-\def\Characters{\doconvertcharacters\Character}
+\let\doconvertmonth\doconvertmonthlong
+
+%D We redefine the \TEX\ primitive \type{\month} as:
+%D
+%D \showsetup{month}
+%D \showsetup{MONTH}
+
+\def\monthlong {\doconvertmonthlong}
+\def\monthshort{\doconvertmonthshort}
+\def\month {\doconvertmonth}
+
+\def\MONTH #1{{\let\labeltext\LABELTEXT\month {#1}}}
+\def\MONTHLONG #1{{\let\labeltext\LABELTEXT\monthlong {#1}}}
+\def\MONTHSHORT#1{{\let\labeltext\LABELTEXT\monthshort{#1}}}
+
+%D We never explicitly needed this, but Tobias Burnus pointed
+%D out that it would be handy to convert to the day of the
+%D week. In doing so, we have to calculate the total number of
+%D days, taking leapyears into account. For those who are
+%D curious:
+%D
+%D \startitemize[packed]
+%D \item years that can be divided by 4 are leapyears
+%D \item exept years that can be divided by 100
+%D \item unless years can be divided by 400
+%D \stopitemize
+%D
+%D This makes the year 1900 into a normal year and 1996 and
+%D 2000 into leap years, right? Well, converting to string
+%D looks familiar:
+
+\def\doconvertday#1%
+ {\labeltext
+ {\ifcase#1
+ \or \v!sunday \or \v!monday \or \v!tuesday \or \v!wednesday
+ \or \v!thursday \or \v!friday \or \v!saturday \fi}}
+
+%D \macros
+%D {getdayoftheweek, dayoftheweek}
+%D
+%D The conversion algoritm is an old one and a translation from
+%D a procedure written in MODULA~2 back in the 80's. I finaly
+%D found the 4--100-400 rules in some enclopedia. Look at this
+%D messy low level routine that takes the day, month and year
+%D as arguments:
+
+\newcount\normalweekday
\def\getdayoftheweek#1#2#3%
{\bgroup
@@ -140,6 +342,77 @@
\def\dayoftheweek#1#2#3%
{\getdayoftheweek{#1}{#2}{#3}\doconvertday{\normalweekday}}
+%D Using this macro in
+%D
+%D \startbuffer
+%D monday: \dayoftheweek {4} {5} {1992}
+%D friday: \dayoftheweek {16} {6} {1995}
+%D monday: \dayoftheweek {25} {8} {1997}
+%D saturday: \dayoftheweek {30} {8} {1997}
+%D tuesday: \dayoftheweek {2} {1} {1996}
+%D tuesday: \dayoftheweek {7} {1} {1997}
+%D tuesday: \dayoftheweek {13} {1} {1998}
+%D friday: \dayoftheweek {1} {1} {2000}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D The macro \type {\getdayoftheweek} can be used to calculate
+%D the number \type {\normalweekday}.
+
+%D \macros
+%D {weekday,WEEKDAY}
+%D
+%D The first one is sort of redundant. It takes the day
+%D number argument.
+%D
+%D \showsetup{weekday}
+%D \showsetup{WEEKDAY}
+
+\def\weekday
+ {\doconvertday}
+
+\def\WEEKDAY#1%
+ {{\let\labeltext\LABELTEXT\doconvertday{#1}}}
+
+%D \macros
+%D {weekoftheday}
+%D
+%D {\em not yet implemented:}
+%D
+%D \starttyping
+%D \def\weekoftheday#1#2#3%
+%D {}
+%D \stoptyping
+
+%D \macros
+%D {doifleapyearelse,
+%D getdayspermonth}
+%D
+%D Sometimes we need to know if we're dealing with a
+%D leapyear, so here is a testmacro:
+%D
+%D \starttyping
+%D \doifleapyearelse{year}{yes}{no}
+%D \stoptyping
+%D
+%D An example of its use can be seen in the macro
+%D
+%D \starttyping
+%D \getdayspermonth{year}{month}
+%D \stoptyping
+%D
+%D The number of days is available in the macro \type
+%D {\numberofdays}.
+
\def\doifleapyearelse#1% #2#3%
{\bgroup
\!!doneafalse
@@ -185,12 +458,450 @@
{\ifcase#2 \or31\or\numberofdays\or31\or30\or
31\or30\or31\or31\or30\or31\or30\or31\fi}}
+%D \macros
+%D {currentdate, date}
+%D
+%D We use these conversion macros in the date formatting
+%D macro:
+%D
+%D \showsetup{currentdate}
+%D
+%D This macro takes care of proper spacing and delivers for
+%D instance:
+%D
+%D \startbuffer
+%D \currentdate[weekday,day,month,year] % still dutch example
+%D \currentdate[WEEKDAY,day,MONTH,year] % still dutch example
+%D \stopbuffer
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D depending of course on the keywords. Here we gave:
+%D
+%D \typebuffer
+%D
+%D If needed one can also add non||keywords, like in
+%D
+%D \startbuffer
+%D \currentdate[dd,--,mm,--,yy]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or typeset: \getbuffer.
+%D
+%D When no argument is passed, the current date is given as
+%D specified per language (using \type{\installlanguage}).
+%D
+%D \showsetup{currentdate}
+%D
+%D \startbuffer
+%D \date
+%D \date[d=12,m=12,y=1998][weekday]
+%D \date[d=12,m=12,y=1998]
+%D \stopbuffer
+%D
+%D We can also typeset arbitrary dates, using the previous
+%D command.
+%D
+%D \typebuffer
+%D
+%D The date is specified by one character keys. When no date
+%D is given, we get the current date.
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+\def\kenmerkdatumpatroon{j,mm,dd} % jj,mm,dd changed at januari 1-1-2000
+
+\newsignal\datesignal
+
+\def\dobetweendates
+ {\ifdim\lastskip=\datesignal\relax\else
+ \unskip\space
+ \hskip\datesignal\relax
+ \fi}
+
+\newtoks \everycurrentdate
+
+\def\complexcurrentdate[#1]%
+ {\bgroup
+ \the\everycurrentdate
+ \def\betweendates{\let\betweendates\dobetweendates}%
+ % was \processcommacommandp[#1]\docomplexcurrentdate
+ \safeedef\ascii{\empty#1}% keep encoded chars
+ \@EA\processcommalist\@EA[\ascii]\docomplexcurrentdate
+ \ifdim\lastskip=\datesignal\relax
+ \unskip
+ \fi
+ \egroup}
+
+\def\docomplexcurrentdate#1%
+ {\lowercase{\edef\!!stringa{#1}}% permits usage in \smallcapped
+ \expanded{\processaction[\!!stringa]}% [#1]
+ [ \v!day=>\betweendates\the\normalday,
+ %\v!day+=>\betweendates\ordinaldaynumber\normalday,
+ \v!day+=>\betweendates\convertnumber{\v!day+}\normalday,
+ \v!month=>\betweendates\month\normalmonth,
+ \v!year=>\betweendates\the\normalyear,
+ \v!space=>\unskip\ \hskip\datesignal,% optimization -)
+ \ =>\unskip\ \hskip\datesignal,% optimization -)
+ d=>\convertnumber\v!day\normalday,
+ %d+=>\ordinaldaynumber\normalday,
+ d+=>\convertnumber{\v!day+}\normalday,
+ m=>\convertnumber\v!month\normalmonth,
+ j=>\convertnumber\v!year\normalyear,
+ y=>\convertnumber\v!year\normalyear,
+ w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+ dd=>\ifnum\normalday >9 \else0\fi\the\normalday,
+ %dd+=>\ordinaldaynumber{\ifnum\normalday >9 \else0\fi\the\normalday},
+ dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday},
+ mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth,
+ jj=>\expandafter\gobbletwoarguments\the\normalyear,
+ yy=>\expandafter\gobbletwoarguments\the\normalyear,
+ \v!weekday=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+ \v!referral=>\expanded{\complexcurrentdate[\kenmerkdatumpatroon]},
+ \s!unknown=>\unskip
+ % #1 and not the lowercased \commalistelement, vietnamese has text
+ % {} because #1 can have comma, like: {\ ,}
+ {#1}%
+ \hskip\datesignal
+ \def\betweendates{\let\betweendates\dobetweendates}]}
+
+\def\simplecurrentdate
+ {\expanded{\complexcurrentdate[\currentdatespecification]}}
+
+\definecomplexorsimple\currentdate
+
+\def\dodate[#1][#2]%
+ {\bgroup
+ \iffirstargument
+ \getparameters[\??da][d=\normalday,m=\normalmonth,y=\normalyear,#1]%
+ \normalday \@@dad\relax
+ \normalmonth\@@dam\relax
+ \normalyear \@@day\relax
+ \ifsecondargument
+ \currentdate[#2]%
+ \else
+ \currentdate
+ \fi
+ \else
+ \currentdate
+ \fi
+ \egroup}
+
+\def\date
+ {\dodoubleempty\dodate}
+
+%D \macros
+%D {currenttime}
+%D
+%D The currenttime is actually the jobtime. You can specify
+%D a pattern similar to the previous date macro using the
+%D keys \type {h}, \type {m} and a separator.
+
\def\calculatecurrenttime
{\dosetdivision\time{60}\scratchcounter
\edef\currenthour {\ifnum\scratchcounter<10 0\fi \the\scratchcounter}%
\dosetmodulo \time{60}\scratchcounter
\edef\currentminute{\ifnum\scratchcounter<10 0\fi \the\scratchcounter}}
+\let\currenthour \!!plusone
+\let\currentminute\!!plusone
+
+\def\currenttimespecification{h,:,m}
+
+\def\complexcurrenttime[#1]%
+ {\calculatecurrenttime
+ \processallactionsinset[#1]
+ [h=>\currenthour,m=>\currentminute,\s!unknown=>\commalistelement]}
+
+\def\simplecurrenttime
+ {\expanded{\complexcurrenttime[\currenttimespecification]}}
+
+\definecomplexorsimple\currenttime
+
+%D Because we're dealing with dates, we also introduce a few
+%D day loops:
+%D
+%D \starttyping
+%D \processmonth{year}{month}{command}
+%D \processyear{year}{command}{before}{after}
+%D \stoptyping
+%D
+%D The counters \type {\normalyear}, \type {\normalmonth} and
+%D \type{\normalday} can be used for for date manipulations.
+
+\long\def\processmonth#1#2#3% year month command
+ {\bgroup
+ \getdayspermonth{#1}{#2}%
+ \dostepwiserecurse1\numberofdays1%
+ {\normalyear #1\relax
+ \normalmonth#2\relax
+ \normalday \recurselevel\relax
+ #3}%
+ \egroup}
+
+\def\lastmonth{12} % can be set to e.g. 1 when testing
+
+\long\def\processyear#1#2#3#4% year command before after
+ {\bgroup
+ \dorecurse\lastmonth
+ {\normalyear #1\relax
+ \normalmonth\recurselevel\relax
+ #3\processmonth\normalyear\normalmonth{#2}#4}%
+ \egroup}
+
+%D \macros
+%D {defineconversion, convertnumber}
+%D
+%D Conversion involves the macros that we implemented earlier
+%D in this module.
+%D
+%D \showsetup{defineconversion}
+%D \showsetup{convertnumber}
+%D
+%D We can feed this command with conversion macros as well as
+%D a set of conversion symbols. Both need a bit different
+%D treatment.
+%D
+%D \starttyping
+%D \defineconversion [roman] [\romannumerals]
+%D \defineconversion [set 1] [$\star$,$\bullet$,$\ast$]
+%D \stoptyping
+%D
+%D You can define a language dependent conversion with:
+%D
+%D \starttyping
+%D \defineconversion [en] [whatever] [\something]
+%D \stoptyping
+
+% \def\dodefineconversion[#1][#2]%
+% {\ConvertConstantAfter\doifinstringelse{,}{#2}
+% {\scratchcounter=0
+% \def\docommand##1%
+% {\advance\scratchcounter 1
+% \setvalue{\??cv#1\the\scratchcounter}{##1}}%
+% \processcommalist[#2]\docommand
+% \setvalue{\??cv#1}##1{\csname\??cv#1##1\endcsname}}
+% {\setvalue{\??cv#1}{#2}}}
+%
+% \def\defineconversion%
+% {\dodoubleargument\dodefineconversion}
+
+\def\defineconversion
+ {\dotripleempty\dodefineconversion}
+
+\def\dodefineconversion[#1][#2][#3]%
+ {\ifthirdargument
+ \dododefineconversion[#1][#2][#3]%
+ \else
+ \dododefineconversion[][#1][#2]%
+ \fi}
+
+%D \starttyping
+%D \def\dododefineconversion[#1][#2][#3]%
+%D {\ConvertConstantAfter\doifinstringelse{,}{#3}
+%D {\scratchcounter\zerocount
+%D \def\docommand##1%
+%D {\advance\scratchcounter \plusone
+%D \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
+%D \processcommalist[#3]\docommand
+%D \setvalue{\??cv#1#2}##1{\executeifdefined{\??cv#1#2##1}\unknown}} % catch out-of-range numbers
+%D {\setvalue{\??cv#1#2}{#3}}}
+%D \stoptyping
+
+%D This approach has the disadvantage that when you run out of
+%D symbols you get unknown results. The following implementation
+%D permits overloading of the converter:
+
+\def\dododefineconversion[#1][#2][#3]%
+ {\ConvertConstantAfter\doifinstringelse{,}{#3}
+ {\scratchcounter\zerocount
+ \def\docommand##1%
+ {\advance\scratchcounter \plusone
+ \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
+ \processcommalist[#3]\docommand
+ \setevalue{\??cv#1#2}##1%
+ {\noexpand\docheckedconversion{#1#2}{\the\scratchcounter}{##1}}}
+ {\setvalue{\??cv#1#2}{#3}}}
+
+\def\docheckedconversion#1#2#3% class maxnumber number
+ {\executeifdefined{\??cv#1#3}\unknown}
+
+%D When Gerben reported problems with footnote numbering per page,
+%D Taco came with the following wrap around solution. So, let's
+%D overload the checked conversion macro:
+
+\def\docheckedconversion#1#2#3% class maxnumber number
+ {\executeifdefined{\??cv#1\modulatednumber{#2}{#3}}\unknown}
+
+%D Taco's modulo code is implemented in the system module
+%D \type {syst-con}.
+
+%D If a conversion is just a font switch then we need to make sure
+%D that the number is indeed end up as number in the input, so we
+%D need to handle the second argument.
+
+\def\convertnumber#1#2%
+ {\csname\??cv
+ \ifcsname\??cv\currentlanguage#1\endcsname
+ \currentlanguage#1%
+ \else\ifcsname\??cv#1\endcsname
+ #1%
+ \else
+ \s!default
+ \fi\fi
+ \endcsname{\number#2}}
+
+\def\doifconversiondefinedelse#1%
+ {\ifcsname\??cv\currentlanguage#1\endcsname
+ \@EA\firstoftwoarguments
+ \else\ifcsname\??cv#1\endcsname
+ \@EAEAEA\firstoftwoarguments
+ \else
+ \@EAEAEA\secondoftwoarguments
+ \fi\fi}
+
+\def\doifelseconversionnumber#1#2% slow but seldom used
+ {\doifdefinedelse{\??cv#1#2}}
+
+%D Handy.
+
+\setvalue{\??cv:\c!n:\v!one }{1}
+\setvalue{\??cv:\c!n:\v!two }{2}
+\setvalue{\??cv:\c!n:\v!three}{3}
+\setvalue{\??cv:\c!n:\v!four }{4}
+\setvalue{\??cv:\c!n:\v!five }{5}
+
+\def\wordtonumber#1#2{\ifcsname\??cv:\c!n:#1\endcsname\csname\??cv:\c!n:#1\endcsname\else#2\fi}
+
+% \defineconversion[ctx][c,o,n,t,e,x,t]
+%
+% \doloop{\doifelseconversionnumber{ctx}{\recurselevel}{[\recurselevel]}{\exitloop}}
+
+\defineconversion [\s!default] [\numbers]
+
+%D As longs as symbols are linked to levels or numbers, we can
+%D also use the conversion mechanism, but in for instance the
+%D itemization macros, we prefer symbols because they can more
+%D easier be (partially) redefined. Symbols are implemented
+%D in another module.
+
+\defineconversion [] [\numbers] % the default conversion
+
+\defineconversion [a] [\characters]
+\defineconversion [A] [\Characters]
+\defineconversion [AK] [\smallcapped\characters]
+\defineconversion [KA] [\smallcapped\characters]
+
+\defineconversion [n] [\numbers]
+\defineconversion [N] [\Numbers]
+\defineconversion [m] [\mediaeval]
+
+\defineconversion [i] [\romannumerals]
+\defineconversion [I] [\Romannumerals]
+\defineconversion [r] [\romannumerals]
+\defineconversion [R] [\Romannumerals]
+\defineconversion [KR] [\smallcapped\romannumerals]
+\defineconversion [RK] [\smallcapped\romannumerals]
+
+\defineconversion [g] [\greeknumerals]
+\defineconversion [G] [\Greeknumerals]
+
+\defineconversion [o] [\oldstylenumerals]
+\defineconversion [O] [\oldstylenumerals]
+\defineconversion [or] [\oldstyleromannumerals]
+
+\defineconversion [\v!character] [\character]
+\defineconversion [\v!Character] [\Character]
+
+\defineconversion [\v!characters] [\characters]
+\defineconversion [\v!Characters] [\Characters]
+
+\defineconversion [\v!numbers] [\numbers]
+\defineconversion [\v!Numbers] [\Numbers]
+\defineconversion [\v!mediaeval] [\mediaeval]
+
+\defineconversion [\v!romannumerals] [\romannumerals]
+\defineconversion [\v!Romannumerals] [\Romannumerals]
+
+\defineconversion [\v!greek] [\greeknumerals]
+\defineconversion [\v!Greek] [\Greeknumerals]
+
+\defineconversion [arabicnumerals] [\arabicnumerals]
+\defineconversion [persiannumerals] [\arabicnumerals]
+
+\defineconversion [month] [\doconvertmonthlong]
+\defineconversion [month:mnem] [\doconvertmonthshort]
+
+% Some bonus ones:
+
+\defineconversion [\v!empty] [\gobbleoneargument]
+\defineconversion [\v!none] [\numbers]
+
+\ifx\symbol\undefined \def\symbol[#1]{#1} \fi % todo
+
+\defineconversion
+ [set 0]
+ [{\symbol[bullet]},
+ {\symbol[dash]},
+ {\symbol[star]},
+ {\symbol[triangle]},
+ {\symbol[circle]},
+ {\symbol[medcircle]},
+ {\symbol[bigcircle]},
+ {\symbol[square]}]
+
+\defineconversion
+ [set 1]
+ [\mathematics{\star},
+ \mathematics{\star\star},
+ \mathematics{\star\star\star},
+ \mathematics{\ddagger},
+ \mathematics{\ddagger\ddagger},
+ \mathematics{\ddagger\ddagger\ddagger},
+ \mathematics{\ast},
+ \mathematics{\ast\ast},
+ \mathematics{\ast\ast\ast}]
+
+\defineconversion
+ [set 2]
+ [\mathematics{*},
+ \mathematics{\dag},
+ \mathematics{\ddag},
+ \mathematics{**},
+ \mathematics{\dag\dag},
+ \mathematics{\ddag\ddag},
+ \mathematics{***},
+ \mathematics{\dag\dag\dag},
+ \mathematics{\ddag\ddag\ddag},
+ \mathematics{****},
+ \mathematics{\dag\dag\dag\dag},
+ \mathematics{\ddag\ddag\ddag\ddag}]
+
+\defineconversion
+ [set 3]
+ [\mathematics{\star},
+ \mathematics{\star\star},
+ \mathematics{\star\star\star},
+ \mathematics{\ddagger},
+ \mathematics{\ddagger\ddagger},
+ \mathematics{\ddagger\ddagger\ddagger},
+ \mathematics{\P},
+ \mathematics{\P\P},
+ \mathematics{\P\P\P},
+ \mathematics{\S},
+ \mathematics{\S\S},
+ \mathematics{\S\S\S},
+ \mathematics{\ast},
+ \mathematics{\ast\ast},
+ \mathematics{\ast\ast\ast}]
%D \macros
%D {defineconversionvector,conversionnumber} % bad names so no danger for clash
@@ -235,24 +946,24 @@
% actually mkiii code
-\beginXETEX
-
-\defineconversionvector{arabicnumerals} {"0660}
-\defineconversionvector{persiannumerals} {"06F0}
-\defineconversionvector{thainumerals} {"0E50}
-\defineconversionvector{devanagarinumerals}{"0966}
-\defineconversionvector{gurmurkhinumerals} {"0A66}
-\defineconversionvector{gujaratinumerals} {"0AE6}
-\defineconversionvector{tibetannumerals} {"0F20} % also "half numerals?"
-
-\defineconversion[arabicnumerals] [\conversionnumber{arabicnumerals}]
-\defineconversion[persiannumerals] [\conversionnumber{persiannumerals}]
-\defineconversion[thainumerals] [\conversionnumber{thainumerals}]
-\defineconversion[devanagarinumerals][\conversionnumber{devanagarinumerals}]
-\defineconversion[gurmurkhinumerals] [\conversionnumber{gurmurkhinumerals}]
-\defineconversion[gujaratinumerals] [\conversionnumber{gujaratinumerals}]
-\defineconversion[tibetannumerals] [\conversionnumber{tibetannumerals}]
-
-\endXETEX
+\ifnum\texengine=\xetexengine
+
+ \defineconversionvector{arabicnumerals} {"0660}
+ \defineconversionvector{persiannumerals} {"06F0}
+ \defineconversionvector{thainumerals} {"0E50}
+ \defineconversionvector{devanagarinumerals}{"0966}
+ \defineconversionvector{gurmurkhinumerals} {"0A66}
+ \defineconversionvector{gujaratinumerals} {"0AE6}
+ \defineconversionvector{tibetannumerals} {"0F20} % also "half numerals?"
+
+ \defineconversion[arabicnumerals] [\conversionnumber{arabicnumerals}]
+ \defineconversion[persiannumerals] [\conversionnumber{persiannumerals}]
+ \defineconversion[thainumerals] [\conversionnumber{thainumerals}]
+ \defineconversion[devanagarinumerals][\conversionnumber{devanagarinumerals}]
+ \defineconversion[gurmurkhinumerals] [\conversionnumber{gurmurkhinumerals}]
+ \defineconversion[gujaratinumerals] [\conversionnumber{gujaratinumerals}]
+ \defineconversion[tibetannumerals] [\conversionnumber{tibetannumerals}]
+
+\fi
\protect \endinput
diff --git a/tex/context/base/core-con.mkiv b/tex/context/base/core-con.mkiv
index 70ddc6991..5568fc78c 100644
--- a/tex/context/base/core-con.mkiv
+++ b/tex/context/base/core-con.mkiv
@@ -1,8 +1,8 @@
%D \module
%D [ file=core-con,
-%D version=2006.09.16,
+%D version=1997.26.08,
%D title=\CONTEXT\ Core Macros,
-%D subtitle=Conversion Macros,
+%D subtitle=Conversion,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,33 +11,331 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
+\writestatus{loading}{ConTeXt Core Macros / Conversion}
\registerctxluafile{core-con}{1.001}
-\def\romannumerals #1{\ctxlua{converters.romannumerals(\number#1)}}
-\def\Romannumerals #1{\ctxlua{converters.Romannumerals(\number#1)}}
-\def\abjadnumerals #1{\ctxlua{converters.arabicnumerals(\number#1)}}
-\def\abjadnodotnumerals#1{\ctxlua{converters.arabicnodotnumerals(\number#1)}}
-\def\abjadnaivenumerals#1{\ctxlua{converters.arabicnaivenumerals(\number#1)}}
+\unprotect
-\defineconversion [romannumerals] [\romannumerals]
-\defineconversion [Romannumerals] [\Romannumerals]
-\defineconversion [abjadnumerals] [\abjadnumerals]
-\defineconversion [abjadnodotnumerals] [\adjadnodotnumerals]
-\defineconversion [abjadnaivenumerals] [\adjadnaivenumerals]
+\ifx\currentlanguage\undefined \let\currentlanguage\empty \fi
+\ifx\labeltext \undefined \let\labeltext\firstofoneargument \fi
-\def\character #1{\ctxlua{converters.character (\number#1)}}
-\def\Character #1{\ctxlua{converters.Character (\number#1)}}
-\def\characters#1{\ctxlua{converters.characters(\number#1)}}
-\def\Characters#1{\ctxlua{converters.Characters(\number#1)}}
+%D This module deals with all kind of conversions from numbers
+%D and dates. I considered splitting this module in a support
+%D one and a core one, but to keep things simple as well as
+%D preserve the overview, I decided against splitting.
+
+\let\spr\firstofoneargument % separator
+\let\stp\firstofoneargument % stopper
+
+% cleaner, some day:
+%
+% \def\isolateseparators % etex only, even works with list separator overloading
+% {\unexpanded\def\spr##1{{##1}}%
+% \unexpanded\def\stp##1{{##1}}}
+
+% needed for arab :
+
+\def\isolateseparators % even works with list separator overloading
+ {\def\spr##1{{##1}}%
+ \def\stp##1{{##1}}}
+
+%D \macros
+%D {numbers}
+%D
+%D First we deal with the dummy conversion of numbers using the
+%D \TEX\ primitive \type{\number}. The uppercase alternative is
+%D only there for compatibility with the other conversion
+%D macros. We could do without \type{#1} but this way we get
+%D rid of unwanted braces. For the savety we also define a
+%D non||sence uppercase alternative.
+%D
+%D \showsetup{numbers}
+%D
+%D \starttyping
+%D \def\numbers#1{\number#1}
+%D \def\Numbers#1{\number#1}
+%D \stoptyping
+%D
+%D Due to read ahead, as in \type{[\pagenumber\space]} the space will
+%D disappear, unless we use:
+
+\def\numbers#1{\purenumber{#1}}
+\def\Numbers#1{\purenumber{#1}}
+
+%D \macros
+%D {romannumerals,Romannumerals}
+%D
+%D \TEX\ the program uses a rather tricky conversion from
+%D numbers to their roman counterparts. This conversion could
+%D of course be programmed in \TEX\ itself, but I guess Knuth
+%D found the programming trick worth presenting.
+%D
+%D \showsetup{romannumerals}
+%D \showsetup{Romannumerals}
+
+\def\romannumerals#1{\ctxlua{converters.romannumerals(\number#1)}}
+\def\Romannumerals#1{\ctxlua{converters.Romannumerals(\number#1)}}
+
+%D Arabic etc:
+
+\def\abjadnumerals #1{\ctxlua{converters.abjadnumerals (\number#1)}}
+\def\abjadnodotnumerals#1{\ctxlua{converters.abjadnodotnumerals(\number#1)}}
+\def\abjadnaivenumerals#1{\ctxlua{converters.arabicnumerals (\number#1)}}
\def\languagecharacters#1{\ctxlua{converters.alphabetic(\number#1,"\currentlanguage")}} % new
\def\languageCharacters#1{\ctxlua{converters.Alphabetic(\number#1,"\currentlanguage")}} % new
+% we could use an auxiliary macro to save some bytes in the format
+%
+% \def\dolanguagecharacters#1#2{\ctxlua{converters.alphabetic(\number#2,"#1")}}
+
+\def\thainumerals #1{\ctxlua{converters.alphabetic(\number#1,"thai")}}
+\def\devanagarinumerals#1{\ctxlua{converters.alphabetic(\number#1,"devanagari")}}
+\def\gurmurkhinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gurmurkhi")}}
+\def\gujaratinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gujarati")}}
+\def\tibetannumerals #1{\ctxlua{converters.alphabetic(\number#1,"tibetan")}}
+\def\greeknumerals #1{\ctxlua{converters.alphabetic(\number#1,"greek")}}
+\def\Greeknumerals #1{\ctxlua{converters.Alphabetic(\number#1,"greek")}}
+\def\arabicnumerals #1{\ctxlua{converters.alphabetic(\number#1,"arabic")}}
+\def\persiannumerals #1{\ctxlua{converters.alphabetic(\number#1,"persian")}}
+
+\let\arabicexnumerals \persiannumerals
+
+\def\koreannumerals #1{\ctxlua{converters.alphabetic(\number#1,"korean")}}
+\def\koreannumeralsp#1{\ctxlua{converters.alphabetic(\number#1,"korean-parent")}}
+\def\koreannumeralsc#1{\ctxlua{converters.alphabetic(\number#1,"korean-circle")}}
+
+\def\chinesenumerals #1{\ctxlua{converters.chinesenumerals (\number#1)}}
+\def\chinesecapnumerals#1{\ctxlua{converters.chinesecapnumerals(\number#1,"cap")}}
+\def\chineseallnumerals#1{\ctxlua{converters.chineseallnumerals(\number#1,"all")}}
+
+%D \macros
+%D {character,Character}
+%D
+%D Converting a number into a character can of course only
+%D be done with numbers less or equal to~26. At the cost of
+%D much more macros a faster conversion is possible, using:
+%D
+%D \starttyping
+%D \setvalue{char1}{a} \def\character#1{\getvalue{char#1}}
+%D \stoptyping
+%D
+%D But we prefer a simpel \type{\case}.
+%D
+%D \showsetup{character}
+%D \showsetup{Character}
+
+\def\unknowncharacter{-} % else in lists \relax
+
+\def\character#1{\ctxlua{converters.character (\number#1)}}
+\def\Character#1{\ctxlua{converters.Character (\number#1)}}
+
+%D \macros
+%D {characters,Characters}
+%D
+%D Converting large numbers is supported by the next two
+%D macros. This time we just count on: $\cdots$~x, y, z, aa,
+%D ab, ac~$\cdots$.
+%D
+%D \showsetup{characters}
+%D \showsetup{Characters}
+
+\def\characters#1{\ctxlua{converters.characters(\number#1)}}
+\def\Characters#1{\ctxlua{converters.Characters(\number#1)}}
+
+%D \macros
+%D {greeknumerals,Greeknumerals}
+%D
+%D Why should we only honour the romans, and not the greek?
+
+\let\greeknumerals\gobbleoneargument
+\let\Greeknumerals\gobbleoneargument
+
+%D \macros
+%D {oldstylenumerals,oldstyleromannumerals}
+%D
+%D These conversions are dedicated to Frans Goddijn.
+
+\unexpanded\def\oldstylenumerals#1%
+ {{\os\number#1}}
+
+\unexpanded\def\oldstyleromannumerals#1%
+ {{\leftrulefalse\rightrulefalse\ss\txx\boxrulewidth.15ex
+ \ruledhbox spread .15em{\hss\uppercased{\romannumerals{#1}}\hss}}}
+
+%D \macros
+%D {protectconversion}
+%D
+%D The previous two commands are not robust enough to be
+%D passed to \type{\write} en \type{\message}. That's why we
+%D introduce:
+
+\def\protectconversion
+ {\def\doconvertcharacters##1{##1}} % was \relax
+ %{\def\doconvertcharacters##1{\ifcase0##1 0\else##1\fi}} more save
+
+%D \macros
+%D {normaltime,normalyear,normalmonth,normalday}
+%D
+%D The last part of this module is dedicated to converting
+%D dates. Because we want to use as meaningful commands as
+%D possible, and because \TEX\ already uses up some of those,
+%D we save the original meanings.
+
+\savenormalmeaning\time
+\savenormalmeaning\year
+\savenormalmeaning\month
+\savenormalmeaning\day
+
+%D \macros
+%D {month,MONTH}
+%D
+%D Converting the month number into a month name is done
+%D using a case statement, abstact values and the label
+%D mechanism. This way users can easily redefine a label from
+%D for instance german into austrian.
+%D
+%D \starttyping
+%D \setuplabeltext [de] [january=J\"anner]
+%D \stoptyping
+%D
+%D Anyhow, the conversion looks like:
+
+\def\domonthtag#1%
+ {\ifcase#1%
+ \or \v!january \or \v!february \or \v!march \or \v!april
+ \or \v!may \or \v!june \or \v!july \or \v!august
+ \or \v!september \or \v!october \or \v!november \or \v!december
+ \else
+ \v!unknown
+ \fi}
+
+\def\doconvertmonthlong #1{\labeltext{\domonthtag{#1}}}
+\def\doconvertmonthshort#1{\labeltext{\domonthtag{#1}:\s!mnem}}
+
+\let\doconvertmonth\doconvertmonthlong
+
+%D We redefine the \TEX\ primitive \type{\month} as:
+%D
+%D \showsetup{month}
+%D \showsetup{MONTH}
+
+\def\monthlong {\doconvertmonthlong}
+\def\monthshort{\doconvertmonthshort}
+\def\month {\doconvertmonth}
+
+\def\MONTH #1{{\let\labeltext\LABELTEXT\month {#1}}}
+\def\MONTHLONG #1{{\let\labeltext\LABELTEXT\monthlong {#1}}}
+\def\MONTHSHORT#1{{\let\labeltext\LABELTEXT\monthshort{#1}}}
+
+%D We never explicitly needed this, but Tobias Burnus pointed
+%D out that it would be handy to convert to the day of the
+%D week. In doing so, we have to calculate the total number of
+%D days, taking leapyears into account. For those who are
+%D curious:
+%D
+%D \startitemize[packed]
+%D \item years that can be divided by 4 are leapyears
+%D \item exept years that can be divided by 100
+%D \item unless years can be divided by 400
+%D \stopitemize
+%D
+%D This makes the year 1900 into a normal year and 1996 and
+%D 2000 into leap years, right? Well, converting to string
+%D looks familiar:
+
+\def\doconvertday#1%
+ {\labeltext
+ {\ifcase#1
+ \or \v!sunday \or \v!monday \or \v!tuesday \or \v!wednesday
+ \or \v!thursday \or \v!friday \or \v!saturday \fi}}
+
+%D \macros
+%D {getdayoftheweek, dayoftheweek}
+%D
+%D The conversion algoritm is an old one and a translation from
+%D a procedure written in MODULA~2 back in the 80's. I finaly
+%D found the 4--100-400 rules in some enclopedia. Look at this
+%D messy low level routine that takes the day, month and year
+%D as arguments:
+
+\newcount\normalweekday
+
\def\getdayoftheweek#1#2#3{\normalweekday\ctxlua{converters.weekday(\number#1,\number#2,\number#3)}}
\def\dayoftheweek #1#2#3{\doconvertday{\ctxlua{converters.weekday(\number#1,\number#2,\number#3)}}}
+%D Using this macro in
+%D
+%D \startbuffer
+%D monday: \dayoftheweek {4} {5} {1992}
+%D friday: \dayoftheweek {16} {6} {1995}
+%D monday: \dayoftheweek {25} {8} {1997}
+%D saturday: \dayoftheweek {30} {8} {1997}
+%D tuesday: \dayoftheweek {2} {1} {1996}
+%D tuesday: \dayoftheweek {7} {1} {1997}
+%D tuesday: \dayoftheweek {13} {1} {1998}
+%D friday: \dayoftheweek {1} {1} {2000}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D The macro \type {\getdayoftheweek} can be used to calculate
+%D the number \type {\normalweekday}.
+
+%D \macros
+%D {weekday,WEEKDAY}
+%D
+%D The first one is sort of redundant. It takes the day
+%D number argument.
+%D
+%D \showsetup{weekday}
+%D \showsetup{WEEKDAY}
+
+\def\weekday
+ {\doconvertday}
+
+\def\WEEKDAY#1%
+ {{\let\labeltext\LABELTEXT\doconvertday{#1}}}
+
+%D \macros
+%D {weekoftheday}
+%D
+%D {\em not yet implemented:}
+%D
+%D \starttyping
+%D \def\weekoftheday#1#2#3%
+%D {}
+%D \stoptyping
+
+%D \macros
+%D {doifleapyearelse,
+%D getdayspermonth}
+%D
+%D Sometimes we need to know if we're dealing with a
+%D leapyear, so here is a testmacro:
+%D
+%D \starttyping
+%D \doifleapyearelse{year}{yes}{no}
+%D \stoptyping
+%D
+%D An example of its use can be seen in the macro
+%D
+%D \starttyping
+%D \getdayspermonth{year}{month}
+%D \stoptyping
+%D
+%D The number of days is available in the macro \type
+%D {\numberofdays}.
+
\def\doifleapyearelse#1%
{\ifcase\ctxlua{converters.leapyear(\number#1)}
\@EA\secondoftwoarguments
@@ -51,11 +349,6 @@
\def\dayspermonth#1#2%
{\ctxlua{converters.nofdays(\number#1,\number#2)}}
-\def\calculatecurrenttime
- {\edef\currenthour {\ctxlua{converters.hour ()}}%
- \edef\currentminute{\ctxlua{converters.minute()}}%
- \edef\currentsecond{\ctxlua{converters.second()}}}
-
% problem is that we calculate with those numbers
%
% \def\time {\numexpr\ctxlua{converters.textime()}\relax}
@@ -71,33 +364,481 @@
% \dayspermonth{2000}{2}
% [\the\normaltime=\the\time]
-% we could use an auxiliary macro to save some bytes in the format
+%D \macros
+%D {currentdate, date}
+%D
+%D We use these conversion macros in the date formatting
+%D macro:
+%D
+%D \showsetup{currentdate}
+%D
+%D This macro takes care of proper spacing and delivers for
+%D instance:
+%D
+%D \startbuffer
+%D \currentdate[weekday,day,month,year] % still dutch example
+%D \currentdate[WEEKDAY,day,MONTH,year] % still dutch example
+%D \stopbuffer
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D depending of course on the keywords. Here we gave:
+%D
+%D \typebuffer
+%D
+%D If needed one can also add non||keywords, like in
+%D
+%D \startbuffer
+%D \currentdate[dd,--,mm,--,yy]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or typeset: \getbuffer.
+%D
+%D When no argument is passed, the current date is given as
+%D specified per language (using \type{\installlanguage}).
+%D
+%D \showsetup{currentdate}
+%D
+%D \startbuffer
+%D \date
+%D \date[d=12,m=12,y=1998][weekday]
+%D \date[d=12,m=12,y=1998]
+%D \stopbuffer
+%D
+%D We can also typeset arbitrary dates, using the previous
+%D command.
+%D
+%D \typebuffer
+%D
+%D The date is specified by one character keys. When no date
+%D is given, we get the current date.
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+\def\kenmerkdatumpatroon{j,mm,dd} % jj,mm,dd changed at januari 1-1-2000
+
+\newsignal\datesignal
+
+\def\dobetweendates
+ {\ifdim\lastskip=\datesignal\relax\else
+ \unskip\space
+ \hskip\datesignal\relax
+ \fi}
+
+\newtoks \everycurrentdate
+
+\def\complexcurrentdate[#1]%
+ {\bgroup
+ \the\everycurrentdate
+ \def\betweendates{\let\betweendates\dobetweendates}%
+ % was \processcommacommandp[#1]\docomplexcurrentdate
+ \safeedef\ascii{\empty#1}% keep encoded chars
+ \@EA\processcommalist\@EA[\ascii]\docomplexcurrentdate
+ \ifdim\lastskip=\datesignal\relax
+ \unskip
+ \fi
+ \egroup}
+
+\def\docomplexcurrentdate#1%
+ {\lowercase{\edef\!!stringa{#1}}% permits usage in \smallcapped
+ \expanded{\processaction[\!!stringa]}% [#1]
+ [ \v!day=>\betweendates\the\normalday,
+ %\v!day+=>\betweendates\ordinaldaynumber\normalday,
+ \v!day+=>\betweendates\convertnumber{\v!day+}\normalday,
+ \v!month=>\betweendates\month\normalmonth,
+ \v!year=>\betweendates\the\normalyear,
+ \v!space=>\unskip\ \hskip\datesignal,% optimization -)
+ \ =>\unskip\ \hskip\datesignal,% optimization -)
+ d=>\convertnumber\v!day\normalday,
+ %d+=>\ordinaldaynumber\normalday,
+ d+=>\convertnumber{\v!day+}\normalday,
+ m=>\convertnumber\v!month\normalmonth,
+ j=>\convertnumber\v!year\normalyear,
+ y=>\convertnumber\v!year\normalyear,
+ w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+ dd=>\ifnum\normalday >9 \else0\fi\the\normalday,
+ %dd+=>\ordinaldaynumber{\ifnum\normalday >9 \else0\fi\the\normalday},
+ dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday},
+ mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth,
+ jj=>\expandafter\gobbletwoarguments\the\normalyear,
+ yy=>\expandafter\gobbletwoarguments\the\normalyear,
+ \v!weekday=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
+ \v!referral=>\expanded{\complexcurrentdate[\kenmerkdatumpatroon]},
+ \s!unknown=>\unskip
+ % #1 and not the lowercased \commalistelement, vietnamese has text
+ % {} because #1 can have comma, like: {\ ,}
+ {#1}%
+ \hskip\datesignal
+ \def\betweendates{\let\betweendates\dobetweendates}]}
+
+\def\simplecurrentdate
+ {\expanded{\complexcurrentdate[\currentdatespecification]}}
+
+\definecomplexorsimple\currentdate
+
+\def\dodate[#1][#2]%
+ {\bgroup
+ \iffirstargument
+ \getparameters[\??da][d=\normalday,m=\normalmonth,y=\normalyear,#1]%
+ \normalday \@@dad\relax
+ \normalmonth\@@dam\relax
+ \normalyear \@@day\relax
+ \ifsecondargument
+ \currentdate[#2]%
+ \else
+ \currentdate
+ \fi
+ \else
+ \currentdate
+ \fi
+ \egroup}
+
+\def\date
+ {\dodoubleempty\dodate}
+
+%D \macros
+%D {currenttime}
+%D
+%D The currenttime is actually the jobtime. You can specify
+%D a pattern similar to the previous date macro using the
+%D keys \type {h}, \type {m} and a separator.
+
+\def\calculatecurrenttime
+ {\edef\currenthour {\ctxlua{converters.hour ()}}%
+ \edef\currentminute{\ctxlua{converters.minute()}}%
+ \edef\currentsecond{\ctxlua{converters.second()}}}
+
+\let\currenthour \!!plusone
+\let\currentminute\!!plusone
+
+\def\currenttimespecification{h,:,m}
+
+\def\complexcurrenttime[#1]%
+ {\calculatecurrenttime
+ \processallactionsinset[#1]
+ [h=>\currenthour,m=>\currentminute,\s!unknown=>\commalistelement]}
+
+\def\simplecurrenttime
+ {\expanded{\complexcurrenttime[\currenttimespecification]}}
+
+\definecomplexorsimple\currenttime
+
+%D Because we're dealing with dates, we also introduce a few
+%D day loops:
+%D
+%D \starttyping
+%D \processmonth{year}{month}{command}
+%D \processyear{year}{command}{before}{after}
+%D \stoptyping
+%D
+%D The counters \type {\normalyear}, \type {\normalmonth} and
+%D \type{\normalday} can be used for for date manipulations.
+
+\long\def\processmonth#1#2#3% year month command
+ {\bgroup
+ \getdayspermonth{#1}{#2}%
+ \dostepwiserecurse1\numberofdays1%
+ {\normalyear #1\relax
+ \normalmonth#2\relax
+ \normalday \recurselevel\relax
+ #3}%
+ \egroup}
+
+\def\lastmonth{12} % can be set to e.g. 1 when testing
+
+\long\def\processyear#1#2#3#4% year command before after
+ {\bgroup
+ \dorecurse\lastmonth
+ {\normalyear #1\relax
+ \normalmonth\recurselevel\relax
+ #3\processmonth\normalyear\normalmonth{#2}#4}%
+ \egroup}
+
+%D \macros
+%D {defineconversion, convertnumber}
+%D
+%D Conversion involves the macros that we implemented earlier
+%D in this module.
+%D
+%D \showsetup{defineconversion}
+%D \showsetup{convertnumber}
+%D
+%D We can feed this command with conversion macros as well as
+%D a set of conversion symbols. Both need a bit different
+%D treatment.
+%D
+%D \starttyping
+%D \defineconversion [roman] [\romannumerals]
+%D \defineconversion [set 1] [$\star$,$\bullet$,$\ast$]
+%D \stoptyping
+%D
+%D You can define a language dependent conversion with:
+%D
+%D \starttyping
+%D \defineconversion [en] [whatever] [\something]
+%D \stoptyping
+
+% \def\dodefineconversion[#1][#2]%
+% {\ConvertConstantAfter\doifinstringelse{,}{#2}
+% {\scratchcounter=0
+% \def\docommand##1%
+% {\advance\scratchcounter 1
+% \setvalue{\??cv#1\the\scratchcounter}{##1}}%
+% \processcommalist[#2]\docommand
+% \setvalue{\??cv#1}##1{\csname\??cv#1##1\endcsname}}
+% {\setvalue{\??cv#1}{#2}}}
%
-% \def\dolanguagecharacters#1#2{\ctxlua{converters.alphabetic(\number#2,"#1")}}
+% \def\defineconversion%
+% {\dodoubleargument\dodefineconversion}
-% this does not belong here, but in a lang-module
+\def\defineconversion
+ {\dotripleempty\dodefineconversion}
-\def\thainumerals #1{\ctxlua{converters.alphabetic(\number#1,"thai")}}
-\def\devanagarinumerals#1{\ctxlua{converters.alphabetic(\number#1,"devanagari")}}
-\def\gurmurkhinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gurmurkhi")}}
-\def\gujaratinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gujarati")}}
-\def\tibetannumerals #1{\ctxlua{converters.alphabetic(\number#1,"tibetan")}}
-\def\greeknumerals #1{\ctxlua{converters.alphabetic(\number#1,"greek")}}
-\def\Greeknumerals #1{\ctxlua{converters.Alphabetic(\number#1,"greek")}}
-\def\arabicnumerals #1{\ctxlua{converters.alphabetic(\number#1,"arabic")}}
-\def\persiannumerals #1{\ctxlua{converters.alphabetic(\number#1,"persian")}}
+\def\dodefineconversion[#1][#2][#3]%
+ {\ifthirdargument
+ \dododefineconversion[#1][#2][#3]%
+ \else
+ \dododefineconversion[][#1][#2]%
+ \fi}
-\let\arabicexnumerals \persiannumerals
+%D \starttyping
+%D \def\dododefineconversion[#1][#2][#3]%
+%D {\ConvertConstantAfter\doifinstringelse{,}{#3}
+%D {\scratchcounter\zerocount
+%D \def\docommand##1%
+%D {\advance\scratchcounter \plusone
+%D \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
+%D \processcommalist[#3]\docommand
+%D \setvalue{\??cv#1#2}##1{\executeifdefined{\??cv#1#2##1}\unknown}} % catch out-of-range numbers
+%D {\setvalue{\??cv#1#2}{#3}}}
+%D \stoptyping
+
+%D This approach has the disadvantage that when you run out of
+%D symbols you get unknown results. The following implementation
+%D permits overloading of the converter:
+
+\def\dododefineconversion[#1][#2][#3]%
+ {\ConvertConstantAfter\doifinstringelse{,}{#3}
+ {\scratchcounter\zerocount
+ \def\docommand##1%
+ {\advance\scratchcounter \plusone
+ \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
+ \processcommalist[#3]\docommand
+ \setevalue{\??cv#1#2}##1%
+ {\noexpand\docheckedconversion{#1#2}{\the\scratchcounter}{##1}}}
+ {\setvalue{\??cv#1#2}{#3}}}
+
+\def\docheckedconversion#1#2#3% class maxnumber number
+ {\executeifdefined{\??cv#1#3}\unknown}
+
+%D When Gerben reported problems with footnote numbering per page,
+%D Taco came with the following wrap around solution. So, let's
+%D overload the checked conversion macro:
+
+\def\docheckedconversion#1#2#3% class maxnumber number
+ {\executeifdefined{\??cv#1\modulatednumber{#2}{#3}}\unknown}
+
+%D Taco's modulo code is implemented in the system module
+%D \type {syst-con}.
+
+%D If a conversion is just a font switch then we need to make sure
+%D that the number is indeed end up as number in the input, so we
+%D need to handle the second argument.
+
+\def\convertnumber#1#2%
+ {\csname\??cv
+ \ifcsname\??cv\currentlanguage#1\endcsname
+ \currentlanguage#1%
+ \else\ifcsname\??cv#1\endcsname
+ #1%
+ \else
+ \s!default
+ \fi\fi
+ \endcsname{\number#2}}
+
+\def\doifconversiondefinedelse#1%
+ {\ifcsname\??cv\currentlanguage#1\endcsname
+ \@EA\firstoftwoarguments
+ \else\ifcsname\??cv#1\endcsname
+ \@EAEAEA\firstoftwoarguments
+ \else
+ \@EAEAEA\secondoftwoarguments
+ \fi\fi}
+
+\def\doifelseconversionnumber#1#2% slow but seldom used
+ {\doifdefinedelse{\??cv#1#2}}
+
+%D Handy.
+
+\setvalue{\??cv:\c!n:\v!one }{1}
+\setvalue{\??cv:\c!n:\v!two }{2}
+\setvalue{\??cv:\c!n:\v!three}{3}
+\setvalue{\??cv:\c!n:\v!four }{4}
+\setvalue{\??cv:\c!n:\v!five }{5}
+
+\def\wordtonumber#1#2{\ifcsname\??cv:\c!n:#1\endcsname\csname\??cv:\c!n:#1\endcsname\else#2\fi}
+
+% \defineconversion[ctx][c,o,n,t,e,x,t]
+%
+% \doloop{\doifelseconversionnumber{ctx}{\recurselevel}{[\recurselevel]}{\exitloop}}
+
+%D As longs as symbols are linked to levels or numbers, we can
+%D also use the conversion mechanism, but in for instance the
+%D itemization macros, we prefer symbols because they can more
+%D easier be (partially) redefined. Symbols are implemented
+%D in another module.
+
+\def\smallcappedromannumerals#1{\smallcapped{\romannumerals{#1}}}
+\def\smallcappedcharacters #1{\smallcapped{\characters {#1}}}
+
+\defineconversion [] [\numbers] % the default conversion
+\defineconversion [\v!empty] [\gobbleoneargument]
+\defineconversion [\v!none] [\numbers]
+\defineconversion [\s!default] [\numbers]
+
+\defineconversion [month] [\doconvertmonthlong]
+\defineconversion [month:mnem] [\doconvertmonthshort]
+
+\defineconversion [\v!character] [\character]
+\defineconversion [\v!Character] [\Character]
+
+\defineconversion [\v!characters] [\characters]
+\defineconversion [\v!Characters] [\Characters]
+
+\defineconversion [a] [\characters]
+\defineconversion [A] [\Characters]
+\defineconversion [AK] [\smallcappedcharacters]
+\defineconversion [KA] [\smallcappedcharacters]
+
+\defineconversion [\v!numbers] [\numbers]
+\defineconversion [\v!Numbers] [\Numbers]
+\defineconversion [\v!mediaeval] [\mediaeval]
+
+\defineconversion [n] [\numbers]
+\defineconversion [N] [\Numbers]
+\defineconversion [m] [\mediaeval]
+\defineconversion [o] [\oldstylenumerals]
+\defineconversion [O] [\oldstylenumerals]
+\defineconversion [or] [\oldstyleromannumerals]
+
+\defineconversion [\v!romannumerals] [\romannumerals]
+\defineconversion [\v!Romannumerals] [\Romannumerals]
+
+\defineconversion [i] [\romannumerals]
+\defineconversion [I] [\Romannumerals]
+\defineconversion [r] [\romannumerals]
+\defineconversion [R] [\Romannumerals]
+
+\defineconversion [KR] [\smallcappedromannumerals]
+\defineconversion [RK] [\smallcappedromannumerals]
+
+\defineconversion [\v!greek] [\greeknumerals]
+\defineconversion [\v!Greek] [\Greeknumerals]
+
+\defineconversion [g] [\greeknumerals]
+\defineconversion [G] [\Greeknumerals]
+
+\defineconversion [arabicnumerals] [\arabicnumerals]
+\defineconversion [persiannumerals] [\persiannumerals]
+
+\defineconversion [abjadnumerals] [\abjadnumerals]
+\defineconversion [abjadnodotnumerals] [\adjadnodotnumerals]
+\defineconversion [abjadnaivenumerals] [\adjadnaivenumerals]
+
+\defineconversion [thainumerals] [\thainumerals]
+\defineconversion [devanagarinumerals] [\devanagarinumerals]
+\defineconversion [gurmurkhinumerals] [\gurmurkhinumerals]
+\defineconversion [gujaratinumerals] [\gujaratinumerals]
+\defineconversion [tibetannumerals] [\tibetannumerals]
+\defineconversion [greeknumerals] [\greeknumerals]
+\defineconversion [Greeknumerals] [\Greeknumerals]
+\defineconversion [arabicnumerals] [\arabicnumerals]
+\defineconversion [persiannumerals] [\persiannumerals]
+\defineconversion [arabicexnumerals] [\arabicexnumerals]
+
+
+\defineconversion [koreannumerals] [\koreannumerals]
+\defineconversion [koreanparentnumerals] [\koreanparentnumerals]
+\defineconversion [koreancirclenumerals] [\koreancirclenumerals]
+
+\defineconversion [kr] [\koreannumerals]
+\defineconversion [kr-p] [\koreanparentnumerals]
+\defineconversion [kr-c] [\koreancirclenumerals]
+
+\defineconversion [chinesenumerals] [\chinesenumerals]
+\defineconversion [chinesecapnumeralscn] [\chinesecapnumerals]
+\defineconversion [chineseallnumeralscn] [\chineseallnumerals]
+
+\defineconversion [cn] [\chinesenumerals]
+\defineconversion [cn-c] [\chinesecapnumerals]
+\defineconversion [cn-a] [\chineseallnumerals]
+
+%D Symbol sets:
+
+\ifx\symbol\undefined \def\symbol[#1]{#1} \fi % todo
+
+\defineconversion
+ [set 0]
+ [{\symbol[bullet]},
+ {\symbol[dash]},
+ {\symbol[star]},
+ {\symbol[triangle]},
+ {\symbol[circle]},
+ {\symbol[medcircle]},
+ {\symbol[bigcircle]},
+ {\symbol[square]}]
+
+\defineconversion
+ [set 1]
+ [\mathematics{\star},
+ \mathematics{\star\star},
+ \mathematics{\star\star\star},
+ \mathematics{\ddagger},
+ \mathematics{\ddagger\ddagger},
+ \mathematics{\ddagger\ddagger\ddagger},
+ \mathematics{\ast},
+ \mathematics{\ast\ast},
+ \mathematics{\ast\ast\ast}]
+
+\defineconversion
+ [set 2]
+ [\mathematics{*},
+ \mathematics{\dag},
+ \mathematics{\ddag},
+ \mathematics{**},
+ \mathematics{\dag\dag},
+ \mathematics{\ddag\ddag},
+ \mathematics{***},
+ \mathematics{\dag\dag\dag},
+ \mathematics{\ddag\ddag\ddag},
+ \mathematics{****},
+ \mathematics{\dag\dag\dag\dag},
+ \mathematics{\ddag\ddag\ddag\ddag}]
-\defineconversion [thainumerals] [\thainumerals]
-\defineconversion [devanagarinumerals] [\devanagarinumerals]
-\defineconversion [gurmurkhinumerals] [\gurmurkhinumerals]
-\defineconversion [gujaratinumerals] [\gujaratinumerals]
-\defineconversion [tibetannumerals] [\tibetannumerals]
-\defineconversion [greeknumerals] [\greeknumerals]
-\defineconversion [Greeknumerals] [\Greeknumerals]
-\defineconversion [arabicnumerals] [\arabicnumerals]
-\defineconversion [persiannumerals] [\persiannumerals]
-\defineconversion [arabicexnumerals] [\arabicexnumerals]
+\defineconversion
+ [set 3]
+ [\mathematics{\star},
+ \mathematics{\star\star},
+ \mathematics{\star\star\star},
+ \mathematics{\ddagger},
+ \mathematics{\ddagger\ddagger},
+ \mathematics{\ddagger\ddagger\ddagger},
+ \mathematics{\P},
+ \mathematics{\P\P},
+ \mathematics{\P\P\P},
+ \mathematics{\S},
+ \mathematics{\S\S},
+ \mathematics{\S\S\S},
+ \mathematics{\ast},
+ \mathematics{\ast\ast},
+ \mathematics{\ast\ast\ast}]
\protect \endinput
diff --git a/tex/context/base/core-con.tex b/tex/context/base/core-con.tex
deleted file mode 100644
index 13d59ecc6..000000000
--- a/tex/context/base/core-con.tex
+++ /dev/null
@@ -1,744 +0,0 @@
-%D \module
-%D [ file=core-con,
-%D version=1997.26.08,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Conversion Macros,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Conversion Macros}
-
-\unprotect
-
-\ifx\currentlanguage\undefined \let\currentlanguage\empty \fi
-\ifx\labeltext \undefined \let\labeltext\firstofoneargument \fi
-
-%D This module deals with all kind of conversions from numbers
-%D and dates. I considered splitting this module in a support
-%D one and a core one, but to keep things simple as well as
-%D preserve the overview, I decided against splitting.
-
-\let\spr\firstofoneargument % separator
-\let\stp\firstofoneargument % stopper
-
-% cleaner, some day:
-%
-% \def\isolateseparators % etex only, even works with list separator overloading
-% {\unexpanded\def\spr##1{{##1}}%
-% \unexpanded\def\stp##1{{##1}}}
-
-% needed for arab :
-
-\def\isolateseparators % even works with list separator overloading
- {\def\spr##1{{##1}}%
- \def\stp##1{{##1}}}
-
-%D \macros
-%D {numbers}
-%D
-%D First we deal with the dummy conversion of numbers using the
-%D \TEX\ primitive \type{\number}. The uppercase alternative is
-%D only there for compatibility with the other conversion
-%D macros. We could do without \type{#1} but this way we get
-%D rid of unwanted braces. For the savety we also define a
-%D non||sence uppercase alternative.
-%D
-%D \showsetup{numbers}
-%D
-%D \starttyping
-%D \def\numbers#1{\number#1}
-%D \def\Numbers#1{\number#1}
-%D \stoptyping
-%D
-%D Due to read ahead, as in \type{[\pagenumber\space]} the space will
-%D disappear, unless we use:
-
-\def\numbers#1{\purenumber{#1}}
-\def\Numbers#1{\purenumber{#1}}
-
-%D \macros
-%D {romannumerals,Romannumerals}
-%D
-%D \TEX\ the program uses a rather tricky conversion from
-%D numbers to their roman counterparts. This conversion could
-%D of course be programmed in \TEX\ itself, but I guess Knuth
-%D found the programming trick worth presenting.
-%D
-%D \showsetup{romannumerals}
-%D \showsetup{Romannumerals}
-
-\let\romannumerals\gobbleoneargument
-\let\Romannumerals\gobbleoneargument
-
-%D \macros
-%D {character,Character}
-%D
-%D Converting a number into a character can of course only
-%D be done with numbers less or equal to~26. At the cost of
-%D much more macros a faster conversion is possible, using:
-%D
-%D \starttyping
-%D \setvalue{char1}{a} \def\character#1{\getvalue{char#1}}
-%D \stoptyping
-%D
-%D But we prefer a simpel \type{\case}.
-%D
-%D \showsetup{character}
-%D \showsetup{Character}
-
-\def\unknowncharacter{-} % else in lists \relax
-
-\let\character\gobbleoneargument
-\let\Character\gobbleoneargument
-
-%D \macros
-%D {characters,Characters}
-%D
-%D Converting large numbers is supported by the next two
-%D macros. This time we just count on: $\cdots$~x, y, z, aa,
-%D ab, ac~$\cdots$.
-%D
-%D \showsetup{characters}
-%D \showsetup{Characters}
-
-\let\characters\gobbleoneargument
-\let\Characters\gobbleoneargument
-
-%D \macros
-%D {greeknumerals,Greeknumerals}
-%D
-%D Why should we only honour the romans, and not the greek?
-
-\let\greeknumerals\gobbleoneargument
-\let\Greeknumerals\gobbleoneargument
-
-%D \macros
-%D {oldstylenumerals,oldstyleromannumerals}
-%D
-%D These conversions are dedicated to Frans Goddijn.
-
-\unexpanded\def\oldstylenumerals#1%
- {{\os\number#1}}
-
-\unexpanded\def\oldstyleromannumerals#1%
- {{\leftrulefalse\rightrulefalse\ss\txx\boxrulewidth.15ex
- \ruledhbox spread .15em{\hss\uppercased{\romannumerals{#1}}\hss}}}
-
-%D \macros
-%D {protectconversion}
-%D
-%D The previous two commands are not robust enough to be
-%D passed to \type{\write} en \type{\message}. That's why we
-%D introduce:
-
-\def\protectconversion
- {\def\doconvertcharacters##1{##1}} % was \relax
- %{\def\doconvertcharacters##1{\ifcase0##1 0\else##1\fi}} more save
-
-%D \macros
-%D {normaltime,normalyear,normalmonth,normalday}
-%D
-%D The last part of this module is dedicated to converting
-%D dates. Because we want to use as meaningful commands as
-%D possible, and because \TEX\ already uses up some of those,
-%D we save the original meanings.
-
-\savenormalmeaning\time
-\savenormalmeaning\year
-\savenormalmeaning\month
-\savenormalmeaning\day
-
-%D \macros
-%D {month,MONTH}
-%D
-%D Converting the month number into a month name is done
-%D using a case statement, abstact values and the label
-%D mechanism. This way users can easily redefine a label from
-%D for instance german into austrian.
-%D
-%D \starttyping
-%D \setuplabeltext [de] [january=J\"anner]
-%D \stoptyping
-%D
-%D Anyhow, the conversion looks like:
-
-\def\domonthtag#1%
- {\ifcase#1%
- \or \v!january \or \v!february \or \v!march \or \v!april
- \or \v!may \or \v!june \or \v!july \or \v!august
- \or \v!september \or \v!october \or \v!november \or \v!december
- \else
- \v!unknown
- \fi}
-
-\def\doconvertmonthlong #1{\labeltext{\domonthtag{#1}}}
-\def\doconvertmonthshort#1{\labeltext{\domonthtag{#1}:\s!mnem}}
-
-\let\doconvertmonth\doconvertmonthlong
-
-%D We redefine the \TEX\ primitive \type{\month} as:
-%D
-%D \showsetup{month}
-%D \showsetup{MONTH}
-
-\def\monthlong {\doconvertmonthlong}
-\def\monthshort{\doconvertmonthshort}
-\def\month {\doconvertmonth}
-
-\def\MONTH #1{{\let\labeltext\LABELTEXT\month {#1}}}
-\def\MONTHLONG #1{{\let\labeltext\LABELTEXT\monthlong {#1}}}
-\def\MONTHSHORT#1{{\let\labeltext\LABELTEXT\monthshort{#1}}}
-
-%D We never explicitly needed this, but Tobias Burnus pointed
-%D out that it would be handy to convert to the day of the
-%D week. In doing so, we have to calculate the total number of
-%D days, taking leapyears into account. For those who are
-%D curious:
-%D
-%D \startitemize[packed]
-%D \item years that can be divided by 4 are leapyears
-%D \item exept years that can be divided by 100
-%D \item unless years can be divided by 400
-%D \stopitemize
-%D
-%D This makes the year 1900 into a normal year and 1996 and
-%D 2000 into leap years, right? Well, converting to string
-%D looks familiar:
-
-\def\doconvertday#1%
- {\labeltext
- {\ifcase#1
- \or \v!sunday \or \v!monday \or \v!tuesday \or \v!wednesday
- \or \v!thursday \or \v!friday \or \v!saturday \fi}}
-
-%D \macros
-%D {getdayoftheweek, dayoftheweek}
-%D
-%D The conversion algoritm is an old one and a translation from
-%D a procedure written in MODULA~2 back in the 80's. I finaly
-%D found the 4--100-400 rules in some enclopedia. Look at this
-%D messy low level routine that takes the day, month and year
-%D as arguments:
-
-\newcount\normalweekday
-
-\let\getdayoftheweek\gobblethreearguments
-\let\dayoftheweek \gobblethreearguments
-
-%D Using this macro in
-%D
-%D \startbuffer
-%D monday: \dayoftheweek {4} {5} {1992}
-%D friday: \dayoftheweek {16} {6} {1995}
-%D monday: \dayoftheweek {25} {8} {1997}
-%D saturday: \dayoftheweek {30} {8} {1997}
-%D tuesday: \dayoftheweek {2} {1} {1996}
-%D tuesday: \dayoftheweek {7} {1} {1997}
-%D tuesday: \dayoftheweek {13} {1} {1998}
-%D friday: \dayoftheweek {1} {1} {2000}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D gives
-%D
-%D \startvoorbeeld
-%D \startlines
-%D \getbuffer
-%D \stoplines
-%D \stopvoorbeeld
-%D
-%D The macro \type {\getdayoftheweek} can be used to calculate
-%D the number \type {\normalweekday}.
-
-%D \macros
-%D {weekday,WEEKDAY}
-%D
-%D The first one is sort of redundant. It takes the day
-%D number argument.
-%D
-%D \showsetup{weekday}
-%D \showsetup{WEEKDAY}
-
-\def\weekday
- {\doconvertday}
-
-\def\WEEKDAY#1%
- {{\let\labeltext\LABELTEXT\doconvertday{#1}}}
-
-%D \macros
-%D {weekoftheday}
-%D
-%D {\em not yet implemented:}
-%D
-%D \starttyping
-%D \def\weekoftheday#1#2#3%
-%D {}
-%D \stoptyping
-
-%D \macros
-%D {doifleapyearelse,
-%D getdayspermonth}
-%D
-%D Sometimes we need to know if we're dealing with a
-%D leapyear, so here is a testmacro:
-%D
-%D \starttyping
-%D \doifleapyearelse{year}{yes}{no}
-%D \stoptyping
-%D
-%D An example of its use can be seen in the macro
-%D
-%D \starttyping
-%D \getdayspermonth{year}{month}
-%D \stoptyping
-%D
-%D The number of days is available in the macro \type
-%D {\numberofdays}.
-
-\def\doifleapyearelse #1{\firstoftwoarguments}
-\def\getdayspermonth#1#2{\let\numberofdays\!!zerocount}
-
-%D \macros
-%D {currentdate, date}
-%D
-%D We use these conversion macros in the date formatting
-%D macro:
-%D
-%D \showsetup{currentdate}
-%D
-%D This macro takes care of proper spacing and delivers for
-%D instance:
-%D
-%D \startbuffer
-%D \currentdate[weekday,day,month,year] % still dutch example
-%D \currentdate[WEEKDAY,day,MONTH,year] % still dutch example
-%D \stopbuffer
-%D
-%D \startvoorbeeld
-%D \startlines
-%D \getbuffer
-%D \stoplines
-%D \stopvoorbeeld
-%D
-%D depending of course on the keywords. Here we gave:
-%D
-%D \typebuffer
-%D
-%D If needed one can also add non||keywords, like in
-%D
-%D \startbuffer
-%D \currentdate[dd,--,mm,--,yy]
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D or typeset: \getbuffer.
-%D
-%D When no argument is passed, the current date is given as
-%D specified per language (using \type{\installlanguage}).
-%D
-%D \showsetup{currentdate}
-%D
-%D \startbuffer
-%D \date
-%D \date[d=12,m=12,y=1998][weekday]
-%D \date[d=12,m=12,y=1998]
-%D \stopbuffer
-%D
-%D We can also typeset arbitrary dates, using the previous
-%D command.
-%D
-%D \typebuffer
-%D
-%D The date is specified by one character keys. When no date
-%D is given, we get the current date.
-%D
-%D \startlines
-%D \getbuffer
-%D \stoplines
-
-\def\kenmerkdatumpatroon{j,mm,dd} % jj,mm,dd changed at januari 1-1-2000
-
-\newsignal\datesignal
-
-\def\dobetweendates
- {\ifdim\lastskip=\datesignal\relax\else
- \unskip\space
- \hskip\datesignal\relax
- \fi}
-
-\newtoks \everycurrentdate
-
-\def\complexcurrentdate[#1]%
- {\bgroup
- \the\everycurrentdate
- \def\betweendates{\let\betweendates\dobetweendates}%
- % was \processcommacommandp[#1]\docomplexcurrentdate
- \safeedef\ascii{\empty#1}% keep encoded chars
- \@EA\processcommalist\@EA[\ascii]\docomplexcurrentdate
- \ifdim\lastskip=\datesignal\relax
- \unskip
- \fi
- \egroup}
-
-\def\docomplexcurrentdate#1%
- {\lowercase{\edef\!!stringa{#1}}% permits usage in \smallcapped
- \expanded{\processaction[\!!stringa]}% [#1]
- [ \v!day=>\betweendates\the\normalday,
- %\v!day+=>\betweendates\ordinaldaynumber\normalday,
- \v!day+=>\betweendates\convertnumber{\v!day+}\normalday,
- \v!month=>\betweendates\month\normalmonth,
- \v!year=>\betweendates\the\normalyear,
- \v!space=>\unskip\ \hskip\datesignal,% optimization -)
- \ =>\unskip\ \hskip\datesignal,% optimization -)
- d=>\convertnumber\v!day\normalday,
- %d+=>\ordinaldaynumber\normalday,
- d+=>\convertnumber{\v!day+}\normalday,
- m=>\convertnumber\v!month\normalmonth,
- j=>\convertnumber\v!year\normalyear,
- y=>\convertnumber\v!year\normalyear,
- w=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
- dd=>\ifnum\normalday >9 \else0\fi\the\normalday,
- %dd+=>\ordinaldaynumber{\ifnum\normalday >9 \else0\fi\the\normalday},
- dd+=>\convertnumber{\v!day+}{\ifnum\normalday >9 \else0\fi\the\normalday},
- mm=>\ifnum\normalmonth>9 \else0\fi\the\normalmonth,
- jj=>\expandafter\gobbletwoarguments\the\normalyear,
- yy=>\expandafter\gobbletwoarguments\the\normalyear,
- \v!weekday=>\betweendates\dayoftheweek\normalday\normalmonth\normalyear,
- \v!referral=>\expanded{\complexcurrentdate[\kenmerkdatumpatroon]},
- \s!unknown=>\unskip
- % #1 and not the lowercased \commalistelement, vietnamese has text
- % {} because #1 can have comma, like: {\ ,}
- {#1}%
- \hskip\datesignal
- \def\betweendates{\let\betweendates\dobetweendates}]}
-
-\def\simplecurrentdate
- {\expanded{\complexcurrentdate[\currentdatespecification]}}
-
-\definecomplexorsimple\currentdate
-
-\def\dodate[#1][#2]%
- {\bgroup
- \iffirstargument
- \getparameters[\??da][d=\normalday,m=\normalmonth,y=\normalyear,#1]%
- \normalday \@@dad\relax
- \normalmonth\@@dam\relax
- \normalyear \@@day\relax
- \ifsecondargument
- \currentdate[#2]%
- \else
- \currentdate
- \fi
- \else
- \currentdate
- \fi
- \egroup}
-
-\def\date
- {\dodoubleempty\dodate}
-
-%D \macros
-%D {currenttime}
-%D
-%D The currenttime is actually the jobtime. You can specify
-%D a pattern similar to the previous date macro using the
-%D keys \type {h}, \type {m} and a separator.
-
-\let\calculatecurrenttime\relax
-
-\let\currenthour \!!plusone
-\let\currentminute\!!plusone
-
-\appendtoks \calculatecurrenttime \to \everyjob
-
-\def\currenttimespecification{h,:,m}
-
-\def\complexcurrenttime[#1]%
- {\calculatecurrenttime
- \processallactionsinset[#1]
- [h=>\currenthour,m=>\currentminute,\s!unknown=>\commalistelement]}
-
-\def\simplecurrenttime
- {\expanded{\complexcurrenttime[\currenttimespecification]}}
-
-\definecomplexorsimple\currenttime
-
-%D Because we're dealing with dates, we also introduce a few
-%D day loops:
-%D
-%D \starttyping
-%D \processmonth{year}{month}{command}
-%D \processyear{year}{command}{before}{after}
-%D \stoptyping
-%D
-%D The counters \type {\normalyear}, \type {\normalmonth} and
-%D \type{\normalday} can be used for for date manipulations.
-
-\long\def\processmonth#1#2#3% year month command
- {\bgroup
- \getdayspermonth{#1}{#2}%
- \dostepwiserecurse1\numberofdays1%
- {\normalyear #1\relax
- \normalmonth#2\relax
- \normalday \recurselevel\relax
- #3}%
- \egroup}
-
-\def\lastmonth{12} % can be set to e.g. 1 when testing
-
-\long\def\processyear#1#2#3#4% year command before after
- {\bgroup
- \dorecurse\lastmonth
- {\normalyear #1\relax
- \normalmonth\recurselevel\relax
- #3\processmonth\normalyear\normalmonth{#2}#4}%
- \egroup}
-
-%D \macros
-%D {defineconversion, convertnumber}
-%D
-%D Conversion involves the macros that we implemented earlier
-%D in this module.
-%D
-%D \showsetup{defineconversion}
-%D \showsetup{convertnumber}
-%D
-%D We can feed this command with conversion macros as well as
-%D a set of conversion symbols. Both need a bit different
-%D treatment.
-%D
-%D \starttyping
-%D \defineconversion [roman] [\romannumerals]
-%D \defineconversion [set 1] [$\star$,$\bullet$,$\ast$]
-%D \stoptyping
-%D
-%D You can define a language dependent conversion with:
-%D
-%D \starttyping
-%D \defineconversion [en] [whatever] [\something]
-%D \stoptyping
-
-% \def\dodefineconversion[#1][#2]%
-% {\ConvertConstantAfter\doifinstringelse{,}{#2}
-% {\scratchcounter=0
-% \def\docommand##1%
-% {\advance\scratchcounter 1
-% \setvalue{\??cv#1\the\scratchcounter}{##1}}%
-% \processcommalist[#2]\docommand
-% \setvalue{\??cv#1}##1{\csname\??cv#1##1\endcsname}}
-% {\setvalue{\??cv#1}{#2}}}
-%
-% \def\defineconversion%
-% {\dodoubleargument\dodefineconversion}
-
-\def\defineconversion
- {\dotripleempty\dodefineconversion}
-
-\def\dodefineconversion[#1][#2][#3]%
- {\ifthirdargument
- \dododefineconversion[#1][#2][#3]%
- \else
- \dododefineconversion[][#1][#2]%
- \fi}
-
-%D \starttyping
-%D \def\dododefineconversion[#1][#2][#3]%
-%D {\ConvertConstantAfter\doifinstringelse{,}{#3}
-%D {\scratchcounter\zerocount
-%D \def\docommand##1%
-%D {\advance\scratchcounter \plusone
-%D \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
-%D \processcommalist[#3]\docommand
-%D \setvalue{\??cv#1#2}##1{\executeifdefined{\??cv#1#2##1}\unknown}} % catch out-of-range numbers
-%D {\setvalue{\??cv#1#2}{#3}}}
-%D \stoptyping
-
-%D This approach has the disadvantage that when you run out of
-%D symbols you get unknown results. The following implementation
-%D permits overloading of the converter:
-
-\def\dododefineconversion[#1][#2][#3]%
- {\ConvertConstantAfter\doifinstringelse{,}{#3}
- {\scratchcounter\zerocount
- \def\docommand##1%
- {\advance\scratchcounter \plusone
- \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
- \processcommalist[#3]\docommand
- \setevalue{\??cv#1#2}##1%
- {\noexpand\docheckedconversion{#1#2}{\the\scratchcounter}{##1}}}
- {\setvalue{\??cv#1#2}{#3}}}
-
-\def\docheckedconversion#1#2#3% class maxnumber number
- {\executeifdefined{\??cv#1#3}\unknown}
-
-%D When Gerben reported problems with footnote numbering per page,
-%D Taco came with the following wrap around solution. So, let's
-%D overload the checked conversion macro:
-
-\def\docheckedconversion#1#2#3% class maxnumber number
- {\executeifdefined{\??cv#1\modulatednumber{#2}{#3}}\unknown}
-
-%D Taco's modulo code is implemented in the system module
-%D \type {syst-con}.
-
-%D If a conversion is just a font switch then we need to make sure
-%D that the number is indeed end up as number in the input, so we
-%D need to handle the second argument.
-
-\def\convertnumber#1#2%
- {\csname\??cv
- \ifcsname\??cv\currentlanguage#1\endcsname
- \currentlanguage#1%
- \else\ifcsname\??cv#1\endcsname
- #1%
- \else
- \s!default
- \fi\fi
- \endcsname{\number#2}}
-
-\def\doifconversiondefinedelse#1%
- {\ifcsname\??cv\currentlanguage#1\endcsname
- \@EA\firstoftwoarguments
- \else\ifcsname\??cv#1\endcsname
- \@EAEAEA\firstoftwoarguments
- \else
- \@EAEAEA\secondoftwoarguments
- \fi\fi}
-
-\def\doifelseconversionnumber#1#2% slow but seldom used
- {\doifdefinedelse{\??cv#1#2}}
-
-% \defineconversion[ctx][c,o,n,t,e,x,t]
-%
-% \doloop{\doifelseconversionnumber{ctx}{\recurselevel}{[\recurselevel]}{\exitloop}}
-
-\defineconversion [\s!default] [\numbers]
-
-%D As longs as symbols are linked to levels or numbers, we can
-%D also use the conversion mechanism, but in for instance the
-%D itemization macros, we prefer symbols because they can more
-%D easier be (partially) redefined. Symbols are implemented
-%D in another module.
-
-\defineconversion [] [\numbers] % the default conversion
-
-\defineconversion [a] [\characters]
-\defineconversion [A] [\Characters]
-\defineconversion [AK] [\smallcapped\characters]
-\defineconversion [KA] [\smallcapped\characters]
-
-\defineconversion [n] [\numbers]
-\defineconversion [N] [\Numbers]
-\defineconversion [m] [\mediaeval]
-
-\defineconversion [i] [\romannumerals]
-\defineconversion [I] [\Romannumerals]
-\defineconversion [r] [\romannumerals]
-\defineconversion [R] [\Romannumerals]
-\defineconversion [KR] [\smallcapped\romannumerals]
-\defineconversion [RK] [\smallcapped\romannumerals]
-
-\defineconversion [g] [\greeknumerals]
-\defineconversion [G] [\Greeknumerals]
-
-\defineconversion [o] [\oldstylenumerals]
-\defineconversion [O] [\oldstylenumerals]
-\defineconversion [or] [\oldstyleromannumerals]
-
-\defineconversion [\v!character] [\character]
-\defineconversion [\v!Character] [\Character]
-
-\defineconversion [\v!characters] [\characters]
-\defineconversion [\v!Characters] [\Characters]
-
-\defineconversion [\v!numbers] [\numbers]
-\defineconversion [\v!Numbers] [\Numbers]
-\defineconversion [\v!mediaeval] [\mediaeval]
-
-\defineconversion [\v!romannumerals] [\romannumerals]
-\defineconversion [\v!Romannumerals] [\Romannumerals]
-
-\defineconversion [\v!greek] [\greeknumerals]
-\defineconversion [\v!Greek] [\Greeknumerals]
-
-\defineconversion [arabicnumerals] [\arabicnumerals]
-\defineconversion [persiannumerals] [\arabicnumerals]
-
-\defineconversion [month] [\doconvertmonthlong]
-\defineconversion [month:mnem] [\doconvertmonthshort]
-
-% Some bonus ones:
-
-\defineconversion [\v!empty] [\gobbleoneargument]
-\defineconversion [\v!none] [\numbers]
-
-\ifx\symbol\undefined \def\symbol[#1]{#1} \fi % todo
-
-\defineconversion
- [set 0]
- [{\symbol[bullet]},
- {\symbol[dash]},
- {\symbol[star]},
- {\symbol[triangle]},
- {\symbol[circle]},
- {\symbol[medcircle]},
- {\symbol[bigcircle]},
- {\symbol[square]}]
-
-\defineconversion
- [set 1]
- [\mathematics{\star},
- \mathematics{\star\star},
- \mathematics{\star\star\star},
- \mathematics{\ddagger},
- \mathematics{\ddagger\ddagger},
- \mathematics{\ddagger\ddagger\ddagger},
- \mathematics{\ast},
- \mathematics{\ast\ast},
- \mathematics{\ast\ast\ast}]
-
-\defineconversion
- [set 2]
- [\mathematics{*},
- \mathematics{\dag},
- \mathematics{\ddag},
- \mathematics{**},
- \mathematics{\dag\dag},
- \mathematics{\ddag\ddag},
- \mathematics{***},
- \mathematics{\dag\dag\dag},
- \mathematics{\ddag\ddag\ddag},
- \mathematics{****},
- \mathematics{\dag\dag\dag\dag},
- \mathematics{\ddag\ddag\ddag\ddag}]
-
-\defineconversion
- [set 3]
- [\mathematics{\star},
- \mathematics{\star\star},
- \mathematics{\star\star\star},
- \mathematics{\ddagger},
- \mathematics{\ddagger\ddagger},
- \mathematics{\ddagger\ddagger\ddagger},
- \mathematics{\P},
- \mathematics{\P\P},
- \mathematics{\P\P\P},
- \mathematics{\S},
- \mathematics{\S\S},
- \mathematics{\S\S\S},
- \mathematics{\ast},
- \mathematics{\ast\ast},
- \mathematics{\ast\ast\ast}]
-
-%D Plugins:
-
-\loadmarkfile{core-con}
-
-\protect \endinput
diff --git a/tex/context/base/core-ctx.lua b/tex/context/base/core-ctx.lua
index 90cd4cb3b..eb9003bf1 100644
--- a/tex/context/base/core-ctx.lua
+++ b/tex/context/base/core-ctx.lua
@@ -6,8 +6,9 @@ if not modules then modules = { } end modules ['supp-fil'] = {
license = "see context related readme files"
}
-commands = commands or { }
-commands.trace_prepfiles = false
+local trace_prepfiles = false trackers.register("resolvers.prepfiles", function(v) trace_prepfiles = v end)
+
+commands = commands or { }
local list, suffix, islocal, found = { }, "prep", false, false
@@ -17,11 +18,11 @@ function commands.loadctxpreplist()
local x = xml.load(ctlname)
if x then
islocal = xml.found(x,"ctx:preplist[@local=='yes']")
- if commands.trace_prepfiles then
+ if trace_prepfiles then
if islocal then
- ctx.writestatus("systems","loading ctx log file (local)") -- todo: m!systems
+ commands.writestatus("systems","loading ctx log file (local)") -- todo: m!systems
else
- ctx.writestatus("systems","loading ctx log file (specified)") -- todo: m!systems
+ commands.writestatus("systems","loading ctx log file (specified)") -- todo: m!systems
end
end
for r, d, k in xml.elements(x,"ctx:prepfile") do
@@ -31,8 +32,8 @@ function commands.loadctxpreplist()
name = file.basename(name)
end
local done = dk.at['done'] or 'no'
- if commands.trace_prepfiles then
- ctx.writestatus("systems","registering %s -> %s",done)
+ if trace_prepfiles then
+ commands.writestatus("systems","registering %s -> %s",done)
end
found = true
list[name] = done -- 'yes' or 'no'
@@ -41,26 +42,26 @@ function commands.loadctxpreplist()
end
end
-local function resolve(name)
- local function found(name)
- local prepname = name .. "." .. suffix
- local done = list[name]
- if done then
- if lfs.isfile(prepname) then
- if commands.trace_prepfiles then
- ctx.writestatus("systems", "preprocessing: using %s",prepname)
- end
- return prepname
- end
+-- -- --
+
+local function found(name) -- used in resolve
+ local prepname = name .. "." .. suffix
+ if list[name] and lfs.isfile(prepname) then
+ if trace_prepfiles then
+ commands.writestatus("systems", "preprocessing: using %s",prepname)
end
- return false
+ return prepname
end
+ return false
+end
+
+local function resolve(name) -- used a few times later on
local filename = file.collapse_path(name)
local prepname = islocal and found(file.basename(name))
if prepname then
return prepname
end
- local prepname = found(filename)
+ prepname = found(filename)
if prepname then
return prepname
end
diff --git a/tex/context/base/core-ctx.mkii b/tex/context/base/core-ctx.mkii
index 673d69c09..93cf8b4be 100644
--- a/tex/context/base/core-ctx.mkii
+++ b/tex/context/base/core-ctx.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Ctx Job Files}
+\writestatus{loading}{ConTeXt Core Macros / Job Control}
\unprotect
diff --git a/tex/context/base/core-ctx.mkiv b/tex/context/base/core-ctx.mkiv
index f2447ffd0..c401b09f0 100644
--- a/tex/context/base/core-ctx.mkiv
+++ b/tex/context/base/core-ctx.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Ctx Job Files}
+\writestatus{loading}{ConTeXt Core Macros / Job Control}
\unprotect
@@ -23,5 +23,4 @@
\appendtoks\loadctxpreplist\to\everystarttext % will become: \prependtoks\loadctxpreplist\to\everyjob
-
\protect \endinput
diff --git a/tex/context/base/core-ctx.tex b/tex/context/base/core-ctx.tex
deleted file mode 100644
index 6eb70f029..000000000
--- a/tex/context/base/core-ctx.tex
+++ /dev/null
@@ -1,22 +0,0 @@
-%D \module
-%D [ file=core-ctx,
-%D version=2006.08.16, % old stuff
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Job Control,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Ctx Job Files}
-
-%D After some experimenting this code moved into the core. It
-%D overloades a few file reading macros and permits runtime
-%D conversion and job control.
-
-\loadmarkfile{core-ctx}
-
-\endinput
diff --git a/tex/context/base/core-dat.tex b/tex/context/base/core-dat.tex
index dc39f979f..44a82e1f3 100644
--- a/tex/context/base/core-dat.tex
+++ b/tex/context/base/core-dat.tex
@@ -13,73 +13,25 @@
% THIS WILL DISAPPEAR, I.E. BE MOVED TO A MODULE
-\writestatus{loading}{Context Database Support}
+\writestatus{loading}{ConTeXt Core Macros / Database Support}
-\startmessages dutch library: databases
- title: database
- 1: --
- 2: lokaal bestand --
- 3: globaal bestand --
- 4: onbekend bestand --
-\stopmessages
+% messages moved
-\startmessages english library: databases
- title: databases
- 1: --
- 2: local file --
- 3: global file --
- 4: unknown file --
-\stopmessages
+% messages moved
-\startmessages german library: databases
- title: Datenbank
- 1: --
- 2: lokale Datei --
- 3: globale Datei --
- 4: unbekannte Datei --
-\stopmessages
+% messages moved
% TOM :
-\startmessages czech library: databases
- title: databases
- 1: --
- 2: local file --
- 3: global file --
- 4: unknown file --
-\stopmessages
+% messages moved
-\startmessages italian library: databases
- title: database
- 1: --
- 2: file locale --
- 3: file globale --
- 4: file sconosciuto --
-\stopmessages
+% messages moved
-\startmessages norwegian library: databases
- title: databaser
- 1: --
- 2: lokal fil --
- 3: global fil --
- 4: ukjent fil --
-\stopmessages
+% messages moved
-\startmessages romanian library: databases
- title: baze de date
- 1: --
- 2: fisier local --
- 3: fisier global --
- 4: fisier necunoscut --
-\stopmessages
+% messages moved
-\startmessages french library: databases
- title: bases de données
- 1: --
- 2: fichier local --
- 3: fichier global --
- 4: fichier inconnu --
-\stopmessages
+% messages moved
\unprotect
diff --git a/tex/context/base/core-def.mkii b/tex/context/base/core-def.mkii
new file mode 100644
index 000000000..ea2d0ff15
--- /dev/null
+++ b/tex/context/base/core-def.mkii
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=core-def,
+%D version=2002.05.07,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Defaults,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Core Macros / Defaults}
+
+%D Here we collect settings that cannot be done earlier due to
+%D depedencies. More code will moved to this module later.
+
+\unprotect
+
+\usesymbols[mis,mvs] % 'glm' no longer needed due to lm
+
+\usesymbols[nav] \setupsymbolset[navigation 1]
+
+\setupinteraction[\c!symbolset=navigation 1]
+
+% initialization order:
+
+%appendtoks \initializeluainstances \to \everyjob
+\appendtoks \showcontextbanner \to \everyjob
+\appendtoks \initializenewlinechar \to \everyjob
+\appendtoks \checksystemcommandmode \to \everyjob
+\appendtoks \calculatecurrenttime \to \everyjob
+\appendtoks \loadsystemfiles \to \everyjob
+
+\appendtoks \loadoptionfile \to \everyjob % can load files !
+
+\appendtoks \preloadfonts \to \everyjob
+\appendtoks \settopskip \to \everyjob
+\appendtoks \preloadlanguages \to \everyjob
+\appendtoks \preloadspecials \to \everyjob
+\appendtoks \openspecialfile \to \everyjob
+\appendtoks \openutilities \to \everyjob
+\appendtoks \splitjobfilename \to \everyjob
+\appendtoks \checknotes \to \everyjob % depends on bodyfont
+\appendtoks \initializeMPgraphics \to \everyjob % after loading system files
+\appendtoks \reportsystemcommandmode \to \everyjob
+\appendtoks \initializemainlanguage \to \everyjob
+\appendtoks \settrue\trackfilenames \to \everyjob
+\appendtoks \newbackgroundfalse \to \everyjob % global
+
+\ifdefined\initializepagecounters
+ \appendtoks \initializepagecounters \to \everyjob
+\fi
+
+\appendtoks \directsetup{*runtime:options} \to \everyjob % we could erase them afterwards % order can change
+\appendtoks \directsetup{*runtime:modules} \to \everyjob % we could erase them afterwards % order can change
+
+\appendtoks \checkpreprocessor \to \everyjob
+
+%appendtoks \page[\v!last] \page \to \everybye % moved to core-job, we need to do this cleaner
+\appendtoks \ifarrangingpages\poparrangedpages\fi \to \everybye
+\appendtoks \registerfileinfo[end]\jobname \to \everybye
+\appendtoks \savenofpages \to \everybye
+\appendtoks \savenofsubpages \to \everybye
+
+\appendtoks \closeutilities \to \everygoodbye
+\appendtoks \stopcopyingblocks \to \everygoodbye
+\appendtoks \closespecialfile \to \everygoodbye
+
+\prependtoks \resetutilities \to \everystarttext % moved 28-02-2002
+\prependtoks \loadtwopassdata \to \everystarttext % moved 28-02-2002
+\appendtoks \checkreferences \to \everystarttext % new 04-12-1999
+
+% \appendtoks\everyjob\expandafter{\the\everyjob\checkpreprocessor}\to\everydump
+
+\protect \endinput
diff --git a/tex/context/base/core-def.mkiv b/tex/context/base/core-def.mkiv
new file mode 100644
index 000000000..380b733bc
--- /dev/null
+++ b/tex/context/base/core-def.mkiv
@@ -0,0 +1,74 @@
+%D \module
+%D [ file=core-def,
+%D version=2002.05.07,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Defaults,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Core Macros / Defaults}
+
+%D Here we collect settings that cannot be done earlier due to
+%D depedencies. More code will moved to this module later.
+
+\unprotect
+
+\usesymbols[mis,mvs,nav]
+
+\setupsymbolset[navigation 1]
+
+\setupinteraction[\c!symbolset=navigation 1]
+
+% initialization order:
+
+\appendtoks \showcontextbanner \to \everyjob
+\appendtoks \initializenewlinechar \to \everyjob
+\appendtoks \checksystemcommandmode \to \everyjob
+\appendtoks \calculatecurrenttime \to \everyjob
+\appendtoks \loadsystemfiles \to \everyjob
+\appendtoks \loadoptionfile \to \everyjob % can load files !
+\appendtoks \preloadfonts \to \everyjob
+\appendtoks \settopskip \to \everyjob
+\appendtoks \preloadlanguages \to \everyjob
+\appendtoks \preloadspecials \to \everyjob
+\appendtoks \splitjobfilename \to \everyjob
+\appendtoks \checknotes \to \everyjob % depends on bodyfont
+\appendtoks \initializeMPgraphics \to \everyjob % after loading system files
+\appendtoks \reportsystemcommandmode \to \everyjob
+\appendtoks \initializemainlanguage \to \everyjob
+\appendtoks \MPLIBregister \to \everyjob
+\appendtoks \xmlinitialize \to \everyjob
+\appendtoks \settrue\trackfilenames \to \everyjob
+\appendtoks \newbackgroundfalse \to \everyjob % global
+\appendtoks \initializepagecounters \to \everyjob
+\appendtoks \directsetup{*runtime:options} \to \everyjob % we could erase them afterwards % order can change
+\appendtoks \directsetup{*runtime:modules} \to \everyjob % we could erase them afterwards % order can change
+\appendtoks \checkpreprocessor \to \everyjob
+
+%appendtoks \page[\v!last] \page \to \everybye % moved to core-job, we need to do this cleaner
+\appendtoks \ifarrangingpages\poparrangedpages\fi \to \everybye
+\appendtoks \registerfileinfo[end]\jobname \to \everybye
+
+\prependtoks \resetutilities \to \everystarttext % moved 28-02-2002
+
+\appendtoks \MPLIBallocate{1000} \to \everydump
+
+\prependtoks \resetallattributes \to \everybeforeoutput
+
+\appendtoks \the\everybackendshipout \to \everyshipout
+\prependtoks \the\everylastbackendshipout \to \everylastshipout
+
+% temporary here:
+
+\ifx\in \undefined\else \let\normalmathin \in \unexpanded\def\in {\mathortext\normalmathin \dospecialin } \fi
+\ifx\at \undefined\else \let\normalmathat \at \unexpanded\def\at {\mathortext\normalmathat \dospecialat } \fi
+\ifx\about\undefined\else \let\normalmathabout\about \unexpanded\def\about{\mathortext\normalmathabout\dospecialabout} \fi
+\ifx\from \undefined\else \let\normalmathfrom \from \unexpanded\def\from {\mathortext\normalmathfrom \dospecialfrom } \fi
+\ifx\over \undefined\else \let\normalmathover \over \unexpanded\def\over {\mathortext\normalmathover \dospecialabout} \fi
+
+\protect \endinput
diff --git a/tex/context/base/core-def.tex b/tex/context/base/core-def.tex
deleted file mode 100644
index c7c49858e..000000000
--- a/tex/context/base/core-def.tex
+++ /dev/null
@@ -1,27 +0,0 @@
-%D \module
-%D [ file=core-def,
-%D version=2002.05.07,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Defaults,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Defaults}
-
-%D Here we collect settings that cannot be done earlier due to
-%D depedencies. More code will moved to this module later.
-
-\unprotect
-
-\usesymbols[mis,mvs] % 'glm' no longer needed due to lm
-
-\usesymbols[nav] \setupsymbolset[navigation 1]
-
-\setupinteraction[\c!symbolset=navigation 1]
-
-\protect \endinput
diff --git a/tex/context/base/core-des.tex b/tex/context/base/core-des.tex
index 1794800a4..dc7136c40 100644
--- a/tex/context/base/core-des.tex
+++ b/tex/context/base/core-des.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Descriptions}
+\writestatus{loading}{ConTeXt Core Macros / Descriptions}
%D In order to be more flexible with theorems Aditya Mahajan added
%D support for titles and endsymbols. At the same time we some more
@@ -394,7 +394,7 @@
% which calls:
\def\@@makedescription#1%
- {\postponefootnotes % new, assumes grouping
+ {\postponenotes % new, assumes grouping
\def\currentdescription{#1}%
\executeifdefined
{@@description\descriptionparameter\c!location}
@@ -829,8 +829,7 @@
\def\do@@label[#1][#2]%
{\numberparameter{#1}\c!before
- \numberparameter{#1}\c!command
- {\doattributes{\@@thenumber{#1}}\c!headstyle\c!headcolor{\getvalue{\e!next#1}[#2]}}%
+ \numberparameter{#1}\c!command{\doattributes{\@@thenumber{#1}}\c!headstyle\c!headcolor{\getvalue{\e!next#1}[#2]}}%
\numberparameter{#1}\c!after}%
\def\do@@nextlabel[#1][#2]%
diff --git a/tex/context/base/core-new.tex b/tex/context/base/core-env.mkii
index e96039d10..a22594b27 100644
--- a/tex/context/base/core-new.tex
+++ b/tex/context/base/core-env.mkii
@@ -1,6 +1,6 @@
%D \module
-%D [ file=core-nav,
-%D version=1995.01.01,
+%D [ file=core-env, % was core-new
+%D version=1995.01.01, % wrong
%D title=\CONTEXT\ Core Macros,
%D subtitle=New ones,
%D author=Hans Hagen,
@@ -11,23 +11,210 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / New Ones}
+\writestatus{loading}{ConTeXt Core Macros / Environments}
\unprotect
+% Clean labels:
+
+\bgroup % some day this will go away / we could use detokenize as well
+
+% actually we should handle all discretionaries here
+
+\catcode`:=\@@active
+
+\gdef\cleanuplabel#1%
+ {\begingroup
+ \let:\lettercolon
+ \xdef\cleanlabel{#1}%
+ \endgroup}
+
+\gdef\cleanupprefixedlabel#1#2%
+ {\begingroup
+ \let:\lettercolon
+ \xdef\cleanprefix{#1}%
+ \xdef\cleanlabel {#2}%
+ \endgroup}
+
+\gdef\protectlabels
+ {\let:\lettercolon}
+
+\global\def\blabelgroup {\begingroup \let:\lettercolon}
+\global\let\elabelgroup \endgroup
+
+\gdef\labelcsname
+ {\begingroup\let:\lettercolon
+ \expandafter\endgroup\csname}
+
+\gdef\labelvalue#1%
+ {\labelcsname#1\endcsname}
+
+\egroup
+
+%D Modes:
+%D
+%D \starttyping
+%D \enablemode[screen,paper,bound]
+%D
+%D \doifmodeelse {paper} {this} {that}
+%D \doifmode {paper,screen} {this}
+%D \doifnotmode {paper,bound} {that}
+%D
+%D \startmode [list]
+%D \stopmode
+%D
+%D \startnotmode [list]
+%D \stopnotmode
+%D \stoptyping
+%D
+%D system modes have a * as prefix
+%D
+%D Sometimes, we want to prevent a mode for being set. Think
+%D of situations where a style enables a mode, but an outer
+%D level style does not want that. Preventing can be
+%D considered a permanent disabling on forehand.
+
+\def\@mode@{@md@}
+
+\def\systemmodeprefix{*}
+
+\def\disabledmode {0}
+\def\enabledmode {1}
+\def\preventedmode {2}
+
+% fast internal ones
+
+\def\setmode #1{\@EA\let\csname\@mode@#1\endcsname\enabledmode }
+\def\resetmode#1{\@EA\let\csname\@mode@#1\endcsname\disabledmode}
+
+\def\setsystemmode #1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\enabledmode }
+\def\resetsystemmode#1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode}
+
+% user ones
+
+\def\preventmode{\unprotect\dopreventmode}
+\def\enablemode {\unprotect\doenablemode }
+\def\disablemode{\unprotect\dodisablemode}
+
+\def\dopreventmode[#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dodopreventmode}
+\def\doenablemode [#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dodoenablemode }
+\def\dodisablemode[#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dododisablemode}
+
+\def\dodopreventmode#1%
+ {\@EA\let\csname\@mode@#1\endcsname\preventedmode}
+
+\def\dodoenablemode#1% mode can be relax
+ {\ifcase0\csname\@mode@#1\endcsname\relax
+ \@EA\let\csname\@mode@#1\endcsname\enabledmode
+ \fi}
+
+\def\dododisablemode#1%
+ {\ifcase0\csname\@mode@#1\endcsname\or
+ \@EA\let\csname\@mode@#1\endcsname\disabledmode
+ \fi}
+
+% handy for mp
+
+\def\booleanmodevalue#1% can be \relax
+ {\expandafter\ifx\csname\@mode@#1\endcsname\relax
+ fals%
+ \else\ifnum0\csname\@mode@#1\endcsname=0
+ fals%
+ \else
+ tru%
+ \fi\fi e}
+
+% check macros
+
+\newif\ifcheckedmode
+
+\def\dodocheckformode#1%
+ {\ifcase0\csname\@mode@#1\endcsname\or\checkedmodetrue\fi}
+
+\def\docheckformode#1#2#3% will be sped up with a quit
+ {\cleanuplabel{#3}%
+ \protect\checkedmodefalse\rawprocesscommacommand[\cleanlabel]\dodocheckformode
+ \ifcheckedmode\@EA#1\else\@EA#2\fi}
+
+\def\dodocheckforallmodes#1%
+ {\ifcase0\csname\@mode@#1\endcsname\relax\checkedmodefalse\or\or\checkedmodefalse\fi}
+
+\def\docheckforallmodes#1#2#3% will be sped up with a quit
+ {\cleanuplabel{#3}%
+ \protect\checkedmodetrue\rawprocesscommacommand[\cleanlabel]\dodocheckforallmodes
+ \ifcheckedmode\@EA#1\else\@EA#2\fi}
+
+% simple ones
+
+\def\doifmodeelse{\unprotect\dodoifmodeelse}
+\def\doifmode {\unprotect\dodoifmode}
+\def\doifnotmode {\unprotect\dodoifnotmode}
+\def\startmode {\unprotect\dostartmode}
+\def\startnotmode{\unprotect\dostartnotmode}
+
+\def\dodoifmodeelse
+ {\docheckformode\firstoftwoarguments\secondoftwoarguments}
+
+\def\dodoifmode
+ {\docheckformode\firstofoneargument\gobbleoneargument}
+
+\def\dodoifnotmode
+ {\docheckformode\gobbleoneargument\firstofoneargument}
+
+\long\def\dostartmode[#1]%
+ {\docheckformode\donothing\dostopmode{#1}}
+
+\long\def\dostartnotmode[#1]%
+ {\docheckformode\dostopnotmode\donothing{#1}}
+
+\let\stopmode \donothing
+\let\stopnotmode\donothing
+
+\long\def\dostopmode #1\stopmode {}
+\long\def\dostopnotmode#1\stopnotmode{}
+
+\def\doifallmodeselse{\unprotect\dodoifallmodeselse}
+\def\doifallmodes {\unprotect\dodoifallmodes}
+\def\doifnotallmodes {\unprotect\dodoifnotallmodes}
+\def\startallmodes {\unprotect\dostartallmodes}
+\def\startnotallmodes{\unprotect\dostartnotallmodes}
+
+\def\dodoifallmodeselse
+ {\docheckforallmodes\firstoftwoarguments\secondoftwoarguments}
+
+\def\dodoifallmodes
+ {\docheckforallmodes\firstofoneargument\gobbleoneargument}
+
+\def\dodoifnotallmodes
+ {\docheckforallmodes\gobbleoneargument\firstofoneargument}
+
+\long\def\dostartallmodes[#1]%
+ {\docheckforallmodes\donothing\dostopallmodes{#1}}
+
+\long\def\dostartnotallmodes[#1]%
+ {\docheckforallmodes\dostopnotallmodes\donothing{#1}}
+
+\let\stopallmodes \donothing
+\let\stopnotallmodes\donothing
+
+\long\def\dostopallmodes #1\stopallmodes {}
+\long\def\dostopnotallmodes#1\stopnotallmodes{}
+
+% Setups
+
\let\startsetups\relax % to please dep checker
\let\stopsetups \relax % to please dep checker
\expanded
{\long\def\@EA\noexpand\csname\e!start\v!setups\endcsname
- {\begingroup\noexpand\doifnextcharelse[%
+ {\begingroup\noexpand\doifnextoptionalelse
{\noexpand\startsetupsA\@EA\noexpand\csname\e!stop\v!setups\endcsname}
{\noexpand\startsetupsB\@EA\noexpand\csname\e!stop\v!setups\endcsname}}}
\letvalue{\e!stop\v!setups}\relax
-\unexpanded \def\setups{\doifnextcharelse\bgroup\dosetupsA\dosetupsB} % {..} or [..]
-\unexpanded \def\setup {\doifnextcharelse\bgroup\dosetups \dosetupsC} % {..} or [..]
+\unexpanded \def\setups{\doifnextbgroupelse\dosetupsA\dosetupsB} % {..} or [..]
+\unexpanded \def\setup {\doifnextbgroupelse\dosetups \dosetupsC} % {..} or [..]
\def\dosetupsA #1{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % {..}
\def\dosetupsB[#1]{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % [..]
@@ -94,7 +281,7 @@
\def\startxmlsetups {\xxstartsetups\plustwo \stopxmlsetups } \let\stopxmlsetups \relax
\def\xxstartsetups#1#2%
- {\begingroup\chardef\setupseolmode#1\doifnextcharelse[{\startsetupsA#2}{\startsetupsB#2}}
+ {\begingroup\chardef\setupseolmode#1\doifnextoptionalelse{\startsetupsA#2}{\startsetupsB#2}}
\def\startsetupsA#1% [ ] delimited
{\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi
@@ -149,55 +336,14 @@
% \ifundefined{\??su\ifgridsnapping\v!grid\fi:#1}#1\else\ifgridsnapping\v!grid\fi%
% #1}}
-%D new and beta
-
-% \def\defineshortcut
-% {\dodoubleargument\dodefineshortcut}
-%
-% \bgroup
-%
-% \catcode`\<=\@@active
-%
-% \gdef\dodefineshortcut[#1][#2]%
-% {\ifsecondargument
-% \catcode`\<=\@@active
-% \def<{\ifmmode\expandafter\normalless\else\expandafter\doshortcut\fi}%
-% \getparameters[\??te#1][\c!commands=,\c!command=,\c!style=,\c!color=,#2]%
-% \else
-% \defineshortcut[][#1]%
-% \fi}
-%
-% \egroup
-%
-% \def\doshortcut
-% {\bgroup
-% \catcode`\>=\@@other
-% \dodoshortcut}
-%
-% \def\dodoshortcut#1>%
-% {\def\shortcut{#1}%
-% \dododoshortcut#1:\end}
-%
-% \def\dododoshortcut#1:#2\end
-% {\doifelsenothing{#2}
-% {\doifundefinedelse{\??te\c!commands}
-% {\shortcut}
-% {\@EA\dodododoshortcut\@EA\??te\@EA:\shortcut:\end}}
-% {\doifundefinedelse{\??te#1\c!commands}
-% {\shortcut}
-% {\dodododoshortcut\??te#1:#2\end}}%
-% \egroup}
-%
-% \def\dodododoshortcut#1:#2:\end
-% {\getvalue{#1\c!commands}%
-% \doattributes{#1}\c!style\c!color{\getvalue{#1\c!command}{#2}}}
+%D new and beta and will become a module instead
\def\defineshortcut
{\dotripleargument\dodefineshortcut}
\def\dodefineshortcut[#1][#2][#3]%
{\ifthirdargument
- \ConvertConstantAfter\doifelse{#1}{}
+ \doifelsenothing{#1}
{\dododefineshortcut[<>][#2][#3]}
{\dododefineshortcut[#1][#2][#3]}%
\else\ifsecondargument
@@ -276,6 +422,99 @@
%D it seems -a:to work- well
%D \stoplines
+%D \macros
+%D {setvariables,getvariable,getvariabledefault}
+%D
+%D \starttyping
+%D \setvariables[xx][title=]
+%D \setvariables[xx][title=test test]
+%D \setvariables[xx][title=test $x=1$ test] % fatal error reported
+%D \setvariables[xx][title=test {$x=1$} test]
+%D \setvariables[xx][title] % fatal error reported
+%D \setvariables[xx][titletitel=e]
+%D \stoptyping
+
+\def\??vars{@@vars}
+
+\def\setvariables {\dotripleargument\dosetvariables[\getrawparameters ]}
+\def\setevariables{\dotripleargument\dosetvariables[\getraweparameters]}
+\def\setgvariables{\dotripleargument\dosetvariables[\getrawgparameters]}
+\def\setxvariables{\dotripleargument\dosetvariables[\getrawxparameters]}
+
+\def\globalsetvariables % obsolete
+ {\dotripleargument\dosetvariables[\globalgetrawparameters]}
+
+\long\def\dosetvariables[#1][#2][#3]% tricky, test on s-pre-60
+ {\errorisfataltrue
+ \doifelse{#2}\currentvariableclass
+ {#1[\??vars:#2:][#3]}%
+ {\pushmacro\currentvariableclass
+ \def\currentvariableclass{#2}%
+ \getvariable{#2}\s!reset
+ #1[\??vars:#2:][#3]%
+ \getvariable{#2}\s!set
+ \popmacro\currentvariableclass}%
+ \errorisfatalfalse}
+
+\long\def\setvariable #1#2#3{\long\setvalue {\??vars:#1:#2}{#3}}
+\long\def\setevariable#1#2#3{\long\setevalue{\??vars:#1:#2}{#3}}
+\long\def\setgvariable#1#2#3{\long\setgvalue{\??vars:#1:#2}{#3}}
+\long\def\setxvariable#1#2#3{\long\setxvalue{\??vars:#1:#2}{#3}}
+
+\def\getvariable#1#2% to be sped up
+ {\csname
+ \ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi
+ \endcsname}
+
+\def\showvariable#1#2%
+ {\showvalue{\ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi}}
+
+\let\currentvariableclass\empty
+
+%D \macros
+%D {doifelsevariable,doifvariable,doifnotvariable}
+%D
+%D A few trivial macros:
+
+\def\doifelsevariable#1#2%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\doifvariable#1#2%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\doifnotvariable#1#2%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\def\getvariabledefault#1#2% #3% can be command, so no ifcsname here
+ {\executeifdefined{\??vars:#1:#2}}% {#3}
+
+%D \macros
+%D {checkvariables}
+%D
+%D I'll probably forget that this on exists.
+
+\def\checkvariables
+ {\dodoubleargument\docheckvariables}
+
+\def\docheckvariables
+ {\dogetparameters\docheckrawvalue}
+
+\def\docheckrawvalue#1#2#3%
+ {\doifundefined {\??vars:#1:#2}{\setvalue{\??vars:#1:#2}{#3}}
+ {\doifvaluenothing{\??vars:#1:#2}{\setvalue{\??vars:#1:#2}{#3}}}}
+
% \def\setupenv{\dodoubleargument\rawgetparameters[\??en]}
%
% \def\doifenvelse#1{\doifdefinedelse{\??en#1}} % speed up
diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv
new file mode 100644
index 000000000..47bd7549d
--- /dev/null
+++ b/tex/context/base/core-env.mkiv
@@ -0,0 +1,472 @@
+%D \module
+%D [ file=core-env, % was core-new
+%D version=1995.01.01, % wrong
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=New ones,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Core Macros / Environments}
+
+\unprotect
+
+%D Clean labels (no longer needed in \MKIV\ but we keep the grouping
+%D till we hav ea full separation of code.):
+
+\def\cleanuplabel#1%
+ {\xdef\cleanlabel{#1}}
+
+\def\cleanupprefixedlabel#1#2%
+ {\xdef\cleanprefix{#1}%
+ \xdef\cleanlabel {#2}}
+
+\let\protectlabels\donothing
+\let\blabelgroup \begingroup % obsolete
+\let\elabelgroup \endgroup % obsolete
+\let\labelcsname \csname
+\let\labelvalue \getvalue
+
+%D Modes:
+%D
+%D \starttyping
+%D \enablemode[screen,paper,bound]
+%D
+%D \doifmodeelse {paper} {this} {that}
+%D \doifmode {paper,screen} {this}
+%D \doifnotmode {paper,bound} {that}
+%D
+%D \startmode [list]
+%D \stopmode
+%D
+%D \startnotmode [list]
+%D \stopnotmode
+%D \stoptyping
+%D
+%D system modes have a * as prefix
+%D
+%D Sometimes, we want to prevent a mode for being set. Think
+%D of situations where a style enables a mode, but an outer
+%D level style does not want that. Preventing can be
+%D considered a permanent disabling on forehand.
+
+\def\@mode@{@md@}
+
+\def\systemmodeprefix{*}
+
+\def\disabledmode {0} % no chardefs
+\def\enabledmode {1}
+\def\preventedmode{2}
+
+% fast internal ones
+
+\def\setmode #1{\@EA\let\csname\@mode@#1\endcsname\enabledmode }
+\def\resetmode#1{\@EA\let\csname\@mode@#1\endcsname\disabledmode}
+
+\def\setsystemmode #1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\enabledmode }
+\def\resetsystemmode#1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode}
+
+% user ones
+
+\def\preventmode{\unprotect\dopreventmode}
+\def\enablemode {\unprotect\doenablemode }
+\def\disablemode{\unprotect\dodisablemode}
+
+\def\dopreventmode[#1]{\protect\rawprocesscommacommand[#1]\dodopreventmode}
+\def\doenablemode [#1]{\protect\rawprocesscommacommand[#1]\dodoenablemode }
+\def\dodisablemode[#1]{\protect\rawprocesscommacommand[#1]\dododisablemode}
+
+\def\dodopreventmode#1%
+ {\@EA\let\csname\@mode@#1\endcsname\preventedmode}
+
+\def\dodoenablemode#1% mode can be relax
+ {\ifcase0\csname\@mode@#1\endcsname\relax
+ \@EA\let\csname\@mode@#1\endcsname\enabledmode
+ \fi}
+
+\def\dododisablemode#1%
+ {\ifcase0\csname\@mode@#1\endcsname\or
+ \@EA\let\csname\@mode@#1\endcsname\disabledmode
+ \fi}
+
+% handy for mp
+
+\def\booleanmodevalue#1% can be \relax
+ {\expandafter\ifx\csname\@mode@#1\endcsname\relax
+ fals%
+ \else\ifnum0\csname\@mode@#1\endcsname=0
+ fals%
+ \else
+ tru%
+ \fi\fi e}
+
+% check macros
+
+\newif\ifcheckedmode
+
+\def\dodocheckformode#1%
+ {\ifcase0\csname\@mode@#1\endcsname\or\checkedmodetrue\fi}
+
+\def\docheckformode#1#2#3% will be sped up with a quit
+ {\protect\checkedmodefalse\rawprocesscommacommand[#3]\dodocheckformode
+ \ifcheckedmode\@EA#1\else\@EA#2\fi}
+
+\def\dodocheckforallmodes#1%
+ {\ifcase0\csname\@mode@#1\endcsname\relax\checkedmodefalse\or\or\checkedmodefalse\fi}
+
+\def\docheckforallmodes#1#2#3% will be sped up with a quit
+ {\protect\checkedmodetrue\rawprocesscommacommand[#3]\dodocheckforallmodes
+ \ifcheckedmode\@EA#1\else\@EA#2\fi}
+
+% simple ones
+
+\def\doifmodeelse{\unprotect\dodoifmodeelse}
+\def\doifmode {\unprotect\dodoifmode}
+\def\doifnotmode {\unprotect\dodoifnotmode}
+\def\startmode {\unprotect\dostartmode}
+\def\startnotmode{\unprotect\dostartnotmode}
+
+\def\dodoifmodeelse
+ {\docheckformode\firstoftwoarguments\secondoftwoarguments}
+
+\def\dodoifmode
+ {\docheckformode\firstofoneargument\gobbleoneargument}
+
+\def\dodoifnotmode
+ {\docheckformode\gobbleoneargument\firstofoneargument}
+
+\long\def\dostartmode[#1]%
+ {\docheckformode\donothing\dostopmode{#1}}
+
+\long\def\dostartnotmode[#1]%
+ {\docheckformode\dostopnotmode\donothing{#1}}
+
+\let\stopmode \donothing
+\let\stopnotmode\donothing
+
+\long\def\dostopmode #1\stopmode {}
+\long\def\dostopnotmode#1\stopnotmode{}
+
+\def\doifallmodeselse{\unprotect\dodoifallmodeselse}
+\def\doifallmodes {\unprotect\dodoifallmodes}
+\def\doifnotallmodes {\unprotect\dodoifnotallmodes}
+\def\startallmodes {\unprotect\dostartallmodes}
+\def\startnotallmodes{\unprotect\dostartnotallmodes}
+
+\def\dodoifallmodeselse
+ {\docheckforallmodes\firstoftwoarguments\secondoftwoarguments}
+
+\def\dodoifallmodes
+ {\docheckforallmodes\firstofoneargument\gobbleoneargument}
+
+\def\dodoifnotallmodes
+ {\docheckforallmodes\gobbleoneargument\firstofoneargument}
+
+\long\def\dostartallmodes[#1]%
+ {\docheckforallmodes\donothing\dostopallmodes{#1}}
+
+\long\def\dostartnotallmodes[#1]%
+ {\docheckforallmodes\dostopnotallmodes\donothing{#1}}
+
+\let\stopallmodes \donothing
+\let\stopnotallmodes\donothing
+
+\long\def\dostopallmodes #1\stopallmodes {}
+\long\def\dostopnotallmodes#1\stopnotallmodes{}
+
+%D Setups:
+
+\let\startsetups\relax % to please dep checker
+\let\stopsetups \relax % to please dep checker
+
+\expanded
+ {\long\def\@EA\noexpand\csname\e!start\v!setups\endcsname
+ {\begingroup\noexpand\doifnextoptionalelse
+ {\noexpand\startsetupsA\@EA\noexpand\csname\e!stop\v!setups\endcsname}
+ {\noexpand\startsetupsB\@EA\noexpand\csname\e!stop\v!setups\endcsname}}}
+
+\letvalue{\e!stop\v!setups}\relax
+
+\unexpanded \def\setups{\doifnextbgroupelse\dosetupsA\dosetupsB} % {..} or [..]
+\unexpanded \def\setup {\doifnextbgroupelse\dosetups \dosetupsC} % {..} or [..]
+
+\def\dosetupsA #1{\processcommacommand[#1]\dosetups} % {..}
+\def\dosetupsB[#1]{\processcommacommand[#1]\dosetups} % [..]
+\def\dosetupsC[#1]{\dosetups{#1}} % [..]
+
+\letvalue{\??su:\letterpercent}\gobbleoneargument
+
+\def\dosetups#1% the grid option will be extended to other main modes
+ {\csname\??su
+ \ifgridsnapping
+ \ifcsname\??su\v!grid:#1\endcsname\v!grid:#1\else\ifcsname\??su:#1\endcsname:#1\else:\letterpercent\fi\fi
+ \else
+ \ifcsname\??su:#1\endcsname:#1\else:\letterpercent\fi
+ \fi
+ \endcsname\empty} % takes one argument
+
+\def\setupwithargument#1% the grid option will be extended to other main modes
+ {\csname\??su:\ifcsname\??su:#1\endcsname#1\else\letterpercent\fi\endcsname}
+
+\let\directsetup\dosetups
+
+\def\doifsetupselse#1% to be done: grid
+ {\doifdefinedelse{\??su:#1}}
+
+\chardef\setupseolmode\plusone
+
+\def\startsetups {\xxstartsetups\plusone \stopsetups } \let\stopsetups \relax
+\def\startlocalsetups{\xxstartsetups\plusone \stoplocalsetups} \let\stoplocalsetups\relax
+\def\startrawsetups {\xxstartsetups\zerocount\stoprawsetups } \let\stoprawsetups \relax
+\def\startxmlsetups {\xxstartsetups\plustwo \stopxmlsetups } \let\stopxmlsetups \relax
+
+\def\xxstartsetups#1#2%
+ {\begingroup\let\setupseolmode#1\doifnextoptionalelse{\startsetupsA#2}{\startsetupsB#2}}
+
+\def\startsetupsA#1% [ ] delimited
+ {\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi
+ \dotripleempty\dostartsetups[#1]}
+
+\def\startsetupsB#1#2 % space delimited
+ {\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi
+ \dodostartsetups#1\empty{#2}}
+
+\def\startsetupsC[#1][#2][#3]{\dodostartsetups#1{#2}{#3}} % [..] [..]
+\def\startsetupsD[#1][#2][#3]{\dodostartsetups#1\empty{#2}} % [..]
+
+\def\dostartsetups
+ {\ifthirdargument\@EA\startsetupsC\else\@EA\startsetupsD\fi}
+
+\long\def\dodostartsetups#1#2#3%
+ {\long\def\dododostartsetups##1#1%
+ {\endgroup
+ \dodoglobal % bah
+ \long\expandafter\def\csname\??su#2:#3\expandafter\endcsname\expandafter####\expandafter1\expandafter{##1}}%
+ \dododostartsetups\empty} % the empty trick prevents the { } in {arg} from being eaten up
+
+\def\systemsetupsprefix{*}
+
+\def\systemsetups#1{\dosetups{\systemsetupsprefix#1}}
+
+\def\resetsetups[#1]% see x-fo for usage
+ {\ifcsname\??su\ifgridsnapping\v!grid\fi:#1\endcsname
+ \dodoglobal\letbeundefined{\??su\ifgridsnapping\v!grid\fi:#1}%
+ \else
+ \dodoglobal\letbeundefined{\??su:#1}%
+ \fi}
+
+%D \defineshortcut [style=type]
+%D \defineshortcut [b] [style=bold]
+%D \defineshortcut [e] [style=\em]
+%D \defineshortcut [t] [style=type]
+%D \defineshortcut [c] [style=cap]
+%D \defineshortcut [k] [style=cap]
+%D \defineshortcut [u] [style=type,command=\hyphenatedurl]
+%D
+%D \startlines
+%D test <ziezo> test
+%D test test <t:ziezo>
+%D test test <b:ziezo>
+%D test test <w:ziezo>
+%D zus<>zo zus<:>zo zus<::>zo
+%D test test <t:ziezo> dat (ziezo)
+%D test test <t::ziezo> dat (:ziezo)
+%D test test <t:ziezo:> dat (ziezo:)
+%D test test <t:zi:ezo:> dat (zi:ezo:)
+%D well, <u:http://www.pragma-ade.nl> looks fuzzy
+%D $10<20$
+%D \stoplines
+%D
+%D \defineshortcut [<>] [i] [style=\it]
+%D \defineshortcut [()] [b] [style=\bf]
+%D \defineshortcut [++] [s] [style=\sl]
+%D \defineshortcut [//] [u] [style=\underbars]
+%D \defineshortcut [--] [a] [style=\overstrike]
+%D
+%D \startlines
+%D it seems <i:to work> well
+%D it seems (b:to work) well
+%D it seems +s:to work+ well
+%D it seems /u:to work/ well
+%D it seems -a:to work- well
+%D \stoplines
+
+\def\defineshortcut
+ {\dotripleargument\dodefineshortcut}
+
+\def\dodefineshortcut[#1][#2][#3]%
+ {\ifthirdargument
+ \doifelsenothing{#1}
+ {\dododefineshortcut[<>][#2][#3]}
+ {\dododefineshortcut[#1][#2][#3]}%
+ \else\ifsecondargument
+ \dododefineshortcut[<>][#1][#2]%
+ \else
+ \dododefineshortcut[<>][][#1]%
+ \fi\fi}
+
+\def\dododefineshortcut[#1#2][#3][#4]% #1 is the trigger, #2 the delimiter/tag
+ {\doifundefined{\??te\??te\string#2}{\letvalue{\??te\??te\string#2}=#1}%
+ \defineactivecharacter #1 {\@EA\doshortcut\string#2} % we need to deactivate in math
+ \getparameters
+ [\??te\string#2#3]
+ [\c!commands=,\c!command=,\c!style=,\c!color=,#4]}
+
+\def\doshortcut#1%
+ {\ifmmode
+ \getvalue{\??te\??te#1}%
+ \else
+ \bgroup
+ \catcode`#1=\@@other
+ \def\dodoshortcut##1#1%
+ {\def\shorttag{\??te#1}%
+ \def\shortcut{##1}%
+ \dododoshortcut##1:\end}%
+ \@EA\dodoshortcut
+ \fi}
+
+\def\dododoshortcut#1:#2\end
+ {\doifelsenothing{#2}
+ {\doifundefinedelse{\shorttag\c!commands}
+ {\shortcut}
+ {\@EA\dodododoshortcut\@EA\shorttag\@EA:\shortcut:\end}}
+ {\doifundefinedelse{\shorttag#1\c!commands}
+ {\shortcut}
+ {\dodododoshortcut\shorttag#1:#2\end}}%
+ \egroup}
+
+\def\dodododoshortcut#1:#2:\end
+ {\getvalue{#1\c!commands}%
+ \doattributes{#1}\c!style\c!color{\getvalue{#1\c!command}{#2}}}
+
+%D \macros
+%D {setvariables,getvariable,getvariabledefault}
+%D
+%D \starttyping
+%D \setvariables[xx][title=]
+%D \setvariables[xx][title=test test]
+%D \setvariables[xx][title=test $x=1$ test] % fatal error reported
+%D \setvariables[xx][title=test {$x=1$} test]
+%D \setvariables[xx][title] % fatal error reported
+%D \setvariables[xx][titletitel=e]
+%D \stoptyping
+
+\def\??vars{@@vars}
+
+\def\setvariables {\dotripleargument\dosetvariables[\getrawparameters ]}
+\def\setevariables{\dotripleargument\dosetvariables[\getraweparameters]}
+\def\setgvariables{\dotripleargument\dosetvariables[\getrawgparameters]}
+\def\setxvariables{\dotripleargument\dosetvariables[\getrawxparameters]}
+
+\def\globalsetvariables % obsolete
+ {\dotripleargument\dosetvariables[\globalgetrawparameters]}
+
+\long\def\dosetvariables[#1][#2][#3]% tricky, test on s-pre-60
+ {\errorisfataltrue
+ \doifelse{#2}\currentvariableclass
+ {#1[\??vars:#2:][#3]}%
+ {\pushmacro\currentvariableclass
+ \def\currentvariableclass{#2}%
+ \getvariable{#2}\s!reset
+ #1[\??vars:#2:][#3]%
+ \getvariable{#2}\s!set
+ \popmacro\currentvariableclass}%
+ \errorisfatalfalse}
+
+\long\def\setvariable #1#2#3{\long\expandafter\def \csname\??vars:#1:#2\endcsname{#3}}
+\long\def\setevariable#1#2#3{\long\expandafter\edef\csname\??vars:#1:#2\endcsname{#3}}
+\long\def\setgvariable#1#2#3{\long\expandafter\gdef\csname\??vars:#1:#2\endcsname{#3}}
+\long\def\setxvariable#1#2#3{\long\expandafter\xdef\csname\??vars:#1:#2\endcsname{#3}}
+
+\def\getvariable#1#2%
+ {\csname
+ \ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi
+ \endcsname}
+
+\def\showvariable#1#2%
+ {\showvalue{\ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi}}
+
+\let\currentvariableclass\empty
+
+%D \macros
+%D {checkvariables}
+%D
+%D I'll probably forget that this on exists.
+
+\def\checkvariables
+ {\dodoubleargument\docheckvariables}
+
+\def\docheckvariables
+ {\dogetparameters\docheckrawvalue}
+
+\long\def\docheckrawvalue#1#2#3%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \edef\checkedrawvalue{\csname\??vars:#1:#2\endcsname}%
+ \ifx\checkedrawvalue\empty
+ \long\expandafter\def\csname\??vars:#1:#2\endcsname{#3}%
+ \fi
+ \else
+ \long\expandafter\def\csname\??vars:#1:#2\endcsname{#3}%
+ \fi}
+
+%D \macros
+%D {doifelsevariable,doifvariable,doifnotvariable}
+%D
+%D A few trivial macros:
+
+\def\doifelsevariable#1#2%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\doifvariable#1#2%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\doifnotvariable#1#2%
+ {\ifcsname\??vars:#1:#2\endcsname
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\def\getvariabledefault#1#2% #3% can be command, so no ifcsname here
+ {\executeifdefined{\??vars:#1:#2}}% {#3}
+
+% \def\setupenv{\dodoubleargument\rawgetparameters[\??en]}
+%
+% \def\doifenvelse#1{\doifdefinedelse{\??en#1}} % speed up
+% \def\doifenv #1{\doifdefined {\??en#1}} % speed up
+% \def\doifnotenv #1{\doifundefined {\??en#1}} % speed up
+%
+% \def\env#1{\csname\??en#1\endcsname}
+%
+% \def\envvar#1#2%
+% {\ifcsname\??en#1\endcsname
+% \csname\??en#1\endcsname\else#2%
+% \fi}
+%
+% low level change, now also accessible as \getvariable
+% {environment}{...}; the next macros will become obsolete
+% some day in favor of normal variables in the environment
+% namespace
+
+\def\s!environment{environment}
+
+\def\setupenv {\dotripleargument\dosetvariables[\getrawparameters][\s!environment]}
+\def\doifenvelse{\doifelsevariable \s!environment}
+\def\doifenv {\doifvariable \s!environment}
+\def\doifnotenv {\doifnotvariable \s!environment}
+\def\env {\getvariable \s!environment}
+\def\envvar {\getvariabledefault\s!environment}
+
+\protect \endinput
diff --git a/tex/context/base/core-fig.tex b/tex/context/base/core-fig.tex
index 714a85e49..63aa1d193 100644
--- a/tex/context/base/core-fig.tex
+++ b/tex/context/base/core-fig.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Figure Handling}
+\writestatus{loading}{ConTeXt Core Macros / Figure Handling}
\unprotect
@@ -491,8 +491,6 @@
\doglobal\beforesplitstring#3\at.\to\typesetfilename
\externalfigure[\typesetfilename.pdf][#2,#4]}
-\appendtoks \setupexternalfigures[\c!option=\v!empty] \to \everyfastmode
-
\setupexternalfigures
[\c!option=,
\c!object=\v!yes, % we only check for no
diff --git a/tex/context/base/core-fil.tex b/tex/context/base/core-fil.tex
index eda055a96..fca253a7b 100644
--- a/tex/context/base/core-fil.tex
+++ b/tex/context/base/core-fil.tex
@@ -11,54 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / File Support}
+\writestatus{loading}{ConTeXt Core Macros / File Support}
\unprotect
-% NOT YET DOCUMENTED !!
-%
-% overal \normalinput
-
-\startmessages dutch library: files
- title: files
- 1: file synoniem -- is al in gebruik voor --
-\stopmessages
-
-\startmessages english library: files
- title: files
- 1: file synonym -- is already used for --
-\stopmessages
-
-\startmessages german library: files
- title: files
- 1: Dateisynonym -- wird bereits fuer -- benutzt
-\stopmessages
-
-\startmessages czech library: files
- title: soubory
- 1: synonymum souboru -- je jiz pouzito pro --
-\stopmessages
-
-\startmessages italian library: files
- title: file
- 1: sinonimo file -- già in uso per --
-\stopmessages
-
-\startmessages norwegian library: files
- title: filer
- 1: filesynonym -- er allerede brukt for --
-\stopmessages
-
-\startmessages romanian library: files
- title: fisiere
- 1: sinonimul fisierelor -- este folosit deja pentru --
-\stopmessages
-
-\startmessages french library: files
- title: fichiers
- 1: le synonyme de fichier -- est déjà utilisé pour --
-\stopmessages
-
%D Files registered as temporary files will be deleted after a
%D run by texexec:
@@ -100,6 +56,8 @@
%D \usemodules[pictex,chemie,unit]
%D \stoptyping
+% will be redone in mkiv
+
\def\definefilesynonym
{\dodoubleempty\dodefinefilesynonym}
@@ -207,6 +165,7 @@
{\dododousemodules{#1-}{#2}}%
\ifconditional\moduleisloaded\else
\showmessage\m!systems6{#2}%
+ \appendtoks\showmessage\m!systems6{#2}\to\everynotabene
\fi}
% \def\usemodules
@@ -254,7 +213,7 @@
\let\currentmodule \s!unknown
\def\startmodule
- {\doifnextcharelse[\dostartmodule\nostartmodule}
+ {\doifnextoptionalelse\dostartmodule\nostartmodule}
\def\nostartmodule #1 %
{\dostartmodule[#1]}
@@ -339,7 +298,7 @@
% The following filenames are defined here:
\def\TEXbufferfile #1{\bufferprefix#1.\f!temporaryextension}
-\def\MPgraphicfile {\bufferprefix mp\ifMPrun run\else graph\fi}
+\def\MPgraphicfile {\bufferprefix mp\ifMPrun run\else graph\fi} % not needed in luatex
\def\convertMPcolorfile{\bufferprefix metacmyk.tmp}
%D To save memory, we implement some seldomly used commands
@@ -373,9 +332,6 @@
\let\checkpreprocessor\relax
-% \appendtoks\relax{\appendtoks \checkpreprocessor \to \everyjob}\to\everydump
-\appendtoks\everyjob\expandafter{\the\everyjob\checkpreprocessor}\to\everydump
-
%D To be documented and probably moved
\def\documentresources{\@@erurl}
diff --git a/tex/context/base/core-fld.tex b/tex/context/base/core-fld.mkii
index 3b1ce9b3f..2b177c916 100644
--- a/tex/context/base/core-fld.tex
+++ b/tex/context/base/core-fld.mkii
@@ -2,7 +2,7 @@
%D [ file=core-fld,
%D version=1997.05.18,
%D title=\CONTEXT\ Core Macros,
-%D subtitle=Fill in fields,
+%D subtitle=Fields,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -20,7 +20,7 @@
% internal string truncated, (3) second time truncated
% string is sent.
-\writestatus{loading}{Context Field Macros}
+\writestatus{loading}{ConTeXt Core Macros / Fields}
% messages
diff --git a/tex/context/base/core-fld.mkiv b/tex/context/base/core-fld.mkiv
new file mode 100644
index 000000000..96ecf6b54
--- /dev/null
+++ b/tex/context/base/core-fld.mkiv
@@ -0,0 +1,1079 @@
+%D \module
+%D [ file=core-fld,
+%D version=1997.05.18,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Fields,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \appendtocommalist versus \addtocommalist
+%
+% * as default trigger in radiofields ?
+%
+% beware: weblink plugin truncates on length, while save as doesn't;
+% more precise: (1) first time right string is sent, (2)
+% internal string truncated, (3) second time truncated
+% string is sent.
+
+\writestatus{loading}{ConTeXt Core Macros / Fields}
+
+% messages
+
+\definemessageconstant{fields}
+
+\unprotect
+
+%D First we hook fields into the (viewer based) layering mechanism
+%D (implemented as properties).
+
+\ifx\currentlayerproperty\undefined\else \let\currentlayerproperty\empty\fi
+
+\appendtoks
+ \doif\@@iafieldlayer\v!auto
+ {\def\@@iafieldlayer{\currentlayerproperty}}%
+\to \everysetupinteraction
+
+\setupinteraction
+ [\c!fieldlayer=\v!auto] % auto by default
+
+%D Internal command, linked to \type{\definesymbol}.
+
+\def\dogetfieldsymbol#1%
+ {\getobject{SYM}{#1}}
+
+\def\dopresetfieldsymbol#1%
+ {\doifobjectfoundelse{SYM}{#1}
+ {}
+ {\settightobject{SYM}{#1}\hbox{\symbol[#1]}%
+ \flushatshipout
+ {\setbox0\hbox{\hskip-\maxdimen\getobject{SYM}{#1}}%
+ \smashbox0\box0}}}
+
+\def\presetfieldsymbols[#1]% slow
+ {\def\dopresetfieldsymbols##1%
+ {\processcommalist[##1]\dopresetfieldsymbol}%
+ \@EA\processcommalist\@EA[#1]\dopresetfieldsymbols}
+
+\def\definedefaultsymbols
+ {\definesymbol[defaultyes][$\times$]%
+ \definesymbol[defaultno][$\cdot$]}
+
+\def\resetfieldsymbol[#1]% for experimental usage only
+ {\resetobject{SYM}{#1}}
+
+%D The interface to the specials. DEFAULT NOG ANDERS
+
+\def\preparefieldvariables % evt \def's at the outer level (test) or \edef's here for fast testing
+ {\let\@@DriverFieldNumber \@@fdn
+ \let\@@DriverFieldStyle \@@fdstyle
+ \let\@@DriverFieldColor \@@fdcolor
+ \let\@@DriverFieldBackgroundColor\@@fdfieldbackgroundcolor
+ \let\@@DriverFieldFrameColor \@@fdfieldframecolor
+ \let\@@DriverFieldLayer \@@fdfieldlayer
+ \let\@@DriverFieldOption \@@fdoption
+ \let\@@DriverFieldAlign \@@fdalign
+ \let\@@DriverFieldClickIn \@@fdclickin
+ \let\@@DriverFieldClickOut \@@fdclickout
+ \let\@@DriverFieldRegionIn \@@fdregionin
+ \let\@@DriverFieldRegionOut \@@fdregionout
+ \let\@@DriverFieldAfterKey \@@fdafterkey
+ \let\@@DriverFieldFormat \@@fdformat
+ \let\@@DriverFieldValidate \@@fdvalidate
+ \let\@@DriverFieldCalculate \@@fdcalculate
+ \let\@@DriverFieldFocusIn \@@fdfocusin
+ \let\@@DriverFieldFocusOut \@@fdfocusout}
+
+% todo : remove arguments, consider DriverField a namespace
+
+\def\presetlinefield
+ {\preparefieldvariables
+ \dopresetlinefield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldNumber}
+ {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldAlign}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presettextfield
+ {\preparefieldvariables
+ \dopresettextfield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldNumber}
+ {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldAlign}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetchoicefield
+ {\preparefieldvariables
+ \dopresetchoicefield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldValues}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetpopupfield
+ {\preparefieldvariables
+ \dopresetpopupfield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldValues}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetcombofield
+ {\preparefieldvariables
+ \dopresetcombofield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldStyle,\@@DriverFieldColor,\@@DriverFieldBackgroundColor,\@@DriverFieldFrameColor}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldValues}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetcheckfield
+ {\preparefieldvariables
+ \presetfieldsymbols[\@@DriverFieldValues]%
+ \dopresetcheckfield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldValues}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetpushfield
+ {\preparefieldvariables
+ %\edef\@@DriverFieldValues{{\@@DriverFieldValues}}% makes sure {a,b,c} is passed
+ \presetfieldsymbols[\@@DriverFieldValues]%
+ \dopresetpushfield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldValues}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetradiofield
+ {\preparefieldvariables
+ \presetfieldsymbols[\@@DriverFieldValues]%
+ \dopresetradiofield
+ {\@@DriverFieldName}
+ {\@@DriverFieldWidth}
+ {\@@DriverFieldHeight}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldRoot}
+ {\@@DriverFieldValues}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\presetradiorecord
+ {\preparefieldvariables
+ \dopresetradiorecord
+ {\@@DriverFieldName}
+ {\@@DriverFieldDefault}
+ {\@@DriverFieldOption}
+ {\@@DriverFieldKids}
+ {\@@DriverFieldClickIn,\@@DriverFieldClickOut,\@@DriverFieldRegionIn,\@@DriverFieldRegionOut,%
+ \@@DriverFieldAfterKey,\@@DriverFieldFormat,\@@DriverFieldValidate,\@@DriverFieldCalculate,%
+ \@@DriverFieldFocusIn,\@@DriverFieldFocusOut}}
+
+\def\setfieldmodes#1#2#3%
+ {\xdef\@@DriverFieldMode{#1}% % 0 1 2 3
+ \xdef\@@DriverFieldFree{#2}% % 0 1
+ \xdef\@@DriverFieldAuto{#3}} % 0 1
+
+\newevery\everysetfield\relax
+
+\def\doiffieldelse#1{\doifdefinedelse{fielddata#1}}
+
+\def\setfield#1#2#3#4#5#6#7#8#9%
+ {\bgroup
+ \doglobal\increment\numberoffields
+ \iftracefields
+ \doglobal\addtocommalist{#1}\collectedfields
+ \fi
+ \the\everysetfield
+ \setxvalue{fielddata#1}% kortere tag #7 needs expansion etc
+ {\noexpand\dosetfield{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}%
+ \egroup}
+
+\def\dosetfield#1#2#3#4#5#6#7#8#9%
+ {\xdef\@@DriverFieldName {#1}%
+ \xdef\@@DriverFieldType {#2}%
+ \xdef\@@DriverFieldRoot {#3}%
+ \xdef\@@DriverFieldParent {#4}%
+ \xdef\@@DriverFieldKids {#5}%
+ \xdef\@@DriverFieldGroup {#6}%
+ \setfieldmodes #7%
+ \bgroup
+ \def\par{\string\n\string\n}%
+ \xdef\@@DriverFieldValues {#8}%
+ \xdef\@@DriverFieldDefault{#9}%
+ \egroup}
+
+\def\changefield#1%
+ {\setfield{#1}\@@DriverFieldType\@@DriverFieldRoot\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldGroup
+ {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}\@@DriverFieldValues\@@DriverFieldDefault}
+
+\def\getfield#1% name
+ {\doifundefinedelse{fielddata#1}
+ {\dosetfield{#1}\empty\empty\empty\empty\empty{\empty00}\empty\empty}
+ {\getvalue{fielddata#1}}}
+
+\newif\iftracefields \tracefieldsfalse
+
+\let\tracefields\tracefieldstrue
+
+\def\doshowfields[#1]% todo: tabulate van maken en runtime
+ {\bgroup
+ \switchtobodyfont[8pt,tt]%
+ \doifsomething{#1}{\def\collectedfields{#1}}%
+ \ifx\collectedfields\empty
+ \par specify [fieldlist] or say \type{\tracefieldstrue} first\par
+ \else
+ \def\normalizedfieldmode##1##2##3%
+ {\ifcase0##2 \else\sl\fi
+ \ifcase0##1 loner\or parent\or clone\or copy\fi}%
+ \def\dosetfield##1##2##3##4##5##6##7##8##9%
+ {##1&##2&##3&##4&##5&##6&\normalizedfieldmode##7&##8&##9\cr}%
+ \halign
+ {&##\strut\hss\quad\cr
+ \noalign{\hrule}%
+ NAME &TYPE &ROOT &
+ PARENT&KIDS &GROUP &
+ MODE &VALUES&DEFAULT\cr
+ \noalign{\hrule}%
+ \@EA\globalprocesscommalist\@EA[\collectedfields]\getfield
+ \noalign{\hrule}}%
+ \fi
+ \egroup}
+
+\def\showfields
+ {\dosingleempty\doshowfields}
+
+\def\dologfields[#1]%
+ {\bgroup
+ \immediate\openout\scratchwrite=fields.log
+ \doifsomething{#1}{\def\collectedfields{#1}}%
+ \ifx\colledtedfields\empty
+ \immediate\write\scratchwrite{use \tracefieldstrue}%
+ \else
+ \def\normalizedfieldmode##1##2##3%
+ {\edef\@@DriverFieldMode
+ {\ifcase##1 loner \or parent \or clone \or copy \fi
+ \ifcase##2 \else(done)\fi}}%
+ \def\dosetfield##1##2##3##4##5##6##7##8##9%
+ {\normalizedfieldmode##7%
+ \immediate\write\scratchwrite
+ {N=##1 / T=##2 / R=##3 / P=##4 / K=##5 / G=##6 /
+ M=\@@DriverFieldMode\space/ V=##8 / D=##9}}%
+ \processcommacommand[\collectedfields]\getfield
+ \fi
+ \immediate\closeout\scratchwrite
+ \egroup}
+
+\def\logfields
+ {\dosingleempty\doLogFields}
+
+%D \starttyping
+%D \definefield [name] [type] [group] [values] [default]
+%D
+%D \definefield [WWWW] [text] [textsetup] [default text]
+%D \definefield [XXXX] [push] [pushsetup] [yes,no] [yes]
+%D \definefield [XXXX] [check] [checksetup] [yes,no] [yes]
+%D \definefield [YYYY] [combo] [combosetup] [a,b,c,d] [b]
+%D \definefield [ZZZZ] [radio] [radiosetup] [W,X,Y,Z] [Y]
+%D
+%D \definesubfield [W] [subsetup] [p,q]
+%D \definesubfield [X,Y] [subsetup] [p,r]
+%D \definesubfield [Z] [subsetup] [y,z]
+%D
+%D evt \definemainfield ... wanneer geplaatst voor subs gegeven
+%D
+%D \clonefield [XXXX] [XX,YY] [mysetup] [on,off]
+%D \clonefield [Z] [AA,BB] [somesetup] [true,false]
+%D \clonefield [Z] [CC,DD] [anothersetup]
+%D
+%D \copyfield [XXXX] [PP,QQ,RR]
+%D
+%D \field[XXXX]
+%D \fitfield[XXXX]
+%D \stoptyping
+
+\newif\ifdefinemainfield \definemainfieldfalse
+
+%D We need to keep track of cloned (related) fields and so by
+%D maintaining lists of field clones.
+%D
+%D The first alternative used a two pass data list and was
+%D implemented as follows:
+%D
+%D \starttyping
+%D \def\getmainfieldkids#1%
+%D {\let\@@DriverFieldKids\empty
+%D \ifdefinemainfield
+%D \definetwopasslist{fld:#1}% defined by system
+%D \doloop
+%D {\gettwopassdata{fld:#1}%
+%D \iftwopassdatafound
+%D %\addtocommalist\twopassdata\@@DriverFieldKids
+%D \appendtocommalist\twopassdata\@@DriverFieldKids
+%D \else
+%D \exitloop
+%D \fi}%
+%D \fi}
+%D \stoptyping
+%D
+%D However, the next alternative is much faster when we have
+%D a field with thousands of clones, something not that
+%D imaginary.
+%D
+%D \starttyping
+%D \def\getmainfieldkids#1%
+%D {\let\@@DriverFieldKids\empty
+%D \ifdefinemainfield
+%D \definetwopasslist{fld:#1}% runtime defined by system
+%D \getnamedtwopassdatalist{fld:#1}\@@DriverFieldKids
+%D \fi}
+%D \stoptyping
+%D
+%D The data is written by file using:
+%D
+%D \starttyping
+%D \newcounter\nofmainfieldkids
+%D
+%D \def\setmainfieldkid#1#2%
+%D {\doglobal\increment\nofmainfieldkids
+%D \savetwopassdata{fld:#1}{\nofmainfieldkids}{#2}}
+%D \stoptyping
+%D
+%D The trade of of this mechanism is that for each cloned or
+%D copied field, the uitlity file is to be read in order to
+%D fetch the data.
+%D
+%D The next, much faster alternative uses a dedicated %
+%D reference mechanism.
+
+\def\setmainfieldkid#1#2%
+ {\immediatewriteutilitycommand{\fieldreference{#1}{#2}}}
+
+\def\checkfieldreferences
+ {\startnointerference
+ \protectlabels
+ \doutilities{fieldreferences}\jobname\empty\relax\relax
+ \global\let\checkfieldreferences\relax
+ \stopnointerference}
+
+\def\setfieldreferences
+ {\def\fieldreference##1##2%
+ {\ifundefined{\r!widget##1}%
+ \setxvalue{\r!widget##1}{##2}%
+ \else
+ \edef\!!stringa{\getvalue{\r!widget##1}}%
+ \setxvalue{\r!widget##1}{\!!stringa,##2}%
+ \fi}}
+
+\def\resetfieldreferences
+ {\let\fieldreference\gobbletwoarguments}
+
+\def\getmainfieldkids#1%
+ {\checkfieldreferences
+ \ifdefinemainfield
+ \doifundefinedelse{\r!widget#1}%
+ {\let\@@DriverFieldKids\empty}
+ {\@EA\let\@EA\@@DriverFieldKids\csname\r!widget#1\endcsname}%
+ \else
+ \let\@@DriverFieldKids\empty
+ \fi}
+
+\resetfieldreferences
+
+%D Of course it costs a few more tokens to implement, but it's
+%D worth the memory: running for instance the 2000 page
+%D english examns publishing on demand document went down from
+%D 1350 seconds to less than 950 on a 650 Mhz pentium.
+
+\def\definefield
+ {\definemainfieldfalse\doquintupleempty\dodefinefield}
+
+\def\definemainfield
+ {\definemainfieldtrue \doquintupleempty\dodefinefield}
+
+\let\collectedfields\empty
+\newcounter\numberoffields
+\newcounter\totalnumberoffields
+
+\def\savenumberoffields
+ {\ifcase\numberoffields\relax\else
+ \savecurrentvalue\totalnumberoffields\numberoffields
+ \fi}
+
+\appendtoks \savenumberoffields \to \everybye % \everylastshipout
+
+% \def\presetfieldreferences
+% {\ifnum\totalnumberoffields>0
+% \definereference[AtOpenInitializeForm][\v!ResetForm]%
+% \fi}
+%
+% \definereference[AtOpenInitializeForm][\v!geen]
+%
+% \appendtoks \presetfieldreferences \to \everycheckreferences
+
+\def\dodefinefield[#1][#2][#3][#4][#5]%
+ {\ifsecondargument
+ \edef\currentfieldname{#1}% just in case we're inside a loop
+ \doifundefinedelse{define#2field}
+ {\writestatus\m!fields{unknown field type #2}}
+ {\doifundefined{fielddata\currentfieldname}
+ {\getmainfieldkids\currentfieldname
+ \ifdefinemainfield
+ \ifx\@@DriverFieldKids\empty
+ \let\@@DriverFieldMode\fieldlonermode
+ \else
+ \let\@@DriverFieldMode\fieldparentmode
+ \fi
+ \def\@@DriverFieldAuto{1}%
+ \else
+ \let\@@DriverFieldMode\fieldlonermode
+ \def\@@DriverFieldAuto{0}%
+ \fi
+ \def\@@DriverFieldFree{0}%
+ \getvalue{define#2field}{\currentfieldname}{#2}{#3}{#4}{#5}}}%
+ \else
+ \writestatus\m!fields{pass fieldname and fieldtype}%
+ \fi}
+
+\def\definelinefield#1#2#3#4#5%
+ {\setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{#4}}
+
+\let\definetextfield=\definelinefield
+
+\def\definechoicefield#1#2#3#4#5%
+ {\doifelsenothing{#4}
+ {\def\@@DriverFieldValues{yes,no}}
+ {\def\@@DriverFieldValues{#4}}%
+ \doifelsenothing{#5}
+ {\dogetcommacommandelement2\from\@@DriverFieldValues \to\@@DriverFieldDefault
+ \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault}
+ {\def\@@DriverFieldDefault{#5}}%
+ \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}}
+
+\let\definepopupfield=\definechoicefield
+\let\definecombofield=\definechoicefield
+
+%\def\definecheckfield#1#2#3#4#5%
+% {\doifelsenothing{#4}
+% {\definedefaultsymbols
+% \def\@@DriverFieldValues{defaultyes}}
+% {\def\@@DriverFieldValues{#4}}%
+% \doifelsenothing{#5}
+% {\dogetcommacommandelement2\from\@@DriverFieldValues\to\@@DriverFieldDefault
+% \dogetcommacommandelement1\from\@@DriverFieldDefault\to\@@DriverFieldDefault}
+% {\def\@@DriverFieldDefault{#5}}%
+% \setfield{#1}{#2}{}{}{\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{\@@DriverFieldValues}{\@@DriverFieldDefault}}
+
+%D Since these fields have an on/off state only, we pass 1/0
+%D to the driver as default values.
+
+\def\definecheckfield#1#2#3#4#5%
+ {\doifelsenothing{#4}
+ {\definedefaultsymbols
+ \def\@@DriverFieldValues{defaultyes}}
+ {\def\@@DriverFieldValues{#4}}%
+ \doifelsenothing{#5}
+ {\def\@@DriverFieldDefault{2}}
+ {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldDefault
+ \doifinstringelse{#5}{\@@DriverFieldDefault}
+ {\def\@@DriverFieldDefault{1}}
+ {\def\@@DriverFieldDefault{0}}}%
+ \setfield
+ {#1}{#2}{}{}{\@@DriverFieldKids}{#3}%
+ {\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}%
+ {\@@DriverFieldValues}{\@@DriverFieldDefault}}
+
+\let\definepushfield=\definecheckfield
+
+\def\defineradiofield#1#2#3#4#5%
+ {\iffourthargument
+ \doifelsenothing{#5}
+ {\dogetcommacommandelement1\from#4\to\SavedFieldDefault
+ \dogetcommacommandelement1\from\SavedFieldDefault\to\SavedFieldDefault}
+ {\def\SavedFieldDefault{#5}}%
+% when opt works
+% \@EA\beforesplitstring\SavedFieldDefault\at=>\to\SavedFieldDefault
+ \ifx\@@DriverFieldKids\empty
+ \setfield{#1}{#2}{}{}{#4}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}%
+ \else
+ \setfield{#1}{#2}{}{}{#4,\@@DriverFieldKids}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\SavedFieldDefault}%
+ \fi
+%
+ \def\docommand##1%
+ {\doifelse{##1}\SavedFieldDefault
+ {\def\@@DriverFieldDefault{##1}}%
+ {\let\@@DriverFieldDefault\empty}%
+ \setfield{##1}{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}%
+% when opt works
+% \def\docommand##1%
+% {\@EA\beforesplitstring##1\at=>\to\FieldValue
+% \doifelse\FieldValue\SavedFieldDefault
+% {\let\@@DriverFieldDefault\FieldValue}%
+% {\let\@@DriverFieldDefault\empty}%
+% \setfield\FieldValue{#2}{#1}{}{}{#3}{\@@DriverFieldMode\@@DriverFieldFree\@@DriverFieldAuto}{}{\@@DriverFieldDefault}}%
+ \processcommalist[#4]\docommand
+ \else
+ \writestatus\m!fields{pass values too}%
+ \fi}
+
+\def\definesubfield
+ {\dotripleempty\dodefinesubfield}
+
+\def\dodefinesubfield[#1][#2][#3]% for the moment only radio ones
+ {\ifsecondargument
+ \def\docommand##1%
+ {\getfield{##1}%
+ \ifx\@@DriverFieldType\empty
+ \writestatus\m!fields{unknown field ##1}% to do
+ \else
+ \doifsomething{#2}
+ {\edef\@@DriverFieldGroup{#2}}%
+ \doifelsenothing{#3}
+ {\definedefaultsymbols
+ \def\@@DriverFieldValues{defaultyes}}
+ {\def\@@DriverFieldValues{#3}}%
+ \changefield{##1}%
+ \fi}%
+ \processcommalist[#1]\docommand
+ \else
+ \writestatus\m!fields{pass fieldname, setupgroup, values and default}%
+ \fi}
+
+\def\doclonefield[#1][#2][#3][#4]% parent children setupgroup values
+ {\ifsecondargument
+ \getfield{#1}%
+\iftrialtypesetting\else
+ \ifx\@@DriverFieldType\empty
+ \writestatus\m!fields{unknown field #1}%
+ \else
+ \let\@@DriverFieldMode\fieldparentmode
+ %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}%
+ \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}%
+ \processcommalist[#2]\docommand
+ \changefield{#1}%
+ \let\@@DriverFieldAutoParent\@@DriverFieldAuto
+ \def\@@DriverFieldParent{#1}%
+ \let\@@DriverFieldKids\empty
+ \let\@@DriverFieldRoot\empty
+ \let\@@DriverFieldMode\fieldchildmode
+ \def\@@DriverFieldFree{0}%
+ \def\@@DriverFieldAuto{0}%
+ \doifsomething{#3}{\edef\@@DriverFieldGroup{#3}}%
+ \doifsomething{#4}{\edef\@@DriverFieldValues{#4}}%
+ \def\docommand##1%
+ {\ifcase\@@DriverFieldAutoParent\else
+ \setmainfieldkid{\@@DriverFieldParent}{##1}%
+ \fi
+ \changefield{##1}}%
+ \processcommalist[#2]\docommand
+ \fi
+\fi
+ \else
+ \writestatus\m!fields{pass parent field and clones}%
+ \fi}
+
+\def\clonefield
+ {\doquadrupleempty\doclonefield}
+
+\def\docopyfield[#1][#2]% parent children
+ {\ifsecondargument
+ \getfield{#1}%
+\iftrialtypesetting\else
+ \ifx\@@DriverFieldType\empty
+ \writestatus\m!fields{unknown field #1}%
+ \else
+ \let\@@DriverFieldMode\fieldparentmode
+ %\def\docommand##1{\addtocommalist{##1}\@@DriverFieldKids}%
+ \def\docommand##1{\appendtocommalist{##1}\@@DriverFieldKids}%
+ \processcommalist[#2]\docommand
+ \changefield{#1}%
+ \let\@@DriverFieldAutoParent\@@DriverFieldAuto
+ \def\@@DriverFieldParent{#1}%
+ \let\@@DriverFieldKids\empty
+ \let\@@DriverFieldRoot\empty
+ \let\@@DriverFieldMode\fieldcopymode
+ \def\@@DriverFieldFree{0}%
+ \def\@@DriverFieldAuto{0}%
+ \def\docommand##1%
+ {\ifcase\@@DriverFieldAutoParent\else
+ \setmainfieldkid{\@@DriverFieldParent}{##1}%
+ \fi
+ \changefield{##1}}%
+ \processcommalist[#2]\docommand
+ \fi
+\fi
+ \else
+ \writestatus\m!fields{pass parent field and copies}%
+ \fi}
+
+\def\copyfield{\dodoubleempty\docopyfield}
+
+\unexpanded\def\field {\dotripleempty\dofield[\dohandlefield]}
+\unexpanded\def\fitfield{\dotripleempty\dofield[\dohandlefitfield]}
+
+\def\dofield[#1][#2][#3]%
+ {\iffirstargument
+ \bgroup
+ \getfield{#2}%
+ \ifsecondargument
+ \def\@@DriverFieldLabel{#3}%
+ \else
+ \let\@@DriverFieldLabel\@@DriverFieldName
+ \fi
+ \ifx\@@DriverFieldType\empty
+ \writestatus\m!fields{unknown field #2}%
+ \else\ifcase\@@DriverFieldFree\relax
+ \doifdefinedelse{\strippedcsname\setupfield\@@DriverFieldGroup}
+ {\let\dosetupfield=#1\getvalue{\strippedcsname\setupfield\@@DriverFieldGroup}}
+ {#1[\@@DriverFieldName][\v!label,\v!frame,\v!horizontal][][][]}%
+\iftrialtypesetting\else
+ \def\@@DriverFieldFree{1}%
+ \changefield{#2}%
+\fi
+ \else\ifcase\@@DriverFieldAuto\relax
+ % \writestatus\m!fields{field #2 already typeset}%
+ \else
+ % \writestatus\m!fields{field #2 automatically copied}%
+ \nextsystemfield
+ \copyfield[\@@DriverFieldName][\currentsystemfield]%
+ \dotripleempty\dofield[#1][\currentsystemfield][#3]% get the if's right
+ \fi\fi\fi
+ \egroup
+ \fi}
+
+\def\typesetfield
+ {\useJSscripts[fld]%
+ \ifx\@@DriverFieldRoot\empty \else
+ \let\@@SavedFieldName\@@DriverFieldName
+ \getfield\@@DriverFieldRoot
+ \ifcase\@@DriverFieldFree\relax
+ \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot
+ \dopresetrecord
+\iftrialtypesetting\else
+ \def\@@DriverFieldFree{1}%
+ \changefield\@@DriverFieldName
+\fi
+ \fi
+ \getfield\@@SavedFieldName
+ \fi
+ \ifx\@@DriverFieldKids\empty
+ \donefalse
+ \else
+ \donetrue
+ \fi
+ \ifdone
+ \let\@@DriverFieldParent\@@DriverFieldName
+ %\addtocommalist\@@DriverFieldParent\@@DriverFieldKids
+ \appendtocommalist\@@DriverFieldParent\@@DriverFieldKids
+ \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot
+ \dopresetfield
+ \let\@@DriverFieldMode\fieldchildmode
+ \fi
+ \dosetfieldstatus\@@DriverFieldMode\@@DriverFieldParent\@@DriverFieldKids\@@DriverFieldRoot
+ \dopresetfield}
+
+\def\dopresetfield
+ {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType field}\fi\fi}
+
+\def\dopresetrecord
+ {\iftrialtypesetting\else\iflocation\getvalue{preset\@@DriverFieldType record}\fi\fi}
+
+\def\dodefinethefieldset[#1][#2]%
+ {\dodefinefieldset{#1}{#2}}
+
+\def\definefieldset%
+ {\dodoubleargument\dodefinethefieldset}
+
+\def\normaldodosetupfield[#1][#2][#3][#4][#5]%
+ {\doifdefinedelse{\strippedcsname\setupfield#1}
+ {\pushmacro\dosetupfield
+ \def\dosetupfield[##1][##2][##3][##4][##5]%
+ {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][##2,#2][##3,#3][##4,#4][##5,#5]}}%
+ \getvalue{\strippedcsname\setupfield#1}%
+ \popmacro\dosetupfield}
+ {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}}}
+
+\let\dodosetupfield\normaldodosetupfield
+
+\def\donosetupfield[#1][#2][#3][#4][#5]%
+ {\setvalue{\strippedcsname\setupfield#1}{\dosetupfield[#1][#2][#3][#4][#5]}}
+
+\def\dosetupfield[#1][#2][#3][#4][#5]%
+ {\iffifthargument
+ \def\docommand##1{\dodosetupfield[##1][#2][#3][#4][#5]}%
+ \processcommalist[#1]\docommand
+ \else\ifthirdargument
+ \def\docommand##1{\dodosetupfield[##1][#2][][][#3]}%
+ \processcommalist[#1]\docommand
+ \else\ifsecondargument
+ \doifelse{#2}\v!reset
+ {\def\docommand##1{\donosetupfield[#1][][][][]}}
+ {\def\docommand##1{\dodosetupfield[##1][][][][#2]}}%
+ \processcommalist[#1]\docommand
+ \else\iffirstargument
+ \def\docommand##1{\dodosetupfield[##1][][][][]}%
+ \processcommalist[#1]\docommand
+ \else
+ \writestatus\m!fields{provide either 1, 2, 3 or 5 arguments}%
+ \fi\fi\fi\fi}
+
+\def\setupfield
+ {\doquintupleempty\dosetupfield}
+
+\def\dosetupfields[#1][#2][#3][#4]%
+ {\ifsecondargument
+ \def\dodosetupfield[##1][##2][##3][##4][##5]%
+ {\doifdefinedelse{\strippedcsname\setupfield##1}
+ {\def\dosetupfield[####1][####2][####3][####4][####5]%
+ {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,####2,##2][#2,####3,##3][#3,####4,##4][#4,####5,##5]}}%
+ \getvalue{\strippedcsname\setupfield##1}}
+ {\setvalue{\strippedcsname\setupfield##1}{\dosetupfield[##1][#1,##2][#2,##3][#3,##4][#4,##5]}}}%
+ \else\iffirstargument
+ \doifelse{#1}\v!reset
+ {\resetfields}
+ {\setupfields[][][][#1]}% checken
+ \else
+ \writestatus\m!fields{provide either 1 or 4 arguments}%
+ \fi\fi}
+
+\def\setupfields
+ {\doquadrupleempty\dosetupfields}
+
+\def\resetfields
+ {\let\dodosetupfield\normaldodosetupfield}
+
+% \setupfields[\v!reset]
+
+% opties: veld, label, kader, vertikaal/horizontaal
+
+\newif\ifShowFieldLabel
+\newif\ifShowFieldFrame
+\newif\ifVerticalField
+\newif\ifHorizontalField
+
+% way to slow/complicated, we need some simple alternative
+% as well
+
+\def\dohandlefield[#1][#2][#3][#4][#5]%
+ {\presetlocalframed[\??fd]%
+ \processallactionsinset
+ [#2]
+ [ \v!reset=>\ShowFieldLabelfalse\ShowFieldFramefalse
+ \HorizontalFieldfalse\VerticalFieldfalse,
+ \v!label=>\ShowFieldLabeltrue,
+ \v!frame=>\ShowFieldFrametrue,
+ \v!horizontal=>\HorizontalFieldtrue,
+ \v!vertical=>\VerticalFieldtrue]%
+ \ifVerticalField
+ \getparameters[\??fd]
+ [\c!distance=\!!zeropoint,\c!inbetween=\vskip\@@localoffset,
+ \c!align=\v!right,\c!width=20em]%
+ \else\ifHorizontalField
+ \getparameters[\??fd]
+ [\c!distance=\@@localoffset,\c!inbetween=,\c!align=\c!left,
+ \c!height=10ex]%
+ \else
+ \getparameters[\??fd]
+ [\c!distance=\!!zeropoint,\c!inbetween=,\c!align=\c!left]%
+ \fi\fi
+ \getparameters[\??fd]
+ [\c!n=,\c!before=,\c!after=\vss,\c!style=,\c!color=,#3]%
+ \reshapeframeboxfalse % else ugly spacing
+ \ifShowFieldFrame
+ \localframed[\??fd][\c!strut=\v!no,\c!align=]\bgroup
+ \else
+ \vbox\bgroup
+ \fi
+ \dontcomplain
+ \ifShowFieldLabel
+ \setbox0\hbox
+ {\reshapeframeboxtrue % else wrong dimensions
+ \framed
+ [\c!style=,\c!color=,\c!align=\c!right,#4]
+ {\@@DriverFieldLabel}}%
+ \fi
+ \setbox2\hbox
+ {\reshapeframeboxtrue % else wrong dimensions
+ \ifVerticalField
+ \setupframed[\c!height=6ex,\c!width=\hsize]%
+ \else\ifHorizontalField
+ \setupframed[\c!height=\vsize,\c!width=20em]%
+ \else
+ \setupframed[\c!height=2cm,\c!width=2cm]%
+ \fi\fi
+ \framed
+ [\c!align=\v!right,\c!strut=\v!no,#5]
+ {\getparameters
+ [\??fd]
+ [\c!color=,\c!style=,\c!align=\v!right,\c!option=,
+ \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=,
+ \c!afterkey=,\c!format=,\c!validate=,\c!calculate=,
+ \c!focusin=,\c!focusout=,
+ \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=,
+ \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5]%
+ \scratchdimen\framedwidth \edef\@@DriverFieldWidth {\the\scratchdimen}%
+ \scratchdimen\framedheight\edef\@@DriverFieldHeight{\the\scratchdimen}%
+ \vfill
+ \hbox{\lower\@@fdfieldoffset\hbox{\typesetfield}}
+ \vss}}%
+ \ifShowFieldLabel
+ \ifVerticalField
+ \vbox
+ {\copy0
+ \@@fdinbetween
+ \copy2}%
+ \else
+ \hbox
+ {\vbox \ifdim\ht2>\ht0 to \ht2 \fi
+ {\@@fdbefore
+ \copy0
+ \@@fdafter}%
+ \hskip\@@fddistance
+ \vbox \ifdim\ht0>\ht2 to \ht0 \fi
+ {\@@fdbefore
+ \box2
+ \@@fdafter}}%
+ \fi
+ \else
+ \box2
+ \fi
+ \egroup}
+
+\chardef\fitfieldmode\plusone % 3 = best
+
+\def\dohandlefitfield[#1][#2][#3][#4][#5]% alleen check
+ {\presetlocalframed[\??fd]%
+ \localframed
+ [\??fd]
+ [\c!n=1024, % beware: weblink plug in truncates
+ \c!strut=\v!no,\c!color=,\c!style=,\c!option=,
+ \c!clickin=,\c!clickout=,\c!regionin=,\c!regionout=,
+ \c!focusin=,\c!focusout=,
+ \c!afterkey=,\c!format=,\c!validate=,\c!calculate=,
+ \c!fieldoffset=\!!zeropoint,\c!fieldbackgroundcolor=,
+ \c!fieldframecolor=,\c!fieldlayer=\@@iafieldlayer,#5,\c!align=]
+ {\dogetcommacommandelement1\from\@@DriverFieldValues\to\@@DriverFieldValue
+ \ifx\@@DriverFieldValue\empty
+ \let\@@DriverFieldValue\@@DriverFieldDefault
+ \fi
+ \dopresetfieldsymbol\@@DriverFieldValue
+ \setbox\scratchbox\hbox{\dogetfieldsymbol\@@DriverFieldValue}%
+ \scratchdimen\wd\scratchbox \edef\@@DriverFieldWidth {\the\scratchdimen}%
+ \scratchdimen\ht\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}%
+ \ifcase\fitfieldmode
+ \typesetfield
+ \or % 1 = ignore depth (original, assumed no depth, actually a bug)
+ \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}%
+ \or % 2 = add depth to height, but no depth in result
+ \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}%
+ \vbox to \ht\scratchbox{\vfill\hbox to \wd\scratchbox{\typesetfield\hfill}\vss}%
+ \or % 3 = add depth to height, and apply depth to result
+ \advance\scratchdimen\dp\scratchbox \edef\@@DriverFieldHeight{\the\scratchdimen}%
+ \hbox to \wd\scratchbox{\lower\dp\scratchbox\hbox{\typesetfield}\hfill}%
+ \fi}}
+
+%D Common stuff
+
+\newcounter\nofsystemfields
+
+\def\nextsystemfield
+ {\doglobal\increment\nofsystemfields
+ \def\currentsystemfield{sys::\nofsystemfields}}
+
+%D An example:
+
+\def\fillinfield
+ {\dosingleempty\dofillinfield}
+
+\def\dofillinfield[#1]#2%
+ {\dontleavehmode
+ \hbox
+ {\forgetall
+ \setupfields[\v!reset]%
+ \nextsystemfield
+ \useJSscripts[ans]%
+ \doifelsenothing{#1}
+ {\def\therightanswer{#2}}
+ {\def\therightanswer{#1}}%
+ \setbox0\hbox{#2}%
+ \setbox2\hbox{\therightanswer}%
+ \dimen0=\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi
+ \advance\dimen0 .2em
+ \definefield
+ [\currentsystemfield][line][systemfield]%
+ \setupfield
+ [systemfield]
+ [\c!n=1024, % beware: weblink plugin truncates
+ \c!location=\v!low,\c!strut=\v!yes,\c!fieldoffset=0pt,
+ \c!height=1.2\openlineheight,\c!width=\dimen0,\c!offset=\v!overlay,
+ \c!style=,\c!align=\v!middle,\c!frame=\v!off,
+ \c!color=red,\c!fieldbackgroundcolor=\s!white,\c!fieldframecolor=blue,
+ \c!validate=JS(Check_Answer{\currentsystemfield,\therightanswer})]%
+ \switchtobodyfont
+ [\c!small]%
+ \hbox to \wd0
+ {\copy0\hskip-\wd0\hss\field[\currentsystemfield]\hss}}}
+
+%D and another one:
+
+\def\tooltip
+ {\dosingleempty\dotooltip}
+
+\def\dotooltip[#1]#2#3%
+ {\bgroup
+ \setupfields[\v!reset]%
+ \useJSscripts[fld]%
+ \setbox0\hbox
+ {\dontcomplain
+ \nextsystemfield
+ \setbox0\hbox{#2}%
+ \definesymbol
+ [\currentsystemfield:txt]
+ [{\inframed[\c!frame=\v!off,\c!background=\v!screen]{#3}}]%
+ \setbox2\hbox{\symbol[\currentsystemfield:txt]}%
+ \definefield
+ [\currentsystemfield:txt][check]
+ [dummy][\currentsystemfield:txt][\currentsystemfield:txt]%
+ \setupfield
+ [dummy]
+ [\c!frame=\v!off,
+ \c!regionout=JS(Hide_Field{\currentsystemfield:txt}),
+ \c!option=\v!hidden]%
+ \hbox to \zeropoint
+ {\dimen0\wd2\advance\dimen0 -\wd0
+ \doifelse{#1}\v!left
+ {\hskip-\dimen0}
+ {\doif{#1}\v!middle
+ {\hskip-.5\dimen0}}%
+ \lower\openlineheight\hbox to \zeropoint
+ {\fitfield[\currentsystemfield:txt]}}%
+ \dimen0=\ifdim\wd0=\zeropoint 3em\else\wd0\fi
+ \definesymbol
+ [\currentsystemfield:but]
+ [{\framed[\c!height=2ex,\c!width=\dimen0,\c!frame=\v!off]{}}]%
+ \definefield
+ [\currentsystemfield:but][push]
+ [dummy][\currentsystemfield:but][\currentsystemfield:but]%
+ \setupfield
+ [dummy]
+ [\c!frame=\v!off,
+ \c!option=,
+ \c!regionin=JS(Vide_Field{\currentsystemfield:txt}),
+ \c!regionout=JS(Hide_Field{\currentsystemfield:txt}),
+ \c!fieldlayer=\@@iafieldlayer]%
+ \lower2ex\hbox to \zeropoint
+ {\fitfield[\currentsystemfield:but]}%
+ #2}%
+ \ht0\strutht\dp0\strutdp\box0
+ \egroup}
+
+%D And one more:
+
+\def\definefieldstack
+ {\dotripleargument\dodefinefieldstack}
+
+\def\dodefinefieldstack[#1][#2][#3]% name, symbols, settings
+ {\doifundefined{fieldstack:#1}
+ {\setgvalue{fieldstack:#1}{\dodofieldstack[#1][#2][#3]}}}
+
+\def\dodofieldstack[#1][#2][#3]% start=n, 0 == leeg
+ {\bgroup
+ \getparameters[\??fd][\c!start=1,#3]%
+ \setupfields[\v!reset]%
+ \definesymbol[\v!empty][]%
+ \useJSscripts[fld][FieldStack]%
+ \newcounter\stackedfieldnumber
+ \def\dododofieldstack##1%
+ {\increment\stackedfieldnumber
+ \ifnum\stackedfieldnumber=\@@fdstart\relax
+ \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][##1]%
+ \else
+ \definefield[#1:\stackedfieldnumber][check][#1][##1,\v!empty][\v!empty]%
+ \fi}%
+ \processcommalist[#2]\dododofieldstack
+ \setupfield[#1][\v!reset]% added
+ \setupfield[#1][\c!option=\v!readonly,#3]% #3 swapped
+ \newcounter\stackedfieldnumber
+ \def\dododofieldstack##1%
+ {\doglobal\increment\stackedfieldnumber
+ \fitfield[#1:\stackedfieldnumber]\egroup\bgroup}%
+ \startoverlay
+ \bgroup
+ \globalprocesscommalist[#2]\dododofieldstack
+ \egroup
+ \stopoverlay
+ \egroup}
+
+\def\dofieldstack[#1][#2][#3]%
+ {\ifsecondargument
+ \dodefinefieldstack[#1][#2][#3]\fieldstack[#1]%
+ \else
+ \getvalue{fieldstack:#1}\setgvalue{fieldstack:#1}{[#1]}%
+ \fi}
+
+\def\fieldstack
+ {\dotripleempty\dofieldstack}
+
+%D When submitting a form, we need to tell the driver module
+%D that we want \FDF\ or \HTML.
+
+\def\setupforms
+ {\dodoubleargument\getparameters[\??fr]}
+
+\def\checksubmitform#1%
+ {\setsubmitoutputformat\@@frmethod}
+
+\setexecutecommandcheck {submitform} \checksubmitform
+
+\setupforms
+ [\c!method=HTML]
+
+\protect \endinput
diff --git a/tex/context/base/core-fnt.tex b/tex/context/base/core-fnt.mkii
index e6f7fada4..9bc2a66f5 100644
--- a/tex/context/base/core-fnt.tex
+++ b/tex/context/base/core-fnt.mkii
@@ -2,7 +2,7 @@
%D [ file=core-fnt,
%D version=1995.10.10,
%D title=\CONTEXT\ Core Macros,
-%D subtitle=Font Support,
+%D subtitle=Fonts,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Font Support}
+\writestatus{loading}{ConTeXt Core Macros / Fonts}
\unprotect
diff --git a/tex/context/base/core-fnt.mkiv b/tex/context/base/core-fnt.mkiv
new file mode 100644
index 000000000..323183712
--- /dev/null
+++ b/tex/context/base/core-fnt.mkiv
@@ -0,0 +1,498 @@
+%D \module
+%D [ file=core-fnt,
+%D version=1995.10.10,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Fonts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Core Macros / Fonts}
+
+\unprotect
+
+%D \macros
+%D {compound}
+%D
+%D We will overload the already active \type {|} so we have
+%D to save its meaning in order to be able to use this handy
+%D macro.
+%D
+%D \starttyping
+%D so test\compound{}test can be used instead of test||test
+%D \stoptyping
+
+\bgroup \catcode`\|=\@@active \gdef\compound#1{|#1|} \egroup
+
+%D Here we hook some code into the clean up mechanism needed
+%D for verbatim data.
+
+\appendtoks
+ \disablecompoundcharacters
+ \disablediscretionaries
+\to \everycleanupfeatures
+
+%D \macros
+%D {stretched}
+%D
+%D Stretching characters in a word is a sort of typographical
+%D murder. Nevertheless we support this manipulation for use in
+%D for instance titles.
+%D
+%D \starttyping
+%D \hbox to 5cm{\stretched{murder}}
+%D \stoptyping
+%D
+%D \typebuffer
+%D
+%D or
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D \showsetup{stretched}
+
+\def\stretched#1%
+ {\ifvmode\hbox to \hsize\else\ifinner\else\hbox\fi\fi
+ \bgroup\processtokens\relax\hss\relax{\hss\hss}{#1}\egroup}
+
+%D \startbuffer
+%D \stretched{Unknown Box}
+%D \hbox to .5\hsize{\stretched{A Horizontal Box}}
+%D \vbox to 2cm{\stretched{A Vertical Box}}
+%D \hbox to 3cm{\stretched{sp{\'e}c{\`\i}{\"a}l}}
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D The first line of this macros takes care of boxing. Normally
+%D one will use an \type{\hbox} specification. The last line
+%D shows how special characters should be passed.
+%D
+%D \typebuffer
+
+%D \macros
+%D {stretchednormalcase, stretcheduppercase, stretchedlowercase}
+%D
+%D A convenient alternative is:
+%D
+%D \starttyping
+%D \stretcheduppercase{Is this what you like?}
+%D \stoptyping
+%D
+%D \typebuffer
+%D
+%D this one uses fixed skips and kerns.
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D The default skip can be set with:
+
+% \def\stretchedspacefactor{4}
+% \def\stretchedspaceamount{.25em}
+%
+% \unexpanded\def\stretcheduppercase#1%
+% {\bgroup
+% \the\everyuppercase
+% \uppercase{\def\textstring{#1}}%
+% \ifdim\stretchedspaceamount>\zeropoint
+% \def\textkern%
+% {\kern\stretchedspaceamount}%
+% \def\textskip%
+% {\scratchdimen=\stretchedspaceamount
+% \hskip\stretchedspacefactor\scratchdimen}%
+% \@EA\processtokens\@EA\relax\@EA\textkern\@EA\relax\@EA
+% \textskip\@EA{\textstring}%
+% \else
+% \textstring
+% \fi
+% \egroup}
+
+%D Given the following settings, the space is 1em by default:
+
+\def\stretchedspacefactor{4}
+\def\stretchedspaceamount{.25em}
+\def\stretchedbreaktokens{.@/}
+
+\unexpanded\def\stretchednormalcase
+ {\stretchedsomecase\firstofoneargument}
+
+\unexpanded\def\stretcheduppercase
+ {\stretchedsomecase{\the\everyuppercase\uppercase}}
+
+\unexpanded\def\stretchedlowercase
+ {\stretchedsomecase{\the\everylowercase\lowercase}}
+
+\def\stretchedsomecase#1#2%
+ {\bgroup
+ #1{\def\textstring{#2}}%
+ \ifdim\stretchedspaceamount=\zeropoint
+ \textstring
+ \else
+ \def\textkern##1%
+ {% beware: ##1 may not be \box\somebox -)
+ \determinemidwordbreak{##1}{\stretchedbreaktokens}%
+ \kern\stretchedspaceamount##1\domidwordbreak}%
+ \def\textskip
+ {\scratchdimen\stretchedspaceamount
+ \hskip\stretchedspacefactor\scratchdimen}%
+ \@EA\processtokens\@EA\relax\@EA\textkern\@EA\relax\@EA
+ \textskip\@EA{\textstring}%
+ \fi
+ \egroup}
+
+%D An auxiliary macro, see for usage \type {\stretcheduppercase}.
+
+\let\domidwordbreak\relax
+
+\def\setmidwordbreaktoken#1%
+ {\sfcode`#1=5000\relax}
+
+\def\determinemidwordbreak#1#2%
+ {\edef\midwordbreaktokens{#2}%
+ \ifx\midwordbreaktokens\empty
+ \global\let\domidwordbreak\relax
+ \else
+ \setbox\scratchbox\hbox
+ {\expandafter\handletokens\midwordbreaktokens\with\setmidwordbreaktoken
+ a\space \!!dimena\lastskip
+ #1\space\!!dimenb\lastskip \relax % needed
+ \ifdim\!!dimena=\!!dimenb
+ \globallet\domidwordbreak\relax
+ \else
+ \globallet\domidwordbreak\allowbreak
+ \fi}%
+ \fi}
+
+%D \macros
+%D {underbar,underbars,
+%D overbar,overbars,
+%D overstrike,overstrikes,
+%D setupunderbar}
+%D
+%D In the rare case that we need undelined words, for instance
+%D because all font alternatives are already in use, one can
+%D use \type{\underbar} and \type{\overstrike} and their plural
+%D forms.
+%D
+%D \startbuffer
+%D \underbars{drawing \underbar{bars} under words is a typewriter leftover}
+%D \overstrikes{striking words makes them \overstrike{unreadable} but
+%D sometimes even \overbar{top lines} come into view.}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D The next macros are derived from the \PLAIN\ \TEX\ one, but
+%D also supports nesting. The \type{$} keeps us in horizontal
+%D mode and at the same time applies grouping.
+%D
+%D \showsetup{underbar}
+%D \showsetup{underbars}
+%D \showsetup{overbar}
+%D \showsetup{overbars}
+%D \showsetup{overstrike}
+%D \showsetup{overstrikes}
+%D
+%D Although underlining is ill advised, we permit some
+%D alternatives, that can be set up by:
+%D
+%D \showsetup{setupunderbar}
+%D
+%D The alternatives show up as
+%D {\setupunderbar [alternative=a]\underbar{alternative a}},
+%D {\setupunderbar [alternative=b]\underbar{alternative b}},
+%D {\setupunderbar [alternative=c]\underbar{alternative c}}
+%D and
+%D {\setupunderbar [rulethickness=1pt]\underbar{1pt width}},
+%D {\setupunderbar [rulethickness=2pt]\underbar{2pt width}},
+%D or whatever. Because \type{\overstrike} uses the same
+%D method, the settings also apply to that macro.
+
+\newcount\underbarlevel
+
+\def\underbarmethoda#1#2#3% RULE
+ {\hbox to #1{\vrule\!!width#1\!!height#2\!!depth#3}}
+
+\def\underbarmethodb#1#2#3% DASH
+ {\hbox to #1
+ {\hskip-.25em
+ \xleaders
+ \hbox{\hskip.25em\vrule\!!width.25em\!!height#2\!!depth#3}
+ \hfil}}
+
+\def\underbarmethodc#1#2#3% PERIOD
+ {\hbox to #1
+ {\dimen4=#3
+ \advance\dimen4 .2ex
+ \hskip-.25em
+ \xleaders
+ \hbox{\hskip.25em\lower\dimen4\hbox{.}}
+ \hfil}}
+
+\def\dododounderbar#1#2#3%
+ {\startmathmode
+ \setbox0\hbox{#3}%
+ \setbox2\hbox{\color[\@@onrulecolor]{\getvalue{underbarmethod\@@onalternative}{\wd0}{#1}{#2}}}%
+ \wd0\zeropoint
+ \ht2\ht0
+ \dp2\dp0
+ \box0\box2
+ \stopmathmode}
+
+\unexpanded\def\dodounderbar#1%
+ {\bgroup
+ \dimen0=\@@onbottomoffset
+ \dimen0=\underbarlevel\dimen0
+ \ifdone \else
+ \advance\dimen0 -\strutht
+ \fi
+ \dimen2\dimen0
+ \advance\dimen2 \@@onrulethickness
+ \dododounderbar{-\dimen0}{\dimen2}{#1}%
+ \egroup}
+
+\def\betweenunderbarwords
+ {\bgroup
+ \setbox0\hbox{\dodounderbar{\hskip\interwordspace}}%
+ \nobreak
+ \hskip\zeropoint\!!minus\interwordshrink
+ \discretionary{}{}{\box0}%
+ \egroup}
+
+\def\betweenunderbarspaces
+ {\hskip\currentspaceskip}
+
+% \unexpanded\def\dounderbar#1#2%
+% {\let\betweenisolatedwords#1%
+% \processisolatedwords{#2}\dodounderbar
+% \egroup}
+
+\unexpanded\def\underbar
+ {\bgroup
+ \advance\underbarlevel\plusone
+ \donetrue
+ \dounderbar\betweenunderbarwords}
+
+\unexpanded\def\dounderbar#1%
+ {\let\betweenisolatedwords#1%
+ \dosingleempty\redounderbar}
+
+\unexpanded\def\redounderbar[#1]#2%
+ {\iffirstargument\setupunderbar[#1]\fi
+ \processisolatedwords{#2}\dodounderbar
+ \egroup}
+
+\unexpanded\def\underbars
+ {\bgroup
+ \advance\underbarlevel\plusone
+ \donetrue
+ \dounderbar\betweenunderbarspaces}
+
+\unexpanded\def\overbar
+ {\bgroup
+ \advance\underbarlevel\minusone
+ \donefalse
+ \dounderbar\betweenunderbarwords}
+
+\unexpanded\def\overbars
+ {\bgroup
+ \advance\underbarlevel\minusone
+ \donefalse
+ \dounderbar\betweenunderbarspaces}
+
+\def\dooverstrike#1%
+ {\bgroup
+ \dimen0=\@@ontopoffset
+ \dimen2=\dimen0
+ \advance\dimen2 \@@onrulethickness
+ \dododounderbar{\dimen2}{-\dimen0}{#1}%
+ \egroup}
+
+\def\betweenoverstrikewords
+ {\bgroup
+ \setbox0\hbox{\dooverstrike{\hskip\interwordspace}}%
+ \nobreak
+ \hskip\zeropoint\!!minus\interwordshrink
+ \discretionary{}{}{\box0}%
+ \egroup}
+
+\unexpanded\def\overstrike#1%
+ {\bgroup
+ \let\betweenisolatedwords\betweenoverstrikewords
+ \processisolatedwords{#1}\dooverstrike
+ \egroup}
+
+\unexpanded\def\overstrikes#1%
+ {\bgroup
+ \processisolatedwords{#1}\dooverstrike
+ \egroup}
+
+\def\underbarparameter#1{\csname\??on#1\csname}
+
+\def\setupunderbar
+ {\dodoubleargument\getparameters[\??on]}
+
+%D \macros
+%D {shiftedword, shiftedwords}
+%D
+%D Used as \type {\shiftedwords {10pt} {some text}} this macro will
+%D move
+
+% \def\shiftedword#1% #2%
+% {\raise#1\hbox} % {#2}} % officially: {\ifdim#1>\zeropoint\raise\else\lower\fi#1\hbox{#2}}
+
+% \def\shiftedwords#1#2%
+% {\processisolatedwords{#2}{\shiftedword{#1}}}
+
+%D \macros
+%D {low, high, lohi, hilo}
+%D
+%D Although \TEX\ is pretty well aware of super- and
+%D subscripts, its mechanism is mainly tuned for math mode.
+%D The next few commands take care of script texts both modes.
+%D
+%D \startbuffer
+%D The higher\high{one goes} the lower\low{one drops}, or\lohi{yes}{no}?
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D Note the different placement of \type {\lohi}, where we
+%D need a bit more space. The implementation looks a bit
+%D fuzzy, since some \type {\fontdimen}'s are involved to
+%D determine the optimal placement.
+
+\def\dodohighlow
+ {\ifx\fontsize\empty
+ \ifmmode
+ \ifnum\fam<0 \tx \else \holamathfont \fi
+ \else
+ \tx
+ \fi
+ \else
+ \tx
+ \fi}
+
+\def\dohighlow#1#2#3#4#5% todo, named fontdimens
+ {\dontleavehmode
+ \bgroup
+ \scratchdimen\ifdim\fontexheight\textfont2=1ex #2\textfont2\else #3ex\fi
+ \advance\scratchdimen #4ex
+ \kern.1ex
+ \setbox\scratchbox\hbox{#1\scratchdimen\hbox{\dodohighlow#5}}%
+ \ht\scratchbox\strutheight
+ \dp\scratchbox\strutdepth
+ \box\scratchbox
+ \egroup}
+
+\unexpanded\def\high{\dohighlow\raise\mathsupnormal{.86}{0}}
+\unexpanded\def\low {\dohighlow\lower\mathsubnormal{.48}{0}}
+
+\unexpanded\def\lohi
+ {\dosingleempty\dolohi}
+
+\unexpanded\def\hilo
+ {\dosingleempty\dohilo}
+
+\def\dolohi[#1]#2#3%
+ {\dontleavehmode
+ \hbox
+ {\setbox4\hbox{\dohighlow\lower\mathsubnormal{.48}{.1}{#2}}%
+ \setbox6\hbox{\dohighlow\raise\mathsupnormal{.86}{.1}{#3}}%
+ \doif{#1}{\v!left}
+ {\ifdim\wd4<\wd6
+ \setbox4\hbox to \wd6{\hss\box4}%
+ \else
+ \setbox6\hbox to \wd4{\hss\box6}%
+ \fi}%
+ \ifdim\wd4<\wd6
+ \wd4=\zeropoint\box4\box6
+ \else
+ \wd6=\zeropoint\box6\box4
+ \fi}}
+
+\def\dohilo[#1]#2#3%
+ {\dolohi[#1]{#3}{#2}}
+
+%D You can provide an optional keyword \type {left}, in which
+%D case the super and subscripts will be aligned in a way that
+%D permits placement at the left of a word (which means that
+%D it will be right aligned).
+%D
+%D \startbuffer
+%D \lohi{aha}{ah} test \lohi{aha}{ah} test
+%D \lohi[left]{aha}{ah} test \lohi[left]{aha}{ah} test
+%D \lohi{aha}{ah} test\lohi{aha}{ah} test
+%D \lohi[left]{aha}{ah}test \lohi[left]{aha}{ah}test
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+
+%D \macros
+%D {setupinitial,placeinitial,checkinitial}
+%D
+%D {\em To be documented.}
+%D
+%D \starttyping
+%D \setupinitial[state=start] \placeinitial \input tufte
+%D \stoptyping
+%D
+%D and
+%D
+%D \starttyping
+%D \def\bpar{\ifvmode\checkinitial\fi}
+%D \def\epar{\ifhmode\par\fi\checkinitial}
+%D \stoptyping
+
+% to do: more fine tuning
+
+\def\setupinitial
+ {\dodoubleempty\getparameters[\??dc]}
+
+\definefontsynonym[Initial][Regular] % prefered initial identifier
+\definefontsynonym[initial][Initial] % internal but accepted too
+
+\setupinitial
+ [\c!state=\v!stop,
+ \c!location=\v!text,
+ \c!n=3,
+ \c!distance=.125em,
+ \c!command=,
+ \s!font=initial]
+
+\def\AutoDroppedCapsCommand{\NiceDroppedCaps\@@dccommand\@@dcfont\@@dcdistance\@@dcn}%
+
+\def\placeinitial
+ {\doifelse\@@dclocation\v!margin{\chardef\DropMode\plusone}{\chardef\DropMode\zerocount}%
+ \doif \@@dcstate\v!start{\ifcase\@@dcn\else\AutoDroppedCaps\fi}}
+
+\let\checkinitial\CheckDroppedCaps
+
+%D This module has only a few setups:
+
+\setupunderbar
+ [\c!alternative=a,
+ \c!rulethickness=\linewidth,
+ \c!bottomoffset=1.5pt,
+ \c!topoffset=2.5pt,
+ \c!rulecolor=]
+
+\protect \endinput
diff --git a/tex/context/base/core-gen.tex b/tex/context/base/core-gen.tex
index aaaba84d1..b6ab2a208 100644
--- a/tex/context/base/core-gen.tex
+++ b/tex/context/base/core-gen.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / General}
+\writestatus{loading}{ConTeXt Core Macros / General}
\unprotect
@@ -60,79 +60,38 @@
%D {waarde groot}
%D \stoptyping
-\def\assigndimension#1#2#3#4#5% can be a skip
- {\processaction
- [#1]
- [ \v!small=>#2=#3\relax,
- \v!medium=>#2=#4\relax,
- \v!big=>#2=#5\relax,
- \v!none=>#2=\zeropoint,
- -\v!small=>#2=-#3\relax,
- -\v!medium=>#2=-#4\relax,
- -\v!big=>#2=-#5\relax,
- \s!unknown=>#2=#1\relax]}
-
-\def\assignalfadimension#1#2#3#4#5%
- {\processaction
- [#1]
- [ \v!small=>\edef#2{#3},
- \v!medium=>\edef#2{#4},
- \v!big=>\edef#2{#5},
- \v!none=>\edef#2{0},
- \s!unknown=>\edef#2{#1}]}
-
-%D De onderstaande implementatie is veel sneller, maar
-%D tegelijkertijd ook veel lelijker. Omdat we deze macro
-%D relatief weinig aanroepen laten we deze optimalisatie maar
-%D achterwege. Bovendien kunnen oplossingen als deze de
-%D hash||table aardig uitputten (\type {\doifdefined}).
-%D
-%D \starttyping
-%D \edef\@@dimension{@@dim}
-%D \edef\@@negdimension{\@@dimension-}
-%D
-%D \def\assigndimension#1#2#3#4#5%
-%D {\setvalue{\@@dimension \v!small }{#3}%
-%D \setvalue{\@@dimension \v!medium}{#4}%
-%D \setvalue{\@@dimension \v!big }{#5}%
-%D \setvalue{\@@dimension \v!none }{\!!zeropoint}%
-%D \setvalue{\@@negdimension\v!small }{-#3}%
-%D \setvalue{\@@negdimension\v!medium}{-#4}%
-%D \setvalue{\@@negdimension\v!big }{-#5}%
-%D \setvalue{\@@negdimension\v!none }{\!!zeropoint}%
-%D \doifdefinedelse{\@@dimension#1}
-%D {#2=\getvalue{\@@dimension#1}}
-%D {#2=#1}}
-%D \stoptyping
-%D
-%D Let's give this a try:
-
-\let\nopv!none \v!none
-\let\posv!big \v!big
-\let\posv!middle \v!medium
-\let\posv!small \v!small
-\edef\negv!big {-\v!big}
-\edef\negv!middle{-\v!medium}
-\edef\negv!small {-\v!small}
-
-\def\assigndimension#1#2#3#4#5%
- {\edef\!!stringa{#1}%
- #2=\ifx\!!stringa\nopv!none \zeropoint\else
- \ifx\!!stringa\posv!big #5\else
- \ifx\!!stringa\posv!middle #4\else
- \ifx\!!stringa\posv!small #3\else
- \ifx\!!stringa\negv!big -#5\else
- \ifx\!!stringa\negv!middle-#4\else
- \ifx\!!stringa\negv!small -#3\else
- #1\fi\fi\fi\fi\fi\fi\fi}
-
-\def\assignalfadimension#1#2#3#4#5%
- {\edef\!!stringa{#1}%
- \edef#2{\ifx\!!stringa\posv!big #5\else
- \ifx\!!stringa\posv!middle#4\else
- \ifx\!!stringa\posv!small #3\else
- \ifx\!!stringa\nopv!none 0\else
- #1\fi\fi\fi\fi}}
+% The third (optimized) version:
+
+\def\@ad@{@ad@}
+
+\setvalue{\@ad@ \v!none }{\zeropoint\gobblethreearguments}
+\setvalue{\@ad@ \v!big }{\thirdofthreearguments}
+\setvalue{\@ad@ \v!medium}{\secondofthreearguments}
+\setvalue{\@ad@ \v!small }{\firstofthreearguments}
+\setvalue{\@ad@-\v!big }{-\thirdofthreearguments}
+\setvalue{\@ad@-\v!medium}{-\secondofthreearguments}
+\setvalue{\@ad@-\v!small }{-\firstofthreearguments}
+
+\def\assigndimension#1#2% #3 #4 #5
+ {#2=\ifcsname\@ad@#1\endcsname
+ \csname\@ad@#1\expandafter\endcsname
+ \else
+ #1\expandafter\gobblethreearguments
+ \fi}
+
+\def\@aa@{@aa@}
+
+\setvalue{\@aa@\v!none }{0\gobblethreearguments}
+\setvalue{\@aa@\v!big }{\thirdofthreearguments}
+\setvalue{\@aa@\v!medium}{\secondofthreearguments}
+\setvalue{\@aa@\v!small }{\firstofthreearguments}
+
+\def\assignalfadimension#1#2#3#4#5% #3#4#5 are single digits
+ {\edef#2{\ifcsname\@aa@#1\endcsname
+ \csname\@aa@#1\expandafter\endcsname
+ \else
+ #1\expandafter\gobblethreearguments
+ \fi#3#4#5}}
%D \macros
%D {assignvalue}
@@ -162,22 +121,18 @@
%D
%D Hier doet \type{geen} dus niet mee.
-\def\assignvalue#1#2#3#4#5%
- {\processaction
- [#1]
- [ \v!small=>\edef#2{#3},
- \v!medium=>\edef#2{#4},
- \v!big=>\edef#2{#5},
- \s!unknown=>\edef#2{#1}]}
+\def\@av@{@av@}
-%D Or faster:
+\letvalue{\@av@\v!big }\thirdofthreearguments
+\letvalue{\@av@\v!medium}\secondofthreearguments
+\letvalue{\@av@\v!small }\firstofthreearguments
\def\assignvalue#1#2#3#4#5%
- {\edef\!!stringa{#1}%
- \edef#2{\ifx\!!stringa\posv!big #5\else
- \ifx\!!stringa\posv!middle#4\else
- \ifx\!!stringa\posv!small #3\else
- #1\fi\fi\fi}}
+ {\edef#2{\ifcsname\@av@#1\endcsname
+ \csname\@av@#1\expandafter\endcsname
+ \else
+ #1\expandafter\gobblethreearguments
+ \fi{#3}{#4}{#5}}}
%D \macros
%D {assignwidth}
@@ -200,11 +155,11 @@
\def\assignwidth#1#2#3#4%
{\doifelsenothing{#2}
- {\setbox0\hbox{#3}%
- #1\wd0}
+ {\setbox\scratchbox\hbox{#3}%
+ #1\wd\scratchbox}
{\doifinsetelse{#2}{\v!fit,\v!broad}
- {\setbox0=\hbox{#3}%
- #1\wd0
+ {\setbox\scratchbox\hbox{#3}%
+ #1\wd\scratchbox
\doif{#2}\v!broad{\advance#1 #4}}%
{#1=#2}}}%
diff --git a/tex/context/base/core-grd.tex b/tex/context/base/core-grd.tex
index 5db966455..249e2e430 100644
--- a/tex/context/base/core-grd.tex
+++ b/tex/context/base/core-grd.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Grid Snapping}
+\writestatus{loading}{ConTeXt Core Macros / Grid Snapping}
\unprotect
diff --git a/tex/context/base/core-inc.lua b/tex/context/base/core-inc.lua
index 1707c1b25..35370058d 100644
--- a/tex/context/base/core-inc.lua
+++ b/tex/context/base/core-inc.lua
@@ -33,63 +33,23 @@ The TeX-Lua mix is suboptimal. This has to do with the fact that we cannot
run TeX code from within Lua. Some more functionality will move to Lua.
]]--
-local texsprint, format = tex.sprint, string.format
+local texsprint, format, lower = tex.sprint, string.format, string.lower
-backends = backends or { }
-backends.pdf = backends.pdf or { }
+local ctxcatcodes = tex.ctxcatcodes
---~ function backends.pdf.startscaling(sx,sy)
---~ return nodes.pdfliteral(format("q %s 0 0 %s 0 0 cm",(sx ~= 0 and sx) or .0001,(sy ~= 0 and sy) or .0001))
---~ end
---~ function backends.pdf.stopscaling()
---~ return nodes.pdfliteral("%Q")
---~ end
-
-function backends.pdf.insertmovie(data)
- data = data or figures.current()
- local dr, du, ds = data.request, data.used, data.status
- local width, height, factor = du.width or dr.width, du.height or dr.height, number.dimenfactors.bp
- local options, actions = "", ""
- if dr["repeat"] then
- actions = actions .. "/Mode /Repeat "
- end
- if dr.controls then
- actions = actions .. "/ShowControls true "
- else
- actions = actions .. "/ShowControls false "
- end
- if dr.preview then
- options = options .. "/Poster true "
- end
- if actions ~= "" then
- actions= "/A <<" .. actions .. ">>"
- end
- texsprint(tex.ctxcatcodes, format(
- "\\doPDFannotation{%ssp}{%ssp}{/Subtype /Movie /Border [0 0 0] /T (movie %s) /Movie << /F (%s) /Aspect [%s %s] %s>> %s}",
- width, height, dr.label, du.foundname, factor * width, factor * height, options, actions
- ))
- return data
-end
-
---~ if node then do
---~ local n = node.new(0,0)
---~ local m = getmetatable(n)
---~ m.__concat = function(a,b)
---~ local t = node.slide(a)
---~ t.next, b.prev = b, t
---~ return a
---~ end
---~ node.free(n)
---~ end end
+local trace_figures = false trackers.register("figures.locating",function(v) trace_figures = v end)
--- some extra img functions ---
-function img.totable(i)
- local t = { }
- for _, v in ipairs(img.keys()) do
- t[v] = i[v]
+local imgkeys = img.keys()
+
+function img.totable(imgtable)
+ local result = { }
+ for k=1,#imgkeys do
+ local key = imgkeys[k]
+ result[key] = imgtable[key]
end
- return t
+ return result
end
function img.serialize(i)
@@ -124,7 +84,6 @@ figures.found = figures.found or { }
figures.suffixes = figures.suffixes or { }
figures.patterns = figures.patterns or { }
figures.boxnumber = figures.boxid or 0
-figures.trace = false
figures.defaultsearch = true
figures.defaultwidth = 0
figures.defaultheight = 0
@@ -226,7 +185,7 @@ function figures.setpaths(locationset,pathlist)
end
end
figures.paths, last_pathlist = t, pathlist
- if figures.trace then
+ if trace_figures then
logs.report("figures","locations: %s",last_locationset)
logs.report("figures","path list: %s",table.concat(figures.paths))
end
@@ -299,11 +258,13 @@ do
end
function figures.push(request)
- input.starttiming(figures)
+ statistics.starttiming(figures)
local figuredata = figures.new()
if request then
- local iv = interfaces.variables
- local w, h = tonumber(request.width), tonumber(request.height)
+ local iv = interfaces.variables
+ -- request.width/height are strings and are only used when no natural dimensions
+ -- can be determined; at some point the handlers might set them to numbers instead
+--~ local w, h = tonumber(request.width), tonumber(request.height)
request.page = math.max(tonumber(request.page) or 1,1)
request.size = img.check_size(request.size)
request.object = iv[request.object] == "yes"
@@ -312,8 +273,8 @@ do
request.cache = request.cache ~= "" and request.cache
request.prefix = request.prefix ~= "" and request.prefix
request.format = request.format ~= "" and request.format
- request.width = (w and w > 0) or false
- request.height = (h and h > 0) or false
+--~ request.width = (w and w > 0) or false
+--~ request.height = (h and h > 0) or false
table.merge(figuredata.request,request)
end
callstack[#callstack+1] = figuredata
@@ -322,7 +283,7 @@ do
function figures.pop()
figuredata = callstack[#callstack]
callstack[#callstack] = nil
- input.stoptiming(figures)
+ statistics.stoptiming(figures)
end
-- maybe move texsprint to tex
function figures.get(category,tag,default)
@@ -334,7 +295,7 @@ do
end
end
function figures.tprint(category,tag,default)
- texsprint(tex.ctxcatcodes,figures.get(category,tag,default))
+ texsprint(ctxcatcodes,figures.get(category,tag,default))
end
function figures.current()
return callstack[#callstack]
@@ -342,187 +303,180 @@ do
end
-do
-
- local function register(askedname,specification)
- if specification then
- local format = specification.format
- if format then
- local converter = figures.converters[format]
- if converter then
- local oldname = specification.fullname
- local newformat = "pdf" -- todo, other target than pdf
- local newpath = file.dirname(oldname)
- local newbase = file.replacesuffix(file.basename(oldname),newformat)
- local fc = specification.cache or figures.cachepaths.path
- if fc and fc ~= "" and fc ~= "." then
- newpath = fc
- end
- local subpath = specification.subpath or figures.cachepaths.subpath
- if subpath and subpath ~= "" and subpath ~= "." then
- newpath = newpath .. "/" .. subpath
- end
- local prefix = specification.prefix or figures.cachepaths.prefix
- if prefix and prefix ~= "" then
- newbase = prefix .. newbase
- end
- local newname = file.join(newpath,newbase)
- dir.makedirs(newpath)
- local oldtime = lfs.attributes(oldname,'modification') or 0
- local newtime = lfs.attributes(newname,'modification') or 0
- if oldtime > newtime then
- converter(oldname,newname)
- end
- if io.exists(newname) then
- specification.foundname = oldname
- specification.fullname = newname
- specification.prefix = prefix
- specification.subpath = subpath
- specification.converted = true
- format = newformat
- elseif io.exists(oldname) then
- specification.fullname = newname
- specification.converted = false
- end
+local function register(askedname,specification)
+ if specification then
+ local format = specification.format
+ if format then
+ local converter = figures.converters[format]
+ if converter then
+ local oldname = specification.fullname
+ local newformat = "pdf" -- todo, other target than pdf
+ local newpath = file.dirname(oldname)
+ local newbase = file.replacesuffix(file.basename(oldname),newformat)
+ local fc = specification.cache or figures.cachepaths.path
+ if fc and fc ~= "" and fc ~= "." then
+ newpath = fc
+ end
+ local subpath = specification.subpath or figures.cachepaths.subpath
+ if subpath and subpath ~= "" and subpath ~= "." then
+ newpath = newpath .. "/" .. subpath
+ end
+ local prefix = specification.prefix or figures.cachepaths.prefix
+ if prefix and prefix ~= "" then
+ newbase = prefix .. newbase
+ end
+ local newname = file.join(newpath,newbase)
+ dir.makedirs(newpath)
+ local oldtime = lfs.attributes(oldname,'modification') or 0
+ local newtime = lfs.attributes(newname,'modification') or 0
+ if oldtime > newtime then
+ converter(oldname,newname)
+ end
+ if io.exists(newname) then
+ specification.foundname = oldname
+ specification.fullname = newname
+ specification.prefix = prefix
+ specification.subpath = subpath
+ specification.converted = true
+ format = newformat
+ elseif io.exists(oldname) then
+ specification.fullname = newname
+ specification.converted = false
end
end
- specification.found = validtypes[format]
- if figures.trace then
+ end
+ local found = figures.suffixes[format] -- validtypes[format]
+ if not found then
+ specification.found = false
+ if trace_figures then
logs.report("figures","format not supported: %s",format)
end
else
- specification = { }
+ specification.found = true
+ if trace_figures then
+ if validtypes[format] then
+ logs.report("figures","format natively supported by backend: %s",format)
+ else
+ logs.report("figures","format supported by output file format: %s",format)
+ end
+ end
end
- specification.foundname = specification.foundname or specification.fullname
- figures.found[askedname] = specification
- return specification
+ else
+ specification = { }
end
+ specification.foundname = specification.foundname or specification.fullname
+ figures.found[askedname] = specification
+ return specification
+end
- local function locate(request) -- name, format, cache
- local askedname = input.clean_path(request.name)
- if figures.found[askedname] then
- return figures.found[askedname]
- end
- local askedpath= file.dirname(askedname)
- local askedbase = file.basename(askedname)
- local askedformat = (request.format ~= "" and request.format ~= "unknown" and request.format) or file.extname(askedname) or ""
- local askedcache = request.cache
- if askedformat ~= "" then
- askedformat = askedformat:lower()
- local format = figures.suffixes[askedformat]
- if not format then
- for _, pattern in ipairs(figures.patterns) do
- if askedformat:find(pattern[1]) then
- format = pattern[2]
- break
- end
+local function locate(request) -- name, format, cache
+ local askedname = resolvers.clean_path(request.name)
+ if figures.found[askedname] then
+ return figures.found[askedname]
+ end
+ local askedpath= file.dirname(askedname)
+ local askedbase = file.basename(askedname)
+ local askedformat = (request.format ~= "" and request.format ~= "unknown" and request.format) or file.extname(askedname) or ""
+ local askedcache = request.cache
+ if askedformat ~= "" then
+ askedformat = lower(askedformat)
+ local format = figures.suffixes[askedformat]
+ if not format then
+ for _, pattern in ipairs(figures.patterns) do
+ if askedformat:find(pattern[1]) then
+ format = pattern[2]
+ break
end
end
- if format then
- local foundname = figures.exists(askedname,askedformat)
- if foundname then
- return register(askedname, {
+ end
+ if format then
+ local foundname = figures.exists(askedname,askedformat)
+ if foundname then
+ return register(askedname, {
+ askedname = askedname,
+ fullname = askedname,
+ format = format,
+ cache = askedcache,
+ foundname = foundname,
+ })
+ end
+ end
+ if askedpath ~= "" then
+ -- path and type given, todo: strip pieces of path
+ if figures.exists(askedname,askedformat) then
+ return register(askedname, {
+ askedname = askedname,
+ fullname = askedname,
+ format = askedformat,
+ cache = askedcache,
+ })
+ end
+ else
+ -- type given
+ for _, path in ipairs(figures.paths) do
+ local check = path .. "/" .. askedname
+ if figures.exists(check,askedformat) then
+ return register(check, {
askedname = askedname,
- fullname = askedname,
- format = format,
+ fullname = check,
+ format = askedformat,
cache = askedcache,
- foundname = foundname,
})
end
end
- if askedpath ~= "" then
- -- path and type given, todo: strip pieces of path
- if figures.exists(askedname,askedformat) then
+ if figures.defaultsearch then
+ local check = resolvers.find_file(askedname)
+ if check and check ~= "" then
return register(askedname, {
askedname = askedname,
- fullname = askedname,
+ fullname = check,
format = askedformat,
cache = askedcache,
})
end
- else
- -- type given
- for _, path in ipairs(figures.paths) do
- local check = path .. "/" .. askedname
- if figures.exists(check,askedformat) then
- return register(check, {
- askedname = askedname,
- fullname = check,
- format = askedformat,
- cache = askedcache,
- })
- end
- end
- if figures.defaultsearch then
- local check = input.find_file(askedname)
- if check and check ~= "" then
- return register(askedname, {
- askedname = askedname,
- fullname = check,
- format = askedformat,
- cache = askedcache,
- })
- end
+ end
+ end
+ elseif askedpath ~= "" then
+ for _, format in ipairs(figures.order) do
+ local list = figures.formats[format].list or { format }
+ for _, suffix in ipairs(list) do
+ local check = file.addsuffix(askedname,suffix)
+ if figures.exists(check,format) then
+ return register(askedname, {
+ askedname = askedname,
+ fullname = check,
+ format = format,
+ cache = askedcache,
+ })
end
end
- elseif askedpath ~= "" then
+ end
+ else
+ if figures.prefer_quality then
for _, format in ipairs(figures.order) do
local list = figures.formats[format].list or { format }
for _, suffix in ipairs(list) do
- local check = file.addsuffix(askedname,suffix)
- if figures.exists(check,format) then
- return register(askedname, {
- askedname = askedname,
- fullname = check,
- format = format,
- cache = askedcache,
- })
- end
- end
- end
- else
- if figures.prefer_quality then
- for _, format in ipairs(figures.order) do
- local list = figures.formats[format].list or { format }
- for _, suffix in ipairs(list) do
- local name = file.replacesuffix(askedbase,suffix)
- for _, path in ipairs(figures.paths) do
- local check = path .. "/" .. name
- if figures.exists(check,format) then
- return register(askedname, {
- askedname = askedname,
- fullname = check,
- format = format,
- cache = askedcache,
- })
- end
- end
- end
- end
- else -- 'location'
- for _, path in ipairs(figures.paths) do
- for _, format in ipairs(figures.order) do
- local list = figures.formats[format].list or { format }
- for _, suffix in ipairs(list) do
- local check = path .. "/" .. file.replacesuffix(askedbase,suffix)
- if figures.exists(check,format) then
- return register(askedname, {
- askedname = askedname,
- fullname = check,
- format = format,
- cache = askedcache,
- })
- end
+ local name = file.replacesuffix(askedbase,suffix)
+ for _, path in ipairs(figures.paths) do
+ local check = path .. "/" .. name
+ if figures.exists(check,format) then
+ return register(askedname, {
+ askedname = askedname,
+ fullname = check,
+ format = format,
+ cache = askedcache,
+ })
end
end
end
end
- if figures.defaultsearch then
+ else -- 'location'
+ for _, path in ipairs(figures.paths) do
for _, format in ipairs(figures.order) do
local list = figures.formats[format].list or { format }
for _, suffix in ipairs(list) do
- local check = input.find_file(file.replacesuffix(askedname,suffix))
- if check and check ~= "" then
+ local check = path .. "/" .. file.replacesuffix(askedbase,suffix)
+ if figures.exists(check,format) then
return register(askedname, {
askedname = askedname,
fullname = check,
@@ -534,75 +488,92 @@ do
end
end
end
- return register(askedname)
+ if figures.defaultsearch then
+ for _, format in ipairs(figures.order) do
+ local list = figures.formats[format].list or { format }
+ for _, suffix in ipairs(list) do
+ local check = resolvers.find_file(file.replacesuffix(askedname,suffix))
+ if check and check ~= "" then
+ return register(askedname, {
+ askedname = askedname,
+ fullname = check,
+ format = format,
+ cache = askedcache,
+ })
+ end
+ end
+ end
+ end
end
+ return register(askedname)
+end
- -- -- -- plugins -- -- --
+-- -- -- plugins -- -- --
- figures.existers = figures.existers or { }
- figures.checkers = figures.checkers or { }
- figures.includers = figures.includers or { }
- figures.converters = figures.converters or { }
- figures.identifiers = figures.identifiers or { }
+figures.existers = figures.existers or { }
+figures.checkers = figures.checkers or { }
+figures.includers = figures.includers or { }
+figures.converters = figures.converters or { }
+figures.identifiers = figures.identifiers or { }
- figures.identifiers.list = {
- figures.identifiers.default
- }
+figures.identifiers.list = {
+ figures.identifiers.default
+}
- function figures.identifiers.default(data)
- local dr, du, ds = data.request, data.used, data.status
- local l = locate(dr)
- local foundname = l.foundname
- local fullname = l.fullname or foundname
- if fullname then
- du.format = l.format or false
- du.fullname = fullname -- can be cached
- ds.fullname = foundname -- original
- ds.format = l.format
- ds.status = (l.found and 10) or 0
- end
- return data
+function figures.identifiers.default(data)
+ local dr, du, ds = data.request, data.used, data.status
+ local l = locate(dr)
+ local foundname = l.foundname
+ local fullname = l.fullname or foundname
+ if fullname then
+ du.format = l.format or false
+ du.fullname = fullname -- can be cached
+ ds.fullname = foundname -- original
+ ds.format = l.format
+ ds.status = (l.found and 10) or 0
end
+ return data
+end
- function figures.identify(data)
- data = data or figures.current()
- for _, identifier in ipairs(figures.identifiers.list) do
- data = identifier(data)
- if data.status.status > 0 then
- break
- end
+function figures.identify(data)
+ data = data or figures.current()
+ for _, identifier in ipairs(figures.identifiers.list) do
+ data = identifier(data)
+ if data.status.status > 0 then
+ break
end
- return data
- end
- function figures.exists(askedname,format)
- return (figures.existers[format] or figures.existers.generic)(askedname)
- end
- function figures.check(data)
- data = data or figures.current()
- local dr, du, ds = data.request, data.used, data.status
- return (figures.checkers[ds.format] or figures.checkers.generic)(data)
- end
- function figures.include(data)
- data = data or figures.current()
- local dr, du, ds = data.request, data.used, data.status
- return (figures.includers[ds.format] or figures.includers.generic)(data)
- end
- function figures.scale(data) -- will become lua code
- texsprint(tex.ctxcatcodes,"\\doscalefigure")
- return data
- end
- function figures.done(data)
- figures.n = figures.n + 1
- data = data or figures.current()
- local dr, du, ds = data.request, data.used, data.status
- ds.width = tex.wd[figures.boxnumber]
- ds.height = tex.ht[figures.boxnumber]
- ds.xscale = ds.width/(du.width or 1)
- ds.yscale = ds.height/(du.height or 1)
- return data
end
+ return data
+end
+function figures.exists(askedname,format)
+ return (figures.existers[format] or figures.existers.generic)(askedname)
+end
+function figures.check(data)
+ data = data or figures.current()
+ local dr, du, ds = data.request, data.used, data.status
+ return (figures.checkers[ds.format] or figures.checkers.generic)(data)
+end
+function figures.include(data)
+ data = data or figures.current()
+ local dr, du, ds = data.request, data.used, data.status
+ return (figures.includers[ds.format] or figures.includers.generic)(data)
+end
+function figures.scale(data) -- will become lua code
+ texsprint(ctxcatcodes,"\\doscalefigure")
+ return data
+end
+function figures.done(data)
+ figures.n = figures.n + 1
+ data = data or figures.current()
+ local dr, du, ds = data.request, data.used, data.status
+ ds.width = tex.wd[figures.boxnumber]
+ ds.height = tex.ht[figures.boxnumber]
+ ds.xscale = ds.width/(du.width or 1)
+ ds.yscale = ds.height/(du.height or 1)
+ return data
+end
- function figures.dummy(data) -- fails
+function figures.dummy(data) -- fails
--~ data = data or figures.current()
--~ local dr, du, ds = data.request, data.used, data.status
--~ local r = node.new("rule")
@@ -610,9 +581,7 @@ do
--~ r.height = du.height or figures.defaultheight
--~ r.depth = du.depth or figures.defaultdepth
--~ tex.box[figures.boxnumber] = node.write(r)
- texsprint(tex.ctxcatcodes,"\\emptyfoundexternalfigure")
- end
-
+ texsprint(ctxcatcodes,"\\emptyfoundexternalfigure")
end
-- -- -- generic -- -- --
@@ -620,10 +589,10 @@ end
function figures.existers.generic(askedname)
--~ local result = io.exists(askedname)
--~ result = (result==true and askedname) or result
---~ local result = input.find_file(askedname) or ""
- local result = input.findbinfile(askedname) or ""
+--~ local result = resolvers.find_file(askedname) or ""
+ local result = resolvers.findbinfile(askedname) or ""
if result == "" then result = false end
- if figures.trace then
+ if trace_figures then
if result then
logs.report("figures","found: %s -> %s",askedname,result)
else
@@ -652,8 +621,9 @@ function figures.checkers.generic(data)
end
function figures.includers.generic(data)
local dr, du, ds = data.request, data.used, data.status
- dr.width = dr.width or du.width
- dr.height = dr.height or du.height
+ -- here we set the 'natural dimensions'
+ dr.width = du.width
+ dr.height = du.height
local hash = figures.hash(data)
local figure = figures.used[hash]
if figure == nil then
@@ -670,7 +640,7 @@ function figures.includers.generic(data)
tex.box[n] = img.node(figure) -- img.write(figure)
tex.wd[n], tex.ht[n], tex.dp[n] = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet)
ds.objectnumber = figure.objnum
- texsprint(tex.ctxcatcodes,"\\relocateexternalfigure")
+ texsprint(ctxcatcodes,"\\relocateexternalfigure")
end
return data
end
@@ -682,13 +652,14 @@ function figures.checkers.nongeneric(data,command)
local name = du.fullname or "unknown nongeneric"
local hash = name
if dr.object then
- if not job.objects["FIG::"..hash] then
- texsprint(tex.ctxcatcodes,command)
- texsprint(tex.ctxcatcodes,format("\\setobject{FIG}{%s}\\vbox{\\box\\foundexternalfigure}",hash))
+ -- hm, bugged
+ if not jobobjects.get("FIG::"..hash) then
+ texsprint(ctxcatcodes,command)
+ texsprint(ctxcatcodes,format("\\setobject{FIG}{%s}\\vbox{\\box\\foundexternalfigure}",hash))
end
- texsprint(tex.ctxcatcodes,format("\\global\\setbox\\foundexternalfigure\\vbox{\\getobject{FIG}{%s}}",hash))
+ texsprint(ctxcatcodes,format("\\global\\setbox\\foundexternalfigure\\vbox{\\getobject{FIG}{%s}}",hash))
else
- texsprint(tex.ctxcatcodes,command)
+ texsprint(ctxcatcodes,command)
end
return data
end
@@ -700,14 +671,25 @@ end
function figures.checkers.mov(data)
local dr, du, ds = data.request, data.used, data.status
- du.width = dr.width or figures.defaultwidth
- du.height = dr.height or figures.defaultheight
+ dr.width = (dr.width or figures.defaultwidth):todimen()
+ dr.height = (dr.height or figures.defaultheight):todimen()
+ du.width = dr.width
+ du.height = dr.height
du.foundname = du.fullname
- texsprint(tex.ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}",du.width,du.height))
- data = backends.pdf.insertmovie(data)
- texsprint(tex.ctxcatcodes,"\\stopfoundexternalfigure")
+ local code = backends.codeinjections {
+ width = du.width or dr.width,
+ height = du.height or dr.height,
+ factor = number.dimenfactors.bp,
+ ["repeat"] = dr["repeat"],
+ controls = dr.controls,
+ preview = dr.preview,
+ label = dr.label,
+ foundname = du.foundname,
+ }
+ texsprint(ctxcatcodes,format("\\startfoundexternalfigure{%ssp}{%ssp}%s\\stopfoundexternalfigure",du.width,du.height,code))
return data
end
+
figures.includers.mov = figures.includers.nongeneric
-- -- -- mps -- -- --
@@ -731,7 +713,7 @@ figures.includers.buffers = figures.includers.nongeneric
-- -- -- tex -- -- --
function figures.existers.tex(askedname)
- askedname = input.find_file(askedname)
+ askedname = resolvers.find_file(askedname)
return (askedname ~= "" and askedname) or false
end
function figures.checkers.tex(data)
@@ -761,38 +743,39 @@ figures.converters.svg = figures.converters.eps
--~ os.spawn(command)
--~ end
-
figures.bases = { }
figures.bases.list = { } -- index => { basename, fullname, xmlroot }
figures.bases.used = { } -- [basename] => { basename, fullname, xmlroot } -- pointer to list
figures.bases.found = { }
figures.bases.enabled = false
-function figures.bases.use(basename)
+local bases = figures.bases
+
+function bases.use(basename)
if basename == "reset" then
- figures.bases.list = { }
- figures.bases.used = { }
- figures.bases.found = { }
- figures.bases.enabled = false
+ bases.list = { }
+ bases.used = { }
+ bases.found = { }
+ bases.enabled = false
else
basename = file.addsuffix(basename,"xml")
- if not figures.bases.used[basename] then
+ if not bases.used[basename] then
local t = { basename, nil, nil }
- figures.bases.used[basename] = t
- figures.bases.list[#figures.bases.list+1] = t
- if not figures.bases.enabled then
- figures.bases.enabled = true
+ bases.used[basename] = t
+ bases.list[#bases.list+1] = t
+ if not bases.enabled then
+ bases.enabled = true
xml.registerns("rlx","http://www.pragma-ade.com/schemas/rlx") -- we should be able to do this per xml file
end
end
end
end
-function figures.bases.find(basename,askedlabel)
+function bases.find(basename,askedlabel)
basename = file.addsuffix(basename,"xml")
- local t = figures.bases.found[askedlabel]
+ local t = bases.found[askedlabel]
if t == nil then
- local base = figures.bases.used[basename]
+ local base = bases.used[basename]
local page = 0
if base[2] == nil then
-- no yet located
@@ -816,7 +799,7 @@ function figures.bases.find(basename,askedlabel)
name = xml.filters.text(e,"*:file"),
page = page,
}
- figures.bases.found[askedlabel] = t
+ bases.found[askedlabel] = t
return t
end
end
@@ -827,9 +810,9 @@ end
-- we can access sequential or by name
-function figures.bases.locate(askedlabel)
- for _, entry in ipairs(figures.bases.list) do
- local t = figures.bases.find(entry[1],askedlabel)
+function bases.locate(askedlabel)
+ for _, entry in ipairs(bases.list) do
+ local t = bases.find(entry[1],askedlabel)
if t then
return t
end
@@ -838,9 +821,9 @@ function figures.bases.locate(askedlabel)
end
function figures.identifiers.base(data)
- if figures.bases.enabled then
+ if bases.enabled then
local dr, du, ds = data.request, data.used, data.status
- local fbl = figures.bases.locate(dr.name or dr.label)
+ local fbl = bases.locate(dr.name or dr.label)
if fbl then
du.page = fbl.page
du.format = fbl.format
@@ -858,3 +841,14 @@ figures.identifiers.list = {
figures.identifiers.base,
figures.identifiers.default
}
+
+-- tracing
+
+statistics.register("graphics processing time", function()
+ local n = figures.n
+ if n > 0 then
+ return format("%s seconds including tex, n=%s", statistics.elapsedtime(figures),n)
+ else
+ return nil
+ end
+end)
diff --git a/tex/context/base/core-inc.mkii b/tex/context/base/core-inc.mkii
index fe3894d57..ce97a0d1b 100644
--- a/tex/context/base/core-inc.mkii
+++ b/tex/context/base/core-inc.mkii
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Figure Inclusion}
+
% todo: directory : system -> \allinputpaths (so that we can \usesubpath)
%D This is a reimplementation of the original module, which
@@ -30,82 +32,19 @@
\unprotect
-\startmessages dutch library: figures
- title: figuren
- 1: figuur -- is niet te vinden
- 2: figuur -- wordt niet preset
- 3: maten van -- worden extern vastgesteld
- 4: maten van -- geladen uit figuurfile zelf
- 5: maten van -- zijn onbekend
- 6: maten van -- berekend door rlxtools
- 8: figuurobject -- wordt opnieuw gebruikt
-\stopmessages
-
-\startmessages english library: figures
- title: figures
- 1: figure -- can not be found
- 2: figure -- is not preset
- 3: dimensions of -- are determined externally
- 4: dimensions of -- loaded from figurefile itself
- 5: dimensions of -- are unknown
- 6: dimensions of -- calculated by rlxtools
- 8: figureobject -- is reused
-\stopmessages
-
-\startmessages german library: figures
- title: Abbildungen
- 1: Abbildung -- kann nicht gefunden werden
- 2: Abbildung -- wird nicht erstellt
- 3: dimensions of -- are determined externally
- 4: Dimensionen von -- geladen aus der Abbildungsdatei selbst
- 5: Dimensions of -- are unknown
- 6: Dimensionen von -- ausgerechnet durch rlxtools
- 8: Abbildungobjekt -- wurde wiederverwandt
-\stopmessages
-
-\startmessages czech library: figures
- title: obrazy
- 1: obraz -- nelze nalezt
- 2: obraz -- nepritomen
- 3: dimensions of -- are determined externally
- 4: dimenze obrazu -- nacteny primo z jeho souboru
- 5: dimensions of -- are unknown
- 6: dimenze obrazu -- spocteny programem rlxtools
- 8: obrazovy objekt -- je znovu pouzit
-\stopmessages
-
-\startmessages italian library: figures
- title: figure
- 1: figura -- non trovata
- 2: la figura -- non è preimpostata
- 3: dimensions of -- are determined externally
- 4: dimensioni di -- caricate dal file di immagini stesso
- 5: dimensions of -- are unknown
- 6: dimensioni di -- calcolate da rlxtools
- 8: oggetto-figura -- riutilizzato
-\stopmessages
-
-\startmessages romanian library: figures
- title: figuri
- 1: figura -- nu poate fi gasita
- 2: figura -- nu este presetata
- 3: dimensions of -- are determined externally
- 4: dimensiunea figurii -- se incarca din fisierul insusi
- 5: dimensions of -- are unknown
- 6: dimensiunea figurii -- este calculata de rlxtools
- 8: obiectul figura -- este refolosit
-\stopmessages
-
-\startmessages french library: figures
- title: figures
- 1: la figure -- ne peut être trouvée
- 2: la figure -- n'est pas pré-sélectionnée
- 3: dimensions of -- are determined externally
- 4: les dimensions de -- chargées implicitement à partir du fichier de figure
- 5: dimensions of -- are unknown
- 6: les dimensions de -- calculées par rlxtools
- 8: figureobject -- est réutilisé
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
%D Due to the mere fact that \DVI|/|\PDF\ drivers differ in their
%D needs for figure dimensions, we have to provide the width,
@@ -827,8 +766,8 @@
\def\insertscaledfiguredriverdata
{\insertfiguredriverdata\finalscaleboxwidth\finalscaleboxheight}
-\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethrearguments\fi
-\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethrearguments\fi
+\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethreearguments\fi
+\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethreearguments\fi
\def\registerexternalfigure % no placement, handy for preprocessing
{\dotripleempty\doregisterexternalfigure}
diff --git a/tex/context/base/core-inc.mkiv b/tex/context/base/core-inc.mkiv
index 24a78e657..06c8dc306 100644
--- a/tex/context/base/core-inc.mkiv
+++ b/tex/context/base/core-inc.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Figure Inclusion}
+
%D todo:
%D
%D - color conversion
@@ -150,6 +152,8 @@
\let\@@efpreview \v!no
\let\@@efrepeat \v!no
%
+ \let\@@efforegroundcolor\empty
+ %
\let\@@efhfactor \empty
\let\@@efwfactor \empty
\let\@@effactor \empty
@@ -165,6 +169,8 @@
\let\@@eflines \empty
\let\@@efgrid \empty}
+\resetfigureusersettings
+
\appendtoks
\resetfigureusersettings
\to \everyexternalfigureresets
@@ -176,6 +182,8 @@
\doif\@@exoption\v!empty
{\skipexternalfigurestrue
\let\@@efframe\v!off}%
+ \doifsomething\@@efwidth {\doifdimensionelse\@@efwidth {\edef\@@efwidth {\the\dimexpr\@@efwidth }}\donothing}%
+ \doifsomething\@@efheight{\doifdimensionelse\@@efheight{\edef\@@efheight{\the\dimexpr\@@efheight}}\donothing}%
% seperation, seldom used
\doifseparatingcolorselse
{\let\@@efforegroundcolor\empty
@@ -346,8 +354,8 @@
\iftrialtypesetting \else \feedbackexternalfigure \fi
\fi}}
-\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethrearguments\fi
-\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethrearguments\fi
+\ifx\externalfigurereplacement\undefined\let\externalfigurereplacement\gobblethreearguments\fi
+\ifx\externalfigureplaceholder\undefined\let\externalfigureplaceholder\gobblethreearguments\fi
\let\feedbackexternalfigure\relax % \gobblefourarguments
\let\dowithfigure \relax
diff --git a/tex/context/base/core-inc.tex b/tex/context/base/core-inc.tex
deleted file mode 100644
index 88d52e746..000000000
--- a/tex/context/base/core-inc.tex
+++ /dev/null
@@ -1,18 +0,0 @@
-%D \module
-%D [ file=core-inc, % moved from core-fig
-%D version=2006.08.26, % overhaul of 1997.03.31
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Figure Inclusion,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Figure Inclusion}
-
-\loadmarkfile{core-inc}
-
-\endinput
diff --git a/tex/context/base/core-ini.tex b/tex/context/base/core-ini.tex
index 4f6e9fe1d..69edf9735 100644
--- a/tex/context/base/core-ini.tex
+++ b/tex/context/base/core-ini.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Initialization}
+\writestatus{loading}{ConTeXt Core Macros / Additional Initialization}
%D We will move more code to here, so that we become less dependent of the
%D orde in which modules are loaded.
diff --git a/tex/context/base/core-ins.tex b/tex/context/base/core-ins.tex
index c1185f7de..069153434 100644
--- a/tex/context/base/core-ins.tex
+++ b/tex/context/base/core-ins.tex
@@ -2,7 +2,7 @@
%D [ file=core-ins,
%D version=2002.04.16,
%D title=\CONTEXT\ Insertion Macros,
-%D subtitle=Insertions,
+%D subtitle=Insertions,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,14 +11,14 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Insertion Macros / General}
+\writestatus{loading}{ConTeXt Core Macros / Insertions}
%D Insertions are special data collections that are associated
%D to \TEX's internal page builder. When multiple footnote
%D classes were introduced, I decided to isolate some of the
-%D functionality in a module.
+%D functionality in a module.
-\unprotect
+\unprotect
\newtoks\@@insertionlist
@@ -29,7 +29,7 @@
%\def\installinsertion#1%
% {\ifx#1\undefined
% \newinsert#1%
-% \count#1\plusthousand
+% \count#1\plusthousand
% \skip #1\zeropoint
% \dimen#1\maxdimen
% \appendtoks\doprocessinsert#1\to\@@insertionlist
@@ -41,7 +41,7 @@
\fi
\ifx#1\relax % permits \csname...\endcsname
\newinsert#1%
- \count#1\plusthousand
+ \count#1\plusthousand
\skip #1\zeropoint
\dimen#1\maxdimen
\appendtoks\doprocessinsert#1\to\@@insertionlist
@@ -52,10 +52,10 @@
{\def\doprocessinsert##1{\ifvoid##1\else\insert##1{\unvbox##1}\fi}%
\processinsertions}
-%D For instance, when we postpone footnotes, we need to save
-%D some data related to the inserts. The next methods are
-%D far from ideal, but better than nothing. We save and
-%D restore box content and associated data independently.
+%D For instance, when we postpone footnotes, we need to save
+%D some data related to the inserts. The next methods are
+%D far from ideal, but better than nothing. We save and
+%D restore box content and associated data independently.
%D The box content is only restores when non||void.
\def\backupinsertion#1%
@@ -63,41 +63,41 @@
\def\installbackupinsertion#1%
{\expandafter\newinsert\csname\string#1\endcsname
- \count\backupinsertion#1\zerocount
+ \count\backupinsertion#1\zerocount
\skip \backupinsertion#1\zeropoint
\dimen\backupinsertion#1\maxdimen}
\def\saveinsertionbox#1%
- {\ifdim\ht#1>\zeropoint % hm, actually unknown
+ {\ifdim\ht#1>\zeropoint % hm, actually unknown
\global\setbox\backupinsertion#1\box#1%
\else
- \global\setbox\backupinsertion#1\box\voidb@x
+ \global\setbox\backupinsertion#1\emptybox
\fi}
\def\restoreinsertionbox#1%
- {\ifvoid\backupinsertion#1\else % if void, we keep the content
+ {\ifvoid\backupinsertion#1\else % if void, we keep the content
\global\setbox#1\box\backupinsertion#1%
\fi}
\def\eraseinsertionbackup#1%
- {\global\setbox\backupinsertion#1\box\voidb@x}
+ {\global\setbox\backupinsertion#1\emptybox}
-\def\saveinsertiondata#1%
+\def\saveinsertiondata#1%
{\global\skip \backupinsertion#1\skip #1%
\global\count\backupinsertion#1\count#1%
\global\dimen\backupinsertion#1\dimen#1}
-\def\restoreinsertiondata#1%
+\def\restoreinsertiondata#1%
{\global\skip #1\skip \backupinsertion#1%
\global\count#1\count\backupinsertion#1%
\global\dimen#1\dimen\backupinsertion#1}
-%D Auxiliary macros:
+%D Auxiliary macros:
\def\addinsertionheight#1\to#2%
{\ifvoid#1\else
- \advance#2 1\skip#1\relax
- \advance#2 \ht #1\relax
+ \advance#2 1\skip#1\relax
+ \advance#2 \ht #1\relax
\fi}
-\protect \endinput
+\protect \endinput
diff --git a/tex/context/base/core-int.tex b/tex/context/base/core-int.mkii
index 79061958d..1ca9d23d1 100644
--- a/tex/context/base/core-int.tex
+++ b/tex/context/base/core-int.mkii
@@ -15,145 +15,7 @@
%D Still to be done properly.
-\writestatus{loading}{Context Core Macros / Interaction}
-
-% interactions 5 and 6 to be translated
-
-\startmessages dutch library: interactions
- title: interactie
- 1: aspect ratio -- x -- (b x h)
- 2: actief
- 3: niet actief
- 4: geen paginasynchronisatie (--) in hmode
- 5: onbekend attachment --
- 6: attachment file -- bestaat niet
-\stopmessages
-
-\startmessages english library: interactions
- title: interaction
- 1: aspect ratio -- x -- (b x h)
- 2: active
- 3: inactive
- 4: no pagesynchronisation (--) in hmode
- 5: unknown attachment --
- 6: attachment file -- does not exist
-\stopmessages
-
-\startmessages german library: interactions
- title: Interaktion
- 1: Seitenverhaeltnis -- x -- (B x H)
- 2: aktiv
- 3: inaktiv
- 4: keine Seitensynchronisation (--) im hmode
- 5: unknown attachment --
- 6: attachment file -- does not exist
-\stopmessages
-
-\startmessages czech library: interactions
- title: interakce
- 1: pomer -- x -- (s x v)
- 2: aktivni
- 3: neaktivni
- 4: zadna strankova synchronizace (--) v hmode
- 5: unknown attachment --
- 6: attachment file -- does not exist
-\stopmessages
-
-\startmessages italian library: interactions
- title: interazione
- 1: rapporto -- x -- (b x a)
- 2: attiva
- 3: inattiva
- 4: sincronizzazione di pagina (--) non disponibile in hmode
- 5: unknown attachment --
- 6: attachment file -- does not exist
-\stopmessages
-
-\startmessages norwegian library: interactions
- title: interaksjon
- 1: forholdstall -- x -- (b x h)
- 2: aktiv
- 3: inaktiv
- 4: ingen sidesynkronisering (--) i hmode
- 5: unknown attachment --
- 6: attachment file -- does not exist
-\stopmessages
-
-\startmessages romanian library: interactions
- title: interactiuni
- 1: aspectul -- x -- (b x h)
- 2: activ
- 3: inactiv
- 4: nu exista sincronizare pt. pagini (--) in hmode
- 5: unknown attachment --
- 6: attachment file -- does not exist
-\stopmessages
-
-\startmessages french library: interactions
- title: interaction
- 1: ratio d'aspect -- x -- (b x h)
- 2: actif
- 3: inactif
- 4: pas de synchronisation de page (--) dans le hmode
- 5: le fichier joint -- est inconnu
- 6: le fichier joint -- n'existe pas
-\stopmessages
-
-\startmessages dutch library: versions
- title: versie
- 1: er mankeert een @+
- 2: markeren pagina's
- 3: geselecteerde pagina's: --
-\stopmessages
-
-\startmessages english library: versions
- title: version
- 1: missing @+
- 2: marking pages
- 3: selected pages: --
-\stopmessages
-
-\startmessages german library: versions
- title: Version
- 1: fehlendes @+
- 2: Erstelle Seiten
- 3: Ausgewaehlte Seiten: --
-\stopmessages
-
-\startmessages czech library: versions
- title: verze
- 1: postradam @+
- 2: oznacuji se strany
- 3: oznacene strany: --
-\stopmessages
-
-\startmessages italian library: versions
- title: version
- 1: @+ mancante
- 2: marcatura pagine
- 3: pagine selezionate: --
-\stopmessages
-
-\startmessages norwegian library: versions
- title: versjon
- 1: manglende @+
- 2: markerer sider
- 3: valgte sider: --
-\stopmessages
-
-\startmessages romanian library: versions
- title: versiuni
- 1: lipseste @+
- 2: pagini marcate
- 3: pagini selectate: --
-\stopmessages
-
-\startmessages french library: versions
- title: version
- 1: @+ manquant
- 2: marquage des pages
- 3: pages sélectionnées : --
-\stopmessages
+\writestatus{loading}{ConTeXt Core Macros / Interaction}
\unprotect
@@ -1129,8 +991,8 @@
% Hier volgen de synchronisatiemacro's:
\def\syncprefix{sync}
-\def\syncmarker{syncmark}
+%def\syncmarker{syncmark}
%\definemarking[\syncmarker]
%\setupmarking[\syncmarker][\c!expansie=\v!ja]
@@ -1534,7 +1396,7 @@
\def\complexinteractionbar[#1]%
{\doifelse{#1}\v!reset
- {\global\setbox\interactionbarbox\box\voidb@x}%
+ {\global\setbox\interactionbarbox\emptybox}%
{\bgroup
\iflocation
\checksubpages % goes wrong / loads \numberofpages too
diff --git a/tex/context/base/core-int.mkiv b/tex/context/base/core-int.mkiv
new file mode 100644
index 000000000..d02881801
--- /dev/null
+++ b/tex/context/base/core-int.mkiv
@@ -0,0 +1,2036 @@
+%D \module
+%D [ file=core-int,
+%D version=1995.01.01,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Interaction,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% evt interactionbaren runtime laden (scheelt 8K)
+
+%D Still to be done properly.
+
+\writestatus{loading}{ConTeXt Core Macros / Interaction}
+
+\unprotect
+
+% \expand vs \expanded
+
+% linked registers implementeren als een koppeling == mooier
+
+\presetlocalframed[\??lk]
+
+\newcounter\numberoflinks
+
+\def\stelkoppelingenin%
+ {\dodoubleargument\getparameters[\??lk]}
+
+\def\definieerkoppeling[#1]% % local loading !
+ {\doifundefined{\s!link:#1:\s!list}
+ {\expanded{\definetwopasslist{\s!link:#1}}%
+ \expanded{\doloadtwopassdata{\s!link:#1}}%
+ \getfirsttwopassdata{\s!link:#1}%
+ \letgvalue{\s!link:#1:f}\twopassdata
+ \getlasttwopassdata{\s!link:#1}%
+ \letgvalue{\s!link:#1:l}\twopassdata
+ \letgvalue{\s!link:#1:s}\noftwopassitems
+ \gettwopassdata{\s!link:#1}%
+ \letgvalue{\s!link:#1:c}\twopassdata
+ \letgvalue{\s!link:#1:n}\twopassdata}}
+
+\def\koppeling[#1]#2%
+ {\bgroup
+ \definieerkoppeling[#1]%
+ \doglobal\increment\numberoflinks
+ \gettwopassdata{\s!link:#1}%
+ \edef\numberoflinks{0\getvalue{\s!link:#1:s}}%
+ \edef\firstlink {0\getvalue{\s!link:#1:f}}%
+ \edef\lastlink {0\getvalue{\s!link:#1:l}}%
+ \edef\currentlink {0\getvalue{\s!link:#1:n}}%
+ \edef\prevlink {0\getvalue{\s!link:#1:c}}%
+ \iftwopassdatafound
+ \edef\nextlink{0\twopassdata}%
+ \letgvalue{\s!link:#1:n}\nextlink
+ \letgvalue{\s!link:#1:c}\currentlink
+ \else
+ \edef\nextlink{0\getvalue{\s!link:#1:l}}%
+ \fi
+ \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}%
+ \ifnum\noflinks<\plustwo
+ \locationfalse
+ \fi
+ \iflocation
+ \hbox
+ {\setinteractionparameter\c!width\!!zeropoint
+ \dogotosomepage\??lk\gotobegincharacter\firstlink\hss
+ \ifnum\noflinks>\plustwo
+ \hskip\@@lkdistance
+ \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss
+ \fi
+ \hskip\@@lkdistance
+ #2\relax
+ \hskip\@@lkdistance
+ \ifnum\noflinks>\plustwo
+ \dogotosomepage\??lk\goforwardcharacter\nextlink\hss
+ \hskip\@@lkdistance
+ \fi
+ \dogotosomepage\??lk\gotoendcharacter\lastlink}%
+ \else
+ \hbox{#2}%
+ \fi
+ \egroup}
+
+\def\definieerkoppeling[#1]% % local loading !
+ {\doifundefined{\s!link:#1:\s!list}
+ {\expanded{\definetwopasslist{\s!link:#1}}% \expanded{\doloadtwopassdata{\s!link:#1}}%
+ \getfirsttwopassdata{\s!link:#1}%
+ \let\firstlink\twopassdata
+ \getlasttwopassdata{\s!link:#1}%
+ \let\lastlink\twopassdata
+ \let\noflinks\noftwopassitems
+ \gettwopassdata{\s!link:#1}%
+ \let\currentlink\twopassdata
+ \let\nextlink\twopassdata
+ \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}}}
+
+\def\koppeling[#1]#2%
+ {\bgroup
+ \definieerkoppeling[#1]%
+ \doglobal\increment\numberoflinks
+ \gettwopassdata{\s!link:#1}%
+ \def\next[##1:##2:##3:##4:##5]%
+ {\edef\firstlink {0##1}%
+ \edef\lastlink {0##2}%
+ \edef\noflinks {0##3}%
+ \edef\prevlink {0##4}%
+ \edef\currentlink{0##5}}%
+ \expanded{\next[\getvalue{\s!link:#1:}]}%
+ \edef\nextlink{0\iftwopassdatafound\twopassdata\else\lastlink\fi}%
+ \setxvalue{\s!link:#1:}{\firstlink:\lastlink:\noflinks:\currentlink:\nextlink}%
+ \lazysavetwopassdata{\s!link:#1}{\numberoflinks}{\noexpand\realfolio}%
+ \ifnum\noflinks<\plustwo
+ \locationfalse
+ \fi
+ \iflocation
+ \hbox
+ {\setinteractionparameter\c!width\!!zeropoint
+ #2\relax
+ \hskip\@@lkdistance
+ \dogotosomepage\??lk\gotobegincharacter\firstlink\hss
+ \ifnum\noflinks>\plustwo
+ \dogotosomepage\??lk\gobackwardcharacter\prevlink\hss
+ \fi
+ \ifnum\noflinks>\plustwo
+ \dogotosomepage\??lk\goforwardcharacter\nextlink\hss
+ \hskip\@@lkdistance
+ \fi
+ \dogotosomepage\??lk\gotoendcharacter\lastlink}%
+ \else
+ \hbox{#2}%
+ \fi
+ \egroup}
+
+\let\setupinteractionscreens\empty
+
+\def\docalculateinteractionscreen
+ {\doifelse\@@scwidth\v!fit
+ {\!!widtha\leftcombitotal
+ \ifdim\backspace>\!!widtha\ifdim\backspace>\zeropoint\relax
+ \advance\backspace -\!!widtha
+ \fi\fi
+ \advance\!!widtha\rightcombitotal
+ \advance\!!widtha 2\dimexpr\@@scbackspace+\@@schoroffset\relax}
+ {\doifelse\@@scwidth\v!max
+ {\!!widtha\printpaperwidth}
+ {\!!widtha\@@scwidth}}%
+ \doifelse\@@scheight\v!fit
+ {\!!heighta\dimexpr\topheight+\topdistance\relax
+ \ifdim\topspace>\!!heighta\ifdim\topspace>\zeropoint\relax
+ \advance\topspace -\!!heighta
+ \fi\fi
+ \advance\!!heighta \dimexpr\makeupheight+\bottomdistance+\bottomheight\relax
+ \advance\!!heighta 2\dimexpr\@@sctopspace+\@@scveroffset\relax}
+ {\doifelse\@@scheight\v!max
+ {\!!heighta\printpaperheight}
+ {\!!heighta\@@scheight}}%
+ \doif\@@scdelay\v!none{\let\@@scdelay\zerocountervalue}}
+
+% The macro is not to be changed; only the \@@ia-variables
+% may be set! ConTeXt is the producer but we no longer
+% mention the pragma site, since we don't want to be bothered
+% with remarks about third party documents and/or associated
+% with documents produced outside our control.
+
+\def\doprepareidentity % beware, we need to construct
+ {\let\!!stringa\@@iakeyword % an unexpanded space separated
+ \let\@@iakeyword\empty % list of keywords from a comma
+ \def\doprepareidentity##1% % separated one
+ {\ifx\@@iakeyword\empty
+ \appended\def\@@iakeyword{##1}%
+ \else
+ \appended\def\@@iakeyword{ ##1}%
+ \fi}%
+ \@EA\processcommalist\@EA[\!!stringa]\doprepareidentity
+ \global\let\doprepareidentity\relax}
+
+%D The Creator field is changed per 12/04/2006 due to user presure. This
+%D means that I need to put my own status info someplace else.
+
+\def\initializeidentity
+ {\doprepareidentity
+ \dosetupidentity % no \expanded{..} will be done in special (else no pdfdoc)
+ {\@@iatitle}{\@@iasubtitle}{\@@iaauthor}%
+ {ConTeXt - \contextversion}%
+ {\@@iadate}{\@@iakeyword}%
+ \global\let\initializeidentity\relax}
+
+\appendtoks \initializeidentity \to \everyshipout
+
+\def\initializepaper
+ {\bgroup
+ \ifx\@@ppleft \empty
+ \ifx\@@ppright\empty
+ \ifx\@@pptop \empty
+ \ifx\@@ppbottom \empty
+ \ifx\@@pcstate\v!start
+ \locationfalse\fi\else
+ \locationfalse\fi\else
+ \locationfalse\fi\else
+ \locationfalse\fi\else
+ \locationfalse\fi
+ \iflocation % without screen settings
+ \egroup
+ \dosetuppaper\papersize\paperwidth\paperheight
+ \else
+ \egroup
+ \dosetuppaper\printpapersize\printpaperwidth\printpaperheight
+ \fi}
+
+\appendtoks \initializepaper \to \everyshipout
+
+\def\doinitializepaper
+ {\bgroup
+ \docalculateinteractionscreen
+ \ifdim\!!widtha>\paperwidth\ifdim\!!widtha>\zeropoint
+ \paperwidth\!!widtha
+ \fi\fi
+ \ifdim\!!heighta>\paperheight\ifdim\!!heighta>\zeropoint
+ \paperheight\!!heighta
+ \fi\fi
+ \dosetuppaper
+ {\printpapersize}
+ {\the\paperwidth}
+ {\the\paperheight}%
+ \egroup}
+
+\let\@@pcscreendata\empty
+
+\def\dosetupinteractionscreens % met a, b en \number
+ {\doifnot\@@pcstate\v!start\dodosetupinteractionscreens}
+
+\setvalue{\??sc\c!option\v!max }{1} % tzt share with driver
+\setvalue{\??sc\c!option\v!bookmark }{2} % tzt share with driver
+\setvalue{\??sc\c!option\v!fit }{3} % tzt share with driver
+\setvalue{\??sc\c!option\v!doublesided}{4} % tzt share with driver
+
+\def\dodosetupinteractionscreens % met a, b en \number
+ {\bgroup
+ \docalculateinteractionscreen
+ \!!counte=0\getvalue{\??sc\c!option\@@scoption}\relax
+ % niet waterdicht
+ \doifnot{\the\!!widtha\the\!!heighta}\@@pcscreendata
+ {\xdef\@@pcscreendata{\the\!!widtha\the\!!heighta}%
+ \showmessage\m!interactions1{\withoutpt\the\!!widtha,\withoutpt\the\!!heighta}}%
+ % needs to be split: dimensions for each page
+ % and mode per document and only once !
+ \dosetupscreen \backoffset\topoffset\!!widtha\!!heighta{\the\!!counte}%
+ \dosetupcropbox\backoffset\topoffset\!!widtha\!!heighta
+ \egroup}
+
+\def\dosetupinteractionscreen[#1]%
+ {\getparameters[\??sc][#1]%
+ \ifproductionrun
+ \let\initializepaper\doinitializepaper
+ \let\setupinteractionscreens\dosetupinteractionscreens
+ \fi}
+
+\appendtoks \setupinteractionscreens \to \everyfirstshipout % needed to get option=max etc working
+\appendtoks \setupinteractionscreens \to \everyshipout % needed for page/screen dimensions
+
+\def\setupinteractionscreen
+ {\dosingleempty\dosetupinteractionscreen}
+
+% \startinteractionmenu[rechts]
+% \but [eerste] eerste \\
+% \txt hello world \\
+% \but [tweede] tweede \\
+% \nop \\
+% \but [tweede] tweede \\
+% \rul whow \\
+% \but [tweede] tweede \\
+% \raw hello world \\
+% \but [tweede] tweede \\
+% \com \vfill \\
+% \but [derde] derde \\
+% \stopinteractionmenu
+
+\newif\iflocationmenupermitted
+
+\def\testinteractionmenu#1%
+ {\iflocation
+ \doifelse\@@iamenu\v!on
+ {\doifelsevalue{\??am#1\c!state}\v!start
+ {\global\locationmenupermittedtrue}
+ {\global\locationmenupermittedfalse}}
+ {\global\locationmenupermittedfalse}%
+ \else
+ \global\locationmenupermittedfalse
+ \fi}
+
+\def\dodisableinteractionmenu[#1][#2][#3]%
+ {\def\dododisableinteractionmenu##1%
+ {\doifelse{#3}{}
+ {\letvalue{\??am##1\c!obstruction}\empty}
+ {\edef\interactieblokkade{\getvalue{\??am##1\c!obstruction}}
+ \def\docommand####1{#1{####1}{\interactieblokkade}}% #1 = \remove or \add
+ \processcommalist[#3]\docommand
+ \setevalue{\??am##1\c!obstruction}{\interactieblokkade}}}%
+ \processcommalist[#2]\dododisableinteractionmenu}
+
+\def\disableinteractionmenu
+ {\dotripleempty\dodisableinteractionmenu[\addtocommalist]}
+
+\def\enableinteractionmenu
+ {\dotripleempty\dodisableinteractionmenu[\removefromcommalist]}
+
+% ja : kader/achtergrond met tekst
+% leeg : kader/achtergrond maar geen tekst
+% nee : alleen ruimte reserveren
+% geen : helemaal weglaten
+
+\newif\iflocationdummy
+\newif\ifskippedmenuitem
+
+\newif\iflocationempty
+\newif\iflocationclick
+
+% ja : kader/achtergrond met tekst
+% leeg : kader/achtergrond maar geen tekst
+% nee : alleen ruimte reserveren
+% geen : helemaal weglaten
+%
+% \setupinteractionmenu[right][samepage=yes, unknownreference=yes]
+% \setupinteractionmenu[right][samepage=empty,unknownreference=empty]
+% \setupinteractionmenu[right][samepage=no, unknownreference=no]
+% \setupinteractionmenu[right][samepage=none, unknownreference=none]
+%
+% \startinteractionmenu[right]
+% \but [firstpage] first \\
+% \but [lastpage] last \\
+% \but [somepage] crap \\
+% \stopinteractionmenu
+
+\def\dosetlocationboxcontent#1[#2]#3[#4]%
+ {\global\skippedmenuitemfalse
+ \setbox\locationbox\hbox
+ {\resetgoto % anders cyclische aanroep !
+ \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}}%
+ \iflocationclick
+ \hbox{\gotolocation{#4}{\box\locationbox}}%
+ \else
+ \hbox{\box\locationbox}%
+ \fi}
+
+\let\dosetlocationboxyes\dosetlocationboxcontent
+
+\def\dosetlocationboxempty#1[%
+ {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,}
+
+\def\dosetlocationboxno#1[%
+ {\dosetlocationboxcontent{#1}[\c!empty=\v!yes,\c!frame=,\c!background=,}
+
+\def\dosetlocationboxnone#1[#2]#3[#4]%
+ {\global\skippedmenuitemtrue}
+
+\def\setlocationboxyes#1[#2]#3[#4]%
+ {\locationclicktrue
+ \setbox\locationbox\hbox
+ {\resetgoto % anders cyclische aanroep !
+ \global\skippedmenuitemfalse
+ \gotolocation
+ {#4}% % needed
+ {\ifrealreferencepage
+ \ifcase\csname\??am\??am\csname#1\c!samepage\endcsname\endcsname\relax
+ \copycsname#1\c!color\endcsname\csname#1\c!contrastcolor\endcsname
+ \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \or
+ \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \or
+ \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \or
+ \global\skippedmenuitemtrue
+ \fi
+ \else
+ \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \fi}}%
+ \ifskippedmenuitem\else\box\locationbox\fi}
+
+\def\setlocationboxnop#1[#2]#3[#4]%
+ {\locationclickfalse
+ \setbox\locationbox\hbox
+ {\resetgoto % anders cyclische aanroep !
+ \global\skippedmenuitemfalse
+ \ifcase\csname\??am\??am\csname#1\c!unknownreference\endcsname\endcsname\relax
+ \localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \or
+ \localframed[#1][\c!empty=\v!yes,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \or
+ \localframed[#1][\c!empty=\v!yes,\c!frame=,\c!background=,#2]{\dolocationattributes{#1}\c!style\c!color{#3}}%
+ \or
+ \global\skippedmenuitemtrue
+ \fi}%
+ \ifskippedmenuitem\else\box\locationbox\fi}
+
+\def\setlocationboxraw#1[#2]#3[#4]%
+ {\localframed[#1][#2]{\dolocationattributes{#1}\c!style\c!color{#3}}}
+
+\def\setlocationbox#1[#2]#3[#4]%
+ {\bgroup % really needed !
+ \edef\permittedreferences{\csname#1\c!obstruction\endcsname}%
+ \doifreferencepermittedelse{#4}%
+ {\setlocationboxyes{#1}[#2]{#3}[#4]}%
+ {\setlocationboxnop{#1}[#2]{#3}[#4]}%
+ \egroup}
+
+\def\setlocationnop#1[#2]#3%
+ {\localframed[#1][#2]{#3}}
+
+\def\executeamboxcommands#1#2#3#4#5%
+ {%\processaction
+ % [\getvalue{\??am#1\c!dummy}]
+ % [ \v!yes=>\chardef\handleunknownmenuitem=0\relax,
+ % \v!empty=>\chardef\handleunknownmenuitem=1\relax,
+ % \v!no=>\chardef\handleunknownmenuitem=2\relax]%
+ \getvalue{\??am#1#3}\relax
+ \setamboxcommands{#1}{#4}%
+ \ignorespaces#2\unskip
+ \getvalue{\??am#1#5}}
+
+\newcounter\currentamposition
+
+\newtoks\everysetmenucommands
+
+\def\setamboxcommands#1#2%
+ {\def\currentmenu{#1}% % kan nog eerder
+ \def\currentsubmenu{#2}% % ? ?
+ \doglobal\newcounter\currentamposition
+ \the\everysetmenucommands}
+
+\def\menu@@amboxcommand#1\\%
+ {\dontleavehmode
+ \bgroup
+ \ignorespaces#1\unskip\relax
+ \ifskippedmenuitem \else
+ \getvalue{\??am\currentmenu\currentsubmenu}%
+ \fi
+ \egroup
+ \ignorespaces}
+
+\appendtoks
+ \let\@@amboxcommand\menu@@amboxcommand
+\to \everysetmenucommands
+
+\def\menu@raw[#1]#2\\%
+ {\@@amboxcommand\gotobox{\ignorespaces#2\unskip}[#1]\\}%
+
+\def\menu@but[#1]#2\\%
+ {\@@amboxcommand\do@@amposition\currentmenu{#1}{\setlocationbox{\??am\currentmenu}[]{\ignorespaces#2\unskip}[#1]}\\}%
+
+\def\menu@got[#1]#2\\% pas op! offset
+ {\@@amboxcommand\setlocationbox{\??am\currentmenu}[\c!frame=\v!off,\c!background=]{\ignorespaces#2\unskip}[#1]\\}%
+
+\def\menu@nop#1\\%
+ {\@@amboxcommand\setlocationboxraw{\??am\currentmenu}[\c!frame=\v!off,\c!background=,\c!empty=\v!yes]{\ignorespaces#1\unskip}[]\\}%
+
+\def\menu@txt#1\\%
+ {\@@amboxcommand\localframed[\??am\currentmenu][\c!frame=\v!off,\c!background=]{\ignorespaces#1\unskip}\\}%
+
+\def\menu@rul#1\\% ook \do@@amposition !
+ {\@@amboxcommand\localframed[\??am\currentmenu][]{\ignorespaces#1\unskip}\\}%
+
+\def\menu@com#1\\%
+ {\ignorespaces#1\unskip\ignorespaces}%
+
+\appendtoks
+ \let\raw\menu@raw
+ \let\but\menu@but
+ \let\got\menu@got
+ \let\nop\menu@nop
+ \let\txt\menu@txt
+ \let\rul\menu@rul
+ \let\com\menu@com
+\to \everysetmenucommands
+
+\ifx\do@@amposition\undefined
+ \let\do@@amposition\gobbletwoarguments % hook for positional thingies
+\fi
+
+\let\currentmenu\empty
+
+% beware : never change the concept of pbgoffset
+
+\def\menuparameter#1{\csname\??am\currentmenu#1\endcsname}
+
+\def\@@amhbox#1#2#3#4%
+ {\def\currentmenu{#3}%
+ \testinteractionmenu{#3}%
+ \iflocationmenupermitted
+ \bgroup
+ \showcomposition
+ \scratchdimen\dimexpr
+ \makeupwidth
+ +\pagebackgroundhoffset
+ +\pagebackgroundhoffset
+ -\menuparameter\c!leftoffset
+ -\menuparameter\c!rightoffset
+ \relax
+ \setbox\scratchbox\hbox to \scratchdimen
+ {\forgetall\executeamboxcommands{#3}{#4}\c!left\c!middle\c!right}%
+ \setbox\scratchbox\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}%
+ \wd\scratchbox\makeupwidth % geen \ht=#2 setting (yet)
+ \hskip\dimexpr-\pagebackgroundhoffset+\menuparameter\c!leftoffset\relax
+ \box\scratchbox
+ \egroup
+ \else
+ #1\relax
+ \fi}
+
+\def\@@amvbox#1#2#3#4% don't change skipping, this one works!
+ {\def\currentmenu{#3}%
+ \testinteractionmenu{#3}%
+ \iflocationmenupermitted
+ \bgroup
+ \showcomposition
+ \scratchdimen\dimexpr
+ \textheight
+ +\pagebackgroundvoffset
+ +\pagebackgroundvoffset
+ +\pagebackgrounddepth
+ -\menuparameter\c!topoffset
+ -\menuparameter\c!bottomoffset
+ \relax
+ \setbox\scratchbox\vbox to \scratchdimen
+ {\forgetall % Voor't geval de afstand
+ %\setupblank[\v!standard]% % (tijdelijk) is aangepast.
+ \restorestandardblank
+ \hsize#2\relax
+ \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after}%
+ \setbox\scratchbox\vbox{\hbox{\do@@ammenuposition{#3}{\box\scratchbox}}}%
+ \setbox\scratchbox\vbox
+ {\ht\scratchbox\zeropoint
+ \vskip\dimexpr-\pagebackgroundvoffset+\menuparameter\c!topoffset\relax
+ \box\scratchbox
+ \vskip\pagebackgroundvoffset}% overbodig
+ \ht\scratchbox\textheight
+ \wd\scratchbox#2\relax
+ \box\scratchbox
+ \egroup
+ \else
+ #1\relax
+ \fi}
+
+\ifx\do@@ammenuposition\undefined
+ \let\do@@ammenuposition\gobbleoneargument % hook for positional thingies
+\fi
+
+\setvalue{\??am\s!do\v!right }{\@@amvbox{\dodummypageskip\v!right }\rightedgewidth}
+\setvalue{\??am\s!do\v!left }{\@@amvbox{\dodummypageskip\v!left }\leftedgewidth }
+\setvalue{\??am\s!do\v!top }{\@@amhbox{\dodummypageskip\v!top }\topheight }
+\setvalue{\??am\s!do\v!bottom}{\@@amhbox{\dodummypageskip\v!bottom}\bottomheight }
+
+\def\dointeractionmenu#1#2%
+ {\getvalue{\??am\s!do\getvalue{\??am#1\c!location}}{#1}{#2}}
+
+\unexpanded\def\interactionmenu[#1]%
+ {\getvalue{\??am\c!menu#1}}
+
+\def\horizontalinteractionmenu#1#2#3#4%
+ {\ifdim#2>\zeropoint % new
+ \scratchdimen\zeropoint
+ \setbox\scratchbox\hbox
+ {\def\docommand##1%
+ {\doifnotvalue{\??am##1\c!state}\v!none
+ {\hskip\scratchdimen
+ \setbox2\hbox to #2
+ {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}%
+ \doifelsevalue{\??am##1\c!distance}\v!overlay
+ {\scratchdimen\zeropoint
+ \wd2\zeropoint}%
+ {\scratchdimen\getvalue{\??am##1\c!distance}}%
+ \box2}}%
+ \startinteraction
+ \processcommacommand[\getvalue{\??am#1}]\docommand
+ \stopinteraction}%
+ \wd\scratchbox#2\relax
+ \box\scratchbox
+ \fi}
+
+\def\verticalinteractionmenu#1#2#3#4%
+ {\ifdim#2>\zeropoint % new
+ \scratchdimen\zeropoint
+ \setbox\scratchbox\vbox
+ {\def\docommand##1%
+ {\doifnotvalue{\??am##1\c!state}\v!none
+ {\vskip\scratchdimen
+ \setbox2\vbox to #2
+ {\getvalue{\??am##1#3}\interactionmenu[##1]\getvalue{\??am##1#4}}%
+ \doifelsevalue{\??am##1\c!distance}\v!overlay
+ {\scratchdimen\zeropoint
+ \offinterlineskip
+ \dp2\zeropoint
+ \ht2\zeropoint}%
+ {\scratchdimen\getvalue{\??am##1\c!distance}}%
+ \box2}}%
+ \startinteraction
+ \processcommacommand[\getvalue{\??am#1}]\docommand
+ \stopinteraction}%
+ \ht\scratchbox#2\relax
+ \dp\scratchbox\zeropoint
+ \box\scratchbox
+ \fi}
+
+\letvalue{\??am\v!left }\empty
+\letvalue{\??am\v!right}\empty
+\letvalue{\??am\v!top }\empty
+\letvalue{\??am\v!bottom }\empty
+
+% todo : \defineinteractionmenuclass
+
+\def\interactionmenus[#1]%
+ {\iflocation
+ \getvalue{\??am\??am\c!menu#1}%
+ \else
+ \dodummypageskip{#1}%
+ \fi}
+
+\setvalue{\??am\??am\c!menu\v!left }{\horizontalinteractionmenu\v!left \leftedgewidth \c!left \c!right}
+\setvalue{\??am\??am\c!menu\v!right }{\horizontalinteractionmenu\v!right \rightedgewidth\c!left \c!right}
+\setvalue{\??am\??am\c!menu\v!top }{\verticalinteractionmenu \v!top \topheight \c!before\c!after}
+\setvalue{\??am\??am\c!menu\v!bottom}{\verticalinteractionmenu \v!bottom\bottomheight \c!before\c!after}
+
+% this can be implemented with the following command (which
+% is new, undocumented, experimental, untested, etc etc)
+
+\def\defineinteractionmenuclass
+ {\dodoubleargument\dodefineinteractionmenuclass}
+
+\def\dodefineinteractionmenuclass[#1][#2]% tag hori|veri
+ {\doifelse{#2}\v!vertical
+ {\setvalue{\??am\??am\c!menu#1}{\verticalinteractionmenu {#1}{\getvalue{\??am#1\c!width }}\c!before\c!after}}
+ {\setvalue{\??am\??am\c!menu#1}{\horizontalinteractionmenu{#1}{\getvalue{\??am#1\c!height}}\c!left\c!right }}}
+
+% \setupinteraction[menu=on,state=start]
+%
+% \defineinteractionmenuclass[test] [vertical]
+% \defineinteractionmenuclass[another][horizontal]
+%
+% \defineinteractionmenu[test] [left][state=start,width=4cm]
+% \defineinteractionmenu[another][top] [state=start,height=1cm]
+%
+% \startinteractionmenu[test]
+% \but [firstpage] test-a \\
+% \but [nextpage] test-b \\
+% \stopinteractionmenu
+%
+% \startinteractionmenu[another]
+% \but [firstpage] test-a \\
+% \but [nextpage] test-b \\
+% \stopinteractionmenu
+%
+% \setupheadertexts[{\interactionmenu[another]}]
+%
+% \starttext
+%
+% test \interactionmenu[test] \page
+% test \interactionmenu[test] \page
+%
+% \stoptext
+
+%D This can save complicated menu macros when one want to
+%D keep control over parts of a menu (i.e.\ turn them on and
+%D off). We could have achieved something similar with modes.
+
+\def\local@@ambox#1#2#3#4% don't change skipping, this one works!
+ {\bgroup
+ \testinteractionmenu{#3}%
+ \iflocationmenupermitted
+ \executeamboxcommands{#3}{#4}\c!before\c!inbetween\c!after
+ \else
+ #1\relax
+ \fi
+ \egroup}
+
+\def\includemenu[#1]%
+ {\doifvalue{\??am#1\c!state}\v!local
+ {\bgroup
+ \letvalue{\??am#1\c!state}\v!start
+ \let\@@amvbox\local@@ambox
+ \let\@@amhbox\local@@ambox
+ \getvalue{\??am\c!menu#1}%
+ \egroup}}
+
+%D We also need an explicit position control some day. I'll
+%D do that when I need it. [The stacking order.]
+
+\newif\ifextendedmenu
+
+% [name] [location]
+% [name] [location] [pars]
+
+\def\defineinteractionmenu
+ {\dotripleempty\dodefineinteractionmenu}
+
+\def\dodefineinteractionmenu[#1][#2][#3]%
+ {% main settings
+ \letvalue{\??am\c!menu#1}\empty
+ \setvalue{\@@dodolistelement#1}{\def\dosomelistelement{\dodomenulistelement{#1}}}%
+ \presetlocalframed[\??am#1]%
+ % register location
+ \expanded{\addtocommalist{#1}\@EA\noexpand\csname\??am#2\endcsname}%
+ % inherit settings
+ \doifnot{#1}{#2}
+ {\copyparameters[\??am#1][\??am#2]
+ [\c!left,\c!middle,\c!right,\c!before,\c!after,\c!inbetween,%
+ \c!width,\c!height,\c!distance,\c!offset,%
+ \c!frame,\c!framecolor,\c!rulethickness,%
+ \c!background,\c!backgroundcolor,\c!backgroundscreen,%
+ \c!style,\c!color,\c!contrastcolor,\c!samepage,\c!unknownreference,%
+ \c!leftoffset,\c!rightoffset,\c!topoffset,\c!bottomoffset]}%
+ % additional settings
+ \getparameters[\??am#1][\c!location=#2,\c!obstruction=,#3]}
+
+\def\setupinteractionmenu
+ {\dodoubleargument\dosetupinteractionmenu}
+
+\def\dosetupinteractionmenu[#1][#2]%
+ {\def\docommand##1{\getparameters[\??am##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+\expandafter\chardef\csname\??am\??am\v!yes \endcsname\zerocount
+\expandafter\chardef\csname\??am\??am\v!empty\endcsname\plusone
+\expandafter\chardef\csname\??am\??am\v!no \endcsname\plustwo
+\expandafter\chardef\csname\??am\??am\v!none \endcsname\plusthree
+\expandafter\chardef\csname\??am\??am \endcsname\plusone % default
+
+\processbetween{\v!interactionmenu}\dostartinteractionmenu
+
+\def\dostartinteractionmenu#1%
+ {\dodostartinteractionmenu#1\dodostopinteractionmenu}
+
+\def\dodostartinteractionmenu[#1]#2\dodostopinteractionmenu
+ {\setvalue{\??am\c!menu#1}{\extendedmenutrue\dointeractionmenu{#1}{#2}}}
+
+\def\resetinteractionmenu[#1]%
+ {\letvalue{\??am\c!menu#1}\empty}
+
+\def\dodomenulistelement#1#2#3#4#5#6#7%
+ {\setbox0=\hbox
+ {\let\gotolocation\gobbleoneargument % hack to catch last []
+ %\locationclickfalse % ipv ^
+ \docheckrealreferencepage{#7}%
+ \setlocationboxyes
+ {\??am#1}% % needed !
+ []% no settings
+ {\limitatetext{#5}{\getvalue{\??li#2\c!maxwidth}}{\unknown}}% % needed !
+ []}% normally the destination, catch by gobble
+ \@@amboxcommand\do@@amposition{#1}{#7}% beware, we pass the pagenumber
+ {\ignorespaces\linklisttoelement{#3}{#6}{#7}{\box0}\unskip}\\}
+
+% \scherm moet worden als \page
+
+\def\screen
+ {\dosingleempty\doscreen}
+
+\def\doscreen[#1]%
+ {\iflocation\page[#1]\fi}
+
+\unexpanded\def\menubutton
+ {\dodoubleempty\domenubutton}
+
+\def\domenubutton[#1]%
+ {\iffirstargument
+ \ifsecondargument
+ \@EAEAEA\domenubuttonB
+ \else
+ \doifassignmentelse{#1}
+ {\@EAEAEA\domenubuttonC}
+ {\@EAEAEA\domenubuttonD}%
+ \fi
+ \else
+ \@EA\domenubuttonA
+ \fi[#1]}
+
+\def\domenubuttonA[#1][#2]#3[#4]% normal button, no parameters
+ {\bgroup
+ %\locationdummytrue
+ \setlocationbox\??bt[]{#3}[#4]%
+ \egroup}
+
+\def\domenubuttonB[#1][#2]#3[#4]% menu button, with parameters
+ {\bgroup
+ %\locationdummytrue
+ \setlocationbox{\??am#1}[#2]{#3}[#4]%
+ \egroup}
+
+\def\domenubuttonC[#1][#2]#3[#4]% normal button, with parameters
+ {\bgroup
+ %\locationdummytrue
+ \setlocationbox\??bt[#1]{#3}[#4]%
+ \egroup}
+
+\def\domenubuttonD[#1][#2]#3[#4]% menu button, no parameters
+ {\bgroup
+ %\locationdummytrue
+ \setlocationbox{\??am#1}[]{#3}[#4]%
+ \egroup}
+
+\def\menubox
+ {\dodoubleempty\domenubox}
+
+\def\domenubox[#1][#2]#3%
+ {\bgroup
+ \let\setlocationbox\setlocationboxraw
+ \domenubutton[#1][#2]#3[]%
+ \egroup}
+
+% Hier volgen de synchronisatiemacro's:
+
+\def\syncprefix{sync}
+
+%def\syncmarker{syncmark}
+%\definemarking[\syncmarker]
+%\setupmarking[\syncmarker][\c!expansie=\v!ja]
+
+\newmark\syncmarker
+
+\newcounter\synccounter
+
+\newif\ifsynchronisation
+
+\def\startsynchronization%
+ {\iflocation\ifsynchronisation
+ \doglobal\increment\synccounter
+ \fi\fi}
+
+\def\stopsynchronization%
+ {\iflocation\ifsynchronisation
+ %\thisisdestination{\syncprefix:\synccounter}%
+ \pagereference[\syncprefix:\synccounter]%
+ \ifvmode
+ \@EA\setmark\@EA\syncmarker\@EA{\synccounter} % \marking[\syncmarker]{\synccounter}%
+ \else
+ \showmessage\m!interactions4\synccounter
+ \fi
+ \fi\fi}
+
+\def\synchronize%
+ {\startsynchronization
+ \stopsynchronization}
+
+\def\dosetupsynchronization[#1]%
+ {\getparameters[\??sy][#1]%
+ \doifelse\@@systate\v!start
+ \synchronisationtrue
+ \synchronisationfalse}
+
+\def\setupsynchronization
+ {\dosingleargument\dosetupsynchronization}
+
+\def\definesynchronization
+ {\dosingleargument\dodefinesynchronization}
+
+\def\setupsynchronizationbar
+ {\dodoubleargument\getparameters[\??ba]}
+
+\presetlocalframed[\??ba]
+
+\setvalue{synchronisatie\v!page}[#1]%
+ {\bgroup
+ %\setupinteraction[\c!width=\!!zeropoint]%
+ \setinteractionparameter\c!width\!!zeropoint
+ \setbox0\hbox
+ {\localframed[\??ba][]{\dolocationattributes\??ba\c!style\c!color{\strut\@@batext}}}%
+ \dontcomplain
+ \def\atthebottom
+ {\leaders\hrule\!!depth1ex\!!height-.5ex\hfil}%
+ \def\atthetop##1##2##3%
+ {\dimen0=\wd0
+ \divide\dimen0 3
+ \multiply\dimen0 ##2\relax
+ \dimen2=.25em % brrr
+ \advance\dimen0 -##3\dimen2
+ %\gotodestination
+ % {}{#1}{\syncprefix:##1}{}
+ % {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}}%
+ \gotobox
+ {\hbox to \dimen0{\color[\locationcolor\@@bacolor]{\atthebottom}}}%
+ [#1::\syncprefix:##1]}%
+ \hbox
+ {\def\check##1##2%
+ {\edef##2{0##1\syncmarker}%
+ \ifnum0##2=0 \def##2{1}\fi}%
+ \check\gettopmark\top
+ \check\getfirstmark\first
+ \check\getbotmark\bot
+ \setbox2\hbox to \wd0
+ {\ifnum\top=\first\relax
+ \ifnum\first=\bot\relax
+ \atthetop\first30\relax
+ \else
+ \atthetop\first21\hss\atthetop\bot11\relax
+ \fi
+ \else
+ \ifnum\first=\bot\relax
+ \atthetop\top11\hss\atthetop\first21\relax
+ \else
+ \atthetop\top11\hss\atthetop\first11\hss\atthetop\bot11\relax
+ \fi
+ \fi}%
+ \wd2=\zeropoint\box2
+ \box0\relax}%
+ \egroup}
+
+\setvalue{synchronisatie\v!local}[#1]%
+ {\bgroup
+ %\setupinteraction[\c!width=\!!zeropoint]%
+ \setinteractionparameter\c!width\!!zeropoint
+ \def\blackrule{\hbox{\vrule\!!height.5em\!!width.5em}}%
+ %\gotodestination
+ % {}{##1}{\syncprefix:#1}{0}
+ % {\color[\locationcolor\@@bacolor]{\blackrule}}%
+ \gotobox %
+ {\color[\locationcolor\@@bacolor]{\blackrule}}%
+ [#1::\syncprefix:\synccounter]%
+ \egroup}
+
+\def\synchronizationbar[#1][#2]%
+ {\iflocation\ifsynchronisation
+ \bgroup
+ \setupsynchronizationbar
+ [\c!text=\getvalue{doc:des:#1},#2]%
+ \getvalue{synchronisatie\@@baalternative}[#1]%
+ \egroup
+ \fi\fi}
+
+% A nice application of glue. All this code will be rewritten and
+% generalized.
+
+\newbox\interactionbarbox
+
+\newif\ifbarsymbol
+
+\def\dogotosomepage#1#2#3% nog checken !
+ {\hbox
+ {\iflocation
+ \ifnum#3=\realpageno
+ #2%
+ \else
+ \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}%
+ \fi
+ \else
+ #2%
+ \fi}}
+
+\def\dogotosomecontrastpage#1#2#3% nog checken, may replace previous
+ {\checkreferences % nodig ??
+ \hbox
+ {\iflocation
+ \ifnum#3=\realpageno
+ \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!contrastcolor}{#2}}%
+ \else
+ \gotorealpage\empty\empty{#3}{\doifsomething{#1}{\dolocationattributes{#1}\c!style\c!color}{#2}}%
+ \fi
+ \else
+ #2%
+ \fi}}
+
+\presetlocalframed[\??ib]
+
+\def\interactionbara % we need better control over contrastcolor
+ {\iflocation % maybe just use gotopage and set colors
+ \bgroup
+ \setinteractionparameter\c!width\zeropoint
+ \setupblackrules[\c!height=\v!max,\c!depth=\v!max]%
+ \!!widthb\dimexpr\@@ibwidth-2.75\emwidth\relax
+ \!!widtha\dimexpr\!!widthb/\lastpage\relax
+ \bgroup
+ \advance\realpageno\minusone
+ \ifvoid\interactionbarbox
+ \bgroup
+ \processaction
+ [\@@ibstep]
+ [ \v!small=>\scratchdimen.25\emwidth,
+ \v!medium=>\scratchdimen.5\emwidth,
+ \v!big=>\scratchdimen\emwidth,
+ \s!unknown=>\scratchdimen\!!widtha]%
+ \ifdim\!!widtha<\scratchdimen\relax
+ \!!counta\numexpr\scratchdimen/\!!widtha\relax
+ \else
+ \!!counta\@@ibstep\relax
+ \fi
+ \!!widtha\!!counta\!!widtha
+ \setbox\scratchbox\hbox{\blackrule[\c!width=\!!widtha,\c!color=middlegray]}% color here, else no mkiv
+ \global\setbox\interactionbarbox\hbox to \!!widthb
+ {\hss
+ \dostepwiserecurse\plusone\lastpage\!!counta
+ {\gotorealpage\empty\empty\recurselevel{\copy\scratchbox}}%
+ \hss}%
+ \global\wd\interactionbarbox\zeropoint
+ \egroup
+ \fi
+ \egroup
+ \noindent
+ \strut
+ \hbox to \@@ibwidth
+ {\dontcomplain
+ \setupblackrules[\c!width=\emwidth]%
+ \dogotosomecontrastpage\??ib\blackrule\firstpage
+ \hss
+ \copy\interactionbarbox
+ \hbox to \!!widthb
+ {\ifdim\!!widtha<\emwidth
+ \!!widtha\emwidth
+ \fi
+ \setupblackrules[\c!width=\!!widtha]%
+ \ifnum\realpageno>\plusone
+ \!!counta\numexpr\realpageno-\plustwo\relax
+ \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow
+ \dogotosomepage\??ib\blackrule\prevpage
+ \fi
+ \dogotosomecontrastpage\??ib{\blackrule[\c!width=.5em]}\realpageno
+ \ifnum\realpageno<\lastpage\relax
+ \dogotosomepage\??ib\blackrule\nextpage
+ \!!counta\numexpr\lastpage-\realpageno-\plusone\relax
+ \hskip\zeropoint\!!plus\!!counta \s!sp\relax % cm gives overflow
+ \fi}%
+ \hss
+ \dogotosomecontrastpage\??ib\blackrule\lastpage}%
+ \egroup
+ \fi}
+
+\def\interactionbarb
+ {\ifnum\lastpage>\firstpage\relax
+ \interactionbuttons[\v!firstpage,\v!previouspage,\v!nextpage,\v!lastpage]%
+ \fi}
+
+\def\interactionbarc
+ {\iflocation
+ \ifnum\lastpage>\plusone
+ \hbox to \@@ibwidth
+ {\setupblackrules[\c!height=\@@ibheight,\c!depth=\@@ibdepth]%
+ \scratchdimen\dimexpr(\@@ibwidth-4\emwidth)/\numexpr\lastpage+\minusone\relax\relax
+ \!!widtha\numexpr\realpageno+\minusone\relax\scratchdimen
+ \!!widthb\numexpr\lastpage-\realpageno\relax\scratchdimen
+ \startcolor[\locationcolor\@@ibcolor]%
+ \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\firstpage
+ \hss
+ \dogotosomepage\empty{\blackrule[\c!width=\!!widtha]}\prevpage
+ \color[\@@ibcontrastcolor]{\blackrule[\c!width=\emwidth]}%
+ \dogotosomepage\empty{\blackrule[\c!width=\!!widthb]}\nextpage
+ \hss
+ \dogotosomepage\empty{\blackrule[\c!width=\emwidth]}\lastpage
+ \stopcolor}%
+ \fi
+ \fi}
+
+\def\interactionbard
+ {\iflocation\ifshowingsubpage
+ \ifnum\nofsubpages>\plusone
+ \hbox \bgroup
+ \setinteractionparameter\c!width\!!zeropoint
+ \ifbarsymbol
+ \setupsymbolset[\@@iasymbolset]%
+ \def\dogotox##1%
+ {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi]}}%
+ \else
+ \def\dogotox##1%
+ {\hbox{\vrule\!!height\@@ibheight\!!depth \@@ibdepth\!!width \@@ibwidth}}%
+ \fi
+ \dostepwiserecurse\plusone\nofsubpages\plusone
+ {\bgroup
+ \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax
+ \ifnum\scratchcounter<\realpageno\relax
+ \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter
+ \else\ifnum\scratchcounter=\realpageno\relax
+ \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter
+ \else
+ \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter
+ \fi\fi
+ \egroup
+ \hskip\@@ibdistance}%
+ \unskip % not needed
+ \egroup
+ \fi
+ \fi\fi}
+
+\def\interactionbare% KAN WORDEN GECOMBINEERD MET D
+ {\iflocation\ifshowingsubpage
+ \ifnum\nofsubpages>\plusone
+ \bgroup
+ \!!widthb\dimexpr\nofsubpages\dimexpr\@@ibdistance\relax-\@@ibdistance\relax % (n-1)
+ \!!widtha\dimexpr(\@@ibwidth-\!!widthb)/\nofsubpages\relax
+ \ifdim\!!widtha<\@@ibdistance\relax
+ \interactionbarf
+ \else
+ \setinteractionparameter\c!width\!!zeropoint
+ \noindent
+ \hbox to \@@ibwidth
+ \bgroup
+ \ifbarsymbol
+ \setupsymbolset[\@@iasymbolset]%
+ \def\dogotox##1%
+ {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!next\fi}}%
+ \else
+ \def\dogotox##1%
+ {\hbox{\vrule\!!height\@@ibheight\!!depth\@@ibdepth\!!width\!!widtha}}%
+ \fi
+ \dostepwiserecurse\plusone\nofsubpages\plusone
+ {\bgroup
+ \scratchcounter\numexpr\recurselevel+\firstsubpage+\minusone\relax
+ \ifnum\scratchcounter<\realpageno\relax
+ \dogotosomecontrastpage\??ib{\dogotox0}\scratchcounter
+ \else\ifnum\scratchcounter=\realpageno\relax
+ \dogotosomecontrastpage\??ib{\dogotox1}\scratchcounter
+ \else
+ \dogotosomecontrastpage\??ib{\dogotox2}\scratchcounter
+ \fi\fi
+ \egroup
+ \hss}%
+ \unskip
+ \egroup
+ \fi
+ \egroup
+ \fi
+ \fi\fi}
+
+\def\interactionbarf % !! KAN WORDEN GECOMBINEERD MET D !!
+ {\iflocation\ifshowingsubpage
+ \ifnum\nofsubpages>\plusone
+ \setinteractionparameter\c!width\!!zeropoint
+ \noindent
+ \hbox to \@@ibwidth
+ \bgroup
+ \!!countb\zerocount
+ \loop % todo: \doloop
+ \advance\!!countb \plusone
+ %\!!countc\nofsubpages \divide\!!countc \!!countb \advance\!!countc \plusone
+ \!!countc\numexpr(\nofsubpages/\!!countb)+\plusone\relax % rounding
+ \!!widthb\@@ibdistance
+ \multiply\!!widthb \!!countc
+ \advance\!!widthb -\@@ibdistance
+ \!!widtha\@@ibwidth
+ \advance\!!widtha -\!!widthb
+ \divide\!!widtha \!!countc
+ \ifdim\!!widtha<\@@ibdistance\relax
+ \repeat
+ \ifnum\!!countc>\plusone
+ % this is not that well tested
+ \advance\!!countc \minustwo
+ \!!widtha-\@@ibdistance
+ \!!widtha\!!countc\!!widtha
+ \advance\!!widtha \@@ibwidth
+ \advance\!!countc \plusone
+ \divide\!!widtha \!!countc
+ \fi
+ \ifbarsymbol
+ \setupsymbolset[\@@iasymbolset]%
+ \def\dogotox##1%
+ {\hbox{\symbol[\ifcase##1 \v!previous\or\v!somewhere\or\v!somewhere\or\v!somewhere\or\v!next\fi}}%
+ \else
+ \def\dogotox##1%
+ {\hbox
+ {\!!heighta\@@ibheight
+ \!!deptha\@@ibdepth
+ \ifcase##1\relax
+ \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha
+ \or
+ \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha
+ \or
+ \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha
+ \or
+ \vrule\!!height.5\!!heighta\!!depth.5\!!deptha\!!width\!!widtha
+ \or
+ \vrule\!!height \!!heighta\!!depth \!!deptha\!!width\!!widtha
+ \fi}}%
+ \fi
+ \!!countc\numexpr\realpageno-\plustwo\relax
+ \!!countd\numexpr\realpageno+\plustwo\relax
+ \ifnum\!!countc<\plusone \!!countc\plusone \fi
+ \!!countf\zerocount
+ \dostepwiserecurse\firstsubpage\lastsubpage\plusone
+ {\!!doneafalse
+ \advance\!!countf \plusone
+ \ifnum\recurselevel=\firstsubpage\relax \!!doneatrue \fi
+ \ifnum\recurselevel=\lastsubpage\relax \!!doneatrue \fi
+ \if!!donea
+ \ifnum\recurselevel<\realpageno
+ \dogotosomecontrastpage\??ib{\dogotox0}\recurselevel
+ \else\ifnum\recurselevel>\realpageno
+ \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel
+ \else
+ \dogotosomecontrastpage\??ib{\dogotox4}\recurselevel
+ \fi\fi
+ \hss
+ \!!countf\zerocount
+ \else\ifnum\!!countf=\!!countb
+ \ifnum\recurselevel<\realpageno
+ \dogotosomecontrastpage\??ib{\dogotox1}\recurselevel
+ \else\ifnum\recurselevel>\realpageno
+ \dogotosomecontrastpage\??ib{\dogotox3}\recurselevel
+ \else
+ \dogotosomecontrastpage\??ib{\dogotox2}\recurselevel
+ \fi\fi
+ \hss
+ \!!countf\zerocount
+ \fi\fi}%
+ \unskip
+ \egroup
+ \fi
+ \fi\fi}
+
+\def\interactionbarg
+ {\ifnum\lastsubpage>\firstsubpage\relax
+ \interactionbuttons[\v!firstsubpage,\v!previoussubpage,\v!nextsubpage,\v!lastsubpage]%
+ \fi}
+
+\def\checkinteractionbar#1#2#3%
+ {\ifdim\@@ibwidth=\zeropoint\def\@@ibwidth{#1}\fi
+ \doifnothing\@@ibheight{\def\@@ibheight{#2}}%
+ \doifnothing\@@ibdepth{\def\@@ibdepth{#3}}}
+
+\def\complexinteractionbar[#1]%
+ {\doifelse{#1}\v!reset
+ {\global\setbox\interactionbarbox\emptybox}%
+ {\bgroup
+ \iflocation
+ \checksubpages % goes wrong / loads \numberofpages too
+ \getparameters[\??ib][#1]%
+ \doif\@@ibstate\v!start
+ {\startinteraction
+ \processaction % breedte defaults !
+ [\@@ibalternative]
+ [ c=>\checkinteractionbar{10em}\v!max \v!max,
+ d=>\checkinteractionbar{.5em}{.5em} \!!zeropoint,
+ e=>\checkinteractionbar{10em}{.5em} \!!zeropoint,
+ f=>\checkinteractionbar{10em}{.5em} \!!zeropoint,
+ \s!default=>\checkinteractionbar{10em}\v!broad\!!zeropoint,
+ \s!unknown=>\checkinteractionbar{10em}\v!broad\!!zeropoint]%
+ \doifelse\@@ibsymbol\v!yes
+ \barsymboltrue\barsymbolfalse
+ \getvalue{interactionbar\@@ibalternative}%
+ \stopinteraction}%
+ \fi
+ \egroup}}
+
+\definecomplexorsimpleempty\interactionbar
+
+\def\setupinteractionbar
+ {\dodoubleargument\getparameters[\??ib]}
+
+% Er wordt vooralsnog uitgegaan van een symmetrische
+% start-stop situatie.
+
+\def\c!profiel!! {profiel:} % brrr
+\def\c!versie!! {versie:}
+
+\def\dodefineprofile[#1][#2]%
+ {\iflocation
+ \def\dododefineprofile##1%
+ {\def\dodododefineprofile####1%
+ {\doifdefinedelse{\c!profiel!!####1}%
+ {\edef\!!stringa{\getvalue{\c!profiel!!####1}}%
+ \setevalue{\c!profiel!!####1}{\!!stringa,##1}}%
+ {\setevalue{\c!profiel!!####1}{##1}}}%
+ \processcommalist[#2]\dodododefineprofile}%
+ \processcommalist[#1]\dododefineprofile
+ \fi}
+
+\def\defineprofile%
+ {\dodoubleargument\dodefineprofile}
+
+% Als met \getpar wordt gewerkt, dan moet \next worden toegepast.
+
+% TZT initialisatie!
+
+\def\profilepage{}
+
+\let\dosetprofilepage\relax
+\let\dogetprofilepage\relax
+
+\def\processprofile#1[#2]%
+ {\iflocation
+ \par % needed for pdftex
+ \bgroup
+ \dosetprofilepage
+ \dogetprofilepage
+ \def\processoneprofile##1##2%
+ {\ExpandBothAfter\doifinsetelse{##2}{\processedprofiles}%
+ {\doifsomething{##1}{(##1)}}%
+ {\addtocommalist{##2}\processedprofiles
+ ##1\relax
+ \ifcase#1\relax
+ \dobeginofprofile{##2}\paperwidth\paperheight\profilepage
+ \else
+ \doendofprofile
+ \fi}}%
+ \let\processedprofiles\empty
+ \def\doprocessprofile##1%
+ {\doifelse{\@@pfoption}{\v!test}%
+ {\goodbreak\blank\nobreak\tt[\space
+ \ifcase#1\v!start\else\v!stop\fi profiel\space ##1:\space
+ \doifdefinedelse{\c!profiel!!##1}%
+ {\def\dodoprocessprofile####1%
+ {\processoneprofile
+ {\goto{####1}[\c!profiel!!####1]}%
+ {####1}%
+ \space}%
+ \processcommacommand
+ [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}%
+ {- }%
+ ]\nobreak\blank}%
+ {\doifdefined{\c!profiel!!##1}%
+ {\def\dodoprocessprofile####1%
+ {\processoneprofile{}{####1}}%
+ \processcommacommand
+ [\getvalue{\c!profiel!!##1}]\dodoprocessprofile}}}%
+ \processcommalist[#2]\doprocessprofile
+ \egroup
+ \par % needed for pdftex
+ \fi}
+
+\def\startprofile[#1]%
+ {\iflocation
+ \bgroup
+ \addtocommalist{#1}\actualprofile
+ \def\stopprofile%
+ {\processprofile1[#1]%
+ \egroup}%
+ \def\next{\processprofile0[#1]}% % \DoAfterFi \processprofile0[#1]%
+ \else % ^^^^^^^^^^ will be obsolete
+ \let\next\relax % since ugly and never used
+ \fi
+ \next}
+
+\let\stopprofile\relax
+
+\def\dofollowprofile#1[#2]%
+ {\iflocation
+ \hbox
+ {\dohandlegoto
+ {\dolocationattributes\??ia\c!style\c!color{#1\presetgoto}}%
+ {\dostartgotoprofile\buttonwidth\buttonheight{#2}}%
+ {\dostopgotoprofile}}%
+ \else
+ {#1}%
+ \fi}
+
+\def\followprofile#1[#2]%
+ {\iflocation
+ \doif\@@pfoption\v!test{\pagereference[\c!profiel!!#2]}%
+ \dofollowprofile{#1}[#2]%
+ \fi}
+
+\def\setupprofiles%
+ {\dodoubleargument\getparameters[\??pf]}
+
+% Als er nog geen tekst op de pagina staat, dan heeft het
+% profiel betrekking op het bovenstaande, dus soms een vorige
+% pagina! Vreemd, omdat PDF paginagewijs werkt. Gelukkig
+% biedt /page een oplossing. Echter: expansie van een
+% \special kan niet worden uitgesteld, zodat alleen een
+% two-pass een oplossing vormt. Het onderstaande kan komen
+% te vervallen als Acrobat dit ondervangt. Het scheelt een
+% pass en een lijst.
+%
+% Er kunnen eventueel twee lijsten worden gebruikt. Een voor
+% het begin (start) en een voor het eind (stop). Nu staat
+% alles in een lijst.
+
+\definetwopasslist\s!profile
+
+\newcounter\currentprofile
+
+\def\dosetprofilepage%
+ {\doglobal\increment\currentprofile
+ \lazysavetwopassdata{\s!profile}{\currentprofile}{\noexpand\realfolio}}
+
+\def\dogetprofilepage%
+ {\gettwopassdata{\s!profile}%
+ \let\profilepage=\twopassdata}
+
+% is this stuff used at all
+
+\newcounter\versionlevel
+\newcounter\versionorder
+
+\newif\ifrecentversion
+
+\let\oldatcharacter=@
+
+\def\minimumversion{0}
+\def\actualversion{0}
+
+\def\dosetupversions[#1]%
+ {\getparameters[\??ve][#1]
+ \stripcharacter.\from\@@venumber\to\minimumversion}
+
+\def\setupversions
+ {\dosingleargument\dosetupversions}
+
+\definetwopasslist\s!versionbegin
+\definetwopasslist\s!versionend
+
+\let\actualprofile\empty
+
+\def\doresetpageversion
+ {\lazysavetwopassdata{\s!versionend}{\versionorder}{\noexpand\realfolio}}
+
+\def\dosetpageversion#1%
+ {\recentversiontrue
+ \doglobal\increment\versionorder\relax
+ \lazysavetwopassdata{\s!versionbegin}{\versionorder}{\noexpand\realfolio}%
+ \let\resetpageversion\doresetpageversion}
+
+\def\recentcontributions{}
+
+\def\checkrecentcontributions%
+ {\gettwopassdata{\s!versionbegin}%
+ \iftwopassdatafound
+ \!!counta\twopassdata\relax
+ \gettwopassdata{\s!versionend}%
+ \iftwopassdatafound
+ \!!countb\twopassdata\relax
+ \doglobal\increment\versionorder\relax
+ \savetwopassdata{\s!versionbegin}{\versionorder}{\the\!!counta}%
+ \savetwopassdata{\s!versionend }{\versionorder}{\the\!!countb}%
+ \dostepwiserecurse\!!counta\!!countb\plusone
+ {\@EA\doglobal\@EA\addtocommalist\@EA{\recurselevel}{\recentcontributions}}%
+ \let\next\checkrecentcontributions
+ \else
+ \let\next\relax
+ \fi
+ \else
+ \let\next\relax
+ \fi
+ \next}
+
+\def\docheckpageversion
+ {\ExpandBothAfter\doifinsetelse{\realfolio}{\recentcontributions}
+ {\pageselectedtrue}%
+ {\pageselectedfalse}}
+
+\let\setpageversion \gobbleoneargument
+\let\resetpageversion \relax
+\let\checkpageversion \relax
+
+\def\complexstartversion[#1]%
+ {\bgroup
+ \doifelsenothing\actualprofile
+ {\startprofile[#1]}%
+ {\startprofile[#1,\actualprofile]}%
+ \def\docomplexstartversie##1%
+ {\stripcharacter.\from##1\to\actualversion
+ \ifnum\versionlevel>\zerocount\relax
+ \ifnum\actualversion=\zerocount
+ \setpageversion\actualversion % unknown version
+ \else
+ \ifnum\actualversion<\minimumversion\relax
+ \relax % old version
+ \else
+ \setpageversion\actualversion % new version
+ \fi
+ \fi
+ \fi}%
+ \doglobal\increment\versionlevel\relax
+ \doifelsenothing{#1}
+ {\docomplexstartversie{0}}%
+ {\processcommalist[#1]\docomplexstartversie}}
+
+\definecomplexorsimpleempty\startversion
+
+\def\stopversion
+ {\stopprofile
+ \doglobal\decrement\versionlevel
+ \ifnum\versionlevel<\zerocount
+ \showmessage\m!versions1\empty
+ \else
+ \resetpageversion
+ \egroup
+ \fi}
+
+\def\markversion
+ {\showmessage\m!versions2\empty
+ \let\setpageversion\dosetpageversion
+ \let\resetpageversion\relax
+ \let\checkpageversion\relax}
+
+\def\selectversion
+ {\checkrecentcontributions
+ \showmessage\m!versions3\recentcontributions
+ \let\setpageversio\gobbleoneargument
+ \let\resetpageversion\relax
+ \let\checkpageversion\docheckpageversion}
+
+\def\dodefineversion[#1][#2]%
+ {\setvalue{\c!versie!!#1}{#2}%
+ \defineprofile[#1][#2]}
+
+\def\defineversion
+ {\dodoubleargument\dodefineversion}
+
+\def\followversion
+ {\followprofile}
+
+\def\followprofileversion#1[#2][#3]%
+ {\def\docommand##1%
+ {\defineprofile[#2#3][##1]}%
+ \processcommacommand[\getvalue{\c!versie!!#3}]\docommand
+ \followprofile#1[#2#3]}
+
+\newcounter\currentpagetransition
+
+\newif\ifrandomtransitions
+
+\def\setuppagetransitions%
+ {\dosingleempty\dosetuppagetransitions}
+
+\def\dosetuppagetransitions[#1]%
+ {\doifelsenothing{#1}
+ {\doifnot\@@scdelay\v!none
+ {\let\setpagetransition\setsomepagedelay}}
+ {\doifelse{#1}\v!start
+ {\doifnot\@@scdelay\v!none
+ {\let\setpagetransition\setsomepagedelay}}
+ {\doglobal\newcounter\currentpagetransition
+ \doifinsetelse{#1}{\v!reset,\v!stop}
+ {\let\setpagetransition\relax}
+ {\let\setpagetransition\setsomepagetransition
+ \doifinsetelse\v!random{#1}
+ {\randomtransitionstrue}{\randomtransitionsfalse}%
+ \edef\userpagetransitions{#1}%
+ \@EA\removefromcommalist\@EA{\v!random}\userpagetransitions
+ \ifx\userpagetransitions\empty
+ \let\userpagetransitions\pagetransitions
+ \fi}}}}
+
+\def\setsomepagedelay
+ {\expanded{\dosetpagetransition{0}{\@@scdelay}}}
+
+\def\setsomepagetransition
+ {\iflocation
+ \ifrandomtransitions
+ \expanded{\getcommalistsize[\userpagetransitions]}%
+ \getrandomnumber\currentpagetransition1\commalistsize
+ \else
+ \doglobal\increment\currentpagetransition
+ \fi
+ \expanded{\getfromcommalist[\userpagetransitions][\currentpagetransition]}%
+ \doifnumberelse\commalistelement
+ {\expanded{\getfromcommalist[\pagetransitions][\commalistelement]}}
+ {}%
+ \ifx\commalistelement\empty
+ \doglobal\newcounter\currentpagetransition
+ \setsomepagetransition
+ \else
+ \doifelse\@@scdelay\v!none
+ {\expanded{\dosetpagetransition{\commalistelement}{0}}}
+ {\expanded{\dosetpagetransition{\commalistelement}{\@@scdelay}}}%
+ \fi
+ \fi}
+
+\prependtoks \setpagetransition \to \everyshipout
+
+% temporary here
+
+%D \startbuffer
+%D \dorecurse{10}
+%D {\horizontalpositionbar
+%D \pos\recurselevel \min1 \max10
+%D \token\framed{\recurselevel}%
+%D \\}
+%D
+%D \hbox to 15em
+%D {\hss
+%D \dorecurse{10}
+%D {\verticalpositionbar\pos\recurselevel\min1\max10\token\blackrule\\
+%D \hss}}
+%D \stopbuffer
+
+\def\horizontalpositionbar\pos#1\min#2\max#3\token#4\\%
+ {\hbox to \hsize
+ {\hskip\zeropoint\!!plus #1\!!fill
+ \hskip\zeropoint\!!plus-#2\!!fill
+ #4\relax
+ \hskip\zeropoint\!!plus #3\!!fill
+ \hskip\zeropoint\!!plus-#1\!!fill}}
+
+\def\verticalpositionbar\pos#1\min#2\max#3\token#4\\%
+ {\vbox to \vsize
+ {\vskip\zeropoint\!!plus #1\!!fill
+ \vskip\zeropoint\!!plus-#2\!!fill
+ \hbox{#4}\relax
+ \vskip\zeropoint\!!plus #3\!!fill
+ \vskip\zeropoint\!!plus-#1\!!fill}}
+
+\def\horizontalgrowingbar\pos#1\min#2\max#3\height#4\depth#5\\%
+ {\hbox to \hsize
+ {\scratchcounter#1%
+ \advance\scratchcounter -#2%
+ \advance\scratchcounter \plusone
+ \leaders\vrule\hskip\zeropoint\!!plus \scratchcounter\!!fill
+ \vrule\!!width\zeropoint\!!height#4\!!depth#5%
+ \hskip\zeropoint\!!plus #3\!!fill
+ \hskip\zeropoint\!!plus-#1\!!fill}}
+
+\def\verticalgrowingbar\pos#1\min#2\max#3\width#4\\%
+ {\vbox to \vsize
+ {\scratchcounter#1%
+ \advance\scratchcounter -#2%
+ \advance\scratchcounter \plusone
+ \leaders\hrule\vskip\zeropoint\!!plus\scratchcounter\!!fill
+ \hrule\!!width#4\!!height\zeropoint\!!depth\zeropoint
+ \vskip\zeropoint\!!plus #3\!!fill
+ \vskip\zeropoint\!!plus-#1\!!fill}}
+
+\newbox\commentbox
+
+\def\doflushcommentanchors
+ {\let\next\relax % new
+ \processaction
+ [\@@cclocation]
+ [% \v!text=>\let\next\relax, % new
+ \v!inmargin=>\let\next\inmargin, % brr not the same as inleft|rightmargin
+ \v!leftedge=>\let\next\inleftedge,
+ \v!rightedge=>\let\next\inrightedge,
+ \v!leftmargin=>\let\next\inleftmargin,
+ \v!rightmargin=>\let\next\inrightmargin]%
+ \next{\hbox{\raise\strutht\box\commentbox}}}
+
+\def\flushcommentanchors % in everypar so indirect
+ {\ifvoid\commentbox\else \doflushcommentanchors \fi}
+
+\def\setupcomment
+ {\dodoubleargument\getparameters[\??cc]}
+
+\setvalue{\e!start\v!comment}% the dummy triple gobbles trailing spaces
+ {\dotripleempty\dostartcommentaar}
+
+\def\comment
+ {\dodoubleempty\docomment}
+
+\def\dodocomment#1%
+ {\!!widtha\@@ccwidth
+ \!!heighta\@@ccheight
+ \doifelse\@@ccoption\v!max
+ {\let\@@ccopen \!!plusone}{\let\@@ccopen \!!zerocount}%
+ \doifelse\@@ccoption\v!buffer
+ {\let\@@cccollect\!!plusone}{\let\@@cccollect\!!zerocount}%
+ \preparecommentvariables
+ \doinsertcomment
+ \@@cctitle\!!widtha\!!heighta
+ \@@cccolor\@@ccopen\@@ccsymbol
+ \@@cccollect{#1}}
+
+\def\preparecommentvariables % more will move here as with fields
+ {\let\@@DriverCommentLayer\@@cctextlayer}
+
+\def\dopreparecommentaar#1#2%
+ {\doifassignmentelse{#1}
+ {\getparameters[\??cc][#1]}
+ {\getparameters[\??cc][\c!title=#1,#2]}%
+ \obeylines
+ \doif\@@ccspace\v!yes\obeyspaces}
+
+\def\dostartcommentaar[#1][#2][#3]%
+ {\bgroup
+ \doifelse\@@ccstate\v!start
+ {\dopreparecommentaar{#1}{#2}%
+ \long\def\docommand##1%
+ {\global\setbox\commentbox\frozenhbox
+ {\hbox to \zeropoint
+ {\struttedbox{\tbox{\dodocomment{##1}}}\hss}%
+ \hskip\ifvoid\commentbox\@@ccmargin\else\@@ccdistance\fi
+ \box\commentbox}%
+ \egroup}}%
+ {\long\def\docommand##1%
+ {\egroup}}%
+ \grabuntil{\e!stop\v!comment}\docommand}
+
+\letvalue{\e!stop\v!comment}\relax % handy for \expanded{...}
+
+\def\docomment[#1][#2]#3%
+ {\doif\@@ccstate\v!start
+ {\hbox to \zeropoint
+ {\dopreparecommentaar{#1}{#2}%
+ \hskip-\@@ccmargin
+ \struttedbox{\tbox{\dodocomment{#3}}\hss}}}%
+ \ignorespaces}
+
+% \startcomment
+% hello beautiful\\world
+% \stopcomment
+%
+% \startcomment[hello]
+% hello << \'e\'erste >>
+% beautiful
+% world
+% \stopcomment
+%
+% \startcomment[hello][color=green,width=4cm,height=3cm]
+% hello \leftguillemot\ \'e\'erste \rightguillemot\
+% beautiful
+% world
+% \stopcommentaar
+%
+% \startcomment[hello][color=green,width=4cm,height=3cm]
+% hello \leftguillemot\ \'e\'erste \rightguillemot\ test
+%
+% beautiful
+%
+% world
+% \stopcomment
+%
+% \startcomment[symbol=Balloon]
+% Do we want this kind of rubish? And, why isn't this and
+% some more features related to text annotations so poorly
+% (actually not) documented? Anyhow, by providing this
+% functionality we demonstrate that \pdfTeX\ can do it. By
+% the way, it's funny that when in Acrobat we scale up the
+% text, the symbols scale down.
+% \stopcomment
+
+% \definesymbol [comment-normal][{\externalfigure[cow.pdf]}]
+% \definesymbol [comment-down] [{\externalfigure[cow.pdf]}]
+%
+% \def\CowSymbol#1#2%
+% {\scale
+% [\c!height=#1]
+% {\startMPcode
+% loadfigure "koe.mp" number 1 ;
+% refill currentpicture withcolor #2 ;
+% \stopMPcode}}
+%
+% \definesymbol [comment-normal]
+% [\CowSymbol{4ex}{red}]
+%
+% \definesymbol [comment-down]
+% [\CowSymbol{4ex}{green}]
+%
+% \setupcomment
+% [\c!symbol={comment-normal,comment-down},
+% \c!option=\v!buffer]
+%
+% \setupfootertexts[\placecomments]
+
+\def\placecomments
+ {\doflushcomments}
+
+% \setupinteraction[state=start]
+%
+% \useattachment[test.tex]
+% \useattachment[whatever][test.tex]
+% \useattachment[whatever][newname][test.tex]
+% \useattachment[whatever][title][newname][test.tex]
+%
+% % \setupattachments[\c!symbol={symbol-normal,symbol-down}]
+%
+% \starttext \attachment[whatever] \stoptext
+
+\definesystemvariable{at}
+
+\def\useattachment
+ {\doquadrupleempty\douseattachment}
+
+\def\douseattachment[#1][#2][#3][#4]% tag title newname filename
+ {\iffourthargument
+ \setgvalue{\??at:#1}{{#2}{#3}{#4}}% tooltip kind of case
+ \else\ifthirdargument
+ \setgvalue{\??at:#1}{{#2}{#2}{#3}}% full path case
+ \else\ifsecondargument
+ \setgvalue{\??at:#1}{{#2}{#2}{#2}}% obvious case
+ \else
+ \setgvalue{\??at:#1}{{#1}{#1}{#1}}% worst case
+ \fi\fi\fi}
+
+\let\attachmenttitle\empty
+\let\attachmentname \empty
+\let\attachmentfile \empty
+
+\def\getattachmentdata[#1]%
+ {\edef\attachmenttitle{\filterfromvalue{\??at:#1}31}% description
+ \edef\attachmentname {\filterfromvalue{\??at:#1}32}% new name
+ \edef\attachmentfile {\filterfromvalue{\??at:#1}33}% original
+ \expandafter\splitstring\attachmentname\at.\to\!!stringa\and\!!stringb
+ \ifx\!!stringb\empty % no suffix, so we need to inherit it
+ \expandafter\splitstring\attachmentfile\at.\to\!!stringc\and\!!stringd
+ \edef\attachmentname{\attachmentname.\!!stringd}%
+ \fi}
+
+\def\attachment
+ {\dodoubleempty\doattachment}
+
+\def\doattachment[#1][#2]% currently title equals newname
+ {\iflocation
+ \ifsecondargument
+ \doifundefined{\??at:#2}
+ {\showmessage\m!interactions6{#2}%
+ \useattachment[#2]}%
+ \doif\@@atstate\v!start
+ {\bgroup
+ \getattachmentdata[#2]%
+ \doiffileelse\attachmentfile
+ {\setupattachments[#1]%
+ \presetattachmentvariables
+\struttedbox{\tbox{%
+ \doattachfile
+ \attachmenttitle
+ {1em}\strutheight\strutdepth\@@atcolor\@@atsymbol
+ \attachmentname
+ \attachmentfile}%
+}}%
+ {\showmessage\m!interactions5\attachmentfile}%
+ \egroup}%
+ \else\iffirstargument
+ \attachment[][#1]%
+ \fi\fi
+ \fi}
+
+\def\presetattachmentvariables
+ {\let\@@DriverAttachmentLayer\@@attextlayer}
+
+\def\setupattachments
+ {\dodoubleempty\getparameters[\??at]}
+
+\setupattachments
+ [\c!state=\v!start,
+ \c!color=\@@iacolor,
+ \c!textlayer=,
+ \c!symbol=]
+
+% jammer, tussen/midden had erin gemoeten; \c!commando toevoegen
+
+\def\registermenucommand#1%
+ {{\textonly\noindent#1\space}} % no math switching
+
+\def\doregistermenubuttons[#1][#2]% [menu id] [register]
+ {\bgroup
+ \ifsecondargument
+ \setupinteractionmenu
+ [#1][\c!unknownreference=\v!yes,\c!samepage=\v!yes]%
+ \def\docommand##1%
+ {\registermenucommand{\menubutton[#1]{##1}[#2:##1]}}%
+ \else
+ \def\docommand##1%
+ {\registermenucommand
+ {\button
+ [\c!unknownreference=\v!yes,\c!samepage=\v!yes]
+ {##1}[#1:##1]}}%
+ \fi
+ \handletokens abcdefghijklmnopqrstuvwxyz\with\docommand % moet anders
+ \egroup}
+
+\def\registermenubuttons
+ {\dodoubleempty\doregistermenubuttons}
+
+\stelkoppelingenin
+ [\c!distance=.25em,
+ \c!width=\v!fit,
+ \c!location=\v!low,
+ \c!color=\@@iacolor,
+ \c!frame=\v!off,
+ \c!background=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!backgroundcolor=]
+
+\defineinteractionmenu
+ [\v!right]
+ [\v!right]
+ [\c!before=,
+ \c!after=\vfil,
+ \c!inbetween=\blank,
+ \c!distance=\bodyfontsize, % 12pt
+ \c!left=\hss,
+ \c!right=\hss,
+ \c!width=\rightedgewidth,
+ \c!height=\v!broad]
+
+\defineinteractionmenu
+ [\v!left]
+ [\v!left]
+ [\c!before=,
+ \c!after=\vfil,
+ \c!inbetween=\blank,
+ \c!distance=\bodyfontsize, % 12pt
+ \c!left=\hss,
+ \c!right=\hss,
+ \c!width=\leftedgewidth,
+ \c!height=\v!broad]
+
+\defineinteractionmenu
+ [\v!bottom]
+ [\v!bottom]
+ [\c!before=\vss,
+ \c!after=\vss,
+ \c!middle=\hfil,
+ \c!distance=\bodyfontsize, % 12pt
+ \c!width=\v!fit,
+ \c!height=\v!broad]
+
+\defineinteractionmenu
+ [\v!top]
+ [\v!top]
+ [\c!before=\vss,
+ \c!after=\vss,
+ \c!middle=\hfil,
+ \c!distance=\bodyfontsize, % 12pt
+ \c!width=\v!fit,
+ \c!height=\v!broad]
+
+\setupinteractionmenu
+ [\v!left,\v!right,\v!top,\v!bottom]
+ [\c!offset=.25em,
+ \c!position=\v!no,
+ \c!frame=\v!on,
+ \c!background=,
+ \c!backgroundcolor=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!style=\@@iastyle,
+ \c!color=\@@iacolor,
+ \c!contrastcolor=\@@iacontrastcolor,
+ \c!state=\v!start,
+ \c!samepage=\v!yes,
+ \c!unknownreference=\v!empty,
+ \c!topoffset=\!!zeropoint,
+ \c!bottomoffset=\!!zeropoint,
+ \c!leftoffset=\!!zeropoint,
+ \c!rightoffset=\!!zeropoint]
+
+\def\placeleftedgetextblock % Is \hss/\hsize really needed here?
+ {\hbox to \leftedgewidth % (check outer level and settings)
+ {\hsize\leftedgewidth\hss\interactionmenus[\v!left]}}
+
+\def\placerightedgetextblock % Is \hss/\hsize really needed here?
+ {\hbox to \rightedgewidth % (check outer level and settings)
+ {\hsize\rightedgewidth\interactionmenus[\v!right]\hss}}
+
+\def\placetoptextblock
+ {\vbox to \topheight
+ {\vsize\topheight
+ \csname\??tk\v!top\c!before\endcsname
+ \interactionmenus[\v!top]%
+ \csname\??tk\v!top\c!after\endcsname
+ \kern\zeropoint}}
+
+\def\placebottomtextblock
+ {\vbox to \bottomheight
+ {\vsize\bottomheight
+ \csname\??tk\v!bottom\c!before\endcsname
+ \interactionmenus[\v!bottom]%
+ \csname\??tk\v!bottom\c!after\endcsname
+ \kern\zeropoint}}
+
+\ifx\leftedgetextcontent\undefined \else
+
+ \appendtoks \placeleftedgetextblock \hskip-\leftedgewidth \to \leftedgetextcontent
+ \appendtoks \placerightedgetextblock \hskip-\rightedgewidth \to \rightedgetextcontent
+ \appendtoks \placetoptextblock \vskip-\topheight \to \toptextcontent
+ \appendtoks \placebottomtextblock \vskip-\bottomheight \to \bottomtextcontent
+
+\fi
+
+\setupinteractionscreen
+ [\c!width=\printpaperwidth,
+ \c!height=\printpaperheight,
+ \c!horoffset=\!!zeropoint,
+ \c!veroffset=\!!zeropoint,
+ \c!backspace=\backspace,
+ \c!topspace=\topspace,
+ \c!option=\v!min,
+ \c!delay=\v!none]
+
+\setupbuttons
+ [\c!state=\v!start,
+ \c!width=\v!fit,
+ \c!height=\v!broad,
+ \c!offset=0.25em,
+ \c!frame=\v!on,
+ \c!background=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!backgroundcolor=,
+ \c!style=\@@iastyle,
+ \c!color=\@@iacolor,
+ \c!contrastcolor=\@@iacontrastcolor,
+ \c!samepage=\v!yes,
+ \c!unknownreference=\v!yes]
+
+\setupinteractionbar
+ [\c!state=\v!start,
+ \c!alternative=a,
+ \c!symbol=\v!no,
+ \c!width=\rightedgewidth,
+ \c!height=, % these are taken care
+ \c!depth=, % of at calling time
+ \c!distance=.5em, % beter relateren aan breedte
+ \c!step=1,
+ \c!color=\@@iacolor,
+ \c!contrastcolor=\@@iacontrastcolor,
+ \c!frame=\v!on,
+ \c!background=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!backgroundcolor=,
+ \c!samepage=\v!yes,
+ \c!unknownreference=\v!yes]
+
+\setupsynchronizationbar
+ [\c!alternative=\v!page,
+ \c!width=\rightedgewidth,
+ \c!style=\@@iastyle,
+ \c!color=\@@iacolor,
+ \c!background=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!backgroundcolor=]
+
+\setupsynchronization
+ [\c!state=\v!stop]
+
+\setupprofiles
+ [\c!option=]
+
+\setuppagetransitions
+ [\v!reset]
+
+\setupcomment
+ [\c!state=\v!start,
+ \c!margin=2.5em,
+ \c!distance=1em,
+ \c!width=.3\textwidth,
+ \c!height=.2\textheight,
+ \c!color=\@@iacolor,
+ \c!title=,
+ \c!space=\v!no,
+ \c!symbol=\v!normal,
+ \c!location=\v!inmargin,
+ \c!option=,
+ \c!textlayer=]
+
+\setupversions % beware, @ is made active here,
+ [\c!number=1, % therefore we set this one at the end
+ \c!style=\ss,
+ \c!color=]
+
+\protect \endinput
diff --git a/tex/context/base/core-itm.tex b/tex/context/base/core-itm.tex
index 1c8744d5b..406f9d1e4 100644
--- a/tex/context/base/core-itm.tex
+++ b/tex/context/base/core-itm.tex
@@ -14,39 +14,23 @@
% new: text + lefttext=(,righttext=)
% start=
-\writestatus{loading}{Context Core Macros / Itemgroups}
+\writestatus{loading}{ConTeXt Core Macros / Itemgroups}
-\startmessages dutch library: layouts
- 9: momenteel maximaal -- niveaus in opsommingen
-\stopmessages
+% messages moved
-\startmessages english library: layouts
- 9: currently no more than -- levels in itemizations
-\stopmessages
+% messages moved
-\startmessages german library: layouts
- 9: z.Z. nicht mehr als -- Ebenen in Aufzaehlungen
-\stopmessages
+% messages moved
-\startmessages czech library: layouts
- 9: aktualne ne vice nez -- urovne/urovni vyctu
-\stopmessages
+% messages moved
-\startmessages italian library: layouts
- 9: attualmente non più di -- livelli di elencazione
-\stopmessages
+% messages moved
-\startmessages norwegian library: layouts
- 9: for øyeblikket maksimalt -- nivåer i opplisting
-\stopmessages
+% messages moved
-\startmessages romanian library: layouts
- 9: acum nu se supota mai mult de -- nivele de adancime la iteratii
-\stopmessages
+% messages moved
-\startmessages french library: layouts
- 9: pas plus de -- niveaux pour l'instant dans les élémentarisations
-\stopmessages
+% messages moved
\unprotect
@@ -944,7 +928,7 @@
\ifdim\scratchdimen>\dimen0
\advance\scratchdimen -\dimen0
\else
- \scratchdimen\z@
+ \scratchdimen\zeropoint
\fi
\llap{\hbox to \dimen0{\ifconditional\sublistitem\llap{+}\fi\box8\hss}}% was: \hfill
\hskip\scratchdimen}
diff --git a/tex/context/base/core-job.lua b/tex/context/base/core-job.lua
index 8b45a5783..fb4f76de1 100644
--- a/tex/context/base/core-job.lua
+++ b/tex/context/base/core-job.lua
@@ -6,79 +6,14 @@ if not modules then modules = { } end modules ['core-job'] = {
license = "see context related readme files"
}
--- will move
+local texsprint, texprint, format, find, gmatch = tex.sprint, tex.print, string.format, string.find, string.gmatch
-local texsprint, texprint, format = tex.sprint, tex.print, string.format
-
-commands.writestatus = ctx.writestatus
-
-function commands.doifelse(b)
- if b then -- faster with if than with expression
- texsprint(tex.texcatcodes,"\\firstoftwoarguments")
- else
- texsprint(tex.texcatcodes,"\\secondoftwoarguments")
- end
-end
-function commands.doif(b)
- if b then
- texsprint(tex.texcatcodes,"\\firstofoneargument")
- else
- texsprint(tex.texcatcodes,"\\gobbleoneargument")
- end
-end
-function commands.doifnot(b)
- if b then
- texsprint(tex.texcatcodes,"\\gobbleoneargument")
- else
- texsprint(tex.texcatcodes,"\\firstofoneargument")
- end
-end
-cs.testcase = commands.doifelse
-
-function commands.doifelsespaces(str)
- return commands.doifelse(str:find("^ +$"))
-end
-
-local s = lpeg.splitat(",")
-
-local h = { }
-
-function commands.doifcommonelse(a,b)
- local ha = h[a]
- local hb = h[b]
- if not ha then ha = s:match(a) h[a] = ha end
- if not hb then hb = s:match(b) h[b] = hb end
- for i=1,#ha do
- for j=1,#hb do
- if ha[i] == hb[i] then
- return cs.testcase(true)
- end
- end
- end
- return cs.testcase(false)
-end
-
-function commands.doifinsetelse(a,b)
- local hb = h[b]
- if not hb then hb = s:match(b) h[b] = hb end
- for j=1,#hb do
- if a == hb[i] then
- return cs.testcase(true)
- end
- end
- return cs.testcase(false)
-end
-
-function commands. def(cs,value) texsprint(tex.ctxcatcodes,format( "\\def\\%s{%s}",cs,value)) end
-function commands.edef(cs,value) texsprint(tex.ctxcatcodes,format("\\edef\\%s{%s}",cs,value)) end
-function commands.gdef(cs,value) texsprint(tex.ctxcatcodes,format("\\gdef\\%s{%s}",cs,value)) end
-function commands.xdef(cs,value) texsprint(tex.ctxcatcodes,format("\\xdef\\%s{%s}",cs,value)) end
-
-function commands.cs(cs,args) texsprint(tex.ctxcatcodes,format("\\csname %s\\endcsname %s",cs,args or"")) end
+local ctxcatcodes = tex.ctxcatcodes
+local texcatcodes = tex.texcatcodes
-- main code
-function input.findctxfile(name,maxreadlevel)
+function resolvers.findctxfile(name,maxreadlevel)
local function exists(n)
if io.exists(n) then
return n
@@ -90,7 +25,7 @@ function input.findctxfile(name,maxreadlevel)
end
return nil
end
- if input.aux.qualified_path(name) then
+ if file.is_qualified_path(name) then
return name
else
-- not that efficient, too many ./ lookups
@@ -107,41 +42,40 @@ function input.findctxfile(name,maxreadlevel)
end
end
end
- return input.find_file(name) or ""
+ return resolvers.find_file(name) or ""
end
end
function commands.processfile(name,maxreadlevel)
- name = input.findctxfile(name,maxreadlevel)
+ name = resolvers.findctxfile(name,maxreadlevel)
if name ~= "" then
---~ texsprint(tex.ctxcatcodes,format('\\input {%s}',name)) -- future version
- texsprint(tex.ctxcatcodes,format("\\input %s\\relax",name)) -- we need \input {name}
+ texsprint(ctxcatcodes,format("\\input %s\\relax",name)) -- we need \input {name}
end
end
function commands.doifinputfileelse(name,maxreadlevel)
- commands.doifelse(input.findctxfile(name,maxreadlevel) ~= "")
+ commands.doifelse(resolvers.findctxfile(name,maxreadlevel) ~= "")
end
function commands.locatefilepath(name,maxreadlevel)
- texsprint(tex.texcatcodes,file.dirname(input.findctxfile(name,maxreadlevel)))
+ texsprint(texcatcodes,file.dirname(resolvers.findctxfile(name,maxreadlevel)))
end
function commands.usepath(paths,maxreadlevel)
- input.register_extra_path(paths)
- texsprint(tex.texcatcodes,table.concat(input.instance.extra_paths or {}, ""))
+ resolvers.register_extra_path(paths)
+ texsprint(texcatcodes,table.concat(resolvers.instance.extra_paths or {}, ""))
end
function commands.usesubpath(subpaths,maxreadlevel)
- input.register_extra_path(nil,subpaths)
- texsprint(tex.texcatcodes,table.concat(input.instance.extra_paths or {}, ""))
+ resolvers.register_extra_path(nil,subpaths)
+ texsprint(texcatcodes,table.concat(resolvers.instance.extra_paths or {}, ""))
end
function commands.usezipfile(name,tree)
if tree and tree ~= "" then
- input.usezipfile(format("zip:///%s?tree=%s",name,tree))
+ resolvers.usezipfile(format("zip:///%s?tree=%s",name,tree))
else
- input.usezipfile(format("zip:///%s",name))
+ resolvers.usezipfile(format("zip:///%s",name))
end
end
@@ -162,20 +96,20 @@ local function convertexamodes(str)
local data = xml.content(dk) or ""
local mode = label:match("^mode:(.+)$")
if mode then
- texsprint(tex.ctxcatcodes,format("\\enablemode[%s:%s]",mode,data))
+ texsprint(ctxcatcodes,format("\\enablemode[%s:%s]",mode,data))
end
- texsprint(tex.ctxcatcodes,format("\\setvariable{exa:variables}{%s}{%s}",label,data:gsub("([{}])","\\%1")))
+ texsprint(ctxcatcodes,format("\\setvariable{exa:variables}{%s}{%s}",label,data:gsub("([{}])","\\%1")))
end
end
end
--- we need a system file option: ,. .. etc + paths but no tex lookup so input.find_file is wrong here
+-- we need a system file option: ,. .. etc + paths but no tex lookup so resolvers.find_file is wrong here
function commands.loadexamodes(filename)
if not filename or filename == "" then
- filename = file.stripsuffix(tex.jobname)
+ filename = file.removesuffix(tex.jobname)
end
- filename = input.find_file(file.addsuffix(filename,'ctm')) or ""
+ filename = resolvers.find_file(file.addsuffix(filename,'ctm')) or ""
if filename ~= "" then
commands.writestatus("examodes","loading %s",filename) -- todo: message system
convertexamodes(io.loaddata(filename))
@@ -184,59 +118,72 @@ function commands.loadexamodes(filename)
end
end
+function commands.logoptionfile(name)
+ -- todo: xml if xml logmode
+ local f = io.open(name)
+ if f then
+ texio.write_nl("log","%\n%\tbegin of optionfile\n%\n")
+ for line in f:lines() do
+ texio.write("log",format("%%\t%s\n",line))
+ end
+ texio.write("log","%\n%\tend of optionfile\n%\n")
+ f:close()
+ end
+end
+
--~ set functions not ok and not faster on mk runs either
--~
--~ local function doifcommonelse(a,b)
---~ local ba = a:find(",")
---~ local bb = b:find(",")
+--~ local ba = find(a,",")
+--~ local bb = find(b,",")
--~ if ba and bb then
---~ for sa in a:gmatch("[^ ,]+") do
---~ for sb in b:gmatch("[^ ,]+") do
+--~ for sa in gmatch(a,"[^ ,]+") do
+--~ for sb in gmatch(b,"[^ ,]+") do
--~ if sa == sb then
---~ texsprint(tex.ctxcatcodes,"\\def\\commalistelement{"..sa.."}")
+--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",sa,"}")
--~ return true
--~ end
--~ end
--~ end
--~ elseif ba then
---~ for sa in a:gmatch("[^ ,]+") do
+--~ for sa in gmatch(a,"[^ ,]+") do
--~ if sa == b then
---~ texsprint(tex.ctxcatcodes,"\\def\\commalistelement{"..b.."}")
+--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",b,"}")
--~ return true
--~ end
--~ end
--~ elseif bb then
---~ for sb in b:gmatch("[^ ,]+") do
+--~ for sb in gmatch(b,"[^ ,]+") do
--~ if a == sb then
---~ texsprint(tex.ctxcatcodes,"\\def\\commalistelement{"..a.."}")
+--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}")
--~ return true
--~ end
--~ end
--~ else
--~ if a == b then
---~ texsprint(tex.ctxcatcodes,"\\def\\commalistelement{"..a.."}")
+--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}")
--~ return true
--~ end
--~ end
---~ texsprint(tex.ctxcatcodes,"\\let\\commalistelement\\empty")
+--~ texsprint(ctxcatcodes,"\\let\\commalistelement\\empty")
--~ return false
--~ end
--~ local function doifinsetelse(a,b)
---~ local bb = b:find(",")
+--~ local bb = find(b,",")
--~ if bb then
---~ for sb in b:gmatch("[^ ,]+") do
+--~ for sb in gmatch(b,"[^ ,]+") do
--~ if a == sb then
---~ texsprint(tex.ctxcatcodes,"\\def\\commalistelement{"..a.."}")
+--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}")
--~ return true
--~ end
--~ end
--~ else
--~ if a == b then
---~ texsprint(tex.ctxcatcodes,"\\def\\commalistelement{"..a.."}")
+--~ texsprint(ctxcatcodes,"\\def\\commalistelement{",a,"}")
--~ return true
--~ end
--~ end
---~ texsprint(tex.ctxcatcodes,"\\let\\commalistelement\\empty")
+--~ texsprint(ctxcatcodes,"\\let\\commalistelement\\empty")
--~ return false
--~ end
--~ function commands.doifcommon (a,b) commands.doif (doifcommonelse(a,b)) end
@@ -245,4 +192,3 @@ end
--~ function commands.doifinset (a,b) commands.doif (doifinsetelse(a,b)) end
--~ function commands.doifnotinset (a,b) commands.doifnot (doifinsetelse(a,b)) end
--~ function commands.doifinsetelse (a,b) commands.doifelse(doifinsetelse(a,b)) end
-
diff --git a/tex/context/base/core-job.mkii b/tex/context/base/core-job.mkii
index 3a0f4e2f4..59d8552df 100644
--- a/tex/context/base/core-job.mkii
+++ b/tex/context/base/core-job.mkii
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-job, % copied from main-001,
-%D version=2008.01.25,
+%D version=1997.03.31,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Job Handling,
%D author=Hans Hagen,
@@ -11,8 +11,44 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+%D This module is still to be split and documented.
+
+\writestatus{loading}{ConTeXt Core Macros / Job Handling}
+
\unprotect
+\let \currentproject \empty
+\let \currentproduct \empty
+\let \currentenvironment \empty
+\let \currentcomponent \empty
+
+\let \loadedfiles \empty
+\let \processedfiles \empty
+
+\let \nomorefiles \relax
+
+\let \allinputpaths \empty
+\let \locatedfilepath \empty
+
+\newcount\textlevel
+\newcount\fileprocesslevel
+
+\setvalue{\c!file::0}{\jobname}
+
+\def\processedfile % is used in styles, don't change !
+ {\getvalue{\c!file::\number\fileprocesslevel}}
+
+\def\dostarttextfile#1%
+ {\global\advance\fileprocesslevel\plusone
+ \setxvalue{\c!file::\number\fileprocesslevel}{#1}%
+ \@EA\doglobal\@EA\addtocommalist\@EA{#1}\processedfiles}
+
+\def\dostoptextfile
+ {\global\advance\fileprocesslevel\minusone}
+
+\def\processlocalfile#1#2%
+ {#1{#2}\donothing{\readfile{#2}\donothing\donothing}}
+
\def\processfile#1%
{\ifx\allinputpaths\empty
\def\next{\processlocalfile\readlocfile}%
@@ -83,4 +119,282 @@
\processcommacommand[\allinputpaths]\docommand
\fi}
+\def\registerfileinfo[#1#2]#3% geen \showmessage ?
+ {\writestatus\m!systems{#1#2 file #3 at line \the\inputlineno}%
+ \immediatewriteutility{f #1 {#3}}}
+
+\ifx\preloadfonts \undefined \let\preloadfonts \relax \fi
+\ifx\preloadspecials\undefined \let\preloadspecials\relax \fi
+
+\def\loadallsystemfiles#1#2%
+ {\ifx\@@svdirectory\empty
+ \readsysfile{#1}{\showmessage\m!systems2{#1}}{#2}%
+ \else% yet undocumented
+ \def\doloadsystemfile##1%
+ {\readsetfile{##1}{#1}{\showmessage\m!systems2{#1}}{#2}}%
+ \processcommacommand[\@@svdirectory]\doloadsystemfile
+ \fi}
+
+\ifx\disableXML\undefined \let\disableXML\relax \fi
+
+\def\loadsystemfiles
+ {\reportprotectionstate
+ \readsysfile\f!newfilename{\showmessage\m!systems2\f!newfilename}\donothing
+ %\readsysfile\f!oldfilename{\showmessage\m!systems2\f!oldfilename}\donothing
+ \loadallsystemfiles\f!filfilename
+ \donothing
+ \loadallsystemfiles\f!sysfilename
+ {\loadallsystemfiles{\f!sysfilename.rme}\donothing % new, fall back
+ \doglobal\appendtoks % brrr better \setcatcodetable\ctxcatcodes % % test
+ \bgroup\disableXML\loadallsystemfiles\f!errfilename\donothing\egroup
+ \to\everygoodbye}}
+
+%D Loading of \type {cont-usr.tex} (edited by the user)
+%D and \type {cont-fmt.tex} (generated by texexec).
+
+\def\loaduserspecifications
+ {% this used to be the file where users can tune their system, especially patterns
+ \readsysfile\f!usrfilename{\showmessage\m!systems2\f!usrfilename}\donothing
+ % this one took care of user preferences (fonts, messages) but lm made this obsolete
+ \readjobfile\f!fmtfilename{\showmessage\m!systems2\f!fmtfilename}\donothing
+ % from now on we preload all patterns (only in mkii)
+ \preloadallpatterns}
+
+\let\loaduserspecifications\relax
+
+%D We don't want multiple jobfiles to interfere.
+
+\def\loadoptionfile
+ {\readjobfile{\jobname.\f!optionextension}
+ {\showmessage\m!systems2{\jobname.\f!optionextension}}%
+ {\writestatus\m!systems {no \jobname.\f!optionextension}}}
+
+% Most natural ...
+%
+% \def\doateverystarttext
+% {\the\everystarttext
+% \global\let\doateverystarttext\relax}
+%
+% ... most practical, since we can load env's in a
+% something.run file (nested \starttext's; see for
+% instance x-res-08, where we definitely want to
+% open the file!).
+
+\def\doateverystarttext
+ {\the\everystarttext
+ \global\everystarttext\emptytoks}
+
+\def\starttext
+ {\doateverystarttext
+ \ifcase\textlevel
+ \registerfileinfo[begin]\jobname
+ \expandafter\startcopyingblocks
+ \fi
+ \global\advance\textlevel\plusone}
+
+\def\stoptext
+ {\global\advance\textlevel\minusone
+ \ifnum\textlevel>\zerocount \else
+ \page[\v!last]\page % new, moved from everybye to here; flushes headers, colors etc etc etc
+ \the\everystoptext
+ %\the\everybye %
+ %\the\everygoodbye % == \end (new)
+ %\expandafter\normalend %
+ \expandafter\finalend
+ \fi}
+
+\def\finalend
+ {\ifnum\textlevel>\zerocount \else
+ \the\everybye
+ \the\everygoodbye
+ \doifsometokselse\everynotabene{\writeline\the\everynotabene\writeline}\donothing
+ \global\everybye \emptytoks % rather unneeded
+ \global\everygoodbye\emptytoks % but for sure
+ \expandafter\normalend
+ \fi}
+
+\let\end\finalend
+
+\def\emergencyend
+ {\writestatus\m!systems{invalid \@EA\string\csname\e!start\v!text\endcsname...\@EA\string\csname\e!stop\v!text\endcsname\space structure}%
+ \stoptext}
+
+\def\currentfile{\inputfilename}
+
+\def\doexecutefileonce#1%
+ {\beforesplitstring#1\at.\to\currentfile
+ \fullexpandtwoargsafter\doifnotinset\currentfile\loadedfiles
+ {\fullexpandoneargafter\addtocommalist\currentfile\loadedfiles
+ \doexecutefile{#1}}}
+
+\def\doexecutefile#1%
+ {\registerfileinfo[begin]{#1}%
+ \dostarttextfile{#1}%
+ \processfile{#1}%
+ \dostoptextfile
+ \registerfileinfo[end]{#1}}
+
+\def\donotexecutefile#1%
+ {}
+
+\def\verwerkfile#1 %
+ {\doexecutefile{#1}}
+
+\def\useenvironment[#1]% maybe commalist
+ {\environment #1 \relax}
+
+\def\environment #1 % at outermost level only (load only once)
+ {\pushmacro\startenvironment
+ \pushmacro\stopenvironment
+ \def\startenvironment ##1 {}%
+ \let\stopenvironment\relax
+ \startreadingfile
+ \doexecutefileonce{#1}
+ \stopreadingfile
+ \popmacro\stopenvironment
+ \popmacro\startenvironment}
+
+\def\component #1 % at outermost level only
+ {\dostarttextfile{#1}%
+ \processfile{#1}%
+ \dostoptextfile}
+
+\newcount\filelevel
+
+\let\currentcomponent \v!text
+\let\currentcomponentpath\f!currentpath
+
+\def\donextlevel#1#2#3#4#5#6#7\\%
+ {\pushmacro\currentcomponent
+ \pushmacro\currentcomponentpath
+ \let\currentcomponent#1%
+ \setsystemmode\currentcomponent
+ \splitfilename{#1}%
+ \ifx\splitoffpath\empty
+ \let\currentcomponentpath\f!currentpath
+ \else
+ \let\currentcomponentpath\splitoffpath
+ \fi
+ \beforesplitstring#7\at.\to#2\relax % can become path + base
+ \ifcase\filelevel\relax
+ \starttext
+ \def\project ##1 {#3{##1}}%
+ \def\environment ##1 {#4{##1}}%
+ \def\product ##1 {#5{##1}}%
+ \def\component ##1 {#6{##1}}%
+ \fi
+ \advance\filelevel\plusone
+ \fullexpandoneargafter\addtocommalist{#1}\loadedfiles}
+
+\def\doprevlevel
+ {\popmacro\currentcomponentpath
+ \popmacro\currentcomponent
+ \setsystemmode\currentcomponent
+ \ifnum\filelevel=\plusone
+ \expandafter\stoptext
+ \else
+ \advance\filelevel\minusone
+ \expandafter\endinput
+ \fi}
+
+\def\startproject #1 %
+ {\donextlevel\v!project\currentproject
+ \donotexecutefile\doexecutefileonce
+ \doexecutefileonce\doexecutefile#1\\}
+
+\def\startproduct #1 %
+ {\doateverystarttext
+ \donextlevel\v!product\currentproduct
+ \doexecutefileonce\doexecutefileonce
+ \donotexecutefile\doexecutefile#1\\}
+
+\def\startcomponent #1 %
+ {\doateverystarttext
+ \donextlevel\v!component\currentcomponent
+ \doexecutefileonce\doexecutefileonce
+ \donotexecutefile\doexecutefile#1\\}
+
+\def\startenvironment #1 %
+ {\donextlevel\v!environment\currentenvironment
+ \donotexecutefile\doexecutefileonce
+ \donotexecutefile\donotexecutefile#1\\}
+
+% \startproject test
+% 1: \startmode[*project] project \stopmode \endgraf
+% 2: \startmode[*product] product \stopmode \endgraf
+% \stopproject
+
+\def\stopproject {\doprevlevel}
+\def\stopproduct {\doprevlevel}
+\def\stopcomponent {\doprevlevel}
+\def\stopenvironment{\doprevlevel}
+
+% more or less replaced by modes
+
+\setvalue{\e!start\v!localenvironment}[#1]%
+ {\let\loadedlocalenvironments\empty
+ \def\docommand##1%
+ {\beforesplitstring##1\at.\to\someevironment
+ \fullexpandoneargafter\addtocommalist\someevironment\loadedlocalenvironments}%
+ \processcommalist[#1]\docommand
+ \fullexpandtwoargsafter\doifcommonelse % no longer next needed
+ {\currentproject,\currentproduct,%
+ \currentcomponent,\currentenvironment}
+ {\loadedlocalenvironments}
+ {\letvalue{\e!stop\v!localenvironment}\relax}
+ {\grabuntil{\e!stop\v!localenvironment}\gobbleoneargument}} % TH: fixed, was \relax
+
+\setvalue{\v!localenvironment}#1 {\doexecutefileonce{#1}}
+
+% NOT TOEVOEGEN: \the\everytrace
+
+\neverypar=\emptytoks
+
+% \appendtoks \flushnotes \to \everypar
+% \appendtoks \synchronizesidefloats \to \everypar
+% \appendtoks \checkindentation \to \everypar
+% \appendtoks \showparagraphnumber \to \everypar
+% \appendtoks \flushmargincontents \to \everypar
+% \appendtoks \flushcommentanchors \to \everypar
+% \appendtoks \synchronizenotes \to \everypar
+
+% \appendtoks \flushnotes \to \everydisplay
+% \appendtoks \adjustsidefloatdisplaylines \to \everydisplay
+
+% soon, when pdftex 1.22 is out in the field:
+
+\chardef\systemcommandmode\zerocount % 0=unknown 1=disabled 2=enabled
+
+\def\checksystemcommandmode
+ {\ifx\pdfshellescape\undefined \else
+ \chardef\systemcommandmode \ifcase\pdfshellescape \plusone \else \plustwo \fi
+ \fi
+ \global\let\checksystemcommandmode\relax}
+
+\def\reportsystemcommandmode
+ {\ifcase\systemcommandmode
+ \or
+ \writestatus\m!systems{system commands are disabled}%
+ \or
+ \writestatus\m!systems{system commands are enabled}%
+ \fi}
+
+% \ifx\etexversion\undefined \else \ifnum\etexversion<202
+% \prependtoks
+% \writestatus\m!systems{eTeX version \number\etexversion\space -> too old (bugs)}%
+% \writeline
+% \to \everyjob
+% \fi \fi
+
+% \ifx\pdftexversion\undefined \else \ifnum\number\pdftexversion<120
+% \prependtoks
+% \writestatus\m!systems{pdfTeX version \number\pdftexversion\space -> please update}%
+% \writeline
+% \to \everyjob
+% \fi \fi
+
+% Default-instellingen (verborgen)
+
+\resetutilities
+
\protect \endinput
diff --git a/tex/context/base/core-job.mkiv b/tex/context/base/core-job.mkiv
index 2c0f34412..cdb1564f4 100644
--- a/tex/context/base/core-job.mkiv
+++ b/tex/context/base/core-job.mkiv
@@ -1,6 +1,6 @@
%D \module
-%D [ file=core-job,
-%D version=2008.01.25,
+%D [ file=core-job, % copied from main-001,
+%D version=1997.03.31,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Job Handling,
%D author=Hans Hagen,
@@ -11,32 +11,333 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\registerctxluafile{core-job}{1.001}
+%D This module is still to be split and documented.
+
+\writestatus{loading}{ConTeXt Core Macros / Job Handling}
\unprotect
-\def\processfile #1{\ctxlua{commands.processfile("#1",\number\maxreadlevel)}}
-\def\doifinputfileelse#1{\ctxlua{commands.doifinputfileelse("#1",\number\maxreadlevel)}}
-\def\locatefilepath #1{\edef\locatedfilepath{\ctxlua{commands.locatefilepath("#1",\number\maxreadlevel)}}}
-\def\usepath [#1]{\edef\allinputpaths{\ctxlua{commands.usepath("#1")}}}
-\def\usesubpath [#1]{\edef\allinputpaths{\ctxlua{commands.usesubpath("#1")}}}
+\registerctxluafile{core-job}{1.001}
+
+\let \currentproject \empty
+\let \currentproduct \empty
+\let \currentenvironment \empty
+\let \currentcomponent \empty
+
+\let \loadedfiles \empty
+\let \processedfiles \empty
+
+\let \nomorefiles \relax
+
+\let \allinputpaths \empty
+\let \locatedfilepath \empty
+\newcount\textlevel
+\newcount\fileprocesslevel
+
+\setvalue{\c!file::0}{\jobname}
+
+\def\processedfile % is used in styles, don't change !
+ {\getvalue{\c!file::\number\fileprocesslevel}}
+
+\def\dostarttextfile#1%
+ {\global\advance\fileprocesslevel\plusone
+ \setxvalue{\c!file::\number\fileprocesslevel}{#1}%
+ \@EA\doglobal\@EA\addtocommalist\@EA{#1}\processedfiles}
+
+\def\dostoptextfile
+ {\global\advance\fileprocesslevel\minusone}
+
+\def\processlocalfile#1#2%
+ {#1{#2}\donothing{\readfile{#2}\donothing\donothing}}
+
+\def\processfile #1{\ctxlua{commands.processfile("#1",\number\maxreadlevel)}}
+\def\doifinputfileelse #1{\ctxlua{commands.doifinputfileelse("#1",\number\maxreadlevel)}}
+\def\locatefilepath #1{\edef\locatedfilepath{\ctxlua{commands.locatefilepath("#1",\number\maxreadlevel)}}}
+\def\usepath [#1]{\edef\allinputpaths{\ctxlua{commands.usepath("#1")}}}
+\def\usesubpath [#1]{\edef\allinputpaths{\ctxlua{commands.usesubpath("#1")}}}
\def\usezipfile {\dodoubleempty\dousezipfile}
\def\dousezipfile[#1][#2]{\ctxlua{commands.usezipfile("#1","#2")}} % [filename] [optional subtree]
\def\loadexamodes {\dosingleempty\doloadexamodes}
\def\doloadexamodes [#1]{\ctxlua{commands.loadexamodes("#1")}}
-% for the moment here:
+\def\registerfileinfo[#1#2]#3% geen \showmessage ?
+ {\writestatus\m!systems{#1#2 file #3 at line \the\inputlineno}%
+ \immediatewriteutility{f #1 {#3}}}
+
+\ifx\preloadfonts \undefined \let\preloadfonts \relax \fi
+\ifx\preloadspecials\undefined \let\preloadspecials\relax \fi
+
+\def\loadallsystemfiles#1#2%
+ {\ifx\@@svdirectory\empty
+ \readsysfile{#1}{\showmessage\m!systems2{#1}}{#2}%
+ \else% yet undocumented
+ \def\doloadsystemfile##1%
+ {\readsetfile{##1}{#1}{\showmessage\m!systems2{#1}}{#2}}%
+ \processcommacommand[\@@svdirectory]\doloadsystemfile
+ \fi}
+
+\ifx\disableXML\undefined \let\disableXML\relax \fi
+
+\def\loadsystemfiles
+ {\reportprotectionstate
+ \readsysfile\f!newfilename{\showmessage\m!systems2\f!newfilename}\donothing
+ %\readsysfile\f!oldfilename{\showmessage\m!systems2\f!oldfilename}\donothing
+ \loadallsystemfiles\f!filfilename
+ \donothing
+ \loadallsystemfiles\f!sysfilename
+ {\loadallsystemfiles{\f!sysfilename.rme}\donothing % new, fall back
+ \doglobal\appendtoks % brrr better \setcatcodetable\ctxcatcodes % % test
+ \bgroup\disableXML\loadallsystemfiles\f!errfilename\donothing\egroup
+ \to\everygoodbye}}
+
+%D Loading of \type {cont-usr.tex} (edited by the user)
+%D and \type {cont-fmt.tex} (generated by texexec).
+
+% \def\loaduserspecifications
+% {% this used to be the file where users can tune their system, especially patterns
+% \readsysfile\f!usrfilename{\showmessage\m!systems2\f!usrfilename}\donothing
+% % this one took care of user preferences (fonts, messages) but lm made this obsolete
+% \readjobfile\f!fmtfilename{\showmessage\m!systems2\f!fmtfilename}\donothing
+% % from now on we preload all patterns (only in mkii)
+% \preloadallpatterns}
+
+\let\loaduserspecifications\relax
+
+%D We don't want multiple jobfiles to interfere.
+
+\def\loadoptionfile
+ {\readjobfile{\jobname.\f!optionextension}
+ {\showmessage\m!systems2{\jobname.\f!optionextension}%
+ \ctxlua{commands.logoptionfile("\jobname.\f!optionextension")}}%
+ {\writestatus\m!systems {no \jobname.\f!optionextension}}}
+
+% Most natural ...
+%
+% \def\doateverystarttext
+% {\the\everystarttext
+% \global\let\doateverystarttext\relax}
+%
+% ... most practical, since we can load env's in a
+% something.run file (nested \starttext's; see for
+% instance x-res-08, where we definitely want to
+% open the file!).
+
+\def\doateverystarttext
+ {\the\everystarttext
+ \global\everystarttext\emptytoks}
+
+\def\starttext
+ {\doateverystarttext
+ \ifcase\textlevel
+ \registerfileinfo[begin]\jobname
+ \fi
+ \global\advance\textlevel\plusone}
+
+\def\stoptext
+ {\global\advance\textlevel\minusone
+ \ifnum\textlevel>\zerocount \else
+ \page[\v!last]\page % new, moved from everybye to here; flushes headers, colors etc etc etc
+ \the\everystoptext
+ %\the\everybye %
+ %\the\everygoodbye % == \end (new)
+ %\expandafter\normalend %
+ \expandafter\finalend
+ \fi}
+
+\def\finalend
+ {\ifnum\textlevel>\zerocount \else
+ \the\everybye
+ \the\everygoodbye
+ \doifsometokselse\everynotabene{\writeline\the\everynotabene\writeline}\donothing
+ \global\everybye \emptytoks % rather unneeded
+ \global\everygoodbye\emptytoks % but for sure
+ \expandafter\normalend
+ \fi}
+
+\let\end\finalend
+
+\def\emergencyend
+ {\writestatus\m!systems{invalid \@EA\string\csname\e!start\v!text\endcsname...\@EA\string\csname\e!stop\v!text\endcsname\space structure}%
+ \stoptext}
+
+\def\currentfile{\inputfilename}
+
+\def\doexecutefileonce#1%
+ {\beforesplitstring#1\at.\to\currentfile
+ \fullexpandtwoargsafter\doifnotinset\currentfile\loadedfiles
+ {\fullexpandoneargafter\addtocommalist\currentfile\loadedfiles
+ \doexecutefile{#1}}}
+
+\def\doexecutefile#1%
+ {\registerfileinfo[begin]{#1}%
+ \dostarttextfile{#1}%
+ \processfile{#1}%
+ \dostoptextfile
+ \registerfileinfo[end]{#1}}
+
+\def\donotexecutefile#1%
+ {}
+
+\def\verwerkfile#1 %
+ {\doexecutefile{#1}}
+
+\def\useenvironment[#1]% maybe commalist
+ {\environment #1 \relax}
+
+\def\environment #1 % at outermost level only (load only once)
+ {\pushmacro\startenvironment
+ \pushmacro\stopenvironment
+ \def\startenvironment ##1 {}%
+ \let\stopenvironment\relax
+ \startreadingfile
+ \doexecutefileonce{#1}
+ \stopreadingfile
+ \popmacro\stopenvironment
+ \popmacro\startenvironment}
+
+\def\component #1 % at outermost level only
+ {\dostarttextfile{#1}%
+ \processfile{#1}%
+ \dostoptextfile}
+
+\newcount\filelevel
+
+\let\currentcomponent \v!text
+\let\currentcomponentpath\f!currentpath
+
+\def\donextlevel#1#2#3#4#5#6#7\\%
+ {\pushmacro\currentcomponent
+ \pushmacro\currentcomponentpath
+ \let\currentcomponent#1%
+ \setsystemmode\currentcomponent
+ \splitfilename{#1}%
+ \ifx\splitoffpath\empty
+ \let\currentcomponentpath\f!currentpath
+ \else
+ \let\currentcomponentpath\splitoffpath
+ \fi
+ \beforesplitstring#7\at.\to#2\relax % can become path + base
+ \ifcase\filelevel\relax
+ \starttext
+ \def\project ##1 {#3{##1}}%
+ \def\environment ##1 {#4{##1}}%
+ \def\product ##1 {#5{##1}}%
+ \def\component ##1 {#6{##1}}%
+ \fi
+ \advance\filelevel\plusone
+ \fullexpandoneargafter\addtocommalist{#1}\loadedfiles}
+
+\def\doprevlevel
+ {\popmacro\currentcomponentpath
+ \popmacro\currentcomponent
+ \setsystemmode\currentcomponent
+ \ifnum\filelevel=\plusone
+ \expandafter\stoptext
+ \else
+ \advance\filelevel\minusone
+ \expandafter\endinput
+ \fi}
+
+\def\startproject #1 %
+ {\donextlevel\v!project\currentproject
+ \donotexecutefile\doexecutefileonce
+ \doexecutefileonce\doexecutefile#1\\}
+
+\def\startproduct #1 %
+ {\doateverystarttext
+ \donextlevel\v!product\currentproduct
+ \doexecutefileonce\doexecutefileonce
+ \donotexecutefile\doexecutefile#1\\}
+
+\def\startcomponent #1 %
+ {\doateverystarttext
+ \donextlevel\v!component\currentcomponent
+ \doexecutefileonce\doexecutefileonce
+ \donotexecutefile\doexecutefile#1\\}
+
+\def\startenvironment #1 %
+ {\donextlevel\v!environment\currentenvironment
+ \donotexecutefile\doexecutefileonce
+ \donotexecutefile\donotexecutefile#1\\}
+
+% \startproject test
+% 1: \startmode[*project] project \stopmode \endgraf
+% 2: \startmode[*product] product \stopmode \endgraf
+% \stopproject
+
+\def\stopproject {\doprevlevel}
+\def\stopproduct {\doprevlevel}
+\def\stopcomponent {\doprevlevel}
+\def\stopenvironment{\doprevlevel}
+
+% more or less replaced by modes
+
+\setvalue{\e!start\v!localenvironment}[#1]%
+ {\let\loadedlocalenvironments\empty
+ \def\docommand##1%
+ {\beforesplitstring##1\at.\to\someevironment
+ \fullexpandoneargafter\addtocommalist\someevironment\loadedlocalenvironments}%
+ \processcommalist[#1]\docommand
+ \fullexpandtwoargsafter\doifcommonelse % no longer next needed
+ {\currentproject,\currentproduct,%
+ \currentcomponent,\currentenvironment}
+ {\loadedlocalenvironments}
+ {\letvalue{\e!stop\v!localenvironment}\relax}
+ {\grabuntil{\e!stop\v!localenvironment}\gobbleoneargument}} % TH: fixed, was \relax
+
+\setvalue{\v!localenvironment}#1 {\doexecutefileonce{#1}}
+
+% NOT TOEVOEGEN: \the\everytrace
+
+\neverypar=\emptytoks
+
+% \appendtoks \flushnotes \to \everypar
+% \appendtoks \synchronizesidefloats \to \everypar
+% \appendtoks \checkindentation \to \everypar
+% \appendtoks \showparagraphnumber \to \everypar
+% \appendtoks \flushmargincontents \to \everypar
+% \appendtoks \flushcommentanchors \to \everypar
+% \appendtoks \synchronizenotes \to \everypar
+
+% \appendtoks \flushnotes \to \everydisplay
+% \appendtoks \adjustsidefloatdisplaylines \to \everydisplay
+
+% soon, when pdftex 1.22 is out in the field:
+
+\chardef\systemcommandmode\zerocount % 0=unknown 1=disabled 2=enabled
+
+\def\checksystemcommandmode
+ {\ifx\pdfshellescape\undefined \else
+ \chardef\systemcommandmode \ifcase\pdfshellescape \plusone \else \plustwo \fi
+ \fi
+ \global\let\checksystemcommandmode\relax}
+
+\def\reportsystemcommandmode
+ {\ifcase\systemcommandmode
+ \or
+ \writestatus\m!systems{system commands are disabled}%
+ \or
+ \writestatus\m!systems{system commands are enabled}%
+ \fi}
-\def\expdoifelse#1#2{\ctxlua{commands.doifelse(\!!bs#1\!!es==\!!bs#2\!!es)}}
-\def\expdoif #1#2{\ctxlua{commands.doif (\!!bs#1\!!es==\!!bs#2\!!es)}}
-\def\expdoifnot #1#2{\ctxlua{commands.doifnot (\!!bs#1\!!es==\!!bs#2\!!es)}}
+% \ifx\etexversion\undefined \else \ifnum\etexversion<202
+% \prependtoks
+% \writestatus\m!systems{eTeX version \number\etexversion\space -> too old (bugs)}%
+% \writeline
+% \to \everyjob
+% \fi \fi
-% \testfeatureonce{100000}{\doifelse{hello world}{here i am}{}} % 0.3
-% \testfeatureonce{100000}{\expandabledoifelse{hello world}{here i am}{}} % 1.5
+% \ifx\pdftexversion\undefined \else \ifnum\number\pdftexversion<120
+% \prependtoks
+% \writestatus\m!systems{pdfTeX version \number\pdftexversion\space -> please update}%
+% \writeline
+% \to \everyjob
+% \fi \fi
+
+% Default-instellingen (verborgen)
-\def\expdoifcommonelse#1#2{\ctxlua{commands.doifcommonelse("#1","#2")}}
-\def\expdoifinsetelse #1#2{\ctxlua{commands.doifinsetelse("#1","#2")}}
+\resetutilities
\protect \endinput
diff --git a/tex/context/base/core-job.tex b/tex/context/base/core-job.tex
deleted file mode 100644
index ca9ef67c3..000000000
--- a/tex/context/base/core-job.tex
+++ /dev/null
@@ -1,368 +0,0 @@
-%D \module
-%D [ file=core-job, % copied from main-001,
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Job Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 still to be split and documented.
-
-\writestatus{loading}{Context Core Macros / Job Handling}
-
-\loadmarkfile{core-job}
-
-\unprotect
-
-\let \currentproject \empty
-\let \currentproduct \empty
-\let \currentenvironment \empty
-\let \currentcomponent \empty
-
-\let \loadedfiles \empty
-\let \processedfiles \empty
-
-\let \nomorefiles \relax
-
-\let \allinputpaths \empty
-\let \locatedfilepath \empty
-
-\newcount\textlevel
-\newcount\fileprocesslevel
-
-\setvalue{\c!file::0}{\jobname}
-
-\def\processedfile % is used in styles, don't change !
- {\getvalue{\c!file::\number\fileprocesslevel}}
-
-\def\dostarttextfile#1%
- {\global\advance\fileprocesslevel\plusone
- \setxvalue{\c!file::\number\fileprocesslevel}{#1}%
- \@EA\doglobal\@EA\addtocommalist\@EA{#1}\processedfiles}
-
-\def\dostoptextfile
- {\global\advance\fileprocesslevel\minusone}
-
-\def\processlocalfile#1#2%
- {#1{#2}\donothing{\readfile{#2}\donothing\donothing}}
-
-\ifx\processfile \undefined \let\processfile \gobbleoneargument \fi
-\ifx\doifinputfileelse\undefined \let\doifinputfileelse \gobbleoneargument \fi
-\ifx\locatefilepath \undefined \let\locatefilepath \gobbleoneargument \fi
-\ifx\usepath \undefined \def\usepath [#1]{} \fi
-\ifx\usesubpath \undefined \def\usesubpath [#1]{} \fi
-
-\def\registerfileinfo[#1#2]#3% geen \showmessage ?
- {\writestatus\m!systems{#1#2 file #3 at line \the\inputlineno}%
- \immediatewriteutility{f #1 {#3}}}
-
-\ifx\preloadfonts \undefined \let\preloadfonts \relax \fi
-\ifx\preloadspecials\undefined \let\preloadspecials\relax \fi
-
-\def\loadallsystemfiles#1#2%
- {\ifx\@@svdirectory\empty
- \readsysfile{#1}{\showmessage\m!systems2{#1}}{#2}%
- \else% yet undocumented
- \def\doloadsystemfile##1%
- {\readsetfile{##1}{#1}{\showmessage\m!systems2{#1}}{#2}}%
- \processcommacommand[\@@svdirectory]\doloadsystemfile
- \fi}
-
-\ifx\disableXML\undefined \let\disableXML\relax \fi
-
-\def\loadsystemfiles
- {\reportprotectionstate
- \readsysfile\f!newfilename{\showmessage\m!systems2\f!newfilename}\donothing
- %\readsysfile\f!oldfilename{\showmessage\m!systems2\f!oldfilename}\donothing
- \loadallsystemfiles\f!filfilename
- \donothing
- \loadallsystemfiles\f!sysfilename
- {\loadallsystemfiles{\f!sysfilename.rme}\donothing % new, fall back
- \doglobal\appendtoks % brrr better \setcatcodetable\ctxcatcodes % % test
- \bgroup\disableXML\loadallsystemfiles\f!errfilename\donothing\egroup
- \to\everygoodbye}}
-
-%D Loading of \type {cont-usr.tex} (edited by the user)
-%D and \type {cont-fmt.tex} (generated by texexec).
-
-\def\loaduserspecifications
- {% this used to be the file where users can tune their system, especially patterns
- \readsysfile\f!usrfilename{\showmessage\m!systems2\f!usrfilename}\donothing
- % this one took care of user preferences (fonts, messages) but lm made this obsolete
- \readjobfile\f!fmtfilename{\showmessage\m!systems2\f!fmtfilename}\donothing
- % from now on we preload all patterns (only in mkii)
- \preloadallpatterns}
-
-%D We don't want multiple jobfiles to interfere.
-
-\def\loadoptionfile
- {\readjobfile{\jobname.\f!optionextension}
- {\showmessage\m!systems2{\jobname.\f!optionextension}}%
- {\writestatus\m!systems {no \jobname.\f!optionextension}}}
-
-% \newevery \everyjob \EveryJob
-% \appendtoks ... \to \everyjob
-
-\appendtoks \loadsystemfiles \to \everyjob
-\appendtoks \preloadfonts \to \everyjob
-\appendtoks \settopskip \to \everyjob
-\appendtoks \preloadlanguages \to \everyjob
-\appendtoks \preloadspecials \to \everyjob
-\appendtoks \openspecialfile \to \everyjob
-%appendtoks \checkutilityfile \to \everyjob % obsolete
-\appendtoks \openutilities \to \everyjob
-\appendtoks \loadoptionfile \to \everyjob
-%appendtoks \loadtwopassdata \to \everyjob
-\appendtoks \checknotes \to \everyjob % depends on bodyfont
-\appendtoks \initializeMPgraphics \to \everyjob % after loading system files
-
-\appendtoks \page[\v!last] \page \to \everybye
-\appendtoks \ifarrangingpages\poparrangedpages\fi \to \everybye
-\appendtoks \registerfileinfo[end]\jobname \to \everybye
-
-\appendtoks \savenofpages \to \everybye
-\appendtoks \savenofsubpages \to \everybye
-
-\appendtoks \closeutilities \to \everygoodbye
-\appendtoks \stopcopyingblocks \to \everygoodbye
-\appendtoks \closespecialfile \to \everygoodbye
-
-\prependtoks \resetutilities \to \everystarttext % moved 28-02-2002
-\prependtoks \loadtwopassdata \to \everystarttext % moved 28-02-2002
-\appendtoks \checkreferences \to \everystarttext % new 04-12-1999
-
-% Most natural ...
-%
-% \def\doateverystarttext
-% {\the\everystarttext
-% \global\let\doateverystarttext\relax}
-%
-% ... most practical, since we can load env's in a
-% something.run file (nested \starttext's; see for
-% instance x-res-08, where we definitely want to
-% open the file!).
-
-\def\doateverystarttext
- {\the\everystarttext
- \global\everystarttext\emptytoks}
-
-\def\starttext
- {\doateverystarttext
- \ifcase\textlevel
- \registerfileinfo[begin]\jobname
- \expandafter\startcopyingblocks
- \fi
- \global\advance\textlevel\plusone}
-
-\def\stoptext
- {\global\advance\textlevel\minusone
- \ifnum\textlevel>\zerocount \else
- \the\everystoptext
- %\the\everybye %
- %\the\everygoodbye % == \end (new)
- %\expandafter\normalend %
- \expandafter\finalend
- \fi}
-
-\def\finalend
- {\ifnum\textlevel>\zerocount \else
- \the\everybye
- \the\everygoodbye
- \global\everybye \emptytoks % rather unneeded
- \global\everygoodbye\emptytoks % but for sure
- \expandafter\normalend
- \fi}
-
-\let\end\finalend
-
-\def\emergencyend
- {\writestatus\m!systems{invalid \@EA\string\csname\e!start\v!text\endcsname...\@EA\string\csname\e!stop\v!text\endcsname\space structure}%
- \stoptext}
-
-\def\currentfile{\inputfilename}
-
-\def\doexecutefileonce#1%
- {\beforesplitstring#1\at.\to\currentfile
- \fullexpandtwoargsafter\doifnotinset\currentfile\loadedfiles
- {\fullexpandoneargafter\addtocommalist\currentfile\loadedfiles
- \doexecutefile{#1}}}
-
-\def\doexecutefile#1%
- {\registerfileinfo[begin]{#1}%
- \dostarttextfile{#1}%
- \processfile{#1}%
- \dostoptextfile
- \registerfileinfo[end]{#1}}
-
-\def\donotexecutefile#1%
- {}
-
-\def\verwerkfile#1 %
- {\doexecutefile{#1}}
-
-\def\useenvironment[#1]% maybe commalist
- {\environment #1 \relax}
-
-\def\environment #1 % at outermost level only (load only once)
- {\pushmacro\startenvironment
- \pushmacro\stopenvironment
- \def\startenvironment ##1 {}%
- \let\stopenvironment\relax
- \startreadingfile
- \doexecutefileonce{#1}
- \stopreadingfile
- \popmacro\stopenvironment
- \popmacro\startenvironment}
-
-\def\component #1 % at outermost level only
- {\dostarttextfile{#1}%
- \processfile{#1}%
- \dostoptextfile}
-
-\newcount\filelevel
-
-\let\currentcomponent \v!text
-\let\currentcomponentpath\f!currentpath
-
-\def\donextlevel#1#2#3#4#5#6#7\\%
- {\pushmacro\currentcomponent
- \pushmacro\currentcomponentpath
- \let\currentcomponent#1%
- \setsystemmode\currentcomponent
- \splitfilename{#1}%
- \ifx\splitoffpath\empty
- \let\currentcomponentpath\f!currentpath
- \else
- \let\currentcomponentpath\splitoffpath
- \fi
- \beforesplitstring#7\at.\to#2\relax % can become path + base
- \ifcase\filelevel\relax
- \starttext
- \def\project ##1 {#3{##1}}%
- \def\environment ##1 {#4{##1}}%
- \def\product ##1 {#5{##1}}%
- \def\component ##1 {#6{##1}}%
- \fi
- \advance\filelevel\plusone
- \fullexpandoneargafter\addtocommalist{#1}\loadedfiles}
-
-\def\doprevlevel
- {\popmacro\currentcomponentpath
- \popmacro\currentcomponent
- \setsystemmode\currentcomponent
- \ifnum\filelevel=\plusone
- \expandafter\stoptext
- \else
- \advance\filelevel\minusone
- \expandafter\endinput
- \fi}
-
-\def\startproject #1 %
- {\donextlevel\v!project\currentproject
- \donotexecutefile\doexecutefileonce
- \doexecutefileonce\doexecutefile#1\\}
-
-\def\startproduct #1 %
- {\doateverystarttext
- \donextlevel\v!product\currentproduct
- \doexecutefileonce\doexecutefileonce
- \donotexecutefile\doexecutefile#1\\}
-
-\def\startcomponent #1 %
- {\doateverystarttext
- \donextlevel\v!component\currentcomponent
- \doexecutefileonce\doexecutefileonce
- \donotexecutefile\doexecutefile#1\\}
-
-\def\startenvironment #1 %
- {\donextlevel\v!environment\currentenvironment
- \donotexecutefile\doexecutefileonce
- \donotexecutefile\donotexecutefile#1\\}
-
-% \startproject test
-% 1: \startmode[*project] project \stopmode \endgraf
-% 2: \startmode[*product] product \stopmode \endgraf
-% \stopproject
-
-\def\stopproject {\doprevlevel}
-\def\stopproduct {\doprevlevel}
-\def\stopcomponent {\doprevlevel}
-\def\stopenvironment{\doprevlevel}
-
-% more or less replaced by modes
-
-\setvalue{\e!start\v!localenvironment}[#1]%
- {\let\loadedlocalenvironments\empty
- \def\docommand##1%
- {\beforesplitstring##1\at.\to\someevironment
- \fullexpandoneargafter\addtocommalist\someevironment\loadedlocalenvironments}%
- \processcommalist[#1]\docommand
- \fullexpandtwoargsafter\doifcommonelse % no longer next needed
- {\currentproject,\currentproduct,%
- \currentcomponent,\currentenvironment}
- {\loadedlocalenvironments}
- {\letvalue{\e!stop\v!localenvironment}\relax}
- {\grabuntil{\e!stop\v!localenvironment}\gobbleoneargument}} % TH: fixed, was \relax
-
-\setvalue{\v!localenvironment}#1 {\doexecutefileonce{#1}}
-
-% NOT TOEVOEGEN: \the\everytrace
-
-\neverypar=\emptytoks
-
-% \appendtoks \flushnotes \to \everypar
-% \appendtoks \synchronizesidefloats \to \everypar
-% \appendtoks \checkindentation \to \everypar
-% \appendtoks \showparagraphnumber \to \everypar
-% \appendtoks \flushmargincontents \to \everypar
-% \appendtoks \flushcommentanchors \to \everypar
-% \appendtoks \synchronizenotes \to \everypar
-
-% \appendtoks \flushnotes \to \everydisplay
-% \appendtoks \adjustsidefloatdisplaylines \to \everydisplay
-
-% soon, when pdftex 1.22 is out in the field:
-
-\chardef\systemcommandmode\zerocount % 0=unknown 1=disabled 2=enabled
-
-\ifx\pdfshellescape\undefined \else
- \prependtoks
- \chardef\systemcommandmode \ifcase\pdfshellescape \plusone \else \plustwo \fi
- \to \everyjob
-\fi
-
-\appendtoks
- \ifcase\systemcommandmode
- \or
- \writestatus\m!systems{system commands are disabled}%
- \or
- \writestatus\m!systems{system commands are enabled}%
- \fi
-\to \everyjob
-
-\ifx\etexversion\undefined \else \ifnum\etexversion<202
- \prependtoks
- \writestatus\m!systems{eTeX version \number\etexversion\space -> too old (bugs)}%
- \writeline
- \to \everyjob
-\fi \fi
-
-\ifx\pdftexversion\undefined \else \ifnum\number\pdftexversion<120
- \prependtoks
- \writestatus\m!systems{pdfTeX version \number\pdftexversion\space -> please update}%
- \writeline
- \to \everyjob
-\fi \fi
-
-\prependtoks \showcontextbanner \to \everyjob
-
-% Default-instellingen (verborgen)
-
-\resetutilities
-
-\protect \endinput
diff --git a/tex/context/base/core-lme.tex b/tex/context/base/core-lme.tex
index d8c99d8c7..69dc3b7b2 100644
--- a/tex/context/base/core-lme.tex
+++ b/tex/context/base/core-lme.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Last Minute Extensions}
+\writestatus{loading}{ConTeXt Core Macros / Last Minute Extensions}
%D Things that depend on too much other things.
diff --git a/tex/context/base/core-lnt.tex b/tex/context/base/core-lnt.tex
index 0d960decd..ae3200e7a 100644
--- a/tex/context/base/core-lnt.tex
+++ b/tex/context/base/core-lnt.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Line Notes}
+\writestatus{loading}{ConTeXt Core Macros / Line Notes}
%D This module loads on top of the footnote and line numbering macros.
diff --git a/tex/context/base/core-lst.tex b/tex/context/base/core-lst.tex
index d246be3bc..84648f6c9 100644
--- a/tex/context/base/core-lst.tex
+++ b/tex/context/base/core-lst.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Lists}
+\writestatus{loading}{ConTeXt Core Macros / Lists}
\unprotect
@@ -241,6 +241,7 @@
\c!depth=\v!broad,
\c!offset=0.25em,
\c!maxwidth=,
+ \c!align=,
\c!state=\v!start,
\c!coupling=\v!off,
\c!criterium=\v!local,
diff --git a/tex/context/base/core-mak.tex b/tex/context/base/core-mak.tex
index 761f83156..574fb9756 100644
--- a/tex/context/base/core-mak.tex
+++ b/tex/context/base/core-mak.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / General Makeup Commands}
+\writestatus{loading}{ConTeXt Core Macros / General Makeup Commands}
\unprotect
diff --git a/tex/context/base/core-mar.tex b/tex/context/base/core-mar.tex
index 45d12d327..8096793ad 100644
--- a/tex/context/base/core-mar.tex
+++ b/tex/context/base/core-mar.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Markings}
+\writestatus{loading}{ConTeXt Core Macros / Markings}
\unprotect
@@ -108,9 +108,6 @@
\let\nomarking\empty
-\def\doifmarkingelse#1%
- {\doifdefinedelse{\??mk#1}}
-
\def\fetchmark[#1][#2]% % expandable / never use \unexpanded
{\ifcsname\??mk::#1\endcsname % saved mark
\csname\??mk::\??mk::#2\@EA\@EA\@EA\endcsname
diff --git a/tex/context/base/core-mat.tex b/tex/context/base/core-mat.tex
index f7517c445..21f4e60b8 100644
--- a/tex/context/base/core-mat.tex
+++ b/tex/context/base/core-mat.tex
@@ -13,7 +13,7 @@
% engels maken
-\writestatus{loading}{Context Core Macros / Math Fundamentals}
+\writestatus{loading}{ConTeXt Core Macros / Math Fundamentals}
\unprotect
@@ -31,16 +31,10 @@
% \definemessageconstant{math}
-% \startmessages all library: math
-% title: math
-% 1: don't use -- here (line \the\inputlineno)
-% \stopmessages
+% % messages moved
% \def\invalidmathcommand#1{\showmessage\m!math1{#1}}
-% \let\normaleqno \eqno
-% \let\normalleqno\leqno
-
% \appendtoks
% \def\eqno {\invalidmathcommand{\string\eqno }}%
% \def\leqno{\invalidmathcommand{\string\leqno}}%
@@ -55,7 +49,7 @@
% H(K|M,C) = H(K|C) - H(M|C)\eqno{\hbox{(\in{}[eq:keyapp])}}
% \stopformula
-\def\mathortext
+\unexpanded\def\mathortext
{\ifmmode
\expandafter\firstoftwoarguments
\else
@@ -342,11 +336,11 @@
\switchtoformulabodyfont[#2]%
\parskip\formulaparskip
\def\currentformula{#1}%
-% may look better in itemizations
-\doif{\formulaparameter\c!option}\v!middle
- {\def\leftdisplayskip{\zeropoint}%
- \def\rightdisplayskip{\zeropoint}}%
-% this was an experiment
+ % may look better in itemizations
+ \doif{\formulaparameter\c!option}\v!middle
+ {\def\leftdisplayskip{\zeropoint}%
+ \def\rightdisplayskip{\zeropoint}}%
+ % this was an experiment
\doifsomething{\formulaparameter\c!margin}% so we test first
{\dosetleftskipadaption{\formulaparameter\c!margin}%
\edef\leftdisplaymargin{\the\leftskipadaption}}% overloaded
@@ -415,9 +409,11 @@
\beforedisplayspace
\par
\ifvmode
- \verticalstrut
- \vskip-\struttotal
- \vskip-\baselineskip
+ \prevdepth-\maxdimen % texbook pagina 79-80
+ % otherwise problems at the top of a page, don't remove:
+ \verticalstrut
+ \vskip-\struttotal
+ \vskip-\baselineskip
\fi
\fi
$$\setdisplaydimensions
@@ -515,8 +511,6 @@
[\c!indentnext=\v!yes,
\c!alternative=multi]
-% in m-math
-%
% \defineformulaalternative[multi][\begindmath][\enddmath]
%
% \fakewords{20}{40}\epar
@@ -622,8 +616,8 @@
\setupsubformulas
[\c!conversion=\v!character,
-% \c!separator=\@@fmseparator,
- \c!separator=,%AM: for compatibility with \placesubformula
+ %\c!separator=\@@fmseparator,
+ \c!separator=,% AM: for compatibility with \placesubformula
\c!indentnext=\@@fmindentnext]
%D Experimental goodie:
@@ -718,9 +712,6 @@
\def\dispplaceformula[#1]#2$$#3$$%
{\dodoplaceformula[#1]{#2}\dostartformula{}#3\dostopformula}
-\let\normalreqno\eqno
-\let\normalleqno\leqno
-
\let\donestedformulanumber\gobbletwoarguments
\def\dodoplaceformula[#1]#2% messy, needs a clean up
@@ -768,6 +759,8 @@
%D The next code is derived from plain \TEX.
+\newcount\interdisplaylinepenalty \interdisplaylinepenalty=100
+
\newif\ifdt@p
\def\displ@y
@@ -777,7 +770,7 @@
{\noalign
{\ifdt@p
\global\dt@pfalse
- \ifdim\prevdepth>-1000\p@
+ \ifdim\prevdepth>-\thousandpoint
\vskip-\lineskiplimit
\vskip\normallineskiplimit
\fi
@@ -789,7 +782,7 @@
\def\displ@y{\resetdisplaymatheq\normaldispl@y}
-\def\m@th{\mathsurround\z@}
+\def\m@th{\mathsurround\zeropoint} % obsolete
%D Here we implement a basic math alignment mechanism. Numbers
%D are also handled. The macros \type {\startinnermath} and
@@ -1031,7 +1024,7 @@
%D some \PLAIN\ macros.
\def\@@dobig#1#2%
- {{\hbox{$\left#2\vbox\!!to#1\bodyfontsize{}\right.\n@space$}}}
+ {{\hbox{$\left#2\vbox\!!to#1\bodyfontsize{}\right.\nulldelimiterspace\zeropoint\relax\mathsurround\zeropoint$}}}
\def\big {\@@dobig{0.85}}
\def\Big {\@@dobig{1.15}}
@@ -2554,8 +2547,8 @@
\def\startsubstack
{\begingroup
\vcenter\bgroup
- \baselineskip\dimexpr\fontdimen10 \scriptfont\plustwo + \fontdimen12 \scriptfont\plustwo\relax
- \lineskip\plusthree\fontdimen8 \scriptfont\plusthree
+ \baselineskip\mathstacktotal
+ \lineskip\mathstackvgap
\lineskiplimit\lineskip
\let\stopmathmode\relax
\def\NC{\domatrixNC}%
@@ -2863,10 +2856,10 @@
\def\mathboldsymbol#1%
{\preparebinrel{#1}%
\currentbinrel{\mathchoice
- {\hbox{\switchtoformulabodyfont [boldmath]$\m@th#1$}}
- {\hbox{\switchtoformulabodyfont [boldmath]$\m@th#1$}}
- {\hbox{\switchtoformulabodyfont [boldmath,script]$\m@th#1$}}
- {\hbox{\switchtoformulabodyfont[boldmath,scriptscript]$\m@th#1$}}}}
+ {\hbox{\switchtoformulabodyfont [boldmath]$\mathsurround\zeropoint#1$}}
+ {\hbox{\switchtoformulabodyfont [boldmath]$\mathsurround\zeropoint#1$}}
+ {\hbox{\switchtoformulabodyfont [boldmath,script]$\mathsurround\zeropoint#1$}}
+ {\hbox{\switchtoformulabodyfont[boldmath,scriptscript]$\mathsurround\zeropoint#1$}}}}
\def\boldsymbol
{\mathortext\mathboldsymbol\bold}
@@ -2902,6 +2895,7 @@
\def\dealwithmathtextencoding
{\expanded{\everyhbox{\the\everyhbox\noexpand\fastenableencoding{\currentencoding}}}%
+ \expanded{\everyvbox{\the\everyvbox\noexpand\fastenableencoding{\currentencoding}}}%
\def\dealwithmathtextencoding{\let\characterencoding\nocharacterencoding}%
\dealwithmathtextencoding}
diff --git a/tex/context/base/core-mis.tex b/tex/context/base/core-mis.mkii
index de1da7597..e860a537a 100644
--- a/tex/context/base/core-mis.tex
+++ b/tex/context/base/core-mis.mkii
@@ -11,48 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Misc Commands}
+\writestatus{loading}{ConTeXt Core Macros / Misc Commands}
% todo: kleur in legenda + letter
-% Obsolete
-%
-% \startmessages dutch library: systems
-% title: systeem
-% 3: probeer LaTeX eens
-% \stopmessages
-%
-% \startmessages english library: systems
-% title: system
-% 3: try LaTeX
-% \stopmessages
-%
-% \startmessages german library: systems
-% title: system
-% 3: Versuche LaTeX
-% \stopmessages
-%
-% \startmessages czech library: systems
-% title: system
-% 3: zkuste LaTeX
-% \stopmessages
-%
-% \startmessages italian library: systems
-% title: sistema
-% 3: provare LaTeX
-% \stopmessages
-%
-% \startmessages norwegian library: systems
-% title: system
-% 3: forsker LaTeX
-% \stopmessages
-%
-% \startmessages romanian library: systems
-% title: sistem
-% 3: incercati LaTeX
-% \stopmessages
-%
-
% %D You would not expect the next macro in \CONTEXT,
% %D wouldn't you? It's there to warn \LATEX\ users that
% %D something is wrong.
@@ -82,16 +44,16 @@
%appendtoks \def\executesynonym#1#2#3#4{#3}\to\simplifiedcommands
%appendtoks \def\executesort#1#2#3{#3}\to\simplifiedcommands
-\appendtoks \def\ { }\to\simplifiedcommands
-\appendtoks \def\type#1{\string\\\strippedcsname#1}\to\simplifiedcommands
-\appendtoks \def\tex#1{\string\\#1}\to\simplifiedcommands
-\appendtoks \def\TeX{TeX}\to\simplifiedcommands
-\appendtoks \def\ConTeXt{ConTeXt}\to\simplifiedcommands
-\appendtoks \def\MetaPost{MetaPost}\to\simplifiedcommands
-\appendtoks \def\MetaFont{MetaFont}\to\simplifiedcommands
-\appendtoks \def\MetaFun{MetaFun}\to\simplifiedcommands
-%appendtoks \def||{-}\to\simplifiedcommands
-\appendtoks \def|#1|{\ifx#1\empty\empty-\else#1\fi}\to\simplifiedcommands
+\appendtoks \def\ { }\to\simplifiedcommands
+\appendtoks \def\type#1{\letterbackslash\strippedcsname#1}\to\simplifiedcommands
+\appendtoks \def\tex#1{\letterbackslash#1}\to\simplifiedcommands
+\appendtoks \def\TeX{TeX}\to\simplifiedcommands
+\appendtoks \def\ConTeXt{ConTeXt}\to\simplifiedcommands
+\appendtoks \def\MetaPost{MetaPost}\to\simplifiedcommands
+\appendtoks \def\MetaFont{MetaFont}\to\simplifiedcommands
+\appendtoks \def\MetaFun{MetaFun}\to\simplifiedcommands
+%appendtoks \def||{-}\to\simplifiedcommands
+\appendtoks \def|#1|{\ifx#1\empty\empty-\else#1\fi}\to\simplifiedcommands
\appendtoks\let\buildtextaccent\secondoftwoarguments\to\simplifiedcommands
@@ -650,7 +612,6 @@
\def\setuphyphenmark
{\dodoubleargument\getparameters[\??kp]}
-
\def\setuphyphenmark[#1]% sign=normal|wide
{\dodoubleargument\getparameters[\??kp][#1]%
\doifinsetelse\@@kpsign {\v!normal}
@@ -1316,74 +1277,74 @@
% old, will become obsolete or module, replace by bib module
-\defineenumeration
- [@publicatie]
- [\c!location=\v!left,
- \c!width=\@@pbwidth,\c!hang=,\c!sample=,
- \c!before=\@@pbbefore,\c!after=\@@pbafter,\c!inbetween=,
- \c!headstyle=\@@pbheadstyle,\c!style=,
- \c!headcolor=\@@pbheadcolor,\c!color=,
- \c!way=\@@pbway,\c!blockway=\@@pbblockway,
- \c!text=,\c!left=\@@pbleft,\c!right=\@@pbright]
-
-\def\dosetuppublications[#1]%
- {\getparameters[\??pb][#1]}
-
-\def\setuppublications%
- {\dosingleargument\dosetuppublications}
-
-\def\apa@publicatie
- {\doifsomething\@@pb@naam {\@@pb@naam,\space}%
- \doifsomething\@@pb@titel {{\sl\@@pb@titel}.\space}%
- \doifsomething\@@pb@jaar {(\@@pb@jaar).\space}%
- \doifsomething\@@pb@plaats {\@@pb@plaats\doifelsenothing\@@pb@uitgever{.}{:\space}}%
- \doifsomething\@@pb@uitgever{\@@pb@uitgever.}}
-
-\def\normaal@publicatie
- {\@@pb@naam, \@@pb@titel, \@@pb@jaar, \@@pb@pagina, \@@pb@plaats, \@@pb@uitgever.}
-
-\def\complexstartpublicatie[#1]#2\stoppublicatie
- {\bgroup
- \def\dosetpublicatie
- {\processcommalist
- [naam,titel,jaar,plaats,pagina,uitgever]
- \setpublicatie
- \ignorespaces}%
- \def\setpublicatie##1%
- {\letvalue{\??pb @##1}\empty
- \setvalue{##1}####1{\setvalue{\??pb @##1}{####1}\ignorespaces}}%
- \def\getpublicatie%
- {\doifsomething\@@pbalternative{\getvalue{\@@pbalternative @publicatie}}}%
- \doifelse\@@pbnumbering\v!yes
- {\@publicatie[#1]\dosetpublicatie#2\getpublicatie\par}%
- {\@@pbbefore
- \dosetpublicatie\ignorespaces#2\getpublicatie
- \@@pbafter}%
- \egroup}
-
-\definecomplexorsimpleempty\startpublicatie
-
-\def\publication#1[#2]%
- {\@@pbleft\in{#1}[#2]\@@pbright}
-
-\setuppublications
- [\c!numbering=\v!yes,
- \c!alternative=\c!apa,
- \c!width=2em,
- \c!hang=,
- \c!sample=,
- \c!before=,
- \c!after=,
- \c!inbetween=,
- \c!headstyle=,
- \c!headcolor=,
- \c!style=,
- \c!color=,
- \c!blockway=\v!by\v!text,
- \c!way=\v!by\v!text,
- \c!text=,
- \c!left={[},
- \c!right={]}]
+% \defineenumeration
+% [@publicatie]
+% [\c!location=\v!left,
+% \c!width=\@@pbwidth,\c!hang=,\c!sample=,
+% \c!before=\@@pbbefore,\c!after=\@@pbafter,\c!inbetween=,
+% \c!headstyle=\@@pbheadstyle,\c!style=,
+% \c!headcolor=\@@pbheadcolor,\c!color=,
+% \c!way=\@@pbway,\c!blockway=\@@pbblockway,
+% \c!text=,\c!left=\@@pbleft,\c!right=\@@pbright]
+
+% \def\dosetuppublications[#1]%
+% {\getparameters[\??pb][#1]}
+%
+% \def\setuppublications%
+% {\dosingleargument\dosetuppublications}
+%
+% \def\apa@publicatie
+% {\doifsomething\@@pb@naam {\@@pb@naam,\space}%
+% \doifsomething\@@pb@titel {{\sl\@@pb@titel}.\space}%
+% \doifsomething\@@pb@jaar {(\@@pb@jaar).\space}%
+% \doifsomething\@@pb@plaats {\@@pb@plaats\doifelsenothing\@@pb@uitgever{.}{:\space}}%
+% \doifsomething\@@pb@uitgever{\@@pb@uitgever.}}
+%
+% \def\normaal@publicatie
+% {\@@pb@naam, \@@pb@titel, \@@pb@jaar, \@@pb@pagina, \@@pb@plaats, \@@pb@uitgever.}
+%
+% \def\complexstartpublicatie[#1]#2\stoppublicatie
+% {\bgroup
+% \def\dosetpublicatie
+% {\processcommalist
+% [naam,titel,jaar,plaats,pagina,uitgever]
+% \setpublicatie
+% \ignorespaces}%
+% \def\setpublicatie##1%
+% {\letvalue{\??pb @##1}\empty
+% \setvalue{##1}####1{\setvalue{\??pb @##1}{####1}\ignorespaces}}%
+% \def\getpublicatie%
+% {\doifsomething\@@pbalternative{\getvalue{\@@pbalternative @publicatie}}}%
+% \doifelse\@@pbnumbering\v!yes
+% {\@publicatie[#1]\dosetpublicatie#2\getpublicatie\par}%
+% {\@@pbbefore
+% \dosetpublicatie\ignorespaces#2\getpublicatie
+% \@@pbafter}%
+% \egroup}
+%
+% \definecomplexorsimpleempty\startpublicatie
+%
+% \def\publication#1[#2]%
+% {\@@pbleft\in{#1}[#2]\@@pbright}
+%
+% \setuppublications
+% [\c!numbering=\v!yes,
+% \c!alternative=\c!apa,
+% \c!width=2em,
+% \c!hang=,
+% \c!sample=,
+% \c!before=,
+% \c!after=,
+% \c!inbetween=,
+% \c!headstyle=,
+% \c!headcolor=,
+% \c!style=,
+% \c!color=,
+% \c!blockway=\v!by\v!text,
+% \c!way=\v!by\v!text,
+% \c!text=,
+% \c!left={[},
+% \c!right={]}]
% only used at pragma, move from kernel to run time module
@@ -1460,37 +1421,21 @@
% THIS WAS MAIN-003.TEX
-\startmessages dutch library: systems
- 41: externe file -- in groep -- bestaat niet
-\stopmessages
+% messages moved
-\startmessages english library: systems
- 41: external file -- in group -- does not exist
-\stopmessages
+% messages moved
-\startmessages german library: systems
- 41: Externe Datei -- in Gruppe -- existiert nicht
-\stopmessages
+% messages moved
-\startmessages czech library: systems
- 41: externi soubor -- ve skupine -- neexistuje
-\stopmessages
+% messages moved
-\startmessages italian library: systems
- 41: il file esterno -- del gruppo -- non esiste
-\stopmessages
+% messages moved
-\startmessages norwegian library: systems
- 41: ekstern fil -- i gruppe -- eksisterer ikke
-\stopmessages
+% messages moved
-\startmessages romanian library: systems
- 41: fisierul extern -- din grupul -- nu exista
-\stopmessages
+% messages moved
-\startmessages french library: systems
- 41: le fichier externe -- du groupe -- n'existe pas
-\stopmessages
+% messages moved
\definetabulate
[\v!legend]
@@ -1852,8 +1797,6 @@
%D Goody:
-\newevery \everyinsidefloat \relax
-
\appendtoks
\global\resetsystemmode{combination}%
\global\resetsystemmode{pairedbox}%
@@ -2331,8 +2274,8 @@
\fi
\setbox\nextbox\vbox{\hbox{\raise\nextboxdp\flushnextbox}}%
\!!dimena \nextboxht
- \calculatecos\@@rorotation\edef\cos{\calculatedcos\@@rorotation}%
- \calculatesin\@@rorotation\edef\sin{\calculatedsin\@@rorotation}%
+ \setcalculatedcos\cos\@@rorotation
+ \setcalculatedsin\sin\@@rorotation
\@@layerxpos\zeropoint
\@@layerypos\zeropoint
\@@layerxoff\zeropoint
diff --git a/tex/context/base/core-mis.mkiv b/tex/context/base/core-mis.mkiv
new file mode 100644
index 000000000..96d3bd2cd
--- /dev/null
+++ b/tex/context/base/core-mis.mkiv
@@ -0,0 +1,2606 @@
+%D \module
+%D [ file=core-mis,
+%D version=1998.01.29,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Miscelaneous,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Core Macros / Misc Commands}
+
+% todo: kleur in legenda + letter
+
+% %D You would not expect the next macro in \CONTEXT,
+% %D wouldn't you? It's there to warn \LATEX\ users that
+% %D something is wrong.
+% %D
+% %D Obsolete now:
+% %
+% % \def\documentstyle{\showmessage\m!systems3\empty\stoptekst}
+% %
+% % \let\documentclass=\documentstyle
+% %D \macros
+% %D {simplifiedcommands, simplifycommands}
+% %D
+% %D I first needed this simplification in bookmarks. Users can
+% %D add their own if needed.
+
+\unprotect
+
+%D Sometimes (for instance in bookmarks) we need to simplify macro
+%D behaviour, so here is the hook.
+
+\ifx\simplifiedcommands\undefined \newtoks\simplifiedcommands \fi
+
+\def\simplifycommands{\the\simplifiedcommands}
+
+%D A possibly growing list:
+
+%appendtoks \def\executesynonym#1#2#3#4{#3}\to\simplifiedcommands
+%appendtoks \def\executesort#1#2#3{#3}\to\simplifiedcommands
+
+\appendtoks \def\ { }\to\simplifiedcommands
+\appendtoks \def\type#1{\letterbackslash\strippedcsname#1}\to\simplifiedcommands
+\appendtoks \def\tex#1{\letterbackslash#1}\to\simplifiedcommands
+\appendtoks \def\TeX{TeX}\to\simplifiedcommands
+\appendtoks \def\ConTeXt{ConTeXt}\to\simplifiedcommands
+\appendtoks \def\MetaPost{MetaPost}\to\simplifiedcommands
+\appendtoks \def\MetaFont{MetaFont}\to\simplifiedcommands
+\appendtoks \def\MetaFun{MetaFun}\to\simplifiedcommands
+%appendtoks \def||{-}\to\simplifiedcommands
+\appendtoks \def|#1|{\ifx#1\empty\empty-\else#1\fi}\to\simplifiedcommands
+
+\appendtoks\let\buildtextaccent\secondoftwoarguments\to\simplifiedcommands
+
+% THIS WAS MAIN-002.TEX
+
+%\def\checkinterlineskip
+% {\ifvmode
+% \ifdim\lastskip>\zeropoint
+% \nointerlineskip
+% \else\ifdim\lastkern>\zeropoint
+% \nointerlineskip
+% \fi\fi
+% \fi}
+
+\def\horitems#1#2% #1=breedte #2=commandos
+ {\scratchdimen#1%
+ \divide\scratchdimen \nofitems
+ \!!counta\zerocount
+ \def\docommand##1%
+ {\advance\!!counta \plusone
+ \processaction
+ [\@@isalign]
+ [ \v!left=>\hbox to \scratchdimen{\strut##1\hss},
+ \v!right=>\hbox to \scratchdimen{\hss\strut##1},
+ \v!middle=>\hbox to \scratchdimen{\hss\strut##1\hss},
+ \v!margin=>\ifnum\!!counta=\plusone\hss\else\hfill\fi
+ \strut##1%
+ \ifnum\!!counta=\nofitems\hss\else\hfill\fi,
+ \s!default=>\hbox to \scratchdimen{\hss\strut##1\hss}, % midden
+ \s!unknown=>\hbox to \scratchdimen{\strut##1\hss}]}% % links
+ \hbox to #1{\hss#2\hss}}
+
+\def\veritems#1#2% #1=breedte #2=commandos
+ {\scratchdimen#1%
+ \def\docommand##1%
+ {\ifdim\scratchdimen<\zeropoint % the - was a signal
+ \hbox to -\scratchdimen{\hss\strut##1}%
+ \else\ifdim\scratchdimen>\zeropoint
+ \hbox to \scratchdimen{\strut##1\hss}%
+ \else
+ \hbox{\strut##1}%
+ \fi\fi}%
+ \vbox{#2}}
+
+\def\dosetupitems[#1]%
+ {\getparameters[\??is][#1]%
+ \doif\@@iswidth\v!unknown
+ {\def\@@iswidth{\hsize}}%
+ \doifconversiondefinedelse\@@issymbol
+ {\def\doitembullet##1{\convertnumber{\@@issymbol}{##1}}}
+ {\doifsymboldefinedelse\@@issymbol
+ {\def\doitembullet##1{\symbol[\@@issymbol]}}{}}}
+
+\def\makeitemsandbullets#1%
+ {\doifelse\@@isn\v!unknown
+ {\getcommalistsize[#1]%
+ \edef\nofitems{\commalistsize}}
+ {\edef\nofitems{\@@isn}}%
+ \setbox0\hbox
+ {\doitems \@@iswidth
+ {\processcommalist[#1]\docommand}}%
+ \setbox2\hbox
+ {\doitems \@@isbulletbreedte
+ {\dorecurse\nofitems
+ {\docommand{\strut\doitembullet\recurselevel}}}}}
+
+\def\dostartitems#1#2#3%
+ {\let\doitems#2%
+ \def\@@isbulletbreedte{#3}%
+ \makeitemsandbullets{#1}%
+ \@@isbefore}
+
+\def\dostopitems
+ {\@@isafter
+ \egroup}
+
+\setvalue{doitems\v!top}#1%
+ {\dostartitems{#1}\horitems\@@iswidth
+ \noindent\vbox
+ {\forgetall
+ \doifsomething\@@issymbol
+ {\doifnot\@@issymbol\v!none
+ {\box2
+ \@@isinbetween
+ \nointerlineskip}}%
+ \box0}%
+ \dostopitems}
+
+\setvalue{doitems\v!bottom}#1%
+ {\dostartitems{#1}\horitems\@@iswidth
+ \noindent\vbox
+ {\forgetall
+ \box0
+ \doifsomething\@@issymbol
+ {\@@isinbetween
+ \nointerlineskip
+ \box2}}%
+ \dostopitems}
+
+\setvalue{doitems\v!inmargin}#1%
+ {\dostartitems{#1}\veritems{-1.5em}% - is a signal
+ \noindent\hbox{\llap{\box2\hskip\leftmargindistance}\box0}%
+ \dostopitems}
+
+\setvalue{doitems\v!left}#1%
+ {\advance\hsize -1.5em%
+ \dostartitems{#1}\veritems{1.5em}%
+ \noindent\hbox{\box2\box0}%
+ \dostopitems}
+
+\setvalue{doitems\v!right}#1%
+ {\dostartitems{#1}\veritems{0em}%
+ \noindent\hbox{\box0\hskip-\wd2\box2}%
+ \dostopitems}
+
+\def\setupitems
+ {\dosingleargument\dosetupitems}
+
+\def\complexitems[#1]%
+ {\bgroup
+ \setupitems[#1]%
+ \parindent\zeropoint
+ \setlocalhsize
+ \hsize\localhsize
+ \dontcomplain
+ %\doifundefined{doitems\@@islocation}%
+ % {\let\@@islocation\v!left}%
+ %\getvalue{doitems\@@islocation}}
+ \executeifdefined{doitems\@@islocation}{\let\@@islocation\v!left}}
+
+\definecomplexorsimpleempty\items
+
+\setupitems
+ [\c!location=\v!left,
+ \c!symbol=5,
+ \c!width=\hsize,
+ \c!align=\v!middle,
+ \c!n=\v!unknown,
+ \c!before=\blank,
+ \c!inbetween={\blank[\v!medium]},
+ \c!after=\blank]
+
+% Te zijner tijd [plaats=boven,onder,midden] implementeren,
+% in dat geval moet eerst de maximale hoogte worden bepaald.
+%
+% Overigens kan een en ander mooier met \halign.
+
+% there is quite some historic balast in this mechanism, the next variant
+% is a first cleanup
+
+\let\currentparagraph\empty
+
+\newcount\alcounter \newcount\alnsize \newdimen\alhsize
+
+\def\paragraphparameter#1% \checkedparameter\??al\currentparagraph#1
+ {\executeifdefined{\??al\currentparagraph#1}{\executeifdefined{\??al#1}\empty}}
+
+\def\paragraphcellmeter#1#2% \checkedparameter\??al\currentparagraph#1
+ {\executeifdefined{\??al\currentparagraph\number#1#2}{\paragraphparameter{#2}}}
+
+\def\dodefineparagraphs[#1][#2]%
+ {\edef\currentparagraph{#1}%
+ \setvalue{\s!do\s!next\currentparagraph}%
+ {\def\\{\getvalue\currentparagraph}}%
+ \setvalue\currentparagraph
+ {\getvalue{\s!do\s!next#1}%
+ \dostartparagraphs{#1}}%
+ \setvalue{\e!next\currentparagraph}%
+ {\getvalue{#1}}%
+ \setvalue{\e!start\currentparagraph}%
+ {\bgroup
+ \edef\currentparagraph{#1}%
+ \letvalue{\s!do\s!next\currentparagraph}\empty
+ \setvalue{\e!stop\currentparagraph}{\getvalue\currentparagraph\egroup}%
+ \getvalue\currentparagraph}%
+ \getparameters[\??al\currentparagraph]%
+ [%\c!n=3,
+ %\c!before=\blank,
+ %\c!after=\blank,
+ %\c!distance=1em,
+ %\c!height=\v!fit,
+ %\c!rule=\v!off,
+ %\c!command=,
+ %\c!align=,
+ %\c!tolerance=\v!tolerant,
+ %\c!rulethickness=\linewidth,
+ %\c!rulecolor=,
+ %\c!style=,
+ %\c!color=,
+ %\c!top=,
+ %\c!top=\vss,
+ %\c!bottom=\vfill,
+ #2]%
+ \setvalue{\e!setup#1\e!endsetup}%
+ {\setupparagraphs[#1]}%
+ \dorecurse
+ {\paragraphparameter\c!n}
+ {\setupparagraphs
+ [\currentparagraph]
+ [\recurselevel]
+ [\c!width=,
+ %\c!bottom=\paragraphparameter\c!bottom,
+ %\c!top=\paragraphparameter\c!top,
+ %\c!height=\paragraphparameter\c!height,
+ %\c!rule=\paragraphparameter\c!rule,
+ %\c!rulethickness=\paragraphparameter\c!rulethickness,
+ %\c!rulecolor=\paragraphparameter\c!rulecolor,
+ %\c!align=\paragraphparameter\c!align,
+ %\c!tolerance=\paragraphparameter\c!tolerance, % obsolete
+ %\c!distance=\paragraphparameter\c!distance,
+ \c!style=\paragraphparameter\c!style,
+ \c!color=\paragraphparameter\c!color]}%
+ \setupparagraphs[\currentparagraph][1][\c!distance=\zeropoint]}
+
+\def\defineparagraphs
+ {\dodoubleargument\dodefineparagraphs}
+
+\def\dosetupparagraphs[#1][#2][#3]%
+ {\edef\currentparagraph{#1}%
+ \ifsecondargument
+ \doifelse{#2}\v!each
+ {\dorecurse
+ {\paragraphparameter\c!n}
+ {\getparameters[\??al\currentparagraph\recurselevel][#3]}}
+ {\doifelsenothing{#3}
+ {\getparameters[\??al\currentparagraph][#2]}
+ {\def\docommand##1{\getparameters[\??al\currentparagraph##1][#3]}%
+ \processcommalist[#2]\docommand}}%
+ \else
+ \getparameters[\??al][#1]%
+ \fi}
+
+\def\setupparagraphs
+ {\dotripleempty\dosetupparagraphs}
+
+\setupparagraphs
+ [\c!n=3,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!distance=1em,
+ \c!height=\v!fit,
+ \c!rule=\v!off,
+ \c!command=,
+ \c!align=,
+ \c!tolerance=\v!tolerant, % obsolete
+ \c!rulethickness=\linewidth,
+ \c!rulecolor=,
+ \c!style=,
+ \c!color=,
+ \c!top=,
+ \c!top=\vss,
+ \c!bottom=\vfill]
+
+\def\doparagraphrule
+ {\doifelse{\paragraphcellmeter\alcounter\c!rule}\v!on
+ {\linewidth\paragraphcellmeter\alcounter\c!rulethickness
+ \scratchdimen\paragraphcellmeter\alcounter\c!distance
+ \advance\scratchdimen-\linewidth
+ \divide\scratchdimen \plustwo
+ \hskip\scratchdimen
+ \color[\paragraphcellmeter\alcounter\c!rulecolor]{\vrule\!!width\linewidth}%
+ \hskip\scratchdimen}
+ {\hskip\paragraphcellmeter\alcounter\c!distance}}
+
+\def\dostartparagraph
+ {\doifelsenothing{\paragraphcellmeter\alcounter\c!width}
+ {\!!widtha\alhsize
+ \divide\!!widtha \alnsize}
+ {\!!widtha\paragraphcellmeter\alcounter\c!width}%
+ \dostartattributes{\??al\currentparagraph\number\alcounter}\c!style\c!color\empty
+ \doifelse{\paragraphcellmeter\alcounter\c!height}\v!fit
+ {\setbox\scratchbox\vtop}
+ {\setbox\scratchbox\vtop to \paragraphcellmeter\alcounter\c!height}%
+ \bgroup
+ \blank[\v!disable]%
+ \forgetall
+ \paragraphcellmeter\alcounter\c!top
+ \paragraphparameter\c!inner
+ \hsize\!!widtha % setting \wd afterwards removed
+ \paragraphcellmeter\alcounter\c!inner % twice
+ \expanded{\setupalign [\paragraphcellmeter\alcounter\c!align ]}% {normal,verytolerant,stretch}
+ \expanded{\setuptolerance[\paragraphcellmeter\alcounter\c!tolerance]}% obsolete
+ \ignorespaces
+ \endgraf
+ \ignorespaces
+ %
+ % Nadeel van de onderstaande constructie is dat \everypar
+ % binnen een groep kan staan en zo steeds \begstruts
+ % worden geplaatst. Mooi is anders dus moet het anders!
+ %
+ % Hier is \Everypar niet nodig.
+ %
+ \everypar{\begstrut\everypar\emptytoks}%
+ %
+ \nospace % remove + ignore
+ \paragraphcellmeter\alcounter\c!command}
+
+\def\dostopparagraph
+ {\ifvmode
+ \removelastskip
+ \else
+ \unskip\endstrut\endgraf
+ \fi
+ \paragraphcellmeter\alcounter\c!bottom
+ \egroup
+ \ifdim\wd\scratchbox=\zeropoint % no data
+ \wd\scratchbox\!!widtha
+ \fi
+ \box\scratchbox
+ \dostopattributes
+ \ifnum\alcounter<\paragraphparameter\c!n\relax
+ \@EA\doparagraphcell
+ \else
+ \@EA\dostopparagraphs
+ \fi}
+
+\def\doparagraphcell
+ {\global\advance\alcounter \plusone
+ \doifelsenothing{\paragraphcellmeter\alcounter\c!distance}
+ {\ifnum\alcounter=\plusone\else
+ \hskip\paragraphparameter\c!distance
+ \fi}
+ {\ifnum\alcounter=\plusone
+ \hskip\paragraphcellmeter\alcounter\c!distance
+ \else
+ \doparagraphrule
+ \fi}%
+ \letvalue\currentparagraph\dostopparagraph
+ \dostartparagraph}
+
+\def\dostartparagraphs#1%
+ {\bgroup
+ \edef\currentparagraph{#1}%
+ \global\alcounter\zerocount
+ \parindent\zeropoint
+ \setlocalhsize
+ \alhsize\localhsize
+ \alnsize\paragraphparameter\c!n\relax
+ \dorecurse \alnsize
+ {\doifelsenothing{\paragraphcellmeter\recurselevel\c!distance}
+ {\ifnum\recurselevel=\plusone\else
+ \global\advance\alhsize -\paragraphparameter\c!distance
+ \fi}
+ {\global\advance\alhsize -\paragraphcellmeter\recurselevel\c!distance}%
+ \doifsomething{\paragraphcellmeter\recurselevel\c!width}
+ {\global\advance\alnsize \minusone
+ \global\advance\alhsize -\paragraphcellmeter\recurselevel\c!width}}%
+ %whitespace % gaat fout bij \framed
+ \paragraphparameter\c!before
+ \leavevmode % gaat wel goed bij \framed, brrr
+ \setbox\scratchbox\vbox\bgroup\hbox\bgroup\doparagraphcell}
+
+\def\dostopparagraphs
+ {\egroup
+ \egroup
+ \iftrue
+ \hbox{\raise\strutheight\box\scratchbox}% new
+ \else
+ \box\scratchbox % old
+ \fi
+ \par
+ \paragraphparameter\c!after
+ \egroup}
+
+\def\dosetuptab[#1]%
+ {\getparameters[\??ta]
+ [\c!headstyle=\v!normal,
+ \c!headcolor=,
+ \c!style=\v!normal,
+ \c!color=,
+ \c!width=\v!broad,
+ \c!sample={\hskip4em},
+ \c!before=,
+ \c!after=,
+ #1]%
+ \definedescription
+ [tab]
+ [\c!headstyle=\@@taheadstyle,
+ \c!headcolor=\@@tacolor,
+ \c!sample=\@@tasample,
+ \c!width=\@@tawidth,
+ \c!before=\@@tabefore,
+ \c!after=\@@taafter]}
+
+\def\setuptab
+ {\dosingleargument\dosetuptab}
+
+\setuptab
+ [\c!location=\v!left]
+
+% The following macro's are derived from PPCHTEX and
+% therefore take some LaTeX font-switching into account.
+
+\newif\ifloweredsubscripts
+
+% Due to some upward incompatibality of LaTeX to LaTeX2.09
+% and/or LaTeX2e we had to force \@@chemieletter. Otherwise
+% some weird \nullfont error comes up.
+
+\doifundefined{@@chemieletter}{\def\@@chemieletter{\rm}}
+
+\def\beginlatexmathmodehack
+ {\ifmmode
+ \let\endlatexmathmodehack\relax
+ \else
+ \def\endlatexmathmodehack{$}$\@@chemieletter
+ \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}{\textfont2}{##2}%
+ \dosetsubscript{##1}{\scriptfont2}{##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}
+
+\let\beginlatexmathmodehack = \relax
+\let\endlatexmathmodehack = \relax
+
+\def\chem#1#2#3%
+ {\bgroup
+ \setsubscripts
+ \mathematics{\hbox{#1}_{#2}^{#3}}%
+ \resetsubscripts
+ \egroup}
+
+\unexpanded\def\celsius #1{#1\mathematics{^\circ}C}
+\unexpanded\def\inch {\mathematics{\prime\prime}} % was: \hbox{\rm\char125\relax}
+\unexpanded\def\fraction#1#2{\mathematics{#1\over#2}}
+
+% very dutch
+
+\unexpanded\def\graden {\mathematics{^\circ}}
+
+\def\bedragprefix {\euro\normalfixedspace}
+\def\bedragsuffix {}
+\def\bedragempty {\euro}
+
+\unexpanded\def\bedrag#1%
+ {\strut\hbox\bgroup
+ \let\normalfixedspace\nonbreakablespace
+ \doifelsenothing{#1}
+ {\bedragempty}
+ {\bedragprefix\digits{#1}\bedragsuffix}%
+ \egroup}
+
+% \definieeralineas[test][n=3]
+%
+% \stelalineasin[test][3][breedte=4cm,uitlijnen=links]
+%
+% \startopelkaar
+% \test hans \\ ton \\ \bedrag{1.000,--} \\
+% \test hans \\ ton \\ \bedrag{~.~~1,--} \\
+% \test hans \\ ton \\ \bedrag{~.~~1,~~} \\
+% \test hans \\ ton \\ \bedrag{~.100,--} \\
+% \test hans \\ ton \\ \subtot{1.000,--} \\
+% \test hans \\ ton \\ \bedrag{1.000,--} \\
+% \test hans \\ ton \\ \bedrag{1.000,--} \\
+% \test hans \\ ton \\ \totaal{1.000,--} \\
+% \test hans \\ ton \\ \bedrag{nihil,--} \\
+% \test hans \\ ton \\ \totaal{nihil,--} \\
+% \test hans \\ ton \\ \subtot{nihil,--} \\
+% \stopopelkaar
+
+\def\periodswidth {.5em}
+\def\periodsdefault{3} % was 5, but now it's like \unknown
+
+\unexpanded\def\periods
+ {\dosingleempty\doperiods}
+
+\def\doperiods[#1]% todo: also n=,width= or maybe just #1,#2
+ {\dontleavehmode
+ \begingroup
+ \scratchdimen\periodswidth
+ \hbox to \iffirstargument#1\else\periodsdefault\fi \scratchdimen
+ {\leaders\hbox to \scratchdimen{\hss.\hss}\hss}%
+ \endgroup}
+
+\unexpanded\def\unknown
+ {\periods\relax} % relax prevents lookahead for []
+
+% Example by Wolfgang Schuster on the context list:
+%
+% \unexpanded\def\fourdots{{\def\periodswidth{.3em}\periods[4]}}
+%
+% Hello\fourdots\ World\fourdots \par Hello\fourdots\ World.
+
+% compatibility macros
+
+\def\doorsnede
+ {\hbox{\rlap/$\circ$} }
+
+\unexpanded\def\ongeveer
+ {\mathematics\pm}
+
+\chardef\boundarycharactermode\plusone
+
+\def\midboundarycharacter#1#2%
+ {\ifcase\boundarycharactermode
+ \or
+ %\nobreak
+ \hskip\hspaceamount\currentlanguage{#2}%
+ \languageparameter#1%
+ %\nobreak
+ \hskip\hspaceamount\currentlanguage{#2}%
+ \or
+ \languageparameter#1%
+ \fi
+ \chardef\boundarycharactermode\plusone}
+
+\def\leftboundarycharacter#1#2%
+ {\ifcase\boundarycharactermode
+ \or
+ \languageparameter#1%
+ \nobreak
+ \hskip\hspaceamount\currentlanguage{#2}%
+ \or
+ \languageparameter#1%
+ \fi
+ \chardef\boundarycharactermode\plusone}
+
+\def\rightboundarycharacter#1#2%
+ {\ifcase\boundarycharactermode
+ \or
+ \prewordbreak %\nobreak
+ \hskip\hspaceamount\currentlanguage{#2}%
+ \languageparameter#1%
+ \or
+ \languageparameter#1%
+ \fi
+ \chardef\boundarycharactermode\plusone}
+
+% actually this is pretty old, but temporary moved here
+%
+% obsolete:
+
+\def\setuphyphenmark
+ {\dodoubleargument\getparameters[\??kp]}
+
+\def\setuphyphenmark[#1]% sign=normal|wide
+ {\dodoubleargument\getparameters[\??kp][#1]%
+ \doifinsetelse\@@kpsign {\v!normal}
+ {\let\textmodehyphen\normalhyphen \let\textmodehyphendiscretionary\normalhyphendiscretionary}
+ {\let\textmodehyphen\composedhyphen\let\textmodehyphendiscretionary\composedhyphendiscretionary}}
+
+\setuphyphenmark[\c!sign=\v!wide]
+% % \setuphyphenmark[\c!sign=\v!normal]
+
+\definesymbol[\c!lefthyphen] [\languageparameter\c!lefthyphen]
+\definesymbol[\c!righthyphen] [\languageparameter\c!righthyphen]
+\definesymbol[\c!hyphen] [\languageparameter\c!hyphen]
+
+\def\normalhyphen
+ {\hbox{\directsymbol\empty\c!hyphen}}
+
+\def\composedhyphen
+ {\hbox{\directsymbol\empty\c!compoundhyphen}}
+
+\def\normalhyphendiscretionary
+ {\discretionary
+ {\hbox{\directsymbol\empty\c!lefthyphen}}
+ {\hbox{\directsymbol\empty\c!righthyphen}}
+ {\hbox{\directsymbol\empty\c!hyphen}}}
+
+\def\composedhyphendiscretionary
+ {\discretionary
+ {\hbox{\directsymbol\empty\c!leftcompoundhyphen}}
+ {\hbox{\directsymbol\empty\c!rightcompoundhyphen}}
+ {\hbox{\directsymbol\empty\c!compoundhyphen}}}
+
+\let\textmodehyphen \composedhyphen
+\let\textmodehyphendiscretionary\composedhyphendiscretionary
+
+\definesymbol[\c!leftcompoundhyphen] [\languageparameter\c!leftcompoundhyphen]
+\definesymbol[\c!rightcompoundhyphen] [\languageparameter\c!rightcompoundhyphen]
+\definesymbol[\c!compoundhyphen] [\languageparameter\c!compoundhyphen]
+
+\definehspace [sentence] [\zeropoint]
+\definehspace [intersentence] [.250em]
+
+\definesymbol
+ [\c!midsentence]
+ [\midboundarycharacter\c!midsentence{sentence}]
+
+\definesymbol
+ [\c!leftsentence]
+ [\leftboundarycharacter\c!leftsentence{sentence}]
+
+\definesymbol
+ [\c!rightsentence]
+ [\rightboundarycharacter\c!rightsentence{sentence}]
+
+\definesymbol
+ [\c!leftsubsentence]
+ [\leftboundarycharacter\c!leftsubsentence{sentence}]
+
+\definesymbol
+ [\c!rightsubsentence]
+ [\rightboundarycharacter\c!rightsubsentence{sentence}]
+
+\newsignal \subsentencesignal
+\newcount \subsentencelevel
+
+\let\beforesubsentence\donothing
+\let\aftersubsentence \donothing
+
+% todo: make this language option
+%
+% \def\beforesubsentence{\removeunwantedspaces}
+% \def\aftersubsentence {\ignorespaces}
+
+\def\midsentence
+ {\symbol[\c!midsentence]}
+
+\def\beginofsubsentence
+ {\beforesubsentence
+ \ifdim\lastkern=\subsentencesignal
+ \unskip
+ \kern\hspaceamount\currentlanguage{intersentence}%
+ \fi
+ \global\advance\subsentencelevel\plusone
+ \ifnum\subsentencelevel=\plusone
+ \dontleavehmode % was \leaveoutervmode
+ \fi
+ \symbol[\ifodd\subsentencelevel\c!leftsentence\else\c!leftsubsentence\fi]%
+ }% \ignorespaces}
+
+\def\endofsubsentence % relax prevents space gobbling
+ {\symbol[\ifodd\subsentencelevel\c!rightsentence\else\c!rightsubsentence\fi]%
+ \global\advance\subsentencelevel\minusone
+ \unskip
+ \kern\subsentencesignal\relax
+ \aftersubsentence}
+
+\def\beginofsubsentencespacing % relax prevents space gobbling
+ {\kern\subsentencesignal\relax}% \ignorespaces}
+
+\def\endofsubsentencespacing
+ {\ifdim\lastkern=\subsentencesignal
+ \unskip
+ \hskip\hspaceamount\currentlanguage{intersentence}%
+ % no good, actually language dependent:
+% \ignorespaces
+ \else
+ \unskip
+ \fi}
+
+%D \startbuffer
+%D test |<|test |<|test|>| test|>| test \par
+%D test|<|test|<|test|>|test|>|test \par
+%D test |<||<|test|>||>| test \par
+%D test \directdiscretionary{<}test\directdiscretionary{>} test \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \getbuffer
+
+\def\startsubsentence{\beginofsubsentence \prewordbreak\beginofsubsentencespacing}
+\def\stopsubsentence {\endofsubsentencespacing\prewordbreak\endofsubsentence}
+
+%D \defineXMLenvironment [subsentence]
+%D {|<|}
+%D {|>|}
+%D \defineXMLenvironment [subsentence]
+%D {\directdiscretionary{<}}
+%D {\directdiscretionary{>}}
+%D \defineXMLenvironment [subsentence]
+%D {\startsubsentence}
+%D {\stopsubsentence}
+%D
+%D \startbuffer
+%D test <subsentence>test</subsentence> test
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \processXMLbuffer
+
+\enableactivediscretionaries
+
+\definehspace [quotation] [\zeropoint]
+\definehspace [interquotation] [.125em]
+
+%definehspace [quote] [\zeropoint]
+%definehspace [speech] [\zeropoint]
+
+\definehspace [quote] [\hspaceamount\currentlanguage{quotation}]
+\definehspace [speech] [\hspaceamount\currentlanguage{quotation}]
+
+\definesymbol
+ [\c!leftquotation]
+ [\leftboundarycharacter\c!leftquotation{quotation}]
+
+\definesymbol
+ [\c!rightquotation]
+ [\rightboundarycharacter\c!rightquotation{quotation}]
+
+\definesymbol
+ [\c!leftquote]
+ [\leftboundarycharacter\c!leftquote{quote}]
+
+\definesymbol
+ [\c!rightquote]
+ [\rightboundarycharacter\c!rightquote{quote}]
+
+\definesymbol
+ [\c!leftspeech]
+ [\leftboundarycharacter\c!leftspeech{speech}]
+
+\definesymbol
+ [\c!rightspeech]
+ [\rightboundarycharacter\c!rightspeech{speech}]
+
+\definesymbol
+ [\c!middlespeech]
+ [\leftboundarycharacter\c!middlespeech{speech}]
+
+\appendtoks\def\quotation#1{"#1"}\to\simplifiedcommands
+\appendtoks\def\quote #1{'#1'}\to\simplifiedcommands
+
+%D The next features was so desperately needed by Giuseppe
+%D Bilotta that he made a module for it. Since this is a
+%D typical example of core functionality, I decided to extend
+%D the low level quotation macros in such a way that a speech
+%D feature could be build on top of it. The speech opening and
+%D closing symbols are defined per language. Italian is an
+%D example of a language that has them set.
+
+% this will replace the quotation and speed definitions
+
+\newsignal\delimitedtextsignal
+
+\let\currentdelimitedtext\s!unknown
+
+\def\delimitedtextlevel{\csname\??ci:\currentdelimitedtext:\c!level\endcsname}
+
+\def\doinitializetextlevel#1%
+ {\ifcsname\??ci:#1:\c!level\endcsname
+ \newcount\csname\??ci:#1:\c!level\endcsname\zerocount
+ \else
+ \expandafter\newcount\csname\??ci:#1:\c!level\endcsname
+ \fi}
+
+\def\delimitedtextparameter#1% will be sped up
+ {\executeifdefined{\??ci\currentdelimitedtext:\number\delimitedtextlevel#1}%
+ {\executeifdefined{\??ci\currentdelimitedtext#1}%
+ {\executeifdefined{\??ci#1}\empty}}}
+
+\def\definedelimitedtext
+ {\dodoubleempty\dodefinedelimitedtext}
+
+\def\dodefinedelimitedtext[#1][#2]%
+ {\doinitializetextlevel{#1}%
+ \doifassignmentelse{#2}
+ {\getparameters
+ [\??ci#1]
+ [\c!location=\v!margin, % \v!text \v!paragraph
+ \c!spacebefore=,
+ \c!spaceafter=\delimitedtextparameter\c!spacebefore,
+ \c!style=\v!normal,
+ \c!color=,
+ \c!leftmargin=\zeropoint,
+ \c!rightmargin=\delimitedtextparameter\c!leftmargin,
+ \c!indentnext=\v!yes,
+ \c!before=,
+ \c!after=,
+ \c!left=,
+ \c!right=,
+ %\c!level=0,
+ \c!repeat=\v!no,
+ \c!method=,
+ #2]}%
+ {\doifdefined{#2}
+ {\copyparameters[\??ci#1][\??ci#2]
+ [\c!location,\c!spacebefore,\c!spaceafter,\c!style,\c!color,
+ \c!leftmargin,\c!rightmargin,\c!indentnext,
+ \c!before,\c!after,\c!left,\c!right]}}%
+ \doifsomething{#1}
+ {\unexpanded\setvalue{#1}{\delimitedtext[#1]}%
+ \setvalue{\e!start#1}{\startdelimitedtext[#1]}%
+ \setvalue{\e!stop #1}{\stopdelimitedtext}}}
+
+\def\setupdelimitedtext
+ {\dotripleargument\dosetupdelimitedtext}
+
+\def\dosetupdelimitedtext[#1][#2][#3]% #2 = optional level
+ {\ifthirdargument
+ \getparameters[\??ci#1:#2][#3]%
+ \else\ifsecondargument
+ \getparameters[\??ci#1][#2]%
+ \else
+ \getparameters[\??ci][#1]%
+ \fi\fi}
+
+\def\dorepeatdelimitedtext
+ {\relax\ifcase\delimitedtextlevel\else
+ \dohandledelimitedtext\c!middle % maybe better \dohandleleftdelimitedtext
+ \fi}
+
+\let\dohandlerepeatdelimitedtext\relax
+
+\def\startdelimitedtext[#1]%
+ {\bgroup
+ \pushdelimitedtext{#1}%
+ \doifelse{\delimitedtextparameter\c!method}\s!font
+ {\def\dostopdelimitedtext
+ {\removeunwantedspaces\ignoredelimitedtext\c!right}%
+ \ignoredelimitedtext\c!left\ignorespaces}
+ {\doifelse{\delimitedtextparameter\c!repeat}\v!yes
+ {\let\dohandlerepeatdelimitedtext\dorepeatdelimitedtext}%
+ {\let\dohandlerepeatdelimitedtext\relax}%
+ \doifinsetelse{\delimitedtextparameter\c!location}{\v!paragraph,\v!margin}%
+ {\dosingleempty\dostartdelimitedtextpar}\dostartdelimitedtexttxt}}
+
+\def\dostartdelimitedtextpar[#1]%
+ {\let\dostopdelimitedtext\dostopdelimitedtextpar
+ \doifsomething{\delimitedtextparameter\c!spacebefore}
+ {\blank[\delimitedtextparameter\c!spacebefore]}%
+ \delimitedtextparameter\c!before
+ % nicer:
+ % \doadaptleftskip {\delimitedtextparameter\c!leftmargin}%
+ % \doadaptrightskip{\delimitedtextparameter\c!rightmargin}%
+ % backward compatible:
+ \doifelsenothing{#1}
+ {\endgraf
+ \doadaptleftskip {\delimitedtextparameter\c!leftmargin}%
+ \doadaptrightskip{\delimitedtextparameter\c!rightmargin}%
+ \let\dodostopdelimitedtextpar\endgraf}
+ {\startnarrower[#1]\let\dodostopdelimitedtextpar\stopnarrower}%
+ % so far
+ % \dochecknextindentation{\??ci\currentdelimitedtext}% AM: not here
+ \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color\empty
+ \leftdelimitedtextmark
+ \ignorespaces}
+
+\def\dostopdelimitedtextpar
+ {\removeunwantedspaces
+ \removelastskip
+ \rightdelimitedtextmark
+ \dostopattributes
+ \dodostopdelimitedtextpar
+ \delimitedtextparameter\c!after
+ \doifsomething{\delimitedtextparameter\c!spaceafter}
+ {\blank[\delimitedtextparameter\c!spaceafter]}%
+ \dochecknextindentation{\??ci\currentdelimitedtext}% AM: here
+ \dorechecknextindentation}% AM: This was missing!
+
+\def\dostartdelimitedtexttxt
+ {\let\dostopdelimitedtext\dostopdelimitedtexttxt
+ \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color\empty
+ \dohandleleftdelimitedtext\c!left
+ \ignorespaces}
+
+\def\dostopdelimitedtexttxt
+ {\removeunwantedspaces
+ \dohandlerightdelimitedtext\c!right
+ \dostopattributes}
+
+\def\stopdelimitedtext
+ {\dostopdelimitedtext
+ \popdelimitedtext
+ \egroup}
+
+\def\pushdelimitedtext#1%
+ {\globalpushmacro\currentdelimitedtext
+ \def\currentdelimitedtext{#1}%
+ \global\advance\delimitedtextlevel\plusone}
+
+\def\popdelimitedtext
+ {\global\advance\delimitedtextlevel\minusone
+ \globalpopmacro\currentdelimitedtext}
+
+\def\delimitedtext[#1]%
+ {\pushdelimitedtext{#1}%
+ \doifelse{\delimitedtextparameter\c!method}\s!font
+ {\dofontdrivendelimited}
+ {\doifinsetelse{\delimitedtextparameter\c!location}{\v!paragraph,\v!margin}%
+ \dodelimitedtextpar\dodelimitedtexttxt}}
+
+% shortcuts
+
+\def\startdelimited{\startdelimitedtext}
+\def\stopdelimited {\stopdelimitedtext} % no let, dynamically assigned
+\def\delimited {\delimitedtext}
+
+\def\leftdelimitedtextmark
+ {\doifsomething{\delimitedtextparameter\c!left}
+ {\setbox\scratchbox\hbox{\delimitedtextparameter\c!left}%
+ \dontleavehmode
+ \doif{\delimitedtextparameter\c!location}\v!margin{\hskip-\wd\scratchbox}%
+ \box\scratchbox}}
+
+\def\rightdelimitedtextmark
+ {\doifsomething{\delimitedtextparameter\c!right}
+ {\hsmash{\delimitedtextparameter\c!right}}}
+
+% \starttext
+% \hyphenatedword{groepsvrijstellingsverordeningen}\par
+% \hyphenatedword{\quote{groepsvrijstellingsverordeningen}}\par
+% \dorecurse{100}{\hskip300pt\hskip\recurselevel pt test \quote{xxx xxxx}.\par}
+% \page \setuppapersize[A5][A4]
+% \quotation {overly beautiful pusillanimous sesquipedalian
+% longwinded} test test test test test test test test test test test
+% test test test test test test test test test test test test test
+% test test test test test test test test test test test test test
+% test test test test test test test test test test test test test
+% test test test
+% \stoptext
+
+\def\dohandledelimitedtext#1#2%
+ {\begingroup
+ \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
+ \ifdim\wd\scratchbox>\zeropoint
+% \ifdim\lastskip=\delimitedtextsignal
+% \unskip
+ \ifdim\lastkern=\delimitedtextsignal
+ \unkern
+ \hskip\hspaceamount\currentlanguage{interquotation}%
+ \else
+ #2%
+ \fi
+ \ifhmode % else funny pagebeaks
+ \penalty\plustenthousand
+ \hskip\zeropoint % == \prewordbreak
+ \fi
+ \strut % new, needed below
+ \delimitedtextparameter#1% unhbox\scratchbox
+% \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods
+ \kern\delimitedtextsignal % +- \prewordbreak
+ \fi
+ \endgroup}
+
+\def\dohandleleftdelimitedtext#1#2%
+ {\begingroup
+ \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
+ \ifdim\wd\scratchbox>\zeropoint
+ \ifdim\lastkern=\delimitedtextsignal
+ \unkern
+ \hskip\hspaceamount\currentlanguage{interquotation}%
+ \else\ifdim\lastskip=\delimitedtextsignal
+ \unskip
+ \hskip\hspaceamount\currentlanguage{interquotation}%
+ \else
+ #2%
+ \fi\fi
+ \strut % new, needed below
+ \ifhmode % else funny pagebeaks
+ \penalty\plustenthousand
+ \hskip\zeropoint % == \prewordbreak
+ \fi
+ \strut % new, needed below
+ \delimitedtextparameter#1% unhbox\scratchbox
+ \hskip\delimitedtextsignal % +- \prewordbreak
+ \fi
+ \endgroup}
+
+\def\dohandlerightdelimitedtext#1#2%
+ {\begingroup
+ \setbox\scratchbox\hbox{\delimitedtextparameter#1}%
+ \ifdim\wd\scratchbox>\zeropoint
+ \ifdim\lastkern=\delimitedtextsignal
+ \unkern
+ \penalty\plustenthousand
+ \hskip\hspaceamount\currentlanguage{interquotation}%
+ \else\ifdim\lastskip=\delimitedtextsignal
+ \unskip
+ \penalty\plustenthousand
+ \hskip\hspaceamount\currentlanguage{interquotation}%
+ \else
+ #2%
+ \fi\fi
+ \ifhmode % else funny pagebeaks
+ \penalty\plustenthousand
+ \hskip\zeropoint % == \prewordbreak
+ \fi
+ \strut % new, needed below
+ \delimitedtextparameter#1% unhbox\scratchbox
+ \kern\delimitedtextsignal % +- \prewordbreak
+ \fi
+ \endgroup}
+
+
+\def\ignoredelimitedtext#1%
+ {\delimitedtextparameter#1}
+
+\def\handledelimitedtext#1%
+ {\dohandledelimitedtext{#1}\relax}
+
+\def\handleleftdelimitedtext#1%
+ {\dohandleleftdelimitedtext{#1}\relax}
+
+\def\handlerightdelimitedtext#1%
+ {\dohandlerightdelimitedtext{#1}\relax}
+
+\unexpanded\def\dodelimitedtextpar
+ {\dohandleleftdelimitedtext\c!left\relax
+ \groupedcommand
+ \donothing
+ {\dohandlerightdelimitedtext\c!right\removelastskip
+ \popdelimitedtext}}
+
+\unexpanded\def\dodelimitedtexttxt
+ {\doifelse{\delimitedtextparameter\c!style}\v!normal
+ \doquoteddelimited\doattributeddelimited}
+
+\def\doquoteddelimited
+ {\dohandleleftdelimitedtext\c!left\relax
+ \groupedcommand
+ \donothing
+ {\dohandlerightdelimitedtext\c!right
+ \removelastskip
+ \popdelimitedtext}}
+
+\def\doattributeddelimited
+ {\groupedcommand
+ {\dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color}
+ {\dostopattributes
+ \popdelimitedtext}}
+
+\def\dofontdrivendelimited
+ {\simplegroupedcommand
+ {\languageparameter{\c!left\currentdelimitedtext}}
+ {\languageparameter{\c!right\currentdelimitedtext}%
+ \popdelimitedtext}}
+
+% testcase for nesting:
+%
+% \quotation{... \quotation{...} ...}
+% \startquotation ... \startquotation... \quotation{...} \stopquotation\space ...\stopquotation
+% \setupdelimitedtext[quotation][1][left=(,right=)]
+% \setupdelimitedtext[quotation][2][left={[},right={]}]
+% \setupdelimitedtext[quotation][3][left=\{,right=\}]
+% \quotation{... \quotation{...} ...}
+% \startquotation ... \startquotation... \quotation{...} \stopquotation\space ...\stopquotation
+
+\definedelimitedtext
+ [\v!quotation]
+ [\c!left={\symbol[\c!leftquotation]},
+ \c!right={\symbol[\c!rightquotation]},
+ \c!leftmargin=\v!standard]
+
+\definedelimitedtext
+ [\v!quote][\v!quotation]
+
+\setupdelimitedtext
+ [\v!quote]
+ [\c!location=\v!text,
+ \c!left={\symbol[\c!leftquote]},
+ \c!right={\symbol[\c!rightquote]}]
+
+\definedelimitedtext
+ [\v!blockquote][\v!quotation]
+
+\setupdelimitedtext
+ [\v!blockquote]
+ [\c!left=,
+ \c!right=]
+
+\definedelimitedtext
+ [\v!speech][\v!quotation]
+
+\setupdelimitedtext
+ [\v!speech]
+ [\c!repeat=\v!yes,
+ \c!left={\symbol[\c!leftspeech]},
+ \c!middle={\symbol[\c!middlespeech]},
+ \c!right={\symbol[\c!rightspeech]}]
+
+% how do we call an tight quote
+%
+% \definedelimitedtext
+% [\v!quotation][\v!quotation]
+%
+% \setupdelimitedtext
+% [\v!quotation]
+% [\c!indentnext=\v!no,
+% \c!spacebefore=\v!nowhite]
+
+\def\setupquotation{\setupdelimitedtext[\v!quotation]}
+\def\setupquote {\setupdelimitedtext[\v!quote]}
+
+% seldom used, move from kernel to run time module
+
+\ifx\tfx\undefined \let\tfx\relax \fi
+
+\def\basegrid
+ {\dosingleempty\dobasegrid}
+
+\def\dobasegrid[#1]%
+ {\begingroup
+ \getparameters[\??rt]
+ [\c!x=0,\c!y=0,
+ \c!nx=10,\c!ny=10,
+ \c!dx=.5,\c!dy=.5,
+ \c!xstep=0,\c!ystep=0,
+ \c!unit=\s!cm,
+ \c!scale=1,
+ \c!factor=1,
+ \c!offset=\v!yes,
+ \c!location=\v!left,
+ #1]%
+ \startpositioning
+ \dimen0=\@@rtdx\@@rtunit\relax
+ \dimen0=\@@rtscale\dimen0\relax
+ \dimen0=\@@rtfactor\dimen0\relax
+ \multiply\dimen0 \@@rtnx\relax
+ \dimen2=\@@rtdy\@@rtunit\relax
+ \dimen2=\@@rtscale\dimen2\relax
+ \dimen2=\@@rtfactor\dimen2\relax
+ \multiply\dimen2 \@@rtny\relax
+ \def\horline
+ {\vbox
+ {\hrule
+ \!!width \dimen0
+ \!!height \linewidth
+ \!!depth \!!zeropoint}}%
+ \def\verline%
+ {\vrule
+ \!!width \linewidth
+ \!!height \dimen2
+ \!!depth \!!zeropoint}%
+ \doglobal\newcounter\@@gridc
+ \doglobal\newcounter\@@gridd
+ \doglobal\newcounter\@@gride
+ \def\setlegend##1##2##3%
+ {\gdef\@@gridc{0}%
+ \dimen0=2em\relax
+ \dimen2=##2\@@rtunit\relax
+ \dimen2=\@@rtscale\dimen2\relax
+ \dimen2=\@@rtfactor\dimen2\relax
+ \divide\dimen0 \dimen2\relax
+ \xdef\@@gride{\number\dimen0}%
+ \ifnum\@@gride>50
+ \gdef\@@gride{100}%
+ \else\ifnum\@@gride>10
+ \gdef\@@gride{50}%
+ \else\ifnum\@@gride>5
+ \gdef\@@gride{10}%
+ \else\ifnum\@@gride>1
+ \gdef\@@gride{5}%
+ \else
+ \gdef\@@gride{1}%
+ \fi\fi\fi\fi
+ \gdef\@@gridd{0}%
+ \def\legend
+ {\ifnum\@@gridd=\zerocount
+ \vbox
+ {\increment(\@@gridc,##1)%
+ \hbox to 2em{\hss\@@gridc\hss}}%
+ \global\let\@@gridd=\@@gride
+ \fi
+ \doglobal\decrement\@@gridd
+ \doglobal\increment(\@@gridc,##1)}}%
+ \def\draw##1##2##3##4##5##6##7##8##9%
+ {\setuppositioning
+ [\c!state=##8,
+ \c!xstep=\v!absolute,
+ \c!ystep=\v!absolute,
+ \c!unit=\@@rtunit,
+ \c!scale=\@@rtscale,
+ \c!factor=\@@rtfactor,
+ \c!offset=\@@rtoffset,
+ \c!xoffset=##6,
+ \c!yoffset=##7]%
+ \doifelse{##9}\v!middle
+ {\scratchdimen##3pt\scratchdimen.5\scratchdimen
+ \edef\@@psxx{\withoutpt\the\scratchdimen}%
+ \scratchdimen##4pt\scratchdimen.5\scratchdimen
+ \edef\@@psyy{\withoutpt\the\scratchdimen}%
+ \scratchcounter##2\advance\scratchcounter -1
+ \edef\@@pszz{\the\scratchcounter}}
+ {\edef\@@psxx{0}\edef\@@psyy{0}\edef\@@pszz{##2}}%
+ \position(\@@psxx,\@@psyy){##1}%
+ \setuppositioning
+ [\c!state=##8,
+ \c!xstep=\v!relative,
+ \c!ystep=\v!relative,
+ \c!scale=\@@rtscale,
+ \c!factor=\@@rtfactor,
+ \c!offset=\@@rtoffset,
+ \c!unit=\@@rtunit]%
+ \dorecurse\@@pszz{\position(##3,##4){##5}}}%
+ \draw
+ \verline\@@rtnx\@@rtdx0\verline\!!zeropoint\!!zeropoint\v!start\empty
+ \draw
+ \horline\@@rtny0\@@rtdy\horline\!!zeropoint\!!zeropoint\v!start\empty
+ \tfx
+ \doifnot\@@rtxstep{0}
+ {\setlegend\@@rtxstep\@@rtdx\@@rtx
+ \draw\legend\@@rtnx\@@rtdx0\legend{-1em}{-1.5em}\v!overlay\@@rtlocation}%
+ \doifnot\@@rtystep{0}
+ {\setlegend\@@rtystep\@@rtdy\@@rty
+ \draw\legend\@@rtny0\@@rtdy\legend{-2em}{-.75ex}\v!overlay\@@rtlocation}%
+ \stoppositioning
+ \endgroup}
+
+\let\grid\basegrid
+
+% only used at pragma, move from kernel to run time module
+
+\def\referraldate
+ {\currentdate[\v!referral]}
+
+\def\doreferral[#1]%
+ {\noheaderandfooterlines
+ \bgroup
+ \getparameters
+ [\??km]
+ [\c!bet=\unknown,\c!dat=\unknown,\c!ken=\unknown,
+ \c!from=,\c!to=,\c!ref=,#1]%
+ % moet anders, hoort niet in 01b
+ \assigntranslation[\s!nl=referentie,\s!en=reference,\s!de=Referenz,\s!sp=referencia]\to\@@@kmref
+ \assigntranslation[\s!nl=van,\s!en=from,\s!de=Von,\s!sp=de]\to\@@@kmvan
+ \assigntranslation[\s!nl=aan,\s!en=to,\s!de=An,\s!sp=a]\to\@@@kmaan
+ \assigntranslation[\s!nl=betreft,\s!en=concerns,\s!de=Betreff,\s!sp=]\to\@@@kmbet
+ \assigntranslation[\s!nl=datum,\s!en=date,\s!de=Datum,\s!sp=fecha]\to\@@@kmdat
+ \assigntranslation[\s!nl=kenmerk,\s!en=mark,\s!de=Kennzeichen,\s!sp=]\to\@@@kmken
+ %
+ \definetabulate[\s!dummy][|l|p|]
+ \startdummy
+ \NC\@@@kmbet\EQ\@@kmbet\NC\NR
+ \NC\@@@kmdat\EQ\@@kmdat\NC\NR
+ \NC\@@@kmken\EQ\expanded{\smallcapped{\@@kmken}}\NC\NR
+ \doifsomething{\@@kmfrom\@@kmto}{\NC\NC\NC\NR}%
+ \doifsomething \@@kmfrom {\NC\@@@kmvan\EQ\@@kmfrom\NC\NR}%
+ \doifsomething \@@kmto {\NC\@@@kmaan\EQ\@@kmto\NC\NR}%
+ \doifsomething \@@kmref {\NC\NC\NC\NR\NC\@@@kmref\EQ\@@kmref\NC\NR}%
+ \stopdummy
+ \egroup}
+
+\def\referral
+ {\dosingleargument\doreferral}
+
+% FUZZY OLD STUFF: will be removed when not used in some manual;
+% rows instead of columns, i'd forgotten that this code exist
+%
+% \definesystemvariable{ri}
+%
+% \def\setuprows
+% {\dodoubleargument\getparameters[\??ri]}
+%
+% \definecomplexorsimpleempty\startrows
+%
+% \def\complexstartrows[#1]%
+% {\bgroup
+% \setuprows[#1]%
+% \let\do@@ribottom\relax
+% \def\row
+% {\do@@ribottom
+% \egroup
+% \dimen0\vsize
+% \divide\dimen0 \@@rin
+% \advance\dimen0 -\lineskip
+% \vbox to \dimen0
+% \bgroup
+% \@@ritop
+% \let\do@@ribottom\@@ribottom
+% \ignorespaces}%
+% \bgroup
+% \row}
+%
+% \def\stoprows
+% {\do@@ribottom
+% \egroup
+% \egroup}
+%
+% \setuprows
+% [\c!n=2,
+% \c!top=,
+% \c!bottom=\vfill]
+
+% THIS WAS MAIN-003.TEX
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+\definetabulate
+ [\v!legend]
+ [|emj1|i1|mR|]
+
+\setuptabulate
+ [\v!legend]
+ [\c!unit=.75em,\c!inner=\setquicktabulate\leg,EQ={=}]
+
+\definetabulate
+ [\v!legend][\v!two]
+ [|emj1|emk1|i1|mR|]
+
+\definetabulate
+ [\v!fact]
+ [|R|ecmj1|i1mR|]
+
+\setuptabulate
+ [\v!fact]
+ [\c!unit=.75em,\c!inner=\setquicktabulate\fact,EQ={=}]
+
+\unexpanded\def\xbox
+ {\bgroup\aftergroup\egroup\hbox\bgroup\tx\let\next=}
+
+\unexpanded\def\xxbox
+ {\bgroup\aftergroup\egroup\hbox\bgroup\txx\let\next=}
+
+% \def\mrm#1%
+% {$\rm#1$}
+
+%D \macros
+%D {definepairedbox, setuppairedbox, placepairedbox}
+%D
+%D Paired boxes, formally called legends, but from now on a
+%D legend is just an instance, are primarily meant for
+%D typesetting some text alongside an illustration. Although
+%D there is quite some variation possible, the functionality is
+%D kept simple, if only because in most cases such pairs are
+%D typeset sober.
+%D
+%D The location specification accepts a pair, where the first
+%D keyword specifies the arrangement, and the second one the
+%D alignment. The first key of the location pair is one of
+%D \type {left}, \type {right}, \type {top} or \type {bottom},
+%D while the second key can also be \type {middle}.
+%D
+%D The first box is just collected in an horizontal box, but
+%D the second one is a vertical box that gets passed the
+%D bodyfont and alignment settings.
+
+%D Today we would implement this using layers .... but for the
+%D moment we keep it this way.
+
+% \startbuffer[test]
+% \test left \test left,top \test left,bottom \test left,middle
+% \test right \test right,top \test right,bottom \test right,middle
+% \test top \test top,left \test top,right \test top,middle
+% \test bottom \test bottom,left \test bottom,right \test bottom,middle
+% \stopbuffer
+%
+% \def\showtest#1%
+% {\pagina
+% \typebuffer[demo]
+% \def\test##1
+% {\startlinecorrection[blank]
+% \getbuffer[demo]%
+% \ruledhbox\placelegend
+% [bodyfont=6pt,location={##1}]
+% {\framed[width=.25\textwidth]{\tttf##1}}
+% {#1}
+% \stoplinecorrection}
+% \getbuffer[test]}
+%
+% \startbuffer[demo]
+% \setuplegend
+% [width=\hsize,maxwidth=\makeupwidth,
+% height=\vsize,maxheight=\makeupheight]
+% \stopbuffer
+%
+% \showtest{These examples demonstrate the default settings.}
+%
+% \startbuffer[demo]
+% \setuplegend
+% [width=\textwidth,
+% maxwidth=\textwidth]
+% \stopbuffer
+%
+% \showtest{\input tufte }
+%
+% \startbuffer[demo]
+% \setuplegend
+% [width=.65\textwidth]
+% \stopbuffer
+%
+% \showtest{\input knuth }
+%
+% \startbuffer[demo]
+% \setuplegend
+% [height=2cm]
+% \stopbuffer
+%
+% \showtest{These examples demonstrate some other settings.}
+%
+% \startbuffer[demo]
+% \setuplegend
+% [width=.65\textwidth,
+% height=2cm]
+% \stopbuffer
+%
+% \showtest{These examples demonstrate some other settings.}
+%
+% \startbuffer[demo]
+% \setuplegend
+% [n=2,align=right,width=.5\textwidth]
+% \stopbuffer
+%
+% \showtest{\input zapf }
+
+%D \macros
+%D {setuplegend, placelegend}
+%D
+%D It makes sense to typeset a legend to a figure in \TEX\
+%D and not in a drawing package. The macro \type {\placelegend}
+%D combines a figure (or something else) and its legend. This
+%D command is just a paired box.
+%D
+%D The legend is placed according to \type {location}, being
+%D \type {bottom} or \type {right}. The macro macro is used as
+%D follows.
+%D
+%D \starttyping
+%D \placefigure
+%D {whow}
+%D {\placelegend
+%D {\externalfigure[cow]}
+%D {\starttabulation
+%D \NC 1 \NC head \NC \NR
+%D \NC 2 \NC legs \NC \NR
+%D \NC 3 \NC tail \NC \NR
+%D \stoptabulation}}
+%D
+%D \placefigure
+%D {whow}
+%D {\placelegend
+%D {\externalfigure[cow]}
+%D {\starttabulation[|l|l|l|l|]
+%D \NC 1 \NC head \NC 3 \NC tail \NC \NR
+%D \NC 2 \NC legs \NC \NC \NC \NR
+%D \stoptabulation}}
+%D
+%D \placefigure
+%D {whow}
+%D {\placelegend[n=2]
+%D {\externalfigure[cow]}
+%D {\starttabulation
+%D \NC 1 \NC head \NC \NR
+%D \NC 2 \NC legs \NC \NR
+%D \NC 3 \NC tail \NC \NR
+%D \stoptabulation}}
+%D
+%D \placefigure
+%D {whow}
+%D {\placelegend[n=2]
+%D {\externalfigure[cow]}
+%D {head \par legs \par tail}}
+%D
+%D \placefigure
+%D {whow}
+%D {\placelegend[n=2]
+%D {\externalfigure[cow]}
+%D {\startitemize[packed]
+%D \item head \item legs \item tail \item belly \item horns
+%D \stopitemize}}
+%D
+%D \placefigure
+%D {whow}
+%D {\placelegend[n=2,width=.8\hsize]
+%D {\externalfigure[cow]}
+%D {\startitemize[packed]
+%D \item head \item legs \item tail \item belly \item horns
+%D \stopitemize}}
+%D \stoptyping
+
+\newbox\firstpairedbox
+\newbox\secondpairedbox
+
+\def\definepairedbox
+ {\dodoubleempty\dodefinepairedbox}
+
+\def\dodefinepairedbox[#1][#2]%
+ {\getparameters
+ [\??ld#1]
+ [\c!n=1,
+ \c!distance=\bodyfontsize,
+ \c!before=,
+ \c!after=,
+ \c!color=,
+ \c!style=,
+ \c!inbetween={\blank[\v!medium]},
+ \c!width=\hsize,
+ \c!height=\vsize,
+ \c!maxwidth=\textwidth, % \makeupwidth,
+ \c!maxheight=\textheight, % \makeupheight,
+ \c!bodyfont=,
+ \c!align=,
+ \c!location=\v!bottom,
+ #2]%
+ \setvalue{\e!setup#1\e!endsetup}{\setuppairedbox[#1]}%
+ \setvalue{\e!place#1}{\placepairedbox[#1]}}
+
+\def\setuppairedbox
+ {\dodoubleempty\dosetuppairedbox}
+
+\def\dosetuppairedbox[#1]%
+ {\getparameters[\??ld#1]}
+
+\def\placepairedbox
+ {\bgroup\dodoubleempty\doplacepairedbox}
+
+\def\doplacepairedbox[#1][#2]% watch the hsize/vsize tricks
+ {\setuppairedbox[#1][#2]% % and don't change them
+ \copyparameters % brrr
+ [\??ld][\??ld#1]
+ [\c!n,\c!distance,\c!inbetween,\c!before,\c!after,
+ \c!width,\c!height,\c!maxwidth,\c!maxheight,
+ \c!color,\c!style,\c!bodyfont,\c!align,\c!location]%
+ \@@ldbefore\bgroup
+ \global\setsystemmode{pairedbox}%
+ \beforefirstpairedbox
+ \dowithnextbox
+ {\betweenbothpairedboxes
+ \dowithnextbox
+ {\afterbothpairedboxes
+ \egroup\@@ldafter
+ \egroup}
+ \vbox\bgroup
+ \insidesecondpairedbox
+ \let\next=}
+ \hbox}
+
+\def\beforefirstpairedbox
+ {\chardef\pairedlocationa1 % left
+ \chardef\pairedlocationb4 % middle
+ \getfromcommacommand[\@@ldlocation][1]%
+ \processaction
+ [\commalistelement]
+ [ \v!left=>\chardef\pairedlocationa0,
+ \v!right=>\chardef\pairedlocationa1,
+ \v!top=>\chardef\pairedlocationa2,
+ \v!bottom=>\chardef\pairedlocationa3]%
+ \getfromcommacommand[\@@ldlocation][2]%
+ \processaction
+ [\commalistelement]
+ [ \v!left=>\chardef\pairedlocationb0,
+ \v!right=>\chardef\pairedlocationb1,
+ \v!high=>\chardef\pairedlocationb2,
+ \v!top=>\chardef\pairedlocationb2,
+ \v!low=>\chardef\pairedlocationb3,
+ \v!bottom=>\chardef\pairedlocationb3,
+ \v!middle=>\chardef\pairedlocationb4]}
+
+\def\betweenbothpairedboxes
+ {\switchtobodyfont[\@@ldbodyfont]% split under same regime
+ \setbox\firstpairedbox\flushnextbox
+ \ifnum\pairedlocationa<2
+ \hsize\wd\firstpairedbox % trick
+ \hsize\@@ldwidth
+ \scratchdimen\wd\firstpairedbox
+ \advance\scratchdimen \@@lddistance
+ \bgroup\advance\scratchdimen \hsize
+ \ifdim\scratchdimen>\@@ldmaxwidth\relax
+ \egroup
+ \hsize\@@ldmaxwidth
+ \advance\hsize -\scratchdimen
+ \else
+ \egroup
+ \fi
+ \else
+ \hsize\wd\firstpairedbox
+ \hsize\@@ldwidth % can be \hsize
+ \ifdim\hsize>\@@ldmaxwidth\relax \hsize\@@ldmaxwidth \fi % can be \hsize
+ \fi
+ \ifnum\@@ldn>\plusone
+ \setrigidcolumnhsize\hsize\@@lddistance\@@ldn
+ \fi}
+
+\def\afterbothpairedboxes
+ {\setbox\secondpairedbox\vbox
+ {% \localstartcolor[\@@ldcolor]% does not work yet
+ \ifnum\@@ldn>1
+ \rigidcolumnbalance\nextbox
+ \else
+ \flushnextbox
+ \fi
+ }% \localstopcolor}%
+ \ifnum\pairedlocationa<2\hbox\else\vbox\fi\bgroup % hide vsize
+ \forgetall
+ \ifnum\pairedlocationa<2
+ \scratchdimen\maxoftwoboxdimens\ht\firstpairedbox\secondpairedbox
+ \vsize\scratchdimen
+ \ifdim\scratchdimen<\@@ldheight\relax % can be \vsize
+ \scratchdimen\@@ldheight
+ \fi
+ \ifdim\scratchdimen>\@@ldmaxheight\relax
+ \scratchdimen\@@ldmaxheight
+ \fi
+ \valignpairedbox\firstpairedbox \scratchdimen
+ \valignpairedbox\secondpairedbox\scratchdimen
+ \else
+ \scratchdimen\maxoftwoboxdimens\wd\firstpairedbox\secondpairedbox
+ \halignpairedbox\firstpairedbox \scratchdimen
+ \halignpairedbox\secondpairedbox\scratchdimen
+ \scratchdimen\ht\secondpairedbox
+ \vsize\scratchdimen
+ \ifdim\ht\secondpairedbox<\@@ldheight\relax % can be \vsize
+ \scratchdimen\@@ldheight\relax % \relax needed
+ \fi
+ \ifdim\scratchdimen>\@@ldmaxheight\relax % todo: totale hoogte
+ \scratchdimen\@@ldmaxheight\relax % \relax needed
+ \fi
+ \ifdim\scratchdimen>\ht\secondpairedbox
+ \setbox\secondpairedbox\vbox to \scratchdimen
+ {\ifnum\pairedlocationa=3 \vss\fi %
+ \box\secondpairedbox
+ \ifnum\pairedlocationa=2 \vss\fi}% \kern\zeropoint
+ \fi
+ \fi
+ \ifcase\pairedlocationa
+ \box\secondpairedbox\hskip\@@lddistance\box\firstpairedbox \or
+ \box\firstpairedbox \hskip\@@lddistance\box\secondpairedbox\or
+ \box\secondpairedbox\endgraf \nointerlineskip \@@ldinbetween \box\firstpairedbox \or
+ \box\firstpairedbox \endgraf \nointerlineskip \@@ldinbetween \box\secondpairedbox\else
+ \fi
+ \egroup}
+
+\def\insidesecondpairedbox
+ {\forgetall
+ \setupalign[\@@ldalign]%
+ \tolerantTABLEbreaktrue % hm.
+ \blank[\v!disable]%
+ \everypar{\begstrut}}
+
+\def\maxoftwoboxdimens#1#2#3%
+ {#1\ifdim#1#2>#1#3 #2\else#3\fi}
+
+\def\valignpairedbox#1#2%
+ {\setbox#1\vbox to #2
+ {\ifcase\pairedlocationb\or\or\or\vss\or\vss\fi
+ \box#1\relax
+ \ifcase\pairedlocationb\or\or\vss\or\or\vss\fi}}
+
+\def\halignpairedbox#1#2%
+ {\setbox#1\hbox to #2
+ {\ifcase\pairedlocationb\or\hss\or\or\or\hss\fi
+ \box#1\relax
+ \ifcase\pairedlocationb\hss\or\or\or\or\hss\fi}}
+
+\definepairedbox[\v!legend]
+
+%D Goody:
+
+\appendtoks
+ \global\resetsystemmode{combination}%
+ \global\resetsystemmode{pairedbox}%
+\to \everyinsidefloat
+
+% todo: \startcombination \startcomb \stopcomb ...
+
+\newcount\horcombination % counter
+\newcount\totcombination
+
+\def\definecombination
+ {\dodoubleempty\dodefinecombination}
+
+\def\dodefinecombination[#1][#2]%
+ {\copyparameters
+ [\??co#1][\??co]
+ [\c!width,\c!height,\c!distance,\c!location,%
+ \c!before,\c!inbetween,\c!after,\c!align,%
+ \c!style,\c!color]%
+ \getparameters
+ [\??co#1][#2]}
+
+\def\setupcombinations
+ {\dodoubleempty\dosetupcombinations}
+
+\def\dosetupcombinations[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??co#1][#2]%
+ \else
+ \getparameters[\??co][#1]%
+ \fi}
+
+\def\combinationparameter#1%
+ {\csname\??co\currentcombination#1\endcsname}%
+
+\def\startcombination
+ {\bgroup % so we can grab a group
+ \dodoubleempty\dostartcombination}
+
+% \startcombination {alpha} {a} {beta} {b} \stopcombination
+% \startcombination[2*1] {alpha} {a} {beta} {b} \stopcombination
+% \startcombination[1*2] {alpha} {a} {beta} {b} \stopcombination
+% \startcombination[2] {alpha} {a} {beta} {b} \stopcombination
+
+\def\dostartcombination[#1][#2]%
+ {\global\setsystemmode{combination}%
+ \doifnothing{#1}\firstargumentfalse % to be sure (when called in macros)
+ \doifnothing{#2}\secondargumentfalse % to be sure (when called in macros)
+ \ifsecondargument
+ \def\currentcombination{#1}%
+ \edef\currentcombinationspec{#2*1*}%
+ \else % better : \doifcombinationelse ... \??co#1\c!location
+ \doifinstringelse{*}{#1}
+ {\let\currentcombination\empty
+ \edef\currentcombinationspec{#1*1*}}
+ {\doifnumberelse{#1}
+ {\let\currentcombination\empty
+ \edef\currentcombinationspec{#1*1*}}
+ {\def\currentcombination{#1}%
+ \edef\currentcombinationspec{2*1*}}}%
+ \fi
+ \forgetall
+ \doifelse{\combinationparameter\c!height}\v!fit
+ \vbox {\vbox to \combinationparameter\c!height}%
+ \bgroup
+ \expanded{\dodostartcombination[\currentcombinationspec]}}
+
+\long\def\dodostartcombination[#1*#2*#3]%
+ {\setuphorizontaldivision
+ [\c!n=\v!fit,\c!distance=\combinationparameter\c!distance]%
+ \global\horcombination#1%
+ \global\totcombination#2%
+ \global\setbox\combinationstack\emptybox
+ \xdef\maxhorcombination{\the\horcombination}%
+ \multiply\totcombination\horcombination
+ \tabskip\zeropoint
+ \doifelse{\combinationparameter\c!width}\v!fit
+ {\halign}{\halign to \combinationparameter\c!width}%
+ \bgroup&%
+ %\hfil##\hfil% now : location={left,top}
+ \expanded{\doifnotinset{\v!left}{\combinationparameter\c!location}}\hfil
+ ##%
+ \expanded{\doifnotinset{\v!right}{\combinationparameter\c!location}}\hfil
+ &\tabskip\zeropoint \!!plus 1fill##\cr
+ \docombination}
+
+\def\docombination % we want to add struts but still ignore an empty box
+ {\dowithnextbox
+ {\setbox0\flushnextbox
+ \dowithnextbox
+ {\setbox2\flushnextbox
+ \dodocombination}%
+ \vtop\bgroup
+ \def\next
+ {\futurelet\nexttoken\nextnext}%
+ \def\nextnext
+ {\ifx\nexttoken\egroup \else % the next box is empty
+ \hsize\wd0
+ \setupalign[\combinationparameter\c!align]%
+ \dostartattributes{\??co\currentcombination}\c!style\c!color\empty
+ \bgroup
+ \aftergroup\endstrut
+ \aftergroup\dostopattributes
+ \aftergroup\egroup
+ \begstrut
+ \fi}%
+ \afterassignment\next\let\nexttoken=}
+ \hbox}
+
+% stupid version, does not align top stuff when captions,
+% keep as example
+%
+% \def\dodocombination
+% {\vbox
+% {\forgetall % \setupwhitespace[\v!none]%
+% \let\next\vbox
+% \ExpandFirstAfter\processallactionsinset
+% [\combinationparameter\c!location]
+% [ \v!top=>\let\next\tbox,
+% \v!middle=>\let\next\halfwaybox]%
+% \next{\copy0}%
+% \ifdim\ht2>\zeropoint % beter dan \wd2, nu \strut mogelijk
+% \combinationparameter\c!inbetween
+% %\vtop % wrong code
+% % {\nointerlineskip % recently added
+% % \hsize\wd0
+% % \setupalign[\combinationparameter\c!align]% % \raggedcenter
+% % \begstrut\unhbox2\endstrut}%
+% \box2
+% \fi}%
+% \ifnum\totcombination>\plusone
+% \global\advance\totcombination\minusone
+% \global\advance\horcombination\minusone
+% \ifnum\horcombination=\zerocount
+% \def\next
+% {\cr\noalign
+% {\forgetall % \setupwhitespace[\v!geen]% no
+% \nointerlineskip
+% \combinationparameter\c!before
+% \combinationparameter\c!after
+% \vss
+% \nointerlineskip}%
+% \global\horcombination\maxhorcombination\relax
+% \docombination}%
+% \else
+% \def\next
+% {&&&\hskip\combinationparameter\c!distance&\docombination}%
+% \fi
+% \else
+% \def\next
+% {\cr\egroup}%
+% \fi
+% \next}
+
+% \def\dodocombination
+% {\vbox
+% {\forgetall % \setupwhitespace[\v!none]%
+% \let\next\vbox
+% \ExpandFirstAfter\processallactionsinset
+% [\combinationparameter\c!plaats]
+% [ \v!top=>\let\next\tbox,
+% \v!middle=>\let\next\halfwaybox]%
+% \next{\copy0}%
+% % we need to save the caption for a next alignment line
+% \saveoncombinationstack2}%
+% \ifnum\totcombination>\plusone
+% \global\advance\totcombination\minusone
+% \global\advance\horcombination\minusone
+% \ifnum\horcombination=\zerocount
+% \def\next
+% {\cr
+% \flushcombinationstack
+% \noalign
+% {\forgetall % \setupwhitespace[\v!none]% no
+% \global\setbox\combinationstack\emptybox
+% \nointerlineskip
+% \combinationparameter\c!after
+% \combinationparameter\c!before
+% \vss
+% \nointerlineskip}%
+% \global\horcombination\maxhorcombination\relax
+% \docombination}%
+% \else
+% \def\next
+% {&&&\hskip\combinationparameter\c!distance&\docombination}%
+% \fi
+% \else
+% \def\next
+% {\cr
+% \flushcombinationstack
+% \egroup}%
+% \fi
+% \next}
+
+\def\depthonlybox
+ {\dowithnextbox{\vtop{\hsize\wd\nextbox\kern\zeropoint\box\nextbox}}\vbox}
+
+% \def\boxwithstrutheight
+% {\dowithnextbox
+% {\scratchdimen\strutheight
+% \advance\scratchdimen-\nextboxht
+% \hbox{\raise\scratchdimen\box\nextbox}}%
+% \vbox}
+
+\def\dodocombination
+ {\vbox
+ {\forgetall % \setupwhitespace[\v!none]%
+ \let\next\vbox
+ \expanded{\processallactionsinset[\combinationparameter\c!location]}
+ [ \v!top=>\let\next\depthonlybox, % \tbox,
+ \v!middle=>\let\next\halfwaybox]%
+ \next{\copy0}%
+ % we need to save the caption for a next alignment line
+ \saveoncombinationstack2}%
+ \ifnum\totcombination>\plusone
+ \global\advance\totcombination\minusone
+ \global\advance\horcombination\minusone
+ \ifnum\horcombination=\zerocount
+ \def\next
+ {\cr
+ \flushcombinationstack
+ \noalign
+ {\forgetall % \setupwhitespace[\v!none]% no
+ \global\setbox\combinationstack\emptybox
+ \nointerlineskip
+ \combinationparameter\c!after
+ \combinationparameter\c!before
+ \vss
+ \nointerlineskip}%
+ \global\horcombination\maxhorcombination\relax
+ \docombination}%
+ \else
+ \def\next
+ {&&&\hskip\combinationparameter\c!distance&\docombination}%
+ \fi
+ \else
+ \def\next
+ {\cr
+ \flushcombinationstack
+ \egroup}%
+ \fi
+ \next}
+
+% formally ok:
+%
+% \def\stopcombination
+% {\egroup
+% \egroup}
+%
+% more robust:
+%
+% \def\stopcombination
+% {{}{}{}{}{}{}{}{}% catches (at most 4) missing entries
+% \egroup
+% \egroup}
+%
+% even better:
+
+\def\stopcombination
+ {{\scratchtoks{{}{}{}}\dorecurse\totcombination{\appendtoks{}{}{}{}\to\scratchtoks}\expandafter}\the\scratchtoks
+ \egroup
+ \egroup}
+
+\newbox\combinationstack
+
+\def\saveoncombinationstack#1%
+ {\global\setbox\combinationstack\hbox
+ {\hbox{\box#1}\unhbox\combinationstack}}
+
+\def\flushcombinationstack
+ {\noalign
+ {\ifdim\ht\combinationstack>\zeropoint
+\nointerlineskip % nieuw
+ \combinationparameter\c!inbetween
+ \global\horcombination\maxhorcombination
+ \globallet\doflushcombinationstack\dodoflushcombinationstack
+ \else
+ \global\setbox\combinationstack\emptybox
+ \globallet\doflushcombinationstack\donothing
+ \fi}%
+ \doflushcombinationstack\crcr}
+
+\gdef\dodoflushcombinationstack
+ {\global\setbox\combinationstack\hbox
+ {\unhbox\combinationstack
+ \global\setbox1\lastbox}%
+ \box1% \ruledhbox{\box1}%
+ \global\advance\horcombination\minusone\relax
+ \ifnum\horcombination>\zerocount
+ \def\next{&&&&\doflushcombinationstack}%
+ \else
+ \global\setbox\combinationstack\emptybox
+ %\let\next\relax
+ \@EA\gobbleoneargument
+ \fi
+ \next}
+
+\setupcombinations
+ [\c!width=\v!fit,
+ \c!height=\v!fit,
+ \c!distance=1em,
+ \c!location=\v!bottom, % can be something {top,left}
+ \c!before=\blank,
+ \c!inbetween={\blank[\v!medium]},
+ \c!style=,
+ \c!color=,
+ \c!after=,
+ \c!align=\v!middle]
+
+%D \macros
+%D {startfloatcombination}
+%D
+%D \setupexternalfigures[directory={../sample}]
+%D \startbuffer
+%D \placefigure
+%D [left,none]
+%D {}
+%D {\startfloatcombination[2*2]
+%D \placefigure{alpha}{\externalfigure[cow.pdf][width=1cm]}
+%D \placefigure{beta} {\externalfigure[cow.pdf][width=2cm]}
+%D \placefigure{gamma}{\externalfigure[cow.pdf][width=3cm]}
+%D \placefigure{delta}{\externalfigure[cow.pdf][width=4cm]}
+%D \stopfloatcombination}
+%D
+%D \input tufte
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\startfloatcombination
+ {\dodoubleempty\dostartfloatcombination}
+
+\def\dostartfloatcombination[#1][#2]%
+ {\vbox\bgroup
+ %\insidecolumnstrue % trick, forces no centering, todo: proper switch/feature
+ \chardef\postcenterfloatmethod\zerocount
+ \forcelocalfloats
+ \def\stopfloatcombination
+ {\scratchtoks\emptytoks
+ \dorecurse\noflocalfloats
+ {\appendetoks{\noexpand\getlocalfloat{\recurselevel}}{}\to\scratchtoks}%
+ \expanded{\startcombination[#1]\the\scratchtoks}\stopcombination
+ \resetlocalfloats
+ \egroup}}
+
+\def\placerelativetoeachother#1#2%
+ {\bgroup
+ \dowithnextbox
+ {\bgroup
+ \setbox0\box\nextbox
+ \dowithnextbox
+ {\setbox2\box\nextbox
+ #1{#2#########2\cr\box0\cr\box2\cr}
+ \egroup
+ \egroup}
+ \hbox}
+ \hbox}
+
+\def\placeontopofeachother{\placerelativetoeachother\halign\hss}
+\def\placesidebyside {\placerelativetoeachother\valign\vss}
+
+% this will be replaced or go away, never used
+
+\def\douseexternalfiles[#1][#2]%
+ {\getparameters
+ [\??fi#1]
+ [\c!file=,
+ \c!bodyfont=,
+ \c!option=,
+ #2]}
+
+\def\useexternalfiles
+ {\dodoubleargument\douseexternalfiles}
+
+\def\dostelexternefilesin[#1][#2]%
+ {\doifundefinedelse{\??fi#1\c!file}
+ {\useexternalfiles[#1][#2]}
+ {\getparameters[\??fi#1][#2]}}
+
+\def\stelexternefilesin
+ {\dodoubleargument\dostelexternefilesin}
+
+\def\verwerkexternefile#1#2#3%
+ {\bgroup
+ \getparameters[\??fi#1][\c!file=,#3]%
+ \doinputonce{\getvalue{\??fi#1\c!file}}%
+ \ExpandFirstAfter\switchtobodyfont[\getvalue{\??fi#1\c!bodyfont}]%
+ \readsysfile{#2} % beter: loc of fix gebied
+ \donothing
+ {\showmessage\m!systems{41}{#2,#1}}%
+ \egroup}
+
+\def\douseexternalfile[#1][#2][#3][#4]%
+ {\stelexternefilesin[#1][]%
+ \doinputonce{\getvalue{\??fi#1\c!file}}%
+ \doifelsenothing{#2}
+ {\setvalue{#3}{\verwerkexternefile{#1}{#3}{#4}}}
+ {\setvalue{#2}{\verwerkexternefile{#1}{#3}{#4}}}}
+
+\def\useexternalfile
+ {\doquadrupleargument\douseexternalfile}
+
+\useexternalfiles
+ [pictex]
+ [\c!bodyfont=\v!small,
+ \c!file=pictex]
+
+\useexternalfiles
+ [table]
+ [\c!file=table]
+
+%D A couple of examples, demonstrating how the depth is
+%D taken care of:
+%D
+%D \startbuffer
+%D test\rotate[frame=on, rotation=0] {gans}%
+%D test\rotate[frame=on, rotation=90] {gans}%
+%D test\rotate[frame=on, rotation=180]{gans}%
+%D test\rotate[frame=on, rotation=270]{gans}%
+%D test
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+% When we rotate over arbitrary angles, we need to relocate the
+% resulting box because rotation brings that box onto the negative
+% axis. The calculations (mostly sin and cosine) need to be tuned for
+% the way a box is packages (i.e. the refence point). A typical example
+% of drawing, scribbling, and going back to the days of school math.
+%
+% We do a bit more calculations than needed, simply because that way
+% it's easier to debug the code.
+
+\def\dododorotatenextbox
+ {\setbox\nextbox\vbox to \@@layerysiz
+ {\vfill
+ \hbox to \@@layerxsiz
+ {\dostartrotation\@@rorotation
+ \nextboxwd\zeropoint
+ \nextboxht\zeropoint
+ \flushnextbox
+ \dostoprotation
+ \hfill}%
+ \kern\@@layerypos}%
+ \setbox\nextbox\hbox
+ {\kern\@@layerxpos
+ \kern\@@layerxoff
+ \lower\@@layeryoff\flushnextbox}}
+
+\def\dodorotatenextbox#1#2% quite some trial and error -)
+ {\dontshowcomposition
+ \dontcomplain
+ \ifnum#2=\plusfour
+ % new, location=middle
+ \!!widthb \nextboxwd
+ \!!heightb\nextboxht
+ \!!depthb \nextboxdp
+ \setbox\nextbox\vbox{\vskip.5\nextboxht\hskip-.5\nextboxwd\flushnextbox}%
+ \smashbox\nextbox
+ \fi
+ \!!widtha \nextboxwd
+ \!!heighta\nextboxht
+ \!!deptha \nextboxdp
+ \!!doneafalse
+ \!!donebfalse
+ \ifcase#2\or
+ % 1: fit
+ \or
+ % 2: depth, not fit
+ \!!doneatrue
+ \!!donebtrue
+ \or
+ % 3: depth, fit
+ \!!donebtrue
+ \fi
+ \setbox\nextbox\vbox{\hbox{\raise\nextboxdp\flushnextbox}}%
+ \!!dimena \nextboxht
+ \setcalculatedcos\cos\@@rorotation
+ \setcalculatedsin\sin\@@rorotation
+ \@@layerxpos\zeropoint
+ \@@layerypos\zeropoint
+ \@@layerxoff\zeropoint
+ \@@layeryoff\zeropoint
+ \ifdim\sin\points>\zeropoint
+ \ifdim\cos\points>\zeropoint
+ \@@layerxsiz \cos\!!widtha
+ \@@layerysiz \sin\!!widtha
+ \advance\@@layerxsiz \sin\!!dimena
+ \advance\@@layerysiz \cos\!!dimena
+ \@@layerypos \cos\!!dimena
+ \if!!donea
+ \@@layerxoff \negated\sin\!!dimena
+ \advance\@@layerxoff \sin\!!deptha
+ \fi
+ \if!!doneb
+ \@@layeryoff \cos\!!deptha
+ \fi
+ \dododorotatenextbox
+ \else
+ \@@layerxsiz \negated\cos\!!widtha
+ \@@layerysiz \sin\!!widtha
+ \advance\@@layerxsiz \sin\!!dimena
+ \advance\@@layerysiz \negated\cos\!!dimena
+ \@@layerxpos \negated\cos\!!widtha
+ \if!!donea
+ \@@layerxoff -\@@layerxsiz
+ \advance\@@layerxoff \sin\!!deptha
+ \fi
+ \if!!doneb
+ \@@layeryoff \negated\cos\!!heighta
+ \fi
+ \dododorotatenextbox
+ \wd\nextbox\if!!donea\sin\!!deptha\else\@@layerxsiz\fi
+ \fi
+ \else
+ \ifdim\cos\points<\zeropoint
+ \@@layerxsiz \negated\cos\!!widtha
+ \@@layerysiz \negated\sin\!!widtha
+ \advance\@@layerxsiz \negated\sin\!!dimena
+ \advance\@@layerysiz \negated\cos\!!dimena
+ \@@layerxpos \@@layerxsiz
+ \@@layerypos \negated\sin\!!widtha
+ \if!!donea
+ \@@layerxoff -\@@layerxsiz
+ \advance\@@layerxoff \negated\sin\!!heighta
+ \fi
+ \if!!doneb
+ \@@layeryoff \@@layerysiz
+ \advance\@@layeryoff \cos\!!deptha
+ \fi
+ \dododorotatenextbox
+ \wd\nextbox\if!!donea\negated\sin\!!heighta\else\@@layerxsiz\fi
+ \else
+ \@@layerxsiz \cos\!!widtha
+ \@@layerysiz \negated\sin\!!widtha
+ \advance\@@layerxsiz \negated\sin\!!dimena
+ \advance\@@layerysiz \cos\!!dimena
+ \ifdim\sin\points=\zeropoint
+ \@@layerxpos \zeropoint
+ \@@layerxoff \zeropoint
+ \@@layerypos \@@layerysiz
+ \if!!doneb
+ \@@layeryoff \!!deptha
+ \fi
+ \else
+ \@@layerypos \@@layerysiz
+ \@@layerxpos \negated\sin\!!dimena
+ \if!!donea
+ \@@layerxoff -\@@layerxsiz
+ \advance\@@layerxoff \negated\sin\!!heighta
+ \fi
+ \if!!doneb
+ \@@layeryoff \negated\sin\!!deptha
+ \fi
+ \fi
+ \dododorotatenextbox
+ \ifdim\sin\points=\zeropoint
+ \else
+ \wd\nextbox\if!!donea\negated\sin\!!heighta\else\@@layerxsiz\fi
+ \fi
+ \fi
+ \fi
+ % new, location=middle
+ \ifnum#2=\plusfour
+ \setbox\nextbox\vbox{\vskip-.5\!!heightb\hskip.5\!!heightb\flushnextbox}%
+ \nextboxwd\!!widthb
+ \nextboxht\!!heightb
+ \nextboxdp\!!depthb
+ \fi}
+
+\def\dorotatenextbox#1#2%
+ {\doifsomething{#1}
+ {\edef\@@rorotation{\realnumber{#1}}% get rid of leading zeros and spaces
+ \setbox\nextbox\vbox{\flushnextbox}% not really needed
+ \dodorotatenextbox\@@rorotation#2}%
+ \hbox{\boxcursor\flushnextbox}}
+
+\def\dodorotatebox#1% {angle} \hbox/\vbox/\vtop
+ {\bgroup\hbox\bgroup % compatibility hack
+ \dowithnextbox
+ {\dorotatenextbox{#1}\plusone
+ \egroup\egroup}}
+
+\def\dorotatebox#1% {angle} \hbox/\vbox/\vtop
+ {\ifcase#1\relax
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\dodorotatebox
+ \fi{#1}}
+
+\unexpanded\def\rotate % \bgroup: \rotate kan argument zijn
+ {\bgroup\complexorsimpleempty\rotate}
+
+% \def\complexrotate[#1]% framed met diepte !
+% {\getparameters[\??ro][#1]%
+% \processaction
+% [\@@rolocation]
+% [ \v!depth=>\!!counta\plusthree\donefalse,% depth fit - raw box
+% \v!fit=>\!!counta\plustwo \donefalse,% depth tight - raw box
+% \v!broad=>\!!counta\plusone \donefalse,% nodepth fit - raw box
+% \v!high=>\!!counta\plusone \donetrue ,% nodepth fit - framed
+% \v!middle=>\!!counta\plusfour \donefalse,% centered, keep dimensions
+% \s!default=>\!!counta\plusthree\donetrue ,% depth fit - framed
+% \s!unknown=>\!!counta\plusthree\donetrue ]% depth fit - framed
+% \ifdone
+% \def\docommand{\localframed[\??ro][#1,\c!location=]}%
+% \else
+% \let\docommand\relax
+% \fi
+% \dowithnextbox{\dorotatenextbox\@@rorotation\!!counta\egroup}\vbox\docommand}
+
+\setvalue{\??ro::\c!location::\v!depth }{\!!counta\plusthree\donefalse} % depth fit - raw box
+\setvalue{\??ro::\c!location::\v!fit }{\!!counta\plustwo \donefalse} % depth tight - raw box
+\setvalue{\??ro::\c!location::\v!broad }{\!!counta\plusone \donefalse} % nodepth fit - raw box
+\setvalue{\??ro::\c!location::\v!high }{\!!counta\plusone \donetrue } % nodepth fit - framed
+\setvalue{\??ro::\c!location::\v!middle }{\!!counta\plusfour \donefalse} % centered, keep dimensions
+\setvalue{\??ro::\c!location::\v!default}{\!!counta\plusthree\donetrue } % depth fit - framed
+
+\def\complexrotate[#1]% framed met diepte !
+ {\getparameters[\??ro][#1]%
+ \executeifdefined{\??ro::\c!location::\@@rolocation}{\!!counta\plusthree\donetrue}%
+ \ifdone
+ \def\docommand{\localframed[\??ro][#1,\c!location=]}%
+ \else
+ \let\docommand\relax
+ \fi
+ \dowithnextbox{\dorotatenextbox\@@rorotation\!!counta\egroup}\vbox\docommand}
+
+\presetlocalframed[\??ro]
+
+\def\setuprotate
+ {\dodoubleargument\getparameters[\??ro]}
+
+\setuprotate
+ [\c!rotation=90,
+ \c!location=\v!normal,
+ \c!width=\v!fit,
+ \c!height=\v!fit,
+ \c!offset=\v!overlay,
+ \c!frame=\v!off]
+
+% \dostepwiserecurse{0}{360}{10}
+% {\startlinecorrection[blank]
+% \hbox
+% {\expanded{\setuprotate[rotation=\recurselevel]}%
+% \traceboxplacementtrue
+% \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=depth] {\ruledhbox{\bfb (depth)}}}}%
+% \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=fit] {\ruledhbox{\bfb (fit)}}}}%
+% \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=broad] {\ruledhbox{\bfb (broad)}}}}%
+% \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=normal]{\ruledhbox{\bfb (normal)}}}}%
+% \hbox to .2\hsize{\hss\ruledhbox{\rotate[location=high] {\ruledhbox{\bfb (high)}}}}}
+% \stoplinecorrection}
+
+% to be used in some other places! todo!
+%
+% divides \hsize in fractions, will be made a bit more
+% clever and advanced when needed
+%
+% \horizontaldivision[n/m,elements,distance]
+%
+% \horizontaldivision[2/5,3,1em]
+% \horizontaldivision[2/5,3,1em]
+% \horizontaldivision[1/5,3,1em]
+%
+% \setuphorizontaldivision[afstand=,aantal=] (passend,passend)
+
+\def\??fr{@@fr}
+
+\def\setuphorizontaldivision
+ {\dodoubleargument\getparameters[\??fr]}
+
+\def\horizontaldivision
+ {\dosingleargument\dohorizontaldivision}
+
+\def\dohorizontaldivision[#1]%
+ {\dodohorizontaldivision[#1,,,,,,]}
+
+\def\dodohorizontaldivision[#1/#2,#3,#4,#5]%
+ {\doifelsenothing{#3}
+ {\doifelse\@@frn\v!fit
+ {\!!counta#2\relax}
+ {\!!counta\@@frn\relax}}
+ {\!!counta#3\relax}%
+ \doifelsenothing{#4}
+ {\doifelse\@@frdistance\v!fit
+ {\!!widtha\zeropoint}
+ {\!!widtha\@@frdistance}}
+ {\!!widtha#4}%
+ \advance\!!counta \minusone
+ \multiply\!!widtha \!!counta
+ \advance\hsize -\!!widtha
+ \divide\hsize #2\relax
+ \hsize#1\hsize}
+
+\setuphorizontaldivision
+ [\c!distance=\tfskipsize,
+ \c!n=\v!fit]
+
+%D This one is for Daniel Pittman, who wanted tight
+%D fractions. We show three versions. First the simple
+%D one using \type {\low} and \type {high}:
+%D
+%D \startbuffer
+%D \def\vfrac#1#2%
+%D {\hbox{\high{\tx#1\kern-.25em}/\low{\kern-.25em\tx#2}}}
+%D
+%D test \vfrac{1}{2} test \vfrac{123}{456} test
+%D \stopbuffer
+%D
+%D \typebuffer {\showmakeup\getbuffer}
+%D
+%D A better way to handle the kerning is the following, here
+%D we kind of assume that tye slash is symmetrical and has
+%D nearly zero width.
+%D
+%D \startbuffer
+%D \def\vfract#1#2%
+%D {\hbox{\high{\tx#1}\hbox to \zeropoint{\hss/\hss}\low{\tx#2}}}
+%D \stopbuffer
+%D
+%D \typebuffer {\showmakeup\getbuffer}
+%D
+%D The third and best alternative is the following:
+%D
+%D {\showmakeup\getbuffer}\crlf\getbuffer
+%D
+%D This time we measure the height of the \type {/} and
+%D shift over the maximum height and depths of this
+%D character and the fractional digits (we use 57 as
+%D sample). Here we combine all methods in one macros.
+
+\chardef\vulgarfractionmethod=3
+
+\definehspace[vulgarfraction][.25em] % [.15em]
+\definesymbol[vulgarfraction][/] % [\raise.2ex\hbox{/}]
+
+\unexpanded\def\vulgarfraction#1#2%
+ {\dontleavehmode
+ \hbox
+ {\def\vulgarfraction{vulgarfraction}%
+ \ifcase\vulgarfractionmethod
+ #1\symbol[\vulgarfraction]#2%
+ \or
+ \high{\tx#1\kern-\hspaceamount\empty\vulgarfraction}%
+ \symbol[\vulgarfraction]%
+ \low {\kern-\hspaceamount\empty\vulgarfraction\tx#2}%
+ \or
+ \high{\tx#1}%
+ \hbox to \zeropoint{\hss\symbol[\vulgarfraction]\hss}%
+ \low{\tx#2}%
+ \or
+ \setbox0\hbox{\symbol[\vulgarfraction]}%
+ \setbox2\hbox{\txx57}%
+ \raise\ht0\hbox{\lower\ht2\hbox{\txx#1}}%
+ \hbox to \zeropoint{\hss\symbol[\vulgarfraction]\hss}%
+ \lower\dp0\hbox{\raise\dp2\hbox{\txx#2}}%
+ \fi}}
+
+\ifx\vfrac\undefined \let\vfrac\vulgarfraction \fi
+
+%D \starttabulate
+%D \HL
+%D \NC \bf method \NC \bf visualization \NC\NR
+%D \HL
+%D \NC 0 \NC \chardef\vulgarfractionmethod0\vulgarfraction{1}{2} \NC\NR
+%D \NC 1 \NC \chardef\vulgarfractionmethod1\vulgarfraction{1}{2} \NC\NR
+%D \NC 2 \NC \chardef\vulgarfractionmethod2\vulgarfraction{1}{2} \NC\NR
+%D \NC 3 \NC \chardef\vulgarfractionmethod3\vulgarfraction{1}{2} \NC\NR
+%D \HL
+%D \stoptabulate
+
+%D Under construction:
+%D
+%D \starttyping
+%D \commalistsentence[aap,noot,mies]
+%D \commalistsentence[aap,noot]
+%D \commalistsentence[aap]
+%D \commalistsentence[a,b,c]
+%D \commalistsentence[a,b,c][{ \& },{ and }]
+%D \commalistsentence[a,b,c][+,-]
+%D \stoptyping
+
+\let\handlecommalistsentence\firstofoneargument
+
+\def\commalistsentenceone{and-1}
+\def\commalistsentencetwo{and-2}
+
+\def\commalistsentence
+ {\dodoubleempty\docommalistsentence}
+
+\def\docommalistsentence[#1][#2]%
+ {\bgroup
+ \getfromcommalist[#2][1]%
+ \ifx\commalistelement\empty
+ \def\@@commalistsentenceone{\labeltext\commalistsentenceone}%
+ \else
+ \let\@@commalistsentenceone\commalistelement
+ \fi
+ \getfromcommalist[#2][2]%
+ \ifx\commalistelement\empty
+ \def\@@commalistsentencetwo{\labeltext\commalistsentencetwo}%
+ \else
+ \let\@@commalistsentencetwo\commalistelement
+ \fi
+ \getcommalistsize[#1]%
+ \ifcase\commalistsize\relax
+ \def\serializedcommalist{#1}%
+ \else
+ \let\serializedcommalist\empty
+ \scratchcounter\zerocount
+ \def\docommand##1%
+ {\advance\scratchcounter \plusone
+ \ifnum\scratchcounter=\plusone
+ \scratchtoks{\handlecommalistsentence{##1}}%
+ \else
+ \ifnum\scratchcounter=\commalistsize
+ \appendtoks\@@commalistsentencetwo\handlecommalistsentence{##1}\to\scratchtoks
+ \else
+ \appendtoks\@@commalistsentenceone\handlecommalistsentence{##1}\to\scratchtoks
+ \fi
+ \fi}%
+ \processcommacommand[#1]\docommand
+ \edef\serializedcommalist{\the\scratchtoks}%
+ \fi
+ \serializedcommalist
+ \egroup}
+
+\def\commacommandsentence[#1]{\@EA\commalistsentence\@EA[#1]}
+
+\ifx\textcomma\undefined \def\textcomma{,} \fi
+
+\setuplabeltext [\s!nl] [and-1=\textcomma\ , and-2= en ]
+\setuplabeltext [\s!en] [and-1=\textcomma\ , and-2=\textcomma\ and ]
+\setuplabeltext [\s!de] [and-1=\textcomma\ , and-2= und ]
+
+%D \macros
+%D {somekindoftab}
+%D
+%D This macro can be used to create tabs:
+%D
+%D \starttyping
+%D \setupheadertexts[{\somekindoftab[alternative=horizontal]{\framed{\realfolio}}}]
+%D \setuptexttexts [{\somekindoftab[alternative=vertical] {\framed{\realfolio}}}]
+%D
+%D \starttext
+%D \showframe \dorecurse{10}{test\page}
+%D \stoptext
+%D \stoptyping
+
+\def\somekindoftab
+ {\dosingleempty\dosomekindoftab}
+
+\def\dosomekindoftab[#1]%
+ {\bgroup
+ \getparameters[xx]
+ [\c!alternative=\v!vertical,
+ \c!width=\textwidth,\c!height=\textheight,
+ \c!n=\lastpage,\c!m=\realpageno,
+ #1]%
+ \doifelse\xxalternative\v!vertical
+ {\dodosomekindoftab\vbox\vskip\xxheight}
+ {\dodosomekindoftab\hbox\hskip\xxwidth }}
+
+\def\dodosomekindoftab#1#2#3#4%
+ {#1 to #3 \bgroup
+ \forgetall
+ \ifnum\xxm>\plusone
+ #2\zeropoint \!!plus \the\numexpr\xxm -1\relax fill\relax
+ \fi
+ #4%
+ \ifnum\xxm<\xxn\relax
+ #2\zeropoint \!!plus \the\numexpr\xxn-\xxm\relax fill\relax
+ \fi
+ \egroup
+ \egroup}
+
+\protect \endinput
diff --git a/tex/context/base/core-nav.tex b/tex/context/base/core-nav.mkii
index 045a05123..f4594ab3b 100644
--- a/tex/context/base/core-nav.tex
+++ b/tex/context/base/core-nav.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Navigation}
+\writestatus{loading}{ConTeXt Core Macros / Navigation}
\unprotect
diff --git a/tex/context/base/core-nav.mkiv b/tex/context/base/core-nav.mkiv
new file mode 100644
index 000000000..e079f5f08
--- /dev/null
+++ b/tex/context/base/core-nav.mkiv
@@ -0,0 +1,425 @@
+%D \module
+%D [ file=core-nav,
+%D version=1998.01.15,
+%D title=\CONTEXT\ Core Macros,
+%D subtitle=Navigation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Core Macros / Navigation}
+
+\unprotect
+
+%D Support for interactive document is very present in
+%D \CONTEXT\ and interwoven in many modules. This means that in
+%D this module, where we deal with some common navigational
+%D features, there will be quite some forward references.
+%D
+%D When I started implementing hypertext support, the macros
+%D were mostly dealing with things related to locations, that
+%D is click in this location and goto that one. The
+%D functionality of many macro depends on the output medium:
+%D paper or screen. The next boolean holds the state:
+
+\newif\iflocation \def\ifinteractief{\iflocation} % upw comp
+
+%D We also allocate a scratchbox:
+
+\newbox\locationbox
+
+%D There is no interaction at all unless enabled by saying:
+%D
+%D \starttyping
+%D \setupinteraction[state=start]
+%D \stoptyping
+%D
+%D The other settings are:
+%D
+%D \showsetup{setupinteraction}
+%D
+%D In the special driver modules we introduced a switch that
+%D forces page destinations (instead of named ones). We set
+%D this switch here.
+
+\def\setinteractionparameter#1#2% use with case, no checking done
+ {\setvalue{\??ia#1}{#2}} % pass #2, can be \blabla
+
+\def\resetinteractionparameter#1% use with case, no checking done
+ {\letvalue{\??ia#1}\empty}
+
+% \def\interactionparameter#1%
+% {\csname\??ia#1\endcsname}
+
+\newtoks\everysetupinteraction
+
+\def\setupinteraction
+ {\dosingleargument\dodosetupinteraction}
+
+\def\dodosetupinteraction[#1]% % \dosetupinteraction == special
+ {\getparameters[\??ia][#1]%
+ \the\everysetupinteraction}
+
+% todo, move partial append to where the action happens
+
+\appendtoks
+ \doifelse\@@iastate\v!start
+ {\iflocation\else
+ \showmessage\m!interactions2{\ifusepagedestinations\space(PAGE)\fi}%
+ \global\locationtrue
+ \fi}
+ {\iflocation
+ \showmessage\m!interactions3{\ifusepagedestinations\space(PAGE)\fi}%
+ \global\locationfalse
+ \fi}%
+ \iflocation
+ \setsystemmode \v!interaction
+ \else
+ \resetsystemmode\v!interaction
+ \fi
+ \dosetuppageview\@@iafocus
+ \doifsomething\@@iacalculate
+ {\doregistercalculationset\@@iacalculate}%
+ \doifelse\@@iastrut\v!yes
+ \locationstruttrue
+ \locationstrutfalse
+ \doifelse\@@iaclick\v!yes
+ \highlighthyperlinkstrue
+ \highlighthyperlinksfalse
+ \doifelse\@@iasplit\v!yes
+ \locationsplittrue
+ \locationsplitfalse
+ \doifelse\@@iadisplay\v!new
+ \gotonewwindowtrue
+ \gotonewwindowfalse
+ \doifelse\@@iapage\v!yes
+ {\global\usepagedestinationstrue}
+ {\global\usepagedestinationsfalse}%
+\to \everysetupinteraction
+
+%D We have to make sure of some settings:
+
+\def\dolocationstartup
+ {\iflocation
+ \dosetupinteraction
+ \handlereferenceactions\@@iaopenaction \dosetupopenaction
+ \handlereferenceactions\@@iacloseaction\dosetupcloseaction
+ \setupinteractionscreens
+ \global\let\dolocationstartup\relax
+ \fi}
+
+\appendtoks \dolocationstartup \to \everyshipout
+
+\def\dolocationpagecheck % brr pdf dependent
+ {\iflocation
+ \handlereferenceactions\@@iaopenpageaction \dosetupopenpageaction
+ \handlereferenceactions\@@iaclosepageaction\dosetupclosepageaction
+ \fi}
+
+\appendtoks \dolocationpagecheck \to \everyshipout
+
+%D The next few macros are really horrible. For proper
+%D navigation a in||line hypertext fragment must have
+%D comfortable properties, so we must force some minimal
+%D dimensions. On the other hand button, and here I mean those
+%D pieces of text with fancy outlines and/or backgrounds, often
+%D have fixed, preset dimensions.
+%D
+%D To make things even worse, if we choose to let the optimal
+%D dimensions depend on the height and depth of a strut, a not
+%D too uncommon practice in \TEX, we have to deal with the fact
+%D that such a strut, set inside a box, is unknown too the
+%D outside world.
+%D
+%D The solution lays in passing the strut characteristics in
+%D a proper way, in our case by applying \type{\presetgoto}:
+%D
+%D \starttyping
+%D {some piece of text \presetgoto}
+%D \stoptyping
+%D
+%D This macro stores the current strut values.
+
+\newif\iflocationstrut
+\newif\iflocationsplit
+
+\def\resetgoto
+ {\globallet\@@ia@@hoogte\!!zeropoint
+ \globallet\@@ia@@diepte\!!zeropoint}
+
+\resetgoto
+
+\def\presetgoto
+ {\iflocationstrut
+ \setstrut
+ %\xdef\@@ia@@hoogte{\the\strutht}%
+ %\xdef\@@ia@@diepte{\the\strutdp}%
+ \globallet\@@ia@@hoogte\strutheight
+ \globallet\@@ia@@diepte\strutdepth
+ \else
+ \globallet\@@ia@@hoogte\@@iaheight
+ \globallet\@@ia@@diepte\@@iadepth
+ \fi}
+
+%D In the macros that deal with making areas into hyperlinks,
+%D we use:
+
+\newbox\driverresources
+
+\def\collectdriverresource#1%
+ {\global\setbox\driverresources\hbox{\box\driverresources#1}}
+
+\def\flushdriverresources
+ {\ifvoid\driverresources\else\box\driverresources\fi}
+
+% \def\dohandlegoto#1#2#3%
+% {\ifsecondaryreference
+% \bgroup\setbox0\hbox{#2#3}\egroup
+% \else
+% \hbox
+% {\setbox0\hbox{#1}%
+% \ifdim\wd0<\@@iawidth\relax
+% \buttonwidth\@@iawidth\relax
+% \else
+% \buttonwidth\wd0
+% \fi
+% \ifdim\ht0<\@@ia@@hoogte\relax
+% \buttonheight\@@ia@@hoogte\relax
+% \else
+% \buttonheight\ht0
+% \fi
+% \ifdim\dp0<\@@ia@@diepte\relax
+% \dimen0=\@@ia@@diepte\relax % = !
+% \else
+% \dimen0\dp0
+% \fi
+% \advance\buttonheight \dimen0
+% \setbox2\hbox
+% {\lower\dimen0\hbox
+% {\dontcomplain
+% \dimen0=.5\wd0 % direct skipping is faster of course
+% \advance\dimen0 -.5\buttonwidth % buts this is nicer
+% \hskip\dimen0#2#3}}% when visualizing things
+% \naturalhbox % needed for omega / moved from plus-omg
+% {\ifreversegoto
+% \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0
+% \else
+% \smashbox2\box2\box0
+% \fi
+% \flushdriverresources}%
+% \resetgoto}%
+% \fi}
+
+\def\dohandlegoto#1#2#3%
+ {\ifcollectreferenceactions
+ % this happens here while in mkii elsewhere, better is to deal with
+ % in in the ref module but that's for later to deal with
+ \bgroup\setbox\scratchbox\hbox{#2#3}\egroup
+ \ifsecondaryreference \else
+ \resetgoto
+ \fi
+ \ifsecondaryreference\else#1\resetgoto\fi
+ \else\ifsecondaryreference
+ \bgroup\setbox\scratchbox\hbox{#2#3}\egroup
+ \else
+ \hbox
+ {\setbox0\hbox{#1}%
+ \ifdim\wd0<\@@iawidth\relax
+ \buttonwidth\@@iawidth\relax
+ \else
+ \buttonwidth\wd0
+ \fi
+ \ifdim\ht0<\@@ia@@hoogte\relax
+ \buttonheight\@@ia@@hoogte\relax
+ \else
+ \buttonheight\ht0
+ \fi
+ \ifdim\dp0<\@@ia@@diepte\relax
+ \dimen0=\@@ia@@diepte\relax % = !
+ \else
+ \dimen0\dp0
+ \fi
+ \advance\buttonheight \dimen0
+ \setbox2\hbox
+ {\lower\dimen0\hbox
+ {\dontcomplain
+ \dimen0=.5\wd0 % direct skipping is faster of course
+ \advance\dimen0 -.5\buttonwidth % buts this is nicer
+ \hskip\dimen0#2#3}}% when visualizing things
+ \naturalhbox % needed for omega / moved from plus-omg
+ {\ifreversegoto
+ \dimen0\wd0\box0\kern-\dimen0\smashbox2\box2\kern\dimen0
+ \else
+ \smashbox2\box2\box0
+ \fi
+ \flushdriverresources}%
+ \resetgoto}%
+ \fi\fi}
+
+%D The secondary references are processed but not typeset. The
+%D special driver must collect the data needed.
+
+%D The width of the active area depends on the dimensions
+%D preset, the actual dimens and/or the height and depth of the
+%D strut.
+%D
+%D Normally the hyper active area is laid on top of the text.
+%D This enables stacking hyperlinks on top of each other. When,
+%D for some reason the opposite is prefered, one can use the
+%D next boolean to signal this wish.
+
+\newif\ifreversegoto \reversegotofalse
+
+%D As long as there a natural feeling of what can be considered
+%D hyper active or not, we have to tell users where they can
+%D possibly click. We've already seen a few macros that deal
+%D with this visualization, something we definitely do not let
+%D up to the viewer. One way of telling is using a distinctive
+%D typeface, another way is using color.
+%D
+%D There are two colors involved: one for normal hyperlinks,
+%D and one for those that point to the currentpage, the
+%D contrast color.
+
+\definecolor [interactioncolor] [r=0, g=.6, b=0]
+\definecolor [interactioncontrastcolor] [r=.8, g=0, b=0]
+
+\definecolor [interactiekleur] [interactioncolor]
+\definecolor [interactiecontrastkleur] [interactioncontrastcolor]
+
+%D The next few macros are responsible for highlighting hyper
+%D links. The first one, \type{\showlocation}, is used in those
+%D situations where the typeface is handled by the calling
+%D macro.
+
+\def\interactioncolor % todo \??ia as argument
+ {\iflocation
+ \ifrealreferencepage
+ \@@iacontrastcolor
+ \else
+ \@@iacolor
+ \fi
+ \fi}
+
+%D CHECK WHERE USED / CONSISTENCY
+
+\def\showlocation#1%
+ {\iflocation\color[\@@iacolor]{#1\presetgoto}\else#1\fi}
+
+%D When local color settings are to be used, we can use the
+%D next macro, where \type{#1} is a tag like \type{\??tg} and
+%D \type{#2} some text.
+
+\def\showcoloredlocation#1#2%
+ {\iflocation
+ \color[\getvalue{#1\c!color}]{#2\presetgoto}%
+ \else
+ #2%
+ \fi}
+
+%D When we're dealing with pure page references, contrast
+%D colors are used when we are already at the page mentioned.
+
+\def\showcontrastlocation#1#2#3% the \@EA is needed
+ {\iflocation
+ \ifnum#2=\realpageno\relax
+ \doifelsevaluenothing{#1\c!color}
+ {#3\presetgoto}
+ {\color[\getvalue{#1\c!contrastcolor}]{#3\presetgoto}}%
+ \else
+ \color[\getvalue{#1\c!color}]{#3\presetgoto}%
+ \fi
+ \else
+ #3%
+ \fi}
+
+%D The next simple macro can be used in color specifications,
+%D like \type{\color[\locationcolor{green}]}.
+
+\def\locationcolor#1%
+ {\iflocation#1\fi}
+
+%D More tokens are spend when we want both typeface and color
+%D highlighting.
+
+\def\dolocationattributes#1#2#3#4%
+ {\bgroup
+ \let\fontattribute\empty
+ \let\colorattribute\empty
+ \doifdefined{#1#2}{\def\fontattribute{\getvalue{#1#2}}}%
+ \iflocation
+ \doifdefined{#1#3}{\def\colorattribute{\getvalue{#1#3}}}%
+ \fi
+ \startcolor[\colorattribute]%
+ \@EA\doconvertfont\@EA{\fontattribute}{#4}% no \edef, but \@EA here
+ \stopcolor
+ \egroup}
+
+\def\navigating
+ {\dolocationattributes\??ia\c!style\c!color}
+
+%D Although not decently supported in current viewers, a
+%D provisory hiding mechanims is implemented. Areas marked as
+%D such, are visible on screen, but invisible on paper. Don't
+%D trust this mechanism yet!
+
+\def\dostartinteraction
+ {\bgroup
+ \let\stopinteraction\egroup
+ \dowithnextbox{\dostarthide\flushnextbox\dostophide\egroup}\hbox}
+
+\let\startinteraction = \relax
+\let\stopinteraction = \relax
+
+% in the future:
+%
+% eerst boolean invoeren bij menu, achtergrond, balk, button
+% enz; verder startinteractie een argument meegeven {#1} ->
+% \getvalue{#1\c!print}=={\v!ja} enz. Consequent menubutton
+% gebruiken!
+
+\def\@@iatimestamp
+ {\the\normalyear
+ \ifnum\normalmonth<10 0\fi\the\normalmonth
+ \ifnum\normalday <10 0\fi\the\normalday}
+
+% happens in core-fld
+%
+% \definereference [AtOpenInitializeForm] [\v!geen]
+
+\setupinteraction % start fit page and reset form
+ [\c!state=\v!stop,
+ \c!page=\v!no,
+ \c!click=\v!yes,
+ \c!display=,
+ %\c!openaction={\v!firstpage,AtOpenInitializeForm},
+ %\c!openaction={\v!firstpage,\v!ResetForm},
+ %\c!openaction=\v!ResetForm, % too buggy in reader 4.05
+ \c!openaction=,
+ \c!closeaction=,
+ \c!openpageaction=,
+ \c!closepageaction=,
+ \c!display=\v!normal,
+ \c!focus=\v!fit,
+ \c!menu=\v!off,
+ \c!style=\v!bold,
+ \c!calculate=,
+ \c!strut=\v!yes,
+ \c!split=\v!yes,
+ \c!color=interactioncolor,
+ \c!contrastcolor=interactioncontrastcolor,
+ \c!symbolset=,
+ \c!width=1em,
+ \c!height=\!!zeropoint,
+ \c!depth=\!!zeropoint,
+ \c!title=\jobname, % needed for fdf/x
+ \c!subtitle=,
+ \c!author=,
+ \c!keyword=,
+ \c!date=\@@iatimestamp]
+
+\protect \endinput
diff --git a/tex/context/base/core-not.tex b/tex/context/base/core-not.tex
index aa6edd0e6..70d3f8627 100644
--- a/tex/context/base/core-not.tex
+++ b/tex/context/base/core-not.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Note Handling}
+\writestatus{loading}{ConTeXt Core Macros / Note Handling}
%D Unfortunately we cannot force an even number of lines in
%D a two column footnote placement.
@@ -36,8 +36,8 @@
%D \stopitemize
%D
%D Because footnotes are declared at the location of their
-%D reference. Footnotes can be seen as a special kind of
-%D floating bodies. There placement is postponed but has to be
+%D reference they can be seen as a special kind of
+%D floating bodies. Their placement is postponed but has to be
%D taken into account in the pagebreak calculations. This kind
%D of calculations are forced by using \type{\insert}.
@@ -383,7 +383,7 @@
\placenoterule
\noteparameter\c!after}%
\global\skip\currentnoteins\ht\scratchbox
- \setbox\scratchbox\box\voidb@x} % scratchbox can be in use
+ \setbox\scratchbox\emptybox} % scratchbox can be in use
\ifx\setnotehsize\undefined
diff --git a/tex/context/base/core-num.tex b/tex/context/base/core-num.tex
index 4dde1d4d3..a86ce8a1d 100644
--- a/tex/context/base/core-num.tex
+++ b/tex/context/base/core-num.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Numbering}
+\writestatus{loading}{ConTeXt Core Macros / Numbering}
\unprotect
diff --git a/tex/context/base/core-obj.lua b/tex/context/base/core-obj.lua
index 338ca9d1f..f879ddc8c 100644
--- a/tex/context/base/core-obj.lua
+++ b/tex/context/base/core-obj.lua
@@ -34,6 +34,10 @@ function jobobjects.set(tag,number,page)
collected[tag] = { number, page }
end
+function jobobjects.get(tag)
+ return collected[tag] or tobesaved[tag]
+end
+
function jobobjects.number(tag,default)
local o = collected[tag] or tobesaved[tag]
texsprint((o and o[1]) or default)
@@ -45,5 +49,6 @@ function jobobjects.page(tag,default)
end
function jobobjects.doifelse(tag)
- cs.testcase(collected[tag] or tobesaved[tag])
+ commands.testcase(collected[tag] or tobesaved[tag])
end
+
diff --git a/tex/context/base/core-obj.mkii b/tex/context/base/core-obj.mkii
index b0599dde9..6e210a0ab 100644
--- a/tex/context/base/core-obj.mkii
+++ b/tex/context/base/core-obj.mkii
@@ -11,9 +11,49 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% todo, move more to mkiv, get rid of blabelgroup
+
+\writestatus{loading}{ConTeXt Core Macros / Object Handling}
+
\unprotect
-\def\mkcheckobjectreferences
+%D \macros
+%D {setobject,getobject,ifinobject}
+%D
+%D Boxes can be considered reuable objects. Unfortunaltely once
+%D passed to the \DVI\ file, such objects cannot be reused. In
+%D \PDF\ however, reusing is possible and sometimes even a
+%D necessity. Therefore, \CONTEXT\ supports reusable objects.
+%D
+%D During the \TEX\ processing run, boxes can serve the purpose
+%D of objects, and the \DVI\ driver module implements objects
+%D using packed boxes.
+%D
+%D The \PDF\ and \PDFTEX\ driver modules implement objects
+%D using \PDF\ forms. There is no (real) restriction on the
+%D number of objects there.
+%D
+%D The first application of objects in \CONTEXT\ concerned
+%D \METAPOST\ graphics and fill||in form fields. The first
+%D application can save lots of bytes, while the latter use is
+%D more a necessity than byte saving.
+%D
+%D \starttyping
+%D \setobject{class}{name}\somebox{}
+%D \getobject{class}{name}
+%D \stoptyping
+%D
+%D Here \type{\somebox} can be whatever box specification suits
+%D \TEX. We save the dimensions of an object, although some
+%D drivers will do so themselves. This means that when for
+%D instance using \PDFTEX\ we could save a hash entry plus some
+%D 20+ memory locations per object by delegating this
+%D housekeeping to the driver. The current approach permits
+%D us to keep the box characteristic too.
+
+\newif\ifinobject
+
+\def\checkobjectreferences
{\startnointerference
\protectlabels
\ifx\usedoutputdriver\currentoutput
@@ -24,6 +64,198 @@
\global\let\checkobjectreferences\relax
\stopnointerference}
+\def\objectplaceholder{NOT YET FLUSHED}%
+
+\def\presetobject#1#2% \global added
+ {\blabelgroup
+ \ifcsname\r!object#1::#2\endcsname\else
+ \global\@EA\let\csname\r!object#1::#2\endcsname\objectplaceholder
+ \fi
+ \elabelgroup}
+
+\def\dosetobject#1#2#3% \initializepaper this will move to \everyshipout
+ {\initializepaper
+ \blabelgroup
+ \ifcsname\r!object#2::#3\endcsname
+ \elabelgroup \expandafter\gobblefivearguments
+ \else % tzt, overload internal referenced objects to save entries
+ \elabelgroup \expandafter\dodosetobject
+ \fi
+ {#1}{#2}{#3}}
+
+\def\resetobject#1#2%
+ {\checkobjectreferences
+ \letbeundefined{\r!object#1::#2}}
+
+%D \macros
+%D {finalizeobjectbox}
+%D
+%D This one provides a hook for last minute object box processing
+%D we need this in \MKIV.
+
+\ifx\finalizeobjectbox\undefined
+ \let\finalizeobjectbox\gobbleoneargument
+\fi
+
+%D Somehow there is a rounding error problem in either \PDFTEX\
+%D or in viewers, or maybe it is conforming the specs. The next
+%D variable compensate for it by removing the rather tight
+%D clip.
+
+\def\objectoffset{1cm}
+
+% \def\dodosetobject#1#2#3%
+% {\bgroup
+% \inobjecttrue
+% \dowithnextbox{\dododosetobject{#1}{#2}{#3}\egroup}}
+
+\def\dodosetobject#1#2#3%
+ {\bgroup
+ \globalpushmacro\crossreferenceobject \objectreferenced
+ \inobjecttrue
+ \dowithnextbox
+ {\globalpopmacro\crossreferenceobject
+ \dododosetobject{#1}{#2}{#3}\egroup}}
+
+\def\dododosetobject#1#2#3%
+ {\blabelgroup
+ \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox
+ \scratchdimen\objectoffset
+ \@EA\xdef\csname\r!object#2::#3\endcsname
+ {\noexpand\dohandleobject{#2}{#3}%
+ {\ifhbox\nextbox\hbox\else\vbox\fi}%
+ %{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}%
+ {\number\nextboxwd}{\number\nextboxht}{\number\nextboxdp}%
+ {\number\scratchdimen}}%
+ \expanded % freeze the dimensions since \dostartobject may use \nextbox
+ {\dostartobject
+ {#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}%
+ \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint
+ \setbox\nextbox\vbox spread 2\scratchdimen
+ {\forgetall \offinterlineskip
+ \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}%
+ \fi \fi
+ \flushnextbox
+ \dostopobject
+ \elabelgroup}
+
+\def\getobject#1#2%
+ {\blabelgroup
+ \let\dohandleobject\dogetobject
+ \csname\r!object#1::#2\endcsname}
+
+% \def\dogetobject#1#2#3#4#5#6%
+% {\initializepaper
+% \forgetall
+% \dontshowcomposition
+% \setbox\scratchbox\vbox
+% {\doinsertobject{#1}{#2}}%
+% \setbox\scratchbox#3%
+% {\vbox to #5\scaledpoint
+% {\ifdim\ht\scratchbox>#5\scaledpoint
+% % or \ifdim\wd\scratchbox>#4\scaledpoint
+% \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
+% \else
+% \vss\box\scratchbox
+% \fi}}%
+% \wd\scratchbox#4\scaledpoint
+% \ht\scratchbox#5\scaledpoint
+% \dp\scratchbox#6\scaledpoint
+% \box\scratchbox
+% \elabelgroup}
+
+% \def\dogetobject#1#2#3#4#5#6#7%
+% {\initializepaper
+% \forgetall
+% \dontshowcomposition
+% \setbox\scratchbox\vbox
+% {\doinsertobject{#1}{#2}}%
+% \setbox\scratchbox#3%
+% {\vbox to #5\scaledpoint
+% {\ifdim\ht\scratchbox>#5\scaledpoint
+% % or \ifdim\wd\scratchbox>#4\scaledpoint
+% \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
+% \else
+% \vss\box\scratchbox
+% \fi}}%
+% \scratchdimen#7\scaledpoint
+% \setbox\nextbox\hbox
+% {\hskip-\scratchdimen\lower\scratchdimen\flushnextbox}%
+% \wd\scratchbox#4\scaledpoint
+% \ht\scratchbox#5\scaledpoint
+% \dp\scratchbox#6\scaledpoint
+% \box\scratchbox
+% \elabelgroup}
+
+\def\dogetobject#1#2#3#4#5#6#7% don't change this, should work for dvi & pdf
+ {\initializepaper
+ \forgetall
+ \dontshowcomposition
+ \setbox\scratchbox\vbox
+ {\doinsertobject{#1}{#2}}%
+ \setbox\scratchbox#3%
+ {\vbox to #5\scaledpoint
+ {\ifdim\ht\scratchbox>#5\scaledpoint
+ \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
+ \else\ifdim\wd\scratchbox>#4\scaledpoint
+ \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
+ \else
+ %\vss\box\scratchbox
+ \vss\hbox to #4\scaledpoint{\box\scratchbox\hss}% fix Chof
+ \fi\fi}}%
+ \box\scratchbox
+ \elabelgroup}
+
+%D If needed one can ask for the dimensions of an object with:
+%D
+%D \starttyping
+%D \getobjectdimensions{class}{name}
+%D \stoptyping
+%D
+%D The results are reported in \type {\objectwidth}, \type
+%D {\objectheight} and \type {\objectdepth}.
+
+% \def\dogetobjectdimensions#1#2#3#4#5#6%
+% {\def\objectwidth {#4\s!sp}%
+% \def\objectheight{#5\s!sp}%
+% \def\objectdepth {#6\s!sp}}
+
+\def\dogetobjectdimensions#1#2#3#4#5#6#7%
+ {\def\objectwidth {#4\s!sp}%
+ \def\objectheight{#5\s!sp}%
+ \def\objectdepth {#6\s!sp}%
+ \def\objectmargin{#7\s!sp}}
+
+\def\getobjectdimensions#1#2%
+ {\let\dohandleobject\dogetobjectdimensions
+ \let\objectwidth \!!zeropoint
+ \let\objectheight\!!zeropoint
+ \let\objectdepth \!!zeropoint
+ \labelcsname\r!object#1::#2\endcsname}
+
+%D Apart from this kind of objects, that have typeset content,
+%D we can have low level driver specific objects. Both types
+%D can have references to internal representations, hidden for
+%D the user. We keep track of such references by means of a
+%D dedicated cross reference mechanism. Normally, objects are
+%D defined before they are used, but forward referencing
+%D sometimes occurs.
+%D
+%D \starttyping
+%D \dosetobjectreference {class} {identifier} {reference value} {page}
+%D \dogetobjectreference {class} {identifier} \csname
+%D \stoptyping
+%D
+%D These commands are to be called by the \type{\startobject},
+%D \type{\stopobject} and \type{\insertobject} specials.
+
+\def\objectreferenced{\global\chardef\crossreferenceobject\plusone}
+\def\driverreferenced{\global\chardef\crossreferenceobject\zerocount}
+
+\objectreferenced
+
+% no undefined test ! ! ! ! (pdftex fails on undefined objects)
+
\def\setobjectreferences
{\def\objectreference##1##2##3##4%
{\ifundefined{\r!driver##1::##2}%
@@ -37,19 +269,36 @@
\resetobjectreferences
-\def\mkregisterobjectreference#1#2#3%
+\def\doregisterobjectreference#1#2#3%
{\checkobjectreferences
\blabelgroup
\expanded{\writeutilitycommand{\noexpand\objectreference{#1}{#2}{#3}{\noexpand\realfolio}}}%
\setxvalue{\r!driver#1::#2}{{#3}{\noexpand\realfolio}}%
\elabelgroup}
-\def\mkoverloadobjectreference#1#2#3%
+\def\dooverloadobjectreference#1#2#3%
{\checkobjectreferences
\blabelgroup
\setxvalue{\r!driver#1::#2}{{#3}{\noexpand\realfolio}}%
\elabelgroup}
+\def\dosetobjectreference
+ {\ifcase\crossreferenceobject
+ \objectreferenced
+ \expandafter\dooverloadobjectreference
+ \else
+ \expandafter\doregisterobjectreference
+ \fi}
+
+\def\dosetdriverreference
+ {\driverreferenced\dosetobjectreference}
+
+\def\defaultobjectreference#1#2{0} % driver dependent
+\def\defaultobjectpage #1#2{\realfolio}
+
+\def\dogetobjectreference {\dodogetobjectreference\firstoftwoarguments\defaultobjectreference}
+\def\dogetobjectreferencepage{\dodogetobjectreference\secondoftwoarguments\defaultobjectpage}
+
\def\dodogetobjectreference#1#2#3#4#5%
{\checkobjectreferences
\blabelgroup
@@ -61,13 +310,28 @@
\fi
\elabelgroup}
-\def\mkgetobjectreference
- {\dodogetobjectreference\firstoftwoarguments\defaultobjectreference}
+\def\setobject {\driverreferenced\dosetobject1}
+\def\settightobject{\driverreferenced\dosetobject0}
+
+%D \macros
+%D {doifobjectfoundelse,doifobjectreferencefoundelse}
+%D
+%D To prevent redundant definition of objects, one can use
+%D the next tests:
+%D
+%D \starttyping
+%D \doifobjectfoundelse{class}{object}{do then}{do else}
+%D \doifobjectreferencefoundelse{class}{object}{do then}{do else}
+%D \stoptyping
-\def\mkgetobjectreferencepage
- {\dodogetobjectreference\secondoftwoarguments\defaultobjectpage}
+\def\doifobjectfoundelse#1#2%
+ {\blabelgroup \ifcsname\r!object#1::#2\endcsname
+ \elabelgroup \expandafter\firstoftwoarguments
+ \else
+ \elabelgroup \expandafter\secondoftwoarguments
+ \fi}
-\def\mkdoifobjectreferencefoundelse#1#2%
+\def\doifobjectreferencefoundelse#1#2%
{\checkobjectreferences
\blabelgroup \ifcsname\r!driver#1::#2\endcsname
\elabelgroup \expandafter\firstoftwoarguments
@@ -75,4 +339,33 @@
\elabelgroup \expandafter\secondoftwoarguments
\fi}
+%D \macros
+%D {doifobjectssupportedelse}
+%D
+%D Starting with reuse of graphics, we will implement object
+%D reuse when possible. To enable mechanisms to determine
+%D what method to use, we provide:
+%D
+%D \starttyping
+%D \doifobjectssupportedelse{true action}{false action}
+%D \stoptyping
+%D
+%D As we can see, currently objects depend on the special
+%D driver.
+
+\newif\ifobjectssupported \objectssupportedtrue
+
+\def\doifobjectssupportedelse
+ {\ifobjectssupported
+ \@EA\doifspecialavailableelse\@EA\doinsertobject
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+%D There is a conceptual problem here. Objects are not possible
+%D in \DVI, unless faked like in \type {spec-dvi}. This means
+%D that we must be careful in loading special drivers that do
+%D support objects while we still want to be able to use the
+%D \DVI\ output.
+
\protect \endinput
diff --git a/tex/context/base/core-obj.mkiv b/tex/context/base/core-obj.mkiv
index 3a54e6507..560a7012d 100644
--- a/tex/context/base/core-obj.mkiv
+++ b/tex/context/base/core-obj.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-obj,
-%D version=2006.10.16,
+%D version=1998.01.15,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Object Handling,
%D author=Hans Hagen,
@@ -11,16 +11,224 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Object Handling}
+
\unprotect
\let\objectreference\gobblefourarguments % catch mkii tuo stuff
\registerctxluafile{core-obj}{1.001}
-\def\mkregisterobjectreference #1#2#3{\expanded{\ctxlatelua{jobobjects.save("#1::#2",#3,\noexpand\the\realpageno)}}}
-\def\mkoverloadobjectreference #1#2#3{\ctxlua{jobobjects.set("#1::#2",#3,\the\realpageno)}}
-\def\mkgetobjectreference #1#2#3{\xdef#3{\ctxlua{jobobjects.number("#1::#2","\defaultobjectreference{#1}{#2}")}}}
-\def\mkgetobjectreferencepage #1#2#3{\xdef#3{\ctxlua{jobobjects.page("#1::#2","\defaultobjectpage{#1}{#2}")}}}
-\def\mkdoifobjectreferencefoundelse#1#2{\ctxlua{jobobjects.doifelse("#1::#2")}}
+%D \macros
+%D {setobject,getobject,ifinobject}
+%D
+%D Boxes can be considered reuable objects. Unfortunaltely once
+%D passed to the \DVI\ file, such objects cannot be reused. In
+%D \PDF\ however, reusing is possible and sometimes even a
+%D necessity. Therefore, \CONTEXT\ supports reusable objects.
+%D
+%D During the \TEX\ processing run, boxes can serve the purpose
+%D of objects, and the \DVI\ driver module implements objects
+%D using packed boxes.
+%D
+%D The \PDF\ and \PDFTEX\ driver modules implement objects
+%D using \PDF\ forms. There is no (real) restriction on the
+%D number of objects there.
+%D
+%D The first application of objects in \CONTEXT\ concerned
+%D \METAPOST\ graphics and fill||in form fields. The first
+%D application can save lots of bytes, while the latter use is
+%D more a necessity than byte saving.
+%D
+%D \starttyping
+%D \setobject{class}{name}\somebox{}
+%D \getobject{class}{name}
+%D \stoptyping
+%D
+%D Here \type{\somebox} can be whatever box specification suits
+%D \TEX. We save the dimensions of an object, although some
+%D drivers will do so themselves. This means that when for
+%D instance using \PDFTEX\ we could save a hash entry plus some
+%D 20+ memory locations per object by delegating this
+%D housekeeping to the driver. The current approach permits
+%D us to keep the box characteristic too.
+
+\newif\ifinobject
+
+\def\objectplaceholder{NOT YET FLUSHED}%
+
+\def\presetobject#1#2% \global added
+ {\ifcsname\r!object#1::#2\endcsname\else
+ \global\@EA\let\csname\r!object#1::#2\endcsname\objectplaceholder
+ \fi}
+
+\def\dosetobject#1#2#3% \initializepaper this will move to \everyshipout
+ {\initializepaper
+ \ifcsname\r!object#2::#3\endcsname
+ \expandafter\gobblefivearguments
+ \else % tzt, overload internal referenced objects to save entries
+ \expandafter\dodosetobject
+ \fi
+ {#1}{#2}{#3}}
+
+\def\resetobject#1#2%
+ {\letbeundefined{\r!object#1::#2}}
+
+%D \macros
+%D {finalizeobjectbox}
+%D
+%D This one provides a hook for last minute object box processing
+%D we need this in \MKIV.
+
+\ifx\finalizeobjectbox\undefined
+ \let\finalizeobjectbox\gobbleoneargument
+\fi
+
+%D Somehow there is a rounding error problem in either \PDFTEX\
+%D or in viewers, or maybe it is conforming the specs. The next
+%D variable compensate for it by removing the rather tight
+%D clip.
+
+\def\objectoffset{1cm}
+
+\def\dodosetobject#1#2#3%
+ {\bgroup
+ \globalpushmacro\crossreferenceobject \objectreferenced
+ \inobjecttrue
+ \dowithnextbox
+ {\globalpopmacro\crossreferenceobject
+ \dododosetobject{#1}{#2}{#3}\egroup}}
+
+\def\dododosetobject#1#2#3%
+ {\begingroup
+ \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox
+ \scratchdimen\objectoffset
+ \@EA\xdef\csname\r!object#2::#3\endcsname
+ {\noexpand\dohandleobject{#2}{#3}%
+ {\ifhbox\nextbox\hbox\else\vbox\fi}%
+ {\number\nextboxwd}{\number\nextboxht}{\number\nextboxdp}%
+ {\number\scratchdimen}}%
+ \expanded % freeze the dimensions since \dostartobject may use \nextbox
+ {\dostartobject{#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}%
+ \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint
+ \setbox\nextbox\vbox spread 2\scratchdimen
+ {\forgetall \offinterlineskip
+ \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}%
+ \fi \fi
+ \flushnextbox
+ \dostopobject
+ \endgroup}
+
+\def\getobject#1#2%
+ {\begingroup
+ \let\dohandleobject\dogetobject
+ \csname\r!object#1::#2\endcsname}
+
+\def\dogetobject#1#2#3#4#5#6#7% don't change this, should work for dvi & pdf
+ {\initializepaper
+ \forgetall
+ \dontshowcomposition
+ \setbox\scratchbox\vbox
+ {\doinsertobject{#1}{#2}}%
+ \setbox\scratchbox#3%
+ {\vbox to #5\scaledpoint
+ {\ifdim\ht\scratchbox>#5\scaledpoint
+ \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
+ \else\ifdim\wd\scratchbox>#4\scaledpoint
+ \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
+ \else
+ %\vss\box\scratchbox
+ \vss\hbox to #4\scaledpoint{\box\scratchbox\hss}% fix Chof
+ \fi\fi}}%
+ \box\scratchbox
+ \endgroup}
+
+%D If needed one can ask for the dimensions of an object with:
+%D
+%D \starttyping
+%D \getobjectdimensions{class}{name}
+%D \stoptyping
+%D
+%D The results are reported in \type {\objectwidth}, \type
+%D {\objectheight} and \type {\objectdepth}.
+
+\def\dogetobjectdimensions#1#2#3#4#5#6#7%
+ {\def\objectwidth {#4\s!sp}%
+ \def\objectheight{#5\s!sp}%
+ \def\objectdepth {#6\s!sp}%
+ \def\objectmargin{#7\s!sp}}
+
+\def\getobjectdimensions#1#2%
+ {\let\dohandleobject\dogetobjectdimensions
+ \let\objectwidth \!!zeropoint
+ \let\objectheight\!!zeropoint
+ \let\objectdepth \!!zeropoint
+ \labelcsname\r!object#1::#2\endcsname}
+
+%D Apart from this kind of objects, that have typeset content,
+%D we can have low level driver specific objects. Both types
+%D can have references to internal representations, hidden for
+%D the user. We keep track of such references by means of a
+%D dedicated cross reference mechanism. Normally, objects are
+%D defined before they are used, but forward referencing
+%D sometimes occurs.
+%D
+%D \starttyping
+%D \dosetobjectreference {class} {identifier} {reference value} {page}
+%D \dogetobjectreference {class} {identifier} \csname
+%D \stoptyping
+%D
+%D These commands are to be called by the \type{\startobject},
+%D \type{\stopobject} and \type{\insertobject} specials.
+
+\def\objectreferenced{\global\chardef\crossreferenceobject\plusone}
+\def\driverreferenced{\global\chardef\crossreferenceobject\zerocount}
+
+\objectreferenced
+
+% no undefined test ! ! ! ! (pdftex fails on undefined objects)
+
+\def\doregisterobjectreference#1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobobjects.save("#1::#2",#3,\noexpand\the\realpageno)}}}
+\def\dooverloadobjectreference#1#2#3{\ctxlua{jobobjects.set("#1::#2",#3,\the\realpageno)}}
+
+\def\dosetobjectreference
+ {\ifcase\crossreferenceobject
+ \objectreferenced
+ \expandafter\dooverloadobjectreference
+ \else
+ \expandafter\doregisterobjectreference
+ \fi}
+
+\def\dosetdriverreference
+ {\driverreferenced\dosetobjectreference}
+
+\def\defaultobjectreference#1#2{0} % driver dependent
+\def\defaultobjectpage #1#2{\realfolio}
+
+\def\dogetobjectreference #1#2#3{\xdef#3{\ctxlua{jobobjects.number("#1::#2","\defaultobjectreference{#1}{#2}")}}}
+\def\dogetobjectreferencepage#1#2#3{\xdef#3{\ctxlua{jobobjects.page("#1::#2","\defaultobjectpage{#1}{#2}")}}}
+
+\def\setobject {\driverreferenced\dosetobject1}
+\def\settightobject{\driverreferenced\dosetobject0}
+
+%D \macros
+%D {doifobjectfoundelse,doifobjectreferencefoundelse}
+%D
+%D To prevent redundant definition of objects, one can use
+%D the next tests:
+%D
+%D \starttyping
+%D \doifobjectfoundelse{class}{object}{do then}{do else}
+%D \doifobjectreferencefoundelse{class}{object}{do then}{do else}
+%D \stoptyping
+
+\def\doifobjectfoundelse#1#2%
+ {\ifcsname\r!object#1::#2\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\doifobjectreferencefoundelse#1#2{\ctxlua{jobobjects.doifelse("#1::#2")}}
\protect \endinput
diff --git a/tex/context/base/core-obj.tex b/tex/context/base/core-obj.tex
deleted file mode 100644
index 23873d2d6..000000000
--- a/tex/context/base/core-obj.tex
+++ /dev/null
@@ -1,365 +0,0 @@
-%D \module
-%D [ file=core-obj,
-%D version=1998.01.15,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Object Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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, move more to mkiv, get rid of blabelgroup
-
-\writestatus{loading}{Context Core Macros / Object Handling}
-
-\unprotect
-
-\startmessages dutch library: references
- 30: onbekend object --
- 31: dubbel object --
-\stopmessages
-
-\startmessages english library: references
- 30: unknown object --
- 31: duplicate object --
-\stopmessages
-
-\startmessages german library: references
- 30: unbekanntes Object --
- 31: doppeltes Object --
-\stopmessages
-
-\startmessages czech library: references
- 30: neznamy objekt --
- 31: duplicitni object --
-\stopmessages
-
-\startmessages italian library: references
- 30: oggetto sconosciuto --
- 31: oggetto duplicato --
-\stopmessages
-
-\startmessages norwegian library: references
- 30: ukjent objekt --
- 31: duplikat objekt --
-\stopmessages
-
-\startmessages romanian library: references
- 30: obiect necunoscut --
- 31: obiect duplicat --
-\stopmessages
-
-\startmessages french library: references
- 30: objet -- inconnu
- 31: objet -- dupliqué
-\stopmessages
-
-%D \macros
-%D {setobject,getobject,ifinobject}
-%D
-%D Boxes can be considered reuable objects. Unfortunaltely once
-%D passed to the \DVI\ file, such objects cannot be reused. In
-%D \PDF\ however, reusing is possible and sometimes even a
-%D necessity. Therefore, \CONTEXT\ supports reusable objects.
-%D
-%D During the \TEX\ processing run, boxes can serve the purpose
-%D of objects, and the \DVI\ driver module implements objects
-%D using packed boxes.
-%D
-%D The \PDF\ and \PDFTEX\ driver modules implement objects
-%D using \PDF\ forms. There is no (real) restriction on the
-%D number of objects there.
-%D
-%D The first application of objects in \CONTEXT\ concerned
-%D \METAPOST\ graphics and fill||in form fields. The first
-%D application can save lots of bytes, while the latter use is
-%D more a necessity than byte saving.
-%D
-%D \starttyping
-%D \setobject{class}{name}\somebox{}
-%D \getobject{class}{name}
-%D \stoptyping
-%D
-%D Here \type{\somebox} can be whatever box specification suits
-%D \TEX. We save the dimensions of an object, although some
-%D drivers will do so themselves. This means that when for
-%D instance using \PDFTEX\ we could save a hash entry plus some
-%D 20+ memory locations per object by delegating this
-%D housekeeping to the driver. The current approach permits
-%D us to keep the box characteristic too.
-
-\newif\ifinobject
-
-\ifx\mkcheckobjectreferences\undefined \let\mkcheckobjectreferences\relax \fi
-
-\def\checkobjectreferences{\mkcheckobjectreferences}
-
-\def\objectplaceholder{NOT YET FLUSHED}%
-
-\def\presetobject#1#2% \global added
- {\blabelgroup
- \ifcsname\r!object#1::#2\endcsname\else
- \global\@EA\let\csname\r!object#1::#2\endcsname\objectplaceholder
- \fi
- \elabelgroup}
-
-\def\dosetobject#1#2#3% \initializepaper this will move to \everyshipout
- {\initializepaper
- \blabelgroup
- \ifcsname\r!object#2::#3\endcsname
- \elabelgroup \expandafter\gobblefivearguments
- \else % tzt, overload internal referenced objects to save entries
- \elabelgroup \expandafter\dodosetobject
- \fi
- {#1}{#2}{#3}}
-
-\def\resetobject#1#2%
- {\checkobjectreferences
- \letbeundefined{\r!object#1::#2}}
-
-%D \macros
-%D {finalizeobjectbox}
-%D
-%D This one provides a hook for last minute object box processing
-%D we need this in \MKIV.
-
-\ifx\finalizeobjectbox\undefined
- \let\finalizeobjectbox\gobbleoneargument
-\fi
-
-%D Somehow there is a rounding error problem in either \PDFTEX\
-%D or in viewers, or maybe it is conforming the specs. The next
-%D variable compensate for it by removing the rather tight
-%D clip.
-
-\def\objectoffset{1cm}
-
-% \def\dodosetobject#1#2#3%
-% {\bgroup
-% \inobjecttrue
-% \dowithnextbox{\dododosetobject{#1}{#2}{#3}\egroup}}
-
-\def\dodosetobject#1#2#3%
- {\bgroup
- \globalpushmacro\crossreferenceobject \objectreferenced
- \inobjecttrue
- \dowithnextbox
- {\globalpopmacro\crossreferenceobject
- \dododosetobject{#1}{#2}{#3}\egroup}}
-
-\def\dododosetobject#1#2#3%
- {\blabelgroup
- \dontshowcomposition % rather fuzzy in \setxvalue ... \hbox
- \scratchdimen\objectoffset
- \@EA\xdef\csname\r!object#2::#3\endcsname
- {\noexpand\dohandleobject{#2}{#3}%
- {\ifhbox\nextbox\hbox\else\vbox\fi}%
- %{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}%
- {\number\nextboxwd}{\number\nextboxht}{\number\nextboxdp}%
- {\number\scratchdimen}}%
- \expanded % freeze the dimensions since \dostartobject may use \nextbox
- {\dostartobject
- {#2}{#3}{\the\nextboxwd}{\the\nextboxht}{\the\nextboxdp}}%
- \ifcase#1\relax\else \ifdim\objectoffset>\zeropoint
- \setbox\nextbox\vbox spread 2\scratchdimen
- {\forgetall \offinterlineskip
- \vss\hbox spread 2\scratchdimen{\hss\flushnextbox\hss}\vss}%
- \fi \fi
- \flushnextbox
- \dostopobject
- \elabelgroup}
-
-\def\getobject#1#2%
- {\blabelgroup
- \let\dohandleobject\dogetobject
- \csname\r!object#1::#2\endcsname}
-
-% \def\dogetobject#1#2#3#4#5#6%
-% {\initializepaper
-% \forgetall
-% \dontshowcomposition
-% \setbox\scratchbox\vbox
-% {\doinsertobject{#1}{#2}}%
-% \setbox\scratchbox#3%
-% {\vbox to #5\scaledpoint
-% {\ifdim\ht\scratchbox>#5\scaledpoint
-% % or \ifdim\wd\scratchbox>#4\scaledpoint
-% \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
-% \else
-% \vss\box\scratchbox
-% \fi}}%
-% \wd\scratchbox#4\scaledpoint
-% \ht\scratchbox#5\scaledpoint
-% \dp\scratchbox#6\scaledpoint
-% \box\scratchbox
-% \elabelgroup}
-
-% \def\dogetobject#1#2#3#4#5#6#7%
-% {\initializepaper
-% \forgetall
-% \dontshowcomposition
-% \setbox\scratchbox\vbox
-% {\doinsertobject{#1}{#2}}%
-% \setbox\scratchbox#3%
-% {\vbox to #5\scaledpoint
-% {\ifdim\ht\scratchbox>#5\scaledpoint
-% % or \ifdim\wd\scratchbox>#4\scaledpoint
-% \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
-% \else
-% \vss\box\scratchbox
-% \fi}}%
-% \scratchdimen#7\scaledpoint
-% \setbox\nextbox\hbox
-% {\hskip-\scratchdimen\lower\scratchdimen\flushnextbox}%
-% \wd\scratchbox#4\scaledpoint
-% \ht\scratchbox#5\scaledpoint
-% \dp\scratchbox#6\scaledpoint
-% \box\scratchbox
-% \elabelgroup}
-
-\def\dogetobject#1#2#3#4#5#6#7% don't change this, should work for dvi & pdf
- {\initializepaper
- \forgetall
- \dontshowcomposition
- \setbox\scratchbox\vbox
- {\doinsertobject{#1}{#2}}%
- \setbox\scratchbox#3%
- {\vbox to #5\scaledpoint
- {\ifdim\ht\scratchbox>#5\scaledpoint
- \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
- \else\ifdim\wd\scratchbox>#4\scaledpoint
- \vss\hbox to #4\scaledpoint{\hss\box\scratchbox\hss}\vss
- \else
- %\vss\box\scratchbox
- \vss\hbox to #4\scaledpoint{\box\scratchbox\hss}% fix Chof
- \fi\fi}}%
- \box\scratchbox
- \elabelgroup}
-
-%D If needed one can ask for the dimensions of an object with:
-%D
-%D \starttyping
-%D \getobjectdimensions{class}{name}
-%D \stoptyping
-%D
-%D The results are reported in \type {\objectwidth}, \type
-%D {\objectheight} and \type {\objectdepth}.
-
-% \def\dogetobjectdimensions#1#2#3#4#5#6%
-% {\def\objectwidth {#4\s!sp}%
-% \def\objectheight{#5\s!sp}%
-% \def\objectdepth {#6\s!sp}}
-
-\def\dogetobjectdimensions#1#2#3#4#5#6#7%
- {\def\objectwidth {#4\s!sp}%
- \def\objectheight{#5\s!sp}%
- \def\objectdepth {#6\s!sp}%
- \def\objectmargin{#7\s!sp}}
-
-\def\getobjectdimensions#1#2%
- {\let\dohandleobject\dogetobjectdimensions
- \let\objectwidth \!!zeropoint
- \let\objectheight\!!zeropoint
- \let\objectdepth \!!zeropoint
- \labelcsname\r!object#1::#2\endcsname}
-
-%D Apart from this kind of objects, that have typeset content,
-%D we can have low level driver specific objects. Both types
-%D can have references to internal representations, hidden for
-%D the user. We keep track of such references by means of a
-%D dedicated cross reference mechanism. Normally, objects are
-%D defined before they are used, but forward referencing
-%D sometimes occurs.
-%D
-%D \starttyping
-%D \dosetobjectreference {class} {identifier} {reference value} {page}
-%D \dogetobjectreference {class} {identifier} \csname
-%D \stoptyping
-%D
-%D These commands are to be called by the \type{\startobject},
-%D \type{\stopobject} and \type{\insertobject} specials.
-
-\def\objectreferenced{\global\chardef\crossreferenceobject\plusone}
-\def\driverreferenced{\global\chardef\crossreferenceobject\zerocount}
-
-\objectreferenced
-
-% no undefined test ! ! ! ! (pdftex fails on undefined objects)
-
-\def\dosetobjectreference
- {\ifcase\crossreferenceobject
- \objectreferenced
- \expandafter\mkoverloadobjectreference
- \else
- \expandafter\mkregisterobjectreference
- \fi}
-
-\def\dosetdriverreference
- {\driverreferenced\dosetobjectreference}
-
-\def\defaultobjectreference#1#2{0} % driver dependent
-\def\defaultobjectpage #1#2{\realfolio}
-
-\def\dogetobjectreference {\mkgetobjectreference}
-\def\dogetobjectreferencepage{\mkgetobjectreferencepage}
-
-\def\setobject {\driverreferenced\dosetobject1}
-\def\settightobject{\driverreferenced\dosetobject0}
-
-%D \macros
-%D {doifobjectfoundelse,doifobjectreferencefoundelse}
-%D
-%D To prevent redundant definition of objects, one can use
-%D the next tests:
-%D
-%D \starttyping
-%D \doifobjectfoundelse{class}{object}{do then}{do else}
-%D \doifobjectreferencefoundelse{class}{object}{do then}{do else}
-%D \stoptyping
-
-\def\doifobjectfoundelse#1#2%
- {\blabelgroup \ifcsname\r!object#1::#2\endcsname
- \elabelgroup \expandafter\firstoftwoarguments
- \else
- \elabelgroup \expandafter\secondoftwoarguments
- \fi}
-
-\def\doifobjectreferencefoundelse{\mkdoifobjectreferencefoundelse}
-
-%D \macros
-%D {doifobjectssupportedelse}
-%D
-%D Starting with reuse of graphics, we will implement object
-%D reuse when possible. To enable mechanisms to determine
-%D what method to use, we provide:
-%D
-%D \starttyping
-%D \doifobjectssupportedelse{true action}{false action}
-%D \stoptyping
-%D
-%D As we can see, currently objects depend on the special
-%D driver.
-
-\newif\ifobjectssupported \objectssupportedtrue
-
-\def\doifobjectssupportedelse
- {\ifobjectssupported
- \@EA\doifspecialavailableelse\@EA\doinsertobject
- \else
- \@EA\secondoftwoarguments
- \fi}
-
-%D There is a conceptual problem here. Objects are not possible
-%D in \DVI, unless faked like in \type {spec-dvi}. This means
-%D that we must be careful in loading special drivers that do
-%D support objects while we still want to be able to use the
-%D \DVI\ output.
-
-%D Plugin code:
-
-\loadmarkfile{core-obj}
-
-\protect \endinput
diff --git a/tex/context/base/core-par.tex b/tex/context/base/core-par.tex
index aa58ebb1e..0b283b294 100644
--- a/tex/context/base/core-par.tex
+++ b/tex/context/base/core-par.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{ConTeXt Pararaph Tricks}
+\writestatus{loading}{ConTeXt Core Macros / Pararaph Tricks}
\unprotect
diff --git a/tex/context/base/core-pgr.tex b/tex/context/base/core-pgr.tex
index e6f91cec8..ab2378441 100644
--- a/tex/context/base/core-pgr.tex
+++ b/tex/context/base/core-pgr.tex
@@ -2,7 +2,7 @@
%D [ file=core-pgr, % split off core-pos
%D version=1999.08.01,
%D title=\CONTEXT\ Core Macros,
-%D subtitle=Positioning Support,
+%D subtitle=Positioning Graphics,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Positioning Grapics}
+\writestatus{loading}{ConTeXt Core Macros / Positioning Grapics}
%D Before we come to graphics support, we have to make sure of
%D the reference point on the page. The next macro does so and
@@ -898,7 +898,7 @@
\def\calculatenexttextpardimensions
{\docalculatetextpardimensions\nextbtbanchor\nextetbanchor\relax}
-\def\docalculatetextpardimensions#1#2#3%
+\def\docalculatetextpardimensions#1#2#3% todo: dimexpr
{\scratchcounter\MPp#2%\etbanchor
\advance\scratchcounter-\MPp#1%\btanchor
\edef\textparpages{\the\scratchcounter}%
@@ -911,7 +911,7 @@
\scratchdimen \MPy#1%\btanchor
\advance\scratchdimen-\MPy#2%\etbanchor
\advance\scratchdimen-\MPy\textanchor
- \advance\scratchdimen \MPy\textanchor
+ \advance\scratchdimen \MPy\textanchor % - and then + ?
\advance\scratchdimen \MPh\textanchor\relax
\ifcase\scratchcounter>2 \ifnum\scratchcounter<5
% more pages
@@ -1185,7 +1185,7 @@
% \stopbuffer
% \getbuffer \typebuffer \flushstatus \page
-\newdimen\laststackvmove
+\newdimen\laststackvmove % use \scratchdimenone instead of skip
\def\stackeddown
{\bgroup
@@ -1214,7 +1214,7 @@
-\MPd\currentposition % untested
+\MPd\previousposition % untested
+\MPh\currentposition
- \relax
+ \relax\relax % second relax realy needed, forgotten while dimexpressing
% todo: also take depth into account
\ifdim\scratchskip<\scratchdimen
%\registerstatus{no \the\scratchskip}%
diff --git a/tex/context/base/core-pos.lua b/tex/context/base/core-pos.lua
index 212c65190..be2ac1915 100644
--- a/tex/context/base/core-pos.lua
+++ b/tex/context/base/core-pos.lua
@@ -18,6 +18,8 @@ jobpositions = jobpositions or { }
jobpositions.collected = jobpositions.collected or { }
jobpositions.tobesaved = jobpositions.tobesaved or { }
+-- these are global since they are used often at the tex end
+
ptbs, pcol = jobpositions.tobesaved, jobpositions.collected -- global
local function initializer()
@@ -35,7 +37,7 @@ function jobpositions.replace(name,...)
end
function jobpositions.doifelse(name)
- cs.testcase(jobpositions.collected[name] or ptbs[name])
+ commands.testcase(jobpositions.collected[name] or ptbs[name])
end
function jobpositions.MPp(id) local jpi = pcol[id] or ptbs[id] texprint((jpi and jpi[1]) or '0' ) end
diff --git a/tex/context/base/core-pos.mkii b/tex/context/base/core-pos.mkii
index 754673cfa..58784ed7b 100644
--- a/tex/context/base/core-pos.mkii
+++ b/tex/context/base/core-pos.mkii
@@ -11,35 +11,86 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
-
-%D A unique prefix used for storing data.
-
-\def\POSprefix{POS::}
-
-%D Reading form the utility file.
-
-\def\pxypos {\pospxy} % obsolete
-\def\pxyposwhd {\pospxywhd} % obsolete
-\def\pxyposplus{\pospxyplus} % obsolete
+% needs a cleanup, things may change; we also need to move the mp
+% related code to meta-pos
-\def\resetpositions
- {\let\pospxy \gobblefourarguments
- \let\pospxywhd \gobblesevenarguments
- \let\pospxyplus\gobbleeightarguments}
+% shorter tags, ..:achtergrond:.. etc in pos actions
-\def\setpositions
- {\let\pospxy \setpospxy
- \let\pospxywhd \setpospxywhd
- \let\pospxyplus\setpospxyplus}
+% dubbele text- * pos's eruit
-%D We need to initialize.
+% class pos -> als gelijk aan vorige, dan niet niet definieren
+% en erven, maw:
+%
+% 1 -> opslaan
+% 2 -> undef, dus == prev
+% 3 -> undef, dus == prev
+% 4 -> opslaan
+
+\writestatus{loading}{ConTeXt Core Macros / Positioning Support}
+
+% todo: topskip als optie voor eerste regel achtergrond
+% todo: build pos layers on top of layers
+% todo: positionlayer pos van text-1 etc delen
+
+%D Although \TEX\ has a rather powerful channel to the outside
+%D world, called \type {\special}, real communication with
+%D other programs is complicated by the fact that no positional
+%D information is available. Mid 1999, I discussed this with
+%D \THANH, the author of \PDFTEX, and after some experiments,
+%D \PDFTEX\ was extended with a simple but effective mechanism,
+%D that provided positional information. The interesting
+%D thought is that, although \TEX\ is frozen, similar
+%D functionality could have been achieved with \type
+%D {\specials} and an additional \DVI\ postprocessor.
+%D
+%D Since we want to be as compatible as can be, \CONTEXT\ will
+%D support both methods, although the development is primarily
+%D driven by the \PDFTEX\ way of doing things. Since the
+%D mechanism is basically not limited to one application, for
+%D the moment we stick to building the functionality around one
+%D \CONTEXT\ special command, but at the same time we keep our
+%D eyes open for extensions in other directions.
+%D
+%D A question that may arise when one reads this module, is to
+%D what extend these macros are generic, in the sense that they
+%D could be collected in a support module instead of a core
+%D module. Since the mechanism described here will closely
+%D cooperate with the \METAPOST\ support built in \CONTEXT,
+%D which in turn will be tightly integrated with the \CONTEXT\
+%D overlay mechanisms, I decided to write a core module instead
+%D of a support one. This makes even more sense, when one takes
+%D into account that this kind of support depends on special
+%D drivers.
-\resetpositions
+\unprotect
-\addutilityreset{positions}
+%D The first application of positional information was embedded
+%D graphics. Since we are interacting with text, it made sense
+%D to take the current line height and depth into account too.
+%D This is why we have two basic position macros: one for
+%D simple positions, and one for boxes.
+%D
+%D We could have sticked to one special, and actually did so in
+%D earlier experiments, but for convenience, as well for
+%D clearness, we now have two alternatives. This approach will
+%D save us quite some bytes when storing large quantities of
+%D positional information. We save as less information as
+%D needed, that is, we save no dimensions, in a \METAPOST\
+%D friendly way.
+%D
+%D The three specials involved are:
+%D
+%D \starttyping
+%D \dosetposition {identifier}
+%D \dosetpositionwhd {identifier} {width} {height} {depth}
+%D \dosetpositionplus {identifier} {width} {height} {depth} {list}
+%D \dosetpositionpapersize {width} {height}
+%D \stoptyping
+
+\newbox\positionbox
+\newif \ifpositioning
-%D Core set macros:
+\def\POSprefix{POS::}
\def\setpospxy#1#2#3#4%
{\@EA\xdef\csname\POSprefix#1\endcsname
@@ -66,6 +117,35 @@
\the\dimexpr#7\relax,%
#8}}
+%D This is real tricky! The page anchor is applied to the
+%D page box and therefore flushed first. So, when present, it
+%D is applied to all positions except itself.
+
+\chardef\positionanchormode=0 % don't relocate page origin
+\chardef\positionanchormode=1 % relocate page origin once
+
+%D The core set macros.
+
+\def\pxypos {\pospxy} % obsolete
+\def\pxyposwhd {\pospxywhd} % obsolete
+\def\pxyposplus{\pospxyplus} % obsolete
+
+\def\resetpositions
+ {\let\pospxy \gobblefourarguments
+ \let\pospxywhd \gobblesevenarguments
+ \let\pospxyplus\gobbleeightarguments}
+
+\def\setpositions
+ {\let\pospxy \setpospxy
+ \let\pospxywhd \setpospxywhd
+ \let\pospxyplus\setpospxyplus}
+
+%D We need to initialize.
+
+\resetpositions
+
+\addutilityreset{positions}
+
%D Sometimes we want to trick the position handler a bit:
\def\replacepospxywhd#1#2#3#4#5#6#7%
@@ -77,7 +157,55 @@
\the\dimexpr#6\relax,%
\the\dimexpr#7\relax}}
-%D Writing to the utility file.
+%D For postprocessing purposes, we save the number of
+%D positions.
+
+\newcount\currentpositions % current number of positions
+\newcounter\totalnofpositions % total from previous run
+
+\appendtoks
+ \expanded{\savecurrentvalue\noexpand\totalnofpositions{\the\currentpositions}}%
+\to \everybye
+
+%D The next switch can be used to communicate a special
+%D situation. Positioning and associated actions can be
+%D executed any time. However, in for instance backgrounds
+%D they can be collected in a layer, for instance the text
+%D layer (especially the hidden text layer). In the case of
+%D floats, we run into problems, since the page information is
+%D not applicable when the content floats indeed. In such
+%D situations one can treat positions and graphics local.
+
+\newif\iflocalpositioning
+
+%D Watch out: sometimes a pagebreak occurs inside a float
+%D placement, so there we need to disable local mode.
+
+\appendtoks
+ \localpositioningtrue
+\to \everyinsidefloat
+
+\appendtoks
+ \localpositioningfalse
+\to \everypagebody
+
+\def\checkpositions
+ {\startnointerference
+ \protectlabels
+ \doutilities{positions}\jobname\empty\relax\relax
+ \global\let\checkpositions\relax
+ \stopnointerference}
+
+%D Since the positional values are to be fully expandable, we
+%D need to preload them as soon as possible, which is why we
+%D load the data when we start a text.
+
+\appendtoks \checkpositions \to \everystarttext
+
+%D Positions are either generated at a delayed write time
+%D (in \PDFTEX), or derived from the dvi file. The actual
+%D method is implemented in a special driver. If needed, the
+%D driver can fall back on the following macros.
\def\dolazysaveposition#1#2#3#4% tag page x y
{\expanded{\writeutilitycommand{\noexpand\pospxy
@@ -103,6 +231,13 @@
{\expanded{\immediatewriteutilitycommand{\noexpand\pospxyplus
{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}}}
+%D \macros
+%D {MPp, MPx, MPy, MPw, MPh, MPd,
+%D MPxy, MPll, MPlr, MPur, MPul, MPpos}
+%D
+%D Access to the positional information is provided by macros
+%D with short names that are clearly meant for \METAPOST.
+
\def\MPp {\doMPxyhdwlr\doMPp }
\def\MPx {\doMPxyhdwlr\doMPx }
\def\MPy {\doMPxyhdwlr\doMPy }
@@ -136,12 +271,25 @@
#10,0pt,0pt,0pt,0pt,0pt,0pt\relax
\fi}
-% \def\doMPxyhdwlr#1#2% evt kan \s!unknown leeg zijn
-% {\@EA\@EA\@EA#1\csname\POSprefix
-% \ifcsname\POSprefix#2\endcsname#2\else\s!unknown\fi\endcsname
-% ,0pt,0pt,0pt,0pt\relax}
-%
-% \setvalue{\POSprefix\s!unknown}{0,0pt,0pt}
+%D \macros
+%D {MPplus, MPrest, MPv, MPvv}
+%D
+%D Since we will probably keep on extending, we provide a
+%D general extension macro. The plus alternative takes an
+%D extra argument, denoting what additional parameter to pick
+%D up. So, the third extra is fetched with,
+%D
+%D \starttyping
+%D \MPplus{identifier}{3}{default}
+%D \stoptyping
+%D
+%D All extras (comma separated) are fetched with:
+%D
+%D \starttyping
+%D \MPrest{identifier}
+%D \stoptyping
+%D
+%D The extra parameters are not treated.
\def\MPplus {\MPdoplus\doMPplus}
\def\MPrest#1{\MPdoplus\doMPrest{#1}{}}
@@ -165,7 +313,177 @@
\def\doMPrest#1,#2,#3,#4,#5,#6,#7,,#8\relax#9%
{#7}
-%D Testing:
+%D \macros
+%D {MPanchor}
+%D
+%D For readability we define a few synonyms:
+
+\def\MPanchor{\MPpos}
+
+%D \macros
+%D {POSp, POSx, POSy, POSh, POSd, POSw}
+%D
+%D and:
+
+\def\POSp{\MPp} \def\POSx{\MPx} \def\POSy{\MPy}
+\def\POSh{\MPh} \def\POSd{\MPd} \def\POSw{\MPw}
+
+%D There are two low level positioning macros. Both store the
+%D position as well as execute an action associated with that
+%D position.
+
+\def\initializenextposition
+ {\ifpositioning \else
+ \global\positioningtrue
+ \dosetpositionpapersize
+ {\printpaperwidth }%
+ {\printpaperheight}%
+ \fi
+ \global\advance\currentpositions\plusone}
+
+\def\setpositiononly#1%
+ {\iftrialtypesetting
+ % nothing
+ \else
+ \initializenextposition
+ \def\currentposition{#1}%
+ \dosetposition\currentposition
+ \fi}
+
+\def\setposition#1%
+ {\iftrialtypesetting
+ % nothing
+ \else
+ \initializenextposition
+ \def\currentposition{#1}%
+ \dosetposition\currentposition
+ \traceposstring\llap\green{\currentposition>}%
+ \dopositionaction\currentposition
+ \fi}
+
+\def\setpositiondata#1#2#3#4%
+ {\iftrialtypesetting \else
+ \initializenextposition
+ \hbox
+ {\def\currentposition{#1}%
+ \dosetpositionwhd\currentposition
+ {\the\dimexpr#2\relax}%
+ {\the\dimexpr#3\relax}%
+ {\the\dimexpr#4\relax}%
+ \traceposstring\llap\green{\currentposition>}%
+ \dopositionaction\currentposition
+ \hss}%
+ \fi}
+
+\def\setpositionbox#1%
+ {\dowithnextbox
+ {\iftrialtypesetting
+ \flushnextbox
+ \else
+ \initializenextposition
+ \hbox to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionwhd\currentposition
+ {\the\nextboxwd}%
+ {\the\nextboxht}%
+ {\the\nextboxdp}%
+ \traceposstring\llap\green{\currentposition>}%
+ \setbox\positionbox\flushnextbox
+ \dopositionaction\currentposition
+ \box\positionbox
+ \hss}%
+ \fi}}
+
+\def\setpositiondataplus#1#2#3#4#5%
+ {\iftrialtypesetting \else
+ \initializenextposition
+ \hbox % bug: to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionplus\currentposition
+ {\the\dimexpr#2\relax}%
+ {\the\dimexpr#3\relax}%
+ {\the\dimexpr#4\relax}%
+ {#5}%
+ \traceposstring\rlap\magenta{<\currentposition}%
+ \dopositionaction\currentposition
+ \hss}%
+ \fi}
+
+\def\setpositionplus#1#2%
+ {\dowithnextbox
+ {\iftrialtypesetting
+ \flushnextbox
+ \else
+ \initializenextposition
+ \hbox to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionplus\currentposition
+ {\the\nextboxwd}%
+ {\the\nextboxht}%
+ {\the\nextboxdp}%
+ {#2}%
+ \traceposstring\rlap\magenta{<\currentposition}%
+ \setbox\positionbox\flushnextbox
+ \dopositionaction\currentposition
+ \box\positionbox
+ \hss}%
+ \fi}}
+
+\let\currentposition\s!unknown
+
+%D A few more low level macros take care of defining and
+%D recalling actions. We could save this information in the
+%D position containers themselves, this would save hash
+%D entries, but at the cost of much more time consuming
+%D expansion. Actions are saved globally!
+
+\newtoks\everypositionaction
+
+\let\POSactionprefix\POSprefix
+
+\def\dosetpositionaction#1%
+ {\setgvalue{\POSactionprefix#1::}}
+
+%D The lists can become quite long (also because there can
+%D be lots of parameters passed on) so we provide a hook
+%D to clean up the list afterwards.
+
+\let\cleanuppositionaction\gobbleoneargument
+
+\def\doifpositionaction#1%
+ {\ifcsname\POSactionprefix#1::\endcsname
+ \@EA\firstofoneargument
+ \else
+ \@EA\gobbleoneargument
+ \fi}
+
+\def\doifpositionactionelse#1%
+ {\ifcsname\POSactionprefix#1::\endcsname
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+%D We can copy a position with:
+%D
+%D \starttyping
+%D \copyposition {to} {from}
+%D \stoptyping
+%D
+%D Again, this is a global action.
+
+\def\copyposition#1#2%
+ {\ifcsname\POSprefix#2\endcsname
+ \global\@EA\let\csname\POSprefix#1\@EA\endcsname\csname\POSprefix#2\endcsname
+ \fi}
+
+%D The fact that handling positions is a two pass operation, is
+%D one of the reasons why we need to be able to test for
+%D existence, using:
+%D
+%D \starttyping
+%D \doifpositionelse {identifier} {found action} {not found action}
+%D \stoptyping
\def\doifpositionelse#1%
{\ifcsname\POSprefix#1\endcsname
@@ -174,11 +492,382 @@
\expandafter\secondoftwoarguments
\fi}
-%D Copying:
+%D We have now arrived at a few macros that would make sense as
+%D support macros, but ended up in the core.
+
+%D \macros
+%D {xypos}
+%D
+%D We have several macros available to save positions. Later
+%D we will see applications.
+%D
+%D \starttabulate[|l|l||]
+%D \NC \type {\xypos} \NC \NC simple position with no dimensions \NC \NR
+%D \NC \type {\hpos} \NC \NC position and characteristics of a \type {\hbox} \NC \NR
+%D \NC \type {\vpos} \NC \NC position and characteristics of a \type {\vbox} \NC \NR
+%D \NC \type {\bpos} \NC b: \NC begin point in a line \NC \NR
+%D \NC \type {\epos} \NC e: \NC end point in a line \NC \NR
+%D \NC \type {\fpos} \NC f: \NC begin point in a paragraph \NC \NR
+%D \NC \type {\tpos} \NC t: \NC end point in a paragraph \NC \NR
+%D \stoptabulate
+%D
+%D Each macro takes an identifier as argument, and the \type
+%D {\hpos} and \type {\vpos} also expect box content.
+
+% \def\xypos{\initializenextposition\dosetposition}
+
+\let\xypos\setpositiononly
+
+\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox}
+\def\vpos#1{\setpositionbox{#1}\vbox}
+
+\def\bpos#1{\hpos{b:#1}{\strut}\ignorespaces}
+\def\epos#1{\removelastspace\hpos{e:#1}{\strut}}
+
+\def\fpos#1%
+ {\setpositionplus{b:#1}{\number\parposcounter}\horizontalstrut
+ \ignorespaces}
+
+\def\tpos#1%
+ {\removelastspace
+ \setpositionplus{e:#1}{\number\parposcounter}\horizontalstrut}
+
+\def\ffpos#1%
+ {\setpositionplus{b:#1}{\number\parposcounter}\horizontalstrut\wpos{#1}%
+ \ignorespaces}
+
+\def\ttpos#1%
+ {\removelastspace
+ \setpositionplus{e:#1}{\number\parposcounter}\horizontalstrut}
+
+\def\wpos#1%
+ {\dontleavehmode\vadjust % may disappear if buried
+ {\setbox0\hbox{\raise\strutdp\hbox{\rawwpos{#1}}}%
+ \rlap{\smashedbox0}}}
+
+\def\wwpos#1% \hsmashed{\llap{\rawwpos{#1}}}
+ {\rlap
+ {\setbox0\hbox{\rawwpos{#1}}%
+ \smashedbox0}}
+
+\def\rawwpos#1%
+ {\hpos{w:#1}
+ {\strut
+ \hskip-\leftskip
+ \hskip\hsize
+ \hskip-\rightskip}}
+
+% the next macro disables par positions (in inner boxes) and
+% only registers the width
+
+\def\setinnerparpositions
+ {\let\fpos\ffpos
+ \let\tpos\ttpos
+ \let\wpos\wwpos}
+
+% example of usage: (see for application "techniek")
+%
+% \appendtoks
+% \setinnerparpositions
+% \to \everytabulate
+
+%D When we want to calculate more complex backgrounds, we
+%D need to know what the current indentation scheme is. At
+%D the cost of many positions and memory, we can keep track
+%D of them. This mechanism is activated automatically
+%D based on information collected in the previous pass.
+
+\newcount\parposcounter
+
+\newif\ifpositioningpar
+
+% we can check for used entries, and if not, then not add one
+
+\def\registerparoptions
+ {\ifpositioningpar \ifpositioning \iftrialtypesetting \else
+ \ifinpagebody \else \ifmmode \else \ifinformula \else
+ \ifprocessingverbatim
+ \iflinepar \doregisterparoptions \fi
+ \else
+ \doregisterparoptions
+ \fi
+ \fi \fi \fi
+ \fi \fi \fi}
+
+\chardef\parposstrut=1 % 0 => no strut data, so fall backs used
+
+\newif\iftracepositions
+
+% \def\doregisterparoptions
+% {\global\advance\parposcounter\plusone
+% \begingroup
+% \leftskip 1\leftskip
+% \rightskip1\rightskip
+% \setpositiondataplus
+% {p:\number\parposcounter}% identifier
+% {\the\zeropoint}%
+% {\the\strutht}%
+% {\the\strutdp}%
+% {\the\hsize ,% 1
+% \the\leftskip ,% 2
+% \the\rightskip ,% 3
+% \the\hangindent,% 4
+% \the\hangafter ,% 5 (num)
+% \the\parindent }% 6
+% %\normalhbox{\registerparsymbol}%
+% \registerparsymbol
+% \endgroup}
+
+\def\doregisterparoptions
+ {\global\advance\parposcounter\plusone
+ \setpositiondataplus
+ {p:\number\parposcounter}% identifier
+ {\the\zeropoint}%
+ {\the\strutht}%
+ {\the\strutdp}%
+ {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}%
+ %\normalhbox{\registerparsymbol}%
+ \iftracepositions\registerparsymbol\fi}
+
+\def\traceposstring#1#2#3%
+ {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi}
+
+\def\registerparsymbol
+ {\iftracepositions
+ \smashedhbox to \zeropoint
+ {\hss
+ \startcolor[blue]%
+ \llap{\infofont\number\parposcounter}%
+ \scratchdimen\onepoint
+ \vrule
+ \!!width 4\scratchdimen
+ \!!height2\scratchdimen
+ \!!depth 2\scratchdimen
+ \stopcolor
+ \hss}%
+ \fi}
+
+% \appendtoks \registerparoptions \to \everypar
+
+%D Eperimental code, don't use this yet: (must be sped up anyway)
+
+\def\@@noden{node:n:}
+\def\@@nodeo{node:o:}
+\def\@@nodep{node:p:}
+
+\def\doifelsenodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\nextnodelocation#1%
+ {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi}
-\def\copyposition#1#2%
- {\ifcsname\POSprefix#2\endcsname
- \global\@EA\let\csname\POSprefix#1\@EA\endcsname\csname\POSprefix#2\endcsname
+\def\newnodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \setcounter{\@@noden#1}\zerocount
+ \letgvalue {\@@nodeo#1}\!!zerocount
\fi}
+\def\tagnodelocation#1%
+ {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi}
+
+\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}}
+\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}}
+\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}}
+
+\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}}
+\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}}
+\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}}
+
+\def\getnodelocationn#1{\countervalue{\@@noden#1}}
+\def\getnodelocationo#1{\getvalue {\@@nodeo#1}}
+
+\chardef\nodelocationmode\plusone
+
+\def\analyzenodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount
+ \fi}
+
+\def\doanalyzenodelocation#1#2#3% class n default
+ {\begingroup
+ \donefalse
+ \ifcase\nodelocationmode
+ % do nothing
+ \else
+ \edef\nodelocationselfn{#2}%
+ \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}%
+ \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}%
+ \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}%
+ \scratchcounter\plusone
+ \doloop
+ {\ifnum\recurselevel=\nodelocationselfn\relax
+ \donetrue
+ \else
+ \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}%
+ \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}%
+ \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}%
+ \ifcase\nodelocationmode
+ \or
+ % ok for single column
+ \ifcase\nodelocationotherp\relax
+ \exitloop
+ \else\ifnum\nodelocationotherp<\nodelocationselfp\relax
+ \donetrue \advance\scratchcounter\plusone
+ \else\ifnum\nodelocationotherp>\nodelocationselfp\relax
+ % skip
+ \else\ifdim\nodelocationothery>\nodelocationselfy\relax
+ \donetrue \advance\scratchcounter\plusone
+ \else\ifdim\nodelocationothery<\nodelocationselfy\relax
+ % skip
+ \else\ifdim\nodelocationotherx<\nodelocationselfx\relax
+ \donetrue \advance\scratchcounter\plusone
+ \fi\fi\fi\fi\fi\fi
+ \or
+ % acceptable for double column
+ \ifcase\nodelocationotherp\relax
+ \exitloop
+ \else\ifnum\nodelocationotherp<\nodelocationselfp\relax
+ \donetrue \advance\scratchcounter\plusone
+ \else\ifnum\nodelocationotherp>\nodelocationselfp\relax
+ % skip
+ \else\ifnum\recurselevel>\nodelocationselfn\relax
+ \donetrue \exitloop
+ \else
+ \donetrue \advance\scratchcounter\plusone
+ \fi\fi\fi\fi
+ \else
+ \exitloop
+ \fi
+ \fi}%
+ \fi
+ \ifdone \else
+ \scratchcounter#3\relax
+ \fi
+ \setxvalue{\@@nodeo#1}{\the\scratchcounter}%
+ \endgroup}
+
+\unexpanded\def\shownodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \analyzenodelocation{#1}%
+ (#1,%
+ n:\getnodelocationn{#1},%
+ p:\getnodelocationp{#1},%
+ x:\getnodelocationx{#1},%
+ y:\getnodelocationy{#1},%
+ o:\getnodelocationo{#1})%
+ \fi}
+
+%D \macros
+%D {doifoverlappingelse}
+%D
+%D A first application of positional information, is to
+%D determine if two boxes do overlap:
+%D
+%D \starttyping
+%D \doifoverlappingelse{point a}{point b}
+%D {action when overlapping}
+%D {action when not overlapping}
+%D \stoptyping
+
+\def\overlappingmargin{-2\scaledpoint}
+
+\def\doifoverlappingelse#1#2%
+ {\begingroup
+ \donefalse
+ \edef\!!stringa{#1}\edef\!!stringb{#2}%
+ \ifnum\MPp\!!stringa=\MPp\!!stringb\relax
+ \!!dimena\MPx\!!stringa
+ \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax
+ \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax
+ \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax
+ \!!dimene\MPx\!!stringb
+ \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax
+ \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax
+ \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax
+ \ifdim\overlappingmargin=\zeropoint\else
+ \advance\!!dimena-\overlappingmargin
+ \advance\!!dimenb+\overlappingmargin
+ \advance\!!dimenc-\overlappingmargin
+ \advance\!!dimend+\overlappingmargin
+ \advance\!!dimene-\overlappingmargin
+ \advance\!!dimenf+\overlappingmargin
+ \advance\!!dimeng-\overlappingmargin
+ \advance\!!dimenh+\overlappingmargin
+ \fi
+ % more often eh fb eg fg
+ \def\checkone##1##2%
+ {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else
+ \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else
+ \donetrue
+ \fi\fi
+ \fi\fi}%
+ \def\checktwo##1##2%
+ {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else
+ \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else
+ \donetrue
+ \fi\fi
+ \fi\fi}%
+ \checkone\!!dimene\!!dimeng \ifdone \else
+ \checkone\!!dimene\!!dimenh \ifdone \else
+ \checkone\!!dimenf\!!dimeng \ifdone \else
+ \checkone\!!dimenf\!!dimenh \ifdone \else
+ \checktwo\!!dimena\!!dimenc \ifdone \else
+ \checktwo\!!dimena\!!dimend \ifdone \else
+ \checktwo\!!dimenb\!!dimene \ifdone \else
+ \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi
+ \fi
+ \ifdone
+ \endgroup\expandafter\firstoftwoarguments
+ \else
+ \endgroup\expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doifpositionsonsamepageelse,
+%D doifpositionsonthispageelse}
+%D
+%D Instead of letting the user handle fuzzy expansion, we
+%D provide a simple test on positione being on the same page.
+%D
+%D \starttyping
+%D \doifpositionsonsamepageelse{point a}{point b}
+%D {action when on same page}
+%D {action when not on same page}
+%D \doifpositionsonthispageelse{point a}{point b}
+%D {action when on this page}
+%D {action when not on this page}
+%D \stoptyping
+
+\def\dodoifpositionsonsamepageelse#1#2#3#4%
+ {\bgroup
+ \scratchcounter#1\donefalse
+ \def\docommand##1%
+ {\ifcase\scratchcounter
+ \scratchcounter\MPp{##1}\donetrue
+ \else
+ \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi
+ \fi}%
+ \rawprocesscommalist[#2]\docommand
+ \ifdone\egroup#3\else\egroup#4\fi}
+
+\def\doifpositionsonsamepageelse
+ {\dodoifpositionsonsamepageelse{0}}
+
+\def\doifpositionsonthispageelse#1#2#3%
+ {\dodoifpositionsonsamepageelse\realfolio}
+
+%D Plugins:
+
+\let\MPv \MPplus
+\let\MPvv\MPrest
+
+\let\MPanchor\MPpos
+
+\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy
+\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw
+
\protect \endinput
diff --git a/tex/context/base/core-pos.mkiv b/tex/context/base/core-pos.mkiv
index 860a7a967..16d5b229f 100644
--- a/tex/context/base/core-pos.mkiv
+++ b/tex/context/base/core-pos.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-pos,
-%D version=2006.09.18,
+%D version=1999.08.01,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Positioning Support,
%D author=Hans Hagen,
@@ -11,7 +11,22 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
+% needs a cleanup, things may change; we also need to move the mp
+% related code to meta-pos
+
+% shorter tags, ..:achtergrond:.. etc in pos actions
+
+% dubbele text- * pos's eruit
+
+% class pos -> als gelijk aan vorige, dan niet niet definieren
+% en erven, maw:
+%
+% 1 -> opslaan
+% 2 -> undef, dus == prev
+% 3 -> undef, dus == prev
+% 4 -> opslaan
+
+\writestatus{loading}{ConTeXt Core Macros / Positioning Support}
% saveposition : tag page x y
% savepositionwhd : tag page x y w h d
@@ -27,12 +42,71 @@
\registerctxluafile{core-pos}{1.001}
-% \def\dolazysaveposition #1#2#3#4{\expanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4"}}}}
-% \def\dolazysavepositionwhd #1#2#3#4#5#6#7{\expanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}}
-% \def\dolazysavepositionplus#1#2#3#4#5#6#7#8{\expanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}}
-% \def\dosaveposition #1#2#3#4{\expanded{\ctxlua {ptbs['#1']={#2,"#3","#4"}}}}
-% \def\dosavepositionwhd #1#2#3#4#5#6#7{\expanded{\ctxlua {ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}}
-% \def\dosavepositionplus #1#2#3#4#5#6#7#8{\expanded{\ctxlua {ptbs['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}}
+% todo: topskip als optie voor eerste regel achtergrond
+% todo: build pos layers on top of layers
+% todo: positionlayer pos van text-1 etc delen
+
+%D Although \TEX\ has a rather powerful channel to the outside
+%D world, called \type {\special}, real communication with
+%D other programs is complicated by the fact that no positional
+%D information is available. Mid 1999, I discussed this with
+%D \THANH, the author of \PDFTEX, and after some experiments,
+%D \PDFTEX\ was extended with a simple but effective mechanism,
+%D that provided positional information. The interesting
+%D thought is that, although \TEX\ is frozen, similar
+%D functionality could have been achieved with \type
+%D {\specials} and an additional \DVI\ postprocessor.
+%D
+%D Since we want to be as compatible as can be, \CONTEXT\ will
+%D support both methods, although the development is primarily
+%D driven by the \PDFTEX\ way of doing things. Since the
+%D mechanism is basically not limited to one application, for
+%D the moment we stick to building the functionality around one
+%D \CONTEXT\ special command, but at the same time we keep our
+%D eyes open for extensions in other directions.
+%D
+%D A question that may arise when one reads this module, is to
+%D what extend these macros are generic, in the sense that they
+%D could be collected in a support module instead of a core
+%D module. Since the mechanism described here will closely
+%D cooperate with the \METAPOST\ support built in \CONTEXT,
+%D which in turn will be tightly integrated with the \CONTEXT\
+%D overlay mechanisms, I decided to write a core module instead
+%D of a support one. This makes even more sense, when one takes
+%D into account that this kind of support depends on special
+%D drivers.
+
+\unprotect
+
+%D The first application of positional information was embedded
+%D graphics. Since we are interacting with text, it made sense
+%D to take the current line height and depth into account too.
+%D This is why we have two basic position macros: one for
+%D simple positions, and one for boxes.
+%D
+%D We could have sticked to one special, and actually did so in
+%D earlier experiments, but for convenience, as well for
+%D clearness, we now have two alternatives. This approach will
+%D save us quite some bytes when storing large quantities of
+%D positional information. We save as less information as
+%D needed, that is, we save no dimensions, in a \METAPOST\
+%D friendly way.
+%D
+%D The three specials involved are:
+%D
+%D \starttyping
+%D \dosetposition {identifier}
+%D \dosetpositionwhd {identifier} {width} {height} {depth}
+%D \dosetpositionplus {identifier} {width} {height} {depth} {list}
+%D \dosetpositionpapersize {width} {height}
+%D \stoptyping
+%D
+%D Positions are either generated at a delayed write time
+%D (in \PDFTEX), or derived from the dvi file. The actual
+%D method is implemented in a special driver. If needed, the
+%D driver can fall back on the following macros.
+
+% TO BE MERGED
\def\dolazysaveposition #1#2#3#4{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4"}}}}
\def\dolazysavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlatelua{ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}}
@@ -41,10 +115,131 @@
\def\dosavepositionwhd #1#2#3#4#5#6#7{\normalexpanded{\ctxlua {ptbs['#1']={#2,"#3","#4","#5","#6","#7"}}}}
\def\dosavepositionplus #1#2#3#4#5#6#7#8{\normalexpanded{\ctxlua {ptbs['#1']={#2,"#3","#4","#5","#6","#7","#8"}}}}
-\def\doifpositionelse #1{\ctxlua{jobpositions.doifelse('#1')}}
-\def\copyposition #1#2{\ctxlua{jobpositions.copy('#1','#2')}}
+% \def\dosetposition#1%
+% {\pdfsavepos
+% \dolazysaveposition
+% {#1}%
+% {\noexpand\realfolio}%
+% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}%
+% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}}%
+%
+% \def\dosetpositionwhd#1#2#3#4%
+% {\pdfsavepos
+% \dolazysavepositionwhd
+% {#1}%
+% {\noexpand\realfolio}%
+% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}%
+% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}%
+% {#2}{#3}{#4}}
+%
+% \def\dosetpositionplus#1#2#3#4#5%
+% {\pdfsavepos
+% \dolazysavepositionplus
+% {#1}%
+% {\noexpand\realfolio}%
+% {\noexpand\the\dimexpr\pdflastxpos\scaledpoint\relax}%
+% {\noexpand\the\dimexpr\pdflastypos\scaledpoint\relax}%
+% {#2}{#3}{#4}{#5}}
+
+\def\lastsavedpositionx {\the\dimexpr\pdflastxpos\scaledpoint\relax}
+\def\lastsavedpositiony {\the\dimexpr\pdflastypos\scaledpoint\relax}
+\let\savecurrentposition\pdfsavepos
+
+\def\dosetposition#1%
+ {\savecurrentposition
+ \normalexpanded{\ctxlatelua{ptbs['#1']={%
+ \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony"}}}}
+
+\def\dosetpositionwhd#1#2#3#4%
+ {\savecurrentposition
+ \normalexpanded{\ctxlatelua{ptbs['#1']={%
+ \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4"}}}}
+
+\def\dosetpositionplus#1#2#3#4#5%
+ {\savecurrentposition
+ \normalexpanded{\ctxlatelua{ptbs['#1']={%
+ \noexpand\realfolio,"\noexpand\lastsavedpositionx","\noexpand\lastsavedpositiony","#2","#3","#4","#5"}}}}
+
+\let\dosetpositionpapersize\gobbletwoarguments
+
+\newbox\positionbox
+\newif \ifpositioning
+
+\def\POSprefix{POS::}
+
+\let\setpospx \gobblefourarguments % suppress errors with mkii tuo file
+\let\setpospxywhd \gobblesevenarguments % suppress errors with mkii tuo file
+\let\setpospxyplus\gobbleeightarguments % suppress errors with mkii tuo file
+
+%D This is real tricky! The page anchor is applied to the
+%D page box and therefore flushed first. So, when present, it
+%D is applied to all positions except itself.
+
+\chardef\positionanchormode=0 % don't relocate page origin
+\chardef\positionanchormode=1 % relocate page origin once
+
+%D The core set macros.
+
+\let\pospxy \gobblefourarguments
+\let\pospxywhd \gobblesevenarguments
+\let\pospxyplus\gobbleeightarguments
+
+%D Sometimes we want to trick the position handler a bit:
+
\def\replacepospxywhd#1#2#3#4#5#6#7{\ctxlua{jobpositions.replace('#1',\number#2,"\the\dimexpr#3\relax","\the\dimexpr#4\relax","\the\dimexpr#5\relax","\the\dimexpr#6\relax","\the\dimexpr#7\relax")}}
+%D For postprocessing purposes, we save the number of
+%D positions.
+
+\newcount\currentpositions % current number of positions
+\newcounter\totalnofpositions % total from previous run
+
+\appendtoks
+ \expanded{\savecurrentvalue\noexpand\totalnofpositions{\the\currentpositions}}%
+\to \everybye
+
+%D The next switch can be used to communicate a special
+%D situation. Positioning and associated actions can be
+%D executed any time. However, in for instance backgrounds
+%D they can be collected in a layer, for instance the text
+%D layer (especially the hidden text layer). In the case of
+%D floats, we run into problems, since the page information is
+%D not applicable when the content floats indeed. In such
+%D situations one can treat positions and graphics local.
+
+\newif\iflocalpositioning
+
+%D Watch out: sometimes a pagebreak occurs inside a float
+%D placement, so there we need to disable local mode.
+
+\appendtoks
+ \localpositioningtrue
+\to \everyinsidefloat
+
+\appendtoks
+ \localpositioningfalse
+\to \everypagebody
+
+\def\checkpositions
+ {\startnointerference
+ \protectlabels
+ \doutilities{positions}\jobname\empty\relax\relax
+ \global\let\checkpositions\relax
+ \stopnointerference}
+
+%D Since the positional values are to be fully expandable, we
+%D need to preload them as soon as possible, which is why we
+%D load the data when we start a text.
+
+\appendtoks \checkpositions \to \everystarttext
+
+%D \macros
+%D {MPp, MPx, MPy, MPw, MPh, MPd,
+%D MPxy, MPll, MPlr, MPur, MPul, MPpos}
+%D
+%D Access to the positional information is provided by macros
+%D with short names that are clearly meant for \METAPOST.
+
\def\MPp #1{\ctxlua{jobpositions.MPp("#1")}}
\def\MPx #1{\ctxlua{jobpositions.MPx("#1")}}
\def\MPy #1{\ctxlua{jobpositions.MPy("#1")}}
@@ -57,7 +252,577 @@
\def\MPur #1{\ctxlua{jobpositions.MPur("#1")}}
\def\MPul #1{\ctxlua{jobpositions.MPul("#1")}}
\def\MPpos #1{\ctxlua{jobpositions.MPpos("#1")}}
-\def\MPplus#1#2#3{\ctxlua{jobpositions.MPplus("#1",#2,"#3")}}
-\def\MPrest #1#2{\ctxlua{jobpositions.MPrest("#1","#2")}}
+
+%D \macros
+%D {MPplus, MPrest, MPv, MPvv}
+%D
+%D Since we will probably keep on extending, we provide a
+%D general extension macro. The plus alternative takes an
+%D extra argument, denoting what additional parameter to pick
+%D up. So, the third extra is fetched with,
+%D
+%D \starttyping
+%D \MPplus{identifier}{3}{default}
+%D \stoptyping
+%D
+%D All extras (comma separated) are fetched with:
+%D
+%D \starttyping
+%D \MPrest{identifier}
+%D \stoptyping
+%D
+%D The extra parameters are not treated.
+
+\def\MPplus#1#2#3{\ctxlua{jobpositions.MPplus("#1",#2,"#3")}} \let\MPv \MPplus
+\def\MPrest #1#2{\ctxlua{jobpositions.MPrest("#1","#2")}} \let\MPvv\MPrest
+
+%D \macros
+%D {MPanchor}
+%D
+%D For readability we define a few synonyms:
+
+\def\MPanchor{\MPpos}
+
+%D \macros
+%D {POSp, POSx, POSy, POSh, POSd, POSw}
+%D
+%D and:
+
+\def\POSp{\MPp} \def\POSx{\MPx} \def\POSy{\MPy}
+\def\POSh{\MPh} \def\POSd{\MPd} \def\POSw{\MPw}
+
+%D There are two low level positioning macros. Both store the
+%D position as well as execute an action associated with that
+%D position.
+
+\def\initializenextposition
+ {\ifpositioning \else
+ \global\positioningtrue
+ \dosetpositionpapersize
+ {\printpaperwidth }%
+ {\printpaperheight}%
+ \fi
+ \global\advance\currentpositions\plusone}
+
+\def\setpositiononly#1%
+ {\iftrialtypesetting
+ % nothing
+ \else
+ \initializenextposition
+ \def\currentposition{#1}%
+ \dosetposition\currentposition
+ \fi}
+
+\def\setposition#1%
+ {\iftrialtypesetting
+ % nothing
+ \else
+ \initializenextposition
+ \def\currentposition{#1}%
+ \dosetposition\currentposition
+ \traceposstring\llap\green{\currentposition>}%
+ \dopositionaction\currentposition
+ \fi}
+
+\def\setpositiondata#1#2#3#4%
+ {\iftrialtypesetting \else
+ \initializenextposition
+ \hbox
+ {\def\currentposition{#1}%
+ \dosetpositionwhd\currentposition
+ {\the\dimexpr#2\relax}%
+ {\the\dimexpr#3\relax}%
+ {\the\dimexpr#4\relax}%
+ \traceposstring\llap\green{\currentposition>}%
+ \dopositionaction\currentposition
+ \hss}%
+ \fi}
+
+\def\setpositionbox#1%
+ {\dowithnextbox
+ {\iftrialtypesetting
+ \flushnextbox
+ \else
+ \initializenextposition
+ \hbox to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionwhd\currentposition
+ {\the\nextboxwd}%
+ {\the\nextboxht}%
+ {\the\nextboxdp}%
+ \traceposstring\llap\green{\currentposition>}%
+ \setbox\positionbox\flushnextbox
+ \dopositionaction\currentposition
+ \box\positionbox
+ \hss}%
+ \fi}}
+
+\def\setpositiondataplus#1#2#3#4#5%
+ {\iftrialtypesetting \else
+ \initializenextposition
+ \hbox % bug: to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionplus\currentposition
+ {\the\dimexpr#2\relax}%
+ {\the\dimexpr#3\relax}%
+ {\the\dimexpr#4\relax}%
+ {#5}%
+ \traceposstring\rlap\magenta{<\currentposition}%
+ \dopositionaction\currentposition
+ \hss}%
+ \fi}
+
+\def\setpositionplus#1#2%
+ {\dowithnextbox
+ {\iftrialtypesetting
+ \flushnextbox
+ \else
+ \initializenextposition
+ \hbox to \nextboxwd
+ {\edef\currentposition{#1}%
+ \dosetpositionplus\currentposition
+ {\the\nextboxwd}%
+ {\the\nextboxht}%
+ {\the\nextboxdp}%
+ {#2}%
+ \traceposstring\rlap\magenta{<\currentposition}%
+ \setbox\positionbox\flushnextbox
+ \dopositionaction\currentposition
+ \box\positionbox
+ \hss}%
+ \fi}}
+
+\let\currentposition\s!unknown
+
+%D A few more low level macros take care of defining and
+%D recalling actions. We could save this information in the
+%D position containers themselves, this would save hash
+%D entries, but at the cost of much more time consuming
+%D expansion. Actions are saved globally!
+
+\newtoks\everypositionaction
+
+\let\POSactionprefix\POSprefix
+
+\def\dosetpositionaction#1%
+ {\setgvalue{\POSactionprefix#1::}}
+
+%D The lists can become quite long (also because there can
+%D be lots of parameters passed on) so we provide a hook
+%D to clean up the list afterwards.
+
+\let\cleanuppositionaction\gobbleoneargument
+
+\def\doifpositionaction#1%
+ {\ifcsname\POSactionprefix#1::\endcsname
+ \@EA\firstofoneargument
+ \else
+ \@EA\gobbleoneargument
+ \fi}
+
+\def\doifpositionactionelse#1%
+ {\ifcsname\POSactionprefix#1::\endcsname
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+%D We can copy a position with:
+%D
+%D \starttyping
+%D \copyposition {to} {from}
+%D \stoptyping
+%D
+%D Again, this is a global action.
+
+\def\copyposition#1#2{\ctxlua{jobpositions.copy('#1','#2')}}
+
+%D The fact that handling positions is a two pass operation, is
+%D one of the reasons why we need to be able to test for
+%D existence, using:
+%D
+%D \starttyping
+%D \doifpositionelse {identifier} {found action} {not found action}
+%D \stoptyping
+
+\def\doifpositionelse#1{\ctxlua{jobpositions.doifelse('#1')}}
+
+%D We have now arrived at a few macros that would make sense as
+%D support macros, but ended up in the core.
+
+%D \macros
+%D {xypos}
+%D
+%D We have several macros available to save positions. Later
+%D we will see applications.
+%D
+%D \starttabulate[|l|l||]
+%D \NC \type {\xypos} \NC \NC simple position with no dimensions \NC \NR
+%D \NC \type {\hpos} \NC \NC position and characteristics of a \type {\hbox} \NC \NR
+%D \NC \type {\vpos} \NC \NC position and characteristics of a \type {\vbox} \NC \NR
+%D \NC \type {\bpos} \NC b: \NC begin point in a line \NC \NR
+%D \NC \type {\epos} \NC e: \NC end point in a line \NC \NR
+%D \NC \type {\fpos} \NC f: \NC begin point in a paragraph \NC \NR
+%D \NC \type {\tpos} \NC t: \NC end point in a paragraph \NC \NR
+%D \stoptabulate
+%D
+%D Each macro takes an identifier as argument, and the \type
+%D {\hpos} and \type {\vpos} also expect box content.
+
+% \def\xypos{\initializenextposition\dosetposition}
+
+\let\xypos\setpositiononly
+
+\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox}
+\def\vpos#1{\setpositionbox{#1}\vbox}
+
+\def\bpos#1{\hpos{b:#1}{\strut}\ignorespaces}
+\def\epos#1{\removelastspace\hpos{e:#1}{\strut}}
+
+\def\fpos#1%
+ {\setpositionplus{b:#1}{\number\parposcounter}\horizontalstrut
+ \ignorespaces}
+
+\def\tpos#1%
+ {\removelastspace
+ \setpositionplus{e:#1}{\number\parposcounter}\horizontalstrut}
+
+\def\ffpos#1%
+ {\setpositionplus{b:#1}{\number\parposcounter}\horizontalstrut\wpos{#1}%
+ \ignorespaces}
+
+\def\ttpos#1%
+ {\removelastspace
+ \setpositionplus{e:#1}{\number\parposcounter}\horizontalstrut}
+
+\def\wpos#1%
+ {\dontleavehmode\vadjust % may disappear if buried
+ {\setbox0\hbox{\raise\strutdp\hbox{\rawwpos{#1}}}%
+ \rlap{\smashedbox0}}}
+
+\def\wwpos#1% \hsmashed{\llap{\rawwpos{#1}}}
+ {\rlap
+ {\setbox0\hbox{\rawwpos{#1}}%
+ \smashedbox0}}
+
+\def\rawwpos#1%
+ {\hpos{w:#1}
+ {\strut
+ \hskip-\leftskip
+ \hskip\hsize
+ \hskip-\rightskip}}
+
+% the next macro disables par positions (in inner boxes) and
+% only registers the width
+
+\def\setinnerparpositions
+ {\let\fpos\ffpos
+ \let\tpos\ttpos
+ \let\wpos\wwpos}
+
+% example of usage: (see for application "techniek")
+%
+% \appendtoks
+% \setinnerparpositions
+% \to \everytabulate
+
+%D When we want to calculate more complex backgrounds, we
+%D need to know what the current indentation scheme is. At
+%D the cost of many positions and memory, we can keep track
+%D of them. This mechanism is activated automatically
+%D based on information collected in the previous pass.
+
+\newcount\parposcounter
+
+\newif\ifpositioningpar
+
+% we can check for used entries, and if not, then not add one
+
+\def\registerparoptions
+ {\ifpositioningpar \ifpositioning \iftrialtypesetting \else
+ \ifinpagebody \else \ifmmode \else \ifinformula \else
+ \ifprocessingverbatim
+ \iflinepar \doregisterparoptions \fi
+ \else
+ \doregisterparoptions
+ \fi
+ \fi \fi \fi
+ \fi \fi \fi}
+
+\chardef\parposstrut=1 % 0 => no strut data, so fall backs used
+
+\newif\iftracepositions
+
+% \def\doregisterparoptions
+% {\global\advance\parposcounter\plusone
+% \begingroup
+% \leftskip 1\leftskip
+% \rightskip1\rightskip
+% \setpositiondataplus
+% {p:\number\parposcounter}% identifier
+% {\the\zeropoint}%
+% {\the\strutht}%
+% {\the\strutdp}%
+% {\the\hsize ,% 1
+% \the\leftskip ,% 2
+% \the\rightskip ,% 3
+% \the\hangindent,% 4
+% \the\hangafter ,% 5 (num)
+% \the\parindent }% 6
+% %\normalhbox{\registerparsymbol}%
+% \registerparsymbol
+% \endgroup}
+
+\def\doregisterparoptions
+ {\global\advance\parposcounter\plusone
+ \setpositiondataplus
+ {p:\number\parposcounter}% identifier
+ {\the\zeropoint}%
+ {\the\strutht}%
+ {\the\strutdp}%
+ {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}%
+ %\normalhbox{\registerparsymbol}%
+ \iftracepositions\registerparsymbol\fi}
+
+\def\traceposstring#1#2#3%
+ {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi}
+
+\def\registerparsymbol
+ {\iftracepositions
+ \smashedhbox to \zeropoint
+ {\hss
+ \startcolor[blue]%
+ \llap{\infofont\number\parposcounter}%
+ \scratchdimen\onepoint
+ \vrule
+ \!!width 4\scratchdimen
+ \!!height2\scratchdimen
+ \!!depth 2\scratchdimen
+ \stopcolor
+ \hss}%
+ \fi}
+
+% \appendtoks \registerparoptions \to \everypar
+
+%D Eperimental code, don't use this yet: (must be sped up anyway)
+
+\def\@@noden{node:n:}
+\def\@@nodeo{node:o:}
+\def\@@nodep{node:p:}
+
+\def\doifelsenodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\nextnodelocation#1%
+ {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi}
+
+\def\newnodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \setcounter{\@@noden#1}\zerocount
+ \letgvalue {\@@nodeo#1}\!!zerocount
+ \fi}
+
+\def\tagnodelocation#1%
+ {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi}
+
+\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}}
+\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}}
+\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}}
+
+\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}}
+\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}}
+\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}}
+
+\def\getnodelocationn#1{\countervalue{\@@noden#1}}
+\def\getnodelocationo#1{\getvalue {\@@nodeo#1}}
+
+\chardef\nodelocationmode\plusone
+
+\def\analyzenodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount
+ \fi}
+
+\def\doanalyzenodelocation#1#2#3% class n default
+ {\begingroup
+ \donefalse
+ \ifcase\nodelocationmode
+ % do nothing
+ \else
+ \edef\nodelocationselfn{#2}%
+ \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}%
+ \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}%
+ \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}%
+ \scratchcounter\plusone
+ \doloop
+ {\ifnum\recurselevel=\nodelocationselfn\relax
+ \donetrue
+ \else
+ \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}%
+ \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}%
+ \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}%
+ \ifcase\nodelocationmode
+ \or
+ % ok for single column
+ \ifcase\nodelocationotherp\relax
+ \exitloop
+ \else\ifnum\nodelocationotherp<\nodelocationselfp\relax
+ \donetrue \advance\scratchcounter\plusone
+ \else\ifnum\nodelocationotherp>\nodelocationselfp\relax
+ % skip
+ \else\ifdim\nodelocationothery>\nodelocationselfy\relax
+ \donetrue \advance\scratchcounter\plusone
+ \else\ifdim\nodelocationothery<\nodelocationselfy\relax
+ % skip
+ \else\ifdim\nodelocationotherx<\nodelocationselfx\relax
+ \donetrue \advance\scratchcounter\plusone
+ \fi\fi\fi\fi\fi\fi
+ \or
+ % acceptable for double column
+ \ifcase\nodelocationotherp\relax
+ \exitloop
+ \else\ifnum\nodelocationotherp<\nodelocationselfp\relax
+ \donetrue \advance\scratchcounter\plusone
+ \else\ifnum\nodelocationotherp>\nodelocationselfp\relax
+ % skip
+ \else\ifnum\recurselevel>\nodelocationselfn\relax
+ \donetrue \exitloop
+ \else
+ \donetrue \advance\scratchcounter\plusone
+ \fi\fi\fi\fi
+ \else
+ \exitloop
+ \fi
+ \fi}%
+ \fi
+ \ifdone \else
+ \scratchcounter#3\relax
+ \fi
+ \setxvalue{\@@nodeo#1}{\the\scratchcounter}%
+ \endgroup}
+
+\unexpanded\def\shownodelocation#1%
+ {\ifcsname\@@noden#1\endcsname
+ \analyzenodelocation{#1}%
+ (#1,%
+ n:\getnodelocationn{#1},%
+ p:\getnodelocationp{#1},%
+ x:\getnodelocationx{#1},%
+ y:\getnodelocationy{#1},%
+ o:\getnodelocationo{#1})%
+ \fi}
+
+%D \macros
+%D {doifoverlappingelse}
+%D
+%D A first application of positional information, is to
+%D determine if two boxes do overlap:
+%D
+%D \starttyping
+%D \doifoverlappingelse{point a}{point b}
+%D {action when overlapping}
+%D {action when not overlapping}
+%D \stoptyping
+
+\def\overlappingmargin{-2\scaledpoint}
+
+\def\doifoverlappingelse#1#2%
+ {\begingroup
+ \donefalse
+ \edef\!!stringa{#1}\edef\!!stringb{#2}%
+ \ifnum\MPp\!!stringa=\MPp\!!stringb\relax
+ \!!dimena\MPx\!!stringa
+ \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax
+ \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax
+ \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax
+ \!!dimene\MPx\!!stringb
+ \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax
+ \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax
+ \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax
+ \ifdim\overlappingmargin=\zeropoint\else
+ \advance\!!dimena-\overlappingmargin
+ \advance\!!dimenb+\overlappingmargin
+ \advance\!!dimenc-\overlappingmargin
+ \advance\!!dimend+\overlappingmargin
+ \advance\!!dimene-\overlappingmargin
+ \advance\!!dimenf+\overlappingmargin
+ \advance\!!dimeng-\overlappingmargin
+ \advance\!!dimenh+\overlappingmargin
+ \fi
+ % more often eh fb eg fg
+ \def\checkone##1##2%
+ {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else
+ \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else
+ \donetrue
+ \fi\fi
+ \fi\fi}%
+ \def\checktwo##1##2%
+ {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else
+ \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else
+ \donetrue
+ \fi\fi
+ \fi\fi}%
+ \checkone\!!dimene\!!dimeng \ifdone \else
+ \checkone\!!dimene\!!dimenh \ifdone \else
+ \checkone\!!dimenf\!!dimeng \ifdone \else
+ \checkone\!!dimenf\!!dimenh \ifdone \else
+ \checktwo\!!dimena\!!dimenc \ifdone \else
+ \checktwo\!!dimena\!!dimend \ifdone \else
+ \checktwo\!!dimenb\!!dimene \ifdone \else
+ \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi
+ \fi
+ \ifdone
+ \endgroup\expandafter\firstoftwoarguments
+ \else
+ \endgroup\expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doifpositionsonsamepageelse,
+%D doifpositionsonthispageelse}
+%D
+%D Instead of letting the user handle fuzzy expansion, we
+%D provide a simple test on positione being on the same page.
+%D
+%D \starttyping
+%D \doifpositionsonsamepageelse{point a}{point b}
+%D {action when on same page}
+%D {action when not on same page}
+%D \doifpositionsonthispageelse{point a}{point b}
+%D {action when on this page}
+%D {action when not on this page}
+%D \stoptyping
+
+\def\dodoifpositionsonsamepageelse#1#2#3#4%
+ {\bgroup
+ \scratchcounter#1\donefalse
+ \def\docommand##1%
+ {\ifcase\scratchcounter
+ \scratchcounter\MPp{##1}\donetrue
+ \else
+ \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi
+ \fi}%
+ \rawprocesscommalist[#2]\docommand
+ \ifdone\egroup#3\else\egroup#4\fi}
+
+\def\doifpositionsonsamepageelse
+ {\dodoifpositionsonsamepageelse{0}}
+
+\def\doifpositionsonthispageelse#1#2#3%
+ {\dodoifpositionsonsamepageelse\realfolio}
+
+%D Plugins:
+
+\let\MPv \MPplus
+\let\MPvv\MPrest
+
+\let\MPanchor\MPpos
+
+\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy
+\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw
\protect \endinput
diff --git a/tex/context/base/core-pos.tex b/tex/context/base/core-pos.tex
deleted file mode 100644
index 06bf55cae..000000000
--- a/tex/context/base/core-pos.tex
+++ /dev/null
@@ -1,767 +0,0 @@
-%D \module
-%D [ file=core-pos,
-%D version=1999.08.01,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Positioning Support,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% needs a cleanup, things may change; we also need to move the mp
-% related code to meta-pos
-
-% shorter tags, ..:achtergrond:.. etc in pos actions
-
-% dubbele text- * pos's eruit
-
-% class pos -> als gelijk aan vorige, dan niet niet definieren
-% en erven, maw:
-%
-% 1 -> opslaan
-% 2 -> undef, dus == prev
-% 3 -> undef, dus == prev
-% 4 -> opslaan
-
-\writestatus{loading}{Context Positioning Support}
-
-% todo: topskip als optie voor eerste regel achtergrond
-% todo: build pos layers on top of layers
-% todo: positionlayer pos van text-1 etc delen
-
-%D Although \TEX\ has a rather powerful channel to the outside
-%D world, called \type {\special}, real communication with
-%D other programs is complicated by the fact that no positional
-%D information is available. Mid 1999, I discussed this with
-%D \THANH, the author of \PDFTEX, and after some experiments,
-%D \PDFTEX\ was extended with a simple but effective mechanism,
-%D that provided positional information. The interesting
-%D thought is that, although \TEX\ is frozen, similar
-%D functionality could have been achieved with \type
-%D {\specials} and an additional \DVI\ postprocessor.
-%D
-%D Since we want to be as compatible as can be, \CONTEXT\ will
-%D support both methods, although the development is primarily
-%D driven by the \PDFTEX\ way of doing things. Since the
-%D mechanism is basically not limited to one application, for
-%D the moment we stick to building the functionality around one
-%D \CONTEXT\ special command, but at the same time we keep our
-%D eyes open for extensions in other directions.
-%D
-%D A question that may arise when one reads this module, is to
-%D what extend these macros are generic, in the sense that they
-%D could be collected in a support module instead of a core
-%D module. Since the mechanism described here will closely
-%D cooperate with the \METAPOST\ support built in \CONTEXT,
-%D which in turn will be tightly integrated with the \CONTEXT\
-%D overlay mechanisms, I decided to write a core module instead
-%D of a support one. This makes even more sense, when one takes
-%D into account that this kind of support depends on special
-%D drivers.
-
-\unprotect
-
-%D The first application of positional information was embedded
-%D graphics. Since we are interacting with text, it made sense
-%D to take the current line height and depth into account too.
-%D This is why we have two basic position macros: one for
-%D simple positions, and one for boxes.
-%D
-%D We could have sticked to one special, and actually did so in
-%D earlier experiments, but for convenience, as well for
-%D clearness, we now have two alternatives. This approach will
-%D save us quite some bytes when storing large quantities of
-%D positional information. We save as less information as
-%D needed, that is, we save no dimensions, in a \METAPOST\
-%D friendly way.
-%D
-%D The three specials involved are:
-%D
-%D \starttyping
-%D \dosetposition {identifier}
-%D \dosetpositionwhd {identifier} {width} {height} {depth}
-%D \dosetpositionplus {identifier} {width} {height} {depth} {list}
-%D \dosetpositionpapersize {width} {height}
-%D \stoptyping
-
-\newbox\positionbox
-\newif \ifpositioning
-
-\def\POSprefix{POS::}
-
-\let\setpospx \gobblefourarguments % suppress errors with mkii tuo file
-\let\setpospxywhd \gobblesevenarguments % suppress errors with mkii tuo file
-\let\setpospxyplus\gobbleeightarguments % suppress errors with mkii tuo file
-
-%D This is real tricky! The page anchor is applied to the
-%D page box and therefore flushed first. So, when present, it
-%D is applied to all positions except itself.
-
-\chardef\positionanchormode=0 % don't relocate page origin
-\chardef\positionanchormode=1 % relocate page origin once
-
-%D The core set macros.
-
-\let\pospxy \gobblefourarguments
-\let\pospxywhd \gobblesevenarguments
-\let\pospxyplus\gobbleeightarguments
-
-%D Sometimes we want to trick the position handler a bit:
-
-\let\replacepospxywhd\gobbleeightarguments
-
-%D For postprocessing purposes, we save the number of
-%D positions.
-
-\newcount\currentpositions % current number of positions
-\newcounter\totalnofpositions % total from previous run
-
-\appendtoks
- \expanded{\savecurrentvalue\noexpand\totalnofpositions{\the\currentpositions}}%
-\to \everybye
-
-%D The next switch can be used to communicate a special
-%D situation. Positioning and associated actions can be
-%D executed any time. However, in for instance backgrounds
-%D they can be collected in a layer, for instance the text
-%D layer (especially the hidden text layer). In the case of
-%D floats, we run into problems, since the page information is
-%D not applicable when the content floats indeed. In such
-%D situations one can treat positions and graphics local.
-
-\newif\iflocalpositioning
-
-%D Watch out: sometimes a pagebreak occurs inside a float
-%D placement, so there we need to disable local mode.
-
-\appendtoks
- \localpositioningtrue
-\to \everyinsidefloat
-
-\appendtoks
- \localpositioningfalse
-\to \everypagebody
-
-\def\checkpositions
- {\startnointerference
- \protectlabels
- \doutilities{positions}\jobname\empty\relax\relax
- \global\let\checkpositions\relax
- \stopnointerference}
-
-%D Since the positional values are to be fully expandable, we
-%D need to preload them as soon as possible, which is why we
-%D load the data when we start a text.
-
-\appendtoks \checkpositions \to \everystarttext
-
-%D Positions are either generated at a delayed write time
-%D (in \PDFTEX), or derived from the dvi file. The actual
-%D method is implemented in a special driver. If needed, the
-%D driver can fall back on the following macros.
-
-\let\dolazysaveposition \gobblefourarguments % tag page x y
-\let\dolazysavepositionwhd \gobblesevenarguments % tag page x y w h d
-\let\dolazysavepositionplus\gobbleeightarguments % tag page x y w h d list
-\let\dosaveposition \gobblefourarguments % tag page x y
-\let\dosavepositionwhd \gobblesevenarguments % tag page x y w h d
-\let\dosavepositionplus \gobbleeightarguments % tag page x y w h d list
-
-%D \macros
-%D {MPp, MPx, MPy, MPw, MPh, MPd,
-%D MPxy, MPll, MPlr, MPur, MPul, MPpos}
-%D
-%D Access to the positional information is provided by macros
-%D with short names that are clearly meant for \METAPOST.
-
-\let\MPp \!!zerocount
-\def\MPx \!!zeropoint
-\def\MPy \!!zeropoint
-\def\MPw \!!zeropoint
-\def\MPh \!!zeropoint
-\def\MPd \!!zeropoint
-\def\MPxy \!!zeropoint
-\def\MPll \!!zeropoint
-\def\MPlr \!!zeropoint
-\def\MPur \!!zeropoint
-\def\MPul \!!zeropoint
-\def\MPpos{\!!zerocount,\!!zeropoint,\!!zeropoint,\!!zeropoint,\!!zeropoint,\!!zeropoint}
-
-%D \macros
-%D {MPplus, MPrest, MPv, MPvv}
-%D
-%D Since we will probably keep on extending, we provide a
-%D general extension macro. The plus alternative takes an
-%D extra argument, denoting what additional parameter to pick
-%D up. So, the third extra is fetched with,
-%D
-%D \starttyping
-%D \MPplus{identifier}{3}{default}
-%D \stoptyping
-%D
-%D All extras (comma separated) are fetched with:
-%D
-%D \starttyping
-%D \MPrest{identifier}
-%D \stoptyping
-%D
-%D The extra parameters are not treated.
-
-\def\MPplus#1#2{\!!zerocount} \def\MPv {\MPplus}
-\def\MPrest#1#2{#2} \def\MPvv{\MPrest}
-
-%D \macros
-%D {MPanchor}
-%D
-%D For readability we define a few synonyms:
-
-\def\MPanchor{\MPpos}
-
-%D \macros
-%D {POSp, POSx, POSy, POSh, POSd, POSw}
-%D
-%D and:
-
-\def\POSp{\MPp} \def\POSx{\MPx} \def\POSy{\MPy}
-\def\POSh{\MPh} \def\POSd{\MPd} \def\POSw{\MPw}
-
-%D There are two low level positioning macros. Both store the
-%D position as well as execute an action associated with that
-%D position.
-
-\def\initializenextposition
- {\ifpositioning \else
- \global\positioningtrue
- \dosetpositionpapersize
- {\printpaperwidth }%
- {\printpaperheight}%
- \fi
- \global\advance\currentpositions\plusone}
-
-\def\setpositiononly#1%
- {\iftrialtypesetting
- % nothing
- \else
- \initializenextposition
- \def\currentposition{#1}%
- \dosetposition\currentposition
- \fi}
-
-\def\setposition#1%
- {\iftrialtypesetting
- % nothing
- \else
- \initializenextposition
- \def\currentposition{#1}%
- \dosetposition\currentposition
- \traceposstring\llap\green{\currentposition>}%
- \dopositionaction\currentposition
- \fi}
-
-\def\setpositiondata#1#2#3#4%
- {\iftrialtypesetting \else
- \initializenextposition
- \hbox
- {\def\currentposition{#1}%
- \dosetpositionwhd\currentposition
- {\the\dimexpr#2\relax}%
- {\the\dimexpr#3\relax}%
- {\the\dimexpr#4\relax}%
- \traceposstring\llap\green{\currentposition>}%
- \dopositionaction\currentposition
- \hss}%
- \fi}
-
-\def\setpositionbox#1%
- {\dowithnextbox
- {\iftrialtypesetting
- \flushnextbox
- \else
- \initializenextposition
- \hbox to \nextboxwd
- {\edef\currentposition{#1}%
- \dosetpositionwhd\currentposition
- {\the\nextboxwd}%
- {\the\nextboxht}%
- {\the\nextboxdp}%
- \traceposstring\llap\green{\currentposition>}%
- \setbox\positionbox\flushnextbox
- \dopositionaction\currentposition
- \box\positionbox
- \hss}%
- \fi}}
-
-\def\setpositiondataplus#1#2#3#4#5%
- {\iftrialtypesetting \else
- \initializenextposition
- \hbox % bug: to \nextboxwd
- {\edef\currentposition{#1}%
- \dosetpositionplus\currentposition
- {\the\dimexpr#2\relax}%
- {\the\dimexpr#3\relax}%
- {\the\dimexpr#4\relax}%
- {#5}%
- \traceposstring\rlap\magenta{<\currentposition}%
- \dopositionaction\currentposition
- \hss}%
- \fi}
-
-\def\setpositionplus#1#2%
- {\dowithnextbox
- {\iftrialtypesetting
- \flushnextbox
- \else
- \initializenextposition
- \hbox to \nextboxwd
- {\edef\currentposition{#1}%
- \dosetpositionplus\currentposition
- {\the\nextboxwd}%
- {\the\nextboxht}%
- {\the\nextboxdp}%
- {#2}%
- \traceposstring\rlap\magenta{<\currentposition}%
- \setbox\positionbox\flushnextbox
- \dopositionaction\currentposition
- \box\positionbox
- \hss}%
- \fi}}
-
-\let\currentposition\s!unknown
-
-%D A few more low level macros take care of defining and
-%D recalling actions. We could save this information in the
-%D position containers themselves, this would save hash
-%D entries, but at the cost of much more time consuming
-%D expansion. Actions are saved globally!
-
-\newtoks\everypositionaction
-
-\let\POSactionprefix\POSprefix
-
-\def\dosetpositionaction#1%
- {\setgvalue{\POSactionprefix#1::}}
-
-%D The lists can become quite long (also because there can
-%D be lots of parameters passed on) so we provide a hook
-%D to clean up the list afterwards.
-
-\let\cleanuppositionaction\gobbleoneargument
-
-\def\doifpositionaction#1%
- {\ifcsname\POSactionprefix#1::\endcsname
- \@EA\firstofoneargument
- \else
- \@EA\gobbleoneargument
- \fi}
-
-\def\doifpositionactionelse#1%
- {\ifcsname\POSactionprefix#1::\endcsname
- \@EA\firstoftwoarguments
- \else
- \@EA\secondoftwoarguments
- \fi}
-
-%D We can copy a position with:
-%D
-%D \starttyping
-%D \copyposition {to} {from}
-%D \stoptyping
-%D
-%D Again, this is a global action.
-
-\let\copyposition\gobbletwoarguments
-
-%D The fact that handling positions is a two pass operation, is
-%D one of the reasons why we need to be able to test for
-%D existence, using:
-%D
-%D \starttyping
-%D \doifpositionelse {identifier} {found action} {not found action}
-%D \stoptyping
-
-\let\doifpositionelse\thirdofthreearguments
-
-%D We have now arrived at a few macros that would make sense as
-%D support macros, but ended up in the core.
-
-%D \macros
-%D {xypos}
-%D
-%D We have several macros available to save positions. Later
-%D we will see applications.
-%D
-%D \starttabulate[|l|l||]
-%D \NC \type {\xypos} \NC \NC simple position with no dimensions \NC \NR
-%D \NC \type {\hpos} \NC \NC position and characteristics of a \type {\hbox} \NC \NR
-%D \NC \type {\vpos} \NC \NC position and characteristics of a \type {\vbox} \NC \NR
-%D \NC \type {\bpos} \NC b: \NC begin point in a line \NC \NR
-%D \NC \type {\epos} \NC e: \NC end point in a line \NC \NR
-%D \NC \type {\fpos} \NC f: \NC begin point in a paragraph \NC \NR
-%D \NC \type {\tpos} \NC t: \NC end point in a paragraph \NC \NR
-%D \stoptabulate
-%D
-%D Each macro takes an identifier as argument, and the \type
-%D {\hpos} and \type {\vpos} also expect box content.
-
-% \def\xypos{\initializenextposition\dosetposition}
-
-\let\xypos\setpositiononly
-
-\def\hpos#1{\dontleavehmode\setpositionbox{#1}\hbox}
-\def\vpos#1{\setpositionbox{#1}\vbox}
-
-\def\bpos#1{\hpos{b:#1}{\strut}\ignorespaces}
-\def\epos#1{\removelastspace\hpos{e:#1}{\strut}}
-
-\def\fpos#1%
- {\setpositionplus{b:#1}{\number\parposcounter}\horizontalstrut
- \ignorespaces}
-
-\def\tpos#1%
- {\removelastspace
- \setpositionplus{e:#1}{\number\parposcounter}\horizontalstrut}
-
-\def\ffpos#1%
- {\setpositionplus{b:#1}{\number\parposcounter}\horizontalstrut\wpos{#1}%
- \ignorespaces}
-
-\def\ttpos#1%
- {\removelastspace
- \setpositionplus{e:#1}{\number\parposcounter}\horizontalstrut}
-
-\def\wpos#1%
- {\dontleavehmode\vadjust % may disappear if buried
- {\setbox0\hbox{\raise\strutdp\hbox{\rawwpos{#1}}}%
- \rlap{\smashedbox0}}}
-
-\def\wwpos#1% \hsmashed{\llap{\rawwpos{#1}}}
- {\rlap
- {\setbox0\hbox{\rawwpos{#1}}%
- \smashedbox0}}
-
-\def\rawwpos#1%
- {\hpos{w:#1}
- {\strut
- \hskip-\leftskip
- \hskip\hsize
- \hskip-\rightskip}}
-
-% the next macro disables par positions (in inner boxes) and
-% only registers the width
-
-\def\setinnerparpositions
- {\let\fpos\ffpos
- \let\tpos\ttpos
- \let\wpos\wwpos}
-
-% example of usage: (see for application "techniek")
-%
-% \appendtoks
-% \setinnerparpositions
-% \to \everytabulate
-
-%D When we want to calculate more complex backgrounds, we
-%D need to know what the current indentation scheme is. At
-%D the cost of many positions and memory, we can keep track
-%D of them. This mechanism is activated automatically
-%D based on information collected in the previous pass.
-
-\newcount\parposcounter
-
-\newif\ifpositioningpar
-
-% we can check for used entries, and if not, then not add one
-
-\def\registerparoptions
- {\ifpositioningpar \ifpositioning \iftrialtypesetting \else
- \ifinpagebody \else \ifmmode \else \ifinformula \else
- \ifprocessingverbatim
- \iflinepar \doregisterparoptions \fi
- \else
- \doregisterparoptions
- \fi
- \fi \fi \fi
- \fi \fi \fi}
-
-\chardef\parposstrut=1 % 0 => no strut data, so fall backs used
-
-\newif\iftracepositions
-
-% \def\doregisterparoptions
-% {\global\advance\parposcounter\plusone
-% \begingroup
-% \leftskip 1\leftskip
-% \rightskip1\rightskip
-% \setpositiondataplus
-% {p:\number\parposcounter}% identifier
-% {\the\zeropoint}%
-% {\the\strutht}%
-% {\the\strutdp}%
-% {\the\hsize ,% 1
-% \the\leftskip ,% 2
-% \the\rightskip ,% 3
-% \the\hangindent,% 4
-% \the\hangafter ,% 5 (num)
-% \the\parindent }% 6
-% %\normalhbox{\registerparsymbol}%
-% \registerparsymbol
-% \endgroup}
-
-\def\doregisterparoptions
- {\global\advance\parposcounter\plusone
- \setpositiondataplus
- {p:\number\parposcounter}% identifier
- {\the\zeropoint}%
- {\the\strutht}%
- {\the\strutdp}%
- {\the\hsize,\the\dimexpr\leftskip\relax,\the\dimexpr\rightskip\relax,\the\hangindent,\the\hangafter,\the\parindent}%
- %\normalhbox{\registerparsymbol}%
- \iftracepositions\registerparsymbol\fi}
-
-\def\traceposstring#1#2#3%
- {\iftracepositions\smashedhbox{#1{\infofont#2#3}}\fi}
-
-\def\registerparsymbol
- {\iftracepositions
- \smashedhbox to \zeropoint
- {\hss
- \startcolor[blue]%
- \llap{\infofont\number\parposcounter}%
- \scratchdimen\onepoint
- \vrule
- \!!width 4\scratchdimen
- \!!height2\scratchdimen
- \!!depth 2\scratchdimen
- \stopcolor
- \hss}%
- \fi}
-
-% \appendtoks \registerparoptions \to \everypar
-
-%D Eperimental code, don't use this yet: (must be sped up anyway)
-
-\def\@@noden{node:n:}
-\def\@@nodeo{node:o:}
-\def\@@nodep{node:p:}
-
-\def\doifelsenodelocation#1%
- {\ifcsname\@@noden#1\endcsname
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\def\nextnodelocation#1%
- {\ifcsname\@@noden#1\endcsname\pluscounter{\@@noden#1}\fi}
-
-\def\newnodelocation#1%
- {\ifcsname\@@noden#1\endcsname
- \setcounter{\@@noden#1}\zerocount
- \letgvalue {\@@nodeo#1}\!!zerocount
- \fi}
-
-\def\tagnodelocation#1%
- {\ifcsname\@@noden#1\endcsname\xypos{\@@nodep#1:\countervalue{\@@noden#1}}\fi}
-
-\def\getnodelocationp#1{\MPp{\@@nodep#1:\countervalue{\@@noden#1}}}
-\def\getnodelocationx#1{\MPx{\@@nodep#1:\countervalue{\@@noden#1}}}
-\def\getnodelocationy#1{\MPy{\@@nodep#1:\countervalue{\@@noden#1}}}
-
-\def\numnodelocationp#1#2{\MPp{\@@nodep#1:\number#2}}
-\def\numnodelocationx#1#2{\MPx{\@@nodep#1:\number#2}}
-\def\numnodelocationy#1#2{\MPy{\@@nodep#1:\number#2}}
-
-\def\getnodelocationn#1{\countervalue{\@@noden#1}}
-\def\getnodelocationo#1{\getvalue {\@@nodeo#1}}
-
-\chardef\nodelocationmode\plusone
-
-\def\analyzenodelocation#1%
- {\ifcsname\@@noden#1\endcsname
- \doanalyzenodelocation{#1}{\getnodelocationn{#1}}\zerocount
- \fi}
-
-\def\doanalyzenodelocation#1#2#3% class n default
- {\begingroup
- \donefalse
- \ifcase\nodelocationmode
- % do nothing
- \else
- \edef\nodelocationselfn{#2}%
- \edef\nodelocationselfp{\numnodelocationp{#1}\nodelocationselfn}%
- \edef\nodelocationselfx{\numnodelocationx{#1}\nodelocationselfn}%
- \edef\nodelocationselfy{\numnodelocationy{#1}\nodelocationselfn}%
- \scratchcounter\plusone
- \doloop
- {\ifnum\recurselevel=\nodelocationselfn\relax
- \donetrue
- \else
- \edef\nodelocationotherp{\numnodelocationp{#1}\recurselevel}%
- \edef\nodelocationotherx{\numnodelocationx{#1}\recurselevel}%
- \edef\nodelocationothery{\numnodelocationy{#1}\recurselevel}%
- \ifcase\nodelocationmode
- \or
- % ok for single column
- \ifcase\nodelocationotherp\relax
- \exitloop
- \else\ifnum\nodelocationotherp<\nodelocationselfp\relax
- \donetrue \advance\scratchcounter\plusone
- \else\ifnum\nodelocationotherp>\nodelocationselfp\relax
- % skip
- \else\ifdim\nodelocationothery>\nodelocationselfy\relax
- \donetrue \advance\scratchcounter\plusone
- \else\ifdim\nodelocationothery<\nodelocationselfy\relax
- % skip
- \else\ifdim\nodelocationotherx<\nodelocationselfx\relax
- \donetrue \advance\scratchcounter\plusone
- \fi\fi\fi\fi\fi\fi
- \or
- % acceptable for double column
- \ifcase\nodelocationotherp\relax
- \exitloop
- \else\ifnum\nodelocationotherp<\nodelocationselfp\relax
- \donetrue \advance\scratchcounter\plusone
- \else\ifnum\nodelocationotherp>\nodelocationselfp\relax
- % skip
- \else\ifnum\recurselevel>\nodelocationselfn\relax
- \donetrue \exitloop
- \else
- \donetrue \advance\scratchcounter\plusone
- \fi\fi\fi\fi
- \else
- \exitloop
- \fi
- \fi}%
- \fi
- \ifdone \else
- \scratchcounter#3\relax
- \fi
- \setxvalue{\@@nodeo#1}{\the\scratchcounter}%
- \endgroup}
-
-\unexpanded\def\shownodelocation#1%
- {\ifcsname\@@noden#1\endcsname
- \analyzenodelocation{#1}%
- (#1,%
- n:\getnodelocationn{#1},%
- p:\getnodelocationp{#1},%
- x:\getnodelocationx{#1},%
- y:\getnodelocationy{#1},%
- o:\getnodelocationo{#1})%
- \fi}
-
-%D \macros
-%D {doifoverlappingelse}
-%D
-%D A first application of positional information, is to
-%D determine if two boxes do overlap:
-%D
-%D \starttyping
-%D \doifoverlappingelse{point a}{point b}
-%D {action when overlapping}
-%D {action when not overlapping}
-%D \stoptyping
-
-\def\overlappingmargin{-2\scaledpoint}
-
-\def\doifoverlappingelse#1#2%
- {\begingroup
- \donefalse
- \edef\!!stringa{#1}\edef\!!stringb{#2}%
- \ifnum\MPp\!!stringa=\MPp\!!stringb\relax
- \!!dimena\MPx\!!stringa
- \!!dimenb\dimexpr\MPx\!!stringa+\MPw\!!stringa\relax
- \!!dimenc\dimexpr\MPy\!!stringa-\MPd\!!stringa\relax
- \!!dimend\dimexpr\MPy\!!stringa+\MPh\!!stringa\relax
- \!!dimene\MPx\!!stringb
- \!!dimenf\dimexpr\MPx\!!stringb+\MPw\!!stringb\relax
- \!!dimeng\dimexpr\MPy\!!stringb-\MPd\!!stringb\relax
- \!!dimenh\dimexpr\MPy\!!stringb+\MPh\!!stringb\relax
- \ifdim\overlappingmargin=\zeropoint\else
- \advance\!!dimena-\overlappingmargin
- \advance\!!dimenb+\overlappingmargin
- \advance\!!dimenc-\overlappingmargin
- \advance\!!dimend+\overlappingmargin
- \advance\!!dimene-\overlappingmargin
- \advance\!!dimenf+\overlappingmargin
- \advance\!!dimeng-\overlappingmargin
- \advance\!!dimenh+\overlappingmargin
- \fi
- % more often eh fb eg fg
- \def\checkone##1##2%
- {\ifdim##1<\!!dimena \else \ifdim##1>\!!dimenb \else
- \ifdim##2<\!!dimenc \else \ifdim##2>\!!dimend \else
- \donetrue
- \fi\fi
- \fi\fi}%
- \def\checktwo##1##2%
- {\ifdim##1<\!!dimene \else \ifdim##1>\!!dimenf \else
- \ifdim##2<\!!dimeng \else \ifdim##2>\!!dimenh \else
- \donetrue
- \fi\fi
- \fi\fi}%
- \checkone\!!dimene\!!dimeng \ifdone \else
- \checkone\!!dimene\!!dimenh \ifdone \else
- \checkone\!!dimenf\!!dimeng \ifdone \else
- \checkone\!!dimenf\!!dimenh \ifdone \else
- \checktwo\!!dimena\!!dimenc \ifdone \else
- \checktwo\!!dimena\!!dimend \ifdone \else
- \checktwo\!!dimenb\!!dimene \ifdone \else
- \checktwo\!!dimenb\!!dimenc \fi \fi \fi \fi \fi \fi \fi
- \fi
- \ifdone
- \endgroup\expandafter\firstoftwoarguments
- \else
- \endgroup\expandafter\secondoftwoarguments
- \fi}
-
-%D \macros
-%D {doifpositionsonsamepageelse,
-%D doifpositionsonthispageelse}
-%D
-%D Instead of letting the user handle fuzzy expansion, we
-%D provide a simple test on positione being on the same page.
-%D
-%D \starttyping
-%D \doifpositionsonsamepageelse{point a}{point b}
-%D {action when on same page}
-%D {action when not on same page}
-%D \doifpositionsonthispageelse{point a}{point b}
-%D {action when on this page}
-%D {action when not on this page}
-%D \stoptyping
-
-\def\dodoifpositionsonsamepageelse#1#2#3#4%
- {\bgroup
- \scratchcounter#1\donefalse
- \def\docommand##1%
- {\ifcase\scratchcounter
- \scratchcounter\MPp{##1}\donetrue
- \else
- \ifnum\scratchcounter=\MPp{##1}\relax\else\donefalse\fi
- \fi}%
- \rawprocesscommalist[#2]\docommand
- \ifdone\egroup#3\else\egroup#4\fi}
-
-\def\doifpositionsonsamepageelse
- {\dodoifpositionsonsamepageelse{0}}
-
-\def\doifpositionsonthispageelse#1#2#3%
- {\dodoifpositionsonsamepageelse\realfolio}
-
-%D Plugins:
-
-\loadmarkfile{core-pos}
-
-\let\MPv \MPplus
-\let\MPvv\MPrest
-
-\let\MPanchor\MPpos
-
-\let\POSp\MPp \let\POSx\MPx \let\POSy\MPy
-\let\POSh\MPh \let\POSd\MPd \let\POSw\MPw
-
-\protect \endinput
diff --git a/tex/context/base/core-ref.lua b/tex/context/base/core-ref.lua
deleted file mode 100644
index 6aaef5cc9..000000000
--- a/tex/context/base/core-ref.lua
+++ /dev/null
@@ -1,106 +0,0 @@
-if not modules then modules = { } end modules ['core-ref'] = {
- version = 1.001,
- comment = "companion to core-ref.tex",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-local format, texsprint = string.format, tex.sprint
-
--- beware, this is a first step in the rewrite (just getting rid of
--- the tuo file); later all access and parsing will also move to lua
-
-jobreferences = jobreferences or { }
-jobreferences.tobesaved = jobreferences.tobesaved or { }
-jobreferences.collected = jobreferences.collected or { }
-
-local tobesaved, collected = jobreferences.tobesaved, jobreferences.collected
-
-local function initializer()
- tobesaved, collected = jobreferences.tobesaved, jobreferences.collected
- -- hack, just the old way
- texsprint(tex.ctxcatcodes,"\\bgroup\\the\\everyreference")
- for prefix, list in pairs(collected) do
- for tag, data in pairs(list) do
- texsprint(tex.ctxcatcodes,format("\\dosetjobreference{%s}{%s}{%s}{%s}{%s}",prefix,tag,data[1],data[2],data[3]))
- end
- end
- texsprint(tex.ctxcatcodes,"\\egroup")
-end
-
-if job then
- job.register('jobreferences.collected', jobreferences.tobesaved, initializer)
-end
-
-function jobreferences.set(prefix,tag,page,realpage,text)
- for ref in tag:gmatch("[^,]+") do
- local p, r = ref:match("^(%-):(.-)$")
- if p and r then
- prefix, ref = "", r
- end
- if ref ~= "" then
- local pd = tobesaved[prefix]
- if not pd then
- pd = { }
- tobesaved[prefix] = pd
- end
- pd[ref] = { page, realpage, text }
- end
- end
-end
-
-function jobreferences.with(tag)
- for ref in tag:gmatch("[^,]+") do
- texsprint(tex.ctxcatcodes,format("\\dowithjobreference{%s}",ref:gsub("^(%-):","")))
- end
-end
-
--- this reference parser is just an lpeg version of the tex based one
-
-local result = { }
-
-local lparent, rparent, lbrace, rbrace, dcolon = lpeg.P("("), lpeg.P(")"), lpeg.P("{"), lpeg.P("}"), lpeg.P("::")
-
-local reset = lpeg.P("") / function (s) result = { } end
-local outer = (1-dcolon-lparent-lbrace )^1 / function (s) result.outer = s end
-local operation = (1-rparent-rbrace-lparent-lbrace)^1 / function (s) result.operation = s end
-local arguments = (1-rbrace )^0 / function (s) result.arguments = s end
-local special = (1-lparent-lbrace-lparent-lbrace)^1 / function (s) result.special = s end
-local inner = (1-lparent-lbrace )^1 / function (s) result.inner = s end
-
-local outer_reference = (outer * dcolon)^0
-
-operation = outer_reference * operation -- special case: page(file::1) and file::page(1)
-
-local optional_arguments = (lbrace * arguments * rbrace)^0
-local inner_reference = inner * optional_arguments
-local special_reference = special * lparent * (operation * optional_arguments + operation^0) * rparent
-
-
-local scanner = (reset * outer_reference * (special_reference + inner_reference)^-1 * -1) / function() return result end
-
-function jobreferences.analyse(str)
- return scanner:match(str)
-end
-
-local template = "\\setreferencevariables{%s}{%s}{%s}{%s}{%s}"
-
-function jobreferences.split(str)
- local t = scanner:match(str)
- texsprint(tex.ctxcatcodes,format(template,t.special or "",t.operation or "",t.arguments or "",t.outer or "",t.inner or ""))
-end
-
---~ print(table.serialize(jobreferences.analyse("")))
---~ print(table.serialize(jobreferences.analyse("inner")))
---~ print(table.serialize(jobreferences.analyse("special(operation{argument,argument})")))
---~ print(table.serialize(jobreferences.analyse("special(operation)")))
---~ print(table.serialize(jobreferences.analyse("special()")))
---~ print(table.serialize(jobreferences.analyse("inner{argument}")))
---~ print(table.serialize(jobreferences.analyse("outer::")))
---~ print(table.serialize(jobreferences.analyse("outer::inner")))
---~ print(table.serialize(jobreferences.analyse("outer::special(operation{argument,argument})")))
---~ print(table.serialize(jobreferences.analyse("outer::special(operation)")))
---~ print(table.serialize(jobreferences.analyse("outer::special()")))
---~ print(table.serialize(jobreferences.analyse("outer::inner{argument}")))
---~ print(table.serialize(jobreferences.analyse("special(outer::operation)")))
diff --git a/tex/context/base/core-ref.mkii b/tex/context/base/core-ref.mkii
deleted file mode 100644
index a5937726a..000000000
--- a/tex/context/base/core-ref.mkii
+++ /dev/null
@@ -1,90 +0,0 @@
-%D \module
-%D [ file=core-ref,
-%D version=2008.10.14,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Cross Referencing,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\rawreference#1#2#3%
- {\bgroup
- \the\everyreference
- \makesectionformat
- \writereference{#2}
- {\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber}%
- {\noexpand\realfolio}%
- {#3}%
- \egroup}
-
-\def\rawpagereference#1#2%
- {\bgroup
- \the\everyreference
- \makesectionformat
- \writereference{#2}
- {\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber}%
- {\noexpand\realfolio}%
- {}%
- \egroup}
-
-\def\rawtextreference#1#2#3%
- {\bgroup
- \the\everyreference
- \writereference{#2}
- {}%
- {\noexpand\realfolio}%
- {#3}%
- \egroup}
-
-%D The last reference is saved in a macro named \type
-%D {\lastreference} (indeed). To keep track of the order of
-%D references, later we will see for what purpose, we maintain
-%D a counter.
-
-\newcount\crossreferencenumber \crossreferencenumber\plusone
-
-\let\lastreference\empty
-
-\def\writereference#1#2#3#4%
- {\ifreferencing
- \edef\!!stringa{#1}%
- \ifx\!!stringa\empty \else
- \def\dowritereference##1%
- {\xdef\lastreference{##1}%
- \@EA\dodowritereference\lastreference\empty\empty\end{#2}{#3}{#4}}%
- \rawprocesscommalist[\!!stringa]\dowritereference
- \fi
- \fi}
-
-%D Beware: \type {#2} gobbles space in references so that
-%D \typ {a nice ref} becomes \typ {anice ref}.
-
-\def\dodowritereference#1#2#3\end#4#5#6%
- {\bgroup
- \global\advance\crossreferencenumber \plusone\relax
- \if#1-\if#2:%
- \let\referenceprefix\empty
- \xdef\lastreference{#3}%
- \else
- % \xdef\lastreference{#1#2#3}% here we loose the space
- \fi\else
- % \xdef\lastreference{#1#2#3}% here we loose the space
- \fi
- \ifx\lastreference\empty \else
- \doiffirstreferenceoccurance\lastreference
- {\thisisdestination{\referenceprefix\lastreference}}%
- \referenceinfo>\lastreference
- \expanded{\writeutilitycommand{\noexpand\mainreference{\referenceprefix}{\lastreference}{#4}{#5}{#6}}}%
- \fi
- \egroup}
-
-%D We will implement \type {\doiffirstreferenceoccurance}
-%D later on.
-
-\protect
diff --git a/tex/context/base/core-ref.mkiv b/tex/context/base/core-ref.mkiv
deleted file mode 100644
index 56ef77b37..000000000
--- a/tex/context/base/core-ref.mkiv
+++ /dev/null
@@ -1,107 +0,0 @@
-%D \module
-%D [ file=core-ref,
-%D version=2008.10.14,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Cross Referencing,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-\let\mainreference\gobblefivearguments % catch mkii tuo stuff
-
-\registerctxluafile{core-ref}{1.001}
-
-\unprotect
-
-% later we will use the lua tables directly (first a hack)
-%
-% \the\everyreference % we're grouped anyway
-
-\newcount\crossreferencenumber \crossreferencenumber\plusone
-
-\def\dowithjobreference#1%
- {\global\advance\crossreferencenumber\plusone
- \doiffirstreferenceoccurance{#1}{\thisisdestination{\referenceprefix#1}}%
- \referenceinfo>{#1}}
-
-% \def\dowithjobreference#1{}
-
-\def\dosetjobreference#1#2#3#4#5%
- {\ifcsname\r!cross\fileprefix#1#2\endcsname
- \ifcase0#4\else
- \showmessage\m!references2{[#1][#2],#4 (\currentutilityfilename)}%
- \fi
- \else
- \ifcase\autocrossfilereferences
- \setglobalcrossreference{#1#2}{#3}{#4}{#5}%
- \or
- \setglobalcrossreference{#1#2}{#3}{#4}{#5}%
- \ifcsname\r!cross#1#2\endcsname
- \showmessage\m!references2{[#1][#2],#4 (auto \currentutilityfilename)}%
- \else
- \expanded{\definereference[#1#2][\fileprefix#1#2]}%
- \fi
- \or
- \ifcsname\r!cross#1#2\endcsname
- \showmessage\m!references2{[#1][#2],#4 (auto \currentutilityfilename)}%
- \else
- \expanded{\definereference[#1#2][\noexpand\v!page(\fileprefix#4)]}%
- \fi
- \fi
- \fi}
-
-\def\rawreference#1#2#3%
- {\ifreferencing
- \doifsomething{#2}
- {\bgroup
- \the\everyreference
- \makesectionformat
- \expanded{\ctxlua{jobreferences.with("#2")}}%
- \expanded{\ctxlatelua{jobreferences.set(
- "\referenceprefix",
- "#2",
- "\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber",
- "\noexpand\the\realpageno",
- \!!bs#3\!!es
- )}}%
- \egroup}%
- \fi}
-
-\def\rawpagereference#1#2%
- {\ifreferencing
- \doifsomething{#2}
- {\bgroup
- \the\everyreference
- \makesectionformat
- \expanded{\ctxlua{jobreferences.with("#2")}}%
- \expanded{\ctxlatelua{jobreferences.set(
- "\referenceprefix",
- "#2",
- "\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber",
- "\noexpand\the\realpageno",
- ""
- )}}%
- \egroup}%
- \fi}
-
-\def\rawtextreference#1#2#3%
- {\ifreferencing
- \doifsomething{#2}
- {\bgroup
- \the\everyreference
- \expanded{\ctxlua{jobreferences.with("#2")}}%
- \expanded{\ctxlatelua{jobreferences.set(
- "\referenceprefix",
- "#2",
- "",
- "\noexpand\the\realpageno",
- \!!bs#3\!!es
- )}}%
- \egroup}%
- \fi}
-
-\protect
diff --git a/tex/context/base/core-ref.tex b/tex/context/base/core-ref.tex
index b67928e45..8ca0a92bf 100644
--- a/tex/context/base/core-ref.tex
+++ b/tex/context/base/core-ref.tex
@@ -11,7 +11,9 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Cross Referencing}
+% we will merge mkii code back in here
+
+\writestatus{loading}{ConTeXt Core Macros / Cross Referencing}
% todo : unknown/illegal reference no arg
% todo : +n pages check on 'samepage' (contrastcolor)
@@ -42,93 +44,21 @@
\unprotect
-\startmessages dutch library: references
- title: verwijzingen
- 1: onbekende verwijzing --
- 2: dubbele verwijzing -- op pagina --
- 3: type verwijzing -- onbekend
- 4: verboden verwijzing --
- 21: document -- geladen
- 22: document -- is niet interactief
- 23: onduidelijke verwijzing -- (prefix=--)
-\stopmessages
-
-\startmessages english library: references
- title: references
- 1: unknown reference --
- 2: duplicate reference -- on page --
- 3: unknown reference type --
- 4: illegal reference --
- 21: document -- loaded
- 22: document -- is not interactive
- 23: obscure reference -- (prefix=--)
-\stopmessages
-
-\startmessages german library: references
- title: referenzen
- 1: unbekannte Referenz --
- 2: doppelte Referenz -- auf Seite --
- 3: unbekannte Referenz Typ --
- 4: illegale Referenz --
- 21: Dokument -- geladen
- 22: Dokument -- ist nicht aktiv
- 23: Obskure Referenz -- (Prefix=--)
-\stopmessages
-
-\startmessages czech library: references
- title: reference
- 1: neznama reference --
- 2: duplicitni reference -- na strane --
- 3: neznamy typ reference --
- 4: nedovolena reference --
- 21: dokument -- nacten
- 22: dokument -- neni interaktivni
- 23: obskurni (nejasna) reference -- (prefix=--)
-\stopmessages
-
-\startmessages italian library: references
- title: riferimenti
- 1: riferimento sconosciuto --
- 2: riferimento duplicato -- a pagina --
- 3: riferimento di tipo sconosciuto --
- 4: riferimento illecito --
- 21: documento -- caricato
- 22: il documento -- non ø interattivo
- 23: riferimento ambiguo -- (prefisso=--)
-\stopmessages
-
-\startmessages norwegian library: references
- title: referanser
- 1: ukjent referanse --
- 2: duplikat referanse -- pø side --
- 3: ukjent referansetype --
- 4: ulovlig referanse --
- 21: dokument -- er lest inn
- 22: dokument -- er ikke interaktivt
- 23: obskur referanse -- (Prefix=--)
-\stopmessages
-
-\startmessages romanian library: references
- title: referinte
- 1: referinta necunoscuta --
- 2: referinta duplicat -- la pagina --
- 3: tip necunoscut de referinta --
- 4: referinta eronata --
- 21: documentul -- este incarcat
- 22: documentul -- nu este interactiv
- 23: referinta obscura -- (prefix=--)
-\stopmessages
-
-\startmessages french library: references
- title: réferences
- 1: réference -- inconnue
- 2: réference -- dupliquée à la page --
- 3: type -- de réference inconnu
- 4: réference -- inconnue
- 21: document -- chargé
- 22: le document -- n'est pas interactif
- 23: reference -- indéterminé (préfixe=--)
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
%D This module deals with referencing. In \CONTEXT\ referencing
%D is one of the core features, although at a first glance
@@ -193,9 +123,79 @@
%D full reference, but it's the concept that counts. The low
%D level implementation is:
-\let\rawreference \gobblethreearguments
-\let\rawpagereference\gobbletwoarguments
-\let\rawtextreference\gobbletwoarguments
+\def\rawreference#1#2#3%
+ {\bgroup
+ \the\everyreference
+ \makesectionformat
+ \writereference{#2}
+ {\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber}%
+ {\noexpand\realfolio}%
+ {#3}%
+ \egroup}
+
+\def\rawpagereference#1#2%
+ {\bgroup
+ \the\everyreference
+ \makesectionformat
+ \writereference{#2}
+ {\sectionformat\sectionseparator\sectionseparator\noexpand\pagenumber}%
+ {\noexpand\realfolio}%
+ {}%
+ \egroup}
+
+\def\rawtextreference#1#2#3%
+ {\bgroup
+ \the\everyreference
+ \writereference{#2}
+ {}%
+ {\noexpand\realfolio}%
+ {#3}%
+ \egroup}
+
+%D The last reference is saved in a macro named \type
+%D {\lastreference} (indeed). To keep track of the order of
+%D references, later we will see for what purpose, we maintain
+%D a counter.
+
+\newcount\crossreferencenumber \crossreferencenumber\plusone
+
+\let\lastreference\empty
+
+\def\writereference#1#2#3#4%
+ {\ifreferencing
+ \edef\!!stringa{#1}%
+ \ifx\!!stringa\empty \else
+ \def\dowritereference##1%
+ {\xdef\lastreference{##1}%
+ \@EA\dodowritereference\lastreference\empty\empty\end{#2}{#3}{#4}}%
+ \rawprocesscommalist[\!!stringa]\dowritereference
+ \fi
+ \fi}
+
+%D Beware: \type {#2} gobbles space in references so that
+%D \typ {a nice ref} becomes \typ {anice ref}.
+
+\def\dodowritereference#1#2#3\end#4#5#6%
+ {\bgroup
+ \global\advance\crossreferencenumber \plusone\relax
+ \if#1-\if#2:%
+ \let\referenceprefix\empty
+ \xdef\lastreference{#3}%
+ \else
+ % \xdef\lastreference{#1#2#3}% here we loose the space
+ \fi\else
+ % \xdef\lastreference{#1#2#3}% here we loose the space
+ \fi
+ \ifx\lastreference\empty \else
+ \doiffirstreferenceoccurance\lastreference
+ {\thisisdestination{\referenceprefix\lastreference}}%
+ \referenceinfo>\lastreference
+ \expanded{\writeutilitycommand{\noexpand\mainreference{\referenceprefix}{\lastreference}{#4}{#5}{#6}}}%
+ \fi
+ \egroup}
+
+%D We will implement \type {\doiffirstreferenceoccurance}
+%D later on.
%D These macros depend on three other ones,
%D \type {\makesectionformat}, that generated \type
@@ -215,8 +215,6 @@
%D different alphabet and needs accented entries in registers.
\appendtoks
- %\def\dohandleaccent #1#2{\string#1\string#2}%
- %\def\dohandlecommand #1{\string#1}%
\cleanupfeatures
\to \everyreference
@@ -671,20 +669,19 @@
\newif\ifreferencefound
-\let\currentfullreference =\empty
-\let\currentreferencespecial =\empty
-\let\currentreferenceoperation=\empty
-\let\currentreferencearguments=\empty
-\let\currentouterreference =\empty
-\let\currentinnerreference =\empty
-
-\def\setreferencevariables#1#2#3#4#5#6%
- {\def\currentfullreference {#1}%
- \def\currentreferencespecial {#2}%
- \def\currentreferenceoperation{#3}%
- \def\currentreferencearguments{#4}%
- \def\currentouterreference {#5}%
- \def\currentinnerreference {#6}}
+\let\currentfullreference \empty
+\let\currentreferencespecial \empty
+\let\currentreferenceoperation\empty
+\let\currentreferencearguments\empty
+\let\currentouterreference \empty
+\let\currentinnerreference \empty
+
+\def\setreferencevariables#1#2#3#4#5%
+ {\def\currentreferencespecial {#1}%
+ \def\currentreferenceoperation{#2}%
+ \def\currentreferencearguments{#3}%
+ \def\currentouterreference {#4}%
+ \def\currentinnerreference {#5}}
\def\splitofffullreference#1%
{\edef\currentfullreference{#1}%
@@ -1835,12 +1832,15 @@
% \let\normalover \over
-\definecommand in {\doinatreference\currenttextreference}
-\definecommand at {\doinatreference\currentpagereference}
+\definecommand in {\dospecialin}
+\definecommand at {\dospecialat}
\definecommand about {\dospecialabout}
\definecommand from {\dospecialfrom}
\definecommand over {\dospecialabout} % needed here, else math problems
+\unexpanded\def\dospecialin{\doinatreference\currenttextreference}
+\unexpanded\def\dospecialat{\doinatreference\currentpagereference}
+
\unexpanded\def\dospecialabout[#1]%
{\dontleavehmode
\bgroup
@@ -1896,9 +1896,7 @@
%D in a different color and typeface).
\def\doinatreference#1%
- {\doifnextcharelse[% {[}
- {\dodoinatreference{#1}{}}
- {\dodoinatreference{#1}}}
+ {\doifnextoptionalelse{\dodoinatreference{#1}{}}{\dodoinatreference{#1}}}
\def\dodoinatreference#1%
{\def\dododoinatreference{\dodododoinatreference{#1}}%
@@ -2068,7 +2066,7 @@
{\dontleavehmode % replaces \leaveoutervmode
\bgroup
\forgetall
- \postponefootnotes
+ \postponenotes
%\leaveoutervmode % replaced by \dontleavehmode
\doifreferencefoundelse{#3}
{\bgroup
@@ -2120,7 +2118,7 @@
\def\dogoto#1[#2]%
{\dontleavehmode
\bgroup
- \postponefootnotes
+ \postponenotes
\doifreferencefoundelse{#2}
{\doifelsenothing{#1}
{\dosymbolreference{}{}[#2]}
@@ -2284,13 +2282,6 @@
\let\useurl\useURL
-% \def\dodouseURL[#1][#2][#3][#4]%
-% {\iffirstargument
-% \iffourthargument\setgvalue{\v!file:::#1}{\doexternaldocument{#2}{#3}{#4}}\else
-% \ifthirdargument \setgvalue{\v!file:::#1}{\doexternaldocument{#2}{#3}{\url[#1]}}\else
-% \ifsecondargument\setgvalue{\v!file:::#1}{\doexternaldocument{#2}{}{\url[#1]}}\fi\fi\fi
-% \fi}
-
\def\dodouseURL[#1][#2][#3][#4]% to be redone: not too tricky redefs ad reuse
{\iffirstargument
\iffourthargument\setgvalue{\v!file:::#1}{\doexternaldocument{#2}{#3}{#4}}\else
@@ -2633,31 +2624,15 @@
\let\currentinnerreference\currentreferenceoperation
\fi
\ifx\currentouterreference\empty
-% numexpr
- \doifinstringelse+\currentinnerreference
- {\scratchcounter\realpageno
- \advance\scratchcounter \currentinnerreference
- \edef\currentinnerreference{\the\scratchcounter}}
- {\doifinstringelse-\currentinnerreference
- {\scratchcounter\realpageno
- \advance\scratchcounter \currentinnerreference
- \edef\currentinnerreference{\the\scratchcounter}}
- \donothing}%
- \doifnonzeropositiveelse\currentinnerreference
- \donothing
- {\edef\currentinnerreference{1}}%
+ \doifinstringelse+\currentinnerreference{\edef\currentinnerreference{\the\numexpr\realpageno\currentinnerreference}}
+ {\doifinstring -\currentinnerreference{\edef\currentinnerreference{\the\numexpr\realpageno\currentinnerreference}}}%
+ \doifnonzeropositiveelse\currentinnerreference\donothing{\edef\currentinnerreference{1}}%
\docheckrealreferencepage\currentinnerreference % new
\let\currentrealreference\currentinnerreference % handy to have this available
\gotorealpage\empty\empty\currentinnerreference{#2}%
\else
\setouterlocation\currentouterreference
- \doifnonzeropositiveelse\currentinnerreference
- \donothing
- {\ifcsname\v!page:::\currentinnerreference\endcsname
- \edef\currentinnerreference{\getvalue{\v!page:::\currentinnerreference}}%
- \else
- \edef\currentinnerreference{1}%
- \fi}%
+ \doifnonzeropositiveelse\currentinnerreference\donothing{\edef\currentinnerreference{\executeifdefined{\v!page:::\currentinnerreference}1}}%
\gotorealpage\otherURL\otherfile\currentinnerreference{#2}%
\fi
\else
@@ -2761,7 +2736,7 @@
\endgroup
\fi}
-\def\coupledocument%
+\def\coupledocument
{\doquadrupleempty\docoupledocument}
%D --- STRANGE HERE, BETTER IN CORE-NAV ---
@@ -2983,8 +2958,6 @@
%D Plugin code:
-\loadmarkfile{core-ref}
-
%D In the next settings we see some variables that were not
%D used here and that concern the way the pagenumbers refered
%D to are typeset.
diff --git a/tex/context/base/core-reg.lua b/tex/context/base/core-reg.lua
deleted file mode 100644
index 820d316a6..000000000
--- a/tex/context/base/core-reg.lua
+++ /dev/null
@@ -1,186 +0,0 @@
-if not modules then modules = { } end modules ['core-reg'] = {
- version = 1.001,
- comment = "companion to core-reg.tex",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-sorters = sorters or { }
-sorters.register = sorters.register or { }
-
--- {'e','3','','test+test+test','2--0-0-0-0-0-0-0--1','1'}
-
-function sorters.register.compare(a,b)
- local result = 0
- for i=1,4 do
- if result == 0 then
- result = sorters.comparers.basic(a,b,i)
- else
- return result
- end
- end
- if a[1] ~= 's' then -- e/f/t
- local page_a, page_b = a[3], b[3]
- if page_a < page_b then
- return -1
- elseif page_a > page_b then
- return 1
- end
- end
- return 0
-end
-
-function sorters.register.prepare(data)
- sorters.prepare(data,sorters.splitters.utf,4)
-end
-
-function sorters.register.sort(data)
- sorters.sort(data,sorters.register.compare)
-end
-
-function sorters.register.unique(data)
- sorters.unique(data)
-end
-
-function sorters.register.cleanup(data)
- sorters.cleanup(data)
-end
-
-function sorters.register.finalize(data)
- local split = { }
- for k,v in ipairs(data) do
- local entry, tag = v[2][1][3][1], ""
- local se = sorters.entries[sorters.language]
- if se and se[entry] then
- if type(se[entry]) == "number" then
- entry = se[entry]
- end
- tag = se[entry]
- else
- entry = 0
- tag = "unknown"
- end
- split[entry] = split[entry] or { tag = tag, data = { } }
- split[entry].data[#split[entry].data+1] = v
- end
- return split
-end
-
--- \registerpage{index}{,}{6}{2--0-0-0-0-0-0-0--1}{1}
-
--- for the moment we use the old structure, some day mkiv code
--- will be different: more structure, less mess
-
-local template = {
- page = "\\registerpage{%s}{%s}{%s}{%s}{%s}",
- see = "\\registersee{%s}{%s}{%s}{%s}",
- letter = "\\registerentry{%s}{%s}",
- entry = {
- "\\registerentrya{%s}{%s}",
- "\\registerentryb{%s}{%s}",
- "\\registerentryc{%s}{%s}",
- "\\registerentryd{%s}{%s}",
- },
-}
-
-function sorters.register.flush(sorted,class)
- class = class or 'index'
- for k,v in ipairs(table.sortedkeys(sorted)) do
- local s = sorted[v]
- tex.sprint(tex.ctxcatcodes,template.letter:format(class,s.tag))
- local done = { false, false, false }
- for kk,vv in ipairs(s.data) do
- if vv[2][1] then
- local e = { false, false, false, false }
- for i=1,4,1 do
- if vv[2][i] then
- e[i] = vv[2][i][1]
- end
- if e[i] ~= done[i] then
- if e[i] and e[i] ~= "" then
- done[i] = e[i]
- tex.sprint(tex.ctxcatcodes,template.entry[i]:format(class,e[i]))
- else
- done[i] = false
- end
- end
- end
- if vv[1] == 'e' then
- -- format reference pagespec realpage
- tex.sprint(tex.ctxcatcodes,template.page:format(class,",",vv[4],vv[5],vv[3]))
- elseif vv[1] == 's' then
- tex.sprint(tex.ctxcatcodes,template.see:format(class,",",vv[5],vv[3]))
- end
- end
- end
- end
-end
-
-function sorters.register.process(data)
- return sorters.process('register',data)
-end
-
--- { { entry, key }, { entry, key }, { entry, key }, { entry, key } }, kind, realpage|see, reference, pagespec
-
-jobregisters = jobregisters or { }
-jobregisters.collected = jobregisters.collected or { }
-jobregisters.tobesaved = jobregisters.tobesaved or { }
-
-job.register('jobregisters.collected', jobregisters.tobesaved)
-
-local function allocate(class)
- local d = jobregisters.tobesaved[class]
- if not d then
- d = {
- language = 'en',
- entries = { },
- sorted = false,
- class = class
- }
- jobregisters.tobesaved[class] = d
- end
- return d
-end
-
-local function collect(class)
- return jobregisters.collected[class]
-end
-
-jobregisters.define = allocate
-
-function jobregisters.save_entry(class,kind,reference,key,entry,page,realpage) -- realpage|see
- local data = allocate(class).entries
- if type(entry) == 'string' then
- entry = entry:splitchr('+')
- end
- if type(key) == 'string' then
- key = key:splitchr('+')
- end
- data[#data+1] = {
- kind, -- kind (e, f, t, s)
- {
- { entry[1] or "", key[1] or "" },
- { entry[2] or "", key[2] or "" },
- { entry[3] or "", key[3] or "" },
- { entry[4] or "", key[4] or "" }
- },
- realpage, -- realpage or seeword (check see)
- reference, -- reference
- page, -- pagespec
- }
-end
-
-jobregisters.save_see = jobregisters.save_entry
-
-function jobregisters.save_variable(class,key,value)
- if key == "l" then key = "language" end
- allocate(class)[key] = value
-end
-
-function jobregisters.process(class)
- local data = collect(class)
- if data then
- return sorters.register.process(data)
- end
-end
diff --git a/tex/context/base/core-reg.mkii b/tex/context/base/core-reg.mkii
deleted file mode 100644
index bd925d568..000000000
--- a/tex/context/base/core-reg.mkii
+++ /dev/null
@@ -1,33 +0,0 @@
-%D \module
-%D [ file=core-reg,
-%D version=2007.05.07,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Register Management,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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
-
-% the spaces between } { are essential for texutil's split
-
-\def\mkdefineregister#1% class
- {\addutilityreset{#1}}
-
-\def\mksaveregisterentry#1#2#3#4#5#6#7% class type reference key entry pagespec realpage
- {\expanded{\writeutility{r #2 {#1} {#3} {#4} {#5} {#6} {#7}}}}
-
-\def\mksaveregistersee#1#2#3#4#5#6#7% class type reference key entry see pagespec
- {\expanded{\writeutility{r #2 {#1} {#3} {#4} {#5} {#6} {#7}}}}
-
-\def\mksaveregistervariable#1#2#3% class type value
- {\expanded{\immediatewriteutility{r #2 {#1} {#3}}}}
-
-\def\mkloadregister#1#2#3% class before after
- {\doutilities{#1}{\registerparameter\c!file}{#1}{#2}{#3}}
-
-\protect \endinput
diff --git a/tex/context/base/core-reg.mkiv b/tex/context/base/core-reg.mkiv
deleted file mode 100644
index 6b7ee4e30..000000000
--- a/tex/context/base/core-reg.mkiv
+++ /dev/null
@@ -1,40 +0,0 @@
-%D \module
-%D [ file=core-reg,
-%D version=2007.05.07,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Register Management,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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
-
-\registerctxluafile{core-reg}{1.001}
-
-\def\mkdefineregister#1% class
- {\ctxlua{jobregisters.define('#1')}}
-
-\def\mksaveregisterentry#1#2#3#4#5#6#7% class type reference key entry pagespec realpage
- {\expanded{\ctxlatelua{jobregisters.save_entry('#1','#2','#3',\!!bs#4\!!es,\!!bs#5\!!es,'#6','#7')}}}
-
-\def\mksaveregistersee#1#2#3#4#5#6#7% class type reference key entry see pagespec
- {\expanded{\ctxlatelua{jobregisters.save_see('#1','#2','#3',\!!bs#4\!!es,\!!bs#5\!!es,'#6','#7')}}}
-
-\def\mksaveregistervariable#1#2#3% class type value
- {\expanded{\ctxlua{jobregisters.save_variable('#1','#2','#3')}}}
-
-% Beware, we have no filename support here. For that we need to save the resulting
-% tex code in a file. No big deal.
-
-\def\mkloadregister#1#2#3% class, todo: loader macro just like mkii
- {\bgroup
- \getvalue{\s!set#1}% smells like a hack
- #2\ctxlua{jobregisters.process('#1')}#3% par needed for hanging indentation
- \getvalue{\s!reset#1}%
- \egroup}
-
-\protect \endinput
diff --git a/tex/context/base/core-reg.tex b/tex/context/base/core-reg.tex
index af779c0b2..1d139a2dc 100644
--- a/tex/context/base/core-reg.tex
+++ b/tex/context/base/core-reg.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Register Management}
+\writestatus{loading}{ConTeXt Core Macros / Register Management}
\newif \ifautoregisterhack % for the moment a private hack
@@ -81,14 +81,6 @@
\newif\ifwritetoregister \writetoregistertrue
-\ifx\undefined\mkdefineregister
- \let\mkdefineregister \gobbleoneargument
- \let\mksaveregistervariable\gobblethreearguments
- \let\mksaveregisterentry \gobblesevenarguments
- \let\mksaveregistersee \gobblesevenarguments
- \let\mkloadregister \gobbleoneargument
-\fi
-
\chardef\registerpagestatus\zerocount
\def\doprocesspageregister[#1]#2#3% key altnum entry
@@ -105,15 +97,13 @@
\makesectionformat
\doifelse{\registerparameter\c!ownnumber}\v!yes
\donetrue\donefalse
- \mksaveregisterentry
- {\currentregister}
- {\ifcase\registerpagestatus\space\or e\or f\or t\fi}
- {\nextinternalreference}
- {\asciiregisterentryA}
- {\asciiregisterentryB}
- {\sectionformat\sectionseparator\sectionseparator
- \ifdone#2\else\noexpand\pagenumber\fi}
- {\noexpand\realfolio}%
+ \expanded{\writeutility{r % spaces are essential
+ {\ifcase\registerpagestatus\space\or e\or f\or t\fi} {\currentregister} %
+ {\nextinternalreference} %
+ {\asciiregisterentryA} %
+ {\asciiregisterentryB} %
+ {\sectionformat\sectionseparator\sectionseparator\ifdone#2\else\noexpand\pagenumber\fi} %
+ {\noexpand\realfolio}}}%
\getfirstcharacter\currentregister
\registerinfo{> \firstcharacter}{#3}%
\endgroup
@@ -197,14 +187,13 @@
\defconvertexpanded\asciiregisterentryA{\registerparameter\c!keyexpansion}{#2}%
\fi}%
\makesectionformat
- \mksaveregistersee
- {\currentregister}
- {s}
- {\nextinternalreference}
- {\asciiregisterentryA}
- {\asciiregisterentryB}
- {\asciiregisterentryC}
- {\sectionformat}%
+ \expanded{\writeutility{r s %
+ {\currentregister} %
+ {\nextinternalreference} %
+ {\asciiregisterentryA} %
+ {\asciiregisterentryB} %
+ {\asciiregisterentryC} %
+ {\sectionformat}}}%
\endgroup
\registerinfo{> see}{#2}%
\fi}
@@ -890,7 +879,7 @@
\let\dosetregister\doloadregisterlinks
\def\currentregister{#1}%
\setupregister[#1][#2]%
- \mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister
+ \doutilities\currentregister{\registerparameter\c!file}\currentregister\dobeforeplaceregister\doafterplaceregister
\endgroup
\ifautoregisterhack
\doinitializeautoregister{#1}%
@@ -1109,7 +1098,7 @@
tolerance=stretch]%
\dontcomplain
\startpacked[\v!blank]%
- \mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister
+ \doutilities\currentregister{\registerparameter\c!file}\currentregister\dobeforeplaceregister\doafterplaceregister
\stoppacked
\stopcolumns
\endgroup
@@ -1138,7 +1127,7 @@
\def\doregisterregisterlanguage#1%
{\savesortlanguage{\getvalue{\??id#1\s!language}}%
- \mksaveregistervariable{#1}{l}{\getvalue{\??id#1\s!language}}}
+ \expanded{\immediatewriteutility{r l {#1} {\getvalue{\??id#1\s!language}}}}}
\def\dodefineregister[#1][#2]%
{\setupregister[#1]%
@@ -1174,7 +1163,7 @@
\doregisterregisterlanguage{#1}%
\to \everysavesortkeys
\presetheadtext[#1=\Word{#1}]%
- \mkdefineregister{#1}%
+ \addutilityreset{#1}%
\setvalue{#1}{\doregister{#1}}%
\setvalue{\e!coupled#1}{\dolinkedregister{#1}}%
\setvalue{\s!set#1}{\dosetregister{#1}}%
@@ -1204,7 +1193,7 @@
\global\utilitydonetrue}
{}}%
\doglobal\newcounter\utilityregisterlength
- \setbox0\vbox{\mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister}%
+ \setbox0\vbox{\doutilities\currentregister{\registerparameter\c!file}\currentregister\dobeforeplaceregister\doafterplaceregister}%
\endgroup
\ifregistergeplaatst
\setsystemmode \v!register
@@ -1215,10 +1204,6 @@
\def\determineregistercharacteristics
{\dodoubleempty\dodetermineregistercharacteristics}
-%D Plugins.
-
-\loadmarkfile{core-reg}
-
%D Default index:
\defineregister
diff --git a/tex/context/base/core-rul.lua b/tex/context/base/core-rul.lua
index 1c93542db..6947c7f7b 100644
--- a/tex/context/base/core-rul.lua
+++ b/tex/context/base/core-rul.lua
@@ -18,7 +18,6 @@ function commands.doreshapeframedbox(n)
local list = tex.box[n].list
for h in node.traverse_id('hlist',list) do
done = true
- -- local p = hpack(h.list)
local p = hpack(copy(h.list))
lastlinelength = p.width
if lastlinelength > width then
diff --git a/tex/context/base/core-rul.mkii b/tex/context/base/core-rul.mkii
index 4381a8d5a..59bfd2f3c 100644
--- a/tex/context/base/core-rul.mkii
+++ b/tex/context/base/core-rul.mkii
@@ -11,12 +11,1864 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Ruled Content Handling}
+
\unprotect
+%D We have removed the rather old and out dated raster methods. They
+%D have not been used for ages.
+
+%D \macros
+%D {linewidth, setuplinewidth}
+%D
+%D This module deals with rules (lines) in several ways. First
+%D we introduce two macros that can be used to set some common
+%D characteristics.
+%D
+%D \showsetup{setuplinewidth}
+%D
+%D The linewidth is available in \type{\linewidth}. The
+%D preset value of .4pt equals the default hard coded \TEX\
+%D rule width.
+
+\newdimen\linewidth
+
+\def\dosetuplinewidth[#1]%
+ {\assigndimension{#1}\linewidth{.2\points}{.4\points}{.6\points}}
+
+\def\setuplinewidth
+ {\dosingleargument\dosetuplinewidth}
+
+%D \macros
+%D {ruledlinewidth, inheritruledlinewidth}
+%D
+%D Inside framed boxed we will use a private dimensions. As
+%D an option one can let the linewidth inherit its value from
+%D this one.
+
+\newdimen\ruledlinewidth \newif\ifinheritruledlinewidth
+
+% %D \TEX\ lacks support for color and even gray scales. The next
+% %D macros can provide a sort of poor mans gray scales as well
+% %D as give access to more suitable methods of rendering. Such a
+% %D method looks like:
+% %D
+% %D \starttyping
+% %D \def\methodegraybox#1#2#3#4#5#6%
+% %D { ... }
+% %D \stoptyping
+% %D
+% %D The string \type{graybox} is a common element in the name,
+% %D so we can have for instance \type {\postscriptgraybox} or
+% %D \type {\texgraybox}. The first three arguments take a
+% %D dimension, the fourth one takes a number between~0 and~1,
+% %D and the last argument specifies a radius of the box when
+% %D rounded corners are used, so:
+% %D
+% %D \startbuffer
+% %D \dotgraybox{.5\hsize}{1cm}{0cm}{.85}{\v!no}{0pt}
+% %D \stopbuffer
+% %D
+% %D \typebuffer
+% %D
+% %D becomes:
+% %D
+% %D %\startlinecorrection
+% %D % \vbox to 1cm{\getbuffer}
+% %D %\stoplinecorrection
+% %D
+% %D \startlinecorrection
+% %D \unprotect
+% %D \vbox to 1cm{\dotgraybox{.5\hsize}{1cm}{0cm}{.85}{\v!no}{0pt}}
+% %D \protect
+% %D \stoplinecorrection
+% %D
+% %D There are two predefined methodes, one uses periods and the
+% %D other uses small rules. The second method is less
+% %D efficient, but sometimes give better results. The dimensions
+% %D of the resullting box are set to zero.
+%
+% \setvalue{\v!dot graybox}{\processraster\symbol\rasterdot}
+% \setvalue{\v!rule graybox}{\processraster\symbol\rasterbox}
+%
+% \def\rasterdot{\rasterfont.}
+% \def\rasterbox{\hss\vrule\!!width.4pt\!!height.4pt\!!depth\zeropoint}
+%
+% %D Now of course we need:
+%
+% \ifx\rasterfont\undefined \def\rasterfont{\fivepoint} \fi
+%
+% %D We implement two pure \TEX\ based generators, that use
+% %D \type{\leaders} to quickly gerenate the gray pattern. One
+% %D should beware of \DIMENSION\ conflicts, so we use some
+% %D registers above~8. These macros are memory hungry and byte
+% %D spoiling.
+%
+% \def\processraster#1#2#3#4#5#6#7%
+% {\bgroup
+% \forgetall
+% \dontcomplain
+% \dimen10=\onepoint
+% \dimen10=\@@rsfactor\dimen10
+% \dimen10=#5\dimen10
+% \setbox2\hbox to #2
+% {\cleaders\hbox to 2\dimen10{#1\hss}\hss}%
+% \dimen12=#3%
+% \advance\dimen12 #4%
+% % \setbox0\vbox to \dimen12
+% {\cleaders\vbox to 2\dimen10{\box2\vss}\vss}%
+% \setbox0\hbox
+% {\hskip-.5\dimen10\lower0.5\dimen10\copy0
+% \hskip-\wd0\hskip\dimen10\lower1.5\dimen10\box0}%
+% \box0
+% \egroup}
+
+%D \macros
+%D {setupscreens}
+%D
+%D The previous macro uses a predefined constant
+%D \type{\@@rsfactor}. This factor can be set by:
+%D
+%D \showsetup{setupscreens}
+
+\def\setupscreens
+ {\dodoubleargument\getparameters[\??rs]}
+
+% %D The most appropriate way to call for this feature is
+% %D using \type{\graybox}, which is defined as:
+%
+% \def\graybox{\getvalue{\@@rsmethod graybox}}
+%
+% %D We just introduced two pure \TEX\ methods for generating
+% %D rasters. However, it's far more efficient and comfortable in
+% %D terms of speed, memory usage and file size, to use a driver
+% %D supported method.
+%
+% \setvalue{\v!external graybox}{\setgraybox}
+%
+% %D For compatibility reasons we also define the original one:
+%
+% \setvalue{\v!postscript graybox}{\getvalue{\v!external graybox}}
+%
+% %D A quite valid way of letting drivers do the job, is giving
+% %D a solid rule a gray texture.
+
+%D We will communicate through module specific variables, current
+%D framed parameters and some reserved dimension registers.
+
+\newdimen \frameddimenwd
+\newdimen \frameddimenht
+\newdimen \frameddimendp
+
+%D We don't have to stick to a \TEX\ drawn rule, but
+%D also can use rounded or even fancier shapes, as we will
+%D see later on.
+
+\def\dofilledbox
+ {\bgroup
+ \doifelse{\framedparameter\c!backgroundcorner}\v!rectangular
+ {\dofilledlinedbox}
+ {\ifzeropt\dimexpr\framedparameter\c!backgroundradius\relax % just in case of .x\bodyfontsize
+ \dofilledlinedbox
+ \else
+ \dofilledroundbox
+ \fi}%
+ \egroup}
+
+\def\dophantombox
+ {\hphantom{\dofilledbox}}
+
+\def\dofilledlinedbox
+ {\vrule\!!width\frameddimenwd\!!height\frameddimenht\!!depth\frameddimendp\relax}%
+
+\def\dostrokedroundbox
+ {\doif{\framedparameter\c!frame}\v!on\dodostrokedroundbox}
+
+\def\dodostrokedroundbox
+ {\bgroup
+ \edef\ovalmod{\framedparameter\c!framecorner}%
+ \doifelse\ovalmod\v!round{\let\ovalmod\!!zerocount}{\edef\ovalmod{\number\ovalmod}}%
+ \edef\ovalwid{\the\frameddimenwd}%
+ \edef\ovalhei{\the\frameddimenht}%
+ \edef\ovaldep{\the\frameddimendp}%
+ \edef\ovallin{\the\dimexpr\ruledlinewidth}%
+ \edef\ovalrad{\the\dimexpr\framedparameter\c!frameradius}%
+ \let\ovalstr\!!plusone
+ \let\ovalfil\!!zerocount
+ \forcecolorhack
+ \doovalbox\ovalwid\ovalhei\ovaldep\ovallin\ovalrad\ovalstr\ovalfil\ovalmod
+ \egroup}
+
+\def\dofilledroundbox
+ {\bgroup
+ \edef\ovalmod{\framedparameter\c!backgroundcorner}%
+ \doifelse\ovalmod\v!round{\let\ovalmod\!!zerocount}{\edef\ovalmod{\number\ovalmod}}%
+ \edef\ovalwid{\the\frameddimenwd}%
+ \edef\ovalhei{\the\frameddimenht}%
+ \edef\ovaldep{\the\frameddimendp}%
+ \edef\ovallin{\the\dimexpr\ruledlinewidth\relax}%
+ \edef\ovalrad{\the\dimexpr\framedparameter\c!backgroundradius\relax}%
+ \let\ovalstr\!!zerocount
+ \let\ovalfil\!!plusone
+ \forcecolorhack
+ \doovalbox\ovalwid\ovalhei\ovaldep\ovallin\ovalrad\ovalstr\ovalfil\ovalmod
+ \egroup}
+
+% a lot of weird corners
+%
+% \startTEXpage
+% \dontleavehmode\framed
+% [corner=0,frame=on,framecolor=green,
+% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green,
+% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green,
+% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {9}{12}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{13}{16}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{17}{20}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{21}{24}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{25}{28}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \stopTEXpage
+
+%D The oval box is drawn using a special macro, depending on
+%D the driver in use.
+
+\def\dograybox % avoid black rules when no gray
+ {\doifelsenothing{\framedparameter\c!backgroundscreen}
+ {\dophantombox}
+ {\raster[\framedparameter\c!backgroundscreen]{\dofilledbox}}}
+
+%D It won't be a surprise that we not only provide gray boxes,
+%D but also colored ones. Here it is:
+
+\def\docolorbox
+ {\hbox{\ifincolor
+ \doifcolorelse{\framedparameter\c!backgroundcolor}
+ {\localcolortrue\color[\framedparameter\c!backgroundcolor]{\dofilledbox}}
+ {\dophantombox}%
+ \else
+ \dophantombox
+ \fi}}
+
+%D \macros
+%D {defineoverlay, doifoverlayelse, overlayoffset,
+%D overlaywidth, overlayheight, overlaydepth,
+%D overlaycolor, overlaylinecolor, overlaylinewidth}
+%D
+%D Before we define the macro that actually takes card of the
+%D backgrounds, we introduce overlays. An overlay is something
+%D that contrary to its name lays {\em under} the text. An
+%D example of an overlay definition is:
+%D
+%D \startbuffer[tmp-1]
+%D \defineoverlay
+%D [fancy]
+%D [{\externalfigure
+%D [mp-cont.502]
+%D [width=\overlaywidth,
+%D height=\overlayheight]}]
+%D \stopbuffer
+%D
+%D \typebuffer[tmp-1]
+%D
+%D That for instance can be uses in:
+%D
+%D \startbuffer[tmp-2]
+%D \framed[backgroundachtergrond=fancy]{How Fancy!}
+%D \framed[backgroundachtergrond=fancy,frame=off]{Even More Fancy!}
+%D \stopbuffer
+%D
+%D and looks like:
+%D
+%D \startlinecorrection
+%D \vbox{\baselineskip24pt\getbuffer[tmp-1]\getbuffer[tmp-2]}
+%D \stoplinecorrection
+%D
+%D The formal definition is:
+%D
+%D \showsetup{defineoverlay}
+%D
+%D This macro's definition is a bit obscure, due the many
+%D non||used arguments and the two step call that enable the
+%D setting of the width, height and depth variables.
+%D Multiple backgrounds are possible and are specified as:
+%D
+%D \starttyping
+%D \framed[background={one,two,three}]{Three backgrounds!}
+%D \stoptyping
+%D
+%D Most drawing packages only know width and height. Therefore
+%D the dimensions have a slightly different meaning here:
+%D
+%D \startitemize[packed]
+%D \item \type{\overlaywidth }: width of the overlay
+%D \item \type{\overlayheight}: height plus depth of the overlay
+%D \item \type{\overlaydepth }: depth of the overlay
+%D \stopitemize
+%D
+%D The resulting box is lowered to the right depth.
+
+\def\overlaywidth {\the\hsize\space} % We preset the variables
+\def\overlayheight {\the\vsize\space} % to some reasonable default
+\let\overlaydepth \!!zeropoint % values. The attributes
+\let\overlayoffset \!!zeropoint % of the frame can be (are)
+\let\overlaycolor \empty % set somewhere else.
+\let\overlaylinewidth \!!zeropoint %
+\let\overlaylinecolor \empty %
+
+%D The next register is used to initialize overlays.
+
+\newtoks\everyoverlay
+
+%D An example of an initialization is the following (overlays
+%D can contain text and be executed under an regime where
+%D interlineskip is off).
+
+\appendtoks \oninterlineskip \to \everyoverlay
+
+\def\defineoverlay
+ {\dodoubleargument\dodefineoverlay}
+
+\def\dodefineoverlay[#1][#2]%
+ {\def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}%
+ \processcommalist[#1]\docommand}
+
+\prependtoks
+ \hsize\overlaywidth
+ \vsize\overlayheight
+\to\everyoverlay
+
+\long\def\executedefinedoverlay#1#2%
+ {\bgroup
+ \edef\overlaywidth {\the\frameddimenwd\space}%
+ \edef\overlayheight{\the\dimexpr\frameddimenht+\frameddimendp\relax\space}%
+ \edef\overlaydepth {\the\frameddimendp\space}%
+ \edef\overlaycolor {\framedparameter\c!backgroundcolor}%
+ %\edef\overlaycorner{\framedparameter\c!backgroundcorner}%
+ %\edef\overlayradius{\framedparameter\c!backgroundradius}%
+ \let\overlayoffset\backgroundoffset % we steal this one
+ \setbox\scratchbox\hbox{\lower\overlaydepth\hbox{\the\everyoverlay#2}}%
+ \setbox\scratchbox\hbox
+ {\hskip-.5\dimexpr\wd\scratchbox-\overlaywidth \relax
+ \raise-.5\dimexpr\ht\scratchbox-\frameddimenht\relax % not overlayheight !
+ \box\scratchbox}%
+ \wd\scratchbox\overlaywidth
+ \ht\scratchbox\overlayheight
+ \dp\scratchbox\overlaydepth
+ \startlayoutcomponent{o:#1}{overlay #1}%
+ \box\scratchbox
+ \stoplayoutcomponent
+ \egroup}
+
+%D The empty case is:
+
+\let\executeoverlay\gobblesevenarguments
+
+%D For testing we provide:
+
+\def\doifoverlayelse#1%
+ {\doifdefinedelse{\??ov#1}}
+
+%D We predefine two already familiar backgrounds:
+
+\setvalue{\??ov\v!screen}{\dograybox }
+\setvalue{\??ov\v!color }{\docolorbox}
+
+% %D After all these preparations, the background macro does no
+% %D bring to many surprises. One has to keep in mind that this
+% %D macro starts up a call chain, depending on the background
+% %D one needs:
+% %D
+% %D \startitemize[packed]
+% %D \item a raster, color or user defined shape
+% %D \item square or round corners
+% %D \item a \TEX\ or driver based method
+% %D \stopitemize
+% %D
+% %D The macro can be extended by adding commands to the token
+% %D list register \type {\everybackgroundbox}. For this
+% %D purpose, the name of the current background is available in
+% %D \type {\currentbackgound}.
+
+%D The content of the box will be (temporary) saved in a box. We
+%D also have an extra box for backgrounds.
+
+\newbox\framebox
+\newbox\extraframebox
+
+\newtoks\everybackgroundbox
+
+\let\currentbackground\empty
+
+% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method
+% {\bgroup
+% \def\currentbackground{#1}%
+% \the\everybackgroundbox
+% \setbox\extraframebox\hbox
+% {\vbox{\moveleft\backgroundoffset\hbox{\executeifdefined{\??ov\currentbackground}\donothing}}}%
+% \wd\extraframebox\zeropoint % \backgroundwidth
+% \ht\extraframebox\backgroundheight
+% \dp\extraframebox\backgrounddepth
+% \box\extraframebox % \hskip-\backgroundwidth
+% \egroup}
+
+% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method
+% {\bgroup
+% \def\currentbackground{#1}%
+% \ifcsname\??ov\currentbackground\endcsname
+% \the\everybackgroundbox
+% \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}%
+% \wd\extraframebox\zeropoint % \backgroundwidth
+% \ht\extraframebox\backgroundheight
+% \dp\extraframebox\backgrounddepth
+% \box\extraframebox % \hskip-\backgroundwidth
+% \fi
+% \egroup}
+
+\def\dodobackgroundbox
+ {\bgroup
+ \ifcsname\??ov\currentbackground\endcsname
+ \the\everybackgroundbox
+ \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}%
+ \wd\extraframebox\zeropoint % \backgroundwidth
+ \ht\extraframebox\backgroundheight
+ \dp\extraframebox\backgrounddepth
+ \box\extraframebox % \hskip-\backgroundwidth
+ \fi
+ \egroup}
+
+\def\dododobackgroundbox#1,#2% #2 gobbles spaces
+ {\edef\currentbackground{#1}%
+ \ifx\currentbackground\s!unknown\else
+ \dodobackgroundbox\expandafter\dododobackgroundbox
+ \fi#2}
+
+\let\backgroundoffset\!!zeropoint
+\let\backgrounddepth \!!zeropoint
+\def\backgroundwidth {\the\hsize}
+\def\backgroundheight{\the\vsize}
+
+% todo: also \def\theforegroundbox{#1}
+
+% \def\dobackgroundbox#1%
+% {\setbox\framebox\vbox
+% {\forgetall
+% \boxmaxdepth\maxdimen
+% \scratchdimen \framedparameter{#1}\relax
+% \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
+% \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
+% \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax
+% \edef\backgroundoffset{\the\scratchdimen}%
+% \edef\backgroundwidth {\the\wd\framebox}%
+% \edef\backgroundheight{\the\ht\framebox}%
+% \edef\backgrounddepth {\the\dp\framebox}%
+% %\edef\foregroundbox{\box#1}%
+% \def\foregroundbox% fuzzy but needed hack, this \vss, otherwise
+% {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift
+% \edef\component{\framedparameter\c!component}%
+% \hbox to \backgroundwidth % in case 'foreground' is used as overlay
+% {\ifx\component\empty
+% \rawprocesscommalist[\framedbackground]\dodobackgroundbox
+% \else
+% \startlayoutcomponent{b:\component}{\s!background\space\component}%
+% \rawprocesscommalist[\framedbackground]\dodobackgroundbox
+% \stoplayoutcomponent
+% \fi
+% \box\framebox\hss}}}
+
+\def\normalforegroundbox% fuzzy but needed hack, this \vss, otherwise
+ {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift
+
+\def\dobackgroundbox#1%
+ {\setbox\framebox\vbox
+ {\forgetall
+ \boxmaxdepth\maxdimen
+ \scratchdimen \framedparameter{#1}\relax
+ \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
+ \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
+ \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax
+ \edef\backgroundoffset{\the\scratchdimen}%
+ \edef\backgroundwidth {\the\wd\framebox}%
+ \edef\backgroundheight{\the\ht\framebox}%
+ \edef\backgrounddepth {\the\dp\framebox}%
+ %\edef\foregroundbox{\box#1}%
+ \edef\component{\framedparameter\c!component}%
+ \let\foregroundbox\normalforegroundbox
+ \hbox to \backgroundwidth % in case 'foreground' is used as overlay
+ {\ifx\component\empty
+ \expanded{\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax
+ \else
+ \startlayoutcomponent{b:\component}{background \component}%
+ \expanded{\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax
+ \stoplayoutcomponent
+ \fi
+ \box\framebox\hss}}}
+
+%D One can explictly insert the foreground box. For that
+%D purpose we introduce the overlay \type {foreground}.
+
+\defineoverlay[\v!foreground][\foregroundbox]
+
+%D We can specify overlays as a comma separated list of
+%D overlays, a sometimes handy feature.
+
+%D Besides backgrounds (overlays) we also need some macros to
+%D draw outlines (ruled borders). Again we have to deal with
+%D square and round corners. The first category can be handled
+%D by \TEX\ itself, the latter one depends on the driver. This
+%D macro also support a negative offset.
+
+\ifx\scratchoffset\undefined \newdimen\scratchoffset \fi
+
+\def\dooutlinebox % we needed to move the color command in order to apply attributes properly
+ {\setbox\framebox\vbox % rules on top of box
+ {\scratchoffset \framedparameter\c!frameoffset\relax
+ \frameddimenwd\dimexpr\wd\framebox+2\scratchoffset\relax
+ \frameddimenht\dimexpr\ht\framebox+ \scratchoffset\relax
+ \frameddimendp\dimexpr\dp\framebox+ \scratchoffset+\framedparameter\c!framedepth\relax
+ \ifdim\frameddimendp<\zeropoint
+ \advance\frameddimenht \frameddimendp
+ \scratchdimen-\frameddimendp
+ \frameddimendp\zeropoint
+ \else
+ \scratchdimen\zeropoint
+ \fi
+ \setbox\extraframebox\hbox
+ {\doifsomething{\framedparameter\c!framecolor}{\color[\framedparameter\c!framecolor]}{\dostrokedbox}}%
+ \setbox\extraframebox\hbox
+ {\raise\scratchdimen\vbox
+ {\moveleft\scratchoffset
+ \box\extraframebox}}%
+ \wd\extraframebox\wd\framebox
+ \ht\extraframebox\ht\framebox
+ \dp\extraframebox\dp\framebox
+ \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}}
+
+\def\dostrokedbox
+ {\doifelse{\framedparameter\c!framecorner}\v!rectangular
+ {\dostrokedlinedbox}
+ {\ifzeropt\dimexpr\framedparameter\c!frameradius\relax % just in case of .x\bodyfontsize
+ \dostrokedlinedbox
+ \else
+ \dostrokedroundbox
+ \fi}}
+
+\def\dostrokedlinedbox
+ {\setbox\scratchbox\null
+ \wd\scratchbox\frameddimenwd
+ \ht\scratchbox\frameddimenht
+ \dp\scratchbox\frameddimendp
+ \setbox\scratchbox\vbox \bgroup
+ \csname t\@@frame@@\framedparameter\c!frame\framedparameter\c!topframe \endcsname
+ \hbox \bgroup
+ \csname l\@@frame@@\framedparameter\c!frame\framedparameter\c!leftframe \endcsname
+ \box\scratchbox
+ \csname r\@@frame@@\framedparameter\c!frame\framedparameter\c!rightframe \endcsname
+ \egroup
+ \csname b\@@frame@@\framedparameter\c!frame\framedparameter\c!bottomframe\endcsname
+ \egroup
+ \wd\scratchbox\frameddimenwd
+ \ht\scratchbox\frameddimenht
+ \dp\scratchbox\frameddimendp
+ \box\scratchbox}
+
+\def\@@frame@@{@@frame@@}
+
+% \setvalue{t\@@frame@@\v!on \v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{t\@@frame@@\v!off\v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{t\@@frame@@\v!on }{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{b\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+% \setvalue{b\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+% \setvalue{b\@@frame@@\v!on }{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+% \setvalue{l\@@frame@@\v!on \v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{l\@@frame@@\v!off\v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{l\@@frame@@\v!on }{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{r\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+% \setvalue{r\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+% \setvalue{r\@@frame@@\v!on }{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+
+\def\@@frame@@trule{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+\def\@@frame@@brule{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+\def\@@frame@@rrule{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+\def\@@frame@@lrule{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+
+\letvalue{t\@@frame@@\v!on \v!on}\@@frame@@trule
+\letvalue{t\@@frame@@\v!off\v!on}\@@frame@@trule
+\letvalue{t\@@frame@@\v!on }\@@frame@@trule
+
+\letvalue{b\@@frame@@\v!on \v!on}\@@frame@@brule
+\letvalue{b\@@frame@@\v!off\v!on}\@@frame@@brule
+\letvalue{b\@@frame@@\v!on }\@@frame@@brule
+
+\letvalue{l\@@frame@@\v!on \v!on}\@@frame@@lrule
+\letvalue{l\@@frame@@\v!off\v!on}\@@frame@@lrule
+\letvalue{l\@@frame@@\v!on }\@@frame@@lrule
+
+\letvalue{r\@@frame@@\v!on \v!on}\@@frame@@rrule
+\letvalue{r\@@frame@@\v!off\v!on}\@@frame@@rrule
+\letvalue{r\@@frame@@\v!on }\@@frame@@rrule
+
+% no overlapping rules
+
+\def\@@frame@@trules{\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}\nointerlineskip\kern-\ruledlinewidth}
+\def\@@frame@@brules{\kern-\ruledlinewidth\nointerlineskip\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}}
+\def\@@frame@@rrules{\kern-\ruledlinewidth\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth}
+\def\@@frame@@lrules{\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth\kern-\ruledlinewidth}
+
+% small is relatively new
+
+\letvalue{t\@@frame@@\v!small\v!small}\@@frame@@trules
+\letvalue{t\@@frame@@\v!off \v!small}\@@frame@@trules
+\letvalue{t\@@frame@@\v!small }\@@frame@@trules
+
+\letvalue{b\@@frame@@\v!small\v!small}\@@frame@@brules
+\letvalue{b\@@frame@@\v!off \v!small}\@@frame@@brules
+\letvalue{b\@@frame@@\v!small }\@@frame@@brules
+
+\letvalue{l\@@frame@@\v!small\v!small}\@@frame@@lrules
+\letvalue{l\@@frame@@\v!off \v!small}\@@frame@@lrules
+\letvalue{l\@@frame@@\v!small }\@@frame@@lrules
+
+\letvalue{r\@@frame@@\v!small\v!small}\@@frame@@rrules
+\letvalue{r\@@frame@@\v!off \v!small}\@@frame@@rrules
+\letvalue{r\@@frame@@\v!small }\@@frame@@rrules
+
+%D I condidered using the low level support command
+%D \type{\ruledhbox}, but this would slow down processing by a
+%D factor~3.
+
+% \framed
+% [width=4cm,height=3cm,rulethickness=3mm,
+% frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on]
+% {}
+% \framed
+% [width=4cm,height=3cm,rulethickness=3mm,
+% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small]
+% {}
+% \framed
+% [width=4cm,height=3cm,rulethickness=3mm,
+% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on]
+% {}
+
+%D The next few macros are probably the most misused ones in
+%D \CONTEXT. They deal with putting rules around boxes, provide
+%D backgrounds, offer alignment features, and some more. We
+%D start with defining some booleans. These give an impression
+%D of what we are going to take into account.
+
+% todo: chardefs
+
+\newif\ifboxhasoffset
+\newif\ifboxhaswidth
+\newif\ifboxhasheight
+\newif\ifboxhasformat
+\newif\ifboxhasstrut
+\newif\ifboxisoverlaid
+\newif\ifboxhasframe
+\newif\ifdelayedstrut
+
+%D We also need a few \DIMENSIONS:
+
+\newdimen\@@localoffset
+\newdimen\@@globalwidth
+
+%D \macros
+%D {framed, setupframed}
+%D
+%D Ruled boxes are typeset using \type{\framed}. This command
+%D is quite versatile and, although some users will probably
+%D seldom use it, one cannot overlook its features.
+%D
+%D \showsetup{setupframed}
+%D \showsetup{framed}
+%D
+%D This general macro is a special version of an even more
+%D general case, that can easily be linked into other macros
+%D that need some kind of framing. The local version is called
+%D with an extra parameter: the variable identifier. The reason
+%D for passing this identifier between brackets lays in the
+%D mere fact that this way we can use the optional argument
+%D grabbers.
+
+\def\defaultframeoffset{.25ex}
+
+\unexpanded\def\framed
+ {\bgroup
+ \copylocalframed[\??ol][\??oi]% == \presetlocalframed[\??ol]%
+ \dodoubleempty\startlocalframed[\??ol]}
+
+\def\presetlocalframed[#1]%
+ {\copylocalframed[#1][\??oi]}
+
+% \def\copylocalframed[#1]#2[#3]%
+% {\copyparameters[#1][#3]%
+% [\c!width,\c!height,\c!radius,\c!corner,\c!depth,\c!offset,%
+% \c!autowidth,\c!empty,\c!component,\c!orientation,\c!lines,%
+% \c!align,\c!bottom,\c!top,\c!strut,\c!autostrut,\c!location,\c!setups,\c!extras,%
+% \c!foregroundstyle,\c!foregroundcolor,%
+% \c!background,\c!backgroundoffset,\c!backgroundcorner,\c!backgroundradius,\c!backgrounddepth,\c!backgroundcolor,\c!backgroundscreen,%
+% \c!frame,\c!frameoffset,\c!framecorner,\c!frameradius,\c!framedepth,\c!framecolor,\c!rulethickness,%
+% \c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe]}
+
+% since framed is used all over the place, we have a (small) speedup)
+
+\def\copylocalframed[#1]#2[#3]%
+ {\edef\copiedfrom{#1}\edef\copiedto{#3}%
+ \docopyvalue\copiedfrom\copiedto\c!width
+ \docopyvalue\copiedfrom\copiedto\c!height
+ \docopyvalue\copiedfrom\copiedto\c!autowidth
+ \docopyvalue\copiedfrom\copiedto\c!offset
+ \docopyvalue\copiedfrom\copiedto\c!empty
+ \docopyvalue\copiedfrom\copiedto\c!rulethickness
+ \docopyvalue\copiedfrom\copiedto\c!radius
+ \docopyvalue\copiedfrom\copiedto\c!corner
+ \docopyvalue\copiedfrom\copiedto\c!depth
+ \docopyvalue\copiedfrom\copiedto\c!frame
+ \docopyvalue\copiedfrom\copiedto\c!framecolor
+ \docopyvalue\copiedfrom\copiedto\c!foregroundstyle
+ \docopyvalue\copiedfrom\copiedto\c!foregroundcolor
+ \docopyvalue\copiedfrom\copiedto\c!lines
+ \docopyvalue\copiedfrom\copiedto\c!orientation
+ \docopyvalue\copiedfrom\copiedto\c!topframe
+ \docopyvalue\copiedfrom\copiedto\c!bottomframe
+ \docopyvalue\copiedfrom\copiedto\c!leftframe
+ \docopyvalue\copiedfrom\copiedto\c!rightframe
+ \docopyvalue\copiedfrom\copiedto\c!rulethickness
+ \docopyvalue\copiedfrom\copiedto\c!frameoffset
+ \docopyvalue\copiedfrom\copiedto\c!background
+ \docopyvalue\copiedfrom\copiedto\c!component
+ \docopyvalue\copiedfrom\copiedto\c!backgroundoffset
+ \docopyvalue\copiedfrom\copiedto\c!backgroundscreen
+ \docopyvalue\copiedfrom\copiedto\c!backgroundcolor
+ \docopyvalue\copiedfrom\copiedto\c!align
+ \docopyvalue\copiedfrom\copiedto\c!bottom
+ \docopyvalue\copiedfrom\copiedto\c!top
+ \docopyvalue\copiedfrom\copiedto\c!strut
+ \docopyvalue\copiedfrom\copiedto\c!autostrut
+ \docopyvalue\copiedfrom\copiedto\c!location
+ \docopyvalue\copiedfrom\copiedto\c!component
+ \docopyvalue\copiedfrom\copiedto\c!extras
+ \docopyvalue\copiedfrom\copiedto\c!setups
+ \docopyvalue\copiedfrom\copiedto\c!backgroundradius
+ \docopyvalue\copiedfrom\copiedto\c!backgroundcorner
+ \docopyvalue\copiedfrom\copiedto\c!backgrounddepth
+ \docopyvalue\copiedfrom\copiedto\c!frameradius
+ \docopyvalue\copiedfrom\copiedto\c!framecorner
+ \docopyvalue\copiedfrom\copiedto\c!framedepth}
+
+\def\setupframed
+ {\dodoubleempty\dosetupframed}
+
+\def\dosetupframed
+ {\ifsecondargument
+ \@EA\dodoublesetupframed
+ \else
+ \@EA\dosinglesetupframed
+ \fi}
+
+\def\dosinglesetupframed[#1][#2]%
+ {\getparameters[\??oi][#1]}
+
+\def\dodoublesetupframed[#1][#2]%
+ {\bgroup
+ \let\dodoubleempty\empty
+ \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}%
+ \getvalue{#1}%
+ \egroup
+ \letvalue{#1}\globalredefinedframed}
+
+%D \startbuffer
+%D \setupframed [framecolor=yellow] \framed{A}
+%D \defineframed[myframed] [framecolor=blue] \myframed{B}
+%D \setupframed [myframed] [framecolor=red] \myframed{C}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \presetlocalframed[myframed]
+%D \setuplocalframed[myframed][width=4cm,height=2cm]
+%D \localframed[myframed][framecolor=green]{oeps}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {ifinframed}
+%D
+%D The normal case first presets all parameters and next starts
+%D looking for the user supplied ones. The first step is
+%D omitted in the local case, because these are preset at
+%D declaration time and keep their values unless explictly
+%D changed. By presetting the variables everytime the normal
+%D command is called, we can use this command nested, without
+%D the unwanted side effect of inheritance. The boolean is
+%D used to speed up the color stack.
+
+\newif\ifinframed
+
+\def\localframed
+ {\bgroup
+ \dodoubleempty\startlocalframed}
+
+%D The next one is faster on multiple backgrounds per page. No
+%D dimensions can be set, only frames and backgrounds.
+
+\def\fastlocalframed[#1]#2[#3]#4% 3-4
+ {\bgroup
+ \inframedtrue
+ \edef\@@framed{#1}%
+ % more bytes
+ % \scratchdimen\framedparameter\c!frameoffset
+ % \setevalue{\@@framed\c!frameoffset}{\the\scratchdimen}%
+ % \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
+ % {\scratchdimen\framedparameter\c!backgroundoffset
+ % \setevalue{\@@framed\c!backgroundoffset}{\the\scratchdimen}}%
+ % less bytes
+ \@EA\freezedimenmacro\csname\@@framed\c!frameoffset\endcsname
+ \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
+ {\@EA\freezedimenmacro\csname\@@framed\c!backgroundoffset\endcsname}%
+ % so far
+ \setbox\framebox\hbox{#4}%
+ \getparameters[\@@framed][#3]% no \expanded !
+ % no, better in calling macro
+ %
+ % \edef\doframedsetups{\framedparameter\c!setups}%
+ % \ifx\doframedsetups\empty\else
+ % \edef\doframedsetups{\noexpand\setups[\doframedsetups]}%
+ % \fi
+ \removeframedboxdepth
+ \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}%
+ \ifx\framedforegroundcolor\empty\else\docolorframebox\fi
+ \edef\overlaylinecolor{\framedparameter\c!framecolor}%
+ \edef\overlaylinewidth{\the\ruledlinewidth}%
+ \edef\@@localframing {\framedparameter\c!frame}%
+ \ifx\@@localframing\v!overlay \else \ifx\@@localframing\v!none \else
+ \edef\framedrulethickness{\framedparameter\c!rulethickness}%
+ \ifx\framedrulethickness\empty\else
+ \ruledlinewidth\framedrulethickness\relax
+ \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi
+ \fi
+ \dooutlinebox % real or invisible frame
+ \fi \fi
+ \edef\framedbackground{\framedparameter\c!background}%
+ \ifx\framedbackground\empty\else\dobackedbox\fi
+ \restoreframedboxdepth
+ \box\framebox
+ \egroup}
+
+%D Before we go into details, we present (and implement) the
+%D main framing routine. I saw no real reason for splitting the
+%D next two macros into smaller pieces. The content will be
+%D collected in a horizontal or vertical box with fixed or free
+%D dimensions and specific settings concerning aligment and
+%D offsets.
+%D
+%D In the first few lines, we pre||expand the frame and
+%D background offsets. We do so, because the can be defined in
+%D terms of the main offset. However, see for instance page
+%D backgrounds, when \type {#2} sets the offset to \type
+%D {overlay}, both offsets become invalid.
+%D
+%D Because it is used so often the he next macro is (and
+%D looks) rather optimized.
+
+\let\postprocessframebox\relax
+
+\let\@@framed\s!unknown
+
+\def\framedparameter#1%
+ {\csname\@@framed#1\endcsname}
+
+\newdimen\!!framedwidth
+\newdimen\!!framedheight
+
+\def\startlocalframed[#1][#2]%
+ {\bgroup
+ \inframedtrue
+ \edef\@@framed{#1}%
+ % this piece of pre expansion is needed (sometimes used in frameoffset)
+ % \doifvaluesomething{\@@framed\c!rulethickness} % obsolete
+ % {\ruledlinewidth\getvalue{\@@framed\c!rulethickness}}% obsolete
+ % this piece of pre expansion is needed (sometimes used circular)
+ \setevalue{\@@framed\c!frameoffset}{\the\dimexpr\framedparameter\c!frameoffset\relax}%
+ \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
+ {\setevalue{\@@framed\c!backgroundoffset}{\the\dimexpr\framedparameter\c!backgroundoffset\relax}}%
+ % to prevent deadlock in case of self refering
+ \ifsecondargument % faster
+ \getparameters[\@@framed][#2]% here !
+ \fi
+ % new, experimental dirty hook
+ \framedparameter\c!extras
+ % to get the right spacing
+ \doifvaluesomething{\@@framed\c!foregroundstyle}
+ {\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}%
+ % beware, both the frame and background offset can be overruled
+ %
+ \edef\doframedsetups{\framedparameter\c!setups}%
+ \ifx\doframedsetups\empty\else
+ \edef\doframedsetups{\noexpand\setups[\doframedsetups]}%
+ \fi
+ % the next macros are visible
+ \edef\localoffset{\framedparameter\c!offset}%
+ \edef\localwidth {\framedparameter\c!width}%
+ \edef\localheight{\framedparameter\c!height}%
+ \edef\localformat{\framedparameter\c!align}%
+ \edef\localstrut {\framedparameter\c!strut}%
+ % these are not
+ \edef\@@localautostrut {\framedparameter\c!autostrut}%
+ \edef\@@localframing {\framedparameter\c!frame}%
+ \edef\@@locallocation {\framedparameter\c!location}%
+ \edef\@@localorientation{\framedparameter\c!orientation}%
+ %
+ \edef\@@localautowidth {\framedparameter\c!autowidth}%
+ %
+ \ifx\@@localframing\v!overlay % no frame, no offset, no framewidth
+ \boxhasframefalse
+ \let\localoffset\v!overlay
+ \else\ifx\@@localframing\v!none % no frame, no framewidth
+ \boxhasframefalse
+ \else
+ \boxhasframetrue
+ \fi\fi
+ \ifboxhasframe
+ \edef\framedrulethickness{\framedparameter\c!rulethickness}%
+ \ifx\framedrulethickness\empty\else
+ \ruledlinewidth\framedrulethickness\relax
+ \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi
+ \fi
+ \else
+ \ruledlinewidth\zeropoint
+ \fi
+ \ifx\localformat\empty
+ \boxhasformatfalse
+ \else
+ \boxhasformattrue
+ \dosetraggedcommand\localformat
+ \edef\dobeforeframedbox{\raggedtopcommand\framedparameter\c!top}%
+ \edef\doafterframedbox {\framedparameter\c!bottom\raggedbottomcommand}%
+ \fi
+ \ifx\localoffset\v!none
+ \boxhasoffsetfalse
+ \boxhasstrutfalse
+ \boxisoverlaidfalse
+ \@@localoffset\ruledlinewidth
+ \else\ifx\localoffset\v!overlay
+ % \ifx\@@localframing\v!no \boxhasframefalse \fi % test first
+ \boxhasoffsetfalse
+ \boxhasstrutfalse
+ \boxisoverlaidtrue
+ \@@localoffset\zeropoint
+ \else
+ \boxhasoffsettrue
+ \boxhasstruttrue
+ \boxisoverlaidfalse
+ \ifx\localoffset\v!default % new per 2-6-2000
+ \let\localoffset\defaultframeoffset
+ \letvalue{\@@framed\c!offset}\defaultframeoffset
+ \else
+ \let\defaultframeoffset\localoffset
+ \fi
+ \@@localoffset\dimexpr\localoffset+\ruledlinewidth\relax
+ \fi\fi
+ \!!framedheight\zeropoint
+ \!!framedwidth \zeropoint
+ \ifx\localwidth\v!fit
+ \ifboxhasformat
+ \boxhaswidthtrue
+ \!!framedwidth\hsize
+ \else
+ \boxhaswidthfalse
+ \fi
+ \else\ifx\localwidth\v!fixed % equals \v!fit but no shapebox
+ \ifboxhasformat
+ \boxhaswidthtrue
+ \!!framedwidth\hsize
+ \else
+ \boxhaswidthfalse
+ \fi
+ \else\ifx\localwidth\v!broad
+ \boxhaswidthtrue
+ \!!framedwidth\hsize
+ \else\ifx\localwidth\v!local
+ \boxhaswidthtrue
+ \setlocalhsize
+ \!!framedwidth\localhsize
+ \else
+ \boxhaswidthtrue
+ \!!framedwidth\localwidth
+ \fi\fi\fi\fi
+ \ifx\localheight\v!fit
+ \boxhasheightfalse % no longer: \boxhasstrutfalse
+ \else\ifx\localheight\v!broad
+ \boxhasheightfalse
+ \else
+ \boxhasheighttrue
+ \!!framedheight\localheight
+ \fi\fi
+ \ifboxhasheight
+ % obey user set height, also downward compatible
+ \else
+ \doifvaluesomething{\@@framed\c!lines}
+ {\ifcase\framedparameter\c!lines\else
+ \!!framedheight\framedparameter\c!lines\lineheight
+ \edef\localheight{\the\!!framedheight}%
+ \boxhasheighttrue
+ \fi}%
+ \fi
+ % this is now an option: width=local
+ %
+ % \ifdim\!!framedwidth=\hsize
+ % \parindent\zeropoint
+ % \setlocalhsize
+ % \!!framedwidth\localhsize
+ % \fi
+ % i.e. disable (colsetbackgroundproblemintechniek)
+ \advance\!!framedwidth -2\@@localoffset
+ \advance\!!framedheight -2\@@localoffset
+ \ifx\localstrut\v!no
+ \boxhasstrutfalse
+ \else\ifx\localstrut\v!global
+ \setstrut
+ \else\ifx\localstrut\v!local
+ \setfontstrut
+ \else
+ \setstrut
+ \fi\fi\fi
+ \ifboxhasstrut
+ \let\localbegstrut\begstrut
+ \let\localendstrut\endstrut
+ \let\localstrut \strut
+ \else
+ \let\localbegstrut\pseudobegstrut % was: \relax
+ \let\localendstrut\pseudoendstrut % was: \relax
+ \let\localstrut \pseudostrut % was: \relax
+ %\ifboxhasheight\ifdim\!!framedheight<\strutht % saveguard
+ % \let\localbegstrut\relax % but not that
+ % \let\localstrut \relax % save after all
+ %\fi\fi
+ \fi
+ \ifx\@@localautostrut\v!yes
+ \let\delayedbegstrut\relax
+ \let\delayedendstrut\relax
+ \let\delayedstrut \relax
+ \else
+ \let\delayedbegstrut\localbegstrut
+ \let\delayedendstrut\localendstrut
+ \let\delayedstrut \localstrut
+ \let\localbegstrut \relax
+ \let\localendstrut \relax
+ \let\localstrut \relax
+ \fi
+ \ifboxhasheight
+ \let\\\vboxednewline
+ \ifboxhaswidth
+ \let\hairline\vboxedhairline
+ \ifboxhasformat
+ \let\next\doformatboxSomeFormat
+ \else
+ \let\next\doformatboxNoFormat
+ \fi
+ \else
+ \let\hairline\hboxedhairline
+ \ifboxhasformat
+ \let\next\doformatboxHeight
+ \else
+ \let\next\doformatboxVSize
+ \fi
+ \fi
+ \else
+ \ifboxhaswidth
+ \ifboxhasformat
+ \let\hairline\vboxedhairline
+ \let\\\vboxednewline
+ \let\next\doformatboxWidth
+ \else
+ \let\hairline\hboxedhairline
+ \let\\\hboxednewline
+ \let\next\doformatboxHSize
+ \fi
+ \else
+ \let\hairline\hboxedhairline
+ \let\\\hboxednewline
+ \let\next\doformatboxNoSize
+ \fi
+ \fi
+ \edef\framedwidth % a new feature, visible for user
+ {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}%
+ \edef\framedheight% a new feature, visible for user
+ {\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}%
+ % we need to register the (outer) color
+ \startregistercolor[\framedparameter\c!foregroundcolor]%
+ % first alternative
+ %\def\dowithframedbox%
+ % {\let\postprocessframebox\relax %new
+ % \aftergroup\stoplocalframed}%
+ % \afterassignment\dowithframedbox
+ % \setbox\framebox=\next}
+ % second alternative
+ %\dowithnextbox
+ % {\setbox\framebox\flushnextbox
+ % \let\postprocessframebox\relax %new
+ % \stoplocalframed}
+ % \next}
+ \@@startframedorientation
+ \afterassignment\dodowithframebox
+ \setbox\framebox\next}
+
+\def\dowithframebox
+ {% moved : \let\postprocessframebox\relax
+ \stoplocalframed}
+
+\def\dodowithframebox
+ {\aftergroup\dowithframebox}
+
+\let\doafterframedbox \relax
+\let\dobeforeframedbox\relax
+
+%D Carefull analysis of this macro will learn us that not all
+%D branches in the last conditionals can be encountered, that
+%D is, some assignments to \type{\next} will never occur.
+%D Nevertheless we implement the whole scheme, if not for
+%D future extensions.
+
+%D \macros
+%D {ifreshapeframebox}
+%D
+%D The last few lines tell what to do after the content of the
+%D box is collected and passed to the next macro. In the case
+%D of a fixed width and centered alignment, the content is
+%D evaluated and used to determine the most natural width. The
+%D rest of the code deals with backgrounds and frames.
+
+\newif\ifreshapeframebox \reshapeframeboxtrue
+
+%D Beware: setting \type {top} and \type {bottom} to nothing, may
+%D result in a frame that is larger that the given height! try:
+%D
+%D \starttyping
+%D \framed
+%D [height=3cm,top=,bottom=,offset=overlay]
+%D {\strut test \shapefill \strut test}
+%D \stoptyping
+%D
+%D This is intended behaviour and not a bug! One can always set
+%D
+%D \starttyping
+%D ...,bottom=\kern0pt,...
+%D \stoptyping
+
+\def\stoplocalframed
+ {\dontshowcomposition
+ \@@stopframedorientation % hm, wrong place ! should rotate the result (after reshape)
+ \stopregistercolor
+ \handleframedlocator\c!before\@@locallocation
+ \ifboxhasformat
+ \ifx\@@localautowidth\v!force
+ \ifreshapeframebox\doreshapeframedbox\fi
+ \boxhaswidthfalse
+ \else
+ \ifx\localwidth\v!fit
+ \ifx\@@localautowidth\v!yes
+ \ifreshapeframebox\doreshapeframedbox\fi
+ \fi
+ \boxhaswidthfalse
+ \else\ifx\localwidth\v!fixed
+ \boxhaswidthfalse
+ \else
+ \resetshapeframebox
+ \fi\fi
+ \fi
+ \else
+ \resetshapeframebox
+ \fi
+ \ifboxhaswidth
+ \wd\framebox\!!framedwidth
+ \fi
+ \ifboxhasheight
+ \ht\framebox\!!framedheight
+ \fi
+ \doifvalue{\@@framed\c!empty}\v!yes
+ {\setbox\scratchbox\null
+ \wd\scratchbox\wd\framebox
+ \ht\scratchbox\ht\framebox
+ \dp\scratchbox\dp\framebox
+ \setbox\framebox\box\scratchbox}%
+ \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}%
+ \ifx\framedforegroundcolor\empty\else\docolorframebox\fi
+ \ifboxhasoffset
+ \dooffsetframebox
+ \fi
+ \ifboxisoverlaid \else
+ \dolocateframebox
+ \fi
+ \ifx\postprocessframebox\relax \else
+ \let\next\postprocessframebox
+ \let\postprocessframebox\relax % prevent nesting
+ \next\framebox
+ \fi
+ \edef\overlaylinecolor{\framedparameter\c!framecolor}%
+ \edef\overlaylinewidth{\the\ruledlinewidth}% \@@...
+ \ifboxhasframe % real or invisible frame
+ \dooutlinebox
+ \fi
+ \edef\framedbackground{\framedparameter\c!background}%
+ \ifx\framedbackground\empty\else\dobackedbox\fi
+ \handleframedlocator\c!after\@@locallocation
+ \box\framebox
+ \egroup
+ \egroup}
+
+\def\installframedlocator#1#2#3%
+ {\setvalue{\??ol:\c!location:\c!before:#1}{#2}%
+ \setvalue{\??ol:\c!location:\c!after :#1}{#3}}
+
+\def\handleframedlocator#1#2%
+ {\getvalue{\??ol:\c!location:#1:#2}}
+
+\def\doprelocframedbox#1%
+ {\scratchdimen\dimexpr#1+\ruledlinewidth\relax
+ \ifboxhasoffset
+ \advance\scratchdimen \framedparameter\c!offset
+ \fi
+ \scratchskip\dimexpr\ht\framebox-\scratchdimen\relax}
+
+% \ruledhbox
+% {A
+% \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging}
+% \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth}
+% \framed[width=2cm,align=middle,location=height] {location\\equals\\height}
+% B}
+% \vskip2cm
+% \ruledhbox
+% {A
+% \framed[width=2cm,align=middle,location=low] {location\\equals\\low}
+% \framed[width=2cm,align=middle,location=line] {location\\equals\\line}
+% \framed[width=2cm,align=middle,location=high] {location\\equals\\high}
+% B}
+% \vskip2cm
+% \ruledhbox
+% {A
+% \framed[width=2cm,align=middle,location=top] {location\\equals\\top}
+% \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom}
+% \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi}
+% \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle}
+% B}
+
+\installframedlocator \v!hanging % best with strut=no
+ {}
+ {\dp\framebox\ht\framebox
+ \ht\framebox\zeropoint}
+
+\installframedlocator \v!depth
+ {}
+ {\ht\framebox\dimexpr\ht\framebox-\strutdp\relax
+ \dp\framebox\strutdp
+ \box\framebox}
+
+\installframedlocator \v!height
+ {}
+ {\dp\framebox\dimexpr\ht\framebox-\strutht\relax
+ \ht\framebox\strutht
+ \box\framebox}
+
+\installframedlocator \v!high
+ {}
+ {\doprelocframedbox\strutht
+ \setbox\framebox\hbox{\lower\scratchskip\box\framebox}%
+ \ht\framebox\strutht
+ \dp\framebox\strutdp
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!line
+ {}
+ {\setbox\framebox\hbox{\lower.5\ht\framebox\box\framebox}%
+ \ht\framebox.5\lineheight
+ \dp\framebox.5\lineheight
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!low
+ {}
+ {\doprelocframedbox\strutdp
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\strutht
+ \dp\framebox\strutdp
+ \box\framebox}
+
+\installframedlocator \v!top
+ {}
+ {\doprelocframedbox\strutht
+ \setbox\framebox\hbox{\lower\scratchskip\box\framebox}%
+ \ht\framebox\scratchdimen
+ \dp\framebox\scratchskip
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!middle
+ {}
+ {\scratchdimen.5\ht\framebox
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\scratchdimen
+ \dp\framebox\scratchdimen
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!lohi
+ {\handleframedlocator\c!before\v!middle}
+ {\handleframedlocator\c!after \v!middle}
+
+\installframedlocator \v!bottom
+ {}
+ {\doprelocframedbox\strutdp
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\scratchskip
+ \dp\framebox\scratchdimen
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!keep % retains height/depth
+ {\removeframedboxdepth}
+ {\restoreframedboxdepth}
+
+% also used in fastlocalframed
+
+\newdimen\originalframedwd
+\newdimen\originalframedht
+\newdimen\originalframeddp
+
+\def\removeframedboxdepth
+ {\originalframedwd\wd\framebox
+ \originalframedht\ht\framebox
+ \originalframeddp\dp\framebox
+ \ifzeropt\originalframeddp\else\setbox\framebox\hbox{\raise\originalframeddp\box\framebox}\fi
+ \wd\framebox\originalframedwd
+ \ht\framebox\dimexpr\originalframedht+\originalframeddp\relax
+ \dp\framebox\zeropoint}
+
+\def\restoreframedboxdepth
+ {\ifzeropt\originalframeddp\else\setbox\framebox\hbox{\lower\originalframeddp\box\framebox}\fi
+ \wd\framebox\originalframedwd
+ \ht\framebox\originalframedht
+ \dp\framebox\originalframeddp}
+
+% \let\@@startframedorientation\relax
+% \let\@@stopframedorientation \relax
+
+% \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax}
+
+\def\@@startframedorientation
+ {\let\@@stopframedorientation \relax
+ \ifx\@@localorientation\empty\else
+ \ifcase\@@localorientation\else
+ \scratchcounter\@@localorientation
+ \divide\scratchcounter\plustwo
+ \ifodd\scratchcounter
+ \swapmacros\framedwidth \framedheight
+ \swapmacros\localwidth \localheight
+ \swapdimens\!!framedheight\!!framedwidth
+ \def\@@stopframedorientation{\@@dostopframedorientation\plusone}%
+ \else
+ \def\@@stopframedorientation{\@@dostopframedorientation\zerocount}%
+ \fi
+ \fi
+ \fi}
+
+\def\@@dostopframedorientation#1%
+ {\ifcase#1\else
+ \swapmacros\framedwidth \framedheight
+ \swapmacros\localwidth \localheight
+ \swapdimens\!!framedheight\!!framedwidth
+ \fi
+ \setbox\framebox\hbox{\dorotatebox\@@localorientation\hbox{\box\framebox}}}
+
+%D The last conditional takes care of the special situation of
+%D in||line \inframed[height=3cm]{framed} boxes. Such boxes have
+%D to be \inframed{aligned} with the running text.
+
+\def\doinframed[#1]% we could omit #1] but readibility ...
+ {\framed[\c!location=\v!low,#1]}
+
+\unexpanded\def\inframed
+ {\dosingleempty\doinframed}
+
+%D When we set \type{empty} to \type{yes}, we get
+%D ourselves a frame and/or background, but no content, so
+%D actually we have a sort of phantom framed box.
+
+%D Because color marks and specials can interfere with
+%D spacing, we provide a way to specify a foregroundcolor.
+
+\def\docolorframebox
+ {\doifvaluesomething{\@@framed\c!foregroundcolor}
+ {\doifcolorelse{\framedparameter\c!foregroundcolor}
+ {\setbox\framebox\hbox
+ {\localcolortrue
+ \color[\framedparameter\c!foregroundcolor]{\box\framebox}}}
+ {}}}
+
+%D \macros
+%D {mframed, minframed}
+%D
+%D When Tobias asked how to frame mathematical elements in
+%D formulas, Taco's posted the next macro:
+%D
+%D \starttyping
+%D \def\mframed#1%
+%D {\relax
+%D \ifmmode
+%D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}%
+%D \else
+%D \framed{$#1$}%
+%D \fi}
+%D \stoptyping
+%D
+%D Because \type {\ifinner} does not (always) reports what
+%D one would expect, we move the test to the outer level. We
+%D also want to pass arguments,
+%D
+%D \starttyping
+%D \def\mframed%
+%D {\dosingleempty\domframed}
+%D
+%D \def\domframed[#1]#2% % tzt \dowithnextmathbox ?
+%D {\relax
+%D \ifmmode
+%D \ifinner
+%D \inframed[#1]{$#2$}%
+%D \else
+%D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}%
+%D \fi
+%D \else
+%D \inframed[#1]{$#2$}%
+%D \fi}
+%D \stoptyping
+%D
+%D Still better is the next alternative, if only because it
+%D takes care of setting the super- and subscripts styles
+
+\ifx\restoremathstyle\undefined \let\restoremathstyle\relax \fi
+
+\def\domframed[#1][#2]#3%
+ {\begingroup
+ \ifmmode
+ \ifinner
+ \let\mframedstyle\restoremathstyle
+ \else
+ \let\mframedstyle\displaystyle
+ \fi
+ \else
+ \let\mframedstyle\restoremathstyle
+ \fi
+ #1\ifdone
+ \def\normalstrut{$\mframedstyle\vphantom($}%
+ \framed
+ [\c!frameoffset=\@@oioffset,\c!offset=\v!overlay,#2]
+ {$\mframedstyle#3$}%
+ \else
+ \inframed
+ [#2]
+ {$\mframedstyle#3$}%
+ \fi
+ \endgroup}
+
+\def\mframed
+ {\dodoubleempty\domframed[\donetrue]}
+
+\def\inmframed
+ {\dodoubleempty\domframed[\donefalse]}
+
+%D So instead of the rather versatile \type {\framed}, we ue
+%D the \type {\mframed}.
+%D
+%D \startbuffer
+%D \startformula
+%D x \times \mframed{y} \times y^{z_z}
+%D x \times \inmframed{y} \times y^{z_z}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D However, we got into troubles when we want to nest sub- and
+%D superscripts, like in
+%D
+%D \startbuffer
+%D \startformula
+%D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D Therefore, we can best use \type {\super} and \type {\suber}
+%D instead of \type {^} and \type {_}. Both commands take care
+%D of proper font switching.
+%D
+%D \startbuffer
+%D \startformula
+%D x \times \mframed{y} \times y\super{\mframed{z}\suber{\mframed{z}}}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D As usual, one can specify in what way the text should be
+%D framed. One should be aware of the fact that, inorder to
+%D preserve the proper spacing, the \type {offset} is set to
+%D \type {overlay} and \type {frameoffset} is used used
+%D instead.
+%D
+%D \startbuffer
+%D \startformula
+%D x \times y\super{\mframed[framecolor=red]{z}\suber{z}}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D For inline use, we also provide the \type {\inmframed}
+%D alternative: we want $x \times \inmframed{y}$ in inline
+%D math, right?
+
+%D This previous framing macros needs a lot of alternatives for
+%D putting rules around boxes, inserting offsets and aligning
+%D text. Each step is handled by separate macros.
+
+\def\dowidenframebox#1%
+ {\setbox\framebox\vbox
+ {\kern#1\hbox{\kern#1\box\framebox\kern#1}\kern#1}}
+
+\def\dooffsetframebox{\dowidenframebox\localoffset}
+\def\dolocateframebox{\dowidenframebox\ruledlinewidth}
+
+%D Let's hope that the next few examples show us enough of
+%D what needs to be done by the auxiliary macros.
+%D
+%D \startbuffer
+%D \framed[height=1cm,offset=.5cm] {rule based learning}
+%D \framed[height=1cm,offset=0cm] {rule based learning}
+%D \framed[height=1cm,offset=none] {rule based learning}
+%D \framed[height=1cm,offset=overlay]{rule based learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D \startbuffer
+%D \framed[offset=.5cm] {rule based learning}
+%D \framed[offset=0cm] {rule based learning}
+%D \framed[offset=none] {rule based learning}
+%D \framed[offset=overlay]{rule based learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D \startbuffer
+%D \framed[strut=nee,offset=.5cm] {rule based learning}
+%D \framed[strut=nee,offset=0cm] {rule based learning}
+%D \framed[strut=nee,offset=none] {rule based learning}
+%D \framed[strut=nee,offset=overlay]{rule based learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D \startbuffer
+%D \framed[width=3cm,align=left] {rule\\based\\learning}
+%D \framed[width=3cm,align=middle] {rule\\based\\learning}
+%D \framed[width=3cm,align=right] {rule\\based\\learning}
+%D \framed[width=fit,align=middle] {rule\\based\\learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\dontcomplain\getbuffer}
+%D \stoplinecorrection
+%D
+%D So now we're ready for the complicated stuff. We distinguish
+%D between borders with straight lines and those with round
+%D corners. When using the first alternative it is possible to
+%D turn off one or more lines. More fancy shapes are also
+%D possible by specifying dedicated backgrounds. Turning lines
+%D on and off is implemented as efficient as possible and as a
+%D result is interface language dependant. This next
+%D implementation evolved from simpler ones. It puts for
+%D instance the rules on top of the content and provides
+%D additional offset capabilities. The lot of calls to other
+%D macros makes this mechanism not that easy to comprehend.
+
+%D Getting the backgrounds right takes less code. Again we
+%D have to take care of additional offsets.
+
+\def\dobackedbox
+ {\doifelsevalue{\@@framed\c!backgroundoffset}\v!frame % new
+ {\dobackgroundbox\c!frameoffset}
+ {\dobackgroundbox\c!backgroundoffset}}
+
+%D We handle left, right or middle alignment as well as fixed
+%D or free widths and heights. Each combination gets its own
+%D macro.
+
+%D The following code handles one-liners: \type{align={line,flushright}}.
+%D Beware, since we entered a group and either or not grab the next
+%D bgroup token, we need to finish the group in the oneliner mode.
+
+\ifx\raggedoneliner\undefined \chardef\raggedoneliner\zerocount \fi
+
+\def\doformatonelinerbox % beware: assumes explicit preceding bgroup
+ {\ifcase\raggedoneliner
+ \expandafter\nodoformatonelinerbox
+ \else
+ \expandafter\dodoformatonelinerbox
+ \fi}
+
+\def\dodoformatonelinerbox
+ {\dowithnextboxcontent
+ {\ignorespaces}
+ {\hbox to \hsize
+ {\ifcase\raggedstatus\or\hss\or\hss\fi
+ \unhbox\nextbox \removeunwantedspaces
+ \ifcase\raggedstatus\or \or\hss\or\hss\fi}%
+ \egroup}
+ \hbox}
+
+\def\nodoformatonelinerbox % grabs {
+ {\let\next=}
+
+%D The handlers:
+
+\def\doformatboxSomeFormat
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \hsize\!!framedwidth
+ \vsize\!!framedheight
+ \doframedsetups
+ \raggedcommand
+ \dobeforeframedbox
+ \bgroup
+ \localbegstrut
+ \aftergroup\localendstrut
+ \aftergroup\doafterframedbox
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxNoFormat
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \hsize\!!framedwidth
+ \vsize\!!framedheight
+ \doframedsetups
+ \raggedcenter
+ \vss
+ \bgroup
+ \localbegstrut
+ \aftergroup\localendstrut
+ \aftergroup\vss
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxHeight
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \doframedsetups
+ \raggedcommand
+ \vss
+ \bgroup
+ \aftergroup\localendstrut
+ \aftergroup\vss
+ \aftergroup\egroup
+ \localbegstrut
+ \doformatonelinerbox}
+
+\def\doformatboxWidth
+ {\vbox
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \hsize\!!framedwidth
+ \doframedsetups
+ \raggedcommand
+ \dobeforeframedbox
+ \bgroup
+ \localbegstrut
+ \aftergroup\localendstrut
+ \aftergroup\doafterframedbox
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxVSize
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \vsize\!!framedheight
+ \doframedsetups
+ \vss
+ \bgroup
+ \aftergroup\vss
+ \aftergroup\egroup
+ \hbox
+ \bgroup
+ \aftergroup\egroup
+ \localstrut
+ \doformatonelinerbox}
+
+\def\doformatboxHSize
+ {\hbox to \!!framedwidth
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \doframedsetups
+ \hss
+ \localstrut
+ \bgroup
+ \aftergroup\hss
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxNoSize
+ {\hbox
+ \bgroup
+ \let\postprocessframebox\relax
+ \doframedsetups
+ \localstrut
+ \doformatonelinerbox}
+
+\let\doframedsetups\relax
+
+%D On the next page we show some examples of how these macros
+%D come into action. The examples show us how
+%D \type {fit}, \type {broad} dimensions influence the
+%D formatting. Watch the visualized struts. \footnote {Here we
+%D used \type {\showstruts}.}
+%D
+%D \startpostponing
+%D \bgroup
+%D \showstruts
+%D \dontcomplain
+%D \startlinecorrection
+%D \halign{#\enskip&#\enskip&#\enskip&#\enskip&#\enskip&#\cr
+%D \framed[width=.2\hsize, height=.2\hsize, align=] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=yes] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=yes] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=yes] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=yes] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=yes] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=right] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=right] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=right] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=right] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=right] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=right] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=left] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=left] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=left] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=left] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=left] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=left] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=middle] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=middle] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=middle] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=middle] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=middle] {a\par b\par c}\cr}
+%D \stoplinecorrection
+%D \blank[2*big]
+%D \egroup
+%D \stoppostponing
+
+%D \macros
+%D {framednoflines, framedlastlength}
+%D
+%D It is possible to let the frame macro calculate the width
+%D of a centered box automatically (\type {fit}). When
+%D doing so, we need to reshape the box:
+
% The next implementation is frozen! It preserves the depth,
% otherwise we get problems with framed display math and auto
% width.
+\newcount\framednoflines
+\newdimen\framedlastlength
+
+\def\resetshapeframebox
+ {\framednoflines \zerocount
+ \framedlastlength\zeropoint}
+
+\chardef\reshapeframeboxmethod\plusone % 0=no flush, 1=old method 2=no depth messing
+
\def\shapeboxstrut % put this in front if needed !
{\vrule\!!width\zeropoint\!!height\ht\shapebox\!!depth\dp\shapebox}
@@ -72,4 +1924,1714 @@
\fi
\fi}
+%D The two variables \type {\framednoflines} and \type
+%D {\framedlastlength} can be used in a second pass to
+%D optimized framed material.
+
+% torture test / strange case (much depth) / method 2 needed
+%
+% \startTEXpage[frame=on]
+% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
+% test outside formula
+% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
+% \blank[big]
+% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
+% test outside formula
+% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
+% \stopTEXpage
+
+%D The examples on the next page show how one can give the
+%D frame as well as the background an additional offset and
+%D even a bit more depth. The blue outline is the frame, the
+%D red box is the background and the small black outline is the
+%D visualization of the resulting box, that is, we applied
+%D \type{\ruledhbox} to the result.
+
+%D \startpostponing
+%D \bgroup
+%D \unprotect
+%D \dontcomplain
+%D
+%D \startbuffer
+%D \vbox to \vsize
+%D \bgroup
+%D \startalignment[middle]
+%D \vss
+%D \dontleavehmode\vbox to .8\vsize
+%D \bgroup
+%D \hsize=300pt
+%D \setupframed
+%D [background=color,
+%D backgroundcolorachtergrondkleur=darkred,
+%D width=300pt,
+%D height=60pt,
+%D framecolorkaderkleur=DemoBlue,
+%D rulethickness=2pt]
+%D \def\status%
+%D {backgroundoffset=\framedparameter\c!backgroundoffset\\
+%D frameoffset=\framedparameter\c!frameoffset\\
+%D depth=\framedparameter\c!depth}
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}}
+%D \egroup
+%D \vss
+%D \stopalignment
+%D \egroup
+%D \stopbuffer
+%D
+%D \getbuffer \page
+%D
+%D {\setupframed[depth=4pt]\getbuffer} \page
+%D
+%D \protect
+%D \egroup
+%D \stoppostponing
+
+%D When typesetting the framed box inline, we have to keep the
+%D baseline intact outside as well as inside the framed box.
+
+\def\doinlineframedbox
+ {\scratchdimen\dimexpr\strutdp+\ruledlinewidth\relax
+ \ifboxhasoffset
+ \advance\scratchdimen \framedparameter\c!offset
+ \fi
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\strutht
+ \dp\framebox\strutdp
+ \box\framebox}
+
+%D We can also lower the box over the natural depth of the
+%D line.
+
+\def\doloweredframedbox
+ {\ht\framebox\dimexpr\ht\framebox+\dp\framebox-\strutdp\relax
+ \dp\framebox\strutdp
+ \box\framebox}
+
+%D Hanging the content is mainly meant for cases like the
+%D following:
+%D
+%D \starttyping
+%D \framed[strut=no]
+%D {\framed[height=2cm,location=hanging]{test}%
+%D \framed[height=1cm,location=hanging]{test}}
+%D \stoptyping
+
+\def\dohangingframedbox % best with strut=no
+ {\scratchdimen\dimexpr\ht\framebox+\dp\framebox\relax
+ \ht\framebox\zeropoint
+ \dp\framebox\scratchdimen}
+
+%D We can draw lines from left to right and top to bottom by
+%D using the normal \type{\hairline} command. Both directions
+%D need a different treatment.
+%D
+%D \startbuffer
+%D \framed[width=4cm] {alfa\hairline beta\hairline gamma}
+%D \framed[height=2cm] {alfa\hairline beta\hairline gamma}
+%D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D These macros try to adapt their behaviour as good as
+%D possible to the circumstances and act as natural as
+%D possible.
+
+\def\vboxedhairline
+ {\bgroup
+ \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi
+ \dimen4=\dimexpr\dimen2+\ruledlinewidth\relax
+ \setbox0\vbox
+ {\advance\hsize 2\dimen4
+ \vskip\dimen2
+ \hrule
+ \!!height\ruledlinewidth
+ \!!depth\zeropoint
+ \!!width\hsize
+ \vskip\dimen2}%
+ %\endgraf\nointerlineskip\endgraf
+ %\moveleft\dimen4\box0
+ %\endgraf\nointerlineskip\localbegstrut
+ \endgraf\obeydepth\nointerlineskip
+ \moveleft\dimen4\box0
+ \endgraf\nointerlineskip\localbegstrut % beware, we might kill it in a style using \vskip\lineheight
+ \egroup} % so this must not be changed
+
+\def\hboxedhairline % use framed dimen
+ {\bgroup
+ \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi
+ \ifboxhasheight
+ \dimen4\dimexpr\localheight/2+\strutdp-2\ruledlinewidth\relax
+ \dimen6\dimexpr\localheight/2-\strutdp+2\ruledlinewidth\relax
+ \else
+ \dimen4\dimexpr\strutht+\dimen2\relax
+ \dimen6\dimexpr\strutdp+\dimen2\relax
+ \fi
+ \unskip
+ \setbox\scratchbox\hbox
+ {\hskip\dimen2
+ \vrule\!!height\dimen4\!!depth\dimen6\!!width\ruledlinewidth
+ \hskip\dimen2}%
+ \ht\scratchbox\strutht
+ \dp\scratchbox\strutdp
+ \box\scratchbox
+ \ignorespaces
+ \egroup}
+
+%D The argument of the frame command accepts \type{\\} as a
+%D sort of newline signal. In horizontal boxes it expands to a
+%D space.
+
+\def\vboxednewline
+ {\endgraf\ignorespaces}
+
+\def\hboxednewline
+ {\unskip\normalspace\ignorespaces}
+
+%D We can set each rule on or off. The default setting is
+%D inherited from \type{frame}. An earlier implementation
+%D use a bit different approach, but the new one seems more
+%D natural:
+%D
+%D \bgroup
+%D \setuptyping[margin=0pt]
+%D \startlinecorrection
+%D \startbuffer
+%D \framed[offset=overlay,frame=on]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=off]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D \stoplinecorrection
+%D \egroup
+
+%D \macros
+%D {setupblackrules}
+%D
+%D The graphic capabilities of \TEX\ do not go beyond simple
+%D filled rules, except of course when using specials. Let's
+%D start with a warning: using this commands is far more slower
+%D than using the \TEX\ primitives \type{\hrule} and
+%D \type{\vrule}, but they save us some tokens. The
+%D characteristics of these rule drawing command can be set by:
+%D
+%D \showsetup{setupblackrules}
+
+\def\setupblackrules
+ {\dodoubleargument\getparameters[\??bj]}
+
+%D \macros
+%D {blackrule}
+%D
+%D The simple command draws only one rule. Its optional
+%D argument can be used to specify the dimensions. By setting
+%D the width, height or depth to \type {max}, one gets the
+%D natural dimensions.
+%D
+%D \showsetup{blackrule}
+
+\def\doblackrule[#1]%
+ {\hbox\bgroup
+ \getparameters[\??bj][#1]%
+ \setstrut
+ \doif\@@bjwidth \v!max{\def\@@bjwidth {1em}}%
+ \doif\@@bjheight\v!max{\def\@@bjheight{\strutht}}%
+ \doif\@@bjdepth \v!max{\def\@@bjdepth {\strutdp}}%
+ \localstartcolor[\@@bjcolor]%
+ \vrule
+ \!!width \@@bjwidth
+ \!!height\@@bjheight
+ \!!depth \@@bjdepth
+ \localstopcolor
+ \egroup}
+
+\unexpanded\def\blackrule
+ {\dosingleempty\doblackrule}
+
+%D \macros
+%D {blackrules}
+%D
+%D One can call for a sequence of black rules, if needed
+%D equally spaced over the given width.
+%D
+%D \showsetup{blackrules}
+%D
+%D The two alternative calls are therefore:
+%D
+%D \startbuffer
+%D Tell me, is this according to the \blackrules[n=6]?
+%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear.
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or:
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D We could of course have implemented this macro using
+%D \type{\leaders}, but this would probably have taken more
+%D tokens.
+
+\def\doblackrules[#1]%
+ {\hbox\bgroup
+ \getparameters[\??bj][#1]%
+ \!!widtha\@@bjwidth
+ \!!widthb\@@bjdistance
+ \doif\@@bjalternative\c!b
+ {\scratchcounter\@@bjn
+ \ifnum\scratchcounter=\plusone
+ \!!widthb\zeropoint
+ \else
+ \advance\scratchcounter \minusone
+ \advance\!!widtha -\scratchcounter\!!widthb
+ \divide \!!widtha \@@bjn
+ \fi}%
+ \localstartcolor[\@@bjcolor]%
+ \dorecurse\@@bjn
+ {\vrule
+ \!!width \!!widtha
+ \!!height\@@bjheight
+ \!!depth \@@bjdepth
+ \hskip\!!widthb}%
+ \unskip
+ \localstopcolor
+ \egroup}
+
+\unexpanded\def\blackrules
+ {\dosingleempty\doblackrules}
+
+%D The next commands can be used to draw margin rules. We
+%D support two methods: \marginrule{one for in||line use} and
+%D one that acts on a paragraph. Drawing a margin rule is
+%D rather straightforward because we can use the commands that
+%D put text in the margin.
+
+\def\dodrawmarginrule
+ {\setbox\scratchbox\hbox
+ {\vrule\!!depth\strutdepth\!!height\strutheight\!!width\@@karulethickness}%
+ \smashbox\scratchbox % no \vsmash !!!
+ \box\scratchbox}
+
+\def\drawmarginrule
+ {\strut\inleft{\dodrawmarginrule}}
+
+%D \macros
+%D {marginrule}
+%D
+%D The first method gobbles words and simply puts a bar in the
+%D margin. This method is not entirely robust.
+%D
+%D \showsetup{marginrule}
+
+\definecomplexorsimple\marginrule
+
+\def\simplemarginrule
+ {\let\processword\drawmarginrule
+ \processwords}
+
+\def\complexmarginrule[#1]%
+ {\ifnum#1<\@@kalevel\relax \else
+ \def\@@kadefaultwidth{#1}%
+ \expandafter\simplemarginrule
+ \fi}
+
+%D We need an auxiliary variable
+
+\def\@@kadefaultwidth{1}
+
+%D \macros
+%D {setupmarginrules}
+%D
+%D This macro definitions show us that we can pass an optional
+%D level, which is matched against the previous set one. The
+%D level can be set up with
+%D
+%D \showsetup{setupmarginrules}
+
+\def\setupmarginrules
+ {\dodoubleargument\getparameters[\??ka]}
+
+%D \macros
+%D {startmarginrule}
+%D
+%D The second method collects text and reformats it afterwards,
+%D using the shapebox macros. We prevent local margin rules.
+%D
+%D \showsetup{startmarginrule}
+
+\definecomplexorsimple\startmarginrule
+
+\def\simplestartmarginrule
+ {\bgroup
+ \let\drawmarginrule\relax
+ \let\stopmarginrule\dostopmarginrule
+ \beginofshapebox}
+
+\def\complexstartmarginrule[#1]%
+ {\bgroup
+ \let\drawmarginrule\relax
+ \ifnum#1<\@@kalevel\relax
+ \let\stopmarginrule\egroup
+ \else
+ \def\@@kadefaultwidth{#1}%
+ \let\stopmarginrule\dostopmarginrule
+ \expandafter\beginofshapebox
+ \fi}
+
+\def\dostopmarginrule
+ {\endofshapebox
+ \reshapebox
+ {\hbox{\inleftmargin{\dodrawmarginrule}\box\shapebox}}%
+ \flushshapebox
+ \egroup}
+
+%D \startbuffer
+%D \setupmarginrules[level=5]
+%D
+%D \startmarginrule[1]
+%D First we set the level at~5. Next we typeset this first
+%D paragraph as a level~1 one. As expected no rule show up.
+%D \stopmarginrule
+%D
+%D \startmarginrule[5]
+%D The second paragraph is a level~5 one. As we can see here,
+%D the marginal rule gets a width according to its level.
+%D \stopmarginrule
+%D
+%D \startmarginrule[8]
+%D It will of course be no surprise that this third paragraph
+%D has a even thicker margin rule. This behavior can be
+%D overruled by specifying the width explictly.
+%D \stopmarginrule
+%D \stopbuffer
+%D
+%D In next example we show most features. Watch the rule
+%D thickness adapting itself to the level.
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D We just said:
+%D
+%D \typebuffer
+
+%D \macros
+%D {vl, hl}
+%D
+%D The command \type{\vl} draws a vertical rule \vl\ with strut
+%D dimensions, multiplied with the factor specified in the
+%D optional argument. The height and depth are clipped \vl[3]
+%D to the baselinedistance. Its horizontal counterpart
+%D \type{\hl} draws a horizontal rule \hl\ with a width of 1em,
+%D multiplied with the optional factor. The horizontal rule is
+%D drawn on top of the baseline.
+%D
+%D \showsetup{vl}
+%D \showsetup{hl}
+
+\def\complexvl[#1]%
+ {\bgroup
+ \!!dimena#1\strutht
+ \!!dimenb#1\strutdp
+ \setbox\scratchbox\hbox
+ {\vrule
+ \!!width \linewidth
+ \!!height\!!dimena
+ \!!depth \!!dimenb}%
+ \dp\scratchbox\strutdp
+ \ht\scratchbox\strutht
+ \box\scratchbox
+ \egroup}
+
+\def\complexhl[#1]%
+ {\hbox
+ {\vrule
+ \!!width #1\s!em
+ \!!height\linewidth
+ \!!depth \zeropoint}}
+
+\definecomplexorsimple\vl \def\simplevl{\complexvl[1]}
+\definecomplexorsimple\hl \def\simplehl{\complexhl[1]}
+
+%D \macros
+%D {hairline, thinrule, thinrules, setupthinrules}
+%D
+%D Drawing thin lines can of course easily be accomplished by
+%D the \TEX\ primitives \type{\hrule} and \type{\vrule}. The
+%D next few macros however free us from some specifications.
+%D
+%D \startbuffer
+%D some text
+%D
+%D \hairline
+%D
+%D some more text
+%D
+%D \thinrule
+%D
+%D more and more text
+%D
+%D hi \thinrule\ there
+%D
+%D and then the final text
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D becomes
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D So we've got
+%D
+%D \showsetup{hairline}
+%D \showsetup{thinrule}
+%D
+%D Both can be set up with:
+%D
+%D \showsetup{setupthinrules}
+%D
+%D We also have
+%D
+%D \showsetup{thinrules}
+%D
+%D which looks like: \thinrules[n=2]
+
+\def\thinrule
+ {\strut
+ \bgroup
+ \chardef\ruletype\plusone
+ \processaction
+ [\@@dlalternative]
+ [ \v!a=>\chardef\ruletype0,% no line
+ %\v!b=>\chardef\ruletype1,% height/depth
+ \v!c=>\chardef\ruletype2,% topheight/botdepth
+ % 11=>\chardef\ruletype1,% fallback for backgrounds
+ 0=>\chardef\ruletype0,% compatible with backgrounds
+ % 1=>\chardef\ruletype1,% compatible with backgrounds
+ 2=>\chardef\ruletype2]% compatible with backgrounds
+ \doifsomething\@@dlrulethickness
+ {\linewidth\@@dlrulethickness}%
+ \ifdim\linewidth=\zeropoint
+ \chardef\ruletype\zerocount
+ \else
+ \doifnot\@@dlframe\v!on{\chardef\ruletype\zerocount}%
+ \fi
+ \ifnum\ruletype=\plusone
+ \doif\@@dlheight\v!max{\let\@@dlheight\!!plusone}%
+ \doif\@@dldepth \v!max{\let\@@dldepth \!!plusone}%
+ \else
+ \let\@@dlheight\!!plusone
+ \let\@@dldepth\!!plusone
+ \fi
+ \freezedimensionwithunit\@@dlheight\strutht
+ \freezedimensionwithunit\@@dldepth\strutdp
+ \divide\linewidth \plustwo
+ \doifelse\@@dlbackground\v!color
+ {\startcolor[\@@dlbackgroundcolor]%
+ \ifnum\ruletype=\plustwo % prevent overshoot due to rounding
+ \leaders
+ \hrule
+ \!!height\dimexpr\@@dlheight-.5\linewidth\relax
+ \!!depth \dimexpr\@@dldepth -.5\linewidth\relax
+ \hfill
+ \else
+ \leaders
+ \hrule
+ \!!height\@@dlheight
+ \!!depth \@@dldepth
+ \hfill
+ \fi
+ \stopcolor
+ \ifcase\ruletype
+ % no rule
+ \or
+ \startcolor[\@@dlcolor]%
+ \hfillneg
+ \leaders\hrule\!!height\linewidth\!!depth\linewidth\hfill
+ \stopcolor
+ \or
+ \startcolor[\@@dlcolor]%
+ \hfillneg\leaders\hrule\!!height\dimexpr-\@@dldepth+\linewidth\relax\!!depth\@@dldepth\hfill
+ \hfillneg\leaders\hrule\!!height\@@dlheight\!!depth\dimexpr-\@@dlheight+\linewidth\relax\hfill
+ \stopcolor
+ \fi}
+ {\ifcase\ruletype \else
+ \startcolor[\@@dlcolor]%
+ \leaders\hrule\!!height\@@dlheight\!!depth\@@dldepth\hfill
+ \stopcolor
+ \fi}%
+ \strut
+ \carryoverpar\egroup}
+
+\def\hairline
+ {\endgraf
+ \thinrule
+ \endgraf}
+
+\def\dosetupthinrules[#1]%
+ {\getparameters[\??dl][#1]}
+
+\def\setupthinrules
+ {\dosingleargument\dosetupthinrules}
+
+\def\dothinrules[#1]%
+ {\bgroup
+ \dosetupthinrules[#1]%
+ \@@dlbefore
+ \assignvalue\@@dlinterlinespace\@@dlinterlinespace{1.0}{1.5}{2.0}%
+ \spacing\@@dlinterlinespace
+ \dorecurse\@@dln
+ {\ifnum\recurselevel=\@@dln \dothinrulesnobreak \else
+ \ifnum\recurselevel=2 \dothinrulesnobreak \fi\fi
+ \thinrule
+ \ifnum\recurselevel<\@@dln\relax
+ % test needed, else messed up whitespace
+ \ifx\@@dlinbetween\empty
+ \softbreak
+ \else
+ \endgraf
+ \nowhitespace
+ \@@dlinbetween
+ \fi
+ \fi}%
+ \doifelsenothing\@@dlafter
+ {\carryoverpar\egroup}
+ {\@@dlafter\egroup}}
+
+\def\thinrules
+ {\dosingleempty\dothinrules}
+
+%D A couple of examples are given below.
+%D
+%D \startbuffer
+%D \setupthinrules[n=3,inbetween=,color=gray]
+%D
+%D test test \thinrules\ test test \par
+%D test test \thinrules [color=green] test test \par
+%D test test \thinrules [height=max, depth=max] test test \par
+%D
+%D \setupthinrules[height=.9,depth=.9]
+%D
+%D test test \thinrules\ test test \par
+%D test test \thinrules [alternativevariant=b] test test \par
+%D test test \thinrules [alternativevariant=c] test test \par
+%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par
+%D \stopbuffer
+%D
+%D \typebuffer {\getbuffer}
+%D
+%D There are a couple of alternative ways to visualize rules
+%D using backgrounds. At first sight these may look strange,
+%D but they make sense in educational settings. The
+%D alternatives are more or less compatible with the more
+%D advanced \METAPOST\ based implementation.
+%D
+%D \startbuffer[a]
+%D \setupthinrules
+%D [n=2,
+%D backgroundcolor=gray ,
+%D rulethickness=1pt,
+%D colorkleur=donkerblauw,
+%D after=\blank,
+%D before=\blank]
+%D \stopbuffer
+%D
+%D \typebuffer[a]
+%D
+%D \startbuffer[b]
+%D \thinrules[alternativevariant=a]
+%D \thinrules[alternativevariant=b]
+%D \thinrules[alternativevariant=c]
+%D \stopbuffer
+%D
+%D \typebuffer[b] \getbuffer[a,b]
+%D
+%D \startbuffer[b]
+%D \thinrules[alternativevariant=a,background=color]
+%D \thinrules[alternativevariant=b,background=color]
+%D \thinrules[alternativevariant=c,background=color]
+%D \stopbuffer
+%D
+%D \typebuffer[b] \getbuffer[a,b]
+%D
+%D \startbuffer[b]
+%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color]
+%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color]
+%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color]
+%D \stopbuffer
+%D
+%D \typebuffer[b] \getbuffer[a,b]
+
+%D \macros
+%D {optimizethinrules}
+%D
+%D By saying \type {\thinrulestrue} or \type {-false}, we
+%D can influence the way dangling lines are handled.
+
+\newif\ifoptimizethinrules \optimizethinrulestrue
+
+\def\dothinrulesnobreak
+ {\ifoptimizethinrules\penalty500\fi}
+
+%D \macros
+%D {startframedtext, setupframedtexts, defineframedtext}
+%D
+%D The general framing command we discussed previously, is not
+%D entirely suited for what we call framed texts, as for
+%D instance used in intermezzo's. The next examples show what
+%D we have in mind.
+%D
+%D \startbuffer[framed-0]
+%D \setupframedtexts
+%D [frame=off,
+%D width=\hsize,
+%D background=screen]
+%D
+%D \startframedtext
+%D By default the framed text is centered \dots
+%D \stopframedtext
+%D
+%D \startframedtext[right]
+%D \dots\ but we can also align left, middle and right.
+%D \stopframedtext
+%D \stopbuffer
+%D
+%D \startbuffer[framed-1]
+%D \defineframedtext
+%D [Example]
+%D [width=6cm,
+%D height=5cm]
+%D
+%D \startExample
+%D \typebuffer[framed-1]
+%D \stopExample
+%D \stopbuffer
+%D
+%D \startbuffer[framed-2]
+%D \defineframedtext
+%D [Example]
+%D [width=6cm]
+%D
+%D \startExample
+%D \typebuffer[framed-2]
+%D \stopExample
+%D \stopbuffer
+%D
+%D \startbuffer[framed-3]
+%D \defineframedtext
+%D [Example]
+%D [height=5cm]
+%D
+%D \startExample
+%D \typebuffer[framed-3]
+%D \stopExample
+%D \stopbuffer
+%D
+%D \startbuffer[framed-4]
+%D \defineframedtext
+%D [Example]
+%D [width=fit,height=broad]
+%D
+%D \Example{a very exciting example}
+%D \stopbuffer
+%D
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup
+%D
+%D Here we can see that we have a predefined framed text class
+%D as well as the tools for defining our own. So we have:
+%D
+%D \showsetup{setupframedtexts}
+%D
+%D as well as the definition command:
+%D
+%D \showsetup{defineframedtext}
+%D
+%D that generates two commands:
+%D
+%D \showsetup{start<<framedtext>>}
+%D \showsetup{<<framedtext>>}
+%D
+%D The next definition shows the defaults.
+
+\def\dodefineframedtext[#1][#2]%
+ {\presetlocalframed[\??kd#1]%
+ \getparameters[\??kd#1]
+ [\c!width=0.75\hsize,
+ \c!height=\v!fit,
+ \c!align=\v!yes,
+ \c!top=,
+ \c!bottom=\vfill,
+ \c!offset=1em,
+ \c!bodyfont=,
+ \c!style=,
+ \c!color=,
+ \c!left=,
+ \c!right=\hfill,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!inner=,
+ \c!frame=\v!on,
+ \c!topframe=,
+ \c!bottomframe=,
+ \c!leftframe=,
+ \c!rightframe=,
+ \c!radius=.5\bodyfontsize,
+ \c!corner=\v!rectangular,
+ \c!foregroundcolor=,
+ \c!foregroundstyle=,
+ \c!background=,
+ \c!backgroundcolor=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!linecorrection=\v!on,
+ \c!depthcorrection=\v!on,
+ \c!margin=\v!standard,
+ \c!orientation=,
+ \c!indenting=,
+ #2]%
+ \setvalue{\e!start#1}{\dostartframedtext[#1]}%
+ \setvalue{\e!stop #1}{\dostopframedtext }%
+ \setvalue {#1}{\doframedtext [#1]}}
+
+\def\defineframedtext
+ {\dodoubleempty\dodefineframedtext}
+
+%D We define the general (and original) case by just saying:
+
+\defineframedtext[\v!framedtext]
+
+%D We need several steps before the actual job is done,
+%D because we have to handle an optional identifier (and
+%D because these commands evolved out of a single case).
+
+\def\framedtextparameter#1#2%
+ {\csname\??kd#1#2\endcsname}
+
+\def\dosetupframedtexts[#1][#2]%
+ {\ifsecondargument
+ \def\docommand##1{\getparameters[\??kd##1][#2]}%
+ \processcommacommand[#1]\docommand % new, #1 may be macro
+ \else
+ \getparameters[\??kd\v!framedtext][#1]%
+ \fi}
+
+\def\setupframedtexts
+ {\dodoubleempty\dosetupframedtexts}
+
+\def\dostartframedtext
+ {\bgroup\dotripleempty\dodostartframedtext}
+
+\def\dodostartframedtext[#1][#2][#3]%
+ {\doifassignmentelse{#2}
+ {\dododostartframedtext[#1][][#2]}
+ {\dododostartframedtext[#1][#2][#3]}}
+
+\setfalse\framedtextlocationnone
+
+\def\dododostartframedtext[#1][#2][#3]% #3 only passed to framed, not to framedtext
+ {\doifsomething{#2}{\setvalue{\??kd#1\c!location}{#2}}% does not listen to #3
+ \setfalse\framedtextlocationnone
+ \processaction % \v!low en \v!depth are already taken !
+ [\framedtextparameter{#1}\c!location]
+ [ \v!left=>\letvalue{\??kd#1\c!left }\relax
+ \letvalue{\??kd#1\c!right}\hfill,
+ \v!right=>\letvalue{\??kd#1\c!left }\hfill
+ \letvalue{\??kd#1\c!right}\relax,
+ \v!middle=>\letvalue{\??kd#1\c!left }\hfill
+ \letvalue{\??kd#1\c!right}\hfill,
+ \v!none=>\letvalue{\??kd#1\c!left }\relax % new
+ \letvalue{\??kd#1\c!right}\relax % new
+ \settrue\framedtextlocationnone]%
+ \letvalue{\??kd#1\c!location}\empty
+ % removed 06/2001
+ % \forgetparindent
+ % added 06/2001 [see demo-bbv]
+ \localhsize\hsize \checkframedtext
+ % so far
+ \setbox\framebox\vbox
+ \startboxedcontent
+ \hsize\localhsize
+ % \insidefloattrue % ? better
+ \expanded{\switchtobodyfont[\framedtextparameter{#1}\c!bodyfont]}%
+ \startcolor[\framedtextparameter{#1}\c!color]%
+ \localframed[\??kd#1][\c!strut=\v!no,#3]% todo: use delayedstrut
+ \bgroup
+ \let\\=\endgraf
+ \framedtextparameter{#1}\c!inner % oud spul
+ \doifvalue{\??kd#1\c!depthcorrection}\v!on % new, inside box
+ {\bgroup
+ \verticalstrut
+ % we need \nowhitespace in case of setups setting whitespace
+ % nb, not safe, text vs \vbox as next
+ \vskip-\struttotal
+ \nowhitespace % na vskip ! new 20/05/2004, fails with next content being box (\scale{..})
+ }%
+ \doinhibitblank % \blank[\v!disable]% plaatst signal
+\setupindenting[\framedtextparameter{#1}\c!indenting]%
+ \doconvertfont{\framedtextparameter{#1}\c!style}\empty
+ \def\dostopframedtext{\dodostopframedtext{#1}{#2}}}
+
+%D The \type {none} option is handy for nested usage, as
+%D in the presentation styles, where we don't want
+%D interference.
+
+\def\dodostopframedtext#1#2% % no \baselinecorrection, see faq docs
+ {\endgraf
+ \removelastskip
+ \doifvalue{\??kd#1\c!depthcorrection}\v!on % local and global
+ {\forgetall
+ \vskip-\struttotal
+ \verticalstrut
+ \egroup
+ \forgetall
+ \vskip-\lineheight
+ % will be an option, not default
+ % \setbaselinecorrections
+ % \donegbotbaselinecorrection
+ \verticalstrut}
+ \stopboxedcontent
+ \stopcolor
+ \ifconditional\framedtextlocationnone
+ \egroup
+ \box\framebox
+ \else\ifinsidefloat
+ \egroup
+ \box\framebox
+ \else
+ \egroup
+ \doplacement[\??kd#1][\c!depthcorrection=\v!off]{\box\framebox}%
+ \fi\fi
+ \egroup}
+
+%D Placement can be ignored:
+%D
+%D \starttyping
+%D \hbox to \hsize \bgroup
+%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext
+%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext
+%D \egroup
+%D
+%D \hbox to \hsize \bgroup
+%D \setupframedtexts[location=none]%
+%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext
+%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext
+%D \egroup
+%D \stoptyping
+
+%D The simple brace (or group) delimited case is typeset
+%D slightly different and is not aligned.
+
+\def\doframedtext
+ {\bgroup\dodoubleempty\dodoframedtext}
+
+\def\dodoframedtext[#1][#2]% beware!
+ {\expanded{\switchtobodyfont[\getvalue{\??kd#1\c!bodyfont}]}%
+ \localframed[\??kd#1][\c!strut=\v!no,#2]%
+ \bgroup
+ \blank[\v!disable]%
+ \let\\=\endgraf
+ \getvalue{\??kd#1\c!inner}% % kleur naar outer level
+ \dostartattributes{\??kd#1}\c!style\c!color\empty
+ \bgroup
+ \aftergroup\docloseframedtext
+ \let\next=}
+
+\def\docloseframedtext
+ {\removelastskip
+ \dostopattributes
+ \egroup
+ \egroup}
+
+%D \macros
+%D {defineframed}
+%D
+%D One can also define simple framed texts, using:
+%D
+%D \showsetup{defineframed}
+
+\def\defineframed
+ {\dodoubleempty\dodefineframed}
+
+\def\dodefineframed[#1][#2]%
+ {\iffirstargument
+ \setvalue{#1}{\dodoubleempty\doframed[#2]}%
+ \fi}
+
+\def\doframed[#1][#2]%
+ {\framed[#1,#2]}
+
+%D \macros
+%D {textrule, starttextrule, setuptextrules}
+%D
+%D Putting rules before and after a paragraph is very space
+%D sensitive, but the next command handles that quite well. It
+%D comes in two disguises:
+%D
+%D \startbuffer
+%D \textrule[top]{fragments}
+%D \input reich
+%D \textrule
+%D \stopbuffer
+%D
+%D \bgroup \typebuffer \getbuffer \egroup
+%D
+%D \startbuffer
+%D \setuptextrules
+%D [width=90pt,distance=12pt,rulecolor=blue,
+%D bodyfont=small,style=\sc,color=red]
+%D
+%D \starttextrule{Ship Building Tools}
+%D \nl \setuptolerance[tolerant] \input materie
+%D \stoptextrule
+%D \stopbuffer
+%D
+%D \bgroup \typebuffer \getbuffer \egroup
+%D
+%D \startbuffer
+%D \setuptextrules
+%D [location=inmargin,
+%D bodyfont=small,style=slantedbold]
+%D
+%D \starttextrule{wonderful}
+%D \input tufte
+%D \stoptextrule
+%D \stopbuffer
+%D
+%D \bgroup \typebuffer \getbuffer \egroup
+%D
+%D The formal definition of these commands is:
+%D
+%D \showsetup{textrule}
+%D \showsetup{starttextrule}
+%D \showsetup{setuptextrules}
+%D
+%D The implementation looks a bit complicated due to the
+%D optional arguments.
+
+\def\setuptextrules
+ {\dodoubleargument\getparameters[\??tl]}
+
+\def\complextextrule[#1]% if needed we can make it installable
+ {\let\next\dobottomtextrule
+ \processaction
+ [#1]
+ [ \v!top=>\let\next\dotoptextrule,
+ \v!middle=>\let\next\domiddletextrule,
+ \v!bottom=>\let\next\dobottomtextrule]%
+ \dosinglegroupempty\next}
+
+\definecomplexorsimple\textrule
+
+\def\simpletextrule
+ {\dosinglegroupempty\dounknowntextrule}
+
+\def\docomplextextrule#1%
+ {\bgroup
+ \advance\hsize\dimexpr-\rightskip-\leftskip\relax
+ \setbox\scratchbox\hbox to \hsize
+ {\dimen4\dimexpr .5ex+.5\linewidth\relax
+ \dimen6\dimexpr-.5ex+.5\linewidth\relax
+ \doifnothing{#1}\firstargumentfalse
+ \iffirstargument
+ \doifelse\@@tllocation\v!inmargin
+ {\llap{\doattributes\??tl\c!style\c!color{#1}\hskip\leftmargindistance}}
+ {\color[\@@tlrulecolor]
+ {\vrule\!!height\dimen4\!!depth\dimen6\!!width\@@tlwidth}%
+ \hbox spread 2\dimexpr\@@tldistance\relax
+ {\hss\doattributes\??tl\c!style\c!color{\strut#1}\hss}}%
+ \fi
+ \color[\@@tlrulecolor]
+ {\leaders\hrule\!!height\dimen4\!!depth\dimen6\hfill}}%
+ \ht\scratchbox\strutht
+ \dp\scratchbox\strutdp
+ \noindent\box\scratchbox
+%\nobreak\verticalstrut\kern-\struttotal
+% evt \witruimte
+ \egroup}
+
+\def\dotoptextrule#1%
+ {\page[\v!preference] % interferes
+ %\whitespace % no
+ \@@tlbefore
+ \docomplextextrule{#1}%
+% todo, option: \doifnothing{#1}{\ruledvskip-.5ex}
+ \nowhitespace
+ \@@tlinbetween
+ \endgraf}
+
+\def\dodobottomtextrule#1#2%
+ {\ifhmode
+ \endgraf
+ \fi
+ \dimen0\strutdp
+ \ifdim\prevdepth>\strutdp\else % was <\strutdp
+ \ifdim\prevdepth>\zeropoint
+ \advance\dimen0 -\prevdepth
+ \fi
+ \fi
+ \advance\dimen0 .5ex
+ \vskip\dimen0
+% ==
+% \vskip\dimexpr \strutdp + .5ex
+% \ifdim\prevdepth>\strutdp\else\ifdim\prevdepth>\zeropoint-\prevdepth\fi\fi\relax
+%
+ \@@tlinbetween
+ \doifelsenothing{#2}
+ {\bgroup
+ \advance\hsize\dimexpr-\rightskip-\leftskip\relax
+ \nointerlineskip
+ \moveleft-\leftskip\vbox
+ {\color[\@@tlrulecolor]
+ {\hrule\!!depth\linewidth\!!height\zeropoint\!!width\hsize}}%
+ \egroup}
+ {\docomplextextrule{#2}}%
+ \ifvmode\prevdepth\zeropoint\fi
+ #1%
+ \page[\v!preference]}
+
+\def\dobottomtextrule
+ {\dodobottomtextrule\@@tlafter}
+
+\def\domiddletextrule
+ {\dodobottomtextrule\@@tlinbetween}
+
+\def\dounknowntextrule
+ {\iffirstargument
+ \@EA\dotoptextrule
+ \else
+ \@EA\dobottomtextrule\@EA\empty
+ \fi}
+
+%D The grouped commands also supports bodyfont switching:
+
+\def\starttextrule#1%
+ {\bgroup
+ \def\dounknowntextrule{\domiddletextrule}
+ \dotoptextrule{#1}
+ \bgroup
+ \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}}
+
+\def\stoptextrule
+ {\par
+ \egroup
+ \dobottomtextrule\empty
+ \egroup}
+
+%D \macros
+%D {fillinrules, setupfillinrules}
+%D
+%D The next few commands do not really deserve a place in a
+%D core module, because they deal with specific typography.
+%D Nevertheless I decided to make them part of the core,
+%D because they permit us to make questionaires. Let's start
+%D with some examples.
+%D
+%D \fillinrules[n=2,width=fit]{first}
+%D \fillinrules[n=2,width=broad]{first}
+%D \fillinrules[n=2,width=3cm]{first}
+%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first}
+%D \fillinrules[n=2]{first}{last}
+%D \fillintext{first}{last} \input reich \par
+%D
+%D The main command is \type{\fillinrules}. This command takes
+%D one and an optional second argument and sets a paragraph with
+%D empty visualized lines.
+%D
+%D \showsetup{fillinrules}
+%D \showsetup{setupfillinrules}
+
+\def\setupfillinrules
+ {\dodoubleargument\getparameters[\??il]}
+
+\definecomplexorsimpleempty\fillinrules
+
+\def\complexfillinrules[#1]%
+ {\def\docomplexfillinrules##1##2%
+ {\dodocomplexfillinrules[#1]{##1}{##2}{\thinrules
+ [\c!n=\@@iln,\c!interlinespace=\@@ilinterlinespace,\c!before=,\c!after=]}}%
+ \dodoublegroupempty\docomplexfillinrules}
+
+\def\dodocomplexfillinrules[#1]#2#3#4%
+ {\endgraf
+ \@@ilbefore
+ \begingroup
+ \setupfillinrules[#1]%
+ \noindent
+ \doifsomething{#2}
+ {\doifelse\@@ilwidth\v!fit
+ {\let\@@ildistance\!!zeropoint
+ \hbox}
+ {\doifelse\@@ilwidth\v!broad
+ {\hbox}
+ {\hbox to \@@ilwidth}}%
+ \bgroup
+ \doattributes\??il\c!style\c!color{\strut#2\hfill\@@ilseparator}%
+ \hskip\@@ildistance
+ \egroup}%
+ %\hangindent=\wd0\relax % tzt hang=yes,n
+ %\parindent=\hangindent
+ %\box0\relax
+ \setupwhitespace[\v!big]%
+ \ignorespaces
+ #4%
+ \doifsomething{#3}
+ {\kern\@@ildistance
+ \doattributes\??il\c!style\c!color{#3\strut}}%
+ \endgroup
+ \endgraf
+ \@@ilafter}
+
+%D \macros
+%D {fillintext}
+%D
+%D To provide compatible layouts when texts and lines are
+%D mixed, one can typeset a paragraph by using the command
+%D \type{\fillintext}.
+%D
+%D \showsetup{fillintext}
+
+\definecomplexorsimpleempty\fillintext
+
+\def\complexfillintext[#1]% rather rough, using an \unhbox is suboptimal
+ {\def\docomplexfillintext##1##2%
+ {\dowithnextbox
+ {\dodocomplexfillinrules[#1]{##1}{\hfill##2}{\unhbox\nextbox\unskip}}%
+ \hbox\bgroup\let\par\egroup\ignorespaces}%
+ \dodoublegroupempty\docomplexfillintext}
+
+%D \macros
+%D {fillinline, setupfillinlines}
+%D
+%D Another member of the family takes care of putting a (often
+%D small) rule after a piece of text, like
+%D
+%D \startbuffer
+%D \fillinline \input reich \par
+%D \fillinline[margin=0cm] \input reich \par
+%D \stopbuffer
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D which was typeset by saying:
+%D
+%D \typebuffer
+%D
+%D The two commands that take care of this are:
+%D
+%D \showsetup{fillinline}
+%D \showsetup{setupfillinlines}
+
+\def\setupfillinlines
+ {\dodoubleargument\getparameters[\??iv]}
+
+\definecomplexorsimpleempty\fillinline
+
+\def\complexfillinline[#1]%
+ {%\endgraf % interferes with \definedescription cum suis
+ \@@ivbefore
+ \begingroup
+ \setupfillinlines[#1]%
+ \advance\rightskip \@@ivmargin
+ \parfillskip\zeropoint
+ \def\par % very dangerous
+ {\let\par\endgraf % -)
+ \ifhmode\unskip\hfill\fi
+ \scratchdimen\dimexpr\@@ivwidth-\@@ivdistance\relax
+ \ifdim\scratchdimen>\@@ivmargin\else\expandafter\rlap\fi
+ {\kern\@@ivdistance
+ \vrule
+ \!!width \scratchdimen
+ \!!height.5\linewidth
+ \!!depth .5\linewidth}%
+ \endgraf % !
+ \endgroup
+ \endgraf % !
+ \@@ilafter}}
+
+%D \stopdocumentation
+%D \bgroup
+%D
+%D \setupframedtexts
+%D [setuptext]
+%D [background=color,backgroundcolor=white]
+%D
+%D \startbuffer
+%D \setupbackground
+%D [backgroundoffset=4pt,
+%D background=screen,
+%D frame=on,
+%D framecolor=red,
+%D leftoffset=2pt]
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \startbackground
+%D
+%D \macros
+%D {setupbackground,startbackground,background}
+%D
+%D The section deals with backgrounds in the running text. This
+%D means that texts is to be collected and split over pages. To
+%D show what can be done, we provide this part of the
+%D documentation with some gray background and a red frame.
+%D Both the background and frame can have all characteristics
+%D of \type{\framed}. This time we used the setting:
+%D
+%D \typebuffer
+%D
+%D The implementation is not that sophisticated, but suffices.
+%D The main problem with this kind of functionality is to get
+%D the spacing all right.
+
+%D Specifying the background is more or less the same as
+%D specifying a framed box.
+%D
+%D \showsetup{setupbackground}
+
+\presetlocalframed[\??ag]
+
+\def\dosetupbackground[#1]%
+ {\getparameters[\??ag][#1]%
+ \doifelse\@@agstate\v!start
+ {\let\startbackground\dostartbackground
+ \let\stopbackground \dostopbackground
+ \let\background \dobackground}
+ {\let\startbackground\relax
+ \let\stopbackground \relax
+ \let\background \relax}}
+
+\def\setupbackground
+ {\dosingleargument\dosetupbackground}
+
+%D Actually typesetting the background is implemented rather
+%D straightforward. We need to handle some spacing as well as
+%D the (often) a bit smaller horizontal size.
+%D
+%D \showsetup{startbackground}
+%D
+%D Although we could have used a scratch one, we first
+%D declare a boolean.
+
+% 0=no-split, 1=no-split+indent, 2=split, 3=split+indent
+
+\chardef\backgroundsplitmode\plusthree
+
+%D The \type{\vbox to \lineheight{}\vskip\zeropoint}
+%D construction gives the first real line a decent height by
+%D adding a dummy line.
+
+\def\dostartbackground
+ {\endgraf
+ \bgroup
+ \setbox0\vbox\bgroup
+ \vbox to \lineheight{}\vskip\zeropoint
+ \blank[\v!disable]
+ % \advance\hsize -\@@agleftoffset
+ % \advance\hsize -\@@agrightoffset
+ \leftskip \@@agleftoffset % new **
+ \rightskip\@@agrightoffset} % new **
+
+%D This dummy line is removed by \type{\setbox2=\vsplit0 to
+%D \lineheight}. That way \type{\topskip} takes care of the
+%D lineheight. I'll probably forget to apply this trick
+%D elsewhere.
+
+\def\dostopbackground % improved version (i hope)
+ {\endgraf
+ \removelastskip
+ \egroup
+ \dimen2\leftskip % new **
+ \forgetall
+ \ifinsidefloat
+ \chardef\backgroundsplitmode\zerocount
+ \fi
+ \ifcase\backgroundsplitmode
+ \localframed[\??ag][\c!offset=\v!overlay]{\box0}%
+ \or
+ \hskip\dimen2
+ \localframed[\??ag][\c!offset=\v!overlay]{\box0}%
+ \else
+ \splitmaxdepth\boxmaxdepth
+ \splittopskip\topskip
+ \setbox2\vsplit0 to \lineheight % get rid of fake line
+ \loop
+ \ifdim\pagetotal=\zeropoint % empty page
+ \scratchdimen\textheight
+ \chardef\backgroundsplit\plusone % split to max height
+ \else
+ \setbox\scratchbox\vbox{\@@agbefore}%
+ \scratchdimen\dimexpr\pagegoal-\ht\scratchbox-\pagetotal\relax
+ \chardef\backgroundsplit\plustwo % split to partial height
+ \fi
+ \advance\scratchdimen\dimexpr-\@@agtopoffset-\@@agbottomoffset\relax
+ \ifdim\scratchdimen>2\lineheight\relax % reasonable, will be configurable
+ \ifdim\ht0>\scratchdimen % larger than page
+ \setbox2\vsplit0 to \scratchdimen
+ \else
+ \setbox2\box0
+ \chardef\backgroundsplit\zerocount % no split
+ \fi
+ \setbox2\vbox \ifcase\backgroundsplit\or to \textheight \fi % max split
+ {\vskip\@@agtopoffset
+ \popsplitproperties
+ \unvcopy2
+ \prevdepth\dp2
+ \obeydepth
+ \vskip\@@agbottomoffset
+ \vfill}
+ \@@agbefore
+ \ifcase\backgroundsplit\or\or % partial split
+ \ifdim\pagegoal<\maxdimen
+ \pagegoal=1.2\pagegoal % be a bit more tolerant
+ \fi
+ \fi
+ \startlinecorrection
+ %\localframed[\??ag][\c!offset=\v!overlay]{\hskip\@@agleftoffset\box2\hskip\@@agrightoffset}%
+ \ifnum\backgroundsplitmode=\plusthree \hskip\dimen2 \fi %
+ \localframed[\??ag][\c!offset=\v!overlay]{\box2}% new **
+ \stoplinecorrection
+ \ifcase\backgroundsplit % no split
+ \@@agafter
+ \else % some split
+ \vfill\eject % geen \page !
+ \fi
+ \else
+ \page
+ \fi
+ \ifdim\ht0>\zeropoint \repeat
+ \fi
+ \egroup
+ \endgraf}
+
+%D As a bonus we also have a short command, that is of not
+%D much use, but kept there for historic reasons.
+%D
+%D \showsetup{background}
+
+\def\dobackground
+ {\bgroup
+ \dowithnextbox
+ {\localframed[\??ag][\c!offset=\v!overlay]{\flushnextbox}\egroup}
+ \vbox}
+
+%D \stopdocumentation
+%D \stopbackground
+%D \egroup
+
+%D New, for the moment private; let's see when GB finds out
+%D about this one and its obscure usage. It's used in:
+%D
+%D \startbuffer
+%D \defineframedtext
+%D [tabulateframe]
+%D [offset=overlay,
+%D backgroundoffset=3pt,
+%D background=color,
+%D backgroundcolor=green]
+%D
+%D \setuptabulate
+%D [tabulate]
+%D [frame=tabulateframe]
+%D
+%D \setuptables
+%D [frame=tabulateframe]
+%D
+%D \input tufte
+%D
+%D \starttabulate[|l|l|]
+%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
+%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
+%D \stoptabulate
+%D
+%D \input tufte
+%D
+%D \starttable[|l|l|]
+%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
+%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
+%D \stoptable
+%D \stopbuffer
+%D
+%D \typebuffer
+
+\def\defineframedcontent
+ {\dodoubleempty\dodefineframedcontent}
+
+\def\dodefineframedcontent[#1][#2]%
+ {\presetlocalframed[\??fc#1]%
+ \getparameters[\??fc#1]
+ [\c!leftoffset=\zeropoint,
+ \c!rightoffset=\getvalue{\??fc#1\c!leftoffset},
+ \c!topoffset=\zeropoint,
+ \c!bottomoffset=\getvalue{\??fc#1\c!topoffset},
+ \c!strut=\v!no,
+ \c!offset=\v!overlay,
+ \c!linecorrection=\v!no,
+ \c!left=,
+ \c!right=,
+ #2]}
+
+\let\setuplocalframed\getparameters
+
+\def\setupframedcontent
+ {\dodoubleempty\dosetupframedcontent}
+
+\def\dosetupframedcontent[#1][#2]%
+ {\def\docommand##1{\getparameters[\??fc##1][#2]}%
+ \processcommacommand[#1]\docommand}
+
+\def\startframedcontent[#1]%
+ {\bgroup
+ \let\stopframedcontent\egroup
+ \doifnot{#1}\v!off
+ {\doifdefined{\??fc#1\c!frame}
+ {\def\stopframedcontent{\dostopframedcontent{#1}}%
+ \dostartframedcontent{#1}}}}
+
+\def\dostartframedcontent#1%
+ {\setbox\framebox\hbox\bgroup
+ \setlocalhsize
+ \hsize\localhsize
+ \advance\hsize\dimexpr-\getvalue{\??fc#1\c!leftoffset}-\getvalue{\??fc#1\c!rightoffset} \relax
+ \advance\vsize\dimexpr-\getvalue{\??fc#1\c!topoffset} -\getvalue{\??fc#1\c!bottomoffset}\relax
+ \hskip\getvalue{\??fc#1\c!leftoffset}%
+ \vbox\bgroup
+ \vskip\getvalue{\??fc#1\c!topoffset}%
+ \vbox\bgroup
+ \forgetall
+ \blank[\v!disable]}
+
+\def\dostopframedcontent#1%
+ {\removelastskip
+ \egroup
+ \vskip\getvalue{\??fc#1\c!bottomoffset}%
+ \egroup
+ \hskip\getvalue{\??fc#1\c!rightoffset}%
+ \egroup
+ \doifvalue{\??fc#1\c!width}\v!fit
+ {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox
+ \ifinsidefloat
+ \donefalse
+ \else
+ \doifelsevalue{\??fc#1\c!linecorrection}\v!yes\donetrue\donefalse
+ \fi
+ % plaats ?
+ \ifdone\startlinecorrection\fi
+ \getvalue{\??fc#1\c!left}% new
+ \localframed[\??fc#1]{\box\framebox}%
+ \getvalue{\??fc#1\c!right}% new
+ \ifdone\stoplinecorrection\fi
+ \egroup}
+
+%D \macros
+%D {backgroundline}
+%D
+%D For the moment an undocumented feature, but a cancidate
+%D for going public.
+
+\def\backgroundline[#1]%
+ %{\doifsomething{#1}{\dobackgroundline{#1}}\hbox}
+ {\doifcolorelse{#1}{\dobackgroundline{#1}\hbox}\hbox}
+
+% \def\backgroundline[#1]%
+% {\doifcolor{#1}{\dobackgroundline{#1}}\hbox}
+
+\def\dobackgroundline#1%
+ {\dowithnextbox
+ {\hbox
+ {\localcolortrue
+ \startcolor[#1]%
+ \vrule
+ \!!width \nextboxwd
+ \!!height\nextboxht
+ \!!depth \nextboxdp
+ \stopcolor
+ \hskip-\nextboxwd
+ \flushnextbox}}}
+
+%D \macros
+%D {encircled}
+%D
+%D Some not so robust left||overs (borrowed from Knuth,
+%D \TEX Book\ page 356):
+
+\def\encircled#1%
+ {{\ooalign{\hfil\raise0.07ex\hbox{{\tx#1}}\hfil\crcr\mathhexbox20D}}}
+
+\let\omcirkeld\encircled
+
+\setuplinewidth
+ [\v!medium]
+
+\setupframed
+ [\c!width=\v!fit,
+ \c!height=\v!broad,
+ \c!lines=,
+ \c!offset=0.25ex, % \defaultframeoffset
+ \c!empty=\v!no,
+ \c!frame=\v!on,
+ \c!topframe=,
+ \c!bottomframe=,
+ \c!leftframe=,
+ \c!rightframe=,
+ \c!radius=.5\bodyfontsize,
+ \c!rulethickness=\linewidth,
+ \c!corner=\v!rectangular,
+ \c!depth=\!!zeropoint,
+ \c!foregroundcolor=,
+ \c!foregroundstyle=,
+ \c!background=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!backgroundcolor=,
+ \c!backgroundoffset=\!!zeropoint,
+ \c!framecolor=,
+ \c!frameoffset=\!!zeropoint,
+ \c!backgroundcorner=\framedparameter\c!corner,
+ \c!backgroundradius=\framedparameter\c!radius,
+ \c!backgrounddepth=\framedparameter\c!depth,
+ \c!framecorner=\framedparameter\c!corner,
+ \c!frameradius=\framedparameter\c!radius,
+ \c!framedepth=\framedparameter\c!depth,
+ \c!component=,
+ \c!align=,
+ \c!bottom=\vss,
+ \c!top=,
+ \c!strut=\v!yes,
+ \c!autostrut=\v!yes,
+ \c!location=\v!normal,
+ \c!orientation=,
+ \c!autowidth=\v!yes,
+ \c!setups=]
+
+\setupscreens
+ [%\c!factor=1.0, % obsolete
+ %\c!method=\v!external, % obsolete
+ \c!screen=0.95]
+
+\setupblackrules
+ [\c!n=3,
+ \c!width=1em,
+ \c!height=1ex,
+ \c!depth=\!!zeropoint,
+ \c!alternative=\c!a,
+ \c!distance=.25ex,
+ \c!color=]
+
+\setupmarginrules
+ [\c!level=0,
+ \c!rulethickness=\@@kadefaultwidth\linewidth]
+
+\setupthinrules
+ [\c!interlinespace=\v!small,
+ \c!n=3,
+ \c!before=,
+ \c!inbetween={\blank[\v!white]},
+ \c!after=,
+ \c!color=,
+ \c!height=.5\linewidth,
+ \c!depth=.5\linewidth,
+ \c!frame=\v!on, % compatible with textbackgrounds
+ \c!alternative=\v!b,
+ \c!backgroundcolor=,
+ \c!background=,
+ \c!rulethickness=]
+
+\setuptextrules
+ [\c!location=\v!left,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!inbetween=,
+ \c!width=2em,
+ \c!style=\v!bold,
+ \c!color=,
+ \c!rulecolor=,
+ \c!bodyfont=,
+ \c!distance=.5em]
+
+\setupfillinrules
+ [\c!width=\v!broad,
+ \c!distance=1em,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!n=1,
+ \c!interlinespace=\v!small,
+ \c!separator=,
+ \c!style=\v!normal,
+ \c!color=]
+
+\setupfillinlines
+ [\c!width=3cm,
+ \c!margin=\@@ivwidth,
+ \c!distance=1em,
+ \c!before=\blank,
+ \c!after=\blank]
+
+\setupbackground
+ [\c!leftoffset=.5\bodyfontsize,
+ \c!rightoffset=\@@agleftoffset,
+ \c!topoffset=\!!zeropoint,
+ \c!bottomoffset=\@@agtopoffset,
+ \c!state=\v!start,
+ \c!radius=.5\bodyfontsize,
+ \c!corner=\v!rectangular,
+ \c!frame=\v!off,
+ \c!color=,
+ \c!depth=\!!zeropoint,
+ \c!background=\v!screen,
+ \c!backgroundcolor=\@@agcolor,
+ \c!screen=\@@rsscreen,
+ \c!before=,
+ \c!after=]
+
\protect \endinput
diff --git a/tex/context/base/core-rul.mkiv b/tex/context/base/core-rul.mkiv
index 24e05974d..78c7156b8 100644
--- a/tex/context/base/core-rul.mkiv
+++ b/tex/context/base/core-rul.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-rul,
-%D version=2008.06.05,
+%D version=1998.10.16,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Ruled Stuff Handling,
%D author=Hans Hagen,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
+\writestatus{loading}{ConTeXt Core Macros / Ruled Content Handling}
%D After a few months testing this solution is now added
%D to the core. This introduces a possible incompatibility
@@ -23,16 +23,263 @@
% 4 lines oeps : 3.6 2.8 3.0
% tufte 7.5 4.1 4.3
-% \newbox\luashapebox
+\unprotect
+
+%D We have removed the rather old and out dated raster methods. They
+%D have not been used for ages.
+
+%D \macros
+%D {linewidth, setuplinewidth}
+%D
+%D This module deals with rules (lines) in several ways. First
+%D we introduce two macros that can be used to set some common
+%D characteristics.
+%D
+%D \showsetup{setuplinewidth}
+%D
+%D The linewidth is available in \type{\linewidth}. The
+%D preset value of .4pt equals the default hard coded \TEX\
+%D rule width.
+
+\newdimen\linewidth
+
+\def\dosetuplinewidth[#1]%
+ {\assigndimension{#1}\linewidth{.2\points}{.4\points}{.6\points}}
+
+\def\setuplinewidth
+ {\dosingleargument\dosetuplinewidth}
+
+%D \macros
+%D {ruledlinewidth, inheritruledlinewidth}
+%D
+%D Inside framed boxed we will use a private dimensions. As
+%D an option one can let the linewidth inherit its value from
+%D this one.
+
+\newdimen\ruledlinewidth \newif\ifinheritruledlinewidth
+
+% %D \TEX\ lacks support for color and even gray scales. The next
+% %D macros can provide a sort of poor mans gray scales as well
+% %D as give access to more suitable methods of rendering. Such a
+% %D method looks like:
+% %D
+% %D \starttyping
+% %D \def\methodegraybox#1#2#3#4#5#6%
+% %D { ... }
+% %D \stoptyping
+% %D
+% %D The string \type{graybox} is a common element in the name,
+% %D so we can have for instance \type {\postscriptgraybox} or
+% %D \type {\texgraybox}. The first three arguments take a
+% %D dimension, the fourth one takes a number between~0 and~1,
+% %D and the last argument specifies a radius of the box when
+% %D rounded corners are used, so:
+% %D
+% %D \startbuffer
+% %D \dotgraybox{.5\hsize}{1cm}{0cm}{.85}{\v!no}{0pt}
+% %D \stopbuffer
+% %D
+% %D \typebuffer
+% %D
+% %D becomes:
+% %D
+% %D %\startlinecorrection
+% %D % \vbox to 1cm{\getbuffer}
+% %D %\stoplinecorrection
+% %D
+% %D \startlinecorrection
+% %D \unprotect
+% %D \vbox to 1cm{\dotgraybox{.5\hsize}{1cm}{0cm}{.85}{\v!no}{0pt}}
+% %D \protect
+% %D \stoplinecorrection
+% %D
+% %D There are two predefined methodes, one uses periods and the
+% %D other uses small rules. The second method is less
+% %D efficient, but sometimes give better results. The dimensions
+% %D of the resullting box are set to zero.
%
-% \def\doreshapeframedbox
-% {\setbox\luashapebox\box\framebox
-% \ctxlua{commands.doreshapeframedbox(\number\luashapebox)}%
-% \setbox\framebox\box\luashapebox}
+% \setvalue{\v!dot graybox}{\processraster\symbol\rasterdot}
+% \setvalue{\v!rule graybox}{\processraster\symbol\rasterbox}
+%
+% \def\rasterdot{\rasterfont.}
+% \def\rasterbox{\hss\vrule\!!width.4pt\!!height.4pt\!!depth\zeropoint}
+%
+% %D Now of course we need:
+%
+% \ifx\rasterfont\undefined \def\rasterfont{\fivepoint} \fi
+%
+% %D We implement two pure \TEX\ based generators, that use
+% %D \type{\leaders} to quickly gerenate the gray pattern. One
+% %D should beware of \DIMENSION\ conflicts, so we use some
+% %D registers above~8. These macros are memory hungry and byte
+% %D spoiling.
+%
+% \def\processraster#1#2#3#4#5#6#7%
+% {\bgroup
+% \forgetall
+% \dontcomplain
+% \dimen10=\onepoint
+% \dimen10=\@@rsfactor\dimen10
+% \dimen10=#5\dimen10
+% \setbox2\hbox to #2
+% {\cleaders\hbox to 2\dimen10{#1\hss}\hss}%
+% \dimen12=#3%
+% \advance\dimen12 #4%
+% % \setbox0\vbox to \dimen12
+% {\cleaders\vbox to 2\dimen10{\box2\vss}\vss}%
+% \setbox0\hbox
+% {\hskip-.5\dimen10\lower0.5\dimen10\copy0
+% \hskip-\wd0\hskip\dimen10\lower1.5\dimen10\box0}%
+% \box0
+% \egroup}
-\def\doreshapeframedbox{\ifvbox\framebox\ctxlua{commands.doreshapeframedbox(\number\framebox)}\fi}
+%D \macros
+%D {setupscreens}
+%D
+%D The previous macro uses a predefined constant
+%D \type{\@@rsfactor}. This factor can be set by:
+%D
+%D \showsetup{setupscreens}
+
+\def\setupscreens
+ {\dodoubleargument\getparameters[\??rs]}
+
+% %D The most appropriate way to call for this feature is
+% %D using \type{\graybox}, which is defined as:
+%
+% \def\graybox{\getvalue{\@@rsmethod graybox}}
+%
+% %D We just introduced two pure \TEX\ methods for generating
+% %D rasters. However, it's far more efficient and comfortable in
+% %D terms of speed, memory usage and file size, to use a driver
+% %D supported method.
+%
+% \setvalue{\v!external graybox}{\setgraybox}
+%
+% %D For compatibility reasons we also define the original one:
+%
+% \setvalue{\v!postscript graybox}{\getvalue{\v!external graybox}}
+%
+% %D A quite valid way of letting drivers do the job, is giving
+% %D a solid rule a gray texture.
+
+%D We will communicate through module specific variables, current
+%D framed parameters and some reserved dimension registers.
+
+\newdimen \frameddimenwd
+\newdimen \frameddimenht
+\newdimen \frameddimendp
+
+%D We don't have to stick to a \TEX\ drawn rule, but
+%D also can use rounded or even fancier shapes, as we will
+%D see later on.
+
+\def\dofilledbox
+ {\bgroup
+ \doifelse{\framedparameter\c!backgroundcorner}\v!rectangular
+ {\dofilledlinedbox}
+ {\ifzeropt\dimexpr\framedparameter\c!backgroundradius\relax % just in case of .x\bodyfontsize
+ \dofilledlinedbox
+ \else
+ \dofilledroundbox
+ \fi}%
+ \egroup}
+
+\def\dophantombox
+ {\hphantom{\dofilledbox}}
+
+\def\dofilledlinedbox
+ {\vrule\!!width\frameddimenwd\!!height\frameddimenht\!!depth\frameddimendp\relax}%
+
+\def\dostrokedroundbox
+ {\doif{\framedparameter\c!frame}\v!on\dodostrokedroundbox}
+
+\def\dodostrokedroundbox
+ {\bgroup
+ \edef\ovalmod{\framedparameter\c!framecorner}%
+ \doifelse\ovalmod\v!round{\let\ovalmod\!!zerocount}{\edef\ovalmod{\number\ovalmod}}%
+ \edef\ovalwid{\the\frameddimenwd}%
+ \edef\ovalhei{\the\frameddimenht}%
+ \edef\ovaldep{\the\frameddimendp}%
+ \edef\ovallin{\the\dimexpr\ruledlinewidth}%
+ \edef\ovalrad{\the\dimexpr\framedparameter\c!frameradius}%
+ \let\ovalstr\!!plusone
+ \let\ovalfil\!!zerocount
+% \forcecolorhack
+ \doovalbox\ovalwid\ovalhei\ovaldep\ovallin\ovalrad\ovalstr\ovalfil\ovalmod
+ \egroup}
+
+\def\dofilledroundbox
+ {\bgroup
+ \edef\ovalmod{\framedparameter\c!backgroundcorner}%
+ \doifelse\ovalmod\v!round{\let\ovalmod\!!zerocount}{\edef\ovalmod{\number\ovalmod}}%
+ \edef\ovalwid{\the\frameddimenwd}%
+ \edef\ovalhei{\the\frameddimenht}%
+ \edef\ovaldep{\the\frameddimendp}%
+ \edef\ovallin{\the\dimexpr\ruledlinewidth\relax}%
+ \edef\ovalrad{\the\dimexpr\framedparameter\c!backgroundradius\relax}%
+ \let\ovalstr\!!zerocount
+ \let\ovalfil\!!plusone
+% \forcecolorhack
+ \doovalbox\ovalwid\ovalhei\ovaldep\ovallin\ovalrad\ovalstr\ovalfil\ovalmod
+ \egroup}
+
+% a lot of weird corners
+%
+% \startTEXpage
+% \dontleavehmode\framed
+% [corner=0,frame=on,framecolor=green,
+% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green,
+% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green,
+% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse {9}{12}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{13}{16}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{17}{20}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{21}{24}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \vskip1em
+% \dontleavehmode\dostepwiserecurse{25}{28}{1}{\framed
+% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
+% \quad}
+% \stopTEXpage
+
+%D The oval box is drawn using a special macro, depending on
+%D the driver in use.
-% speedup, prelude to dedicated mkiv module
+\def\dograybox % avoid black rules when no gray
+ {\doifelsenothing{\framedparameter\c!backgroundscreen}
+ {\dophantombox}
+ {\raster[\framedparameter\c!backgroundscreen]{\dofilledbox}}}
+
+%D It won't be a surprise that we not only provide gray boxes,
+%D but also colored ones. Here it is:
\def\dobackgroundcolorbox
{\hbox{\faststartcolor[\framedbackgroundcolor]\dofilledbox\faststopcolor}}
@@ -50,9 +297,3379 @@
\dophantombox
\fi}
+%D \macros
+%D {defineoverlay, doifoverlayelse, overlayoffset,
+%D overlaywidth, overlayheight, overlaydepth,
+%D overlaycolor, overlaylinecolor, overlaylinewidth}
+%D
+%D Before we define the macro that actually takes card of the
+%D backgrounds, we introduce overlays. An overlay is something
+%D that contrary to its name lays {\em under} the text. An
+%D example of an overlay definition is:
+%D
+%D \startbuffer[tmp-1]
+%D \defineoverlay
+%D [fancy]
+%D [{\externalfigure
+%D [mp-cont.502]
+%D [width=\overlaywidth,
+%D height=\overlayheight]}]
+%D \stopbuffer
+%D
+%D \typebuffer[tmp-1]
+%D
+%D That for instance can be uses in:
+%D
+%D \startbuffer[tmp-2]
+%D \framed[backgroundachtergrond=fancy]{How Fancy!}
+%D \framed[backgroundachtergrond=fancy,frame=off]{Even More Fancy!}
+%D \stopbuffer
+%D
+%D and looks like:
+%D
+%D \startlinecorrection
+%D \vbox{\baselineskip24pt\getbuffer[tmp-1]\getbuffer[tmp-2]}
+%D \stoplinecorrection
+%D
+%D The formal definition is:
+%D
+%D \showsetup{defineoverlay}
+%D
+%D This macro's definition is a bit obscure, due the many
+%D non||used arguments and the two step call that enable the
+%D setting of the width, height and depth variables.
+%D Multiple backgrounds are possible and are specified as:
+%D
+%D \starttyping
+%D \framed[background={one,two,three}]{Three backgrounds!}
+%D \stoptyping
+%D
+%D Most drawing packages only know width and height. Therefore
+%D the dimensions have a slightly different meaning here:
+%D
+%D \startitemize[packed]
+%D \item \type{\overlaywidth }: width of the overlay
+%D \item \type{\overlayheight}: height plus depth of the overlay
+%D \item \type{\overlaydepth }: depth of the overlay
+%D \stopitemize
+%D
+%D The resulting box is lowered to the right depth.
+
+\def\overlaywidth {\the\hsize\space} % We preset the variables
+\def\overlayheight {\the\vsize\space} % to some reasonable default
+\let\overlaydepth \!!zeropoint % values. The attributes
+\let\overlayoffset \!!zeropoint % of the frame can be (are)
+\let\overlaycolor \empty % set somewhere else.
+\let\overlaylinewidth \!!zeropoint %
+\let\overlaylinecolor \empty %
+
+%D The next register is used to initialize overlays.
+
+\newtoks\everyoverlay
+
+%D An example of an initialization is the following (overlays
+%D can contain text and be executed under an regime where
+%D interlineskip is off).
+
+\appendtoks \oninterlineskip \to \everyoverlay
+
+\def\defineoverlay
+ {\dodoubleargument\dodefineoverlay}
+
+\def\dodefineoverlay[#1][#2]%
+ {\def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}%
+ \processcommalist[#1]\docommand}
+
+\prependtoks
+ \hsize\overlaywidth
+ \vsize\overlayheight
+\to\everyoverlay
+
+\long\def\executedefinedoverlay#1#2%
+ {\bgroup
+ \edef\overlaywidth {\the\frameddimenwd\space}%
+ \edef\overlayheight{\the\dimexpr\frameddimenht+\frameddimendp\relax\space}%
+ \edef\overlaydepth {\the\frameddimendp\space}%
+ \edef\overlaycolor {\framedparameter\c!backgroundcolor}%
+ %\edef\overlaycorner{\framedparameter\c!backgroundcorner}%
+ %\edef\overlayradius{\framedparameter\c!backgroundradius}%
+ \let\overlayoffset\backgroundoffset % we steal this one
+ \setbox\scratchbox\hbox{\lower\overlaydepth\hbox{\the\everyoverlay#2}}%
+ \setbox\scratchbox\hbox
+ {\hskip-.5\dimexpr\wd\scratchbox-\overlaywidth \relax
+ \raise-.5\dimexpr\ht\scratchbox-\frameddimenht\relax % not overlayheight !
+ \box\scratchbox}%
+ \wd\scratchbox\overlaywidth
+ \ht\scratchbox\overlayheight
+ \dp\scratchbox\overlaydepth
+ \startlayoutcomponent{o:#1}{overlay #1}%
+ \box\scratchbox
+ \stoplayoutcomponent
+ \egroup}
+
+%D The empty case is:
+
+\let\executeoverlay\gobblesevenarguments
+
+%D For testing we provide:
+
+\def\doifoverlayelse#1%
+ {\doifdefinedelse{\??ov#1}}
+
+%D We predefine two already familiar backgrounds:
+
+\setvalue{\??ov\v!screen}{\dograybox }
+\setvalue{\??ov\v!color }{\docolorbox}
+
+% %D After all these preparations, the background macro does no
+% %D bring to many surprises. One has to keep in mind that this
+% %D macro starts up a call chain, depending on the background
+% %D one needs:
+% %D
+% %D \startitemize[packed]
+% %D \item a raster, color or user defined shape
+% %D \item square or round corners
+% %D \item a \TEX\ or driver based method
+% %D \stopitemize
+% %D
+% %D The macro can be extended by adding commands to the token
+% %D list register \type {\everybackgroundbox}. For this
+% %D purpose, the name of the current background is available in
+% %D \type {\currentbackgound}.
+
+%D The content of the box will be (temporary) saved in a box. We
+%D also have an extra box for backgrounds.
+
+\newbox\framebox
+\newbox\extraframebox
+
+\newtoks\everybackgroundbox
+
+\let\currentbackground\empty
+
+% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method
+% {\bgroup
+% \def\currentbackground{#1}%
+% \the\everybackgroundbox
+% \setbox\extraframebox\hbox
+% {\vbox{\moveleft\backgroundoffset\hbox{\executeifdefined{\??ov\currentbackground}\donothing}}}%
+% \wd\extraframebox\zeropoint % \backgroundwidth
+% \ht\extraframebox\backgroundheight
+% \dp\extraframebox\backgrounddepth
+% \box\extraframebox % \hskip-\backgroundwidth
+% \egroup}
+
+% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method
+% {\bgroup
+% \def\currentbackground{#1}%
+% \ifcsname\??ov\currentbackground\endcsname
+% \the\everybackgroundbox
+% \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}%
+% \wd\extraframebox\zeropoint % \backgroundwidth
+% \ht\extraframebox\backgroundheight
+% \dp\extraframebox\backgrounddepth
+% \box\extraframebox % \hskip-\backgroundwidth
+% \fi
+% \egroup}
+
+\def\dodobackgroundbox
+ {\bgroup
+ \ifcsname\??ov\currentbackground\endcsname
+ \the\everybackgroundbox
+ \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}%
+ \wd\extraframebox\zeropoint % \backgroundwidth
+ \ht\extraframebox\backgroundheight
+ \dp\extraframebox\backgrounddepth
+ \box\extraframebox % \hskip-\backgroundwidth
+ \fi
+ \egroup}
+
+\def\dododobackgroundbox#1,#2% #2 gobbles spaces
+ {\edef\currentbackground{#1}%
+ \ifx\currentbackground\s!unknown\else
+ \dodobackgroundbox\expandafter\dododobackgroundbox
+ \fi#2}
+
+\let\backgroundoffset\!!zeropoint
+\let\backgrounddepth \!!zeropoint
+\def\backgroundwidth {\the\hsize}
+\def\backgroundheight{\the\vsize}
+
+% todo: also \def\theforegroundbox{#1}
+
+% \def\dobackgroundbox#1%
+% {\setbox\framebox\vbox
+% {\forgetall
+% \boxmaxdepth\maxdimen
+% \scratchdimen \framedparameter{#1}\relax
+% \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
+% \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
+% \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax
+% \edef\backgroundoffset{\the\scratchdimen}%
+% \edef\backgroundwidth {\the\wd\framebox}%
+% \edef\backgroundheight{\the\ht\framebox}%
+% \edef\backgrounddepth {\the\dp\framebox}%
+% %\edef\foregroundbox{\box#1}%
+% \def\foregroundbox% fuzzy but needed hack, this \vss, otherwise
+% {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift
+% \edef\component{\framedparameter\c!component}%
+% \hbox to \backgroundwidth % in case 'foreground' is used as overlay
+% {\ifx\component\empty
+% \rawprocesscommalist[\framedbackground]\dodobackgroundbox
+% \else
+% \startlayoutcomponent{b:\component}{\s!background\space\component}%
+% \rawprocesscommalist[\framedbackground]\dodobackgroundbox
+% \stoplayoutcomponent
+% \fi
+% \box\framebox\hss}}}
+
+\def\normalforegroundbox% fuzzy but needed hack, this \vss, otherwise
+ {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift
+
+\def\dobackgroundbox#1%
+ {\setbox\framebox\vbox
+ {\forgetall
+ \boxmaxdepth\maxdimen
+ \scratchdimen \framedparameter{#1}\relax
+ \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
+ \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
+ \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax
+ \edef\backgroundoffset{\the\scratchdimen}%
+ \edef\backgroundwidth {\the\wd\framebox}%
+ \edef\backgroundheight{\the\ht\framebox}%
+ \edef\backgrounddepth {\the\dp\framebox}%
+ %\edef\foregroundbox{\box#1}%
+ \edef\component{\framedparameter\c!component}%
+ \let\foregroundbox\normalforegroundbox
+ \hbox to \backgroundwidth % in case 'foreground' is used as overlay
+ {\ifx\component\empty
+ \normalexpanded{\noexpand\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax
+ \else
+ \startlayoutcomponent{b:\component}{background \component}%
+ \normalexpanded{\noexpand\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax
+ \stoplayoutcomponent
+ \fi
+ \box\framebox\hss}}}
+
+%D One can explictly insert the foreground box. For that
+%D purpose we introduce the overlay \type {foreground}.
+
+\defineoverlay[\v!foreground][\foregroundbox]
+
+%D We can specify overlays as a comma separated list of
+%D overlays, a sometimes handy feature.
+
+%D Besides backgrounds (overlays) we also need some macros to
+%D draw outlines (ruled borders). Again we have to deal with
+%D square and round corners. The first category can be handled
+%D by \TEX\ itself, the latter one depends on the driver. This
+%D macro also support a negative offset.
+
+\ifx\scratchoffset\undefined \newdimen\scratchoffset \fi
+
+\def\dooutlinebox % we needed to move the color command in order to apply attributes properly
+ {\setbox\framebox\vbox % rules on top of box
+ {\scratchoffset \framedparameter\c!frameoffset\relax
+ \frameddimenwd\dimexpr\wd\framebox+2\scratchoffset\relax
+ \frameddimenht\dimexpr\ht\framebox+ \scratchoffset\relax
+ \frameddimendp\dimexpr\dp\framebox+ \scratchoffset+\framedparameter\c!framedepth\relax
+ \ifdim\frameddimendp<\zeropoint
+ \advance\frameddimenht \frameddimendp
+ \scratchdimen-\frameddimendp
+ \frameddimendp\zeropoint
+ \else
+ \scratchdimen\zeropoint
+ \fi
+ \setbox\extraframebox\hbox
+ {\doifsomething{\framedparameter\c!framecolor}{\color[\framedparameter\c!framecolor]}{\dostrokedbox}}%
+ \setbox\extraframebox\hbox
+ {\raise\scratchdimen\vbox
+ {\moveleft\scratchoffset
+ \box\extraframebox}}%
+ \wd\extraframebox\wd\framebox
+ \ht\extraframebox\ht\framebox
+ \dp\extraframebox\dp\framebox
+ \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}}
+
+\def\dostrokedbox
+ {\doifelse{\framedparameter\c!framecorner}\v!rectangular
+ {\dostrokedlinedbox}
+ {\ifzeropt\dimexpr\framedparameter\c!frameradius\relax % just in case of .x\bodyfontsize
+ \dostrokedlinedbox
+ \else
+ \dostrokedroundbox
+ \fi}}
+
+\def\dostrokedlinedbox
+ {\setbox\scratchbox\null
+ \wd\scratchbox\frameddimenwd
+ \ht\scratchbox\frameddimenht
+ \dp\scratchbox\frameddimendp
+ \setbox\scratchbox\vbox \bgroup
+ \csname t\@@frame@@\framedparameter\c!frame\framedparameter\c!topframe \endcsname
+ \hbox \bgroup
+ \csname l\@@frame@@\framedparameter\c!frame\framedparameter\c!leftframe \endcsname
+ \box\scratchbox
+ \csname r\@@frame@@\framedparameter\c!frame\framedparameter\c!rightframe \endcsname
+ \egroup
+ \csname b\@@frame@@\framedparameter\c!frame\framedparameter\c!bottomframe\endcsname
+ \egroup
+ \wd\scratchbox\frameddimenwd
+ \ht\scratchbox\frameddimenht
+ \dp\scratchbox\frameddimendp
+ \box\scratchbox}
+
+\def\@@frame@@{@@frame@@}
+
+% \setvalue{t\@@frame@@\v!on \v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{t\@@frame@@\v!off\v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{t\@@frame@@\v!on }{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{b\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+% \setvalue{b\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+% \setvalue{b\@@frame@@\v!on }{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+% \setvalue{l\@@frame@@\v!on \v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{l\@@frame@@\v!off\v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{l\@@frame@@\v!on }{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+% \setvalue{r\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+% \setvalue{r\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+% \setvalue{r\@@frame@@\v!on }{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+
+\def\@@frame@@trule{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
+\def\@@frame@@brule{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
+\def\@@frame@@rrule{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
+\def\@@frame@@lrule{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
+
+\letvalue{t\@@frame@@\v!on \v!on}\@@frame@@trule
+\letvalue{t\@@frame@@\v!off\v!on}\@@frame@@trule
+\letvalue{t\@@frame@@\v!on }\@@frame@@trule
+
+\letvalue{b\@@frame@@\v!on \v!on}\@@frame@@brule
+\letvalue{b\@@frame@@\v!off\v!on}\@@frame@@brule
+\letvalue{b\@@frame@@\v!on }\@@frame@@brule
+
+\letvalue{l\@@frame@@\v!on \v!on}\@@frame@@lrule
+\letvalue{l\@@frame@@\v!off\v!on}\@@frame@@lrule
+\letvalue{l\@@frame@@\v!on }\@@frame@@lrule
+
+\letvalue{r\@@frame@@\v!on \v!on}\@@frame@@rrule
+\letvalue{r\@@frame@@\v!off\v!on}\@@frame@@rrule
+\letvalue{r\@@frame@@\v!on }\@@frame@@rrule
+
+% no overlapping rules
+
+\def\@@frame@@trules{\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}\nointerlineskip\kern-\ruledlinewidth}
+\def\@@frame@@brules{\kern-\ruledlinewidth\nointerlineskip\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}}
+\def\@@frame@@rrules{\kern-\ruledlinewidth\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth}
+\def\@@frame@@lrules{\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth\kern-\ruledlinewidth}
+
+% small is relatively new
+
+\letvalue{t\@@frame@@\v!small\v!small}\@@frame@@trules
+\letvalue{t\@@frame@@\v!off \v!small}\@@frame@@trules
+\letvalue{t\@@frame@@\v!small }\@@frame@@trules
+
+\letvalue{b\@@frame@@\v!small\v!small}\@@frame@@brules
+\letvalue{b\@@frame@@\v!off \v!small}\@@frame@@brules
+\letvalue{b\@@frame@@\v!small }\@@frame@@brules
+
+\letvalue{l\@@frame@@\v!small\v!small}\@@frame@@lrules
+\letvalue{l\@@frame@@\v!off \v!small}\@@frame@@lrules
+\letvalue{l\@@frame@@\v!small }\@@frame@@lrules
+
+\letvalue{r\@@frame@@\v!small\v!small}\@@frame@@rrules
+\letvalue{r\@@frame@@\v!off \v!small}\@@frame@@rrules
+\letvalue{r\@@frame@@\v!small }\@@frame@@rrules
+
+%D I condidered using the low level support command
+%D \type{\ruledhbox}, but this would slow down processing by a
+%D factor~3.
+
+% \framed
+% [width=4cm,height=3cm,rulethickness=3mm,
+% frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on]
+% {}
+% \framed
+% [width=4cm,height=3cm,rulethickness=3mm,
+% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small]
+% {}
+% \framed
+% [width=4cm,height=3cm,rulethickness=3mm,
+% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on]
+% {}
+
+%D The next few macros are probably the most misused ones in
+%D \CONTEXT. They deal with putting rules around boxes, provide
+%D backgrounds, offer alignment features, and some more. We
+%D start with defining some booleans. These give an impression
+%D of what we are going to take into account.
+
+% todo: chardefs
+
+\newif\ifboxhasoffset
+\newif\ifboxhaswidth
+\newif\ifboxhasheight
+\newif\ifboxhasformat
+\newif\ifboxhasstrut
+\newif\ifboxisoverlaid
+\newif\ifboxhasframe
+\newif\ifdelayedstrut
+\newif\ifboxhasextraoffset
+
+%D We also need a few \DIMENSIONS:
+
+\newdimen\@@localoffset
+\newdimen\@@globalwidth
+
+%D \macros
+%D {framed, setupframed}
+%D
+%D Ruled boxes are typeset using \type{\framed}. This command
+%D is quite versatile and, although some users will probably
+%D seldom use it, one cannot overlook its features.
+%D
+%D \showsetup{setupframed}
+%D \showsetup{framed}
+%D
+%D This general macro is a special version of an even more
+%D general case, that can easily be linked into other macros
+%D that need some kind of framing. The local version is called
+%D with an extra parameter: the variable identifier. The reason
+%D for passing this identifier between brackets lays in the
+%D mere fact that this way we can use the optional argument
+%D grabbers.
+
+\def\defaultframeoffset{.25ex}
+
+\def\presetlocalframed [#1]{\letvalue{#1\s!parent}\??oi}
+\def\inheritlocalframed[#1]#2[#3]{\letvalue{#1\s!parent}#3}
+\def\copylocalframed [#1]#2[#3]{\setvalue{#1\s!parent}{#3}}
+
+\presetlocalframed[\??ol]
+
+% \unexpanded\def\framed
+% {\bgroup
+% \dodoubleempty\startlocalframed[\??ol]}
+
+\newcount\framednesting
+
+\unexpanded\def\framed
+ {\bgroup
+ \advance\framednesting\plusone
+ \letvalue{\??ol:\the\framednesting\s!parent}\??ol
+ \dodoubleempty\startlocalframed[\??ol:\the\framednesting]}
+
+\def\setupframed
+ {\dodoubleempty\dosetupframed}
+
+\def\dosetupframed
+ {\ifsecondargument
+ \@EA\dodoublesetupframed
+ \else
+ \@EA\dosinglesetupframed
+ \fi}
+
+\def\dosinglesetupframed[#1][#2]%
+ {\getparameters[\??ol][#1]}
+
+\def\dodoublesetupframed[#1][#2]%
+ {\bgroup
+ \let\dodoubleempty\empty
+ \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}%
+ \getvalue{#1}%
+ \egroup
+ \letvalue{#1}\globalredefinedframed}
+
+%D \startbuffer
+%D \setupframed [framecolor=yellow] \framed{A}
+%D \defineframed[myframed] [framecolor=blue] \myframed{B}
+%D \setupframed [myframed] [framecolor=red] \myframed{C}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \presetlocalframed[myframed]
+%D \setuplocalframed[myframed][width=4cm,height=2cm]
+%D \localframed[myframed][framecolor=green]{oeps}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {ifinframed}
+%D
+%D The normal case first presets all parameters and next starts
+%D looking for the user supplied ones. The first step is
+%D omitted in the local case, because these are preset at
+%D declaration time and keep their values unless explictly
+%D changed. By presetting the variables everytime the normal
+%D command is called, we can use this command nested, without
+%D the unwanted side effect of inheritance. The boolean is
+%D used to speed up the color stack.
+
+\newif\ifinframed
+
+\def\localframed
+ {\bgroup
+ \dodoubleempty\startlocalframed}
+
+%D The next one is faster on multiple backgrounds per page. No
+%D dimensions can be set, only frames and backgrounds.
+
+\def\fastlocalframed[#1]#2[#3]#4% 3-4
+ {\bgroup
+ \inframedtrue
+ \edef\@@framed{#1}%
+ % some hackery (no \dimexpr)
+ \scratchdimen\framedparameter\c!frameoffset
+ \setevalue{\@@framed\c!frameoffset}{\the\scratchdimen}%
+ \doifnot{\framedparameter\c!backgroundoffset}\v!frame
+ {\scratchdimen\framedparameter\c!backgroundoffset
+ \setevalue{\@@framed\c!backgroundoffset}{\the\scratchdimen}}%
+ % so far
+ \setbox\framebox\hbox{#4}%
+ \getparameters[\@@framed][#3]% no \expanded !
+ % not here, in calling macro: setups
+ \removeframedboxdepth
+ \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}%
+ \ifx\framedforegroundcolor\empty\else\docolorframebox\fi
+ \edef\overlaylinecolor{\framedparameter\c!framecolor}%
+ \edef\overlaylinewidth{\the\ruledlinewidth}%
+ \edef\@@localframing {\framedparameter\c!frame}%
+ \ifx\@@localframing\v!overlay \else \ifx\@@localframing\v!none \else
+ \edef\framedrulethickness{\framedparameter\c!rulethickness}%
+ \ifx\framedrulethickness\empty\else
+ \ruledlinewidth\framedrulethickness\relax
+ \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi
+ \fi
+ \dooutlinebox % real or invisible frame
+ \fi \fi
+ \edef\framedbackground{\framedparameter\c!background}%
+ \ifx\framedbackground\empty\else\dobackedbox\fi
+ \restoreframedboxdepth
+ \box\framebox
+ \egroup}
+
+%D Before we go into details, we present (and implement) the
+%D main framing routine. I saw no real reason for splitting the
+%D next two macros into smaller pieces. The content will be
+%D collected in a horizontal or vertical box with fixed or free
+%D dimensions and specific settings concerning aligment and
+%D offsets.
+%D
+%D In the first few lines, we pre||expand the frame and
+%D background offsets. We do so, because the can be defined in
+%D terms of the main offset. However, see for instance page
+%D backgrounds, when \type {#2} sets the offset to \type
+%D {overlay}, both offsets become invalid.
+%D
+%D Because it is used so often the he next macro is (and
+%D looks) rather optimized.
+
+\let\postprocessframebox\relax
+
+\let\@@framed\s!unknown
+
+\def\framedparameter #1{\csname\doframedparameter\@@framed#1\endcsname}
+\def\framedparameterhash#1{\doframedparameterhash \@@framed#1}
+
+\def\doframedparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doframedparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\doframedparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doframedparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\doframedparentparameter #1#2{\ifx#1\relax\s!empty\else\doframedparameter #1#2\fi}
+\def\doframedparentparameterhash#1#2{\ifx#1\relax \else\doframedparameterhash#1#2\fi}
+
+% \def\s!root{root} % maybe configurable
+
+\def\doframedparentparameter#1#2{\ifx#1\relax\doframedrootparameter#2\else\doframedparameter#1#2\fi}
+\def\doframedrootparameter #1{\ifcsname\??oi#1\endcsname\??oi#1\else\s!empty\fi}
+
+\def\dosetframedattributes#1#2% style color
+ {\edef\fontattributehash {\framedparameterhash#1}%
+ \edef\colorattributehash{\framedparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+% defaults, kind of isolated now
+
+\getparameters
+ [\??oi]
+ [\c!width=\v!fit,
+ \c!height=\v!broad,
+ %\c!lines=,
+ \c!offset=0.25ex, % \defaultframeoffset
+ \c!empty=\v!no,
+ \c!frame=\v!on,
+ %\c!topframe=,
+ %\c!bottomframe=,
+ %\c!leftframe=,
+ %\c!rightframe=,
+ \c!radius=.5\bodyfontsize,
+ \c!rulethickness=\linewidth,
+ \c!corner=\v!rectangular,
+ \c!depth=\!!zeropoint,
+ %\c!foregroundcolor=,
+ %\c!foregroundstyle=,
+ %\c!background=,
+ %\c!backgroundscreen=,
+ %\c!backgroundcolor=,
+ \c!backgroundoffset=\!!zeropoint,
+ %\c!framecolor=,
+ \c!frameoffset=\!!zeropoint,
+ \c!backgroundcorner=\framedparameter\c!corner,
+ \c!backgroundradius=\framedparameter\c!radius,
+ \c!backgrounddepth=\framedparameter\c!depth,
+ \c!framecorner=\framedparameter\c!corner,
+ \c!frameradius=\framedparameter\c!radius,
+ \c!framedepth=\framedparameter\c!depth,
+ %\c!component=,
+ %\c!align=,
+ \c!bottom=\vss,
+ %\c!top=,
+ \c!strut=\v!yes,
+ \c!autostrut=\v!yes,
+ \c!location=\v!normal,
+ %\c!orientation=,
+ \c!autowidth=\v!yes,
+ %\c!setups=
+]
+
+\getparameters
+ [\??od] % for fast version
+ [\c!frame=\v!off,
+ \c!depth=\zeropoint,
+ \c!offset=\v!overlay,
+ %\c!component=,
+ \c!radius=.5\bodyfontsize,
+ \c!rulethickness=\linewidth,
+ \c!corner=\v!rectangular,
+ \c!backgroundoffset=\!!zeropoint,
+ \c!frameoffset=\!!zeropoint,
+ \c!backgroundcorner=\framedparameter\c!corner,
+ \c!backgroundradius=\framedparameter\c!radius,
+ \c!backgrounddepth=\framedparameter\c!depth,
+ \c!framecorner=\framedparameter\c!corner,
+ \c!frameradius=\framedparameter\c!radius,
+ \c!framedepth=\framedparameter\c!depth,
+ \c!location=\v!normal]
+
+% so far
+
+\newdimen\!!framedwidth
+\newdimen\!!framedheight
+\newdimen\!!framedscratch % so that users can use \scratchdimen
+
+\let\setextraframedoffsets \relax
+\let\applyextraframedoffsets\relax
+
+\def\startlocalframed[#1][#2]%
+ {\bgroup
+ \inframedtrue
+ \edef\@@framed{#1}%
+ % this piece of pre expansion is needed (sometimes used circular)
+ \!!framedscratch\framedparameter\c!frameoffset
+ \setevalue{\@@framed\c!frameoffset}{\the\!!framedscratch}%
+ \doifnot{\framedparameter\c!backgroundoffset}\v!frame
+ {\!!framedscratch\framedparameter\c!backgroundoffset
+ \setevalue{\@@framed\c!backgroundoffset}{\the\!!framedscratch}}%
+ % to prevent deadlock in case of self refering
+ \ifsecondargument % faster
+ \getparameters[\@@framed][#2]% here !
+ \fi
+ % new, experimental dirty hook
+ \framedparameter\c!extras
+ % to get the right spacing
+ \doifsomething{\framedparameter\c!foregroundstyle}
+ {\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}%
+ % beware, both the frame and background offset can be overruled
+ %
+ \edef\doframedsetups{\framedparameter\c!setups}%
+ \ifx\doframedsetups\empty\else
+ \edef\doframedsetups{\noexpand\setups[\doframedsetups]}%
+ \fi
+ % the next macros are visible
+ \edef\localoffset{\framedparameter\c!offset}%
+ \edef\localwidth {\framedparameter\c!width}%
+ \edef\localheight{\framedparameter\c!height}%
+ \edef\localformat{\framedparameter\c!align}%
+ \edef\localstrut {\framedparameter\c!strut}%
+ % these are not
+ \edef\@@localautostrut {\framedparameter\c!autostrut}%
+ \edef\@@localframing {\framedparameter\c!frame}%
+ \edef\@@locallocation {\framedparameter\c!location}%
+ \edef\@@localorientation{\framedparameter\c!orientation}%
+ %
+ \edef\@@localautowidth {\framedparameter\c!autowidth}%
+ %
+ \ifx\@@localframing\v!overlay % no frame, no offset, no framewidth
+ \boxhasframefalse
+ \let\localoffset\v!overlay
+ \else\ifx\@@localframing\v!none % no frame, no framewidth
+ \boxhasframefalse
+ \else
+ \boxhasframetrue
+ \fi\fi
+ \ifboxhasframe
+ \edef\framedrulethickness{\framedparameter\c!rulethickness}%
+ \ifx\framedrulethickness\empty\else
+ \ruledlinewidth\framedrulethickness\relax
+ \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi
+ \fi
+ \else
+ \ruledlinewidth\zeropoint
+ \fi
+ \ifx\localformat\empty
+ \boxhasformatfalse
+ \else
+ \boxhasformattrue
+ \dosetraggedcommand\localformat
+ \edef\dobeforeframedbox{\raggedtopcommand\framedparameter\c!top}%
+ \edef\doafterframedbox {\framedparameter\c!bottom\raggedbottomcommand}%
+ \fi
+ \ifx\localoffset\v!none
+ \boxhasoffsetfalse
+ \boxhasstrutfalse
+ \boxisoverlaidfalse
+ \@@localoffset\ruledlinewidth
+ \else\ifx\localoffset\v!overlay
+ % \ifx\@@localframing\v!no \boxhasframefalse \fi % test first
+ \boxhasoffsetfalse
+ \boxhasstrutfalse
+ \boxisoverlaidtrue
+ \@@localoffset\zeropoint
+ \else
+ \boxhasoffsettrue
+ \boxhasstruttrue
+ \boxisoverlaidfalse
+ \ifx\localoffset\v!default % new per 2-6-2000
+ \let\localoffset\defaultframeoffset
+ \letvalue{\@@framed\c!offset}\defaultframeoffset
+ \else
+ \let\defaultframeoffset\localoffset
+ \fi
+ \@@localoffset\dimexpr\localoffset+\ruledlinewidth\relax
+ \fi\fi
+ \!!framedheight\zeropoint
+ \!!framedwidth \zeropoint
+ \ifx\localwidth\v!fit
+ \ifboxhasformat
+ \boxhaswidthtrue
+ \!!framedwidth\hsize
+ \else
+ \boxhaswidthfalse
+ \fi
+ \else\ifx\localwidth\v!fixed % equals \v!fit but no shapebox
+ \ifboxhasformat
+ \boxhaswidthtrue
+ \!!framedwidth\hsize
+ \else
+ \boxhaswidthfalse
+ \fi
+ \else\ifx\localwidth\v!broad
+ \boxhaswidthtrue
+ \!!framedwidth\hsize
+ \else\ifx\localwidth\v!local
+ \boxhaswidthtrue
+ \setlocalhsize
+ \!!framedwidth\localhsize
+ \else
+ \boxhaswidthtrue
+ \!!framedwidth\localwidth
+ \fi\fi\fi\fi
+ \ifx\localheight\v!fit
+ \boxhasheightfalse % no longer: \boxhasstrutfalse
+ \else\ifx\localheight\v!broad
+ \boxhasheightfalse
+ \else
+ \boxhasheighttrue
+ \!!framedheight\localheight
+ \fi\fi
+ \ifboxhasheight
+ % obey user set height, also downward compatible
+ \else
+ \doifsomething{\framedparameter\c!lines}
+ {\ifcase\framedparameter\c!lines\else
+ \!!framedheight\framedparameter\c!lines\lineheight
+ \edef\localheight{\the\!!framedheight}%
+ \boxhasheighttrue
+ \fi}%
+ \fi
+ % this is now an option: width=local
+ %
+ % \ifdim\!!framedwidth=\hsize
+ % \parindent\zeropoint
+ % \setlocalhsize
+ % \!!framedwidth\localhsize
+ % \fi
+ % i.e. disable (colsetbackgroundproblemintechniek)
+ \advance\!!framedwidth -2\@@localoffset
+ \advance\!!framedheight -2\@@localoffset
+ \ifx\localstrut\v!no
+ \boxhasstrutfalse
+ \else\ifx\localstrut\v!global
+ \setstrut
+ \else\ifx\localstrut\v!local
+ \setfontstrut
+ \else
+ \setstrut
+ \fi\fi\fi
+ \ifboxhasstrut
+ \let\localbegstrut\begstrut
+ \let\localendstrut\endstrut
+ \let\localstrut \strut
+ \else
+ \let\localbegstrut\pseudobegstrut % was: \relax
+ \let\localendstrut\pseudoendstrut % was: \relax
+ \let\localstrut \pseudostrut % was: \relax
+ %\ifboxhasheight\ifdim\!!framedheight<\strutht % saveguard
+ % \let\localbegstrut\relax % but not that
+ % \let\localstrut \relax % save after all
+ %\fi\fi
+ \fi
+ \ifx\@@localautostrut\v!yes
+ \let\delayedbegstrut\relax
+ \let\delayedendstrut\relax
+ \let\delayedstrut \relax
+ \else
+ \let\delayedbegstrut\localbegstrut
+ \let\delayedendstrut\localendstrut
+ \let\delayedstrut \localstrut
+ \let\localbegstrut \relax
+ \let\localendstrut \relax
+ \let\localstrut \relax
+ \fi
+ \ifboxhasheight
+ \let\\\vboxednewline
+ \ifboxhaswidth
+ \let\hairline\vboxedhairline
+ \ifboxhasformat
+ \let\next\doformatboxSomeFormat
+ \else
+ \let\next\doformatboxNoFormat
+ \fi
+ \else
+ \let\hairline\hboxedhairline
+ \ifboxhasformat
+ \let\next\doformatboxHeight
+ \else
+ \let\next\doformatboxVSize
+ \fi
+ \fi
+ \else
+ \ifboxhaswidth
+ \ifboxhasformat
+ \let\hairline\vboxedhairline
+ \let\\\vboxednewline
+ \let\next\doformatboxWidth
+ \else
+ \let\hairline\hboxedhairline
+ \let\\\hboxednewline
+ \let\next\doformatboxHSize
+ \fi
+ \else
+ \let\hairline\hboxedhairline
+ \let\\\hboxednewline
+ \let\next\doformatboxNoSize
+ \fi
+ \fi
+ \setextraframedoffsets
+ \edef\framedwidth % a new feature, visible for user
+ {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}%
+ \edef\framedheight% a new feature, visible for user
+ {\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}%
+ % we need to register the (outer) color
+ \startregistercolor[\framedparameter\c!foregroundcolor]%
+ % first alternative
+ %\def\dowithframedbox%
+ % {\let\postprocessframebox\relax %new
+ % \aftergroup\stoplocalframed}%
+ % \afterassignment\dowithframedbox
+ % \setbox\framebox=\next}
+ % second alternative
+ %\dowithnextbox
+ % {\setbox\framebox\flushnextbox
+ % \let\postprocessframebox\relax %new
+ % \stoplocalframed}
+ % \next}
+ \@@startframedorientation
+ \afterassignment\dodowithframebox
+ \setbox\framebox\next}
+
+\def\dowithframebox
+ {% moved : \let\postprocessframebox\relax
+ \stoplocalframed}
+
+\def\dodowithframebox
+ {\aftergroup\dowithframebox}
+
+\let\doafterframedbox \relax
+\let\dobeforeframedbox\relax
+
+%D Carefull analysis of this macro will learn us that not all
+%D branches in the last conditionals can be encountered, that
+%D is, some assignments to \type{\next} will never occur.
+%D Nevertheless we implement the whole scheme, if not for
+%D future extensions.
+
+%D \macros
+%D {ifreshapeframebox}
+%D
+%D The last few lines tell what to do after the content of the
+%D box is collected and passed to the next macro. In the case
+%D of a fixed width and centered alignment, the content is
+%D evaluated and used to determine the most natural width. The
+%D rest of the code deals with backgrounds and frames.
+
+\newif\ifreshapeframebox \reshapeframeboxtrue
+
+%D Beware: setting \type {top} and \type {bottom} to nothing, may
+%D result in a frame that is larger that the given height! try:
+%D
+%D \starttyping
+%D \framed
+%D [height=3cm,top=,bottom=,offset=overlay]
+%D {\strut test \shapefill \strut test}
+%D \stoptyping
+%D
+%D This is intended behaviour and not a bug! One can always set
+%D
+%D \starttyping
+%D ...,bottom=\kern0pt,...
+%D \stoptyping
+
+\def\stoplocalframed
+ {\dontshowcomposition
+ \@@stopframedorientation % hm, wrong place ! should rotate the result (after reshape)
+ \stopregistercolor
+ \handleframedlocator\c!before\@@locallocation
+ \ifboxhasformat
+ \ifx\@@localautowidth\v!force
+ \ifreshapeframebox\doreshapeframedbox\fi
+ \boxhaswidthfalse
+ \else
+ \ifx\localwidth\v!fit
+ \ifx\@@localautowidth\v!yes
+ \ifreshapeframebox\doreshapeframedbox\fi
+ \fi
+ \boxhaswidthfalse
+ \else\ifx\localwidth\v!fixed
+ \boxhaswidthfalse
+ \else
+ \resetshapeframebox
+ \fi\fi
+ \fi
+\ifconditional\boxcontentneedsprocessing
+ \mkdoprocessboxcontents\framebox
+\fi
+ \else
+ \resetshapeframebox
+ \fi
+ \ifboxhaswidth
+ \wd\framebox\!!framedwidth
+ \fi
+ \ifboxhasheight
+ \ht\framebox\!!framedheight
+ \fi
+ \doif{\framedparameter\c!empty}\v!yes
+ {\setbox\scratchbox\null
+ \wd\scratchbox\wd\framebox
+ \ht\scratchbox\ht\framebox
+ \dp\scratchbox\dp\framebox
+ \setbox\framebox\box\scratchbox}%
+ \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}%
+ \ifx\framedforegroundcolor\empty\else\docolorframebox\fi
+ \ifboxhasextraoffset
+ \applyextraframedoffsets
+ \fi
+ \ifboxhasoffset
+ \dooffsetframebox
+ \fi
+ \ifboxisoverlaid \else
+ \dolocateframebox
+ \fi
+ \ifx\postprocessframebox\relax \else
+ \let\next\postprocessframebox
+ \let\postprocessframebox\relax % prevent nesting
+ \next\framebox
+ \fi
+ \edef\overlaylinecolor{\framedparameter\c!framecolor}%
+ \edef\overlaylinewidth{\the\ruledlinewidth}% \@@...
+ \ifboxhasframe % real or invisible frame
+ \dooutlinebox
+ \fi
+ \edef\framedbackground{\framedparameter\c!background}%
+ \ifx\framedbackground\empty\else\dobackedbox\fi
+ \handleframedlocator\c!after\@@locallocation
+ \box\framebox
+ \egroup
+ \egroup}
+
+\def\installframedlocator#1#2#3%
+ {\setvalue{\??oi:\c!location:\c!before:#1}{#2}%
+ \setvalue{\??oi:\c!location:\c!after :#1}{#3}}
+
+\def\handleframedlocator#1#2%
+ {\getvalue{\??oi:\c!location:#1:#2}}
+
+\def\doprelocframedbox#1%
+ {\scratchdimen\dimexpr#1+\ruledlinewidth\relax
+ \ifboxhasoffset
+ \advance\scratchdimen \framedparameter\c!offset
+ \fi
+ \scratchskip\dimexpr\ht\framebox-\scratchdimen\relax}
+
+% \ruledhbox
+% {A
+% \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging}
+% \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth}
+% \framed[width=2cm,align=middle,location=height] {location\\equals\\height}
+% B}
+% \vskip2cm
+% \ruledhbox
+% {A
+% \framed[width=2cm,align=middle,location=low] {location\\equals\\low}
+% \framed[width=2cm,align=middle,location=line] {location\\equals\\line}
+% \framed[width=2cm,align=middle,location=high] {location\\equals\\high}
+% B}
+% \vskip2cm
+% \ruledhbox
+% {A
+% \framed[width=2cm,align=middle,location=top] {location\\equals\\top}
+% \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom}
+% \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi}
+% \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle}
+% B}
+
+\installframedlocator \v!hanging % best with strut=no
+ {}
+ {\dp\framebox\ht\framebox
+ \ht\framebox\zeropoint}
+
+\installframedlocator \v!depth
+ {}
+ {\ht\framebox\dimexpr\ht\framebox-\strutdp\relax
+ \dp\framebox\strutdp
+ \box\framebox}
+
+\installframedlocator \v!height
+ {}
+ {\dp\framebox\dimexpr\ht\framebox-\strutht\relax
+ \ht\framebox\strutht
+ \box\framebox}
+
+\installframedlocator \v!high
+ {}
+ {\doprelocframedbox\strutht
+ \setbox\framebox\hbox{\lower\scratchskip\box\framebox}%
+ \ht\framebox\strutht
+ \dp\framebox\strutdp
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!line
+ {}
+ {\setbox\framebox\hbox{\lower.5\ht\framebox\box\framebox}%
+ \ht\framebox.5\lineheight
+ \dp\framebox.5\lineheight
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!low
+ {}
+ {\doprelocframedbox\strutdp
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\strutht
+ \dp\framebox\strutdp
+ \box\framebox}
+
+\installframedlocator \v!top
+ {}
+ {\doprelocframedbox\strutht
+ \setbox\framebox\hbox{\lower\scratchskip\box\framebox}%
+ \ht\framebox\scratchdimen
+ \dp\framebox\scratchskip
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!middle
+ {}
+ {\scratchdimen.5\ht\framebox
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\scratchdimen
+ \dp\framebox\scratchdimen
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!lohi
+ {\handleframedlocator\c!before\v!middle}
+ {\handleframedlocator\c!after \v!middle}
+
+\installframedlocator \v!bottom
+ {}
+ {\doprelocframedbox\strutdp
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\scratchskip
+ \dp\framebox\scratchdimen
+ \hbox{\box\framebox}}
+
+\installframedlocator \v!keep % retains height/depth
+ {\removeframedboxdepth}
+ {\restoreframedboxdepth}
+
+% also used in fastlocalframed
+
+\newdimen\originalframedwd
+\newdimen\originalframedht
+\newdimen\originalframeddp
+
+\def\removeframedboxdepth
+ {\originalframedwd\wd\framebox
+ \originalframedht\ht\framebox
+ \originalframeddp\dp\framebox
+ \ifzeropt\originalframeddp\else\setbox\framebox\hbox{\raise\originalframeddp\box\framebox}\fi
+ \wd\framebox\originalframedwd
+ \ht\framebox\dimexpr\originalframedht+\originalframeddp\relax
+ \dp\framebox\zeropoint}
+
+\def\restoreframedboxdepth
+ {\ifzeropt\originalframeddp\else\setbox\framebox\hbox{\lower\originalframeddp\box\framebox}\fi
+ \wd\framebox\originalframedwd
+ \ht\framebox\originalframedht
+ \dp\framebox\originalframeddp}
+
+% \let\@@startframedorientation\relax
+% \let\@@stopframedorientation \relax
+
+% \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax}
+% \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax}
+
+\def\@@startframedorientation
+ {\let\@@stopframedorientation \relax
+ \ifx\@@localorientation\empty\else
+ \ifcase\@@localorientation\else
+ \scratchcounter\@@localorientation
+ \divide\scratchcounter\plustwo
+ \ifodd\scratchcounter
+ \swapmacros\framedwidth \framedheight
+ \swapmacros\localwidth \localheight
+ \swapdimens\!!framedheight\!!framedwidth
+ \def\@@stopframedorientation{\@@dostopframedorientation\plusone}%
+ \else
+ \def\@@stopframedorientation{\@@dostopframedorientation\zerocount}%
+ \fi
+ \fi
+ \fi}
+
+\def\@@dostopframedorientation#1%
+ {\ifcase#1\else
+ \swapmacros\framedwidth \framedheight
+ \swapmacros\localwidth \localheight
+ \swapdimens\!!framedheight\!!framedwidth
+ \fi
+ \setbox\framebox\hbox{\dorotatebox\@@localorientation\hbox{\box\framebox}}}
+
+%D The last conditional takes care of the special situation of
+%D in||line \inframed[height=3cm]{framed} boxes. Such boxes have
+%D to be \inframed{aligned} with the running text.
+
+\def\doinframed[#1]% we could omit #1] but readibility ...
+ {\framed[\c!location=\v!low,#1]}
+
+\unexpanded\def\inframed
+ {\dosingleempty\doinframed}
+
+%D When we set \type{empty} to \type{yes}, we get
+%D ourselves a frame and/or background, but no content, so
+%D actually we have a sort of phantom framed box.
+
+%D Because color marks and specials can interfere with
+%D spacing, we provide a way to specify a foregroundcolor.
+
\def\docolorframebox
{\doifcolor\framedforegroundcolor
{\setbox\framebox\hbox{\faststartcolor[\framedforegroundcolor]\box\framebox\faststopcolor}}}
%{\setbox\framebox\hbox{\doactivatecolor\framedforegroundcolor\box\framebox}}}
+%D \macros
+%D {mframed, minframed}
+%D
+%D When Tobias asked how to frame mathematical elements in
+%D formulas, Taco's posted the next macro:
+%D
+%D \starttyping
+%D \def\mframed#1%
+%D {\relax
+%D \ifmmode
+%D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}%
+%D \else
+%D \framed{$#1$}%
+%D \fi}
+%D \stoptyping
+%D
+%D Because \type {\ifinner} does not (always) reports what
+%D one would expect, we move the test to the outer level. We
+%D also want to pass arguments,
+%D
+%D \starttyping
+%D \def\mframed%
+%D {\dosingleempty\domframed}
+%D
+%D \def\domframed[#1]#2% % tzt \dowithnextmathbox ?
+%D {\relax
+%D \ifmmode
+%D \ifinner
+%D \inframed[#1]{$#2$}%
+%D \else
+%D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}%
+%D \fi
+%D \else
+%D \inframed[#1]{$#2$}%
+%D \fi}
+%D \stoptyping
+%D
+%D Still better is the next alternative, if only because it
+%D takes care of setting the super- and subscripts styles
+
+\newcount\mframedstyle
+
+\def\doinlinemframed[#1]#2%
+ {\begingroup
+ \mframedstyle\mathstyle\relax
+ \inframed[#1]{$\triggermathstyle\mframedstyle#2$}%
+ \endgroup}
+
+\def\dodisplaymframed[#1]#2%
+ {\begingroup
+ \mframedstyle\mathstyle\relax
+ \def\normalstrut{$\triggermathstyle\mframedstyle\vphantom{(}$}%
+ \framed[#1]{$\triggermathstyle\mframedstyle#2$}%
+ \endgroup}
+
+\def\mframed {\dosingleempty\dodisplaymframed}
+\def\inmframed{\dosingleempty\doinlinemframed }
+
+%D So instead of the rather versatile \type {\framed}, we ue
+%D the \type {\mframed}.
+%D
+%D \startbuffer
+%D \startformula
+%D x \times \mframed{y} \times y^{z_z}
+%D x \times \inmframed{y} \times y^{z_z}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D However, we got into troubles when we want to nest sub- and
+%D superscripts, like in
+%D
+%D \startbuffer
+%D \startformula
+%D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D Therefore, we can best use \type {\super} and \type {\suber}
+%D instead of \type {^} and \type {_}. Both commands take care
+%D of proper font switching.
+%D
+%D \startbuffer
+%D \startformula
+%D x \times \mframed{y} \times y\super{\mframed{z}\suber{\mframed{z}}}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D As usual, one can specify in what way the text should be
+%D framed. One should be aware of the fact that, inorder to
+%D preserve the proper spacing, the \type {offset} is set to
+%D \type {overlay} and \type {frameoffset} is used used
+%D instead.
+%D
+%D \startbuffer
+%D \startformula
+%D x \times y\super{\mframed[framecolor=red]{z}\suber{z}}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D For inline use, we also provide the \type {\inmframed}
+%D alternative: we want $x \times \inmframed{y}$ in inline
+%D math, right?
+
+%D This previous framing macros needs a lot of alternatives for
+%D putting rules around boxes, inserting offsets and aligning
+%D text. Each step is handled by separate macros.
+
+\def\dowidenframebox#1%
+ {\setbox\framebox\vbox
+ {\kern#1\hbox{\kern#1\box\framebox\kern#1}\kern#1}}
+
+\def\dooffsetframebox{\dowidenframebox\localoffset}
+\def\dolocateframebox{\dowidenframebox\ruledlinewidth}
+
+%D Let's hope that the next few examples show us enough of
+%D what needs to be done by the auxiliary macros.
+%D
+%D \startbuffer
+%D \framed[height=1cm,offset=.5cm] {rule based learning}
+%D \framed[height=1cm,offset=0cm] {rule based learning}
+%D \framed[height=1cm,offset=none] {rule based learning}
+%D \framed[height=1cm,offset=overlay]{rule based learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D \startbuffer
+%D \framed[offset=.5cm] {rule based learning}
+%D \framed[offset=0cm] {rule based learning}
+%D \framed[offset=none] {rule based learning}
+%D \framed[offset=overlay]{rule based learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D \startbuffer
+%D \framed[strut=nee,offset=.5cm] {rule based learning}
+%D \framed[strut=nee,offset=0cm] {rule based learning}
+%D \framed[strut=nee,offset=none] {rule based learning}
+%D \framed[strut=nee,offset=overlay]{rule based learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D \startbuffer
+%D \framed[width=3cm,align=left] {rule\\based\\learning}
+%D \framed[width=3cm,align=middle] {rule\\based\\learning}
+%D \framed[width=3cm,align=right] {rule\\based\\learning}
+%D \framed[width=fit,align=middle] {rule\\based\\learning}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\dontcomplain\getbuffer}
+%D \stoplinecorrection
+%D
+%D So now we're ready for the complicated stuff. We distinguish
+%D between borders with straight lines and those with round
+%D corners. When using the first alternative it is possible to
+%D turn off one or more lines. More fancy shapes are also
+%D possible by specifying dedicated backgrounds. Turning lines
+%D on and off is implemented as efficient as possible and as a
+%D result is interface language dependant. This next
+%D implementation evolved from simpler ones. It puts for
+%D instance the rules on top of the content and provides
+%D additional offset capabilities. The lot of calls to other
+%D macros makes this mechanism not that easy to comprehend.
+
+%D Getting the backgrounds right takes less code. Again we
+%D have to take care of additional offsets.
+
+\def\dobackedbox
+ {\doifelsevalue{\@@framed\c!backgroundoffset}\v!frame % new
+ {\dobackgroundbox\c!frameoffset}
+ {\dobackgroundbox\c!backgroundoffset}}
+
+%D We handle left, right or middle alignment as well as fixed
+%D or free widths and heights. Each combination gets its own
+%D macro.
+
+%D The following code handles one-liners: \type{align={line,flushright}}.
+%D Beware, since we entered a group and either or not grab the next
+%D bgroup token, we need to finish the group in the oneliner mode.
+
+\ifx\raggedoneliner\undefined \chardef\raggedoneliner\zerocount \fi
+
+\def\doformatonelinerbox % beware: assumes explicit preceding bgroup
+ {\ifcase\raggedoneliner
+ \expandafter\nodoformatonelinerbox
+ \else
+ \expandafter\dodoformatonelinerbox
+ \fi}
+
+\def\dodoformatonelinerbox
+ {\dowithnextboxcontent
+ {\ignorespaces}
+ {\hbox to \hsize
+ {\ifcase\raggedstatus\or\hss\or\hss\fi
+ \unhbox\nextbox \removeunwantedspaces
+ \ifcase\raggedstatus\or \or\hss\or\hss\fi}%
+ \egroup}
+ \hbox}
+
+\def\nodoformatonelinerbox % grabs {
+ {\let\next=}
+
+%D The handlers:
+
+\def\doformatboxSomeFormat
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \hsize\!!framedwidth
+ \vsize\!!framedheight
+ \doframedsetups
+ \raggedcommand
+ \dobeforeframedbox
+ \bgroup
+ \localbegstrut
+ \aftergroup\localendstrut
+ \aftergroup\doafterframedbox
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxNoFormat
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \hsize\!!framedwidth
+ \vsize\!!framedheight
+ \doframedsetups
+ \raggedcenter
+ \vss
+ \bgroup
+ \localbegstrut
+ \aftergroup\localendstrut
+ \aftergroup\vss
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxHeight
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \doframedsetups
+ \raggedcommand
+ \vss
+ \bgroup
+ \aftergroup\localendstrut
+ \aftergroup\vss
+ \aftergroup\egroup
+ \localbegstrut
+ \doformatonelinerbox}
+
+\def\doformatboxWidth
+ {\vbox
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \oninterlineskip
+ \hsize\!!framedwidth
+ \doframedsetups
+ \raggedcommand
+ \dobeforeframedbox
+ \bgroup
+ \localbegstrut
+ \aftergroup\localendstrut
+ \aftergroup\doafterframedbox
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxVSize
+ {\vbox to \!!framedheight
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \vsize\!!framedheight
+ \doframedsetups
+ \vss
+ \bgroup
+ \aftergroup\vss
+ \aftergroup\egroup
+ \hbox
+ \bgroup
+ \aftergroup\egroup
+ \localstrut
+ \doformatonelinerbox}
+
+\def\doformatboxHSize
+ {\hbox to \!!framedwidth
+ \bgroup
+ \let\postprocessframebox\relax
+ \forgetall
+ \doframedsetups
+ \hss
+ \localstrut
+ \bgroup
+ \aftergroup\hss
+ \aftergroup\egroup
+ \doformatonelinerbox}
+
+\def\doformatboxNoSize
+ {\hbox
+ \bgroup
+ \let\postprocessframebox\relax
+ \doframedsetups
+ \localstrut
+ \doformatonelinerbox}
+
+\let\doframedsetups\relax
+
+%D On the next page we show some examples of how these macros
+%D come into action. The examples show us how
+%D \type {fit}, \type {broad} dimensions influence the
+%D formatting. Watch the visualized struts. \footnote {Here we
+%D used \type {\showstruts}.}
+%D
+%D \startpostponing
+%D \bgroup
+%D \showstruts
+%D \dontcomplain
+%D \startlinecorrection
+%D \halign{#\enskip&#\enskip&#\enskip&#\enskip&#\enskip&#\cr
+%D \framed[width=.2\hsize, height=.2\hsize, align=] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=yes] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=yes] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=yes] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=yes] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=yes] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=right] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=right] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=right] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=right] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=right] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=right] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=left] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=left] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=left] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=left] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=left] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=left] {a\par b\par c}\cr
+%D \noalign{\vskip1em}
+%D \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=broad, align=middle] {a\par b\par c}&
+%D \framed[width=.2\hsize, height=fit, align=middle] {a\par b\par c}&
+%D \framed[width=fit, height=.2\hsize, align=middle] {a\par b\par c}&
+%D \framed[width=fit, height=broad, align=middle] {a\par b\par c}&
+%D \framed[width=fit, height=fit, align=middle] {a\par b\par c}\cr}
+%D \stoplinecorrection
+%D \blank[2*big]
+%D \egroup
+%D \stoppostponing
+
+%D \macros
+%D {framednoflines, framedlastlength}
+%D
+%D It is possible to let the frame macro calculate the width
+%D of a centered box automatically (\type {fit}). When
+%D doing so, we need to reshape the box:
+
+% The next implementation is frozen! It preserves the depth,
+% otherwise we get problems with framed display math and auto
+% width.
+
+\newcount\framednoflines
+\newdimen\framedlastlength
+
+\def\resetshapeframebox
+ {\framednoflines \zerocount
+ \framedlastlength\zeropoint}
+
+\let\framedboxwidth \!!zeropoint
+\let\framedboxheight\!!zeropoint
+\let\framedboxdepth \!!zeropoint
+
+\chardef\reshapeframeboxmethod\plusone % 0=no flush, 1=old method 2=no depth messing
+
+% \newbox\luashapebox
+%
+% \def\doreshapeframedbox
+% {\setbox\luashapebox\box\framebox
+% \ctxlua{commands.doreshapeframedbox(\number\luashapebox)}%
+% \setbox\framebox\box\luashapebox}
+
+\def\doreshapeframedbox{\ifvbox\framebox\ctxlua{commands.doreshapeframedbox(\number\framebox)}\fi}
+
+%D The two variables \type {\framednoflines} and \type
+%D {\framedlastlength} can be used in a second pass to
+%D optimized framed material.
+
+% torture test / strange case (much depth) / method 2 needed
+%
+% \startTEXpage[frame=on]
+% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
+% test outside formula
+% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
+% \blank[big]
+% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
+% test outside formula
+% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
+% \stopTEXpage
+
+%D The examples on the next page show how one can give the
+%D frame as well as the background an additional offset and
+%D even a bit more depth. The blue outline is the frame, the
+%D red box is the background and the small black outline is the
+%D visualization of the resulting box, that is, we applied
+%D \type{\ruledhbox} to the result.
+
+%D \startpostponing
+%D \bgroup
+%D \unprotect
+%D \dontcomplain
+%D
+%D \startbuffer
+%D \vbox to \vsize
+%D \bgroup
+%D \startalignment[middle]
+%D \vss
+%D \dontleavehmode\vbox to .8\vsize
+%D \bgroup
+%D \hsize=300pt
+%D \setupframed
+%D [background=color,
+%D backgroundcolorachtergrondkleur=darkred,
+%D width=300pt,
+%D height=60pt,
+%D framecolorkaderkleur=DemoBlue,
+%D rulethickness=2pt]
+%D \def\status%
+%D {backgroundoffset=\framedparameter\c!backgroundoffset\\
+%D frameoffset=\framedparameter\c!frameoffset\\
+%D depth=\framedparameter\c!depth}
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}}
+%D \vss
+%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}}
+%D \egroup
+%D \vss
+%D \stopalignment
+%D \egroup
+%D \stopbuffer
+%D
+%D \getbuffer \page
+%D
+%D {\setupframed[depth=4pt]\getbuffer} \page
+%D
+%D \protect
+%D \egroup
+%D \stoppostponing
+
+%D When typesetting the framed box inline, we have to keep the
+%D baseline intact outside as well as inside the framed box.
+
+\def\doinlineframedbox
+ {\scratchdimen\dimexpr\strutdp+\ruledlinewidth\relax
+ \ifboxhasoffset
+ \advance\scratchdimen \framedparameter\c!offset
+ \fi
+ \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
+ \ht\framebox\strutht
+ \dp\framebox\strutdp
+ \box\framebox}
+
+%D We can also lower the box over the natural depth of the
+%D line.
+
+\def\doloweredframedbox
+ {\ht\framebox\dimexpr\ht\framebox+\dp\framebox-\strutdp\relax
+ \dp\framebox\strutdp
+ \box\framebox}
+
+%D Hanging the content is mainly meant for cases like the
+%D following:
+%D
+%D \starttyping
+%D \framed[strut=no]
+%D {\framed[height=2cm,location=hanging]{test}%
+%D \framed[height=1cm,location=hanging]{test}}
+%D \stoptyping
+
+\def\dohangingframedbox % best with strut=no
+ {\scratchdimen\dimexpr\ht\framebox+\dp\framebox\relax
+ \ht\framebox\zeropoint
+ \dp\framebox\scratchdimen}
+
+%D We can draw lines from left to right and top to bottom by
+%D using the normal \type{\hairline} command. Both directions
+%D need a different treatment.
+%D
+%D \startbuffer
+%D \framed[width=4cm] {alfa\hairline beta\hairline gamma}
+%D \framed[height=2cm] {alfa\hairline beta\hairline gamma}
+%D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \hbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D These macros try to adapt their behaviour as good as
+%D possible to the circumstances and act as natural as
+%D possible.
+
+\def\vboxedhairline
+ {\bgroup
+ \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi
+ \dimen4=\dimexpr\dimen2+\ruledlinewidth\relax
+ \setbox0\vbox
+ {\advance\hsize 2\dimen4
+ \vskip\dimen2
+ \hrule
+ \!!height\ruledlinewidth
+ \!!depth\zeropoint
+ \!!width\hsize
+ \vskip\dimen2}%
+ %\endgraf\nointerlineskip\endgraf
+ %\moveleft\dimen4\box0
+ %\endgraf\nointerlineskip\localbegstrut
+ \endgraf\obeydepth\nointerlineskip
+ \moveleft\dimen4\box0
+ \endgraf\nointerlineskip\localbegstrut % beware, we might kill it in a style using \vskip\lineheight
+ \egroup} % so this must not be changed
+
+\def\hboxedhairline % use framed dimen
+ {\bgroup
+ \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi
+ \ifboxhasheight
+ \dimen4\dimexpr\localheight/2+\strutdp-2\ruledlinewidth\relax
+ \dimen6\dimexpr\localheight/2-\strutdp+2\ruledlinewidth\relax
+ \else
+ \dimen4\dimexpr\strutht+\dimen2\relax
+ \dimen6\dimexpr\strutdp+\dimen2\relax
+ \fi
+ \unskip
+ \setbox\scratchbox\hbox
+ {\hskip\dimen2
+ \vrule\!!height\dimen4\!!depth\dimen6\!!width\ruledlinewidth
+ \hskip\dimen2}%
+ \ht\scratchbox\strutht
+ \dp\scratchbox\strutdp
+ \box\scratchbox
+ \ignorespaces
+ \egroup}
+
+%D The argument of the frame command accepts \type{\\} as a
+%D sort of newline signal. In horizontal boxes it expands to a
+%D space.
+
+\def\vboxednewline
+ {\endgraf\ignorespaces}
+
+\def\hboxednewline
+ {\unskip\normalspace\ignorespaces}
+
+%D We can set each rule on or off. The default setting is
+%D inherited from \type{frame}. An earlier implementation
+%D use a bit different approach, but the new one seems more
+%D natural:
+%D
+%D \bgroup
+%D \setuptyping[margin=0pt]
+%D \startlinecorrection
+%D \startbuffer
+%D \framed[offset=overlay,frame=on]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=off]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D
+%D \startbuffer
+%D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule}
+%D \stopbuffer
+%D \hbox{\getbuffer\vbox{\typebuffer}}
+%D \stoplinecorrection
+%D \egroup
+
+%D \macros
+%D {setupblackrules}
+%D
+%D The graphic capabilities of \TEX\ do not go beyond simple
+%D filled rules, except of course when using specials. Let's
+%D start with a warning: using this commands is far more slower
+%D than using the \TEX\ primitives \type{\hrule} and
+%D \type{\vrule}, but they save us some tokens. The
+%D characteristics of these rule drawing command can be set by:
+%D
+%D \showsetup{setupblackrules}
+
+\def\setupblackrules
+ {\dodoubleargument\getparameters[\??bj]}
+
+%D \macros
+%D {blackrule}
+%D
+%D The simple command draws only one rule. Its optional
+%D argument can be used to specify the dimensions. By setting
+%D the width, height or depth to \type {max}, one gets the
+%D natural dimensions.
+%D
+%D \showsetup{blackrule}
+
+\def\doblackrule[#1]%
+ {\hbox\bgroup
+ \getparameters[\??bj][#1]%
+ \setstrut
+ \doif\@@bjwidth \v!max{\def\@@bjwidth {1em}}%
+ \doif\@@bjheight\v!max{\def\@@bjheight{\strutht}}%
+ \doif\@@bjdepth \v!max{\def\@@bjdepth {\strutdp}}%
+ \localstartcolor[\@@bjcolor]%
+ \vrule
+ \!!width \@@bjwidth
+ \!!height\@@bjheight
+ \!!depth \@@bjdepth
+ \localstopcolor
+ \egroup}
+
+\unexpanded\def\blackrule
+ {\dosingleempty\doblackrule}
+
+%D \macros
+%D {blackrules}
+%D
+%D One can call for a sequence of black rules, if needed
+%D equally spaced over the given width.
+%D
+%D \showsetup{blackrules}
+%D
+%D The two alternative calls are therefore:
+%D
+%D \startbuffer
+%D Tell me, is this according to the \blackrules[n=6]?
+%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear.
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or:
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D We could of course have implemented this macro using
+%D \type{\leaders}, but this would probably have taken more
+%D tokens.
+
+\def\doblackrules[#1]%
+ {\hbox\bgroup
+ \getparameters[\??bj][#1]%
+ \!!widtha\@@bjwidth
+ \!!widthb\@@bjdistance
+ \doif\@@bjalternative\c!b
+ {\scratchcounter\@@bjn
+ \ifnum\scratchcounter=\plusone
+ \!!widthb\zeropoint
+ \else
+ \advance\scratchcounter \minusone
+ \advance\!!widtha -\scratchcounter\!!widthb
+ \divide \!!widtha \@@bjn
+ \fi}%
+ \localstartcolor[\@@bjcolor]%
+ \dorecurse\@@bjn
+ {\vrule
+ \!!width \!!widtha
+ \!!height\@@bjheight
+ \!!depth \@@bjdepth
+ \hskip\!!widthb}%
+ \unskip
+ \localstopcolor
+ \egroup}
+
+\unexpanded\def\blackrules
+ {\dosingleempty\doblackrules}
+
+%D The next commands can be used to draw margin rules. We
+%D support two methods: \marginrule{one for in||line use} and
+%D one that acts on a paragraph. Drawing a margin rule is
+%D rather straightforward because we can use the commands that
+%D put text in the margin.
+
+\def\dodrawmarginrule
+ {\setbox\scratchbox\hbox
+ {\vrule\!!depth\strutdepth\!!height\strutheight\!!width\@@karulethickness}%
+ \smashbox\scratchbox % no \vsmash !!!
+ \box\scratchbox}
+
+\def\drawmarginrule
+ {\strut\inleft{\dodrawmarginrule}}
+
+%D \macros
+%D {marginrule}
+%D
+%D The first method gobbles words and simply puts a bar in the
+%D margin. This method is not entirely robust.
+%D
+%D \showsetup{marginrule}
+
+\definecomplexorsimple\marginrule
+
+\def\simplemarginrule
+ {\let\processword\drawmarginrule
+ \processwords}
+
+\def\complexmarginrule[#1]%
+ {\ifnum#1<\@@kalevel\relax \else
+ \def\@@kadefaultwidth{#1}%
+ \expandafter\simplemarginrule
+ \fi}
+
+%D We need an auxiliary variable
+
+\def\@@kadefaultwidth{1}
+
+%D \macros
+%D {setupmarginrules}
+%D
+%D This macro definitions show us that we can pass an optional
+%D level, which is matched against the previous set one. The
+%D level can be set up with
+%D
+%D \showsetup{setupmarginrules}
+
+\def\setupmarginrules
+ {\dodoubleargument\getparameters[\??ka]}
+
+%D \macros
+%D {startmarginrule}
+%D
+%D The second method collects text and reformats it afterwards,
+%D using the shapebox macros. We prevent local margin rules.
+%D
+%D \showsetup{startmarginrule}
+
+\definecomplexorsimple\startmarginrule
+
+\def\simplestartmarginrule
+ {\bgroup
+ \let\drawmarginrule\relax
+ \let\stopmarginrule\dostopmarginrule
+ \beginofshapebox}
+
+\def\complexstartmarginrule[#1]%
+ {\bgroup
+ \let\drawmarginrule\relax
+ \ifnum#1<\@@kalevel\relax
+ \let\stopmarginrule\egroup
+ \else
+ \def\@@kadefaultwidth{#1}%
+ \let\stopmarginrule\dostopmarginrule
+ \expandafter\beginofshapebox
+ \fi}
+
+\def\dostopmarginrule
+ {\endofshapebox
+ \reshapebox
+ {\hbox{\inleftmargin{\dodrawmarginrule}\box\shapebox}}%
+ \flushshapebox
+ \egroup}
+
+%D \startbuffer
+%D \setupmarginrules[level=5]
+%D
+%D \startmarginrule[1]
+%D First we set the level at~5. Next we typeset this first
+%D paragraph as a level~1 one. As expected no rule show up.
+%D \stopmarginrule
+%D
+%D \startmarginrule[5]
+%D The second paragraph is a level~5 one. As we can see here,
+%D the marginal rule gets a width according to its level.
+%D \stopmarginrule
+%D
+%D \startmarginrule[8]
+%D It will of course be no surprise that this third paragraph
+%D has a even thicker margin rule. This behavior can be
+%D overruled by specifying the width explictly.
+%D \stopmarginrule
+%D \stopbuffer
+%D
+%D In next example we show most features. Watch the rule
+%D thickness adapting itself to the level.
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D We just said:
+%D
+%D \typebuffer
+
+%D \macros
+%D {vl, hl}
+%D
+%D The command \type{\vl} draws a vertical rule \vl\ with strut
+%D dimensions, multiplied with the factor specified in the
+%D optional argument. The height and depth are clipped \vl[3]
+%D to the baselinedistance. Its horizontal counterpart
+%D \type{\hl} draws a horizontal rule \hl\ with a width of 1em,
+%D multiplied with the optional factor. The horizontal rule is
+%D drawn on top of the baseline.
+%D
+%D \showsetup{vl}
+%D \showsetup{hl}
+
+\def\complexvl[#1]%
+ {\bgroup
+ \!!dimena#1\strutht
+ \!!dimenb#1\strutdp
+ \setbox\scratchbox\hbox
+ {\vrule
+ \!!width \linewidth
+ \!!height\!!dimena
+ \!!depth \!!dimenb}%
+ \dp\scratchbox\strutdp
+ \ht\scratchbox\strutht
+ \box\scratchbox
+ \egroup}
+
+\def\complexhl[#1]%
+ {\hbox
+ {\vrule
+ \!!width #1\s!em
+ \!!height\linewidth
+ \!!depth \zeropoint}}
+
+\definecomplexorsimple\vl \def\simplevl{\complexvl[1]}
+\definecomplexorsimple\hl \def\simplehl{\complexhl[1]}
+
+%D \macros
+%D {hairline, thinrule, thinrules, setupthinrules}
+%D
+%D Drawing thin lines can of course easily be accomplished by
+%D the \TEX\ primitives \type{\hrule} and \type{\vrule}. The
+%D next few macros however free us from some specifications.
+%D
+%D \startbuffer
+%D some text
+%D
+%D \hairline
+%D
+%D some more text
+%D
+%D \thinrule
+%D
+%D more and more text
+%D
+%D hi \thinrule\ there
+%D
+%D and then the final text
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D becomes
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D So we've got
+%D
+%D \showsetup{hairline}
+%D \showsetup{thinrule}
+%D
+%D Both can be set up with:
+%D
+%D \showsetup{setupthinrules}
+%D
+%D We also have
+%D
+%D \showsetup{thinrules}
+%D
+%D which looks like: \thinrules[n=2]
+
+\def\thinrule
+ {\strut
+ \bgroup
+ \chardef\ruletype\plusone
+ \processaction
+ [\@@dlalternative]
+ [ \v!a=>\chardef\ruletype0,% no line
+ %\v!b=>\chardef\ruletype1,% height/depth
+ \v!c=>\chardef\ruletype2,% topheight/botdepth
+ % 11=>\chardef\ruletype1,% fallback for backgrounds
+ 0=>\chardef\ruletype0,% compatible with backgrounds
+ % 1=>\chardef\ruletype1,% compatible with backgrounds
+ 2=>\chardef\ruletype2]% compatible with backgrounds
+ \doifsomething\@@dlrulethickness
+ {\linewidth\@@dlrulethickness}%
+ \ifdim\linewidth=\zeropoint
+ \chardef\ruletype\zerocount
+ \else
+ \doifnot\@@dlframe\v!on{\chardef\ruletype\zerocount}%
+ \fi
+ \ifnum\ruletype=\plusone
+ \doif\@@dlheight\v!max{\let\@@dlheight\!!plusone}%
+ \doif\@@dldepth \v!max{\let\@@dldepth \!!plusone}%
+ \else
+ \let\@@dlheight\!!plusone
+ \let\@@dldepth\!!plusone
+ \fi
+ \freezedimensionwithunit\@@dlheight\strutht
+ \freezedimensionwithunit\@@dldepth\strutdp
+ \divide\linewidth \plustwo
+ \doifelse\@@dlbackground\v!color
+ {\startcolor[\@@dlbackgroundcolor]%
+ \ifnum\ruletype=\plustwo % prevent overshoot due to rounding
+ \leaders
+ \hrule
+ \!!height\dimexpr\@@dlheight-.5\linewidth\relax
+ \!!depth \dimexpr\@@dldepth -.5\linewidth\relax
+ \hfill
+ \else
+ \leaders
+ \hrule
+ \!!height\@@dlheight
+ \!!depth \@@dldepth
+ \hfill
+ \fi
+ \stopcolor
+ \ifcase\ruletype
+ % no rule
+ \or
+ \startcolor[\@@dlcolor]%
+ \hfillneg
+ \leaders\hrule\!!height\linewidth\!!depth\linewidth\hfill
+ \stopcolor
+ \or
+ \startcolor[\@@dlcolor]%
+ \hfillneg\leaders\hrule\!!height\dimexpr-\@@dldepth+\linewidth\relax\!!depth\@@dldepth\hfill
+ \hfillneg\leaders\hrule\!!height\@@dlheight\!!depth\dimexpr-\@@dlheight+\linewidth\relax\hfill
+ \stopcolor
+ \fi}
+ {\ifcase\ruletype \else
+ \startcolor[\@@dlcolor]%
+ \leaders\hrule\!!height\@@dlheight\!!depth\@@dldepth\hfill
+ \stopcolor
+ \fi}%
+ \strut
+ \carryoverpar\egroup}
+
+\def\hairline
+ {\endgraf
+ \thinrule
+ \endgraf}
+
+\def\dosetupthinrules[#1]%
+ {\getparameters[\??dl][#1]}
+
+\def\setupthinrules
+ {\dosingleargument\dosetupthinrules}
+
+\def\dothinrules[#1]%
+ {\bgroup
+ \dosetupthinrules[#1]%
+ \@@dlbefore
+ \assignvalue\@@dlinterlinespace\@@dlinterlinespace{1.0}{1.5}{2.0}%
+ \spacing\@@dlinterlinespace
+ \dorecurse\@@dln
+ {\ifnum\recurselevel=\@@dln \dothinrulesnobreak \else
+ \ifnum\recurselevel=2 \dothinrulesnobreak \fi\fi
+ \thinrule
+ \ifnum\recurselevel<\@@dln\relax
+ % test needed, else messed up whitespace
+ \ifx\@@dlinbetween\empty
+ \softbreak
+ \else
+ \endgraf
+ \nowhitespace
+ \@@dlinbetween
+ \fi
+ \fi}%
+ \doifelsenothing\@@dlafter
+ {\carryoverpar\egroup}
+ {\@@dlafter\egroup}}
+
+\def\thinrules
+ {\dosingleempty\dothinrules}
+
+%D A couple of examples are given below.
+%D
+%D \startbuffer
+%D \setupthinrules[n=3,inbetween=,color=gray]
+%D
+%D test test \thinrules\ test test \par
+%D test test \thinrules [color=green] test test \par
+%D test test \thinrules [height=max, depth=max] test test \par
+%D
+%D \setupthinrules[height=.9,depth=.9]
+%D
+%D test test \thinrules\ test test \par
+%D test test \thinrules [alternativevariant=b] test test \par
+%D test test \thinrules [alternativevariant=c] test test \par
+%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par
+%D \stopbuffer
+%D
+%D \typebuffer {\getbuffer}
+%D
+%D There are a couple of alternative ways to visualize rules
+%D using backgrounds. At first sight these may look strange,
+%D but they make sense in educational settings. The
+%D alternatives are more or less compatible with the more
+%D advanced \METAPOST\ based implementation.
+%D
+%D \startbuffer[a]
+%D \setupthinrules
+%D [n=2,
+%D backgroundcolor=gray ,
+%D rulethickness=1pt,
+%D colorkleur=donkerblauw,
+%D after=\blank,
+%D before=\blank]
+%D \stopbuffer
+%D
+%D \typebuffer[a]
+%D
+%D \startbuffer[b]
+%D \thinrules[alternativevariant=a]
+%D \thinrules[alternativevariant=b]
+%D \thinrules[alternativevariant=c]
+%D \stopbuffer
+%D
+%D \typebuffer[b] \getbuffer[a,b]
+%D
+%D \startbuffer[b]
+%D \thinrules[alternativevariant=a,background=color]
+%D \thinrules[alternativevariant=b,background=color]
+%D \thinrules[alternativevariant=c,background=color]
+%D \stopbuffer
+%D
+%D \typebuffer[b] \getbuffer[a,b]
+%D
+%D \startbuffer[b]
+%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color]
+%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color]
+%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color]
+%D \stopbuffer
+%D
+%D \typebuffer[b] \getbuffer[a,b]
+
+%D \macros
+%D {optimizethinrules}
+%D
+%D By saying \type {\thinrulestrue} or \type {-false}, we
+%D can influence the way dangling lines are handled.
+
+\newif\ifoptimizethinrules \optimizethinrulestrue
+
+\def\dothinrulesnobreak
+ {\ifoptimizethinrules\penalty500\fi}
+
+%D \macros
+%D {startframedtext, setupframedtexts, defineframedtext}
+%D
+%D The general framing command we discussed previously, is not
+%D entirely suited for what we call framed texts, as for
+%D instance used in intermezzo's. The next examples show what
+%D we have in mind.
+%D
+%D \startbuffer[framed-0]
+%D \setupframedtexts
+%D [frame=off,
+%D width=\hsize,
+%D background=screen]
+%D
+%D \startframedtext
+%D By default the framed text is centered \dots
+%D \stopframedtext
+%D
+%D \startframedtext[right]
+%D \dots\ but we can also align left, middle and right.
+%D \stopframedtext
+%D \stopbuffer
+%D
+%D \startbuffer[framed-1]
+%D \defineframedtext
+%D [Example]
+%D [width=6cm,
+%D height=5cm]
+%D
+%D \startExample
+%D \typebuffer[framed-1]
+%D \stopExample
+%D \stopbuffer
+%D
+%D \startbuffer[framed-2]
+%D \defineframedtext
+%D [Example]
+%D [width=6cm]
+%D
+%D \startExample
+%D \typebuffer[framed-2]
+%D \stopExample
+%D \stopbuffer
+%D
+%D \startbuffer[framed-3]
+%D \defineframedtext
+%D [Example]
+%D [height=5cm]
+%D
+%D \startExample
+%D \typebuffer[framed-3]
+%D \stopExample
+%D \stopbuffer
+%D
+%D \startbuffer[framed-4]
+%D \defineframedtext
+%D [Example]
+%D [width=fit,height=broad]
+%D
+%D \Example{a very exciting example}
+%D \stopbuffer
+%D
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup
+%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup
+%D
+%D Here we can see that we have a predefined framed text class
+%D as well as the tools for defining our own. So we have:
+%D
+%D \showsetup{setupframedtexts}
+%D
+%D as well as the definition command:
+%D
+%D \showsetup{defineframedtext}
+%D
+%D that generates two commands:
+%D
+%D \showsetup{start<<framedtext>>}
+%D \showsetup{<<framedtext>>}
+%D
+%D The next definition shows the defaults.
+
+\def\dodefineframedtext[#1][#2]%
+ {\presetlocalframed[\??kd#1]%
+ \getparameters[\??kd#1]
+ [\c!width=0.75\hsize,
+ \c!height=\v!fit,
+ \c!align=\v!yes,
+ \c!top=,
+ \c!bottom=\vfill,
+ \c!offset=1em,
+ \c!bodyfont=,
+ \c!style=,
+ \c!color=,
+ \c!left=,
+ \c!right=\hfill,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!inner=,
+ \c!frame=\v!on,
+ \c!topframe=,
+ \c!bottomframe=,
+ \c!leftframe=,
+ \c!rightframe=,
+ \c!radius=.5\bodyfontsize,
+ \c!corner=\v!rectangular,
+ \c!foregroundcolor=,
+ \c!foregroundstyle=,
+ \c!background=,
+ \c!backgroundcolor=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!linecorrection=\v!on,
+ \c!depthcorrection=\v!on,
+ \c!margin=\v!standard,
+ \c!orientation=,
+ \c!indenting=,
+ #2]%
+ \setvalue{\e!start#1}{\dostartframedtext[#1]}%
+ \setvalue{\e!stop #1}{\dostopframedtext }%
+ \setvalue {#1}{\doframedtext [#1]}}
+
+\def\defineframedtext
+ {\dodoubleempty\dodefineframedtext}
+
+%D We define the general (and original) case by just saying:
+
+\defineframedtext[\v!framedtext]
+
+%D We need several steps before the actual job is done,
+%D because we have to handle an optional identifier (and
+%D because these commands evolved out of a single case).
+
+\def\framedtextparameter#1#2%
+ {\csname\??kd#1#2\endcsname}
+
+\def\dosetupframedtexts[#1][#2]%
+ {\ifsecondargument
+ \def\docommand##1{\getparameters[\??kd##1][#2]}%
+ \processcommacommand[#1]\docommand % new, #1 may be macro
+ \else
+ \getparameters[\??kd\v!framedtext][#1]%
+ \fi}
+
+\def\setupframedtexts
+ {\dodoubleempty\dosetupframedtexts}
+
+\def\dostartframedtext
+ {\bgroup\dotripleempty\dodostartframedtext}
+
+\def\dodostartframedtext[#1][#2][#3]%
+ {\doifassignmentelse{#2}
+ {\dododostartframedtext[#1][][#2]}
+ {\dododostartframedtext[#1][#2][#3]}}
+
+\setfalse\framedtextlocationnone
+
+\def\dododostartframedtext[#1][#2][#3]% #3 only passed to framed, not to framedtext
+ {\doifsomething{#2}{\setvalue{\??kd#1\c!location}{#2}}% does not listen to #3
+ \setfalse\framedtextlocationnone
+ \processaction % \v!low en \v!depth are already taken !
+ [\framedtextparameter{#1}\c!location]
+ [ \v!left=>\letvalue{\??kd#1\c!left }\relax
+ \letvalue{\??kd#1\c!right}\hfill,
+ \v!right=>\letvalue{\??kd#1\c!left }\hfill
+ \letvalue{\??kd#1\c!right}\relax,
+ \v!middle=>\letvalue{\??kd#1\c!left }\hfill
+ \letvalue{\??kd#1\c!right}\hfill,
+ \v!none=>\letvalue{\??kd#1\c!left }\relax % new
+ \letvalue{\??kd#1\c!right}\relax % new
+ \settrue\framedtextlocationnone]%
+ \letvalue{\??kd#1\c!location}\empty
+ % removed 06/2001
+ % \forgetparindent
+ % added 06/2001 [see demo-bbv]
+ \localhsize\hsize \checkframedtext
+ % so far
+ \setbox\framebox\vbox
+ \startboxedcontent
+ \hsize\localhsize
+ % \insidefloattrue % ? better
+ \normalexpanded{\noexpand\switchtobodyfont[\framedtextparameter{#1}\c!bodyfont]}%
+ \startcolor[\framedtextparameter{#1}\c!color]%
+ \localframed[\??kd#1][\c!strut=\v!no,#3]% todo: use delayedstrut
+ \bgroup
+ \let\\=\endgraf
+ \framedtextparameter{#1}\c!inner % oud spul
+ \doifvalue{\??kd#1\c!depthcorrection}\v!on % new, inside box
+ {\bgroup
+ \verticalstrut
+ % we need \nowhitespace in case of setups setting whitespace
+ % nb, not safe, text vs \vbox as next
+ \vskip-\struttotal
+ \nowhitespace % na vskip ! new 20/05/2004, fails with next content being box (\scale{..})
+ }%
+ \doinhibitblank % \blank[\v!disable]% plaatst signal
+\setupindenting[\framedtextparameter{#1}\c!indenting]%
+ \doconvertfont{\framedtextparameter{#1}\c!style}\empty
+ \def\dostopframedtext{\dodostopframedtext{#1}{#2}}}
+
+%D The \type {none} option is handy for nested usage, as
+%D in the presentation styles, where we don't want
+%D interference.
+
+\def\dodostopframedtext#1#2% % no \baselinecorrection, see faq docs
+ {\endgraf
+ \removelastskip
+ \doifvalue{\??kd#1\c!depthcorrection}\v!on % local and global
+ {\forgetall
+ \vskip-\struttotal
+ \verticalstrut
+ \egroup
+ \forgetall
+ \vskip-\lineheight
+ % will be an option, not default
+ % \setbaselinecorrections
+ % \donegbotbaselinecorrection
+ \verticalstrut}
+ \stopboxedcontent
+ \stopcolor
+ \ifconditional\framedtextlocationnone
+ \egroup
+ \box\framebox
+ \else\ifinsidefloat
+ \egroup
+ \box\framebox
+ \else
+ \egroup
+ \doplacement[\??kd#1][\c!depthcorrection=\v!off]{\box\framebox}%
+ \fi\fi
+ \egroup}
+
+%D Placement can be ignored:
+%D
+%D \starttyping
+%D \hbox to \hsize \bgroup
+%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext
+%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext
+%D \egroup
+%D
+%D \hbox to \hsize \bgroup
+%D \setupframedtexts[location=none]%
+%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext
+%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext
+%D \egroup
+%D \stoptyping
+
+%D The simple brace (or group) delimited case is typeset
+%D slightly different and is not aligned.
+
+\def\doframedtext
+ {\bgroup\dodoubleempty\dodoframedtext}
+
+\def\dodoframedtext[#1][#2]% beware!
+ {\normalexpanded{\noexpand\switchtobodyfont[\getvalue{\??kd#1\c!bodyfont}]}%
+ \localframed[\??kd#1][\c!strut=\v!no,#2]%
+ \bgroup
+ \blank[\v!disable]%
+ \let\\=\endgraf
+ \getvalue{\??kd#1\c!inner}% % kleur naar outer level
+ \dostartattributes{\??kd#1}\c!style\c!color\empty
+ \bgroup
+ \aftergroup\docloseframedtext
+ \let\next=}
+
+\def\docloseframedtext
+ {\removelastskip
+ \dostopattributes
+ \egroup
+ \egroup}
+
+%D \macros
+%D {defineframed}
+%D
+%D One can also define simple framed texts, using:
+%D
+%D \showsetup{defineframed}
+
+\def\defineframed
+ {\dodoubleempty\dodefineframed}
+
+\def\dodefineframed[#1][#2]%
+ {\iffirstargument
+ \setvalue{#1}{\dodoubleempty\doframed[#2]}%
+ \fi}
+
+\def\doframed[#1][#2]%
+ {\framed[#1,#2]}
+
+%D \macros
+%D {textrule, starttextrule, setuptextrules}
+%D
+%D Putting rules before and after a paragraph is very space
+%D sensitive, but the next command handles that quite well. It
+%D comes in two disguises:
+%D
+%D \startbuffer
+%D \textrule[top]{fragments}
+%D \input reich
+%D \textrule
+%D \stopbuffer
+%D
+%D \bgroup \typebuffer \getbuffer \egroup
+%D
+%D \startbuffer
+%D \setuptextrules
+%D [width=90pt,distance=12pt,rulecolor=blue,
+%D bodyfont=small,style=\sc,color=red]
+%D
+%D \starttextrule{Ship Building Tools}
+%D \nl \setuptolerance[tolerant] \input materie
+%D \stoptextrule
+%D \stopbuffer
+%D
+%D \bgroup \typebuffer \getbuffer \egroup
+%D
+%D \startbuffer
+%D \setuptextrules
+%D [location=inmargin,
+%D bodyfont=small,style=slantedbold]
+%D
+%D \starttextrule{wonderful}
+%D \input tufte
+%D \stoptextrule
+%D \stopbuffer
+%D
+%D \bgroup \typebuffer \getbuffer \egroup
+%D
+%D The formal definition of these commands is:
+%D
+%D \showsetup{textrule}
+%D \showsetup{starttextrule}
+%D \showsetup{setuptextrules}
+%D
+%D The implementation looks a bit complicated due to the
+%D optional arguments.
+
+\def\setuptextrules
+ {\dodoubleargument\getparameters[\??tl]}
+
+\def\complextextrule[#1]% if needed we can make it installable
+ {\let\next\dobottomtextrule
+ \processaction
+ [#1]
+ [ \v!top=>\let\next\dotoptextrule,
+ \v!middle=>\let\next\domiddletextrule,
+ \v!bottom=>\let\next\dobottomtextrule]%
+ \dosinglegroupempty\next}
+
+\definecomplexorsimple\textrule
+
+\def\simpletextrule
+ {\dosinglegroupempty\dounknowntextrule}
+
+\def\docomplextextrule#1%
+ {\bgroup
+ \advance\hsize\dimexpr-\rightskip-\leftskip\relax
+ \setbox\scratchbox\hbox to \hsize
+ {\dimen4\dimexpr .5ex+.5\linewidth\relax
+ \dimen6\dimexpr-.5ex+.5\linewidth\relax
+ \doifnothing{#1}\firstargumentfalse
+ \iffirstargument
+ \doifelse\@@tllocation\v!inmargin
+ {\llap{\doattributes\??tl\c!style\c!color{#1}\hskip\leftmargindistance}}
+ {\color[\@@tlrulecolor]
+ {\vrule\!!height\dimen4\!!depth\dimen6\!!width\@@tlwidth}%
+ \hbox spread 2\dimexpr\@@tldistance\relax
+ {\hss\doattributes\??tl\c!style\c!color{\strut#1}\hss}}%
+ \fi
+ \color[\@@tlrulecolor]
+ {\leaders\hrule\!!height\dimen4\!!depth\dimen6\hfill}}%
+ \ht\scratchbox\strutht
+ \dp\scratchbox\strutdp
+ \noindent\box\scratchbox
+%\nobreak\verticalstrut\kern-\struttotal
+% evt \witruimte
+ \egroup}
+
+\def\dotoptextrule#1%
+ {\page[\v!preference] % interferes
+ %\whitespace % no
+ \@@tlbefore
+ \docomplextextrule{#1}%
+% todo, option: \doifnothing{#1}{\ruledvskip-.5ex}
+ \nowhitespace
+ \@@tlinbetween
+ \endgraf}
+
+\def\dodobottomtextrule#1#2%
+ {\ifhmode
+ \endgraf
+ \fi
+ \dimen0\strutdp
+ \ifdim\prevdepth>\strutdp\else % was <\strutdp
+ \ifdim\prevdepth>\zeropoint
+ \advance\dimen0 -\prevdepth
+ \fi
+ \fi
+ \advance\dimen0 .5ex
+ \vskip\dimen0
+% ==
+% \vskip\dimexpr \strutdp + .5ex
+% \ifdim\prevdepth>\strutdp\else\ifdim\prevdepth>\zeropoint-\prevdepth\fi\fi\relax
+%
+ \@@tlinbetween
+ \doifelsenothing{#2}
+ {\bgroup
+ \advance\hsize\dimexpr-\rightskip-\leftskip\relax
+ \nointerlineskip
+ \moveleft-\leftskip\vbox
+ {\color[\@@tlrulecolor]
+ {\hrule\!!depth\linewidth\!!height\zeropoint\!!width\hsize}}%
+ \egroup}
+ {\docomplextextrule{#2}}%
+ \ifvmode\prevdepth\zeropoint\fi
+ #1%
+ \page[\v!preference]}
+
+\def\dobottomtextrule
+ {\dodobottomtextrule\@@tlafter}
+
+\def\domiddletextrule
+ {\dodobottomtextrule\@@tlinbetween}
+
+\def\dounknowntextrule
+ {\iffirstargument
+ \@EA\dotoptextrule
+ \else
+ \@EA\dobottomtextrule\@EA\empty
+ \fi}
+
+%D The grouped commands also supports bodyfont switching:
+
+\def\starttextrule#1%
+ {\bgroup
+ \def\dounknowntextrule{\domiddletextrule}
+ \dotoptextrule{#1}
+ \bgroup
+ \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}}
+
+\def\stoptextrule
+ {\par
+ \egroup
+ \dobottomtextrule\empty
+ \egroup}
+
+%D \macros
+%D {fillinrules, setupfillinrules}
+%D
+%D The next few commands do not really deserve a place in a
+%D core module, because they deal with specific typography.
+%D Nevertheless I decided to make them part of the core,
+%D because they permit us to make questionaires. Let's start
+%D with some examples.
+%D
+%D \fillinrules[n=2,width=fit]{first}
+%D \fillinrules[n=2,width=broad]{first}
+%D \fillinrules[n=2,width=3cm]{first}
+%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first}
+%D \fillinrules[n=2]{first}{last}
+%D \fillintext{first}{last} \input reich \par
+%D
+%D The main command is \type{\fillinrules}. This command takes
+%D one and an optional second argument and sets a paragraph with
+%D empty visualized lines.
+%D
+%D \showsetup{fillinrules}
+%D \showsetup{setupfillinrules}
+
+\def\setupfillinrules
+ {\dodoubleargument\getparameters[\??il]}
+
+\definecomplexorsimpleempty\fillinrules
+
+\def\complexfillinrules[#1]%
+ {\def\docomplexfillinrules##1##2%
+ {\dodocomplexfillinrules[#1]{##1}{##2}{\thinrules
+ [\c!n=\@@iln,\c!interlinespace=\@@ilinterlinespace,\c!before=,\c!after=]}}%
+ \dodoublegroupempty\docomplexfillinrules}
+
+\def\dodocomplexfillinrules[#1]#2#3#4%
+ {\endgraf
+ \@@ilbefore
+ \begingroup
+ \setupfillinrules[#1]%
+ \noindent
+ \doifsomething{#2}
+ {\doifelse\@@ilwidth\v!fit
+ {\let\@@ildistance\!!zeropoint
+ \hbox}
+ {\doifelse\@@ilwidth\v!broad
+ {\hbox}
+ {\hbox to \@@ilwidth}}%
+ \bgroup
+ \doattributes\??il\c!style\c!color{\strut#2\hfill\@@ilseparator}%
+ \hskip\@@ildistance
+ \egroup}%
+ %\hangindent=\wd0\relax % tzt hang=yes,n
+ %\parindent=\hangindent
+ %\box0\relax
+ \setupwhitespace[\v!big]%
+ \ignorespaces
+ #4%
+ \doifsomething{#3}
+ {\kern\@@ildistance
+ \doattributes\??il\c!style\c!color{#3\strut}}%
+ \endgroup
+ \endgraf
+ \@@ilafter}
+
+%D \macros
+%D {fillintext}
+%D
+%D To provide compatible layouts when texts and lines are
+%D mixed, one can typeset a paragraph by using the command
+%D \type{\fillintext}.
+%D
+%D \showsetup{fillintext}
+
+\definecomplexorsimpleempty\fillintext
+
+\def\complexfillintext[#1]% rather rough, using an \unhbox is suboptimal
+ {\def\docomplexfillintext##1##2%
+ {\dowithnextbox
+ {\dodocomplexfillinrules[#1]{##1}{\hfill##2}{\unhbox\nextbox\unskip}}%
+ \hbox\bgroup\let\par\egroup\ignorespaces}%
+ \dodoublegroupempty\docomplexfillintext}
+
+%D \macros
+%D {fillinline, setupfillinlines}
+%D
+%D Another member of the family takes care of putting a (often
+%D small) rule after a piece of text, like
+%D
+%D \startbuffer
+%D \fillinline \input reich \par
+%D \fillinline[margin=0cm] \input reich \par
+%D \stopbuffer
+%D
+%D \startvoorbeeld
+%D \getbuffer
+%D \stopvoorbeeld
+%D
+%D which was typeset by saying:
+%D
+%D \typebuffer
+%D
+%D The two commands that take care of this are:
+%D
+%D \showsetup{fillinline}
+%D \showsetup{setupfillinlines}
+
+\def\setupfillinlines
+ {\dodoubleargument\getparameters[\??iv]}
+
+\definecomplexorsimpleempty\fillinline
+
+\def\complexfillinline[#1]%
+ {%\endgraf % interferes with \definedescription cum suis
+ \@@ivbefore
+ \begingroup
+ \setupfillinlines[#1]%
+ \advance\rightskip \@@ivmargin
+ \parfillskip\zeropoint
+ \def\par % very dangerous
+ {\let\par\endgraf % -)
+ \ifhmode\unskip\hfill\fi
+ \scratchdimen\dimexpr\@@ivwidth-\@@ivdistance\relax
+ \ifdim\scratchdimen>\@@ivmargin\else\expandafter\rlap\fi
+ {\kern\@@ivdistance
+ \vrule
+ \!!width \scratchdimen
+ \!!height.5\linewidth
+ \!!depth .5\linewidth}%
+ \endgraf % !
+ \endgroup
+ \endgraf % !
+ \@@ilafter}}
+
+%D \stopdocumentation
+%D \bgroup
+%D
+%D \setupframedtexts
+%D [setuptext]
+%D [background=color,backgroundcolor=white]
+%D
+%D \startbuffer
+%D \setupbackground
+%D [backgroundoffset=4pt,
+%D background=screen,
+%D frame=on,
+%D framecolor=red,
+%D leftoffset=2pt]
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \startbackground
+%D
+%D \macros
+%D {setupbackground,startbackground,background}
+%D
+%D The section deals with backgrounds in the running text. This
+%D means that texts is to be collected and split over pages. To
+%D show what can be done, we provide this part of the
+%D documentation with some gray background and a red frame.
+%D Both the background and frame can have all characteristics
+%D of \type{\framed}. This time we used the setting:
+%D
+%D \typebuffer
+%D
+%D The implementation is not that sophisticated, but suffices.
+%D The main problem with this kind of functionality is to get
+%D the spacing all right.
+
+%D Specifying the background is more or less the same as
+%D specifying a framed box.
+%D
+%D \showsetup{setupbackground}
+
+\presetlocalframed[\??ag]
+
+\def\dosetupbackground[#1]%
+ {\getparameters[\??ag][#1]%
+ \doifelse\@@agstate\v!start
+ {\let\startbackground\dostartbackground
+ \let\stopbackground \dostopbackground
+ \let\background \dobackground}
+ {\let\startbackground\relax
+ \let\stopbackground \relax
+ \let\background \relax}}
+
+\def\setupbackground
+ {\dosingleargument\dosetupbackground}
+
+%D Actually typesetting the background is implemented rather
+%D straightforward. We need to handle some spacing as well as
+%D the (often) a bit smaller horizontal size.
+%D
+%D \showsetup{startbackground}
+%D
+%D Although we could have used a scratch one, we first
+%D declare a boolean.
+
+% 0=no-split, 1=no-split+indent, 2=split, 3=split+indent
+
+\chardef\backgroundsplitmode\plusthree
+
+%D The \type{\vbox to \lineheight{}\vskip\zeropoint}
+%D construction gives the first real line a decent height by
+%D adding a dummy line.
+
+\def\dostartbackground
+ {\endgraf
+ \bgroup
+ \setbox0\vbox\bgroup
+ \vbox to \lineheight{}\vskip\zeropoint
+ \blank[\v!disable]
+ % \advance\hsize -\@@agleftoffset
+ % \advance\hsize -\@@agrightoffset
+ \leftskip \@@agleftoffset % new **
+ \rightskip\@@agrightoffset} % new **
+
+%D This dummy line is removed by \type{\setbox2=\vsplit0 to
+%D \lineheight}. That way \type{\topskip} takes care of the
+%D lineheight. I'll probably forget to apply this trick
+%D elsewhere.
+
+\def\dostopbackground % improved version (i hope)
+ {\endgraf
+ \removelastskip
+ \egroup
+ \dimen2\leftskip % new **
+ \forgetall
+ \ifinsidefloat
+ \chardef\backgroundsplitmode\zerocount
+ \fi
+ \ifcase\backgroundsplitmode
+ \localframed[\??ag][\c!offset=\v!overlay]{\box0}%
+ \or
+ \hskip\dimen2
+ \localframed[\??ag][\c!offset=\v!overlay]{\box0}%
+ \else
+ \splitmaxdepth\boxmaxdepth
+ \splittopskip\topskip
+ \setbox2\vsplit0 to \lineheight % get rid of fake line
+ \loop
+ \ifdim\pagetotal=\zeropoint % empty page
+ \scratchdimen\textheight
+ \chardef\backgroundsplit\plusone % split to max height
+ \else
+ \setbox\scratchbox\vbox{\@@agbefore}%
+ \scratchdimen\dimexpr\pagegoal-\ht\scratchbox-\pagetotal\relax
+ \chardef\backgroundsplit\plustwo % split to partial height
+ \fi
+ \advance\scratchdimen\dimexpr-\@@agtopoffset-\@@agbottomoffset\relax
+ \ifdim\scratchdimen>2\lineheight\relax % reasonable, will be configurable
+ \ifdim\ht0>\scratchdimen % larger than page
+ \setbox2\vsplit0 to \scratchdimen
+ \else
+ \setbox2\box0
+ \chardef\backgroundsplit\zerocount % no split
+ \fi
+ \setbox2\vbox \ifcase\backgroundsplit\or to \textheight \fi % max split
+ {\vskip\@@agtopoffset
+ \popsplitproperties
+ \unvcopy2
+ \prevdepth\dp2
+ \obeydepth
+ \vskip\@@agbottomoffset
+ \vfill}
+ \@@agbefore
+ \ifcase\backgroundsplit\or\or % partial split
+ \ifdim\pagegoal<\maxdimen
+ \pagegoal=1.2\pagegoal % be a bit more tolerant
+ \fi
+ \fi
+ \startlinecorrection
+ %\localframed[\??ag][\c!offset=\v!overlay]{\hskip\@@agleftoffset\box2\hskip\@@agrightoffset}%
+ \ifnum\backgroundsplitmode=\plusthree \hskip\dimen2 \fi %
+ \localframed[\??ag][\c!offset=\v!overlay]{\box2}% new **
+ \stoplinecorrection
+ \ifcase\backgroundsplit % no split
+ \@@agafter
+ \else % some split
+ \vfill\eject % geen \page !
+ \fi
+ \else
+ \page
+ \fi
+ \ifdim\ht0>\zeropoint \repeat
+ \fi
+ \egroup
+ \endgraf}
+
+%D As a bonus we also have a short command, that is of not
+%D much use, but kept there for historic reasons.
+%D
+%D \showsetup{background}
+
+\def\dobackground
+ {\bgroup
+ \dowithnextbox
+ {\localframed[\??ag][\c!offset=\v!overlay]{\flushnextbox}\egroup}
+ \vbox}
+
+%D \stopdocumentation
+%D \stopbackground
+%D \egroup
+
+%D New, for the moment private; let's see when GB finds out
+%D about this one and its obscure usage. It's used in:
+%D
+%D \startbuffer
+%D \defineframedtext
+%D [tabulateframe]
+%D [offset=overlay,
+%D backgroundoffset=3pt,
+%D background=color,
+%D backgroundcolor=green]
+%D
+%D \setuptabulate
+%D [tabulate]
+%D [frame=tabulateframe]
+%D
+%D \setuptables
+%D [frame=tabulateframe]
+%D
+%D \input tufte
+%D
+%D \starttabulate[|l|l|]
+%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
+%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
+%D \stoptabulate
+%D
+%D \input tufte
+%D
+%D \starttable[|l|l|]
+%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
+%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
+%D \stoptable
+%D \stopbuffer
+%D
+%D \typebuffer
+
+\def\defineframedcontent
+ {\dodoubleempty\dodefineframedcontent}
+
+\def\dodefineframedcontent[#1][#2]%
+ {\presetlocalframed[\??fc#1]%
+ \getparameters[\??fc#1]
+ [\c!leftoffset=\zeropoint,
+ \c!rightoffset=\getvalue{\??fc#1\c!leftoffset},
+ \c!topoffset=\zeropoint,
+ \c!bottomoffset=\getvalue{\??fc#1\c!topoffset},
+ \c!strut=\v!no,
+ \c!offset=\v!overlay,
+ \c!linecorrection=\v!no,
+ \c!left=,
+ \c!right=,
+ #2]}
+
+\let\setuplocalframed\getparameters
+
+\def\setupframedcontent
+ {\dodoubleempty\dosetupframedcontent}
+
+\def\dosetupframedcontent[#1][#2]%
+ {\def\docommand##1{\getparameters[\??fc##1][#2]}%
+ \processcommacommand[#1]\docommand}
+
+\def\startframedcontent[#1]%
+ {\bgroup
+ \let\stopframedcontent\egroup
+ \doifnot{#1}\v!off
+ {\doifdefined{\??fc#1\c!frame}
+ {\def\stopframedcontent{\dostopframedcontent{#1}}%
+ \dostartframedcontent{#1}}}}
+
+\def\dostartframedcontent#1%
+ {\setbox\framebox\hbox\bgroup
+ \setlocalhsize
+ \hsize\localhsize
+ \advance\hsize\dimexpr-\getvalue{\??fc#1\c!leftoffset}-\getvalue{\??fc#1\c!rightoffset} \relax
+ \advance\vsize\dimexpr-\getvalue{\??fc#1\c!topoffset} -\getvalue{\??fc#1\c!bottomoffset}\relax
+ \hskip\getvalue{\??fc#1\c!leftoffset}%
+ \vbox\bgroup
+ \vskip\getvalue{\??fc#1\c!topoffset}%
+ \vbox\bgroup
+ \forgetall
+ \blank[\v!disable]}
+
+\def\dostopframedcontent#1%
+ {\removelastskip
+ \egroup
+ \vskip\getvalue{\??fc#1\c!bottomoffset}%
+ \egroup
+ \hskip\getvalue{\??fc#1\c!rightoffset}%
+ \egroup
+ \doifvalue{\??fc#1\c!width}\v!fit
+ {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox
+ \ifinsidefloat
+ \donefalse
+ \else
+ \doifelsevalue{\??fc#1\c!linecorrection}\v!yes\donetrue\donefalse
+ \fi
+ % plaats ?
+ \ifdone\startlinecorrection\fi
+ \getvalue{\??fc#1\c!left}% new
+ \localframed[\??fc#1]{\box\framebox}%
+ \getvalue{\??fc#1\c!right}% new
+ \ifdone\stoplinecorrection\fi
+ \egroup}
+
+%D \macros
+%D {backgroundline}
+%D
+%D For the moment an undocumented feature, but a cancidate
+%D for going public.
+
+\def\backgroundline[#1]%
+ %{\doifsomething{#1}{\dobackgroundline{#1}}\hbox}
+ {\doifcolorelse{#1}{\dobackgroundline{#1}\hbox}\hbox}
+
+% \def\backgroundline[#1]%
+% {\doifcolor{#1}{\dobackgroundline{#1}}\hbox}
+
+\def\dobackgroundline#1%
+ {\dowithnextbox
+ {\hbox
+ {\localcolortrue
+ \startcolor[#1]%
+ \vrule
+ \!!width \nextboxwd
+ \!!height\nextboxht
+ \!!depth \nextboxdp
+ \stopcolor
+ \hskip-\nextboxwd
+ \flushnextbox}}}
+
+%D \macros
+%D {encircled}
+%D
+%D Some not so robust left||overs (borrowed from Knuth,
+%D \TEX Book\ page 356):
+
+\def\encircled#1%
+ {{\ooalign{\hfil\raise0.07ex\hbox{{\tx#1}}\hfil\crcr\mathhexbox20D}}}
+
+\let\omcirkeld\encircled
+
+\setuplinewidth
+ [\v!medium]
+
+\setupframed
+ [\c!width=\v!fit,
+ \c!height=\v!broad,
+ \c!lines=,
+ \c!offset=0.25ex, % \defaultframeoffset
+ \c!empty=\v!no,
+ \c!frame=\v!on,
+ \c!topframe=,
+ \c!bottomframe=,
+ \c!leftframe=,
+ \c!rightframe=,
+ \c!radius=.5\bodyfontsize,
+ \c!rulethickness=\linewidth,
+ \c!corner=\v!rectangular,
+ \c!depth=\!!zeropoint,
+ \c!foregroundcolor=,
+ \c!foregroundstyle=,
+ \c!background=,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!backgroundcolor=,
+ \c!backgroundoffset=\!!zeropoint,
+ \c!framecolor=,
+ \c!frameoffset=\!!zeropoint,
+ \c!backgroundcorner=\framedparameter\c!corner,
+ \c!backgroundradius=\framedparameter\c!radius,
+ \c!backgrounddepth=\framedparameter\c!depth,
+ \c!framecorner=\framedparameter\c!corner,
+ \c!frameradius=\framedparameter\c!radius,
+ \c!framedepth=\framedparameter\c!depth,
+ \c!component=,
+ \c!align=,
+ \c!bottom=\vss,
+ \c!top=,
+ \c!strut=\v!yes,
+ \c!autostrut=\v!yes,
+ \c!location=\v!normal,
+ \c!orientation=,
+ \c!autowidth=\v!yes,
+ \c!setups=]
+
+\setupscreens
+ [%\c!factor=1.0, % obsolete
+ %\c!method=\v!external, % obsolete
+ \c!screen=0.95]
+
+\setupblackrules
+ [\c!n=3,
+ \c!width=1em,
+ \c!height=1ex,
+ \c!depth=\!!zeropoint,
+ \c!alternative=\c!a,
+ \c!distance=.25ex,
+ \c!color=]
+
+\setupmarginrules
+ [\c!level=0,
+ \c!rulethickness=\@@kadefaultwidth\linewidth]
+
+\setupthinrules
+ [\c!interlinespace=\v!small,
+ \c!n=3,
+ \c!before=,
+ \c!inbetween={\blank[\v!white]},
+ \c!after=,
+ \c!color=,
+ \c!height=.5\linewidth,
+ \c!depth=.5\linewidth,
+ \c!frame=\v!on, % compatible with textbackgrounds
+ \c!alternative=\v!b,
+ \c!backgroundcolor=,
+ \c!background=,
+ \c!rulethickness=]
+
+\setuptextrules
+ [\c!location=\v!left,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!inbetween=,
+ \c!width=2em,
+ \c!style=\v!bold,
+ \c!color=,
+ \c!rulecolor=,
+ \c!bodyfont=,
+ \c!distance=.5em]
+
+\setupfillinrules
+ [\c!width=\v!broad,
+ \c!distance=1em,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!n=1,
+ \c!interlinespace=\v!small,
+ \c!separator=,
+ \c!style=\v!normal,
+ \c!color=]
+
+\setupfillinlines
+ [\c!width=3cm,
+ \c!margin=\@@ivwidth,
+ \c!distance=1em,
+ \c!before=\blank,
+ \c!after=\blank]
+
+\setupbackground
+ [\c!leftoffset=.5\bodyfontsize,
+ \c!rightoffset=\@@agleftoffset,
+ \c!topoffset=\!!zeropoint,
+ \c!bottomoffset=\@@agtopoffset,
+ \c!state=\v!start,
+ \c!radius=.5\bodyfontsize,
+ \c!corner=\v!rectangular,
+ \c!frame=\v!off,
+ \c!color=,
+ \c!depth=\!!zeropoint,
+ \c!background=\v!screen,
+ \c!backgroundcolor=\@@agcolor,
+ \c!screen=\@@rsscreen,
+ \c!before=,
+ \c!after=]
+
+% Experimental extension:
+
+\def\c!loffset{loffset}
+\def\c!roffset{roffset}
+\def\c!toffset{toffset}
+\def\c!boffset{boffset}
+
+\getparameters
+ [\??oi]
+ [\c!loffset=\zeropoint,
+ \c!roffset=\zeropoint,
+ \c!toffset=\zeropoint,
+ \c!boffset=\zeropoint]
+
+\newdimen\!!framedloffset
+\newdimen\!!framedroffset
+\newdimen\!!framedtoffset
+\newdimen\!!framedboffset
+
+\def\setextraframedoffsets
+ {\boxhasextraoffsetfalse
+ \!!framedloffset\framedparameter\c!loffset
+ \!!framedroffset\framedparameter\c!roffset
+ \!!framedtoffset\framedparameter\c!toffset
+ \!!framedboffset\framedparameter\c!boffset
+ \ifzeropt\!!framedloffset\else \advance\!!framedwidth -\!!framedloffset \boxhasextraoffsettrue \fi
+ \ifzeropt\!!framedroffset\else \advance\!!framedwidth -\!!framedroffset \boxhasextraoffsettrue \fi
+ \ifzeropt\!!framedtoffset\else \advance\!!framedheight-\!!framedtoffset \boxhasextraoffsettrue \fi
+ \ifzeropt\!!framedboffset\else \advance\!!framedheight-\!!framedboffset \boxhasextraoffsettrue \fi}
+
+\def\applyextraframedoffsets
+ {\setbox\framebox\vbox\bgroup
+ \vskip\!!framedtoffset
+ \hbox\bgroup
+ \hskip\!!framedloffset
+ \box\framebox
+ \hskip\!!framedroffset
+ \egroup
+ \vskip\!!framedboffset
+ \egroup}
+
\protect \endinput
diff --git a/tex/context/base/core-rul.tex b/tex/context/base/core-rul.tex
deleted file mode 100644
index f9386d560..000000000
--- a/tex/context/base/core-rul.tex
+++ /dev/null
@@ -1,3590 +0,0 @@
-%D \module
-%D [ file=core-rul,
-%D version=1998.10.16,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Ruled Stuff Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Ruled Content Handling}
-
-\loadmarkfile{core-rul}
-
-\unprotect
-
-%D We have removed the rather old and out dated raster methods. They
-%D have not been used for ages.
-
-%D \macros
-%D {linewidth, setuplinewidth}
-%D
-%D This module deals with rules (lines) in several ways. First
-%D we introduce two macros that can be used to set some common
-%D characteristics.
-%D
-%D \showsetup{setuplinewidth}
-%D
-%D The linewidth is available in \type{\linewidth}. The
-%D preset value of .4pt equals the default hard coded \TEX\
-%D rule width.
-
-\newdimen\linewidth
-
-\def\dosetuplinewidth[#1]%
- {\assigndimension{#1}\linewidth{.2\points}{.4\points}{.6\points}}
-
-\def\setuplinewidth
- {\dosingleargument\dosetuplinewidth}
-
-%D \macros
-%D {ruledlinewidth, inheritruledlinewidth}
-%D
-%D Inside framed boxed we will use a private dimensions. As
-%D an option one can let the linewidth inherit its value from
-%D this one.
-
-\newdimen\ruledlinewidth \newif\ifinheritruledlinewidth
-
-% %D \TEX\ lacks support for color and even gray scales. The next
-% %D macros can provide a sort of poor mans gray scales as well
-% %D as give access to more suitable methods of rendering. Such a
-% %D method looks like:
-% %D
-% %D \starttyping
-% %D \def\methodegraybox#1#2#3#4#5#6%
-% %D { ... }
-% %D \stoptyping
-% %D
-% %D The string \type{graybox} is a common element in the name,
-% %D so we can have for instance \type {\postscriptgraybox} or
-% %D \type {\texgraybox}. The first three arguments take a
-% %D dimension, the fourth one takes a number between~0 and~1,
-% %D and the last argument specifies a radius of the box when
-% %D rounded corners are used, so:
-% %D
-% %D \startbuffer
-% %D \dotgraybox{.5\hsize}{1cm}{0cm}{.85}{\v!no}{0pt}
-% %D \stopbuffer
-% %D
-% %D \typebuffer
-% %D
-% %D becomes:
-% %D
-% %D %\startlinecorrection
-% %D % \vbox to 1cm{\getbuffer}
-% %D %\stoplinecorrection
-% %D
-% %D \startlinecorrection
-% %D \unprotect
-% %D \vbox to 1cm{\dotgraybox{.5\hsize}{1cm}{0cm}{.85}{\v!no}{0pt}}
-% %D \protect
-% %D \stoplinecorrection
-% %D
-% %D There are two predefined methodes, one uses periods and the
-% %D other uses small rules. The second method is less
-% %D efficient, but sometimes give better results. The dimensions
-% %D of the resullting box are set to zero.
-%
-% \setvalue{\v!dot graybox}{\processraster\symbol\rasterdot}
-% \setvalue{\v!rule graybox}{\processraster\symbol\rasterbox}
-%
-% \def\rasterdot{\rasterfont.}
-% \def\rasterbox{\hss\vrule\!!width.4pt\!!height.4pt\!!depth\zeropoint}
-%
-% %D Now of course we need:
-%
-% \ifx\rasterfont\undefined \def\rasterfont{\fivepoint} \fi
-%
-% %D We implement two pure \TEX\ based generators, that use
-% %D \type{\leaders} to quickly gerenate the gray pattern. One
-% %D should beware of \DIMENSION\ conflicts, so we use some
-% %D registers above~8. These macros are memory hungry and byte
-% %D spoiling.
-%
-% \def\processraster#1#2#3#4#5#6#7%
-% {\bgroup
-% \forgetall
-% \dontcomplain
-% \dimen10=\onepoint
-% \dimen10=\@@rsfactor\dimen10
-% \dimen10=#5\dimen10
-% \setbox2\hbox to #2
-% {\cleaders\hbox to 2\dimen10{#1\hss}\hss}%
-% \dimen12=#3%
-% \advance\dimen12 #4%
-% % \setbox0\vbox to \dimen12
-% {\cleaders\vbox to 2\dimen10{\box2\vss}\vss}%
-% \setbox0\hbox
-% {\hskip-.5\dimen10\lower0.5\dimen10\copy0
-% \hskip-\wd0\hskip\dimen10\lower1.5\dimen10\box0}%
-% \box0
-% \egroup}
-
-%D \macros
-%D {setupscreens}
-%D
-%D The previous macro uses a predefined constant
-%D \type{\@@rsfactor}. This factor can be set by:
-%D
-%D \showsetup{setupscreens}
-
-\def\setupscreens
- {\dodoubleargument\getparameters[\??rs]}
-
-% %D The most appropriate way to call for this feature is
-% %D using \type{\graybox}, which is defined as:
-%
-% \def\graybox{\getvalue{\@@rsmethod graybox}}
-%
-% %D We just introduced two pure \TEX\ methods for generating
-% %D rasters. However, it's far more efficient and comfortable in
-% %D terms of speed, memory usage and file size, to use a driver
-% %D supported method.
-%
-% \setvalue{\v!external graybox}{\setgraybox}
-%
-% %D For compatibility reasons we also define the original one:
-%
-% \setvalue{\v!postscript graybox}{\getvalue{\v!external graybox}}
-%
-% %D A quite valid way of letting drivers do the job, is giving
-% %D a solid rule a gray texture.
-
-%D We will communicate through module specific variables, current
-%D framed parameters and some reserved dimension registers.
-
-\newdimen \frameddimenwd
-\newdimen \frameddimenht
-\newdimen \frameddimendp
-
-%D We don't have to stick to a \TEX\ drawn rule, but
-%D also can use rounded or even fancier shapes, as we will
-%D see later on.
-
-\def\dofilledbox
- {\bgroup
- \doifelse{\framedparameter\c!backgroundcorner}\v!rectangular
- {\dofilledlinedbox}
- {\ifzeropt\dimexpr\framedparameter\c!backgroundradius\relax % just in case of .x\bodyfontsize
- \dofilledlinedbox
- \else
- \dofilledroundbox
- \fi}%
- \egroup}
-
-\def\dophantombox
- {\hphantom{\dofilledbox}}
-
-\def\dofilledlinedbox
- {\vrule\!!width\frameddimenwd\!!height\frameddimenht\!!depth\frameddimendp\relax}%
-
-\def\dostrokedroundbox
- {\doif{\framedparameter\c!frame}\v!on\dodostrokedroundbox}
-
-\def\dodostrokedroundbox
- {\bgroup
- \edef\ovalmod{\framedparameter\c!framecorner}%
- \doifelse\ovalmod\v!round{\let\ovalmod\!!zerocount}{\edef\ovalmod{\number\ovalmod}}%
- \edef\ovalwid{\the\frameddimenwd}%
- \edef\ovalhei{\the\frameddimenht}%
- \edef\ovaldep{\the\frameddimendp}%
- \edef\ovallin{\the\dimexpr\ruledlinewidth}%
- \edef\ovalrad{\the\dimexpr\framedparameter\c!frameradius}%
- \let\ovalstr\!!plusone
- \let\ovalfil\!!zerocount
- \doovalbox\ovalwid\ovalhei\ovaldep\ovallin\ovalrad\ovalstr\ovalfil\ovalmod
- \egroup}
-
-\def\dofilledroundbox
- {\bgroup
- \edef\ovalmod{\framedparameter\c!backgroundcorner}%
- \doifelse\ovalmod\v!round{\let\ovalmod\!!zerocount}{\edef\ovalmod{\number\ovalmod}}%
- \edef\ovalwid{\the\frameddimenwd}%
- \edef\ovalhei{\the\frameddimenht}%
- \edef\ovaldep{\the\frameddimendp}%
- \edef\ovallin{\the\dimexpr\ruledlinewidth\relax}%
- \edef\ovalrad{\the\dimexpr\framedparameter\c!backgroundradius\relax}%
- \let\ovalstr\!!zerocount
- \let\ovalfil\!!plusone
- \doovalbox\ovalwid\ovalhei\ovaldep\ovallin\ovalrad\ovalstr\ovalfil\ovalmod
- \egroup}
-
-% a lot of weird corners
-%
-% \startTEXpage
-% \dontleavehmode\framed
-% [corner=0,frame=on,framecolor=green,
-% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green,
-% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green,
-% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse {9}{12}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse{13}{16}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse{17}{20}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse{21}{24}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \vskip1em
-% \dontleavehmode\dostepwiserecurse{25}{28}{1}{\framed
-% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
-% \quad}
-% \stopTEXpage
-
-%D The oval box is drawn using a special macro, depending on
-%D the driver in use.
-
-\def\dograybox % avoid black rules when no gray
- {\doifelsenothing{\framedparameter\c!backgroundscreen}
- {\dophantombox}
- {\raster[\framedparameter\c!backgroundscreen]{\dofilledbox}}}
-
-%D It won't be a surprise that we not only provide gray boxes,
-%D but also colored ones. Here it is:
-
-\def\docolorbox
- {\hbox{\ifincolor
- \doifcolorelse{\framedparameter\c!backgroundcolor}
- {\localcolortrue\color[\framedparameter\c!backgroundcolor]{\dofilledbox}}
- {\dophantombox}%
- \else
- \dophantombox
- \fi}}
-
-%D \macros
-%D {defineoverlay, doifoverlayelse, overlayoffset,
-%D overlaywidth, overlayheight, overlaydepth,
-%D overlaycolor, overlaylinecolor, overlaylinewidth}
-%D
-%D Before we define the macro that actually takes card of the
-%D backgrounds, we introduce overlays. An overlay is something
-%D that contrary to its name lays {\em under} the text. An
-%D example of an overlay definition is:
-%D
-%D \startbuffer[tmp-1]
-%D \defineoverlay
-%D [fancy]
-%D [{\externalfigure
-%D [mp-cont.502]
-%D [width=\overlaywidth,
-%D height=\overlayheight]}]
-%D \stopbuffer
-%D
-%D \typebuffer[tmp-1]
-%D
-%D That for instance can be uses in:
-%D
-%D \startbuffer[tmp-2]
-%D \framed[backgroundachtergrond=fancy]{How Fancy!}
-%D \framed[backgroundachtergrond=fancy,frame=off]{Even More Fancy!}
-%D \stopbuffer
-%D
-%D and looks like:
-%D
-%D \startlinecorrection
-%D \vbox{\baselineskip24pt\getbuffer[tmp-1]\getbuffer[tmp-2]}
-%D \stoplinecorrection
-%D
-%D The formal definition is:
-%D
-%D \showsetup{defineoverlay}
-%D
-%D This macro's definition is a bit obscure, due the many
-%D non||used arguments and the two step call that enable the
-%D setting of the width, height and depth variables.
-%D Multiple backgrounds are possible and are specified as:
-%D
-%D \starttyping
-%D \framed[background={one,two,three}]{Three backgrounds!}
-%D \stoptyping
-%D
-%D Most drawing packages only know width and height. Therefore
-%D the dimensions have a slightly different meaning here:
-%D
-%D \startitemize[packed]
-%D \item \type{\overlaywidth }: width of the overlay
-%D \item \type{\overlayheight}: height plus depth of the overlay
-%D \item \type{\overlaydepth }: depth of the overlay
-%D \stopitemize
-%D
-%D The resulting box is lowered to the right depth.
-
-\def\overlaywidth {\the\hsize\space} % We preset the variables
-\def\overlayheight {\the\vsize\space} % to some reasonable default
-\let\overlaydepth \!!zeropoint % values. The attributes
-\let\overlayoffset \!!zeropoint % of the frame can be (are)
-\let\overlaycolor \empty % set somewhere else.
-\let\overlaylinewidth \!!zeropoint %
-\let\overlaylinecolor \empty %
-
-%D The next register is used to initialize overlays.
-
-\newtoks\everyoverlay
-
-%D An example of an initialization is the following (overlays
-%D can contain text and be executed under an regime where
-%D interlineskip is off).
-
-\appendtoks \oninterlineskip \to \everyoverlay
-
-\def\defineoverlay
- {\dodoubleargument\dodefineoverlay}
-
-\def\dodefineoverlay[#1][#2]%
- {\def\docommand##1{\setvalue{\??ov##1}{\executedefinedoverlay{##1}{#2}}}%
- \processcommalist[#1]\docommand}
-
-\prependtoks
- \hsize\overlaywidth
- \vsize\overlayheight
-\to\everyoverlay
-
-\long\def\executedefinedoverlay#1#2%
- {\bgroup
- \edef\overlaywidth {\the\frameddimenwd\space}%
- \edef\overlayheight{\the\dimexpr\frameddimenht+\frameddimendp\relax\space}%
- \edef\overlaydepth {\the\frameddimendp\space}%
- \edef\overlaycolor {\framedparameter\c!backgroundcolor}%
- %\edef\overlaycorner{\framedparameter\c!backgroundcorner}%
- %\edef\overlayradius{\framedparameter\c!backgroundradius}%
- \let\overlayoffset\backgroundoffset % we steal this one
- \setbox\scratchbox\hbox{\lower\overlaydepth\hbox{\the\everyoverlay#2}}%
- \setbox\scratchbox\hbox
- {\hskip-.5\dimexpr\wd\scratchbox-\overlaywidth \relax
- \raise-.5\dimexpr\ht\scratchbox-\frameddimenht\relax % not overlayheight !
- \box\scratchbox}%
- \wd\scratchbox\overlaywidth
- \ht\scratchbox\overlayheight
- \dp\scratchbox\overlaydepth
- \startlayoutcomponent{o:#1}{overlay #1}%
- \box\scratchbox
- \stoplayoutcomponent
- \egroup}
-
-%D The empty case is:
-
-\let\executeoverlay\gobblesevenarguments
-
-%D For testing we provide:
-
-\def\doifoverlayelse#1%
- {\doifdefinedelse{\??ov#1}}
-
-%D We predefine two already familiar backgrounds:
-
-\setvalue{\??ov\v!screen}{\dograybox }
-\setvalue{\??ov\v!color }{\docolorbox}
-
-% %D After all these preparations, the background macro does no
-% %D bring to many surprises. One has to keep in mind that this
-% %D macro starts up a call chain, depending on the background
-% %D one needs:
-% %D
-% %D \startitemize[packed]
-% %D \item a raster, color or user defined shape
-% %D \item square or round corners
-% %D \item a \TEX\ or driver based method
-% %D \stopitemize
-% %D
-% %D The macro can be extended by adding commands to the token
-% %D list register \type {\everybackgroundbox}. For this
-% %D purpose, the name of the current background is available in
-% %D \type {\currentbackgound}.
-
-\newbox\extraframebox
-
-\newtoks\everybackgroundbox
-
-\let\currentbackground\empty
-
-% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method
-% {\bgroup
-% \def\currentbackground{#1}%
-% \the\everybackgroundbox
-% \setbox\extraframebox\hbox
-% {\vbox{\moveleft\backgroundoffset\hbox{\executeifdefined{\??ov\currentbackground}\donothing}}}%
-% \wd\extraframebox\zeropoint % \backgroundwidth
-% \ht\extraframebox\backgroundheight
-% \dp\extraframebox\backgrounddepth
-% \box\extraframebox % \hskip-\backgroundwidth
-% \egroup}
-
-% \def\dodobackgroundbox#1% also less passing, we can get rid of the old method
-% {\bgroup
-% \def\currentbackground{#1}%
-% \ifcsname\??ov\currentbackground\endcsname
-% \the\everybackgroundbox
-% \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}%
-% \wd\extraframebox\zeropoint % \backgroundwidth
-% \ht\extraframebox\backgroundheight
-% \dp\extraframebox\backgrounddepth
-% \box\extraframebox % \hskip-\backgroundwidth
-% \fi
-% \egroup}
-
-\def\dodobackgroundbox
- {\bgroup
- \ifcsname\??ov\currentbackground\endcsname
- \the\everybackgroundbox
- \setbox\extraframebox\hbox{\vbox{\moveleft\backgroundoffset\hbox{\csname\??ov\currentbackground\endcsname}}}%
- \wd\extraframebox\zeropoint % \backgroundwidth
- \ht\extraframebox\backgroundheight
- \dp\extraframebox\backgrounddepth
- \box\extraframebox % \hskip-\backgroundwidth
- \fi
- \egroup}
-
-\def\dododobackgroundbox#1,#2% #2 gobbles spaces
- {\edef\currentbackground{#1}%
- \ifx\currentbackground\s!unknown\else
- \dodobackgroundbox\expandafter\dododobackgroundbox
- \fi#2}
-
-\let\backgroundoffset\!!zeropoint
-\let\backgrounddepth \!!zeropoint
-\def\backgroundwidth {\the\hsize}
-\def\backgroundheight{\the\vsize}
-
-% todo: also \def\theforegroundbox{#1}
-
-% \def\dobackgroundbox#1%
-% {\setbox\framebox\vbox
-% {\forgetall
-% \boxmaxdepth\maxdimen
-% \scratchdimen \framedparameter{#1}\relax
-% \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
-% \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
-% \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax
-% \edef\backgroundoffset{\the\scratchdimen}%
-% \edef\backgroundwidth {\the\wd\framebox}%
-% \edef\backgroundheight{\the\ht\framebox}%
-% \edef\backgrounddepth {\the\dp\framebox}%
-% %\edef\foregroundbox{\box#1}%
-% \def\foregroundbox% fuzzy but needed hack, this \vss, otherwise
-% {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift
-% \edef\component{\framedparameter\c!component}%
-% \hbox to \backgroundwidth % in case 'foreground' is used as overlay
-% {\ifx\component\empty
-% \rawprocesscommalist[\framedbackground]\dodobackgroundbox
-% \else
-% \startlayoutcomponent{b:\component}{\s!background\space\component}%
-% \rawprocesscommalist[\framedbackground]\dodobackgroundbox
-% \stoplayoutcomponent
-% \fi
-% \box\framebox\hss}}}
-
-\def\normalforegroundbox% fuzzy but needed hack, this \vss, otherwise
- {\vbox to \backgroundheight{\vss\box\framebox\vss}}% vertical shift
-
-\def\dobackgroundbox#1%
- {\setbox\framebox\vbox
- {\forgetall
- \boxmaxdepth\maxdimen
- \scratchdimen \framedparameter{#1}\relax
- \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
- \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
- \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!backgrounddepth\relax
- \edef\backgroundoffset{\the\scratchdimen}%
- \edef\backgroundwidth {\the\wd\framebox}%
- \edef\backgroundheight{\the\ht\framebox}%
- \edef\backgrounddepth {\the\dp\framebox}%
- %\edef\foregroundbox{\box#1}%
- \edef\component{\framedparameter\c!component}%
- \let\foregroundbox\normalforegroundbox
- \hbox to \backgroundwidth % in case 'foreground' is used as overlay
- {\ifx\component\empty
- \expanded{\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax
- \else
- \startlayoutcomponent{b:\component}{background \component}%
- \expanded{\dododobackgroundbox\framedparameter\c!background},\s!unknown,\relax
- \stoplayoutcomponent
- \fi
- \box\framebox\hss}}}
-
-%D One can explictly insert the foreground box. For that
-%D purpose we introduce the overlay \type {foreground}.
-
-\defineoverlay[\v!foreground][\foregroundbox]
-
-%D We can specify overlays as a comma separated list of
-%D overlays, a sometimes handy feature.
-
-%D Besides backgrounds (overlays) we also need some macros to
-%D draw outlines (ruled borders). Again we have to deal with
-%D square and round corners. The first category can be handled
-%D by \TEX\ itself, the latter one depends on the driver. This
-%D macro also support a negative offset.
-
-\ifx\scratchoffset\undefined \newdimen\scratchoffset \fi
-
-\def\dooutlinebox % we needed to move the color command in order to apply attributes properly
- {\setbox\framebox\vbox % rules on top of box
- {\scratchoffset \framedparameter\c!frameoffset\relax
- \frameddimenwd\dimexpr\wd\framebox+2\scratchoffset\relax
- \frameddimenht\dimexpr\ht\framebox+ \scratchoffset\relax
- \frameddimendp\dimexpr\dp\framebox+ \scratchoffset+\framedparameter\c!framedepth\relax
- \ifdim\frameddimendp<\zeropoint
- \advance\frameddimenht \frameddimendp
- \scratchdimen-\frameddimendp
- \frameddimendp\zeropoint
- \else
- \scratchdimen\zeropoint
- \fi
- \setbox\extraframebox\hbox
- {\doifsomething{\framedparameter\c!framecolor}{\color[\framedparameter\c!framecolor]}{\dostrokedbox}}%
- \setbox\extraframebox\hbox
- {\raise\scratchdimen\vbox
- {\moveleft\scratchoffset
- \box\extraframebox}}%
- \wd\extraframebox\wd\framebox
- \ht\extraframebox\ht\framebox
- \dp\extraframebox\dp\framebox
- \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}}
-
-\def\dostrokedbox
- {\doifelse{\framedparameter\c!framecorner}\v!rectangular
- {\dostrokedlinedbox}
- {\ifzeropt\dimexpr\framedparameter\c!frameradius\relax % just in case of .x\bodyfontsize
- \dostrokedlinedbox
- \else
- \dostrokedroundbox
- \fi}}
-
-\def\dostrokedlinedbox
- {\setbox\scratchbox\null
- \wd\scratchbox\frameddimenwd
- \ht\scratchbox\frameddimenht
- \dp\scratchbox\frameddimendp
- \setbox\scratchbox\vbox \bgroup
- \csname t\@@frame@@\framedparameter\c!frame\framedparameter\c!topframe \endcsname
- \hbox \bgroup
- \csname l\@@frame@@\framedparameter\c!frame\framedparameter\c!leftframe \endcsname
- \box\scratchbox
- \csname r\@@frame@@\framedparameter\c!frame\framedparameter\c!rightframe \endcsname
- \egroup
- \csname b\@@frame@@\framedparameter\c!frame\framedparameter\c!bottomframe\endcsname
- \egroup
- \wd\scratchbox\frameddimenwd
- \ht\scratchbox\frameddimenht
- \dp\scratchbox\frameddimendp
- \box\scratchbox}
-
-\def\@@frame@@{@@frame@@}
-
-% \setvalue{t\@@frame@@\v!on \v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
-% \setvalue{t\@@frame@@\v!off\v!on}{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
-% \setvalue{t\@@frame@@\v!on }{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
-% \setvalue{b\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
-% \setvalue{b\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
-% \setvalue{b\@@frame@@\v!on }{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
-% \setvalue{l\@@frame@@\v!on \v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
-% \setvalue{l\@@frame@@\v!off\v!on}{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
-% \setvalue{l\@@frame@@\v!on }{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
-% \setvalue{r\@@frame@@\v!on \v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
-% \setvalue{r\@@frame@@\v!off\v!on}{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
-% \setvalue{r\@@frame@@\v!on }{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
-
-\def\@@frame@@trule{\hrule\!!height\ruledlinewidth\kern-\ruledlinewidth}
-\def\@@frame@@brule{\kern-\ruledlinewidth\hrule\!!height\ruledlinewidth}
-\def\@@frame@@rrule{\kern-\ruledlinewidth\vrule\!!width\ruledlinewidth}
-\def\@@frame@@lrule{\vrule\!!width\ruledlinewidth\kern-\ruledlinewidth}
-
-\letvalue{t\@@frame@@\v!on \v!on}\@@frame@@trule
-\letvalue{t\@@frame@@\v!off\v!on}\@@frame@@trule
-\letvalue{t\@@frame@@\v!on }\@@frame@@trule
-
-\letvalue{b\@@frame@@\v!on \v!on}\@@frame@@brule
-\letvalue{b\@@frame@@\v!off\v!on}\@@frame@@brule
-\letvalue{b\@@frame@@\v!on }\@@frame@@brule
-
-\letvalue{l\@@frame@@\v!on \v!on}\@@frame@@lrule
-\letvalue{l\@@frame@@\v!off\v!on}\@@frame@@lrule
-\letvalue{l\@@frame@@\v!on }\@@frame@@lrule
-
-\letvalue{r\@@frame@@\v!on \v!on}\@@frame@@rrule
-\letvalue{r\@@frame@@\v!off\v!on}\@@frame@@rrule
-\letvalue{r\@@frame@@\v!on }\@@frame@@rrule
-
-% no overlapping rules
-
-\def\@@frame@@trules{\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}\nointerlineskip\kern-\ruledlinewidth}
-\def\@@frame@@brules{\kern-\ruledlinewidth\nointerlineskip\hbox{\kern\ruledlinewidth\vrule\!!width\dimexpr\frameddimenwd-2\ruledlinewidth\relax\!!height\ruledlinewidth}}
-\def\@@frame@@rrules{\kern-\ruledlinewidth\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth}
-\def\@@frame@@lrules{\vrule\!!height\dimexpr\frameddimenht-\ruledlinewidth\relax\!!depth-\ruledlinewidth\!!width\ruledlinewidth\kern-\ruledlinewidth}
-
-% small is relatively new
-
-\letvalue{t\@@frame@@\v!small\v!small}\@@frame@@trules
-\letvalue{t\@@frame@@\v!off \v!small}\@@frame@@trules
-\letvalue{t\@@frame@@\v!small }\@@frame@@trules
-
-\letvalue{b\@@frame@@\v!small\v!small}\@@frame@@brules
-\letvalue{b\@@frame@@\v!off \v!small}\@@frame@@brules
-\letvalue{b\@@frame@@\v!small }\@@frame@@brules
-
-\letvalue{l\@@frame@@\v!small\v!small}\@@frame@@lrules
-\letvalue{l\@@frame@@\v!off \v!small}\@@frame@@lrules
-\letvalue{l\@@frame@@\v!small }\@@frame@@lrules
-
-\letvalue{r\@@frame@@\v!small\v!small}\@@frame@@rrules
-\letvalue{r\@@frame@@\v!off \v!small}\@@frame@@rrules
-\letvalue{r\@@frame@@\v!small }\@@frame@@rrules
-
-%D I condidered using the low level support command
-%D \type{\ruledhbox}, but this would slow down processing by a
-%D factor~3.
-
-% \framed
-% [width=4cm,height=3cm,rulethickness=3mm,
-% frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on]
-% {}
-% \framed
-% [width=4cm,height=3cm,rulethickness=3mm,
-% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small]
-% {}
-% \framed
-% [width=4cm,height=3cm,rulethickness=3mm,
-% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on]
-% {}
-
-%D The next few macros are probably the most misused ones in
-%D \CONTEXT. They deal with putting rules around boxes, provide
-%D backgrounds, offer alignment features, and some more. We
-%D start with defining some booleans. These give an impression
-%D of what we are going to take into account.
-
-% todo: chardefs
-
-\newif\ifboxhasoffset
-\newif\ifboxhaswidth
-\newif\ifboxhasheight
-\newif\ifboxhasformat
-\newif\ifboxhasstrut
-\newif\ifboxisoverlaid
-\newif\ifboxhasframe
-\newif\ifdelayedstrut
-
-%D We also need a few \DIMENSIONS:
-
-\newdimen\@@localoffset
-\newdimen\@@globalwidth
-
-%D The content of the box will be (temporary) saved in a box:
-
-\newbox\framebox
-
-%D We also need a box for outlines and backgrounds:
-
-\newbox\extraframebox
-
-%D \macros
-%D {framed, setupframed}
-%D
-%D Ruled boxes are typeset using \type{\framed}. This command
-%D is quite versatile and, although some users will probably
-%D seldom use it, one cannot overlook its features.
-%D
-%D \showsetup{setupframed}
-%D \showsetup{framed}
-%D
-%D This general macro is a special version of an even more
-%D general case, that can easily be linked into other macros
-%D that need some kind of framing. The local version is called
-%D with an extra parameter: the variable identifier. The reason
-%D for passing this identifier between brackets lays in the
-%D mere fact that this way we can use the optional argument
-%D grabbers.
-
-\def\defaultframeoffset{.25ex}
-
-\unexpanded\def\framed
- {\bgroup
- \copylocalframed[\??ol][\??oi]% == \presetlocalframed[\??ol]%
- \dodoubleempty\startlocalframed[\??ol]}
-
-\def\presetlocalframed[#1]%
- {\copylocalframed[#1][\??oi]}
-
-% \def\copylocalframed[#1]#2[#3]%
-% {\copyparameters[#1][#3]%
-% [\c!width,\c!height,\c!radius,\c!corner,\c!depth,\c!offset,%
-% \c!autowidth,\c!empty,\c!component,\c!orientation,\c!lines,%
-% \c!align,\c!bottom,\c!top,\c!strut,\c!autostrut,\c!location,\c!setups,\c!extras,%
-% \c!foregroundstyle,\c!foregroundcolor,%
-% \c!background,\c!backgroundoffset,\c!backgroundcorner,\c!backgroundradius,\c!backgrounddepth,\c!backgroundcolor,\c!backgroundscreen,%
-% \c!frame,\c!frameoffset,\c!framecorner,\c!frameradius,\c!framedepth,\c!framecolor,\c!rulethickness,%
-% \c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe]}
-
-% since framed is used all over the place, we have a (small) speedup)
-
-\def\copylocalframed[#1]#2[#3]%
- {\edef\copiedfrom{#1}\edef\copiedto{#3}%
- \docopyvalue\copiedfrom\copiedto\c!width
- \docopyvalue\copiedfrom\copiedto\c!height
- \docopyvalue\copiedfrom\copiedto\c!autowidth
- \docopyvalue\copiedfrom\copiedto\c!offset
- \docopyvalue\copiedfrom\copiedto\c!empty
- \docopyvalue\copiedfrom\copiedto\c!rulethickness
- \docopyvalue\copiedfrom\copiedto\c!radius
- \docopyvalue\copiedfrom\copiedto\c!corner
- \docopyvalue\copiedfrom\copiedto\c!depth
- \docopyvalue\copiedfrom\copiedto\c!frame
- \docopyvalue\copiedfrom\copiedto\c!framecolor
- \docopyvalue\copiedfrom\copiedto\c!foregroundstyle
- \docopyvalue\copiedfrom\copiedto\c!foregroundcolor
- \docopyvalue\copiedfrom\copiedto\c!lines
- \docopyvalue\copiedfrom\copiedto\c!orientation
- \docopyvalue\copiedfrom\copiedto\c!topframe
- \docopyvalue\copiedfrom\copiedto\c!bottomframe
- \docopyvalue\copiedfrom\copiedto\c!leftframe
- \docopyvalue\copiedfrom\copiedto\c!rightframe
- \docopyvalue\copiedfrom\copiedto\c!rulethickness
- \docopyvalue\copiedfrom\copiedto\c!frameoffset
- \docopyvalue\copiedfrom\copiedto\c!background
- \docopyvalue\copiedfrom\copiedto\c!component
- \docopyvalue\copiedfrom\copiedto\c!backgroundoffset
- \docopyvalue\copiedfrom\copiedto\c!backgroundscreen
- \docopyvalue\copiedfrom\copiedto\c!backgroundcolor
- \docopyvalue\copiedfrom\copiedto\c!align
- \docopyvalue\copiedfrom\copiedto\c!bottom
- \docopyvalue\copiedfrom\copiedto\c!top
- \docopyvalue\copiedfrom\copiedto\c!strut
- \docopyvalue\copiedfrom\copiedto\c!autostrut
- \docopyvalue\copiedfrom\copiedto\c!location
- \docopyvalue\copiedfrom\copiedto\c!component
- \docopyvalue\copiedfrom\copiedto\c!extras
- \docopyvalue\copiedfrom\copiedto\c!setups
- \docopyvalue\copiedfrom\copiedto\c!backgroundradius
- \docopyvalue\copiedfrom\copiedto\c!backgroundcorner
- \docopyvalue\copiedfrom\copiedto\c!backgrounddepth
- \docopyvalue\copiedfrom\copiedto\c!frameradius
- \docopyvalue\copiedfrom\copiedto\c!framecorner
- \docopyvalue\copiedfrom\copiedto\c!framedepth}
-
-\def\setupframed
- {\dodoubleempty\dosetupframed}
-
-\def\dosetupframed
- {\ifsecondargument
- \@EA\dodoublesetupframed
- \else
- \@EA\dosinglesetupframed
- \fi}
-
-\def\dosinglesetupframed[#1][#2]%
- {\getparameters[\??oi][#1]}
-
-\def\dodoublesetupframed[#1][#2]%
- {\bgroup
- \let\dodoubleempty\empty
- \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}%
- \getvalue{#1}%
- \egroup
- \letvalue{#1}\globalredefinedframed}
-
-%D \startbuffer
-%D \setupframed [framecolor=yellow] \framed{A}
-%D \defineframed[myframed] [framecolor=blue] \myframed{B}
-%D \setupframed [myframed] [framecolor=red] \myframed{C}
-%D \stopbuffer
-%D
-%D \typebuffer \getbuffer
-%D
-%D \startbuffer
-%D \presetlocalframed[myframed]
-%D \setuplocalframed[myframed][width=4cm,height=2cm]
-%D \localframed[myframed][framecolor=green]{oeps}
-%D \stopbuffer
-%D
-%D \typebuffer \getbuffer
-
-%D \macros
-%D {ifinframed}
-%D
-%D The normal case first presets all parameters and next starts
-%D looking for the user supplied ones. The first step is
-%D omitted in the local case, because these are preset at
-%D declaration time and keep their values unless explictly
-%D changed. By presetting the variables everytime the normal
-%D command is called, we can use this command nested, without
-%D the unwanted side effect of inheritance. The boolean is
-%D used to speed up the color stack.
-
-\newif\ifinframed
-
-\def\localframed
- {\bgroup
- \dodoubleempty\startlocalframed}
-
-%D The next one is faster on multiple backgrounds per page. No
-%D dimensions can be set, only frames and backgrounds.
-
-\def\fastlocalframed[#1]#2[#3]#4% 3-4
- {\bgroup
- \inframedtrue
- \edef\@@framed{#1}%
- % more bytes
- % \scratchdimen\framedparameter\c!frameoffset
- % \setevalue{\@@framed\c!frameoffset}{\the\scratchdimen}%
- % \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
- % {\scratchdimen\framedparameter\c!backgroundoffset
- % \setevalue{\@@framed\c!backgroundoffset}{\the\scratchdimen}}%
- % less bytes
- \@EA\freezedimenmacro\csname\@@framed\c!frameoffset\endcsname
- \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
- {\@EA\freezedimenmacro\csname\@@framed\c!backgroundoffset\endcsname}%
- % so far
- \setbox\framebox\hbox{#4}%
- \getparameters[\@@framed][#3]% no \expanded !
- % no, better in calling macro
- %
- % \edef\doframedsetups{\framedparameter\c!setups}%
- % \ifx\doframedsetups\empty\else
- % \edef\doframedsetups{\noexpand\setups[\doframedsetups]}%
- % \fi
- \removeframedboxdepth
- \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}%
- \ifx\framedforegroundcolor\empty\else\docolorframebox\fi
- \edef\overlaylinecolor{\framedparameter\c!framecolor}%
- \edef\overlaylinewidth{\the\ruledlinewidth}%
- \edef\@@localframing {\framedparameter\c!frame}%
- \ifx\@@localframing\v!overlay \else \ifx\@@localframing\v!none \else
- \edef\framedrulethickness{\framedparameter\c!rulethickness}%
- \ifx\framedrulethickness\empty\else
- \ruledlinewidth\framedrulethickness\relax
- \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi
- \fi
- \dooutlinebox % real or invisible frame
- \fi \fi
- \edef\framedbackground{\framedparameter\c!background}%
- \ifx\framedbackground\empty\else\dobackedbox\fi
- \restoreframedboxdepth
- \box\framebox
- \egroup}
-
-%D Before we go into details, we present (and implement) the
-%D main framing routine. I saw no real reason for splitting the
-%D next two macros into smaller pieces. The content will be
-%D collected in a horizontal or vertical box with fixed or free
-%D dimensions and specific settings concerning aligment and
-%D offsets.
-%D
-%D In the first few lines, we pre||expand the frame and
-%D background offsets. We do so, because the can be defined in
-%D terms of the main offset. However, see for instance page
-%D backgrounds, when \type {#2} sets the offset to \type
-%D {overlay}, both offsets become invalid.
-%D
-%D Because it is used so often the he next macro is (and
-%D looks) rather optimized.
-
-\let\postprocessframebox\relax
-
-\let\@@framed\s!unknown
-
-\def\framedparameter#1%
- {\csname\@@framed#1\endcsname}
-
-\newdimen\!!framedwidth
-\newdimen\!!framedheight
-
-\def\startlocalframed[#1][#2]%
- {\bgroup
- \inframedtrue
- \edef\@@framed{#1}%
- % this piece of pre expansion is needed (sometimes used in frameoffset)
- % \doifvaluesomething{\@@framed\c!rulethickness} % obsolete
- % {\ruledlinewidth\getvalue{\@@framed\c!rulethickness}}% obsolete
- % this piece of pre expansion is needed (sometimes used circular)
- \setevalue{\@@framed\c!frameoffset}{\the\dimexpr\framedparameter\c!frameoffset\relax}%
- \doifnotvalue{\@@framed\c!backgroundoffset}\v!frame
- {\setevalue{\@@framed\c!backgroundoffset}{\the\dimexpr\framedparameter\c!backgroundoffset\relax}}%
- % to prevent deadlock in case of self refering
- \ifsecondargument % faster
- \getparameters[\@@framed][#2]% here !
- \fi
- % new, experimental dirty hook
- \framedparameter\c!extras
- % to get the right spacing
- \doifvaluesomething{\@@framed\c!foregroundstyle}
- {\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}%
- % beware, both the frame and background offset can be overruled
- %
- \edef\doframedsetups{\framedparameter\c!setups}%
- \ifx\doframedsetups\empty\else
- \edef\doframedsetups{\noexpand\setups[\doframedsetups]}%
- \fi
- % the next macros are visible
- \edef\localoffset{\framedparameter\c!offset}%
- \edef\localwidth {\framedparameter\c!width}%
- \edef\localheight{\framedparameter\c!height}%
- \edef\localformat{\framedparameter\c!align}%
- \edef\localstrut {\framedparameter\c!strut}%
- % these are not
- \edef\@@localautostrut {\framedparameter\c!autostrut}%
- \edef\@@localframing {\framedparameter\c!frame}%
- \edef\@@locallocation {\framedparameter\c!location}%
- \edef\@@localorientation{\framedparameter\c!orientation}%
- %
- \edef\@@localautowidth {\framedparameter\c!autowidth}%
- %
- \ifx\@@localframing\v!overlay % no frame, no offset, no framewidth
- \boxhasframefalse
- \let\localoffset\v!overlay
- \else\ifx\@@localframing\v!none % no frame, no framewidth
- \boxhasframefalse
- \else
- \boxhasframetrue
- \fi\fi
- \ifboxhasframe
- \edef\framedrulethickness{\framedparameter\c!rulethickness}%
- \ifx\framedrulethickness\empty\else
- \ruledlinewidth\framedrulethickness\relax
- \ifinheritruledlinewidth\linewidth\ruledlinewidth\fi
- \fi
- \else
- \ruledlinewidth\zeropoint
- \fi
- \ifx\localformat\empty
- \boxhasformatfalse
- \else
- \boxhasformattrue
- \dosetraggedcommand\localformat
- \edef\dobeforeframedbox{\raggedtopcommand\framedparameter\c!top}%
- \edef\doafterframedbox {\framedparameter\c!bottom\raggedbottomcommand}%
- \fi
- \ifx\localoffset\v!none
- \boxhasoffsetfalse
- \boxhasstrutfalse
- \boxisoverlaidfalse
- \@@localoffset\ruledlinewidth
- \else\ifx\localoffset\v!overlay
- % \ifx\@@localframing\v!no \boxhasframefalse \fi % test first
- \boxhasoffsetfalse
- \boxhasstrutfalse
- \boxisoverlaidtrue
- \@@localoffset\zeropoint
- \else
- \boxhasoffsettrue
- \boxhasstruttrue
- \boxisoverlaidfalse
- \ifx\localoffset\v!default % new per 2-6-2000
- \let\localoffset\defaultframeoffset
- \letvalue{\@@framed\c!offset}\defaultframeoffset
- \else
- \let\defaultframeoffset\localoffset
- \fi
- \@@localoffset\dimexpr\localoffset+\ruledlinewidth\relax
- \fi\fi
- \!!framedheight\zeropoint
- \!!framedwidth \zeropoint
- \ifx\localwidth\v!fit
- \ifboxhasformat
- \boxhaswidthtrue
- \!!framedwidth\hsize
- \else
- \boxhaswidthfalse
- \fi
- \else\ifx\localwidth\v!fixed % equals \v!fit but no shapebox
- \ifboxhasformat
- \boxhaswidthtrue
- \!!framedwidth\hsize
- \else
- \boxhaswidthfalse
- \fi
- \else\ifx\localwidth\v!broad
- \boxhaswidthtrue
- \!!framedwidth\hsize
- \else\ifx\localwidth\v!local
- \boxhaswidthtrue
- \setlocalhsize
- \!!framedwidth\localhsize
- \else
- \boxhaswidthtrue
- \!!framedwidth\localwidth
- \fi\fi\fi\fi
- \ifx\localheight\v!fit
- \boxhasheightfalse % no longer: \boxhasstrutfalse
- \else\ifx\localheight\v!broad
- \boxhasheightfalse
- \else
- \boxhasheighttrue
- \!!framedheight\localheight
- \fi\fi
- \ifboxhasheight
- % obey user set height, also downward compatible
- \else
- \doifvaluesomething{\@@framed\c!lines}
- {\ifcase\framedparameter\c!lines\else
- \!!framedheight\framedparameter\c!lines\lineheight
- \edef\localheight{\the\!!framedheight}%
- \boxhasheighttrue
- \fi}%
- \fi
- % this is now an option: width=local
- %
- % \ifdim\!!framedwidth=\hsize
- % \parindent\zeropoint
- % \setlocalhsize
- % \!!framedwidth\localhsize
- % \fi
- % i.e. disable (colsetbackgroundproblemintechniek)
- \advance\!!framedwidth -2\@@localoffset
- \advance\!!framedheight -2\@@localoffset
- \ifx\localstrut\v!no
- \boxhasstrutfalse
- \else\ifx\localstrut\v!global
- \setstrut
- \else\ifx\localstrut\v!local
- \setfontstrut
- \else
- \setstrut
- \fi\fi\fi
- \ifboxhasstrut
- \let\localbegstrut\begstrut
- \let\localendstrut\endstrut
- \let\localstrut \strut
- \else
- \let\localbegstrut\pseudobegstrut % was: \relax
- \let\localendstrut\pseudoendstrut % was: \relax
- \let\localstrut \pseudostrut % was: \relax
- %\ifboxhasheight\ifdim\!!framedheight<\strutht % saveguard
- % \let\localbegstrut\relax % but not that
- % \let\localstrut \relax % save after all
- %\fi\fi
- \fi
- \ifx\@@localautostrut\v!yes
- \let\delayedbegstrut\relax
- \let\delayedendstrut\relax
- \let\delayedstrut \relax
- \else
- \let\delayedbegstrut\localbegstrut
- \let\delayedendstrut\localendstrut
- \let\delayedstrut \localstrut
- \let\localbegstrut \relax
- \let\localendstrut \relax
- \let\localstrut \relax
- \fi
- \ifboxhasheight
- \let\\\vboxednewline
- \ifboxhaswidth
- \let\hairline\vboxedhairline
- \ifboxhasformat
- \let\next\doformatboxSomeFormat
- \else
- \let\next\doformatboxNoFormat
- \fi
- \else
- \let\hairline\hboxedhairline
- \ifboxhasformat
- \let\next\doformatboxHeight
- \else
- \let\next\doformatboxVSize
- \fi
- \fi
- \else
- \ifboxhaswidth
- \ifboxhasformat
- \let\hairline\vboxedhairline
- \let\\\vboxednewline
- \let\next\doformatboxWidth
- \else
- \let\hairline\hboxedhairline
- \let\\\hboxednewline
- \let\next\doformatboxHSize
- \fi
- \else
- \let\hairline\hboxedhairline
- \let\\\hboxednewline
- \let\next\doformatboxNoSize
- \fi
- \fi
- \edef\framedwidth % a new feature, visible for user
- {\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}%
- \edef\framedheight% a new feature, visible for user
- {\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}%
- % we need to register the (outer) color
- \startregistercolor[\framedparameter\c!foregroundcolor]%
- % first alternative
- %\def\dowithframedbox%
- % {\let\postprocessframebox\relax %new
- % \aftergroup\stoplocalframed}%
- % \afterassignment\dowithframedbox
- % \setbox\framebox=\next}
- % second alternative
- %\dowithnextbox
- % {\setbox\framebox\flushnextbox
- % \let\postprocessframebox\relax %new
- % \stoplocalframed}
- % \next}
- \@@startframedorientation
- \afterassignment\dodowithframebox
- \setbox\framebox\next}
-
-\def\dowithframebox
- {% moved : \let\postprocessframebox\relax
- \stoplocalframed}
-
-\def\dodowithframebox
- {\aftergroup\dowithframebox}
-
-\let\doafterframedbox \relax
-\let\dobeforeframedbox\relax
-
-%D Carefull analysis of this macro will learn us that not all
-%D branches in the last conditionals can be encountered, that
-%D is, some assignments to \type{\next} will never occur.
-%D Nevertheless we implement the whole scheme, if not for
-%D future extensions.
-
-%D \macros
-%D {ifreshapeframebox}
-%D
-%D The last few lines tell what to do after the content of the
-%D box is collected and passed to the next macro. In the case
-%D of a fixed width and centered alignment, the content is
-%D evaluated and used to determine the most natural width. The
-%D rest of the code deals with backgrounds and frames.
-
-\newif\ifreshapeframebox \reshapeframeboxtrue
-
-%D Beware: setting \type {top} and \type {bottom} to nothing, may
-%D result in a frame that is larger that the given height! try:
-%D
-%D \starttyping
-%D \framed
-%D [height=3cm,top=,bottom=,offset=overlay]
-%D {\strut test \shapefill \strut test}
-%D \stoptyping
-%D
-%D This is intended behaviour and not a bug! One can always set
-%D
-%D \starttyping
-%D ...,bottom=\kern0pt,...
-%D \stoptyping
-
-\def\stoplocalframed
- {\dontshowcomposition
- \@@stopframedorientation % hm, wrong place ! should rotate the result (after reshape)
- \stopregistercolor
- \handleframedlocator\c!before\@@locallocation
- \ifboxhasformat
- \ifx\@@localautowidth\v!force
- \ifreshapeframebox\doreshapeframedbox\fi
- \boxhaswidthfalse
- \else
- \ifx\localwidth\v!fit
- \ifx\@@localautowidth\v!yes
- \ifreshapeframebox\doreshapeframedbox\fi
- \fi
- \boxhaswidthfalse
- \else\ifx\localwidth\v!fixed
- \boxhaswidthfalse
- \else
- \resetshapeframebox
- \fi\fi
- \fi
- \else
- \resetshapeframebox
- \fi
- \ifboxhaswidth
- \wd\framebox\!!framedwidth
- \fi
- \ifboxhasheight
- \ht\framebox\!!framedheight
- \fi
- \doifvalue{\@@framed\c!empty}\v!yes
- {\setbox\scratchbox\null
- \wd\scratchbox\wd\framebox
- \ht\scratchbox\ht\framebox
- \dp\scratchbox\dp\framebox
- \setbox\framebox\box\scratchbox}%
- \edef\framedforegroundcolor{\framedparameter\c!foregroundcolor}%
- \ifx\framedforegroundcolor\empty\else\docolorframebox\fi
- \ifboxhasoffset
- \dooffsetframebox
- \fi
- \ifboxisoverlaid \else
- \dolocateframebox
- \fi
- \ifx\postprocessframebox\relax \else
- \let\next\postprocessframebox
- \let\postprocessframebox\relax % prevent nesting
- \next\framebox
- \fi
- \edef\overlaylinecolor{\framedparameter\c!framecolor}%
- \edef\overlaylinewidth{\the\ruledlinewidth}% \@@...
- \ifboxhasframe % real or invisible frame
- \dooutlinebox
- \fi
- \edef\framedbackground{\framedparameter\c!background}%
- \ifx\framedbackground\empty\else\dobackedbox\fi
- \handleframedlocator\c!after\@@locallocation
- \box\framebox
- \egroup
- \egroup}
-
-\def\installframedlocator#1#2#3%
- {\setvalue{\??ol:\c!location:\c!before:#1}{#2}%
- \setvalue{\??ol:\c!location:\c!after :#1}{#3}}
-
-\def\handleframedlocator#1#2%
- {\getvalue{\??ol:\c!location:#1:#2}}
-
-\def\doprelocframedbox#1%
- {\scratchdimen\dimexpr#1+\ruledlinewidth\relax
- \ifboxhasoffset
- \advance\scratchdimen \framedparameter\c!offset
- \fi
- \scratchskip\dimexpr\ht\framebox-\scratchdimen\relax}
-
-% \ruledhbox
-% {A
-% \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging}
-% \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth}
-% \framed[width=2cm,align=middle,location=height] {location\\equals\\height}
-% B}
-% \vskip2cm
-% \ruledhbox
-% {A
-% \framed[width=2cm,align=middle,location=low] {location\\equals\\low}
-% \framed[width=2cm,align=middle,location=line] {location\\equals\\line}
-% \framed[width=2cm,align=middle,location=high] {location\\equals\\high}
-% B}
-% \vskip2cm
-% \ruledhbox
-% {A
-% \framed[width=2cm,align=middle,location=top] {location\\equals\\top}
-% \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom}
-% \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi}
-% \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle}
-% B}
-
-\installframedlocator \v!hanging % best with strut=no
- {}
- {\dp\framebox\ht\framebox
- \ht\framebox\zeropoint}
-
-\installframedlocator \v!depth
- {}
- {\ht\framebox\dimexpr\ht\framebox-\strutdp\relax
- \dp\framebox\strutdp
- \box\framebox}
-
-\installframedlocator \v!height
- {}
- {\dp\framebox\dimexpr\ht\framebox-\strutht\relax
- \ht\framebox\strutht
- \box\framebox}
-
-\installframedlocator \v!high
- {}
- {\doprelocframedbox\strutht
- \setbox\framebox\hbox{\lower\scratchskip\box\framebox}%
- \ht\framebox\strutht
- \dp\framebox\strutdp
- \hbox{\box\framebox}}
-
-\installframedlocator \v!line
- {}
- {\setbox\framebox\hbox{\lower.5\ht\framebox\box\framebox}%
- \ht\framebox.5\lineheight
- \dp\framebox.5\lineheight
- \hbox{\box\framebox}}
-
-\installframedlocator \v!low
- {}
- {\doprelocframedbox\strutdp
- \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
- \ht\framebox\strutht
- \dp\framebox\strutdp
- \box\framebox}
-
-\installframedlocator \v!top
- {}
- {\doprelocframedbox\strutht
- \setbox\framebox\hbox{\lower\scratchskip\box\framebox}%
- \ht\framebox\scratchdimen
- \dp\framebox\scratchskip
- \hbox{\box\framebox}}
-
-\installframedlocator \v!middle
- {}
- {\scratchdimen.5\ht\framebox
- \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
- \ht\framebox\scratchdimen
- \dp\framebox\scratchdimen
- \hbox{\box\framebox}}
-
-\installframedlocator \v!lohi
- {\handleframedlocator\c!before\v!middle}
- {\handleframedlocator\c!after \v!middle}
-
-\installframedlocator \v!bottom
- {}
- {\doprelocframedbox\strutdp
- \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
- \ht\framebox\scratchskip
- \dp\framebox\scratchdimen
- \hbox{\box\framebox}}
-
-\installframedlocator \v!keep % retains height/depth
- {\removeframedboxdepth}
- {\restoreframedboxdepth}
-
-% also used in fastlocalframed
-
-\newdimen\originalframedwd
-\newdimen\originalframedht
-\newdimen\originalframeddp
-
-\def\removeframedboxdepth
- {\originalframedwd\wd\framebox
- \originalframedht\ht\framebox
- \originalframeddp\dp\framebox
- \ifzeropt\originalframeddp\else\setbox\framebox\hbox{\raise\originalframeddp\box\framebox}\fi
- \wd\framebox\originalframedwd
- \ht\framebox\dimexpr\originalframedht+\originalframeddp\relax
- \dp\framebox\zeropoint}
-
-\def\restoreframedboxdepth
- {\ifzeropt\originalframeddp\else\setbox\framebox\hbox{\lower\originalframeddp\box\framebox}\fi
- \wd\framebox\originalframedwd
- \ht\framebox\originalframedht
- \dp\framebox\originalframeddp}
-
-% \let\@@startframedorientation\relax
-% \let\@@stopframedorientation \relax
-
-% \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax}
-% \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax}
-% \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax}
-% \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax}
-% \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax}
-% \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax}
-% \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax}
-
-\def\@@startframedorientation
- {\let\@@stopframedorientation \relax
- \ifx\@@localorientation\empty\else
- \ifcase\@@localorientation\else
- \scratchcounter\@@localorientation
- \divide\scratchcounter\plustwo
- \ifodd\scratchcounter
- \swapmacros\framedwidth \framedheight
- \swapmacros\localwidth \localheight
- \swapdimens\!!framedheight\!!framedwidth
- \def\@@stopframedorientation{\@@dostopframedorientation\plusone}%
- \else
- \def\@@stopframedorientation{\@@dostopframedorientation\zerocount}%
- \fi
- \fi
- \fi}
-
-\def\@@dostopframedorientation#1%
- {\ifcase#1\else
- \swapmacros\framedwidth \framedheight
- \swapmacros\localwidth \localheight
- \swapdimens\!!framedheight\!!framedwidth
- \fi
- \setbox\framebox\hbox{\dorotatebox\@@localorientation\hbox{\box\framebox}}}
-
-%D The last conditional takes care of the special situation of
-%D in||line \inframed[height=3cm]{framed} boxes. Such boxes have
-%D to be \inframed{aligned} with the running text.
-
-\def\doinframed[#1]% we could omit #1] but readibility ...
- {\framed[\c!location=\v!low,#1]}
-
-\unexpanded\def\inframed
- {\dosingleempty\doinframed}
-
-%D When we set \type{empty} to \type{yes}, we get
-%D ourselves a frame and/or background, but no content, so
-%D actually we have a sort of phantom framed box.
-
-%D Because color marks and specials can interfere with
-%D spacing, we provide a way to specify a foregroundcolor.
-
-\def\docolorframebox
- {\doifvaluesomething{\@@framed\c!foregroundcolor}
- {\doifcolorelse{\framedparameter\c!foregroundcolor}
- {\setbox\framebox\hbox
- {\localcolortrue
- \color[\framedparameter\c!foregroundcolor]{\box\framebox}}}
- {}}}
-
-%D \macros
-%D {mframed, minframed}
-%D
-%D When Tobias asked how to frame mathematical elements in
-%D formulas, Taco's posted the next macro:
-%D
-%D \starttyping
-%D \def\mframed#1%
-%D {\relax
-%D \ifmmode
-%D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}%
-%D \else
-%D \framed{$#1$}%
-%D \fi}
-%D \stoptyping
-%D
-%D Because \type {\ifinner} does not (always) reports what
-%D one would expect, we move the test to the outer level. We
-%D also want to pass arguments,
-%D
-%D \starttyping
-%D \def\mframed%
-%D {\dosingleempty\domframed}
-%D
-%D \def\domframed[#1]#2% % tzt \dowithnextmathbox ?
-%D {\relax
-%D \ifmmode
-%D \ifinner
-%D \inframed[#1]{$#2$}%
-%D \else
-%D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}%
-%D \fi
-%D \else
-%D \inframed[#1]{$#2$}%
-%D \fi}
-%D \stoptyping
-%D
-%D Still better is the next alternative, if only because it
-%D takes care of setting the super- and subscripts styles
-
-\ifx\restoremathstyle\undefined \let\restoremathstyle\relax \fi
-
-\def\domframed[#1][#2]#3%
- {\begingroup
- \ifmmode
- \ifinner
- \let\mframedstyle\restoremathstyle
- \else
- \let\mframedstyle\displaystyle
- \fi
- \else
- \let\mframedstyle\restoremathstyle
- \fi
- #1\ifdone
- \def\normalstrut{$\mframedstyle\vphantom($}%
- \framed
- [\c!frameoffset=\@@oioffset,\c!offset=\v!overlay,#2]
- {$\mframedstyle#3$}%
- \else
- \inframed
- [#2]
- {$\mframedstyle#3$}%
- \fi
- \endgroup}
-
-\def\mframed
- {\dodoubleempty\domframed[\donetrue]}
-
-\def\inmframed
- {\dodoubleempty\domframed[\donefalse]}
-
-%D So instead of the rather versatile \type {\framed}, we ue
-%D the \type {\mframed}.
-%D
-%D \startbuffer
-%D \startformula
-%D x \times \mframed{y} \times y^{z_z}
-%D x \times \inmframed{y} \times y^{z_z}
-%D \stopformula
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \getbuffer
-%D
-%D However, we got into troubles when we want to nest sub- and
-%D superscripts, like in
-%D
-%D \startbuffer
-%D \startformula
-%D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}}
-%D \stopformula
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \getbuffer
-%D
-%D Therefore, we can best use \type {\super} and \type {\suber}
-%D instead of \type {^} and \type {_}. Both commands take care
-%D of proper font switching.
-%D
-%D \startbuffer
-%D \startformula
-%D x \times \mframed{y} \times y\super{\mframed{z}\suber{\mframed{z}}}
-%D \stopformula
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \getbuffer
-%D
-%D As usual, one can specify in what way the text should be
-%D framed. One should be aware of the fact that, inorder to
-%D preserve the proper spacing, the \type {offset} is set to
-%D \type {overlay} and \type {frameoffset} is used used
-%D instead.
-%D
-%D \startbuffer
-%D \startformula
-%D x \times y\super{\mframed[framecolor=red]{z}\suber{z}}
-%D \stopformula
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \getbuffer
-%D
-%D For inline use, we also provide the \type {\inmframed}
-%D alternative: we want $x \times \inmframed{y}$ in inline
-%D math, right?
-
-%D This previous framing macros needs a lot of alternatives for
-%D putting rules around boxes, inserting offsets and aligning
-%D text. Each step is handled by separate macros.
-
-\def\dowidenframebox#1%
- {\setbox\framebox\vbox
- {\kern#1\hbox{\kern#1\box\framebox\kern#1}\kern#1}}
-
-\def\dooffsetframebox{\dowidenframebox\localoffset}
-\def\dolocateframebox{\dowidenframebox\ruledlinewidth}
-
-%D Let's hope that the next few examples show us enough of
-%D what needs to be done by the auxiliary macros.
-%D
-%D \startbuffer
-%D \framed[height=1cm,offset=.5cm] {rule based learning}
-%D \framed[height=1cm,offset=0cm] {rule based learning}
-%D \framed[height=1cm,offset=none] {rule based learning}
-%D \framed[height=1cm,offset=overlay]{rule based learning}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection
-%D \hbox{\getbuffer}
-%D \stoplinecorrection
-%D
-%D \startbuffer
-%D \framed[offset=.5cm] {rule based learning}
-%D \framed[offset=0cm] {rule based learning}
-%D \framed[offset=none] {rule based learning}
-%D \framed[offset=overlay]{rule based learning}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection
-%D \hbox{\getbuffer}
-%D \stoplinecorrection
-%D
-%D \startbuffer
-%D \framed[strut=nee,offset=.5cm] {rule based learning}
-%D \framed[strut=nee,offset=0cm] {rule based learning}
-%D \framed[strut=nee,offset=none] {rule based learning}
-%D \framed[strut=nee,offset=overlay]{rule based learning}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection
-%D \hbox{\getbuffer}
-%D \stoplinecorrection
-%D
-%D \startbuffer
-%D \framed[width=3cm,align=left] {rule\\based\\learning}
-%D \framed[width=3cm,align=middle] {rule\\based\\learning}
-%D \framed[width=3cm,align=right] {rule\\based\\learning}
-%D \framed[width=fit,align=middle] {rule\\based\\learning}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection
-%D \hbox{\dontcomplain\getbuffer}
-%D \stoplinecorrection
-%D
-%D So now we're ready for the complicated stuff. We distinguish
-%D between borders with straight lines and those with round
-%D corners. When using the first alternative it is possible to
-%D turn off one or more lines. More fancy shapes are also
-%D possible by specifying dedicated backgrounds. Turning lines
-%D on and off is implemented as efficient as possible and as a
-%D result is interface language dependant. This next
-%D implementation evolved from simpler ones. It puts for
-%D instance the rules on top of the content and provides
-%D additional offset capabilities. The lot of calls to other
-%D macros makes this mechanism not that easy to comprehend.
-
-%D Getting the backgrounds right takes less code. Again we
-%D have to take care of additional offsets.
-
-\def\dobackedbox
- {\doifelsevalue{\@@framed\c!backgroundoffset}\v!frame % new
- {\dobackgroundbox\c!frameoffset}
- {\dobackgroundbox\c!backgroundoffset}}
-
-%D We handle left, right or middle alignment as well as fixed
-%D or free widths and heights. Each combination gets its own
-%D macro.
-
-%D The following code handles one-liners: \type{align={line,flushright}}.
-%D Beware, since we entered a group and either or not grab the next
-%D bgroup token, we need to finish the group in the oneliner mode.
-
-\ifx\raggedoneliner\undefined \chardef\raggedoneliner\zerocount \fi
-
-\def\doformatonelinerbox % beware: assumes explicit preceding bgroup
- {\ifcase\raggedoneliner
- \expandafter\nodoformatonelinerbox
- \else
- \expandafter\dodoformatonelinerbox
- \fi}
-
-\def\dodoformatonelinerbox
- {\dowithnextboxcontent
- {\ignorespaces}
- {\hbox to \hsize
- {\ifcase\raggedstatus\or\hss\or\hss\fi
- \unhbox\nextbox \removeunwantedspaces
- \ifcase\raggedstatus\or \or\hss\or\hss\fi}%
- \egroup}
- \hbox}
-
-\def\nodoformatonelinerbox % grabs {
- {\let\next=}
-
-%D The handlers:
-
-\def\doformatboxSomeFormat
- {\vbox to \!!framedheight
- \bgroup
- \let\postprocessframebox\relax
- \forgetall
- \oninterlineskip
- \hsize\!!framedwidth
- \vsize\!!framedheight
- \doframedsetups
- \raggedcommand
- \dobeforeframedbox
- \bgroup
- \localbegstrut
- \aftergroup\localendstrut
- \aftergroup\doafterframedbox
- \aftergroup\egroup
- \doformatonelinerbox}
-
-\def\doformatboxNoFormat
- {\vbox to \!!framedheight
- \bgroup
- \let\postprocessframebox\relax
- \forgetall
- \oninterlineskip
- \hsize\!!framedwidth
- \vsize\!!framedheight
- \doframedsetups
- \raggedcenter
- \vss
- \bgroup
- \localbegstrut
- \aftergroup\localendstrut
- \aftergroup\vss
- \aftergroup\egroup
- \doformatonelinerbox}
-
-\def\doformatboxHeight
- {\vbox to \!!framedheight
- \bgroup
- \let\postprocessframebox\relax
- \forgetall
- \oninterlineskip
- \doframedsetups
- \raggedcommand
- \vss
- \bgroup
- \aftergroup\localendstrut
- \aftergroup\vss
- \aftergroup\egroup
- \localbegstrut
- \doformatonelinerbox}
-
-\def\doformatboxWidth
- {\vbox
- \bgroup
- \let\postprocessframebox\relax
- \forgetall
- \oninterlineskip
- \hsize\!!framedwidth
- \doframedsetups
- \raggedcommand
- \dobeforeframedbox
- \bgroup
- \localbegstrut
- \aftergroup\localendstrut
- \aftergroup\doafterframedbox
- \aftergroup\egroup
- \doformatonelinerbox}
-
-\def\doformatboxVSize
- {\vbox to \!!framedheight
- \bgroup
- \let\postprocessframebox\relax
- \forgetall
- \vsize\!!framedheight
- \doframedsetups
- \vss
- \bgroup
- \aftergroup\vss
- \aftergroup\egroup
- \hbox
- \bgroup
- \aftergroup\egroup
- \localstrut
- \doformatonelinerbox}
-
-\def\doformatboxHSize
- {\hbox to \!!framedwidth
- \bgroup
- \let\postprocessframebox\relax
- \forgetall
- \doframedsetups
- \hss
- \localstrut
- \bgroup
- \aftergroup\hss
- \aftergroup\egroup
- \doformatonelinerbox}
-
-\def\doformatboxNoSize
- {\hbox
- \bgroup
- \let\postprocessframebox\relax
- \doframedsetups
- \localstrut
- \doformatonelinerbox}
-
-\let\doframedsetups\relax
-
-%D On the next page we show some examples of how these macros
-%D come into action. The examples show us how
-%D \type {fit}, \type {broad} dimensions influence the
-%D formatting. Watch the visualized struts. \footnote {Here we
-%D used \type {\showstruts}.}
-%D
-%D \startpostponing
-%D \bgroup
-%D \showstruts
-%D \dontcomplain
-%D \startlinecorrection
-%D \halign{#\enskip&#\enskip&#\enskip&#\enskip&#\enskip&#\cr
-%D \framed[width=.2\hsize, height=.2\hsize, align=] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=broad, align=] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=fit, align=] {a\par b\par c}&
-%D \framed[width=fit, height=.2\hsize, align=] {a\par b\par c}&
-%D \framed[width=fit, height=broad, align=] {a\par b\par c}&
-%D \framed[width=fit, height=fit, align=] {a\par b\par c}\cr
-%D \noalign{\vskip1em}
-%D \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=broad, align=yes] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=fit, align=yes] {a\par b\par c}&
-%D \framed[width=fit, height=.2\hsize, align=yes] {a\par b\par c}&
-%D \framed[width=fit, height=broad, align=yes] {a\par b\par c}&
-%D \framed[width=fit, height=fit, align=yes] {a\par b\par c}\cr
-%D \noalign{\vskip1em}
-%D \framed[width=.2\hsize, height=.2\hsize, align=right] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=broad, align=right] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=fit, align=right] {a\par b\par c}&
-%D \framed[width=fit, height=.2\hsize, align=right] {a\par b\par c}&
-%D \framed[width=fit, height=broad, align=right] {a\par b\par c}&
-%D \framed[width=fit, height=fit, align=right] {a\par b\par c}\cr
-%D \noalign{\vskip1em}
-%D \framed[width=.2\hsize, height=.2\hsize, align=left] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=broad, align=left] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=fit, align=left] {a\par b\par c}&
-%D \framed[width=fit, height=.2\hsize, align=left] {a\par b\par c}&
-%D \framed[width=fit, height=broad, align=left] {a\par b\par c}&
-%D \framed[width=fit, height=fit, align=left] {a\par b\par c}\cr
-%D \noalign{\vskip1em}
-%D \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=broad, align=middle] {a\par b\par c}&
-%D \framed[width=.2\hsize, height=fit, align=middle] {a\par b\par c}&
-%D \framed[width=fit, height=.2\hsize, align=middle] {a\par b\par c}&
-%D \framed[width=fit, height=broad, align=middle] {a\par b\par c}&
-%D \framed[width=fit, height=fit, align=middle] {a\par b\par c}\cr}
-%D \stoplinecorrection
-%D \blank[2*big]
-%D \egroup
-%D \stoppostponing
-
-%D \macros
-%D {framednoflines, framedlastlength}
-%D
-%D It is possible to let the frame macro calculate the width
-%D of a centered box automatically (\type {fit}). When
-%D doing so, we need to reshape the box:
-
-% The next implementation is frozen! It preserves the depth,
-% otherwise we get problems with framed display math and auto
-% width.
-
-\newcount\framednoflines
-\newdimen\framedlastlength
-
-\def\resetshapeframebox
- {\framednoflines \zerocount
- \framedlastlength\zeropoint}
-
-\let\framedboxwidth \!!zeropoint
-\let\framedboxheight\!!zeropoint
-\let\framedboxdepth \!!zeropoint
-
-\chardef\reshapeframeboxmethod\plusone % 0=no flush, 1=old method 2=no depth messing
-
-%D The two variables \type {\framednoflines} and \type
-%D {\framedlastlength} can be used in a second pass to
-%D optimized framed material.
-
-% torture test / strange case (much depth) / method 2 needed
-%
-% \startTEXpage[frame=on]
-% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
-% test outside formula
-% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
-% \blank[big]
-% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
-% test outside formula
-% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
-% \stopTEXpage
-
-%D The examples on the next page show how one can give the
-%D frame as well as the background an additional offset and
-%D even a bit more depth. The blue outline is the frame, the
-%D red box is the background and the small black outline is the
-%D visualization of the resulting box, that is, we applied
-%D \type{\ruledhbox} to the result.
-
-%D \startpostponing
-%D \bgroup
-%D \unprotect
-%D \dontcomplain
-%D
-%D \startbuffer
-%D \vbox to \vsize
-%D \bgroup
-%D \startalignment[middle]
-%D \vss
-%D \leavevmode\vbox to .8\vsize
-%D \bgroup
-%D \hsize=300pt
-%D \setupframed
-%D [background=color,
-%D backgroundcolorachtergrondkleur=darkred,
-%D width=300pt,
-%D height=60pt,
-%D framecolorkaderkleur=DemoBlue,
-%D rulethickness=2pt]
-%D \def\status%
-%D {backgroundoffset=\framedparameter\c!backgroundoffset\\
-%D frameoffset=\framedparameter\c!frameoffset\\
-%D depth=\framedparameter\c!depth}
-%D \leavevmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}}
-%D \vss
-%D \leavevmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}}
-%D \vss
-%D \leavevmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}}
-%D \vss
-%D \leavevmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}}
-%D \vss
-%D \leavevmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}}
-%D \vss
-%D \leavevmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}}
-%D \egroup
-%D \vss
-%D \stopalignment
-%D \egroup
-%D \stopbuffer
-%D
-%D \getbuffer \page
-%D
-%D {\setupframed[depth=4pt]\getbuffer} \page
-%D
-%D \protect
-%D \egroup
-%D \stoppostponing
-
-%D When typesetting the framed box inline, we have to keep the
-%D baseline intact outside as well as inside the framed box.
-
-\def\doinlineframedbox
- {\scratchdimen\dimexpr\strutdp+\ruledlinewidth\relax
- \ifboxhasoffset
- \advance\scratchdimen \framedparameter\c!offset
- \fi
- \setbox\framebox\hbox{\lower\scratchdimen\box\framebox}%
- \ht\framebox\strutht
- \dp\framebox\strutdp
- \box\framebox}
-
-%D We can also lower the box over the natural depth of the
-%D line.
-
-\def\doloweredframedbox
- {\ht\framebox\dimexpr\ht\framebox+\dp\framebox-\strutdp\relax
- \dp\framebox\strutdp
- \box\framebox}
-
-%D Hanging the content is mainly meant for cases like the
-%D following:
-%D
-%D \starttyping
-%D \framed[strut=no]
-%D {\framed[height=2cm,location=hanging]{test}%
-%D \framed[height=1cm,location=hanging]{test}}
-%D \stoptyping
-
-\def\dohangingframedbox % best with strut=no
- {\scratchdimen\dimexpr\ht\framebox+\dp\framebox\relax
- \ht\framebox\zeropoint
- \dp\framebox\scratchdimen}
-
-%D We can draw lines from left to right and top to bottom by
-%D using the normal \type{\hairline} command. Both directions
-%D need a different treatment.
-%D
-%D \startbuffer
-%D \framed[width=4cm] {alfa\hairline beta\hairline gamma}
-%D \framed[height=2cm] {alfa\hairline beta\hairline gamma}
-%D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection
-%D \hbox{\getbuffer}
-%D \stoplinecorrection
-%D
-%D These macros try to adapt their behaviour as good as
-%D possible to the circumstances and act as natural as
-%D possible.
-
-\def\vboxedhairline
- {\bgroup
- \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi
- \dimen4=\dimexpr\dimen2+\ruledlinewidth\relax
- \setbox0\vbox
- {\advance\hsize 2\dimen4
- \vskip\dimen2
- \hrule
- \!!height\ruledlinewidth
- \!!depth\zeropoint
- \!!width\hsize
- \vskip\dimen2}%
- %\endgraf\nointerlineskip\endgraf
- %\moveleft\dimen4\box0
- %\endgraf\nointerlineskip\localbegstrut
- \endgraf\obeydepth\nointerlineskip
- \moveleft\dimen4\box0
- \endgraf\nointerlineskip\localbegstrut % beware, we might kill it in a style using \vskip\lineheight
- \egroup} % so this must not be changed
-
-\def\hboxedhairline % use framed dimen
- {\bgroup
- \dimen2=\ifboxhasoffset \localoffset \else \zeropoint \fi
- \ifboxhasheight
- \dimen4\dimexpr\localheight/2+\strutdp-2\ruledlinewidth\relax
- \dimen6\dimexpr\localheight/2-\strutdp+2\ruledlinewidth\relax
- \else
- \dimen4\dimexpr\strutht+\dimen2\relax
- \dimen6\dimexpr\strutdp+\dimen2\relax
- \fi
- \unskip
- \setbox\scratchbox\hbox
- {\hskip\dimen2
- \vrule\!!height\dimen4\!!depth\dimen6\!!width\ruledlinewidth
- \hskip\dimen2}%
- \ht\scratchbox\strutht
- \dp\scratchbox\strutdp
- \box\scratchbox
- \ignorespaces
- \egroup}
-
-%D The argument of the frame command accepts \type{\\} as a
-%D sort of newline signal. In horizontal boxes it expands to a
-%D space.
-
-\def\vboxednewline
- {\endgraf\ignorespaces}
-
-\def\hboxednewline
- {\unskip\normalspace\ignorespaces}
-
-%D We can set each rule on or off. The default setting is
-%D inherited from \type{frame}. An earlier implementation
-%D use a bit different approach, but the new one seems more
-%D natural:
-%D
-%D \bgroup
-%D \setuptyping[margin=0pt]
-%D \startlinecorrection
-%D \startbuffer
-%D \framed[offset=overlay,frame=on]{\darkred\blackrule}
-%D \stopbuffer
-%D \hbox{\getbuffer\vbox{\typebuffer}}
-%D
-%D \startbuffer
-%D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule}
-%D \stopbuffer
-%D \hbox{\getbuffer\vbox{\typebuffer}}
-%D
-%D \startbuffer
-%D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule}
-%D \stopbuffer
-%D \hbox{\getbuffer\vbox{\typebuffer}}
-%D
-%D \startbuffer
-%D \framed[offset=overlay,frame=off]{\darkred\blackrule}
-%D \stopbuffer
-%D \hbox{\getbuffer\vbox{\typebuffer}}
-%D
-%D \startbuffer
-%D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule}
-%D \stopbuffer
-%D \hbox{\getbuffer\vbox{\typebuffer}}
-%D
-%D \startbuffer
-%D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule}
-%D \stopbuffer
-%D \hbox{\getbuffer\vbox{\typebuffer}}
-%D \stoplinecorrection
-%D \egroup
-
-%D \macros
-%D {setupblackrules}
-%D
-%D The graphic capabilities of \TEX\ do not go beyond simple
-%D filled rules, except of course when using specials. Let's
-%D start with a warning: using this commands is far more slower
-%D than using the \TEX\ primitives \type{\hrule} and
-%D \type{\vrule}, but they save us some tokens. The
-%D characteristics of these rule drawing command can be set by:
-%D
-%D \showsetup{setupblackrules}
-
-\def\setupblackrules
- {\dodoubleargument\getparameters[\??bj]}
-
-%D \macros
-%D {blackrule}
-%D
-%D The simple command draws only one rule. Its optional
-%D argument can be used to specify the dimensions. By setting
-%D the width, height or depth to \type {max}, one gets the
-%D natural dimensions.
-%D
-%D \showsetup{blackrule}
-
-\def\doblackrule[#1]%
- {\hbox\bgroup
- \getparameters[\??bj][#1]%
- \setstrut
- \doif\@@bjwidth \v!max{\def\@@bjwidth {1em}}%
- \doif\@@bjheight\v!max{\def\@@bjheight{\strutht}}%
- \doif\@@bjdepth \v!max{\def\@@bjdepth {\strutdp}}%
- \localstartcolor[\@@bjcolor]%
- \vrule
- \!!width \@@bjwidth
- \!!height\@@bjheight
- \!!depth \@@bjdepth
- \localstopcolor
- \egroup}
-
-\unexpanded\def\blackrule
- {\dosingleempty\doblackrule}
-
-%D \macros
-%D {blackrules}
-%D
-%D One can call for a sequence of black rules, if needed
-%D equally spaced over the given width.
-%D
-%D \showsetup{blackrules}
-%D
-%D The two alternative calls are therefore:
-%D
-%D \startbuffer
-%D Tell me, is this according to the \blackrules[n=6]?
-%D These \blackrules[alternativevariant=b,n=10,distance=.2em,width=4cm] are quite clear.
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D or:
-%D
-%D \startvoorbeeld
-%D \startlines
-%D \getbuffer
-%D \stoplines
-%D \stopvoorbeeld
-%D
-%D We could of course have implemented this macro using
-%D \type{\leaders}, but this would probably have taken more
-%D tokens.
-
-\def\doblackrules[#1]%
- {\hbox\bgroup
- \getparameters[\??bj][#1]%
- \!!widtha\@@bjwidth
- \!!widthb\@@bjdistance
- \doif\@@bjalternative\c!b
- {\scratchcounter\@@bjn
- \ifnum\scratchcounter=\plusone
- \!!widthb\zeropoint
- \else
- \advance\scratchcounter \minusone
- \advance\!!widtha -\scratchcounter\!!widthb
- \divide \!!widtha \@@bjn
- \fi}%
- \localstartcolor[\@@bjcolor]%
- \dorecurse\@@bjn
- {\vrule
- \!!width \!!widtha
- \!!height\@@bjheight
- \!!depth \@@bjdepth
- \hskip\!!widthb}%
- \unskip
- \localstopcolor
- \egroup}
-
-\unexpanded\def\blackrules
- {\dosingleempty\doblackrules}
-
-%D The next commands can be used to draw margin rules. We
-%D support two methods: \marginrule{one for in||line use} and
-%D one that acts on a paragraph. Drawing a margin rule is
-%D rather straightforward because we can use the commands that
-%D put text in the margin.
-
-\def\dodrawmarginrule
- {\setbox\scratchbox\hbox
- {\vrule\!!depth\strutdepth\!!height\strutheight\!!width\@@karulethickness}%
- \smashbox\scratchbox % no \vsmash !!!
- \box\scratchbox}
-
-\def\drawmarginrule
- {\strut\inleft{\dodrawmarginrule}}
-
-%D \macros
-%D {marginrule}
-%D
-%D The first method gobbles words and simply puts a bar in the
-%D margin. This method is not entirely robust.
-%D
-%D \showsetup{marginrule}
-
-\definecomplexorsimple\marginrule
-
-\def\simplemarginrule
- {\let\processword\drawmarginrule
- \processwords}
-
-\def\complexmarginrule[#1]%
- {\ifnum#1<\@@kalevel\relax \else
- \def\@@kadefaultwidth{#1}%
- \expandafter\simplemarginrule
- \fi}
-
-%D We need an auxiliary variable
-
-\def\@@kadefaultwidth{1}
-
-%D \macros
-%D {setupmarginrules}
-%D
-%D This macro definitions show us that we can pass an optional
-%D level, which is matched against the previous set one. The
-%D level can be set up with
-%D
-%D \showsetup{setupmarginrules}
-
-\def\setupmarginrules
- {\dodoubleargument\getparameters[\??ka]}
-
-%D \macros
-%D {startmarginrule}
-%D
-%D The second method collects text and reformats it afterwards,
-%D using the shapebox macros. We prevent local margin rules.
-%D
-%D \showsetup{startmarginrule}
-
-\definecomplexorsimple\startmarginrule
-
-\def\simplestartmarginrule
- {\bgroup
- \let\drawmarginrule\relax
- \let\stopmarginrule\dostopmarginrule
- \beginofshapebox}
-
-\def\complexstartmarginrule[#1]%
- {\bgroup
- \let\drawmarginrule\relax
- \ifnum#1<\@@kalevel\relax
- \let\stopmarginrule\egroup
- \else
- \def\@@kadefaultwidth{#1}%
- \let\stopmarginrule\dostopmarginrule
- \expandafter\beginofshapebox
- \fi}
-
-\def\dostopmarginrule
- {\endofshapebox
- \reshapebox
- {\hbox{\inleftmargin{\dodrawmarginrule}\box\shapebox}}%
- \flushshapebox
- \egroup}
-
-%D \startbuffer
-%D \setupmarginrules[level=5]
-%D
-%D \startmarginrule[1]
-%D First we set the level at~5. Next we typeset this first
-%D paragraph as a level~1 one. As expected no rule show up.
-%D \stopmarginrule
-%D
-%D \startmarginrule[5]
-%D The second paragraph is a level~5 one. As we can see here,
-%D the marginal rule gets a width according to its level.
-%D \stopmarginrule
-%D
-%D \startmarginrule[8]
-%D It will of course be no surprise that this third paragraph
-%D has a even thicker margin rule. This behavior can be
-%D overruled by specifying the width explictly.
-%D \stopmarginrule
-%D \stopbuffer
-%D
-%D In next example we show most features. Watch the rule
-%D thickness adapting itself to the level.
-%D
-%D \startvoorbeeld
-%D \getbuffer
-%D \stopvoorbeeld
-%D
-%D We just said:
-%D
-%D \typebuffer
-
-%D \macros
-%D {vl, hl}
-%D
-%D The command \type{\vl} draws a vertical rule \vl\ with strut
-%D dimensions, multiplied with the factor specified in the
-%D optional argument. The height and depth are clipped \vl[3]
-%D to the baselinedistance. Its horizontal counterpart
-%D \type{\hl} draws a horizontal rule \hl\ with a width of 1em,
-%D multiplied with the optional factor. The horizontal rule is
-%D drawn on top of the baseline.
-%D
-%D \showsetup{vl}
-%D \showsetup{hl}
-
-\def\complexvl[#1]%
- {\bgroup
- \!!dimena#1\strutht
- \!!dimenb#1\strutdp
- \setbox\scratchbox\hbox
- {\vrule
- \!!width \linewidth
- \!!height\!!dimena
- \!!depth \!!dimenb}%
- \dp\scratchbox\strutdp
- \ht\scratchbox\strutht
- \box\scratchbox
- \egroup}
-
-\def\complexhl[#1]%
- {\hbox
- {\vrule
- \!!width #1\s!em
- \!!height\linewidth
- \!!depth \zeropoint}}
-
-\definecomplexorsimple\vl \def\simplevl{\complexvl[1]}
-\definecomplexorsimple\hl \def\simplehl{\complexhl[1]}
-
-%D \macros
-%D {hairline, thinrule, thinrules, setupthinrules}
-%D
-%D Drawing thin lines can of course easily be accomplished by
-%D the \TEX\ primitives \type{\hrule} and \type{\vrule}. The
-%D next few macros however free us from some specifications.
-%D
-%D \startbuffer
-%D some text
-%D
-%D \hairline
-%D
-%D some more text
-%D
-%D \thinrule
-%D
-%D more and more text
-%D
-%D hi \thinrule\ there
-%D
-%D and then the final text
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D becomes
-%D
-%D \startvoorbeeld
-%D \getbuffer
-%D \stopvoorbeeld
-%D
-%D So we've got
-%D
-%D \showsetup{hairline}
-%D \showsetup{thinrule}
-%D
-%D Both can be set up with:
-%D
-%D \showsetup{setupthinrules}
-%D
-%D We also have
-%D
-%D \showsetup{thinrules}
-%D
-%D which looks like: \thinrules[n=2]
-
-\def\thinrule
- {\strut
- \bgroup
- \chardef\ruletype\plusone
- \processaction
- [\@@dlalternative]
- [ \v!a=>\chardef\ruletype0,% no line
- %\v!b=>\chardef\ruletype1,% height/depth
- \v!c=>\chardef\ruletype2,% topheight/botdepth
- % 11=>\chardef\ruletype1,% fallback for backgrounds
- 0=>\chardef\ruletype0,% compatible with backgrounds
- % 1=>\chardef\ruletype1,% compatible with backgrounds
- 2=>\chardef\ruletype2]% compatible with backgrounds
- \doifsomething\@@dlrulethickness
- {\linewidth\@@dlrulethickness}%
- \ifdim\linewidth=\zeropoint
- \chardef\ruletype\zerocount
- \else
- \doifnot\@@dlframe\v!on{\chardef\ruletype\zerocount}%
- \fi
- \ifnum\ruletype=\plusone
- \doif\@@dlheight\v!max{\let\@@dlheight\!!plusone}%
- \doif\@@dldepth \v!max{\let\@@dldepth \!!plusone}%
- \else
- \let\@@dlheight\!!plusone
- \let\@@dldepth\!!plusone
- \fi
- \freezedimensionwithunit\@@dlheight\strutht
- \freezedimensionwithunit\@@dldepth\strutdp
- \divide\linewidth \plustwo
- \doifelse\@@dlbackground\v!color
- {\startcolor[\@@dlbackgroundcolor]%
- \ifnum\ruletype=\plustwo % prevent overshoot due to rounding
- \leaders
- \hrule
- \!!height\dimexpr\@@dlheight-.5\linewidth\relax
- \!!depth \dimexpr\@@dldepth -.5\linewidth\relax
- \hfill
- \else
- \leaders
- \hrule
- \!!height\@@dlheight
- \!!depth \@@dldepth
- \hfill
- \fi
- \stopcolor
- \ifcase\ruletype
- % no rule
- \or
- \startcolor[\@@dlcolor]%
- \hfillneg
- \leaders\hrule\!!height\linewidth\!!depth\linewidth\hfill
- \stopcolor
- \or
- \startcolor[\@@dlcolor]%
- \hfillneg\leaders\hrule\!!height\dimexpr-\@@dldepth+\linewidth\relax\!!depth\@@dldepth\hfill
- \hfillneg\leaders\hrule\!!height\@@dlheight\!!depth\dimexpr-\@@dlheight+\linewidth\relax\hfill
- \stopcolor
- \fi}
- {\ifcase\ruletype \else
- \startcolor[\@@dlcolor]%
- \leaders\hrule\!!height\@@dlheight\!!depth\@@dldepth\hfill
- \stopcolor
- \fi}%
- \strut
- \carryoverpar\egroup}
-
-\def\hairline
- {\endgraf
- \thinrule
- \endgraf}
-
-\def\dosetupthinrules[#1]%
- {\getparameters[\??dl][#1]}
-
-\def\setupthinrules
- {\dosingleargument\dosetupthinrules}
-
-\def\dothinrules[#1]%
- {\bgroup
- \dosetupthinrules[#1]%
- \@@dlbefore
- \assignvalue\@@dlinterlinespace\@@dlinterlinespace{1.0}{1.5}{2.0}%
- \spacing\@@dlinterlinespace
- \dorecurse\@@dln
- {\ifnum\recurselevel=\@@dln \dothinrulesnobreak \else
- \ifnum\recurselevel=2 \dothinrulesnobreak \fi\fi
- \thinrule
- \ifnum\recurselevel<\@@dln\relax
- % test needed, else messed up whitespace
- \ifx\@@dlinbetween\empty
- \softbreak
- \else
- \endgraf
- \nowhitespace
- \@@dlinbetween
- \fi
- \fi}%
- \doifelsenothing\@@dlafter
- {\carryoverpar\egroup}
- {\@@dlafter\egroup}}
-
-\def\thinrules
- {\dosingleempty\dothinrules}
-
-%D A couple of examples are given below.
-%D
-%D \startbuffer
-%D \setupthinrules[n=3,inbetween=,color=gray]
-%D
-%D test test \thinrules\ test test \par
-%D test test \thinrules [color=green] test test \par
-%D test test \thinrules [height=max, depth=max] test test \par
-%D
-%D \setupthinrules[height=.9,depth=.9]
-%D
-%D test test \thinrules\ test test \par
-%D test test \thinrules [alternativevariant=b] test test \par
-%D test test \thinrules [alternativevariant=c] test test \par
-%D test test \thinrules [alternativevariant=c,inbetween=\vskip2ex] test test \par
-%D \stopbuffer
-%D
-%D \typebuffer {\getbuffer}
-%D
-%D There are a couple of alternative ways to visualize rules
-%D using backgrounds. At first sight these may look strange,
-%D but they make sense in educational settings. The
-%D alternatives are more or less compatible with the more
-%D advanced \METAPOST\ based implementation.
-%D
-%D \startbuffer[a]
-%D \setupthinrules
-%D [n=2,
-%D backgroundcolor=gray ,
-%D rulethickness=1pt,
-%D colorkleur=donkerblauw,
-%D after=\blank,
-%D before=\blank]
-%D \stopbuffer
-%D
-%D \typebuffer[a]
-%D
-%D \startbuffer[b]
-%D \thinrules[alternativevariant=a]
-%D \thinrules[alternativevariant=b]
-%D \thinrules[alternativevariant=c]
-%D \stopbuffer
-%D
-%D \typebuffer[b] \getbuffer[a,b]
-%D
-%D \startbuffer[b]
-%D \thinrules[alternativevariant=a,background=color]
-%D \thinrules[alternativevariant=b,background=color]
-%D \thinrules[alternativevariant=c,background=color]
-%D \stopbuffer
-%D
-%D \typebuffer[b] \getbuffer[a,b]
-%D
-%D \startbuffer[b]
-%D \thinrules[alternativevariant=a,height=.8,depth=.8,background=color]
-%D \thinrules[alternativevariant=b,height=.8,depth=.8,background=color]
-%D \thinrules[alternativevariant=c,height=.8,depth=.8,background=color]
-%D \stopbuffer
-%D
-%D \typebuffer[b] \getbuffer[a,b]
-
-%D \macros
-%D {optimizethinrules}
-%D
-%D By saying \type {\thinrulestrue} or \type {-false}, we
-%D can influence the way dangling lines are handled.
-
-\newif\ifoptimizethinrules \optimizethinrulestrue
-
-\def\dothinrulesnobreak
- {\ifoptimizethinrules\penalty500\fi}
-
-%D \macros
-%D {startframedtext, setupframedtexts, defineframedtext}
-%D
-%D The general framing command we discussed previously, is not
-%D entirely suited for what we call framed texts, as for
-%D instance used in intermezzo's. The next examples show what
-%D we have in mind.
-%D
-%D \startbuffer[framed-0]
-%D \setupframedtexts
-%D [frame=off,
-%D width=\hsize,
-%D background=screen]
-%D
-%D \startframedtext
-%D By default the framed text is centered \dots
-%D \stopframedtext
-%D
-%D \startframedtext[right]
-%D \dots\ but we can also align left, middle and right.
-%D \stopframedtext
-%D \stopbuffer
-%D
-%D \startbuffer[framed-1]
-%D \defineframedtext
-%D [Example]
-%D [width=6cm,
-%D height=5cm]
-%D
-%D \startExample
-%D \typebuffer[framed-1]
-%D \stopExample
-%D \stopbuffer
-%D
-%D \startbuffer[framed-2]
-%D \defineframedtext
-%D [Example]
-%D [width=6cm]
-%D
-%D \startExample
-%D \typebuffer[framed-2]
-%D \stopExample
-%D \stopbuffer
-%D
-%D \startbuffer[framed-3]
-%D \defineframedtext
-%D [Example]
-%D [height=5cm]
-%D
-%D \startExample
-%D \typebuffer[framed-3]
-%D \stopExample
-%D \stopbuffer
-%D
-%D \startbuffer[framed-4]
-%D \defineframedtext
-%D [Example]
-%D [width=fit,height=broad]
-%D
-%D \Example{a very exciting example}
-%D \stopbuffer
-%D
-%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup
-%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup
-%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup
-%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup
-%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup
-%D
-%D Here we can see that we have a predefined framed text class
-%D as well as the tools for defining our own. So we have:
-%D
-%D \showsetup{setupframedtexts}
-%D
-%D as well as the definition command:
-%D
-%D \showsetup{defineframedtext}
-%D
-%D that generates two commands:
-%D
-%D \showsetup{start<<framedtext>>}
-%D \showsetup{<<framedtext>>}
-%D
-%D The next definition shows the defaults.
-
-\def\dodefineframedtext[#1][#2]%
- {\presetlocalframed[\??kd#1]%
- \getparameters[\??kd#1]
- [\c!width=0.75\hsize,
- \c!height=\v!fit,
- \c!align=\v!yes,
- \c!top=,
- \c!bottom=\vfill,
- \c!offset=1em,
- \c!bodyfont=,
- \c!style=,
- \c!color=,
- \c!left=,
- \c!right=\hfill,
- \c!before=\blank,
- \c!after=\blank,
- \c!inner=,
- \c!frame=\v!on,
- \c!topframe=,
- \c!bottomframe=,
- \c!leftframe=,
- \c!rightframe=,
- \c!radius=.5\bodyfontsize,
- \c!corner=\v!rectangular,
- \c!foregroundcolor=,
- \c!foregroundstyle=,
- \c!background=,
- \c!backgroundcolor=,
- \c!backgroundscreen=\@@rsscreen,
- \c!linecorrection=\v!on,
- \c!depthcorrection=\v!on,
- \c!margin=\v!standard,
- \c!orientation=,
- \c!indenting=,
- #2]%
- \setvalue{\e!start#1}{\dostartframedtext[#1]}%
- \setvalue{\e!stop #1}{\dostopframedtext }%
- \setvalue {#1}{\doframedtext [#1]}}
-
-\def\defineframedtext
- {\dodoubleempty\dodefineframedtext}
-
-%D We define the general (and original) case by just saying:
-
-\defineframedtext[\v!framedtext]
-
-%D We need several steps before the actual job is done,
-%D because we have to handle an optional identifier (and
-%D because these commands evolved out of a single case).
-
-\def\framedtextparameter#1#2%
- {\csname\??kd#1#2\endcsname}
-
-\def\dosetupframedtexts[#1][#2]%
- {\ifsecondargument
- \def\docommand##1{\getparameters[\??kd##1][#2]}%
- \processcommacommand[#1]\docommand % new, #1 may be macro
- \else
- \getparameters[\??kd\v!framedtext][#1]%
- \fi}
-
-\def\setupframedtexts
- {\dodoubleempty\dosetupframedtexts}
-
-\def\dostartframedtext
- {\bgroup\dotripleempty\dodostartframedtext}
-
-\def\dodostartframedtext[#1][#2][#3]%
- {\doifassignmentelse{#2}
- {\dododostartframedtext[#1][][#2]}
- {\dododostartframedtext[#1][#2][#3]}}
-
-\setfalse\framedtextlocationnone
-
-\def\dododostartframedtext[#1][#2][#3]% #3 only passed to framed, not to framedtext
- {\doifsomething{#2}{\setvalue{\??kd#1\c!location}{#2}}% does not listen to #3
- \setfalse\framedtextlocationnone
- \processaction % \v!low en \v!depth are already taken !
- [\framedtextparameter{#1}\c!location]
- [ \v!left=>\letvalue{\??kd#1\c!left }\relax
- \letvalue{\??kd#1\c!right}\hfill,
- \v!right=>\letvalue{\??kd#1\c!left }\hfill
- \letvalue{\??kd#1\c!right}\relax,
- \v!middle=>\letvalue{\??kd#1\c!left }\hfill
- \letvalue{\??kd#1\c!right}\hfill,
- \v!none=>\letvalue{\??kd#1\c!left }\relax % new
- \letvalue{\??kd#1\c!right}\relax % new
- \settrue\framedtextlocationnone]%
- \letvalue{\??kd#1\c!location}\empty
- % removed 06/2001
- % \forgetparindent
- % added 06/2001 [see demo-bbv]
- \localhsize\hsize \checkframedtext
- % so far
- \setbox\framebox\vbox
- \startboxedcontent
- \hsize\localhsize
- % \insidefloattrue % ? better
- \expanded{\switchtobodyfont[\framedtextparameter{#1}\c!bodyfont]}%
- \startcolor[\framedtextparameter{#1}\c!color]%
- \localframed[\??kd#1][\c!strut=\v!no,#3]% todo: use delayedstrut
- \bgroup
- \let\\=\endgraf
- \framedtextparameter{#1}\c!inner % oud spul
- \doifvalue{\??kd#1\c!depthcorrection}\v!on % new, inside box
- {\bgroup
- \verticalstrut
- % we need \nowhitespace in case of setups setting whitespace
- % nb, not safe, text vs \vbox as next
- \vskip-\struttotal
- \nowhitespace % na vskip ! new 20/05/2004, fails with next content being box (\scale{..})
- }%
- \doinhibitblank % \blank[\v!disable]% plaatst signal
-\setupindenting[\framedtextparameter{#1}\c!indenting]%
- \doconvertfont{\framedtextparameter{#1}\c!style}\empty
- \def\dostopframedtext{\dodostopframedtext{#1}{#2}}}
-
-%D The \type {none} option is handy for nested usage, as
-%D in the presentation styles, where we don't want
-%D interference.
-
-\def\dodostopframedtext#1#2% % no \baselinecorrection, see faq docs
- {\endgraf
- \removelastskip
- \doifvalue{\??kd#1\c!depthcorrection}\v!on % local and global
- {\forgetall
- \vskip-\struttotal
- \verticalstrut
- \egroup
- \forgetall
- \vskip-\lineheight
- % will be an option, not default
- % \setbaselinecorrections
- % \donegbotbaselinecorrection
- \verticalstrut}
- \stopboxedcontent
- \stopcolor
- \ifconditional\framedtextlocationnone
- \egroup
- \box\framebox
- \else\ifinsidefloat
- \egroup
- \box\framebox
- \else
- \egroup
- \doplacement[\??kd#1][\c!depthcorrection=\v!off]{\box\framebox}%
- \fi\fi
- \egroup}
-
-%D Placement can be ignored:
-%D
-%D \starttyping
-%D \hbox to \hsize \bgroup
-%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext
-%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext
-%D \egroup
-%D
-%D \hbox to \hsize \bgroup
-%D \setupframedtexts[location=none]%
-%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext
-%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext
-%D \egroup
-%D \stoptyping
-
-%D The simple brace (or group) delimited case is typeset
-%D slightly different and is not aligned.
-
-\def\doframedtext
- {\bgroup\dodoubleempty\dodoframedtext}
-
-\def\dodoframedtext[#1][#2]% beware!
- {\expanded{\switchtobodyfont[\getvalue{\??kd#1\c!bodyfont}]}%
- \localframed[\??kd#1][\c!strut=\v!no,#2]%
- \bgroup
- \blank[\v!disable]%
- \let\\=\endgraf
- \getvalue{\??kd#1\c!inner}% % kleur naar outer level
- \dostartattributes{\??kd#1}\c!style\c!color\empty
- \bgroup
- \aftergroup\docloseframedtext
- \let\next=}
-
-\def\docloseframedtext
- {\removelastskip
- \dostopattributes
- \egroup
- \egroup}
-
-%D \macros
-%D {defineframed}
-%D
-%D One can also define simple framed texts, using:
-%D
-%D \showsetup{defineframed}
-
-\def\defineframed
- {\dodoubleempty\dodefineframed}
-
-\def\dodefineframed[#1][#2]%
- {\iffirstargument
- \setvalue{#1}{\dodoubleempty\doframed[#2]}%
- \fi}
-
-\def\doframed[#1][#2]%
- {\framed[#1,#2]}
-
-%D \macros
-%D {textrule, starttextrule, setuptextrules}
-%D
-%D Putting rules before and after a paragraph is very space
-%D sensitive, but the next command handles that quite well. It
-%D comes in two disguises:
-%D
-%D \startbuffer
-%D \textrule[top]{fragments}
-%D \input reich
-%D \textrule
-%D \stopbuffer
-%D
-%D \bgroup \typebuffer \getbuffer \egroup
-%D
-%D \startbuffer
-%D \setuptextrules
-%D [width=90pt,distance=12pt,rulecolor=blue,
-%D bodyfont=small,style=\sc,color=red]
-%D
-%D \starttextrule{Ship Building Tools}
-%D \nl \setuptolerance[tolerant] \input materie
-%D \stoptextrule
-%D \stopbuffer
-%D
-%D \bgroup \typebuffer \getbuffer \egroup
-%D
-%D \startbuffer
-%D \setuptextrules
-%D [location=inmargin,
-%D bodyfont=small,style=slantedbold]
-%D
-%D \starttextrule{wonderful}
-%D \input tufte
-%D \stoptextrule
-%D \stopbuffer
-%D
-%D \bgroup \typebuffer \getbuffer \egroup
-%D
-%D The formal definition of these commands is:
-%D
-%D \showsetup{textrule}
-%D \showsetup{starttextrule}
-%D \showsetup{setuptextrules}
-%D
-%D The implementation looks a bit complicated due to the
-%D optional arguments.
-
-\def\setuptextrules
- {\dodoubleargument\getparameters[\??tl]}
-
-\def\complextextrule[#1]% if needed we can make it installable
- {\let\next\dobottomtextrule
- \processaction
- [#1]
- [ \v!top=>\let\next\dotoptextrule,
- \v!middle=>\let\next\domiddletextrule,
- \v!bottom=>\let\next\dobottomtextrule]%
- \dosinglegroupempty\next}
-
-\definecomplexorsimple\textrule
-
-\def\simpletextrule
- {\dosinglegroupempty\dounknowntextrule}
-
-\def\docomplextextrule#1%
- {\bgroup
- \advance\hsize\dimexpr-\rightskip-\leftskip\relax
- \setbox\scratchbox\hbox to \hsize
- {\dimen4\dimexpr .5ex+.5\linewidth\relax
- \dimen6\dimexpr-.5ex+.5\linewidth\relax
- \doifnothing{#1}\firstargumentfalse
- \iffirstargument
- \doifelse\@@tllocation\v!inmargin
- {\llap{\doattributes\??tl\c!style\c!color{#1}\hskip\leftmargindistance}}
- {\color[\@@tlrulecolor]
- {\vrule\!!height\dimen4\!!depth\dimen6\!!width\@@tlwidth}%
- \hbox spread 2\dimexpr\@@tldistance\relax
- {\hss\doattributes\??tl\c!style\c!color{\strut#1}\hss}}%
- \fi
- \color[\@@tlrulecolor]
- {\leaders\hrule\!!height\dimen4\!!depth\dimen6\hfill}}%
- \ht\scratchbox\strutht
- \dp\scratchbox\strutdp
- \noindent\box\scratchbox
-%\nobreak\verticalstrut\kern-\struttotal
-% evt \witruimte
- \egroup}
-
-\def\dotoptextrule#1%
- {\page[\v!preference] % interferes
- %\whitespace % no
- \@@tlbefore
- \docomplextextrule{#1}%
-% todo, option: \doifnothing{#1}{\ruledvskip-.5ex}
- \nowhitespace
- \@@tlinbetween
- \endgraf}
-
-\def\dodobottomtextrule#1#2%
- {\ifhmode
- \endgraf
- \fi
- \dimen0\strutdp
- \ifdim\prevdepth>\strutdp\else % was <\strutdp
- \ifdim\prevdepth>\zeropoint
- \advance\dimen0 -\prevdepth
- \fi
- \fi
- \advance\dimen0 .5ex
- \vskip\dimen0
-% ==
-% \vskip\dimexpr \strutdp + .5ex
-% \ifdim\prevdepth>\strutdp\else\ifdim\prevdepth>\zeropoint-\prevdepth\fi\fi\relax
-%
- \@@tlinbetween
- \doifelsenothing{#2}
- {\bgroup
- \advance\hsize\dimexpr-\rightskip-\leftskip\relax
- \nointerlineskip
- \moveleft-\leftskip\vbox
- {\color[\@@tlrulecolor]
- {\hrule\!!depth\linewidth\!!height\zeropoint\!!width\hsize}}%
- \egroup}
- {\docomplextextrule{#2}}%
- \ifvmode\prevdepth\zeropoint\fi
- #1%
- \page[\v!preference]}
-
-\def\dobottomtextrule
- {\dodobottomtextrule\@@tlafter}
-
-\def\domiddletextrule
- {\dodobottomtextrule\@@tlinbetween}
-
-\def\dounknowntextrule
- {\iffirstargument
- \@EA\dotoptextrule
- \else
- \@EA\dobottomtextrule\@EA\empty
- \fi}
-
-%D The grouped commands also supports bodyfont switching:
-
-\def\starttextrule#1%
- {\bgroup
- \def\dounknowntextrule{\domiddletextrule}
- \dotoptextrule{#1}
- \bgroup
- \doifsomething\@@tlbodyfont{\switchtobodyfont[\@@tlbodyfont]}}
-
-\def\stoptextrule
- {\par
- \egroup
- \dobottomtextrule\empty
- \egroup}
-
-%D \macros
-%D {fillinrules, setupfillinrules}
-%D
-%D The next few commands do not really deserve a place in a
-%D core module, because they deal with specific typography.
-%D Nevertheless I decided to make them part of the core,
-%D because they permit us to make questionaires. Let's start
-%D with some examples.
-%D
-%D \fillinrules[n=2,width=fit]{first}
-%D \fillinrules[n=2,width=broad]{first}
-%D \fillinrules[n=2,width=3cm]{first}
-%D \fillinrules[n=2,width=3cm,distance=.5em,separator=:]{first}
-%D \fillinrules[n=2]{first}{last}
-%D \fillintext{first}{last} \input reich \par
-%D
-%D The main command is \type{\fillinrules}. This command takes
-%D one and an optional second argument and sets a paragraph with
-%D empty visualized lines.
-%D
-%D \showsetup{fillinrules}
-%D \showsetup{setupfillinrules}
-
-\def\setupfillinrules
- {\dodoubleargument\getparameters[\??il]}
-
-\definecomplexorsimpleempty\fillinrules
-
-\def\complexfillinrules[#1]%
- {\def\docomplexfillinrules##1##2%
- {\dodocomplexfillinrules[#1]{##1}{##2}{\thinrules
- [\c!n=\@@iln,\c!interlinespace=\@@ilinterlinespace,\c!before=,\c!after=]}}%
- \dodoublegroupempty\docomplexfillinrules}
-
-\def\dodocomplexfillinrules[#1]#2#3#4%
- {\endgraf
- \@@ilbefore
- \begingroup
- \setupfillinrules[#1]%
- \noindent
- \doifsomething{#2}
- {\doifelse\@@ilwidth\v!fit
- {\let\@@ildistance\!!zeropoint
- \hbox}
- {\doifelse\@@ilwidth\v!broad
- {\hbox}
- {\hbox to \@@ilwidth}}%
- \bgroup
- \doattributes\??il\c!style\c!color{\strut#2\hfill\@@ilseparator}%
- \hskip\@@ildistance
- \egroup}%
- %\hangindent=\wd0\relax % tzt hang=yes,n
- %\parindent=\hangindent
- %\box0\relax
- \setupwhitespace[\v!big]%
- \ignorespaces
- #4%
- \doifsomething{#3}
- {\kern\@@ildistance
- \doattributes\??il\c!style\c!color{#3\strut}}%
- \endgroup
- \endgraf
- \@@ilafter}
-
-%D \macros
-%D {fillintext}
-%D
-%D To provide compatible layouts when texts and lines are
-%D mixed, one can typeset a paragraph by using the command
-%D \type{\fillintext}.
-%D
-%D \showsetup{fillintext}
-
-\definecomplexorsimpleempty\fillintext
-
-\def\complexfillintext[#1]% rather rough, using an \unhbox is suboptimal
- {\def\docomplexfillintext##1##2%
- {\dowithnextbox
- {\dodocomplexfillinrules[#1]{##1}{\hfill##2}{\unhbox\nextbox\unskip}}%
- \hbox\bgroup\let\par\egroup\ignorespaces}%
- \dodoublegroupempty\docomplexfillintext}
-
-%D \macros
-%D {fillinline, setupfillinlines}
-%D
-%D Another member of the family takes care of putting a (often
-%D small) rule after a piece of text, like
-%D
-%D \startbuffer
-%D \fillinline \input reich \par
-%D \fillinline[margin=0cm] \input reich \par
-%D \stopbuffer
-%D
-%D \startvoorbeeld
-%D \getbuffer
-%D \stopvoorbeeld
-%D
-%D which was typeset by saying:
-%D
-%D \typebuffer
-%D
-%D The two commands that take care of this are:
-%D
-%D \showsetup{fillinline}
-%D \showsetup{setupfillinlines}
-
-\def\setupfillinlines
- {\dodoubleargument\getparameters[\??iv]}
-
-\definecomplexorsimpleempty\fillinline
-
-\def\complexfillinline[#1]%
- {%\endgraf % interferes with \definedescription cum suis
- \@@ivbefore
- \begingroup
- \setupfillinlines[#1]%
- \advance\rightskip \@@ivmargin
- \parfillskip\zeropoint
- \def\par % very dangerous
- {\let\par\endgraf % -)
- \ifhmode\unskip\hfill\fi
- \scratchdimen\dimexpr\@@ivwidth-\@@ivdistance\relax
- \ifdim\scratchdimen>\@@ivmargin\else\expandafter\rlap\fi
- {\kern\@@ivdistance
- \vrule
- \!!width \scratchdimen
- \!!height.5\linewidth
- \!!depth .5\linewidth}%
- \endgraf % !
- \endgroup
- \endgraf % !
- \@@ilafter}}
-
-%D \stopdocumentation
-%D \bgroup
-%D
-%D \setupframedtexts
-%D [setuptext]
-%D [background=color,backgroundcolor=white]
-%D
-%D \startbuffer
-%D \setupbackground
-%D [backgroundoffset=4pt,
-%D background=screen,
-%D frame=on,
-%D framecolor=red,
-%D leftoffset=2pt]
-%D \stopbuffer
-%D
-%D \getbuffer
-%D
-%D \startbackground
-%D
-%D \macros
-%D {setupbackground,startbackground,background}
-%D
-%D The section deals with backgrounds in the running text. This
-%D means that texts is to be collected and split over pages. To
-%D show what can be done, we provide this part of the
-%D documentation with some gray background and a red frame.
-%D Both the background and frame can have all characteristics
-%D of \type{\framed}. This time we used the setting:
-%D
-%D \typebuffer
-%D
-%D The implementation is not that sophisticated, but suffices.
-%D The main problem with this kind of functionality is to get
-%D the spacing all right.
-
-%D Specifying the background is more or less the same as
-%D specifying a framed box.
-%D
-%D \showsetup{setupbackground}
-
-\presetlocalframed[\??ag]
-
-\def\dosetupbackground[#1]%
- {\getparameters[\??ag][#1]%
- \doifelse\@@agstate\v!start
- {\let\startbackground\dostartbackground
- \let\stopbackground \dostopbackground
- \let\background \dobackground}
- {\let\startbackground\relax
- \let\stopbackground \relax
- \let\background \relax}}
-
-\def\setupbackground
- {\dosingleargument\dosetupbackground}
-
-%D Actually typesetting the background is implemented rather
-%D straightforward. We need to handle some spacing as well as
-%D the (often) a bit smaller horizontal size.
-%D
-%D \showsetup{startbackground}
-%D
-%D Although we could have used a scratch one, we first
-%D declare a boolean.
-
-% 0=no-split, 1=no-split+indent, 2=split, 3=split+indent
-
-\chardef\backgroundsplitmode\plusthree
-
-%D The \type{\vbox to \lineheight{}\vskip\zeropoint}
-%D construction gives the first real line a decent height by
-%D adding a dummy line.
-
-\def\dostartbackground
- {\endgraf
- \bgroup
- \setbox0\vbox\bgroup
- \vbox to \lineheight{}\vskip\zeropoint
- \blank[\v!disable]
- % \advance\hsize -\@@agleftoffset
- % \advance\hsize -\@@agrightoffset
- \leftskip \@@agleftoffset % new **
- \rightskip\@@agrightoffset} % new **
-
-%D This dummy line is removed by \type{\setbox2=\vsplit0 to
-%D \lineheight}. That way \type{\topskip} takes care of the
-%D lineheight. I'll probably forget to apply this trick
-%D elsewhere.
-
-\def\dostopbackground % improved version (i hope)
- {\endgraf
- \removelastskip
- \egroup
- \dimen2\leftskip % new **
- \forgetall
- \ifinsidefloat
- \chardef\backgroundsplitmode\zerocount
- \fi
- \ifcase\backgroundsplitmode
- \localframed[\??ag][\c!offset=\v!overlay]{\box0}%
- \or
- \hskip\dimen2
- \localframed[\??ag][\c!offset=\v!overlay]{\box0}%
- \else
- \splitmaxdepth\boxmaxdepth
- \splittopskip\topskip
- \setbox2\vsplit0 to \lineheight % get rid of fake line
- \loop
- \ifdim\pagetotal=\zeropoint % empty page
- \scratchdimen\textheight
- \chardef\backgroundsplit\plusone % split to max height
- \else
- \setbox\scratchbox\vbox{\@@agbefore}%
- \scratchdimen\dimexpr\pagegoal-\ht\scratchbox-\pagetotal\relax
- \chardef\backgroundsplit\plustwo % split to partial height
- \fi
- \advance\scratchdimen\dimexpr-\@@agtopoffset-\@@agbottomoffset\relax
- \ifdim\scratchdimen>2\lineheight\relax % reasonable, will be configurable
- \ifdim\ht0>\scratchdimen % larger than page
- \setbox2\vsplit0 to \scratchdimen
- \else
- \setbox2\box0
- \chardef\backgroundsplit\zerocount % no split
- \fi
- \setbox2\vbox \ifcase\backgroundsplit\or to \textheight \fi % max split
- {\vskip\@@agtopoffset
- \popsplitproperties
- \unvcopy2
- \prevdepth\dp2
- \obeydepth
- \vskip\@@agbottomoffset
- \vfill}
- \@@agbefore
- \ifcase\backgroundsplit\or\or % partial split
- \ifdim\pagegoal<\maxdimen
- \pagegoal=1.2\pagegoal % be a bit more tolerant
- \fi
- \fi
- \startlinecorrection
- %\localframed[\??ag][\c!offset=\v!overlay]{\hskip\@@agleftoffset\box2\hskip\@@agrightoffset}%
- \ifnum\backgroundsplitmode=\plusthree \hskip\dimen2 \fi %
- \localframed[\??ag][\c!offset=\v!overlay]{\box2}% new **
- \stoplinecorrection
- \ifcase\backgroundsplit % no split
- \@@agafter
- \else % some split
- \vfill\eject % geen \page !
- \fi
- \else
- \page
- \fi
- \ifdim\ht0>\zeropoint \repeat
- \fi
- \egroup
- \endgraf}
-
-%D As a bonus we also have a short command, that is of not
-%D much use, but kept there for historic reasons.
-%D
-%D \showsetup{background}
-
-\def\dobackground
- {\bgroup
- \dowithnextbox
- {\localframed[\??ag][\c!offset=\v!overlay]{\flushnextbox}\egroup}
- \vbox}
-
-%D \stopdocumentation
-%D \stopbackground
-%D \egroup
-
-%D New, for the moment private; let's see when GB finds out
-%D about this one and its obscure usage. It's used in:
-%D
-%D \startbuffer
-%D \defineframedtext
-%D [tabulateframe]
-%D [offset=overlay,
-%D backgroundoffset=3pt,
-%D background=color,
-%D backgroundcolor=green]
-%D
-%D \setuptabulate
-%D [tabulate]
-%D [frame=tabulateframe]
-%D
-%D \setuptables
-%D [frame=tabulateframe]
-%D
-%D \input tufte
-%D
-%D \starttabulate[|l|l|]
-%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
-%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
-%D \stoptabulate
-%D
-%D \input tufte
-%D
-%D \starttable[|l|l|]
-%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
-%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
-%D \stoptable
-%D \stopbuffer
-%D
-%D \typebuffer
-
-\def\defineframedcontent
- {\dodoubleempty\dodefineframedcontent}
-
-\def\dodefineframedcontent[#1][#2]%
- {\presetlocalframed[\??fc#1]%
- \getparameters[\??fc#1]
- [\c!leftoffset=\zeropoint,
- \c!rightoffset=\getvalue{\??fc#1\c!leftoffset},
- \c!topoffset=\zeropoint,
- \c!bottomoffset=\getvalue{\??fc#1\c!topoffset},
- \c!strut=\v!no,
- \c!offset=\v!overlay,
- \c!linecorrection=\v!no,
- \c!left=,
- \c!right=,
- #2]}
-
-\let\setuplocalframed\getparameters
-
-\def\setupframedcontent
- {\dodoubleempty\dosetupframedcontent}
-
-\def\dosetupframedcontent[#1][#2]%
- {\def\docommand##1{\getparameters[\??fc##1][#2]}%
- \processcommacommand[#1]\docommand}
-
-\def\startframedcontent[#1]%
- {\bgroup
- \let\stopframedcontent\egroup
- \doifnot{#1}\v!off
- {\doifdefined{\??fc#1\c!frame}
- {\def\stopframedcontent{\dostopframedcontent{#1}}%
- \dostartframedcontent{#1}}}}
-
-\def\dostartframedcontent#1%
- {\setbox\framebox\hbox\bgroup
- \setlocalhsize
- \hsize\localhsize
- \advance\hsize\dimexpr-\getvalue{\??fc#1\c!leftoffset}-\getvalue{\??fc#1\c!rightoffset} \relax
- \advance\vsize\dimexpr-\getvalue{\??fc#1\c!topoffset} -\getvalue{\??fc#1\c!bottomoffset}\relax
- \hskip\getvalue{\??fc#1\c!leftoffset}%
- \vbox\bgroup
- \vskip\getvalue{\??fc#1\c!topoffset}%
- \vbox\bgroup
- \forgetall
- \blank[\v!disable]}
-
-\def\dostopframedcontent#1%
- {\removelastskip
- \egroup
- \vskip\getvalue{\??fc#1\c!bottomoffset}%
- \egroup
- \hskip\getvalue{\??fc#1\c!rightoffset}%
- \egroup
- \doifvalue{\??fc#1\c!width}\v!fit
- {\letvalue{\??fc#1\c!width}\v!fixed}% no shapebox
- \ifinsidefloat
- \donefalse
- \else
- \doifelsevalue{\??fc#1\c!linecorrection}\v!yes\donetrue\donefalse
- \fi
- % plaats ?
- \ifdone\startlinecorrection\fi
- \getvalue{\??fc#1\c!left}% new
- \localframed[\??fc#1]{\box\framebox}%
- \getvalue{\??fc#1\c!right}% new
- \ifdone\stoplinecorrection\fi
- \egroup}
-
-%D \macros
-%D {backgroundline}
-%D
-%D For the moment an undocumented feature, but a cancidate
-%D for going public.
-
-\def\backgroundline[#1]%
- %{\doifsomething{#1}{\dobackgroundline{#1}}\hbox}
- {\doifcolorelse{#1}{\dobackgroundline{#1}\hbox}\hbox}
-
-% \def\backgroundline[#1]%
-% {\doifcolor{#1}{\dobackgroundline{#1}}\hbox}
-
-\def\dobackgroundline#1%
- {\dowithnextbox
- {\hbox
- {\localcolortrue
- \startcolor[#1]%
- \vrule
- \!!width \nextboxwd
- \!!height\nextboxht
- \!!depth \nextboxdp
- \stopcolor
- \hskip-\nextboxwd
- \flushnextbox}}}
-
-%D \macros
-%D {encircled}
-%D
-%D Some not so robust left||overs (borrowed from Knuth,
-%D \TEX Book\ page 356):
-
-\def\encircled#1%
- {{\ooalign{\hfil\raise0.07ex\hbox{{\tx#1}}\hfil\crcr\mathhexbox20D}}}
-
-\let\omcirkeld\encircled
-
-\setuplinewidth
- [\v!medium]
-
-\setupframed
- [\c!width=\v!fit,
- \c!height=\v!broad,
- \c!lines=,
- \c!offset=0.25ex, % \defaultframeoffset
- \c!empty=\v!no,
- \c!frame=\v!on,
- \c!topframe=,
- \c!bottomframe=,
- \c!leftframe=,
- \c!rightframe=,
- \c!radius=.5\bodyfontsize,
- \c!rulethickness=\linewidth,
- \c!corner=\v!rectangular,
- \c!depth=\!!zeropoint,
- \c!foregroundcolor=,
- \c!foregroundstyle=,
- \c!background=,
- \c!backgroundscreen=\@@rsscreen,
- \c!backgroundcolor=,
- \c!backgroundoffset=\!!zeropoint,
- \c!framecolor=,
- \c!frameoffset=\!!zeropoint,
- \c!backgroundcorner=\framedparameter\c!corner,
- \c!backgroundradius=\framedparameter\c!radius,
- \c!backgrounddepth=\framedparameter\c!depth,
- \c!framecorner=\framedparameter\c!corner,
- \c!frameradius=\framedparameter\c!radius,
- \c!framedepth=\framedparameter\c!depth,
- \c!component=,
- \c!align=,
- \c!bottom=\vss,
- \c!top=,
- \c!strut=\v!yes,
- \c!autostrut=\v!yes,
- \c!location=\v!normal,
- \c!orientation=,
- \c!autowidth=\v!yes,
- \c!setups=]
-
-\setupscreens
- [%\c!factor=1.0, % obsolete
- %\c!method=\v!external, % obsolete
- \c!screen=0.95]
-
-\setupblackrules
- [\c!n=3,
- \c!width=1em,
- \c!height=1ex,
- \c!depth=\!!zeropoint,
- \c!alternative=\c!a,
- \c!distance=.25ex,
- \c!color=]
-
-\setupmarginrules
- [\c!level=0,
- \c!rulethickness=\@@kadefaultwidth\linewidth]
-
-\setupthinrules
- [\c!interlinespace=\v!small,
- \c!n=3,
- \c!before=,
- \c!inbetween={\blank[\v!white]},
- \c!after=,
- \c!color=,
- \c!height=.5\linewidth,
- \c!depth=.5\linewidth,
- \c!frame=\v!on, % compatible with textbackgrounds
- \c!alternative=\v!b,
- \c!backgroundcolor=,
- \c!background=,
- \c!rulethickness=]
-
-\setuptextrules
- [\c!location=\v!left,
- \c!before=\blank,
- \c!after=\blank,
- \c!inbetween=,
- \c!width=2em,
- \c!style=\v!bold,
- \c!color=,
- \c!rulecolor=,
- \c!bodyfont=,
- \c!distance=.5em]
-
-\setupfillinrules
- [\c!width=\v!broad,
- \c!distance=1em,
- \c!before=\blank,
- \c!after=\blank,
- \c!n=1,
- \c!interlinespace=\v!small,
- \c!separator=,
- \c!style=\v!normal,
- \c!color=]
-
-\setupfillinlines
- [\c!width=3cm,
- \c!margin=\@@ivwidth,
- \c!distance=1em,
- \c!before=\blank,
- \c!after=\blank]
-
-\setupbackground
- [\c!leftoffset=.5\bodyfontsize,
- \c!rightoffset=\@@agleftoffset,
- \c!topoffset=\!!zeropoint,
- \c!bottomoffset=\@@agtopoffset,
- \c!state=\v!start,
- \c!radius=.5\bodyfontsize,
- \c!corner=\v!rectangular,
- \c!frame=\v!off,
- \c!color=,
- \c!depth=\!!zeropoint,
- \c!background=\v!screen,
- \c!backgroundcolor=\@@agcolor,
- \c!screen=\@@rsscreen,
- \c!before=,
- \c!after=]
-
-\protect \endinput
diff --git a/tex/context/base/core-sec.mkiv b/tex/context/base/core-sec.mkiv
deleted file mode 100644
index fdab75bc8..000000000
--- a/tex/context/base/core-sec.mkiv
+++ /dev/null
@@ -1,2621 +0,0 @@
-%D \module
-%D [ file=core-sec,
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Sectioning,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% start-stop per section en dan combineren met sectieblok; in dat geval
-% eenvoudiger per-* acties
-
-% nummeren per sectieblok implementeren
-
-% this module needs a clean up, currently some manipulations
-% take place multiple times; also, some clever recursive level
-% thing makes more sense
-
-% in manual (zie prikkels) : tussen=\blanko is enige hook om
-% met kop-in-hoofd een spatiering af te dwingen
-
-\writestatus{loading}{Context Core Macros / Sectioning}
-
-\startmessages dutch library: structures
- title: structuur
- 1: begin van sectieblok --
- 2: eind van sectieblok --
-\stopmessages
-
-\startmessages english library: structures
- title: structure
- 1: begin of sectionblock --
- 2: end of sectionblock --
-\stopmessages
-
-\startmessages german library: structures
- title: struktur
- 1: Begin des Abschnittsblocks --
- 2: Ende des Abschnittsblocks --
-\stopmessages
-
-\startmessages czech library: structures
- title: struktury
- 1: zacatek oddilu (sekce) --
- 2: konec oddilu (sekce) --
-\stopmessages
-
-\startmessages italian library: structures
- title: struttura
- 1: inizio del blocco (sezione) --
- 2: fine del blocco (sezione) --
-\stopmessages
-
-\startmessages norwegian library: structures
- title: struktur
- 1: starten av blokk -- (seksjon)
- 2: slutten av blokk -- (seksjon)
-\stopmessages
-
-\startmessages romanian library: structures
- title: structuri
- 1: inceput de bloc sectiune --
- 2: sfarsit de bloc sectiune --
-\stopmessages
-
-\startmessages french library: structures
- title: structure
- 1: début de blocsection --
- 2: fin de blocsection --
-\stopmessages
-
-\unprotect
-
-% new and to be tested
-
-\unexpanded\def\separatorlist#1%
- {\ifx\sepnumber\undefined\def\sepnumber{0}\fi
- \increment\sepnumber
- \getfromcommacommand[#1][\sepnumber]%
- \ifx\commalistelement\empty
- \getcommalistsize[#1]%
- \def\sepnumber{\number\commalistsize}%
- \getfromcommacommand[#1][\sepnumber]%
- \fi
- \commalistelement}
-
-% \setuphead[section] [separator=\separatorlist{?,!,*}]
-% \setuphead[subsection][separator=\separatorlist{??,!!,**}]
-%
-% \let\spr\separatorlist % this will enable this feature
-%
-% \setuphead[section] [separator={?,!,*}]
-% \setuphead[subsection][separator={??,!!,**}]
-%
-% \setupheads[separator={A,B,C,D,E,F}]
-% \chapter{test}
-% \section{test} \subsection{test} \subsection{test}
-% \section{test} \subsection{test} \subsection{test}
-
-% from now on, internaly numbers are separated by a period
-% and postprocessed on demand; this will change to {} {} {}
-
-\def\numberseparator {.} % reasonable default
-\def\sectionseparator{-} % was : but is now -
-
-\def\@@filterfirstpart [#1--#2]{#1}
-\def\@@filtersecondpart [#1--#2]{#2}
-
-\def\@@filterblockpart [#1--#2--#3]{#1}
-\def\@@filternumberpart [#1--#2--#3]{#2}
-\def\@@filterpagepart [#1--#2--#3]{#3}
-\def\@@filterblocknumberpart[#1--#2--#3]{#1--#2}
-
-\def\@@filterheadpart[#1]{\@EA\@@dofilterheadpart\@EA[#1-0]}
-\def\@@filtertailpart[#1]{\@EA\@@dofiltertailpart\@EA[#1-0]}
-
-\def\@@dofilterheadpart[#1-#2]{#1}
-\def\@@dofiltertailpart[#1-#2]{#2}
-
-\def\@@filterlevelpart[#1--#2--#3]{\@@dofilterlevelpart[#2-0-0-0-0]}
-
-\def\@@dofilterlevelpart[#1-0-0-0-#2]{#1}
-
-\def\gobbleuntilrelax#1\relax{}
-
-\def\separatednumber #1{\doseparatednumber #1.\empty\relax}
-\def\removefirstprefix#1{\doremovefirstprefix#1.\empty\relax}
-\def\removeallprefixes#1{\doremoveallprefixes#1.\empty\relax}
-
-\def\doseparatednumber#1.#2%
- {#1%
- \ifx#2\empty
- \@EA\gobbleuntilrelax
- \else \numberseparator
- \@EA\doseparatednumber
- \fi#2}
-
-\def\doremoveallprefixes#1.#2%
- {\ifx#2\empty
- #1\@EA\gobbleuntilrelax
- \else
- \@EA\doremoveallprefixes
- \fi#2}
-
-\def\doremovefirstprefix#1.#2%
- {\ifx#2\empty
- #1\@EA\gobbleuntilrelax
- \else
- \@EA\noremovefirstprefix
- \fi#2}
-
-\def\noremovefirstprefix#1.\empty\relax
- {#1}
-
-% we need to expand in order to get something separatable
-
-\def\dohandleheadnumber#1%
- {\expanded{\separatednumber{#1}}}
-
-\def\dodochecknumber#1#2#3% will become ugly after speed up
- {\bgroup
- \doifinstringelse{.0}{.#2}
- {\doifnot{#3}\v!by
- {%\debuggerinfo\m!systems{number #1 #3 becomes \getnumbervariable{#1\c!way}}%
- \setevalue{\@@thenumber{#1}\c!way}{#3}% geen \xdef, gaat mis met \subpage
- \dochecknumber{#1}}} % tricky and ugly
- {\doifnotvalue{\@@thenumber{#1}\s!check}{#2}
- {% new, calculate accumulated number
- \scratchcounter\getvalue{\@@thenumber{#1}\c!n}\relax
- \advance\scratchcounter\countervalue{\@@thenumber{#1}}\relax
- \setxvalue{\@@thenumber{#1}\c!n}{\the\scratchcounter}%
- %
- \setcounter{\@@thenumber{#1}}{0\getvalue{\@@thenumber{#1}\c!start}}%
- \setxvalue{\@@thenumber{#1}\c!way\c!local}{\getvalue{\@@thenumber{#1}\c!way}}%
- \setxvalue{\@@thenumber{#1}\s!check}{#2}}}%
- \egroup}
-
-\def\dochecknumber#1%
- {\edef\currentsection{\csname\??by\csname\@@thenumber{#1}\c!way\endcsname\endcsname}%
- \ifx\currentsection\empty\else
- \dodochecknumber
- {#1}%
- {\csname\currentsection\c!number\endcsname}%
- {\v!by\previoussection\currentsection}%
- \fi}
-
-\def\checknumber[#1]%
- {\bgroup
- %\ifcase\blocklevel\else
- \ifdoingblocks
- \doifnotvalue{\@@thenumber{#1}\c!blockway}\v!no\setblockcounters
- \fi
- \dochecknumber{#1}%
- \egroup}
-
-\def\rawsectionnumber#1%
- {\countervalue{\??se#1}}
-
-\def\precedingseparator{\@@koseparator} % brrr
-
-\def\domakeprecedingsectionnumber[#1]% will become ugly after speed up
- {\bgroup % added
- \globallet\precedingsectionnumber\empty
- \ifsectionnumber
- \doifvalue{\??sb\@@sectionblock\c!number}\v!yes % added
- {\doifelsevalue{\@@thenumber{#1}\c!sectionnumber}\v!yes
- \donetrue\donefalse
- \doifvalue{\@@thenumber{#1}\c!sectionnumber}\v!number
- {\donetrue\let\@@sectionconversion\gobbleoneargument}%
- \ifdone
- \edef\currentsection
- {\getvalue{\??by\getvalue{\@@thenumber{#1}\c!way\c!local}}}%
- \doifnot\currentsection\zerosection
- {\doifnot{\@@sectionvalue\currentsection}{0}
- {\xdef\precedingsectionnumber
- {\getvalue{\currentsection\c!number}%
- \spr{\precedingseparator}}}}%
- \fi}%
- \fi
- \egroup}
-
-\def\makeprecedingsectionnumber[#1]%
- {\bgroup
- %\ifnum\blocklevel>0
- %\ifcase\blocklevel\else
- \ifdoingblocks
- \doifnotvalue{\@@thenumber{#1}\c!blockway}\v!no\setblockcounters
- \fi
- \domakeprecedingsectionnumber[#1]%
- \egroup}
-
-% \def\makesectionnumber[#1]%
-% {\makeprecedingsectionnumber[#1]%
-% \xdef\composedsectionnumber%
-% {\precedingsectionnumber\convertednumber[#1]}}%
-%
-% hack needed for chinese and oldstyle in normal tex, will change
-
-\def\makesectionnumber[#1]%
- {\bgroup
- \forceunexpanded % i don't like this hack
- \makeprecedingsectionnumber[#1]%
- \xdef\composedsectionnumber% was \xdef maar dat gaat fout met font switches
- {\precedingsectionnumber\convertednumber[#1]}%
- \egroup}
-
-% \def\preparethenumber#1#2#3% {\??id#1} \number \result
-% {\doifelsevaluenothing{#1\c!separator}
-% {\let\numberseparator\empty
-% \let#3#2}
-% {% was \unexpanded \edef, but we need it unexpanded !
-% \edef\numberseparator{\spr{\getvalue{#1\c!separator}}}%
-% \doifelsenothing{\executeifdefined{#1\c!suffix}\empty}
-% {\edef#3%
-% {\@EA\separatednumber\@EA{#2}%
-% }}%\stp{\getvalue{#1\c!stopper}}}}
-% {\edef#3%
-% {\@EA\separatednumber\@EA{#2}%
-% \spr{\getvalue{#1\c!separator}}%
-% \getvalue{#1\c!suffix}%
-% \stp{\getvalue{#1\c!stopper}}}}}}
-%
-% some day we do a real cleanup
-
-\def\analyzenumber#1#2#3% {\??id#1} \(precedingsection)number \result
- {% was \unexpanded \edef, but we need it unexpanded !
- \doifelsenothing{\executeifdefined{#1\c!suffix}\empty}
- {\let \numbersuffix \empty}
- {\edef\numbersuffix{\spr{\getvalue{#1\c!suffix}}}}%
- \doifelsenothing{\executeifdefined{#1\c!stopper}\empty}
- {\let \numberstopper \empty}
- {\edef\numberstopper{\spr{\getvalue{#1\c!stopper}}}}%
- \doifelsenothing{\executeifdefined{#1\c!separator}\empty}
- {\let \numberseparator \empty}
- {\edef\numberseparator{\spr{\getvalue{#1\c!separator}}}}%
- \let\numberprefix\empty}
-
-\def\preparefullnumber#1#2#3% {\??id#1} \(precedingsection)number \result
- {\analyzenumber{#1}#2#3%
- \ifx\numberseparator\empty
- \edef\numberprefix{#2}%
- \else
- \edef\numberprefix{\@EA\separatednumber\@EA{#2}}%
- \fi
- \ifx\numbersuffix\empty
- \ifx\numberprefix\empty
- \let #3\empty
- \else
- \edef#3{\numberprefix\numberstopper}%
- \fi
- \else
- \ifx\numberprefix\empty
- \edef#3{\numbersuffix\numberstopper}%
- \else
- \edef#3{\numberprefix\numberseparator\numbersuffix\numberstopper}%
- \fi
- \fi}
-
-\def\prepareprefixnumber#1#2#3% {\??id#1} \number \result
- {\analyzenumber{#1}#2#3%
- \ifx\numberseparator\empty
- \edef\numberprefix{#2}%
- \else
- \edef\numberprefix{\@EA\separatednumber\@EA{#2}}%
- \fi
- \let#3\numberprefix}
-
-\def\sectionnumberonly[#1]%
- {\makesectionnumber[#1]%
- \composedsectionnumber}
-
-% sectioning
-
-\newcount\nofsections
-
-\let\zerosection \v!text
-\let\firstsection\empty
-\let\lastsection \empty
-\let\@@sectie \empty
-\let\@@koppeling \empty
-
-\makecounter{\??se\v!text}
-
-\letvalueempty{\??se\v!text\c!before}
-\letvalueempty{\??se\v!text\c!after }
-
-\setvalue {\v!text\c!number}{0}
-\letvalueempty{\v!text\s!format}
-
-\letvalueempty{\??sk\v!text}
-\letvalueempty{\??sk }
-
-\letvalue{\??by }\v!text
-\letvalue{\??by\v!text }\v!text
-\letvalue{\??by\v!all }\v!text
-\letvalue{\??by\v!by }\v!text
-\letvalue{\??by\v!by\v!text}\v!text
-\letvalue{\??by\v!by\v!all }\v!text
-\letvalue{\??by\v!by\v!page}\v!text % see footnotes
-
-\def\sectionofhead#1{\executeifdefined{\??ko#1\c!section}\s!unknown}
-
-\def\setupsection
- {\dotripleempty\dosetupsection}
-
-\def\dosetupsection[#1]%
- {\doifdefinedelse{\??se#1}
- {\dodosetupsection[#1]}%
- {\dodosetupsection[\sectionofhead{#1}]}}
-
-\def\dodosetupsection[#1][#2][#3]%
- {\doifdefined{\??se#1}
- {\ifthirdargument
- \getparameters[\??se#1#2][#3]%
- \else
- \getparameters[\??se#1][#2]%
- \fi
- \doifelsevalue{\??se#1\c!previousnumber}\v!yes
- {\setvalue{#1\c!number}{\@@longsectionnumber {#1}}}
- {\setvalue{#1\c!number}{\@@shortsectionnumber{#1}}}}}
-
-\def\docouplemarking[#1][#2]%
- {\doifdefinedelse{\??ko#2\c!section}
- {\docouplemarking[#1][\getvalue{\??ko#2\c!section}]}
- {\def\donexttrackcommando##1%
- {\edef\coupledmarkings{\getvalue{\??se##1\c!marking}}%
- \doifelse{##1}{#2}
- {\addtocommalist{#1}\coupledmarkings}
- {\removefromcommalist{#1}\coupledmarkings}%
- \setevalue{\??se##1\c!marking}{\coupledmarkings}%
- \donexttracklevel{##1}}%
- \donexttracklevel{\zerosection}}} % \firstsection
-
-\def\couplemarking
- {\dodoubleargument\docouplemarking}
-
-\def\decouplemarking[#1]%
- {\couplemarking[#1][]}
-
-\def\definesection[#1]%
- {\doifundefined{\??se#1}
- {\doifelsenothing\firstsection
- {\def\firstsection{#1}%
- \setevalue{\??se#1\c!before}{\v!text}%
- \setevalue{\??se\v!text\c!after}{#1}}
- {\setevalue{\??se\commalistelement\c!after}{#1}% commalistelement ?
- \setevalue{\??se#1\c!before}{\lastsection}%
- \setevalue{\??se\lastsection\c!after}{#1}}%
- \advance\nofsections \plusone
- \setevalue{\??se#1\c!level}{\the\nofsections}%
- \letvalue{\??se#1\c!after}\empty
- \setvalue{\e!next#1}{\@@nextsectionnumber{#1}}%
- \setvalue{#1\c!number}{\@@longsectionnumber{#1}}%
- \setvalue{#1\s!format}{\@@longformatnumber{#1}}%
- \setevalue{\??by#1}{#1}%
- \setevalue{\??by\v!by#1}{#1}%
- \makecounter{\??se#1}%
- \makecounter{\??se\v!last#1}% GB
- \edef\lastsection{#1}%
- \setvalue{\??sk#1}{#1}%
- \letvalue{\??se#1\c!marking}\empty
- \setupsection[#1][\c!previousnumber=\v!yes]}}%
-
-\def\previoussection#1{\csname\??se#1\c!before\endcsname}
-\def\nextsection #1{\csname\??se#1\c!after \endcsname}
-
-\let\preservedsection\v!unknown % \def\preservedsection{\firstsection}
-
-\def\checkpreservevalueafter#1% GB
- {\ifnum\getvalue{\??se#1\c!level}<\nofsections
- \edef\preservedsection{\getvalue{\??se#1\c!after}}%
- \ifconditional\@@resetsubheadnumbers
- \setcounter{\??se\v!last\preservedsection}\zerocount % {0}%
- \else
- \setcounter{\??se\v!last\preservedsection}{\countervalue{\??se\preservedsection}}%
- \fi
- \fi}
-
-\def\@@setsectionnumber#1#2%
- {\letgvalueempty{\??se#1\s!start}% signal i.p.v. boolean
- \setcounter{\??se#1}{#2}%
- \checkpreservevalueafter{#1}% GB
- \resetsectioncounters{#1}%
- \checkpagecounter}
-
-\def\@@nextsectionnumber#1% patched by GB
- {\letgvalueempty{\??se#1\s!start}% signal i.p.v. boolean
- \ifnum\countervalue{\??se\v!last#1}>\zerocount
- \setcounter{\??se#1}{\countervalue{\??se\v!last#1}}%
- \setcounter{\??se\v!last#1}\zerocount % {0}%
- \fi
- \pluscounter{\??se#1}%
- \checkpreservevalueafter{#1}%
- \resetsectioncounters{#1}%
- \checkpagecounter}
-
-\def\@@sectionvalue#1% % nog niet overal doorgevoerd
- {\countervalue{\??se#1}} % zoeken op \??se
-
-% suited for chinese too:
-
-\def\@@sectionconversion#1#2% a doublure with \@@shortsectionnumber
- {\ifnum#2=0 0\else % else troubles with \uchar
- \@EA\ifx\csname\??se#1\@@sectionblock\c!conversion\endcsname\relax
- \@EA\ifx\csname\??se#1\c!conversion\endcsname\relax
- #2%
- \else
- \convertnumber{\getvalue{\??se#1\c!conversion}}{#2}%
- \fi
- \else
- \convertnumber{\getvalue{\??se#1\@@sectionblock\c!conversion}}{#2}%
- \fi
- \fi}
-
-% \def\@@sectionlevel#1%
-% {\ifundefined{\??se#1\c!level}0\else\getvalue{\??se#1\c!level}\fi}
-
-\def\@@sectionlevel#1%
- {\executeifdefined{\??se#1\c!level}0}
-
-% Omdat een markering kan worden herdefinieerd moeten we
-% eerst testen of er wel een keten||afhankelijkheid is.
-
-\def\resetsectionmarks#1% can invoke a break
- {\ifundefined{\??se#1}%
- \fastresetmarker[\mainmarking{#1}]% % redundant \mainmarking
- \else
- \let\donexttrackcommando\doresetsectionmarks
- \donexttracklevel{#1}%
- \fi}
-
-\def\doresetsectionmarks#1%
- {\ifundefined{\??se#1\c!marking}\else % skip zero level
- \fastresetmarkerlist[\csname\??se#1\c!marking\endcsname]%
- \fi
- \donexttracklevel{#1}}
-
-% I'm not sure if the next one is better:
-%
-% \def\doresetsectionmarks#1%
-% {\ifundefined{\??se#1\c!markering}% skip zero level
-% \donexttracklevel{#1}%
-% \else
-% \fastresetmarkerlist[\csname\??se#1\c!markering\endcsname]%
-% \fi}
-%
-% and indeed, it isn't, actually, it does not work at all, so let's drop it.
-
-% packaged:
-%
-% \def\resetsectioncounters#1%
-% {\def\donexttrackcommando##1%
-% {\resetcounter{\??se##1}%
-% \donexttracklevel{##1}}%
-% \donexttracklevel{#1}}
-%
-% nicer
-%
-% \def\doresetsectioncounters#1%
-% {\resetcounter{\??se#1}%
-% \donexttracklevel{#1}}
-%
-% obey eigennummer
-
-\def\doresetsectioncounters#1%
- {\resetcounter{\??se#1}%
- \letgvalue{\??se#1\c!ownnumber}\relax
- \donexttracklevel{#1}}
-
-\def\resetsectioncounters % #1
- {\let\donexttrackcommando\doresetsectioncounters
- \donexttracklevel} % #1
-
-% bij checken kan geen prefix worden bekeken, anders vallen
-% er titels buiten de inhoudsopgave
-
-% evt ook level gaan opslaan tbv snelle selectie
-
-% \def\makesectionformat
-% {\edef\sectionformat
-% {\@@sectiontype\sectionseparator
-% \csname\lastsection\s!format\endcsname}}
-
-\unprotected \def\makesectionformat % we don't want eigennummers here
- {\pushmacro\@@shortsectionnumber
- \let\@@shortsectionnumber\@@sectionvalue
- \edef\sectionformat
- {\@@sectiontype\sectionseparator
- \csname\lastsection\s!format\endcsname}%
- \popmacro\@@shortsectionnumber}
-
-\def\dobacktracklevel#1%
- {\doifnot{\previoussection{#1}}\zerosection
- {\dobacktrackcommando{\previoussection{#1}}}}
-
-\def\donexttracklevel#1%
- {\doifnot{#1}\lastsection
- {\donexttrackcommando{\nextsection{#1}}}}
-
-\chardef\alltoclevels\zerocount
-
-\let\currentlevel\empty
-
-\def\dosetcurrentlevel#1%
- {\global\chardef\alltoclevels\zerocount
- \xdef\currentlevel{\getvalue{\lastsection\s!format}}}
-
-\def\dosetpreviouslevel#1%
- {\global\chardef\alltoclevels\plusone
- \globallet\currentlevel\empty
- \def\dobacktrackcommando##1%
- {\ifnum\countervalue{\??se##1}>\zerocount
- \global\chardef\alltoclevels\zerocount
- \xdef\currentlevel{\getvalue{\previoussection{##1}\s!format}}%
- \else
- \dobacktracklevel{##1}%
- \fi}%
- \dobacktrackcommando\lastsection}
-
-\def\dosettextlevel#1%
- {\global\chardef\alltoclevels\plusone
- \globallet\currentlevel\empty}
-
-\def\dosetotherlevel#1%
- {\doifdefinedelse{\??ko#1\c!section} % beter alteratief: ook
- {\edef\@@sectie{\getvalue{\??ko#1\c!section}}} % hoofdstuk\c!format
- {\edef\@@sectie{#1}}%
- \doifdefinedelse{\??se\@@sectie}
- {\global\chardef\alltoclevels\zerocount
- \xdef\currentlevel{\getvalue{\@@sectie\s!format}}}
- {\global\chardef\alltoclevels\plusone
- \globallet\currentlevel\empty
- \def\dobacktrackcommando##1%
- {\@EA\ifx\csname\??se##1\c!start\endcsname\relax
- \dobacktracklevel{##1}%
- \else
- \ifnum\countervalue{\??se##1}>\zerocount
- \global\chardef\alltoclevels\zerocount
- \xdef\currentlevel{\getvalue{##1\s!format}}%
- \else
- \dobacktracklevel{##1}%
- \fi
- \fi}%
- \dobacktrackcommando\lastsection}}
-
-% \def\ignoresectionconversion % brrr
-% {\let\@@sectionconversion\secondoftwoarguments}
-
-% todo: criterium=appendix|frontmatter|....
-
-\def\dosetfilterlevel#1#2% beware: this one is \let
- {\bgroup
- \let\@@shortsectionnumber\@@sectionvalue
-% \ignoresectionconversion
- \edef\askedlevel{#1}%
- \edef\askedfilter{#2}%
- \ifx\askedlevel\v!current
- \dosetcurrentlevel\askedlevel
- \else\ifx\askedlevel\v!previous
- \dosetpreviouslevel\askedlevel
- \else\ifx\askedlevel\v!all
- \global\chardef\alltoclevels\plusone
- \else\ifx\askedlevel\v!text
- \global\chardef\alltoclevels\plusone
- \else
- \edef\byaskedlevel{\csname\??by\askedlevel\endcsname}%
- \ifx\byaskedlevel\v!text
- \dosettextlevel\askedlevel
- \else
- \dosetotherlevel\askedlevel
- \fi
- \fi\fi\fi\fi
- % experiment
- \ifx\askedfilter\empty \else
- \xdef\currentlevel{\currentlevel\sectionseparator\askedfilter}%
- \fi
- \egroup}
-
-% \def\dontsetfilterlevel#1#2%
-% {\let\currentlevel\somesavedlevel
-% \chardef\alltoclevels\zerocount}
-
-\def\dontsetfilterlevel#1#2%
- {\let\currentlevel\somesavedlevel
- \let\@@sectiontype\@@tocsectiontype
- \chardef\alltoclevels\zerocount}
-
-\def\honorlocalfilterlevel % local lists will be real local
- {\let\dosetfilterlevel\dontsetfilterlevel}
-
-% cleaner
-%
-% \def\doifnextlevelelse[#1::#2]#3#4%
-% {\ifcase\alltoclevels
-% \doifelse{\@@sectiontype}{#1}
-% {\doifinstringelse{=\currentlevel:}{=:#2:}
-% {\doifinstringelse{=\currentlevel:0}{=:#2:}{#4}{#3}}
-% {#4}}
-% {#4}%
-% \else
-% #3%
-% \fi}
-%
-% \def\doifprevlevelelse[#1::#2]#3#4%
-% {\ifcase\alltoclevels
-% \doifelse{\@@sectiontype}{#1}
-% {\doifinstringelse{=\currentlevel:}{=:#2:}{#3}{#4}}
-% {#4}%
-% \else
-% #3%
-% \fi}
-%
-% faster
-%
-% \def\doifnextlevelelse[#1::#2]%
-% {\ifcase\alltoclevels
-% \doifelse{\@@sectiontype}{#1}
-% {\doifinstringelse{=\currentlevel:}{=:#2:}
-% {\doifinstringelse{=\currentlevel:0}{=:#2:}\donefalse\donetrue}
-% \donefalse}
-% \donefalse
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-% \def\doifprevlevelelse[#1::#2]%
-% {\ifcase\alltoclevels
-% \doifelse{\@@sectiontype}{#1}
-% {\doifinstringelse{=\currentlevel:}{=:#2:}\donetrue\donefalse}
-% \donefalse
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-% meaner
-%
-% \setuplist
-% [chapter]
-% [after={\startcolumns\placelist[section]\stopcolumns}]
-
-\def\somesavedlevel{0}
-
-% \def\dosavesomelevel[#1:0:0:0:#2]%
-% {\def\somesavedlevel{:#1}}
-
-% \def\doifnextlevelelse[#1::#2]%
-% {\dosavesomelevel[#2:0:0:0:0]%
-% \ifcase\alltoclevels
-% \doifelse{\@@sectiontype}{#1}
-% {\doifinstringelse{=\currentlevel:}{=:#2:}
-% {\doifinstringelse{=\currentlevel:0}{=:#2:}\donefalse\donetrue}
-% \donefalse}
-% \donefalse
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-% \def\doifprevlevelelse[#1::#2]%
-% {\dosavesomelevel[#2:0:0:0:0]%
-% \ifcase\alltoclevels
-% \doifelse{\@@sectiontype}{#1}
-% {\doifinstringelse{=\currentlevel:}{=:#2:}\donetrue\donefalse}
-% \donefalse
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-% again faster:
-
-% \def\doifnextlevelelse[#1::#2]% beware: this one is \let
-% {\dosavesomelevel[#2:0:0:0:0]%
-% \ifcase\alltoclevels
-% \ifnum\@@sectiontype=#1
-% \def\levelstring{=:#2:}%
-% \doifincsnameelse{=\currentlevel:}\levelstring
-% {\doifincsnameelse{=\currentlevel:0}\levelstring\donefalse\donetrue}
-% \donefalse
-% \else
-% \donefalse
-% \fi
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-%\def\doifprevlevelelse[#1::#2]% beware: this one is \let
-% {\dosavesomelevel[#2:0:0:0:0]%
-% \ifcase\alltoclevels
-% \ifnum\@@sectiontype=#1
-% \doifinstringelse{=\currentlevel:}{=:#2:}\donetrue\donefalse
-% \else
-% \donefalse
-% \fi
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-% \let\doiftoclevelelse\doifnextlevelelse
-% \let\doifreglevelelse\doifprevlevelelse
-% \let\doifblklevelelse\doifprevlevelelse
-%
-% we want to be able to overload them globally
-
-% This will be reimplemented some day soon
-%
-% {nn}{xx}{yy}
-%
-% -> \scan{..}{..}{0} met 0 als sentinel
-
-% still not perfect
-%
-% \def\doifnextlevelelse[#1]% !! this one is \let / uti seperator --
-% {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}%
-% \ifcase\alltoclevels
-% \ifnum\@@sectiontype=\@@filterblockpart[#1]\relax
-% \edef\levelstring{=\sectionseparator\@@filternumberpart[#1]\sectionseparator}%
-% \doifincsnameelse{=\currentlevel\sectionseparator}\levelstring
-% {\doifincsnameelse{=\currentlevel\sectionseparator0}\levelstring
-% \donefalse
-% \donetrue}
-% \donefalse
-% \else
-% \donefalse
-% \fi
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-%
-% \def\doifprevlevelelse[#1]% !! this one is \let / uti seperator --
-% {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}%
-% \ifcase\alltoclevels
-% \ifnum\@@sectiontype=\@@filterblockpart[#1]\relax
-% \doifinstringelse
-% {=\currentlevel\sectionseparator}
-% {=\sectionseparator\@@filternumberpart[#1]\sectionseparator}
-% \donetrue\donefalse
-% \else
-% \donefalse
-% \fi
-% \else
-% \donetrue
-% \fi
-% \ifdone
-% \expandafter\firstoftwoarguments
-% \else
-% \expandafter\secondoftwoarguments
-% \fi}
-
-\def\doifnextlevelelse[#1]% !! this one is \let / uti seperator --
- {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}%
- \edef\@@tocsectiontype{\@@filterblockpart[#1]}% needed for nested tocs
- \ifcase\alltoclevels
- \ifnum\@@sectiontype=\@@tocsectiontype\relax
- \edef\levelstring{=\sectionseparator\@@filternumberpart[#1]\sectionseparator}%
- \doifincsnameelse{=\currentlevel\sectionseparator}\levelstring
- {\doifincsnameelse{=\currentlevel\sectionseparator0}\levelstring
- \donefalse
- \donetrue}
- \donefalse
- \else
- \donefalse
- \fi
- \else
- \donetrue
- \fi
- \ifdone
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\def\doifprevlevelelse[#1]% !! this one is \let / uti seperator --
- {\edef\somesavedlevel{\sectionseparator\@@filterlevelpart[#1]}%
- \edef\@@tocsectiontype{\@@filterblockpart[#1]}% needed for nested tocs
- \ifcase\alltoclevels
- \ifnum\@@sectiontype=\@@tocsectiontype\relax
- \doifinstringelse
- {=\currentlevel\sectionseparator}
- {=\sectionseparator\@@filternumberpart[#1]\sectionseparator}
- \donetrue\donefalse
- \else
- \donefalse
- \fi
- \else
- \donetrue
- \fi
- \ifdone
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-% we need to cover the special case of nested lists in section blocks
-%
-% \starttext
-%
-% \def\ChapterEntry#1#2#3%
-% {chapter : \hbox to \hsize{\strut\bf#2\hss#3}\endgraf\placelist[section]}
-%
-% \startfrontmatter % optional
-% \placelist[chapter][alternative=command,command=\ChapterEntry,criterium=text] \page
-% \stopfrontmatter % optional
-%
-% \startbodymatter % optional
-% \chapter{first} \section{one} test \section{two} test \page
-% \chapter{second} \section{alpha} test \section{beta} test \page
-% \stopbodymatter % optional
-%
-% \stoptext
-
-\def\doiftoclevelelse{\doifnextlevelelse}
-\def\doifreglevelelse{\doifprevlevelelse}
-\def\doifblklevelelse{\doifprevlevelelse}
-
-\def\@@longformatnumber#1%
- {\csname\previoussection{#1}\s!format\endcsname
- \sectionseparator
- \@@shortsectionnumber{#1}}
-
-% \def\@@longsectionnumber#1%
-% {\ifnum\countervalue{\??se\previoussection{#1}}>\zerocount
-% \csname\previoussection{#1}\c!nummer\endcsname.%
-% \fi
-% \@@shortsectionnumber{#1}}
-
-\def\@@longsectionnumber#1%
- {\ifreversesectionnumbers
- \@@shortsectionnumber{#1}%
- \ifnum\countervalue{\??se\previoussection{#1}}>\zerocount
- .\csname\previoussection{#1}\c!number\endcsname
- \fi
- \else
- \ifnum\countervalue{\??se\previoussection{#1}}>\zerocount
- \csname\previoussection{#1}\c!number\endcsname.%
- \fi
- \@@shortsectionnumber{#1}%
- \fi}
-
-% suited for chinese too:
-%
-% \def\@@shortsectionnumber#1%
-% {\@EA\ifx\csname\??se#1\@@sectionblock\c!conversie\endcsname\relax
-% \@@sectionvalue{#1}%
-% \else
-% \@@sectionconversion{#1}{\@@sectionvalue{#1}}%
-% \fi}
-%
-% obey eigennummer
-%
-% \def\@@shortsectionnumber#1%
-% {\@EA\ifx\csname\??se#1\c!eigennummer\endcsname\relax
-% \@EA\ifx\csname\??se#1\@@sectionblock\c!conversie\endcsname\relax
-% \@EA\ifx\csname\??se#1\c!conversie\endcsname\relax
-% \@@sectionvalue{#1}%
-% \else
-% \@@sectionconversion{#1}{\@@sectionvalue{#1}}%
-% \fi
-% \else
-% \@@sectionconversion{#1}{\@@sectionvalue{#1}}%
-% \fi
-% \else
-% \csname\??se#1\c!eigennummer\endcsname
-% \fi}
-
-\def\@@shortsectionnumber#1%
- {\@EA\ifx\csname\??se#1\c!ownnumber\endcsname\relax
- \@EA\ifx\csname\??se#1\@@sectionblock\c!conversion\endcsname\relax
- \@EA\ifx\csname\??se#1\c!conversion\endcsname\relax
- \@@sectionvalue{#1}%
- \else
- \@@sectionconversion{#1}{\@@sectionvalue{#1}}%
- \fi
- \else
- \@@sectionconversion{#1}{\@@sectionvalue{#1}}%
- \fi
- \else
- \csname\??se#1\c!ownnumber\endcsname
- \fi}
-
-\def\dosetlocalsectionblock#1#2#3% new \edef's
- {\edef\@@sectiontype {#1}%
- \edef\@@sectionblock {#2}%
- \edef\@@sectionblocks{#3}}
-
-% beware, the \resetsectionmarks generates some nodes that
-% will result in an additional last page, which needs to be
-% captured at the end
-
-% \def\doaroundsectionblock#1%
-% {\doifvaluesomething{\??sb#1\c!page}
-% {\ExpandFirstAfter\page[\getvalue{\??sb#1\c!page}]}%
-% \resetsectioncounters\zerosection % was firstsection
-% \resetsectionmarks\zerosection}
-
-% \def\dostartsectionblock#1#2%
-% {\begingroup
-% \doaroundsectionblock{#1}% % going to a new page or so
-% \getvalue{\??sb#1}% % set name of section block
-% \getsectionblockenvironment{#1}% % special settings, grouped
-% %\expandafter\csname#2true\endcsname % obsolete
-% \setsystemmode{#1}% % can be used in conditionals
-% \getvalue{\??sb\@@sectionblock\c!before}% this one is not to be moved!
-% \showmessage\m!structures1\@@sectionblocks}
-
-% \def\dostopsectionblock
-% {\showmessage\m!structures2\@@sectionblocks
-% \getvalue{\??sb\@@sectionblock\c!after}% don't move
-% \doaroundsectionblock\@@sectionblock
-% \endgroup}
-
-\def\doaroundsectionblock
- {\doifvaluesomething{\??sb\@@sectionblock\c!page}
- {\page[\getvalue{\??sb\@@sectionblock\c!page}]}%
- \resetsectioncounters\zerosection % was firstsection
- \resetsectionmarks\zerosection}
-
-\def\dostartsectionblock#1#2%
- {\begingroup
- \getvalue{\??sb#1}%
- \doaroundsectionblock
-% \doifvaluesomething{\??sb\@@sectionblock\c!page}{\page[\getvalue{\??sb\@@sectionblock\c!page}]}%
-% \resetsectioncounters\zerosection % was firstsection
-% \resetsectionmarks\zerosection
- \getsectionblockenvironment\@@sectionblock
- \setsystemmode\@@sectionblock
- \getvalue{\??sb\@@sectionblock\c!before}%
- \showmessage\m!structures1\@@sectionblocks}
-
-\def\dostopsectionblock
- {\showmessage\m!structures2\@@sectionblocks
- \getvalue{\??sb\@@sectionblock\c!after}% don't move
- \doaroundsectionblock
-% \doifvaluesomething{\??sb\@@sectionblock\c!page}{\page[\getvalue{\??sb\@@sectionblock\c!page}]}%
-% \resetsectioncounters\zerosection % was firstsection
-% \resetsectionmarks\zerosection
- \endgroup}
-
-\def\dosetupsectionblock[#1]% [#2]
- {\getparameters[\??sb#1]}
-
-\def\setupsectionblock
- {\dodoubleargument\dosetupsectionblock}
-
-\long\def\setsectionblockenvironment#1#2%
- {\long\setvalue{\??sb\s!do#1}{\do{#2}}}
-
-\def\getsectionblockenvironment#1%
- {\let\do\firstofoneargument\getvalue{\??sb\s!do#1}}
-
-\setvalue{\e!start\v!sectionblockenvironment}%
- {\dosingleargument\dostartsectionblockenvironment}
-
-\def\dostartsectionblockenvironment[#1]% evt \pushendofline \popendofline
- {\long\def\do##1##2{\setsectionblockenvironment{#1}{##1##2}}%
- \grabuntil{\e!stop\v!sectionblockenvironment}{\getvalue{\??sb\s!do#1}}}
-
-%D \starttyping
-%D \startsectionblockenvironment[frontpart]
-%D \setuppagenumbering[conversion=romannumerals]
-%D \stopsectionblockenvironment
-%D
-%D \startsectionblockenvironment[bodypart]
-%D \setuppagenumber[number=1]
-%D \stopsectionblockenvironment
-%D
-%D \startsectionblockenvironment[frontpart]
-%D \setuppagenumbering[conversion=character]
-%D \stopsectionblockenvironment
-%D
-%D \starttext
-%D \startfrontmatter \chapter{test} \stopfrontmatter
-%D \startbodymatter \chapter{test} \stopbodymatter
-%D \startappendices \chapter{test} \stopappendices
-%D \stoptext
-%D \stoptyping
-
-% We used to use the first char as id, but a counter is
-% better, because in english we get a name clash.
-
-\newcounter\currentsectionblock
-
-\def\currentsection{\@@sectionblock}
-
-\def\dodefinesectionblock[#1][#2][#3]%
- {\getparameters
- [\??sb#1]
- [\c!number=\v!yes,
- \c!page=\v!right, % anders worden marks te vroeg gereset !
- %\c!before=,
- %\c!after=,
- #3]%
- \expandafter\newif\csname if#2\endcsname % better a mode
- \doglobal\increment\currentsectionblock
- \setsectionblockenvironment{#1}{}%
- \setevalue{\??sb #1}{\noexpand\dosetlocalsectionblock{\currentsectionblock}{#1}{#2}}%
- \setvalue {\e!start#2}{\dostartsectionblock{#1}{#2}}%
- \setvalue {\e!stop #2}{\dostopsectionblock}}
-
-\def\definesectionblock
- {\dotripleargument\dodefinesectionblock}
-
-\def\sectionblocklabel#1#2%
- {\@EA\ifx\csname\??ko#1\@@sectionblock\c!label\endcsname\relax
- \labeltexts{#1}{#2}%
- \else
- \labeltexts{\getvalue{\??ko#1\@@sectionblock\c!label}}{#2}%
- \fi}
-
-\dosetlocalsectionblock{2}{\v!bodypart}{\v!bodymatter} % hm, dirty
-
-\def\setsectiontype[#1]%
- {\getvalue{\??sb#1}}
-
-\def\writesection#1#2#3% #3 -> \asciititle
- {\bgroup
- \edef\!!stringa{#1}%
- \@EA\writestatus\@EA
- {\!!stringa}
- {\ifsectionnumber#2\else(#2)\fi\normalspace\asciititle}%
- \egroup}
-
-\def\@@kolevel{1} \def\headlevel{\@@kolevel}
-
-\def\dohandlepagebreakAA#1%
- {\ifnum\lastpenalty>0
- \global\paginageblokkeerdtrue
- \fi}
-
-% \setuphead[section][aligntitle=float] % permits title next to sidefloat
-%
-% \placefigure[left]{}{} \section{\dorecurse{10}{bagger }} \input tufte
-
-% \def\dohandlepagebreakAB#1% will be replaced by a more clever (signaling) mechanism (in beta)
-% {\doifnotvalue{\??ko#1\c!aligntitle}\v!float\flushsidefloats
-% \getvalue{\??ko#1\c!before}%
-% % \whitespace vervangen door \noindent elders
-% \relax
-% \ifpaginageblokkeerd
-% \global\paginageblokkeerdfalse
-% \else
-% \!!countb\getvalue{\??se\@@sectie\c!level}\relax
-% \ifnum\!!countb>\@@kolevel\relax
-% \!!counta20000
-% \multiply\!!countb 500
-% \advance\!!counta \!!countb
-% \dosomebreak{\penalty\!!counta}%
-% \else
-% \dosomebreak\allowbreak
-% \fi
-% \fi
-% \doifvalue{\??ko#1\c!aligntitle}\v!float\indent
-% \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}}
-
-\chardef\somebreakmethod\plusone
-
-\def\dohandlepagebreakAB#1% will be replaced by a more clever (signaling) mechanism (in beta)
- {\doifnotvalue{\??ko#1\c!aligntitle}\v!float\flushsidefloats
- \getvalue{\??ko#1\c!before}%
- % \whitespace vervangen door \noindent elders
- \relax
- \ifpaginageblokkeerd
- \global\paginageblokkeerdfalse
- \else
- \ifcase\somebreakmethod
- % 0 = nothing
- \or
- % 1 = old weighted version
- \!!countb\getvalue{\??se\@@sectie\c!level}\relax
- \ifnum\!!countb>\@@kolevel\relax
- \!!counta20000
- \multiply\!!countb 500
- \advance\!!counta \!!countb
- \dosomebreak{\penalty\!!counta}%
- \else
- \dosomebreak\allowbreak % brr
- \fi
- \or
- % 2 = strict version
- \dosomebreak{\penalty\maxdimen}%
- \else
- % nothing
- \fi
- \fi
- \doifvalue{\??ko#1\c!aligntitle}\v!float\indent
- \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}}
-
-\def\dohandlepagebreakBB#1#2#3%
- {%\doifinsetelse{\getvalue{\??tk#2\c!state}}{\v!normal,\v!start}
- \doifelselayouttextline{#2}
- {\doifvaluesomething{\??ko#1#3}
- {\setuplayouttext[#2][\c!state=\getvalue{\??ko#1#3}]}}
- \donothing}
-
-\def\dohandlepagebreakB#1%
- {\doifvaluesomething{\??ko#1\c!page}
- {\def\resetcurrentsectionmarks% toegevoegd, zie \page
- {\resetsectionmarks{\previoussection\@@sectie}}%
- \page[\getvalue{\??ko#1\c!page}]%
- \dohandlepagebreakBB{#1}\v!header\c!header
- \dohandlepagebreakBB{#1}\v!text \c!text
- \dohandlepagebreakBB{#1}\v!footer\c!footer}}
-
-\def\dohandlepagebreakX#1% zie doordefinieren / boven
- {\bgroup
- \!!countb\@@kolevel
- \advance\!!countb #1
- \multiply\!!countb 500
- \!!counta20000
- \advance\!!counta \!!countb
- \dosomebreak{\penalty\!!counta}%
- \egroup}
-
-\newconditional\ignorehandlepagebreak
-
-\def\handlepagebreak#1%
- {\ifconditional\ignorehandlepagebreak
- \setfalse\ignorehandlepagebreak
- \else
- \dohandlepagebreakAA{#1}%
- \ifnum\countervalue{\??se\previoussection\@@sectie}>\zerocount\relax
- \ifnum\countervalue{\??se\@@sectie}>\zerocount
- \dohandlepagebreakB{#1}%
- \else
- \doifnotvalue{\??ko#1\c!continue}\v!yes{\dohandlepagebreakB{#1}}%
- \fi
- \else
- \dohandlepagebreakB{#1}%
- \fi
- \dohandlepagebreakAB{#1}%
- \fi}
-
-\def\handlenopagebreak#1%
- {\ifconditional\ignorehandlepagebreak
- \setfalse\ignorehandlepagebreak
- \else
- \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}%
- \nobreak
- \fi}
-
-\def\localheadheight {\strutht}
-\def\localheaddepth {\strutdp}
-\def\localheadlineheight{\lineheight}
-
-\def\dolocalheadsetup#1% koppeling met standaard kopcommando / engels
- {\forgetall % traag dus ...
- \doifvaluesomething{\??ko#1\c!align} % wordt al expanded in spa
- {\expanded{\setupalign[\getvalue{\??ko#1\c!align}]}}%
- \doifvaluesomething{\??ko#1\c!tolerance} % wordt al expanded in spa
- {\expanded{\setuptolerance[\getvalue{\??ko#1\c!tolerance}]}}%
- \doifvalue{\??ko#1\c!strut}\v!no % wordt al expanded in spa
- {\setnostrut}% new
- \def\\{\crlf\strut\ignorespaces}}
-
-\def\localkopsetup{\localheadsetup} % kan tzt weg
-
-% todo: make them conditionals:
-
-\newif\ifincrementnumber
-\newif\ifreversesectionnumbers % todo: key/val
-\newif\ifsectionnumber \sectionnumbertrue
-\newif\ifdisplaysectionhead \displaysectionheadtrue
-\newif\ifplacehead
-\newif\ifemptyhead
-\newif\ifwritetolist
-\newif\ifheadnumber
-\newif\ifheadnumbercontent % niet meer wijzigen / wordt mode
-\newif\ifheadprefix
-\newif\ifsomeheadconversion
-
-% new
-
-\newconditional\@@resetsubheadnumbers
-
-\def\setsectieenkoppeling#1%
- {\edef\@@koppeling{\getvalue{\??ko#1\c!coupling}}%
- \edef\@@sectie{\getvalue{\??ko#1\c!section}}%
- \doifnothing\@@koppeling
- {\edef\@@koppeling{#1}}%
- \doifnothing\@@sectie
- {\edef\@@sectie{\getvalue{\??ko\@@koppeling\c!section}}}}
-
-% \handlepagebreak komt het eerst omdat eventueel
-% subpaginanummers moeten worden afgehandeld. Vervolgens
-% worden de nummers opgehoogd en referenties geset, dan
-% volgt de kop en tot slot de worden de marks en de prefix
-% geset.
-
-% \hoofdstuk {tekst}
-% \hoofdstuk tekst
-% \hoofdstuk <niets>
-
-\let\finalsectionnumber\empty
-
-\def\dofinalsectionnumber
- {\ifundefined{\@@sectie\c!number}\else
- \ifsomeheadconversion
- \@@shortsectionnumber\@@sectie
- \else
- \getvalue{\@@sectie\c!number}%
- \fi
- \fi}
-
-\def\findsectionnumber#1#2#3% class file title / uti seperator --
- {\begingroup
- \setsectieenkoppeling{#1}%
- \xdef\foundsectionnumber{1}%
- \def\dolistelement##1##2##3##4##5##6%
- {\doif{##1}{#1}
- {\ConvertConstantAfter\doif{##4}{#3}
- {\global\utilitydonetrue
- \scratchcounter=0\getvalue{\??se\@@sectie\c!level}%
- %
- %\advance\scratchcounter 2
- %\@EA\def\@EA\do\@EA####\@EA1\sectionseparator####2]%
- % {\advance\scratchcounter -1
- % \ifcase\scratchcounter
- % \xdef\foundsectionnumber{####1}%
- % \else
- % \do####2]%
- % \fi}%
- %\do##5]}}}%
- %
- \def\do####1\relax % :/- clean
- {\advance\scratchcounter \minusone
- \ifcase\scratchcounter
- \xdef\foundsectionnumber{\@@filterheadpart[####1]}%
- \else
- \@EAEAEA\do\@@filtertailpart[####1]\relax
- \fi}%
- \@EA\do\@@filternumberpart[##5]\relax}}}%
- \setbox0\vbox
- {\doutilities{#1}{#2}{#1}\relax\relax}%
- \endgroup
- \doifnumberelse\foundsectionnumber
- {\doif\foundsectionnumber\!!zerocount
- {\globallet\foundsectionnumber\!!plusone}}
- {\globallet\foundsectionnumber\!!plusone}% an appendix or so
- \setupheadnumber[#1][\foundsectionnumber]%
- \setupheadnumber[#1][-1]}
-
-% deal with eigennummer
-
-\def\setsomeheadconversion#1#2%
- {\someheadconversionfalse
- \doifelsevalue{\??ko#1\c!ownnumber}\v!yes
- {\setgvalue{\??se\@@sectie\c!ownnumber}{#2}%
- \def\someheadconversion{#2}}
- {\letgvalue{\??se\@@sectie\c!ownnumber}\relax
- \determineheadnumber[#1]%
- \@EA\ifx\csname\??se\@@sectie\@@sectionblock\c!headconversion\endcsname\relax
- \@EA\ifx\csname\??se\@@sectie\c!headconversion\endcsname\relax
- \def\someheadconversion{#2}%
- \else
- \@EA\ifx\csname\??se\@@sectie\c!headconversion\endcsname\empty
- \def\someheadconversion{#2}%
- \else
- \someheadconversiontrue
- \def\someheadconversion%
- {\fullsectionnumber{#1}{\getvalue{\??se\@@sectie\c!headconversion}}{#2}}%
- \fi
- \fi
- \else
- \@EA\ifx\csname\??se\@@sectie\@@sectionblock\c!headconversion\endcsname\empty
- \def\someheadconversion{#2}%
- \else
- \someheadconversiontrue
- \def\someheadconversion%
- {\fullsectionnumber{#1}{\getvalue{\??se\@@sectie\@@sectionblock\c!headconversion}}{#2}}%
- \fi
- \fi}}
-
-\def\writtenfullsectionnumber
- {\string\fullsectionnumber}
-
-\def\ignoredfullsectionnumber#1#2#3%
- {#3}
-
-\let\storedfullsectionnumber\relax
-
-\def\expandablefullsectionnumber#1#2#3%
- {\convertnumber{#2}{#3}}
-
-\unexpanded\def\naturalfullsectionnumber#1#2#3%
- {\sectionblocklabel{#1}{\convertnumber{#2}{#3}}}
-
-\unexpanded\def\limitedfullsectionnumber#1#2#3%
- {\convertnumber{#2}{#3}}
-
-\def\setfullsectionnumber#1%
- {\doifelsevalue{#1\c!headconversion}\v!yes
- {\doifelsevalue{#1\c!headlabel}\v!yes
- {\let\fullsectionnumber\naturalfullsectionnumber}
- {\let\fullsectionnumber\limitedfullsectionnumber}}
- {\let\fullsectionnumber\ignoredfullsectionnumber}}
-
-\let\fullsectionnumber\limitedfullsectionnumber
-
-% \dodododoconstructhead IS NON GROUPED, SO WE NEED TO RESTORE !!!!
-%
-% dit kan dus beter \everyaroundhead zijn
-
-\let\currentheadnumber\empty
-\let\currentheadtext \empty
-
-\def\dodoconstructhead#1[#2]#3% [ref] {title}
- {\doifelsevalue{\??ko#1\c!ownnumber}\v!yes
- {\doquadruplegroupempty\dododoconstructhead{#1}{#2}{#3}}
- {\fourthargumentfalse \dododoconstructhead{#1}{#2}{#3}{}}}
-
-\def\dododoconstructhead#1#2#3#4% [ref] {own} {title}
- {\iffourthargument
- \def\next{\dodododoconstructhead{#1}[#2]{#3}{#4}}%
- \else
- \def\next{\dodododoconstructhead{#1}[#2]{\finalsectionnumber}{#3}}%
- \fi
- \next}
-
-% pas met \ExpandFirstAfter op bij twee||taligheid
-
-\ifx\dohandleheadnumber\undefined
- \let\dohandleheadnumber\firstofoneargument
-\fi
-
-\unexpanded\def\\{\space}
-
-\def\emptyheadcorrection % experimental, should work
- {\ifemptyhead % well with na=\blank
- \vskip-\lineheight
- \dosomebreak\nobreak
- \kern\zeropoint
- \prevdepth\strutdepth
- \fi}
-
-\let\localkopprefix\empty
-
-\def\headparameter#1% to do: everywhere in core-sec
- {\executeifdefined{\??ko\currenthead#1}\empty}
-
-% todo: write to list etc in both args or in enclosing h/vbox else it gets
-% lost when no #1 or #2 is typeset
-
-% we will use variables here
-
-\def\dodododoconstructhead#1[#2]#3#4% [ref] {number} {title}
- {\def\currenthead{#1}% dus #1 overal vervangen
- \let\finalsectionnumber\dofinalsectionnumber % overloaded ungrouped -)
- \unexpanded\def\\{\space}%
- \edef\numberseparator{\spr{\getvalue{\??ko\currenthead\c!separator}}}%
- \flushingcolumnfloatsfalse % {number} can be \finalsectionnumber
- \someheadconversionfalse
- \let\fullsectionnumber\limitedfullsectionnumber
- \setsectieenkoppeling{#1}%
- \doifelsevaluenothing{\??ko#1\c!prefix}
- \headprefixfalse\headprefixtrue
- \ifheadprefix
- \doifelsevalue{\??ko#1\c!prefix}{+}
- {\doifelsenothing{#2}
- {\def\localkopprefix{+}}
- {\def\localkopprefix{#2}}} % eigenlijk alleen eerste
- {\edef\localkoprefix{\getvalue{\??ko#1\c!prefix}}}%
- \else
- \let\localkoprefix\empty
- \fi
- \placeheadtrue
- \processaction
- [\getvalue{\??ko#1\c!placehead}]
- [ \v!yes=>\emptyheadfalse,
- \v!empty=>\emptyheadtrue,
- \v!no=>\emptyheadtrue\placeheadfalse]%
- \doifelsevalue{\??ko#1\c!resetnumber}\v!no
- {\setfalse\@@resetsubheadnumbers}%
- {\settrue \@@resetsubheadnumbers}%
- \writetolistfalse
- \processaction
- [\getvalue{\??ko#1\c!incrementnumber}]
- [ \v!yes=>\incrementnumbertrue,
- \v!no=>\incrementnumberfalse,
- \v!list=>\incrementnumberfalse
- % beware, since no numbers are used, no nested lists are
- % possible here
- \writetolisttrue,
- \s!unknown=>{\ifx\currentproduct\empty
- \findsectionnumber{#1}\commalistelement{#4}%
- \fi
- \incrementnumbertrue}]%
- \edef\numberheaddistance {\getvalue{\??ko#1\c!distance}}%
- \edef\numberheadalternative{\getvalue{\??ko#1\c!alternative}}%
- \doifelsevalue{\??ko:\numberheadalternative}\v!horizontal
- \displaysectionheadfalse
- \displaysectionheadtrue
- \ifsectionnumber
- \doifelsevalue{\??sb\@@sectionblock\c!number}\v!yes
- {\doifelsevalue{\??ko#1\c!number}\v!yes
- \headnumbertrue
- \headnumberfalse}
- {\headnumberfalse}%
- \else
- \headnumberfalse
- \fi
- \defconvertexpanded\asciititle{\getvalue{\??ko#1\c!expansion}}{#4}%
- %
- \gdef\currentheadtext{#4}% scheelt args
- \globallet\currentheadnumber\empty
- %
- \ifincrementnumber
- \ifplacehead
- \checknexthead\handlepagebreak{#1}%
- \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...]
- \ifheadprefix
- %\setupreferencing[\c!prefix=-]%
- \setupreferenceprefix[-]%
- \fi
- \getvalue{\e!next\@@sectie}%
- \ifheadnumber
- \setsomeheadconversion{#1}{#3}%
- \let\fullsectionnumber\expandablefullsectionnumber
- \xdef\currentheadnumber{\someheadconversion}%
- \getvalue{\??ko#1\c!inbetween}%
- \ifsomeheadconversion
- \let\fullsectionnumber\naturalfullsectionnumber
- \doplaceheadnumbertext
- {#1}
- {\setsectionlistreference{\@@sectie}{#1}%
- \pagetype[\@@koppeling]%
- \let\fullsectionnumber\writtenfullsectionnumber
- \rawreference\s!sec{#2}{{\someheadconversion}{\asciititle}}%
- \resetsectionmarks\@@sectie
- \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}%
- \let\fullsectionnumber\writtenfullsectionnumber
- \dowritetolist\@@koppeling\someheadconversion{#4}\v!head}%
- {\dohandleheadnumber\someheadconversion}% handle is new
- {#4}
- {\marking[#1]{#4}%
- \let\fullsectionnumber\storedfullsectionnumber
- \expanded{\marking[#1\v!number]{\someheadconversion}}}%
- \let\fullsectionnumber\ignoredfullsectionnumber
- \writesection{#1}{\someheadconversion}{#4}%
- \else
- \doplaceheadnumbertext
- {#1}
- {\setsectionlistreference{\@@sectie}{#1}%
- \pagetype[\@@koppeling]%
- \rawreference\s!sec{#2}{{#3}{\asciititle}}%
- \resetsectionmarks\@@sectie
- \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}%
- \dowritetolist\@@koppeling{#3}{#4}\v!head}
- {\sectionblocklabel{#1}{\dohandleheadnumber{#3}}}% handle is new
- {#4}
- {\marking[#1]{#4}%
- \doifelsevalue{\??ko#1\c!ownnumber}\v!yes % rommelig omdat
- {\edef\finalsectionnumber{#3}} % #3 al is toegekend
- {\determineheadnumber[#1]}% migreert naar 3e argument
- \expanded{\marking[#1\v!number]{\finalsectionnumber}}}%
- \writesection{#1}{#3}{#4}%
- \fi
- \else
- \getvalue{\??ko#1\c!inbetween}%
- \doplaceheadtext
- {#1}
- {\setsectionlistreference{\@@sectie}{#1}%
- \pagetype[\@@koppeling]%
- \rawreference\s!sec{#2}{{#3}{\asciititle}}%
- \resetsectionmarks\@@sectie
- \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}%
- \doifelsevalue{\??ko#1\c!ownnumber}\v!yes % brrr, new per 18/1/2005, sometimes we need
- {\dowritetolist\@@koppeling{#3}{#4}\v!head} % entries in the list (special purpose) but
- {\dowritetolist\@@koppeling {}{#4}\v!head}% not in the header, ok we could pop in a command
- }% \dowritetolist\@@koppeling{}{#4}\v!head}
- {#4}
- {\marking[#1]{#4}%
- \doifelsevalue{\??ko#1\c!ownnumber}\v!yes % brrr
- {\edef\finalsectionnumber{#3}}
- {\determineheadnumber[#1]}%
- % todo : geen markering (leeg maken)
- \expanded{\marking[#1\v!number]{\finalsectionnumber}}}%
- \writesection{#1}{-}{#4}%
- \fi
- \ifheadprefix
- \setupreferenceprefix[\localkopprefix]%
- \fi
- \ifdisplaysectionhead
- \dosomebreak\nobreak
- \emptyheadcorrection
- \getvalue{\??ko#1\c!after}%
- \fi
- \else
- % Whatever future tex's will do with nodes,
- % we assume a node here, because other \c!after=\blank
- % will fail! See 'prikkels'
- %
- % so, maybe we need an explicit \kern
- %
- % do nothing / should be vbox to 0pt
- %
- \checknexthead\dohandlepagebreakB{#1}% toegevoegd ivm subpaginanr / tug sheets
- \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...]
- \ifheadprefix
- \setupreferenceprefix[-]%
- \fi
- \getvalue{\e!next\@@sectie}%
- \ifheadnumber
- \setsomeheadconversion{#1}{#3}%
- \let\fullsectionnumber\expandablefullsectionnumber
- \xdef\currentheadnumber{\someheadconversion}%
- \fi
- \getvalue{\??ko#1\c!inbetween}% documenteren, is enige hook
- \bgroup
- \setsectionlistreference{\@@sectie}{#1}%
- \resetsectionmarks\@@sectie
- \marking[#1]{#4}%
- \doifelsevalue{\??ko#1\c!ownnumber}\v!yes
- {\edef\finalsectionnumber{#3}}
- {\determineheadnumber[#1]}%
- \expanded{\marking[#1\v!number]{\finalsectionnumber}}%
- \pagetype[\@@koppeling]%
-% \bgroup
- \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}%
- \ifheadnumber
- \rawreference\s!sec{#2}{{#3}{\asciititle}}%
- \dowritetolist\@@koppeling{#3}{#4}\v!head
- \writesection{#1}{#3}{#4}%
- \else % hm, also no own number
- \rawreference\s!sec{#2}{{#3}{\asciititle}}%
- \dowritetolist\@@koppeling{}{#4}\v!head
- \writesection{#1}{-}{#4}%
- \fi
- \egroup
- \ifheadprefix
- \setupreferenceprefix[\localkopprefix]%
- \fi
- \fi
- \else
- % todo : ref prefix
- \ifplacehead
- \checknexthead\handlepagebreak{#1}%
- \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...]
- \getvalue{\??ko#1\c!inbetween}%
- \doplaceheadtext
- {#1}
- {\forcesectiontolist{#1}{#4}%
- \rawreference\s!sec{#2}{{#3}{\asciititle}}} % #3 ?
- {#4}
- %{}% new:
- {\marking[#1]{#4}%
- \marking[#1\v!number]{}}%
- \writesection{#1}{-}{#4}%
- \ifdisplaysectionhead
- \dosomebreak\nobreak
- \emptyheadcorrection
- \getvalue{\??ko#1\c!after}%
- \fi
- \else
- % do nothing / should be vbox to 0pt
- \checknexthead\handlepagebreak{#1}%
- \setsectieenkoppeling{#1}% can be changed when [voor=\somehead{..}...]
- \getvalue{\??ko#1\c!inbetween}%
- \forcesectiontolist{#1}{#4}%
- \rawreference\s!sec{#2}{{#3}{\asciititle}}% #3 ?
- \marking[#1]{#4}%
- \marking[#1\v!number]{}%
- \writesection{#1}{-}{#4}%
- \fi
- \fi
- \flushingcolumnfloatstrue
- \someheadconversionfalse
- \setfalse\ignorehandlepagebreak
- \let\fullsectionnumber\limitedfullsectionnumber
- % ignorespaces prevents spaces creeping in when after=\dontleavehmode
- \ifdisplaysectionhead\ignorespaces\else\expandafter\GotoPar\fi}
-
-\def\forcesectiontolist#1#2%
- {\ifwritetolist
- % we need to make sure that there is a number set (non
- % zero) else the list mechanism cannot determine the
- % level
- \bgroup
- \setupheadnumber[#1][+1]% traag, wordt \getvalue{\c!next...}
- \setlistparameter\@@koppeling\c!expansion{\getvalue{\??ko#1\c!expansion}}%
- \dowritetolist\@@koppeling{}{#2}\v!head
- \setupheadnumber[#1][-1]% traag, wordt \getvalue{\c!previous...}
- \egroup
- \fi}
-
-\let\previoussectionformat\empty
-\let\currentsectionformat \empty
-
-\let\updatelistreferences \relax
-\let\updatedlistreferences\empty
-
-\def\setsectionlistreference#1#2%
- {\ifnum\countervalue{\??se\previoussection{#1}}>0\relax
- \xdef\previoussectionformat{\@@longformatnumber{\previoussection{#1}}}%
- \else
- \globallet\previoussectionformat\empty
- \fi
- \xdef\currentsectionformat{\@@longformatnumber{#1}}}
-
-\def\startlistreferences#1%
- {\thisissomeinternal{\s!lst}{#1\currentsectionformat}%
- \setxvalue{\s!lst:#1}{\realfolio}% to be sure
- \setxvalue{\s!lst:#1\currentsectionformat}{\realfolio}%
- \setxvalue{\e!previouslocal#1}{\s!lst:#1\previoussectionformat}%
- \setxvalue{\e!currentlocal#1}{\s!lst:#1\currentsectionformat}%
- \doifelse{\currentsectionformat}{}
- {\setglobalcrossreference
- {\e!previous#1}{}{\realfolio}{}}
- {\setglobalsystemreference\rt!list
- {\e!previous#1}{\getvalue{\e!previouslocal#1}}}%
- \def\stoplistreferences{\dostoplistreferences{#1}}}
-
-\def\dostoplistreferences#1%
- {\ifutilitydone
- \addtocommalist{#1}\updatedlistreferences % nog global (\doglobal)
- \globallet\updatedlistreferences\updatedlistreferences % een noodverbandje
- \gdef\updatelistreferences%
- {\def\docommand####1%
- {\setglobalsystemreference\rt!list
- {\e!previous####1}{\getvalue{\e!currentlocal####1}}}%
- \processcommacommand[\updatedlistreferences]\docommand
- \globallet\updatelistreferences\relax
- \globallet\updatedlistreferences\empty}%
- \fi}
-
-\let\stoplistreferences\relax
-
-\appendtoks
- \updatelistreferences
-\to\aftereverypage
-
-% \prevdepth\strutdp % is belangrijk, vergelijk naast elkaar:
-%
-% \subject{test} \input tufte
-% \subject{test} \strut \input tufte
-% \subject{test} \placelist[...]
-
-% todo: kap
-
-% to be documented: \placeheadtext \placeheadnumber
-
-\unexpanded\def\placeheadtext
- {\doquintupleempty\doplaceheadtextornumber
- [\c!textstyle][\c!textcolor][\empty]}
-
-\unexpanded\def\placeheadnumber
- {\doquintupleempty\doplaceheadtextornumber
- [\c!numberstyle][\c!numbercolor][\v!number]}
-
-\def\doplaceheadtextornumber[#1][#2][#3][#4][#5]%
- {\bgroup
- \edef\@@sectie{\??ko\iffifthargument#5\else#4\fi}%
- \dostartattributes\@@sectie\c!style\c!color\empty
- \dontconvertfont
- \dostartattributes\@@sectie{#1}{#2}\empty
- \setupinterlinespace
- \begstrut\getmarking[\mainmarking{#4#3}]\endstrut
- \endgraf
- \dostopattributes
- \dostopattributes
- \egroup}
-
-\chardef\headtimingmode=0
-
-% \chardef\headtimingmode=1 % 0 also works ok now too
-%
-% Martin Kolarik's problem:
-%
-% \setuphead[section][command=\doTitle]
-%
-% \def\doTitle#1#2%
-% {\ruledvbox{\forgetall \hsize=4cm
-% \ruledhbox{\ruledvtop{#1}\ruledvtop{#2}}}}
-%
-% \section{test test test test test test test test test test
-% test test test test test test test}
-
-\newevery \everyheadstart \relax
-
-\def\placeheadmargintexts#1%
- {\the\everyheadstart
- \doifvalue{\??ko#1\c!margintext}\v!yes\placemargincontent}
-
-\def\doplaceheadtext#1#2#3#4%
- {\beginheadplacement{#1}%
- \ifemptyhead % = needed
- \setbox0=\ifvertical\vbox\else\hbox\fi to \zeropoint
- {\headnumbercontentfalse
- \resetsystemmode\v!sectionnumber
- #2}%
- \makestrutofbox0
- \else % = needed
- \setbox0=\ifvertical\vbox\else\hbox\fi % \vhbox
- {\headnumbercontentfalse
- \resetsystemmode\v!sectionnumber
- % less interfering
- \ifcase\headtimingmode\or#2\fi
- % outerside font determines distance
- \dosetfontattribute{\??ko#1}\c!style
- \dosetcolorattribute{\??ko#1}\c!color
- % todo: get the if-else out of it
- \getvalue{\??ko#1\c!command}
- {} % no number
- {\dostartattributes{\??ko#1}\c!textstyle\c!textcolor\empty
- \dontconvertfont
- \ifdisplaysectionhead
- \setupinterlinespace
- \else
- \setupspacing
- \fi
- % \ifcase\headtimingmode#2\fi % can introduce cr
- \getvalue{\??ko#1\c!commandbefore}%
- \placeheadmargintexts{#1}% binnen #3?
- \ifdisplaysectionhead
- \getvalue{\??ko#1\c!textcommand}% struts can be nilled with \setnostrut
- {\setstrut
- \begstrut
- \ifcase\headtimingmode\hbox{#2}\fi
- \executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#3}%
- \endstrut}% \hbox prevents break
- \xdef\localheadheight {\the\strutht}%
- \xdef\localheaddepth {\the\strutdp}%
- \xdef\localheadlineheight{\the\lineheight}%
- % == \globallet\localheaddepth\strutdepth
- \else
- \ifcase\headtimingmode#2\fi
- \getvalue{\??ko#1\c!textcommand}%
- {\executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#3}}%
- \fi
- \getvalue{\??ko#1\c!commandafter}%
- \ifdisplaysectionhead\endgraf\fi
- \dostopattributes}}%
- \fi
- \endheadplacement{#1}{#4}}
-
-\def\doplaceheadnumbertext#1#2#3#4#5% maybe move modes outside box
- {\beginheadplacement{#1}%
- \ifemptyhead % = needed
- \setbox0=\ifvertical\vbox\else\hbox\fi to \zeropoint
- {\doiftextelse{#3}
- {\setsystemmode \v!sectionnumber\headnumbercontenttrue }
- {\resetsystemmode\v!sectionnumber\headnumbercontentfalse}%
- #2}%
- \makestrutofbox0
- \else % = needed
- \setbox0=\ifvertical\vbox\else\hbox\fi % \vhbox
- {\doiftextelse{#3}
- {\setsystemmode \v!sectionnumber\headnumbercontenttrue }
- {\resetsystemmode\v!sectionnumber\headnumbercontentfalse}%
- % less interfering
- \ifcase\headtimingmode\or#2\fi
- % outerside font determines distance
- \dosetfontattribute{\??ko#1}\c!style
- \dosetcolorattribute{\??ko#1}\c!color
- % but we don't want color to influence user commands
- \getvalue{\??ko#1\c!command}%
- {\dostartattributes{\??ko#1}\c!numberstyle\c!numbercolor\empty
- % \getvalue{\??ko#1\c!commandbefore}% strange, why here? moved 21/11/2005
- \placeheadmargintexts{#1}% binnen #3?
- \ifdisplaysectionhead
- % can be nilled with \setnostrut
- \getvalue{\??ko#1\c!numbercommand}%
- {\setstrut
- \begstrut
- \executeifdefined{\??ko#1\c!deepnumbercommand}\firstofoneargument{#3}%
- \endstrut}%
- \else
- \getvalue{\??ko#1\c!numbercommand}%
- {\executeifdefined{\??ko#1\c!deepnumbercommand}\firstofoneargument{#3}}%
- \fi
- \dostopattributes}
- {\dostartattributes{\??ko#1}\c!textstyle\c!textcolor\empty
- \dontconvertfont
- \ifdisplaysectionhead
- \setupinterlinespace
- \else
- \setupspacing
- \fi
- % \ifcase\headtimingmode#2\fi % can introduce cr
- \getvalue{\??ko#1\c!commandbefore}% makes more sense here
- \placeheadmargintexts{#1}% binnen #3?
- \ifdisplaysectionhead
- \getvalue{\??ko#1\c!textcommand}% struts can be nilled with \setnostrut
- {\setstrut
- \begstrut
- \ifcase\headtimingmode\hbox{#2}\fi
- \executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#4}%
- \endstrut}% \hbox prevents break
- \xdef\localheadheight {\the\strutht}%
- \xdef\localheaddepth {\the\strutdp}%
- \xdef\localheadlineheight{\the\lineheight}%
- % == \globallet\localheaddepth\strutdepth
- \else
- \ifcase\headtimingmode#2\fi % inside textcommand ?
- \getvalue{\??ko#1\c!textcommand}%
- {\executeifdefined{\??ko#1\c!deeptextcommand}\firstofoneargument{#4}}%
- \fi
- \getvalue{\??ko#1\c!commandafter}%
- \ifdisplaysectionhead\endgraf\fi
- \dostopattributes}}%
- \fi
- \endheadplacement{#1}{#5}}
-
-
-
-%D \starttyping
-%D \def\StretchedBox#1%
-%D {\framed
-%D [frame=off,offset=.5em,align=middle,width=broad]
-%D {\sc\def\stretchedspaceamount{.3em}\stretchednormalcase{#1}}}
-%D
-%D \definehead[MySubject][subject]
-%D \setuphead [MySubject][deeptextcommand=\StretchedBox]
-%D
-%D \MySubject{feeling stretched feeling stretched feeling stretched feeling stretched}
-%D \stoptyping
-
-\newsignal\headsignal
-\let\headlastlinewidth\!!zeropoint
-
-\def\beginheadplacement#1%
- {\bgroup
- \setsystemmode{#1}% to be documented
- \ifgridsnapping\iftracegridsnapping\showstruts\fi\fi
- \xdef\localheadheight {\the\strutht}%
- \xdef\localheaddepth {\the\strutdp}%
- \xdef\localheadlineheight{\the\lineheight}%
- % == \globallet\localheaddepth\strutdp
- \everypar\emptytoks % needed indeed
- \noindent % ipv \whitespace elders, na \forgetall !
- \bgroup
- \doifinsetelse{\getvalue{\??ko#1\c!aligntitle}}{\v!yes,\v!float}% new
- {\skip0 1\leftskip
- \skip2 1\rightskip
- \xdef\localheadskip{\the\skip0}%
- \forgetall
- \leftskip\skip0
- \rightskip\skip2
- \setlocalhsize\hsize\localhsize
- \forgetbothskips}
- {\globallet\localheadskip\!!zeropoint
- \forgetall}%
- \dontcomplain
- \postponefootnotes
- \iflocation\ifdisplaysectionhead\else\noninterferingmarks\fi\fi
- \resetinteractionparameter\c!style
- \resetinteractionparameter\c!color
- \resetinteractionparameter\c!contrastcolor
- \strictouterreferencestrue % tzt instelling
- \def\localheadsetup{\dolocalheadsetup{#1}}%
- \startsynchronization}
-
-% \setuphead[chapter] [style=\bfd,after=,hang=line] % fit broad 2
-% \setuphead[section] [style=\bfc,after=,hang=line]
-% \setuphead[subsection] [style=\bfb,after=,hang=line]
-% \setuphead[subsubsection] [style=\bfa,after=,hang=line]
-% \setuphead[subsubsubsection][style=\bf ,after=,hang=line]
-%
-% \chapter {Test} \input tufte \page
-% \section {Test} \input tufte \page
-% \subsection {Test} \input tufte \page
-% \subsubsection {Test} \input tufte \page
-% \subsubsubsection{Test} \input tufte \page
-%
-% \chapter {Test\\Test} \input tufte \page
-% \section {Test\\Test} \input tufte \page
-% \subsection {Test\\Test} \input tufte \page
-% \subsubsection {Test\\Test} \input tufte \page
-% \subsubsubsection{Test\\Test} \input tufte \page
-
-\def\hangheadplacement
- {\scratchdimen\localheadlineheight
- \bgroup
- \openlineheight\scratchdimen
- \scratchdimen\ht0
- \advance\scratchdimen\dp0
- \getnoflines\scratchdimen
- \advance\noflines\minusone
- \expanded{\egroup\noflines\the\noflines}% brrr
- \setbox0\hbox{\lower\noflines\scratchdimen\box0}%
- \scratchdimen\ht0
- \advance\scratchdimen\dp0
- \advance\scratchdimen-\localheadheight
- \advance\scratchdimen+\strutdp
- \ht0 \strutht
- \dp0 \strutdp
- \edef\localheaddepth{\the\strutdp}}
-
-\newconditional\continuoussectionhead % oeps, \newif\ifcontinuoushead got lost
-
-\def\endheadplacement#1#2%
- {\doifelsevalue{\??rf#1\c!state}\v!start
- {\doifvaluenothing{\??ko#1\c!file}{\autocrossdocumentfalse}}
- {\autocrossdocumentfalse}%
- % no message needed here, should be a proper switch
- \noflines\zerocount
- \ifdisplaysectionhead
- % new (tod tight == one following line up)
- \processaction
- [\getvalue{\??ko#1\c!hang}]
- [ \v!line=>\hangheadplacement\noflines\zerocount,
- \v!broad=>\hangheadplacement\getnoflines\scratchdimen,
- \v!fit=>\hangheadplacement\getrawnoflines\scratchdimen,
- \v!none=>\noflines\zerocount,
- \v!default=>\noflines\zerocount,
- \v!unknown=>\hangheadplacement\noflines0\commalistelement\advance\noflines\minusone]%
- % so far
- \let\headlastlinewidth\!!zeropoint
- \snaptogrid[\getvalue{\??ko#1\c!grid}]\hbox
- {\hskip\localheadskip
- \hskip\getvalue{\??ko#1\c!margin}\relax
- \iflocation
- \ifautocrossdocument
- \doifreferencefoundelse{\getvalue{\??ko#1\c!file}::#1}
- {\edef\currentinnerreference{\s!aut:\currenttextreference}% stored in
- \gotoouterlocation{}{\box0}} % text slot
- {\hbox{\box0}}%
- \else
- \hbox{\box0}%
- \fi
- \else
- \hbox{\box0}%
- \fi}%
- \doflushnotes % new, not really needed
- \endgraf
- \ifvmode
- \ifnum\noflines>\zerocount
- \dorecurse\noflines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}%
- \fi
- \nointerlineskip
- \dosomebreak\nobreak
- \fi
- #2%
- \else
- \strut
- \doflushnotes % new, here since we're in par mode
- \iflocation
- \ifautocrossdocument
- \hhboxindent=\ifconditional\continuoussectionhead\headlastlinewidth\else\zeropoint\fi
- \unhhbox0\with{\gotobox{\box\hhbox}[\getvalue{\??ko#1\c!file}::#1]}%
- \advance\lasthhboxwidth by \numberheaddistance
- \xdef\headlastlinewidth{\the\lasthhboxwidth}%
- \else
- \unhbox0
- \globallet\headlastlinewidth\!!zeropoint
- \fi
- \else
- \unhbox0
- \globallet\headlastlinewidth\!!zeropoint
- \fi
- #2%
- \dimen0=\numberheaddistance
- \hskip\dimen0 \!!plus \dimen0 \!!minus .25\dimen0
- \hskip\headsignal\ignorespaces
- \fi
- \ifdisplaysectionhead \ifvmode
- \ifgridsnapping % important, font related depth, see comment
- \prevdepth\strutdp
- \else
- \prevdepth\localheaddepth
- \fi
- \fi \fi
- \stopsynchronization
- \egroup
- \egroup
- \ifdisplaysectionhead
- \dochecknextindentation{\??ko#1}%
- \else
- \nonoindentation % recently added, was a bug
- \fi}
-
-\def\checknexthead#1#2% nog optioneel
- {\ifhmode
- \scratchcounter=\lastpenalty\unpenalty % no beauty in this
- \ifdim\lastskip=\headsignal
- \handlenopagebreak{#1}%
- \global\settrue\continuoussectionhead
- \else
- \penalty\scratchcounter
- \global\setfalse\continuoussectionhead
- #1{#2}%
- \fi
- \else
- \global\setfalse\continuoussectionhead
- #1{#2}%
- \fi}
-
-\def\dosetupheadnumber[#1][#2#3]% todo: = (don't reset)
- {\bgroup
- \setsectieenkoppeling{#1}%
- \doifinstringelse{#2}{+-}
- {\doifelsenothing{#3}
- {\@@nextsectionnumber\@@sectie}
- {\!!counta=#2#3\relax
- \advance\!!counta \@@sectionvalue\@@sectie
- \@@setsectionnumber\@@sectie\!!counta}}
- {\@@setsectionnumber\@@sectie{#2#3}}%
- \egroup}
-
-\def\setupheadnumber
- {\dodoubleargument\dosetupheadnumber}
-
-\def\currentheadnumber{0}
-
-\def\determineheadnumber[#1]%
- {\bgroup
- \setsectieenkoppeling{#1}%
- \xdef\currentheadnumber{\@@sectionvalue{\@@sectie}}%
- \egroup}
-
-\def\complexheadnumber[#1]%
- {\bgroup
- \edef\currentheadnumber{#1}%
- \doifinsetelse{-}{#1} % br undocumented
- {\removefromcommalist{-}\currentheadnumber % br
- \setsectieenkoppeling\currentheadnumber
- \setupsection[\@@sectie][\c!previousnumber=\v!no]}%
- {\setsectieenkoppeling\currentheadnumber}%
- \xdef\currentheadnumber{\@@sectionvalue{\@@sectie}}%
- \doifnot{\currentheadnumber}{0}{\finalsectionnumber}%
- \egroup}
-
-\def\simpleheadnumber
- {\currentheadnumber}
-
-\definecomplexorsimple\headnumber
-
-\def\alinea
- {\par}
-
-% nice testcase
-%
-% \setupheads[aligntitle=yes]
-%
-% \startnarrower
-% \subject{\dorecurse{100}{x }}
-% \section{\dorecurse{100}{x }}
-% \input tufte \par
-% \setupheads[alternative=inmargin]
-% \subject{\dorecurse{100}{x }}
-% \section{\dorecurse{100}{x }}
-% \input tufte \par
-% \stopnarrower
-
-\let\numberheadalternative\v!normal
-
-\def\defineheadplacement
- {\dodoubleargument\dodefineheadplacement}
-
-\def\dodefineheadplacement[#1][#2]% #3#4
- {\setvalue{\??ko:#1}{#2}%
- \setvalue{\??ko::#1}}
-
-\def\normalplacehead
- {\executeifdefined
- {\??ko::\numberheadalternative}
- {\getvalue{\??ko::\v!normal}}}
-
-\defineheadplacement[\v!paragraph][\v!vertical]#1#2%
- {\vbox
- {\localheadsetup
- \begstrut\ifheadnumbercontent#1\hskip\numberheaddistance\fi#2}}
-
-% \defineheadplacement[\v!normal][\v!vertical]#1#2%
-% {\ifheadnumbercontent
-% \setbox0\hbox{{#1}\hskip\numberheaddistance}%
-% \vbox
-% {\localheadsetup
-% \hangindent 1\wd0
-% \hangafter 1
-% \noindent
-% \unhbox0 % don't use \strut's here!
-% #2}%
-% \else
-% \vbox
-% {\localheadsetup\noindent#2}%
-% \fi}
-%
-% enhanced version:
-
-% \setuphead
-% [chapter]
-% [numberwidth=2cm,hang=line,after={\blank[3*line]}]
-%
-% \chapter{Oeps oeps oeps} \input tufte \section{Oeps}
-% \chapter{Oeps oeps oeps} \section{Oeps} \input tufte
-
-\defineheadplacement[\v!normal][\v!vertical]#1#2%
- {\vbox
- {\localheadsetup
- \edef\headwidth {\headparameter\c!width }%
- \edef\headnumberwidth{\headparameter\c!numberwidth}%
- \edef\headtextwidth {\headparameter\c!textwidth }%
- \ifheadnumbercontent
- \ifx\headwidth\empty
- \else
- \ifx\headnumberwidth\empty
- \ifx\headtextwidth\empty\else
- \edef\headnumberwidth{\the\dimexpr\headwidth-\headtextwidth\relax}%
- \fi
- \else
- \ifx\headtextwidth\empty
- \edef\headtextwidth{\the\dimexpr\headwidth-\headnumberwidth\relax}%
- \fi
- \fi
- \hsize\headwidth
- \fi
- \ifx\headnumberwidth\empty\else
- \let\numberheaddistance\!!zeropoint
- \fi
- \setbox\scratchbox\hbox \ifx\headnumberwidth\empty\else to \headnumberwidth\fi{{#1}}%
- \scratchdimen\dimexpr\wd\scratchbox+\numberheaddistance\relax
- \ifx\headtextwidth\empty\else
- \hsize\dimexpr\scratchdimen+\headparameter\c!textwidth\relax
- \fi
- \hangindent\scratchdimen
- \hangafter \plusone
- \noindent
- \box\scratchbox\hskip\numberheaddistance
- \else
- \ifx\headtextwidth\empty
- \ifx\headwidth\empty
- \else
- \hsize\headwidth
- \fi
- \else
- \hsize\headtextwidth
- \fi
- \noindent
- \fi
- #2}}
-
-\def\placeheadmargin#1#2%
- {\vbox
- {\localheadsetup
- \begstrut % use one \strut here!
- \dontleavehmode % in case there is no strut, else side effects with llap
- \ifheadnumbercontent
- \llap{\hbox to 5em{\hfill{#1}\hskip\localheadskip\hskip\leftmargindistance}}% introduces whitespace
- % maybe better:
- % \inleftmargin{\hbox{\hss{#1}\hskip\localheadskip}}%
- \fi
- {#2}}}
-
-\defineheadplacement[\v!inmargin][\v!vertical]#1#2{\placeheadmargin{#1}{#2}}
-\defineheadplacement[\v!margin] [\v!vertical]#1#2{\placeheadmargin{#1}{#2}}
-
-\defineheadplacement[\v!middle][\v!vertical]#1#2%
- {\vbox
- {\localheadsetup
- \veryraggedcenter
- \let\\\endgraf
- \let\crlf\endgraf
- \ifheadnumbercontent\strut#1\par\fi\begstrut#2}}
-
-\defineheadplacement[\v!text][\v!horizontal]#1#2%
- {\bgroup
- \localheadsetup % no stretch in distance
- \ifheadnumbercontent{#1}\kern\numberheaddistance\fi{\begstrut#2}%
- \egroup}
-
-\def\placeheadlohi#1#2#3%
- {\ifheadnumbercontent
- \setbox0\hbox{#2}
- \setbox2=#1{\localheadsetup\advance\hsize-\wd0\relax#3}%
- \hbox{\box0\hskip\numberheaddistance\box2}%
- \else
- #1{\localheadsetup\noindent#3}%
- \fi}
-
-% onder/boven lijnt het nummer op de onderste/bovenste regel
-% uit van een meerregelige kop
-
-\defineheadplacement[\v!bottom][\v!vertical]#1#2{\placeheadlohi\vbox{#1}{#2}}
-\defineheadplacement[\v!top] [\v!vertical]#1#2{\placeheadlohi\vtop{#1}{#2}}
-
-% default == instellingen
-% koppeling == koppen, breaks, marks, enz.
-% sectie == nummering
-
-\let\@@kolist=\empty
-
-\def\dododefinehead#1#2% % don't preset prefix to much
- {\presetlabeltext[#1=]%
-% \getparameters
-% [\??ko#1]
-% [\c!numberstyle=\getvalue{\??ko#1\c!style},
-% \c!textstyle=\getvalue{\??ko#1\c!style},
-% \c!numbercolor=\getvalue{\??ko#1\c!color},
-% \c!textcolor=\getvalue{\??ko#1\c!color}]%
- % deeptextcommand and deepnumbercommand are left undefined !
- \doifassignmentelse{#2}
- {\getparameters
- [\??ko#1]
- [\c!section=\getvalue{\??ko\getvalue{\??ko#1\c!coupling}\c!section},
-\c!numberstyle=,
-\c!textstyle=,
-\c!numbercolor=,
-\c!textcolor=,
- \c!default=,
- \c!coupling=,
- \c!prefix=,
- \c!before=,
- \c!after=,
- \c!distance=\!!zeropoint,
- \c!page=,
- \c!header=,
- \c!text=,
- \c!footer=,
- \c!style=,
- \c!numbercommand=,
- \c!textcommand=,
- \c!ownnumber=\v!no,
- \c!number=\v!yes,
- \c!color=,
- \c!continue=\v!yes,
- \c!placehead=\v!yes,
- \c!resetnumber=\v!yes,
- \c!incrementnumber=\v!yes,
- \c!alternative=\@@koalternative,
- \c!command=\normalplacehead,
- \c!separator=\@@koseparator,
- \c!stopper=\@@kostopper,
- \c!align=\@@koalign,
- \c!aligntitle=\@@koaligntitle,
- \c!tolerance=\@@kotolerance,
- \c!indentnext=\@@koindentnext,
- \c!strut=\@@kostrut,
- \c!hang=\@@kohang,
- \c!file=,
- \c!expansion=,
- \c!grid=,
- \c!margintext=,
- \c!margin=\@@komargin,
- #2]%
- \ConvertToConstant\doifnot{#1}{\getvalue{\??ko#1\c!default}}
- {\doifsomething{\getvalue{\??ko#1\c!default}}
- {\copyparameters
- [\??ko#1][\??ko\getvalue{\??ko#1\c!default}]
- [\c!before,\c!after,\c!command,\c!file,\c!page,\c!continue,
- \c!header,\c!text,\c!footer,\c!separator,\c!stopper,\c!resetnumber,
- \c!number,\c!ownnumber,\c!placehead,\c!incrementnumber,
- \c!style,\c!color,\c!distance,\c!alternative,\c!indentnext,
- % new per 20/03/3002 (o-pbu-l) / was too confusing
- % \c!numberstyle,\c!textstyle,\c!expansion,
- % again too confusing
- \c!align,\c!aligntitle,\c!tolerance,\c!grid,\c!hang,\c!strut,
- \c!numbercommand,\c!textcommand,\c!margintext,\c!margin]}}%
- \getparameters[\??ko#1][#2]%
- \doifsomething{\getvalue{\??ko#1\c!section}}
- {\doifelsemarking{#1}% \doifundefined{\??mk#1}
- {}% marking #1 already defined
- {\definemarking[#1]%
- \couplemarking[#1][\getvalue{\??ko#1\c!section}]%
- \definemarking[#1\v!number]%
- \couplemarking[#1\v!number][\getvalue{\??ko#1\c!section}]}}%
- \doifundefined{\??li#1}{\definelist[#1]}}
- {\ConvertToConstant\doifelse{#1}{#2}
- {\doifundefined{\??li#1}{\definelist[#1]}}
- {\copyparameters
- [\??ko#1][\??ko#2]
- [\c!level,\c!section,\c!coupling,\c!prefix,
- \c!before,\c!after,\c!command,\c!file,\c!page,\c!continue,
- \c!separator,\c!stopper,
- \c!header,\c!text,\c!footer,\c!resetnumber,
- \c!number,\c!ownnumber,\c!placehead,\c!incrementnumber,
- \c!style,\c!color,\c!distance,\c!alternative,\c!indentnext,
- % new per 20/03/3002 (o-pbu-l) / was too confusing
- % \c!numberstyle,\c!textstyle,\c!expansion,
- % again too confusing
- \c!align,\c!aligntitle,\c!tolerance,\c!grid,\c!hang,\c!strut,
- \c!numbercommand,\c!textcommand,\c!margintext,\c!margin]%
- \getparameters[\??ko#1][\c!expansion=]% iig een value, rather fuzzy
- \definemarking[#1][#2]%
- \definemarking[#1\v!number][#2\v!number]%
- \doifundefined{\??li#1}{\definelist[#1][#2]}}}%
- \addtocommalist{#1}\@@kolist
- \setevalue{\??sk#1}{\getvalue{\??ko#1\c!coupling}}%
- \setevalue{\??by#1}{\getvalue{\??ko#1\c!section}}%
- \setevalue{\??by\v!by#1}{\getvalue{\??ko#1\c!section}}%
- \setvalue{#1}{\dodoubleempty\doconstructhead[#1]}}
-
-\def\dodefinehead[#1][#2]%
- {\doifelsenothing{#2}
- {% todo: message that it's an invalid definition
- \setvalue{#1}{\endgraf[#1]\kern.5em}}
- {\doifassignmentelse{#2}
- {\dododefinehead{#1}{#2}}
- {\doifdefined{\??ko#2\c!section}
- {\dododefinehead{#1}{#2}}}}}
-
-\def\definehead
- {\dodoubleemptywithset\dodefinehead}
-
-\def\doconstructhead[#1][#2]%
- {\dowithpargument{\dodoconstructhead{#1}[#2]}}
-
-\def\dosetuphead[#1][#2]%
- {\getparameters[\??ko#1][#2]%
- % The next check prevents hard to trace problems. I once
- % set \c!command to nothing and (quite natural) got the
- % wrong references etc. The whole bunch should be boxed!
- \expandafter\defconvertedcommand\expandafter\ascii\csname\??ko#1\c!command\endcsname
- \doifnothing\ascii{\setvalue{\??ko#1\c!command}{\normalplacehead}}}
-
-\def\setuphead
- {\dodoubleargumentwithset\dosetuphead}
-
-\def\dosetupheads[#1]%
- {\getparameters[\??ko][#1]%
- \doifelse{\@@kosectionnumber}\v!yes\sectionnumbertrue\sectionnumberfalse}
-
-\def\setupheads
- {\dosingleargument\dosetupheads}
-
-\def\systemsuppliedchapter {\getvalue{\v!chapter}}
-\def\systemsuppliedtitle {\getvalue{\v!title}}
-
-% a left over
-
-\def\complexbijlage[#1]#2%
- {\page[\v!right]
- \setuppagenumbering[\c!state=\v!stop]
- \systemsuppliedchapter[#1]{#2}
- \page[\v!right]
- \setuppagenumbering[\c!state=\v!start]
- \setuppagenumbering[\c!number=1]}
-
-\setvalue{\v!appendix}%
- {\complexorsimpleempty\bijlage}
-
-\setupheads
- [\c!alternative=\v!normal,
- \c!sectionnumber=\v!yes,
- \c!separator=.,
- \c!stopper=,
- \c!limittext=\v!yes,
- \c!align=,
- \c!aligntitle=,
- \c!tolerance=,
- \c!strut=,
- \c!indentnext=\v!no,
- \c!margin=\zeropoint,
- \c!hang=\v!none,
- \c!command=]
-
-\definesectionblock [\v!frontpart] [\v!frontmatter] [\c!number=\v!no]
-\definesectionblock [\v!bodypart] [\v!bodymatter] [\c!number=\v!yes]
-\definesectionblock [\v!appendix] [\v!appendices] [\c!number=\v!yes]
-\definesectionblock [\v!backpart] [\v!backmatter] [\c!number=\v!no]
-
-\definesection[\s!section-1] % part
-\definesection[\s!section-2] % chapter
-\definesection[\s!section-3] % section
-\definesection[\s!section-4] % subsection
-\definesection[\s!section-5] % subsubsection
-\definesection[\s!section-6] % subsubsubsection
-\definesection[\s!section-7] % subsubsubsubsection
-
-% \c!eigennummer ook hier?
-
-\definehead
- [\v!part]
- [\c!section=\s!section-1,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!chapter]
- [\c!section=\s!section-2,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!section]
- [\c!section=\s!section-3,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!subsection]
- [\c!section=\s!section-4,
- \c!default=\v!section,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!subsubsection]
- [\c!section=\s!section-5,
- \c!default=\v!subsection,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!subsubsubsection]
- [\c!section=\s!section-6,
- \c!default=\v!subsubsection,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!subsubsubsubsection]
- [\c!section=\s!section-7,
- \c!default=\v!subsubsubsection,
- \c!ownnumber=\v!no]
-
-\definehead
- [\v!title]
- [\c!coupling=\v!chapter,
- \c!default=\v!chapter,
- \c!incrementnumber=\v!no]
-
-\definehead
- [\v!subject]
- [\c!coupling=\v!section,
- \c!default=\v!section,
- \c!incrementnumber=\v!no]
-
-\definehead
- [\v!subsubject]
- [\c!coupling=\v!subsection,
- \c!default=\v!subsection,
- \c!incrementnumber=\v!no]
-
-\definehead
- [\v!subsubsubject]
- [\c!coupling=\v!subsubsection,
- \c!default=\v!subsubsection,
- \c!incrementnumber=\v!no]
-
-\definehead
- [\v!subsubsubsubject]
- [\c!coupling=\v!subsubsubsection,
- \c!default=\v!subsubsubsection,
- \c!incrementnumber=\v!no]
-
-\definehead
- [\v!subsubsubsubsubject]
- [\c!coupling=\v!subsubsubsubsection,
- \c!default=\v!subsubsubsubsection,
- \c!incrementnumber=\v!no]
-
-\setupsection
- [\s!section-2]
- [\v!appendix\c!conversion=\v!Character,
- \c!previousnumber=\v!no]
-
-\setuphead
- [\v!part]
- [\c!placehead=\v!no]
-
-\setuphead
- [\v!chapter]
- [\v!appendix\c!label=\v!appendix,
- \v!bodypart\c!label=\v!chapter] % bijlageconversie=\Character
-
-\setuphead
- [\v!section]
- [\v!appendix\c!label=\v!section,
- \v!bodypart\c!label=\v!section] % bijlageconversie=\Character
-
-\setuphead
- [\v!subsection]
- [\v!appendix\c!label=\v!subsection,
- \v!bodypart\c!label=\v!subsection] % bijlageconversie=\Character
-
-\setuphead
- [\v!subsubsection]
- [\v!appendix\c!label=\v!subsubsection,
- \v!bodypart\c!label=\v!subsubsection] % bijlageconversie=\Character
-
-\setuphead
- [\v!part,\v!chapter]
- [%\c!align=,
- %\c!indentnext=\v!no,
- \c!continue=\v!no,
- \c!page=\v!right,
- \c!header=,
- \c!style=\tfc,
- \c!distance=.75em,
- \c!before={\blank[2*\v!big]},
- \c!after={\blank[2*\v!big]}]
-
-\setuphead
- [\v!section]
- [%\c!align=,
- %\c!indentnext=\v!no,
- \c!style=\tfa,
- \c!distance=.75em,
- \c!before={\blank[2*\v!big]},
- \c!after=\blank]
-
-\setuphead % nieuw
- [\v!subsection]
- [\c!page=]
-
-\definecombinedlist
- [\v!content]
- [\v!part,
- \v!chapter,
- \v!section,
- \v!subsection,
- \v!subsubsection,
- \v!subsubsubsection,
- \v!subsubsubsubsection]
- [\c!level=\v!subsubsubsubsection,
- \c!criterium=\v!local]
-
-\setuplist
- [\v!part]
- [\c!before={\blank\page[\v!preference]},
- \c!after=\blank,
- \c!label=\v!yes,
- \c!separator=:,
- \c!distance=1em]
-
-\setuplist
- [\v!chapter]
- [\c!before={\blank\page[\v!preference]},
- \c!after=]
-
-\setuplist [\v!part] [\c!width=0em]
-\setuplist [\v!chapter] [\c!width=2em]
-\setuplist [\v!section] [\c!width=3em]
-\setuplist [\v!subsection] [\c!width=4em]
-\setuplist [\v!subsubsection] [\c!width=5em]
-\setuplist [\v!subsubsubsection] [\c!width=6em]
-\setuplist [\v!subsubsubsubsection] [\c!width=7em]
-
-% hm
-
-\setuppagenumbering % na instellen hoofdteksten !
- [\c!alternative=\v!singlesided,
- \c!location={\v!header,\v!middle},
- \c!conversion=\v!numbers,
- \c!width=, % in geval van \v!marginedge
- \c!left=,
- \c!right=,
- \c!way=\v!by\v!part,
- \c!text=,
- \v!chapter\v!number=\v!no, % v
- \v!part\v!number=\v!yes, % v
- \c!numberseparator=--,
- \c!textseparator=\tfskip,
- \c!state=\v!start,
- \c!command=,
- \c!strut=\v!yes, % nieuw
- \c!style=, % \v!normal, % empty, otherwise conflict
- \c!color=]
-
-\protect \endinput
diff --git a/tex/context/base/core-sec.mkii b/tex/context/base/core-sec.tex
index 960de366f..6cc0fbbf9 100644
--- a/tex/context/base/core-sec.mkii
+++ b/tex/context/base/core-sec.tex
@@ -23,55 +23,7 @@
% in manual (zie prikkels) : tussen=\blanko is enige hook om
% met kop-in-hoofd een spatiering af te dwingen
-\writestatus{loading}{Context Core Macros / Sectioning}
-
-\startmessages dutch library: structures
- title: structuur
- 1: begin van sectieblok --
- 2: eind van sectieblok --
-\stopmessages
-
-\startmessages english library: structures
- title: structure
- 1: begin of sectionblock --
- 2: end of sectionblock --
-\stopmessages
-
-\startmessages german library: structures
- title: struktur
- 1: Begin des Abschnittsblocks --
- 2: Ende des Abschnittsblocks --
-\stopmessages
-
-\startmessages czech library: structures
- title: struktury
- 1: zacatek oddilu (sekce) --
- 2: konec oddilu (sekce) --
-\stopmessages
-
-\startmessages italian library: structures
- title: struttura
- 1: inizio del blocco (sezione) --
- 2: fine del blocco (sezione) --
-\stopmessages
-
-\startmessages norwegian library: structures
- title: struktur
- 1: starten av blokk -- (seksjon)
- 2: slutten av blokk -- (seksjon)
-\stopmessages
-
-\startmessages romanian library: structures
- title: structuri
- 1: inceput de bloc sectiune --
- 2: sfarsit de bloc sectiune --
-\stopmessages
-
-\startmessages french library: structures
- title: structure
- 1: début de blocsection --
- 2: fin de blocsection --
-\stopmessages
+\writestatus{loading}{ConTeXt Core Macros / Sectioning}
\unprotect
@@ -1101,7 +1053,7 @@
\def\dohandlepagebreakAA#1%
{\ifnum\lastpenalty>0
- \global\paginageblokkeerdtrue
+ \global\pagebreakdisabledtrue
\fi}
% \setuphead[section][aligntitle=float] % permits title next to sidefloat
@@ -1113,8 +1065,8 @@
% \getvalue{\??ko#1\c!before}%
% % \whitespace vervangen door \noindent elders
% \relax
-% \ifpaginageblokkeerd
-% \global\paginageblokkeerdfalse
+% \ifpagebreakdisabled
+% \global\pagebreakdisabledfalse
% \else
% \!!countb\getvalue{\??se\@@sectie\c!level}\relax
% \ifnum\!!countb>\@@kolevel\relax
@@ -1136,8 +1088,8 @@
\getvalue{\??ko#1\c!before}%
% \whitespace vervangen door \noindent elders
\relax
- \ifpaginageblokkeerd
- \global\paginageblokkeerdfalse
+ \ifpagebreakdisabled
+ \global\pagebreakdisabledfalse
\else
\ifcase\somebreakmethod
% 0 = nothing
@@ -1920,7 +1872,7 @@
{\globallet\localheadskip\!!zeropoint
\forgetall}%
\dontcomplain
- \postponefootnotes
+ \postponenotes
\iflocation\ifdisplaysectionhead\else\noninterferingmarks\fi\fi
\resetinteractionparameter\c!style
\resetinteractionparameter\c!color
diff --git a/tex/context/base/core-snc.tex b/tex/context/base/core-snc.tex
index ac6960f4d..99c7d58f6 100644
--- a/tex/context/base/core-snc.tex
+++ b/tex/context/base/core-snc.tex
@@ -2,7 +2,7 @@
%D [ file=core-snc,
%D version=2003.12.01,
%D title=\CONTEXT\ Core Macros,
-%D subtitle=Synchronization Support,
+%D subtitle=Synchronization,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Synchronization}
+\writestatus{loading}{ConTeXt Core Macros / Synchronization}
\unprotect
diff --git a/tex/context/base/core-spa.lua b/tex/context/base/core-spa.lua
index 5f4df72a2..0f308b19c 100644
--- a/tex/context/base/core-spa.lua
+++ b/tex/context/base/core-spa.lua
@@ -6,13 +6,43 @@ if not modules then modules = { } end modules ['core-spa'] = {
license = "see context related readme files"
}
--- todo: test without unset
+-- this code dates from the beginning and is kind of experimental; it
+-- will be optimized and improved soon
-local format, insert = string.format, table.insert
-local utfchar = utf.char
+local next, type = next, type
+local format, gmatch, concat = string.format, string.gmatch, table.concat
+local texsprint, texlists = tex.sprint, tex.lists
+
+local ctxcatcodes = tex.ctxcatcodes
-- vertical space handler
+local trace_vbox_vspacing = false trackers.register("nodes.vbox_vspacing", function(v) trace_vbox_vspacing = v end)
+local trace_page_vspacing = false trackers.register("nodes.page_vspacing", function(v) trace_page_vspacing = v end)
+local trace_collect_vspacing = false trackers.register("nodes.collect_vspacing", function(v) trace_collect_vspacing = v end)
+local trace_vspacing = false trackers.register("nodes.vspacing", function(v) trace_vspacing = v end)
+
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local set_attribute = node.set_attribute
+local slide_node_list = node.slide
+local free_node = node.free
+local copy_node = node.copy
+local traverse_nodes = node.traverse
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local remove_node = nodes.remove
+local make_penalty_node = nodes.penalty
+local count_nodes = nodes.count
+local node_ids_to_string = nodes.ids_to_string
+
+local glyph = node.id("glyph")
+local penalty = node.id("penalty")
+local kern = node.id("kern")
+local glue = node.id('glue')
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+
vspacing = vspacing or { }
vspacing.categories = {
@@ -26,12 +56,14 @@ vspacing.categories = {
[7] = 'goback',
}
+local categories = vspacing.categories
+
function vspacing.tocategories(str)
local t = { }
- for s in str:gmatch("[^, ]") do
+ for s in gmatch(str,"[^, ]") do
local n = tonumber(s)
if n then
- t[vspacing.categories[n]] = true
+ t[categories[n]] = true
else
t[b] = true
end
@@ -43,7 +75,7 @@ function vspacing.tocategory(str)
if type(str) == "string" then
return set.tonumber(vspacing.tocategories(str))
else
- return set.tonumber({ [vspacing.categories[str]] = true })
+ return set.tonumber({ [categories[str]] = true })
end
end
@@ -51,90 +83,87 @@ vspacing.data = vspacing.data or { }
vspacing.data.map = vspacing.data.map or { }
vspacing.data.skip = vspacing.data.skip or { }
-input.storage.register(false, "vspacing/data/map", vspacing.data.map, "vspacing.data.map")
-input.storage.register(false, "vspacing/data/skip", vspacing.data.skip, "vspacing.data.skip")
+storage.register("vspacing/data/map", vspacing.data.map, "vspacing.data.map")
+storage.register("vspacing/data/skip", vspacing.data.skip, "vspacing.data.skip")
do
+ vspacing.fixed = false
+
local map = vspacing.data.map
local skip = vspacing.data.skip
- vspacing.fixed = false
- vspacing.trace = false
-
local multiplier = lpeg.C(lpeg.S("+-")^0 * lpeg.R("09")^1) * lpeg.P("*")
local category = lpeg.P(":") * lpeg.C(lpeg.P(1)^1)
local keyword = lpeg.C((1-category)^1)
-
local splitter = (multiplier + lpeg.Cc(1)) * keyword * (category + lpeg.Cc(false))
- function vspacing.analyse(str)
- local category, order, penalty, command, fixed = { }, 0, 0, { }, vspacing.fixed
- local function analyse(str)
- for s in str:gmatch("([^ ,]+)") do
- local amount, keyword, detail = splitter:match(s)
- if keyword then
- local mk = map[keyword]
- if mk then
- analyse(mk)
- elseif keyword == "fixed" then
- fixed = true
- elseif keyword == "flexible" then
- fixed = false
- elseif keyword == "category" then
- -- is a set
- local n = tonumber(detail)
- if n then
- category[vspacing.categories[n]] = true
- else
- category[detail] = true
- end
- elseif keyword == "order" then
- -- last one counts
- order = tonumber(detail) or 0
- elseif keyword == "penalty" then
- -- last one counts
- penalty = tonumber(detail) or 0
- elseif keyword == "skip" then
- -- last one counts
- command[#command+1] = { 1, tonumber(detail or 1) or 1}
+ local function analyse(str,category,order,penalty,command,fixed)
+ for s in gmatch(str,"([^ ,]+)") do
+ local amount, keyword, detail = splitter:match(s)
+ if keyword then
+ local mk = map[keyword]
+ if mk then
+ analyse(mk,category,order,penalty,command,fixed)
+ elseif keyword == "fixed" then
+ fixed = true
+ elseif keyword == "flexible" then
+ fixed = false
+ elseif keyword == "category" then
+ -- is a set
+ local n = tonumber(detail)
+ if n then
+ category[categories[n]] = true
else
- amount = tonumber(amount) or 1
- local sk = skip[keyword]
- if sk then
- command[#command+1] = { amount, sk[1], sk[2] or sk[1]}
- else -- no check
- command[#command+1] = { amount, keyword, keyword, keyword}
- end
+ category[detail] = true
end
+ elseif keyword == "order" then
+ -- last one counts
+ order = tonumber(detail) or 0
+ elseif keyword == "penalty" then
+ -- last one counts
+ penalty = tonumber(detail) or 0
+ elseif keyword == "skip" then
+ -- last one counts
+ command[#command+1] = { 1, tonumber(detail or 1) or 1}
else
- logs.report("vspacing","unknown directive: %s",str)
+ amount = tonumber(amount) or 1
+ local sk = skip[keyword]
+ if sk then
+ command[#command+1] = { amount, sk[1], sk[2] or sk[1]}
+ else -- no check
+ command[#command+1] = { amount, keyword, keyword, keyword}
+ end
end
+ else
+ logs.report("vspacing","unknown directive: %s",str)
end
end
- analyse(str)
+ end
+
+ local function logger(c,s)
+ logs.report("vspacing",s)
+ texsprint(c,s)
+ end
+
+ function vspacing.analyse(str)
+ local texsprint = (trace_vspacing and logger) or texsprint
+ local category, order, penalty, command, fixed = { }, 0, 0, { }, vspacing.fixed
+ analyse(str,category,order,penalty,command,fixed)
category = set.tonumber(category)
- local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes
- if vspacing.trace then
- -- quick and dirty
- texsprint = function(c,s)
- logs.report("vspacing",s)
- tex.sprint(c,s)
- end
- end
texsprint(ctxcatcodes,"\\startblankhandling")
if category > 0 then
- texsprint(ctxcatcodes,("\\setblankcategory{%s}"):format(category))
+ texsprint(ctxcatcodes,format("\\setblankcategory{%s}",category))
end
if order > 0 then
- texsprint(ctxcatcodes,("\\setblankorder{%s}"):format(order))
+ texsprint(ctxcatcodes,format("\\setblankorder{%s}",order))
end
if penalty > 0 then
- texsprint(ctxcatcodes,("\\setblankpenalty{%s}"):format(penalty))
+ texsprint(ctxcatcodes,format("\\setblankpenalty{%s}",penalty))
end
for i=1,#command do
local c = command[i]
- texsprint(ctxcatcodes,("\\addblankskip{%s}{%s}{%s}"):format(c[1],c[2],c[3] or c[2]))
+ texsprint(ctxcatcodes,format("\\addblankskip{%s}{%s}{%s}",c[1],c[2],c[3] or c[2]))
end
if fixed then
texsprint(ctxcatcodes,"\\fixedblankskip")
@@ -165,1488 +194,488 @@ function nodes.setsnapvalue(n,ht,dp)
nodes.snapvalues[n] = { ht, dp, ht+dp }
end
-do
-
- nodes.trace_vbox_spacing = false
- nodes.trace_page_spacing = false
+local trace_list, tracing_info, before, after = { }, false, "", ""
- local kern, glue, penalty, hlist = node.id('kern'), node.id('glue'), node.id('penalty'), node.id('hlist')
-
- local has_attribute = node.has_attribute
- local unset_attribute = node.unset_attribute
- local set_attribute = node.set_attribute
- local has_field = node.has_field
-
- local trace_list, tracing_info, before, after = { }, false, "", ""
-
- local function glue_to_string(glue)
- local spec = glue.spec
- if spec then
- local t = { }
- t[#t+1] = aux.strip_zeros(number.topoints(spec.width))
- if spec.stretch_order and spec.stretch_order ~= 0 then
- t[#t+1] = format("plus -%sfi%s",spec.stretch/65536,string.rep("l",math.abs(spec.stretch_order)-1))
- elseif spec.stretch and spec.stretch ~= 0 then
- t[#t+1] = format("plus %s",aux.strip_zeros(number.topoints(spec.stretch)))
- end
- if spec.shrink_order and spec.shrink_order ~= 0 then
- t[#t+1] = format("minus -%sfi%s",spec.shrink/65536,string.rep("l",math.abs(spec.shrink_order)-1))
- elseif spec.shrink and spec.shrink ~= 0 then
- t[#t+1] = format("minus %s",aux.strip_zeros(number.topoints(spec.shrink)))
- end
- return table.concat(t," ")
- else
- return "[0pt]"
- end
- end
- local function nodes_to_string(head)
- local current, t = head, { }
- while current do
- local id = current.id
- local ty = node.type(id)
- if id == penalty then
- t[#t+1] = format("%s:%s",ty,current.penalty)
- elseif id == glue then
- if current.spec then
- t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.spec.width)))
- else
- t[#t+1] = format("%s:[0pt]",ty)
- end
- elseif id == kern then
- t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.kern)))
- else
- t[#t+1] = ty
- end
- current = current.next
- end
- return table.concat(t," + ")
- end
- local function reset_tracing(head)
- trace_list, tracing_info, before, after = { }, false, nodes_to_string(head), ""
- end
- local function trace_skip(str,sc,so,sp,data)
- trace_list[#trace_list+1] = { "skip", ("%s | %s | category %s | order %s | penalty %s"):format(str, glue_to_string(data), sc or "-", so or "-", sp or "-") }
- tracing_info = true
- end
- local function trace_natural(str,data)
- trace_list[#trace_list+1] = { "skip", ("%s | %s"):format(str, glue_to_string(data)) }
- tracing_info = true
- end
- local function trace_info(message, where, what)
- trace_list[#trace_list+1] = { "info", format("%s: %s/%s",message,where,what) }
- end
- local function trace_node(what)
- local nt = node.type(what.id)
- local tl = trace_list[#trace_list]
- if tl[1] == "node" then
- trace_list[#trace_list] = { "node", tl[2] .. " + " .. nt }
- else
- trace_list[#trace_list+1] = { "node", nt }
+local function glue_to_string(glue)
+ local spec = glue.spec
+ if spec then
+ local t = { }
+ t[#t+1] = aux.strip_zeros(number.topoints(spec.width))
+ if spec.stretch_order and spec.stretch_order ~= 0 then
+ t[#t+1] = format("plus -%sfi%s",spec.stretch/65536,string.rep("l",math.abs(spec.stretch_order)-1))
+ elseif spec.stretch and spec.stretch ~= 0 then
+ t[#t+1] = format("plus %s",aux.strip_zeros(number.topoints(spec.stretch)))
end
- end
- local function trace_done(str,data)
- if data.id == penalty then
- trace_list[#trace_list+1] = { "penalty", ("%s | %s"):format(str, data.penalty) }
- else
- trace_list[#trace_list+1] = { "glue", ("%s | %s"):format(str, glue_to_string(data)) }
- end
- tracing_info = true
- end
- local function show_tracing(head)
- if tracing_info then
- after = nodes_to_string(head)
- for i=1,#trace_list do
- local tag, text = unpack(trace_list[i])
- if tag == "info" then
- logs.report("collapse",text)
- else
- logs.report("collapse"," %s: %s",tag,text)
- end
- end
- logs.report("collapse","before: %s",before)
- logs.report("collapse","after : %s",after)
+ if spec.shrink_order and spec.shrink_order ~= 0 then
+ t[#t+1] = format("minus -%sfi%s",spec.shrink/65536,string.rep("l",math.abs(spec.shrink_order)-1))
+ elseif spec.shrink and spec.shrink ~= 0 then
+ t[#t+1] = format("minus %s",aux.strip_zeros(number.topoints(spec.shrink)))
end
+ return concat(t," ")
+ else
+ return "[0pt]"
end
+end
- -- we assume that these are defined
-
- local skip_category = attributes.numbers['skip-category'] or 101
- local skip_penalty = attributes.numbers['skip-penalty'] or 102
- local skip_order = attributes.numbers['skip-order'] or 103
- local snap_category = attributes.numbers['snap-category'] or 111
- local display_math = attributes.numbers['display-math'] or 121
-
- -- alignment box begin_of_par vmode_par hmode_par insert penalty before_display after_display
-
- local user_skip = 0
- local line_skip = 1
- local baseline_skip = 2
- local par_skip = 3
- local above_display_skip = 4
- local below_display_skip = 5
- local above_display_short_skip = 6
- local below_display_short_skip = 7
- local left_skip_code = 8
- local right_skip_code = 9
- local top_skip_code = 10
- local split_top_skip_code = 11
- local tab_skip_code = 12
- local space_skip_code = 13
- local xspace_skip_code = 14
- local par_fill_skip_code = 15
- local thin_mu_skip_code = 16
- local med_mu_skip_code = 17
- local thick_mu_skip_code = 18
-
- local skips = {
- [ 0] = "user_skip",
- [ 1] = "line_skip",
- [ 2] = "baseline_skip",
- [ 3] = "par_skip",
- [ 4] = "above_display_skip",
- [ 5] = "below_display_skip",
- [ 6] = "above_display_short_skip",
- [ 7] = "below_display_short_skip",
- [ 8] = "left_skip_code",
- [ 9] = "right_skip_code",
- [10] = "top_skip_code",
- [11] = "split_top_skip_code",
- [12] = "tab_skip_code",
- [13] = "space_skip_code",
- [14] = "xspace_skip_code",
- [15] = "par_fill_skip_code",
- [16] = "thin_mu_skip_code",
- [17] = "med_mu_skip_code",
- [18] = "thick_mu_skip_code",
- }
-
- function nodes.is_display_math(head)
- local n = head.prev
- while n do
- local id = n.id
- if id == penalty then
- elseif id == glue then
- if n.subtype == 6 then -- above_display_short_skip
- return true
- end
- else
- break
- end
- n = n.prev
- end
- n = head.next
- while n do
- local id = n.id
- if id == penalty then
- elseif id == glue then
- if n.subtype == 7 then -- below_display_short_skip
- return true
- end
+local function nodes_to_string(head)
+ local current, t = head, { }
+ while current do
+ local id = current.id
+ local ty = node.type(id)
+ if id == penalty then
+ t[#t+1] = format("%s:%s",ty,current.penalty)
+ elseif id == glue then
+ if current.spec then
+ t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.spec.width)))
else
- break
- end
- n = n.next
- end
- return false
- end
-
- local function collapser(head,where,what,trace,preceding)
- if head then
- input.starttiming(nodes)
- if trace then reset_tracing(head) end
- if trace then trace_info("start analyzing",where,what) end
- node.slide(head) -- hm, why
- local current, tail = head, nil
- local glue_order, glue_data = 0, nil
- local penalty_order, penalty_data, natural_penalty = 0, nil, nil
- local parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false
- while current do
- local id = current.id
- if id == glue and current.subtype == 0 then -- todo, other subtypes, like math
- local sc = has_attribute(current,skip_category)
- local so = has_attribute(current,skip_order)
- local sp = has_attribute(current,skip_penalty)
---~ if sc then unset_attribute(current,skip_category) end
---~ if so then unset_attribute(current,skip_order) end
---~ if sp then unset_attribute(current,skip_penalty) end
- so = so or 1
- if not sc then
- if glue_data then
- if trace then trace_done("flush",glue_data) end
- head, current = nodes.before(head,current,glue_data)
- if trace then trace_natural("natural",current) end
- else
- -- not look back across head
- local previous = current.prev
- if previous and previous.id == glue and previous.subtype == 0 then
- local ps = previous.spec
- if ps then
- local cs = current.spec
- if cs and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then
- local pw, pp, pm = ps.width, ps.stretch, ps.shrink
- local cw, cp, cm = cs.width, cs.stretch, cs.shrink
- ps.width, ps.stretch, ps.shrink = pw + cw, pp + cp, pm + cm
- if trace then trace_natural("removed",current) end
- head, current = nodes.remove(head, current, true)
- current = previous
- if trace then trace_natural("collapsed",current) end
- else
- if trace then trace_natural("filler",current) end
- end
- else
- if trace then trace_natural("natural (no prev spec)",current) end
- end
- else
- if trace then trace_natural("natural (no prev)",current) end
- end
- end
- glue_order, glue_data = 0, nil
- if current then
- current = current.next
- end
- else
- local sct = vspacing.categories[sc] -- or 'unknown'
- if sct == 'disable' then
- ignore_following = true
- if trace then trace_skip(sct,sc,so,sp,current) end
- head, current = nodes.remove(head, current, true)
- elseif sct == 'nowhite' then
- ignore_whitespace = true
- head, current = nodes.remove(head, current, true)
- elseif sct == 'discard' then
- if trace then trace_skip(sct,sc,so,sp,current) end
- head, current = nodes.remove(head, current, true)
- else
- if sp then
- if not penalty_data then
- penalty_data = sp
- elseif penalty_order < so then
- penalty_order, penalty_data = so, sp
- elseif penalty_order == so and sp > penalty_data then
- penalty_data = sp
- end
- end
- if ignore_following then
- if trace then trace_skip("disabled",sc,so,sp,current) end
- head, current = nodes.remove(head, current, true)
- elseif not glue_data then
- if trace then trace_skip("assign " .. sct,sc,so,sp,current) end
- glue_order = so
- head, current, glue_data = nodes.remove(head, current)
- elseif glue_order < so then
- if trace then trace_skip("force",sc,so,sp,current) end
- glue_order = so
- node.free(glue_data)
- head, current, glue_data = nodes.remove(head, current)
- elseif glue_order == so then
- if sct == 'largest' then
- local cs, gs = current.spec, glue_data.spec
- local cw = (cs and cs.width) or 0
- local gw = (gs and gs.width) or 0
- if cw > gw then
- if trace then trace_skip(sct,sc,so,sp,current) end
- node.free(glue_data) -- also free spec
- head, current, glue_data = nodes.remove(head, current)
- else
- if trace then trace_skip('remove smallest',sc,so,sp,current) end
- head, current = nodes.remove(head, current, true)
- end
- elseif sct == 'goback' then
- if trace then trace_skip(sct,sc,so,sp,current) end
- node.free(glue_data) -- also free spec
- head, current, glue_data = nodes.remove(head, current)
- elseif sct == 'force' then
- -- todo: inject kern
- if trace then trace_skip(sct,sc,so,sp,current) end
- node.free(glue_data) -- also free spec
- head, current, glue_data = nodes.remove(head, current)
- elseif sct == 'penalty' then
- if trace then trace_skip(sct,sc,so,sp,current) end
- node.free(glue_data) -- also free spec
- head, current = nodes.remove(head, current, true)
- elseif sct == 'add' then
- if trace then trace_skip(sct,sc,so,sp,current) end
- local old, new = glue_data.spec, current.spec
- old.width = old.width + new.width
- old.stretch = old.stretch + new.stretch
- old.shrink = old.shrink + new.shrink
- -- toto: order
- head, current = nodes.remove(head, current, true)
- else
- if trace then trace_skip("unknown",sc,so,sp,current) end
- head, current = nodes.remove(head, current, true)
- end
- else
- if trace then trace_skip("unknown",sc,so,sp,current) end
- head, current = nodes.remove(head, current, true)
- end
- end
- end
- elseif id == penalty then
---~ natural_penalty = current.penalty
---~ if trace then trace_done("removed penalty",current) end
---~ head, current = nodes.remove(head, current, true)
-current = current.next
- elseif id == glue and current.subtype == 2 then
- local sn = has_attribute(current,snap_category)
- if sn then
- -- local sv = nodes.snapvalues[sn]
- -- if sv then
- if trace then trace_natural("removed baselineskip",current) end
- head, current = nodes.remove(head, current, true)
- -- else
- -- current = current.next
- -- end
- else
- if trace then trace_natural("keep baselineskip",current) end
- current = current.next
- end
- elseif id == glue and current.subtype == 3 then
- -- parskip always comes later
- if ignore_whitespace then
- if trace then trace_natural("ignored parskip",current) end
- head, current = nodes.remove(head,current,true)
- elseif glue_data then
- local ps, gs = current.spec, glue_data.spec
- if ps and gs and ps.width > gs.width then
- node.free(glue_data.spec)
- glue_data.spec = ps
- if trace then trace_natural("taking parskip",current) end
- else
- if trace then trace_natural("removed parskip",current) end
- end
- head, current = nodes.remove(head, current,true)
- else
- if trace then trace_natural("honored parskip",current) end
- head, current, glue_data = nodes.remove(head, current)
- end
---~ if trace then trace_natural("removed parskip",current) end
---~ current.spec = nil
---~ current = current.next
- else
- if glue_data then
- if trace then trace_done("flushed",glue_data) end
- head, current = node.insert_before(head,current,glue_data)
- glue_order, glue_data = 0, nil
- end
- if penalty_data then
- local p = nodes.penalty(penalty_data)
- if trace then trace_done("flushed",p) end
- head, current = node.insert_before(head,current,p)
- penalty_data = nil
- end
- if trace then trace_node(current) end
- if id == hlist and where == 'hmode_par' then
- local list = current.list
- if list then
- local sn = has_attribute(list,snap_category)
- if sn then
- local sv = nodes.snapvalues[sn]
- if sv then
- local height, depth, lineheight = sv[1], sv[2], sv[3]
- current.height = math.ceil((current.height-height)/lineheight)*lineheight + height
- current.depth = math.ceil((current.depth -depth )/lineheight)*lineheight + depth
- end
- end
- end
- end
- current = current.next
- end
- end
- tail = node.slide(head)
- if trace then trace_info("stop analyzing",where,what) end
---~ if natural_penalty and (not penalty_data or natural_penalty > penalty_data) then
---~ penalty_data = natural_penalty
---~ end
- if trace and (glue_data or penalty_data) then trace_info("start flushing",where,what) end
- if penalty_data then
- local p = nodes.penalty(penalty_data)
- if trace then trace_done("result",p) end
- head, tail = node.insert_after(head,tail,p)
- end
- if glue_data then
- if trace then trace_done("result",glue_data) end
- head, tail = node.insert_after(head,tail,glue_data)
+ t[#t+1] = format("%s:[0pt]",ty)
end
- if trace and (glue_data or penalty_data) then trace_info("stop flushing",where,what) end
- input.stoptiming(nodes)
- if trace then show_tracing(head) end
+ elseif id == kern then
+ t[#t+1] = format("%s:%s",ty,aux.strip_zeros(number.topoints(current.kern)))
+ else
+ t[#t+1] = ty
end
- return head, true
- end
-
- -- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display
-
- function nodes.handle_page_spacing(where) -- no arguments
- --~ status.best_page_break
- --~ tex.lists.best_page_break
- --~ tex.lists.best_size (natural size to best_page_break)
- --~ tex.lists.least_page_cost ( badness van best_page_break)
- --~ tex.lists.page_head
- --~ tex.lists.contrib_head
- local head, done= collapser(tex.lists.contrib_head,"page",where,nodes.trace_page_spacing,tex.lists.page_head)
- tex.lists.contrib_head = head
+ current = current.next
end
-
- -- split_keep, split_off, vbox
-
- local not_needed = table.tohash {
- "split_keep",
- "split_off",
- }
-
- function nodes.handle_vbox_spacing(t,where)
- return (t and not not_needed[where] and t.next and collapser(t,"vbox",where,nodes.trace_vbox_spacing)) or t
- end
-
+ return concat(t," + ")
end
--- experimental callback definitions will be moved elsewhere
---
--- this will become a chain
-
-function vspacing.enable()
---~ callback.register('vpack_filter', nodes.handle_vbox_spacing)
- callback.register('buildpage_filter', nodes.handle_page_spacing)
+local function reset_tracing(head)
+ trace_list, tracing_info, before, after = { }, false, nodes_to_string(head), ""
end
-function vspacing.disable()
- callback.register('vpack_filter', nil)
- callback.register('buildpage_filter', nil)
-end
-
--- horizontal stuff
--- probably a has_glyphs is rather fast too
-
-do -- maybe just share these locals
-
- local has_attribute = node.has_attribute
- local unset_attribute = node.unset_attribute
- local set_attribute = node.set_attribute
- local traverse_id = node.traverse_id
-
---~ local function unset_attribute(n,attribute)
---~ set_attribute(n,attribute,0)
---~ end
-
- local glyph = node.id("glyph")
- local whatsit = node.id("whatsit")
- local penalty = node.id("penalty")
- local kern = node.id("kern")
- local disc = node.id('disc')
- local glue = node.id('glue')
- local hlist = node.id('hlist')
- local vlist = node.id('vlist')
-
- spacings = spacings or { }
- spacings.mapping = spacings.mapping or { }
- spacings.enabled = false
-
- input.storage.register(false,"spacings/mapping", spacings.mapping, "spacings.mapping")
+local function trace_skip(str,sc,so,sp,data)
+ trace_list[#trace_list+1] = { "skip", format("%s | %s | category %s | order %s | penalty %s", str, glue_to_string(data), sc or "-", so or "-", sp or "-") }
+ tracing_info = true
+end
- function spacings.setspacing(id,char,left,right,alternative)
- local mapping = spacings.mapping[id]
- if not mapping then
- mapping = { }
- spacings.mapping[id] = mapping
- end
- local map = mapping[char]
- if not map then
- map = { }
- mapping[char] = map
- end
- map.left, map.right, map.alternative = left, right, alternative
- end
+local function trace_natural(str,data)
+ trace_list[#trace_list+1] = { "skip", format("%s | %s", str, glue_to_string(data)) }
+ tracing_info = true
+end
- -- todo: no ligatures
+local function trace_info(message, where, what)
+ trace_list[#trace_list+1] = { "info", format("%s: %s/%s",message,where,what) }
+end
- function nodes.somespace(n,all)
- if n then
- local id = n.id
- if id == glue then
- return (all or (n.spec.width ~= 0)) and glue
- elseif id == kern then
- return (all or (n.kern ~= 0)) and kern
- elseif id == glyph then
- local category = characters.data[n.char].category
- -- maybe more category checks are needed
- return (category == "zs") and glyph
- end
- end
- return false
+local function trace_node(what)
+ local nt = node.type(what.id)
+ local tl = trace_list[#trace_list]
+ if tl[1] == "node" then
+ trace_list[#trace_list] = { "node", tl[2] .. " + " .. nt }
+ else
+ trace_list[#trace_list+1] = { "node", nt }
end
+end
- function nodes.somepenalty(n,value)
- if n then
- local id = n.id
- if id == penalty then
- if value then
- return n.penalty == value
- else
- return true
- end
- end
- end
- return false
+local function trace_done(str,data)
+ if data.id == penalty then
+ trace_list[#trace_list+1] = { "penalty", format("%s | %s", str, data.penalty) }
+ else
+ trace_list[#trace_list+1] = { "glue", format("%s | %s", str, glue_to_string(data)) }
end
+ tracing_info = true
+end
- spacings.trace = false
-
- function spacings.process(namespace,attribute,head)
- local done, mapping, fontids = false, spacings.mapping, fonts.tfm.id
- local start = head
- -- head is always begin of par (whatsit), so we have at least two prev nodes
- -- penalty followed by glue
- while start do
- if start.id == glyph then
- local attr = has_attribute(start,attribute)
- if attr and attr > 0 then
- local map = mapping[attr]
- if map then
- map = map[start.char]
- unset_attribute(start,attribute)
- if map then
- local trace = spacings.trace
- local left, right, alternative = map.left, map.right, map.alternative
- local quad = fontids[start.font].parameters.quad
- local prev = start.prev
- if left and left ~= 0 and prev then
- local ok = false
- if alternative == 1 then
- local somespace = nodes.somespace(prev,true)
- if somespace then
- local prevprev = prev.prev
- local somepenalty = nodes.somepenalty(prevprev,10000)
- if somepenalty then
- if trace then
- logs.report("spacing","removing penalty and space before %s", utfchar(start.char))
- end
- head, _ = nodes.remove(head,prev,true)
- head, _ = nodes.remove(head,prevprev,true)
- else
- local somespace = nodes.somespace(prev,true)
- if somespace then
- if trace then
- logs.report("spacing","removing space before %s", utfchar(start.char))
- end
- head, _ = nodes.remove(head,prev,true)
- end
- end
- end
- ok = true
- else
- ok = not (nodes.somespace(prev,true) and nodes.somepenalty(prev.prev,true)) or nodes.somespace(prev,true)
- end
- if ok then
- if trace then
- logs.report("spacing","inserting penalty and space before %s", utfchar(start.char))
- end
- node.insert_before(head,start,nodes.penalty(10000))
- node.insert_before(head,start,nodes.glue(tex.scale(quad,left)))
- done = true
- end
- end
- local next = start.next
- if right and right ~= 0 and next then
- local ok = false
- if alternative == 1 then
- local somepenalty = nodes.somepenalty(next,10000)
- if somepenalty then
- local nextnext = next.next
- local somespace = nodes.somespace(nextnext,true)
- if somespace then
- if trace then
- logs.report("spacing","removing penalty and space after %s", utfchar(start.char))
- end
- head, _ = nodes.remove(head,next,true)
- head, _ = nodes.remove(head,nextnext,true)
- end
- else
- local somespace = nodes.somespace(next,true)
- if somespace then
- if trace then
- logs.report("spacing","removing space after %s", utfchar(start.char))
- end
- head, _ = nodes.remove(head,next,true)
- end
- end
- ok = true
- else
- ok = not (nodes.somepenalty(next,10000) and nodes.somespace(next.next,true)) or nodes.somespace(next,true)
- end
- if ok then
- if trace then
- logs.report("spacing","inserting penalty and space after %s", utfchar(start.char))
- end
- node.insert_after(head,start,nodes.glue(tex.scale(quad,right)))
- node.insert_after(head,start,nodes.penalty(10000))
- done = true
- end
- end
- end
- end
- end
+local function show_tracing(head)
+ if tracing_info then
+ after = nodes_to_string(head)
+ for i=1,#trace_list do
+ local tag, text = unpack(trace_list[i])
+ if tag == "info" then
+ logs.report("collapse",text)
+ else
+ logs.report("collapse"," %s: %s",tag,text)
end
- start = start.next
end
- return head, done
- end
-
- lists.handle_spacing = nodes.install_attribute_handler {
- name = "spacing",
- namespace = spacings,
- processor = spacings.process,
- }
-
- kerns = kerns or { }
- kerns.mapping = kerns.mapping or { }
- kerns.enabled = false
-
- input.storage.register(false, "kerns/mapping", kerns.mapping, "kerns.mapping")
-
- function kerns.setspacing(id,factor)
- kerns.mapping[id] = factor
+ logs.report("collapse","before: %s",before)
+ logs.report("collapse","after : %s",after)
end
+end
- -- local marks = fti[font].shared.otfdata.luatex.marks
- -- if not marks[tchar] then
-
- -- todo: use node.* functions
+-- we assume that these are defined
+
+local skip_category = attributes.private('skip-category')
+local skip_penalty = attributes.private('skip-penalty')
+local skip_order = attributes.private('skip-order')
+local snap_category = attributes.private('snap-category')
+local display_math = attributes.private('display-math')
+
+-- alignment box begin_of_par vmode_par hmode_par insert penalty before_display after_display
+
+local user_skip = 0
+local line_skip = 1
+local baseline_skip = 2
+local par_skip = 3
+local above_display_skip = 4
+local below_display_skip = 5
+local above_display_short_skip = 6
+local below_display_short_skip = 7
+local left_skip_code = 8
+local right_skip_code = 9
+local top_skip_code = 10
+local split_top_skip_code = 11
+local tab_skip_code = 12
+local space_skip_code = 13
+local xspace_skip_code = 14
+local par_fill_skip_code = 15
+local thin_mu_skip_code = 16
+local med_mu_skip_code = 17
+local thick_mu_skip_code = 18
+
+local skips = {
+ [ 0] = "user_skip",
+ [ 1] = "line_skip",
+ [ 2] = "baseline_skip",
+ [ 3] = "par_skip",
+ [ 4] = "above_display_skip",
+ [ 5] = "below_display_skip",
+ [ 6] = "above_display_short_skip",
+ [ 7] = "below_display_short_skip",
+ [ 8] = "left_skip_code",
+ [ 9] = "right_skip_code",
+ [10] = "top_skip_code",
+ [11] = "split_top_skip_code",
+ [12] = "tab_skip_code",
+ [13] = "space_skip_code",
+ [14] = "xspace_skip_code",
+ [15] = "par_fill_skip_code",
+ [16] = "thin_mu_skip_code",
+ [17] = "med_mu_skip_code",
+ [18] = "thick_mu_skip_code",
+}
- function kerns.process(namespace,attribute,head) -- todo interchar kerns / disc nodes / can be made faster
- local fti, scale = fonts.tfm.id, tex.scale
- local start, done, mapping, fontids, lastfont = head, false, kerns.mapping, fonts.tfm.id, nil
- while start do
- -- faster to test for attr first
- local attr = has_attribute(start,attribute)
- if attr and attr > 0 then
- unset_attribute(start,attribute)
- local krn = mapping[attr]
- if krn and krn ~= 0 then
- local id = start.id
- if id == glyph then
- lastfont = start.font
- local c = start.components
- if c then
- local s = start
- local tail = node.slide(c)
- if s.prev then
- s.prev.next = c
- c.prev = s.prev
+local free_glue_node = free_node
+local free_glue_spec = free_node
+--~ local free_glue_node = function(n) free_node(n) end
+--~ local free_glue_spec = function(n) end
+
+local function collapser(head,where,what,trace) -- maybe also pass tail
+ if trace then
+ reset_tracing(head)
+ trace_info("start analyzing",where,what)
+ end
+ local current = head
+ local glue_order, glue_data = 0, nil
+ local penalty_order, penalty_data, natural_penalty = 0, nil, nil
+ local parskip, ignore_parskip, ignore_following, ignore_whitespace = nil, false, false, false
+ while current do
+ local id = current.id
+ if id == glue and current.subtype == 0 then -- todo, other subtypes, like math
+ local sc = has_attribute(current,skip_category) -- has no default, no unset (yet)
+ local so = has_attribute(current,skip_order ) or 1 -- has 1 default, no unset (yet)
+ local sp = has_attribute(current,skip_penalty ) -- has no degault, no unset (yet)
+ if not sc then
+ if glue_data then
+ if trace then trace_done("flush",glue_data) end
+ head, current = nodes.before(head,current,glue_data)
+ if trace then trace_natural("natural",current) end
+ else
+ -- not look back across head
+ local previous = current.prev
+ if previous and previous.id == glue and previous.subtype == 0 then
+ local ps = previous.spec
+ if ps then
+ local cs = current.spec
+ if cs and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then
+ local pw, pp, pm = ps.width, ps.stretch, ps.shrink
+ local cw, cp, cm = cs.width, cs.stretch, cs.shrink
+ ps.width, ps.stretch, ps.shrink = pw + cw, pp + cp, pm + cm
+ if trace then trace_natural("removed",current) end
+ head, current = remove_node(head, current, true)
+ current = previous
+ if trace then trace_natural("collapsed",current) end
else
- head = c
- end
- if s.next then
- s.next.prev = tail
- end
- tail.next = s.next
- start = c
- start.attr = s.attr
- s.attr = nil
- s.components = nil
- node.free(s)
- done = true
- end
- local prev = start.prev
- if prev then
- local pid = prev.id
- if not pid then
- -- nothing
- elseif pid == kern and prev.subtype == 0 then
- prev.subtype = 1
- prev.kern = prev.kern + scale(fontids[lastfont].parameters.quad,krn)
- done = true
- elseif pid == glyph then
- -- fontdata access can be done more efficient
- if prev.font == lastfont then
- local prevchar, lastchar = prev.char, start.char
- local tfm = fti[lastfont].characters[prevchar]
- local ickern = tfm.kerns
- if ickern and ickern[lastchar] then
- krn = scale(ickern[lastchar]+fontids[lastfont].parameters.quad,krn)
- else
- krn = scale(fontids[lastfont].parameters.quad,krn)
- end
- else
- krn = scale(fontids[lastfont].parameters.quad,krn)
- end
- node.insert_before(head,start,nodes.kern(krn))
- done = true
- elseif pid == disc then
- local disc = start.prev -- disc
- local pre, post, replace = disc.pre, disc.post, disc.replace
- if pre then -- must pair with start.prev
- local before = node.copy(disc.prev)
- pre.prev = before
- before.next = pre
- before.prev = nil
- pre = kerns.process(namespace,attribute,before)
- pre = pre.next
- pre.prev = nil
- disc.pre = pre
- node.free(before)
- end
- if post then -- must pair with start
- local after = node.copy(disc.next)
- local tail = node.slide(post)
- tail.next = after
- after.prev = tail
- after.next = nil
- post = kerns.process(namespace,attribute,post)
- tail.next = nil
- disc.post = post
- node.free(after)
- end
- if replace then -- must pair with start and start.prev
- local before = node.copy(disc.prev)
- local after = node.copy(disc.next)
- local tail = node.slide(post)
- replace.prev = before
- before.next = replace
- before.prev = nil
- tail.next = after
- after.prev = tail
- after.next = nil
- replace = kerns.process(namespace,attribute,before)
- replace = replace.next
- replace.prev = nil
- tail.next = nil
- disc.replace = replace
- node.free(after)
- node.free(before)
- end
+ if trace then trace_natural("filler",current) end
end
+ else
+ if trace then trace_natural("natural (no prev spec)",current) end
end
- elseif id == glue and start.subtype == 0 then
- local s = start.spec
- local w = s.width
- if w > 0 then
- local width, stretch, shrink = w+2*scale(w,krn), s.stretch, s.shrink
- start.spec = nodes.glue_spec(width,scale(stretch,width/w),scale(shrink,width/w))
- -- local width, stretch, shrink = w+2*w*krn, s.stretch, s.shrink
- -- start.spec = nodes.glue_spec(width,stretch*width/w,shrink*width/w))
- done = true
- end
- elseif false and id == kern and start.subtype == 0 then -- handle with glyphs
- local sk = start.kern
- if sk > 0 then
- -- start.kern = scale(sk,krn)
- start.kern = sk*krn
- done = true
- end
- elseif lastfont and (id == hlist or id == vlist) then -- todo: lookahead
- if start.prev then
- node.insert_before(head,start,nodes.kern(scale(fontids[lastfont].parameters.quad,krn)))
- done = true
- end
- if start.next then
- node.insert_after(head,start,nodes.kern(scale(fontids[lastfont].parameters.quad,krn)))
- done = true
- end
- end
- end
- end
- if start then
- start = start.next
- end
- end
- return head, done
- end
-
- lists.handle_kerning = nodes.install_attribute_handler {
- name = "kern",
- namespace = kerns,
- processor = kerns.process,
- }
-
- -- spacing == attributename !! does not belong here but we will
- -- relocate node and attribute stuff once it's more complete !!
-
- -- experimental, we may extend or change this
-
- --~ Analysis by Idris:
- --~
- --~ 1. Assuming the reading- vs word-order distinction (bidi-char types) is governing;
- --~ 2. Assuming that 'ARAB' represents an actual arabic string in raw input order, not word-order;
- --~ 3. Assuming that 'BARA' represent the correct RL word order;
- --~
- --~ Then we have, with input: LATIN ARAB
- --~
- --~ \textdir TLT LATIN ARAB => LATIN BARA
- --~ \textdir TRT LATIN ARAB => LATIN BARA
- --~ \textdir TRT LRO LATIN ARAB => LATIN ARAB
- --~ \textdir TLT LRO LATIN ARAB => LATIN ARAB
- --~ \textdir TLT RLO LATIN ARAB => NITAL ARAB
- --~ \textdir TRT RLO LATIN ARAB => NITAL ARAB
-
- -- elseif d == "es" then -- European Number Separator
- -- elseif d == "et" then -- European Number Terminator
- -- elseif d == "cs" then -- Common Number Separator
- -- elseif d == "nsm" then -- Non-Spacing Mark
- -- elseif d == "bn" then -- Boundary Neutral
- -- elseif d == "b" then -- Paragraph Separator
- -- elseif d == "s" then -- Segment Separator
- -- elseif d == "ws" then -- Whitespace
- -- elseif d == "on" then -- Other Neutrals
-
- mirror = mirror or { }
- mirror.enabled = false
- mirror.trace = false
- mirror.strip = false
-
- local state = attributes.numbers['state'] or 100
-
- function mirror.process(namespace,attribute,head)
- local done, data, directions, trace = false, characters.data, characters.directions, mirror.trace
- local current, inserted, obsolete = head, nil, { }
- local override, embedded, autodir = 0, 0, 0
- local list, glyphs = trace and { }, false
- local stack, top, finished, finidir, finipos = { }, 0, nil, nil, 1
- local finish = nil
- local lro, rlo, prevattr = false, false, 0
- -- todo: delayed inserts here
- local function finish_auto_before()
- head, inserted = node.insert_before(head,current,nodes.textdir("-"..finish))
- finished, finidir = inserted, finish
- if trace then insert(list,#list,format("finish %s",finish)) ; finipos = #list-1 end
- finish, autodir, done = nil, 0, true
- end
- local function finish_auto_after()
- head, current = node.insert_after(head,current,nodes.textdir("-"..finish))
- finished, finidir = current, finish
- if trace then list[#list+1] = format("finish %s",finish) ; finipos = #list end
- finish, autodir, done = nil, 0, true
- end
- local function force_auto_left_before()
- if finish then
- finish_auto_before()
- end
- if embedded >= 0 then
- finish, autodir, done = "TLT", 1, true
- else
- finish, autodir, done = "TRT", -1, true
- end
- if finidir == finish then
- nodes.remove(head,finished,true)
- if trace then list[finipos] = list[finipos].." (deleted)" end
- if trace then insert(list,#list,format("start %s (deleted)",finish)) end
- else
- head, inserted = node.insert_before(head,current,nodes.textdir("+"..finish))
- if trace then insert(list,#list,format("start %s",finish)) end
- end
- end
- local function force_auto_right_before()
- if finish then
- finish_auto_before()
- end
- if embedded <= 0 then
- finish, autodir, done = "TRT", -1, true
- else
- finish, autodir, done = "TLT", 1, true
- end
- if finidir == finish then
- nodes.remove(head,finished,true)
- if trace then list[finipos] = list[finipos].." (deleted)" end
- if trace then insert(list,#list,format("start %s (deleted)",finish)) end
- else
- head, inserted = node.insert_before(head,current,nodes.textdir("+"..finish))
- if trace then insert(list,#list,format("start %s",finish)) end
- end
- end
- local function is_right(n)
- if n then
- local id = n.id
- if id == glyph then
- local attr = has_attribute(n,attribute)
- if attr and attr > 0 then
- local d = directions[n.char]
- if d == "r" or d == "al" then -- override
- return true
- end
- end
- end
- end
- return false
- end
- while current do
- local id = current.id
- local attr = has_attribute(current,attribute)
- if attr and attr > 0 then
- unset_attribute(current,attribute)
- if attr == 1 then
- -- bidi parsing mode
- elseif attr ~= prevattr then
- -- no pop, grouped driven (2=normal,3=lro,4=rlo)
- if attr == 3 then
- if trace then list[#list+1] = format("override right -> left (lro) (bidi=%s)",attr) end
- lro, rlo = true, false
- elseif attr == 4 then
- if trace then list[#list+1] = format("override left -> right (rlo) (bidi=%s)",attr) end
- lro, rlo = false, true
else
- if trace and current ~= head then list[#list+1] = format("override reset (bidi=%s)",attr) end
- lro, rlo = false, false
+ if trace then trace_natural("natural (no prev)",current) end
end
- prevattr = attr
end
- end
- if id == glyph then
- glyphs = true
- if attr and attr > 0 then
- local char = current.char
- local d = directions[char]
- if rlo or override > 0 then
- if d == "l" then
- if trace then list[#list+1] = format("char %s of class %s overidden to r (bidi=%s)",utf.char(char),d,attr) end
- d = "r"
- elseif trace then
- if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
- list[#list+1] = format("override char of class %s (bidi=%s)",d,attr)
- else -- todo: rle lre
- list[#list+1] = format("char %s of class %s (bidi=%s)",utf.char(char),d,attr)
- end
- end
- elseif lro or override < 0 then
- if d == "r" or d == "al" then
- set_attribute(current,state,4) -- maybe better have a special bidi attr value -> override (9) -> todo
- if trace then list[#list+1] = format("char %s of class %s overidden to l (bidi=%s) (state=isol)",utf.char(char),d,attr) end
- d = "l"
- elseif trace then
- if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
- list[#list+1] = format("override char of class %s (bidi=%s)",d,attr)
- else -- todo: rle lre
- list[#list+1] = format("char %s of class %s (bidi=%s)",utf.char(char),d,attr)
- end
- end
- elseif trace then
- if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
- list[#list+1] = format("override char of class %s (bidi=%s)",d,attr)
- else -- todo: rle lre
- list[#list+1] = format("char %s of class %s (bidi=%s)",utf.char(char),d,attr)
+ glue_order, glue_data = 0, nil
+ if current then
+ current = current.next
+ end
+ else
+ local sct = categories[sc] -- or 'unknown'
+ if sct == 'disable' then
+ ignore_following = true
+ if trace then trace_skip(sct,sc,so,sp,current) end
+ head, current = remove_node(head, current, true)
+ elseif sct == 'nowhite' then
+ ignore_whitespace = true
+ head, current = remove_node(head, current, true)
+ elseif sct == 'discard' then
+ if trace then trace_skip(sct,sc,so,sp,current) end
+ head, current = remove_node(head, current, true)
+ else
+ if sp then
+ if not penalty_data then
+ penalty_data = sp
+ elseif penalty_order < so then
+ penalty_order, penalty_data = so, sp
+ elseif penalty_order == so and sp > penalty_data then
+ penalty_data = sp
end
end
- if d == "on" then
- local mirror = data[char].mirror
- if mirror and fonts.tfm.id[current.font].characters[mirror] then
- -- todo: set attribute
- if autodir < 0 then
- current.char = mirror
- done = true
- --~ elseif left or autodir > 0 then
- --~ if not is_right(current.prev) then
- --~ current.char = mirror
- --~ done = true
- --~ end
+ if ignore_following then
+ if trace then trace_skip("disabled",sc,so,sp,current) end
+ head, current = remove_node(head, current, true)
+ elseif not glue_data then
+ if trace then trace_skip("assign " .. sct,sc,so,sp,current) end
+ glue_order = so
+ head, current, glue_data = remove_node(head, current)
+ elseif glue_order < so then
+ if trace then trace_skip("force",sc,so,sp,current) end
+ glue_order = so
+ free_glue_node(glue_data)
+ head, current, glue_data = remove_node(head, current)
+ elseif glue_order == so then
+ if sct == 'largest' then
+ local cs, gs = current.spec, glue_data.spec
+ local cw = (cs and cs.width) or 0
+ local gw = (gs and gs.width) or 0
+ if cw > gw then
+ if trace then trace_skip('largest',sc,so,sp,current) end
+ free_glue_node(glue_data) -- also free spec
+ head, current, glue_data = remove_node(head, current)
+ else
+ if trace then trace_skip('remove smallest',sc,so,sp,current) end
+ head, current = remove_node(head, current, true)
end
- end
- elseif d == "l" or d == "en" then -- european number
- if autodir <= 0 then
- force_auto_left_before()
- end
- elseif d == "r" or d == "al" or d == "an" then -- arabic left, arabic number
- if autodir >= 0 then
- force_auto_right_before()
- end
- elseif d == "lro" then -- Left-to-Right Override -> right becomes left
- if trace then list[#list+1] = "override right -> left" end
- top = top + 1
- stack[top] = { override, embedded }
- override = -1
- obsolete[#obsolete+1] = current
- elseif d == "rlo" then -- Right-to-Left Override -> left becomes right
- if trace then list[#list+1] = "override left -> right" end
- top = top + 1
- stack[top] = { override, embedded }
- override = 1
- obsolete[#obsolete+1] = current
- elseif d == "lre" then -- Left-to-Right Embedding -> TLT
- if trace then list[#list+1] = "embedding left -> right" end
- top = top + 1
- stack[top] = { override, embedded }
- embedded = 1
- obsolete[#obsolete+1] = current
- elseif d == "rle" then -- Right-to-Left Embedding -> TRT
- if trace then list[#list+1] = "embedding right -> left" end
- top = top + 1
- stack[top] = { override, embedded }
- embedded = 1
- obsolete[#obsolete+1] = current
- elseif d == "pdf" then -- Pop Directional Format
- -- override = 0
- if top > 0 then
- local s = stack[top]
- override, embedded = s[1], s[2]
- top = top - 1
- if trace then list[#list+1] = format("state: override: %s, embedded: %s, autodir: %s",override,embedded,autodir) end
- else
- if trace then list[#list+1] = "pop (error, too many pops)" end
- end
- obsolete[#obsolete+1] = current
- end
- else
- if trace then
- local char = current.char
- local d = directions[char]
- list[#list+1] = format("char %s of class %s (no bidi)",utf.char(char),d)
- end
- end
- elseif id == whatsit then
- if finish then
- finish_auto_before()
- end
- local subtype = current.subtype
- if subtype == 6 then
- local dir = current.dir
- local d = dir:sub(2,2)
- if dir:find(".R.") then
- autodir = -1
- else
- autodir = 1
- end
- embeddded = autodir
- if trace then list[#list+1] = format("pardir %s",dir) end
- elseif subtype == 7 then
- local dir = current.dir
- local sign = dir:sub(1,1)
- local dire = dir:sub(3,3)
- if dire == "R" then
- if sign == "+" then
- finish, autodir = "TRT", -1
+ elseif sct == 'goback' then
+ if trace then trace_skip('goback',sc,so,sp,current) end
+ free_glue_node(glue_data) -- also free spec
+ head, current, glue_data = remove_node(head, current)
+ elseif sct == 'force' then
+ -- todo: inject kern
+ if trace then trace_skip('force',sc,so,sp,current) end
+ free_glue_node(glue_data) -- also free spec
+ head, current, glue_data = remove_node(head, current)
+ elseif sct == 'penalty' then
+ if trace then trace_skip('penalty',sc,so,sp,current) end
+ free_glue_node(glue_data) -- also free spec
+ glue_data = nil
+ head, current = remove_node(head, current, true)
+ elseif sct == 'add' then
+ if trace then trace_skip('add',sc,so,sp,current) end
+ local old, new = glue_data.spec, current.spec
+ old.width = old.width + new.width
+ old.stretch = old.stretch + new.stretch
+ old.shrink = old.shrink + new.shrink
+ -- toto: order
+ head, current = remove_node(head, current, true)
else
- finish, autodir = nil, 0
+ if trace then trace_skip("unknown",sc,so,sp,current) end
+ head, current = remove_node(head, current, true)
end
else
- if sign == "+" then
- finish, autodir = "TLT", 1
- else
- finish, autodir = nil, 0
- end
+ if trace then trace_skip("unknown",sc,so,sp,current) end
+ head, current = remove_node(head, current, true)
end
- if trace then list[#list+1] = format("textdir %s",dir) end
- end
- else
- if trace then list[#list+1] = format("node %s",node.type(id)) end
- if finish then
- finish_auto_before()
end
end
- local cn = current.next
- if not cn then
- if finish then
- finish_auto_after()
+ elseif id == penalty then
+ --~ natural_penalty = current.penalty
+ --~ if trace then trace_done("removed penalty",current) end
+ --~ head, current = remove_node(head, current, true)
+ current = current.next
+ elseif id == glue and current.subtype == 2 then
+ local sn = has_attribute(current,snap_category)
+ if sn then
+ -- local sv = nodes.snapvalues[sn]
+ -- if sv then
+ if trace then trace_natural("removed baselineskip",current) end
+ head, current = remove_node(head, current, true)
+ -- else
+ -- current = current.next
+ -- end
+ else
+ if trace then trace_natural("keep baselineskip",current) end
+ current = current.next
+ end
+ elseif id == glue and current.subtype == 3 then
+ -- parskip always comes later
+ if ignore_whitespace then
+ if trace then trace_natural("ignored parskip",current) end
+ head, current = remove_node(head,current,true)
+ elseif glue_data then
+ local ps, gs = current.spec, glue_data.spec
+ if ps and gs and ps.width > gs.width then
+ -- free_glue_spec(glue_data.spec) -- result in double free
+ glue_data.spec = copy_node(ps)
+ if trace then trace_natural("taking parskip",current) end
+ else
+ if trace then trace_natural("removed parskip",current) end
end
+ head, current = remove_node(head, current,true)
+ else
+ if trace then trace_natural("honored parskip",current) end
+ head, current, glue_data = remove_node(head, current)
end
- current = cn
- end
- if trace and glyphs then
- logs.report("bidi","start log")
- for i=1,#list do
- logs.report("bidi","%02i: %s",i,list[i])
- end
- logs.report("bidi","stop log")
- end
- if done and mirror.strip then
- local n = #obsolete
- if n > 0 then
- for i=1,n do
- nodes.remove(head,obsolete[i],true)
- end
- logs.report("bidi","%s character nodes removed",n)
+ --~ if trace then trace_natural("removed parskip",current) end
+ --~ current.spec = nil
+ --~ current = current.next
+ else
+ if glue_data then
+ if trace then trace_done("flushed",glue_data) end
+ head, current = insert_node_before(head,current,glue_data)
+ glue_order, glue_data = 0, nil
end
- end
- return head, done
- end
-
- chars.handle_mirroring = nodes.install_attribute_handler {
- name = "mirror",
- namespace = mirror,
- processor = mirror.process,
- }
-
- cases = cases or { }
- cases.enabled = false
- cases.actions = { }
-
- local function helper(start, code, codes)
- local data, char = characters.data, start.char
- local dc = data[char]
- if dc then
- local fnt = start.font
- local ifc = fonts.tfm.id[fnt].characters
- local ucs = dc[codes]
- if ucs then
- local ok = true
- for i=1,#ucs do
- ok = ok and ifc[ucs[i]]
- end
- if ok then
- local prev, original, copy = start, start, node.copy
- for i=1,#ucs do
- local chr = ucs[i]
- prev = start
- if i == 1 then
- start.char = chr
- else
- local g = copy(original)
- g.char = chr
- local next = start.next
- g.prev = start
- if next then
- g.next = next
- start.next = g
- next.prev = g
- end
- start = g
+ if penalty_data then
+ local p = make_penalty_node(penalty_data)
+ if trace then trace_done("flushed",p) end
+ head, current = insert_node_before(head,current,p)
+ penalty_data = nil
+ end
+ if trace then trace_node(current) end
+ if id == hlist and where == 'hmode_par' then
+ local list = current.list
+ if list then
+ local sn = has_attribute(list,snap_category)
+ if sn then
+ local sv = nodes.snapvalues[sn]
+ if sv then
+ local height, depth, lineheight = sv[1], sv[2], sv[3]
+ -- is math.ceil really needed?
+ current.height = math.ceil((current.height-height)/lineheight)*lineheight + height
+ current.depth = math.ceil((current.depth -depth )/lineheight)*lineheight + depth
end
end
- return prev, true
end
- return start, false
- end
- local uc = dc[code]
- if uc and ifc[uc] then
- start.char = uc
- return start, true
end
+ current = current.next
end
- return start, false
end
-
- local function upper(start)
- return helper(start,'uccode','uccodes')
+ local tail = slide_node_list(head) -- still needed, check previous code ?
+ if trace then trace_info("stop analyzing",where,what) end
+ --~ if natural_penalty and (not penalty_data or natural_penalty > penalty_data) then
+ --~ penalty_data = natural_penalty
+ --~ end
+ if trace and (glue_data or penalty_data) then
+ trace_info("start flushing",where,what)
end
- local function lower(start)
- return helper(start,'lccode','lccodes')
+ if penalty_data then
+ local p = make_penalty_node(penalty_data)
+ if trace then trace_done("result",p) end
+ head, tail = insert_node_after(head,tail,p)
end
-
- cases.actions[1], cases.actions[2] = upper, lower
-
- cases.actions[3] = function(start,attribute)
- local prev = start.prev
- if prev and prev.id == kern and prev.subtype == 0 then
- prev = prev.prev
- end
- if not prev or prev.id ~= glyph then
- --- only the first character is treated
- for n in traverse_id(glyph,start.next) do
- if has_attribute(n,attribute) then
- unset_attribute(n,attribute)
- end
- end
- return upper(start)
- else
- return start, false
- end
+ if glue_data then
+ if trace then trace_done("result",glue_data) end
+ head, tail = insert_node_after(head,tail,glue_data)
end
-
- cases.actions[4] = function(start,attribute)
- local prev = start.prev
- if prev and prev.id == kern and prev.subtype == 0 then
- prev = prev.prev
- end
- if not prev or prev.id ~= glyph then
- return upper(start)
- else
- return start, false
+ if trace then
+ if glue_data or penalty_data then
+ trace_info("stop flushing",where,what)
end
+ show_tracing(head)
end
+ return head, true
+end
+
+-- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display
+-- \par -> vmode_par
+--
+-- status.best_page_break
+-- tex.lists.best_page_break
+-- tex.lists.best_size (natural size to best_page_break)
+-- tex.lists.least_page_cost (badness of best_page_break)
+-- tex.lists.page_head
+-- tex.lists.contrib_head
+
+local stackhead, stacktail, stackhack = nil, nil, false
- -- cases.actions[5] = function(start)
- -- local prev, next = start.prev, start.next
- -- if prev and prev.id == kern and prev.subtype == 0 then
- -- prev = prev.prev
- -- end
- -- if next and next.id == kern and next.subtype == 0 then
- -- next = next.next
- -- end
- -- if (not prev or prev.id ~= glyph) and next and next.id == glyph then
- -- return upper(start)
- -- else
- -- return start, false
- -- end
- -- end
+local function report(message,lst)
+ logs.report("vspacing",message,count_nodes(lst,true),node_ids_to_string(lst))
+end
- cases.actions[8] = function(start)
- local data = characters.data
- local ch = start.char
- local mr = math.random
- local tfm = fonts.tfm.id[start.font].characters
- if data[ch].lccode then
- while true do
- local d = data[mr(1,0xFFFF)]
- if d then
- local uc = d.uccode
- if uc and tfm[uc] then
- start.char = uc
- return start, true
+function nodes.handle_page_spacing(where)
+ local newhead = texlists.contrib_head
+ if newhead then
+ statistics.starttiming(vspacing)
+ local newtail = slide_node_list(newhead)
+ local flush = false
+ for n in traverse_nodes(newhead) do
+ local id = n.id
+ if id == glue then
+ if n.subtype == 0 then
+ if has_attribute(n,skip_category) then
+ stackhack = true
+ else
+ flush = true
end
+ else
+ -- tricky
end
+ else
+ flush = true
end
- elseif data[ch].uccode then
- while true do
- local d = data[mr(1,0xFFFF)]
- if d then
- local lc = d.lccode
- if lc and tfm[lc] then
- start.char = lc
- return start, true
- end
- end
+ end
+ if flush then
+ if stackhead then
+ if trace_collect_vspacing then report("appending %s nodes to stack (final): %s",newhead) end
+ stacktail.next = newhead
+ newhead.prev = stacktail
+ newhead = stackhead
+ stackhead, stacktail = nil, nil
+ end
+ if stackhack then
+ stackhack = false
+ if trace_collect_vspacing then report("processing %s nodes: %s",newhead) end
+ texlists.contrib_head = collapser(newhead,"page",where,trace_page_vspacing)
+ else
+ if trace_collect_vspacing then report("flushing %s nodes: %s",newhead) end
+ texlists.contrib_head = newhead
end
else
- return start, false
- end
- end
-
- -- node.traverse_id_attr
-
- function cases.process(namespace,attribute,head) -- not real fast but also not used on much data
- local done, actions = false, cases.actions
- for start in traverse_id(glyph,head) do
- local attr = has_attribute(start,attribute)
- if attr and attr > 0 then
- unset_attribute(start,attribute)
- local action = actions[attr]
- if action then
- local _, ok = action(start,attribute)
- done = done and ok
- end
+ if stackhead then
+ if trace_collect_vspacing then report("appending %s nodes to stack (intermediate): %s",newhead) end
+ stacktail.next = newhead
+ newhead.prev = stacktail
+ else
+ if trace_collect_vspacing then report("storing %s nodes in stack (initial): %s",newhead) end
+ stackhead = newhead
end
+ stacktail = newtail
+ texlists.contrib_head = nil
end
- return head, done
+ statistics.stoptiming(vspacing)
end
+end
- chars.handle_casing = nodes.install_attribute_handler {
- name = "case",
- namespace = cases,
- processor = cases.process,
- }
-
- breakpoints = breakpoints or { }
- breakpoints.mapping = breakpoints.mapping or { }
- breakpoints.methods = breakpoints.methods or { }
- breakpoints.enabled = false
-
- input.storage.register(false,"breakpoints/mapping", breakpoints.mapping, "breakpoints.mapping")
+local ignore = table.tohash {
+ "split_keep",
+ "split_off",
+ -- "vbox",
+}
- function breakpoints.setreplacement(id,char,kind,before,after)
- local mapping = breakpoints.mapping[id]
- if not mapping then
- mapping = { }
- breakpoints.mapping[id] = mapping
- end
- mapping[char] = { kind or 1, before or 1, after or 1 }
+function nodes.handle_vbox_spacing(head,where)
+ if head and not ignore[where] and head.next then
+ statistics.starttiming(vspacing)
+ head = collapser(slide_node_list(head),"vbox",where,trace_vbox_vspacing)
+ statistics.stoptiming(vspacing)
end
+ return head
+end
- breakpoints.methods[1] = function(head,start)
- if start.prev and start.next then
- node.insert_before(head,start,nodes.penalty(10000))
- node.insert_before(head,start,nodes.glue(0))
- node.insert_after(head,start,nodes.glue(0))
- node.insert_after(head,start,nodes.penalty(0))
- end
- return head, start
- end
- breakpoints.methods[2] = function(head,start) -- ( => (-
- if start.prev and start.next then
- local tmp = start
- start = nodes.disc()
- start.prev, start.next = tmp.prev, tmp.next
- tmp.prev.next, tmp.next.prev = start, start
- tmp.prev, tmp.next = nil, nil
- start.replace = tmp
- local tmp, hyphen = node.copy(tmp), node.copy(tmp)
- hyphen.char = languages.prehyphenchar(tmp.lang)
- tmp.next, hyphen.prev = hyphen, tmp
- start.post = tmp
- node.insert_before(head,start,nodes.penalty(10000))
- node.insert_before(head,start,nodes.glue(0))
- node.insert_after(head,start,nodes.glue(0))
- node.insert_after(head,start,nodes.penalty(10000))
- end
- return head, start
- end
- breakpoints.methods[3] = function(head,start) -- ) => -)
- if start.prev and start.next then
- local tmp = start
- start = nodes.disc()
- start.prev, start.next = tmp.prev, tmp.next
- tmp.prev.next, tmp.next.prev = start, start
- tmp.prev, tmp.next = nil, nil
- start.replace = tmp
- local tmp, hyphen = node.copy(tmp), node.copy(tmp)
- hyphen.char = languages.prehyphenchar(tmp.lang)
- tmp.prev, hyphen.next = hyphen, tmp
- start.pre = hyphen
- node.insert_before(head,start,nodes.penalty(10000))
- node.insert_before(head,start,nodes.glue(0))
- node.insert_after(head,start,nodes.glue(0))
- node.insert_after(head,start,nodes.penalty(10000))
- end
- return head, start
+statistics.register("v-node processing time", function()
+ if statistics.elapsedindeed(vspacing) then
+ return format("%s seconds", statistics.elapsedtime(vspacing))
end
+end)
- function breakpoints.process(namespace,attribute,head)
- local done, mapping, fontids = false, breakpoints.mapping, fonts.tfm.id
- local start, n = head, 0
- while start do
- local id = start.id
- if id == glyph then
- local attr = has_attribute(start,attribute)
- if attr and attr > 0 then
- unset_attribute(start,attribute) -- maybe test for subtype > 256 (faster)
- -- look ahead and back n chars
- local map = mapping[attr]
- if map then
- local smap = map[start.char]
- if smap then
- if n >= smap[2] then
- local m = smap[3]
- local next = start.next
- while next do -- gamble on same attribute
- local id = next.id
- if id == glyph then -- gamble on same attribute
- if map[next.char] then
- break
- elseif m == 1 then
- local method = breakpoints.methods[smap[1]]
- if method then
- head, start = method(head,start)
- done = true
- end
- break
- else
- m = m - 1
- next = next.next
- end
- elseif id == kern and next.subtype == 0 then
- next = next.next
- -- ignore intercharacter kerning, will go way
- else
- -- we can do clever and set n and jump ahead but ... not now
- break
- end
- end
- end
- n = 0
- else
- n = n + 1
- end
- else
- n = 0
- end
- end
- elseif id == kern and start.subtype == 0 then
- -- ignore intercharacter kerning, will go way
- else
- n = 0
- end
- start = start.next
- end
- return head, done
- end
-
- chars.handle_breakpoints = nodes.install_attribute_handler {
- name = "breakpoint",
- namespace = breakpoints,
- processor = breakpoints.process,
- }
+-- these are experimental callback definitions that definitely will
+-- be moved elsewhere as part of a chain of vnode handling
+function vspacing.enable()
+--~ callback.register('vpack_filter', nodes.handle_vbox_spacing)
+ callback.register('buildpage_filter', nodes.handle_page_spacing)
end
--- educational: snapper
-
---~ function demo_snapper(head,where) -- snap_category 105 / nodes.snapvalue = { [1] = { 8*65536, 4*65536, 12*65536 } }
---~ if head then
---~ local current, tail, dummy = head, nil, nil
---~ while current do
---~ local id = current.id
---~ if id == glue and current.subtype == 2 then
---~ local sn = has_attribute(current,snap_category)
---~ if sn then
---~ local sv = nodes.snapvalues[sn]
---~ if sv then
---~ head, current, dummy = node.delete(head, current)
---~ node.free(dummy)
---~ else
---~ current = current.next
---~ end
---~ else
---~ current = current.next
---~ end
---~ else
---~ if id == hlist and where == 'hmode_par' and current.list then
---~ local sn = has_attribute(current.list,snap_category)
---~ if sn then
---~ local sv = nodes.snapvalues[sn]
---~ if sv then
---~ local height, depth, lineheight = sv[1], sv[2], sv[3]
---~ current.height = math.ceil((current.height-height)/lineheight)*lineheight + height
---~ current.depth = math.ceil((current.depth -depth )/lineheight)*lineheight + depth
---~ end
---~ end
---~ end
---~ current = current.next
---~ end
---~ tail = current
---~ end
---~ end
---~ return head
---~ end
-
---~ callback.register('buildpage_filter', demo_snapper)
-
--- obsolete, callback changed
-
---~ local head, tail = nil, nil
-
---~ function nodes.flush_vertical_spacing()
---~ if head and head.next then
---~ local t = collapser(head,'flush')
---~ head = nil
---~ -- tail = nil
---~ return t
---~ else
---~ return head
---~ end
---~ end
-
---~ function nodes.handle_page_spacing(t, where)
---~ where = where or "page"
---~ -- we need to add the latest t too, else we miss skips and such
---~ if t then
---~ --~ node.slide(t) -- redunant
---~ if t.next then
---~ local tt = node.slide(t)
---~ local id = tt.id
---~ if id == glue then -- or id == penalty then -- or maybe: if not hlist or vlist
---~ if head then
---~ t.prev = tail
---~ tail.next = t
---~ else
---~ head = t
---~ end
---~ tail = tt
---~ t = nil
---~ elseif head then
---~ t.prev = tail
---~ tail.next = t
---~ t = collapser(head,"page",where)
---~ head = nil
---~ else
---~ t = collapser(t,"page",where)
---~ end
---~ elseif head then
---~ t.prev = tail
---~ tail.next = t
---~ t = collapser(head,"page",where)
---~ head = nil
---~ else
---~ t = collapser(t,"page",where)
---~ end
---~ elseif head then
---~ t = collapser(head,"page",where)
---~ head = nil
---~ end
---~ return t
---~ end
+function vspacing.disable()
+ callback.register('vpack_filter', nil)
+ callback.register('buildpage_filter', nil)
+end
diff --git a/tex/context/base/core-spa.mkii b/tex/context/base/core-spa.mkii
index b3d71699d..356b2cbe3 100644
--- a/tex/context/base/core-spa.mkii
+++ b/tex/context/base/core-spa.mkii
@@ -11,36 +11,4644 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Spacing}
+
+% to be sorted out: dependencies, order of initialization / also some dutch code here
+
\unprotect
-% Just after we implemented the \MKIV\ code, Thanh posted a patch for
-% \PDFTEX. The following code is untested! (\LUATEX\ does not contain
-% this code!)
+% some will move to core-var
+
+\newif \ifgridsnapping
+\newif \iffuzzyvskip
+\let \fuzzyvskip \gobbleoneargument
+\let \removelastfuzzyvskip \relax
+
+\let \startbaselinecorrection \relax
+\let \stopbaselinecorrection \relax
+\let \baselinecorrection \relax
+\let \offbaselinecorrection \relax
+
+\appendtoks \spacing 1\to \everybodyfont
+\appendtoks \presetnormallineheight \to \everybodyfont
+\appendtoks \setnormalbaselines \to \everybodyfont % check if redundant
+\appendtoks \setstrut \to \everybodyfont % check if redundant
+\appendtoks \settopskip \to \everybodyfont
+\appendtoks \setmaxdepth \to \everybodyfont
+%appendtoks \spacing 1\to \everybodyfont
+\appendtoks \simplesetupindenting \to \everybodyfont
+\appendtoks \simplesetupblank \to \everybodyfont
+\appendtoks \simplesetupwhitespace \to \everybodyfont
+%appendtoks \checknotes \to \everybodyfont % not
+\appendtoks \simplesetupspacing \to \everybodyfont % nieuw
+\appendtoks \setrelativeinterlinespace \to \everybodyfont
+
+\appendtoks \updateraggedskips \to \everyfontswitch % under test
+\prependtoks \let\par\endgraf \to \everypagebody % see \fillinline
+\appendtoks \simplesetupspacing \to \everydefinedfont
+
+% if you want to hyphenate the first word of a paragraph ... \appendtoks\hskip0pt\to\everypar
+
+\def\stelfactorenin
+ {\simplesetupwhitespace
+ \simplesetupblank
+ \settopskip
+ \setmaxdepth}
+
+\def\softbreak
+ {\relax\ifhmode\hskip\parfillskip\break\fi}
+
+\let\poplastnode\relax
+
+\def\pushlastnode
+ {\ifdim\lastskip=\zeropoint
+ \ifnum\lastpenalty=\zerocount
+ \ifnum\lastkern=\zerocount
+ \let\poplastnode\relax
+ \else
+ \edef\poplastnode{\kern\the\lastkern\relax}\kern-\lastkern % untested
+ \fi
+ \else
+ \edef\poplastnode{\penalty\the\lastpenalty\relax}\nobreak % untested
+ \fi
+ \else
+ \edef\poplastnode{\vskip\the\lastskip\relax}\vskip-\lastskip % \removelastskip
+ \fi}
+
+%D The dreadful sequence \type {\bgroup} \unknown\
+%D \type {\carryoverpar} \unknown\ \type {\egroup} is needed
+%D when for instance sidefloats are used in combination with
+%D something that starts with a group. This is because
+%D otherwise the indentation as set (by the output routine)
+%D inside the group are forgotten afterwards. (I must
+%D not forget its existence).
+
+\global\let\carriedoverpar\relax
+
+\def\carryoverpar#1%
+ {\expanded % \scratchtoks{#1}%
+ {\noexpand#1% \the\scratchtoks
+ \hangindent\the\hangindent
+ \hangafter \the\hangafter
+ \parskip \the\parskip
+ \leftskip \the\leftskip
+ \rightskip \the\rightskip}}
+
+%D A quick way to determine left|/|middle|/|right states
+%D (experimental).
+
+\setvalue{\??as\v!left }{0}
+\setvalue{\??as\v!middle}{1}
+\setvalue{\??as\v!right }{2}
+
+\def\setalignmentswitch#1%
+ {\chardef\alignmentswitch0\csname\??as#1\endcsname\relax}
+
+%D There are two ways to influence the interline spacing. The
+%D most general and often most consistent way is using
+%D
+%D \showsetup{setupinterlinespace}
+%D
+%D For instance
+%D
+%D \starttyping
+%D \setupinterlinespace[line=2.8ex]
+%D \stoptyping
+%D
+%D This setting adapts itself to the bodyfontsize, while for
+%D instance saying
+%D
+%D \starttyping
+%D \setupinterlinespace[line=12pt]
+%D \stoptyping
+%D
+%D sets things fixed for all sizes, which is definitely not
+%D what we want. Therefore one can also say:
+%D
+%D \starttyping
+%D \definebodyfontenvironment[9pt][interlinespace=11pt]
+%D \stoptyping
+%D
+%D One can still use \type{\setupinterlinespace} (without
+%D arguments) to set the interline space according to the
+%D current font, e.g. a \type{\bfa}.
+
+\newif\iflocalinterlinespace
+
+% font-ini
+
+\ifx\bodyfontinterlinespecs\undefined
+
+ \let\bodyfontinterlinespecs\empty
+ \let\bodyfontinterlinespace\empty
+
+\fi
+
+\def\presetnormallineheight
+ {\edef\normallineheight{\@@itline}%
+% done elsewhere : \spacing\!!plusone % new per 10/08/2004, else problems in otr / !! needed
+ \iflocalinterlinespace \else
+ \doifdefined\bodyfontinterlinespecs
+ {\doifsomething\bodyfontinterlinespace
+ {\edef\normallineheight{\bodyfontinterlinespace}}}%
+ \fi}
+
+\def\setupspecifiedinterlinespace[#1]%
+ {\getparameters[\??it][#1]%
+ \scratchdimen0\@@itheight\points
+ \advance\scratchdimen 0\@@itdepth\points
+ \ifdim\scratchdimen>\onepoint
+ \showmessage\m!layouts{10}{\@@itheight,\@@itdepth}%
+ \let\@@itheight\strutheightfactor
+ \let\@@itdepth \strutdepthfactor
+ \else
+ \let\strutheightfactor\@@itheight
+ \let\strutdepthfactor \@@itdepth
+ \fi
+ \let\minimumstrutheight \@@itminheight
+ \let\minimumstrutdepth \@@itmindepth
+ \let\minimumlinedistance\@@itdistance
+ \let\normallineheight \@@itline % let ! ! ! ! ! ivm ex
+ \doifelse\@@ittop\v!height % new, topskip does more bad than good
+ {\let\topskipfactor \@@itheight}
+ {\let\topskipfactor \@@ittop }%
+ \let\maxdepthfactor \@@itbottom
+ \let\baselinegluefactor \@@itstretch
+ \setfontparameters % redundant, can be \setstrut, test first
+ \updateraggedskips} % yes indeed
+
+% \let\currentrelativeinterlinespace\empty
+%
+% \def\setuprelativeinterlinespace[#1]%
+% {\processallactionsinset
+% [#1]
+% [ \v!on=>\oninterlineskip,
+% \v!off=>\offinterlineskip,
+% \v!reset=>\let\currentrelativeinterlinespace\empty
+% \setfontparameters,% just \setstrut, test first
+% \s!unknown=>\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
+% \spacing\currentrelativeinterlinespace]}
+
+% \setupinterlinespace[big] \switchtobodyfont[11pt] -> forgotten
+% \setupinterlinespace[auto,big] \switchtobodyfont[11pt] -> remembered
+
+\let\currentrelativeinterlinespace\empty
+
+\def\setuprelativeinterlinespace[#1]%
+ {\processallactionsinset
+ [#1]
+ [ \v!on=>\oninterlineskip,
+ \v!off=>\offinterlineskip,
+ \v!reset=>\let\currentrelativeinterlinespace\empty
+ \let\setrelativeinterlinespace\relax
+ \setfontparameters,
+ \v!auto=>\let\setrelativeinterlinespace\dosetrelativeinterlinespace,
+ \s!unknown=>\assignvalue\commalistelement\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
+ \spacing\currentrelativeinterlinespace]}
+
+\def\dosetrelativeinterlinespace
+ {\ifx\currentrelativeinterlinespace\empty\else
+ \spacing\currentrelativeinterlinespace
+ \fi}
+
+\let\setrelativeinterlinespace\relax
+
+% \appendtoks \setrelativeinterlinespace \to \everybodyfont
+
+\def\complexsetupinterlinespace[#1]% \commalistelement ipv #1
+ {\doifassignmentelse{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]}
+
+\def\setuplocalinterlinespace[#1]%
+ {\localinterlinespacetrue
+ \setupinterlinespace[#1]%
+ \localinterlinespacefalse}
+
+\def\simplesetupinterlinespace
+ {\localinterlinespacetrue
+ \setfontparameters
+ \updateraggedskips % funny one here
+ \localinterlinespacefalse}
+
+\definecomplexorsimple\setupinterlinespace
+
+% In earlier versions \type{\bigskipamount} was
+% \type{\ht\strutbox} and the stretch was plus or minus
+% \type{.4\dp\strutbox}. Don't ask me why. The most recent
+% implementation is based on a user supplied distance, which
+% is by default \type{.75\normalskipamount} where
+% \type{\normalskipamount} equals the current baseline
+% distance.
+
+% \lineskiplimit = -\maxdimen -> freezes baselineskip
+
+% can be conditionals
+
+\newif\ifblanknowhite \blanknowhitefalse
+\newif\ifblankindeed \blankindeedfalse
+\newif\ifblankreset \blankresetfalse
+\newif\ifblankdisable \blankdisablefalse
+\newif\ifblankflexible \blankflexibletrue
+\newif\ifblankouter
+\newif\ifblankforce
+\newif\ifblankgoback
+
+\newskip\blankskip \blankskip=\bigskipamount
+\newskip\blankskipamount
+
+\def\skipfactor {.75}
+\def\skipgluefactor{.25}
+
+\def\normalskipamount
+ {\openlineheight
+ \ifgridsnapping \else \ifblankflexible
+ \!!plus \skipgluefactor\openlineheight
+ \!!minus\skipgluefactor\openlineheight
+ \fi \fi
+ \relax}
+
+\def\linedistance {\normalskipamount}
+\def\appliedblankskip{\skipfactor\linedistance}
+\def\lastblankskip {\blankskip}
+\def\currentblank {\v!big}
+\def\oldprevdepth {\prevdepth}
+\def\newprevdepth {-1001pt}
+\def\mindimen {1sp} % was: 0.00002pt
+
+\newif\iflocalblankfixed
+\newif\iflocalblankflexible
+
+\def\geenblanko{\removelastskip} % will become obsolete
+
+%%%% pas op, wordt ook in core-pos gebruikt
+
+\def\doassignsomeskip#1\to#2% ook nog \v!halfline+fuzzysnap
+ {\doifelse{#1}\v!line
+ {#2\openlineheight}
+ {\ifgridsnapping
+ \assigndimension{#1}{#2}{.25\openlineheight}{.5\openlineheight}\openlineheight
+ \else
+ \assigndimension{#1}{#2}\smallskipamount\medskipamount\bigskipamount
+ \fi}%
+ \relax}
+
+% \relax is really needed, else we may loose stretch due to lookahead; somehow
+% this bug was introduced a while ago but somehow went unnoticed; fixed 2/7/2008
+
+\def\addblankskip#1#2#3{\global\advance\blankskip#1\ifgridsnapping#3\else#2\fi\relax}
+
+\def\defineblankmethod[#1]#2{\setvalue{\??bo\??bo#1}{#2}}
+
+\defineblankmethod [\v!big] {\addblankskip+\bigskipamount \openlineheight}
+\defineblankmethod [-\v!big] {\addblankskip-\bigskipamount \openlineheight}
+\defineblankmethod [\v!medium] {\addblankskip+\medskipamount {.5\openlineheight}}
+\defineblankmethod [-\v!medium] {\addblankskip-\medskipamount {.5\openlineheight}}
+\defineblankmethod [\v!small] {\addblankskip+\smallskipamount{.25\openlineheight}}
+\defineblankmethod [-\v!small] {\addblankskip-\smallskipamount{.25\openlineheight}}
+\defineblankmethod [\v!white] {\addblankskip+\parskip \openlineheight}
+\defineblankmethod [-\v!white] {\addblankskip-\parskip \openlineheight}
+\defineblankmethod [\v!line] {\addblankskip+\openlineheight \openlineheight}
+\defineblankmethod [-\v!line] {\addblankskip-\openlineheight \openlineheight}
+
+\defineblankmethod [\v!formula] {\global\advance\blankskip\medskipamount}
+\defineblankmethod [\v!nowhite] {\global\blanknowhitetrue}
+\defineblankmethod [\v!disable] {\global\blankdisabletrue}
+\defineblankmethod [\v!force] {\global\blankforcetrue}
+\defineblankmethod [\v!outer] {\ifvmode\ifinner\blankoutertrue\fi\fi}
+\defineblankmethod [\v!reset] {\global\blankresettrue}
+\defineblankmethod [\v!flexible] {\global\localblankflexibletrue}
+\defineblankmethod [\v!fixed] {\global\localblankfixedtrue}
+\defineblankmethod [\v!back] {\global\blankgobacktrue} % {\geenblanko}
+\defineblankmethod [\v!halfline] {\ifgridsnapping\global\fuzzyvskiptrue\fi
+ \global\advance\blankskip .5\lineheight}
+
+\defineblankmethod [\v!none] {\global\blankresettrue}
+\defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi}
+
+\defineblankmethod [\v!always] {\redowhitespace} % experimental
+
+% happens often, so we speed this up:
+%
+% \defineblankmethod [2*\v!line] {\addblankskip+{2\openlineheight}{2\openlineheight}}
+% \defineblankmethod [2*\v!big] {\addblankskip+{2\bigskipamount }{2\openlineheight}}
+%
+% no, with 2\whatever we loose the stretch and shrink! Taco's alternative:
+
+\defineblankmethod
+ [2*\v!line]
+ {\addblankskip+\openlineheight\openlineheight
+ \addblankskip+\openlineheight\openlineheight}
+
+\defineblankmethod
+ [2*\v!big]
+ {\addblankskip+\bigskipamount\openlineheight
+ \addblankskip+\bigskipamount\openlineheight}
+
+\def\doblank#1%
+ {\edefconvertedargument\ascii{#1}%
+ \ifx\ascii\empty\else
+ \ifcsname\??bo\??bo\ascii\endcsname % internal def
+ \csname\??bo\??bo\ascii\endcsname
+ \else\ifcsname\??bo\ascii\endcsname % user def / slow
+ \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
+ \else
+ \dorepeatwithcommand[#1]\redoblank
+ \fi\fi
+ \fi
+ \relax}
+
+\def\redoblank#1%
+ {\edefconvertedargument\ascii{#1}%
+ \ifx\ascii\empty\else
+ \ifcsname\??bo\??bo\ascii\endcsname % internal def
+ \csname\??bo\??bo\ascii\endcsname
+ \else\ifcsname\??bo\ascii\endcsname % user def / slow
+ \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
+ \else
+ \global\advance\blankskip#1\relax
+ \fi\fi
+ \fi
+ \relax}
+
+\unexpanded\def\blank % the \relax is definitely needed due to the many \if's
+ {\relax\complexorsimple\doblank}
+
+\def\complexdoblank
+ {\flushnotes
+ \ifmmode
+ \@EA\nocomplexdoblank
+ \else
+ \ifopelkaar
+ \ifinpagebody
+ \@EA\@EAEAEA\@EA\docomplexdoblank
+ \else
+ \@EA\@EAEAEA\@EA\nocomplexdoblank
+ \fi
+ \else
+ \@EAEAEA\docomplexdoblank
+ \fi
+ \fi}
+
+\def\nocomplexdoblank[#1]%
+ {% evt blokkeerfalse
+ \ifmmode\else\par\fi}
+
+% Overloaded in cont-new!
+
+\newsignal\noblanksignal
+
+% \def\doinhibitblank
+% {\kern\noblanksignal}
+
+% \def\inhibitblank% the fast, local way
+% {\endgraf\ifvmode\prevdepth\newprevdepth\fi}
+
+% \def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
+% {\global\blankresetfalse
+% \global\blankdisablefalse
+% \global\blanknowhitefalse
+% \global\localblankflexiblefalse
+% \global\localblankfixedfalse
+% \global\blankskip\zeropoint
+% \global\blankforcefalse
+% \global\blankgobackfalse
+% \blankouterfalse
+% \expanded{\rawprocesscommalist[#1]}\doblank
+% \ifdim\blankskip=\zeropoint\relax
+% \iflocalblankflexible
+% \doglobal\advance\blankskip \currentblank
+% \else\iflocalblankfixed
+% \doglobal\advance\blankskip \currentblank
+% \fi\fi
+% \fi
+% \ifblankouter
+% \else
+% \par
+% \ifvmode
+% \ifblankgoback
+% \removelastskip
+% \fi
+% \ifblankforce
+% % dit gaat mis in pos fonts
+% % \ifdim\prevdepth>\zeropoint\else ...
+% % -1000pt signals top of page or column (\ejectcolumn)
+% \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
+% \fi
+% \ifblankdisable
+% \global\blankindeedfalse
+% \ifgridsnapping
+% \ifdim\prevdepth<\zeropoint
+% % brrr
+% \else
+% % dirty trick: smaller blanks are ignored after
+% % a larger one, so 10 lines is probably safe; first make
+% % sure that we honor penalties
+% \scratchcounter\lastpenalty
+% % now comes the trick (cross our fingers that this works
+% % well in multi columns; maybe an ifinner test is needed
+% % \vskip-10\lineheight
+% % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
+% % \vskip 10\lineheight
+% % allas, this leads to overfull pages, so we try this:
+% \kern-\noblanksignal
+% \ifnum\scratchcounter=\zerocount
+% \else
+% \penalty\lastpenalty
+% \fi
+% \kern\noblanksignal
+% % end-of-dirty-trick
+% \fi
+% \else
+% \ifdim\prevdepth<\zeropoint
+% % brrr
+% \else
+% % ensure at least a proper prevdepth, this should be
+% % an option
+% \vskip-\prevdepth
+% \vskip\strutdepth
+% \prevdepth\strutdepth
+% \fi
+% % the old crappy piece of code
+% \edef\oldprevdepth{\the\prevdepth}%
+% \prevdepth\newprevdepth
+% \fi
+% \else
+% \global\blankindeedtrue
+% \fi
+% \ifblankreset
+% \global\blankindeedtrue
+% \ifgridsnapping
+% % let's play safe and not fool around with the depth, if
+% % only because it took a lot of effort to sort out the grid
+% % stuff in the first place
+% \else
+% \ifdim\prevdepth=\newprevdepth
+% \prevdepth\oldprevdepth
+% \fi
+% \fi
+% \fi
+% \ifblankindeed
+% \ifdim1\lastskip<1\blankskip\relax
+% % else when \blanko[2*groot] + \blanko[3*groot] with parskip
+% % equaling 1*groot, gives a groot=\parskip so adding a small
+% % value makes it distinguishable; can also be done at parskip
+% % setting time (better)
+% \global\advance\blankskip \mindimen\relax % = skip
+% % test this on 2* + 3* and parskip groot
+% \ifblanknowhite
+% \global\advance\blankskip -\parskip
+% \else
+% \ifdim\lastskip=\parskip
+% \else % force this due to previous comment
+% \ifdim\parskip>\zeropoint\relax
+% \ifdim\blankskip<\parskip\relax
+% \global\blankskip\zeropoint
+% \else
+% \global\advance\blankskip -\parskip
+% \fi
+% \fi
+% \fi
+% \fi
+% \ifblankflexible \else
+% \blankskip1\blankskip
+% \fi
+% \iflocalblankfixed
+% \blankskip1\blankskip
+% \fi
+% \iflocalblankflexible
+% \blankskip1\blankskip
+% \!!plus\skipgluefactor\blankskip
+% \!!minus\skipgluefactor\blankskip
+% \fi
+% \ifdim\lastkern=\noblanksignal % controled and grid
+% \global\blankindeedfalse
+% \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
+% \global\blankindeedfalse
+% \fi\fi\fi
+% \ifblankindeed
+% \iffuzzyvskip
+% \removelastfuzzyvskip
+% \fuzzyvskip\blankskip\relax
+% \else
+% \removelastskip
+% \vskip\blankskip\relax
+% \fi
+% \fi
+% \else
+% \iffuzzyvskip
+% \removelastfuzzyvskip
+% \fuzzyvskip\blankskip\relax
+% \else
+% % new, test this on pascal
+% \ifdim\blankskip<\zeropoint
+% \advance\blankskip-\lastskip
+% \removelastskip
+% \ifdim\blankskip>\zeropoint
+% \vskip\blankskip
+% \else
+% \vskip\zeropoint
+% \fi
+% \else
+% % also new
+% \ifdim\blankskip=\zeropoint
+% \ifblanknowhite
+% \geenwitruimte
+% \fi
+% \fi
+% \fi
+% \fi
+% \fi
+% \fi
+% \fi
+% \fi
+% \global\fuzzyvskipfalse
+% \presetindentation}
+
+% goback was broken:
+
+% \def\doinhibitblank
+% {\kern\noblanksignal}
+
+% \def\inhibitblank% the fast, local way
+% {\endgraf\ifvmode\prevdepth\newprevdepth\fi}
+
+% problem: we cannot look back in the mvl so we need 3 kinds of signals
+
+\def\noblankpsignal{1010101}
+
+\def\inhibitgridblank % was doinhibitblank
+ {\ifvmode\else\endgraf\fi
+ \ifvmode
+ \ifnum\lastpenalty<10000
+ \kern-\noblanksignal % new
+ \kern \noblanksignal
+ \else
+ \penalty\noblankpsignal
+ \fi
+ \fi}
+
+\def\inhibittextblank % was inhibitblank
+ {\endgraf
+ \ifvmode
+ \prevdepth\newprevdepth
+ \fi}
+
+% new macro
+%
+% \def\inhibitblank % need some work
+% {\endgraf
+% \ifvmode
+% \ifgridsnapping
+% \inhibitgridblank
+% \else
+% % this one spoils the grid
+% \inhibittextblank
+% \fi
+% \fi}
+
+\def\doinhibitblank{\inhibitgridblank}
+\def\inhibitblank {\inhibittextblank}
+
+% will become obsolete
+
+\ifx\undefined\savedlastskip \newskip \savedlastskip \fi
+\ifx\undefined\savedlastpenalty \newcount\savedlastpenalty \fi
+
+% beware, prevdepth can have funny values (e.g. mvl value when in box)
+
+\def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
+ {\global\blankresetfalse
+ \global\blankdisablefalse
+ \global\blanknowhitefalse
+ \global\localblankflexiblefalse
+ \global\localblankfixedfalse
+ \global\blankforcefalse
+ \global\blankgobackfalse
+ \blankouterfalse
+ \global\blankskip\zeropoint
+%
+\edefconvertedargument\ascii{#1}% todo fast check for simple
+\ifcsname\??bo\??bo\ascii\endcsname % internal def
+ \csname\??bo\??bo\ascii\endcsname
+\else\ifcsname\??bo\ascii\endcsname % user def / slow
+ \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
+\else
+ \expanded{\rawprocesscommalist[#1]}\doblank
+\fi\fi
+%
+ \relax % to be sure
+ \ifdim\blankskip=\zeropoint\relax
+ \iflocalblankflexible
+ \doglobal\advance\blankskip \currentblank
+ \else\iflocalblankfixed
+ \doglobal\advance\blankskip \currentblank
+ \fi\fi
+ \fi
+ \relax % to be sure
+ \ifblankouter
+ % do nothing
+ \else
+ \par
+ \ifvmode
+ \ifblankgoback
+ \ifdim\lastskip>\zeropoint \vskip-\lastskip \fi
+ \savedlastskip\zeropoint
+ \else\ifdim\lastskip>\zeropoint
+ \savedlastskip\lastskip
+ \else % todo: lastnode, dan namelijk geen skip !
+ \savedlastskip\zeropoint
+ \fi\fi
+ \ifblankforce
+ % dit gaat mis in pos fonts
+ % \ifdim\prevdepth>\zeropoint\else ...
+ % -1000pt signals top of page or column (\ejectcolumn)
+ \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
+ \savedlastskip\zeropoint
+ \fi
+ \savedlastpenalty\lastpenalty % hm, now it gets lost
+ \ifblankdisable
+ \global\blankindeedfalse % keep this, i.e. disable current too
+ \ifgridsnapping
+ \ifdim\prevdepth<\zeropoint
+ % brrr
+ \else
+ % dirty trick: smaller blanks are ignored after a
+ % larger one, so 10 lines is probably safe; we need
+ % to make sure that we honor penalties; here comes the
+ % trick (cross our fingers that this works well in
+ % multi columns; maybe an ifinner test is needed
+ % \scratchcounter\lastpenalty
+ % \vskip-10\lineheight
+ % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
+ % \vskip 10\lineheight
+ % alas, this leads to overfull pages, so we try this:
+ \inhibitgridblank
+ \fi
+ \else
+ \ifdim\prevdepth<\zeropoint
+ % brrr
+ \else
+ % ensure at least a proper prevdepth, this should be
+ % an option
+ \vskip-\prevdepth
+ \vskip\strutdepth
+ \prevdepth\strutdepth
+ \fi
+ % the old crappy piece of code
+ \edef\oldprevdepth{\the\prevdepth}%
+ \prevdepth\newprevdepth % == \inhibittextblank
+ \fi
+ \else
+ \global\blankindeedtrue
+ \fi
+ \ifblankreset
+ \global\blankindeedtrue
+ \ifgridsnapping
+ % let's play safe and not fool around with the depth, if
+ % only because it took a lot of effort to sort out the grid
+ % stuff in the first place
+ \else
+ \ifdim\prevdepth=\newprevdepth
+ \prevdepth\oldprevdepth
+ \fi
+ \fi
+ \fi
+ \ifblankindeed
+ \ifdim1\savedlastskip<1\blankskip\relax
+ % else when \blank[2*groot] + \blank[3*groot] with parskip
+ % equaling 1*groot, gives a groot=\parskip so adding a small
+ % value makes it distinguishable; can also be done at parskip
+ % setting time (better)
+ \global\advance\blankskip \mindimen\relax % = skip
+ % test this on 2* + 3* and parskip groot
+ \ifblanknowhite
+ \global\advance\blankskip -\parskip
+ \else
+ \ifdim\savedlastskip=\parskip
+ \else % force this due to previous comment
+ \ifdim\parskip>\zeropoint\relax
+ \ifdim\blankskip<\parskip\relax
+ \global\blankskip\zeropoint
+ \else
+ \global\advance\blankskip -\parskip
+ \fi
+ \fi
+ \fi
+ \fi
+ \ifblankflexible \else
+ \blankskip1\blankskip
+ \fi
+ \iflocalblankfixed
+ \blankskip1\blankskip
+ \fi
+ \iflocalblankflexible
+ \blankskip1\blankskip
+ \!!plus \skipgluefactor\blankskip
+ \!!minus\skipgluefactor\blankskip
+ \fi
+ \ifdim\lastkern=\noblanksignal\relax % controlled and grid
+ \global\blankindeedfalse
+ \else\ifnum\savedlastpenalty=\noblankpsignal\relax % controlled and grid
+ \global\blankindeedfalse
+ \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
+ \global\blankindeedfalse
+ \fi\fi\fi\fi
+ \ifblankindeed
+ \iffuzzyvskip
+ \removelastfuzzyvskip
+ \fuzzyvskip\blankskip\relax
+ \else
+ \relax\ifdim\savedlastskip=\zeropoint\else
+ \vskip-\savedlastskip
+ \fi
+ \vskip\blankskip\relax
+ \fi
+ \fi
+ \else
+ \iffuzzyvskip
+ \removelastfuzzyvskip
+ \fuzzyvskip\blankskip\relax
+ \else
+ % new, test this on pascal
+ \ifdim\blankskip<\zeropoint
+ \relax\ifdim\savedlastskip=\zeropoint\else
+ \advance\blankskip-\savedlastskip
+ \vskip-\savedlastskip
+ \fi
+ \ifdim\blankskip>\zeropoint
+ \vskip\blankskip
+ \else
+ \vskip\zeropoint
+ \fi
+ \else
+ % also new
+ \ifdim\blankskip=\zeropoint
+ \ifblanknowhite
+ \nowhitespace
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \global\fuzzyvskipfalse
+ \presetindentation}
+
+%D For a long time we had:
+%D
+%D \starttyping
+%D \def\simpledoblank%
+%D {\doifelse{\currentwhitespace}{\v!geen}
+%D {\blank[\currentblank]}
+%D {\blank[\currentwhitespace]}}
+%D \stoptyping
+%D
+%D But Berend de Boer wanted more control, so now we have:
+
+\def\simpledoblank % ...
+ {\doifelse\currentwhitespace\v!none
+ {\blank[\currentblank]}
+ {\blank[\s!default]}}
+
+%D Another useful definition would be:
+%D
+%D \starttyping
+%D \defineblank
+%D [\s!default]
+%D [\v!groot]
+%D \stoptyping
+
+\def\dosetupblank#1% amount are an plain inheritance
+ {\bigskipamount#1\relax
+ \ifblankflexible \else
+ \bigskipamount1\bigskipamount
+ \fi
+ \medskipamount \bigskipamount \divide\medskipamount \plustwo
+ \smallskipamount\bigskipamount \divide\smallskipamount\plusfour}%
+
+\def\complexsetupblank[#1]% more \let's -> this also wil become installable
+ {\ifgridsnapping
+ \blankflexiblefalse
+ \else
+ \ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!flexible=>\blankflexibletrue,
+ \v!fixed=>\blankflexiblefalse]%
+ \fi
+ \ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!flexible=>\dosetupblank\appliedblankskip,
+ \v!fixed=>\dosetupblank\appliedblankskip,
+ \v!line=>\edef\appliedblankskip{\linedistance}%
+ \dosetupblank\appliedblankskip,
+ \v!halfline=>\scratchskip.5\linedistance
+ \edef\appliedblankskip{\the\scratchskip}%
+ \dosetupblank\appliedblankskip,
+ \v!big=>\ifgridsnapping
+ \edef\appliedblankskip{\linedistance}%
+ \dosetupblank\appliedblankskip
+ \fi
+ \let\currentblank\v!big,
+ \v!medium=>\let\currentblank\v!medium,
+ \v!small=>\let\currentblank\v!small,
+ \v!global=>\let\currentblank\v!global,
+ \v!normal=>\dosetupblank\appliedblankskip,
+ \v!standard=>\edef\appliedblankskip{\skipfactor\linedistance}%
+ \dosetupblank\appliedblankskip,
+ \s!default=>\dosetupblank\appliedblankskip,
+ \s!unknown=>\let\appliedblankskip\commalistelement
+ \dosetupblank\appliedblankskip]%
+ \simplesetupwhitespace}
+
+% \definecomplexorsimpleempty\setupblank
+%
+% speed gain: 60 sec -> 30 sec
+
+\definecomplexorsimple\setupblank
+
+\def\simplesetupblank % == snelle \setupblank[\s!default]
+ {\ifgridsnapping
+ \blankflexiblefalse
+ \fi
+ \dosetupblank\appliedblankskip
+ % \let\deblanko\v!big
+ \simplesetupwhitespace}
+
+\def\restorestandardblank% \v!standard
+ {\edef\appliedblankskip{\skipfactor\linedistance}%
+ \dosetupblank\appliedblankskip
+ }%\let\deblanko\v!big}
+
+\def\dodefineblank[#1][#2]%
+ {\def\docommand##1{\setvalue{\??bo##1}{#2}}%
+ \processcommalist[#1]\docommand}
+
+\def\defineblank
+ {\dodoubleargument\dodefineblank}
+
+\def\savecurrentblank
+ {\edef\restorecurrentblank
+ {\bigskipamount\the\bigskipamount
+ \medskipamount\the\medskipamount
+ \smallskipamount\the\smallskipamount
+ \noexpand\def\noexpand\currentblank{\currentblank}%
+ \ifblankflexible
+ \noexpand\blankflexibletrue
+ \else
+ \noexpand\blankflexiblefalse
+ \fi}}
+
+%D Now.
+
+\defineblank [\s!default] [\v!white]
+\defineblank [\v!height] [\strutheight]
+\defineblank [\v!depth] [\strutdepth]
+
+% old implementation
+%
+% \let\currentindentation=\empty
+%
+% \newdimen\ctxparindent
+%
+% \newif\ifindentfirstparagraph % \indentfirstparagraphtrue
+%
+% \def\presetindentation
+% {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}
+%
+% \definecomplexorsimple\setupindenting
+%
+% \def\complexsetupindenting[#1]%
+% {\processallactionsinset
+% [#1]
+% [ \v!first=>\indentfirstparagraphtrue,
+% \v!next=>\indentfirstparagraphfalse,
+% \s!default=>\simplesetupindenting,
+% \s!unknown=>\edef\currentindentation{\commalistelement}%
+% \simplesetupindenting]}
+%
+% \def\simplesetupindenting
+% {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}%
+% \parindent\ctxparindent\relax}
+%
+% \def\indenting % watch out: \dodo and no \do
+% {\dosingleargument\dodoindenting}
+%
+% \def\dodoindenting[#1]% oeps, we needed a commalist handler here!
+% {\edef\currentindenting{#1}%
+% \processcommacommand[#1]\dododoindenting}
+%
+% \def\dododoindenting#1%
+% {\executeifdefined{\??in:#1}\donothing}
+%
+% \let\currentindenting\empty
+%
+% \def\defineindentingmethod[#1]#2%
+% {\setvalue{\??in:#1}{#2}}
+%
+% \defineindentingmethod [\v!no] {\parindent\ctxparindent\noindent}
+% \defineindentingmethod [\v!not] {\parindent\ctxparindent\noindent}
+%
+% \defineindentingmethod [\v!first] {\indentfirstparagraphtrue}
+% \defineindentingmethod [\v!next] {\indentfirstparagraphfalse}
+%
+% \defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent !
+% \defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent !
+%
+% \defineindentingmethod [\v!never] {\parindent\zeropoint\relax} % no \indent !
+%
+% \def\noindenting{\indenting[\v!no,\v!next]} % was \nietinspringen
+% \def\doindenting{\indenting[\v!yes,\v!first]} % was \welinspringen
+%
+% \def\dochecknextindentation#1% internal one
+% {\checknextindentation[\getvalue{#1\c!indentnext}]}
+%
+% \def\checknextindentation[#1]%
+% {\processaction[#1][%\v!keep=>,
+% \v!yes=>\doindentation,
+% \v!no=>\noindentation,
+% \v!auto=>\autoindentation]}
+%
+% \def\doindentation% too simple
+% {\gdef\checkindentation{\global\indentationtrue}}
+%
+% \ifx\autoindentation\undefined
+% \let\autoindentation\relax
+% \fi
+%
+% \newif\ifindentation \indentationtrue % documenteren, naar buiten
+%
+% \let\checkindentation=\relax
+%
+% \def\donoindentation
+% {\ifdim\parindent=\zeropoint \else
+% \bgroup \setbox\scratchbox\lastbox \egroup
+% \fi}
+%
+% \def\noindentation % made global
+% {\ifinpagebody \else
+% \global\indentationfalse
+% \gdef\checkindentation
+% {\donoindentation
+% \gdef\checkindentation{\global\indentationtrue}}%
+% \fi}
+%
+% \def\nonoindentation % bv bij floats
+% {\ifinpagebody \else
+% \global\indentationtrue
+% \gdef\checkindentation{\global\indentationtrue}%
+% \fi}
+%
+% \def\indentation
+% {\ifvmode \ifdim\parindent=\zeropoint \else
+% % was : \hskip\parindent
+% % can be: \indent
+% % but we test:
+% \noindent\hskip\parindent
+% \fi \fi}
+
+\let\currentindentation\empty % amount/keyword
+% \let\normalindentation \empty % used for reinstating normal indentation
+\let\currentindenting \empty % method
+
+\newdimen\ctxparindent
+
+\newif\ifindentfirstparagraph % \indentfirstparagraphtrue
+
+\chardef\indentingtoggle\zerocount
+
+%D After a blank or comparable situation (left side floats) we
+%D need to check if the next paragraph has to be indented.
+
+\def\presetindentation
+ {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}
+
+%D This sets up the (normally) global indentation behavior as well
+%D as the amounts.
+
+\definecomplexorsimple\setupindenting
+
+% \def\complexsetupindenting[#1]%
+% {\edef\currentindenting{#1}%
+% \indentfirstparagraphtrue
+% \parindent\ctxparindent
+% \chardef\indentingtoggle\zerocount
+% \processcommalist[#1]\docomplexsetupindenting
+% \ifindentfirstparagraph\else\noindentation\fi % added
+% \toggleindentation}
+
+\indentfirstparagraphtrue
+\parindent\ctxparindent
+\chardef\indentingtoggle\zerocount
+
+% \newtoks\savedeverypar \savedeverypar\everypar
+% \def\restoreeverypar{\everypar\savedeverypar}
+
+% we need a better everypar model: for each option a switch, which we
+% set to false with \forgetall and can enable when needed (context 4);
+% that way we can control the order of execution of options
+
+\def\checkeverypar % currently a hack
+ {\ifzeropt\parindent\else
+ \doifsometokselse\everypar\donothing{\appendtoks\checkindentation\to\everypar}%
+ \fi}
+
+\def\complexsetupindenting[#1]%
+ {\edef\currentindenting{#1}%
+ \doifsomething\currentindenting % handy when a parameter is passed
+ {% not here: \indentfirstparagraphtrue
+ % not here: \parindent\ctxparindent
+ % not here: \chardef\indentingtoggle\zerocount
+ % we use commacommand in order to catch #1 being a command (expanded parameter)
+ \processcommacommand[\currentindenting]\docomplexsetupindentingA % catch small, medium, etc
+ \processcommacommand[\currentindenting]\docomplexsetupindentingB % catch rest
+ \checkeverypar % only when non-empty #1
+ \ifindentfirstparagraph\else\noindentation\fi % added
+ \toggleindentation}}
+
+\def\docomplexsetupindentingA#1%
+ {\edefconvertedargument\!!stringa{#1}%
+ \doifundefined{\??in:\!!stringa}%
+ {\edef\currentindentation{#1}%
+ \let\normalindentation\currentindentation
+ \simplesetupindenting}}
+
+\def\docomplexsetupindentingB#1%
+ {\edefconvertedargument\!!stringa{#1}% catch #1=\somedimen
+ \executeifdefined{\??in:\!!stringa}\donothing}
+
+\def\simplesetupindenting % empty case, a it strange, needed this way?
+ {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}}
+
+\def\indenting % kind of obsolete
+ {\dosingleargument\complexsetupindenting}
+
+% use \noindentation to suppress next indentation
+
+\def\defineindentingmethod[#1]#2%
+ {\setvalue{\??in:#1}{#2}}
+
+\defineindentingmethod [\v!no] {\parindent\zeropoint}% was: \ctxparindent\noindent}
+\defineindentingmethod [\v!not] {\parindent\zeropoint}% was: \ctxparindent\noindent}
+
+\defineindentingmethod [\v!first] {\indentfirstparagraphtrue}
+\defineindentingmethod [\v!next] {\indentfirstparagraphfalse}
+
+\defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent !
+\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent !
+
+\defineindentingmethod [\v!never] {\parindent\zeropoint\relax % no \indent !
+ \chardef\indentingtoggle\zerocount}
+
+\defineindentingmethod [\v!odd] {\chardef\indentingtoggle\plusone}
+\defineindentingmethod [\v!even] {\chardef\indentingtoggle\plustwo}
+
+\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else
+ \let\currentindentation\normalindentation
+ \simplesetupindenting
+ \fi}
+
+\defineindentingmethod [\v!reset] {\indentfirstparagraphtrue
+ \parindent\zeropoint
+ \chardef\indentingtoggle\zerocount}
+
+\def\noindenting{\indenting[\v!no, \v!next ]}
+\def\doindenting{\indenting[\v!yes,\v!first]}
+
+%D This one sets up the local indentation behaviour (i.e. either or not
+%D a next paragraph will be indented).
+
+\def\dochecknextindentation#1% internal one
+ {\checknextindentation[\getvalue{#1\c!indentnext}]}
+
+\def\checknextindentation[#1]%
+ {\processaction
+ [#1]
+ [%\v!keep=>,
+ \v!yes=>\doindentation,
+ \v!no=>\noindentation,
+ \v!auto=>\autoindentation]}
+
+%D Here come the handlers.
+
+\newif\ifindentation \indentationtrue % documenteren, naar buiten
+
+\let\checkindentation\relax
+
+\ifx\autoindentation\undefined \let\autoindentation\relax \fi % hook
+
+\def\doindentation
+ {\gdef\checkindentation{\global\indentationtrue}}
+
+\def\noindentation % made global
+ {\ifinpagebody \else
+ \global\indentationfalse
+ \gdef\checkindentation
+ {\donoindentation
+ \gdef\checkindentation{\global\indentationtrue}}%
+ \fi}
+
+\def\nonoindentation % bv bij floats
+ {\ifinpagebody \else
+ \global\indentationtrue
+ \gdef\checkindentation{\global\indentationtrue}%
+ \fi}
+
+\def\donoindentation
+ {\ifdim\parindent=\zeropoint \else
+ \bgroup \setbox\scratchbox\lastbox \egroup
+ \fi}
+
+\def\indentation
+ {\ifvmode \ifdim\parindent=\zeropoint \else
+ % was : \hskip\parindent
+ % can be: \indent
+ % but we test:
+ \noindent\hskip\parindent
+ \fi \fi}
+
+\def\toggleindentation
+ {\ifcase\indentingtoggle
+ % nothing
+ \or
+ \notoggleindentation
+ \or
+ \dotoggleindentation
+ \fi}
+
+\def\dokillindentation
+ {\gdef\checkindentation{\global\indentationfalse\donoindentation}}
+
+\def\dotoggleindentation
+ {\gdef\checkindentation{\global\indentationfalse\notoggleindentation\donoindentation}}
+
+\def\notoggleindentation
+ {\gdef\checkindentation{\global\indentationtrue\dotoggleindentation}}
+
+\appendtoks
+ \pushmacro\checkindentation
+ \pushmacro\ifindentation
+\to \everypushsomestate
+
+\appendtoks
+ \popmacro\ifindentation
+ \popmacro\checkindentation
+\to \everypopsomestate
+
+% we need to save the state if we want to adapt behaviour to empty lines
+%
+% \def\setlasthvmode
+% {\global\chardef\savedhvmode\ifhmode\plusone\else\ifvmode\plustwo\else\zerocount\fi\fi}
+%
+% \def\resetlasthvmode
+% {\global\chardef\savedhvmode\zerocount}
+%
+% \chardef\savedhvmode\zerocount
+
+% This is a user requested hack (using the auto-hook).
+
+\chardef\recheckindentationmode\zerocount
+
+\def\dontrechecknextindentation
+ {\global\chardef\recheckindentationmode\zerocount}
+
+\def\dorechecknextindentation
+ {\ifcase\recheckindentationmode
+ % nothing
+ \or
+ \dontrechecknextindentation
+ \expandafter\doautoindentation
+ \fi}
+
+\def\doautoindentation
+ {\doifnextcharelse\par\donothing\noindentation}
+
+\def\autoindentation
+ {\global\chardef\recheckindentationmode\plusone}
+
+%D An example of usage:
+%D
+%D \starttyping
+%D \setupindenting[small,yes]
+%D
+%D \setupitemize [indentnext=auto]
+%D \setuptyping [indentnext=auto]
+%D \setupformulas[indentnext=auto]
+%D
+%D \input tufte
+%D
+%D \startitemize
+%D \item itemize
+%D \stopitemize
+%D \input tufte
+%D
+%D \startitemize
+%D \item itemize
+%D \stopitemize
+%D
+%D \input tufte
+%D
+%D \startitemize
+%D \item itemize
+%D \stopitemize
+%D
+%D \page
+%D
+%D \input tufte
+%D
+%D \starttyping
+%D verbatim
+%D \stoptyping
+%D \input tufte
+%D
+%D \starttyping
+%D verbatim
+%D \stoptyping
+%D
+%D \input tufte
+%D
+%D \starttyping
+%D verbatim
+%D \stoptyping
+%D
+%D \page
+%D
+%D \input tufte
+%D
+%D \startformula
+%D a = b
+%D \stopformula
+%D \input tufte
+%D
+%D \startformula
+%D a = b
+%D \stopformula
+%D
+%D \input tufte
+%D
+%D \startformula
+%D a = b
+%D \stopformula
+
+
+%D \macros
+%D {frenchspacing,nonfrenchspacing}
+%D
+%D Smehow \type{\frenchspacing} can lead to hyphenation between
+%D dashes so we now have \type {\newfrenchspacing} (moved from
+%D \type {syst-chr}).
+
+%D Hm ... todo:
+
+\sfcode`\)=0
+\sfcode`\'=0
+\sfcode`\]=0
+
+\def\setfrenchspacing#1%
+ {\sfcode`\.#1 \sfcode`\,#1\relax
+ \sfcode`\?#1 \sfcode`\!#1\relax
+ \sfcode`\:#1 \sfcode`\;#1\relax}
+
+\def\frenchspacing
+ {\setfrenchspacing{1000}}
+
+\def\resetfrenchspacing
+ {\sfcode`\.3000 \sfcode`\,1250
+ \sfcode`\?3000 \sfcode`\!3000
+ \sfcode`\:2000 \sfcode`\;1500 }
+
+\def\frenchspacing {\setfrenchspacing{1000}}
+\def\newfrenchspacing{\setfrenchspacing{1050}}
+\def\nonfrenchspacing{\resetfrenchspacing}
+
+\def\definespacingmethod[#1]#2{\setvalue{\??sg\??sg#1}{#2}}
+
+\definespacingmethod[\v!packed]{\newfrenchspacing}
+\definespacingmethod[\v!broad ]{\nonfrenchspacing}
+
+\def\complexsetupspacing[#1]%
+ {\executeifdefined{\??sg\??sg#1}\relax
+ \updateraggedskips}
+
+\def\simplesetupspacing
+ {\updateraggedskips}
+
+\definecomplexorsimple\setupspacing
+
+% \dorecurse{100}{\recurselevel\spacefactor 800 \space} \par
+% \dorecurse{100}{\recurselevel\spacefactor1200 \space} \par
+% \dorecurse{100}{\recurselevel\spacefactor 800 \normalspaceprimitive} \par
+% \dorecurse{100}{\recurselevel\spacefactor1200 \normalspaceprimitive} \par
+
+% When we don't add the % here, we effectively get \<endlinechar> and
+% since we have by default \def\^^M{\ } we get into a loop.
+
+\let\normalspaceprimitive=\ % space-comment is really needed
+
+\unexpanded\def\ {\mathortext\normalspaceprimitive\space} % no \dontleavehmode\space (else no frenchspacing)
+
+\unexpanded\def\nonbreakablespace{\penalty\plustenthousand\space}
+
+\letcatcodecommand \ctxcatcodes `\~ \nonbreakablespace % overloaded later
+
+\def\space { }
+\def\removelastspace{\ifhmode\unskip\fi}
+\def\nospace {\removelastspace\ignorespaces}
+
+% in tables we need:
+%
+% \def\fixedspace {\hskip.5em\relax}
+%
+% but, since not all fonts have .5em digits:
+
+\unexpanded\def\fixedspace
+ {\setbox\scratchbox\normalhbox{\mathortext{0}{0}}%
+ \hskip\wd\scratchbox\relax}
+
+\def\fixedspaces
+ {\letcatcodecommand \ctxcatcodes `\~ \fixedspace}
+
+\def\removeunwantedspaces
+ {\ifhmode % we also need to unskip 0pt skips
+ \unskip\unskip\unskip\unskip\unskip
+ \unskip\unskip\unskip\unskip\unskip
+ \fi}
+
+\appendtoks\let~\space\to\simplifiedcommands
+
+% still not fixed in aleph / luatex
+%
+% \def\removeunwantedspaces
+% {\ifhmode \ifnum\lastnodetype=\@@gluenode
+% \unskip \@EAEAEA\removeunwantedspaces
+% \fi \fi}
+
+%D For old time sake, will disappear soon.
+
+\let\hardespatie\fixedspace
+\let\geenspatie \nospace
+
+% \startbuffer
+% \startlines \tt \fixedspaces
+% 0~1~~2~~~3~~~~4~~~~~5
+% 0~~~~~~~~~~~~~~~~~~~5
+% $0~1~~2~~~3~~~~4~~~~~5$
+% $0~~~~~~~~~~~~~~~~~~~5$
+% \stoplines
+%
+% \starttabulate[|~|]
+% \NC 0~1~~2~~~3~~~~4~~~~~5 \NC \NR \NC 0~~~~~~~~~~~~~~~~~~~5 \NC \NR
+% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \NR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \NR
+% \stoptabulate
+%
+% \starttable[||]
+% \NC 0~1~~2~~~3~~~~4~~~~~5 \NC \AR \NC 0~~~~~~~~~~~~~~~~~~~5 \NC \AR
+% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \AR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \AR
+% \stoptable
+% \stopbuffer
+%
+% \setupbodyfont[cmr] \getbuffer
+% \setupbodyfont[lbr] \getbuffer
+
+\def\packed
+ {\nointerlineskip}
+
+\def\godown[#1]%
+ {\relax
+ \ifhmode\endgraf\fi
+ \ifvmode\nointerlineskip\vskip#1\relax\fi}
+
+%D A couple of plain macros:
+
+\ifx\thinspace\undefined
-\ifx\pdfkeeplinedimen\undefined
+ \def\thinspace {\kern .16667em }
+ \def\negthinspace{\kern-.16667em }
+ \def\enspace {\kern .5em }
- \let\mksetupgridsnapping \relax
- \let\mkenablegridsnapping \relax
- \let\mkdisablegridsnapping\relax
+ \def\thinspace {\kern .16667\emwidth}
+ \def\negthinspace{\kern-.16667\emwidth}
+ \def\enspace {\kern .5\emwidth}
+\fi
+
+\ifx\quad\undefined
+
+ \def\enskip{\hskip.5em\relax}
+ \def\quad {\hskip 1em\relax}
+ \def\qquad {\hskip 2em\relax}
+
+ \def\enskip{\hskip.5\emwidth}
+ \def\quad {\hskip \emwidth}
+ \def\qquad {\hskip 2\emwidth}
+
+\fi
+
+\let\emspace\quad
+
+\ifx\smallskip\undefined
+
+ \def\smallskip{\vskip\smallskipamount}
+ \def\medskip {\vskip\medskipamount}
+ \def\bigskip {\vskip\bigskipamount}
+
+\fi
+
+\ifx\allowbreak\undefined
+
+ \def\break {\penalty\ifhmode-\plustenthousand\else\ejectpenalty\fi}
+ \def\nobreak {\penalty \plustenthousand}
+ \def\allowbreak{\penalty \zeropoint}
+ \def\filbreak {\par\vfil\penalty-200\vfilneg}
+ \def\goodbreak {\par\penalty-500 }
+
+\fi
+
+%D Made slightly more readable:
+
+\ifx\vglue\undefined
+
+ \def\vglue {\afterassignment\dovglue\scratchskip=}
+ \def\hglue {\afterassignment\dohglue\scratchskip=}
+ \def\topglue{\nointerlineskip\vglue-\topskip\vglue}
+
+ \def\dovglue
+ {\par
+ \scratchdimen\prevdepth
+ \hrule\!!height\zeropoint
+ \nobreak\vskip\scratchskip
+ \prevdepth\scratchdimen}
+
+ \def\dohglue
+ {\dontleavehmode % \leavevmode
+ \scratchcounter\spacefactor
+ \vrule\!!width\zeropoint
+ \nobreak\hskip\scratchskip
+ \spacefactor\scratchcounter}
+
+\fi
+
+\ifx\eject\undefined
+
+ \def\eject{\par\break}
+
+\fi
+
+\ifx\supereject\undefined
+
+ \def\supereject{\par\penalty\superpenalty}
+
+\fi
+
+\ifx\dosupereject\undefined
+
+ \def\dosupereject
+ {\ifnum\insertpenalties>\zerocount % something is being held over
+ \line{}
+ \kern-\topskip
+ \nobreak
+ \vfill\supereject
+ \fi}
+
+\fi
+
+%D We adapt plain's \type {\removelastskip} a bit:
+
+\ifx\removelastskip\undefined
+
+ \def\removelastskip
+ {\ifvmode \ifdim\lastskip=\zeropoint \else
+ \vskip-\lastskip
+ \fi \fi}
+
+\fi
+
+\ifx\smallbreak\undefined
+
+\def\smallbreak
+ {\par
+ \ifdim\lastskip<\smallskipamount
+ \removelastskip
+ \penalty-50
+ \smallskip
+ \fi}
+
+\def\medbreak
+ {\par
+ \ifdim\lastskip<\medskipamount
+ \removelastskip
+ \penalty-100
+ \medskip
+ \fi}
+
+\def\bigbreak
+ {\par
+ \ifdim\lastskip<\bigskipamount
+ \removelastskip
+ \penalty-200
+ \bigskip
+ \fi}
+
+\fi
+
+\newskip\ctxparskip \ctxparskip\zeropoint
+
+\newconditional \flexiblewhitespace \settrue\flexiblewhitespace
+
+\def\blankokleinmaat {\smallskipamount}
+\def\blankomiddelmaat {\medskipamount}
+\def\blankogrootmaat {\bigskipamount}
+\def\currentwhitespace {\zeropoint}
+
+\definecomplexorsimple\setupwhitespace
+
+% \def\simplesetupwhitespace
+% {\doifnot\currentwhitespace\v!none\dosetupwhitespace}
+%
+% \def\complexsetupwhitespace[#1]%
+% {\doifelsenothing{#1}
+% {\simplesetupwhitespace}
+% {\edef\currentwhitespace{#1}%
+% \dosetupwhitespace}}
+%
+% \def\dosetupwhitespace
+% {\processcommacommand[\currentwhitespace]\dowhitespacemethod
+% \dodosetupwhitespace}
+
+\def\simplesetupwhitespace
+ {\doifnot\currentwhitespace\v!none\dosetupwhitespace}
+
+\def\complexsetupwhitespace[#1]%
+ {\edef\nextcurrentwhitespace{#1}%
+ \ifx\nextcurrentwhitespace\empty
+ \simplesetupwhitespace
+ \else
+ \let\currentwhitespace\nextcurrentwhitespace
+ \dosetupwhitespace
+ \fi}
+
+\def\dosetupwhitespace % quick test for no list
+ {\ifcsname\??ws\??ws\currentwhitespace\endcsname
+ \csname\??ws\??ws\currentwhitespace\endcsname
+ \else
+ \expandafter\processcommalist\expandafter[\currentwhitespace]\dowhitespacemethod % can be raw
+ \fi\relax
+ \ifgridsnapping
+ \setfalse\flexiblewhitespace
+ \ifdim\ctxparskip>\zeropoint
+ \ctxparskip
+ \ifcase\baselinegridmode
+ \baselineskip % normal ! ! ! ! !!
+ \or
+ \ifdim\scratchdimen=\baselineskip % maybe range
+ \baselineskip % normal ! ! ! ! !!
+ \else
+ \numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
+ \fi
+ \else
+ \baselineskip % normal ! ! ! ! !!
+ \fi
+ \fi
+ \else
+ \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
+ \fi
+ \parskip\ctxparskip}
+
+\chardef\baselinegridmode=0 % option in layout / 1=permit_half_lines
+
+\def\dodosetupwhitespace
+ {\ifgridsnapping
+ \setfalse\flexiblewhitespace
+ \ctxparskip1\ctxparskip
+ \ifdim\ctxparskip>\zeropoint
+ \ifcase\baselinegridmode
+ \ctxparskip\baselineskip % normal ! ! ! ! !!
+ \or
+ \ifdim\scratchdimen=\baselineskip % maybe range
+ \ctxparskip\baselineskip % normal ! ! ! ! !!
+ \else
+ \ctxparskip\numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
+ \fi
+ \else
+ \ctxparskip\baselineskip % normal ! ! ! ! !!
+ \fi
+ \fi
+ \else
+ \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
+ \fi
+ \parskip\ctxparskip}
+
+\definesystemvariable {ws} % whitespace
+
+\def\definewhitespacemethod[#1]#2{\setvalue{\??ws\??ws#1}{#2}}
+
+\definewhitespacemethod [\v!fix] {}
+\definewhitespacemethod [\v!fixed] {\setfalse\flexiblewhitespace}
+\definewhitespacemethod [\v!flexible] {\settrue\flexiblewhitespace}
+\definewhitespacemethod [\v!line] {\ctxparskip \baselineskip}
+\definewhitespacemethod [\v!halfline] {\ctxparskip.5\baselineskip}
+\definewhitespacemethod [\v!none] {\ctxparskip \zeropoint}
+\definewhitespacemethod [\v!big] {\ctxparskip \bigskipamount}
+\definewhitespacemethod [\v!medium] {\ctxparskip \medskipamount}
+\definewhitespacemethod [\v!small] {\ctxparskip \smallskipamount}
+
+\definewhitespacemethod [\s!default] {\simplesetupwhitespace} % {\stelwitruimteopnieuwin}
+
+% \def\dowhitespacemethod#1%
+% {\executeifdefined{\??ws\??ws#1}{\ctxparskip#1}\relax}
+
+\def\dowhitespacemethod#1%
+ {\ifcsname\??ws\??ws#1\endcsname\csname\??ws\??ws#1\endcsname\else\ctxparskip#1\fi\relax}
+
+\def\nowhitespace
+ {\ifdim\parskip>\zeropoint\relax
+ \ifdim\lastskip=-\parskip
+ \else
+ \vskip-\parskip
+ \fi
+ \fi}
+
+\def\nowhitespaceunlessskip
+ {\ifdim\lastskip>\zeropoint \else
+ \nowhitespace
+ \fi}
+
+\def\redowhitespace
+ {\ifdim\lastskip>-\parskip \else
+ \vskip\parskip
+ \fi}
+
+\def\savecurrentwhitespace
+ {\edef\restorecurrentwhitespace
+ {\ctxparskip\the\ctxparskip
+ \parskip\the\parskip
+ \noexpand\def\noexpand\currentwhitespace{\currentwhitespace}%
+ \ifconditional\flexiblewhitespace
+ \noexpand\settrue\flexiblewhitespace
+ \else
+ \noexpand\setfalse\flexiblewhitespace
+ \fi}}
+
+% deze variant is nodig binnen \startopelkaar
+% steeds testen:
+%
+% \hoofdstuk{..}
+% \plaatslijst[..]
+% \hoofdstuk{..}
+% \input tufte
+%
+% met/zonder witruimte
+
+\def\whitespace
+ {\par
+ \ifdim\parskip>\zeropoint\relax
+ %\ifdim\lastskip>\parskip \else
+ % \removelastskip interferes with blanko blokkeer en klein
+ \vskip\parskip
+ %\fi
+ \fi}
+
+\def\nonoblanko[#1]%
+ {\par}
+
+\def\noblanko
+ {\dosingleempty\nonoblanko}
+
+% De onderstaande macro handelt ook de situatie dat er geen
+% tekst tussen \start ... \stop is geplaatst. Daartoe wordt de
+% laatste skip over de lege tekst heen gehaald. Dit komt goed
+% van pas bij het plaatsen van (mogelijk lege) lijsten.
+
+\newif\ifopelkaar
+
+\newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt}
+\def\lastdoneparskip {0pt}
+
+\def\startpacked
+ {\dosingleempty\dostartpacked}
+
+\def\dostartpacked[#1]% nesting afvangen
+ {\par
+ \ifvmode
+ \edef\lastdoneparskip {\the\lastskip}%
+ \edef\lastdoneprevdepth{\the\prevdepth}% zeer recent toegevoegd
+ \ifdim\prevdepth=-\thousandpoint % toegevoegd omdat binnen
+ \else % een vbox een extra skip
+ \whitespace % ongewenst is; dit kan
+ \baselinecorrection %% zie in \placeregister[n=1]
+ \vskip\noparskipsignal % waarschijnlijk ook in
+ \fi % blanko blokkeer
+ \bgroup
+ \doifelse{#1}\v!blank
+ \opelkaarfalse
+ \opelkaartrue
+ \blank[\v!disable] % dit is nog niet ok, gaat fout
+ \setupwhitespace[\v!none] % bovenin vtop (dwz, baseline)
+ \fi}
+
+\def\stoppacked
+ {\par
+ \ifvmode
+ \egroup
+ \ifdim\lastskip=\noparskipsignal\relax
+ \removelastskip
+ \nowhitespace
+ \vskip-\lastdoneparskip
+ \vskip+\lastdoneparskip
+ \prevdepth-\lastdoneprevdepth % zeer recent toegevoegd
+ \fi
+ \fi}
+
+\def\startunpacked
+ {\blank
+ \leavevmode
+ \bgroup}
+
+\def\stopunpacked
+ {\egroup
+ \blank}
+
+% De onderstaande macro's moeten nog eens nader worden uitgewerkt.
+% Ze spelen een rol bij de spatiering rond omkaderde teksten
+% en/of boxen zonder diepte.
+
+\def\toonregelcorrectie{\showbaselinecorrection}
+\def\regelcorrectie {\baselinecorrection}
+
+% \prevdepth crosses pageboundaries!
+%
+% todo: a version that works ok inside a box
+
+\let\doaroundlinecorrection\relax
+
+\def\startlinecorrection
+ {\dodoubleempty\dostartlinecorrection}
+
+\def\dostartlinecorrection[#1][#2]% #2 gobbles spaces
+ {\bgroup
+ \processaction
+ [#1]
+ [ \v!blank=>\let\doaroundlinecorrection\blank,
+ \s!default=>\let\doaroundlinecorrection\relax,
+ \s!unknown=>{\def\doaroundlinecorrection{\blank[#1]}}]%
+ \doaroundlinecorrection
+ \startbaselinecorrection
+ \offbaselinecorrection
+ \ignorespaces}
+
+\def\stoplinecorrection
+ {\stopbaselinecorrection
+ \doaroundlinecorrection
+ \egroup}
+
+\def\correctwhitespace
+ {\dowithnextbox
+ {\startbaselinecorrection
+ \flushnextbox
+ \stopbaselinecorrection}%
+ \vbox}
+
+\def\verticalstrut {\normalvbox{\hsize\zeropoint\forgetall\strut}}
+\def\horizontalstrut{\normalhbox {\strut}}
+
+% Hieronder volgen enkele instellingen en macro's ten behoeve
+% van de interlinie en \strut. De waarden 2.8, 0.07, 0.72 en
+% 0.28 zijn ooit eens ontleend aan INRS-TEX en moeten wellicht
+% nog eens instelbaar worden.
+%
+% \lineheight : de hoogte van een regel
+% \spacing{getal} : instellen interlinie
+% \normalbaselines : instellen regelafstend
+%
+% \setstrut : instellen \strut
+% \setnostrut : resetten \strut, \endstrut, \begstrut
+%
+% \setteststrut : instellen zichtbare struts
+% \resetteststrut : instellen onzichtbare struts
+%
+% \setfontparameters : instellen na fontset
+%
+% De hoogte van een regel (\lineheight) is gelijk aan de
+% som van de hoogte (\ht) en diepte (\dp) van \strutbox.
+%
+% \strut : denkbeeldig blokje met hoogte en diepte
+%
+% Een \hbox kan als deze aan het begin van een regel staat
+% een breedte \hsize krijgen. Dit is soms te voorkomen met het
+% commando \leavevmode. Binnen een \vbox geeft dit echter
+% niet altijd het gewenste resultaat, vandaar het commando
+%
+% \leaveoutervmode
+
+% Pas op: niet zomaar \topskip en \baselineskip aanpassen
+% en zeker niet \widowpenalty. Dit kan ernstige gevolgen
+% hebben voor kolommen.
+%
+% Enige glue kan op zich geen kwaad, echter als blanko=vast,
+% dan moet ook de rek 0 zijn. Binnen kolommen is rek ook
+% niet bepaald mooi. Een hele kleine waarde (0.025) voldoet,
+% omdat een positieve glue eindeloos rekbaar is.
+
+\newdimen\strutdimen
+\newdimen\lineheight
+\newdimen\openlineheight
+\newdimen\openstrutheight
+\newdimen\openstrutdepth
+\newdimen\topskipgap
+\newdimen\struttotal
+
+\def\strutheightfactor {.72}
+\def\strutdepthfactor {.28}
+
+\def\baselinefactor {2.8}
+\def\baselinegluefactor {0}
+
+\def\minimumstrutheight {0pt}
+\def\minimumstrutdepth {0pt}
+
+\def\normallineheight {\baselinefactor ex}
+\def\minimumlinedistance {\lineskip}
+
+\def\strutheight {0pt}
+\def\strutdepth {0pt}
+\def\strutwidth {0pt}
+
+\def\spacingfactor {1}
+
+\def\topskipfactor {1.0}
+\def\maxdepthfactor {0.5}
+
+\def\systemtopskipfactor {\topskipfactor}
+\def\systemmaxdepthfactor {\maxdepthfactor}
+
+% De onderstaande definitie wordt in de font-module overruled
+
+\ifdefined\globalbodyfontsize\else
+ \newdimen\globalbodyfontsize
+ \globalbodyfontsize=12pt
+\fi
+
+\ifx\normalizedbodyfontsize\undefined
+ \def\normalizedbodyfontsize{12pt}
+\fi
+
+% door een \dimen. Dit is geen probleem omdat (1) de default
+% korpsgrootte 12pt is en (2) de fonts nog niet geladen zijn
+% en de instellingen bij het laden nogmaals plaatsvinden.
+
+% \def\topskipcorrection
+% {\ifdim\topskip>\openstrutheight
+% % == \vskip\topskipgap
+% \vskip\topskip
+% \vskip-\openstrutheight
+% \fi
+% \verticalstrut
+% \vskip-\struttotal}
+
+\def\topskipcorrection
+ {\simpletopskipcorrection
+ \vskip-\struttotal
+ \verticalstrut}
+
+\def\simpletopskipcorrection
+ {\ifdim\topskip>\openstrutheight
+ % == \vskip\topskipgap
+ \vskip\topskip
+ \vskip-\openstrutheight
+ \fi}
+
+% \def\settopskip % the extra test is needed for the lbr family
+% {\topskip\systemtopskipfactor\globalbodyfontsize
+% \ifgridsnapping \else
+% \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
+% \fi
+% \relax % the skip
+% \topskipgap\topskip
+% \advance\topskipgap -\openstrutheight\relax
+% \ifdim\topskip<\strutheightfactor\openlineheight
+% \topskip\strutheightfactor\openlineheight\relax
+% \fi}
+
+\def\settopskip % the extra test is needed for the lbr family
+ {\topskip\systemtopskipfactor\globalbodyfontsize
+ \ifgridsnapping \else
+ \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
+ \fi
+ \relax % the skip
+ \topskipgap\topskip
+ \advance\topskipgap -\openstrutheight\relax
+\ifdim\minimumstrutheight>\zeropoint
+ \ifdim\topskip<\minimumstrutheight
+ \topskip\minimumstrutheight\relax
+ \fi
\else
+ \ifdim\topskip<\strutheightfactor\openlineheight
+ \topskip\strutheightfactor\openlineheight\relax
+ \fi
+\fi}
+
+\def\setmaxdepth
+ {\maxdepth\systemmaxdepthfactor\globalbodyfontsize}
+
+\def\normalbaselines
+ {\baselineskip \normalbaselineskip
+ \lineskip \normallineskip
+ \lineskiplimit\normallineskiplimit}
+
+% \def\setnormalbaselines
+% {\ifdim\normallineheight>\zeropoint
+% \lineheight\normallineheight
+% \fi
+% \openlineheight\spacingfactor\lineheight
+% \openstrutheight\strutheightfactor\openlineheight
+% \openstrutdepth \strutdepthfactor \openlineheight
+% \normalbaselineskip\openlineheight
+% \!!plus\baselinegluefactor\openlineheight
+% \!!minus\baselinegluefactor\openlineheight
+% \normallineskip\minimumlinedistance\relax % \onepoint\relax
+% \normallineskiplimit\zeropoint\relax
+% \normalbaselines}
+
+\def\setnormalbaselines
+ {\ifdim\normallineheight>\zeropoint
+ \lineheight\normallineheight
+ \fi
+ \openlineheight\spacingfactor\lineheight
+ \openstrutheight \ifdim\minimumstrutheight>\zeropoint
+ \minimumstrutheight % new
+ \else
+ \strutheightfactor\openlineheight
+ \fi
+ \openstrutdepth \ifdim\minimumstrutdepth>\zeropoint
+ \minimumstrutdepth % new
+ \else
+ \strutdepthfactor \openlineheight
+ \fi
+ \ifdim\dimexpr\minimumstrutdepth+\minimumstrutheight\relax>\zeropoint
+ \openlineheight\dimexpr\openstrutheight+\openstrutdepth\relax % new
+ \fi
+ \normalbaselineskip\openlineheight
+ \ifgridsnapping\else
+ \!!plus \baselinegluefactor\openlineheight
+ \!!minus\baselinegluefactor\openlineheight
+ \fi
+ \normallineskip\minimumlinedistance\relax % \onepoint\relax
+ \normallineskiplimit\zeropoint\relax
+ \normalbaselines}
+
+% \def\setspacingfactor#1\to#2\by#3\\%
+% {\strutdimen#2\points
+% \strutdimen#3\strutdimen
+% \edef#1{\withoutpt\the\strutdimen}}
+%
+% \def\spacing#1%
+% {\ifgridsnapping
+% %\doifnot{#1}{1}{\showmessage\m!layouts{11}{#1}}%
+% \ifdim#1\points=\onepoint\else\showmessage\m!layouts{11}{#1}\fi
+% \edef\spacingfactor{1}%
+% \else
+% \edef\spacingfactor{#1}%
+% \fi
+% \setspacingfactor\systemtopskipfactor \to\topskipfactor \by#1\\% why no \spacingfactor ?
+% \setspacingfactor\systemmaxdepthfactor\to\maxdepthfactor\by#1\\% why no \spacingfactor ?
+% \setnormalbaselines
+% \setstrut}
+%
+% \def\setspacingfactor#1#2#3%
+% {\edef#1{\withoutpt\the\dimexpr#2\points*#3\relax}}
+
+\def\spacing#1%
+ {\ifgridsnapping
+ \ifdim#1\points=\onepoint\else\showmessage\m!layouts{11}{#1}\fi
+ \edef\spacingfactor{1}%
+ \else
+ \edef\spacingfactor{#1}%
+ \fi
+ %\setspacingfactor\systemtopskipfactor \topskipfactor {#1}% why no \spacingfactor ?
+ %\setspacingfactor\systemmaxdepthfactor\maxdepthfactor{#1}% why no \spacingfactor ?
+ \edef\systemtopskipfactor {\withoutpt\the\dimexpr#1\dimexpr\topskipfactor \points}%
+ \edef\systemmaxdepthfactor{\withoutpt\the\dimexpr#1\dimexpr\maxdepthfactor\points}%
+ \setnormalbaselines
+ \setstrut}
+
+%D Sometimes one needs to freeze the interlinespacing
+%D
+%D \starttyping
+%D \rm \saveinterlinespace .... {\ss \restoreinterlinespace .... \endgraf}
+%D \stoptyping
+
+\let\restoreinterlinespace\relax
+
+\def\saveinterlinespace
+ {\edef\restoreinterlinespace
+ {\lineheight \the\lineheight
+ \openstrutheight \the\openstrutheight
+ \openstrutdepth \the\openstrutdepth
+ \openlineheight \the\openlineheight
+ \normalbaselineskip \the\normalbaselineskip
+ \normallineskip \the\normallineskip
+ \normallineskiplimit\the\normallineskiplimit
+ \noexpand\def\noexpand\normallineheight{\the\dimexpr\normallineheight}%
+ \noexpand\normalbaselines}}
+
+% plain definition:
+%
+% \def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
+%
+% could be:
+%
+% \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
+
+\ifx\strutbox\undefined
+
+ \newbox\strutbox
+
+ \setbox\strutbox=\normalhbox{\vrule height8.5pt depth3.5pt width\zeropoint}
+
+ %\def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
+ \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
+
+\fi
+
+\let\normalstrut\strut
+
+% The double \hbox construction enables us to \backtrack
+% boxes.
+
+% \def\setstrutdimen#1#2#3% % een strut is n.m maal ex
+% {\strutdimen\normallineheight % wat niet per se \lineheight
+% \strutdimen#2\strutdimen % is omdat een strut lokaal
+% \strutdimen#3\strutdimen % kan afwijken van de globale
+% \edef#1{\the\strutdimen}} % macro % strut
+
+% \def\setstrutdimen#1#2#3% % een strut is n.m maal ex
+% {\strutdimen\normallineheight % wat niet per se \lineheight
+% \strutdimen#2\strutdimen % is omdat een strut lokaal
+% \strutdimen#3\strutdimen % kan afwijken van de globale
+% \edef#1{\the\strutdimen}} % macro % strut
+
+% \def\setstrut
+% {\setstrutdimen\strutheight\strutheightfactor\spacingfactor
+% \setstrutdimen\strutdepth \strutdepthfactor \spacingfactor
+% \let\strut=\normalstrut
+% \setbox\strutbox=\normalhbox
+% {\normalhbox
+% {\vrule
+% \!!width \strutwidth
+% \!!height \strutheight
+% \!!depth \strutdepth
+% \normalkern-\strutwidth}}}
+
+% \def\setstrut
+% {\setstrutdimen\strutheight\strutheightfactor\spacingfactor
+% \setstrutdimen\strutdepth \strutdepthfactor \spacingfactor
+% \dosetstrut}
+
+% \def\setstrut
+% {\strutdimen\normallineheight
+% \strutdimen\strutheightfactor\strutdimen
+% \strutdimen\spacingfactor\strutdimen
+% \edef\strutheight{\the\strutdimen}%
+% \strutdimen\normallineheight
+% \ifgridsnapping
+% \advance\strutdimen-\strutheight
+% \else
+% \strutdimen\strutdepthfactor\strutdimen
+% \strutdimen\spacingfactor\strutdimen
+% \fi
+% \edef\strutdepth{\the\strutdimen}%
+% \dosetstrut}
+
+% interesting, strutdepth is 4.05064pt vs 4.05066pt depending on grid
+% nasty rounding problem
+
+% \def\setstrut
+% {% height
+% \strutdimen\normallineheight
+% \ifdim\minimumstrutheight>\zeropoint
+% \strutdimen\minimumstrutheight
+% \else
+% \strutdimen\strutheightfactor\strutdimen
+% \fi
+% \strutdimen\spacingfactor\strutdimen
+% \edef\strutheight{\the\strutdimen}%
+% % depth
+% \strutdimen\normallineheight
+% \ifgridsnapping
+% \ifdim\minimumstrutdepth>\zeropoint
+% \strutdimen\minimumstrutdepth
+% \else
+% \advance\strutdimen-\strutheight
+% \fi
+% \else
+% \ifdim\minimumstrutdepth>\zeropoint
+% \strutdimen\minimumstrutdepth
+% \else
+% \strutdimen\strutdepthfactor\strutdimen
+% \fi
+% \strutdimen\spacingfactor\strutdimen
+% \fi
+% \edef\strutdepth{\the\strutdimen}%
+% % finish
+% \dosetstrut}
+
+% \def\setstrut
+% {% height
+% \ifdim\minimumstrutheight>\zeropoint
+% \edef\strutheight{\the\dimexpr\spacingfactor\dimexpr\minimumstrutheight}%
+% \else
+% \edef\strutheight{\the\dimexpr\spacingfactor\dimexpr\strutheightfactor\dimexpr\normallineheight}%
+% \fi
+% % depth
+% \ifgridsnapping
+% \ifdim\minimumstrutdepth>\zeropoint
+% \edef\strutdepth{\the\dimexpr\minimumstrutdepth}%
+% \else
+% \edef\strutdepth{\the\dimexpr\normallineheight-\strutheight}%
+% \fi
+% \else
+% \ifdim\minimumstrutdepth>\zeropoint
+% \edef\strutdepth{\the\dimexpr\spacingfactor\dimexpr\minimumstrutdepth}%
+% \else
+% \edef\strutdepth{\the\dimexpr\spacingfactor\dimexpr\strutdepthfactor\dimexpr\normallineheight}%
+% \fi
+% \fi
+% % finish
+% \dosetstrut}
+
+\unexpanded\def\setstrut
+ {% height
+ \edef\strutheight
+ {\the\dimexpr\spacingfactor\dimexpr
+ \ifdim\minimumstrutheight>\zeropoint
+ \minimumstrutheight
+ \else
+ \strutheightfactor\dimexpr\normallineheight
+ \fi}%
+ % depth
+ \edef\strutdepth
+ {\the\dimexpr
+ \ifgridsnapping
+ \ifdim\minimumstrutdepth>\zeropoint
+ \minimumstrutdepth
+ \else
+ \normallineheight-\strutheight
+ \fi
+ \else
+ \spacingfactor\dimexpr
+ \ifdim\minimumstrutdepth>\zeropoint
+ \minimumstrutdepth
+ \else
+ \strutdepthfactor\dimexpr\normallineheight
+ \fi
+ \fi}%
+ % finish
+ \dosetstrut}
+
+\unexpanded\def\setcharstrut#1%
+ {\setbox\strutbox\normalhbox{#1}%
+ \edef\strutheight{\the\strutht}%
+ \edef\strutdepth {\the\strutdp}%
+ \dosetstrut}
+
+% \def\setfontstrut
+% {\setcharstrut{(}}
+%
+% better, since some fonts have small (but descending Q etc)
+
+\unexpanded\def\setfontstrut
+ {\setcharstrut{(gplQT}}
+
+\unexpanded\def\setcapstrut% could be M, but Q has descender
+ {\setcharstrut{Q}}
+
+%D Handy for math (used in mathml):
+
+\def\charhtstrut
+ {\begingroup
+ \setcharstrut{GJY}%
+ \vrule\!!width\zeropoint\!!depth\zeropoint\!!height\strutht
+ \endgroup}
+
+\def\chardpstrut
+ {\begingroup
+ \setcharstrut{gjy}%
+ \vrule\!!width\zeropoint\!!depth\strutdp\!!height\zeropoint
+ \endgroup}
+
+%D Centered looks nicer:
+
+% \def\dosetstrut
+% {\let\strut\normalstrut
+% \setbox\strutbox\normalhbox
+% {\normalhbox to \zeropoint
+% {% \hss % new, will be option
+% \vrule
+% \!!width \strutwidth
+% \!!height\strutheight
+% \!!depth \strutdepth
+% \hss}}%
+% \struttotal\dimexpr\strutht+\strutdp\relax}
+%
+% because of all the callbacks in mkiv, we avoid unnecessary boxes ...
+% maybe use an attribute so that we can tag boxes that don't need a
+% treatment; tests with using an attribute so far have shown that
+% it's slower because testing the attribute takes time too
+
+\def\dosetstrut
+ {\let\strut\normalstrut
+ \ifdim\strutwidth=\zeropoint
+ \setbox\strutbox\normalhbox
+ {\vrule
+ \!!width \zeropoint
+ \!!height\strutheight
+ \!!depth \strutdepth}%
+ \else
+ \setbox\strutbox\normalhbox
+ {\normalhbox to \zeropoint
+ {% \hss % new, will be option
+ \vrule
+ \!!width \strutwidth
+ \!!height\strutheight
+ \!!depth \strutdepth
+ \hss}}%
+ \fi
+ \struttotal\dimexpr\strutht+\strutdp\relax}
+
+%D The dimen \type {\struttotal} holds the exact size of the
+%D strut; occasionally a one scaled point difference can show
+%D up with the lineheight.
+
+%D Sometimes a capstrut comes in handy
+%D
+%D \starttabulate[|Tl|l|l|]
+%D \NC yes \NC normal strut \NC {\showstruts\setupstrut[yes]\strut} \NC \NR
+%D \NC no \NC no strut \NC {\showstruts\setupstrut[no]\strut} \NC \NR
+%D \NC kap \NC a capital strut (i.e. Q) \NC {\showstruts\setupstrut[cap]\strut} \NC \NR
+%D \NC A B \unknown \NC a character strut (e.g. A) \NC {\showstruts\setupstrut[A]\strut} \NC \NR
+%D \NC \NC a normal strut \NC {\showstruts\setupstrut\strut} \NC \NR
+%D \stoptabulate
+
+\def\setupstrut
+ {\dosingleempty\dosetupstrut}
+
+\def\dosetupstrut[#1]% yet undocumented, todo: fontstrut
+ {\processaction
+ [#1]
+ [ \v!yes=>\setstrut,
+ \v!auto=>\setautostrut,
+ \v!no=>\setnostrut,
+ \v!cap=>\setcapstrut,
+ \v!fit=>\setfontstrut,
+ \v!line=>\setstrut,
+ \s!default=>\setstrut,
+ \s!unknown=>\setcharstrut\commalistelement]}
+
+\def\setteststrut
+ {\def\strutwidth{.8pt}%
+ \setstrut}
+
+\def\autostrutfactor{1.1}
+
+\def\setautostrut
+ {\begingroup
+ \setbox\scratchbox\copy\strutbox
+ \setstrut
+ \ifdim\ht\strutbox>\autostrutfactor\ht\scratchbox
+ \endgroup \setstrut
+ \else\ifdim\dp\strutbox>\autostrutfactor\dp\scratchbox
+ \endgroup \setstrut
+ \else
+ \endgroup
+ \fi\fi}
+
+% simple version
+%
+% \def\begstrut
+% {\relax\ifcase\strutht\else
+% \strut
+% \normalpenalty\plustenthousand
+% \normalhskip\zeropoint
+% \ignorespaces
+% \fi}
+%
+% \def\endstrut
+% {\relax\ifhmode\ifcase\strutht\else
+% \removeunwantedspaces
+% \normalpenalty\plustenthousand
+% \normalhskip\zeropoint
+% \strut
+% \fi\fi}
+
+% when enabled, sigstruts will remove themselves if nothing
+% goes inbetween
+
+\newsignal\strutsignal \setfalse\sigstruts
+
+\def\begstrut
+ {\relax\ifcase\strutht\else
+ \ifconditional\sigstruts
+ \noindent\horizontalstrut
+ \normalpenalty\plustenthousand
+ \normalhskip-\strutsignal
+ \normalhskip\strutsignal
+ \else
+ \strut
+ \normalpenalty\plustenthousand
+ \normalhskip\zeropoint
+ \fi
+ \expandafter \ignorespaces
+ \fi}
+
+\def\endstrut
+ {\relax\ifhmode\ifcase\strutht\else
+ \ifconditional\sigstruts
+ \ifdim\lastskip=\strutsignal
+ \unskip\unskip\unpenalty\setbox\scratchbox\lastbox
+ \else
+ \normalpenalty\plustenthousand
+ \normalhskip\zeropoint
+ \strut
+ \fi
+ \else
+ \removeunwantedspaces
+ \normalpenalty\plustenthousand
+ \normalhskip\zeropoint
+ \strut
+ \fi
+ \fi\fi}
+
+\newbox\nostrutbox \setbox\nostrutbox\normalhbox{} % {\normalhbox{}}
+
+\def\setnostrut
+ {\setbox\strutbox\copy\nostrutbox
+ \let\strut\empty
+ \let\endstrut\empty
+ \let\begstrut\empty
+ \let\crlfplaceholder\empty}
+
+% unsave:
+%
+% \def\pseudostrut
+% {\bgroup
+% \setnostrut
+% \normalstrut
+% \egroup}
+%
+% try:
+%
+% \startchemie
+% \chemie[ONE,Z0,SB15,MOV1,SB15,Z0][C,C]
+% \stopchemie
+%
+% so:
+
+\def\pseudostrut
+ {\noindent} % better: \dontleavehmode
+
+\let\pseudobegstrut\pseudostrut
+
+\let\pseudoendstrut\removeunwantedspaces
+
+\def\resetteststrut
+ {\let\strutwidth\zeropoint
+ \setstrut}
+
+\ifx\setfontparameters\undefined
+ % problems ! ! ! !
+ \def\setfontparameters{\the\everybodyfont}
+\fi
+
+%D Handy:
+
+\def\baselinedistance{\the\lineheight}
+
+%D We need \type{\normaloffinterlineskip} because the new
+%D definition contains an assignment, and |<|don't ask me
+%D why|>| this assignment gives troubles in for instance the
+%D visual debugger.
+
+%D The plain ones:
+
+\def\offinterlineskip
+ {\baselineskip-\thousandpoint
+ \lineskip\zeropoint
+ \lineskiplimit\maxdimen}
+
+\def\nointerlineskip
+ {\prevdepth-\thousandpoint}
+
+\let\normaloffinterlineskip=\offinterlineskip % knuth's original
+
+%D My own one:
+
+\def\offinterlineskip
+ {\ifdim\baselineskip>\zeropoint
+ \edef\oninterlineskip
+ {\baselineskip\the\baselineskip
+ \lineskip\the\lineskip
+ \lineskiplimit\the\lineskiplimit
+ \let\noexpand\offinterlineskip\noexpand\normaloffinterlineskip}%
+ \else
+ \let\oninterlineskip\setnormalbaselines
+ \fi
+ \normaloffinterlineskip}
+
+\let\oninterlineskip=\relax
+
+\def\leaveoutervmode
+ {\ifvmode\ifinner\else
+ \leavevmode
+ \fi\fi}
+
+% We stellen enkele penalties anders in dan Plain TEX:
+
+% oud
+%
+% \widowpenalty=\defaultwidowpenalty\relax
+% \clubpenalty =\defaultclubpenalty \relax
+
+\def\resetpenalties#1%
+ {\ifx#1\undefined\else
+ #1\minusone
+ \fi}
- \def\mksetupgridsnapping
- {\pdfeachlineheight \openstrutheight
- \pdfeachlinedepth \openstrutdepth
- \pdffirstlineheight \pdfeachlineheight
- \pdflastlinedepth \pdfeachlinedepth}
+\def\setpenalties#1#2#3%
+ {\ifx#1\undefined\else % space before #3 prevents lookahead problems, needed when #3=text
+ #1\numexpr#2+\plusone\relax\space\doexpandedrecurse{\the\numexpr#2\relax}{ #3}\zerocount\relax
+ \fi}
- \def\mkenablegridsnapping
- {\pdfkeeplinedimen\maxdimen
- \topskip\strutht
- \offinterlineskip}
+\def\doexpandedrecurse#1#2%
+ {\ifnum#1>\zerocount#2\@EA\doexpandedrecurse\@EA{\the\numexpr#1-1\relax}{#2}\fi}
- \def\mkdisablegridsnapping
- {\pdfkeeplinedimen\zeropoint
- % reset topskip
- \oninterlineskip}
+%D \macros
+%D {keeplinestogether}
+%D
+%D Dirty hack, needed in margin content that can run of a page.
+
+\def\keeplinestogether#1%
+ {\xdef\restoreinterlinepenalty{\global\resetpenalties\interlinepenalties}%
+ \global\setpenalties\interlinepenalties{#1}\plustenthousand}
+
+\newif\ifgridsnapping % to be sure
+
+\def\defaultwidowpenalty {2000} % was: 1000
+\def\defaultclubpenalty {2000} % was: 800
+\def\defaultdisplaywidowpenalty {50}
+\def\defaultbrokenpenalty {100}
+
+\def\defaultgridwidowpenalty {0}
+\def\defaultgridclubpenalty {0}
+\def\defaultgriddisplaywidowpenalty {0}
+\def\defaultgridbrokenpenalty {0}
+
+% The original approach:
+%
+% \def\setdefaultpenalties
+% {\ifgridsnapping
+% \widowpenalty\defaultgridwidowpenalty
+% \clubpenalty \defaultgridclubpenalty
+% \else
+% \widowpenalty\defaultwidowpenalty
+% \clubpenalty \defaultclubpenalty
+% \fi}
+%
+% However, we will use setups:
+
+% to be documented
+
+\def\nopenalties
+ {\widowpenalty \zerocount
+ \clubpenalty \zerocount
+ \brokenpenalty \zerocount
+ \doublehyphendemerits\zerocount
+ \finalhyphendemerits \zerocount
+ \adjdemerits \zerocount}
+
+\def\setdefaultpenalties
+ {\directsetup{\systemsetupsprefix\s!default}}
+
+\startsetups [\systemsetupsprefix\s!reset]
+ \resetpenalties\widowpenalties
+ \resetpenalties\clubpenalties
+ \resetpenalties\interlinepenalties
+\stopsetups
+
+% we use \directsetup because it's faster and we know there is no csl
+
+\startsetups [\systemsetupsprefix\s!default]
+
+ \directsetup{\systemsetupsprefix\s!reset}
+
+ \widowpenalty \defaultwidowpenalty
+ \clubpenalty \defaultclubpenalty
+ \displaywidowpenalty\defaultdisplaywidowpenalty
+ \brokenpenalty \defaultbrokenpenalty
+
+\stopsetups
+
+\startsetups [\v!grid] [\systemsetupsprefix\s!default]
+
+ \directsetup{\systemsetupsprefix\s!reset}
+
+ \widowpenalty \defaultgridwidowpenalty
+ \clubpenalty \defaultgridclubpenalty
+ \displaywidowpenalty\defaultgriddisplaywidowpenalty
+ \brokenpenalty \defaultgridbrokenpenalty
+
+\stopsetups
+
+% as an illustration:
+
+\startsetups [\systemsetupsprefix\v!strict]
+
+ \directsetup{\systemsetupsprefix\s!reset}
+
+ \setpenalties\widowpenalties2\maxdimen
+ \setpenalties\clubpenalties 2\maxdimen
+ \brokenpenalty \maxdimen
+
+\stopsetups
+
+\setdefaultpenalties % will happen later in \setuplayout
+
+% Suggested by GB (not the name -):
+
+\def\rapfillskip{.5\hsize plus .092\hsize minus .5\hsize} % D.A.'s value
+
+% Bovendien definieren we enkele extra \fill's:
+
+\def\hfilll{\hskip\zeropoint\!!plus1filll\relax}
+\def\vfilll{\vskip\zeropoint\!!plus1filll\relax}
+
+% De onderstaande hulpmacro's moeten nog eens instelbaar worden
+% gemaakt.
+
+\def\tfskipsize{1em\relax}
+\def\tfkernsize{1ex\relax}
+
+\def\tfskip{\dotfskip\tfskipsize}
+\def\tfkern{\dotfkern\tfkernsize}
+
+\def\dotfskip#1{{\tf\hskip#1}}
+\def\dotfkern#1{{\tf\kern #1}}
+
+% needs a proper \definenarrower or installnarrower
+
+\newskip\ctxleftskip
+\newskip\ctxrightskip
+\newskip\ctxmidskip
+
+\def\dosinglenarrower#1%
+ {\processaction
+ [#1]
+ [ \v!left=>\global\advance\ctxleftskip \@@slleft,
+ \v!middle=>\global\advance\ctxmidskip \@@slmiddle,
+ \v!right=>\global\advance\ctxrightskip \@@slright,
+ \v!reset=>\global\ctxleftskip \zeropoint
+ \global\ctxmidskip \zeropoint
+ \global\ctxrightskip\zeropoint,
+ \v!none=>,
+ \s!unknown=>\global\advance\ctxmidskip \commalistelement]}
+
+% \def\donarrower[#1]% hm, can be dorepeat directly
+% {\processaction
+% [#1]
+% [ \v!left=>\global\advance\ctxleftskip \@@slleft,
+% \v!middle=>\global\advance\ctxmidskip \@@slmiddle,
+% \v!right=>\global\advance\ctxrightskip \@@slright,
+% \v!none=>,% handy for delimitedtexts
+% \s!unknown=>{\dorepeatwithcommand[#1]\dosinglenarrower}]}
+
+\def\donarrower[#1]% hm, can be dorepeat directly
+ {\dorepeatwithcommand[#1]\dosinglenarrower}
+
+\def\complexstartnarrower[#1]%
+ {\@@slbefore % was hard coded \par
+ \bgroup
+ \global\ctxleftskip \zeropoint
+ \global\ctxrightskip\zeropoint
+ \global\ctxmidskip \zeropoint
+ \processcommalistwithparameters[#1]\donarrower
+ \advance\leftskip \ctxleftskip
+ \advance\rightskip \ctxrightskip
+ \advance\leftskip \ctxmidskip
+ \advance\rightskip \ctxmidskip
+ \seteffectivehsize}
+
+% todo: definenarrower
+
+\def\simplestartnarrower
+ {\startnarrower[\v!middle]}
+
+\definecomplexorsimple\startnarrower
+
+\def\stopnarrower
+ {\@@slafter % was hard coded \par / needed, else skips forgotten
+ \egroup}
+
+\def\setupnarrower
+ {\dodoubleargument\getparameters[\??sl]}
+
+\newdimen\@@effectivehsize \def\effectivehsize {\hsize}
+\newdimen\@@effectiveleftskip \def\effectiveleftskip {\leftskip}
+\newdimen\@@effectiverightskip \def\effectiverightskip{\rightskip}
+
+\def\seteffectivehsize
+ {\setlocalhsize
+ \@@effectivehsize \localhsize
+ \@@effectiveleftskip \leftskip
+ \@@effectiverightskip \rightskip
+ \let\effectivehsize \@@effectivehsize
+ \let\effectiveleftskip \@@effectiveleftskip
+ \let\effectiverightskip\@@effectiverightskip}
+
+\def\dodefinehbox[#1][#2]%
+ {\setvalue{hbox#1}##1%
+ {\hbox to #2{\begstrut##1\endstrut\hss}}}
+
+\def\definehbox
+ {\dodoubleargument\dodefinehbox}
+
+\def\iobox#1#2#3#% here #3# is not really needed
+ {\vbox\bgroup % we want to return a vbox like the others
+ \hbox\bgroup% we need to pack the signal with the box
+ \signalrightpage
+ \dowithnextboxcontent
+ {\let\\=\endgraf\forgetall\doifrightpageelse#1#2}
+ {\box\nextbox\egroup\egroup}
+ \vbox#3}
+
+\def\obox{\iobox\raggedleft \raggedright} % outerbox
+\def\ibox{\iobox\raggedright\raggedleft} % innerbox
+
+\def\dosetraggedvbox#1%
+ {\let\raggedbox\vbox
+ \processfirstactioninset
+ [#1]
+ [ \v!left=>\let\raggedbox\lbox,
+ \v!right=>\let\raggedbox\rbox,
+ \v!middle=>\let\raggedbox\cbox,
+ \v!inner=>\let\raggedbox\ibox,
+ \v!outer=>\let\raggedbox\obox,
+ \v!flushleft=>\let\raggedbox\rbox,
+ \v!flushright=>\let\raggedbox\lbox,
+ \v!center=>\let\raggedbox\cbox,
+ \v!no=>\def\raggedbox{\vbox\bgroup\raggedright\let\next=}]}
+
+\def\dosetraggedhbox#1%
+ {\let\raggedbox\hbox
+ \processaction % slow
+ [#1]
+ [ \v!left=>\def\raggedbox{\doalignedline\v!left },
+ \v!right=>\def\raggedbox{\doalignedline\v!right },
+ \v!middle=>\def\raggedbox{\doalignedline\v!middle},
+ \v!inner=>\def\raggedbox{\doalignedline\v!inner },
+ \v!outer=>\def\raggedbox{\doalignedline\v!outer },
+ \v!flushleft=>\def\raggedbox{\doalignedline\v!right },
+ \v!flushright=>\def\raggedbox{\doalignedline\v!left },
+ \v!center=>\def\raggedbox{\doalignedline\v!middle}]}
+
+\def\dosetraggedcommand#1%
+ {\expanded{\dodosetraggedcommand{#1}}}
+
+% \def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
+% {\let\raggedcommand \relax
+% \let\raggedtopcommand \empty
+% \let\raggedbottomcommand\empty
+% \chardef\raggedoneliner\zerocount
+% \doifsomething{#1}
+% {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
+% \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
+% \!!donectrue
+% \rawprocesscommalist[#1]\dododosetraggedcommand}}
+
+\newtoks\everyraggedcommand
+
+\def\raggedcommand{\the\everyraggedcommand}
+
+\def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
+ {\everyraggedcommand \emptytoks
+ \let\raggedtopcommand \empty
+ \let\raggedbottomcommand\empty
+ \chardef\raggedoneliner\zerocount
+ \doifsomething{#1}
+ {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
+ \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
+ \!!donectrue
+ \rawprocesscommalist[#1]\dododosetraggedcommand}}
+
+\def\dododosetraggedcommand#1%
+ {\executeifdefined{\@@ragged@@command\string#1}\relax}
+
+\def\@@ragged@@command{@@raggedcommand}
+
+\setvalue{\@@ragged@@command\v!hanging }{\appendtoks\enableprotruding \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nothanging }{\appendtoks\disableprotruding \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!hz }{\appendtoks\enableadjusting \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nohz }{\appendtoks\disableadjusting \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!spacing }{\appendtoks\enablespacehandling
+ \enablekernhandling \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nospacing }{\appendtoks\disablespacehandling
+ \disablekernhandling \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!hyphenated }{\appendtoks\dohyphens \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nothyphenated}{\appendtoks\nohyphens \to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!tolerant }{\appendtoks\tolerance3000\relax \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!verytolerant}{\appendtoks\tolerance4500\relax \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!stretch }{\appendtoks\emergencystretch\bodyfontsize\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!left}%
+ {\if!!donea \appendtoks\veryraggedleft\to\everyraggedcommand
+ \else \appendtoks\raggedleft \to\everyraggedcommand
+ \fi
+ \!!donecfalse}
+
+\setvalue{\@@ragged@@command\v!right}%
+ {\if!!donea \appendtoks\veryraggedright\to\everyraggedcommand
+ \else \appendtoks\raggedright \to\everyraggedcommand
+ \fi
+ \!!donecfalse}
+
+\setvalue{\@@ragged@@command\v!middle}%
+ {\if!!donec
+ \if!!doneb \appendtoks\raggedwidecenter\to\everyraggedcommand
+ \else\if!!donea \appendtoks\veryraggedcenter\to\everyraggedcommand
+ \else \appendtoks\raggedcenter \to\everyraggedcommand
+ \fi\fi
+ \!!donecfalse
+ \else
+ \let\raggedbottomcommand\vfilll % bonus, pretty strong
+ \let\raggedtopcommand \vfilll % used with \framed for
+ \fi} % instance in tables
+
+\setvalue{\@@ragged@@command\v!flushleft }{\getvalue{\@@ragged@@command\v!right }}
+\setvalue{\@@ragged@@command\v!flushright}{\getvalue{\@@ragged@@command\v!left }}
+\setvalue{\@@ragged@@command\v!center }{\getvalue{\@@ragged@@command\v!middle}}
+
+\setvalue{\@@ragged@@command\v!high}%
+ {\let\raggedbottomcommand\vfilll} % and since we lack a
+
+\setvalue{\@@ragged@@command\v!low}%
+ {\let\raggedtopcommand\vfilll} % proper keyword, but
+
+\setvalue{\@@ragged@@command\v!lohi}%
+ {\let\raggedbottomcommand\vfilll % we do support the
+ \let\raggedtopcommand\vfilll} % ugly laho (lohi)
+
+\setvalue{\@@ragged@@command\v!no}%
+ {\appendtoks\raggedright\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!yes}%
+ {\appendtoks\notragged\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!normal}%
+ {\appendtoks\notragged\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!inner}% not yet perfect
+ {\signalrightpage % may interfere
+ \doifrightpageelse
+ {\getvalue{\@@ragged@@command\v!right}}
+ {\getvalue{\@@ragged@@command\v!left}}}
+
+\setvalue{\@@ragged@@command\v!outer}% not yet perfect
+ {\signalrightpage % may interfere
+ \doifrightpageelse
+ {\getvalue{\@@ragged@@command\v!left}}
+ {\getvalue{\@@ragged@@command\v!right}}}
+
+\setvalue{\@@ragged@@command\v!lesshyphenation}%
+ {\appendtoks\lesshyphens\to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!morehyphenation}%
+ {\appendtoks\morehyphens\to\everyraggedcommand}
+
+% compare:
+%
+% \framed[width=4cm,align=no] {\hfil xxx}
+% \framed[width=4cm,align=disable]{\hfil xxx}
+
+\setvalue{\@@ragged@@command\v!disable}% for one liners
+ {\appendtoks\raggedright\parfillskip\zeropoint\to\everyraggedcommand}
+
+\chardef\raggedoneliner\zerocount
+
+\setvalue{\@@ragged@@command\v!line}%
+ {\chardef\raggedoneliner\plusone}
+
+%D Unofficial, may disappear. Now handled directly in the
+%D core-rul module.
+
+% \def\@@startraggedoneliner
+% {\ifcase\raggedoneliner\else
+% \dontleavehmode\hbox to \hsize \bgroup % hsize added, else useless
+% \ifcase\raggedstatus\or\hss\or\hss\fi
+% \ignorespaces
+% \bgroup
+% \aftergroup\removeunwantedspaces
+% \fi}
+
+% \def\@@stopraggedoneliner
+% {\ifcase\raggedoneliner\else
+% \egroup
+% \ifcase\raggedstatus\or\or\hss\or\hss\fi
+% \egroup
+% \ignorespaces % ? ? ?
+% \fi}
+
+% \def\@@handleoneliner
+% {\ifcase\raggedoneliner\else
+% \@@startraggedoneliner
+% \aftergroup\@@stopraggedoneliner
+% \fi}
+
+% Nog doen:
+%
+% \goodbreak -> \allowbreak en \dosomebreak{..} in koppen
+%
+% bij koppen zowieso: \blanko[reset]
+
+% Nog in commando verwerken:
+%
+% \voorkeur la \blanko
+%
+% Om ongewenste witruimte te voorkomen kan met \dosomebreak{\break}
+% een \penalty voor witruimte worden geplaatst.
+
+\def\removelastskip % a redefinition of plain
+ {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi}
+
+% first version:
+%
+% \def\dosomebreak#1%
+% {\scratchskip\lastskip
+% \removelastskip
+% %\type{#1}%
+% #1\relax
+% \ifdim\scratchskip=\zeropoint \else
+% \vskip\scratchskip
+% \fi}
+%
+% don't change the next improvement:
+
+% \def\dosomebreak#1%
+% {\endgraf % beware, this forces a newline
+% \ifvmode
+% \ifdim\lastskip=\zeropoint
+% #1\relax
+% \else
+% \scratchskip\lastskip
+% \removelastskip
+% #1\relax
+% \vskip\scratchskip
+% \fi
+% \fi}
+
+% beter, vooral in \vbox; nog in \pagina toepassen s!
+
+\def\doifoutervmode#1%
+ {\ifvmode\ifinner\else#1\fi\fi}
+
+\ifx\dosomebreak\undefined % defined in mkiv
+
+ \def\dosomebreak#1%
+ {\doifoutervmode
+ {\scratchskip\lastskip
+ \removelastskip
+ %\leavevmode\type{#1}%
+ #1\relax
+ \ifdim\scratchskip=\zeropoint % else interference with footnotes
+ \else
+ \vskip\scratchskip
+ \fi}}
\fi
+\def\forgeteverypar
+ {\everypar{\the\neverypar}}
+
+%\def\forgetparindent
+% {\forgeteverypar
+% \indentfirstparagraphtrue % recently added
+% \setupindenting[\v!geen]}
+
+%\def\forgetparskip
+% {\setupwhitespace[\v!geen]}
+
+\def\forgetparindent
+ {\forgeteverypar
+ \indentfirstparagraphtrue % recently added
+ \let\currentindentation\v!none
+ \ctxparindent\zeropoint
+ \parindent\zeropoint\relax}
+
+\def\forgetparskip
+ {\let\currentwhitespace\v!none
+ \ctxparskip\zeropoint
+ \parskip\zeropoint\relax}
+
+\def\forgetbothskips
+ {\tolerance1500
+ \leftskip\zeropoint
+ \rightskip\zeropoint\relax}
+
+\def\forgetspacing
+ {\emergencystretch\zeropoint}
+
+\newif\ifforgotten % rather good signal for inner
+
+\appendtoks \forgottentrue \to \everyforgetall
+\appendtoks \forgetragged \to \everyforgetall
+\appendtoks \forgetparskip \to \everyforgetall
+\appendtoks \forgetparindent \to \everyforgetall
+\appendtoks \forgetbothskips \to \everyforgetall
+\appendtoks \forgetspacing \to \everyforgetall % i.v.m. funny spacing in pagebody
+\appendtoks \spacing\!!plusone \to \everyforgetall % new per 10/08/2004, else problems in otr / !! needed
+\appendtoks \everypar\emptytoks \to \everyforgetall % indeed!
+
+\def\localvbox#1#%
+ {\vbox#1\bgroup
+ \forgetparskip
+ \setlocalhsize
+ \hsize\localhsize
+ \forgetparindent
+ \forgetbothskips
+ \forgeteverypar
+ \let\next=}
+
+% ach ja, hoort niet hier
+
+% \unexpanded\def\dostartattributes#1#2#3%
+% {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+% \doifdefinedelse{#1#2}
+% {\def\fontattribute{\getvalue{#1#2}}}
+% {\let\fontattribute=\empty}%
+% \doifdefinedelse{#1#3}
+% {\def\colorattribute{\getvalue{#1#3}}}
+% {\let\colorattribute=\empty}%
+% \startcolor[\colorattribute]%
+% \@EA\doconvertfont\@EA{\fontattribute}}
+%
+% \unexpanded\def\dostopattributes%
+% {\stopcolor
+% \endgroup}
+%
+% \unexpanded\def\doattributes#1#2#3#4%
+% {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}
+
+%D A hardly faster implementation follows. We cannot use
+%D \type {csname} testing since the first argument can be
+%D anything, even a raw fontswitch. No a real improvement
+%D (some 5 seconds on 260 seconds for the maps bibliography).
+
+\let\dostopattributes\relax % in case these commands end up in an edef
+
+\unexpanded\def\dostartattributes#1#2#3%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \startcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \ifcsname#1#2\endcsname
+ \expandafter\doconvertfont
+ \else
+ \expandafter\gobbleoneargument
+ \fi{\csname#1#2\endcsname}}
+
+\newconditional \parbasedattributes
+
+\def\finishparbasedattributes
+ {\ifconditional\parbasedattributes
+ \setfalse\parbasedattributes
+ \par
+ \fi}
+
+\def\dostopparbasedattributes
+ {\settrue\parbasedattributes
+ \dostopattributes}
+
+\unexpanded\def\@@dostopattributes
+ {\stopcolor
+ \finishparbasedattributes
+ \endgroup}
+
+\unexpanded\def\@@nostopattributes
+ {\finishparbasedattributes
+ \endgroup}
+
+\unexpanded\def\doattributes#1#2#3#4%
+ {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}
+
+% An even faster \ETEX\ version:
+
+\unexpanded\def\dostartattributes#1#2#3%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifincolor
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \faststartcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \ifcsname#1#2\endcsname
+ % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi}
+
+\unexpanded\def\@@dostopattributes
+ {\faststopcolor
+ \finishparbasedattributes
+ \endgroup}
+
+\unexpanded\def\@@nostopattributes
+ {\finishparbasedattributes
+ \endgroup}
+
+%D Bonus macro, see core-sec.tex
+
+\unexpanded\def\dosetfontattribute#1#2%
+ {\ifcsname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi\empty}
+
+%D Since this happens a lot, and sometimes large arguments
+%D are passed in \type {#4}, we just copy some code:
+
+\unexpanded\def\doattributes#1#2#3#4%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifincolor
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \faststartcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\endgroup
+ \fi
+ \else
+ \let\dostopattributes\endgroup
+ \fi
+ \ifcsname#1#2\endcsname
+ % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi
+ {#4}%
+ \dostopattributes}
+
+% Kan vaker worden toegepast en moet bovendien sneller!
+
+\newskip\leftskipadaption
+\newskip\rightskipadaption
+
+\def\doadaptleftskip#1%
+ {\dosetleftskipadaption{#1}%
+ \advance\leftskip \leftskipadaption}
+
+\def\doadaptrightskip#1%
+ {\dosetrightskipadaption{#1}%
+ \advance\rightskip \rightskipadaption}
+
+\setvalue{@lsa@\v!standard}{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
+\setvalue{@lsa@\v!yes }{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
+\letvalue{@lsa@\v!no }\zeropoint
+\letvalue{@lsa@\empty }\zeropoint
+\setvalue{@rsa@\v!standard}{\@@slright}
+\setvalue{@rsa@\v!yes }{\@@slright}
+\letvalue{@rsa@\v!no }\zeropoint
+\letvalue{@rsa@\empty }\zeropoint
+
+% not safe for 2\parindent
+%
+% \def\dosetleftskipadaption#1%
+% {\leftskipadaption
+% \ifcsname @lsa@#1\endcsname
+% \csname @lsa@#1\endcsname
+% \else
+% #1%
+% \fi
+% \relax}
+
+\def\dosetleftskipadaption#1%
+ {\edefconvertedargument\ascii{@lsa@#1}%
+ \leftskipadaption
+ \ifcsname\ascii\endcsname
+ \csname\ascii\endcsname
+ \else
+ #1%
+ \fi
+ \relax}
+
+\def\dosetrightskipadaption#1%
+ {\edefconvertedargument\ascii{@rsa@#1}%
+ \rightskipadaption
+ \ifcsname\ascii\endcsname
+ \csname\ascii\endcsname
+ \else
+ #1%
+ \fi
+ \relax}
+
+\newcount \noftrackedpagestates
+\newif \ifpagestatemismatch
+\newcount \realpagestateno
+\chardef \frozenpagestate \zerocount
+
+\def\dotrackpagestate#1#2%
+ {\ifdoublesided \ifinpagebody \else
+ \doforcedtrackpagestate{#1}{#2}%
+ \fi \fi}
+
+\def\doforcedtrackpagestate#1#2%
+ {\ifcase\frozenpagestate
+ \global\advance\noftrackedpagestates\plusone
+ \global\advance#2\plusone
+ \lazysavetaggedtwopassdata{#1}{\number\noftrackedpagestates}{\number#2}{\noexpand\realfolio}%
+ %\llap{\infofont\number\noftrackedpagestates/\number#2}% tracing
+ \fi}
+
+\def\doifrightpagestateelse#1#2%
+ {\ifcase\frozenpagestate
+ \pagestatemismatchfalse
+ \realpagestateno\realfolio
+ \ifinpagebody
+ \ifdoublesided
+ \ifodd\realpageno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \else
+ \twopassdatafoundtrue
+ \fi
+ \else\ifdoublesided
+ \findtwopassdata{#1}{\number#2}%
+ \iftwopassdatafound
+ \realpagestateno\twopassdata\relax
+ \ifnum\twopassdata=\realpageno \else
+ \pagestatemismatchtrue
+ \fi
+ \ifodd\twopassdata\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \else
+ \ifodd\realpageno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \else
+ \twopassdatafoundtrue
+ \fi\fi
+ \else
+ \ifodd\realpagestateno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \iftwopassdatafound
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\def\doifforcedrightpagestateelse#1#2%
+ {\ifcase\frozenpagestate
+ \pagestatemismatchfalse
+ \realpagestateno\realfolio
+ \findtwopassdata{#1}{\number#2}%
+ \iftwopassdatafound
+ \realpagestateno\twopassdata\relax
+ \ifnum\twopassdata=\realpageno \else
+ \pagestatemismatchtrue
+ \fi
+ \ifodd\twopassdata\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \else
+ \ifodd\realpageno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \else
+ \ifodd\realpagestateno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \iftwopassdatafound
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\def\freezepagestate {\chardef\frozenpagestate\plusone }
+\def\defrostpagestate{\chardef\frozenpagestate\zerocount}
+
+% we can make more of these on top, but how to deal with mixed frozen states
+
+\definetwopasslist\s!paragraph \newcount \nofraggedparagraphs
+
+\def\signalrightpage {\dotrackpagestate \s!paragraph\nofraggedparagraphs}
+\def\doifrightpageelse{\doifrightpagestateelse\s!paragraph\nofraggedparagraphs}
+
+\newcount\pagesignallevel
+
+\def\startsignalrightpage % one may do a \postsignalrightplace
+ {\advance\pagesignallevel\plusone
+ \presignalrightpage
+ \let\signalrightpage\relax
+ \let\presignalrightpage\relax
+ \let\startsignalrightpage\relax
+ \doifrightpageelse\donothing\donothing
+ \freezepagestate}
+
+\def\stopsignalrightpage
+ {\ifcase\pagesignallevel\or\postsignalrightpage\fi
+ \advance\pagesignallevel\minusone}
+
+\def\setraggedparagraphmode
+ {\signalrightpage\doifrightpageelse} % move it there
+
+\ifx\swapmargins\undefined \let\swapmargins\undefined \fi % todo
+
+\def\doifswappedrightpageelse#1#2% alleen in box construction !
+ {\doifrightpageelse
+ {#1}
+ {\scratchcounter\realpageno
+ \realpageno\realpagestateno\relax
+ \swapmargins
+ \realpageno\scratchcounter
+ #2}}
+
+\newbox\signaledrightpage % this way we can avoid interference, i.e. postpone placement
+
+\def\presignalrightpage {\global\setbox\signaledrightpage\hbox{\signalrightpage}}
+\def\postsignalrightpage{\ifvoid\signaledrightpage\else\box\signaledrightpage\fi}
+
+% The next feature is is used in:
+%
+% \definenumber[test][way=bypage]
+%
+% \def\Test
+% {\incrementnumber[test]\rawnumber[test]/%
+% \incrementnumber[test]\rawnumber[test]/%
+% \incrementnumber[test]\rawnumber[test]\space
+% \checkpagechange{oeps}\changedpage{oeps}\space
+% \ifpagechanged TRUE\else FALSE\fi}
+%
+% \Test\page \Test\par \Test\page \Test\par \Test\page \Test\page
+%
+% (adapted from cont-new.tex:)
+
+\newif\ifpagechanged \let\lastchangedpage\empty
+
+\def\docheckpagestatechange#1#2#3%
+ {\pagechangedfalse
+ \doforcedtrackpagestate{#2}{#3}%
+ \findtwopassdata{#2}{\number#3}%
+ \iftwopassdatafound
+ \ifnum\twopassdata>0\getvalue{#2:p:#1}\relax
+ \pagechangedtrue
+ \fi
+ \fi
+ \ifpagechanged
+ \letgvalue{#2:p:#1}\twopassdata
+ \globallet\lastchangedpage\twopassdata
+ \else
+ \globallet\lastchangedpage\realfolio
+ \fi}
+
+\def\changedpagestate#1#2%
+ {\executeifdefined{#2:p:#1}{0}}
+
+\def\checkpagechange#1{\docheckpagestatechange{#1}\s!paragraph\nofraggedparagraphs}
+\def\changedpage #1{\changedpagestate{#1}\s!paragraph}
+
+% saved struts
+
+\ifx\savedstrutbox\undefined \newbox\savedstrutbox \fi
+
+\def\savestrut {\setbox\savedstrutbox\copy\strutbox}
+\def\savedstrut{\copy \savedstrutbox}
+
+% De onderstaande macro's zijn opgenomen in Plain TeX.
+%
+% \def\raggedright%
+% {\rightskip\zeropoint plus2em \spaceskip.3333em \xspaceskip.5em\relax}
+%
+% \def\ttraggedright%
+% {\tttf\rightskip\zeropoint plus2em\relax}
+%
+% \newif\ifr@ggedbottom
+%
+% \def\raggedbottom%
+% {\topskip 10\points plus60\points \r@ggedbottomtrue}
+%
+% \def\normalbottom%
+% {\topskip 10\points \r@ggedbottomfalse}
+%
+% en worden hieronder wat aangepast.
+
+% the three boolean will become obsolete some day in favour
+% of \bottomraggedness
+
+\chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
+
+\def\bottomalignlimit{3\lineheight}
+
+\newif\ifn@rmalbottom
+\newif\ifr@ggedbottom
+\newif\ifb@selinebottom
+
+\def\normalbottom
+ {% \topskip 10pt
+ \r@ggedbottomfalse}
+
+\def\raggedbottom
+ {\chardef\bottomraggedness\zerocount
+ \n@rmalbottomfalse
+ \r@ggedbottomtrue
+ \b@selinebottomfalse
+ \settopskip}
+
+\def\alignbottom
+ {\chardef\bottomraggedness\plusone
+ \n@rmalbottomtrue
+ \r@ggedbottomfalse
+ \b@selinebottomfalse
+ \settopskip}
+
+\def\baselinebottom
+ {\chardef\bottomraggedness\plustwo
+ \n@rmalbottomfalse
+ \r@ggedbottomfalse
+ \b@selinebottomtrue
+ \settopskip}
+
+\let\normalbottom=\alignbottom % downward compatible
+
+% so, the new one will be
+%
+% \chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
+%
+% \def\bottomalignlimit{3\lineheight} % will be settable
+%
+% \def\raggedbottom {\chardef\bottomraggedness=0 \settopskip}
+% \def\alignbottom {\chardef\bottomraggedness=1 \settopskip}
+% \def\baselinebottom{\chardef\bottomraggedness=2 \settopskip}
+%
+% \let\normalbottom =\alignbottom
+
+% \hyphenpenalty = ( 2.5 * \hsize ) / \raggedness
+% \tolerance >= 1500 % was 200
+% \raggedness = 2 .. 6\bodyfontsize
+
+\chardef\raggedstatus=0 % normal left center right
+
+\def\leftraggedness {2\bodyfontsize}
+\def\rightraggedness {2\bodyfontsize}
+\def\middleraggedness {6\bodyfontsize}
+
+\def\middleraggedness {.5\hsize} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
+
+% oeps, hsize can be 0pt in which case we get a strange division
+
+\def\middleraggedness {\ifdim\hsize=\zeropoint6\bodyfontsize\else.5\hsize\fi} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
+
+%D More hyphenation control, will be combined with align
+%D setup.
+
+\def\nohyphens
+ {\ifx\dohyphens\relax
+ \edef\dohyphens
+ {\hyphenpenalty\the\hyphenpenalty
+ \exhyphenpenalty\the\exhyphenpenalty\relax}%
+ \fi
+ \hyphenpenalty\plustenthousand
+ \exhyphenpenalty\plustenthousand}
+
+\let\dohyphens\relax
+
+%D To prevent unwanted side effects, we also have to check
+%D for hyphens here:
+
+% \def\setraggedness#1%
+% {\ifnum\tolerance<1500\relax % small values have
+% \tolerance1500\relax % unwanted side effects
+% \fi
+% \spaceskip2.5\hsize % we misuse these registers
+% \xspaceskip#1\relax % for temporary storage;
+% \divide\spaceskip \xspaceskip % they are changed anyway
+% \ifx\dohyphens\relax
+% \hyphenpenalty\spaceskip % \else no hyphens is active
+% \fi}
+
+\newskip\@@raggedskipa
+\newskip\@@raggedskipb
+
+\def\setraggedness#1%
+ {\ifnum\tolerance<1500\relax % small values have
+ \tolerance1500\relax % unwanted side effects
+ \fi
+ \ifx\dohyphens\relax
+ % this code will be reconsidered / kind of fuzzy (and old)
+ \@@raggedskipa 2.5\hsize
+ \@@raggedskipb #1\relax
+ \divide\@@raggedskipa \@@raggedskipb
+ \hyphenpenalty\@@raggedskipa
+ \fi}
+
+\let\updateraggedskips\relax
+
+\def\setraggedskips#1#2#3#4#5#6#7% never change this name
+ {\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
+ \updateraggedskips}
+
+\def\dosetraggedskips#1#2#3#4#5#6#7%
+ {\chardef \raggedstatus#1\relax
+ \leftskip 1\leftskip \!!plus#2\relax % zie: Tex By Topic 8.1.3
+ \rightskip 1\rightskip\!!plus#3\relax % zie: Tex By Topic 8.1.3
+ \spaceskip #4\relax
+ \xspaceskip #5\relax
+ \parfillskip\zeropoint\!!plus#6\relax
+ \parindent #7\relax}
+
+% \def\notragged%
+% {\setraggedskips{0}{0em}{0em}{0em}{0em}{1fil}{\parindent}}
+
+% older (context) names:
+
+\let\spaceamount \interwordspace
+\let\emspaceamount\emwidth
+
+% tracing:
+
+\def\doshowpardata#1%
+ {\ifx#1\relax\else
+ \hbox{\string#1: \the#1}\endgraf
+ \expandafter\doshowpardata
+ \fi}
+
+\def\showpardata
+ {\edef\thepardata
+ {\hbox{font: \fontname\font}\endgraf
+ \doshowpardata
+ \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
+ \hsize \vsize
+ \leftskip \rightskip
+ \spaceskip \xspaceskip
+ \parindent \parfillskip
+ \hyphenpenalty \exhyphenpenalty
+ \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty
+ \doublehyphendemerits \finalhyphendemerits \adjdemerits
+ \relax}%
+ \begingroup
+ \dontshowcomposition
+ \inleftmargin{\vsmash
+ {\switchtobodyfont[7pt,tt]%
+ \framed[\c!align=\v!right]{\thepardata}}}%
+ \endgroup}
+
+\def\startshowpardata
+ {\begingroup
+ \showcomposition
+ \showstruts\tracepositionstrue \tracingparagraphs\maxdimen
+ \appendtoksonce\showpardata\let\showpardata\relax\to\everypar}
+
+\def\stopshowpardata
+ {\endgraf
+ \endgroup}
+
+% \defineXMLenvironment[showpardata] \startshowpardata \stopshowpardata
+% \defineXMLsingular [showpardata] \showpardata
+
+% defaults
+
+\def\raggedfillamount {1fil}
+\def\raggedhalffillamount{.5fil}
+\def\raggedspaceamount {\interwordspace} % {.3333em}
+\def\raggedxspaceamount {.5em}
+
+\def\notragged
+ {\chardef\raggedstatus\zerocount
+ \leftskip 1\leftskip
+ \rightskip 1\rightskip
+ \spaceskip \zeropoint
+ \xspaceskip \zeropoint
+ \parfillskip\zeropoint\!!plus\raggedfillamount\relax
+ \let\updateraggedskips\relax} % new
+
+\let\forgetragged\notragged
+
+\def\raggedleft
+ {\setraggedness\leftraggedness
+ \setraggedskips1\leftraggedness\zeropoint\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+\def\raggedcenter
+ {\setraggedness\middleraggedness
+ \setraggedskips2\middleraggedness\middleraggedness\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+%D We used to have:
+%D
+%D \starttyping
+%D \def\raggedright
+%D {\setraggedness\rightraggedness
+%D \setraggedskips{3}{0em}{\rightraggedness}{.3333em}{.5em}{0em}{\parindent}}
+%D \stoptyping
+%D
+%D However, the next alternative, suggested by Taco, is better.
+
+\def\raggedright
+ {\setraggedness\rightraggedness
+ \setraggedskips3\zeropoint\rightraggedness\raggedspaceamount
+ \raggedxspaceamount\raggedfillamount\parindent}
+
+\def\veryraggedleft
+ {\setraggedskips1\raggedfillamount\zeropoint\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+%D When we want the last line to have a natural width:
+%D
+%D \starttyping
+%D \def\veryraggedleft%
+%D {\setraggedskips{1}{1fil}{0em}{.3333em}{.5em}{0em}{-1fil}}
+%D \stoptyping
+%D
+%D but this one is not accepted by the macros.
+
+\def\veryraggedcenter
+ {\setraggedskips2\raggedfillamount\raggedfillamount\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+\def\veryraggedright
+ {\setraggedskips3\zeropoint\raggedfillamount\raggedspaceamount
+ \raggedxspaceamount\zeropoint\parindent}
+
+\def\ttraggedright
+ {\tttf
+ \setraggedskips3\zeropoint\rightraggedness
+ \zeropoint\zeropoint\zeropoint\parindent} % \ctxparindent
+
+%D A bonus one:
+
+\def\raggedwidecenter
+ {\setraggedness\middleraggedness
+ \setraggedskips2\raggedhalffillamount\raggedhalffillamount
+ \raggedspaceamount\raggedxspaceamount\zeropoint\zeropoint}
+
+\newif\if@@asragged \@@asraggedtrue % old method
+
+% todo
+%
+% \setuplayout[grid=yes,lines=44] \showgrid
+% \starttext
+% test \vfill test \endgraf \strut \endgraf \vskip-\lineheight \removedepth \pagina test
+% \stoptext
+
+% \setupalign[reset,new,right,old]
+
+\def\@@align@@rl{\if!!donea\veryraggedleft \else\raggedleft \fi}
+\def\@@align@@rr{\if!!donea\veryraggedright \else\raggedright \fi}
+\def\@@align@@rc{\if!!donea\veryraggedcenter\else\raggedcenter\fi}
+
+\setvalue{@@ngila@@\v!broad }{\!!doneatrue}
+\setvalue{@@ngila@@\v!wide }{\!!donebtrue}
+
+\def\installalign#1#2{\setvalue{@@align@@#1}{#2}} % can be used for overloads
+
+\installalign \v!new {\@@asraggedfalse}
+\installalign \v!old {\@@asraggedtrue}
+\installalign \empty {}
+
+\installalign \v!line {\baselinebottom}
+\installalign \v!bottom {\raggedbottom}
+\installalign \v!height {\normalbottom}
+\installalign \v!width {\notragged}
+\installalign \v!normal {\notragged}
+\installalign \v!yes {\notragged}
+\installalign \v!no {\raggedright}
+\installalign \v!inner {\if@@asragged \setraggedparagraphmode\@@align@@rl\@@align@@rr \else
+ \setraggedparagraphmode\@@align@@rr\@@align@@rl \fi}
+\installalign \v!outer {\if@@asragged \setraggedparagraphmode\@@align@@rr\@@align@@rl \else
+ \setraggedparagraphmode\@@align@@rl\@@align@@rr \fi}
+\installalign \v!left {\if@@asragged\@@align@@rl\else\@@align@@rr\fi}
+\installalign \v!right {\if@@asragged\@@align@@rr\else\@@align@@rl\fi}
+\installalign \v!middle {\if!!doneb\raggedwidecenter\else\@@align@@rc\fi}
+\installalign \v!flushleft {\if!!donea\veryraggedright \else\raggedright\fi}
+\installalign \v!flushright {\if!!donea\veryraggedleft \else\raggedleft \fi}
+\installalign \v!flushouter {\setraggedparagraphmode\raggedleft\raggedright}
+\installalign \v!flushinner {\setraggedparagraphmode\raggedright\raggedleft}
+\installalign \v!center {\if!!doneb\raggedwidecenter\else\@@align@@rc\fi}
+\installalign \v!hanging {\enableprotruding}
+\installalign \v!nothanging {\disableprotruding}
+\installalign \v!hz {\enableadjusting}
+\installalign \v!nohz {\disableadjusting}
+\installalign \v!spacing {\enablespacehandling \enablekernhandling}
+\installalign \v!nospacing {\disablespacehandling\disablekernhandling}
+\installalign \v!hyphenated {\dohyphens}
+\installalign \v!nothyphenated {\nohyphens}
+\installalign \v!new {\@@asraggedfalse} % so new will give you consistency
+\installalign \v!reset {\notragged\normalbottom}
+
+\installalign \v!tolerant {\tolerance3000 \relax}
+\installalign \v!verytolerant {\tolerance4500 \relax}
+\installalign \v!stretch {\emergencystretch\bodyfontsize}
+
+\newcount\hyphenminoffset
+
+\ifx\sethyphenationvariables\undefined \let\sethyphenationvariables\relax \fi
+
+\def\lesshyphens
+ {\advance\hyphenminoffset\plusone
+ \sethyphenationvariables}
+
+\def\morehyphens
+ {\ifcase\hyphenminoffset \else
+ \advance\hyphenminoffset\minusone
+ \fi
+ \sethyphenationvariables}
+
+\installalign \v!lesshyphenation {\lesshyphens}
+\installalign \v!morehyphenation {\morehyphens}
+
+\def\dodosetupalign#1{\csname @@align@@#1\endcsname}
+\def\dodosetupngila#1{\csname @@ngila@@#1\endcsname}
+
+\def\setupalign
+ {\dosingleargument\dosetupalign}
+
+\def\dosetupalign[#1]% can be made faster by checking for defined #1
+ {\!!doneafalse
+ \!!donebfalse
+ \processcommacommand[#1]\dodosetupngila
+ \processcommacommand[#1]\dodosetupalign}
+
+% \setupalign[flushleft] \input ward \par % lijnlinks
+% \setupalign[right] \input ward \par
+
+% \setupalign[flushright] \input ward \par % lijnrechts
+% \setupalign[left] \input ward \par
+
+% \setupalign[middle] \input ward \par % centreer
+% \setupalign[center] \input ward \par
+
+\def\startalignment
+ {\bgroup
+ \setupalign}
+
+\def\stopalignment
+ {\par
+ \egroup}
+
+\chardef\alignstrutmode=1
+
+% see later for the real definition, which in the simple case is:
+
+\newtoks \everyleftofalignedline
+\newtoks \everyrightofalignedline
+
+\def\shiftalignedline#1#2#3#4% left, right, inner, outer
+ {\rightorleftpageaction
+ {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
+ \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
+ {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
+ \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}
+
+% \def\doalignline#1#2% \\ == newline
+% {\begingroup
+% \setlocalhsize % new
+% \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
+% \dowithnextbox
+% {\noindentation % was \noindent
+% \dontleavehmode % added in marrakesch at TUG 2006
+% \hbox to \localhsize
+% {\ifcase\alignstrutmode\or\strut\fi
+% \the\everyleftofalignedline
+% #1\unhbox\nextbox#2\relax
+% \the\everyrightofalignedline}%
+% \endgroup}
+% \hbox}
+
+\def\doalignline#1#2% \\ == newline
+ {\noindentation % was \noindent
+ \dontleavehmode % added in marrakesch at TUG 2006\begingroup
+ \begingroup
+ \setlocalhsize % new
+ \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
+ \dowithnextbox
+ {\hbox to \localhsize
+ {\ifcase\alignstrutmode\or\strut\fi
+ \the\everyleftofalignedline
+ #1\unhbox\nextbox#2\relax
+ \the\everyrightofalignedline}%
+ \endgroup}
+ \hbox}
+
+% plain commands
+
+\ifx\undefined\line \def\line {\hbox to\hsize} \fi
+\ifx\undefined\leftline \def\leftline #1{\line{#1\hss}} \fi
+\ifx\undefined\rightline \def\rightline #1{\line{\hss#1}} \fi
+\ifx\undefined\centerline \def\centerline#1{\line{\hss#1\hss}} \fi
+
+% directe commando's
+
+\def\leftaligned {\doalignline \relax \hss }
+\def\midaligned {\doalignline \hss \hss }
+\def\rightaligned{\doalignline \hss \relax}
+
+\let\centeraligned\midaligned
+
+\def\regelbegrensd#1{\limitatetext{#1}{\hsize}{\unknown}} % to be translated
+
+% indirecte commando's
+
+\letvalue{\s!do\v!line\v!left }\leftaligned
+\letvalue{\s!do\v!line\v!right }\rightaligned
+\letvalue{\s!do\v!line\v!middle }\midaligned
+\letvalue{\s!do\v!line\v!flushleft }\rightaligned
+\letvalue{\s!do\v!line\v!flushright}\leftaligned
+\letvalue{\s!do\v!line\v!center }\midaligned
+
+\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}
+
+%D Experimental:
+
+% simple version
+%
+% \def\doxalignline#1#2%
+% {\bgroup
+% \setlocalhsize
+% \def\\{\egroup\par\doxalignline{#1}{#2}\bgroup}% inefficient
+% \dowithnextbox
+% {\noindent\hbox to \localhsize
+% {\ifcase\alignstrutmode\or\strut\fi
+% \signalrightpage
+% \doifrightpageelse{#1\unhbox\nextbox#2}{#2\unhbox\nextbox#1}}%
+% \egroup}
+% \hbox}
+%
+% \setvalue{\s!do\v!regel\v!binnen}{\doxalignline\relax\hss}
+% \setvalue{\s!do\v!regel\v!buiten}{\doxalignline\hss\relax}
+%
+% more extensive:
+
+\def\doxalignline#1#2#3#4#5#6%
+ {\noindentation % was \noindent
+ \dontleavehmode % added in marrakesch at TUG 2006\begingroup
+ \begingroup
+ \setlocalhsize
+ \def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
+ \dowithnextbox
+ {%\noindent moved up
+ \hbox to \localhsize
+ {#1\hskip\ifdone#2\else#3\fi#4%
+ \hbox to \localhsize
+ {\the\everyleftofalignedline
+ \ifcase\alignstrutmode\or\strut\fi
+ \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
+ \the\everyrightofalignedline}%
+ \hss}%
+ \endgroup}
+ \hbox}
+
+\def\doxcheckline
+ {\signalrightpage\doifrightpageelse\donetrue\donefalse}
+
+\setvalue{\s!do\v!line\v!inner }{\doxalignline\doxcheckline++\zeropoint \relax\hss }
+\setvalue{\s!do\v!line\v!outer }{\doxalignline\doxcheckline++\zeropoint \hss \relax}
+\setvalue{\s!do\v!line\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss }
+\setvalue{\s!do\v!line\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss \relax}
+\setvalue{\s!do\v!line\v!inneredge }{\doxalignline\doxcheckline-+\inneredgetotal \relax\hss }
+\setvalue{\s!do\v!line\v!outeredge }{\doxalignline\doxcheckline+-\outeredgetotal \hss \relax}
+\setvalue{\s!do\v!line\v!backspace }{\doxalignline\doxcheckline-+\backspace \relax\hss }
+\setvalue{\s!do\v!line\v!cutspace }{\doxalignline\doxcheckline+-\cutspace \hss \relax}
+
+\setvalue{\s!do\v!line\v!leftmargin }{\doxalignline\donefalse --\leftmargintotal \hss \relax}
+\setvalue{\s!do\v!line\v!rightmargin}{\doxalignline\donefalse ++\rightmargintotal\relax\hss }
+\setvalue{\s!do\v!line\v!leftedge }{\doxalignline\donefalse --\leftedgetotal \hss \relax}
+\setvalue{\s!do\v!line\v!rightedge }{\doxalignline\donefalse ++\rightedgetotal \relax\hss }
+
+% ! ! ! beware, redefining \doalignline gives the wrong results ! ! !
+%
+% \def\doalignline{\doxalignline\donefalse++\zeropoint}
+
+%D Better:
+
+\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}
+
+% \def\alignedline#1#2% setting default
+% {\csname
+% \s!do\v!line
+% \ifundefined{\s!do\v!line#1}#2\else#1\fi
+% \endcsname}
+
+\def\alignedline#1#2% setting default
+ {\csname\s!do\v!line\ifcsname\s!do\v!line#1\endcsname#1\else#2\fi\endcsname}
+
+%D ...
+
+\def\dosetuptolerance[#1]%
+ {\doifinsetelse\v!vertical{#1}%
+ {\ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!verystrict=>\def\bottomtolerance{},
+ \v!strict=>\def\bottomtolerance{.050},
+ \v!tolerant=>\def\bottomtolerance{.075},
+ \v!verytolerant=>\def\bottomtolerance{.100}]}%
+ {\ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!stretch=>\emergencystretch\bodyfontsize,
+ \v!space=>\spaceskip.5em\!!plus.25em\!!minus.25em\relax,
+ \v!verystrict=>\tolerance 200,
+ \v!strict=>\tolerance1500,
+ \v!tolerant=>\tolerance3000,
+ \v!verytolerant=>\tolerance4500]}}
+
+\def\setuptolerance
+ {\dosingleargument\dosetuptolerance}
+
+% \def\woordrechts
+% {\groupedcommand{\hfill\hbox}{\parfillskip\zeropoint}}
+
+% beware: \wordright{whatever\kern-\rightskip} should work!
+% so, no funny boxing here
+
+\def\dowordright[#1]%
+ {% don't change
+ \groupedcommand
+ {\removeunwantedspaces
+ \hfill
+ \allowbreak % changed back from \hskip\zeropoint
+ \strut
+ \hfill
+ \quad % decent spacing
+ \hbox}
+ {\doifelse{#1}\v!right{\kern-\rightskip}{\doifsomething{#1}{\kern-#1}}%
+ \parfillskip\zeropoint
+ %\finalhyphendemerits\zerocount % yes or no
+ \par}}
+
+\def\wordright
+ {\dosingleempty\dowordright}
+
+% \dorecurse{5}{something } \wordright{--someone} \endgraf
+% \dorecurse{6}{something } \wordright{--someone} \endgraf
+% \dorecurse{7}{something } \wordright{--someone} \endgraf
+%
+% \dorecurse{5}{something } \wordright{--someone else entirely} \endgraf
+% \dorecurse{6}{something } \wordright{--someone else entirely} \endgraf
+% \dorecurse{7}{something } \wordright{--someone else entirely} \endgraf
+%
+% \wordright[\rightskip]{whatever}
+
+% \simplealignedbox{2cm}{right}{x}
+
+\setvalue{\s!simple\c!align\v!right }#1#2{\hbox to #1{#2\hss}}
+\setvalue{\s!simple\c!align\v!left }#1#2{\hbox to #1{\hss#2}}
+\setvalue{\s!simple\c!align\v!flushright }#1#2{\hbox to #1{\hss#2}}
+\setvalue{\s!simple\c!align\v!flushleft }#1#2{\hbox to #1{#2\hss}}
+\setvalue{\s!simple\c!align\v!middle }#1#2{\hbox to #1{\hss#2\hss}}
+
+\def\simplealignedbox#1{\executeifdefined{\s!simple\c!align#1}{\getvalue{\s!simple\c!align\v!right}}}
+
+%D \macros
+%D {pushindentation,popindentation}
+%D
+%D The pushing and popping is done by:
+
+\newbox\indentationboxA
+\newbox\indentationboxB
+
+\def\pushindentation
+ {\bgroup
+ \ifhmode
+ \unskip
+ \setbox\indentationboxA\lastbox % get \strut if present
+ \unskip
+ \setbox\indentationboxB\lastbox % get \indent generated box
+ \unskip
+ \else
+ \hskip\zeropoint % switch to horizontal mode
+ \unskip
+ \setbox\indentationboxA\lastbox % get \indent generated box
+ \setbox\indentationboxB\emptybox
+ \fi}
+
+\def\popindentation
+ {\box\indentationboxB\box\indentationboxA % put back the boxes
+ \egroup}
+
+%D The only complication lays in \type{\strut}. In \PLAIN\
+%D \TEX\ a \type{\strut} is defined as:
+%D
+%D \starttyping
+%D \def\strut%
+%D {\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
+%D \stoptyping
+%D
+%D But what is a \type{\strut}? Normally it's a rule of width
+%D zero, but when made visual, it's a rule and a negative skip.
+%D The mechanism for putting things in the margins described
+%D here cannot handle this situation very well. One
+%D characteristic of \type{\strut} is that the \type{\unhcopy}
+%D results in entering horizontal mode, which in return leads
+%D to some indentation.
+%D
+%D To serve our purpose a bit better, the macro \type{\strut}
+%D can be redefined as:
+%D
+%D \starttyping
+%D \def\strut
+%D {\relax\ifmmode\else\hskip0pt\fi\copy\strutbox}
+%D \stoptyping
+%D
+%D Or more compatible:
+%D
+%D \starttyping
+%D \def\strut
+%D {\relax\ifmmode
+%D \copy\strutbox
+%D \else
+%D \bgroup\setbox\strutbox=\normalhbox{\box\strutbox}\unhcopy\strutbox\egroup
+%D \fi}
+%D \stoptyping
+%D
+%D In \CONTEXT\ however we save some processing time by putting
+%D an extra \type{\hbox} around the \type{\strutbox}.
+
+% moved from page-lin.tex to here (due to visualization added
+% in august 2003)
+%
+% \unexpanded \def\crlf
+% {\ifhmode\unskip\else\strut\fi\ifcase\raggedstatus\hfil\fi\break}
+
+\unexpanded \def\crlf
+ {\ifhmode
+ \unskip
+ \prewordbreak\crlfplaceholder
+ \ifcase\raggedstatus\hfil\or\or\or\hfil\fi
+ \break
+ \else
+ \crlfplaceholder
+ \endgraf
+ \fi}
+
+\def\crlfplaceholder
+ {\strut}
+
+\def\settestcrlf
+ {\def\crlfplaceholder
+ {\hbox to \zeropoint
+ {\strut{\infofont\kern.25em}\lohi{\infofont CR}{\infofont LF}\hss}}}
+
+%D \starttyping
+%D % \setuplayout[gridgrid=yes] \showgrid
+%D
+%D \startbuffer
+%D test 1\crlf
+%D test 2\crlf
+%D
+%D \crlf test 3
+%D
+%D test 4\crlf
+%D test 5
+%D
+%D \crlf
+%D \crlf
+%D \crlf
+%D test 6
+%D \stopbuffer
+%D
+%D \hbox
+%D {\hsize5em
+%D \ruledvtop{\getbuffer}\enspace
+%D \ruledvtop{\showstruts\getbuffer}\enspace
+%D \hsize15em \setuptyping[before=,after=]%
+%D \ruledvtop{\typebuffer}}
+%D \stoptyping
+
+\def\opeenregel % to be used grouped
+ {\def\crlf{\removelastspace\space}\let\\\crlf}
+
+\def\showstruts
+ {\setteststrut
+ \settestcrlf}
+
+\def\definehspace
+ {\dotripleempty\dodefinehspace}
+
+\def\dodefinehspace[#1][#2][#3]% #1 = optional namespace
+ {\ifthirdargument
+ \setvalue{\??hs#1:#2}{#3}%
+ \else
+ \setvalue{\??hs:#1}{#2}%
+ \fi}
+
+\unexpanded\def\hspace
+ {\dodoubleempty\dohspace}
+
+%\def\dohspace[#1][#2]%
+% {\ifhmode
+% \removeunwantedspaces
+% \hskip
+% \ifsecondargument
+% \hspaceamount{#1}{#2}%
+% \else
+% \hspaceamount\empty{\iffirstargument#1\else\s!default\fi}%
+% \fi
+% \expandafter\ignorespaces
+% \fi}
+
+\def\dohspace[#1][#2]%
+ {\ifsecondargument
+ \dodohspace[#1][#2]%
+ \else\iffirstargument
+ \hspace[][#1]%
+ \else
+ \hspace[][\s!default]%
+ \fi\fi}
+
+% \def\dodohspace[#1][#2#3]%
+% {\ifhmode
+% \removeunwantedspaces
+% \doifelse{#2}{-}
+% {{\scratchskip\hspaceamount{#1}{#3}\hskip-\scratchskip}}
+% {\hskip\hspaceamount{#1}{#2#3}}%
+% \expandafter\ignorespaces
+% \fi}
+%
+% not needed, tex handles -- as +
+
+\def\dodohspace[#1][#2]%
+ {\ifhmode
+ \removeunwantedspaces
+ \hskip\hspaceamount{#1}{#2}%
+ \expandafter\ignorespaces
+ \fi}
+
+\def\hspaceamount#1#2%
+ {\executeifdefined{\??hs#1:#2}{\executeifdefined{\??hs:#2}\zeropoint}}
+
+\definehspace [\v!small] [.25\emspaceamount]
+\definehspace [\v!medium] [.5\emspaceamount]
+\definehspace [\v!big] [1\emspaceamount]
+\definehspace [\v!normal] [1\spaceamount]
+\definehspace [\v!default] [\spaceamount]
+
+%D Taken from Taco's math module (cq. \AMS\ macros), but
+%D adapted to \type {\hspace}:
+
+\unexpanded\def\textormathspace#1#2#3%
+ {\ifmmode\mskip#1#2\else\kern#1\hspaceamount\empty{#3}\fi\relax}
+
+\newmuskip\hairmuskip \hairmuskip=.15mu
+
+\def\hairspace {\textormathspace+\hairmuskip{.5}}
+\def\thinspace {\textormathspace+\thinmuskip 1}
+\def\medspace {\textormathspace+\medmuskip 2}
+\def\thickspace {\textormathspace+\thickmuskip3}
+\def\neghairspace {\textormathspace-\thinmuskip{.5}}
+\def\negthinspace {\textormathspace-\thinmuskip 1}
+\def\negmedspace {\textormathspace-\medmuskip 2}
+\def\negthickspace{\textormathspace-\thickmuskip3}
+
+% needed for unicode:
+
+\def\twoperemspace {\hskip\dimexpr\emwidth/2\relax} % == \enspace
+\def\threeperemspace {\hskip\dimexpr\emwidth/3\relax}
+\def\fourperemspace {\hskip\dimexpr\emwidth/4\relax}
+\def\fiveperemspace {\hskip\dimexpr\emwidth/5\relax} % goodie
+\def\sixperemspace {\hskip\dimexpr\emwidth/6\relax}
+\def\figurespace {\begingroup\setbox\scratchbox\hbox{0}\hskip\wd\scratchbox\endgroup} % there is a command for this
+\def\punctuationspace {\begingroup\setbox\scratchbox\hbox{.}\hskip\wd\scratchbox\endgroup}
+\def\ideographicspace {\hskip\dimexpr\emwidth/1\relax}
+\def\ideographichalffillspace{\hskip\dimexpr\emwidth/2\relax}
+%def\nobreakspace {\penalty\plustenthousand\space}
+\def\nobreakspace {\penalty\plustenthousand\kern\interwordspace}
+\def\narrownobreakspace {\penalty\plustenthousand\thinspace}
+%def\zerowidthnobreakspace {\penalty\plustenthousand\hskip\zeropoint}
+\def\zerowidthnobreakspace {\penalty\plustenthousand\kern\zeropoint}
+\def\zerowidthspace {\hskip\zeropoint}
+
+\definehspace[.5][.1250\emspaceamount] % could also be [.1250\spaceamount]
+\definehspace[1] [.1667\emspaceamount]
+\definehspace[2] [.2222\emspaceamount]
+\definehspace[3] [.2777\emspaceamount]
+
+\let \, \thinspace
+\let \: \medspace
+\let \; \thickspace
+\let \! \negthinspace
+
+% this will become an alternative bunch of \blank settings
+%
+% \startlines
+% \scratchskip=.23pt plus 10pt minus 4pt \relax \number\scratchskip \space \the\scratchskip
+% \setsimplifiedskip\scratchskip1 \number\scratchskip \space \the\scratchskip
+% \setsimplifiedskip\scratchskip2 \number\scratchskip \space \the\scratchskip
+% \getsimplifiedskip\scratchskip\scratchcounter \number\scratchcounter
+% \stoplines
+%
+% \hrule width10cm \endgraf
+% \discardedskip{10pt}
+% \retainedskip {4pt}
+% \discardedskip {5pt}
+% \hrule width10cm \endgraf
+% \blockedskip{0pt}
+% \discardedskip{10pt}
+% \retainedskip {4pt}
+% \discardedskip {5pt}
+% \hrule width10cm \endgraf
+% \frozenskip {4cm}
+% \hrule width10cm \endgraf
+% \vskip10pt
+% \hrule width10cm \endgraf
+
+% ! ! ! etex only, evt splitskip macro gebruiken (syst-new)
+
+\newskip\simplifiedskip
+\newskip\simplifiedcounter
+
+\chardef\@@discardedskip1
+\chardef\@@retainedskip 2
+\chardef\@@forcedskip 3
+\chardef\@@blockedskip 4
+\chardef\@@frozenskip 5 % after heads, no break
+
+\def\setsimplifiedskip#1#2%
+ {#1\dimexpr(10\dimexpr(#1/10)) plus \gluestretch#1 minus \glueshrink#1\relax
+ \advance#1\numexpr(#2)sp\relax}
+
+\def\getsimplifiedskip#1#2%
+ {\simplifiedskip#1\relax
+ \ifzeropt\simplifiedskip % \ifdim\simplifiedskip=\zeropoint
+ #2\zerocount
+ \else
+ \simplifiedcounter\dimexpr10\dimexpr#1/10\relax\relax
+ \advance\simplifiedskip-\simplifiedcounter
+ #2\number\simplifiedskip\relax
+ \fi}
+
+\def\conditionalskip#1#2%
+ {\scratchskip#1\relax
+ \setsimplifiedskip\scratchskip#2\relax
+ \vskip\scratchskip\relax}
+
+\def\defrostskip
+ {\scratchskip\lastskip\penalty50000\normalvskip-\scratchskip\penalty50000\relax}
+
+\def\frozenskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \fi}
+
+\def\discardedskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifcase\scratchcounter
+ \conditionalskip{#1}\@@discardedskip
+ \or % discard
+ \ifdim\lastskip>#1\else
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@discardedskip
+ \fi
+ \or % retain
+ \ifdim\lastskip>#1\else
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@discardedskip
+ \fi
+ \or % forced
+ \conditionalskip{#1}\@@discardedskip
+ \or % ignored
+ \or % frozen
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \else\ifdim#1=\zeropoint\else
+ \vskip#1\relax
+ \fi\fi
+ \fi}
+
+\def\retainedskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifcase\scratchcounter
+ \conditionalskip{#1}\@@retainedskip
+ \or % discard
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@retainedskip
+ \or % retain
+ \ifdim\lastskip>#1\else
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@retainedskip
+ \fi
+ \or % forced
+ \conditionalskip{#1}\@@retainedskip
+ \or % ignored
+ \or % frozen
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \else\ifdim#1=\zeropoint\else
+ \vskip#1\relax
+ \fi\fi
+ \fi}
+
+\def\forcedskip#1%
+ {\endgraf
+ \ifvmode
+ \conditionalskip{#1}\@@forcedskip
+ \fi}
+
+\def\blockedskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifcase\scratchcounter
+ \conditionalskip{#1}\@@blockedskip
+ \or % discard
+ \conditionalskip{#1}\@@blockedskip
+ \or % retain
+ \conditionalskip{#1}\@@blockedskip
+ \or % forced
+ \conditionalskip{#1}\@@blockedskip
+ \or % ignored
+ \or % frozen
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \else\ifdim#1=\zeropoint\else
+ \vskip#1\relax
+ \fi\fi
+ \fi}
+
+% beware, changing this will break some code (like pos/backgrounds)
+
+\newtoks\everyfirstparagraphintro
+\newtoks\everynextparagraphintro
+\newtoks\@@everyparagraphtoks
+
+\chardef\everyparagraphintro\zerocount
+
+\def\setupparagraphintro
+ {\dodoubleempty\dosetupparagraphintro}
+
+\def\dosetupparagraphintro[#1][#2]%
+ {\processallactionsinset
+ [#1]
+ [ \v!reset=>\global\chardef\everyparagraphintro\zerocount
+ \global\everyfirstparagraphintro\emptytoks
+ \global\everynextparagraphintro \emptytoks,
+ \v!first=>\global\chardef\everyparagraphintro\plusone
+ \doglobal\appendtoks#2\to\everyfirstparagraphintro,
+ \v!next=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plusone\fi
+ \doglobal\appendtoks#2\to\everynextparagraphintro,
+ \v!each=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plustwo\fi
+ \doglobal\appendtoks#2\to\everyfirstparagraphintro
+ \doglobal\appendtoks#2\to\everynextparagraphintro]}
+
+%D We can say:
+%D
+%D \starttyping
+%D \setupparagraphintro[first][\index{Knuth}]
+%D \stoptyping
+%D
+%D Maybe more convenient is:
+%D
+%D \starttyping
+%D \flushatparagraph{\index{Zapf}}
+%D \stoptyping
+
+\def\flushatparagraph#1%
+ {\global\chardef\everyparagraphintro\plusone
+ \global\appendtoks{#1}\to\everyfirstparagraphintro}
+
+% \def\doinsertparagraphintro
+% {\ifcase\everyparagraphintro\relax
+% % no data
+% \@@everyparagraphtoks\emptytoks
+% \or
+% % first data
+% \global\chardef\everyparagraphintro\plustwo
+% \@@everyparagraphtoks\everyfirstparagraphintro
+% \global\everyfirstparagraphintro\emptytoks
+% \or
+% % next data
+% \@@everyparagraphtoks\everynextparagraphintro
+% \fi
+% \the\@@everyparagraphtoks}
+
+\def\doinsertparagraphintro
+ {\begingroup
+ \everypar\emptytoks
+ \ifcase\everyparagraphintro\relax
+ % no data
+ \@@everyparagraphtoks\emptytoks
+ \or
+ % first data
+ \global\chardef\everyparagraphintro\plustwo
+ \@@everyparagraphtoks\everyfirstparagraphintro
+ \global\everyfirstparagraphintro\emptytoks
+ \or
+ % next data
+ \@@everyparagraphtoks\everynextparagraphintro
+ \fi
+ \the\@@everyparagraphtoks
+ \endgroup}
+
+\def\insertparagraphintro
+ {\ifcase\everyparagraphintro\else\@EA\doinsertparagraphintro\fi}
+
+% \appendtoksonce\insertparagraphintro\to\everypar % should come last
+
+%D \starttyping
+%D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}]
+%D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}]
+%D \setupparagraphintro[next] [\hbox to 3.5em{\tt NEXT \hss}]
+%D \setupparagraphintro[next] [\hbox to 3.5em{\tt TXEN \hss}]
+%D \setupparagraphintro[each] [\hbox to 3.0em{\tt EACH \hss}]
+%D \setupparagraphintro[each] [\hbox to 3.0em{\tt HCEA \hss}]
+%D
+%D some paragraph \par
+%D some paragraph \par
+%D some paragraph \par
+%D
+%D \definelabel[parnumber]
+%D
+%D \setupparagraphintro[reset,each][\inleft{\slxx\parnumber}]
+%D
+%D some paragraph \par
+%D some paragraph \par
+%D some paragraph \par
+%D \stoptyping
+
+%D \macros
+%D {flushatnextpar}
+%D
+%D This macro collects data that will be flushed at the next paragraph.
+%D By using this macro you can avoid interfering nodes (writes, etc).
+
+\newbox \postponednodedata
+
+\def\flushatnextpar
+ {\bgroup
+ \dowithnextbox
+ {\global\setbox\postponednodedata\hbox{\box\postponednodedata\box\nextbox}\egroup}%
+ \hbox}
+
+\def\flushpostponednodedata
+ {\ifvoid\postponednodedata\else
+ \hbox{\smashedbox\postponednodedata}%
+ \fi}
+
+% Very nasty but needed for margin stuff inside colored
+% paragraphs.
+
+\let\normalvadjust\vadjust
+
+% \def\graphicvadjust % bad, those low level color calls here
+% {\dowithnextbox
+% {\normalvadjust
+% {\dostartgraphicgroup
+% \localstarttextcolor
+% \unvbox\nextbox
+% \localstoptextcolor
+% \dostopgraphicgroup}}%
+% \vbox}
+
+% test this prikkels/pascal margin text before heads (mode
+% 1) as well as uitwerkingen (mode 2)
+
+%chardef\graphicvadjustmode=0 % fake
+%chardef\graphicvadjustmode=1 % normal
+\chardef\graphicvadjustmode=2 % normal + compensate (== default)
+
+\def\graphicvadjust % bad, those low level color calls here
+ {\dowithnextboxcontent
+ {\forgetall}
+ {\ifcase\graphicvadjustmode \@EA \fakedvadjust \else \@EA\normalvadjust \fi
+ {\dostartgraphicgroup % don't ask
+ \localstarttextcolor
+ \unvbox\nextbox
+ \localstoptextcolor % don't ask
+ \dostopgraphicgroup
+ \ifcase\graphicvadjustmode \or \or
+ % corrects for one line paragraphs
+ \nointerlineskip
+ \kern-\struttotal
+ \nointerlineskip
+ \verticalstrut
+ \fi}}%
+ \vbox}
+
+%D This works only in a properly strutted line, and is meant
+%D for deeply burried operations, like in heads.
+
+\def\fakedvadjust
+ {\dowithnextbox
+ {\setbox\nextbox\hbox{\llap{\lower\strutdepth\box\nextbox}}%
+ \smashedbox\nextbox}%
+ \vtop}
+
+\def\flexiblespaceamount#1#2#3%
+ {#1\interwordspace
+ \!!plus#2\interwordstretch
+ \!!minus#3\interwordshrink}
+
+\def\fixedspaceamount#1%
+ {#1\interwordspace}
+
+%D This is a dangerous feature because it makes the \TEX\ source
+%D less portable, i.e. any parser now needs to apply exactly the
+%D same algorithm when it wants to interpret the source. We
+%D strongly recommend not to mention this feature in manuals! It's
+%D provided for users who are hooked to such a mechanism.
+%D
+%D \starttyping
+%D \setupsorting[logo][next=\autoinsertnextspace] \logo[TEX]{\TeX}
+%D
+%D bla bla \TEX bla bla \TEX (bla) bla (\TEX)
+%D \stoptyping
+
+\def\autoinsertnextspace{\futurelet\nexttoken\doautoinsertnextspace}
+
+\def\doautoinsertnextspace % slightly extended version of a user supplied macro
+ {\ifx\nexttoken \bgroup\else \ifx\nexttoken\begingroup\else
+ \ifx\nexttoken \egroup\else \ifx\nexttoken \endgroup\else
+ \ifx\nexttoken \/\else \ifx\nexttoken /\else \ifx\nexttoken ~\else
+ \ifx\nexttoken \ \else \ifx\nexttoken \blankspace\else \ifx\nexttoken \space\else
+ \ifx\nexttoken .\else \ifx\nexttoken ,\else
+ \ifx\nexttoken !\else \ifx\nexttoken ?\else
+ \ifx\nexttoken :\else \ifx\nexttoken ;\else
+ \ifx\nexttoken '\else \ifx\nexttoken "\else
+ \ifx\nexttoken )\else \ifx\nexttoken -\else \ifx\nexttoken |\else
+ \ifx\nexttoken \%\else \ifx\nexttoken \&\else
+ \space
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% moved from page-lin
+
+\def\installspacehandler#1#2% needs to set \obeyedspace
+ {\setvalue{\??sr#1}{#2}}
+
+\installspacehandler \v!on
+ {\obeyspaces
+ \def\obeyedspace{\mathortext\normalspace{\dontleavehmode{\tt\controlspace}}}%
+ \let\ =\obeyedspace}
+
+\installspacehandler \v!yes
+ {\obeyspaces
+ \def\obeyedspace{\mathortext\normalspace{\dontleavehmode \normalspace }}%
+ \let\ =\obeyedspace}
+
+\installspacehandler \v!off
+ {\normalspaces
+ \let\obeyedspace\normalspace
+ \let\ =\normalspace}
+
+\installspacehandler \v!fixed
+ {\obeyspaces
+ \def\obeyedspace{\mathortext\normalspace{\dontleavehmode\fixedspace}}%
+ \let\ =\obeyedspace}
+
+\def\activatespacehandler#1%
+ {\executeifdefined{\??sr#1}{\activatespacehandler\v!off}}
+
+% moved from page-lin
+
+%D When spacing is active we need to handle commands in
+%D a special way:
+%D
+%D \starttyping
+%D \setuplines[space=on]
+%D
+%D \startlines
+%D Let's talk about this{\ttsl\gobbleoneargument or}that.
+%D \stoplines
+%D
+%D \startlines
+%D Let's talk about this{\getvalue{ttsl}or}that.
+%D \stoplines
+%D \stoptyping
+%D
+%D One can indent in several ways:
+%D
+%D \starttyping
+%D \setupindenting[medium] \setuplines[indenting=odd] % no yes odd even
+%D
+%D \startlines
+%D first
+%D second
+%D third
+%D fourth
+%D \stoplines
+%D \stoptyping
+
+\def\setuplines
+ {\dodoubleargument\getparameters[\??rg]}
+
+\def\startlines
+ {\@@rgbefore
+ \pushmacro\checkindentation
+ \whitespace
+ %\page[\v!preference]} gaat mis na koppen, nieuw: later \nobreak
+ \begingroup
+ \setupindenting[\@@rgindenting]%
+ \typesettinglinestrue
+ \setupwhitespace[\v!none]%
+ \obeylines
+ \ignorespaces
+ \gdef\afterfirstobeyedline % tzt two pass, net als opsomming
+ {\gdef\afterfirstobeyedline
+ {\nobreak
+ \global\let\afterfirstobeyedline\relax}}%
+ \def\obeyedline
+ {\par
+ \afterfirstobeyedline
+ \futurelet\next\dobetweenthelines}%
+ \activatespacehandler\@@rgspace
+ \GotoPar}
+
+\def\stoplines
+ {\endgroup
+ \popmacro\checkindentation
+ \@@rgafter}
+
+\def\dobetweenthelines
+ {\doifmeaningelse\next\obeyedline\@@rginbetween\donothing}
+
+\setuplines
+ [\c!before=\blank,
+ \c!after=\blank,
+ \c!inbetween=\blank,
+ \c!indenting=\v!no,
+ \c!space=\v!default]
+
+\def\emptylines
+ {\dosingleempty\doemptylines}
+
+\def\doemptylines[#1]%
+ {\endgraf\dorecurse{\iffirstargument#1\else3\fi}\crlf}
+
+\setupwhitespace
+ [\v!none]
+
+% still old-fashioned
+
+\indenting
+ [\v!never]
+
+\setupindenting
+ [\v!none]
+
+\setupblank
+ [\v!standard,
+ \v!big]
+
+\defineblank[\v!default] [\currentblank]
+\defineblank[\v!before] [\v!default]
+\defineblank[\v!inbetween][\v!default]
+\defineblank[\v!after] [\v!before]
+
+\setupinterlinespace
+ [\c!minheight=0pt, % only special purpose
+ \c!mindepth=0pt, % only special purpose
+ \c!height=.72,
+ \c!depth=.28,
+ \c!top=1.0,
+ \c!bottom=0.4,
+ \c!distance=1pt,
+ \c!line=2.8ex,
+ \c!stretch=0]
+
+\setupnarrower
+ [\c!before=\endgraf,
+ \c!after=\endgraf,
+ \c!left=1.5em,
+ \c!right=1.5em,
+ \c!middle=1.5em]
+
+\setuptolerance
+ [\v!horizontal,\v!verystrict]
+
+\setuptolerance
+ [\v!vertical,\v!strict]
+
+\setupalign
+ [\v!bottom,
+ \v!width]
+
+\setupspacing
+ [\v!packed]
+
\protect \endinput
diff --git a/tex/context/base/core-spa.mkiv b/tex/context/base/core-spa.mkiv
index 8c1df68dc..dfb84da53 100644
--- a/tex/context/base/core-spa.mkiv
+++ b/tex/context/base/core-spa.mkiv
@@ -11,289 +11,2794 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Buffers}
+\writestatus{loading}{ConTeXt Core Macros / Spacing}
+
+% to be sorted out: dependencies, order of initialization / also some dutch code here
+% more documentation in the mkii file
\unprotect
-% category:
-%
-% 0 == discard
-% 1 == only if larger
-% 2 == force even if smaller
-% 3 == only take penalty component
-% 4 == add to existing skip
-% 5 == ignore following skips (== disable)
+% some will move to core-var
-% penalty:
+\newif \ifgridsnapping
+\newif \iffuzzyvskip
+\let \fuzzyvskip \gobbleoneargument
+\let \removelastfuzzyvskip \relax
+
+\let \startbaselinecorrection \relax
+\let \stopbaselinecorrection \relax
+\let \baselinecorrection \relax
+\let \offbaselinecorrection \relax
+
+\appendtoks \spacing 1\to \everybodyfont
+\appendtoks \presetnormallineheight \to \everybodyfont
+\appendtoks \setnormalbaselines \to \everybodyfont % check if redundant
+\appendtoks \setstrut \to \everybodyfont % check if redundant
+\appendtoks \settopskip \to \everybodyfont
+\appendtoks \setmaxdepth \to \everybodyfont
+%appendtoks \spacing 1\to \everybodyfont
+\appendtoks \simplesetupindenting \to \everybodyfont
+\appendtoks \simplesetupblank \to \everybodyfont
+\appendtoks \simplesetupwhitespace \to \everybodyfont
+%appendtoks \checknotes \to \everybodyfont % not
+\appendtoks \simplesetupspacing \to \everybodyfont % nieuw
+\appendtoks \setrelativeinterlinespace \to \everybodyfont
+
+\appendtoks \updateraggedskips \to \everyfontswitch % under test
+\prependtoks \let\par\endgraf \to \everypagebody % see \fillinline
+\appendtoks \simplesetupspacing \to \everydefinedfont
+
+% if you want to hyphenate the first word of a paragraph ... \appendtoks\hskip0pt\to\everypar
+
+\def\stelfactorenin
+ {\simplesetupwhitespace
+ \simplesetupblank
+ \settopskip
+ \setmaxdepth}
+
+\def\softbreak
+ {\relax\ifhmode\hskip\parfillskip\break\fi}
+
+\let\poplastnode\relax
+
+\def\pushlastnode
+ {\ifdim\lastskip=\zeropoint
+ \ifnum\lastpenalty=\zerocount
+ \ifnum\lastkern=\zerocount
+ \let\poplastnode\relax
+ \else
+ \edef\poplastnode{\kern\the\lastkern\relax}\kern-\lastkern % untested
+ \fi
+ \else
+ \edef\poplastnode{\penalty\the\lastpenalty\relax}\nobreak % untested
+ \fi
+ \else
+ \edef\poplastnode{\vskip\the\lastskip\relax}\vskip-\lastskip % \removelastskip
+ \fi}
+
+%D The dreadful sequence \type {\bgroup} \unknown\
+%D \type {\carryoverpar} \unknown\ \type {\egroup} is needed
+%D when for instance sidefloats are used in combination with
+%D something that starts with a group. This is because
+%D otherwise the indentation as set (by the output routine)
+%D inside the group are forgotten afterwards. (I must
+%D not forget its existence).
+
+\global\let\carriedoverpar\relax
+
+\def\carryoverpar#1%
+ {\expanded % \scratchtoks{#1}%
+ {\noexpand#1% \the\scratchtoks
+ \hangindent\the\hangindent
+ \hangafter \the\hangafter
+ \parskip \the\parskip
+ \leftskip \the\leftskip
+ \rightskip \the\rightskip}}
+
+%D A quick way to determine left|/|middle|/|right states
+%D (experimental).
+
+\setvalue{\??as\v!left }{0}
+\setvalue{\??as\v!middle}{1}
+\setvalue{\??as\v!right }{2}
+
+\def\setalignmentswitch#1%
+ {\chardef\alignmentswitch0\csname\??as#1\endcsname\relax}
+
+%D There are two ways to influence the interline spacing. The
+%D most general and often most consistent way is using
+%D
+%D \showsetup{setupinterlinespace}
+%D
+%D For instance
+%D
+%D \starttyping
+%D \setupinterlinespace[line=2.8ex]
+%D \stoptyping
+%D
+%D This setting adapts itself to the bodyfontsize, while for
+%D instance saying
+%D
+%D \starttyping
+%D \setupinterlinespace[line=12pt]
+%D \stoptyping
+%D
+%D sets things fixed for all sizes, which is definitely not
+%D what we want. Therefore one can also say:
+%D
+%D \starttyping
+%D \definebodyfontenvironment[9pt][interlinespace=11pt]
+%D \stoptyping
+%D
+%D One can still use \type{\setupinterlinespace} (without
+%D arguments) to set the interline space according to the
+%D current font, e.g. a \type{\bfa}.
+
+\newif\iflocalinterlinespace
+
+% font-ini
+
+\ifx\bodyfontinterlinespecs\undefined
+
+ \let\bodyfontinterlinespecs\empty
+ \let\bodyfontinterlinespace\empty
+
+\fi
+
+\def\presetnormallineheight
+ {\edef\normallineheight{\@@itline}%
+% done elsewhere : \spacing\!!plusone % new per 10/08/2004, else problems in otr / !! needed
+ \iflocalinterlinespace \else
+ \doifdefined\bodyfontinterlinespecs
+ {\doifsomething\bodyfontinterlinespace
+ {\edef\normallineheight{\bodyfontinterlinespace}}}%
+ \fi}
+
+\def\setupspecifiedinterlinespace[#1]%
+ {\getparameters[\??it][#1]%
+ \scratchdimen0\@@itheight\points
+ \advance\scratchdimen 0\@@itdepth\points
+ \ifdim\scratchdimen>\onepoint
+ \showmessage\m!layouts{10}{\@@itheight,\@@itdepth}%
+ \let\@@itheight\strutheightfactor
+ \let\@@itdepth \strutdepthfactor
+ \else
+ \let\strutheightfactor\@@itheight
+ \let\strutdepthfactor \@@itdepth
+ \fi
+ \let\minimumstrutheight \@@itminheight
+ \let\minimumstrutdepth \@@itmindepth
+ \let\minimumlinedistance\@@itdistance
+ \let\normallineheight \@@itline % let ! ! ! ! ! ivm ex
+ \doifelse\@@ittop\v!height % new, topskip does more bad than good
+ {\let\topskipfactor \@@itheight}
+ {\let\topskipfactor \@@ittop }%
+ \let\maxdepthfactor \@@itbottom
+ \let\baselinegluefactor \@@itstretch
+ \setfontparameters % redundant, can be \setstrut, test first
+ \updateraggedskips} % yes indeed
+
+\let\currentrelativeinterlinespace\empty
+
+\def\setuprelativeinterlinespace[#1]%
+ {\processallactionsinset
+ [#1]
+ [ \v!on=>\oninterlineskip,
+ \v!off=>\offinterlineskip,
+ \v!reset=>\let\currentrelativeinterlinespace\empty
+ \let\setrelativeinterlinespace\relax
+ \setfontparameters,
+ \v!auto=>\let\setrelativeinterlinespace\dosetrelativeinterlinespace,
+ \s!unknown=>\assignvalue\commalistelement\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
+ \spacing\currentrelativeinterlinespace]}
+
+\def\dosetrelativeinterlinespace
+ {\ifx\currentrelativeinterlinespace\empty\else
+ \spacing\currentrelativeinterlinespace
+ \fi}
+
+\let\setrelativeinterlinespace\relax
+
+% \appendtoks \setrelativeinterlinespace \to \everybodyfont
+
+\def\complexsetupinterlinespace[#1]% \commalistelement ipv #1
+ {\doifassignmentelse{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]}
+
+\def\setuplocalinterlinespace[#1]%
+ {\localinterlinespacetrue
+ \setupinterlinespace[#1]%
+ \localinterlinespacefalse}
+
+\def\simplesetupinterlinespace
+ {\localinterlinespacetrue
+ \setfontparameters
+ \updateraggedskips % funny one here
+ \localinterlinespacefalse}
+
+\definecomplexorsimple\setupinterlinespace
+
+% In earlier versions \type{\bigskipamount} was
+% \type{\ht\strutbox} and the stretch was plus or minus
+% \type{.4\dp\strutbox}. Don't ask me why. The most recent
+% implementation is based on a user supplied distance, which
+% is by default \type{.75\normalskipamount} where
+% \type{\normalskipamount} equals the current baseline
+% distance.
+
+% \lineskiplimit = -\maxdimen -> freezes baselineskip
+
+% can be conditionals
+
+\newif\ifblanknowhite \blanknowhitefalse
+\newif\ifblankindeed \blankindeedfalse
+\newif\ifblankreset \blankresetfalse
+\newif\ifblankdisable \blankdisablefalse
+\newif\ifblankflexible \blankflexibletrue
+\newif\ifblankouter
+\newif\ifblankforce
+\newif\ifblankgoback
+
+\newskip\blankskip \blankskip=\bigskipamount
+\newskip\blankskipamount
+
+\def\skipfactor {.75}
+\def\skipgluefactor{.25}
+
+\def\normalskipamount
+ {\openlineheight
+ \ifgridsnapping \else \ifblankflexible
+ \!!plus \skipgluefactor\openlineheight
+ \!!minus\skipgluefactor\openlineheight
+ \fi \fi
+ \relax}
+
+\def\linedistance {\normalskipamount}
+\def\appliedblankskip{\skipfactor\linedistance}
+\def\lastblankskip {\blankskip}
+\def\currentblank {\v!big}
+\def\oldprevdepth {\prevdepth}
+\def\newprevdepth {-1001pt}
+\def\mindimen {1sp} % was: 0.00002pt
+
+\newif\iflocalblankfixed
+\newif\iflocalblankflexible
+
+\def\geenblanko{\removelastskip} % will become obsolete
+
+%%%% pas op, wordt ook in core-pos gebruikt
+
+\def\doassignsomeskip#1\to#2% ook nog \v!halfline+fuzzysnap
+ {\doifelse{#1}\v!line
+ {#2\openlineheight}
+ {\ifgridsnapping
+ \assigndimension{#1}{#2}{.25\openlineheight}{.5\openlineheight}\openlineheight
+ \else
+ \assigndimension{#1}{#2}\smallskipamount\medskipamount\bigskipamount
+ \fi}%
+ \relax}
+
+% \relax is really needed, else we may loose stretch due to lookahead; somehow
+% this bug was introduced a while ago but somehow went unnoticed; fixed 2/7/2008
+
+\def\addblankskip#1#2#3{\global\advance\blankskip#1\ifgridsnapping#3\else#2\fi\relax}
+
+\def\defineblankmethod[#1]#2{\setvalue{\??bo\??bo#1}{#2}}
+
+\defineblankmethod [\v!big] {\addblankskip+\bigskipamount \openlineheight}
+\defineblankmethod [-\v!big] {\addblankskip-\bigskipamount \openlineheight}
+\defineblankmethod [\v!medium] {\addblankskip+\medskipamount {.5\openlineheight}}
+\defineblankmethod [-\v!medium] {\addblankskip-\medskipamount {.5\openlineheight}}
+\defineblankmethod [\v!small] {\addblankskip+\smallskipamount{.25\openlineheight}}
+\defineblankmethod [-\v!small] {\addblankskip-\smallskipamount{.25\openlineheight}}
+\defineblankmethod [\v!white] {\addblankskip+\parskip \openlineheight}
+\defineblankmethod [-\v!white] {\addblankskip-\parskip \openlineheight}
+\defineblankmethod [\v!line] {\addblankskip+\openlineheight \openlineheight}
+\defineblankmethod [-\v!line] {\addblankskip-\openlineheight \openlineheight}
+
+\defineblankmethod [\v!formula] {\global\advance\blankskip\medskipamount}
+\defineblankmethod [\v!nowhite] {\global\blanknowhitetrue}
+\defineblankmethod [\v!disable] {\global\blankdisabletrue}
+\defineblankmethod [\v!force] {\global\blankforcetrue}
+\defineblankmethod [\v!outer] {\ifvmode\ifinner\blankoutertrue\fi\fi}
+\defineblankmethod [\v!reset] {\global\blankresettrue}
+\defineblankmethod [\v!flexible] {\global\localblankflexibletrue}
+\defineblankmethod [\v!fixed] {\global\localblankfixedtrue}
+\defineblankmethod [\v!back] {\global\blankgobacktrue} % {\geenblanko}
+\defineblankmethod [\v!halfline] {\ifgridsnapping\global\fuzzyvskiptrue\fi
+ \global\advance\blankskip .5\lineheight}
+
+\defineblankmethod [\v!none] {\global\blankresettrue}
+\defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi}
+
+\defineblankmethod [\v!always] {\redowhitespace} % experimental
+
+% happens often, so we speed this up:
%
-% larger wins
+% \defineblankmethod [2*\v!line] {\addblankskip+{2\openlineheight}{2\openlineheight}}
+% \defineblankmethod [2*\v!big] {\addblankskip+{2\bigskipamount }{2\openlineheight}}
+%
+% no, with 2\whatever we loose the stretch and shrink! Taco's alternative:
-% order:
+\defineblankmethod
+ [2*\v!line]
+ {\addblankskip+\openlineheight\openlineheight
+ \addblankskip+\openlineheight\openlineheight}
+
+\defineblankmethod
+ [2*\v!big]
+ {\addblankskip+\bigskipamount\openlineheight
+ \addblankskip+\bigskipamount\openlineheight}
+
+\def\doblank#1%
+ {\edefconvertedargument\ascii{#1}%
+ \ifx\ascii\empty\else
+ \ifcsname\??bo\??bo\ascii\endcsname % internal def
+ \csname\??bo\??bo\ascii\endcsname
+ \else\ifcsname\??bo\ascii\endcsname % user def / slow
+ \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
+ \else
+ \dorepeatwithcommand[#1]\redoblank
+ \fi\fi
+ \fi
+ \relax}
+
+\def\redoblank#1%
+ {\edefconvertedargument\ascii{#1}%
+ \ifx\ascii\empty\else
+ \ifcsname\??bo\??bo\ascii\endcsname % internal def
+ \csname\??bo\??bo\ascii\endcsname
+ \else\ifcsname\??bo\ascii\endcsname % user def / slow
+ \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
+ \else
+ \global\advance\blankskip#1\relax
+ \fi\fi
+ \fi
+ \relax}
+
+\unexpanded\def\blank % the \relax is definitely needed due to the many \if's
+ {\relax\complexorsimple\doblank}
+
+\def\complexdoblank
+ {\flushnotes
+ \ifmmode
+ \@EA\nocomplexdoblank
+ \else
+ \ifopelkaar
+ \ifinpagebody
+ \@EA\@EAEAEA\@EA\docomplexdoblank
+ \else
+ \@EA\@EAEAEA\@EA\nocomplexdoblank
+ \fi
+ \else
+ \@EAEAEA\docomplexdoblank
+ \fi
+ \fi}
+
+\def\nocomplexdoblank[#1]%
+ {% evt blokkeerfalse
+ \ifmmode\else\par\fi}
+
+% Overloaded in cont-new!
+
+\newsignal\noblanksignal
+
+% problem: we cannot look back in the mvl so we need 3 kinds of signals
+
+\def\noblankpsignal{1010101}
+
+\def\inhibitgridblank % was doinhibitblank
+ {\ifvmode\else\endgraf\fi
+ \ifvmode
+ \ifnum\lastpenalty<10000
+ \kern-\noblanksignal % new
+ \kern \noblanksignal
+ \else
+ \penalty\noblankpsignal
+ \fi
+ \fi}
+
+\def\inhibittextblank % was inhibitblank
+ {\endgraf
+ \ifvmode
+ \prevdepth\newprevdepth
+ \fi}
+
+% new macro
%
-% larger wins
+% \def\inhibitblank % need some work
+% {\endgraf
+% \ifvmode
+% \ifgridsnapping
+% \inhibitgridblank
+% \else
+% % this one spoils the grid
+% \inhibittextblank
+% \fi
+% \fi}
-\defineattribute[kern-chars]
+\def\doinhibitblank{\inhibitgridblank}
+\def\inhibitblank {\inhibittextblank}
-\defineattribute[skip-category]
-\defineattribute[skip-penalty]
-\defineattribute[skip-order]
+% will become obsolete
-\defineattribute[snap-category]
+\ifx\undefined\savedlastskip \newskip \savedlastskip \fi
+\ifx\undefined\savedlastpenalty \newcount\savedlastpenalty \fi
-\defineattribute[display-math]
+% beware, prevdepth can have funny values (e.g. mvl value when in box)
-\registerctxluafile{core-spa}{1.001}
+\def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
+ {\global\blankresetfalse
+ \global\blankdisablefalse
+ \global\blanknowhitefalse
+ \global\localblankflexiblefalse
+ \global\localblankfixedfalse
+ \global\blankforcefalse
+ \global\blankgobackfalse
+ \blankouterfalse
+ \global\blankskip\zeropoint
+%
+\edefconvertedargument\ascii{#1}% todo fast check for simple
+\ifcsname\??bo\??bo\ascii\endcsname % internal def
+ \csname\??bo\??bo\ascii\endcsname
+\else\ifcsname\??bo\ascii\endcsname % user def / slow
+ \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
+\else
+ \expanded{\rawprocesscommalist[#1]}\doblank
+\fi\fi
+%
+ \relax % to be sure
+ \ifdim\blankskip=\zeropoint\relax
+ \iflocalblankflexible
+ \doglobal\advance\blankskip \currentblank
+ \else\iflocalblankfixed
+ \doglobal\advance\blankskip \currentblank
+ \fi\fi
+ \fi
+ \relax % to be sure
+ \ifblankouter
+ % do nothing
+ \else
+ \par
+ \ifvmode
+ \ifblankgoback
+ \ifdim\lastskip>\zeropoint \vskip-\lastskip \fi
+ \savedlastskip\zeropoint
+ \else\ifdim\lastskip>\zeropoint
+ \savedlastskip\lastskip
+ \else % todo: lastnode, dan namelijk geen skip !
+ \savedlastskip\zeropoint
+ \fi\fi
+ \ifblankforce
+ % dit gaat mis in pos fonts
+ % \ifdim\prevdepth>\zeropoint\else ...
+ % -1000pt signals top of page or column (\ejectcolumn)
+ \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
+ \savedlastskip\zeropoint
+ \fi
+ \savedlastpenalty\lastpenalty % hm, now it gets lost
+ \ifblankdisable
+ \global\blankindeedfalse % keep this, i.e. disable current too
+ \ifgridsnapping
+ \ifdim\prevdepth<\zeropoint
+ % brrr
+ \else
+ % dirty trick: smaller blanks are ignored after a
+ % larger one, so 10 lines is probably safe; we need
+ % to make sure that we honor penalties; here comes the
+ % trick (cross our fingers that this works well in
+ % multi columns; maybe an ifinner test is needed
+ % \scratchcounter\lastpenalty
+ % \vskip-10\lineheight
+ % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
+ % \vskip 10\lineheight
+ % alas, this leads to overfull pages, so we try this:
+ \inhibitgridblank
+ \fi
+ \else
+ \ifdim\prevdepth<\zeropoint
+ % brrr
+ \else
+ % ensure at least a proper prevdepth, this should be
+ % an option
+ \vskip-\prevdepth
+ \vskip\strutdepth
+ \prevdepth\strutdepth
+ \fi
+ % the old crappy piece of code
+ \edef\oldprevdepth{\the\prevdepth}%
+ \prevdepth\newprevdepth % == \inhibittextblank
+ \fi
+ \else
+ \global\blankindeedtrue
+ \fi
+ \ifblankreset
+ \global\blankindeedtrue
+ \ifgridsnapping
+ % let's play safe and not fool around with the depth, if
+ % only because it took a lot of effort to sort out the grid
+ % stuff in the first place
+ \else
+ \ifdim\prevdepth=\newprevdepth
+ \prevdepth\oldprevdepth
+ \fi
+ \fi
+ \fi
+ \ifblankindeed
+ \ifdim1\savedlastskip<1\blankskip\relax
+ % else when \blank[2*groot] + \blank[3*groot] with parskip
+ % equaling 1*groot, gives a groot=\parskip so adding a small
+ % value makes it distinguishable; can also be done at parskip
+ % setting time (better)
+ \global\advance\blankskip \mindimen\relax % = skip
+ % test this on 2* + 3* and parskip groot
+ \ifblanknowhite
+ \global\advance\blankskip -\parskip
+ \else
+ \ifdim\savedlastskip=\parskip
+ \else % force this due to previous comment
+ \ifdim\parskip>\zeropoint\relax
+ \ifdim\blankskip<\parskip\relax
+ \global\blankskip\zeropoint
+ \else
+ \global\advance\blankskip -\parskip
+ \fi
+ \fi
+ \fi
+ \fi
+ \ifblankflexible \else
+ \blankskip1\blankskip
+ \fi
+ \iflocalblankfixed
+ \blankskip1\blankskip
+ \fi
+ \iflocalblankflexible
+ \blankskip1\blankskip
+ \!!plus \skipgluefactor\blankskip
+ \!!minus\skipgluefactor\blankskip
+ \fi
+ \ifdim\lastkern=\noblanksignal\relax % controlled and grid
+ \global\blankindeedfalse
+ \else\ifnum\savedlastpenalty=\noblankpsignal\relax % controlled and grid
+ \global\blankindeedfalse
+ \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
+ \global\blankindeedfalse
+ \fi\fi\fi\fi
+ \ifblankindeed
+ \iffuzzyvskip
+ \removelastfuzzyvskip
+ \fuzzyvskip\blankskip\relax
+ \else
+ \relax\ifdim\savedlastskip=\zeropoint\else
+ \vskip-\savedlastskip
+ \fi
+ \vskip\blankskip\relax
+ \fi
+ \fi
+ \else
+ \iffuzzyvskip
+ \removelastfuzzyvskip
+ \fuzzyvskip\blankskip\relax
+ \else
+ % new, test this on pascal
+ \ifdim\blankskip<\zeropoint
+ \relax\ifdim\savedlastskip=\zeropoint\else
+ \advance\blankskip-\savedlastskip
+ \vskip-\savedlastskip
+ \fi
+ \ifdim\blankskip>\zeropoint
+ \vskip\blankskip
+ \else
+ \vskip\zeropoint
+ \fi
+ \else
+ % also new
+ \ifdim\blankskip=\zeropoint
+ \ifblanknowhite
+ \nowhitespace
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \global\fuzzyvskipfalse
+ \presetindentation}
-% \start \dosetstretch{.25em} \setuptolerance[tolerant,stretch] \input tufte \endgraf \stop
-% \start \dosetstretch{.5em} effe flink doorfietsen \stop
+%D For a long time we had:
+%D
+%D \starttyping
+%D \def\simpledoblank%
+%D {\doifelse{\currentwhitespace}{\v!geen}
+%D {\blank[\currentblank]}
+%D {\blank[\currentwhitespace]}}
+%D \stoptyping
+%D
+%D But Berend de Boer wanted more control, so now we have:
-\def\dosetstretch#1% to be interfaces
- {\relax\ifdim#1>\zeropoint
- \dosetattribute{kern-chars}{\number\dimexpr#1\relax}%
+\def\simpledoblank % ...
+ {\doifelse\currentwhitespace\v!none
+ {\blank[\currentblank]}
+ {\blank[\s!default]}}
+
+%D Another useful definition would be:
+%D
+%D \starttyping
+%D \defineblank
+%D [\s!default]
+%D [\v!groot]
+%D \stoptyping
+
+\def\dosetupblank#1% amount are an plain inheritance
+ {\bigskipamount#1\relax
+ \ifblankflexible \else
+ \bigskipamount1\bigskipamount
+ \fi
+ \medskipamount \bigskipamount \divide\medskipamount \plustwo
+ \smallskipamount\bigskipamount \divide\smallskipamount\plusfour}%
+
+\def\complexsetupblank[#1]% more \let's -> this also wil become installable
+ {\ifgridsnapping
+ \blankflexiblefalse
\else
- \doresetattribute{kern-chars}%
+ \ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!flexible=>\blankflexibletrue,
+ \v!fixed=>\blankflexiblefalse]%
+ \fi
+ \ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!flexible=>\dosetupblank\appliedblankskip,
+ \v!fixed=>\dosetupblank\appliedblankskip,
+ \v!line=>\edef\appliedblankskip{\linedistance}%
+ \dosetupblank\appliedblankskip,
+ \v!halfline=>\scratchskip.5\linedistance
+ \edef\appliedblankskip{\the\scratchskip}%
+ \dosetupblank\appliedblankskip,
+ \v!big=>\ifgridsnapping
+ \edef\appliedblankskip{\linedistance}%
+ \dosetupblank\appliedblankskip
+ \fi
+ \let\currentblank\v!big,
+ \v!medium=>\let\currentblank\v!medium,
+ \v!small=>\let\currentblank\v!small,
+ \v!global=>\let\currentblank\v!global,
+ \v!normal=>\dosetupblank\appliedblankskip,
+ \v!standard=>\edef\appliedblankskip{\skipfactor\linedistance}%
+ \dosetupblank\appliedblankskip,
+ \s!default=>\dosetupblank\appliedblankskip,
+ \s!unknown=>\let\appliedblankskip\commalistelement
+ \dosetupblank\appliedblankskip]%
+ \simplesetupwhitespace}
+
+% \definecomplexorsimpleempty\setupblank
+%
+% speed gain: 60 sec -> 30 sec
+
+\definecomplexorsimple\setupblank
+
+\def\simplesetupblank % == snelle \setupblank[\s!default]
+ {\ifgridsnapping
+ \blankflexiblefalse
+ \fi
+ \dosetupblank\appliedblankskip
+ % \let\deblanko\v!big
+ \simplesetupwhitespace}
+
+\def\restorestandardblank% \v!standard
+ {\edef\appliedblankskip{\skipfactor\linedistance}%
+ \dosetupblank\appliedblankskip
+ }%\let\deblanko\v!big}
+
+\def\dodefineblank[#1][#2]%
+ {\def\docommand##1{\setvalue{\??bo##1}{#2}}%
+ \processcommalist[#1]\docommand}
+
+\def\defineblank
+ {\dodoubleargument\dodefineblank}
+
+\def\savecurrentblank
+ {\edef\restorecurrentblank
+ {\bigskipamount\the\bigskipamount
+ \medskipamount\the\medskipamount
+ \smallskipamount\the\smallskipamount
+ \noexpand\def\noexpand\currentblank{\currentblank}%
+ \ifblankflexible
+ \noexpand\blankflexibletrue
+ \else
+ \noexpand\blankflexiblefalse
+ \fi}}
+
+%D Now.
+
+\defineblank [\s!default] [\v!white]
+\defineblank [\v!height] [\strutheight]
+\defineblank [\v!depth] [\strutdepth]
+
+\let\currentindentation\empty % amount/keyword
+% \let\normalindentation \empty % used for reinstating normal indentation
+\let\currentindenting \empty % method
+
+\newdimen\ctxparindent
+
+\newif\ifindentfirstparagraph % \indentfirstparagraphtrue
+
+\chardef\indentingtoggle\zerocount
+
+%D After a blank or comparable situation (left side floats) we
+%D need to check if the next paragraph has to be indented.
+
+\def\presetindentation
+ {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}
+
+%D This sets up the (normally) global indentation behavior as well
+%D as the amounts.
+
+\definecomplexorsimple\setupindenting
+
+\indentfirstparagraphtrue
+\parindent\ctxparindent
+\chardef\indentingtoggle\zerocount
+
+% we need a better everypar model: for each option a switch, which we
+% set to false with \forgetall and can enable when needed (context 4);
+% that way we can control the order of execution of options
+
+\def\checkeverypar % currently a hack
+ {\ifzeropt\parindent\else
+ \doifsometokselse\everypar\donothing{\appendtoks\checkindentation\to\everypar}%
\fi}
-\appendtoks\doresetattribute{kern-chars}\to\everyforgetall
+\def\complexsetupindenting[#1]%
+ {\edef\currentindenting{#1}%
+ \doifsomething\currentindenting % handy when a parameter is passed
+ {% not here: \indentfirstparagraphtrue
+ % not here: \parindent\ctxparindent
+ % not here: \chardef\indentingtoggle\zerocount
+ % we use commacommand in order to catch #1 being a command (expanded parameter)
+ \processcommacommand[\currentindenting]\docomplexsetupindentingA % catch small, medium, etc
+ \processcommacommand[\currentindenting]\docomplexsetupindentingB % catch rest
+ \checkeverypar % only when non-empty #1
+ \ifindentfirstparagraph\else\noindentation\fi % added
+ \toggleindentation}}
-\def\mksetupgridsnapping
- {\ctxlua{nodes.setsnapvalue(1,\number\openstrutheight,\number\openstrutdepth)}}
+\def\docomplexsetupindentingA#1%
+ {\edefconvertedargument\!!stringa{#1}%
+ \doifundefined{\??in:\!!stringa}%
+ {\edef\currentindentation{#1}%
+ \let\normalindentation\currentindentation
+ \simplesetupindenting}}
-\def\mkenablegridsnapping
- {\dosetattribute{snap-category}{1}%
- \topskip\strutht
- \offinterlineskip}
+\def\docomplexsetupindentingB#1%
+ {\edefconvertedargument\!!stringa{#1}% catch #1=\somedimen
+ \executeifdefined{\??in:\!!stringa}\donothing}
-\def\mkdisablegridsnapping
- {\doresetattribute{snap-category}%
- % reset topskip
- \oninterlineskip}
+\def\simplesetupindenting % empty case, a it strange, needed this way?
+ {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}}
+
+\def\indenting % kind of obsolete
+ {\dosingleargument\complexsetupindenting}
+
+% use \noindentation to suppress next indentation
+
+\def\defineindentingmethod[#1]#2%
+ {\setvalue{\??in:#1}{#2}}
+
+\defineindentingmethod [\v!no] {\parindent\zeropoint}% was: \ctxparindent\noindent}
+\defineindentingmethod [\v!not] {\parindent\zeropoint}% was: \ctxparindent\noindent}
+
+\defineindentingmethod [\v!first] {\indentfirstparagraphtrue}
+\defineindentingmethod [\v!next] {\indentfirstparagraphfalse}
+
+\defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent !
+\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent !
+
+\defineindentingmethod [\v!never] {\parindent\zeropoint\relax % no \indent !
+ \chardef\indentingtoggle\zerocount}
+
+\defineindentingmethod [\v!odd] {\chardef\indentingtoggle\plusone}
+\defineindentingmethod [\v!even] {\chardef\indentingtoggle\plustwo}
+
+\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else
+ \let\currentindentation\normalindentation
+ \simplesetupindenting
+ \fi}
+
+\defineindentingmethod [\v!reset] {\indentfirstparagraphtrue
+ \parindent\zeropoint
+ \chardef\indentingtoggle\zerocount}
+
+\def\noindenting{\indenting[\v!no, \v!next ]}
+\def\doindenting{\indenting[\v!yes,\v!first]}
+
+%D This one sets up the local indentation behaviour (i.e. either or not
+%D a next paragraph will be indented).
+
+\def\dochecknextindentation#1% internal one
+ {\checknextindentation[\csname#1\c!indentnext\endcsname]}
+
+\setvalue{\??in->\s!empty}{}
+\setvalue{\??in->\v!yes }{\doindentation}
+\setvalue{\??in->\v!no }{\noindentation}
+\setvalue{\??in->\v!auto }{\autoindentation}
+
+\def\checknextindentation[#1]%
+ {\csname\??in->\ifcsname\??in->#1\endcsname#1\else\s!empty\fi\endcsname}
+
+%D Here come the handlers.
+
+\newif\ifindentation \indentationtrue % documenteren, naar buiten
+
+\let\checkindentation\relax
+
+\ifx\autoindentation\undefined \let\autoindentation\relax \fi % hook
+
+\def\doindentation
+ {\gdef\checkindentation{\global\indentationtrue}}
+
+\def\noindentation % made global
+ {\ifinpagebody \else
+ \global\indentationfalse
+ \gdef\checkindentation
+ {\donoindentation
+ \gdef\checkindentation{\global\indentationtrue}}%
+ \fi}
-% experimental mirroring
+\def\nonoindentation % bv bij floats
+ {\ifinpagebody \else
+ \global\indentationtrue
+ \gdef\checkindentation{\global\indentationtrue}%
+ \fi}
-\defineattribute[mirror]
+\def\donoindentation
+ {\ifdim\parindent=\zeropoint \else
+ \bgroup \setbox\scratchbox\lastbox \egroup
+ \fi}
-\def\setcharactermirroring
- {\ctxlua{mirror.enabled=true}%
- \gdef\setcharactermirroring[##1]{\dosetattribute{mirror}{\number##1}}%
- \setcharactermirroring}
+\def\indentation
+ {\ifvmode \ifdim\parindent=\zeropoint \else
+ % was : \hskip\parindent
+ % can be: \indent
+ % but we test:
+ \noindent\hskip\parindent
+ \fi \fi}
-\def\resetcharactermirroring
- {\doresetattribute{mirror}}
+\def\toggleindentation
+ {\ifcase\indentingtoggle
+ % nothing
+ \or
+ \notoggleindentation
+ \or
+ \dotoggleindentation
+ \fi}
-\newtoks\everysetupdirections
+\def\dokillindentation
+ {\gdef\checkindentation{\global\indentationfalse\donoindentation}}
-\def\setupdirections[#1]% there will be more like setting up directions themselves
- {\getparameters[\??di][#1]%
- \the\everysetupdirections}
+\def\dotoggleindentation
+ {\gdef\checkindentation{\global\indentationfalse\notoggleindentation\donoindentation}}
-\chardef\directionsbidimode=0
+\def\notoggleindentation
+ {\gdef\checkindentation{\global\indentationtrue\dotoggleindentation}}
-\letvalue{\??di:bidi:\v!off }\zerocount
-\letvalue{\??di:bidi:\v!global}\plusone
-\letvalue{\??di:bidi:\v!local }\plustwo
-\letvalue{\??di:bidi:\v!on }\plustwo
+\appendtoks
+ \pushmacro\checkindentation
+ \pushmacro\ifindentation
+\to \everypushsomestate
\appendtoks
- \chardef\directionsbidimode\executeifdefined{\??di:bidi:\@@dibidi}\zerocount\relax
- \ifcase\directionsbidimode
- \resetcharactermirroring
- \or
- \setcharactermirroring[1]% global, chars
- \or
- \setcharactermirroring[2]% local, attributes
- \or
- \setcharactermirroring[1]% default
- \fi
-\to \everysetupdirections
+ \popmacro\ifindentation
+ \popmacro\checkindentation
+\to \everypopsomestate
+
+% we need to save the state if we want to adapt behaviour to empty lines
+%
+% \def\setlasthvmode
+% {\global\chardef\savedhvmode\ifhmode\plusone\else\ifvmode\plustwo\else\zerocount\fi\fi}
+%
+% \def\resetlasthvmode
+% {\global\chardef\savedhvmode\zerocount}
+%
+% \chardef\savedhvmode\zerocount
+
+% This is a user requested hack (using the auto-hook).
+
+\chardef\recheckindentationmode\zerocount
+
+\def\dontrechecknextindentation
+ {\global\chardef\recheckindentationmode\zerocount}
+
+\def\dorechecknextindentation
+ {\ifcase\recheckindentationmode
+ % nothing
+ \or
+ \dontrechecknextindentation
+ \expandafter\doautoindentation
+ \fi}
+
+\def\doautoindentation
+ {\doifnextcharelse\par\donothing\noindentation}
+
+\def\autoindentation
+ {\global\chardef\recheckindentationmode\plusone}
+
+%D An example of usage:
+%D
+%D \starttyping
+%D \setupindenting[small,yes]
+%D
+%D \setupitemize [indentnext=auto]
+%D \setuptyping [indentnext=auto]
+%D \setupformulas[indentnext=auto]
+%D
+%D \input tufte
+%D
+%D \startitemize
+%D \item itemize
+%D \stopitemize
+%D \input tufte
+%D
+%D \startitemize
+%D \item itemize
+%D \stopitemize
+%D
+%D \input tufte
+%D
+%D \startitemize
+%D \item itemize
+%D \stopitemize
+%D
+%D \page
+%D
+%D \input tufte
+%D
+%D \starttyping
+%D verbatim
+%D \stoptyping
+%D \input tufte
+%D
+%D \starttyping
+%D verbatim
+%D \stoptyping
+%D
+%D \input tufte
+%D
+%D \starttyping
+%D verbatim
+%D \stoptyping
+%D
+%D \page
+%D
+%D \input tufte
+%D
+%D \startformula
+%D a = b
+%D \stopformula
+%D \input tufte
+%D
+%D \startformula
+%D a = b
+%D \stopformula
+%D
+%D \input tufte
+%D
+%D \startformula
+%D a = b
+%D \stopformula
+
+
+%D \macros
+%D {frenchspacing,nonfrenchspacing}
+%D
+%D Smehow \type{\frenchspacing} can lead to hyphenation between
+%D dashes so we now have \type {\newfrenchspacing} (moved from
+%D \type {syst-chr}).
+
+%D Hm ... todo:
+
+\sfcode`\)=0
+\sfcode`\'=0
+\sfcode`\]=0
+
+\def\setfrenchspacing#1%
+ {\sfcode`\.#1 \sfcode`\,#1\relax
+ \sfcode`\?#1 \sfcode`\!#1\relax
+ \sfcode`\:#1 \sfcode`\;#1\relax}
+
+\def\frenchspacing
+ {\setfrenchspacing{1000}}
+
+\def\resetfrenchspacing
+ {\sfcode`\.3000 \sfcode`\,1250
+ \sfcode`\?3000 \sfcode`\!3000
+ \sfcode`\:2000 \sfcode`\;1500 }
-% bidi: local=obey grouping, global=ignore grouping (unicode has no grouping)
+\def\frenchspacing {\setfrenchspacing{1000}}
+\def\newfrenchspacing{\setfrenchspacing{1050}}
+\def\nonfrenchspacing{\resetfrenchspacing}
-\setupdirections % maybe start/stop
- [bidi=\v!off]
+\def\definespacingmethod[#1]#2{\setvalue{\??sg\??sg#1}{#2}}
-\unexpanded\def\bidilre{\utfchar{"0x202A}}
-\unexpanded\def\bidirle{\utfchar{"0x202B}}
-\unexpanded\def\bidipop{\utfchar{"0x202C}}
-\unexpanded\def\bidilro{\utfchar{"0x202D}}
-\unexpanded\def\bidirlo{\utfchar{"0x202E}}
+\definespacingmethod[\v!packed]{\newfrenchspacing}
+\definespacingmethod[\v!broad ]{\nonfrenchspacing}
-\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi}
-\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi}
-\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setcharactermirroring[3]\fi}
-\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setcharactermirroring[4]\fi}
+\def\complexsetupspacing[#1]%
+ {\executeifdefined{\??sg\??sg#1}\relax
+ \updateraggedskips}
-% test at end of file
+\def\simplesetupspacing
+ {\updateraggedskips}
-% for the moment: \setcharactermirroring[\plusone]
+\definecomplexorsimple\setupspacing
+
+% \dorecurse{100}{\recurselevel\spacefactor 800 \space} \par
+% \dorecurse{100}{\recurselevel\spacefactor1200 \space} \par
+% \dorecurse{100}{\recurselevel\spacefactor 800 \normalspaceprimitive} \par
+% \dorecurse{100}{\recurselevel\spacefactor1200 \normalspaceprimitive} \par
-% experimental spacing
+% When we don't add the % here, we effectively get \<endlinechar> and
+% since we have by default \def\^^M{\ } we get into a loop.
+
+\let\normalspaceprimitive=\ % space-comment is really needed
+
+\unexpanded\def\ {\mathortext\normalspaceprimitive\space} % no \dontleavehmode\space (else no frenchspacing)
+
+\unexpanded\def\nonbreakablespace{\penalty\plustenthousand\space}
+
+\letcatcodecommand \ctxcatcodes `\~ \nonbreakablespace % overloaded later
+
+\def\space { }
+\def\removelastspace{\ifhmode\unskip\fi}
+\def\nospace {\removelastspace\ignorespaces}
+
+% in tables we need:
%
-% test: oeps {\setcharacterspacing[frenchpunctuation]x: xx \bfd x: xx} oeps: test
+% \def\fixedspace {\hskip.5em\relax}
+%
+% but, since not all fonts have .5em digits:
-\defineattribute[spacing]
+\unexpanded\def\fixedspace
+ {\setbox\scratchbox\normalhbox{\mathortext{0}{0}}%
+ \hskip\wd\scratchbox\relax}
-\newcount \maxcharacterspacingid
+\def\fixedspaces
+ {\letcatcodecommand \ctxcatcodes `\~ \fixedspace}
-\def\definecharacterspacing[#1]%
- {\ifcsname\??ch#1\endcsname \else
- \global\advance\maxcharacterspacingid\plusone
- \setxvalue{\??ch:#1}{\the\maxcharacterspacingid}%
+\def\removeunwantedspaces
+ {\ifhmode % we also need to unskip 0pt skips
+ \unskip\unskip\unskip\unskip\unskip
+ \unskip\unskip\unskip\unskip\unskip
\fi}
-\def\setupcharacterspacing
- {\dotripleargument\dosetupcharacterspacing}
+\appendtoks\let~\space\to\simplifiedcommands
-\def\dosetupcharacterspacing[#1][#2][#3]%
- {\ifcsname\??ch:#1\endcsname
- \begingroup % for the moment we use modes, in ordere to avoid interface translation
- \getparameters[\??ch][\c!left=0,\c!right=0,\c!alternative=0,#3]%
- \ctxlua{spacings.setspacing(\getvalue{\??ch:#1},\number#2,\@@chleft,\@@chright,\@@chalternative)}%
- \endgroup
+% still not fixed in aleph / luatex
+%
+% \def\removeunwantedspaces
+% {\ifhmode \ifnum\lastnodetype=\@@gluenode
+% \unskip \@EAEAEA\removeunwantedspaces
+% \fi \fi}
+
+%D For old time sake, will disappear soon.
+
+\let\hardespatie\fixedspace
+\let\geenspatie \nospace
+
+% \startbuffer
+% \startlines \tt \fixedspaces
+% 0~1~~2~~~3~~~~4~~~~~5
+% 0~~~~~~~~~~~~~~~~~~~5
+% $0~1~~2~~~3~~~~4~~~~~5$
+% $0~~~~~~~~~~~~~~~~~~~5$
+% \stoplines
+%
+% \starttabulate[|~|]
+% \NC 0~1~~2~~~3~~~~4~~~~~5 \NC \NR \NC 0~~~~~~~~~~~~~~~~~~~5 \NC \NR
+% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \NR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \NR
+% \stoptabulate
+%
+% \starttable[||]
+% \NC 0~1~~2~~~3~~~~4~~~~~5 \NC \AR \NC 0~~~~~~~~~~~~~~~~~~~5 \NC \AR
+% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \AR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \AR
+% \stoptable
+% \stopbuffer
+%
+% \setupbodyfont[cmr] \getbuffer
+% \setupbodyfont[lbr] \getbuffer
+
+\def\packed
+ {\nointerlineskip}
+
+\def\godown[#1]%
+ {\relax
+ \ifhmode\endgraf\fi
+ \ifvmode\nointerlineskip\vskip#1\relax\fi}
+
+%D A couple of plain macros:
+
+\ifx\thinspace\undefined
+
+ \def\thinspace {\kern .16667em }
+ \def\negthinspace{\kern-.16667em }
+ \def\enspace {\kern .5em }
+
+ \def\thinspace {\kern .16667\emwidth}
+ \def\negthinspace{\kern-.16667\emwidth}
+ \def\enspace {\kern .5\emwidth}
+
+\fi
+
+\ifx\quad\undefined
+
+ \def\enskip{\hskip.5em\relax}
+ \def\quad {\hskip 1em\relax}
+ \def\qquad {\hskip 2em\relax}
+
+ \def\enskip{\hskip.5\emwidth}
+ \def\quad {\hskip \emwidth}
+ \def\qquad {\hskip 2\emwidth}
+
+\fi
+
+\let\emspace\quad
+
+\ifx\smallskip\undefined
+
+ \def\smallskip{\vskip\smallskipamount}
+ \def\medskip {\vskip\medskipamount}
+ \def\bigskip {\vskip\bigskipamount}
+
+\fi
+
+\ifx\allowbreak\undefined
+
+ \def\break {\penalty\ifhmode-\plustenthousand\else\ejectpenalty\fi}
+ \def\nobreak {\penalty \plustenthousand}
+ \def\allowbreak{\penalty \zeropoint}
+ \def\filbreak {\par\vfil\penalty-200\vfilneg}
+ \def\goodbreak {\par\penalty-500 }
+
+\fi
+
+%D Made slightly more readable:
+
+\ifx\vglue\undefined
+
+ \def\vglue {\afterassignment\dovglue\scratchskip=}
+ \def\hglue {\afterassignment\dohglue\scratchskip=}
+ \def\topglue{\nointerlineskip\vglue-\topskip\vglue}
+
+ \def\dovglue
+ {\par
+ \scratchdimen\prevdepth
+ \hrule\!!height\zeropoint
+ \nobreak\vskip\scratchskip
+ \prevdepth\scratchdimen}
+
+ \def\dohglue
+ {\dontleavehmode % \leavevmode
+ \scratchcounter\spacefactor
+ \vrule\!!width\zeropoint
+ \nobreak\hskip\scratchskip
+ \spacefactor\scratchcounter}
+
+\fi
+
+\ifx\eject\undefined
+
+ \def\eject{\par\break}
+
+\fi
+
+\ifx\supereject\undefined
+
+ \def\supereject{\par\penalty\superpenalty}
+
+\fi
+
+\ifx\dosupereject\undefined
+
+ \def\dosupereject
+ {\ifnum\insertpenalties>\zerocount % something is being held over
+ \line{}
+ \kern-\topskip
+ \nobreak
+ \vfill\supereject
+ \fi}
+
+\fi
+
+%D We adapt plain's \type {\removelastskip} a bit:
+
+\ifx\removelastskip\undefined
+
+ \def\removelastskip
+ {\ifvmode \ifdim\lastskip=\zeropoint \else
+ \vskip-\lastskip
+ \fi \fi}
+
+\fi
+
+\ifx\smallbreak\undefined
+
+\def\smallbreak
+ {\par
+ \ifdim\lastskip<\smallskipamount
+ \removelastskip
+ \penalty-50
+ \smallskip
+ \fi}
+
+\def\medbreak
+ {\par
+ \ifdim\lastskip<\medskipamount
+ \removelastskip
+ \penalty-100
+ \medskip
+ \fi}
+
+\def\bigbreak
+ {\par
+ \ifdim\lastskip<\bigskipamount
+ \removelastskip
+ \penalty-200
+ \bigskip
+ \fi}
+
+\fi
+
+\newskip\ctxparskip \ctxparskip\zeropoint
+
+\newconditional \flexiblewhitespace \settrue\flexiblewhitespace
+
+\def\blankokleinmaat {\smallskipamount}
+\def\blankomiddelmaat {\medskipamount}
+\def\blankogrootmaat {\bigskipamount}
+\def\currentwhitespace {\zeropoint}
+
+\definecomplexorsimple\setupwhitespace
+
+\def\simplesetupwhitespace
+ {\doifnot\currentwhitespace\v!none\dosetupwhitespace}
+
+\def\complexsetupwhitespace[#1]%
+ {\edef\nextcurrentwhitespace{#1}%
+ \ifx\nextcurrentwhitespace\empty
+ \simplesetupwhitespace
+ \else
+ \let\currentwhitespace\nextcurrentwhitespace
+ \dosetupwhitespace
+ \fi}
+
+\def\dosetupwhitespace % quick test for no list
+ {\ifcsname\??ws\??ws\currentwhitespace\endcsname
+ \csname\??ws\??ws\currentwhitespace\endcsname
+ \else
+ \expandafter\processcommalist\expandafter[\currentwhitespace]\dowhitespacemethod % can be raw
+ \fi\relax
+ \ifgridsnapping
+ \setfalse\flexiblewhitespace
+ \ifdim\ctxparskip>\zeropoint
+ \ctxparskip
+ \ifcase\baselinegridmode
+ \baselineskip % normal ! ! ! ! !!
+ \or
+ \ifdim\scratchdimen=\baselineskip % maybe range
+ \baselineskip % normal ! ! ! ! !!
+ \else
+ \numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
+ \fi
+ \else
+ \baselineskip % normal ! ! ! ! !!
+ \fi
+ \fi
+ \else
+ \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
+ \fi
+ \parskip\ctxparskip}
+
+\chardef\baselinegridmode=0 % option in layout / 1=permit_half_lines
+
+\def\dodosetupwhitespace
+ {\ifgridsnapping
+ \setfalse\flexiblewhitespace
+ \ctxparskip1\ctxparskip
+ \ifdim\ctxparskip>\zeropoint
+ \ifcase\baselinegridmode
+ \ctxparskip\baselineskip % normal ! ! ! ! !!
+ \or
+ \ifdim\scratchdimen=\baselineskip % maybe range
+ \ctxparskip\baselineskip % normal ! ! ! ! !!
+ \else
+ \ctxparskip\numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
+ \fi
+ \else
+ \ctxparskip\baselineskip % normal ! ! ! ! !!
+ \fi
+ \fi
+ \else
+ \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
+ \fi
+ \parskip\ctxparskip}
+
+\definesystemvariable {ws} % whitespace
+
+\def\definewhitespacemethod[#1]#2{\setvalue{\??ws\??ws#1}{#2}}
+
+\definewhitespacemethod [\v!fix] {}
+\definewhitespacemethod [\v!fixed] {\setfalse\flexiblewhitespace}
+\definewhitespacemethod [\v!flexible] {\settrue\flexiblewhitespace}
+\definewhitespacemethod [\v!line] {\ctxparskip \baselineskip}
+\definewhitespacemethod [\v!halfline] {\ctxparskip.5\baselineskip}
+\definewhitespacemethod [\v!none] {\ctxparskip \zeropoint}
+\definewhitespacemethod [\v!big] {\ctxparskip \bigskipamount}
+\definewhitespacemethod [\v!medium] {\ctxparskip \medskipamount}
+\definewhitespacemethod [\v!small] {\ctxparskip \smallskipamount}
+
+\definewhitespacemethod [\s!default] {\simplesetupwhitespace} % {\stelwitruimteopnieuwin}
+
+% \def\dowhitespacemethod#1%
+% {\executeifdefined{\??ws\??ws#1}{\ctxparskip#1}\relax}
+
+\def\dowhitespacemethod#1%
+ {\ifcsname\??ws\??ws#1\endcsname\csname\??ws\??ws#1\endcsname\else\ctxparskip#1\fi\relax}
+
+\def\nowhitespace
+ {\ifdim\parskip>\zeropoint\relax
+ \ifdim\lastskip=-\parskip
+ \else
+ \vskip-\parskip
+ \fi
\fi}
-\def\setcharacterspacing
- {\ctxlua{spacings.enabled=true}%
- \gdef\setcharacterspacing[##1]{\dosetattribute{spacing}{\csname\??ch:##1\endcsname}}%
- \setcharacterspacing}
+\def\nowhitespaceunlessskip
+ {\ifdim\lastskip>\zeropoint \else
+ \nowhitespace
+ \fi}
+
+\def\redowhitespace
+ {\ifdim\lastskip>-\parskip \else
+ \vskip\parskip
+ \fi}
+
+\def\savecurrentwhitespace
+ {\edef\restorecurrentwhitespace
+ {\ctxparskip\the\ctxparskip
+ \parskip\the\parskip
+ \noexpand\def\noexpand\currentwhitespace{\currentwhitespace}%
+ \ifconditional\flexiblewhitespace
+ \noexpand\settrue\flexiblewhitespace
+ \else
+ \noexpand\setfalse\flexiblewhitespace
+ \fi}}
+
+% deze variant is nodig binnen \startopelkaar
+% steeds testen:
+%
+% \hoofdstuk{..}
+% \plaatslijst[..]
+% \hoofdstuk{..}
+% \input tufte
+%
+% met/zonder witruimte
+
+\def\whitespace
+ {\par
+ \ifdim\parskip>\zeropoint\relax
+ %\ifdim\lastskip>\parskip \else
+ % \removelastskip interferes with blanko blokkeer en klein
+ \vskip\parskip
+ %\fi
+ \fi}
+
+\def\nonoblanko[#1]%
+ {\par}
+
+\def\noblanko
+ {\dosingleempty\nonoblanko}
+
+% De onderstaande macro handelt ook de situatie dat er geen
+% tekst tussen \start ... \stop is geplaatst. Daartoe wordt de
+% laatste skip over de lege tekst heen gehaald. Dit komt goed
+% van pas bij het plaatsen van (mogelijk lege) lijsten.
+
+\newif\ifopelkaar
+
+\newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt}
+\def\lastdoneparskip {0pt}
+
+\def\startpacked
+ {\dosingleempty\dostartpacked}
+
+\def\dostartpacked[#1]% nesting afvangen
+ {\par
+ \ifvmode
+ \edef\lastdoneparskip {\the\lastskip}%
+ \edef\lastdoneprevdepth{\the\prevdepth}% zeer recent toegevoegd
+ \ifdim\prevdepth=-\thousandpoint % toegevoegd omdat binnen
+ \else % een vbox een extra skip
+ \whitespace % ongewenst is; dit kan
+ \baselinecorrection %% zie in \placeregister[n=1]
+ \vskip\noparskipsignal % waarschijnlijk ook in
+ \fi % blanko blokkeer
+ \bgroup
+ \doifelse{#1}\v!blank
+ \opelkaarfalse
+ \opelkaartrue
+ \blank[\v!disable] % dit is nog niet ok, gaat fout
+ \setupwhitespace[\v!none] % bovenin vtop (dwz, baseline)
+ \fi}
+
+\def\stoppacked
+ {\par
+ \ifvmode
+ \egroup
+ \ifdim\lastskip=\noparskipsignal\relax
+ \removelastskip
+ \nowhitespace
+ \vskip-\lastdoneparskip
+ \vskip+\lastdoneparskip
+ \prevdepth-\lastdoneprevdepth % zeer recent toegevoegd
+ \fi
+ \fi}
+
+\def\startunpacked
+ {\blank
+ \leavevmode
+ \bgroup}
-\def\resetcharacterspacing
- {\doresetattribute{spacing}}
+\def\stopunpacked
+ {\egroup
+ \blank}
+
+% De onderstaande macro's moeten nog eens nader worden uitgewerkt.
+% Ze spelen een rol bij de spatiering rond omkaderde teksten
+% en/of boxen zonder diepte.
-\letvalue{\??ch:\s!reset}\minusone
+\def\toonregelcorrectie{\showbaselinecorrection}
+\def\regelcorrectie {\baselinecorrection}
-% \setcharacterspacing[frenchpunctuation]
-% «\type{bla}»\crlf « \type{bla}»\crlf
-% «bla »\crlf « bla»\crlf « bla »\crlf
-% bla: bla\crlf bla : bla
+% \prevdepth crosses pageboundaries!
+%
+% todo: a version that works ok inside a box
+
+\let\doaroundlinecorrection\relax
+
+\def\startlinecorrection
+ {\dodoubleempty\dostartlinecorrection}
-\definecharacterspacing [frenchpunctuation] % name may change / unit is em
+\def\dostartlinecorrection[#1][#2]% #2 gobbles spaces
+ {\bgroup
+ \processaction
+ [#1]
+ [ \v!blank=>\let\doaroundlinecorrection\blank,
+ \s!default=>\let\doaroundlinecorrection\relax,
+ \s!unknown=>{\def\doaroundlinecorrection{\blank[#1]}}]%
+ \doaroundlinecorrection
+ \startbaselinecorrection
+ \offbaselinecorrection
+ \ignorespaces}
-\setupcharacterspacing [frenchpunctuation] ["003A] [\c!left =.25,\c!alternative=1] % : % strip preceding space(char)
-\setupcharacterspacing [frenchpunctuation] ["003B] [\c!left =.25,\c!alternative=1] % ; % strip preceding space(char)
-\setupcharacterspacing [frenchpunctuation] ["003F] [\c!left =.25,\c!alternative=1] % ? % strip preceding space(char)
-\setupcharacterspacing [frenchpunctuation] ["0021] [\c!left =.25,\c!alternative=1] % ! % strip preceding space(char)
-\setupcharacterspacing [frenchpunctuation] ["00AB] [\c!right=.25,\c!alternative=1] % guillemotleft/leftguillemot % strip following space(char)
-\setupcharacterspacing [frenchpunctuation] ["00BB] [\c!left =.25,\c!alternative=1] % guillemotright/rightguillemot % strip preceding space(char)
+\def\stoplinecorrection
+ {\stopbaselinecorrection
+ \doaroundlinecorrection
+ \egroup}
+
+\def\correctwhitespace
+ {\dowithnextbox
+ {\startbaselinecorrection
+ \flushnextbox
+ \stopbaselinecorrection}%
+ \vbox}
+
+\def\verticalstrut {\normalvbox{\hsize\zeropoint\forgetall\strut}}
+\def\horizontalstrut{\normalhbox {\strut}}
+
+% Hieronder volgen enkele instellingen en macro's ten behoeve
+% van de interlinie en \strut. De waarden 2.8, 0.07, 0.72 en
+% 0.28 zijn ooit eens ontleend aan INRS-TEX en moeten wellicht
+% nog eens instelbaar worden.
+%
+% \lineheight : de hoogte van een regel
+% \spacing{getal} : instellen interlinie
+% \normalbaselines : instellen regelafstend
+%
+% \setstrut : instellen \strut
+% \setnostrut : resetten \strut, \endstrut, \begstrut
+%
+% \setteststrut : instellen zichtbare struts
+% \resetteststrut : instellen onzichtbare struts
+%
+% \setfontparameters : instellen na fontset
+%
+% De hoogte van een regel (\lineheight) is gelijk aan de
+% som van de hoogte (\ht) en diepte (\dp) van \strutbox.
+%
+% \strut : denkbeeldig blokje met hoogte en diepte
+%
+% Een \hbox kan als deze aan het begin van een regel staat
+% een breedte \hsize krijgen. Dit is soms te voorkomen met het
+% commando \leavevmode. Binnen een \vbox geeft dit echter
+% niet altijd het gewenste resultaat, vandaar het commando
+%
+% \leaveoutervmode
-% more
+% Pas op: niet zomaar \topskip en \baselineskip aanpassen
+% en zeker niet \widowpenalty. Dit kan ernstige gevolgen
+% hebben voor kolommen.
%
-% {\setcharacterkerning[extrakerning]\input davis\relax}
+% Enige glue kan op zich geen kwaad, echter als blanko=vast,
+% dan moet ook de rek 0 zijn. Binnen kolommen is rek ook
+% niet bepaald mooi. Een hele kleine waarde (0.025) voldoet,
+% omdat een positieve glue eindeloos rekbaar is.
+
+\newdimen\strutdimen
+\newdimen\lineheight
+\newdimen\openlineheight
+\newdimen\openstrutheight
+\newdimen\openstrutdepth
+\newdimen\topskipgap
+\newdimen\struttotal
+
+\def\strutheightfactor {.72}
+\def\strutdepthfactor {.28}
+
+\def\baselinefactor {2.8}
+\def\baselinegluefactor {0}
+
+\def\minimumstrutheight {0pt}
+\def\minimumstrutdepth {0pt}
+
+\def\normallineheight {\baselinefactor ex}
+\def\minimumlinedistance {\lineskip}
+
+\def\strutheight {0pt}
+\def\strutdepth {0pt}
+\def\strutwidth {0pt}
+
+\def\spacingfactor {1}
+
+\def\topskipfactor {1.0}
+\def\maxdepthfactor {0.5}
+
+\def\systemtopskipfactor {\topskipfactor}
+\def\systemmaxdepthfactor {\maxdepthfactor}
+
+% De onderstaande definitie wordt in de font-module overruled
+
+\ifdefined\globalbodyfontsize\else
+ \newdimen\globalbodyfontsize
+ \globalbodyfontsize=12pt
+\fi
-\defineattribute[kern]
+\ifx\normalizedbodyfontsize\undefined
+ \def\normalizedbodyfontsize{12pt}
+\fi
-\newcount \maxcharacterkerningid
+% door een \dimen. Dit is geen probleem omdat (1) de default
+% korpsgrootte 12pt is en (2) de fonts nog niet geladen zijn
+% en de instellingen bij het laden nogmaals plaatsvinden.
-\def\definecharacterkerning
- {\dosingleargument\dodefinecharacterkerning}
+\def\topskipcorrection
+ {\simpletopskipcorrection
+ \vskip-\struttotal
+ \verticalstrut}
-\def\dodefinecharacterkerning[#1]%
- {\ifcsname\??ck#1\endcsname \else
- \global\advance\maxcharacterkerningid\plusone
- \setxvalue{\??ck:#1}{\the\maxcharacterkerningid}%
+\def\simpletopskipcorrection
+ {\ifdim\topskip>\openstrutheight
+ % == \vskip\topskipgap
+ \vskip\topskip
+ \vskip-\openstrutheight
\fi}
-\def\setupcharacterkerning
- {\dodoubleargument\dosetupcharacterkerning}
+\def\settopskip % the extra test is needed for the lbr family
+ {\topskip\systemtopskipfactor\globalbodyfontsize
+ \ifgridsnapping \else
+ \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
+ \fi
+ \relax % the skip
+ \topskipgap\topskip
+ \advance\topskipgap -\openstrutheight\relax
+\ifdim\minimumstrutheight>\zeropoint
+ \ifdim\topskip<\minimumstrutheight
+ \topskip\minimumstrutheight\relax
+ \fi
+\else
+ \ifdim\topskip<\strutheightfactor\openlineheight
+ \topskip\strutheightfactor\openlineheight\relax
+ \fi
+\fi}
-\def\dosetupcharacterkerning[#1][#2]%
- {\ifcsname\??ck:#1\endcsname
- \begingroup
- \getparameters[\??ck][\c!factor=0,#2]%
- \ctxlua{kerns.setspacing(\getvalue{\??ck:#1},\@@ckfactor)}%
+\def\setmaxdepth
+ {\maxdepth\systemmaxdepthfactor\globalbodyfontsize}
+
+\def\normalbaselines
+ {\baselineskip \normalbaselineskip
+ \lineskip \normallineskip
+ \lineskiplimit\normallineskiplimit}
+
+\def\setnormalbaselines
+ {\ifdim\normallineheight>\zeropoint
+ \lineheight\normallineheight
+ \fi
+ \openlineheight\spacingfactor\lineheight
+ \openstrutheight \ifdim\minimumstrutheight>\zeropoint
+ \minimumstrutheight % new
+ \else
+ \strutheightfactor\openlineheight
+ \fi
+ \openstrutdepth \ifdim\minimumstrutdepth>\zeropoint
+ \minimumstrutdepth % new
+ \else
+ \strutdepthfactor \openlineheight
+ \fi
+ \ifdim\dimexpr\minimumstrutdepth+\minimumstrutheight\relax>\zeropoint
+ \openlineheight\dimexpr\openstrutheight+\openstrutdepth\relax % new
+ \fi
+ \normalbaselineskip\openlineheight
+ \ifgridsnapping\else
+ \!!plus \baselinegluefactor\openlineheight
+ \!!minus\baselinegluefactor\openlineheight
+ \fi
+ \normallineskip\minimumlinedistance\relax % \onepoint\relax
+ \normallineskiplimit\zeropoint\relax
+ \normalbaselines
+ \dosetupgridsnapping}
+
+\def\spacing#1%
+ {\ifgridsnapping
+ \ifdim#1\points=\onepoint\else\showmessage\m!layouts{11}{#1}\fi
+ \edef\spacingfactor{1}%
+ \else
+ \edef\spacingfactor{#1}%
+ \fi
+ %\setspacingfactor\systemtopskipfactor \topskipfactor {#1}% why no \spacingfactor ?
+ %\setspacingfactor\systemmaxdepthfactor\maxdepthfactor{#1}% why no \spacingfactor ?
+ \edef\systemtopskipfactor {\withoutpt\the\dimexpr#1\dimexpr\topskipfactor \points}%
+ \edef\systemmaxdepthfactor{\withoutpt\the\dimexpr#1\dimexpr\maxdepthfactor\points}%
+ \setnormalbaselines
+ \setstrut}
+
+%D Sometimes one needs to freeze the interlinespacing
+%D
+%D \starttyping
+%D \rm \saveinterlinespace .... {\ss \restoreinterlinespace .... \endgraf}
+%D \stoptyping
+
+\let\restoreinterlinespace\relax
+
+\def\saveinterlinespace
+ {\edef\restoreinterlinespace
+ {\lineheight \the\lineheight
+ \openstrutheight \the\openstrutheight
+ \openstrutdepth \the\openstrutdepth
+ \openlineheight \the\openlineheight
+ \normalbaselineskip \the\normalbaselineskip
+ \normallineskip \the\normallineskip
+ \normallineskiplimit\the\normallineskiplimit
+ \noexpand\def\noexpand\normallineheight{\the\dimexpr\normallineheight}%
+ \noexpand\normalbaselines}}
+
+% plain definition:
+%
+% \def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
+%
+% could be:
+%
+% \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
+
+\ifx\strutbox\undefined
+
+ \newbox\strutbox
+
+ \setbox\strutbox=\normalhbox{\vrule height8.5pt depth3.5pt width\zeropoint}
+
+ %\def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
+ \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
+
+\fi
+
+\let\normalstrut\strut
+
+% The double \hbox construction enables us to \backtrack
+% boxes.
+
+\unexpanded\def\setstrut
+ {% height
+ \edef\strutheight
+ {\the\dimexpr\spacingfactor\dimexpr
+ \ifdim\minimumstrutheight>\zeropoint
+ \minimumstrutheight
+ \else
+ \strutheightfactor\dimexpr\normallineheight
+ \fi}%
+ % depth
+ \edef\strutdepth
+ {\the\dimexpr
+ \ifgridsnapping
+ \ifdim\minimumstrutdepth>\zeropoint
+ \minimumstrutdepth
+ \else
+ \normallineheight-\strutheight
+ \fi
+ \else
+ \spacingfactor\dimexpr
+ \ifdim\minimumstrutdepth>\zeropoint
+ \minimumstrutdepth
+ \else
+ \strutdepthfactor\dimexpr\normallineheight
+ \fi
+ \fi}%
+ % finish
+ \dosetstrut}
+
+\unexpanded\def\setcharstrut#1%
+ {\setbox\strutbox\normalhbox{#1}%
+ \edef\strutheight{\the\strutht}%
+ \edef\strutdepth {\the\strutdp}%
+ \dosetstrut}
+
+\unexpanded\def\setfontstrut
+ {\setcharstrut{(gplQT}}
+
+\unexpanded\def\setcapstrut% could be M, but Q has descender
+ {\setcharstrut{Q}}
+
+%D Handy for math (used in mathml):
+
+\def\charhtstrut
+ {\begingroup
+ \setcharstrut{GJY}%
+ \vrule\!!width\zeropoint\!!depth\zeropoint\!!height\strutht
+ \endgroup}
+
+\def\chardpstrut
+ {\begingroup
+ \setcharstrut{gjy}%
+ \vrule\!!width\zeropoint\!!depth\strutdp\!!height\zeropoint
+ \endgroup}
+
+% because of all the callbacks in mkiv, we avoid unnecessary boxes ...
+% maybe use an attribute so that we can tag boxes that don't need a
+% treatment; tests with using an attribute so far have shown that
+% it's slower because testing the attribute takes time too
+
+\def\dosetstrut
+ {\let\strut\normalstrut
+ \ifdim\strutwidth=\zeropoint
+ \setbox\strutbox\normalhbox
+ {\vrule
+ \!!width \zeropoint
+ \!!height\strutheight
+ \!!depth \strutdepth}%
+ \else
+ \setbox\strutbox\normalhbox
+ {\normalhbox to \zeropoint
+ {% \hss % new, will be option
+ \vrule
+ \!!width \strutwidth
+ \!!height\strutheight
+ \!!depth \strutdepth
+ \hss}}%
+ \fi
+ \struttotal\dimexpr\strutht+\strutdp\relax}
+
+%D The dimen \type {\struttotal} holds the exact size of the
+%D strut; occasionally a one scaled point difference can show
+%D up with the lineheight.
+
+%D Sometimes a capstrut comes in handy
+%D
+%D \starttabulate[|Tl|l|l|]
+%D \NC yes \NC normal strut \NC {\showstruts\setupstrut[yes]\strut} \NC \NR
+%D \NC no \NC no strut \NC {\showstruts\setupstrut[no]\strut} \NC \NR
+%D \NC kap \NC a capital strut (i.e. Q) \NC {\showstruts\setupstrut[cap]\strut} \NC \NR
+%D \NC A B \unknown \NC a character strut (e.g. A) \NC {\showstruts\setupstrut[A]\strut} \NC \NR
+%D \NC \NC a normal strut \NC {\showstruts\setupstrut\strut} \NC \NR
+%D \stoptabulate
+
+\def\setupstrut
+ {\dosingleempty\dosetupstrut}
+
+\def\dosetupstrut[#1]% yet undocumented, todo: fontstrut
+ {\processaction
+ [#1]
+ [ \v!yes=>\setstrut,
+ \v!auto=>\setautostrut,
+ \v!no=>\setnostrut,
+ \v!cap=>\setcapstrut,
+ \v!fit=>\setfontstrut,
+ \v!line=>\setstrut,
+ \s!default=>\setstrut,
+ \s!unknown=>\setcharstrut\commalistelement]}
+
+\def\setteststrut
+ {\def\strutwidth{.8pt}%
+ \setstrut}
+
+\def\autostrutfactor{1.1}
+
+\def\setautostrut
+ {\begingroup
+ \setbox\scratchbox\copy\strutbox
+ \setstrut
+ \ifdim\ht\strutbox>\autostrutfactor\ht\scratchbox
+ \endgroup \setstrut
+ \else\ifdim\dp\strutbox>\autostrutfactor\dp\scratchbox
+ \endgroup \setstrut
+ \else
\endgroup
+ \fi\fi}
+
+% when enabled, sigstruts will remove themselves if nothing
+% goes inbetween
+
+\newsignal\strutsignal \setfalse\sigstruts
+
+\def\begstrut
+ {\relax\ifcase\strutht\else
+ \ifconditional\sigstruts
+ \noindent\horizontalstrut
+ \normalpenalty\plustenthousand
+ \normalhskip-\strutsignal
+ \normalhskip\strutsignal
+ \else
+ \strut
+ \normalpenalty\plustenthousand
+ \normalhskip\zeropoint
+ \fi
+ \expandafter \ignorespaces
+ \fi}
+
+\def\endstrut
+ {\relax\ifhmode\ifcase\strutht\else
+ \ifconditional\sigstruts
+ \ifdim\lastskip=\strutsignal
+ \unskip\unskip\unpenalty\setbox\scratchbox\lastbox
+ \else
+ \normalpenalty\plustenthousand
+ \normalhskip\zeropoint
+ \strut
+ \fi
+ \else
+ \removeunwantedspaces
+ \normalpenalty\plustenthousand
+ \normalhskip\zeropoint
+ \strut
+ \fi
+ \fi\fi}
+
+\newbox\nostrutbox \setbox\nostrutbox\normalhbox{} % {\normalhbox{}}
+
+\def\setnostrut
+ {\setbox\strutbox\copy\nostrutbox
+ \let\strut\empty
+ \let\endstrut\empty
+ \let\begstrut\empty
+ \let\crlfplaceholder\empty}
+
+% unsave:
+%
+% \def\pseudostrut
+% {\bgroup
+% \setnostrut
+% \normalstrut
+% \egroup}
+%
+% try:
+%
+% \startchemie
+% \chemie[ONE,Z0,SB15,MOV1,SB15,Z0][C,C]
+% \stopchemie
+%
+% so:
+
+\def\pseudostrut
+ {\noindent} % better: \dontleavehmode
+
+\let\pseudobegstrut\pseudostrut
+
+\let\pseudoendstrut\removeunwantedspaces
+
+\def\resetteststrut
+ {\let\strutwidth\zeropoint
+ \setstrut}
+
+\ifx\setfontparameters\undefined
+ % problems ! ! ! !
+ \def\setfontparameters{\the\everybodyfont}
+\fi
+
+%D Handy:
+
+\def\baselinedistance{\the\lineheight}
+
+%D We need \type{\normaloffinterlineskip} because the new
+%D definition contains an assignment, and |<|don't ask me
+%D why|>| this assignment gives troubles in for instance the
+%D visual debugger.
+
+%D The plain ones:
+
+\def\offinterlineskip
+ {\baselineskip-\thousandpoint
+ \lineskip\zeropoint
+ \lineskiplimit\maxdimen}
+
+\def\nointerlineskip
+ {\prevdepth-\thousandpoint}
+
+\let\normaloffinterlineskip=\offinterlineskip % knuth's original
+
+%D My own one:
+
+\def\offinterlineskip
+ {\ifdim\baselineskip>\zeropoint
+ \edef\oninterlineskip
+ {\baselineskip\the\baselineskip
+ \lineskip\the\lineskip
+ \lineskiplimit\the\lineskiplimit
+ \let\noexpand\offinterlineskip\noexpand\normaloffinterlineskip}%
+ \else
+ \let\oninterlineskip\setnormalbaselines
+ \fi
+ \normaloffinterlineskip}
+
+\let\oninterlineskip=\relax
+
+\def\leaveoutervmode
+ {\ifvmode\ifinner\else
+ \leavevmode
+ \fi\fi}
+
+% We stellen enkele penalties anders in dan Plain TEX:
+
+% oud
+%
+% \widowpenalty=\defaultwidowpenalty\relax
+% \clubpenalty =\defaultclubpenalty \relax
+
+\def\resetpenalties#1%
+ {\ifx#1\undefined\else
+ #1\minusone
\fi}
-\def\setcharacterkerning
- {\ctxlua{kerns.enabled=true}%
- \gdef\setcharacterkerning[##1]{\dosetattribute{kern}{\csname\??ck:##1\endcsname}}%
- \setcharacterkerning}
+\def\setpenalties#1#2#3%
+ {\ifx#1\undefined\else % space before #3 prevents lookahead problems, needed when #3=text
+ #1\numexpr#2+\plusone\relax\space\doexpandedrecurse{\the\numexpr#2\relax}{ #3}\zerocount\relax
+ \fi}
+
+\def\doexpandedrecurse#1#2%
+ {\ifnum#1>\zerocount#2\@EA\doexpandedrecurse\@EA{\the\numexpr#1-1\relax}{#2}\fi}
+
+%D \macros
+%D {keeplinestogether}
+%D
+%D Dirty hack, needed in margin content that can run of a page.
+
+\def\keeplinestogether#1%
+ {\xdef\restoreinterlinepenalty{\global\resetpenalties\interlinepenalties}%
+ \global\setpenalties\interlinepenalties{#1}\plustenthousand}
+
+\newif\ifgridsnapping % to be sure
+
+\def\defaultwidowpenalty {2000} % was: 1000
+\def\defaultclubpenalty {2000} % was: 800
+\def\defaultdisplaywidowpenalty {50}
+\def\defaultbrokenpenalty {100}
+
+\def\defaultgridwidowpenalty {0}
+\def\defaultgridclubpenalty {0}
+\def\defaultgriddisplaywidowpenalty {0}
+\def\defaultgridbrokenpenalty {0}
+
+\def\nopenalties
+ {\widowpenalty \zerocount
+ \clubpenalty \zerocount
+ \brokenpenalty \zerocount
+ \doublehyphendemerits\zerocount
+ \finalhyphendemerits \zerocount
+ \adjdemerits \zerocount}
+
+\def\setdefaultpenalties
+ {\directsetup{\systemsetupsprefix\s!default}}
+
+\startsetups [\systemsetupsprefix\s!reset]
+ \resetpenalties\widowpenalties
+ \resetpenalties\clubpenalties
+ \resetpenalties\interlinepenalties
+\stopsetups
+
+% we use \directsetup because it's faster and we know there is no csl
+
+\startsetups [\systemsetupsprefix\s!default]
+
+ \directsetup{\systemsetupsprefix\s!reset}
+
+ \widowpenalty \defaultwidowpenalty
+ \clubpenalty \defaultclubpenalty
+ \displaywidowpenalty\defaultdisplaywidowpenalty
+ \brokenpenalty \defaultbrokenpenalty
+
+\stopsetups
+
+\startsetups [\v!grid] [\systemsetupsprefix\s!default]
+
+ \directsetup{\systemsetupsprefix\s!reset}
+
+ \widowpenalty \defaultgridwidowpenalty
+ \clubpenalty \defaultgridclubpenalty
+ \displaywidowpenalty\defaultgriddisplaywidowpenalty
+ \brokenpenalty \defaultgridbrokenpenalty
+
+\stopsetups
+
+% as an illustration:
+
+\startsetups [\systemsetupsprefix\v!strict]
+
+ \directsetup{\systemsetupsprefix\s!reset}
+
+ \setpenalties\widowpenalties2\maxdimen
+ \setpenalties\clubpenalties 2\maxdimen
+ \brokenpenalty \maxdimen
-\letvalue{\??ck:\s!reset}\minusone
+\stopsetups
-\definecharacterkerning[extrakerning]
+\setdefaultpenalties % will happen later in \setuplayout
-\setupcharacterkerning[extrakerning][\c!factor=.125]
+% Suggested by GB (not the name -):
-% sorry, here:
+\def\rapfillskip{.5\hsize plus .092\hsize minus .5\hsize} % D.A.'s value
-% test \WORD{test TEST \TeX} test
-% test \word{test TEST \TeX} test
-% test \Word{test TEST \TeX} test
+% Bovendien definieren we enkele extra \fill's:
-\defineattribute[case]
+\def\hfilll{\hskip\zeropoint\!!plus1filll\relax}
+\def\vfilll{\vskip\zeropoint\!!plus1filll\relax}
-\def\setcharactercasing
- {\ctxlua{cases.enabled=true}%
- \gdef\setcharactercasing[##1]{\dosetattribute{case}{\number##1}}%
- \setcharactercasing}
+% De onderstaande hulpmacro's moeten nog eens instelbaar worden
+% gemaakt.
-\def\WORD {\groupedcommand{\setcharactercasing[\plusone ]}{}}
-\def\word {\groupedcommand{\setcharactercasing[\plustwo ]}{}}
-\def\Word {\groupedcommand{\setcharactercasing[\plusthree]}{}}
-\def\Words{\groupedcommand{\setcharactercasing[\plusfour]}{}}
+\def\tfskipsize{1em\relax}
+\def\tfkernsize{1ex\relax}
-\let\WORDS\WORD
-\let\words\word
+\def\tfskip{\dotfskip\tfskipsize}
+\def\tfkern{\dotfkern\tfkernsize}
-% \definestartstop is not yet in available at core-spa time
+\def\dotfskip#1{{\tf\hskip#1}}
+\def\dotfkern#1{{\tf\kern #1}}
+
+% needs a proper \definenarrower or installnarrower
+
+\newskip\ctxleftskip
+\newskip\ctxrightskip
+\newskip\ctxmidskip
+
+\def\dosinglenarrower#1%
+ {\processaction
+ [#1]
+ [ \v!left=>\global\advance\ctxleftskip \@@slleft,
+ \v!middle=>\global\advance\ctxmidskip \@@slmiddle,
+ \v!right=>\global\advance\ctxrightskip \@@slright,
+ \v!reset=>\global\ctxleftskip \zeropoint
+ \global\ctxmidskip \zeropoint
+ \global\ctxrightskip\zeropoint,
+ \v!none=>,
+ \s!unknown=>\global\advance\ctxmidskip \commalistelement]}
+
+\def\donarrower[#1]% hm, can be dorepeat directly
+ {\dorepeatwithcommand[#1]\dosinglenarrower}
+
+\def\complexstartnarrower[#1]%
+ {\@@slbefore % was hard coded \par
+ \bgroup
+ \global\ctxleftskip \zeropoint
+ \global\ctxrightskip\zeropoint
+ \global\ctxmidskip \zeropoint
+ \processcommalistwithparameters[#1]\donarrower
+ \advance\leftskip \ctxleftskip
+ \advance\rightskip \ctxrightskip
+ \advance\leftskip \ctxmidskip
+ \advance\rightskip \ctxmidskip
+ \seteffectivehsize}
+
+% todo: definenarrower
+
+\def\simplestartnarrower
+ {\startnarrower[\v!middle]}
+
+\definecomplexorsimple\startnarrower
+
+\def\stopnarrower
+ {\@@slafter % was hard coded \par / needed, else skips forgotten
+ \egroup}
+
+\def\setupnarrower
+ {\dodoubleargument\getparameters[\??sl]}
+
+\newdimen\@@effectivehsize \def\effectivehsize {\hsize}
+\newdimen\@@effectiveleftskip \def\effectiveleftskip {\leftskip}
+\newdimen\@@effectiverightskip \def\effectiverightskip{\rightskip}
+
+\def\seteffectivehsize
+ {\setlocalhsize
+ \@@effectivehsize \localhsize
+ \@@effectiveleftskip \leftskip
+ \@@effectiverightskip \rightskip
+ \let\effectivehsize \@@effectivehsize
+ \let\effectiveleftskip \@@effectiveleftskip
+ \let\effectiverightskip\@@effectiverightskip}
+
+\unexpanded\def\lefttoright{\textdir TLT\pardir TLT\relax}
+\unexpanded\def\righttoleft{\textdir TRT\pardir TRT\relax}
+
+\def\dodefinehbox[#1][#2]%
+ {\setvalue{hbox#1}##1%
+ {\hbox to #2{\begstrut##1\endstrut\hss}}}
+
+\def\definehbox
+ {\dodoubleargument\dodefinehbox}
+
+\def\iobox#1#2#3#% here #3# is not really needed
+ {\vbox\bgroup % we want to return a vbox like the others
+ \hbox\bgroup% we need to pack the signal with the box
+ \signalrightpage
+ \dowithnextboxcontent
+ {\let\\=\endgraf\forgetall\doifrightpageelse#1#2}
+ {\box\nextbox\egroup\egroup}
+ \vbox#3}
+
+\def\obox{\iobox\raggedleft \raggedright} % outerbox
+\def\ibox{\iobox\raggedright\raggedleft} % innerbox
+
+\def\dosetraggedvbox#1%
+ {\let\raggedbox\vbox
+ \processfirstactioninset
+ [#1]
+ [ \v!left=>\let\raggedbox\lbox,
+ \v!right=>\let\raggedbox\rbox,
+ \v!middle=>\let\raggedbox\cbox,
+ \v!inner=>\let\raggedbox\ibox,
+ \v!outer=>\let\raggedbox\obox,
+ \v!flushleft=>\let\raggedbox\rbox,
+ \v!flushright=>\let\raggedbox\lbox,
+ \v!center=>\let\raggedbox\cbox,
+ \v!no=>\def\raggedbox{\vbox\bgroup\raggedright\let\next=}]}
+
+\def\dosetraggedhbox#1%
+ {\let\raggedbox\hbox
+ \processaction % slow
+ [#1]
+ [ \v!left=>\def\raggedbox{\doalignedline\v!left },
+ \v!right=>\def\raggedbox{\doalignedline\v!right },
+ \v!middle=>\def\raggedbox{\doalignedline\v!middle},
+ \v!inner=>\def\raggedbox{\doalignedline\v!inner },
+ \v!outer=>\def\raggedbox{\doalignedline\v!outer },
+ \v!flushleft=>\def\raggedbox{\doalignedline\v!right },
+ \v!flushright=>\def\raggedbox{\doalignedline\v!left },
+ \v!center=>\def\raggedbox{\doalignedline\v!middle}]}
+
+\def\dosetraggedcommand#1%
+ {\expanded{\dodosetraggedcommand{#1}}}
+
+\newtoks\everyraggedcommand
+
+\def\raggedcommand{\the\everyraggedcommand}
+
+\def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
+ {\everyraggedcommand \emptytoks
+ \let\raggedtopcommand \empty
+ \let\raggedbottomcommand\empty
+ \chardef\raggedoneliner\zerocount
+ \doifsomething{#1}
+ {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
+ \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
+ \!!donectrue
+ \rawprocesscommalist[#1]\dododosetraggedcommand}}
+
+\def\dododosetraggedcommand#1%
+ {\executeifdefined{\@@ragged@@command\string#1}\relax}
+
+\def\@@ragged@@command{@@raggedcommand}
+
+\setvalue{\@@ragged@@command\v!hanging }{\appendtoks\enableprotruding \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nothanging }{\appendtoks\disableprotruding \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!hz }{\appendtoks\enableadjusting \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nohz }{\appendtoks\disableadjusting \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!spacing }{\appendtoks\enablespacehandling
+ \enablekernhandling \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nospacing }{\appendtoks\disablespacehandling
+ \disablekernhandling \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!hyphenated }{\appendtoks\dohyphens \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!nothyphenated}{\appendtoks\nohyphens \to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!tolerant }{\appendtoks\tolerance3000\relax \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!verytolerant}{\appendtoks\tolerance4500\relax \to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!stretch }{\appendtoks\emergencystretch\bodyfontsize\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!left}%
+ {\if!!donea \appendtoks\veryraggedleft\to\everyraggedcommand
+ \else \appendtoks\raggedleft \to\everyraggedcommand
+ \fi
+ \!!donecfalse}
+
+\setvalue{\@@ragged@@command\v!right}%
+ {\if!!donea \appendtoks\veryraggedright\to\everyraggedcommand
+ \else \appendtoks\raggedright \to\everyraggedcommand
+ \fi
+ \!!donecfalse}
+
+\setvalue{\@@ragged@@command\v!middle}%
+ {\if!!donec
+ \if!!doneb \appendtoks\raggedwidecenter\to\everyraggedcommand
+ \else\if!!donea \appendtoks\veryraggedcenter\to\everyraggedcommand
+ \else \appendtoks\raggedcenter \to\everyraggedcommand
+ \fi\fi
+ \!!donecfalse
+ \else
+ \let\raggedbottomcommand\vfilll % bonus, pretty strong
+ \let\raggedtopcommand \vfilll % used with \framed for
+ \fi} % instance in tables
+
+\setvalue{\@@ragged@@command\v!flushleft }{\getvalue{\@@ragged@@command\v!right }}
+\setvalue{\@@ragged@@command\v!flushright}{\getvalue{\@@ragged@@command\v!left }}
+\setvalue{\@@ragged@@command\v!center }{\getvalue{\@@ragged@@command\v!middle}}
+
+\setvalue{\@@ragged@@command\v!high}%
+ {\let\raggedbottomcommand\vfilll} % and since we lack a
+
+\setvalue{\@@ragged@@command\v!low}%
+ {\let\raggedtopcommand\vfilll} % proper keyword, but
+
+\setvalue{\@@ragged@@command\v!lohi}%
+ {\let\raggedbottomcommand\vfilll % we do support the
+ \let\raggedtopcommand\vfilll} % ugly laho (lohi)
+
+\setvalue{\@@ragged@@command\v!no}%
+ {\appendtoks\raggedright\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!yes}%
+ {\appendtoks\notragged\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!normal}%
+ {\appendtoks\notragged\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!inner}% not yet perfect
+ {\signalrightpage % may interfere
+ \doifrightpageelse
+ {\getvalue{\@@ragged@@command\v!right}}
+ {\getvalue{\@@ragged@@command\v!left}}}
+
+\setvalue{\@@ragged@@command\v!outer}% not yet perfect
+ {\signalrightpage % may interfere
+ \doifrightpageelse
+ {\getvalue{\@@ragged@@command\v!left}}
+ {\getvalue{\@@ragged@@command\v!right}}}
+
+\setvalue{\@@ragged@@command\v!lesshyphenation}%
+ {\appendtoks\lesshyphens\to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!morehyphenation}%
+ {\appendtoks\morehyphens\to\everyraggedcommand}
+
+\setvalue{\@@ragged@@command\v!lefttoright}{\appendtoks\lefttoright\to\everyraggedcommand}
+\setvalue{\@@ragged@@command\v!righttoleft}{\appendtoks\righttoleft\to\everyraggedcommand}
+\setvalue{\@@ragged@@command l2r}{\appendtoks\lefttoright\to\everyraggedcommand}
+\setvalue{\@@ragged@@command r2l}{\appendtoks\righttoleft\to\everyraggedcommand}
+
+% compare:
+%
+% \framed[width=4cm,align=no] {\hfil xxx}
+% \framed[width=4cm,align=disable]{\hfil xxx}
+
+\setvalue{\@@ragged@@command\v!disable}% for one liners
+ {\appendtoks\raggedright\parfillskip\zeropoint\to\everyraggedcommand}
+
+\chardef\raggedoneliner\zerocount
+
+\setvalue{\@@ragged@@command\v!line}%
+ {\chardef\raggedoneliner\plusone}
+
+% Nog doen:
+%
+% \goodbreak -> \allowbreak en \dosomebreak{..} in koppen
+%
+% bij koppen zowieso: \blanko[reset]
+
+% Nog in commando verwerken:
%
-% \startrandomized \input tufte \stoprandomized
+% \voorkeur la \blanko
%
-% \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=]
+% Om ongewenste witruimte te voorkomen kan met \dosomebreak{\break}
+% een \penalty voor witruimte worden geplaatst.
-\def\randomizetext{\groupedcommand{\dosetattribute{case}{8}}{}}
+\def\removelastskip % a redefinition of plain
+ {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi}
-% compound stuff (under construction)
+\def\doifoutervmode#1%
+ {\ifvmode\ifinner\else#1\fi\fi}
-\defineattribute[breakpoint]
+\ifx\dosomebreak\undefined % defined in mkiv
-\newbox\breakpointbox
+ \def\dosomebreak#1%
+ {\doifoutervmode
+ {\scratchskip\lastskip
+ \removelastskip
+ %\leavevmode\type{#1}%
+ #1\relax
+ \ifdim\scratchskip=\zeropoint % else interference with footnotes
+ \else
+ \vskip\scratchskip
+ \fi}}
-\definesystemvariable {bp} % BreakPoint
+\fi
-\exhyphenchar=\minusone % we use a different order then base tex, so we really need this
+\def\forgeteverypar
+ {\everypar{\the\neverypar}}
-\newcount \maxbreakpointsid
+\def\forgetparindent
+ {\forgeteverypar
+ \indentfirstparagraphtrue % recently added
+ \let\currentindentation\v!none
+ \ctxparindent\zeropoint
+ \parindent\zeropoint\relax}
-\def\definebreakpoints
- {\dosingleargument\dodefinebreakpoints}
+\def\forgetparskip
+ {\let\currentwhitespace\v!none
+ \ctxparskip\zeropoint
+ \parskip\zeropoint\relax}
-\def\dodefinebreakpoints[#1]%
- {\ifcsname\??bp:#1\endcsname \else
- \global\advance\maxbreakpointsid\plusone
- \setxvalue{\??bp:#1}{\the\maxbreakpointsid}%
+\def\forgetbothskips
+ {\tolerance1500
+ \leftskip\zeropoint
+ \rightskip\zeropoint\relax}
+
+\def\forgetspacing
+ {\emergencystretch\zeropoint}
+
+\newif\ifforgotten % rather good signal for inner
+
+\appendtoks \forgottentrue \to \everyforgetall
+\appendtoks \forgetragged \to \everyforgetall
+\appendtoks \forgetparskip \to \everyforgetall
+\appendtoks \forgetparindent \to \everyforgetall
+\appendtoks \forgetbothskips \to \everyforgetall
+\appendtoks \forgetspacing \to \everyforgetall % i.v.m. funny spacing in pagebody
+\appendtoks \spacing\!!plusone \to \everyforgetall % new per 10/08/2004, else problems in otr / !! needed
+\appendtoks \everypar\emptytoks \to \everyforgetall % indeed!
+
+\def\localvbox#1#%
+ {\vbox#1\bgroup
+ \forgetparskip
+ \setlocalhsize
+ \hsize\localhsize
+ \forgetparindent
+ \forgetbothskips
+ \forgeteverypar
+ \let\next=}
+
+\let\dostopattributes\relax % in case these commands end up in an edef
+
+% \unexpanded\def\dostartattributes#1#2#3%
+% {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+% \ifcsname#1#3\endcsname
+% \let\dostopattributes\@@dostopattributes
+% \startcolor[\csname#1#3\endcsname]%
+% \else
+% \let\dostopattributes\@@nostopattributes
+% \fi
+% \ifcsname#1#2\endcsname
+% \expandafter\doconvertfont
+% \else
+% \expandafter\gobbleoneargument
+% \fi{\csname#1#2\endcsname}}
+
+\newconditional \parbasedattributes
+
+\def\finishparbasedattributes
+ {\ifconditional\parbasedattributes
+ \setfalse\parbasedattributes
+ \par
\fi}
-\def\installbreakpoint
- {\dotripleempty\doinstallbreakpoint}
+\def\dostopparbasedattributes
+ {\settrue\parbasedattributes
+ \dostopattributes}
-% hm, we cannot prebuild lists, font dependent
+\unexpanded\def\@@dostopattributes
+ {\stopcolor
+ \finishparbasedattributes
+ \endgroup}
-\def\doinstallbreakpoint[#1][#2][#3]%
- {\ifcsname\??bp:#1\endcsname
- \begingroup
- \getparameters[\??bp][\c!type=1,\c!nleft=3,\c!nright=3,#3]%
- \ctxlua{breakpoints.setreplacement(\csname\??bp:#1\endcsname,#2,\@@bptype,\@@bpnleft,\@@bpnright)}%
- \endgroup
+\unexpanded\def\@@nostopattributes
+ {\finishparbasedattributes
+ \endgroup}
+
+\unexpanded\def\doattributes#1#2#3#4%
+ {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}
+
+% An even faster \ETEX\ version:
+
+\unexpanded\def\dostartattributes#1#2#3%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifincolor
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \faststartcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \ifcsname#1#2\endcsname
+ % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi}
+
+\unexpanded\def\@@dostopattributes
+ {\faststopcolor
+ \finishparbasedattributes
+ \endgroup}
+
+\unexpanded\def\@@nostopattributes
+ {\finishparbasedattributes
+ \endgroup}
+
+%D Bonus macro, see core-sec.tex
+
+\unexpanded\def\dosetfontattribute#1#2%
+ {\ifcsname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi\empty}
+
+%D Since this happens a lot, and sometimes large arguments
+%D are passed in \type {#4}, we just copy some code:
+
+\unexpanded\def\doattributes#1#2#3#4%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifincolor
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \faststartcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\endgroup
+ \fi
+ \else
+ \let\dostopattributes\endgroup
+ \fi
+ \ifcsname#1#2\endcsname
+ % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi
+ {#4}%
+ \dostopattributes}
+
+% Kan vaker worden toegepast en moet bovendien sneller!
+
+\newskip\leftskipadaption
+\newskip\rightskipadaption
+
+\def\doadaptleftskip#1%
+ {\dosetleftskipadaption{#1}%
+ \advance\leftskip \leftskipadaption}
+
+\def\doadaptrightskip#1%
+ {\dosetrightskipadaption{#1}%
+ \advance\rightskip \rightskipadaption}
+
+\setvalue{@lsa@\v!standard}{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
+\setvalue{@lsa@\v!yes }{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
+\letvalue{@lsa@\v!no }\zeropoint
+\letvalue{@lsa@\empty }\zeropoint
+\setvalue{@rsa@\v!standard}{\@@slright}
+\setvalue{@rsa@\v!yes }{\@@slright}
+\letvalue{@rsa@\v!no }\zeropoint
+\letvalue{@rsa@\empty }\zeropoint
+
+\def\dosetleftskipadaption#1%
+ {\edefconvertedargument\ascii{@lsa@#1}%
+ \leftskipadaption
+ \ifcsname\ascii\endcsname
+ \csname\ascii\endcsname
+ \else
+ #1%
+ \fi
+ \relax}
+
+\def\dosetrightskipadaption#1%
+ {\edefconvertedargument\ascii{@rsa@#1}%
+ \rightskipadaption
+ \ifcsname\ascii\endcsname
+ \csname\ascii\endcsname
+ \else
+ #1%
+ \fi
+ \relax}
+
+\newcount \noftrackedpagestates
+\newif \ifpagestatemismatch
+\newcount \realpagestateno
+\chardef \frozenpagestate \zerocount
+
+\def\dotrackpagestate#1#2%
+ {\ifdoublesided \ifinpagebody \else
+ \doforcedtrackpagestate{#1}{#2}%
+ \fi \fi}
+
+\def\doforcedtrackpagestate#1#2%
+ {\ifcase\frozenpagestate
+ \global\advance\noftrackedpagestates\plusone
+ \global\advance#2\plusone
+ \lazysavetaggedtwopassdata{#1}{\number\noftrackedpagestates}{\number#2}{\noexpand\realfolio}%
+ %\llap{\infofont\number\noftrackedpagestates/\number#2}% tracing
+ \fi}
+
+\def\doifrightpagestateelse#1#2%
+ {\ifcase\frozenpagestate
+ \pagestatemismatchfalse
+ \realpagestateno\realfolio
+ \ifinpagebody
+ \ifdoublesided
+ \ifodd\realpageno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \else
+ \twopassdatafoundtrue
+ \fi
+ \else\ifdoublesided
+ \findtwopassdata{#1}{\number#2}%
+ \iftwopassdatafound
+ \realpagestateno\twopassdata\relax
+ \ifnum\twopassdata=\realpageno \else
+ \pagestatemismatchtrue
+ \fi
+ \ifodd\twopassdata\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \else
+ \ifodd\realpageno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \else
+ \twopassdatafoundtrue
+ \fi\fi
+ \else
+ \ifodd\realpagestateno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \iftwopassdatafound
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\def\doifforcedrightpagestateelse#1#2%
+ {\ifcase\frozenpagestate
+ \pagestatemismatchfalse
+ \realpagestateno\realfolio
+ \findtwopassdata{#1}{\number#2}%
+ \iftwopassdatafound
+ \realpagestateno\twopassdata\relax
+ \ifnum\twopassdata=\realpageno \else
+ \pagestatemismatchtrue
+ \fi
+ \ifodd\twopassdata\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \else
+ \ifodd\realpageno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \else
+ \ifodd\realpagestateno\relax
+ \twopassdatafoundtrue \else \twopassdatafoundfalse
+ \fi
+ \fi
+ \iftwopassdatafound
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\def\freezepagestate {\chardef\frozenpagestate\plusone }
+\def\defrostpagestate{\chardef\frozenpagestate\zerocount}
+
+% we can make more of these on top, but how to deal with mixed frozen states
+
+\definetwopasslist\s!paragraph \newcount \nofraggedparagraphs
+
+\def\signalrightpage {\dotrackpagestate \s!paragraph\nofraggedparagraphs}
+\def\doifrightpageelse{\doifrightpagestateelse\s!paragraph\nofraggedparagraphs}
+
+\newcount\pagesignallevel
+
+\def\startsignalrightpage % one may do a \postsignalrightplace
+ {\advance\pagesignallevel\plusone
+ \presignalrightpage
+ \let\signalrightpage\relax
+ \let\presignalrightpage\relax
+ \let\startsignalrightpage\relax
+ \doifrightpageelse\donothing\donothing
+ \freezepagestate}
+
+\def\stopsignalrightpage
+ {\ifcase\pagesignallevel\or\postsignalrightpage\fi
+ \advance\pagesignallevel\minusone}
+
+\def\setraggedparagraphmode
+ {\signalrightpage\doifrightpageelse} % move it there
+
+\ifx\swapmargins\undefined \let\swapmargins\undefined \fi % todo
+
+\def\doifswappedrightpageelse#1#2% alleen in box construction !
+ {\doifrightpageelse
+ {#1}
+ {\scratchcounter\realpageno
+ \realpageno\realpagestateno\relax
+ \swapmargins
+ \realpageno\scratchcounter
+ #2}}
+
+\newbox\signaledrightpage % this way we can avoid interference, i.e. postpone placement
+
+\def\presignalrightpage {\global\setbox\signaledrightpage\hbox{\signalrightpage}}
+\def\postsignalrightpage{\ifvoid\signaledrightpage\else\box\signaledrightpage\fi}
+
+% The next feature is is used in:
+%
+% \definenumber[test][way=bypage]
+%
+% \def\Test
+% {\incrementnumber[test]\rawnumber[test]/%
+% \incrementnumber[test]\rawnumber[test]/%
+% \incrementnumber[test]\rawnumber[test]\space
+% \checkpagechange{oeps}\changedpage{oeps}\space
+% \ifpagechanged TRUE\else FALSE\fi}
+%
+% \Test\page \Test\par \Test\page \Test\par \Test\page \Test\page
+%
+% (adapted from cont-new.tex:)
+
+\newif\ifpagechanged \let\lastchangedpage\empty
+
+\def\docheckpagestatechange#1#2#3%
+ {\pagechangedfalse
+ \doforcedtrackpagestate{#2}{#3}%
+ \findtwopassdata{#2}{\number#3}%
+ \iftwopassdatafound
+ \ifnum\twopassdata>0\getvalue{#2:p:#1}\relax
+ \pagechangedtrue
+ \fi
+ \fi
+ \ifpagechanged
+ \letgvalue{#2:p:#1}\twopassdata
+ \globallet\lastchangedpage\twopassdata
+ \else
+ \globallet\lastchangedpage\realfolio
\fi}
-\def\setbreakpoints
- {\ctxlua{breakpoints.enabled=true}%
- \gdef\setbreakpoints[##1]{\dosetattribute{breakpoint}{\csname\??bp:##1\endcsname}}%
- \setbreakpoints}
+\def\changedpagestate#1#2%
+ {\executeifdefined{#2:p:#1}{0}}
+
+\def\checkpagechange#1{\docheckpagestatechange{#1}\s!paragraph\nofraggedparagraphs}
+\def\changedpage #1{\changedpagestate{#1}\s!paragraph}
+
+% saved struts
+
+\ifx\savedstrutbox\undefined \newbox\savedstrutbox \fi
+
+\def\savestrut {\setbox\savedstrutbox\copy\strutbox}
+\def\savedstrut{\copy \savedstrutbox}
+
+\chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
+
+\def\bottomalignlimit{3\lineheight}
+
+\newif\ifn@rmalbottom
+\newif\ifr@ggedbottom
+\newif\ifb@selinebottom
+
+\def\normalbottom
+ {% \topskip 10pt
+ \r@ggedbottomfalse}
+
+\def\raggedbottom
+ {\chardef\bottomraggedness\zerocount
+ \n@rmalbottomfalse
+ \r@ggedbottomtrue
+ \b@selinebottomfalse
+ \settopskip}
+
+\def\alignbottom
+ {\chardef\bottomraggedness\plusone
+ \n@rmalbottomtrue
+ \r@ggedbottomfalse
+ \b@selinebottomfalse
+ \settopskip}
+
+\def\baselinebottom
+ {\chardef\bottomraggedness\plustwo
+ \n@rmalbottomfalse
+ \r@ggedbottomfalse
+ \b@selinebottomtrue
+ \settopskip}
+
+\let\normalbottom=\alignbottom % downward compatible
+
+% new code, not in use yet
+
+% for future chinese typo-module:
+%
+% % \let\raggedleft\veryraggedleft
+% % \let\raggedleft\veryraggedright
+%
+% \startbuffer
+% 中中中中中中中中中中中中中中中中中中中中中中中中中%
+% 中中中中中中中中中中中中中中中中中中中中中中中中中%
+% 中中中中中中中中中中中中中中中中中中中中中中中中中%
+% 中中中中中中中中中中中中中中中中中中中中中中中中中%
+% \stopbuffer
+%
+% \framedtext
+% [align={broad,flushright},width=90mm]
+% {\getbuffer}
+%
+% \framedtext
+% [align={broad,flushleft},width=90mm]
+% {\getbuffer}
+%
+% \framedtext
+% [align=middle,width=90mm]
+% {\getbuffer}
+%
+% using just flushleft is not okay here due to the fact that
+% leftskip has less stretch than the inter character spacing
+
+% category:
+%
+% 0 == discard
+% 1 == only if larger
+% 2 == force even if smaller
+% 3 == only take penalty component
+% 4 == add to existing skip
+% 5 == ignore following skips (== disable)
+
+% penalty:
+%
+% larger wins
+
+% order:
+%
+% larger wins
-\letvalue{\??bp:\s!reset}\minusone
+\registerctxluafile{core-spa}{1.001}
+
+\definesystemattribute[kern-chars]
+\definesystemattribute[skip-category]
+\definesystemattribute[skip-penalty]
+\definesystemattribute[skip-order]
+\definesystemattribute[snap-category]
+\definesystemattribute[display-math]
-\definebreakpoints[compound]
+% \start \dosetstretch{.25em} \setuptolerance[tolerant,stretch] \input tufte \endgraf \stop
+% \start \dosetstretch{.5em} effe flink doorfietsen \stop
-\installbreakpoint [compound] [\number`+] [\c!left=3,\c!right=3,\c!type=1]
-\installbreakpoint [compound] [\number`-] [\c!left=3,\c!right=3,\c!type=1]
-\installbreakpoint [compound] [\number`/] [\c!left=3,\c!right=3,\c!type=1]
-\installbreakpoint [compound] [\number`(] [\c!left=3,\c!right=3,\c!type=2]
-\installbreakpoint [compound] [\number`)] [\c!left=3,\c!right=3,\c!type=3]
+\def\dosetupgridsnapping % calls too often, only needed in gridsnapping
+ {\ctxlua{nodes.setsnapvalue(1,\number\openstrutheight,\number\openstrutdepth)}}
-% \setbreakpoints[compound]
+\def\doenablegridsnapping
+ {\dosetattribute{snap-category}{1}%
+ \topskip\strutht
+ \offinterlineskip}
+
+\def\dodisablegridsnapping
+ {\doresetattribute{snap-category}%
+ % reset topskip
+ \oninterlineskip}
% experimental code, not yet interfaced:
@@ -355,7 +2860,7 @@
\def\dodefinevspacing[#1][#2]%
{\ctxlua{vspacing.setmap("#1","#2")}}
-\def\vspacing
+\unexpanded\def\vspacing
{\dosingleempty\dovspacing}
\def\dovspacing[#1]%
@@ -395,30 +2900,1209 @@
\setfalse\vspacingenabled
-% \def\dosomebreak#1%
-% {\doifoutervmode
-% {\scratchskip\lastskip
-% \removelastskip
-% #1\relax
-% \ifconditional\vspacingenabled
-% % we have collapsed so always 0pt
-% \vskip\scratchskip
-% \else\ifdim\scratchskip=\zeropoint
-% % else interference with footnotes
-% \else
-% \vskip\scratchskip
-% \fi\fi}}
-
% ! ! ! ! ! later, now each newline does a \par and call to the callback
-\def\enablevspacing {\settrue \vspacingenabled\ctxlua{vspacing.enable()}}
-\def\disablevspacing{\setfalse\vspacingenabled\ctxlua{vspacing.disable()}}
+\newtoks\everyenablevspacing
+\newtoks\everydisablevspacing
+
+\def\enablevspacing {\the\everyenablevspacing}
+\def\disablevspacing{\the\everydisablevspacing}
+
+\appendtoks
+ \writestatus\m!systems{! ! enabling vspacing ! !}%
+ \settrue\vspacingenabled
+ \ctxlua{vspacing.enable()}%
+\to \everyenablevspacing
+
+\appendtoks
+ \writestatus\m!systems{! ! disabling vspacing ! !}%
+ \setfalse\vspacingenabled
+ \ctxlua{vspacing.disable()}%
+\to \everydisablevspacing
+
+\let\originalblank \blank % we use \original for non-primitives
+\let\originalvspacing\vspacing
\let\setupvspacing\setupblank % for the moment
-\protect \endinput
+% so, the new one will be
+%
+% \chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
+%
+% \def\bottomalignlimit{3\lineheight} % will be settable
+%
+% \def\raggedbottom {\chardef\bottomraggedness=0 \settopskip}
+% \def\alignbottom {\chardef\bottomraggedness=1 \settopskip}
+% \def\baselinebottom{\chardef\bottomraggedness=2 \settopskip}
+%
+% \let\normalbottom =\alignbottom
+
+% \hyphenpenalty = ( 2.5 * \hsize ) / \raggedness
+% \tolerance >= 1500 % was 200
+% \raggedness = 2 .. 6\bodyfontsize
+
+\chardef\raggedstatus=0 % normal left center right
+
+\def\leftraggedness {2\bodyfontsize}
+\def\rightraggedness {2\bodyfontsize}
+\def\middleraggedness {6\bodyfontsize}
+
+\def\middleraggedness {.5\hsize} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
+
+% oeps, hsize can be 0pt in which case we get a strange division
+
+\def\middleraggedness {\ifdim\hsize=\zeropoint6\bodyfontsize\else.5\hsize\fi} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
+
+%D More hyphenation control, will be combined with align
+%D setup.
+
+\def\nohyphens
+ {\ifx\dohyphens\relax
+ \edef\dohyphens
+ {\hyphenpenalty\the\hyphenpenalty
+ \exhyphenpenalty\the\exhyphenpenalty\relax}%
+ \fi
+ \hyphenpenalty\plustenthousand
+ \exhyphenpenalty\plustenthousand}
+
+\let\dohyphens\relax
+
+%D To prevent unwanted side effects, we also have to check
+%D for hyphens here:
+
+\newskip\@@raggedskipa
+\newskip\@@raggedskipb
+
+\def\setraggedness#1%
+ {\ifnum\tolerance<1500\relax % small values have
+ \tolerance1500\relax % unwanted side effects
+ \fi
+ \ifx\dohyphens\relax
+ % this code will be reconsidered / kind of fuzzy (and old)
+ \@@raggedskipa 2.5\hsize
+ \@@raggedskipb #1\relax
+ \divide\@@raggedskipa \@@raggedskipb
+ \hyphenpenalty\@@raggedskipa
+ \fi}
+
+\let\updateraggedskips\relax
+
+\def\setraggedskips#1#2#3#4#5#6#7% never change this name
+ {\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
+ \updateraggedskips}
+
+\def\dosetraggedskips#1#2#3#4#5#6#7%
+ {\chardef \raggedstatus#1\relax
+ \leftskip 1\leftskip \!!plus#2\relax % zie: Tex By Topic 8.1.3
+ \rightskip 1\rightskip\!!plus#3\relax % zie: Tex By Topic 8.1.3
+ \spaceskip #4\relax
+ \xspaceskip #5\relax
+ \parfillskip\zeropoint\!!plus#6\relax
+ \parindent #7\relax}
+
+% \def\notragged%
+% {\setraggedskips{0}{0em}{0em}{0em}{0em}{1fil}{\parindent}}
+
+% older (context) names:
+
+\let\spaceamount \interwordspace
+\let\emspaceamount\emwidth
-\starttext
+% tracing:
+
+\def\doshowpardata#1%
+ {\ifx#1\relax\else
+ \hbox{\string#1: \the#1}\endgraf
+ \expandafter\doshowpardata
+ \fi}
+
+\def\showpardata
+ {\edef\thepardata
+ {\hbox{font: \fontname\font}\endgraf
+ \doshowpardata
+ \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
+ \hsize \vsize
+ \leftskip \rightskip
+ \spaceskip \xspaceskip
+ \parindent \parfillskip
+ \hyphenpenalty \exhyphenpenalty
+ \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty
+ \doublehyphendemerits \finalhyphendemerits \adjdemerits
+ \relax}%
+ \begingroup
+ \dontshowcomposition
+ \inleftmargin{\vsmash
+ {\switchtobodyfont[7pt,tt]%
+ \framed[\c!align=\v!right]{\thepardata}}}%
+ \endgroup}
+
+\def\startshowpardata
+ {\begingroup
+ \showcomposition
+ \showstruts\tracepositionstrue \tracingparagraphs\maxdimen
+ \appendtoksonce\showpardata\let\showpardata\relax\to\everypar}
+
+\def\stopshowpardata
+ {\endgraf
+ \endgroup}
+
+% \defineXMLenvironment[showpardata] \startshowpardata \stopshowpardata
+% \defineXMLsingular [showpardata] \showpardata
+
+% defaults
+
+\def\raggedfillamount {1fil}
+\def\raggedhalffillamount{.5fil}
+\def\raggedspaceamount {\interwordspace} % {.3333em}
+\def\raggedxspaceamount {.5em}
+
+\def\notragged
+ {\chardef\raggedstatus\zerocount
+ \leftskip 1\leftskip
+ \rightskip 1\rightskip
+ \spaceskip \zeropoint
+ \xspaceskip \zeropoint
+ \parfillskip\zeropoint\!!plus\raggedfillamount\relax
+ \let\updateraggedskips\relax} % new
+
+\let\forgetragged\notragged
+
+\def\raggedleft
+ {\setraggedness\leftraggedness
+ \setraggedskips1\leftraggedness\zeropoint\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+\def\raggedcenter
+ {\setraggedness\middleraggedness
+ \setraggedskips2\middleraggedness\middleraggedness\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+%D We used to have:
+%D
+%D \starttyping
+%D \def\raggedright
+%D {\setraggedness\rightraggedness
+%D \setraggedskips{3}{0em}{\rightraggedness}{.3333em}{.5em}{0em}{\parindent}}
+%D \stoptyping
+%D
+%D However, the next alternative, suggested by Taco, is better.
+
+\def\raggedright
+ {\setraggedness\rightraggedness
+ \setraggedskips3\zeropoint\rightraggedness\raggedspaceamount
+ \raggedxspaceamount\raggedfillamount\parindent}
+
+\def\veryraggedleft
+ {\setraggedskips1\raggedfillamount\zeropoint\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+%D When we want the last line to have a natural width:
+%D
+%D \starttyping
+%D \def\veryraggedleft%
+%D {\setraggedskips{1}{1fil}{0em}{.3333em}{.5em}{0em}{-1fil}}
+%D \stoptyping
+%D
+%D but this one is not accepted by the macros.
+
+\def\veryraggedcenter
+ {\setraggedskips2\raggedfillamount\raggedfillamount\raggedspaceamount
+ \raggedxspaceamount\zeropoint\zeropoint}
+
+\def\veryraggedright
+ {\setraggedskips3\zeropoint\raggedfillamount\raggedspaceamount
+ \raggedxspaceamount\zeropoint\parindent}
+
+\def\ttraggedright
+ {\tttf
+ \setraggedskips3\zeropoint\rightraggedness
+ \zeropoint\zeropoint\zeropoint\parindent} % \ctxparindent
+
+%D A bonus one:
+
+\def\raggedwidecenter
+ {\setraggedness\middleraggedness
+ \setraggedskips2\raggedhalffillamount\raggedhalffillamount
+ \raggedspaceamount\raggedxspaceamount\zeropoint\zeropoint}
+
+\newif\if@@asragged \@@asraggedtrue % old method
+
+% todo
+%
+% \setuplayout[grid=yes,lines=44] \showgrid
+% \starttext
+% test \vfill test \endgraf \strut \endgraf \vskip-\lineheight \removedepth \pagina test
+% \stoptext
+
+% \setupalign[reset,new,right,old]
+
+\def\@@align@@rl{\if!!donea\veryraggedleft \else\raggedleft \fi}
+\def\@@align@@rr{\if!!donea\veryraggedright \else\raggedright \fi}
+\def\@@align@@rc{\if!!donea\veryraggedcenter\else\raggedcenter\fi}
+
+\setvalue{@@ngila@@\v!broad }{\!!doneatrue}
+\setvalue{@@ngila@@\v!wide }{\!!donebtrue}
+
+\def\installalign#1#2{\setvalue{@@align@@#1}{#2}} % can be used for overloads
+
+\installalign \v!new {\@@asraggedfalse}
+\installalign \v!old {\@@asraggedtrue}
+\installalign \empty {}
+
+\installalign \v!line {\baselinebottom}
+\installalign \v!bottom {\raggedbottom}
+\installalign \v!height {\normalbottom}
+\installalign \v!width {\notragged}
+\installalign \v!normal {\notragged}
+\installalign \v!yes {\notragged}
+\installalign \v!no {\raggedright}
+\installalign \v!inner {\if@@asragged \setraggedparagraphmode\@@align@@rl\@@align@@rr \else
+ \setraggedparagraphmode\@@align@@rr\@@align@@rl \fi}
+\installalign \v!outer {\if@@asragged \setraggedparagraphmode\@@align@@rr\@@align@@rl \else
+ \setraggedparagraphmode\@@align@@rl\@@align@@rr \fi}
+\installalign \v!left {\if@@asragged\@@align@@rl\else\@@align@@rr\fi}
+\installalign \v!right {\if@@asragged\@@align@@rr\else\@@align@@rl\fi}
+\installalign \v!middle {\if!!doneb\raggedwidecenter\else\@@align@@rc\fi}
+\installalign \v!flushleft {\if!!donea\veryraggedright \else\raggedright\fi}
+\installalign \v!flushright {\if!!donea\veryraggedleft \else\raggedleft \fi}
+\installalign \v!flushouter {\setraggedparagraphmode\raggedleft\raggedright}
+\installalign \v!flushinner {\setraggedparagraphmode\raggedright\raggedleft}
+\installalign \v!center {\if!!doneb\raggedwidecenter\else\@@align@@rc\fi}
+\installalign \v!hanging {\enableprotruding}
+\installalign \v!nothanging {\disableprotruding}
+\installalign \v!hz {\enableadjusting}
+\installalign \v!nohz {\disableadjusting}
+\installalign \v!spacing {\enablespacehandling \enablekernhandling}
+\installalign \v!nospacing {\disablespacehandling\disablekernhandling}
+\installalign \v!hyphenated {\dohyphens}
+\installalign \v!nothyphenated {\nohyphens}
+\installalign \v!new {\@@asraggedfalse} % so new will give you consistency
+\installalign \v!reset {\notragged\normalbottom}
+
+\installalign \v!tolerant {\tolerance3000 \relax}
+\installalign \v!verytolerant {\tolerance4500 \relax}
+\installalign \v!stretch {\emergencystretch\bodyfontsize}
+
+\installalign \v!grid {\doenablegridsnapping } % only mkiv
+\installalign \v!nogrid {\dodisablegridsnapping} % only mkiv
+
+\installalign \v!righttoleft {\lefttoright}
+\installalign \v!lefttoright {\righttoleft}
+\installalign {l2r} {\lefttoright}
+\installalign {r2l} {\righttoleft}
+
+\newcount\hyphenminoffset
+
+\ifx\sethyphenationvariables\undefined \let\sethyphenationvariables\relax \fi
+
+\def\lesshyphens
+ {\advance\hyphenminoffset\plusone
+ \sethyphenationvariables}
+
+\def\morehyphens
+ {\ifcase\hyphenminoffset \else
+ \advance\hyphenminoffset\minusone
+ \fi
+ \sethyphenationvariables}
+
+\installalign \v!lesshyphenation {\lesshyphens}
+\installalign \v!morehyphenation {\morehyphens}
+
+\def\dodosetupalign#1{\csname @@align@@#1\endcsname}
+\def\dodosetupngila#1{\csname @@ngila@@#1\endcsname}
+
+\def\setupalign
+ {\dosingleargument\dosetupalign}
+
+\def\dosetupalign[#1]% can be made faster by checking for defined #1
+ {\!!doneafalse
+ \!!donebfalse
+ \processcommacommand[#1]\dodosetupngila
+ \processcommacommand[#1]\dodosetupalign}
+
+% \setupalign[flushleft] \input ward \par % lijnlinks
+% \setupalign[right] \input ward \par
+
+% \setupalign[flushright] \input ward \par % lijnrechts
+% \setupalign[left] \input ward \par
+
+% \setupalign[middle] \input ward \par % centreer
+% \setupalign[center] \input ward \par
+
+\def\startalignment
+ {\bgroup
+ \setupalign}
+
+\def\stopalignment
+ {\par
+ \egroup}
+
+\chardef\alignstrutmode=1
+
+% see later for the real definition, which in the simple case is:
+
+\newtoks \everyleftofalignedline
+\newtoks \everyrightofalignedline
+
+\def\shiftalignedline#1#2#3#4% left, right, inner, outer
+ {\rightorleftpageaction
+ {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
+ \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
+ {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
+ \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}
+
+\def\doalignline#1#2% \\ == newline
+ {\noindentation % was \noindent
+ \dontleavehmode % added in marrakesch at TUG 2006\begingroup
+ \begingroup
+ \setlocalhsize % new
+ \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
+ \dowithnextbox
+ {\hbox to \localhsize
+ {\ifcase\alignstrutmode\or\strut\fi
+ \the\everyleftofalignedline
+ #1\unhbox\nextbox#2\relax
+ \the\everyrightofalignedline}%
+ \endgroup}
+ \hbox}
+
+% plain commands
+
+\ifx\undefined\line \def\line {\hbox to\hsize} \fi
+\ifx\undefined\leftline \def\leftline #1{\line{#1\hss}} \fi
+\ifx\undefined\rightline \def\rightline #1{\line{\hss#1}} \fi
+\ifx\undefined\centerline \def\centerline#1{\line{\hss#1\hss}} \fi
+
+% directe commando's
+
+\def\leftaligned {\doalignline \relax \hss }
+\def\midaligned {\doalignline \hss \hss }
+\def\rightaligned{\doalignline \hss \relax}
+
+\let\centeraligned\midaligned
+
+\def\regelbegrensd#1{\limitatetext{#1}{\hsize}{\unknown}} % to be translated
+
+% indirecte commando's
+
+\letvalue{\s!do\v!line\v!left }\leftaligned
+\letvalue{\s!do\v!line\v!right }\rightaligned
+\letvalue{\s!do\v!line\v!middle }\midaligned
+\letvalue{\s!do\v!line\v!flushleft }\rightaligned
+\letvalue{\s!do\v!line\v!flushright}\leftaligned
+\letvalue{\s!do\v!line\v!center }\midaligned
+
+\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}
+
+%D Experimental:
+
+\def\doxalignline#1#2#3#4#5#6%
+ {\noindentation % was \noindent
+ \dontleavehmode % added in marrakesch at TUG 2006\begingroup
+ \begingroup
+ \setlocalhsize
+ \def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
+ \dowithnextbox
+ {%\noindent moved up
+ \hbox to \localhsize
+ {#1\hskip\ifdone#2\else#3\fi#4%
+ \hbox to \localhsize
+ {\the\everyleftofalignedline
+ \ifcase\alignstrutmode\or\strut\fi
+ \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
+ \the\everyrightofalignedline}%
+ \hss}%
+ \endgroup}
+ \hbox}
+
+\def\doxcheckline
+ {\signalrightpage\doifrightpageelse\donetrue\donefalse}
+
+\setvalue{\s!do\v!line\v!inner }{\doxalignline\doxcheckline++\zeropoint \relax\hss }
+\setvalue{\s!do\v!line\v!outer }{\doxalignline\doxcheckline++\zeropoint \hss \relax}
+\setvalue{\s!do\v!line\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss }
+\setvalue{\s!do\v!line\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss \relax}
+\setvalue{\s!do\v!line\v!inneredge }{\doxalignline\doxcheckline-+\inneredgetotal \relax\hss }
+\setvalue{\s!do\v!line\v!outeredge }{\doxalignline\doxcheckline+-\outeredgetotal \hss \relax}
+\setvalue{\s!do\v!line\v!backspace }{\doxalignline\doxcheckline-+\backspace \relax\hss }
+\setvalue{\s!do\v!line\v!cutspace }{\doxalignline\doxcheckline+-\cutspace \hss \relax}
+
+\setvalue{\s!do\v!line\v!leftmargin }{\doxalignline\donefalse --\leftmargintotal \hss \relax}
+\setvalue{\s!do\v!line\v!rightmargin}{\doxalignline\donefalse ++\rightmargintotal\relax\hss }
+\setvalue{\s!do\v!line\v!leftedge }{\doxalignline\donefalse --\leftedgetotal \hss \relax}
+\setvalue{\s!do\v!line\v!rightedge }{\doxalignline\donefalse ++\rightedgetotal \relax\hss }
+
+% ! ! ! beware, redefining \doalignline gives the wrong results ! ! !
+%
+% \def\doalignline{\doxalignline\donefalse++\zeropoint}
+
+%D Better:
+
+\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}
+
+\def\alignedline#1#2% setting default
+ {\csname\s!do\v!line\ifcsname\s!do\v!line#1\endcsname#1\else#2\fi\endcsname}
+
+%D ...
+
+\def\dosetuptolerance[#1]%
+ {\doifinsetelse\v!vertical{#1}%
+ {\ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!verystrict=>\def\bottomtolerance{},
+ \v!strict=>\def\bottomtolerance{.050},
+ \v!tolerant=>\def\bottomtolerance{.075},
+ \v!verytolerant=>\def\bottomtolerance{.100}]}%
+ {\ExpandFirstAfter\processallactionsinset
+ [#1]
+ [ \v!stretch=>\emergencystretch\bodyfontsize,
+ \v!space=>\spaceskip.5em\!!plus.25em\!!minus.25em\relax,
+ \v!verystrict=>\tolerance 200,
+ \v!strict=>\tolerance1500,
+ \v!tolerant=>\tolerance3000,
+ \v!verytolerant=>\tolerance4500]}}
+
+\def\setuptolerance
+ {\dosingleargument\dosetuptolerance}
+
+% \def\woordrechts
+% {\groupedcommand{\hfill\hbox}{\parfillskip\zeropoint}}
+
+% beware: \wordright{whatever\kern-\rightskip} should work!
+% so, no funny boxing here
+
+\def\dowordright[#1]%
+ {% don't change
+ \groupedcommand
+ {\removeunwantedspaces
+ \hfill
+ \allowbreak % changed back from \hskip\zeropoint
+ \strut
+ \hfill
+ \quad % decent spacing
+ \hbox}
+ {\doifelse{#1}\v!right{\kern-\rightskip}{\doifsomething{#1}{\kern-#1}}%
+ \parfillskip\zeropoint
+ %\finalhyphendemerits\zerocount % yes or no
+ \par}}
+
+\def\wordright
+ {\dosingleempty\dowordright}
+
+% \dorecurse{5}{something } \wordright{--someone} \endgraf
+% \dorecurse{6}{something } \wordright{--someone} \endgraf
+% \dorecurse{7}{something } \wordright{--someone} \endgraf
+%
+% \dorecurse{5}{something } \wordright{--someone else entirely} \endgraf
+% \dorecurse{6}{something } \wordright{--someone else entirely} \endgraf
+% \dorecurse{7}{something } \wordright{--someone else entirely} \endgraf
+%
+% \wordright[\rightskip]{whatever}
+
+% \simplealignedbox{2cm}{right}{x}
+
+\setvalue{\s!simple\c!align\v!right }#1#2{\hbox to #1{#2\hss}}
+\setvalue{\s!simple\c!align\v!left }#1#2{\hbox to #1{\hss#2}}
+\setvalue{\s!simple\c!align\v!flushright }#1#2{\hbox to #1{\hss#2}}
+\setvalue{\s!simple\c!align\v!flushleft }#1#2{\hbox to #1{#2\hss}}
+\setvalue{\s!simple\c!align\v!middle }#1#2{\hbox to #1{\hss#2\hss}}
+
+\def\simplealignedbox#1{\executeifdefined{\s!simple\c!align#1}{\getvalue{\s!simple\c!align\v!right}}}
+
+%D \macros
+%D {pushindentation,popindentation}
+%D
+%D The pushing and popping is done by:
+
+\newbox\indentationboxA
+\newbox\indentationboxB
+
+\def\pushindentation
+ {\bgroup
+ \ifhmode
+ \unskip
+ \setbox\indentationboxA\lastbox % get \strut if present
+ \unskip
+ \setbox\indentationboxB\lastbox % get \indent generated box
+ \unskip
+ \else
+ \hskip\zeropoint % switch to horizontal mode
+ \unskip
+ \setbox\indentationboxA\lastbox % get \indent generated box
+ \setbox\indentationboxB\emptybox
+ \fi}
+
+\def\popindentation
+ {\box\indentationboxB\box\indentationboxA % put back the boxes
+ \egroup}
+
+%D The only complication lays in \type{\strut}. In \PLAIN\
+%D \TEX\ a \type{\strut} is defined as:
+%D
+%D \starttyping
+%D \def\strut%
+%D {\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
+%D \stoptyping
+%D
+%D But what is a \type{\strut}? Normally it's a rule of width
+%D zero, but when made visual, it's a rule and a negative skip.
+%D The mechanism for putting things in the margins described
+%D here cannot handle this situation very well. One
+%D characteristic of \type{\strut} is that the \type{\unhcopy}
+%D results in entering horizontal mode, which in return leads
+%D to some indentation.
+%D
+%D To serve our purpose a bit better, the macro \type{\strut}
+%D can be redefined as:
+%D
+%D \starttyping
+%D \def\strut
+%D {\relax\ifmmode\else\hskip0pt\fi\copy\strutbox}
+%D \stoptyping
+%D
+%D Or more compatible:
+%D
+%D \starttyping
+%D \def\strut
+%D {\relax\ifmmode
+%D \copy\strutbox
+%D \else
+%D \bgroup\setbox\strutbox=\normalhbox{\box\strutbox}\unhcopy\strutbox\egroup
+%D \fi}
+%D \stoptyping
+%D
+%D In \CONTEXT\ however we save some processing time by putting
+%D an extra \type{\hbox} around the \type{\strutbox}.
+
+% moved from page-lin.tex to here (due to visualization added
+% in august 2003)
+%
+% \unexpanded \def\crlf
+% {\ifhmode\unskip\else\strut\fi\ifcase\raggedstatus\hfil\fi\break}
+
+\unexpanded \def\crlf
+ {\ifhmode
+ \unskip
+ \prewordbreak\crlfplaceholder
+ \ifcase\raggedstatus\hfil\or\or\or\hfil\fi
+ \break
+ \else
+ \crlfplaceholder
+ \endgraf
+ \fi}
+
+\def\crlfplaceholder
+ {\strut}
+
+\def\settestcrlf
+ {\def\crlfplaceholder
+ {\hbox to \zeropoint
+ {\strut{\infofont\kern.25em}\lohi{\infofont CR}{\infofont LF}\hss}}}
+
+%D \starttyping
+%D % \setuplayout[gridgrid=yes] \showgrid
+%D
+%D \startbuffer
+%D test 1\crlf
+%D test 2\crlf
+%D
+%D \crlf test 3
+%D
+%D test 4\crlf
+%D test 5
+%D
+%D \crlf
+%D \crlf
+%D \crlf
+%D test 6
+%D \stopbuffer
+%D
+%D \hbox
+%D {\hsize5em
+%D \ruledvtop{\getbuffer}\enspace
+%D \ruledvtop{\showstruts\getbuffer}\enspace
+%D \hsize15em \setuptyping[before=,after=]%
+%D \ruledvtop{\typebuffer}}
+%D \stoptyping
+
+\def\justonespace
+ {\removelastspace\space} % \removeunwantedspaces\space
+
+\def\ignorecrlf
+ {\let\crlf\justonespace\let\\\crlf}
+
+\def\showstruts
+ {\setteststrut
+ \settestcrlf}
+
+\def\definehspace
+ {\dotripleempty\dodefinehspace}
+
+\def\dodefinehspace[#1][#2][#3]% #1 = optional namespace
+ {\ifthirdargument
+ \setvalue{\??hs#1:#2}{#3}%
+ \else
+ \setvalue{\??hs:#1}{#2}%
+ \fi}
+
+\unexpanded\def\hspace
+ {\dodoubleempty\dohspace}
+
+\def\dohspace[#1][#2]%
+ {\ifsecondargument
+ \dodohspace[#1][#2]%
+ \else\iffirstargument
+ \hspace[][#1]%
+ \else
+ \hspace[][\s!default]%
+ \fi\fi}
+
+\def\dodohspace[#1][#2]%
+ {\ifhmode
+ \removeunwantedspaces
+ \hskip\hspaceamount{#1}{#2}%
+ \expandafter\ignorespaces
+ \fi}
+
+\def\hspaceamount#1#2%
+ {\executeifdefined{\??hs#1:#2}{\executeifdefined{\??hs:#2}\zeropoint}}
+
+\definehspace [\v!small] [.25\emspaceamount]
+\definehspace [\v!medium] [.5\emspaceamount]
+\definehspace [\v!big] [1\emspaceamount]
+\definehspace [\v!normal] [1\spaceamount]
+\definehspace [\v!default] [\spaceamount]
+
+%D Taken from Taco's math module (cq. \AMS\ macros), but
+%D adapted to \type {\hspace}:
+
+\unexpanded\def\textormathspace#1#2#3%
+ {\ifmmode\mskip#1#2\else\kern#1\hspaceamount\empty{#3}\fi\relax}
+
+\newmuskip\hairmuskip \hairmuskip=.15mu
+
+\unexpanded\def\hairspace {\textormathspace+\hairmuskip{.5}}
+\unexpanded\def\thinspace {\textormathspace+\thinmuskip 1}
+\unexpanded\def\medspace {\textormathspace+\medmuskip 2}
+\unexpanded\def\thickspace {\textormathspace+\thickmuskip3}
+\unexpanded\def\neghairspace {\textormathspace-\thinmuskip{.5}}
+\unexpanded\def\negthinspace {\textormathspace-\thinmuskip 1}
+\unexpanded\def\negmedspace {\textormathspace-\medmuskip 2}
+\unexpanded\def\negthickspace{\textormathspace-\thickmuskip3}
+
+% needed for unicode:
+
+\unexpanded\def\twoperemspace {\hskip\dimexpr\emwidth/2\relax} % == \enspace
+\unexpanded\def\threeperemspace {\hskip\dimexpr\emwidth/3\relax}
+\unexpanded\def\fourperemspace {\hskip\dimexpr\emwidth/4\relax}
+\unexpanded\def\fiveperemspace {\hskip\dimexpr\emwidth/5\relax} % goodie
+\unexpanded\def\sixperemspace {\hskip\dimexpr\emwidth/6\relax}
+\unexpanded\def\figurespace {\begingroup\setbox\scratchbox\hbox{0}\hskip\wd\scratchbox\endgroup} % there is a command for this
+\unexpanded\def\punctuationspace {\begingroup\setbox\scratchbox\hbox{.}\hskip\wd\scratchbox\endgroup}
+\unexpanded\def\ideographicspace {\hskip\dimexpr\emwidth/1\relax}
+\unexpanded\def\ideographichalffillspace{\hskip\dimexpr\emwidth/2\relax}
+%unexpanded\def\nobreakspace {\penalty\plustenthousand\space}
+\unexpanded\def\nobreakspace {\penalty\plustenthousand\kern\interwordspace}
+\unexpanded\def\narrownobreakspace {\penalty\plustenthousand\thinspace}
+%unexpanded\def\zerowidthnobreakspace {\penalty\plustenthousand\hskip\zeropoint}
+\unexpanded\def\zerowidthnobreakspace {\penalty\plustenthousand\kern\zeropoint}
+\unexpanded\def\zerowidthspace {\hskip\zeropoint}
+
+\definehspace[.5][.1250\emspaceamount] % could also be [.1250\spaceamount]
+\definehspace[1] [.1667\emspaceamount]
+\definehspace[2] [.2222\emspaceamount]
+\definehspace[3] [.2777\emspaceamount]
+
+\let \, \thinspace
+\let \: \medspace
+\let \; \thickspace
+\let \! \negthinspace
+
+% this will become an alternative bunch of \blank settings
+%
+% \startlines
+% \scratchskip=.23pt plus 10pt minus 4pt \relax \number\scratchskip \space \the\scratchskip
+% \setsimplifiedskip\scratchskip1 \number\scratchskip \space \the\scratchskip
+% \setsimplifiedskip\scratchskip2 \number\scratchskip \space \the\scratchskip
+% \getsimplifiedskip\scratchskip\scratchcounter \number\scratchcounter
+% \stoplines
+%
+% \hrule width10cm \endgraf
+% \discardedskip{10pt}
+% \retainedskip {4pt}
+% \discardedskip {5pt}
+% \hrule width10cm \endgraf
+% \blockedskip{0pt}
+% \discardedskip{10pt}
+% \retainedskip {4pt}
+% \discardedskip {5pt}
+% \hrule width10cm \endgraf
+% \frozenskip {4cm}
+% \hrule width10cm \endgraf
+% \vskip10pt
+% \hrule width10cm \endgraf
+
+\newskip\simplifiedskip
+\newskip\simplifiedcounter
+
+\chardef\@@discardedskip1
+\chardef\@@retainedskip 2
+\chardef\@@forcedskip 3
+\chardef\@@blockedskip 4
+\chardef\@@frozenskip 5 % after heads, no break
+
+\def\setsimplifiedskip#1#2%
+ {#1\dimexpr(10\dimexpr(#1/10)) plus \gluestretch#1 minus \glueshrink#1\relax
+ \advance#1\numexpr(#2)sp\relax}
+
+\def\getsimplifiedskip#1#2%
+ {\simplifiedskip#1\relax
+ \ifzeropt\simplifiedskip % \ifdim\simplifiedskip=\zeropoint
+ #2\zerocount
+ \else
+ \simplifiedcounter\dimexpr10\dimexpr#1/10\relax\relax
+ \advance\simplifiedskip-\simplifiedcounter
+ #2\number\simplifiedskip\relax
+ \fi}
+
+\def\conditionalskip#1#2%
+ {\scratchskip#1\relax
+ \setsimplifiedskip\scratchskip#2\relax
+ \vskip\scratchskip\relax}
+
+\def\defrostskip
+ {\scratchskip\lastskip\penalty50000\normalvskip-\scratchskip\penalty50000\relax}
+
+\def\frozenskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \fi}
+
+\def\discardedskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifcase\scratchcounter
+ \conditionalskip{#1}\@@discardedskip
+ \or % discard
+ \ifdim\lastskip>#1\else
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@discardedskip
+ \fi
+ \or % retain
+ \ifdim\lastskip>#1\else
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@discardedskip
+ \fi
+ \or % forced
+ \conditionalskip{#1}\@@discardedskip
+ \or % ignored
+ \or % frozen
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \else\ifdim#1=\zeropoint\else
+ \vskip#1\relax
+ \fi\fi
+ \fi}
+
+\def\retainedskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifcase\scratchcounter
+ \conditionalskip{#1}\@@retainedskip
+ \or % discard
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@retainedskip
+ \or % retain
+ \ifdim\lastskip>#1\else
+ \normalvskip-\lastskip
+ \conditionalskip{#1}\@@retainedskip
+ \fi
+ \or % forced
+ \conditionalskip{#1}\@@retainedskip
+ \or % ignored
+ \or % frozen
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \else\ifdim#1=\zeropoint\else
+ \vskip#1\relax
+ \fi\fi
+ \fi}
+
+\def\forcedskip#1%
+ {\endgraf
+ \ifvmode
+ \conditionalskip{#1}\@@forcedskip
+ \fi}
+
+\def\blockedskip#1%
+ {\endgraf
+ \ifvmode
+ \getsimplifiedskip\lastskip\scratchcounter
+ \ifcase\scratchcounter
+ \conditionalskip{#1}\@@blockedskip
+ \or % discard
+ \conditionalskip{#1}\@@blockedskip
+ \or % retain
+ \conditionalskip{#1}\@@blockedskip
+ \or % forced
+ \conditionalskip{#1}\@@blockedskip
+ \or % ignored
+ \or % frozen
+ \ifdim\lastskip>#1\else
+ \defrostskip
+ \conditionalskip{#1}\@@frozenskip
+ \fi
+ \else\ifdim#1=\zeropoint\else
+ \vskip#1\relax
+ \fi\fi
+ \fi}
+
+% beware, changing this will break some code (like pos/backgrounds)
+
+\newtoks\everyfirstparagraphintro
+\newtoks\everynextparagraphintro
+\newtoks\@@everyparagraphtoks
+
+\chardef\everyparagraphintro\zerocount
+
+\def\setupparagraphintro
+ {\dodoubleempty\dosetupparagraphintro}
+
+\def\dosetupparagraphintro[#1][#2]%
+ {\processallactionsinset
+ [#1]
+ [ \v!reset=>\global\chardef\everyparagraphintro\zerocount
+ \global\everyfirstparagraphintro\emptytoks
+ \global\everynextparagraphintro \emptytoks,
+ \v!first=>\global\chardef\everyparagraphintro\plusone
+ \doglobal\appendtoks#2\to\everyfirstparagraphintro,
+ \v!next=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plusone\fi
+ \doglobal\appendtoks#2\to\everynextparagraphintro,
+ \v!each=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plustwo\fi
+ \doglobal\appendtoks#2\to\everyfirstparagraphintro
+ \doglobal\appendtoks#2\to\everynextparagraphintro]}
+
+%D We can say:
+%D
+%D \starttyping
+%D \setupparagraphintro[first][\index{Knuth}]
+%D \stoptyping
+%D
+%D Maybe more convenient is:
+%D
+%D \starttyping
+%D \flushatparagraph{\index{Zapf}}
+%D \stoptyping
+
+\def\flushatparagraph#1%
+ {\global\chardef\everyparagraphintro\plusone
+ \global\appendtoks{#1}\to\everyfirstparagraphintro}
+
+\def\doinsertparagraphintro
+ {\begingroup
+ \everypar\emptytoks
+ \ifcase\everyparagraphintro\relax
+ % no data
+ \@@everyparagraphtoks\emptytoks
+ \or
+ % first data
+ \global\chardef\everyparagraphintro\plustwo
+ \@@everyparagraphtoks\everyfirstparagraphintro
+ \global\everyfirstparagraphintro\emptytoks
+ \or
+ % next data
+ \@@everyparagraphtoks\everynextparagraphintro
+ \fi
+ \the\@@everyparagraphtoks
+ \endgroup}
+
+\def\insertparagraphintro
+ {\ifcase\everyparagraphintro\else\@EA\doinsertparagraphintro\fi}
+
+% \appendtoksonce\insertparagraphintro\to\everypar % should come last
+
+%D \starttyping
+%D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}]
+%D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}]
+%D \setupparagraphintro[next] [\hbox to 3.5em{\tt NEXT \hss}]
+%D \setupparagraphintro[next] [\hbox to 3.5em{\tt TXEN \hss}]
+%D \setupparagraphintro[each] [\hbox to 3.0em{\tt EACH \hss}]
+%D \setupparagraphintro[each] [\hbox to 3.0em{\tt HCEA \hss}]
+%D
+%D some paragraph \par
+%D some paragraph \par
+%D some paragraph \par
+%D
+%D \definelabel[parnumber]
+%D
+%D \setupparagraphintro[reset,each][\inleft{\slxx\parnumber}]
+%D
+%D some paragraph \par
+%D some paragraph \par
+%D some paragraph \par
+%D \stoptyping
+
+%D \macros
+%D {flushatnextpar}
+%D
+%D This macro collects data that will be flushed at the next paragraph.
+%D By using this macro you can avoid interfering nodes (writes, etc).
+
+\newbox \postponednodedata
+
+\def\flushatnextpar
+ {\bgroup
+ \dowithnextbox
+ {\global\setbox\postponednodedata\hbox{\box\postponednodedata\box\nextbox}\egroup}%
+ \hbox}
+
+\def\flushpostponednodedata
+ {\ifvoid\postponednodedata\else
+ \hbox{\smashedbox\postponednodedata}%
+ \fi}
+
+% Very nasty but needed for margin stuff inside colored
+% paragraphs.
+
+\let\normalvadjust\vadjust
+
+% test this prikkels/pascal margin text before heads (mode
+% 1) as well as uitwerkingen (mode 2)
+
+%chardef\graphicvadjustmode=0 % fake
+%chardef\graphicvadjustmode=1 % normal
+\chardef\graphicvadjustmode=2 % normal + compensate (== default)
+
+\def\graphicvadjust % bad, those low level color calls here
+ {\dowithnextboxcontent
+ {\forgetall}
+ {\ifcase\graphicvadjustmode \@EA \fakedvadjust \else \@EA\normalvadjust \fi
+ {\dostartgraphicgroup % don't ask
+ \localstarttextcolor
+ \unvbox\nextbox
+ \localstoptextcolor % don't ask
+ \dostopgraphicgroup
+ \ifcase\graphicvadjustmode \or \or
+ % corrects for one line paragraphs
+ \nointerlineskip
+ \kern-\struttotal
+ \nointerlineskip
+ \verticalstrut
+ \fi}}%
+ \vbox}
+
+%D This works only in a properly strutted line, and is meant
+%D for deeply burried operations, like in heads.
+
+\def\fakedvadjust
+ {\dowithnextbox
+ {\setbox\nextbox\hbox{\llap{\lower\strutdepth\box\nextbox}}%
+ \smashedbox\nextbox}%
+ \vtop}
+
+\def\flexiblespaceamount#1#2#3%
+ {#1\interwordspace
+ \!!plus#2\interwordstretch
+ \!!minus#3\interwordshrink}
+
+\def\fixedspaceamount#1%
+ {#1\interwordspace}
+
+%D This is a dangerous feature because it makes the \TEX\ source
+%D less portable, i.e. any parser now needs to apply exactly the
+%D same algorithm when it wants to interpret the source. We
+%D strongly recommend not to mention this feature in manuals! It's
+%D provided for users who are hooked to such a mechanism.
+%D
+%D \starttyping
+%D \setupsorting[logo][next=\autoinsertnextspace] \logo[TEX]{\TeX}
+%D
+%D bla bla \TEX bla bla \TEX (bla) bla (\TEX)
+%D \stoptyping
+
+\def\autoinsertnextspace{\futurelet\nexttoken\doautoinsertnextspace}
+
+\def\doautoinsertnextspace % slightly extended version of a user supplied macro
+ {\ifx\nexttoken \bgroup\else \ifx\nexttoken\begingroup\else
+ \ifx\nexttoken \egroup\else \ifx\nexttoken \endgroup\else
+ \ifx\nexttoken \/\else \ifx\nexttoken /\else \ifx\nexttoken ~\else
+ \ifx\nexttoken \ \else \ifx\nexttoken \blankspace\else \ifx\nexttoken \space\else
+ \ifx\nexttoken .\else \ifx\nexttoken ,\else
+ \ifx\nexttoken !\else \ifx\nexttoken ?\else
+ \ifx\nexttoken :\else \ifx\nexttoken ;\else
+ \ifx\nexttoken '\else \ifx\nexttoken "\else
+ \ifx\nexttoken )\else \ifx\nexttoken -\else \ifx\nexttoken |\else
+ \ifx\nexttoken \%\else \ifx\nexttoken \&\else
+ \space
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% moved from page-lin
+
+\def\installspacehandler#1#2% needs to set \obeyedspace
+ {\setvalue{\??sr#1}{#2}}
+
+\installspacehandler \v!on
+ {\obeyspaces
+ \def\obeyedspace{\mathortext\normalspace{\dontleavehmode{\tt\controlspace}}}%
+ \let\ =\obeyedspace}
+
+\installspacehandler \v!yes
+ {\obeyspaces
+ \def\obeyedspace{\mathortext\normalspace{\dontleavehmode \normalspace }}%
+ \let\ =\obeyedspace}
+
+\installspacehandler \v!off
+ {\normalspaces
+ \let\obeyedspace\normalspace
+ \let\ =\normalspace}
+
+\installspacehandler \v!fixed
+ {\obeyspaces
+ \def\obeyedspace{\mathortext\normalspace{\dontleavehmode\fixedspace}}%
+ \let\ =\obeyedspace}
+
+\def\activatespacehandler#1%
+ {\executeifdefined{\??sr#1}{\activatespacehandler\v!off}}
+
+% moved from page-lin
+
+%D When spacing is active we need to handle commands in
+%D a special way:
+%D
+%D \starttyping
+%D \setuplines[space=on]
+%D
+%D \startlines
+%D Let's talk about this{\ttsl\gobbleoneargument or}that.
+%D \stoplines
+%D
+%D \startlines
+%D Let's talk about this{\getvalue{ttsl}or}that.
+%D \stoplines
+%D \stoptyping
+%D
+%D One can indent in several ways:
+%D
+%D \starttyping
+%D \setupindenting[medium] \setuplines[indenting=odd] % no yes odd even
+%D
+%D \startlines
+%D first
+%D second
+%D third
+%D fourth
+%D \stoplines
+%D \stoptyping
+
+\def\setuplines
+ {\dodoubleargument\getparameters[\??rg]}
+
+\def\startlines
+ {\@@rgbefore
+ \pushmacro\checkindentation
+ \whitespace
+ %\page[\v!preference]} gaat mis na koppen, nieuw: later \nobreak
+ \begingroup
+ \setupindenting[\@@rgindenting]%
+ \typesettinglinestrue
+ \setupwhitespace[\v!none]%
+ \obeylines
+ \ignorespaces
+ \gdef\afterfirstobeyedline % tzt two pass, net als opsomming
+ {\gdef\afterfirstobeyedline
+ {\nobreak
+ \global\let\afterfirstobeyedline\relax}}%
+ \def\obeyedline
+ {\par
+ \afterfirstobeyedline
+ \futurelet\next\dobetweenthelines}%
+ \activatespacehandler\@@rgspace
+ \GotoPar}
+
+\def\stoplines
+ {\endgroup
+ \popmacro\checkindentation
+ \@@rgafter}
+
+\def\dobetweenthelines
+ {\doifmeaningelse\next\obeyedline\@@rginbetween\donothing}
+
+\setuplines
+ [\c!before=\blank,
+ \c!after=\blank,
+ \c!inbetween=\blank,
+ \c!indenting=\v!no,
+ \c!space=\v!default]
+
+\def\emptylines
+ {\dosingleempty\doemptylines}
+
+\def\doemptylines[#1]%
+ {\endgraf\dorecurse{\iffirstargument#1\else3\fi}\crlf}
+
+\setupwhitespace
+ [\v!none]
+
+% still old-fashioned
+
+\indenting
+ [\v!never]
+
+\setupindenting
+ [\v!none]
+
+\setupblank
+ [\v!standard,
+ \v!big]
+
+\defineblank[\v!default] [\currentblank]
+\defineblank[\v!before] [\v!default]
+\defineblank[\v!inbetween][\v!default]
+\defineblank[\v!after] [\v!before]
+
+\setupinterlinespace
+ [\c!minheight=0pt, % only special purpose
+ \c!mindepth=0pt, % only special purpose
+ \c!height=.72,
+ \c!depth=.28,
+ \c!top=1.0,
+ \c!bottom=0.4,
+ \c!distance=1pt,
+ \c!line=2.8ex,
+ \c!stretch=0]
+
+\setupnarrower
+ [\c!before=\endgraf,
+ \c!after=\endgraf,
+ \c!left=1.5em,
+ \c!right=1.5em,
+ \c!middle=1.5em]
+
+\setuptolerance
+ [\v!horizontal,\v!verystrict]
+
+\setuptolerance
+ [\v!vertical,\v!strict]
+
+\setupalign
+ [\v!bottom,
+ \v!width]
+
+\setupspacing
+ [\v!packed]
+
+\protect \endinput
\dorecurse{2}{
$2^{2^{2^{2}}}$ $2_{2_{2_{2}}}^{2^{2^{2^{2^{2^{2^{2^{2^{2}}}}}}}}}$
@@ -470,71 +4154,3 @@
\vskip10pt
fifth
}
-
-% bidi test
-
-\definefontfeature
- [arab]
- [mode=node,language=dflt,script=arab,
- init=yes,medi=yes,fina=yes,isol=yes,
- liga=yes,dlig=yes,rlig=yes,clig=yes,
- mark=yes,mkmk=yes,kern=yes,curs=yes]
-
-\font\Arabic=arabtype*arab at 20pt
-
-\def\LATIN{LATIN} {\setcharactermirroring[1]} % enable this
-\def\ARAB {محمد}
-
-\startluacode
- function document.split_tokens(str)
- for s in str:bytes() do
- tex.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s))
- end
- end
-\stopluacode
-
-\def\biditest#1#2#3% font text raw
- {\dontleavehmode\hbox
- {\framed[offset=overlay]{\tttf#2}\quad
- \ctxlua{mirror.trace = true}%
- \framed[offset=overlay]{#1#3}\quad
- \ctxlua{mirror.trace = false}
- \tttf\ctxlua{document.split_tokens([[\detokenize{#3}]])}}}
-
-\startbuffer[bidi-sample]
-\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{LATIN ARAB}{\textdir TLT{\bidilro \LATIN\ \ARAB}}\par % right -> left
-\biditest\Arabic{LATIN ARAB}{\textdir TRT{\bidilro \LATIN\ \ARAB}}\par % right -> left
-\biditest\Arabic{BARA NITAL}{\textdir TLT{\bidirlo \LATIN\ \ARAB}}\par % left -> right
-\biditest\Arabic{BARA NITAL}{\textdir TRT{\bidirlo \LATIN\ \ARAB}}\par % left -> right
-\stopbuffer
-
-\startbuffer[bidi-sample]
-\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par
-\biditest\Arabic{LATIN ARAB}{\textdir TLT\bidilro \LATIN\ \ARAB}\par % right -> left
-\biditest\Arabic{LATIN ARAB}{\textdir TRT\bidilro \LATIN\ \ARAB}\par % right -> left
-\biditest\Arabic{BARA NITAL}{\textdir TLT\bidirlo \LATIN\ \ARAB}\par % left -> right
-\biditest\Arabic{BARA NITAL}{\textdir TRT\bidirlo \LATIN\ \ARAB}\par % left -> right
-\stopbuffer
-
-\startbuffer[bidi-setup]
-\setupdirections[bidi=off]
-\stopbuffer
-
-{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
-
-\startbuffer[bidi-setup]
-\setupdirections[bidi=global]
-\stopbuffer
-
-{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
-
-\startbuffer[bidi-setup]
-\setupdirections[bidi=local]
-\stopbuffer
-
-{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
-
-\stoptext
diff --git a/tex/context/base/core-spa.tex b/tex/context/base/core-spa.tex
deleted file mode 100644
index 31a75876e..000000000
--- a/tex/context/base/core-spa.tex
+++ /dev/null
@@ -1,4637 +0,0 @@
-%D \module
-%D [ file=core-spa,
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Spacing,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Spacing Macros}
-
-% to be sorted out: dependencies, order of initialization / also some dutch code here
-
-\unprotect
-
-% interfacing mkii/mkiv
-
-\ifx\mksetupgridsnapping \undefined \let\mksetupgridsnapping \relax \fi
-\ifx\mkenablegridsnapping \undefined \let\mkenablegridsnapping \relax \fi
-\ifx\mkdisablegridsnapping\undefined \let\mkdisablegridsnapping\relax \fi
-
-% some will move to core-var
-
-\newif \ifgridsnapping
-\newif \iffuzzyvskip
-\let \fuzzyvskip \gobbleoneargument
-\let \removelastfuzzyvskip \relax
-
-\let \startbaselinecorrection \relax
-\let \stopbaselinecorrection \relax
-\let \baselinecorrection \relax
-\let \offbaselinecorrection \relax
-
-\appendtoks \spacing 1\to \everybodyfont
-\appendtoks \presetnormallineheight \to \everybodyfont
-\appendtoks \setnormalbaselines \to \everybodyfont % check if redundant
-\appendtoks \setstrut \to \everybodyfont % check if redundant
-\appendtoks \settopskip \to \everybodyfont
-\appendtoks \setmaxdepth \to \everybodyfont
-%appendtoks \spacing 1\to \everybodyfont
-\appendtoks \simplesetupindenting \to \everybodyfont
-\appendtoks \simplesetupblank \to \everybodyfont
-\appendtoks \simplesetupwhitespace \to \everybodyfont
-%appendtoks \checknotes \to \everybodyfont % not
-\appendtoks \simplesetupspacing \to \everybodyfont % nieuw
-\appendtoks \setrelativeinterlinespace \to \everybodyfont
-
-\appendtoks \updateraggedskips \to \everyfontswitch % under test
-\prependtoks \let\par\endgraf \to \everypagebody % see \fillinline
-\appendtoks \simplesetupspacing \to \everydefinedfont
-
-% if you want to hyphenate the first word of a paragraph ... \appendtoks\hskip0pt\to\everypar
-
-\def\stelfactorenin
- {\simplesetupwhitespace
- \simplesetupblank
- \settopskip
- \setmaxdepth}
-
-\def\softbreak
- {\relax\ifhmode\hskip\parfillskip\break\fi}
-
-\let\poplastnode\relax
-
-\def\pushlastnode
- {\ifdim\lastskip=\zeropoint
- \ifnum\lastpenalty=\zerocount
- \ifnum\lastkern=\zerocount
- \let\poplastnode\relax
- \else
- \edef\poplastnode{\kern\the\lastkern\relax}\kern-\lastkern % untested
- \fi
- \else
- \edef\poplastnode{\penalty\the\lastpenalty\relax}\nobreak % untested
- \fi
- \else
- \edef\poplastnode{\vskip\the\lastskip\relax}\vskip-\lastskip % \removelastskip
- \fi}
-
-%D The dreadful sequence \type {\bgroup} \unknown\
-%D \type {\carryoverpar} \unknown\ \type {\egroup} is needed
-%D when for instance sidefloats are used in combination with
-%D something that starts with a group. This is because
-%D otherwise the indentation as set (by the output routine)
-%D inside the group are forgotten afterwards. (I must
-%D not forget its existence).
-
-\global\let\carriedoverpar\relax
-
-\def\carryoverpar#1%
- {\expanded % \scratchtoks{#1}%
- {\noexpand#1% \the\scratchtoks
- \hangindent\the\hangindent
- \hangafter \the\hangafter
- \parskip \the\parskip
- \leftskip \the\leftskip
- \rightskip \the\rightskip}}
-
-%D A quick way to determine left|/|middle|/|right states
-%D (experimental).
-
-\setvalue{\??as\v!left }{0}
-\setvalue{\??as\v!middle}{1}
-\setvalue{\??as\v!right }{2}
-
-\def\setalignmentswitch#1%
- {\chardef\alignmentswitch0\csname\??as#1\endcsname\relax}
-
-%D There are two ways to influence the interline spacing. The
-%D most general and often most consistent way is using
-%D
-%D \showsetup{setupinterlinespace}
-%D
-%D For instance
-%D
-%D \starttyping
-%D \setupinterlinespace[line=2.8ex]
-%D \stoptyping
-%D
-%D This setting adapts itself to the bodyfontsize, while for
-%D instance saying
-%D
-%D \starttyping
-%D \setupinterlinespace[line=12pt]
-%D \stoptyping
-%D
-%D sets things fixed for all sizes, which is definitely not
-%D what we want. Therefore one can also say:
-%D
-%D \starttyping
-%D \definebodyfontenvironment[9pt][interlinespace=11pt]
-%D \stoptyping
-%D
-%D One can still use \type{\setupinterlinespace} (without
-%D arguments) to set the interline space according to the
-%D current font, e.g. a \type{\bfa}.
-
-\newif\iflocalinterlinespace
-
-% font-ini
-
-\ifx\bodyfontinterlinespecs\undefined
-
- \let\bodyfontinterlinespecs\empty
- \let\bodyfontinterlinespace\empty
-
-\fi
-
-\def\presetnormallineheight
- {\edef\normallineheight{\@@itline}%
-% done elsewhere : \spacing\!!plusone % new per 10/08/2004, else problems in otr / !! needed
- \iflocalinterlinespace \else
- \doifdefined\bodyfontinterlinespecs
- {\doifsomething\bodyfontinterlinespace
- {\edef\normallineheight{\bodyfontinterlinespace}}}%
- \fi}
-
-\def\setupspecifiedinterlinespace[#1]%
- {\getparameters[\??it][#1]%
- \scratchdimen0\@@itheight\points
- \advance\scratchdimen 0\@@itdepth\points
- \ifdim\scratchdimen>\onepoint
- \showmessage\m!layouts{10}{\@@itheight,\@@itdepth}%
- \let\@@itheight\strutheightfactor
- \let\@@itdepth \strutdepthfactor
- \else
- \let\strutheightfactor\@@itheight
- \let\strutdepthfactor \@@itdepth
- \fi
- \let\minimumstrutheight \@@itminheight
- \let\minimumstrutdepth \@@itmindepth
- \let\minimumlinedistance\@@itdistance
- \let\normallineheight \@@itline % let ! ! ! ! ! ivm ex
- \doifelse\@@ittop\v!height % new, topskip does more bad than good
- {\let\topskipfactor \@@itheight}
- {\let\topskipfactor \@@ittop }%
- \let\maxdepthfactor \@@itbottom
- \let\baselinegluefactor \@@itstretch
- \setfontparameters % redundant, can be \setstrut, test first
- \updateraggedskips} % yes indeed
-
-% \let\currentrelativeinterlinespace\empty
-%
-% \def\setuprelativeinterlinespace[#1]%
-% {\processallactionsinset
-% [#1]
-% [ \v!on=>\oninterlineskip,
-% \v!off=>\offinterlineskip,
-% \v!reset=>\let\currentrelativeinterlinespace\empty
-% \setfontparameters,% just \setstrut, test first
-% \s!unknown=>\assignvalue{#1}\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
-% \spacing\currentrelativeinterlinespace]}
-
-% \setupinterlinespace[big] \switchtobodyfont[11pt] -> forgotten
-% \setupinterlinespace[auto,big] \switchtobodyfont[11pt] -> remembered
-
-\let\currentrelativeinterlinespace\empty
-
-\def\setuprelativeinterlinespace[#1]%
- {\processallactionsinset
- [#1]
- [ \v!on=>\oninterlineskip,
- \v!off=>\offinterlineskip,
- \v!reset=>\let\currentrelativeinterlinespace\empty
- \let\setrelativeinterlinespace\relax
- \setfontparameters,
- \v!auto=>\let\setrelativeinterlinespace\dosetrelativeinterlinespace,
- \s!unknown=>\assignvalue\commalistelement\currentrelativeinterlinespace{1.00}{1.25}{1.50}%
- \spacing\currentrelativeinterlinespace]}
-
-\def\dosetrelativeinterlinespace
- {\ifx\currentrelativeinterlinespace\empty\else
- \spacing\currentrelativeinterlinespace
- \fi}
-
-\let\setrelativeinterlinespace\relax
-
-% \appendtoks \setrelativeinterlinespace \to \everybodyfont
-
-\def\complexsetupinterlinespace[#1]% \commalistelement ipv #1
- {\doifassignmentelse{#1}\setupspecifiedinterlinespace\setuprelativeinterlinespace[#1]}
-
-\def\setuplocalinterlinespace[#1]%
- {\localinterlinespacetrue
- \setupinterlinespace[#1]%
- \localinterlinespacefalse}
-
-\def\simplesetupinterlinespace
- {\localinterlinespacetrue
- \setfontparameters
- \updateraggedskips % funny one here
- \localinterlinespacefalse}
-
-\definecomplexorsimple\setupinterlinespace
-
-% In earlier versions \type{\bigskipamount} was
-% \type{\ht\strutbox} and the stretch was plus or minus
-% \type{.4\dp\strutbox}. Don't ask me why. The most recent
-% implementation is based on a user supplied distance, which
-% is by default \type{.75\normalskipamount} where
-% \type{\normalskipamount} equals the current baseline
-% distance.
-
-% \lineskiplimit = -\maxdimen -> freezes baselineskip
-
-% can be conditionals
-
-\newif\ifblanknowhite \blanknowhitefalse
-\newif\ifblankindeed \blankindeedfalse
-\newif\ifblankreset \blankresetfalse
-\newif\ifblankdisable \blankdisablefalse
-\newif\ifblankflexible \blankflexibletrue
-\newif\ifblankouter
-\newif\ifblankforce
-\newif\ifblankgoback
-
-\newskip\blankskip \blankskip=\bigskipamount
-\newskip\blankskipamount
-
-\def\skipfactor {.75}
-\def\skipgluefactor{.25}
-
-\def\normalskipamount
- {\openlineheight
- \ifgridsnapping \else \ifblankflexible
- \!!plus \skipgluefactor\openlineheight
- \!!minus\skipgluefactor\openlineheight
- \fi \fi
- \relax}
-
-\def\linedistance {\normalskipamount}
-\def\appliedblankskip{\skipfactor\linedistance}
-\def\lastblankskip {\blankskip}
-\def\currentblank {\v!big}
-\def\oldprevdepth {\prevdepth}
-\def\newprevdepth {-1001pt}
-\def\mindimen {1sp} % was: 0.00002pt
-
-\newif\iflocalblankfixed
-\newif\iflocalblankflexible
-
-\def\geenblanko{\removelastskip} % will become obsolete
-
-%%%% pas op, wordt ook in core-pos gebruikt
-
-\def\doassignsomeskip#1\to#2% ook nog \v!halfline+fuzzysnap
- {\doifelse{#1}\v!line
- {#2\openlineheight}
- {\ifgridsnapping
- \assigndimension{#1}{#2}{.25\openlineheight}{.5\openlineheight}\openlineheight
- \else
- \assigndimension{#1}{#2}\smallskipamount\medskipamount\bigskipamount
- \fi}%
- \relax}
-
-% \relax is really needed, else we may loose stretch due to lookahead; somehow
-% this bug was introduced a while ago but somehow went unnoticed; fixed 2/7/2008
-
-\def\addblankskip#1#2#3{\global\advance\blankskip#1\ifgridsnapping#3\else#2\fi\relax}
-
-\def\defineblankmethod[#1]#2{\setvalue{\??bo\??bo#1}{#2}}
-
-\defineblankmethod [\v!big] {\addblankskip+\bigskipamount \openlineheight}
-\defineblankmethod [-\v!big] {\addblankskip-\bigskipamount \openlineheight}
-\defineblankmethod [\v!medium] {\addblankskip+\medskipamount {.5\openlineheight}}
-\defineblankmethod [-\v!medium] {\addblankskip-\medskipamount {.5\openlineheight}}
-\defineblankmethod [\v!small] {\addblankskip+\smallskipamount{.25\openlineheight}}
-\defineblankmethod [-\v!small] {\addblankskip-\smallskipamount{.25\openlineheight}}
-\defineblankmethod [\v!white] {\addblankskip+\parskip \openlineheight}
-\defineblankmethod [-\v!white] {\addblankskip-\parskip \openlineheight}
-\defineblankmethod [\v!line] {\addblankskip+\openlineheight \openlineheight}
-\defineblankmethod [-\v!line] {\addblankskip-\openlineheight \openlineheight}
-
-\defineblankmethod [\v!formula] {\global\advance\blankskip\medskipamount}
-\defineblankmethod [\v!nowhite] {\global\blanknowhitetrue}
-\defineblankmethod [\v!disable] {\global\blankdisabletrue}
-\defineblankmethod [\v!force] {\global\blankforcetrue}
-\defineblankmethod [\v!outer] {\ifvmode\ifinner\blankoutertrue\fi\fi}
-\defineblankmethod [\v!reset] {\global\blankresettrue}
-\defineblankmethod [\v!flexible] {\global\localblankflexibletrue}
-\defineblankmethod [\v!fixed] {\global\localblankfixedtrue}
-\defineblankmethod [\v!back] {\global\blankgobacktrue} % {\geenblanko}
-\defineblankmethod [\v!halfline] {\ifgridsnapping\global\fuzzyvskiptrue\fi
- \global\advance\blankskip .5\lineheight}
-
-\defineblankmethod [\v!none] {\global\blankresettrue}
-\defineblankmethod [\v!joinedup] {\ifvmode\nointerlineskip\fi}
-
-\defineblankmethod [\v!always] {\redowhitespace} % experimental
-
-% happens often, so we speed this up:
-%
-% \defineblankmethod [2*\v!line] {\addblankskip+{2\openlineheight}{2\openlineheight}}
-% \defineblankmethod [2*\v!big] {\addblankskip+{2\bigskipamount }{2\openlineheight}}
-%
-% no, with 2\whatever we loose the stretch and shrink! Taco's alternative:
-
-\defineblankmethod
- [2*\v!line]
- {\addblankskip+\openlineheight\openlineheight
- \addblankskip+\openlineheight\openlineheight}
-
-\defineblankmethod
- [2*\v!big]
- {\addblankskip+\bigskipamount\openlineheight
- \addblankskip+\bigskipamount\openlineheight}
-
-\def\doblank#1%
- {\edefconvertedargument\ascii{#1}%
- \ifx\ascii\empty\else
- \ifcsname\??bo\??bo\ascii\endcsname % internal def
- \csname\??bo\??bo\ascii\endcsname
- \else\ifcsname\??bo\ascii\endcsname % user def / slow
- \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
- \else
- \dorepeatwithcommand[#1]\redoblank
- \fi\fi
- \fi
- \relax}
-
-\def\redoblank#1%
- {\edefconvertedargument\ascii{#1}%
- \ifx\ascii\empty\else
- \ifcsname\??bo\??bo\ascii\endcsname % internal def
- \csname\??bo\??bo\ascii\endcsname
- \else\ifcsname\??bo\ascii\endcsname % user def / slow
- \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
- \else
- \global\advance\blankskip#1\relax
- \fi\fi
- \fi
- \relax}
-
-\unexpanded\def\blank % the \relax is definitely needed due to the many \if's
- {\relax\complexorsimple\doblank}
-
-\def\complexdoblank
- {\flushnotes
- \ifmmode
- \@EA\nocomplexdoblank
- \else
- \ifopelkaar
- \ifinpagebody
- \@EA\@EAEAEA\@EA\docomplexdoblank
- \else
- \@EA\@EAEAEA\@EA\nocomplexdoblank
- \fi
- \else
- \@EAEAEA\docomplexdoblank
- \fi
- \fi}
-
-\def\nocomplexdoblank[#1]%
- {% evt blokkeerfalse
- \ifmmode\else\par\fi}
-
-% Overloaded in cont-new!
-
-\newsignal\noblanksignal
-
-% \def\doinhibitblank
-% {\kern\noblanksignal}
-
-% \def\inhibitblank% the fast, local way
-% {\endgraf\ifvmode\prevdepth\newprevdepth\fi}
-
-% \def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
-% {\global\blankresetfalse
-% \global\blankdisablefalse
-% \global\blanknowhitefalse
-% \global\localblankflexiblefalse
-% \global\localblankfixedfalse
-% \global\blankskip\zeropoint
-% \global\blankforcefalse
-% \global\blankgobackfalse
-% \blankouterfalse
-% \expanded{\rawprocesscommalist[#1]}\doblank
-% \ifdim\blankskip=\zeropoint\relax
-% \iflocalblankflexible
-% \doglobal\advance\blankskip \currentblank
-% \else\iflocalblankfixed
-% \doglobal\advance\blankskip \currentblank
-% \fi\fi
-% \fi
-% \ifblankouter
-% \else
-% \par
-% \ifvmode
-% \ifblankgoback
-% \removelastskip
-% \fi
-% \ifblankforce
-% % dit gaat mis in pos fonts
-% % \ifdim\prevdepth>\zeropoint\else ...
-% % -1000pt signals top of page or column (\ejectcolumn)
-% \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
-% \fi
-% \ifblankdisable
-% \global\blankindeedfalse
-% \ifgridsnapping
-% \ifdim\prevdepth<\zeropoint
-% % brrr
-% \else
-% % dirty trick: smaller blanks are ignored after
-% % a larger one, so 10 lines is probably safe; first make
-% % sure that we honor penalties
-% \scratchcounter\lastpenalty
-% % now comes the trick (cross our fingers that this works
-% % well in multi columns; maybe an ifinner test is needed
-% % \vskip-10\lineheight
-% % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
-% % \vskip 10\lineheight
-% % allas, this leads to overfull pages, so we try this:
-% \kern-\noblanksignal
-% \ifnum\scratchcounter=\zerocount
-% \else
-% \penalty\lastpenalty
-% \fi
-% \kern\noblanksignal
-% % end-of-dirty-trick
-% \fi
-% \else
-% \ifdim\prevdepth<\zeropoint
-% % brrr
-% \else
-% % ensure at least a proper prevdepth, this should be
-% % an option
-% \vskip-\prevdepth
-% \vskip\strutdepth
-% \prevdepth\strutdepth
-% \fi
-% % the old crappy piece of code
-% \edef\oldprevdepth{\the\prevdepth}%
-% \prevdepth\newprevdepth
-% \fi
-% \else
-% \global\blankindeedtrue
-% \fi
-% \ifblankreset
-% \global\blankindeedtrue
-% \ifgridsnapping
-% % let's play safe and not fool around with the depth, if
-% % only because it took a lot of effort to sort out the grid
-% % stuff in the first place
-% \else
-% \ifdim\prevdepth=\newprevdepth
-% \prevdepth\oldprevdepth
-% \fi
-% \fi
-% \fi
-% \ifblankindeed
-% \ifdim1\lastskip<1\blankskip\relax
-% % else when \blanko[2*groot] + \blanko[3*groot] with parskip
-% % equaling 1*groot, gives a groot=\parskip so adding a small
-% % value makes it distinguishable; can also be done at parskip
-% % setting time (better)
-% \global\advance\blankskip \mindimen\relax % = skip
-% % test this on 2* + 3* and parskip groot
-% \ifblanknowhite
-% \global\advance\blankskip -\parskip
-% \else
-% \ifdim\lastskip=\parskip
-% \else % force this due to previous comment
-% \ifdim\parskip>\zeropoint\relax
-% \ifdim\blankskip<\parskip\relax
-% \global\blankskip\zeropoint
-% \else
-% \global\advance\blankskip -\parskip
-% \fi
-% \fi
-% \fi
-% \fi
-% \ifblankflexible \else
-% \blankskip1\blankskip
-% \fi
-% \iflocalblankfixed
-% \blankskip1\blankskip
-% \fi
-% \iflocalblankflexible
-% \blankskip1\blankskip
-% \!!plus\skipgluefactor\blankskip
-% \!!minus\skipgluefactor\blankskip
-% \fi
-% \ifdim\lastkern=\noblanksignal % controled and grid
-% \global\blankindeedfalse
-% \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
-% \global\blankindeedfalse
-% \fi\fi\fi
-% \ifblankindeed
-% \iffuzzyvskip
-% \removelastfuzzyvskip
-% \fuzzyvskip\blankskip\relax
-% \else
-% \removelastskip
-% \vskip\blankskip\relax
-% \fi
-% \fi
-% \else
-% \iffuzzyvskip
-% \removelastfuzzyvskip
-% \fuzzyvskip\blankskip\relax
-% \else
-% % new, test this on pascal
-% \ifdim\blankskip<\zeropoint
-% \advance\blankskip-\lastskip
-% \removelastskip
-% \ifdim\blankskip>\zeropoint
-% \vskip\blankskip
-% \else
-% \vskip\zeropoint
-% \fi
-% \else
-% % also new
-% \ifdim\blankskip=\zeropoint
-% \ifblanknowhite
-% \geenwitruimte
-% \fi
-% \fi
-% \fi
-% \fi
-% \fi
-% \fi
-% \fi
-% \fi
-% \global\fuzzyvskipfalse
-% \presetindentation}
-
-% goback was broken:
-
-% \def\doinhibitblank
-% {\kern\noblanksignal}
-
-% \def\inhibitblank% the fast, local way
-% {\endgraf\ifvmode\prevdepth\newprevdepth\fi}
-
-% problem: we cannot look back in the mvl so we need 3 kinds of signals
-
-\def\noblankpsignal{1010101}
-
-\def\inhibitgridblank % was doinhibitblank
- {\ifvmode\else\endgraf\fi
- \ifvmode
- \ifnum\lastpenalty<10000
- \kern-\noblanksignal % new
- \kern \noblanksignal
- \else
- \penalty\noblankpsignal
- \fi
- \fi}
-
-\def\inhibittextblank % was inhibitblank
- {\endgraf
- \ifvmode
- \prevdepth\newprevdepth
- \fi}
-
-% new macro
-%
-% \def\inhibitblank % need some work
-% {\endgraf
-% \ifvmode
-% \ifgridsnapping
-% \inhibitgridblank
-% \else
-% % this one spoils the grid
-% \inhibittextblank
-% \fi
-% \fi}
-
-\def\doinhibitblank{\inhibitgridblank}
-\def\inhibitblank {\inhibittextblank}
-
-% will become obsolete
-
-\ifx\undefined\savedlastskip \newskip \savedlastskip \fi
-\ifx\undefined\savedlastpenalty \newcount\savedlastpenalty \fi
-
-% beware, prevdepth can have funny values (e.g. mvl value when in box)
-
-\def\docomplexdoblank[#1]% pas op \relax's zijn nodig ivm volgende \if
- {\global\blankresetfalse
- \global\blankdisablefalse
- \global\blanknowhitefalse
- \global\localblankflexiblefalse
- \global\localblankfixedfalse
- \global\blankforcefalse
- \global\blankgobackfalse
- \blankouterfalse
- \global\blankskip\zeropoint
-%
-\edefconvertedargument\ascii{#1}% todo fast check for simple
-\ifcsname\??bo\??bo\ascii\endcsname % internal def
- \csname\??bo\??bo\ascii\endcsname
-\else\ifcsname\??bo\ascii\endcsname % user def / slow
- \@EA\rawprocesscommalist\@EA[\csname\??bo\ascii\endcsname]\doblank\relax
-\else
- \expanded{\rawprocesscommalist[#1]}\doblank
-\fi\fi
-%
- \relax % to be sure
- \ifdim\blankskip=\zeropoint\relax
- \iflocalblankflexible
- \doglobal\advance\blankskip \currentblank
- \else\iflocalblankfixed
- \doglobal\advance\blankskip \currentblank
- \fi\fi
- \fi
- \relax % to be sure
- \ifblankouter
- % do nothing
- \else
- \par
- \ifvmode
- \ifblankgoback
- \ifdim\lastskip>\zeropoint \vskip-\lastskip \fi
- \savedlastskip\zeropoint
- \else\ifdim\lastskip>\zeropoint
- \savedlastskip\lastskip
- \else % todo: lastnode, dan namelijk geen skip !
- \savedlastskip\zeropoint
- \fi\fi
- \ifblankforce
- % dit gaat mis in pos fonts
- % \ifdim\prevdepth>\zeropoint\else ...
- % -1000pt signals top of page or column (\ejectcolumn)
- \bgroup\forgeteverypar\verticalstrut\egroup\kern-\struttotal
- \savedlastskip\zeropoint
- \fi
- \savedlastpenalty\lastpenalty % hm, now it gets lost
- \ifblankdisable
- \global\blankindeedfalse % keep this, i.e. disable current too
- \ifgridsnapping
- \ifdim\prevdepth<\zeropoint
- % brrr
- \else
- % dirty trick: smaller blanks are ignored after a
- % larger one, so 10 lines is probably safe; we need
- % to make sure that we honor penalties; here comes the
- % trick (cross our fingers that this works well in
- % multi columns; maybe an ifinner test is needed
- % \scratchcounter\lastpenalty
- % \vskip-10\lineheight
- % \ifnum\scratchcounter=\zerocount \else \penalty\lastpenalty \fi
- % \vskip 10\lineheight
- % alas, this leads to overfull pages, so we try this:
- \inhibitgridblank
- \fi
- \else
- \ifdim\prevdepth<\zeropoint
- % brrr
- \else
- % ensure at least a proper prevdepth, this should be
- % an option
- \vskip-\prevdepth
- \vskip\strutdepth
- \prevdepth\strutdepth
- \fi
- % the old crappy piece of code
- \edef\oldprevdepth{\the\prevdepth}%
- \prevdepth\newprevdepth % == \inhibittextblank
- \fi
- \else
- \global\blankindeedtrue
- \fi
- \ifblankreset
- \global\blankindeedtrue
- \ifgridsnapping
- % let's play safe and not fool around with the depth, if
- % only because it took a lot of effort to sort out the grid
- % stuff in the first place
- \else
- \ifdim\prevdepth=\newprevdepth
- \prevdepth\oldprevdepth
- \fi
- \fi
- \fi
- \ifblankindeed
- \ifdim1\savedlastskip<1\blankskip\relax
- % else when \blank[2*groot] + \blank[3*groot] with parskip
- % equaling 1*groot, gives a groot=\parskip so adding a small
- % value makes it distinguishable; can also be done at parskip
- % setting time (better)
- \global\advance\blankskip \mindimen\relax % = skip
- % test this on 2* + 3* and parskip groot
- \ifblanknowhite
- \global\advance\blankskip -\parskip
- \else
- \ifdim\savedlastskip=\parskip
- \else % force this due to previous comment
- \ifdim\parskip>\zeropoint\relax
- \ifdim\blankskip<\parskip\relax
- \global\blankskip\zeropoint
- \else
- \global\advance\blankskip -\parskip
- \fi
- \fi
- \fi
- \fi
- \ifblankflexible \else
- \blankskip1\blankskip
- \fi
- \iflocalblankfixed
- \blankskip1\blankskip
- \fi
- \iflocalblankflexible
- \blankskip1\blankskip
- \!!plus \skipgluefactor\blankskip
- \!!minus\skipgluefactor\blankskip
- \fi
- \ifdim\lastkern=\noblanksignal\relax % controlled and grid
- \global\blankindeedfalse
- \else\ifnum\savedlastpenalty=\noblankpsignal\relax % controlled and grid
- \global\blankindeedfalse
- \else\ifgridsnapping\else\ifdim\prevdepth=\newprevdepth
- \global\blankindeedfalse
- \fi\fi\fi\fi
- \ifblankindeed
- \iffuzzyvskip
- \removelastfuzzyvskip
- \fuzzyvskip\blankskip\relax
- \else
- \relax\ifdim\savedlastskip=\zeropoint\else
- \vskip-\savedlastskip
- \fi
- \vskip\blankskip\relax
- \fi
- \fi
- \else
- \iffuzzyvskip
- \removelastfuzzyvskip
- \fuzzyvskip\blankskip\relax
- \else
- % new, test this on pascal
- \ifdim\blankskip<\zeropoint
- \relax\ifdim\savedlastskip=\zeropoint\else
- \advance\blankskip-\savedlastskip
- \vskip-\savedlastskip
- \fi
- \ifdim\blankskip>\zeropoint
- \vskip\blankskip
- \else
- \vskip\zeropoint
- \fi
- \else
- % also new
- \ifdim\blankskip=\zeropoint
- \ifblanknowhite
- \nowhitespace
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \global\fuzzyvskipfalse
- \presetindentation}
-
-%D For a long time we had:
-%D
-%D \starttyping
-%D \def\simpledoblank%
-%D {\doifelse{\currentwhitespace}{\v!geen}
-%D {\blank[\currentblank]}
-%D {\blank[\currentwhitespace]}}
-%D \stoptyping
-%D
-%D But Berend de Boer wanted more control, so now we have:
-
-\def\simpledoblank % ...
- {\doifelse\currentwhitespace\v!none
- {\blank[\currentblank]}
- {\blank[\s!default]}}
-
-%D Another useful definition would be:
-%D
-%D \starttyping
-%D \defineblank
-%D [\s!default]
-%D [\v!groot]
-%D \stoptyping
-
-\def\dosetupblank#1% amount are an plain inheritance
- {\bigskipamount#1\relax
- \ifblankflexible \else
- \bigskipamount1\bigskipamount
- \fi
- \medskipamount \bigskipamount \divide\medskipamount \plustwo
- \smallskipamount\bigskipamount \divide\smallskipamount\plusfour}%
-
-\def\complexsetupblank[#1]% more \let's -> this also wil become installable
- {\ifgridsnapping
- \blankflexiblefalse
- \else
- \ExpandFirstAfter\processallactionsinset
- [#1]
- [ \v!flexible=>\blankflexibletrue,
- \v!fixed=>\blankflexiblefalse]%
- \fi
- \ExpandFirstAfter\processallactionsinset
- [#1]
- [ \v!flexible=>\dosetupblank\appliedblankskip,
- \v!fixed=>\dosetupblank\appliedblankskip,
- \v!line=>\edef\appliedblankskip{\linedistance}%
- \dosetupblank\appliedblankskip,
- \v!halfline=>\scratchskip.5\linedistance
- \edef\appliedblankskip{\the\scratchskip}%
- \dosetupblank\appliedblankskip,
- \v!big=>\ifgridsnapping
- \edef\appliedblankskip{\linedistance}%
- \dosetupblank\appliedblankskip
- \fi
- \let\currentblank\v!big,
- \v!medium=>\let\currentblank\v!medium,
- \v!small=>\let\currentblank\v!small,
- \v!global=>\let\currentblank\v!global,
- \v!normal=>\dosetupblank\appliedblankskip,
- \v!standard=>\edef\appliedblankskip{\skipfactor\linedistance}%
- \dosetupblank\appliedblankskip,
- \s!default=>\dosetupblank\appliedblankskip,
- \s!unknown=>\let\appliedblankskip\commalistelement
- \dosetupblank\appliedblankskip]%
- \simplesetupwhitespace}
-
-% \definecomplexorsimpleempty\setupblank
-%
-% speed gain: 60 sec -> 30 sec
-
-\definecomplexorsimple\setupblank
-
-\def\simplesetupblank % == snelle \setupblank[\s!default]
- {\ifgridsnapping
- \blankflexiblefalse
- \fi
- \dosetupblank\appliedblankskip
- % \let\deblanko\v!big
- \simplesetupwhitespace}
-
-\def\restorestandardblank% \v!standard
- {\edef\appliedblankskip{\skipfactor\linedistance}%
- \dosetupblank\appliedblankskip
- }%\let\deblanko\v!big}
-
-\def\dodefineblank[#1][#2]%
- {\def\docommand##1{\setvalue{\??bo##1}{#2}}%
- \processcommalist[#1]\docommand}
-
-\def\defineblank
- {\dodoubleargument\dodefineblank}
-
-\def\savecurrentblank
- {\edef\restorecurrentblank
- {\bigskipamount\the\bigskipamount
- \medskipamount\the\medskipamount
- \smallskipamount\the\smallskipamount
- \noexpand\def\noexpand\currentblank{\currentblank}%
- \ifblankflexible
- \noexpand\blankflexibletrue
- \else
- \noexpand\blankflexiblefalse
- \fi}}
-
-%D Now.
-
-\defineblank [\s!default] [\v!white]
-\defineblank [\v!height] [\strutheight]
-\defineblank [\v!depth] [\strutdepth]
-
-% old implementation
-%
-% \let\currentindentation=\empty
-%
-% \newdimen\ctxparindent
-%
-% \newif\ifindentfirstparagraph % \indentfirstparagraphtrue
-%
-% \def\presetindentation
-% {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}
-%
-% \definecomplexorsimple\setupindenting
-%
-% \def\complexsetupindenting[#1]%
-% {\processallactionsinset
-% [#1]
-% [ \v!first=>\indentfirstparagraphtrue,
-% \v!next=>\indentfirstparagraphfalse,
-% \s!default=>\simplesetupindenting,
-% \s!unknown=>\edef\currentindentation{\commalistelement}%
-% \simplesetupindenting]}
-%
-% \def\simplesetupindenting
-% {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}%
-% \parindent\ctxparindent\relax}
-%
-% \def\indenting % watch out: \dodo and no \do
-% {\dosingleargument\dodoindenting}
-%
-% \def\dodoindenting[#1]% oeps, we needed a commalist handler here!
-% {\edef\currentindenting{#1}%
-% \processcommacommand[#1]\dododoindenting}
-%
-% \def\dododoindenting#1%
-% {\executeifdefined{\??in:#1}\donothing}
-%
-% \let\currentindenting\empty
-%
-% \def\defineindentingmethod[#1]#2%
-% {\setvalue{\??in:#1}{#2}}
-%
-% \defineindentingmethod [\v!no] {\parindent\ctxparindent\noindent}
-% \defineindentingmethod [\v!not] {\parindent\ctxparindent\noindent}
-%
-% \defineindentingmethod [\v!first] {\indentfirstparagraphtrue}
-% \defineindentingmethod [\v!next] {\indentfirstparagraphfalse}
-%
-% \defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent !
-% \defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent !
-%
-% \defineindentingmethod [\v!never] {\parindent\zeropoint\relax} % no \indent !
-%
-% \def\noindenting{\indenting[\v!no,\v!next]} % was \nietinspringen
-% \def\doindenting{\indenting[\v!yes,\v!first]} % was \welinspringen
-%
-% \def\dochecknextindentation#1% internal one
-% {\checknextindentation[\getvalue{#1\c!indentnext}]}
-%
-% \def\checknextindentation[#1]%
-% {\processaction[#1][%\v!keep=>,
-% \v!yes=>\doindentation,
-% \v!no=>\noindentation,
-% \v!auto=>\autoindentation]}
-%
-% \def\doindentation% too simple
-% {\gdef\checkindentation{\global\indentationtrue}}
-%
-% \ifx\autoindentation\undefined
-% \let\autoindentation\relax
-% \fi
-%
-% \newif\ifindentation \indentationtrue % documenteren, naar buiten
-%
-% \let\checkindentation=\relax
-%
-% \def\donoindentation
-% {\ifdim\parindent=\zeropoint \else
-% \bgroup \setbox\scratchbox\lastbox \egroup
-% \fi}
-%
-% \def\noindentation % made global
-% {\ifinpagebody \else
-% \global\indentationfalse
-% \gdef\checkindentation
-% {\donoindentation
-% \gdef\checkindentation{\global\indentationtrue}}%
-% \fi}
-%
-% \def\nonoindentation % bv bij floats
-% {\ifinpagebody \else
-% \global\indentationtrue
-% \gdef\checkindentation{\global\indentationtrue}%
-% \fi}
-%
-% \def\indentation
-% {\ifvmode \ifdim\parindent=\zeropoint \else
-% % was : \hskip\parindent
-% % can be: \indent
-% % but we test:
-% \noindent\hskip\parindent
-% \fi \fi}
-
-\let\currentindentation\empty % amount/keyword
-% \let\normalindentation \empty % used for reinstating normal indentation
-\let\currentindenting \empty % method
-
-\newdimen\ctxparindent
-
-\newif\ifindentfirstparagraph % \indentfirstparagraphtrue
-
-\chardef\indentingtoggle\zerocount
-
-%D After a blank or comparable situation (left side floats) we
-%D need to check if the next paragraph has to be indented.
-
-\def\presetindentation
- {\doifoutervmode{\ifindentfirstparagraph\else\noindentation\fi}}
-
-%D This sets up the (normally) global indentation behavior as well
-%D as the amounts.
-
-\definecomplexorsimple\setupindenting
-
-% \def\complexsetupindenting[#1]%
-% {\edef\currentindenting{#1}%
-% \indentfirstparagraphtrue
-% \parindent\ctxparindent
-% \chardef\indentingtoggle\zerocount
-% \processcommalist[#1]\docomplexsetupindenting
-% \ifindentfirstparagraph\else\noindentation\fi % added
-% \toggleindentation}
-
-\indentfirstparagraphtrue
-\parindent\ctxparindent
-\chardef\indentingtoggle\zerocount
-
-% \newtoks\savedeverypar \savedeverypar\everypar
-% \def\restoreeverypar{\everypar\savedeverypar}
-
-% we need a better everypar model: for each option a switch, which we
-% set to false with \forgetall and can enable when needed (context 4);
-% that way we can control the order of execution of options
-
-\def\checkeverypar % currently a hack
- {\ifzeropt\parindent\else
- \doifsometokselse\everypar\donothing{\appendtoks\checkindentation\to\everypar}%
- \fi}
-
-\def\complexsetupindenting[#1]%
- {\edef\currentindenting{#1}%
- \doifsomething\currentindenting % handy when a parameter is passed
- {% not here: \indentfirstparagraphtrue
- % not here: \parindent\ctxparindent
- % not here: \chardef\indentingtoggle\zerocount
- % we use commacommand in order to catch #1 being a command (expanded parameter)
- \processcommacommand[\currentindenting]\docomplexsetupindentingA % catch small, medium, etc
- \processcommacommand[\currentindenting]\docomplexsetupindentingB % catch rest
- \checkeverypar % only when non-empty #1
- \ifindentfirstparagraph\else\noindentation\fi % added
- \toggleindentation}}
-
-\def\docomplexsetupindentingA#1%
- {\edefconvertedargument\!!stringa{#1}%
- \doifundefined{\??in:\!!stringa}%
- {\edef\currentindentation{#1}%
- \let\normalindentation\currentindentation
- \simplesetupindenting}}
-
-\def\docomplexsetupindentingB#1%
- {\edefconvertedargument\!!stringa{#1}% catch #1=\somedimen
- \executeifdefined{\??in:\!!stringa}\donothing}
-
-\def\simplesetupindenting % empty case, a it strange, needed this way?
- {\assigndimension\currentindentation\ctxparindent{1em}{1.5em}{2em}}
-
-\def\indenting % kind of obsolete
- {\dosingleargument\complexsetupindenting}
-
-% use \noindentation to suppress next indentation
-
-\def\defineindentingmethod[#1]#2%
- {\setvalue{\??in:#1}{#2}}
-
-\defineindentingmethod [\v!no] {\parindent\zeropoint}% was: \ctxparindent\noindent}
-\defineindentingmethod [\v!not] {\parindent\zeropoint}% was: \ctxparindent\noindent}
-
-\defineindentingmethod [\v!first] {\indentfirstparagraphtrue}
-\defineindentingmethod [\v!next] {\indentfirstparagraphfalse}
-
-\defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent !
-\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent !
-
-\defineindentingmethod [\v!never] {\parindent\zeropoint\relax % no \indent !
- \chardef\indentingtoggle\zerocount}
-
-\defineindentingmethod [\v!odd] {\chardef\indentingtoggle\plusone}
-\defineindentingmethod [\v!even] {\chardef\indentingtoggle\plustwo}
-
-\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else
- \let\currentindentation\normalindentation
- \simplesetupindenting
- \fi}
-
-\defineindentingmethod [\v!reset] {\indentfirstparagraphtrue
- \parindent\zeropoint
- \chardef\indentingtoggle\zerocount}
-
-\def\noindenting{\indenting[\v!no, \v!next ]}
-\def\doindenting{\indenting[\v!yes,\v!first]}
-
-%D This one sets up the local indentation behaviour (i.e. either or not
-%D a next paragraph will be indented).
-
-\def\dochecknextindentation#1% internal one
- {\checknextindentation[\getvalue{#1\c!indentnext}]}
-
-\def\checknextindentation[#1]%
- {\processaction
- [#1]
- [%\v!keep=>,
- \v!yes=>\doindentation,
- \v!no=>\noindentation,
- \v!auto=>\autoindentation]}
-
-%D Here come the handlers.
-
-\newif\ifindentation \indentationtrue % documenteren, naar buiten
-
-\let\checkindentation\relax
-
-\ifx\autoindentation\undefined \let\autoindentation\relax \fi % hook
-
-\def\doindentation
- {\gdef\checkindentation{\global\indentationtrue}}
-
-\def\noindentation % made global
- {\ifinpagebody \else
- \global\indentationfalse
- \gdef\checkindentation
- {\donoindentation
- \gdef\checkindentation{\global\indentationtrue}}%
- \fi}
-
-\def\nonoindentation % bv bij floats
- {\ifinpagebody \else
- \global\indentationtrue
- \gdef\checkindentation{\global\indentationtrue}%
- \fi}
-
-\def\donoindentation
- {\ifdim\parindent=\zeropoint \else
- \bgroup \setbox\scratchbox\lastbox \egroup
- \fi}
-
-\def\indentation
- {\ifvmode \ifdim\parindent=\zeropoint \else
- % was : \hskip\parindent
- % can be: \indent
- % but we test:
- \noindent\hskip\parindent
- \fi \fi}
-
-\def\toggleindentation
- {\ifcase\indentingtoggle
- % nothing
- \or
- \notoggleindentation
- \or
- \dotoggleindentation
- \fi}
-
-\def\dokillindentation
- {\gdef\checkindentation{\global\indentationfalse\donoindentation}}
-
-\def\dotoggleindentation
- {\gdef\checkindentation{\global\indentationfalse\notoggleindentation\donoindentation}}
-
-\def\notoggleindentation
- {\gdef\checkindentation{\global\indentationtrue\dotoggleindentation}}
-
-\appendtoks
- \pushmacro\checkindentation
- \pushmacro\ifindentation
-\to \everypushsomestate
-
-\appendtoks
- \popmacro\ifindentation
- \popmacro\checkindentation
-\to \everypopsomestate
-
-% we need to save the state if we want to adapt behaviour to empty lines
-%
-% \def\setlasthvmode
-% {\global\chardef\savedhvmode\ifhmode\plusone\else\ifvmode\plustwo\else\zerocount\fi\fi}
-%
-% \def\resetlasthvmode
-% {\global\chardef\savedhvmode\zerocount}
-%
-% \chardef\savedhvmode\zerocount
-
-% This is a user requested hack (using the auto-hook).
-
-\chardef\recheckindentationmode\zerocount
-
-\def\dontrechecknextindentation
- {\global\chardef\recheckindentationmode\zerocount}
-
-\def\dorechecknextindentation
- {\ifcase\recheckindentationmode
- % nothing
- \or
- \dontrechecknextindentation
- \expandafter\doautoindentation
- \fi}
-
-\def\doautoindentation
- {\doifnextcharelse\par\donothing\noindentation}
-
-\def\autoindentation
- {\global\chardef\recheckindentationmode\plusone}
-
-%D An example of usage:
-%D
-%D \starttyping
-%D \setupindenting[small,yes]
-%D
-%D \setupitemize [indentnext=auto]
-%D \setuptyping [indentnext=auto]
-%D \setupformulas[indentnext=auto]
-%D
-%D \input tufte
-%D
-%D \startitemize
-%D \item itemize
-%D \stopitemize
-%D \input tufte
-%D
-%D \startitemize
-%D \item itemize
-%D \stopitemize
-%D
-%D \input tufte
-%D
-%D \startitemize
-%D \item itemize
-%D \stopitemize
-%D
-%D \page
-%D
-%D \input tufte
-%D
-%D \starttyping
-%D verbatim
-%D \stoptyping
-%D \input tufte
-%D
-%D \starttyping
-%D verbatim
-%D \stoptyping
-%D
-%D \input tufte
-%D
-%D \starttyping
-%D verbatim
-%D \stoptyping
-%D
-%D \page
-%D
-%D \input tufte
-%D
-%D \startformula
-%D a = b
-%D \stopformula
-%D \input tufte
-%D
-%D \startformula
-%D a = b
-%D \stopformula
-%D
-%D \input tufte
-%D
-%D \startformula
-%D a = b
-%D \stopformula
-
-% \frenchspacing leidt soms tot afbreken tussen -, vandaar
-% de variant \newfrenchspacing.
-
-\def\frenchspacing {\setfrenchspacing{1000}}
-\def\newfrenchspacing{\setfrenchspacing{1050}}
-\def\nonfrenchspacing{\resetfrenchspacing}
-
-\def\definespacingmethod[#1]#2{\setvalue{\??sg\??sg#1}{#2}}
-
-\definespacingmethod[\v!packed]{\newfrenchspacing}
-\definespacingmethod[\v!broad ]{\nonfrenchspacing}
-
-\def\complexsetupspacing[#1]%
- {\executeifdefined{\??sg\??sg#1}\relax
- \updateraggedskips}
-
-\def\simplesetupspacing
- {\updateraggedskips}
-
-\definecomplexorsimple\setupspacing
-
-% \dorecurse{100}{\recurselevel\spacefactor 800 \space} \par
-% \dorecurse{100}{\recurselevel\spacefactor1200 \space} \par
-% \dorecurse{100}{\recurselevel\spacefactor 800 \normalspaceprimitive} \par
-% \dorecurse{100}{\recurselevel\spacefactor1200 \normalspaceprimitive} \par
-
-% When we don't add the % here, we effectively get \<endlinechar> and
-% since we have by default \def\^^M{\ } we get into a loop.
-
-\let\normalspaceprimitive=\ % space-comment is really needed
-
-\unexpanded\def\ {\mathortext\normalspaceprimitive\space} % no \dontleavehmode\space (else no frenchspacing)
-
-\unexpanded\def\nonbreakablespace{\penalty\plustenthousand\space}
-
-\letcatcodecommand \ctxcatcodes `\~ \nonbreakablespace % overloaded later
-
-\def\space { }
-\def\removelastspace{\ifhmode\unskip\fi}
-\def\nospace {\removelastspace\ignorespaces}
-
-% in tables we need:
-%
-% \def\fixedspace {\hskip.5em\relax}
-%
-% but, since not all fonts have .5em digits:
-
-\unexpanded\def\fixedspace
- {\setbox\scratchbox\normalhbox{\mathortext{0}{0}}%
- \hskip\wd\scratchbox\relax}
-
-\def\fixedspaces
- {\letcatcodecommand \ctxcatcodes `\~ \fixedspace}
-
-\def\removeunwantedspaces
- {\ifhmode % we also need to unskip 0pt skips
- \unskip\unskip\unskip\unskip\unskip
- \unskip\unskip\unskip\unskip\unskip
- \fi}
-
-\appendtoks\let~\space\to\simplifiedcommands
-
-% still not fixed in aleph / luatex
-%
-% \def\removeunwantedspaces
-% {\ifhmode \ifnum\lastnodetype=\@@gluenode
-% \unskip \@EAEAEA\removeunwantedspaces
-% \fi \fi}
-
-%D For old time sake, will disappear soon.
-
-\let\hardespatie\fixedspace
-\let\geenspatie \nospace
-
-% \startbuffer
-% \startlines \tt \fixedspaces
-% 0~1~~2~~~3~~~~4~~~~~5
-% 0~~~~~~~~~~~~~~~~~~~5
-% $0~1~~2~~~3~~~~4~~~~~5$
-% $0~~~~~~~~~~~~~~~~~~~5$
-% \stoplines
-%
-% \starttabulate[|~|]
-% \NC 0~1~~2~~~3~~~~4~~~~~5 \NC \NR \NC 0~~~~~~~~~~~~~~~~~~~5 \NC \NR
-% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \NR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \NR
-% \stoptabulate
-%
-% \starttable[||]
-% \NC 0~1~~2~~~3~~~~4~~~~~5 \NC \AR \NC 0~~~~~~~~~~~~~~~~~~~5 \NC \AR
-% \NC $0~1~~2~~~3~~~~4~~~~~5$ \NC \AR \NC $0~~~~~~~~~~~~~~~~~~~5$ \NC \AR
-% \stoptable
-% \stopbuffer
-%
-% \setupbodyfont[cmr] \getbuffer
-% \setupbodyfont[lbr] \getbuffer
-
-\def\packed
- {\nointerlineskip}
-
-\def\godown[#1]%
- {\relax
- \ifhmode\endgraf\fi
- \ifvmode\nointerlineskip\vskip#1\relax\fi}
-
-%D A couple of plain macros:
-
-\ifx\thinspace\undefined
-
- \def\thinspace {\kern .16667em }
- \def\negthinspace{\kern-.16667em }
- \def\enspace {\kern .5em }
-
- \def\thinspace {\kern .16667\fontdimen6\font}
- \def\negthinspace{\kern-.16667\fontdimen6\font}
- \def\enspace {\kern .5\fontdimen6\font}
-
-\fi
-
-\ifx\quad\undefined
-
- \def\enskip{\hskip.5em\relax}
- \def\quad {\hskip 1em\relax}
- \def\qquad {\hskip 2em\relax}
-
- \def\enskip{\hskip.5\fontdimen6\font}
- \def\quad {\hskip \fontdimen6\font} % faster
- \def\qquad {\hskip 2\fontdimen6\font}
-
-\fi
-
-\let\emspace\quad
-
-\ifx\smallskip\undefined
-
- \def\smallskip{\vskip\smallskipamount}
- \def\medskip {\vskip\medskipamount}
- \def\bigskip {\vskip\bigskipamount}
-
-\fi
-
-\ifx\allowbreak\undefined
-
- \def\break {\penalty\ifhmode-\plustenthousand\else\ejectpenalty\fi}
- \def\nobreak {\penalty \plustenthousand}
- \def\allowbreak{\penalty \zeropoint}
- \def\filbreak {\par\vfil\penalty-200\vfilneg}
- \def\goodbreak {\par\penalty-500 }
-
-\fi
-
-%D Made slightly more readable:
-
-\ifx\vglue\undefined
-
- \def\vglue {\afterassignment\dovglue\scratchskip=}
- \def\hglue {\afterassignment\dohglue\scratchskip=}
- \def\topglue{\nointerlineskip\vglue-\topskip\vglue}
-
- \def\dovglue
- {\par
- \scratchdimen\prevdepth
- \hrule\!!height\zeropoint
- \nobreak\vskip\scratchskip
- \prevdepth\scratchdimen}
-
- \def\dohglue
- {\dontleavehmode % \leavevmode
- \scratchcounter\spacefactor
- \vrule\!!width\zeropoint
- \nobreak\hskip\scratchskip
- \spacefactor\scratchcounter}
-
-\fi
-
-\ifx\eject\undefined
-
- \def\eject{\par\break}
-
-\fi
-
-\ifx\supereject\undefined
-
- \def\supereject{\par\penalty\superpenalty}
-
-\fi
-
-\ifx\dosupereject\undefined
-
- \def\dosupereject
- {\ifnum\insertpenalties>\z@ % something is being held over
- \line{}
- \kern-\topskip
- \nobreak
- \vfill\supereject
- \fi}
-
-\fi
-
-%D We adapt plain's \type {\removelastskip} a bit:
-
-\ifx\removelastskip\undefined
-
- \def\removelastskip
- {\ifvmode \ifdim\lastskip=\zeropoint \else
- \vskip-\lastskip
- \fi \fi}
-
-\fi
-
-\ifx\smallbreak\undefined
-
-\def\smallbreak
- {\par
- \ifdim\lastskip<\smallskipamount
- \removelastskip
- \penalty-50
- \smallskip
- \fi}
-
-\def\medbreak
- {\par
- \ifdim\lastskip<\medskipamount
- \removelastskip
- \penalty-100
- \medskip
- \fi}
-
-\def\bigbreak
- {\par
- \ifdim\lastskip<\bigskipamount
- \removelastskip
- \penalty-200
- \bigskip
- \fi}
-
-\fi
-
-\newskip\ctxparskip \ctxparskip\zeropoint
-
-\newconditional \flexiblewhitespace \settrue\flexiblewhitespace
-
-\def\blankokleinmaat {\smallskipamount}
-\def\blankomiddelmaat {\medskipamount}
-\def\blankogrootmaat {\bigskipamount}
-\def\currentwhitespace {\zeropoint}
-
-\definecomplexorsimple\setupwhitespace
-
-% \def\simplesetupwhitespace
-% {\doifnot\currentwhitespace\v!none\dosetupwhitespace}
-%
-% \def\complexsetupwhitespace[#1]%
-% {\doifelsenothing{#1}
-% {\simplesetupwhitespace}
-% {\edef\currentwhitespace{#1}%
-% \dosetupwhitespace}}
-%
-% \def\dosetupwhitespace
-% {\processcommacommand[\currentwhitespace]\dowhitespacemethod
-% \dodosetupwhitespace}
-
-\def\simplesetupwhitespace
- {\doifnot\currentwhitespace\v!none\dosetupwhitespace}
-
-\def\complexsetupwhitespace[#1]%
- {\edef\nextcurrentwhitespace{#1}%
- \ifx\nextcurrentwhitespace\empty
- \simplesetupwhitespace
- \else
- \let\currentwhitespace\nextcurrentwhitespace
- \dosetupwhitespace
- \fi}
-
-\def\dosetupwhitespace % quick test for no list
- {\ifcsname\??ws\??ws\currentwhitespace\endcsname
- \csname\??ws\??ws\currentwhitespace\endcsname
- \else
- \expandafter\processcommalist\expandafter[\currentwhitespace]\dowhitespacemethod % can be raw
- \fi\relax
- \ifgridsnapping
- \setfalse\flexiblewhitespace
- \ifdim\ctxparskip>\zeropoint
- \ctxparskip
- \ifcase\baselinegridmode
- \baselineskip % normal ! ! ! ! !!
- \or
- \ifdim\scratchdimen=\baselineskip % maybe range
- \baselineskip % normal ! ! ! ! !!
- \else
- \numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
- \fi
- \else
- \baselineskip % normal ! ! ! ! !!
- \fi
- \fi
- \else
- \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
- \fi
- \parskip\ctxparskip}
-
-\chardef\baselinegridmode=0 % option in layout / 1=permit_half_lines
-
-\def\dodosetupwhitespace
- {\ifgridsnapping
- \setfalse\flexiblewhitespace
- \ctxparskip1\ctxparskip
- \ifdim\ctxparskip>\zeropoint
- \ifcase\baselinegridmode
- \ctxparskip\baselineskip % normal ! ! ! ! !!
- \or
- \ifdim\scratchdimen=\baselineskip % maybe range
- \ctxparskip\baselineskip % normal ! ! ! ! !!
- \else
- \ctxparskip\numexpr\ctxparskip/\dimexpr.5\lineheight\relax\relax\dimexpr.5\lineheight\relax
- \fi
- \else
- \ctxparskip\baselineskip % normal ! ! ! ! !!
- \fi
- \fi
- \else
- \ifconditional\flexiblewhitespace \else \ctxparskip1\ctxparskip \fi
- \fi
- \parskip\ctxparskip}
-
-\definesystemvariable {ws} % whitespace
-
-\def\definewhitespacemethod[#1]#2{\setvalue{\??ws\??ws#1}{#2}}
-
-\definewhitespacemethod [\v!fix] {}
-\definewhitespacemethod [\v!fixed] {\setfalse\flexiblewhitespace}
-\definewhitespacemethod [\v!flexible] {\settrue\flexiblewhitespace}
-\definewhitespacemethod [\v!line] {\ctxparskip \baselineskip}
-\definewhitespacemethod [\v!halfline] {\ctxparskip.5\baselineskip}
-\definewhitespacemethod [\v!none] {\ctxparskip \zeropoint}
-\definewhitespacemethod [\v!big] {\ctxparskip \bigskipamount}
-\definewhitespacemethod [\v!medium] {\ctxparskip \medskipamount}
-\definewhitespacemethod [\v!small] {\ctxparskip \smallskipamount}
-
-\definewhitespacemethod [\s!default] {\simplesetupwhitespace} % {\stelwitruimteopnieuwin}
-
-% \def\dowhitespacemethod#1%
-% {\executeifdefined{\??ws\??ws#1}{\ctxparskip#1}\relax}
-
-\def\dowhitespacemethod#1%
- {\ifcsname\??ws\??ws#1\endcsname\csname\??ws\??ws#1\endcsname\else\ctxparskip#1\fi\relax}
-
-\def\nowhitespace
- {\ifdim\parskip>\zeropoint\relax
- \ifdim\lastskip=-\parskip
- \else
- \vskip-\parskip
- \fi
- \fi}
-
-\def\nowhitespaceunlessskip
- {\ifdim\lastskip>\zeropoint \else
- \nowhitespace
- \fi}
-
-\def\redowhitespace
- {\ifdim\lastskip>-\parskip \else
- \vskip\parskip
- \fi}
-
-\def\savecurrentwhitespace
- {\edef\restorecurrentwhitespace
- {\ctxparskip\the\ctxparskip
- \parskip\the\parskip
- \noexpand\def\noexpand\currentwhitespace{\currentwhitespace}%
- \ifconditional\flexiblewhitespace
- \noexpand\settrue\flexiblewhitespace
- \else
- \noexpand\setfalse\flexiblewhitespace
- \fi}}
-
-% deze variant is nodig binnen \startopelkaar
-% steeds testen:
-%
-% \hoofdstuk{..}
-% \plaatslijst[..]
-% \hoofdstuk{..}
-% \input tufte
-%
-% met/zonder witruimte
-
-\def\whitespace
- {\par
- \ifdim\parskip>\zeropoint\relax
- %\ifdim\lastskip>\parskip \else
- % \removelastskip interferes with blanko blokkeer en klein
- \vskip\parskip
- %\fi
- \fi}
-
-\def\nonoblanko[#1]%
- {\par}
-
-\def\noblanko
- {\dosingleempty\nonoblanko}
-
-% De onderstaande macro handelt ook de situatie dat er geen
-% tekst tussen \start ... \stop is geplaatst. Daartoe wordt de
-% laatste skip over de lege tekst heen gehaald. Dit komt goed
-% van pas bij het plaatsen van (mogelijk lege) lijsten.
-
-\newif\ifopelkaar
-
-\newsignal \noparskipsignal % \def\noparskipsignal {0.00001pt}
-\def\lastdoneparskip {0pt}
-
-\def\startpacked
- {\dosingleempty\dostartpacked}
-
-\def\dostartpacked[#1]% nesting afvangen
- {\par
- \ifvmode
- \edef\lastdoneparskip {\the\lastskip}%
- \edef\lastdoneprevdepth{\the\prevdepth}% zeer recent toegevoegd
- \ifdim\prevdepth=-\thousandpoint % toegevoegd omdat binnen
- \else % een vbox een extra skip
- \whitespace % ongewenst is; dit kan
- \baselinecorrection %% zie in \placeregister[n=1]
- \vskip\noparskipsignal % waarschijnlijk ook in
- \fi % blanko blokkeer
- \bgroup
- \doifelse{#1}\v!blank
- \opelkaarfalse
- \opelkaartrue
- \blank[\v!disable] % dit is nog niet ok, gaat fout
- \setupwhitespace[\v!none] % bovenin vtop (dwz, baseline)
- \fi}
-
-\def\stoppacked
- {\par
- \ifvmode
- \egroup
- \ifdim\lastskip=\noparskipsignal\relax
- \removelastskip
- \nowhitespace
- \vskip-\lastdoneparskip
- \vskip+\lastdoneparskip
- \prevdepth-\lastdoneprevdepth % zeer recent toegevoegd
- \fi
- \fi}
-
-\def\startunpacked
- {\blank
- \leavevmode
- \bgroup}
-
-\def\stopunpacked
- {\egroup
- \blank}
-
-% De onderstaande macro's moeten nog eens nader worden uitgewerkt.
-% Ze spelen een rol bij de spatiering rond omkaderde teksten
-% en/of boxen zonder diepte.
-
-\def\toonregelcorrectie{\showbaselinecorrection}
-\def\regelcorrectie {\baselinecorrection}
-
-% \prevdepth crosses pageboundaries!
-%
-% todo: a version that works ok inside a box
-
-\let\doaroundlinecorrection\relax
-
-\def\startlinecorrection
- {\dodoubleempty\dostartlinecorrection}
-
-\def\dostartlinecorrection[#1][#2]% #2 gobbles spaces
- {\bgroup
- \processaction
- [#1]
- [ \v!blank=>\let\doaroundlinecorrection\blank,
- \s!default=>\let\doaroundlinecorrection\relax,
- \s!unknown=>{\def\doaroundlinecorrection{\blank[#1]}}]%
- \doaroundlinecorrection
- \startbaselinecorrection
- \offbaselinecorrection
- \ignorespaces}
-
-\def\stoplinecorrection
- {\stopbaselinecorrection
- \doaroundlinecorrection
- \egroup}
-
-\def\correctwhitespace
- {\dowithnextbox
- {\startbaselinecorrection
- \flushnextbox
- \stopbaselinecorrection}%
- \vbox}
-
-\def\verticalstrut {\normalvbox{\hsize\zeropoint\forgetall\strut}}
-\def\horizontalstrut{\normalhbox {\strut}}
-
-% Hieronder volgen enkele instellingen en macro's ten behoeve
-% van de interlinie en \strut. De waarden 2.8, 0.07, 0.72 en
-% 0.28 zijn ooit eens ontleend aan INRS-TEX en moeten wellicht
-% nog eens instelbaar worden.
-%
-% \lineheight : de hoogte van een regel
-% \spacing{getal} : instellen interlinie
-% \normalbaselines : instellen regelafstend
-%
-% \setstrut : instellen \strut
-% \setnostrut : resetten \strut, \endstrut, \begstrut
-%
-% \setteststrut : instellen zichtbare struts
-% \resetteststrut : instellen onzichtbare struts
-%
-% \setfontparameters : instellen na fontset
-%
-% De hoogte van een regel (\lineheight) is gelijk aan de
-% som van de hoogte (\ht) en diepte (\dp) van \strutbox.
-%
-% \strut : denkbeeldig blokje met hoogte en diepte
-%
-% Een \hbox kan als deze aan het begin van een regel staat
-% een breedte \hsize krijgen. Dit is soms te voorkomen met het
-% commando \leavevmode. Binnen een \vbox geeft dit echter
-% niet altijd het gewenste resultaat, vandaar het commando
-%
-% \leaveoutervmode
-
-% Pas op: niet zomaar \topskip en \baselineskip aanpassen
-% en zeker niet \widowpenalty. Dit kan ernstige gevolgen
-% hebben voor kolommen.
-%
-% Enige glue kan op zich geen kwaad, echter als blanko=vast,
-% dan moet ook de rek 0 zijn. Binnen kolommen is rek ook
-% niet bepaald mooi. Een hele kleine waarde (0.025) voldoet,
-% omdat een positieve glue eindeloos rekbaar is.
-
-\newdimen\strutdimen
-\newdimen\lineheight
-\newdimen\openlineheight
-\newdimen\openstrutheight
-\newdimen\openstrutdepth
-\newdimen\topskipgap
-\newdimen\struttotal
-
-\def\strutheightfactor {.72}
-\def\strutdepthfactor {.28}
-
-\def\baselinefactor {2.8}
-\def\baselinegluefactor {0}
-
-\def\minimumstrutheight {0pt}
-\def\minimumstrutdepth {0pt}
-
-\def\normallineheight {\baselinefactor ex}
-\def\minimumlinedistance {\lineskip}
-
-\def\strutheight {0pt}
-\def\strutdepth {0pt}
-\def\strutwidth {0pt}
-
-\def\spacingfactor {1}
-
-\def\topskipfactor {1.0}
-\def\maxdepthfactor {0.5}
-
-\def\systemtopskipfactor {\topskipfactor}
-\def\systemmaxdepthfactor {\maxdepthfactor}
-
-% De onderstaande definitie wordt in de font-module overruled
-
-\ifx\globalbodyfontsize\undefined
- \newdimen\globalbodyfontsize
- \globalbodyfontsize=12pt
-\fi
-
-\ifx\normalizedbodyfontsize\undefined
- \def\normalizedbodyfontsize{12pt}
-\fi
-
-% door een \dimen. Dit is geen probleem omdat (1) de default
-% korpsgrootte 12pt is en (2) de fonts nog niet geladen zijn
-% en de instellingen bij het laden nogmaals plaatsvinden.
-
-% \def\topskipcorrection
-% {\ifdim\topskip>\openstrutheight
-% % == \vskip\topskipgap
-% \vskip\topskip
-% \vskip-\openstrutheight
-% \fi
-% \verticalstrut
-% \vskip-\struttotal}
-
-\def\topskipcorrection
- {\simpletopskipcorrection
- \vskip-\struttotal
- \verticalstrut}
-
-\def\simpletopskipcorrection
- {\ifdim\topskip>\openstrutheight
- % == \vskip\topskipgap
- \vskip\topskip
- \vskip-\openstrutheight
- \fi}
-
-% \def\settopskip % the extra test is needed for the lbr family
-% {\topskip\systemtopskipfactor\globalbodyfontsize
-% \ifgridsnapping \else
-% \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
-% \fi
-% \relax % the skip
-% \topskipgap\topskip
-% \advance\topskipgap -\openstrutheight\relax
-% \ifdim\topskip<\strutheightfactor\openlineheight
-% \topskip\strutheightfactor\openlineheight\relax
-% \fi}
-
-\def\settopskip % the extra test is needed for the lbr family
- {\topskip\systemtopskipfactor\globalbodyfontsize
- \ifgridsnapping \else
- \ifr@ggedbottom\!!plus5\globalbodyfontsize\fi
- \fi
- \relax % the skip
- \topskipgap\topskip
- \advance\topskipgap -\openstrutheight\relax
-\ifdim\minimumstrutheight>\zeropoint
- \ifdim\topskip<\minimumstrutheight
- \topskip\minimumstrutheight\relax
- \fi
-\else
- \ifdim\topskip<\strutheightfactor\openlineheight
- \topskip\strutheightfactor\openlineheight\relax
- \fi
-\fi}
-
-\def\setmaxdepth
- {\maxdepth\systemmaxdepthfactor\globalbodyfontsize}
-
-\def\normalbaselines
- {\baselineskip \normalbaselineskip
- \lineskip \normallineskip
- \lineskiplimit\normallineskiplimit}
-
-% \def\setnormalbaselines
-% {\ifdim\normallineheight>\zeropoint
-% \lineheight\normallineheight
-% \fi
-% \openlineheight\spacingfactor\lineheight
-% \openstrutheight\strutheightfactor\openlineheight
-% \openstrutdepth \strutdepthfactor \openlineheight
-% \normalbaselineskip\openlineheight
-% \!!plus\baselinegluefactor\openlineheight
-% \!!minus\baselinegluefactor\openlineheight
-% \normallineskip\minimumlinedistance\relax % \onepoint\relax
-% \normallineskiplimit\zeropoint\relax
-% \normalbaselines}
-
-\def\setnormalbaselines
- {\ifdim\normallineheight>\zeropoint
- \lineheight\normallineheight
- \fi
- \openlineheight\spacingfactor\lineheight
- \openstrutheight \ifdim\minimumstrutheight>\zeropoint
- \minimumstrutheight % new
- \else
- \strutheightfactor\openlineheight
- \fi
- \openstrutdepth \ifdim\minimumstrutdepth>\zeropoint
- \minimumstrutdepth % new
- \else
- \strutdepthfactor \openlineheight
- \fi
- \ifdim\dimexpr\minimumstrutdepth+\minimumstrutheight\relax>\zeropoint
- \openlineheight\dimexpr\openstrutheight+\openstrutdepth\relax % new
- \fi
- \normalbaselineskip\openlineheight
- \ifgridsnapping\else
- \!!plus \baselinegluefactor\openlineheight
- \!!minus\baselinegluefactor\openlineheight
- \fi
- \normallineskip\minimumlinedistance\relax % \onepoint\relax
- \normallineskiplimit\zeropoint\relax
- \normalbaselines
- \mksetupgridsnapping}
-
-% \def\setspacingfactor#1\to#2\by#3\\%
-% {\strutdimen#2\points
-% \strutdimen#3\strutdimen
-% \edef#1{\withoutpt\the\strutdimen}}
-%
-% \def\spacing#1%
-% {\ifgridsnapping
-% %\doifnot{#1}{1}{\showmessage\m!layouts{11}{#1}}%
-% \ifdim#1\points=\onepoint\else\showmessage\m!layouts{11}{#1}\fi
-% \edef\spacingfactor{1}%
-% \else
-% \edef\spacingfactor{#1}%
-% \fi
-% \setspacingfactor\systemtopskipfactor \to\topskipfactor \by#1\\% why no \spacingfactor ?
-% \setspacingfactor\systemmaxdepthfactor\to\maxdepthfactor\by#1\\% why no \spacingfactor ?
-% \setnormalbaselines
-% \setstrut}
-%
-% \def\setspacingfactor#1#2#3%
-% {\edef#1{\withoutpt\the\dimexpr#2\points*#3\relax}}
-
-\def\spacing#1%
- {\ifgridsnapping
- \ifdim#1\points=\onepoint\else\showmessage\m!layouts{11}{#1}\fi
- \edef\spacingfactor{1}%
- \else
- \edef\spacingfactor{#1}%
- \fi
- %\setspacingfactor\systemtopskipfactor \topskipfactor {#1}% why no \spacingfactor ?
- %\setspacingfactor\systemmaxdepthfactor\maxdepthfactor{#1}% why no \spacingfactor ?
- \edef\systemtopskipfactor {\withoutpt\the\dimexpr#1\dimexpr\topskipfactor \points}%
- \edef\systemmaxdepthfactor{\withoutpt\the\dimexpr#1\dimexpr\maxdepthfactor\points}%
- \setnormalbaselines
- \setstrut}
-
-%D Sometimes one needs to freeze the interlinespacing
-%D
-%D \starttyping
-%D \rm \saveinterlinespace .... {\ss \restoreinterlinespace .... \endgraf}
-%D \stoptyping
-
-\let\restoreinterlinespace\relax
-
-\def\saveinterlinespace
- {\edef\restoreinterlinespace
- {\lineheight \the\lineheight
- \openstrutheight \the\openstrutheight
- \openstrutdepth \the\openstrutdepth
- \openlineheight \the\openlineheight
- \normalbaselineskip \the\normalbaselineskip
- \normallineskip \the\normallineskip
- \normallineskiplimit\the\normallineskiplimit
- \noexpand\def\noexpand\normallineheight{\the\dimexpr\normallineheight}%
- \noexpand\normalbaselines}}
-
-% plain definition:
-%
-% \def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
-%
-% could be:
-%
-% \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
-
-\ifx\strutbox\undefined
-
- \newbox\strutbox
-
- \setbox\strutbox=\normalhbox{\vrule height8.5pt depth3.5pt width\z@}
-
- %\def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
- \def\strut{\relax\ifmmode\copy\else\unhcopy\fi\strutbox}
-
-\fi
-
-\let\normalstrut=\strut
-
-% The double \hbox construction enables us to \backtrack
-% boxes.
-
-% \def\setstrutdimen#1#2#3% % een strut is n.m maal ex
-% {\strutdimen\normallineheight % wat niet per se \lineheight
-% \strutdimen#2\strutdimen % is omdat een strut lokaal
-% \strutdimen#3\strutdimen % kan afwijken van de globale
-% \edef#1{\the\strutdimen}} % macro % strut
-
-% \def\setstrutdimen#1#2#3% % een strut is n.m maal ex
-% {\strutdimen\normallineheight % wat niet per se \lineheight
-% \strutdimen#2\strutdimen % is omdat een strut lokaal
-% \strutdimen#3\strutdimen % kan afwijken van de globale
-% \edef#1{\the\strutdimen}} % macro % strut
-
-% \def\setstrut
-% {\setstrutdimen\strutheight\strutheightfactor\spacingfactor
-% \setstrutdimen\strutdepth \strutdepthfactor \spacingfactor
-% \let\strut=\normalstrut
-% \setbox\strutbox=\normalhbox
-% {\normalhbox
-% {\vrule
-% \!!width \strutwidth
-% \!!height \strutheight
-% \!!depth \strutdepth
-% \normalkern-\strutwidth}}}
-
-% \def\setstrut
-% {\setstrutdimen\strutheight\strutheightfactor\spacingfactor
-% \setstrutdimen\strutdepth \strutdepthfactor \spacingfactor
-% \dosetstrut}
-
-% \def\setstrut
-% {\strutdimen\normallineheight
-% \strutdimen\strutheightfactor\strutdimen
-% \strutdimen\spacingfactor\strutdimen
-% \edef\strutheight{\the\strutdimen}%
-% \strutdimen\normallineheight
-% \ifgridsnapping
-% \advance\strutdimen-\strutheight
-% \else
-% \strutdimen\strutdepthfactor\strutdimen
-% \strutdimen\spacingfactor\strutdimen
-% \fi
-% \edef\strutdepth{\the\strutdimen}%
-% \dosetstrut}
-
-% interesting, strutdepth is 4.05064pt vs 4.05066pt depending on grid
-% nasty rounding problem
-
-% \def\setstrut
-% {% height
-% \strutdimen\normallineheight
-% \ifdim\minimumstrutheight>\zeropoint
-% \strutdimen\minimumstrutheight
-% \else
-% \strutdimen\strutheightfactor\strutdimen
-% \fi
-% \strutdimen\spacingfactor\strutdimen
-% \edef\strutheight{\the\strutdimen}%
-% % depth
-% \strutdimen\normallineheight
-% \ifgridsnapping
-% \ifdim\minimumstrutdepth>\zeropoint
-% \strutdimen\minimumstrutdepth
-% \else
-% \advance\strutdimen-\strutheight
-% \fi
-% \else
-% \ifdim\minimumstrutdepth>\zeropoint
-% \strutdimen\minimumstrutdepth
-% \else
-% \strutdimen\strutdepthfactor\strutdimen
-% \fi
-% \strutdimen\spacingfactor\strutdimen
-% \fi
-% \edef\strutdepth{\the\strutdimen}%
-% % finish
-% \dosetstrut}
-
-% \def\setstrut
-% {% height
-% \ifdim\minimumstrutheight>\zeropoint
-% \edef\strutheight{\the\dimexpr\spacingfactor\dimexpr\minimumstrutheight}%
-% \else
-% \edef\strutheight{\the\dimexpr\spacingfactor\dimexpr\strutheightfactor\dimexpr\normallineheight}%
-% \fi
-% % depth
-% \ifgridsnapping
-% \ifdim\minimumstrutdepth>\zeropoint
-% \edef\strutdepth{\the\dimexpr\minimumstrutdepth}%
-% \else
-% \edef\strutdepth{\the\dimexpr\normallineheight-\strutheight}%
-% \fi
-% \else
-% \ifdim\minimumstrutdepth>\zeropoint
-% \edef\strutdepth{\the\dimexpr\spacingfactor\dimexpr\minimumstrutdepth}%
-% \else
-% \edef\strutdepth{\the\dimexpr\spacingfactor\dimexpr\strutdepthfactor\dimexpr\normallineheight}%
-% \fi
-% \fi
-% % finish
-% \dosetstrut}
-
-\unexpanded\def\setstrut
- {% height
- \edef\strutheight
- {\the\dimexpr\spacingfactor\dimexpr
- \ifdim\minimumstrutheight>\zeropoint
- \minimumstrutheight
- \else
- \strutheightfactor\dimexpr\normallineheight
- \fi}%
- % depth
- \edef\strutdepth%
- {\the\dimexpr
- \ifgridsnapping
- \ifdim\minimumstrutdepth>\zeropoint
- \minimumstrutdepth
- \else
- \normallineheight-\strutheight
- \fi
- \else
- \spacingfactor\dimexpr
- \ifdim\minimumstrutdepth>\zeropoint
- \minimumstrutdepth
- \else
- \strutdepthfactor\dimexpr\normallineheight
- \fi
- \fi}%
- % finish
- \dosetstrut}
-
-\unexpanded\def\setcharstrut#1%
- {\setbox\strutbox\normalhbox{#1}%
- \edef\strutheight{\the\strutht}%
- \edef\strutdepth {\the\strutdp}%
- \dosetstrut}
-
-% \def\setfontstrut
-% {\setcharstrut{(}}
-%
-% better, since some fonts have small (but descending Q etc)
-
-\unexpanded\def\setfontstrut
- {\setcharstrut{(gplQT}}
-
-\unexpanded\def\setcapstrut% could be M, but Q has descender
- {\setcharstrut{Q}}
-
-%D Handy for math (used in mathml):
-
-\def\charhtstrut
- {\begingroup
- \setcharstrut{GJY}%
- \vrule\!!width\zeropoint\!!depth\zeropoint\!!height\strutht
- \endgroup}
-
-\def\chardpstrut
- {\begingroup
- \setcharstrut{gjy}%
- \vrule\!!width\zeropoint\!!depth\strutdp\!!height\zeropoint
- \endgroup}
-
-%D Centered looks nicer:
-
-% \def\dosetstrut
-% {\let\strut\normalstrut
-% \setbox\strutbox\normalhbox
-% {\normalhbox to \zeropoint
-% {% \hss % new, will be option
-% \vrule
-% \!!width \strutwidth
-% \!!height\strutheight
-% \!!depth \strutdepth
-% \hss}}%
-% \struttotal\dimexpr\strutht+\strutdp\relax}
-%
-% because of all the callbacks in mkiv, we avoid unnecessary boxes ...
-% maybe use an attribute so that we can tag boxes that don't need a
-% treatment; tests with using an attribute so far have shown that
-% it's slower because testing the attribute takes time too
-
-\def\dosetstrut
- {\let\strut\normalstrut
- \ifdim\strutwidth=\zeropoint
- \setbox\strutbox\normalhbox
- {\vrule
- \!!width \zeropoint
- \!!height\strutheight
- \!!depth \strutdepth}%
- \else
- \setbox\strutbox\normalhbox
- {\normalhbox to \zeropoint
- {% \hss % new, will be option
- \vrule
- \!!width \strutwidth
- \!!height\strutheight
- \!!depth \strutdepth
- \hss}}%
- \fi
- \struttotal\dimexpr\strutht+\strutdp\relax}
-
-%D The dimen \type {\struttotal} holds the exact size of the
-%D strut; occasionally a one scaled point difference can show
-%D up with the lineheight.
-
-%D Sometimes a capstrut comes in handy
-%D
-%D \starttabulate[|Tl|l|l|]
-%D \NC yes \NC normal strut \NC {\showstruts\setupstrut[yes]\strut} \NC \NR
-%D \NC no \NC no strut \NC {\showstruts\setupstrut[no]\strut} \NC \NR
-%D \NC kap \NC a capital strut (i.e. Q) \NC {\showstruts\setupstrut[cap]\strut} \NC \NR
-%D \NC A B \unknown \NC a character strut (e.g. A) \NC {\showstruts\setupstrut[A]\strut} \NC \NR
-%D \NC \NC a normal strut \NC {\showstruts\setupstrut\strut} \NC \NR
-%D \stoptabulate
-
-\def\setupstrut
- {\dosingleempty\dosetupstrut}
-
-\def\dosetupstrut[#1]% yet undocumented, todo: fontstrut
- {\processaction
- [#1]
- [ \v!yes=>\setstrut,
- \v!auto=>\setautostrut,
- \v!no=>\setnostrut,
- \v!cap=>\setcapstrut,
- \v!fit=>\setfontstrut,
- \v!line=>\setstrut,
- \s!default=>\setstrut,
- \s!unknown=>\setcharstrut\commalistelement]}
-
-\def\setteststrut
- {\def\strutwidth{.8pt}%
- \setstrut}
-
-\def\autostrutfactor{1.1}
-
-\def\setautostrut
- {\begingroup
- \setbox\scratchbox\copy\strutbox
- \setstrut
- \ifdim\ht\strutbox>\autostrutfactor\ht\scratchbox
- \endgroup \setstrut
- \else\ifdim\dp\strutbox>\autostrutfactor\dp\scratchbox
- \endgroup \setstrut
- \else
- \endgroup
- \fi\fi}
-
-% simple version
-%
-% \def\begstrut
-% {\relax\ifcase\strutht\else
-% \strut
-% \normalpenalty\plustenthousand
-% \normalhskip\zeropoint
-% \ignorespaces
-% \fi}
-%
-% \def\endstrut
-% {\relax\ifhmode\ifcase\strutht\else
-% \removeunwantedspaces
-% \normalpenalty\plustenthousand
-% \normalhskip\zeropoint
-% \strut
-% \fi\fi}
-
-% when enabled, sigstruts will remove themselves if nothing
-% goes inbetween
-
-\newsignal\strutsignal \setfalse\sigstruts
-
-\def\begstrut
- {\relax\ifcase\strutht\else
- \ifconditional\sigstruts
- \noindent\horizontalstrut
- \normalpenalty\plustenthousand
- \normalhskip-\strutsignal
- \normalhskip\strutsignal
- \else
- \strut
- \normalpenalty\plustenthousand
- \normalhskip\zeropoint
- \fi
- \expandafter \ignorespaces
- \fi}
-
-\def\endstrut
- {\relax\ifhmode\ifcase\strutht\else
- \ifconditional\sigstruts
- \ifdim\lastskip=\strutsignal
- \unskip\unskip\unpenalty\setbox\scratchbox\lastbox
- \else
- \normalpenalty\plustenthousand
- \normalhskip\zeropoint
- \strut
- \fi
- \else
- \removeunwantedspaces
- \normalpenalty\plustenthousand
- \normalhskip\zeropoint
- \strut
- \fi
- \fi\fi}
-
-\newbox\nostrutbox \setbox\nostrutbox\normalhbox{} % {\normalhbox{}}
-
-\def\setnostrut
- {\setbox\strutbox\copy\nostrutbox
- \let\strut\empty
- \let\endstrut\empty
- \let\begstrut\empty
- \let\crlfplaceholder\empty}
-
-% unsave:
-%
-% \def\pseudostrut
-% {\bgroup
-% \setnostrut
-% \normalstrut
-% \egroup}
-%
-% try:
-%
-% \startchemie
-% \chemie[ONE,Z0,SB15,MOV1,SB15,Z0][C,C]
-% \stopchemie
-%
-% so:
-
-\def\pseudostrut
- {\noindent} % better: \dontleavehmode
-
-\let\pseudobegstrut\pseudostrut
-
-\let\pseudoendstrut\removeunwantedspaces
-
-\def\resetteststrut
- {\let\strutwidth\zeropoint
- \setstrut}
-
-\ifx\setfontparameters\undefined
- % problems ! ! ! !
- \def\setfontparameters{\the\everybodyfont}
-\fi
-
-%D Handy:
-
-\def\baselinedistance{\the\lineheight}
-
-%D We need \type{\normaloffinterlineskip} because the new
-%D definition contains an assignment, and |<|don't ask me
-%D why|>| this assignment gives troubles in for instance the
-%D visual debugger.
-
-%D The plain ones:
-
-\def\offinterlineskip
- {\baselineskip-\thousandpoint
- \lineskip\zeropoint
- \lineskiplimit\maxdimen}
-
-\def\nointerlineskip
- {\prevdepth-\thousandpoint}
-
-\let\normaloffinterlineskip=\offinterlineskip % knuth's original
-
-%D My own one:
-
-\def\offinterlineskip
- {\ifdim\baselineskip>\zeropoint
- \edef\oninterlineskip
- {\baselineskip\the\baselineskip
- \lineskip\the\lineskip
- \lineskiplimit\the\lineskiplimit
- \let\noexpand\offinterlineskip\noexpand\normaloffinterlineskip}%
- \else
- \let\oninterlineskip\setnormalbaselines
- \fi
- \normaloffinterlineskip}
-
-\let\oninterlineskip=\relax
-
-\def\leaveoutervmode
- {\ifvmode\ifinner\else
- \leavevmode
- \fi\fi}
-
-% We stellen enkele penalties anders in dan Plain TEX:
-
-% oud
-%
-% \widowpenalty=\defaultwidowpenalty\relax
-% \clubpenalty =\defaultclubpenalty \relax
-
-\def\resetpenalties#1%
- {\ifx#1\undefined\else
- #1\minusone
- \fi}
-
-\def\setpenalties#1#2#3%
- {\ifx#1\undefined\else % space before #3 prevents lookahead problems, needed when #3=text
- #1\numexpr#2+\plusone\relax\space\doexpandedrecurse{\the\numexpr#2\relax}{ #3}\zerocount\relax
- \fi}
-
-\def\doexpandedrecurse#1#2%
- {\ifnum#1>\zerocount#2\@EA\doexpandedrecurse\@EA{\the\numexpr#1-1\relax}{#2}\fi}
-
-%D \macros
-%D {keeplinestogether}
-%D
-%D Dirty hack, needed in margin content that can run of a page.
-
-\def\keeplinestogether#1%
- {\xdef\restoreinterlinepenalty{\global\resetpenalties\interlinepenalties}%
- \global\setpenalties\interlinepenalties{#1}\plustenthousand}
-
-\newif\ifgridsnapping % to be sure
-
-\def\defaultwidowpenalty {2000} % was: 1000
-\def\defaultclubpenalty {2000} % was: 800
-\def\defaultdisplaywidowpenalty {50}
-\def\defaultbrokenpenalty {100}
-
-\def\defaultgridwidowpenalty {0}
-\def\defaultgridclubpenalty {0}
-\def\defaultgriddisplaywidowpenalty {0}
-\def\defaultgridbrokenpenalty {0}
-
-% The original approach:
-%
-% \def\setdefaultpenalties
-% {\ifgridsnapping
-% \widowpenalty\defaultgridwidowpenalty
-% \clubpenalty \defaultgridclubpenalty
-% \else
-% \widowpenalty\defaultwidowpenalty
-% \clubpenalty \defaultclubpenalty
-% \fi}
-%
-% However, we will use setups:
-
-% to be documented
-
-\def\nopenalties
- {\widowpenalty \zerocount
- \clubpenalty \zerocount
- \brokenpenalty \zerocount
- \doublehyphendemerits\zerocount
- \finalhyphendemerits \zerocount
- \adjdemerits \zerocount}
-
-\def\setdefaultpenalties
- {\directsetup{\systemsetupsprefix\s!default}}
-
-\startsetups [\systemsetupsprefix\s!reset]
- \resetpenalties\widowpenalties
- \resetpenalties\clubpenalties
- \resetpenalties\interlinepenalties
-\stopsetups
-
-% we use \directsetup because it's faster and we know there is no csl
-
-\startsetups [\systemsetupsprefix\s!default]
-
- \directsetup{\systemsetupsprefix\s!reset}
-
- \widowpenalty \defaultwidowpenalty
- \clubpenalty \defaultclubpenalty
- \displaywidowpenalty\defaultdisplaywidowpenalty
- \brokenpenalty \defaultbrokenpenalty
-
-\stopsetups
-
-\startsetups [\v!grid] [\systemsetupsprefix\s!default]
-
- \directsetup{\systemsetupsprefix\s!reset}
-
- \widowpenalty \defaultgridwidowpenalty
- \clubpenalty \defaultgridclubpenalty
- \displaywidowpenalty\defaultgriddisplaywidowpenalty
- \brokenpenalty \defaultgridbrokenpenalty
-
-\stopsetups
-
-% as an illustration:
-
-\startsetups [\systemsetupsprefix\v!strict]
-
- \directsetup{\systemsetupsprefix\s!reset}
-
- \setpenalties\widowpenalties2\maxdimen
- \setpenalties\clubpenalties 2\maxdimen
- \brokenpenalty \maxdimen
-
-\stopsetups
-
-\setdefaultpenalties % will happen later in \setuplayout
-
-% Suggested by GB (not the name -):
-
-\def\rapfillskip{.5\hsize plus .092\hsize minus .5\hsize} % D.A.'s value
-
-% Bovendien definieren we enkele extra \fill's:
-
-\def\hfilll{\hskip\zeropoint\!!plus1filll\relax}
-\def\vfilll{\vskip\zeropoint\!!plus1filll\relax}
-
-% De onderstaande hulpmacro's moeten nog eens instelbaar worden
-% gemaakt.
-
-\def\tfskipsize{1em\relax}
-\def\tfkernsize{1ex\relax}
-
-\def\tfskip{\dotfskip\tfskipsize}
-\def\tfkern{\dotfkern\tfkernsize}
-
-\def\dotfskip#1{{\tf\hskip#1}}
-\def\dotfkern#1{{\tf\kern #1}}
-
-% needs a proper \definenarrower or installnarrower
-
-\newskip\ctxleftskip
-\newskip\ctxrightskip
-\newskip\ctxmidskip
-
-\def\dosinglenarrower#1%
- {\processaction
- [#1]
- [ \v!left=>\global\advance\ctxleftskip \@@slleft,
- \v!middle=>\global\advance\ctxmidskip \@@slmiddle,
- \v!right=>\global\advance\ctxrightskip \@@slright,
- \v!reset=>\global\ctxleftskip \zeropoint
- \global\ctxmidskip \zeropoint
- \global\ctxrightskip\zeropoint,
- \v!none=>,
- \s!unknown=>\global\advance\ctxmidskip \commalistelement]}
-
-% \def\donarrower[#1]% hm, can be dorepeat directly
-% {\processaction
-% [#1]
-% [ \v!left=>\global\advance\ctxleftskip \@@slleft,
-% \v!middle=>\global\advance\ctxmidskip \@@slmiddle,
-% \v!right=>\global\advance\ctxrightskip \@@slright,
-% \v!none=>,% handy for delimitedtexts
-% \s!unknown=>{\dorepeatwithcommand[#1]\dosinglenarrower}]}
-
-\def\donarrower[#1]% hm, can be dorepeat directly
- {\dorepeatwithcommand[#1]\dosinglenarrower}
-
-\def\complexstartnarrower[#1]%
- {\@@slbefore % was hard coded \par
- \bgroup
- \global\ctxleftskip \zeropoint
- \global\ctxrightskip\zeropoint
- \global\ctxmidskip \zeropoint
- \processcommalistwithparameters[#1]\donarrower
- \advance\leftskip \ctxleftskip
- \advance\rightskip \ctxrightskip
- \advance\leftskip \ctxmidskip
- \advance\rightskip \ctxmidskip
- \seteffectivehsize}
-
-% todo: definenarrower
-
-\def\simplestartnarrower
- {\startnarrower[\v!middle]}
-
-\definecomplexorsimple\startnarrower
-
-\def\stopnarrower
- {\@@slafter % was hard coded \par / needed, else skips forgotten
- \egroup}
-
-\def\setupnarrower
- {\dodoubleargument\getparameters[\??sl]}
-
-\newdimen\@@effectivehsize \def\effectivehsize {\hsize}
-\newdimen\@@effectiveleftskip \def\effectiveleftskip {\leftskip}
-\newdimen\@@effectiverightskip \def\effectiverightskip{\rightskip}
-
-\def\seteffectivehsize
- {\setlocalhsize
- \@@effectivehsize \localhsize
- \@@effectiveleftskip \leftskip
- \@@effectiverightskip \rightskip
- \let\effectivehsize \@@effectivehsize
- \let\effectiveleftskip \@@effectiveleftskip
- \let\effectiverightskip\@@effectiverightskip}
-
-\def\dodefinehbox[#1][#2]%
- {\setvalue{hbox#1}##1%
- {\hbox to #2{\begstrut##1\endstrut\hss}}}
-
-\def\definehbox
- {\dodoubleargument\dodefinehbox}
-
-\def\iobox#1#2#3#% here #3# is not really needed
- {\vbox\bgroup % we want to return a vbox like the others
- \hbox\bgroup% we need to pack the signal with the box
- \signalrightpage
- \dowithnextboxcontent
- {\let\\=\endgraf\forgetall\doifrightpageelse#1#2}
- {\box\nextbox\egroup\egroup}
- \vbox#3}
-
-\def\obox{\iobox\raggedleft \raggedright} % outerbox
-\def\ibox{\iobox\raggedright\raggedleft} % innerbox
-
-\def\dosetraggedvbox#1%
- {\let\raggedbox\vbox
- \processfirstactioninset
- [#1]
- [ \v!left=>\let\raggedbox\lbox,
- \v!right=>\let\raggedbox\rbox,
- \v!middle=>\let\raggedbox\cbox,
- \v!inner=>\let\raggedbox\ibox,
- \v!outer=>\let\raggedbox\obox,
- \v!flushleft=>\let\raggedbox\rbox,
- \v!flushright=>\let\raggedbox\lbox,
- \v!center=>\let\raggedbox\cbox,
- \v!no=>\def\raggedbox{\vbox\bgroup\raggedright\let\next=}]}
-
-\def\dosetraggedhbox#1%
- {\let\raggedbox\hbox
- \processaction % slow
- [#1]
- [ \v!left=>\def\raggedbox{\doalignedline\v!left },
- \v!right=>\def\raggedbox{\doalignedline\v!right },
- \v!middle=>\def\raggedbox{\doalignedline\v!middle},
- \v!inner=>\def\raggedbox{\doalignedline\v!inner },
- \v!outer=>\def\raggedbox{\doalignedline\v!outer },
- \v!flushleft=>\def\raggedbox{\doalignedline\v!right },
- \v!flushright=>\def\raggedbox{\doalignedline\v!left },
- \v!center=>\def\raggedbox{\doalignedline\v!middle}]}
-
-\def\dosetraggedcommand#1%
- {\expanded{\dodosetraggedcommand{#1}}}
-
-% \def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
-% {\let\raggedcommand \relax
-% \let\raggedtopcommand \empty
-% \let\raggedbottomcommand\empty
-% \chardef\raggedoneliner\zerocount
-% \doifsomething{#1}
-% {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
-% \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
-% \!!donectrue
-% \rawprocesscommalist[#1]\dododosetraggedcommand}}
-
-\newtoks\everyraggedcommand
-
-\def\raggedcommand{\the\everyraggedcommand}
-
-\def\dodosetraggedcommand#1% beware: #1=empty is ignored, keep that!
- {\everyraggedcommand \emptytoks
- \let\raggedtopcommand \empty
- \let\raggedbottomcommand\empty
- \chardef\raggedoneliner\zerocount
- \doifsomething{#1}
- {\doifinsetelse\v!broad{#1}\!!doneatrue\!!doneafalse
- \doifinsetelse\v!wide {#1}\!!donebtrue\!!donebfalse
- \!!donectrue
- \rawprocesscommalist[#1]\dododosetraggedcommand}}
-
-\def\dododosetraggedcommand#1%
- {\executeifdefined{\@@ragged@@command\string#1}\relax}
-
-\def\@@ragged@@command{@@raggedcommand}
-
-\setvalue{\@@ragged@@command\v!hanging }{\appendtoks\enableprotruding \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!nothanging }{\appendtoks\disableprotruding \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!hz }{\appendtoks\enableadjusting \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!nohz }{\appendtoks\disableadjusting \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!spacing }{\appendtoks\enablespacehandling
- \enablekernhandling \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!nospacing }{\appendtoks\disablespacehandling
- \disablekernhandling \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!hyphenated }{\appendtoks\dohyphens \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!nothyphenated}{\appendtoks\nohyphens \to\everyraggedcommand}
-
-\setvalue{\@@ragged@@command\v!tolerant }{\appendtoks\tolerance3000\relax \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!verytolerant}{\appendtoks\tolerance4500\relax \to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!stretch }{\appendtoks\emergencystretch\bodyfontsize\to\everyraggedcommand}
-
-\setvalue{\@@ragged@@command\v!left}%
- {\if!!donea \appendtoks\veryraggedleft\to\everyraggedcommand
- \else \appendtoks\raggedleft \to\everyraggedcommand
- \fi
- \!!donecfalse}
-
-\setvalue{\@@ragged@@command\v!right}%
- {\if!!donea \appendtoks\veryraggedright\to\everyraggedcommand
- \else \appendtoks\raggedright \to\everyraggedcommand
- \fi
- \!!donecfalse}
-
-\setvalue{\@@ragged@@command\v!middle}%
- {\if!!donec
- \if!!doneb \appendtoks\raggedwidecenter\to\everyraggedcommand
- \else\if!!donea \appendtoks\veryraggedcenter\to\everyraggedcommand
- \else \appendtoks\raggedcenter \to\everyraggedcommand
- \fi\fi
- \!!donecfalse
- \else
- \let\raggedbottomcommand\vfilll % bonus, pretty strong
- \let\raggedtopcommand \vfilll % used with \framed for
- \fi} % instance in tables
-
-\setvalue{\@@ragged@@command\v!flushleft }{\getvalue{\@@ragged@@command\v!right }}
-\setvalue{\@@ragged@@command\v!flushright}{\getvalue{\@@ragged@@command\v!left }}
-\setvalue{\@@ragged@@command\v!center }{\getvalue{\@@ragged@@command\v!middle}}
-
-\setvalue{\@@ragged@@command\v!high}%
- {\let\raggedbottomcommand\vfilll} % and since we lack a
-
-\setvalue{\@@ragged@@command\v!low}%
- {\let\raggedtopcommand\vfilll} % proper keyword, but
-
-\setvalue{\@@ragged@@command\v!lohi}%
- {\let\raggedbottomcommand\vfilll % we do support the
- \let\raggedtopcommand\vfilll} % ugly laho (lohi)
-
-\setvalue{\@@ragged@@command\v!no}%
- {\appendtoks\raggedright\to\everyraggedcommand}
-
-\setvalue{\@@ragged@@command\v!yes}%
- {\appendtoks\notragged\to\everyraggedcommand}
-
-\setvalue{\@@ragged@@command\v!normal}%
- {\appendtoks\notragged\to\everyraggedcommand}
-
-\setvalue{\@@ragged@@command\v!inner}% not yet perfect
- {\signalrightpage % may interfere
- \doifrightpageelse
- {\getvalue{\@@ragged@@command\v!right}}
- {\getvalue{\@@ragged@@command\v!left}}}
-
-\setvalue{\@@ragged@@command\v!outer}% not yet perfect
- {\signalrightpage % may interfere
- \doifrightpageelse
- {\getvalue{\@@ragged@@command\v!left}}
- {\getvalue{\@@ragged@@command\v!right}}}
-
-\setvalue{\@@ragged@@command\v!lesshyphenation}%
- {\appendtoks\lesshyphens\to\everyraggedcommand}
-\setvalue{\@@ragged@@command\v!morehyphenation}%
- {\appendtoks\morehyphens\to\everyraggedcommand}
-
-% compare:
-%
-% \framed[width=4cm,align=no] {\hfil xxx}
-% \framed[width=4cm,align=disable]{\hfil xxx}
-
-\setvalue{\@@ragged@@command\v!disable}% for one liners
- {\appendtoks\raggedright\parfillskip\zeropoint\to\everyraggedcommand}
-
-\chardef\raggedoneliner\zerocount
-
-\setvalue{\@@ragged@@command\v!line}%
- {\chardef\raggedoneliner\plusone}
-
-%D Unofficial, may disappear. Now handled directly in the
-%D core-rul module.
-
-% \def\@@startraggedoneliner
-% {\ifcase\raggedoneliner\else
-% \dontleavehmode\hbox to \hsize \bgroup % hsize added, else useless
-% \ifcase\raggedstatus\or\hss\or\hss\fi
-% \ignorespaces
-% \bgroup
-% \aftergroup\removeunwantedspaces
-% \fi}
-
-% \def\@@stopraggedoneliner
-% {\ifcase\raggedoneliner\else
-% \egroup
-% \ifcase\raggedstatus\or\or\hss\or\hss\fi
-% \egroup
-% \ignorespaces % ? ? ?
-% \fi}
-
-% \def\@@handleoneliner
-% {\ifcase\raggedoneliner\else
-% \@@startraggedoneliner
-% \aftergroup\@@stopraggedoneliner
-% \fi}
-
-% Nodig i.v.m. inspringen eerste alineas
-
-\def\explicithmode{\unhbox\voidb@x} % can probably become \dontleavehmode
-
-% Nog doen:
-%
-% \goodbreak -> \allowbreak en \dosomebreak{..} in koppen
-%
-% bij koppen zowieso: \blanko[reset]
-
-% Nog in commando verwerken:
-%
-% \voorkeur la \blanko
-%
-% Om ongewenste witruimte te voorkomen kan met \dosomebreak{\break}
-% een \penalty voor witruimte worden geplaatst.
-
-\def\removelastskip % a redefinition of plain
- {\ifvmode\ifdim\lastskip=\zeropoint\else\vskip-\lastskip\fi\fi}
-
-% first version:
-%
-% \def\dosomebreak#1%
-% {\scratchskip\lastskip
-% \removelastskip
-% %\type{#1}%
-% #1\relax
-% \ifdim\scratchskip=\zeropoint \else
-% \vskip\scratchskip
-% \fi}
-%
-% don't change the next improvement:
-
-% \def\dosomebreak#1%
-% {\endgraf % beware, this forces a newline
-% \ifvmode
-% \ifdim\lastskip=\zeropoint
-% #1\relax
-% \else
-% \scratchskip\lastskip
-% \removelastskip
-% #1\relax
-% \vskip\scratchskip
-% \fi
-% \fi}
-
-% beter, vooral in \vbox; nog in \pagina toepassen s!
-
-\def\doifoutervmode#1%
- {\ifvmode\ifinner\else#1\fi\fi}
-
-\ifx\dosomebreak\undefined % defined in mkiv
-
- \def\dosomebreak#1%
- {\doifoutervmode
- {\scratchskip\lastskip
- \removelastskip
- %\leavevmode\type{#1}%
- #1\relax
- \ifdim\scratchskip=\zeropoint % else interference with footnotes
- \else
- \vskip\scratchskip
- \fi}}
-
-\fi
-
-\def\forgeteverypar
- {\everypar{\the\neverypar}}
-
-%\def\forgetparindent
-% {\forgeteverypar
-% \indentfirstparagraphtrue % recently added
-% \setupindenting[\v!geen]}
-
-%\def\forgetparskip
-% {\setupwhitespace[\v!geen]}
-
-\def\forgetparindent
- {\forgeteverypar
- \indentfirstparagraphtrue % recently added
- \let\currentindentation\v!none
- \ctxparindent\zeropoint
- \parindent\zeropoint\relax}
-
-\def\forgetparskip
- {\let\currentwhitespace\v!none
- \ctxparskip\zeropoint
- \parskip\zeropoint\relax}
-
-\def\forgetbothskips
- {\tolerance1500
- \leftskip\zeropoint
- \rightskip\zeropoint\relax}
-
-\def\forgetspacing
- {\emergencystretch\zeropoint}
-
-\newif\ifforgotten % rather good signal for inner
-
-\appendtoks \forgottentrue \to \everyforgetall
-\appendtoks \forgetragged \to \everyforgetall
-\appendtoks \forgetparskip \to \everyforgetall
-\appendtoks \forgetparindent \to \everyforgetall
-\appendtoks \forgetbothskips \to \everyforgetall
-\appendtoks \forgetspacing \to \everyforgetall % i.v.m. funny spacing in pagebody
-\appendtoks \spacing\!!plusone \to \everyforgetall % new per 10/08/2004, else problems in otr / !! needed
-\appendtoks \everypar\emptytoks \to \everyforgetall % indeed!
-
-\def\localvbox#1#%
- {\vbox#1\bgroup
- \forgetparskip
- \setlocalhsize
- \hsize\localhsize
- \forgetparindent
- \forgetbothskips
- \forgeteverypar
- \let\next=}
-
-% ach ja, hoort niet hier
-
-% \unexpanded\def\dostartattributes#1#2#3%
-% {\begingroup % geen \bgroup, anders in mathmode lege \hbox
-% \doifdefinedelse{#1#2}
-% {\def\fontattribute{\getvalue{#1#2}}}
-% {\let\fontattribute=\empty}%
-% \doifdefinedelse{#1#3}
-% {\def\colorattribute{\getvalue{#1#3}}}
-% {\let\colorattribute=\empty}%
-% \startcolor[\colorattribute]%
-% \@EA\doconvertfont\@EA{\fontattribute}}
-%
-% \unexpanded\def\dostopattributes%
-% {\stopcolor
-% \endgroup}
-%
-% \unexpanded\def\doattributes#1#2#3#4%
-% {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}
-
-%D A hardly faster implementation follows. We cannot use
-%D \type {csname} testing since the first argument can be
-%D anything, even a raw fontswitch. No a real improvement
-%D (some 5 seconds on 260 seconds for the maps bibliography).
-
-\let\dostopattributes\relax % in case these commands end up in an edef
-
-\unexpanded\def\dostartattributes#1#2#3%
- {\begingroup % geen \bgroup, anders in mathmode lege \hbox
- \ifcsname#1#3\endcsname
- \let\dostopattributes\@@dostopattributes
- \startcolor[\csname#1#3\endcsname]%
- \else
- \let\dostopattributes\@@nostopattributes
- \fi
- \ifcsname#1#2\endcsname
- \expandafter\doconvertfont
- \else
- \expandafter\gobbleoneargument
- \fi{\csname#1#2\endcsname}}
-
-\newconditional \parbasedattributes
-
-\def\finishparbasedattributes
- {\ifconditional\parbasedattributes
- \setfalse\parbasedattributes
- \par
- \fi}
-
-\def\dostopparbasedattributes
- {\settrue\parbasedattributes
- \dostopattributes}
-
-\unexpanded\def\@@dostopattributes
- {\stopcolor
- \finishparbasedattributes
- \endgroup}
-
-\unexpanded\def\@@nostopattributes
- {\finishparbasedattributes
- \endgroup}
-
-\unexpanded\def\doattributes#1#2#3#4%
- {\dostartattributes{#1}{#2}{#3}{#4}\dostopattributes}
-
-% An even faster \ETEX\ version:
-
-\unexpanded\def\dostartattributes#1#2#3%
- {\begingroup % geen \bgroup, anders in mathmode lege \hbox
- \ifincolor
- \ifcsname#1#3\endcsname
- \let\dostopattributes\@@dostopattributes
- \faststartcolor[\csname#1#3\endcsname]%
- \else
- \let\dostopattributes\@@nostopattributes
- \fi
- \else
- \let\dostopattributes\@@nostopattributes
- \fi
- \ifcsname#1#2\endcsname
- % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
- \@EA\doconvertfont\csname#1#2\@EA\endcsname
- \fi}
-
-\unexpanded\def\@@dostopattributes
- {\faststopcolor
- \finishparbasedattributes
- \endgroup}
-
-\unexpanded\def\@@nostopattributes
- {\finishparbasedattributes
- \endgroup}
-
-%D Bonus macro, see core-sec.tex
-
-\unexpanded\def\dosetfontattribute#1#2%
- {\ifcsname#1#2\endcsname
- \@EA\doconvertfont\csname#1#2\@EA\endcsname
- \fi\empty}
-
-%D Since this happens a lot, and sometimes large arguments
-%D are passed in \type {#4}, we just copy some code:
-
-\unexpanded\def\doattributes#1#2#3#4%
- {\begingroup % geen \bgroup, anders in mathmode lege \hbox
- \ifincolor
- \ifcsname#1#3\endcsname
- \let\dostopattributes\@@dostopattributes
- \faststartcolor[\csname#1#3\endcsname]%
- \else
- \let\dostopattributes\endgroup
- \fi
- \else
- \let\dostopattributes\endgroup
- \fi
- \ifcsname#1#2\endcsname
- % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
- \@EA\doconvertfont\csname#1#2\@EA\endcsname
- \fi
- {#4}%
- \dostopattributes}
-
-% Kan vaker worden toegepast en moet bovendien sneller!
-
-\newskip\leftskipadaption
-\newskip\rightskipadaption
-
-\def\doadaptleftskip#1%
- {\dosetleftskipadaption{#1}%
- \advance\leftskip \leftskipadaption}
-
-\def\doadaptrightskip#1%
- {\dosetrightskipadaption{#1}%
- \advance\rightskip \rightskipadaption}
-
-\setvalue{@lsa@\v!standard}{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
-\setvalue{@lsa@\v!yes }{\ifdim\ctxparindent=\zeropoint\@@slleft\else\ctxparindent\fi}
-\letvalue{@lsa@\v!no }\zeropoint
-\letvalue{@lsa@\empty }\zeropoint
-\setvalue{@rsa@\v!standard}{\@@slright}
-\setvalue{@rsa@\v!yes }{\@@slright}
-\letvalue{@rsa@\v!no }\zeropoint
-\letvalue{@rsa@\empty }\zeropoint
-
-% not safe for 2\parindent
-%
-% \def\dosetleftskipadaption#1%
-% {\leftskipadaption
-% \ifcsname @lsa@#1\endcsname
-% \csname @lsa@#1\endcsname
-% \else
-% #1%
-% \fi
-% \relax}
-
-\def\dosetleftskipadaption#1%
- {\edefconvertedargument\ascii{@lsa@#1}%
- \leftskipadaption
- \ifcsname\ascii\endcsname
- \csname\ascii\endcsname
- \else
- #1%
- \fi
- \relax}
-
-\def\dosetrightskipadaption#1%
- {\edefconvertedargument\ascii{@rsa@#1}%
- \rightskipadaption
- \ifcsname\ascii\endcsname
- \csname\ascii\endcsname
- \else
- #1%
- \fi
- \relax}
-
-\newcount \noftrackedpagestates
-\newif \ifpagestatemismatch
-\newcount \realpagestateno
-\chardef \frozenpagestate \zerocount
-
-\def\dotrackpagestate#1#2%
- {\ifdoublesided \ifinpagebody \else
- \doforcedtrackpagestate{#1}{#2}%
- \fi \fi}
-
-\def\doforcedtrackpagestate#1#2%
- {\ifcase\frozenpagestate
- \global\advance\noftrackedpagestates\plusone
- \global\advance#2\plusone
- \lazysavetaggedtwopassdata{#1}{\number\noftrackedpagestates}{\number#2}{\noexpand\realfolio}%
- %\llap{\infofont\number\noftrackedpagestates/\number#2}% tracing
- \fi}
-
-\def\doifrightpagestateelse#1#2%
- {\ifcase\frozenpagestate
- \pagestatemismatchfalse
- \realpagestateno\realfolio
- \ifinpagebody
- \ifdoublesided
- \ifodd\realpageno\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \else
- \twopassdatafoundtrue
- \fi
- \else\ifdoublesided
- \findtwopassdata{#1}{\number#2}%
- \iftwopassdatafound
- \realpagestateno\twopassdata\relax
- \ifnum\twopassdata=\realpageno \else
- \pagestatemismatchtrue
- \fi
- \ifodd\twopassdata\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \else
- \ifodd\realpageno\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \fi
- \else
- \twopassdatafoundtrue
- \fi\fi
- \else
- \ifodd\realpagestateno\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \fi
- \iftwopassdatafound
- \@EA\firstoftwoarguments
- \else
- \@EA\secondoftwoarguments
- \fi}
-
-\def\doifforcedrightpagestateelse#1#2%
- {\ifcase\frozenpagestate
- \pagestatemismatchfalse
- \realpagestateno\realfolio
- \findtwopassdata{#1}{\number#2}%
- \iftwopassdatafound
- \realpagestateno\twopassdata\relax
- \ifnum\twopassdata=\realpageno \else
- \pagestatemismatchtrue
- \fi
- \ifodd\twopassdata\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \else
- \ifodd\realpageno\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \fi
- \else
- \ifodd\realpagestateno\relax
- \twopassdatafoundtrue \else \twopassdatafoundfalse
- \fi
- \fi
- \iftwopassdatafound
- \@EA\firstoftwoarguments
- \else
- \@EA\secondoftwoarguments
- \fi}
-
-\def\freezepagestate {\chardef\frozenpagestate\plusone }
-\def\defrostpagestate{\chardef\frozenpagestate\zerocount}
-
-% we can make more of these on top, but how to deal with mixed frozen states
-
-\definetwopasslist\s!paragraph \newcount \nofraggedparagraphs
-
-\def\signalrightpage {\dotrackpagestate \s!paragraph\nofraggedparagraphs}
-\def\doifrightpageelse{\doifrightpagestateelse\s!paragraph\nofraggedparagraphs}
-
-\newcount\pagesignallevel
-
-\def\startsignalrightpage % one may do a \postsignalrightplace
- {\advance\pagesignallevel\plusone
- \presignalrightpage
- \let\signalrightpage\relax
- \let\presignalrightpage\relax
- \let\startsignalrightpage\relax
- \doifrightpageelse\donothing\donothing
- \freezepagestate}
-
-\def\stopsignalrightpage
- {\ifcase\pagesignallevel\or\postsignalrightpage\fi
- \advance\pagesignallevel\minusone}
-
-\def\setraggedparagraphmode
- {\signalrightpage\doifrightpageelse} % move it there
-
-\ifx\swapmargins\undefined \let\swapmargins\undefined \fi % todo
-
-\def\doifswappedrightpageelse#1#2% alleen in box construction !
- {\doifrightpageelse
- {#1}
- {\scratchcounter\realpageno
- \realpageno\realpagestateno\relax
- \swapmargins
- \realpageno\scratchcounter
- #2}}
-
-\newbox\signaledrightpage % this way we can avoid interference, i.e. postpone placement
-
-\def\presignalrightpage {\global\setbox\signaledrightpage\hbox{\signalrightpage}}
-\def\postsignalrightpage{\ifvoid\signaledrightpage\else\box\signaledrightpage\fi}
-
-% The next feature is is used in:
-%
-% \definenumber[test][way=bypage]
-%
-% \def\Test
-% {\incrementnumber[test]\rawnumber[test]/%
-% \incrementnumber[test]\rawnumber[test]/%
-% \incrementnumber[test]\rawnumber[test]\space
-% \checkpagechange{oeps}\changedpage{oeps}\space
-% \ifpagechanged TRUE\else FALSE\fi}
-%
-% \Test\page \Test\par \Test\page \Test\par \Test\page \Test\page
-%
-% (adapted from cont-new.tex:)
-
-\newif\ifpagechanged \let\lastchangedpage\empty
-
-\def\docheckpagestatechange#1#2#3%
- {\pagechangedfalse
- \doforcedtrackpagestate{#2}{#3}%
- \findtwopassdata{#2}{\number#3}%
- \iftwopassdatafound
- \ifnum\twopassdata>0\getvalue{#2:p:#1}\relax
- \pagechangedtrue
- \fi
- \fi
- \ifpagechanged
- \letgvalue{#2:p:#1}\twopassdata
- \globallet\lastchangedpage\twopassdata
- \else
- \globallet\lastchangedpage\realfolio
- \fi}
-
-\def\changedpagestate#1#2%
- {\executeifdefined{#2:p:#1}{0}}
-
-\def\checkpagechange#1{\docheckpagestatechange{#1}\s!paragraph\nofraggedparagraphs}
-\def\changedpage #1{\changedpagestate{#1}\s!paragraph}
-
-% saved struts
-
-\ifx\savedstrutbox\undefined \newbox\savedstrutbox \fi
-
-\def\savestrut {\setbox\savedstrutbox\copy\strutbox}
-\def\savedstrut{\copy \savedstrutbox}
-
-% De onderstaande macro's zijn opgenomen in Plain TeX.
-%
-% \def\raggedright%
-% {\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax}
-%
-% \def\ttraggedright%
-% {\tttf\rightskip\z@ plus2em\relax}
-%
-% \newif\ifr@ggedbottom
-%
-% \def\raggedbottom%
-% {\topskip 10\p@ plus60\p@ \r@ggedbottomtrue}
-%
-% \def\normalbottom%
-% {\topskip 10\p@ \r@ggedbottomfalse}
-%
-% en worden hieronder wat aangepast.
-
-% the three boolean will become obsolete some day in favour
-% of \bottomraggedness
-
-\chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
-
-\def\bottomalignlimit{3\lineheight}
-
-\newif\ifn@rmalbottom
-\newif\ifr@ggedbottom
-\newif\ifb@selinebottom
-
-\def\normalbottom
- {% \topskip 10pt
- \r@ggedbottomfalse}
-
-\def\raggedbottom
- {\chardef\bottomraggedness\zerocount
- \n@rmalbottomfalse
- \r@ggedbottomtrue
- \b@selinebottomfalse
- \settopskip}
-
-\def\alignbottom
- {\chardef\bottomraggedness\plusone
- \n@rmalbottomtrue
- \r@ggedbottomfalse
- \b@selinebottomfalse
- \settopskip}
-
-\def\baselinebottom
- {\chardef\bottomraggedness\plustwo
- \n@rmalbottomfalse
- \r@ggedbottomfalse
- \b@selinebottomtrue
- \settopskip}
-
-\let\normalbottom=\alignbottom % downward compatible
-
-% so, the new one will be
-%
-% \chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline
-%
-% \def\bottomalignlimit{3\lineheight} % will be settable
-%
-% \def\raggedbottom {\chardef\bottomraggedness=0 \settopskip}
-% \def\alignbottom {\chardef\bottomraggedness=1 \settopskip}
-% \def\baselinebottom{\chardef\bottomraggedness=2 \settopskip}
-%
-% \let\normalbottom =\alignbottom
-
-% \hyphenpenalty = ( 2.5 * \hsize ) / \raggedness
-% \tolerance >= 1500 % was 200
-% \raggedness = 2 .. 6\bodyfontsize
-
-\chardef\raggedstatus=0 % normal left center right
-
-\def\leftraggedness {2\bodyfontsize}
-\def\rightraggedness {2\bodyfontsize}
-\def\middleraggedness {6\bodyfontsize}
-
-\def\middleraggedness {.5\hsize} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
-
-% oeps, hsize can be 0pt in which case we get a strange division
-
-\def\middleraggedness {\ifdim\hsize=\zeropoint6\bodyfontsize\else.5\hsize\fi} % was: 6\bodyfontsize, fails on: \placefigure{x $x=x$ x}{}
-
-%D More hyphenation control, will be combined with align
-%D setup.
-
-\def\nohyphens
- {\ifx\dohyphens\relax
- \edef\dohyphens
- {\hyphenpenalty\the\hyphenpenalty
- \exhyphenpenalty\the\exhyphenpenalty\relax}%
- \fi
- \hyphenpenalty\plustenthousand
- \exhyphenpenalty\plustenthousand}
-
-\let\dohyphens\relax
-
-%D To prevent unwanted side effects, we also have to check
-%D for hyphens here:
-
-% \def\setraggedness#1%
-% {\ifnum\tolerance<1500\relax % small values have
-% \tolerance1500\relax % unwanted side effects
-% \fi
-% \spaceskip2.5\hsize % we misuse these registers
-% \xspaceskip#1\relax % for temporary storage;
-% \divide\spaceskip \xspaceskip % they are changed anyway
-% \ifx\dohyphens\relax
-% \hyphenpenalty\spaceskip % \else no hyphens is active
-% \fi}
-
-\newskip\@@raggedskipa
-\newskip\@@raggedskipb
-
-\def\setraggedness#1%
- {\ifnum\tolerance<1500\relax % small values have
- \tolerance1500\relax % unwanted side effects
- \fi
- \ifx\dohyphens\relax
- % this code will be reconsidered / kind of fuzzy (and old)
- \@@raggedskipa 2.5\hsize
- \@@raggedskipb #1\relax
- \divide\@@raggedskipa \@@raggedskipb
- \hyphenpenalty\@@raggedskipa
- \fi}
-
-\let\updateraggedskips\relax
-
-\def\setraggedskips#1#2#3#4#5#6#7% never change this name
- {\def\updateraggedskips{\dosetraggedskips{#1}{#2}{#3}{#4}{#5}{#6}{#7}}%
- \updateraggedskips}
-
-\def\dosetraggedskips#1#2#3#4#5#6#7%
- {\chardef \raggedstatus#1\relax
- \leftskip 1\leftskip \!!plus#2\relax % zie: Tex By Topic 8.1.3
- \rightskip 1\rightskip\!!plus#3\relax % zie: Tex By Topic 8.1.3
- \spaceskip #4\relax
- \xspaceskip #5\relax
- \parfillskip\zeropoint\!!plus#6\relax
- \parindent #7\relax}
-
-% \def\notragged%
-% {\setraggedskips{0}{0em}{0em}{0em}{0em}{1fil}{\parindent}}
-
-% older (context) names:
-
-\let\spaceamount \interwordspace
-\let\emspaceamount\emwidth
-
-% tracing:
-
-\def\doshowpardata#1%
- {\ifx#1\relax\else
- \hbox{\string#1: \the#1}\endgraf
- \expandafter\doshowpardata
- \fi}
-
-\def\showpardata
- {\edef\thepardata
- {\hbox{font: \fontname\font}\endgraf
- \doshowpardata
- \interwordspace \interwordstretch \interwordshrink \emwidth \exheight \extraspace
- \hsize \vsize
- \leftskip \rightskip
- \spaceskip \xspaceskip
- \parindent \parfillskip
- \hyphenpenalty \exhyphenpenalty
- \displaywidowpenalty \widowpenalty \clubpenalty \brokenpenalty
- \doublehyphendemerits \finalhyphendemerits \adjdemerits
- \relax}%
- \begingroup
- \dontshowcomposition
- \inleftmargin{\vsmash
- {\switchtobodyfont[7pt,tt]%
- \framed[\c!align=\v!right]{\thepardata}}}%
- \endgroup}
-
-\def\startshowpardata
- {\begingroup
- \showcomposition
- \showstruts\tracepositionstrue \tracingparagraphs\maxdimen
- \appendtoksonce\showpardata\let\showpardata\relax\to\everypar}
-
-\def\stopshowpardata
- {\endgraf
- \endgroup}
-
-% \defineXMLenvironment[showpardata] \startshowpardata \stopshowpardata
-% \defineXMLsingular [showpardata] \showpardata
-
-% defaults
-
-\def\raggedfillamount {1fil}
-\def\raggedhalffillamount{.5fil}
-\def\raggedspaceamount {\interwordspace} % {.3333em}
-\def\raggedxspaceamount {.5em}
-
-\def\notragged
- {\chardef\raggedstatus\zerocount
- \leftskip 1\leftskip
- \rightskip 1\rightskip
- \spaceskip \zeropoint
- \xspaceskip \zeropoint
- \parfillskip\zeropoint\!!plus\raggedfillamount\relax
- \let\updateraggedskips\relax} % new
-
-\let\forgetragged\notragged
-
-\def\raggedleft
- {\setraggedness\leftraggedness
- \setraggedskips1\leftraggedness\zeropoint\raggedspaceamount
- \raggedxspaceamount\zeropoint\zeropoint}
-
-\def\raggedcenter
- {\setraggedness\middleraggedness
- \setraggedskips2\middleraggedness\middleraggedness\raggedspaceamount
- \raggedxspaceamount\zeropoint\zeropoint}
-
-%D We used to have:
-%D
-%D \starttyping
-%D \def\raggedright
-%D {\setraggedness\rightraggedness
-%D \setraggedskips{3}{0em}{\rightraggedness}{.3333em}{.5em}{0em}{\parindent}}
-%D \stoptyping
-%D
-%D However, the next alternative, suggested by Taco, is better.
-
-\def\raggedright
- {\setraggedness\rightraggedness
- \setraggedskips3\zeropoint\rightraggedness\raggedspaceamount
- \raggedxspaceamount\raggedfillamount\parindent}
-
-\def\veryraggedleft
- {\setraggedskips1\raggedfillamount\zeropoint\raggedspaceamount
- \raggedxspaceamount\zeropoint\zeropoint}
-
-%D When we want the last line to have a natural width:
-%D
-%D \starttyping
-%D \def\veryraggedleft%
-%D {\setraggedskips{1}{1fil}{0em}{.3333em}{.5em}{0em}{-1fil}}
-%D \stoptyping
-%D
-%D but this one is not accepted by the macros.
-
-\def\veryraggedcenter
- {\setraggedskips2\raggedfillamount\raggedfillamount\raggedspaceamount
- \raggedxspaceamount\zeropoint\zeropoint}
-
-\def\veryraggedright
- {\setraggedskips3\zeropoint\raggedfillamount\raggedspaceamount
- \raggedxspaceamount\zeropoint\parindent}
-
-\def\ttraggedright
- {\tttf
- \setraggedskips3\zeropoint\rightraggedness
- \zeropoint\zeropoint\zeropoint\parindent} % \ctxparindent
-
-%D A bonus one:
-
-\def\raggedwidecenter
- {\setraggedness\middleraggedness
- \setraggedskips2\raggedhalffillamount\raggedhalffillamount
- \raggedspaceamount\raggedxspaceamount\zeropoint\zeropoint}
-
-\newif\if@@asragged \@@asraggedtrue % old method
-
-% todo
-%
-% \setuplayout[grid=yes,lines=44] \showgrid
-% \starttext
-% test \vfill test \endgraf \strut \endgraf \vskip-\lineheight \removedepth \pagina test
-% \stoptext
-
-% \setupalign[reset,new,right,old]
-
-\def\@@align@@rl{\if!!donea\veryraggedleft \else\raggedleft \fi}
-\def\@@align@@rr{\if!!donea\veryraggedright \else\raggedright \fi}
-\def\@@align@@rc{\if!!donea\veryraggedcenter\else\raggedcenter\fi}
-
-\setvalue{@@ngila@@\v!broad }{\!!doneatrue}
-\setvalue{@@ngila@@\v!wide }{\!!donebtrue}
-
-\def\installalign#1#2{\setvalue{@@align@@#1}{#2}} % can be used for overloads
-
-\installalign \v!new {\@@asraggedfalse}
-\installalign \v!old {\@@asraggedtrue}
-\installalign \empty {}
-
-\installalign \v!line {\baselinebottom}
-\installalign \v!bottom {\raggedbottom}
-\installalign \v!height {\normalbottom}
-\installalign \v!width {\notragged}
-\installalign \v!normal {\notragged}
-\installalign \v!yes {\notragged}
-\installalign \v!no {\raggedright}
-\installalign \v!inner {\if@@asragged \setraggedparagraphmode\@@align@@rl\@@align@@rr \else
- \setraggedparagraphmode\@@align@@rr\@@align@@rl \fi}
-\installalign \v!outer {\if@@asragged \setraggedparagraphmode\@@align@@rr\@@align@@rl \else
- \setraggedparagraphmode\@@align@@rl\@@align@@rr \fi}
-\installalign \v!left {\if@@asragged\@@align@@rl\else\@@align@@rr\fi}
-\installalign \v!right {\if@@asragged\@@align@@rr\else\@@align@@rl\fi}
-\installalign \v!middle {\if!!doneb\raggedwidecenter\else\@@align@@rc\fi}
-\installalign \v!flushleft {\if!!donea\veryraggedright \else\raggedright\fi}
-\installalign \v!flushright {\if!!donea\veryraggedleft \else\raggedleft \fi}
-\installalign \v!flushouter {\setraggedparagraphmode\raggedleft\raggedright}
-\installalign \v!flushinner {\setraggedparagraphmode\raggedright\raggedleft}
-\installalign \v!center {\if!!doneb\raggedwidecenter\else\@@align@@rc\fi}
-\installalign \v!hanging {\enableprotruding}
-\installalign \v!nothanging {\disableprotruding}
-\installalign \v!hz {\enableadjusting}
-\installalign \v!nohz {\disableadjusting}
-\installalign \v!spacing {\enablespacehandling \enablekernhandling}
-\installalign \v!nospacing {\disablespacehandling\disablekernhandling}
-\installalign \v!hyphenated {\dohyphens}
-\installalign \v!nothyphenated {\nohyphens}
-\installalign \v!new {\@@asraggedfalse} % so new will give you consistency
-\installalign \v!reset {\notragged\normalbottom}
-
-\installalign \v!tolerant {\tolerance3000 \relax}
-\installalign \v!verytolerant {\tolerance4500 \relax}
-\installalign \v!stretch {\emergencystretch\bodyfontsize}
-
-\installalign \v!grid {\mkenablegridsnapping } % only mkiv
-\installalign \v!nogrid {\mkdisablegridsnapping} % only mkiv
-
-\newcount\hyphenminoffset
-
-\ifx\sethyphenationvariables\undefined \let\sethyphenationvariables\relax \fi
-
-\def\lesshyphens
- {\advance\hyphenminoffset\plusone
- \sethyphenationvariables}
-
-\def\morehyphens
- {\ifcase\hyphenminoffset \else
- \advance\hyphenminoffset\minusone
- \fi
- \sethyphenationvariables}
-
-\installalign \v!lesshyphenation {\lesshyphens}
-\installalign \v!morehyphenation {\morehyphens}
-
-\def\dodosetupalign#1{\csname @@align@@#1\endcsname}
-\def\dodosetupngila#1{\csname @@ngila@@#1\endcsname}
-
-\def\setupalign
- {\dosingleargument\dosetupalign}
-
-\def\dosetupalign[#1]% can be made faster by checking for defined #1
- {\!!doneafalse
- \!!donebfalse
- \processcommacommand[#1]\dodosetupngila
- \processcommacommand[#1]\dodosetupalign}
-
-% \setupalign[flushleft] \input ward \par % lijnlinks
-% \setupalign[right] \input ward \par
-
-% \setupalign[flushright] \input ward \par % lijnrechts
-% \setupalign[left] \input ward \par
-
-% \setupalign[middle] \input ward \par % centreer
-% \setupalign[center] \input ward \par
-
-\def\startalignment
- {\bgroup
- \setupalign}
-
-\def\stopalignment
- {\par
- \egroup}
-
-\chardef\alignstrutmode=1
-
-% see later for the real definition, which in the simple case is:
-
-\newtoks \everyleftofalignedline
-\newtoks \everyrightofalignedline
-
-\def\shiftalignedline#1#2#3#4% left, right, inner, outer
- {\rightorleftpageaction
- {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
- \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
- {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
- \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}
-
-% \def\doalignline#1#2% \\ == newline
-% {\begingroup
-% \setlocalhsize % new
-% \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
-% \dowithnextbox
-% {\noindentation % was \noindent
-% \dontleavehmode % added in marrakesch at TUG 2006
-% \hbox to \localhsize
-% {\ifcase\alignstrutmode\or\strut\fi
-% \the\everyleftofalignedline
-% #1\unhbox\nextbox#2\relax
-% \the\everyrightofalignedline}%
-% \endgroup}
-% \hbox}
-
-\def\doalignline#1#2% \\ == newline
- {\noindentation % was \noindent
- \dontleavehmode % added in marrakesch at TUG 2006\begingroup
- \begingroup
- \setlocalhsize % new
- \def\\{\egroup\par\doalignline{#1}{#2}\bgroup}%
- \dowithnextbox
- {\hbox to \localhsize
- {\ifcase\alignstrutmode\or\strut\fi
- \the\everyleftofalignedline
- #1\unhbox\nextbox#2\relax
- \the\everyrightofalignedline}%
- \endgroup}
- \hbox}
-
-% directe commando's
-
-\def\leftaligned {\doalignline \relax \hss }
-\def\midaligned {\doalignline \hss \hss }
-\def\rightaligned{\doalignline \hss \relax}
-
-\def\regelbegrensd#1{\limitatetext{#1}{\hsize}{\unknown}} % to be translated
-
-% indirecte commando's
-
-\letvalue{\s!do\v!line\v!left }\leftaligned
-\letvalue{\s!do\v!line\v!right }\rightaligned
-\letvalue{\s!do\v!line\v!middle }\midaligned
-\letvalue{\s!do\v!line\v!flushleft }\rightaligned
-\letvalue{\s!do\v!line\v!flushright}\leftaligned
-\letvalue{\s!do\v!line\v!center }\midaligned
-
-\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}
-
-%D Experimental:
-
-% simple version
-%
-% \def\doxalignline#1#2%
-% {\bgroup
-% \setlocalhsize
-% \def\\{\egroup\par\doxalignline{#1}{#2}\bgroup}% inefficient
-% \dowithnextbox
-% {\noindent\hbox to \localhsize
-% {\ifcase\alignstrutmode\or\strut\fi
-% \signalrightpage
-% \doifrightpageelse{#1\unhbox\nextbox#2}{#2\unhbox\nextbox#1}}%
-% \egroup}
-% \hbox}
-%
-% \setvalue{\s!do\v!regel\v!binnen}{\doxalignline\relax\hss}
-% \setvalue{\s!do\v!regel\v!buiten}{\doxalignline\hss\relax}
-%
-% more extensive:
-
-\def\doxalignline#1#2#3#4#5#6%
- {\noindentation % was \noindent
- \dontleavehmode % added in marrakesch at TUG 2006\begingroup
- \begingroup
- \setlocalhsize
- \def\\{\egroup\par\doxalignline#1#2#3#4#5#6\bgroup}% inefficient
- \dowithnextbox
- {%\noindent moved up
- \hbox to \localhsize
- {#1\hskip\ifdone#2\else#3\fi#4%
- \hbox to \localhsize
- {\the\everyleftofalignedline
- \ifcase\alignstrutmode\or\strut\fi
- \ifdone#5\unhbox\nextbox#6\else#6\unhbox\nextbox#5\fi
- \the\everyrightofalignedline}%
- \hss}%
- \endgroup}
- \hbox}
-
-\def\doxcheckline
- {\signalrightpage\doifrightpageelse\donetrue\donefalse}
-
-\setvalue{\s!do\v!line\v!inner }{\doxalignline\doxcheckline++\zeropoint \relax\hss }
-\setvalue{\s!do\v!line\v!outer }{\doxalignline\doxcheckline++\zeropoint \hss \relax}
-\setvalue{\s!do\v!line\v!innermargin}{\doxalignline\doxcheckline-+\innermargintotal\relax\hss }
-\setvalue{\s!do\v!line\v!outermargin}{\doxalignline\doxcheckline+-\outermargintotal\hss \relax}
-\setvalue{\s!do\v!line\v!inneredge }{\doxalignline\doxcheckline-+\inneredgetotal \relax\hss }
-\setvalue{\s!do\v!line\v!outeredge }{\doxalignline\doxcheckline+-\outeredgetotal \hss \relax}
-\setvalue{\s!do\v!line\v!backspace }{\doxalignline\doxcheckline-+\backspace \relax\hss }
-\setvalue{\s!do\v!line\v!cutspace }{\doxalignline\doxcheckline+-\cutspace \hss \relax}
-
-\setvalue{\s!do\v!line\v!leftmargin }{\doxalignline\donefalse --\leftmargintotal \hss \relax}
-\setvalue{\s!do\v!line\v!rightmargin}{\doxalignline\donefalse ++\rightmargintotal\relax\hss }
-\setvalue{\s!do\v!line\v!leftedge }{\doxalignline\donefalse --\leftedgetotal \hss \relax}
-\setvalue{\s!do\v!line\v!rightedge }{\doxalignline\donefalse ++\rightedgetotal \relax\hss }
-
-% ! ! ! beware, redefining \doalignline gives the wrong results ! ! !
-%
-% \def\doalignline{\doxalignline\donefalse++\zeropoint}
-
-%D Better:
-
-\def\doalignedline#1{\csname\s!do\v!line#1\endcsname}
-
-% \def\alignedline#1#2% setting default
-% {\csname
-% \s!do\v!line
-% \ifundefined{\s!do\v!line#1}#2\else#1\fi
-% \endcsname}
-
-\def\alignedline#1#2% setting default
- {\csname\s!do\v!line\ifcsname\s!do\v!line#1\endcsname#1\else#2\fi\endcsname}
-
-%D ...
-
-\def\dosetuptolerance[#1]%
- {\doifinsetelse\v!vertical{#1}%
- {\ExpandFirstAfter\processallactionsinset
- [#1]
- [ \v!verystrict=>\def\bottomtolerance{},
- \v!strict=>\def\bottomtolerance{.050},
- \v!tolerant=>\def\bottomtolerance{.075},
- \v!verytolerant=>\def\bottomtolerance{.100}]}%
- {\ExpandFirstAfter\processallactionsinset
- [#1]
- [ \v!stretch=>\emergencystretch\bodyfontsize,
- \v!space=>\spaceskip.5em\!!plus.25em\!!minus.25em\relax,
- \v!verystrict=>\tolerance 200,
- \v!strict=>\tolerance1500,
- \v!tolerant=>\tolerance3000,
- \v!verytolerant=>\tolerance4500]}}
-
-\def\setuptolerance
- {\dosingleargument\dosetuptolerance}
-
-% \def\woordrechts
-% {\groupedcommand{\hfill\hbox}{\parfillskip\zeropoint}}
-
-% beware: \wordright{whatever\kern-\rightskip} should work!
-% so, no funny boxing here
-
-\def\dowordright[#1]%
- {% don't change
- \groupedcommand
- {\removeunwantedspaces
- \hfill
- \allowbreak % changed back from \hskip\zeropoint
- \strut
- \hfill
- \quad % decent spacing
- \hbox}
- {\doifelse{#1}\v!right{\kern-\rightskip}{\doifsomething{#1}{\kern-#1}}%
- \parfillskip\zeropoint
- %\finalhyphendemerits\zerocount % yes or no
- \par}}
-
-\def\wordright
- {\dosingleempty\dowordright}
-
-% \dorecurse{5}{something } \wordright{--someone} \endgraf
-% \dorecurse{6}{something } \wordright{--someone} \endgraf
-% \dorecurse{7}{something } \wordright{--someone} \endgraf
-%
-% \dorecurse{5}{something } \wordright{--someone else entirely} \endgraf
-% \dorecurse{6}{something } \wordright{--someone else entirely} \endgraf
-% \dorecurse{7}{something } \wordright{--someone else entirely} \endgraf
-%
-% \wordright[\rightskip]{whatever}
-
-% \simplealignedbox{2cm}{right}{x}
-
-\setvalue{\s!simple\c!align\v!right }#1#2{\hbox to #1{#2\hss}}
-\setvalue{\s!simple\c!align\v!left }#1#2{\hbox to #1{\hss#2}}
-\setvalue{\s!simple\c!align\v!flushright }#1#2{\hbox to #1{\hss#2}}
-\setvalue{\s!simple\c!align\v!flushleft }#1#2{\hbox to #1{#2\hss}}
-\setvalue{\s!simple\c!align\v!middle }#1#2{\hbox to #1{\hss#2\hss}}
-
-\def\simplealignedbox#1{\executeifdefined{\s!simple\c!align#1}{\getvalue{\s!simple\c!align\v!right}}}
-
-%D \macros
-%D {pushindentation,popindentation}
-%D
-%D The pushing and popping is done by:
-
-\newbox\indentationboxA
-\newbox\indentationboxB
-
-\def\pushindentation
- {\bgroup
- \ifhmode
- \unskip
- \setbox\indentationboxA\lastbox % get \strut if present
- \unskip
- \setbox\indentationboxB\lastbox % get \indent generated box
- \unskip
- \else
- \hskip\zeropoint % switch to horizontal mode
- \unskip
- \setbox\indentationboxA\lastbox % get \indent generated box
- \setbox\indentationboxB\box\voidb@x
- \fi}
-
-\def\popindentation
- {\box\indentationboxB\box\indentationboxA % put back the boxes
- \egroup}
-
-%D The only complication lays in \type{\strut}. In \PLAIN\
-%D \TEX\ a \type{\strut} is defined as:
-%D
-%D \starttyping
-%D \def\strut%
-%D {\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
-%D \stoptyping
-%D
-%D But what is a \type{\strut}? Normally it's a rule of width
-%D zero, but when made visual, it's a rule and a negative skip.
-%D The mechanism for putting things in the margins described
-%D here cannot handle this situation very well. One
-%D characteristic of \type{\strut} is that the \type{\unhcopy}
-%D results in entering horizontal mode, which in return leads
-%D to some indentation.
-%D
-%D To serve our purpose a bit better, the macro \type{\strut}
-%D can be redefined as:
-%D
-%D \starttyping
-%D \def\strut
-%D {\relax\ifmmode\else\hskip0pt\fi\copy\strutbox}
-%D \stoptyping
-%D
-%D Or more compatible:
-%D
-%D \starttyping
-%D \def\strut
-%D {\relax\ifmmode
-%D \copy\strutbox
-%D \else
-%D \bgroup\setbox\strutbox=\normalhbox{\box\strutbox}\unhcopy\strutbox\egroup
-%D \fi}
-%D \stoptyping
-%D
-%D In \CONTEXT\ however we save some processing time by putting
-%D an extra \type{\hbox} around the \type{\strutbox}.
-
-% moved from page-lin.tex to here (due to visualization added
-% in august 2003)
-%
-% \unexpanded \def\crlf
-% {\ifhmode\unskip\else\strut\fi\ifcase\raggedstatus\hfil\fi\break}
-
-\unexpanded \def\crlf
- {\ifhmode
- \unskip
- \prewordbreak\crlfplaceholder
- \ifcase\raggedstatus\hfil\or\or\or\hfil\fi
- \break
- \else
- \crlfplaceholder
- \endgraf
- \fi}
-
-\def\crlfplaceholder
- {\strut}
-
-\def\settestcrlf
- {\def\crlfplaceholder
- {\hbox to \zeropoint
- {\strut{\infofont\kern.25em}\lohi{\infofont CR}{\infofont LF}\hss}}}
-
-%D \starttyping
-%D % \setuplayout[gridgrid=yes] \showgrid
-%D
-%D \startbuffer
-%D test 1\crlf
-%D test 2\crlf
-%D
-%D \crlf test 3
-%D
-%D test 4\crlf
-%D test 5
-%D
-%D \crlf
-%D \crlf
-%D \crlf
-%D test 6
-%D \stopbuffer
-%D
-%D \hbox
-%D {\hsize5em
-%D \ruledvtop{\getbuffer}\enspace
-%D \ruledvtop{\showstruts\getbuffer}\enspace
-%D \hsize15em \setuptyping[before=,after=]%
-%D \ruledvtop{\typebuffer}}
-%D \stoptyping
-
-\def\opeenregel % to be used grouped
- {\def\crlf{\removelastspace\space}\let\\\crlf}
-
-\def\showstruts
- {\setteststrut
- \settestcrlf}
-
-\def\definehspace
- {\dotripleempty\dodefinehspace}
-
-\def\dodefinehspace[#1][#2][#3]% #1 = optional namespace
- {\ifthirdargument
- \setvalue{\??hs#1:#2}{#3}%
- \else
- \setvalue{\??hs:#1}{#2}%
- \fi}
-
-\unexpanded\def\hspace
- {\dodoubleempty\dohspace}
-
-%\def\dohspace[#1][#2]%
-% {\ifhmode
-% \removeunwantedspaces
-% \hskip
-% \ifsecondargument
-% \hspaceamount{#1}{#2}%
-% \else
-% \hspaceamount\empty{\iffirstargument#1\else\s!default\fi}%
-% \fi
-% \expandafter\ignorespaces
-% \fi}
-
-\def\dohspace[#1][#2]%
- {\ifsecondargument
- \dodohspace[#1][#2]%
- \else\iffirstargument
- \hspace[][#1]%
- \else
- \hspace[][\s!default]%
- \fi\fi}
-
-% \def\dodohspace[#1][#2#3]%
-% {\ifhmode
-% \removeunwantedspaces
-% \doifelse{#2}{-}
-% {{\scratchskip\hspaceamount{#1}{#3}\hskip-\scratchskip}}
-% {\hskip\hspaceamount{#1}{#2#3}}%
-% \expandafter\ignorespaces
-% \fi}
-%
-% not needed, tex handles -- as +
-
-\def\dodohspace[#1][#2]%
- {\ifhmode
- \removeunwantedspaces
- \hskip\hspaceamount{#1}{#2}%
- \expandafter\ignorespaces
- \fi}
-
-\def\hspaceamount#1#2%
- {\executeifdefined{\??hs#1:#2}{\executeifdefined{\??hs:#2}\zeropoint}}
-
-\definehspace [\v!small] [.25\emspaceamount]
-\definehspace [\v!medium] [.5\emspaceamount]
-\definehspace [\v!big] [1\emspaceamount]
-\definehspace [\v!normal] [1\spaceamount]
-\definehspace [\v!default] [\spaceamount]
-
-%D Taken from Taco's math module (cq. \AMS\ macros), but
-%D adapted to \type {\hspace}:
-
-\unexpanded\def\textormathspace#1#2#3%
- {\ifmmode\mskip#1#2\else\kern#1\hspaceamount\empty{#3}\fi\relax}
-
-\newmuskip\hairmuskip \hairmuskip=.15mu
-
-\def\hairspace {\textormathspace+\hairmuskip{.5}}
-\def\thinspace {\textormathspace+\thinmuskip 1}
-\def\medspace {\textormathspace+\medmuskip 2}
-\def\thickspace {\textormathspace+\thickmuskip3}
-\def\neghairspace {\textormathspace-\thinmuskip{.5}}
-\def\negthinspace {\textormathspace-\thinmuskip 1}
-\def\negmedspace {\textormathspace-\medmuskip 2}
-\def\negthickspace{\textormathspace-\thickmuskip3}
-
-% needed for unicode:
-
-\def\twoperemspace {\hskip\dimexpr\emwidth/2\relax} % == \enspace
-\def\threeperemspace {\hskip\dimexpr\emwidth/3\relax}
-\def\fourperemspace {\hskip\dimexpr\emwidth/4\relax}
-\def\fiveperemspace {\hskip\dimexpr\emwidth/5\relax} % goodie
-\def\sixperemspace {\hskip\dimexpr\emwidth/6\relax}
-\def\figurespace {\begingroup\setbox\scratchbox\hbox{0}\hskip\wd\scratchbox\endgroup} % there is a command for this
-\def\punctuationspace {\begingroup\setbox\scratchbox\hbox{.}\hskip\wd\scratchbox\endgroup}
-\def\ideographicspace {\hskip\dimexpr\emwidth/1\relax}
-\def\ideographichalffillspace{\hskip\dimexpr\emwidth/2\relax}
-\def\nobreakspace {\penalty\plustenthousand\space}
-\def\narrownobreakspace {\penalty\plustenthousand\thinspace}
-\def\zerowidthnobreakspace {\penalty\plustenthousand\hskip\zeropoint}
-\def\zerowidthspace {\hskip\zeropoint}
-
-\definehspace[.5][.1250\emspaceamount] % could also be [.1250\spaceamount]
-\definehspace[1] [.1667\emspaceamount]
-\definehspace[2] [.2222\emspaceamount]
-\definehspace[3] [.2777\emspaceamount]
-
-\let \, \thinspace
-\let \: \medspace
-\let \; \thickspace
-\let \! \negthinspace
-
-% this will become an alternative bunch of \blank settings
-%
-% \startlines
-% \scratchskip=.23pt plus 10pt minus 4pt \relax \number\scratchskip \space \the\scratchskip
-% \setsimplifiedskip\scratchskip1 \number\scratchskip \space \the\scratchskip
-% \setsimplifiedskip\scratchskip2 \number\scratchskip \space \the\scratchskip
-% \getsimplifiedskip\scratchskip\scratchcounter \number\scratchcounter
-% \stoplines
-%
-% \hrule width10cm \endgraf
-% \discardedskip{10pt}
-% \retainedskip {4pt}
-% \discardedskip {5pt}
-% \hrule width10cm \endgraf
-% \blockedskip{0pt}
-% \discardedskip{10pt}
-% \retainedskip {4pt}
-% \discardedskip {5pt}
-% \hrule width10cm \endgraf
-% \frozenskip {4cm}
-% \hrule width10cm \endgraf
-% \vskip10pt
-% \hrule width10cm \endgraf
-
-% ! ! ! etex only, evt splitskip macro gebruiken (syst-new)
-
-\newskip\simplifiedskip
-\newskip\simplifiedcounter
-
-\chardef\@@discardedskip1
-\chardef\@@retainedskip 2
-\chardef\@@forcedskip 3
-\chardef\@@blockedskip 4
-\chardef\@@frozenskip 5 % after heads, no break
-
-\def\setsimplifiedskip#1#2%
- {#1\dimexpr(10\dimexpr(#1/10)) plus \gluestretch#1 minus \glueshrink#1\relax
- \advance#1\numexpr(#2)sp\relax}
-
-\def\getsimplifiedskip#1#2%
- {\simplifiedskip#1\relax
- \ifzeropt\simplifiedskip % \ifdim\simplifiedskip=\zeropoint
- #2\zerocount
- \else
- \simplifiedcounter\dimexpr10\dimexpr#1/10\relax\relax
- \advance\simplifiedskip-\simplifiedcounter
- #2\number\simplifiedskip\relax
- \fi}
-
-\def\conditionalskip#1#2%
- {\scratchskip#1\relax
- \setsimplifiedskip\scratchskip#2\relax
- \vskip\scratchskip\relax}
-
-\def\defrostskip
- {\scratchskip\lastskip\penalty50000\normalvskip-\scratchskip\penalty50000\relax}
-
-\def\frozenskip#1%
- {\endgraf
- \ifvmode
- \getsimplifiedskip\lastskip\scratchcounter
- \ifdim\lastskip>#1\else
- \defrostskip
- \conditionalskip{#1}\@@frozenskip
- \fi
- \fi}
-
-\def\discardedskip#1%
- {\endgraf
- \ifvmode
- \getsimplifiedskip\lastskip\scratchcounter
- \ifcase\scratchcounter
- \conditionalskip{#1}\@@discardedskip
- \or % discard
- \ifdim\lastskip>#1\else
- \normalvskip-\lastskip
- \conditionalskip{#1}\@@discardedskip
- \fi
- \or % retain
- \ifdim\lastskip>#1\else
- \normalvskip-\lastskip
- \conditionalskip{#1}\@@discardedskip
- \fi
- \or % forced
- \conditionalskip{#1}\@@discardedskip
- \or % ignored
- \or % frozen
- \ifdim\lastskip>#1\else
- \defrostskip
- \conditionalskip{#1}\@@frozenskip
- \fi
- \else\ifdim#1=\zeropoint\else
- \vskip#1\relax
- \fi\fi
- \fi}
-
-\def\retainedskip#1%
- {\endgraf
- \ifvmode
- \getsimplifiedskip\lastskip\scratchcounter
- \ifcase\scratchcounter
- \conditionalskip{#1}\@@retainedskip
- \or % discard
- \normalvskip-\lastskip
- \conditionalskip{#1}\@@retainedskip
- \or % retain
- \ifdim\lastskip>#1\else
- \normalvskip-\lastskip
- \conditionalskip{#1}\@@retainedskip
- \fi
- \or % forced
- \conditionalskip{#1}\@@retainedskip
- \or % ignored
- \or % frozen
- \ifdim\lastskip>#1\else
- \defrostskip
- \conditionalskip{#1}\@@frozenskip
- \fi
- \else\ifdim#1=\zeropoint\else
- \vskip#1\relax
- \fi\fi
- \fi}
-
-\def\forcedskip#1%
- {\endgraf
- \ifvmode
- \conditionalskip{#1}\@@forcedskip
- \fi}
-
-\def\blockedskip#1%
- {\endgraf
- \ifvmode
- \getsimplifiedskip\lastskip\scratchcounter
- \ifcase\scratchcounter
- \conditionalskip{#1}\@@blockedskip
- \or % discard
- \conditionalskip{#1}\@@blockedskip
- \or % retain
- \conditionalskip{#1}\@@blockedskip
- \or % forced
- \conditionalskip{#1}\@@blockedskip
- \or % ignored
- \or % frozen
- \ifdim\lastskip>#1\else
- \defrostskip
- \conditionalskip{#1}\@@frozenskip
- \fi
- \else\ifdim#1=\zeropoint\else
- \vskip#1\relax
- \fi\fi
- \fi}
-
-% beware, changing this will break some code (like pos/backgrounds)
-
-\newtoks\everyfirstparagraphintro
-\newtoks\everynextparagraphintro
-\newtoks\@@everyparagraphtoks
-
-\chardef\everyparagraphintro\zerocount
-
-\def\setupparagraphintro
- {\dodoubleempty\dosetupparagraphintro}
-
-\def\dosetupparagraphintro[#1][#2]%
- {\processallactionsinset
- [#1]
- [ \v!reset=>\global\chardef\everyparagraphintro\zerocount
- \global\everyfirstparagraphintro\emptytoks
- \global\everynextparagraphintro \emptytoks,
- \v!first=>\global\chardef\everyparagraphintro\plusone
- \doglobal\appendtoks#2\to\everyfirstparagraphintro,
- \v!next=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plusone\fi
- \doglobal\appendtoks#2\to\everynextparagraphintro,
- \v!each=>\ifcase\everyparagraphintro\global\chardef\everyparagraphintro\plustwo\fi
- \doglobal\appendtoks#2\to\everyfirstparagraphintro
- \doglobal\appendtoks#2\to\everynextparagraphintro]}
-
-%D We can say:
-%D
-%D \starttyping
-%D \setupparagraphintro[first][\index{Knuth}]
-%D \stoptyping
-%D
-%D Maybe more convenient is:
-%D
-%D \starttyping
-%D \flushatparagraph{\index{Zapf}}
-%D \stoptyping
-
-\def\flushatparagraph#1%
- {\global\chardef\everyparagraphintro\plusone
- \global\appendtoks{#1}\to\everyfirstparagraphintro}
-
-% \def\doinsertparagraphintro
-% {\ifcase\everyparagraphintro\relax
-% % no data
-% \@@everyparagraphtoks\emptytoks
-% \or
-% % first data
-% \global\chardef\everyparagraphintro\plustwo
-% \@@everyparagraphtoks\everyfirstparagraphintro
-% \global\everyfirstparagraphintro\emptytoks
-% \or
-% % next data
-% \@@everyparagraphtoks\everynextparagraphintro
-% \fi
-% \the\@@everyparagraphtoks}
-
-\def\doinsertparagraphintro
- {\begingroup
- \everypar\emptytoks
- \ifcase\everyparagraphintro\relax
- % no data
- \@@everyparagraphtoks\emptytoks
- \or
- % first data
- \global\chardef\everyparagraphintro\plustwo
- \@@everyparagraphtoks\everyfirstparagraphintro
- \global\everyfirstparagraphintro\emptytoks
- \or
- % next data
- \@@everyparagraphtoks\everynextparagraphintro
- \fi
- \the\@@everyparagraphtoks
- \endgroup}
-
-\def\insertparagraphintro
- {\ifcase\everyparagraphintro\else\@EA\doinsertparagraphintro\fi}
-
-% \appendtoksonce\insertparagraphintro\to\everypar % should come last
-
-%D \starttyping
-%D \setupparagraphintro[first][\hbox to 3.5em{\tt FIRST \hss}]
-%D \setupparagraphintro[first][\hbox to 3.5em{\tt TSRIF \hss}]
-%D \setupparagraphintro[next] [\hbox to 3.5em{\tt NEXT \hss}]
-%D \setupparagraphintro[next] [\hbox to 3.5em{\tt TXEN \hss}]
-%D \setupparagraphintro[each] [\hbox to 3.0em{\tt EACH \hss}]
-%D \setupparagraphintro[each] [\hbox to 3.0em{\tt HCEA \hss}]
-%D
-%D some paragraph \par
-%D some paragraph \par
-%D some paragraph \par
-%D
-%D \definelabel[parnumber]
-%D
-%D \setupparagraphintro[reset,each][\inleft{\slxx\parnumber}]
-%D
-%D some paragraph \par
-%D some paragraph \par
-%D some paragraph \par
-%D \stoptyping
-
-%D \macros
-%D {flushatnextpar}
-%D
-%D This macro collects data that will be flushed at the next paragraph.
-%D By using this macro you can avoid interfering nodes (writes, etc).
-
-\newbox \postponednodedata
-
-\def\flushatnextpar
- {\bgroup
- \dowithnextbox
- {\global\setbox\postponednodedata\hbox{\box\postponednodedata\box\nextbox}\egroup}%
- \hbox}
-
-\def\flushpostponednodedata
- {\ifvoid\postponednodedata\else
- \hbox{\smashedbox\postponednodedata}%
- \fi}
-
-% Very nasty but needed for margin stuff inside colored
-% paragraphs.
-
-\let\normalvadjust\vadjust
-
-% \def\graphicvadjust % bad, those low level color calls here
-% {\dowithnextbox
-% {\normalvadjust
-% {\dostartgraphicgroup
-% \localstarttextcolor
-% \unvbox\nextbox
-% \localstoptextcolor
-% \dostopgraphicgroup}}%
-% \vbox}
-
-% test this prikkels/pascal margin text before heads (mode
-% 1) as well as uitwerkingen (mode 2)
-
-%chardef\graphicvadjustmode=0 % fake
-%chardef\graphicvadjustmode=1 % normal
-\chardef\graphicvadjustmode=2 % normal + compensate (== default)
-
-\def\graphicvadjust % bad, those low level color calls here
- {\dowithnextboxcontent
- {\forgetall}
- {\ifcase\graphicvadjustmode \@EA \fakedvadjust \else \@EA\normalvadjust \fi
- {\dostartgraphicgroup % don't ask
- \localstarttextcolor
- \unvbox\nextbox
- \localstoptextcolor % don't ask
- \dostopgraphicgroup
- \ifcase\graphicvadjustmode \or \or
- % corrects for one line paragraphs
- \nointerlineskip
- \kern-\struttotal
- \nointerlineskip
- \verticalstrut
- \fi}}%
- \vbox}
-
-%D This works only in a properly strutted line, and is meant
-%D for deeply burried operations, like in heads.
-
-\def\fakedvadjust
- {\dowithnextbox
- {\setbox\nextbox\hbox{\llap{\lower\strutdepth\box\nextbox}}%
- \smashedbox\nextbox}%
- \vtop}
-
-\def\flexiblespaceamount#1#2#3%
- {#1\interwordspace
- \!!plus#2\interwordstretch
- \!!minus#3\interwordshrink}
-
-\def\fixedspaceamount#1%
- {#1\interwordspace}
-
-%D This is a dangerous feature because it makes the \TEX\ source
-%D less portable, i.e. any parser now needs to apply exactly the
-%D same algorithm when it wants to interpret the source. We
-%D strongly recommend not to mention this feature in manuals! It's
-%D provided for users who are hooked to such a mechanism.
-%D
-%D \starttyping
-%D \setupsorting[logo][next=\autoinsertnextspace] \logo[TEX]{\TeX}
-%D
-%D bla bla \TEX bla bla \TEX (bla) bla (\TEX)
-%D \stoptyping
-
-\def\autoinsertnextspace{\futurelet\nexttoken\doautoinsertnextspace}
-
-\def\doautoinsertnextspace % slightly extended version of a user supplied macro
- {\ifx\nexttoken \bgroup\else \ifx\nexttoken\begingroup\else
- \ifx\nexttoken \egroup\else \ifx\nexttoken \endgroup\else
- \ifx\nexttoken \/\else \ifx\nexttoken /\else \ifx\nexttoken ~\else
- \ifx\nexttoken \ \else \ifx\nexttoken \blankspace\else \ifx\nexttoken \space\else
- \ifx\nexttoken .\else \ifx\nexttoken ,\else
- \ifx\nexttoken !\else \ifx\nexttoken ?\else
- \ifx\nexttoken :\else \ifx\nexttoken ;\else
- \ifx\nexttoken '\else \ifx\nexttoken "\else
- \ifx\nexttoken )\else \ifx\nexttoken -\else \ifx\nexttoken |\else
- \ifx\nexttoken \%\else \ifx\nexttoken \&\else
- \space
- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
-
-% moved from page-lin
-
-\def\installspacehandler#1#2% needs to set \obeyedspace
- {\setvalue{\??sr#1}{#2}}
-
-\installspacehandler \v!on
- {\obeyspaces
- \def\obeyedspace{\mathortext\normalspace{\dontleavehmode{\tt\controlspace}}}%
- \let\ =\obeyedspace}
-
-\installspacehandler \v!yes
- {\obeyspaces
- \def\obeyedspace{\mathortext\normalspace{\dontleavehmode \normalspace }}%
- \let\ =\obeyedspace}
-
-\installspacehandler \v!off
- {\normalspaces
- \let\obeyedspace\normalspace
- \let\ =\normalspace}
-
-\installspacehandler \v!fixed
- {\obeyspaces
- \def\obeyedspace{\mathortext\normalspace{\dontleavehmode\fixedspace}}%
- \let\ =\obeyedspace}
-
-\def\activatespacehandler#1%
- {\executeifdefined{\??sr#1}{\activatespacehandler\v!off}}
-
-% moved from page-lin
-
-%D When spacing is active we need to handle commands in
-%D a special way:
-%D
-%D \starttyping
-%D \setuplines[space=on]
-%D
-%D \startlines
-%D Let's talk about this{\ttsl\gobbleoneargument or}that.
-%D \stoplines
-%D
-%D \startlines
-%D Let's talk about this{\getvalue{ttsl}or}that.
-%D \stoplines
-%D \stoptyping
-%D
-%D One can indent in several ways:
-%D
-%D \starttyping
-%D \setupindenting[medium] \setuplines[indenting=odd] % no yes odd even
-%D
-%D \startlines
-%D first
-%D second
-%D third
-%D fourth
-%D \stoplines
-%D \stoptyping
-
-\def\setuplines
- {\dodoubleargument\getparameters[\??rg]}
-
-\def\startlines
- {\@@rgbefore
- \pushmacro\checkindentation
- \whitespace
- %\page[\v!preference]} gaat mis na koppen, nieuw: later \nobreak
- \begingroup
- \setupindenting[\@@rgindenting]%
- \typesettinglinestrue
- \setupwhitespace[\v!none]%
- \obeylines
- \ignorespaces
- \gdef\afterfirstobeyedline % tzt two pass, net als opsomming
- {\gdef\afterfirstobeyedline
- {\nobreak
- \global\let\afterfirstobeyedline\relax}}%
- \def\obeyedline
- {\par
- \afterfirstobeyedline
- \futurelet\next\dobetweenthelines}%
- \activatespacehandler\@@rgspace
- \GotoPar}
-
-\def\stoplines
- {\endgroup
- \popmacro\checkindentation
- \@@rgafter}
-
-\def\dobetweenthelines
- {\doifmeaningelse\next\obeyedline\@@rginbetween\donothing}
-
-\setuplines
- [\c!before=\blank,
- \c!after=\blank,
- \c!inbetween=\blank,
- \c!indenting=\v!no,
- \c!space=\v!default]
-
-\def\emptylines
- {\dosingleempty\doemptylines}
-
-\def\doemptylines[#1]%
- {\endgraf\dorecurse{\iffirstargument#1\else3\fi}\crlf}
-
-% plugins
-
-\loadmarkfile{core-spa}
-
-\setupwhitespace
- [\v!none]
-
-% still old-fashioned
-
-\indenting
- [\v!never]
-
-\setupindenting
- [\v!none]
-
-\setupblank
- [\v!standard,
- \v!big]
-
-\defineblank[\v!default] [\currentblank]
-\defineblank[\v!before] [\v!default]
-\defineblank[\v!inbetween][\v!default]
-\defineblank[\v!after] [\v!before]
-
-\setupinterlinespace
- [\c!minheight=0pt, % only special purpose
- \c!mindepth=0pt, % only special purpose
- \c!height=.72,
- \c!depth=.28,
- \c!top=1.0,
- \c!bottom=0.4,
- \c!distance=1pt,
- \c!line=2.8ex,
- \c!stretch=0]
-
-\setupnarrower
- [\c!before=\endgraf,
- \c!after=\endgraf,
- \c!left=1.5em,
- \c!right=1.5em,
- \c!middle=1.5em]
-
-\setuptolerance
- [\v!horizontal,\v!verystrict]
-
-\setuptolerance
- [\v!vertical,\v!strict]
-
-\setupalign
- [\v!bottom,
- \v!width]
-
-\setupspacing
- [\v!packed]
-
-\protect \endinput
diff --git a/tex/context/base/core-stg.tex b/tex/context/base/core-stg.tex
index 94e5250e5..429e1e894 100644
--- a/tex/context/base/core-stg.tex
+++ b/tex/context/base/core-stg.tex
@@ -12,7 +12,7 @@
%C details.
%D This is a prelude to strategies. It is rather old code
-%D used in a project may years ago. Use with care since I
+%D used in a project many years ago. Use with care since I
%D will pick up this thread. (moved from cont-new)
\unprotect
@@ -28,7 +28,7 @@
\definetwopasslist{\s!strategy}
-\def\registerstrategypass%
+\def\registerstrategypass
{\ifnum\currentstrategypass>\maximumstrategypass \else
\ifconditional\strategypassforced
\doglobal\increment\currentstrategypass
diff --git a/tex/context/base/core-syn.lua b/tex/context/base/core-syn.lua
deleted file mode 100644
index 10bd9d6d9..000000000
--- a/tex/context/base/core-syn.lua
+++ /dev/null
@@ -1,127 +0,0 @@
-if not modules then modules = { } end modules ['core-syn'] = {
- version = 1.001,
- comment = "companion to core-syn.tex",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
-sorters = sorters or { }
-sorters.list = sorters.list or { }
-
-function sorters.list.compare(a,b)
- return sorters.comparers.basic(a,b,1)
-end
-
-function sorters.list.prepare(data)
- sorters.prepare(data,sorters.splitters.utf,1)
-end
-
-function sorters.list.sort(data)
- sorters.sort(data,sorters.list.compare)
-end
-
-function sorters.list.unique(data)
- sorters.unique(data)
-end
-
-function sorters.list.cleanup(data)
- sorters.cleanup(data)
-end
-
-function sorters.list.finalize(data) -- hm, this really needs documentation
- -- we use the same splitter as with indices
- local split = { }
- for k,v in ipairs(data) do
- local entry, tag = v[2][1][3][1], ""
- local se = sorters.entries[sorters.language]
- if se and se[entry] then
- if type(se[entry]) == "number" then
- entry = se[entry]
- end
- tag = se[entry]
- else
- entry = 0
- tag = "unknown"
- end
- split[entry] = split[entry] or { tag = tag, data = { } }
- split[entry].data[#split[entry].data+1] = v
- end
- return split
-end
-
--- for the moment we use the old structure, some day mkiv code
--- will be different: more structure, less mess
-
-local template = {
- entry = "\\synonymentry{%s}{%s}{%s}{%s}"
-}
-
-function sorters.list.flush(sorted,class)
- -- for the moment we don't add split data (letters) yet
- class = class or 'abbreviation'
- for k,v in ipairs(table.sortedkeys(sorted)) do
- for _, vv in ipairs(sorted[v].data) do
- tex.sprint(tex.ctxcatcodes,template.entry:format(class,vv[2][1][1],vv[2][1][2],vv[3]))
- end
- end
-end
-
-function sorters.list.process(data)
- return sorters.process('list',data)
-end
-
--- interface to tex end
-
-joblists = joblists or { }
-joblists.collected = joblists.collected or { }
-joblists.tobesaved = joblists.tobesaved or { }
-
-local collected, tobesaved = joblists.collected, joblists.tobesaved
-
-local function initializer()
- collected, tobesaved = joblists.collected, joblists.tobesaved
-end
-
-job.register('joblists.collected', joblists.tobesaved, initializer, nil)
-
-local function allocate(class)
- local d = tobesaved[class]
- if not d then
- d = {
- language = 'en',
- entries = { },
- sorted = false,
- class = class
- }
- tobesaved[class] = d
- end
- return d
-end
-
-local function collect(class)
- return collected[class]
-end
-
-joblists.define = allocate
-
--- this should be more generic, i.e. userdata = { meaning = "" }
--- or at least we should get rid of the { { } } which is a quick
--- hack to share code with the indexer
-
-function joblists.save_entry(class,kind,entry,key,meaning)
- local data = allocate(class).entries
- data[#data+1] = { kind, { { entry, key } }, meaning } -- { kind, entry, key, meaning }
-end
-
-function joblists.save_variable(class,key,value)
- if key == "l" then key = "language" end
- allocate(class)[key] = value
-end
-
-function joblists.process(class)
- local data = collect(class)
- if data then
- sorters.list.process(data)
- end
-end
diff --git a/tex/context/base/core-syn.mkii b/tex/context/base/core-syn.mkii
deleted file mode 100644
index b3fdb1738..000000000
--- a/tex/context/base/core-syn.mkii
+++ /dev/null
@@ -1,28 +0,0 @@
-%D \module
-%D [ file=core-syn,
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Synonyms and Sorts,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\mkdefinesortedlist#1% class
- {\addutilityreset{#1}}
-
-\def\mksavesortedlistentry#1#2#3#4%
- {\immediatewriteutility{s e {#1} {#2} {#3} {#4}}}
-
-\def\mksavesortedlistvariable#1#2#3% class type value
- {\immediatewriteutility{s #2 {#1} {#3}}}
-
-\def\mkloadsortedlist#1% class
- {\doutilities{#1}\jobname{#1}\relax\relax}
-
-\protect \endinput
diff --git a/tex/context/base/core-syn.mkiv b/tex/context/base/core-syn.mkiv
deleted file mode 100644
index 3b5398b56..000000000
--- a/tex/context/base/core-syn.mkiv
+++ /dev/null
@@ -1,34 +0,0 @@
-%D \module
-%D [ file=core-syn,
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Synonyms and Sorts,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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
-
-\registerctxluafile{core-syn}{1.001}
-
-\def\mkdefinesortedlist#1% class
- {\ctxlua{joblists.define('#1')}}
-
-\def\mksavesortedlistentry#1#2#3#4% class key entry meaning
- {\ctxlua{joblists.save_entry('#1','e','#2',\!!bs#3\!!es,\!!bs#4\!!es)}}
-
-\def\mksavesortedlistvariable#1#2#3% class type value
- {\ctxlua{joblists.save_variable('#1','#2','#3')}}
-
-\def\mkloadsortedlist#1% class
- {\bgroup
- \getvalue{\s!set#1}%
- \ctxlua{joblists.process('#1')}%
- \getvalue{\s!reset#1}%
- \egroup}
-
-\protect \endinput
diff --git a/tex/context/base/core-syn.tex b/tex/context/base/core-syn.tex
index 926e58233..b5c87c487 100644
--- a/tex/context/base/core-syn.tex
+++ b/tex/context/base/core-syn.tex
@@ -11,17 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Synonyms and Sorts}
+\writestatus{loading}{ConTeXt Core Macros / Synonyms and Sorts}
\unprotect
-\ifx\mkdefinesortedlist\undefined
- \let\mkdefinesortedlist \gobbleoneargument
- \let\mksavesortedlistentry \gobblefourarguments
- \let\mksavesortedlistvariable\gobblethreearguments
- \let\mkloadsortedlist \gobbleoneargument
-\fi
-
% \checkdefined kan hierheen
% Formaat tex-utility-input-file <jobname.tui>:
@@ -86,7 +79,7 @@
\c!color=]%
\setupwhitespace[\v!none]%
%doutilities{#1}\jobname{#2}\relax\par % no longer \par
- \mkloadsortedlist{#1}%
+ \doutilities{#1}\jobname{#1}\relax\relax
\endgroup
\ifutilitydone\else\nowhitespace\fi}
@@ -101,7 +94,7 @@
\synonymmeaningfalse
\doattributes{\??sm#1}\c!synonymstyle\c!synonymcolor{#3}%
\else
- \explicithmode
+ \dontleavehmode
\doattributes{\??sm#1}\c!textstyle\c!textcolor{#2}%
\fi
\endgroup}
@@ -119,7 +112,7 @@
{\begingroup % anders in mathmode lege \hbox
\defconvertexpanded\asciisynonym{\getvalue{\??sm#1\c!expansion}}{#3}%
\defconvertexpanded\asciimeaning{\getvalue{\??sm#1\c!expansion}}{#4}%
- \mksavesortedlistentry{#1}{#2}{\asciisynonym}{\asciimeaning}%
+ \immediatewriteutility{s e {#1} {#2} {\asciisynonym} {\asciimeaning}}%
\endgroup}
\def\reprocesssynonym#1#2#3%
@@ -155,7 +148,7 @@
{\bgroup
\let\dosetsynonym\doloadsynonym
\showmessage\m!systems{19}{#2}%
- \mkloadsortedlist{#1}%
+ \doutilities{#1}\jobname{#1}\relax\relax
\egroup
\setvalue{\s!check#1}##1{}}
@@ -180,7 +173,7 @@
\def\doregistersynonymlanguage#1%
{\savesortlanguage{\getvalue{\??sm#1\s!language}}%
- \mksavesortedlistvariable{#1}{l}{\getvalue{\??sm#1\s!language}}}
+ \immediatewriteutility{s l {#1} {\getvalue{\??sm#1\s!language}}}}
\def\dodefinesynonyms[#1][#2][#3][#4]%
{\iffourthargument
@@ -210,7 +203,7 @@
\doregistersynonymlanguage{#1}%
\to \everysavesortkeys
\presetheadtext[#2=\Word{#2}]% changes the \if...argument
- \mkdefinesortedlist{#1}%
+ \addutilityreset{#1}%
\setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??sm#1]}% to be obsolete
\setvalue{\s!set #1}{\dosetsynonym{#1}}%
\setvalue{\s!reset #1}{\doresetsynonym{#1}}%
@@ -256,8 +249,7 @@
{\whitespace % ZONDER WITRUIMTE ETC ETC
\begingroup
\setupwhitespace[\v!none]%
- %doutilities{#1}\jobname{#1}\relax\par % brr \par
- \mkloadsortedlist{#1}%
+ \doutilities{#1}\jobname{#1}\relax\relax
\endgroup
\ifutilitydone\else\nowhitespace\fi}
@@ -266,7 +258,7 @@
% \def\doplacelistofsorts#1% NOG EEN RUWE VERSIE MAKEN
% {\startpacked
% %doutilities{#1}\jobname{#1}\relax\par
-% \mkloadsortedlist{#1}%
+% \doutilities{#1}\jobname{#1}\relax\relax
% \stoppacked}
\def\docompletelistofsorts#1#2%
@@ -280,7 +272,7 @@
% {\doplacelistofsorts{#1}}
\def\processsort#1#2#3%
- {\explicithmode
+ {\dontleavehmode
\begingroup % was \bgroup
\doattributes{\??so#1}\c!style\c!color{#2}%
\endgroup} % was \egroup
@@ -288,7 +280,7 @@
\def\dowritesort#1#2#3%
{\bgroup
\defconvertexpanded\asciisynonym{\getvalue{\??so#1\c!expansion}}{#3}%
- \mksavesortedlistentry{#1}{#2}{\asciisynonym}{}%
+ \immediatewriteutility{s e {#1} {#2} {\asciisynonym} {}}%
\egroup}
\def\synonymentry#1%
@@ -321,7 +313,7 @@
{\bgroup
\let\dosetsort\doloadsort
\showmessage\m!systems{20}{#2}%
- \mkloadsortedlist{#1}%
+ \doutilities{#1}\jobname{#1}\relax\relax
\egroup
\setvalue{\s!check#1}##1{}}
@@ -346,7 +338,7 @@
\def\doregistersortinglanguage#1%
{\savesortlanguage{\getvalue{\??so#1\s!language}}%
- \mksavesortedlistvariable{#1}{l}{\getvalue{\??so#1\s!language}}}
+ \immediatewriteutility{s l {#1} {\getvalue{\??so#1\s!language}}}}
\def\dodefinesorting[#1][#2][#3]%
{\getparameters[\??so#1]
@@ -370,7 +362,7 @@
\else
\setvalue{#1}{\dotripleempty\docomplexsort[][#1]}%
\fi
- \mkdefinesortedlist{#1}%
+ \addutilityreset{#1}%
\presetheadtext[#2=\Word{#2}]% after \ifthirdargument -)
\setvalue{\e!setup#2\e!endsetup}[##1]{\getparameters[\??so#1][##1]}% to be obsolete
\setvalue{\s!set#1}{\dosetsort{#1}}%
@@ -388,7 +380,7 @@
%D written by Taco.
\def\processlistofsorts[#1]%
- {\mkloadsortedlist{#1}}
+ {\doutilities{#1}\jobname{#1}\relax\relax}
\newcounter\nofsortedalphalists
@@ -410,10 +402,6 @@
% \def\whatever{ax,bx,qx,dx,rx,fx} \sortalphacommacommand\whatever \whatever \endgraf
% \stoptext
-%D Plugins.
-
-\loadmarkfile{core-syn}
-
%D Presets.
\definesynonyms
diff --git a/tex/context/base/core-sys.mkii b/tex/context/base/core-sys.mkii
index 6816364de..24975ffb6 100644
--- a/tex/context/base/core-sys.mkii
+++ b/tex/context/base/core-sys.mkii
@@ -11,4 +11,386 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D For the moment this file is empty.
+\writestatus{loading}{ConTeXt Core Macros / System}
+
+\unprotect
+
+%D Version checking:
+
+\def\newcontextversion#1%
+ {\doifelse{#1}\contextversion
+ {\let\newcontextversion\gobbleoneargument}
+ {\writeline
+ \writestatus{Fatal Error}{Your format does not match the base files!}%
+ \writeline
+ \writestatus{Format Version}{\contextversion\space\contextmark}%
+ \writestatus{Files Version}{#1}%
+ \batchmode
+ \normalend}}
+
+%D End of lines to the output. \TEX\ will map this onto the platform specific
+%D line ending. I hate this mess.
+
+%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}}
+\newlinechar=10 \edef\outputnewlinechar{^^J}
+
+% in case formats are shared:
+
+\def\initializenewlinechar
+ {\bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup}
+
+%D Job names.
+
+\def\outputfilename {\@@svfile}
+\def\inputfilename {\@@svinputfile}
+\def\operatingsystem{\@@svtype}
+
+\let\jobfilename \jobname
+\let\jobfilesuffix\c!tex
+
+\def\splitjobfilename % todo: mkiv
+ {\resetsystemmode{suffix-\jobfilesuffix}%
+ \edef\ascii{\inputfilename}\defconvertedcommand\ascii\ascii
+ \splitstring\ascii\at.\to\jobfilename\and\jobfilesuffix
+ \lowercasestring\jobfilesuffix\to\jobfilesuffix
+ \doifnothing\jobfilename {\let\jobfilename \jobname}%
+ % todo and totest: \defconvertedcommand\jobfilename\jobfilename
+ \doifnothing\jobfilesuffix{\let\jobfilesuffix\c!tex}%
+ \setsystemmode{suffix-\jobfilesuffix}}
+
+% Some mechanisms (see x-res-01) use either \jobfilename or
+% \jobfilename.somesuffix, in which case we need to use the
+% full name if given or a default (like \jobfilename.xml);
+% this comes down to replacing the default tex suffix.
+
+\def\jobfullname{\jobfilename.\jobfilesuffix}
+
+\def\setjobfullname#1% #1 = default if not given
+ {\doifelsenothing\jobfilename
+ {\let\jobfullname\empty}
+ {\doif\jobfilesuffix\c!tex{\edef\jobfullname{\jobfilename.#1}}}}
+
+% ...
+
+\def\dosetupsystem[#1]%
+ {\getparameters[\??sv][#1]%
+ \setuprandomize[\@@svrandom]%
+ \beforesplitstring\@@svresolution\at dpi\to\@@svresolution
+ \let\outputresolution\@@svresolution
+ \ifcase\@@svn
+ % % 0 : unknown
+ \or
+ \setsystemmode\v!first % 1 : first run
+ \or
+ % % 2 : successive run
+ \or
+ \setsystemmode\v!first % 3 : first and only run
+ \or
+ \setsystemmode\v!last % 4 : (extra) last run
+ \fi
+% \processaction
+% [\@@svtype]
+% %[ mswin=>\edef\@@svline{\rawcharacter{13}\rawcharacter{10}}, % crlf
+% [ mswin=>\edef\@@svline{\rawcharacter{13}}, % cr % crlf
+% darwin=>\edef\@@svline{\rawcharacter{13}}, % cr
+% \s!unknown=>\edef\@@svline{\rawcharacter{10}}]% % lf
+ \splitjobfilename}
+
+% \edef\@@svline{\rawcharacter{10}} % unix is the most critical/sensitive system
+
+\let\systemendofline\outputnewlinechar % will become obsolete
+
+\def\setupsystem
+ {\dosingleargument\dosetupsystem}
+
+\def\systemparameter#1{\executeifdefined{\??sv#1}\empty}
+
+%D The system modes set by the setup command can be used in
+%D situations like:
+%D
+%D \starttyping
+%D \startmode[*first]
+%D \executesystemcommand{cleanupxml text.xml clean-text.xml}
+%D \stopmode
+%D
+%D \starttext
+%D \typefile{clean-text.xml}
+%D \stoptext
+%D \stoptyping
+
+\def\setuprandomize[#1]%
+ {\doifsomething{#1}
+ {\bgroup
+ % tex's time is in minutes
+ \scratchcounter\normaltime
+ \processaction
+ [#1]
+ [ \v!small=>\divide\scratchcounter 15, % 900,
+ \v!medium=>\divide\scratchcounter 30, % 1800,
+ \v!big=>\divide\scratchcounter 60, % 3600,
+ \v!normal=>\getnewrandomseed\scratchcounter,
+ \s!default=>\getnewrandomseed\scratchcounter,
+ \s!unknown=>\scratchcounter#1]%
+ \expanded{\setrandomseed{\the\scratchcounter}}%
+% \writestatus\m!systems{randomseed: \the\scratchcounter}%
+ \egroup}}
+
+
+\setupsystem
+ [\c!directory=,
+ \c!n=0, % 0:unknown 1: one run 2: first 3: successive 4: final run
+ \c!resolution=600dpi,
+ \c!random=,
+ \c!file=\jobname,
+ \c!inputfile=\outputfilename,
+ \c!type=unix, % windows is normally less sensitive to handle
+ \c!bodyfont=\normalizedlocalbodyfontsize] % of iets anders
+
+%D Remark: windows programs normally handle \type {cr|lf|crlf} but unix
+%D is more picky, so we default to the \type {cr}. I never understood why
+%D \type {crlf} was not used in all systems, since it makes most sense.
+
+\def\dostartglobaldefs#1#2%
+ {\edef\!!stringa{\the\globaldefs}%
+ \ifnum\globaldefs#10
+ \globaldefs-\globaldefs
+ \fi
+ \advance\globaldefs #21
+ \setevalue{@gd@\the\globaldefs}{\!!stringa}}
+
+\def\dostopglobaldefs
+ {\doifdefinedelse{@gd@\the\globaldefs}
+ {\globaldefs\getvalue{@gd@\the\globaldefs}\relax}
+ {\globaldefs\zerocount}}
+
+\def\startlocal {\dostartglobaldefs>-}
+\def\stoplocal {\dostopglobaldefs}
+\def\startglobal {\dostartglobaldefs<+}
+\def\stopglobal {\dostopglobaldefs}
+
+\def\complexstart[#1]{\bgroup\getvalue{\e!start#1}}
+\def\complexstop [#1]{\getvalue{\e!stop #1}\egroup}
+
+\let\simplestart\bgroup
+\let\simplestop \egroup
+
+\definecomplexorsimple\start
+\definecomplexorsimple\stop
+
+\def\dododefinestartstop[#1][#2]% todo: use indirect commands
+ {\getparameters
+ [\??be#1]
+ [\c!before=,
+ \c!after=,
+ \c!inbetween=,
+ \c!commands=,
+ \c!style=,
+ #2]%
+ \unexpanded\setvalue{#1}%
+ {\groupedcommand
+ {\getvalue{\??be#1\c!commands}%
+ \dostartattributes{\??be#1}\c!style\c!color}
+ {\dostopattributes
+ \getvalue{\??be#1\c!inbetween}}}%
+ \setvalue{\e!start#1}%
+ {\getvalue{\??be#1\c!before}%
+ \bgroup
+ \getvalue{\??be#1\c!commands}%
+ \dostartattributes{\??be#1}\c!style\c!color\empty}%
+ \setvalue{\e!stop#1}%
+ {\dostopattributes
+ \egroup
+ \getvalue{\??be#1\c!after}}}
+
+\def\dodefinestartstop[#1][#2]%
+ {\def\docommand##1{\dododefinestartstop[##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+\def\definestartstop
+ {\dodoubleargument\dodefinestartstop}
+
+\def\dosetupstartstop[#1][#2]%
+ {\def\docommand##1{\getparameters[\??be##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+\def\setupstartstop
+ {\dodoubleargument\dosetupstartstop}
+
+% \docommand kan niet worden gebruikt omdat deze macro
+% soms lokaal wordt gebruikt
+
+% te zijner tijd:
+%
+% \definevariable {pc} % ProtectedCommand
+%
+% \def\executeprotected#1%
+% {\csname\??pc\string#1\endcsname}
+%
+% \def\defineprotected#1#2%
+% {\expandafter\def\csname\??pc\string#2\endcsname}
+%
+% \def\defineunprotected#1%
+% {\def#1}
+%
+% \def\doprotected%
+% {\ifx\next\define
+% \let\next=\defineprotected
+% \else
+% \let\next=\executeprotected
+% \fi
+% \next}
+%
+% \def\unexpanded%
+% {\futurelet\next\doprotected}
+%
+% \unexpanded\define\ziezo{ziezo}
+%
+% \unexpanded\ziezo
+
+\def\complexdefine[#1]#2#3%
+ {\ifx#2\undefined
+ \else
+ \showmessage\m!systems4{\string#2}%
+ \fi
+ \ifcase0#1\def#2{#3}%
+ \or\def#2##1{#3}%
+ \or\def#2##1##2{#3}%
+ \or\def#2##1##2##3{#3}%
+ \or\def#2##1##2##3##4{#3}%
+ \or\def#2##1##2##3##4##5{#3}%
+ \or\def#2##1##2##3##4##5##6{#3}%
+ \or\def#2##1##2##3##4##5##6##7{#3}%
+ \or\def#2##1##2##3##4##5##6##7##8{#3}%
+ \or\def#2##1##2##3##4##5##6##7##8##9{#3}%
+ \else\def#2{#3}%
+ \fi}
+
+\definecomplexorsimpleempty\define
+
+\unexpanded\def\macroname#1% brrr
+ {\executeifdefined{#1}\empty}
+
+\def\usecommands#1%
+ {\bgroup
+ \def\docommand##1{\setbox0\hbox{\getvalue{\string##1}##1}}%
+ \processcommalist[#1]\docommand
+ \egroup}
+
+\newif\ifforcefileexpansion % handy for document level overload
+
+%D The next implementation is about 4 times as faster than a
+%D processaction alternative on an string of average length.
+%D Since this feature is used in XML processing, it made sense
+%D to support this faster alternative. It's installable as well.
+
+\def\installexpander#1#2#3% changed, no longer \convert..\to...
+ {\setvalue{\s!do\c!expansion#1l}{#2}%
+ \setvalue{\s!do\c!expansion#1g}{#3}}%
+
+% \convertexpanded is obsolete
+
+\long\def\doconvertexpanded#1#2#3% #4 % [l|g] \cs {kind} {data}
+ {\csname % that we assign all exp a value
+ \s!do\c!expansion
+ \ifforcefileexpansion
+ \v!yes
+ \else\ifcsname\s!do\c!expansion#3#1\endcsname
+ #3%
+ \else
+ \s!default
+ \fi\fi
+ #1%
+ \endcsname#2}% #3
+
+\long\def\defconvertexpanded {\doconvertexpanded l}
+\long\def\gdefconvertexpanded{\doconvertexpanded g}
+
+\installexpander\v!command \defconvertedcommand \gdefconvertedcommand
+\installexpander\s!default \defconvertedargument \gdefconvertedargument
+\installexpander\empty \defconvertedargument \gdefconvertedargument
+\installexpander\v!no \defconvertedargument \gdefconvertedargument
+\installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning
+\installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning
+\installexpander\v!strict \defreducedargument \gdefreducedargument
+\installexpander {utf} \defreducedtoutf \gdefreducedtoutf
+
+%installexpander {xml} {see xtag-ext}
+
+\def\dodefconvertedmeaning#1#2#3% watch the double expansion !
+ {\bgroup
+ \honorunexpanded
+ \convertencodedtokens % can be overloaded
+ \xdef\@@globalexpanded{#3}%
+ \xdef\@@globalexpanded{\@@globalexpanded}%
+ \egroup
+ #1#2\@@globalexpanded}
+
+\def\defconvertedmeaning {\dodefconvertedmeaning\defconvertedcommand}
+\def\gdefconvertedmeaning{\dodefconvertedmeaning\gdefconvertedcommand}
+
+\def\dodefreducedargument#1#2#3%
+ {\begingroup
+ \reducetocoding[raw]%
+ \edef\ascii{#3}%
+ \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}}
+
+\def\defreducedargument {\dodefreducedargument\edef}
+\def\gdefreducedargument{\dodefreducedargument\xdef}
+
+% \setupindex[expansion=utf]\index{\eacute}
+
+\def\dodefreducedtoutf#1#2#3%
+ {\begingroup
+ \reducetocoding[uc]%
+ \let\uchar\uchartoutf
+ \let\unicodechar\numbertoutf
+ \edef\ascii{#3}%
+ \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}}
+
+\def\defreducedtoutf {\dodefreducedtoutf\edef}
+\def\gdefreducedtoutf{\dodefreducedtoutf\xdef}
+
+% old syntax:
+
+\def\convertmeaning#1\to#2% watch the double expansion !
+ {\bgroup
+ \honorunexpanded
+ \convertencodedtokens % can be overloaded
+ \xdef\@@globalexpanded{#1}%
+ \xdef\@@globalexpanded{\@@globalexpanded}%
+ \egroup
+ \defconvertedcommand#2\@@globalexpanded}
+
+\def\reduceargument#1\to#2%
+ {\begingroup
+ \reducetocoding[raw]%
+ \edef\ascii{#1}%
+ \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}
+
+\def\reducetoutf#1\to#2%
+ {\begingroup
+ \reducetocoding[uc]%
+ \let\uchar\uchartoutf
+ \let\unicodechar\numbertoutf
+ \edef\ascii{#1}%
+ \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}
+
+% \setvalue{statevalue\v!stop }{0}
+% \setvalue{statevalue\v!start }{1}
+% \setvalue{statevalue\v!normaal}{2}
+% \setvalue{statevalue\v!leeg }{3}
+% \setvalue{statevalue\v!geen }{4}
+%
+% \def\setcurrentstate#1%
+% {\chardef\currentstate=0\getvalue{statevalue\getvalue{#1\c!state}\relax}
+%
+% \ifcase\currentstate ...
+
+\def\redo{\dorepeat} % [n*10], kind of obsolete
+
+% obsolete, use \dorecurse instead
+%
+% \def\herhaler {\repeater}
+% \def\herhaalmetcommando {\dorepeatwithcommand}
+
+\protect \endinput
diff --git a/tex/context/base/core-sys.mkiv b/tex/context/base/core-sys.mkiv
index 0cef6c236..073c29b66 100644
--- a/tex/context/base/core-sys.mkiv
+++ b/tex/context/base/core-sys.mkiv
@@ -1,6 +1,6 @@
%D \module
-%D [ file=core-sys,
-%D version=2006.09.18,
+%D [ file=core-sys, % moved from main-001
+%D version=1997.03.31,
%D title=\CONTEXT\ Core Macros,
%D subtitle=System,
%D author=Hans Hagen,
@@ -11,6 +11,371 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% we need to mkiv-ize this file !
+
+\writestatus{loading}{ConTeXt Core Macros / System}
+
+\unprotect
+
+%D Version checking:
+
+\def\newcontextversion#1%
+ {\doifelse{#1}\contextversion
+ {\let\newcontextversion\gobbleoneargument}
+ {\writeline
+ \writestatus{Fatal Error}{Your format does not match the base files!}%
+ \writeline
+ \writestatus{Format Version}{\contextversion\space\contextmark}%
+ \writestatus{Files Version}{#1}%
+ \batchmode
+ \normalend}}
+
+%D End of lines to the output. \TEX\ will map this onto the platform specific
+%D line ending. I hate this mess.
+
+%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}}
+\newlinechar=10 \edef\outputnewlinechar{^^J}
+
+% in case formats are shared:
+
+\def\initializenewlinechar
+ {\bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup}
+
+%D Job names.
+
+\def\outputfilename {\@@svfile}
+\def\inputfilename {\@@svinputfile}
+\def\operatingsystem{\@@svtype}
+
+\let\jobfilename \jobname
+\let\jobfilesuffix\c!tex
+
+\def\splitjobfilename % todo: mkiv
+ {\resetsystemmode{suffix-\jobfilesuffix}%
+ \edef\ascii{\inputfilename}\defconvertedcommand\ascii\ascii
+ \splitstring\ascii\at.\to\jobfilename\and\jobfilesuffix
+ \lowercasestring\jobfilesuffix\to\jobfilesuffix
+ \doifnothing\jobfilename {\let\jobfilename \jobname}%
+ % todo and totest: \defconvertedcommand\jobfilename\jobfilename
+ \doifnothing\jobfilesuffix{\let\jobfilesuffix\c!tex}%
+ \setsystemmode{suffix-\jobfilesuffix}}
+
+% Some mechanisms (see x-res-01) use either \jobfilename or
+% \jobfilename.somesuffix, in which case we need to use the
+% full name if given or a default (like \jobfilename.xml);
+% this comes down to replacing the default tex suffix.
+
+\def\jobfullname{\jobfilename.\jobfilesuffix}
+
+\def\setjobfullname#1% #1 = default if not given
+ {\doifelsenothing\jobfilename
+ {\let\jobfullname\empty}
+ {\doif\jobfilesuffix\c!tex{\edef\jobfullname{\jobfilename.#1}}}}
+
+% ...
+
+\def\dosetupsystem[#1]%
+ {\getparameters[\??sv][#1]%
+ \setuprandomize[\@@svrandom]%
+ \beforesplitstring\@@svresolution\at dpi\to\@@svresolution
+ \let\outputresolution\@@svresolution
+ \ifcase\@@svn
+ % % 0 : unknown
+ \or
+ \setsystemmode\v!first % 1 : first run
+ \or
+ % % 2 : successive run
+ \or
+ \setsystemmode\v!first % 3 : first and only run
+ \or
+ \setsystemmode\v!last % 4 : (extra) last run
+ \fi
+% \processaction
+% [\@@svtype]
+% %[ mswin=>\edef\@@svline{\rawcharacter{13}\rawcharacter{10}}, % crlf
+% [ mswin=>\edef\@@svline{\rawcharacter{13}}, % cr % crlf
+% darwin=>\edef\@@svline{\rawcharacter{13}}, % cr
+% \s!unknown=>\edef\@@svline{\rawcharacter{10}}]% % lf
+ \splitjobfilename}
+
+% \edef\@@svline{\rawcharacter{10}} % unix is the most critical/sensitive system
+
+\let\systemendofline\outputnewlinechar % will become obsolete
+
+\def\setupsystem
+ {\dosingleargument\dosetupsystem}
+
+\def\systemparameter#1{\executeifdefined{\??sv#1}\empty}
+
+%D The system modes set by the setup command can be used in
+%D situations like:
+%D
+%D \starttyping
+%D \startmode[*first]
+%D \executesystemcommand{cleanupxml text.xml clean-text.xml}
+%D \stopmode
+%D
+%D \starttext
+%D \typefile{clean-text.xml}
+%D \stoptext
+%D \stoptyping
+
+\def\setuprandomize[#1]%
+ {\doifsomething{#1}
+ {\bgroup
+ % tex's time is in minutes
+ \scratchcounter\normaltime
+ \processaction
+ [#1]
+ [ \v!small=>\divide\scratchcounter 15, % 900,
+ \v!medium=>\divide\scratchcounter 30, % 1800,
+ \v!big=>\divide\scratchcounter 60, % 3600,
+ \v!normal=>\getnewrandomseed\scratchcounter,
+ \s!default=>\getnewrandomseed\scratchcounter,
+ \s!unknown=>\scratchcounter#1]%
+ \expanded{\setrandomseed{\the\scratchcounter}}%
+% \writestatus\m!systems{randomseed: \the\scratchcounter}%
+ \egroup}}
+
+\setupsystem
+ [\c!directory=,
+ \c!n=0, % 0:unknown 1: one run 2: first 3: successive 4: final run
+ \c!resolution=600dpi,
+ \c!random=,
+ \c!file=\jobname,
+ \c!inputfile=\outputfilename,
+ \c!type=unix, % windows is normally less sensitive to handle
+ \c!bodyfont=\normalizedlocalbodyfontsize] % of iets anders
+
+%D Remark: windows programs normally handle \type {cr|lf|crlf} but unix
+%D is more picky, so we default to the \type {cr}. I never understood why
+%D \type {crlf} was not used in all systems, since it makes most sense.
+
+\def\dostartglobaldefs#1#2%
+ {\edef\!!stringa{\the\globaldefs}%
+ \ifnum\globaldefs#10
+ \globaldefs-\globaldefs
+ \fi
+ \advance\globaldefs #21
+ \setevalue{@gd@\the\globaldefs}{\!!stringa}}
+
+\def\dostopglobaldefs
+ {\doifdefinedelse{@gd@\the\globaldefs}
+ {\globaldefs\getvalue{@gd@\the\globaldefs}\relax}
+ {\globaldefs\zerocount}}
+
+\def\startlocal {\dostartglobaldefs>-}
+\def\stoplocal {\dostopglobaldefs}
+\def\startglobal {\dostartglobaldefs<+}
+\def\stopglobal {\dostopglobaldefs}
+
+\def\complexstart[#1]{\bgroup\getvalue{\e!start#1}}
+\def\complexstop [#1]{\getvalue{\e!stop #1}\egroup}
+
+\let\simplestart\bgroup
+\let\simplestop \egroup
+
+\definecomplexorsimple\start
+\definecomplexorsimple\stop
+
+\def\dododefinestartstop[#1][#2]% todo: use indirect commands
+ {\getparameters
+ [\??be#1]
+ [\c!before=,
+ \c!after=,
+ \c!inbetween=,
+ \c!commands=,
+ \c!style=,
+ #2]%
+ \unexpanded\setvalue{#1}%
+ {\groupedcommand
+ {\getvalue{\??be#1\c!commands}%
+ \dostartattributes{\??be#1}\c!style\c!color}
+ {\dostopattributes
+ \getvalue{\??be#1\c!inbetween}}}%
+ \setvalue{\e!start#1}%
+ {\getvalue{\??be#1\c!before}%
+ \bgroup
+ \getvalue{\??be#1\c!commands}%
+ \dostartattributes{\??be#1}\c!style\c!color\empty}%
+ \setvalue{\e!stop#1}%
+ {\dostopattributes
+ \egroup
+ \getvalue{\??be#1\c!after}}}
+
+\def\dodefinestartstop[#1][#2]%
+ {\def\docommand##1{\dododefinestartstop[##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+\def\definestartstop
+ {\dodoubleargument\dodefinestartstop}
+
+\def\dosetupstartstop[#1][#2]%
+ {\def\docommand##1{\getparameters[\??be##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+\def\setupstartstop
+ {\dodoubleargument\dosetupstartstop}
+
+% \docommand kan niet worden gebruikt omdat deze macro
+% soms lokaal wordt gebruikt
+
+% te zijner tijd:
+%
+% \definevariable {pc} % ProtectedCommand
+%
+% \def\executeprotected#1%
+% {\csname\??pc\string#1\endcsname}
+%
+% \def\defineprotected#1#2%
+% {\expandafter\def\csname\??pc\string#2\endcsname}
+%
+% \def\defineunprotected#1%
+% {\def#1}
+%
+% \def\doprotected%
+% {\ifx\next\define
+% \let\next=\defineprotected
+% \else
+% \let\next=\executeprotected
+% \fi
+% \next}
+%
+% \def\unexpanded%
+% {\futurelet\next\doprotected}
+%
+% \unexpanded\define\ziezo{ziezo}
+%
+% \unexpanded\ziezo
+
+\def\complexdefine[#1]#2#3%
+ {\ifx#2\undefined
+ \else
+ \showmessage\m!systems4{\string#2}%
+ \fi
+ \ifcase0#1\def#2{#3}%
+ \or\def#2##1{#3}%
+ \or\def#2##1##2{#3}%
+ \or\def#2##1##2##3{#3}%
+ \or\def#2##1##2##3##4{#3}%
+ \or\def#2##1##2##3##4##5{#3}%
+ \or\def#2##1##2##3##4##5##6{#3}%
+ \or\def#2##1##2##3##4##5##6##7{#3}%
+ \or\def#2##1##2##3##4##5##6##7##8{#3}%
+ \or\def#2##1##2##3##4##5##6##7##8##9{#3}%
+ \else\def#2{#3}%
+ \fi}
+
+\definecomplexorsimpleempty\define
+
+\unexpanded\def\macroname#1% brrr
+ {\executeifdefined{#1}\empty}
+
+\def\usecommands#1%
+ {\bgroup
+ \def\docommand##1{\setbox0\hbox{\getvalue{\string##1}##1}}%
+ \processcommalist[#1]\docommand
+ \egroup}
+
+\newif\ifforcefileexpansion % handy for document level overload
+
+%D The next implementation is about 4 times as faster than a
+%D processaction alternative on an string of average length.
+%D Since this feature is used in XML processing, it made sense
+%D to support this faster alternative. It's installable as well.
+
+\def\installexpander#1#2#3% changed, no longer \convert..\to...
+ {\setvalue{\s!do\c!expansion#1l}{#2}%
+ \setvalue{\s!do\c!expansion#1g}{#3}}%
+
+% \convertexpanded is obsolete
+
+\long\def\doconvertexpanded#1#2#3% #4 % [l|g] \cs {kind} {data}
+ {\csname % that we assign all exp a value
+ \s!do\c!expansion
+ \ifforcefileexpansion
+ \v!yes
+ \else\ifcsname\s!do\c!expansion#3#1\endcsname
+ #3%
+ \else
+ \s!default
+ \fi\fi
+ #1%
+ \endcsname#2}% #3
+
+\long\def\defconvertexpanded {\doconvertexpanded l}
+\long\def\gdefconvertexpanded{\doconvertexpanded g}
+
+\installexpander\v!command \defconvertedcommand \gdefconvertedcommand
+\installexpander\s!default \defconvertedargument \gdefconvertedargument
+\installexpander\empty \defconvertedargument \gdefconvertedargument
+\installexpander\v!no \defconvertedargument \gdefconvertedargument
+\installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning
+\installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning
+\installexpander\v!strict \defreducedargument \gdefreducedargument
+\installexpander {utf} \defreducedtoutf \gdefreducedtoutf
+
+%installexpander {xml} {see xtag-ext}
+
+\def\dodefconvertedmeaning#1#2#3% watch the double expansion !
+ {\bgroup
+ \honorunexpanded
+ \convertencodedtokens % can be overloaded
+ \xdef\@@globalexpanded{#3}%
+ \xdef\@@globalexpanded{\@@globalexpanded}%
+ \egroup
+ #1#2\@@globalexpanded}
+
+\def\defconvertedmeaning {\dodefconvertedmeaning\defconvertedcommand}
+\def\gdefconvertedmeaning{\dodefconvertedmeaning\gdefconvertedcommand}
+
+\def\dodefreducedargument#1#2#3%
+ {\begingroup
+ \reducetocoding[raw]%
+ \edef\ascii{#3}%
+ \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}}
+
+\def\defreducedargument {\dodefreducedargument\edef}
+\def\gdefreducedargument{\dodefreducedargument\xdef}
+
+% \setupindex[expansion=utf]\index{\eacute}
+
+\def\dodefreducedtoutf#1#2#3%
+ {\begingroup
+ \reducetocoding[uc]%
+ \let\uchar\uchartoutf
+ \let\unicodechar\numbertoutf
+ \edef\ascii{#3}%
+ \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}}
+
+\def\defreducedtoutf {\dodefreducedtoutf\edef}
+\def\gdefreducedtoutf{\dodefreducedtoutf\xdef}
+
+% old syntax:
+
+\def\convertmeaning#1\to#2% watch the double expansion !
+ {\bgroup
+ \honorunexpanded
+ \convertencodedtokens % can be overloaded
+ \xdef\@@globalexpanded{#1}%
+ \xdef\@@globalexpanded{\@@globalexpanded}%
+ \egroup
+ \defconvertedcommand#2\@@globalexpanded}
+
+\def\reduceargument#1\to#2%
+ {\begingroup
+ \reducetocoding[raw]%
+ \edef\ascii{#1}%
+ \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}
+
+\def\reducetoutf#1\to#2%
+ {\begingroup
+ \reducetocoding[uc]%
+ \let\uchar\uchartoutf
+ \let\unicodechar\numbertoutf
+ \edef\ascii{#1}%
+ \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}
+
\startruntimeluacode
\ctxlua {
environment.inputfilename = "\inputfilename"
@@ -19,5 +384,5 @@
environment.jobfilesuffix = "\jobfilesuffix"
}
\stopruntimeluacode
-
-\endinput
+
+\protect \endinput
diff --git a/tex/context/base/core-sys.tex b/tex/context/base/core-sys.tex
deleted file mode 100644
index 7e3aa3c04..000000000
--- a/tex/context/base/core-sys.tex
+++ /dev/null
@@ -1,401 +0,0 @@
-%D \module
-%D [ file=core-sys, % moved from main-001
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=System,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros (System)}
-
-\unprotect
-
-%D Version checking:
-
-\def\newcontextversion#1%
- {\doifelse{#1}\contextversion
- {\let\newcontextversion\gobbleoneargument}
- {\writeline
- \writestatus{Fatal Error}{Your format does not match the base files!}%
- \writeline
- \writestatus{Format Version}{\contextversion\space\contextmark}%
- \writestatus{Files Version}{#1}%
- \batchmode
- \normalend}}
-
-%D End of lines to the output. \TEX\ will map this onto the platform specific
-%D line ending. I hate this mess.
-
-%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}}
-\newlinechar=10 \edef\outputnewlinechar{^^J}
-
-% in case formats are shared:
-
-\appendtoks
- \bgroup\newlinechar=10\xdef\outputnewlinechar{^^J}\egroup
-\to \everyjob
-
-%D Job names.
-
-\def\outputfilename {\@@svfile}
-\def\inputfilename {\@@svinputfile}
-\def\operatingsystem{\@@svtype}
-
-\let\jobfilename \jobname
-\let\jobfilesuffix\c!tex
-
-\def\splitjobfilename % todo: mkiv
- {\resetsystemmode{suffix-\jobfilesuffix}%
- \edef\ascii{\inputfilename}\defconvertedcommand\ascii\ascii
- \splitstring\ascii\at.\to\jobfilename\and\jobfilesuffix
- \lowercasestring\jobfilesuffix\to\jobfilesuffix
- \doifnothing\jobfilename {\let\jobfilename \jobname}%
- % todo and totest: \defconvertedcommand\jobfilename\jobfilename
- \doifnothing\jobfilesuffix{\let\jobfilesuffix\c!tex}%
- \setsystemmode{suffix-\jobfilesuffix}}
-
-\appendtoks \splitjobfilename \to \everyjob
-
-% Some mechanisms (see x-res-01) use either \jobfilename or
-% \jobfilename.somesuffix, in which case we need to use the
-% full name if given or a default (like \jobfilename.xml);
-% this comes down to replacing the default tex suffix.
-
-\def\jobfullname{\jobfilename.\jobfilesuffix}
-
-\def\setjobfullname#1% #1 = default if not given
- {\doifelsenothing\jobfilename
- {\let\jobfullname\empty}
- {\doif\jobfilesuffix\c!tex{\edef\jobfullname{\jobfilename.#1}}}}
-
-% ...
-
-\def\dosetupsystem[#1]%
- {\getparameters[\??sv][#1]%
- \setuprandomize[\@@svrandom]%
- \beforesplitstring\@@svresolution\at dpi\to\@@svresolution
- \let\outputresolution\@@svresolution
- \ifcase\@@svn
- % % 0 : unknown
- \or
- \setsystemmode\v!first % 1 : first run
- \or
- % % 2 : successive run
- \or
- \setsystemmode\v!first % 3 : first and only run
- \or
- \setsystemmode\v!last % 4 : (extra) last run
- \fi
-% \processaction
-% [\@@svtype]
-% %[ mswin=>\edef\@@svline{\rawcharacter{13}\rawcharacter{10}}, % crlf
-% [ mswin=>\edef\@@svline{\rawcharacter{13}}, % cr % crlf
-% darwin=>\edef\@@svline{\rawcharacter{13}}, % cr
-% \s!unknown=>\edef\@@svline{\rawcharacter{10}}]% % lf
- \splitjobfilename}
-
-% \edef\@@svline{\rawcharacter{10}} % unix is the most critical/sensitive system
-
-\let\systemendofline\outputnewlinechar % will become obsolete
-
-\def\setupsystem
- {\dosingleargument\dosetupsystem}
-
-\def\systemparameter#1{\executeifdefined{\??sv#1}\empty}
-
-%D The system modes set by the setup command can be used in
-%D situations like:
-%D
-%D \starttyping
-%D \startmode[*first]
-%D \executesystemcommand{cleanupxml text.xml clean-text.xml}
-%D \stopmode
-%D
-%D \starttext
-%D \typefile{clean-text.xml}
-%D \stoptext
-%D \stoptyping
-
-\def\setuprandomize[#1]%
- {\doifsomething{#1}
- {\bgroup
- % tex's time is in minutes
- \scratchcounter\normaltime
- \processaction
- [#1]
- [ \v!small=>\divide\scratchcounter 15, % 900,
- \v!medium=>\divide\scratchcounter 30, % 1800,
- \v!big=>\divide\scratchcounter 60, % 3600,
- \v!normal=>\getnewrandomseed\scratchcounter,
- \s!default=>\getnewrandomseed\scratchcounter,
- \s!unknown=>\scratchcounter#1]%
- \expanded{\setrandomseed{\the\scratchcounter}}%
- \egroup}}
-
-\setupsystem
- [\c!directory=,
- \c!n=0, % 0:unknown 1: one run 2: first 3: successive 4: final run
- \c!resolution=600dpi,
- \c!random=,
- \c!file=\jobname,
- \c!inputfile=\outputfilename,
- \c!type=unix, % windows is normally less sensitive to handle
- \c!bodyfont=\normalizedlocalbodyfontsize] % of iets anders
-
-%D Remark: windows programs normally handle \type {cr|lf|crlf} but unix
-%D is more picky, so we default to the \type {cr}. I never understood why
-%D \type {crlf} was not used in all systems, since it makes most sense.
-
-\def\dostartglobaldefs#1#2%
- {\edef\!!stringa{\the\globaldefs}%
- \ifnum\globaldefs#10
- \globaldefs-\globaldefs
- \fi
- \advance\globaldefs #21
- \setevalue{@gd@\the\globaldefs}{\!!stringa}}
-
-\def\dostopglobaldefs
- {\doifdefinedelse{@gd@\the\globaldefs}
- {\globaldefs\getvalue{@gd@\the\globaldefs}\relax}
- {\globaldefs\zerocount}}
-
-\def\startlocal {\dostartglobaldefs>-}
-\def\stoplocal {\dostopglobaldefs}
-\def\startglobal {\dostartglobaldefs<+}
-\def\stopglobal {\dostopglobaldefs}
-
-\def\complexstart[#1]{\bgroup\getvalue{\e!start#1}}
-\def\complexstop [#1]{\getvalue{\e!stop #1}\egroup}
-
-\let\simplestart\bgroup
-\let\simplestop \egroup
-
-\definecomplexorsimple\start
-\definecomplexorsimple\stop
-
-\def\dododefinestartstop[#1][#2]% todo: use indirect commands
- {\getparameters
- [\??be#1]
- [\c!before=,
- \c!after=,
- \c!inbetween=,
- \c!commands=,
- \c!style=,
- #2]%
- \unexpanded\setvalue{#1}%
- {\groupedcommand
- {\getvalue{\??be#1\c!commands}%
- \dostartattributes{\??be#1}\c!style\c!color}
- {\dostopattributes
- \getvalue{\??be#1\c!inbetween}}}%
- \setvalue{\e!start#1}%
- {\getvalue{\??be#1\c!before}%
- \bgroup
- \getvalue{\??be#1\c!commands}%
- \dostartattributes{\??be#1}\c!style\c!color\empty}%
- \setvalue{\e!stop#1}%
- {\dostopattributes
- \egroup
- \getvalue{\??be#1\c!after}}}
-
-\def\dodefinestartstop[#1][#2]%
- {\def\docommand##1{\dododefinestartstop[##1][#2]}%
- \processcommalist[#1]\docommand}
-
-\def\definestartstop
- {\dodoubleargument\dodefinestartstop}
-
-\def\dosetupstartstop[#1][#2]%
- {\def\docommand##1{\getparameters[\??be##1][#2]}%
- \processcommalist[#1]\docommand}
-
-\def\setupstartstop
- {\dodoubleargument\dosetupstartstop}
-
-% \docommand kan niet worden gebruikt omdat deze macro
-% soms lokaal wordt gebruikt
-
-% te zijner tijd:
-%
-% \definevariable {pc} % ProtectedCommand
-%
-% \def\executeprotected#1%
-% {\csname\??pc\string#1\endcsname}
-%
-% \def\defineprotected#1#2%
-% {\expandafter\def\csname\??pc\string#2\endcsname}
-%
-% \def\defineunprotected#1%
-% {\def#1}
-%
-% \def\doprotected%
-% {\ifx\next\define
-% \let\next=\defineprotected
-% \else
-% \let\next=\executeprotected
-% \fi
-% \next}
-%
-% \def\unexpanded%
-% {\futurelet\next\doprotected}
-%
-% \unexpanded\define\ziezo{ziezo}
-%
-% \unexpanded\ziezo
-
-\def\complexdefine[#1]#2#3%
- {\ifx#2\undefined
- \else
- \showmessage\m!systems4{\string#2}%
- \fi
- \ifcase0#1\def#2{#3}%
- \or\def#2##1{#3}%
- \or\def#2##1##2{#3}%
- \or\def#2##1##2##3{#3}%
- \or\def#2##1##2##3##4{#3}%
- \or\def#2##1##2##3##4##5{#3}%
- \or\def#2##1##2##3##4##5##6{#3}%
- \or\def#2##1##2##3##4##5##6##7{#3}%
- \or\def#2##1##2##3##4##5##6##7##8{#3}%
- \or\def#2##1##2##3##4##5##6##7##8##9{#3}%
- \else\def#2{#3}%
- \fi}
-
-\definecomplexorsimpleempty\define
-
-\unexpanded\def\macroname#1% brrr
- {\executeifdefined{#1}\empty}
-
-\def\usecommands#1%
- {\bgroup
- \def\docommand##1{\setbox0\hbox{\getvalue{\string##1}##1}}%
- \processcommalist[#1]\docommand
- \egroup}
-
-\newif\ifforcefileexpansion % handy for document level overload
-
-%D The next implementation is about 4 times as faster than a
-%D processaction alternative on an string of average length.
-%D Since this feature is used in XML processing, it made sense
-%D to support this faster alternative. It's installable as well.
-
-\def\installexpander#1#2#3% changed, no longer \convert..\to...
- {\setvalue{\s!do\c!expansion#1l}{#2}%
- \setvalue{\s!do\c!expansion#1g}{#3}}%
-
-% \convertexpanded is obsolete
-
-\long\def\doconvertexpanded#1#2#3% #4 % [l|g] \cs {kind} {data}
- {\csname % that we assign all exp a value
- \s!do\c!expansion
- \ifforcefileexpansion
- \v!yes
- \else\ifcsname\s!do\c!expansion#3#1\endcsname
- #3%
- \else
- \s!default
- \fi\fi
- #1%
- \endcsname#2}% #3
-
-\long\def\defconvertexpanded {\doconvertexpanded l}
-\long\def\gdefconvertexpanded{\doconvertexpanded g}
-
-\installexpander\v!command \defconvertedcommand \gdefconvertedcommand
-\installexpander\s!default \defconvertedargument \gdefconvertedargument
-\installexpander\empty \defconvertedargument \gdefconvertedargument
-\installexpander\v!no \defconvertedargument \gdefconvertedargument
-\installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning
-\installexpander\v!yes \defconvertedmeaning \gdefconvertedmeaning
-\installexpander\v!strict \defreducedargument \gdefreducedargument
-\installexpander {utf} \defreducedtoutf \gdefreducedtoutf
-
-%installexpander {xml} {see xtag-ext}
-
-\def\dodefconvertedmeaning#1#2#3% watch the double expansion !
- {\bgroup
- \honorunexpanded
- \convertencodedtokens % can be overloaded
- \xdef\@@globalexpanded{#3}%
- \xdef\@@globalexpanded{\@@globalexpanded}%
- \egroup
- #1#2\@@globalexpanded}
-
-\def\defconvertedmeaning {\dodefconvertedmeaning\defconvertedcommand}
-\def\gdefconvertedmeaning{\dodefconvertedmeaning\gdefconvertedcommand}
-
-\def\dodefreducedargument#1#2#3%
- {\begingroup
- \reducetocoding[raw]%
- \edef\ascii{#3}%
- \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}}
-
-\def\defreducedargument {\dodefreducedargument\edef}
-\def\gdefreducedargument{\dodefreducedargument\xdef}
-
-% \setupindex[expansion=utf]\index{\eacute}
-
-\def\dodefreducedtoutf#1#2#3%
- {\begingroup
- \reducetocoding[uc]%
- \let\uchar\uchartoutf
- \let\unicodechar\numbertoutf
- \edef\ascii{#3}%
- \expandafter\endgroup\expandafter#1\expandafter#2\expandafter{\ascii}}
-
-\def\defreducedtoutf {\dodefreducedtoutf\edef}
-\def\gdefreducedtoutf{\dodefreducedtoutf\xdef}
-
-% old syntax:
-
-\def\convertmeaning#1\to#2% watch the double expansion !
- {\bgroup
- \honorunexpanded
- \convertencodedtokens % can be overloaded
- \xdef\@@globalexpanded{#1}%
- \xdef\@@globalexpanded{\@@globalexpanded}%
- \egroup
- \defconvertedcommand#2\@@globalexpanded}
-
-\def\reduceargument#1\to#2%
- {\begingroup
- \reducetocoding[raw]%
- \edef\ascii{#1}%
- \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}
-
-\def\reducetoutf#1\to#2%
- {\begingroup
- \reducetocoding[uc]%
- \let\uchar\uchartoutf
- \let\unicodechar\numbertoutf
- \edef\ascii{#1}%
- \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}}
-
-% \setvalue{statevalue\v!stop }{0}
-% \setvalue{statevalue\v!start }{1}
-% \setvalue{statevalue\v!normaal}{2}
-% \setvalue{statevalue\v!leeg }{3}
-% \setvalue{statevalue\v!geen }{4}
-%
-% \def\setcurrentstate#1%
-% {\chardef\currentstate=0\getvalue{statevalue\getvalue{#1\c!state}\relax}
-%
-% \ifcase\currentstate ...
-
-\def\redo{\dorepeat} % [n*10], kind of obsolete
-
-% obsolete, use \dorecurse instead
-%
-% \def\herhaler {\repeater}
-% \def\herhaalmetcommando {\dorepeatwithcommand}
-
-%D Plugins
-
-\loadmarkfile{core-sys}
-
-\protect \endinput
diff --git a/tex/context/base/core-trf.tex b/tex/context/base/core-trf.tex
index 2049667d0..c7fa8d42b 100644
--- a/tex/context/base/core-trf.tex
+++ b/tex/context/base/core-trf.tex
@@ -14,7 +14,7 @@
%D It may be that some functionality got lost. If it concerns
%D defined features, let me know and it will be sorted out.
-\writestatus{loading}{Context Core Macros / Transformations}
+\writestatus{loading}{ConTeXt Core Macros / Transformations}
\unprotect
@@ -200,6 +200,14 @@
\xdef\finalscaleboxxscale {\withoutpt\the\dimexpr\scax\points/\plushundred\relax}%
\xdef\finalscaleboxyscale {\withoutpt\the\dimexpr\scay\points/\plushundred\relax}}
+
+\setvalue{\??xy:\c!grid:\v!yes }{\getnoflines \fighei\setevalue{\currentscaletag\c!height}{\the\noflines\lineheight}}
+\setvalue{\??xy:\c!grid:\v!height }{\getrawnoflines\fighei\setevalue{\currentscaletag\c!height}{\the\dimexpr\noflines\lineheight+\strutdepth\relax}}
+\setvalue{\??xy:\c!grid:\v!depth }{\getrawnoflines\fighei\setevalue{\currentscaletag\c!height}{\the\dimexpr\noflines\lineheight-\strutdepth\relax}}
+\setvalue{\??xy:\c!grid:\v!halfline}{\getrawnoflines\fighei\setevalue{\currentscaletag\c!height}{\the\dimexpr\noflines\lineheight+.5\lineheight\relax}}
+\setvalue{\??xy:\c!grid:\v!fit }{\getrawnoflines\fighei\setevalue{\currentscaletag\c!height}{\the\noflines\lineheight}}
+\letvalue{\??xy:\c!grid:\empty }\donothing
+
\def\checkscaleboxsettings
{\doifsomething{\scaleparameter\c!maxwidth }% can be defined in itself
{\setevalue{\currentscaletag\c!maxwidth }{\the\dimexpr\scaleparameter\c!maxwidth \relax}}%
@@ -207,19 +215,7 @@
{\setevalue{\currentscaletag\c!maxheight}{\the\dimexpr\scaleparameter\c!maxheight\relax}}%
\doifsomething{\scaleparameter\c!lines}
{\setevalue{\currentscaletag\c!height}{\the\dimexpr\scaleparameter\c!lines\lineheight\relax}}%
- \doifsomething{\scaleparameter\c!grid}
- {\processaction
- [\scaleparameter\c!grid]
- [ \v!yes=>\getnoflines\fighei
- \setevalue{\currentscaletag\c!height}{\the\noflines\lineheight},
- \v!height=>\getrawnoflines\fighei
- \setevalue{\currentscaletag\c!height}{\the\dimexpr\noflines\lineheight+\strutdepth\relax},
- \v!depth=>\getrawnoflines\fighei
- \setevalue{\currentscaletag\c!height}{\the\dimexpr\noflines\lineheight-\strutdepth\relax},
- \v!halfline=>\getrawnoflines\fighei
- \setevalue{\currentscaletag\c!height}{\the\dimexpr\noflines\lineheight+.5\lineheight\relax},
- \v!fit=>\getrawnoflines\fighei
- \setevalue{\currentscaletag\c!height}{\the\noflines\lineheight}]}}
+ \getvalue{\??xy:\c!grid:\scaleparameter\c!grid}}
\def\setscaleboxbynature % where ! ! ! ! !
{\doifsomething{\scaleparameter\c!width }{\global\scaleboxdimx\scaleparameter\c!width }%
@@ -260,7 +256,7 @@
\docalculatescaleboxnorm\scaleboxdimx\c!wfactor\c!width \hsize \hsize
\donefalse}}}%
\ifdone
-\settrue\scaleboxscalingdone
+ \settrue\scaleboxscalingdone
\ifdim\scaleboxdimx>\scaleboxhsize
\global\scaleboxdimy\zeropoint \global\scaleboxdimx\scaleboxhsize
\else\ifdim\scaleboxdimy>\scaleboxvsize
@@ -327,7 +323,7 @@
#3\relax
\fi}}
-\def\docalculatescaleboxnorm#1#2#3#4#5% 2 3 parameters
+\def\docalculatescaleboxnorm#1#2#3#4#5% 2 3 parameters (dodo:speedup)
{\processaction
[\scaleparameter#2]
[ \v!max=>\global#1\dimexpr#4\relax,
diff --git a/tex/context/base/core-two.lua b/tex/context/base/core-two.lua
index 748c4eb97..5749d406d 100644
--- a/tex/context/base/core-two.lua
+++ b/tex/context/base/core-two.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['core-two'] = {
license = "see context related readme files"
}
+local remove, concat = table.remove, table.concat
+
local texprint = tex.print
--[[ldx--
@@ -49,21 +51,21 @@ end
function jobpasses.get(id)
local jti = collected[id]
if jti and #jti > 0 then
- tex.print(table.remove(jti,1))
+ texprint(remove(jti,1))
end
end
function jobpasses.first(id)
local jti = collected[id]
if jti and #jti > 0 then
- tex.print(jti[1])
+ texprint(jti[1])
end
end
function jobpasses.last(id)
local jti = collected[id]
if jti and #jti > 0 then
- tex.print(jti[#jti])
+ texprint(jti[#jti])
end
end
@@ -84,7 +86,7 @@ end
function jobpasses.list(id)
local jti = collected[id]
if jti then
- texprint(table.concat(jti,','))
+ texprint(concat(jti,','))
end
end
@@ -92,15 +94,15 @@ function jobpasses.doifinlistelse(id,str)
local jti = collected[id]
if jti then
local found = false
- for _, v in pairs(jti) do
+ for _, v in next, jti do
if v == str then
found = true
break
end
end
- cs.testcase(found)
+ commands.testcase(found)
else
- cs.testcase(false)
+ commands.testcase(false)
end
end
@@ -119,7 +121,7 @@ end
function jobpasses.getfield(id,index,tag,default)
local jti = collected[id]
- jti = jit and jti[index]
- texprint((jit and jti[tag]) or default)
+ jti = jti and jti[index]
+ texprint((jti and jti[tag]) or default)
end
diff --git a/tex/context/base/core-two.mkii b/tex/context/base/core-two.mkii
index a14586dc4..0f2e0048c 100644
--- a/tex/context/base/core-two.mkii
+++ b/tex/context/base/core-two.mkii
@@ -11,9 +11,72 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Two Pass Data}
+
+%D This is a rather old mechanism which has not changed much over
+%D time, apart from adding a few more selectors. This code used
+%D to be part of \type {core-uti}. The following examples demonstrate
+%D the interface.
+%D
+%D \startbuffer
+%D \definetwopasslist{test-1}
+%D
+%D \gettwopassdatalist{test-1} [\twopassdatalist=]
+%D \checktwopassdata {test-1} [\twopassdata=]
+%D \checktwopassdata {test-1} [\twopassdata=]
+%D \gettwopassdata {test-1} [\twopassdata=]
+%D \gettwopassdata {test-1} [\twopassdata=]
+%D
+%D \definetwopasslist{test-2}
+%D
+%D \lazysavetwopassdata{test-2}{1}{x}
+%D \lazysavetwopassdata{test-2}{2}{y}
+%D \lazysavetwopassdata{test-2}{3}{z}
+%D
+%D \gettwopassdatalist{test-2} [\twopassdatalist=x,y,z]
+%D \checktwopassdata {test-2} [\twopassdata=x]
+%D \checktwopassdata {test-2} [\twopassdata=x]
+%D \gettwopassdata {test-2} [\twopassdata=x]
+%D \gettwopassdata {test-2} [\twopassdata=y]
+%D \gettwopassdata {test-2} [\twopassdata=z]
+%D \gettwopassdata {test-2} [\twopassdata=]
+%D
+%D \definetwopasslist{test-3}
+%D
+%D \lazysavetaggedtwopassdata{test-3}{1}{x}{a}
+%D \lazysavetaggedtwopassdata{test-3}{2}{y}{b}
+%D \lazysavetaggedtwopassdata{test-3}{3}{z}{c}
+%D
+%D \findtwopassdata{test-3}{x} [\twopassdata=a]
+%D \findtwopassdata{test-3}{y} [\twopassdata=b]
+%D \findtwopassdata{test-3}{z} [\twopassdata=c]
+%D \findtwopassdata{test-3}{w} [\twopassdata=]
+%D
+%D \definetwopasslist{test-4}
+%D
+%D \lazysavetwopassdata{test-4}{1}{A}
+%D \lazysavetwopassdata{test-4}{2}{B}
+%D \lazysavetwopassdata{test-4}{3}{C}
+%D
+%D \getfirsttwopassdata{test-4} [\twopassdata=A]
+%D \getlasttwopassdata {test-4} [\twopassdata=C]
+%D \getfirsttwopassdata{test-4} [\twopassdata=A]
+%D \getlasttwopassdata {test-4} [\twopassdata=C]
+%D \getfromtwopassdata {test-4}{1} [\twopassdata=A]
+%D \getfromtwopassdata {test-4}{3} [\twopassdata=C]
+%D \getfromtwopassdata {test-4}{2} [\twopassdata=B]
+%D \stopbuffer
+%D
+%D \getbuffer \typebuffer
+
\unprotect
-%D We save two pass information in the utility file.
+\let\alltwopasslists\empty
+\let\twopassentry \gobblethreearguments % permits loading a MK II file
+\let\twopassdata \empty
+\let\twopassdatalist\empty
+
+\newif\iftwopassdatafound
\addutilityreset{twopassentries}
diff --git a/tex/context/base/core-two.mkiv b/tex/context/base/core-two.mkiv
index f4062725a..f7dbd4c91 100644
--- a/tex/context/base/core-two.mkiv
+++ b/tex/context/base/core-two.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-two, % moved from core-uti
-%D version=2006.09.24,
+%D version=1997.03.31,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Two Pass Data,
%D author=Hans Hagen,
@@ -11,17 +11,82 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Two Pass Data}
+
+%D This is a rather old mechanism which has not changed much over
+%D time, apart from adding a few more selectors. This code used
+%D to be part of \type {core-uti}. The following examples demonstrate
+%D the interface.
+%D
+%D \startbuffer
+%D \definetwopasslist{test-1}
+%D
+%D \gettwopassdatalist{test-1} [\twopassdatalist=]
+%D \checktwopassdata {test-1} [\twopassdata=]
+%D \checktwopassdata {test-1} [\twopassdata=]
+%D \gettwopassdata {test-1} [\twopassdata=]
+%D \gettwopassdata {test-1} [\twopassdata=]
+%D
+%D \definetwopasslist{test-2}
+%D
+%D \lazysavetwopassdata{test-2}{1}{x}
+%D \lazysavetwopassdata{test-2}{2}{y}
+%D \lazysavetwopassdata{test-2}{3}{z}
+%D
+%D \gettwopassdatalist{test-2} [\twopassdatalist=x,y,z]
+%D \checktwopassdata {test-2} [\twopassdata=x]
+%D \checktwopassdata {test-2} [\twopassdata=x]
+%D \gettwopassdata {test-2} [\twopassdata=x]
+%D \gettwopassdata {test-2} [\twopassdata=y]
+%D \gettwopassdata {test-2} [\twopassdata=z]
+%D \gettwopassdata {test-2} [\twopassdata=]
+%D
+%D \definetwopasslist{test-3}
+%D
+%D \lazysavetaggedtwopassdata{test-3}{1}{x}{a}
+%D \lazysavetaggedtwopassdata{test-3}{2}{y}{b}
+%D \lazysavetaggedtwopassdata{test-3}{3}{z}{c}
+%D
+%D \findtwopassdata{test-3}{x} [\twopassdata=a]
+%D \findtwopassdata{test-3}{y} [\twopassdata=b]
+%D \findtwopassdata{test-3}{z} [\twopassdata=c]
+%D \findtwopassdata{test-3}{w} [\twopassdata=]
+%D
+%D \definetwopasslist{test-4}
+%D
+%D \lazysavetwopassdata{test-4}{1}{A}
+%D \lazysavetwopassdata{test-4}{2}{B}
+%D \lazysavetwopassdata{test-4}{3}{C}
+%D
+%D \getfirsttwopassdata{test-4} [\twopassdata=A]
+%D \getlasttwopassdata {test-4} [\twopassdata=C]
+%D \getfirsttwopassdata{test-4} [\twopassdata=A]
+%D \getlasttwopassdata {test-4} [\twopassdata=C]
+%D \getfromtwopassdata {test-4}{1} [\twopassdata=A]
+%D \getfromtwopassdata {test-4}{3} [\twopassdata=C]
+%D \getfromtwopassdata {test-4}{2} [\twopassdata=B]
+%D \stopbuffer
+%D
+%D \getbuffer \typebuffer
+
\unprotect
+\let\alltwopasslists\empty
+\let\twopassentry \empty
+\let\twopassentry \gobblethreearguments % permits loading a MK II file
+\let\twopassdatalist\empty
+
+\newif\iftwopassdatafound
+
\registerctxluafile{core-two}{1.001}
%D I'm not that sure if this behaves exactly like mkii. This needs a cleanup.
-\def\immediatesavetwopassdata #1#2#3{\expanded{\ctxlua {jobpasses.save('#1',"#3")}}}
-\def\savetwopassdata #1#2#3{\expanded{\ctxlatetua{jobpasses.save('#1',"#3")}}}
-\def\lazysavetwopassdata #1#2#3{\expanded{\ctxlatelua{jobpasses.save('#1',"#3")}}}
-\def\savetaggedtwopassdata #1#2#3#4{\expanded{\ctxlua {jobpasses.savetagged('#1','#3',"#4")}}}
-\def\lazysavetaggedtwopassdata#1#2#3#4{\expanded{\ctxlatelua{jobpasses.savetagged('#1','#3',"#4")}}}
+\def\immediatesavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlua {jobpasses.save('#1',"#3")}}}
+\def\savetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobpasses.save('#1',"#3")}}}
+\def\lazysavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatelua{jobpasses.save('#1',"#3")}}}
+\def\savetaggedtwopassdata #1#2#3#4{\normalexpanded{\noexpand\ctxlua {jobpasses.savetagged('#1','#3',"#4")}}}
+\def\lazysavetaggedtwopassdata#1#2#3#4{\normalexpanded{\noexpand\ctxlatelua{jobpasses.savetagged('#1','#3',"#4")}}}
% temp hack: needs a proper \starteverytimeluacode
diff --git a/tex/context/base/core-two.tex b/tex/context/base/core-two.tex
deleted file mode 100644
index 5a845c614..000000000
--- a/tex/context/base/core-two.tex
+++ /dev/null
@@ -1,103 +0,0 @@
-%D \module
-%D [ file=core-two, % moved from core-uti
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Two Pass Data,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Two Pass Data}
-
-%D This is a rather old mechanism which has not changed much over
-%D time, apart from adding a few more selectors. This code used
-%D to be part of \type {core-uti}. The following examples demonstrate
-%D the interface.
-%D
-%D \startbuffer
-%D \definetwopasslist{test-1}
-%D
-%D \gettwopassdatalist{test-1} [\twopassdatalist=]
-%D \checktwopassdata {test-1} [\twopassdata=]
-%D \checktwopassdata {test-1} [\twopassdata=]
-%D \gettwopassdata {test-1} [\twopassdata=]
-%D \gettwopassdata {test-1} [\twopassdata=]
-%D
-%D \definetwopasslist{test-2}
-%D
-%D \lazysavetwopassdata{test-2}{1}{x}
-%D \lazysavetwopassdata{test-2}{2}{y}
-%D \lazysavetwopassdata{test-2}{3}{z}
-%D
-%D \gettwopassdatalist{test-2} [\twopassdatalist=x,y,z]
-%D \checktwopassdata {test-2} [\twopassdata=x]
-%D \checktwopassdata {test-2} [\twopassdata=x]
-%D \gettwopassdata {test-2} [\twopassdata=x]
-%D \gettwopassdata {test-2} [\twopassdata=y]
-%D \gettwopassdata {test-2} [\twopassdata=z]
-%D \gettwopassdata {test-2} [\twopassdata=]
-%D
-%D \definetwopasslist{test-3}
-%D
-%D \lazysavetaggedtwopassdata{test-3}{1}{x}{a}
-%D \lazysavetaggedtwopassdata{test-3}{2}{y}{b}
-%D \lazysavetaggedtwopassdata{test-3}{3}{z}{c}
-%D
-%D \findtwopassdata{test-3}{x} [\twopassdata=a]
-%D \findtwopassdata{test-3}{y} [\twopassdata=b]
-%D \findtwopassdata{test-3}{z} [\twopassdata=c]
-%D \findtwopassdata{test-3}{w} [\twopassdata=]
-%D
-%D \definetwopasslist{test-4}
-%D
-%D \lazysavetwopassdata{test-4}{1}{A}
-%D \lazysavetwopassdata{test-4}{2}{B}
-%D \lazysavetwopassdata{test-4}{3}{C}
-%D
-%D \getfirsttwopassdata{test-4} [\twopassdata=A]
-%D \getlasttwopassdata {test-4} [\twopassdata=C]
-%D \getfirsttwopassdata{test-4} [\twopassdata=A]
-%D \getlasttwopassdata {test-4} [\twopassdata=C]
-%D \getfromtwopassdata {test-4}{1} [\twopassdata=A]
-%D \getfromtwopassdata {test-4}{3} [\twopassdata=C]
-%D \getfromtwopassdata {test-4}{2} [\twopassdata=B]
-%D \stopbuffer
-%D
-%D \getbuffer \typebuffer
-
-\unprotect
-
-\let\alltwopasslists\empty
-\let\twopassentry \empty
-\let\twopassdata \empty
-\let\twopassdatalist\empty
-
-\newif\iftwopassdatafound
-
-\let\savetwopassdata \gobblethreearguments
-\let\immediatesavetwopassdata \gobblethreearguments
-\let\lazysavetwopassdata \gobblethreearguments
-\let\savetaggedtwopassdata \gobblefourarguments
-\let\lazysavetaggedtwopassdata\gobblefourarguments
-
-\let\twopassentry \gobblethreearguments % permits loading a MK II file
-\let\loadtwopassdata\relax % permits loading a MK II file
-
-\let\definetwopasslist\gobbleoneargument
-
-\def\gettwopassdata #1{\let\twopassdata \empty \twopassdatafoundfalse}
-\def\checktwopassdata #1{\let\twopassdata \empty \twopassdatafoundfalse}
-\def\findtwopassdata #1#2{\let\twopassdata \empty \twopassdatafoundfalse}
-\def\getlasttwopassdata #1{\let\twopassdata \empty \twopassdatafoundfalse}
-\def\getfromtwopassdata #1#2{\let\twopassdata \empty \twopassdatafoundfalse}
-\def\gettwopassdatalist #1{\let\twopassdatalist\empty \twopassdatafoundfalse}
-\def\getnamedtwopassdatalist#1#2{\let#1 \empty \twopassdatafoundfalse}
-\def\doifelseintwopassdata #1#2{\secondoftwoarguments}
-
-\loadmarkfile{core-two}
-
-\protect \endinput
diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua
index fc99f67cb..20c63efd1 100644
--- a/tex/context/base/core-uti.lua
+++ b/tex/context/base/core-uti.lua
@@ -17,12 +17,13 @@ utility file under different setups, we now load a table once. This
saves much runtime but at the cost of more memory usage.</p>
--ldx]]--
-local format = string.format
+local sort, concat, format = table.sort, table.concat, string.format
+local next, type, tostring = next, type, tostring
if not jobs then jobs = { } end
if not job then jobs['main'] = { } end job = jobs['main']
-jobs.version = 1.01
+jobs.version = 1.10
--[[ldx--
<p>Variables are saved using in the previously defined table and passed
@@ -32,39 +33,206 @@ directly access the variable using a <l n='lua'/> call.</p>
local savelist, comment = { }, { }
-function job.comment(...)
- for _, str in ipairs({...}) do
- comment[#comment+1] = str
- end
+function job.comment(str)
+ comment[#comment+1] = str
end
job.comment(format("version: %1.2f",jobs.version))
job._save_, job._load_ = { }, { }
+function job.initialize(loadname,savename)
+ job.load(loadname)
+ main.register_stop_actions(function()
+ if not status.lasterrorstring or status.lasterrorstring == "" then
+ job.save(savename)
+ end
+ end)
+end
+
+function job.register(...) -- collected, tobesaved, initializer, finalizer
+ savelist[#savelist+1] = { ... }
+end
+
+-- as an example we implement variables
+
+jobvariables = jobvariables or { }
+jobvariables.collected = jobvariables.collected or { }
+jobvariables.tobesaved = jobvariables.tobesaved or { }
+
+jobvariables.checksums = jobvariables.checksums or { }
+
+if not jobvariables.checksums.old then jobvariables.checksums.old = md5.HEX("old") end
+if not jobvariables.checksums.new then jobvariables.checksums.new = md5.HEX("new") end
+
+job.register('jobvariables.checksums', jobvariables.checksums)
+
+local function initializer()
+ local r = jobvariables.collected.randomseed
+ if not r then
+ r = math.random()
+ end
+ math.randomseed(r)
+ jobvariables.tobesaved.randomseed = r
+ for cs, value in next, jobvariables.collected do
+ tex.sprint(format("\\xdef\\%s{%s}",cs,value))
+ end
+end
+
+job.register('jobvariables.collected', jobvariables.tobesaved, initializer)
+
+function jobvariables.save(cs,value)
+ jobvariables.tobesaved[cs] = value
+end
+
+-- experiment (bugged: some loop in running)
+
+-- for the moment here, very experimental stuff
+
+packer = packer or { }
+packer.version = 1.00
+
+local function hashed(t)
+ local s = { }
+ for k, v in next, t do
+ if type(v) == "table" then
+ s[#s+1] = k.."={"..hashed(v).."}"
+ else
+ s[#s+1] = k.."="..tostring(v)
+ end
+ end
+ sort(s)
+ return concat(s,",")
+end
+
+local function pack(t,keys,hash,index)
+ for k,v in next, t do
+ if type(v) == "table" then
+ pack(v,keys,hash,index)
+ end
+ if keys[k] and type(v) == "table" then
+ local h = hashed(v)
+ local i = hash[h]
+ if not i then
+ i = #index+1
+ index[i] = v
+ hash[h] = i
+ end
+ t[k] = i
+ end
+ end
+end
+
+local function unpack(t,keys,index)
+ for k,v in next, t do
+ if keys[k] and type(v) == "number" then
+ local iv = index[v]
+ if iv then
+ v = iv
+ t[k] = v
+ end
+ end
+ if type(v) == "table" then
+ unpack(v,keys,index)
+ end
+ end
+end
+
+function packer.new(keys,version)
+ return {
+ version = version or packer.version,
+ keys = table.tohash(keys),
+ hash = { },
+ index = { },
+ }
+end
+
+function packer.pack(t,p,shared)
+ if shared then
+ pack(t,p.keys,p.hash,p.index)
+ elseif not t.packer then
+ pack(t,p.keys,p.hash,p.index)
+ if #p.index > 0 then
+ t.packer = {
+ version = p.version or packer.version,
+ keys = p.keys,
+ index = p.index,
+ }
+ end
+ p.hash, p.index = { }, { }
+ end
+end
+
+function packer.unpack(t,p,shared)
+ if shared then
+ if p then
+ unpack(t,p.keys,p.index)
+ end
+ else
+ local tp = t.packer
+ if tp then
+ if tp.version == (p and p.version or packer.version) then
+ unpack(t,tp.keys,tp.index)
+ else
+ -- fatal error, wrong version
+ end
+ t.packer = nil
+ end
+ end
+end
+
+function packer.strip(p)
+ p.hash = nil
+end
+
+
+local packlist = {
+ "numbers",
+ "metadata",
+ "sectiondata",
+ "prefixdata",
+ "numberdata",
+ "pagedata",
+ "directives",
+ "specification",
+--~ "references",
+}
+
+local jobpacker = packer.new(packlist,1.01)
+
+job.pack = true
+
function job.save(filename)
- input.starttiming(job._save_)
+ statistics.starttiming(job._save_)
local f = io.open(filename,'w')
if f then
- for _, str in ipairs(comment) do
- f:write("-- ",str,"\n")
+ for c=1,#comment do
+ f:write("-- ",comment[c],"\n")
end
f:write("\n")
- for _, list in ipairs(savelist) do
+ for l=1,#savelist do
+ local list = savelist[l]
local target, data, finalizer = list[1], list[2], list[4]
if type(finalizer) == "function" then
finalizer()
end
+ if job.pack then
+ packer.pack(data,jobpacker,true)
+ end
f:write(aux.definetable(target),"\n")
f:write(table.serialize(data,target,true,true),"\n")
end
+ if job.pack then
+ packer.strip(jobpacker)
+ f:write(table.serialize(jobpacker,"job.packer",true,true),"\n")
+ end
f:close()
end
- input.stoptiming(job._save_)
+ statistics.stoptiming(job._save_)
end
function job.load(filename)
- input.starttiming(job._load_)
+ statistics.starttiming(job._load_)
local data = io.loaddata(filename)
if data and data ~= "" then
local version = tonumber(data:match("^-- version: ([%d%.]+)"))
@@ -72,46 +240,51 @@ function job.load(filename)
logs.report("job","version mismatch with jobfile: %s <> %s", version or "?", jobs.version)
else
loadstring(data)()
- for _, list in ipairs(savelist) do
+ for l=1,#savelist do
+ local list = savelist[l]
local target, initializer = list[1], list[3]
+ packer.unpack(aux.accesstable(target),job.packer,true)
if type(initializer) == "function" then
initializer(aux.accesstable(target))
end
end
+ job.packer = nil
end
end
- input.stoptiming(job._load_)
-end
-
-function job.initialize(loadname,savename)
- job.load(loadname)
- table.insert(input.stop_actions, function()
- if not status.lasterrorstring or status.lasterrorstring == "" then
- job.save(savename)
- end
- end)
+ statistics.stoptiming(job._load_)
end
-function job.register(...) -- collected, tobesaved, initializer, finalizer
- savelist[#savelist+1] = { ... }
-end
+-- eventually this will end up in strc-ini
--- as an example we implement variables
-
-jobvariables = jobvariables or { }
-jobvariables.collected = jobvariables.collected or { }
-jobvariables.tobesaved = jobvariables.tobesaved or { }
+statistics.register("startup time", function()
+ if statistics.elapsedindeed(ctx) then
+ return format("%s seconds (including runtime option file processing)", statistics.elapsedtime(ctx))
+ end
+end)
-local function initializer()
- for cs, value in pairs(jobvariables.collected) do
- tex.sprint(string.format("\\xdef\\%s{%s}",cs,value))
+statistics.register("jobdata time",function()
+ if statistics.elapsedindeed(job._save_) or statistics.elapsedindeed(job._load_) then
+ return format("%s seconds saving, %s seconds loading", statistics.elapsedtime(job._save_), statistics.elapsedtime(job._load_))
end
-end
+end)
-job.register('jobvariables.collected', jobvariables.tobesaved, initializer)
+statistics.register("callbacks", function()
+ local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0
+ local pages = tex.count['realpageno'] - 1
+ if pages > 1 then
+ return format("direct: %s, indirect: %s, total: %s (%i per page)", total-indirect, indirect, total, total/pages)
+ else
+ return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total)
+ end
+end)
-function jobvariables.save(cs,value)
- jobvariables.tobesaved[cs] = value
+function statistics.formatruntime(runtime)
+ local shipped = tex.count['nofshipouts']
+ local pages = tex.count['realpageno'] - 1
+ if shipped > 0 or pages > 0 then
+ local persecond = shipped / runtime
+ return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond)
+ else
+ return format("%s seconds",runtime)
+ end
end
-
-
diff --git a/tex/context/base/core-uti.mkii b/tex/context/base/core-uti.mkii
index 8d8fc6dcb..b348ba358 100644
--- a/tex/context/base/core-uti.mkii
+++ b/tex/context/base/core-uti.mkii
@@ -11,6 +11,154 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Utility File Handling}
+
+\unprotect
+
+% todo : safe lan etc too
+% todo : load all commands at once (tok)
+% todo : merge status info patch into tui file (language, encoding, etc),
+
+% Utility-file
+%
+% De onderstaande macro's ondersteunen het gebruik van de
+% zogeheten utility-file. Alle extern onder te brengen
+% informatie wordt opgeslagen in de file \jobname.tui, tenzij
+% er selectief pagina's worden gezet. In dat geval wordt de
+% file \jobname.tmp gebruikt. Informatie wordt ingelezen uit
+% de file \jobname.tuo, welke door TeXUtil wordt aangemaakt.
+
+\edef\utilityversion{1998.07.07} % was: 1996.03.15 % status variables
+\edef\utilityversion{1998.12.20} % was: 1998.07.07 % index attributes
+\edef\utilityversion{2003.07.19} % was: 1998.12.20 % object pages
+\edef\utilityversion{2006.06.23} % was: 2003.07.19 % -- instead of :
+\edef\utilityversion{2006.09.21} % pt in pos
+\edef\utilityversion{2008.10.14} % moved more to lua in mkiv
+
+% Bepaalde commando's worden als string weggeschreven. Deze
+% zijn aan het eind van deze file gedefinieerd.
+
+% Om een opbouw van spaties te voorkomen (???) moet ^^M een
+% andere betekenis krijgen:
+%
+% \catcode`\^^M=14 (comment)
+%
+% read file
+%
+% \catcode`\^^M=5 (end of line)
+
+\newwrite\utility@tui
+\newif\ifutilitydone
+
+\ifx\sectionseparator\undefined \def\sectionseparator{-} \fi
+
+\def\@@utilityerrormessage
+ {\showmessage\m!systems8\empty
+ \globallet\@@utilityerrormessage\relax}
+
+\def\thisisutilityversion#1%
+ {\doifelse\utilityversion{#1}%
+ {\checksectionseparator}
+ {\@@utilityerrormessage\resetutilities\endinput}}
+
+\def\checksectionseparator % catches backward compatibility conflict
+ {}% \doifnot\sectionseparator:\endinput} % this dependency may go in a few years
+
+\def\dosplitofffoliopart[#1--#2--#3]{#3}
+
+\def\thisissectionseparator#1%
+ {\bgroup
+ \globallet\checksectionseparator\relax
+ \defconvertedcommand \asciia\sectionseparator
+ \defconvertedargument\asciib{#1}%
+ \expanded{\gdef\noexpand\dosplitofffoliopart[####1\sectionseparator
+ \sectionseparator####2\sectionseparator\sectionseparator####3]{####3}}%
+ \ifx\asciia\asciib
+ \egroup
+ \else
+ \egroup
+ % todo \@@utilityerrormessage
+ \resetutilities
+ \endinput
+ \fi}
+
+\def\writeutility {\write\utility@tui}
+\def\writeutilitycommand#1{\write\utility@tui{c \string#1}}
+
+% less tokens
+%
+% \def\immediatewriteutility {\immediate\writeutility}
+% \def\immediatewriteutilitycommand{\immediate\writeutilitycommand}
+%
+% more flexible (for overloading)
+
+\def\immediatewriteutility {\immediate\write\utility@tui}
+\def\immediatewriteutilitycommand#1{\immediate\write\utility@tui{c \string#1}}
+
+% as in:
+
+\def\cwriteutility#1%
+ {\write\utility@tui{\noexpand\checkedutility{\number\nofshipouts}{#1}}}
+
+\def\cwriteutilitycommand#1%
+ {\write\utility@tui{\noexpand\checkedutility{\number\nofshipouts}{c \string#1}}}
+
+\let\checkedutility\secondoftwoarguments
+
+\def\docheckedutility#1#2{\ifnum#1=\nofshipouts#2\else\letterpercent\fi}
+
+\prependtoks
+ \let\checkedutility\docheckedutility
+\to \everybeforeshipout
+
+% Better use marks.
+
+\newtoks \everyopenutilities
+\newtoks \everycloseutilities
+\newtoks \everycheckutilities
+
+\def\openutilities {\the\everyopenutilities } % \global\everyopenutilities\emptytoks
+\def\closeutilities{\the\everycloseutilities}
+\def\checkutilities{\the\everycheckutilities}
+
+\appendtoks
+ \let\writeutility \cwriteutility
+ \let\writeutilitycommand \cwriteutilitycommand
+ %\let\immediatewriteutility \cimmediatewriteutility
+ %\let\immediatewriteutilitycommand\cimmediatewriteutilitycommand
+ \let\checkutilities \relax
+\to \everycheckutilities
+
+\appendtoks
+ \immediate\openout\utility@tui\jobname.\f!inputextension
+ \immediatewriteutilitycommand{\thisissectionseparator{\sectionseparator}}% for the moment
+ \immediatewriteutilitycommand{\thisisutilityversion {\utilityversion }}% in this order
+\to \everyopenutilities
+
+\appendtoks
+% \immediate\closeout\utility@tui % niet echt nodig
+ \reportutilityproblems
+ % should be a message :
+ \let\writeutilitycommand \gobbleoneargument
+ \let\writeutility \gobbleoneargument
+ \let\immediatewriteutilitycommand\gobbleoneargument
+ \let\immediatewriteutility \gobbleoneargument
+\to \everycloseutilities
+
+% \def\reopenutilities
+% {\immediate\closeout\utility@tui
+% \openutilities}
+
+\def\abortutilitygeneration
+ {\immediatewriteutilitycommand\utilitygenerationaborted
+ \immediatewriteutility{q {quit}}}
+
+\def\utilitygenerationaborted
+ {\showmessage\m!systems{21}\empty
+ \globallet\utilitygenerationaborted\endinput
+ \gdef\reportutilityproblems{\showmessage\m!systems{22}\empty}%
+ \endinput}
+
\def\savecurrentvalue#1#2%
{\immediatewriteutilitycommand{\initializevariable\string#1{#2}}}
@@ -20,6 +168,46 @@
\globallet\initializevariable\gobbletwoarguments
\to \everyafterutilityread
+\let\reportutilityproblems\relax
+
+\newtoks\utilityresetlist
+
+\def\addutilityreset#1%
+ {\@EA\appendtoks\csname\s!reset#1\endcsname\to\utilityresetlist}
+
+\def\resetutilities
+ {\the\utilityresetlist}
+
+% #1=type #2=file #3=melding #4=voor #5=na
+%
+% Er wordt gegroepeerd. Als binnen een lijst (bijvoorbeeld) de
+% \leftskip is aangepast, maar nog geen \par is gegeven, dan
+% geldt buiten de groep de oude \leftskip. Aan #5 kan dan
+% ook \par worden meegegeven om de paragraaf af te sluiten.
+
+\newif\ifdoinpututilities
+\newif\ifunprotectutilities % voor't geval er \v!xxxxxx's zijn
+
+\def\currentutilityfilename{\jobname}
+
+% we need to pop and push, else problems with reading
+% utility files (toc) in xml mode and (e.g.) in a toc
+% entry doing a doifmode
+%
+% the following is not ok because we have no way to signal
+% xml content (yet), so for the moment we use this:
+
+\appendtoks
+ \ifprocessingXML
+ \processingXMLfalse
+ \enableXML
+ \catcode`\\=\@@escape
+ \catcode`\{=\@@begingroup
+ \catcode`\}=\@@endgroup
+ \catcode`\%=\@@comment\relax
+ \fi
+\to \everybeforeutilityread
+
\edef\testbytesequence
{\rawcharacter{7}%
\rawcharacter{27}%
@@ -36,12 +224,123 @@
\fi
\global\let\thisisbytesequence\gobbleoneargument}
-\beginXETEX
+\ifnum\texengine=\xetexengine
\let\testbytesequence\empty
-\endXETEX
+\fi
\appendtoks
\immediatewriteutilitycommand{\thisisbytesequence{\testbytesequence}}%
\to \everyopenutilities
-\endinput
+\long\def\doutilities#1#2#3#4#5% % introduceren in utility file
+ {\resetutilities
+ % more than one utility thing can be handled in one pass,
+ % for instance lists, so we process ##1 as list
+ \def\douticommand##1{\csname\s!set##1\endcsname}%
+ \processcommacommand[#1]\douticommand
+ \begingroup
+ \def\currentutilityfilename{#2}%
+ \notesenabledfalse
+ \doinpututilitiestrue
+ \global\utilitydonefalse
+ \pushendofline % geeft problemen zodra andere file wordt ingelezen
+ \pushcatcodetable
+ \setcatcodetable\ctxcatcodes
+ \ifunprotectutilities % nog nodig ?
+ \unprotect
+ \fi
+ #4%
+ \the\everybeforeutilityread
+ \readjobfile{#2.\f!outputextension}\donothing\donothing
+ \the\everyafterutilityread
+ \popcatcodetable
+ #5%
+ \relax
+ \ifunprotectutilities
+ \protect
+ \fi
+ \popendofline
+ \ifutilitydone\else
+ \doifsomething{#3}
+ {\showmessage\m!systems9{{#3}}%
+ \doifconcepttracing
+ {\blank
+ \setmessagetext\m!systems9{{#3}}%
+ \type{[\currentmessagetext]}%
+ \blank}}%
+ \fi
+ \endgroup}
+
+% Default-instellingen (verborgen)
+
+\prependtoks \resetutilities \to \everyjob
+
+% Experiment
+%
+% \installprogram{Hello World}
+% \installprogram[hw]{Hello World}
+% \installedprogram[hw]
+
+\def\installprogram
+ {\dosingleempty\doinstallprogram}
+
+\def\doinstallprogram[#1]#2%
+ {\doifelsenothing{#1}
+ {\dodoinstallprogram{#2}}
+ {\setvalue{\??up#1}{\dodoinstallprogram{#2}}}}
+
+\def\dodoinstallprogram#1%
+ {\immediatewriteutility{e p {#1}}}
+
+\def\installedprogram[#1]%
+ {\getvalue{\??up#1}}
+
+% \writeplugindata{texutil}{{alpha}}
+% \writeplugindata{texutil}{{beta}}
+% \writeplugindata{texutil}{{gamma}}
+% \writeplugindata{texutil}{{delta}}
+%
+% \loadplugindata {plugintest}
+
+\def\immediatewriteplugindata#1#2%
+ {\immediatewriteutility{p u {#1} #2}}
+
+\def\writeplugindata#1#2%
+ {\writeutility{p u {#1} #2}}
+
+\def\loadplugindata#1%
+ {\doutilities{#1}\jobname\empty\relax\relax}
+
+% \plugincommand{\command{}{}{}}
+%
+% this way we can catch undefined commands
+
+\long\def\plugincommand#1%
+ {\doplugincommand#1\relax}
+
+\long\def\doplugincommand#1%
+ {\ifx#1\undefined
+ \expandafter\noplugincommand
+ \else
+ \expandafter#1%
+ \fi}
+
+\long\def\noplugincommand#1\relax
+ {}
+
+% \addutilityreset{plugintest}
+%
+% \def\resetplugintest{\let\plugintest\gobbletwoarguments}
+% \def\setplugintest {\let\plugintest\writestatus}
+%
+% \installplugin
+% {plugintest}
+% {\let\plugintest\gobbletwoarguments}
+% {\let\plugintest\writestatus}
+
+\long\def\installplugin#1#2#3%
+ {\addutilityreset {#1}%
+ \long\setvalue{\s!reset#1}{#2}%
+ \long\setvalue{\s!set #1}{#3}}
+
+\protect \endinput
diff --git a/tex/context/base/core-uti.mkiv b/tex/context/base/core-uti.mkiv
index ddbc47311..77cf91dd9 100644
--- a/tex/context/base/core-uti.mkiv
+++ b/tex/context/base/core-uti.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-uti,
-%D version=2006.09.19,
+%D version=1997.03.31, % 2006.09.19 mkiv
%D title=\CONTEXT\ Core Macros,
%D subtitle=Utility File Handling,
%D author=Hans Hagen,
@@ -11,67 +11,86 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
-
-\registerctxluafile{core-uti}{1.001}
+%D Most will disappear!
-%D We need a way to pass strings safely to \LUA\ without the
-%D need for tricky escaping. Compare:
-%D
-%D \starttyping
-%D \ctxlua {something("anything tricky can go here")}
-%D \ctxlua {something([\luastringsep[anything tricky can go here]\luastringsep])}
-%D \stoptyping
+\writestatus{loading}{ConTeXt Core Macros / Utility File Handling}
-\def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems
-
-\edef\!!bs{[\luastringsep[}
-\edef\!!es{]\luastringsep]}
-
-%D We have a the following available as primitive so there is no need
-%D for it:
-%D
-%D \starttyping
-%D \long\edef\luaescapestring#1{\!!bs#1\!!es}
-%D \stoptyping
+\unprotect
-% variables
+\registerctxluafile{core-uti}{1.001}
\def\savecurrentvalue#1#2%
{\ctxlua{jobvariables.save("\strippedcsname#1","#2")}}
-% temp
-
+\let\initializevariable\gobbletwoarguments % mkii/mkiv
\let\thisisbytesequence\gobbleoneargument
-% wrong place but we need to have it someplace
+\appendtoks
+ \globallet\initializevariable\gobbletwoarguments
+\to \everyafterutilityread
\appendtoks
- \ctxlua{input.storage.dump()}%
+ \ctxlua{storage.dump()}%
\to \everydump
\appendtoks
- \ctxlua{input.storage.finalize()}%
+ \ctxlua{storage.finalize()}%
\to \everyfinalizeluacode
\appendtoks
\ctxlua{nodes.cleanup_reserved()}%
\to \everydump
-% new
-
-% this loads and also sets the saving
-
\appendtoks
\ctxlua {
- job.comment(
- "file: \jobname",
- "format: \contextformat",
- "stamp: \contextversion",
- "escape: \!!bs\space...\space\!!es"
- )
+ job.comment("file: \jobname")
+ job.comment("format: \contextformat")
+ job.comment("stamp: \contextversion")
+ job.comment("escape: \!!bs\space...\space\!!es")
job.initialize("\jobname.tuc","\jobname.tua")
}%
\to \everystarttext
+% cleaner, for the moment
+
+% \appendtoks
+% \ctxlua {
+% os.remove("\jobname.tui")
+% os.remove("\jobname.tuo")
+% }%
+% \to \everystarttext
+
+% keep this for a while
+
+\newif\ifutilitydone
+\newif\ifdoinpututilities
+\newif\ifunprotectutilities
+
+\let\writeutility \gobbleoneargument
+\let\writeutilitycommand \gobbleoneargument
+\let\immediatewriteutility \gobbleoneargument
+\let\immediatewriteutilitycommand\gobbleoneargument
+\let\cwriteutility \gobbleoneargument
+\let\cwriteutilitycommand \gobbleoneargument
+\let\checkedutility \secondoftwoarguments
+\let\doutilities \gobblefivearguments
+\let\abortutilitygeneration \relax
+
+\newtoks \everyopenutilities \let\openutilities \relax
+\newtoks \everycloseutilities \let\closeutilities\relax
+\newtoks \everycheckutilities \let\checkutilities\relax
+\newtoks \utilityresetlist
+
+\def\addutilityreset#1{\@EA\appendtoks\csname\s!reset#1\endcsname\to\utilityresetlist}
+\def\resetutilities {\the\utilityresetlist}
+
+\def\currentutilityfilename{\jobname}
+
+\prependtoks \resetutilities \to \everyjob
+
+\def\installprogram {\dosingleempty\doinstallprogram}
+\def\doinstallprogram[#1]{\gobbleoneargument}
+\def\installedprogram[#1]{}
+\let\installplugin \gobblethreearguments
+
\protect \endinput
diff --git a/tex/context/base/core-uti.tex b/tex/context/base/core-uti.tex
deleted file mode 100644
index e84a6db5c..000000000
--- a/tex/context/base/core-uti.tex
+++ /dev/null
@@ -1,382 +0,0 @@
-%D \module
-%D [ file=core-uti,
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Utility File Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Utility File Handling}
-
-\unprotect
-
-% todo : safe lan etc too
-% todo : load all commands at once (tok)
-% todo : merge status info patch into tui file (language, encoding, etc),
-
-% Utility-file
-%
-% De onderstaande macro's ondersteunen het gebruik van de
-% zogeheten utility-file. Alle extern onder te brengen
-% informatie wordt opgeslagen in de file \jobname.tui, tenzij
-% er selectief pagina's worden gezet. In dat geval wordt de
-% file \jobname.tmp gebruikt. Informatie wordt ingelezen uit
-% de file \jobname.tuo, welke door TeXUtil wordt aangemaakt.
-
-\edef\utilityversion{1998.07.07} % was: 1996.03.15 % status variables
-\edef\utilityversion{1998.12.20} % was: 1998.07.07 % index attributes
-\edef\utilityversion{2003.07.19} % was: 1998.12.20 % object pages
-\edef\utilityversion{2006.06.23} % was: 2003.07.19 % -- instead of :
-\edef\utilityversion{2006.09.21} % pt in pos
-\edef\utilityversion{2008.10.14} % moved more to lua in mkiv
-
-% Bepaalde commando's worden als string weggeschreven. Deze
-% zijn aan het eind van deze file gedefinieerd.
-
-% Om een opbouw van spaties te voorkomen (???) moet ^^M een
-% andere betekenis krijgen:
-%
-% \catcode`\^^M=14 (comment)
-%
-% read file
-%
-% \catcode`\^^M=5 (end of line)
-
-\newwrite\utility@tui
-\newif\ifutilitydone
-
-\def\@@utilityerrormessage
- {\showmessage\m!systems8\empty
- \globallet\@@utilityerrormessage\relax}
-
-\def\thisisutilityversion#1%
- {\doifelse\utilityversion{#1}%
- {\checksectionseparator}
- {\@@utilityerrormessage\resetutilities\endinput}}
-
-\def\checksectionseparator % catches backward compatibility conflict
- {}% \doifnot\sectionseparator:\endinput} % this dependency may go in a few years
-
-\def\dosplitofffoliopart[#1--#2--#3]{#3}
-
-\def\thisissectionseparator#1%
- {\bgroup
- \globallet\checksectionseparator\relax
- \defconvertedcommand \asciia\sectionseparator
- \defconvertedargument\asciib{#1}%
- \expanded{\gdef\noexpand\dosplitofffoliopart[####1\sectionseparator
- \sectionseparator####2\sectionseparator\sectionseparator####3]{####3}}%
- \ifx\asciia\asciib
- \egroup
- \else
- \egroup
- % todo \@@utilityerrormessage
- \resetutilities
- \endinput
- \fi}
-
-\def\writeutility {\write\utility@tui}
-\def\writeutilitycommand#1{\write\utility@tui{c \string#1}}
-
-% less tokens
-%
-% \def\immediatewriteutility {\immediate\writeutility}
-% \def\immediatewriteutilitycommand{\immediate\writeutilitycommand}
-%
-% more flexible (for overloading)
-
-\def\immediatewriteutility {\immediate\write\utility@tui}
-\def\immediatewriteutilitycommand#1{\immediate\write\utility@tui{c \string#1}}
-
-% as in:
-
-\def\cwriteutility#1%
- {\write\utility@tui{\noexpand\checkedutility{\number\nofshipouts}{#1}}}
-
-\def\cwriteutilitycommand#1%
- {\write\utility@tui{\noexpand\checkedutility{\number\nofshipouts}{c \string#1}}}
-
-\let\checkedutility\secondoftwoarguments
-
-\def\docheckedutility#1#2{\ifnum#1=\nofshipouts#2\else\letterpercent\fi}
-
-\prependtoks
- \let\checkedutility\docheckedutility
-\to \everybeforeshipout
-
-% Better use marks.
-
-\newtoks \everyopenutilities
-\newtoks \everycloseutilities
-\newtoks \everycheckutilities
-
-\def\openutilities {\the\everyopenutilities } % \global\everyopenutilities\emptytoks
-\def\closeutilities{\the\everycloseutilities}
-\def\checkutilities{\the\everycheckutilities}
-
-\appendtoks
- \let\writeutility \cwriteutility
- \let\writeutilitycommand \cwriteutilitycommand
- %\let\immediatewriteutility \cimmediatewriteutility
- %\let\immediatewriteutilitycommand\cimmediatewriteutilitycommand
- \let\checkutilities \relax
-\to \everycheckutilities
-
-\appendtoks
- \immediate\openout\utility@tui\jobname.\f!inputextension
- \immediatewriteutilitycommand{\thisissectionseparator{\sectionseparator}}% for the moment
- \immediatewriteutilitycommand{\thisisutilityversion {\utilityversion }}% in this order
-\to \everyopenutilities
-
-\appendtoks
-% \immediate\closeout\utility@tui % niet echt nodig
- \reportutilityproblems
- % should be a message :
- \let\writeutilitycommand \gobbleoneargument
- \let\writeutility \gobbleoneargument
- \let\immediatewriteutilitycommand\gobbleoneargument
- \let\immediatewriteutility \gobbleoneargument
-\to \everycloseutilities
-
-% \def\reopenutilities
-% {\immediate\closeout\utility@tui
-% \openutilities}
-
-\def\abortutilitygeneration
- {\immediatewriteutilitycommand\utilitygenerationaborted
- \immediatewriteutility{q {quit}}}
-
-\def\utilitygenerationaborted
- {\showmessage\m!systems{21}\empty
- \globallet\utilitygenerationaborted\endinput
- \gdef\reportutilityproblems{\showmessage\m!systems{22}\empty}%
- \endinput}
-
-\let\savecurrentvalue \gobbletwoarguments % mkii/mkiv
-\let\initializevariable\gobbletwoarguments % mkii/mkiv
-
-\appendtoks
- \globallet\initializevariable\gobbletwoarguments
-\to \everyafterutilityread
-
-\let\reportutilityproblems\relax
-\let\utilityresetlist \empty
-
-\newtoks\utilityresetlist
-
-\def\addutilityreset#1%
- {\@EA\appendtoks\csname\s!reset#1\endcsname\to\utilityresetlist}
-
-\def\resetutilities
- {\the\utilityresetlist}
-
-% #1=type
-% #2=file
-% #3=melding
-
-% #4=voor
-% #5=na
-
-% Er wordt gegroepeerd. Als binnen een lijst (bijvoorbeeld) de
-% \leftskip is aangepast, maar nog geen \par is gegeven, dan
-% geldt buiten de groep de oude \leftskip. Aan #5 kan dan
-% ook \par worden meegegeven om de paragraaf af te sluiten.
-
-\newif\ifdoinpututilities
-\newif\ifunprotectutilities % voor't geval er \v!xxxxxx's zijn
-
-\def\currentutilityfilename{\jobname}
-
-% \long\def\doutilities#1#2#3#4#5% % introduceren in utility file
-% {\restorecatcodes
-% \resetutilities
-% % more than one utility thing can be handled in one pass,
-% % for instance lists, so we process ##1 as list
-% \def\douticommand##1{\csname\s!set##1\endcsname}%
-% \processcommacommand[#1]\douticommand
-% \begingroup
-% \def\currentutilityfilename{#2}%
-% \notesenabledfalse
-% \doinpututilitiestrue
-% \global\utilitydonefalse
-% \catcode`\\=\@@escape
-% \catcode`\{=\@@begingroup
-% \catcode`\}=\@@endgroup
-% \catcode`\%=\@@comment\relax
-% \pushendofline % geeft problemen zodra andere file wordt ingelezen
-% \ifunprotectutilities % nog nodig ?
-% \unprotect
-% \fi
-% \ifnum\catcode`\@=\@@active \else
-% \catcode`\@=\@@letter % permits expanded commands with \@'s
-% \fi
-% \ifnum\catcode`\!=\@@active \else
-% \catcode`\!=\@@letter % permits multilingual constants
-% \fi
-% #4%
-% \the\everybeforeutilityread
-% \readjobfile{#2.\f!outputextension}\donothing\donothing
-% \the\everyafterutilityread
-% #5%
-% \relax
-% \ifunprotectutilities
-% \protect
-% \fi
-% \popendofline
-% \ifutilitydone\else
-% \doifsomething{#3}
-% {\showmessage\m!systems9{{#3}}%
-% \doifconcepttracing
-% {\blank
-% \type{[\currentmessagetext]}%
-% \blank}}%
-% \fi
-% \endgroup}
-
-% we need to pop and push, else problems with reading
-% utility files (toc) in xml mode and (e.g.) in a toc
-% entry doing a doifmode
-%
-% the following is not ok because we have no way to signal
-% xml content (yet), so for the moment we use this:
-
-\appendtoks
- \ifprocessingXML
- \processingXMLfalse
- \enableXML
- \catcode`\\=\@@escape
- \catcode`\{=\@@begingroup
- \catcode`\}=\@@endgroup
- \catcode`\%=\@@comment\relax
- \fi
-\to \everybeforeutilityread
-
-\long\def\doutilities#1#2#3#4#5% % introduceren in utility file
- {\resetutilities
- % more than one utility thing can be handled in one pass,
- % for instance lists, so we process ##1 as list
- \def\douticommand##1{\csname\s!set##1\endcsname}%
- \processcommacommand[#1]\douticommand
- \begingroup
- \def\currentutilityfilename{#2}%
- \notesenabledfalse
- \doinpututilitiestrue
- \global\utilitydonefalse
- \pushendofline % geeft problemen zodra andere file wordt ingelezen
- \pushcatcodetable
- \setcatcodetable\ctxcatcodes
- \ifunprotectutilities % nog nodig ?
- \unprotect
- \fi
- #4%
- \the\everybeforeutilityread
- \readjobfile{#2.\f!outputextension}\donothing\donothing
- \the\everyafterutilityread
- \popcatcodetable
- #5%
- \relax
- \ifunprotectutilities
- \protect
- \fi
- \popendofline
- \ifutilitydone\else
- \doifsomething{#3}
- {\showmessage\m!systems9{{#3}}%
- \doifconcepttracing
- {\blank
- \setmessagetext\m!systems9{{#3}}%
- \type{[\currentmessagetext]}%
- \blank}}%
- \fi
- \endgroup}
-
-% Default-instellingen (verborgen)
-
-\prependtoks \resetutilities \to \everyjob
-
-% Experiment
-%
-% \installprogram{Hello World}
-% \installprogram[hw]{Hello World}
-% \installedprogram[hw]
-
-\def\installprogram
- {\dosingleempty\doinstallprogram}
-
-\def\doinstallprogram[#1]#2%
- {\doifelsenothing{#1}
- {\dodoinstallprogram{#2}}
- {\setvalue{\??up#1}{\dodoinstallprogram{#2}}}}
-
-% \def\doinstallprogram[#1][#2]% less code
-% {\doifsomething{#1}{\setvalue{\??up#1}}{\dodoinstallprogram{#2}}}
-
-\def\dodoinstallprogram#1%
- {\immediatewriteutility{e p {#1}}}
-
-\def\installedprogram[#1]%
- {\getvalue{\??up#1}}
-
-% \writeplugindata{texutil}{{alpha}}
-% \writeplugindata{texutil}{{beta}}
-% \writeplugindata{texutil}{{gamma}}
-% \writeplugindata{texutil}{{delta}}
-%
-% \loadplugindata {plugintest}
-
-\def\immediatewriteplugindata#1#2%
- {\immediatewriteutility{p u {#1} #2}}
-
-\def\writeplugindata#1#2%
- {\writeutility{p u {#1} #2}}
-
-\def\loadplugindata#1%
- {\doutilities{#1}\jobname\empty\relax\relax}
-
-% \plugincommand{\command{}{}{}}
-%
-% this way we can catch undefined commands
-
-\long\def\plugincommand#1%
- {\doplugincommand#1\relax}
-
-\long\def\doplugincommand#1%
- {\ifx#1\undefined
- \expandafter\noplugincommand
- \else
- \expandafter#1%
- \fi}
-
-% shorter:
-%
-% \long\def\doplugincommand#1%
-% {\ifx#1\undefined\expandafter\noplugincommand\fi#1}
-
-\long\def\noplugincommand#1\relax
- {}
-
-% \addutilityreset{plugintest}
-%
-% \def\resetplugintest{\let\plugintest\gobbletwoarguments}
-% \def\setplugintest {\let\plugintest\writestatus}
-%
-% \installplugin
-% {plugintest}
-% {\let\plugintest\gobbletwoarguments}
-% {\let\plugintest\writestatus}
-
-\long\def\installplugin#1#2#3%
- {\addutilityreset {#1}%
- \long\setvalue{\s!reset#1}{#2}%
- \long\setvalue{\s!set #1}{#3}}
-
-% plugins
-
-\loadmarkfile{core-uti}
-
-\protect \endinput
diff --git a/tex/context/base/core-var.tex b/tex/context/base/core-var.tex
index 38c434e0b..4de1b8718 100644
--- a/tex/context/base/core-var.tex
+++ b/tex/context/base/core-var.tex
@@ -11,304 +11,121 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Variables}
+\writestatus{loading}{ConTeXt Core Macros / Variables}
\unprotect
-%D Modes:
-%D
-%D \starttyping
-%D \enablemode[screen,paper,bound]
-%D
-%D \doifmodeelse {paper} {this} {that}
-%D \doifmode {paper,screen} {this}
-%D \doifnotmode {paper,bound} {that}
-%D
-%D \startmode [list]
-%D \stopmode
-%D
-%D \startnotmode [list]
-%D \stopnotmode
-%D \stoptyping
-%D
-%D system modes have a * as prefix
+%D We introduce a couple of variables that are used all over
+%D \CONTEXT. Alternatively we could define them in each module
+%D but as they are part of the bigger picture we prefer to do
+%D it here.
+
+%D \macros
+%D {every...}
%D
-%D Sometimes, we want to prevent a mode for being set. Think
-%D of situations where a style enables a mode, but an outer
-%D level style does not want that. Preventing can be
-%D considered a permanent disabling on forehand.
-
-% \def\systemmodeprefix{*}
-%
-% \let\currentmode \empty
-% \let\preventedmodes\empty
-%
-% \def\preventmode[#1]%
-% {\expanded{\addtocommalist{#1}\noexpand\preventedmodes}}
-%
-% \def\enablemode[#1]%
-% {\expanded
-% {\doifnotinset{#1}{\preventedmodes}
-% {\noexpand\addtocommalist{#1}\noexpand\currentmode}}}
-%
-% \def\disablemode[#1]%
-% {\expanded{\removefromcommalist{#1}\noexpand\currentmode}}
-%
-% \def\doifmodeelse{\unprotect\dodoifmodeelse}
-% \def\doifmode {\unprotect\dodoifmode }
-% \def\doifnotmode {\unprotect\dodoifnotmode }
-% \def\startmode {\unprotect\dostartmode }
-% \def\startnotmode{\unprotect\dostartnotmode}
-%
-% \long\def\dodoifmodeelse#1%
-% {\protect\expanded{\doifcommonelse{#1}{\currentmode}}}
-%
-% \long\def\dodoifmode#1%
-% {\protect\expanded{\doifcommon {#1}{\currentmode}}}
-%
-% \long\def\dodoifnotmode#1%
-% {\protect\expanded{\doifnotcommon {#1}{\currentmode}}}
-%
-% \let\stopmode \relax
-% \let\stopnotmode\relax
-%
-% \long\def\dostartmode[#1]%
-% {\protect
-% \expanded{\doifnotcommon{#1}{\currentmode}}{\gobbleuntil\stopmode}}
-%
-% \long\def\dostartnotmode[#1]%
-% {\protect
-% \expanded{\doifcommon {#1}{\currentmode}}{\gobbleuntil\stopnotmode}}
-%
-% \def\doifallmodeselse{\unprotect\dodoifallmodeselse}
-% \def\doifallmodes {\unprotect\dodoifallmodes}
-% \def\doifnotallmodes {\unprotect\dodoifnotallmodes}
-% \def\startallmodes {\unprotect\dostartallmodes}
-% \def\startnotallmodes{\unprotect\dostartnotallmodes}
-%
-% \long\def\dodoifallmodeselse#1%
-% {\protect\expanded{\doifallcommonelse{#1}{\currentmode}}}
-%
-% \long\def\dodoifallmodes#1%
-% {\protect\expanded{\doifallcommon {#1}{\currentmode}}}
-%
-% \long\def\dodoifnotallmodes#1%
-% {\protect\expanded{\doifnotallcommon {#1}{\currentmode}}}
-%
-% \let\stopallmodes \relax
-% \let\stopnotallmodes\relax
-%
-% \long\def\dostartallmodes[#1]%
-% {\protect
-% \expanded{\doifnotallcommon{#1}{\currentmode}}{\gobbleuntil\stopallmodes}}
-%
-% \long\def\dostartnotallmodes[#1]%
-% {\protect
-% \expanded{\doifallcommon {#1}{\currentmode}}{\gobbleuntil\stopnotallmodes}}
-
-% faster
-
-\def\@mode@{@md@}
-
-\def\systemmodeprefix{*}
-
-\def\disabledmode {0}
-\def\enabledmode {1}
-\def\preventedmode {2}
-
-% fast internal ones
-
-\def\setmode #1{\@EA\let\csname\@mode@#1\endcsname\enabledmode }
-\def\resetmode#1{\@EA\let\csname\@mode@#1\endcsname\disabledmode}
-
-\def\setsystemmode #1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\enabledmode }
-\def\resetsystemmode#1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode}
-
-% user ones
-
-\def\preventmode{\unprotect\dopreventmode}
-\def\enablemode {\unprotect\doenablemode }
-\def\disablemode{\unprotect\dodisablemode}
-
-% \def\dopreventmode[#1]{\protect\rawprocesscommalist[#1]\dodopreventmode}
-% \def\doenablemode [#1]{\protect\rawprocesscommalist[#1]\dodoenablemode }
-% \def\dodisablemode[#1]{\protect\rawprocesscommalist[#1]\dododisablemode}
-%
-% better:
-
-\def\dopreventmode[#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dodopreventmode}
-\def\doenablemode [#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dodoenablemode }
-\def\dodisablemode[#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dododisablemode}
-
-\def\dodopreventmode#1%
- {\@EA\let\csname\@mode@#1\endcsname\preventedmode}
-
-\def\dodoenablemode#1% mode can be relax
- {\ifcase0\csname\@mode@#1\endcsname\relax
- \@EA\let\csname\@mode@#1\endcsname\enabledmode
- \fi}
+%D A few every's. Some are only used in \MKII\ or \MKIV.
-\def\dododisablemode#1%
- {\ifcase0\csname\@mode@#1\endcsname\or
- \@EA\let\csname\@mode@#1\endcsname\disabledmode
- \fi}
+%D Output routine:
-% handy for mp
+\newtoks \everybeforeoutput
+\newtoks \everyafteroutput
-\def\booleanmodevalue#1% can be \relax
- {\expandafter\ifx\csname\@mode@#1\endcsname\relax
- fals%
- \else\ifnum0\csname\@mode@#1\endcsname=0
- fals%
- \else
- tru%
- \fi\fi e}
+%D Shipout:
-% check macros
+\newtoks \everyshipout
+\newtoks \everybeforeshipout
+\newtoks \everyaftershipout
+\newtoks \everyfirstshipout
+\newtoks \everylastshipout
-\newif\ifcheckedmode
+%D End of run:
-\def\dodocheckformode#1%
- {\ifcase0\csname\@mode@#1\endcsname\or\checkedmodetrue\fi}
+\newtoks \everybye
+\newtoks \everygoodbye
+\newtoks \everynotabene
-\def\docheckformode#1#2#3% will be sped up with a quit
- {\cleanuplabel{#3}%
- \protect\checkedmodefalse\rawprocesscommacommand[\cleanlabel]\dodocheckformode
- \ifcheckedmode\@EA#1\else\@EA#2\fi}
+%D Document
-\def\dodocheckforallmodes#1%
- {\ifcase0\csname\@mode@#1\endcsname\relax\checkedmodefalse\or\or\checkedmodefalse\fi}
+\newtoks \everysetupdocument
+\newtoks \everyendoftextbody
-\def\docheckforallmodes#1#2#3% will be sped up with a quit
- {\cleanuplabel{#3}%
- \protect\checkedmodetrue\rawprocesscommacommand[\cleanlabel]\dodocheckforallmodes
- \ifcheckedmode\@EA#1\else\@EA#2\fi}
+\newtoks \everystarttext
+\newtoks \everystoptext
-% simple ones
+%D Purity:
-\def\doifmodeelse{\unprotect\dodoifmodeelse}
-\def\doifmode {\unprotect\dodoifmode}
-\def\doifnotmode {\unprotect\dodoifnotmode}
-\def\startmode {\unprotect\dostartmode}
-\def\startnotmode{\unprotect\dostartnotmode}
+\newtoks \everyforgetall
+\newtoks \everycleanupfeatures
-\def\dodoifmodeelse
- {\docheckformode\firstoftwoarguments\secondoftwoarguments}
+\def\cleanupfeatures{\the\everycleanupfeatures}
+\def\forgetall {\the\everyforgetall}
-\def\dodoifmode
- {\docheckformode\firstofoneargument\gobbleoneargument}
+%D Page building:
-\def\dodoifnotmode
- {\docheckformode\gobbleoneargument\firstofoneargument}
+\newtoks \everybeforepagebody
+\newtoks \everyafterpagebody
-\long\def\dostartmode[#1]%
- {\docheckformode\donothing\dostopmode{#1}}
+\let \everypagebody \everybeforepagebody % backward compatible
-\long\def\dostartnotmode[#1]%
- {\docheckformode\dostopnotmode\donothing{#1}}
+%D Multipass:
-\let\stopmode \donothing
-\let\stopnotmode\donothing
+\newtoks \everybeforeutilityread
+\newtoks \everyafterutilityread
-\long\def\dostopmode #1\stopmode {}
-\long\def\dostopnotmode#1\stopnotmode{}
+%D Floats:
-\def\doifallmodeselse{\unprotect\dodoifallmodeselse}
-\def\doifallmodes {\unprotect\dodoifallmodes}
-\def\doifnotallmodes {\unprotect\dodoifnotallmodes}
-\def\startallmodes {\unprotect\dostartallmodes}
-\def\startnotallmodes{\unprotect\dostartnotallmodes}
+\newtoks \everyinsidefloat
-\def\dodoifallmodeselse
- {\docheckforallmodes\firstoftwoarguments\secondoftwoarguments}
+%D Sectioning:
-\def\dodoifallmodes
- {\docheckforallmodes\firstofoneargument\gobbleoneargument}
+\newtoks \everyheadstart
-\def\dodoifnotallmodes
- {\docheckforallmodes\gobbleoneargument\firstofoneargument}
+%D Par building (experimental, used in xml <p> .. </p>)
-\long\def\dostartallmodes[#1]%
- {\docheckforallmodes\donothing\dostopallmodes{#1}}
+\newtoks \everybeginofpar
+\newtoks \everyendofpar
+%newtoks \everyparflush
-\long\def\dostartnotallmodes[#1]%
- {\docheckforallmodes\dostopnotallmodes\donothing{#1}}
+\def\bpar{\the\everybeginofpar\ignorespaces} % may interfere with \everypar
+\def\epar{\ifhmode\removeunwantedspaces\the\everyendofpar\fi} % test prevents problems with \bpar\epar
-\let\stopallmodes \donothing
-\let\stopnotallmodes\donothing
+%D Lists:
-\long\def\dostopallmodes #1\stopallmodes {}
-\long\def\dostopnotallmodes#1\stopnotallmodes{}
+\newtoks \everylistentry
+\newtoks \everysavesortkeys
-%D \macros
-%D {every...}
-%D
-%D A few every's.
-
-\newevery \everyshipout \relax
-\newevery \everybeforeshipout \relax
-\newevery \everyaftershipout \relax
-\newevery \everyfirstshipout \relax
-\newevery \everylastshipout \relax
-\newevery \everybye \relax
-\newevery \everygoodbye \relax
-\newevery \everystarttext \relax
-\newevery \everystoptext \relax
-\newevery \everyforgetall \relax
-\newevery \everybeforepagebody \relax
-\newevery \everyafterpagebody \relax
-\newevery \everybeforeutilityread \relax
-\newevery \everyafterutilityread \relax
-
-\let \everypagebody \everybeforepagebody % backward compatible
-
-%newevery \everybeforeutilitywrite \relax
-
-\newevery \everycleanupfeatures \relax
-\newevery \everyinsidefloat \relax
-\newevery \everyheadstart \relax
-\newevery \everyendoftextbody \relax
-\newevery \everybeginofpar \relax
-\newevery \everyendofpar \relax
-\newevery \everylistentry \relax
-\newevery \everymarking \relax
-\newevery \everysavesortkeys \relax
-
-\newevery \everyfont \relax
-\newevery \everybodyfont \EveryBodyFont
-\newevery \everyglobalbodyfont \relax
-\newevery \everyfontswitch \EveryFontSwitch
-\newevery \everydefinedfont \relax
-
-\newevery \everybeforeoutput \relax
-\newevery \everyafteroutput \relax
-
-\newevery \everybeforedisplayformula \relax
+%D Marks:
-\def\cleanupfeatures{\the\everycleanupfeatures}
-\def\forgetall {\the\everyforgetall}
+\newtoks \everymarking
-%D State mess:
+%D Fonts:
-\newtoks \everypushsomestate
-\newtoks \everypopsomestate
+\newtoks \everyfont
+\newtoks \everyglobalbodyfont
+\newtoks \everydefinedfont
-\def\pushsomestates{\the\everypushsomestate}
-\def\popsomestates {\the\everypopsomestate }
+\newevery \everybodyfont \EveryBodyFont
+\newevery \everyfontswitch \EveryFontSwitch
-%D For shared \type {\everymath} and \type {\everydisplay}:
+%D Math:
-\newevery \everymathematics \relax
+\newtoks \everybeforedisplayformula
+\newtoks \everymathematics
\prependtoks \the\everymathematics \to \everymath
\prependtoks \the\everymathematics \to \everydisplay
-% \newevery \everyparflush \relax % collected nodes
+%D Tables
-%D Experimental (used in xml <p> .. </p>
+\newtoks \everytable
-\def\bpar{\the\everybeginofpar\ignorespaces} % may interfere with \everypar
-\def\epar{\ifhmode\removeunwantedspaces\the\everyendofpar\fi} % test prevents problems with \bpar\epar
+%D State mess:
+
+\newtoks \everypushsomestate
+\newtoks \everypopsomestate
+
+\def\pushsomestates{\the\everypushsomestate}
+\def\popsomestates {\the\everypopsomestate }
%D More generic (used to be pushcolor etc)
@@ -337,8 +154,9 @@
%D
%D New. Some work needs to be done.
+% not in mkiv
+
\def\defineinputmode[#1]{\@EA\newtoks\csname every#1inputmode\endcsname}
-%def\setinputmode [#1]{\the \csname every#1inputmode\endcsname}
\def\setinputmode [#1]{\the\executeifdefined{every#1inputmode}\emptytoks}
\defineinputmode [TEX]
@@ -352,7 +170,7 @@
%D We disable trial typesetting in the output routine,
%D just to be sure.
-% defined in syst-ext
+\newif\iftrialtypesetting
\prependtoks \trialtypesettingfalse \to \everybeforepagebody
@@ -372,7 +190,7 @@
%D
%D We need this one even if no \XML\ is supported.
-\newif\ifprocessingXML
+\newif\ifprocessingXML % old way
%D \macros
%D {ifproductionrun}
@@ -382,7 +200,9 @@
\ifx\protectionlevel\undefined \newcount\protectionlevel \fi
-\newif\ifproductionrun \appendtoks \productionruntrue \to \everydump
+\newif\ifproductionrun
+
+\appendtoks \productionruntrue \to \everydump
\appendtoks \ifcase\protectionlevel\else\reportunprotection\fi \to \everydump
@@ -393,8 +213,8 @@
%D This one is relatively new and will be used as a more
%D robust test for inner situations.
-\newif \ifboxedcontent
-\newevery \everyboxedcontent \relax
+\newif \ifboxedcontent
+\newtoks\everyboxedcontent
\appendtoks \boxedcontenttrue \to \everyboxedcontent
@@ -402,145 +222,12 @@
\let\stopboxedcontent \egroup
%D \macros
-%D {fastmode}
-%D
-%D The command \type {\fastmode} disables some time consuming
-%D typesetting.
-
-\newevery \everyfastmode \relax
-
-\newif\iffastmode
-
-\def\fastmode
- {\fastmodetrue
- \the\everyfastmode}
-
-\def\silentmode % ook hier \everysilentmode net als \fastmode
- {\showmessagesfalse
- \showwarningsfalse
- \let\writestatus\gobbletwoarguments}
-
-%D \macros
-%D {pdfoutput}
-%D
-%D There are some fundamental differences between producing
-%D \DVI\ and \PDF\ output, especially when we use \PDFTEX, like
-%D object reuse, one pass graphic inclusion and the lack of a
-%D postprocessing stage. Because we must make sure that
-%D \CONTEXT\ knows what it's up to, we always default to \DVI\
-%D mode, even when users explicitly ask for \PDF\ output in the
-%D \PDFTEX\ configuration file.
-
-% we assume no pdfcontext or whatever
-%
-% \ifx\pdfoutput\undefined \else
-% \prependtoks \pdfoutput=0 \to \everyjob
-% \fi
-
-%D \macros
-%D {setvariables,getvariable,getvariabledefault}
+%D {fastmode,silentmode}
%D
-%D \starttyping
-%D \setvariables[xx][title=]
-%D \setvariables[xx][title=test test]
-%D \setvariables[xx][title=test $x=1$ test] % fatal error reported
-%D \setvariables[xx][title=test {$x=1$} test]
-%D \setvariables[xx][title] % fatal error reported
-%D \setvariables[xx][titletitel=e]
-%D \stoptyping
-
-\def\??vars{@@vars}
-
-\def\setvariables {\dotripleargument\dosetvariables[\getrawparameters ]}
-\def\setevariables{\dotripleargument\dosetvariables[\getraweparameters]}
-\def\setgvariables{\dotripleargument\dosetvariables[\getrawgparameters]}
-\def\setxvariables{\dotripleargument\dosetvariables[\getrawxparameters]}
-
-\def\globalsetvariables % obsolete
- {\dotripleargument\dosetvariables[\globalgetrawparameters]}
-
-% \long\def\dosetvariables[#1][#2][#3]%
-% {\errorisfataltrue
-% \def\currentvariableclass{#2}%
-% \getvariable{#2}\s!reset
-% #1[\??vars:#2:][#3]%
-% \getvariable{#2}\s!set
-% \errorisfatalfalse}
-%
-% permit nested definitions while preventing nested set/reset
-%
-% wrong:
-%
-% \long\def\dosetvariables[#1][#2][#3]%
-% {\errorisfataltrue
-% \getrawparameters[\??vars:*:][\s!reset=*,\s!set=*,#3]%
-% \doifelse{\getvalue{\??vars:*:\s!reset}\getvalue{\??vars:*:\s!set}}{**}
-% {\doifelse{#2}\currentvariableclass
-% {#1[\??vars:#2:][#3]}
-% {\pushmacro\currentvariableclass
-% \def\currentvariableclass{#2}%
-% \getvariable{#2}\s!reset
-% #1[\??vars:#2:][#3]%
-% \getvariable{#2}\s!set
-% \popmacro\currentvariableclass}}%
-% {#1[\??vars:#2:][#3]}%
-% \errorisfatalfalse}
-
-\long\def\dosetvariables[#1][#2][#3]% tricky, test on s-pre-60
- {\errorisfataltrue
- \doifelse{#2}\currentvariableclass
- {#1[\??vars:#2:][#3]}%
- {\pushmacro\currentvariableclass
- \def\currentvariableclass{#2}%
- \getvariable{#2}\s!reset
- #1[\??vars:#2:][#3]%
- \getvariable{#2}\s!set
- \popmacro\currentvariableclass}%
- \errorisfatalfalse}
-
-\long\def\setvariable #1#2#3{\long\setvalue {\??vars:#1:#2}{#3}}
-\long\def\setevariable#1#2#3{\long\setevalue{\??vars:#1:#2}{#3}}
-\long\def\setgvariable#1#2#3{\long\setgvalue{\??vars:#1:#2}{#3}}
-\long\def\setxvariable#1#2#3{\long\setxvalue{\??vars:#1:#2}{#3}}
-
-\def\getvariable#1#2% to be sped up
- {\csname
- \ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi
- \endcsname}
-
-\def\showvariable#1#2%
- {\showvalue{\ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi}}
-
-\let\currentvariableclass\empty
-
-%D \macros
-%D {doifelsevariable,doifvariable,doifnotvariable}
-%D
-%D A few trivial macros:
-
-\def\doifelsevariable#1#2%
- {\ifcsname\??vars:#1:#2\endcsname
- \expandafter\firstoftwoarguments
- \else
- \expandafter\secondoftwoarguments
- \fi}
-
-\def\doifvariable#1#2%
- {\ifcsname\??vars:#1:#2\endcsname
- \expandafter\firstofoneargument
- \else
- \expandafter\gobbleoneargument
- \fi}
-
-\def\doifnotvariable#1#2%
- {\ifcsname\??vars:#1:#2\endcsname
- \expandafter\gobbleoneargument
- \else
- \expandafter\firstofoneargument
- \fi}
+%D These commands are obsolete.
-\def\getvariabledefault#1#2% #3% can be command, so no ifcsname here
- {\executeifdefined{\??vars:#1:#2}}% {#3}
+\let\fastmode \relax
+\let\silentmode\relax
%D \macros
%D {defineselector,setupselector}
@@ -571,95 +258,20 @@
{\executeifdefined{\??sx#1\c!max}1}
{\executeifdefined{\??sx#1\c!n }1}}
-%D \macros
-%D {checkvariables}
-%D
-%D I'll probably forget that this on exists.
-
-\def\checkvariables
- {\dodoubleargument\docheckvariables}
-
-\def\docheckvariables
- {\dogetparameters\docheckrawvalue}
-
-\def\docheckrawvalue#1#2#3%
- {\doifundefined {\??vars:#1:#2}{\setvalue{\??vars:#1:#2}{#3}}
- {\doifvaluenothing{\??vars:#1:#2}{\setvalue{\??vars:#1:#2}{#3}}}}
-
%D We store some original meanings, maybe in \type
%D {math-ini}.
-\let\normalat \at
-\let\normalin \in
-\let\normalfrom \from
-\let\normalover \over
-\let\normalabout \about
-
-\let\normalabove \above
-\let\normalatop \atop
-
-\let\normaloverwithdelims \overwithdelims
-\let\normalabovewithdelims\abovewithdelims
-\let\normalatopwithdelims \atopwithdelims
+\let\normalat \at
+\let\normalin \in
+\let\normalfrom \from
+%let\normalover \over
+\let\normalabout\about
%D Add-ons:
\let\startlayoutcomponent\gobbletwoarguments
\let\stoplayoutcomponent \relax
-
-%D Label cleanup:
-\bgroup % some day this will go away / we could use detokenize as well
-
-% actually we should handle all discretionaries here
-
-\catcode`:=\@@active
-
-\gdef\cleanuplabel#1%
- {\begingroup
- \let:\lettercolon
- \xdef\cleanlabel{#1}%
- \endgroup}
-
-\gdef\cleanupprefixedlabel#1#2%
- {\begingroup
- \let:\lettercolon
- \xdef\cleanprefix{#1}%
- \xdef\cleanlabel {#2}%
- \endgroup}
-
-\gdef\protectlabels
- {\let:\lettercolon}
-
-\global\def\blabelgroup {\begingroup \let:\lettercolon}
-\global\let\elabelgroup \endgroup
-
-\gdef\labelcsname
- {\begingroup\let:\lettercolon
- \expandafter\endgroup\csname}
-
-\gdef\labelvalue#1%
- {\labelcsname#1\endcsname}
-
-\egroup
-
-%D TO BE TESTED FIRST (needs changes in usage too)
-
-% \def\cleanuplabel#1%
-% {\edef\cleanlabel{\detokenize{#1}}}
-%
-% \def\cleanupprefixedlabel#1#2%
-% {\edef\cleanprefix{\detokenize{#1}}%
-% \edef\cleanlabel {\detokenize{#2}}}
-%
-% \def\labelvalue#1%
-% {\csname\detokenize{#1}\endcsname}
-%
-% \let\protectlabels\donothing
-%
-% \def\blabelgroup {\begingroup} % why no \let ?
-% \let\elabelgroup \endgroup
-
%D Concepts:
\chardef\conceptmode\zerocount
diff --git a/tex/context/base/core-ver.mkii b/tex/context/base/core-ver.mkii
index 4e51c934c..dd8f5f84f 100644
--- a/tex/context/base/core-ver.mkii
+++ b/tex/context/base/core-ver.mkii
@@ -11,12 +11,51 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Verbatim}
+
\unprotect
-% uses \prettyidentifier and sets \setupprettytype
+\ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
+\ifx\stoplinenumbering \undefined \let\stoplinenumbering\relax \fi
+\ifx\setuplinenumbering\undefined \def\setuplinenumbering[#1]{} \fi
+
+% \type{ <crlf> char} geeft bagger
+
+%D We are going to embed the general verbatim support macros in
+%D a proper environment. First we show the common setup
+%D macro, so we know what features are supported. The options
+%D are hooked into the support macros via the \type{\obey}
+%D macros.
+
+\newif\ifslantedtypeactivated
+\newif\ifslantedtypepermitted
-\def\mksetupprettiesintype
- {\doifundefined{setuppretty\prettyidentifier type}%
+\def\switchslantedtype
+ {\ifslantedtypepermitted
+ \ifslantedtypeactivated
+ \slantedtypeactivatedfalse\tttf
+ \else
+ \slantedtypeactivatedtrue\ttsl
+ \fi
+ \fi}
+
+\newprettytrue % movet to here from cont-sys.tex
+
+\def\prettyidentifier {TEX}
+\def\prettypalet {}
+
+\def\installprettytype
+ {\dodoubleargument\doinstallprettytype}
+
+\def\doinstallprettytype[#1][#2]% map #1 onto #2
+ {\uppercasestring#1\to\asciia
+ \uppercasestring#2\to\asciib
+ \setevalue{\??ty\??ty\asciia}{\asciib}}
+
+\def\setupprettiesintype#1%
+ {\uppercasestring#1\to\ascii
+ \edef\prettyidentifier{\executeifdefined{\??ty\??ty\ascii}{TEX}}%
+ \doifundefined{setuppretty\prettyidentifier type}%
{\startnointerference
\restorecatcodes % also needed when loading during \newpretty
\startreadingfile % restore < and > if needed
@@ -26,8 +65,229 @@
\stopnointerference}%
\doifdefinedelse{setuppretty\prettyidentifier type}%
{\let\uncatcodecharacters\uncatcodeallcharacters % ugly, should be switch / todo
- \def\mksetupprettytype{\getvalue{setuppretty\prettyidentifier type}}}
- {\let\mksetupprettytype\relax}}
+ \def\dosetupprettytype{\getvalue{setuppretty\prettyidentifier type}}}
+ {\let\dosetupprettytype\relax}}
+
+\def\setupprettytype{\dosetupprettytype}
+
+% \def\setupcommonverbatim
+% {\recatcodeuppercharactersfalse % obey regime / encoding
+% %
+% \let\prettyidentifier\s!default
+% %
+% \doifelse{\typingparameter\c!text}\v!yes
+% \naturaltextexttrue
+% \naturaltextextfalse
+% \def\prettyidentifierfont{\typingparameter\c!icommand}%
+% \def\prettyvariablefont {\typingparameter\c!vcommand}%
+% \def\prettynaturalfont {\typingparameter\c!ccommand}%
+% %
+% \doif{\typingparameter\c!space}\v!on
+% {\def\obeyspaces{\setcontrolspaces}}%
+% \doif{\typingparameter\c!page }\v!no
+% {\def\obeypages {\ignorepages}}%
+% %
+% \doifelse{\typingparameter\c!tab}\v!yes
+% {\def\obeytabs{\settabskips}}%
+% {\doif{\typingparameter\c!tab}\s!ascii
+% {\chardef\tabskipmode\plustwo % quit on >127
+% \def\obeytabs{\settabskips}}}%
+% %
+% \ignorehyphens % default
+% \ExpandFirstAfter\processaction
+% [\typingparameter\c!lines]
+% [ \v!yes=>\obeybreakpoints,
+% \v!hyphenated=>\obeyhyphens]%
+% \processaction
+% [\typingparameter\c!empty]
+% [\v!yes=>\obeyemptylines,
+% \v!all=>\obeyallemptylines]%
+% %
+% \ExpandFirstAfter\processaction
+% [\typingparameter\c!option]
+% [ \v!none=>\let\obeycharacters\relax,
+% \v!color=>\setupprettiesintype{TEX}%
+% \let\obeycharacters\setupprettytype
+% \let\obeytabs\ignoretabs,
+% \v!normal=>\let\obeycharacters\setupgroupedtype,
+% \v!commands=>\def\obeycharacters{\setupcommandsintype}% \let
+% \let\obeytabs\ignoretabs,
+% \v!slanted=>\let\obeycharacters\setupslantedtype
+% \let\obeytabs\ignoretabs,
+% \s!unknown=>\setupprettiesintype{\typingparameter\c!option}%
+% \let\obeycharacters\setupprettytype
+% \let\obeytabs\ignoretabs]%
+% \doifnumberelse{\typingparameter\c!tab}
+% {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
+% \donothing
+% %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
+% % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
+% \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
+% \setupverbatimcolor}
+
+\setvalue{\??tp:\c!lines:\v!yes }{\obeybreakpoints}
+\setvalue{\??tp:\c!lines:\v!hyphenated}{\obeyhyphens}
+
+\setvalue{\??tp:\c!empty:\v!yes }{\obeyemptylines}
+\setvalue{\??tp:\c!empty:\v!all }{\obeyallemptylines}
+
+\setvalue{\??tp:\c!option:\v!none }{\let\obeycharacters\relax}
+\setvalue{\??tp:\c!option:\v!color }{\setupprettiesintype{TEX}%
+ \let\obeycharacters\setupprettytype
+ \let\obeytabs\ignoretabs}
+\setvalue{\??tp:\c!option:\v!normal }{\let\obeycharacters\setupgroupedtype}
+\setvalue{\??tp:\c!option:\v!commands }{\def\obeycharacters{\setupcommandsintype}%
+ \let\obeytabs\ignoretabs}
+\setvalue{\??tp:\c!option:\v!slanted }{\let\obeycharacters\setupslantedtype
+ \let\obeytabs\ignoretabs}
+\setvalue{\??tp:\c!option:\s!unknown }{\setupprettiesintype{\typingparameter\c!option}%
+ \let\obeycharacters\setupprettytype
+ \let\obeytabs\ignoretabs}
+
+
+\def\setupcommonverbatim
+ {\recatcodeuppercharactersfalse % obey regime / encoding
+ %
+ \let\prettyidentifier\s!default
+ %
+ \doifelse{\typingparameter\c!text}\v!yes
+ \naturaltextexttrue
+ \naturaltextextfalse
+ \def\prettyidentifierfont{\typingparameter\c!icommand}%
+ \def\prettyvariablefont {\typingparameter\c!vcommand}%
+ \def\prettynaturalfont {\typingparameter\c!ccommand}%
+ %
+ \doif{\typingparameter\c!space}\v!on
+ {\def\obeyspaces{\setcontrolspaces}}%
+ \doif{\typingparameter\c!page }\v!no
+ {\def\obeypages {\ignorepages}}%
+ %
+ \doifelse{\typingparameter\c!tab}\v!yes
+ {\def\obeytabs{\settabskips}}%
+ {\doif{\typingparameter\c!tab}\s!ascii % not needed in mkiv
+ {\chardef\tabskipmode\plustwo % quit on >127
+ \def\obeytabs{\settabskips}}}%
+ %
+ \ignorehyphens % default
+ \getvalue{\??tp:\c!lines:\typingparameter\c!lines}%
+ \getvalue{\??tp:\c!empty:\typingparameter\c!empty}%
+ \getvalue{\??tp:\c!option:\ifcsname\??tp:\c!option:\typingparameter\c!option\endcsname\typingparameter\c!option\else\s!unknown\fi}%
+ \doifnumberelse{\typingparameter\c!tab}
+ {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
+ \donothing
+ %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
+ % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
+ \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
+ \setupverbatimcolor}
+
+% BEWARE: the noligatures will globally change the verbatim font's behaviour
+
+% test case:
+%
+% \definetype[typeTEX][option=tex]
+%
+% \typeTEX|\example---oeps|. this---ligates---again.
+% \typeTEX{\example---oeps}. this---ligates---again.
+% \type {\example---oeps}. this---ligates---again.
+
+\def\setupcommandsintype % can also be \string\
+ {\setupgroupedtype
+ \edef\\{\typingparameter\c!escape}%
+ \letvalue{\\}=\\% for instance \/=/
+ \@EA\catcode\@EA`\\=\@@escape
+ \def\BTEX##1\ETEX##2% ##2 gobbles active space
+ {\naturaltextext##1\unskip\relax}}
+
+\def\setupslantedtype
+ {\slantedtypepermittedtrue\setupgroupedtype}
+
+\ifx\setupprettytype \undefined \let\setupprettytype \relax \fi
+\ifx\setupslantedtype \undefined \let\setupslantedtype \relax \fi
+\ifx\setupgroupedtype \undefined \let\setupgroupedtype \relax \fi
+\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi
+
+%D The verbatim commands have a rather long and turbulent
+%D history. Most users of \CONTEXT\ probably will never use
+%D some of the features, but I've kept in mind that when one is
+%D writing a users manual, about everything can and undoubtly
+%D will be subject to a verbatim treatment.
+%D
+%D Verbatim command are very sensitive to argument processing,
+%D which is a direct result of the \CATCODES\ being fixed at
+%D reading time. With our growing understanding of \TEX,
+%D especially of the mechanism that can be used for looking
+%D ahead and manipulating \CATCODES, the verbatim support
+%D became more and more advanced and natural.
+%D
+%D Typesetting inline verbatim can be accomplished by
+%D \type{\type}, which in this sentence was typeset by saying
+%D just \type{\type{\type}}, which in turn was typeset by
+%D \unknown. Using the normal grouping characters \type{{}} is
+%D the most natural way of using this command.
+%D
+%D A second, more or less redundant, alternative is delimiting
+%D the argument with an own character. This method was
+%D implemented in the context of a publication in the \MAPS,
+%D where this way of delimiting is recognized by \LATEX\ users.
+%D
+%D The third, more original alternative, is the one using
+%D \type{<<} and \type{>>} as delimiters. This alternative can
+%D be used in situations where slanted typeseting is needed.
+
+% todo: we can use \letter... here:
+
+\def\lesscharacter {<}
+\def\morecharacter {>}
+
+\chardef\texescape = `\\
+\chardef\leftargument = `\{
+\chardef\rightargument = `\}
+
+%D \macros
+%D {type}
+%D
+%D We define \type{\type} as a protected command. This command
+%D has several invocations: grouped, wirt boundary characters,
+%D and with font switches.
+
+% \starttyping
+% normal: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
+% normal: \par \type{xx<..xx..<xx <slanted> >..>xx} \par \type{<....>} \par \type{<..<xx>..>}
+% \setuptype[option=slanted]
+% slanted: \par \type{xx<<..sl..<<xx <<sl>> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<<sl>>..>> \par
+% slanted: \par \type{xx<<..sl..<xx <sl> xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<sl>..>> \par
+% \setuptype[option=none]
+% none: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
+% \stoptyping
+
+%D When writing the manual to \CONTEXT\ and documenting this
+%D source we needed to typeset \type{<<} and \type{>>}. Because
+%D we wanted to do this in the natural way, we've adapted the
+%D original definition a bit. This implementation went through
+%D several live cycles. The final implementation looks a bit
+%D further and treats the lone \type{<<} and \type{>>} a bit
+%D different. The \type {\null} prevents ligatures, which
+%D unfortunately turn up in Lucida fonts.
+
+%D The following lines show what happens when we set
+%D \type {option=commands}.
+%D
+%D \startbuffer
+%D \starttyping
+%D test//test test/BTEX \footnote{test test test}/ETEX test
+%D test//test test/BTEX \footnote{test test test}/ETEX test
+%D test test test/BTEX \bf(nota bene)/ETEX test
+%D test test test /BTEX \bf(nota bene)/ETEX test
+%D \stoptyping
+%D \stopbuffer
+%D
+%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup
+%D
+%D this was keyed in as:
+%D
+%D \typebuffer
+
+\unexpanded\def\type{\dotype\empty}
% not that fast but catches \type{\command} % nothing more after \command
%
@@ -51,7 +311,7 @@
% the rather messy \type command
-\def\mktype#1% was \dotype
+\def\dotype#1% was \dotype
{\bgroup
\resumecoloraftergroup % a problem is that we can still be in color mode, tricky hack
\begstrut % new, enables leading space in \type { abc } at par start / begstrut else no hyphenation
@@ -101,6 +361,32 @@
\@EAEAEA\dodotypeD
\fi\fi}
+% The next one is safe for: \def\xx#1{\type{#1}} \xx{\ifx}
+
+\let\protectedfirsttype\string % \relax for special cases
+
+\bgroup
+\catcode`\<=\active
+\catcode`\>=\active
+\gdef\doprotectfirsttype
+ {\normalifx\next<%
+ \endrobusttest \let\next\relax
+ \normalelse\normalifx\next\bgroup
+ \endrobusttest \let\next\relax
+ \normalelse\normalifx\next\egroup % takes care of \type{}
+ \endrobusttest \let\next\relax
+ \normalelse\normalifx\next\activeleftargument
+ \endrobusttest \let\next\relax
+ \normalelse
+ \endrobusttest \let\next\protectedfirsttype
+ \normalfi\normalfi\normalfi\normalfi
+ \next}
+\egroup
+
+\def\protectfirsttype
+ {\beginrobusttest
+ \futurelet\next\doprotectfirsttype}
+
% Verbatim does not work when passed as an argument, so here is a
% workaround. Beware, spaces are introduced after a \type {\csname}.
@@ -247,52 +533,802 @@
\def>{\futurelet\next\domore}}
\egroup
-\def\mksetupcommandsintype% can also be \string\
- {\setupgroupedtype
- \edef\\{\typingparameter\c!escape}%
- \letvalue{\\}=\\% for instance \/=/
- \@EA\catcode\@EA`\\=\@@escape
- \def\BTEX##1\ETEX##2% ##2 gobbles active space
- {\naturaltextext##1\unskip\relax}}
+%D The neccessary initializations are done by calling
+%D \type{\initializetype} which in return calls for the support
+%D macro \type{\setupinlineverbatim}.
-\def\mksetupslantedtype
- {\setupgroupedtype}
+\def\initializetype
+ {\let\obeylines\ignorelines
+ \setupcommonverbatim
+ \setupinlineverbatim}
-\let\protectedfirsttype\string % \relax for special cases
+%D \macros
+%D {setuptype}
+%D
+%D Some characteristics of \type{\type} can be set up by:
-% The next one is safe for: \def\xx#1{\type{#1}} \xx{\ifx}
+\def\setuptype
+ {\dodoubleempty\dosetuptype}
-\bgroup
-\catcode`\<=\active
-\catcode`\>=\active
-\gdef\doprotectfirsttype
- {\normalifx\next<%
- \endrobusttest \let\next\relax
- \normalelse\normalifx\next\bgroup
- \endrobusttest \let\next\relax
- \normalelse\normalifx\next\egroup % takes care of \type{}
- \endrobusttest \let\next\relax
- \normalelse\normalifx\next\activeleftargument
- \endrobusttest \let\next\relax
- \normalelse
- \endrobusttest \let\next\protectedfirsttype
- \normalfi\normalfi\normalfi\normalfi
- \next}
-\egroup
+\def\dosetuptype[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??ty#1][#2]%
+ \else
+ \getparameters[\??ty][#1]%
+ \fi}
-\def\protectfirsttype
- {\beginrobusttest
- \futurelet\next\doprotectfirsttype}
+%D \macros
+%D {typ,obeyhyphens,obeybreakpoints}
+%D
+%D Although it's not clear from the macros, one character
+%D trait of this macros, which are build on top of the support
+%D module, is that they don't hyphenate. We therefore offer
+%D the alternative \type{\typ}. The current implementation
+%D works all right, but a decent hyphenation support of
+%D \type{\tt} text will be implemented soon.
+
+\def\obeyhyphens
+ {\def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
+ \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}%
+ \spaceskip.25em\relax} % hm a bit of stretch !
-% typing:
+\def\obeybreakpoints
+ {\ignorehyphens
+ \veryraggedright}
-\def\mktypeblockverbatim#1#2%
- {\processdisplayverbatim{#2}} % needs to be fixed
+\def\ignorehyphens
+ {% \language\minusone % extra bonus, the \null should do the job too
+ \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
+ \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}%
+ \spaceskip.5em\relax}
-% typefile:
+\unexpanded\def\typ
+ {\bgroup
+ \let\@@tylines\v!hyphenated
+ \futurelet\next\dodotype}
-\def\mktypefileverbatim {\processfileverbatim \readfilename} % #1
-\def\mktypefilelinesverbatim{\processfilelinesverbatim\readfilename} % #1 / #2#3
+%D \macros
+%D {tex,arg,mat,dis}
+%D
+%D Sometimes, for instance when we pass verbatim text as an
+%D argument, the fixed \CATCODES\ interfere with our wishes. An
+%D experimental implementation of character by character
+%D processing of verbatim text did overcome this limitation,
+%D but we've decided not to use that slow and sometimes
+%D troublesome solution. Instead we stick to some 'old'
+%D \CONTEXT\ macros for typesetting typical \TEX\ characters.
+%D
+%D The next implementation is more clear but less versatile,
+%D so we treated it for a beter one.
+%D
+%D \starttyping
+%D \def\dospecialtype#1#2%
+%D {\bgroup
+%D \initializetype
+%D \catcode`\{=\@@begingroup
+%D \catcode`\}=\@@endgroup
+%D \def\dospecialtype%
+%D {\def\dospecialtype{#2\egroup}%
+%D \bgroup
+%D \aftergroup\dospecialtype
+%D #1}%
+%D \afterassignment\dospecialtype
+%D \let\next=}
+%D
+%D \unexpanded\def\tex{\dospecialtype\texescape\relax}
+%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument}
+%D \unexpanded\def\mat{\dospecialtype\$\$}
+%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}}
+%D \stoptyping
-\protect \endinput
+\def\setgroupedtype
+ {\let\currenttypingclass\??ty
+ \initializetype
+ \verbatimcolor
+ %\setcatcodetable \typcatcodesa
+ \catcode`\{=\@@begingroup
+ \catcode`\}=\@@endgroup}
+
+\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}}
+\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}}
+\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}}
+\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}}
+
+%D \macros
+%D {starttyping}
+%D
+%D Display verbatim is realized far more easy, which is mostly
+%D due to the fact that we use \type{\stop...} as delimiter.
+%D The implementation inherits some features, for instance the
+%D support of linenumbering, which can best be studied in the
+%D documented support module.
+
+\let\currenttyping \empty
+\let\currenttypingclass\??ty % saveguard
+
+% \def\typingparameter#1%
+% {\executeifdefined
+% {\currenttypingclass\currenttyping#1}%
+% {\executeifdefined{\currenttypingclass#1}\empty}}
+
+\def\typingparameter#1%
+ {\ifcsname\currenttypingclass\currenttyping#1\endcsname
+ \csname\currenttypingclass\currenttyping#1\endcsname
+ \else\ifcsname\currenttypingclass#1\endcsname
+ \csname\currenttypingclass#1\endcsname
+ \fi\fi}
+
+\def\settypingparameter#1#2%
+ {\setvalue{\currenttypingclass\currenttyping#1}{#2}}
+
+\def\setxtypingparameter#1#2%
+ {\setxvalue{\currenttypingclass\currenttyping#1}{#2}}
+
+% \def\initializetyping
+% {%\donefalse
+% \switchtobodyfont[\typingparameter\c!bodyfont]%
+% \donefalse
+% \scratchskip\typingparameter\c!oddmargin\relax
+% \ifzeropt\scratchskip\else\donetrue\fi
+% \scratchskip\typingparameter\c!evenmargin\relax
+% \ifzeropt\scratchskip\else\donetrue\fi
+% \ifdone
+% \def\doopenupverbatimline
+% {\getpagestatus
+% \ifrightpage
+% \hskip\typingparameter\c!oddmargin\relax
+% \else
+% \hskip\typingparameter\c!evenmargin\relax
+% \fi}%
+% \else
+% \doadaptleftskip{\typingparameter\c!margin}%
+% \fi
+% \doifdefinedelse{\??bo\typingparameter\c!blank}
+% {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}}
+% {\edef\!!stringa{\typingparameter\c!blank}}%
+% \processaction
+% [\!!stringa]
+% [ \v!standard=>\scratchskip\ctxparskip,
+% \v!small=>\scratchskip\blankokleinmaat,
+% \v!medium=>\scratchskip\blankomiddelmaat,
+% \v!big=>\scratchskip\blankogrootmaat,
+% \v!halfline=>\scratchskip.5\baselineskip,
+% \v!line=>\scratchskip\baselineskip,
+% \v!none=>\scratchskip\zeropoint,
+% \s!unknown=>\scratchskip\commalistelement]%
+% \ifgridsnapping
+% \ifdim\scratchskip=.5\baselineskip\relax
+% \edef\verbatimbaselineskip{\the\scratchskip}% new
+% \else
+% \edef\verbatimbaselineskip{\the\baselineskip}%
+% \fi
+% \else
+% \edef\verbatimbaselineskip{\the\scratchskip}%
+% \fi
+% \setupcommonverbatim}
+
+\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip}
+\setvalue{\??tp:\c!blank:\v!small }{\blankokleinmaat}
+\setvalue{\??tp:\c!blank:\v!medium }{\blankomiddelmaat}
+\setvalue{\??tp:\c!blank:\v!big }{\blankogrootmaat}
+\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip}
+\setvalue{\??tp:\c!blank:\v!line }{\baselineskip}
+\setvalue{\??tp:\c!blank:\v!none }{\zeropoint}
+
+\def\initializetyping
+ {%\donefalse
+ \switchtobodyfont[\typingparameter\c!bodyfont]%
+ \donefalse
+ \scratchskip\typingparameter\c!oddmargin\relax
+ \ifzeropt\scratchskip\else\donetrue\fi
+ \scratchskip\typingparameter\c!evenmargin\relax
+ \ifzeropt\scratchskip\else\donetrue\fi
+ \ifdone
+ \def\doopenupverbatimline
+ {\getpagestatus
+ \ifrightpage
+ \hskip\typingparameter\c!oddmargin\relax
+ \else
+ \hskip\typingparameter\c!evenmargin\relax
+ \fi}%
+ \else
+ \doadaptleftskip{\typingparameter\c!margin}%
+ \fi
+ \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}%
+ \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax
+ \ifgridsnapping
+ \ifdim\scratchskip=.5\baselineskip\relax
+ \edef\verbatimbaselineskip{\the\scratchskip}% new
+ \else
+ \edef\verbatimbaselineskip{\the\baselineskip}%
+ \fi
+ \else
+ \edef\verbatimbaselineskip{\the\scratchskip}%
+ \fi
+ \setupcommonverbatim}
+
+%D The basic display verbatim commands are defined in an
+%D indirect way. As we will see, they are a specific case of a
+%D more general mechanism.
+
+% we need this hack because otherwise verbatim skips
+% the first line (everything after the initial command)
+
+\def\dostarttyping#1% tricky non standard lookahead
+ {\bgroup
+ \let\currenttypingclass\??tp
+ \edef\currenttyping{#1}%
+ \obeylines
+ \futurelet\nexttoken\dodostarttyping}
+
+\def\dodostarttyping
+ {\ifx\nexttoken[%
+ \expandafter\dododostarttyping
+ \else
+ \expandafter\nododostarttyping
+ \fi}
+
+\def\nododostarttyping
+ {\dododostarttyping[]}
+
+\def\dododostarttyping[#1]%
+ {\typingparameter\c!before
+ \startpacked % includes \bgroup
+ \dosetuptypelinenumbering{#1}%
+ \initializetyping
+ \startverbatimcolor
+ \expanded{\processdisplayverbatim{\s!stop\currenttyping}}}
+
+\def\dostoptyping#1% hm, currenttyping
+ {\stopverbatimcolor
+ \stoppacked % includes \egroup
+ \typingparameter\c!after
+ \egroup
+ \dochecknextindentation{\??tp#1}%
+ \dorechecknextindentation}
+
+%D Line numbering for files is combined with filtering, while
+%D display verbatim has the ability to continue.
+%D
+%D \starttyping
+%D \typefile[numbering=file,start=10,stop=12]{test.tex}
+%D
+%D \definetyping[code][numbering=line]
+%D
+%D \starttext
+%D \startcode
+%D ...
+%D ...
+%D \stopcode
+%D
+%D \startcode[continue]
+%D ...
+%D ...
+%D \stopcode
+%D
+%D \startcode[start=10]
+%D ...
+%D \stopcode
+%D \stoptyping
+
+%D \macros
+%D {setuptyping}
+%D
+%D The setup of typing accepts two arguments. The optional
+%D first one identifies the user defined ones. If only one
+%D argument is given, the values apply to both the standard
+%D command \type{\starttyping} and \type{\typefile}.
+
+\def\dosetuptyping[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??tp#1][#2]%
+ \else
+ \getparameters[\??tp][#1]%
+ \fi}
+
+\def\setuptyping
+ {\dodoubleempty\dosetuptyping}
+
+%D \macros
+%D {definetype}
+%D
+%D Specific inline verbatim commands can be defined with the
+%D following command.
+
+\def\definetype
+ {\dodoubleempty\dodefinetype}
+
+\def\dodefinetype[#1][#2]%
+ {\unexpanded\setvalue{#1}{\dotype{#1}}%
+ \getparameters[\??ty#1][#2]}
+
+%D \macros
+%D {definetyping}
+%D
+%D For most users the standard \type{\start}||\type{\stop}||pair
+%D will suffice, but for documentation purposes the next
+%D definition command can be of use:
+%D
+%D \starttyping
+%D \definetyping[extratyping][margin=3em]
+%D
+%D \startextratyping
+%D these extra ones are indented by 1 em
+%D \stopextratyping
+%D \stoptyping
+%D
+%D The definitions default to the standard typing values.
+
+\def\presettyping[#1][#2]%
+ {\copyparameters[\??tp#1][\??tp][\c!color,\c!style]%
+ \getparameters [\??tp#1][#2]}
+
+\def\dodefinetyping[#1][#2]%
+ {\setvalue{\e!start#1}{\dostarttyping{#1}}%
+ \setvalue{\e!stop #1}{\dostoptyping {#1}}%
+ \presettyping[#1][#2]}
+
+\def\definetyping
+ {\dodoubleempty\dodefinetyping}
+
+%D We can use some core color commands. These are faster than
+%D the standard color switching ones and work ok on a line by
+%D line basis.
+%D
+%D \starttyping
+%D \def\setupverbatimcolor%
+%D {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}%
+%D \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
+%D \def\endofpretty {\stopcolormode}}
+%D \stoptyping
+%D
+%D Since we support a global color too, the folowing
+%D definition is better:
+
+% \def\setupverbatimcolor% fast and local versus slow and global
+% {\doifelsenothing{\typingparameter\c!color}
+% {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
+% \let\endofpretty \restorecolormode % \stopcolormode
+% \let\startverbatimcolor \relax
+% \let\stopverbatimcolor \relax
+% \let\verbatimcolor \relax}
+% {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
+% \let\endofpretty \stopcolor
+% \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
+% \let\stopverbatimcolor \stopcolor
+% \def\verbatimcolor {\getvalue{\typingparameter\c!color}}}% command !
+% \doifelsenothing{\typingparameter\c!palet}
+% {\let\prettypalet\empty
+% \let\endofpretty\relax
+% \def\beginofpretty[##1]{}}
+% {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
+%
+% let's forget about this optimization not that we have mkiv
+
+\def\setupverbatimcolor
+ {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
+ \let\endofpretty \stopcolor
+ \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
+ \let\stopverbatimcolor \stopcolor
+ \def\verbatimcolor {\getvalue{\typingparameter\c!color}}% command !
+ \doifelsenothing{\typingparameter\c!palet}
+ {\let\prettypalet\empty
+ \let\endofpretty\relax
+ \def\beginofpretty[##1]{}}
+ {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
+
+\let\prettypalet \empty
+\let\startverbatimcolor\relax
+\let\stopverbatimcolor \relax
+\let\verbatimcolor \relax
+
+%D In the verbatim module, there are some examples given of
+%D the more obscure features of the verbatim environments.
+%D
+%D \startbuffer
+%D \startTEX
+%D \def\mathematics#1% % usage: \type {\mathematics{x^2}}
+%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2}
+%D \stopTEX
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This gives, as can be expected:
+%D
+%D \getbuffer
+%D
+%D When we want to see some typeset \TEX\ too, we can say:
+%D
+%D \startbuffer
+%D \startTEX
+%D \def\mathematics#1% %%\ N usage: \type {\mathematics{x^2}}
+%D {\ifmmode#1\else$#1$\fi} %%\ N becomes: \mathematics{x^2}
+%D \stopTEX
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or:
+%D
+%D \getbuffer
+%D
+%D In a similar way:
+%D
+%D \startbuffer
+%D \startSQL
+%D select * -- indeed, here we {\em do} select
+%D from tableA
+%D where 1 = 2
+%D \stopSQL
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives:
+%D
+%D \getbuffer
+%D
+%D The next examples sow how we can directly call for natural
+%D \TEX\ comments:
+%D
+%D \startbuffer
+%D \setuptyping
+%D [TEX]
+%D [text=yes]
+%D
+%D \startTEX
+%D \def\mathematics#1% % usage: \type {\mathematics{x^2}}
+%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2}
+%D \stopTEX
+%D
+%D \setuptyping
+%D [SQL]
+%D [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it]
+%D
+%D \startSQL
+%D select * -- indeed, here we {\em do} select
+%D from tableA
+%D where 1 = 2
+%D \stopSQL
+%D
+%D \setuptyping
+%D [SQL]
+%D [ccommand=\tf\underbar]
+%D
+%D \startSQL
+%D select * -- indeed, here we {\em do} select
+%D from tableA
+%D where 1 = 2
+%D \stopSQL
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Now watch:
+%D
+%D \getbuffer
+%D
+%D The natural \TEX\ typesetting was introduced when Tobias
+%D and Berend started using verbatim \JAVASCRIPT\ and \SQL.
+
+%D \macros
+%D {EveryPar, EveryLine, iflinepar}
+%D
+%D One of the features of these commands is the support of
+%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}.
+%D In the documentation of the verbatim support module we give
+%D some examples of line- and paragraph numbering using these
+%D macros.
+
+%D \macros
+%D {typefile}
+%D
+%D Typesetting files verbatim (for the moment) only supports
+%D colorization of \TEX\ sources as valid option. The other
+%D setup values are inherited from display verbatim.
+%D The implementation of \type{\typefile} is straightforward:
+% new feature (not yet 100\% ok)
+%
+% \setuptyping[file][numbering=file]
+%
+% \typefile[start=2,nlines=3]{zapf}
+% \typefile[start=continue,nlines=13]{zapf}
+% \typefile{zapf}
+%
+% \setuptyping[file][numbering=line]
+%
+% \typefile[start=4,step=3]{zapf}
+% \typefile{zapf}
+
+\def\typefile
+ {\dodoubleempty\dotypefile}
+
+\def\dotypefile[#1][#2]#3%
+ {\ifsecondargument
+ \dodotypefile[#1][#2]{#3}%
+ \else\iffirstargument
+ \doifassignmentelse{#1}
+ {\dodotypefile[\v!file][#1]{#3}}
+ {\dodotypefile[#1][]{#3}}%
+ \else
+ \dodotypefile[\v!file][]{#3}%
+ \fi\fi}
+
+\def\dosetuptypelinenumbering#1% fuzzy
+ {\doifundefined{\currenttypingclass\currenttyping\c!start}
+ {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}%
+ \setuptyping[\currenttyping][#1]%
+ \doifelse{\typingparameter\c!numbering}\v!file
+ {% kind of special: filters lines !
+ \setuplinenumbering[\c!method=\v!file]%
+ \donetrue}
+ {\doifelse{\typingparameter\c!numbering}\v!line
+ {% \setuplinenumbering defaults start/step to 1/1, so we need
+ \doifinsetelse\v!continue{#1,\typingparameter\c!start}
+ {\scratchcounter0\typingparameter\c!n
+ \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}%
+ {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}%
+ \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}%
+ \setuplinenumbering
+ [\c!method=\v!type,
+ \c!start=\typingparameter\c!start,
+ \c!stop=\typingparameter\c!stop,
+ \c!step=\typingparameter\c!step]%
+ \donetrue}
+ {\donefalse}}%
+ \ifdone
+ \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
+ \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi
+ \def\beginofverbatimlines{\startlinenumbering}%
+ \def\endofverbatimlines {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}%
+ \fi}
+
+\def\reporttypingerror#1% temp hack
+ {\blank
+ \dontleavehmode\hbox\bgroup
+ \expanded{\defconvertedargument\noexpand\ascii{#1}}%
+ \tttf[\makemessage\m!verbatims1\ascii]%
+ \showmessage\m!verbatims1\ascii
+ \egroup
+ \blank}
+
+\def\dosometyping#1#2#3#4#5%
+ {\bgroup
+ \let\currenttypingclass\??tp
+ \edef\currenttyping{#1}%
+ \typingparameter\c!before
+ \startpacked % includes \bgroup
+ \dosetuptypelinenumbering{#2}%
+ \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal}
+ {\setuptyping[#1][\c!option=\v!none]}%
+ \doif{\typingparameter\c!option}\v!color
+ {\expandafter\aftersplitstring#3\at.\to\prettyidentifier
+ \settypingparameter\c!option{\prettyidentifier}}%
+ \initializetyping
+ \startverbatimcolor
+ \doifundefinedelse{\currenttypingclass#3\v!global\c!start}
+ {\scratchcounter\zerocount}
+ {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}%
+ \advance\scratchcounter\plusone
+ \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}%
+ \doifelsenothing{\typingparameter\c!start}
+ {#4}
+ {\doif{\typingparameter\c!start}\v!continue
+ {\setevalue{\currenttypingclass#1\c!start}%
+ {\getvalue{\currenttypingclass#3\v!global\c!start}}}%
+ \doifelsenothing{\typingparameter\c!stop}
+ {\doifelsenothing{\typingparameter\c!nlines}
+ {#4}
+ {\setxvalue{\currenttypingclass#3\v!global\c!start}%
+ {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}%
+ #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}%
+ {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}%
+ \stopverbatimcolor
+ \stoppacked
+ \typingparameter\c!after
+ \egroup}
+
+\def\doifelsetypingfile#1% sets \readfilename (we will make this proper mkiv i.e. less messy)
+ {\doiflocfileelse{#1}
+ {\firstoftwoarguments}
+ {\doifinputfileelse{#1}
+ {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments} % messy, looks wrong too
+ {\secondoftwoarguments}}}
+
+\def\dodotypefile[#1][#2]#3%
+ {\doifelsetypingfile{#3}
+ {\dosometyping{#1}{#2}{#3}{\processfileverbatim\readfilename}{\processfilelinesverbatim\readfilename}}
+ {\reporttypingerror{#3}}}
+
+%D \macros
+%D {filename}
+%D
+%D Typesetting filenames in monospaced fonts is possible with
+%D
+%D \starttyping
+%D \filename{here/there/filename.suffix}
+%D \stoptyping
+%D
+%D The definition is not that spectacular.
+
+\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}}
+
+%D This leaves some settings:
+
+\permitshiftedendofverbatim
+\optimizeverbatimtrue
+
+%D And a bonus macro:
+
+\def\verbatim#1{\defconvertedargument\ascii{#1}\ascii}
+
+%D The setups for display verbatim and file verbatim are
+%D shared. One can adapt the extra defined typing environments,
+%D but they also default to the values below. Watch the
+%D alternative escape character.
+
+\setuptyping
+ [ \c!before=\blank,
+ \c!after=\blank,
+ \c!bodyfont=,
+ \c!color=,
+ \c!space=\v!off,
+ \c!page=\v!no,
+ \c!tab=\s!ascii,
+ \c!option=\v!none,
+ \c!palet=colorpretty,
+ \c!text=\v!no,
+ \c!style=\tttf,
+ \c!icommand=\ttsl,
+ \c!vcommand=,
+ \c!ccommand=\tttf,
+ \c!indentnext=\v!yes,
+ \c!margin=\!!zeropoint,
+ \c!evenmargin=\!!zeropoint,
+ \c!oddmargin=\!!zeropoint,
+ \c!blank=\v!line,
+ \c!escape=/, % beware \string\ , should also be accepted
+ \c!numbering=\v!no,
+ \c!lines=,
+ \c!empty=,
+ \c!start=1,
+ \c!stop=,
+ \c!step=1,
+ \c!continue=,
+ \c!nlines=]
+
+\definetyping[\v!typing]
+
+\presettyping[\v!file][]
+
+% \setuptyping % not needed
+% [\v!file]
+% [\c!start=1,
+% \c!stop=,
+% \c!step=1,
+% \c!continue=,
+% \c!nlines=]
+
+%D The setups for inline verbatim default to:
+
+\setuptype
+ [ \c!space=\v!off,
+ \c!color=,
+ \c!style=\tt\tf, % \tttf gives problems with {\tx \type...}
+ \c!page=\v!no,
+ \c!tab=\v!yes,
+ \c!palet=colorpretty,
+ \c!option=\v!normal]
+
+\definetyping[RAW] [\c!option=RAW]
+\definetyping[MP] [\c!option=MP]
+\definetyping[PL] [\c!option=PL]
+\definetyping[PM] [\c!option=PL]
+\definetyping[JS] [\c!option=JS]
+\definetyping[JV] [\c!option=JV]
+\definetyping[SQL] [\c!option=SQL]
+\definetyping[TEX] [\c!option=TEX]
+\definetyping[PAS] [\c!option=PAS]
+\definetyping[PASCAL][\c!option=PAS]
+\definetyping[MOD] [\c!option=PAS]
+\definetyping[MODULA][\c!option=PAS]
+\definetyping[DELPHI][\c!option=PAS]
+\definetyping[EIFFEL][\c!option=EIF]
+\definetyping[XML] [\c!option=XML]
+\definetyping[LUA] [\c!option=LUA]
+
+\installprettytype [RAW] [RAW]
+
+\installprettytype [TEX] [TEX]
+
+\installprettytype [PERL] [PL]
+\installprettytype [PL] [PL]
+\installprettytype [PM] [PL]
+
+\installprettytype [METAPOST] [MP]
+\installprettytype [METAFONT] [MP]
+\installprettytype [MP] [MP]
+\installprettytype [MF] [MP]
+
+\installprettytype [JAVASCRIPT] [JS]
+\installprettytype [JAVA] [JV]
+\installprettytype [JS] [JS]
+\installprettytype [JV] [JV]
+
+\installprettytype [SQL] [SQL]
+
+\installprettytype [PASCAL] [PAS]
+\installprettytype [PAS] [PAS]
+\installprettytype [MODULA] [PAS]
+\installprettytype [MOD] [PAS]
+
+\installprettytype [EIFFEL] [EIF]
+\installprettytype [EIF] [EIF]
+\installprettytype [E] [EIF]
+
+\installprettytype [XML] [XML]
+
+\installprettytype [LUA] [LUA]
+
+\installnewpretty M {\setupprettiesintype {MP}\setupprettytype}
+\installnewpretty P {\setupprettiesintype {PL}\setupprettytype}
+\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype}
+\installnewpretty J {\setupprettiesintype {JV}\setupprettytype}
+\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype}
+\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth
+\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken
+\installnewpretty X {\setupprettiesintype{XML}\setupprettytype}
+
+%D We use the \CONTEXT\ color system for switching to and from
+%D color mode. We can always redefine these colors afterwards.
+
+\definecolor [colorprettyone] [r=.9, g=.0, b=.0] % red
+\definecolor [colorprettytwo] [r=.0, g=.8, b=.0] % green
+\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue
+\definecolor [colorprettyfour] [r=.8, g=.8, b=.6] % yellow
+
+\definecolor [grayprettyone] [s=.30]
+\definecolor [grayprettytwo] [s=.45]
+\definecolor [grayprettythree] [s=.60]
+\definecolor [grayprettyfour] [s=.75]
+
+\definepalet
+ [colorpretty]
+ [ prettyone=colorprettyone,
+ prettytwo=colorprettytwo,
+ prettythree=colorprettythree,
+ prettyfour=colorprettyfour]
+
+\definepalet
+ [graypretty]
+ [ prettyone=grayprettyone,
+ prettytwo=grayprettytwo,
+ prettythree=grayprettythree,
+ prettyfour=grayprettyfour]
+
+\definepalet [TEXcolorpretty] [colorpretty]
+\definepalet [TEXgraypretty] [graypretty]
+\definepalet [PLcolorpretty] [colorpretty]
+\definepalet [PLgraypretty] [graypretty]
+\definepalet [PMcolorpretty] [colorpretty]
+\definepalet [PMgraypretty] [graypretty]
+\definepalet [MPcolorpretty] [colorpretty]
+\definepalet [MPgraypretty] [graypretty]
+\definepalet [JVcolorpretty] [colorpretty]
+\definepalet [JVgraypretty] [graypretty]
+\definepalet [JScolorpretty] [colorpretty]
+\definepalet [JSgraypretty] [graypretty]
+\definepalet [SQLcolorpretty] [colorpretty]
+\definepalet [SQLgraypretty] [graypretty]
+\definepalet [PAScolorpretty] [colorpretty]
+\definepalet [PASgraypretty] [graypretty]
+\definepalet [EIFcolorpretty] [colorpretty]
+\definepalet [EIFgraypretty] [graypretty]
+\definepalet [XMLcolorpretty] [colorpretty]
+\definepalet [XMLgraypretty] [graypretty]
+\definepalet [LUAcolorpretty] [colorpretty]
+\definepalet [LUAgraypretty] [graypretty]
+
+\protect \endinput
diff --git a/tex/context/base/core-ver.mkiv b/tex/context/base/core-ver.mkiv
index dcc283d6f..e9c092f66 100644
--- a/tex/context/base/core-ver.mkiv
+++ b/tex/context/base/core-ver.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=core-ver,
-%D version=2000.10.13,
+%D version=2000.05.09,
%D title=\CONTEXT\ Core Macros,
%D subtitle=Verbatim,
%D author=Hans Hagen,
@@ -11,45 +11,122 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Core Macros / Verbatim}
+
\unprotect
-\def\mksetupprettiesintype
- {\begingroup
+\ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
+\ifx\stoplinenumbering \undefined \let\stoplinenumbering\relax \fi
+\ifx\setuplinenumbering\undefined \def\setuplinenumbering[#1]{} \fi
+
+% \type{ <crlf> char} geeft bagger
+
+%D We are going to embed the general verbatim support macros in
+%D a proper environment. First we show the common setup
+%D macro, so we know what features are supported. The options
+%D are hooked into the support macros via the \type{\obey}
+%D macros.
+
+\newif\ifslantedtypeactivated
+\newif\ifslantedtypepermitted
+
+\def\switchslantedtype
+ {\ifslantedtypepermitted
+ \ifslantedtypeactivated
+ \slantedtypeactivatedfalse\tttf
+ \else
+ \slantedtypeactivatedtrue\ttsl
+ \fi
+ \fi}
+
+\newprettytrue % movet to here from cont-sys.tex
+
+\def\prettyidentifier {TEX}
+\def\prettypalet {}
+
+\def\installprettytype
+ {\dodoubleargument\doinstallprettytype}
+
+\def\doinstallprettytype[#1][#2]% map #1 onto #2
+ {\uppercasestring#1\to\asciia
+ \uppercasestring#2\to\asciib
+ \setevalue{\??ty\??ty\asciia}{\asciib}}
+
+% \ctxluafileload{verb-tex}{}
+% \ctxluafileload{verb-mp} {}
+% \registerctxluafile{core-buf-tex}{}
+% \registerctxluafile{core-buf-mp} {}
+
+\def\setupprettiesintype#1%
+ {\uppercasestring#1\to\ascii
+ \edef\prettyidentifier{\executeifdefined{\??ty\??ty\ascii}{TEX}}%
+ \begingroup
\lowercasestring verb-\prettyidentifier\to\filename
\doonlyonce\filename{\ctxloadluafile\filename\empty}%
\endgroup}
-% todo: obeytabs|spaces|lines|pages
-
-% \def\mksetupprettytype % todo check
-% {\processingverbatimtrue % will move
-% \ctxlua{buffers.doifelsevisualizer("\prettyidentifier")}
-% {\ctxlua{buffers.setvisualizer("\prettyidentifier")}%
-% % \def\obs{\obeyedspace}%
-% % \def\bop{\bgroup\beginofpretty}%
-% % \def\eop{\endofpretty\egroup}%
-% % \def\sop{\endofpretty\egroup\bgroup\beginofpretty}}
-% }
-% {\def\obs{\obeyedspace}}}
-% \def\mkinitializeverbatim
-% {\ctxlua{buffers.visualizers.reset()}%
-% \localcolortrue % tricky, maybe not here
-% \def\obs{\obeyedspace}%
-% \def\obs{\obeyedspace}%
-% \def\bop{\bgroup\beginofpretty}%
-% \def\eop{\endofpretty\egroup}%
-% \def\sop{\endofpretty\egroup\bgroup\beginofpretty}%
-% \verbatimfont
-% \resetfontfeature
-% \obeycharacters}
-
-\def\mksetupprettytype % todo check
+\def\setupprettytype
{\processingverbatimtrue % will move
\ctxlua{buffers.visualizers.reset()}}
+\setvalue{\??tp:\c!lines:\v!yes }{\obeybreakpoints}
+\setvalue{\??tp:\c!lines:\v!hyphenated}{\obeyhyphens}
+
+\setvalue{\??tp:\c!empty:\v!yes }{\obeyemptylines}
+\setvalue{\??tp:\c!empty:\v!all }{\obeyallemptylines}
+
+\setvalue{\??tp:\c!option:\v!none }{\let\obeycharacters\relax}
+\setvalue{\??tp:\c!option:\v!color }{\setupprettiesintype{TEX}%
+ \let\obeycharacters\setupprettytype
+ \let\obeytabs\ignoretabs}
+\setvalue{\??tp:\c!option:\v!normal }{\let\obeycharacters\setupgroupedtype}
+\setvalue{\??tp:\c!option:\v!commands }{\def\obeycharacters{\setupcommandsintype}%
+ \let\obeytabs\ignoretabs}
+\setvalue{\??tp:\c!option:\v!slanted }{\let\obeycharacters\setupslantedtype
+ \let\obeytabs\ignoretabs}
+\setvalue{\??tp:\c!option:\s!unknown }{\setupprettiesintype{\typingparameter\c!option}%
+ \let\obeycharacters\setupprettytype
+ \let\obeytabs\ignoretabs}
+
+
+\def\setupcommonverbatim
+ {\recatcodeuppercharactersfalse % obey regime / encoding
+ %
+ \let\prettyidentifier\s!default
+ %
+ \doifelse{\typingparameter\c!text}\v!yes
+ \naturaltextexttrue
+ \naturaltextextfalse
+ \def\prettyidentifierfont{\typingparameter\c!icommand}%
+ \def\prettyvariablefont {\typingparameter\c!vcommand}%
+ \def\prettynaturalfont {\typingparameter\c!ccommand}%
+ %
+ \doif{\typingparameter\c!space}\v!on
+ {\def\obeyspaces{\setcontrolspaces}}%
+ \doif{\typingparameter\c!page }\v!no
+ {\def\obeypages {\ignorepages}}%
+ %
+ \doifelse{\typingparameter\c!tab}\v!yes
+ {\def\obeytabs{\settabskips}}%
+ {\doif{\typingparameter\c!tab}\s!ascii % not needed in mkiv
+ {\chardef\tabskipmode\plustwo % quit on >127
+ \def\obeytabs{\settabskips}}}%
+ %
+ \ignorehyphens % default
+ \getvalue{\??tp:\c!lines:\typingparameter\c!lines}%
+ \getvalue{\??tp:\c!empty:\typingparameter\c!empty}%
+ \getvalue{\??tp:\c!option:\ifcsname\??tp:\c!option:\typingparameter\c!option\endcsname\typingparameter\c!option\else\s!unknown\fi}%
+ \doifnumberelse{\typingparameter\c!tab}
+ {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
+ \donothing
+ %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
+ % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
+ \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
+ \setupverbatimcolor}
+
\newtoks \everyinitializeverbatim
-\def\mkinitializeverbatim
+\def\doinitializeverbatim
{\ctxlua{buffers.visualizers.reset()}%
\def\obs{\obeyedspace}%
\ctxlua{buffers.doifelsevisualizer("\prettyidentifier")}
@@ -69,37 +146,116 @@
\resetcharacterspacing
\to \everyinitializeverbatim
-% \ctxluafileload{verb-tex}{}
-% \ctxluafileload{verb-mp} {}
-
-% \registerctxluafile{core-buf-tex}{}
-% \registerctxluafile{core-buf-mp} {}
-
-% \def\mktype#1%
-% {\bgroup
-% \begstrut % new, enables leading space in \type { abc } at par start
-% \let\currenttypingclass\??ty
-% \edef\currenttyping{#1}%
-% \initializetype % probably too much
-% \verbatimcolor
-% \setcatcodetable \typcatcodesa
-% \dodotype}
-% \def\dodotype#1%
-% {\obeycharacters % everyinitializeverbatim
-% \ctxlua{buffers.hooks.flush_line(\!!bs\detokenize{#1}\!!es)}%
-% \egroup}
+% BEWARE: the noligatures will globally change the verbatim font's behaviour
-\let\mksetupslantedtype \relax
+% test case:
+%
+% \definetype[typeTEX][option=tex]
+%
+% \typeTEX|\example---oeps|. this---ligates---again.
+% \typeTEX{\example---oeps}. this---ligates---again.
+% \type {\example---oeps}. this---ligates---again.
-\def\mksetupcommandsintype% can also be \string\
+\def\setupcommandsintype % can also be \string\
{\ctxlua{
buffers.visualizers.enableescape = true
buffers.visualizers.escapetoken = \!!bs\typingparameter\c!escape\!!es
}%
\setevalue{\typingparameter\c!escape}{\typingparameter\c!escape}}
-\def\mktype#1% was \dotype
+\def\setupslantedtype
+ {\slantedtypepermittedtrue}
+
+\ifx\setupprettytype \undefined \let\setupprettytype \relax \fi
+\ifx\setupslantedtype \undefined \let\setupslantedtype \relax \fi
+\ifx\setupgroupedtype \undefined \let\setupgroupedtype \relax \fi
+\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi
+
+%D The verbatim commands have a rather long and turbulent
+%D history. Most users of \CONTEXT\ probably will never use
+%D some of the features, but I've kept in mind that when one is
+%D writing a users manual, about everything can and undoubtly
+%D will be subject to a verbatim treatment.
+%D
+%D Verbatim command are very sensitive to argument processing,
+%D which is a direct result of the \CATCODES\ being fixed at
+%D reading time. With our growing understanding of \TEX,
+%D especially of the mechanism that can be used for looking
+%D ahead and manipulating \CATCODES, the verbatim support
+%D became more and more advanced and natural.
+%D
+%D Typesetting inline verbatim can be accomplished by
+%D \type{\type}, which in this sentence was typeset by saying
+%D just \type{\type{\type}}, which in turn was typeset by
+%D \unknown. Using the normal grouping characters \type{{}} is
+%D the most natural way of using this command.
+%D
+%D A second, more or less redundant, alternative is delimiting
+%D the argument with an own character. This method was
+%D implemented in the context of a publication in the \MAPS,
+%D where this way of delimiting is recognized by \LATEX\ users.
+%D
+%D The third, more original alternative, is the one using
+%D \type{<<} and \type{>>} as delimiters. This alternative can
+%D be used in situations where slanted typeseting is needed.
+
+% todo: we can use \letter... here:
+
+\def\lesscharacter {<}
+\def\morecharacter {>}
+
+\chardef\texescape = `\\
+\chardef\leftargument = `\{
+\chardef\rightargument = `\}
+
+%D \macros
+%D {type}
+%D
+%D We define \type{\type} as a protected command. This command
+%D has several invocations: grouped, wirt boundary characters,
+%D and with font switches.
+
+% \starttyping
+% normal: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
+% normal: \par \type{xx<..xx..<xx <slanted> >..>xx} \par \type{<....>} \par \type{<..<xx>..>}
+% \setuptype[option=slanted]
+% slanted: \par \type{xx<<..sl..<<xx <<sl>> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<<sl>>..>> \par
+% slanted: \par \type{xx<<..sl..<xx <sl> xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<sl>..>> \par
+% \setuptype[option=none]
+% none: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
+% \stoptyping
+
+%D When writing the manual to \CONTEXT\ and documenting this
+%D source we needed to typeset \type{<<} and \type{>>}. Because
+%D we wanted to do this in the natural way, we've adapted the
+%D original definition a bit. This implementation went through
+%D several live cycles. The final implementation looks a bit
+%D further and treats the lone \type{<<} and \type{>>} a bit
+%D different. The \type {\null} prevents ligatures, which
+%D unfortunately turn up in Lucida fonts.
+
+%D The following lines show what happens when we set
+%D \type {option=commands}.
+%D
+%D \startbuffer
+%D \starttyping
+%D test//test test/BTEX \footnote{test test test}/ETEX test
+%D test//test test/BTEX \footnote{test test test}/ETEX test
+%D test test test/BTEX \bf(nota bene)/ETEX test
+%D test test test /BTEX \bf(nota bene)/ETEX test
+%D \stoptyping
+%D \stopbuffer
+%D
+%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup
+%D
+%D this was keyed in as:
+%D
+%D \typebuffer
+
+\unexpanded\def\type{\dotype\empty}
+
+\def\dotype#1% was \dotype
{\bgroup
\begstrut % new, enables leading space in \type { abc } at par start / begstrut else no hyphenation
\let\currenttypingclass\??ty
@@ -124,7 +280,7 @@
\dodotypeAA}
\def\dodotypeAA#1%
- {\mkinitializeverbatim
+ {\doinitializeverbatim
\def\obs{\obeyedspace}%
\ctxlua{buffers.hooks.flush_line(\!!bs\detokenize{#1}\!!es)}%
\egroup}
@@ -136,7 +292,7 @@
\dodotypeBB}
\def\dodotypeBB#1%
- {\mkinitializeverbatim
+ {\doinitializeverbatim
\ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,false)}%
\egroup
\gobbleoneargument} % grab last >
@@ -148,7 +304,7 @@
\dodotypeCC}
\def\dodotypeCC#1%
- {\mkinitializeverbatim
+ {\doinitializeverbatim
\ifx\obeycharacters\setupprettytype % temp hack, we need a proper signal
\ctxlua{buffers.hooks.flush_line([\!!bs\detokenize{#1}\!!es,true)}%
\else
@@ -166,33 +322,827 @@
\dodotypeDD}
\def\dodotypeDD#1%
- {\mkinitializeverbatim
+ {\doinitializeverbatim
\ctxlua{buffers.hooks.flush_line(\!!bs\detokenize{#1}\!!es,true)}%
\egroup
\gobbleoneargument} % grab last >
-% \typing:
+%D The neccessary initializations are done by calling
+%D \type{\initializetype} which in return calls for the support
+%D macro \type{\setupinlineverbatim}.
+
+\def\initializetype
+ {\let\obeylines\ignorelines
+ \setupcommonverbatim
+ \setupinlineverbatim}
+
+%D \macros
+%D {setuptype}
+%D
+%D Some characteristics of \type{\type} can be set up by:
+
+\def\setuptype
+ {\dodoubleempty\dosetuptype}
+
+\def\dosetuptype[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??ty#1][#2]%
+ \else
+ \getparameters[\??ty][#1]%
+ \fi}
+
+%D \macros
+%D {typ,obeyhyphens,obeybreakpoints}
+%D
+%D Although it's not clear from the macros, one character
+%D trait of this macros, which are build on top of the support
+%D module, is that they don't hyphenate. We therefore offer
+%D the alternative \type{\typ}. The current implementation
+%D works all right, but a decent hyphenation support of
+%D \type{\tt} text will be implemented soon.
+
+\def\obeyhyphens
+ {\def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
+ \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}%
+ \spaceskip.25em\relax} % hm a bit of stretch !
+
+\def\obeybreakpoints
+ {\ignorehyphens
+ \veryraggedright}
+
+\def\ignorehyphens
+ {% \language\minusone % extra bonus, the \null should do the job too
+ \def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
+ \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}%
+ \spaceskip.5em\relax}
+
+\unexpanded\def\typ
+ {\bgroup
+ \let\@@tylines\v!hyphenated
+ \futurelet\next\dodotype}
+
+%D \macros
+%D {tex,arg,mat,dis}
+%D
+%D Sometimes, for instance when we pass verbatim text as an
+%D argument, the fixed \CATCODES\ interfere with our wishes. An
+%D experimental implementation of character by character
+%D processing of verbatim text did overcome this limitation,
+%D but we've decided not to use that slow and sometimes
+%D troublesome solution. Instead we stick to some 'old'
+%D \CONTEXT\ macros for typesetting typical \TEX\ characters.
+%D
+%D The next implementation is more clear but less versatile,
+%D so we treated it for a beter one.
+%D
+%D \starttyping
+%D \def\dospecialtype#1#2%
+%D {\bgroup
+%D \initializetype
+%D \catcode`\{=\@@begingroup
+%D \catcode`\}=\@@endgroup
+%D \def\dospecialtype%
+%D {\def\dospecialtype{#2\egroup}%
+%D \bgroup
+%D \aftergroup\dospecialtype
+%D #1}%
+%D \afterassignment\dospecialtype
+%D \let\next=}
+%D
+%D \unexpanded\def\tex{\dospecialtype\texescape\relax}
+%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument}
+%D \unexpanded\def\mat{\dospecialtype\$\$}
+%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}}
+%D \stoptyping
+
+\def\setgroupedtype
+ {\let\currenttypingclass\??ty
+ \initializetype
+ \verbatimcolor
+ %\setcatcodetable \typcatcodesa
+ \catcode`\{=\@@begingroup
+ \catcode`\}=\@@endgroup}
+
+\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}}
+\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}}
+\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}}
+\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}}
+
+%D \macros
+%D {starttyping}
+%D
+%D Display verbatim is realized far more easy, which is mostly
+%D due to the fact that we use \type{\stop...} as delimiter.
+%D The implementation inherits some features, for instance the
+%D support of linenumbering, which can best be studied in the
+%D documented support module.
+
+\let\currenttyping \empty
+\let\currenttypingclass\??ty % saveguard
+
+% \def\typingparameter#1%
+% {\executeifdefined
+% {\currenttypingclass\currenttyping#1}%
+% {\executeifdefined{\currenttypingclass#1}\empty}}
+
+\def\typingparameter#1%
+ {\ifcsname\currenttypingclass\currenttyping#1\endcsname
+ \csname\currenttypingclass\currenttyping#1\endcsname
+ \else\ifcsname\currenttypingclass#1\endcsname
+ \csname\currenttypingclass#1\endcsname
+ \fi\fi}
+
+\def\settypingparameter#1#2%
+ {\setvalue{\currenttypingclass\currenttyping#1}{#2}}
+
+\def\setxtypingparameter#1#2%
+ {\setxvalue{\currenttypingclass\currenttyping#1}{#2}}
+
+% \def\initializetyping
+% {%\donefalse
+% \switchtobodyfont[\typingparameter\c!bodyfont]%
+% \donefalse
+% \scratchskip\typingparameter\c!oddmargin\relax
+% \ifzeropt\scratchskip\else\donetrue\fi
+% \scratchskip\typingparameter\c!evenmargin\relax
+% \ifzeropt\scratchskip\else\donetrue\fi
+% \ifdone
+% \def\doopenupverbatimline
+% {\getpagestatus
+% \ifrightpage
+% \hskip\typingparameter\c!oddmargin\relax
+% \else
+% \hskip\typingparameter\c!evenmargin\relax
+% \fi}%
+% \else
+% \doadaptleftskip{\typingparameter\c!margin}%
+% \fi
+% \doifdefinedelse{\??bo\typingparameter\c!blank}
+% {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}}
+% {\edef\!!stringa{\typingparameter\c!blank}}%
+% \processaction
+% [\!!stringa]
+% [ \v!standard=>\scratchskip\ctxparskip,
+% \v!small=>\scratchskip\blankokleinmaat,
+% \v!medium=>\scratchskip\blankomiddelmaat,
+% \v!big=>\scratchskip\blankogrootmaat,
+% \v!halfline=>\scratchskip.5\baselineskip,
+% \v!line=>\scratchskip\baselineskip,
+% \v!none=>\scratchskip\zeropoint,
+% \s!unknown=>\scratchskip\commalistelement]%
+% \ifgridsnapping
+% \ifdim\scratchskip=.5\baselineskip\relax
+% \edef\verbatimbaselineskip{\the\scratchskip}% new
+% \else
+% \edef\verbatimbaselineskip{\the\baselineskip}%
+% \fi
+% \else
+% \edef\verbatimbaselineskip{\the\scratchskip}%
+% \fi
+% \setupcommonverbatim}
+
+\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip}
+\setvalue{\??tp:\c!blank:\v!small }{\blankokleinmaat}
+\setvalue{\??tp:\c!blank:\v!medium }{\blankomiddelmaat}
+\setvalue{\??tp:\c!blank:\v!big }{\blankogrootmaat}
+\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip}
+\setvalue{\??tp:\c!blank:\v!line }{\baselineskip}
+\setvalue{\??tp:\c!blank:\v!none }{\zeropoint}
+
+\def\initializetyping
+ {%\donefalse
+ \switchtobodyfont[\typingparameter\c!bodyfont]%
+ \donefalse
+ \scratchskip\typingparameter\c!oddmargin\relax
+ \ifzeropt\scratchskip\else\donetrue\fi
+ \scratchskip\typingparameter\c!evenmargin\relax
+ \ifzeropt\scratchskip\else\donetrue\fi
+ \ifdone
+ \def\doopenupverbatimline
+ {\getpagestatus
+ \ifrightpage
+ \hskip\typingparameter\c!oddmargin\relax
+ \else
+ \hskip\typingparameter\c!evenmargin\relax
+ \fi}%
+ \else
+ \doadaptleftskip{\typingparameter\c!margin}%
+ \fi
+ \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}%
+ \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax
+ \ifgridsnapping
+ \ifdim\scratchskip=.5\baselineskip\relax
+ \edef\verbatimbaselineskip{\the\scratchskip}% new
+ \else
+ \edef\verbatimbaselineskip{\the\baselineskip}%
+ \fi
+ \else
+ \edef\verbatimbaselineskip{\the\scratchskip}%
+ \fi
+ \setupcommonverbatim}
+
+%D The basic display verbatim commands are defined in an
+%D indirect way. As we will see, they are a specific case of a
+%D more general mechanism.
+
+% we need this hack because otherwise verbatim skips
+% the first line (everything after the initial command)
+
+\def\dostarttyping#1% tricky non standard lookahead
+ {\bgroup
+ \let\currenttypingclass\??tp
+ \edef\currenttyping{#1}%
+ \obeylines
+ \futurelet\nexttoken\dodostarttyping}
+
+\def\dodostarttyping
+ {\ifx\nexttoken[%
+ \expandafter\dododostarttyping
+ \else
+ \expandafter\nododostarttyping
+ \fi}
+
+\def\nododostarttyping
+ {\dododostarttyping[]}
-\def\mktypeblockverbatim#1#2%
+\def\dotypefileverbatim
+ {\doinitializeverbatim
+ \ctxlua{buffers.typefile("\readfilename")}}
+
+\def\dotypefilelinesverbatim#1#2%
+ {#1%
+ \doinitializeverbatim
+ \ctxlua{buffers.typefile("\readfilename")}%
+ #2}
+
+\def\dotypeblockverbatim#1#2%
{\dowithbuffer{_typing_}{#1}{#2}
{}
- {\mkinitializeverbatim
+ {\doinitializeverbatim
\beginofverbatimlines
\ctxlua{buffers.type("_typing_")}%
\endofverbatimlines
\getvalue{\strippedcsname#2}}}
-% \typefile:
+\def\dododostarttyping[#1]%
+ {\typingparameter\c!before
+ \startpacked % includes \bgroup
+ \dosetuptypelinenumbering{#1}%
+ \initializetyping
+ \startverbatimcolor
+ \expanded{\dotypeblockverbatim{\s!start\currenttyping}{\s!stop\currenttyping}}}
-\def\mktypefileverbatim
- {\mkinitializeverbatim
- \ctxlua{buffers.typefile("\readfilename")}}
+\def\dostoptyping#1% hm, currenttyping
+ {\stopverbatimcolor
+ \stoppacked % includes \egroup
+ \typingparameter\c!after
+ \egroup
+ \dochecknextindentation{\??tp#1}%
+ \dorechecknextindentation}
-\def\mktypefilelinesverbatim#1#2%
- {#1%
- \mkinitializeverbatim
- \ctxlua{buffers.typefile("\readfilename")}%
- #2}
+%D Line numbering for files is combined with filtering, while
+%D display verbatim has the ability to continue.
+%D
+%D \starttyping
+%D \typefile[numbering=file,start=10,stop=12]{test.tex}
+%D
+%D \definetyping[code][numbering=line]
+%D
+%D \starttext
+%D \startcode
+%D ...
+%D ...
+%D \stopcode
+%D
+%D \startcode[continue]
+%D ...
+%D ...
+%D \stopcode
+%D
+%D \startcode[start=10]
+%D ...
+%D \stopcode
+%D \stoptyping
+
+%D \macros
+%D {setuptyping}
+%D
+%D The setup of typing accepts two arguments. The optional
+%D first one identifies the user defined ones. If only one
+%D argument is given, the values apply to both the standard
+%D command \type{\starttyping} and \type{\typefile}.
+
+\def\dosetuptyping[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??tp#1][#2]%
+ \else
+ \getparameters[\??tp][#1]%
+ \fi}
+
+\def\setuptyping
+ {\dodoubleempty\dosetuptyping}
+
+%D \macros
+%D {definetype}
+%D
+%D Specific inline verbatim commands can be defined with the
+%D following command.
+
+\def\definetype
+ {\dodoubleempty\dodefinetype}
+
+\def\dodefinetype[#1][#2]%
+ {\unexpanded\setvalue{#1}{\dotype{#1}}%
+ \getparameters[\??ty#1][#2]}
+
+%D \macros
+%D {definetyping}
+%D
+%D For most users the standard \type{\start}||\type{\stop}||pair
+%D will suffice, but for documentation purposes the next
+%D definition command can be of use:
+%D
+%D \starttyping
+%D \definetyping[extratyping][margin=3em]
+%D
+%D \startextratyping
+%D these extra ones are indented by 1 em
+%D \stopextratyping
+%D \stoptyping
+%D
+%D The definitions default to the standard typing values.
+
+\def\presettyping[#1][#2]%
+ {\copyparameters[\??tp#1][\??tp][\c!color,\c!style]%
+ \getparameters [\??tp#1][#2]}
+
+\def\dodefinetyping[#1][#2]%
+ {\setvalue{\e!start#1}{\dostarttyping{#1}}%
+ \setvalue{\e!stop #1}{\dostoptyping {#1}}%
+ \presettyping[#1][#2]}
+
+\def\definetyping
+ {\dodoubleempty\dodefinetyping}
+
+%D We can use some core color commands. These are faster than
+%D the standard color switching ones and work ok on a line by
+%D line basis.
+%D
+%D \starttyping
+%D \def\setupverbatimcolor%
+%D {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}%
+%D \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
+%D \def\endofpretty {\stopcolormode}}
+%D \stoptyping
+%D
+%D Since we support a global color too, the folowing
+%D definition is better:
+
+% \def\setupverbatimcolor% fast and local versus slow and global
+% {\doifelsenothing{\typingparameter\c!color}
+% {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
+% \let\endofpretty \restorecolormode % \stopcolormode
+% \let\startverbatimcolor \relax
+% \let\stopverbatimcolor \relax
+% \let\verbatimcolor \relax}
+% {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
+% \let\endofpretty \stopcolor
+% \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
+% \let\stopverbatimcolor \stopcolor
+% \def\verbatimcolor {\getvalue{\typingparameter\c!color}}}% command !
+% \doifelsenothing{\typingparameter\c!palet}
+% {\let\prettypalet\empty
+% \let\endofpretty\relax
+% \def\beginofpretty[##1]{}}
+% {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
+%
+% let's forget about this optimization not that we have mkiv
+
+\def\setupverbatimcolor
+ {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
+ \let\endofpretty \stopcolor
+ \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
+ \let\stopverbatimcolor \stopcolor
+ \def\verbatimcolor {\getvalue{\typingparameter\c!color}}% command !
+ \doifelsenothing{\typingparameter\c!palet}
+ {\let\prettypalet\empty
+ \let\endofpretty\relax
+ \def\beginofpretty[##1]{}}
+ {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
+
+\let\prettypalet \empty
+\let\startverbatimcolor\relax
+\let\stopverbatimcolor \relax
+\let\verbatimcolor \relax
+
+%D In the verbatim module, there are some examples given of
+%D the more obscure features of the verbatim environments.
+%D
+%D \startbuffer
+%D \startTEX
+%D \def\mathematics#1% % usage: \type {\mathematics{x^2}}
+%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2}
+%D \stopTEX
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This gives, as can be expected:
+%D
+%D \getbuffer
+%D
+%D When we want to see some typeset \TEX\ too, we can say:
+%D
+%D \startbuffer
+%D \startTEX
+%D \def\mathematics#1% %%\ N usage: \type {\mathematics{x^2}}
+%D {\ifmmode#1\else$#1$\fi} %%\ N becomes: \mathematics{x^2}
+%D \stopTEX
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D or:
+%D
+%D \getbuffer
+%D
+%D In a similar way:
+%D
+%D \startbuffer
+%D \startSQL
+%D select * -- indeed, here we {\em do} select
+%D from tableA
+%D where 1 = 2
+%D \stopSQL
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives:
+%D
+%D \getbuffer
+%D
+%D The next examples sow how we can directly call for natural
+%D \TEX\ comments:
+%D
+%D \startbuffer
+%D \setuptyping
+%D [TEX]
+%D [text=yes]
+%D
+%D \startTEX
+%D \def\mathematics#1% % usage: \type {\mathematics{x^2}}
+%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2}
+%D \stopTEX
+%D
+%D \setuptyping
+%D [SQL]
+%D [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it]
+%D
+%D \startSQL
+%D select * -- indeed, here we {\em do} select
+%D from tableA
+%D where 1 = 2
+%D \stopSQL
+%D
+%D \setuptyping
+%D [SQL]
+%D [ccommand=\tf\underbar]
+%D
+%D \startSQL
+%D select * -- indeed, here we {\em do} select
+%D from tableA
+%D where 1 = 2
+%D \stopSQL
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Now watch:
+%D
+%D \getbuffer
+%D
+%D The natural \TEX\ typesetting was introduced when Tobias
+%D and Berend started using verbatim \JAVASCRIPT\ and \SQL.
+
+%D \macros
+%D {EveryPar, EveryLine, iflinepar}
+%D
+%D One of the features of these commands is the support of
+%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}.
+%D In the documentation of the verbatim support module we give
+%D some examples of line- and paragraph numbering using these
+%D macros.
+
+%D \macros
+%D {typefile}
+%D
+%D Typesetting files verbatim (for the moment) only supports
+%D colorization of \TEX\ sources as valid option. The other
+%D setup values are inherited from display verbatim.
+%D The implementation of \type{\typefile} is straightforward:
+
+% new feature (not yet 100\% ok)
+%
+% \setuptyping[file][numbering=file]
+%
+% \typefile[start=2,nlines=3]{zapf}
+% \typefile[start=continue,nlines=13]{zapf}
+% \typefile{zapf}
+%
+% \setuptyping[file][numbering=line]
+%
+% \typefile[start=4,step=3]{zapf}
+% \typefile{zapf}
+
+\def\typefile
+ {\dodoubleempty\dotypefile}
+
+\def\dotypefile[#1][#2]#3%
+ {\ifsecondargument
+ \dodotypefile[#1][#2]{#3}%
+ \else\iffirstargument
+ \doifassignmentelse{#1}
+ {\dodotypefile[\v!file][#1]{#3}}
+ {\dodotypefile[#1][]{#3}}%
+ \else
+ \dodotypefile[\v!file][]{#3}%
+ \fi\fi}
+
+\def\dosetuptypelinenumbering#1% fuzzy
+ {\doifundefined{\currenttypingclass\currenttyping\c!start}
+ {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}%
+ \setuptyping[\currenttyping][#1]%
+ \doifelse{\typingparameter\c!numbering}\v!file
+ {% kind of special: filters lines !
+ \setuplinenumbering[\c!method=\v!file]%
+ \donetrue}
+ {\doifelse{\typingparameter\c!numbering}\v!line
+ {% \setuplinenumbering defaults start/step to 1/1, so we need
+ \doifinsetelse\v!continue{#1,\typingparameter\c!start}
+ {\scratchcounter0\typingparameter\c!n
+ \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}%
+ {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}%
+ \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}%
+ \setuplinenumbering
+ [\c!method=\v!type,
+ \c!start=\typingparameter\c!start,
+ \c!stop=\typingparameter\c!stop,
+ \c!step=\typingparameter\c!step]%
+ \donetrue}
+ {\donefalse}}%
+ \ifdone
+ \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
+ \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi
+ \def\beginofverbatimlines{\startlinenumbering}%
+ \def\endofverbatimlines {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}%
+ \fi}
+
+\def\reporttypingerror#1% temp hack
+ {\blank
+ \dontleavehmode\hbox\bgroup
+ \expanded{\defconvertedargument\noexpand\ascii{#1}}%
+ \tttf[\makemessage\m!verbatims1\ascii]%
+ \showmessage\m!verbatims1\ascii
+ \egroup
+ \blank}
+
+\def\dosometyping#1#2#3#4#5%
+ {\bgroup
+ \let\currenttypingclass\??tp
+ \edef\currenttyping{#1}%
+ \typingparameter\c!before
+ \startpacked % includes \bgroup
+ \dosetuptypelinenumbering{#2}%
+ \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal}
+ {\setuptyping[#1][\c!option=\v!none]}%
+ \doif{\typingparameter\c!option}\v!color
+ {\expandafter\aftersplitstring#3\at.\to\prettyidentifier
+ \settypingparameter\c!option{\prettyidentifier}}%
+ \initializetyping
+ \startverbatimcolor
+ \doifundefinedelse{\currenttypingclass#3\v!global\c!start}
+ {\scratchcounter\zerocount}
+ {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}%
+ \advance\scratchcounter\plusone
+ \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}%
+ \doifelsenothing{\typingparameter\c!start}
+ {#4}
+ {\doif{\typingparameter\c!start}\v!continue
+ {\setevalue{\currenttypingclass#1\c!start}%
+ {\getvalue{\currenttypingclass#3\v!global\c!start}}}%
+ \doifelsenothing{\typingparameter\c!stop}
+ {\doifelsenothing{\typingparameter\c!nlines}
+ {#4}
+ {\setxvalue{\currenttypingclass#3\v!global\c!start}%
+ {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}%
+ #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}%
+ {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}%
+ \stopverbatimcolor
+ \stoppacked
+ \typingparameter\c!after
+ \egroup}
+
+\def\doifelsetypingfile#1% sets \readfilename (we will make this proper mkiv i.e. less messy)
+ {\doiflocfileelse{#1}
+ {\firstoftwoarguments}
+ {\doifinputfileelse{#1}
+ {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments} % messy, looks wrong too
+ {\secondoftwoarguments}}}
+
+\def\dodotypefile[#1][#2]#3%
+ {\doifelsetypingfile{#3}
+ {\dosometyping{#1}{#2}{#3}\dotypefileverbatim\dotypefilelinesverbatim}
+ {\reporttypingerror{#3}}}
+
+%D \macros
+%D {filename}
+%D
+%D Typesetting filenames in monospaced fonts is possible with
+%D
+%D \starttyping
+%D \filename{here/there/filename.suffix}
+%D \stoptyping
+%D
+%D The definition is not that spectacular.
+
+\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}}
+
+%D This leaves some settings:
+
+\permitshiftedendofverbatim
+\optimizeverbatimtrue
+
+%D And a bonus macro:
+
+\def\verbatim#1{\defconvertedargument\ascii{#1}\ascii}
+
+%D The setups for display verbatim and file verbatim are
+%D shared. One can adapt the extra defined typing environments,
+%D but they also default to the values below. Watch the
+%D alternative escape character.
+
+\setuptyping
+ [ \c!before=\blank,
+ \c!after=\blank,
+ \c!bodyfont=,
+ \c!color=,
+ \c!space=\v!off,
+ \c!page=\v!no,
+ \c!tab=\s!ascii,
+ \c!option=\v!none,
+ \c!palet=colorpretty,
+ \c!text=\v!no,
+ \c!style=\tttf,
+ \c!icommand=\ttsl,
+ \c!vcommand=,
+ \c!ccommand=\tttf,
+ \c!indentnext=\v!yes,
+ \c!margin=\!!zeropoint,
+ \c!evenmargin=\!!zeropoint,
+ \c!oddmargin=\!!zeropoint,
+ \c!blank=\v!line,
+ \c!escape=/, % beware \string\ , should also be accepted
+ \c!numbering=\v!no,
+ \c!lines=,
+ \c!empty=,
+ \c!start=1,
+ \c!stop=,
+ \c!step=1,
+ \c!continue=,
+ \c!nlines=]
+
+\definetyping[\v!typing]
+
+\presettyping[\v!file][]
+
+% \setuptyping % not needed
+% [\v!file]
+% [\c!start=1,
+% \c!stop=,
+% \c!step=1,
+% \c!continue=,
+% \c!nlines=]
+
+%D The setups for inline verbatim default to:
+
+\setuptype
+ [ \c!space=\v!off,
+ \c!color=,
+ \c!style=\tt\tf, % \tttf gives problems with {\tx \type...}
+ \c!page=\v!no,
+ \c!tab=\v!yes,
+ \c!palet=colorpretty,
+ \c!option=\v!normal]
+
+\definetyping[RAW] [\c!option=RAW]
+\definetyping[MP] [\c!option=MP]
+\definetyping[PL] [\c!option=PL]
+\definetyping[PM] [\c!option=PL]
+\definetyping[JS] [\c!option=JS]
+\definetyping[JV] [\c!option=JV]
+\definetyping[SQL] [\c!option=SQL]
+\definetyping[TEX] [\c!option=TEX]
+\definetyping[PAS] [\c!option=PAS]
+\definetyping[PASCAL][\c!option=PAS]
+\definetyping[MOD] [\c!option=PAS]
+\definetyping[MODULA][\c!option=PAS]
+\definetyping[DELPHI][\c!option=PAS]
+\definetyping[EIFFEL][\c!option=EIF]
+\definetyping[XML] [\c!option=XML]
+\definetyping[LUA] [\c!option=LUA]
+
+\installprettytype [RAW] [RAW]
+
+\installprettytype [TEX] [TEX]
+
+\installprettytype [PERL] [PL]
+\installprettytype [PL] [PL]
+\installprettytype [PM] [PL]
+
+\installprettytype [METAPOST] [MP]
+\installprettytype [METAFONT] [MP]
+\installprettytype [MP] [MP]
+\installprettytype [MF] [MP]
+
+\installprettytype [JAVASCRIPT] [JS]
+\installprettytype [JAVA] [JV]
+\installprettytype [JS] [JS]
+\installprettytype [JV] [JV]
+
+\installprettytype [SQL] [SQL]
+
+\installprettytype [PASCAL] [PAS]
+\installprettytype [PAS] [PAS]
+\installprettytype [MODULA] [PAS]
+\installprettytype [MOD] [PAS]
+
+\installprettytype [EIFFEL] [EIF]
+\installprettytype [EIF] [EIF]
+\installprettytype [E] [EIF]
+
+\installprettytype [XML] [XML]
+
+\installprettytype [LUA] [LUA]
+
+\installnewpretty M {\setupprettiesintype {MP}\setupprettytype}
+\installnewpretty P {\setupprettiesintype {PL}\setupprettytype}
+\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype}
+\installnewpretty J {\setupprettiesintype {JV}\setupprettytype}
+\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype}
+\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth
+\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken
+\installnewpretty X {\setupprettiesintype{XML}\setupprettytype}
+
+%D We use the \CONTEXT\ color system for switching to and from
+%D color mode. We can always redefine these colors afterwards.
+
+\definecolor [colorprettyone] [r=.9, g=.0, b=.0] % red
+\definecolor [colorprettytwo] [r=.0, g=.8, b=.0] % green
+\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue
+\definecolor [colorprettyfour] [r=.8, g=.8, b=.6] % yellow
+
+\definecolor [grayprettyone] [s=.30]
+\definecolor [grayprettytwo] [s=.45]
+\definecolor [grayprettythree] [s=.60]
+\definecolor [grayprettyfour] [s=.75]
+
+\definepalet
+ [colorpretty]
+ [ prettyone=colorprettyone,
+ prettytwo=colorprettytwo,
+ prettythree=colorprettythree,
+ prettyfour=colorprettyfour]
+
+\definepalet
+ [graypretty]
+ [ prettyone=grayprettyone,
+ prettytwo=grayprettytwo,
+ prettythree=grayprettythree,
+ prettyfour=grayprettyfour]
+
+\definepalet [TEXcolorpretty] [colorpretty]
+\definepalet [TEXgraypretty] [graypretty]
+\definepalet [PLcolorpretty] [colorpretty]
+\definepalet [PLgraypretty] [graypretty]
+\definepalet [PMcolorpretty] [colorpretty]
+\definepalet [PMgraypretty] [graypretty]
+\definepalet [MPcolorpretty] [colorpretty]
+\definepalet [MPgraypretty] [graypretty]
+\definepalet [JVcolorpretty] [colorpretty]
+\definepalet [JVgraypretty] [graypretty]
+\definepalet [JScolorpretty] [colorpretty]
+\definepalet [JSgraypretty] [graypretty]
+\definepalet [SQLcolorpretty] [colorpretty]
+\definepalet [SQLgraypretty] [graypretty]
+\definepalet [PAScolorpretty] [colorpretty]
+\definepalet [PASgraypretty] [graypretty]
+\definepalet [EIFcolorpretty] [colorpretty]
+\definepalet [EIFgraypretty] [graypretty]
+\definepalet [XMLcolorpretty] [colorpretty]
+\definepalet [XMLgraypretty] [graypretty]
+\definepalet [LUAcolorpretty] [colorpretty]
+\definepalet [LUAgraypretty] [graypretty]
% patched from verb-ini (todo)
diff --git a/tex/context/base/core-ver.tex b/tex/context/base/core-ver.tex
deleted file mode 100644
index 57dba0af1..000000000
--- a/tex/context/base/core-ver.tex
+++ /dev/null
@@ -1,1120 +0,0 @@
-%D \module
-%D [ file=core-ver,
-%D version=2000.05.09,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Verbatim,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Verbatim}
-
-\startmessages dutch library: verbatims
- title: typen
- 1: file -- bestaat niet
-\stopmessages
-
-\startmessages english library: verbatims
- title: verbatim
- 1: file -- does not exist
-\stopmessages
-
-\startmessages german library: verbatims
- title: verbatim
- 1: Datei -- existiert nicht
-\stopmessages
-
-\startmessages czech library: verbatims
- title: verbatim
- 1: soubor -- neexistuje
-\stopmessages
-
-\startmessages italian library: verbatims
- title: verbatim
- 1: il file -- non esiste
-\stopmessages
-
-\startmessages norwegian library: verbatims
- title: verbatim
- 1: fil -- eksisterer ikke
-\stopmessages
-
-\startmessages romanian library: verbatims
- title: verbatim
- 1: fisierul -- nu exista
-\stopmessages
-
-\startmessages french library: verbatims
- title: verbatim
- 1: le fichier -- n'existe pas
-\stopmessages
-
-\unprotect
-
-\ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
-\ifx\stoplinenumbering \undefined \let\stoplinenumbering\relax \fi
-\ifx\setuplinenumbering\undefined \def\setuplinenumbering[#1]{} \fi
-
-% \type{ <crlf> char} geeft bagger
-
-%D We are going to embed the general verbatim support macros in
-%D a proper environment. First we show the common setup
-%D macro, so we know what features are supported. The options
-%D are hooked into the support macros via the \type{\obey}
-%D macros.
-
-\newif\ifslantedtypeactivated
-\newif\ifslantedtypepermitted
-
-\def\switchslantedtype
- {\ifslantedtypepermitted
- \ifslantedtypeactivated
- \slantedtypeactivatedfalse\tttf
- \else
- \slantedtypeactivatedtrue\ttsl
- \fi
- \fi}
-
-\newprettytrue % movet to here from cont-sys.tex
-
-\def\prettyidentifier {TEX}
-\def\prettypalet {}
-
-\def\installprettytype
- {\dodoubleargument\doinstallprettytype}
-
-\def\doinstallprettytype[#1][#2]% map #1 onto #2
- {\uppercasestring#1\to\asciia
- \uppercasestring#2\to\asciib
- \setevalue{\??ty\??ty\asciia}{\asciib}}
-
-\def\setupprettiesintype#1%
- {\uppercasestring#1\to\ascii
- \edef\prettyidentifier{\executeifdefined{\??ty\??ty\ascii}{TEX}}%
- \mksetupprettiesintype}
-
-\def\setupprettytype{\mksetupprettytype}
-
-% \def\setupcommonverbatim
-% {\recatcodeuppercharactersfalse % obey regime / encoding
-% %
-% \let\prettyidentifier\s!default
-% %
-% \doifelse{\typingparameter\c!text}\v!yes
-% \naturaltextexttrue
-% \naturaltextextfalse
-% \def\prettyidentifierfont{\typingparameter\c!icommand}%
-% \def\prettyvariablefont {\typingparameter\c!vcommand}%
-% \def\prettynaturalfont {\typingparameter\c!ccommand}%
-% %
-% \doif{\typingparameter\c!space}\v!on
-% {\def\obeyspaces{\setcontrolspaces}}%
-% \doif{\typingparameter\c!page }\v!no
-% {\def\obeypages {\ignorepages}}%
-% %
-% \doifelse{\typingparameter\c!tab}\v!yes
-% {\def\obeytabs{\settabskips}}%
-% {\doif{\typingparameter\c!tab}\s!ascii
-% {\chardef\tabskipmode\plustwo % quit on >127
-% \def\obeytabs{\settabskips}}}%
-% %
-% \ignorehyphens % default
-% \ExpandFirstAfter\processaction
-% [\typingparameter\c!lines]
-% [ \v!yes=>\obeybreakpoints,
-% \v!hyphenated=>\obeyhyphens]%
-% \processaction
-% [\typingparameter\c!empty]
-% [\v!yes=>\obeyemptylines,
-% \v!all=>\obeyallemptylines]%
-% %
-% \ExpandFirstAfter\processaction
-% [\typingparameter\c!option]
-% [ \v!none=>\let\obeycharacters\relax,
-% \v!color=>\setupprettiesintype{TEX}%
-% \let\obeycharacters\setupprettytype
-% \let\obeytabs\ignoretabs,
-% \v!normal=>\let\obeycharacters\setupgroupedtype,
-% \v!commands=>\def\obeycharacters{\setupcommandsintype}% \let
-% \let\obeytabs\ignoretabs,
-% \v!slanted=>\let\obeycharacters\setupslantedtype
-% \let\obeytabs\ignoretabs,
-% \s!unknown=>\setupprettiesintype{\typingparameter\c!option}%
-% \let\obeycharacters\setupprettytype
-% \let\obeytabs\ignoretabs]%
-% \doifnumberelse{\typingparameter\c!tab}
-% {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
-% \donothing
-% %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
-% % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
-% \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
-% \setupverbatimcolor}
-
-\setvalue{\??tp:\c!lines:\v!yes }{\obeybreakpoints}
-\setvalue{\??tp:\c!lines:\v!hyphenated}{\obeyhyphens}
-
-\setvalue{\??tp:\c!empty:\v!yes }{\obeyemptylines}
-\setvalue{\??tp:\c!empty:\v!all }{\obeyallemptylines}
-
-\setvalue{\??tp:\c!option:\v!none }{\let\obeycharacters\relax}
-\setvalue{\??tp:\c!option:\v!color }{\setupprettiesintype{TEX}%
- \let\obeycharacters\setupprettytype
- \let\obeytabs\ignoretabs}
-\setvalue{\??tp:\c!option:\v!normal }{\let\obeycharacters\setupgroupedtype}
-\setvalue{\??tp:\c!option:\v!commands }{\def\obeycharacters{\setupcommandsintype}%
- \let\obeytabs\ignoretabs}
-\setvalue{\??tp:\c!option:\v!slanted }{\let\obeycharacters\setupslantedtype
- \let\obeytabs\ignoretabs}
-\setvalue{\??tp:\c!option:\s!unknown }{\setupprettiesintype{\typingparameter\c!option}%
- \let\obeycharacters\setupprettytype
- \let\obeytabs\ignoretabs}
-
-
-\def\setupcommonverbatim
- {\recatcodeuppercharactersfalse % obey regime / encoding
- %
- \let\prettyidentifier\s!default
- %
- \doifelse{\typingparameter\c!text}\v!yes
- \naturaltextexttrue
- \naturaltextextfalse
- \def\prettyidentifierfont{\typingparameter\c!icommand}%
- \def\prettyvariablefont {\typingparameter\c!vcommand}%
- \def\prettynaturalfont {\typingparameter\c!ccommand}%
- %
- \doif{\typingparameter\c!space}\v!on
- {\def\obeyspaces{\setcontrolspaces}}%
- \doif{\typingparameter\c!page }\v!no
- {\def\obeypages {\ignorepages}}%
- %
- \doifelse{\typingparameter\c!tab}\v!yes
- {\def\obeytabs{\settabskips}}%
- {\doif{\typingparameter\c!tab}\s!ascii % not needed in mkiv
- {\chardef\tabskipmode\plustwo % quit on >127
- \def\obeytabs{\settabskips}}}%
- %
- \ignorehyphens % default
- \getvalue{\??tp:\c!lines:\typingparameter\c!lines}%
- \getvalue{\??tp:\c!empty:\typingparameter\c!empty}%
- \getvalue{\??tp:\c!option:\ifcsname\??tp:\c!option:\typingparameter\c!option\endcsname\typingparameter\c!option\else\s!unknown\fi}%
- \doifnumberelse{\typingparameter\c!tab}
- {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
- \donothing
- %\def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
- % more generic, but beware of the \redoconvertfont (else no typing in titles and such)
- \def\verbatimfont{\redoconvertfont\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
- \setupverbatimcolor}
-
-% BEWARE: the noligatures will globally change the verbatim font's behaviour
-
-% test case:
-%
-% \definetype[typeTEX][option=tex]
-%
-% \typeTEX|\example---oeps|. this---ligates---again.
-% \typeTEX{\example---oeps}. this---ligates---again.
-% \type {\example---oeps}. this---ligates---again.
-
-\def\setupcommandsintype{\mksetupcommandsintype}
-\def\setupslantedtype {\slantedtypepermittedtrue\mksetupslantedtype}
-
-\ifx\setupprettytype \undefined \let\setupprettytype \relax \fi
-\ifx\setupslantedtype \undefined \let\setupslantedtype \relax \fi
-\ifx\setupgroupedtype \undefined \let\setupgroupedtype \relax \fi
-\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi
-
-%D The verbatim commands have a rather long and turbulent
-%D history. Most users of \CONTEXT\ probably will never use
-%D some of the features, but I've kept in mind that when one is
-%D writing a users manual, about everything can and undoubtly
-%D will be subject to a verbatim treatment.
-%D
-%D Verbatim command are very sensitive to argument processing,
-%D which is a direct result of the \CATCODES\ being fixed at
-%D reading time. With our growing understanding of \TEX,
-%D especially of the mechanism that can be used for looking
-%D ahead and manipulating \CATCODES, the verbatim support
-%D became more and more advanced and natural.
-%D
-%D Typesetting inline verbatim can be accomplished by
-%D \type{\type}, which in this sentence was typeset by saying
-%D just \type{\type{\type}}, which in turn was typeset by
-%D \unknown. Using the normal grouping characters \type{{}} is
-%D the most natural way of using this command.
-%D
-%D A second, more or less redundant, alternative is delimiting
-%D the argument with an own character. This method was
-%D implemented in the context of a publication in the \MAPS,
-%D where this way of delimiting is recognized by \LATEX\ users.
-%D
-%D The third, more original alternative, is the one using
-%D \type{<<} and \type{>>} as delimiters. This alternative can
-%D be used in situations where slanted typeseting is needed.
-
-% todo: we can use \letter... here:
-
-\def\lesscharacter {<}
-\def\morecharacter {>}
-
-\chardef\texescape = `\\
-\chardef\leftargument = `\{
-\chardef\rightargument = `\}
-
-%D \macros
-%D {type}
-%D
-%D We define \type{\type} as a protected command. This command
-%D has several invocations: grouped, wirt boundary characters,
-%D and with font switches.
-
-% \starttyping
-% normal: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
-% normal: \par \type{xx<..xx..<xx <slanted> >..>xx} \par \type{<....>} \par \type{<..<xx>..>}
-% \setuptype[option=slanted]
-% slanted: \par \type{xx<<..sl..<<xx <<sl>> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<<sl>>..>> \par
-% slanted: \par \type{xx<<..sl..<xx <sl> xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<sl>..>> \par
-% \setuptype[option=none]
-% none: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
-% \stoptyping
-
-%D When writing the manual to \CONTEXT\ and documenting this
-%D source we needed to typeset \type{<<} and \type{>>}. Because
-%D we wanted to do this in the natural way, we've adapted the
-%D original definition a bit. This implementation went through
-%D several live cycles. The final implementation looks a bit
-%D further and treats the lone \type{<<} and \type{>>} a bit
-%D different. The \type {\null} prevents ligatures, which
-%D unfortunately turn up in Lucida fonts.
-
-%D The following lines show what happens when we set
-%D \type {option=commands}.
-%D
-%D \startbuffer
-%D \starttyping
-%D test//test test/BTEX \footnote{test test test}/ETEX test
-%D test//test test/BTEX \footnote{test test test}/ETEX test
-%D test test test/BTEX \bf(nota bene)/ETEX test
-%D test test test /BTEX \bf(nota bene)/ETEX test
-%D \stoptyping
-%D \stopbuffer
-%D
-%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup
-%D
-%D this was keyed in as:
-%D
-%D \typebuffer
-
-\unexpanded\def\type{\mktype\empty}
-
-\let\mktype\gobbleoneargument
-
-%D The neccessary initializations are done by calling
-%D \type{\initializetype} which in return calls for the support
-%D macro \type{\setupinlineverbatim}.
-
-\def\initializetype
- {\let\obeylines\ignorelines
- \setupcommonverbatim
- \setupinlineverbatim}
-
-%D \macros
-%D {setuptype}
-%D
-%D Some characteristics of \type{\type} can be set up by:
-
-\def\setuptype
- {\dodoubleempty\dosetuptype}
-
-\def\dosetuptype[#1][#2]%
- {\ifsecondargument
- \getparameters[\??ty#1][#2]%
- \else
- \getparameters[\??ty][#1]%
- \fi}
-
-%D \macros
-%D {typ,obeyhyphens,obeybreakpoints}
-%D
-%D Although it's not clear from the macros, one character
-%D trait of this macros, which are build on top of the support
-%D module, is that they don't hyphenate. We therefore offer
-%D the alternative \type{\typ}. The current implementation
-%D works all right, but a decent hyphenation support of
-%D \type{\tt} text will be implemented soon.
-
-\def\obeyhyphens
- {\def\obeyedspace {\hskip\interwordspace\relax}% better than spaceskip
- \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint}%
- \spaceskip.25em\relax} % hm a bit of stretch !
-
-\def\obeybreakpoints
- {\ignorehyphens
- \veryraggedright}
-
-% \def\ignorehyphens
-% {\def\obeyedspace {\null\hskip\interwordspace\null}% better than spaceskip
-% \def\controlspace{\null\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\null}%
-% \spaceskip.5em\relax}
-
-\def\ignorehyphens
- {% \language\minusone % extra bonus, the \null should do the job too
- \def\obeyedspace {\hskip\interwordspace}% better than spaceskip
- \def\controlspace{\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint}%
- \spaceskip.5em\relax}
-
-\unexpanded\def\typ
- {\bgroup
- \let\@@tylines\v!hyphenated
- \futurelet\next\dodotype}
-
-%D \macros
-%D {tex,arg,mat,dis}
-%D
-%D Sometimes, for instance when we pass verbatim text as an
-%D argument, the fixed \CATCODES\ interfere with our wishes. An
-%D experimental implementation of character by character
-%D processing of verbatim text did overcome this limitation,
-%D but we've decided not to use that slow and sometimes
-%D troublesome solution. Instead we stick to some 'old'
-%D \CONTEXT\ macros for typesetting typical \TEX\ characters.
-%D
-%D The next implementation is more clear but less versatile,
-%D so we treated it for a beter one.
-%D
-%D \starttyping
-%D \def\dospecialtype#1#2%
-%D {\bgroup
-%D \initializetype
-%D \catcode`\{=\@@begingroup
-%D \catcode`\}=\@@endgroup
-%D \def\dospecialtype%
-%D {\def\dospecialtype{#2\egroup}%
-%D \bgroup
-%D \aftergroup\dospecialtype
-%D #1}%
-%D \afterassignment\dospecialtype
-%D \let\next=}
-%D
-%D \unexpanded\def\tex{\dospecialtype\texescape\relax}
-%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument}
-%D \unexpanded\def\mat{\dospecialtype\$\$}
-%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}}
-%D \stoptyping
-
-\def\setgroupedtype
- {\let\currenttypingclass\??ty
- \initializetype
- \catcode`\{=\@@begingroup
- \catcode`\}=\@@endgroup}
-
-\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}}
-\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}}
-\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}}
-\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}}
-
-%D \macros
-%D {starttyping}
-%D
-%D Display verbatim is realized far more easy, which is mostly
-%D due to the fact that we use \type{\stop...} as delimiter.
-%D The implementation inherits some features, for instance the
-%D support of linenumbering, which can best be studied in the
-%D documented support module.
-
-\let\currenttyping \empty
-\let\currenttypingclass\??ty % saveguard
-
-% \def\typingparameter#1%
-% {\executeifdefined
-% {\currenttypingclass\currenttyping#1}%
-% {\executeifdefined{\currenttypingclass#1}\empty}}
-
-\def\typingparameter#1%
- {\ifcsname\currenttypingclass\currenttyping#1\endcsname
- \csname\currenttypingclass\currenttyping#1\endcsname
- \else\ifcsname\currenttypingclass#1\endcsname
- \csname\currenttypingclass#1\endcsname
- \fi\fi}
-
-\def\settypingparameter#1#2%
- {\setvalue{\currenttypingclass\currenttyping#1}{#2}}
-
-\def\setxtypingparameter#1#2%
- {\setxvalue{\currenttypingclass\currenttyping#1}{#2}}
-
-% \def\initializetyping
-% {%\donefalse
-% \switchtobodyfont[\typingparameter\c!bodyfont]%
-% \donefalse
-% \scratchskip\typingparameter\c!oddmargin\relax
-% \ifzeropt\scratchskip\else\donetrue\fi
-% \scratchskip\typingparameter\c!evenmargin\relax
-% \ifzeropt\scratchskip\else\donetrue\fi
-% \ifdone
-% \def\doopenupverbatimline
-% {\getpagestatus
-% \ifrightpage
-% \hskip\typingparameter\c!oddmargin\relax
-% \else
-% \hskip\typingparameter\c!evenmargin\relax
-% \fi}%
-% \else
-% \doadaptleftskip{\typingparameter\c!margin}%
-% \fi
-% \doifdefinedelse{\??bo\typingparameter\c!blank}
-% {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}}
-% {\edef\!!stringa{\typingparameter\c!blank}}%
-% \processaction
-% [\!!stringa]
-% [ \v!standard=>\scratchskip\ctxparskip,
-% \v!small=>\scratchskip\blankokleinmaat,
-% \v!medium=>\scratchskip\blankomiddelmaat,
-% \v!big=>\scratchskip\blankogrootmaat,
-% \v!halfline=>\scratchskip.5\baselineskip,
-% \v!line=>\scratchskip\baselineskip,
-% \v!none=>\scratchskip\zeropoint,
-% \s!unknown=>\scratchskip\commalistelement]%
-% \ifgridsnapping
-% \ifdim\scratchskip=.5\baselineskip\relax
-% \edef\verbatimbaselineskip{\the\scratchskip}% new
-% \else
-% \edef\verbatimbaselineskip{\the\baselineskip}%
-% \fi
-% \else
-% \edef\verbatimbaselineskip{\the\scratchskip}%
-% \fi
-% \setupcommonverbatim}
-
-\setvalue{\??tp:\c!blank:\v!standard}{\ctxparskip}
-\setvalue{\??tp:\c!blank:\v!small }{\blankokleinmaat}
-\setvalue{\??tp:\c!blank:\v!medium }{\blankomiddelmaat}
-\setvalue{\??tp:\c!blank:\v!big }{\blankogrootmaat}
-\setvalue{\??tp:\c!blank:\v!halfline}{.5\baselineskip}
-\setvalue{\??tp:\c!blank:\v!line }{\baselineskip}
-\setvalue{\??tp:\c!blank:\v!none }{\zeropoint}
-
-\def\initializetyping
- {%\donefalse
- \switchtobodyfont[\typingparameter\c!bodyfont]%
- \donefalse
- \scratchskip\typingparameter\c!oddmargin\relax
- \ifzeropt\scratchskip\else\donetrue\fi
- \scratchskip\typingparameter\c!evenmargin\relax
- \ifzeropt\scratchskip\else\donetrue\fi
- \ifdone
- \def\doopenupverbatimline
- {\getpagestatus
- \ifrightpage
- \hskip\typingparameter\c!oddmargin\relax
- \else
- \hskip\typingparameter\c!evenmargin\relax
- \fi}%
- \else
- \doadaptleftskip{\typingparameter\c!margin}%
- \fi
- \edef\!!stringa{\executeifdefined{\??bo\typingparameter\c!blank}{\typingparameter\c!blank}}%
- \scratchskip\executeifdefined{\??tp:\c!blank:\!!stringa}\!!stringa\relax
- \ifgridsnapping
- \ifdim\scratchskip=.5\baselineskip\relax
- \edef\verbatimbaselineskip{\the\scratchskip}% new
- \else
- \edef\verbatimbaselineskip{\the\baselineskip}%
- \fi
- \else
- \edef\verbatimbaselineskip{\the\scratchskip}%
- \fi
- \setupcommonverbatim}
-
-%D The basic display verbatim commands are defined in an
-%D indirect way. As we will see, they are a specific case of a
-%D more general mechanism.
-
-% we need this hack because otherwise verbatim skips
-% the first line (everything after the initial command)
-
-\def\dostarttyping#1% tricky non standard lookahead
- {\bgroup
- \let\currenttypingclass\??tp
- \edef\currenttyping{#1}%
- \obeylines
- \futurelet\nexttoken\dodostarttyping}
-
-\def\dodostarttyping
- {\ifx\nexttoken[%
- \expandafter\dododostarttyping
- \else
- \expandafter\nododostarttyping
- \fi}
-
-\def\nododostarttyping
- {\dododostarttyping[]}
-
-\def\dododostarttyping[#1]%
- {\typingparameter\c!before
- \startpacked % includes \bgroup
- \dosetuptypelinenumbering{#1}%
- \initializetyping
- \startverbatimcolor
- \expanded{\mktypeblockverbatim{\s!start\currenttyping}{\s!stop\currenttyping}}}
-
-\def\dostoptyping#1% hm, currenttyping
- {\stopverbatimcolor
- \stoppacked % includes \egroup
- \typingparameter\c!after
- \egroup
- \dochecknextindentation{\??tp#1}%
- \dorechecknextindentation}
-
-%D Line numbering for files is combined with filtering, while
-%D display verbatim has the ability to continue.
-%D
-%D \starttyping
-%D \typefile[numbering=file,start=10,stop=12]{test.tex}
-%D
-%D \definetyping[code][numbering=line]
-%D
-%D \starttext
-%D \startcode
-%D ...
-%D ...
-%D \stopcode
-%D
-%D \startcode[continue]
-%D ...
-%D ...
-%D \stopcode
-%D
-%D \startcode[start=10]
-%D ...
-%D \stopcode
-%D \stoptyping
-
-%D \macros
-%D {setuptyping}
-%D
-%D The setup of typing accepts two arguments. The optional
-%D first one identifies the user defined ones. If only one
-%D argument is given, the values apply to both the standard
-%D command \type{\starttyping} and \type{\typefile}.
-
-\def\dosetuptyping[#1][#2]%
- {\ifsecondargument
- \getparameters[\??tp#1][#2]%
- \else
- \getparameters[\??tp][#1]%
- \fi}
-
-\def\setuptyping
- {\dodoubleempty\dosetuptyping}
-
-%D \macros
-%D {definetype}
-%D
-%D Specific inline verbatim commands can be defined with the
-%D following command.
-
-\def\definetype
- {\dodoubleempty\dodefinetype}
-
-\def\dodefinetype[#1][#2]%
- {\unexpanded\setvalue{#1}{\mktype{#1}}%
- \getparameters[\??ty#1][#2]}
-
-%D \macros
-%D {definetyping}
-%D
-%D For most users the standard \type{\start}||\type{\stop}||pair
-%D will suffice, but for documentation purposes the next
-%D definition command can be of use:
-%D
-%D \starttyping
-%D \definetyping[extratyping][margin=3em]
-%D
-%D \startextratyping
-%D these extra ones are indented by 1 em
-%D \stopextratyping
-%D \stoptyping
-%D
-%D The definitions default to the standard typing values.
-
-\def\presettyping[#1][#2]%
- {\copyparameters[\??tp#1][\??tp][\c!color,\c!style]%
- \getparameters [\??tp#1][#2]}
-
-\def\dodefinetyping[#1][#2]%
- {\setvalue{\e!start#1}{\dostarttyping{#1}}%
- \setvalue{\e!stop #1}{\dostoptyping {#1}}%
- \presettyping[#1][#2]}
-
-\def\definetyping
- {\dodoubleempty\dodefinetyping}
-
-%D We can use some core color commands. These are faster than
-%D the standard color switching ones and work ok on a line by
-%D line basis.
-%D
-%D \starttyping
-%D \def\setupverbatimcolor%
-%D {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}%
-%D \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
-%D \def\endofpretty {\stopcolormode}}
-%D \stoptyping
-%D
-%D Since we support a global color too, the folowing
-%D definition is better:
-
-% \def\setupverbatimcolor% fast and local versus slow and global
-% {\doifelsenothing{\typingparameter\c!color}
-% {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
-% \let\endofpretty \restorecolormode % \stopcolormode
-% \let\startverbatimcolor \relax
-% \let\stopverbatimcolor \relax
-% \let\verbatimcolor \relax}
-% {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
-% \let\endofpretty \stopcolor
-% \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
-% \let\stopverbatimcolor \stopcolor
-% \def\verbatimcolor {\getvalue{\typingparameter\c!color}}}% command !
-% \doifelsenothing{\typingparameter\c!palet}
-% {\let\prettypalet\empty
-% \let\endofpretty\relax
-% \def\beginofpretty[##1]{}}
-% {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
-%
-% let's forget about this optimization not that we have mkiv
-
-\def\setupverbatimcolor
- {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
- \let\endofpretty \stopcolor
- \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
- \let\stopverbatimcolor \stopcolor
- \def\verbatimcolor {\getvalue{\typingparameter\c!color}}% command !
- \doifelsenothing{\typingparameter\c!palet}
- {\let\prettypalet\empty
- \let\endofpretty\relax
- \def\beginofpretty[##1]{}}
- {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}
-
-\let\prettypalet \empty
-\let\startverbatimcolor\relax
-\let\stopverbatimcolor \relax
-\let\verbatimcolor \relax
-
-%D In the verbatim module, there are some examples given of
-%D the more obscure features of the verbatim environments.
-%D
-%D \startbuffer
-%D \startTEX
-%D \def\mathematics#1% % usage: \type {\mathematics{x^2}}
-%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2}
-%D \stopTEX
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D This gives, as can be expected:
-%D
-%D \getbuffer
-%D
-%D When we want to see some typeset \TEX\ too, we can say:
-%D
-%D \startbuffer
-%D \startTEX
-%D \def\mathematics#1% %%\ N usage: \type {\mathematics{x^2}}
-%D {\ifmmode#1\else$#1$\fi} %%\ N becomes: \mathematics{x^2}
-%D \stopTEX
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D or:
-%D
-%D \getbuffer
-%D
-%D In a similar way:
-%D
-%D \startbuffer
-%D \startSQL
-%D select * -- indeed, here we {\em do} select
-%D from tableA
-%D where 1 = 2
-%D \stopSQL
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D gives:
-%D
-%D \getbuffer
-%D
-%D The next examples sow how we can directly call for natural
-%D \TEX\ comments:
-%D
-%D \startbuffer
-%D \setuptyping
-%D [TEX]
-%D [text=yes]
-%D
-%D \startTEX
-%D \def\mathematics#1% % usage: \type {\mathematics{x^2}}
-%D {\ifmmode#1\else$#1$\fi} % becomes: \mathematics{x^2}
-%D \stopTEX
-%D
-%D \setuptyping
-%D [SQL]
-%D [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it]
-%D
-%D \startSQL
-%D select * -- indeed, here we {\em do} select
-%D from tableA
-%D where 1 = 2
-%D \stopSQL
-%D
-%D \setuptyping
-%D [SQL]
-%D [ccommand=\tf\underbar]
-%D
-%D \startSQL
-%D select * -- indeed, here we {\em do} select
-%D from tableA
-%D where 1 = 2
-%D \stopSQL
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Now watch:
-%D
-%D \getbuffer
-%D
-%D The natural \TEX\ typesetting was introduced when Tobias
-%D and Berend started using verbatim \JAVASCRIPT\ and \SQL.
-
-%D \macros
-%D {EveryPar, EveryLine, iflinepar}
-%D
-%D One of the features of these commands is the support of
-%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}.
-%D In the documentation of the verbatim support module we give
-%D some examples of line- and paragraph numbering using these
-%D macros.
-
-%D \macros
-%D {typefile}
-%D
-%D Typesetting files verbatim (for the moment) only supports
-%D colorization of \TEX\ sources as valid option. The other
-%D setup values are inherited from display verbatim.
-%D The implementation of \type{\typefile} is straightforward:
-
-% new feature (not yet 100\% ok)
-%
-% \setuptyping[file][numbering=file]
-%
-% \typefile[start=2,nlines=3]{zapf}
-% \typefile[start=continue,nlines=13]{zapf}
-% \typefile{zapf}
-%
-% \setuptyping[file][numbering=line]
-%
-% \typefile[start=4,step=3]{zapf}
-% \typefile{zapf}
-
-\def\typefile
- {\dodoubleempty\dotypefile}
-
-\def\dotypefile[#1][#2]#3%
- {\ifsecondargument
- \dodotypefile[#1][#2]{#3}%
- \else\iffirstargument
- \doifassignmentelse{#1}
- {\dodotypefile[\v!file][#1]{#3}}
- {\dodotypefile[#1][]{#3}}%
- \else
- \dodotypefile[\v!file][]{#3}%
- \fi\fi}
-
-\def\dosetuptypelinenumbering#1% fuzzy
- {\doifundefined{\currenttypingclass\currenttyping\c!start}
- {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}%
- \setuptyping[\currenttyping][#1]%
- \doifelse{\typingparameter\c!numbering}\v!file
- {% kind of special: filters lines !
- \setuplinenumbering[\c!method=\v!file]%
- \donetrue}
- {\doifelse{\typingparameter\c!numbering}\v!line
- {% \setuplinenumbering defaults start/step to 1/1, so we need
- \doifinsetelse\v!continue{#1,\typingparameter\c!start}
- {\scratchcounter0\typingparameter\c!n
- \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}%
- {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}%
- \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}%
- \setuplinenumbering
- [\c!method=\v!type,
- \c!start=\typingparameter\c!start,
- \c!stop=\typingparameter\c!stop,
- \c!step=\typingparameter\c!step]%
- \donetrue}
- {\donefalse}}%
- \ifdone
- \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
- \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi
- \def\beginofverbatimlines{\startlinenumbering}%
- \def\endofverbatimlines {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}%
- \fi}
-
-\def\reporttypingerror#1% temp hack
- {\blank
- \dontleavehmode\hbox\bgroup
- \expanded{\defconvertedargument\noexpand\ascii{#1}}%
- \tttf[\makemessage\m!verbatims1\ascii]%
- \showmessage\m!verbatims1\ascii
- \egroup
- \blank}
-
-\def\dosometyping#1#2#3#4#5%
- {\bgroup
- \let\currenttypingclass\??tp
- \edef\currenttyping{#1}%
- \typingparameter\c!before
- \startpacked % includes \bgroup
- \dosetuptypelinenumbering{#2}%
- \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal}
- {\setuptyping[#1][\c!option=\v!none]}%
- \doif{\typingparameter\c!option}\v!color
- {\expandafter\aftersplitstring#3\at.\to\prettyidentifier
- \settypingparameter\c!option{\prettyidentifier}}%
- \initializetyping
- \startverbatimcolor
- \doifundefinedelse{\currenttypingclass#3\v!global\c!start}
- {\scratchcounter\zerocount}
- {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}%
- \advance\scratchcounter\plusone
- \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}%
- \doifelsenothing{\typingparameter\c!start}
- {#4}
- {\doif{\typingparameter\c!start}\v!continue
- {\setevalue{\currenttypingclass#1\c!start}%
- {\getvalue{\currenttypingclass#3\v!global\c!start}}}%
- \doifelsenothing{\typingparameter\c!stop}
- {\doifelsenothing{\typingparameter\c!nlines}
- {#4}
- {\setxvalue{\currenttypingclass#3\v!global\c!start}%
- {\the\numexpr\typingparameter\c!start+\typingparameter\c!nlines+\minusone\relax}%
- #5{\typingparameter\c!start}{\getvalue{\currenttypingclass#3\v!global\c!start}}}}%
- {#5{\typingparameter\c!start}{\typingparameter\c!stop}}}%
- \stopverbatimcolor
- \stoppacked
- \typingparameter\c!after
- \egroup}
-
-\def\doifelsetypingfile#1% sets \readfilename
- {\doiflocfileelse{#1}
- {\firstoftwoarguments}
- {\doifinputfileelse{#1}
- {\def\readfilename{\pathplusfile\filepath{#1}}\firstoftwoarguments}
- {\secondoftwoarguments}}}
-
-\def\dodotypefile[#1][#2]#3%
- {\doifelsetypingfile{#3}
- {\dosometyping{#1}{#2}{#3}\mktypefileverbatim\mktypefilelinesverbatim}
- {\reporttypingerror{#3}}}
-
-%D \macros
-%D {filename}
-%D
-%D Typesetting filenames in monospaced fonts is possible with
-%D
-%D \starttyping
-%D \filename{here/there/filename.suffix}
-%D \stoptyping
-%D
-%D The definition is not that spectacular.
-
-\unexpanded\def\filename#1{{\tttf\hyphenatedfilename{#1}}}
-
-%D This leaves some settings:
-
-\permitshiftedendofverbatim
-\optimizeverbatimtrue
-
-%D And a bonus macro:
-
-\def\verbatim#1{\defconvertedargument\ascii{#1}\ascii}
-
-%D Plugins
-
-\loadmarkfile{core-ver}
-
-%D The setups for display verbatim and file verbatim are
-%D shared. One can adapt the extra defined typing environments,
-%D but they also default to the values below. Watch the
-%D alternative escape character.
-
-\setuptyping
- [ \c!before=\blank,
- \c!after=\blank,
- \c!bodyfont=,
- \c!color=,
- \c!space=\v!off,
- \c!page=\v!no,
- \c!tab=\s!ascii,
- \c!option=\v!none,
- \c!palet=colorpretty,
- \c!text=\v!no,
- \c!style=\tttf,
- \c!icommand=\ttsl,
- \c!vcommand=,
- \c!ccommand=\tttf,
- \c!indentnext=\v!yes,
- \c!margin=\!!zeropoint,
- \c!evenmargin=\!!zeropoint,
- \c!oddmargin=\!!zeropoint,
- \c!blank=\v!line,
- \c!escape=/, % beware \string\ , should also be accepted
- \c!numbering=\v!no,
- \c!lines=,
- \c!empty=,
- \c!start=1,
- \c!stop=,
- \c!step=1,
- \c!continue=,
- \c!nlines=]
-
-\definetyping[\v!typing]
-
-\presettyping[\v!file][]
-
-% \setuptyping % not needed
-% [\v!file]
-% [\c!start=1,
-% \c!stop=,
-% \c!step=1,
-% \c!continue=,
-% \c!nlines=]
-
-%D The setups for inline verbatim default to:
-
-\setuptype
- [ \c!space=\v!off,
- \c!color=,
- \c!style=\tt\tf, % \tttf gives problems with {\tx \type...}
- \c!page=\v!no,
- \c!tab=\v!yes,
- \c!palet=colorpretty,
- \c!option=\v!normal]
-
-\definetyping[RAW] [\c!option=RAW]
-\definetyping[MP] [\c!option=MP]
-\definetyping[PL] [\c!option=PL]
-\definetyping[PM] [\c!option=PL]
-\definetyping[JS] [\c!option=JS]
-\definetyping[JV] [\c!option=JV]
-\definetyping[SQL] [\c!option=SQL]
-\definetyping[TEX] [\c!option=TEX]
-\definetyping[PAS] [\c!option=PAS]
-\definetyping[PASCAL][\c!option=PAS]
-\definetyping[MOD] [\c!option=PAS]
-\definetyping[MODULA][\c!option=PAS]
-\definetyping[DELPHI][\c!option=PAS]
-\definetyping[EIFFEL][\c!option=EIF]
-\definetyping[XML] [\c!option=XML]
-\definetyping[LUA] [\c!option=LUA]
-
-\installprettytype [RAW] [RAW]
-
-\installprettytype [TEX] [TEX]
-
-\installprettytype [PERL] [PL]
-\installprettytype [PL] [PL]
-\installprettytype [PM] [PL]
-
-\installprettytype [METAPOST] [MP]
-\installprettytype [METAFONT] [MP]
-\installprettytype [MP] [MP]
-\installprettytype [MF] [MP]
-
-\installprettytype [JAVASCRIPT] [JS]
-\installprettytype [JAVA] [JV]
-\installprettytype [JS] [JS]
-\installprettytype [JV] [JV]
-
-\installprettytype [SQL] [SQL]
-
-\installprettytype [PASCAL] [PAS]
-\installprettytype [PAS] [PAS]
-\installprettytype [MODULA] [PAS]
-\installprettytype [MOD] [PAS]
-
-\installprettytype [EIFFEL] [EIF]
-\installprettytype [EIF] [EIF]
-\installprettytype [E] [EIF]
-
-\installprettytype [XML] [XML]
-
-\installprettytype [LUA] [LUA]
-
-\installnewpretty M {\setupprettiesintype {MP}\setupprettytype}
-\installnewpretty P {\setupprettiesintype {PL}\setupprettytype}
-\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype}
-\installnewpretty J {\setupprettiesintype {JV}\setupprettytype}
-\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype}
-\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth
-\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken
-\installnewpretty X {\setupprettiesintype{XML}\setupprettytype}
-
-%D We use the \CONTEXT\ color system for switching to and from
-%D color mode. We can always redefine these colors afterwards.
-
-\definecolor [colorprettyone] [r=.9, g=.0, b=.0] % red
-\definecolor [colorprettytwo] [r=.0, g=.8, b=.0] % green
-\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue
-\definecolor [colorprettyfour] [r=.8, g=.8, b=.6] % yellow
-
-\definecolor [grayprettyone] [s=.30]
-\definecolor [grayprettytwo] [s=.45]
-\definecolor [grayprettythree] [s=.60]
-\definecolor [grayprettyfour] [s=.75]
-
-\definepalet
- [colorpretty]
- [ prettyone=colorprettyone,
- prettytwo=colorprettytwo,
- prettythree=colorprettythree,
- prettyfour=colorprettyfour]
-
-\definepalet
- [graypretty]
- [ prettyone=grayprettyone,
- prettytwo=grayprettytwo,
- prettythree=grayprettythree,
- prettyfour=grayprettyfour]
-
-\definepalet [TEXcolorpretty] [colorpretty]
-\definepalet [TEXgraypretty] [graypretty]
-\definepalet [PLcolorpretty] [colorpretty]
-\definepalet [PLgraypretty] [graypretty]
-\definepalet [PMcolorpretty] [colorpretty]
-\definepalet [PMgraypretty] [graypretty]
-\definepalet [MPcolorpretty] [colorpretty]
-\definepalet [MPgraypretty] [graypretty]
-\definepalet [JVcolorpretty] [colorpretty]
-\definepalet [JVgraypretty] [graypretty]
-\definepalet [JScolorpretty] [colorpretty]
-\definepalet [JSgraypretty] [graypretty]
-\definepalet [SQLcolorpretty] [colorpretty]
-\definepalet [SQLgraypretty] [graypretty]
-\definepalet [PAScolorpretty] [colorpretty]
-\definepalet [PASgraypretty] [graypretty]
-\definepalet [EIFcolorpretty] [colorpretty]
-\definepalet [EIFgraypretty] [graypretty]
-\definepalet [XMLcolorpretty] [colorpretty]
-\definepalet [XMLgraypretty] [graypretty]
-\definepalet [LUAcolorpretty] [colorpretty]
-\definepalet [LUAgraypretty] [graypretty]
-
-\protect \endinput
diff --git a/tex/context/base/core-vis.tex b/tex/context/base/core-vis.tex
index b20c9b9ce..949cd176f 100644
--- a/tex/context/base/core-vis.tex
+++ b/tex/context/base/core-vis.tex
@@ -25,14 +25,12 @@
%D %\leftskip only if explicit one
%D %\rightskip only if explicit one
-\writestatus{loading}{Context Support Macros / Visualization}
+\writestatus{loading}{ConTeXt Support Macros / Visualization}
\unprotect
%D \macros
-%D {indent, noindent,
-%D leavevmode,
-%D par}
+%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
@@ -43,17 +41,11 @@
%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}, \type{\leavevmode} and \type{\par}. Other
+%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:
-\let\normalnoindent = \noindent
-\let\normalindent = \indent
-\let\normalpar = \par
-
-\let\normalleavevmode = \leavevmode
-
\def\showparagraphcue#1#2#3#4#5%
{\bgroup
\scratchdimen#1\relax
@@ -128,30 +120,15 @@
\fi
\normalhskip\parindent}
-\def\ruledleavevmode
- {\relax
- \normalleavevmode
- \ifdim\parindent>\zeropoint
- \normalhskip-\parindent
- \ruledparagraphcues
- \showparagraphcue\parindent\relax\leftrulefalse\rightrulefalse\!!height
- \normalhskip\parindent
- \else
- \ruledparagraphcues
- \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\rightrulefalse\!!height
- \fi}
-
\def\dontshowimplicits
{\let\noindent \normalnoindent
\let\indent \normalindent
- \let\leavevmode \normalleavevmode
\let\par \normalpar}
\def\showimplicits
{\testrulewidth \defaulttestrulewidth
\let\noindent \rulednoindent
\let\indent \ruledindent
- \let\leavevmode \ruledleavevmode
\let\par \ruledpar}
%D The next few||line examples show the four cues. Keep in
@@ -170,18 +147,15 @@
%D
%D \voorbeeld \indent
%D \voorbeeld \noindent
-%D \voorbeeld \leavevmode
%D
%D \parindent=60pt
%D
%D \voorbeeld \indent
%D \voorbeeld \noindent
-%D \voorbeeld \leavevmode
%D
%D \startnarrower
%D \voorbeeld \indent
%D \voorbeeld \noindent
-%D \voorbeeld \leavevmode
%D \stopnarrower
%D \egroup
%D
diff --git a/tex/context/base/data-aux.lua b/tex/context/base/data-aux.lua
new file mode 100644
index 000000000..492cce6fd
--- /dev/null
+++ b/tex/context/base/data-aux.lua
@@ -0,0 +1,57 @@
+if not modules then modules = { } end modules ['data-aux'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local find = string.find
+
+local trace_verbose = false trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+
+function resolvers.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix
+ local scriptpath = "scripts/context/lua"
+ newname = file.addsuffix(newname,"lua")
+ local oldscript = resolvers.clean_path(oldname)
+ if trace_verbose then
+ logs.report("fileio","to be replaced old script %s", oldscript)
+ end
+ local newscripts = resolvers.find_files(newname) or { }
+ if #newscripts == 0 then
+ if trace_verbose then
+ logs.report("fileio","unable to locate new script")
+ end
+ else
+ for i=1,#newscripts do
+ local newscript = resolvers.clean_path(newscripts[i])
+ if trace_verbose then
+ logs.report("fileio","checking new script %s", newscript)
+ end
+ if oldscript == newscript then
+ if trace_verbose then
+ logs.report("fileio","old and new script are the same")
+ end
+ elseif not find(newscript,scriptpath) then
+ if trace_verbose then
+ logs.report("fileio","new script should come from %s",scriptpath)
+ end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_verbose then
+ logs.report("fileio","invalid new script name")
+ end
+ else
+ local newdata = io.loaddata(newscript)
+ if newdata then
+ if trace_verbose then
+ logs.report("fileio","old script content replaced by new content")
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_verbose then
+ logs.report("fileio","unable to load new script")
+ end
+ end
+ end
+ end
+end
diff --git a/tex/context/base/data-bin.lua b/tex/context/base/data-bin.lua
new file mode 100644
index 000000000..5f342c339
--- /dev/null
+++ b/tex/context/base/data-bin.lua
@@ -0,0 +1,26 @@
+if not modules then modules = { } end modules ['data-bin'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
+
+function resolvers.findbinfile(filename, filetype)
+ return resolvers.methodhandler('finders',file.collapse_path(filename), filetype)
+end
+
+function resolvers.openbinfile(filename)
+ return resolvers.methodhandler('loaders',file.collapse_path(filename))
+end
+
+function resolvers.loadbinfile(filename, filetype)
+ local fname = resolvers.findbinfile(file.collapse_path(filename), filetype)
+ if fname and fname ~= "" then
+ return resolvers.openbinfile(fname)
+ else
+ return unpack(loaders.notfound)
+ end
+end
diff --git a/tex/context/base/data-con.lua b/tex/context/base/data-con.lua
new file mode 100644
index 000000000..02ee9eedd
--- /dev/null
+++ b/tex/context/base/data-con.lua
@@ -0,0 +1,122 @@
+if not modules then modules = { } end modules ['data-con'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, lower, gsub = string.format, string.lower, string.gsub
+
+local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end)
+local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
+local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
+local trace_verbose = false trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v trackers.enable("resolvers.verbose") end)
+
+--[[ldx--
+<p>Once we found ourselves defining similar cache constructs
+several times, containers were introduced. Containers are used
+to collect tables in memory and reuse them when possible based
+on (unique) hashes (to be provided by the calling function).</p>
+
+<p>Caching to disk is disabled by default. Version numbers are
+stored in the saved table which makes it possible to change the
+table structures without bothering about the disk cache.</p>
+
+<p>Examples of usage can be found in the font related code.</p>
+--ldx]]--
+
+containers = containers or { }
+
+containers.usecache = true
+
+local function report(container,tag,name)
+ if trace_cache or trace_containers then
+ logs.report(format("%s cache",container.subcategory),"%s: %s",tag,name or 'invalid')
+ end
+end
+
+local allocated = { }
+
+-- tracing
+
+function containers.define(category, subcategory, version, enabled)
+ return function()
+ if category and subcategory then
+ local c = allocated[category]
+ if not c then
+ c = { }
+ allocated[category] = c
+ end
+ local s = c[subcategory]
+ if not s then
+ s = {
+ category = category,
+ subcategory = subcategory,
+ storage = { },
+ enabled = enabled,
+ version = version or 1.000,
+ trace = false,
+ path = caches and caches.setpath and caches.setpath(category,subcategory),
+ }
+ c[subcategory] = s
+ end
+ return s
+ else
+ return nil
+ end
+ end
+end
+
+function containers.is_usable(container, name)
+ return container.enabled and caches and caches.iswritable(container.path, name)
+end
+
+function containers.is_valid(container, name)
+ if name and name ~= "" then
+ local storage = container.storage[name]
+ return storage and not table.is_empty(storage) and storage.cache_version == container.version
+ else
+ return false
+ end
+end
+
+function containers.read(container,name)
+ if container.enabled and caches and not container.storage[name] and containers.usecache then
+ container.storage[name] = caches.loaddata(container.path,name)
+ if containers.is_valid(container,name) then
+ report(container,"loaded",name)
+ else
+ container.storage[name] = nil
+ end
+ end
+ if container.storage[name] then
+ report(container,"reusing",name)
+ end
+ return container.storage[name]
+end
+
+function containers.write(container, name, data)
+ if data then
+ data.cache_version = container.version
+ if container.enabled and caches then
+ local unique, shared = data.unique, data.shared
+ data.unique, data.shared = nil, nil
+ caches.savedata(container.path, name, data)
+ report(container,"saved",name)
+ data.unique, data.shared = unique, shared
+ end
+ report(container,"stored",name)
+ container.storage[name] = data
+ end
+ return data
+end
+
+function containers.content(container,name)
+ return container.storage[name]
+end
+
+function containers.cleanname(name)
+ return (gsub(lower(name),"[^%w%d]+","-"))
+end
diff --git a/tex/context/base/data-crl.lua b/tex/context/base/data-crl.lua
new file mode 100644
index 000000000..5cad241a6
--- /dev/null
+++ b/tex/context/base/data-crl.lua
@@ -0,0 +1,58 @@
+if not modules then modules = { } end modules ['data-crl'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+curl = curl or { }
+
+curl.cached = { }
+curl.cachepath = caches.definepath("curl")
+
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
+
+function curl.fetch(protocol, name)
+ local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-")
+-- cachename = cachename:gsub("[\\/]", io.fileseparator)
+ cachename = cachename:gsub("[\\]", "/") -- cleanup
+ if not curl.cached[name] then
+ if not io.exists(cachename) then
+ curl.cached[name] = cachename
+ local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name -- no protocol .. "://"
+ os.spawn(command)
+ end
+ if io.exists(cachename) then
+ curl.cached[name] = cachename
+ else
+ curl.cached[name] = ""
+ end
+ end
+ return curl.cached[name]
+end
+
+function finders.curl(protocol,filename)
+ local foundname = curl.fetch(protocol, filename)
+ return finders.generic(protocol,foundname,filetype)
+end
+
+function openers.curl(protocol,filename)
+ return openers.generic(protocol,filename)
+end
+
+function loaders.curl(protocol,filename)
+ return loaders.generic(protocol,filename)
+end
+
+-- todo: metamethod
+
+function curl.install(protocol)
+ finders[protocol] = function (filename,filetype) return finders.curl(protocol,filename) end
+ openers[protocol] = function (filename) return openers.curl(protocol,filename) end
+ loaders[protocol] = function (filename) return loaders.curl(protocol,filename) end
+end
+
+curl.install('http')
+curl.install('https')
+curl.install('ftp')
diff --git a/tex/context/base/data-ctx.lua b/tex/context/base/data-ctx.lua
new file mode 100644
index 000000000..00d307b6d
--- /dev/null
+++ b/tex/context/base/data-ctx.lua
@@ -0,0 +1,29 @@
+if not modules then modules = { } end modules ['data-ctx'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+
+function resolvers.save_used_files_in_trees(filename,jobname)
+ if not filename then filename = 'luatex.jlg' end
+ local found = instance.foundintrees
+ local f = io.open(filename,'w')
+ if f then
+ f:write("<?xml version='1.0' standalone='yes'?>\n")
+ f:write("<rl:job>\n")
+ if jobname then
+ f:write(format("\t<rl:name>%s</rl:name>\n",jobname))
+ end
+ f:write("\t<rl:files>\n")
+ for _,v in ipairs(table.sortedkeys(found)) do
+ f:write(format("\t\t<rl:file n='%s'>%s</rl:file>\n",found[v],v))
+ end
+ f:write("\t</rl:files>\n")
+ f:write("</rl:usedfiles>\n")
+ f:close()
+ end
+end
diff --git a/tex/context/base/data-gen.lua b/tex/context/base/data-gen.lua
new file mode 100644
index 000000000..8537b0526
--- /dev/null
+++ b/tex/context/base/data-gen.lua
@@ -0,0 +1,9 @@
+if not modules then modules = { } end modules ['data-gen'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- move generators here
diff --git a/tex/context/base/data-inp.lua b/tex/context/base/data-inp.lua
new file mode 100644
index 000000000..700e982c2
--- /dev/null
+++ b/tex/context/base/data-inp.lua
@@ -0,0 +1,15 @@
+if not modules then modules = { } end modules ['data-inp'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+resolvers.finders = resolvers.finders or { }
+resolvers.openers = resolvers.openers or { }
+resolvers.loaders = resolvers.loaders or { }
+
+resolvers.finders.notfound = { nil }
+resolvers.openers.notfound = { nil }
+resolvers.loaders.notfound = { false, nil, 0 }
diff --git a/tex/context/base/data-kps.lua b/tex/context/base/data-kps.lua
new file mode 100644
index 000000000..09d502409
--- /dev/null
+++ b/tex/context/base/data-kps.lua
@@ -0,0 +1,101 @@
+if not modules then modules = { } end modules ['luat-kps'] = {
+ version = 1.001,
+ comment = "companion to luatools.lua",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>This file is used when we want the input handlers to behave like
+<type>kpsewhich</type>. What to do with the following:</p>
+
+<typing>
+{$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}
+$SELFAUTOLOC : /usr/tex/bin/platform
+$SELFAUTODIR : /usr/tex/bin
+$SELFAUTOPARENT : /usr/tex
+</typing>
+
+<p>How about just forgetting about them?</p>
+--ldx]]--
+
+local suffixes = resolvers.suffixes
+local formats = resolvers.formats
+
+suffixes['gf'] = { '<resolution>gf' }
+suffixes['pk'] = { '<resolution>pk' }
+suffixes['base'] = { 'base' }
+suffixes['bib'] = { 'bib' }
+suffixes['bst'] = { 'bst' }
+suffixes['cnf'] = { 'cnf' }
+suffixes['mem'] = { 'mem' }
+suffixes['mf'] = { 'mf' }
+suffixes['mfpool'] = { 'pool' }
+suffixes['mft'] = { 'mft' }
+suffixes['mppool'] = { 'pool' }
+suffixes['graphic/figure'] = { 'eps', 'epsi' }
+suffixes['texpool'] = { 'pool' }
+suffixes['PostScript header'] = { 'pro' }
+suffixes['ist'] = { 'ist' }
+suffixes['web'] = { 'web', 'ch' }
+suffixes['cweb'] = { 'w', 'web', 'ch' }
+suffixes['cmap files'] = { 'cmap' }
+suffixes['lig files'] = { 'lig' }
+suffixes['bitmap font'] = { }
+suffixes['MetaPost support'] = { }
+suffixes['TeX system documentation'] = { }
+suffixes['TeX system sources'] = { }
+suffixes['dvips config'] = { }
+suffixes['type42 fonts'] = { }
+suffixes['web2c files'] = { }
+suffixes['other text files'] = { }
+suffixes['other binary files'] = { }
+suffixes['opentype fonts'] = { 'otf' }
+
+suffixes['fmt'] = { 'fmt' }
+suffixes['texmfscripts'] = { 'rb','lua','py','pl' }
+
+suffixes['pdftex config'] = { }
+suffixes['Troff fonts'] = { }
+
+suffixes['ls-R'] = { }
+
+--[[ldx--
+<p>If you wondered abou tsome of the previous mappings, how about
+the next bunch:</p>
+--ldx]]--
+
+formats['bib'] = ''
+formats['bst'] = ''
+formats['mft'] = ''
+formats['ist'] = ''
+formats['web'] = ''
+formats['cweb'] = ''
+formats['MetaPost support'] = ''
+formats['TeX system documentation'] = ''
+formats['TeX system sources'] = ''
+formats['Troff fonts'] = ''
+formats['dvips config'] = ''
+formats['graphic/figure'] = ''
+formats['ls-R'] = ''
+formats['other text files'] = ''
+formats['other binary files'] = ''
+
+formats['gf'] = ''
+formats['pk'] = ''
+formats['base'] = 'MFBASES'
+formats['cnf'] = ''
+formats['mem'] = 'MPMEMS'
+formats['mf'] = 'MFINPUTS'
+formats['mfpool'] = 'MFPOOL'
+formats['mppool'] = 'MPPOOL'
+formats['texpool'] = 'TEXPOOL'
+formats['PostScript header'] = 'TEXPSHEADERS'
+formats['cmap files'] = 'CMAPFONTS'
+formats['type42 fonts'] = 'T42FONTS'
+formats['web2c files'] = 'WEB2C'
+formats['pdftex config'] = 'PDFTEXCONFIG'
+formats['texmfscripts'] = 'TEXMFSCRIPTS'
+formats['bitmap font'] = ''
+formats['lig files'] = 'LIGFONTS'
diff --git a/tex/context/base/data-lst.lua b/tex/context/base/data-lst.lua
new file mode 100644
index 000000000..10d3ea479
--- /dev/null
+++ b/tex/context/base/data-lst.lua
@@ -0,0 +1,58 @@
+if not modules then modules = { } end modules ['data-lst'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- used in mtxrun
+
+local find, concat, upper, format = string.find, table.concat, string.upper, string.format
+
+resolvers.listers = resolvers.listers or { }
+
+local function tabstr(str)
+ if type(str) == 'table' then
+ return concat(str," | ")
+ else
+ return str
+ end
+end
+
+local function list(list,report)
+ local instance = resolvers.instance
+ local pat = upper(pattern or "","")
+ local report = report or texio.write_nl
+ for _,key in pairs(table.sortedkeys(list)) do
+ if instance.pattern == "" or find(upper(key),pat) then
+ if instance.kpseonly then
+ if instance.kpsevars[key] then
+ report(format("%s=%s",key,tabstr(list[key])))
+ end
+ else
+ report(format('%s %s=%s',(instance.kpsevars[key] and 'K') or 'E',key,tabstr(list[key])))
+ end
+ end
+ end
+end
+
+function resolvers.listers.variables () list(resolvers.instance.variables ) end
+function resolvers.listers.expansions() list(resolvers.instance.expansions) end
+
+function resolvers.listers.configurations(report)
+ local report = report or texio.write_nl
+ local instance = resolvers.instance
+ for _,key in ipairs(table.sortedkeys(instance.kpsevars)) do
+ if not instance.pattern or (instance.pattern=="") or find(key,instance.pattern) then
+ report(format("%s\n",key))
+ for i,c in ipairs(instance.order) do
+ local str = c[key]
+ if str then
+ report(format("\t%s\t%s",i,str))
+ end
+ end
+ report("")
+ end
+ end
+end
diff --git a/tex/context/base/data-lua.lua b/tex/context/base/data-lua.lua
new file mode 100644
index 000000000..86231b3a3
--- /dev/null
+++ b/tex/context/base/data-lua.lua
@@ -0,0 +1,55 @@
+if not modules then modules = { } end modules ['data-lua'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- some loading stuff ... we might move this one to slot 1 depending
+-- on the developments (the loaders must not trigger kpse); we could
+-- of course use a more extensive lib path spec
+
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
+
+local gsub = string.gsub
+
+local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' }
+local libpaths = file.split_path(package.path)
+
+package.loaders[#package.loaders+1] = function(name)
+ for i=1,#libformats do
+ local format = libformats[i]
+ local resolved = resolvers.find_file(name,format) or ""
+ if resolved ~= "" then
+ if trace_locating then
+ logs.report("fileio","! lib '%s' located via environment: '%s'",name,resolved)
+ end
+ return function() return dofile(resolved) end
+ end
+ end
+ local simple = file.removesuffix(name)
+ for i=1,#libpaths do
+ local resolved = gsub(libpaths[i],"?",simple)
+ if resolvers.isreadable.file(resolved) then
+ if trace_locating then
+ logs.report("fileio","! lib '%s' located via 'package.path': '%s'",name,resolved)
+ end
+ return function() return dofile(resolved) end
+ end
+ end
+ -- just in case the distribution is messed up
+ local resolved = resolvers.find_file(file.basename(name),'luatexlibs') or ""
+ if resolved ~= "" then
+ if trace_locating then
+ logs.report("fileio","! lib '%s' located by basename via environment: '%s'",name,resolved)
+ end
+ return function() return dofile(resolved) end
+ end
+ if trace_locating then
+ logs.report("fileio",'? unable to locate lib: %s',name)
+ end
+ return "unable to locate " .. name
+end
+
+resolvers.loadlualib = require
diff --git a/tex/context/base/data-out.lua b/tex/context/base/data-out.lua
new file mode 100644
index 000000000..b774e25fc
--- /dev/null
+++ b/tex/context/base/data-out.lua
@@ -0,0 +1,10 @@
+if not modules then modules = { } end modules ['data-out'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+outputs = outputs or { }
+
diff --git a/tex/context/base/data-pre.lua b/tex/context/base/data-pre.lua
new file mode 100644
index 000000000..deee9ebf4
--- /dev/null
+++ b/tex/context/base/data-pre.lua
@@ -0,0 +1,90 @@
+if not modules then modules = { } end modules ['data-res'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--~ print(resolvers.resolve("abc env:tmp file:cont-en.tex path:cont-en.tex full:cont-en.tex rel:zapf/one/p-chars.tex"))
+
+local upper, lower, gsub = string.upper, string.lower, string.gsub
+
+local prefixes = { }
+
+prefixes.environment = function(str)
+ return resolvers.clean_path(os.getenv(str) or os.getenv(upper(str)) or os.getenv(lower(str)) or "")
+end
+
+prefixes.relative = function(str,n)
+ if io.exists(str) then
+ -- nothing
+ elseif io.exists("./" .. str) then
+ str = "./" .. str
+ else
+ local p = "../"
+ for i=1,n or 2 do
+ if io.exists(p .. str) then
+ str = p .. str
+ break
+ else
+ p = p .. "../"
+ end
+ end
+ end
+ return resolvers.clean_path(str)
+end
+
+prefixes.locate = function(str)
+ local fullname = resolvers.find_given_file(str) or ""
+ return resolvers.clean_path((fullname ~= "" and fullname) or str)
+end
+
+prefixes.filename = function(str)
+ local fullname = resolvers.find_given_file(str) or ""
+ return resolvers.clean_path(file.basename((fullname ~= "" and fullname) or str))
+end
+
+prefixes.pathname = function(str)
+ local fullname = resolvers.find_given_file(str) or ""
+ return resolvers.clean_path(file.dirname((fullname ~= "" and fullname) or str))
+end
+
+prefixes.env = prefixes.environment
+prefixes.rel = prefixes.relative
+prefixes.loc = prefixes.locate
+prefixes.kpse = prefixes.locate
+prefixes.full = prefixes.locate
+prefixes.file = prefixes.filename
+prefixes.path = prefixes.pathname
+
+local function _resolve_(method,target)
+ if prefixes[method] then
+ return prefixes[method](target)
+ else
+ return method .. ":" .. target
+ end
+end
+
+local function resolve(str)
+ if type(str) == "table" then
+ for k, v in pairs(str) do -- ipairs
+ str[k] = resolve(v) or v
+ end
+ elseif str and str ~= "" then
+ str = gsub(str,"([a-z]+):([^ \"\']*)",_resolve_)
+ end
+ return str
+end
+
+resolvers.resolve = resolve
+
+if os.uname then
+
+ for k, v in pairs(os.uname()) do
+ if not prefixes[k] then
+ prefixes[k] = function() return v end
+ end
+ end
+
+end
diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua
new file mode 100644
index 000000000..0981881a2
--- /dev/null
+++ b/tex/context/base/data-res.lua
@@ -0,0 +1,2029 @@
+if not modules then modules = { } end modules ['data-inp'] = {
+ version = 1.001,
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ comment = "companion to luat-lib.tex",
+}
+
+-- After a few years using the code the large luat-inp.lua file
+-- has been split up a bit. In the process some functionality was
+-- dropped:
+--
+-- * support for reading lsr files
+-- * selective scanning (subtrees)
+-- * some public auxiliary functions were made private
+--
+-- TODO: os.getenv -> os.env[]
+-- TODO: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
+-- TODO: check escaping in find etc, too much, too slow
+
+-- This lib is multi-purpose and can be loaded again later on so that
+-- additional functionality becomes available. We will split thislogs.report("fileio",
+-- module in components once we're done with prototyping. This is the
+-- first code I wrote for LuaTeX, so it needs some cleanup. Before changing
+-- something in this module one can best check with Taco or Hans first; there
+-- is some nasty trickery going on that relates to traditional kpse support.
+
+-- To be considered: hash key lowercase, first entry in table filename
+-- (any case), rest paths (so no need for optimization). Or maybe a
+-- separate table that matches lowercase names to mixed case when
+-- present. In that case the lower() cases can go away. I will do that
+-- only when we run into problems with names ... well ... Iwona-Regular.
+
+-- Beware, loading and saving is overloaded in luat-tmp!
+
+local format, gsub, find, lower, upper, match, gmatch = string.format, string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
+local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
+local next, type = next, type
+
+local trace_locating, trace_detail, trace_verbose = false, false, false
+
+trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+trackers.register("resolvers.locating", function(v) trace_locating = v trackers.enable("resolvers.verbose") end)
+trackers.register("resolvers.detail", function(v) trace_detail = v trackers.enable("resolvers.verbose,resolvers.detail") end)
+
+if not resolvers then
+ resolvers = {
+ suffixes = { },
+ formats = { },
+ dangerous = { },
+ suffixmap = { },
+ alternatives = { },
+ locators = { }, -- locate databases
+ hashers = { }, -- load databases
+ generators = { }, -- generate databases
+ }
+end
+
+local resolvers = resolvers
+
+resolvers.locators .notfound = { nil }
+resolvers.hashers .notfound = { nil }
+resolvers.generators.notfound = { nil }
+
+resolvers.cacheversion = '1.0.1'
+resolvers.cnfname = 'texmf.cnf'
+resolvers.luaname = 'texmfcnf.lua'
+resolvers.homedir = os.env[os.platform == "windows" and 'USERPROFILE'] or os.env['HOME'] or '~'
+resolvers.cnfdefault = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c}'
+
+local dummy_path_expr = "^!*unset/*$"
+
+local formats = resolvers.formats
+local suffixes = resolvers.suffixes
+local dangerous = resolvers.dangerous
+local suffixmap = resolvers.suffixmap
+local alternatives = resolvers.alternatives
+
+formats['afm'] = 'AFMFONTS' suffixes['afm'] = { 'afm' }
+formats['enc'] = 'ENCFONTS' suffixes['enc'] = { 'enc' }
+formats['fmt'] = 'TEXFORMATS' suffixes['fmt'] = { 'fmt' }
+formats['map'] = 'TEXFONTMAPS' suffixes['map'] = { 'map' }
+formats['mp'] = 'MPINPUTS' suffixes['mp'] = { 'mp' }
+formats['ocp'] = 'OCPINPUTS' suffixes['ocp'] = { 'ocp' }
+formats['ofm'] = 'OFMFONTS' suffixes['ofm'] = { 'ofm', 'tfm' }
+formats['otf'] = 'OPENTYPEFONTS' suffixes['otf'] = { 'otf' } -- 'ttf'
+formats['opl'] = 'OPLFONTS' suffixes['opl'] = { 'opl' }
+formats['otp'] = 'OTPINPUTS' suffixes['otp'] = { 'otp' }
+formats['ovf'] = 'OVFFONTS' suffixes['ovf'] = { 'ovf', 'vf' }
+formats['ovp'] = 'OVPFONTS' suffixes['ovp'] = { 'ovp' }
+formats['tex'] = 'TEXINPUTS' suffixes['tex'] = { 'tex' }
+formats['tfm'] = 'TFMFONTS' suffixes['tfm'] = { 'tfm' }
+formats['ttf'] = 'TTFONTS' suffixes['ttf'] = { 'ttf', 'ttc' }
+formats['pfb'] = 'T1FONTS' suffixes['pfb'] = { 'pfb', 'pfa' }
+formats['vf'] = 'VFFONTS' suffixes['vf'] = { 'vf' }
+
+formats['fea'] = 'FONTFEATURES' suffixes['fea'] = { 'fea' }
+formats['cid'] = 'FONTCIDMAPS' suffixes['cid'] = { 'cid', 'cidmap' }
+
+formats ['texmfscripts'] = 'TEXMFSCRIPTS' -- new
+suffixes['texmfscripts'] = { 'rb', 'pl', 'py' } -- 'lua'
+
+formats ['lua'] = 'LUAINPUTS' -- new
+suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
+
+-- backward compatible ones
+
+alternatives['map files'] = 'map'
+alternatives['enc files'] = 'enc'
+alternatives['cid files'] = 'cid'
+alternatives['fea files'] = 'fea'
+alternatives['opentype fonts'] = 'otf'
+alternatives['truetype fonts'] = 'ttf'
+alternatives['truetype collections'] = 'ttc'
+alternatives['type1 fonts'] = 'pfb'
+
+-- obscure ones
+
+formats ['misc fonts'] = ''
+suffixes['misc fonts'] = { }
+
+formats ['sfd'] = 'SFDFONTS'
+suffixes ['sfd'] = { 'sfd' }
+alternatives['subfont definition files'] = 'sfd'
+
+-- In practice we will work within one tds tree, but i want to keep
+-- the option open to build tools that look at multiple trees, which is
+-- why we keep the tree specific data in a table. We used to pass the
+-- instance but for practical pusposes we now avoid this and use a
+-- instance variable.
+
+-- here we catch a few new thingies (todo: add these paths to context.tmf)
+--
+-- FONTFEATURES = .;$TEXMF/fonts/fea//
+-- FONTCIDMAPS = .;$TEXMF/fonts/cid//
+
+-- we always have one instance active
+
+resolvers.instance = resolvers.instance or nil -- the current one (slow access)
+local instance = resolvers.instance or nil -- the current one (fast access)
+
+function resolvers.newinstance()
+
+ -- store once, freeze and faster (once reset we can best use
+ -- instance.environment) maybe better have a register suffix
+ -- function
+
+ for k, v in next, suffixes do
+ for i=1,#v do
+ local vi = v[i]
+ if vi then
+ suffixmap[vi] = k
+ end
+ end
+ end
+
+ -- because vf searching is somewhat dangerous, we want to prevent
+ -- too liberal searching esp because we do a lookup on the current
+ -- path anyway; only tex (or any) is safe
+
+ for k, v in next, formats do
+ dangerous[k] = true
+ end
+ dangerous.tex = nil
+
+ -- the instance
+
+ local newinstance = {
+ rootpath = '',
+ treepath = '',
+ progname = 'context',
+ engine = 'luatex',
+ format = '',
+ environment = { },
+ variables = { },
+ expansions = { },
+ files = { },
+ remap = { },
+ configuration = { },
+ setup = { },
+ order = { },
+ found = { },
+ foundintrees = { },
+ kpsevars = { },
+ hashes = { },
+ cnffiles = { },
+ luafiles = { },
+ lists = { },
+ remember = true,
+ diskcache = true,
+ renewcache = false,
+ scandisk = true,
+ cachepath = nil,
+ loaderror = false,
+ sortdata = false,
+ savelists = true,
+ cleanuppaths = true,
+ allresults = false,
+ pattern = nil, -- lists
+ data = { }, -- only for loading
+ force_suffixes = true,
+ fakepaths = { },
+ }
+
+ local ne = newinstance.environment
+
+ for k,v in next, os.env do
+ ne[k] = resolvers.bare_variable(v)
+ end
+
+ return newinstance
+
+end
+
+function resolvers.setinstance(someinstance)
+ instance = someinstance
+ resolvers.instance = someinstance
+ return someinstance
+end
+
+function resolvers.reset()
+ return resolvers.setinstance(resolvers.newinstance())
+end
+
+local function reset_hashes()
+ instance.lists = { }
+ instance.found = { }
+end
+
+local function check_configuration() -- not yet ok, no time for debugging now
+ local ie = instance.environment
+ local function fix(varname,default)
+ local proname = varname .. "." .. instance.progname or "crap"
+ local p, v = ie[proname], ie[varname]
+ if not ((p and p ~= "") or (v and v ~= "")) then
+ instance.variables[varname] = default -- or environment?
+ end
+ end
+ local name = os.name
+ if name == "windows" then
+ fix("OSFONTDIR", "c:/windows/fonts//")
+ elseif name == "macosx" then
+ fix("OSFONTDIR", "$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ else
+ -- bad luck
+ end
+ fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
+ fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
+end
+
+function resolvers.bare_variable(str) -- assumes str is a string
+ return (gsub(str,"\s*([\"\']?)(.+)%1\s*", "%2"))
+end
+
+function resolvers.settrace(n) -- no longer number but: 'locating' or 'detail'
+ if n then
+ trackers.disable("resolvers.*")
+ trackers.enable("resolvers."..n)
+ end
+end
+
+resolvers.settrace(os.getenv("MTX.resolvers.TRACE") or os.getenv("MTX_INPUT_TRACE"))
+
+function resolvers.osenv(key)
+ local ie = instance.environment
+ local value = ie[key]
+ if value == nil then
+ -- local e = os.getenv(key)
+ local e = os.env[key]
+ if e == nil then
+ -- value = "" -- false
+ else
+ value = resolvers.bare_variable(e)
+ end
+ ie[key] = value
+ end
+ return value or ""
+end
+
+function resolvers.env(key)
+ return instance.environment[key] or resolvers.osenv(key)
+end
+
+--
+
+local function expand_vars(lst) -- simple vars
+ local variables, env = instance.variables, resolvers.env
+ local function resolve(a)
+ return variables[a] or env(a)
+ end
+ for k=1,#lst do
+ lst[k] = gsub(lst[k],"%$([%a%d%_%-]+)",resolve)
+ end
+end
+
+local function expanded_var(var) -- simple vars
+ local function resolve(a)
+ return instance.variables[a] or resolvers.env(a)
+ end
+ return (gsub(var,"%$([%a%d%_%-]+)",resolve))
+end
+
+local function entry(entries,name)
+ if name and (name ~= "") then
+ name = gsub(name,'%$','')
+ local result = entries[name..'.'..instance.progname] or entries[name]
+ if result then
+ return result
+ else
+ result = resolvers.env(name)
+ if result then
+ instance.variables[name] = result
+ resolvers.expand_variables()
+ return instance.expansions[name] or ""
+ end
+ end
+ end
+ return ""
+end
+
+local function is_entry(entries,name)
+ if name and name ~= "" then
+ name = gsub(name,'%$','')
+ return (entries[name..'.'..instance.progname] or entries[name]) ~= nil
+ else
+ return false
+ end
+end
+
+-- {a,b,c,d}
+-- a,b,c/{p,q,r},d
+-- a,b,c/{p,q,r}/d/{x,y,z}//
+-- a,b,c/{p,q/{x,y,z},r},d/{p,q,r}
+-- a,b,c/{p,q/{x,y,z},r},d/{p,q,r}
+-- a{b,c}{d,e}f
+-- {a,b,c,d}
+-- {a,b,c/{p,q,r},d}
+-- {a,b,c/{p,q,r}/d/{x,y,z}//}
+-- {a,b,c/{p,q/{x,y,z}},d/{p,q,r}}
+-- {a,b,c/{p,q/{x,y,z},w}v,d/{p,q,r}}
+-- {$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c}
+
+-- this one is better and faster, but it took me a while to realize
+-- that this kind of replacement is cleaner than messy parsing and
+-- fuzzy concatenating we can probably gain a bit with selectively
+-- applying lpeg, but experiments with lpeg parsing this proved not to
+-- work that well; the parsing is ok, but dealing with the resulting
+-- table is a pain because we need to work inside-out recursively
+
+local function splitpathexpr(str, t, validate)
+ -- no need for further optimization as it is only called a
+ -- few times, we can use lpeg for the sub; we could move
+ -- the local functions outside the body
+ t = t or { }
+ str = gsub(str,",}",",@}")
+ str = gsub(str,"{,","{@,")
+ -- str = "@" .. str .. "@"
+ local ok, done
+ local function do_first(a,b)
+ local t = { }
+ for s in gmatch(b,"[^,]+") do t[#t+1] = a .. s end
+ return "{" .. concat(t,",") .. "}"
+ end
+ local function do_second(a,b)
+ local t = { }
+ for s in gmatch(a,"[^,]+") do t[#t+1] = s .. b end
+ return "{" .. concat(t,",") .. "}"
+ end
+ local function do_both(a,b)
+ local t = { }
+ for sa in gmatch(a,"[^,]+") do
+ for sb in gmatch(b,"[^,]+") do
+ t[#t+1] = sa .. sb
+ end
+ end
+ return "{" .. concat(t,",") .. "}"
+ end
+ local function do_three(a,b,c)
+ return a .. b.. c
+ end
+ while true do
+ done = false
+ while true do
+ str, ok = gsub(str,"([^{},]+){([^{}]+)}",do_first)
+ if ok > 0 then done = true else break end
+ end
+ while true do
+ str, ok = gsub(str,"{([^{}]+)}([^{},]+)",do_second)
+ if ok > 0 then done = true else break end
+ end
+ while true do
+ str, ok = gsub(str,"{([^{}]+)}{([^{}]+)}",do_both)
+ if ok > 0 then done = true else break end
+ end
+ str, ok = gsub(str,"({[^{}]*){([^{}]+)}([^{}]*})",do_three)
+ if ok > 0 then done = true end
+ if not done then break end
+ end
+ str = gsub(str,"[{}]", "")
+ str = gsub(str,"@","")
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s = validate(s)
+ if s then t[#t+1] = s end
+ end
+ else
+ for s in gmatch(str,"[^,]+") do
+ t[#t+1] = s
+ end
+ end
+ return t
+end
+
+local function expanded_path_from_list(pathlist) -- maybe not a list, just a path
+ -- a previous version fed back into pathlist
+ local newlist, ok = { }, false
+ for k=1,#pathlist do
+ if find(pathlist[k],"[{}]") then
+ ok = true
+ break
+ end
+ end
+ if ok then
+ local function validate(s)
+ s = file.collapse_path(s)
+ return s ~= "" and not find(s,dummy_path_expr) and s
+ end
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ else
+ for k=1,#pathlist do
+ for p in gmatch(pathlist[k],"([^,]+)") do
+ p = file.collapse_path(p)
+ if p ~= "" then newlist[#newlist+1] = p end
+ end
+ end
+ end
+ return newlist
+end
+
+-- we follow a rather traditional approach:
+--
+-- (1) texmf.cnf given in TEXMFCNF
+-- (2) texmf.cnf searched in default variable
+--
+-- also we now follow the stupid route: if not set then just assume *one*
+-- cnf file under texmf (i.e. distribution)
+
+resolvers.ownpath = resolvers.ownpath or nil
+resolvers.ownbin = resolvers.ownbin or arg[-2] or arg[-1] or arg[0] or "luatex"
+resolvers.autoselfdir = true -- false may be handy for debugging
+
+function resolvers.getownpath()
+ if not resolvers.ownpath then
+ if resolvers.autoselfdir and os.selfdir then
+ resolvers.ownpath = os.selfdir
+ else
+ local binary = resolvers.ownbin
+ if os.platform == "windows" then
+ binary = file.replacesuffix(binary,"exe")
+ end
+ for p in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local b = file.join(p,binary)
+ if lfs.isfile(b) then
+ -- we assume that after changing to the path the currentdir function
+ -- resolves to the real location and use this side effect here; this
+ -- trick is needed because on the mac installations use symlinks in the
+ -- path instead of real locations
+ local olddir = lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp = lfs.currentdir()
+ if trace_verbose and p ~= pp then
+ logs.report("fileio","following symlink %s to %s",p,pp)
+ end
+ resolvers.ownpath = pp
+ lfs.chdir(olddir)
+ else
+ if trace_verbose then
+ logs.report("fileio","unable to check path %s",p)
+ end
+ resolvers.ownpath = p
+ end
+ break
+ end
+ end
+ end
+ if not resolvers.ownpath then resolvers.ownpath = '.' end
+ end
+ return resolvers.ownpath
+end
+
+local own_places = { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF" }
+
+local function identify_own()
+ local ownpath = resolvers.getownpath() or lfs.currentdir()
+ local ie = instance.environment
+ if ownpath then
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ else
+ logs.report("fileio","error: unable to locate ownpath")
+ os.exit()
+ end
+ if resolvers.env('TEXMFCNF') == "" then os.env['TEXMFCNF'] = resolvers.cnfdefault end
+ if resolvers.env('TEXOS') == "" then os.env['TEXOS'] = resolvers.env('SELFAUTODIR') end
+ if resolvers.env('TEXROOT') == "" then os.env['TEXROOT'] = resolvers.env('SELFAUTOPARENT') end
+ if trace_verbose then
+ for i=1,#own_places do
+ local v = own_places[i]
+ logs.report("fileio","variable %s set to %s",v,resolvers.env(v) or "unknown")
+ end
+ end
+ identify_own = function() end
+end
+
+function resolvers.identify_cnf()
+ if #instance.cnffiles == 0 then
+ -- fallback
+ identify_own()
+ -- the real search
+ resolvers.expand_variables()
+ local t = resolvers.split_path(resolvers.env('TEXMFCNF'))
+ t = expanded_path_from_list(t)
+ expand_vars(t) -- redundant
+ local function locate(filename,list)
+ for i=1,#t do
+ local ti = t[i]
+ local texmfcnf = file.collapse_path(file.join(ti,filename))
+ if lfs.isfile(texmfcnf) then
+ list[#list+1] = texmfcnf
+ end
+ end
+ end
+ locate(resolvers.luaname,instance.luafiles)
+ locate(resolvers.cnfname,instance.cnffiles)
+ end
+end
+
+local function load_cnf_file(fname)
+ fname = resolvers.clean_path(fname)
+ local lname = file.replacesuffix(fname,'lua')
+ local f = io.open(lname)
+ if f then -- this will go
+ f:close()
+ local dname = file.dirname(fname)
+ if not instance.configuration[dname] then
+ resolvers.load_data(dname,'configuration',lname and file.basename(lname))
+ instance.order[#instance.order+1] = instance.configuration[dname]
+ end
+ else
+ f = io.open(fname)
+ if f then
+ if trace_verbose then
+ logs.report("fileio","loading %s", fname)
+ end
+ local line, data, n, k, v
+ local dname = file.dirname(fname)
+ if not instance.configuration[dname] then
+ instance.configuration[dname] = { }
+ instance.order[#instance.order+1] = instance.configuration[dname]
+ end
+ local data = instance.configuration[dname]
+ while true do
+ local line, n = f:read(), 0
+ if line then
+ while true do -- join lines
+ line, n = gsub(line,"\\%s*$", "")
+ if n > 0 then
+ line = line .. f:read()
+ else
+ break
+ end
+ end
+ if not find(line,"^[%%#]") then
+ local l = gsub(line,"%s*%%.*$","")
+ local k, v = match(l,"%s*(.-)%s*=%s*(.-)%s*$")
+ if k and v and not data[k] then
+ v = gsub(v,"[%%#].*",'')
+ data[k] = gsub(v,"~","$HOME")
+ instance.kpsevars[k] = true
+ end
+ end
+ else
+ break
+ end
+ end
+ f:close()
+ elseif trace_verbose then
+ logs.report("fileio","skipping %s", fname)
+ end
+ end
+end
+
+local function collapse_cnf_data() -- potential optimization: pass start index (setup and configuration are shared)
+ for _,c in ipairs(instance.order) do
+ for k,v in next, c do
+ if not instance.variables[k] then
+ if instance.environment[k] then
+ instance.variables[k] = instance.environment[k]
+ else
+ instance.kpsevars[k] = true
+ instance.variables[k] = resolvers.bare_variable(v)
+ end
+ end
+ end
+ end
+end
+
+function resolvers.load_cnf()
+ local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
+ end
+ end
+ -- instance.cnffiles contain complete names now !
+ if #instance.cnffiles == 0 then
+ if trace_verbose then
+ logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
+ end
+ else
+ instance.rootpath = instance.cnffiles[1]
+ for k,fname in ipairs(instance.cnffiles) do
+ instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ end
+ for i=1,3 do
+ instance.rootpath = file.dirname(instance.rootpath)
+ end
+ instance.rootpath = file.collapse_path(instance.rootpath)
+ if instance.diskcache and not instance.renewcache then
+ resolvers.loadoldconfig(instance.cnffiles)
+ if instance.loaderror then
+ loadoldconfigdata()
+ resolvers.saveoldconfig()
+ end
+ else
+ loadoldconfigdata()
+ if instance.renewcache then
+ resolvers.saveoldconfig()
+ end
+ end
+ collapse_cnf_data()
+ end
+ check_configuration()
+end
+
+function resolvers.load_lua()
+ if #instance.luafiles == 0 then
+ -- yet harmless
+ else
+ instance.rootpath = instance.luafiles[1]
+ for k,fname in ipairs(instance.luafiles) do
+ instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ end
+ for i=1,3 do
+ instance.rootpath = file.dirname(instance.rootpath)
+ end
+ instance.rootpath = file.collapse_path(instance.rootpath)
+ resolvers.loadnewconfig()
+ collapse_cnf_data()
+ end
+ check_configuration()
+end
+
+-- database loading
+
+function resolvers.load_hash()
+ resolvers.locatelists()
+ if instance.diskcache and not instance.renewcache then
+ resolvers.loadfiles()
+ if instance.loaderror then
+ resolvers.loadlists()
+ resolvers.savefiles()
+ end
+ else
+ resolvers.loadlists()
+ if instance.renewcache then
+ resolvers.savefiles()
+ end
+ end
+end
+
+function resolvers.append_hash(type,tag,name)
+ if trace_locating then
+ logs.report("fileio","= hash append: %s",tag)
+ end
+ insert(instance.hashes, { ['type']=type, ['tag']=tag, ['name']=name } )
+end
+
+function resolvers.prepend_hash(type,tag,name)
+ if trace_locating then
+ logs.report("fileio","= hash prepend: %s",tag)
+ end
+ insert(instance.hashes, 1, { ['type']=type, ['tag']=tag, ['name']=name } )
+end
+
+function resolvers.extend_texmf_var(specification) -- crap, we could better prepend the hash
+-- local t = resolvers.expanded_path_list('TEXMF') -- full expansion
+ local t = resolvers.split_path(resolvers.env('TEXMF'))
+ insert(t,1,specification)
+ local newspec = concat(t,";")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"] = newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"] = newspec
+ else
+ -- weird
+ end
+ resolvers.expand_variables()
+ reset_hashes()
+end
+
+-- locators
+
+function resolvers.locatelists()
+ for _, path in ipairs(resolvers.clean_path_list('TEXMF')) do
+ if trace_verbose then
+ logs.report("fileio","locating list of %s",path)
+ end
+ resolvers.locatedatabase(file.collapse_path(path))
+ end
+end
+
+function resolvers.locatedatabase(specification)
+ return resolvers.methodhandler('locators', specification)
+end
+
+function resolvers.locators.tex(specification)
+ if specification and specification ~= '' and lfs.isdir(specification) then
+ if trace_locating then
+ logs.report("fileio",'! tex locator found: %s',specification)
+ end
+ resolvers.append_hash('file',specification,filename)
+ elseif trace_locating then
+ logs.report("fileio",'? tex locator not found: %s',specification)
+ end
+end
+
+-- hashers
+
+function resolvers.hashdatabase(tag,name)
+ return resolvers.methodhandler('hashers',tag,name)
+end
+
+function resolvers.loadfiles()
+ instance.loaderror = false
+ instance.files = { }
+ if not instance.renewcache then
+ for _, hash in ipairs(instance.hashes) do
+ resolvers.hashdatabase(hash.tag,hash.name)
+ if instance.loaderror then break end
+ end
+ end
+end
+
+function resolvers.hashers.tex(tag,name)
+ resolvers.load_data(tag,'files')
+end
+
+-- generators:
+
+function resolvers.loadlists()
+ for _, hash in ipairs(instance.hashes) do
+ resolvers.generatedatabase(hash.tag)
+ end
+end
+
+function resolvers.generatedatabase(specification)
+ return resolvers.methodhandler('generators', specification)
+end
+
+-- starting with . or .. etc or funny char
+
+local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
+
+function resolvers.generators.tex(specification)
+ local tag = specification
+ if trace_verbose then
+ logs.report("fileio","scanning path %s",specification)
+ end
+ instance.files[tag] = { }
+ local files = instance.files[tag]
+ local n, m, r = 0, 0, 0
+ local spec = specification .. '/'
+ local attributes = lfs.attributes
+ local directory = lfs.dir
+ local function action(path)
+ local full
+ if path then
+ full = spec .. path .. '/'
+ else
+ full = spec
+ end
+ for name in directory(full) do
+ if not weird:match(name) then
+ local mode = attributes(full..name,'mode')
+ if mode == 'file' then
+ if path then
+ n = n + 1
+ local f = files[name]
+ if f then
+ if type(f) == 'string' then
+ files[name] = { f, path }
+ else
+ f[#f+1] = path
+ end
+ else -- probably unique anyway
+ files[name] = path
+ local lower = lower(name)
+ if name ~= lower then
+ files["remap:"..lower] = name
+ r = r + 1
+ end
+ end
+ end
+ elseif mode == 'directory' then
+ m = m + 1
+ if path then
+ action(path..'/'..name)
+ else
+ action(name)
+ end
+ end
+ end
+ end
+ end
+ action()
+ if trace_verbose then
+ logs.report("fileio","%s files found on %s directories with %s uppercase remappings",n,m,r)
+ end
+end
+
+-- savers, todo
+
+function resolvers.savefiles()
+ resolvers.save_data('files')
+end
+
+-- A config (optionally) has the paths split in tables. Internally
+-- we join them and split them after the expansion has taken place. This
+-- is more convenient.
+
+function resolvers.splitconfig()
+ for i,c in ipairs(instance) do
+ for k,v in pairs(c) do
+ if type(v) == 'string' then
+ local t = file.split_path(v)
+ if #t > 1 then
+ c[k] = t
+ end
+ end
+ end
+ end
+end
+
+function resolvers.joinconfig()
+ for i,c in ipairs(instance.order) do
+ for k,v in pairs(c) do -- ipairs?
+ if type(v) == 'table' then
+ c[k] = file.join_path(v)
+ end
+ end
+ end
+end
+function resolvers.split_path(str)
+ if type(str) == 'table' then
+ return str
+ else
+ return file.split_path(str)
+ end
+end
+function resolvers.join_path(str)
+ if type(str) == 'table' then
+ return file.join_path(str)
+ else
+ return str
+ end
+end
+
+function resolvers.splitexpansions()
+ local ie = instance.expansions
+ for k,v in next, ie do
+ local t, h = { }, { }
+ for _,vv in ipairs(file.split_path(v)) do
+ if vv ~= "" and not h[vv] then
+ t[#t+1] = vv
+ h[vv] = true
+ end
+ end
+ if #t > 1 then
+ ie[k] = t
+ else
+ ie[k] = t[1]
+ end
+ end
+end
+
+-- end of split/join code
+
+function resolvers.saveoldconfig()
+ resolvers.splitconfig()
+ resolvers.save_data('configuration')
+ resolvers.joinconfig()
+end
+
+resolvers.configbanner = [[
+-- This is a Luatex configuration file created by 'luatools.lua' or
+-- 'luatex.exe' directly. For comment, suggestions and questions you can
+-- contact the ConTeXt Development Team. This configuration file is
+-- not copyrighted. [HH & TH]
+]]
+
+function resolvers.serialize(files)
+ -- This version is somewhat optimized for the kind of
+ -- tables that we deal with, so it's much faster than
+ -- the generic serializer. This makes sense because
+ -- luatools and mtxtools are called frequently. Okay,
+ -- we pay a small price for properly tabbed tables.
+ local t = { }
+ local function dump(k,v,m) -- could be moved inline
+ if type(v) == 'string' then
+ return m .. "['" .. k .. "']='" .. v .. "',"
+ elseif #v == 1 then
+ return m .. "['" .. k .. "']='" .. v[1] .. "',"
+ else
+ return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
+ end
+ end
+ t[#t+1] = "return {"
+ if instance.sortdata then
+ for _, k in pairs(sortedkeys(files)) do -- ipairs
+ local fk = files[k]
+ if type(fk) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for _, kk in pairs(sortedkeys(fk)) do -- ipairs
+ t[#t+1] = dump(kk,fk[kk],"\t\t")
+ end
+ t[#t+1] = "\t},"
+ else
+ t[#t+1] = dump(k,fk,"\t")
+ end
+ end
+ else
+ for k, v in next, files do
+ if type(v) == 'table' then
+ t[#t+1] = "\t['" .. k .. "']={"
+ for kk,vv in next, v do
+ t[#t+1] = dump(kk,vv,"\t\t")
+ end
+ t[#t+1] = "\t},"
+ else
+ t[#t+1] = dump(k,v,"\t")
+ end
+ end
+ end
+ t[#t+1] = "}"
+ return concat(t,"\n")
+end
+
+function resolvers.save_data(dataname, makename) -- untested without cache overload
+ for cachename, files in next, instance[dataname] do
+ local name = (makename or file.join)(cachename,dataname)
+ local luaname, lucname = name .. ".lua", name .. ".luc"
+ if trace_verbose then
+ logs.report("fileio","preparing %s for %s",dataname,cachename)
+ end
+ for k, v in next, files do
+ if type(v) == "table" and #v == 1 then
+ files[k] = v[1]
+ end
+ end
+ local data = {
+ type = dataname,
+ root = cachename,
+ version = resolvers.cacheversion,
+ date = os.date("%Y-%m-%d"),
+ time = os.date("%H:%M:%S"),
+ content = files,
+ }
+ local ok = io.savedata(luaname,resolvers.serialize(data))
+ if ok then
+ if trace_verbose then
+ logs.report("fileio","%s saved in %s",dataname,luaname)
+ end
+ if utils.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip
+ if trace_verbose then
+ logs.report("fileio","%s compiled to %s",dataname,lucname)
+ end
+ else
+ if trace_verbose then
+ logs.report("fileio","compiling failed for %s, deleting file %s",dataname,lucname)
+ end
+ os.remove(lucname)
+ end
+ elseif trace_verbose then
+ logs.report("fileio","unable to save %s in %s (access error)",dataname,luaname)
+ end
+ end
+end
+
+function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
+ filename = ((not filename or (filename == "")) and dataname) or filename
+ filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
+ local blob = loadfile(filename .. ".luc") or loadfile(filename .. ".lua")
+ if blob then
+ local data = blob()
+ if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ if trace_verbose then
+ logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
+ end
+ instance[dataname][pathname] = data.content
+ else
+ if trace_verbose then
+ logs.report("fileio","skipping %s for %s from %s",dataname,pathname,filename)
+ end
+ instance[dataname][pathname] = { }
+ instance.loaderror = true
+ end
+ elseif trace_verbose then
+ logs.report("fileio","skipping %s for %s from %s",dataname,pathname,filename)
+ end
+end
+
+-- some day i'll use the nested approach, but not yet (actually we even drop
+-- engine/progname support since we have only luatex now)
+--
+-- first texmfcnf.lua files are located, next the cached texmf.cnf files
+--
+-- return {
+-- TEXMFBOGUS = 'effe checken of dit werkt',
+-- }
+
+function resolvers.resetconfig()
+ identify_own()
+ instance.configuration, instance.setup, instance.order, instance.loaderror = { }, { }, { }, false
+end
+
+function resolvers.loadnewconfig()
+ for _, cnf in ipairs(instance.luafiles) do
+ local pathname = file.dirname(cnf)
+ local filename = file.join(pathname,resolvers.luaname)
+ local blob = loadfile(filename)
+ if blob then
+ local data = blob()
+ if data then
+ if trace_verbose then
+ logs.report("fileio","loading configuration file %s",filename)
+ end
+ if true then
+ -- flatten to variable.progname
+ local t = { }
+ for k, v in next, data do -- v = progname
+ if type(v) == "string" then
+ t[k] = v
+ else
+ for kk, vv in next, v do -- vv = variable
+ if type(vv) == "string" then
+ t[vv.."."..v] = kk
+ end
+ end
+ end
+ end
+ instance['setup'][pathname] = t
+ else
+ instance['setup'][pathname] = data
+ end
+ else
+ if trace_verbose then
+ logs.report("fileio","skipping configuration file %s",filename)
+ end
+ instance['setup'][pathname] = { }
+ instance.loaderror = true
+ end
+ elseif trace_verbose then
+ logs.report("fileio","skipping configuration file %s",filename)
+ end
+ instance.order[#instance.order+1] = instance.setup[pathname]
+ if instance.loaderror then break end
+ end
+end
+
+function resolvers.loadoldconfig()
+ if not instance.renewcache then
+ for _, cnf in ipairs(instance.cnffiles) do
+ local dname = file.dirname(cnf)
+ resolvers.load_data(dname,'configuration')
+ instance.order[#instance.order+1] = instance.configuration[dname]
+ if instance.loaderror then break end
+ end
+ end
+ resolvers.joinconfig()
+end
+
+function resolvers.expand_variables()
+ local expansions, environment, variables = { }, instance.environment, instance.variables
+ local env = resolvers.env
+ instance.expansions = expansions
+ if instance.engine ~= "" then environment['engine'] = instance.engine end
+ if instance.progname ~= "" then environment['progname'] = instance.progname end
+ for k,v in next, environment do
+ local a, b = match(k,"^(%a+)%_(.*)%s*$")
+ if a and b then
+ expansions[a..'.'..b] = v
+ else
+ expansions[k] = v
+ end
+ end
+ for k,v in next, environment do -- move environment to expansions
+ if not expansions[k] then expansions[k] = v end
+ end
+ for k,v in next, variables do -- move variables to expansions
+ if not expansions[k] then expansions[k] = v end
+ end
+ local busy = false
+ local function resolve(a)
+ busy = true
+ return expansions[a] or env(a)
+ end
+ while true do
+ busy = false
+ for k,v in next, expansions do
+ local s, n = gsub(v,"%$([%a%d%_%-]+)",resolve)
+ local s, m = gsub(s,"%$%{([%a%d%_%-]+)%}",resolve)
+ if n > 0 or m > 0 then
+ expansions[k]= s
+ end
+ end
+ if not busy then break end
+ end
+ for k,v in next, expansions do
+ expansions[k] = gsub(v,"\\", '/')
+ end
+end
+
+function resolvers.variable(name)
+ return entry(instance.variables,name)
+end
+
+function resolvers.expansion(name)
+ return entry(instance.expansions,name)
+end
+
+function resolvers.is_variable(name)
+ return is_entry(instance.variables,name)
+end
+
+function resolvers.is_expansion(name)
+ return is_entry(instance.expansions,name)
+end
+
+function resolvers.unexpanded_path_list(str)
+ local pth = resolvers.variable(str)
+ local lst = resolvers.split_path(pth)
+ return expanded_path_from_list(lst)
+end
+
+function resolvers.unexpanded_path(str)
+ return file.join_path(resolvers.unexpanded_path_list(str))
+end
+
+do -- no longer needed
+
+ local done = { }
+
+ function resolvers.reset_extra_path()
+ local ep = instance.extra_paths
+ if not ep then
+ ep, done = { }, { }
+ instance.extra_paths = ep
+ elseif #ep > 0 then
+ instance.lists, done = { }, { }
+ end
+ end
+
+ function resolvers.register_extra_path(paths,subpaths)
+ local ep = instance.extra_paths or { }
+ local n = #ep
+ if paths and paths ~= "" then
+ if subpaths and subpaths ~= "" then
+ for p in gmatch(paths,"[^,]+") do
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
+ local ps = p .. "/" .. s
+ if not done[ps] then
+ ep[#ep+1] = resolvers.clean_path(ps)
+ done[ps] = true
+ end
+ end
+ end
+ else
+ for p in gmatch(paths,"[^,]+") do
+ if not done[p] then
+ ep[#ep+1] = resolvers.clean_path(p)
+ done[p] = true
+ end
+ end
+ end
+ elseif subpaths and subpaths ~= "" then
+ for i=1,n do
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
+ local ps = ep[i] .. "/" .. s
+ if not done[ps] then
+ ep[#ep+1] = resolvers.clean_path(ps)
+ done[ps] = true
+ end
+ end
+ end
+ end
+ if #ep > 0 then
+ instance.extra_paths = ep -- register paths
+ end
+ if #ep > n then
+ instance.lists = { } -- erase the cache
+ end
+ end
+
+end
+
+local function made_list(instance,list)
+ local ep = instance.extra_paths
+ if not ep or #ep == 0 then
+ return list
+ else
+ local done, new = { }, { }
+ -- honour . .. ../.. but only when at the start
+ for k=1,#list do
+ local v = list[k]
+ if not done[v] then
+ if find(v,"^[%.%/]$") then
+ done[v] = true
+ new[#new+1] = v
+ else
+ break
+ end
+ end
+ end
+ -- first the extra paths
+ for k=1,#ep do
+ local v = ep[k]
+ if not done[v] then
+ done[v] = true
+ new[#new+1] = v
+ end
+ end
+ -- next the formal paths
+ for k=1,#list do
+ local v = list[k]
+ if not done[v] then
+ done[v] = true
+ new[#new+1] = v
+ end
+ end
+ return new
+ end
+end
+
+function resolvers.clean_path_list(str)
+ local t = resolvers.expanded_path_list(str)
+ if t then
+ for i=1,#t do
+ t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ end
+ end
+ return t
+end
+
+function resolvers.expand_path(str)
+ return file.join_path(resolvers.expanded_path_list(str))
+end
+
+function resolvers.expanded_path_list(str)
+ if not str then
+ return ep or { }
+ elseif instance.savelists then
+ -- engine+progname hash
+ str = gsub(str,"%$","")
+ if not instance.lists[str] then -- cached
+ local lst = made_list(instance,resolvers.split_path(resolvers.expansion(str)))
+ instance.lists[str] = expanded_path_from_list(lst)
+ end
+ return instance.lists[str]
+ else
+ local lst = resolvers.split_path(resolvers.expansion(str))
+ return made_list(instance,expanded_path_from_list(lst))
+ end
+end
+
+function resolvers.expanded_path_list_from_var(str) -- brrr
+ local tmp = resolvers.var_of_format_or_suffix(gsub(str,"%$",""))
+ if tmp ~= "" then
+ return resolvers.expanded_path_list(str)
+ else
+ return resolvers.expanded_path_list(tmp)
+ end
+end
+
+function resolvers.expand_path_from_var(str)
+ return file.join_path(resolvers.expanded_path_list_from_var(str))
+end
+
+function resolvers.format_of_var(str)
+ return formats[str] or formats[alternatives[str]] or ''
+end
+function resolvers.format_of_suffix(str)
+ return suffixmap[file.extname(str)] or 'tex'
+end
+
+function resolvers.variable_of_format(str)
+ return formats[str] or formats[alternatives[str]] or ''
+end
+
+function resolvers.var_of_format_or_suffix(str)
+ local v = formats[str]
+ if v then
+ return v
+ end
+ v = formats[alternatives[str]]
+ if v then
+ return v
+ end
+ v = suffixmap[file.extname(str)]
+ if v then
+ return formats[isf]
+ end
+ return ''
+end
+
+function resolvers.expand_braces(str) -- output variable and brace expansion of STRING
+ local ori = resolvers.variable(str)
+ local pth = expanded_path_from_list(resolvers.split_path(ori))
+ return file.join_path(pth)
+end
+
+resolvers.isreadable = { }
+
+function resolvers.isreadable.file(name)
+ local readable = lfs.isfile(name) -- brrr
+ if trace_detail then
+ if readable then
+ logs.report("fileio","+ readable: %s",name)
+ else
+ logs.report("fileio","- readable: %s", name)
+ end
+ end
+ return readable
+end
+
+resolvers.isreadable.tex = resolvers.isreadable.file
+
+-- name
+-- name/name
+
+local function collect_files(names)
+ local filelist = { }
+ for k=1,#names do
+ local fname = names[k]
+ if trace_detail then
+ logs.report("fileio","? blobpath asked: %s",fname)
+ end
+ local bname = file.basename(fname)
+ local dname = file.dirname(fname)
+ if dname == "" or find(dname,"^%.") then
+ dname = false
+ else
+ dname = "/" .. dname .. "$"
+ end
+ local hashes = instance.hashes
+ for h=1,#hashes do
+ local hash = hashes[h]
+ local blobpath = hash.tag
+ local files = blobpath and instance.files[blobpath]
+ if files then
+ if trace_detail then
+ logs.report("fileio",'? blobpath do: %s (%s)',blobpath,bname)
+ end
+ local blobfile = files[bname]
+ if not blobfile then
+ local rname = "remap:"..bname
+ blobfile = files[rname]
+ if blobfile then
+ bname = files[rname]
+ blobfile = files[bname]
+ end
+ end
+ if blobfile then
+ if type(blobfile) == 'string' then
+ if not dname or find(blobfile,dname) then
+ filelist[#filelist+1] = {
+ hash.type,
+ file.join(blobpath,blobfile,bname), -- search
+ resolvers.concatinators[hash.type](blobpath,blobfile,bname) -- result
+ }
+ end
+ else
+ for kk=1,#blobfile do
+ local vv = blobfile[kk]
+ if not dname or find(vv,dname) then
+ filelist[#filelist+1] = {
+ hash.type,
+ file.join(blobpath,vv,bname), -- search
+ resolvers.concatinators[hash.type](blobpath,vv,bname) -- result
+ }
+ end
+ end
+ end
+ end
+ elseif trace_locating then
+ logs.report("fileio",'! blobpath no: %s (%s)',blobpath,bname)
+ end
+ end
+ end
+ if #filelist > 0 then
+ return filelist
+ else
+ return nil
+ end
+end
+
+function resolvers.suffix_of_format(str)
+ if suffixes[str] then
+ return suffixes[str][1]
+ else
+ return ""
+ end
+end
+
+function resolvers.suffixes_of_format(str)
+ if suffixes[str] then
+ return suffixes[str]
+ else
+ return {}
+ end
+end
+
+function resolvers.register_in_trees(name)
+ if not find(name,"^%.") then
+ instance.foundintrees[name] = (instance.foundintrees[name] or 0) + 1 -- maybe only one
+ end
+end
+
+-- split the next one up for readability (bu this module needs a cleanup anyway)
+
+local function can_be_dir(name) -- can become local
+ local fakepaths = instance.fakepaths
+ if not fakepaths[name] then
+ if lfs.isdir(name) then
+ fakepaths[name] = 1 -- directory
+ else
+ fakepaths[name] = 2 -- no directory
+ end
+ end
+ return (fakepaths[name] == 1)
+end
+
+local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
+ local result = collected or { }
+ local stamp = nil
+ filename = file.collapse_path(filename) -- elsewhere
+ filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ -- speed up / beware: format problem
+ if instance.remember then
+ stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
+ if instance.found[stamp] then
+ if trace_locating then
+ logs.report("fileio",'! remembered: %s',filename)
+ end
+ return instance.found[stamp]
+ end
+ end
+ if not dangerous[instance.format or "?"] then
+ if resolvers.isreadable.file(filename) then
+ if trace_detail then
+ logs.report("fileio",'= found directly: %s',filename)
+ end
+ instance.found[stamp] = { filename }
+ return { filename }
+ end
+ end
+ if find(filename,'%*') then
+ if trace_locating then
+ logs.report("fileio",'! wildcard: %s', filename)
+ end
+ result = resolvers.find_wildcard_files(filename)
+ elseif file.is_qualified_path(filename) then
+ if resolvers.isreadable.file(filename) then
+ if trace_locating then
+ logs.report("fileio",'! qualified: %s', filename)
+ end
+ result = { filename }
+ else
+ local forcedname, ok, suffix = "", false, file.extname(filename)
+ if suffix == "" then -- why
+ if instance.format == "" then
+ forcedname = filename .. ".tex"
+ if resolvers.isreadable.file(forcedname) then
+ if trace_locating then
+ logs.report("fileio",'! no suffix, forcing standard filetype: tex')
+ end
+ result, ok = { forcedname }, true
+ end
+ else
+ local suffixes = resolvers.suffixes_of_format(instance.format)
+ for _, s in next, suffixes do
+ forcedname = filename .. "." .. s
+ if resolvers.isreadable.file(forcedname) then
+ if trace_locating then
+ logs.report("fileio",'! no suffix, forcing format filetype: %s', s)
+ end
+ result, ok = { forcedname }, true
+ break
+ end
+ end
+ end
+ end
+ if not ok and suffix ~= "" then
+ -- try to find in tree (no suffix manipulation), here we search for the
+ -- matching last part of the name
+ local basename = file.basename(filename)
+ local pattern = (filename .. "$"):gsub("([%.%-])","%%%1")
+ local savedformat = instance.format
+ local format = savedformat or ""
+ if format == "" then
+ instance.format = resolvers.format_of_suffix(suffix)
+ end
+ if not format then
+ instance.format = "othertextfiles" -- kind of everything, maybe texinput is better
+ end
+ --
+ local resolved = collect_instance_files(basename)
+ if #result == 0 then
+ local lowered = lower(basename)
+ if filename ~= lowered then
+ resolved = collect_instance_files(lowered)
+ end
+ end
+ resolvers.format = savedformat
+ --
+ for r=1,#resolved do
+ local rr = resolved[r]
+ if rr:find(pattern) then
+ result[#result+1], ok = rr, true
+ end
+ end
+ -- a real wildcard:
+ --
+ -- if not ok then
+ -- local filelist = collect_files({basename})
+ -- for f=1,#filelist do
+ -- local ff = filelist[f][3] or ""
+ -- if ff:find(pattern) then
+ -- result[#result+1], ok = ff, true
+ -- end
+ -- end
+ -- end
+ end
+ if not ok and trace_locating then
+ logs.report("fileio",'? qualified: %s', filename)
+ end
+ end
+ else
+ -- search spec
+ local filetype, extra, done, wantedfiles, ext = '', nil, false, { }, file.extname(filename)
+ if ext == "" then
+ if not instance.force_suffixes then
+ wantedfiles[#wantedfiles+1] = filename
+ end
+ else
+ wantedfiles[#wantedfiles+1] = filename
+ end
+ if instance.format == "" then
+ if ext == "" then
+ local forcedname = filename .. '.tex'
+ wantedfiles[#wantedfiles+1] = forcedname
+ filetype = resolvers.format_of_suffix(forcedname)
+ if trace_locating then
+ logs.report("fileio",'! forcing filetype: %s',filetype)
+ end
+ else
+ filetype = resolvers.format_of_suffix(filename)
+ if trace_locating then
+ logs.report("fileio",'! using suffix based filetype: %s',filetype)
+ end
+ end
+ else
+ if ext == "" then
+ local suffixes = resolvers.suffixes_of_format(instance.format)
+ for _, s in next, suffixes do
+ wantedfiles[#wantedfiles+1] = filename .. "." .. s
+ end
+ end
+ filetype = instance.format
+ if trace_locating then
+ logs.report("fileio",'! using given filetype: %s',filetype)
+ end
+ end
+ local typespec = resolvers.variable_of_format(filetype)
+ local pathlist = resolvers.expanded_path_list(typespec)
+ if not pathlist or #pathlist == 0 then
+ -- no pathlist, access check only / todo == wildcard
+ if trace_detail then
+ logs.report("fileio",'? filename: %s',filename)
+ logs.report("fileio",'? filetype: %s',filetype or '?')
+ logs.report("fileio",'? wanted files: %s',concat(wantedfiles," | "))
+ end
+ for k=1,#wantedfiles do
+ local fname = wantedfiles[k]
+ if fname and resolvers.isreadable.file(fname) then
+ filename, done = fname, true
+ result[#result+1] = file.join('.',fname)
+ break
+ end
+ end
+ -- this is actually 'other text files' or 'any' or 'whatever'
+ local filelist = collect_files(wantedfiles)
+ local fl = filelist and filelist[1]
+ if fl then
+ filename = fl[3]
+ result[#result+1] = filename
+ done = true
+ end
+ else
+ -- list search
+ local filelist = collect_files(wantedfiles)
+ local doscan, recurse
+ if trace_detail then
+ logs.report("fileio",'? filename: %s',filename)
+ end
+ -- a bit messy ... esp the doscan setting here
+ for k=1,#pathlist do
+ local path = pathlist[k]
+ if find(path,"^!!") then doscan = false else doscan = true end
+ if find(path,"//$") then recurse = true else recurse = false end
+ local pathname = gsub(path,"^!+", '')
+ done = false
+ -- using file list
+ if filelist and not (done and not instance.allresults) and recurse then
+ -- compare list entries with permitted pattern
+ pathname = gsub(pathname,"([%-%.])","%%%1") -- this also influences
+ pathname = gsub(pathname,"/+$", '/.*') -- later usage of pathname
+ pathname = gsub(pathname,"//", '/.-/') -- not ok for /// but harmless
+ local expr = "^" .. pathname
+ for k=1,#filelist do
+ local fl = filelist[k]
+ local f = fl[2]
+ if find(f,expr) then
+ if trace_detail then
+ logs.report("fileio",'= found in hash: %s',f)
+ end
+ --- todo, test for readable
+ result[#result+1] = fl[3]
+ resolvers.register_in_trees(f) -- for tracing used files
+ done = true
+ if not instance.allresults then break end
+ end
+ end
+ end
+ if not done and doscan then
+ -- check if on disk / unchecked / does not work at all / also zips
+ if resolvers.splitmethod(pathname).scheme == 'file' then -- ?
+ local pname = gsub(pathname,"%.%*$",'')
+ if not find(pname,"%*") then
+ local ppname = gsub(pname,"/+$","")
+ if can_be_dir(ppname) then
+ for k=1,#wantedfiles do
+ local w = wantedfiles[k]
+ local fname = file.join(ppname,w)
+ if resolvers.isreadable.file(fname) then
+ if trace_detail then
+ logs.report("fileio",'= found by scanning: %s',fname)
+ end
+ result[#result+1] = fname
+ done = true
+ if not instance.allresults then break end
+ end
+ end
+ else
+ -- no access needed for non existing path, speedup (esp in large tree with lots of fake)
+ end
+ end
+ end
+ end
+ if not done and doscan then
+ -- todo: slow path scanning
+ end
+ if done and not instance.allresults then break end
+ end
+ end
+ end
+ for k=1,#result do
+ result[k] = file.collapse_path(result[k])
+ end
+ if instance.remember then
+ instance.found[stamp] = result
+ end
+ return result
+end
+
+if not resolvers.concatinators then resolvers.concatinators = { } end
+
+resolvers.concatinators.tex = file.join
+resolvers.concatinators.file = resolvers.concatinators.tex
+
+function resolvers.find_files(filename,filetype,mustexist)
+ if type(mustexist) == boolean then
+ -- all set
+ elseif type(filetype) == 'boolean' then
+ filetype, mustexist = nil, false
+ elseif type(filetype) ~= 'string' then
+ filetype, mustexist = nil, false
+ end
+ instance.format = filetype or ''
+ local result = collect_instance_files(filename)
+ if #result == 0 then
+ local lowered = lower(filename)
+ if filename ~= lowered then
+ return collect_instance_files(lowered)
+ end
+ end
+ instance.format = ''
+ return result
+end
+
+function resolvers.find_file(filename,filetype,mustexist)
+ return (resolvers.find_files(filename,filetype,mustexist)[1] or "")
+end
+
+function resolvers.find_given_files(filename)
+ local bname, result = file.basename(filename), { }
+ local hashes = instance.hashes
+ for k=1,#hashes do
+ local hash = hashes[k]
+ local files = instance.files[hash.tag]
+ local blist = files[bname]
+ if not blist then
+ local rname = "remap:"..bname
+ blist = files[rname]
+ if blist then
+ bname = files[rname]
+ blist = files[bname]
+ end
+ end
+ if blist then
+ if type(blist) == 'string' then
+ result[#result+1] = resolvers.concatinators[hash.type](hash.tag,blist,bname) or ""
+ if not instance.allresults then break end
+ else
+ for kk=1,#blist do
+ local vv = blist[kk]
+ result[#result+1] = resolvers.concatinators[hash.type](hash.tag,vv,bname) or ""
+ if not instance.allresults then break end
+ end
+ end
+ end
+ end
+ return result
+end
+
+function resolvers.find_given_file(filename)
+ return (resolvers.find_given_files(filename)[1] or "")
+end
+
+local function doit(path,blist,bname,tag,kind,result,allresults)
+ local done = false
+ if blist and kind then
+ if type(blist) == 'string' then
+ -- make function and share code
+ if find(lower(blist),path) then
+ result[#result+1] = resolvers.concatinators[kind](tag,blist,bname) or ""
+ done = true
+ end
+ else
+ for kk=1,#blist do
+ local vv = blist[kk]
+ if find(lower(vv),path) then
+ result[#result+1] = resolvers.concatinators[kind](tag,vv,bname) or ""
+ done = true
+ if not allresults then break end
+ end
+ end
+ end
+ end
+ return done
+end
+
+function resolvers.find_wildcard_files(filename) -- todo: remap:
+ local result = { }
+ local bname, dname = file.basename(filename), file.dirname(filename)
+ local path = gsub(dname,"^*/","")
+ path = gsub(path,"*",".*")
+ path = gsub(path,"-","%%-")
+ if dname == "" then
+ path = ".*"
+ end
+ local name = bname
+ name = gsub(name,"*",".*")
+ name = gsub(name,"-","%%-")
+ path = lower(path)
+ name = lower(name)
+ local files, allresults, done = instance.files, instance.allresults, false
+ if find(name,"%*") then
+ local hashes = instance.hashes
+ for k=1,#hashes do
+ local hash = hashes[k]
+ local tag, kind = hash.tag, hash.type
+ for kk, hh in next, files[hash.tag] do
+ if not find(kk,"^remap:") then
+ if find(lower(kk),name) then
+ if doit(path,hh,kk,tag,kind,result,allresults) then done = true end
+ if done and not allresults then break end
+ end
+ end
+ end
+ end
+ else
+ local hashes = instance.hashes
+ for k=1,#hashes do
+ local hash = hashes[k]
+ local tag, kind = hash.tag, hash.type
+ if doit(path,files[tag][bname],bname,tag,kind,result,allresults) then done = true end
+ if done and not allresults then break end
+ end
+ end
+ -- we can consider also searching the paths not in the database, but then
+ -- we end up with a messy search (all // in all path specs)
+ return result
+end
+
+function resolvers.find_wildcard_file(filename)
+ return (resolvers.find_wildcard_files(filename)[1] or "")
+end
+
+-- main user functions
+
+function resolvers.automount()
+ -- implemented later
+end
+
+function resolvers.load(option)
+ statistics.starttiming(instance)
+ resolvers.resetconfig()
+ resolvers.identify_cnf()
+ resolvers.load_lua()
+ resolvers.expand_variables()
+ resolvers.load_cnf()
+ resolvers.expand_variables()
+ if option ~= "nofiles" then
+ resolvers.load_hash()
+ resolvers.automount()
+ end
+ statistics.stoptiming(instance)
+end
+
+function resolvers.for_files(command, files, filetype, mustexist)
+ if files and #files > 0 then
+ local function report(str)
+ if trace_verbose then
+ logs.report("fileio",str) -- has already verbose
+ else
+ print(str)
+ end
+ end
+ if trace_verbose then
+ report('')
+ end
+ for _, file in ipairs(files) do
+ local result = command(file,filetype,mustexist)
+ if type(result) == 'string' then
+ report(result)
+ else
+ for _,v in ipairs(result) do
+ report(v)
+ end
+ end
+ end
+ end
+end
+
+-- strtab
+
+resolvers.var_value = resolvers.variable -- output the value of variable $STRING.
+resolvers.expand_var = resolvers.expansion -- output variable expansion of STRING.
+
+function resolvers.show_path(str) -- output search path for file type NAME
+ return file.join_path(resolvers.expanded_path_list(resolvers.format_of_var(str)))
+end
+
+-- resolvers.find_file(filename)
+-- resolvers.find_file(filename, filetype, mustexist)
+-- resolvers.find_file(filename, mustexist)
+-- resolvers.find_file(filename, filetype)
+
+function resolvers.register_file(files, name, path)
+ if files[name] then
+ if type(files[name]) == 'string' then
+ files[name] = { files[name], path }
+ else
+ files[name] = path
+ end
+ else
+ files[name] = path
+ end
+end
+
+function resolvers.splitmethod(filename)
+ if not filename then
+ return { } -- safeguard
+ elseif type(filename) == "table" then
+ return filename -- already split
+ elseif not find(filename,"://") then
+ return { scheme="file", path = filename, original=filename } -- quick hack
+ else
+ return url.hashed(filename)
+ end
+end
+
+function table.sequenced(t,sep) -- temp here
+ local s = { }
+ for k, v in pairs(t) do -- pairs?
+ s[#s+1] = k .. "=" .. v
+ end
+ return concat(s, sep or " | ")
+end
+
+function resolvers.methodhandler(what, filename, filetype) -- ...
+ local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
+ local scheme = specification.scheme
+ if resolvers[what][scheme] then
+ if trace_locating then
+ logs.report("fileio",'= handler: %s -> %s -> %s',specification.original,what,table.sequenced(specification))
+ end
+ return resolvers[what][scheme](filename,filetype) -- todo: specification
+ else
+ return resolvers[what].tex(filename,filetype) -- todo: specification
+ end
+end
+
+function resolvers.clean_path(str)
+ if str then
+ str = gsub(str,"\\","/")
+ str = gsub(str,"^!+","")
+ str = gsub(str,"^~",resolvers.homedir)
+ return str
+ else
+ return nil
+ end
+end
+
+function resolvers.do_with_path(name,func)
+ for _, v in pairs(resolvers.expanded_path_list(name)) do -- pairs?
+ func("^"..resolvers.clean_path(v))
+ end
+end
+
+function resolvers.do_with_var(name,func)
+ func(expanded_var(name))
+end
+
+function resolvers.with_files(pattern,handle)
+ for _, hash in ipairs(instance.hashes) do
+ local blobpath = hash.tag
+ local blobtype = hash.type
+ if blobpath then
+ local files = instance.files[blobpath]
+ if files then
+ for k,v in next, files do
+ if find(k,"^remap:") then
+ k = files[k]
+ v = files[k] -- chained
+ end
+ if find(k,pattern) then
+ if type(v) == "string" then
+ handle(blobtype,blobpath,v,k)
+ else
+ for _,vv in pairs(v) do -- ipairs?
+ handle(blobtype,blobpath,vv,k)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+function resolvers.locate_format(name)
+ local barename, fmtname = name:gsub("%.%a+$",""), ""
+ if resolvers.usecache then
+ local path = file.join(caches.setpath("formats")) -- maybe platform
+ fmtname = file.join(path,barename..".fmt") or ""
+ end
+ if fmtname == "" then
+ fmtname = resolvers.find_files(barename..".fmt")[1] or ""
+ end
+ fmtname = resolvers.clean_path(fmtname)
+ if fmtname ~= "" then
+ local barename = file.removesuffix(fmtname)
+ local luaname, lucname, luiname = barename .. ".lua", barename .. ".luc", barename .. ".lui"
+ if lfs.isfile(luiname) then
+ return barename, luiname
+ elseif lfs.isfile(lucname) then
+ return barename, lucname
+ elseif lfs.isfile(luaname) then
+ return barename, luaname
+ end
+ end
+ return nil, nil
+end
+
+function resolvers.boolean_variable(str,default)
+ local b = resolvers.expansion(str)
+ if b == "" then
+ return default
+ else
+ b = toboolean(b)
+ return (b == nil and default) or b
+ end
+end
+
+texconfig.kpse_init = false
+
+kpse = { original = kpse } setmetatable(kpse, { __index = function(k,v) return resolvers[v] end } )
+
+-- for a while
+
+input = resolvers
diff --git a/tex/context/base/data-tex.lua b/tex/context/base/data-tex.lua
new file mode 100644
index 000000000..792c48fec
--- /dev/null
+++ b/tex/context/base/data-tex.lua
@@ -0,0 +1,220 @@
+if not modules then modules = { } end modules ['data-tex'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- special functions that deal with io
+
+local format, lower = string.format, string.lower
+
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
+
+local texiowrite_nl = (texio and texio.write_nl) or print
+local texiowrite = (texio and texio.write) or print
+
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
+
+function finders.generic(tag,filename,filetype)
+ local foundname = resolvers.find_file(filename,filetype)
+ if foundname and foundname ~= "" then
+ if trace_locating then
+ logs.report("fileio",'+ finder: %s, file: %s', tag,filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ logs.report("fileio",'- finder: %s, file: %s', tag,filename)
+ end
+ return unpack(finders.notfound)
+ end
+end
+
+--~ local getlines = lpeg.Ct(lpeg.linebyline)
+
+local input_translator, utf_translator, user_translator = nil, nil, nil
+
+function resolvers.install_text_filter(name,func)
+ if name == "input" then input_translator = func
+ elseif name == "utf" then utf_translator = func
+ elseif name == "user" then user_translator = func end
+end
+
+function openers.text_opener(filename,file_handle,tag)
+ local u = unicode.utftype(file_handle)
+ local t = { }
+ if u > 0 then
+ if trace_locating then
+ logs.report("fileio",'+ opener: %s (%s), file: %s',tag,unicode.utfname[u],filename)
+ end
+ local l
+ if u > 2 then
+ l = unicode.utf32_to_utf8(file_handle:read("*a"),u==4)
+ else
+ l = unicode.utf16_to_utf8(file_handle:read("*a"),u==2)
+ end
+ file_handle:close()
+ t = {
+ utftype = u, -- may go away
+ lines = l,
+ current = 0, -- line number, not really needed
+ handle = nil,
+ noflines = #l,
+ close = function()
+ if trace_locating then
+ logs.report("fileio",'= closer: %s (%s), file: %s',tag,unicode.utfname[u],filename)
+ end
+ logs.show_close(filename)
+ t = nil
+ end,
+ reader = function(self)
+ self = self or t
+ local current, lines = self.current, self.lines
+ if current >= #lines then
+ return nil
+ else
+ current = current + 1
+ self.current = current
+ local line = lines[current]
+ if not line then
+ return nil
+ elseif line == "" then
+ return ""
+ else
+ if input_translator then
+ line = input_translator(line)
+ end
+ if utf_translator then
+ line = utf_translator(line)
+ end
+ if user_translator then
+ line = user_translator(line)
+ end
+ return line
+ end
+ end
+ end
+ }
+ else
+ if trace_locating then
+ logs.report("fileio",'+ opener: %s, file: %s',tag,filename)
+ end
+ -- todo: file;name -> freeze / eerste regel scannen -> freeze
+ --~ local data = getlines:match(file_handle:read("*a"))
+ --~ local n = 0
+ t = {
+ reader = function() -- self
+ local line = file_handle:read()
+ --~ n = n + 1
+ --~ local line = data[n]
+ --~ print(line)
+ if not line then
+ return nil
+ elseif line == "" then
+ return ""
+ else
+ if input_translator then
+ line = input_translator(line)
+ end
+ if utf_translator then
+ line = utf_translator(line)
+ end
+ if user_translator then
+ line = user_translator(line)
+ end
+ return line
+ end
+ end,
+ close = function()
+ if trace_locating then
+ logs.report("fileio",'= closer: %s, file: %s',tag,filename)
+ end
+ logs.show_close(filename)
+ file_handle:close()
+ t = nil
+ end,
+ handle = function()
+ return file_handle
+ end,
+ noflines = function()
+ t.noflines = io.noflines(file_handle)
+ return t.noflines
+ end
+ }
+ end
+ return t
+end
+
+function openers.generic(tag,filename)
+ if filename and filename ~= "" then
+ local f = io.open(filename,"r")
+ if f then
+ logs.show_open(filename)
+ return openers.text_opener(filename,f,tag)
+ end
+ end
+ if trace_locating then
+ logs.report("fileio",'- opener: %s, file: %s',tag,filename)
+ end
+ return unpack(openers.notfound)
+end
+
+function loaders.generic(tag,filename)
+ if filename and filename ~= "" then
+ local f = io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ logs.report("fileio",'+ loader: %s, file: %s',tag,filename)
+ end
+ local s = f:read("*a")
+ if garbagecollector and garbagecollector.check then garbagecollector.check(#s) end
+ f:close()
+ if s then
+ return true, s, #s
+ end
+ end
+ end
+ if trace_locating then
+ logs.report("fileio",'- loader: %s, file: %s',tag,filename)
+ end
+ return unpack(loaders.notfound)
+end
+
+function finders.tex(filename,filetype)
+ return finders.generic('tex',filename,filetype)
+end
+
+function openers.tex(filename)
+ return openers.generic('tex',filename)
+end
+
+function loaders.tex(filename)
+ return loaders.generic('tex',filename)
+end
+
+function resolvers.findtexfile(filename, filetype)
+ return resolvers.methodhandler('finders',file.collapse_path(filename), filetype)
+end
+
+function resolvers.opentexfile(filename)
+ return resolvers.methodhandler('openers',file.collapse_path(filename))
+end
+
+function resolvers.openfile(filename)
+ local fullname = resolvers.findtexfile(filename)
+ if fullname and (fullname ~= "") then
+ return resolvers.opentexfile(fullname)
+ else
+ return nil
+ end
+end
+
+function resolvers.texdatablob(filename, filetype)
+ local ok, data, size = resolvers.loadbinfile(filename, filetype)
+ return data or ""
+end
+
+resolvers.loadtexfile = resolvers.texdatablob
diff --git a/tex/context/base/data-tmf.lua b/tex/context/base/data-tmf.lua
new file mode 100644
index 000000000..302841a65
--- /dev/null
+++ b/tex/context/base/data-tmf.lua
@@ -0,0 +1,72 @@
+if not modules then modules = { } end modules ['data-tmf'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- loads *.tmf files in minimal tree roots (to be optimized and documented)
+
+function resolvers.check_environment(tree)
+ logs.simpleline()
+ os.setenv('TMP', os.getenv('TMP') or os.getenv('TEMP') or os.getenv('TMPDIR') or os.getenv('HOME'))
+ os.setenv('TEXOS', os.getenv('TEXOS') or ("texmf-" .. os.currentplatform()))
+ os.setenv('TEXPATH', (tree or "tex"):gsub("\/+$",''))
+ os.setenv('TEXMFOS', os.getenv('TEXPATH') .. "/" .. os.getenv('TEXOS'))
+ logs.simpleline()
+ logs.simple("preset : TEXPATH => %s", os.getenv('TEXPATH'))
+ logs.simple("preset : TEXOS => %s", os.getenv('TEXOS'))
+ logs.simple("preset : TEXMFOS => %s", os.getenv('TEXMFOS'))
+ logs.simple("preset : TMP => %s", os.getenv('TMP'))
+ logs.simple('')
+end
+
+function resolvers.load_environment(name) -- todo: key=value as well as lua
+ local f = io.open(name)
+ if f then
+ for line in f:lines() do
+ if line:find("^[%%%#]") then
+ -- skip comment
+ else
+ local key, how, value = line:match("^(.-)%s*([<=>%?]+)%s*(.*)%s*$")
+ if how then
+ value = value:gsub("%%(.-)%%", function(v) return os.getenv(v) or "" end)
+ if how == "=" or how == "<<" then
+ os.setenv(key,value)
+ elseif how == "?" or how == "??" then
+ os.setenv(key,os.getenv(key) or value)
+ elseif how == "<" or how == "+=" then
+ if os.getenv(key) then
+ os.setenv(key,os.getenv(key) .. io.fileseparator .. value)
+ else
+ os.setenv(key,value)
+ end
+ elseif how == ">" or how == "=+" then
+ if os.getenv(key) then
+ os.setenv(key,value .. io.pathseparator .. os.getenv(key))
+ else
+ os.setenv(key,value)
+ end
+ end
+ end
+ end
+ end
+ f:close()
+ end
+end
+
+function resolvers.load_tree(tree)
+ if tree and tree ~= "" then
+ local setuptex = 'setuptex.tmf'
+ if lfs.attributes(tree, "mode") == "directory" then -- check if not nil
+ setuptex = tree .. "/" .. setuptex
+ else
+ setuptex = tree
+ end
+ if io.exists(setuptex) then
+ resolvers.check_environment(tree)
+ resolvers.load_environment(setuptex)
+ end
+ end
+end
diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua
new file mode 100644
index 000000000..31d0147ea
--- /dev/null
+++ b/tex/context/base/data-tmp.lua
@@ -0,0 +1,174 @@
+if not modules then modules = { } end modules ['data-tmp'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>This module deals with caching data. It sets up the paths and
+implements loaders and savers for tables. Best is to set the
+following variable. When not set, the usual paths will be
+checked. Personally I prefer the (users) temporary path.</p>
+
+</code>
+TEXMFCACHE=$TMP;$TEMP;$TMPDIR;$TEMPDIR;$HOME;$TEXMFVAR;$VARTEXMF;.
+</code>
+
+<p>Currently we do no locking when we write files. This is no real
+problem because most caching involves fonts and the chance of them
+being written at the same time is small. We also need to extend
+luatools with a recache feature.</p>
+--ldx]]--
+
+local format, lower, gsub = string.format, string.lower, string.gsub
+
+local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end)
+
+caches = caches or { }
+
+caches.path = caches.path or nil
+caches.base = caches.base or "luatex-cache"
+caches.more = caches.more or "context"
+caches.direct = false -- true is faster but may need huge amounts of memory
+caches.tree = false
+caches.paths = caches.paths or nil
+caches.force = false
+caches.defaults = { "TEXMFCACHE", "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" }
+
+function caches.temp()
+ local cachepath = nil
+ local function check(list,isenv)
+ if not cachepath then
+ for k=1,#list do
+ local v = list[k]
+ cachepath = (isenv and (os.env[v] or "")) or v or ""
+ if cachepath == "" then
+ -- next
+ else
+ cachepath = resolvers.clean_path(cachepath)
+ if lfs.isdir(cachepath) and file.iswritable(cachepath) then -- lfs.attributes(cachepath,"mode") == "directory"
+ break
+ elseif caches.force or io.ask(format("\nShould I create the cache path %s?",cachepath), "no", { "yes", "no" }) == "yes" then
+ dir.mkdirs(cachepath)
+ if lfs.isdir(cachepath) and file.iswritable(cachepath) then
+ break
+ end
+ end
+ end
+ cachepath = nil
+ end
+ end
+ end
+ check(resolvers.clean_path_list("TEXMFCACHE") or { })
+ check(caches.defaults,true)
+ if not cachepath then
+ print("\nfatal error: there is no valid (writable) cache path defined\n")
+ os.exit()
+ elseif not lfs.isdir(cachepath) then -- lfs.attributes(cachepath,"mode") ~= "directory"
+ print(format("\nfatal error: cache path %s is not a directory\n",cachepath))
+ os.exit()
+ end
+ cachepath = file.collapse_path(cachepath)
+ function caches.temp()
+ return cachepath
+ end
+ return cachepath
+end
+
+function caches.configpath()
+ return table.concat(resolvers.instance.cnffiles,";")
+end
+
+function caches.hashed(tree)
+ return md5.hex(gsub(lower(tree),"[\\\/]+","/"))
+end
+
+function caches.treehash()
+ local tree = caches.configpath()
+ if not tree or tree == "" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
+end
+
+function caches.setpath(...)
+ if not caches.path then
+ if not caches.path then
+ caches.path = caches.temp()
+ end
+ caches.path = resolvers.clean_path(caches.path) -- to be sure
+ caches.tree = caches.tree or caches.treehash()
+ if caches.tree then
+ caches.path = dir.mkdirs(caches.path,caches.base,caches.more,caches.tree)
+ else
+ caches.path = dir.mkdirs(caches.path,caches.base,caches.more)
+ end
+ end
+ if not caches.path then
+ caches.path = '.'
+ end
+ caches.path = resolvers.clean_path(caches.path)
+ if not table.is_empty({...}) then
+ local pth = dir.mkdirs(caches.path,...)
+ return pth
+ end
+ caches.path = dir.expand_name(caches.path)
+ return caches.path
+end
+
+function caches.definepath(category,subcategory)
+ return function()
+ return caches.setpath(category,subcategory)
+ end
+end
+
+function caches.setluanames(path,name)
+ return path .. "/" .. name .. ".tma", path .. "/" .. name .. ".tmc"
+end
+
+function caches.loaddata(path,name)
+ local tmaname, tmcname = caches.setluanames(path,name)
+ local loader = loadfile(tmcname) or loadfile(tmaname)
+ if loader then
+ return loader()
+ else
+ return false
+ end
+end
+
+--~ function caches.loaddata(path,name)
+--~ local tmaname, tmcname = caches.setluanames(path,name)
+--~ return dofile(tmcname) or dofile(tmaname)
+--~ end
+
+function caches.iswritable(filepath,filename)
+ local tmaname, tmcname = caches.setluanames(filepath,filename)
+ return file.iswritable(tmaname)
+end
+
+function caches.savedata(filepath,filename,data,raw)
+ local tmaname, tmcname = caches.setluanames(filepath,filename)
+ local reduce, simplify = true, true
+ if raw then
+ reduce, simplify = false, false
+ end
+ if caches.direct then
+ file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
+ else
+ table.tofile(tmaname, data,'return',false,true,false) -- maybe not the last true
+ end
+ local cleanup = resolvers.boolean_variable("PURGECACHE", false)
+ local strip = resolvers.boolean_variable("LUACSTRIP", true)
+ utils.lua.compile(tmaname, tmcname, cleanup, strip)
+end
+
+-- here we use the cache for format loading (texconfig.[formatname|jobname])
+
+--~ if tex and texconfig and texconfig.formatname and texconfig.formatname == "" then
+if tex and texconfig and (not texconfig.formatname or texconfig.formatname == "") and input and resolvers.instance then
+ if not texconfig.luaname then texconfig.luaname = "cont-en.lua" end -- or luc
+ texconfig.formatname = caches.setpath("formats") .. "/" .. gsub(texconfig.luaname,"%.lu.$",".fmt")
+end
diff --git a/tex/context/base/data-tre.lua b/tex/context/base/data-tre.lua
new file mode 100644
index 000000000..9cac73b8e
--- /dev/null
+++ b/tex/context/base/data-tre.lua
@@ -0,0 +1,43 @@
+if not modules then modules = { } end modules ['data-tre'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- \input tree://oeps1/**/oeps.tex
+
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
+
+local done, found = { }, { }
+
+function finders.tree(specification,filetype)
+ local fnd = found[specification]
+ if not fnd then
+ local spec = resolvers.splitmethod(specification).path or ""
+ if spec ~= "" then
+ local path, name = file.dirname(spec), file.basename(spec)
+ if path == "" then path = "." end
+ local hash = done[path]
+ if not hash then
+ local pattern = path .. "/*" -- we will use the proper splitter
+ hash = dir.glob(pattern)
+ done[path] = hash
+ end
+ local pattern = "/" .. name:gsub("([%.%-%+])", "%%%1") .. "$"
+ for k, v in pairs(hash) do
+ if v:find(pattern) then
+ found[specification] = v
+ return v
+ end
+ end
+ end
+ fnd = unpack(finders.notfound)
+ found[specification] = fnd
+ end
+ return fnd
+end
+
+openers.tree = openers.generic
+loaders.tree = loaders.generic
diff --git a/tex/context/base/data-use.lua b/tex/context/base/data-use.lua
new file mode 100644
index 000000000..609ffd88f
--- /dev/null
+++ b/tex/context/base/data-use.lua
@@ -0,0 +1,127 @@
+if not modules then modules = { } end modules ['data-use'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, lower, gsub = string.format, string.lower, string.gsub
+
+local trace_verbose = false trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v trackers.enable("resolvers.verbose") end)
+
+-- since we want to use the cache instead of the tree, we will now
+-- reimplement the saver.
+
+local save_data = resolvers.save_data
+local load_data = resolvers.load_data
+
+resolvers.cachepath = nil -- public, for tracing
+resolvers.usecache = true -- public, for tracing
+
+function resolvers.save_data(dataname)
+ save_data(dataname, function(cachename,dataname)
+ resolvers.usecache = not toboolean(resolvers.expansion("CACHEINTDS") or "false",true)
+ if resolvers.usecache then
+ resolvers.cachepath = resolvers.cachepath or caches.definepath("trees")
+ return file.join(resolvers.cachepath(),caches.hashed(cachename))
+ else
+ return file.join(cachename,dataname)
+ end
+ end)
+end
+
+function resolvers.load_data(pathname,dataname,filename)
+ load_data(pathname,dataname,filename,function(dataname,filename)
+ resolvers.usecache = not toboolean(resolvers.expansion("CACHEINTDS") or "false",true)
+ if resolvers.usecache then
+ resolvers.cachepath = resolvers.cachepath or caches.definepath("trees")
+ return file.join(resolvers.cachepath(),caches.hashed(pathname))
+ else
+ if not filename or (filename == "") then
+ filename = dataname
+ end
+ return file.join(pathname,filename)
+ end
+ end)
+end
+
+-- we will make a better format, maybe something xml or just text or lua
+
+resolvers.automounted = resolvers.automounted or { }
+
+function resolvers.automount(usecache)
+ local mountpaths = resolvers.clean_path_list(resolvers.expansion('TEXMFMOUNT'))
+ if table.is_empty(mountpaths) and usecache then
+ mountpaths = { caches.setpath("mount") }
+ end
+ if not table.is_empty(mountpaths) then
+ statistics.starttiming(resolvers.instance)
+ for k, root in pairs(mountpaths) do
+ local f = io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if line:find("^[%%#%-]") then -- or %W
+ -- skip
+ elseif line:find("^zip://") then
+ if trace_locating then
+ logs.report("fileio","mounting %s",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
+ end
+ end
+ end
+ f:close()
+ end
+ end
+ statistics.stoptiming(resolvers.instance)
+ end
+end
+
+-- status info
+
+statistics.register("used config path", function() return caches.configpath() end)
+statistics.register("used cache path", function() return caches.temp() or "?" end)
+
+-- experiment (code will move)
+
+function statistics.save_fmt_status(texname,formatbanner,sourcefile) -- texname == formatname
+ local enginebanner = status.list().banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname = file.replacesuffix(texname,"luv")
+ local luvdata = {
+ enginebanner = enginebanner,
+ formatbanner = formatbanner,
+ sourcehash = md5.hex(io.loaddata(resolvers.find_file(sourcefile)) or "unknown"),
+ sourcefile = sourcefile,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ end
+end
+
+function statistics.check_fmt_status(texname)
+ local enginebanner = status.list().banner
+ if enginebanner and texname then
+ local luvname = file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv = dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
+ if luv.enginebanner and luv.enginebanner ~= enginebanner then
+ return "engine mismatch"
+ end
+ if luv.sourcehash and luv.sourcehash ~= sourcehash then
+ return "source mismatch"
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
+ end
+ end
+ return true
+end
diff --git a/tex/context/base/data-zip.lua b/tex/context/base/data-zip.lua
new file mode 100644
index 000000000..dcb6b170a
--- /dev/null
+++ b/tex/context/base/data-zip.lua
@@ -0,0 +1,241 @@
+if not modules then modules = { } end modules ['data-zip'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, find = string.format, string.find
+
+local trace_locating, trace_verbose = false, false
+
+trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+trackers.register("resolvers.locating", function(v) trace_locating = v trace_verbose = v end)
+
+zip = zip or { }
+zip.archives = zip.archives or { }
+zip.registeredfiles = zip.registeredfiles or { }
+
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
+local locators, hashers, concatinators = resolvers.locators, resolvers.hashers, resolvers.concatinators
+
+local archives = zip.archives
+
+-- zip:///oeps.zip?name=bla/bla.tex
+-- zip:///oeps.zip?tree=tex/texmf-local
+
+local function validzip(str) -- todo: use url splitter
+ if not find(str,"^zip://") then
+ return "zip:///" .. str
+ else
+ return str
+ end
+end
+
+function zip.openarchive(name)
+ if not name or name == "" then
+ return nil
+ else
+ local arch = archives[name]
+ if not arch then
+ local full = resolvers.find_file(name) or ""
+ arch = (full ~= "" and zip.open(full)) or false
+ archives[name] = arch
+ end
+ return arch
+ end
+end
+
+function zip.closearchive(name)
+ if not name or (name == "" and archives[name]) then
+ zip.close(archives[name])
+ archives[name] = nil
+ end
+end
+
+-- zip:///texmf.zip?tree=/tex/texmf
+-- zip:///texmf.zip?tree=/tex/texmf-local
+-- zip:///texmf-mine.zip?tree=/tex/texmf-projects
+
+function locators.zip(specification) -- where is this used? startup zips (untested)
+ specification = resolvers.splitmethod(specification)
+ local zipfile = specification.path
+ local zfile = zip.openarchive(name) -- tricky, could be in to be initialized tree
+ if trace_locating then
+ if zfile then
+ logs.report("fileio",'! zip locator, found: %s',specification.original)
+ else
+ logs.report("fileio",'? zip locator, not found: %s',specification.original)
+ end
+ end
+end
+
+function hashers.zip(tag,name)
+ if trace_verbose then
+ logs.report("fileio","loading zip file %s as %s",name,tag)
+ end
+ resolvers.usezipfile(format("%s?tree=%s",tag,name))
+end
+
+function concatinators.zip(tag,path,name)
+ if not path or path == "" then
+ return format('%s?name=%s',tag,name)
+ else
+ return format('%s?name=%s/%s',tag,path,name)
+ end
+end
+
+function resolvers.isreadable.zip(name)
+ return true
+end
+
+function finders.zip(specification,filetype)
+ specification = resolvers.splitmethod(specification)
+ if specification.path then
+ local q = url.query(specification.query)
+ if q.name then
+ local zfile = zip.openarchive(specification.path)
+ if zfile then
+ if trace_locating then
+ logs.report("fileio",'! zip finder, path: %s',specification.path)
+ end
+ local dfile = zfile:open(q.name)
+ if dfile then
+ dfile = zfile:close()
+ if trace_locating then
+ logs.report("fileio",'+ zip finder, name: %s',q.name)
+ end
+ return specification.original
+ end
+ elseif trace_locating then
+ logs.report("fileio",'? zip finder, path %s',specification.path)
+ end
+ end
+ end
+ if trace_locating then
+ logs.report("fileio",'- zip finder, name: %s',filename)
+ end
+ return unpack(finders.notfound)
+end
+
+function openers.zip(specification)
+ local zipspecification = resolvers.splitmethod(specification)
+ if zipspecification.path then
+ local q = url.query(zipspecification.query)
+ if q.name then
+ local zfile = zip.openarchive(zipspecification.path)
+ if zfile then
+ if trace_locating then
+ logs.report("fileio",'+ zip starter, path: %s',zipspecification.path)
+ end
+ local dfile = zfile:open(q.name)
+ if dfile then
+ logs.show_open(specification)
+ return openers.text_opener(specification,dfile,'zip')
+ end
+ elseif trace_locating then
+ logs.report("fileio",'- zip starter, path %s',zipspecification.path)
+ end
+ end
+ end
+ if trace_locating then
+ logs.report("fileio",'- zip opener, name: %s',filename)
+ end
+ return unpack(openers.notfound)
+end
+
+function loaders.zip(specification)
+ specification = resolvers.splitmethod(specification)
+ if specification.path then
+ local q = url.query(specification.query)
+ if q.name then
+ local zfile = zip.openarchive(specification.path)
+ if zfile then
+ if trace_locating then
+ logs.report("fileio",'+ zip starter, path: %s',specification.path)
+ end
+ local dfile = zfile:open(q.name)
+ if dfile then
+ logs.show_load(filename)
+ if trace_locating then
+ logs.report("fileio",'+ zip loader, name: %s',filename)
+ end
+ local s = dfile:read("*all")
+ dfile:close()
+ return true, s, #s
+ end
+ elseif trace_locating then
+ logs.report("fileio",'- zip starter, path: %s',specification.path)
+ end
+ end
+ end
+ if trace_locating then
+ logs.report("fileio",'- zip loader, name: %s',filename)
+ end
+ return unpack(openers.notfound)
+end
+
+-- zip:///somefile.zip
+-- zip:///somefile.zip?tree=texmf-local -> mount
+
+function resolvers.usezipfile(zipname)
+ zipname = validzip(zipname)
+ if trace_locating then
+ logs.report("fileio",'! zip use, file: %s',zipname)
+ end
+ local specification = resolvers.splitmethod(zipname)
+ local zipfile = specification.path
+ if zipfile and not zip.registeredfiles[zipname] then
+ local tree = url.query(specification.query).tree or ""
+ if trace_locating then
+ logs.report("fileio",'! zip register, file: %s',zipname)
+ end
+ local z = zip.openarchive(zipfile)
+ if z then
+ local instance = resolvers.instance
+ if trace_locating then
+ logs.report("fileio","= zipfile, registering: %s",zipname)
+ end
+ statistics.starttiming(instance)
+ resolvers.prepend_hash('zip',zipname,zipfile)
+ resolvers.extend_texmf_var(zipname) -- resets hashes too
+ zip.registeredfiles[zipname] = z
+ instance.files[zipname] = resolvers.register_zip_file(z,tree or "")
+ statistics.stoptiming(instance)
+ elseif trace_locating then
+ logs.report("fileio","? zipfile, unknown: %s",zipname)
+ end
+ elseif trace_locating then
+ logs.report("fileio",'! zip register, no file: %s',zipname)
+ end
+end
+
+function resolvers.register_zip_file(z,tree)
+ local files, filter = { }, ""
+ if tree == "" then
+ filter = "^(.+)/(.-)$"
+ else
+ filter = format("^%s/(.+)/(.-)$",tree)
+ end
+ if trace_locating then
+ logs.report("fileio",'= zip filter: %s',filter)
+ end
+ local register, n = resolvers.register_file, 0
+ for i in z:files() do
+ local path, name = i.filename:match(filter)
+ if path then
+ if name and name ~= '' then
+ register(files, name, path)
+ n = n + 1
+ else
+ -- directory
+ end
+ else
+ register(files, i.filename, '')
+ n = n + 1
+ end
+ end
+ logs.report("fileio",'= zip entries: %s',n)
+ return files
+end
diff --git a/tex/context/base/enco-cyr.tex b/tex/context/base/enco-cyr.tex
index 0ac82207f..36bca82b5 100644
--- a/tex/context/base/enco-cyr.tex
+++ b/tex/context/base/enco-cyr.tex
@@ -256,6 +256,8 @@
% \definecharacter textperthousand {\%\char 24 }
% \definecharacter textpertenthousand {\%\char 24\char 24 }
+\definecharacter cyrillicgheupturn 160 % to satisfy the patterns
+
\stopencoding
\startmapping[t2b]
diff --git a/tex/context/base/enco-def.tex b/tex/context/base/enco-def.tex
index c319c0065..a0631ac25 100644
--- a/tex/context/base/enco-def.tex
+++ b/tex/context/base/enco-def.tex
@@ -509,6 +509,7 @@
\definecharacter greekzeta {\zeta}
\definecharacter greeketa {\eta}
\definecharacter greektheta {\theta}
+\definecharacter greekthetaalt {\vartheta}
\definecharacter greekiota {\iota}
\definecharacter greekkappa {\kappa}
\definecharacter greeklambda {\lambda}
@@ -522,7 +523,8 @@
\definecharacter greeksigma {\sigma}
\definecharacter greektau {\tau}
\definecharacter greekupsilon {\upsilon}
-\definecharacter greekphi {\phi}
+\definecharacter greekphi {\varphi}
+\definecharacter greekphialt {\phi}
\definecharacter greekchi {\chi}
\definecharacter greekpsi {\psi}
\definecharacter greekomega {\omega}
@@ -893,7 +895,7 @@
\startencoding[\s!default]
-\definecharacter texthorizontalbar {{--\kern\zeropoint--}}
+\definecharacter texthorizontalbar {{\endash\kern\zeropoint\endash}}
\definecharacter textdong {\underbar{\dstroke}}
\stopencoding
diff --git a/tex/context/base/enco-fpl.tex b/tex/context/base/enco-fpl.tex
index ee9d98dc8..14d102ff1 100644
--- a/tex/context/base/enco-fpl.tex
+++ b/tex/context/base/enco-fpl.tex
@@ -21,7 +21,7 @@
\startlanguagespecifics[\s!pl]
- \appendtoks \makecharacteractive / \to \everynormalcatcodes
+% \appendtoks \makecharacteractive / \to \everynormalcatcodes % obsolete
\installcompoundcharacter /a {\aogonek}
\installcompoundcharacter /c {\cacute}
diff --git a/tex/context/base/enco-ini.mkii b/tex/context/base/enco-ini.mkii
index d39a64fca..9379c3a7f 100644
--- a/tex/context/base/enco-ini.mkii
+++ b/tex/context/base/enco-ini.mkii
@@ -1,34 +1,1137 @@
%D \module
%D [ file=enco-ini,
-%D version=2007.02.19,
+%D version=2007.02.19, % 2000.12.27, % 1998.12.03,
%D title=\CONTEXT\ Encoding Macros,
%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright=\PRAGMA]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%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 end we will cleanup enco-ini.tex!
+%D Quite some code will be moved to the mk files once we're ready
+%D for it.
+
+%D This module is a reimplementation of the module that handled
+%D composed characters and non \ASCII\ characters. The changed
+%D are not that fundamental, and mainly concerns moving
+%D definitions of specific glyphs and accents to other files as
+%D well as moving plain handling of accents to this module
+%D instead of overloading plain \TEX\ commands.
+
+%D Patterns are kind of mixed with font encodings and
+%D mappings. Alas.
+
+\ifx\synchronizepatterns\undefined \let\synchronizepatterns\relax \fi
+
+%D While dealing with input (the text source) and output (the
+%D glyphs), encoding comes into view. To summarize a few:
+%D
+%D \startitemize
+%D \item Bytes in the input file are mapped to an internal
+%D representation. An~\type {a} often stays an~\type {a},
+%D but~\type {\"e} can become either one code or become
+%D two codes (ending in overlapping glyphs).
+%D \item Characters can be made active and mapped onto another
+%D character.
+%D \item When changing case, characters are mapped onto
+%D themselves, their case||counterpart or a reasonable
+%D alternative, like~\"e onto~e.
+%D \item Single character representations in a \DVI\ file can
+%D be mapped onto one or more characters, either of not
+%D in more than one font file (virtual fonts).
+%D \item In the final format, fonts collections can be
+%D partially embedded, thereby losing the one||to||one
+%D relation between several instances of one font.
+%D \item For special purposes, individual characters should be
+%D mapped onto a dedicated encoding vector, for instance
+%D \PDF\ document encoding.
+%D \stopitemize
+%D
+%D These and other kind of mappings are to be dealt with, and
+%D the exact way of dealing often depends on the language to be
+%D typeset.
+
+\writestatus{loading}{ConTeXt Encoding Macros / Initialization}
\unprotect
-\beginOLDTEX
+%D First we define a few local or not yet initialized constants.
- \useencoding[ans,il2,ec,tbo,pdf,pol,qx,t5,cyr,agr] % pol and il2 will go away, not needed in mkiv, uc removed
+\def\@map@{@m@ap@} % mapping prefix
+\def\@fha@{@f@ha@} % font prefix
+\def\@cas@{@c@as@} % casecom prefix
- \useencoding[032,033,037] % fallbacks for some unicode chars
+\ifx\currentlanguage\undefined \let\currentlanguage\s!en \fi
- \setupencoding[\s!default=ec] % was: [\s!default=\s!default]
+%D \macros
+%D {setupencoding}
+%D
+%D The following setup command is used to tune encoding
+%D handling.
-\endOLDTEX
+\def\setupencoding
+ {\dosingleargument\dosetupencoding}
-\beginXETEX
+\def\dosetupencoding[#1]%
+ {\getparameters[\??ec][#1]%
+ \edef\defaultencoding
+ {\ifx\@@ecdefault\empty\s!default\else\@@ecdefault\fi}}
- \setupencoding[\s!default=\s!default]
+%D \macros
+%D {useencoding}
+%D
+%D Encodings things are defined in separate files and are
+%D loaded only once, using:
+%D
+%D \showsetup{useencoding}
+
+\def\douseencoding#1%
+ {\doifundefined{\c!file\f!encodingprefix#1}%
+ {\letvalue{\c!file\f!encodingprefix#1}\empty
+ \makeshortfilename[\truefilename{\f!encodingprefix#1}]%
+ \startreadingfile
+ \readsysfile\shortfilename
+ {\showmessage\m!encodings2{#1}}
+ {\showmessage\m!encodings3{#1}}%
+ \stopreadingfile}}
+
+\def\useencoding[#1]%
+ {\processcommalist[#1]\douseencoding}
+
+%D \macros
+%D {startmapping,enablemapping}
+%D
+%D In order to process patterns, convert from lower to
+%D uppercase and vise versa and some more, we provide a
+%D mechanism to define mappings. The first real application
+%D of this command was:
+%D
+%D \starttyping
+%D \startmapping [something]
+%D \definecasemap 165 181 165
+%D \definecasemap 171 187 171
+%D ...
+%D \defineuppercasecom \i {I}
+%D \defineuppercasecom \l \L
+%D \definelowercasecom \AE \ae
+%D ...
+%D \stopmapping
+%D \stoptyping
+%D
+%D So, character 165 becomes 181 in uppercase and 165 in
+%D lowercase. A mapping is activated with \type {\enablemapping}.
+
+\def\startsavingmappingtoks#1%
+ {\bgroup
+ \edef\charactermapping{@#1@}%
+ \checkmappingtoks
+ \setmappingtoks
+ \the\mappingtoks}
+
+\def\stopsavingmappingtoks
+ {\global\mappingtoks\emptytoks
+ \dostepwiserecurse{0}{255}\plusone
+ {\edef\@@expanded
+ {\the\mappingtoks
+ \ifnum\recurselevel>127
+ \noexpand\settoletterunlessactive{\recurselevel}%
+ \fi
+ \lccode\recurselevel\ifnum\lccode\recurselevel=\zerocount\zerocount\else\space\the\lccode\recurselevel\space\fi
+ \uccode\recurselevel\ifnum\uccode\recurselevel=\zerocount\zerocount\else\space\the\uccode\recurselevel\space\fi
+ \ifnum\sfcode\recurselevel=\plusthousand\else\sfcode\recurselevel=\the\sfcode\recurselevel\space\fi
+ }%
+ \global\mappingtoks\expandafter{\@@expanded}}%
+ \egroup
+ \let\enabledmapping\empty
+ \enablemapping[\currentmapping]}
+
+\def\startmapping[#1]%
+ {\startsavingmappingtoks{#1}}
+
+\def\stopmapping
+ {\stopsavingmappingtoks}
+
+\def\optimizemapping[#1]%
+ {\startsavingmappingtoks{#1}%
+ % nothing, just an automatic cleanup
+ \stopsavingmappingtoks
+ % we need to resync
+ %\let\enabledmapping\relax
+ }%\enablemapping[\currentmapping]}
+
+\def\setmappingtoks
+ {\@EA\let\@EA\mappingtoks\csname\@map@\charactermapping\endcsname
+ \@EA\let\@EA\casecomtoks\csname\@cas@\charactermapping\endcsname}
+
+\def\checkmappingtoks
+ {\ifundefined{\@map@\charactermapping}%
+ \expandafter\newtoks\csname\@map@\charactermapping\endcsname
+ \fi
+ \ifundefined{\@cas@\charactermapping}%
+ \expandafter\newtoks\csname\@cas@\charactermapping\endcsname
+ \fi}
+
+\def\definecasemap #1 #2 #3 % code lower upper
+ {\doifelse{#2}{to}
+ {\presetcaserange{#1}{#3}}
+ {\lccode#1=#2\relax
+ \uccode#1=#3\relax}%
+ \ignorespaces}
+
+%D Saves a few tokens
+
+\def\definecaseswap #1 #2 % lower upper
+ {\lccode#1=#1\relax
+ \uccode#2=#2\relax
+ \lccode#2=#1\relax
+ \uccode#1=#2\relax
+ \ignorespaces}
+
+\def\definecaseself #1 % lower=upper=self
+ {\lccode#1=#1\relax
+ \uccode#1=#1\relax
+ \ignorespaces}
+
+%D Watch the \type {\definecasemap 127 to 255} option!
+%D Dedicated to Taco there is also:
+
+\def\definecasemaps #1 to #2 lc #3 uc #4 % from to lc+ uc+
+ {\dostepwiserecurse{#1}{#2}\plusone
+ {\scratchcounter\recurselevel\advance\scratchcounter#3\lccode\recurselevel=\scratchcounter
+ \scratchcounter\recurselevel\advance\scratchcounter#4\uccode\recurselevel=\scratchcounter}%
+ \ignorespaces}
+
+%D This can be used like:
+%D
+%D \starttyping
+%D \definecasemaps 128 to 156 lc 32 uc 0
+%D \definecasemaps 160 to 188 lc -32 uc 0
+%D \definecasemaps 160 to 188 lc -32 uc 0
+%D \definecasemaps 192 to 255 lc 32 uc 0
+%D \stoptyping
+%D
+%D and saves a lot of typing (copying).
+
+\def\resetcaserange #1 to #2
+ {\dostepwiserecurse{#1}{#2}\plusone
+ {\lccode\recurselevel\zerocount
+ \uccode\recurselevel\zerocount}%
+ \ignorespaces}
+
+\def\presetcaserange#1#2% could be pre-expanded
+ {\dostepwiserecurse{#1}{#2}\plusone
+ {\lccode\recurselevel=\recurselevel
+ \uccode\recurselevel=\recurselevel}%
+ \ignorespaces}
+
+\def\setcasemap #1 #2 #3 %
+ {\settoletterunlessactive{#1}%
+ \lccode #1=#2
+ \uccode #1=#3 }
+
+\def\setcaseswap #1 #2 %
+ {\settoletterunlessactive{#1}%
+ \settoletterunlessactive{#2}%
+ \lccode #1=#1
+ \uccode #2=#2
+ \lccode #2=#1
+ \uccode #1=#2 }
+
+\def\setcaseself #1 %
+ {\settoletterunlessactive{#1}%
+ \lccode #1=#1
+ \uccode #1=#1 }
+
+\def\definespacemap #1 #2 % code sfcode
+ {\sfcode#1=#2%
+ \ignorespaces}
+
+\def\setspacemap #1 #2 %
+ {\settootherunlessactive{#1}%
+ %\lccode #1=\zerocount
+ %\uccode #1=\zerocount
+ \sfcode #1=#2 }
+
+\def\defineuppercasecom#1#2%
+ {\global\casecomtoks\expandafter{\the\casecomtoks\setuppercasecom#1{#2}}%
+ \ignorespaces}
+
+\def\definelowercasecom#1#2%
+ {\global\casecomtoks\expandafter{\the\casecomtoks\setlowercasecom#1{#2}}%
+ \ignorespaces}
+
+\let\setuppercasecom\gobbletwoarguments
+\let\setlowercasecom\gobbletwoarguments
+
+\def\setcasecom#1#2{\def#1{#2}}
+
+\let\enabledmapping\empty % indirect, needed to handle default too
+
+\def\enablemapping[#1]%
+ {\edef\charactermapping{@#1@}%
+ \ifx\enabledmapping\charactermapping \else
+ \doifdefined{\@map@\charactermapping}
+ {%\expandafter\showthe\csname\@map@\charactermapping\endcsname\endcsname
+ \the\csname\@map@\charactermapping\endcsname}%
+ % == \the\executeifdefined{\@map@\charactermapping}\emptytoks
+ \edef\enabledmapping{\charactermapping}%
+ \enablelanguagespecifics[\currentlanguage]% new
+ % \edef\enabledmapping{\charactermapping\currentlanguage}% can be comma list
+ \fi
+ \synchronizepatterns}
+
+% on behalf of font switching:
+
+\def\fastenablemapping#1%
+ {\edef\charactermapping{@#1@}%
+ \ifx\enabledmapping\charactermapping \else
+ \@EA\ifx\csname\@map@\charactermapping\endcsname\relax\else
+ \the\csname\@map@\charactermapping\endcsname
+ \fi
+ % == \the\executeifdefined{\@map@\charactermapping}\emptytoks
+ \let\enabledmapping\charactermapping
+ \enablelanguagespecifics[\currentlanguage]% to faster
+ \fi}
+
+%D This macro wil be implemented in \type {lang-ini.tex}.
+
+\ifx\enablelanguagespecifics\undefined
+ \def\enablelanguagespecifics[#1]{}
+\fi
+
+%D Further on we have to take some precautions when dealing
+%D with special characters like~\type{~}, \type{_}
+%D and~\type{^}, so let us define ourselve some handy macros
+%D first.
+
+\def\protectfontcharacters
+ {\edef\unprotectfontcharacters
+ {\catcode`\noexpand ~=\the\catcode`~\relax
+ \catcode`\noexpand _=\the\catcode`_\relax
+ \catcode`\noexpand ^=\the\catcode`^\relax}%
+ \catcode`~=\@@letter
+ \catcode`_=\@@letter
+ \catcode`^=\@@letter\relax}
+
+%D The completeness of the Computer Modern Roman typefaces
+%D makes clear how incomplete other faces are. To honour 7~bit
+%D \ASCII, these fonts were designed using only the first 127
+%D values of the 256 ones that can be presented by one byte.
+%D Nowadays 8~bit character codings are more common, mainly
+%D because they permit us to predefine some composed
+%D characters, which are needed in most european languages.
+%D
+%D Supporting more than the standard \TEX\ encoding vector
+%D |<|which in itself is far from standard and differs per
+%D font|>| puts a burden on the fonts mechanism. The \CONTEXT\
+%D mechanism is far from complete, but can handle several
+%D schemes at once. The main problem lays in the accented
+%D characters and ligatures like~ff, although handling
+%D ligatures is not the responsibility of this module.
+%D
+%D By default, we use \PLAIN\ \TEX's approach of placing
+%D accents. All other schemes sooner or later give problems
+%D when we distribute \DVI||files are distributed across
+%D machines and platforms. Nevertheless, we have to take care
+%D of different encoding vectors, which tell us where to find
+%D the characters we need. This means that all kind of
+%D character placement macro's like \type{\"} and \type{\ae}
+%D have to be implemented and adapted in a way that suits
+%D these vectors.
+%D
+%D The main difference between different vector is the way
+%D accents are ordered and/or the availability of prebuilt
+%D accented characters. Accented characters can for instance be
+%D called for by sequences like \type{\"e}. Here the \type{\"}
+%D is defined as:
+%D
+%D \starttyping
+%D \def\"#1{{\accent"7F #1}}
+%D \stoptyping
+%D
+%D This macro places the accent \accent"7F {} on top of an~e
+%D gives \"e. Some fonts however can have prebuild accents and
+%D use a more direct approach like
+%D
+%D \starttyping
+%D \def\"#1{\if#1e\char 235\else ... \fi}
+%D \stoptyping
+%D
+%D The latter approach is not used in \CONTEXT, because we
+%D store relevant combinations of accents and characters in
+%D individual macros.
+
+%D We define character substitutes and commands with definition
+%D commands like:
+%D
+%D \starttyping
+%D \startcoding[texnansi]
+%D
+%D \defineaccent " a 228
+%D \defineaccent ^ e 234
+%D \defineaccent ' {\dotlessi} 237
+%D
+%D \definecharacter ae 230
+%D \definecharacter oe 156
+%D
+%D \definecommand b \texnansiencodedb
+%D \definecommand c \texnansiencodedc
+%D
+%D \stopcoding
+%D \stoptyping
+%D
+%D The last argument of \type{\defineaccent} and
+%D \type{\definecharacter} tells \TEX\ the position of the
+%D accented character in the encoding vector. In order to
+%D complish this, we tag each implementation with the character
+%D coding identifier. We therefore need two auxiliary variables
+%D \type{\characterencoding} and \type{\nocharacterencoding}. These
+%D contain the current and default encoding vectors and both
+%D default to the \PLAIN\ one.
+
+\edef\characterencoding {@\s!default @}
+\edef\nocharacterencoding {@\s!default @}
+\edef\charactermapping {@\s!default @}
+
+% todo, else \d j == \dj, print file and check
+
+\def\accentprefix {}%{*}
+\def\commandprefix {}%{=}
+\def\characterprefix{}%{-}
+
+%D \macros
+%D {startcoding, reducetocoding}
+%D
+%D Before we can redefine accents and special characters, we
+%D have to tell \CONTEXT\ what encoding is in force. The next
+%D command is responsible for doing this and also takes care of
+%D the definition of the recoding commands. We use the \type
+%D {\start}||\type {\stop}||commands for definitions and the
+%D \type {\reduceto}||command for local switching to
+%D simplified commands.
+
+% etex : \ifcsname
+
+\def\justhandleaccent#1#2% \empty makes #2={} save % no \unexpanded
+ {\ifundefined{\accentprefix\characterencoding#1\string#2\empty}%
+ #2%
+ \else
+ \csname\accentprefix\characterencoding#1\string#2\empty\endcsname
+ \fi}
+
+\def\justhandlecommand#1% % no \unexpanded, otherwise pdfdoc will fail
+ {\ifundefined{\commandprefix\characterencoding#1}% as well as hyph patterns
+ #1%
+ \else
+ \csname\commandprefix\characterencoding#1\endcsname
+ \fi}
+
+\def\enableencoding
+ {\dodoubleempty\doenableencoding}
+
+\def\doenableencoding[#1][#2]% main fallback
+ {\iffirstargument\edef\characterencoding{@#1@}\fi
+ \edef\nocharacterencoding{@\ifsecondargument#2\else\s!default\fi @}%
+ \synchronizepatterns}
+
+\edef\xnocharacterencoding{@\s!default @}
+
+\def\fastenableencoding#1%
+ {\edef\characterencoding{@#1@}%
+ \let\nocharacterencoding\xnocharacterencoding}
+
+\def\startencoding
+ {\dodoubleempty\dostartencoding}
+
+\def\dostartencoding[#1][#2]% encoding regime
+ {%\showmessage\m!encodings1{#1}%
+ \pushmacro\characterencoding
+ \pushmacro\currentregime
+ \pushmacro\dohandleaccent % still needed?
+ \pushmacro\dohandlecommand % still needed?
+ \pushmacro\doautosetregime
+ \let\dohandleaccent\donthandleaccent % still needed?
+ \let\dohandlecommand\donthandlecommand % still needed?
+ %let\definesortkey\savesortkey
+ \edef\characterencoding{@#1@}%
+ \doifelsenothing{#2}%
+ {\let\doautosetregime\gobbletwoarguments}
+ {\def\currentregime{#2}}}
+
+\def\stopencoding
+ {\popmacro\doautosetregime
+ \popmacro\dohandlecommand % still needed?
+ \popmacro\dohandleaccent % still needed?
+ \popmacro\currentregime
+ \popmacro\characterencoding}
+
+% probably obsolete (hm, not yet)
+
+\def\reducetocoding[#1]% use grouped!
+ {\doifsomething{#1}
+ {\let\dohandleaccent \justhandleaccent
+ \let\dohandlecommand\justhandlecommand
+ \enableencoding[#1]%
+ \enablelanguagespecifics[\currentlanguage]}}
+
+\let\startcoding \startencoding
+\def\stopcoding {\stopencoding}
+\let\enablecoding \enableencoding
+
+%D The use of these macros are not limited to font
+%D definition files, but may also be used when loading
+%D patterns.
+
+%D \macros
+%D {definesortkey,flushsortkeys,flushsortkey}
+%D
+%D Yet another definition concerns sorting of indexes and
+%D lists.
+%D
+%D \starttyping
+%D \definesortkey {\'e} {e} {a} {\'e}
+%D \stoptyping
+%D
+%D The first argument denotes the string to be treated. The
+%D second argument is the raw replacement, while the third
+%D argument determines the sort order given the replacement.
+%D The last argument is used as entry in the index (a, b, etc).
+%D
+%D The keys can be flushed using \type {\flushsortkeys}
+%D which in turn results in a sequence of calls to \type
+%D {\flushsortkey}, a macro taking 4~arguments.
+%D
+%D This mechanism is currently being tested and subjected to
+%D changes! Obsolete:
+
+\let\definesortkey\gobblefourarguments
+\let\savesortkey \gobblefourarguments
+\let\flushsortkeys\relax
+\let\flushsortkey \relax
+
+%D \macros
+%D {defineaccent, definecharacter, definecommand}
+%D
+%D The actual definition of accents, special characters and
+%D commands is done with the next three commands.
+
+\def\defineaccent
+ {\protectfontcharacters
+ \dodefineaccent}
+
+\def\dodefineaccent#1 #2 %
+ {\unprotectfontcharacters
+ \dododefineaccent#1 #2 }
+
+\def\dododefineaccent#1 #2 #3 %
+ {\setvalue{#1}{\dohandleaccent{#1}}%
+ \doifnumberelse{\string#3}
+ {\setvalue{\accentprefix\characterencoding#1\string#2}{\char#3 }} % space added
+ {\setvalue{\accentprefix\characterencoding#1\string#2}{#3}}}
+
+\def\dohandleaccent#1#2%
+ {\ifcsname\accentprefix\characterencoding#1\string#2\empty\endcsname
+ \csname\accentprefix\characterencoding#1\string#2\empty\endcsname
+ \else\ifcsname\accentprefix\nocharacterencoding#1\string#2\empty\endcsname
+ \csname\accentprefix\nocharacterencoding#1\string#2\empty\endcsname
+ \else\ifcsname\accentprefix\characterencoding#1\endcsname
+ \csname\accentprefix\characterencoding#1\endcsname{#2}%
+ \else%\ifcsname\accentprefix\nocharacterencoding#1\endcsname
+ \csname\accentprefix\nocharacterencoding#1\endcsname{#2}%
+% \else
+% \donormaltextaccent{#1}{#2}%
+ \fi\fi\fi}%\fi}
+
+\def\patternchar#1 {\rawcharacter{#1}} % space is part of character definition !
+
+% \ifx \enablepatterntokens\undefined
+% \def\handlepatterntoken#1]{\csname#1\endcsname}
+% \fi
+
+% we need to postpone catcode changes, e.g. hr patterns
+% have \catcode" -> which fails when " is letter
+
+\def\pathypsettings
+ {\ifx \enablepatterntokens\undefined
+ \defineactivecharacter [ {\handlepatterntoken}%
+ \else
+ \enablepatterntokens
+ \fi
+ \let\dochar\thechr
+ \lccode16=16 % brrr, extra quote in ec (turkish)
+ \lccode17=17 % brrr, extra quote in ec (turkish)
+ \lccode`\-=`\-
+ \lccode`\'=`\'
+ \lccode`\"=`\"
+ \relax}
+
+\def\patterns {\pathypsettings\normalpatterns }
+\def\hyphenation{\pathypsettings\normalhyphenation}
+
+%D Because we don't want to use the second command grouped, we
+%D (re)define it as follows:
+
+\def\hyphenation
+ {\begingroup\def\hyphenation{\normalhyphenation{\the\scratchtoks}\endgroup}%
+ \pathypsettings\afterassignment\hyphenation\scratchtoks=}
+
+%D This is not needed for patterns because they are loaded grouped
+%D anyway and it saves us an assignment. Can go ... no longer
+%D shared patterns.
+
+\def\startpatternloading#1#2#3% % we should use \everypatternloading
+ {\startreadingfile
+ \bgroup
+ % let's get rid of interfering stuff
+ \let\everyjob\scratchtoks
+ \let\message \gobbleoneargument
+ % we want direct characters
+ \let\char\patternchar
+ \doifelsenothing{#2}{\enableencoding[ec]}{\enableencoding[#2]}%
+ \doifelsenothing{#3}{\enablemapping [ec]}{\enablemapping [#3]}%
+ \expanded{\doifinstring{\f!languageprefix}{#1}}
+ {\ifx \enablepatternxml\undefined \else
+ \enablepatternxml
+ \fi}%
+ \let\dohandleaccent\normaldohandleaccent}
+
+\def\stoppatternloading
+ {\egroup
+ \stopreadingfile}
+
+ \def\thechr#1{\char#1 } % just in case \relax interferes
+\unexpanded\def\numchr#1{\char#1\relax}
+\unexpanded\def\strchr#1{\csname#1\endcsname}
+
+\let\dochar\numchr
+
+\def\startdirectcharacters {\pushmacro\dochar \let\dochar\thechr}
+\def\stopdirectcharacters {\popmacro \dochar}
+
+\def\definecharacter#1 #2 %
+ {\ifundefined{#1}\setvalue{#1}{\dohandlecharacter{#1}}\fi
+ \doifnumberelse{\string#2}
+ {\setvalue{\characterprefix\characterencoding\string#1}{\dochar{#2}}%
+ \doautosetregime{#1}{#2}}
+ {\setvalue{\characterprefix\characterencoding\string#1}{#2}}}
+
+\def\dohandlecharacter#1%
+ {\csname\characterprefix\ifcsname\characterprefix\characterencoding#1\endcsname
+ \characterencoding\else\nocharacterencoding\fi#1\endcsname}
+
+% \def\fallbackpatternchar{x} % makes no sense, duplicate patterns
+
+\def\defaultcharacter#1%
+ {\csname\characterprefix\nocharacterencoding\strippedcsname#1\endcsname}
+
+%D Instead of numbers, a command may be entered.
+
+\def\definecommand#1 #2 %
+ {\setvalue{\string#1}{\dohandlecommand{#1}}%
+ %\redefinecommand #1 % just to be sure
+ \setvalue{\commandprefix\characterencoding\string#1}{#2}}
+
+%D Here we see that redefining accents is characters is more
+%D or less the same as redefining commands. We also could have
+%D said:
+%D
+%D \starttyping
+%D \def\defineaccent#1 #2 {\definecommand#1\string#2 \char}
+%D \def\definecharacter#1 {\definecommand#1 \char}
+%D \stoptyping
+
+%D \macros
+%D {defineaccentcommand}
+%D
+%D When needed, one can overload the default positions of the
+%D accents. The \PLAIN\ \TEX\ defaults are:
+%D
+%D \starttyping
+%D \defineaccentcommand ` 18
+%D \defineaccentcommand ' 19
+%D \defineaccentcommand v 20
+%D \defineaccentcommand u 21
+%D \defineaccentcommand = 22
+%D \defineaccentcommand ^ 94
+%D \defineaccentcommand . 95
+%D \defineaccentcommand H 125 % "7D
+%D \defineaccentcommand ~ 126 % "7E
+%D \defineaccentcommand " 127 % "7F
+%D \stoptyping
-\endXETEX
+\def\defineaccentcommand
+ {\protectfontcharacters
+ \dodefineaccentcommand}
+
+\def\dodefineaccentcommand#1 #2 % \string toegevoegd
+ {\doifnumberelse{\string#2}
+ {\setvalue{\accentprefix\characterencoding\string#1}##1{{\accent#2 ##1}}}
+ {\setvalue{\accentprefix\characterencoding\string#1}##1{{#2##1}}}%
+ \unprotectfontcharacters}
+
+%D We don't have to define them for the default \PLAIN\ case.
+%D Commands may be used instead of character codes.
+
+%D \macros
+%D {redefinecommand}
+%D
+%D Redefinition of encoding dependant commands like \type{\b}
+%D and \type{\c} can be triggered by:
+%D
+%D \starttyping
+%D \redefinecommand b % something math
+%D \redefinecommand c % something math
+%D \stoptyping
+%D
+%D Handling of characters is easier than handling accents
+%D because here we don't have to take care of arguments. We
+%D just call for the right glyph in the right place.
+%D
+%D The \type{\next} construction permits handling of commands
+%D that take arguments. This means that we can use this
+%D command to redefine accent handling commands too
+%D (although today the next is not needed any longer in test
+%D macros).
+
+\def\redefinecommand#1 %
+ {% no \unexpanded, else pdfdoc fails
+ \setvalue{\string#1}{\dohandlecommand{#1}}}%
+
+\def\dohandlecommand#1%
+ {\csname\commandprefix
+ \ifcsname\commandprefix\characterencoding#1\endcsname
+ \characterencoding
+ \else
+ \nocharacterencoding
+ \fi
+ #1\endcsname}
+
+%D \macros
+%D {currentencoding, currentmapping}
+%D
+%D When we show 'm, we don't want to see the protection
+%D measures.
+
+\def\currentencoding{\@EA\dopureencodingname\characterencoding}
+\def\currentmapping {\@EA\dopureencodingname\charactermapping }
+
+\def\dopureencodingname @#1@{#1}
+
+\def\pureencodingname#1{\@EA\dopureencodingname#1}
+
+%D \macros
+%D {showaccents, showcharacters,
+%D showcharacterbounds, showhyphenations}
+%D
+%D Encoding is a tricky business. Therefore we provide a
+%D a few macros that show most of the characters involved. The
+%D next two tables show the result of \type {\showaccents}.
+%D
+%D \placetable
+%D {The special glyphs in default encoding.}
+%D {\showaccents}
+%D
+%D \placetable
+%D {The special glyphs in texnansi encoding.}
+%D {\switchtobodyfont[lbr]\showaccents}
+%D
+%D The command
+%D
+%D \starttyping
+%D \showhyphenations{doordefini\"eren}
+%D \stoptyping
+%D
+%D can be used to check the correct loading of hyphenation
+%D patterns.
+
+\fetchruntimecommand \showaccents {\f!encodingprefix\s!run}
+\fetchruntimecommand \showcharacters {\f!encodingprefix\s!run}
+\fetchruntimecommand \showcharacterbounds {\f!encodingprefix\s!run}
+\fetchruntimecommand \showhyphenations {\f!encodingprefix\s!run}
+\fetchruntimecommand \showmapping {\f!encodingprefix\s!run}
+
+%D \macros
+%D {everyuppercase, EveryUppercase,
+%D everyuppercase, EveryUppercase}
+%D
+%D When we want to uppercase strings of characters, we have to
+%D take care of those characters that have a special meaning or
+%D are only accessible by means of macros. The next hack was
+%D introduced when Tobias Burnus started translating head and
+%D label texts into spanish and italian. The first application
+%D of this token register therefore can be found in the module
+%D that deals with these texts.
+
+\newevery \everyuppercase \EveryUppercase
+\newevery \everylowercase \EveryLowercase
+
+%D This magic trick maps takes care of mapping from lower to
+%D upper case and reverse.
+
+\def\reloadmapping{\the\executeifdefined{\@cas@\charactermapping}\emptytoks}
+
+\appendtoks\let\setuppercasecom\setcasecom\to\everyuppercase
+\appendtoks\let\setlowercasecom\setcasecom\to\everylowercase
+
+\appendtoks\reloadmapping\to\everyuppercase % slow, will be sped up
+\appendtoks\reloadmapping\to\everylowercase % slow, will be sped up
+
+\newtoks\everyULmap
+
+\appendtoks\let\remapcase\remapuppercase\the\everyULmap\to\everyuppercase
+\appendtoks\let\remapcase\remaplowercase\the\everyULmap\to\everylowercase
+
+\let\remapcase\gobbletwoarguments
+
+\def\remapuppercase#1#2{\let#2#1} % more efficient:
+\def\remaplowercase#1#2{\let#1#2} \let\remaplowercase\let
+
+\def\defineLCcharacter #1 #2 %
+ {\appendtoks\let\to\everylowercase
+ \@EA\appendtoks\csname#1\endcsname\to\everylowercase
+ \@EA\appendtoks\csname#2\endcsname\to\everylowercase}
+
+\def\defineUCcharacter #1 #2 %
+ {\appendtoks\let\to\everyuppercase
+ \@EA\appendtoks\csname#1\endcsname\to\everyuppercase
+ \@EA\appendtoks\csname#2\endcsname\to\everyuppercase}
+
+\def\defineULcharacter #1 #2 %
+ {\appendtoks\remapcase\to\everyULmap
+ \@EA\appendtoks\csname#1\endcsname\to\everyULmap
+ \@EA\appendtoks\csname#2\endcsname\to\everyULmap}
+
+% slightly faster with \smallcapped's but far more hash and stringspace
+%
+% \newif\ifuppercase \appendtoks\uppercasetrue\to\everyuppercase
+% \newif\iflowercase \appendtoks\lowercasetrue\to\everylowercase
+%
+% \def\defineULcharacter #1 #2 %
+% {\def\!!stringa{@#1}\@EA\letvalue\@EA\!!stringa\csname#1\endcsname
+% \def\!!stringa{@#2}\@EA\letvalue\@EA\!!stringa\csname#2\endcsname
+% \setvalue{#1}{\getvalue{@\ifuppercase#2\else#1\fi}}%
+% \setvalue{#2}{\getvalue{@\iflowercase#1\else#2\fi}}}
+
+% 2 = tricky, since expanding \definedfont[lowcasename] ... goes wrong
+
+\chardef\uppercasemode\plusthree % 0=ignore 1=normal 2=expand 3=auto
+\chardef\casecommode \plusone % 0=noexpand 1=expand
+
+\def\setcasecom #1#2{\def#1{\ifcase\casecommode\noexpand#1\else#2\fi}}
+
+% \def\OEPS{whatever}
+%
+% \startmapping[ec]
+% \defineuppercasecom \oeps {\getvalue{OEPS}}
+% \stopmapping
+%
+% \WORD{xx \oeps}
+
+\def\douppercase#1%
+ {\bgroup
+ \let\douppercase\firstofoneargument
+ \the\everyuppercase % currently also checks uppercasemode
+ \let\dochar\rawcharacter
+ \ifcase\uppercasemode
+ #1%
+ \or % No expansion here, otherwise \getvalue problems! Default!!!
+ %\edef\next{#1}% keep this to prevent roll back
+ %\uppercase\expandafter{\next}% keep this to prevent roll back
+ \uppercase{#1}%
+ \or
+ \chardef\casecommode\zerocount
+ \let\docasecom\firstoftwoarguments
+ \edef\ascii{#1}%
+ \edef\ascii{\expandafter\uppercase\expandafter{\ascii}}% needed when in regime
+ \chardef\casecommode\plusone
+ \ascii
+ \else
+ % mode three may trigger setting 2 elsewhere (e.g. regime test)
+ \uppercase{#1}%
+ \fi
+ \egroup}
+
+\prependtoksonce
+ \doifnot\currentregime\s!default
+ {\ifnum\uppercasemode=\plusthree \chardef\uppercasemode\plustwo \fi}%
+\to \everyuppercase
+
+%D \macros
+%D {everysanitize, EverySanitize}
+%D
+%D Whenever we are sanitizing strings, like we sometimes do
+%D when we deal with specials, the next token register can be
+%D called.
+
+\newevery \everysanitize \EverySanitize
+
+%D \macros
+%D {defineuclass,defineudigit,udigit}
+%D
+%D The next few macros are experimental and needed for unicoded
+%D chinese characters.
+
+\def\defineuclass #1 #2 #3 %
+ {\setvalue{uc\the\numexpr#2*256+#3\relax}{#1}}
+
+\def\defineudigit #1 #2 #3 {\setvalue{\characterencoding uc#1}{\uchar{#2}{#3}}}
+
+%D It may look strange, but for the moment, we want the encoding
+%D to be part of the digit specification. This may change!
+
+\unexpanded\def\udigit#1#2{\getvalue{@#1@uc\number#2}}
+
+%D \macros
+%D {uchar, octuchar, hexuchar}
+
+\ifx\uchar\undefined \def\uchar#1#2{(\number#1,\number#2)} \fi
+
+\def\octuchar#1#2{\uchar{`#1}{`#2}}
+\def\hexuchar#1#2{\uchar{"#1}{"#2}}
+
+%D Basics and fallbacks.
+
+\newif\ifignoreaccent
+
+\let\textaccent \accent
+\let\normaltextaccent\textaccent
+
+% ** we will explicitly embrace the two arguments, since in definitions
+% this may not be the case, and we don't want faulty expansions like
+% "\dobuildtextaccent \char 18 a" but "\dobuildtextaccent {\char 18}{a}"
+% instead
+
+\def\buildmathaccent#1%
+ {\mathaccent#1 }
+
+\def\buildtextaccent#1#2% **
+ {\ifignoreaccent
+ \expandafter\nobuildtextaccent
+ \else
+ \expandafter\dobuildtextaccent
+ \fi{#1}{#2}}
+
+\unexpanded\def\nobuildtextaccent#1#2%
+ {#2}
+
+\unexpanded\def\dobuildtextaccent#1#2%
+ {{\let\char\normalaccent#1\let\char\normalchar#2}}
+
+% some fake ones, name will change into build
+
+\unexpanded\def\bottomaccent#1#2#3#4#5% down right slantcorrection accent char
+ {\dontleavehmode % why this align mess
+ \vtop
+ {\forgetall
+ \baselineskip\zeropoint
+ \lineskip#1%
+ \everycr\emptytoks
+ \tabskip\zeropoint
+ \lineskiplimit\zeropoint
+ \setbox0\hbox{#4}%
+ \halign
+ {##\crcr\hbox{#5}\crcr
+ \hidewidth
+ \hskip#2\wd0
+ \hskip-#3\slantperpoint % in plain 1ex * dimenless value
+ \vbox to .2ex{\box0\vss}\hidewidth
+ \crcr}}}
+
+\def\buildtextmacron {\bottomaccent{.25ex}{0}{15}{\textmacron}}
+\def\buildtextbottomdot{\bottomaccent{.25ex}{0}{5}{\textbottomdot}}
+\def\buildtextcedilla {\bottomaccent{0ex}{0}{5}{\textcedilla}}
+\def\buildtextogonek {\bottomaccent{-.1ex}{.5}{0}{\textogonek}}
+
+%D A collectors item:
+
+\def\buildtextbottomcomma{\bottomaccent{.15ex}{0}{5}{\tx,}}
+
+%D Rarely needed but there:
+
+\unexpanded\def\topaccent#1#2#3#4#5% down right slantcorrection accent char
+ {\dontleavehmode
+ \bgroup
+ \setbox0\hbox{#4}%
+ \setbox2\hbox{#5}%
+ \hbox to \wd2 \bgroup
+ \hss\copy2\hss
+ \hskip-\wd2
+ \hss\hskip#2\wd0\hskip-#3\slantperpoint\raise#1\hbox{#4}\hss
+ \egroup
+ \egroup}
+
+\def\buildtextgrave{\topaccent{0pt}{0}{15}{\textgrave}} % e.g.
+
+% \definecharacter schwa {\hbox{\rotate[rotation=180,location=high]{\hbox{e}}}}
+% \definecharacter schwagrave {\buildtextgrave\schwa}
+
+% math stuff, will change
+
+\def\definemathaccent#1 #2%
+ {\setvalue{\string#1}{#2}%
+ \setvalue{normalmathaccent\string#1}{#2}}
+
+\def\donormalmathaccent#1%
+ {\getvalue{normalmathaccent\string#1}}
+
+%D Some precautions:
+
+\ifx\usepdffontresource\undefined
+ \def\usepdffontresource #1 {} % this will be defined elsewhere
+\fi
+
+\def\donthandleaccent #1{\expandafter\string\csname#1\endcsname\space}
+\def\donthandlecommand #1{\expandafter\string\csname#1\endcsname\space}
+\def\donthandlecharacter #1{\expandafter\string\csname#1\endcsname\space}
+
+\def\stringifyhandleaccent #1{\strchr{#1}}
+\def\stringifyhandlecommand #1{\strchr{#1}}
+\def\stringifyhandlecharacter#1{\strchr{#1}}
+
+\def\keephandleaccent #1{\expandafter\noexpand\csname#1\endcsname}
+\def\keephandlecommand #1{\expandafter\noexpand\csname#1\endcsname}
+\def\keephandlecharacter #1{\expandafter\noexpand\csname#1\endcsname}
+
+\def\handleaccent #1{\csname#1\endcsname}
+\def\handlecommand #1{\csname#1\endcsname}
+\def\handlecharacter #1{\csname#1\endcsname}
+
+\def\dontexpandencoding
+ {\let\dohandleaccent \donthandleaccent
+ \let\dohandlecommand \donthandlecommand
+ \let\dohandlecharacter\donthandlecharacter}
+
+\def\keepencodedtokens
+ {\let\dohandleaccent \keephandleaccent
+ \let\dohandlecommand \keephandlecommand
+ \let\dohandlecharacter\keephandlecharacter}
+
+\def\literateencodedtokens
+ {% \let\dohandleaccent \keephandleaccent
+ % \let\dohandlecommand \keephandlecommand
+ \let\dohandlecharacter\keephandlecharacter}
+
+\def\stringifyencodedtokens
+ {% \let\dohandleaccent \stringifyhandleaccent
+ % \let\dohandlecommand \stringifyhandlecommand
+ \let\dohandlecharacter\stringifyhandlecharacter}
+
+\unexpanded\def\uhandleaccent #1{\csname#1\endcsname}
+\unexpanded\def\uhandlecommand #1{\csname#1\endcsname}
+\unexpanded\def\uhandlecharacter#1{\csname#1\endcsname}
+
+\def\dontexpandencodedtokens
+ {\def\dohandleaccent {\uhandleaccent}%
+ \def\dohandlecommand {\uhandlecommand}%
+ \def\dohandlecharacter{\uhandlecharacter}}
+
+% no longer: \def\convertencodedtokens{\dontexpandencoding} but:
+
+\def\convertencodedtokens{\stringifyencodedtokens}
+
+% test case:
+%
+% \enableregime[cp1250]
+% \mainlanguage[cz]
+%
+% \starttext
+%
+% \title{Ϭuޯu餭 kon졺p
+% \placelist[chapter][criterium=all]
+%
+% \startbuffer
+% <chapter>
+% <title>Ϭuޯu餭 kon졺p󛱴itle>
+% </chapter>
+% \stopbuffer
+%
+% \defineXMLenvironment
+% [chapter]
+% {\defineXMLsave[title]}
+% {\expanded{\chapter{\XMLflush{title}}}}
+% \processXMLbuffer
+%
+% \setuphead[chapter][expansion=yes]
+% \defineXMLenvironment
+% [chapter]
+% {\defineXMLsave[title]}
+% {\chapter{\XMLflush{title}}}
+% \processXMLbuffer
+%
+% \stoptext
+
+%D Still valid? To be checked:
+
+\def\doignoreaccent #1#2{\string#1\string#2}%
+\def\doignorecommand #1{\string#1}
+\def\doignorecharacter#1{\string#1}
+
+\def\ignoreencoding
+ {\let\dohandleaccent \doignoreaccent
+ \let\dohandlecommand \doignorecommand
+ \let\dohandlecharacter\doignorecharacter}
+
+\appendtoks
+ \ignoreencoding
+\to \everycleanupfeatures
+
+\appendtoks
+ \keepencodedtokens
+\to \everysafeexpanded
+
+%D Now we will not redefine any more, so:
+
+\let\normaldohandleaccent \dohandleaccent
+\let\normaldohandlecharacter\dohandlecharacter
+
+\definecommand ` {\buildtextaccent\textgrave}
+\definecommand ' {\buildtextaccent\textacute}
+\definecommand r {\buildtextaccent\textring}
+\definecommand v {\buildtextaccent\textcaron}
+\definecommand u {\buildtextaccent\textbreve}
+\definecommand = {\buildtextaccent\textmacron}
+\definecommand ^ {\buildtextaccent\textcircumflex}
+\definecommand . {\buildtextaccent\textdotaccent}
+\definecommand H {\buildtextaccent\texthungarumlaut}
+\definecommand ~ {\buildtextaccent\texttilde}
+\definecommand " {\buildtextaccent\textdiaeresis}
+
+\definecommand c {\buildtextcedilla}
+\definecommand b {\buildtextmacron}
+\definecommand d {\buildtextbottomdot}
+\definecommand k {\buildtextogonek}
+
+\definemathaccent acute {\buildmathaccent\mathacute}
+\definemathaccent grave {\buildmathaccent\mathgrave}
+\definemathaccent ddot {\buildmathaccent\mathddot}
+\definemathaccent tilde {\buildmathaccent\mathtilde}
+\definemathaccent bar {\buildmathaccent\mathbar}
+\definemathaccent breve {\buildmathaccent\mathbreve}
+\definemathaccent check {\buildmathaccent\mathcheck}
+\definemathaccent hat {\buildmathaccent\mathhat}
+\definemathaccent vec {\buildmathaccent\mathvec}
+\definemathaccent dot {\buildmathaccent\mathdot}
+\definemathaccent widetilde {\buildmathaccent\mathwidetilde}
+\definemathaccent widehat {\buildmathaccent\mathwidehat}
+
+\useencoding[def] % defaults (partly simplified)
+\useencoding[acc] % accent commands
+\useencoding[raw] % simplified (incomplete)
+\useencoding[com] % a few commands
+\useencoding[cas] % case mapping, not needed in mkiv
+\useencoding[mis] % a few commands
+
+%D We preload several encodings:
+
+\ifnum\texengine=\xetexengine
+ \setupencoding[\s!default=\s!default]
+\else
+ \useencoding[ans,il2,ec,tbo,pdf,pol,qx,t5,cyr,agr] % pol and il2 will go away, not needed in mkiv, uc removed
+ \useencoding[032,033,037] % fallbacks for some unicode chars
+ \setupencoding[\s!default=ec] % was: [\s!default=\s!default]
+\fi
\protect \endinput
diff --git a/tex/context/base/enco-ini.mkiv b/tex/context/base/enco-ini.mkiv
index cbebaad9e..5fd3d9cef 100644
--- a/tex/context/base/enco-ini.mkiv
+++ b/tex/context/base/enco-ini.mkiv
@@ -1,61 +1,122 @@
%D \module
%D [ file=enco-ini,
-%D version=2007.02.19,
+%D version=2007.02.19, % 2000.12.27, % 1998.12.03,
%D title=\CONTEXT\ Encoding Macros,
%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright=\PRAGMA]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%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 end we will cleanup enco-ini.tex!
-
-% \setinterfacecommand{setuphead}{stelleüberschriftein}
-% \section{Oeps}
-% \stelleüberschriftein[section][style=\bf]
-% \section{Oeps}
-
-% could also be a new kind of table \definecharacter {name} {char} {fallback}
-
-% \startruntimectxluacode
-% characters.context.rehash()
-% \stopruntimectxluacode
-
-% % % % \ctxlua{characters.context.rehash()}
-
-% \ctxlua {
-% characters.context.define(
-% { % letter catcodes
-% \number\texcatcodes,
-% \number\ctxcatcodes,
-% \number\notcatcodes,
-% \number\mthcatcodes,
-% \number\vrbcatcodes,
-% \number\prtcatcodes,
-% \number\xmlcatcodesn,
-% \number\xmlcatcodese,
-% \number\xmlcatcodesr,
-% \number\typcatcodesa,
-% \number\typcatcodesb,
-% },
-% { % activate catcodes
-% \number\ctxcatcodes,
-% \number\notcatcodes,
-% \number\xmlcatcodesn,
-% \number\xmlcatcodese,
-% \number\xmlcatcodesr,
-% }
-% )
-% }
+%D This is s stripped down version of th eoriginal enco-ini.tex
+%D file. For more details you might want to study the \MKII\ file
+%D but since \LUATEX\ is unicode inside we need less code.
+
+% When dealing with characters we have four cases to take into account when moving
+% from mkii to mkiv:
+
+% 1. <byte 200> => ref to slot 200 in current font
+% 2. \char 200 => ref to slot 200 in current font
+% 3. <active 200> => can (e.g.) map to another slot in current font
+% 4. \namedglyph => can map to some slot in some font
+
+% Using case 2 for special characters is doomed to fail because we are not going
+% to intercept these on the fly as happens automatically with traditional font
+% encoding handling. We could do that in a node pass but it's not worth the effort
+% because we seldom use this case in a document source.
+
+% We can consider using utf as internal format for mkii. The main reason for not
+% doing this before was that it was slow. On the other hand, it would make dealing
+% with utility files easier. However, we've now kind of frozen mkii.
+
+\writestatus{loading}{ConTeXt Encoding Macros / Initialization}
\unprotect
+%D Quite some commands are now obsolete. These nillers will disappear soon.
+
+\def\currentencoding {utf}
+\def\currentmapping {utf}
+
+\let\defaultencoding \s!default
+\let\characterencoding \s!default
+\let\nocharacterencoding\s!default
+
+\def\setupencoding [#1]{}
+\def\startmapping [#1]{\gobbleuntil\stopmapping}
+\def\startencoding [#1]{}
+\let\stopencoding \relax
+\let\startcoding \startencoding
+\let\stopcoding \relax
+\def\optimizemapping [#1]{}
+\def\enablemapping [#1]{}
+\def\enableencoding [#1]{}
+\def\enablecoding [#1]{}
+\def\fastenableencoding #1{}
+\def\enablelanguagespecifics[#1]{}
+\def\useencoding [#1]{}
+
+\let\dontexpandencoding \relax
+\let\keepencodedtokens \relax
+\let\literateencodedtokens \relax
+\let\stringifyencodedtokens \relax
+\let\dontexpandencodedtokens\relax
+\let\convertencodedtokens \relax
+\let\ignoreencoding \relax
+
+% todo:
+
+% \def\showaccents {\f!encodingprefix\s!run}
+% \def\showcharacters {\f!encodingprefix\s!run}
+% \def\showcharacterbounds {\f!encodingprefix\s!run}
+% \def\showhyphenations {\f!encodingprefix\s!run}
+% \def\showmapping {\f!encodingprefix\s!run}
+
+%D \macros
+%D {defineaccent, definecharacter, definecommand}
+
+\def\accentprefix{@acc@}
+
+\def\defineaccent#1 #2 #3 %
+ {\setevalue{\string#1}{\noexpand\dohandleaccent{\string#1}}%
+ \setvalue{\accentprefix\string#1\string#2}{#3}}
+
+\def\dohandleaccent#1#2%
+ {\csname\accentprefix\string#1\string#2\endcsname}
+
+\def\definecharacter#1 #2 %
+ {\doifnumberelse{\string#2}
+ {\setevalue{\string#1}{\utfchar{#2}}} % or {\expandafter\chardef\csname#1\endcsname#2\relax}
+ {\unexpanded\setvalue {\string#1}{#2}}}
+
+\def\definecommand#1 #2 %
+ {\unexpanded\setvalue{\string#1}{#2}}
+
+%D \macros
+%D {everyuppercase, EveryUppercase,
+%D everyuppercase, EveryUppercase,
+%D everysanitize, EverySanitize}
+
+\newevery \everyuppercase \EveryUppercase
+\newevery \everylowercase \EveryLowercase
+\newevery \everysanitize \EverySanitize
+
+%D Some saved meanings (not really needed):
+
+\let\textaccent \accent
+\let\normaltextaccent\accent
+
+%D Accent handling (try to avoid this):
+
\newbox\accenttestbox
-\unexpanded\def\dobuildtextaccent#1#2%
+\def\buildmathaccent#1%
+ {\mathaccent#1 }
+
+\unexpanded\def\buildtextaccent#1#2%
{\begingroup
\global\setbox\accenttestbox\hbox{#1}%
\scratchcounter\ctxlua{characters.charcode(\number\accenttestbox)}%
@@ -63,47 +124,405 @@
\relax#2%
\endgroup}
-\useencoding[032,033,037] % fallbacks for some unicode chars, todo
+\unexpanded\def\bottomaccent#1#2#3#4#5% down right slantcorrection accent char
+ {\dontleavehmode % why this align mess
+ \vtop
+ {\forgetall
+ \baselineskip\zeropoint
+ \lineskip#1%
+ \everycr\emptytoks
+ \tabskip\zeropoint
+ \lineskiplimit\zeropoint
+ \setbox0\hbox{#4}%
+ \halign
+ {##\crcr\hbox{#5}\crcr
+ \hidewidth
+ \hskip#2\wd0
+ \hskip-#3\slantperpoint % in plain 1ex * dimenless value
+ \vbox to .2ex{\box0\vss}\hidewidth
+ \crcr}}}
-\setupencoding[\s!default=ec] % for the moment keep it this way, till fonts are there
+\def\buildtextmacron {\bottomaccent{.25ex}{0}{15}{\textmacron}}
+\def\buildtextbottomdot {\bottomaccent{.25ex}{0}{5}{\textbottomdot}}
+\def\buildtextcedilla {\bottomaccent{0ex}{0}{5}{\textcedilla}}
+\def\buildtextogonek {\bottomaccent{-.1ex}{.5}{0}{\textogonek}}
+\def\buildtextbottomcomma{\bottomaccent{.15ex}{0}{5}{\tx,}}
-\protect \endinput
+\unexpanded\def\topaccent#1#2#3#4#5% down right slantcorrection accent char
+ {\dontleavehmode
+ \bgroup
+ \setbox0\hbox{#4}%
+ \setbox2\hbox{#5}%
+ \hbox to \wd2 \bgroup
+ \hss\copy2\hss
+ \hskip-\wd2
+ \hss\hskip#2\wd0\hskip-#3\slantperpoint\raise#1\hbox{#4}\hss
+ \egroup
+ \egroup}
+
+\def\buildtextgrave{\topaccent{0pt}{0}{15}{\textgrave}} % e.g.
+
+\def\definemathaccent#1 #2%
+ {\setvalue{#1}{\mathaccent#2 }}
+
+%D Math (will move):
+
+\definemathaccent acute \mathacute
+\definemathaccent grave \mathgrave
+\definemathaccent ddot \mathddot
+\definemathaccent tilde \mathtilde
+\definemathaccent bar \mathbar
+\definemathaccent breve \mathbreve
+\definemathaccent check \mathcheck
+\definemathaccent hat \mathhat
+\definemathaccent vec \mathvec
+\definemathaccent dot \mathdot
+\definemathaccent widetilde \mathwidetilde
+\definemathaccent widehat \mathwidehat
+
+% from enco-com:
+
+\def\AA{\Aring}
+\def\aa{\aring}
+\def\AE{\AEligature}
+\def\ae{\aeligature}
+\def\CC{\Ccedilla}
+\def\cc{\ccedilla}
+\def \L{\Lstroke}
+\def \l{\lstroke}
+\def \O{\Ostroke}
+\def \o{\ostroke}
+\def\OE{\OEligature}
+\def\oe{\oeligature}
+\def\SZ{\Ssharp}
+\def\sz{\ssharp}
+\def\SS{\ssharp}
+\def\IJ{\IJligature}
+\def\ij{\ijligature}
+\def \i{\dotlessi}
+\def \j{\dotlessj}
+
+% from enco-def:
+
+\def\dotlessI {I}
+\def\dotlessJ {J}
+
+\def\Ssharp {SS}
+
+\def\eszett {\ssharp}
+\def\Eszett {\Ssharp}
+
+\def\lslash {\lstroke}
+\def\Lslash {\Lstroke}
+\def\dslash {\dstroke}
+\def\Dslash {\Dstroke}
+\def\oslash {\ostroke}
+\def\Oslash {\Ostroke}
+\def\dcroat {\dstroke}
+\def\Dcroat {\Dstroke}
+
+\def\Kcedilla {\Kcommaaccent}
+\def\kcedilla {\kcommaaccent}
+\def\Lcedilla {\Lcommaaccent}
+\def\lcedilla {\lcommaaccent}
+\def\Ncedilla {\Ncommaaccent}
+\def\ncedilla {\ncommaaccent}
+\def\Rcedilla {\Rcommaaccent}
+\def\rcedilla {\rcommaaccent}
+
+\def\S {\sectionmark}
+\def\P {\paragraphmark}
+
+\def\aumlaut {\adiaeresis}
+\def\eumlaut {\ediaeresis}
+\def\iumlaut {\idiaeresis}
+\def\oumlaut {\odiaeresis}
+\def\uumlaut {\udiaeresis}
+\def\Aumlaut {\Adiaeresis}
+\def\Eumlaut {\Ediaeresis}
+\def\Iumlaut {\Idiaeresis}
+\def\Oumlaut {\Odiaeresis}
+\def\Uumlaut {\Udiaeresis}
+
+% for latex users
+
+\def\textS {\sectionmark}
+\def\textP {\paragraphmark}
+
+% for old times sake
+
+\def\textflorin{\fhook}
+\def\florin {\textflorin}
+\def\dollar {\textdollar}
+\def\pound {\textsterling}
+\def\sterling {\textsterling}
+\def\promille {\perthousand}
+\def\permille {\perthousand}
+\def\procent {\percent}
+\def\permine {\fakepermine}
+
+% some more
+
+\def\hyphen {\softhyphen}
+\def\compoundwordmark {\hyphen}
+\def\cwm {\hyphen}
+\def\nonbreakinghyphen{\hyphen}
+\def\breakinghyphen {\hyphen\prewordbreak}
-When dealing with characters we have four cases to take into account when moving
-from mkii to mkiv:
-
-1. <byte 200> => ref to slot 200 in current font
-2. \char 200 => ref to slot 200 in current font
-3. <active 200> => can (e.g.) map to another slot in current font
-4. \namedglyph => can map to some slot in some font
-
-Using case 2 for special characters is doomed to fail because we are not going
-to intercept these on the fly as happens automatically with traditional font
-encoding handling. We could do that in a node pass but it's not worth the effort
-because we seldom use this case in a document source.
-
-We can consider using utf as internal format for mkii. The main reason for not
-doing this before was that it was slow. On the other hand, it would make dealing
-with utility files easier.
-
-These are the only cases where char references are used:
-
-enco-def.tex : 46 : \definecharacter dotlessi {\char"10 }
-enco-def.tex : 47 : \definecharacter dotlessj {\char"11 }
-enco-def.tex : 54 : \definecharacter aeligature {\char26 } % "1A
-enco-def.tex : 55 : \definecharacter AEligature {\char29 } % "1D
-enco-def.tex : 58 : \definecharacter oeligature {\char27 } % "1B
-enco-def.tex : 59 : \definecharacter OEligature {\char30 } % "1E
-enco-def.tex : 61 : \definecharacter ssharp {\char25 } % "19
-enco-def.tex : 336 : \definecharacter Lstroke {\hsmash{\char32}L}
-enco-def.tex : 337 : \definecharacter lstroke {\hsmash{\char32}l}
-enco-def.tex : 338 : \definecharacter Ostroke {\char31 } % "1F
-enco-def.tex : 339 : \definecharacter ostroke {\char28 } % "1C
-enco-il2.tex : 147 : {\dontleavehmode{\char32l}}
-enco-il2.tex : 152 : \hbox to\wd0{\hss\char32L}%
-symb-eur.tex : 37 : \definesymbol [euro] [\getglyph{Euro}{\char160}]
-symb-glm.tex : 61 : \definesymbol [xleftguillemot] [\getglyph{Guil}{\char19}]
-symb-glm.tex : 62 : \definesymbol [xrightguillemot] [\getglyph{Guil}{\char20}]
-symb-glm.tex : 64 : \definesymbol [xguilsingleleft] [\getglyph{Guil}{\char14}]
-symb-glm.tex : 65 : \definesymbol [xguilsingleright] [\getglyph{Guil}{\char15}]
+% quotes
+\def\lowerleftsingleninequote {\quotesinglebase}
+\def\lowerleftdoubleninequote {\quotedblbase}
+\def\lowerrightsingleninequote {\quotesinglebase}
+\def\lowerrightdoubleninequote {\quotedblbase}
+
+\def\upperleftsingleninequote {\quoteright}
+\def\upperleftdoubleninequote {\quotedblright}
+\def\upperrightsingleninequote {\quoteright}
+\def\upperrightdoubleninequote {\quotedblright}
+
+\def\upperleftsinglesixquote {\quoteleft}
+\def\upperleftdoublesixquote {\quotedblleft}
+\def\upperrightsinglesixquote {\quoteleft}
+\def\upperrightdoublesixquote {\quotedblleft}
+
+\def\leftsubguillemot {\guilsingleleft}
+\def\rightsubguillemot {\guilsingleright}
+
+% obsolete:
+
+% \greekleftquot {[obsolete]}
+% \greekrightquot {[obsolete]}
+% \greekapostrophos {[obsolete]}
+% \greekupsilondialytika{[obsolete]}
+% \Ycaron {[obsolete]}
+% \ycaron {[obsolete]}
+
+% to be done in char-def:
+
+% \definecharacter cyrillicGUP {GUP}
+% \definecharacter cyrillicGHCRS {GHCRS}
+% \definecharacter cyrillicZHDSC {ZHDSC}
+% \definecharacter cyrillicKDSC {KDSC}
+% \definecharacter cyrillicKBEAK {KBEAK}
+% \definecharacter cyrillicKVCRS {KVCRS}
+% \definecharacter cyrillicNG {NG}
+% \definecharacter cyrillicOTLD {OTLD}
+% \definecharacter cyrillicY {Y}
+% \definecharacter cyrillicYHCRS {YHCRS}
+% \definecharacter cyrillicHDSC {HDSC}
+% \definecharacter cyrillicCHVCRS {CHVCRS}
+% \definecharacter cyrillicCHRDSC {CHRDSC}
+% \definecharacter cyrillicQ {Q}
+% \definecharacter cyrillicW {W}
+%
+% \definecharacter cyrillicgup {gup}
+% \definecharacter cyrillicghcrs {ghcrs}
+% \definecharacter cyrilliczhdsc {zhdsc}
+% \definecharacter cyrillickdsc {kdsc}
+% \definecharacter cyrillickbeak {kbeak}
+% \definecharacter cyrillickvcrs {kvcrs}
+% \definecharacter cyrillicng {ng}
+% \definecharacter cyrillicotld {otld}
+% \definecharacter cyrillicy {y}
+% \definecharacter cyrillicyhcrs {yhcrs}
+% \definecharacter cyrillichdsc {hdsc}
+% \definecharacter cyrillicchvcrs {chvcrs}
+% \definecharacter cyrillicchrdsc {chrdsc}
+% \definecharacter cyrillicq {q}
+% \definecharacter cyrillicw {w}
+
+% \definecharacter softhyphen 45
+% \definecharacter compoundwordmark 23
+
+% left-overs (some day in private unicode space, so that we can roundtrip)
+
+\unexpanded\def\textblacksquare {\dontleavehmode\hbox{\vrule\!!width.3\s!em\!!height.4\s!em\!!depth-.1\s!em}}
+\unexpanded\def\schwa {\hbox{\rotate[\c!rotation=180,\c!location=\v!high]{\hbox{e}}}}
+\unexpanded\def\schwagrave {\buildtextgrave\schwa}
+
+\unexpanded\def\normalcontrolspace{\getglyph{ComputerModernMono}{\char32}}
+\unexpanded\def\textvisiblespace {\fakecontrolspace}
+\unexpanded\def\fakecontrolspace {\let\normalcontrolspace\fakedcontrolspace}
+
+% helpers
+
+\def\fakepercent
+ {\mathematics{^{\scriptscriptstyle0}\kern-.25em/\kern-.2em_{\scriptscriptstyle0}}}
+
+\def\fakeperthousand
+ {\mathematics{^{\scriptscriptstyle0}\kern-.25em/\kern-.2em_{\scriptscriptstyle00}}}
+
+\def\fakepermine
+ {\dontleavehmode
+ \bgroup
+ \setbox\scratchbox\hbox
+ {\mathematics{+}}%
+ \hbox to \wd\scratchbox
+ {\hss\mathematics{^{\scriptscriptstyle-}\kern-.4em/\kern-.3em_{\scriptscriptstyle-}}\hss}%
+ \egroup}
+
+\def\fakedcontrolspace % can be virtual in luatex
+ {\dontleavehmode\hbox
+ {\scratchdimen.1ex%
+ \kern\scratchdimen
+ \vrule \!!width\scratchdimen \!!height5.5\scratchdimen\!!depth3\scratchdimen
+ \vrule \!!width\dimexpr.5em-4\scratchdimen\!!height -2\scratchdimen\!!depth3\scratchdimen
+ \vrule \!!width\scratchdimen \!!height5.5\scratchdimen\!!depth3\scratchdimen
+ \kern\scratchdimen}}
+
+% what to do with these:
+%
+% \definecharacter mathacute "7013
+% \definecharacter mathgrave "7012
+% \definecharacter mathddot "707F
+% \definecharacter mathtilde "707E
+% \definecharacter mathbar "7016
+% \definecharacter mathbreve "7015
+% \definecharacter mathcheck "7014
+% \definecharacter mathhat "705E
+% \definecharacter mathvec "017E
+% \definecharacter mathdot "705F
+% \definecharacter mathwidetilde "0365
+% \definecharacter mathwidehat "0362
+
+% from enco-acc:
+
+\defineaccent ^ A {\Acircumflex} \defineaccent ^ a {\acircumflex}
+\defineaccent ^ C {\Ccircumflex} \defineaccent ^ c {\ccircumflex}
+\defineaccent ^ E {\Ecircumflex} \defineaccent ^ e {\ecircumflex}
+\defineaccent ^ G {\Gcircumflex} \defineaccent ^ g {\gcircumflex}
+\defineaccent ^ H {\Hcircumflex} \defineaccent ^ h {\hcircumflex}
+\defineaccent ^ I {\Icircumflex} \defineaccent ^ i {\icircumflex} \defineaccent ^ {\i} {\icircumflex}
+\defineaccent ^ J {\Jcircumflex} \defineaccent ^ j {\jcircumflex} \defineaccent ^ {\j} {\jcircumflex}
+\defineaccent ^ O {\Ocircumflex} \defineaccent ^ o {\ocircumflex}
+\defineaccent ^ S {\Scircumflex} \defineaccent ^ s {\scircumflex}
+\defineaccent ^ U {\Ucircumflex} \defineaccent ^ u {\ucircumflex}
+\defineaccent ^ W {\Wcircumflex} \defineaccent ^ w {\wcircumflex}
+\defineaccent ^ Y {\Ycircumflex} \defineaccent ^ y {\ycircumflex}
+
+\defineaccent ` A {\Agrave} \defineaccent ` a {\agrave}
+\defineaccent ` E {\Egrave} \defineaccent ` e {\egrave}
+\defineaccent ` I {\Igrave} \defineaccent ` i {\igrave} \defineaccent ` {\i} {\igrave}
+\defineaccent ` O {\Ograve} \defineaccent ` o {\ograve}
+\defineaccent ` U {\Ugrave} \defineaccent ` u {\ugrave}
+\defineaccent ` Y {\Ygrave} \defineaccent ` y {\ygrave}
+
+\defineaccent ~ A {\Atilde} \defineaccent ~ a {\atilde}
+\defineaccent ~ I {\Itilde} \defineaccent ~ i {\itilde} \defineaccent ~ {\i} {\itilde}
+\defineaccent ~ O {\Otilde} \defineaccent ~ o {\otilde}
+\defineaccent ~ U {\Utilde} \defineaccent ~ u {\utilde}
+
+\defineaccent " A {\Adiaeresis} \defineaccent " a {\adiaeresis}
+\defineaccent " E {\Ediaeresis} \defineaccent " e {\ediaeresis}
+\defineaccent " I {\Idiaeresis} \defineaccent " i {\idiaeresis} \defineaccent " {\i} {\idiaeresis}
+\defineaccent " O {\Odiaeresis} \defineaccent " o {\odiaeresis}
+\defineaccent " U {\Udiaeresis} \defineaccent " u {\udiaeresis}
+\defineaccent " Y {\Ydiaeresis} \defineaccent " y {\ydiaeresis}
+
+\defineaccent ' A {\Aacute} \defineaccent ' a {\aacute}
+\defineaccent ' C {\Cacute} \defineaccent ' c {\cacute}
+\defineaccent ' E {\Eacute} \defineaccent ' e {\eacute}
+\defineaccent ' I {\Iacute} \defineaccent ' i {\iacute} \defineaccent ' {\i} {\iacute}
+\defineaccent ' L {\Lacute} \defineaccent ' l {\lacute}
+\defineaccent ' N {\Nacute} \defineaccent ' n {\nacute}
+\defineaccent ' O {\Oacute} \defineaccent ' o {\oacute}
+\defineaccent ' R {\Racute} \defineaccent ' r {\racute}
+\defineaccent ' S {\Sacute} \defineaccent ' s {\sacute}
+\defineaccent ' U {\Uacute} \defineaccent ' u {\uacute}
+\defineaccent ' Y {\Yacute} \defineaccent ' y {\yacute}
+\defineaccent ' Z {\Zacute} \defineaccent ' z {\zacute}
+
+\defineaccent . C {\Cdotaccent} \defineaccent . c {\cdotaccent}
+\defineaccent . E {\Edotaccent} \defineaccent . e {\edotaccent}
+\defineaccent . G {\Gdotaccent} \defineaccent . g {\gdotaccent}
+\defineaccent . I {\Idotaccent} \defineaccent . i {\idotaccent} \defineaccent . {\i} {\idotaccent}
+\defineaccent . Z {\Zdotaccent} \defineaccent . z {\zdotaccent}
+
+\defineaccent = A {\Amacron} \defineaccent = a {\amacron}
+\defineaccent = E {\Emacron} \defineaccent = e {\emacron}
+\defineaccent = I {\Imacron} \defineaccent = i {\imacron} \defineaccent = {\i} {\imacron}
+\defineaccent = O {\Omacron} \defineaccent = o {\omacron}
+\defineaccent = U {\Umacron} \defineaccent = u {\umacron}
+
+\defineaccent c C {\Ccedilla} \defineaccent c c {\ccedilla}
+\defineaccent c K {\Kcedilla} \defineaccent c k {\kcedilla}
+\defineaccent c L {\Lcedilla} \defineaccent c l {\lcedilla}
+\defineaccent c N {\Ncedilla} \defineaccent c n {\ncedilla}
+\defineaccent c R {\Rcedilla} \defineaccent c r {\rcedilla}
+\defineaccent c S {\Scedilla} \defineaccent c s {\scedilla}
+\defineaccent c T {\Tcedilla} \defineaccent c t {\tcedilla}
+
+\defineaccent H O {\Ohungarumlaut} \defineaccent H o {\ohungarumlaut}
+\defineaccent H u {\uhungarumlaut} \defineaccent H U {\Uhungarumlaut}
+
+\defineaccent k A {\Aogonek} \defineaccent k a {\aogonek}
+\defineaccent k E {\Eogonek} \defineaccent k e {\eogonek}
+\defineaccent k I {\Iogonek} \defineaccent k i {\iogonek}
+\defineaccent k U {\Uogonek} \defineaccent k u {\uogonek}
+
+\defineaccent r A {\Aring} \defineaccent r a {\aring}
+\defineaccent r U {\Uring} \defineaccent r u {\uring}
+
+\defineaccent u A {\Abreve} \defineaccent u a {\abreve}
+\defineaccent u E {\Ebreve} \defineaccent u e {\ebreve}
+\defineaccent u G {\Gbreve} \defineaccent u g {\gbreve}
+\defineaccent u I {\Ibreve} \defineaccent u i {\ibreve} \defineaccent u {\i} {\ibreve}
+\defineaccent u O {\Obreve} \defineaccent u o {\obreve}
+\defineaccent u U {\Ubreve} \defineaccent u u {\ubreve}
+
+\defineaccent v C {\Ccaron} \defineaccent v c {\ccaron}
+\defineaccent v D {\Dcaron} \defineaccent v d {\dcaron}
+\defineaccent v E {\Ecaron} \defineaccent v e {\ecaron}
+\defineaccent v L {\Lcaron} \defineaccent v l {\lcaron}
+\defineaccent v N {\Ncaron} \defineaccent v n {\ncaron}
+\defineaccent v R {\Rcaron} \defineaccent v r {\rcaron}
+\defineaccent v S {\Scaron} \defineaccent v s {\scaron}
+\defineaccent v T {\Tcaron} \defineaccent v t {\tcaron}
+\defineaccent v Z {\Zcaron} \defineaccent v z {\zcaron}
+
+% from enco-mis:
+
+\def\fakepercent
+ {\mathematics{^{\scriptscriptstyle0}\kern-.25em/\kern-.2em_{\scriptscriptstyle0}}}
+
+\def\fakeperthousand
+ {\mathematics{^{\scriptscriptstyle0}\kern-.25em/\kern-.2em_{\scriptscriptstyle00}}}
+
+\def\fakepermine
+ {\dontleavehmode
+ \bgroup
+ \setbox\scratchbox\hbox
+ {\mathematics{+}}%
+ \hbox to \wd\scratchbox
+ {\hss
+ \mathematics{^{\scriptscriptstyle-}\kern-.4em/\kern-.3em_{\scriptscriptstyle-}}%
+ \hss}%
+ \egroup}
+
+%D A smaller and bolder variant, more like the math and monospaced ones.
+
+\def\fakeunderscore
+ {\leavevmode\hbox
+ {\setbox\scratchbox\hbox{(}%
+ \scratchdimen.2\dp\scratchbox
+ \setbox\scratchbox\hbox{\space}%
+ \vrule
+ \!!depth \scratchdimen
+ \!!width \wd\scratchbox
+ \!!height\zeropoint}}
+
+
+\def\fakeunderscores{\let\_\fakeunderscore}
+\def\textunderscores{\let\_\textunderscore}
+
+\textunderscores
+
+\ifx\mathunderscore\undefined \let\mathunderscore\fakeunderscore \fi
+\ifx\textunderscore\undefined \let\textunderscore\fakeunderscore \fi
+
+\unexpanded\def\normalunderscore{\ifmmode\mathunderscore\else\textunderscore\fi}
+
+\let\_\normalunderscore
+
+\protect \endinput
diff --git a/tex/context/base/enco-ini.tex b/tex/context/base/enco-ini.tex
deleted file mode 100644
index 4c85bac5b..000000000
--- a/tex/context/base/enco-ini.tex
+++ /dev/null
@@ -1,1228 +0,0 @@
-%D \module
-%D [ file=enco-ini,
-%D version=2000.12.27, % 1998.12.03,
-%D title=\CONTEXT\ Encoding Macros,
-%D subtitle=Initialization,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Quite some code will be moved to the mk files once we're ready
-%D for it.
-
-%D This module is a reimplementation of the module that handled
-%D composed characters and non \ASCII\ characters. The changed
-%D are not that fundamental, and mainly concerns moving
-%D definitions of specific glyphs and accents to other files as
-%D well as moving plain handling of accents to this module
-%D instead of overloading plain \TEX\ commands.
-
-%D Patterns are kind of mixed with font encodings and
-%D mappings. Alas.
-
-\ifx\synchronizepatterns\undefined \let\synchronizepatterns\relax \fi
-
-%D While dealing with input (the text source) and output (the
-%D glyphs), encoding comes into view. To summarize a few:
-%D
-%D \startitemize
-%D \item Bytes in the input file are mapped to an internal
-%D representation. An~\type {a} often stays an~\type {a},
-%D but~\type {\"e} can become either one code or become
-%D two codes (ending in overlapping glyphs).
-%D \item Characters can be made active and mapped onto another
-%D character.
-%D \item When changing case, characters are mapped onto
-%D themselves, their case||counterpart or a reasonable
-%D alternative, like~\"e onto~e.
-%D \item Single character representations in a \DVI\ file can
-%D be mapped onto one or more characters, either of not
-%D in more than one font file (virtual fonts).
-%D \item In the final format, fonts collections can be
-%D partially embedded, thereby losing the one||to||one
-%D relation between several instances of one font.
-%D \item For special purposes, individual characters should be
-%D mapped onto a dedicated encoding vector, for instance
-%D \PDF\ document encoding.
-%D \stopitemize
-%D
-%D These and other kind of mappings are to be dealt with, and
-%D the exact way of dealing often depends on the language to be
-%D typeset.
-
-\writestatus{loading}{Context Encoding Macros (ini)}
-
-\unprotect
-
-\startmessages dutch library: encodings
- title: encoding
- 1: codering --
- 2: codering -- wordt geladen
- 3: onbekende codering --
-\stopmessages
-
-\startmessages english library: encodings
- title: encoding
- 1: coding --
- 2: coding -- is loaded
- 3: unknown coding --
-\stopmessages
-
-\startmessages german library: encodings
- title: Kodierung
- 1: Kodierung --
- 2: Kodierung -- ist geladen
- 3: Unbekannte Kodierung --
-\stopmessages
-
-\startmessages czech library: encodings
- title: kodovani
- 1: kodovani --
- 2: je nacteno kodovani --
- 3: nezname kodovani --
-\stopmessages
-
-\startmessages italian library: encodings
- title: codifica
- 1: codifica --
- 2: codifica -- caricata
- 3: codifica sconosciuta --
-\stopmessages
-
-\startmessages norwegian library: encodings
- title: koding
- 1: koding --
- 2: koding -- er lest inn
- 3: ukjent koding --
-\stopmessages
-
-\startmessages romanian library: encodings
- title: codificari
- 1: codificarea --
- 2: codificarea -- este Encarcata
- 3: codificarea -- este necunoscuta
-\stopmessages
-
-\startmessages french library: encodings
- title: encodage
- 1: encodage --
- 2: l'encodage -- est chargé
- 3: encodage -- inconnu
-\stopmessages
-
-%D First we define a few local or not yet initialized constants.
-
-\def\@map@{@m@ap@} % mapping prefix
-\def\@fha@{@f@ha@} % font prefix
-\def\@cas@{@c@as@} % casecom prefix
-
-\ifx\currentlanguage\undefined \let\currentlanguage\s!en \fi
-
-%D \macros
-%D {setupencoding}
-%D
-%D The following setup command is used to tune encoding
-%D handling.
-
-\def\setupencoding
- {\dosingleargument\dosetupencoding}
-
-\def\dosetupencoding[#1]%
- {\getparameters[\??ec][#1]%
- \edef\defaultencoding
- {\ifx\@@ecdefault\empty\s!default\else\@@ecdefault\fi}}
-
-%D \macros
-%D {useencoding}
-%D
-%D Encodings things are defined in separate files and are
-%D loaded only once, using:
-%D
-%D \showsetup{useencoding}
-
-\def\douseencoding#1%
- {\doifundefined{\c!file\f!encodingprefix#1}%
- {\letvalue{\c!file\f!encodingprefix#1}\empty
- \makeshortfilename[\truefilename{\f!encodingprefix#1}]%
- \startreadingfile
- \readsysfile\shortfilename
- {\showmessage\m!encodings2{#1}}
- {\showmessage\m!encodings3{#1}}%
- \stopreadingfile}}
-
-\def\useencoding[#1]%
- {\processcommalist[#1]\douseencoding}
-
-%D \macros
-%D {startmapping,enablemapping}
-%D
-%D In order to process patterns, convert from lower to
-%D uppercase and vise versa and some more, we provide a
-%D mechanism to define mappings. The first real application
-%D of this command was:
-%D
-%D \starttyping
-%D \startmapping [something]
-%D \definecasemap 165 181 165
-%D \definecasemap 171 187 171
-%D ...
-%D \defineuppercasecom \i {I}
-%D \defineuppercasecom \l \L
-%D \definelowercasecom \AE \ae
-%D ...
-%D \stopmapping
-%D \stoptyping
-%D
-%D So, character 165 becomes 181 in uppercase and 165 in
-%D lowercase. A mapping is activated with \type {\enablemapping}.
-
-\def\startsavingmappingtoks#1%
- {\bgroup
- \edef\charactermapping{@#1@}%
- \checkmappingtoks
- \setmappingtoks
- \the\mappingtoks}
-
-\def\stopsavingmappingtoks
- {\global\mappingtoks\emptytoks
- \dostepwiserecurse{0}{255}\plusone
- {\edef\@@expanded
- {\the\mappingtoks
- \ifnum\recurselevel>127
- \noexpand\settoletterunlessactive{\recurselevel}%
- \fi
- \lccode\recurselevel\ifnum\lccode\recurselevel=\zerocount\zerocount\else\space\the\lccode\recurselevel\space\fi
- \uccode\recurselevel\ifnum\uccode\recurselevel=\zerocount\zerocount\else\space\the\uccode\recurselevel\space\fi
- \ifnum\sfcode\recurselevel=\plusthousand\else\sfcode\recurselevel=\the\sfcode\recurselevel\space\fi
- }%
- \global\mappingtoks\expandafter{\@@expanded}}%
- \egroup
- \let\enabledmapping\empty
- \enablemapping[\currentmapping]}
-
-\def\startmapping[#1]%
- {\startsavingmappingtoks{#1}}
-
-\def\stopmapping
- {\stopsavingmappingtoks}
-
-\def\optimizemapping[#1]%
- {\startsavingmappingtoks{#1}%
- % nothing, just an automatic cleanup
- \stopsavingmappingtoks
- % we need to resync
- %\let\enabledmapping\relax
- }%\enablemapping[\currentmapping]}
-
-\def\setmappingtoks
- {\@EA\let\@EA\mappingtoks\csname\@map@\charactermapping\endcsname
- \@EA\let\@EA\casecomtoks\csname\@cas@\charactermapping\endcsname}
-
-\def\checkmappingtoks
- {\ifundefined{\@map@\charactermapping}%
- \expandafter\newtoks\csname\@map@\charactermapping\endcsname
- \fi
- \ifundefined{\@cas@\charactermapping}%
- \expandafter\newtoks\csname\@cas@\charactermapping\endcsname
- \fi}
-
-\def\definecasemap #1 #2 #3 % code lower upper
- {\doifelse{#2}{to}
- {\presetcaserange{#1}{#3}}
- {\lccode#1=#2\relax
- \uccode#1=#3\relax}%
- \ignorespaces}
-
-%D Saves a few tokens
-
-\def\definecaseswap #1 #2 % lower upper
- {\lccode#1=#1\relax
- \uccode#2=#2\relax
- \lccode#2=#1\relax
- \uccode#1=#2\relax
- \ignorespaces}
-
-\def\definecaseself #1 % lower=upper=self
- {\lccode#1=#1\relax
- \uccode#1=#1\relax
- \ignorespaces}
-
-%D Watch the \type {\definecasemap 127 to 255} option!
-%D Dedicated to Taco there is also:
-
-\def\definecasemaps #1 to #2 lc #3 uc #4 % from to lc+ uc+
- {\dostepwiserecurse{#1}{#2}\plusone
- {\scratchcounter\recurselevel\advance\scratchcounter#3\lccode\recurselevel=\scratchcounter
- \scratchcounter\recurselevel\advance\scratchcounter#4\uccode\recurselevel=\scratchcounter}%
- \ignorespaces}
-
-%D This can be used like:
-%D
-%D \starttyping
-%D \definecasemaps 128 to 156 lc 32 uc 0
-%D \definecasemaps 160 to 188 lc -32 uc 0
-%D \definecasemaps 160 to 188 lc -32 uc 0
-%D \definecasemaps 192 to 255 lc 32 uc 0
-%D \stoptyping
-%D
-%D and saves a lot of typing (copying).
-
-\def\resetcaserange #1 to #2
- {\dostepwiserecurse{#1}{#2}\plusone
- {\lccode\recurselevel\zerocount
- \uccode\recurselevel\zerocount}%
- \ignorespaces}
-
-\def\presetcaserange#1#2% could be pre-expanded
- {\dostepwiserecurse{#1}{#2}\plusone
- {\lccode\recurselevel=\recurselevel
- \uccode\recurselevel=\recurselevel}%
- \ignorespaces}
-
-\def\setcasemap #1 #2 #3 %
- {\settoletterunlessactive{#1}%
- \lccode #1=#2
- \uccode #1=#3 }
-
-\def\setcaseswap #1 #2 %
- {\settoletterunlessactive{#1}%
- \settoletterunlessactive{#2}%
- \lccode #1=#1
- \uccode #2=#2
- \lccode #2=#1
- \uccode #1=#2 }
-
-\def\setcaseself #1 %
- {\settoletterunlessactive{#1}%
- \lccode #1=#1
- \uccode #1=#1 }
-
-\def\definespacemap #1 #2 % code sfcode
- {\sfcode#1=#2%
- \ignorespaces}
-
-\def\setspacemap #1 #2 %
- {\settootherunlessactive{#1}%
- %\lccode #1=\zerocount
- %\uccode #1=\zerocount
- \sfcode #1=#2 }
-
-\def\defineuppercasecom#1#2%
- {\global\casecomtoks\expandafter{\the\casecomtoks\setuppercasecom#1{#2}}%
- \ignorespaces}
-
-\def\definelowercasecom#1#2%
- {\global\casecomtoks\expandafter{\the\casecomtoks\setlowercasecom#1{#2}}%
- \ignorespaces}
-
-\let\setuppercasecom\gobbletwoarguments
-\let\setlowercasecom\gobbletwoarguments
-
-\def\setcasecom#1#2{\def#1{#2}}
-
-\let\enabledmapping\empty % indirect, needed to handle default too
-
-\def\enablemapping[#1]%
- {\edef\charactermapping{@#1@}%
- \ifx\enabledmapping\charactermapping \else
- \doifdefined{\@map@\charactermapping}
- {%\expandafter\showthe\csname\@map@\charactermapping\endcsname\endcsname
- \the\csname\@map@\charactermapping\endcsname}%
- % == \the\executeifdefined{\@map@\charactermapping}\emptytoks
- \edef\enabledmapping{\charactermapping}%
- \enablelanguagespecifics[\currentlanguage]% new
- % \edef\enabledmapping{\charactermapping\currentlanguage}% can be comma list
- \fi
- \synchronizepatterns}
-
-% on behalf of font switching:
-
-\def\fastenablemapping#1%
- {\edef\charactermapping{@#1@}%
- \ifx\enabledmapping\charactermapping \else
- \@EA\ifx\csname\@map@\charactermapping\endcsname\relax\else
- \the\csname\@map@\charactermapping\endcsname
- \fi
- % == \the\executeifdefined{\@map@\charactermapping}\emptytoks
- \let\enabledmapping\charactermapping
- \enablelanguagespecifics[\currentlanguage]% to faster
- \fi}
-
-%D This macro wil be implemented in \type {lang-ini.tex}.
-
-\ifx\enablelanguagespecifics\undefined
- \def\enablelanguagespecifics[#1]{}
-\fi
-
-%D Further on we have to take some precautions when dealing
-%D with special characters like~\type{~}, \type{_}
-%D and~\type{^}, so let us define ourselve some handy macros
-%D first.
-
-\def\protectfontcharacters
- {\edef\unprotectfontcharacters
- {\catcode`\noexpand ~=\the\catcode`~\relax
- \catcode`\noexpand _=\the\catcode`_\relax
- \catcode`\noexpand ^=\the\catcode`^\relax}%
- \catcode`~=\@@letter
- \catcode`_=\@@letter
- \catcode`^=\@@letter\relax}
-
-%D The completeness of the Computer Modern Roman typefaces
-%D makes clear how incomplete other faces are. To honour 7~bit
-%D \ASCII, these fonts were designed using only the first 127
-%D values of the 256 ones that can be presented by one byte.
-%D Nowadays 8~bit character codings are more common, mainly
-%D because they permit us to predefine some composed
-%D characters, which are needed in most european languages.
-%D
-%D Supporting more than the standard \TEX\ encoding vector
-%D |<|which in itself is far from standard and differs per
-%D font|>| puts a burden on the fonts mechanism. The \CONTEXT\
-%D mechanism is far from complete, but can handle several
-%D schemes at once. The main problem lays in the accented
-%D characters and ligatures like~ff, although handling
-%D ligatures is not the responsibility of this module.
-%D
-%D By default, we use \PLAIN\ \TEX's approach of placing
-%D accents. All other schemes sooner or later give problems
-%D when we distribute \DVI||files are distributed across
-%D machines and platforms. Nevertheless, we have to take care
-%D of different encoding vectors, which tell us where to find
-%D the characters we need. This means that all kind of
-%D character placement macro's like \type{\"} and \type{\ae}
-%D have to be implemented and adapted in a way that suits
-%D these vectors.
-%D
-%D The main difference between different vector is the way
-%D accents are ordered and/or the availability of prebuilt
-%D accented characters. Accented characters can for instance be
-%D called for by sequences like \type{\"e}. Here the \type{\"}
-%D is defined as:
-%D
-%D \starttyping
-%D \def\"#1{{\accent"7F #1}}
-%D \stoptyping
-%D
-%D This macro places the accent \accent"7F {} on top of an~e
-%D gives \"e. Some fonts however can have prebuild accents and
-%D use a more direct approach like
-%D
-%D \starttyping
-%D \def\"#1{\if#1e\char 235\else ... \fi}
-%D \stoptyping
-%D
-%D The latter approach is not used in \CONTEXT, because we
-%D store relevant combinations of accents and characters in
-%D individual macros.
-
-%D We define character substitutes and commands with definition
-%D commands like:
-%D
-%D \starttyping
-%D \startcoding[texnansi]
-%D
-%D \defineaccent " a 228
-%D \defineaccent ^ e 234
-%D \defineaccent ' {\dotlessi} 237
-%D
-%D \definecharacter ae 230
-%D \definecharacter oe 156
-%D
-%D \definecommand b \texnansiencodedb
-%D \definecommand c \texnansiencodedc
-%D
-%D \stopcoding
-%D \stoptyping
-%D
-%D The last argument of \type{\defineaccent} and
-%D \type{\definecharacter} tells \TEX\ the position of the
-%D accented character in the encoding vector. In order to
-%D complish this, we tag each implementation with the character
-%D coding identifier. We therefore need two auxiliary variables
-%D \type{\characterencoding} and \type{\nocharacterencoding}. These
-%D contain the current and default encoding vectors and both
-%D default to the \PLAIN\ one.
-
-\edef\characterencoding {@\s!default @}
-\edef\nocharacterencoding {@\s!default @}
-\edef\charactermapping {@\s!default @}
-
-% todo, else \d j == \dj, print file and check
-
-\def\accentprefix {}%{*}
-\def\commandprefix {}%{=}
-\def\characterprefix{}%{-}
-
-%D \macros
-%D {startcoding, reducetocoding}
-%D
-%D Before we can redefine accents and special characters, we
-%D have to tell \CONTEXT\ what encoding is in force. The next
-%D command is responsible for doing this and also takes care of
-%D the definition of the recoding commands. We use the \type
-%D {\start}||\type {\stop}||commands for definitions and the
-%D \type {\reduceto}||command for local switching to
-%D simplified commands.
-
-% etex : \ifcsname
-
-\def\justhandleaccent#1#2% \empty makes #2={} save % no \unexpanded
- {\ifundefined{\accentprefix\characterencoding#1\string#2\empty}%
- #2%
- \else
- \csname\accentprefix\characterencoding#1\string#2\empty\endcsname
- \fi}
-
-\def\justhandlecommand#1% % no \unexpanded, otherwise pdfdoc will fail
- {\ifundefined{\commandprefix\characterencoding#1}% as well as hyph patterns
- #1%
- \else
- \csname\commandprefix\characterencoding#1\endcsname
- \fi}
-
-\def\enableencoding
- {\dodoubleempty\doenableencoding}
-
-\def\doenableencoding[#1][#2]% main fallback
- {\iffirstargument\edef\characterencoding{@#1@}\fi
- \edef\nocharacterencoding{@\ifsecondargument#2\else\s!default\fi @}%
- \synchronizepatterns}
-
-\edef\xnocharacterencoding{@\s!default @}
-
-\def\fastenableencoding#1%
- {\edef\characterencoding{@#1@}%
- \let\nocharacterencoding\xnocharacterencoding}
-
-\def\startencoding
- {\dodoubleempty\dostartencoding}
-
-\def\dostartencoding[#1][#2]% encoding regime
- {%\showmessage\m!encodings1{#1}%
- \pushmacro\characterencoding
- \pushmacro\currentregime
- \pushmacro\dohandleaccent % still needed?
- \pushmacro\dohandlecommand % still needed?
- \pushmacro\doautosetregime
- \let\dohandleaccent\donthandleaccent % still needed?
- \let\dohandlecommand\donthandlecommand % still needed?
- %let\definesortkey\savesortkey
- \edef\characterencoding{@#1@}%
- \doifelsenothing{#2}%
- {\let\doautosetregime\gobbletwoarguments}
- {\def\currentregime{#2}}}
-
-\def\stopencoding
- {\popmacro\doautosetregime
- \popmacro\dohandlecommand % still needed?
- \popmacro\dohandleaccent % still needed?
- \popmacro\currentregime
- \popmacro\characterencoding}
-
-% probably obsolete (hm, not yet)
-
-\def\reducetocoding[#1]% use grouped!
- {\doifsomething{#1}
- {\let\dohandleaccent \justhandleaccent
- \let\dohandlecommand\justhandlecommand
- \enableencoding[#1]%
- \enablelanguagespecifics[\currentlanguage]}}
-
-\let\startcoding \startencoding
-\def\stopcoding {\stopencoding}
-\let\enablecoding \enableencoding
-
-%D The use of these macros are not limited to font
-%D definition files, but may also be used when loading
-%D patterns.
-
-%D \macros
-%D {definesortkey,flushsortkeys,flushsortkey}
-%D
-%D Yet another definition concerns sorting of indexes and
-%D lists.
-%D
-%D \starttyping
-%D \definesortkey {\'e} {e} {a} {\'e}
-%D \stoptyping
-%D
-%D The first argument denotes the string to be treated. The
-%D second argument is the raw replacement, while the third
-%D argument determines the sort order given the replacement.
-%D The last argument is used as entry in the index (a, b, etc).
-%D
-%D The keys can be flushed using \type {\flushsortkeys}
-%D which in turn results in a sequence of calls to \type
-%D {\flushsortkey}, a macro taking 4~arguments.
-%D
-%D This mechanism is currently being tested and subjected to
-%D changes! Obsolete:
-
-\let\definesortkey\gobblefourarguments
-\let\savesortkey \gobblefourarguments
-\let\flushsortkeys\relax
-\let\flushsortkey \relax
-
-%D \macros
-%D {defineaccent, definecharacter, definecommand}
-%D
-%D The actual definition of accents, special characters and
-%D commands is done with the next three commands.
-
-\def\defineaccent
- {\protectfontcharacters
- \dodefineaccent}
-
-\def\dodefineaccent#1 #2 %
- {\unprotectfontcharacters
- \dododefineaccent#1 #2 }
-
-\def\dododefineaccent#1 #2 #3 %
- {\setvalue{#1}{\dohandleaccent{#1}}%
- \doifnumberelse{\string#3}
- {\setvalue{\accentprefix\characterencoding#1\string#2}{\char#3 }} % space added
- {\setvalue{\accentprefix\characterencoding#1\string#2}{#3}}}
-
-\def\dohandleaccent#1#2%
- {\ifcsname\accentprefix\characterencoding#1\string#2\empty\endcsname
- \csname\accentprefix\characterencoding#1\string#2\empty\endcsname
- \else\ifcsname\accentprefix\nocharacterencoding#1\string#2\empty\endcsname
- \csname\accentprefix\nocharacterencoding#1\string#2\empty\endcsname
- \else\ifcsname\accentprefix\characterencoding#1\endcsname
- \csname\accentprefix\characterencoding#1\endcsname{#2}%
- \else%\ifcsname\accentprefix\nocharacterencoding#1\endcsname
- \csname\accentprefix\nocharacterencoding#1\endcsname{#2}%
-% \else
-% \donormaltextaccent{#1}{#2}%
- \fi\fi\fi}%\fi}
-
-%D In patterns, characters have to be bytes. These will be
-%D mapped onto the compact pattern arrays.
-
-\let\normalpatterns \patterns
-\let\normalhyphenation\hyphenation
-
-\def\patternchar#1 {\rawcharacter{#1}} % space is part of character definition !
-
-% \ifx \enablepatterntokens\undefined
-% \def\handlepatterntoken#1]{\csname#1\endcsname}
-% \fi
-
-% we need to postpone catcode changes, e.g. hr patterns
-% have \catcode" -> which fails when " is letter
-
-\def\pathypsettings
- {\ifx \enablepatterntokens\undefined
- \defineactivecharacter [ {\handlepatterntoken}%
- \else
- \enablepatterntokens
- \fi
- \let\dochar\thechr
- \lccode16=16 % brrr, extra quote in ec (turkish)
- \lccode17=17 % brrr, extra quote in ec (turkish)
- \lccode`\-=`\-
- \lccode`\'=`\'
- \lccode`\"=`\"
- \relax}
-
-\def\patterns {\pathypsettings\normalpatterns }
-\def\hyphenation{\pathypsettings\normalhyphenation}
-
-%D Because we don't want to use the second command grouped, we
-%D (re)define it as follows:
-
-\def\hyphenation
- {\begingroup\def\hyphenation{\normalhyphenation{\the\scratchtoks}\endgroup}%
- \pathypsettings\afterassignment\hyphenation\scratchtoks=}
-
-%D This is not needed for patterns because they are loaded grouped
-%D anyway and it saves us an assignment. Can go ... no longer
-%D shared patterns.
-
-\def\startpatternloading#1#2#3% % we should use \everypatternloading
- {\startreadingfile
- \bgroup
- % let's get rid of interfering stuff
- \let\everyjob\scratchtoks
- \let\message \gobbleoneargument
- % we want direct characters
- \let\char\patternchar
- \doifelsenothing{#2}{\enableencoding[ec]}{\enableencoding[#2]}%
- \doifelsenothing{#3}{\enablemapping [ec]}{\enablemapping [#3]}%
- \expanded{\doifinstring{\f!languageprefix}{#1}}
- {\ifx \enablepatternxml\undefined \else
- \enablepatternxml
- \fi}%
- \let\dohandleaccent\normaldohandleaccent}
-
-\def\stoppatternloading
- {\egroup
- \stopreadingfile}
-
- \def\thechr#1{\char#1 } % just in case \relax interferes
-\unexpanded\def\numchr#1{\char#1\relax}
-\unexpanded\def\strchr#1{\csname#1\endcsname}
-
-\let\dochar\numchr
-
-\def\startdirectcharacters {\pushmacro\dochar \let\dochar\thechr}
-\def\stopdirectcharacters {\popmacro \dochar}
-
-\def\definecharacter#1 #2 %
- {\ifundefined{#1}\setvalue{#1}{\dohandlecharacter{#1}}\fi
- \doifnumberelse{\string#2}
- {\setvalue{\characterprefix\characterencoding\string#1}{\dochar{#2}}%
- \doautosetregime{#1}{#2}}
- {\setvalue{\characterprefix\characterencoding\string#1}{#2}}}
-
-\def\dohandlecharacter#1%
- {\csname\characterprefix\ifcsname\characterprefix\characterencoding#1\endcsname
- \characterencoding\else\nocharacterencoding\fi#1\endcsname}
-
-% \def\fallbackpatternchar{x} % makes no sense, duplicate patterns
-
-\def\defaultcharacter#1%
- {\csname\characterprefix\nocharacterencoding\strippedcsname#1\endcsname}
-
-%D Instead of numbers, a command may be entered.
-
-\def\definecommand#1 #2 %
- {\setvalue{\string#1}{\dohandlecommand{#1}}%
- %\redefinecommand #1 % just to be sure
- \setvalue{\commandprefix\characterencoding\string#1}{#2}}
-
-%D Here we see that redefining accents is characters is more
-%D or less the same as redefining commands. We also could have
-%D said:
-%D
-%D \starttyping
-%D \def\defineaccent#1 #2 {\definecommand#1\string#2 \char}
-%D \def\definecharacter#1 {\definecommand#1 \char}
-%D \stoptyping
-
-%D \macros
-%D {defineaccentcommand}
-%D
-%D When needed, one can overload the default positions of the
-%D accents. The \PLAIN\ \TEX\ defaults are:
-%D
-%D \starttyping
-%D \defineaccentcommand ` 18
-%D \defineaccentcommand ' 19
-%D \defineaccentcommand v 20
-%D \defineaccentcommand u 21
-%D \defineaccentcommand = 22
-%D \defineaccentcommand ^ 94
-%D \defineaccentcommand . 95
-%D \defineaccentcommand H 125 % "7D
-%D \defineaccentcommand ~ 126 % "7E
-%D \defineaccentcommand " 127 % "7F
-%D \stoptyping
-
-\def\defineaccentcommand
- {\protectfontcharacters
- \dodefineaccentcommand}
-
-\def\dodefineaccentcommand#1 #2 % \string toegevoegd
- {\doifnumberelse{\string#2}
- {\setvalue{\accentprefix\characterencoding\string#1}##1{{\accent#2 ##1}}}
- {\setvalue{\accentprefix\characterencoding\string#1}##1{{#2##1}}}%
- \unprotectfontcharacters}
-
-%D We don't have to define them for the default \PLAIN\ case.
-%D Commands may be used instead of character codes.
-
-%D \macros
-%D {normalaccent,normalchar}
-%D
-%D Accents are either placed by \TEX's \type {\accent}
-%D primitive, or part of the glyph. By default the former
-%D method is used, unless overruled in the encoding
-%D definitions.
-
-\let\normalchar =\char
-\let\normalaccent=\accent
-
-%D \macros
-%D {redefinecommand}
-%D
-%D Redefinition of encoding dependant commands like \type{\b}
-%D and \type{\c} can be triggered by:
-%D
-%D \starttyping
-%D \redefinecommand b % something math
-%D \redefinecommand c % something math
-%D \stoptyping
-%D
-%D Handling of characters is easier than handling accents
-%D because here we don't have to take care of arguments. We
-%D just call for the right glyph in the right place.
-%D
-%D The \type{\next} construction permits handling of commands
-%D that take arguments. This means that we can use this
-%D command to redefine accent handling commands too
-%D (although today the next is not needed any longer in test
-%D macros).
-
-\def\redefinecommand#1 %
- {% no \unexpanded, else pdfdoc fails
- \setvalue{\string#1}{\dohandlecommand{#1}}}%
-
-\def\dohandlecommand#1%
- {\csname\commandprefix
- \ifcsname\commandprefix\characterencoding#1\endcsname
- \characterencoding
- \else
- \nocharacterencoding
- \fi
- #1\endcsname}
-
-%D \macros
-%D {currentencoding, currentmapping}
-%D
-%D When we show 'm, we don't want to see the protection
-%D measures.
-
-\def\currentencoding{\@EA\dopureencodingname\characterencoding}
-\def\currentmapping {\@EA\dopureencodingname\charactermapping }
-
-\def\dopureencodingname @#1@{#1}
-
-\def\pureencodingname#1{\@EA\dopureencodingname#1}
-
-%D \macros
-%D {showaccents, showcharacters,
-%D showcharacterbounds, showhyphenations}
-%D
-%D Encoding is a tricky business. Therefore we provide a
-%D a few macros that show most of the characters involved. The
-%D next two tables show the result of \type {\showaccents}.
-%D
-%D \placetable
-%D {The special glyphs in default encoding.}
-%D {\showaccents}
-%D
-%D \placetable
-%D {The special glyphs in texnansi encoding.}
-%D {\switchtobodyfont[lbr]\showaccents}
-%D
-%D The command
-%D
-%D \starttyping
-%D \showhyphenations{doordefini\"eren}
-%D \stoptyping
-%D
-%D can be used to check the correct loading of hyphenation
-%D patterns.
-
-\fetchruntimecommand \showaccents {\f!encodingprefix\s!run}
-\fetchruntimecommand \showcharacters {\f!encodingprefix\s!run}
-\fetchruntimecommand \showcharacterbounds {\f!encodingprefix\s!run}
-\fetchruntimecommand \showhyphenations {\f!encodingprefix\s!run}
-\fetchruntimecommand \showmapping {\f!encodingprefix\s!run}
-
-%D \macros
-%D {everyuppercase, EveryUppercase,
-%D everyuppercase, EveryUppercase}
-%D
-%D When we want to uppercase strings of characters, we have to
-%D take care of those characters that have a special meaning or
-%D are only accessible by means of macros. The next hack was
-%D introduced when Tobias Burnus started translating head and
-%D label texts into spanish and italian. The first application
-%D of this token register therefore can be found in the module
-%D that deals with these texts.
-
-\newevery \everyuppercase \EveryUppercase
-\newevery \everylowercase \EveryLowercase
-
-%D This magic trick maps takes care of mapping from lower to
-%D upper case and reverse.
-
-\def\reloadmapping{\the\executeifdefined{\@cas@\charactermapping}\emptytoks}
-
-\appendtoks\let\setuppercasecom\setcasecom\to\everyuppercase
-\appendtoks\let\setlowercasecom\setcasecom\to\everylowercase
-
-\appendtoks\reloadmapping\to\everyuppercase % slow, will be sped up
-\appendtoks\reloadmapping\to\everylowercase % slow, will be sped up
-
-\newtoks\everyULmap
-
-\appendtoks\let\remapcase\remapuppercase\the\everyULmap\to\everyuppercase
-\appendtoks\let\remapcase\remaplowercase\the\everyULmap\to\everylowercase
-
-\let\remapcase\gobbletwoarguments
-
-\def\remapuppercase#1#2{\let#2#1} % more efficient:
-\def\remaplowercase#1#2{\let#1#2} \let\remaplowercase\let
-
-\def\defineLCcharacter #1 #2 %
- {\appendtoks\let\to\everylowercase
- \@EA\appendtoks\csname#1\endcsname\to\everylowercase
- \@EA\appendtoks\csname#2\endcsname\to\everylowercase}
-
-\def\defineUCcharacter #1 #2 %
- {\appendtoks\let\to\everyuppercase
- \@EA\appendtoks\csname#1\endcsname\to\everyuppercase
- \@EA\appendtoks\csname#2\endcsname\to\everyuppercase}
-
-\def\defineULcharacter #1 #2 %
- {\appendtoks\remapcase\to\everyULmap
- \@EA\appendtoks\csname#1\endcsname\to\everyULmap
- \@EA\appendtoks\csname#2\endcsname\to\everyULmap}
-
-% slightly faster with \smallcapped's but far more hash and stringspace
-%
-% \newif\ifuppercase \appendtoks\uppercasetrue\to\everyuppercase
-% \newif\iflowercase \appendtoks\lowercasetrue\to\everylowercase
-%
-% \def\defineULcharacter #1 #2 %
-% {\def\!!stringa{@#1}\@EA\letvalue\@EA\!!stringa\csname#1\endcsname
-% \def\!!stringa{@#2}\@EA\letvalue\@EA\!!stringa\csname#2\endcsname
-% \setvalue{#1}{\getvalue{@\ifuppercase#2\else#1\fi}}%
-% \setvalue{#2}{\getvalue{@\iflowercase#1\else#2\fi}}}
-
-% 2 = tricky, since expanding \definedfont[lowcasename] ... goes wrong
-
-\chardef\uppercasemode\plusthree % 0=ignore 1=normal 2=expand 3=auto
-\chardef\casecommode \plusone % 0=noexpand 1=expand
-
-\def\setcasecom #1#2{\def#1{\ifcase\casecommode\noexpand#1\else#2\fi}}
-
-% \def\OEPS{whatever}
-%
-% \startmapping[ec]
-% \defineuppercasecom \oeps {\getvalue{OEPS}}
-% \stopmapping
-%
-% \WORD{xx \oeps}
-
-\def\douppercase#1%
- {\bgroup
- \let\douppercase\firstofoneargument
- \the\everyuppercase % currently also checks uppercasemode
- \let\dochar\rawcharacter
- \ifcase\uppercasemode
- #1%
- \or % No expansion here, otherwise \getvalue problems! Default!!!
- %\edef\next{#1}% keep this to prevent roll back
- %\uppercase\expandafter{\next}% keep this to prevent roll back
- \uppercase{#1}%
- \or
- \chardef\casecommode\zerocount
- \let\docasecom\firstoftwoarguments
- \edef\ascii{#1}%
- \edef\ascii{\expandafter\uppercase\expandafter{\ascii}}% needed when in regime
- \chardef\casecommode\plusone
- \ascii
- \else
- % mode three may trigger setting 2 elsewhere (e.g. regime test)
- \uppercase{#1}%
- \fi
- \egroup}
-
-\prependtoksonce
- \doifnot\currentregime\s!default
- {\ifnum\uppercasemode=\plusthree \chardef\uppercasemode\plustwo \fi}%
-\to \everyuppercase
-
-%D \macros
-%D {everysanitize, EverySanitize}
-%D
-%D Whenever we are sanitizing strings, like we sometimes do
-%D when we deal with specials, the next token register can be
-%D called.
-
-\newevery \everysanitize \EverySanitize
-
-%D \macros
-%D {defineuclass,defineudigit,udigit}
-%D
-%D The next few macros are experimental and needed for unicoded
-%D chinese characters.
-
-\def\defineuclass #1 #2 #3 %
- {\setvalue{uc\the\numexpr#2*256+#3\relax}{#1}}
-
-\def\defineudigit #1 #2 #3 {\setvalue{\characterencoding uc#1}{\uchar{#2}{#3}}}
-
-%D It may look strange, but for the moment, we want the encoding
-%D to be part of the digit specification. This may change!
-
-\unexpanded\def\udigit#1#2{\getvalue{@#1@uc\number#2}}
-
-%D \macros
-%D {uchar, octuchar, hexuchar}
-
-\ifx\uchar\undefined \def\uchar#1#2{(\number#1,\number#2)} \fi
-
-\def\octuchar#1#2{\uchar{`#1}{`#2}}
-\def\hexuchar#1#2{\uchar{"#1}{"#2}}
-
-%D Basics and fallbacks.
-
-\newif\ifignoreaccent
-
-\let\textaccent \accent
-
-\let\normalaccent \accent
-\let\normaltextaccent\textaccent
-\let\normalmathaccent\mathaccent
-\let\normalchar \char
-
-% ** we will explicitly embrace the two arguments, since in definitions
-% this may not be the case, and we don't want faulty expansions like
-% "\dobuildtextaccent \char 18 a" but "\dobuildtextaccent {\char 18}{a}"
-% instead
-
-\def\buildmathaccent#1%
- {\mathaccent#1 }
-
-\def\buildtextaccent#1#2% **
- {\ifignoreaccent
- \expandafter\nobuildtextaccent
- \else
- \expandafter\dobuildtextaccent
- \fi{#1}{#2}}
-
-\unexpanded\def\nobuildtextaccent#1#2%
- {#2}
-
-\unexpanded\def\dobuildtextaccent#1#2%
- {{\let\char\normalaccent#1\let\char\normalchar#2}}
-
-% EVENTUALLY THIS CODE WILL MOVE TO AN mkiv module
-
-\beginLUATEX
-
-\newbox\accenttestbox
-
-\unexpanded\def\dobuildtextaccent#1#2%
- {\begingroup
- \global\setbox\accenttestbox\hbox{#1}%
- \scratchcounter\ctxlua{characters.charcode(\number\accenttestbox)}%
- \ifcase\scratchcounter\else\accent\scratchcounter\fi
- \relax#2%
- \endgroup}
-
-\endLUATEX
-
-% some fake ones, name will change into build
-
-\unexpanded\def\bottomaccent#1#2#3#4#5% down right slantcorrection accent char
- {\dontleavehmode % why this align mess
- \vtop
- {\forgetall
- \baselineskip\zeropoint
- \lineskip#1%
- \everycr\emptytoks
- \tabskip\zeropoint
- \lineskiplimit\zeropoint
- \setbox0\hbox{#4}%
- \halign
- {##\crcr\hbox{#5}\crcr
- \hidewidth
- \hskip#2\wd0
- \hskip-#3\slantperpoint % in plain 1ex * dimenless value
- \vbox to .2ex{\box0\vss}\hidewidth
- \crcr}}}
-
-\def\buildtextmacron {\bottomaccent{.25ex}{0}{15}{\textmacron}}
-\def\buildtextbottomdot{\bottomaccent{.25ex}{0}{5}{\textbottomdot}}
-\def\buildtextcedilla {\bottomaccent{0ex}{0}{5}{\textcedilla}}
-\def\buildtextogonek {\bottomaccent{-.1ex}{.5}{0}{\textogonek}}
-
-%D A collectors item:
-
-\def\buildtextbottomcomma{\bottomaccent{.15ex}{0}{5}{\tx,}}
-
-%D Rarely needed but there:
-
-\unexpanded\def\topaccent#1#2#3#4#5% down right slantcorrection accent char
- {\dontleavehmode
- \bgroup
- \setbox0\hbox{#4}%
- \setbox2\hbox{#5}%
- \hbox to \wd2 \bgroup
- \hss\copy2\hss
- \hskip-\wd2
- \hss\hskip#2\wd0\hskip-#3\slantperpoint\raise#1\hbox{#4}\hss
- \egroup
- \egroup}
-
-\def\buildtextgrave{\topaccent{0pt}{0}{15}{\textgrave}} % e.g.
-
-% \definecharacter schwa {\hbox{\rotate[rotation=180,location=high]{\hbox{e}}}}
-% \definecharacter schwagrave {\buildtextgrave\schwa}
-
-% math stuff, will change
-
-\def\definemathaccent#1 #2%
- {\setvalue{\string#1}{#2}%
- \setvalue{normalmathaccent\string#1}{#2}}
-
-\def\donormalmathaccent#1%
- {\getvalue{normalmathaccent\string#1}}
-
-%D Some precautions:
-
-\ifx\usepdffontresource\undefined
- \def\usepdffontresource #1 {} % this will be defined elsewhere
-\fi
-
-\def\donthandleaccent #1{\expandafter\string\csname#1\endcsname\space}
-\def\donthandlecommand #1{\expandafter\string\csname#1\endcsname\space}
-\def\donthandlecharacter #1{\expandafter\string\csname#1\endcsname\space}
-
-\def\stringifyhandleaccent #1{\strchr{#1}}
-\def\stringifyhandlecommand #1{\strchr{#1}}
-\def\stringifyhandlecharacter#1{\strchr{#1}}
-
-\def\keephandleaccent #1{\expandafter\noexpand\csname#1\endcsname}
-\def\keephandlecommand #1{\expandafter\noexpand\csname#1\endcsname}
-\def\keephandlecharacter #1{\expandafter\noexpand\csname#1\endcsname}
-
-\def\handleaccent #1{\csname#1\endcsname}
-\def\handlecommand #1{\csname#1\endcsname}
-\def\handlecharacter #1{\csname#1\endcsname}
-
-\def\dontexpandencoding
- {\let\dohandleaccent \donthandleaccent
- \let\dohandlecommand \donthandlecommand
- \let\dohandlecharacter\donthandlecharacter}
-
-\def\keepencodedtokens
- {\let\dohandleaccent \keephandleaccent
- \let\dohandlecommand \keephandlecommand
- \let\dohandlecharacter\keephandlecharacter}
-
-\def\literateencodedtokens
- {% \let\dohandleaccent \keephandleaccent
- % \let\dohandlecommand \keephandlecommand
- \let\dohandlecharacter\keephandlecharacter}
-
-\def\stringifyencodedtokens
- {% \let\dohandleaccent \stringifyhandleaccent
- % \let\dohandlecommand \stringifyhandlecommand
- \let\dohandlecharacter\stringifyhandlecharacter}
-
-\unexpanded\def\uhandleaccent #1{\csname#1\endcsname}
-\unexpanded\def\uhandlecommand #1{\csname#1\endcsname}
-\unexpanded\def\uhandlecharacter#1{\csname#1\endcsname}
-
-\def\dontexpandencodedtokens
- {\def\dohandleaccent {\uhandleaccent}%
- \def\dohandlecommand {\uhandlecommand}%
- \def\dohandlecharacter{\uhandlecharacter}}
-
-% no longer: \def\convertencodedtokens{\dontexpandencoding} but:
-
-\def\convertencodedtokens{\stringifyencodedtokens}
-
-% test case:
-%
-% \enableregime[cp1250]
-% \mainlanguage[cz]
-%
-% \starttext
-%
-% \title{luouc kon p}
-% \placelist[chapter][criterium=all]
-%
-% \startbuffer
-% <chapter>
-% <title>luouc kon p</title>
-% </chapter>
-% \stopbuffer
-%
-% \defineXMLenvironment
-% [chapter]
-% {\defineXMLsave[title]}
-% {\expanded{\chapter{\XMLflush{title}}}}
-% \processXMLbuffer
-%
-% \setuphead[chapter][expansion=yes]
-% \defineXMLenvironment
-% [chapter]
-% {\defineXMLsave[title]}
-% {\chapter{\XMLflush{title}}}
-% \processXMLbuffer
-%
-% \stoptext
-
-%D Still valid? To be checked:
-
-\def\doignoreaccent #1#2{\string#1\string#2}%
-\def\doignorecommand #1{\string#1}
-\def\doignorecharacter#1{\string#1}
-
-\def\ignoreencoding
- {\let\dohandleaccent \doignoreaccent
- \let\dohandlecommand \doignorecommand
- \let\dohandlecharacter\doignorecharacter}
-
-\appendtoks
- \ignoreencoding
-\to \everycleanupfeatures
-
-\appendtoks
- \keepencodedtokens
-\to \everysafeexpanded
-
-%D Now we will not redefine any more, so:
-
-\let\normaldohandleaccent \dohandleaccent
-\let\normaldohandlecharacter\dohandlecharacter
-
-%D We preload several encodings:
-
-\loadmarkfile{enco-ini}
-
-\definecommand ` {\buildtextaccent\textgrave}
-\definecommand ' {\buildtextaccent\textacute}
-\definecommand r {\buildtextaccent\textring}
-\definecommand v {\buildtextaccent\textcaron}
-\definecommand u {\buildtextaccent\textbreve}
-\definecommand = {\buildtextaccent\textmacron}
-\definecommand ^ {\buildtextaccent\textcircumflex}
-\definecommand . {\buildtextaccent\textdotaccent}
-\definecommand H {\buildtextaccent\texthungarumlaut}
-\definecommand ~ {\buildtextaccent\texttilde}
-\definecommand " {\buildtextaccent\textdiaeresis}
-
-\definecommand c {\buildtextcedilla}
-\definecommand b {\buildtextmacron}
-\definecommand d {\buildtextbottomdot}
-\definecommand k {\buildtextogonek}
-
-\definemathaccent acute {\buildmathaccent\mathacute}
-\definemathaccent grave {\buildmathaccent\mathgrave}
-\definemathaccent ddot {\buildmathaccent\mathddot}
-\definemathaccent tilde {\buildmathaccent\mathtilde}
-\definemathaccent bar {\buildmathaccent\mathbar}
-\definemathaccent breve {\buildmathaccent\mathbreve}
-\definemathaccent check {\buildmathaccent\mathcheck}
-\definemathaccent hat {\buildmathaccent\mathhat}
-\definemathaccent vec {\buildmathaccent\mathvec}
-\definemathaccent dot {\buildmathaccent\mathdot}
-\definemathaccent widetilde {\buildmathaccent\mathwidetilde}
-\definemathaccent widehat {\buildmathaccent\mathwidehat}
-
-\useencoding[def] % defaults (partly simplified)
-\useencoding[acc] % accent commands
-\useencoding[raw] % simplified (incomplete)
-\useencoding[com] % a few commands
-\useencoding[cas] % case mapping, not needed in mkiv
-\useencoding[mis] % a few commands
-
-% \useencoding[ans,il2,ec,tbo,pdf,uc,pol,qx,t5,cyr,agr] % pol and il2 will go away, not needed in mkiv
-% \useencoding[032,033,037] % fallbacks for some unicode chars
-% \setupencoding[\s!default=ec] % was: [\s!default=\s!default]
-
-\protect \endinput
diff --git a/tex/context/base/enco-mis.tex b/tex/context/base/enco-mis.tex
index b04d4ab7d..92dc61b3f 100644
--- a/tex/context/base/enco-mis.tex
+++ b/tex/context/base/enco-mis.tex
@@ -36,30 +36,6 @@
\unprotect
-% \def\pseudoencodeddj % like in babel
-% {\leavevmode\hbox\bgroup
-% \setbox0\hbox{d}%
-% \dimen0=\ht0
-% \advance\dimen0 1ex
-% \dimen0=.45\dimen0
-% \dimen2=\withoutpt\the\slantperpoint\dimen0
-% \advance\dimen2 .5ex
-% \rlap{\raise\dimen0\hbox{\kern\dimen2\vbox{\hrule\!!height0.1ex\!!width0.3em}}}%
-% \box0
-% \egroup}
-%
-% \def\pseudoencodedDJ % like in babel
-% {\leavevmode
-% \hbox\bgroup
-% \setbox0\hbox{D}%
-% \dimen0=.55\ht0
-% \dimen2=\withoutpt\the\slantperpoint\dimen0
-% \advance\dimen2 .15ex
-% \advance\dimen2 -.15\extraspace
-% \rlap{\raise\dimen0\hbox{\kern\dimen2\vbox{\hrule\!!height0.1ex\!!width0.33em}}}%
-% \box0
-% \egroup}
-
\def\pseudoencodeddj % like in babel, but safer
{\dontleavehmode\hbox\bgroup
\setbox\scratchbox\hbox{d}%
@@ -73,19 +49,6 @@
\raise\scratchdimen\hbox{\kern\dimen2\vbox{\hrule\!!height0.1ex\!!width0.3em}}}%
\egroup}
-% \def\pseudoencodedDJ % like in babel, but safer
-% {\leavevmode
-% \hbox\bgroup
-% \setbox\scratchbox\hbox{D}%
-% \scratchdimen.55\ht\scratchbox
-% \dimen2=\withoutpt\the\slantperpoint\scratchdimen
-% \advance\dimen2 .15ex
-% \advance\dimen2 -.15\extraspace
-% \hbox to \wd\scratchbox
-% {\box\scratchbox\hss
-% \raise\scratchdimen\hbox{\kern\dimen2\vbox{\hrule\!!height0.1ex\!!width0.3em}}}%
-% \egroup}
-
\def\pseudoencodedDJ % design: taco; quality assurance: mojca; cleanup: hans
{\dontleavehmode
\hbox\bgroup
diff --git a/tex/context/base/enco-pfr.mkii b/tex/context/base/enco-pfr.mkii
deleted file mode 100644
index aec926e22..000000000
--- a/tex/context/base/enco-pfr.mkii
+++ /dev/null
@@ -1,20 +0,0 @@
-%D \module
-%D [ file=enco-pfr,
-%D version=2000.12.10, % adapted 2005.08.14 to more delayed loading
-%D title=\CONTEXT\ Encoding Macros,
-%D subtitle=PDF Font Resource Inclusion,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\pdfglyphtounicode\undefined \else
- \appendtoks
- \doif\jobsuffix{pdf}{\readfile{pdfr-def.tex}\donothing\donothing}%
- \to \everystarttext
-\fi
-
-\endinput
diff --git a/tex/context/base/enco-pfr.mkiv b/tex/context/base/enco-pfr.mkiv
deleted file mode 100644
index 52ef0cc3b..000000000
--- a/tex/context/base/enco-pfr.mkiv
+++ /dev/null
@@ -1,22 +0,0 @@
-%D \module
-%D [ file=enco-pfr,
-%D version=2000.12.10, % adapted 2005.08.14 to more delayed loading
-%D title=\CONTEXT\ Encoding Macros,
-%D subtitle=PDF Font Resource Inclusion,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% obsolete, at least for wide fonts, we may need to support it otherwise
-%
-% \ifx\pdfglyphtounicode\undefined \else
-% \appendtoks
-% \doif\jobsuffix{pdf}{\ctxlua{characters.setpdfunicodes()}}% pdftounicode mappings can only be done runtime
-% \to \everystarttext
-% \fi
-
-\endinput
diff --git a/tex/context/base/enco-pfr.tex b/tex/context/base/enco-pfr.tex
index 902eb7bcd..a90c62352 100644
--- a/tex/context/base/enco-pfr.tex
+++ b/tex/context/base/enco-pfr.tex
@@ -2,7 +2,7 @@
%D [ file=enco-pfr,
%D version=2000.12.10, % adapted 2005.08.14 to more delayed loading
%D title=\CONTEXT\ Encoding Macros,
-%D subtitle=PDF Font Resource Inclusion,
+%D subtitle=PDF Resources,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,17 +11,13 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\beginXETEX
+\ifnum\texengine>\pdftexengine
\endinput
-\endXETEX
-
-\beginLUATEX
- \endinput
-\endLUATEX
+\fi
\ifx\pdffontresource\undefined\else\endinput\fi
-\writestatus{loading}{Context Encoding Macros (pdf)}
+\writestatus{loading}{ConTeXt Encoding Macros / PDF Resources}
%D This is an experimental module in which we implement
%D font resource inclusion in \PDF. One reason to include
@@ -60,7 +56,11 @@
\newif\ifincludepdffontresources \includepdffontresourcestrue
-\ifx\pdfglyphtounicode\undefined \else \loadmarkfile{enco-pfr} \fi
+\ifx\pdfglyphtounicode\undefined \else
+ \appendtoks
+ \doif\jobsuffix{pdf}{\readfile{pdfr-def.tex}\donothing\donothing}%
+ \to \everystarttext
+\fi
% somehow we cannot preload this beast; also, it's mk dependent
%
diff --git a/tex/context/base/enco-run.tex b/tex/context/base/enco-run.tex
index 8e50e9398..50fb52e15 100644
--- a/tex/context/base/enco-run.tex
+++ b/tex/context/base/enco-run.tex
@@ -98,16 +98,7 @@
% {\font\test=uplr8t \test \ruledhbox{t}
% \font\test=uplr8r \test \ruledhbox{t}}
-\gdef\showcharacterbounds
- {\bgroup
- \localcolortrue
- \dorecurse{255}
- {\ifdim\fontcharwd\font\recurselevel>\zeropoint
- \noindent\ruledhbox{\darkgray\char\recurselevel}\space
- \fi}\unskip
- \egroup}
-
-\beginOLDTEX
+\ifnum\texengine=\pdftexengine
\gdef\showhyphenations#1%
{\starttabulate[|le|l|]
@@ -119,9 +110,28 @@
\NC sample \NC \hyphenatedword{#1} \NC \NR
\stoptabulate}
-\endOLDTEX
+ \gdef\showmapping
+ {\dostepwiserecurse{128}{255}{1}
+ {\hbox\bgroup
+ \hbox to 2em{\hss\recurselevel}%
+ \hbox to 2em{\hss\char\recurselevel\hss}%
+ \hbox to 3em{\hss\ifcase\lccode\recurselevel\else\the \lccode\recurselevel\fi}%
+ \hbox to 2em{\hss\ifcase\lccode\recurselevel\else\char\lccode\recurselevel\fi\hss}%
+ \hbox to 3em{\hss\ifcase\lccode\recurselevel\else\the \uccode\recurselevel\fi}%
+ \hbox to 2em{\hss\ifcase\uccode\recurselevel\else\char\uccode\recurselevel\fi\hss}%
+ \egroup
+ \endgraf}}
-\beginNEWTEX
+ \gdef\showcharacterbounds
+ {\bgroup
+ \localcolortrue
+ \dorecurse{255}
+ {\ifdim\fontcharwd\font\recurselevel>\zeropoint
+ \noindent\ruledhbox{\darkgray\char\recurselevel}\space
+ \fi}\unskip
+ \egroup}
+
+\else
\gdef\showhyphenations#1%
{\starttabulate[|le|l|]
@@ -130,18 +140,10 @@
\NC sample \NC \hyphenatedword{#1} \NC \NR
\stoptabulate}
-\endNEWTEX
-
-\gdef\showmapping
- {\dostepwiserecurse{128}{255}{1}
- {\hbox\bgroup
- \hbox to 2em{\hss\recurselevel}%
- \hbox to 2em{\hss\char\recurselevel\hss}%
- \hbox to 3em{\hss\ifcase\lccode\recurselevel\else\the \lccode\recurselevel\fi}%
- \hbox to 2em{\hss\ifcase\lccode\recurselevel\else\char\lccode\recurselevel\fi\hss}%
- \hbox to 3em{\hss\ifcase\lccode\recurselevel\else\the \uccode\recurselevel\fi}%
- \hbox to 2em{\hss\ifcase\uccode\recurselevel\else\char\uccode\recurselevel\fi\hss}%
- \egroup
- \endgraf}}
+ \globallet\showmapping\relax
+
+ \globallet\showcharacterbounds\relax
+
+\fi
\protect \endinput
diff --git a/tex/context/base/enco-t5.tex b/tex/context/base/enco-t5.tex
index ee9fa4856..251c68765 100644
--- a/tex/context/base/enco-t5.tex
+++ b/tex/context/base/enco-t5.tex
@@ -210,8 +210,8 @@
%
% \def\xfiveencodedAA%
% {\leavevmode
-% \setbox\z@\hbox{h}%
-% \dimen@\ht\z@
+% \setbox\zerocount\hbox{h}%
+% \dimen@\ht\zerocount
% \advance\dimen@ -1ex
% \rlap{\raise.67\dimen@\hbox{\char23}}A}
diff --git a/tex/context/base/enco-utf.tex b/tex/context/base/enco-utf.tex
deleted file mode 100644
index bfb427381..000000000
--- a/tex/context/base/enco-utf.tex
+++ /dev/null
@@ -1,3126 +0,0 @@
-% filename : enco-utf.tex
-% comment : generated by mtxrun --script chars --utf
-% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-% copyright: PRAGMA ADE / ConTeXt Development Team
-% license : see context related readme files
-
-\ifx\setcclcucx\undefined
-
- \def\setcclcucx #1 #2 #3 %
- {\global\catcode"#1=11
- \global\lccode "#1="#2
- \global\uccode "#1="#3 }
-
-\fi
-
-% lc/uc/catcode mappings
-
-\setcclcucx 0041 0061 0041 % LATIN CAPITAL LETTER A
-\setcclcucx 0042 0062 0042 % LATIN CAPITAL LETTER B
-\setcclcucx 0043 0063 0043 % LATIN CAPITAL LETTER C
-\setcclcucx 0044 0064 0044 % LATIN CAPITAL LETTER D
-\setcclcucx 0045 0065 0045 % LATIN CAPITAL LETTER E
-\setcclcucx 0046 0066 0046 % LATIN CAPITAL LETTER F
-\setcclcucx 0047 0067 0047 % LATIN CAPITAL LETTER G
-\setcclcucx 0048 0068 0048 % LATIN CAPITAL LETTER H
-\setcclcucx 0049 0069 0049 % LATIN CAPITAL LETTER I
-\setcclcucx 004A 006A 004A % LATIN CAPITAL LETTER J
-\setcclcucx 004B 006B 004B % LATIN CAPITAL LETTER K
-\setcclcucx 004C 006C 004C % LATIN CAPITAL LETTER L
-\setcclcucx 004D 006D 004D % LATIN CAPITAL LETTER M
-\setcclcucx 004E 006E 004E % LATIN CAPITAL LETTER N
-\setcclcucx 004F 006F 004F % LATIN CAPITAL LETTER O
-\setcclcucx 0050 0070 0050 % LATIN CAPITAL LETTER P
-\setcclcucx 0051 0071 0051 % LATIN CAPITAL LETTER Q
-\setcclcucx 0052 0072 0052 % LATIN CAPITAL LETTER R
-\setcclcucx 0053 0073 0053 % LATIN CAPITAL LETTER S
-\setcclcucx 0054 0074 0054 % LATIN CAPITAL LETTER T
-\setcclcucx 0055 0075 0055 % LATIN CAPITAL LETTER U
-\setcclcucx 0056 0076 0056 % LATIN CAPITAL LETTER V
-\setcclcucx 0057 0077 0057 % LATIN CAPITAL LETTER W
-\setcclcucx 0058 0078 0058 % LATIN CAPITAL LETTER X
-\setcclcucx 0059 0079 0059 % LATIN CAPITAL LETTER Y
-\setcclcucx 005A 007A 005A % LATIN CAPITAL LETTER Z
-\setcclcucx 0061 0061 0041 % LATIN SMALL LETTER A
-\setcclcucx 0062 0062 0042 % LATIN SMALL LETTER B
-\setcclcucx 0063 0063 0043 % LATIN SMALL LETTER C
-\setcclcucx 0064 0064 0044 % LATIN SMALL LETTER D
-\setcclcucx 0065 0065 0045 % LATIN SMALL LETTER E
-\setcclcucx 0066 0066 0046 % LATIN SMALL LETTER F
-\setcclcucx 0067 0067 0047 % LATIN SMALL LETTER G
-\setcclcucx 0068 0068 0048 % LATIN SMALL LETTER H
-\setcclcucx 0069 0069 0049 % LATIN SMALL LETTER I
-\setcclcucx 006A 006A 004A % LATIN SMALL LETTER J
-\setcclcucx 006B 006B 004B % LATIN SMALL LETTER K
-\setcclcucx 006C 006C 004C % LATIN SMALL LETTER L
-\setcclcucx 006D 006D 004D % LATIN SMALL LETTER M
-\setcclcucx 006E 006E 004E % LATIN SMALL LETTER N
-\setcclcucx 006F 006F 004F % LATIN SMALL LETTER O
-\setcclcucx 0070 0070 0050 % LATIN SMALL LETTER P
-\setcclcucx 0071 0071 0051 % LATIN SMALL LETTER Q
-\setcclcucx 0072 0072 0052 % LATIN SMALL LETTER R
-\setcclcucx 0073 0073 0053 % LATIN SMALL LETTER S
-\setcclcucx 0074 0074 0054 % LATIN SMALL LETTER T
-\setcclcucx 0075 0075 0055 % LATIN SMALL LETTER U
-\setcclcucx 0076 0076 0056 % LATIN SMALL LETTER V
-\setcclcucx 0077 0077 0057 % LATIN SMALL LETTER W
-\setcclcucx 0078 0078 0058 % LATIN SMALL LETTER X
-\setcclcucx 0079 0079 0059 % LATIN SMALL LETTER Y
-\setcclcucx 007A 007A 005A % LATIN SMALL LETTER Z
-\setcclcucx 00AA 00AA 00AA % FEMININE ORDINAL INDICATOR
-\setcclcucx 00B5 00B5 039C % MICRO SIGN
-\setcclcucx 00BA 00BA 00BA % MASCULINE ORDINAL INDICATOR
-\setcclcucx 00C0 00E0 00C0 % LATIN CAPITAL LETTER A WITH GRAVE
-\setcclcucx 00C1 00E1 00C1 % LATIN CAPITAL LETTER A WITH ACUTE
-\setcclcucx 00C2 00E2 00C2 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX
-\setcclcucx 00C3 00E3 00C3 % LATIN CAPITAL LETTER A WITH TILDE
-\setcclcucx 00C4 00E4 00C4 % LATIN CAPITAL LETTER A WITH DIAERESIS
-\setcclcucx 00C5 00E5 00C5 % LATIN CAPITAL LETTER A WITH RING ABOVE
-\setcclcucx 00C6 00E6 00C6 % LATIN CAPITAL LETTER AE
-\setcclcucx 00C7 00E7 00C7 % LATIN CAPITAL LETTER C WITH CEDILLA
-\setcclcucx 00C8 00E8 00C8 % LATIN CAPITAL LETTER E WITH GRAVE
-\setcclcucx 00C9 00E9 00C9 % LATIN CAPITAL LETTER E WITH ACUTE
-\setcclcucx 00CA 00EA 00CA % LATIN CAPITAL LETTER E WITH CIRCUMFLEX
-\setcclcucx 00CB 00EB 00CB % LATIN CAPITAL LETTER E WITH DIAERESIS
-\setcclcucx 00CC 00EC 00CC % LATIN CAPITAL LETTER I WITH GRAVE
-\setcclcucx 00CD 00ED 00CD % LATIN CAPITAL LETTER I WITH ACUTE
-\setcclcucx 00CE 00EE 00CE % LATIN CAPITAL LETTER I WITH CIRCUMFLEX
-\setcclcucx 00CF 00EF 00CF % LATIN CAPITAL LETTER I WITH DIAERESIS
-\setcclcucx 00D0 00F0 00D0 % LATIN CAPITAL LETTER ETH
-\setcclcucx 00D1 00F1 00D1 % LATIN CAPITAL LETTER N WITH TILDE
-\setcclcucx 00D2 00F2 00D2 % LATIN CAPITAL LETTER O WITH GRAVE
-\setcclcucx 00D3 00F3 00D3 % LATIN CAPITAL LETTER O WITH ACUTE
-\setcclcucx 00D4 00F4 00D4 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX
-\setcclcucx 00D5 00F5 00D5 % LATIN CAPITAL LETTER O WITH TILDE
-\setcclcucx 00D6 00F6 00D6 % LATIN CAPITAL LETTER O WITH DIAERESIS
-\setcclcucx 00D8 00F8 00D8 % LATIN CAPITAL LETTER O WITH STROKE
-\setcclcucx 00D9 00F9 00D9 % LATIN CAPITAL LETTER U WITH GRAVE
-\setcclcucx 00DA 00FA 00DA % LATIN CAPITAL LETTER U WITH ACUTE
-\setcclcucx 00DB 00FB 00DB % LATIN CAPITAL LETTER U WITH CIRCUMFLEX
-\setcclcucx 00DC 00FC 00DC % LATIN CAPITAL LETTER U WITH DIAERESIS
-\setcclcucx 00DD 00FD 00DD % LATIN CAPITAL LETTER Y WITH ACUTE
-\setcclcucx 00DE 00FE 00DE % LATIN CAPITAL LETTER THORN
-\setcclcucx 00DF 00DF 00DF % LATIN SMALL LETTER SHARP S
-\setcclcucx 00E0 00E0 00C0 % LATIN SMALL LETTER A WITH GRAVE
-\setcclcucx 00E1 00E1 00C1 % LATIN SMALL LETTER A WITH ACUTE
-\setcclcucx 00E2 00E2 00C2 % LATIN SMALL LETTER A WITH CIRCUMFLEX
-\setcclcucx 00E3 00E3 00C3 % LATIN SMALL LETTER A WITH TILDE
-\setcclcucx 00E4 00E4 00C4 % LATIN SMALL LETTER A WITH DIAERESIS
-\setcclcucx 00E5 00E5 00C5 % LATIN SMALL LETTER A WITH RING ABOVE
-\setcclcucx 00E6 00E6 00C6 % LATIN SMALL LETTER AE
-\setcclcucx 00E7 00E7 00C7 % LATIN SMALL LETTER C WITH CEDILLA
-\setcclcucx 00E8 00E8 00C8 % LATIN SMALL LETTER E WITH GRAVE
-\setcclcucx 00E9 00E9 00C9 % LATIN SMALL LETTER E WITH ACUTE
-\setcclcucx 00EA 00EA 00CA % LATIN SMALL LETTER E WITH CIRCUMFLEX
-\setcclcucx 00EB 00EB 00CB % LATIN SMALL LETTER E WITH DIAERESIS
-\setcclcucx 00EC 00EC 00CC % LATIN SMALL LETTER I WITH GRAVE
-\setcclcucx 00ED 00ED 00CD % LATIN SMALL LETTER I WITH ACUTE
-\setcclcucx 00EE 00EE 00CE % LATIN SMALL LETTER I WITH CIRCUMFLEX
-\setcclcucx 00EF 00EF 00CF % LATIN SMALL LETTER I WITH DIAERESIS
-\setcclcucx 00F0 00F0 00D0 % LATIN SMALL LETTER ETH
-\setcclcucx 00F1 00F1 00D1 % LATIN SMALL LETTER N WITH TILDE
-\setcclcucx 00F2 00F2 00D2 % LATIN SMALL LETTER O WITH GRAVE
-\setcclcucx 00F3 00F3 00D3 % LATIN SMALL LETTER O WITH ACUTE
-\setcclcucx 00F4 00F4 00D4 % LATIN SMALL LETTER O WITH CIRCUMFLEX
-\setcclcucx 00F5 00F5 00D5 % LATIN SMALL LETTER O WITH TILDE
-\setcclcucx 00F6 00F6 00D6 % LATIN SMALL LETTER O WITH DIAERESIS
-\setcclcucx 00F8 00F8 00D8 % LATIN SMALL LETTER O WITH STROKE
-\setcclcucx 00F9 00F9 00D9 % LATIN SMALL LETTER U WITH GRAVE
-\setcclcucx 00FA 00FA 00DA % LATIN SMALL LETTER U WITH ACUTE
-\setcclcucx 00FB 00FB 00DB % LATIN SMALL LETTER U WITH CIRCUMFLEX
-\setcclcucx 00FC 00FC 00DC % LATIN SMALL LETTER U WITH DIAERESIS
-\setcclcucx 00FD 00FD 00DD % LATIN SMALL LETTER Y WITH ACUTE
-\setcclcucx 00FE 00FE 00DE % LATIN SMALL LETTER THORN
-\setcclcucx 00FF 00FF 0178 % LATIN SMALL LETTER Y WITH DIAERESIS
-\setcclcucx 0100 0101 0100 % LATIN CAPITAL LETTER A WITH MACRON
-\setcclcucx 0101 0101 0100 % LATIN SMALL LETTER A WITH MACRON
-\setcclcucx 0102 0103 0102 % LATIN CAPITAL LETTER A WITH BREVE
-\setcclcucx 0103 0103 0102 % LATIN SMALL LETTER A WITH BREVE
-\setcclcucx 0104 0105 0104 % LATIN CAPITAL LETTER A WITH OGONEK
-\setcclcucx 0105 0105 0104 % LATIN SMALL LETTER A WITH OGONEK
-\setcclcucx 0106 0107 0106 % LATIN CAPITAL LETTER C WITH ACUTE
-\setcclcucx 0107 0107 0106 % LATIN SMALL LETTER C WITH ACUTE
-\setcclcucx 0108 0109 0108 % LATIN CAPITAL LETTER C WITH CIRCUMFLEX
-\setcclcucx 0109 0109 0108 % LATIN SMALL LETTER C WITH CIRCUMFLEX
-\setcclcucx 010A 010B 010A % LATIN CAPITAL LETTER C WITH DOT ABOVE
-\setcclcucx 010B 010B 010A % LATIN SMALL LETTER C WITH DOT ABOVE
-\setcclcucx 010C 010D 010C % LATIN CAPITAL LETTER C WITH CARON
-\setcclcucx 010D 010D 010C % LATIN SMALL LETTER C WITH CARON
-\setcclcucx 010E 010F 010E % LATIN CAPITAL LETTER D WITH CARON
-\setcclcucx 010F 010F 010E % LATIN SMALL LETTER D WITH CARON
-\setcclcucx 0110 0111 0110 % LATIN CAPITAL LETTER D WITH STROKE
-\setcclcucx 0111 0111 0110 % LATIN SMALL LETTER D WITH STROKE
-\setcclcucx 0112 0113 0112 % LATIN CAPITAL LETTER E WITH MACRON
-\setcclcucx 0113 0113 0112 % LATIN SMALL LETTER E WITH MACRON
-\setcclcucx 0114 0115 0114 % LATIN CAPITAL LETTER E WITH BREVE
-\setcclcucx 0115 0115 0114 % LATIN SMALL LETTER E WITH BREVE
-\setcclcucx 0116 0117 0116 % LATIN CAPITAL LETTER E WITH DOT ABOVE
-\setcclcucx 0117 0117 0116 % LATIN SMALL LETTER E WITH DOT ABOVE
-\setcclcucx 0118 0119 0118 % LATIN CAPITAL LETTER E WITH OGONEK
-\setcclcucx 0119 0119 0118 % LATIN SMALL LETTER E WITH OGONEK
-\setcclcucx 011A 011B 011A % LATIN CAPITAL LETTER E WITH CARON
-\setcclcucx 011B 011B 011A % LATIN SMALL LETTER E WITH CARON
-\setcclcucx 011C 011D 011C % LATIN CAPITAL LETTER G WITH CIRCUMFLEX
-\setcclcucx 011D 011D 011C % LATIN SMALL LETTER G WITH CIRCUMFLEX
-\setcclcucx 011E 011F 011E % LATIN CAPITAL LETTER G WITH BREVE
-\setcclcucx 011F 011F 011E % LATIN SMALL LETTER G WITH BREVE
-\setcclcucx 0120 0121 0120 % LATIN CAPITAL LETTER G WITH DOT ABOVE
-\setcclcucx 0121 0121 0120 % LATIN SMALL LETTER G WITH DOT ABOVE
-\setcclcucx 0122 0123 0122 % LATIN CAPITAL LETTER G WITH CEDILLA
-\setcclcucx 0123 0123 0122 % LATIN SMALL LETTER G WITH CEDILLA
-\setcclcucx 0124 0125 0124 % LATIN CAPITAL LETTER H WITH CIRCUMFLEX
-\setcclcucx 0125 0125 0124 % LATIN SMALL LETTER H WITH CIRCUMFLEX
-\setcclcucx 0126 0127 0126 % LATIN CAPITAL LETTER H WITH STROKE
-\setcclcucx 0127 0127 0126 % LATIN SMALL LETTER H WITH STROKE
-\setcclcucx 0128 0129 0128 % LATIN CAPITAL LETTER I WITH TILDE
-\setcclcucx 0129 0129 0128 % LATIN SMALL LETTER I WITH TILDE
-\setcclcucx 012A 012B 012A % LATIN CAPITAL LETTER I WITH MACRON
-\setcclcucx 012B 012B 012A % LATIN SMALL LETTER I WITH MACRON
-\setcclcucx 012C 012D 012C % LATIN CAPITAL LETTER I WITH BREVE
-\setcclcucx 012D 012D 012C % LATIN SMALL LETTER I WITH BREVE
-\setcclcucx 012E 012F 012E % LATIN CAPITAL LETTER I WITH OGONEK
-\setcclcucx 012F 012F 012E % LATIN SMALL LETTER I WITH OGONEK
-\setcclcucx 0130 0069 0130 % LATIN CAPITAL LETTER I WITH DOT ABOVE
-\setcclcucx 0131 0131 0049 % LATIN SMALL LETTER DOTLESS I
-\setcclcucx 0132 0133 0132 % LATIN CAPITAL LIGATURE IJ
-\setcclcucx 0133 0133 0132 % LATIN SMALL LIGATURE IJ
-\setcclcucx 0134 0135 0134 % LATIN CAPITAL LETTER J WITH CIRCUMFLEX
-\setcclcucx 0135 0135 0134 % LATIN SMALL LETTER J WITH CIRCUMFLEX
-\setcclcucx 0136 0137 0136 % LATIN CAPITAL LETTER K WITH CEDILLA
-\setcclcucx 0137 0137 0136 % LATIN SMALL LETTER K WITH CEDILLA
-\setcclcucx 0138 0138 0138 % LATIN SMALL LETTER KRA
-\setcclcucx 0139 013A 0139 % LATIN CAPITAL LETTER L WITH ACUTE
-\setcclcucx 013A 013A 0139 % LATIN SMALL LETTER L WITH ACUTE
-\setcclcucx 013B 013C 013B % LATIN CAPITAL LETTER L WITH CEDILLA
-\setcclcucx 013C 013C 013B % LATIN SMALL LETTER L WITH CEDILLA
-\setcclcucx 013D 013E 013D % LATIN CAPITAL LETTER L WITH CARON
-\setcclcucx 013E 013E 013D % LATIN SMALL LETTER L WITH CARON
-\setcclcucx 013F 0140 013F % LATIN CAPITAL LETTER L WITH MIDDLE DOT
-\setcclcucx 0140 0140 013F % LATIN SMALL LETTER L WITH MIDDLE DOT
-\setcclcucx 0141 0142 0141 % LATIN CAPITAL LETTER L WITH STROKE
-\setcclcucx 0142 0142 0141 % LATIN SMALL LETTER L WITH STROKE
-\setcclcucx 0143 0144 0143 % LATIN CAPITAL LETTER N WITH ACUTE
-\setcclcucx 0144 0144 0143 % LATIN SMALL LETTER N WITH ACUTE
-\setcclcucx 0145 0146 0145 % LATIN CAPITAL LETTER N WITH CEDILLA
-\setcclcucx 0146 0146 0145 % LATIN SMALL LETTER N WITH CEDILLA
-\setcclcucx 0147 0148 0147 % LATIN CAPITAL LETTER N WITH CARON
-\setcclcucx 0148 0148 0147 % LATIN SMALL LETTER N WITH CARON
-\setcclcucx 0149 0149 0149 % LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-\setcclcucx 014A 014B 014A % LATIN CAPITAL LETTER ENG
-\setcclcucx 014B 014B 014A % LATIN SMALL LETTER ENG
-\setcclcucx 014C 014D 014C % LATIN CAPITAL LETTER O WITH MACRON
-\setcclcucx 014D 014D 014C % LATIN SMALL LETTER O WITH MACRON
-\setcclcucx 014E 014F 014E % LATIN CAPITAL LETTER O WITH BREVE
-\setcclcucx 014F 014F 014E % LATIN SMALL LETTER O WITH BREVE
-\setcclcucx 0150 0151 0150 % LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
-\setcclcucx 0151 0151 0150 % LATIN SMALL LETTER O WITH DOUBLE ACUTE
-\setcclcucx 0152 0153 0152 % LATIN CAPITAL LIGATURE OE
-\setcclcucx 0153 0153 0152 % LATIN SMALL LIGATURE OE
-\setcclcucx 0154 0155 0154 % LATIN CAPITAL LETTER R WITH ACUTE
-\setcclcucx 0155 0155 0154 % LATIN SMALL LETTER R WITH ACUTE
-\setcclcucx 0156 0157 0156 % LATIN CAPITAL LETTER R WITH CEDILLA
-\setcclcucx 0157 0157 0156 % LATIN SMALL LETTER R WITH CEDILLA
-\setcclcucx 0158 0159 0158 % LATIN CAPITAL LETTER R WITH CARON
-\setcclcucx 0159 0159 0158 % LATIN SMALL LETTER R WITH CARON
-\setcclcucx 015A 015B 015A % LATIN CAPITAL LETTER S WITH ACUTE
-\setcclcucx 015B 015B 015A % LATIN SMALL LETTER S WITH ACUTE
-\setcclcucx 015C 015D 015C % LATIN CAPITAL LETTER S WITH CIRCUMFLEX
-\setcclcucx 015D 015D 015C % LATIN SMALL LETTER S WITH CIRCUMFLEX
-\setcclcucx 015E 015F 015E % LATIN CAPITAL LETTER S WITH CEDILLA
-\setcclcucx 015F 015F 015E % LATIN SMALL LETTER S WITH CEDILLA
-\setcclcucx 0160 0161 0160 % LATIN CAPITAL LETTER S WITH CARON
-\setcclcucx 0161 0161 0160 % LATIN SMALL LETTER S WITH CARON
-\setcclcucx 0162 0163 0162 % LATIN CAPITAL LETTER T WITH CEDILLA
-\setcclcucx 0163 0163 0162 % LATIN SMALL LETTER T WITH CEDILLA
-\setcclcucx 0164 0165 0164 % LATIN CAPITAL LETTER T WITH CARON
-\setcclcucx 0165 0165 0164 % LATIN SMALL LETTER T WITH CARON
-\setcclcucx 0166 0167 0166 % LATIN CAPITAL LETTER T WITH STROKE
-\setcclcucx 0167 0167 0166 % LATIN SMALL LETTER T WITH STROKE
-\setcclcucx 0168 0169 0168 % LATIN CAPITAL LETTER U WITH TILDE
-\setcclcucx 0169 0169 0168 % LATIN SMALL LETTER U WITH TILDE
-\setcclcucx 016A 016B 016A % LATIN CAPITAL LETTER U WITH MACRON
-\setcclcucx 016B 016B 016A % LATIN SMALL LETTER U WITH MACRON
-\setcclcucx 016C 016D 016C % LATIN CAPITAL LETTER U WITH BREVE
-\setcclcucx 016D 016D 016C % LATIN SMALL LETTER U WITH BREVE
-\setcclcucx 016E 016F 016E % LATIN CAPITAL LETTER U WITH RING ABOVE
-\setcclcucx 016F 016F 016E % LATIN SMALL LETTER U WITH RING ABOVE
-\setcclcucx 0170 0171 0170 % LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
-\setcclcucx 0171 0171 0170 % LATIN SMALL LETTER U WITH DOUBLE ACUTE
-\setcclcucx 0172 0173 0172 % LATIN CAPITAL LETTER U WITH OGONEK
-\setcclcucx 0173 0173 0172 % LATIN SMALL LETTER U WITH OGONEK
-\setcclcucx 0174 0175 0174 % LATIN CAPITAL LETTER W WITH CIRCUMFLEX
-\setcclcucx 0175 0175 0174 % LATIN SMALL LETTER W WITH CIRCUMFLEX
-\setcclcucx 0176 0177 0176 % LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
-\setcclcucx 0177 0177 0176 % LATIN SMALL LETTER Y WITH CIRCUMFLEX
-\setcclcucx 0178 00FF 0178 % LATIN CAPITAL LETTER Y WITH DIAERESIS
-\setcclcucx 0179 017A 0179 % LATIN CAPITAL LETTER Z WITH ACUTE
-\setcclcucx 017A 017A 0179 % LATIN SMALL LETTER Z WITH ACUTE
-\setcclcucx 017B 017C 017B % LATIN CAPITAL LETTER Z WITH DOT ABOVE
-\setcclcucx 017C 017C 017B % LATIN SMALL LETTER Z WITH DOT ABOVE
-\setcclcucx 017D 017E 017D % LATIN CAPITAL LETTER Z WITH CARON
-\setcclcucx 017E 017E 017D % LATIN SMALL LETTER Z WITH CARON
-\setcclcucx 017F 017F 0053 % LATIN SMALL LETTER LONG S
-\setcclcucx 0180 0180 0243 % LATIN SMALL LETTER B WITH STROKE
-\setcclcucx 0181 0253 0181 % LATIN CAPITAL LETTER B WITH HOOK
-\setcclcucx 0182 0183 0182 % LATIN CAPITAL LETTER B WITH TOPBAR
-\setcclcucx 0183 0183 0182 % LATIN SMALL LETTER B WITH TOPBAR
-\setcclcucx 0184 0185 0184 % LATIN CAPITAL LETTER TONE SIX
-\setcclcucx 0185 0185 0184 % LATIN SMALL LETTER TONE SIX
-\setcclcucx 0186 0254 0186 % LATIN CAPITAL LETTER OPEN O
-\setcclcucx 0187 0188 0187 % LATIN CAPITAL LETTER C WITH HOOK
-\setcclcucx 0188 0188 0187 % LATIN SMALL LETTER C WITH HOOK
-\setcclcucx 0189 0256 0189 % LATIN CAPITAL LETTER AFRICAN D
-\setcclcucx 018A 0257 018A % LATIN CAPITAL LETTER D WITH HOOK
-\setcclcucx 018B 018C 018B % LATIN CAPITAL LETTER D WITH TOPBAR
-\setcclcucx 018C 018C 018B % LATIN SMALL LETTER D WITH TOPBAR
-\setcclcucx 018D 018D 018D % LATIN SMALL LETTER TURNED DELTA
-\setcclcucx 018E 01DD 018E % LATIN CAPITAL LETTER REVERSED E
-\setcclcucx 018F 0259 018F % LATIN CAPITAL LETTER SCHWA
-\setcclcucx 0190 025B 0190 % LATIN CAPITAL LETTER OPEN E
-\setcclcucx 0191 0192 0191 % LATIN CAPITAL LETTER F WITH HOOK
-\setcclcucx 0192 0192 0191 % LATIN SMALL LETTER F WITH HOOK
-\setcclcucx 0193 0260 0193 % LATIN CAPITAL LETTER G WITH HOOK
-\setcclcucx 0194 0263 0194 % LATIN CAPITAL LETTER GAMMA
-\setcclcucx 0195 0195 01F6 % LATIN SMALL LETTER HV
-\setcclcucx 0196 0269 0196 % LATIN CAPITAL LETTER IOTA
-\setcclcucx 0197 0268 0197 % LATIN CAPITAL LETTER I WITH STROKE
-\setcclcucx 0198 0199 0198 % LATIN CAPITAL LETTER K WITH HOOK
-\setcclcucx 0199 0199 0198 % LATIN SMALL LETTER K WITH HOOK
-\setcclcucx 019A 019A 023D % LATIN SMALL LETTER L WITH BAR
-\setcclcucx 019B 019B 019B % LATIN SMALL LETTER LAMBDA WITH STROKE
-\setcclcucx 019C 026F 019C % LATIN CAPITAL LETTER TURNED M
-\setcclcucx 019D 0272 019D % LATIN CAPITAL LETTER N WITH LEFT HOOK
-\setcclcucx 019E 019E 0220 % LATIN SMALL LETTER N WITH LONG RIGHT LEG
-\setcclcucx 019F 0275 019F % LATIN CAPITAL LETTER O WITH MIDDLE TILDE
-\setcclcucx 01A0 01A1 01A0 % LATIN CAPITAL LETTER O WITH HORN
-\setcclcucx 01A1 01A1 01A0 % LATIN SMALL LETTER O WITH HORN
-\setcclcucx 01A2 01A3 01A2 % LATIN CAPITAL LETTER OI
-\setcclcucx 01A3 01A3 01A2 % LATIN SMALL LETTER OI
-\setcclcucx 01A4 01A5 01A4 % LATIN CAPITAL LETTER P WITH HOOK
-\setcclcucx 01A5 01A5 01A4 % LATIN SMALL LETTER P WITH HOOK
-\setcclcucx 01A6 0280 01A6 % LATIN LETTER YR
-\setcclcucx 01A7 01A8 01A7 % LATIN CAPITAL LETTER TONE TWO
-\setcclcucx 01A8 01A8 01A7 % LATIN SMALL LETTER TONE TWO
-\setcclcucx 01A9 0283 01A9 % LATIN CAPITAL LETTER ESH
-\setcclcucx 01AA 01AA 01AA % LATIN LETTER REVERSED ESH LOOP
-\setcclcucx 01AB 01AB 01AB % LATIN SMALL LETTER T WITH PALATAL HOOK
-\setcclcucx 01AC 01AD 01AC % LATIN CAPITAL LETTER T WITH HOOK
-\setcclcucx 01AD 01AD 01AC % LATIN SMALL LETTER T WITH HOOK
-\setcclcucx 01AE 0288 01AE % LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
-\setcclcucx 01AF 01B0 01AF % LATIN CAPITAL LETTER U WITH HORN
-\setcclcucx 01B0 01B0 01AF % LATIN SMALL LETTER U WITH HORN
-\setcclcucx 01B1 028A 01B1 % LATIN CAPITAL LETTER UPSILON
-\setcclcucx 01B2 028B 01B2 % LATIN CAPITAL LETTER V WITH HOOK
-\setcclcucx 01B3 01B4 01B3 % LATIN CAPITAL LETTER Y WITH HOOK
-\setcclcucx 01B4 01B4 01B3 % LATIN SMALL LETTER Y WITH HOOK
-\setcclcucx 01B5 01B6 01B5 % LATIN CAPITAL LETTER Z WITH STROKE
-\setcclcucx 01B6 01B6 01B5 % LATIN SMALL LETTER Z WITH STROKE
-\setcclcucx 01B7 0292 01B7 % LATIN CAPITAL LETTER EZH
-\setcclcucx 01B8 01B9 01B8 % LATIN CAPITAL LETTER EZH REVERSED
-\setcclcucx 01B9 01B9 01B8 % LATIN SMALL LETTER EZH REVERSED
-\setcclcucx 01BA 01BA 01BA % LATIN SMALL LETTER EZH WITH TAIL
-\setcclcucx 01BC 01BD 01BC % LATIN CAPITAL LETTER TONE FIVE
-\setcclcucx 01BD 01BD 01BC % LATIN SMALL LETTER TONE FIVE
-\setcclcucx 01BE 01BE 01BE % LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE
-\setcclcucx 01BF 01BF 01F7 % LATIN LETTER WYNN
-\setcclcucx 01C4 01C6 01C5 % LATIN CAPITAL LETTER DZ WITH CARON
-\setcclcucx 01C5 01C6 01C4 % LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
-\setcclcucx 01C6 01C6 01C4 % LATIN SMALL LETTER DZ WITH CARON
-\setcclcucx 01C7 01C9 01C8 % LATIN CAPITAL LETTER LJ
-\setcclcucx 01C8 01C9 01C7 % LATIN CAPITAL LETTER L WITH SMALL LETTER J
-\setcclcucx 01C9 01C9 01C7 % LATIN SMALL LETTER LJ
-\setcclcucx 01CA 01CC 01CB % LATIN CAPITAL LETTER NJ
-\setcclcucx 01CB 01CC 01CA % LATIN CAPITAL LETTER N WITH SMALL LETTER J
-\setcclcucx 01CC 01CC 01CA % LATIN SMALL LETTER NJ
-\setcclcucx 01CD 01CE 01CD % LATIN CAPITAL LETTER A WITH CARON
-\setcclcucx 01CE 01CE 01CD % LATIN SMALL LETTER A WITH CARON
-\setcclcucx 01CF 01D0 01CF % LATIN CAPITAL LETTER I WITH CARON
-\setcclcucx 01D0 01D0 01CF % LATIN SMALL LETTER I WITH CARON
-\setcclcucx 01D1 01D2 01D1 % LATIN CAPITAL LETTER O WITH CARON
-\setcclcucx 01D2 01D2 01D1 % LATIN SMALL LETTER O WITH CARON
-\setcclcucx 01D3 01D4 01D3 % LATIN CAPITAL LETTER U WITH CARON
-\setcclcucx 01D4 01D4 01D3 % LATIN SMALL LETTER U WITH CARON
-\setcclcucx 01D5 01D6 01D5 % LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
-\setcclcucx 01D6 01D6 01D5 % LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
-\setcclcucx 01D7 01D8 01D7 % LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
-\setcclcucx 01D8 01D8 01D7 % LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
-\setcclcucx 01D9 01DA 01D9 % LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
-\setcclcucx 01DA 01DA 01D9 % LATIN SMALL LETTER U WITH DIAERESIS AND CARON
-\setcclcucx 01DB 01DC 01DB % LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
-\setcclcucx 01DC 01DC 01DB % LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
-\setcclcucx 01DD 01DD 018E % LATIN SMALL LETTER TURNED E
-\setcclcucx 01DE 01DF 01DE % LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
-\setcclcucx 01DF 01DF 01DE % LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
-\setcclcucx 01E0 01E1 01E0 % LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
-\setcclcucx 01E1 01E1 01E0 % LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
-\setcclcucx 01E2 01E3 01E2 % LATIN CAPITAL LETTER AE WITH MACRON
-\setcclcucx 01E3 01E3 01E2 % LATIN SMALL LETTER AE WITH MACRON
-\setcclcucx 01E4 01E5 01E4 % LATIN CAPITAL LETTER G WITH STROKE
-\setcclcucx 01E5 01E5 01E4 % LATIN SMALL LETTER G WITH STROKE
-\setcclcucx 01E6 01E7 01E6 % LATIN CAPITAL LETTER G WITH CARON
-\setcclcucx 01E7 01E7 01E6 % LATIN SMALL LETTER G WITH CARON
-\setcclcucx 01E8 01E9 01E8 % LATIN CAPITAL LETTER K WITH CARON
-\setcclcucx 01E9 01E9 01E8 % LATIN SMALL LETTER K WITH CARON
-\setcclcucx 01EA 01EB 01EA % LATIN CAPITAL LETTER O WITH OGONEK
-\setcclcucx 01EB 01EB 01EA % LATIN SMALL LETTER O WITH OGONEK
-\setcclcucx 01EC 01ED 01EC % LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
-\setcclcucx 01ED 01ED 01EC % LATIN SMALL LETTER O WITH OGONEK AND MACRON
-\setcclcucx 01EE 01EF 01EE % LATIN CAPITAL LETTER EZH WITH CARON
-\setcclcucx 01EF 01EF 01EE % LATIN SMALL LETTER EZH WITH CARON
-\setcclcucx 01F0 01F0 01F0 % LATIN SMALL LETTER J WITH CARON
-\setcclcucx 01F1 01F3 01F2 % LATIN CAPITAL LETTER DZ
-\setcclcucx 01F2 01F3 01F1 % LATIN CAPITAL LETTER D WITH SMALL LETTER Z
-\setcclcucx 01F3 01F3 01F1 % LATIN SMALL LETTER DZ
-\setcclcucx 01F4 01F5 01F4 % LATIN CAPITAL LETTER G WITH ACUTE
-\setcclcucx 01F5 01F5 01F4 % LATIN SMALL LETTER G WITH ACUTE
-\setcclcucx 01F6 0195 01F6 % LATIN CAPITAL LETTER HWAIR
-\setcclcucx 01F7 01BF 01F7 % LATIN CAPITAL LETTER WYNN
-\setcclcucx 01F8 01F9 01F8 % LATIN CAPITAL LETTER N WITH GRAVE
-\setcclcucx 01F9 01F9 01F8 % LATIN SMALL LETTER N WITH GRAVE
-\setcclcucx 01FA 01FB 01FA % LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
-\setcclcucx 01FB 01FB 01FA % LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
-\setcclcucx 01FC 01FD 01FC % LATIN CAPITAL LETTER AE WITH ACUTE
-\setcclcucx 01FD 01FD 01FC % LATIN SMALL LETTER AE WITH ACUTE
-\setcclcucx 01FE 01FF 01FE % LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
-\setcclcucx 01FF 01FF 01FE % LATIN SMALL LETTER O WITH STROKE AND ACUTE
-\setcclcucx 0200 0201 0200 % LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
-\setcclcucx 0201 0201 0200 % LATIN SMALL LETTER A WITH DOUBLE GRAVE
-\setcclcucx 0202 0203 0202 % LATIN CAPITAL LETTER A WITH INVERTED BREVE
-\setcclcucx 0203 0203 0202 % LATIN SMALL LETTER A WITH INVERTED BREVE
-\setcclcucx 0204 0205 0204 % LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
-\setcclcucx 0205 0205 0204 % LATIN SMALL LETTER E WITH DOUBLE GRAVE
-\setcclcucx 0206 0207 0206 % LATIN CAPITAL LETTER E WITH INVERTED BREVE
-\setcclcucx 0207 0207 0206 % LATIN SMALL LETTER E WITH INVERTED BREVE
-\setcclcucx 0208 0209 0208 % LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
-\setcclcucx 0209 0209 0208 % LATIN SMALL LETTER I WITH DOUBLE GRAVE
-\setcclcucx 020A 020B 020A % LATIN CAPITAL LETTER I WITH INVERTED BREVE
-\setcclcucx 020B 020B 020A % LATIN SMALL LETTER I WITH INVERTED BREVE
-\setcclcucx 020C 020D 020C % LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
-\setcclcucx 020D 020D 020C % LATIN SMALL LETTER O WITH DOUBLE GRAVE
-\setcclcucx 020E 020F 020E % LATIN CAPITAL LETTER O WITH INVERTED BREVE
-\setcclcucx 020F 020F 020E % LATIN SMALL LETTER O WITH INVERTED BREVE
-\setcclcucx 0210 0211 0210 % LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
-\setcclcucx 0211 0211 0210 % LATIN SMALL LETTER R WITH DOUBLE GRAVE
-\setcclcucx 0212 0213 0212 % LATIN CAPITAL LETTER R WITH INVERTED BREVE
-\setcclcucx 0213 0213 0212 % LATIN SMALL LETTER R WITH INVERTED BREVE
-\setcclcucx 0214 0215 0214 % LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
-\setcclcucx 0215 0215 0214 % LATIN SMALL LETTER U WITH DOUBLE GRAVE
-\setcclcucx 0216 0217 0216 % LATIN CAPITAL LETTER U WITH INVERTED BREVE
-\setcclcucx 0217 0217 0216 % LATIN SMALL LETTER U WITH INVERTED BREVE
-\setcclcucx 0218 0219 0218 % LATIN CAPITAL LETTER S WITH COMMA BELOW
-\setcclcucx 0219 0219 0218 % LATIN SMALL LETTER S WITH COMMA BELOW
-\setcclcucx 021A 021B 021A % LATIN CAPITAL LETTER T WITH COMMA BELOW
-\setcclcucx 021B 021B 021A % LATIN SMALL LETTER T WITH COMMA BELOW
-\setcclcucx 021C 021D 021C % LATIN CAPITAL LETTER YOGH
-\setcclcucx 021D 021D 021C % LATIN SMALL LETTER YOGH
-\setcclcucx 021E 021F 021E % LATIN CAPITAL LETTER H WITH CARON
-\setcclcucx 021F 021F 021E % LATIN SMALL LETTER H WITH CARON
-\setcclcucx 0220 019E 0220 % LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
-\setcclcucx 0221 0221 0221 % LATIN SMALL LETTER D WITH CURL
-\setcclcucx 0222 0223 0222 % LATIN CAPITAL LETTER OU
-\setcclcucx 0223 0223 0222 % LATIN SMALL LETTER OU
-\setcclcucx 0224 0225 0224 % LATIN CAPITAL LETTER Z WITH HOOK
-\setcclcucx 0225 0225 0224 % LATIN SMALL LETTER Z WITH HOOK
-\setcclcucx 0226 0227 0226 % LATIN CAPITAL LETTER A WITH DOT ABOVE
-\setcclcucx 0227 0227 0226 % LATIN SMALL LETTER A WITH DOT ABOVE
-\setcclcucx 0228 0229 0228 % LATIN CAPITAL LETTER E WITH CEDILLA
-\setcclcucx 0229 0229 0228 % LATIN SMALL LETTER E WITH CEDILLA
-\setcclcucx 022A 022B 022A % LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
-\setcclcucx 022B 022B 022A % LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
-\setcclcucx 022C 022D 022C % LATIN CAPITAL LETTER O WITH TILDE AND MACRON
-\setcclcucx 022D 022D 022C % LATIN SMALL LETTER O WITH TILDE AND MACRON
-\setcclcucx 022E 022F 022E % LATIN CAPITAL LETTER O WITH DOT ABOVE
-\setcclcucx 022F 022F 022E % LATIN SMALL LETTER O WITH DOT ABOVE
-\setcclcucx 0230 0231 0230 % LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
-\setcclcucx 0231 0231 0230 % LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
-\setcclcucx 0232 0233 0232 % LATIN CAPITAL LETTER Y WITH MACRON
-\setcclcucx 0233 0233 0232 % LATIN SMALL LETTER Y WITH MACRON
-\setcclcucx 0234 0234 0234 % LATIN SMALL LETTER L WITH CURL
-\setcclcucx 0235 0235 0235 % LATIN SMALL LETTER N WITH CURL
-\setcclcucx 0236 0236 0236 % LATIN SMALL LETTER T WITH CURL
-\setcclcucx 0237 0237 0237 % LATIN SMALL LETTER DOTLESS J
-\setcclcucx 0238 0238 0238 % LATIN SMALL LETTER DB DIGRAPH
-\setcclcucx 0239 0239 0239 % LATIN SMALL LETTER QP DIGRAPH
-\setcclcucx 023A 2C65 023A % LATIN CAPITAL LETTER A WITH STROKE
-\setcclcucx 023B 023C 023B % LATIN CAPITAL LETTER C WITH STROKE
-\setcclcucx 023C 023C 023B % LATIN SMALL LETTER C WITH STROKE
-\setcclcucx 023D 019A 023D % LATIN CAPITAL LETTER L WITH BAR
-\setcclcucx 023E 2C66 023E % LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
-\setcclcucx 023F 023F 023F % LATIN SMALL LETTER S WITH SWASH TAIL
-\setcclcucx 0240 0240 0240 % LATIN SMALL LETTER Z WITH SWASH TAIL
-\setcclcucx 0241 0242 0241 % LATIN CAPITAL LETTER GLOTTAL STOP
-\setcclcucx 0242 0242 0241 % LATIN SMALL LETTER GLOTTAL STOP
-\setcclcucx 0243 0180 0243 % LATIN CAPITAL LETTER B WITH STROKE
-\setcclcucx 0244 0289 0244 % LATIN CAPITAL LETTER U BAR
-\setcclcucx 0245 028C 0245 % LATIN CAPITAL LETTER TURNED V
-\setcclcucx 0246 0247 0246 % LATIN CAPITAL LETTER E WITH STROKE
-\setcclcucx 0247 0247 0246 % LATIN SMALL LETTER E WITH STROKE
-\setcclcucx 0248 0249 0248 % LATIN CAPITAL LETTER J WITH STROKE
-\setcclcucx 0249 0249 0248 % LATIN SMALL LETTER J WITH STROKE
-\setcclcucx 024A 024B 024A % LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
-\setcclcucx 024B 024B 024A % LATIN SMALL LETTER Q WITH HOOK TAIL
-\setcclcucx 024C 024D 024C % LATIN CAPITAL LETTER R WITH STROKE
-\setcclcucx 024D 024D 024C % LATIN SMALL LETTER R WITH STROKE
-\setcclcucx 024E 024F 024E % LATIN CAPITAL LETTER Y WITH STROKE
-\setcclcucx 024F 024F 024E % LATIN SMALL LETTER Y WITH STROKE
-\setcclcucx 0250 0250 0250 % LATIN SMALL LETTER TURNED A
-\setcclcucx 0251 0251 0251 % LATIN SMALL LETTER ALPHA
-\setcclcucx 0252 0252 0252 % LATIN SMALL LETTER TURNED ALPHA
-\setcclcucx 0253 0253 0181 % LATIN SMALL LETTER B WITH HOOK
-\setcclcucx 0254 0254 0186 % LATIN SMALL LETTER OPEN O
-\setcclcucx 0255 0255 0255 % LATIN SMALL LETTER C WITH CURL
-\setcclcucx 0256 0256 0189 % LATIN SMALL LETTER D WITH TAIL
-\setcclcucx 0257 0257 018A % LATIN SMALL LETTER D WITH HOOK
-\setcclcucx 0258 0258 0258 % LATIN SMALL LETTER REVERSED E
-\setcclcucx 0259 0259 018F % LATIN SMALL LETTER SCHWA
-\setcclcucx 025A 025A 025A % LATIN SMALL LETTER SCHWA WITH HOOK
-\setcclcucx 025B 025B 0190 % LATIN SMALL LETTER OPEN E
-\setcclcucx 025C 025C 025C % LATIN SMALL LETTER REVERSED OPEN E
-\setcclcucx 025D 025D 025D % LATIN SMALL LETTER REVERSED OPEN E WITH HOOK
-\setcclcucx 025E 025E 025E % LATIN SMALL LETTER CLOSED REVERSED OPEN E
-\setcclcucx 025F 025F 025F % LATIN SMALL LETTER DOTLESS J WITH STROKE
-\setcclcucx 0260 0260 0193 % LATIN SMALL LETTER G WITH HOOK
-\setcclcucx 0261 0261 0261 % LATIN SMALL LETTER SCRIPT G
-\setcclcucx 0262 0262 0262 % LATIN LETTER SMALL CAPITAL G
-\setcclcucx 0263 0263 0194 % LATIN SMALL LETTER GAMMA
-\setcclcucx 0264 0264 0264 % LATIN SMALL LETTER RAMS HORN
-\setcclcucx 0265 0265 0265 % LATIN SMALL LETTER TURNED H
-\setcclcucx 0266 0266 0266 % LATIN SMALL LETTER H WITH HOOK
-\setcclcucx 0267 0267 0267 % LATIN SMALL LETTER HENG WITH HOOK
-\setcclcucx 0268 0268 0197 % LATIN SMALL LETTER I WITH STROKE
-\setcclcucx 0269 0269 0196 % LATIN SMALL LETTER IOTA
-\setcclcucx 026A 026A 026A % LATIN LETTER SMALL CAPITAL I
-\setcclcucx 026B 026B 2C62 % LATIN SMALL LETTER L WITH MIDDLE TILDE
-\setcclcucx 026C 026C 026C % LATIN SMALL LETTER L WITH BELT
-\setcclcucx 026D 026D 026D % LATIN SMALL LETTER L WITH RETROFLEX HOOK
-\setcclcucx 026E 026E 026E % LATIN SMALL LETTER LEZH
-\setcclcucx 026F 026F 019C % LATIN SMALL LETTER TURNED M
-\setcclcucx 0270 0270 0270 % LATIN SMALL LETTER TURNED M WITH LONG LEG
-\setcclcucx 0271 0271 0271 % LATIN SMALL LETTER M WITH HOOK
-\setcclcucx 0272 0272 019D % LATIN SMALL LETTER N WITH LEFT HOOK
-\setcclcucx 0273 0273 0273 % LATIN SMALL LETTER N WITH RETROFLEX HOOK
-\setcclcucx 0274 0274 0274 % LATIN LETTER SMALL CAPITAL N
-\setcclcucx 0275 0275 019F % LATIN SMALL LETTER BARRED O
-\setcclcucx 0276 0276 0276 % LATIN LETTER SMALL CAPITAL OE
-\setcclcucx 0277 0277 0277 % LATIN SMALL LETTER CLOSED OMEGA
-\setcclcucx 0278 0278 0278 % LATIN SMALL LETTER PHI
-\setcclcucx 0279 0279 0279 % LATIN SMALL LETTER TURNED R
-\setcclcucx 027A 027A 027A % LATIN SMALL LETTER TURNED R WITH LONG LEG
-\setcclcucx 027B 027B 027B % LATIN SMALL LETTER TURNED R WITH HOOK
-\setcclcucx 027C 027C 027C % LATIN SMALL LETTER R WITH LONG LEG
-\setcclcucx 027D 027D 2C64 % LATIN SMALL LETTER R WITH TAIL
-\setcclcucx 027E 027E 027E % LATIN SMALL LETTER R WITH FISHHOOK
-\setcclcucx 027F 027F 027F % LATIN SMALL LETTER REVERSED R WITH FISHHOOK
-\setcclcucx 0280 0280 01A6 % LATIN LETTER SMALL CAPITAL R
-\setcclcucx 0281 0281 0281 % LATIN LETTER SMALL CAPITAL INVERTED R
-\setcclcucx 0282 0282 0282 % LATIN SMALL LETTER S WITH HOOK
-\setcclcucx 0283 0283 01A9 % LATIN SMALL LETTER ESH
-\setcclcucx 0284 0284 0284 % LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK
-\setcclcucx 0285 0285 0285 % LATIN SMALL LETTER SQUAT REVERSED ESH
-\setcclcucx 0286 0286 0286 % LATIN SMALL LETTER ESH WITH CURL
-\setcclcucx 0287 0287 0287 % LATIN SMALL LETTER TURNED T
-\setcclcucx 0288 0288 01AE % LATIN SMALL LETTER T WITH RETROFLEX HOOK
-\setcclcucx 0289 0289 0244 % LATIN SMALL LETTER U BAR
-\setcclcucx 028A 028A 01B1 % LATIN SMALL LETTER UPSILON
-\setcclcucx 028B 028B 01B2 % LATIN SMALL LETTER V WITH HOOK
-\setcclcucx 028C 028C 0245 % LATIN SMALL LETTER TURNED V
-\setcclcucx 028D 028D 028D % LATIN SMALL LETTER TURNED W
-\setcclcucx 028E 028E 028E % LATIN SMALL LETTER TURNED Y
-\setcclcucx 028F 028F 028F % LATIN LETTER SMALL CAPITAL Y
-\setcclcucx 0290 0290 0290 % LATIN SMALL LETTER Z WITH RETROFLEX HOOK
-\setcclcucx 0291 0291 0291 % LATIN SMALL LETTER Z WITH CURL
-\setcclcucx 0292 0292 01B7 % LATIN SMALL LETTER EZH
-\setcclcucx 0293 0293 0293 % LATIN SMALL LETTER EZH WITH CURL
-\setcclcucx 0295 0295 0295 % LATIN LETTER PHARYNGEAL VOICED FRICATIVE
-\setcclcucx 0296 0296 0296 % LATIN LETTER INVERTED GLOTTAL STOP
-\setcclcucx 0297 0297 0297 % LATIN LETTER STRETCHED C
-\setcclcucx 0298 0298 0298 % LATIN LETTER BILABIAL CLICK
-\setcclcucx 0299 0299 0299 % LATIN LETTER SMALL CAPITAL B
-\setcclcucx 029A 029A 029A % LATIN SMALL LETTER CLOSED OPEN E
-\setcclcucx 029B 029B 029B % LATIN LETTER SMALL CAPITAL G WITH HOOK
-\setcclcucx 029C 029C 029C % LATIN LETTER SMALL CAPITAL H
-\setcclcucx 029D 029D 029D % LATIN SMALL LETTER J WITH CROSSED-TAIL
-\setcclcucx 029E 029E 029E % LATIN SMALL LETTER TURNED K
-\setcclcucx 029F 029F 029F % LATIN LETTER SMALL CAPITAL L
-\setcclcucx 02A0 02A0 02A0 % LATIN SMALL LETTER Q WITH HOOK
-\setcclcucx 02A1 02A1 02A1 % LATIN LETTER GLOTTAL STOP WITH STROKE
-\setcclcucx 02A2 02A2 02A2 % LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE
-\setcclcucx 02A3 02A3 02A3 % LATIN SMALL LETTER DZ DIGRAPH
-\setcclcucx 02A4 02A4 02A4 % LATIN SMALL LETTER DEZH DIGRAPH
-\setcclcucx 02A5 02A5 02A5 % LATIN SMALL LETTER DZ DIGRAPH WITH CURL
-\setcclcucx 02A6 02A6 02A6 % LATIN SMALL LETTER TS DIGRAPH
-\setcclcucx 02A7 02A7 02A7 % LATIN SMALL LETTER TESH DIGRAPH
-\setcclcucx 02A8 02A8 02A8 % LATIN SMALL LETTER TC DIGRAPH WITH CURL
-\setcclcucx 02A9 02A9 02A9 % LATIN SMALL LETTER FENG DIGRAPH
-\setcclcucx 02AA 02AA 02AA % LATIN SMALL LETTER LS DIGRAPH
-\setcclcucx 02AB 02AB 02AB % LATIN SMALL LETTER LZ DIGRAPH
-\setcclcucx 02AC 02AC 02AC % LATIN LETTER BILABIAL PERCUSSIVE
-\setcclcucx 02AD 02AD 02AD % LATIN LETTER BIDENTAL PERCUSSIVE
-\setcclcucx 02AE 02AE 02AE % LATIN SMALL LETTER TURNED H WITH FISHHOOK
-\setcclcucx 02AF 02AF 02AF % LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
-\setcclcucx 037B 037B 03FD % GREEK SMALL REVERSED LUNATE SIGMA SYMBOL
-\setcclcucx 037C 037C 03FE % GREEK SMALL DOTTED LUNATE SIGMA SYMBOL
-\setcclcucx 037D 037D 03FF % GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
-\setcclcucx 0386 03AC 0386 % GREEK CAPITAL LETTER ALPHA WITH TONOS
-\setcclcucx 0388 03AD 0388 % GREEK CAPITAL LETTER EPSILON WITH TONOS
-\setcclcucx 0389 03AE 0389 % GREEK CAPITAL LETTER ETA WITH TONOS
-\setcclcucx 038A 03AF 038A % GREEK CAPITAL LETTER IOTA WITH TONOS
-\setcclcucx 038C 03CC 038C % GREEK CAPITAL LETTER OMICRON WITH TONOS
-\setcclcucx 038E 03CD 038E % GREEK CAPITAL LETTER UPSILON WITH TONOS
-\setcclcucx 038F 03CE 038F % GREEK CAPITAL LETTER OMEGA WITH TONOS
-\setcclcucx 0390 0390 0390 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-\setcclcucx 0391 03B1 0391 % GREEK CAPITAL LETTER ALPHA
-\setcclcucx 0392 03B2 0392 % GREEK CAPITAL LETTER BETA
-\setcclcucx 0393 03B3 0393 % GREEK CAPITAL LETTER GAMMA
-\setcclcucx 0394 03B4 0394 % GREEK CAPITAL LETTER DELTA
-\setcclcucx 0395 03B5 0395 % GREEK CAPITAL LETTER EPSILON
-\setcclcucx 0396 03B6 0396 % GREEK CAPITAL LETTER ZETA
-\setcclcucx 0397 03B7 0397 % GREEK CAPITAL LETTER ETA
-\setcclcucx 0398 03B8 0398 % GREEK CAPITAL LETTER THETA
-\setcclcucx 0399 03B9 0399 % GREEK CAPITAL LETTER IOTA
-\setcclcucx 039A 03BA 039A % GREEK CAPITAL LETTER KAPPA
-\setcclcucx 039B 03BB 039B % GREEK CAPITAL LETTER LAMDA
-\setcclcucx 039C 03BC 039C % GREEK CAPITAL LETTER MU
-\setcclcucx 039D 03BD 039D % GREEK CAPITAL LETTER NU
-\setcclcucx 039E 03BE 039E % GREEK CAPITAL LETTER XI
-\setcclcucx 039F 03BF 039F % GREEK CAPITAL LETTER OMICRON
-\setcclcucx 03A0 03C0 03A0 % GREEK CAPITAL LETTER PI
-\setcclcucx 03A1 03C1 03A1 % GREEK CAPITAL LETTER RHO
-\setcclcucx 03A3 03C3 03A3 % GREEK CAPITAL LETTER SIGMA
-\setcclcucx 03A4 03C4 03A4 % GREEK CAPITAL LETTER TAU
-\setcclcucx 03A5 03C5 03A5 % GREEK CAPITAL LETTER UPSILON
-\setcclcucx 03A6 03C6 03A6 % GREEK CAPITAL LETTER PHI
-\setcclcucx 03A7 03C7 03A7 % GREEK CAPITAL LETTER CHI
-\setcclcucx 03A8 03C8 03A8 % GREEK CAPITAL LETTER PSI
-\setcclcucx 03A9 03C9 03A9 % GREEK CAPITAL LETTER OMEGA
-\setcclcucx 03AA 03CA 03AA % GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
-\setcclcucx 03AB 03CB 03AB % GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
-\setcclcucx 03AC 03AC 0386 % GREEK SMALL LETTER ALPHA WITH TONOS
-\setcclcucx 03AD 03AD 0388 % GREEK SMALL LETTER EPSILON WITH TONOS
-\setcclcucx 03AE 03AE 0389 % GREEK SMALL LETTER ETA WITH TONOS
-\setcclcucx 03AF 03AF 038A % GREEK SMALL LETTER IOTA WITH TONOS
-\setcclcucx 03B0 03B0 03B0 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-\setcclcucx 03B1 03B1 0391 % GREEK SMALL LETTER ALPHA
-\setcclcucx 03B2 03B2 0392 % GREEK SMALL LETTER BETA
-\setcclcucx 03B3 03B3 0393 % GREEK SMALL LETTER GAMMA
-\setcclcucx 03B4 03B4 0394 % GREEK SMALL LETTER DELTA
-\setcclcucx 03B5 03B5 0395 % GREEK SMALL LETTER EPSILON
-\setcclcucx 03B6 03B6 0396 % GREEK SMALL LETTER ZETA
-\setcclcucx 03B7 03B7 0397 % GREEK SMALL LETTER ETA
-\setcclcucx 03B8 03B8 0398 % GREEK SMALL LETTER THETA
-\setcclcucx 03B9 03B9 0399 % GREEK SMALL LETTER IOTA
-\setcclcucx 03BA 03BA 039A % GREEK SMALL LETTER KAPPA
-\setcclcucx 03BB 03BB 039B % GREEK SMALL LETTER LAMDA
-\setcclcucx 03BC 03BC 039C % GREEK SMALL LETTER MU
-\setcclcucx 03BD 03BD 039D % GREEK SMALL LETTER NU
-\setcclcucx 03BE 03BE 039E % GREEK SMALL LETTER XI
-\setcclcucx 03BF 03BF 039F % GREEK SMALL LETTER OMICRON
-\setcclcucx 03C0 03C0 03A0 % GREEK SMALL LETTER PI
-\setcclcucx 03C1 03C1 03A1 % GREEK SMALL LETTER RHO
-\setcclcucx 03C2 03C2 03A3 % GREEK SMALL LETTER FINAL SIGMA
-\setcclcucx 03C3 03C3 03A3 % GREEK SMALL LETTER SIGMA
-\setcclcucx 03C4 03C4 03A4 % GREEK SMALL LETTER TAU
-\setcclcucx 03C5 03C5 03A5 % GREEK SMALL LETTER UPSILON
-\setcclcucx 03C6 03C6 03A6 % GREEK SMALL LETTER PHI
-\setcclcucx 03C7 03C7 03A7 % GREEK SMALL LETTER CHI
-\setcclcucx 03C8 03C8 03A8 % GREEK SMALL LETTER PSI
-\setcclcucx 03C9 03C9 03A9 % GREEK SMALL LETTER OMEGA
-\setcclcucx 03CA 03CA 03AA % GREEK SMALL LETTER IOTA WITH DIALYTIKA
-\setcclcucx 03CB 03CB 03AB % GREEK SMALL LETTER UPSILON WITH DIALYTIKA
-\setcclcucx 03CC 03CC 038C % GREEK SMALL LETTER OMICRON WITH TONOS
-\setcclcucx 03CD 03CD 038E % GREEK SMALL LETTER UPSILON WITH TONOS
-\setcclcucx 03CE 03CE 038F % GREEK SMALL LETTER OMEGA WITH TONOS
-\setcclcucx 03D0 03D0 0392 % GREEK BETA SYMBOL
-\setcclcucx 03D1 03D1 0398 % GREEK THETA SYMBOL
-\setcclcucx 03D2 03D2 03D2 % GREEK UPSILON WITH HOOK SYMBOL
-\setcclcucx 03D3 03D3 03D3 % GREEK UPSILON WITH ACUTE AND HOOK SYMBOL
-\setcclcucx 03D4 03D4 03D4 % GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL
-\setcclcucx 03D5 03D5 03A6 % GREEK PHI SYMBOL
-\setcclcucx 03D6 03D6 03A0 % GREEK PI SYMBOL
-\setcclcucx 03D7 03D7 03D7 % GREEK KAI SYMBOL
-\setcclcucx 03D8 03D9 03D8 % GREEK LETTER ARCHAIC KOPPA
-\setcclcucx 03D9 03D9 03D8 % GREEK SMALL LETTER ARCHAIC KOPPA
-\setcclcucx 03DA 03DB 03DA % GREEK LETTER STIGMA
-\setcclcucx 03DB 03DB 03DA % GREEK SMALL LETTER STIGMA
-\setcclcucx 03DC 03DD 03DC % GREEK LETTER DIGAMMA
-\setcclcucx 03DD 03DD 03DC % GREEK SMALL LETTER DIGAMMA
-\setcclcucx 03DE 03DF 03DE % GREEK LETTER KOPPA
-\setcclcucx 03DF 03DF 03DE % GREEK SMALL LETTER KOPPA
-\setcclcucx 03E0 03E1 03E0 % GREEK LETTER SAMPI
-\setcclcucx 03E1 03E1 03E0 % GREEK SMALL LETTER SAMPI
-\setcclcucx 03E2 03E3 03E2 % COPTIC CAPITAL LETTER SHEI
-\setcclcucx 03E3 03E3 03E2 % COPTIC SMALL LETTER SHEI
-\setcclcucx 03E4 03E5 03E4 % COPTIC CAPITAL LETTER FEI
-\setcclcucx 03E5 03E5 03E4 % COPTIC SMALL LETTER FEI
-\setcclcucx 03E6 03E7 03E6 % COPTIC CAPITAL LETTER KHEI
-\setcclcucx 03E7 03E7 03E6 % COPTIC SMALL LETTER KHEI
-\setcclcucx 03E8 03E9 03E8 % COPTIC CAPITAL LETTER HORI
-\setcclcucx 03E9 03E9 03E8 % COPTIC SMALL LETTER HORI
-\setcclcucx 03EA 03EB 03EA % COPTIC CAPITAL LETTER GANGIA
-\setcclcucx 03EB 03EB 03EA % COPTIC SMALL LETTER GANGIA
-\setcclcucx 03EC 03ED 03EC % COPTIC CAPITAL LETTER SHIMA
-\setcclcucx 03ED 03ED 03EC % COPTIC SMALL LETTER SHIMA
-\setcclcucx 03EE 03EF 03EE % COPTIC CAPITAL LETTER DEI
-\setcclcucx 03EF 03EF 03EE % COPTIC SMALL LETTER DEI
-\setcclcucx 03F0 03F0 039A % GREEK KAPPA SYMBOL
-\setcclcucx 03F1 03F1 03A1 % GREEK RHO SYMBOL
-\setcclcucx 03F2 03F2 03F9 % GREEK LUNATE SIGMA SYMBOL
-\setcclcucx 03F3 03F3 03F3 % GREEK LETTER YOT
-\setcclcucx 03F4 03B8 03F4 % GREEK CAPITAL THETA SYMBOL
-\setcclcucx 03F5 03F5 0395 % GREEK LUNATE EPSILON SYMBOL
-\setcclcucx 03F7 03F8 03F7 % GREEK CAPITAL LETTER SHO
-\setcclcucx 03F8 03F8 03F7 % GREEK SMALL LETTER SHO
-\setcclcucx 03F9 03F2 03F9 % GREEK CAPITAL LUNATE SIGMA SYMBOL
-\setcclcucx 03FA 03FB 03FA % GREEK CAPITAL LETTER SAN
-\setcclcucx 03FB 03FB 03FA % GREEK SMALL LETTER SAN
-\setcclcucx 03FC 03FC 03FC % GREEK RHO WITH STROKE SYMBOL
-\setcclcucx 03FD 037B 03FD % GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
-\setcclcucx 03FE 037C 03FE % GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
-\setcclcucx 03FF 037D 03FF % GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
-\setcclcucx 0400 0450 0400 % CYRILLIC CAPITAL LETTER IE WITH GRAVE
-\setcclcucx 0401 0451 0401 % CYRILLIC CAPITAL LETTER IO
-\setcclcucx 0402 0452 0402 % CYRILLIC CAPITAL LETTER DJE
-\setcclcucx 0403 0453 0403 % CYRILLIC CAPITAL LETTER GJE
-\setcclcucx 0404 0454 0404 % CYRILLIC CAPITAL LETTER UKRAINIAN IE
-\setcclcucx 0405 0455 0405 % CYRILLIC CAPITAL LETTER DZE
-\setcclcucx 0406 0456 0406 % CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
-\setcclcucx 0407 0457 0407 % CYRILLIC CAPITAL LETTER YI
-\setcclcucx 0408 0458 0408 % CYRILLIC CAPITAL LETTER JE
-\setcclcucx 0409 0459 0409 % CYRILLIC CAPITAL LETTER LJE
-\setcclcucx 040A 045A 040A % CYRILLIC CAPITAL LETTER NJE
-\setcclcucx 040B 045B 040B % CYRILLIC CAPITAL LETTER TSHE
-\setcclcucx 040C 045C 040C % CYRILLIC CAPITAL LETTER KJE
-\setcclcucx 040D 045D 040D % CYRILLIC CAPITAL LETTER I WITH GRAVE
-\setcclcucx 040E 045E 040E % CYRILLIC CAPITAL LETTER SHORT U
-\setcclcucx 040F 045F 040F % CYRILLIC CAPITAL LETTER DZHE
-\setcclcucx 0410 0430 0410 % CYRILLIC CAPITAL LETTER A
-\setcclcucx 0411 0431 0411 % CYRILLIC CAPITAL LETTER BE
-\setcclcucx 0412 0432 0412 % CYRILLIC CAPITAL LETTER VE
-\setcclcucx 0413 0433 0413 % CYRILLIC CAPITAL LETTER GHE
-\setcclcucx 0414 0434 0414 % CYRILLIC CAPITAL LETTER DE
-\setcclcucx 0415 0435 0415 % CYRILLIC CAPITAL LETTER IE
-\setcclcucx 0416 0436 0416 % CYRILLIC CAPITAL LETTER ZHE
-\setcclcucx 0417 0437 0417 % CYRILLIC CAPITAL LETTER ZE
-\setcclcucx 0418 0438 0418 % CYRILLIC CAPITAL LETTER I
-\setcclcucx 0419 0439 0419 % CYRILLIC CAPITAL LETTER SHORT I
-\setcclcucx 041A 043A 041A % CYRILLIC CAPITAL LETTER KA
-\setcclcucx 041B 043B 041B % CYRILLIC CAPITAL LETTER EL
-\setcclcucx 041C 043C 041C % CYRILLIC CAPITAL LETTER EM
-\setcclcucx 041D 043D 041D % CYRILLIC CAPITAL LETTER EN
-\setcclcucx 041E 043E 041E % CYRILLIC CAPITAL LETTER O
-\setcclcucx 041F 043F 041F % CYRILLIC CAPITAL LETTER PE
-\setcclcucx 0420 0440 0420 % CYRILLIC CAPITAL LETTER ER
-\setcclcucx 0421 0441 0421 % CYRILLIC CAPITAL LETTER ES
-\setcclcucx 0422 0442 0422 % CYRILLIC CAPITAL LETTER TE
-\setcclcucx 0423 0443 0423 % CYRILLIC CAPITAL LETTER U
-\setcclcucx 0424 0444 0424 % CYRILLIC CAPITAL LETTER EF
-\setcclcucx 0425 0445 0425 % CYRILLIC CAPITAL LETTER HA
-\setcclcucx 0426 0446 0426 % CYRILLIC CAPITAL LETTER TSE
-\setcclcucx 0427 0447 0427 % CYRILLIC CAPITAL LETTER CHE
-\setcclcucx 0428 0448 0428 % CYRILLIC CAPITAL LETTER SHA
-\setcclcucx 0429 0449 0429 % CYRILLIC CAPITAL LETTER SHCHA
-\setcclcucx 042A 044A 042A % CYRILLIC CAPITAL LETTER HARD SIGN
-\setcclcucx 042B 044B 042B % CYRILLIC CAPITAL LETTER YERU
-\setcclcucx 042C 044C 042C % CYRILLIC CAPITAL LETTER SOFT SIGN
-\setcclcucx 042D 044D 042D % CYRILLIC CAPITAL LETTER E
-\setcclcucx 042E 044E 042E % CYRILLIC CAPITAL LETTER YU
-\setcclcucx 042F 044F 042F % CYRILLIC CAPITAL LETTER YA
-\setcclcucx 0430 0430 0410 % CYRILLIC SMALL LETTER A
-\setcclcucx 0431 0431 0411 % CYRILLIC SMALL LETTER BE
-\setcclcucx 0432 0432 0412 % CYRILLIC SMALL LETTER VE
-\setcclcucx 0433 0433 0413 % CYRILLIC SMALL LETTER GHE
-\setcclcucx 0434 0434 0414 % CYRILLIC SMALL LETTER DE
-\setcclcucx 0435 0435 0415 % CYRILLIC SMALL LETTER IE
-\setcclcucx 0436 0436 0416 % CYRILLIC SMALL LETTER ZHE
-\setcclcucx 0437 0437 0417 % CYRILLIC SMALL LETTER ZE
-\setcclcucx 0438 0438 0418 % CYRILLIC SMALL LETTER I
-\setcclcucx 0439 0439 0419 % CYRILLIC SMALL LETTER SHORT I
-\setcclcucx 043A 043A 041A % CYRILLIC SMALL LETTER KA
-\setcclcucx 043B 043B 041B % CYRILLIC SMALL LETTER EL
-\setcclcucx 043C 043C 041C % CYRILLIC SMALL LETTER EM
-\setcclcucx 043D 043D 041D % CYRILLIC SMALL LETTER EN
-\setcclcucx 043E 043E 041E % CYRILLIC SMALL LETTER O
-\setcclcucx 043F 043F 041F % CYRILLIC SMALL LETTER PE
-\setcclcucx 0440 0440 0420 % CYRILLIC SMALL LETTER ER
-\setcclcucx 0441 0441 0421 % CYRILLIC SMALL LETTER ES
-\setcclcucx 0442 0442 0422 % CYRILLIC SMALL LETTER TE
-\setcclcucx 0443 0443 0423 % CYRILLIC SMALL LETTER U
-\setcclcucx 0444 0444 0424 % CYRILLIC SMALL LETTER EF
-\setcclcucx 0445 0445 0425 % CYRILLIC SMALL LETTER HA
-\setcclcucx 0446 0446 0426 % CYRILLIC SMALL LETTER TSE
-\setcclcucx 0447 0447 0427 % CYRILLIC SMALL LETTER CHE
-\setcclcucx 0448 0448 0428 % CYRILLIC SMALL LETTER SHA
-\setcclcucx 0449 0449 0429 % CYRILLIC SMALL LETTER SHCHA
-\setcclcucx 044A 044A 042A % CYRILLIC SMALL LETTER HARD SIGN
-\setcclcucx 044B 044B 042B % CYRILLIC SMALL LETTER YERU
-\setcclcucx 044C 044C 042C % CYRILLIC SMALL LETTER SOFT SIGN
-\setcclcucx 044D 044D 042D % CYRILLIC SMALL LETTER E
-\setcclcucx 044E 044E 042E % CYRILLIC SMALL LETTER YU
-\setcclcucx 044F 044F 042F % CYRILLIC SMALL LETTER YA
-\setcclcucx 0450 0450 0400 % CYRILLIC SMALL LETTER IE WITH GRAVE
-\setcclcucx 0451 0451 0401 % CYRILLIC SMALL LETTER IO
-\setcclcucx 0452 0452 0402 % CYRILLIC SMALL LETTER DJE
-\setcclcucx 0453 0453 0403 % CYRILLIC SMALL LETTER GJE
-\setcclcucx 0454 0454 0404 % CYRILLIC SMALL LETTER UKRAINIAN IE
-\setcclcucx 0455 0455 0405 % CYRILLIC SMALL LETTER DZE
-\setcclcucx 0456 0456 0406 % CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
-\setcclcucx 0457 0457 0407 % CYRILLIC SMALL LETTER YI
-\setcclcucx 0458 0458 0408 % CYRILLIC SMALL LETTER JE
-\setcclcucx 0459 0459 0409 % CYRILLIC SMALL LETTER LJE
-\setcclcucx 045A 045A 040A % CYRILLIC SMALL LETTER NJE
-\setcclcucx 045B 045B 040B % CYRILLIC SMALL LETTER TSHE
-\setcclcucx 045C 045C 040C % CYRILLIC SMALL LETTER KJE
-\setcclcucx 045D 045D 040D % CYRILLIC SMALL LETTER I WITH GRAVE
-\setcclcucx 045E 045E 040E % CYRILLIC SMALL LETTER SHORT U
-\setcclcucx 045F 045F 040F % CYRILLIC SMALL LETTER DZHE
-\setcclcucx 0460 0461 0460 % CYRILLIC CAPITAL LETTER OMEGA
-\setcclcucx 0461 0461 0460 % CYRILLIC SMALL LETTER OMEGA
-\setcclcucx 0462 0463 0462 % CYRILLIC CAPITAL LETTER YAT
-\setcclcucx 0463 0463 0462 % CYRILLIC SMALL LETTER YAT
-\setcclcucx 0464 0465 0464 % CYRILLIC CAPITAL LETTER IOTIFIED E
-\setcclcucx 0465 0465 0464 % CYRILLIC SMALL LETTER IOTIFIED E
-\setcclcucx 0466 0467 0466 % CYRILLIC CAPITAL LETTER LITTLE YUS
-\setcclcucx 0467 0467 0466 % CYRILLIC SMALL LETTER LITTLE YUS
-\setcclcucx 0468 0469 0468 % CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
-\setcclcucx 0469 0469 0468 % CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS
-\setcclcucx 046A 046B 046A % CYRILLIC CAPITAL LETTER BIG YUS
-\setcclcucx 046B 046B 046A % CYRILLIC SMALL LETTER BIG YUS
-\setcclcucx 046C 046D 046C % CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
-\setcclcucx 046D 046D 046C % CYRILLIC SMALL LETTER IOTIFIED BIG YUS
-\setcclcucx 046E 046F 046E % CYRILLIC CAPITAL LETTER KSI
-\setcclcucx 046F 046F 046E % CYRILLIC SMALL LETTER KSI
-\setcclcucx 0470 0471 0470 % CYRILLIC CAPITAL LETTER PSI
-\setcclcucx 0471 0471 0470 % CYRILLIC SMALL LETTER PSI
-\setcclcucx 0472 0473 0472 % CYRILLIC CAPITAL LETTER FITA
-\setcclcucx 0473 0473 0472 % CYRILLIC SMALL LETTER FITA
-\setcclcucx 0474 0475 0474 % CYRILLIC CAPITAL LETTER IZHITSA
-\setcclcucx 0475 0475 0474 % CYRILLIC SMALL LETTER IZHITSA
-\setcclcucx 0476 0477 0476 % CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
-\setcclcucx 0477 0477 0476 % CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
-\setcclcucx 0478 0479 0478 % CYRILLIC CAPITAL LETTER UK
-\setcclcucx 0479 0479 0478 % CYRILLIC SMALL LETTER UK
-\setcclcucx 047A 047B 047A % CYRILLIC CAPITAL LETTER ROUND OMEGA
-\setcclcucx 047B 047B 047A % CYRILLIC SMALL LETTER ROUND OMEGA
-\setcclcucx 047C 047D 047C % CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
-\setcclcucx 047D 047D 047C % CYRILLIC SMALL LETTER OMEGA WITH TITLO
-\setcclcucx 047E 047F 047E % CYRILLIC CAPITAL LETTER OT
-\setcclcucx 047F 047F 047E % CYRILLIC SMALL LETTER OT
-\setcclcucx 0480 0481 0480 % CYRILLIC CAPITAL LETTER KOPPA
-\setcclcucx 0481 0481 0480 % CYRILLIC SMALL LETTER KOPPA
-\setcclcucx 048A 048B 048A % CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
-\setcclcucx 048B 048B 048A % CYRILLIC SMALL LETTER SHORT I WITH TAIL
-\setcclcucx 048C 048D 048C % CYRILLIC CAPITAL LETTER SEMISOFT SIGN
-\setcclcucx 048D 048D 048C % CYRILLIC SMALL LETTER SEMISOFT SIGN
-\setcclcucx 048E 048F 048E % CYRILLIC CAPITAL LETTER ER WITH TICK
-\setcclcucx 048F 048F 048E % CYRILLIC SMALL LETTER ER WITH TICK
-\setcclcucx 0490 0491 0490 % CYRILLIC CAPITAL LETTER GHE WITH UPTURN
-\setcclcucx 0491 0491 0490 % CYRILLIC SMALL LETTER GHE WITH UPTURN
-\setcclcucx 0492 0493 0492 % CYRILLIC CAPITAL LETTER GHE WITH STROKE
-\setcclcucx 0493 0493 0492 % CYRILLIC SMALL LETTER GHE WITH STROKE
-\setcclcucx 0494 0495 0494 % CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
-\setcclcucx 0495 0495 0494 % CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK
-\setcclcucx 0496 0497 0496 % CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
-\setcclcucx 0497 0497 0496 % CYRILLIC SMALL LETTER ZHE WITH DESCENDER
-\setcclcucx 0498 0499 0498 % CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
-\setcclcucx 0499 0499 0498 % CYRILLIC SMALL LETTER ZE WITH DESCENDER
-\setcclcucx 049A 049B 049A % CYRILLIC CAPITAL LETTER KA WITH DESCENDER
-\setcclcucx 049B 049B 049A % CYRILLIC SMALL LETTER KA WITH DESCENDER
-\setcclcucx 049C 049D 049C % CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
-\setcclcucx 049D 049D 049C % CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
-\setcclcucx 049E 049F 049E % CYRILLIC CAPITAL LETTER KA WITH STROKE
-\setcclcucx 049F 049F 049E % CYRILLIC SMALL LETTER KA WITH STROKE
-\setcclcucx 04A0 04A1 04A0 % CYRILLIC CAPITAL LETTER BASHKIR KA
-\setcclcucx 04A1 04A1 04A0 % CYRILLIC SMALL LETTER BASHKIR KA
-\setcclcucx 04A2 04A3 04A2 % CYRILLIC CAPITAL LETTER EN WITH DESCENDER
-\setcclcucx 04A3 04A3 04A2 % CYRILLIC SMALL LETTER EN WITH DESCENDER
-\setcclcucx 04A4 04A5 04A4 % CYRILLIC CAPITAL LIGATURE EN GHE
-\setcclcucx 04A5 04A5 04A4 % CYRILLIC SMALL LIGATURE EN GHE
-\setcclcucx 04A6 04A7 04A6 % CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
-\setcclcucx 04A7 04A7 04A6 % CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK
-\setcclcucx 04A8 04A9 04A8 % CYRILLIC CAPITAL LETTER ABKHASIAN HA
-\setcclcucx 04A9 04A9 04A8 % CYRILLIC SMALL LETTER ABKHASIAN HA
-\setcclcucx 04AA 04AB 04AA % CYRILLIC CAPITAL LETTER ES WITH DESCENDER
-\setcclcucx 04AB 04AB 04AA % CYRILLIC SMALL LETTER ES WITH DESCENDER
-\setcclcucx 04AC 04AD 04AC % CYRILLIC CAPITAL LETTER TE WITH DESCENDER
-\setcclcucx 04AD 04AD 04AC % CYRILLIC SMALL LETTER TE WITH DESCENDER
-\setcclcucx 04AE 04AF 04AE % CYRILLIC CAPITAL LETTER STRAIGHT U
-\setcclcucx 04AF 04AF 04AE % CYRILLIC SMALL LETTER STRAIGHT U
-\setcclcucx 04B0 04B1 04B0 % CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
-\setcclcucx 04B1 04B1 04B0 % CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
-\setcclcucx 04B2 04B3 04B2 % CYRILLIC CAPITAL LETTER HA WITH DESCENDER
-\setcclcucx 04B3 04B3 04B2 % CYRILLIC SMALL LETTER HA WITH DESCENDER
-\setcclcucx 04B4 04B5 04B4 % CYRILLIC CAPITAL LIGATURE TE TSE
-\setcclcucx 04B5 04B5 04B4 % CYRILLIC SMALL LIGATURE TE TSE
-\setcclcucx 04B6 04B7 04B6 % CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
-\setcclcucx 04B7 04B7 04B6 % CYRILLIC SMALL LETTER CHE WITH DESCENDER
-\setcclcucx 04B8 04B9 04B8 % CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
-\setcclcucx 04B9 04B9 04B8 % CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
-\setcclcucx 04BA 04BB 04BA % CYRILLIC CAPITAL LETTER SHHA
-\setcclcucx 04BB 04BB 04BA % CYRILLIC SMALL LETTER SHHA
-\setcclcucx 04BC 04BD 04BC % CYRILLIC CAPITAL LETTER ABKHASIAN CHE
-\setcclcucx 04BD 04BD 04BC % CYRILLIC SMALL LETTER ABKHASIAN CHE
-\setcclcucx 04BE 04BF 04BE % CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
-\setcclcucx 04BF 04BF 04BE % CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER
-\setcclcucx 04C0 04CF 04C0 % CYRILLIC LETTER PALOCHKA
-\setcclcucx 04C1 04C2 04C1 % CYRILLIC CAPITAL LETTER ZHE WITH BREVE
-\setcclcucx 04C2 04C2 04C1 % CYRILLIC SMALL LETTER ZHE WITH BREVE
-\setcclcucx 04C3 04C4 04C3 % CYRILLIC CAPITAL LETTER KA WITH HOOK
-\setcclcucx 04C4 04C4 04C3 % CYRILLIC SMALL LETTER KA WITH HOOK
-\setcclcucx 04C5 04C6 04C5 % CYRILLIC CAPITAL LETTER EL WITH TAIL
-\setcclcucx 04C6 04C6 04C5 % CYRILLIC SMALL LETTER EL WITH TAIL
-\setcclcucx 04C7 04C8 04C7 % CYRILLIC CAPITAL LETTER EN WITH HOOK
-\setcclcucx 04C8 04C8 04C7 % CYRILLIC SMALL LETTER EN WITH HOOK
-\setcclcucx 04C9 04CA 04C9 % CYRILLIC CAPITAL LETTER EN WITH TAIL
-\setcclcucx 04CA 04CA 04C9 % CYRILLIC SMALL LETTER EN WITH TAIL
-\setcclcucx 04CB 04CC 04CB % CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
-\setcclcucx 04CC 04CC 04CB % CYRILLIC SMALL LETTER KHAKASSIAN CHE
-\setcclcucx 04CD 04CE 04CD % CYRILLIC CAPITAL LETTER EM WITH TAIL
-\setcclcucx 04CE 04CE 04CD % CYRILLIC SMALL LETTER EM WITH TAIL
-\setcclcucx 04CF 04CF 04C0 % CYRILLIC SMALL LETTER PALOCHKA
-\setcclcucx 04D0 04D1 04D0 % CYRILLIC CAPITAL LETTER A WITH BREVE
-\setcclcucx 04D1 04D1 04D0 % CYRILLIC SMALL LETTER A WITH BREVE
-\setcclcucx 04D2 04D3 04D2 % CYRILLIC CAPITAL LETTER A WITH DIAERESIS
-\setcclcucx 04D3 04D3 04D2 % CYRILLIC SMALL LETTER A WITH DIAERESIS
-\setcclcucx 04D4 04D5 04D4 % CYRILLIC CAPITAL LIGATURE A IE
-\setcclcucx 04D5 04D5 04D4 % CYRILLIC SMALL LIGATURE A IE
-\setcclcucx 04D6 04D7 04D6 % CYRILLIC CAPITAL LETTER IE WITH BREVE
-\setcclcucx 04D7 04D7 04D6 % CYRILLIC SMALL LETTER IE WITH BREVE
-\setcclcucx 04D8 04D9 04D8 % CYRILLIC CAPITAL LETTER SCHWA
-\setcclcucx 04D9 04D9 04D8 % CYRILLIC SMALL LETTER SCHWA
-\setcclcucx 04DA 04DB 04DA % CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
-\setcclcucx 04DB 04DB 04DA % CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS
-\setcclcucx 04DC 04DD 04DC % CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
-\setcclcucx 04DD 04DD 04DC % CYRILLIC SMALL LETTER ZHE WITH DIAERESIS
-\setcclcucx 04DE 04DF 04DE % CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
-\setcclcucx 04DF 04DF 04DE % CYRILLIC SMALL LETTER ZE WITH DIAERESIS
-\setcclcucx 04E0 04E1 04E0 % CYRILLIC CAPITAL LETTER ABKHASIAN DZE
-\setcclcucx 04E1 04E1 04E0 % CYRILLIC SMALL LETTER ABKHASIAN DZE
-\setcclcucx 04E2 04E3 04E2 % CYRILLIC CAPITAL LETTER I WITH MACRON
-\setcclcucx 04E3 04E3 04E2 % CYRILLIC SMALL LETTER I WITH MACRON
-\setcclcucx 04E4 04E5 04E4 % CYRILLIC CAPITAL LETTER I WITH DIAERESIS
-\setcclcucx 04E5 04E5 04E4 % CYRILLIC SMALL LETTER I WITH DIAERESIS
-\setcclcucx 04E6 04E7 04E6 % CYRILLIC CAPITAL LETTER O WITH DIAERESIS
-\setcclcucx 04E7 04E7 04E6 % CYRILLIC SMALL LETTER O WITH DIAERESIS
-\setcclcucx 04E8 04E9 04E8 % CYRILLIC CAPITAL LETTER BARRED O
-\setcclcucx 04E9 04E9 04E8 % CYRILLIC SMALL LETTER BARRED O
-\setcclcucx 04EA 04EB 04EA % CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
-\setcclcucx 04EB 04EB 04EA % CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS
-\setcclcucx 04EC 04ED 04EC % CYRILLIC CAPITAL LETTER E WITH DIAERESIS
-\setcclcucx 04ED 04ED 04EC % CYRILLIC SMALL LETTER E WITH DIAERESIS
-\setcclcucx 04EE 04EF 04EE % CYRILLIC CAPITAL LETTER U WITH MACRON
-\setcclcucx 04EF 04EF 04EE % CYRILLIC SMALL LETTER U WITH MACRON
-\setcclcucx 04F0 04F1 04F0 % CYRILLIC CAPITAL LETTER U WITH DIAERESIS
-\setcclcucx 04F1 04F1 04F0 % CYRILLIC SMALL LETTER U WITH DIAERESIS
-\setcclcucx 04F2 04F3 04F2 % CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
-\setcclcucx 04F3 04F3 04F2 % CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE
-\setcclcucx 04F4 04F5 04F4 % CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
-\setcclcucx 04F5 04F5 04F4 % CYRILLIC SMALL LETTER CHE WITH DIAERESIS
-\setcclcucx 04F6 04F7 04F6 % CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
-\setcclcucx 04F7 04F7 04F6 % CYRILLIC SMALL LETTER GHE WITH DESCENDER
-\setcclcucx 04F8 04F9 04F8 % CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
-\setcclcucx 04F9 04F9 04F8 % CYRILLIC SMALL LETTER YERU WITH DIAERESIS
-\setcclcucx 04FA 04FB 04FA % CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
-\setcclcucx 04FB 04FB 04FA % CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK
-\setcclcucx 04FC 04FD 04FC % CYRILLIC CAPITAL LETTER HA WITH HOOK
-\setcclcucx 04FD 04FD 04FC % CYRILLIC SMALL LETTER HA WITH HOOK
-\setcclcucx 04FE 04FF 04FE % CYRILLIC CAPITAL LETTER HA WITH STROKE
-\setcclcucx 04FF 04FF 04FE % CYRILLIC SMALL LETTER HA WITH STROKE
-\setcclcucx 0500 0501 0500 % CYRILLIC CAPITAL LETTER KOMI DE
-\setcclcucx 0501 0501 0500 % CYRILLIC SMALL LETTER KOMI DE
-\setcclcucx 0502 0503 0502 % CYRILLIC CAPITAL LETTER KOMI DJE
-\setcclcucx 0503 0503 0502 % CYRILLIC SMALL LETTER KOMI DJE
-\setcclcucx 0504 0505 0504 % CYRILLIC CAPITAL LETTER KOMI ZJE
-\setcclcucx 0505 0505 0504 % CYRILLIC SMALL LETTER KOMI ZJE
-\setcclcucx 0506 0507 0506 % CYRILLIC CAPITAL LETTER KOMI DZJE
-\setcclcucx 0507 0507 0506 % CYRILLIC SMALL LETTER KOMI DZJE
-\setcclcucx 0508 0509 0508 % CYRILLIC CAPITAL LETTER KOMI LJE
-\setcclcucx 0509 0509 0508 % CYRILLIC SMALL LETTER KOMI LJE
-\setcclcucx 050A 050B 050A % CYRILLIC CAPITAL LETTER KOMI NJE
-\setcclcucx 050B 050B 050A % CYRILLIC SMALL LETTER KOMI NJE
-\setcclcucx 050C 050D 050C % CYRILLIC CAPITAL LETTER KOMI SJE
-\setcclcucx 050D 050D 050C % CYRILLIC SMALL LETTER KOMI SJE
-\setcclcucx 050E 050F 050E % CYRILLIC CAPITAL LETTER KOMI TJE
-\setcclcucx 050F 050F 050E % CYRILLIC SMALL LETTER KOMI TJE
-\setcclcucx 0510 0511 0510 % CYRILLIC CAPITAL LETTER REVERSED ZE
-\setcclcucx 0511 0511 0510 % CYRILLIC SMALL LETTER REVERSED ZE
-\setcclcucx 0512 0513 0512 % CYRILLIC CAPITAL LETTER EL WITH HOOK
-\setcclcucx 0513 0513 0512 % CYRILLIC SMALL LETTER EL WITH HOOK
-\setcclcucx 0531 0561 0531 % ARMENIAN CAPITAL LETTER AYB
-\setcclcucx 0532 0562 0532 % ARMENIAN CAPITAL LETTER BEN
-\setcclcucx 0533 0563 0533 % ARMENIAN CAPITAL LETTER GIM
-\setcclcucx 0534 0564 0534 % ARMENIAN CAPITAL LETTER DA
-\setcclcucx 0535 0565 0535 % ARMENIAN CAPITAL LETTER ECH
-\setcclcucx 0536 0566 0536 % ARMENIAN CAPITAL LETTER ZA
-\setcclcucx 0537 0567 0537 % ARMENIAN CAPITAL LETTER EH
-\setcclcucx 0538 0568 0538 % ARMENIAN CAPITAL LETTER ET
-\setcclcucx 0539 0569 0539 % ARMENIAN CAPITAL LETTER TO
-\setcclcucx 053A 056A 053A % ARMENIAN CAPITAL LETTER ZHE
-\setcclcucx 053B 056B 053B % ARMENIAN CAPITAL LETTER INI
-\setcclcucx 053C 056C 053C % ARMENIAN CAPITAL LETTER LIWN
-\setcclcucx 053D 056D 053D % ARMENIAN CAPITAL LETTER XEH
-\setcclcucx 053E 056E 053E % ARMENIAN CAPITAL LETTER CA
-\setcclcucx 053F 056F 053F % ARMENIAN CAPITAL LETTER KEN
-\setcclcucx 0540 0570 0540 % ARMENIAN CAPITAL LETTER HO
-\setcclcucx 0541 0571 0541 % ARMENIAN CAPITAL LETTER JA
-\setcclcucx 0542 0572 0542 % ARMENIAN CAPITAL LETTER GHAD
-\setcclcucx 0543 0573 0543 % ARMENIAN CAPITAL LETTER CHEH
-\setcclcucx 0544 0574 0544 % ARMENIAN CAPITAL LETTER MEN
-\setcclcucx 0545 0575 0545 % ARMENIAN CAPITAL LETTER YI
-\setcclcucx 0546 0576 0546 % ARMENIAN CAPITAL LETTER NOW
-\setcclcucx 0547 0577 0547 % ARMENIAN CAPITAL LETTER SHA
-\setcclcucx 0548 0578 0548 % ARMENIAN CAPITAL LETTER VO
-\setcclcucx 0549 0579 0549 % ARMENIAN CAPITAL LETTER CHA
-\setcclcucx 054A 057A 054A % ARMENIAN CAPITAL LETTER PEH
-\setcclcucx 054B 057B 054B % ARMENIAN CAPITAL LETTER JHEH
-\setcclcucx 054C 057C 054C % ARMENIAN CAPITAL LETTER RA
-\setcclcucx 054D 057D 054D % ARMENIAN CAPITAL LETTER SEH
-\setcclcucx 054E 057E 054E % ARMENIAN CAPITAL LETTER VEW
-\setcclcucx 054F 057F 054F % ARMENIAN CAPITAL LETTER TIWN
-\setcclcucx 0550 0580 0550 % ARMENIAN CAPITAL LETTER REH
-\setcclcucx 0551 0581 0551 % ARMENIAN CAPITAL LETTER CO
-\setcclcucx 0552 0582 0552 % ARMENIAN CAPITAL LETTER YIWN
-\setcclcucx 0553 0583 0553 % ARMENIAN CAPITAL LETTER PIWR
-\setcclcucx 0554 0584 0554 % ARMENIAN CAPITAL LETTER KEH
-\setcclcucx 0555 0585 0555 % ARMENIAN CAPITAL LETTER OH
-\setcclcucx 0556 0586 0556 % ARMENIAN CAPITAL LETTER FEH
-\setcclcucx 0561 0561 0531 % ARMENIAN SMALL LETTER AYB
-\setcclcucx 0562 0562 0532 % ARMENIAN SMALL LETTER BEN
-\setcclcucx 0563 0563 0533 % ARMENIAN SMALL LETTER GIM
-\setcclcucx 0564 0564 0534 % ARMENIAN SMALL LETTER DA
-\setcclcucx 0565 0565 0535 % ARMENIAN SMALL LETTER ECH
-\setcclcucx 0566 0566 0536 % ARMENIAN SMALL LETTER ZA
-\setcclcucx 0567 0567 0537 % ARMENIAN SMALL LETTER EH
-\setcclcucx 0568 0568 0538 % ARMENIAN SMALL LETTER ET
-\setcclcucx 0569 0569 0539 % ARMENIAN SMALL LETTER TO
-\setcclcucx 056A 056A 053A % ARMENIAN SMALL LETTER ZHE
-\setcclcucx 056B 056B 053B % ARMENIAN SMALL LETTER INI
-\setcclcucx 056C 056C 053C % ARMENIAN SMALL LETTER LIWN
-\setcclcucx 056D 056D 053D % ARMENIAN SMALL LETTER XEH
-\setcclcucx 056E 056E 053E % ARMENIAN SMALL LETTER CA
-\setcclcucx 056F 056F 053F % ARMENIAN SMALL LETTER KEN
-\setcclcucx 0570 0570 0540 % ARMENIAN SMALL LETTER HO
-\setcclcucx 0571 0571 0541 % ARMENIAN SMALL LETTER JA
-\setcclcucx 0572 0572 0542 % ARMENIAN SMALL LETTER GHAD
-\setcclcucx 0573 0573 0543 % ARMENIAN SMALL LETTER CHEH
-\setcclcucx 0574 0574 0544 % ARMENIAN SMALL LETTER MEN
-\setcclcucx 0575 0575 0545 % ARMENIAN SMALL LETTER YI
-\setcclcucx 0576 0576 0546 % ARMENIAN SMALL LETTER NOW
-\setcclcucx 0577 0577 0547 % ARMENIAN SMALL LETTER SHA
-\setcclcucx 0578 0578 0548 % ARMENIAN SMALL LETTER VO
-\setcclcucx 0579 0579 0549 % ARMENIAN SMALL LETTER CHA
-\setcclcucx 057A 057A 054A % ARMENIAN SMALL LETTER PEH
-\setcclcucx 057B 057B 054B % ARMENIAN SMALL LETTER JHEH
-\setcclcucx 057C 057C 054C % ARMENIAN SMALL LETTER RA
-\setcclcucx 057D 057D 054D % ARMENIAN SMALL LETTER SEH
-\setcclcucx 057E 057E 054E % ARMENIAN SMALL LETTER VEW
-\setcclcucx 057F 057F 054F % ARMENIAN SMALL LETTER TIWN
-\setcclcucx 0580 0580 0550 % ARMENIAN SMALL LETTER REH
-\setcclcucx 0581 0581 0551 % ARMENIAN SMALL LETTER CO
-\setcclcucx 0582 0582 0552 % ARMENIAN SMALL LETTER YIWN
-\setcclcucx 0583 0583 0553 % ARMENIAN SMALL LETTER PIWR
-\setcclcucx 0584 0584 0554 % ARMENIAN SMALL LETTER KEH
-\setcclcucx 0585 0585 0555 % ARMENIAN SMALL LETTER OH
-\setcclcucx 0586 0586 0556 % ARMENIAN SMALL LETTER FEH
-\setcclcucx 0587 0587 0587 % ARMENIAN SMALL LIGATURE ECH YIWN
-\setcclcucx 10A0 2D00 10A0 % GEORGIAN CAPITAL LETTER AN
-\setcclcucx 10A1 2D01 10A1 % GEORGIAN CAPITAL LETTER BAN
-\setcclcucx 10A2 2D02 10A2 % GEORGIAN CAPITAL LETTER GAN
-\setcclcucx 10A3 2D03 10A3 % GEORGIAN CAPITAL LETTER DON
-\setcclcucx 10A4 2D04 10A4 % GEORGIAN CAPITAL LETTER EN
-\setcclcucx 10A5 2D05 10A5 % GEORGIAN CAPITAL LETTER VIN
-\setcclcucx 10A6 2D06 10A6 % GEORGIAN CAPITAL LETTER ZEN
-\setcclcucx 10A7 2D07 10A7 % GEORGIAN CAPITAL LETTER TAN
-\setcclcucx 10A8 2D08 10A8 % GEORGIAN CAPITAL LETTER IN
-\setcclcucx 10A9 2D09 10A9 % GEORGIAN CAPITAL LETTER KAN
-\setcclcucx 10AA 2D0A 10AA % GEORGIAN CAPITAL LETTER LAS
-\setcclcucx 10AB 2D0B 10AB % GEORGIAN CAPITAL LETTER MAN
-\setcclcucx 10AC 2D0C 10AC % GEORGIAN CAPITAL LETTER NAR
-\setcclcucx 10AD 2D0D 10AD % GEORGIAN CAPITAL LETTER ON
-\setcclcucx 10AE 2D0E 10AE % GEORGIAN CAPITAL LETTER PAR
-\setcclcucx 10AF 2D0F 10AF % GEORGIAN CAPITAL LETTER ZHAR
-\setcclcucx 10B0 2D10 10B0 % GEORGIAN CAPITAL LETTER RAE
-\setcclcucx 10B1 2D11 10B1 % GEORGIAN CAPITAL LETTER SAN
-\setcclcucx 10B2 2D12 10B2 % GEORGIAN CAPITAL LETTER TAR
-\setcclcucx 10B3 2D13 10B3 % GEORGIAN CAPITAL LETTER UN
-\setcclcucx 10B4 2D14 10B4 % GEORGIAN CAPITAL LETTER PHAR
-\setcclcucx 10B5 2D15 10B5 % GEORGIAN CAPITAL LETTER KHAR
-\setcclcucx 10B6 2D16 10B6 % GEORGIAN CAPITAL LETTER GHAN
-\setcclcucx 10B7 2D17 10B7 % GEORGIAN CAPITAL LETTER QAR
-\setcclcucx 10B8 2D18 10B8 % GEORGIAN CAPITAL LETTER SHIN
-\setcclcucx 10B9 2D19 10B9 % GEORGIAN CAPITAL LETTER CHIN
-\setcclcucx 10BA 2D1A 10BA % GEORGIAN CAPITAL LETTER CAN
-\setcclcucx 10BB 2D1B 10BB % GEORGIAN CAPITAL LETTER JIL
-\setcclcucx 10BC 2D1C 10BC % GEORGIAN CAPITAL LETTER CIL
-\setcclcucx 10BD 2D1D 10BD % GEORGIAN CAPITAL LETTER CHAR
-\setcclcucx 10BE 2D1E 10BE % GEORGIAN CAPITAL LETTER XAN
-\setcclcucx 10BF 2D1F 10BF % GEORGIAN CAPITAL LETTER JHAN
-\setcclcucx 10C0 2D20 10C0 % GEORGIAN CAPITAL LETTER HAE
-\setcclcucx 10C1 2D21 10C1 % GEORGIAN CAPITAL LETTER HE
-\setcclcucx 10C2 2D22 10C2 % GEORGIAN CAPITAL LETTER HIE
-\setcclcucx 10C3 2D23 10C3 % GEORGIAN CAPITAL LETTER WE
-\setcclcucx 10C4 2D24 10C4 % GEORGIAN CAPITAL LETTER HAR
-\setcclcucx 10C5 2D25 10C5 % GEORGIAN CAPITAL LETTER HOE
-\setcclcucx 1D00 1D00 1D00 % LATIN LETTER SMALL CAPITAL A
-\setcclcucx 1D01 1D01 1D01 % LATIN LETTER SMALL CAPITAL AE
-\setcclcucx 1D02 1D02 1D02 % LATIN SMALL LETTER TURNED AE
-\setcclcucx 1D03 1D03 1D03 % LATIN LETTER SMALL CAPITAL BARRED B
-\setcclcucx 1D04 1D04 1D04 % LATIN LETTER SMALL CAPITAL C
-\setcclcucx 1D05 1D05 1D05 % LATIN LETTER SMALL CAPITAL D
-\setcclcucx 1D06 1D06 1D06 % LATIN LETTER SMALL CAPITAL ETH
-\setcclcucx 1D07 1D07 1D07 % LATIN LETTER SMALL CAPITAL E
-\setcclcucx 1D08 1D08 1D08 % LATIN SMALL LETTER TURNED OPEN E
-\setcclcucx 1D09 1D09 1D09 % LATIN SMALL LETTER TURNED I
-\setcclcucx 1D0A 1D0A 1D0A % LATIN LETTER SMALL CAPITAL J
-\setcclcucx 1D0B 1D0B 1D0B % LATIN LETTER SMALL CAPITAL K
-\setcclcucx 1D0C 1D0C 1D0C % LATIN LETTER SMALL CAPITAL L WITH STROKE
-\setcclcucx 1D0D 1D0D 1D0D % LATIN LETTER SMALL CAPITAL M
-\setcclcucx 1D0E 1D0E 1D0E % LATIN LETTER SMALL CAPITAL REVERSED N
-\setcclcucx 1D0F 1D0F 1D0F % LATIN LETTER SMALL CAPITAL O
-\setcclcucx 1D10 1D10 1D10 % LATIN LETTER SMALL CAPITAL OPEN O
-\setcclcucx 1D11 1D11 1D11 % LATIN SMALL LETTER SIDEWAYS O
-\setcclcucx 1D12 1D12 1D12 % LATIN SMALL LETTER SIDEWAYS OPEN O
-\setcclcucx 1D13 1D13 1D13 % LATIN SMALL LETTER SIDEWAYS O WITH STROKE
-\setcclcucx 1D14 1D14 1D14 % LATIN SMALL LETTER TURNED OE
-\setcclcucx 1D15 1D15 1D15 % LATIN LETTER SMALL CAPITAL OU
-\setcclcucx 1D16 1D16 1D16 % LATIN SMALL LETTER TOP HALF O
-\setcclcucx 1D17 1D17 1D17 % LATIN SMALL LETTER BOTTOM HALF O
-\setcclcucx 1D18 1D18 1D18 % LATIN LETTER SMALL CAPITAL P
-\setcclcucx 1D19 1D19 1D19 % LATIN LETTER SMALL CAPITAL REVERSED R
-\setcclcucx 1D1A 1D1A 1D1A % LATIN LETTER SMALL CAPITAL TURNED R
-\setcclcucx 1D1B 1D1B 1D1B % LATIN LETTER SMALL CAPITAL T
-\setcclcucx 1D1C 1D1C 1D1C % LATIN LETTER SMALL CAPITAL U
-\setcclcucx 1D1D 1D1D 1D1D % LATIN SMALL LETTER SIDEWAYS U
-\setcclcucx 1D1E 1D1E 1D1E % LATIN SMALL LETTER SIDEWAYS DIAERESIZED U
-\setcclcucx 1D1F 1D1F 1D1F % LATIN SMALL LETTER SIDEWAYS TURNED M
-\setcclcucx 1D20 1D20 1D20 % LATIN LETTER SMALL CAPITAL V
-\setcclcucx 1D21 1D21 1D21 % LATIN LETTER SMALL CAPITAL W
-\setcclcucx 1D22 1D22 1D22 % LATIN LETTER SMALL CAPITAL Z
-\setcclcucx 1D23 1D23 1D23 % LATIN LETTER SMALL CAPITAL EZH
-\setcclcucx 1D24 1D24 1D24 % LATIN LETTER VOICED LARYNGEAL SPIRANT
-\setcclcucx 1D25 1D25 1D25 % LATIN LETTER AIN
-\setcclcucx 1D26 1D26 1D26 % GREEK LETTER SMALL CAPITAL GAMMA
-\setcclcucx 1D27 1D27 1D27 % GREEK LETTER SMALL CAPITAL LAMDA
-\setcclcucx 1D28 1D28 1D28 % GREEK LETTER SMALL CAPITAL PI
-\setcclcucx 1D29 1D29 1D29 % GREEK LETTER SMALL CAPITAL RHO
-\setcclcucx 1D2A 1D2A 1D2A % GREEK LETTER SMALL CAPITAL PSI
-\setcclcucx 1D2B 1D2B 1D2B % CYRILLIC LETTER SMALL CAPITAL EL
-\setcclcucx 1D62 1D62 1D62 % LATIN SUBSCRIPT SMALL LETTER I
-\setcclcucx 1D63 1D63 1D63 % LATIN SUBSCRIPT SMALL LETTER R
-\setcclcucx 1D64 1D64 1D64 % LATIN SUBSCRIPT SMALL LETTER U
-\setcclcucx 1D65 1D65 1D65 % LATIN SUBSCRIPT SMALL LETTER V
-\setcclcucx 1D66 1D66 1D66 % GREEK SUBSCRIPT SMALL LETTER BETA
-\setcclcucx 1D67 1D67 1D67 % GREEK SUBSCRIPT SMALL LETTER GAMMA
-\setcclcucx 1D68 1D68 1D68 % GREEK SUBSCRIPT SMALL LETTER RHO
-\setcclcucx 1D69 1D69 1D69 % GREEK SUBSCRIPT SMALL LETTER PHI
-\setcclcucx 1D6A 1D6A 1D6A % GREEK SUBSCRIPT SMALL LETTER CHI
-\setcclcucx 1D6B 1D6B 1D6B % LATIN SMALL LETTER UE
-\setcclcucx 1D6C 1D6C 1D6C % LATIN SMALL LETTER B WITH MIDDLE TILDE
-\setcclcucx 1D6D 1D6D 1D6D % LATIN SMALL LETTER D WITH MIDDLE TILDE
-\setcclcucx 1D6E 1D6E 1D6E % LATIN SMALL LETTER F WITH MIDDLE TILDE
-\setcclcucx 1D6F 1D6F 1D6F % LATIN SMALL LETTER M WITH MIDDLE TILDE
-\setcclcucx 1D70 1D70 1D70 % LATIN SMALL LETTER N WITH MIDDLE TILDE
-\setcclcucx 1D71 1D71 1D71 % LATIN SMALL LETTER P WITH MIDDLE TILDE
-\setcclcucx 1D72 1D72 1D72 % LATIN SMALL LETTER R WITH MIDDLE TILDE
-\setcclcucx 1D73 1D73 1D73 % LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE
-\setcclcucx 1D74 1D74 1D74 % LATIN SMALL LETTER S WITH MIDDLE TILDE
-\setcclcucx 1D75 1D75 1D75 % LATIN SMALL LETTER T WITH MIDDLE TILDE
-\setcclcucx 1D76 1D76 1D76 % LATIN SMALL LETTER Z WITH MIDDLE TILDE
-\setcclcucx 1D77 1D77 1D77 % LATIN SMALL LETTER TURNED G
-\setcclcucx 1D79 1D79 1D79 % LATIN SMALL LETTER INSULAR G
-\setcclcucx 1D7A 1D7A 1D7A % LATIN SMALL LETTER TH WITH STRIKETHROUGH
-\setcclcucx 1D7B 1D7B 1D7B % LATIN SMALL CAPITAL LETTER I WITH STROKE
-\setcclcucx 1D7C 1D7C 1D7C % LATIN SMALL LETTER IOTA WITH STROKE
-\setcclcucx 1D7D 1D7D 2C63 % LATIN SMALL LETTER P WITH STROKE
-\setcclcucx 1D7E 1D7E 1D7E % LATIN SMALL CAPITAL LETTER U WITH STROKE
-\setcclcucx 1D7F 1D7F 1D7F % LATIN SMALL LETTER UPSILON WITH STROKE
-\setcclcucx 1D80 1D80 1D80 % LATIN SMALL LETTER B WITH PALATAL HOOK
-\setcclcucx 1D81 1D81 1D81 % LATIN SMALL LETTER D WITH PALATAL HOOK
-\setcclcucx 1D82 1D82 1D82 % LATIN SMALL LETTER F WITH PALATAL HOOK
-\setcclcucx 1D83 1D83 1D83 % LATIN SMALL LETTER G WITH PALATAL HOOK
-\setcclcucx 1D84 1D84 1D84 % LATIN SMALL LETTER K WITH PALATAL HOOK
-\setcclcucx 1D85 1D85 1D85 % LATIN SMALL LETTER L WITH PALATAL HOOK
-\setcclcucx 1D86 1D86 1D86 % LATIN SMALL LETTER M WITH PALATAL HOOK
-\setcclcucx 1D87 1D87 1D87 % LATIN SMALL LETTER N WITH PALATAL HOOK
-\setcclcucx 1D88 1D88 1D88 % LATIN SMALL LETTER P WITH PALATAL HOOK
-\setcclcucx 1D89 1D89 1D89 % LATIN SMALL LETTER R WITH PALATAL HOOK
-\setcclcucx 1D8A 1D8A 1D8A % LATIN SMALL LETTER S WITH PALATAL HOOK
-\setcclcucx 1D8B 1D8B 1D8B % LATIN SMALL LETTER ESH WITH PALATAL HOOK
-\setcclcucx 1D8C 1D8C 1D8C % LATIN SMALL LETTER V WITH PALATAL HOOK
-\setcclcucx 1D8D 1D8D 1D8D % LATIN SMALL LETTER X WITH PALATAL HOOK
-\setcclcucx 1D8E 1D8E 1D8E % LATIN SMALL LETTER Z WITH PALATAL HOOK
-\setcclcucx 1D8F 1D8F 1D8F % LATIN SMALL LETTER A WITH RETROFLEX HOOK
-\setcclcucx 1D90 1D90 1D90 % LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK
-\setcclcucx 1D91 1D91 1D91 % LATIN SMALL LETTER D WITH HOOK AND TAIL
-\setcclcucx 1D92 1D92 1D92 % LATIN SMALL LETTER E WITH RETROFLEX HOOK
-\setcclcucx 1D93 1D93 1D93 % LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK
-\setcclcucx 1D94 1D94 1D94 % LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK
-\setcclcucx 1D95 1D95 1D95 % LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK
-\setcclcucx 1D96 1D96 1D96 % LATIN SMALL LETTER I WITH RETROFLEX HOOK
-\setcclcucx 1D97 1D97 1D97 % LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK
-\setcclcucx 1D98 1D98 1D98 % LATIN SMALL LETTER ESH WITH RETROFLEX HOOK
-\setcclcucx 1D99 1D99 1D99 % LATIN SMALL LETTER U WITH RETROFLEX HOOK
-\setcclcucx 1D9A 1D9A 1D9A % LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
-\setcclcucx 1E00 1E01 1E00 % LATIN CAPITAL LETTER A WITH RING BELOW
-\setcclcucx 1E01 1E01 1E00 % LATIN SMALL LETTER A WITH RING BELOW
-\setcclcucx 1E02 1E03 1E02 % LATIN CAPITAL LETTER B WITH DOT ABOVE
-\setcclcucx 1E03 1E03 1E02 % LATIN SMALL LETTER B WITH DOT ABOVE
-\setcclcucx 1E04 1E05 1E04 % LATIN CAPITAL LETTER B WITH DOT BELOW
-\setcclcucx 1E05 1E05 1E04 % LATIN SMALL LETTER B WITH DOT BELOW
-\setcclcucx 1E06 1E07 1E06 % LATIN CAPITAL LETTER B WITH LINE BELOW
-\setcclcucx 1E07 1E07 1E06 % LATIN SMALL LETTER B WITH LINE BELOW
-\setcclcucx 1E08 1E09 1E08 % LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
-\setcclcucx 1E09 1E09 1E08 % LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
-\setcclcucx 1E0A 1E0B 1E0A % LATIN CAPITAL LETTER D WITH DOT ABOVE
-\setcclcucx 1E0B 1E0B 1E0A % LATIN SMALL LETTER D WITH DOT ABOVE
-\setcclcucx 1E0C 1E0D 1E0C % LATIN CAPITAL LETTER D WITH DOT BELOW
-\setcclcucx 1E0D 1E0D 1E0C % LATIN SMALL LETTER D WITH DOT BELOW
-\setcclcucx 1E0E 1E0F 1E0E % LATIN CAPITAL LETTER D WITH LINE BELOW
-\setcclcucx 1E0F 1E0F 1E0E % LATIN SMALL LETTER D WITH LINE BELOW
-\setcclcucx 1E10 1E11 1E10 % LATIN CAPITAL LETTER D WITH CEDILLA
-\setcclcucx 1E11 1E11 1E10 % LATIN SMALL LETTER D WITH CEDILLA
-\setcclcucx 1E12 1E13 1E12 % LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
-\setcclcucx 1E13 1E13 1E12 % LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
-\setcclcucx 1E14 1E15 1E14 % LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
-\setcclcucx 1E15 1E15 1E14 % LATIN SMALL LETTER E WITH MACRON AND GRAVE
-\setcclcucx 1E16 1E17 1E16 % LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
-\setcclcucx 1E17 1E17 1E16 % LATIN SMALL LETTER E WITH MACRON AND ACUTE
-\setcclcucx 1E18 1E19 1E18 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
-\setcclcucx 1E19 1E19 1E18 % LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
-\setcclcucx 1E1A 1E1B 1E1A % LATIN CAPITAL LETTER E WITH TILDE BELOW
-\setcclcucx 1E1B 1E1B 1E1A % LATIN SMALL LETTER E WITH TILDE BELOW
-\setcclcucx 1E1C 1E1D 1E1C % LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
-\setcclcucx 1E1D 1E1D 1E1C % LATIN SMALL LETTER E WITH CEDILLA AND BREVE
-\setcclcucx 1E1E 1E1F 1E1E % LATIN CAPITAL LETTER F WITH DOT ABOVE
-\setcclcucx 1E1F 1E1F 1E1E % LATIN SMALL LETTER F WITH DOT ABOVE
-\setcclcucx 1E20 1E21 1E20 % LATIN CAPITAL LETTER G WITH MACRON
-\setcclcucx 1E21 1E21 1E20 % LATIN SMALL LETTER G WITH MACRON
-\setcclcucx 1E22 1E23 1E22 % LATIN CAPITAL LETTER H WITH DOT ABOVE
-\setcclcucx 1E23 1E23 1E22 % LATIN SMALL LETTER H WITH DOT ABOVE
-\setcclcucx 1E24 1E25 1E24 % LATIN CAPITAL LETTER H WITH DOT BELOW
-\setcclcucx 1E25 1E25 1E24 % LATIN SMALL LETTER H WITH DOT BELOW
-\setcclcucx 1E26 1E27 1E26 % LATIN CAPITAL LETTER H WITH DIAERESIS
-\setcclcucx 1E27 1E27 1E26 % LATIN SMALL LETTER H WITH DIAERESIS
-\setcclcucx 1E28 1E29 1E28 % LATIN CAPITAL LETTER H WITH CEDILLA
-\setcclcucx 1E29 1E29 1E28 % LATIN SMALL LETTER H WITH CEDILLA
-\setcclcucx 1E2A 1E2B 1E2A % LATIN CAPITAL LETTER H WITH BREVE BELOW
-\setcclcucx 1E2B 1E2B 1E2A % LATIN SMALL LETTER H WITH BREVE BELOW
-\setcclcucx 1E2C 1E2D 1E2C % LATIN CAPITAL LETTER I WITH TILDE BELOW
-\setcclcucx 1E2D 1E2D 1E2C % LATIN SMALL LETTER I WITH TILDE BELOW
-\setcclcucx 1E2E 1E2F 1E2E % LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
-\setcclcucx 1E2F 1E2F 1E2E % LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
-\setcclcucx 1E30 1E31 1E30 % LATIN CAPITAL LETTER K WITH ACUTE
-\setcclcucx 1E31 1E31 1E30 % LATIN SMALL LETTER K WITH ACUTE
-\setcclcucx 1E32 1E33 1E32 % LATIN CAPITAL LETTER K WITH DOT BELOW
-\setcclcucx 1E33 1E33 1E32 % LATIN SMALL LETTER K WITH DOT BELOW
-\setcclcucx 1E34 1E35 1E34 % LATIN CAPITAL LETTER K WITH LINE BELOW
-\setcclcucx 1E35 1E35 1E34 % LATIN SMALL LETTER K WITH LINE BELOW
-\setcclcucx 1E36 1E37 1E36 % LATIN CAPITAL LETTER L WITH DOT BELOW
-\setcclcucx 1E37 1E37 1E36 % LATIN SMALL LETTER L WITH DOT BELOW
-\setcclcucx 1E38 1E39 1E38 % LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
-\setcclcucx 1E39 1E39 1E38 % LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
-\setcclcucx 1E3A 1E3B 1E3A % LATIN CAPITAL LETTER L WITH LINE BELOW
-\setcclcucx 1E3B 1E3B 1E3A % LATIN SMALL LETTER L WITH LINE BELOW
-\setcclcucx 1E3C 1E3D 1E3C % LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
-\setcclcucx 1E3D 1E3D 1E3C % LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
-\setcclcucx 1E3E 1E3F 1E3E % LATIN CAPITAL LETTER M WITH ACUTE
-\setcclcucx 1E3F 1E3F 1E3E % LATIN SMALL LETTER M WITH ACUTE
-\setcclcucx 1E40 1E41 1E40 % LATIN CAPITAL LETTER M WITH DOT ABOVE
-\setcclcucx 1E41 1E41 1E40 % LATIN SMALL LETTER M WITH DOT ABOVE
-\setcclcucx 1E42 1E43 1E42 % LATIN CAPITAL LETTER M WITH DOT BELOW
-\setcclcucx 1E43 1E43 1E42 % LATIN SMALL LETTER M WITH DOT BELOW
-\setcclcucx 1E44 1E45 1E44 % LATIN CAPITAL LETTER N WITH DOT ABOVE
-\setcclcucx 1E45 1E45 1E44 % LATIN SMALL LETTER N WITH DOT ABOVE
-\setcclcucx 1E46 1E47 1E46 % LATIN CAPITAL LETTER N WITH DOT BELOW
-\setcclcucx 1E47 1E47 1E46 % LATIN SMALL LETTER N WITH DOT BELOW
-\setcclcucx 1E48 1E49 1E48 % LATIN CAPITAL LETTER N WITH LINE BELOW
-\setcclcucx 1E49 1E49 1E48 % LATIN SMALL LETTER N WITH LINE BELOW
-\setcclcucx 1E4A 1E4B 1E4A % LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
-\setcclcucx 1E4B 1E4B 1E4A % LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
-\setcclcucx 1E4C 1E4D 1E4C % LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
-\setcclcucx 1E4D 1E4D 1E4C % LATIN SMALL LETTER O WITH TILDE AND ACUTE
-\setcclcucx 1E4E 1E4F 1E4E % LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
-\setcclcucx 1E4F 1E4F 1E4E % LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
-\setcclcucx 1E50 1E51 1E50 % LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
-\setcclcucx 1E51 1E51 1E50 % LATIN SMALL LETTER O WITH MACRON AND GRAVE
-\setcclcucx 1E52 1E53 1E52 % LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
-\setcclcucx 1E53 1E53 1E52 % LATIN SMALL LETTER O WITH MACRON AND ACUTE
-\setcclcucx 1E54 1E55 1E54 % LATIN CAPITAL LETTER P WITH ACUTE
-\setcclcucx 1E55 1E55 1E54 % LATIN SMALL LETTER P WITH ACUTE
-\setcclcucx 1E56 1E57 1E56 % LATIN CAPITAL LETTER P WITH DOT ABOVE
-\setcclcucx 1E57 1E57 1E56 % LATIN SMALL LETTER P WITH DOT ABOVE
-\setcclcucx 1E58 1E59 1E58 % LATIN CAPITAL LETTER R WITH DOT ABOVE
-\setcclcucx 1E59 1E59 1E58 % LATIN SMALL LETTER R WITH DOT ABOVE
-\setcclcucx 1E5A 1E5B 1E5A % LATIN CAPITAL LETTER R WITH DOT BELOW
-\setcclcucx 1E5B 1E5B 1E5A % LATIN SMALL LETTER R WITH DOT BELOW
-\setcclcucx 1E5C 1E5D 1E5C % LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
-\setcclcucx 1E5D 1E5D 1E5C % LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
-\setcclcucx 1E5E 1E5F 1E5E % LATIN CAPITAL LETTER R WITH LINE BELOW
-\setcclcucx 1E5F 1E5F 1E5E % LATIN SMALL LETTER R WITH LINE BELOW
-\setcclcucx 1E60 1E61 1E60 % LATIN CAPITAL LETTER S WITH DOT ABOVE
-\setcclcucx 1E61 1E61 1E60 % LATIN SMALL LETTER S WITH DOT ABOVE
-\setcclcucx 1E62 1E63 1E62 % LATIN CAPITAL LETTER S WITH DOT BELOW
-\setcclcucx 1E63 1E63 1E62 % LATIN SMALL LETTER S WITH DOT BELOW
-\setcclcucx 1E64 1E65 1E64 % LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
-\setcclcucx 1E65 1E65 1E64 % LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
-\setcclcucx 1E66 1E67 1E66 % LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
-\setcclcucx 1E67 1E67 1E66 % LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
-\setcclcucx 1E68 1E69 1E68 % LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
-\setcclcucx 1E69 1E69 1E68 % LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
-\setcclcucx 1E6A 1E6B 1E6A % LATIN CAPITAL LETTER T WITH DOT ABOVE
-\setcclcucx 1E6B 1E6B 1E6A % LATIN SMALL LETTER T WITH DOT ABOVE
-\setcclcucx 1E6C 1E6D 1E6C % LATIN CAPITAL LETTER T WITH DOT BELOW
-\setcclcucx 1E6D 1E6D 1E6C % LATIN SMALL LETTER T WITH DOT BELOW
-\setcclcucx 1E6E 1E6F 1E6E % LATIN CAPITAL LETTER T WITH LINE BELOW
-\setcclcucx 1E6F 1E6F 1E6E % LATIN SMALL LETTER T WITH LINE BELOW
-\setcclcucx 1E70 1E71 1E70 % LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
-\setcclcucx 1E71 1E71 1E70 % LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
-\setcclcucx 1E72 1E73 1E72 % LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
-\setcclcucx 1E73 1E73 1E72 % LATIN SMALL LETTER U WITH DIAERESIS BELOW
-\setcclcucx 1E74 1E75 1E74 % LATIN CAPITAL LETTER U WITH TILDE BELOW
-\setcclcucx 1E75 1E75 1E74 % LATIN SMALL LETTER U WITH TILDE BELOW
-\setcclcucx 1E76 1E77 1E76 % LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
-\setcclcucx 1E77 1E77 1E76 % LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
-\setcclcucx 1E78 1E79 1E78 % LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
-\setcclcucx 1E79 1E79 1E78 % LATIN SMALL LETTER U WITH TILDE AND ACUTE
-\setcclcucx 1E7A 1E7B 1E7A % LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
-\setcclcucx 1E7B 1E7B 1E7A % LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
-\setcclcucx 1E7C 1E7D 1E7C % LATIN CAPITAL LETTER V WITH TILDE
-\setcclcucx 1E7D 1E7D 1E7C % LATIN SMALL LETTER V WITH TILDE
-\setcclcucx 1E7E 1E7F 1E7E % LATIN CAPITAL LETTER V WITH DOT BELOW
-\setcclcucx 1E7F 1E7F 1E7E % LATIN SMALL LETTER V WITH DOT BELOW
-\setcclcucx 1E80 1E81 1E80 % LATIN CAPITAL LETTER W WITH GRAVE
-\setcclcucx 1E81 1E81 1E80 % LATIN SMALL LETTER W WITH GRAVE
-\setcclcucx 1E82 1E83 1E82 % LATIN CAPITAL LETTER W WITH ACUTE
-\setcclcucx 1E83 1E83 1E82 % LATIN SMALL LETTER W WITH ACUTE
-\setcclcucx 1E84 1E85 1E84 % LATIN CAPITAL LETTER W WITH DIAERESIS
-\setcclcucx 1E85 1E85 1E84 % LATIN SMALL LETTER W WITH DIAERESIS
-\setcclcucx 1E86 1E87 1E86 % LATIN CAPITAL LETTER W WITH DOT ABOVE
-\setcclcucx 1E87 1E87 1E86 % LATIN SMALL LETTER W WITH DOT ABOVE
-\setcclcucx 1E88 1E89 1E88 % LATIN CAPITAL LETTER W WITH DOT BELOW
-\setcclcucx 1E89 1E89 1E88 % LATIN SMALL LETTER W WITH DOT BELOW
-\setcclcucx 1E8A 1E8B 1E8A % LATIN CAPITAL LETTER X WITH DOT ABOVE
-\setcclcucx 1E8B 1E8B 1E8A % LATIN SMALL LETTER X WITH DOT ABOVE
-\setcclcucx 1E8C 1E8D 1E8C % LATIN CAPITAL LETTER X WITH DIAERESIS
-\setcclcucx 1E8D 1E8D 1E8C % LATIN SMALL LETTER X WITH DIAERESIS
-\setcclcucx 1E8E 1E8F 1E8E % LATIN CAPITAL LETTER Y WITH DOT ABOVE
-\setcclcucx 1E8F 1E8F 1E8E % LATIN SMALL LETTER Y WITH DOT ABOVE
-\setcclcucx 1E90 1E91 1E90 % LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
-\setcclcucx 1E91 1E91 1E90 % LATIN SMALL LETTER Z WITH CIRCUMFLEX
-\setcclcucx 1E92 1E93 1E92 % LATIN CAPITAL LETTER Z WITH DOT BELOW
-\setcclcucx 1E93 1E93 1E92 % LATIN SMALL LETTER Z WITH DOT BELOW
-\setcclcucx 1E94 1E95 1E94 % LATIN CAPITAL LETTER Z WITH LINE BELOW
-\setcclcucx 1E95 1E95 1E94 % LATIN SMALL LETTER Z WITH LINE BELOW
-\setcclcucx 1E96 1E96 1E96 % LATIN SMALL LETTER H WITH LINE BELOW
-\setcclcucx 1E97 1E97 1E97 % LATIN SMALL LETTER T WITH DIAERESIS
-\setcclcucx 1E98 1E98 1E98 % LATIN SMALL LETTER W WITH RING ABOVE
-\setcclcucx 1E99 1E99 1E99 % LATIN SMALL LETTER Y WITH RING ABOVE
-\setcclcucx 1E9A 1E9A 1E9A % LATIN SMALL LETTER A WITH RIGHT HALF RING
-\setcclcucx 1E9B 1E9B 1E60 % LATIN SMALL LETTER LONG S WITH DOT ABOVE
-\setcclcucx 1EA0 1EA1 1EA0 % LATIN CAPITAL LETTER A WITH DOT BELOW
-\setcclcucx 1EA1 1EA1 1EA0 % LATIN SMALL LETTER A WITH DOT BELOW
-\setcclcucx 1EA2 1EA3 1EA2 % LATIN CAPITAL LETTER A WITH HOOK ABOVE
-\setcclcucx 1EA3 1EA3 1EA2 % LATIN SMALL LETTER A WITH HOOK ABOVE
-\setcclcucx 1EA4 1EA5 1EA4 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
-\setcclcucx 1EA5 1EA5 1EA4 % LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
-\setcclcucx 1EA6 1EA7 1EA6 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
-\setcclcucx 1EA7 1EA7 1EA6 % LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
-\setcclcucx 1EA8 1EA9 1EA8 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
-\setcclcucx 1EA9 1EA9 1EA8 % LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
-\setcclcucx 1EAA 1EAB 1EAA % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
-\setcclcucx 1EAB 1EAB 1EAA % LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
-\setcclcucx 1EAC 1EAD 1EAC % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
-\setcclcucx 1EAD 1EAD 1EAC % LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
-\setcclcucx 1EAE 1EAF 1EAE % LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
-\setcclcucx 1EAF 1EAF 1EAE % LATIN SMALL LETTER A WITH BREVE AND ACUTE
-\setcclcucx 1EB0 1EB1 1EB0 % LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
-\setcclcucx 1EB1 1EB1 1EB0 % LATIN SMALL LETTER A WITH BREVE AND GRAVE
-\setcclcucx 1EB2 1EB3 1EB2 % LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
-\setcclcucx 1EB3 1EB3 1EB2 % LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
-\setcclcucx 1EB4 1EB5 1EB4 % LATIN CAPITAL LETTER A WITH BREVE AND TILDE
-\setcclcucx 1EB5 1EB5 1EB4 % LATIN SMALL LETTER A WITH BREVE AND TILDE
-\setcclcucx 1EB6 1EB7 1EB6 % LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
-\setcclcucx 1EB7 1EB7 1EB6 % LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
-\setcclcucx 1EB8 1EB9 1EB8 % LATIN CAPITAL LETTER E WITH DOT BELOW
-\setcclcucx 1EB9 1EB9 1EB8 % LATIN SMALL LETTER E WITH DOT BELOW
-\setcclcucx 1EBA 1EBB 1EBA % LATIN CAPITAL LETTER E WITH HOOK ABOVE
-\setcclcucx 1EBB 1EBB 1EBA % LATIN SMALL LETTER E WITH HOOK ABOVE
-\setcclcucx 1EBC 1EBD 1EBC % LATIN CAPITAL LETTER E WITH TILDE
-\setcclcucx 1EBD 1EBD 1EBC % LATIN SMALL LETTER E WITH TILDE
-\setcclcucx 1EBE 1EBF 1EBE % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
-\setcclcucx 1EBF 1EBF 1EBE % LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
-\setcclcucx 1EC0 1EC1 1EC0 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
-\setcclcucx 1EC1 1EC1 1EC0 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
-\setcclcucx 1EC2 1EC3 1EC2 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
-\setcclcucx 1EC3 1EC3 1EC2 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
-\setcclcucx 1EC4 1EC5 1EC4 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
-\setcclcucx 1EC5 1EC5 1EC4 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
-\setcclcucx 1EC6 1EC7 1EC6 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
-\setcclcucx 1EC7 1EC7 1EC6 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
-\setcclcucx 1EC8 1EC9 1EC8 % LATIN CAPITAL LETTER I WITH HOOK ABOVE
-\setcclcucx 1EC9 1EC9 1EC8 % LATIN SMALL LETTER I WITH HOOK ABOVE
-\setcclcucx 1ECA 1ECB 1ECA % LATIN CAPITAL LETTER I WITH DOT BELOW
-\setcclcucx 1ECB 1ECB 1ECA % LATIN SMALL LETTER I WITH DOT BELOW
-\setcclcucx 1ECC 1ECD 1ECC % LATIN CAPITAL LETTER O WITH DOT BELOW
-\setcclcucx 1ECD 1ECD 1ECC % LATIN SMALL LETTER O WITH DOT BELOW
-\setcclcucx 1ECE 1ECF 1ECE % LATIN CAPITAL LETTER O WITH HOOK ABOVE
-\setcclcucx 1ECF 1ECF 1ECE % LATIN SMALL LETTER O WITH HOOK ABOVE
-\setcclcucx 1ED0 1ED1 1ED0 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
-\setcclcucx 1ED1 1ED1 1ED0 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
-\setcclcucx 1ED2 1ED3 1ED2 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
-\setcclcucx 1ED3 1ED3 1ED2 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
-\setcclcucx 1ED4 1ED5 1ED4 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
-\setcclcucx 1ED5 1ED5 1ED4 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
-\setcclcucx 1ED6 1ED7 1ED6 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
-\setcclcucx 1ED7 1ED7 1ED6 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
-\setcclcucx 1ED8 1ED9 1ED8 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
-\setcclcucx 1ED9 1ED9 1ED8 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
-\setcclcucx 1EDA 1EDB 1EDA % LATIN CAPITAL LETTER O WITH HORN AND ACUTE
-\setcclcucx 1EDB 1EDB 1EDA % LATIN SMALL LETTER O WITH HORN AND ACUTE
-\setcclcucx 1EDC 1EDD 1EDC % LATIN CAPITAL LETTER O WITH HORN AND GRAVE
-\setcclcucx 1EDD 1EDD 1EDC % LATIN SMALL LETTER O WITH HORN AND GRAVE
-\setcclcucx 1EDE 1EDF 1EDE % LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
-\setcclcucx 1EDF 1EDF 1EDE % LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
-\setcclcucx 1EE0 1EE1 1EE0 % LATIN CAPITAL LETTER O WITH HORN AND TILDE
-\setcclcucx 1EE1 1EE1 1EE0 % LATIN SMALL LETTER O WITH HORN AND TILDE
-\setcclcucx 1EE2 1EE3 1EE2 % LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
-\setcclcucx 1EE3 1EE3 1EE2 % LATIN SMALL LETTER O WITH HORN AND DOT BELOW
-\setcclcucx 1EE4 1EE5 1EE4 % LATIN CAPITAL LETTER U WITH DOT BELOW
-\setcclcucx 1EE5 1EE5 1EE4 % LATIN SMALL LETTER U WITH DOT BELOW
-\setcclcucx 1EE6 1EE7 1EE6 % LATIN CAPITAL LETTER U WITH HOOK ABOVE
-\setcclcucx 1EE7 1EE7 1EE6 % LATIN SMALL LETTER U WITH HOOK ABOVE
-\setcclcucx 1EE8 1EE9 1EE8 % LATIN CAPITAL LETTER U WITH HORN AND ACUTE
-\setcclcucx 1EE9 1EE9 1EE8 % LATIN SMALL LETTER U WITH HORN AND ACUTE
-\setcclcucx 1EEA 1EEB 1EEA % LATIN CAPITAL LETTER U WITH HORN AND GRAVE
-\setcclcucx 1EEB 1EEB 1EEA % LATIN SMALL LETTER U WITH HORN AND GRAVE
-\setcclcucx 1EEC 1EED 1EEC % LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
-\setcclcucx 1EED 1EED 1EEC % LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
-\setcclcucx 1EEE 1EEF 1EEE % LATIN CAPITAL LETTER U WITH HORN AND TILDE
-\setcclcucx 1EEF 1EEF 1EEE % LATIN SMALL LETTER U WITH HORN AND TILDE
-\setcclcucx 1EF0 1EF1 1EF0 % LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
-\setcclcucx 1EF1 1EF1 1EF0 % LATIN SMALL LETTER U WITH HORN AND DOT BELOW
-\setcclcucx 1EF2 1EF3 1EF2 % LATIN CAPITAL LETTER Y WITH GRAVE
-\setcclcucx 1EF3 1EF3 1EF2 % LATIN SMALL LETTER Y WITH GRAVE
-\setcclcucx 1EF4 1EF5 1EF4 % LATIN CAPITAL LETTER Y WITH DOT BELOW
-\setcclcucx 1EF5 1EF5 1EF4 % LATIN SMALL LETTER Y WITH DOT BELOW
-\setcclcucx 1EF6 1EF7 1EF6 % LATIN CAPITAL LETTER Y WITH HOOK ABOVE
-\setcclcucx 1EF7 1EF7 1EF6 % LATIN SMALL LETTER Y WITH HOOK ABOVE
-\setcclcucx 1EF8 1EF9 1EF8 % LATIN CAPITAL LETTER Y WITH TILDE
-\setcclcucx 1EF9 1EF9 1EF8 % LATIN SMALL LETTER Y WITH TILDE
-\setcclcucx 1F00 1F00 1F08 % GREEK SMALL LETTER ALPHA WITH PSILI
-\setcclcucx 1F01 1F01 1F09 % GREEK SMALL LETTER ALPHA WITH DASIA
-\setcclcucx 1F02 1F02 1F0A % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA
-\setcclcucx 1F03 1F03 1F0B % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA
-\setcclcucx 1F04 1F04 1F0C % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA
-\setcclcucx 1F05 1F05 1F0D % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA
-\setcclcucx 1F06 1F06 1F0E % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F07 1F07 1F0F % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F08 1F00 1F08 % GREEK CAPITAL LETTER ALPHA WITH PSILI
-\setcclcucx 1F09 1F01 1F09 % GREEK CAPITAL LETTER ALPHA WITH DASIA
-\setcclcucx 1F0A 1F02 1F0A % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
-\setcclcucx 1F0B 1F03 1F0B % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
-\setcclcucx 1F0C 1F04 1F0C % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
-\setcclcucx 1F0D 1F05 1F0D % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
-\setcclcucx 1F0E 1F06 1F0E % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F0F 1F07 1F0F % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F10 1F10 1F18 % GREEK SMALL LETTER EPSILON WITH PSILI
-\setcclcucx 1F11 1F11 1F19 % GREEK SMALL LETTER EPSILON WITH DASIA
-\setcclcucx 1F12 1F12 1F1A % GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA
-\setcclcucx 1F13 1F13 1F1B % GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA
-\setcclcucx 1F14 1F14 1F1C % GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA
-\setcclcucx 1F15 1F15 1F1D % GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
-\setcclcucx 1F18 1F10 1F18 % GREEK CAPITAL LETTER EPSILON WITH PSILI
-\setcclcucx 1F19 1F11 1F19 % GREEK CAPITAL LETTER EPSILON WITH DASIA
-\setcclcucx 1F1A 1F12 1F1A % GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
-\setcclcucx 1F1B 1F13 1F1B % GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
-\setcclcucx 1F1C 1F14 1F1C % GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
-\setcclcucx 1F1D 1F15 1F1D % GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
-\setcclcucx 1F20 1F20 1F28 % GREEK SMALL LETTER ETA WITH PSILI
-\setcclcucx 1F21 1F21 1F29 % GREEK SMALL LETTER ETA WITH DASIA
-\setcclcucx 1F22 1F22 1F2A % GREEK SMALL LETTER ETA WITH PSILI AND VARIA
-\setcclcucx 1F23 1F23 1F2B % GREEK SMALL LETTER ETA WITH DASIA AND VARIA
-\setcclcucx 1F24 1F24 1F2C % GREEK SMALL LETTER ETA WITH PSILI AND OXIA
-\setcclcucx 1F25 1F25 1F2D % GREEK SMALL LETTER ETA WITH DASIA AND OXIA
-\setcclcucx 1F26 1F26 1F2E % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F27 1F27 1F2F % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F28 1F20 1F28 % GREEK CAPITAL LETTER ETA WITH PSILI
-\setcclcucx 1F29 1F21 1F29 % GREEK CAPITAL LETTER ETA WITH DASIA
-\setcclcucx 1F2A 1F22 1F2A % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
-\setcclcucx 1F2B 1F23 1F2B % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
-\setcclcucx 1F2C 1F24 1F2C % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
-\setcclcucx 1F2D 1F25 1F2D % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
-\setcclcucx 1F2E 1F26 1F2E % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F2F 1F27 1F2F % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F30 1F30 1F38 % GREEK SMALL LETTER IOTA WITH PSILI
-\setcclcucx 1F31 1F31 1F39 % GREEK SMALL LETTER IOTA WITH DASIA
-\setcclcucx 1F32 1F32 1F3A % GREEK SMALL LETTER IOTA WITH PSILI AND VARIA
-\setcclcucx 1F33 1F33 1F3B % GREEK SMALL LETTER IOTA WITH DASIA AND VARIA
-\setcclcucx 1F34 1F34 1F3C % GREEK SMALL LETTER IOTA WITH PSILI AND OXIA
-\setcclcucx 1F35 1F35 1F3D % GREEK SMALL LETTER IOTA WITH DASIA AND OXIA
-\setcclcucx 1F36 1F36 1F3E % GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F37 1F37 1F3F % GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F38 1F30 1F38 % GREEK CAPITAL LETTER IOTA WITH PSILI
-\setcclcucx 1F39 1F31 1F39 % GREEK CAPITAL LETTER IOTA WITH DASIA
-\setcclcucx 1F3A 1F32 1F3A % GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
-\setcclcucx 1F3B 1F33 1F3B % GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
-\setcclcucx 1F3C 1F34 1F3C % GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
-\setcclcucx 1F3D 1F35 1F3D % GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
-\setcclcucx 1F3E 1F36 1F3E % GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F3F 1F37 1F3F % GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F40 1F40 1F48 % GREEK SMALL LETTER OMICRON WITH PSILI
-\setcclcucx 1F41 1F41 1F49 % GREEK SMALL LETTER OMICRON WITH DASIA
-\setcclcucx 1F42 1F42 1F4A % GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA
-\setcclcucx 1F43 1F43 1F4B % GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA
-\setcclcucx 1F44 1F44 1F4C % GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA
-\setcclcucx 1F45 1F45 1F4D % GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
-\setcclcucx 1F48 1F40 1F48 % GREEK CAPITAL LETTER OMICRON WITH PSILI
-\setcclcucx 1F49 1F41 1F49 % GREEK CAPITAL LETTER OMICRON WITH DASIA
-\setcclcucx 1F4A 1F42 1F4A % GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
-\setcclcucx 1F4B 1F43 1F4B % GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
-\setcclcucx 1F4C 1F44 1F4C % GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
-\setcclcucx 1F4D 1F45 1F4D % GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
-\setcclcucx 1F50 1F50 1F50 % GREEK SMALL LETTER UPSILON WITH PSILI
-\setcclcucx 1F51 1F51 1F59 % GREEK SMALL LETTER UPSILON WITH DASIA
-\setcclcucx 1F52 1F52 1F52 % GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
-\setcclcucx 1F53 1F53 1F5B % GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA
-\setcclcucx 1F54 1F54 1F54 % GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
-\setcclcucx 1F55 1F55 1F5D % GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA
-\setcclcucx 1F56 1F56 1F56 % GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
-\setcclcucx 1F57 1F57 1F5F % GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
-\setcclcucx 1F59 1F51 1F59 % GREEK CAPITAL LETTER UPSILON WITH DASIA
-\setcclcucx 1F5B 1F53 1F5B % GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
-\setcclcucx 1F5D 1F55 1F5D % GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
-\setcclcucx 1F5F 1F57 1F5F % GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
-\setcclcucx 1F60 1F60 1F68 % GREEK SMALL LETTER OMEGA WITH PSILI
-\setcclcucx 1F61 1F61 1F69 % GREEK SMALL LETTER OMEGA WITH DASIA
-\setcclcucx 1F62 1F62 1F6A % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA
-\setcclcucx 1F63 1F63 1F6B % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA
-\setcclcucx 1F64 1F64 1F6C % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA
-\setcclcucx 1F65 1F65 1F6D % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA
-\setcclcucx 1F66 1F66 1F6E % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F67 1F67 1F6F % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F68 1F60 1F68 % GREEK CAPITAL LETTER OMEGA WITH PSILI
-\setcclcucx 1F69 1F61 1F69 % GREEK CAPITAL LETTER OMEGA WITH DASIA
-\setcclcucx 1F6A 1F62 1F6A % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
-\setcclcucx 1F6B 1F63 1F6B % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
-\setcclcucx 1F6C 1F64 1F6C % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
-\setcclcucx 1F6D 1F65 1F6D % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
-\setcclcucx 1F6E 1F66 1F6E % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
-\setcclcucx 1F6F 1F67 1F6F % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
-\setcclcucx 1F70 1F70 1FBA % GREEK SMALL LETTER ALPHA WITH VARIA
-\setcclcucx 1F71 1F71 1FBB % GREEK SMALL LETTER ALPHA WITH OXIA
-\setcclcucx 1F72 1F72 1FC8 % GREEK SMALL LETTER EPSILON WITH VARIA
-\setcclcucx 1F73 1F73 1FC9 % GREEK SMALL LETTER EPSILON WITH OXIA
-\setcclcucx 1F74 1F74 1FCA % GREEK SMALL LETTER ETA WITH VARIA
-\setcclcucx 1F75 1F75 1FCB % GREEK SMALL LETTER ETA WITH OXIA
-\setcclcucx 1F76 1F76 1FDA % GREEK SMALL LETTER IOTA WITH VARIA
-\setcclcucx 1F77 1F77 1FDB % GREEK SMALL LETTER IOTA WITH OXIA
-\setcclcucx 1F78 1F78 1FF8 % GREEK SMALL LETTER OMICRON WITH VARIA
-\setcclcucx 1F79 1F79 1FF9 % GREEK SMALL LETTER OMICRON WITH OXIA
-\setcclcucx 1F7A 1F7A 1FEA % GREEK SMALL LETTER UPSILON WITH VARIA
-\setcclcucx 1F7B 1F7B 1FEB % GREEK SMALL LETTER UPSILON WITH OXIA
-\setcclcucx 1F7C 1F7C 1FFA % GREEK SMALL LETTER OMEGA WITH VARIA
-\setcclcucx 1F7D 1F7D 1FFB % GREEK SMALL LETTER OMEGA WITH OXIA
-\setcclcucx 1F80 1F80 1F88 % GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
-\setcclcucx 1F81 1F81 1F89 % GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
-\setcclcucx 1F82 1F82 1F8A % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-\setcclcucx 1F83 1F83 1F8B % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-\setcclcucx 1F84 1F84 1F8C % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-\setcclcucx 1F85 1F85 1F8D % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-\setcclcucx 1F86 1F86 1F8E % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1F87 1F87 1F8F % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1F88 1F80 1F88 % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
-\setcclcucx 1F89 1F81 1F89 % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
-\setcclcucx 1F8A 1F82 1F8A % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-\setcclcucx 1F8B 1F83 1F8B % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-\setcclcucx 1F8C 1F84 1F8C % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-\setcclcucx 1F8D 1F85 1F8D % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-\setcclcucx 1F8E 1F86 1F8E % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-\setcclcucx 1F8F 1F87 1F8F % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-\setcclcucx 1F90 1F90 1F98 % GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
-\setcclcucx 1F91 1F91 1F99 % GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
-\setcclcucx 1F92 1F92 1F9A % GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-\setcclcucx 1F93 1F93 1F9B % GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-\setcclcucx 1F94 1F94 1F9C % GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-\setcclcucx 1F95 1F95 1F9D % GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-\setcclcucx 1F96 1F96 1F9E % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1F97 1F97 1F9F % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1F98 1F90 1F98 % GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
-\setcclcucx 1F99 1F91 1F99 % GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
-\setcclcucx 1F9A 1F92 1F9A % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-\setcclcucx 1F9B 1F93 1F9B % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-\setcclcucx 1F9C 1F94 1F9C % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-\setcclcucx 1F9D 1F95 1F9D % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-\setcclcucx 1F9E 1F96 1F9E % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-\setcclcucx 1F9F 1F97 1F9F % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-\setcclcucx 1FA0 1FA0 1FA8 % GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
-\setcclcucx 1FA1 1FA1 1FA9 % GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
-\setcclcucx 1FA2 1FA2 1FAA % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-\setcclcucx 1FA3 1FA3 1FAB % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-\setcclcucx 1FA4 1FA4 1FAC % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-\setcclcucx 1FA5 1FA5 1FAD % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-\setcclcucx 1FA6 1FA6 1FAE % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1FA7 1FA7 1FAF % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1FA8 1FA0 1FA8 % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
-\setcclcucx 1FA9 1FA1 1FA9 % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
-\setcclcucx 1FAA 1FA2 1FAA % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-\setcclcucx 1FAB 1FA3 1FAB % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-\setcclcucx 1FAC 1FA4 1FAC % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-\setcclcucx 1FAD 1FA5 1FAD % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-\setcclcucx 1FAE 1FA6 1FAE % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-\setcclcucx 1FAF 1FA7 1FAF % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-\setcclcucx 1FB0 1FB0 1FB8 % GREEK SMALL LETTER ALPHA WITH VRACHY
-\setcclcucx 1FB1 1FB1 1FB9 % GREEK SMALL LETTER ALPHA WITH MACRON
-\setcclcucx 1FB2 1FB2 1FB2 % GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
-\setcclcucx 1FB3 1FB3 1FBC % GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
-\setcclcucx 1FB4 1FB4 1FB4 % GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-\setcclcucx 1FB6 1FB6 1FB6 % GREEK SMALL LETTER ALPHA WITH PERISPOMENI
-\setcclcucx 1FB7 1FB7 1FB7 % GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1FB8 1FB0 1FB8 % GREEK CAPITAL LETTER ALPHA WITH VRACHY
-\setcclcucx 1FB9 1FB1 1FB9 % GREEK CAPITAL LETTER ALPHA WITH MACRON
-\setcclcucx 1FBA 1F70 1FBA % GREEK CAPITAL LETTER ALPHA WITH VARIA
-\setcclcucx 1FBB 1F71 1FBB % GREEK CAPITAL LETTER ALPHA WITH OXIA
-\setcclcucx 1FBC 1FB3 1FBC % GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-\setcclcucx 1FBE 1FBE 0399 % GREEK PROSGEGRAMMENI
-\setcclcucx 1FC2 1FC2 1FC2 % GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
-\setcclcucx 1FC3 1FC3 1FCC % GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
-\setcclcucx 1FC4 1FC4 1FC4 % GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-\setcclcucx 1FC6 1FC6 1FC6 % GREEK SMALL LETTER ETA WITH PERISPOMENI
-\setcclcucx 1FC7 1FC7 1FC7 % GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1FC8 1F72 1FC8 % GREEK CAPITAL LETTER EPSILON WITH VARIA
-\setcclcucx 1FC9 1F73 1FC9 % GREEK CAPITAL LETTER EPSILON WITH OXIA
-\setcclcucx 1FCA 1F74 1FCA % GREEK CAPITAL LETTER ETA WITH VARIA
-\setcclcucx 1FCB 1F75 1FCB % GREEK CAPITAL LETTER ETA WITH OXIA
-\setcclcucx 1FCC 1FC3 1FCC % GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-\setcclcucx 1FD0 1FD0 1FD8 % GREEK SMALL LETTER IOTA WITH VRACHY
-\setcclcucx 1FD1 1FD1 1FD9 % GREEK SMALL LETTER IOTA WITH MACRON
-\setcclcucx 1FD2 1FD2 1FD2 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
-\setcclcucx 1FD3 1FD3 1FD3 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-\setcclcucx 1FD6 1FD6 1FD6 % GREEK SMALL LETTER IOTA WITH PERISPOMENI
-\setcclcucx 1FD7 1FD7 1FD7 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
-\setcclcucx 1FD8 1FD0 1FD8 % GREEK CAPITAL LETTER IOTA WITH VRACHY
-\setcclcucx 1FD9 1FD1 1FD9 % GREEK CAPITAL LETTER IOTA WITH MACRON
-\setcclcucx 1FDA 1F76 1FDA % GREEK CAPITAL LETTER IOTA WITH VARIA
-\setcclcucx 1FDB 1F77 1FDB % GREEK CAPITAL LETTER IOTA WITH OXIA
-\setcclcucx 1FE0 1FE0 1FE8 % GREEK SMALL LETTER UPSILON WITH VRACHY
-\setcclcucx 1FE1 1FE1 1FE9 % GREEK SMALL LETTER UPSILON WITH MACRON
-\setcclcucx 1FE2 1FE2 1FE2 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
-\setcclcucx 1FE3 1FE3 1FE3 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
-\setcclcucx 1FE4 1FE4 1FE4 % GREEK SMALL LETTER RHO WITH PSILI
-\setcclcucx 1FE5 1FE5 1FEC % GREEK SMALL LETTER RHO WITH DASIA
-\setcclcucx 1FE6 1FE6 1FE6 % GREEK SMALL LETTER UPSILON WITH PERISPOMENI
-\setcclcucx 1FE7 1FE7 1FE7 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
-\setcclcucx 1FE8 1FE0 1FE8 % GREEK CAPITAL LETTER UPSILON WITH VRACHY
-\setcclcucx 1FE9 1FE1 1FE9 % GREEK CAPITAL LETTER UPSILON WITH MACRON
-\setcclcucx 1FEA 1F7A 1FEA % GREEK CAPITAL LETTER UPSILON WITH VARIA
-\setcclcucx 1FEB 1F7B 1FEB % GREEK CAPITAL LETTER UPSILON WITH OXIA
-\setcclcucx 1FEC 1FE5 1FEC % GREEK CAPITAL LETTER RHO WITH DASIA
-\setcclcucx 1FF2 1FF2 1FF2 % GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
-\setcclcucx 1FF3 1FF3 1FFC % GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
-\setcclcucx 1FF4 1FF4 1FF4 % GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-\setcclcucx 1FF6 1FF6 1FF6 % GREEK SMALL LETTER OMEGA WITH PERISPOMENI
-\setcclcucx 1FF7 1FF7 1FF7 % GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
-\setcclcucx 1FF8 1F78 1FF8 % GREEK CAPITAL LETTER OMICRON WITH VARIA
-\setcclcucx 1FF9 1F79 1FF9 % GREEK CAPITAL LETTER OMICRON WITH OXIA
-\setcclcucx 1FFA 1F7C 1FFA % GREEK CAPITAL LETTER OMEGA WITH VARIA
-\setcclcucx 1FFB 1F7D 1FFB % GREEK CAPITAL LETTER OMEGA WITH OXIA
-\setcclcucx 1FFC 1FF3 1FFC % GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-\setcclcucx 2071 2071 2071 % SUPERSCRIPT LATIN SMALL LETTER I
-\setcclcucx 207F 207F 207F % SUPERSCRIPT LATIN SMALL LETTER N
-\setcclcucx 2102 2102 2102 % DOUBLE-STRUCK CAPITAL C
-\setcclcucx 2107 2107 2107 % EULER CONSTANT
-\setcclcucx 210A 210A 210A % SCRIPT SMALL G
-\setcclcucx 210B 210B 210B % SCRIPT CAPITAL H
-\setcclcucx 210C 210C 210C % BLACK-LETTER CAPITAL H
-\setcclcucx 210D 210D 210D % DOUBLE-STRUCK CAPITAL H
-\setcclcucx 210E 210E 210E % PLANCK CONSTANT
-\setcclcucx 210F 210F 210F % PLANCK CONSTANT OVER TWO PI
-\setcclcucx 2110 2110 2110 % SCRIPT CAPITAL I
-\setcclcucx 2111 2111 2111 % BLACK-LETTER CAPITAL I
-\setcclcucx 2112 2112 2112 % SCRIPT CAPITAL L
-\setcclcucx 2113 2113 2113 % SCRIPT SMALL L
-\setcclcucx 2115 2115 2115 % DOUBLE-STRUCK CAPITAL N
-\setcclcucx 2119 2119 2119 % DOUBLE-STRUCK CAPITAL P
-\setcclcucx 211A 211A 211A % DOUBLE-STRUCK CAPITAL Q
-\setcclcucx 211B 211B 211B % SCRIPT CAPITAL R
-\setcclcucx 211C 211C 211C % BLACK-LETTER CAPITAL R
-\setcclcucx 211D 211D 211D % DOUBLE-STRUCK CAPITAL R
-\setcclcucx 2124 2124 2124 % DOUBLE-STRUCK CAPITAL Z
-\setcclcucx 2126 03C9 2126 % OHM SIGN
-\setcclcucx 2128 2128 2128 % BLACK-LETTER CAPITAL Z
-\setcclcucx 212A 006B 212A % KELVIN SIGN
-\setcclcucx 212B 00E5 212B % ANGSTROM SIGN
-\setcclcucx 212C 212C 212C % SCRIPT CAPITAL B
-\setcclcucx 212D 212D 212D % BLACK-LETTER CAPITAL C
-\setcclcucx 212F 212F 212F % SCRIPT SMALL E
-\setcclcucx 2130 2130 2130 % SCRIPT CAPITAL E
-\setcclcucx 2131 2131 2131 % SCRIPT CAPITAL F
-\setcclcucx 2132 214E 2132 % TURNED CAPITAL F
-\setcclcucx 2133 2133 2133 % SCRIPT CAPITAL M
-\setcclcucx 2134 2134 2134 % SCRIPT SMALL O
-\setcclcucx 2139 2139 2139 % INFORMATION SOURCE
-\setcclcucx 213C 213C 213C % DOUBLE-STRUCK SMALL PI
-\setcclcucx 213D 213D 213D % DOUBLE-STRUCK SMALL GAMMA
-\setcclcucx 213E 213E 213E % DOUBLE-STRUCK CAPITAL GAMMA
-\setcclcucx 213F 213F 213F % DOUBLE-STRUCK CAPITAL PI
-\setcclcucx 2145 2145 2145 % DOUBLE-STRUCK ITALIC CAPITAL D
-\setcclcucx 2146 2146 2146 % DOUBLE-STRUCK ITALIC SMALL D
-\setcclcucx 2147 2147 2147 % DOUBLE-STRUCK ITALIC SMALL E
-\setcclcucx 2148 2148 2148 % DOUBLE-STRUCK ITALIC SMALL I
-\setcclcucx 2149 2149 2149 % DOUBLE-STRUCK ITALIC SMALL J
-\setcclcucx 214E 214E 2132 % TURNED SMALL F
-\setcclcucx 2183 2184 2183 % ROMAN NUMERAL REVERSED ONE HUNDRED
-\setcclcucx 2184 2184 2183 % LATIN SMALL LETTER REVERSED C
-\setcclcucx 2C00 2C30 2C00 % GLAGOLITIC CAPITAL LETTER AZU
-\setcclcucx 2C01 2C31 2C01 % GLAGOLITIC CAPITAL LETTER BUKY
-\setcclcucx 2C02 2C32 2C02 % GLAGOLITIC CAPITAL LETTER VEDE
-\setcclcucx 2C03 2C33 2C03 % GLAGOLITIC CAPITAL LETTER GLAGOLI
-\setcclcucx 2C04 2C34 2C04 % GLAGOLITIC CAPITAL LETTER DOBRO
-\setcclcucx 2C05 2C35 2C05 % GLAGOLITIC CAPITAL LETTER YESTU
-\setcclcucx 2C06 2C36 2C06 % GLAGOLITIC CAPITAL LETTER ZHIVETE
-\setcclcucx 2C07 2C37 2C07 % GLAGOLITIC CAPITAL LETTER DZELO
-\setcclcucx 2C08 2C38 2C08 % GLAGOLITIC CAPITAL LETTER ZEMLJA
-\setcclcucx 2C09 2C39 2C09 % GLAGOLITIC CAPITAL LETTER IZHE
-\setcclcucx 2C0A 2C3A 2C0A % GLAGOLITIC CAPITAL LETTER INITIAL IZHE
-\setcclcucx 2C0B 2C3B 2C0B % GLAGOLITIC CAPITAL LETTER I
-\setcclcucx 2C0C 2C3C 2C0C % GLAGOLITIC CAPITAL LETTER DJERVI
-\setcclcucx 2C0D 2C3D 2C0D % GLAGOLITIC CAPITAL LETTER KAKO
-\setcclcucx 2C0E 2C3E 2C0E % GLAGOLITIC CAPITAL LETTER LJUDIJE
-\setcclcucx 2C0F 2C3F 2C0F % GLAGOLITIC CAPITAL LETTER MYSLITE
-\setcclcucx 2C10 2C40 2C10 % GLAGOLITIC CAPITAL LETTER NASHI
-\setcclcucx 2C11 2C41 2C11 % GLAGOLITIC CAPITAL LETTER ONU
-\setcclcucx 2C12 2C42 2C12 % GLAGOLITIC CAPITAL LETTER POKOJI
-\setcclcucx 2C13 2C43 2C13 % GLAGOLITIC CAPITAL LETTER RITSI
-\setcclcucx 2C14 2C44 2C14 % GLAGOLITIC CAPITAL LETTER SLOVO
-\setcclcucx 2C15 2C45 2C15 % GLAGOLITIC CAPITAL LETTER TVRIDO
-\setcclcucx 2C16 2C46 2C16 % GLAGOLITIC CAPITAL LETTER UKU
-\setcclcucx 2C17 2C47 2C17 % GLAGOLITIC CAPITAL LETTER FRITU
-\setcclcucx 2C18 2C48 2C18 % GLAGOLITIC CAPITAL LETTER HERU
-\setcclcucx 2C19 2C49 2C19 % GLAGOLITIC CAPITAL LETTER OTU
-\setcclcucx 2C1A 2C4A 2C1A % GLAGOLITIC CAPITAL LETTER PE
-\setcclcucx 2C1B 2C4B 2C1B % GLAGOLITIC CAPITAL LETTER SHTA
-\setcclcucx 2C1C 2C4C 2C1C % GLAGOLITIC CAPITAL LETTER TSI
-\setcclcucx 2C1D 2C4D 2C1D % GLAGOLITIC CAPITAL LETTER CHRIVI
-\setcclcucx 2C1E 2C4E 2C1E % GLAGOLITIC CAPITAL LETTER SHA
-\setcclcucx 2C1F 2C4F 2C1F % GLAGOLITIC CAPITAL LETTER YERU
-\setcclcucx 2C20 2C50 2C20 % GLAGOLITIC CAPITAL LETTER YERI
-\setcclcucx 2C21 2C51 2C21 % GLAGOLITIC CAPITAL LETTER YATI
-\setcclcucx 2C22 2C52 2C22 % GLAGOLITIC CAPITAL LETTER SPIDERY HA
-\setcclcucx 2C23 2C53 2C23 % GLAGOLITIC CAPITAL LETTER YU
-\setcclcucx 2C24 2C54 2C24 % GLAGOLITIC CAPITAL LETTER SMALL YUS
-\setcclcucx 2C25 2C55 2C25 % GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
-\setcclcucx 2C26 2C56 2C26 % GLAGOLITIC CAPITAL LETTER YO
-\setcclcucx 2C27 2C57 2C27 % GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
-\setcclcucx 2C28 2C58 2C28 % GLAGOLITIC CAPITAL LETTER BIG YUS
-\setcclcucx 2C29 2C59 2C29 % GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
-\setcclcucx 2C2A 2C5A 2C2A % GLAGOLITIC CAPITAL LETTER FITA
-\setcclcucx 2C2B 2C5B 2C2B % GLAGOLITIC CAPITAL LETTER IZHITSA
-\setcclcucx 2C2C 2C5C 2C2C % GLAGOLITIC CAPITAL LETTER SHTAPIC
-\setcclcucx 2C2D 2C5D 2C2D % GLAGOLITIC CAPITAL LETTER TROKUTASTI A
-\setcclcucx 2C2E 2C5E 2C2E % GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
-\setcclcucx 2C30 2C30 2C00 % GLAGOLITIC SMALL LETTER AZU
-\setcclcucx 2C31 2C31 2C01 % GLAGOLITIC SMALL LETTER BUKY
-\setcclcucx 2C32 2C32 2C02 % GLAGOLITIC SMALL LETTER VEDE
-\setcclcucx 2C33 2C33 2C03 % GLAGOLITIC SMALL LETTER GLAGOLI
-\setcclcucx 2C34 2C34 2C04 % GLAGOLITIC SMALL LETTER DOBRO
-\setcclcucx 2C35 2C35 2C05 % GLAGOLITIC SMALL LETTER YESTU
-\setcclcucx 2C36 2C36 2C06 % GLAGOLITIC SMALL LETTER ZHIVETE
-\setcclcucx 2C37 2C37 2C07 % GLAGOLITIC SMALL LETTER DZELO
-\setcclcucx 2C38 2C38 2C08 % GLAGOLITIC SMALL LETTER ZEMLJA
-\setcclcucx 2C39 2C39 2C09 % GLAGOLITIC SMALL LETTER IZHE
-\setcclcucx 2C3A 2C3A 2C0A % GLAGOLITIC SMALL LETTER INITIAL IZHE
-\setcclcucx 2C3B 2C3B 2C0B % GLAGOLITIC SMALL LETTER I
-\setcclcucx 2C3C 2C3C 2C0C % GLAGOLITIC SMALL LETTER DJERVI
-\setcclcucx 2C3D 2C3D 2C0D % GLAGOLITIC SMALL LETTER KAKO
-\setcclcucx 2C3E 2C3E 2C0E % GLAGOLITIC SMALL LETTER LJUDIJE
-\setcclcucx 2C3F 2C3F 2C0F % GLAGOLITIC SMALL LETTER MYSLITE
-\setcclcucx 2C40 2C40 2C10 % GLAGOLITIC SMALL LETTER NASHI
-\setcclcucx 2C41 2C41 2C11 % GLAGOLITIC SMALL LETTER ONU
-\setcclcucx 2C42 2C42 2C12 % GLAGOLITIC SMALL LETTER POKOJI
-\setcclcucx 2C43 2C43 2C13 % GLAGOLITIC SMALL LETTER RITSI
-\setcclcucx 2C44 2C44 2C14 % GLAGOLITIC SMALL LETTER SLOVO
-\setcclcucx 2C45 2C45 2C15 % GLAGOLITIC SMALL LETTER TVRIDO
-\setcclcucx 2C46 2C46 2C16 % GLAGOLITIC SMALL LETTER UKU
-\setcclcucx 2C47 2C47 2C17 % GLAGOLITIC SMALL LETTER FRITU
-\setcclcucx 2C48 2C48 2C18 % GLAGOLITIC SMALL LETTER HERU
-\setcclcucx 2C49 2C49 2C19 % GLAGOLITIC SMALL LETTER OTU
-\setcclcucx 2C4A 2C4A 2C1A % GLAGOLITIC SMALL LETTER PE
-\setcclcucx 2C4B 2C4B 2C1B % GLAGOLITIC SMALL LETTER SHTA
-\setcclcucx 2C4C 2C4C 2C1C % GLAGOLITIC SMALL LETTER TSI
-\setcclcucx 2C4D 2C4D 2C1D % GLAGOLITIC SMALL LETTER CHRIVI
-\setcclcucx 2C4E 2C4E 2C1E % GLAGOLITIC SMALL LETTER SHA
-\setcclcucx 2C4F 2C4F 2C1F % GLAGOLITIC SMALL LETTER YERU
-\setcclcucx 2C50 2C50 2C20 % GLAGOLITIC SMALL LETTER YERI
-\setcclcucx 2C51 2C51 2C21 % GLAGOLITIC SMALL LETTER YATI
-\setcclcucx 2C52 2C52 2C22 % GLAGOLITIC SMALL LETTER SPIDERY HA
-\setcclcucx 2C53 2C53 2C23 % GLAGOLITIC SMALL LETTER YU
-\setcclcucx 2C54 2C54 2C24 % GLAGOLITIC SMALL LETTER SMALL YUS
-\setcclcucx 2C55 2C55 2C25 % GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL
-\setcclcucx 2C56 2C56 2C26 % GLAGOLITIC SMALL LETTER YO
-\setcclcucx 2C57 2C57 2C27 % GLAGOLITIC SMALL LETTER IOTATED SMALL YUS
-\setcclcucx 2C58 2C58 2C28 % GLAGOLITIC SMALL LETTER BIG YUS
-\setcclcucx 2C59 2C59 2C29 % GLAGOLITIC SMALL LETTER IOTATED BIG YUS
-\setcclcucx 2C5A 2C5A 2C2A % GLAGOLITIC SMALL LETTER FITA
-\setcclcucx 2C5B 2C5B 2C2B % GLAGOLITIC SMALL LETTER IZHITSA
-\setcclcucx 2C5C 2C5C 2C2C % GLAGOLITIC SMALL LETTER SHTAPIC
-\setcclcucx 2C5D 2C5D 2C2D % GLAGOLITIC SMALL LETTER TROKUTASTI A
-\setcclcucx 2C5E 2C5E 2C2E % GLAGOLITIC SMALL LETTER LATINATE MYSLITE
-\setcclcucx 2C60 2C61 2C60 % LATIN CAPITAL LETTER L WITH DOUBLE BAR
-\setcclcucx 2C61 2C61 2C60 % LATIN SMALL LETTER L WITH DOUBLE BAR
-\setcclcucx 2C62 026B 2C62 % LATIN CAPITAL LETTER L WITH MIDDLE TILDE
-\setcclcucx 2C63 1D7D 2C63 % LATIN CAPITAL LETTER P WITH STROKE
-\setcclcucx 2C64 027D 2C64 % LATIN CAPITAL LETTER R WITH TAIL
-\setcclcucx 2C65 2C65 023A % LATIN SMALL LETTER A WITH STROKE
-\setcclcucx 2C66 2C66 023E % LATIN SMALL LETTER T WITH DIAGONAL STROKE
-\setcclcucx 2C67 2C68 2C67 % LATIN CAPITAL LETTER H WITH DESCENDER
-\setcclcucx 2C68 2C68 2C67 % LATIN SMALL LETTER H WITH DESCENDER
-\setcclcucx 2C69 2C6A 2C69 % LATIN CAPITAL LETTER K WITH DESCENDER
-\setcclcucx 2C6A 2C6A 2C69 % LATIN SMALL LETTER K WITH DESCENDER
-\setcclcucx 2C6B 2C6C 2C6B % LATIN CAPITAL LETTER Z WITH DESCENDER
-\setcclcucx 2C6C 2C6C 2C6B % LATIN SMALL LETTER Z WITH DESCENDER
-\setcclcucx 2C74 2C74 2C74 % LATIN SMALL LETTER V WITH CURL
-\setcclcucx 2C75 2C76 2C75 % LATIN CAPITAL LETTER HALF H
-\setcclcucx 2C76 2C76 2C75 % LATIN SMALL LETTER HALF H
-\setcclcucx 2C77 2C77 2C77 % LATIN SMALL LETTER TAILLESS PHI
-\setcclcucx 2C80 2C81 2C80 % COPTIC CAPITAL LETTER ALFA
-\setcclcucx 2C81 2C81 2C80 % COPTIC SMALL LETTER ALFA
-\setcclcucx 2C82 2C83 2C82 % COPTIC CAPITAL LETTER VIDA
-\setcclcucx 2C83 2C83 2C82 % COPTIC SMALL LETTER VIDA
-\setcclcucx 2C84 2C85 2C84 % COPTIC CAPITAL LETTER GAMMA
-\setcclcucx 2C85 2C85 2C84 % COPTIC SMALL LETTER GAMMA
-\setcclcucx 2C86 2C87 2C86 % COPTIC CAPITAL LETTER DALDA
-\setcclcucx 2C87 2C87 2C86 % COPTIC SMALL LETTER DALDA
-\setcclcucx 2C88 2C89 2C88 % COPTIC CAPITAL LETTER EIE
-\setcclcucx 2C89 2C89 2C88 % COPTIC SMALL LETTER EIE
-\setcclcucx 2C8A 2C8B 2C8A % COPTIC CAPITAL LETTER SOU
-\setcclcucx 2C8B 2C8B 2C8A % COPTIC SMALL LETTER SOU
-\setcclcucx 2C8C 2C8D 2C8C % COPTIC CAPITAL LETTER ZATA
-\setcclcucx 2C8D 2C8D 2C8C % COPTIC SMALL LETTER ZATA
-\setcclcucx 2C8E 2C8F 2C8E % COPTIC CAPITAL LETTER HATE
-\setcclcucx 2C8F 2C8F 2C8E % COPTIC SMALL LETTER HATE
-\setcclcucx 2C90 2C91 2C90 % COPTIC CAPITAL LETTER THETHE
-\setcclcucx 2C91 2C91 2C90 % COPTIC SMALL LETTER THETHE
-\setcclcucx 2C92 2C93 2C92 % COPTIC CAPITAL LETTER IAUDA
-\setcclcucx 2C93 2C93 2C92 % COPTIC SMALL LETTER IAUDA
-\setcclcucx 2C94 2C95 2C94 % COPTIC CAPITAL LETTER KAPA
-\setcclcucx 2C95 2C95 2C94 % COPTIC SMALL LETTER KAPA
-\setcclcucx 2C96 2C97 2C96 % COPTIC CAPITAL LETTER LAULA
-\setcclcucx 2C97 2C97 2C96 % COPTIC SMALL LETTER LAULA
-\setcclcucx 2C98 2C99 2C98 % COPTIC CAPITAL LETTER MI
-\setcclcucx 2C99 2C99 2C98 % COPTIC SMALL LETTER MI
-\setcclcucx 2C9A 2C9B 2C9A % COPTIC CAPITAL LETTER NI
-\setcclcucx 2C9B 2C9B 2C9A % COPTIC SMALL LETTER NI
-\setcclcucx 2C9C 2C9D 2C9C % COPTIC CAPITAL LETTER KSI
-\setcclcucx 2C9D 2C9D 2C9C % COPTIC SMALL LETTER KSI
-\setcclcucx 2C9E 2C9F 2C9E % COPTIC CAPITAL LETTER O
-\setcclcucx 2C9F 2C9F 2C9E % COPTIC SMALL LETTER O
-\setcclcucx 2CA0 2CA1 2CA0 % COPTIC CAPITAL LETTER PI
-\setcclcucx 2CA1 2CA1 2CA0 % COPTIC SMALL LETTER PI
-\setcclcucx 2CA2 2CA3 2CA2 % COPTIC CAPITAL LETTER RO
-\setcclcucx 2CA3 2CA3 2CA2 % COPTIC SMALL LETTER RO
-\setcclcucx 2CA4 2CA5 2CA4 % COPTIC CAPITAL LETTER SIMA
-\setcclcucx 2CA5 2CA5 2CA4 % COPTIC SMALL LETTER SIMA
-\setcclcucx 2CA6 2CA7 2CA6 % COPTIC CAPITAL LETTER TAU
-\setcclcucx 2CA7 2CA7 2CA6 % COPTIC SMALL LETTER TAU
-\setcclcucx 2CA8 2CA9 2CA8 % COPTIC CAPITAL LETTER UA
-\setcclcucx 2CA9 2CA9 2CA8 % COPTIC SMALL LETTER UA
-\setcclcucx 2CAA 2CAB 2CAA % COPTIC CAPITAL LETTER FI
-\setcclcucx 2CAB 2CAB 2CAA % COPTIC SMALL LETTER FI
-\setcclcucx 2CAC 2CAD 2CAC % COPTIC CAPITAL LETTER KHI
-\setcclcucx 2CAD 2CAD 2CAC % COPTIC SMALL LETTER KHI
-\setcclcucx 2CAE 2CAF 2CAE % COPTIC CAPITAL LETTER PSI
-\setcclcucx 2CAF 2CAF 2CAE % COPTIC SMALL LETTER PSI
-\setcclcucx 2CB0 2CB1 2CB0 % COPTIC CAPITAL LETTER OOU
-\setcclcucx 2CB1 2CB1 2CB0 % COPTIC SMALL LETTER OOU
-\setcclcucx 2CB2 2CB3 2CB2 % COPTIC CAPITAL LETTER DIALECT-P ALEF
-\setcclcucx 2CB3 2CB3 2CB2 % COPTIC SMALL LETTER DIALECT-P ALEF
-\setcclcucx 2CB4 2CB5 2CB4 % COPTIC CAPITAL LETTER OLD COPTIC AIN
-\setcclcucx 2CB5 2CB5 2CB4 % COPTIC SMALL LETTER OLD COPTIC AIN
-\setcclcucx 2CB6 2CB7 2CB6 % COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
-\setcclcucx 2CB7 2CB7 2CB6 % COPTIC SMALL LETTER CRYPTOGRAMMIC EIE
-\setcclcucx 2CB8 2CB9 2CB8 % COPTIC CAPITAL LETTER DIALECT-P KAPA
-\setcclcucx 2CB9 2CB9 2CB8 % COPTIC SMALL LETTER DIALECT-P KAPA
-\setcclcucx 2CBA 2CBB 2CBA % COPTIC CAPITAL LETTER DIALECT-P NI
-\setcclcucx 2CBB 2CBB 2CBA % COPTIC SMALL LETTER DIALECT-P NI
-\setcclcucx 2CBC 2CBD 2CBC % COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
-\setcclcucx 2CBD 2CBD 2CBC % COPTIC SMALL LETTER CRYPTOGRAMMIC NI
-\setcclcucx 2CBE 2CBF 2CBE % COPTIC CAPITAL LETTER OLD COPTIC OOU
-\setcclcucx 2CBF 2CBF 2CBE % COPTIC SMALL LETTER OLD COPTIC OOU
-\setcclcucx 2CC0 2CC1 2CC0 % COPTIC CAPITAL LETTER SAMPI
-\setcclcucx 2CC1 2CC1 2CC0 % COPTIC SMALL LETTER SAMPI
-\setcclcucx 2CC2 2CC3 2CC2 % COPTIC CAPITAL LETTER CROSSED SHEI
-\setcclcucx 2CC3 2CC3 2CC2 % COPTIC SMALL LETTER CROSSED SHEI
-\setcclcucx 2CC4 2CC5 2CC4 % COPTIC CAPITAL LETTER OLD COPTIC SHEI
-\setcclcucx 2CC5 2CC5 2CC4 % COPTIC SMALL LETTER OLD COPTIC SHEI
-\setcclcucx 2CC6 2CC7 2CC6 % COPTIC CAPITAL LETTER OLD COPTIC ESH
-\setcclcucx 2CC7 2CC7 2CC6 % COPTIC SMALL LETTER OLD COPTIC ESH
-\setcclcucx 2CC8 2CC9 2CC8 % COPTIC CAPITAL LETTER AKHMIMIC KHEI
-\setcclcucx 2CC9 2CC9 2CC8 % COPTIC SMALL LETTER AKHMIMIC KHEI
-\setcclcucx 2CCA 2CCB 2CCA % COPTIC CAPITAL LETTER DIALECT-P HORI
-\setcclcucx 2CCB 2CCB 2CCA % COPTIC SMALL LETTER DIALECT-P HORI
-\setcclcucx 2CCC 2CCD 2CCC % COPTIC CAPITAL LETTER OLD COPTIC HORI
-\setcclcucx 2CCD 2CCD 2CCC % COPTIC SMALL LETTER OLD COPTIC HORI
-\setcclcucx 2CCE 2CCF 2CCE % COPTIC CAPITAL LETTER OLD COPTIC HA
-\setcclcucx 2CCF 2CCF 2CCE % COPTIC SMALL LETTER OLD COPTIC HA
-\setcclcucx 2CD0 2CD1 2CD0 % COPTIC CAPITAL LETTER L-SHAPED HA
-\setcclcucx 2CD1 2CD1 2CD0 % COPTIC SMALL LETTER L-SHAPED HA
-\setcclcucx 2CD2 2CD3 2CD2 % COPTIC CAPITAL LETTER OLD COPTIC HEI
-\setcclcucx 2CD3 2CD3 2CD2 % COPTIC SMALL LETTER OLD COPTIC HEI
-\setcclcucx 2CD4 2CD5 2CD4 % COPTIC CAPITAL LETTER OLD COPTIC HAT
-\setcclcucx 2CD5 2CD5 2CD4 % COPTIC SMALL LETTER OLD COPTIC HAT
-\setcclcucx 2CD6 2CD7 2CD6 % COPTIC CAPITAL LETTER OLD COPTIC GANGIA
-\setcclcucx 2CD7 2CD7 2CD6 % COPTIC SMALL LETTER OLD COPTIC GANGIA
-\setcclcucx 2CD8 2CD9 2CD8 % COPTIC CAPITAL LETTER OLD COPTIC DJA
-\setcclcucx 2CD9 2CD9 2CD8 % COPTIC SMALL LETTER OLD COPTIC DJA
-\setcclcucx 2CDA 2CDB 2CDA % COPTIC CAPITAL LETTER OLD COPTIC SHIMA
-\setcclcucx 2CDB 2CDB 2CDA % COPTIC SMALL LETTER OLD COPTIC SHIMA
-\setcclcucx 2CDC 2CDD 2CDC % COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
-\setcclcucx 2CDD 2CDD 2CDC % COPTIC SMALL LETTER OLD NUBIAN SHIMA
-\setcclcucx 2CDE 2CDF 2CDE % COPTIC CAPITAL LETTER OLD NUBIAN NGI
-\setcclcucx 2CDF 2CDF 2CDE % COPTIC SMALL LETTER OLD NUBIAN NGI
-\setcclcucx 2CE0 2CE1 2CE0 % COPTIC CAPITAL LETTER OLD NUBIAN NYI
-\setcclcucx 2CE1 2CE1 2CE0 % COPTIC SMALL LETTER OLD NUBIAN NYI
-\setcclcucx 2CE2 2CE3 2CE2 % COPTIC CAPITAL LETTER OLD NUBIAN WAU
-\setcclcucx 2CE3 2CE3 2CE2 % COPTIC SMALL LETTER OLD NUBIAN WAU
-\setcclcucx 2CE4 2CE4 2CE4 % COPTIC SYMBOL KAI
-\setcclcucx 2D00 2D00 10A0 % GEORGIAN SMALL LETTER AN
-\setcclcucx 2D01 2D01 10A1 % GEORGIAN SMALL LETTER BAN
-\setcclcucx 2D02 2D02 10A2 % GEORGIAN SMALL LETTER GAN
-\setcclcucx 2D03 2D03 10A3 % GEORGIAN SMALL LETTER DON
-\setcclcucx 2D04 2D04 10A4 % GEORGIAN SMALL LETTER EN
-\setcclcucx 2D05 2D05 10A5 % GEORGIAN SMALL LETTER VIN
-\setcclcucx 2D06 2D06 10A6 % GEORGIAN SMALL LETTER ZEN
-\setcclcucx 2D07 2D07 10A7 % GEORGIAN SMALL LETTER TAN
-\setcclcucx 2D08 2D08 10A8 % GEORGIAN SMALL LETTER IN
-\setcclcucx 2D09 2D09 10A9 % GEORGIAN SMALL LETTER KAN
-\setcclcucx 2D0A 2D0A 10AA % GEORGIAN SMALL LETTER LAS
-\setcclcucx 2D0B 2D0B 10AB % GEORGIAN SMALL LETTER MAN
-\setcclcucx 2D0C 2D0C 10AC % GEORGIAN SMALL LETTER NAR
-\setcclcucx 2D0D 2D0D 10AD % GEORGIAN SMALL LETTER ON
-\setcclcucx 2D0E 2D0E 10AE % GEORGIAN SMALL LETTER PAR
-\setcclcucx 2D0F 2D0F 10AF % GEORGIAN SMALL LETTER ZHAR
-\setcclcucx 2D10 2D10 10B0 % GEORGIAN SMALL LETTER RAE
-\setcclcucx 2D11 2D11 10B1 % GEORGIAN SMALL LETTER SAN
-\setcclcucx 2D12 2D12 10B2 % GEORGIAN SMALL LETTER TAR
-\setcclcucx 2D13 2D13 10B3 % GEORGIAN SMALL LETTER UN
-\setcclcucx 2D14 2D14 10B4 % GEORGIAN SMALL LETTER PHAR
-\setcclcucx 2D15 2D15 10B5 % GEORGIAN SMALL LETTER KHAR
-\setcclcucx 2D16 2D16 10B6 % GEORGIAN SMALL LETTER GHAN
-\setcclcucx 2D17 2D17 10B7 % GEORGIAN SMALL LETTER QAR
-\setcclcucx 2D18 2D18 10B8 % GEORGIAN SMALL LETTER SHIN
-\setcclcucx 2D19 2D19 10B9 % GEORGIAN SMALL LETTER CHIN
-\setcclcucx 2D1A 2D1A 10BA % GEORGIAN SMALL LETTER CAN
-\setcclcucx 2D1B 2D1B 10BB % GEORGIAN SMALL LETTER JIL
-\setcclcucx 2D1C 2D1C 10BC % GEORGIAN SMALL LETTER CIL
-\setcclcucx 2D1D 2D1D 10BD % GEORGIAN SMALL LETTER CHAR
-\setcclcucx 2D1E 2D1E 10BE % GEORGIAN SMALL LETTER XAN
-\setcclcucx 2D1F 2D1F 10BF % GEORGIAN SMALL LETTER JHAN
-\setcclcucx 2D20 2D20 10C0 % GEORGIAN SMALL LETTER HAE
-\setcclcucx 2D21 2D21 10C1 % GEORGIAN SMALL LETTER HE
-\setcclcucx 2D22 2D22 10C2 % GEORGIAN SMALL LETTER HIE
-\setcclcucx 2D23 2D23 10C3 % GEORGIAN SMALL LETTER WE
-\setcclcucx 2D24 2D24 10C4 % GEORGIAN SMALL LETTER HAR
-\setcclcucx 2D25 2D25 10C5 % GEORGIAN SMALL LETTER HOE
-\setcclcucx FB00 FB00 FB00 % LATIN SMALL LIGATURE FF
-\setcclcucx FB01 FB01 FB01 % LATIN SMALL LIGATURE FI
-\setcclcucx FB02 FB02 FB02 % LATIN SMALL LIGATURE FL
-\setcclcucx FB03 FB03 FB03 % LATIN SMALL LIGATURE FFI
-\setcclcucx FB04 FB04 FB04 % LATIN SMALL LIGATURE FFL
-\setcclcucx FB05 FB05 FB05 % LATIN SMALL LIGATURE LONG S T
-\setcclcucx FB06 FB06 FB06 % LATIN SMALL LIGATURE ST
-\setcclcucx FB13 FB13 FB13 % ARMENIAN SMALL LIGATURE MEN NOW
-\setcclcucx FB14 FB14 FB14 % ARMENIAN SMALL LIGATURE MEN ECH
-\setcclcucx FB15 FB15 FB15 % ARMENIAN SMALL LIGATURE MEN INI
-\setcclcucx FB16 FB16 FB16 % ARMENIAN SMALL LIGATURE VEW NOW
-\setcclcucx FB17 FB17 FB17 % ARMENIAN SMALL LIGATURE MEN XEH
-\setcclcucx FF21 FF41 FF21 % FULLWIDTH LATIN CAPITAL LETTER A
-\setcclcucx FF22 FF42 FF22 % FULLWIDTH LATIN CAPITAL LETTER B
-\setcclcucx FF23 FF43 FF23 % FULLWIDTH LATIN CAPITAL LETTER C
-\setcclcucx FF24 FF44 FF24 % FULLWIDTH LATIN CAPITAL LETTER D
-\setcclcucx FF25 FF45 FF25 % FULLWIDTH LATIN CAPITAL LETTER E
-\setcclcucx FF26 FF46 FF26 % FULLWIDTH LATIN CAPITAL LETTER F
-\setcclcucx FF27 FF47 FF27 % FULLWIDTH LATIN CAPITAL LETTER G
-\setcclcucx FF28 FF48 FF28 % FULLWIDTH LATIN CAPITAL LETTER H
-\setcclcucx FF29 FF49 FF29 % FULLWIDTH LATIN CAPITAL LETTER I
-\setcclcucx FF2A FF4A FF2A % FULLWIDTH LATIN CAPITAL LETTER J
-\setcclcucx FF2B FF4B FF2B % FULLWIDTH LATIN CAPITAL LETTER K
-\setcclcucx FF2C FF4C FF2C % FULLWIDTH LATIN CAPITAL LETTER L
-\setcclcucx FF2D FF4D FF2D % FULLWIDTH LATIN CAPITAL LETTER M
-\setcclcucx FF2E FF4E FF2E % FULLWIDTH LATIN CAPITAL LETTER N
-\setcclcucx FF2F FF4F FF2F % FULLWIDTH LATIN CAPITAL LETTER O
-\setcclcucx FF30 FF50 FF30 % FULLWIDTH LATIN CAPITAL LETTER P
-\setcclcucx FF31 FF51 FF31 % FULLWIDTH LATIN CAPITAL LETTER Q
-\setcclcucx FF32 FF52 FF32 % FULLWIDTH LATIN CAPITAL LETTER R
-\setcclcucx FF33 FF53 FF33 % FULLWIDTH LATIN CAPITAL LETTER S
-\setcclcucx FF34 FF54 FF34 % FULLWIDTH LATIN CAPITAL LETTER T
-\setcclcucx FF35 FF55 FF35 % FULLWIDTH LATIN CAPITAL LETTER U
-\setcclcucx FF36 FF56 FF36 % FULLWIDTH LATIN CAPITAL LETTER V
-\setcclcucx FF37 FF57 FF37 % FULLWIDTH LATIN CAPITAL LETTER W
-\setcclcucx FF38 FF58 FF38 % FULLWIDTH LATIN CAPITAL LETTER X
-\setcclcucx FF39 FF59 FF39 % FULLWIDTH LATIN CAPITAL LETTER Y
-\setcclcucx FF3A FF5A FF3A % FULLWIDTH LATIN CAPITAL LETTER Z
-\setcclcucx FF41 FF41 FF21 % FULLWIDTH LATIN SMALL LETTER A
-\setcclcucx FF42 FF42 FF22 % FULLWIDTH LATIN SMALL LETTER B
-\setcclcucx FF43 FF43 FF23 % FULLWIDTH LATIN SMALL LETTER C
-\setcclcucx FF44 FF44 FF24 % FULLWIDTH LATIN SMALL LETTER D
-\setcclcucx FF45 FF45 FF25 % FULLWIDTH LATIN SMALL LETTER E
-\setcclcucx FF46 FF46 FF26 % FULLWIDTH LATIN SMALL LETTER F
-\setcclcucx FF47 FF47 FF27 % FULLWIDTH LATIN SMALL LETTER G
-\setcclcucx FF48 FF48 FF28 % FULLWIDTH LATIN SMALL LETTER H
-\setcclcucx FF49 FF49 FF29 % FULLWIDTH LATIN SMALL LETTER I
-\setcclcucx FF4A FF4A FF2A % FULLWIDTH LATIN SMALL LETTER J
-\setcclcucx FF4B FF4B FF2B % FULLWIDTH LATIN SMALL LETTER K
-\setcclcucx FF4C FF4C FF2C % FULLWIDTH LATIN SMALL LETTER L
-\setcclcucx FF4D FF4D FF2D % FULLWIDTH LATIN SMALL LETTER M
-\setcclcucx FF4E FF4E FF2E % FULLWIDTH LATIN SMALL LETTER N
-\setcclcucx FF4F FF4F FF2F % FULLWIDTH LATIN SMALL LETTER O
-\setcclcucx FF50 FF50 FF30 % FULLWIDTH LATIN SMALL LETTER P
-\setcclcucx FF51 FF51 FF31 % FULLWIDTH LATIN SMALL LETTER Q
-\setcclcucx FF52 FF52 FF32 % FULLWIDTH LATIN SMALL LETTER R
-\setcclcucx FF53 FF53 FF33 % FULLWIDTH LATIN SMALL LETTER S
-\setcclcucx FF54 FF54 FF34 % FULLWIDTH LATIN SMALL LETTER T
-\setcclcucx FF55 FF55 FF35 % FULLWIDTH LATIN SMALL LETTER U
-\setcclcucx FF56 FF56 FF36 % FULLWIDTH LATIN SMALL LETTER V
-\setcclcucx FF57 FF57 FF37 % FULLWIDTH LATIN SMALL LETTER W
-\setcclcucx FF58 FF58 FF38 % FULLWIDTH LATIN SMALL LETTER X
-\setcclcucx FF59 FF59 FF39 % FULLWIDTH LATIN SMALL LETTER Y
-\setcclcucx FF5A FF5A FF3A % FULLWIDTH LATIN SMALL LETTER Z
-
-% named characters mapped onto utf (\\char is needed for accents)
-
-\def\textbackslash {\char"005C } % REVERSE SOLIDUS: \
-\def\textasciicircum {\char"005E } % CIRCUMFLEX ACCENT: ^
-\def\textunderscore {\char"005F } % LOW LINE: _
-\def\textgrave {\char"0060 } % GRAVE ACCENT: `
-\def\textbraceleft {\char"007B } % LEFT CURLY BRACKET: {
-\def\textbar {\char"007C } % VERTICAL LINE: |
-\def\textbraceright {\char"007D } % RIGHT CURLY BRACKET: }
-\def\textasciitilde {\char"007E } % TILDE: ~
-\def\nonbreakablespace {\char"00A0 } % NO-BREAK SPACE:  
-\def\exclamdown {\char"00A1 } % INVERTED EXCLAMATION MARK: ¡
-\def\textcent {\char"00A2 } % CENT SIGN: ¢
-\def\textsterling {\char"00A3 } % POUND SIGN: £
-\def\textcurrency {\char"00A4 } % CURRENCY SIGN: ¤
-\def\textyen {\char"00A5 } % YEN SIGN: ¥
-\def\textbrokenbar {\char"00A6 } % BROKEN BAR: ¦
-\def\sectionmark {\char"00A7 } % SECTION SIGN: §
-\def\textdiaeresis {\char"00A8 } % DIAERESIS: ¨
-\def\copyright {\char"00A9 } % COPYRIGHT SIGN: ©
-\def\ordfeminine {\char"00AA } % FEMININE ORDINAL INDICATOR: ª
-\def\leftguillemot {\char"00AB } % LEFT-POINTING DOUBLE ANGLE QUOTATION MARK: «
-\def\textlognot {\char"00AC } % NOT SIGN: ¬
-\def\softhyphen {\char"00AD } % SOFT HYPHEN: ­
-\def\registered {\char"00AE } % REGISTERED SIGN: ®
-\def\textmacron {\char"00AF } % MACRON: ¯
-\def\textdegree {\char"00B0 } % DEGREE SIGN: °
-\def\textpm {\char"00B1 } % PLUS-MINUS SIGN: ±
-\def\twosuperior {\char"00B2 } % SUPERSCRIPT TWO: ²
-\def\threesuperior {\char"00B3 } % SUPERSCRIPT THREE: ³
-\def\textacute {\char"00B4 } % ACUTE ACCENT: ´
-\def\textmu {\char"00B5 } % MICRO SIGN: µ
-\def\paragraphmark {\char"00B6 } % PILCROW SIGN: ¶
-\def\periodcentered {\char"00B7 } % MIDDLE DOT: ·
-\def\textcedilla {\char"00B8 } % CEDILLA: ¸
-\def\onesuperior {\char"00B9 } % SUPERSCRIPT ONE: ¹
-\def\ordmasculine {\char"00BA } % MASCULINE ORDINAL INDICATOR: º
-\def\rightguillemot {\char"00BB } % RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK: »
-\def\onequarter {\char"00BC } % VULGAR FRACTION ONE QUARTER: ¼
-\def\onehalf {\char"00BD } % VULGAR FRACTION ONE HALF: ½
-\def\threequarter {\char"00BE } % VULGAR FRACTION THREE QUARTERS: ¾
-\def\questiondown {\char"00BF } % INVERTED QUESTION MARK: ¿
-\def\Agrave {\char"00C0 } % LATIN CAPITAL LETTER A WITH GRAVE: À
-\def\Aacute {\char"00C1 } % LATIN CAPITAL LETTER A WITH ACUTE: Á
-\def\Acircumflex {\char"00C2 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX: Â
-\def\Atilde {\char"00C3 } % LATIN CAPITAL LETTER A WITH TILDE: Ã
-\def\Adiaeresis {\char"00C4 } % LATIN CAPITAL LETTER A WITH DIAERESIS: Ä
-\def\Aring {\char"00C5 } % LATIN CAPITAL LETTER A WITH RING ABOVE: Å
-\def\AEligature {\char"00C6 } % LATIN CAPITAL LETTER AE: Æ
-\def\Ccedilla {\char"00C7 } % LATIN CAPITAL LETTER C WITH CEDILLA: Ç
-\def\Egrave {\char"00C8 } % LATIN CAPITAL LETTER E WITH GRAVE: È
-\def\Eacute {\char"00C9 } % LATIN CAPITAL LETTER E WITH ACUTE: É
-\def\Ecircumflex {\char"00CA } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX: Ê
-\def\Ediaeresis {\char"00CB } % LATIN CAPITAL LETTER E WITH DIAERESIS: Ë
-\def\Igrave {\char"00CC } % LATIN CAPITAL LETTER I WITH GRAVE: Ì
-\def\Iacute {\char"00CD } % LATIN CAPITAL LETTER I WITH ACUTE: Í
-\def\Icircumflex {\char"00CE } % LATIN CAPITAL LETTER I WITH CIRCUMFLEX: Î
-\def\Idiaeresis {\char"00CF } % LATIN CAPITAL LETTER I WITH DIAERESIS: Ï
-\def\Eth {\char"00D0 } % LATIN CAPITAL LETTER ETH: Ð
-\def\Ntilde {\char"00D1 } % LATIN CAPITAL LETTER N WITH TILDE: Ñ
-\def\Ograve {\char"00D2 } % LATIN CAPITAL LETTER O WITH GRAVE: Ò
-\def\Oacute {\char"00D3 } % LATIN CAPITAL LETTER O WITH ACUTE: Ó
-\def\Ocircumflex {\char"00D4 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX: Ô
-\def\Otilde {\char"00D5 } % LATIN CAPITAL LETTER O WITH TILDE: Õ
-\def\Odiaeresis {\char"00D6 } % LATIN CAPITAL LETTER O WITH DIAERESIS: Ö
-\def\textmultiply {\char"00D7 } % MULTIPLICATION SIGN: ×
-\def\Ostroke {\char"00D8 } % LATIN CAPITAL LETTER O WITH STROKE: Ø
-\def\Ugrave {\char"00D9 } % LATIN CAPITAL LETTER U WITH GRAVE: Ù
-\def\Uacute {\char"00DA } % LATIN CAPITAL LETTER U WITH ACUTE: Ú
-\def\Ucircumflex {\char"00DB } % LATIN CAPITAL LETTER U WITH CIRCUMFLEX: Û
-\def\Udiaeresis {\char"00DC } % LATIN CAPITAL LETTER U WITH DIAERESIS: Ü
-\def\Yacute {\char"00DD } % LATIN CAPITAL LETTER Y WITH ACUTE: Ý
-\def\Thorn {\char"00DE } % LATIN CAPITAL LETTER THORN: Þ
-\def\ssharp {\char"00DF } % LATIN SMALL LETTER SHARP S: ß
-\def\agrave {\char"00E0 } % LATIN SMALL LETTER A WITH GRAVE: à
-\def\aacute {\char"00E1 } % LATIN SMALL LETTER A WITH ACUTE: á
-\def\acircumflex {\char"00E2 } % LATIN SMALL LETTER A WITH CIRCUMFLEX: â
-\def\atilde {\char"00E3 } % LATIN SMALL LETTER A WITH TILDE: ã
-\def\adiaeresis {\char"00E4 } % LATIN SMALL LETTER A WITH DIAERESIS: ä
-\def\aring {\char"00E5 } % LATIN SMALL LETTER A WITH RING ABOVE: å
-\def\aeligature {\char"00E6 } % LATIN SMALL LETTER AE: æ
-\def\ccedilla {\char"00E7 } % LATIN SMALL LETTER C WITH CEDILLA: ç
-\def\egrave {\char"00E8 } % LATIN SMALL LETTER E WITH GRAVE: è
-\def\eacute {\char"00E9 } % LATIN SMALL LETTER E WITH ACUTE: é
-\def\ecircumflex {\char"00EA } % LATIN SMALL LETTER E WITH CIRCUMFLEX: ê
-\def\ediaeresis {\char"00EB } % LATIN SMALL LETTER E WITH DIAERESIS: ë
-\def\igrave {\char"00EC } % LATIN SMALL LETTER I WITH GRAVE: ì
-\def\iacute {\char"00ED } % LATIN SMALL LETTER I WITH ACUTE: í
-\def\icircumflex {\char"00EE } % LATIN SMALL LETTER I WITH CIRCUMFLEX: î
-\def\idiaeresis {\char"00EF } % LATIN SMALL LETTER I WITH DIAERESIS: ï
-\def\eth {\char"00F0 } % LATIN SMALL LETTER ETH: ð
-\def\ntilde {\char"00F1 } % LATIN SMALL LETTER N WITH TILDE: ñ
-\def\ograve {\char"00F2 } % LATIN SMALL LETTER O WITH GRAVE: ò
-\def\oacute {\char"00F3 } % LATIN SMALL LETTER O WITH ACUTE: ó
-\def\ocircumflex {\char"00F4 } % LATIN SMALL LETTER O WITH CIRCUMFLEX: ô
-\def\otilde {\char"00F5 } % LATIN SMALL LETTER O WITH TILDE: õ
-\def\odiaeresis {\char"00F6 } % LATIN SMALL LETTER O WITH DIAERESIS: ö
-\def\textdiv {\char"00F7 } % DIVISION SIGN: ÷
-\def\ostroke {\char"00F8 } % LATIN SMALL LETTER O WITH STROKE: ø
-\def\ugrave {\char"00F9 } % LATIN SMALL LETTER U WITH GRAVE: ù
-\def\uacute {\char"00FA } % LATIN SMALL LETTER U WITH ACUTE: ú
-\def\ucircumflex {\char"00FB } % LATIN SMALL LETTER U WITH CIRCUMFLEX: û
-\def\udiaeresis {\char"00FC } % LATIN SMALL LETTER U WITH DIAERESIS: ü
-\def\yacute {\char"00FD } % LATIN SMALL LETTER Y WITH ACUTE: ý
-\def\thorn {\char"00FE } % LATIN SMALL LETTER THORN: þ
-\def\ydiaeresis {\char"00FF } % LATIN SMALL LETTER Y WITH DIAERESIS: ÿ
-\def\Amacron {\char"0100 } % LATIN CAPITAL LETTER A WITH MACRON: Ā
-\def\amacron {\char"0101 } % LATIN SMALL LETTER A WITH MACRON: ā
-\def\Abreve {\char"0102 } % LATIN CAPITAL LETTER A WITH BREVE: Ă
-\def\abreve {\char"0103 } % LATIN SMALL LETTER A WITH BREVE: ă
-\def\Aogonek {\char"0104 } % LATIN CAPITAL LETTER A WITH OGONEK: Ą
-\def\aogonek {\char"0105 } % LATIN SMALL LETTER A WITH OGONEK: ą
-\def\Cacute {\char"0106 } % LATIN CAPITAL LETTER C WITH ACUTE: Ć
-\def\cacute {\char"0107 } % LATIN SMALL LETTER C WITH ACUTE: ć
-\def\Ccircumflex {\char"0108 } % LATIN CAPITAL LETTER C WITH CIRCUMFLEX: Ĉ
-\def\ccircumflex {\char"0109 } % LATIN SMALL LETTER C WITH CIRCUMFLEX: ĉ
-\def\Cdotaccent {\char"010A } % LATIN CAPITAL LETTER C WITH DOT ABOVE: Ċ
-\def\cdotaccent {\char"010B } % LATIN SMALL LETTER C WITH DOT ABOVE: ċ
-\def\Ccaron {\char"010C } % LATIN CAPITAL LETTER C WITH CARON: Č
-\def\ccaron {\char"010D } % LATIN SMALL LETTER C WITH CARON: č
-\def\Dcaron {\char"010E } % LATIN CAPITAL LETTER D WITH CARON: Ď
-\def\dcaron {\char"010F } % LATIN SMALL LETTER D WITH CARON: ď
-\def\Dstroke {\char"0110 } % LATIN CAPITAL LETTER D WITH STROKE: Đ
-\def\dstroke {\char"0111 } % LATIN SMALL LETTER D WITH STROKE: đ
-\def\Emacron {\char"0112 } % LATIN CAPITAL LETTER E WITH MACRON: Ē
-\def\emacron {\char"0113 } % LATIN SMALL LETTER E WITH MACRON: ē
-\def\Ebreve {\char"0114 } % LATIN CAPITAL LETTER E WITH BREVE: Ĕ
-\def\ebreve {\char"0115 } % LATIN SMALL LETTER E WITH BREVE: ĕ
-\def\Edotaccent {\char"0116 } % LATIN CAPITAL LETTER E WITH DOT ABOVE: Ė
-\def\edotaccent {\char"0117 } % LATIN SMALL LETTER E WITH DOT ABOVE: ė
-\def\Eogonek {\char"0118 } % LATIN CAPITAL LETTER E WITH OGONEK: Ę
-\def\eogonek {\char"0119 } % LATIN SMALL LETTER E WITH OGONEK: ę
-\def\Ecaron {\char"011A } % LATIN CAPITAL LETTER E WITH CARON: Ě
-\def\ecaron {\char"011B } % LATIN SMALL LETTER E WITH CARON: ě
-\def\Gcircumflex {\char"011C } % LATIN CAPITAL LETTER G WITH CIRCUMFLEX: Ĝ
-\def\gcircumflex {\char"011D } % LATIN SMALL LETTER G WITH CIRCUMFLEX: ĝ
-\def\Gbreve {\char"011E } % LATIN CAPITAL LETTER G WITH BREVE: Ğ
-\def\gbreve {\char"011F } % LATIN SMALL LETTER G WITH BREVE: ğ
-\def\Gdotaccent {\char"0120 } % LATIN CAPITAL LETTER G WITH DOT ABOVE: Ġ
-\def\gdotaccent {\char"0121 } % LATIN SMALL LETTER G WITH DOT ABOVE: ġ
-\def\Gcommaaccent {\char"0122 } % LATIN CAPITAL LETTER G WITH CEDILLA: Ģ
-\def\gcommaaccent {\char"0123 } % LATIN SMALL LETTER G WITH CEDILLA: ģ
-\def\Hcircumflex {\char"0124 } % LATIN CAPITAL LETTER H WITH CIRCUMFLEX: Ĥ
-\def\hcircumflex {\char"0125 } % LATIN SMALL LETTER H WITH CIRCUMFLEX: ĥ
-\def\Hstroke {\char"0126 } % LATIN CAPITAL LETTER H WITH STROKE: Ħ
-\def\hstroke {\char"0127 } % LATIN SMALL LETTER H WITH STROKE: ħ
-\def\Itilde {\char"0128 } % LATIN CAPITAL LETTER I WITH TILDE: Ĩ
-\def\itilde {\char"0129 } % LATIN SMALL LETTER I WITH TILDE: ĩ
-\def\Imacron {\char"012A } % LATIN CAPITAL LETTER I WITH MACRON: Ī
-\def\imacron {\char"012B } % LATIN SMALL LETTER I WITH MACRON: ī
-\def\Ibreve {\char"012C } % LATIN CAPITAL LETTER I WITH BREVE: Ĭ
-\def\ibreve {\char"012D } % LATIN SMALL LETTER I WITH BREVE: ĭ
-\def\Iogonek {\char"012E } % LATIN CAPITAL LETTER I WITH OGONEK: Į
-\def\iogonek {\char"012F } % LATIN SMALL LETTER I WITH OGONEK: į
-\def\Idotaccent {\char"0130 } % LATIN CAPITAL LETTER I WITH DOT ABOVE: İ
-\def\dotlessi {\char"0131 } % LATIN SMALL LETTER DOTLESS I: ı
-\def\IJligature {\char"0132 } % LATIN CAPITAL LIGATURE IJ: IJ
-\def\ijligature {\char"0133 } % LATIN SMALL LIGATURE IJ: ij
-\def\Jcircumflex {\char"0134 } % LATIN CAPITAL LETTER J WITH CIRCUMFLEX: Ĵ
-\def\jcircumflex {\char"0135 } % LATIN SMALL LETTER J WITH CIRCUMFLEX: ĵ
-\def\Kcommaaccent {\char"0136 } % LATIN CAPITAL LETTER K WITH CEDILLA: Ķ
-\def\kcommaaccent {\char"0137 } % LATIN SMALL LETTER K WITH CEDILLA: ķ
-\def\kkra {\char"0138 } % LATIN SMALL LETTER KRA: ĸ
-\def\Lacute {\char"0139 } % LATIN CAPITAL LETTER L WITH ACUTE: Ĺ
-\def\lacute {\char"013A } % LATIN SMALL LETTER L WITH ACUTE: ĺ
-\def\Lcommaaccent {\char"013B } % LATIN CAPITAL LETTER L WITH CEDILLA: Ļ
-\def\lcommaaccent {\char"013C } % LATIN SMALL LETTER L WITH CEDILLA: ļ
-\def\Lcaron {\char"013D } % LATIN CAPITAL LETTER L WITH CARON: Ľ
-\def\lcaron {\char"013E } % LATIN SMALL LETTER L WITH CARON: ľ
-\def\Ldotmiddle {\char"013F } % LATIN CAPITAL LETTER L WITH MIDDLE DOT: Ŀ
-\def\ldotmiddle {\char"0140 } % LATIN SMALL LETTER L WITH MIDDLE DOT: ŀ
-\def\Lstroke {\char"0141 } % LATIN CAPITAL LETTER L WITH STROKE: Ł
-\def\lstroke {\char"0142 } % LATIN SMALL LETTER L WITH STROKE: ł
-\def\Nacute {\char"0143 } % LATIN CAPITAL LETTER N WITH ACUTE: Ń
-\def\nacute {\char"0144 } % LATIN SMALL LETTER N WITH ACUTE: ń
-\def\Ncommaaccent {\char"0145 } % LATIN CAPITAL LETTER N WITH CEDILLA: Ņ
-\def\ncommaaccent {\char"0146 } % LATIN SMALL LETTER N WITH CEDILLA: ņ
-\def\Ncaron {\char"0147 } % LATIN CAPITAL LETTER N WITH CARON: Ň
-\def\ncaron {\char"0148 } % LATIN SMALL LETTER N WITH CARON: ň
-\def\napostrophe {\char"0149 } % LATIN SMALL LETTER N PRECEDED BY APOSTROPHE: ʼn
-\def\Neng {\char"014A } % LATIN CAPITAL LETTER ENG: Ŋ
-\def\neng {\char"014B } % LATIN SMALL LETTER ENG: ŋ
-\def\Omacron {\char"014C } % LATIN CAPITAL LETTER O WITH MACRON: Ō
-\def\omacron {\char"014D } % LATIN SMALL LETTER O WITH MACRON: ō
-\def\Obreve {\char"014E } % LATIN CAPITAL LETTER O WITH BREVE: Ŏ
-\def\obreve {\char"014F } % LATIN SMALL LETTER O WITH BREVE: ŏ
-\def\Ohungarumlaut {\char"0150 } % LATIN CAPITAL LETTER O WITH DOUBLE ACUTE: Ő
-\def\ohungarumlaut {\char"0151 } % LATIN SMALL LETTER O WITH DOUBLE ACUTE: ő
-\def\OEligature {\char"0152 } % LATIN CAPITAL LIGATURE OE: Œ
-\def\oeligature {\char"0153 } % LATIN SMALL LIGATURE OE: œ
-\def\Racute {\char"0154 } % LATIN CAPITAL LETTER R WITH ACUTE: Ŕ
-\def\racute {\char"0155 } % LATIN SMALL LETTER R WITH ACUTE: ŕ
-\def\Rcommaaccent {\char"0156 } % LATIN CAPITAL LETTER R WITH CEDILLA: Ŗ
-\def\rcommaaccent {\char"0157 } % LATIN SMALL LETTER R WITH CEDILLA: ŗ
-\def\Rcaron {\char"0158 } % LATIN CAPITAL LETTER R WITH CARON: Ř
-\def\rcaron {\char"0159 } % LATIN SMALL LETTER R WITH CARON: ř
-\def\Sacute {\char"015A } % LATIN CAPITAL LETTER S WITH ACUTE: Ś
-\def\sacute {\char"015B } % LATIN SMALL LETTER S WITH ACUTE: ś
-\def\Scircumflex {\char"015C } % LATIN CAPITAL LETTER S WITH CIRCUMFLEX: Ŝ
-\def\scircumflex {\char"015D } % LATIN SMALL LETTER S WITH CIRCUMFLEX: ŝ
-\def\Scedilla {\char"015E } % LATIN CAPITAL LETTER S WITH CEDILLA: Ş
-\def\scedilla {\char"015F } % LATIN SMALL LETTER S WITH CEDILLA: ş
-\def\Scaron {\char"0160 } % LATIN CAPITAL LETTER S WITH CARON: Š
-\def\scaron {\char"0161 } % LATIN SMALL LETTER S WITH CARON: š
-\def\Tcedilla {\char"0162 } % LATIN CAPITAL LETTER T WITH CEDILLA: Ţ
-\def\tcedilla {\char"0163 } % LATIN SMALL LETTER T WITH CEDILLA: ţ
-\def\Tcaron {\char"0164 } % LATIN CAPITAL LETTER T WITH CARON: Ť
-\def\tcaron {\char"0165 } % LATIN SMALL LETTER T WITH CARON: ť
-\def\Tstroke {\char"0166 } % LATIN CAPITAL LETTER T WITH STROKE: Ŧ
-\def\tstroke {\char"0167 } % LATIN SMALL LETTER T WITH STROKE: ŧ
-\def\Utilde {\char"0168 } % LATIN CAPITAL LETTER U WITH TILDE: Ũ
-\def\utilde {\char"0169 } % LATIN SMALL LETTER U WITH TILDE: ũ
-\def\Umacron {\char"016A } % LATIN CAPITAL LETTER U WITH MACRON: Ū
-\def\umacron {\char"016B } % LATIN SMALL LETTER U WITH MACRON: ū
-\def\Ubreve {\char"016C } % LATIN CAPITAL LETTER U WITH BREVE: Ŭ
-\def\ubreve {\char"016D } % LATIN SMALL LETTER U WITH BREVE: ŭ
-\def\Uring {\char"016E } % LATIN CAPITAL LETTER U WITH RING ABOVE: Ů
-\def\uring {\char"016F } % LATIN SMALL LETTER U WITH RING ABOVE: ů
-\def\Uhungarumlaut {\char"0170 } % LATIN CAPITAL LETTER U WITH DOUBLE ACUTE: Ű
-\def\uhungarumlaut {\char"0171 } % LATIN SMALL LETTER U WITH DOUBLE ACUTE: ű
-\def\Uogonek {\char"0172 } % LATIN CAPITAL LETTER U WITH OGONEK: Ų
-\def\uogonek {\char"0173 } % LATIN SMALL LETTER U WITH OGONEK: ų
-\def\Wcircumflex {\char"0174 } % LATIN CAPITAL LETTER W WITH CIRCUMFLEX: Ŵ
-\def\wcircumflex {\char"0175 } % LATIN SMALL LETTER W WITH CIRCUMFLEX: ŵ
-\def\Ycircumflex {\char"0176 } % LATIN CAPITAL LETTER Y WITH CIRCUMFLEX: Ŷ
-\def\ycircumflex {\char"0177 } % LATIN SMALL LETTER Y WITH CIRCUMFLEX: ŷ
-\def\Ydiaeresis {\char"0178 } % LATIN CAPITAL LETTER Y WITH DIAERESIS: Ÿ
-\def\Zacute {\char"0179 } % LATIN CAPITAL LETTER Z WITH ACUTE: Ź
-\def\zacute {\char"017A } % LATIN SMALL LETTER Z WITH ACUTE: ź
-\def\Zdotaccent {\char"017B } % LATIN CAPITAL LETTER Z WITH DOT ABOVE: Ż
-\def\zdotaccent {\char"017C } % LATIN SMALL LETTER Z WITH DOT ABOVE: ż
-\def\Zcaron {\char"017D } % LATIN CAPITAL LETTER Z WITH CARON: Ž
-\def\zcaron {\char"017E } % LATIN SMALL LETTER Z WITH CARON: ž
-\def\slong {\char"017F } % LATIN SMALL LETTER LONG S: ſ
-\def\bstroke {\char"0180 } % LATIN SMALL LETTER B WITH STROKE: ƀ
-\def\Bhook {\char"0181 } % LATIN CAPITAL LETTER B WITH HOOK: Ɓ
-\def\Chook {\char"0187 } % LATIN CAPITAL LETTER C WITH HOOK: Ƈ
-\def\chook {\char"0188 } % LATIN SMALL LETTER C WITH HOOK: ƈ
-\def\Dafrican {\char"0189 } % LATIN CAPITAL LETTER AFRICAN D: Ɖ
-\def\Dhook {\char"018A } % LATIN CAPITAL LETTER D WITH HOOK: Ɗ
-\def\Schwa {\char"018F } % LATIN CAPITAL LETTER SCHWA: Ə
-\def\Fhook {\char"0191 } % LATIN CAPITAL LETTER F WITH HOOK: Ƒ
-\def\fhook {\char"0192 } % LATIN SMALL LETTER F WITH HOOK: ƒ
-\def\Ghook {\char"0193 } % LATIN CAPITAL LETTER G WITH HOOK: Ɠ
-\def\Istroke {\char"0197 } % LATIN CAPITAL LETTER I WITH STROKE: Ɨ
-\def\Khook {\char"0198 } % LATIN CAPITAL LETTER K WITH HOOK: Ƙ
-\def\khook {\char"0199 } % LATIN SMALL LETTER K WITH HOOK: ƙ
-\def\lbar {\char"019A } % LATIN SMALL LETTER L WITH BAR: ƚ
-\def\Ohorn {\char"01A0 } % LATIN CAPITAL LETTER O WITH HORN: Ơ
-\def\ohorn {\char"01A1 } % LATIN SMALL LETTER O WITH HORN: ơ
-\def\Phook {\char"01A4 } % LATIN CAPITAL LETTER P WITH HOOK: Ƥ
-\def\phook {\char"01A5 } % LATIN SMALL LETTER P WITH HOOK: ƥ
-\def\Thook {\char"01AC } % LATIN CAPITAL LETTER T WITH HOOK: Ƭ
-\def\thook {\char"01AD } % LATIN SMALL LETTER T WITH HOOK: ƭ
-\def\Uhorn {\char"01AF } % LATIN CAPITAL LETTER U WITH HORN: Ư
-\def\uhorn {\char"01B0 } % LATIN SMALL LETTER U WITH HORN: ư
-\def\Uhook {\char"01B2 } % LATIN CAPITAL LETTER V WITH HOOK: Ʋ
-\def\Yhook {\char"01B3 } % LATIN CAPITAL LETTER Y WITH HOOK: Ƴ
-\def\yhook {\char"01B4 } % LATIN SMALL LETTER Y WITH HOOK: ƴ
-\def\Zstroke {\char"01B5 } % LATIN CAPITAL LETTER Z WITH STROKE: Ƶ
-\def\zstroke {\char"01B6 } % LATIN SMALL LETTER Z WITH STROKE: ƶ
-\def\DZcaronligature {\char"01C4 } % LATIN CAPITAL LETTER DZ WITH CARON: DŽ
-\def\Dzcaronligature {\char"01C5 } % LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON: Dž
-\def\dzcaronligature {\char"01C6 } % LATIN SMALL LETTER DZ WITH CARON: dž
-\def\LJligature {\char"01C7 } % LATIN CAPITAL LETTER LJ: LJ
-\def\Ljligature {\char"01C8 } % LATIN CAPITAL LETTER L WITH SMALL LETTER J: Lj
-\def\ljligature {\char"01C9 } % LATIN SMALL LETTER LJ: lj
-\def\NJligature {\char"01CA } % LATIN CAPITAL LETTER NJ: NJ
-\def\Njligature {\char"01CB } % LATIN CAPITAL LETTER N WITH SMALL LETTER J: Nj
-\def\njligature {\char"01CC } % LATIN SMALL LETTER NJ: nj
-\def\Acaron {\char"01CD } % LATIN CAPITAL LETTER A WITH CARON: Ǎ
-\def\acaron {\char"01CE } % LATIN SMALL LETTER A WITH CARON: ǎ
-\def\Icaron {\char"01CF } % LATIN CAPITAL LETTER I WITH CARON: Ǐ
-\def\icaron {\char"01D0 } % LATIN SMALL LETTER I WITH CARON: ǐ
-\def\Ocaron {\char"01D1 } % LATIN CAPITAL LETTER O WITH CARON: Ǒ
-\def\ocaron {\char"01D2 } % LATIN SMALL LETTER O WITH CARON: ǒ
-\def\Ucaron {\char"01D3 } % LATIN CAPITAL LETTER U WITH CARON: Ǔ
-\def\ucaron {\char"01D4 } % LATIN SMALL LETTER U WITH CARON: ǔ
-\def\Udiaeresismacron {\char"01D5 } % LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON: Ǖ
-\def\udiaeresismacron {\char"01D6 } % LATIN SMALL LETTER U WITH DIAERESIS AND MACRON: ǖ
-\def\Udiaeresisacute {\char"01D7 } % LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE: Ǘ
-\def\udiaeresisacute {\char"01D8 } % LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE: ǘ
-\def\Udiaeresiscaron {\char"01D9 } % LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON: Ǚ
-\def\udiaeresiscaron {\char"01DA } % LATIN SMALL LETTER U WITH DIAERESIS AND CARON: ǚ
-\def\Udiaeresisgrave {\char"01DB } % LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE: Ǜ
-\def\udiaeresisgrave {\char"01DC } % LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE: ǜ
-\def\Adiaeresismacron {\char"01DE } % LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON: Ǟ
-\def\adiaeresismacron {\char"01DF } % LATIN SMALL LETTER A WITH DIAERESIS AND MACRON: ǟ
-\def\Adotaccentmacron {\char"01E0 } % LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON: Ǡ
-\def\adotaccentmacron {\char"01E1 } % LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON: ǡ
-\def\AEmacron {\char"01E2 } % LATIN CAPITAL LETTER AE WITH MACRON: Ǣ
-\def\aemacron {\char"01E3 } % LATIN SMALL LETTER AE WITH MACRON: ǣ
-\def\Gstroke {\char"01E4 } % LATIN CAPITAL LETTER G WITH STROKE: Ǥ
-\def\gstroke {\char"01E5 } % LATIN SMALL LETTER G WITH STROKE: ǥ
-\def\Gcaron {\char"01E6 } % LATIN CAPITAL LETTER G WITH CARON: Ǧ
-\def\gcaron {\char"01E7 } % LATIN SMALL LETTER G WITH CARON: ǧ
-\def\Kcaron {\char"01E8 } % LATIN CAPITAL LETTER K WITH CARON: Ǩ
-\def\kcaron {\char"01E9 } % LATIN SMALL LETTER K WITH CARON: ǩ
-\def\Oogonek {\char"01EA } % LATIN CAPITAL LETTER O WITH OGONEK: Ǫ
-\def\oogonek {\char"01EB } % LATIN SMALL LETTER O WITH OGONEK: ǫ
-\def\Oogonekmacron {\char"01EC } % LATIN CAPITAL LETTER O WITH OGONEK AND MACRON: Ǭ
-\def\oogonekmacron {\char"01ED } % LATIN SMALL LETTER O WITH OGONEK AND MACRON: ǭ
-\def\jcaron {\char"01F0 } % LATIN SMALL LETTER J WITH CARON: ǰ
-\def\DZligature {\char"01F1 } % LATIN CAPITAL LETTER DZ: DZ
-\def\Dzligature {\char"01F2 } % LATIN CAPITAL LETTER D WITH SMALL LETTER Z: Dz
-\def\dzligature {\char"01F3 } % LATIN SMALL LETTER DZ: dz
-\def\Gacute {\char"01F4 } % LATIN CAPITAL LETTER G WITH ACUTE: Ǵ
-\def\gacute {\char"01F5 } % LATIN SMALL LETTER G WITH ACUTE: ǵ
-\def\Ngrave {\char"01F8 } % LATIN CAPITAL LETTER N WITH GRAVE: Ǹ
-\def\ngrave {\char"01F9 } % LATIN SMALL LETTER N WITH GRAVE: ǹ
-\def\Aringacute {\char"01FA } % LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE: Ǻ
-\def\aringacute {\char"01FB } % LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE: ǻ
-\def\AEacute {\char"01FC } % LATIN CAPITAL LETTER AE WITH ACUTE: Ǽ
-\def\aeacute {\char"01FD } % LATIN SMALL LETTER AE WITH ACUTE: ǽ
-\def\Ostrokeacute {\char"01FE } % LATIN CAPITAL LETTER O WITH STROKE AND ACUTE: Ǿ
-\def\ostrokeacute {\char"01FF } % LATIN SMALL LETTER O WITH STROKE AND ACUTE: ǿ
-\def\Adoublegrave {\char"0200 } % LATIN CAPITAL LETTER A WITH DOUBLE GRAVE: Ȁ
-\def\adoublegrave {\char"0201 } % LATIN SMALL LETTER A WITH DOUBLE GRAVE: ȁ
-\def\Ainvertedbreve {\char"0202 } % LATIN CAPITAL LETTER A WITH INVERTED BREVE: Ȃ
-\def\ainvertedbreve {\char"0203 } % LATIN SMALL LETTER A WITH INVERTED BREVE: ȃ
-\def\Edoublegrave {\char"0204 } % LATIN CAPITAL LETTER E WITH DOUBLE GRAVE: Ȅ
-\def\edoublegrave {\char"0205 } % LATIN SMALL LETTER E WITH DOUBLE GRAVE: ȅ
-\def\Einvertedbreve {\char"0206 } % LATIN CAPITAL LETTER E WITH INVERTED BREVE: Ȇ
-\def\einvertedbreve {\char"0207 } % LATIN SMALL LETTER E WITH INVERTED BREVE: ȇ
-\def\Idoublegrave {\char"0208 } % LATIN CAPITAL LETTER I WITH DOUBLE GRAVE: Ȉ
-\def\idoublegrave {\char"0209 } % LATIN SMALL LETTER I WITH DOUBLE GRAVE: ȉ
-\def\Iinvertedbreve {\char"020A } % LATIN CAPITAL LETTER I WITH INVERTED BREVE: Ȋ
-\def\iinvertedbreve {\char"020B } % LATIN SMALL LETTER I WITH INVERTED BREVE: ȋ
-\def\Odoublegrave {\char"020C } % LATIN CAPITAL LETTER O WITH DOUBLE GRAVE: Ȍ
-\def\odoublegrave {\char"020D } % LATIN SMALL LETTER O WITH DOUBLE GRAVE: ȍ
-\def\Oinvertedbreve {\char"020E } % LATIN CAPITAL LETTER O WITH INVERTED BREVE: Ȏ
-\def\oinvertedbreve {\char"020F } % LATIN SMALL LETTER O WITH INVERTED BREVE: ȏ
-\def\Rdoublegrave {\char"0210 } % LATIN CAPITAL LETTER R WITH DOUBLE GRAVE: Ȑ
-\def\rdoublegrave {\char"0211 } % LATIN SMALL LETTER R WITH DOUBLE GRAVE: ȑ
-\def\Rinvertedbreve {\char"0212 } % LATIN CAPITAL LETTER R WITH INVERTED BREVE: Ȓ
-\def\rinvertedbreve {\char"0213 } % LATIN SMALL LETTER R WITH INVERTED BREVE: ȓ
-\def\Udoublegrave {\char"0214 } % LATIN CAPITAL LETTER U WITH DOUBLE GRAVE: Ȕ
-\def\udoublegrave {\char"0215 } % LATIN SMALL LETTER U WITH DOUBLE GRAVE: ȕ
-\def\Uinvertedbreve {\char"0216 } % LATIN CAPITAL LETTER U WITH INVERTED BREVE: Ȗ
-\def\uinvertedbreve {\char"0217 } % LATIN SMALL LETTER U WITH INVERTED BREVE: ȗ
-\def\Scommaaccent {\char"0218 } % LATIN CAPITAL LETTER S WITH COMMA BELOW: Ș
-\def\scommaaccent {\char"0219 } % LATIN SMALL LETTER S WITH COMMA BELOW: ș
-\def\Tcommaaccent {\char"021A } % LATIN CAPITAL LETTER T WITH COMMA BELOW: Ț
-\def\tcommaaccent {\char"021B } % LATIN SMALL LETTER T WITH COMMA BELOW: ț
-\def\Hcaron {\char"021E } % LATIN CAPITAL LETTER H WITH CARON: Ȟ
-\def\hcaron {\char"021F } % LATIN SMALL LETTER H WITH CARON: ȟ
-\def\dcurl {\char"0221 } % LATIN SMALL LETTER D WITH CURL: ȡ
-\def\Zhook {\char"0224 } % LATIN CAPITAL LETTER Z WITH HOOK: Ȥ
-\def\zhook {\char"0225 } % LATIN SMALL LETTER Z WITH HOOK: ȥ
-\def\Adotaccent {\char"0226 } % LATIN CAPITAL LETTER A WITH DOT ABOVE: Ȧ
-\def\adotaccent {\char"0227 } % LATIN SMALL LETTER A WITH DOT ABOVE: ȧ
-\def\Ecedilla {\char"0228 } % LATIN CAPITAL LETTER E WITH CEDILLA: Ȩ
-\def\ecedilla {\char"0229 } % LATIN SMALL LETTER E WITH CEDILLA: ȩ
-\def\Odiaeresismacron {\char"022A } % LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON: Ȫ
-\def\odiaeresismacron {\char"022B } % LATIN SMALL LETTER O WITH DIAERESIS AND MACRON: ȫ
-\def\Otildemacron {\char"022C } % LATIN CAPITAL LETTER O WITH TILDE AND MACRON: Ȭ
-\def\otildemacron {\char"022D } % LATIN SMALL LETTER O WITH TILDE AND MACRON: ȭ
-\def\Odotaccent {\char"022E } % LATIN CAPITAL LETTER O WITH DOT ABOVE: Ȯ
-\def\odotaccent {\char"022F } % LATIN SMALL LETTER O WITH DOT ABOVE: ȯ
-\def\Odotaccentmacron {\char"0230 } % LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON: Ȱ
-\def\odotaccentmacron {\char"0231 } % LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON: ȱ
-\def\Ymacron {\char"0232 } % LATIN CAPITAL LETTER Y WITH MACRON: Ȳ
-\def\ymacron {\char"0233 } % LATIN SMALL LETTER Y WITH MACRON: ȳ
-\def\lcurl {\char"0234 } % LATIN SMALL LETTER L WITH CURL: ȴ
-\def\ncurl {\char"0235 } % LATIN SMALL LETTER N WITH CURL: ȵ
-\def\tcurl {\char"0236 } % LATIN SMALL LETTER T WITH CURL: ȶ
-\def\dotlessj {\char"0237 } % LATIN SMALL LETTER DOTLESS J: ȷ
-\def\Astroke {\char"023A } % LATIN CAPITAL LETTER A WITH STROKE: Ⱥ
-\def\Cstroke {\char"023B } % LATIN CAPITAL LETTER C WITH STROKE: Ȼ
-\def\cstroke {\char"023C } % LATIN SMALL LETTER C WITH STROKE: ȼ
-\def\Lbar {\char"023D } % LATIN CAPITAL LETTER L WITH BAR: Ƚ
-\def\bhook {\char"0253 } % LATIN SMALL LETTER B WITH HOOK: ɓ
-\def\ccurl {\char"0255 } % LATIN SMALL LETTER C WITH CURL: ɕ
-\def\dtail {\char"0256 } % LATIN SMALL LETTER D WITH TAIL: ɖ
-\def\dhook {\char"0257 } % LATIN SMALL LETTER D WITH HOOK: ɗ
-\def\schwa {\char"0259 } % LATIN SMALL LETTER SCHWA: ə
-\def\schwahook {\char"025A } % LATIN SMALL LETTER SCHWA WITH HOOK: ɚ
-\def\dotlessjstroke {\char"025F } % LATIN SMALL LETTER DOTLESS J WITH STROKE: ɟ
-\def\textcircumflex {\char"02C6 } % MODIFIER LETTER CIRCUMFLEX ACCENT: ˆ
-\def\textcaron {\char"02C7 } % CARON: ˇ
-\def\textbreve {\char"02D8 } % BREVE: ˘
-\def\textdotaccent {\char"02D9 } % DOT ABOVE: ˙
-\def\textring {\char"02DA } % RING ABOVE: ˚
-\def\textogonek {\char"02DB } % OGONEK: ˛
-\def\texttilde {\char"02DC } % SMALL TILDE: ˜
-\def\texthungarumlaut {\char"02DD } % DOUBLE ACUTE ACCENT: ˝
-\def\greektonos {\char"0384 } % GREEK TONOS: ΄
-\def\greekdialytikatonos {\char"0385 } % GREEK DIALYTIKA TONOS: ΅
-\def\greekAlphatonos {\char"0386 } % GREEK CAPITAL LETTER ALPHA WITH TONOS: Ά
-\def\greekEpsilontonos {\char"0388 } % GREEK CAPITAL LETTER EPSILON WITH TONOS: Έ
-\def\greekEtatonos {\char"0389 } % GREEK CAPITAL LETTER ETA WITH TONOS: Ή
-\def\greekIotatonos {\char"038A } % GREEK CAPITAL LETTER IOTA WITH TONOS: Ί
-\def\greekOmicrontonos {\char"038C } % GREEK CAPITAL LETTER OMICRON WITH TONOS: Ό
-\def\greekUpsilontonos {\char"038E } % GREEK CAPITAL LETTER UPSILON WITH TONOS: Ύ
-\def\greekOmegatonos {\char"038F } % GREEK CAPITAL LETTER OMEGA WITH TONOS: Ώ
-\def\greekiotadialytikatonos {\char"0390 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS: ΐ
-\def\greekAlpha {\char"0391 } % GREEK CAPITAL LETTER ALPHA: Α
-\def\greekBeta {\char"0392 } % GREEK CAPITAL LETTER BETA: Β
-\def\greekGamma {\char"0393 } % GREEK CAPITAL LETTER GAMMA: Γ
-\def\greekDelta {\char"0394 } % GREEK CAPITAL LETTER DELTA: Δ
-\def\greekEpsilon {\char"0395 } % GREEK CAPITAL LETTER EPSILON: Ε
-\def\greekZeta {\char"0396 } % GREEK CAPITAL LETTER ZETA: Ζ
-\def\greekEta {\char"0397 } % GREEK CAPITAL LETTER ETA: Η
-\def\greekTheta {\char"0398 } % GREEK CAPITAL LETTER THETA: Θ
-\def\greekIota {\char"0399 } % GREEK CAPITAL LETTER IOTA: Ι
-\def\greekKappa {\char"039A } % GREEK CAPITAL LETTER KAPPA: Κ
-\def\greekLambda {\char"039B } % GREEK CAPITAL LETTER LAMDA: Λ
-\def\greekMu {\char"039C } % GREEK CAPITAL LETTER MU: Μ
-\def\greekNu {\char"039D } % GREEK CAPITAL LETTER NU: Ν
-\def\greekXi {\char"039E } % GREEK CAPITAL LETTER XI: Ξ
-\def\greekOmicron {\char"039F } % GREEK CAPITAL LETTER OMICRON: Ο
-\def\greekPi {\char"03A0 } % GREEK CAPITAL LETTER PI: Π
-\def\greekRho {\char"03A1 } % GREEK CAPITAL LETTER RHO: Ρ
-\def\greekSigma {\char"03A3 } % GREEK CAPITAL LETTER SIGMA: Σ
-\def\greekTau {\char"03A4 } % GREEK CAPITAL LETTER TAU: Τ
-\def\greekUpsilon {\char"03A5 } % GREEK CAPITAL LETTER UPSILON: Υ
-\def\greekPhi {\char"03A6 } % GREEK CAPITAL LETTER PHI: Φ
-\def\greekChi {\char"03A7 } % GREEK CAPITAL LETTER CHI: Χ
-\def\greekPsi {\char"03A8 } % GREEK CAPITAL LETTER PSI: Ψ
-\def\greekOmega {\char"03A9 } % GREEK CAPITAL LETTER OMEGA: Ω
-\def\greekIotadialytika {\char"03AA } % GREEK CAPITAL LETTER IOTA WITH DIALYTIKA: Ϊ
-\def\greekUpsilondialytika {\char"03AB } % GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA: Ϋ
-\def\greekalphatonos {\char"03AC } % GREEK SMALL LETTER ALPHA WITH TONOS: ά
-\def\greekepsilontonos {\char"03AD } % GREEK SMALL LETTER EPSILON WITH TONOS: έ
-\def\greeketatonos {\char"03AE } % GREEK SMALL LETTER ETA WITH TONOS: ή
-\def\greekiotatonos {\char"03AF } % GREEK SMALL LETTER IOTA WITH TONOS: ί
-\def\greekupsilondialytikatonos {\char"03B0 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS: ΰ
-\def\greekalpha {\char"03B1 } % GREEK SMALL LETTER ALPHA: α
-\def\greekbeta {\char"03B2 } % GREEK SMALL LETTER BETA: β
-\def\greekgamma {\char"03B3 } % GREEK SMALL LETTER GAMMA: γ
-\def\greekdelta {\char"03B4 } % GREEK SMALL LETTER DELTA: δ
-\def\greekepsilon {\char"03B5 } % GREEK SMALL LETTER EPSILON: ε
-\def\greekzeta {\char"03B6 } % GREEK SMALL LETTER ZETA: ζ
-\def\greeketa {\char"03B7 } % GREEK SMALL LETTER ETA: η
-\def\greektheta {\char"03B8 } % GREEK SMALL LETTER THETA: θ
-\def\greekiota {\char"03B9 } % GREEK SMALL LETTER IOTA: ι
-\def\greekkappa {\char"03BA } % GREEK SMALL LETTER KAPPA: κ
-\def\greeklambda {\char"03BB } % GREEK SMALL LETTER LAMDA: λ
-\def\greekmu {\char"03BC } % GREEK SMALL LETTER MU: μ
-\def\greeknu {\char"03BD } % GREEK SMALL LETTER NU: ν
-\def\greekxi {\char"03BE } % GREEK SMALL LETTER XI: ξ
-\def\greekomicron {\char"03BF } % GREEK SMALL LETTER OMICRON: ο
-\def\greekpi {\char"03C0 } % GREEK SMALL LETTER PI: π
-\def\greekrho {\char"03C1 } % GREEK SMALL LETTER RHO: ρ
-\def\greekfinalsigma {\char"03C2 } % GREEK SMALL LETTER FINAL SIGMA: ς
-\def\greeksigma {\char"03C3 } % GREEK SMALL LETTER SIGMA: σ
-\def\greektau {\char"03C4 } % GREEK SMALL LETTER TAU: τ
-\def\greekupsilon {\char"03C5 } % GREEK SMALL LETTER UPSILON: υ
-\def\greekphi {\char"03C6 } % GREEK SMALL LETTER PHI: φ
-\def\greekchi {\char"03C7 } % GREEK SMALL LETTER CHI: χ
-\def\greekpsi {\char"03C8 } % GREEK SMALL LETTER PSI: ψ
-\def\greekomega {\char"03C9 } % GREEK SMALL LETTER OMEGA: ω
-\def\greekiotadialytika {\char"03CA } % GREEK SMALL LETTER IOTA WITH DIALYTIKA: ϊ
-\def\greekupsilondiaeresis {\char"03CB } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA: ϋ
-\def\greekomicrontonos {\char"03CC } % GREEK SMALL LETTER OMICRON WITH TONOS: ό
-\def\greekupsilontonos {\char"03CD } % GREEK SMALL LETTER UPSILON WITH TONOS: ύ
-\def\greekomegatonos {\char"03CE } % GREEK SMALL LETTER OMEGA WITH TONOS: ώ
-\def\greekthetaalt {\char"03D1 } % GREEK THETA SYMBOL: ϑ
-\def\greekphialt {\char"03D5 } % GREEK PHI SYMBOL: ϕ
-\def\greekpialt {\char"03D6 } % GREEK PI SYMBOL: ϖ
-\def\greekkoppa {\char"03D9 } % GREEK SMALL LETTER ARCHAIC KOPPA: ϙ
-\def\greekstigma {\char"03DB } % GREEK SMALL LETTER STIGMA: ϛ
-\def\greekdigamma {\char"03DD } % GREEK SMALL LETTER DIGAMMA: ϝ
-\def\greeknumkoppa {\char"03DF } % GREEK SMALL LETTER KOPPA: ϟ
-\def\greeksampi {\char"03E1 } % GREEK SMALL LETTER SAMPI: ϡ
-\def\greekrhoalt {\char"03F1 } % GREEK RHO SYMBOL: ϱ
-\def\greeksigmalunate {\char"03F2 } % GREEK LUNATE SIGMA SYMBOL: ϲ
-\def\greekepsilonalt {\char"03F5 } % GREEK LUNATE EPSILON SYMBOL: ϵ
-\def\greekSigmalunate {\char"03F9 } % GREEK CAPITAL LUNATE SIGMA SYMBOL: Ϲ
-\def\cyrillicEgrave {\char"0400 } % CYRILLIC CAPITAL LETTER IE WITH GRAVE: Ѐ
-\def\cyrillicYO {\char"0401 } % CYRILLIC CAPITAL LETTER IO: Ё
-\def\cyrillicDJE {\char"0402 } % CYRILLIC CAPITAL LETTER DJE: Ђ
-\def\cyrillicGJE {\char"0403 } % CYRILLIC CAPITAL LETTER GJE: Ѓ
-\def\cyrillicIE {\char"0404 } % CYRILLIC CAPITAL LETTER UKRAINIAN IE: Є
-\def\cyrillicDZE {\char"0405 } % CYRILLIC CAPITAL LETTER DZE: Ѕ
-\def\cyrillicII {\char"0406 } % CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I: І
-\def\cyrillicYI {\char"0407 } % CYRILLIC CAPITAL LETTER YI: Ї
-\def\cyrillicJE {\char"0408 } % CYRILLIC CAPITAL LETTER JE: Ј
-\def\cyrillicLJE {\char"0409 } % CYRILLIC CAPITAL LETTER LJE: Љ
-\def\cyrillicNJE {\char"040A } % CYRILLIC CAPITAL LETTER NJE: Њ
-\def\cyrillicTSHE {\char"040B } % CYRILLIC CAPITAL LETTER TSHE: Ћ
-\def\cyrillicKJE {\char"040C } % CYRILLIC CAPITAL LETTER KJE: Ќ
-\def\cyrillicIgrave {\char"040D } % CYRILLIC CAPITAL LETTER I WITH GRAVE: Ѝ
-\def\cyrillicUSHRT {\char"040E } % CYRILLIC CAPITAL LETTER SHORT U: Ў
-\def\cyrillicDZHE {\char"040F } % CYRILLIC CAPITAL LETTER DZHE: Џ
-\def\cyrillicA {\char"0410 } % CYRILLIC CAPITAL LETTER A: А
-\def\cyrillicB {\char"0411 } % CYRILLIC CAPITAL LETTER BE: Б
-\def\cyrillicV {\char"0412 } % CYRILLIC CAPITAL LETTER VE: В
-\def\cyrillicG {\char"0413 } % CYRILLIC CAPITAL LETTER GHE: Г
-\def\cyrillicD {\char"0414 } % CYRILLIC CAPITAL LETTER DE: Д
-\def\cyrillicE {\char"0415 } % CYRILLIC CAPITAL LETTER IE: Е
-\def\cyrillicZH {\char"0416 } % CYRILLIC CAPITAL LETTER ZHE: Ж
-\def\cyrillicZ {\char"0417 } % CYRILLIC CAPITAL LETTER ZE: З
-\def\cyrillicI {\char"0418 } % CYRILLIC CAPITAL LETTER I: И
-\def\cyrillicISHRT {\char"0419 } % CYRILLIC CAPITAL LETTER SHORT I: Й
-\def\cyrillicK {\char"041A } % CYRILLIC CAPITAL LETTER KA: К
-\def\cyrillicL {\char"041B } % CYRILLIC CAPITAL LETTER EL: Л
-\def\cyrillicM {\char"041C } % CYRILLIC CAPITAL LETTER EM: М
-\def\cyrillicN {\char"041D } % CYRILLIC CAPITAL LETTER EN: Н
-\def\cyrillicO {\char"041E } % CYRILLIC CAPITAL LETTER O: О
-\def\cyrillicP {\char"041F } % CYRILLIC CAPITAL LETTER PE: П
-\def\cyrillicR {\char"0420 } % CYRILLIC CAPITAL LETTER ER: Р
-\def\cyrillicS {\char"0421 } % CYRILLIC CAPITAL LETTER ES: С
-\def\cyrillicT {\char"0422 } % CYRILLIC CAPITAL LETTER TE: Т
-\def\cyrillicU {\char"0423 } % CYRILLIC CAPITAL LETTER U: У
-\def\cyrillicF {\char"0424 } % CYRILLIC CAPITAL LETTER EF: Ф
-\def\cyrillicH {\char"0425 } % CYRILLIC CAPITAL LETTER HA: Х
-\def\cyrillicC {\char"0426 } % CYRILLIC CAPITAL LETTER TSE: Ц
-\def\cyrillicCH {\char"0427 } % CYRILLIC CAPITAL LETTER CHE: Ч
-\def\cyrillicSH {\char"0428 } % CYRILLIC CAPITAL LETTER SHA: Ш
-\def\cyrillicSHCH {\char"0429 } % CYRILLIC CAPITAL LETTER SHCHA: Щ
-\def\cyrillicHRDSN {\char"042A } % CYRILLIC CAPITAL LETTER HARD SIGN: Ъ
-\def\cyrillicERY {\char"042B } % CYRILLIC CAPITAL LETTER YERU: Ы
-\def\cyrillicSFTSN {\char"042C } % CYRILLIC CAPITAL LETTER SOFT SIGN: Ь
-\def\cyrillicEREV {\char"042D } % CYRILLIC CAPITAL LETTER E: Э
-\def\cyrillicYU {\char"042E } % CYRILLIC CAPITAL LETTER YU: Ю
-\def\cyrillicYA {\char"042F } % CYRILLIC CAPITAL LETTER YA: Я
-\def\cyrillica {\char"0430 } % CYRILLIC SMALL LETTER A: а
-\def\cyrillicb {\char"0431 } % CYRILLIC SMALL LETTER BE: б
-\def\cyrillicv {\char"0432 } % CYRILLIC SMALL LETTER VE: в
-\def\cyrillicg {\char"0433 } % CYRILLIC SMALL LETTER GHE: г
-\def\cyrillicd {\char"0434 } % CYRILLIC SMALL LETTER DE: д
-\def\cyrillice {\char"0435 } % CYRILLIC SMALL LETTER IE: е
-\def\cyrilliczh {\char"0436 } % CYRILLIC SMALL LETTER ZHE: ж
-\def\cyrillicz {\char"0437 } % CYRILLIC SMALL LETTER ZE: з
-\def\cyrillici {\char"0438 } % CYRILLIC SMALL LETTER I: и
-\def\cyrillicishrt {\char"0439 } % CYRILLIC SMALL LETTER SHORT I: й
-\def\cyrillick {\char"043A } % CYRILLIC SMALL LETTER KA: к
-\def\cyrillicl {\char"043B } % CYRILLIC SMALL LETTER EL: л
-\def\cyrillicm {\char"043C } % CYRILLIC SMALL LETTER EM: м
-\def\cyrillicn {\char"043D } % CYRILLIC SMALL LETTER EN: н
-\def\cyrillico {\char"043E } % CYRILLIC SMALL LETTER O: о
-\def\cyrillicp {\char"043F } % CYRILLIC SMALL LETTER PE: п
-\def\cyrillicr {\char"0440 } % CYRILLIC SMALL LETTER ER: р
-\def\cyrillics {\char"0441 } % CYRILLIC SMALL LETTER ES: с
-\def\cyrillict {\char"0442 } % CYRILLIC SMALL LETTER TE: т
-\def\cyrillicu {\char"0443 } % CYRILLIC SMALL LETTER U: у
-\def\cyrillicf {\char"0444 } % CYRILLIC SMALL LETTER EF: ф
-\def\cyrillich {\char"0445 } % CYRILLIC SMALL LETTER HA: х
-\def\cyrillicc {\char"0446 } % CYRILLIC SMALL LETTER TSE: ц
-\def\cyrillicch {\char"0447 } % CYRILLIC SMALL LETTER CHE: ч
-\def\cyrillicsh {\char"0448 } % CYRILLIC SMALL LETTER SHA: ш
-\def\cyrillicshch {\char"0449 } % CYRILLIC SMALL LETTER SHCHA: щ
-\def\cyrillichrdsn {\char"044A } % CYRILLIC SMALL LETTER HARD SIGN: ъ
-\def\cyrillicery {\char"044B } % CYRILLIC SMALL LETTER YERU: ы
-\def\cyrillicsftsn {\char"044C } % CYRILLIC SMALL LETTER SOFT SIGN: ь
-\def\cyrillicerev {\char"044D } % CYRILLIC SMALL LETTER E: э
-\def\cyrillicyu {\char"044E } % CYRILLIC SMALL LETTER YU: ю
-\def\cyrillicya {\char"044F } % CYRILLIC SMALL LETTER YA: я
-\def\cyrillicegrave {\char"0450 } % CYRILLIC SMALL LETTER IE WITH GRAVE: ѐ
-\def\cyrillicyo {\char"0451 } % CYRILLIC SMALL LETTER IO: ё
-\def\cyrillicdje {\char"0452 } % CYRILLIC SMALL LETTER DJE: ђ
-\def\cyrillicgje {\char"0453 } % CYRILLIC SMALL LETTER GJE: ѓ
-\def\cyrillicie {\char"0454 } % CYRILLIC SMALL LETTER UKRAINIAN IE: є
-\def\cyrillicdze {\char"0455 } % CYRILLIC SMALL LETTER DZE: ѕ
-\def\cyrillicii {\char"0456 } % CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I: і
-\def\cyrillicyi {\char"0457 } % CYRILLIC SMALL LETTER YI: ї
-\def\cyrillicje {\char"0458 } % CYRILLIC SMALL LETTER JE: ј
-\def\cyrilliclje {\char"0459 } % CYRILLIC SMALL LETTER LJE: љ
-\def\cyrillicnje {\char"045A } % CYRILLIC SMALL LETTER NJE: њ
-\def\cyrillictshe {\char"045B } % CYRILLIC SMALL LETTER TSHE: ћ
-\def\cyrillickje {\char"045C } % CYRILLIC SMALL LETTER KJE: ќ
-\def\cyrillicigrave {\char"045D } % CYRILLIC SMALL LETTER I WITH GRAVE: ѝ
-\def\cyrillicushrt {\char"045E } % CYRILLIC SMALL LETTER SHORT U: ў
-\def\cyrillicdzhe {\char"045F } % CYRILLIC SMALL LETTER DZHE: џ
-\def\cyrillicOMEGA {\char"0460 } % CYRILLIC CAPITAL LETTER OMEGA: Ѡ
-\def\cyrillicomega {\char"0461 } % CYRILLIC SMALL LETTER OMEGA: ѡ
-\def\cyrillicYAT {\char"0462 } % CYRILLIC CAPITAL LETTER YAT: Ѣ
-\def\cyrillicyat {\char"0463 } % CYRILLIC SMALL LETTER YAT: ѣ
-\def\cyrillicEiotified {\char"0464 } % CYRILLIC CAPITAL LETTER IOTIFIED E: Ѥ
-\def\cyrilliceiotified {\char"0465 } % CYRILLIC SMALL LETTER IOTIFIED E: ѥ
-\def\cyrillicLITTLEYUS {\char"0466 } % CYRILLIC CAPITAL LETTER LITTLE YUS: Ѧ
-\def\cyrilliclittleyus {\char"0467 } % CYRILLIC SMALL LETTER LITTLE YUS: ѧ
-\def\cyrillicLITTLEYUSiotified {\char"0468 } % CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS: Ѩ
-\def\cyrilliclittleyusiotified {\char"0469 } % CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS: ѩ
-\def\cyrillicBIGYUS {\char"046A } % CYRILLIC CAPITAL LETTER BIG YUS: Ѫ
-\def\cyrillicbigyus {\char"046B } % CYRILLIC SMALL LETTER BIG YUS: ѫ
-\def\cyrillicBIGYUSiotified {\char"046C } % CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS: Ѭ
-\def\cyrillicbigyusiotified {\char"046D } % CYRILLIC SMALL LETTER IOTIFIED BIG YUS: ѭ
-\def\cyrillicKSI {\char"046E } % CYRILLIC CAPITAL LETTER KSI: Ѯ
-\def\cyrillicksi {\char"046F } % CYRILLIC SMALL LETTER KSI: ѯ
-\def\cyrillicPSI {\char"0470 } % CYRILLIC CAPITAL LETTER PSI: Ѱ
-\def\cyrillicpsi {\char"0471 } % CYRILLIC SMALL LETTER PSI: ѱ
-\def\cyrillicFITA {\char"0472 } % CYRILLIC CAPITAL LETTER FITA: Ѳ
-\def\cyrillicfita {\char"0473 } % CYRILLIC SMALL LETTER FITA: ѳ
-\def\cyrillicIZHITSA {\char"0474 } % CYRILLIC CAPITAL LETTER IZHITSA: Ѵ
-\def\cyrillicizhitsa {\char"0475 } % CYRILLIC SMALL LETTER IZHITSA: ѵ
-\def\cyrillicIZHITSAdoublegrave {\char"0476 } % CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT: Ѷ
-\def\cyrillicizhitsadoublegrave {\char"0477 } % CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT: ѷ
-\def\cyrillicUK {\char"0478 } % CYRILLIC CAPITAL LETTER UK: Ѹ
-\def\cyrillicuk {\char"0479 } % CYRILLIC SMALL LETTER UK: ѹ
-\def\cyrillicOMEGAround {\char"047A } % CYRILLIC CAPITAL LETTER ROUND OMEGA: Ѻ
-\def\cyrillicomegaround {\char"047B } % CYRILLIC SMALL LETTER ROUND OMEGA: ѻ
-\def\cyrillicOMEGAtitlo {\char"047C } % CYRILLIC CAPITAL LETTER OMEGA WITH TITLO: Ѽ
-\def\cyrillicomegatitlo {\char"047D } % CYRILLIC SMALL LETTER OMEGA WITH TITLO: ѽ
-\def\cyrillicOT {\char"047E } % CYRILLIC CAPITAL LETTER OT: Ѿ
-\def\cyrillicot {\char"047F } % CYRILLIC SMALL LETTER OT: ѿ
-\def\cyrillicKOPPA {\char"0480 } % CYRILLIC CAPITAL LETTER KOPPA: Ҁ
-\def\cyrillickoppa {\char"0481 } % CYRILLIC SMALL LETTER KOPPA: ҁ
-\def\cyrillicTITLO {\char"0483 } % COMBINING CYRILLIC TITLO: ҃
-\def\cyrillicPALATALIZATION {\char"0484 } % COMBINING CYRILLIC PALATALIZATION: ҄
-\def\cyrillicDASIAPNEUMATA {\char"0485 } % COMBINING CYRILLIC DASIA PNEUMATA: ҅
-\def\cyrillicPSILIPNEUMATA {\char"0486 } % COMBINING CYRILLIC PSILI PNEUMATA: ҆
-\def\cyrillicISHRTtail {\char"048A } % CYRILLIC CAPITAL LETTER SHORT I WITH TAIL: Ҋ
-\def\cyrillicishrttail {\char"048B } % CYRILLIC SMALL LETTER SHORT I WITH TAIL: ҋ
-\def\cyrillicSEMISOFT {\char"048C } % CYRILLIC CAPITAL LETTER SEMISOFT SIGN: Ҍ
-\def\cyrillicsemisoft {\char"048D } % CYRILLIC SMALL LETTER SEMISOFT SIGN: ҍ
-\def\cyrillicERtick {\char"048E } % CYRILLIC CAPITAL LETTER ER WITH TICK: Ҏ
-\def\cyrillicertick {\char"048F } % CYRILLIC SMALL LETTER ER WITH TICK: ҏ
-\def\cyrillicGHEupturn {\char"0490 } % CYRILLIC CAPITAL LETTER GHE WITH UPTURN: Ґ
-\def\cyrillicgheupturn {\char"0491 } % CYRILLIC SMALL LETTER GHE WITH UPTURN: ґ
-\def\cyrillicGHEstroke {\char"0492 } % CYRILLIC CAPITAL LETTER GHE WITH STROKE: Ғ
-\def\cyrillicghestroke {\char"0493 } % CYRILLIC SMALL LETTER GHE WITH STROKE: ғ
-\def\cyrillicGHEmidhook {\char"0494 } % CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK: Ҕ
-\def\cyrillicghemidhook {\char"0495 } % CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK: ҕ
-\def\cyrillicZHEdescender {\char"0496 } % CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER: Җ
-\def\cyrilliczhedescender {\char"0497 } % CYRILLIC SMALL LETTER ZHE WITH DESCENDER: җ
-\def\cyrillicZDSC {\char"0498 } % CYRILLIC CAPITAL LETTER ZE WITH DESCENDER: Ҙ
-\def\cyrilliczdsc {\char"0499 } % CYRILLIC SMALL LETTER ZE WITH DESCENDER: ҙ
-\def\cyrillicKADC {\char"049A } % CYRILLIC CAPITAL LETTER KA WITH DESCENDER: Қ
-\def\cyrillickadc {\char"049B } % CYRILLIC SMALL LETTER KA WITH DESCENDER: қ
-\def\cyrillicKAvertstroke {\char"049C } % CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE: Ҝ
-\def\cyrillickavertstroke {\char"049D } % CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE: ҝ
-\def\cyrillicKAstroke {\char"049E } % CYRILLIC CAPITAL LETTER KA WITH STROKE: Ҟ
-\def\cyrillickastroke {\char"049F } % CYRILLIC SMALL LETTER KA WITH STROKE: ҟ
-\def\cyrillicKAbashkir {\char"04A0 } % CYRILLIC CAPITAL LETTER BASHKIR KA: Ҡ
-\def\cyrillickabashkir {\char"04A1 } % CYRILLIC SMALL LETTER BASHKIR KA: ҡ
-\def\cyrillicENDC {\char"04A2 } % CYRILLIC CAPITAL LETTER EN WITH DESCENDER: Ң
-\def\cyrillicendc {\char"04A3 } % CYRILLIC SMALL LETTER EN WITH DESCENDER: ң
-\def\cyrillicENGHE {\char"04A4 } % CYRILLIC CAPITAL LIGATURE EN GHE: Ҥ
-\def\cyrillicenghe {\char"04A5 } % CYRILLIC SMALL LIGATURE EN GHE: ҥ
-\def\cyrillicPEmidhook {\char"04A6 } % CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK: Ҧ
-\def\cyrillicpemidhook {\char"04A7 } % CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK: ҧ
-\def\cyrillicHA {\char"04A8 } % CYRILLIC CAPITAL LETTER ABKHASIAN HA: Ҩ
-\def\cyrillicha {\char"04A9 } % CYRILLIC SMALL LETTER ABKHASIAN HA: ҩ
-\def\cyrillicSDSC {\char"04AA } % CYRILLIC CAPITAL LETTER ES WITH DESCENDER: Ҫ
-\def\cyrillicsdsc {\char"04AB } % CYRILLIC SMALL LETTER ES WITH DESCENDER: ҫ
-\def\cyrillicTEDC {\char"04AC } % CYRILLIC CAPITAL LETTER TE WITH DESCENDER: Ҭ
-\def\cyrillictedc {\char"04AD } % CYRILLIC SMALL LETTER TE WITH DESCENDER: ҭ
-\def\cyrillicYstr {\char"04AE } % CYRILLIC CAPITAL LETTER STRAIGHT U: Ү
-\def\cyrillicystr {\char"04AF } % CYRILLIC SMALL LETTER STRAIGHT U: ү
-\def\cyrillicYstrstroke {\char"04B0 } % CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE: Ұ
-\def\cyrillicystrstroke {\char"04B1 } % CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE: ұ
-\def\cyrillicHADC {\char"04B2 } % CYRILLIC CAPITAL LETTER HA WITH DESCENDER: Ҳ
-\def\cyrillichadc {\char"04B3 } % CYRILLIC SMALL LETTER HA WITH DESCENDER: ҳ
-\def\cyrillicTETSE {\char"04B4 } % CYRILLIC CAPITAL LIGATURE TE TSE: Ҵ
-\def\cyrillictetse {\char"04B5 } % CYRILLIC SMALL LIGATURE TE TSE: ҵ
-\def\cyrillicCHEDC {\char"04B6 } % CYRILLIC CAPITAL LETTER CHE WITH DESCENDER: Ҷ
-\def\cyrillicchedc {\char"04B7 } % CYRILLIC SMALL LETTER CHE WITH DESCENDER: ҷ
-\def\cyrillicCHEvertstroke {\char"04B8 } % CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE: Ҹ
-\def\cyrillicchevertstroke {\char"04B9 } % CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE: ҹ
-\def\cyrillicSHHA {\char"04BA } % CYRILLIC CAPITAL LETTER SHHA: Һ
-\def\cyrillicshha {\char"04BB } % CYRILLIC SMALL LETTER SHHA: һ
-\def\cyrillicCHEabkhasian {\char"04BC } % CYRILLIC CAPITAL LETTER ABKHASIAN CHE: Ҽ
-\def\cyrilliccheabkhasian {\char"04BD } % CYRILLIC SMALL LETTER ABKHASIAN CHE: ҽ
-\def\cyrillicCHEDCabkhasian {\char"04BE } % CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER: Ҿ
-\def\cyrillicchedcabkhasian {\char"04BF } % CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER: ҿ
-\def\cyrillicPALOCHKA {\char"04C0 } % CYRILLIC LETTER PALOCHKA: Ӏ
-\def\cyrillicZHEbreve {\char"04C1 } % CYRILLIC CAPITAL LETTER ZHE WITH BREVE: Ӂ
-\def\cyrilliczhebreve {\char"04C2 } % CYRILLIC SMALL LETTER ZHE WITH BREVE: ӂ
-\def\cyrillicKAhook {\char"04C3 } % CYRILLIC CAPITAL LETTER KA WITH HOOK: Ӄ
-\def\cyrillickahook {\char"04C4 } % CYRILLIC SMALL LETTER KA WITH HOOK: ӄ
-\def\cyrillicELtail {\char"04C5 } % CYRILLIC CAPITAL LETTER EL WITH TAIL: Ӆ
-\def\cyrilliceltail {\char"04C6 } % CYRILLIC SMALL LETTER EL WITH TAIL: ӆ
-\def\cyrillicENhook {\char"04C7 } % CYRILLIC CAPITAL LETTER EN WITH HOOK: Ӈ
-\def\cyrillicenhook {\char"04C8 } % CYRILLIC SMALL LETTER EN WITH HOOK: ӈ
-\def\cyrillicENtail {\char"04C9 } % CYRILLIC CAPITAL LETTER EN WITH TAIL: Ӊ
-\def\cyrillicentail {\char"04CA } % CYRILLIC SMALL LETTER EN WITH TAIL: ӊ
-\def\cyrillicCHEkhakassian {\char"04CB } % CYRILLIC CAPITAL LETTER KHAKASSIAN CHE: Ӌ
-\def\cyrillicchekhakassian {\char"04CC } % CYRILLIC SMALL LETTER KHAKASSIAN CHE: ӌ
-\def\cyrillicEMtail {\char"04CD } % CYRILLIC CAPITAL LETTER EM WITH TAIL: Ӎ
-\def\cyrillicemtail {\char"04CE } % CYRILLIC SMALL LETTER EM WITH TAIL: ӎ
-\def\cyrillicAbreve {\char"04D0 } % CYRILLIC CAPITAL LETTER A WITH BREVE: Ӑ
-\def\cyrillicabreve {\char"04D1 } % CYRILLIC SMALL LETTER A WITH BREVE: ӑ
-\def\cyrillicAdiaeresis {\char"04D2 } % CYRILLIC CAPITAL LETTER A WITH DIAERESIS: Ӓ
-\def\cyrillicadiaeresis {\char"04D3 } % CYRILLIC SMALL LETTER A WITH DIAERESIS: ӓ
-\def\cyrillicAE {\char"04D4 } % CYRILLIC CAPITAL LIGATURE A IE: Ӕ
-\def\cyrillicae {\char"04D5 } % CYRILLIC SMALL LIGATURE A IE: ӕ
-\def\cyrillicEbreve {\char"04D6 } % CYRILLIC CAPITAL LETTER IE WITH BREVE: Ӗ
-\def\cyrillicebreve {\char"04D7 } % CYRILLIC SMALL LETTER IE WITH BREVE: ӗ
-\def\cyrillicSCHWA {\char"04D8 } % CYRILLIC CAPITAL LETTER SCHWA: Ә
-\def\cyrillicschwa {\char"04D9 } % CYRILLIC SMALL LETTER SCHWA: ә
-\def\cyrillicSCHWAdiaeresis {\char"04DA } % CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS: Ӛ
-\def\cyrillicschwadiaeresis {\char"04DB } % CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS: ӛ
-\def\cyrillicZHEdiaeresis {\char"04DC } % CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS: Ӝ
-\def\cyrilliczhediaeresis {\char"04DD } % CYRILLIC SMALL LETTER ZHE WITH DIAERESIS: ӝ
-\def\cyrillicZEdiaeresis {\char"04DE } % CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS: Ӟ
-\def\cyrilliczediaeresis {\char"04DF } % CYRILLIC SMALL LETTER ZE WITH DIAERESIS: ӟ
-\def\cyrillicDZEabkhasian {\char"04E0 } % CYRILLIC CAPITAL LETTER ABKHASIAN DZE: Ӡ
-\def\cyrillicdzeabkhasian {\char"04E1 } % CYRILLIC SMALL LETTER ABKHASIAN DZE: ӡ
-\def\cyrillicImacron {\char"04E2 } % CYRILLIC CAPITAL LETTER I WITH MACRON: Ӣ
-\def\cyrillicimacron {\char"04E3 } % CYRILLIC SMALL LETTER I WITH MACRON: ӣ
-\def\cyrillicIdiaeresis {\char"04E4 } % CYRILLIC CAPITAL LETTER I WITH DIAERESIS: Ӥ
-\def\cyrillicidiaeresis {\char"04E5 } % CYRILLIC SMALL LETTER I WITH DIAERESIS: ӥ
-\def\cyrillicOdiaeresis {\char"04E6 } % CYRILLIC CAPITAL LETTER O WITH DIAERESIS: Ӧ
-\def\cyrillicodiaeresis {\char"04E7 } % CYRILLIC SMALL LETTER O WITH DIAERESIS: ӧ
-\def\cyrillicObarred {\char"04E8 } % CYRILLIC CAPITAL LETTER BARRED O: Ө
-\def\cyrillicobarred {\char"04E9 } % CYRILLIC SMALL LETTER BARRED O: ө
-\def\cyrillicObarreddiaeresis {\char"04EA } % CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS: Ӫ
-\def\cyrillicobarreddiaeresis {\char"04EB } % CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS: ӫ
-\def\cyrillicEdiaeresis {\char"04EC } % CYRILLIC CAPITAL LETTER E WITH DIAERESIS: Ӭ
-\def\cyrillicediaeresis {\char"04ED } % CYRILLIC SMALL LETTER E WITH DIAERESIS: ӭ
-\def\cyrillicUmacron {\char"04EE } % CYRILLIC CAPITAL LETTER U WITH MACRON: Ӯ
-\def\cyrillicumacron {\char"04EF } % CYRILLIC SMALL LETTER U WITH MACRON: ӯ
-\def\cyrillicUdiaeresis {\char"04F0 } % CYRILLIC CAPITAL LETTER U WITH DIAERESIS: Ӱ
-\def\cyrillicudiaeresis {\char"04F1 } % CYRILLIC SMALL LETTER U WITH DIAERESIS: ӱ
-\def\cyrillicUdoubleacute {\char"04F2 } % CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE: Ӳ
-\def\cyrillicudoubleacute {\char"04F3 } % CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE: ӳ
-\def\cyrillicCHEdiaeresis {\char"04F4 } % CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS: Ӵ
-\def\cyrillicchediaeresis {\char"04F5 } % CYRILLIC SMALL LETTER CHE WITH DIAERESIS: ӵ
-\def\cyrillicYERUdiaeresis {\char"04F8 } % CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS: Ӹ
-\def\cyrillicyerudiaeresis {\char"04F9 } % CYRILLIC SMALL LETTER YERU WITH DIAERESIS: ӹ
-\def\hebrewAlef {\char"05D0 } % HEBREW LETTER ALEF: א
-\def\hebrewBet {\char"05D1 } % HEBREW LETTER BET: ב
-\def\hebrewGimel {\char"05D2 } % HEBREW LETTER GIMEL: ג
-\def\hebrewDalet {\char"05D3 } % HEBREW LETTER DALET: ד
-\def\hebrewHe {\char"05D4 } % HEBREW LETTER HE: ה
-\def\hebrewVav {\char"05D5 } % HEBREW LETTER VAV: ו
-\def\hebrewZayin {\char"05D6 } % HEBREW LETTER ZAYIN: ז
-\def\hebrewHet {\char"05D7 } % HEBREW LETTER HET: ח
-\def\hebrewTet {\char"05D8 } % HEBREW LETTER TET: ט
-\def\hebrewYod {\char"05D9 } % HEBREW LETTER YOD: י
-\def\hebrewKaffinal {\char"05DA } % HEBREW LETTER FINAL KAF: ך
-\def\hebrewKaf {\char"05DB } % HEBREW LETTER KAF: כ
-\def\hebrewLamed {\char"05DC } % HEBREW LETTER LAMED: ל
-\def\hebrewMemfinal {\char"05DD } % HEBREW LETTER FINAL MEM: ם
-\def\hebrewMem {\char"05DE } % HEBREW LETTER MEM: מ
-\def\hebrewNunfinal {\char"05DF } % HEBREW LETTER FINAL NUN: ן
-\def\hebrewNun {\char"05E0 } % HEBREW LETTER NUN: נ
-\def\hebrewSamekh {\char"05E1 } % HEBREW LETTER SAMEKH: ס
-\def\hebrewAyin {\char"05E2 } % HEBREW LETTER AYIN: ע
-\def\hebrewPefinal {\char"05E3 } % HEBREW LETTER FINAL PE: ף
-\def\hebrewPe {\char"05E4 } % HEBREW LETTER PE: פ
-\def\hebrewTsadifinal {\char"05E5 } % HEBREW LETTER FINAL TSADI: ץ
-\def\hebrewTsadi {\char"05E6 } % HEBREW LETTER TSADI: צ
-\def\hebrewQof {\char"05E7 } % HEBREW LETTER QOF: ק
-\def\hebrewResh {\char"05E8 } % HEBREW LETTER RESH: ר
-\def\hebrewShin {\char"05E9 } % HEBREW LETTER SHIN: ש
-\def\hebrewTav {\char"05EA } % HEBREW LETTER TAV: ת
-\def\Adotbelow {\char"1EA0 } % LATIN CAPITAL LETTER A WITH DOT BELOW: Ạ
-\def\adotbelow {\char"1EA1 } % LATIN SMALL LETTER A WITH DOT BELOW: ạ
-\def\Ahook {\char"1EA2 } % LATIN CAPITAL LETTER A WITH HOOK ABOVE: Ả
-\def\ahook {\char"1EA3 } % LATIN SMALL LETTER A WITH HOOK ABOVE: ả
-\def\Acircumflexacute {\char"1EA4 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE: Ấ
-\def\acircumflexacute {\char"1EA5 } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE: ấ
-\def\Acircumflexgrave {\char"1EA6 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE: Ầ
-\def\acircumflexgrave {\char"1EA7 } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE: ầ
-\def\Acircumflexhook {\char"1EA8 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE: Ẩ
-\def\acircumflexhook {\char"1EA9 } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE: ẩ
-\def\Acircumflextilde {\char"1EAA } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE: Ẫ
-\def\acircumflextilde {\char"1EAB } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE: ẫ
-\def\Acircumflexdotbelow {\char"1EAC } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW: Ậ
-\def\acircumflexdotbelow {\char"1EAD } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW: ậ
-\def\Abreveacute {\char"1EAE } % LATIN CAPITAL LETTER A WITH BREVE AND ACUTE: Ắ
-\def\abreveacute {\char"1EAF } % LATIN SMALL LETTER A WITH BREVE AND ACUTE: ắ
-\def\Abrevegrave {\char"1EB0 } % LATIN CAPITAL LETTER A WITH BREVE AND GRAVE: Ằ
-\def\abrevegrave {\char"1EB1 } % LATIN SMALL LETTER A WITH BREVE AND GRAVE: ằ
-\def\Abrevehook {\char"1EB2 } % LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE: Ẳ
-\def\abrevehook {\char"1EB3 } % LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE: ẳ
-\def\Abrevetilde {\char"1EB4 } % LATIN CAPITAL LETTER A WITH BREVE AND TILDE: Ẵ
-\def\abrevetilde {\char"1EB5 } % LATIN SMALL LETTER A WITH BREVE AND TILDE: ẵ
-\def\Abrevedotbelow {\char"1EB6 } % LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW: Ặ
-\def\abrevedotbelow {\char"1EB7 } % LATIN SMALL LETTER A WITH BREVE AND DOT BELOW: ặ
-\def\Edotbelow {\char"1EB8 } % LATIN CAPITAL LETTER E WITH DOT BELOW: Ẹ
-\def\edotbelow {\char"1EB9 } % LATIN SMALL LETTER E WITH DOT BELOW: ẹ
-\def\Ehook {\char"1EBA } % LATIN CAPITAL LETTER E WITH HOOK ABOVE: Ẻ
-\def\ehook {\char"1EBB } % LATIN SMALL LETTER E WITH HOOK ABOVE: ẻ
-\def\Etilde {\char"1EBC } % LATIN CAPITAL LETTER E WITH TILDE: Ẽ
-\def\etilde {\char"1EBD } % LATIN SMALL LETTER E WITH TILDE: ẽ
-\def\Ecircumflexacute {\char"1EBE } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE: Ế
-\def\ecircumflexacute {\char"1EBF } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE: ế
-\def\Ecircumflexgrave {\char"1EC0 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE: Ề
-\def\ecircumflexgrave {\char"1EC1 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE: ề
-\def\Ecircumflexhook {\char"1EC2 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE: Ể
-\def\ecircumflexhook {\char"1EC3 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE: ể
-\def\Ecircumflextilde {\char"1EC4 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE: Ễ
-\def\ecircumflextilde {\char"1EC5 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE: ễ
-\def\Ecircumflexdotbelow {\char"1EC6 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW: Ệ
-\def\ecircumflexdotbelow {\char"1EC7 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW: ệ
-\def\Ihook {\char"1EC8 } % LATIN CAPITAL LETTER I WITH HOOK ABOVE: Ỉ
-\def\ihook {\char"1EC9 } % LATIN SMALL LETTER I WITH HOOK ABOVE: ỉ
-\def\Idotbelow {\char"1ECA } % LATIN CAPITAL LETTER I WITH DOT BELOW: Ị
-\def\idotbelow {\char"1ECB } % LATIN SMALL LETTER I WITH DOT BELOW: ị
-\def\Odotbelow {\char"1ECC } % LATIN CAPITAL LETTER O WITH DOT BELOW: Ọ
-\def\odotbelow {\char"1ECD } % LATIN SMALL LETTER O WITH DOT BELOW: ọ
-\def\Ohook {\char"1ECE } % LATIN CAPITAL LETTER O WITH HOOK ABOVE: Ỏ
-\def\ohook {\char"1ECF } % LATIN SMALL LETTER O WITH HOOK ABOVE: ỏ
-\def\Ocircumflexacute {\char"1ED0 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE: Ố
-\def\ocircumflexacute {\char"1ED1 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE: ố
-\def\Ocircumflexgrave {\char"1ED2 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE: Ồ
-\def\ocircumflexgrave {\char"1ED3 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE: ồ
-\def\Ocircumflexhook {\char"1ED4 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE: Ổ
-\def\ocircumflexhook {\char"1ED5 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE: ổ
-\def\Ocircumflextilde {\char"1ED6 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE: Ỗ
-\def\ocircumflextilde {\char"1ED7 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE: ỗ
-\def\Ocircumflexdotbelow {\char"1ED8 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW: Ộ
-\def\ocircumflexdotbelow {\char"1ED9 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW: ộ
-\def\Ohornacute {\char"1EDA } % LATIN CAPITAL LETTER O WITH HORN AND ACUTE: Ớ
-\def\ohornacute {\char"1EDB } % LATIN SMALL LETTER O WITH HORN AND ACUTE: ớ
-\def\Ohorngrave {\char"1EDC } % LATIN CAPITAL LETTER O WITH HORN AND GRAVE: Ờ
-\def\ohorngrave {\char"1EDD } % LATIN SMALL LETTER O WITH HORN AND GRAVE: ờ
-\def\Ohornhook {\char"1EDE } % LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE: Ở
-\def\ohornhook {\char"1EDF } % LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE: ở
-\def\Ohorntilde {\char"1EE0 } % LATIN CAPITAL LETTER O WITH HORN AND TILDE: Ỡ
-\def\ohorntilde {\char"1EE1 } % LATIN SMALL LETTER O WITH HORN AND TILDE: ỡ
-\def\Ohorndotbelow {\char"1EE2 } % LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW: Ợ
-\def\ohorndotbelow {\char"1EE3 } % LATIN SMALL LETTER O WITH HORN AND DOT BELOW: ợ
-\def\Udotbelow {\char"1EE4 } % LATIN CAPITAL LETTER U WITH DOT BELOW: Ụ
-\def\udotbelow {\char"1EE5 } % LATIN SMALL LETTER U WITH DOT BELOW: ụ
-\def\Uhook {\char"1EE6 } % LATIN CAPITAL LETTER U WITH HOOK ABOVE: Ủ
-\def\uhook {\char"1EE7 } % LATIN SMALL LETTER U WITH HOOK ABOVE: ủ
-\def\Uhornacute {\char"1EE8 } % LATIN CAPITAL LETTER U WITH HORN AND ACUTE: Ứ
-\def\uhornacute {\char"1EE9 } % LATIN SMALL LETTER U WITH HORN AND ACUTE: ứ
-\def\Uhorngrave {\char"1EEA } % LATIN CAPITAL LETTER U WITH HORN AND GRAVE: Ừ
-\def\uhorngrave {\char"1EEB } % LATIN SMALL LETTER U WITH HORN AND GRAVE: ừ
-\def\Uhornhook {\char"1EEC } % LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE: Ử
-\def\uhornhook {\char"1EED } % LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE: ử
-\def\Uhorntilde {\char"1EEE } % LATIN CAPITAL LETTER U WITH HORN AND TILDE: Ữ
-\def\uhorntilde {\char"1EEF } % LATIN SMALL LETTER U WITH HORN AND TILDE: ữ
-\def\Uhorndotbelow {\char"1EF0 } % LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW: Ự
-\def\uhorndotbelow {\char"1EF1 } % LATIN SMALL LETTER U WITH HORN AND DOT BELOW: ự
-\def\Ygrave {\char"1EF2 } % LATIN CAPITAL LETTER Y WITH GRAVE: Ỳ
-\def\ygrave {\char"1EF3 } % LATIN SMALL LETTER Y WITH GRAVE: ỳ
-\def\Ydotbelow {\char"1EF4 } % LATIN CAPITAL LETTER Y WITH DOT BELOW: Ỵ
-\def\ydotbelow {\char"1EF5 } % LATIN SMALL LETTER Y WITH DOT BELOW: ỵ
-\def\Yhook {\char"1EF6 } % LATIN CAPITAL LETTER Y WITH HOOK ABOVE: Ỷ
-\def\yhook {\char"1EF7 } % LATIN SMALL LETTER Y WITH HOOK ABOVE: ỷ
-\def\Ytilde {\char"1EF8 } % LATIN CAPITAL LETTER Y WITH TILDE: Ỹ
-\def\ytilde {\char"1EF9 } % LATIN SMALL LETTER Y WITH TILDE: ỹ
-\def\greekalphapsili {\char"1F00 } % GREEK SMALL LETTER ALPHA WITH PSILI: ἀ
-\def\greekalphadasia {\char"1F01 } % GREEK SMALL LETTER ALPHA WITH DASIA: ἁ
-\def\greekalphapsilivaria {\char"1F02 } % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA: ἂ
-\def\greekalphadasiavaria {\char"1F03 } % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA: ἃ
-\def\greekalphapsilitonos {\char"1F04 } % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA: ἄ
-\def\greekalphadasiatonos {\char"1F05 } % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA: ἅ
-\def\greekalphapsiliperispomeni {\char"1F06 } % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI: ἆ
-\def\greekalphadasiaperispomeni {\char"1F07 } % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI: ἇ
-\def\greekAlphapsili {\char"1F08 } % GREEK CAPITAL LETTER ALPHA WITH PSILI: Ἀ
-\def\greekAlphadasia {\char"1F09 } % GREEK CAPITAL LETTER ALPHA WITH DASIA: Ἁ
-\def\greekAlphapsilivaria {\char"1F0A } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA: Ἂ
-\def\greekAlphadasiavaria {\char"1F0B } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA: Ἃ
-\def\greekAlphapsilitonos {\char"1F0C } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA: Ἄ
-\def\greekAlphadasiatonos {\char"1F0D } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA: Ἅ
-\def\greekAlphapsiliperispomeni {\char"1F0E } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI: Ἆ
-\def\greekAlphadasiaperispomeni {\char"1F0F } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI: Ἇ
-\def\greekepsilonpsili {\char"1F10 } % GREEK SMALL LETTER EPSILON WITH PSILI: ἐ
-\def\greekepsilondasia {\char"1F11 } % GREEK SMALL LETTER EPSILON WITH DASIA: ἑ
-\def\greekepsilonpsilivaria {\char"1F12 } % GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA: ἒ
-\def\greekepsilondasiavaria {\char"1F13 } % GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA: ἓ
-\def\greekepsilonpsilitonos {\char"1F14 } % GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA: ἔ
-\def\greekepsilondasiatonos {\char"1F15 } % GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA: ἕ
-\def\greekEpsilonpsili {\char"1F18 } % GREEK CAPITAL LETTER EPSILON WITH PSILI: Ἐ
-\def\greekEpsilondasia {\char"1F19 } % GREEK CAPITAL LETTER EPSILON WITH DASIA: Ἑ
-\def\greekEpsilonpsilivaria {\char"1F1A } % GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA: Ἒ
-\def\greekEpsilondasiavaria {\char"1F1B } % GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA: Ἓ
-\def\greekEpsilonpsilitonos {\char"1F1C } % GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA: Ἔ
-\def\greekEpsilondasiatonos {\char"1F1D } % GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA: Ἕ
-\def\greeketapsili {\char"1F20 } % GREEK SMALL LETTER ETA WITH PSILI: ἠ
-\def\greeketadasia {\char"1F21 } % GREEK SMALL LETTER ETA WITH DASIA: ἡ
-\def\greeketapsilivaria {\char"1F22 } % GREEK SMALL LETTER ETA WITH PSILI AND VARIA: ἢ
-\def\greeketadasiavaria {\char"1F23 } % GREEK SMALL LETTER ETA WITH DASIA AND VARIA: ἣ
-\def\greeketapsilitonos {\char"1F24 } % GREEK SMALL LETTER ETA WITH PSILI AND OXIA: ἤ
-\def\greeketadasiatonos {\char"1F25 } % GREEK SMALL LETTER ETA WITH DASIA AND OXIA: ἥ
-\def\greeketapsiliperispomeni {\char"1F26 } % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI: ἦ
-\def\greeketadasiaperispomeni {\char"1F27 } % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI: ἧ
-\def\greekEtapsili {\char"1F28 } % GREEK CAPITAL LETTER ETA WITH PSILI: Ἠ
-\def\greekEtadasia {\char"1F29 } % GREEK CAPITAL LETTER ETA WITH DASIA: Ἡ
-\def\greekEtapsilivaria {\char"1F2A } % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA: Ἢ
-\def\greekEtadasiavaria {\char"1F2B } % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA: Ἣ
-\def\greekEtapsilitonos {\char"1F2C } % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA: Ἤ
-\def\greekEtadasiatonos {\char"1F2D } % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA: Ἥ
-\def\greekEtapsiliperispomeni {\char"1F2E } % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI: Ἦ
-\def\greekEtadasiaperispomeni {\char"1F2F } % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI: Ἧ
-\def\greekiotapsili {\char"1F30 } % GREEK SMALL LETTER IOTA WITH PSILI: ἰ
-\def\greekiotadasia {\char"1F31 } % GREEK SMALL LETTER IOTA WITH DASIA: ἱ
-\def\greekiotapsilivaria {\char"1F32 } % GREEK SMALL LETTER IOTA WITH PSILI AND VARIA: ἲ
-\def\greekiotadasiavaria {\char"1F33 } % GREEK SMALL LETTER IOTA WITH DASIA AND VARIA: ἳ
-\def\greekiotapsilitonos {\char"1F34 } % GREEK SMALL LETTER IOTA WITH PSILI AND OXIA: ἴ
-\def\greekiotadasiatonos {\char"1F35 } % GREEK SMALL LETTER IOTA WITH DASIA AND OXIA: ἵ
-\def\greekiotapsiliperispomeni {\char"1F36 } % GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI: ἶ
-\def\greekiotadasiaperispomeni {\char"1F37 } % GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI: ἷ
-\def\greekIotapsili {\char"1F38 } % GREEK CAPITAL LETTER IOTA WITH PSILI: Ἰ
-\def\greekIotadasia {\char"1F39 } % GREEK CAPITAL LETTER IOTA WITH DASIA: Ἱ
-\def\greekIotapsilivaria {\char"1F3A } % GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA: Ἲ
-\def\greekIotadasiavaria {\char"1F3B } % GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA: Ἳ
-\def\greekIotapsilitonos {\char"1F3C } % GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA: Ἴ
-\def\greekIotadasiatonos {\char"1F3D } % GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA: Ἵ
-\def\greekIotapsiliperispomeni {\char"1F3E } % GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI: Ἶ
-\def\greekIotadasiaperispomeni {\char"1F3F } % GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI: Ἷ
-\def\greekomicronpsili {\char"1F40 } % GREEK SMALL LETTER OMICRON WITH PSILI: ὀ
-\def\greekomicrondasia {\char"1F41 } % GREEK SMALL LETTER OMICRON WITH DASIA: ὁ
-\def\greekomicronpsilivaria {\char"1F42 } % GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA: ὂ
-\def\greekomicrondasiavaria {\char"1F43 } % GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA: ὃ
-\def\greekomicronpsilitonos {\char"1F44 } % GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA: ὄ
-\def\greekomicrondasiatonos {\char"1F45 } % GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA: ὅ
-\def\greekOmicronpsili {\char"1F48 } % GREEK CAPITAL LETTER OMICRON WITH PSILI: Ὀ
-\def\greekOmicrondasia {\char"1F49 } % GREEK CAPITAL LETTER OMICRON WITH DASIA: Ὁ
-\def\greekOmicronpsilivaria {\char"1F4A } % GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA: Ὂ
-\def\greekOmicrondasiavaria {\char"1F4B } % GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA: Ὃ
-\def\greekOmicronpsilitonos {\char"1F4C } % GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA: Ὄ
-\def\greekOmicrondasiatonos {\char"1F4D } % GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA: Ὅ
-\def\greekupsilonpsili {\char"1F50 } % GREEK SMALL LETTER UPSILON WITH PSILI: ὐ
-\def\greekupsilondasia {\char"1F51 } % GREEK SMALL LETTER UPSILON WITH DASIA: ὑ
-\def\greekupsilonpsilivaria {\char"1F52 } % GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA: ὒ
-\def\greekupsilondasiavaria {\char"1F53 } % GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA: ὓ
-\def\greekupsilonpsilitonos {\char"1F54 } % GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA: ὔ
-\def\greekupsilondasiatonos {\char"1F55 } % GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA: ὕ
-\def\greekupsilonpsiliperispomeni {\char"1F56 } % GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI: ὖ
-\def\greekupsilondasiaperispomeni {\char"1F57 } % GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI: ὗ
-\def\greekUpsilondasia {\char"1F59 } % GREEK CAPITAL LETTER UPSILON WITH DASIA: Ὑ
-\def\greekUpsilondasiavaria {\char"1F5B } % GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA: Ὓ
-\def\greekUpsilondasiatonos {\char"1F5D } % GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA: Ὕ
-\def\greekUpsilondasiaperispomeni {\char"1F5F } % GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI: Ὗ
-\def\greekomegapsili {\char"1F60 } % GREEK SMALL LETTER OMEGA WITH PSILI: ὠ
-\def\greekomegadasia {\char"1F61 } % GREEK SMALL LETTER OMEGA WITH DASIA: ὡ
-\def\greekomegapsilivaria {\char"1F62 } % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA: ὢ
-\def\greekomegadasiavaria {\char"1F63 } % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA: ὣ
-\def\greekomegapsilitonos {\char"1F64 } % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA: ὤ
-\def\greekomegadasiatonos {\char"1F65 } % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA: ὥ
-\def\greekomegapsiliperispomeni {\char"1F66 } % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI: ὦ
-\def\greekomegadasiaperispomeni {\char"1F67 } % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI: ὧ
-\def\greekOmegapsili {\char"1F68 } % GREEK CAPITAL LETTER OMEGA WITH PSILI: Ὠ
-\def\greekOmegadasia {\char"1F69 } % GREEK CAPITAL LETTER OMEGA WITH DASIA: Ὡ
-\def\greekOmegapsilivaria {\char"1F6A } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA: Ὢ
-\def\greekOmegadasiavaria {\char"1F6B } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA: Ὣ
-\def\greekOmegapsilitonos {\char"1F6C } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA: Ὤ
-\def\greekOmegadasiatonos {\char"1F6D } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA: Ὥ
-\def\greekOmegapsiliperispomeni {\char"1F6E } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI: Ὦ
-\def\greekOmegadasiaperispomeni {\char"1F6F } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI: Ὧ
-\def\greekalphavaria {\char"1F70 } % GREEK SMALL LETTER ALPHA WITH VARIA: ὰ
-\def\greekalphaoxia {\char"1F71 } % GREEK SMALL LETTER ALPHA WITH OXIA: ά
-\def\greekepsilonvaria {\char"1F72 } % GREEK SMALL LETTER EPSILON WITH VARIA: ὲ
-\def\greekepsilonoxia {\char"1F73 } % GREEK SMALL LETTER EPSILON WITH OXIA: έ
-\def\greeketavaria {\char"1F74 } % GREEK SMALL LETTER ETA WITH VARIA: ὴ
-\def\greeketaoxia {\char"1F75 } % GREEK SMALL LETTER ETA WITH OXIA: ή
-\def\greekiotavaria {\char"1F76 } % GREEK SMALL LETTER IOTA WITH VARIA: ὶ
-\def\greekiotaoxia {\char"1F77 } % GREEK SMALL LETTER IOTA WITH OXIA: ί
-\def\greekomicronvaria {\char"1F78 } % GREEK SMALL LETTER OMICRON WITH VARIA: ὸ
-\def\greekomicronoxia {\char"1F79 } % GREEK SMALL LETTER OMICRON WITH OXIA: ό
-\def\greekupsilonvaria {\char"1F7A } % GREEK SMALL LETTER UPSILON WITH VARIA: ὺ
-\def\greekupsilonoxia {\char"1F7B } % GREEK SMALL LETTER UPSILON WITH OXIA: ύ
-\def\greekomegavaria {\char"1F7C } % GREEK SMALL LETTER OMEGA WITH VARIA: ὼ
-\def\greekomegaoxia {\char"1F7D } % GREEK SMALL LETTER OMEGA WITH OXIA: ώ
-\def\greekalphaiotasubpsili {\char"1F80 } % GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI: ᾀ
-\def\greekalphaiotasubdasia {\char"1F81 } % GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI: ᾁ
-\def\greekalphaiotasubpsilivaria {\char"1F82 } % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI: ᾂ
-\def\greekalphaiotasubdasiavaria {\char"1F83 } % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI: ᾃ
-\def\greekalphaiotasubpsilitonos {\char"1F84 } % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI: ᾄ
-\def\greekalphaiotasubdasiatonos {\char"1F85 } % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI: ᾅ
-\def\greekalphaiotasubpsiliperispomeni{\char"1F86 } % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI: ᾆ
-\def\greekalphaiotasubdasiaperispomeni{\char"1F87 } % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI: ᾇ
-\def\greekAlphaiotasubpsili {\char"1F88 } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI: ᾈ
-\def\greekAlphaiotasubdasia {\char"1F89 } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI: ᾉ
-\def\greekAlphaiotasubpsilivaria {\char"1F8A } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI: ᾊ
-\def\greekAlphaiotasubdasiavaria {\char"1F8B } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI: ᾋ
-\def\greekAlphaiotasubpsilitonos {\char"1F8C } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI: ᾌ
-\def\greekAlphaiotasubdasiatonos {\char"1F8D } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI: ᾍ
-\def\greekAlphaiotasubpsiliperispomeni{\char"1F8E } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI: ᾎ
-\def\greekAlphaiotasubdasiaperispomeni{\char"1F8F } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI: ᾏ
-\def\greeketaiotasubpsili {\char"1F90 } % GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI: ᾐ
-\def\greeketaiotasubdasia {\char"1F91 } % GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI: ᾑ
-\def\greeketaiotasubpsilivaria {\char"1F92 } % GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI: ᾒ
-\def\greeketaiotasubdasiavaria {\char"1F93 } % GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI: ᾓ
-\def\greeketaiotasubpsilitonos {\char"1F94 } % GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI: ᾔ
-\def\greeketaiotasubdasiatonos {\char"1F95 } % GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI: ᾕ
-\def\greeketaiotasubpsiliperispomeni {\char"1F96 } % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI: ᾖ
-\def\greeketaiotasubdasiaperispomeni {\char"1F97 } % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI: ᾗ
-\def\greekEtaiotasubpsili {\char"1F98 } % GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI: ᾘ
-\def\greekEtaiotasubdasia {\char"1F99 } % GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI: ᾙ
-\def\greekEtaiotasubpsilivaria {\char"1F9A } % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI: ᾚ
-\def\greekEtaiotasubdasiavaria {\char"1F9B } % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI: ᾛ
-\def\greekEtaiotasubpsilitonos {\char"1F9C } % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI: ᾜ
-\def\greekEtaiotasubdasiatonos {\char"1F9D } % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI: ᾝ
-\def\greekEtaiotasubpsiliperispomeni {\char"1F9E } % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI: ᾞ
-\def\greekEtaiotasubdasiaperispomeni {\char"1F9F } % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI: ᾟ
-\def\greekomegaiotasubpsili {\char"1FA0 } % GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI: ᾠ
-\def\greekomegaiotasubdasia {\char"1FA1 } % GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI: ᾡ
-\def\greekomegaiotasubpsilivaria {\char"1FA2 } % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI: ᾢ
-\def\greekomegaiotasubdasiavaria {\char"1FA3 } % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI: ᾣ
-\def\greekomegaiotasubpsilitonos {\char"1FA4 } % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI: ᾤ
-\def\greekomegaiotasubdasiatonos {\char"1FA5 } % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI: ᾥ
-\def\greekomegaiotasubpsiliperispomeni{\char"1FA6 } % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI: ᾦ
-\def\greekomegaiotasubdasiaperispomeni{\char"1FA7 } % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI: ᾧ
-\def\greekOmegaiotasubpsili {\char"1FA8 } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI: ᾨ
-\def\greekOmegaiotasubdasia {\char"1FA9 } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI: ᾩ
-\def\greekOmegaiotasubpsilivaria {\char"1FAA } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI: ᾪ
-\def\greekOmegaiotasubdasiavaria {\char"1FAB } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI: ᾫ
-\def\greekOmegaiotasubpsilitonos {\char"1FAC } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI: ᾬ
-\def\greekOmegaiotasubdasiatonos {\char"1FAD } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI: ᾭ
-\def\greekOmegaiotasubpsiliperispomeni{\char"1FAE } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI: ᾮ
-\def\greekOmegaiotasubdasiaperispomeni{\char"1FAF } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI: ᾯ
-\def\greekalphavrachy {\char"1FB0 } % GREEK SMALL LETTER ALPHA WITH VRACHY: ᾰ
-\def\greekalphamacron {\char"1FB1 } % GREEK SMALL LETTER ALPHA WITH MACRON: ᾱ
-\def\greekalphaiotasubvaria {\char"1FB2 } % GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI: ᾲ
-\def\greekalphaiotasub {\char"1FB3 } % GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI: ᾳ
-\def\greekalphaiotasubtonos {\char"1FB4 } % GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI: ᾴ
-\def\greekalphaperispomeni {\char"1FB6 } % GREEK SMALL LETTER ALPHA WITH PERISPOMENI: ᾶ
-\def\greekalphaiotasubperispomeni {\char"1FB7 } % GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI: ᾷ
-\def\greekAlphavrachy {\char"1FB8 } % GREEK CAPITAL LETTER ALPHA WITH VRACHY: Ᾰ
-\def\greekAlphamacron {\char"1FB9 } % GREEK CAPITAL LETTER ALPHA WITH MACRON: Ᾱ
-\def\greekAlphavaria {\char"1FBA } % GREEK CAPITAL LETTER ALPHA WITH VARIA: Ὰ
-\def\greekAlphatonos {\char"1FBB } % GREEK CAPITAL LETTER ALPHA WITH OXIA: Ά
-\def\greekAlphaiotasub {\char"1FBC } % GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI: ᾼ
-\def\greekCoronis {\char"1FBD } % GREEK KORONIS: ᾽
-\def\greekprosgegrammeni {\char"1FBE } % GREEK PROSGEGRAMMENI: ι
-\def\greekpsili {\char"1FBF } % GREEK PSILI: ᾿
-\def\greekperispomeni {\char"1FC0 } % GREEK PERISPOMENI: ῀
-\def\greekdialytikaperispomeni {\char"1FC1 } % GREEK DIALYTIKA AND PERISPOMENI: ῁
-\def\greeketaiotasubvaria {\char"1FC2 } % GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI: ῂ
-\def\greeketaiotasub {\char"1FC3 } % GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI: ῃ
-\def\greeketaiotasubtonos {\char"1FC4 } % GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI: ῄ
-\def\greeketaperispomeni {\char"1FC6 } % GREEK SMALL LETTER ETA WITH PERISPOMENI: ῆ
-\def\greeketaiotasubperispomeni {\char"1FC7 } % GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI: ῇ
-\def\greekEpsilonvaria {\char"1FC8 } % GREEK CAPITAL LETTER EPSILON WITH VARIA: Ὲ
-\def\greekEpsilontonos {\char"1FC9 } % GREEK CAPITAL LETTER EPSILON WITH OXIA: Έ
-\def\greekEtavaria {\char"1FCA } % GREEK CAPITAL LETTER ETA WITH VARIA: Ὴ
-\def\greekEtatonos {\char"1FCB } % GREEK CAPITAL LETTER ETA WITH OXIA: Ή
-\def\greekEtaiotasub {\char"1FCC } % GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI: ῌ
-\def\greekpsilivaria {\char"1FCD } % GREEK PSILI AND VARIA: ῍
-\def\greekpsilitonos {\char"1FCE } % GREEK PSILI AND OXIA: ῎
-\def\greekpsiliperispomeni {\char"1FCF } % GREEK PSILI AND PERISPOMENI: ῏
-\def\greekiotavrachy {\char"1FD0 } % GREEK SMALL LETTER IOTA WITH VRACHY: ῐ
-\def\greekiotamacron {\char"1FD1 } % GREEK SMALL LETTER IOTA WITH MACRON: ῑ
-\def\greekiotadialytikavaria {\char"1FD2 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA: ῒ
-\def\greekiotadialytikatonos {\char"1FD3 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA: ΐ
-\def\greekiotaperispomeni {\char"1FD6 } % GREEK SMALL LETTER IOTA WITH PERISPOMENI: ῖ
-\def\greekiotadialytikaperispomeni {\char"1FD7 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI: ῗ
-\def\greekIotavrachy {\char"1FD8 } % GREEK CAPITAL LETTER IOTA WITH VRACHY: Ῐ
-\def\greekIotamacron {\char"1FD9 } % GREEK CAPITAL LETTER IOTA WITH MACRON: Ῑ
-\def\greekIotavaria {\char"1FDA } % GREEK CAPITAL LETTER IOTA WITH VARIA: Ὶ
-\def\greekIotatonos {\char"1FDB } % GREEK CAPITAL LETTER IOTA WITH OXIA: Ί
-\def\greekdasiavaria {\char"1FDD } % GREEK DASIA AND VARIA: ῝
-\def\greekdasiatonos {\char"1FDE } % GREEK DASIA AND OXIA: ῞
-\def\greekdasiaperispomeni {\char"1FDF } % GREEK DASIA AND PERISPOMENI: ῟
-\def\greekupsilonvrachy {\char"1FE0 } % GREEK SMALL LETTER UPSILON WITH VRACHY: ῠ
-\def\greekupsilonmacron {\char"1FE1 } % GREEK SMALL LETTER UPSILON WITH MACRON: ῡ
-\def\greekupsilondialytikavaria {\char"1FE2 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA: ῢ
-\def\greekupsilondialytikatonos {\char"1FE3 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA: ΰ
-\def\greekrhopsili {\char"1FE4 } % GREEK SMALL LETTER RHO WITH PSILI: ῤ
-\def\greekrhodasia {\char"1FE5 } % GREEK SMALL LETTER RHO WITH DASIA: ῥ
-\def\greekupsilonperispomeni {\char"1FE6 } % GREEK SMALL LETTER UPSILON WITH PERISPOMENI: ῦ
-\def\greekupsilondialytikaperispomeni {\char"1FE7 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI: ῧ
-\def\greekUpsilonvrachy {\char"1FE8 } % GREEK CAPITAL LETTER UPSILON WITH VRACHY: Ῠ
-\def\greekUpsilonmacron {\char"1FE9 } % GREEK CAPITAL LETTER UPSILON WITH MACRON: Ῡ
-\def\greekUpsilonvaria {\char"1FEA } % GREEK CAPITAL LETTER UPSILON WITH VARIA: Ὺ
-\def\greekUpsilontonos {\char"1FEB } % GREEK CAPITAL LETTER UPSILON WITH OXIA: Ύ
-\def\greekRhodasia {\char"1FEC } % GREEK CAPITAL LETTER RHO WITH DASIA: Ῥ
-\def\greekdialytikavaria {\char"1FED } % GREEK DIALYTIKA AND VARIA: ῭
-\def\greekdialytikatonos {\char"1FEE } % GREEK DIALYTIKA AND OXIA: ΅
-\def\greekvaria {\char"1FEF } % GREEK VARIA: `
-\def\greekomegaiotasubvaria {\char"1FF2 } % GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI: ῲ
-\def\greekomegaiotasub {\char"1FF3 } % GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI: ῳ
-\def\greekomegaiotasubtonos {\char"1FF4 } % GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI: ῴ
-\def\greekomegaperispomeni {\char"1FF6 } % GREEK SMALL LETTER OMEGA WITH PERISPOMENI: ῶ
-\def\greekomegaiotasubperispomeni {\char"1FF7 } % GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI: ῷ
-\def\greekOmicronvaria {\char"1FF8 } % GREEK CAPITAL LETTER OMICRON WITH VARIA: Ὸ
-\def\greekOmicrontonos {\char"1FF9 } % GREEK CAPITAL LETTER OMICRON WITH OXIA: Ό
-\def\greekOmegavaria {\char"1FFA } % GREEK CAPITAL LETTER OMEGA WITH VARIA: Ὼ
-\def\greekOmegatonos {\char"1FFB } % GREEK CAPITAL LETTER OMEGA WITH OXIA: Ώ
-\def\greekOmegaiotasub {\char"1FFC } % GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI: ῼ
-\def\greekoxia {\char"1FFD } % GREEK OXIA: ´
-\def\greekdasia {\char"1FFE } % GREEK DASIA: ῾
-\def\enspace {\char"2002 } % EN SPACE:  
-\def\emspace {\char"2003 } % EM SPACE:  
-\def\thinspace {\char"2009 } % THIN SPACE:  
-\def\hairspace {\char"200A } % HAIR SPACE:  
-\def\textminus {\char"2012 } % FIGURE DASH: ‒
-\def\endash {\char"2013 } % EN DASH: –
-\def\emdash {\char"2014 } % EM DASH: —
-\def\texthorizontalbar {\char"2015 } % HORIZONTAL BAR: ―
-\def\quoteleft {\char"2018 } % LEFT SINGLE QUOTATION MARK: ‘
-\def\quoteright {\char"2019 } % RIGHT SINGLE QUOTATION MARK: ’
-\def\quotesinglebase {\char"201A } % SINGLE LOW-0x0009 QUOTATION MARK: ‚
-\def\quotedblleft {\char"201C } % LEFT DOUBLE QUOTATION MARK: “
-\def\quotedblright {\char"201D } % RIGHT DOUBLE QUOTATION MARK: ”
-\def\quotedblbase {\char"201E } % DOUBLE LOW-0x0009 QUOTATION MARK: „
-\def\textdag {\char"2020 } % DAGGER: †
-\def\textddag {\char"2021 } % DOUBLE DAGGER: ‡
-\def\textbullet {\char"2022 } % BULLET: •
-\def\textellipsis {\char"2026 } % HORIZONTAL ELLIPSIS: …
-\def\perthousand {\char"2030 } % PER MILLE SIGN: ‰
-\def\guilsingleleft {\char"2039 } % SINGLE LEFT-POINTING ANGLE QUOTATION MARK: ‹
-\def\guilsingleright {\char"203A } % SINGLE RIGHT-POINTING ANGLE QUOTATION MARK: ›
-\def\textdong {\char"20AB } % DONG SIGN: ₫
-\def\texteuro {\char"20AC } % EURO SIGN: €
-\def\textnumero {\char"2116 } % NUMERO SIGN: №
-\def\trademark {\char"2122 } % TRADE MARK SIGN: ™
-\def\onethird {\char"2153 } % VULGAR FRACTION ONE THIRD: ⅓
-\def\twothirds {\char"2154 } % VULGAR FRACTION TWO THIRDS: ⅔
-\def\onefifth {\char"2155 } % VULGAR FRACTION ONE FIFTH: ⅕
-\def\twofifths {\char"2156 } % VULGAR FRACTION TWO FIFTHS: ⅖
-\def\threefifths {\char"2157 } % VULGAR FRACTION THREE FIFTHS: ⅗
-\def\fourfifths {\char"2158 } % VULGAR FRACTION FOUR FIFTHS: ⅘
-\def\onesixth {\char"2159 } % VULGAR FRACTION ONE SIXTH: ⅙
-\def\fivesixths {\char"215A } % VULGAR FRACTION FIVE SIXTHS: ⅚
-\def\oneeighth {\char"215B } % VULGAR FRACTION ONE EIGHTH: ⅛
-\def\threeeighths {\char"215C } % VULGAR FRACTION THREE EIGHTHS: ⅜
-\def\fiveeighths {\char"215D } % VULGAR FRACTION FIVE EIGHTHS: ⅝
-\def\seveneighths {\char"215E } % VULGAR FRACTION SEVEN EIGHTHS: ⅞
-\def\romanI {\char"2160 } % ROMAN NUMERAL ONE: Ⅰ
-\def\romanII {\char"2161 } % ROMAN NUMERAL TWO: Ⅱ
-\def\romanIII {\char"2162 } % ROMAN NUMERAL THREE: Ⅲ
-\def\romanIV {\char"2163 } % ROMAN NUMERAL FOUR: Ⅳ
-\def\romanV {\char"2164 } % ROMAN NUMERAL FIVE: Ⅴ
-\def\romanVI {\char"2165 } % ROMAN NUMERAL SIX: Ⅵ
-\def\romanVII {\char"2166 } % ROMAN NUMERAL SEVEN: Ⅶ
-\def\romanVIII {\char"2167 } % ROMAN NUMERAL EIGHT: Ⅷ
-\def\romanIX {\char"2168 } % ROMAN NUMERAL NINE: Ⅸ
-\def\romanX {\char"2169 } % ROMAN NUMERAL TEN: Ⅹ
-\def\romanXI {\char"216A } % ROMAN NUMERAL ELEVEN: Ⅺ
-\def\romanXII {\char"216B } % ROMAN NUMERAL TWELVE: Ⅻ
-\def\romanL {\char"216C } % ROMAN NUMERAL FIFTY: Ⅼ
-\def\romanC {\char"216D } % ROMAN NUMERAL ONE HUNDRED: Ⅽ
-\def\romanD {\char"216E } % ROMAN NUMERAL FIVE HUNDRED: Ⅾ
-\def\romanM {\char"216F } % ROMAN NUMERAL ONE THOUSAND: Ⅿ
-\def\romani {\char"2170 } % SMALL ROMAN NUMERAL ONE: ⅰ
-\def\romanii {\char"2171 } % SMALL ROMAN NUMERAL TWO: ⅱ
-\def\romaniii {\char"2172 } % SMALL ROMAN NUMERAL THREE: ⅲ
-\def\romaniv {\char"2173 } % SMALL ROMAN NUMERAL FOUR: ⅳ
-\def\romanv {\char"2174 } % SMALL ROMAN NUMERAL FIVE: ⅴ
-\def\romanvi {\char"2175 } % SMALL ROMAN NUMERAL SIX: ⅵ
-\def\romanvii {\char"2176 } % SMALL ROMAN NUMERAL SEVEN: ⅶ
-\def\romanviii {\char"2177 } % SMALL ROMAN NUMERAL EIGHT: ⅷ
-\def\romanix {\char"2178 } % SMALL ROMAN NUMERAL NINE: ⅸ
-\def\romanx {\char"2179 } % SMALL ROMAN NUMERAL TEN: ⅹ
-\def\romanxi {\char"217A } % SMALL ROMAN NUMERAL ELEVEN: ⅺ
-\def\romanxii {\char"217B } % SMALL ROMAN NUMERAL TWELVE: ⅻ
-\def\romanl {\char"217C } % SMALL ROMAN NUMERAL FIFTY: ⅼ
-\def\romanc {\char"217D } % SMALL ROMAN NUMERAL ONE HUNDRED: ⅽ
-\def\romand {\char"217E } % SMALL ROMAN NUMERAL FIVE HUNDRED: ⅾ
-\def\romanm {\char"217F } % SMALL ROMAN NUMERAL ONE THOUSAND: ⅿ
-\def\ffligature {\char"FB00 } % LATIN SMALL LIGATURE FF: ff
-\def\filigature {\char"FB01 } % LATIN SMALL LIGATURE FI: fi
-\def\flligature {\char"FB02 } % LATIN SMALL LIGATURE FL: fl
-\def\ffiligature {\char"FB03 } % LATIN SMALL LIGATURE FFI: ffi
-\def\fflligature {\char"FB04 } % LATIN SMALL LIGATURE FFL: ffl
-\def\stligature {\char"FB06 } % LATIN SMALL LIGATURE ST: st
-
-\endinput
diff --git a/tex/context/base/enco-x5.tex b/tex/context/base/enco-x5.tex
index 32a7399ca..f82ec6c5c 100644
--- a/tex/context/base/enco-x5.tex
+++ b/tex/context/base/enco-x5.tex
@@ -8,12 +8,12 @@
%D copyright=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.
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
-%D This module is derived from the some files Han The Thanh
-%D prepared for \LATEX. The dual accent support is still
-%D preliminary, but works ok.
+%D This module is derived from the some files Han The Thanh
+%D prepared for \LATEX. The dual accent support is still
+%D preliminary, but works ok.
\startencoding[x5]
@@ -28,8 +28,8 @@
\definecharacter textbreve 8
\definecharacter textmacron 9
\definecharacter textdotaccent 10
-\definecharacter textcedilla 11
-\definecharacter textogonek 12
+\definecharacter textcedilla 11
+\definecharacter textogonek 12
\definecharacter dotlessi 25
\definecharacter DJ 30
@@ -168,24 +168,24 @@
\defineaccent h y 27
\defineaccent d y 29
-\stopencoding
+\stopencoding
-\endinput
+\endinput
% \startencoding [x5]
-%
+%
% \definecharacter aa {\xfiveencodedaa}
% \definecharacter AA {\xfiveencodedAA}
-%
-% \stopencoding
-%
+%
+% \stopencoding
+%
% \def\xfiveencodedaa%
% {\accent23a}
%
% \def\xfiveencodedAA%
% {\leavevmode
-% \setbox\z@\hbox{h}%
-% \dimen@\ht\z@
+% \setbox\zerocount\hbox{h}%
+% \dimen@\ht\zerocount
% \advance\dimen@ -1ex
% \rlap{\raise.67\dimen@\hbox{\char23}}A}
@@ -200,8 +200,8 @@
% \textendash 21
% \textemdash 22
% \textcompwordmark 23
-% \textperthousand \% \char 24
-% \textpertenthousand \%\char 24\char 24
+% \textperthousand \% \char 24
+% \textpertenthousand \%\char 24\char 24
% \textvisiblespace 32
% \textquotedbl `\"
% \textdollar `\$
diff --git a/tex/context/base/filt-ini.tex b/tex/context/base/filt-ini.tex
index 98c885467..49b32bdd8 100644
--- a/tex/context/base/filt-ini.tex
+++ b/tex/context/base/filt-ini.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Filter Macros (ini)}
+\writestatus{loading}{ConTeXt Filter Macros / Initialization}
% \ifx\OmegaVersion\undefined
@@ -28,41 +28,17 @@
%D The real work starts here.
-\startmessages dutch library: filters
- title: filter
- 1: filter -- wordt geladen
- 2: onbekend filter --
-\stopmessages
-
-\startmessages english library: filters
- title: filter
- 1: filter -- is loaded
- 2: unknown filter --
-\stopmessages
-
-\startmessages german library: filters
- title: filter
- 1: filter -- ist geladen
- 2: unknown filter --
-\stopmessages
-
-\startmessages czech library: filters
- title: filter
- 1: filter -- is loaded
- 2: unknown filter --
-\stopmessages
-
-\startmessages italian library: filters
- title: filtri
- 1: filtro -- caricato
- 2: filtro sconosciuto --
-\stopmessages
-
-\startmessages french library: filters
- title: filtre
- 1: le filtre -- est chargé
- 2: filtre -- inconnu
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
% We need the {\??ot::#1} check because otherwise aleph will crash. Taco's
% torture test:
@@ -108,12 +84,6 @@
\def\magicocpnumber{1}
-% \def\dodousefiltersequence#1%
-% {\expandafter\ocp\csname\??or:#1\endcsname=\truefiltername{#1}\relax
-% \@EA \appendtoks
-% \@EA \addbeforeocplist \@EA \magicocpnumber \csname\??or:#1\endcsname
-% \to \scratchtoks}
-
% one can do:
%
% \definefiltersequence
@@ -135,14 +105,6 @@
\expandafter\noexpand\csname\??or:\!!stringa\endcsname
\to \scratchtoks}
-% \unexpanded\def\usefiltersequence[#1]%
-% {\edef\currentfiltersequence{\getvalue{\??ot#1}}%
-% \scratchtoks\emptytoks
-% \processcommacommand[\currentfiltersequence]\dodousefiltersequence
-% % \showthe\scratchtoks
-% \expanded{\ocplist\csname\??ot:#1\endcsname=\the\scratchtoks}\nullocplist
-% \expanded{\pushocplist\csname\??ot:#1\endcsname}\relax}
-
\unexpanded\def\usefiltersequence[#1]%
{\doifdefined{\??ot::#1}%
{\doifvalue{\??ot::#1}\v!stop
diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua
index eef80c597..6cc227588 100644
--- a/tex/context/base/font-afm.lua
+++ b/tex/context/base/font-afm.lua
@@ -17,7 +17,11 @@ where we handles font encodings. Eventually font encoding goes
away.</p>
--ldx]]--
-local format = string.format
+local trace_features = false trackers.register("afm.features", function(v) trace_features = v end)
+local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end)
+local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end)
+
+local format, match, gmatch, lower = string.format, string.match, string.gmatch, string.lower
fonts = fonts or { }
fonts.afm = fonts.afm or { }
@@ -25,10 +29,9 @@ fonts.afm = fonts.afm or { }
local afm = fonts.afm
local tfm = fonts.tfm
-afm.version = 1.30 -- incrementing this number one up will force a re-cache
-afm.syncspace = true -- when true, nicer stretch values
-afm.enhance_data = true -- best leave this set to true
-afm.trace_features = false
+afm.version = 1.400 -- incrementing this number one up will force a re-cache
+afm.syncspace = true -- when true, nicer stretch values
+afm.enhance_data = true -- best leave this set to true
afm.features = { }
afm.features.aux = { }
afm.features.data = { }
@@ -93,25 +96,25 @@ end
local keys = { }
-function keys.FontName (data,line) data.fullname = line:strip() end
-function keys.ItalicAngle (data,line) data.italicangle = tonumber (line) end
-function keys.IsFixedPitch(data,line) data.isfixedpitch = toboolean(line,true) end
-function keys.CharWidth (data,line) data.charwidth = tonumber (line) end
-function keys.XHeight (data,line) data.xheight = tonumber (line) end
-function keys.Descender (data,line) data.descender = tonumber (line) end
-function keys.Ascender (data,line) data.ascender = tonumber (line) end
+function keys.FontName (data,line) data.metadata.fullname = line:strip() end
+function keys.ItalicAngle (data,line) data.metadata.italicangle = tonumber (line) end
+function keys.IsFixedPitch(data,line) data.metadata.isfixedpitch = toboolean(line,true) end
+function keys.CharWidth (data,line) data.metadata.charwidth = tonumber (line) end
+function keys.XHeight (data,line) data.metadata.xheight = tonumber (line) end
+function keys.Descender (data,line) data.metadata.descender = tonumber (line) end
+function keys.Ascender (data,line) data.metadata.ascender = tonumber (line) end
function keys.Comment (data,line)
-- Comment DesignSize 12 (pts)
-- Comment TFM designsize: 12 (in points)
- line = line:lower()
- local designsize = line:match("designsize[^%d]*(%d+)")
- if designsize then data.designsize = tonumber(designsize) end
+ line = lower(line)
+ local designsize = match(line,"designsize[^%d]*(%d+)")
+ if designsize then data.metadata.designsize = tonumber(designsize) end
end
local function get_charmetrics(data,charmetrics,vector)
local characters = data.characters
local chr, str, ind = { }, "", 0
- for k,v in charmetrics:gmatch("([%a]+) +(.-) *;") do
+ for k,v in gmatch(charmetrics,"([%a]+) +(.-) *;") do
if k == 'C' then
if str ~= "" then characters[str] = chr end
chr = { }
@@ -128,10 +131,10 @@ local function get_charmetrics(data,charmetrics,vector)
elseif k == 'N' then
str = v
elseif k == 'B' then
- local llx, lly, urx, ury = v:match("^ *(.-) +(.-) +(.-) +(.-)$")
+ local llx, lly, urx, ury = match(v,"^ *(.-) +(.-) +(.-) +(.-)$")
chr.boundingbox = { tonumber(llx), tonumber(lly), tonumber(urx), tonumber(ury) }
elseif k == 'L' then
- local plus, becomes = v:match("^(.-) +(.-)$")
+ local plus, becomes = match(v,"^(.-) +(.-)$")
if not chr.ligatures then chr.ligatures = { } end
chr.ligatures[plus] = becomes
end
@@ -143,7 +146,7 @@ end
local function get_kernpairs(data,kernpairs)
local characters = data.characters
- for one, two, value in kernpairs:gmatch("KPX +(.-) +(.-) +(.-)\n") do
+ for one, two, value in gmatch(kernpairs,"KPX +(.-) +(.-) +(.-)\n") do
local chr = characters[one]
if chr then
if not chr.kerns then chr.kerns = { } end
@@ -153,83 +156,85 @@ local function get_kernpairs(data,kernpairs)
end
local function get_variables(data,fontmetrics)
- for key, rest in fontmetrics:gmatch("(%a+) *(.-)[\n\r]") do
+ for key, rest in gmatch(fontmetrics,"(%a+) *(.-)[\n\r]") do
if keys[key] then keys[key](data,rest) end
end
end
local function get_indexes(data,filename)
- local trace = fonts.trace
- local pfbname = input.find_file(file.removesuffix(filename)..".pfb","pfb") or ""
+ local pfbfile = file.replacesuffix(filename,"pfb")
+ local pfbname = resolvers.find_file(pfbfile,"pfb") or ""
if pfbname == "" then
- pfbname = input.find_file(file.removesuffix(file.basename(filename))..".pfb","pfb") or ""
+ pfbname = resolvers.find_file(file.basename(pfbfile),"pfb") or ""
end
if pfbname ~= "" then
- data.luatex = data.luatex or { }
data.luatex.filename = pfbname
- local pfbblob = fontforge.open(pfbname)
+ local pfbblob = fontloader.open(pfbname)
if pfbblob then
local characters = data.characters
- local pfbdata = fontforge.to_table(pfbblob)
+ local pfbdata = fontloader.to_table(pfbblob)
--~ print(table.serialize(pfbdata))
if pfbdata then
local glyphs = pfbdata.glyphs
if glyphs then
- if trace then
+ if trace_loading then
logs.report("load afm","getting index data from %s",pfbname)
end
-- local offset = (glyphs[0] and glyphs[0] != .notdef) or 0
- for index, glyph in pairs(glyphs) do
+ for index, glyph in next, glyphs do
local name = glyph.name
if name then
local char = characters[name]
if char then
- if trace then
+ if trace_indexing then
logs.report("load afm","glyph %s has index %s",name,index)
end
char.index = index
end
end
end
- elseif trace then
+ elseif trace_loading then
logs.report("load afm","no glyph data in pfb file %s",pfbname)
end
- elseif trace then
+ elseif trace_loading then
logs.report("load afm","no data in pfb file %s",pfbname)
end
- elseif trace then
+ fontloader.close(pfbblob)
+ elseif trace_loading then
logs.report("load afm","invalid pfb file %s",pfbname)
end
- elseif trace then
+ elseif trace_loading then
logs.report("load afm","no pfb file for %s",filename)
end
end
function afm.read_afm(filename)
- local ok, afmblob, size = input.loadbinfile(filename) -- has logging
+ local ok, afmblob, size = resolvers.loadbinfile(filename) -- has logging
-- local ok, afmblob = true, file.readdata(filename)
if ok and afmblob then
local data = {
- version = version or '0',
characters = { },
- filename = file.removesuffix(file.basename(filename))
+ metadata = {
+ version = version or '0', -- hm
+ filename = file.removesuffix(file.basename(filename))
+ }
}
afmblob = afmblob:gsub("StartCharMetrics(.-)EndCharMetrics", function(charmetrics)
- if fonts.trace then
+ if trace_loading then
logs.report("load afm","loading char metrics")
end
get_charmetrics(data,charmetrics,vector)
return ""
end)
afmblob = afmblob:gsub("StartKernPairs(.-)EndKernPairs", function(kernpairs)
- if fonts.trace then
+ if trace_loading then
logs.report("load afm","loading kern pairs")
end
get_kernpairs(data,kernpairs)
return ""
end)
afmblob = afmblob:gsub("StartFontMetrics%s+([%d%.]+)(.-)EndFontMetrics", function(version,fontmetrics)
- if fonts.trace then
+ if trace_loading then
logs.report("load afm","loading variables")
end
data.afmversion = version
@@ -237,10 +242,11 @@ function afm.read_afm(filename)
data.fontdimens = scan_comment(fontmetrics) -- todo: all lpeg, no time now
return ""
end)
+ data.luatex = { }
get_indexes(data,filename)
return data
else
- if fonts.trace then
+ if trace_loading then
logs.report("load afm","no valid afm file %s",filename)
end
return nil
@@ -254,50 +260,53 @@ way we can set them faster when defining a font.</p>
--ldx]]--
function afm.load(filename)
- local name = file.removesuffix(filename)
- local data = containers.read(afm.cache(),name)
- if data and data.verbose ~= fonts.verbose then
- data = nil
- end
- local size = lfs.attributes(name,"size") or 0
- if data and data.size ~= size then
- data = nil
- end
- if not data then
- local foundname = input.find_file(filename,'afm')
- if foundname and foundname ~= "" then
- data = afm.read_afm(foundname)
+ -- hm, for some reasons not resolved yet
+ filename = resolvers.find_file(filename,'afm') or ""
+ if filename ~= "" then
+ local name = file.removesuffix(file.basename(filename))
+ local data = containers.read(afm.cache(),name)
+ local size = lfs.attributes(filename,"size") or 0
+ if not data or data.verbose ~= fonts.verbose or data.size ~= size then
+ logs.report("load afm", "reading %s",filename)
+ data = afm.read_afm(filename)
if data then
+ -- data.luatex = data.luatex or { }
+ logs.report("load afm", "unifying %s",filename)
afm.unify(data,filename)
if afm.enhance_data then
+ logs.report("load afm", "add ligatures")
afm.add_ligatures(data,'ligatures') -- easier this way
+ logs.report("load afm", "add tex-ligatures")
afm.add_ligatures(data,'texligatures') -- easier this way
+ logs.report("load afm", "add extra kerns")
afm.add_kerns(data) -- faster this way
end
- logs.report("load afm","file size: %s",size)
data.size = size
data.verbose = fonts.verbose
- logs.report("load afm","saving: in cache")
+ logs.report("load afm","saving: %s in cache",name)
data = containers.write(afm.cache(), name, data)
+ data = containers.read(afm.cache(),name)
end
end
+ return data
+ else
+ return nil
end
- return data
end
function afm.unify(data, filename)
local unicodevector = fonts.enc.load('unicode').hash
local glyphs, indices, unicodes, names = { }, { }, { }, { }
local verbose, private = fonts.verbose, fonts.private
- for name, blob in pairs(data.characters) do
+ for name, blob in next, data.characters do
local code = unicodevector[name] -- or characters.name_to_unicode[name]
if not code then
- local u = name:match("^uni(%x+)$")
+ local u = match(name,"^uni(%x+)$")
code = u and tonumber(u,16)
if not code then
code = private
private = private + 1
- logs.report("afm glyph", "assigning private slot 0x%04X for unknown glyph name %s", code, name)
+ logs.report("afm glyph", "assigning private slot U+%04X for unknown glyph name %s", code, name)
end
end
local index = blob.index
@@ -319,14 +328,15 @@ function afm.unify(data, filename)
blob.index = nil
end
end
- data.luatex = {
- filename = file.basename(filename),
- unicodes = unicodes, -- name to unicode
- indices = indices, -- unicode to index
- names = names, -- name to index
- }
data.glyphs = glyphs
data.characters = nil
+ local luatex = data.luatex
+ luatex.filename = luatex.filename or file.removesuffix(file.basename(filename))
+ luatex.unicodes = unicodes -- name to unicode
+ luatex.indices = indices -- unicode to index
+ luatex.marks = { } -- todo
+ luatex.names = names -- name to index
+ luatex.private = private
end
--[[ldx--
@@ -335,15 +345,12 @@ and extra kerns. This saves quite some lookups later.</p>
--ldx]]--
function afm.add_ligatures(afmdata,ligatures)
- local glyphs = afmdata.glyphs
- local luatex = afmdata.luatex
- local indices = luatex.indices
- local unicodes = luatex.unicodes
- local names = luatex.names
- for k,v in pairs(characters[ligatures]) do -- main characters table
+ local glyphs, luatex = afmdata.glyphs, afmdata.luatex
+ local indices, unicodes, names = luatex.indices, luatex.unicodes, luatex.names
+ for k,v in next, characters[ligatures] do -- main characters table
local one = glyphs[names[k]]
if one then
- for _, b in pairs(v) do
+ for _, b in next, v do
two, three = b[1], b[2]
if two and three and names[two] and names[three] then
local ol = one[ligatures]
@@ -370,28 +377,42 @@ function afm.add_kerns(afmdata)
local names = afmdata.luatex.names
local uncomposed = characters.uncomposed
local function do_it_left(what)
- for index, glyph in pairs(glyphs) do
- if glyph.kerns then
- local k = { }
- for complex, simple in pairs(uncomposed[what]) do
- local ks = k[simple]
- if ks and not k[complex] then
- k[complex] = ks
+ for index, glyph in next, glyphs do
+ local kerns = glyph.kerns
+ if kerns then
+ local extrakerns = glyph.extrakerns or { }
+ for complex, simple in next, uncomposed[what] do
+ if names[compex] then
+ local ks = kerns[simple]
+ if ks and not kerns[complex] then
+ extrakerns[complex] = ks
+ end
end
end
- if next(k) then
- glyph.extrakerns = k
+ if next(extrakerns) then
+ glyph.extrakerns = extrakerns
end
end
end
end
local function do_it_copy(what)
- for complex, simple in pairs(uncomposed[what]) do
+ for complex, simple in next, uncomposed[what] do
local c = glyphs[names[complex]]
if c then -- optional
local s = glyphs[names[simple]]
- if s and s.kerns then
- c.extrakerns = s.kerns -- ok ? no merge ?
+ if s then
+ if not c.kerns then
+ c.extrakerns = s.kerns or { }
+ end
+ if s.extrakerns then
+ local extrakerns = c.extrakerns or { }
+ for k, v in next, s.extrakerns do
+ extrakerns[k] = v
+ end
+ if next(extrakerns) then
+ s.extrakerns = extrakerns
+ end
+ end
end
end
end
@@ -413,12 +434,20 @@ end
function afm.add_dimensions(data) -- we need to normalize afm to otf i.e. indexed table instead of name
if data then
- for index, glyph in pairs(data.glyphs) do
+ for index, glyph in next, data.glyphs do
local bb = glyph.boundingbox
if bb then
local ht, dp = bb[4], -bb[2]
- if ht ~= 0 then glyph.height = ht end
- if dp ~= 0 then glyph.depth = dp end
+ if ht == 0 or ht < 0 then
+ -- no need to set it and no negative heights, nil == 0
+ else
+ glyph.height = ht
+ end
+ if dp == 0 or dp < 0 then
+ -- no negative depths and no negative depths, nil == 0
+ else
+ glyph.depth = dp
+ end
end
end
end
@@ -428,42 +457,48 @@ function afm.copy_to_tfm(data)
if data then
local glyphs = data.glyphs
if glyphs then
+ local metadata, luatex = data.metadata, data.luatex
+ local unicodes, indices = luatex.unicodes, luatex.indices
local characters, parameters, descriptions = { }, { }, { }
- local unicodes = data.luatex.unicodes
- local indices = data.luatex.indices
- local tfm = { characters = characters, parameters = parameters, descriptions = descriptions }
- for u, i in pairs(indices) do
+ local tfm = {
+ characters = characters,
+ parameters = parameters,
+ descriptions = descriptions,
+ indices = indices,
+ unicodes = unicodes,
+ luatex = luatex,
+ }
+ for u, i in next, indices do
local d = glyphs[i]
- characters[u] = { } -- not needed
+ characters[u] = { }
descriptions[u] = d
- d.index = i
end
- tfm.encodingbytes = data.encodingbytes or 2
- tfm.fullname = data.fullname
- tfm.filename = data.filename
- tfm.name = tfm.fullname -- data.name or tfm.fullname
+ tfm.encodingbytes = metadata.encodingbytes or 2
+ tfm.fullname = metadata.fullname
+ tfm.filename = metadata.filename
+ tfm.name = tfm.fullname
tfm.type = "real"
tfm.units = 1000
- tfm.stretch = stretch
- tfm.slant = slant
+ tfm.stretch = stretch -- nil
+ tfm.slant = slant -- nil
tfm.direction = 0
tfm.boundarychar_label = 0
tfm.boundarychar = 65536
--~ tfm.false_boundarychar = 65536 -- produces invalid tfm in luatex
- tfm.designsize = (data.designsize or 10)*65536
+ tfm.designsize = (metadata.designsize or 10)*65536
local spaceunits = 500
tfm.spacer = "500 units"
-- same as otf
local endash, emdash = unicodes['space'], unicodes['emdash']
- if data.isfixedpitch then
+ if metadata.isfixedpitch then
if descriptions[endash] then
spaceunits, tfm.spacer = descriptions[endash].width, "space"
end
if not spaceunits and descriptions[emdash] then
spaceunits, tfm.spacer = descriptions[emdash].width, "emdash"
end
- if not spaceunits and data.charwidth then
- spaceunits, tfm.spacer = data.charwidth, "charwidth"
+ if not spaceunits and metadata.charwidth then
+ spaceunits, tfm.spacer = metadata.charwidth, "charwidth"
end
else
if descriptions[endash] then
@@ -472,8 +507,8 @@ function afm.copy_to_tfm(data)
-- if not spaceunits and descriptions[emdash] then
-- spaceunits, tfm.spacer = descriptions[emdash].width/2, "emdash/2"
-- end
- if not spaceunits and data.charwidth then
- spaceunits, tfm.spacer = data.charwidth, "charwidth"
+ if not spaceunits and metadata.charwidth then
+ spaceunits, tfm.spacer = metadata.charwidth, "charwidth"
end
end
--
@@ -484,25 +519,26 @@ function afm.copy_to_tfm(data)
parameters.space_shrink = 333
parameters.x_height = 400
parameters.quad = 1000
- parameters.extra_space = 0
if spaceunits < 200 then
-- todo: warning
end
- tfm.italicangle = data.italicangle
- tfm.ascender = math.abs(data.ascender or 0)
- tfm.descender = math.abs(data.descender or 0)
- if data.italicangle then
- parameters.slant = parameters.slant - math.round(math.tan(data.italicangle*math.pi/180))
+ tfm.ascender = math.abs(metadata.ascender or 0)
+ tfm.descender = math.abs(metadata.descender or 0)
+ local italicangle = data.metadata.italicangle
+ if italicangle then
+ tfm.italicangle = italicangle
+ parameters.slant = parameters.slant - math.round(math.tan(italicangle*math.pi/180))
end
- if data.isfixedpitch then
+ if metadata.isfixedpitch then
parameters.space_stretch = 0
parameters.space_shrink = 0
elseif afm.syncspace then
parameters.space_stretch = spaceunits/2
parameters.space_shrink = spaceunits/3
end
- if data.xheight and data.xheight > 0 then
- parameters.x_height = data.xheight
+ parameters.extra_space = parameters.space_shrink
+ if metadata.xheight and metadata.xheight > 0 then
+ parameters.x_height = metadata.xheight
else
-- same as otf
local x = unicodes['x']
@@ -516,7 +552,7 @@ function afm.copy_to_tfm(data)
end
local fd = data.fontdimens
if fd and fd[8] and fd[9] and fd[10] then -- math
- for k,v in pairs(fd) do
+ for k,v in next, fd do
parameters[k] = v
end
end
@@ -543,47 +579,59 @@ end
function afm.set_features(tfmdata)
local shared = tfmdata.shared
local afmdata = shared.afmdata
- -- elsewhere: shared.features = fonts.define.check(shared.features,afm.features.default)
local features = shared.features
if not table.is_empty(features) then
local mode = tfmdata.mode or fonts.mode
- local fi = fonts.initializers[mode]
- if fi and fi.afm then
- local function initialize(list) -- using tex lig and kerning
+ local initializers = fonts.initializers
+ local fi = initializers[mode]
+ local fiafm = fi and fi.afm
+ if fiafm then
+ local lists = {
+ fonts.triggers,
+ afm.features.list,
+ fonts.manipulators,
+ }
+ for l=1,3 do
+ local list = lists[l]
if list then
- for _, f in ipairs(list) do
+ for i=1,#list do
+ local f = list[i]
local value = features[f]
- if value and fi.afm[f] then -- brr
- if afm.trace_features then
+ if value and fiafm[f] then -- brr
+ if trace_features then
logs.report("define afm","initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown',tfmdata.name or 'unknown')
end
- fi.afm[f](tfmdata,value)
+ fiafm[f](tfmdata,value)
mode = tfmdata.mode or fonts.mode
- fi = fonts.initializers[mode]
+ fiafm = initializers[mode].afm
end
end
end
end
- initialize(fonts.triggers)
- initialize(afm.features.list)
- initialize(fonts.manipulators)
end
local fm = fonts.methods[mode]
- if fm and fm.afm then
- local function register(list) -- node manipulations
+ local fmafm = fm and fm.afm
+ if fmfm then
+ local lists = {
+ afm.features.list,
+ }
+ local sp = shared.processors
+ for l=1,1 do
+ local list = lists[l]
if list then
- for _, f in ipairs(list) do
- if features[f] and fm.afm[f] then -- brr
- if not shared.processors then -- maybe also predefine
- shared.processors = { fm.afm[f] }
+ for i=1,#list do
+ local f = list[i]
+ if features[f] and fmafm[f] then -- brr
+ if not sp then
+ sp = { fmafm[f] }
+ shared.processors = sp
else
- shared.processors[#shared.processors+1] = fm.afm[f]
+ sp[#sp+1] = fmafm[f]
end
end
end
end
end
- register(afm.features.list)
end
end
end
@@ -598,21 +646,21 @@ end
function afm.afm_to_tfm(specification)
local afmname = specification.filename or specification.name
- local encoding, filename = afmname:match("^(.-)%-(.*)$") -- context: encoding-name.*
+ local encoding, filename = match(afmname,"^(.-)%-(.*)$") -- context: encoding-name.*
if encoding and filename and fonts.enc.known[encoding] then
tfm.set_normal_feature(specification,'encoding',encoding) -- will go away
- if fonts.trace then
+ if trace_loading then
logs.report("load afm","stripping encoding prefix from filename %s",afmname)
end
afmname = filename
- elseif specification.forced == "afm" then
- if fonts.trace then
+ elseif specification.forced == "afm" or specification.format == "afm" then -- move this one up
+ if trace_loading then
logs.report("load afm","forcing afm format for %s",afmname)
end
else
- local tfmname = input.findbinfile(afmname,"ofm") or ""
+ local tfmname = resolvers.findbinfile(afmname,"ofm") or ""
if tfmname ~= "" then
- if fonts.trace then
+ if trace_loading then
logs.report("load afm","fallback from afm to tfm for %s",afmname)
end
afmname = ""
@@ -638,7 +686,7 @@ function afm.afm_to_tfm(specification)
tfmdata.shared.features = features
afm.set_features(tfmdata)
end
- elseif fonts.trace then
+ elseif trace_loading then
logs.report("load afm","no (valid) afm file found with name %s",afmname)
end
tfmdata = containers.write(tfm.cache(),cache_id,tfmdata)
@@ -677,8 +725,8 @@ function tfm.read_from_afm(specification)
end
if filename then
tfmtable.encodingbytes = 2
- tfmtable.filename = input.findbinfile(filename,"") or filename
- tfmtable.fullname = afmdata.fontname or afmdata.fullname
+ tfmtable.filename = resolvers.findbinfile(filename,"") or filename
+ tfmtable.fullname = afmdata.metadata.fontname or afmdata.metadata.fullname
tfmtable.format = 'type1'
tfmtable.name = afmdata.luatex.filename or tfmtable.fullname
end
@@ -701,7 +749,7 @@ function afm.features.prepare_ligatures(tfmdata,ligatures,value)
local luatex = afmdata.luatex
local unicodes = luatex.unicodes
local descriptions = tfmdata.descriptions
- for u, chr in pairs(tfmdata.characters) do
+ for u, chr in next, tfmdata.characters do
local d = descriptions[u]
local l = d[ligatures]
if l then
@@ -710,7 +758,7 @@ function afm.features.prepare_ligatures(tfmdata,ligatures,value)
ligatures = { }
chr.ligatures = ligatures
end
- for k, v in pairs(l) do
+ for k, v in next, l do
local uk, uv = unicodes[k], unicodes[v]
if uk and uv then
ligatures[uk] = {
@@ -730,7 +778,7 @@ function afm.features.prepare_kerns(tfmdata,kerns,value)
local luatex = afmdata.luatex
local unicodes = luatex.unicodes
local descriptions = tfmdata.descriptions
- for u, chr in pairs(tfmdata.characters) do
+ for u, chr in next, tfmdata.characters do
local d = descriptions[u]
local newkerns = d[kerns]
if newkerns then
@@ -739,7 +787,7 @@ function afm.features.prepare_kerns(tfmdata,kerns,value)
kerns = { }
chr.kerns = kerns
end
- for k,v in pairs(newkerns) do
+ for k,v in next, newkerns do
local uk = unicodes[k]
if uk then
kerns[uk] = v
diff --git a/tex/context/base/font-bfm.tex b/tex/context/base/font-bfm.tex
index a7bf398ef..23e3176c4 100644
--- a/tex/context/base/font-bfm.tex
+++ b/tex/context/base/font-bfm.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Font Macros / Mixed Bold Math Support}
+\writestatus{loading}{ConTeXt Font Macros / Mixed Bold Math Support}
%D The following example demonstrates how to use normal, bold, and mixed
%D normal|/|bold math. Since not everyone has the Lucida on his|/|her
diff --git a/tex/context/base/font-chi.tex b/tex/context/base/font-chi.tex
index cf30470d7..0acf710d5 100644
--- a/tex/context/base/font-chi.tex
+++ b/tex/context/base/font-chi.tex
@@ -22,7 +22,7 @@
%D unicode codepoints (yet); if it were possible we could use
%D just one table per input encoding.
-\writestatus{loading}{Context Font Macros / Chinese}
+\writestatus{loading}{ConTeXt Font Macros / Chinese}
% much will to typo-chi.tex
diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua
new file mode 100644
index 000000000..61f3f8ab5
--- /dev/null
+++ b/tex/context/base/font-chk.lua
@@ -0,0 +1,80 @@
+if not modules then modules = { } end modules ['font-chk'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- possible optimization: delayed initialization of vectors
+
+fonts = fonts or { }
+fonts.checkers = fonts.checkers or { }
+
+local checkers = fonts.checkers
+local fontdata = fonts.ids
+local is_character = characters.is_character
+local chardata = characters.data
+
+local glyph = node.id('glyph')
+local traverse_id = node.traverse_id
+
+-- maybe in fonts namespace
+-- deletion can be option
+
+checkers.enabled = false
+checkers.delete = false
+
+function fonts.register_message(font,char,message)
+ local tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ local messages = shared.messages
+ if not messages then
+ messages = { }
+ shared.messages = messages
+ end
+ local category = messages[message]
+ if not category then
+ category = { }
+ messages[message] = category
+ end
+ if not category[char] then
+ logs.report("fonts","char U+%04X in font '%s' with id %s: %s",char,tfmdata.fullname,font,message)
+ category[char] = true
+ end
+end
+
+function checkers.missing(head,tail)
+ if checkers.enabled then
+ local lastfont, characters, found = nil, nil, nil
+ for n in traverse_id(glyph,head) do
+ local font, char = n.font, n.char
+ if font ~= lastfont then
+ characters = fontdata[font].characters
+ end
+ if not characters[char] and is_character[chardata[char].category] then
+ if checkers.delete then
+ fonts.register_message(font,char,"missing (will be deleted)")
+ else
+ fonts.register_message(font,char,"missing")
+ end
+ if not found then
+ found = { n }
+ else
+ found[#found+1] = n
+ end
+ end
+ end
+ if found and checkers.delete then
+ for i=1,#found do
+ local n = found[i]
+ if n == tail then
+ head, tail = nodes.remove(head,n,true)
+ else
+ head, _ = nodes.remove(head,n,true)
+ end
+ end
+ end
+ end
+ return head, tail, false
+end
diff --git a/tex/context/base/font-cid.lua b/tex/context/base/font-cid.lua
new file mode 100644
index 000000000..b8dfc4294
--- /dev/null
+++ b/tex/context/base/font-cid.lua
@@ -0,0 +1,143 @@
+if not modules then modules = { } end modules ['font-cid'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (cidmaps)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, match = string.format, string.match
+local tonumber = tonumber
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+fonts = fonts or { }
+fonts.cid = fonts.cid or { }
+fonts.cid.map = fonts.cid.map or { }
+fonts.cid.max = fonts.cid.max or 10
+
+
+-- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap
+--
+-- 18964 18964 (leader)
+-- 0 /.notdef
+-- 1..95 0020
+-- 99 3000
+
+local number = lpeg.C(lpeg.R("09","af","AF")^1)
+local space = lpeg.S(" \n\r\t")
+local spaces = space^0
+local period = lpeg.P(".")
+local periods = period * period
+local name = lpeg.P("/") * lpeg.C((1-space)^1)
+
+local unicodes, names = { }, { }
+
+local function do_one(a,b)
+ unicodes[tonumber(a)] = tonumber(b,16)
+end
+
+local function do_range(a,b,c)
+ c = tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i] = c
+ c = c + 1
+ end
+end
+
+local function do_name(a,b)
+ names[tonumber(a)] = b
+end
+
+local grammar = lpeg.P { "start",
+ start = number * spaces * number * lpeg.V("series"),
+ series = (spaces * (lpeg.V("one") + lpeg.V("range") + lpeg.V("named")) )^1,
+ one = (number * spaces * number) / do_one,
+ range = (number * periods * number * spaces * number) / do_range,
+ named = (number * spaces * name) / do_name
+}
+
+function fonts.cid.load(filename)
+ local data = io.loaddata(filename)
+ if data then
+ unicodes, names = { }, { }
+ grammar:match(data)
+ local supplement, registry, ordering = match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement = supplement,
+ registry = registry,
+ ordering = ordering,
+ filename = filename,
+ unicodes = unicodes,
+ names = names
+ }
+ else
+ return nil
+ end
+end
+
+local template = "%s-%s-%s.cidmap"
+
+local function locate(registry,ordering,supplement)
+ local filename = string.lower(format(template,registry,ordering,supplement))
+ local cidmap = fonts.cid.map[filename]
+ if not cidmap then
+ if trace_loading then
+ logs.report("load otf","checking cidmap, registry: %s, ordering: %s, supplement: %s, filename: %s",registry,ordering,supplement,filename)
+ end
+ local fullname = resolvers.find_file(filename,'cid') or ""
+ if fullname ~= "" then
+ cidmap = fonts.cid.load(fullname)
+ if cidmap then
+ if trace_loading then
+ logs.report("load otf","using cidmap file %s",filename)
+ end
+ fonts.cid.map[filename] = cidmap
+ return cidmap
+ end
+ end
+ end
+ return cidmap
+end
+
+function fonts.cid.getmap(registry,ordering,supplement)
+ -- cf Arthur R. we can safely scan upwards since cids are downward compatible
+ local supplement = tonumber(supplement)
+ if trace_loading then
+ logs.report("load otf","needed cidmap, registry: %s, ordering: %s, supplement: %s",registry,ordering,supplement)
+ end
+ local cidmap = locate(registry,ordering,supplement)
+ if not cidmap then
+ local cidnum = nil
+ -- next highest (alternatively we could start high)
+ if supplement < fonts.cid.max then
+ for supplement=supplement+1,fonts.cid.max do
+ local c = locate(registry,ordering,supplement)
+ if c then
+ cidmap, cidnum = c, supplement
+ break
+ end
+ end
+ end
+ -- next lowest (least worse fit)
+ if not cidmap and supplement > 0 then
+ for supplement=supplement-1,0,-1 do
+ local c = locate(registry,ordering,supplement)
+ if c then
+ cidmap, cidnum = c, supplement
+ break
+ end
+ end
+ end
+ -- prevent further lookups
+ if cidmap and cidnum > 0 then
+ for s=0,cidnum-1 do
+ filename = format(template,registry,ordering,s)
+ if not fonts.cid.map[filename] then
+ fonts.cid.map[filename] = cidmap -- copy of ref
+ end
+ end
+ end
+ end
+ return cidmap
+end
diff --git a/tex/context/base/font-col.lua b/tex/context/base/font-col.lua
index 0bafea708..5d089fef2 100644
--- a/tex/context/base/font-col.lua
+++ b/tex/context/base/font-col.lua
@@ -8,17 +8,24 @@ if not modules then modules = { } end modules ['font-col'] = {
-- possible optimization: delayed initialization of vectors
-fonts = fonts or { }
-nodes = nodes or { }
+local format, gmatch, texsprint, type = string.format, string.gmatch, tex.sprint, type
+local traverse_id, first_character = node.traverse_id, node.first_character
-local format, texsprint = string.format, tex.sprint
-local traverse_id, glyph = node.traverse_id, node.id('glyph')
+local ctxcatcodes = tex.ctxcatcodes
+
+local trace_collecting = false trackers.register("fonts.collecting", function(v) trace_collecting = v end)
+
+local fontdata = fonts.ids
+
+local glyph = node.id('glyph')
+
+fonts.normalizers = fonts.normalizers or { }
fonts.collections = fonts.collections or { }
fonts.collections.definitions = fonts.collections.definitions or { }
fonts.collections.vectors = fonts.collections.vectors or { }
-fonts.collections.trace = false
+local collections = fonts.collections
local definitions = fonts.collections.definitions
local vectors = fonts.collections.vectors
@@ -26,7 +33,7 @@ local list, current, active = { }, 0, false
-- maybe also a copy
-function fonts.collections.reset(name,font)
+function collections.reset(name,font)
if font and font ~= "" then
local d = definitions[name]
if d then
@@ -40,17 +47,16 @@ function fonts.collections.reset(name,font)
end
end
-function fonts.collections.define(name,font,ranges,details)
+function collections.define(name,font,ranges,details)
-- todo: details -> method=force|conditional rscale=
-- todo: remap=name
- local trace = fonts.collections.trace
local d = definitions[name]
if d then
- if name and trace then
+ if name and trace_collecting then
logs.report("fonts","def: extending set %s using %s",name, font)
end
else
- if name and trace then
+ if name and trace_collecting then
logs.report("fonts","def: defining set %s using %s",name, font)
end
d = { }
@@ -58,17 +64,17 @@ function fonts.collections.define(name,font,ranges,details)
end
details = aux.settings_to_hash(details)
-- todo, combine per font start/stop as arrays
- for s in ranges:gmatch("([^, ]+)") do
+ for s in gmatch(ranges,"([^, ]+)") do
local start, stop, description = characters.getrange(s)
if start and stop then
- if trace then
+ if trace_collecting then
if description then
- logs.report("fonts","def: using range %s (0x%04x-0x%04X, %s)",s,start,stop,description)
+ logs.report("fonts","def: using range %s (U+%04x-U+%04X, %s)",s,start,stop,description)
end
for i=1,#d do
local di = d[i]
if (start >= di.start and start <= di.stop) or (stop >= di.start and stop <= di.stop) then
- logs.report("fonts","def: overlapping ranges 0x%04x-0x%04X and 0x%04x-0x%04X",start,stop,di.start,di.stop)
+ logs.report("fonts","def: overlapping ranges U+%04x-U+%04X and U+%04x-U+%04X",start,stop,di.start,di.stop)
end
end
end
@@ -78,37 +84,35 @@ function fonts.collections.define(name,font,ranges,details)
end
end
-function fonts.collections.stage_1(name)
- input.starttiming(fonts)
+function collections.stage_1(name)
local last = font.current()
- if fonts.collections.trace then
+ if trace_collecting then
logs.report("fonts","def: registering font %s with name %s",last,name)
end
list[#list+1] = last
end
-function fonts.collections.stage_2(name)
+function collections.stage_2(name)
+ statistics.starttiming(fonts)
local d = definitions[name]
local t = { }
- local ids = fonts.tfm.id
- local trace = fonts.collections.trace
- if trace then
+ if trace_collecting then
logs.report("fonts","def: process collection %s",name)
end
for i=1,#d do
local f = d[i]
local id = list[i]
local start, stop = f.start, f.stop
- if trace then
- logs.report("fonts","def: remapping font %s to %s for range 0x%04X - 0x%04X",current,id,start,stop)
+ if trace_collecting then
+ logs.report("fonts","def: remapping font %s to %s for range U+%04X - U+%04X",current,id,start,stop)
end
- local check = toboolean(f.check or "false")
- local force = toboolean(f.force or "true")
+ local check = toboolean(f.check or "false",true)
+ local force = toboolean(f.force or "true",true)
local remap = f.remap or nil
-- check: when true, only set when present in font
-- force: when false, then not set when already set
- local oldchars = ids[current].characters
- local newchars = ids[id].characters
+ local oldchars = fontdata[current].characters
+ local newchars = fontdata[id].characters
if check then
for i=start,stop do
if newchars[i] and (force or (not t[i] and not oldchars[i])) then
@@ -132,11 +136,11 @@ function fonts.collections.stage_2(name)
end
end
vectors[current] = t
- if trace then
+ if trace_collecting then
logs.report("fonts","def: activating collection %s for font %s",name,current)
end
active = true
- input.stoptiming(fonts)
+ statistics.stoptiming(fonts)
end
local P, Cc = lpeg.P, lpeg.Cc
@@ -145,47 +149,47 @@ local okay = ((1-spec)^1 * spec * Cc(true)) + Cc(false)
-- todo: check for already done
-function fonts.collections.prepare(name)
+function collections.prepare(name)
current = font.current()
if vectors[current] then
return
end
- local ids = fonts.tfm.id
- local trace = fonts.collections.trace
local d = definitions[name]
if d then
- if trace then
- local filename = file.basename(ids[current].filename or "?")
+ if trace_collecting then
+ local filename = file.basename(fontdata[current].filename or "?")
logs.report("fonts","def: applying collection %s to %s (file: %s)",name,current,filename)
end
list = { }
- texsprint(tex.ctxcatcodes,"\\dostartcloningfonts") -- move this to tex \dostart...
+ texsprint(ctxcatcodes,"\\dostartcloningfonts") -- move this to tex \dostart...
for i=1,#d do
local f = d[i]
local name = f.font
local scale = f.rscale or 1
if okay:match(name) then
- texsprint(tex.ctxcatcodes,format("\\doclonefonta{%s}{%s}",name,scale)) -- define with unique specs
+ texsprint(ctxcatcodes,format("\\doclonefonta{%s}{%s}",name,scale)) -- define with unique specs
else
- texsprint(tex.ctxcatcodes,format("\\doclonefontb{%s}{%s}",name,scale)) -- define with inherited specs
+ texsprint(ctxcatcodes,format("\\doclonefontb{%s}{%s}",name,scale)) -- define with inherited specs
end
- texsprint(tex.ctxcatcodes,format("\\ctxlua{fonts.collections.stage_1('%s')}",name)) -- registering main font
+ texsprint(ctxcatcodes,format("\\ctxlua{fonts.collections.stage_1('%s')}",name)) -- registering main font
end
- texsprint(tex.ctxcatcodes,format("\\ctxlua{fonts.collections.stage_2('%s')}",name)) -- preparing clone vectors
- texsprint(tex.ctxcatcodes,"\\dostopcloningfonts")
+ texsprint(ctxcatcodes,format("\\ctxlua{fonts.collections.stage_2('%s')}",name)) -- preparing clone vectors
+ texsprint(ctxcatcodes,"\\dostopcloningfonts")
+ elseif trace_collecting then
+ local filename = file.basename(fontdata[current].filename or "?")
+ logs.report("fonts","def: error in applying collection %s to %s (file: %s)",name,current,filename)
end
end
-function fonts.collections.message(message)
- if fonts.collections.trace then
+function collections.message(message)
+ if trace_collecting then
logs.report("fonts","tex: %s",message)
end
end
-function fonts.collections.normalize(head,tail)
+function collections.process(head,tail)
if active then
local done = false
- local trace = fonts.collections.trace
for n in traverse_id(glyph,head) do
local v = vectors[n.font]
if v then
@@ -193,12 +197,12 @@ function fonts.collections.normalize(head,tail)
if id then
if type(id) == "table" then
local newid, newchar = id[1], id[2]
- if trace then
+ if trace_collecting then
logs.report("fonts","lst: remapping character %s in font %s to character %s in font %s",n.char,n.font,newchar,newid)
end
n.font, n.char = newid, newchar
else
- if trace then
+ if trace_collecting then
logs.report("fonts","lst: remapping font %s to %s for character %s",n.font,id,n.char)
end
n.font = id
@@ -209,5 +213,3 @@ function fonts.collections.normalize(head,tail)
end
return head, tail, done
end
-
-nodes.normalize_fonts = fonts.collections.normalize
diff --git a/tex/context/base/font-col.tex b/tex/context/base/font-col.mkiv
index 3383b6515..22a67ac8e 100644
--- a/tex/context/base/font-col.tex
+++ b/tex/context/base/font-col.mkiv
@@ -21,7 +21,7 @@
% \definefontfallback [whatever] [Bold] [0x0080-0x00FF,0x00A0-0x00AF] [rscale=1.2]
% \definefontfallback [whatever] [BoldSlanted] [0x00C0-0x00C7] [check=yes,force=yes]
-\writestatus{loading}{Context Font Fallbacks (col)}
+\writestatus{loading}{ConTeXt Font Macros / Collections}
\registerctxluafile{font-col}{1.001}
@@ -113,8 +113,6 @@
% }
% \stopcolumns
-% \ctxlua{fonts.trace = true ; fonts.collections.trace = true}
-%
% \definefontfeature[zh][mode=node,script=hang,lang=zhs]
% \definefontfallback[serifwhatever] [lmroman10-regular] [0x0000-0x0400][force=yes]
% \definefontfallback[serifboldwhatever] [lmroman10-bold] [0x0000-0x0400][force=yes]
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
new file mode 100644
index 000000000..e87b21165
--- /dev/null
+++ b/tex/context/base/font-ctx.lua
@@ -0,0 +1,387 @@
+if not modules then modules = { } end modules ['font-ctx'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local texsprint, count = tex.sprint, tex.count
+local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower
+local tostring, next = tostring, next
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+local tfm = fonts.tfm
+local define = fonts.define
+local fontdata = fonts.ids
+local specify = define.specify
+
+specify.context_setups = specify.context_setups or { }
+specify.context_numbers = specify.context_numbers or { }
+specify.context_merged = specify.context_merged or { }
+specify.synonyms = specify.synonyms or { }
+
+local setups = specify.context_setups
+local numbers = specify.context_numbers
+local merged = specify.context_merged
+local synonyms = specify.synonyms
+local triggers = fonts.triggers
+
+--[[ldx--
+<p>So far we haven't really dealt with features (or whatever we want
+to pass along with the font definition. We distinguish the following
+situations:</p>
+situations:</p>
+
+<code>
+name:xetex like specs
+name@virtual font spec
+name*context specification
+</code>
+--ldx]]--
+
+function specify.predefined(specification)
+ local detail = specification.detail
+ if detail ~= "" then
+ -- detail = detail:gsub("["..define.splitsymbols.."].*$","") -- get rid of *whatever specs and such
+ if define.methods[detail] then -- since these may be appended at the
+ specification.features.vtf = { preset = detail } -- tex end by default
+ end
+ end
+ return specification
+end
+
+define.register_split("@", specify.predefined)
+
+storage.register("fonts/setups" , define.specify.context_setups , "fonts.define.specify.context_setups" )
+storage.register("fonts/numbers", define.specify.context_numbers, "fonts.define.specify.context_numbers")
+storage.register("fonts/merged", define.specify.context_merged, "fonts.define.specify.context_merged")
+storage.register("fonts/synonyms", define.specify.synonyms, "fonts.define.specify.synonyms")
+
+local normalize_meanings = fonts.otf.meanings.normalize
+local settings_to_hash = aux.settings_to_hash
+local default_features = fonts.otf.features.default
+
+local function preset_context(name,parent,features) -- currently otf only
+ if features == "" then
+ if find(parent,"=") then
+ features = parent
+ parent = ""
+ end
+ end
+ local number = (setups[name] and setups[name].number) or 0
+ local t = (features == "" and { }) or normalize_meanings(settings_to_hash(features))
+ -- todo: synonyms, and not otf bound
+ if parent ~= "" then
+ for p in gmatch(parent,"[^, ]+") do
+ local s = setups[p]
+ if s then
+ for k,v in next, s do
+ if t[k] == nil then
+ t[k] = v
+ end
+ end
+ end
+ end
+ end
+ -- these are auto set so in order to prevent redundant definitions
+ -- we need to preset them (we hash the features and adding a default
+ -- setting during initialization may result in a different hash)
+ for k,v in next, triggers do
+ if type(t[v]) == "nil" then
+ local vv = default_features[v]
+ if vv then t[v] = vv end
+ end
+ end
+ -- sparse 'm so that we get a better hash and less test (experimental
+ -- optimization)
+ local tt = { } -- maybe avoid tt
+ for k,v in next, t do
+ if v then tt[k] = v end
+ end
+ -- needed for dynamic features
+ if number == 0 then
+ number = #numbers + 1
+ numbers[number] = name
+ end
+ tt.number = number
+ setups[name] = tt
+ return number
+end
+
+local function context_number(name) -- will be replaced
+ local t = setups[name]
+ if not t then
+ return 0
+ elseif t.auto then
+ local lng = tonumber(tex.language)
+ local tag = name .. ":" .. lng
+ local s = setups[tag]
+ if s then
+ return s.number or 0
+ else
+ local script, language = languages.association(lng)
+ if t.script ~= script or t.language ~= language then
+ local s = table.fastcopy(t)
+ local n = #numbers + 1
+ setups[tag] = s
+ numbers[n] = tag
+ s.number = n
+ s.script = script
+ s.language = language
+ return n
+ else
+ setups[tag] = t
+ return t.number or 0
+ end
+ end
+ else
+ return t.number or 0
+ end
+end
+
+local function merge_context(currentnumber,extraname,option)
+ local current = setups[numbers[currentnumber]]
+ local extra = setups[extraname]
+ if extra then
+ local mergedfeatures, mergedname = { }, nil
+ if option < 0 then
+ if current then
+ for k, v in next, current do
+ if not extra[k] then
+ mergedfeatures[k] = v
+ end
+ end
+ end
+ mergedname = currentnumber .. "-" .. extraname
+ else
+ if current then
+ for k, v in next, current do
+ mergedfeatures[k] = v
+ end
+ end
+ for k, v in next, extra do
+ mergedfeatures[k] = v
+ end
+ mergedname = currentnumber .. "+" .. extraname
+ end
+ local number = #numbers + 1
+ mergedfeatures.number = number
+ numbers[number] = mergedname
+ merged[number] = option
+ setups[mergedname] = mergedfeatures
+ return number -- context_number(mergedname)
+ else
+ return currentnumber
+ end
+end
+
+local function register_context(fontnumber,extraname,option)
+ local extra = setups[extraname]
+ if extra then
+ local mergedfeatures, mergedname = { }, nil
+ if option < 0 then
+ mergedname = fontnumber .. "-" .. extraname
+ else
+ mergedname = fontnumber .. "+" .. extraname
+ end
+ for k, v in next, extra do
+ mergedfeatures[k] = v
+ end
+ local number = #numbers + 1
+ mergedfeatures.number = number
+ numbers[number] = mergedname
+ merged[number] = option
+ setups[mergedname] = mergedfeatures
+ return number -- context_number(mergedname)
+ else
+ return 0
+ end
+end
+
+specify.preset_context = preset_context
+specify.context_number = context_number
+specify.merge_context = merge_context
+specify.register_context = register_context
+
+local current_font = font.current
+local tex_attribute = tex.attribute
+
+local cache = { } -- concat might be less efficient than nested tables
+
+function fonts.withset(name,what)
+ local zero = tex_attribute[0]
+ local hash = zero .. "+" .. name .. "*" .. what
+ local done = cache[hash]
+ if not done then
+ done = merge_context(zero,name,what)
+ cache[hash] = done
+ end
+ tex_attribute[0] = done
+end
+function fonts.withfnt(name,what)
+ local font = current_font()
+ local hash = font .. "*" .. name .. "*" .. what
+ local done = cache[hash]
+ if not done then
+ done = register_context(font,name,what)
+ cache[hash] = done
+ end
+ tex_attribute[0] = done
+end
+
+function specify.show_context(name)
+ return setups[name] or setups[numbers[name]] or setups[numbers[tonumber(name)]] or { }
+end
+
+local function split_context(features)
+ return setups[features] or (preset_context(features,"","") and setups[features])
+end
+
+specify.split_context = split_context
+
+function specify.context_tostring(name,kind,separator,yes,no,strict,omit) -- not used
+ return aux.hash_to_string(table.merged(fonts[kind].features.default or {},setups[name] or {}),separator,yes,no,strict,omit)
+end
+
+local splitter = lpeg.splitat(",")
+
+function specify.starred(features) -- no longer fallbacks here
+ local detail = features.detail
+ if detail and detail ~= "" then
+ features.features.normal = split_context(detail)
+ else
+ features.features.normal = { }
+ end
+ return features
+end
+
+define.register_split('*',specify.starred)
+
+-- define (two steps)
+
+local P, C, Cc = lpeg.P, lpeg.C, lpeg.Cc
+
+local space = P(" ")
+local spaces = space^0
+local value = C((1-space)^1)
+local rest = C(P(1)^0)
+local scale_none = Cc(0)
+local scale_at = P("at") * Cc(1) * spaces * value
+local scale_sa = P("sa") * Cc(2) * spaces * value
+local scale_mo = P("mo") * Cc(3) * spaces * value
+local scale_scaled = P("scaled") * Cc(4) * spaces * value
+
+local sizepattern = spaces * (scale_at + scale_sa + scale_mo + scale_scaled + scale_none)
+local splitpattern = spaces * value * spaces * rest
+
+local specification --
+
+local get_specification = define.get_specification
+
+function define.command_1(str)
+ statistics.starttiming(fonts)
+ local fullname, size = splitpattern:match(str)
+ local lookup, name, sub, method, detail = get_specification(fullname)
+ if not name then
+ logs.report("define font","strange definition '%s'",str)
+ texsprint(ctxcatcodes,"\\glet\\somefontname\\defaultfontfile")
+ elseif name == "unknown" then
+ texsprint(ctxcatcodes,"\\glet\\somefontname\\defaultfontfile")
+ else
+ texsprint(ctxcatcodes,format("\\xdef\\somefontname{%s}",name))
+ end
+ -- we can also use a count for the size
+ if size and size ~= "" then
+ local mode, size = sizepattern:match(size)
+ if size and mode then
+ count.scaledfontmode = mode
+ texsprint(ctxcatcodes,format("\\def\\somefontsize{%s}",size))
+ else
+ count.scaledfontmode = 0
+ texsprint(ctxcatcodes,format("\\let\\somefontsize\\empty",size))
+ end
+ elseif true then
+ -- so we don't need to check in tex
+ count.scaledfontmode = 2
+--~ texsprint(ctxcatcodes,format("\\def\\somefontsize{*}",size))
+ texsprint(ctxcatcodes,format("\\let\\somefontsize\\empty",size))
+ else
+ count.scaledfontmode = 0
+ texsprint(ctxcatcodes,format("\\let\\somefontsize\\empty",size))
+ end
+ specification = define.makespecification(str,lookup,name,sub,method,detail,size)
+end
+
+function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfallbacks,fontfallbacks,mathsize,textsize)
+ -- name is now resolved and size is scaled cf sa/mo
+ local lookup, name, sub, method, detail = get_specification(str or "")
+ -- asome settings can be overloaded
+ if lookup and lookup ~= "" then specification.lookup = lookup end
+ specification.name = name
+ specification.size = size
+ specification.sub = sub
+ specification.mathsize = mathsize
+ specification.textsize = textsize
+ if detail and detail ~= "" then
+ specification.method, specification.detail = method or "*", detail
+ elseif specification.detail and specification.detail ~= "" then
+ -- already set
+ elseif fontfeatures and fontfeatures ~= "" then
+ specification.method, specification.detail = "*", fontfeatures
+ elseif classfeatures and classfeatures ~= "" then
+ specification.method, specification.detail = "*", classfeatures
+ end
+ if trace_defining then
+ logs.report("define font","memory usage before: %s",statistics.memused())
+ end
+ if fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
+ elseif classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ end
+ local tfmdata = define.read(specification,size) -- id not yet known
+ if not tfmdata then
+ logs.report("define font","unable to define %s as \\%s",name,cs)
+ elseif type(tfmdata) == "number" then
+ if trace_defining then
+ logs.report("define font","reusing %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s)",name,tfmdata,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks)
+ end
+ tex.definefont(global,cs,tfmdata)
+ -- resolved (when designsize is used):
+ texsprint(ctxcatcodes,format("\\def\\somefontsize{%isp}",fontdata[tfmdata].size))
+ else
+ -- local t = os.clock(t)
+ local id = font.define(tfmdata)
+ -- print(name,os.clock()-t)
+ tfmdata.id = id
+ define.register(tfmdata,id)
+ tex.definefont(global,cs,id)
+ tfm.cleanup_table(tfmdata)
+ if trace_defining then
+ logs.report("define font","defining %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s)",name,id,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks)
+ end
+ -- resolved (when designsize is used):
+ texsprint(ctxcatcodes,format("\\def\\somefontsize{%isp}",tfmdata.size))
+ --~ if specification.fallbacks then
+ --~ fonts.collections.prepare(specification.fallbacks)
+ --~ end
+ end
+ if trace_defining then
+ logs.report("define font","memory usage after: %s",statistics.memused())
+ end
+ statistics.stoptiming(fonts)
+end
+
+--~ table.insert(readers.sequence,1,'vtf')
+
+--~ function readers.vtf(specification)
+--~ if specification.features.vtf and specification.features.vtf.preset then
+--~ return tfm.make(specification)
+--~ else
+--~ return nil
+--~ end
+--~ end
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index 474cde41d..8c367e148 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -6,9 +6,13 @@ if not modules then modules = { } end modules ['font-def'] = {
license = "see context related readme files"
}
--- check reuse of lmroman1o-regular vs lmr10
+local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower
+local tostring, next = tostring, next
-local texsprint, count, dimen, format, concat = tex.sprint, tex.count, tex.dimen, string.format, table.concat
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading")
+trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*")
--[[ldx--
<p>Here we deal with defining fonts. We do so by intercepting the
@@ -18,43 +22,30 @@ default loader that only handles <l n='tfm'/>.</p>
fonts = fonts or { }
fonts.define = fonts.define or { }
fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
fonts.vf = fonts.vf or { }
fonts.used = fonts.used or { }
-local tfm = fonts.tfm
-local vf = fonts.vf
+local tfm = fonts.tfm
+local vf = fonts.vf
+local define = fonts.define
tfm.version = 1.01
tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm
---[[ldx--
-<p>Choosing a font by name and specififying its size is only part of the
-game. In order to prevent complex commands, <l n='xetex'/> introduced
-a method to pass feature information as part of the font name. At the
-risk of introducing nasty parsing and compatinility problems, this
-syntax was expanded over time.</p>
-
-<p>For the sake of users who have defined fonts using that syntax, we
-will support it, but we will provide additional methods as well.
-Normally users will not use this direct way, but use a more abstract
-interface.</p>
- --ldx]]--
-
---~ name, kind, features = fonts.features.split_xetex("blabla / B : + lnum ; foo = bar ; - whatever ; whow ; + hans ; test = yes")
-
-fonts.define.method = 3 -- 1: tfm 2: tfm and if not then afm 3: afm and if not then tfm
-fonts.define.auto_afm = true
-fonts.define.auto_otf = true
-fonts.define.specify = fonts.define.specify or { }
-fonts.define.methods = fonts.define.methods or { }
+define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm
+define.specify = fonts.define.specify or { }
+define.methods = fonts.define.methods or { }
tfm.fonts = tfm.fonts or { }
tfm.readers = tfm.readers or { }
tfm.internalized = tfm.internalized or { } -- internal tex numbers
-tfm.id = tfm.id or { } -- font data, maybe use just fonts.ids (faster lookup)
tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' }
+local readers = tfm.readers
+local sequence = readers.sequence
+
--[[ldx--
<p>We hardly gain anything when we cache the final (pre scaled)
<l n='tfm'/> table. But it can be handy for debugging.</p>
@@ -84,7 +75,7 @@ and prepares a table that will move along as we proceed.</p>
local splitter, specifiers = nil, ""
-function fonts.define.add_specifier(symbol)
+function define.add_specifier(symbol)
specifiers = specifiers .. symbol
local left = lpeg.P("(")
local right = lpeg.P(")")
@@ -92,27 +83,32 @@ function fonts.define.add_specifier(symbol)
local method = lpeg.S(specifiers)
local lookup = lpeg.C(lpeg.P("file")+lpeg.P("name")) * colon -- hard test, else problems with : method
local sub = left * lpeg.C(lpeg.P(1-left-right-method)^1) * right
- local specification = lpeg.C(method) * lpeg.C(lpeg.P(1-method)^1)
+--~ local specification = lpeg.C(method) * lpeg.C(lpeg.P(1-method)^1)
+ local specification = lpeg.C(method) * lpeg.C(lpeg.P(1)^1)
local name = lpeg.C((1-sub-specification)^1)
splitter = lpeg.P((lookup + lpeg.Cc("")) * name * (sub + lpeg.Cc("")) * (specification + lpeg.Cc("")))
end
-function fonts.define.get_specification(str)
+function define.get_specification(str)
return splitter:match(str)
end
-function fonts.define.register_split(symbol,action)
- fonts.define.add_specifier(symbol)
- fonts.define.specify[symbol] = action
+function define.register_split(symbol,action)
+ define.add_specifier(symbol)
+ define.specify[symbol] = action
end
-function fonts.define.makespecification(specification, lookup, name, sub, method, detail, size)
+function define.makespecification(specification, lookup, name, sub, method, detail, size)
size = size or 655360
- if fonts.trace then
+ if trace_defining then
logs.report("define font","%s -> lookup: %s, name: %s, sub: %s, method: %s, detail: %s",
specification, (lookup ~= "" and lookup) or "[file]", (name ~= "" and name) or "-",
(sub ~= "" and sub) or "-", (method ~= "" and method) or "-", (detail ~= "" and detail) or "-")
end
+--~ if specification.lookup then
+--~ lookup = specification.lookup -- can come from xetex [] syntax
+--~ specification.lookup = nil
+--~ end
if lookup ~= 'name' then -- for the moment only two lookups, maybe some day also system:
lookup = 'file'
end
@@ -131,37 +127,43 @@ function fonts.define.makespecification(specification, lookup, name, sub, method
return t
end
-function fonts.define.analyze(specification, size)
- local lookup, name, sub, method, detail = fonts.define.get_specification(specification or "")
- return fonts.define.makespecification(specification,lookup, name, sub, method, detail, size)
+function define.analyze(specification, size)
+ -- can be optimized with locals
+ local lookup, name, sub, method, detail = define.get_specification(specification or "")
+ return define.makespecification(specification,lookup, name, sub, method, detail, size)
end
--[[ldx--
<p>A unique hash value is generated by:</p>
--ldx]]--
+local sortedhashkeys = table.sortedhashkeys
+
function tfm.hash_features(specification)
local features = specification.features
if features then
local t = { }
local normal = features.normal
if normal and next(normal) then
- local f = table.sortedhashkeys(normal)
+ local f = sortedhashkeys(normal)
for i=1,#f do
local v = f[i]
- if v ~= "number" then
+ if v ~= "number" and v ~= "features" then -- i need to figure this out, features
t[#t+1] = v .. '=' .. tostring(normal[v])
end
end
end
local vtf = features.vtf
if vtf and next(vtf) then
- local f = table.sortedhashkeys(vtf)
+ local f = sortedhashkeys(vtf)
for i=1,#f do
local v = f[i]
t[#t+1] = v .. '=' .. tostring(vtf[v])
end
end
+--~ if specification.mathsize then
+--~ t[#t] = "mathsize=" .. specification.mathsize
+--~ end
if #t > 0 then
return concat(t,"+")
end
@@ -189,18 +191,28 @@ function tfm.hash_instance(specification,force)
size = math.round(tfm.scaled(size, fonts.designsizes[hash]))
specification.size = size
end
- if fallbacks then
- return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks
- else
- return hash .. ' @ ' .. tostring(size)
- end
+--~ local mathsize = specification.mathsize or 0
+--~ if mathsize > 0 then
+--~ local textsize = specification.textsize
+--~ if fallbacks then
+--~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks
+--~ else
+--~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]'
+--~ end
+--~ else
+ if fallbacks then
+ return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks
+ else
+ return hash .. ' @ ' .. tostring(size)
+ end
+--~ end
end
--[[ldx--
<p>We can resolve the filename using the next function:</p>
--ldx]]--
-function fonts.define.resolve(specification)
+function define.resolve(specification)
if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash
if specification.lookup == 'name' then
specification.resolved, specification.sub = fonts.names.resolve(specification.name,specification.sub)
@@ -218,7 +230,8 @@ function fonts.define.resolve(specification)
else
specification.forced = specification.forced
end
- specification.hash = specification.name .. ' @ ' .. tfm.hash_features(specification)
+--~ specification.hash = specification.name .. ' @ ' .. tfm.hash_features(specification)
+ specification.hash = lower(specification.name .. ' @ ' .. tfm.hash_features(specification))
if specification.sub and specification.sub ~= "" then
specification.hash = specification.sub .. ' @ ' .. specification.hash
end
@@ -242,22 +255,23 @@ specification yet.</p>
--ldx]]--
function tfm.read(specification)
---~ input.starttiming(fonts)
local hash = tfm.hash_instance(specification)
local tfmtable = tfm.fonts[hash] -- hashes by size !
if not tfmtable then
- if specification.forced and specification.forced ~= "" then
- tfmtable = tfm.readers[specification.forced:lower()](specification)
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmtable = readers[lower(forced)](specification)
if not tfmtable then
- logs.report("define font","forced type %s of %s not found",specification.forced,specification.name)
+ logs.report("define font","forced type %s of %s not found",forced,specification.name)
end
else
- for _, reader in ipairs(tfm.readers.sequence) do
- if tfm.readers[reader] then -- not really needed
- if fonts.trace then
+ for s=1,#sequence do -- reader sequence
+ local reader = sequence[s]
+ if readers[reader] then -- not really needed
+ if trace_defining then
logs.report("define font","trying type %s for %s with file %s",reader,specification.name,specification.filename or "unknown")
end
- tfmtable = tfm.readers[reader](specification)
+ tfmtable = readers[reader](specification)
if tfmtable then break end
end
end
@@ -273,7 +287,6 @@ function tfm.read(specification)
--~ tfmtable.mode = specification.features.normal.mode or "base"
end
end
---~ input.stoptiming(fonts)
if not tfmtable then
logs.report("define font","font with name %s is not found",specification.name)
end
@@ -285,26 +298,26 @@ end
--ldx]]--
function tfm.read_and_define(name,size) -- no id
- local specification = fonts.define.analyze(name,size)
+ local specification = define.analyze(name,size)
local method = specification.method
- if method and fonts.define.specify[method] then
- specification = fonts.define.specify[method](specification)
+ if method and define.specify[method] then
+ specification = define.specify[method](specification)
end
- specification = fonts.define.resolve(specification)
+ specification = define.resolve(specification)
local hash = tfm.hash_instance(specification)
- local id = fonts.define.registered(hash)
+ local id = define.registered(hash)
if not id then
local fontdata = tfm.read(specification)
if fontdata then
fontdata.hash = hash
id = font.define(fontdata)
- fonts.define.register(fontdata,id)
-tfm.cleanup_table(fontdata)
+ define.register(fontdata,id)
+ tfm.cleanup_table(fontdata)
else
id = 0 -- signal
end
end
- return tfm.id[id], id
+ return fonts.ids[id], id
end
--[[ldx--
@@ -312,275 +325,113 @@ end
evolved. Each one has its own way of dealing with its format.</p>
--ldx]]--
-function tfm.readers.opentype(specification,suffix,what)
- if fonts.define.auto_otf then
- local fullname, tfmtable = nil, nil
- fullname = input.findbinfile(specification.name,suffix) or ""
- if fullname == "" then
- local fb = fonts.names.old_to_new[specification.name]
- if fb then
- fullname = input.findbinfile(fb,suffix) or ""
- end
- end
- if fullname == "" then
- local fb = fonts.names.new_to_old[specification.name]
- if fb then
- fullname = input.findbinfile(fb,suffix) or ""
- end
- end
- if fullname ~= "" then
- specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then
- tfmtable = tfm.read_from_open_type(specification) -- we need to do it for all matches / todo
- end
- return tfmtable
- else
- return nil
+local function check_tfm(specification,fullname)
+ -- ofm directive blocks local path search unless set
+ fullname = resolvers.findbinfile(fullname, 'tfm') or "" -- just to be sure
+ if fullname ~= "" then
+ specification.filename, specification.format = fullname, "ofm"
+ return tfm.read_from_tfm(specification)
end
end
-function tfm.readers.otf(specification) return tfm.readers.opentype(specification,"otf","opentype") end
-function tfm.readers.ttf(specification) return tfm.readers.opentype(specification,"ttf","truetype") end
-function tfm.readers.ttc(specification) return tfm.readers.opentype(specification,"ttf","truetype") end -- !!
-
-function tfm.readers.afm(specification,method)
- local fullname, tfmtable = nil, nil
- method = method or fonts.define.method
- if method == 2 then
- fullname = input.findbinfile(specification.name,"ofm") or ""
- if fullname == "" then
- tfmtable = tfm.read_from_afm(specification)
- else -- redundant
- specification.filename = fullname
- tfmtable = tfm.read_from_tfm(specification)
- end
- elseif method == 3 then -- maybe also findbinfile here
- if fonts.define.auto_afm then
- tfmtable = tfm.read_from_afm(specification)
- end
- elseif method == 4 then -- maybe also findbinfile here
- tfmtable = tfm.read_from_afm(specification)
+local function check_afm(specification,fullname)
+ fullname = resolvers.findbinfile(fullname, 'afm') or "" -- just to be sure
+ if fullname ~= "" then
+ specification.filename, specification.format = fullname, "afm"
+ return tfm.read_from_afm(specification)
end
- return tfmtable
end
-function tfm.readers.tfm(specification)
- local fullname, tfmtable = nil, nil
- tfmtable = tfm.read_from_tfm(specification)
- return tfmtable
-end
-
---[[ldx--
-<p>So far we haven't really dealt with features (or whatever we want
-to pass along with the font definition. We distinguish the following
-situations:</p>
-situations:</p>
-
-<code>
-name:xetex like specs
-name@virtual font spec
-name*context specification
-</code>
-
-<p>Of course one can always define more.</p>
---ldx]]--
-
-function fonts.define.specify.predefined(specification)
- local detail = specification.detail
- if detail ~= "" then
- -- detail = detail:gsub("["..fonts.define.splitsymbols.."].*$","") -- get rid of *whatever specs and such
- if fonts.define.methods[detail] then -- since these may be appended at the
- specification.features.vtf = { preset = detail } -- tex end by default
+function readers.tfm(specification)
+ local fullname, tfmtable = specification.filename or "", nil
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmtable = check_tfm(specification,specification.name .. "." .. forced)
end
- end
- return specification
-end
-
-fonts.define.register_split("@", fonts.define.specify.predefined)
-
-function fonts.define.specify.colonized(specification) -- xetex mode
- local list = { }
- if specification.detail and specification.detail ~= "" then
- local expanded_features = { }
- local function expand(features)
- for _,v in pairs(features:split(";")) do --just gmatch
- expanded_features[#expanded_features+1] = v
- end
- end
- expand(specification.detail)
- for _,v in pairs(expanded_features) do
- local a, b = v:match("^%s*(%S+)%s*=%s*(%S+)%s*$")
- if a and b then
- list[a] = b:is_boolean()
- if type(list[a]) == "nil" then
- list[a] = b
- end
- else
- local a, b = v:match("^%s*([%+%-]?)%s*(%S+)%s*$")
- if a and b then
- list[b] = a ~= "-"
- end
- end
+ if not tfmtable then
+ tfmtable = check_tfm(specification,specification.name)
end
- end
- specification.features.normal = list
- return specification
-end
-
-function tfm.make(specification)
- -- currently fonts are scaled while constructing the font, so we
- -- have to do scaling of commands in the vf at that point using
- -- e.g. "local scale = g.factor or 1" after all, we need to work
- -- with copies anyway and scaling needs to be done at some point;
- -- however, when virtual tricks are used as feature (makes more
- -- sense) we scale the commands in fonts.tfm.scale (and set the
- -- factor there)
- local fvm = fonts.define.methods[specification.features.vtf.preset]
- if fvm then
- return fvm(specification)
else
- return nil
+ tfmtable = check_tfm(specification,fullname)
end
+ return tfmtable
end
-fonts.define.register_split(":", fonts.define.specify.colonized)
-
-fonts.define.specify.context_setups = fonts.define.specify.context_setups or { }
-fonts.define.specify.context_numbers = fonts.define.specify.context_numbers or { }
-fonts.define.specify.synonyms = fonts.define.specify.synonyms or { }
-
-input.storage.register(false,"fonts/setups" , fonts.define.specify.context_setups , "fonts.define.specify.context_setups" )
-input.storage.register(false,"fonts/numbers", fonts.define.specify.context_numbers, "fonts.define.specify.context_numbers")
-
-fonts.triggers = fonts.triggers or { }
-
-function fonts.define.specify.preset_context(name,parent,features)
- if features == "" then
- if parent:find("=") then
- features = parent
- parent = ""
+function readers.afm(specification,method)
+ local fullname, tfmtable = specification.filename or "", nil
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmtable = check_afm(specification,specification.name .. "." .. forced)
end
- end
- local fds = fonts.define.specify
- local setups, numbers, synonyms = fds.context_setups, fds.context_numbers, fds.synonyms
- local number = (setups[name] and setups[name].number) or 0
- local t = (features == "" and { }) or fonts.otf.meanings.normalize(aux.settings_to_hash(features))
- -- todo: synonyms, and not otf bound
- if parent ~= "" then
- for p in parent:gmatch("[^, ]+") do
- local s = setups[p]
- if s then
- for k,v in pairs(s) do
- if t[k] == nil then
- t[k] = v
- end
- end
+ if not tfmtable then
+ method = method or define.method or "afm or tfm"
+ if method == "tfm" then
+ tfmtable = check_tfm(specification,specification.name)
+ elseif method == "afm" then
+ tfmtable = check_afm(specification,specification.name)
+ elseif method == "tfm or afm" then
+ tfmtable = check_tfm(specification,specification.name) or check_afm(specification,specification.name)
+ else -- method == "afm or tfm" or method == "" then
+ tfmtable = check_afm(specification,specification.name) or check_tfm(specification,specification.name)
end
end
- end
- -- these are auto set so in order to prevent redundant definitions
- -- we need to preset them (we hash the features and adding a default
- -- setting during initialization may result in a different hash)
- local default = fonts.otf.features.default
- for k,v in pairs(fonts.triggers) do
- if type(t[v]) == "nil" then
- local vv = default[v]
- if vv then t[v] = vv end
- end
- end
- -- sparse 'm so that we get a better hash and less test (experimental
- -- optimization)
- local tt = { }
- for k,v in pairs(t) do
- if v then tt[k] = v end
- end
- -- needed for dynamic features
- if number == 0 then
- numbers[#numbers+1] = name
- tt.number = #numbers
else
- tt.number = number
+ tfmtable = check_afm(specification,fullname)
end
- setups[name] = tt
+ return tfmtable
end
-do
-
- -- here we clone features according to languages
-
- local default = 0
- local setups = fonts.define.specify.context_setups
- local numbers = fonts.define.specify.context_numbers
-
- function fonts.define.specify.context_number(name)
- local t = setups[name]
- if not t then
- return default
- elseif t.auto then
- local lng = tonumber(tex.language)
- local tag = name .. ":" .. lng
- local s = setups[tag]
- if s then
- return s.number or default
- else
- local script, language = languages.association(lng)
- if t.script ~= script or t.language ~= language then
- local s = table.fastcopy(t)
- local n = #numbers + 1
- setups[tag] = s
- numbers[n] = tag
- s.number = n
- s.script = script
- s.language = language
- return n
- else
- setups[tag] = t
- return t.number or default
- end
- end
- else
- return t.number or default
+local function check_otf(specification,suffix,what)
+ local fullname, tfmtable = resolvers.findbinfile(specification.name,suffix) or "", nil
+ if fullname == "" then
+ local fb = fonts.names.old_to_new[specification.name]
+ if fb then
+ fullname = resolvers.findbinfile(fb,suffix) or ""
end
end
-
-end
-
-function fonts.define.specify.context_tostring(name,kind,separator,yes,no,strict,omit) -- not used
- return aux.hash_to_string(table.merged(fonts[kind].features.default or {},fonts.define.specify.context_setups[name] or {}),separator,yes,no,strict,omit)
-end
-
-function fonts.define.specify.split_context(features)
- if fonts.define.specify.context_setups[features] then
- return fonts.define.specify.context_setups[features]
- else -- ? ? ?
- return fonts.define.specify.preset_context("***",features)
+ if fullname == "" then
+ local fb = fonts.names.new_to_old[specification.name]
+ if fb then
+ fullname = resolvers.findbinfile(fb,suffix) or ""
+ end
+ end
+ if fullname ~= "" then
+ specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then
+ tfmtable = tfm.read_from_open_type(specification) -- we need to do it for all matches / todo
end
+ return tfmtable
end
-local splitter = lpeg.splitat(",")
-
-function fonts.define.specify.starred(features) -- no longer fallbacks here
- local detail = features.detail
- if detail and detail ~= "" then
- features.features.normal = fonts.define.specify.split_context(detail)
+function readers.opentype(specification,suffix,what)
+ local forced = specification.forced or ""
+ if forced == "otf" then
+ return check_otf(specification,forced,"opentype")
+ elseif forced == "ttf" then
+ return check_otf(specification,forced,"truetype")
+ elseif forced == "ttf" then
+ return check_otf(specification,forced,"truetype")
else
- features.features.normal = { }
+ return check_otf(specification,suffix,what)
end
- return features
end
-fonts.define.register_split('*',fonts.define.specify.starred)
+function readers.otf(specification) return readers.opentype(specification,"otf","opentype") end
+function readers.ttf(specification) return readers.opentype(specification,"ttf","truetype") end
+function readers.ttc(specification) return readers.opentype(specification,"ttf","truetype") end -- !!
--[[ldx--
<p>We need to check for default features. For this we provide
a helper function.</p>
--ldx]]--
-function fonts.define.check(features,defaults) -- nb adapts features !
+function define.check(features,defaults) -- nb adapts features !
local done = false
if table.is_empty(features) then
features, done = table.fastcopy(defaults), true
else
- for k,v in pairs(defaults) do
+ for k,v in next, defaults do
if features[k] == nil then
features[k], done = v, true
end
@@ -601,43 +452,59 @@ not gain much. By the way, passing id's back to in the callback was
introduced later in the development.</p>
--ldx]]--
-fonts.define.last = nil
+define.last = nil
-function fonts.define.register(fontdata,id)
+function define.register(fontdata,id)
if fontdata and id then
local hash = fontdata.hash
if not tfm.internalized[hash] then
- if fonts.trace then
+ if trace_defining then
logs.report("define font","loading at 2 id %s, hash: %s",id or "?",hash or "?")
end
- tfm.id[id] = fontdata
+ fonts.ids[id] = fontdata
tfm.internalized[hash] = id
end
end
end
-function fonts.define.registered(hash)
+function define.registered(hash)
local id = tfm.internalized[hash]
- return id, id and tfm.id[id]
+ return id, id and fonts.ids[id]
end
local cache_them = false
-function fonts.define.read(specification,size,id) -- id can be optional, name can already be table
- input.starttiming(fonts)
+function tfm.make(specification)
+ -- currently fonts are scaled while constructing the font, so we
+ -- have to do scaling of commands in the vf at that point using
+ -- e.g. "local scale = g.factor or 1" after all, we need to work
+ -- with copies anyway and scaling needs to be done at some point;
+ -- however, when virtual tricks are used as feature (makes more
+ -- sense) we scale the commands in fonts.tfm.scale (and set the
+ -- factor there)
+ local fvm = define.methods[specification.features.vtf.preset]
+ if fvm then
+ return fvm(specification)
+ else
+ return nil
+ end
+end
+
+function define.read(specification,size,id) -- id can be optional, name can already be table
+ statistics.starttiming(fonts)
if type(specification) == "string" then
- specification = fonts.define.analyze(specification,size)
+ specification = define.analyze(specification,size)
end
local method = specification.method
- if method and fonts.define.specify[method] then
- specification = fonts.define.specify[method](specification)
+ if method and define.specify[method] then
+ specification = define.specify[method](specification)
end
- specification = fonts.define.resolve(specification)
+ specification = define.resolve(specification)
local hash = tfm.hash_instance(specification)
if cache_them then
local fontdata = containers.read(fonts.cache(),hash) -- for tracing purposes
end
- local fontdata = fonts.define.registered(hash) -- id
+ local fontdata = define.registered(hash) -- id
if not fontdata then
if specification.features.vtf and specification.features.vtf.preset then
fontdata = tfm.make(specification)
@@ -652,15 +519,16 @@ function fonts.define.read(specification,size,id) -- id can be optional, name ca
end
if fontdata then
fontdata.hash = hash
+ fontdata.cache = "no"
if id then
- fonts.define.register(fontdata,id)
+ define.register(fontdata,id)
end
end
end
- fonts.define.last = fontdata or id -- todo ! ! ! ! !
+ define.last = fontdata or id -- todo ! ! ! ! !
if not fontdata then
logs.report("define font", "unknown font %s, loading aborted",specification.name)
- elseif fonts.trace and type(fontdata) == "table" then
+ elseif trace_defining and type(fontdata) == "table" then
logs.report("define font","using %s font with id %s, n:%s s:%s b:%s e:%s p:%s f:%s",
fontdata.type or "unknown",
id or "?",
@@ -671,148 +539,30 @@ function fonts.define.read(specification,size,id) -- id can be optional, name ca
fontdata.fullname or "?",
file.basename(fontdata.filename or "?"))
end
- input.stoptiming(fonts)
+ statistics.stoptiming(fonts)
return fontdata
end
--- define (two steps)
-
-local P, C, Cc = lpeg.P, lpeg.C, lpeg.Cc
-
-local space = P(" ")
-local spaces = space^0
-local value = C((1-space)^1)
-local rest = C(P(1)^0)
-local scale_none = Cc(0)
-local scale_at = P("at") * Cc(1) * spaces * value
-local scale_sa = P("sa") * Cc(2) * spaces * value
-local scale_mo = P("mo") * Cc(3) * spaces * value
-local scale_scaled = P("scaled") * Cc(4) * spaces * value
-
-local sizepattern = spaces * (scale_at + scale_sa + scale_mo + scale_scaled + scale_none)
-local splitpattern = spaces * value * spaces * rest
-
-local specification --
-
-function fonts.define.command_1(str)
- input.starttiming(fonts)
- local fullname, size = splitpattern:match(str)
- local lookup, name, sub, method, detail = fonts.define.get_specification(fullname)
- if not name then
- logs.report("define font","strange definition '%s'",str)
- texsprint(tex.ctxcatcodes,"\\glet\\somefontname\\defaultfontfile")
- elseif name == "unknown" then
- texsprint(tex.ctxcatcodes,"\\glet\\somefontname\\defaultfontfile")
- else
- texsprint(tex.ctxcatcodes,format("\\xdef\\somefontname{%s}",name))
- end
- -- we can also use a count for the size
- if size and size ~= "" then
- local mode, size = sizepattern:match(size)
- if size and mode then
- count.scaledfontmode = mode
- texsprint(tex.ctxcatcodes,format("\\def\\somefontsize{%s}",size))
- else
- count.scaledfontmode = 0
- texsprint(tex.ctxcatcodes,format("\\let\\somefontsize\\empty",size))
- end
- else
- count.scaledfontmode = 0
- texsprint(tex.ctxcatcodes,format("\\let\\somefontsize\\empty",size))
- end
- specification = fonts.define.makespecification(str,lookup,name,sub,method,detail,size)
-end
-
-function fonts.define.command_2(global,cs,name,size,classfeatures,fontfeatures,classfallbacks,fontfallbacks)
- local trace = fonts.trace
- -- name is now resolved and size is scaled cf sa/mo
- local lookup, name, sub, method, detail = fonts.define.get_specification(name or "")
- -- asome settings can be overloaded
- if lookup and lookup ~= "" then specification.lookup = lookup end
- specification.name = name
- specification.size = size
- specification.sub = sub
- if detail and detail ~= "" then
- specification.method, specification.detail = method or "*", detail
- elseif specification.detail and specification.detail ~= "" then
- -- already set
- elseif fontfeatures and fontfeatures ~= "" then
- specification.method, specification.detail = "*", fontfeatures
- elseif classfeatures and classfeatures ~= "" then
- specification.method, specification.detail = "*", classfeatures
- end
- if trace then
- logs.report("define font","memory usage before: %s",ctx.memused())
- end
-if fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
-elseif classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
-end
- local tfmdata = fonts.define.read(specification,size) -- id not yet known
- if not tfmdata then
- logs.report("define font","unable to define %s as \\%s",name,cs)
- elseif type(tfmdata) == "number" then
- if trace then
- logs.report("define font","reusing %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s)",name,tfmdata,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks)
- end
- tex.definefont(global,cs,tfmdata)
- -- resolved (when designsize is used):
- texsprint(tex.ctxcatcodes,format("\\def\\somefontsize{%isp}",tfm.id[tfmdata].size))
- else
- -- local t = os.clock(t)
- local id = font.define(tfmdata)
- -- print(name,os.clock()-t)
- tfmdata.id = id
- fonts.define.register(tfmdata,id)
- tex.definefont(global,cs,id)
- tfm.cleanup_table(tfmdata)
- if fonts.trace then
- logs.report("define font","defining %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s)",name,id,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks)
- end
- -- resolved (when designsize is used):
- texsprint(tex.ctxcatcodes,format("\\def\\somefontsize{%isp}",tfmdata.size))
- --~ if specification.fallbacks then
- --~ fonts.collections.prepare(specification.fallbacks)
- --~ end
- end
- if trace then
- logs.report("define font","memory usage after: %s",ctx.memused())
- end
- input.stoptiming(fonts)
-end
-
-
---~ table.insert(tfm.readers.sequence,1,'vtf')
-
---~ function tfm.readers.vtf(specification)
---~ if specification.features.vtf and specification.features.vtf.preset then
---~ return tfm.make(specification)
---~ else
---~ return nil
---~ end
---~ end
-
-function fonts.vf.find(name)
+function vf.find(name)
name = file.removesuffix(file.basename(name))
if tfm.resolve_vf then
local format = fonts.logger.format(name)
if format == 'tfm' or format == 'ofm' then
- if fonts.trace then
+ if trace_defining then
logs.report("define font","locating vf for %s",name)
end
- return input.findbinfile(name,"ovf")
+ return resolvers.findbinfile(name,"ovf")
else
- if fonts.trace then
+ if trace_defining then
logs.report("define font","vf for %s is already taken care of",name)
end
return nil -- ""
end
else
- if fonts.trace then
+ if trace_defining then
logs.report("define font","locating vf for %s",name)
end
- return input.findbinfile(name,"ovf")
+ return resolvers.findbinfile(name,"ovf")
end
end
@@ -820,5 +570,5 @@ end
<p>We overload both the <l n='tfm'/> and <l n='vf'/> readers.</p>
--ldx]]--
-callback.register('define_font' , fonts.define.read)
-callback.register('find_vf_file', fonts.vf.find ) -- not that relevant any more
+callback.register('define_font' , define.read)
+callback.register('find_vf_file', vf.find ) -- not that relevant any more
diff --git a/tex/context/base/font-dum.lua b/tex/context/base/font-dum.lua
new file mode 100644
index 000000000..0d28128d8
--- /dev/null
+++ b/tex/context/base/font-dum.lua
@@ -0,0 +1,113 @@
+if not modules then modules = { } end modules ['font-dum'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+fonts = fonts or { }
+
+-- general
+
+fonts.otf.pack = false
+fonts.tfm.resolve_vf = false -- no sure about this
+
+-- readers
+
+fonts.tfm.readers = fonts.tfm.readers or { }
+fonts.tfm.readers.sequence = { 'otf', 'ttf', 'tfm' }
+fonts.tfm.readers.afm = nil
+
+-- define
+
+fonts.define = fonts.define or { }
+
+--~ fonts.define.method = "tfm"
+
+fonts.define.specify.colonized_default_lookup = "name"
+
+function fonts.define.get_specification(str)
+ return "", str, "", ":", str
+end
+
+-- logger
+
+fonts.logger = fonts.logger or { }
+
+function fonts.logger.save()
+end
+
+-- names
+
+fonts.names = fonts.names or { }
+
+fonts.names.basename = "luatex-fonts-names.lua"
+fonts.names.new_to_old = { }
+fonts.names.old_to_new = { }
+
+local data, loaded = nil, false
+
+function fonts.names.resolve(name,sub)
+ if not loaded then
+ local basename = fonts.names.basename
+ if basename and basename ~= "" then
+ for _, format in ipairs { "lua", "tex", "other text files" } do
+ local foundname = resolvers.find_file(basename,format) or ""
+ if foundname ~= "" then
+ data = dofile(foundname)
+ if data then
+ local d = { }
+ for k, v in pairs(data.mapping) do
+ local t = v[1]
+ if t == "ttf" or t == "otf" or t == "ttc" then
+ d[k] = v
+ end
+ end
+ data.mapping = d
+ end
+ break
+ end
+ end
+ end
+ loaded = true
+ end
+ if type(data) == "table" and data.version == 1.08 then
+ local condensed = string.gsub(name,"[^%a%d]","")
+ local found = data.mapping and data.mapping[condensed]
+ if found then
+ local filename, is_sub = found[3], found[4]
+ if is_sub then is_sub = found[2] end
+ return filename, is_sub
+ else
+ return name, false -- fallback to filename
+ end
+ end
+end
+
+-- For the moment we put this (adapted) pseudo feature here.
+
+table.insert(fonts.triggers,"itlc")
+
+local function itlc(tfmdata,value)
+ if value then
+ -- the magic 40 and it formula come from Dohyun Kim
+ local metadata = tfmdata.shared.otfdata.metadata
+ if metadata then
+ local italicangle = metadata.italicangle
+ if italicangle and italicangle ~= 0 then
+ local uwidth = (metadata.uwidth or 40)/2
+ for unicode, d in next, tfmdata.descriptions do
+ local it = d.boundingbox[3] - d.width + uwidth
+ if it ~= 0 then
+ d.italic = it
+ end
+ end
+ tfmdata.has_italic = true
+ end
+ end
+ end
+end
+
+fonts.initializers.base.otf.itlc = itlc
+fonts.initializers.node.otf.itlc = itlc
diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua
index 86ace93c6..faeae3a10 100644
--- a/tex/context/base/font-enc.lua
+++ b/tex/context/base/font-enc.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['font-enc'] = {
license = "see context related readme files"
}
+local match, gmatch, gsub = string.match, string.gmatch, string.gsub
+
--[[ldx--
<p>Because encodings are going to disappear, we don't bother defining
them in tables. But we may do so some day, for consistency.</p>
@@ -62,15 +64,15 @@ function fonts.enc.load(filename)
return data
end
local vector, tag, hash, unicodes = { }, "", { }, { }
- local foundname = input.find_file(filename,'enc')
+ local foundname = resolvers.find_file(filename,'enc')
if foundname and foundname ~= "" then
- local ok, encoding, size = input.loadbinfile(foundname)
+ local ok, encoding, size = resolvers.loadbinfile(foundname)
if ok and encoding then
local enccodes = characters.enccodes
- encoding = encoding:gsub("%%(.-)\n","")
- local tag, vec = encoding:match("/(%w+)%s*%[(.*)%]%s*def")
+ encoding = gsub(encoding,"%%(.-)\n","")
+ local tag, vec = match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
local i = 0
- for ch in vec:gmatch("/([%a%d%.]+)") do
+ for ch in gmatch(vec,"/([%a%d%.]+)") do
if ch ~= ".notdef" then
vector[i] = ch
if not hash[ch] then
@@ -105,7 +107,7 @@ one.</p>
function fonts.enc.make_unicode_vector()
local vector, hash = { }, { }
- for code, v in pairs(characters.data) do
+ for code, v in next, characters.data do
local name = v.adobename
if name then
vector[code], hash[name] = name, code
@@ -113,7 +115,7 @@ function fonts.enc.make_unicode_vector()
vector[code] = '.notdef'
end
end
- for name, code in pairs(characters.synonyms) do
+ for name, code in next, characters.synonyms do
vector[code], hash[name] = name, code
end
return containers.write(fonts.enc.cache(), 'unicode', { name='unicode', tag='unicode', vector=vector, hash=hash })
diff --git a/tex/context/base/font-ext.lua b/tex/context/base/font-ext.lua
index c3979fad6..17c302c53 100644
--- a/tex/context/base/font-ext.lua
+++ b/tex/context/base/font-ext.lua
@@ -6,7 +6,191 @@ if not modules then modules = { } end modules ['font-ext'] = {
license = "see context related readme files"
}
-local byte = string.byte
+local next, type, byte = next, type, string.byte
+
+--[[ldx--
+<p>When we implement functions that deal with features, most of them
+will depend of the font format. Here we define the few that are kind
+of neutral.</p>
+--ldx]]--
+
+fonts.triggers = fonts.triggers or { }
+fonts.initializers = fonts.initializers or { }
+fonts.initializers.common = fonts.initializers.common or { }
+
+local initializers = fonts.initializers
+
+--[[ldx--
+<p>This feature will remove inter-digit kerns.</p>
+--ldx]]--
+
+table.insert(fonts.triggers,"equaldigits")
+
+function initializers.common.equaldigits(tfmdata,value)
+ if value then
+ local chr = tfmdata.characters
+ for i = utfbyte('0'), utfbyte('9') do
+ local c = chr[i]
+ if c then
+ c.kerns = nil
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>This feature will give all glyphs an equal height and/or depth. Valid
+values are <type>none</type>, <type>height</type>, <type>depth</type> and
+<type>both</type>.</p>
+--ldx]]--
+
+table.insert(fonts.triggers,"lineheight")
+
+function initializers.common.lineheight(tfmdata,value)
+ if value and type(value) == "string" then
+ if value == "none" then
+ for _,v in next, tfmdata.characters do
+ v.height, v.depth = 0, 0
+ end
+ else
+ local ascender, descender = tfmdata.ascender, tfmdata.descender
+ if ascender and descender then
+ local ht, dp = ascender or 0, descender or 0
+ if value == "height" then
+ dp = 0
+ elseif value == "depth" then
+ ht = 0
+ end
+ if ht > 0 then
+ if dp > 0 then
+ for _,v in next, tfmdata.characters do
+ v.height, v.depth = ht, dp
+ end
+ else
+ for _,v in next, tfmdata.characters do
+ v.height = ht
+ end
+ end
+ elseif dp > 0 then
+ for _,v in next, tfmdata.characters do
+ v.depth = dp
+ end
+ end
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>It does not make sense any more to support messed up encoding vectors
+so we stick to those that implement oldstyle and small caps. After all,
+we move on. We can extend the next function on demand. This features is
+only used with <l n='afm'/> files.</p>
+--ldx]]--
+
+--~ do
+--~
+--~ local smallcaps = lpeg.P(".sc") + lpeg.P(".smallcaps") + lpeg.P(".caps") + lpeg.P("small")
+--~ local oldstyle = lpeg.P(".os") + lpeg.P(".oldstyle") + lpeg.P(".onum")
+--~
+--~ smallcaps = lpeg.Cs((1-smallcaps)^1) * smallcaps^1
+--~ oldstyle = lpeg.Cs((1-oldstyle )^1) * oldstyle ^1
+--~
+--~ function initializers.common.encoding(tfmdata,value)
+--~ if value then
+--~ local afmdata = tfmdata.shared.afmdata
+--~ if afmdata then
+--~ local encodingfile = value .. '.enc'
+--~ local encoding = fonts.enc.load(encodingfile)
+--~ if encoding then
+--~ local vector = encoding.vector
+--~ local characters = tfmdata.characters
+--~ local unicodes = afmdata.luatex.unicodes
+--~ local function remap(pattern,name)
+--~ local p = pattern:match(name)
+--~ if p then
+--~ local oldchr, newchr = unicodes[p], unicodes[name]
+--~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+--~ -- logs.report("encoding","%s (%s) -> %s (%s)",p,oldchr or -1,name,newchr or -1)
+--~ characters[oldchr] = characters[newchr]
+--~ end
+--~ end
+--~ return p
+--~ end
+--~ for _, name in next, vector do
+--~ local ok = remap(smallcaps,name) or remap(oldstyle,name)
+--~ end
+--~ if fonts.map.data[tfmdata.name] then
+--~ fonts.map.data[tfmdata.name].encoding = encodingfile
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ -- when needed we can provide this as features in e.g. afm files
+--~
+--~ function initializers.common.remap(tfmdata,value,pattern) -- will go away
+--~ if value then
+--~ local afmdata = tfmdata.shared.afmdata
+--~ if afmdata then
+--~ local characters = tfmdata.characters
+--~ local descriptions = tfmdata.descriptions
+--~ local unicodes = afmdata.luatex.unicodes
+--~ local done = false
+--~ for u, _ in next, characters do
+--~ local name = descriptions[u].name
+--~ if name then
+--~ local p = pattern:match(name)
+--~ if p then
+--~ local oldchr, newchr = unicodes[p], unicodes[name]
+--~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+--~ characters[oldchr] = characters[newchr]
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ function initializers.common.oldstyle(tfmdata,value)
+--~ initializers.common.remap(tfmdata,value,oldstyle)
+--~ end
+--~ function initializers.common.smallcaps(tfmdata,value)
+--~ initializers.common.remap(tfmdata,value,smallcaps)
+--~ end
+--~
+--~ function initializers.common.fakecaps(tfmdata,value)
+--~ if value then
+--~ -- todo: scale down
+--~ local afmdata = tfmdata.shared.afmdata
+--~ if afmdata then
+--~ local characters = tfmdata.characters
+--~ local descriptions = tfmdata.descriptions
+--~ local unicodes = afmdata.luatex.unicodes
+--~ for u, _ in next, characters do
+--~ local name = descriptions[u].name
+--~ if name then
+--~ local p = lower(name)
+--~ if p then
+--~ local oldchr, newchr = unicodes[p], unicodes[name]
+--~ if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
+--~ characters[oldchr] = characters[newchr]
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~
+--~ end
+--~
+--~ function initializers.common.install(format,feature) -- 'afm','lineheight'
+--~ initializers.base[format][feature] = initializers.common[feature]
+--~ initializers.node[format][feature] = initializers.common[feature]
+--~ end
-- -- -- -- -- --
-- expansion (hz)
@@ -16,19 +200,23 @@ fonts.expansions = fonts.expansions or { }
fonts.expansions.classes = fonts.expansions.classes or { }
fonts.expansions.vectors = fonts.expansions.vectors or { }
+local expansions = fonts.expansions
+local classes = fonts.expansions.classes
+local vectors = fonts.expansions.vectors
+
-- beware, pdftex itself uses percentages * 10
-fonts.expansions.classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 }
+classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 }
function commands.setupfontexpansion(class,settings)
- aux.getparameters(fonts.expansions.classes,class,'preset',settings)
+ aux.getparameters(classes,class,'preset',settings)
end
-fonts.expansions.classes['quality'] = {
+classes['quality'] = {
stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1
}
-fonts.expansions.vectors['default'] = {
+vectors['default'] = {
[byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7,
[byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7,
[byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7,
@@ -40,11 +228,11 @@ fonts.expansions.vectors['default'] = {
[byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7,
}
-function fonts.initializers.common.expansion(tfmdata,value)
+function initializers.common.expansion(tfmdata,value)
if value then
- local class = fonts.expansions.classes[value]
+ local class = classes[value]
if class then
- local vector = fonts.expansions.vectors[class.vector]
+ local vector = vectors[class.vector]
if vector then
tfmdata.stretch = (class.stretch or 0) * 10
tfmdata.shrink = (class.shrink or 0) * 10
@@ -52,7 +240,7 @@ function fonts.initializers.common.expansion(tfmdata,value)
tfmdata.auto_expand = true
local factor = class.factor or 1
local data = characters.data
- for i, chr in pairs(tfmdata.characters) do
+ for i, chr in next, tfmdata.characters do
local v = vector[i]
if not v then
local d = data[i]
@@ -80,11 +268,11 @@ end
table.insert(fonts.manipulators,"expansion")
-fonts.initializers.base.otf.expansion = fonts.initializers.common.expansion
-fonts.initializers.node.otf.expansion = fonts.initializers.common.expansion
+initializers.base.otf.expansion = initializers.common.expansion
+initializers.node.otf.expansion = initializers.common.expansion
-fonts.initializers.base.afm.expansion = fonts.initializers.common.expansion
-fonts.initializers.node.afm.expansion = fonts.initializers.common.expansion
+initializers.base.afm.expansion = initializers.common.expansion
+initializers.node.afm.expansion = initializers.common.expansion
-- -- -- -- -- --
-- protrusion
@@ -94,28 +282,32 @@ fonts.protrusions = fonts.protrusions or { }
fonts.protrusions.classes = fonts.protrusions.classes or { }
fonts.protrusions.vectors = fonts.protrusions.vectors or { }
+local protrusions = fonts.protrusions
+local classes = fonts.protrusions.classes
+local vectors = fonts.protrusions.vectors
+
-- the values need to be revisioned
-fonts.protrusions.classes.preset = { factor = 1 }
+classes.preset = { factor = 1 }
function commands.setupfontprotrusion(class,settings)
- aux.getparameters(fonts.protrusions.classes,class,'preset',settings)
+ aux.getparameters(classes,class,'preset',settings)
end
-fonts.protrusions.classes['pure'] = {
+classes['pure'] = {
vector = 'pure', factor = 1
}
-fonts.protrusions.classes['punctuation'] = {
+classes['punctuation'] = {
vector = 'punctuation', factor = 1
}
-fonts.protrusions.classes['alpha'] = {
+classes['alpha'] = {
vector = 'alpha', factor = 1
}
-fonts.protrusions.classes['quality'] = {
+classes['quality'] = {
vector = 'quality', factor = 1
}
-fonts.protrusions.vectors['pure'] = {
+vectors['pure'] = {
[0x002C] = { 0, 1 }, -- comma
[0x002E] = { 0, 1 }, -- period
@@ -126,10 +318,13 @@ fonts.protrusions.vectors['pure'] = {
[0x2014] = { 0, 0.33 }, -- emdash
[0x3001] = { 0, 1 }, -- ideographic comma 、
[0x3002] = { 0, 1 }, -- ideographic full stop 。
+ [0x060C] = { 0, 1 }, -- arabic comma ،
+ [0x061B] = { 0, 1 }, -- arabic semicolon ؛
+ [0x06D4] = { 0, 1 }, -- arabic full stop ۔
}
-fonts.protrusions.vectors['punctuation'] = {
+vectors['punctuation'] = {
[0x003F] = { 0, 0.20 }, -- ?
[0x00BF] = { 0, 0.20 }, -- ¿
@@ -146,6 +341,10 @@ fonts.protrusions.vectors['punctuation'] = {
[0x002D] = { 0, 0.70 }, -- hyphen
[0x2013] = { 0, 0.30 }, -- endash
[0x2014] = { 0, 0.20 }, -- emdash
+ [0x060C] = { 0, 0.70 }, -- arabic comma
+ [0x061B] = { 0, 0.50 }, -- arabic semicolon
+ [0x06D4] = { 0, 0.70 }, -- arabic full stop
+ [0x061F] = { 0, 0.20 }, -- ؟
-- todo: left and right quotes: .5 double, .7 single
@@ -165,7 +364,7 @@ fonts.protrusions.vectors['punctuation'] = {
}
-fonts.protrusions.vectors['alpha'] = {
+vectors['alpha'] = {
[byte("A")] = { .05, .05 },
[byte("F")] = { 0, .05 },
@@ -188,21 +387,22 @@ fonts.protrusions.vectors['alpha'] = {
}
-fonts.protrusions.vectors['quality'] = table.merge( {},
- fonts.protrusions.vectors['punctuation'],
- fonts.protrusions.vectors['alpha']
+vectors['quality'] = table.merge( {},
+ vectors['punctuation'],
+ vectors['alpha']
)
-function fonts.initializers.common.protrusion(tfmdata,value)
+function initializers.common.protrusion(tfmdata,value)
if value then
- local class = fonts.protrusions.classes[value]
+ local class = classes[value]
if class then
- local vector = fonts.protrusions.vectors[class.vector]
+ local vector = vectors[class.vector]
if vector then
local factor = class.factor or 1
local data = characters.data
local emwidth = tfmdata.parameters.quad
- for i, chr in pairs(tfmdata.characters) do
+ tfmdata.auto_protrude = true
+ for i, chr in next, tfmdata.characters do
local v, pl, pr = vector[i], nil, nil
if v then
pl, pr = v[1], v[2]
@@ -234,8 +434,46 @@ end
table.insert(fonts.manipulators,"protrusion")
-fonts.initializers.base.otf.protrusion = fonts.initializers.common.protrusion
-fonts.initializers.node.otf.protrusion = fonts.initializers.common.protrusion
+initializers.base.otf.protrusion = initializers.common.protrusion
+initializers.node.otf.protrusion = initializers.common.protrusion
+
+initializers.base.afm.protrusion = initializers.common.protrusion
+initializers.node.afm.protrusion = initializers.common.protrusion
+
+function initializers.common.nostackmath(tfmdata,value)
+ tfmdata.ignore_stack_math = value
+end
+
+table.insert(fonts.manipulators,"nostackmath")
+
+initializers.base.otf.nostackmath = initializers.common.nostackmath
+initializers.node.otf.nostackmath = initializers.common.nostackmath
+
+table.insert(fonts.triggers,"itlc")
+
+function initializers.common.itlc(tfmdata,value)
+ if value then
+ -- the magic 40 and it formula come from Dohyun Kim
+ local fontdata = tfmdata.shared.otfdata or tfmdata.shared.afmdata
+ local metadata = fontdata and fontdata.metadata
+ if metadata then
+ local italicangle = metadata.italicangle
+ if italicangle and italicangle ~= 0 then
+ local uwidth = (metadata.uwidth or 40)/2
+ for unicode, d in next, tfmdata.descriptions do
+ local it = d.boundingbox[3] - d.width + uwidth
+ if it ~= 0 then
+ d.italic = it
+ end
+ end
+ tfmdata.has_italic = true
+ end
+ end
+ end
+end
+
+initializers.base.otf.itlc = initializers.common.itlc
+initializers.node.otf.itlc = initializers.common.itlc
-fonts.initializers.base.afm.protrusion = fonts.initializers.common.protrusion
-fonts.initializers.node.afm.protrusion = fonts.initializers.common.protrusion
+initializers.base.afm.itlc = initializers.common.itlc
+initializers.node.afm.itlc = initializers.common.itlc
diff --git a/tex/context/base/font-fbk.lua b/tex/context/base/font-fbk.lua
index d3287c393..6c4f78a3c 100644
--- a/tex/context/base/font-fbk.lua
+++ b/tex/context/base/font-fbk.lua
@@ -6,34 +6,37 @@ if not modules then modules = { } end modules ['font-fbk'] = {
license = "see context related readme files"
}
+local cos, tan, rad, format = math.cos, math.tan, math.rad, string.format
+
+local trace_combining = false trackers.register("fonts.combining", function(v) trace_combining = v end)
+
--[[ldx--
<p>This is very experimental code!</p>
--ldx]]--
-fonts.fallbacks = fonts.fallbacks or { }
-fonts.vf.aux.combine.trace = false
+fonts.fallbacks = fonts.fallbacks or { }
local vf = fonts.vf
local tfm = fonts.tfm
vf.aux.combine.commands["enable-tracing"] = function(g,v)
- vf.aux.combine.trace = true
+ trace_combining = true
end
vf.aux.combine.commands["disable-tracing"] = function(g,v)
- vf.aux.combine.trace = false
+ trace_combining = false
end
vf.aux.combine.commands["set-tracing"] = function(g,v)
if v[2] == nil then
- vf.aux.combine.trace = true
+ trace_combining = true
else
- vf.aux.combine.trace = v[2]
+ trace_combining = v[2]
end
end
function vf.aux.combine.initialize_trace()
- if vf.aux.combine.trace then
+ if trace_combining then
return "special", "pdf: .8 0 0 rg .8 0 0 RG", "pdf: 0 .8 0 rg 0 .8 0 RG", "pdf: 0 0 .8 rg 0 0 .8 RG", "pdf: 0 g 0 G"
else
return "comment", "", "", "", ""
@@ -54,7 +57,7 @@ end
fonts.fallbacks['textcent'] = function (g)
local c = ("c"):byte()
local t = table.fastcopy(g.characters[c])
- local a = - math.tan(math.rad(g.italicangle or 0))
+ local a = - tan(rad(g.italicangle or 0))
local special, red, green, blue, black = vf.aux.combine.initialize_trace()
local quad = g.parameters.quad
if a == 0 then
@@ -71,7 +74,7 @@ fonts.fallbacks['textcent'] = function (g)
{"push"},
{"right", .5*t.width-.025*quad},
{"down", .2*t.height},
- {"special",("pdf: q 1 0 %s 1 0 0 cm"):format(a)},
+ {"special",format("pdf: q 1 0 %s 1 0 0 cm",a)},
{special, green},
{"rule", 1.4*t.height, .025*quad},
{special, black},
@@ -84,6 +87,7 @@ fonts.fallbacks['textcent'] = function (g)
-- todo: set height
t.height = 1.2*t.height
t.depth = 0.2*t.height
+ g.virtualized = true
local d = g.descriptions
return t, d and d[c]
end
@@ -91,7 +95,7 @@ end
fonts.fallbacks['texteuro'] = function (g)
local c = ("C"):byte()
local t = table.fastcopy(g.characters[c])
- local d = math.cos(math.rad(90+(g.italicangle)))
+ local d = cos(rad(90+(g.italicangle)))
local special, red, green, blue, black = vf.aux.combine.initialize_trace()
local quad = g.parameters.quad
t.width = 1.05*t.width
@@ -104,6 +108,7 @@ fonts.fallbacks['texteuro'] = function (g)
{"rule", .05*quad, .4*quad},
{special, black},
}
+ g.virtualized = true
return t, g.descriptions[c]
end
@@ -111,6 +116,10 @@ end
vf.aux.combine.force_composed = false
+local push, pop = { "push" }, { "pop" }
+
+local cache = { } -- we could make these weak
+
function vf.aux.compose_characters(g) -- todo: scaling depends on call location
-- this assumes that slot 1 is self, there will be a proper self some day
local chars, descs = g.characters, g.descriptions
@@ -120,14 +129,16 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location
if xchar and xdesc then
local scale = g.factor or 1
local cap_lly = scale*xdesc.boundingbox[4]
- local ita_cor = math.cos(math.rad(90+(g.italicangle or 0)))
+ local ita_cor = cos(rad(90+(g.italicangle or 0)))
local force = vf.aux.combine.force_composed
local fallbacks = characters.fallbacks
- local special, red, green, blue, black = vf.aux.combine.initialize_trace()
- red, green, blue, black = { special, red }, { special, green }, { special, blue }, { special, black }
- local push, pop = { "push" }, { "pop" }
- local trace = vf.aux.combine.trace -- saves mem
- for i,c in pairs(characters.data) do
+ local special, red, green, blue, black
+ if trace_combining then
+ special, red, green, blue, black = vf.aux.combine.initialize_trace()
+ red, green, blue, black = { special, red }, { special, green }, { special, blue }, { special, black }
+ end
+ local done = false
+ for i,c in next, characters.data do
if force or not chars[i] then
local s = c.specials
if s and s[1] == 'char' then
@@ -138,17 +149,35 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location
if cc == 'll' or cc == 'lu' or cc == 'lt' then
local acc = s[3]
local t = { }
- for k, v in pairs(charschr) do
+ for k, v in next, charschr do
if k ~= "commands" then
t[k] = v
end
end
local charsacc = chars[acc]
+--~ local ca = charsacc.category
+--~ if ca == "mn" then
+--~ -- mark nonspacing
+--~ elseif ca == "ms" then
+--~ -- mark spacing combining
+--~ elseif ca == "me" then
+--~ -- mark enclosing
+--~ else
if not charsacc then
acc = fallbacks[acc]
charsacc = acc and chars[acc]
end
if charsacc then
+ local chr_t = cache[chr]
+ if not cht_t then
+ chr_t = {"slot", 1, chr}
+ cache[chr] = chr_t
+ end
+ local acc_t = cache[acc]
+ if not acc_t then
+ acc_t = {"slot", 1, acc}
+ cache[acc] = acc_t
+ end
local cb = descs[chr].boundingbox
local ab = descs[acc].boundingbox
if cb and ab then
@@ -158,77 +187,75 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location
local dx = (c_urx - a_urx - a_llx + c_llx)/2
local dd = (c_urx - c_llx)*ita_cor
if a_ury < 0 then
- -- local dy = cap_lly-a_lly
- if trace then
+ if trace_combining then
t.commands = {
push,
{"right", dx-dd},
- -- {"down", -dy}, -- added
red,
- {"slot", 1, acc},
+ acc_t,
black,
pop,
- {"slot", 1, chr},
+ chr_t,
}
else
t.commands = {
push,
{"right", dx-dd},
- -- {"down", -dy}, -- added
- {"slot", 1, acc},
+ acc_t,
pop,
- {"slot", 1, chr},
+ chr_t,
}
end
elseif c_ury > a_lly then
local dy = cap_lly-a_lly
- if trace then
+ if trace_combining then
t.commands = {
push,
{"right", dx+dd},
{"down", -dy},
green,
- {"slot", 1, acc},
+ acc_t,
black,
pop,
- {"slot", 1, chr},
+ chr_t,
}
else
t.commands = {
push,
{"right", dx+dd},
{"down", -dy},
- {"slot", 1, acc},
+ acc_t,
pop,
- {"slot", 1, chr},
+ chr_t,
}
end
else
- if trace then
+ if trace_combining then
t.commands = {
{"push"},
{"right", dx+dd},
blue,
- {"slot", 1, acc},
+ acc_t,
black,
{"pop"},
- {"slot", 1, chr},
+ chr_t,
}
else
t.commands = {
{"push"},
{"right", dx+dd},
- {"slot", 1, acc},
+ acc_t,
{"pop"},
- {"slot", 1, chr},
+ chr_t,
}
end
end
+ done = true
end
end
chars[i] = t
local d = { }
- for k, v in pairs(descs[chr]) do
+ for k, v in next, descs[chr] do
d[k] = v
end
d.name = c.adobename or "unknown"
@@ -239,6 +266,9 @@ function vf.aux.compose_characters(g) -- todo: scaling depends on call location
end
end
end
+ if done then
+ g.virtualized = true
+ end
end
end
diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua
index 5db2973a1..248a2baca 100644
--- a/tex/context/base/font-ini.lua
+++ b/tex/context/base/font-ini.lua
@@ -10,34 +10,44 @@ if not modules then modules = { } end modules ['font-ini'] = {
<p>Not much is happening here.</p>
--ldx]]--
+local utf = unicode.utf8
+
+if not fontloader then fontloader = fontforge end
+
+fontloader.totable = fontloader.to_table
+
-- vtf comes first
-- fix comes last
-fonts = fonts or { }
+fonts = fonts or { }
+fonts.ids = fonts.ids or { } -- aka fontdata
+fonts.tfm = fonts.tfm or { }
-fonts.trace = false -- true
fonts.mode = 'base'
-fonts.private = 0xE000
+fonts.private = 0xF0000 -- 0x10FFFF
fonts.verbose = false -- more verbose cache tables
-fonts.methods = {
+fonts.methods = fonts.methods or {
base = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
node = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
}
-fonts.initializers = {
+fonts.initializers = fonts.initializers or {
base = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
node = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } }
}
-fonts.triggers = {
+fonts.triggers = fonts.triggers or {
'mode',
'language',
'script',
'strategy',
}
-fonts.manipulators = {
+fonts.processors = fonts.processors or {
+}
+
+fonts.manipulators = fonts.manipulators or {
}
fonts.define = fonts.define or { }
@@ -48,18 +58,35 @@ fonts.define.specify.synonyms = fonts.define.specify.synonyms or { }
fonts.color = fonts.color or { }
-fonts.color.trace = false
-
-local attribute = attributes.numbers['color'] or 7 -- we happen to know this -)
-local mapping = attributes.list[attribute]
+local attribute = attributes.private('color')
+local mapping = (attributes and attributes.list[attribute]) or { }
local set_attribute = node.set_attribute
local unset_attribute = node.unset_attribute
function fonts.color.set(n,c)
--- local mc = mapping[c] if mc then unset_attribute((n,attribute) else set_attribute(n,attribute,mc) end
- set_attribute(n,attribute,mapping[c] or -1) -- also handles -1 now
+ local mc = mapping[c]
+ if not mc then
+ unset_attribute(n,attribute)
+ else
+ set_attribute(n,attribute,mc)
+ end
end
function fonts.color.reset(n)
unset_attribute(n,attribute)
end
+
+-- this will change ...
+
+function fonts.show_char_data(n)
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata then
+ if type(n) == "string" then
+ n = utf.byte(n)
+ end
+ local chr = tfmdata.characters[n]
+ if chr then
+ texio.write_nl(table.serialize(chr,string.format("U_%04X",n)))
+ end
+ end
+end
diff --git a/tex/context/base/font-ini.mkii b/tex/context/base/font-ini.mkii
index 9b9f5ac83..658d06f70 100644
--- a/tex/context/base/font-ini.mkii
+++ b/tex/context/base/font-ini.mkii
@@ -12,7 +12,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Font Macros (ini)}
+\writestatus{loading}{ConTeXt Font Macros / Initialization}
\unprotect
@@ -121,125 +121,21 @@
%%% message 14 added
-\startmessages dutch library: fonts
- title: korps
- 1: codering --
- 2: variant -- wordt geladen
- 3: onbekende variant --
- 4: korps -- is niet gedefinieerd
- 5: stijl -- is niet gedefinieerd
- 6: -- wordt geladen
- 7: onbekend formaat --
- 8: stijl -- gedefinieerd
-% 9: mapping -- is geladen
- 10: onbekende font file --
- 14: korps -- is gedefinieerd (kan beter globaal plaatsvinden)
-\stopmessages
-
-\startmessages english library: fonts
- title: bodyfont
- 1: coding --
- 2: variant -- is loaded
- 3: unknown variant --
- 4: bodyfont -- is not defined
- 5: style -- is not defined
- 6: -- is loaded
- 7: unknown format --
- 8: style -- defined
-% 9: mapping -- is loaded
- 10: unknown font file --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages german library: fonts
- title: Fliesstext
- 1: Kodierung --
- 2: Variante -- ist geladen
- 3: Unbekannte Variante --
- 4: Fliesstext -- ist nicht definiert
- 5: Stil -- ist nicht definiert
- 6: -- ist geladen
- 7: unbekanntes Format --
- 8: Stil -- definiert
-% 9: Map -- ist geladen
- 10: unbekanntes Font --
- 14: Fliesstext -- wurde definiert (besser waere globale Definition)
-\stopmessages
-
-\startmessages czech library: fonts
- title: zakladnifont
- 1: kodovani --
- 2: varianta -- je nactena
- 3: neznama varianta --
- 4: zakladni font -- neni definovan
- 5: styl -- neni definovan
- 6: -- je nacten
- 7: neznamy format --
- 8: styl -- definovan
-% 9: mapovani -- je nacteno
- 10: neznamy font --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages italian library: fonts
- title: font del corpo
- 1: codifica --
- 2: variante -- caricata
- 3: variante sconosciuta --
- 4: corpo del testo -- non definito
- 5: stile -- non definito
- 6: -- caricato
- 7: formato sconosciuto --
- 8: stile -- definito
-% 9: mappatura -- caricata
- 10: file di font sconosciuto --
- 14: corpo del testo -- definito (sarebbe meglio globale)
-\stopmessages
-
-\startmessages norwegian library: fonts
- title: hovedfont
- 1: koding --
- 2: variant -- er lest inn
- 3: ukjent variant --
- 4: hovedfont -- er ikke definert
- 5: stil -- er ikke definert
- 6: -- er lest inn
- 7: ukjent format --
- 8: stil -- definert
-% 9: avbildning -- er lest inn
- 10: ukjent fontfil --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages romanian library: fonts
- title: corp de litere
- 1: codificarea --
- 2: varianta -- este incarcata
- 3: varianta necunoscuta --
- 4: corpul de litere -- nu este definit
- 5: stilul -- nu este definit
- 6: -- este incarcat
- 7: format necunoscut --
- 8: stilul -- definit
-% 9: maparea -- este incarcat
- 10: fisier font necunoscut --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages french library: fonts
- title: corps de texte
- 1: encodage --
- 2: la variante -- est chargée
- 3: variante -- inconnue
- 4: policecorps -- n'est pas définie
- 5: le style -- n'est pas défini
- 6: -- est chargé
- 7: format -- inconnu
- 8: style -- défini
-% 9: mapping -- is loaded
- 10: fichier de police -- inconnu
- 14: policecorps -- est défini (une définition globale pourrait être plus adéquat)
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
%D This module is one of the oldest modules of \CONTEXT. The
%D macros below evolved out of the \PLAIN\ \TEX\ macros and
@@ -682,8 +578,6 @@
%D
%D We can fix this by defining
-\let\normalmathop\mathop
-
\unexpanded\def\mathop
{\normalmathop
\bgroup
@@ -694,8 +588,6 @@
%D \TEX\ primitive \type{\hbox}:
%D
%D \starttyping
-%D \let\normalhbox=\hbox
-%D
%D \def\hbox{\ifmmode\mbox\else\normalhbox\fi}
%D \stoptyping
%D
@@ -875,6 +767,7 @@
\def\@shortstyle@ {@f@sh@} % short style prefix (rm etc)
\def\@letter@ {@f@le@} % first alternative typeface
\def\@noletter@ {@f@no@} % second alternative typeface
+\def\@fontclass@ {@f@cl@} % fontclass
%D The families can be grouped into math specific ones and
%D more text related families, although text ones can be
@@ -1060,9 +953,7 @@
%D separated list. Appart from practical limitations one can
%D define as many styles as needed.
-\let\stylelist=\empty
-
-\def\fontsizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small}
+\def\fontrelativesizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small}
%D \macros
%D {magfactor,magfactorhalf}
@@ -1099,7 +990,7 @@
%D \stoptable
\def\magstep#1% \relax removed, otherwise space after it sticks, else added
- {\ifcase#1 \@m\or1200\or1440\or1728\or2074\or2488\or\@m\fi}
+ {\ifcase#1 1000\or1200\or1440\or1728\or2074\or2488\or1000\fi}
\def\magstephalf
{1095}
@@ -1287,25 +1178,21 @@
% [encoding=ec]
% \definedfont[blabla] test \currentencoding/\fontfile \par
-\beginOLDTEX
-
- \def\checkfontfilename
- {\expandafter\docheckfontfilename\fontfile:\empty:\empty\relax}
-
- \def\docheckfontfilename#1:#2:#3#4\relax
- {\edef\!!stringa{#1}%
- \edef\!!stringb{#2}%
- \ifx\!!stringb\empty
- \edef\checkedfontfile{\!!stringa}%
- \else\ifx\!!stringa\v!file
- \edef\checkedfontfile{"\!!stringb"}%
- \else\ifx\!!stringa\v!name
- \edef\checkedfontfile{"\!!stringb"}%
- \else
- \edef\checkedfontfile{\!!stringb}%
- \fi\fi\fi}
-
-\endOLDTEX
+\def\checkfontfilename
+ {\expandafter\docheckfontfilename\fontfile:\empty:\empty\relax}
+
+\def\docheckfontfilename#1:#2:#3#4\relax
+ {\edef\!!stringa{#1}%
+ \edef\!!stringb{#2}%
+ \ifx\!!stringb\empty
+ \edef\checkedfontfile{\!!stringa}%
+ \else\ifx\!!stringa\v!file
+ \edef\checkedfontfile{"\!!stringb"}%
+ \else\ifx\!!stringa\v!name
+ \edef\checkedfontfile{"\!!stringb"}%
+ \else
+ \edef\checkedfontfile{\!!stringb}%
+ \fi\fi\fi}
% \definefontfeature[default] [liga=yes,texligatures=yes,texquotes=yes]
% \definefontfeature[default-caps][liga=yes,texligatures=yes,texquotes=yes,smcp=yes,script=latn]
@@ -1389,156 +1276,6 @@
%
% \stoptext
-% xetex / todo: disable default features ! file:, name:, [], "" etc etc
-
-\beginXETEX
-
- % for some reason xetex does not support [filename] for tfm files and
- % quotes also behave kind of strange " vs ' vs [ vs ...
-
- % we need to use the specs,
- %
- % \font\myfont = msam7 % ok
- % \font\myfont = "msam7" % also ok
- % \font\myfont = "msam7" at 8pt % error
-
- \ifx\suppressfontnotfounderror\undefined
-
- \newcount\xetexsavedinteractionmode
- \newbox \xetexcrappyhackbox
-
- \def\doiffoundxetexfontelse#1#2%
- {\xetexsavedinteractionmode\interactionmode
- \batchmode
- \setbox\xetexcrappyhackbox\vbox{\par}% resets error count
- \font\xetextempfont=#2\somefontspec\relax
- \edef\xetextempfont{\fontname\xetextempfont}%
- \ifx\xetextempfont\nullfontname
- \interactionmode\xetexsavedinteractionmode
- %\writestatus\m!fonts{fails #1: #2 (\xetextempfont)}%
- \expandafter\secondoftwoarguments
- \else
- \interactionmode\xetexsavedinteractionmode
- %\writestatus\m!fonts{succeeds #1: #2 (\xetextempfont)}%
- \expandafter\firstoftwoarguments
- \fi}
-
- \else
-
- \def\doiffoundxetexfontelse#1#2%
- {\suppressfontnotfounderror\plusone
- \font\xetextempfont=#2\somefontspec\relax
- \suppressfontnotfounderror\zerocount
- \edef\xetextempfont{\fontname\xetextempfont}%
- \ifx\xetextempfont\nullfontname
- %\writestatus\m!fonts{fails #1: #2 (\xetextempfont)}%
- \expandafter\secondoftwoarguments
- \else
- %\writestatus\m!fonts{succeeds #1: #2 (\xetextempfont)}%
- \expandafter\firstoftwoarguments
- \fi}
-
- \fi
-
- \def\docheckfontfilenameprefix#1:#2:#3#4\relax
- {\edef\!!stringa{#1}%
- \edef\!!stringb{#2}%
- \ifx\!!stringb\empty
- % no prefix
- \let\checkedfontfile\!!stringa
- \doiffoundxetexfontelse{1a}{\checkedfontfile\checkedfontfeatures}
- {\edef\checkedfontfile{\checkedfontfile\checkedfontfeatures}}
- {\doiffoundxetexfontelse{1b}{"\checkedfontfile\checkedfontfeatures"}
- {\edef\checkedfontfile{"\checkedfontfile\checkedfontfeatures"}}
- {\doiffoundxetexfontelse{1c}{"[\checkedfontfile]\checkedfontfeatures"}
- {\edef\checkedfontfile{"[\checkedfontfile]\checkedfontfeatures"}}
- {}}}%
- \else\ifx\!!stringa\v!file
- % force file, only file check when no spaces
- \let\checkedfontfile\!!stringb
- \doiffoundxetexfontelse{2b}{"[\checkedfontfile]\checkedfontfeatures"}
- {\edef\checkedfontfile{"[\checkedfontfile]\checkedfontfeatures"}}
- {\doiffoundxetexfontelse{2c}{"\checkedfontfile\checkedfontfeatures"}
- {\edef\checkedfontfile{"\checkedfontfile\checkedfontfeatures"}}
- {}}%
- \else\ifx\!!stringa\v!name
- % force name, always lookup by xetex itself, "" forces otf/ttf/type1
- \edef\checkedfontfile{"\!!stringb\checkedfontfeatures"}%
- \else
- % whatever, maybe even xetex spec, forget about features
- \edef\checkedfontfile{"\!!stringa\!!stringb"}%
- \fi\fi\fi}
-
- \def\checkfontfilename% -- todo: integrate so that we call do.. directly
- {\expandafter\docheckfontfilename\fontfile*\empty*\relax}
-
- \def\docheckfontfilename#1*#2#3*#4\relax % class overrules file
- {\edef\checkedfontfeatures
- {\expandafter\ifx\csname\fontclass\s!features\endcsname\empty
- \ifx\@@fontfeatures\empty\ifx#2\empty\else#2#3\fi\else\@@fontfeatures\fi
- \else\expandafter\ifx\csname\fontclass\s!features\endcsname\relax % redundant, will go away
- \ifx\@@fontfeatures\empty\ifx#2\empty\else#2#3\fi\else\@@fontfeatures\fi
- \else
- \csname\fontclass\s!features\endcsname
- \fi\fi}%
- \ifx\checkedfontfeatures\empty
- % done
- \else
- \edef\checkedfontfeatures{\executeifdefined{\??fa\checkedfontfeatures}\empty}%
- \ifx\checkedfontfeatures\empty
- % done
- \else
- \let\convertedfontfeatures\empty
- \processcommacommand[\checkedfontfeatures]\doconvertfontfeatures % raw
- \ifx\convertedfontfeatures\empty
- \let\checkedfontfeatures\empty
- \else
- \edef\checkedfontfeatures{:\convertedfontfeatures}%
- \fi
- \fi
- \fi
- \docheckfontfilenameprefix#1:\empty:\empty\relax
- \doshowcheckedfontfeatures}
-
- \def\dodoconvertfontfeatures#1=#2#3=#4\relax
- {\ifx#2\empty
- % invalid feature
- \else\ifcsname @xtx@#1@#2#3\endcsname
- \expandafter\ifx\csname @xtx@#1@#2#3\endcsname\empty\else
- \edef\convertedfontfeatures{\convertedfontfeatures\csname @xtx@#1@#2#3\endcsname;}%
- \fi
- \else
- \edef\!!stringa{#1}%
- \edef\!!stringb{#2#3}%
- \edef\convertedfontfeatures
- {\convertedfontfeatures
- \ifx\!!stringb\v!yes
- +\!!stringa
- \else\ifx\!!stringb\v!no
- -\!!stringa
- \else
- \!!stringa=\!!stringb
- \fi\fi;}%
- \fi\fi}
-
- \def\doconvertfontfeatures#1%
- {\dodoconvertfontfeatures#1=\empty=\relax}
-
- \def\remapfontfeature #1 #2 #3 {\setevalue{@xtx@#1@#2}{#3}}
-
- % this may move to another file, maybe font-xtx
-
- \remapfontfeature tlig yes mapping=tlig
- %remapfontfeature tlig no mapping=
- \remapfontfeature trep yes {}
- \remapfontfeature trep no {}
- \remapfontfeature texligatures yes mapping=tlig
- %remapfontfeature texligatures no mapping=
- %remapfontfeature texquotes yes mapping=tex-text
- %remapfontfeature texquotes no mapping=
-
-\endXETEX
-
\let\doshowcheckedfontfeatures\relax
\def\showcheckedfontfeatures
@@ -1550,7 +1287,7 @@
\def\donoparsefontspec % #1 == \cs
{\edef\fontfile{\truefontname\somefontname}%
- \ifx\fontfile\s!unknown \let\fontfile\defaultfontfile \fi
+ \ifx\fontfile\s!unknown \let\fontfile\defaultfontfile \fi % can for instance happen with MathGamma
\updatefontparameters
\checkfontfilename
\edef\lastfontname{\checkedfontfile\somefontspec}%
@@ -1606,10 +1343,6 @@
\edef\nullfontname {\fontname\nullfont}
\edef\dummyfontname {font\strippedcsname\\}
-\beginXETEX
- \def\defaultfontfile{lmtypewriter10-regular}
-\endXETEX
-
%D \macros
%D {everyfont,everyfontswitch}
%D
@@ -1688,12 +1421,10 @@
\def\classfont#1#2{#1#2} % \definefont[whatever][\classfont{xx}{yy} at 10pt]
-\beginOLDTEX
-
\def\definefontsynonym[#1]#2[#3]%
{\edef\@@fontfile{#3}%
\@EA\let\csname\??ff\fontclass#1\endcsname\@@fontfile
- \doifnextcharelse[\dodefinefontsynonym\donothing}
+ \doifnextoptionalelse\dodefinefontsynonym\donothing}
\def\dodefinefontsynonym[#1]%
{\edef\@@fontdata{#1}%
@@ -1703,48 +1434,6 @@
\getglobalfontparameters
\fi \fi}
-\endOLDTEX
-
-% We need to move the feature into the filename else it may be
-% overloaded by another reference. For instance the definition of
-% a regular and caps variant can use the same font.
-
-% We could use an indirect method ... store in 'array' and refer to
-% slot.
-
-\beginNEWTEX
-
-\def\definefontsynonym[#1]#2[#3]%
- {\edef\@@fontname{#1}%
- \edef\@@fontfile{#3}%
- \doifnextcharelse[\dodefinefontsynonym\nodefinefontsynonym}
-
-\def\nodefinefontsynonym
- {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile}
-
-\def\dodefinefontsynonym[#1]%
- {\edef\@@fontdata{#1}%
- \ifx\@@fontdata\empty
- \nodefinefontsynonym
- \else
- \ifx\fontclass\empty
- \getfontparameters
- \else
- \getglobalfontparameters
- \fi
- \ifcsname\??ff\@@fontfile\s!features\endcsname
- \@EA\edef\csname\??ff\fontclass\@@fontname\endcsname{\@@fontfile*\csname\??ff\@@fontfile\s!features\endcsname}%
- \@EA\let\csname\??ff\@@fontfile\s!features\endcsname\undefined
- \else
- \nodefinefontsynonym
- \fi
- \fi}
-
-\endNEWTEX
-
-% \def\resetfontsynonym[#1]% fails
-% {\letbeundefined{\??ff\fontclass#1}\letbeundefined{\??ff#1}}
-
\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater
\def\setupfontsynonym
@@ -1776,8 +1465,6 @@
\csname\??ff#2\endcsname
\fi\fi\fi\fi}
-\beginOLDTEX
-
\def\truefontname#1%
{\ifcsname\??ff\fontclass#1\endcsname
\@EA\truefontname\csname\??ff\fontclass#1\endcsname
@@ -1787,86 +1474,6 @@
#1%
\fi\fi}
-\endOLDTEX
-
-\beginNEWTEX
-
-% simple version
-%
-% \def\truefontname#1%
-% {\@EA\dotruefontname#1*\relax}
-%
-% \def\dotruefontname#1*#2\relax
-% {\ifcsname\??ff\fontclass#1\endcsname
-% \@EA\truefontname\csname\??ff\fontclass#1\endcsname
-% \else\ifcsname\??ff#1\endcsname
-% \@EA\truefontname\csname\??ff#1\endcsname
-% \else
-% #1%
-% \fi\fi}
-%
-% last counts
-%
-% \def\truefontname#1%
-% {\@EA\dotruefontname#1*\empty*\relax}
-%
-% \def\dotruefontname#1*#2#3*#4\relax
-% {\ifcsname\??ff\fontclass#1\endcsname
-% \ifx#2\empty
-% \@EA\truefontname\csname\??ff\fontclass#1\endcsname
-% \else
-% \@EA\truefontname\csname\??ff\fontclass#1\endcsname*#2#3%
-% \fi
-% \else\ifcsname\??ff#1\endcsname
-% \ifx#2\empty
-% \@EA\truefontname\csname\??ff#1\endcsname
-% \else
-% \@EA\truefontname\csname\??ff#1\endcsname*#2#3%
-% \fi
-% \else
-% \ifx#2\empty
-% #1%
-% \else
-% #1*#2#3%
-% \fi
-% \fi\fi}
-%
-% first counts
-
-\def\truefontname#1%
- {\@EA\dotruefontname#1*\empty*\relax}
-
-\def\dotruefontname#1*#2#3*#4\relax
- {\ifcsname\??ff\fontclass#1\endcsname
- \ifx#2\empty
- \@EA\truefontname\csname\??ff\fontclass#1\endcsname
- \else
- \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3%
- \fi
- \else\ifcsname\??ff#1\endcsname
- \ifx#2\empty
- \@EA\truefontname\csname\??ff#1\endcsname
- \else
- \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3%
- \fi
- \else
- #1\ifx#2\empty\else*#2#3\fi
- \fi\fi}
-
-\def\redotruefontname#1%
- {\@EA\dodotruefontname#1*\relax}
-
-\def\dodotruefontname#1*#2\relax
- {\ifcsname\??ff\fontclass#1\endcsname
- \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname
- \else\ifcsname\??ff#1\endcsname
- \@EA\redotruefontname\csname\??ff#1\endcsname
- \else
- #1%
- \fi\fi}
-
-\endNEWTEX
-
\def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1)
{\ifcsname\??ff\fontclass#2\endcsname
\expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}%
@@ -2109,26 +1716,24 @@
%D To be documented.
-\let\sizelist\empty
+\let\fontsizelist\empty
+\let\fontstylelist\empty
\def\definefontsize[#1]% sneller met toks
- {\addtocommalist{#1}\sizelist
+ {\addtocommalist{#1}\fontsizelist
\def\docommand##1%
{\def\dodocommand####1%
{\def\dododocommand########1%
%{\checkbodyfont{}{########1}{####1}{##1}}%
{\checkbodyfont{########1}{####1}{##1}}%
- \processcommacommand[\stylelist]\dododocommand}%
- \processcommacommand[\alternativelist]\dodocommand}%
- \processcommacommand[\sizelist]\docommand}
-
-\def\alternativetextlist{\c!tf,\c!bf,\c!it,\c!sl,\c!bs,\c!bi,\c!sc}
-\def\alternativemathlist{\c!mr,\c!mi,\c!sy,\c!ex,\c!ma,\c!mb}
+ \processcommacommand[\fontstylelist]\dododocommand}%
+ \processcommacommand[\fontalternativelist]\dodocommand}%
+ \processcommacommand[\fontsizelist]\docommand}
-\let\alternativelist\alternativetextlist % upward compatible
+\def\fontalternativetextlist{\c!tf,\c!bf,\c!it,\c!sl,\c!bs,\c!bi,\c!sc}
+\def\fontalternativemathlist{\c!mr,\c!mi,\c!sy,\c!ex,\c!ma,\c!mb}
-%\definefontsize[\c!a] \definefontsize[\c!b]
-%\definefontsize[\c!c] \definefontsize[\c!d]
+\let\fontalternativelist\fontalternativetextlist % upward compatible
%D \macros
%D {currentfontscale,currentfontbodyscale}
@@ -2268,7 +1873,7 @@
\scratchdimen\csname\??ft\s!default##1\endcsname\scratchdimen
\normalizebodyfontsize\scratchdimen\to\tempbodyfontsize
\setevalue{\??ft#2#1##1}{\tempbodyfontsize}}%
- \processcommacommand[\fontsizelist]\docommand
+ \processcommacommand[\fontrelativesizelist]\docommand
\copyparameters
[\??ft#2#1][\??ft\s!default]
[\c!interlinespace,\c!em]}%
@@ -2595,7 +2200,7 @@
% \scratchdimen\csname\??ft\s!default##1\endcsname\scratchdimen
% \normalizebodyfontsize\scratchdimen\to\!!stringa
% \letvalue{\??ft#1##1}\!!stringa}}%
-% \processcommacommand[\fontsizelist]\docommand
+% \processcommacommand[\fontrelativesizelist]\docommand
% \let\c!text\c!savedtext
% \ifdone
% \donefalse
@@ -2605,7 +2210,7 @@
% {\doifdefined{\s!default\s!default##1}
% {\donetrue\getvalue{\s!default\s!default##1}{#1}{##1}}}%
% \processcommacommand
-% [\stylelist]
+% [\fontstylelist]
% \defineunknownbodyfont
% \ifdone
% \setvalue{\@size@#1}{\docompletefontswitch[#1]}%
@@ -2614,7 +2219,7 @@
% \def\defineunknownsubfont##1%
% {\doifundefined{\@size@\getvalue{\??ft#1##1}}
% {\defineunknownfont{\getvalue{\??ft#1##1}}}}%
-% \processcommacommand[\fontsizelist]\defineunknownsubfont
+% \processcommacommand[\fontrelativesizelist]\defineunknownsubfont
% \definingunknownfontfalse
% \fi
% \fi
@@ -2659,19 +2264,19 @@
{\let\c!savedtext\c!text
\let\c!text\s!text
\donefalse
- \processcommacommand[\fontsizelist]{\dodefineunknownfont{#1}}%
+ \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}%
\let\c!text\c!savedtext
\ifdone
\donefalse
\processcommacommand
- [\stylelist]
+ [\fontstylelist]
{\dodefineunknownbodyfont{#1}}%
\ifdone
\donefalse
\setvalue{\@size@#1}{\docompletefontswitch[#1]}%
\ifdefiningunknownfont \else
\definingunknownfonttrue
- \processcommacommand[\fontsizelist]{\dodefineunknownsubfont{#1}}%
+ \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}%
\definingunknownfontfalse
\fi
\fi
@@ -2683,7 +2288,7 @@
% \def\defineunknownfontstyles#1%
% {\def\defineunknownbodyfont##1% see ***
% {\executeifdefined{\s!default\s!default##1}\gobbletwoarguments{#1}{##1}}%
-% \rawprocesscommacommand[\stylelist]\defineunknownbodyfont}
+% \rawprocesscommacommand[\fontstylelist]\defineunknownbodyfont}
%D These macros show that quite some definitions take place.
%D Fonts are not loaded yet! This means that at format
@@ -2741,8 +2346,8 @@
%D size and the local (sometimes in the textflow) size. We
%D store these dimensions in two \DIMENSION\ registers.
-\newdimen\globalbodyfontsize \globalbodyfontsize=12pt
-\newdimen\localbodyfontsize \localbodyfontsize =\globalbodyfontsize
+\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt
+\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize
%D \macros
%D {bodyfontsize}
@@ -2776,27 +2381,37 @@
%D often not the way users specify the bodyfont size. Therefore
%D we also store the normalized value.
-\chardef\fontdigits=1
+\chardef\fontdigits=2 % was 1
+
+% \def\normalizebodyfontsize#1\to#2%
+% {\scratchdimen#1\relax
+% \ifcase\fontdigits\advance\scratchdimen.5\points\fi
+% \@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\scratchdimen00\to#2}
+%
+% \def\donormalizedbodyfontsize#1.#2#3#4\to#5% \points ?
+% {\edef#5%
+% {#1%
+% \ifcase\fontdigits\or
+% \ifcase#2 \else.#2\fi % and not: \ifcase#2\else ...
+% \else
+% \ifcase#2#3 \else.#2\ifcase#3 \else#3\fi\fi % not: \ifcase#2#3\else ...
+% \fi
+% \s!pt}}
\def\normalizebodyfontsize#1\to#2%
- {\scratchdimen#1\relax
- \ifcase\fontdigits\advance\scratchdimen.5\points\fi
- \@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\scratchdimen00\to#2}
+ {\scratchdimen\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax
+ \@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\scratchdimen000\to#2}
-\def\donormalizedbodyfontsize#1.#2#3#4\to#5% \points ?
- {\edef#5%
+\def\donormalizedbodyfontsize#1.#2#3#4#5\to#6% \points ?
+ {\edef#6% not \ifcase#2\else due to \relax adding
{#1%
- \ifcase\fontdigits\or
- \ifcase#2 \else.#2\fi % and not: \ifcase#2\else ...
- \else
- \ifcase#2#3 \else.#2\ifcase#3 \else#3\fi\fi % not: \ifcase#2#3\else ...
+ \ifcase\fontdigits
+ \or \ifcase#2 \else .#2\fi % 1
+ \or \ifcase#2#3 \else .#2\ifcase#3 \else #3\fi\fi % 2
+ \else \ifcase#2#3#4 \else .#2\ifcase#4 \ifcase#3 \else#3\fi \else#3#4\fi\fi % 3
\fi
\s!pt}}
-\normalizebodyfontsize\bodyfontsize\to\normalizedglobalbodyfontsize
-\normalizebodyfontsize\bodyfontsize\to\normalizedlocalbodyfontsize
-\normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize
-
%D To be internationalized:
\def\korpsgrootte {\bodyfontsize}
@@ -3018,8 +2633,16 @@
\let\fontclass\empty \let\globalfontclass\fontclass
+% \def\setcurrentfontclass#1%
+% {\edef\fontclass{#1}}
+
+\def\registerfontclass#1%
+ {\letgvalue{\@fontclass@#1}\v!yes} % global ?
+
\def\setcurrentfontclass#1%
- {\edef\fontclass{#1}}
+ {\ifcsname\@fontclass@#1\endcsname
+ \edef\fontclass{#1}%
+ \fi}
\let\defaultfontstyle \c!rm
\let\defaultfontalternative \c!tf
@@ -3317,9 +2940,9 @@
%D \stoptyping
\def\dodefinefontstyle[#1][#2]%
- {\rawdoifinsetelse{#2}{\stylelist}
+ {\rawdoifinsetelse{#2}{\fontstylelist}
{}%\debuggerinfo\m!fonts{unknown style #2}}
- {\addtocommalist{#2}\stylelist
+ {\addtocommalist{#2}\fontstylelist
\showmessage\m!fonts8{#2\space (#1)}}%
% check kan hier
\def\docommand##1%
@@ -4389,7 +4012,7 @@
%D {bordermatrix}
%D
%D In \PLAIN\ \TEX\ the width of a parenthesis is stored in
-%D the \DIMENSION\ \type{\p@renwd}. This value is derived from
+%D the \DIMENSION\ \type{\mathparentwd}. This value is derived from
%D the width of \type{\tenrm B}, so let's take care of it now:
\let\normalbordermatrix=\bordermatrix
@@ -4397,7 +4020,7 @@
\def\bordermatrix%
{\bgroup
\setbox0\hbox{\getvalue{\textface\c!mm\c!ex}B}%
- \global\p@renwd\wd0\relax
+ \global\mathparentwd\wd0\relax
\egroup
\normalbordermatrix}
@@ -4678,6 +4301,7 @@
%D So far.
+\definefontstyle [\c!mm] [\c!mm]
\definefontstyle [\c!rm,\v!roman,\v!serif,\v!regular] [\c!rm]
\definefontstyle [\c!ss,\v!sansserif,\v!sans,\v!support] [\c!ss]
\definefontstyle [\c!tt,\v!teletype,\v!type,\v!mono] [\c!tt]
@@ -4800,24 +4424,6 @@
\def\fontvariant#1#2{\executeifdefined{\??fv#1#2}\empty}
-% original:
-%
-% \def\variant[#1]%
-% {\expanded{\definedfont
-% [\truefontname{\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1}}
-% at \currentfontscale\bodyfontsize]}}
-%
-% \beginXETEX \font
-%
-% \def\variant[#1]%
-% {\font\variantfont\truefontname{\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1}}
-% at \currentfontscale\bodyfontsize
-% \variantfont}
-%
-% \endXETEX
-%
-% better
-
\def\dosetscaledfont
{\checkrelativefontsize\fontstyle
\scaledfont\currentfontscale\bodyfontsize
@@ -4830,16 +4436,6 @@
at \scaledfont]}%
\ignoreimplicitspaces}
-\beginXETEX \font
-
- \unexpanded\def\variant[#1]%
- {\dosetscaledfont
- \font\variantfont\truefontname{\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1}}
- at \scaledfont
- \variantfont}
-
-\endXETEX
-
\ifx\Var\undefined \let\Var\variant \fi
%D By default we load the Computer Modern Roman fonts (but
@@ -4847,7 +4443,7 @@
%D bodyfont. Sans serif and teletype are also available and
%D can be called for by \type{\ss} and \type{\tt}.
-\setupbodyfont [unk, rm]
+% \setupbodyfont [unk, rm]
%D Also needed is:
@@ -4889,4 +4485,83 @@
\egroup\expandafter\firstoftwoarguments
\fi}
+%D New commands (not yet interfaced):
+
+\def\style[#1]% for inline usage, like \color
+ {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}}
+
+\def\startstyle[#1]%
+ {\begingroup
+ \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}
+
+\def\stopstyle
+ {\endgroup}
+
+%D Still experimental (might even go away).
+
+% \definestylecollection[mine]
+
+% \definestyleinstance[mine][default][sorry]
+% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
+% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
+% \definestyleinstance[mine][bf][\sl]
+% \definestyleinstance[mine][sl][\tt]
+
+% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}
+
+\definesystemvariable{sx}
+
+\def\definestylecollection
+ {\dosingleargument\dodefinestylecollection}
+
+\def\dodefinestylecollection[#1]%
+ {\iffirstargument
+ \unexpanded\setvalue{#1}{\styleinstance[#1]}%
+ \def\docommand##1%
+ {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}%
+ \processcommacommand[\fontalternativelist,\s!default]\dodocommand}%
+ \processcommacommand[\fontstylelist,\s!default]\docommand
+ \fi}
+
+\def\definestyleinstance
+ {\doquadrupleargument\dodefinestyleinstance}
+
+\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
+ {\iffirstargument
+ \doifundefined{#1}{\definestylecollection[#1]}%
+ \fi
+ \iffourthargument
+ \setvalue{\??sx#1:#2:#3}{#4}%
+ \else\ifthirdargument
+ \setvalue{\??sx#1::#2}{#3}%
+ \else\ifsecondargument
+ \letvalue{\??sx#1::#2}\empty
+ \fi\fi\fi}
+
+\unexpanded\def\styleinstance[#1]% will be faster
+ {%\begingroup\expanded{\infofont[#1:\fontstyle:\fontalternative]}\endgroup
+ \executeifdefined{\??sx#1:\fontstyle:\fontalternative}%
+ {\executeifdefined{\??sx#1:\fontstyle:\s!default}%
+ {\executeifdefined{\??sx#1::\fontalternative}
+ {\getvalue {\??sx#1::\s!default}}}}}
+
+% \unexpanded\def\styleinstance[#1]%
+% {\csname\??sx#1%
+% \ifcsname:\fontstyle:\fontalternative\endcsname
+% :\fontstyle:\fontalternative
+% \else\ifcsname:\fontstyle:\s!default\endcsname
+% :\fontstyle:\s!default
+% \else\ifcsname::\fontalternative\endcsname
+% ::\fontalternative
+% \else\ifcsname::\s!default\endcsname
+% ::\s!default
+% \else
+% % nothing, \relax
+% \fi\fi\fi\fi
+% \endcsname}
+
+%D \Compatibility with \MKIV:
+
+\def\somefontsize{\scaledfont}
+
\protect \endinput
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
index 3e2e57145..4d0d92fc5 100644
--- a/tex/context/base/font-ini.mkiv
+++ b/tex/context/base/font-ini.mkiv
@@ -12,26 +12,64 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% simplification ... we no longer deal with specific mmtfa specifications
-% \rm\bf --> \song
-% \rm\it --> \kai
-% \ss\it --> \kai
-% \tt\bf --> \hei
+% todo: always fontclass, then less testing
-\writestatus{loading}{Context Font Macros (ini)}
+% \starttext
+% \definefontfeature[basekerned][default][mode=base]
+% \definefontfeature[nodekerned][default][mode=node]
+% \definefontfeature[nonekerned][default][mode=base,kern=no]
+% \setupcolors[state=start]
+% \startoverlay
+% {\vbox{\red \definedfont[Serif*nonekerned at 12pt]\input tufte }}
+% {\vbox{\blue \definedfont[Serif*basekerned at 12pt]\input tufte }}
+% {\vbox{\green\definedfont[Serif*nodekerned at 12pt]\input tufte }}
+% \stopoverlay
+% \stoptext
+
+% \enabletrackers[otf.kerns]
+%
+% \definefontfeature[withkern][default][mode=node]
+% \definefontfeature[nokern] [default][mode=node,kern=no]
+% \definefontfeature[single] [default][mode=node,cpsp=yes]
+% \definefontfeature[simple] [default][mode=node,cpsp=yes,kern=no]
+%
+% {\definedfont[Serif*default] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+% {\definedfont[Serif*nokern] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+% {\definedfont[Serif*single] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+% {\definedfont[Serif*simple] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
+
+% figure out why \fontbody is not expanded
+
+\writestatus{loading}{ConTeXt Font Macros / Initialization}
\registerctxluafile{font-ini}{1.001}
+\registerctxluafile{node-fnt}{1.001} % here
\registerctxluafile{font-enc}{1.001}
\registerctxluafile{font-map}{1.001}
\registerctxluafile{font-syn}{1.001}
+\registerctxluafile{font-log}{1.001}
\registerctxluafile{font-tfm}{1.001}
\registerctxluafile{font-afm}{1.001}
-\registerctxluafile{font-otf}{1.001}
+\registerctxluafile{font-cid}{1.001} % cid maps
+\registerctxluafile{font-ott}{1.001} % otf tables
+\registerctxluafile{font-otf}{1.001} % otf main
+\registerctxluafile{font-otd}{1.001} % otf dynamics
+\registerctxluafile{font-oti}{1.001} % otf initialization
+\registerctxluafile{font-otb}{1.001} % otf main base
+\registerctxluafile{font-otn}{1.001} % otf main node
+\registerctxluafile{font-ota}{1.001} % otf analyzers
+\registerctxluafile{font-otp}{1.001} % otf pack
+\registerctxluafile{font-otc}{1.001} % otf context
\registerctxluafile{font-vf} {1.001}
\registerctxluafile{font-def}{1.001}
+\registerctxluafile{font-ctx}{1.001}
+\registerctxluafile{font-xtx}{1.001}
\registerctxluafile{font-fbk}{1.001}
\registerctxluafile{font-ext}{1.001}
\registerctxluafile{font-pat}{1.001}
+\registerctxluafile{font-chk}{1.001}
\unprotect
@@ -107,10 +145,10 @@
%D
%D A couple of relatively new macros:
-\newevery \everydefinedfont \relax % not ot be confused with \everydefinefont
+% \newtoks \everydefinedfont % not ot be confused with \everydefinefont
\def\dodefinedfont[#1]%
- {\iffirstargument\definefont[thedefinedfont][#1]\fi
+ {\iffirstargument\definefont[thedefinedfont][#1]\fi % we can speed this one up
\csname thedefinedfont\endcsname
\the\everydefinedfont}
@@ -132,158 +170,10 @@
\egroup\expandafter\secondoftwoarguments
\fi}
-%%% message 14 added
-
-\startmessages dutch library: fonts
- title: korps
- 1: codering --
- 2: variant -- wordt geladen
- 3: onbekende variant --
- 4: korps -- is niet gedefinieerd
- 5: stijl -- is niet gedefinieerd
- 6: -- wordt geladen
- 7: onbekend formaat --
- 8: stijl -- gedefinieerd
-% 9: mapping -- is geladen
- 10: onbekende font file --
- 14: korps -- is gedefinieerd (kan beter globaal plaatsvinden)
-\stopmessages
-
-\startmessages english library: fonts
- title: bodyfont
- 1: coding --
- 2: variant -- is loaded
- 3: unknown variant --
- 4: bodyfont -- is not defined
- 5: style -- is not defined
- 6: -- is loaded
- 7: unknown format --
- 8: style -- defined
-% 9: mapping -- is loaded
- 10: unknown font file --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages german library: fonts
- title: Fliesstext
- 1: Kodierung --
- 2: Variante -- ist geladen
- 3: Unbekannte Variante --
- 4: Fliesstext -- ist nicht definiert
- 5: Stil -- ist nicht definiert
- 6: -- ist geladen
- 7: unbekanntes Format --
- 8: Stil -- definiert
-% 9: Map -- ist geladen
- 10: unbekanntes Font --
- 14: Fliesstext -- wurde definiert (besser waere globale Definition)
-\stopmessages
-
-\startmessages czech library: fonts
- title: zakladnifont
- 1: kodovani --
- 2: varianta -- je nactena
- 3: neznama varianta --
- 4: zakladni font -- neni definovan
- 5: styl -- neni definovan
- 6: -- je nacten
- 7: neznamy format --
- 8: styl -- definovan
-% 9: mapovani -- je nacteno
- 10: neznamy font --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages italian library: fonts
- title: font del corpo
- 1: codifica --
- 2: variante -- caricata
- 3: variante sconosciuta --
- 4: corpo del testo -- non definito
- 5: stile -- non definito
- 6: -- caricato
- 7: formato sconosciuto --
- 8: stile -- definito
-% 9: mappatura -- caricata
- 10: file di font sconosciuto --
- 14: corpo del testo -- definito (sarebbe meglio globale)
-\stopmessages
-
-\startmessages norwegian library: fonts
- title: hovedfont
- 1: koding --
- 2: variant -- er lest inn
- 3: ukjent variant --
- 4: hovedfont -- er ikke definert
- 5: stil -- er ikke definert
- 6: -- er lest inn
- 7: ukjent format --
- 8: stil -- definert
-% 9: avbildning -- er lest inn
- 10: ukjent fontfil --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages romanian library: fonts
- title: corp de litere
- 1: codificarea --
- 2: varianta -- este incarcata
- 3: varianta necunoscuta --
- 4: corpul de litere -- nu este definit
- 5: stilul -- nu este definit
- 6: -- este incarcat
- 7: format necunoscut --
- 8: stilul -- definit
-% 9: maparea -- este incarcat
- 10: fisier font necunoscut --
- 14: bodyfont -- is defined (can better be done global)
-\stopmessages
-
-\startmessages french library: fonts
- title: corps de texte
- 1: encodage --
- 2: la variante -- est chargée
- 3: variante -- inconnue
- 4: policecorps -- n'est pas définie
- 5: le style -- n'est pas défini
- 6: -- est chargé
- 7: format -- inconnu
- 8: style -- défini
-% 9: mapping -- is loaded
- 10: fichier de police -- inconnu
- 14: policecorps -- est défini (une définition globale pourrait être plus adéquat)
-\stopmessages
-
-%D This module is one of the oldest modules of \CONTEXT. The
-%D macros below evolved out of the \PLAIN\ \TEX\ macros and
-%D therefore use a similar naming scheme (\type{\rm},
-%D \type{\bf}, etc). This module grew out of our needs. We
-%D started with the \PLAIN\ \TEX\ definitions, generalized the
-%D underlaying macros, and extended those to a level at which
-%D probably no one will ever recognize them.
-%D
-%D In 2001 we ran into a couple of projects where more than
-%D one combined set of fonts was involved in a document. To
-%D make definitions more readable, as well as to overcome the
-%D problem of ever growing file name lists, and also because
-%D we needed to scale fonts relative to each other, the low
-%D level implementation was partly rewritten. Global
-%D font assignments, relative scaling, font classes and alike
-%D were added then. At the same time some macros were made a
-%D bit more readable, and math support was extended to the
-%D larger sizes.
-%D
-%D One important characteristic of the font mechanism presented
-%D here is the postponing of font loading. This makes it
-%D possible to distribute \type{fmt} files without bothering
-%D about the specific breed of \type{tfm} files.
-%D
-%D Another feature implemented here is the massive switching
-%D from roman to {\ss sans serif}, {\tt teletype} or else. This
-%D means one doesn't have to take care of all kind of relations
-%D between fonts.
-%D
-%D \page[bigpreference]
+%D For more detailed (and historic information) we refer to the file
+%D \type {font-ini.mkii}. Here we have a much simplified lower level
+%D implementation due to a different approach to math. Also the chapter
+%D on fonts in the reference manual explains a lot.
%D \macros
%D {rm,ss,tt,hw,cg}
@@ -314,56 +204,6 @@
%D \stoptable
%D \stoplinecorrection
%D
-%D Anyone who feels the need, can define additional ones, like
-%D
-%D \startlinecorrection
-%D \starttable[|l||]
-%D \HL
-%D \NC faxfont \NC \type{\ff} \NC\FR
-%D \NC blackboard \NC \type{\bb} \NC\LR
-%D \HL
-%D \stoptable
-%D \stoplinecorrection
-%D
-%D Or even
-%D
-%D \startlinecorrection
-%D \starttable[|l||]
-%D \HL
-%D \NC hebrew \NC \type{\hb} \NC\SR
-%D \HL
-%D \stoptable
-%D \stoplinecorrection
-%D
-%D Styles are grouped in font sets. At the moment there are
-%D three main sets defined:
-%D
-%D \startlinecorrection
-%D \starttable[|l|l||]
-%D \HL
-%D \NC Computer Modern Roman \NC Knuth \NC \type{cmr} \NC\FR
-%D \NC Lucida Bright \NC Bigelow \& Holmes \NC \type{lbr} \NC\MR
-%D \NC Standard Postscript Fonts \NC Adobe \NC \type{pos} \NC\LR
-%D \HL
-%D \stoptable
-%D \stoplinecorrection
-%D
-%D There are also some Computer Modern Roman alternatives:
-%D
-%D \startlinecorrection
-%D \starttable[|l|l||]
-%D \HL
-%D \NC Computer Modern Roman \NC Knuth \& Sauter \NC \type{sau} \NC\FR
-%D \NC Euler fonts \NC Zapf \NC \type{eul} \NC\MR
-%D \NC Computer Modern Concrete \NC Knuth \& Zapf \NC \type{con} \NC\LR
-%D \HL
-%D \stoptable
-%D \stoplinecorrection
-%D
-%D All these definitions are ordered in files with names like
-%D \type{font-cmr} and \type{font-pos}, where the last three
-%D characters specify the name as known to \CONTEXT.
-%D
%D Within such a font set (\type{cmr}) and style (\type{\rm})
%D we can define a number of text font alternatives:
%D
@@ -380,43 +220,6 @@
%D \HL
%D \stoptable
%D \stoplinecorrection
-
-%D For old stylish Frans Goddijn we have:
-%D
-%D \startlinecorrection
-%D \starttable[|l||]
-%D \HL
-%D \NC oldstyle \NC \type{\os} \NC\SR
-%D \HL
-%D \stoptable
-%D \stoplinecorrection
-%D
-%D The availability of these alternatives depends on the
-%D completeness of a font family and of course the definitions
-%D in the font files.
-%D
-%D But let's not forget math. In addition to the previous \TEX\
-%D families (the mysterious \type{\fam}'s) we've got some more:
-%D
-%D \startlinecorrection
-%D \starttable[|l||]
-%D \HL
-%D \NC Math Roman \NC \type{\mr} \NC\FR
-%D \NC Math Italic \NC \type{\mi} \NC\MR
-%D \NC Math Symbol \NC \type{\sy} \NC\MR
-%D \NC Math Extra \NC \type{\ex} \NC\MR
-%D \NC Math A \NC \type{\ma} \NC\MR
-%D \NC Math B \NC \type{\mb} \NC\MR
-%D \NC Math C \NC \type{\mc} \NC\LR
-%D \HL
-%D \stoptable
-%D \stoplinecorrection
-%D
-%D Users can call for specific fonts in many ways. Switches to
-%D other typefaces, like the switch from normal to bold, are as
-%D intuitive as possible, which means that all dependant fonts
-%D also switch. One can imagine that this takes quite some
-%D processing time.
%D
%D Internally fonts are stored as combination of size, style
%D and alternative, e.g. \type{12pt}+\type{\ss}+\type{\bf}.
@@ -514,7 +317,7 @@
%D And compare $\rm \scriptstyle THIS$ with the slightly larger
%D \cap{THIS}: \ruledhbox{$\rm \scriptstyle scriptstyle: THIS$}
%D or \ruledhbox{\cap{x style: THIS}} makes a big difference.
-
+%D
%D The \type{x..d} sizes should be used grouped. If you
%D don't group them, i.e. call them in a row, \CONTEXT\ will
%D not be able to sort out your intention (\type {x} inside
@@ -592,282 +395,8 @@
%D \NC \NR
%D \HL
%D \stoptabulate
-
-%D \macros
-%D {mf}
-%D
-%D Math fonts are a species in their own. They are tightly
-%D hooked into smaller and even smaller ones of similar breed
-%D to form a tight family. Let's first see how these are
-%D related:
-%D
-%D \startbuffer
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+ \bi x^2 =\rm 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+{\bi x^2}=\rm 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+ \bi x^2 =\tf 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+{\bi x^2}=\tf 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+ \bi x^2 =\bf 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+{\bi x^2}=\bf 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+ \bi x^2 =\sl 6x^2$
-%D $\tf x^2+\bf x^2+\sl x^2+\it x^2+\bs x^2+{\bi x^2}=\sl 6x^2$
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Gives both an expected and unexpected result:
-%D
-%D \startvoorbeeld
-%D \startlines
-%D \getbuffer
-%D \stoplines
-%D \stopvoorbeeld
-%D
-%D We see here that the character shapes change accordingly to
-%D the current family, but that the symbols are always typeset
-%D in the font assigned to \type{\fam0}.
-%D
-%D \startbuffer
-%D $\tf\mf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = 6x^2$
-%D $\bf\mf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = 6x^2$
-%D $\sl\mf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = 6x^2$
-%D $\bs\mf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = 6x^2$
-%D $\it\mf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = 6x^2$
-%D $\bi\mf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = 6x^2$
-%D \stopbuffer
-%D
-%D \startvoorbeeld
-%D \startlines
-%D \getbuffer
-%D \stoplines
-%D \stopvoorbeeld
%D
-%D In this example we see a new command \type{\mf} surface
-%D which means as much as {\em math font}. This commands
-%D reactivates the last font alternative and therefore equals
-%D \type{\bf}, \type{\sl} etc. but by default it equals
-%D \type{\tf}:
-
-\unexpanded\def\mf
- {\dodosetmathfont\fontalternative
- \csname\fontalternative\endcsname}
-
-%D The previous example was typeset saying:
-%D
-%D \typebuffer
-%D
-%D Beware: the exact location of \type{\mf} is not that
-%D important, we could as well has said
-%D
-%D \startbuffer
-%D $\bf x^2 + x^2 + x^2 + x^2 + x^2 + x^2 = \mf 6x^2$
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D This is due to the way \TEX\ handles fonts in math mode.
-%D
-%D Of course we'll have to redefine \type{\mf} every time we
-%D change the current \type{\fam}.
-
-%D \macros
-%D {mbox,enablembox,mathop}
-%D
-%D Now how can we put this to use? Will the next sequence
-%D give the desired result?
-%D
-%D \startbuffer
-%D $\bf x^2 + \hbox{\mf whatever} + \sin(2x)$
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D It won't!
-%D
-%D \startvoorbeeld
-%D \let\mathop=\normalmathop \getbuffer
-%D \stopvoorbeeld
-%D
-%D The reason for this is that \type{\sin} is defined as:
-%D
-%D \starttyping
-%D \def\sin{\mathop{\rm sin}\nolimits}
-%D \stoptyping
-%D
-%D We can fix this by defining
-
-\let\normalmathop\mathop
-
-\unexpanded\def\mathop
- {\normalmathop
- \bgroup
- \let\rm\mf
- \let\next=}
-
-%D We can fix arbitrary horizontal boxes by redefining the
-%D \TEX\ primitive \type{\hbox}:
-%D
-%D \starttyping
-%D \let\normalhbox=\hbox
-%D
-%D \def\hbox{\ifmmode\mbox\else\normalhbox\fi}
-%D \stoptyping
-%D
-%D with
-%D
-%D \starttyping
-%D \def\mbox#1#%
-%D {\normalhbox#1\bgroup\mf\let\next=}
-%D \stoptyping
-%D
-%D or more robust, that is, also accepting \type{\hbox\bgroup}:
-%D
-%D \starttyping
-%D \def\mbox%
-%D {\normalhbox\bgroup\mf
-%D \dowithnextbox{\flushnextbox\egroup}%
-%D \normalhbox}
-%D \stoptyping
-%D
-%D And now:
-%D
-%D \startbuffer
-%D $\bf x^2 + \hbox{whatever} + \sin(2x)$
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Indeed gives:
-%D
-%D \startvoorbeeld
-%D \enablembox\getbuffer
-%D \stopvoorbeeld
-%D
-%D But, do we want this kind of trickery to be activated? No,
-%D simply because we cannot be sure of incompatibilities,
-%D although for instance unboxing goes ok. Therefore we
-%D introduce:
-
-% best can go to math-ini and make \mf a hook then
-
-% better use \dowithnextboxcontent
-
-\def\normalmbox
- {\normalhbox\bgroup\mf
- \dowithnextbox{\flushnextbox\egroup}\normalhbox}
-
-% to test:
-%
-% \def\normalmbox
-% {\dowithnextboxcontent\mf\flushnextbox\normalhbox}
-
-\def\mbox
- {\ifmmode\normalmbox\else\normalhbox\fi}
-
-\def\enablembox
- {\appendtoks
- \ifx\normalhbox\undefined\let\normalhbox\hbox\fi
- \let\hbox\mbox
- \to\everymathematics}
-
-%D So in fact one can enable this feature if needed. I would say:
-%D go along, but use grouping if needed!
-
-%D \macros
-%D {mrfam,mifam,syfam,exfam,
-%D bsfam,bifam,scfam,tffam,
-%D mafam,mbfam,msfam}
-%D
-%D After this short mathematical excursion, we enter the world
-%D of fonts and fontswitching. We start with something very
-%D \TEX: \type{\fam} specified font families. \TEX\ uses
-%D families for managing fonts in math mode. Such a family has
-%D three members: text, script and scriptscript: $x^{y^z}$. In
-%D \CONTEXT\ we take a bit different approach than \PLAIN\
-%D \TEX\ does. \PLAIN\ \TEX\ needs at least four families for
-%D typesetting math. We use those but give them symbolic names.
-
-\chardef\mrfam = 0 % (Plain TeX) Math Roman
-\chardef\mifam = 1 % (Plain TeX) Math Italic
-\chardef\syfam = 2 % (Plain TeX) Math Symbol
-\chardef\exfam = 3 % (Plain TeX) Math Extra
-
-%D \PLAIN\ \TEX\ also defines families for {\it italic}, {\sl
-%D slanted} and {\bf bold} typefaces, so we don't have to
-%D define them here.
-
-\ifx\itfam\undefined
-
-\chardef\itfam = 4 % (Plain TeX) Italic
-\chardef\slfam = 5 % (Plain TeX) Slanted
-\chardef\bffam = 6 % (Plain TeX) Boldface
-
-\fi
-
-%D Family~7 in \PLAIN\ \TEX\ is not used in \CONTEXT, because
-%D we do massive switches from roman to sans serif, teletype or
-%D other faces.
-
-\ifx\ttfam\undefined
- \chardef\ttfam = 7 % (Plain TeX) can be reused!
-\fi
-
-%D We define ourselves some more families for {\bs bold
-%D slanted}, {\bi bold italic} and {\sc Small Caps}, so
-%D we can use them in math mode too. Instead of separate
-%D families for {\ss sans serif} and \type{teletype} we use the
-%D more general \type{\tffam}, which stands for typeface.
-
-\chardef\bsfam = 8 % (ConTeXt) BoldSlanted
-\chardef\bifam = 9 % (ConTeXt) BoldItalic
-\chardef\scfam = 10 % (ConTeXt) SmallCaps
-\chardef\tffam = 11 % (ConTeXt) TypeFace
-
-%D Because Taco needs a few more math families, we reuse
-%D family~7 for all those typefaces that have no related
-%D family, and therefore are grouped into one.
-
-\chardef\nnfam = 7 % (ReUsed) NoName
-
-%D Normally \type{\mrfam} equals \type{\tffam}, but a more
-%D distinctive alternatives are possible, for instance the
-%D Euler and Concrete Typefaces.
-%D
-%D After having defined all those in nature non||mathematical
-%D families, we define ourselves some real math ones. These are
-%D needed for the \AMS\ Symbol Fonts and Extended Lucida
-%D Bright.
-
-\chardef\mafam = 12 % (ConTeXt) Math A Fam (AmsTeX A)
-\chardef\mbfam = 13 % (ConTeXt) Math B Fam (AmsTeX B)
-\chardef\mcfam = 14 % (ConTeXt) Math C Fam (MathTime)
-\chardef\mdfam = 15 % (ConTeXt) Math D Fam (MathTime)
-
-%D Because there are 16~families and because \type{\ttfam}
-%D is reused, at the moment we have no so many families
-%D left. By default, we map any newly defined family on the
-%D last one (F).
-
-\def\newfam#1{\chardef#1=15 }
-
-%D This hack is also needed because in \ETEX\ we are going
-%D to reuse the \type {\newfam} allocation counter.
-
-%D To ease the support of font packages, we als define
-%D shortcuts to these familynames. This is necessary because
-%D the family names are in fact \type{\chardef}'s, which means
-%D that we're dealing with numbers (one can check this by
-%D applying \type{\showthe} and \type{\show}). In the
-%D specification of math symbols however we need hexadecimal
-%D numbers, so we have to convert the \type{\fam}'s value.
-
-\edef\hexmrfam {\hexnumber\mrfam} \edef\hexbsfam {\hexnumber\bsfam}
-\edef\hexmifam {\hexnumber\mifam} \edef\hexbifam {\hexnumber\bifam}
-\edef\hexsyfam {\hexnumber\syfam} \edef\hexscfam {\hexnumber\scfam}
-\edef\hexexfam {\hexnumber\exfam} \edef\hextffam {\hexnumber\tffam}
-\edef\hexitfam {\hexnumber\itfam} \edef\hexmafam {\hexnumber\mafam}
-\edef\hexslfam {\hexnumber\slfam} \edef\hexmbfam {\hexnumber\mbfam}
-\edef\hexbffam {\hexnumber\bffam} \edef\hexmcfam {\hexnumber\mcfam}
-\edef\hexnnfam {\hexnumber\nnfam} \edef\hexmdfam {\hexnumber\mdfam}
+%D Remark: math support has changed a bit.
%D \macros
%D {uchar}
@@ -886,244 +415,122 @@
\def\@shortstyle@ {@f@sh@} % short style prefix (rm etc)
\def\@letter@ {@f@le@} % first alternative typeface
\def\@noletter@ {@f@no@} % second alternative typeface
+\def\@fontclass@ {@f@cl@} % fontclass
+
+%D \macros
+%D {fontclass, defaultfontclass}
+%D
+%D The fontclass model was introduced a while after we implement
+%D the basic font model and at that time we still defaulted to
+%D no model at all. Nowadays we default to the \type {modern}
+%D fontclass.
+
+\let\fontclass \empty
+\let\defaultfontclass\empty
-%D The families can be grouped into math specific ones and
-%D more text related families, although text ones can be
-%D mapped onto the math ones to get for instance bold math.
+%D \macros
+%D {textonly}
%D
-%D Both groups of families are handles by a couple of token
-%D list tagged as strategies. This implementation makes
-%D implementing extensions more comfortable.
+%D Traditionally math has a big impact on font definitions, mainly
+%D because we need to define alphabet variants using families and
+%D fonts. This means that one can easily get 10 fonts loaded per
+%D math size. In \MKIV\ we use a different approach: one family
+%D which has either a virtual font made of traditional fonts, or
+%D an \OPENTYPE\ font that has it all.
+%D
+%D We currently use only one math family but in the future we
+%D might consider using a second one for bold math. For the
+%D moment we keep the \MKII\ method of using a token register
+%D for definitions but we already dropped the text and symbols
+%D ones since they now live in the same family.
-\newtoks \textstrategies
\newtoks \mathstrategies
-\newtoks \symbstrategies
\newif\ifsynchronizemathfonts \synchronizemathfontstrue
-\def\synchronizetext % stylish text in mmode
- {\ifsynchronizemathfonts\the\textstrategies\fi} % \if...\fam\minusone\fi}
-
\def\synchronizemath % math stuff in mmode
- {\ifsynchronizemathfonts\the\mathstrategies\fi} % \if...\fam\minusone\fi}
+ {\ifsynchronizemathfonts\the\mathstrategies\fi}
-\def\synchronizesymb % stylish math stuff in mmode
- {\ifsynchronizemathfonts\the\symbstrategies\fi} % \if...\fam\minusone\fi}
+\def\textonly{\synchronizemathfontsfalse} % document this
-%D By not setting the family we can append a font switch to \type
-%D {\everymath}. On the other hand, one never knows in what family
-%D state the strategies brought us.
-%D
-%D \starttyping
-%D {\bfa $\the\fam$} {\bfa \everymath{} $\the\fam$}
-%D \stoptyping
+%D The main math font definer. We have removed some optimized
+%D code simply because we now always have a fontclass. We could
+%D check for fontclass being default or empty and save a few
+%D tests but it does not help us when no math is defined.
-%D \macros
-%D {textonly}
-%D
-%D We can inhibit this slow||downer with:
+\chardef\mrfam\zerocount % math regular
+\chardef\mbfam\zerocount % math bold
-\def\textonly{\synchronizemathfontsfalse} % document this
+\def\mathtextsuffix {-text}
+\def\mathscriptsuffix {-script}
+\def\mathscriptscriptsuffix{-scriptscript}
-\appendtoks
- \dosettextfamily\c!tf
- \dosettextfamily\c!bf
- \dosettextfamily\c!sl
- \dosettextfamily\c!it
- \dosettextfamily\c!bs
- \dosettextfamily\c!bi
- \dosettextfamily\c!sc
-\to \textstrategies
-
-\def\dosettextfamily#1% better pass fontbody to dodoset
- {\let\savedfontbody\fontbody
- \let\fontfamily#1%
- \let\fontbody\scriptscriptface\dodosettextfamily\scriptscriptfont
- \let\fontbody\scriptface \dodosettextfamily \scriptfont
- \let\fontbody\textface \dodosettextfamily \textfont
- \let\fontbody\savedfontbody}
-
-% \def\s!nullfont{nullfont}
-
-\def\dodosettextfamily
- {\ifx\fontclass\empty
- \@EA\dodosettextfamilyA
- \else
- \@EA\dodosettextfamilyB
- \fi}
+% \let\mathsizesuffix\empty
-\def\dodosettextfamilyA#1%
- {\ifcsname \fontbody\c!mm\fontfamily\fontsize\endcsname \autofontsizefalse
- \csname \fontbody\c!mm\fontfamily\fontsize\endcsname \else
- \ifcsname \fontbody\c!mm\fontfamily\endcsname \autofontsizetrue
- \csname \fontbody\c!mm\fontfamily\endcsname \else
- \ifcsname \fontbody\c!rm\fontfamily\fontsize\endcsname \autofontsizefalse
- \csname \fontbody\c!rm\fontfamily\fontsize\endcsname \else
- \ifcsname \fontbody\c!rm\fontfamily\endcsname \autofontsizetrue
- \csname \fontbody\c!rm\fontfamily\endcsname \else
- \nullfont \autofontsizetrue
- \fi\fi\fi\fi
- #1\csname\fontfamily\s!fam\endcsname\font}
-
-\def\dodosettextfamilyB#1%
- {\ifcsname\fontclass\fontbody\c!mm\fontfamily\fontsize\endcsname \autofontsizefalse
- \csname\fontclass\fontbody\c!mm\fontfamily\fontsize\endcsname \else
- \ifcsname\fontclass\fontbody\c!mm\fontfamily\endcsname \autofontsizetrue
- \csname\fontclass\fontbody\c!mm\fontfamily\endcsname \else
- \ifcsname\fontclass\fontbody\c!rm\fontfamily\fontsize\endcsname \autofontsizefalse
- \csname\fontclass\fontbody\c!rm\fontfamily\fontsize\endcsname \else
- \ifcsname\fontclass\fontbody\c!rm\fontfamily\endcsname \autofontsizetrue
- \csname\fontclass\fontbody\c!rm\fontfamily\endcsname \else
- \dodosettextfamilyA#1%
- \fi\fi\fi\fi
- #1\csname\fontfamily\s!fam\endcsname\font}
-
-\def\mrfallback{\c!rm\c!tf}
+\chardef\currentmathsize\zerocount
-\appendtoks
- \dosetmathfamily\mrfam\textface\scriptface\scriptscriptface\c!mr\mrfallback
- \dosetmathfamily\mifam\textface\scriptface\scriptscriptface\c!mi\empty
- \dosetmathfamily\syfam\textface\scriptface\scriptscriptface\c!sy\empty
- \dosetmathfamily\exfam\textface\textface \textface \c!ex\empty
- \dosetmathfamily\mafam\textface\scriptface\scriptscriptface\c!ma\empty
- \dosetmathfamily\mbfam\textface\scriptface\scriptscriptface\c!mb\empty
- \dosetmathfamily\mcfam\textface\scriptface\scriptscriptface\c!mc\empty
-% \dosetmathfamily\mdfam\textface\scriptface\scriptscriptface\c!md\empty
- \dosetmathfamily\nnfam\textface\scriptface\scriptscriptface\c!nn\empty
-\to \mathstrategies
+\def\mathsizesuffix{\ifcase\currentmathsize\or\mathtextsuffix\or\mathscriptscriptsuffix\or\mathscriptsuffix\fi}
-\appendtoks
- \dosetskewchar\mifam\defaultskewcharmi % implemented later on
- \dosetskewchar\syfam\defaultskewcharsy % implemented later on
-\to \mathstrategies
+\def\dodosetmathfamily#1#2%
+ {\ifcsname\fontclass \fontbody\c!mm\fontfamily\fontsize\the\currentmathsize\endcsname \autofontsizefalse
+ \csname\fontclass \fontbody\c!mm\fontfamily\fontsize\the\currentmathsize\endcsname \else
+ \ifcsname\fontclass \fontbody\c!mm\fontfamily \the\currentmathsize\endcsname \autofontsizetrue
+ \csname\fontclass \fontbody\c!mm\fontfamily \the\currentmathsize\endcsname \else
+ \dodosetmathfamilyx#1#2%
+ \fi\fi
+ #1#2\font}
-\def\dosetmathfamily#1#2#3#4#5#6%
- {\let\savedfontbody\fontbody % op hoger plan
- \let\fontfamily#5%
- \let\backfamily#6%
- \let\fontbody #4\dodosetmathfamily\scriptscriptfont#1%
- \let\fontbody #3\dodosetmathfamily \scriptfont#1%
- \let\fontbody #2\dodosetmathfamily \textfont#1%
- \let\fontbody\savedfontbody}
-
-\def\dodosetmathfamily
- {\ifx\fontclass\empty
- \@EA\dodosetmathfamilyA
- \else
- \@EA\dodosetmathfamilyB
- \fi}
+\def\dodosetmathfamilyx#1#2%
+ {\ifcsname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\the\currentmathsize\endcsname \autofontsizefalse
+ \csname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\the\currentmathsize\endcsname \else
+ \ifcsname\defaultfontclass\fontbody\c!mm\fontfamily \the\currentmathsize\endcsname \autofontsizetrue
+ \csname\defaultfontclass\fontbody\c!mm\fontfamily \the\currentmathsize\endcsname \else
+ \dodosetmathfamilyxx#1#2%
+ \fi\fi}
-\def\dodosetmathfamilyA#1#2%
- {\ifcsname \fontbody\c!mm\fontfamily\fontsize\endcsname \autofontsizefalse
- \csname \fontbody\c!mm\fontfamily\fontsize\endcsname \else
- \ifcsname \fontbody\c!mm\fontfamily \endcsname \autofontsizetrue
- \csname \fontbody\c!mm\fontfamily \endcsname \else
- \ifcsname \fontbody \backfamily\fontsize\endcsname \autofontsizefalse
- \csname \fontbody \backfamily\fontsize\endcsname \else
- \ifcsname \fontbody \backfamily \endcsname \autofontsizetrue
- \csname \fontbody \backfamily \endcsname \else
- \nullfont \autofontsizetrue
- \fi\fi\fi\fi
- #1#2\font}
+\def\dodosetmathfamilyxx#1#2%
+ {\ifcsname \fontbody\c!mm\fontfamily\fontsize\the\currentmathsize\endcsname \autofontsizefalse
+ \csname \fontbody\c!mm\fontfamily\fontsize\the\currentmathsize\endcsname \else
+ \ifcsname \fontbody\c!mm\fontfamily \the\currentmathsize\endcsname \autofontsizetrue
+ \csname \fontbody\c!mm\fontfamily \the\currentmathsize\endcsname \else
+ \nullfont \autofontsizetrue
+ \fi\fi}
-\def\dodosetmathfamilyB#1#2%
- {\ifcsname\fontclass\fontbody\c!mm\fontfamily\fontsize\endcsname \autofontsizefalse
- \csname\fontclass\fontbody\c!mm\fontfamily\fontsize\endcsname \else
- \ifcsname\fontclass\fontbody\c!mm\fontfamily \endcsname \autofontsizetrue
- \csname\fontclass\fontbody\c!mm\fontfamily \endcsname \else
- \ifcsname\fontclass\fontbody \backfamily\fontsize\endcsname \autofontsizefalse
- \csname\fontclass\fontbody \backfamily\fontsize\endcsname \else
- \ifcsname\fontclass\fontbody \backfamily \endcsname \autofontsizetrue
- \csname\fontclass\fontbody \backfamily \endcsname \else
- \dodosetmathfamilyA#1#2%
- \fi\fi\fi\fi
- #1#2\font}
+\def\dosetmathfamily#1#2%
+ {\let\savedfontbody\fontbody % op hoger plan
+ \let\fontfamily#2%
+ \let\currentmathsize\plusthree\let\fontbody\scriptscriptface\dodosetmathfamily\scriptscriptfont#1%
+ \let\currentmathsize\plustwo \let\fontbody\scriptface \dodosetmathfamily\scriptfont #1%
+ \let\currentmathsize\plusone \let\fontbody\textface \dodosetmathfamily\textfont #1%
+ \let\currentmathsize\zerocount
+ \let\fontbody\savedfontbody
+ \autofontsizefalse}
\appendtoks
- \dosetsymbfamily\mrfam\textface\scriptface\scriptscriptface\c!mr
- \dosetsymbfamily\mifam\textface\scriptface\scriptscriptface\c!mi
- \dosetsymbfamily\syfam\textface\scriptface\scriptscriptface\c!sy
- \dosetsymbfamily\exfam\textface\textface \textface \c!ex
- \dosetsymbfamily\mafam\textface\scriptface\scriptscriptface\c!ma
- \dosetsymbfamily\mbfam\textface\scriptface\scriptscriptface\c!mb
- \dosetsymbfamily\mcfam\textface\scriptface\scriptscriptface\c!mc
-% \dosetsymbfamily\mdfam\textface\scriptface\scriptscriptface\c!md % also ?
-\to \symbstrategies
-
-\def\dosetsymbfamily#1#2#3#4#5%
- {\let\savedfontbody\fontbody
- \let\fontfamily#5%
- \let\fontbody #4\dodosetsymbfamily\scriptscriptfont#1%
- \let\fontbody #3\dodosetsymbfamily \scriptfont#1%
- \let\fontbody #2\dodosetsymbfamily \textfont#1%
- \let\fontbody\savedfontbody}
-
-\def\dodosetsymbfamily#1#2%
- {\ifcsname\fontclass\fontbody\c!mm\fontfamily\fontalternative\fontsize\endcsname
- \csname\fontclass\fontbody\c!mm\fontfamily\fontalternative\fontsize\endcsname
- #1#2\font
- \else\ifcsname\fontbody\c!mm\fontfamily\fontalternative\fontsize\endcsname
- \csname\fontbody\c!mm\fontfamily\fontalternative\fontsize\endcsname
- #1#2\font
- \fi\fi}
+ \dosetmathfamily\mrfam\c!mr
+ %\dosetmathfamily\mbfam\c!mb % some day, only when defined, else equivalent to 0
+\to \mathstrategies
%D All used styles, like rm, ss and tt, are saved in a comma
%D separated list. Appart from practical limitations one can
%D define as many styles as needed.
-\let\stylelist=\empty
+\def\fontrelativesizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small}
-\def\fontsizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small}
-
-%D \macros
-%D {magfactor,magfactorhalf}
-%D
%D There are several ways to specify a font. Three of them are
%D pure \TeX\ ones, the fourth one is new:
%D
%D \starttyping
%D \font\name=cmr12
%D \font\name=cmr12 at 10pt
-%D \font\name=cmr12 scaled \magstep2
+%D \font\name=cmr12 scaled 2
%D \font\name=cmr12 sa 1.440
%D \stoptyping
%D
%D The non||\TEX\ alternative \type{sa} stands for {\em scaled
%D at}. This means as much as: scale the bodyfontsize with this
-%D factor. The value 1.440 in this example is derived
-%D from the \type{\magstep}'s as mentioned in
-%D \in{table}[tab:magstep]. We therefore introduce
-%D \type{\magfactor} as an alternative for \type{\magstep}.
-%D
-%D \placetable[here][tab:magstep]
-%D {Factors to be used with \type{sa.}}
-%D \starttable[|c|c|c|]
-%D \HL
-%D \NC \bf magstep \NC \bf equivalent \NC \bf factor \NC\SR
-%D \HL
-%D \NC 1 \NC \type{\magfactor1} \NC 1.200 \NC\FR
-%D \NC 2 \NC \type{\magfactor2} \NC 1.440 \NC\MR
-%D \NC 3 \NC \type{\magfactor3} \NC 1.728 \NC\MR
-%D \NC 4 \NC \type{\magfactor4} \NC 2.074 \NC\MR
-%D \NC 5 \NC \type{\magfactor5} \NC 2.488 \NC\LR
-%D \HL
-%D \stoptable
-
-\def\magstep#1% \relax removed, otherwise space after it sticks, else added
- {\ifcase#1 \@m\or1200\or1440\or1728\or2074\or2488\or\@m\fi}
-
-\def\magstephalf
- {1095}
-
-\def\magfactor#1%
- {\ifcase#1 1.000\or1.200\or1.440\or1.728\or2.074\or2.488\or1\fi}
-
-\def\magfactorhalf
- {1.095}
-
-%D These macros enable the use of definitions like \type{sa
-%D \magfactor3} which saves us both (mis|)|calculations and
-%D potential mistypings.
+%D factor. The scaled option is not that useful as one needs to
+%D know the design size.
%D
%D Because \type {sa} (scaled at) and \type {mo} (mapped on)
%D are not low level \TEX\ supported alternatives, we have to
@@ -1146,9 +553,25 @@
{\edef\relativefontsize
{\ifcsname\fontclass#1\s!rscale\endcsname
\csname\fontclass#1\s!rscale\endcsname
+ \else\ifcsname\defaultfontclass#1\s!rscale\endcsname
+ \csname\defaultfontclass#1\s!rscale\endcsname
\else
\defaultrelativefontsize
- \fi}}
+ \fi\fi}}
+
+% \letvalue{\s!default\s!rscale}\defaultrelativefontsize
+%
+% \def\checkrelativefontsize#1%
+% {\edef\relativefontsize
+% {\csname
+% \ifcsname\fontclass#1\s!rscale\endcsname
+% \fontclass#1%
+% \else\ifcsname\defaultfontclass#1\s!rscale\endcsname
+% \defaultfontclass#1%
+% \else
+% \s!default
+% \fi\fi
+% \s!rscale\endcsname}}
%D We also save:
@@ -1159,6 +582,38 @@
{\executeifdefined{\fontclass\c!mm\s!text}\empty}
%D Scaling macros:
+%D
+%D This system is somewhat complicated by two (possible conflicting)
+%D demands:
+%D
+%D \startitemize
+%D \item We support wildcards like \type {sa *} which will adapt
+%D to the current size. This is also the default specification.
+%D \item We support named scales like \type {sa d}; beware: \type
+%D {x} and \type {xx} are valid scales but they are not alway
+%D the same as the ones used in for instance \type {\bfx} because
+%D there the sized come from the bodyfont environment. In the
+%D future there maybe a switch that also honors the environment
+%D in named scales.
+%D \stopitemize
+
+%D Keep in mind that the smaller sizes are just for text super and
+%D subscripts while larger sizes can be used in titles where for
+%D instance math follows the size.
+
+% b:x{\definedfont[SerifBold sa b]x}{\bfb x $x^x$}\par
+% 1:x{\definedfont[SerifBold sa 1]x}{\bf x $x^x$}\par
+% x:x{\definedfont[SerifBold sa x]x}{\bfx x $x^x$}\par
+% xx:x{\definedfont[SerifBold sa xx]x}{\bfxx x $x^x$}\par
+%
+% *:x{\definedfont[Serif sa *]x}\par
+% 1:x{\definedfont[Serif sa 1]x}\par
+% 2:x{\definedfont[Serif sa 2]x}\par
+% 3:x{\definedfont[Serif sa 3]x}\par
+% 4:x{\definedfont[Serif sa 4]x}\par
+% 5:x{\definedfont[Serif sa 5]x}\par
+%
+% {\definedfont[cmbx10 at 10pt]x\definedfont[cmbx8 at 10pt]x}
\def\safontscale{\number\dimexpr\localabsolutefontsize\relax}
\def\mofontscale{\number\dimexpr\setmappedfontsize\localabsolutefontsize\relax}
@@ -1171,29 +626,39 @@
\newdimen\scaledfontsize
\newtoks\everydefinefont
+\def\currentfontbodysize
+ {\ifcsname\??ft\s!default\somefontsize\endcsname
+ \csname\??ft\s!default\somefontsize\endcsname
+ \else
+ \somefontsize
+ \fi}
+
\def\lowleveldefinefont#1#2% #2 = cs
- {\ctxlua{fonts.define.command_1("\luaescapestring{#1}")}% the escapestring catches at \somedimen
+ {%
+ \ctxlua{fonts.define.command_1("\luaescapestring{#1}")}% the escapestring catches at \somedimen
% sets \scaledfontmode and \somefontname and \somefontsize
\ifcase\scaledfontmode\relax
- % none
+ % none, avoid the designsize if possible
\scaledfontsize-1000\scaledpoint
\or
% at
\scaledfontsize\somefontsize
\or
% sa
- \scaledfontsize\localabsolutefontsize
- \scaledfontsize\ifcsname\??ft\s!default\somefontsize\endcsname\csname\??ft\s!default\somefontsize\endcsname\else\somefontsize\fi\scaledfontsize
+ \scaledfontsize\localabsolutefontsize\relax
+ \scaledfontsize\currentfontbodysize\scaledfontsize
\or
% mo
\scaledfontsize\setmappedfontsize\localabsolutefontsize
- \scaledfontsize\ifcsname\??ft\s!default\somefontsize\endcsname\csname\??ft\s!default\somefontsize\endcsname\else\somefontsize\fi\scaledfontsize
+ \scaledfontsize\currentfontbodysize\scaledfontsize
\or
- % scaled
+ % scaled, don't use this one as it's unpredictable
\scaledfontsize-\somefontsize\scaledpoint
\fi
\scaledfontsize\localrelativefontsize\scaledfontsize
- \ifautofontsize\scaledfontsize\currentfontbodyscale\scaledfontsize\fi
+ \ifautofontsize
+ \scaledfontsize\currentfontbodyscale\scaledfontsize
+ \fi
\edef\somefontspec{at \number\scaledfontsize sp}%
\edef\somefontfile{\truefontname\somefontname}%
\ifx\somefontfile\s!unknown
@@ -1209,7 +674,9 @@
"\@@fontclassfeatures",
"\@@fontfeatures",
"\@@fontclassfallbacks",
- "\@@fontfallbacks"
+ "\@@fontfallbacks",
+ \number\currentmathsize,
+ \number\dimexpr\textface\relax
)}%
\edef\somefontspec{at \somefontsize}% we need the resolved designsize (for fallbacks)
\expandafter\let\expandafter\lastrawfontcall\csname#2\endcsname
@@ -1219,12 +686,48 @@
{\edef\@@fontclassfeatures {\ifcsname\fontclass\s!features \endcsname\csname\fontclass\s!features \endcsname\fi}%
\edef\@@fontclassfallbacks{\ifcsname\fontclass\s!fallbacks\endcsname\csname\fontclass\s!fallbacks\endcsname\fi}}
+% resolve
+
+\def\@@thefeaturesyes#1%
+ {\ifcsname\??ff\fontclass#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff\fontclass#1\s!features \endcsname\else
+ \ifcsname\??ff #1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff #1\s!features \endcsname\else
+ \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefeaturesyes \csname\??ff\fontclass #1\endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesyes \csname\??ff #1\endcsname\else
+ \let \@@fontfeatures \empty \fi\fi\fi\fi}
+
+\def\@@thefallbacksyes#1%
+ {\ifcsname\??ff\fontclass#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff\fontclass#1\s!fallbacks\endcsname\else
+ \ifcsname\??ff #1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff #1\s!fallbacks\endcsname\else
+ \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefallbacksyes\csname\??ff\fontclass #1\endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksyes\csname\??ff #1\endcsname\else
+ \let \@@fontfallbacks \empty \fi\fi\fi\fi}
+
+\def\@@thefeaturesnop#1%
+ {\ifcsname\??ff#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff#1\s!features \endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesnop \csname\??ff #1\endcsname\else
+ \let \@@fontfeatures \empty \fi\fi}
+
+\def\@@thefallbacksnop#1%
+ {\ifcsname\??ff#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff#1\s!fallbacks\endcsname\else
+ \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksnop\csname\??ff #1\endcsname\else
+ \let \@@fontfallbacks \empty \fi\fi}
+
+\def\updatefontparametersyes
+ {\@@thefeaturesyes \somefontname
+ \@@thefallbacksyes\somefontname}
+
+\def\updatefontparametersnop
+ {\@@thefeaturesnop \somefontname
+ \@@thefallbacksnop\somefontname}
+
+\def\updatefontparameters
+ {\ifx\fontclass\empty\updatefontparametersnop\else\updatefontparametersyes\fi}
+
\let\@@fontclassfeatures \empty
\let\@@fontclassfallbacks\empty
\let\@@fontfallbacks\empty
\let\@@fontfeatures \empty
-\let\@@skewchar \empty
\let\@@hyphenchar \empty % todo, will go to encoding
%D This brings down maps processing from 466 to 309 seconds
@@ -1334,14 +837,6 @@
%D We also accept \type{sa a}||\type{sa d} as specification.
-%D The duplicate font definition, using the ever the same dummy
-%D font name, results in less fuzzy error messages. In the log
-%D file, for instance when overfull boxes are reported, the
-%D simple keyword `font' replaces the \TEX\ ordinated name. The
-%D latter can be too misleading, due to the fact that \TEX\ has
-%D a rather optimized font memory management. Thanks to Taco
-%D for helping me sort this out.
-
%D \macros
%D {definefontsynonym, doifelsefontsynonym,
%D expandfontsynonym, truefontname, truefontdata}
@@ -1366,47 +861,64 @@
\def\definefontsynonym[#1]#2[#3]%
{\edef\@@fontname{#1}%
\edef\@@fontfile{#3}%
- \doifnextcharelse[\dodefinefontsynonym\nodefinefontsynonym}
-
-\def\nodefinefontsynonym
- {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile}
-
-\def\dodefinefontsynonym[#1]%
- {\edef\@@fontdata{#1}%
- \ifx\@@fontdata\empty
- \nodefinefontsynonym
+ \ifx\fontclass\empty
+ \expandafter\dodefinefontsynonymnop
\else
- \ifx\fontclass\empty
- \getfontparameters
- \else
- \getglobalfontparameters
- \fi
- \ifcsname\??ff\@@fontfile\s!features\endcsname
- \@EA\edef\csname\??ff\fontclass\@@fontname\endcsname{\@@fontfile*\csname\??ff\@@fontfile\s!features\endcsname}%
- \@EA\let\csname\??ff\@@fontfile\s!features\endcsname\undefined
- \else
- \nodefinefontsynonym
- \fi
+ \expandafter\dodefinefontsynonymyes
\fi}
-\def\getfontparameters
- {\expandafter\dogetfontparameter\@@fontdata,]=,}
+\def\dodefinefontsynonymnop
+ {\@EA\let\csname\??ff\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
+ \doifnextoptionalelse\dododefinefontsynonymnop\nonodefinefontsynonymnop}
+
+\def\dodefinefontsynonymyes
+ {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
+ \doifnextoptionalelse\dododefinefontsynonymyes\nonodefinefontsynonymyes}
+
+\def\dododefinefontsynonymnop[#1]%
+ {\let\@@ff@@features \undefined
+ \let\@@ff@@fallbacks\undefined
+ \expandafter\dogetfontparameternop#1,]=,}
-\def\getglobalfontparameters
- {\expandafter\dogetglobalfontparameter\@@fontdata,]=,}
+\def\dododefinefontsynonymyes[#1]%
+ {\let\@@ff@@features \undefined
+ \let\@@ff@@fallbacks\undefined
+ \expandafter\dogetfontparameteryes#1,]=,}
-\def\dogetfontparameter#1=#2,%
- {\if]#1\else
- \expandafter\def\csname\??ff\@@fontfile#1\endcsname{#2}%
- \expandafter\dogetfontparameter
+\def\dogetfontparameternop#1=#2,%
+ {\if]#1%
+ \dodododefinefontsynonymnop
+ \else
+ \expandafter\def\csname @@ff@@#1\endcsname{#2}%
+ \expandafter\dogetfontparameternop
\fi}
-\def\dogetglobalfontparameter#1=#2,%
- {\if]#1\else
- \expandafter\gdef\csname\??ff\@@fontfile#1\endcsname{#2}%
- \expandafter\dogetglobalfontparameter
+\def\dogetfontparameteryes#1=#2,%
+ {\if]#1%
+ \dodododefinefontsynonymyes
+ \else
+ \expandafter\def\csname @@ff@@#1\endcsname{#2}%
+ \expandafter\dogetfontparameteryes
\fi}
+% hm, was wrong, class/global reversed
+
+\def\nonodefinefontsynonymnop
+ {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined
+ \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined}
+
+\def\nonodefinefontsynonymyes
+ {\global\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined
+ \global\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined}
+
+\def\dodododefinefontsynonymnop
+ {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features
+ \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks}
+
+\def\dodododefinefontsynonymyes
+ {\global\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features
+ \global\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks}
+
\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater
\def\setupfontsynonym
@@ -1423,20 +935,51 @@
\fi
\fi}
-\def\truefontdata#1#2%
- {\ifcsname\??ff#1#2\endcsname
- % raw(Regular) raw(key)
- \csname\??ff#1#2\endcsname
- \else\ifcsname\??ff\fontclass#1\endcsname
- % exp(palatino Regular) raw(key)
- \expandafter\truefontdata\csname\??ff\fontclass#1\endcsname#2%
- \else\ifcsname\??ff#1\endcsname
- % exp(Regular) raw(key)
- \expandafter\truefontdata\csname\??ff#1\endcsname#2%
- \else\ifcsname\??ff#2\endcsname
- % raw(key)
- \csname\??ff#2\endcsname
- \fi\fi\fi\fi}
+% \def\truefontname#1%
+% {\@EA\dotruefontname#1*\empty*\relax}
+%
+% \def\dotruefontname#1*#2#3*#4\relax
+% {\ifcsname\??ff\fontclass#1\endcsname
+% \ifx#2\empty
+% \@EA\truefontname\csname\??ff\fontclass#1\endcsname
+% \else
+% \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3%
+% \fi
+% \else\ifcsname\??ff#1\endcsname
+% \ifx#2\empty
+% \@EA\truefontname\csname\??ff#1\endcsname
+% \else
+% \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3%
+% \fi
+% \else
+% #1\ifx#2\empty\else*#2#3\fi
+% \fi\fi}
+%
+% \def\redotruefontname#1%
+% {\@EA\dodotruefontname#1*\relax}
+%
+% \def\dodotruefontname#1*#2\relax
+% {\ifcsname\??ff\fontclass#1\endcsname
+% \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname
+% \else\ifcsname\??ff#1\endcsname
+% \@EA\redotruefontname\csname\??ff#1\endcsname
+% \else
+% #1%
+% \fi\fi}
+%
+% \def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1)
+% {\ifcsname\??ff\fontclass#2\endcsname
+% \expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}%
+% \fi}
+%
+% \def\doifelsefontsynonym#1%
+% {\ifcsname\??ff\fontclass#1\endcsname
+% \expandafter\firstoftwoarguments
+% \else
+% \expandafter\secondoftwoarguments
+% \fi}
+
+% maybe we need to stick in one branch
\def\truefontname#1%
{\@EA\dotruefontname#1*\empty*\relax}
@@ -1448,6 +991,12 @@
\else
\@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3%
\fi
+ \else\ifcsname\??ff\defaultfontclass#1\endcsname
+ \ifx#2\empty
+ \@EA\truefontname\csname\??ff\defaultfontclass#1\endcsname
+ \else
+ \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname*#2#3%
+ \fi
\else\ifcsname\??ff#1\endcsname
\ifx#2\empty
\@EA\truefontname\csname\??ff#1\endcsname
@@ -1456,7 +1005,7 @@
\fi
\else
#1\ifx#2\empty\else*#2#3\fi
- \fi\fi}
+ \fi\fi\fi}
\def\redotruefontname#1%
{\@EA\dodotruefontname#1*\relax}
@@ -1464,23 +1013,29 @@
\def\dodotruefontname#1*#2\relax
{\ifcsname\??ff\fontclass#1\endcsname
\@EA\redotruefontname\csname\??ff\fontclass#1\endcsname
+ \else\ifcsname\??ff\defaultfontclass#1\endcsname
+ \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname
\else\ifcsname\??ff#1\endcsname
\@EA\redotruefontname\csname\??ff#1\endcsname
\else
#1%
- \fi\fi}
+ \fi\fi\fi}
\def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1)
{\ifcsname\??ff\fontclass#2\endcsname
\expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}%
- \fi}
+ \else\ifcsname\??ff\defaultfontclass#2\endcsname
+ \expandafter\def\expandafter#1\expandafter{\csname\??ff\defaultfontclass#2\endcsname}%
+ \fi\fi}
\def\doifelsefontsynonym#1%
{\ifcsname\??ff\fontclass#1\endcsname
- \expandafter\firstoftwoarguments
+ \@EA\firstoftwoarguments
+ \else\ifcsname\??ff\defaultfontclass#1\endcsname
+ \@EAEAEA\firstoftwoarguments
\else
- \expandafter\secondoftwoarguments
- \fi}
+ \@EAEAEA\secondoftwoarguments
+ \fi\fi}
% \definetypeface[palatino][rm][serif][palatino,allbold][default]
%
@@ -1498,7 +1053,7 @@
\def\dostartfontclass[#1]%
{\pushmacro\fontclass
- \doifelse{#1}{\v!each}
+ \doifelse{#1}\v!each
{\let\fontclass\empty}
{\doifsomething{#1}{\def\fontclass{#1}}}}
@@ -1510,47 +1065,14 @@
%D
%D A goody:
-\def\tracedfontencoding#1%
- {\ifcsname\??ff#1\s!encoding\endcsname
- \space[\csname\??ff#1\s!encoding\endcsname]%
- \fi}
-
\def\tracedfontname#1%
- {\ifcsname\??ff\fontclass#1\endcsname
- #1\tracedfontencoding{\fontclass#1}\space->\space
- \@EA\tracedfontname\csname\??ff\fontclass#1\endcsname
+ {#1\ifcsname\??ff\fontclass#1\endcsname
+ \@EA\tracedfontname\csname\??ff\fontclass#1\endcsname
\else\ifcsname\??ff#1\endcsname
- #1\tracedfontencoding{#1}\space->\space
- \@EA\tracedfontname\csname\??ff#1\endcsname
- \else
- #1%
+ \@EA\tracedfontname\csname\??ff#1\endcsname
\fi\fi}
%D \macros
-%D {getfontfileparameters}
-%D
-%D For special purposes, one can use the next macro to
-%D access font file characteristics, for instance:
-%D
-%D \starttyping
-%D \getfontfileparameters{Regular}
-%D \stoptyping
-%D
-%D can result in:
-%D
-%D \starttyping
-%D \def\currentfontfileencoding{texnansi}
-%D \stoptyping
-
-% \let\currentfontfileencoding\s!unknown
-% \let\currentfontfilemapping \s!unknown
-% \let\currentfontfilehandling\s!unknown
-
-% \def\getfontfileparameters#1%
-% {\edef\@@truefontname{\truefontname{#1}}%
-% \edef\currentfontfilefeatures{\truefontdata\@@truefontname\s!features}}
-
-%D \macros
%D {definefont}
%D
%D Before we implement the main definition macro, we first show
@@ -1568,14 +1090,23 @@
\def\definefont
{\dotripleempty\dodefinefont}
+% \def\dodefinefont[#1][#2][#3]% [name][spec][1.6 | line=10pt | setup_id]
+% {\doifinstringelse{ }{#2}
+% {\ifthirdargument
+% \unexpanded\setvalue{#1}{\redodefinefont{#1}{#2}{#3}}%
+% \else
+% \unexpanded\setvalue{#1}{\dododefinefont{#1}{#2}}%
+% \fi}
+% {\definefont[#1][#2 sa *][#3]}}
+
+% we moved the unspecified size check to lua
+
\def\dodefinefont[#1][#2][#3]% [name][spec][1.6 | line=10pt | setup_id]
- {\doifinstringelse{ }{#2}
- {\ifthirdargument
- \unexpanded\setvalue{#1}{\redodefinefont{#1}{#2}{#3}}%
- \else
- \unexpanded\setvalue{#1}{\dododefinefont{#1}{#2}}%
- \fi}
- {\definefont[#1][#2 sa *][#3]}}
+ {\ifthirdargument
+ \unexpanded\setvalue{#1}{\redodefinefont{#1}{#2}{#3}}%
+ \else
+ \unexpanded\setvalue{#1}{\dododefinefont{#1}{#2}}%
+ \fi}
\def\redodefinefont#1#2#3%
{\dododefinefont{#1}{#2}%
@@ -1636,11 +1167,6 @@
\the\everyfontswitch
\fi}
-%D I considered checking for mistakenly use of \PLAIN's
-%D \type{\magstep}'s but although it would take only a few
-%D lines of code, this would not add to consistent use. I
-%D therefore removed this check.
-
%D \macros
%D {mapfontsize}
%D
@@ -1673,8 +1199,7 @@
{\dodoubleargument\domapfontsize}
\def\domapfontsize[#1][#2]%
- {\scratchdimen#1\relax % \relax is really needed here
- \setvalue{\??ft*\the\scratchdimen}{#2}}
+ {\setvalue{\??ft*\the\dimexpr#1\relax}{#2}}
\def\setmappedfontsize#1%
{\ifcsname\??ft*#1\endcsname
@@ -1695,26 +1220,25 @@
%D To be documented.
-\let\sizelist\empty
+\let\fontsizelist \empty
+\let\fontalternativelist\empty
+\let\fontstylelist \empty
-\def\definefontsize[#1]% sneller met toks
- {\addtocommalist{#1}\sizelist
- \def\docommand##1%
+\def\checkfontnamecombinations
+ {\def\docommand##1%
{\def\dodocommand####1%
- {\def\dododocommand########1%
- %{\checkbodyfont{}{########1}{####1}{##1}}%
- {\checkbodyfont{########1}{####1}{##1}}%
- \processcommacommand[\stylelist]\dododocommand}%
- \processcommacommand[\alternativelist]\dodocommand}%
- \processcommacommand[\sizelist]\docommand}
-
-\def\alternativetextlist{\c!tf,\c!bf,\c!it,\c!sl,\c!bs,\c!bi,\c!sc}
-\def\alternativemathlist{\c!mr,\c!mi,\c!sy,\c!ex,\c!ma,\c!mb}
+ {\def\dododocommand########1{\checkbodyfont{########1}{####1}{##1}}%
+ \processcommacommand[\fontstylelist]\dododocommand}%
+ \processcommacommand[\fontalternativelist]\dodocommand}%
+ \processcommacommand[\fontsizelist]\docommand}
-\let\alternativelist\alternativetextlist % upward compatible
+\def\definefontsize[#1]% sneller met toks
+ {\addtocommalist{#1}\fontsizelist
+ \checkfontnamecombinations}
-%\definefontsize[\c!a] \definefontsize[\c!b]
-%\definefontsize[\c!c] \definefontsize[\c!d]
+\def\definefontalternative[#1]%
+ {\addtocommalist{#1}\fontalternativelist
+ \checkfontnamecombinations}
%D \macros
%D {currentfontscale,currentfontbodyscale}
@@ -1810,7 +1334,7 @@
\let\bodyfontenvironmentlist\empty
-\newcount\@@fontdefhack
+\newcount\@@fontdefhack % check if this is still needed
\def\@@beginfontdef
{\ifcase\@@fontdefhack
@@ -1843,29 +1367,44 @@
\@EA\dododefinebodyfontenvironment\@EA[\tempbodyfontsize][#1][#3]}%
\@@endfontdef
\else
+ \ifx\fontclass\empty\else
+ \writestatus\m!fonts{beware: fontclass ignored (if needed use: [fontclass][size][settings])}%
+ \fi
+ \pushmacro\fontclass
+ \let\fontclass\empty
\definebodyfontenvironment[\fontclass][#1][#2]% change */*
+ \popmacro\fontclass
\fi}
\def\dododefinebodyfontenvironment[#1][#2][#3]% size class settings
- {\@@beginfontdef
- \doifundefined{\??ft#2#1\c!em} % \s!text goes wrong in testing because
- {\def\docommand##1% % the 12pt alternative will called when
- {\scratchdimen#1\relax % typesetting the test (or so)
- \scratchdimen\csname\??ft\s!default##1\endcsname\scratchdimen
+ {\@@beginfontdef % \s!text goes wrong in testing because the 12pt alternative will called when typesetting the test (or so)
+ \ifcsname\??ft#2#1\c!em\endcsname
+ % we test for em as we assume it to be set
+ \else
+ \def\docommand##1%
+% fails: \def\checkbodyfontenvironment[#1]{! #1 ! \definebodyfontenvironment[\fontclass][#1][]} \setupbodyfont[8.5pt]
+% {\normalizebodyfontsize\csname\??ft\s!default##1\endcsname\dimexpr#1\relax\to\tempbodyfontsize
+% \letvalue{\??ft#2#1##1}\tempbodyfontsize}%
+ {\scratchdimen\csname\??ft\s!default##1\endcsname\dimexpr#1\relax
\normalizebodyfontsize\scratchdimen\to\tempbodyfontsize
- \setevalue{\??ft#2#1##1}{\tempbodyfontsize}}%
- \processcommacommand[\fontsizelist]\docommand
+ \letvalue{\??ft#2#1##1}\tempbodyfontsize}%
+ \processcommacommand[\fontrelativesizelist]\docommand
\copyparameters
[\??ft#2#1][\??ft\s!default]
- [\c!interlinespace,\c!em]}%
+ [\c!interlinespace,\c!em]%
+ \fi
\getparameters[\??ft#2#1][#3]%
\@@endfontdef
% new code, see remark
- \ifloadingfonts \else % only runtime
- \doifundefined{\@size@#1} % only once
- {\letvalue{\@size@#1}\empty % prevent loop
- \defineunknownfont{#1}}% % safeguard
- \fi
+ \ifloadingfonts
+ % only runtime
+ \else\ifcsname\@size@#1\endcsname
+ % only once
+ \else
+ % prevent loop (hence \empty)
+ \letvalue{\@size@#1}\empty
+ \defineunknownfont{#1}%
+ \fi\fi
% so far
\setvalue{\@size@#1}{\docompletefontswitch[#1]}}
@@ -1891,28 +1430,18 @@
\def\checkbodyfontenvironment[#1]%
{\definebodyfontenvironment[\fontclass][#1][]}
+
+\def\checkbodyfontenvironment[#1]%
+ {\ifcsname\??ft\fontclass#1\c!em\endcsname
+ % we test for em as we assume it to be set
+ \else
+ \definebodyfontenvironment[\fontclass][#1][]%
+ \fi}
% this one already catches both define/setup
\def\setupbodyfontenvironment{\definebodyfontenvironment}
-% officially, but not needed (yet):
-%
-% \def\dosetupbodyfontenvironment[#1][#2][#3]% class size settings
-% {\ifthirdargument
-% \localbodyfontsize#2\relax
-% \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize
-% \doifundefinedelse{\??ft#1\normalizedbodyfontsize\c!em}
-% {\definebodyfontenvironment[#1][#2][#3]}%
-% {\getparameters[\??ft#1\normalizedbodyfontsize][#3]}%
-% \else
-% \localbodyfontsize#1\relax
-% \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize
-% \doifundefinedelse{\??ft\normalizedbodyfontsize\c!em}
-% {\definebodyfontenvironment[#1][#2]}%
-% {\getparameters[\??ft\normalizedbodyfontsize][#2]}%
-% \fi}
-
%D Just a couple of interface macros:
\def\bodyfontvariable#1%
@@ -1952,7 +1481,8 @@
%D We show two examples, that show all the alternative
%D scaling options. The \type{\tfa} alternatives can be
%D extended with \type{\bfa}, \type{\slb}, etc. or even
-%D \type{e} and higher alternatives.
+%D \type{e} and higher alternatives. The magic scaled
+%D values are derived from plain \TEX's \type {\magstep}:
%D
%D \starttyping
%D \definebodyfont [12pt] [rm]
@@ -1962,10 +1492,10 @@
%D sl=cmsl12,
%D bi=cmbxti10 at 12pt,
%D bs=cmbxsl10 at 12pt,
-%D tfa=cmr12 scaled \magstep1,
-%D tfb=cmr12 scaled \magstep2,
-%D tfc=cmr12 scaled \magstep3,
-%D tfd=cmr12 scaled \magstep4,
+%D tfa=cmr12 scaled 1.200,
+%D tfb=cmr12 scaled 1.440,
+%D tfc=cmr12 scaled 1.728,
+%D tfd=cmr12 scaled 2.074,
%D sc=cmcsc10 at 12pt]
%D
%D \definebodyfont [12pt,11pt,10pt,9pt,8pt] [rm]
@@ -2026,12 +1556,12 @@
\doifnumberelse{#1}
{\doifassignmentelse{#3}
{% [12pt] [style] [settings]
- \doifundefined{#2}{\expanded{\definefontstyle[#2][#2]}}% new
+ \doifundefined{#2}{\normalexpanded{\noexpand\definefontstyle[#2][#2]}}% new
\processcommalist[#1]{\dododefinebodyfont{#2}{#3}}}
{% [12pt] [style] [identifier]
\dodefinedefaultbodyfont[#1][#2][#3]}} % body style identifier
{% [identifier] [style] [settings] % see ***
- \setvalue{\s!default#1#2}##1##2{\expanded{\xdodefinebodyfont[##1][##2][#3]}}}%
+ \setvalue{\s!default#1#2}##1##2{\normalexpanded{\noexpand\xdodefinebodyfont[##1][##2][#3]}}}%
\else\ifsecondargument
\definebodyfont[#1][\c!rm][#2]%
\else
@@ -2042,9 +1572,8 @@
\fi\fi}
\def\xdodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier
- {%\writestatus{[#1]}{[#2][#3]}%
- \checkrelativefontsize{#2}% rather new, inherit from other defs
- \ifundefined{#2}\expanded{\definefontstyle[#2][#2]}\fi % new
+ {\checkrelativefontsize{#2}% rather new, inherit from other defs
+ \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new
\processcommalist[#1]{\dododefinebodyfont{#2}{#3}}%
\let\relativefontsize\defaultrelativefontsize}
@@ -2055,47 +1584,56 @@
\def\dodododefinebodyfont#1#2#3% style body def
{\dododododefinebodyfont{#1}{#2}[#3]}
-\def\iflocalclassfonts{\ifx\fontclass\empty}
-
-\def\dododododefinebodyfont#1#2[#3#4#5=#6]% style body def
- {\ifundefined{#1#3#4#5}%
- %\checkbodyfont{#2}{#1}{#3#4}{#5}% not \definefontsize[#5]
- \checkbodyfont{#1}{#3#4}{#5}% not \definefontsize[#5]
- \fi
- \iflocalclassfonts
- \letbeundefined{*\fontclass#2#1#3#4#5*}%
- \scratchtoks{#6}%
- \expanded{\unexpanded\noexpand\setvalue{#2#1#3#4#5}%
- {\noexpand\xxdododefinefont{\relativefontsize}{#2}%
- {#2#1#3#4#5}{\the\scratchtoks}}}%
+\def\dododododefinebodyfont
+ {\ifx\fontclass\empty
+ \expandafter\dododododefinebodyfontnop
\else
- %\expanded{\writestatus{defining}{[\fontclass][#2#1#3#4#5] \resolvefontname#6 }}%
- \global\letbeundefined{*\fontclass#2#1#3#4#5*}%
- \scratchtoks{#6}%
- \expanded{\unexpanded\noexpand\setgvalue{\fontclass#2#1#3#4#5}%
- {\noexpand\xxdododefinefont{\relativefontsize}{#2}%
- {#2#1#3#4#5}{\the\scratchtoks}}}%
+ \expandafter\dododododefinebodyfontyes
\fi}
-% \def\checkbodyfont#1#2#3#4% body style alt size / gdef % #4 can be empty
-% {\def\c!!mm{#2}%
-% \ifx\c!!mm\c!mm % prevents \max and alike (re)defs
-% \unexpanded\setgvalue {#2}{\setcurrentfontstyle {#2}}% \rm
-% \unexpanded\setgvalue {#3}{\setcurrentfontalternative {#3}}% \sl
-% \else
-% \unexpanded\setgvalue {#2#4}{\setcurrentfontstylesize {#2}{#4}}% \rma
-% \unexpanded\setgvalue {#3#4}{\setcurrentfontalternativesize {#3}{#4}}% \sla
-% \unexpanded\setgvalue {#2#3#4}{\setcurrentfontstylealternativesize{#2}{#3}{#4}}% \rmsla
-% \unexpanded\setgvalue {#2}{\setcurrentfontstyle {#2}}% \rm
-% \unexpanded\setgvalue {#3}{\setcurrentfontalternative {#3}}% \sl
-% \unexpanded\setgvalue {#2\c!x}{\setcurrentfontxstylealternative {#2}}% \rmx
-% \unexpanded\setgvalue{#2\c!xx}{\setcurrentfontxxstylealternative {#2}}% \rmxx
-% \unexpanded\setgvalue {#3\c!x}{\setcurrentfontxalternative {#3}}% \slx
-% \unexpanded\setgvalue{#3\c!xx}{\setcurrentfontxxalternative {#3}}% \slxx
-% \unexpanded\setgvalue {#2#3}{\setcurrentfontstylealternative {#2}{#3}}% \rmsl
-% \fi}
-%
-% leaner
+\def\dododododefinebodyfontyes#1% style body def
+ {\edef\askedbodyfontstyle{#1}%
+ \ifx\askedbodyfontstyle\c!mm
+ \expandafter\dodefinebodyfontyesmm
+ \else
+ \expandafter\dodefinebodyfontyesxx
+ \fi\askedbodyfontstyle} % we can get rid of #1
+
+\def\dododododefinebodyfontnop#1% style body def
+ {\edef\askedbodyfontstyle{#1}%
+ \ifx\askedbodyfontstyle\c!mm
+ \expandafter\dodefinebodyfontnopmm
+ \else
+ \expandafter\dodefinebodyfontnopxx
+ \fi\askedbodyfontstyle} % we can get rid of #1
+
+\def\dodefinebodyfontnopxx#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \@EA\let\csname*#2#1#3#4#5*\endcsname\undefined
+ \normalprotected\@EA\edef\csname#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}}
+
+\def\dodefinebodyfontyesxx#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \global\@EA\let\csname*\fontclass#2#1#3#4#5*\endcsname\undefined
+ \normalprotected\@EA\xdef\csname\fontclass#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}}
+
+\def\dodefinebodyfontnopmm#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \@EA\let\csname*#2#1#3#4#51*\endcsname\undefined
+ \@EA\let\csname*#2#1#3#4#52*\endcsname\undefined
+ \@EA\let\csname*#2#1#3#4#53*\endcsname\undefined
+ \normalprotected\@EA\edef\csname#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}%
+ \normalprotected\@EA\edef\csname#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}%
+ \normalprotected\@EA\edef\csname#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}}
+
+\def\dodefinebodyfontyesmm#1#2[#3#4#5=#6]% style body def
+ {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
+ \global\@EA\let\csname*\fontclass#2#1#3#4#51*\endcsname\undefined
+ \global\@EA\let\csname*\fontclass#2#1#3#4#52*\endcsname\undefined
+ \global\@EA\let\csname*\fontclass#2#1#3#4#53*\endcsname\undefined
+ \normalprotected\@EA\xdef\csname\fontclass#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}%
+ \normalprotected\@EA\xdef\csname\fontclass#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}%
+ \normalprotected\@EA\xdef\csname\fontclass#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}}
\def\checkbodyfont#1% tests for ttsl mmbf
{\def\c!!mm{#1}%
@@ -2108,9 +1646,9 @@
\def\checkmathbodyfont#1#2#3% style alt size / gdef % #3 can be empty
{%\message{!m #1 #2 #3!}%
% #1 #2 #3 = signal
- \unexpanded\setgvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \mmsla
- \unexpanded\setgvalue {#1}{\setcurrentfontstyle {#1}}% \mm
- \unexpanded\setgvalue {#2}{\setcurrentfontalternative {#2}}}% \sl
+ %unexpanded\setgvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \mmsla
+ \unexpanded\setgvalue {#2}{\setcurrentfontalternative {#2}}% \sl
+ \unexpanded\setgvalue {#1}{\setcurrentfontstyle {#1}}}% \mm
\def\checktextbodyfont#1#2#3% style alt size / gdef % #3 can be empty
{%\message{!t #1 #2 #3!}%
@@ -2144,40 +1682,42 @@
\newif\ifdefiningunknownfont
\def\dodefineunknownfont#1#2%
- {\doifdefined{\??ft\s!default#2}
- {\donetrue
- \scratchdimen#1\relax
- \scratchdimen\csname\??ft\s!default#2\endcsname\scratchdimen
- \normalizebodyfontsize\scratchdimen\to\!!stringa
- \letvalue{\??ft#1#2}\!!stringa}}
+ {\ifcsname\??ft\s!default#2\endcsname
+ \donetrue
+ \normalizebodyfontsize\csname\??ft\s!default#2\endcsname\dimexpr#1\relax\to\tempbodyfontsize
+ \letvalue{\??ft#1#2}\tempbodyfontsize
+ \fi}
\def\dodefineunknownbodyfont#1#2% see ***
- {\doifdefined{\s!default\s!default#2}% somehow related to */*
- {\donetrue
- \getvalue{\s!default\s!default#2}{#1}{#2}}}
+ {\ifcsname\s!default\s!default#2\endcsname % somehow related to */*
+ \donetrue
+ \getvalue{\s!default\s!default#2}{#1}{#2}%
+ \fi}
\def\dodefineunknownsubfont#1#2%
- {\doifundefined{\@size@\getvalue{\??ft#1#2}}
- {\donetrue
- \defineunknownfont{\getvalue{\??ft#1#2}}}}
+ {\ifcsname\@size@\getvalue{\??ft#1#2}\endcsname
+ \else
+ \donetrue
+ \defineunknownfont{\getvalue{\??ft#1#2}}%
+ \fi}
\def\defineunknownfont#1%
{\let\c!savedtext\c!text
\let\c!text\s!text
\donefalse
- \processcommacommand[\fontsizelist]{\dodefineunknownfont{#1}}%
+ \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}%
\let\c!text\c!savedtext
\ifdone
\donefalse
\processcommacommand
- [\stylelist]
+ [\fontstylelist]
{\dodefineunknownbodyfont{#1}}%
\ifdone
\donefalse
\setvalue{\@size@#1}{\docompletefontswitch[#1]}%
\ifdefiningunknownfont \else
\definingunknownfonttrue
- \processcommacommand[\fontsizelist]{\dodefineunknownsubfont{#1}}%
+ \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}%
\definingunknownfontfalse
\fi
\fi
@@ -2238,8 +1778,8 @@
%D size and the local (sometimes in the textflow) size. We
%D store these dimensions in two \DIMENSION\ registers.
-\newdimen\globalbodyfontsize \globalbodyfontsize=12pt
-\newdimen\localbodyfontsize \localbodyfontsize =\globalbodyfontsize
+\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt
+\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize
%D \macros
%D {bodyfontsize}
@@ -2273,34 +1813,41 @@
%D often not the way users specify the bodyfont size. Therefore
%D we also store the normalized value.
-\chardef\fontdigits=1
+\chardef\fontdigits=2 % was 1
\def\normalizebodyfontsize#1\to#2%
- {\scratchdimen#1\relax
- \ifcase\fontdigits\advance\scratchdimen.5\points\fi
- \@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\scratchdimen00\to#2}
+ {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}
-\def\donormalizedbodyfontsize#1.#2#3#4\to#5% \points ?
- {\edef#5%
+\def\donormalizedbodyfontsize#1.#2#3#4#5\to#6% \points ?
+ {\edef#6% not \ifcase#2\else due to \relax adding
{#1%
- \ifcase\fontdigits\or
- \ifcase#2 \else.#2\fi % and not: \ifcase#2\else ...
- \else
- \ifcase#2#3 \else.#2\ifcase#3 \else#3\fi\fi % not: \ifcase#2#3\else ...
+ \ifcase\fontdigits
+ \or \ifcase#2 \else .#2\fi % 1
+ \or \ifcase#2#3 \else .#2\ifcase#3 \else #3\fi\fi % 2
+ \else \ifcase#2#3#4 \else .#2\ifcase#4 \ifcase#3 \else#3\fi \else#3#4\fi\fi % 3
\fi
\s!pt}}
+% not faster, just less tracing
+%
+% \def\setfontdigits#1%
+% {\chardef\fontdigits\ifnum#1>\plusthree\plusthree\else#1\fi\relax
+% \@EA\let\@EA\normalizedbfs\csname normalizedbfs\number\fontdigits\endcsname}
+%
+% \def\normalizebodyfontsize#1\to#2%
+% {\@EA\@EA\@EA\normalizedbfs\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}
+%
+% \setvalue{normalizedbfs0}#1.#2\to #3{\edef#3{#1\s!pt}}
+% \setvalue{normalizedbfs1}#1.#2#3\to #4{\edef#4{#1\ifcase#2 \else.#2\fi\s!pt}}
+% \setvalue{normalizedbfs2}#1.#2#3#4\to #5{\edef#5{#1\ifcase#2#3 \else.#2\ifcase#3 \else#3\fi\fi\s!pt}}
+% \setvalue{normalizedbfs3}#1.#2#3#4#5\to#6{\edef#6{#1\ifcase#2#3#4 \else.#2\ifcase#4 \ifcase#3 \else#3\fi\else#3#4\fi\fi\s!pt}}
+%
+% \setfontdigits2
+
\normalizebodyfontsize\bodyfontsize\to\normalizedglobalbodyfontsize
\normalizebodyfontsize\bodyfontsize\to\normalizedlocalbodyfontsize
\normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize
-%D To be internationalized:
-
-\def\korpsgrootte {\bodyfontsize}
-\def\korpspunten {\bodyfontpoints}
-
-%D some day.
-
%D \macros
%D {fontstyle,fontalternative,fontsize}
%D
@@ -2322,28 +1869,6 @@
\let\fontstyle = \defaultfontstyle
\let\fontsize = \defaultfontsize
-%D {\em The following approach is obsolete.}
-%D
-%D All things related to fonts are grouped into files with
-%D names like \type{font-cmr}. These files are loaded by:
-
-\def\resetfontdefinitionfile[#1]%
- {\letbeundefined{\c!file\f!fontprefix#1}}
-
-\newif\ifloadfontfileonce
-
-\def\doreadfontdefinitionfile#1#2% #1 = set/switch state
- {\doifundefined{\c!file\f!fontprefix#2}%
- {\ifloadfontfileonce
- \letvalue{\c!file\f!fontprefix#2}\empty
- \fi
- \makeshortfilename[\truefilename{\f!fontprefix#2}]%
- \startreadingfile
- \readsysfile\shortfilename
- {\showmessage\m!fonts2{#2}}
- {\showmessage\m!fonts3{#2}}%
- \stopreadingfile}}
-
%D When \type {\loadfontfileoncetrue}, such files are
%D only loaded once! This permits redundant loading, but at
%D the same time forced grouping when we want continuously mix
@@ -2352,8 +1877,10 @@
%D needed to prevent problems with loading files that use this
%D character in numbers.
+% can be made faster (only used internally now)
+
\def\doswitchpoints[#1]%
- {\expanded{\dodoswitchpoints{#1}}}
+ {\normalexpanded{\noexpand\dodoswitchpoints{#1}}}
\def\dodoswitchpoints#1%
{\doifundefined{\@size@#1}
@@ -2363,6 +1890,7 @@
{\getvalue{\@size@#1}%
\localbodyfontsize#1\relax
\normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize
+% \edef\fontbody{\fontbody}% to be tested but we can clean up mkiv further
\checkbodyfontenvironment[\normalizedbodyfontsize]}
{\showmessage\m!fonts4{#1}}}
@@ -2425,17 +1953,29 @@
%D sequence of a session. After the loading job is done, the
%D macro relaxes itself and reset the signal.
+% \appendtoks
+% \to \everysetupdocument
+
+\newconditional\fontsareloaded
+
\def\preloadfonts % never called, needs a clean up
- {\showmessage\m!fonts6{\normalizedbodyfontsize\normalspace\fontstyle}%
- \global\loadingfontsfalse
- \doswitchpoints[\normalizedbodyfontsize]%
- \doswitchstyle[\fontstyle]%
- \the\everybodyfont
- \the\everyglobalbodyfont
- \saveinterlinespace
+ {\global\loadingfontsfalse
+ \ifconditional\fontsareloaded \else
+ \doifmodeelse {*nofonts}
+ {\writestatus\m!fonts{latin modern fonts are not preloaded}}
+ {\writestatus\m!fonts{preloading latin modern fonts}%
+ \usetypescript[modern]%
+ \setuptypeface[modern]%
+ \showmessage\m!fonts6{\normalizedbodyfontsize\normalspace\fontstyle}}%
+ \fi
\global\let\preloadfonts\relax}
-% \prependtoks \preloadfonts \to \everydump % saves .1 s on a DELL P60 - 2GHZ
+% maybe add this to \everystarttext
+%
+% \ifconditional\fontsareloaded\else
+% \usetypescript[modern]%
+% \setuptypeface[modern]%
+% \fi
%D Here comes the main font switching macros. These macros
%D handle changes in size as well as returning to the global
@@ -2446,36 +1986,68 @@
{\restoreglobalbodyfont}
{\processcommacommand[#2]{\dodosetfont{#1}}% ##1 get also passed
\ifloadingfonts\else
+ \global\settrue\fontsareloaded
\doswitchpoints[\normalizedbodyfontsize]%
\doswitchstyle[\fontstyle]%
+ \ifx\defaultfontclass\empty
+ \let\defaultfontclass\fontclass
+ \fi
\fi}%
\chardef\currentxfontsize\zerocount}
\def\dodosetfont#1#2% #1 = set/switch state | check fo rempty, else space
{\doifsomething{#2}{\dododosetfont{#1}{#2}{\showmessage\m!fonts4{#2}}}}
-\def\dododosetfont#1#2#3% #1 = set/switch state
- {\doifnumberelse{#2}
- {\dodododosetfont{#1}{#2}{#3}}
- {\doifdefinedelse{\??ft\normalizedbodyfontsize\interfaced{#2}}
- {\edef\fontstep{\csname\bodyfontvariable\normalizedbodyfontsize\interfaced{#2}\endcsname}%
- \expanded{\dodododosetfont{#1}{\fontstep}}{#3}}
- {\doifelse{#2}\v!reset
- {\let\fontstyle\empty % new 31/7/2006
- \let\fontsize \empty}
- {\doifdefinedelse{\@style@#2}
- {\edef\fontstyle{#2}}
- {\doreadfontdefinitionfile{#1}{#2}}}}}}
+% % % this can be retrofitted in mkii code % % %
+
+% \def\normalizebodyfontsize#1\to#2%
+% {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}
+
+\def\dododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii
+ {\doifnumberelse{#2}\dodododosetfont\redododosetfont{#1}{#2}{#3}}
+
+\def\redododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii
+ {\edef\expandedfontthing{#2}%
+ \def\interfacedfontsize{\normalizedbodyfontsize\interfaced\expandedfontthing}%
+ \ifcsname\??ft\interfacedfontsize\endcsname
+ \edef\fontstep{\csname\bodyfontvariable\interfacedfontsize\endcsname}%
+ \normalexpanded{\noexpand\dodododosetfont{#1}{\fontstep}}{#3}%
+ \else\ifx\expandedfontthing\v!reset
+ \let\fontstyle\empty % new 31/7/2006
+ \let\fontsize \empty
+ \else
+ \ifcsname\@style@\expandedfontthing\endcsname
+ \let\fontstyle\expandedfontthing
+ \else
+ \setcurrentfontclass\expandedfontthing
+ \ifcase#1\relax
+ \let\globalfontclass\globalfontclass
+ \else
+ \let\globalfontclass\fontclass
+ \fi
+ \ifx\fontclass\empty
+ \let\fontstyle\c!rm
+ \else\ifcsname\??tf\fontclass\s!default\endcsname
+ \edef\fontstyle{\csname\??tf\fontclass\s!default\endcsname}%
+ \else
+ \let\fontstyle\c!rm
+ \fi\fi
+ \fi
+ \fi\fi}
\def\dodododosetfont#1#2#3% #1 = set/switch state
- {\scratchdimen#2\relax
- \normalizebodyfontsize\scratchdimen\to\normalizedsetfont
- \doifundefined{\@size@\normalizedsetfont}
- {\defineunknownfont{#2}}%
- \doifdefinedelse{\@size@\normalizedsetfont}
- {\localbodyfontsize\normalizedsetfont
- \let\normalizedbodyfontsize\normalizedsetfont}
- {#3\dosetsubstitutefont{#1}{#2}}}
+ {\normalizebodyfontsize#2\to\normalizedsetfont
+ \ifcsname\@size@\normalizedsetfont\endcsname \else
+ \defineunknownfont{#2}%
+ \fi
+ \ifcsname\@size@\normalizedsetfont\endcsname
+ \localbodyfontsize\normalizedsetfont
+ \let\normalizedbodyfontsize\normalizedsetfont
+ \else
+ #3\dosetsubstitutefont{#1}{#2}%
+ \fi}
+
+% % %
%D In the previous macros we use \type{\currentxfontsize} to
%D hold the current x||size of the font. This enables us to
@@ -2515,8 +2087,15 @@
\let\fontclass\empty \let\globalfontclass\fontclass
+% we need to check the fontclass
+
+\def\registerfontclass#1%
+ {\letgvalue{\@fontclass@#1}\v!yes} % global ?
+
\def\setcurrentfontclass#1%
- {\edef\fontclass{#1}}
+ {\ifcsname\@fontclass@#1\endcsname
+ \edef\fontclass{#1}%
+ \fi}
\let\defaultfontstyle \c!rm
\let\defaultfontalternative \c!tf
@@ -2553,7 +2132,7 @@
% already in sync
\else
\let\bigmathfontsize\fontsize
- \synchronizemath \synchronizetext
+ \synchronizemath
\fi}
\def\checkbigmathsynchronization
@@ -2572,10 +2151,7 @@
\checkbigmathsynchronization}
\def\dosetcurrentfontalternative#1%
- {\edef\fontalternative{#1}%
- \ifmmode % maybe no test, or actually, an option
- \fam\csname\fontalternative\s!fam\endcsname
- \fi}
+ {\edef\fontalternative{#1}}
\def\setcurrentfont#1#2#3#4%
{%\message{[1 #1 #2 #3 #4]}%
@@ -2660,6 +2236,7 @@
\global\let\fontstrategy\dofontstrategy
\the\fontstrategies \relax % \relax still needed ?
\fi
+ \autofontsizefalse
\ifskipfontcharacteristics
\setfontcharacteristics
\the\everyfontswitch
@@ -2675,6 +2252,8 @@
#1\csname\fontclass#2#3#4#5\endcsname \tryingfontfalse
\fi}
+% old sequence
+
\appendtoks \iftryingfont \fontstrategy \autofontsizefalse % --- --- --- --- % pt tt bf a
\fontbody \fontstyle \fontalternative \fontsize
\fi \to \fontstrategies
@@ -2706,7 +2285,6 @@
\prependtoks
\ifsynchronizefonts
\synchronizemath
- \synchronizetext
\synchronizefont % problem: syncs last font
\fi
\to \everybodyfont
@@ -2757,9 +2335,6 @@
% This alterative is not really needed, but for old time's sake
% we keep it there. We can speed it up when needed.
-% \def\setcurrentfontxstylealternative #1{\csname#1\endcsname\tfx}
-% \def\setcurrentfontxxstylealternative#1{\csname#1\endcsname\tfxx}
-
\def\setcurrentfontxstylealternative #1{\csname#1\endcsname\tx}
\def\setcurrentfontxxstylealternative#1{\csname#1\endcsname\txx}
@@ -2808,10 +2383,11 @@
%D \stoptyping
\def\dodefinefontstyle[#1][#2]%
- {\rawdoifinsetelse{#2}{\stylelist}
- {}%\debuggerinfo\m!fonts{unknown style #2}}
- {\addtocommalist{#2}\stylelist
- \showmessage\m!fonts8{#2\space (#1)}}%
+ {\rawdoifinsetelse{#2}{\fontstylelist}
+ {%\debuggerinfo\m!fonts{unknown style #2}%
+ }
+ {%\debuggerinfo\m!fonts8{#2\space (#1)}%
+ \addtocommalist{#2}\fontstylelist}%
% check kan hier
\def\docommand##1%
{\setvalue{\@shortstyle@##1}{#2}%
@@ -2823,25 +2399,9 @@
\def\setfontstyle#1#2% #1:name (roman, romaan) #2:style (rm)
{\edef\fontstyle{#1}%
+ \checkfontnamecombinations
\setcurrentfontstyle\normalizedbodyfontsize}
-\chardef\defaultskewcharmi=127 % '177
-\chardef\defaultskewcharsy= 48 % '60
-
-% \def\dosetskewchar#1%
-% {\skewchar\font\ifx\@@fontskewchar\empty#1\else\@@fontskewchar\fi}
-
-\def\dosetskewchar#1#2%
- {\ifx\@@fontskewchar\empty
- \skewchar\textfont #1#2%
- \skewchar\scriptfont #1#2%
- \skewchar\scriptscriptfont#1#2%
- \else
- \skewchar\textfont #1\@@fontskewchar
- \skewchar\scriptfont #1\@@fontskewchar
- \skewchar\scriptscriptfont#1\@@fontskewchar
- \fi}
-
%D The previous macros show that it's is not always
%D neccessary to define the whole bunch of fonts, take for
%D instance the sequence:
@@ -2878,7 +2438,7 @@
\def\docompletefontswitch[#1]%
{\bodyfontsize#1\relax
- \dimensiontocount\bodyfontsize\bodyfontpoints
+ \dimensiontocount\bodyfontsize\bodyfontpoints % rounded, still used in m-chart
\edef\bodyfontfactor{\withoutpt\the\bodyfontsize}%
\normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize
\dosetbodyfontface \textface \s!text
@@ -2948,8 +2508,7 @@
\def\fastswitchtobodyfont#1%
{\ifcsname\??ft\normalizedbodyfontsize#1\endcsname
- \edef\futurebodyfontsize
- {\csname\??ft\normalizedbodyfontsize#1\endcsname}%
+ \edef\futurebodyfontsize{\csname\??ft\normalizedbodyfontsize#1\endcsname}%
\ifcsname\@size@\futurebodyfontsize\endcsname
\csname\@size@\futurebodyfontsize\endcsname
\localbodyfontsize\futurebodyfontsize\relax
@@ -2958,46 +2517,10 @@
\csname\@style@\fontstyle\endcsname
\the\everybodyfont}
-%D Because the last macro can appear in arguments or be assigned
-%D to parameters, we protect this one for unwanted expansion.
-
-\def\dodosetmathfont#1%
- {\setcurrentfontalternative{#1}%
- % \doifdefinedelse{#1\s!fam} % adapted
- % {\edef\mffam{\getvalue{#1\s!fam}}}
- % {\edef\mffam{\getvalue{\c!nn\s!fam}}}%
- \textfont \mrfam\textfont \mffam
- \scriptfont \mrfam\scriptfont \mffam
- \scriptscriptfont\mrfam\scriptscriptfont\mffam}
-
-\def\domffam#1%
- {\csname\ifcsname#1\s!fam\endcsname#1\else\c!nn\fi\s!fam\endcsname}
-
-\def\mffam
- {\domffam\fontalternative}
-
-\def\dosetmathfont
- {\def\rm{\fam\mrfam}\dodosetmathfont}
-
-\def\enableencodinginmath
- {\appendtoks
- \everyhbox{\mr\everyhbox\emptytoks}%
- \everyvbox{\mr\everyvbox\emptytoks}%
- \to \everymathematics} % was \everymath
-
-% \enableencodinginmath % too untested to enable by default
-
%D \starttyping
%D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$
%D \stoptyping
-%D The font specific features are bound to the filename.
-
-\def\updatefontparameters
- {\edef\@@fontfeatures {\truefontdata\somefontfile\s!features}%
- \edef\@@fontfallbacks{\truefontdata\somefontname\s!fallbacks}%
- \edef\@@fontskewchar {\truefontdata\somefontfile\s!skewchar}} % will be replaced
-
\def\setfontcharacteristics
{\the\everyfont}
@@ -3020,27 +2543,53 @@
{\dotripleargument\dodefinefontfeature}
\def\dodefinefontfeature[#1][#2][#3]%
- {\ctxlua{fonts.define.specify.preset_context("#1","#2","#3")}}
+ {\global\expandafter\chardef\csname\??fq=#1\endcsname
+ \ctxlua{tex.write(fonts.define.specify.preset_context("#1","#2","#3"))}\relax}
\definefontfeature
[default]
- [liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes
+ [%mode=node,%
+ liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes
\definefontfeature
[smallcaps]
- [liga=yes,kern=yes,tlig=yes,trep=yes,smcp=yes] % texligatures=yes,texquotes=yes
+ [%mode=node,%
+ liga=yes,kern=yes,tlig=yes,trep=yes,smcp=yes] % texligatures=yes,texquotes=yes
\definefontfeature
[oldstyle]
- [liga=yes,kern=yes,tlig=yes,trep=yes,onum=yes] % texligatures=yes,texquotes=yes
+ [%mode=node,%
+ liga=yes,kern=yes,tlig=yes,trep=yes,onum=yes] % texligatures=yes,texquotes=yes
-\definefontfeature % no calt
+\definefontfeature
[arabic]
- [mode=node,language=dflt,script=arab,
+ [mode=node,language=dflt,script=arab,ccmp=yes,
init=yes,medi=yes,fina=yes,isol=yes,
- liga=yes,dlig=yes,rlig=yes,clig=yes,
+ liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes,
mark=yes,mkmk=yes,kern=yes,curs=yes]
+\definefontfeature
+ [none]
+ [mode=none,features=off]
+
+\definefontfeature
+ [virtualmath]
+ [mode=base,liga=yes,kern=yes,tlig=yes,trep=yes]
+
+% for the moment here, this will change but we need it for mk.tex
+
+\definefontfeature[math-text] [virtualmath][ssty=no]
+\definefontfeature[math-script] [virtualmath][ssty=1,mathsize=yes]
+\definefontfeature[math-scriptscript][virtualmath][ssty=2,mathsize=yes]
+
+\definefontfeature [math-nostack-text] [math-text] [nostackmath=yes]
+\definefontfeature [math-nostack-script] [math-script] [nostackmath=yes]
+\definefontfeature [math-nostack-scriptscript][math-scriptscript][nostackmath=yes]
+
+% \definefontfeature[mathtext] [math-text]
+% \definefontfeature[mathscript] [math-script]
+% \definefontfeature[mathscriptscript] [math-scriptscript]
+
%D Also new:
% handy for manuals
@@ -3052,32 +2601,9 @@
\definecolor[font:init][r=.75]
\definecolor[font:medi][g=.75]
\definecolor[font:fina][b=.75]
-\definecolor[font:isol][y=.75]
-\definecolor[font:mark][m=.75]
-\definecolor[font:rest][c=.75]
-
-%D goodies:
-%D
-%D \starttyping
-%D \showinstalledfonts[officinasans.*][all]
-%D \showinstalledfonts[officinaserif.*][all]
-%D \showinstalledfonts[officina.*itc.*][all]
-%D
-%D \showinstalledfonts[officina.*itc.*][all,new]
-%D \stoptyping
-
-\def\showinstalledfonts
- {\dodoubleempty\doshowinstalledfonts}
-
-\def\doshowinstalledfonts[#1][#2]%
- {\bgroup
- \def\pattern{#1}%
- \def\all{false}%
- \def\reload{false}%
- \doifnothing\pattern{\def\pattern{.*}}%
- \processallactionsinset[#2][\v!new=>\def\reload{true},\v!all=>\def\all{true}]%
- \ctxlua{fonts.names.table("#1",\reload,\all)}%
- \egroup}
+\definecolor[font:isol][r=.75,g=.75] % [y=.75]
+\definecolor[font:mark][r=.75,b=.75] % [m=.75]
+\definecolor[font:rest][g=.75,b=.75] % [c=.75]
%D Experimental!
@@ -3085,7 +2611,7 @@
{\dodoubleargument\doinstallfontfeature}
\def\doinstallfontfeature[#1][#2]%
- {\ctxlua{fonts.install_feature("#1","#2")}}
+ {\writestatus\m!fonts{installing font features was experimental}} % \ctxlua{fonts.install_feature("#1","#2")}}
%D Not yet in \MKII.
@@ -3099,13 +2625,35 @@
\let\currentfeature\empty
+% ! ! ! very experimental, some test code for idris advanced features ! ! !
+%
+% \startbuffer
+% \definefontfeature[smallcaps][smallcaps][script=latn]
+% \definefontfeature[oldstyle] [oldstyle] [script=latn]
+%
+% \definedfont[name:cambria at 15pt]
+%
+% Hello there {\setff{smallcaps}capped 123 \setff{oldstyle}123!} \blank
+% Hello there {\addff{smallcaps}capped 123 \addff{oldstyle}123!} \blank
+% Hello there {\addff{smallcaps}capped \subff{smallcaps}normal} \blank
+% \stopbuffer
+%
+% \typebuffer \getbuffer
+
\def\featureattribute#1{\ctxlua{tex.sprint(fonts.define.specify.context_number("#1"))}}
\def\setfontfeature #1{\edef\currentfeature{#1}\attribute\zerocount\featureattribute{#1}\relax}
-\def\resetfontfeature#1{\let\currentfeature\empty\attribute\zerocount\zerocount}
+\def\resetfontfeature#1{\let\currentfeature\empty\attribute\zerocount\zerocount} % initial value
-\appendtoks
- \setfontfeature\currentfeature
-\to \everylanguage
+\def\addfontfeaturetoset #1{\ctxlua{fonts.withset("#1", 1)}}
+\def\subtractfontfeaturefromset #1{\ctxlua{fonts.withset("#1",-1)}}
+\def\addfontfeaturetofont #1{\ctxlua{fonts.withfnt("#1", 2)}}
+\def\subtractfontfeaturefromfont#1{\ctxlua{fonts.withfnt("#1",-2)}}
+
+\let\setff\setfontfeature
+\let\addfs\addfontfeaturetoset
+\let\subfs\subtractfontfeaturefromset
+\let\addff\addfontfeaturetofont
+\let\subff\subtractfontfeaturefromfont
%D The next auxilliary macro is an alternative to \type
%D {\fontname}.
@@ -3140,75 +2688,23 @@
\the\everybodyfont} % needed ?
%D \macros
-%D {os,frak, goth, cal}
-%D
-%D Old style numerals can be typeset with \type{\os} and look
-%D like {\os 1234567890} instead of the more common looking
-%D 1234567890.
+%D {os}
%D
-%D On behalf of {\frac Tobias Burnus}, we define some more of
-%D these. Later we will link these names to real file names.
-
-% older
-%
-% \definefont [os] [OldStyle sa *]
-% \definefont [frak] [Fraktur sa *]
-% \definefont [goth] [Gothic sa *]
-% \definefont [cal] [Calligraphic sa *]
-% \definefont [bbd] [Blackboard sa *]
-%
-% newer
+%D In good old \TEX, the old style numerals were often taken
+%D from the math fonts. No longer.
-\def\os {\mathortext{\fam\purefamily {oldstyle}}{\symbolicfont {OldStyle}}}
-\def\frak{\mathortext{\fam\purefamily {fraktur}}{\symbolicfont {Fraktur}}}
-\def\goth{\mathortext{\fam\purefamily {gothic}}{\symbolicfont {Gothic}}}
-\def\cal {\mathortext{\fam\purefamily{calligraphic}}{\symbolicfont{Calligraphic}}}
-\def\bbd {\mathortext{\fam\purefamily {blackboard}}{\symbolicfont {Blackboard}}}
+\definefontfeature
+ [just-os]
+ [mode=node,onum=yes]
-\definefontsynonym [OldStyle] [Serif]
-\definefontsynonym [Fraktur] [Serif]
-\definefontsynonym [Gothic] [Serif]
-\definefontsynonym [Calligraphic] [Serif]
-\definefontsynonym [Blackboard] [Serif]
+% \def\sc{\setfontfeature{smallcaps}}
+\def\os{\setfontfeature{just-os}}
-%D \macros
-%D {fraktur, gothic, calligraphic, blackboard}
-%D
-%D These macros assume that we use text fonts, and not math
-%D families.
+%D Code for swithcing to fraktur and script has also been
+%D changed. We now have an alphabet switcher.
\ifx\mathtext\undefined \let\mathtext\hbox \fi
-\def\fraktur #1{\mathortext\domathtext\donothing{\frak#1}}
-\def\gothic #1{\mathortext\domathtext\donothing{\goth#1}}
-\def\calligraphic#1{\mathortext\domathtext\donothing{\cal #1}}
-\def\blackboard #1{\mathortext\domathtext\donothing{\bbd#1}}
-
-%D Torture test:
-%D
-%D \starttyping
-%D \usetypescript[modern] [texnansi]
-%D \usetypescript[lucida] [texnansi]
-%D \usetypescript[palatino][texnansi]
-%D \usetypescript[times] [texnansi]
-%D \usetypescript[fourier] [ec]
-%D
-%D \startbuffer
-%D \section{\blackboard{T\high{\blackboard{T}}} \blackboard{E}\high{\blackboard{E}} \blackboard{X}\high{\blackboard{X}}}
-%D
-%D {\fontclass: 123 \os123 \cal TEX $\os 123$}
-%D
-%D $\blackboard{T}^{\blackboard{T}} \blackboard{E}^{\blackboard{E}} \blackboard{X}^{\blackboard{X}}$
-%D \blackboard{T}\high{\blackboard{T}} \blackboard{E}\high{\blackboard{E}} \blackboard{X}\high{\blackboard{X}}
-%D \stopbuffer
-%D
-%D {\setupbodyfont[lucida] \getbuffer}
-%D {\setupbodyfont[modern] \getbuffer}
-%D {\setupbodyfont[palatino] \getbuffer}
-%D {\setupbodyfont[times] \getbuffer}
-%D {\setupbodyfont[fourier] \getbuffer}
-%D \stoptyping
-
%D \macros
%D {definebodyfontswitch}
%D
@@ -3264,7 +2760,7 @@
%D in the main bodyfont and style of the document. Returning to
%D the global state can be done with the next macro:
-\let\mainfontclass\empty
+\let\globalfontstyle\c!rm
\def\fullrestoreglobalbodyfont
{\let\fontsize\defaultfontsize
@@ -3420,7 +2916,7 @@
%D \stoptyping
%D
%D We deliberately pass an argument. This enables us to
-%D assign converters that handle one agrument, like
+%D assign converters that handle one argument, like
%D \type{\cap}.
%D
%D By default the first specification is used to set the style,
@@ -3429,43 +2925,11 @@
%D \type{\noconvertfont}. In nested calls, we can restore the
%D conversion by saying \type{\redoconvertfont}.
-% \def\@@dodoconvertfont#1{\csname\@letter@ #1\endcsname}
-% \def\@@donoconvertfont#1{\csname\@noletter@#1\endcsname}
-%
-% \unexpanded\def\dodoconvertfont#1% #2% we need the protection
-% {\doifdefinedelse{\@letter@#1} % in testing
-% {\doifelsenothing{#1}\gobbleoneargument\@@dodoconvertfont}
-% {\doifdefinedelse{#1}\getvalue \firstofoneargument}%
-% {#1}} % {#2}}
-%
-% \let\doconvertfont\dodoconvertfont
-%
-% \def\noconvertfont#1% #2%
-% {\doifdefinedelse{\@noletter@#1}
-% {\doifelsenothing{#1}\gobbleoneargument\@@donoconvertfont}\gobbleoneargument
-% {#1}} % {#2}}
-
-% \def\@@dodoconvertfont{\csname\@letter@ \p!defined\endcsname}
-% \def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname}
-% \def\@@redoconvertfont{\csname \p!defined\endcsname}
-%
-% \unexpanded\def\dodoconvertfont#1% #2% we need the protection
-% {\edef\p!defined{#1}%
-% \ifcsname\@letter@\detokenize\@EA{\p!defined}\endcsname
-% \ifx\p!defined\empty\else\@EAEAEA\@@dodoconvertfont\fi
-% \else
-% \ifcsname\detokenize\@EA{\p!defined}\endcsname\@EAEAEA\@@redoconvertfont\else\@EAEAEA\p!defined\fi
-% \fi} % {#2}}
-%
-% \unexpanded\def\noconvertfont#1% #2%
-% {\edef\p!defined{#1}%
-% \ifcsname\@noletter@\detokenize\@EA{\p!defined}\endcsname
-% \ifx\p!defined\empty\else\@EAEAEA\@@donoconvertfont\fi
-% \fi} % {#2}}
+% subtle ... \expandafter is needed else problems with lookahead caps
-\def\@@dodoconvertfont{\csname\@letter@ \p!defined\endcsname\gobbleoneargument}
+\def\@@dodoconvertfont{\csname\@letter@ \p!defined\expandafter\endcsname\gobbleoneargument}
\def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname}
-\def\@@redoconvertfont{\csname \p!defined\endcsname\gobbleoneargument}
+\def\@@redoconvertfont{\csname \p!defined\expandafter\endcsname\gobbleoneargument}
% beware: p!defined can contain crap like \edef crap {...} and such
% so we need to pass #1 as well
@@ -3501,11 +2965,8 @@
%D Extras:
-\unexpanded\def\dontconvertfont
- {\let\doconvertfont\noconvertfont}
-
-\unexpanded\def\redoconvertfont
- {\let\doconvertfont\dodoconvertfont}
+\unexpanded\def\dontconvertfont{\let\doconvertfont\noconvertfont}
+\unexpanded\def\redoconvertfont{\let\doconvertfont\dodoconvertfont}
%D These commands are not grouped! Grouping is most probably
%D done by the calling macro's and would lead to unnecessary
@@ -3534,13 +2995,7 @@
%D or even better:
-% \def\doemphasistypeface#1#2%
-% {\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!slanted#1%
-% {\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!italic #2%
-% {\doifelsevalue{\??ft \normalizedbodyfontsize\c!em}\v!slanted#1%
-% {\doifvalue {\??ft \normalizedbodyfontsize\c!em}\v!italic #2}}}}
-
-\def\doemphasistypeface#1#2%
+\def\doemphasistypeface#1#2% slow
{\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!slanted
{#1}%
{\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!italic
@@ -3553,6 +3008,25 @@
{\getvalue{\??ft\normalizedbodyfontsize\c!em}}}}
{\getvalue{\??ft\fontclass\normalizedbodyfontsize\c!em}}}}}
+% \def\doemphasistypeface#1#2%
+% {\edef\emphasizedtypeface{\csname\??ft\fontclass\normalizedbodyfontsize\c!em\endcsname}%
+% \ifx\emphasizedtypeface\v!slanted
+% #1%
+% \else\ifx\emphasizedtypeface\v!italic
+% #2%
+% \else\ifx\emphasizedtypeface\v!empty
+% \edef\emphasizedtypeface{\csname\??ft\normalizedbodyfontsize\c!em\endcsname}%
+% \ifx\emphasizedtypeface\v!slanted
+% #1%
+% \else\ifx\emphasizedtypeface\v!italic
+% #2%
+% \else
+% \getvalue\emphasizedtypeface
+% \fi\fi
+% \else
+% \getvalue\emphasizedtypeface
+% \fi\fi\fi}
+
\def\emphasistypeface{\doemphasistypeface\sl\it}
\def\emphasisboldface{\doemphasistypeface\bs\bi}
@@ -3571,15 +3045,15 @@
\setfalse\emneeded
\fi
\setemphasisboldface % new
- \ifx\fontalternative\c!it % \ifnum\fam=\itfam
+ \ifx\fontalternative\c!it
\def\emphasistypeface{\it}\tf
- \else\ifx\fontalternative\c!sl % \ifnum\fam=\slfam
+ \else\ifx\fontalternative\c!sl
\def\emphasistypeface{\sl}\tf
- \else\ifx\fontalternative\c!bf % \ifnum\fam=\bffam
+ \else\ifx\fontalternative\c!bf
\emphasisboldface
- \else\ifx\fontalternative\c!bs % \ifnum\fam=\bsfam
+ \else\ifx\fontalternative\c!bs
\def\emphasisboldface{\bs}\bf
- \else\ifx\fontalternative\c!bi % \ifnum\fam=\bifam
+ \else\ifx\fontalternative\c!bi
\def\emphasisboldface{\bi}\bf
\else
\emphasistypeface
@@ -3605,9 +3079,9 @@
\unexpanded\def\bf
{%\relax
\let\bf\relax % new
- \ifx\fontalternative\c!it % \ifnum\fam=\itfam
+ \ifx\fontalternative\c!it
\bi
- \else\ifx\fontalternative\c!sl % \ifnum\fam=\slfam
+ \else\ifx\fontalternative\c!sl
\bs
\else
\normalbf
@@ -3619,24 +3093,35 @@
%D look for something that looks like a dash, in which case we
%D don't correct.
-\let\italiccorrection=\/
+\let\italiccorrection=\/ % tex primitive
\def\emphasiscorrection
{\ifhmode
\expandafter\emphasislook
\fi}
+% \def\emphasislook
+% {\begingroup
+% \beginrobusttest
+% \futurelet\next\emphasistest}
+
+% \def\emphasistest
+% {\normalifcat\noexpand\next,%
+% \endrobusttest\expandafter\doemphasiscorrection
+% \normalelse
+% \endrobusttest\expandafter\dododoemphasiscorrection
+% \normalfi}
+
\def\emphasislook
{\begingroup
- \beginrobusttest
\futurelet\next\emphasistest}
\def\emphasistest
- {\normalifcat\noexpand\next,%
- \endrobusttest\expandafter\doemphasiscorrection
- \normalelse
- \endrobusttest\expandafter\dododoemphasiscorrection
- \normalfi}
+ {\ifcat\noexpand\next,% still ok?
+ \expandafter\doemphasiscorrection
+ \else
+ \expandafter\dododoemphasiscorrection
+ \fi}
\def\doemphasiscorrection
{\futurelet\next\dodoemphasiscorrection}
@@ -3792,11 +3277,6 @@
%D \stopbuffer
%D
%D \typebuffer
-%D
-%D Below the table the name, encoding, mapping and handling are
-%D shown. Special characters like the \type {\skewchar} and
-%D \type {\hyphenchar} als marked.
-%D
%D \getbuffer
% to be internationalized
@@ -3954,49 +3434,6 @@
%D The shape as well as the size is adapted to the current
%D environment.
-%D Fonts can only be used when loaded. In \CONTEXT\ we
-%D postpone the loading of fonts, even when we load \PLAIN.
-%D This means that we have to redefine one of the \PLAIN\
-%D macros. Let's tell that to the user first:
-
-\writestatus{loading}{Postponed Plain TeX Font Definitions}
-
-%D \macros
-%D {bordermatrix}
-%D
-%D In \PLAIN\ \TEX\ the width of a parenthesis is stored in
-%D the \DIMENSION\ \type{\p@renwd}. This value is derived from
-%D the width of \type{\tenrm B}, so let's take care of it now:
-
-\let\normalbordermatrix=\bordermatrix
-
-\def\bordermatrix%
- {\bgroup
- \setbox0\hbox{\getvalue{\textface\c!mm\c!ex}B}%
- \global\p@renwd\wd0\relax
- \egroup
- \normalbordermatrix}
-
-%D Because we want to be as \PLAIN\ compatible as possible, we
-%D make most of \PLAIN's font mechanisme available to the
-%D \CONTEXT\ user.
-
-\def\setplainfonts#1#2%
- {\setvalue {ten#1}{\getvalue{\!!tenpoint #2}}%
- \setvalue{seven#1}{\getvalue{\!!sevenpoint#2}}%
- \setvalue {five#1}{\getvalue{\!!fivepoint #2}}}
-
-\setplainfonts {\c!rm} {\c!rm\c!tf}
-\setplainfonts {\c!bf} {\c!rm\c!bf}
-\setplainfonts {\c!sl} {\c!rm\c!sl}
-\setplainfonts {\c!it} {\c!rm\c!it}
-\setplainfonts {\c!tt} {\c!rm\c!tt}
-\setplainfonts {\c!sy} {\c!mm\c!sy}
-\setplainfonts {\c!ex} {\c!mm\c!ex}
-\setplainfonts {\c!i} {\c!mm\c!mi}
-
-\let\setplainfonts=\undefined
-
%D \macros
%D {ss, SS, sz}
%D
@@ -4008,81 +3445,11 @@
\ifx\undefined\SS \let\SS=\ss \fi
\ifx\undefined\sz \let\sz=\ss \fi
-%D \macros
-%D {xi}
-%D
-%D We are going to redefine \type{\xi}, but fortunately this
-%D is a math mode character, so we can just say:
-
-\let\normalxi=\xi
-
-%D \macros
-%D {smashaccent}
-%D
-%D When we let \TEX\ put an accent on top of a character, such
-%D composed characters can get more height that height of a
-%D standard \type{\strut}. The next macro takes care of such
-%D unwanted compositions.
-%D
-%D We need to reach over the number that specifies the accent,
-%D and in doing so we use \type{\scratchcounter} as a placeholder
-%D because it accepts 8 bit numbers in octal, decimal or
-%D hexadecimal format. Next we set the height of the accented
-%D character to the natural height of the character.
-
-\unexpanded\def\smashaccent#1%
- {\dontleavehmode
- \bgroup
- \setbox\scratchbox\hbox{#1}%
- \ifdim\ht\scratchbox>\strutheight\relax\ht\scratchbox\strutheight\fi
- \ifdim\dp\scratchbox>\strutdepth \relax\dp\scratchbox\strutdepth \fi
- \box\scratchbox
- \egroup}
-
-%D For instance we can say:
-%D
-%D \starttyping
-%D \smashaccent{\"Uberhaupt}
-%D \stoptyping
-%D
-%D But normally one will use it as a prefix in definitions.
-%D The difference is in the height:
-%D
-%D \leavevmode\ruledhbox
-%D {\ruledhbox{\smashaccent{\"U}berhaupt}\quad
-%D oder\quad
-%D \ruledhbox{\"Uberhaupt}}
-
-%D \macros
-%D {moveaccent}
-%D
-%D Exact positioning of accents can be realized by saying:
-%D
-%D \starttyping
-%D \moveaccent{-.1ex}{\"u}berhaupt
-%D \stoptyping
-%D
-%D Again, this one will mostly used as a prefix in definitions.
-%D Here the difference is in the position:
-%D
-%D \leavevmode\ruledhbox
-%D {\ruledhbox{\moveaccent{-.1ex}{\"}Uberhaupt}\quad
-%D oder\quad
-%D \ruledhbox{\"Uberhaupt}}
-
-\unexpanded\def\moveaccent#1#2%
- {\smashaccent
- {\dimen0\exheight
- \dimen2\dimen0
- \advance\dimen2 -#1%
- \exheight\dimen2
- #2\relax
- \exheight\dimen0}}
-
-%D Personally I think that using \TEX\ is complicated by the
-%D way fonts are handled. Apart from the many encodings, we
-%D also deal with different naming schemes. Confronted with
-%D this problem, I decided to change the definitions into:
+%D Personally I think that using \TEX\ macro packages is
+%D complicated by the way fonts are handled. Apart from the
+%D many encodings, we also deal with different naming schemes.
+%D Confronted with this problem, I decided to change the
+%D definitions into:
%D
%D \starttyping
%D \definebodyfont [12pt] [rm] [tf=Times-Roman at 12pt]
@@ -4244,22 +3611,31 @@
\definebodyfontswitch [fivepoint] [\!!fivepoint]
\definebodyfontswitch [fourpoint] [\!!fourpoint]
-\definebodyfontswitch [xii] [\!!twelvepoint]
-\definebodyfontswitch [xi] [\!!elevenpoint]
-\definebodyfontswitch [x] [\!!tenpoint]
-\definebodyfontswitch [ix] [\!!ninepoint]
-\definebodyfontswitch [viii] [\!!eightpoint]
-\definebodyfontswitch [vii] [\!!sevenpoint]
-\definebodyfontswitch [vi] [\!!sixpoint]
+% \definebodyfontswitch [xii] [\!!twelvepoint]
+% \definebodyfontswitch [xi] [\!!elevenpoint]
+% \definebodyfontswitch [x] [\!!tenpoint]
+% \definebodyfontswitch [ix] [\!!ninepoint]
+% \definebodyfontswitch [viii] [\!!eightpoint]
+% \definebodyfontswitch [vii] [\!!sevenpoint]
+% \definebodyfontswitch [vi] [\!!sixpoint]
%D So far.
+\definefontstyle [\c!mm] [\c!mm]
\definefontstyle [\c!rm,\v!roman,\v!serif,\v!regular] [\c!rm]
\definefontstyle [\c!ss,\v!sansserif,\v!sans,\v!support] [\c!ss]
\definefontstyle [\c!tt,\v!teletype,\v!type,\v!mono] [\c!tt]
\definefontstyle [\c!hw,\v!handwritten] [\c!hw]
\definefontstyle [\c!cg,\v!calligraphic] [\c!cg]
+\definefontalternative[\c!tf]
+\definefontalternative[\c!bf]
+\definefontalternative[\c!it]
+\definefontalternative[\c!sl]
+\definefontalternative[\c!bs]
+\definefontalternative[\c!bi]
+\definefontalternative[\c!sc]
+
\definefontsize[\c!a] \definefontsize[\c!b]
\definefontsize[\c!c] \definefontsize[\c!d]
@@ -4295,41 +3671,11 @@
\definealternativestyle [\v!WORD] [\WORD] [\WORD]
%D \macros
-%D {...math}
-%D
-%D New or old?
-
-% tzt proper \define...
-%
-% watch out: \synchronizesymb resets the family so we need a second
-% \mf (or maybe \mr): messy and to be sorted out
-
-\def\tfmath{\tf\mf\synchronizesymb\mf}
-\def\bfmath{\bf\mf\synchronizesymb\mf}
-\def\slmath{\sl\mf\synchronizesymb\mf}
-\def\itmath{\it\mf\synchronizesymb\mf}
-\def\bsmath{\bs\mf\synchronizesymb\mf}
-\def\bimath{\bi\mf\synchronizesymb\mf}
-\def\scmath{\sc\mf\synchronizesymb\mf}
-\def\nnmath{\nn\mf\synchronizesymb\mf}
-
-\def\textmath {\synchronizesymb}
-
-%D \macros
%D {fontstylesuffix}
%D
%D The next macro is used to map non latin fontnames on
%D fonts. See \type {font-uni} for an example of its use.
-%\def\fontstylesuffix%
-% {\ifnum\fam=\tffam \s!Regular \else
-% \ifnum\fam=\bffam \s!Bold \else
-% \ifnum\fam=\slfam \s!Slanted \else
-% \ifnum\fam=\itfam \s!Italic \else
-% \ifnum\fam=\bsfam \s!BoldSlanted \else
-% \ifnum\fam=\bifam \s!BoldItalic \else
-% \s!Regular \fi\fi\fi\fi\fi\fi}%
-
\def\fontstylesuffix% why the \s!Regular ? see \getglyph
{\ifx\fontalternative\c!tf \s!Regular \else
\ifx\fontalternative\c!bf \s!Bold \else
@@ -4340,10 +3686,6 @@
\ifx\fontalternative\c!sc \s!Caps \else
\s!Regular \fi\fi\fi\fi\fi\fi\fi}%
-%D We still have to take care of \type{\xi}, so:
-
-\def\xi{\ifmmode\normalxi\else\elevenpoint\fi}
-
%D \macros
%D {definefontvariant,fontvariant,variant}
%D
@@ -4383,7 +3725,7 @@
\unexpanded\def\variant[#1]% slow
{\dosetscaledfont
- \expanded{\definedfont[\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1} at \the\dimexpr\scaledfontsize\relax]}%
+ \normalexpanded{\noexpand\definedfont[\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1} at \the\dimexpr\scaledfontsize\relax]}%
\ignoreimplicitspaces}
\ifx\Var\undefined \let\Var\variant \fi
@@ -4393,262 +3735,113 @@
%D bodyfont. Sans serif and teletype are also available and
%D can be called for by \type{\ss} and \type{\tt}.
-\setupbodyfont [unk, rm]
+% \setupbodyfont [unk, rm]
+% \setupbodyfont [rm]
%D Also needed is:
\definefont[tinyfont][Mono at 1ex]
-%D \macros
-%D {doiffontpresentelse}
-%D
-%D \starttyping
-%D \doiffontpresentelse{texnansi-lmr10}{YES}{NO}
-%D \doiffontpresentelse{adam-lindsay-modern-serif}{YES}{NO}
-%D \stoptyping
+% \tracinglostchars=1
-\def\doiffontpresentelse#1{\ctxlua{commands.doifelse(fonts.names.exists("#1"))}}
+% this needs some interfacing
+%
+% \setupfonts[check=...]
-%D OPTIMIZATIONS
+\def\checkcharactersinfont {\ctxlua{fonts.checkers.enabled=true}}
+\def\removemissingcharacters{\ctxlua{fonts.checkers.enabled=true fonts.checkers.delete=true}}
-\def\definefontsynonym[#1]#2[#3]%
- {\edef\@@fontname{#1}%
- \edef\@@fontfile{#3}%
- \@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
- \doifnextcharelse[\dodefinefontsynonym\nodefinefontsynonym}
+%D New commands (not yet interfaced):
-\def\dodefinefontsynonym[#1]%
- {\let\@@ff@@features \undefined
- \let\@@ff@@fallbacks\undefined
- \let\@@ff@@skewchar \undefined
- \expandafter\dogetfontparameter#1,]=,}
+\def\style[#1]% for inline usage, like \color
+ {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}}
-\def\dogetfontparameter#1=#2,%
- {\if]#1%
- \dododefinefontsynonym
- \else
- \expandafter\def\csname @@ff@@#1\endcsname{#2}%
- \expandafter\dogetfontparameter
- \fi}
+\def\startstyle[#1]%
+ {\begingroup
+ \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}
-\def\nodefinefontsynonym
- {\ifx\fontclass\empty
- \@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined
- \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined
- \@EA\let\csname\??ff\@@fontfile\s!skewchar \endcsname\undefined
- \else
- \global\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined
- \global\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined
- \global\@EA\let\csname\??ff\fontclass\@@fontfile\s!skewchar \endcsname\undefined
- \fi}
+\def\stopstyle
+ {\endgroup}
-\def\dododefinefontsynonym
- {\ifx\fontclass\empty
- \@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features
- \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks
- \@EA\let\csname\??ff\@@fontfile\s!skewchar \endcsname\@@ff@@skewchar
- \else
- \global\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features
- \global\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks
- \global\@EA\let\csname\??ff\fontclass\@@fontfile\s!skewchar \endcsname\@@ff@@skewchar
- \fi}
+%D Still experimental (might even go away).
-\def\truefontname#1%
- {\ifcsname\??ff\fontclass#1\endcsname
- \@EA\truefontname\csname\??ff\fontclass#1\endcsname
- \else\ifcsname\??ff#1\endcsname
- \@EA\truefontname\csname\??ff#1\endcsname
- \else
- #1%
- \fi\fi}
+% \definestylecollection[mine]
-\def\updatefontparameters
- {\edef\@@fontfeatures {\@@thefeatures \somefontname}%
- \edef\@@fontfallbacks{\@@thefallbacks\somefontname}%
- \edef\@@fontskewchar {\@@theskewchar \somefontname}}
-
-\def\@@thefeatures#1%
- {\ifcsname\??ff\fontclass#1\s!features\endcsname \csname\??ff\fontclass#1\s!features\endcsname\else % class + symbolic_name
- \ifcsname\??ff #1\s!features\endcsname \csname\??ff #1\s!features\endcsname\else % symbolic_name
- \ifcsname\??ff\fontclass#1\endcsname \@EA\@@thefeatures\csname\??ff\fontclass#1\endcsname \else % fontclass + parent_name
- \ifcsname\??ff #1\endcsname \@EA\@@thefeatures\csname\??ff #1\endcsname \fi\fi\fi\fi} % parent_name
-
-\def\@@thefallbacks#1%
- {\ifcsname\??ff\fontclass#1\s!fallbacks\endcsname \csname\??ff\fontclass#1\s!fallbacks\endcsname\else % class + symbolic_name
- \ifcsname\??ff #1\s!fallbacks\endcsname \csname\??ff #1\s!fallbacks\endcsname\else % symbolic_name
- \ifcsname\??ff\fontclass#1\endcsname \@EA\@@thefallbacks\csname\??ff\fontclass#1\endcsname \else % fontclass + parent_name
- \ifcsname\??ff #1\endcsname \@EA\@@thefallbacks\csname\??ff #1\endcsname \fi\fi\fi\fi} % parent_name
-
-\def\@@theskewchar#1% skew chars will be done differently (just a hash with registered skewchars)
- {\ifcsname\??ff\fontclass#1\s!skewchar\endcsname \csname\??ff\fontclass#1\s!skewchar\endcsname\else % class + symbolic_name
- \ifcsname\??ff #1\s!skewchar\endcsname \csname\??ff #1\s!skewchar\endcsname\else % symbolic_name
- \ifcsname\??ff\fontclass#1\endcsname \@EA\@@theskewchar\csname\??ff\fontclass#1\endcsname \else % fontclass + parent_name
- \ifcsname\??ff #1\endcsname \@EA\@@theskewchar\csname\??ff #1\endcsname \fi\fi\fi\fi} % parent_name
-
-% more efficient ?
+% \definestyleinstance[mine][default][sorry]
+% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
+% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
+% \definestyleinstance[mine][bf][\sl]
+% \definestyleinstance[mine][sl][\tt]
-\def\definefontsynonym[#1]#2[#3]%
- {\edef\@@fontname{#1}%
- \edef\@@fontfile{#3}%
- \ifx\fontclass\empty
- \expandafter\dodefinefontsynonymnop
- \else
- \expandafter\dodefinefontsynonymyes
- \fi}
+% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}
-\def\dodefinefontsynonymyes
- {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
- \doifnextcharelse[\dododefinefontsynonymyes\nonodefinefontsynonymyes}
-\def\dodefinefontsynonymnop
- {\@EA\let\csname\??ff\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
- \doifnextcharelse[\dododefinefontsynonymnop\nonodefinefontsynonymnop}
+\definesystemvariable{sx}
-\def\dododefinefontsynonymyes[#1]%
- {\let\@@ff@@features \undefined
- \let\@@ff@@fallbacks\undefined
- \let\@@ff@@skewchar \undefined
- \expandafter\dogetfontparameteryes#1,]=,}
-\def\dododefinefontsynonymnop[#1]%
- {\let\@@ff@@features \undefined
- \let\@@ff@@fallbacks\undefined
- \let\@@ff@@skewchar \undefined
- \expandafter\dogetfontparameternop#1,]=,}
+\def\definestylecollection
+ {\dosingleargument\dodefinestylecollection}
-\def\dogetfontparameteryes#1=#2,%
- {\if]#1%
- \dodododefinefontsynonymyes
- \else
- \expandafter\def\csname @@ff@@#1\endcsname{#2}%
- \expandafter\dogetfontparameteryes
+\def\dodefinestylecollection[#1]%
+ {\iffirstargument
+ \unexpanded\setvalue{#1}{\styleinstance[#1]}%
+ \def\docommand##1%
+ {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}%
+ \processcommacommand[\fontalternativelist,\s!default]\dodocommand}%
+ \processcommacommand[\fontstylelist,\s!default]\docommand
\fi}
-\def\dogetfontparameternop#1=#2,%
- {\if]#1%
- \dodododefinefontsynonymnop
- \else
- \expandafter\def\csname @@ff@@#1\endcsname{#2}%
- \expandafter\dogetfontparameternop
- \fi}
-
-\def\nonodefinefontsynonymyes
- {\global\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined
- \global\@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined
- \global\@EA\let\csname\??ff\@@fontfile\s!skewchar \endcsname\undefined}
-\def\nonodefinefontsynonymnop
- {\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined
- \@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined
- \@EA\let\csname\??ff\fontclass\@@fontfile\s!skewchar \endcsname\undefined}
-
-\def\dodododefinefontsynonymyes
- {\global\@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features
- \global\@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks
- \global\@EA\let\csname\??ff\@@fontfile\s!skewchar \endcsname\@@ff@@skewchar}
-\def\dodododefinefontsynonymnop
- {\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features
- \@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks
- \@EA\let\csname\??ff\fontclass\@@fontfile\s!skewchar \endcsname\@@ff@@skewchar}
-
-% resolve
-
-\def\@@thefeaturesyes#1%
- {\ifcsname\??ff\fontclass#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff\fontclass#1\s!features \endcsname\else
- \ifcsname\??ff #1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff #1\s!features \endcsname\else
- \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefeaturesyes \csname\??ff\fontclass #1\endcsname\else
- \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesyes \csname\??ff #1\endcsname\else
- \let \@@fontfeatures \empty \fi\fi\fi\fi}
-\def\@@thefallbacksyes#1%
- {\ifcsname\??ff\fontclass#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff\fontclass#1\s!fallbacks\endcsname\else
- \ifcsname\??ff #1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff #1\s!fallbacks\endcsname\else
- \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefallbacksyes\csname\??ff\fontclass #1\endcsname\else
- \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksyes\csname\??ff #1\endcsname\else
- \let \@@fontfallbacks \empty \fi\fi\fi\fi}
-\def\@@theskewcharyes#1%
- {\ifcsname\??ff\fontclass#1\s!skewchar \endcsname\@EA\let\@EA\@@fontskewchar \csname\??ff\fontclass#1\s!skewchar \endcsname\else
- \ifcsname\??ff #1\s!skewchar \endcsname\@EA\let\@EA\@@fontskewchar \csname\??ff #1\s!skewchar \endcsname\else
- \ifcsname\??ff\fontclass #1\endcsname\@EA \@@theskewcharyes \csname\??ff\fontclass #1\endcsname\else
- \ifcsname\??ff #1\endcsname\@EA \@@theskewcharyes \csname\??ff #1\endcsname\else
- \let \@@fontskewchar \empty \fi\fi\fi\fi}
-
-\def\@@thefeaturesnop#1%
- {\ifcsname\??ff#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff#1\s!features \endcsname\else
- \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesnop \csname\??ff #1\endcsname\else
- \let \@@fontfeatures \empty \fi\fi}
-\def\@@thefallbacksnop#1%
- {\ifcsname\??ff#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff#1\s!fallbacks\endcsname\else
- \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksnop\csname\??ff #1\endcsname\else
- \let \@@fontfallbacks \empty \fi\fi}
-\def\@@theskewcharnop#1%
- {\ifcsname\??ff#1\s!skewchar \endcsname\@EA\let\@EA\@@fontskewchar \csname\??ff#1\s!skewchar \endcsname\else
- \ifcsname\??ff #1\endcsname\@EA \@@theskewcharnop \csname\??ff #1\endcsname\else
- \let \@@fontskewchar \empty \fi\fi}
-\def\updatefontparametersyes
- {\@@thefeaturesyes \somefontname
- \@@thefallbacksyes\somefontname
- \@@theskewcharyes \somefontname}
-\def\updatefontparametersnop
- {\@@thefeaturesnop \somefontname
- \@@thefallbacksnop\somefontname
- \@@theskewcharnop \somefontname}
+\def\definestyleinstance
+ {\doquadrupleargument\dodefinestyleinstance}
-\def\updatefontparameters
- {\ifx\fontclass\empty\updatefontparametersnop\else\updatefontparametersyes\fi}
+\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
+ {\iffirstargument
+ \doifundefined{#1}{\definestylecollection[#1]}%
+ \fi
+ \iffourthargument
+ \setvalue{\??sx#1:#2:#3}{#4}%
+ \else\ifthirdargument
+ \setvalue{\??sx#1::#2}{#3}%
+ \else\ifsecondargument
+ \letvalue{\??sx#1::#2}\empty
+ \fi\fi\fi}
+
+\unexpanded\def\styleinstance[#1]% will be faster
+ {%\begingroup\normalexpanded{\noexpand\infofont[#1:\fontstyle:\fontalternative]}\endgroup
+ \executeifdefined{\??sx#1:\fontstyle:\fontalternative}%
+ {\executeifdefined{\??sx#1:\fontstyle:\s!default}%
+ {\executeifdefined{\??sx#1::\fontalternative}
+ {\getvalue {\??sx#1::\s!default}}}}}
+
+% \unexpanded\def\styleinstance[#1]%
+% {\csname\??sx#1%
+% \ifcsname:\fontstyle:\fontalternative\endcsname
+% :\fontstyle:\fontalternative
+% \else\ifcsname:\fontstyle:\s!default\endcsname
+% :\fontstyle:\s!default
+% \else\ifcsname::\fontalternative\endcsname
+% ::\fontalternative
+% \else\ifcsname::\s!default\endcsname
+% ::\s!default
+% \else
+% % nothing, \relax
+% \fi\fi\fi\fi
+% \endcsname}
\protect \endinput
-% bewaren
-%
-% \def\truefontdata#1#2%
-% {\ifcsname\??ff\fontclass#1#2\endcsname
-% % raw(Regular) raw(key)
-% \csname\??ff\fontclass#1#2\endcsname
-% \else\ifcsname\??ff\fontclass#1\endcsname
-% % exp(palatino Regular) raw(key)
-% \expandafter\truefontdata\csname\??ff\fontclass#1\endcsname#2%
-% \else\ifcsname\??ff#1\endcsname
-% % exp(Regular) raw(key)
-% \expandafter\truefontdata\csname\??ff#1\endcsname#2%
-% \else\ifcsname\??ff#2\endcsname
-% % raw(key)
-% \csname\??ff#2\endcsname
-% \fi\fi\fi\fi}
-
-% test file
-%
-% \starttypescript[serif][mine-1]
-% \definefontsynonym[Serif] [TeXGyrePagella-Regular]
-% \definefontsynonym[TeXGyrePagella-Regular][file:texgyrepagella-regular]
-% \stoptypescript
-%
-% \starttypescript[serif][mine-2]
-% \definefontsynonym[Serif] [TeXGyrePagella-Regular] [features=default]
-% \definefontsynonym[TeXGyrePagella-Regular][file:texgyrepagella-regular] [features=oldstyle]
-% \stoptypescript
-%
-% \starttypescript[serif][mine-3]
-% \definefontsynonym[Serif] [TeXGyrePagella-Regular] [features=oldstyle]
-% \definefontsynonym[TeXGyrePagella-Regular][file:texgyrepagella-regular] [features=default]
-% \stoptypescript
-%
-% \starttypescript[serif][mine-4]
-% \definefontsynonym[Serif] [TeXGyrePagella-Regular] [features=default]
-% \definefontsynonym[TeXGyrePagella-Regular][file:texgyrepagella-regular] [features=default]
-% \stoptypescript
-%
-% \starttypescript[serif][mine-5]
-% \definefontsynonym[Serif] [TeXGyrePagella-Regular] [features=oldstyle]
-% \definefontsynonym[TeXGyrePagella-Regular][file:texgyrepagella-regular] [features=oldstyle]
-% \stoptypescript
-%
-% \starttext
-% \dorecurse {5} {
-% \expanded{\definetypeface[mine-\recurselevel][rm][serif][mine-\recurselevel][default]}
-% \expanded{\setupbodyfont [mine-\recurselevel] mine-\recurselevel: text 1234567890 done}
-% \par
-% }
-% \blank
-% \dorecurse {5} {
-% \expanded{\definetypeface[more-\recurselevel][rm][serif][mine-\recurselevel][default][features=oldstyle]}
-% \expanded{\setupbodyfont [more-\recurselevel] mine-\recurselevel: text 1234567890 done}
-% \par
-% }
-% \stoptext
+% \startluacode
+% function commands.doifelsecurrentfonthasfeature(name)
+% local f = fonts.ids[font.current()]
+% f = f and f.shared
+% f = f and f.otfdata
+% f = f and f.luatex
+% f = f and f.features
+% commands.doifelse(f and (f.gpos[name] or f.gsub[name]))
+% end
+% \stopluacode
+
+% \def\doifelsecurrentfonthasfeature#1%
+% {\ctxlua{commands.doifelsecurrentfonthasfeature("#1")}}
+
+% \doifelsecurrentfonthasfeature{smcp}{YES}{NO}
+% \doifelsecurrentfonthasfeature{crap}{YES}{NO}
+% \doifelsecurrentfonthasfeature{kern}{YES}{NO}
diff --git a/tex/context/base/font-jap.tex b/tex/context/base/font-jap.tex
index 6bb813ccc..42480df43 100644
--- a/tex/context/base/font-jap.tex
+++ b/tex/context/base/font-jap.tex
@@ -15,7 +15,7 @@
\ifx\handlejapaneseunicodeglyph\undefined \else \endinput \fi
\ifx\handlechineseunicodeglyph \undefined \input font-chi.tex \fi
-\writestatus{loading}{Context Font Macros / Japanese}
+\writestatus{loading}{ConTeXt Font Macros / Japanese}
\unprotect
diff --git a/tex/context/base/font-log.lua b/tex/context/base/font-log.lua
new file mode 100644
index 000000000..499bd4304
--- /dev/null
+++ b/tex/context/base/font-log.lua
@@ -0,0 +1,53 @@
+if not modules then modules = { } end modules ['font-log'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, format, lower, concat = next, string.format, string.lower, table.concat
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+fonts.logger = fonts.logger or { }
+
+--[[ldx--
+<p>The following functions are used for reporting about the fonts
+used. The message itself is not that useful in regular runs but since
+we now have several readers it may be handy to know what reader is
+used for which font.</p>
+--ldx]]--
+
+function fonts.logger.save(tfmtable,source,specification) -- save file name in spec here ! ! ! ! ! !
+ if tfmtable and specification and specification.specification then
+ local name = lower(specification.name)
+ if trace_defining and not fonts.used[name] then
+ logs.report("define font","registering %s as %s",file.basename(specification.name),source)
+ end
+ specification.source = source
+ fonts.loaded[lower(specification.specification)] = specification
+ fonts.used[name] = source
+ end
+end
+
+function fonts.logger.report()
+ local t = { }
+ for name, used in table.sortedpairs(fonts.used) do
+ t[#t+1] = file.basename(name) .. ":" .. used
+ end
+ return t
+end
+
+function fonts.logger.format(name)
+ return fonts.used[name] or "unknown"
+end
+
+statistics.register("loaded fonts", function()
+ if next(fonts.used) then
+ local t = fonts.logger.report(separator)
+ return (#t > 0 and format("%s files: %s",#t,concat(t,separator or " "))) or "none"
+ else
+ return nil
+ end
+end)
diff --git a/tex/context/base/font-map.lua b/tex/context/base/font-map.lua
index 64ff268fb..35cfaf32f 100644
--- a/tex/context/base/font-map.lua
+++ b/tex/context/base/font-map.lua
@@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['font-map'] = {
license = "see context related readme files"
}
+local match, format, find = string.match, string.format, string.find
+
+local ctxcatcodes = tex.ctxcatcodes
+
--[[ldx--
<p>Eventually this code will disappear because map files are kind
of obsolete. Some code may move to runtime or auxiliary modules.</p>
@@ -29,21 +33,21 @@ function fonts.map.line.pdftex(e) -- so far no combination of slant and stretch
local fullname = e.fullname or ""
if e.slant and e.slant ~= 0 then
if e.encoding then
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile))
+ return fonts.map.line.pdfmapline("=",format('%s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile))
else
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile))
+ return fonts.map.line.pdfmapline("=",format('%s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile))
end
elseif e.stretch and e.stretch ~= 1 and e.stretch ~= 0 then
if e.encoding then
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.stretch,e.encoding,e.fontfile))
+ return fonts.map.line.pdfmapline("=",format('%s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.stretch,e.encoding,e.fontfile))
else
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s',e.name,fullname,e.stretch,e.fontfile))
+ return fonts.map.line.pdfmapline("=",format('%s %s "%g ExtendFont" <%s',e.name,fullname,e.stretch,e.fontfile))
end
else
if e.encoding then
- return fonts.map.line.pdfmapline("=",string.format('%s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile))
+ return fonts.map.line.pdfmapline("=",format('%s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile))
else
- return fonts.map.line.pdfmapline("=",string.format('%s %s <%s',e.name,fullname,e.fontfile))
+ return fonts.map.line.pdfmapline("=",format('%s %s <%s',e.name,fullname,e.fontfile))
end
end
else
@@ -54,7 +58,7 @@ end
function fonts.map.flush(backend) -- will also erase the accumulated data
local flushline = fonts.map.line[backend or "pdftex"] or fonts.map.line.pdftex
for _, e in pairs(fonts.map.data) do
- tex.sprint(tex.ctxcatcodes,flushline(e))
+ tex.sprint(ctxcatcodes,flushline(e))
end
fonts.map.data = { }
end
@@ -76,27 +80,27 @@ function fonts.map.load_file(filename, entries, encodings)
if f then
local data = f:read("*a")
if data then
- for line in data:gmatch("(.-)[\n\t]") do
- if line:find("^[%#%%%s]") then
+ for line in gmatch(data,"(.-)[\n\t]") do
+ if find(line,"^[%#%%%s]") then
-- print(line)
else
local stretch, slant, name, fullname, fontfile, encoding
line = line:gsub('"(.+)"', function(s)
- stretch = s:find('"([^"]+) ExtendFont"')
- slant = s:find('"([^"]+) SlantFont"')
+ stretch = find(s,'"([^"]+) ExtendFont"')
+ slant = find(s,'"([^"]+) SlantFont"')
return ""
end)
if not name then
-- name fullname encoding fontfile
- name, fullname, encoding, fontfile = line:match("^(%S+)%s+(%S*)[%s<]+(%S*)[%s<]+(%S*)%s*$")
+ name, fullname, encoding, fontfile = match(line,"^(%S+)%s+(%S*)[%s<]+(%S*)[%s<]+(%S*)%s*$")
end
if not name then
-- name fullname (flag) fontfile encoding
- name, fullname, fontfile, encoding = line:match("^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$")
+ name, fullname, fontfile, encoding = match(line,"^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$")
end
if not name then
-- name fontfile
- name, fontfile = line:match("^(%S+)%s+[%d%s<]+(%S*)%s*$")
+ name, fontfile = match(line,"^(%S+)%s+[%d%s<]+(%S*)%s*$")
end
if name then
if encoding == "" then encoding = nil end
diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua
new file mode 100644
index 000000000..520f9e7a6
--- /dev/null
+++ b/tex/context/base/font-mis.lua
@@ -0,0 +1,91 @@
+if not modules then modules = { } end modules ['font-mis'] = {
+ version = 1.001,
+ comment = "companion to luatex-fonts.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, pairs, ipairs = next, pairs, ipairs
+local lower, strip = string.lower, string.strip
+
+fonts.otf = fonts.otf or { }
+
+fonts.otf.version = fonts.otf.version or 2.626
+fonts.otf.pack = true
+fonts.otf.cache = containers.define("fonts", "otf", fonts.otf.version, true)
+
+function fonts.otf.loadcached(filename,format,sub)
+ -- no recache when version mismatch
+ local name = file.basename(file.removesuffix(filename))
+ if sub == "" then sub = false end
+ local hash = name
+ if sub then
+ hash = hash .. "-" .. sub
+ end
+ hash = containers.cleanname(hash)
+ local data = containers.read(fonts.otf.cache(), hash)
+ if data and not data.verbose then
+ fonts.otf.enhancers.unpack(data)
+ return data
+ else
+ return nil
+ end
+end
+
+function fonts.get_features(name,t,script,language)
+ local t = lower(t or (name and file.extname(name)) or "")
+ if t == "otf" or t == "ttf" or t == "ttc" then
+ local filename = resolvers.find_file(name,t) or ""
+ if filename ~= "" then
+ local data = fonts.otf.loadcached(filename)
+ if data and data.luatex and data.luatex.features then
+ return data.luatex.features
+ else
+ local ff = fontloader.open(filename)
+ if ff then
+ local data = fontloader.to_table(ff)
+ fontloader.close(ff)
+ local features = { }
+ for k, what in pairs { "gsub", "gpos" } do
+ local dw = data[what]
+ if dw then
+ local f = { }
+ features[what] = f
+ for _, d in ipairs(dw) do
+ if d.features then
+ for _, df in ipairs(d.features) do
+ local tag = strip(lower(df.tag))
+ local ft = f[tag] if not ft then ft = {} f[tag] = ft end
+ for _, ds in ipairs(df.scripts) do
+ local scri = strip(lower(ds.script))
+ local fts = ft[scri] if not fts then fts = {} ft[scri] = fts end
+ for _, lang in ipairs(ds.langs) do
+ lang = strip(lower(lang))
+ if scri == script then
+ if lang == language then
+ fts[lang] = 'sl'
+ else
+ fts[lang] = 's'
+ end
+ else
+ if lang == language then
+ fts[lang] = 'l'
+ else
+ fts[lang] = true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return features
+ end
+ end
+ end
+ end
+ return nil, nil
+end
diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua
new file mode 100644
index 000000000..72e7414c8
--- /dev/null
+++ b/tex/context/base/font-ota.lua
@@ -0,0 +1,320 @@
+if not modules then modules = { } end modules ['font-ota'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (analysing)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this might become scrp-*.lua
+
+local type, tostring, match, format, concat = type, tostring, string.match, string.format, table.concat
+
+if not trackers then trackers = { register = function() end } end
+
+local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end)
+local trace_cjk = false trackers.register("cjk.injections", function(v) trace_cjk = v end)
+
+trackers.register("cjk.analyzing","otf.analyzing")
+
+fonts = fonts or { }
+fonts.analyzers = fonts.analyzers or { }
+fonts.analyzers.initializers = fonts.analyzers.initializers or { node = { otf = { } } }
+fonts.analyzers.methods = fonts.analyzers.methods or { node = { otf = { } } }
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local initializers = fonts.analyzers.initializers
+local methods = fonts.analyzers.methods
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local penalty = node.id('penalty')
+
+local set_attribute = node.set_attribute
+local has_attribute = node.has_attribute
+local traverse_id = node.traverse_id
+local delete_node = nodes.delete
+local replace_node = nodes.replace
+local insert_node_after = node.insert_after
+local insert_node_before = node.insert_before
+local traverse_node_list = node.traverse
+
+local fontdata = fonts.ids
+local state = attributes.private('state')
+
+local fcs = (fonts.color and fonts.color.set) or function() end
+local fcr = (fonts.color and fonts.color.reset) or function() end
+
+local a_to_script = otf.a_to_script
+local a_to_language = otf.a_to_language
+
+-- in the future we will use language/script attributes instead of the
+-- font related value, but then we also need dynamic features which is
+-- somewhat slower; and .. we need a chain of them
+
+
+function fonts.initializers.node.otf.analyze(tfmdata,value,attr)
+ if attr and attr > 0 then
+ script, language = a_to_script[attr], a_to_language[attr]
+ else
+ script, language = tfmdata.script, tfmdata.language
+ end
+ local action = initializers[script]
+ if action then
+ if type(action) == "function" then
+ return action(tfmdata,value)
+ else
+ local action = action[language]
+ if action then
+ return action(tfmdata,value)
+ end
+ end
+ end
+ return nil
+end
+
+function fonts.methods.node.otf.analyze(head,font,attr)
+ local tfmdata = fontdata[font]
+ local script, language
+ if attr and attr > 0 then
+ script, language = a_to_script[attr], a_to_language[attr]
+ else
+ script, language = tfmdata.script, tfmdata.language
+ end
+ local action = methods[script]
+ if action then
+ if type(action) == "function" then
+ return action(head,font,attr)
+ else
+ action = action[language]
+ if action then
+ return action(head,font,attr)
+ end
+ end
+ end
+ return head, false
+end
+
+otf.features.register("analyze",true) -- we always analyze
+table.insert(fonts.triggers,"analyze") -- we need a proper function for doing this
+
+-- latin
+
+fonts.analyzers.methods.latn = fonts.analyzers.aux.setstate
+
+-- this info eventually will go into char-def
+
+local zwnj = 0x200C
+local zwj = 0x200D
+
+local isol = {
+ [0x0600] = true, [0x0601] = true, [0x0602] = true, [0x0603] = true,
+ [0x0608] = true, [0x060B] = true, [0x0621] = true, [0x0674] = true,
+ [0x06DD] = true, [zwnj] = true,
+}
+
+local isol_fina = {
+ [0x0622] = true, [0x0623] = true, [0x0624] = true, [0x0625] = true,
+ [0x0627] = true, [0x0629] = true, [0x062F] = true, [0x0630] = true,
+ [0x0631] = true, [0x0632] = true, [0x0648] = true, [0x0671] = true,
+ [0x0672] = true, [0x0673] = true, [0x0675] = true, [0x0676] = true,
+ [0x0677] = true, [0x0688] = true, [0x0689] = true, [0x068A] = true,
+ [0x068B] = true, [0x068C] = true, [0x068D] = true, [0x068E] = true,
+ [0x068F] = true, [0x0690] = true, [0x0691] = true, [0x0692] = true,
+ [0x0693] = true, [0x0694] = true, [0x0695] = true, [0x0696] = true,
+ [0x0697] = true, [0x0698] = true, [0x0699] = true, [0x06C0] = true,
+ [0x06C3] = true, [0x06C4] = true, [0x06C5] = true, [0x06C6] = true,
+ [0x06C7] = true, [0x06C8] = true, [0x06C9] = true, [0x06CA] = true,
+ [0x06CB] = true, [0x06CD] = true, [0x06CF] = true, [0x06D2] = true,
+ [0x06D3] = true, [0x06D5] = true, [0x06EE] = true, [0x06EF] = true,
+ [0x0759] = true, [0x075A] = true, [0x075B] = true, [0x076B] = true,
+ [0x076C] = true, [0x0771] = true, [0x0773] = true, [0x0774] = true,
+ [0x0778] = true, [0x0779] = true,
+}
+
+local isol_fina_medi_init = {
+ [0x0626] = true, [0x0628] = true, [0x062A] = true, [0x062B] = true,
+ [0x062C] = true, [0x062D] = true, [0x062E] = true, [0x0633] = true,
+ [0x0634] = true, [0x0635] = true, [0x0636] = true, [0x0637] = true,
+ [0x0638] = true, [0x0639] = true, [0x063A] = true, [0x063B] = true,
+ [0x063C] = true, [0x063D] = true, [0x063E] = true, [0x063F] = true,
+ [0x0640] = true, [0x0641] = true, [0x0642] = true, [0x0643] = true,
+ [0x0644] = true, [0x0645] = true, [0x0646] = true, [0x0647] = true,
+ [0x0649] = true, [0x064A] = true, [0x066E] = true, [0x066F] = true,
+ [0x0678] = true, [0x0679] = true, [0x067A] = true, [0x067B] = true,
+ [0x067C] = true, [0x067D] = true, [0x067E] = true, [0x067F] = true,
+ [0x0680] = true, [0x0681] = true, [0x0682] = true, [0x0683] = true,
+ [0x0684] = true, [0x0685] = true, [0x0686] = true, [0x0687] = true,
+ [0x069A] = true, [0x069B] = true, [0x069C] = true, [0x069D] = true,
+ [0x069E] = true, [0x069F] = true, [0x06A0] = true, [0x06A1] = true,
+ [0x06A2] = true, [0x06A3] = true, [0x06A4] = true, [0x06A5] = true,
+ [0x06A6] = true, [0x06A7] = true, [0x06A8] = true, [0x06A9] = true,
+ [0x06AA] = true, [0x06AB] = true, [0x06AC] = true, [0x06AD] = true,
+ [0x06AE] = true, [0x06AF] = true, [0x06B0] = true, [0x06B1] = true,
+ [0x06B2] = true, [0x06B3] = true, [0x06B4] = true, [0x06B5] = true,
+ [0x06B6] = true, [0x06B7] = true, [0x06B8] = true, [0x06B9] = true,
+ [0x06BA] = true, [0x06BB] = true, [0x06BC] = true, [0x06BD] = true,
+ [0x06BE] = true, [0x06BF] = true, [0x06C1] = true, [0x06C2] = true,
+ [0x06CC] = true, [0x06CE] = true, [0x06D0] = true, [0x06D1] = true,
+ [0x06FA] = true, [0x06FB] = true, [0x06FC] = true, [0x06FF] = true,
+ [0x0750] = true, [0x0751] = true, [0x0752] = true, [0x0753] = true,
+ [0x0754] = true, [0x0755] = true, [0x0756] = true, [0x0757] = true,
+ [0x0758] = true, [0x075C] = true, [0x075D] = true, [0x075E] = true,
+ [0x075F] = true, [0x0760] = true, [0x0761] = true, [0x0762] = true,
+ [0x0763] = true, [0x0764] = true, [0x0765] = true, [0x0766] = true,
+ [0x0767] = true, [0x0768] = true, [0x0769] = true, [0x076A] = true,
+ [0x076D] = true, [0x076E] = true, [0x076F] = true, [0x0770] = true,
+ [0x0772] = true, [0x0775] = true, [0x0776] = true, [0x0777] = true,
+ [0x077A] = true, [0x077B] = true, [0x077C] = true, [0x077D] = true,
+ [0x077E] = true, [0x077F] = true, [zwj] = true,
+}
+
+local arab_warned = { }
+
+-- todo: gref
+
+local function warning(current,what)
+ local char = current.char
+ if not arab_warned[char] then
+ log.report("analyze","arab: character %s (U+%04X) has no %s class", char, char, what)
+ arab_warned[char] = true
+ end
+end
+
+function fonts.analyzers.methods.nocolor(head,font,attr)
+ for n in traverse_node_list(head,glyph) do
+ if not font or n.font == font then
+ fcr(n)
+ end
+ end
+ return head, true
+end
+
+otf.remove_joiners = false -- true -- for idris who want it as option
+
+local function finish(first,last)
+ if last then
+ if first == last then
+ local fc = first.char
+ if isol_fina_medi_init[fc] or isol_fina[fc] then
+ set_attribute(first,state,4) -- isol
+ if trace_analyzing then fcs(first,"font:isol") end
+ else
+ warning(first,"isol")
+ set_attribute(first,state,0) -- error
+ if trace_analyzing then fcr(first) end
+ end
+ else
+ local lc = last.char
+ if isol_fina_medi_init[lc] or isol_fina[lc] then -- why isol here ?
+ -- if laststate == 1 or laststate == 2 or laststate == 4 then
+ set_attribute(last,state,3) -- fina
+ if trace_analyzing then fcs(last,"font:fina") end
+ else
+ warning(last,"fina")
+ set_attribute(last,state,0) -- error
+ if trace_analyzing then fcr(last) end
+ end
+ end
+ first, last = nil, nil
+ elseif first then
+ -- first and last are either both set so we never com here
+ local fc = first.char
+ if isol_fina_medi_init[fc] or isol_fina[fc] then
+ set_attribute(first,state,4) -- isol
+ if trace_analyzing then fcs(first,"font:isol") end
+ else
+ warning(first,"isol")
+ set_attribute(first,state,0) -- error
+ if trace_analyzing then fcr(first) end
+ end
+ first = nil
+ end
+ return first, last
+end
+
+function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace
+ local tfmdata = fontdata[font]
+ local marks = tfmdata.marks
+ local first, last, current, done = nil, nil, head, false
+ local joiners, nonjoiners
+ local removejoiners = tfmdata.remove_joiners -- or otf.remove_joiners
+ if removejoiners then
+ joiners, nonjoiners = { }, { }
+ end
+ while current do
+ if current.id == glyph and current.subtype<256 and current.font == font and not has_attribute(current,state) then
+ done = true
+ local char = current.char
+ if removejoiners then
+ if char == zwj then
+ joiners[#joiners+1] = current
+ elseif char == zwnj then
+ nonjoiners[#nonjoiners+1] = current
+ end
+ end
+ if marks[char] then
+ set_attribute(current,state,5) -- mark
+ if trace_analyzing then fcs(current,"font:mark") end
+ elseif isol[char] then -- can be zwj or zwnj too
+ first, last = finish(first,last)
+ set_attribute(current,state,4) -- isol
+ if trace_analyzing then fcs(current,"font:isol") end
+ first, last = nil, nil
+ elseif not first then
+ if isol_fina_medi_init[char] then
+ set_attribute(current,state,1) -- init
+ if trace_analyzing then fcs(current,"font:init") end
+ first, last = first or current, current
+ elseif isol_fina[char] then
+ set_attribute(current,state,4) -- isol
+ if trace_analyzing then fcs(current,"font:isol") end
+ first, last = nil, nil
+ else -- no arab
+ first, last = finish(first,last)
+ end
+ elseif isol_fina_medi_init[char] then
+ first, last = first or current, current
+ set_attribute(current,state,2) -- medi
+ if trace_analyzing then fcs(current,"font:medi") end
+ elseif isol_fina[char] then
+ if not has_attribute(last,state,1) then
+ -- tricky, we need to check what last may be !
+ set_attribute(last,state,2) -- medi
+ if trace_analyzing then fcs(last,"font:medi") end
+ end
+ set_attribute(current,state,3) -- fina
+ if trace_analyzing then fcs(current,"font:fina") end
+ first, last = nil, nil
+ elseif char >= 0x0600 and char <= 0x06FF then
+ if trace_analyzing then fcs(current,"font:rest") end
+ first, last = finish(first,last)
+ else --no
+ first, last = finish(first,last)
+ end
+ else
+ first, last = finish(first,last)
+ end
+ current = current.next
+ end
+ first, last = finish(first,last)
+ if removejoiners then
+ for i=1,#joiners do
+ head = delete_node(head,joiners[i])
+ end
+ for i=1,#nonjoiners do
+ head = replace_node(head,nonjoiners[i],nodes.glue(0)) -- or maybe a kern
+ end
+ end
+ return head, done
+end
+
+table.insert(fonts.manipulators,"joiners")
+
+function fonts.initializers.node.otf.joiners(tfmdata,value)
+ if value == "strip" then
+ tfmdata.remove_joiners = true
+ end
+end
diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua
new file mode 100644
index 000000000..2a14085d6
--- /dev/null
+++ b/tex/context/base/font-otb.lua
@@ -0,0 +1,364 @@
+if not modules then modules = { } end modules ['font-otb'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local concat = table.concat
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end)
+local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end)
+local trace_multiples = false trackers.register("otf.multiples", function(v) trace_multiples = v end)
+local trace_alternatives = false trackers.register("otf.alternatives", function(v) trace_alternatives = v end)
+local trace_ligatures = false trackers.register("otf.ligatures", function(v) trace_ligatures = v end)
+local trace_kerns = false trackers.register("otf.kerns", function(v) trace_kerns = v end)
+local trace_preparing = false trackers.register("otf.preparing", function(v) trace_preparing = v end)
+
+local wildcard = "*"
+local default = "dflt"
+
+local split_at_space = lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway
+
+local pcache, fcache = { }, { } -- could be weak
+
+local function gref(descriptions,n)
+ if type(n) == "number" then
+ local name = descriptions[n].name
+ if name then
+ return format("U+%04X (%s)",n,name)
+ else
+ return format("U+%04X")
+ end
+ elseif n then
+ local num, nam = { }, { }
+ for i=1,#n do
+ local ni = n[i]
+ num[i] = format("U+%04X",ni)
+ nam[i] = descriptions[ni].name or "?"
+ end
+ return format("%s (%s)",concat(num," "), concat(nam," "))
+ else
+ return "?"
+ end
+end
+
+local function cref(kind,lookupname)
+ if lookupname then
+ return format("feature %s, lookup %s",kind,lookupname)
+ else
+ return format("feature %s",kind)
+ end
+end
+
+local function resolve_ligatures(tfmdata,ligatures,kind)
+ kind = kind or "unknown"
+ local unicodes = tfmdata.unicodes
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local changed = tfmdata.changed
+ local done = { }
+ while true do
+ local ok = false
+ for k,v in next, ligatures do
+ local lig = v[1]
+ if not done[lig] then
+ local ligs = split_at_space:match(lig)
+ if #ligs == 2 then
+ local uc = v[2]
+ local c, f, s = characters[uc], ligs[1], ligs[2]
+ local uft, ust = unicodes[f] or 0, unicodes[s] or 0
+ if not uft or not ust then
+ logs.report("define otf","%s: unicode problem with base ligature %s = %s + %s",cref(kind),gref(descriptions,uc),gref(descriptions,uft),gref(descriptions,ust))
+ -- some kind of error
+ else
+ if type(uft) == "number" then uft = { uft } end
+ if type(ust) == "number" then ust = { ust } end
+ for ufi=1,#uft do
+ local uf = uft[ufi]
+ for usi=1,#ust do
+ local us = ust[usi]
+ if changed[uf] or changed[us] then
+ if trace_baseinit and trace_ligatures then
+ logs.report("define otf","%s: base ligature %s + %s ignored",cref(kind),gref(descriptions,uf),gref(descriptions,us))
+ end
+ else
+ local first, second = characters[uf], us
+ if first and second then
+ local t = first.ligatures
+ if not t then
+ t = { }
+ first.ligatures = t
+ end
+ if type(uc) == "number" then
+ t[second] = { type = 0, char = uc }
+ else
+ t[second] = { type = 0, char = uc[1] } -- can this still happen?
+ end
+ if trace_baseinit and trace_ligatures then
+ logs.report("define otf","%s: base ligature %s + %s => %s",cref(kind),gref(descriptions,uf),gref(descriptions,us),gref(descriptions,uc))
+ end
+ end
+ end
+ end
+ end
+ end
+ ok, done[lig] = true, descriptions[uc].name
+ end
+ end
+ end
+ if ok then
+ -- done has "a b c" = "a_b_c" and ligatures the already set ligatures: "a b" = 123
+ -- and here we add extras (f i i = fi + i and alike)
+ --
+ -- we could use a hash for fnc and pattern
+ --
+ -- this might be interfering !
+ for d,n in next, done do
+ local pattern = pcache[d] if not pattern then pattern = "^(" .. d .. ") " pcache[d] = pattern end
+ local fnc = fcache[n] if not fnc then fnc = function() return n .. " " end fcache[n] = fnc end
+ for k,v in next, ligatures do
+ v[1] = gsub(v[1],pattern,fnc)
+ end
+ end
+ else
+ break
+ end
+ end
+end
+
+local function collect_lookups(otfdata,kind,script,language)
+ -- maybe store this in the font
+ local sequences = otfdata.luatex.sequences
+ if sequences then
+ local featuremap, featurelist = { }, { }
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local features = sequence.features
+ features = features and features[kind]
+ features = features and (features[script] or features[default] or features[wildcard])
+ features = features and (features[language] or features[default] or features[wildcard])
+ if features then
+ local subtables = sequence.subtables
+ if subtables then
+ for s=1,#subtables do
+ local ss = subtables[s]
+ if not featuremap[s] then
+ featuremap[ss] = true
+ featurelist[#featurelist+1] = ss
+ end
+ end
+ end
+ end
+ end
+ if #featurelist > 0 then
+ return featuremap, featurelist
+ end
+ end
+ return nil, nil
+end
+
+local splitter = lpeg.splitat(" ")
+
+function prepare_base_substitutions(tfmdata,kind,value) -- we can share some code with the node features
+ if value then
+ local otfdata = tfmdata.shared.otfdata
+ local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
+ if validlookups then
+ local ligatures = { }
+ local unicodes = tfmdata.unicodes -- names to unicodes
+ local indices = tfmdata.indices
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local changed = tfmdata.changed
+ for k,c in next, characters do
+ local glyph = descriptions[k]
+ local lookups = glyph.lookups
+ if lookups then
+ for l=1,#lookuplist do
+ local lookup = lookuplist[l]
+ local ps = lookups[lookup]
+ if ps then
+ for i=1,#ps do
+ local p = ps[i]
+ local t = p[1]
+ if t == 'substitution' then
+ local pv = p[2] -- p.variant
+ if pv then
+ local upv = unicodes[pv]
+ if upv then
+ if type(upv) == "table" then
+ upv = upv[1]
+ end
+ if characters[upv] then
+ if trace_baseinit and trace_singles then
+ logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv))
+ end
+ changed[k] = upv
+ end
+ end
+ end
+ elseif t == 'alternate' then
+ local pc = p[2] -- p.components
+ if pc then
+ -- a bit optimized ugliness
+ if value == 1 then
+ pc = splitter:match(pc)
+ elseif value == 2 then
+ local a, b = splitter:match(pc)
+ pc = b or a
+ else
+ pc = { splitter:match(pc) }
+ pc = pc[value] or pc[#pc]
+ end
+ if pc then
+ local upc = unicodes[pc]
+ if upc then
+ if type(upc) == "table" then
+ upc = upc[1]
+ end
+ if characters[upc] then
+ if trace_baseinit and trace_alternatives then
+ logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc))
+ end
+ changed[k] = upc
+ end
+ end
+ end
+ end
+ elseif t == 'ligature' and not changed[k] then
+ local pc = p[2]
+ if pc then
+ if trace_baseinit and trace_ligatures then
+ local upc = { splitter:match(pc) }
+ for i=1,#upc do upc[i] = unicodes[upc[i]] end
+ -- we assume that it's no table
+ logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k))
+ end
+ ligatures[#ligatures+1] = { pc, k }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ resolve_ligatures(tfmdata,ligatures,kind)
+ end
+ else
+ tfmdata.ligatures = tfmdata.ligatures or { } -- left over from what ?
+ end
+end
+
+local function prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns, currently all
+ if value then
+ local otfdata = tfmdata.shared.otfdata
+ local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
+ if validlookups then
+ local unicodes = tfmdata.unicodes -- names to unicodes
+ local indices = tfmdata.indices
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ for u, chr in next, characters do
+ local d = descriptions[u]
+ if d then
+ local dk = d.mykerns
+ if dk then
+ local t, done = chr.kerns or { }, false
+ for l=1,#lookuplist do
+ local lookup = lookuplist[l]
+ local kerns = dk[lookup]
+ if kerns then
+ for k, v in next, kerns do
+ if v ~= 0 and not t[k] then -- maybe no 0 test here
+ t[k], done = v, true
+ if trace_baseinit and trace_kerns then
+ logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v)
+ end
+ end
+ end
+ end
+ end
+ if done then
+ chr.kerns = t -- no empty assignments
+ end
+ -- elseif d.kerns then
+ -- logs.report("define otf","%s: invalid mykerns for %s",cref(kind),gref(descriptions,u))
+ end
+ end
+ end
+ end
+ end
+end
+
+-- In principle we could register each feature individually which was
+-- what we did in earlier versions. However, after the rewrite it
+-- made more sense to collect them in an overall features initializer
+-- just as with the node variant. There it was needed because we need
+-- to do complete mixed runs and not run featurewise (as we did before).
+
+local supported_gsub = {
+ 'liga','dlig','rlig','hlig',
+ 'pnum','onum','tnum','lnum',
+ 'zero',
+ 'smcp','cpsp','c2sc','ornm','aalt',
+ 'hwid','fwid',
+ 'ssty', -- math
+}
+
+local supported_gpos = {
+ 'kern'
+}
+
+function otf.features.register_base_substitution(tag)
+ supported_gsub[#supported_gsub+1] = tag
+end
+function otf.features.register_base_kern(tag)
+ supported_gsub[#supported_gpos+1] = tag
+end
+
+local basehash, basehashes = { }, 1
+
+function fonts.initializers.base.otf.features(tfmdata,value)
+ if true then -- value then
+ -- not shared
+ local t = trace_preparing and os.clock()
+ local features = tfmdata.shared.features
+ if features then
+ local h = { }
+ for f=1,#supported_gsub do
+ local feature = supported_gsub[f]
+ prepare_base_substitutions(tfmdata,feature,features[feature])
+ h[#h+1] = feature
+ end
+ for f=1,#supported_gpos do
+ local feature = supported_gpos[f]
+ prepare_base_kerns(tfmdata,feature,features[feature])
+ h[#h+1] = feature
+ end
+ local hash = concat(h," ")
+ local base = basehash[hash]
+ if not base then
+ basehashes = basehashes + 1
+ base = basehashes
+ basehash[hash] = base
+ end
+ -- We need to make sure that luatex sees the difference between
+ -- base fonts that have different glyphs in the same slots in fonts
+ -- that have the same fullname (or filename). LuaTeX will merge fonts
+ -- eventually (and subset later on). If needed we can use a more
+ -- verbose name as long as we don't use <()<>[]{}/%> and the length
+ -- is < 128.
+ tfmdata.fullname = tfmdata.fullname .. base
+ end
+ if trace_preparing then
+ logs.report("otf define","preparation time is %0.3f seconds for %s",os.clock()-t,tfmdata.fullname or "?")
+ end
+ end
+end
diff --git a/tex/context/base/font-otc.lua b/tex/context/base/font-otc.lua
new file mode 100644
index 000000000..f75da39cd
--- /dev/null
+++ b/tex/context/base/font-otc.lua
@@ -0,0 +1,238 @@
+if not modules then modules = { } end modules ['font-otc'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (context)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, insert = string.format, table.insert
+local type, next = type, next
+
+local ctxcatcodes = tex.ctxcatcodes
+
+-- we assume that the other otf stuff is loaded already
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+-- instead of "script = "DFLT", langs = { 'dflt' }" we now use wildcards (we used to
+-- have always); some day we can write a "force always when true" trick for other
+-- features as well
+
+local extra_lists = {
+ tlig = {
+ {
+ endash = "hyphen hyphen",
+ emdash = "hyphen hyphen hyphen",
+ -- quotedblleft = "quoteleft quoteleft",
+ -- quotedblright = "quoteright quoteright",
+ -- quotedblleft = "grave grave",
+ -- quotedblright = "quotesingle quotesingle",
+ -- quotedblbase = "comma comma",
+ },
+ },
+ trep = {
+ {
+ -- [0x0022] = 0x201D,
+ [0x0027] = 0x2019,
+ -- [0x0060] = 0x2018,
+ },
+ },
+ anum = {
+ { -- arabic
+ [0x0030] = 0x0660,
+ [0x0031] = 0x0661,
+ [0x0032] = 0x0662,
+ [0x0033] = 0x0663,
+ [0x0034] = 0x0664,
+ [0x0035] = 0x0665,
+ [0x0036] = 0x0666,
+ [0x0037] = 0x0667,
+ [0x0038] = 0x0668,
+ [0x0039] = 0x0669,
+ },
+ { -- persian
+ [0x0030] = 0x06F0,
+ [0x0031] = 0x06F1,
+ [0x0032] = 0x06F2,
+ [0x0033] = 0x06F3,
+ [0x0034] = 0x06F4,
+ [0x0035] = 0x06F5,
+ [0x0036] = 0x06F6,
+ [0x0037] = 0x06F7,
+ [0x0038] = 0x06F8,
+ [0x0039] = 0x06F9,
+ },
+ },
+}
+
+local extra_features = { -- maybe just 1..n so that we prescribe order
+ tlig = {
+ {
+ features = { { scripts = { { script = "*", langs = { "*" }, } }, tag = "tlig", comment = "added bij mkiv" }, },
+ name = "ctx_tlig_1",
+ subtables = { { name = "ctx_tlig_1_s" } },
+ type = "gsub_ligature",
+ flags = { },
+ },
+ },
+ trep = {
+ {
+ features = { { scripts = { { script = "*", langs = { "*" }, } }, tag = "trep", comment = "added bij mkiv" }, },
+ name = "ctx_trep_1",
+ subtables = { { name = "ctx_trep_1_s" } },
+ type = "gsub_single",
+ flags = { },
+ },
+ },
+ anum = {
+ {
+ features = { { scripts = { { script = "arab", langs = { "dflt", "FAR" }, } }, tag = "anum", comment = "added bij mkiv" }, },
+ name = "ctx_anum_1",
+ subtables = { { name = "ctx_anum_1_s" } },
+ type = "gsub_single",
+ flags = { },
+ },
+ {
+ features = { { scripts = { { script = "arab", langs = { "URD" }, } }, tag = "anum", comment = "added bij mkiv" }, },
+ name = "ctx_anum_2",
+ subtables = { { name = "ctx_anum_2_s" } },
+ type = "gsub_single",
+ flags = { },
+ },
+ },
+}
+
+fonts.otf.enhancers["add some missing characters"] = function(data,filename)
+ -- todo
+end
+
+fonts.otf.enhancers["enrich with features"] = function(data,filename)
+ -- could be done elsewhere (true can be #)
+ local used = { }
+ for i=1,#otf.glists do
+ local g = data[otf.glists[i]]
+ if g then
+ for i=1,#g do
+ local f = g[i].features
+ if f then
+ for i=1,#f do
+ local t = f[i].tag
+ if t then used[t] = true end
+ end
+ end
+ end
+ end
+ end
+ --
+ local glyphs = data.glyphs
+ local indices = data.map.map
+ data.gsub = data.gsub or { }
+ for kind, specifications in next, extra_features do
+ if not used[kind] then
+ local done = 0
+ for s=1,#specifications do
+ local added = false
+ local specification = specifications[s]
+ local list = extra_lists[kind][s]
+ local name = specification.name .. "_s"
+ if specification.type == "gsub_ligature" then
+ for unicode, index in next, indices do
+ local glyph = glyphs[index]
+ local ligature = list[glyph.name]
+ if ligature then
+ local o = glyph.lookups or { }
+ -- o[name] = { "ligature", ligature, glyph.name }
+ o[name] = {
+ {
+ ["type"] = "ligature",
+ ["specification"] = {
+ char = glyph.name,
+ components = ligature,
+ }
+ }
+ }
+ glyph.lookups, done, added = o, done+1, true
+ end
+ end
+ elseif specification.type == "gsub_single" then
+ for unicode, index in next, indices do
+ local glyph = glyphs[index]
+ local r = list[unicode]
+ if r then
+ local replacement = indices[r]
+ if replacement and glyphs[replacement] then
+ local o = glyph.lookups or { }
+ -- o[name] = { { "substitution", glyphs[replacement].name } }
+ o[name] = {
+ {
+ ["type"] = "substitution",
+ ["specification"] = {
+ variant = glyphs[replacement].name,
+ }
+ }
+ }
+ glyph.lookups, done, added = o, done+1, true
+ end
+ end
+ end
+ end
+ if added then
+ insert(data.gsub,s,table.fastcopy(specification)) -- right order
+ end
+ end
+ if done > 0 then
+ if trace_loading then
+ logs.report("load otf","enhance: registering %s feature (%s glyphs affected)",kind,done)
+ end
+ end
+ end
+ end
+end
+
+otf.tables.features['tlig'] = 'TeX Ligatures'
+otf.tables.features['trep'] = 'TeX Replacements'
+otf.tables.features['anum'] = 'Arabic Digits'
+
+otf.features.register_base_substitution('tlig')
+otf.features.register_base_substitution('trep')
+otf.features.register_base_substitution('anum')
+
+-- the functionality is defined elsewhere
+
+fonts.initializers.base.otf.equaldigits = fonts.initializers.common.equaldigits
+fonts.initializers.node.otf.equaldigits = fonts.initializers.common.equaldigits
+
+fonts.initializers.base.otf.lineheight = fonts.initializers.common.lineheight
+fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight
+
+fonts.initializers.base.otf.compose = fonts.initializers.common.compose
+fonts.initializers.node.otf.compose = fonts.initializers.common.compose
+
+-- bonus function
+
+function otf.name_to_slot(name) -- todo: afm en tfm
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata and tfmdata.shared then
+ local otfdata = tfmdata.shared.otfdata
+ local unicode = otfdata.luatex.unicodes[name]
+ if type(unicode) == "number" then
+ return unicode
+ else
+ return unicode[1]
+ end
+ end
+ return nil
+end
+
+function otf.char(n) -- todo: afm en tfm
+ if type(n) == "string" then
+ n = otf.name_to_slot(n)
+ end
+ if n then
+ tex.sprint(ctxcatcodes,format("\\char%s ",n))
+ end
+end
diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua
new file mode 100644
index 000000000..78a828146
--- /dev/null
+++ b/tex/context/base/font-otd.lua
@@ -0,0 +1,78 @@
+if not modules then modules = { } end modules ['font-otd'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end)
+
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+
+local otf = fonts.otf
+local fontdata = fonts.ids
+
+otf.features = otf.features or { }
+otf.features.default = otf.features.default or { }
+
+local context_setups = fonts.define.specify.context_setups
+local context_numbers = fonts.define.specify.context_numbers
+
+local a_to_script = { } otf.a_to_script = a_to_script
+local a_to_language = { } otf.a_to_language = a_to_language
+
+function otf.set_dynamics(font,dynamics,attribute)
+ features = context_setups[context_numbers[attribute]] -- can be moved to caller
+ if features then
+ local script = features.script or 'dflt'
+ local language = features.language or 'dflt'
+ local ds = dynamics[script]
+ if not ds then
+ ds = { }
+ dynamics[script] = ds
+ end
+ local dsl = ds[language]
+ if not dsl then
+ dsl = { }
+ ds[language] = dsl
+ end
+ local dsla = dsl[attribute]
+ if dsla then
+ -- if trace_dynamics then
+ -- logs.report("otf define","using dynamics %s: attribute %s, script %s, language %s",context_numbers[attribute],attribute,script,language)
+ -- end
+ return dsla
+ else
+ local tfmdata = fontdata[font]
+ a_to_script [attribute] = script
+ a_to_language[attribute] = language
+ -- we need to save some values
+ local saved = {
+ script = tfmdata.script,
+ language = tfmdata.language,
+ mode = tfmdata.mode,
+ features = tfmdata.shared.features
+ }
+ tfmdata.mode = "node"
+ tfmdata.language = language
+ tfmdata.script = script
+ tfmdata.shared.features = { }
+ -- end of save
+ dsla = otf.set_features(tfmdata,fonts.define.check(features,otf.features.default))
+ if trace_dynamics then
+ logs.report("otf define","setting dynamics %s: attribute %s, script %s, language %s",context_numbers[attribute],attribute,script,language)
+ end
+ -- we need to restore some values
+ tfmdata.script = saved.script
+ tfmdata.language = saved.language
+ tfmdata.mode = saved.mode
+ tfmdata.shared.features = saved.features
+ -- end of restore
+ dynamics[script][language][attribute] = dsla -- cache
+ return dsla
+ end
+ end
+ return nil -- { }
+end
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index fffd4eeda..20273f8f5 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -6,829 +6,210 @@ if not modules then modules = { } end modules ['font-otf'] = {
license = "see context related readme files"
}
-local format, concat, getn = string.format, table.concat, table.getn
-local type, pairs, ipairs, next, tonumber, tostring = type, pairs, ipairs, next, tonumber, tostring
+local utf = unicode.utf8
-local space = lpeg.P(" ")
-local nospaces = (1-space)^1
-local optionalspace = space^0
+local concat, getn, utfbyte = table.concat, table.getn, utf.byte
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring = type, next, tonumber, tostring
-local split_at_space = lpeg.Ct((lpeg.C(nospaces) * optionalspace)^0) -- table !
+local trace_private = false trackers.register("otf.private", function(v) trace_private = v end)
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+local trace_features = false trackers.register("otf.features", function(v) trace_features = v end)
+local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end)
+local trace_sequences = false trackers.register("otf.sequences", function(v) trace_sequences = v end)
+local trace_math = false trackers.register("otf.math", function(v) trace_math = v end)
--- we can use more lpegs when lpeg is extended with function args and so
+--~ trackers.enable("otf.loading")
--- the flattening code is a prelude to a more compact table format (so, we're now
--- at the fourth version); maybe we will go unicode, although that will mean that we
--- miss some glyphs (unicode -1)
-
--- todo: featuredata is now indexed by kind,lookup but probably lookup is okay too
-
--- todo: now that we pack ... resolve strings to unicode points
--- todo: unpack already in tmc file, i.e. save tables and return ref''d version
--- todo: dependents etc resolve too, maybe even reorder glyphs to unicode
--- todo: pack ignoreflags
-
--- abvf abvs blwf blws dist falt half halt jalt lfbd ljmo
--- mset opbd palt pwid qwid rand rtbd ruby size tjmo twid valt vatu vert
--- vhal vjmo vkna vkrn vpal vrt2
-
--- The specification of OpenType is vague, very vague. Apart from a lack of proper
--- specifications (a free one) there's also the problem that Microsoft and Adobe
--- may have their own rules. Anyhow, the following is from Adobe's feature file
--- specification:
---
--- http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html#6.h
---
--- The following is a reference summary of the algorithm used by an OpenType layout
--- (OTL) engine to perform substitutions and positionings. The important aspect of
--- this for a feature file editor is that each lookup corresponds to one "pass" over
--- the glyph run (see step 4 below). Thus, each lookup has as input the accumulated
--- result of all previous lookups in the LookupList (whether in the same feature or
--- in other features).
--- 1. All glyphs in the client's glyph run must belong to the same language
--- system. Glyph sequence matching may not occur across language
--- systems. Do the following first for the GSUB and then for the GPOS:
--- 2. Assemble all features (including any required feature) for the glyph
--- run's language system.
--- 3. Assemble all lookups in these features, in LookupList order, removing
--- any duplicates. All features and thus all lookups needn't be applied to
--- every glyph in the run.
--- 4. For each lookup:
--- 5. For each glyph in the glyph run:
--- 6. If the lookup is applied to that glyph and the lookupflag doesn't
--- indicate that that glyph is to be ignored:
--- 7. For each subtable in the lookup:
--- 8. If the subtable's target context is matched:
--- 9. Do the glyph substitution or positioning,
--- --- OR: ---
--- If this is a (chain) contextual lookup do the following
--- [(10)-(11)] in the subtable's Subst/PosLookupRecord order:
--- 10. For each (sequenceIndex, lookupListIndex) pair:
--- 11. Apply lookup[lookupListIndex] at input sequence[sequenceIndex]
--- [steps (7)-(11)]
--- 12. Goto the glyph after the input sequence matched in (8)
--- (i.e. skip any remaining subtables in the lookup).
--- The "target context" in step 8 above comprises the input sequence and any
--- backtrack and lookahead sequences.
--- The input sequence must be matched entirely within the lookup's "application
--- range" at that glyph (that contiguous subrun of glyphs including and around
--- the current glyph on which the lookup is applied). There is no such restriction
--- on the backtrack and lookahead sequences.
--- "Matching" includes matching any glyphs designated to be skipped in the
--- lookup's LookupFlag.
+local zwnj = 0x200C
+local zwj = 0x200D
--[[ldx--
-<p>This module is sparsely documented because it is a moving target.
-The table format of the reader changes and we experiment a lot with
-different methods for supporting features.</p>
+<p>The fontforge table has organized lookups in a certain way. A first implementation
+of this code was organized featurewise: information related to features was
+collected and processing boiled down to a run over the features. The current
+implementation honors the order in the main feature table. Since we can reorder this
+table as we want, we can eventually support several models of processing. We kept
+the static as well as dynamic feature processing, because it had proved to be
+rather useful. The formerly three loop variants have beem discarded but will
+reapear at some time.</p>
+
+<itemize>
+<item>we loop over all lookups</item>
+<item>for each lookup we do a run over the list of glyphs</item>
+<item>but we only process them for features that are enabled</item>
+<item>if we're dealing with a contextual lookup, we loop over all contexts</item>
+<item>in that loop we quit at a match and then process the list of sublookups</item>
+<item>we always continue after the match</item>
+</itemize>
+
+<p>In <l n='context'/> we do this for each font that is used in a list, so in
+practice we have quite some nested loops.</p>
+
+<p>We process the whole list and then consult the glyph nodes. An alternative approach
+is to collect strings of characters using the same font including spaces (because some
+lookups involve spaces). However, we then need to reconstruct the list which is no fun.
+Also, we need to carry quite some information, like attributes, so eventually we don't
+gain much (if we gain something at all).</p>
+
+<p>Another consideration has been to operate on sublists (subhead, subtail) but again
+this would complicate matters as we then neext to keep track of a changing subhead
+and subtail. On the other hand, this might save some runtime. The number of changes
+involved is not that large. This only makes sense when we have many fonts in a list
+and don't change to frequently.</p>
+--ldx]]--
-<p>As with the <l n='afm'/> code, we may decide to store more information
-in the <l n='otf'/> table.</p>
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+fonts.tfm = fonts.tfm or { }
-<p>Incrementing the version number will force a re-cache. We jump the
-number by one when there's a fix in the <l n='fontforge'/> library or
-<l n='lua'/> code that results in different tables.</p>
---ldx]]--
+local otf = fonts.otf
+local tfm = fonts.tfm
---~ The node based processing functions look quite complex which is mainly due to
---~ the fact that we need to share data and cache resolved issues (saves much memory and
---~ is also faster). A further complication is that we support static as well as dynamic
---~ features.
+local fontdata = fonts.ids
-fonts = fonts or { }
-fonts.otf = fonts.otf or { }
+otf.tables = otf.tables or { } -- defined in font-ott.lua
+otf.meanings = otf.meanings or { } -- defined in font-ott.lua
+otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua
+otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua
+otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua
-local otf = fonts.otf
-local tfm = fonts.tfm
+otf.features = otf.features or { }
+otf.features.list = otf.features.list or { }
+otf.features.default = otf.features.default or { }
-otf.version = 2.24
-otf.pack = true
-otf.tables = otf.tables or { }
-otf.meanings = otf.meanings or { }
-otf.enhance_data = false
-otf.syncspace = true
-otf.features = { }
-otf.features.aux = { }
-otf.features.data = { }
-otf.features.list = { } -- not (yet) used, oft fonts have gpos/gsub lists
-otf.features.default = { }
-otf.trace_features = false
-otf.trace_set_features = false
-otf.trace_replacements = false
-otf.trace_contexts = false
-otf.trace_anchors = false
-otf.trace_ligatures = false
-otf.trace_kerns = false
-otf.trace_cursive = false
-otf.notdef = false
-otf.cache = containers.define("fonts", "otf", otf.version, true)
+otf.enhancers = otf.enhancers or { }
+otf.glists = { "gsub", "gpos" }
-function otf.trace_process()
- otf.trace_replacements = true
- otf.trace_contexts = true
- otf.trace_anchors = true
- otf.trace_ligatures = true
- otf.trace_kerns = true
- otf.trace_cursive = true
-end
+otf.version = 2.626 -- beware: also sync font-mis.lua
+otf.pack = true -- beware: also sync font-mis.lua
+otf.syncspace = true
+otf.notdef = false
+otf.cache = containers.define("fonts", "otf", otf.version, true)
+otf.cleanup_aat = false -- only context
--[[ldx--
<p>We start with a lot of tables and related functions.</p>
--ldx]]--
-otf.tables.scripts = {
- ['dflt'] = 'Default',
-
- ['arab'] = 'Arabic',
- ['armn'] = 'Armenian',
- ['bali'] = 'Balinese',
- ['beng'] = 'Bengali',
- ['bopo'] = 'Bopomofo',
- ['brai'] = 'Braille',
- ['bugi'] = 'Buginese',
- ['buhd'] = 'Buhid',
- ['byzm'] = 'Byzantine Music',
- ['cans'] = 'Canadian Syllabics',
- ['cher'] = 'Cherokee',
- ['copt'] = 'Coptic',
- ['cprt'] = 'Cypriot Syllabary',
- ['cyrl'] = 'Cyrillic',
- ['deva'] = 'Devanagari',
- ['dsrt'] = 'Deseret',
- ['ethi'] = 'Ethiopic',
- ['geor'] = 'Georgian',
- ['glag'] = 'Glagolitic',
- ['goth'] = 'Gothic',
- ['grek'] = 'Greek',
- ['gujr'] = 'Gujarati',
- ['guru'] = 'Gurmukhi',
- ['hang'] = 'Hangul',
- ['hani'] = 'CJK Ideographic',
- ['hano'] = 'Hanunoo',
- ['hebr'] = 'Hebrew',
- ['ital'] = 'Old Italic',
- ['jamo'] = 'Hangul Jamo',
- ['java'] = 'Javanese',
- ['kana'] = 'Hiragana and Katakana',
- ['khar'] = 'Kharosthi',
- ['khmr'] = 'Khmer',
- ['knda'] = 'Kannada',
- ['lao' ] = 'Lao',
- ['latn'] = 'Latin',
- ['limb'] = 'Limbu',
- ['linb'] = 'Linear B',
- ['math'] = 'Mathematical Alphanumeric Symbols',
- ['mlym'] = 'Malayalam',
- ['mong'] = 'Mongolian',
- ['musc'] = 'Musical Symbols',
- ['mymr'] = 'Myanmar',
- ['nko' ] = "N'ko",
- ['ogam'] = 'Ogham',
- ['orya'] = 'Oriya',
- ['osma'] = 'Osmanya',
- ['phag'] = 'Phags-pa',
- ['phnx'] = 'Phoenician',
- ['runr'] = 'Runic',
- ['shaw'] = 'Shavian',
- ['sinh'] = 'Sinhala',
- ['sylo'] = 'Syloti Nagri',
- ['syrc'] = 'Syriac',
- ['tagb'] = 'Tagbanwa',
- ['tale'] = 'Tai Le',
- ['talu'] = 'Tai Lu',
- ['taml'] = 'Tamil',
- ['telu'] = 'Telugu',
- ['tfng'] = 'Tifinagh',
- ['tglg'] = 'Tagalog',
- ['thaa'] = 'Thaana',
- ['thai'] = 'Thai',
- ['tibt'] = 'Tibetan',
- ['ugar'] = 'Ugaritic Cuneiform',
- ['xpeo'] = 'Old Persian Cuneiform',
- ['xsux'] = 'Sumero-Akkadian Cuneiform',
- ['yi' ] = 'Yi'
-}
-
-otf.tables.languages = {
- ['dflt'] = 'Default',
-
- ['aba'] = 'Abaza',
- ['abk'] = 'Abkhazian',
- ['ady'] = 'Adyghe',
- ['afk'] = 'Afrikaans',
- ['afr'] = 'Afar',
- ['agw'] = 'Agaw',
- ['als'] = 'Alsatian',
- ['alt'] = 'Altai',
- ['amh'] = 'Amharic',
- ['ara'] = 'Arabic',
- ['ari'] = 'Aari',
- ['ark'] = 'Arakanese',
- ['asm'] = 'Assamese',
- ['ath'] = 'Athapaskan',
- ['avr'] = 'Avar',
- ['awa'] = 'Awadhi',
- ['aym'] = 'Aymara',
- ['aze'] = 'Azeri',
- ['bad'] = 'Badaga',
- ['bag'] = 'Baghelkhandi',
- ['bal'] = 'Balkar',
- ['bau'] = 'Baule',
- ['bbr'] = 'Berber',
- ['bch'] = 'Bench',
- ['bcr'] = 'Bible Cree',
- ['bel'] = 'Belarussian',
- ['bem'] = 'Bemba',
- ['ben'] = 'Bengali',
- ['bgr'] = 'Bulgarian',
- ['bhi'] = 'Bhili',
- ['bho'] = 'Bhojpuri',
- ['bik'] = 'Bikol',
- ['bil'] = 'Bilen',
- ['bkf'] = 'Blackfoot',
- ['bli'] = 'Balochi',
- ['bln'] = 'Balante',
- ['blt'] = 'Balti',
- ['bmb'] = 'Bambara',
- ['bml'] = 'Bamileke',
- ['bos'] = 'Bosnian',
- ['bre'] = 'Breton',
- ['brh'] = 'Brahui',
- ['bri'] = 'Braj Bhasha',
- ['brm'] = 'Burmese',
- ['bsh'] = 'Bashkir',
- ['bti'] = 'Beti',
- ['cat'] = 'Catalan',
- ['ceb'] = 'Cebuano',
- ['che'] = 'Chechen',
- ['chg'] = 'Chaha Gurage',
- ['chh'] = 'Chattisgarhi',
- ['chi'] = 'Chichewa',
- ['chk'] = 'Chukchi',
- ['chp'] = 'Chipewyan',
- ['chr'] = 'Cherokee',
- ['chu'] = 'Chuvash',
- ['cmr'] = 'Comorian',
- ['cop'] = 'Coptic',
- ['cos'] = 'Corsican',
- ['cre'] = 'Cree',
- ['crr'] = 'Carrier',
- ['crt'] = 'Crimean Tatar',
- ['csl'] = 'Church Slavonic',
- ['csy'] = 'Czech',
- ['dan'] = 'Danish',
- ['dar'] = 'Dargwa',
- ['dcr'] = 'Woods Cree',
- ['deu'] = 'German',
- ['dgr'] = 'Dogri',
- ['div'] = 'Divehi',
- ['djr'] = 'Djerma',
- ['dng'] = 'Dangme',
- ['dnk'] = 'Dinka',
- ['dri'] = 'Dari',
- ['dun'] = 'Dungan',
- ['dzn'] = 'Dzongkha',
- ['ebi'] = 'Ebira',
- ['ecr'] = 'Eastern Cree',
- ['edo'] = 'Edo',
- ['efi'] = 'Efik',
- ['ell'] = 'Greek',
- ['eng'] = 'English',
- ['erz'] = 'Erzya',
- ['esp'] = 'Spanish',
- ['eti'] = 'Estonian',
- ['euq'] = 'Basque',
- ['evk'] = 'Evenki',
- ['evn'] = 'Even',
- ['ewe'] = 'Ewe',
- ['fan'] = 'French Antillean',
- ['far'] = 'Farsi',
- ['fin'] = 'Finnish',
- ['fji'] = 'Fijian',
- ['fle'] = 'Flemish',
- ['fne'] = 'Forest Nenets',
- ['fon'] = 'Fon',
- ['fos'] = 'Faroese',
- ['fra'] = 'French',
- ['fri'] = 'Frisian',
- ['frl'] = 'Friulian',
- ['fta'] = 'Futa',
- ['ful'] = 'Fulani',
- ['gad'] = 'Ga',
- ['gae'] = 'Gaelic',
- ['gag'] = 'Gagauz',
- ['gal'] = 'Galician',
- ['gar'] = 'Garshuni',
- ['gaw'] = 'Garhwali',
- ['gez'] = "Ge'ez",
- ['gil'] = 'Gilyak',
- ['gmz'] = 'Gumuz',
- ['gon'] = 'Gondi',
- ['grn'] = 'Greenlandic',
- ['gro'] = 'Garo',
- ['gua'] = 'Guarani',
- ['guj'] = 'Gujarati',
- ['hai'] = 'Haitian',
- ['hal'] = 'Halam',
- ['har'] = 'Harauti',
- ['hau'] = 'Hausa',
- ['haw'] = 'Hawaiin',
- ['hbn'] = 'Hammer-Banna',
- ['hil'] = 'Hiligaynon',
- ['hin'] = 'Hindi',
- ['hma'] = 'High Mari',
- ['hnd'] = 'Hindko',
- ['ho'] = 'Ho',
- ['hri'] = 'Harari',
- ['hrv'] = 'Croatian',
- ['hun'] = 'Hungarian',
- ['hye'] = 'Armenian',
- ['ibo'] = 'Igbo',
- ['ijo'] = 'Ijo',
- ['ilo'] = 'Ilokano',
- ['ind'] = 'Indonesian',
- ['ing'] = 'Ingush',
- ['inu'] = 'Inuktitut',
- ['iri'] = 'Irish',
- ['irt'] = 'Irish Traditional',
- ['isl'] = 'Icelandic',
- ['ism'] = 'Inari Sami',
- ['ita'] = 'Italian',
- ['iwr'] = 'Hebrew',
- ['jan'] = 'Japanese',
- ['jav'] = 'Javanese',
- ['jii'] = 'Yiddish',
- ['jud'] = 'Judezmo',
- ['jul'] = 'Jula',
- ['kab'] = 'Kabardian',
- ['kac'] = 'Kachchi',
- ['kal'] = 'Kalenjin',
- ['kan'] = 'Kannada',
- ['kar'] = 'Karachay',
- ['kat'] = 'Georgian',
- ['kaz'] = 'Kazakh',
- ['keb'] = 'Kebena',
- ['kge'] = 'Khutsuri Georgian',
- ['kha'] = 'Khakass',
- ['khk'] = 'Khanty-Kazim',
- ['khm'] = 'Khmer',
- ['khs'] = 'Khanty-Shurishkar',
- ['khv'] = 'Khanty-Vakhi',
- ['khw'] = 'Khowar',
- ['kik'] = 'Kikuyu',
- ['kir'] = 'Kirghiz',
- ['kis'] = 'Kisii',
- ['kkn'] = 'Kokni',
- ['klm'] = 'Kalmyk',
- ['kmb'] = 'Kamba',
- ['kmn'] = 'Kumaoni',
- ['kmo'] = 'Komo',
- ['kms'] = 'Komso',
- ['knr'] = 'Kanuri',
- ['kod'] = 'Kodagu',
- ['koh'] = 'Korean Old Hangul',
- ['kok'] = 'Konkani',
- ['kon'] = 'Kikongo',
- ['kop'] = 'Komi-Permyak',
- ['kor'] = 'Korean',
- ['koz'] = 'Komi-Zyrian',
- ['kpl'] = 'Kpelle',
- ['kri'] = 'Krio',
- ['krk'] = 'Karakalpak',
- ['krl'] = 'Karelian',
- ['krm'] = 'Karaim',
- ['krn'] = 'Karen',
- ['krt'] = 'Koorete',
- ['ksh'] = 'Kashmiri',
- ['ksi'] = 'Khasi',
- ['ksm'] = 'Kildin Sami',
- ['kui'] = 'Kui',
- ['kul'] = 'Kulvi',
- ['kum'] = 'Kumyk',
- ['kur'] = 'Kurdish',
- ['kuu'] = 'Kurukh',
- ['kuy'] = 'Kuy',
- ['kyk'] = 'Koryak',
- ['lad'] = 'Ladin',
- ['lah'] = 'Lahuli',
- ['lak'] = 'Lak',
- ['lam'] = 'Lambani',
- ['lao'] = 'Lao',
- ['lat'] = 'Latin',
- ['laz'] = 'Laz',
- ['lcr'] = 'L-Cree',
- ['ldk'] = 'Ladakhi',
- ['lez'] = 'Lezgi',
- ['lin'] = 'Lingala',
- ['lma'] = 'Low Mari',
- ['lmb'] = 'Limbu',
- ['lmw'] = 'Lomwe',
- ['lsb'] = 'Lower Sorbian',
- ['lsm'] = 'Lule Sami',
- ['lth'] = 'Lithuanian',
- ['ltz'] = 'Luxembourgish',
- ['lub'] = 'Luba',
- ['lug'] = 'Luganda',
- ['luh'] = 'Luhya',
- ['luo'] = 'Luo',
- ['lvi'] = 'Latvian',
- ['maj'] = 'Majang',
- ['mak'] = 'Makua',
- ['mal'] = 'Malayalam Traditional',
- ['man'] = 'Mansi',
- ['map'] = 'Mapudungun',
- ['mar'] = 'Marathi',
- ['maw'] = 'Marwari',
- ['mbn'] = 'Mbundu',
- ['mch'] = 'Manchu',
- ['mcr'] = 'Moose Cree',
- ['mde'] = 'Mende',
- ['men'] = "Me'en",
- ['miz'] = 'Mizo',
- ['mkd'] = 'Macedonian',
- ['mle'] = 'Male',
- ['mlg'] = 'Malagasy',
- ['mln'] = 'Malinke',
- ['mlr'] = 'Malayalam Reformed',
- ['mly'] = 'Malay',
- ['mnd'] = 'Mandinka',
- ['mng'] = 'Mongolian',
- ['mni'] = 'Manipuri',
- ['mnk'] = 'Maninka',
- ['mnx'] = 'Manx Gaelic',
- ['moh'] = 'Mohawk',
- ['mok'] = 'Moksha',
- ['mol'] = 'Moldavian',
- ['mon'] = 'Mon',
- ['mor'] = 'Moroccan',
- ['mri'] = 'Maori',
- ['mth'] = 'Maithili',
- ['mts'] = 'Maltese',
- ['mun'] = 'Mundari',
- ['nag'] = 'Naga-Assamese',
- ['nan'] = 'Nanai',
- ['nas'] = 'Naskapi',
- ['ncr'] = 'N-Cree',
- ['ndb'] = 'Ndebele',
- ['ndg'] = 'Ndonga',
- ['nep'] = 'Nepali',
- ['new'] = 'Newari',
- ['ngr'] = 'Nagari',
- ['nhc'] = 'Norway House Cree',
- ['nis'] = 'Nisi',
- ['niu'] = 'Niuean',
- ['nkl'] = 'Nkole',
- ['nko'] = "N'ko",
- ['nld'] = 'Dutch',
- ['nog'] = 'Nogai',
- ['nor'] = 'Norwegian',
- ['nsm'] = 'Northern Sami',
- ['nta'] = 'Northern Tai',
- ['nto'] = 'Esperanto',
- ['nyn'] = 'Nynorsk',
- ['oci'] = 'Occitan',
- ['ocr'] = 'Oji-Cree',
- ['ojb'] = 'Ojibway',
- ['ori'] = 'Oriya',
- ['oro'] = 'Oromo',
- ['oss'] = 'Ossetian',
- ['paa'] = 'Palestinian Aramaic',
- ['pal'] = 'Pali',
- ['pan'] = 'Punjabi',
- ['pap'] = 'Palpa',
- ['pas'] = 'Pashto',
- ['pgr'] = 'Polytonic Greek',
- ['pil'] = 'Pilipino',
- ['plg'] = 'Palaung',
- ['plk'] = 'Polish',
- ['pro'] = 'Provencal',
- ['ptg'] = 'Portuguese',
- ['qin'] = 'Chin',
- ['raj'] = 'Rajasthani',
- ['rbu'] = 'Russian Buriat',
- ['rcr'] = 'R-Cree',
- ['ria'] = 'Riang',
- ['rms'] = 'Rhaeto-Romanic',
- ['rom'] = 'Romanian',
- ['roy'] = 'Romany',
- ['rsy'] = 'Rusyn',
- ['rua'] = 'Ruanda',
- ['rus'] = 'Russian',
- ['sad'] = 'Sadri',
- ['san'] = 'Sanskrit',
- ['sat'] = 'Santali',
- ['say'] = 'Sayisi',
- ['sek'] = 'Sekota',
- ['sel'] = 'Selkup',
- ['sgo'] = 'Sango',
- ['shn'] = 'Shan',
- ['sib'] = 'Sibe',
- ['sid'] = 'Sidamo',
- ['sig'] = 'Silte Gurage',
- ['sks'] = 'Skolt Sami',
- ['sky'] = 'Slovak',
- ['sla'] = 'Slavey',
- ['slv'] = 'Slovenian',
- ['sml'] = 'Somali',
- ['smo'] = 'Samoan',
- ['sna'] = 'Sena',
- ['snd'] = 'Sindhi',
- ['snh'] = 'Sinhalese',
- ['snk'] = 'Soninke',
- ['sog'] = 'Sodo Gurage',
- ['sot'] = 'Sotho',
- ['sqi'] = 'Albanian',
- ['srb'] = 'Serbian',
- ['srk'] = 'Saraiki',
- ['srr'] = 'Serer',
- ['ssl'] = 'South Slavey',
- ['ssm'] = 'Southern Sami',
- ['sur'] = 'Suri',
- ['sva'] = 'Svan',
- ['sve'] = 'Swedish',
- ['swa'] = 'Swadaya Aramaic',
- ['swk'] = 'Swahili',
- ['swz'] = 'Swazi',
- ['sxt'] = 'Sutu',
- ['syr'] = 'Syriac',
- ['tab'] = 'Tabasaran',
- ['taj'] = 'Tajiki',
- ['tam'] = 'Tamil',
- ['tat'] = 'Tatar',
- ['tcr'] = 'TH-Cree',
- ['tel'] = 'Telugu',
- ['tgn'] = 'Tongan',
- ['tgr'] = 'Tigre',
- ['tgy'] = 'Tigrinya',
- ['tha'] = 'Thai',
- ['tht'] = 'Tahitian',
- ['tib'] = 'Tibetan',
- ['tkm'] = 'Turkmen',
- ['tmn'] = 'Temne',
- ['tna'] = 'Tswana',
- ['tne'] = 'Tundra Nenets',
- ['tng'] = 'Tonga',
- ['tod'] = 'Todo',
- ['trk'] = 'Turkish',
- ['tsg'] = 'Tsonga',
- ['tua'] = 'Turoyo Aramaic',
- ['tul'] = 'Tulu',
- ['tuv'] = 'Tuvin',
- ['twi'] = 'Twi',
- ['udm'] = 'Udmurt',
- ['ukr'] = 'Ukrainian',
- ['urd'] = 'Urdu',
- ['usb'] = 'Upper Sorbian',
- ['uyg'] = 'Uyghur',
- ['uzb'] = 'Uzbek',
- ['ven'] = 'Venda',
- ['vit'] = 'Vietnamese',
- ['wa' ] = 'Wa',
- ['wag'] = 'Wagdi',
- ['wcr'] = 'West-Cree',
- ['wel'] = 'Welsh',
- ['wlf'] = 'Wolof',
- ['xbd'] = 'Tai Lue',
- ['xhs'] = 'Xhosa',
- ['yak'] = 'Yakut',
- ['yba'] = 'Yoruba',
- ['ycr'] = 'Y-Cree',
- ['yic'] = 'Yi Classic',
- ['yim'] = 'Yi Modern',
- ['zhh'] = 'Chinese Hong Kong',
- ['zhp'] = 'Chinese Phonetic',
- ['zhs'] = 'Chinese Simplified',
- ['zht'] = 'Chinese Traditional',
- ['znd'] = 'Zande',
- ['zul'] = 'Zulu'
-}
-
-otf.tables.features = {
- ['aalt'] = 'Access All Alternates',
- ['abvf'] = 'Above-Base Forms',
- ['abvm'] = 'Above-Base Mark Positioning',
- ['abvs'] = 'Above-Base Substitutions',
- ['afrc'] = 'Alternative Fractions',
- ['akhn'] = 'Akhands',
- ['blwf'] = 'Below-Base Forms',
- ['blwm'] = 'Below-Base Mark Positioning',
- ['blws'] = 'Below-Base Substitutions',
- ['c2pc'] = 'Petite Capitals From Capitals',
- ['c2sc'] = 'Small Capitals From Capitals',
- ['calt'] = 'Contextual Alternates',
- ['case'] = 'Case-Sensitive Forms',
- ['ccmp'] = 'Glyph Composition/Decomposition',
- ['cjct'] = 'Conjunct Forms',
- ['clig'] = 'Contextual Ligatures',
- ['cpsp'] = 'Capital Spacing',
- ['cswh'] = 'Contextual Swash',
- ['curs'] = 'Cursive Positioning',
- ['dflt'] = 'Default Processing',
- ['dist'] = 'Distances',
- ['dlig'] = 'Discretionary Ligatures',
- ['dnom'] = 'Denominators',
- ['expt'] = 'Expert Forms',
- ['falt'] = 'Final glyph Alternates',
- ['fin2'] = 'Terminal Forms #2',
- ['fin3'] = 'Terminal Forms #3',
- ['fina'] = 'Terminal Forms',
- ['frac'] = 'Fractions',
- ['fwid'] = 'Full Width',
- ['half'] = 'Half Forms',
- ['haln'] = 'Halant Forms',
- ['halt'] = 'Alternate Half Width',
- ['hist'] = 'Historical Forms',
- ['hkna'] = 'Horizontal Kana Alternates',
- ['hlig'] = 'Historical Ligatures',
- ['hngl'] = 'Hangul',
- ['hojo'] = 'Hojo Kanji Forms',
- ['hwid'] = 'Half Width',
- ['init'] = 'Initial Forms',
- ['isol'] = 'Isolated Forms',
- ['ital'] = 'Italics',
- ['jalt'] = 'Justification Alternatives',
- ['jp04'] = 'JIS2004 Forms',
- ['jp78'] = 'JIS78 Forms',
- ['jp83'] = 'JIS83 Forms',
- ['jp90'] = 'JIS90 Forms',
- ['kern'] = 'Kerning',
- ['lfbd'] = 'Left Bounds',
- ['liga'] = 'Standard Ligatures',
- ['ljmo'] = 'Leading Jamo Forms',
- ['lnum'] = 'Lining Figures',
- ['locl'] = 'Localized Forms',
- ['mark'] = 'Mark Positioning',
- ['med2'] = 'Medial Forms #2',
- ['medi'] = 'Medial Forms',
- ['mgrk'] = 'Mathematical Greek',
- ['mkmk'] = 'Mark to Mark Positioning',
- ['mset'] = 'Mark Positioning via Substitution',
- ['nalt'] = 'Alternate Annotation Forms',
- ['nlck'] = 'NLC Kanji Forms',
- ['nukt'] = 'Nukta Forms',
- ['numr'] = 'Numerators',
- ['onum'] = 'Old Style Figures',
- ['opbd'] = 'Optical Bounds',
- ['ordn'] = 'Ordinals',
- ['ornm'] = 'Ornaments',
- ['palt'] = 'Proportional Alternate Width',
- ['pcap'] = 'Petite Capitals',
- ['pnum'] = 'Proportional Figures',
- ['pref'] = 'Pre-base Forms',
- ['pres'] = 'Pre-base Substitutions',
- ['pstf'] = 'Post-base Forms',
- ['psts'] = 'Post-base Substitutions',
- ['pwid'] = 'Proportional Widths',
- ['qwid'] = 'Quarter Widths',
- ['rand'] = 'Randomize',
- ['rkrf'] = 'Rakar Forms',
- ['rlig'] = 'Required Ligatures',
- ['rphf'] = 'Reph Form',
- ['rtbd'] = 'Right Bounds',
- ['rtla'] = 'Right-To-Left Alternates',
- ['ruby'] = 'Ruby Notation Forms',
- ['salt'] = 'Stylistic Alternates',
- ['sinf'] = 'Scientific Inferiors',
- ['size'] = 'Optical Size',
- ['smcp'] = 'Small Capitals',
- ['smpl'] = 'Simplified Forms',
- ['ss01'] = 'Stylistic Set 1',
- ['ss02'] = 'Stylistic Set 2',
- ['ss03'] = 'Stylistic Set 3',
- ['ss04'] = 'Stylistic Set 4',
- ['ss05'] = 'Stylistic Set 5',
- ['ss06'] = 'Stylistic Set 6',
- ['ss07'] = 'Stylistic Set 7',
- ['ss08'] = 'Stylistic Set 8',
- ['ss09'] = 'Stylistic Set 9',
- ['ss10'] = 'Stylistic Set 10',
- ['ss11'] = 'Stylistic Set 11',
- ['ss12'] = 'Stylistic Set 12',
- ['ss13'] = 'Stylistic Set 13',
- ['ss14'] = 'Stylistic Set 14',
- ['ss15'] = 'Stylistic Set 15',
- ['ss16'] = 'Stylistic Set 16',
- ['ss17'] = 'Stylistic Set 17',
- ['ss18'] = 'Stylistic Set 18',
- ['ss19'] = 'Stylistic Set 19',
- ['ss20'] = 'Stylistic Set 20',
- ['subs'] = 'Subscript',
- ['sups'] = 'Superscript',
- ['swsh'] = 'Swash',
- ['titl'] = 'Titling',
- ['tjmo'] = 'Trailing Jamo Forms',
- ['tnam'] = 'Traditional Name Forms',
- ['tnum'] = 'Tabular Figures',
- ['trad'] = 'Traditional Forms',
- ['twid'] = 'Third Widths',
- ['unic'] = 'Unicase',
- ['valt'] = 'Alternate Vertical Metrics',
- ['vatu'] = 'Vattu Variants',
- ['vert'] = 'Vertical Writing',
- ['vhal'] = 'Alternate Vertical Half Metrics',
- ['vjmo'] = 'Vowel Jamo Forms',
- ['vkna'] = 'Vertical Kana Alternates',
- ['vkrn'] = 'Vertical Kerning',
- ['vpal'] = 'Proportional Alternate Vertical Metrics',
- ['vrt2'] = 'Vertical Rotation',
- ['zero'] = 'Slashed Zero'
+otf.tables.global_fields = table.tohash {
+ "lookups",
+ "glyphs",
+ "subfonts",
+ "luatex",
+ "pfminfo",
+ "cidinfo",
+ "tables",
+ "names",
+ "unicodes",
+ "names",
+ "anchor_classes",
+ "kern_classes",
+ "gpos",
+ "gsub"
}
-otf.tables.baselines = {
- ['hang'] = 'Hanging baseline',
- ['icfb'] = 'Ideographic character face bottom edge baseline',
- ['icft'] = 'Ideographic character face tope edige baseline',
- ['ideo'] = 'Ideographic em-box bottom edge baseline',
- ['idtp'] = 'Ideographic em-box top edge baseline',
- ['math'] = 'Mathmatical centered baseline',
- ['romn'] = 'Roman baseline'
+otf.tables.valid_fields = {
+ "anchor_classes",
+ "ascent",
+ "cache_version",
+ "cidinfo",
+ "copyright",
+ "creationtime",
+ "descent",
+ "design_range_bottom",
+ "design_range_top",
+ "design_size",
+ "encodingchanged",
+ "extrema_bound",
+ "familyname",
+ "fontname",
+ "fontstyle_id",
+ "fontstyle_name",
+ "fullname",
+ "glyphs",
+ "hasvmetrics",
+ "head_optimized_for_cleartype",
+ "horiz_base",
+ "issans",
+ "isserif",
+ "italicangle",
+ "kerns",
+ "lookups",
+ -- "luatex",
+ "macstyle",
+ "modificationtime",
+ "onlybitmaps",
+ "origname",
+ "os2_version",
+ "pfminfo",
+ "private",
+ "serifcheck",
+ "sfd_version",
+ -- "size",
+ "strokedfont",
+ "strokewidth",
+ "subfonts",
+ "table_version",
+ -- "tables",
+ -- "ttf_tab_saved",
+ "ttf_tables",
+ "uni_interp",
+ "uniqueid",
+ "units_per_em",
+ "upos",
+ "use_typo_metrics",
+ "uwidth",
+ "validation_state",
+ "verbose",
+ "version",
+ "vert_base",
+ "weight",
+ "weight_width_slope_only",
+ "xuid",
}
-function otf.tables.to_tag(id)
- return stringformat("%4s",id:lower())
-end
+--[[ldx--
+<p>Here we go.</p>
+--ldx]]--
-function otf.meanings.resolve(tab,id)
- if tab and id then
- id = id:lower()
- return tab[id] or tab[id:gsub(" ","")] or tab['dflt'] or ''
- else
- return "unknown"
+local function load_featurefile(ff,featurefile)
+ if featurefile then
+ featurefile = resolvers.find_file(file.addsuffix(featurefile,'fea')) -- "FONTFEATURES"
+ if featurefile and featurefile ~= "" then
+ if trace_loading then
+ logs.report("load otf", "featurefile: %s", featurefile)
+ end
+ fontloader.apply_featurefile(ff, featurefile)
+ end
end
end
-function otf.meanings.script(id)
- return otf.meanings.resolve(otf.tables.scripts,id)
-end
-function otf.meanings.language(id)
- return otf.meanings.resolve(otf.tables.languages,id)
-end
-function otf.meanings.feature(id)
- return otf.meanings.resolve(otf.tables.features,id)
-end
-function otf.meanings.baseline(id)
- return otf.meanings.resolve(otf.tables.baselines,id)
-end
-
-otf.tables.to_scripts = table.reverse_hash(otf.tables.scripts )
-otf.tables.to_languages = table.reverse_hash(otf.tables.languages)
-otf.tables.to_features = table.reverse_hash(otf.tables.features )
-
-do
-
- local scripts = otf.tables.scripts
- local languages = otf.tables.languages
- local features = otf.tables.features
-
- local to_scripts = otf.tables.to_scripts
- local to_languages = otf.tables.to_languages
- local to_features = otf.tables.to_features
-
- function otf.meanings.normalize(features)
- local h = { }
- for k,v in pairs(features) do
- k = k:lower() -- :gsub("[^a-z0-9%-%.]" -- not needed
- if k == "language" or k == "lang" then
- v = (v:lower()):gsub("[^a-z0-9%-]","")
- k = language
- if not languages[v] then
- h.language = to_languages[v] or "dflt"
- else
- h.language = v
- end
- elseif k == "script" then
- v = (v:lower()):gsub("[^a-z0-9%-]","")
- if not scripts[v] then
- h.script = to_scripts[v] or "dflt"
- else
- h.script = v
- end
- else
- if type(v) == "string" then
- local b = v:is_boolean()
- if type(b) == "nil" then
- v = tonumber(v) or v:lower() -- gsub("[^a-z0-9%-]") -- too dangerous, e.g. featurefiles
- else
- v = b
- end
- end
- h[to_features[k] or k] = v
- end
+function otf.enhance(name,data,filename,verbose)
+ local enhancer = otf.enhancers[name]
+ if enhancer then
+ if (verbose ~= nil and verbose) or trace_loading then
+ logs.report("load otf","enhance: %s",name)
end
- return h
+ enhancer(data,filename)
end
-
end
---[[ldx--
-<p>Here we go.</p>
---ldx]]--
-
-otf.enhance = otf.enhance or { }
-otf.enhance.add_kerns = true
-
-otf.featurefiles = {
---~ "texhistoric.fea"
+local enhancers = {
+ -- pack and unpack are handled separately; they might even be moved
+ -- away from the enhancers namespace
+ "patch bugs",
+ "merge cid fonts", "prepare unicode", "cleanup ttf tables", "compact glyphs", "reverse coverage",
+ "cleanup aat", "enrich with features", "add some missing characters",
+ "reorganize kerns", -- moved here
+ "flatten glyph lookups", "flatten anchor tables", "flatten feature tables",
+ "prepare luatex tables",
+ "analyse features", "rehash features",
+ "analyse anchors", "analyse marks", "analyse unicodes", "analyse subtables",
+ "check italic correction","check math",
+ "share widths",
+ "strip not needed data",
+ "migrate metadata",
}
function otf.load(filename,format,sub,featurefile)
@@ -838,72 +219,45 @@ function otf.load(filename,format,sub,featurefile)
end
if sub == "" then sub = false end
local hash = name
- if sub then -- name cleanup will move to cache code
+ if sub then
hash = hash .. "-" .. sub
- hash = hash:lower()
- hash = hash:gsub("[^%w%d]+","-")
end
+ hash = containers.cleanname(hash)
local data = containers.read(otf.cache(), hash)
- if data and data.verbose ~= fonts.verbose then
- data = nil
- end
local size = lfs.attributes(filename,"size") or 0
- if data and data.size ~= size then
- data = nil
- end
- if not data then
+ if not data or data.verbose ~= fonts.verbose or data.size ~= size then
logs.report("load otf","loading: %s",filename)
local ff, messages
if sub then
- ff, messages = fontforge.open(filename,sub)
+ ff, messages = fontloader.open(filename,sub)
else
- ff, messages = fontforge.open(filename)
+ ff, messages = fontloader.open(filename)
end
- if messages and #messages > 0 then
- for _, m in ipairs(messages) do
- logs.report("load otf","warning: %s",m)
+ if trace_loading and messages and #messages > 0 then
+ for m=1,#messages do
+ logs.report("load otf","warning: %s",messages[m])
end
end
if ff then
- local function load_featurefile(featurefile)
- if featurefile then
- featurefile = input.find_file(file.addsuffix(featurefile,'fea')) -- "FONTFEATURES"
- if featurefile and featurefile ~= "" then
- logs.report("load otf", "featurefile: %s", featurefile)
- fontforge.apply_featurefile(ff, featurefile)
- end
- end
- end
- -- for _, featurefile in pairs(otf.featurefiles) do
- -- load_featurefile(featurefile)
- -- end
- load_featurefile(featurefile)
- data = fontforge.to_table(ff)
- fontforge.close(ff)
+ load_featurefile(ff,featurefile)
+ data = fontloader.to_table(ff)
+ fontloader.close(ff)
if data then
- logs.report("load otf","enhance: patch")
- otf.enhance.patch(data,filename)
- logs.report("load otf","enhance: before")
- otf.enhance.before(data,filename)
- logs.report("load otf","enhance: enrich")
- otf.enhance.enrich(data,filename)
- logs.report("load otf","enhance: flatten")
- otf.enhance.flatten(data,filename)
- logs.report("load otf","enhance: analyze")
- otf.enhance.analyze(data,filename)
- logs.report("load otf","enhance: after")
- otf.enhance.after(data,filename)
- logs.report("load otf","enhance: strip")
- otf.enhance.strip(data,filename)
+ logs.report("load otf","file size: %s", size)
+ logs.report("load otf","enhancing ...")
+ for e=1,#enhancers do
+ otf.enhance(enhancers[e],data,filename)
+ end
if otf.pack and not fonts.verbose then
- logs.report("load otf","enhance: pack")
- otf.enhance.pack(data)
+ otf.enhance("pack",data,filename)
end
- logs.report("load otf","file size: %s", size)
data.size = size
data.verbose = fonts.verbose
- logs.report("load otf","saving: in cache")
+ logs.report("load otf","saving in cache: %s",filename)
data = containers.write(otf.cache(), hash, data)
+ collectgarbage("collect")
+ data = containers.read(otf.cache(), hash) -- this frees the old table and load the sparse one
+ collectgarbage("collect")
else
logs.report("load otf","loading failed (table conversion error)")
end
@@ -911,375 +265,357 @@ function otf.load(filename,format,sub,featurefile)
logs.report("load otf","loading failed (file read error)")
end
end
- otf.enhance.unpack(data)
+ if data then
+ otf.enhance("unpack",data,filename,false) -- no message here
+ otf.add_dimensions(data)
+ if trace_sequences then
+ otf.show_feature_order(data,filename)
+ end
+ end
return data
end
--- memory saver ..
-
-local criterium, threshold = 1, 0
-
-function otf.enhance.pack(data)
+function otf.add_dimensions(data)
+ -- todo: forget about the width if it's the defaultwidth (saves mem)
+ -- we could also build the marks hash here (instead of storing it)
if data then
- local h, t, c = { }, { }, { }
- local hh, tt, cc = { }, { }, { }
- local function tabstr(t)
- for i=1,#t do
- -- tricky, was if type(t[i]) == "boolean" then, but if no [1] then error
- local ti = type(t[i])
- if ti ~= "string" or ti ~= "number" then
- local s = tostring(t[1])
- for i=2,#t do
- s = s .. ",".. tostring(t[i])
- end
- return s
- end
- end
- return concat(t,",")
- end
- for pass=1,2 do
- local pack
- if pass == 1 then
- pack = function(v)
- -- v == table
- local tag = tabstr(v,",")
- local ht = h[tag]
- if not ht then
- ht = #t+1
- t[ht] = v
- h[tag] = ht
- c[ht] = 1
- else
- c[ht] = c[ht] + 1
- end
- return ht
- end
- else
- pack = function(v)
- -- v == number
- if c[v] <= criterium then
- return t[v]
- else
- -- compact hash
- local hv = hh[v]
- if not hv then
- hv = #tt+1
- tt[hv] = t[v]
- hh[v] = hv
- cc[hv] = c[v]
- end
- return hv
- end
- end
- end
- for k, v in pairs(data.glyphs) do
- v.boundingbox = pack(v.boundingbox)
- if v.lookups then
- for k,v in pairs(v.lookups) do
- for kk=1,#v do
- v[kk] = pack(v[kk])
- end
- end
- end
- local a = v.anchors
- if a then
- for k,v in pairs(a) do
- if k == "baselig" then
- for kk, vv in pairs(v) do
- for kkk=1,#vv do
- vv[kkk] = pack(vv[kkk])
- end
- end
- else
- for kk, vv in pairs(v) do
- v[kk] = pack(vv)
- end
- end
- end
- end
+ local force = otf.notdef
+ local luatex = data.luatex
+ local defaultwidth = luatex.defaultwidth or 0
+ local defaultheight = luatex.defaultheight or 0
+ local defaultdepth = luatex.defaultdepth or 0
+ for _, d in next, data.glyphs do
+ local bb, wd = d.boundingbox, d.width
+ if not wd then
+ d.width = defaultwidth
+ elseif wd ~= 0 and d.class == "mark" then
+ d.width = -wd
end
- if data.lookups then
- for k, v in pairs(data.lookups) do
- if v.rules then
- for kk, vv in pairs(v.rules) do
- local l = vv.lookups
- if l then
- vv.lookups = pack(l)
- end
- local c = vv.coverage
- if c then
- c.before = c.before and pack(c.before )
- c.after = c.after and pack(c.after )
- c.current = c.current and pack(c.current)
- end
- end
- end
- end
+ if force and not d.name then
+ d.name = ".notdef"
end
- if data.luatex then
- local li = data.luatex.ignore_flags
- if li then
- for k, v in pairs(li) do
- li[k] = pack(v)
- end
+ if bb then
+ local ht, dp = bb[4], -bb[2]
+ if ht == 0 or ht < 0 then
+ -- no need to set it and no negative heights, nil == 0
+ else
+ d.height = ht
end
- end
- if #t == 0 then
- logs.report("load otf","pack quality: nothing to pack")
- break
- elseif #t >= threshold then
- local one, two, rest = 0, 0, 0
- if pass == 1 then
- for k,v in pairs(c) do
- if v == 1 then
- one = one + 1
- elseif v == 2 then
- two = two + 1
- else
- rest = rest + 1
- end
- end
+ if dp == 0 or dp < 0 then
+ -- no negative depths and no negative depths, nil == 0
else
- for k,v in pairs(cc) do
- if v >20 then
- rest = rest + 1
- elseif v >10 then
- two = two + 1
- else
- one = one + 1
- end
- end
- data.tables = tt
+ d.depth = dp
end
- logs.report("load otf","pack quality: pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", pass, one+two+rest, one, two, rest, criterium)
- else
- logs.report("load otf","pack quality: pass 1, %s packed, aborting pack (threshold: %s)", #t, threshold)
- break
end
end
end
end
-function otf.enhance.unpack(data)
- if data then
- local t = data.tables
- if t then
- for k, v in pairs(data.glyphs) do
- local tv = t[v.boundingbox] if tv then v.boundingbox = tv end
- local l = v.lookups
- if l then
- for k,v in pairs(l) do
- for i=1,#v do
- local tv = t[v[i]] if tv then v[i] = tv end
- end
- end
- end
- local a = v.anchors
- if a then
- for k,v in pairs(a) do
- if k == "baselig" then
- for kk, vv in pairs(v) do
- for kkk=1,#vv do
- local tv = t[vv[kkk]] if tv then vv[kkk] = tv end
- end
- end
- else
- for kk, vv in pairs(v) do
- local tv = t[vv] if tv then v[kk] = tv end
- end
- end
- end
- end
+function otf.show_feature_order(otfdata,filename)
+ local sequences = otfdata.luatex.sequences
+ if sequences and #sequences > 0 then
+ if trace_loading then
+ logs.report("otf check","font %s has %s sequences",filename,#sequences)
+ logs.report("otf check"," ")
+ end
+ for nos=1,#sequences do
+ local sequence = sequences[nos]
+ local typ = sequence.type or "no-type"
+ local name = sequence.name or "no-name"
+ local subtables = sequence.subtables or { "no-subtables" }
+ local features = sequence.features
+ if trace_loading then
+ logs.report("otf check","%3i %-15s %-20s [%s]",nos,name,typ,concat(subtables,","))
end
- if data.lookups then
- for k, v in pairs(data.lookups) do
- local r = v.rules
- if r then
- for kk, vv in pairs(r) do
- local l = vv.lookups
- if l then
- local tv = t[l] if tv then vv.lookups = tv end
- end
- local c = vv.coverage
- if c then
- local cc = c.before if cc then local tv = t[cc] if tv then c.before = tv end end
- cc = c.after if cc then local tv = t[cc] if tv then c.after = tv end end
- cc = c.current if cc then local tv = t[cc] if tv then c.current = tv end end
- end
+ if features then
+ for feature, scripts in next, features do
+ local tt = { }
+ for script, languages in next, scripts do
+ local ttt = { }
+ for language, _ in next, languages do
+ ttt[#ttt+1] = language
end
+ tt[#tt+1] = format("[%s: %s]",script,concat(ttt," "))
end
- end
- end
- if data.luatex then
- local li = data.luatex.ignore_flags
- if li then
- for k, v in pairs(li) do
- local tv = t[v] if tv then li[k] = tv end
+ if trace_loading then
+ logs.report("otf check"," %s: %s",feature,concat(tt," "))
end
end
end
- data.tables = nil
end
+ if trace_loading then
+ logs.report("otf check","\n")
+ end
+ elseif trace_loading then
+ logs.report("otf check","font %s has no sequences",filename)
end
end
-- todo: normalize, design_size => designsize
-function otf.enhance.analyze(data,filename)
- local t = {
---~ filename = file.basename(filename),
- filename = filename,
- version = otf.version,
- creator = "context mkiv",
- unicodes = otf.analyze_unicodes(data),
- gposfeatures = otf.analyze_features(data.gpos),
- gsubfeatures = otf.analyze_features(data.gsub),
- marks = otf.analyze_class(data,'mark'),
- }
- t.subtables, t.name_to_type, t.internals, t.always_valid, t.ignore_flags, t.ctx_always = otf.analyze_subtables(data)
- data.luatex = t
+otf.enhancers["prepare luatex tables"] = function(data,filename)
+ data.luatex = data.luatex or { }
+ local luatex = data.luatex
+ luatex.filename = filename
+ luatex.version = otf.version
+ luatex.creator = "context mkiv"
end
-do
- -- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap
- --
- -- 18964 18964 (leader)
- -- 0 /.notdef
- -- 1..95 0020
- -- 99 3000
-
- local number = lpeg.C(lpeg.R("09","af","AF")^1)
- local space = lpeg.S(" \n\r\t")
- local spaces = space^0
- local period = lpeg.P(".")
- local periods = period * period
- local name = lpeg.P("/") * lpeg.C((1-space)^1)
-
- local unicodes, names = { }, {}
-
- local function do_one(a,b)
- unicodes[tonumber(a)] = tonumber(b,16)
- end
- local function do_range(a,b,c)
- c = tonumber(c,16)
- for i=tonumber(a),tonumber(b) do
- unicodes[i] = c
- c = c + 1
- end
+otf.enhancers["cleanup aat"] = function(data,filename)
+ if otf.cleanup_aat then
end
- local function do_name(a,b)
- names[tonumber(a)] = b
- end
-
- local grammar = lpeg.P { "start",
- start = number * spaces * number * lpeg.V("series"),
- series = (spaces * (lpeg.V("one") + lpeg.V("range") + lpeg.V("named")) )^1,
- one = (number * spaces * number) / do_one,
- range = (number * periods * number * spaces * number) / do_range,
- named = (number * spaces * name) / do_name
- }
+end
- function otf.load_cidmap(filename) -- lpeg
- local data = io.loaddata(filename)
- if data then
- unicodes, names = { }, { }
- grammar:match(data)
- local supplement, registry, ordering = filename:match("^(.-)%-(.-)%-()%.(.-)$")
- return {
- supplement = supplement,
- registry = registry,
- ordering = ordering,
- filename = filename,
- unicodes = unicodes,
- names = names
- }
- else
- return nil
+local function analyze_features(g, features)
+ if g then
+ local t, done = { }, { }
+ for k=1,#g do
+ local f = features or g[k].features
+ if f then
+ for k=1,#f do
+ -- scripts and tag
+ local tag = f[k].tag
+ if not done[tag] then
+ t[#t+1] = tag
+ done[tag] = true
+ end
+ end
+ end
+ end
+ if #t > 0 then
+ return t
end
end
-
+ return nil
end
-otf.cidmaps = { }
-otf.cidmax = 10
+otf.enhancers["analyse features"] = function(data,filename)
+ -- local luatex = data.luatex
+ -- luatex.gposfeatures = analyze_features(data.gpos)
+ -- luatex.gsubfeatures = analyze_features(data.gsub)
+end
-function otf.cidmap(registry,ordering,supplement)
- -- cf Arthur R. we can safely scan upwards since cids are downward compatible
- local template = "%s-%s-%s.cidmap"
- local supplement = tonumber(supplement)
- logs.report("load otf","needed cidmap, registry: %s, ordering: %s, supplement: %s",registry,ordering,supplement)
- local function locate(registry,ordering,supplement)
- local filename = format(template,registry,ordering,supplement)
- local cidmap = otf.cidmaps[filename]
- if not cidmap then
- logs.report("load otf","checking cidmap, registry: %s, ordering: %s, supplement: %s, filename: %s",registry,ordering,supplement,filename)
- local fullname = input.find_file(filename,'cid') or ""
- if fullname ~= "" then
- cidmap = otf.load_cidmap(fullname)
- if cidmap then
- logs.report("load otf","using cidmap file %s",filename)
- otf.cidmaps[filename] = cidmap
- return cidmap
+otf.enhancers["rehash features"] = function(data,filename)
+ local features = { }
+ data.luatex.features = features
+ for k, what in next, otf.glists do
+ local dw = data[what]
+ if dw then
+ local f = { }
+ features[what] = f
+ for i=1,#dw do
+ local d= dw[i]
+ local dfeatures = d.features
+ if dfeatures then
+ for i=1,#dfeatures do
+ local df = dfeatures[i]
+ local tag = strip(lower(df.tag))
+ local ft = f[tag] if not ft then ft = {} f[tag] = ft end
+ local dscripts = df.scripts
+ for script, languages in next, dscripts do
+ script = strip(lower(script))
+ local fts = ft[script] if not fts then fts = {} ft[script] = fts end
+ for i=1,#languages do
+ fts[strip(lower(languages[i]))] = true
+ end
+ end
+ end
end
end
end
- return cidmap
end
- local cidmap = locate(registry,ordering,supplement)
- if not cidmap then
- local cidnum = nil
- -- next highest (alternatively we could start high)
- if supplement < otf.cidmax then
- for supplement=supplement+1,otf.cidmax do
- local c = locate(registry,ordering,supplement)
- if c then
- cidmap, cidnum = c, supplement
- break
- end
+end
+
+otf.enhancers["analyse anchors"] = function(data,filename)
+ local classes = data.anchor_classes
+ local luatex = data.luatex
+ local anchor_to_lookup, lookup_to_anchor = { }, { }
+ luatex.anchor_to_lookup, luatex.lookup_to_anchor = anchor_to_lookup, lookup_to_anchor
+ if classes then
+ for c=1,#classes do
+ local class = classes[c]
+ local anchor = class.name
+ local lookups = class.lookup
+ if type(lookups) ~= "table" then
+ lookups = { lookups }
+ end
+ local a = anchor_to_lookup[anchor]
+ if not a then a = { } anchor_to_lookup[anchor] = a end
+ for l=1,#lookups do
+ local lookup = lookups[l]
+ local l = lookup_to_anchor[lookup]
+ if not l then l = { } lookup_to_anchor[lookup] = l end
+ l[anchor] = true
+ a[lookup] = true
end
end
- -- next lowest (least worse fit)
- if not cidmap and supplement > 0 then
- for supplement=supplement-1,0,-1 do
- local c = locate(registry,ordering,supplement)
- if c then
- cidmap, cidnum = c, supplement
- break
- end
- end
+ end
+end
+
+otf.enhancers["analyse marks"] = function(data,filename)
+ local glyphs = data.glyphs
+ local marks = { }
+ data.luatex.marks = marks
+ for unicode, index in next, data.luatex.indices do
+ local glyph = glyphs[index]
+ if glyph.class == "mark" then
+ marks[unicode] = true
end
- -- prevent further lookups
- if cidmap and cidnum > 0 then
- for s=0,cidnum-1 do
- filename = format(template,registry,ordering,s)
- if not otf.cidmaps[filename] then
- otf.cidmaps[filename] = cidmap -- copy of ref
+ end
+end
+
+local other = lpeg.C((1 - lpeg.S("_."))^0)
+local ligsplitter = lpeg.Ct(other * (lpeg.P("_") * other)^0)
+
+--~ print(splitter:match("this"))
+--~ print(splitter:match("this.that"))
+--~ print(splitter:match("such_so_more"))
+--~ print(splitter:match("such_so_more.that"))
+
+otf.enhancers["analyse unicodes"] = function(data,filename)
+ local unicodes = data.luatex.unicodes
+ -- we need to move this code
+ unicodes['space'] = unicodes['space'] or 32 -- handly later on
+ unicodes['hyphen'] = unicodes['hyphen'] or 45 -- handly later on
+ unicodes['zwj'] = unicodes['zwj'] or zwj -- handly later on
+ unicodes['zwnj'] = unicodes['zwnj'] or zwnj -- handly later on
+ -- the tounicode mapping is sparse and only needed for alternatives
+ local tounicode, originals, ns, nl, private, unknown = { }, { }, 0, 0, fonts.private, format("%04X",utfbyte("?"))
+ data.luatex.tounicode, data.luatex.originals = tounicode, originals
+ for index, glyph in next, data.glyphs do
+ local name, unic = glyph.name, glyph.unicode or -1 -- play safe
+ if unic == -1 or unic >= private or (unic >= 0xE000 and unic <= 0xF8FF) or unic == 0xFFFE or unic == 0xFFFF then
+ -- a.whatever or a_b_c.whatever or a_b_c
+ local split = ligsplitter:match(name)
+ if #split == 0 then
+ -- skip
+ elseif #split == 1 then
+ local u = unicodes[split[1]]
+ if u then
+ if type(u) == "table" then
+ u = u[1]
+ end
+ if u < 0x10000 then
+ originals[index], tounicode[index] = u, format("%04X",u)
+ else
+ originals[index], tounicode[index] = u, format("%04X%04X",u/1024+0xD800,u%1024+0xDC00)
+ end
+ ns = ns + 1
+ else
+ originals[index], tounicode[index] = 0xFFFD, "FFFD"
+ end
+ else
+ local as = { }
+ for l=1,#split do
+ local u = unicodes[split[l]]
+ if not u then
+ as[l], split[l] = 0xFFFD, "FFFD"
+ else
+ if type(u) == "table" then
+ u = u[1]
+ end
+ if u < 0x10000 then
+ as[l], split[l] = u, format("%04X",u)
+ else
+ as[l], split[l] = u, format("%04X%04X",u/1024+0xD800,u%1024+0xDC00)
+ end
+ end
+ end
+ split = concat(split)
+ if split ~= "" then
+ originals[index], tounicode[index] = as, split
+ nl = nl + 1
+ else
+ originals[index], tounicode[index] = 0xFFFD, "FFFD"
end
end
end
end
- return cidmap
+ if trace_loading and (ns > 0 or nl > 0) then
+ logs.report("load otf","enhance: %s tounicode entries added (%s ligatures)",nl+ns, ns)
+ end
end
---~ ["cidinfo"]={
---~ ["ordering"]="Japan1",
---~ ["registry"]="Adobe",
---~ ["supplement"]=6,
---~ ["version"]=6,
---~ },
+otf.enhancers["analyse subtables"] = function(data,filename)
+ data.luatex = data.luatex or { }
+ local luatex = data.luatex
+ local sequences = { }
+ local lookups = { }
+ luatex.sequences = sequences
+ luatex.lookups = lookups
+ for _, g in next, { data.gsub, data.gpos } do
+ for k=1,#g do
+ local gk = g[k]
-function otf.enhance.before(data,filename)
- local private = fonts.private
+local typ = gk.type
+if typ == "gsub_contextchain" or typ == "gpos_contextchain" then
+ gk.chain = 1
+elseif typ == "gsub_reversecontextchain" or typ == "gpos_reversecontextchain" then
+ gk.chain = -1
+else
+ gk.chain = 0
+end
+
+ local features = gk.features
+ if features then
+ sequences[#sequences+1] = gk
+ -- scripts, tag, ismac
+ local t = { }
+ for f=1,#features do
+ local feature = features[f]
+ local hash = { }
+ -- only script and langs matter
+ for s, languages in next, feature.scripts do
+ s = lower(s)
+ local h = hash[s]
+ if not h then h = { } hash[s] = h end
+ for l=1,#languages do
+ h[strip(lower(languages[l]))] = true
+ end
+ end
+ t[feature.tag] = hash
+ end
+ gk.features = t
+ else
+ lookups[gk.name] = gk
+ gk.name = nil
+ end
+ local subtables = gk.subtables
+ if subtables then
+ local t = { }
+ for s=1,#subtables do
+ local subtable = subtables[s]
+ local name = subtable.name
+ t[#t+1] = name
+ end
+ gk.subtables = t
+ end
+ local flags = gk.flags
+ if flags then
+ gk.flags = { -- forcing false packs nicer
+ (flags.ignorecombiningmarks and "mark") or false,
+ (flags.ignoreligatures and "ligature") or false,
+ (flags.ignorebaseglyphs and "base") or false,
+ flags.r2l or false
+ }
+ end
+ end
+ end
+end
+
+otf.enhancers["merge cid fonts"] = function(data,filename)
+ -- we can also move the names to data.luatex.names which might
+ -- save us some more memory (at the cost of harder tracing)
if data.subfonts and table.is_empty(data.glyphs) then
local cidinfo = data.cidinfo
local verbose = fonts.verbose
if cidinfo.registry then
- local cidmap = otf.cidmap(cidinfo.registry,cidinfo.ordering,cidinfo.supplement)
+ local cidmap = fonts.cid.getmap and fonts.cid.getmap(cidinfo.registry,cidinfo.ordering,cidinfo.supplement)
if cidmap then
local glyphs, uni_to_int, int_to_uni, nofnames, nofunicodes = { }, { }, { }, 0, 0
local unicodes, names = cidmap.unicodes, cidmap.names
- for n, subfont in pairs(data.subfonts) do
- for index, g in pairs(subfont.glyphs) do
+ for n, subfont in next, data.subfonts do
+ for index, g in next, subfont.glyphs do
if not next(g) then
-- dummy entry
else
@@ -1288,90 +624,143 @@ function otf.enhance.before(data,filename)
g.boundingbox = g.boundingbox -- or zerobox
g.name = g.name or name or "unknown"
if unicode then
--- g.unicode = unicode
uni_to_int[unicode] = index
int_to_uni[index] = unicode
nofunicodes = nofunicodes + 1
+ g.unicode = unicode
elseif name then
--- g.unicode = -1
nofnames = nofnames + 1
+ g.unicode = -1
end
glyphs[index] = g
end
end
subfont.glyphs = nil
end
- logs.report("load otf","cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes, nofnames, nofunicodes+nofnames)
+ if trace_loading then
+ logs.report("load otf","cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes, nofnames, nofunicodes+nofnames)
+ end
data.glyphs = glyphs
data.map = data.map or { }
data.map.map = uni_to_int
data.map.backmap = int_to_uni
- else
+ elseif trace_loading then
logs.report("load otf","unable to remap cid font, missing cid file for %s",filename)
end
- else
+ elseif trace_loading then
logs.report("load otf","font %s has no glyphs",filename)
end
end
- if data.map then
- local uni_to_int = data.map.map -- [unic] = slot
- local int_to_uni = data.map.backmap -- { [0|1] = unic, ... }
- for index, glyph in pairs(data.glyphs) do
- if glyph.name then
--- local unic = glyph.unicode or glyph.unicodeenc or -1
-local unic = int_to_uni[index] or -1
- if index > 0 and (unic == -1 or unic >= 0x110000) then
- while uni_to_int[private] do
- private = private + 1
- end
- uni_to_int[private] = index
- int_to_uni[index] = private
--- glyph.unicode = private
- if fonts.trace then
- logs.report("load otf","enhance: glyph %s at index %s is moved to private unicode slot %s",glyph.name,index,private)
- end
+end
+
+otf.enhancers["prepare unicode"] = function(data,filename)
+ local luatex = data.luatex
+ if not luatex then luatex = { } data.luatex = luatex end
+ local indices, unicodes, multiples, internals = { }, { }, { }, { }
+ local glyphs = data.glyphs
+ local mapmap = data.map
+ if not mapmap then
+ logs.report("load otf","no map in %s",filename)
+ mapmap = { }
+ data.map = { map = mapmap }
+ elseif not mapmap.map then
+ logs.report("load otf","no unicode map in %s",filename)
+ mapmap = { }
+ data.map.map = mapmap
+ else
+ mapmap = mapmap.map
+ end
+ local criterium = fonts.private
+ local private = fonts.private
+ for index, glyph in next, glyphs do
+ if index > 0 then
+ local name = glyph.name
+ if name then
+ local unicode = glyph.unicode
+ if unicode == -1 or unicode >= criterium then
+ glyph.unicode = private
+ indices[private] = index
+ unicodes[name] = private
+ internals[index] = true
+ if trace_private then
+ logs.report("load otf","enhance: glyph %s at index U+%04X is moved to private unicode slot U+%04X",name,index,private)
+ end
+ private = private + 1
else
- glyph.unicode = unic -- safeguard for older version
+ indices[unicode] = index
+ unicodes[name] = unicode
end
end
end
- local n = 0
- for k,v in pairs(int_to_uni) do
- if v == -1 or v >= 0x110000 then
- int_to_uni[k], n = nil, n+1
- end
- end
- if fonts.trace then
- logs.report("load otf","enhance: %s entries removed from map.backmap",n)
- end
- local n = 0
- for k,v in pairs(uni_to_int) do
- if k == -1 or k >= 0x110000 then
- uni_to_int[k], n = nil, n+1
+ end
+ -- beware: the indeces table is used to initialize the tfm table
+ for unicode, index in next, mapmap do
+ if not internals[index] then
+ local name = glyphs[index].name
+ if name then
+ local un = unicodes[name]
+ if not un then
+ unicodes[name] = unicode -- or 0
+ elseif type(un) == "number" then
+ if un ~= unicode then
+ multiples[#multiples+1] = name
+ unicodes[name] = { un, unicode }
+ indices[unicode] = index
+ end
+ else
+ local ok = false
+ for u=1,#un do
+ if un[u] == unicode then
+ ok = true
+ break
+ end
+ end
+ if not ok then
+ multiples[#multiples+1] = name
+ un[#un+1] = unicode
+ indices[unicode] = index
+ end
+ end
end
end
- if fonts.trace then
- logs.report("load otf","enhance: %s entries removed from map.mapmap",n)
+ end
+ if trace_loading then
+ if #multiples > 0 then
+ logs.report("load otf","%s glyph are reused: %s",#multiples, concat(multiples," "))
+ else
+ logs.report("load otf","no glyph are reused")
end
- else
- data.map = { map = {}, backmap = {} }
end
- if data.ttf_tables then
- for _, v in ipairs(data.ttf_tables) do
- if v.data then v.data = "deleted" end
+ luatex.indices = indices
+ luatex.unicodes = unicodes
+ luatex.private = private
+end
+
+otf.enhancers["cleanup ttf tables"] = function(data,filename)
+ local ttf_tables = data.ttf_tables
+ if ttf_tables then
+ for k=1,#ttf_tables do
+ if ttf_tables[k].data then ttf_tables[k].data = "deleted" end
end
end
- table.compact(data.glyphs)
+ data.ttf_tab_saved = nil
+end
+
+otf.enhancers["compact glyphs"] = function(data,filename)
+ table.compact(data.glyphs) -- needed?
if data.subfonts then
- for _, subfont in pairs(data.subfonts) do
- table.compact(subfont.glyphs)
+ for _, subfont in next, data.subfonts do
+ table.compact(subfont.glyphs) -- needed?
end
end
+end
+
+otf.enhancers["reverse coverage"] = function(data,filename)
-- we prefer the before lookups in a normal order
if data.lookups then
- for _, v in pairs(data.lookups) do
+ for _, v in next, data.lookups do
if v.rules then
- for _, vv in pairs(v.rules) do
+ for _, vv in next, v.rules do
local c = vv.coverage
if c and c.before then
c.before = table.reverse(c.before)
@@ -1382,24 +771,148 @@ local unic = int_to_uni[index] or -1
end
end
-function otf.enhance.after(data,filename) -- to be split
- if otf.enhance.add_kerns then
- local glyphs, mapmap, unicodes = data.glyphs, data.map.map, data.luatex.unicodes
- local mkdone = false
- for index, glyph in pairs(data.glyphs) do
- if glyph.kerns then
- local mykerns = { } -- unicode indexed !
- for k,v in pairs(glyph.kerns) do
- local vc, vo, vl = v.char, v.off, v.lookup
- if vc and vo and vl then -- brrr, wrong! we miss the non unicode ones
- local uvc = unicodes[vc]
- if not uvc then
+otf.enhancers["check italic correction"] = function(data,filename)
+ local glyphs = data.glyphs
+ local ok = false
+ for index, glyph in next, glyphs do
+ local ic = glyph.italic_correction
+ if ic then
+ if ic ~= 0 then
+ glyph.italic = ic
+ end
+ glyph.italic_correction = nil
+ ok = true
+ end
+ end
+ -- we can use this to avoid calculations
+ otf.tables.valid_fields[#otf.tables.valid_fields+1] = "has_italic"
+ data.has_italic = true
+end
+
+otf.enhancers["check math"] = function(data,filename)
+ if data.math then
+ -- we move the math stuff into a math subtable because we then can
+ -- test faster in the tfm copy
+ local glyphs = data.glyphs
+ local unicodes = data.luatex.unicodes
+ for index, glyph in next, glyphs do
+ local mk = glyph.mathkern
+ local hv = glyph.horiz_variants
+ local vv = glyph.vert_variants
+ if mk or hv or vv then
+ local math = { }
+ glyph.math = math
+ if mk then
+ for k, v in next, mk do
+ if not next(v) then
+ mk[k] = nil
+ end
+ end
+ math.kerns = mk
+ glyph.mathkern = nil
+ end
+ if hv then
+ math.horiz_variants = hv.variants
+ local p = hv.parts
+ if p then
+ if #p>0 then
+ for i=1,#p do
+ local pi = p[i]
+ pi.glyph = unicodes[pi.component] or 0
+ end
+ math.horiz_parts = p
+ end
+ end
+ local ic = hv.italic_correction
+ if ic and ic ~= 0 then
+ math.horiz_italic_correction = ic
+ end
+ glyph.horiz_variants = nil
+ end
+ if vv then
+ local uc = unicodes[index]
+ math.vert_variants = vv.variants
+ local p = vv.parts
+ if p then
+ if #p>0 then
+ for i=1,#p do
+ local pi = p[i]
+ pi.glyph = unicodes[pi.component] or 0
+ end
+ math.vert_parts = p
+ end
+ end
+ local ic = vv.italic_correction
+ if ic and ic ~= 0 then
+ math.vert_italic_correction = ic
+ end
+ glyph.vert_variants = nil
+ end
+ local ic = glyph.italic_correction
+ if ic then
+ if ic ~= 0 then
+ math.italic_correction = ic
+ end
+ glyph.italic_correction = nil
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["share widths"] = function(data,filename)
+ local glyphs = data.glyphs
+ local widths = { }
+ for index, glyph in next, glyphs do
+ local width = glyph.width
+ widths[width] = (widths[width] or 0) + 1
+ end
+ -- share width for cjk fonts
+ local wd, most = 0, 1
+ for k,v in next, widths do
+ if v > most then
+ wd, most = k, v
+ end
+ end
+ if most > 1000 then
+ if trace_loading then
+ logs.report("load otf", "most common width: %s (%s times), sharing (cjk font)",wd,most)
+ end
+ for k, v in next, glyphs do
+ if v.width == wd then
+ v.width = nil
+ end
+ end
+ data.luatex.defaultwidth = wd
+ end
+end
+
+-- kern: ttf has a table with kerns
+
+otf.enhancers["reorganize kerns"] = function(data,filename)
+ local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes
+ local mkdone = false
+ for index, glyph in next, data.glyphs do
+ if glyph.kerns then
+ local mykerns = { }
+ for k,v in next, glyph.kerns do
+ local vc, vo, vl = v.char, v.off, v.lookup
+ if vc and vo and vl then -- brrr, wrong! we miss the non unicode ones
+ local uvc = unicodes[vc]
+ if not uvc then
+ if trace_loading then
logs.report("load otf","problems with unicode %s of kern %s at glyph %s",vc,k,index)
- else
- local mkl = mykerns[vl]
+ end
+ else
+ if type(vl) ~= "table" then
+ vl = { vl }
+ end
+ for l=1,#vl do
+ local vll = vl[l]
+ local mkl = mykerns[vll]
if not mkl then
mkl = { }
- mykerns[v.lookup] = mkl
+ mykerns[vll] = mkl
end
if type(uvc) == "table" then
for u=1,#uvc do
@@ -1411,62 +924,86 @@ function otf.enhance.after(data,filename) -- to be split
end
end
end
- glyph.mykerns = mykerns
- glyph.kerns = nil -- saves space and time
- mkdone = true
end
+ glyph.mykerns = mykerns
+ glyph.kerns = nil -- saves space and time
+ mkdone = true
end
- if mkdone then
- logs.report("load otf", "replacing 'kerns' tables by 'mykerns' tables")
+ end
+ if trace_loading and mkdone then
+ logs.report("load otf", "replacing 'kerns' tables by 'mykerns' tables")
+ end
+ if data.kerns then
+ if trace_loading then
+ logs.report("load otf", "removing global 'kern' table")
end
- if data.gpos then
- for _, gpos in ipairs(data.gpos) do
- if gpos.subtables then
- for _, subtable in ipairs(gpos.subtables) do
- local kernclass = subtable.kernclass
- if kernclass then
- for _, kcl in ipairs(kernclass) do
- local firsts, seconds, offsets, lookup = kcl.firsts, kcl.seconds, kcl.offsets, kcl.lookup
+ data.kerns = nil
+ end
+ local dgpos = data.gpos
+ if dgpos then
+ for gp=1,#dgpos do
+ local gpos = dgpos[gp]
+ local subtables = gpos.subtables
+ if subtables then
+ for s=1,#subtables do
+ local subtable = subtables[s]
+ local kernclass = subtable.kernclass -- name is inconsistent with anchor_classes
+ if kernclass then
+ for k=1,#kernclass do
+ local kcl = kernclass[k]
+ local firsts, seconds, offsets, lookups = kcl.firsts, kcl.seconds, kcl.offsets, kcl.lookup -- singular
+ if type(lookups) ~= "table" then
+ lookups = { lookups }
+ end
+ for l=1,#lookups do
+ local lookup = lookups[l]
local maxfirsts, maxseconds = getn(firsts), getn(seconds)
- logs.report("load otf", "adding kernclass %s with %s times %s pairs)",lookup, maxfirsts, maxseconds)
- for fk, fv in pairs(firsts) do
- for first in fv:gmatch("[^ ]+") do
+ if trace_loading then
+ logs.report("load otf", "adding kernclass %s with %s times %s pairs",lookup, maxfirsts, maxseconds)
+ end
+ for fk, fv in next, firsts do
+ for first in gmatch(fv,"[^ ]+") do
local first_unicode = unicodes[first]
if type(first_unicode) == "number" then
first_unicode = { first_unicode }
end
for f=1,#first_unicode do
local glyph = glyphs[mapmap[first_unicode[f]]]
- local mykerns = glyph.mykerns
- if not mykerns then
- mykerns = { } -- unicode indexed !
- glyph.mykerns = mykerns
- end
- local lookupkerns = mykerns[lookup]
- if not lookupkerns then
- lookupkerns = { }
- mykerns[lookup] = lookupkerns
- end
- for sk, sv in pairs(seconds) do
- local offset = offsets[(fk-1) * maxseconds + sk]
- for second in sv:gmatch("[^ ]+") do
- local second_unicode = unicodes[second]
- if type(second_unicode) == "number" then
- lookupkerns[second_unicode] = offset
- else
- for s=1,#second_unicode do
- lookupkerns[second_unicode[s]] = offset
+ if glyph then
+ local mykerns = glyph.mykerns
+ if not mykerns then
+ mykerns = { } -- unicode indexed !
+ glyph.mykerns = mykerns
+ end
+ local lookupkerns = mykerns[lookup]
+ if not lookupkerns then
+ lookupkerns = { }
+ mykerns[lookup] = lookupkerns
+ end
+ for sk, sv in next, seconds do
+ local offset = offsets[(fk-1) * maxseconds + sk]
+ --~ local offset = offsets[sk] -- (fk-1) * maxseconds + sk]
+ for second in gmatch(sv,"[^ ]+") do
+ local second_unicode = unicodes[second]
+ if type(second_unicode) == "number" then
+ lookupkerns[second_unicode] = offset
+ else
+ for s=1,#second_unicode do
+ lookupkerns[second_unicode[s]] = offset
+ end
end
end
end
+ elseif trace_loading then
+ logs.report("load otf", "no glyph data for U+%04X", first_unicode[f])
end
end
end
end
end
- subtable.comment = "The kernclass table is merged into mykerns in the indexed glyph tables."
- subtable.kernclass = { }
end
+ subtable.comment = "The kernclass table is merged into mykerns in the indexed glyph tables."
+ subtable.kernclass = { }
end
end
end
@@ -1474,21 +1011,28 @@ function otf.enhance.after(data,filename) -- to be split
end
end
-function otf.enhance.strip(data)
+otf.enhancers["strip not needed data"] = function(data,filename)
local verbose = fonts.verbose
- local int_to_uni = data.map.backmap
- for k, v in pairs(data.glyphs) do
+ local int_to_uni = data.luatex.unicodes
+ for k, v in next, data.glyphs do
local d = v.dependents
if d then v.dependents = nil end
+ local a = v.altuni
+ if a then v.altuni = nil end
if verbose then
local code = int_to_uni[k]
+ -- looks like this is done twice ... bug?
if code then
local vu = v.unicode
if not vu then
v.unicode = code
elseif type(vu) == "table" then
- vu[#bu+1] = code
- else
+ if vu[#vu] == code then
+ -- weird
+ else
+ vu[#vu+1] = code
+ end
+ elseif vu ~= code then
v.unicode = { vu, code }
end
end
@@ -1498,19 +1042,39 @@ function otf.enhance.strip(data)
end
end
data.luatex.comment = "Glyph tables have their original index. When present, mykern tables are indexed by unicode."
- data.luatex.indices = data.map.map -- needed for shared glyphs
data.map = nil
- data.names = nil
+ data.names = nil -- funny names for editors
data.glyphcnt = nil
data.glyphmax = nil
+ if true then
+ data.gpos = nil
+ data.gsub = nil
+ data.anchor_classes = nil
+ end
end
-function otf.enhance.flatten(data,filename) -- to be split
- logs.report("load otf", "flattening 'specifications' tables")
- for k, v in pairs(data.glyphs) do
+otf.enhancers["migrate metadata"] = function(data,filename)
+ local global_fields = otf.tables.global_fields
+ local metadata = { }
+ for k,v in next, data do
+ if not global_fields[k] then
+ metadata[k] = v
+ data[k] = nil
+ end
+ end
+ data.metadata = metadata
+ -- goodies
+ local pfminfo = data.pfminfo
+ metadata.isfixedpitch = metadata.isfixedpitch or (pfminfo.panose and pfminfo.panose["proportion"] == "Monospaced")
+ metadata.charwidth = pfminfo and pfminfo.avgwidth
+end
+
+otf.enhancers["flatten glyph lookups"] = function(data,filename)
+ for k, v in next, data.glyphs do
if v.lookups then
- for kk, vv in pairs(v.lookups) do
- for kkk, vvv in ipairs(vv) do
+ for kk, vv in next, v.lookups do
+ for kkk=1,#vv do
+ local vvv = vv[kkk]
local s = vvv.specification
if s then
local t = vvv.type
@@ -1523,27 +1087,29 @@ function otf.enhance.flatten(data,filename) -- to be split
elseif t == "multiple" then
vv[kkk] = { "multiple", s.components }
elseif t == "position" then
- vv[kkk] = { "position", s.x or 0, s.y or 0, s.h or 0, s.v or 0 }
+ vv[kkk] = { "position", { s.x or 0, s.y or 0, s.h or 0, s.v or 0 } }
elseif t == "pair" then
local one, two, paired = s.offsets[1], s.offsets[2], s.paired or ""
if one then
if two then
- vv[kkk] = { "pair", paired, one.x or 0, one.y or 0, one.h or 0, one.v or 0, two.x or 0, two.y or 0, two.h or 0, two.v or 0 }
+ vv[kkk] = { "pair", paired, { one.x or 0, one.y or 0, one.h or 0, one.v or 0 }, { two.x or 0, two.y or 0, two.h or 0, two.v or 0 } }
else
- vv[kkk] = { "pair", paired, one.x or 0, one.y or 0, one.h or 0 }
+ vv[kkk] = { "pair", paired, { one.x or 0, one.y or 0, one.h or 0, one.v or 0 } }
end
else
if two then
- vv[kkk] = { "pair", paired, 0, 0, 0, 0, two.x or 0, two.y or 0, two.h or 0, two.v or 0 }
+ vv[kkk] = { "pair", paired, { }, { two.x or 0, two.y or 0, two.h or 0, two.v or 0} } -- maybe nil instead of { }
else
vv[kkk] = { "pair", paired }
end
end
else
- logs.report("load otf", "flattening needed, warn Hans and/or Taco")
- for a, b in pairs(s) do
- if vvv[a] then
- logs.report("load otf", "flattening conflict, warn Hans and/or Taco")
+ if trace_loading then
+ logs.report("load otf", "flattening needed, report to context list")
+ end
+ for a, b in next, s do
+ if trace_loading and vvv[a] then
+ logs.report("load otf", "flattening conflict, report to context list")
end
vvv[a] = b
end
@@ -1554,15 +1120,18 @@ function otf.enhance.flatten(data,filename) -- to be split
end
end
end
- logs.report("load otf", "flattening 'anchor' tables")
- for k, v in pairs(data.glyphs) do
+end
+
+otf.enhancers["flatten anchor tables"] = function(data,filename)
+ for k, v in next, data.glyphs do
if v.anchors then
- for kk, vv in pairs(v.anchors) do
- for kkk, vvv in pairs(vv) do
- if vvv.x or vvv.y then -- kkk == "centry"
+ for kk, vv in next, v.anchors do
+ for kkk, vvv in next, vv do
+ if vvv.x or vvv.y then
vv[kkk] = { vvv.x or 0, vvv.y or 0 }
else
- for kkkk, vvvv in ipairs(vvv) do
+ for kkkk=1,#vvv do
+ local vvvv = vvv[kkkk]
vvv[kkkk] = { vvvv.x or 0, vvvv.y or 0 }
end
end
@@ -1570,14 +1139,24 @@ function otf.enhance.flatten(data,filename) -- to be split
end
end
end
- for _, tag in pairs({"gpos","gsub"}) do
+end
+
+otf.enhancers["flatten feature tables"] = function(data,filename)
+ -- is this needed? do we still use them at all?
+ for _, tag in next, otf.glists do
if data[tag] then
- logs.report("load otf", "flattening '%s' tables", tag)
- for k, v in pairs(data[tag]) do
- if v.features then
- for kk, vv in ipairs(v.features) do
+ if trace_loading then
+ logs.report("load otf", "flattening %s table", tag)
+ end
+ for k, v in next, data[tag] do
+ local features = v.features
+ if features then
+ for kk=1,#features do
+ local vv = features[kk]
local t = { }
- for kkk, vvv in ipairs(vv.scripts) do
+ local scripts = vv.scripts
+ for kkk=1,#scripts do
+ local vvv = scripts[kkk]
t[vvv.script] = vvv.langs
end
vv.scripts = t
@@ -1588,12 +1167,12 @@ function otf.enhance.flatten(data,filename) -- to be split
end
end
-otf.enhance.patches = { }
+otf.enhancers.patches = otf.enhancers.patches or { }
-function otf.enhance.patch(data,filename)
- local basename = file.basename(filename:lower())
- for pattern, action in pairs(otf.enhance.patches) do
- if basename:find(pattern) then
+otf.enhancers["patch bugs"] = function(data,filename)
+ local basename = file.basename(lower(filename))
+ for pattern, action in next, otf.enhancers.patches do
+ if find(basename,pattern) then
action(data,filename)
end
end
@@ -1601,160 +1180,8 @@ end
-- tex features
-function otf.enhance.enrich(data,filename)
- -- later
-end
-
-function otf.analyze_class(data,class)
- local classes = { }
- local glyphs = data.glyphs
- for unicode, index in pairs(data.map.map) do
- local glyph = glyphs[index]
- if glyph.class == class then
- classes[unicode] = true
- end
- end
- return classes
-end
-
-function otf.analyze_subtables(data)
- local subtables, name_to_type, internals, always_valid, ignore_flags, ctx_always = { }, { }, { }, { }, { }, { }
- local function collect(g)
- if g then
- for k,v in ipairs(g) do
- if v.features then
- local ignored = { false, false, false }
- local flags = v.flags
- if flags.ignorecombiningmarks then ignored[1] = 'mark' end
- if flags.ignorebasechars then ignored[2] = 'base' end
- if flags.ignoreligatures then ignored[3] = 'ligature' end
- if v.subtables then
- local type = v.type
- for _, feature in ipairs(v.features) do
- local ft = feature.tag:lower()
- subtables[ft] = subtables[ft] or { }
- ctx_always[ft] = v.always
- for script, languages in pairs(feature.scripts) do
- script = script:lower()
- script = script:strip()
- sft = subtables[ft]
- local sfts = sft[script]
- if not sfts then
- sfts = { }
- sft[script] = sfts
- end
- for _, language in ipairs(languages) do
- language = language:lower()
- language = language:strip()
- local sftsl = sfts[language]
- if not sftsl then
- sftsl = sfts[language] or { }
- sfts[language] = sftsl
- end
- local lookups, valid = sftsl.lookups or { }, sftsl.valid or { }
- for n, subtable in ipairs(v.subtables) do
- local stl = subtable.name
- if stl then
- lookups[#lookups+1] = stl
- valid[stl] = true
- name_to_type[stl] = type
- ignore_flags[stl] = ignored
- end
- end
- sftsl.lookups, sftsl.valid = lookups, valid
- end
- end
- end
- end
- else
- -- we have an internal feature, say ss_l_83 that resolves to
- -- subfeatures like ss_l_83_s which we find in the glyphs
- name_to_type[v.name] = v.type
- local lookups, valid = { }, { }
- for n, subtable in ipairs(v.subtables) do
- local stl = subtable.name
- if stl then
- lookups[#lookups+1] = stl
- valid[stl] = true
- always_valid[stl] = true
- end
- end
- internals[v.name] = {
- lookups = lookups,
- valid = valid
- }
- always_valid[v.name] = true -- bonus
- end
- end
- end
- end
- collect(data.gsub)
- collect(data.gpos)
- return subtables, name_to_type, internals, always_valid, ignore_flags, ctx_always
-end
-
-function otf.analyze_unicodes(data)
- local unicodes = { }
- local indices = data.map.map
- local glyphs = data.glyphs
- local multiples = { }
- for unicode, index in pairs(indices) do
- local name = glyphs[index].name
- if name then
- local un = unicodes[name]
- if not un then
- unicodes[name] = unicode -- or 0
- elseif type(un) == "number" then
- multiples[#multiples+1] = name
- unicodes[name] = { un, unicode }
- else
- un[#un+1] = unicode
- end
- end
- end
- if #multiples > 0 then
- logs.report("load otf","%s glyph are reused: %s",#multiples, concat(multiples," "))
- end
- unicodes['space'] = unicodes['space'] or 32 -- handly later on
- unicodes['hyphen'] = unicodes['hyphen'] or 45 -- handly later on
- return unicodes
-end
-
-function otf.analyze_features(g, features)
- if g then
- local t, done = { }, { }
- for k=1,#g do
- local f = features or g[k].features
- if f then
- for k=1,#f do
- -- scripts and tag
- local tag = f[k].tag
- if not done[tag] then
- t[#t+1] = tag
- done[tag] = true
- end
- end
- end
- end
- if #t > 0 then
- return t
- end
- end
- return nil
-end
-
-function otf.valid_subtable(otfdata,kind,script,language)
- local tk = otfdata.luatex.subtables[kind]
- if tk then
- local tks = tk[script] or tk.dflt
- if tks then
- local tksl = tks[language] or tks.dflt
- if tksl then
- return tksl.lookups
- end
- end
- end
- return false
+fonts.otf.enhancers["enrich with features"] = function(data,filename)
+ -- later, ctx only
end
function otf.features.register(name,default)
@@ -1762,75 +1189,70 @@ function otf.features.register(name,default)
otf.features.default[name] = default
end
-function otf.set_features(tfmdata) -- node and base, simple mapping
- local shared = tfmdata.shared
- local otfdata = shared.otfdata
- shared.features = fonts.define.check(shared.features,otf.features.default)
- local features = shared.features
- local trace = otf.trace_features or otf.trace_set_features
- if not tfmdata.language then tfmdata.language = 'dflt' end
- if not tfmdata.script then tfmdata.script = 'dflt' end
+function otf.set_features(tfmdata,features)
+ local processes = { }
if not table.is_empty(features) then
- local gposlist = otfdata.luatex.gposfeatures
- local gsublist = otfdata.luatex.gsubfeatures
- local mode = tfmdata.mode or fonts.mode
+ local lists = {
+ fonts.triggers,
+ fonts.processors,
+ fonts.manipulators,
+ }
+ local mode = tfmdata.mode or fonts.mode -- or features.mode
local initializers = fonts.initializers
local fi = initializers[mode]
- if fi then -- todo: delay initilization for mode 'node'
+ if fi then
local fiotf = fi.otf
if fiotf then
local done = { }
- local function initialize(list) -- using tex lig and kerning
+ for l=1,4 do
+ local list = lists[l]
if list then
for i=1,#list do
local f = list[i]
local value = features[f]
if value and fiotf[f] then -- brr
if not done[f] then -- so, we can move some to triggers
- if trace then
+ if trace_features then
logs.report("define otf","initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown', tfmdata.fullname or 'unknown')
end
fiotf[f](tfmdata,value) -- can set mode (no need to pass otf)
mode = tfmdata.mode or fonts.mode -- keep this, mode can be set local !
- local fi = initializers[mode]
- fiotf = fi.otf
+ local im = initializers[mode]
+ if im then
+ fiotf = initializers[mode].otf
+ end
done[f] = true
end
end
end
end
end
- initialize(fonts.triggers)
- initialize(gsublist)
- initialize(gposlist)
- initialize(fonts.manipulators)
end
end
local fm = fonts.methods[mode]
if fm then
local fmotf = fm.otf
- local sp = shared.processors
if fmotf then
- local function register(list) -- node manipulations
+ for l=1,4 do
+ local list = lists[l]
if list then
for i=1,#list do
local f = list[i]
- if features[f] and fmotf[f] then -- brr
- if trace then
+ if fmotf[f] then -- brr
+ if trace_features then
logs.report("define otf","installing feature handler %s for mode %s for font %s",f,mode or 'unknown', tfmdata.fullname or 'unknown')
end
- sp[#sp+1] = fmotf[f]
+ processes[#processes+1] = fmotf[f]
end
end
end
end
- register(fonts.triggers)
- register(gsublist)
- register(gposlist)
- register(fonts.manipulators)
end
+ else
+ -- message
end
end
+ return processes, features
end
function otf.otf_to_tfm(specification)
@@ -1841,38 +1263,37 @@ function otf.otf_to_tfm(specification)
local features = specification.features.normal
local cache_id = specification.hash
local tfmdata = containers.read(tfm.cache(),cache_id)
+--~ print(cache_id)
if not tfmdata then
local otfdata = otf.load(filename,format,sub,features and features.featurefile)
if not table.is_empty(otfdata) then
- otf.add_dimensions(otfdata)
- if true then
- otfdata._shared_ = otfdata._shared_ or { -- aggressive sharing
- processes = { },
- lookuptable = { },
- featuredata = { },
- featurecache = { },
- }
- end
- tfmdata = otf.copy_to_tfm(otfdata)
+ otfdata.shared = otfdata.shared or {
+ featuredata = { },
+ anchorhash = { },
+ initialized = false,
+ }
+ tfmdata = otf.copy_to_tfm(otfdata,cache_id)
if not table.is_empty(tfmdata) then
tfmdata.unique = tfmdata.unique or { }
tfmdata.shared = tfmdata.shared or { } -- combine
local shared = tfmdata.shared
shared.otfdata = otfdata
- shared.features = features
- shared.processors = { }
+ shared.features = features -- default
shared.dynamics = { }
shared.processes = { }
- shared.lookuptable = { }
- shared.featuredata = { }
- shared.featurecache = { }
- if otfdata._shared_ then
- shared.processes = otfdata._shared_.processes
- shared.lookuptable = otfdata._shared_.lookuptable
- shared.featuredata = otfdata._shared_.featuredata
- shared.featurecache = otfdata._shared_.featurecache
- end
- otf.set_features(tfmdata)
+ shared.set_dynamics = otf.set_dynamics -- fast access and makes other modules independent
+ -- this will be done later anyway, but it's convenient to have
+ -- them already for fast access
+ tfmdata.luatex = otfdata.luatex
+ tfmdata.indices = otfdata.luatex.indices
+ tfmdata.unicodes = otfdata.luatex.unicodes
+ tfmdata.marks = otfdata.luatex.marks
+ tfmdata.originals = otfdata.luatex.originals
+ tfmdata.changed = { }
+ tfmdata.has_italic = otfdata.metadata.has_italic
+ if not tfmdata.language then tfmdata.language = 'dflt' end
+ if not tfmdata.script then tfmdata.script = 'dflt' end
+ shared.processes, shared.features = otf.set_features(tfmdata,fonts.define.check(features,otf.features.default))
end
end
containers.write(tfm.cache(),cache_id,tfmdata)
@@ -1880,108 +1301,106 @@ function otf.otf_to_tfm(specification)
return tfmdata
end
-function otf.features.prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns, currently all
- if value then
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local unicodes = otfdata.luatex.unicodes -- names to unicodes
- local somevalid = otf.some_valid_feature(otfdata,kind,tfmdata.script,tfmdata.language)
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- for u, chr in pairs(characters) do
- -- hm, maybe just use descriptions, and why still index? font is already in
- -- unicode with private slots, so: d = glyphs[u] should work ok
- local d = glyphs[descriptions[u].index]
- if d then
- local dk = d.mykerns
- if dk then
- local t, done = chr.kerns or { }, false
- for lookup,kerns in pairs(dk) do
- if somevalid[lookup] then
- for k, v in pairs(kerns) do
- if v ~= 0 then
- t[k], done = v, true
+--~ {
+--~ ['boundingbox']={ 95, -458, 733, 1449 },
+--~ ['class']="base",
+--~ ['name']="braceleft",
+--~ ['unicode']=123,
+--~ ['vert_variants']={
+--~ ['italic_correction']=0,
+--~ ['parts']={
+--~ { ['component']="uni23A9", ['endConnectorLength']=1000, ['fullAdvance']=2546, ['is_extender']=0, ['startConnectorLength']=0, }, -- bot
+--~ { ['component']="uni23AA", ['endConnectorLength']=2500, ['fullAdvance']=2501, ['is_extender']=1, ['startConnectorLength']=2500, }, -- rep
+--~ { ['component']="uni23A8", ['endConnectorLength']=1000, ['fullAdvance']=4688, ['is_extender']=0, ['startConnectorLength']=1000, }, -- mid
+--~ { ['component']="uni23AA", ['endConnectorLength']=2500, ['fullAdvance']=2501, ['is_extender']=1, ['startConnectorLength']=2500, }, -- rep
+--~ { ['component']="uni23A7", ['endConnectorLength']=0, ['fullAdvance']=2546, ['is_extender']=0, ['startConnectorLength']=1000, }, -- top
+--~ },
+--~ ['variants']="braceleft braceleft.vsize1 braceleft.vsize2 braceleft.vsize3 braceleft.vsize4 braceleft.vsize5 braceleft.vsize6 braceleft.vsize7",
+--~ },
+--~ ['width']=793,
+--~ },
+
+-- the first version made a top/mid/not extensible table, now we just pass on the variants data
+-- and deal with it in the tfm scaler (there is no longer an extensible table anyway)
+
+-- we cannot share descriptions as virtual fonts might extend them (ok, we could
+-- use a cache with a hash
+
+function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder the tma to unicode (nasty due to one->many)
+ if data then
+ local glyphs, pfminfo, metadata = data.glyphs or { }, data.pfminfo or { }, data.metadata or { }
+ local luatex = data.luatex
+ local unicodes = luatex.unicodes -- names to unicodes
+ local indices = luatex.indices
+ local characters, parameters, math_parameters, descriptions = { }, { }, { }, { }
+ local tfm = {
+ characters = characters,
+ parameters = parameters,
+ math_parameters = math_parameters,
+ descriptions = descriptions,
+ indices = indices,
+ unicodes = unicodes,
+ }
+ -- indices maps from unicodes to indices
+ for u, i in next, indices do
+ characters[u] = { } -- we need this because for instance we add protruding info
+ descriptions[u] = glyphs[i]
+ end
+ -- math
+ if metadata.math then
+ -- parameters
+ for name, value in next, metadata.math do
+ math_parameters[name] = value
+ end
+ -- we could use a subset
+ for u, char in next, characters do
+ local d = descriptions[u]
+ local m = d.math
+ -- we have them shared because that packs nicer
+ -- we could prepare the variants and keep 'm in descriptions
+ if m then
+ local variants = m.horiz_variants
+ if variants then
+ local c = char
+ for n in variants:gmatch("[^ ]+") do
+ local un = unicodes[n]
+ if un and u ~= un then
+ c.next = un
+ c = characters[un]
+ end
+ end
+ c.horiz_variants = m.horiz_parts
+ else
+ local variants = m.vert_variants
+ if variants then
+ local c = char
+ for n in variants:gmatch("[^ ]+") do
+ local un = unicodes[n]
+ if un and u ~= un then
+ c.next = un
+ c = characters[un]
end
end
+ c.vert_variants = m.vert_parts
end
end
- if done then
- chr.kerns = t -- no empty assignments
- end
- else
- dk = d.kerns
- if dk then
- local t, done = chr.kerns or { }, false
- for _, v in pairs(dk) do
- if somevalid[v.lookup] then
- local k = unicodes[v.char]
- local o = v.off
- if type(k) == "number" then
- if k > 0 then
- t[k], done = o, true
- end
- else
- for i=1,#k do
- local ki = k[i]
- if ki > 0 then
- t[ki], done = o, true
- end
- end
- end
- end
- end
- if done then
- chr.kerns = t -- no empty assignments
- end
+ local kerns = m.kerns
+ if kerns then
+ char.mathkerns = kerns
end
end
end
end
- end
-end
-
-function otf.add_dimensions(data)
- if data then
- local force = otf.notdef
- for k, d in pairs(data.glyphs) do
- local bb, wd = d.boundingbox, d.width or 0
- if force and not d.name then
- d.name = ".notdef"
- end
- if wd ~= 0 and d.class == "mark" then
- d.width = -wd
- end
- if bb then
- local ht, dp = bb[4], -bb[2]
- if ht ~= 0 then d.height = ht end
- if dp ~= 0 then d.depth = dp end
- end
- d.index = k
- end
- end
-end
-
-function otf.copy_to_tfm(data) -- we can save a copy when we reorder the tma to unicode
- if data then
- local characters, parameters, descriptions = { }, { }, { }
- local tfm = { characters = characters, parameters = parameters, descriptions = descriptions }
- local luatex = data.luatex
- local indices = luatex.indices -- unicodes to indices
- local glyphs = data.glyphs
- for u, i in pairs(indices) do
- local d = glyphs[i]
- characters[u] = { } -- not needed
- descriptions[u] = d
- end
- local designsize = data.designsize or data.design_size or 100
+ -- end math
+ local designsize = metadata.designsize or metadata.design_size or 100
if designsize == 0 then
designsize = 100
end
local spaceunits = 500
- tfm.units = data.units_per_em or 1000
+ tfm.units = metadata.units_per_em or 1000
-- we need a runtime lookup because of running from cdrom or zip, brrr
- tfm.filename = input.findbinfile(data.luatex.filename,"") or data.luatex.filename
- tfm.fullname = data.fontname or data.fullname
+ tfm.filename = resolvers.findbinfile(luatex.filename,"") or luatex.filename
+ tfm.fullname = metadata.fontname or metadata.fullname
tfm.encodingbytes = 2
tfm.cidinfo = data.cidinfo
tfm.cidinfo.registry = tfm.cidinfo.registry or ""
@@ -1993,21 +1412,16 @@ function otf.copy_to_tfm(data) -- we can save a copy when we reorder the tma to
tfm.boundarychar = 65536
tfm.designsize = (designsize/10)*65536
tfm.spacer = "500 units"
- data.isfixedpitch = data.pfminfo and data.pfminfo.panose and data.pfminfo.panose["proportion"] == "Monospaced"
- data.charwidth = nil
- if data.pfminfo then
- data.charwidth = data.pfminfo.avgwidth
- end
local endash, emdash = 0x20, 0x2014 -- unicodes['space'], unicodes['emdash']
- if data.isfixedpitch then
+ if metadata.isfixedpitch then
if descriptions[endash] then
spaceunits, tfm.spacer = descriptions[endash].width, "space"
end
if not spaceunits and descriptions[emdash] then
spaceunits, tfm.spacer = descriptions[emdash].width, "emdash"
end
- if not spaceunits and data.charwidth then
- spaceunits, tfm.spacer = data.charwidth, "charwidth"
+ if not spaceunits and metadata.charwidth then
+ spaceunits, tfm.spacer = metadata.charwidth, "charwidth"
end
else
if descriptions[endash] then
@@ -2016,36 +1430,37 @@ function otf.copy_to_tfm(data) -- we can save a copy when we reorder the tma to
if not spaceunits and descriptions[emdash] then
spaceunits, tfm.spacer = descriptions[emdash].width/2, "emdash/2"
end
- if not spaceunits and data.charwidth then
- spaceunits, tfm.spacer = data.charwidth, "charwidth"
+ if not spaceunits and metadata.charwidth then
+ spaceunits, tfm.spacer = metadata.charwidth, "charwidth"
end
end
spaceunits = tonumber(spaceunits) or tfm.units/2 -- 500 -- brrr
parameters.slant = 0
- parameters.space = spaceunits
- parameters.space_stretch = tfm.units/2 -- 500
- parameters.space_shrink = 2*tfm.units/3 -- 333
- parameters.x_height = 4*tfm.units/5 -- 400
+ parameters.space = spaceunits -- 3.333 (cmr10)
+ parameters.space_stretch = tfm.units/2 -- 500 -- 1.666 (cmr10)
+ parameters.space_shrink = 1*tfm.units/3 -- 333 -- 1.111 (cmr10)
+ parameters.x_height = 2*tfm.units/5 -- 400
parameters.quad = tfm.units -- 1000
- parameters.extra_space = 0
if spaceunits < 2*tfm.units/5 then
-- todo: warning
end
- tfm.italicangle = data.italicangle
- tfm.ascender = math.abs(data.ascent or 0)
- tfm.descender = math.abs(data.descent or 0)
- if data.italicangle then -- maybe also in afm _
- parameters.slant = parameters.slant - math.round(math.tan(data.italicangle*math.pi/180))
+ local italicangle = metadata.italicangle
+ tfm.ascender = math.abs(metadata.ascent or 0)
+ tfm.descender = math.abs(metadata.descent or 0)
+ if italicangle then -- maybe also in afm _
+ tfm.italicangle = italicangle
+ parameters.slant = parameters.slant - math.round(math.tan(italicangle*math.pi/180))
end
- if data.isfixedpitch then
+ if metadata.isfixedpitch then
parameters.space_stretch = 0
parameters.space_shrink = 0
elseif otf.syncspace then --
parameters.space_stretch = spaceunits/2
parameters.space_shrink = spaceunits/3
end
- if data.pfminfo and data.pfminfo.os2_xheight and data.pfminfo.os2_xheight > 0 then
- parameters.x_height = data.pfminfo.os2_xheight
+ parameters.extra_space = parameters.space_shrink -- 1.111 (cmr10)
+ if pfminfo.os2_xheight and pfminfo.os2_xheight > 0 then
+ parameters.x_height = pfminfo.os2_xheight
else
local x = 0x78 -- unicodes['x']
if x then
@@ -2062,23 +1477,55 @@ function otf.copy_to_tfm(data) -- we can save a copy when we reorder the tma to
end
end
+otf.features.register('mathsize')
+
function tfm.read_from_open_type(specification)
local tfmtable = otf.otf_to_tfm(specification)
if tfmtable then
+ local otfdata = tfmtable.shared.otfdata
tfmtable.name = specification.name
tfmtable.sub = specification.sub
- tfmtable = tfm.scale(tfmtable, specification.size)
+ local s = specification.size
+ local m = otfdata.metadata.math
+ if m then
+ local f = specification.features
+ if f then
+ local f = f.normal
+ if f and f.mathsize then
+ local mathsize = specification.mathsize or 0
+ if mathsize == 2 then
+ local p = m.ScriptPercentScaleDown
+ if p then
+ local ps = p * specification.textsize / 100
+ if trace_math then
+ logs.report("define font","asked script size: %s, used: %s (%2.2f %%)",s,ps,(ps/s)*100)
+ end
+ s = ps
+ end
+ elseif mathsize == 3 then
+ local p = m.ScriptScriptPercentScaleDown
+ if p then
+ local ps = p * specification.textsize / 100
+ if trace_math then
+ logs.report("define font","asked scriptscript size: %s, used: %s (%2.2f %%)",s,ps,(ps/s)*100)
+ end
+ s = ps
+ end
+ end
+ end
+ end
+ end
+ tfmtable = tfm.scale(tfmtable,s)
-- here we resolve the name; file can be relocated, so this info is not in the cache
- local otfdata = tfmtable.shared.otfdata
local filename = (otfdata and otfdata.luatex and otfdata.luatex.filename) or specification.filename
if not filename then
-- try to locate anyway and set otfdata.luatex.filename
end
if filename then
tfmtable.encodingbytes = 2
- tfmtable.filename = input.findbinfile(filename,"") or filename
- tfmtable.fullname = otfdata.fontname or otfdata.fullname
- local order = otfdata and otfdata.order2
+ tfmtable.filename = resolvers.findbinfile(filename,"") or filename
+ tfmtable.fullname = otfdata.metadata.fontname or otfdata.metadata.fullname
+ local order = otfdata and otfdata.metadata.order2
if order == 0 then
tfmtable.format = 'opentype'
elseif order == 1 then
@@ -2092,3295 +1539,3 @@ function tfm.read_from_open_type(specification)
end
return tfmtable
end
-
-function otf.analyze_only(otfdata)
- local analyze = otf.analyze_features
- return analyze(otfdata.gpos), analyze(otfdata.gsub)
-end
-
-local a_to_script = { }
-local a_to_language = { }
-
-do
-
- local context_setups = fonts.define.specify.context_setups
- local context_numbers = fonts.define.specify.context_numbers
-
- function otf.set_dynamics(tfmdata,attribute,features) --currently experimental and slow / hackery
- local shared = tfmdata.shared
- if shared then
- local dynamics = shared.dynamics
- if dynamics then
- features = features or context_setups[context_numbers[attribute]]
- if features then
- local script = features.script or 'dflt'
- local language = features.language or 'dflt'
- local ds = dynamics[script]
- if not ds then
- ds = { }
- dynamics[script] = ds
- end
- local dsl = ds[language]
- if not dsl then
- dsl = { }
- ds[language] = dsl
- end
- local dsla = dsl[attribute]
- if dsla then
- return dsla
- else
- a_to_script [attribute] = script
- a_to_language[attribute] = language
- dsla = { }
- local otfdata = shared.otfdata
- local methods = fonts.methods.node.otf
- local initializers = fonts.initializers.node.otf
- local gposfeatures, gsubfeatures = otf.analyze_only(otfdata,features)
- local default = otf.features.default
- local function register(list)
- if list then
- for i=1,#list do
- local f = list[i]
- local value = features[f] or default[f]
- if value then
- local i, m = initializers[f], methods[f]
- if i then
- i(tfmdata,value)
- end
- if m then
- dsla[#dsla+1] = m
- end
- end
- end
- end
- end
- register(fonts.triggers)
- register(gsubfeatures)
- register(gposfeatures)
- dynamics[script][language][attribute] = dsla
- return dsla
- end
- end
- end
- end
- return { } -- todo: false
- end
-
-end
-
--- scripts
-
-otf.default_language = 'latn'
-otf.default_script = 'dflt'
-
-function otf.valid_feature(otfdata,kind,script,language) -- return hash is faster
- local luatex = otfdata.luatex
- if luatex.ctx_always[kind] then
- script, language = 'dflt', 'dflt'
- else
- script = script or otf.default_script
- language = language or otf.default_language
- end
- script, language = script:lower(), language:lower() -- will go away, we will lowercase values
- local ft = luatex.subtables[kind]
- local st = ft[script] or ft.dflt
- local lt = st and (st[language] or st.dflt)
- return false, luatex.always_valid, lt.valid
-end
-
-function otf.some_valid_feature(otfdata,kind,script,language)
- local luatex = otfdata.luatex
- if luatex.ctx_always[kind] then
- script, language = 'dflt', 'dflt'
- else
- script = script or otf.default_script
- language = language or otf.default_language
- script, language = script:lower(), language:lower() -- will go away, we will lowercase values
- end
- local t = luatex.subtables[kind]
- if t then
- local ts = t[script] or t.dflt
- if ts then
- local tsl = ts[language] or ts.dflt
- return (tsl and tsl.valid) or { }
- end
- end
- return { }
-end
-
-function otf.features.aux.resolve_ligatures(tfmdata,ligatures,kind)
- local otfdata = tfmdata.shared.otfdata
- local unicodes = otfdata.luatex.unicodes
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local changed = tfmdata.changed or { }
- local done = { }
- kind = kind or "unknown"
- local trace = otf.trace_features
- while true do
- local ok = false
- for k,v in pairs(ligatures) do
- local lig = v[1]
- if not done[lig] then
- local ligs = split_at_space:match(lig)
- if #ligs == 2 then
- local uc = v[2]
- local c, f, s = characters[uc], ligs[1], ligs[2]
---~ local uf, us = unicodes[f], unicodes[s]
-
-local uft, ust = unicodes[f], unicodes[s]
-if not uft or not ust then
- logs.report("define otf","%s: unicode problem with ligature (%s->%s=%s->%s+%s->%s)",kind,descriptions[uc].name or "?",uc,f,uft or "?",s,ust or "?")
- -- some kind of error
-else
- if type(uft) == "number" then uft = { uft } end
- if type(ust) == "number" then ust = { ust } end
- for ufi=1,#uft do
- local uf = uft[ufi]
- for usi=1,#ust do
- local us = ust[usi]
-
- if changed[uf] or changed[us] then
- if trace then
- logs.report("define otf","%s: %s (%s) + %s (%s) ignored",kind,f,uf,s,us)
- end
- else
- local first, second = characters[uf], us
- if first and second then
- local t = first.ligatures
- if not t then
- t = { }
- first.ligatures = t
- end
- local uuc = unicodes[descriptions[uc].name]
- if type(uuc) == "number" then
- t[second] = { type = 0, char = uuc }
- else
- t[second] = { type = 0, char = uuc[1] }
- end
- if trace then
- logs.report("define otf","%s: %s (%s) + %s (%s) = %s (%s)",kind,f,uf,s,us,descriptions[uc].name,unicodes[descriptions[uc].name])
- end
- end
- end
-
- end
- end
-end
-
- ok, done[lig] = true, descriptions[uc].name
- end
- end
- end
- if ok then
- for d,n in pairs(done) do
- local pattern = "^(" .. d .. ") "
- for k,v in pairs(ligatures) do
- v[1] = v[1]:gsub(pattern, function(str)
- return n .. " "
- end)
- end
- end
- else
- break
- end
- end
-end
-
-function otf.features.prepare_base_substitutions(tfmdata,kind,value) -- we can share some code with the node features
- if value then
- local ligatures = { }
- local otfdata = tfmdata.shared.otfdata
- local unicodes = otfdata.luatex.unicodes
- local trace = otf.trace_features
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local somevalid = otf.some_valid_feature(otfdata,kind,tfmdata.script,tfmdata.language)
- if not table.is_empty(somevalid) then
- tfmdata.changed = tfmdata.changed or { }
- local changed = tfmdata.changed
- local glyphs = otfdata.glyphs
- for k,c in pairs(characters) do
- local o = glyphs[descriptions[k].index]
- if o and o.lookups then
- for lookup,ps in pairs(o.lookups) do
- if somevalid[lookup] then
- for i=1,#ps do
- local p = ps[i]
- local t = p[1]
- if t == 'substitution' then
- local pv = p[2] -- p.variant
- if pv then
- local upv = unicodes[pv]
- if upv then
- if type(upv) == "number" then
- if characters[upv] then
- if trace then
- logs.report("define otf","%s: %s (%s) => %s (%s)",kind,descriptions[k].name,k,descriptions[upv].name,upv)
- end
- characters[k] = characters[upv]
- descriptions[k] = descriptions[upv]
- changed[k] = true
- end
- else
- for i=1,#upv do
- local upv = upv[i]
- if characters[upv] then
- if trace then
- logs.report("define otf","%s: %s (%s) => %s (%s)",kind,descriptions[k].name,k,descriptions[upv].name,upv)
- end
- characters[k] = characters[upv]
- descriptions[k] = descriptions[upv]
- changed[k] = true
- end
- end
- end
- end
- end
- elseif t == 'alternate' then
- local pc = p[2] -- p.components
- if pc then
- pc = pa.components:match("([^ ]+)") -- todo: selector
- if pc then
- local upc = unicodes[pc]
- if upc then
- if type(upc) == "number" then
- if chars[upc] then
- if trace then
- logs.report("define otf","%s: %s (%s) => %s (%s)",kind,descriptions[k].name,k,descriptions[upc].name,upc)
- end
- characters[k] = characters[upc]
- descriptions[k] = descriptions[upc]
- changed[k] = true
- end
- else
- for i=1,#upc do
- local upc = upc[i]
- if chars[upc] then
- if trace then
- logs.report("define otf","%s: %s (%s) => %s (%s)",kind,descriptions[k].name,k,descriptions[upc].name,upc)
- end
- characters[k] = characters[upc]
- descriptions[k] = descriptions[upc]
- changed[k] = true
- end
- end
- end
- end
- end
- end
- elseif t == 'ligature' and not changed[k] then
- local pc = p[2]
- if pc then
- if trace then
- logs.report("define otf","%s: %s => %s (%s)",kind,pc,descriptions[k].name,k)
- end
- ligatures[#ligatures+1] = { pc, k }
- end
- end
- end
- end
- end
- end
- end
- otf.features.aux.resolve_ligatures(tfmdata,ligatures,kind)
- end
- else
- tfmdata.ligatures = tfmdata.ligatures or { }
- end
-end
-
-function fonts.initializers.base.otf.liga(tfm,value) otf.features.prepare_base_substitutions(tfm,'liga',value) end
-function fonts.initializers.base.otf.dlig(tfm,value) otf.features.prepare_base_substitutions(tfm,'dlig',value) end
-function fonts.initializers.base.otf.rlig(tfm,value) otf.features.prepare_base_substitutions(tfm,'rlig',value) end
-function fonts.initializers.base.otf.hlig(tfm,value) otf.features.prepare_base_substitutions(tfm,'hlig',value) end
-function fonts.initializers.base.otf.pnum(tfm,value) otf.features.prepare_base_substitutions(tfm,'pnum',value) end
-function fonts.initializers.base.otf.onum(tfm,value) otf.features.prepare_base_substitutions(tfm,'onum',value) end
-function fonts.initializers.base.otf.tnum(tfm,value) otf.features.prepare_base_substitutions(tfm,'tnum',value) end
-function fonts.initializers.base.otf.lnum(tfm,value) otf.features.prepare_base_substitutions(tfm,'lnum',value) end
-function fonts.initializers.base.otf.zero(tfm,value) otf.features.prepare_base_substitutions(tfm,'zero',value) end
-function fonts.initializers.base.otf.smcp(tfm,value) otf.features.prepare_base_substitutions(tfm,'smcp',value) end
-function fonts.initializers.base.otf.cpsp(tfm,value) otf.features.prepare_base_substitutions(tfm,'cpsp',value) end
-function fonts.initializers.base.otf.c2sc(tfm,value) otf.features.prepare_base_substitutions(tfm,'c2sc',value) end
-function fonts.initializers.base.otf.ornm(tfm,value) otf.features.prepare_base_substitutions(tfm,'ornm',value) end
-function fonts.initializers.base.otf.aalt(tfm,value) otf.features.prepare_base_substitutions(tfm,'aalt',value) end
-
-function fonts.initializers.base.otf.hwid(tfm,value) otf.features.prepare_base_substitutions(tfm,'hwid',value) end
-function fonts.initializers.base.otf.fwid(tfm,value) otf.features.prepare_base_substitutions(tfm,'fwid',value) end
-
--- Here comes the real thing ... node processing! The next session prepares
--- things. The main features (unchained by rules) have their own caches,
--- while the private ones cache locally.
-
-do
-
- otf.features.prepare = { }
-
- local falsetable = { false, false, false }
-
- function otf.features.prepare.feature(tfmdata,kind,value)
- if value then
- local language, script = tfmdata.language or "dflt", tfmdata.script or "dflt"
- local shared = tfmdata.shared
- local otfdata = shared.otfdata
- local lookuptable = otf.valid_subtable(otfdata,kind,script,language)
- if lookuptable then
- local fullkind = kind .. script .. language
- if not shared.lookuptable [fullkind] then
- --~ print(tfmdata,file.basename(tfmdata.fullname or ""),kind,script,language,lookuptable,fullkind)
- local processes = { }
- -- featuredata and featurecache are indexed by lookup so we can share them
- shared.featuredata [kind] = shared.featuredata [kind] or { }
- shared.featurecache[kind] = shared.featurecache[kind] or false -- signal
- shared.lookuptable [fullkind] = lookuptable
- shared.processes [fullkind] = processes
- local luatex = otfdata.luatex
- local types = luatex.name_to_type
- local flags = luatex.ignore_flags
- local preparers = otf.features.prepare
- local process = otf.features.process
- for i=1,#lookuptable do
- local lookupname = lookuptable[i]
- local lookuptype = types[lookupname]
- local prepare = preparers[lookuptype]
- if prepare then
- local processdata = prepare(tfmdata,kind,lookupname)
- if processdata then
- local processflags = flags[lookupname] or falsetable --- share false table
- -- local chain = (lookuptype == "gsub_contextchain") or (lookuptype == "gpos_contextchain")
- local chain = lookuptype:find("context") ~= nil
- processes[#processes+1] = { process[lookuptype], lookupname, processdata, processflags, chain }
- end
- end
- end
- end
- end
- end
- end
-
- -- helper: todo, we don't need to store non local ones for chains so we can pass the
- -- validator as parameter
-
- function otf.features.collect_ligatures(tfmdata,kind) -- ligs are spread all over the place
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes -- names to unicode
- local indices = luatex.indices -- unicode to index
- local trace = otf.trace_features
- local ligatures = { }
- local function collect(lookup,unicode,glyph,ps)
- for i=1,#ps do
- local p = ps[i]
- if p[1] == 'ligature' then
- if trace then
- logs.report("define otf","feature %s lookup %s ligature %s => %s",kind,lookup,p[2],glyph.name)
- end
- local t = ligatures[lookup]
- if not t then
- t = { }
- ligatures[lookup] = t
- end
- -- this table is kind of special:
- -- unicode -> tree of names/indices -> unicode
- -- this way we can handle multiple unicode to one glyph cases
- local first = true
- for s in p[2]:gmatch("[^ ]+") do
- if first then
- local u = unicodes[s]
- if not u then
- logs.report("define otf","feature %s lookup %s ligature %s => %s ignored due to invalid unicode",kind,lookup,p[2],glyph.name)
- elseif type(u) == "number" then
- if not t[u] then
- t[u] = { { } }
- end
- t = t[u]
- else
- local tt = t
- local tu
- for i=1,#u do
- local u = u[i]
- if i==1 then
- if not t[u] then
- t[u] = { { } }
- end
- tu = t[u]
- t = tu
- else
- if not t[u] then
- tt[u] = tu
- end
- end
- end
- end
- first = false
- else
- -- beware, we mix unicodes and indices, we can comment these
- -- lines when testing, see (*lig*)
- s = unicodes[s]
- if type(s) == "number" then
- s = indices[s]
- else
- s = indices[s[1]]
- end
- -- maybe we will introduce a names table some day
- local t1 = t[1]
- if not t1[s] then
- t1[s] = { { } }
- end
- t = t1[s]
- end
- end
- t[2] = unicode
- end
- end
- end
- local forced, always, okay = otf.valid_feature(otfdata,kind,tfmdata.script,tfmdata.language)
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local lookups = glyph.lookups
- if lookups then
- if forced then
- for lookup, ps in pairs(lookups) do collect(lookup,unicode,glyph,ps) end
- elseif okay then
- for lookup, ps in pairs(lookups) do if always[lookup] or okay[lookup] then collect(lookup,unicode,glyph,ps) end end
- else
- for lookup, ps in pairs(lookups) do if always[lookup] then collect(lookup,unicode,glyph,ps) end end
- end
- end
- end
- return ligatures
- end
-
- -- gsub_single -> done
- -- gsub_multiple -> done
- -- gsub_alternate -> done
- -- gsub_ligature -> done
- -- gsub_context -> todo
- -- gsub_contextchain -> done
- -- gsub_reversecontextchain -> todo
-
- -- we used to share code in the following functions but that was relatively
- -- due to extensive calls to functions (easily hundreds of thousands per
- -- document)
-
- function otf.features.prepare.gsub_single(tfmdata,kind,lookupname)
- local featuredata = tfmdata.shared.featuredata[kind]
- local substitutions = featuredata[lookupname]
- if not substitutions then
- substitutions = { }
- featuredata[lookupname] = substitutions
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes -- names to unicode
- local indices = luatex.indices -- unicode to index
- local trace = otf.trace_features
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local lookups = glyph.lookups
- if lookups then
- for lookup,ps in pairs(lookups) do
- if lookup == lookupname then
- for i=1,#ps do
- local p = ps[i]
- if p[1] == 'substitution' then
- local old, new = unicode, unicodes[p[2]]
- if type(new) == "table" then
- new = new[1]
- end
- substitutions[old] = new
- if trace then
- logs.report("define otf","%s:%s substitution %s => %s",kind,lookupname,old,new)
- end
- end
- end
- end
- end
- end
- end
- end
- return substitutions
- end
-
- function otf.features.prepare.gsub_multiple(tfmdata,kind,lookupname)
- local featuredata = tfmdata.shared.featuredata[kind]
- local substitutions = featuredata[lookupname]
- if not substitutions then
- substitutions = { }
- featuredata[lookupname] = substitutions
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes -- names to unicode
- local indices = luatex.indices -- unicode to index
- local trace = otf.trace_features
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local lookups = glyph.lookups
- if lookups then
- for lookup,ps in pairs(lookups) do
- if lookup == lookupname then
- for i=1,#ps do
- local p = ps[i]
- if p[1] == 'multiple' then
- local old, new = unicode, { }
- substitutions[old] = new
- for pc in p[2]:gmatch("[^ ]+") do
- local upc = unicodes[pc]
- if type(upc) == "number" then
- new[#new+1] = upc
- else
- new[#new+1] = upc[1]
- end
- end
- if trace then
- logs.report("define otf","%s:%s multiple %s => %s",kind,lookupname,old,concat(new," "))
- end
- end
- end
- end
- end
- end
- end
- end
- return substitutions
- end
-
- function otf.features.prepare.gsub_alternate(tfmdata,kind,lookupname)
- -- todo: configurable preference list
- local featuredata = tfmdata.shared.featuredata[kind]
- local substitutions = featuredata[lookupname]
- if not substitutions then
- featuredata[lookupname] = { }
- substitutions = featuredata[lookupname]
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes -- names to unicode
- local indices = luatex.indices -- unicode to index
- local trace = otf.trace_features
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local lookups = glyph.lookups
- if lookups then
- for lookup,ps in pairs(lookups) do
- if lookup == lookupname then
- for i=1,#ps do
- local p = ps[i]
- if p[1] == 'alternate' then
- local old = unicode
- local t = { }
- for pc in p[2]:gmatch("[^ ]+") do
- local upc = unicodes[pc]
- if type(upc) == "number" then
- t[#t+1] = upc
- else
- t[#t+1] = upc[1]
- end
- end
- substitutions[old] = t
- if trace then
- logs.report("define otf","%s:%s alternate %s => %s",kind,lookupname,old,concat(substitutions,"|"))
- end
- end
- end
- end
- end
- end
- end
- end
- return substitutions
- end
-
- function otf.features.prepare.gsub_ligature(tfmdata,kind,lookupname)
- -- we collect them for all lookups, this saves loops, we only use the
- -- lookupname for testing, we need to check if this leads to redundant
- -- collections
- local ligatures = tfmdata.shared.featuredata[kind]
- if not ligatures[lookupname] then
- ligatures = otf.features.collect_ligatures(tfmdata,kind)
- tfmdata.shared.featuredata[kind] = ligatures
- end
- return ligatures[lookupname]
- end
-
- function otf.features.prepare.contextchain(tfmdata,kind,lookupname)
- local featuredata = tfmdata.shared.featuredata[kind]
- local contexts = featuredata[lookupname]
- if not contexts then
- contexts = { }
- featuredata[lookupname] = contexts
- local characters = tfmdata.characters
- local otfdata = tfmdata.shared.otfdata
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes
- local internals = luatex.internals
- local flags = luatex.ignore_flags
- local types = luatex.name_to_type
- local cache = luatex.covers
- if not cache then
- cache = { }
- luatex.covers = cache
- end
- local function uncover(covers,result)
- -- lpeg hardly faster (.005 sec on mk)
- for n=1,#covers do
- local c = covers[n]
- local cc = cache[c]
- if not cc then
- local t = { }
- for s in c:gmatch("[^ ]+") do
- local us = unicodes[s]
- if type(us) == "number" then
- t[us] = true
- else
- for i=1,#us do
- t[us[i]] = true
- end
- end
- end
- cache[c] = t
- result[#result+1] = t
- else
- result[#result+1] = cc
- end
- end
- end
- local lookupdata = otfdata.lookups[lookupname]
- if not lookupdata then
- logs.report("otf process","missing lookupdata table %s",lookupname)
- elseif lookupdata.rules then
- local rules = lookupdata.rules
- local center_match = otf.center_match
- for nofrules=1,#rules do
- local rule = rules[nofrules]
- local coverage = rule.coverage
- if coverage and coverage.current then
- local current, before, after, sequence = coverage.current, coverage.before, coverage.after, { }
- if before then
- uncover(before,sequence)
- end
- local start = #sequence + 1
- uncover(current,sequence)
- local stop = #sequence
- if after then
- uncover(after,sequence)
- end
- if sequence[1] then
- local lookups, lookuptype = rule.lookups, 'self'
- -- for the moment only lookup index 1
- if lookups then
- if #lookups > 1 then
- logs.report("otf process","WARNING: more than one lookup in rule")
- end
- lookuptype = types[lookups[1]]
- end
- -- this may be wrong; we cannot copy inside the for loop (out of memory with hz);
- -- so we may end up with a different usage of sequence in the chainproc handlers
- sequence = table.copy(sequence)
- -- we trigger on the first character in current
- for unic, _ in pairs(sequence[start]) do
- local t = contexts[unic]
- if not t then
- contexts[unic] = { lookups={}, flags=flags[lookupname] }
- t = contexts[unic].lookups
- end
- t[#t+1] = { nofrules, lookuptype, sequence, start, stop, lookups }
- end
- end
- end
- end
- end
- end
- return contexts
- end
-
- otf.features.prepare.gsub_context = otf.features.prepare.contextchain
- otf.features.prepare.gsub_contextchain = otf.features.prepare.contextchain
- otf.features.prepare.gsub_reversecontextchain = otf.features.prepare.contextchain
-
- -- ruled->lookup=ks_latn_l_27_c_4 => internal[ls_l_84] => valid[ls_l_84_s]
-
- -- gpos_mark2base -> done
- -- gpos_mark2ligature -> done
- -- gpos_mark2mark -> done
- -- gpos_single -> not done
- -- gpos_pair -> not done
- -- gpos_cursive -> not done
- -- gpos_context -> not done
- -- gpos_reversecontextchain -> not done
-
- function otf.features.prepare.anchors(tfmdata,kind,lookupname) -- tracing
- local featuredata = tfmdata.shared.featuredata[kind]
- local anchors = featuredata[lookupname]
- if not anchors then
- anchors = { }
- featuredata[lookupname] = anchors
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes
- local indices = luatex.indices
- local validanchors = { }
- local trace = otf.trace_features
- local classes = otfdata.anchor_classes
- if classes then
- for k=1,#classes do
- local class = classes[k]
- if class.lookup == lookupname then
- if trace then
- logs.report("define otf","%s:%s anchor -> %s",kind,lookupname,class.name)
- end
- validanchors[class.name] = true
- end
- end
- end
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local oanchor = glyph.anchors
- if oanchor then
- local t, ok = { }, false
- for type, anchors in pairs(oanchor) do -- types
- local tt = false
- for name, anchor in pairs(anchors) do
- if validanchors[name] then
- if not tt then
- tt = { [name] = anchor }
- t[type] = tt
- ok = true
- else
- tt[name] = anchor
- end
- end
- end
- end
- if ok then
- anchors[unicode] = t
- end
- end
- end
- end
---~ if kind == "mkmk" then print(lookupname,table.serialize(anchors)) end
- return anchors
- end
-
- otf.features.prepare.gpos_mark2base = otf.features.prepare.anchors
- otf.features.prepare.gpos_mark2ligature = otf.features.prepare.anchors
- otf.features.prepare.gpos_mark2mark = otf.features.prepare.anchors
- otf.features.prepare.gpos_cursive = otf.features.prepare.anchors
- otf.features.prepare.gpos_context = otf.features.prepare.contextchain
- otf.features.prepare.gpos_contextchain = otf.features.prepare.contextchain
-
- function otf.features.prepare.gpos_single(tfmdata,kind,lookupname)
- logs.report("otf define","gpos_single not yet supported")
- end
-
- -- ["kerns"]={ { ["char"]="ytilde", ["lookup"]="pp_l_1_s", ["off"]=-83, ...
- -- ["mykerns"] = { ["pp_l_1_s"] = { [67] = -28, ...
-
- function otf.features.prepare.gpos_pair(tfmdata,kind,lookupname)
- local featuredata = tfmdata.shared.featuredata[kind]
- local kerns = featuredata[lookupname]
- if not kerns then
- local trace = otf.trace_features
- featuredata[lookupname] = { }
- kerns = featuredata[lookupname]
- local otfdata = tfmdata.shared.otfdata
- local glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- local unicodes = luatex.unicodes
- local indices = luatex.indices
- -- ff has isolated kerns in a separate table
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local list = glyph.mykerns
- if list then
- local omk = list[lookupname]
- if omk then
- local krn = kerns[unicode]
- for other, off in pairs(omk) do
- if not krn then
- krn = { }
- kerns[unicode] = krn
- end
- krn[other] = off
- if trace then
- logs.report("define otf","feature %s kern pair %s - %s",kind,unicode,other)
- end
- end
- end
- else
- list = glyph.kerns
- if list then
- local krn
- for ok=1,#list do
- local k = list[ok]
- if k.lookup == lookupname then
- local char = k.char
- if char then
- if not krn then
- krn = kerns[unicode]
- if not krn then
- krn = { }
- kerns[unicode] = krn
- end
- end
- local second = unicodes[char]
- local off = k.off
- if type(second) == "number" then
- krn[second] = off
- if trace then
- logs.report("define otf","feature %s kern pair %s - %s",kind,unicode,second)
- end
- else
- for i=1,#second do
- local second = second[i]
- krn[second] = off
- if trace then
- logs.report("define otf","feature %s kern pair %s - %s",kind,unicode,second)
- end
- end
- end
- end
- end
- end
- end
- end
- list = glyphs.lookups
- if list then
- for lookup,ps in pairs(list) do
- if lookup == lookupname then
- local krn
- for i=1,#ps do
- local p = ps[i]
- if p[1] == 'pair' then
- if not krn then
- krn = kerns[unicode]
- if not krn then
- krn = { }
- kerns[unicode] = krn
- end
- end
- local second = unicodes[p[2]]
- if type(second) == "number" then
- krn[second] = p
- if trace then
- logs.report("define otf","feature %s kern pair %s - %s",kind,unicode,second)
- end
- else
- for i=1,#second do
- local second = second[i]
- krn[second] = p
- if trace then
- logs.report("define otf","feature %s kern pair %s - %s",kind,unicode,second)
- end
- end
- end
- end
- end
- end
- end
- end
- end
- end
- return kerns
- end
-
- otf.features.prepare.gpos_contextchain = otf.features.prepare.contextchain
-
-end
-
--- can be generalized: one loop in main
-
-do
-
- local prepare = otf.features.prepare.feature
-
- function fonts.initializers.node.otf.aalt(tfm,value) return prepare(tfm,'aalt',value) end
- function fonts.initializers.node.otf.abvm(tfm,value) return prepare(tfm,'abvm',value) end
- function fonts.initializers.node.otf.afrc(tfm,value) return prepare(tfm,'afrc',value) end
- function fonts.initializers.node.otf.akhn(tfm,value) return prepare(tfm,'akhn',value) end
- function fonts.initializers.node.otf.blwm(tfm,value) return prepare(tfm,'blwm',value) end
- function fonts.initializers.node.otf.c2pc(tfm,value) return prepare(tfm,'c2pc',value) end
- function fonts.initializers.node.otf.c2sc(tfm,value) return prepare(tfm,'c2sc',value) end
- function fonts.initializers.node.otf.calt(tfm,value) return prepare(tfm,'calt',value) end
- function fonts.initializers.node.otf.case(tfm,value) return prepare(tfm,'case',value) end
- function fonts.initializers.node.otf.ccmp(tfm,value) return prepare(tfm,'ccmp',value) end
- function fonts.initializers.node.otf.clig(tfm,value) return prepare(tfm,'clig',value) end
- function fonts.initializers.node.otf.cpsp(tfm,value) return prepare(tfm,'cpsp',value) end
- function fonts.initializers.node.otf.cswh(tfm,value) return prepare(tfm,'cswh',value) end
- function fonts.initializers.node.otf.curs(tfm,value) return prepare(tfm,'curs',value) end
- function fonts.initializers.node.otf.dlig(tfm,value) return prepare(tfm,'dlig',value) end
- function fonts.initializers.node.otf.dnom(tfm,value) return prepare(tfm,'dnom',value) end
- function fonts.initializers.node.otf.expt(tfm,value) return prepare(tfm,'expt',value) end
- function fonts.initializers.node.otf.fin2(tfm,value) return prepare(tfm,'fin2',value) end
- function fonts.initializers.node.otf.fin3(tfm,value) return prepare(tfm,'fin3',value) end
- function fonts.initializers.node.otf.fina(tfm,value) return prepare(tfm,'fina',value) end
- function fonts.initializers.node.otf.frac(tfm,value) return prepare(tfm,'frac',value) end
- function fonts.initializers.node.otf.fwid(tfm,value) return prepare(tfm,'fwid',value) end
- function fonts.initializers.node.otf.haln(tfm,value) return prepare(tfm,'haln',value) end
- function fonts.initializers.node.otf.hist(tfm,value) return prepare(tfm,'hist',value) end
- function fonts.initializers.node.otf.hkna(tfm,value) return prepare(tfm,'hkna',value) end
- function fonts.initializers.node.otf.hlig(tfm,value) return prepare(tfm,'hlig',value) end
- function fonts.initializers.node.otf.hngl(tfm,value) return prepare(tfm,'hngl',value) end
- function fonts.initializers.node.otf.hwid(tfm,value) return prepare(tfm,'hwid',value) end
- function fonts.initializers.node.otf.init(tfm,value) return prepare(tfm,'init',value) end
- function fonts.initializers.node.otf.isol(tfm,value) return prepare(tfm,'isol',value) end
- function fonts.initializers.node.otf.ital(tfm,value) return prepare(tfm,'ital',value) end
- function fonts.initializers.node.otf.jp78(tfm,value) return prepare(tfm,'jp78',value) end
- function fonts.initializers.node.otf.jp83(tfm,value) return prepare(tfm,'jp83',value) end
- function fonts.initializers.node.otf.jp90(tfm,value) return prepare(tfm,'jp90',value) end
- function fonts.initializers.node.otf.kern(tfm,value) return prepare(tfm,'kern',value) end
- function fonts.initializers.node.otf.liga(tfm,value) return prepare(tfm,'liga',value) end
- function fonts.initializers.node.otf.lnum(tfm,value) return prepare(tfm,'lnum',value) end
- function fonts.initializers.node.otf.locl(tfm,value) return prepare(tfm,'locl',value) end
- function fonts.initializers.node.otf.mark(tfm,value) return prepare(tfm,'mark',value) end
- function fonts.initializers.node.otf.med2(tfm,value) return prepare(tfm,'med2',value) end
- function fonts.initializers.node.otf.medi(tfm,value) return prepare(tfm,'medi',value) end
- function fonts.initializers.node.otf.mgrk(tfm,value) return prepare(tfm,'mgrk',value) end
- function fonts.initializers.node.otf.mkmk(tfm,value) return prepare(tfm,'mkmk',value) end
- function fonts.initializers.node.otf.nalt(tfm,value) return prepare(tfm,'nalt',value) end
- function fonts.initializers.node.otf.nlck(tfm,value) return prepare(tfm,'nlck',value) end
- function fonts.initializers.node.otf.nukt(tfm,value) return prepare(tfm,'nukt',value) end
- function fonts.initializers.node.otf.numr(tfm,value) return prepare(tfm,'numr',value) end
- function fonts.initializers.node.otf.onum(tfm,value) return prepare(tfm,'onum',value) end
- function fonts.initializers.node.otf.ordn(tfm,value) return prepare(tfm,'ordn',value) end
- function fonts.initializers.node.otf.ornm(tfm,value) return prepare(tfm,'ornm',value) end
- function fonts.initializers.node.otf.pnum(tfm,value) return prepare(tfm,'pnum',value) end
- function fonts.initializers.node.otf.pref(tfm,value) return prepare(tfm,'pref',value) end
- function fonts.initializers.node.otf.pres(tfm,value) return prepare(tfm,'pres',value) end
- function fonts.initializers.node.otf.pstf(tfm,value) return prepare(tfm,'pstf',value) end
- function fonts.initializers.node.otf.rlig(tfm,value) return prepare(tfm,'rlig',value) end
- function fonts.initializers.node.otf.rphf(tfm,value) return prepare(tfm,'rphf',value) end
- function fonts.initializers.node.otf.rtla(tfm,value) return prepare(tfm,'rtla',value) end
- function fonts.initializers.node.otf.salt(tfm,value) return prepare(tfm,'salt',value) end
- function fonts.initializers.node.otf.sinf(tfm,value) return prepare(tfm,'sinf',value) end
- function fonts.initializers.node.otf.smcp(tfm,value) return prepare(tfm,'smcp',value) end
- function fonts.initializers.node.otf.smpl(tfm,value) return prepare(tfm,'smpl',value) end
- function fonts.initializers.node.otf.ss01(tfm,value) return prepare(tfm,'ss01',value) end
- function fonts.initializers.node.otf.ss02(tfm,value) return prepare(tfm,'ss02',value) end
- function fonts.initializers.node.otf.ss03(tfm,value) return prepare(tfm,'ss03',value) end
- function fonts.initializers.node.otf.ss04(tfm,value) return prepare(tfm,'ss04',value) end
- function fonts.initializers.node.otf.ss05(tfm,value) return prepare(tfm,'ss05',value) end
- function fonts.initializers.node.otf.ss06(tfm,value) return prepare(tfm,'ss06',value) end
- function fonts.initializers.node.otf.ss07(tfm,value) return prepare(tfm,'ss07',value) end
- function fonts.initializers.node.otf.ss08(tfm,value) return prepare(tfm,'ss08',value) end
- function fonts.initializers.node.otf.ss09(tfm,value) return prepare(tfm,'ss09',value) end
- function fonts.initializers.node.otf.subs(tfm,value) return prepare(tfm,'subs',value) end
- function fonts.initializers.node.otf.sups(tfm,value) return prepare(tfm,'sups',value) end
- function fonts.initializers.node.otf.swsh(tfm,value) return prepare(tfm,'swsh',value) end
- function fonts.initializers.node.otf.titl(tfm,value) return prepare(tfm,'titl',value) end
- function fonts.initializers.node.otf.tnam(tfm,value) return prepare(tfm,'tnam',value) end
- function fonts.initializers.node.otf.tnum(tfm,value) return prepare(tfm,'tnum',value) end
- function fonts.initializers.node.otf.trad(tfm,value) return prepare(tfm,'trad',value) end
- function fonts.initializers.node.otf.unic(tfm,value) return prepare(tfm,'unic',value) end
- function fonts.initializers.node.otf.zero(tfm,value) return prepare(tfm,'zero',value) end
-
-end
-
-do
-
- -- todo: use nodes helpers
-
- local glyph = node.id('glyph')
- local glue = node.id('glue')
- local kern = node.id('kern')
- local disc = node.id('disc')
- local whatsit = node.id('whatsit')
-
- local fontdata = tfm.id
- local has_attribute = node.has_attribute
- local set_attribute = node.set_attribute
- local state = attributes.numbers['state'] or 100
- local marknumber = attributes.numbers['mark'] or 200
- local report = logs.report
- local scale = tex.scale
-
- otf.features.process = { }
-
- -- we share some vars here, after all, we have no nested lookups and
- -- less code
-
- local tfmdata = false
- local otfdata = false
- local characters = false
- local descriptions = false
- local marks = false
- local indices = false
- local glyphs = false
- local currentfont = false
- local rlmode = 0
-
- -- we cheat a bit and assume that a font,attr combination are kind of ranged
-
- local context_setups = fonts.define.specify.context_setups
- local context_numbers = fonts.define.specify.context_numbers
-
- -- 1 loop over glyphs loop over lookups, quit at match
- -- 2 loop over glyphs loop over lookups, continue at match
- -- 3 loop over lookups loop over glyphs
-
- otf.strategy = 2
-
- function otf.features.process.feature(head,font,attr,kind,attribute)
- tfmdata = fontdata[font]
- local shared = tfmdata.shared
- otfdata = shared.otfdata
- characters = tfmdata.characters
- descriptions = tfmdata.descriptions
- glyphs = otfdata.glyphs
- local luatex = otfdata.luatex
- marks = luatex.marks
- indices = luatex.indices
- currentfont = font
- rlmode = 0
- local script, language, strategy
- if attr and attr > 0 then
- local features = context_setups[context_numbers[attr]]
- language, script, strategy = features.language or "dflt", features.script or "dflt", features.strategy or otf.strategy
- else
- language, script, strategy = tfmdata.language or "dflt", tfmdata.script or "dflt", tfmdata.strategy or otf.strategy
- end
- local fullkind = kind .. script .. language
- local lookuptable = shared.lookuptable[fullkind]
- if lookuptable then
- -- local strategy = otf.strategy
- local types = otfdata.luatex.name_to_type
- local start, done, ok = head, false, false
- local processes = shared.processes[fullkind]
- if #processes == 1 then
- local p = processes[1]
- while start do -- evt splitsen
- local id = start.id
- if id == glyph then
- if start.subtype<256 and start.font == font and
- (not attr or has_attribute(start,0,attr)) and -- dynamic feature
- (not attribute or has_attribute(start,state,attribute)) then
- -- we can make the p vars also global to this closure
- local pp = p[3] -- all lookups
- local pc = pp[start.char]
- if pc then
- start, ok = p[1](start,kind,p[2],pc,pp,p[4])
- done = done or ok
- if start then start = start.next end
- else
- start = start.next
- end
- else
- start = start.next
- end
- elseif id == glue and p[5] then
- local pp = p[3] -- all lookups
- local pc = pp[32] -- space, todo: more generic spacing
- if pc then
- start, ok = p[1](start,kind,p[2],pc,pp,p[4])
- done = done or ok
- if start then start = start.next end
- else
- start = start.next
- end
- elseif id == whatsit then
- local subtype = start.subtype
- if subtype == 7 then
- local dir = start.dir
- if dir == "+TRT" then
- rlmode = -1
- elseif dir == "+TLT" then
- rlmode = 1
- else
- rlmode = 0
- end
- elseif subtype == 6 then
- local dir = start.dir
- if dir == "TRT" then
- rlmode = -1
- elseif dir == "TLT" then
- rlmode = 1
- else
- rlmode = 0
- end
- end
- start = start.next
- else
- start = start.next
- end
- end
- elseif strategy == 3 then
- for i=1,#processes do local p = processes[i]
- local pp = p[3]
- start = head
- while start do
- local id = start.id
- if id == glyph then
- if start.subtype<256 and start.font == font and
- (not attr or has_attribute(start,0,attr)) and -- dynamic feature
- (not attribute or has_attribute(start,state,attribute)) then
- local pc = pp[start.char]
- if pc then
- start, ok = p[1](start,kind,p[2],pc,pp,p[4])
- if ok then
- done = true
- end -- else
- if start then start = start.next end
- else
- start = start.next
- end
- else
- start = start.next
- end
- elseif id == glue then
- if p[5] then -- chain
- local pc = pp[32]
- if pc then
- start, ok = p[1](start,kind,p[2],pc,p[3],p[4])
- if ok then
- done = true
- end
- if start then start = start.next end
- else
- start = start.next
- end
- else
- start = start.next
- end
- elseif id == whatsit then
- local subtype = start.subtype
- if subtype == 7 then
- local dir = start.dir
- if dir == "+TRT" then
- rlmode = -1
- elseif dir == "+TLT" then
- rlmode = 1
- else
- rlmode = 0
- end
- elseif subtype == 6 then
- local dir = start.dir
- if dir == "TRT" then
- rlmode = -1
- elseif dir == "TLT" then
- rlmode = 1
- else
- rlmode = 0
- end
- end
- start = start.next
- else
- start = start.next
- end
- end
- end
- else
- while start do
- local id = start.id
- if id == glyph then
- if start.subtype<256 and start.font == font and
- (not attr or has_attribute(start,0,attr)) and -- dynamic feature
- (not attribute or has_attribute(start,state,attribute)) then
- local chr = start.char -- used ?
- for i=1,#processes do local p = processes[i]
- local pp = p[3]
---~ local pc = pp[chr]
- local pc = pp[start.char]
- if pc then
- start, ok = p[1](start,kind,p[2],pc,pp,p[4])
- if ok then
- done = true
- if strategy == 1 then
- break
- end
- end -- else
- if not start then
- break
- end
- end
- end
- if start then start = start.next end
- else
- start = start.next
- end
- elseif id == glue then
- for i=1,#processes do local p = processes[i]
- if p[5] then -- chain
- local pp = p[3]
- local pc = pp[32]
- if pc then
- start, ok = p[1](start,kind,p[2],pc,pp,p[4])
- if ok then
- done = true
- if strategy == 1 then
- break
- end
- end
- if not start then
- break
- end
- end
- end
- end
- if start then start = start.next end
- elseif id == whatsit then
- local subtype = start.subtype
- if subtype == 7 then
- local dir = start.dir
- if dir == "+TRT" then
- rlmode = -1
- elseif dir == "+TLT" then
- rlmode = 1
- else
- rlmode = 0
- end
- elseif subtype == 6 then
- local dir = start.dir
- if dir == "TRT" then
- rlmode = -1
- elseif dir == "TLT" then
- rlmode = 1
- else
- rlmode = 0
- end
- end
- start = start.next
- else
- start = start.next
- end
- end
- end
- return head, done
- else
- return head, false
- end
- end
-
- -- we can assume that languages that use marks are not hyphenated
- -- we can also assume that at most one discretionary is present
-
- local copy_list, slide, free = node.copy_list, node.slide, node.free
-
- local function toligature(start,stop,char,markflag,discfound) -- brr head
- if start ~= stop then
- if discfound then
- local lignode = node.copy(start)
- lignode.font = start.font
- lignode.char = char
- lignode.subtype = 2
- start = node.do_ligature_n(start, stop, lignode)
- if start.id == disc then
- local prev = start.prev
- start = start.next
- end
- else -- start is the ligature
- -- to be checked: this marknum mess (sensitive for looping)
- local deletemarks = markflag ~= "mark"
---~ deletemarks = false
- start.components = copy_list(start,stop)
- local last = slide(start.components)
- start.components.prev, last.next = nil, nil
- start.char, start.subtype = char, 2
- local next, done, marknum = start.next, false, 1
- local after = stop.next
- while not done do
- done = next == stop
- if not deletemarks and marks[next.char] then
- set_attribute(next,marknumber,marknum)
- next = next.next
- --~ marknum = marknum + 1
- else
- marknum = marknum + 1
- start, next = nodes.remove(start,next,true)
- end
- end
- while after and after.id == glyph and after.font == currentfont and marks[after.char] do
- if deletemarks then
- start, after = nodes.remove(start,after,true)
- else
- set_attribute(after,marknumber,marknum)
- after = after.next
- --~ marknum = marknum + 1
- end
- end
-
- end
- end
- return start
- end
-
- function otf.features.process.gsub_single(start,kind,lookupname,replacements)
- if replacements then
- if otf.trace_replacements then
- report("otf process","%s:%s replacing 0x%04X by 0x%04X",kind,lookupname,start.char,replacements)
- end
- start.char = replacements
- return start, true
- else
- return start, false
- end
- end
-
- function otf.features.process.gsub_alternate(start,kind,lookupname,alternatives)
- if alternatives then
- if otf.trace_replacements then
- report("otf process","%s:%s alternative 0x%04X => %s",kind,lookupname,start.char,table.hexed(alternatives))
- end
- start.char = alternatives[1] -- will be preference
- return start, true
- else
- return start, false
- end
- end
-
- function otf.features.process.gsub_multiple(start,kind,lookupname,multiples)
- if multiples then
- if otf.trace_replacements then
- report("otf process","%s:%s multiple 0x%04X => %s",kind,lookupname,start.char,table.hexed(multiples))
- end
- start.char = multiples[1]
- if #multiples > 1 then
- for k=2,#multiples do
- local n = node.copy(start)
- local sn = start.next
- n.char = multiples[k]
- n.next = sn
- n.prev = start
- if sn then
- sn.prev = n
- end
- start.next = n
- start = n
- end
- end
- return start, true
- else
- return start, false
- end
- end
-
- function otf.features.process.gsub_ligature(start,kind,lookupname,ligatures,alldata,flags)
- local s, stop, discfound = start.next, nil, false
- while s do
- local id = s.id
- if id == glyph and s.subtype<256 then
- if s.font == currentfont then
- local char = s.char
- if marks[char] then
- s = s.next
- else
- -- we use indices, which saves a lookup, but we can use
- -- names when we comment the line after (*lig*)
- -- local lg = ligatures[1][glyphs[indices[char]].name]
- local lg = ligatures[1][indices[char]]
- -- mayb esome day we introduce a more efficient method
- if not lg then
- break
- else
- stop = s
- ligatures = lg
- s = s.next
- end
- end
- else
- break
- end
- elseif id == disc then
- discfound = true
- s = s.next
- else
- break
- end
- end
- if stop and ligatures[2] then
- start = toligature(start,stop,ligatures[2],flags[1],discfound)
- if otf.trace_ligatures then
- report("otf process","%s: inserting ligature 0x%04X (%s)",kind,start.char,utf.char(start.char))
- end
- return start, true
- end
- return start, false
- end
-
- function otf.features.process.gpos_mark2base(start,kind,lookupname,m_anchors,b_anchors)
- local markchar = start.char
- if marks[markchar] then
- local markanchors = m_anchors['mark']
- if markanchors then
- local component = start.prev
- while component and component.id == glyph and component.subtype<256 and component.font == currentfont do
- local basechar = component.char
- if marks[basechar] then
- component = component.prev
- else
- local baseanchors = b_anchors[basechar]
- if baseanchors then
- baseanchors = baseanchors['basechar']
- if baseanchors then
- for anchor, ma in pairs(markanchors) do
- local ba = baseanchors[anchor]
- if ba then
- local factor = tfmdata.factor
- local dx, dy = scale(ba[1]-ma[1],factor), scale(ba[2]-ma[2],factor)
- start.xoffset, start.yoffset = component.xoffset - dx, component.yoffset + dy
- if otf.trace_anchors then
- report("otf process","%s: anchoring mark 0x%04X to basechar 0x%04X => (%s,%s) => (%s,%s)",
- kind,markchar,basechar,dx,dy,start.xoffset,start.yoffset)
- end
- return start, true
- end
- end
- end
- end
- break
- end
- end
- end
- end
- return start, false
- end
-
- function otf.features.process.gpos_mark2ligature(start,kind,lookupname,m_anchors,b_anchors) -- maybe use copies
- local markchar = start.char
- if marks[markchar] then
- local markanchors = m_anchors['mark']
- if markanchors then
- local component = start.prev
- while component and component.id == glyph and component.subtype<256 and component.font == currentfont do
- local basechar = component.char
- if marks[basechar] then
- component = component.prev
- else
- local baseanchors = b_anchors[basechar]
- if baseanchors then
- baseanchors = baseanchors['baselig']
- if baseanchors then
- for anchor, ma in pairs(markanchors) do
- local ba = baseanchors[anchor]
- if ba then
- local n = has_attribute(start,marknumber)
- ba = ba[n]
- if ba then
- local factor = tfmdata.factor
- local dx, dy = scale(ba[1]-ma[1],factor), scale(ba[2]-ma[2],factor)
- start.xoffset, start.yoffset = component.xoffset - dx, component.yoffset + dy
- if otf.trace_anchors then
- report("otf process","%s: anchoring mark 0x%04X to baseligature 0x%04X => (%s,%s) => (%s,%s)",
- kind,markchar,basechar,dx,dy,component.xoffset,component.yoffset)
- end
- return start, true
- end
- end
- end
- end
- end
- break
- end
- end
- return start, done
- end
- end
- return start, false
- end
-
- -- hm which one is the correct one? chainprocs.gpos_mark2mark ot the next; the next one
- -- had more tracing so might be the best
-
- function otf.features.process.gpos_mark2mark(start,kind,lookupname,b_anchors,m_anchors)
- local basemarkchar = start.char
- if marks[basemarkchar] then
- local baseanchors = b_anchors['basemark']
- if baseanchors then
- local component = start.next
- while component and component.id == glyph and component.subtype<256 and component.font == currentfont do
- local markchar = component.char
- if not marks[markchar] then
- break
- else
- local basemarkattr = has_attribute(start,marknumber) or 1
- local markattr = has_attribute(component,marknumber) or 1
- if basemarkattr == markattr then -- still needed?
- local markanchors = m_anchors[markchar]
- if markanchors then
- local markanchor = markanchors['mark']
- if markanchor then
- for anchor,ma in pairs(markanchor) do
- local ba = baseanchors[anchor]
- if ba then
- local factor = tfmdata.factor
- local dx, dy = scale(ba[1]-ma[1],factor), scale(ba[2]-ma[2],factor)
- component.xoffset, component.yoffset = start.xoffset - dx, start.yoffset + dy
- if otf.trace_anchors then
- report("otf process","%s:%s:%s anchoring mark 0x%04X to basemark 0x%04X => (%s,%s) => (%s,%s)",
- kind,anchor,markattr,markchar,basemarkchar,dx,dy,component.xoffset,component.yoffset)
- end
- return start, true
- end
- end
- end
- end
- -- weird, was here
- end
- component = component.next
- end
- end
- end
- end
- return start, false
- end
-
- function otf.features.process.gpos_cursive(start,kind,lookupname,exitanchors,anchors)
- local trace = otf.trace_cursive
- if rlmode >= 0 then
- local prev, done = start.prev, false
- while prev do
- if prev.id == glyph and prev.subtype<256 and prev.font == currentfont then
- local prevchar = prev.char
- if marks[prevchar] then
- -- what do do with marks, give them the offset of the previous glyph?
- prev = prev.prev
- else
- local startchar = start.char
- local entryanchors, exitanchors = anchors[startchar], anchors[prevchar]
- if entryanchors and exitanchors then
- local centry, cexit = entryanchors['centry'], exitanchors['cexit']
- if centry and cexit then
- for anchor, entry in pairs(centry) do
- local exit = cexit[anchor]
- if exit then
- local factor = tfmdata.factor
- local dx = -(descriptions[prevchar].width-exit[1]) - entry[1]
- local dy = -(entry[2]-exit[2])
- start.yoffset = prev.yoffset + scale(dy, factor)
- -- start.xoffset = scale(tx[i], factor)
- node.insert_before(prev,start,nodes.kern(scale(dx,factor)))
- if trace then
- report("otf process","%s:%s move 0x%04X cursive (%s,%s)",kind,lookupname,startchar,dx,dy)
- end
- done = true
- end
- end
- end
- end
- break
- end
- else
- break
- end
- end
- else
- local trace, factor = fonts.otf.trace_anchors, tfmdata.factor
- local next, done, total_x, total_y, tx, ty, stack = start.next, false, 0, 0, { }, { }, { }
- local function finish()
- done = true
- for i=1,#stack do
- local s = stack[i]
- s.yoffset = scale(total_y, factor)
- node.insert_before(s.prev,s,nodes.kern(scale(tx[i],factor)))
- if fonts.otf.trace_cursive then
- report("otf process",format("%s:%s move 0x%04X cursive (%s,%s)",kind,lookupname,s.char,tx[i],total_y))
- end
- total_y = total_y - (ty[i] or 0)
- end
- total_x, total_y, tx, ty, stack = 0, 0, { }, { }, { }
- end
- while next do
- if next.id == glyph and next.subtype<256 and next.font == currentfont then
- local nextchar = next.char
- if marks[nextchar] then
- next = next.next
- else
- local entryanchors, exitanchors = anchors[nextchar], anchors[start.char]
- if entryanchors and exitanchors then
- local centry, cexit = entryanchors['centry'], exitanchors['cexit']
- if centry and cexit then
- for anchor, entry in pairs(centry) do
- local exit = cexit[anchor]
- if exit then
- local dy = -exit[2] + entry[2]
- local dx = -(descriptions[nextchar].width-entry[1]) - exit[1] -- often width == entry 1
- tx[#tx+1], ty[#ty+1] = dx, dy
- total_x, total_y = total_x + dx, total_y + dy
- stack[#stack+1] = start
- break
- end
- end
- else
- finish()
- end
- else
- finish()
- end
- start = next
- next = start.next
- end
- else
- finish()
- break
- end
- end
- return start, done
- end
- return start, done
- end
-
- function otf.features.process.gpos_single(start,kind,lookupname,basekerns,kerns)
- report("otf process","gpos_single not yet supported")
- return start, false
- end
-
- function otf.features.process.gpos_pair(start,kind,lookupname,basekerns,kerns)
- -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too
- -- todo: kerns in components of ligatures
- local next = start.next
- if not next then
- return start, false
- else
- local prev, done = start, false
- local trace = otf.trace_kerns
- local factor = tfmdata.factor
- while next and next.id == glyph and next.subtype<256 and next.font == currentfont do
- local cn = descriptions[next.char]
- if not cn or cn.class == 'mark' then
- prev = next
- next = next.next
- else
- local krn = basekerns[next.char]
- if not krn then
- -- skip
- elseif type(krn) == "table" then
- local a, b = krn[3], krn[7]
- if a and a ~= 0 then
- local k = nodes.kern(scale(a,factor))
- k.next = next
- k.prev = prev
- prev.next = k
- next.prev = k
- if trace then
- -- todo
- end
- end
- if b and b ~= 0 then
- report("otf process","we need to do something with the second kern xoff %s",b)
- end
- else
- -- todo, just start, next = node.insert_before(head,next,nodes.kern(scale(kern,factor)))
- if otf.trace_kerns then
- report("otf process","%s: inserting kern %s between 0x%04X and 0x%04X",kind,krn,prev.char,next.char)
- end
- local k = nodes.kern(scale(krn,factor))
- k.next = next
- k.prev = prev
- prev.next = k
- next.prev = k
- end
- break
- end
- end
- return start, done
- end
- end
-
--- -- -- temp here, needs to be tested first -- -- --
-
---~ function do_gpos_pair(start,kind,lookupname,basekerns,kerns)
---~ local trace = otf.trace_kerns
---~ local factor = tfmdata.factor
---~ local next, prev, middle = start.next, start, nil
---~ -- to be optimized, we can consider using basemode for fonts without lookups
---~ -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too
---~ -- todo: kerns in components of ligatures
---~ --
---~ -- find valid next
---~ while next do
---~ local id = next.id
---~ if id == glyph and next.subtype<256 and next.font == currentfont then
---~ local cn = characters[next.char]
---~ if not cn or cn.description.class == 'mark' then
---~ prev = next
---~ next = next.next
---~ else
---~ break
---~ end
---~ elseif id == disc then -- assume same font
---~ middle = next
---~ else
---~ return start, false
---~ end
---~ end
---~ local function inject(head, prevkern, nextkern)
---~ if head then
---~ -- kern between prevchar and head
---~ local tail = node.slide(head) -- tail
---~ if head.id == glyph then
---~ local c = head.char
---~ local pc = prevkern[c]
---~ if pc then
---~ local k = nodes.kern(scale(pc,factor))
---~ k.next = head
---~ head = k
---~ end
---~ end
---~ -- kern between prevchar and tail
---~ if tail.id == glyph then
---~ local c = tail.char
---~ local nc = nextkern[c]
---~ if nc then
---~ tail.next = nodes.kern(scale(nc,factor))
---~ end
---~ end
---~ -- kern between head .. tail
---~ local c = head
---~ while c do do_gpos_pair(c,kind,lookupname,basekerns,kerns) ; c = c.next end
---~ end
---~ return head
---~ end
---~ if middle then
---~ -- prev middle next - assumes same lookup
---~ local prevkern, nextkern = kerns[prev.char], kerns[next.char]
---~ local m = middle.pre ; if m then middle.pre = inject(m, prevkern, nextkern) end
---~ local m = middle.post ; if m then middle.post = inject(m, prevkern, nextkern) end
---~ local m = middle.replace ; if m then middle.replace = inject(m, prevkern, nextkern) end
---~ elseif next then
---~ local prevchar, nextchar = prev.char, next.char
---~ if prev.components then
---~ local prevkern, nextkern = kerns[prev.char], kerns[next.char]
---~ local p = prev.components ; if p then prev.components = inject(p, prevkern, nextkern) end
---~ end
---~ local krn = basekerns[nextchar]
---~ if not krn then
---~ return start, false
---~ elseif type(krn) == "table" then
---~ local a, b = krn[3], krn[7]
---~ if a and a ~= 0 then
---~ start, next = node.insert_before(start,next,nodes.kern(scale(a,factor)))
---~ if trace then
---~ report("otf process","%s: inserting kern %s between 0x%04X and 0x%04X",kind,a,prevchar,nextchar)
---~ end
---~ end
---~ if b and b ~= 0 then
---~ report("otf process","we need to do something with the second kern xoff %s",b)
---~ end
---~ return start, true -- could be next
---~ else
---~ if otf.trace_kerns then
---~ report("otf process","%s: inserting kern %s between 0x%04X and 0x%04X",kind,krn,prevchar,nextchar)
---~ end
---~ start, next = node.insert_before(start,next,nodes.kern(scale(krn,factor)))
---~ return start, true -- could be next
---~ end
---~ end
---~ return start, false
---~ end
-
---~ otf.features.process.gpos_pair = do_gpos_pair
-
--- -- -- temp here, needs to be tested -- -- --
-
-
- local chainprocs = { } -- we can probably optimize this because they're all internal lookups
-
- -- For the moment we save each looked up glyph in the sequence, which is ok because
- -- each lookup in the chain has its own sequence. This saves memory. Only ligatures
- -- are stored in the featurecache, because we don't want to loop over all characters
- -- in order to locate them.
-
- function chainprocs.gsub_single(start,stop,kind,lookupname,sequence,f,l,lookups)
- local trace = otf.trace_replacements
- local c, r = trace and { }, trace and { }
- local lookup, index, current = 1, f, start
- while current ~= nil do
- if current.id == glyph then -- test for more ?
- local char = current.char
- local cacheslot = sequence[index]
- local replacement = cacheslot[char]
- if replacement == true then
- if lookups then
- -- didn't we have the arrays available?
- local looks = glyphs[descriptions[char].index].lookups -- SLOW, USE OTFDATA
- if looks then
- local luatex = otfdata.luatex
- local glyphlookups = luatex.internals[lookups[lookup]].lookups
- local unicodes = luatex.unicodes
- for gl=1,#glyphlookups do
- local lv = looks[glyphlookups[gl]]
- if lv then
- local ulv = unicodes[lv[1][2]]
- if not ulv then
- replacement = char
- elseif type(ulv) == "number" then
- replacement = ulv
- else
- replacement = ulv[1]
- end
- cacheslot[char] = replacement
- break
- end
- end
- else
- replacement, cacheslot[char] = char, char
- end
- else
- replacement, cacheslot[char] = char, char
- end
- end
- if trace then
- c[#c+1], r[#r+1] = char, replacement
- end
- current.char = replacement
- if current == stop then
- break
- else
- current, lookup, index = current.next, lookup + 1, index + 1
- end
- elseif current == stop then
- break
- else
- current = current.next
- end
- end
- if trace then
- report("otf chain","%s: single replacement %s by %s",kind,table.hexed(c),table.hexed(r))
- end
- return start
- end
-
- function chainprocs.gsub_multiple(start,stop,kind,lookupname,sequence,f,l,lookups)
- local char = start.char
- local cacheslot = sequence[f] -- [1]
- local replacement = cacheslot[char]
- if replacement == true then
- if lookups then
- local looks = glyphs[descriptions[char].index].lookups
- if looks then
- local luatex = otfdata.luatex
- local lookups = luatex.internals[lookups[1]].lookups
- local unicodes = luatex.unicodes
- for l=1,#lookups do
- local lv = looks[lookups[l]]
- if lv then
- replacement = { }
- for c in lv[1][2]:gmatch("[^ ]+") do
- local uc = unicodes[c]
- if type(uc) == "number" then
- replacement[#replacement+1] = uc
- else
- replacement[#replacement+1] = uc[1]
- end
- end
- cacheslot[char] = replacement
- break
- end
- end
- else
- replacement = { char }
- cacheslot[char] = replacement
- end
- else
- replacement = { char }
- cacheslot[char] = replacement
- end
- end
- if otf.trace_replacements then
- report("otf chain","%s: replacing character 0x%04X by multiple 0x%04X",kind,char,table.hexed(replacement))
- end
- start.char = replacement[1]
- if #replacement > 1 then
- for k=2,#replacement do
- local n = node.copy(start)
- local sn = start.next
- n.char = replacement[k]
- n.next = sn
- n.prev = start
- if sn then
- sn.prev = n
- end
- start.next = n
- start = n
- end
- end
- return start
- end
-
- function chainprocs.gsub_alternate(start,stop,kind,lookupname,sequence,f,l,lookups)
- local char = start.char
- local cacheslot = sequence[f] -- [1]
- local replacement = cacheslot[char]
- if replacement == true then
- if lookups then
- local looks = glyphs[descriptions[char].index].lookups
- if looks then
- local luatex = otfdata.luatex
- local lookups = luatex.internals[lookups[1]].lookups
- local unicodes = luatex.unicodes
- for l=1,#lookups do
- local lv = looks[lookups[l]]
- if lv then
- replacement = { }
- for c in lv[1][2]:gmatch("[^ ]+") do
- local uc = unicodes[c]
- if type(uc) == "number" then
- replacement[#replacement+1] = uc
- else
- replacement[#replacement+1] = uc[1]
- end
- end
- cacheslot[char] = replacement
- break
- end
- end
- else
- replacement = { char }
- cacheslot[char] = replacement
- end
- else
- replacement = { char }
- cacheslot[char] = replacement
- end
- end
- if otf.trace_replacements then
- report("otf chain","%s: replacing character 0x%04X by alternate",kind,char)
- end
- start.char = replacement[1]
- return start
- end
-
- function chainprocs.gsub_ligature(start,stop,kind,lookupname,sequence,f,l,lookups,flags)
- if lookups then
- if start == stop then
- -- print("todo: optimize")
- end
- local featurecache = fontdata[currentfont].shared.featurecache
- local ligaturecache = featurecache[kind]
- if not ligaturecache then
- ligaturecache = otf.features.collect_ligatures(tfmdata,kind) -- double cached ?
- featurecache[kind] = ligaturecache
- end
- local lookups = otfdata.luatex.internals[lookups[1]].lookups
- local trace = otf.trace_ligatures
- for i=1,#lookups do
- local ligatures = ligaturecache[lookups[i]]
- if ligatures and ligatures[start.char] then
- ligatures = ligatures[start.char]
- local s, discfound = start.next, false
- while s do
- local id = s.id
- if id == disc then
- s = s.next
- discfound = true
- elseif descriptions[s.char].class == 'mark' then -- marks
- s = s.next
- else
- local lg = ligatures[1][s.char]
- if not lg then
- break
- else
- ligatures = lg
- if s == stop then
- break
- else
- s = s.next
- end
- end
- end
- end
- if ligatures[2] then
- if trace then
- if start == stop then
- report("otf chain","%s: replacing character 0x%04X by ligature 0x%04X",kind,start.char,ligatures[2])
- else
- report("otf chain","%s: replacing character 0x%04X upto 0x%04X by ligature 0x%04X",kind,start.char,stop.char,ligatures[2])
- end
- end
- return toligature(start,stop,ligatures[2],flags[1],discfound)
- end
- break
- end
- end
- end
- return stop
- end
-
- -- weird, mkmk can have a mark2base, in idris font
-
- function chainprocs.gpos_mark2base(start,stop,kind,lookupname,sequence,f,l,lookups,flags)
- -- dynamic resolver
- local markchar = start.char
- if marks[markchar] then
- local anchortag = sequence[f][markchar]
- if anchortag == true then
- local ok = false
- local classes = otfdata.anchor_classes
- local lookups = otfdata.luatex.internals[lookups[1]].lookups
- for k=1,#classes do
- local v = classes[k]
- if v.lookup == lookups[1] then -- let's gamble for uniqueness: and v.type == kind then
- anchortag = v.name
- sequence[f][markchar] = anchortag
- ok = true
- break
- end
- end
- if not ok and otf.trace_anchors then
- report("otf chain","%s: no matching mark2base anchor class for 0x%04X, lookup %s",kind,markchar,lookups[1])
- end
- end
- if anchortag ~= true then
- local component = start.prev
- while component and component.id == glyph and component.subtype<256 and component.font == currentfont do
- local basechar = component.char
- if marks[basechar] then
- component = component.prev
- else
- local bglyph = glyphs[descriptions[basechar].index] -- startchar
- local baseanchors = bglyph.anchors['basechar']
- if baseanchors then
- local ba = baseanchors[anchortag]
- if ba then
- local mglyph = glyphs[descriptions[markchar].index]
- local markanchors = mglyph.anchors['mark']
- if markanchors then
- local ma = markanchors[anchortag]
- if ma then
- local factor = tfmdata.factor
- local dx, dy = scale(ba[1]-ma[1],factor), scale(ba[2]-ma[2],factor)
- start.xoffset, start.yoffset = component.xoffset - dx, component.yoffset + dy
- if otf.trace_anchors then
- report("otf chain","%s: anchoring mark 0x%04X to basechar 0x%04X => (%s,%s) => (%s,%s)",
- kind,markchar,basechar,dx,dy,start.xoffset,start.yoffset)
- end
- return start, true
- end
- end
- end
- end
- break
- end
- end
- end
- end
- return start, false
- end
-
- function chainprocs.gpos_mark2ligature(start,stop,kind,lookupname,sequence,f,l,lookups,flags)
- -- dynamic resolver
- local markchar = start.char
- if marks[markchar] then
- local anchortag = sequence[f][markchar]
- if anchortag == true then
- local classes = otfdata.anchor_classes
- local lookups = otfdata.luatex.internals[lookups[1]].lookups
- local ok = false
- for k=1,#classes do
- local v = classes[k]
- if v.lookup == lookups[1] then -- and v.type == kind then
- anchortag = v.name
- sequence[f][markchar] = anchortag
- ok = true
- break
- end
- end
- if not ok and otf.trace_anchors then
- report("otf chain","%s: no matching mark2ligature anchor class for 0x%04X, lookup %s",kind,markchar,lookups[1])
- end
- end
- if anchortag ~= true then
- local component = start.prev
- while component and component.id == glyph and component.subtype<256 and component.font == currentfont do
- local basechar = component.char
- if marks[basechar] then
- component = component.prev
- else
- local bglyph = glyphs[descriptions[basechar].index] -- startchar
- local baseanchors = bglyph.anchors['baselig']
- if baseanchors then
- local ba = baseanchors[anchortag]
- if ba then
- local n = has_attribute(start,marknumber)
- ba = ba[n] -- ok ?
- if ba then
- local mglyph = glyphs[descriptions[markchar].index]
- local markanchors = mglyph.anchors['mark']
- if markanchors then
- local ma = markanchors[anchortag]
- if ma then
- local factor = tfmdata.factor
- local dx, dy = scale(ba[1]-ma[1],factor), scale(ba[2]-ma[2],factor)
- start.xoffset, start.yoffset = component.xoffset - dx, component.yoffset + dy
- if otf.trace_anchors then
- report("otf chain","%s: anchoring mark 0x%04X to baseligature 0x%04X => (%s,%s) => (%s,%s)",
- kind,basechar,markchar,dx,dy,start.xoffset,start.yoffset)
- end
- return start, true
- end
- end
- end
- end
- end
- break
- end
- end
- end
- end
- return start, false
- end
-
- -- to be checked (see previous generic mark2mark)
-
- function chainprocs.gpos_mark2mark(start,stop,kind,lookupname,sequence,f,l,lookups)
- local component = start.next
- if component and component.id == glyph and component.subtype<256 and component.font == currentfont and marks[component.char] then
- local markchar = start.char
- local anchortag = sequence[f][markchar] -- [1][char]
- if anchortag == true then
- local classes = otfdata.anchor_classes
- local ok = false
- for k=1,#classes do
- local v = classes[k]
- if v.lookup == lookupname then -- and v.type == kind then
- anchortag = v.name
- sequence[f][markchar] = anchortag
- ok = true
- break
- end
- end
- if not ok and otf.trace_anchors then
- report("otf chain","%s: no matching mark2mark anchor class for 0x%04X, lookup %s",kind,markchar,lookups[1])
- end
- end
- if anchortag ~= true then
- -- the following may have been be spoiled while idrising the other ones
- local markattr = has_attribute(start, marknumber) or 1 -- i need to check this ! 1 is new !
- local baseattr = has_attribute(component,marknumber) or 1 -- i need to check this ! 1 is new !
- if baseattr == markattr then
- local glyph = glyphs[descriptions[markchar].index]
- if glyph.anchors and glyph.anchors[anchortag] then
- local trace = otf.trace_anchors
- local done = false
- local baseanchors = glyph.anchors['basemark'][anchortag]
- while component do
- local basechar = component.char
- local markanchors = glyphs[descriptions[basechar].index].anchors['mark'][anchortag]
- if markanchors then
- for anchor,data in pairs(markanchors) do
- local ba = baseanchors[anchor]
- if ba then
- local factor = tfmdata.factor
- local dx, dy = scale(ba[1]-ma[1],factor), scale(ba[2]-ma[2],factor)
- start.xoffset, start.yoffset = component.xoffset - dx, component.yoffset + dy
- if otf.trace_anchors then
- report("otf chain","%s: anchoring mark 0x%04X to basemark 0x%04X => (%s,%s) => (%s,%s)",
- kind,markchar,basechar,dx,dy,component.xoffset,component.yoffset)
- end
- done = true
- break
- end
- end
- end
- component = component.next
- if component and component.id == glyph and component.subtype<256 and component.font == currentfont and marks[component.char] then
- markattr = has_attribute(component,marknumber)
- if baseattr ~= markattr then
- break
- end
- else
- break
- end
- end
- return start, done
- end
- end
- end
- end
- return start, false
- end
-
- function chainprocs.gpos_cursive(start,stop,kind,lookupname,sequence,f,l,lookups)
- report("otf chain","chainproc gpos_cursive not yet supported")
- return start
- end
- function chainprocs.gpos_single(start,stop,kind,lookupname,sequence,f,l,lookups)
- report("otf process","chainproc gpos_single not yet supported")
- return start
- end
- function chainprocs.gpos_pair(start,stop,kind,lookupname,sequence,f,l,lookups)
- report("otf process","chainproc gpos_pair not yet supported")
- return start
- end
-
- function chainprocs.self(start,stop,kind,lookupname,sequence,f,l,lookups)
- report("otf process","self refering lookup cannot happen")
- return stop
- end
-
- local zwnj = 0x200C
- local zwj = 0x200D
-
- -- what pointer to return, spec says stop
-
- -- to be discussed ... is bidi changer a space?
-
- function otf.features.process.contextchain(start,kind,lookupname,contextdata)
- local contexts, flags, done = contextdata.lookups, contextdata.flags, false
- local skipmark, skipligature, skipbase = unpack(flags) -- unpack slower than assignment
- for k=1,#contexts do
- local match, next, last = true, start, start
- local rule, lookuptype, sequence, f, l, lookups = unpack(contexts[k]) -- unpack is slow
- local s = #sequence
- if s == 1 then
- match = next.id == glyph and next.subtype<256 and next.font == currentfont and sequence[1][next.char]
- else
- -- todo: better space check (maybe check for glue)
- local n = f
- while n <= l do
- if last then
- local id = last.id
- if id == glyph and last.subtype<256 and last.font == currentfont then
- local char = last.char
- local cc = characters[char]
- if cc then
- local ccd = descriptions[char]
- if ccd then
- local class = ccd.class
- if class == skipmark or class == skipligature or class == skipbase then
- -- skip 'm
- last = last.next
- elseif sequence[n][char] then
- if n < l then
- last = last.next
- end
- n = n + 1
- else
- match = false break
- end
- else
- match = false break
- end
- else -- play safe
- match = false break
- end
- elseif id == disc then -- what to do with kerns?
- last = last.next
- else
- match = false break
- end
- else
- match = false break
- end
- end
- if match and f > 1 then
- local prev = start.prev
- if prev then
- -- removed optimiziation for f == 2, we have to deal with marks anyway
- local n = f-1
- while n >= 1 do
- if prev then
- local id = prev.id
- if id == glyph and prev.subtype<256 and prev.font == currentfont then -- normal char
- local char = prev.char
- local cc = characters[char]
- if cc then
- local ccd = descriptions[char]
- if ccd then
- local class = ccd.class
- if class == skipmark or class == skipligature or class == skipbase then
- -- skip 'm
- elseif sequence[n][char] then
- n = n -1
- else
- match = false break
- end
- else
- match = false break
- end
- else
- match = false break
- end
- elseif id == disc then
- -- skip 'm
- elseif sequence[n][32] then
- n = n -1
- else
- match = false break
- end
- prev = prev.prev
- elseif sequence[n][32] then
- n = n -1
- else
- match = false break
- end
- end
- elseif f == 2 then
- match = sequence[1][32]
- else
- for n=f-1,1 do
- if not sequence[n][32] then
- match = false break
- end
- end
- end
- end
- if match and s > l then
- local next = last.next
- if next then
- -- removed optimiziation for s-l == 1, we have to deal with marks anyway
- local n = l+ 1
- while n <= s do
- if next then
- local id = next.id
- if id == glyph and next.subtype<256 and next.font == currentfont then -- normal char
- local char = next.char
- local cc = characters[char]
- if cc then
- local ccd = descriptions[char]
- if ccd then
- local class = ccd.class
- if class == skipmark or class == skipligature or class == skipbase then
- -- skip 'm
- elseif sequence[n][char] then
- n = n + 1
- else
- match = false break
- end
- else
- match = false break
- end
- else
- match = false break
- end
- elseif id == disc then
- -- skip 'm
- elseif sequence[n][32] then -- brrr
- n = n + 1
- else
- match = false break
- end
- next = next.next
- elseif sequence[n][32] then
- n = n + 1
- else
- match = false break
- end
- end
- elseif s-l == 1 then
- match = sequence[s][32]
- else
- for n=l+1,s do
- if not sequence[n][32] then
- match = false break
- end
- end
- end
- end
- end
- if match then
- local trace = otf.trace_contexts
- if trace then
- local char = start.char
- report("otf chain","%s: rule %s of %s matches at char 0x%04X (%s) for (%s,%s,%s) chars, lookuptype %s",kind,rule,lookupname,char,utf.char(char),f-1,l-f+1,s-l,lookuptype)
- end
- if lookups then
- local cp = chainprocs[lookuptype]
- if cp then
- start = cp(start,last,kind,lookupname,sequence,f,l,lookups,flags)
- else
- report("otf chain","%s: lookuptype %s not supported yet for %s",kind,lookuptype,lookupname)
- end
- elseif trace then
- report("otf chain","%s: skipping match for %s",kind,lookupname)
- end
- done = true
- break
- end
- end
- return start, done
- end
-
---~ if true then
---~ if n < f then
---~ texio.write_nl(format("%s before %s %04x %s %s %s",lookupname,n,char,class,skipmark or "?",tostring(sequence[n][char])))
---~ elseif n > l then
---~ texio.write_nl(format("%s after %s %04x %s %s %s",lookupname,n,char,class,skipmark or "?",tostring(sequence[n][char])))
---~ else
---~ texio.write_nl(format("%s current %s %04x %s %s %s",lookupname,n,char,class,skipmark or "?",tostring(sequence[n][char])))
---~ end
---~ end
-
---~ elseif char == zwnj and sequence[n][32] then -- brrr
-
- -- this needs to be fixed ! ! ! ! ! ! ! !
-
- function otf.features.process.reversecontextchain(start,kind,lookupname,contextdata)
- -- PROBABLY WRONG, WE NEED TO WALK BACK OVER THE LIST
- local done = false
- local contexts = contextdata.lookups
- local flags = contextdata.flags
- local skipmark, skipligature, skipbase = unpack(flags)
- for k=1,#contexts do
- local match, next, first, last = true, start, start, start
- local rule, lookuptype, sequence, f, l, lookups = unpack(contexts[k]) -- unpack is slow
- if #sequence == 1 then
- match = next.id == glyph and next.subtype<256 and next.font == currentfont and sequence[1][next.char]
- else
- local n, s = #sequence, 1
- while n > 0 do
- if next then
- local id = next.id
- if id == glyph and next.subtype<256 and next.font == currentfont then -- normal char
- local char = next.char
- local class = descriptions[char].class
- if class == skipmark or class == skipligature or class == skipbase then
- -- skip
- elseif sequence[n][char] then
- if n == f then
- first = next -- ok ?
- end
- if n == l then
- last = next -- ok ?
- end
- n = n - 1
- else
- match = false break
- end
- elseif id == disc then
- -- skip
- elseif not sequence[n][32] then -- brrr
- match = false break
- end
- next = next.next
- elseif sequence[n][32] then
- n = n - 1
- else
- match = false break
- end
- end
- end
- if match then
- local trace = otf.trace_contexts
- if trace then
- local char = first.char
- report("otf reverse chain","%s: rule %s of %s matches, replacing starts at char 0x%04X (%s) lookuptype %s",kind,rule,lookupname,char,utf.char(char),lookuptype)
- end
- if lookups then
- local cp = chainprocs[lookuptype]
- if cp then
- if start == first then
- start = cp(first,last,kind,lookupname,sequence,f,l,lookups,flags)
- else
- first = cp(first,last,kind,lookupname,sequence,f,l,lookups,flags)
- end
- else
- report("otf reverse chain","%s: lookuptype %s not supported yet for %s",kind,lookuptype,lookupname)
- end
- elseif trace then
- report("otf reverse chain","%s: skipping match for %s",kind,lookupname)
- end
- done = true
- break
- end
- end
- return start, done
- end
-
- otf.features.process.gsub_context = otf.features.process.contextchain
- otf.features.process.gsub_contextchain = otf.features.process.contextchain
- otf.features.process.gsub_reversecontextchain = otf.features.process.reversecontextchain
-
- otf.features.process.gpos_contextchain = otf.features.process.contextchain
- otf.features.process.gpos_context = otf.features.process.contextchain
-
-end
-
-do
-
- local process = otf.features.process.feature
-
- function fonts.methods.node.otf.aalt(head,font,attr) return process(head,font,attr,'aalt') end
- function fonts.methods.node.otf.abvm(head,font,attr) return process(head,font,attr,'abvm') end
- function fonts.methods.node.otf.afrc(head,font,attr) return process(head,font,attr,'afrc') end
- function fonts.methods.node.otf.akhn(head,font,attr) return process(head,font,attr,'akhn') end
- function fonts.methods.node.otf.blwm(head,font,attr) return process(head,font,attr,'blwm') end
- function fonts.methods.node.otf.c2pc(head,font,attr) return process(head,font,attr,'c2pc') end
- function fonts.methods.node.otf.c2sc(head,font,attr) return process(head,font,attr,'c2sc') end
- function fonts.methods.node.otf.calt(head,font,attr) return process(head,font,attr,'calt') end
- function fonts.methods.node.otf.case(head,font,attr) return process(head,font,attr,'case') end
- function fonts.methods.node.otf.ccmp(head,font,attr) return process(head,font,attr,'ccmp') end
- function fonts.methods.node.otf.clig(head,font,attr) return process(head,font,attr,'clig') end
- function fonts.methods.node.otf.cpsp(head,font,attr) return process(head,font,attr,'cpsp') end
- function fonts.methods.node.otf.cswh(head,font,attr) return process(head,font,attr,'cswh') end
- function fonts.methods.node.otf.curs(head,font,attr) return process(head,font,attr,'curs') end
- function fonts.methods.node.otf.dlig(head,font,attr) return process(head,font,attr,'dlig') end
- function fonts.methods.node.otf.dnom(head,font,attr) return process(head,font,attr,'dnom') end
- function fonts.methods.node.otf.expt(head,font,attr) return process(head,font,attr,'expt') end
- function fonts.methods.node.otf.fin2(head,font,attr) return process(head,font,attr,'fin2') end
- function fonts.methods.node.otf.fin3(head,font,attr) return process(head,font,attr,'fin3') end
- function fonts.methods.node.otf.fina(head,font,attr) return process(head,font,attr,'fina',3) end
- function fonts.methods.node.otf.frac(head,font,attr) return process(head,font,attr,'frac') end
- function fonts.methods.node.otf.fwid(head,font,attr) return process(head,font,attr,'fwid') end
- function fonts.methods.node.otf.haln(head,font,attr) return process(head,font,attr,'haln') end
- function fonts.methods.node.otf.hist(head,font,attr) return process(head,font,attr,'hist') end
- function fonts.methods.node.otf.hkna(head,font,attr) return process(head,font,attr,'hkna') end
- function fonts.methods.node.otf.hlig(head,font,attr) return process(head,font,attr,'hlig') end
- function fonts.methods.node.otf.hngl(head,font,attr) return process(head,font,attr,'hngl') end
- function fonts.methods.node.otf.hwid(head,font,attr) return process(head,font,attr,'hwid') end
- function fonts.methods.node.otf.init(head,font,attr) return process(head,font,attr,'init',1) end
- function fonts.methods.node.otf.isol(head,font,attr) return process(head,font,attr,'isol',4) end
- function fonts.methods.node.otf.ital(head,font,attr) return process(head,font,attr,'ital') end
- function fonts.methods.node.otf.jp78(head,font,attr) return process(head,font,attr,'jp78') end
- function fonts.methods.node.otf.jp83(head,font,attr) return process(head,font,attr,'jp83') end
- function fonts.methods.node.otf.jp90(head,font,attr) return process(head,font,attr,'jp90') end
- function fonts.methods.node.otf.kern(head,font,attr) return process(head,font,attr,'kern') end
- function fonts.methods.node.otf.liga(head,font,attr) return process(head,font,attr,'liga') end
- function fonts.methods.node.otf.lnum(head,font,attr) return process(head,font,attr,'lnum') end
- function fonts.methods.node.otf.locl(head,font,attr) return process(head,font,attr,'locl') end
- function fonts.methods.node.otf.mark(head,font,attr) return process(head,font,attr,'mark') end
- function fonts.methods.node.otf.med2(head,font,attr) return process(head,font,attr,'med2') end
- function fonts.methods.node.otf.medi(head,font,attr) return process(head,font,attr,'medi',2) end
- function fonts.methods.node.otf.mgrk(head,font,attr) return process(head,font,attr,'mgrk') end
- function fonts.methods.node.otf.mkmk(head,font,attr) return process(head,font,attr,'mkmk') end
- function fonts.methods.node.otf.nalt(head,font,attr) return process(head,font,attr,'nalt') end
- function fonts.methods.node.otf.nlck(head,font,attr) return process(head,font,attr,'nlck') end
- function fonts.methods.node.otf.nukt(head,font,attr) return process(head,font,attr,'nukt') end
- function fonts.methods.node.otf.numr(head,font,attr) return process(head,font,attr,'numr') end
- function fonts.methods.node.otf.onum(head,font,attr) return process(head,font,attr,'onum') end
- function fonts.methods.node.otf.ordn(head,font,attr) return process(head,font,attr,'ordn') end
- function fonts.methods.node.otf.ornm(head,font,attr) return process(head,font,attr,'ornm') end
- function fonts.methods.node.otf.pnum(head,font,attr) return process(head,font,attr,'pnum') end
- function fonts.methods.node.otf.pref(head,font,attr) return process(head,font,attr,'pref') end
- function fonts.methods.node.otf.pres(head,font,attr) return process(head,font,attr,'pres') end
- function fonts.methods.node.otf.pstf(head,font,attr) return process(head,font,attr,'pstf') end
- function fonts.methods.node.otf.rlig(head,font,attr) return process(head,font,attr,'rlig') end
- function fonts.methods.node.otf.rphf(head,font,attr) return process(head,font,attr,'rphf') end
- function fonts.methods.node.otf.rtla(head,font,attr) return process(head,font,attr,'rtla') end
- function fonts.methods.node.otf.salt(head,font,attr) return process(head,font,attr,'calt') end
- function fonts.methods.node.otf.sinf(head,font,attr) return process(head,font,attr,'sinf') end
- function fonts.methods.node.otf.smcp(head,font,attr) return process(head,font,attr,'smcp') end
- function fonts.methods.node.otf.smpl(head,font,attr) return process(head,font,attr,'smpl') end
- function fonts.methods.node.otf.ss01(head,font,attr) return process(head,font,attr,'ss01') end
- function fonts.methods.node.otf.ss02(head,font,attr) return process(head,font,attr,'ss02') end
- function fonts.methods.node.otf.ss03(head,font,attr) return process(head,font,attr,'ss03') end
- function fonts.methods.node.otf.ss04(head,font,attr) return process(head,font,attr,'ss04') end
- function fonts.methods.node.otf.ss05(head,font,attr) return process(head,font,attr,'ss05') end
- function fonts.methods.node.otf.ss06(head,font,attr) return process(head,font,attr,'ss06') end
- function fonts.methods.node.otf.ss07(head,font,attr) return process(head,font,attr,'ss07') end
- function fonts.methods.node.otf.ss08(head,font,attr) return process(head,font,attr,'ss08') end
- function fonts.methods.node.otf.ss09(head,font,attr) return process(head,font,attr,'ss09') end
- function fonts.methods.node.otf.subs(head,font,attr) return process(head,font,attr,'subs') end
- function fonts.methods.node.otf.sups(head,font,attr) return process(head,font,attr,'sups') end
- function fonts.methods.node.otf.swsh(head,font,attr) return process(head,font,attr,'swsh') end
- function fonts.methods.node.otf.titl(head,font,attr) return process(head,font,attr,'titl') end
- function fonts.methods.node.otf.tnam(head,font,attr) return process(head,font,attr,'tnam') end
- function fonts.methods.node.otf.tnum(head,font,attr) return process(head,font,attr,'tnum') end
- function fonts.methods.node.otf.trad(head,font,attr) return process(head,font,attr,'trad') end
- function fonts.methods.node.otf.unic(head,font,attr) return process(head,font,attr,'unic') end
- function fonts.methods.node.otf.zero(head,font,attr) return process(head,font,attr,'zero') end
-
-end
-
--- common stuff
-
-function otf.features.language(tfmdata,value)
- if value then
- value = value:lower()
- if otf.tables.languages[value] then
- tfmdata.language = value
- end
- end
-end
-
-function otf.features.script(tfmdata,value)
- if value then
- value = value:lower()
- if otf.tables.scripts[value] then
- tfmdata.script = value
- end
- end
-end
-
-function otf.features.mode(tfmdata,value)
- if value then
- tfmdata.mode = value:lower()
- end
-end
-
-function otf.features.strategy(tfmdata,value)
- if value then
- tfmdata.strategy = tonumber(value) or otf.strategy
- end
-end
-
-fonts.initializers.base.otf.language = otf.features.language
-fonts.initializers.base.otf.script = otf.features.script
-fonts.initializers.base.otf.mode = otf.features.mode
-fonts.initializers.base.otf.method = otf.features.mode
-fonts.initializers.base.otf.strategy = otf.features.strategy -- not needed
-
-fonts.initializers.node.otf.language = otf.features.language
-fonts.initializers.node.otf.script = otf.features.script
-fonts.initializers.node.otf.mode = otf.features.mode
-fonts.initializers.node.otf.method = otf.features.mode
-fonts.initializers.node.otf.strategy = otf.features.strategy
-
-do
-
- local tlig_list = {
- endash = "hyphen hyphen",
- emdash = "hyphen hyphen hyphen",
- --~ quotedblleft = "quoteleft quoteleft",
- --~ quotedblright = "quoteright quoteright",
- --~ quotedblleft = "grave grave",
- --~ quotedblright = "quotesingle quotesingle",
- --~ quotedblbase = "comma comma",
- }
- local trep_list = {
- --~ [0x0022] = 0x201D,
- [0x0027] = 0x2019,
- --~ [0x0060] = 0x2018,
- }
-
- local tlig_feature = {
- features = { { scripts = { { script = "DFLT", langs = { "dflt" }, } }, tag = "tlig", comment = "added bij mkiv" }, },
- name = "ctx_tlig",
- subtables = { { name = "ctx_tlig_1" } },
- type = "gsub_ligature",
- flags = { },
- always = true
- }
- local trep_feature = {
- features = { { scripts = { { script = "DFLT", langs = { "dflt" }, } }, tag = "trep", comment = "added bij mkiv" }, },
- name = "ctx_trep",
- subtables = { { name = "ctx_trep_1" } },
- type = "gsub_single",
- flags = { },
- always = true
- }
-
- function otf.enhance.enrich(data,filename)
- local glyphs = data.glyphs
- local indices = data.map.map
- for unicode, index in pairs(indices) do
- local glyph = glyphs[index]
- local l = tlig_list[glyph.name]
- if l then
- local o = glyph.lookups or { }
- o["ctx_tlig_1"] = { { "ligature", l, glyph.name } }
- glyph.lookups = o
- end
- local r = trep_list[unicode]
- if r then
- local replacement = indices[r]
- if replacement then
- local o = glyph.lookups or { }
- o["ctx_trep_1"] = { { "substitution", glyphs[replacement].name } } ---
- glyph.lookups = o
- end
- end
- end
- data.gsub = data.gsub or { }
- logs.report("load otf","enhance: registering tlig feature")
- table.insert(data.gsub,1,table.fastcopy(tlig_feature))
- logs.report("load otf","enhance: registering trep feature")
- table.insert(data.gsub,1,table.fastcopy(trep_feature))
- end
-
- local prepare = otf.features.prepare.feature
- local process = otf.features.process.feature
-
- otf.tables.features['tlig'] = 'TeX Ligatures'
- otf.tables.features['trep'] = 'TeX Replacements'
-
- function fonts.initializers.node.otf.tlig(tfm,value) return prepare(tfm,'tlig',value) end
- function fonts.initializers.node.otf.trep(tfm,value) return prepare(tfm,'trep',value) end
-
- function fonts.methods.node.otf.tlig(head,font,attr) return process(head,font,attr,'tlig') end
- function fonts.methods.node.otf.trep(head,font,attr) return process(head,font,attr,'trep') end
-
- function fonts.initializers.base.otf.tlig(tfm,value) otf.features.prepare_base_substitutions(tfm,'tlig',value) end
- function fonts.initializers.base.otf.trep(tfm,value) otf.features.prepare_base_substitutions(tfm,'trep',value) end
-
-end
-
--- we need this because fonts can be bugged
-
--- \definefontfeature[calt][language=nld,script=latn,mode=node,calt=yes,clig=yes,rlig=yes]
--- \definefontfeature[dflt][language=nld,script=latn,mode=node,calt=no, clig=yes,rlig=yes]
--- \definefontfeature[fixd][language=nld,script=latn,mode=node,calt=no, clig=yes,rlig=yes,ignoredrules={44,45,47}]
-
--- \starttext
-
--- {\type{dflt:}\font\test=ZapfinoExtraLTPro*dflt at 24pt \test \char57777\char57812 c/o} \endgraf
--- {\type{calt:}\font\test=ZapfinoExtraLTPro*calt at 24pt \test \char57777\char57812 c/o} \endgraf
--- {\type{fixd:}\font\test=ZapfinoExtraLTPro*fixd at 24pt \test \char57777\char57812 c/o} \endgraf
-
--- \stoptext
-
---~ table.insert(fonts.triggers,"ignoredrules")
-
---~ function fonts.initializers.node.otf.ignoredrules(tfmdata,value)
---~ if value then
---~ -- these tests must move !
---~ tfmdata.unique = tfmdata.unique or { }
---~ tfmdata.unique.ignoredrules = tfmdata.unique.ignoredrules or { }
---~ local ignored = tfmdata.unique.ignoredrules
---~ -- value is already ok now
---~ for s in string.gmatch(value:gsub("[{}]","")..",", "%s*(.-),") do
---~ ignored[tonumber(s)] = true
---~ end
---~ end
---~ end
-
-fonts.initializers.base.otf.equaldigits = fonts.initializers.common.equaldigits
-fonts.initializers.node.otf.equaldigits = fonts.initializers.common.equaldigits
-
-fonts.initializers.base.otf.lineheight = fonts.initializers.common.lineheight
-fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight
-
-fonts.initializers.base.otf.compose = fonts.initializers.common.compose
-fonts.initializers.node.otf.compose = fonts.initializers.common.compose
-
--- temp hack, may change
-
-function fonts.initializers.base.otf.kern(tfmdata,value)
- otf.features.prepare_base_kerns(tfmdata,'kern',value)
-end
-
--- bonus function
-
-function otf.name_to_slot(name) -- todo: afm en tfm
- local tfmdata = tfm.id[font.current()]
- if tfmdata and tfmdata.shared then
- local otfdata = tfmdata.shared.otfdata
- if otfdata and otfdata.luatex then
- local unicode = otfdata.luatex.unicodes[name]
- if type(unicode) == "number" then
- return unicode
- else
- return unicode[1]
- end
- end
- end
- return nil
-end
-
-function otf.char(n) -- todo: afm en tfm
- if type(n) == "string" then
- n = otf.name_to_slot(n)
- end
- if n then
- tex.sprint(tex.ctxcatcodes,format("\\char%s ",n))
- end
-end
-
--- Here we plug in some analyzing code (will move to font-tfm).
-
-do
-
- local glyph = node.id('glyph')
- local glue = node.id('glue')
- local penalty = node.id('penalty')
-
- local fontdata = tfm.id
- local set_attribute = node.set_attribute
- local has_attribute = node.has_attribute
- local state = attributes.numbers['state'] or 100
-
- local fcs = fonts.color.set
- local fcr = fonts.color.reset
- local remove = node.remove
-
- -- in the future we will use language/script attributes instead of the
- -- font related value, but then we also need dynamic features which is
- -- somewhat slower; and .. we need a chain of them
-
- local type = type
-
- local initializers, methods = fonts.analyzers.initializers, fonts.analyzers.methods
-
- function fonts.initializers.node.otf.analyze(tfmdata,value,attr)
- if attr and attr > 0 then
- script, language = a_to_script[attr], a_to_language[attr]
- else
- script, language = tfmdata.script, tfmdata.language
- end
- local action = initializers[script]
- if action then
- if type(action) == "function" then
- return action(tfmdata,value)
- else
- local action = action[language]
- if action then
- return action(tfmdata,value)
- end
- end
- end
- return nil
- end
-
- function fonts.methods.node.otf.analyze(head,font,attr)
- local tfmdata = fontdata[font]
- local script, language
- if attr and attr > 0 then
- script, language = a_to_script[attr], a_to_language[attr]
- else
- script, language = tfmdata.script, tfmdata.language
- end
- local action = methods[script]
- if action then
- if type(action) == "function" then
- return action(head,font,attr)
- else
- action = action[language]
- if action then
- return action(head,font,attr)
- end
- end
- end
- return head, false
- end
-
- otf.features.register("analyze",true) -- we always analyze
- table.insert(fonts.triggers,"analyze") -- we need a proper function for doing this
-
- -- latin
-
- fonts.analyzers.methods.latn = fonts.analyzers.aux.setstate
-
- -- this info eventually will go into char-def
-
- local zwnj = 0x200C
- local zwj = 0x200D
-
- local isol = {
- [0x0621] = true, [zwnj] = true,
- }
-
- local isol_fina = {
- [0x0622] = true, [0x0623] = true, [0x0624] = true, [0x0625] = true, [0x0627] = true, [0x062F] = true,
- [0x0630] = true, [0x0631] = true, [0x0632] = true,
- [0x0648] = true, [0x0698] = true,
- [0xFEF5] = true, [0xFEF7] = true, [0xFEF9] = true, [0xFEFB] = true,
- }
-
- local isol_fina_medi_init = {
- [0x0626] = true, [0x0628] = true, [0x0629] = true, [0x062A] = true, [0x062B] = true, [0x062C] = true, [0x062D] = true, [0x062E] = true,
- [0x0633] = true, [0x0634] = true, [0x0635] = true, [0x0636] = true, [0x0637] = true, [0x0638] = true, [0x0639] = true, [0x063A] = true,
- [0x0640] = true, -- tadwil
- [0x0641] = true, [0x0642] = true, [0x0643] = true, [0x0644] = true, [0x0645] = true, [0x0646] = true, [0x0647] = true, [0x0649] = true, [0x064A] = true,
- [0x067E] = true, [0x0686] = true, [0x06AF] = true, [0x06A9] = true, [0x06CC] = true,
- [zwj] = true,
- }
-
- local arab_warned = { }
-
- local function warning(current,what)
- local char = current.char
- if not arab_warned[char] then
- log.report("analyze","arab: character %s (0x%04X) has no %s class", char, char, what)
- arab_warned[char] = true
- end
- end
-
- function fonts.analyzers.methods.nocolor(head,font,attr)
- for n in node.traverse(head,glyph) do
- if not font or n.font == font then
- fcr(n)
- end
- end
- return head, true
- end
-
- otf.remove_joiners = true -- for idris who want it as option
-
- function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace
- local tfmdata = fontdata[font]
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local first, last, current, done = nil, nil, head, false
- local trace, removejoiners = fonts.color.trace, otf.remove_joiners
- --~ local laststate = 0
- local joiners = { }
- local function finish()
- if last then
- if first == last then
- local fc = first.char
- if isol_fina_medi_init[fc] or isol_fina[fc] then
- set_attribute(first,state,4) -- isol
- if trace then fcs(first,"font:isol") end
- else
- warning(first,"isol")
- set_attribute(first,state,0) -- error
- if trace then fcr(first) end
- end
- else
- local lc = last.char
- if isol_fina_medi_init[lc] or isol_fina[lc] then -- why isol here ?
- -- if laststate == 1 or laststate == 2 or laststate == 4 then
- set_attribute(last,state,3) -- fina
- if trace then fcs(last,"font:fina") end
- else
- warning(last,"fina")
- set_attribute(last,state,0) -- error
- if trace then fcr(last) end
- end
- end
- first, last = nil, nil
- elseif first then
- -- first and last are either both set so we never com here
- local fc = first.char
- if isol_fina_medi_init[fc] or isol_fina[fc] then
- set_attribute(first,state,4) -- isol
- if trace then fcs(first,"font:isol") end
- else
- warning(first,"isol")
- set_attribute(first,state,0) -- error
- if trace then fcr(first) end
- end
- first = nil
- end
- --~ laststate = 0
- end
- while current do
- if current.id == glyph and current.subtype<256 and current.font == font and not has_attribute(current,state) then
- done = true
- -- some day we will make a characters.marks hash
- -- this is also more efficient since it's shared
- local char = current.char
- local descriptions = descriptions[char]
- if removejoiners and char == zwj or char == zwnj then
- joiners[#joiners+1] = current
- end
- if descriptions and descriptions.class == "mark" then
- set_attribute(current,state,5) -- mark
- if trace then fcs(current,"font:mark") end
- elseif isol[char] then -- can be zwj or zwnj too
- finish()
- set_attribute(current,state,4) -- isol
- if trace then fcs(current,"font:isol") end
- first, last = nil, nil
- --~ laststate = 0
- elseif not first then
- if isol_fina_medi_init[char] then
- set_attribute(current,state,1) -- init
- if trace then fcs(current,"font:init") end
- first, last = first or current, current
- --~ laststate = 1
- elseif isol_fina[char] then
- set_attribute(current,state,4) -- isol
- if trace then fcs(current,"font:isol") end
- first, last = nil, nil
- --~ laststate = 0
- else -- no arab
- finish()
- end
- elseif isol_fina_medi_init[char] then
- first, last = first or current, current
- set_attribute(current,state,2) -- medi
- if trace then fcs(current,"font:medi") end
- --~ laststate = 2
- elseif isol_fina[char] then
- -- if not laststate == 1 then
- if not has_attribute(last,state,1) then
- -- tricky, we need to check what last may be !
- set_attribute(last,state,2) -- medi
- if trace then fcs(last,"font:medi") end
- end
- set_attribute(current,state,3) -- fina
- if trace then fcs(current,"font:fina") end
- first, last = nil, nil
- --~ laststate = 0
- elseif char >= 0x0600 and char <= 0x06FF then
- if trace then fcs(current,"font:rest") end
- finish()
- else --no
- finish()
- end
- else
- finish()
- end
- current = current.next
- end
- finish()
- if removejoiners then
- for i=1,#joiners do
- head = remove(head,joiners[i])
- end
- end
- return head, done
- end
-
- -- han (chinese) (unfinished)
-
- -- this info eventually will go into char-def
-
- -- in the future we will use language/script attributes instead of the
- -- font related value, but then we also need dynamic features which is
- -- somewhat slower; and .. we need a chain of them
-
- local type = type
-
- local opening_parenthesis_hw = table.tohash { -- half width
- 0x0028,
- 0x005B,
- 0x007B,
- 0x2018, -- ‘
- 0x201C, -- “
- }
-
- local opening_parenthesis_fw = table.tohash { -- full width
- 0x3008, -- 〈 Left book quote
- 0x300A, -- 《 Left double book quote
- 0x300C, -- 「 left quote
- 0x300E, -- 『 left double quote
- 0x3010, -- 【 left double book quote
- 0x3014, -- 〔 left book quote
- 0x3016, --〖 left double book quote
- 0x3018, -- left tortoise bracket
- 0x301A, -- left square bracket
- 0x301D, -- reverse double prime qm
- 0xFF08, -- ( left parenthesis
- 0xFF3B, -- [ left square brackets
- 0xFF5B, -- { left curve bracket
- 0xFF62, -- left corner bracket
- }
-
- local closing_parenthesis_hw = table.tohash { -- half width
- 0x0029,
- 0x005D,
- 0x007D,
- 0x2019, -- ’ right quote, right
- 0x201D, -- ” right double quote
- }
-
- local closing_parenthesis_fw = table.tohash { -- full width
- 0x3009, -- 〉 book quote
- 0x300B, -- 》 double book quote
- 0x300D, -- 」 right quote, right
- 0x300F, -- 』 right double quote
- 0x3011, -- 】 right double book quote
- 0x3015, -- 〕 right book quote
- 0x3017, -- 〗 right double book quote
- 0x3019, -- right tortoise bracket
- 0x301B, -- right square bracket
- 0x301E, -- double prime qm
- 0x301F, -- low double prime qm
- 0xFF09, -- ) right parenthesis
- 0xFF3D, -- ] right square brackets
- 0xFF5D, -- } right curve brackets
- 0xFF63, -- right corner bracket
- }
-
- local opening_vertical = table.tohash {
- 0xFE35, 0xFE37, 0xFE39, 0xFE3B, 0xFE3D, 0xFE3F, 0xFE41, 0xFE43, 0xFE47,
- }
-
- local closing_vertical = table.tohash {
- 0xFE36, 0xFE38, 0xFE3A, 0xFE3C, 0xFE3E, 0xFE40, 0xFE42, 0xFE44, 0xFE48,
- }
-
- local opening_punctuation_hw = table.tohash { -- half width
- }
-
- local opening_punctuation_fw = table.tohash {
- -- 0x2236, -- ∶
- -- 0xFF0C, -- ,
- }
-
- local closing_punctuation_hw = table.tohash { -- half width
- 0x0021, -- !
- 0x002C, -- ,
- 0x002E, -- .
- 0x003A, -- :
- 0x003B, -- ;
- 0x003F, -- ?
- 0xFF61, -- hw full stop
- }
-
- local closing_punctuation_fw = table.tohash { -- full width
- 0x3001, -- 、
- 0x3002, -- 。
- 0xFF01, -- !
- 0xFF0C, -- ,
- 0xFF0E, -- .
- 0xFF1A, -- :
- 0xFF1B, -- ;
- 0xFF1F, -- ?
- }
-
- local non_starter = table.tohash { -- japanese
- 0x3005, 0x3041, 0x3043, 0x3045, 0x3047,
- 0x3049, 0x3063, 0x3083, 0x3085, 0x3087,
- 0x308E, 0x3095, 0x3096, 0x309B, 0x309C,
- 0x309D, 0x309E, 0x30A0, 0x30A1, 0x30A3,
- 0x30A5, 0x30A7, 0x30A9, 0x30C3, 0x30E3,
- 0x30E5, 0x30E7, 0x30EE, 0x30F5, 0x30F6,
- 0x30FC, 0x30FD, 0x30FE, 0x31F0, 0x31F1,
- 0x30F2, 0x30F3, 0x30F4, 0x31F5, 0x31F6,
- 0x30F7, 0x30F8, 0x30F9, 0x31FA, 0x31FB,
- 0x30FC, 0x30FD, 0x30FE, 0x31FF,
- }
-
- -- the characters below are always appear in a double form, so there
- -- will be two Chinese ellipsis characters together that denote
- -- ellipsis marks and it is not allowed to break between them
-
- local hyphenation = table.tohash {
- 0x2026, -- … ellipsis
- 0x2014, -- — hyphen
- }
-
- local function is_han_character(char)
- -- we might add such info to char-def
- return
- (char>=0x03040 and char<=0x0309F) or
- (char>=0x030A0 and char<=0x030FF) or
- (char>=0x031F0 and char<=0x031FF) or
- (char>=0x03400 and char<=0x04DFF) or
- (char>=0x04E00 and char<=0x09FFF) or
- (char>=0x0F900 and char<=0x0FAFF) or
- (char>=0x0FF00 and char<=0x0FFEF) or
- (char>=0x20000 and char<=0x2A6DF) or
- (char>=0x2F800 and char<=0x2FA1F)
- end
- -- maybe an entry in the character table: hanclass
-
- --~ opening_parenthesis_hw / closing_parenthesis_hw
- --~ opening_parenthesis_fw / closing_parenthesis_fw
- --~ opening_punctuation_hw / closing_punctuation_hw
- --~ opening_punctuation_fw / closing_punctuation_fw
-
- --~ non_starter
- --~ hyphenation
-
- --~ opening_vertical / closing_vertical
-
- fonts.analyzers.methods.stretch_hang = true
-
- fonts.analyzers.methods.hang_data = {
- inter_char_stretch_factor = 2.00, -- we started with 0.5, then 1.0
- inter_char_half_factor = 0.50, -- normally there is no reason to change this
- inter_char_half_shrink_factor = 0.25, -- normally there is no reason to change this
- }
-
- local hang_data = fonts.analyzers.methods.hang_data
-
- local insert_after, insert_before, delete = node.insert_after, node.insert_before, nodes.delete
-
- local function nobreak_before(head,current)
- local p = current.prev
- if p then
- p = p.prev
- if p and p.id == penalty then
- p.penalty = 10000
- return head, current
- end
- end
- return insert_before(head,current,nodes.penalty(10000))
- end
-
- function fonts.analyzers.methods.hani(head,font,attr)
- -- maybe make a special version with no trace
- local tfmdata = fontdata[font]
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local current, done, stretch, prevclass = head, false, 0, 0
- if fonts.analyzers.methods.stretch_hang then
- stretch = fontdata[font].parameters.quad
- end
- -- penalty before break
- local interspecialskip = - stretch * hang_data.inter_char_half_factor
- local interspecialshrink = stretch * hang_data.inter_char_half_shrink_factor
- local internormalstretch = stretch * hang_data.inter_char_stretch_factor
- local trace = fonts.color.trace
- -- todo: check for first and last
- -- maybe it's better to look back
--- we need to backtrack a glyph (also other font)
- while current do
- if current.id == glyph and current.subtype<256 then
- if current.font == font then
- local char = current.char
- if false then
- -- don't ask -)
- elseif opening_punctuation_fw[char] or opening_parenthesis_fw[char] then
- if trace then fcs(current,"font:init") end
- if head ~= current then
- head, _ = insert_before(head,current,nodes.glue(interspecialskip,0,interspecialshrink))
- end
- head, current = insert_after(head,current,nodes.penalty(10000))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- prevclass, done = 1, true
- elseif closing_punctuation_fw[char] or closing_parenthesis_fw[char] then
- if trace then fcs(current,"font:fina") end
- if prevclass > 0 then
- head, current = nobreak_before(head,current)
- head, current = insert_after(head,current,nodes.penalty(10000))
- head, current = insert_after(head,current,nodes.glue(interspecialskip,0,interspecialshrink))
- head, current = insert_after(head,current,nodes.penalty(0))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- end
- prevclass, done = 2, true
- elseif opening_punctuation_hw[char] or opening_parenthesis_hw[char] then
- if trace then fcs(current,"font:init") end
- head, current = insert_after(head,current,nodes.penalty(10000))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- prevclass, done = 3, true
- elseif closing_punctuation_hw[char] or closing_parenthesis_hw[char] then
- if trace then fcs(current,"font:fina") end
- if prevclass > 0 then
- head, current = nobreak_before(head,current)
- head, current = insert_after(head,current,nodes.penalty(0))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- end
- prevclass, done = 4, true
- elseif hyphenation[char] then
- if trace then fcs(current,"font:medi") end
- if prevclass > 0 then
- head, current = nobreak_before(head,current)
- head, current = insert_after(head,current,nodes.penalty(0))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- end
- prevclass, done = 5, true
- elseif non_starter[char] then
- if trace then fcs(current,"font:isol") end
- head, current = insert_after(head,current,nodes.penalty(10000))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- prevclass, done = 6, true
- elseif is_han_character(char) then
- -- if trace then fcs(current,"font:isol") end
- prevclass, done = 7, true
- head, current = insert_after(head,current,nodes.penalty(0))
- head, current = insert_after(head,current,nodes.glue(0,internormalstretch,0))
- end
- else
--- here we might have a mixed font
- prevclass = 0
- end
- elseif prevclass > 0 and current.id == glue and current.spec and current.spec.width > 0 then
- -- hack, it might be better to look back and flush (we need to delete end-of-line spaces)
- local next = current.next
- if next.id == glyph and next.font == font then
- head, current = delete(head,current)
- end
- end
- if current then
- current = current.next
- end
- end
- return head, done
- end
-
- fonts.analyzers.methods.hang = fonts.analyzers.methods.hani
-
-end
-
--- experimental and will probably change
-
-do
- local process = otf.features.process.feature
- local prepare = otf.features.prepare.feature
- function fonts.install_feature(type,...)
- if fonts[type] and fonts[type].install_feature then
- fonts[type].install_feature(...)
- end
- end
- function otf.install_feature(tag)
- fonts.methods.node.otf [tag] = function(head,font,attr) return process(head,font,attr,tag) end
- fonts.initializers.node.otf[tag] = function(tfm,value) return prepare(tfm,tag,value) end
- end
-end
diff --git a/tex/context/base/font-oti.lua b/tex/context/base/font-oti.lua
new file mode 100644
index 000000000..cbac6d36a
--- /dev/null
+++ b/tex/context/base/font-oti.lua
@@ -0,0 +1,57 @@
+if not modules then modules = { } end modules ['font-oti'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- i need to check features=yes|no also in relation to hashing
+
+local lower = string.lower
+
+local otf = fonts.otf
+
+otf.default_language = 'latn'
+otf.default_script = 'dflt'
+
+local languages = otf.tables.languages
+local scripts = otf.tables.scripts
+
+function otf.features.language(tfmdata,value)
+ if value then
+ value = lower(value)
+ if languages[value] then
+ tfmdata.language = value
+ end
+ end
+end
+
+function otf.features.script(tfmdata,value)
+ if value then
+ value = lower(value)
+ if scripts[value] then
+ tfmdata.script = value
+ end
+ end
+end
+
+function otf.features.mode(tfmdata,value)
+ if value then
+ tfmdata.mode = lower(value)
+ end
+end
+
+fonts.initializers.base.otf.language = otf.features.language
+fonts.initializers.base.otf.script = otf.features.script
+fonts.initializers.base.otf.mode = otf.features.mode
+fonts.initializers.base.otf.method = otf.features.mode
+
+fonts.initializers.node.otf.language = otf.features.language
+fonts.initializers.node.otf.script = otf.features.script
+fonts.initializers.node.otf.mode = otf.features.mode
+fonts.initializers.node.otf.method = otf.features.mode
+
+otf.features.register("features",true) -- we always do features
+table.insert(fonts.processors,"features") -- we need a proper function for doing this
+
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
new file mode 100644
index 000000000..113f90470
--- /dev/null
+++ b/tex/context/base/font-otn.lua
@@ -0,0 +1,2496 @@
+if not modules then modules = { } end modules ['font-otn'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this is still somewhat preliminary and it will get better in due time;
+-- much functionality could only be implemented thanks to the husayni font
+-- of Idris Samawi Hamid to who we dedicate this module.
+
+-- we can use more lpegs when lpeg is extended with function args and so
+-- resolving to unicode does not gain much
+
+-- in retrospect it always looks easy but believe it or not, it took a lot
+-- of work to get proper open type support done: buggy fonts, fuzzy specs,
+-- special made testfonts, many skype sessions between taco, idris and me,
+-- torture tests etc etc ... unfortunately the code does not show how much
+-- time it took ...
+
+-- todo:
+--
+-- kerning is probably not yet ok for latin around dics nodes
+-- extension infrastructure (for usage out of context)
+-- sorting features according to vendors/renderers
+-- alternative loop quitters
+-- check cursive and r2l
+-- find out where ignore-mark-classes went
+-- remove unused tables
+-- slide tail (always glue at the end so only needed once
+-- default features (per language, script)
+-- cleanup kern(class) code, remove double info
+-- handle positions (we need example fonts)
+-- handle gpos_single (we might want an extra width field in glyph nodes because adding kerns might interfere)
+
+--[[ldx--
+<p>This module is a bit more split up that I'd like but since we also want to test
+with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/>
+and discussion about improvements and functionality mostly happens on the
+<l n='context'/> mailing list.</p>
+
+<p>The specification of OpenType is kind of vague. Apart from a lack of a proper
+free specifications there's also the problem that Microsoft and Adobe
+may have their own interpretation of how and in what order to apply features.
+In general the Microsoft website has more detailed specifications and is a
+better reference. There is also some information in the FontForge help files.</p>
+
+<p>Because there is so much possible, fonts might contain bugs and/or be made to
+work with certain rederers. These may evolve over time which may have the side
+effect that suddenly fonts behave differently.</p>
+
+<p>After a lot of experiments (mostly by Taco, me and Idris) we're now at yet another
+implementation. Of course all errors are mine and of course the code can be
+improved. There are quite some optimizations going on here and processing speed
+is currently acceptable. Not all functions are implemented yet, often because I
+lack the fonts for testing. Many scripts are not yet supported either, but I will
+look into them as soon as <l n='context'/> users ask for it.</p>
+
+<p>Because there are different interpretations possible, I will extend the code
+with more (configureable) variants. I can also add hooks for users so that they can
+write their own extensions.</p>
+
+<p>Glyphs are indexed not by unicode but in their own way. This is because there is no
+relationship with unicode at all, apart from the fact that a font might cover certain
+ranges of characters. One character can have multiple shapes. However, at the
+<l n='tex'/> end we use unicode so and all extra glyphs are mapped into a private
+space. This is needed because we need to access them and <l n='tex'/> has to include
+then in the output eventually.</p>
+
+<p>The raw table as it coms from <l n='fontforge'/> gets reorganized in to fit out needs.
+In <l n='context'/> that table is packed (similar tables are shared) and cached on disk
+so that successive runs can use the optimized table (after loading the table is
+unpacked). The flattening code used later is a prelude to an even more compact table
+format (and as such it keeps evolving).</p>
+
+<p>This module is sparsely documented because it is a moving target. The table format
+of the reader changes and we experiment a lot with different methods for supporting
+features.</p>
+
+<p>As with the <l n='afm'/> code, we may decide to store more information in the
+<l n='otf'/> table.</p>
+
+<p>Incrementing the version number will force a re-cache. We jump the number by one
+when there's a fix in the <l n='fontforge'/> library or <l n='lua'/> code that
+results in different tables.</p>
+--ldx]]--
+
+-- action handler chainproc chainmore comment
+--
+-- gsub_single ok ok ok
+-- gsub_multiple ok ok not implemented yet
+-- gsub_alternate ok ok not implemented yet
+-- gsub_ligature ok ok ok
+-- gsub_context ok --
+-- gsub_contextchain ok --
+-- gsub_reversecontextchain ok --
+-- chainsub -- ok
+-- reversesub -- ok
+-- gpos_mark2base ok ok
+-- gpos_mark2ligature ok ok
+-- gpos_mark2mark ok ok
+-- gpos_cursive ok untested
+-- gpos_single ok ok
+-- gpos_pair ok ok
+-- gpos_context ok --
+-- gpos_contextchain ok --
+--
+-- actions:
+--
+-- handler : actions triggered by lookup
+-- chainproc : actions triggered by contextual lookup
+-- chainmore : multiple substitutions triggered by contextual lookup (e.g. fij -> f + ij)
+--
+-- remark: the 'not implemented yet' variants will be done when we have fonts that use them
+-- remark: we need to check what to do with discretionaries
+
+local concat = table.concat
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local trace_lookups = false trackers.register("otf.lookups", function(v) trace_lookups = v end)
+local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end)
+local trace_multiples = false trackers.register("otf.multiples", function(v) trace_multiples = v end)
+local trace_alternatives = false trackers.register("otf.alternatives", function(v) trace_alternatives = v end)
+local trace_ligatures = false trackers.register("otf.ligatures", function(v) trace_ligatures = v end)
+local trace_contexts = false trackers.register("otf.contexts", function(v) trace_contexts = v end)
+local trace_marks = false trackers.register("otf.marks", function(v) trace_marks = v end)
+local trace_kerns = false trackers.register("otf.kerns", function(v) trace_kerns = v end)
+local trace_cursive = false trackers.register("otf.cursive", function(v) trace_cursive = v end)
+local trace_preparing = false trackers.register("otf.preparing", function(v) trace_preparing = v end)
+local trace_bugs = false trackers.register("otf.bugs", function(v) trace_bugs = v end)
+local trace_details = false trackers.register("otf.details", function(v) trace_details = v end)
+local trace_applied = false trackers.register("otf.applied", function(v) trace_applied = v end)
+local trace_steps = false trackers.register("otf.steps", function(v) trace_steps = v end)
+
+trackers.register("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end)
+trackers.register("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end)
+
+trackers.register("otf.replacements", "otf.singles,otf.multiples,otf.alternatives,otf.ligatures")
+trackers.register("otf.positions","otf.marks,otf.kerns,otf.cursive")
+trackers.register("otf.actions","otf.replacements,otf.positions")
+trackers.register("otf.injections","nodes.injections")
+
+trackers.register("*otf.sample","otf.steps,otf.actions,otf.analyzing")
+
+local insert_node_after = node.insert_after
+local delete_node = nodes.delete
+local copy_node = node.copy
+local slide_node_list = node.slide
+local set_attribute = node.set_attribute
+local has_attribute = node.has_attribute
+
+local zwnj = 0x200C
+local zwj = 0x200D
+local wildcard = "*"
+local default = "dflt"
+
+local split_at_space = lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local kern = node.id('kern')
+local disc = node.id('disc')
+local whatsit = node.id('whatsit')
+
+local state = attributes.private('state')
+local markbase = attributes.private('markbase')
+local markmark = attributes.private('markmark')
+local markdone = attributes.private('markdone')
+local cursbase = attributes.private('cursbase')
+local curscurs = attributes.private('curscurs')
+local cursdone = attributes.private('cursdone')
+local kernpair = attributes.private('kernpair')
+
+local set_mark = nodes.set_mark
+local set_cursive = nodes.set_cursive
+local set_kern = nodes.set_kern
+local set_pair = nodes.set_pair
+
+local markonce = true
+local cursonce = true
+local kernonce = true
+
+local fontdata = fonts.ids
+
+otf.features.process = { }
+
+-- we share some vars here, after all, we have no nested lookups and
+-- less code
+
+local tfmdata = false
+local otfdata = false
+local characters = false
+local descriptions = false
+local marks = false
+local indices = false
+local unicodes = false
+local currentfont = false
+local lookuptable = false
+local anchorlookups = false
+local handlers = { }
+local rlmode = 0
+local featurevalue = false
+
+-- we cheat a bit and assume that a font,attr combination are kind of ranged
+
+local context_setups = fonts.define.specify.context_setups
+local context_numbers = fonts.define.specify.context_numbers
+local context_merged = fonts.define.specify.context_merged
+
+-- we cannot optimize with "start = first_character(head)" because then we don't
+-- know which rlmode we're in which messes up cursive handling later on
+--
+-- head is always a whatsit so we can safely assume that head is not changed
+
+local special_attributes = {
+ init = 1,
+ medi = 2,
+ fina = 3,
+ isol = 4
+}
+
+-- we use this for special testing and documentation
+
+local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end
+local registerstep = (nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end
+local registermessage = (nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf direct",...)
+end
+local function logwarning(...)
+ logs.report("otf direct",...)
+end
+
+local function gref(n)
+ if type(n) == "number" then
+ local description = descriptions[n]
+ local name = description and description.name
+ if name then
+ return format("U+%04X (%s)",n,name)
+ else
+ return format("U+%04X",n)
+ end
+ elseif not n then
+ return "<error in tracing>"
+ else
+ local num, nam = { }, { }
+ for i=1,#n do
+ local ni = n[i]
+ num[#num+1] = format("U+%04X",ni)
+ local dni = descriptions[ni]
+ nam[#num] = (dni and dni.name) or "?"
+ end
+ return format("%s (%s)",concat(num," "), concat(nam," "))
+ end
+end
+
+local function cref(kind,chainname,chainlookupname,lookupname,index)
+ if index then
+ return format("feature %s, chain %s, sub %s, lookup %s, index %s",kind,chainname,chainlookupname,lookupname,index)
+ elseif lookupname then
+ return format("feature %s, chain %s, sub %s, lookup %s",kind,chainname or "?",chainlookupname or "?",lookupname)
+ elseif chainlookupname then
+ return format("feature %s, chain %s, sub %s",kind,chainname or "?",chainlookupname)
+ elseif chainname then
+ return format("feature %s, chain %s",kind,chainname)
+ else
+ return format("feature %s",kind)
+ end
+end
+
+local function pref(kind,lookupname)
+ return format("feature %s, lookup %s",kind,lookupname)
+end
+
+-- we can assume that languages that use marks are not hyphenated
+-- we can also assume that at most one discretionary is present
+
+local function markstoligature(kind,lookupname,start,stop,char)
+ local n = copy_node(start)
+ local keep = start
+ local current
+ current, start = insert_node_after(start,start,n)
+ local snext = stop.next
+ current.next = snext
+ if snext then
+ snext.prev = current
+ end
+ start.prev, stop.next = nil, nil
+ current.char, current.subtype, current.components = char, 2, start
+ return keep
+end
+
+local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- brr head
+ if start ~= stop then
+ if discfound then
+ local lignode = copy_node(start)
+ lignode.font = start.font
+ lignode.char = char
+ lignode.subtype = 2
+ start = node.do_ligature_n(start, stop, lignode)
+ if start.id == disc then
+ local prev = start.prev
+ start = start.next
+ end
+ else -- start is the ligature
+ local deletemarks = markflag ~= "mark"
+ local n = copy_node(start)
+ local current
+ current, start = insert_node_after(start,start,n)
+ local snext = stop.next
+ current.next = snext
+ if snext then
+ snext.prev = current
+ end
+ start.prev, stop.next = nil, nil
+ current.char, current.subtype, current.components = char, 2, start
+ local head = current
+ if deletemarks then
+ if trace_marks then
+ while start do
+ if marks[start.char] then
+ logwarning("%s: remove mark %s",pref(kind,lookupname),gref(start.char))
+ end
+ start = start.next
+ end
+ end
+ else
+ local i = 0
+ while start do
+ if marks[start.char] then
+ set_attribute(start,markdone,i)
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
+ end
+ head, current = insert_node_after(head,current,copy_node(start))
+ else
+ i = i + 1
+ end
+ start = start.next
+ end
+ start = current.next
+ while start and start.id == glyph do
+ if marks[start.char] then
+ set_attribute(start,markdone,i)
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
+ end
+ else
+ break
+ end
+ start = start.next
+ end
+ end
+ return head
+ end
+ else
+ start.char = char
+ end
+ return start
+end
+
+function handlers.gsub_single(start,kind,lookupname,replacement)
+ if trace_singles then
+ logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement))
+ end
+ start.char = replacement
+ return start, true
+end
+
+local function alternative_glyph(start,alternatives,kind,chainname,chainlookupname,lookupname) -- chainname and chainlookupname optional
+ local value, choice, n = featurevalue or tfmdata.shared.features[kind], nil, #alternatives -- global value, brrr
+ if value == "random" then
+ local r = math.random(1,n)
+ value, choice = format("random, choice %s",r), alternatives[r]
+ elseif value == "first" then
+ value, choice = format("first, choice %s",1), alternatives[1]
+ elseif value == "last" then
+ value, choice = format("last, choice %s",n), alternatives[n]
+ elseif type(value) ~= "number" then
+ value, choice = "default, choice 1", alternatives[1]
+ elseif value > n then
+ value, choice = format("no %s variants, taking %s",value,n), alternatives[n]
+ elseif value == 0 then
+ value, choice = format("choice %s (no change)",value), start.char
+ elseif value < 1 then
+ value, choice = format("no %s variants, taking %s",value,1), alternatives[1]
+ else
+ value, choice = format("choice %s",value), alternatives[value]
+ end
+ if not choice then
+ logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char))
+ choice, value = start.char, format("no replacement instead of %s",value)
+ end
+ return choice, value
+end
+
+function handlers.gsub_alternate(start,kind,lookupname,alternative,sequence)
+ local choice, index = alternative_glyph(start,alternative,kind,lookupname)
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(start.char),gref(choice),index)
+ end
+ start.char = choice
+ return start, true
+end
+
+function handlers.gsub_multiple(start,kind,lookupname,multiple)
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple))
+ end
+ start.char = multiple[1]
+ if #multiple > 1 then
+ for k=2,#multiple do
+ local n = copy_node(start)
+ n.char = multiple[k]
+ local sn = start.next
+ n.next = sn
+ n.prev = start
+ if sn then
+ sn.prev = n
+ end
+ start.next = n
+ start = n
+ end
+ end
+ return start, true
+end
+
+function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or maybe pass lookup ref
+ local s, stop, discfound = start.next, nil, false
+ if marks[start.char] then
+ while s do
+ local id = s.id
+ if id == glyph and s.subtype<256 then
+ if s.font == currentfont then
+ local char = s.char
+ local lg = ligature[1][char]
+ if not lg then
+ break
+ else
+ stop = s
+ ligature = lg
+ s = s.next
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if stop and ligature[2] then
+ if trace_ligatures then
+ local startchar, stopchar = start.char, stop.char
+ start = markstoligature(kind,lookupname,start,stop,ligature[2])
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = markstoligature(kind,lookupname,start,stop,ligature[2])
+ end
+ return start, true
+ end
+ else
+ local skipmark = sequence.flags[1]
+ while s do
+ local id = s.id
+ if id == glyph and s.subtype<256 then
+ if s.font == currentfont then
+ local char = s.char
+ if skipmark and marks[char] then
+ s = s.next
+ else
+ local lg = ligature[1][char]
+ if not lg then
+ break
+ else
+ stop = s
+ ligature = lg
+ s = s.next
+ end
+ end
+ else
+ break
+ end
+ elseif id == disc then
+ discfound = true
+ s = s.next
+ else
+ break
+ end
+ end
+ if stop and ligature[2] then
+ if trace_ligatures then
+ local startchar, stopchar = start.char, stop.char
+ start = toligature(kind,lookupname,start,stop,ligature[2],skipmark,discfound)
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = toligature(kind,lookupname,start,stop,ligature[2],skipmark,discfound)
+ end
+ return start, true
+ end
+ end
+ return start, false
+end
+
+--[[ldx--
+<p>We get hits on a mark, but we're not sure if the it has to be applied so
+we need to explicitly test for basechar, baselig and basemark entries.</p>
+--ldx]]--
+
+function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence)
+ local markchar = start.char
+ if marks[markchar] then
+ local base = start.prev -- [glyph] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+ end
+ end
+ end
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
+ end
+ if baseanchors then
+ local baseanchors = baseanchors['basechar']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)",
+ pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s, no matching anchors for mark %s and base %s",pref(kind,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ fonts.register_message(currentfont,basechar,"no base anchors")
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char",pref(kind,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
+ -- check chainpos variant
+ local markchar = start.char
+ if marks[markchar] then
+ local base = start.prev -- [glyph] [optional marks] [start=mark]
+ local index = 1
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ else
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+ end
+ end
+ end
+ local i = has_attribute(start,markdone)
+ if i then index = i end
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
+ if baseanchors then
+ local baseanchors = baseanchors['baselig']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ ba = ba[index]
+ if ba then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma,index)
+ if trace_marks then
+ logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)",
+ pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s",pref(kind,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ fonts.register_message(currentfont,basechar,"no base anchors")
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char",pref(kind,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence)
+ local markchar = start.char
+ if marks[markchar] then
+--~ local alreadydone = markonce and has_attribute(start,markmark)
+--~ if not alreadydone then
+ local base = start.prev -- [glyph] [basemark] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go
+ local basechar = base.char
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
+ if baseanchors then
+ baseanchors = baseanchors['basemark']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)",
+ pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start,true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and basemark %s",pref(kind,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ fonts.register_message(currentfont,basechar,"no base anchors")
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark",pref(kind,lookupname))
+ end
+--~ elseif trace_marks and trace_details then
+--~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone)
+--~ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
+ end
+ return start,false
+end
+
+function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to be checked
+ local alreadydone = cursonce and has_attribute(start,cursbase)
+ if not alreadydone then
+ local done = false
+ local startchar = start.char
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar))
+ end
+ else
+ local nxt = start.next
+ while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do
+ local nextchar = nxt.char
+ if marks[nextchar] then
+ -- should not happen (maybe warning)
+ nxt = nxt.next
+ else
+ local entryanchors = descriptions[nextchar]
+ if entryanchors then
+ entryanchors = entryanchors.anchors
+ if entryanchors then
+ entryanchors = entryanchors['centry']
+ if entryanchors then
+ local al = anchorlookups[lookupname]
+ for anchor, entry in next, entryanchors do
+ if al[anchor] then
+ local exit = exitanchors[anchor]
+ if exit then
+ local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ end
+ done = true
+ break
+ end
+ end
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(startchar))
+ fonts.register_message(currentfont,startchar,"no entry anchors")
+ end
+ break
+ end
+ end
+ end
+ return start, done
+ else
+ if trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
+ end
+ return start, false
+ end
+end
+
+function handlers.gpos_single(start,kind,lookupname,kerns,sequence)
+ local startchar = start.char
+ local dx, dy = set_pair(start,tfmdata.factor,rlmode,kerns,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting single %s by (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy)
+ end
+ return start, false
+end
+
+function handlers.gpos_pair(start,kind,lookupname,kerns,sequence)
+ -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too
+ -- todo: kerns in components of ligatures
+ local snext = start.next
+ if not snext then
+ return start, false
+ else
+ local prev, done = start, false
+ local factor = tfmdata.factor
+ while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do
+ local nextchar = snext.char
+local krn = kerns[nextchar]
+ if not krn and marks[nextchar] then
+ prev = snext
+ snext = snext.next
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ -- skip
+ elseif type(krn) == "table" then
+ if krn[1] == "pair" then
+ local a, b = krn[3], krn[4]
+ if a and #a > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(start,factor,rlmode,a,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b and #b > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(snext,factor,rlmode,b,characters[nextchar])
+ if trace_kerns then
+ logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ else
+ logs.report("%s: check this out (old kern stuff)",pref(kind,lookupname))
+ local a, b = krn[3], krn[7]
+ if a and a ~= 0 then
+ local k = set_kern(snext,factor,rlmode,a)
+ if trace_kerns then
+ logprocess("%s: inserting first kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar))
+ end
+ end
+ if b and b ~= 0 then
+ logwarning("%s: ignoring second kern xoff %s",pref(kind,lookupname),b*factor)
+ end
+ end
+ done = true
+ elseif krn ~= 0 then
+ local k = set_kern(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar))
+ end
+ done = true
+ end
+ break
+ end
+ end
+ return start, done
+ end
+end
+
+--[[ldx--
+<p>I will implement multiple chain replacements once I run into a font that uses
+it. It's not that complex to handle.</p>
+--ldx]]--
+
+local chainmores = { }
+local chainprocs = { }
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf subchain",...)
+end
+local function logwarning(...)
+ logs.report("otf subchain",...)
+end
+
+-- ['coverage']={
+-- ['after']={ "r" },
+-- ['before']={ "q" },
+-- ['current']={ "a", "b", "c" },
+-- },
+-- ['lookups']={ "ls_l_1", "ls_l_1", "ls_l_1" },
+
+function chainmores.chainsub(start,stop,kind,chainname,currentcontext,cache,lookuplist,chainlookupname,n)
+ logprocess("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+
+-- handled later:
+--
+-- function chainmores.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- return chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- end
+
+function chainmores.gsub_multiple(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+ logprocess("%s: gsub_multiple not yet supported",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+function chainmores.gsub_alternate(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+ logprocess("%s: gsub_alternate not yet supported",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+
+-- handled later:
+--
+-- function chainmores.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- return chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- end
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf chain",...)
+end
+local function logwarning(...)
+ logs.report("otf chain",...)
+end
+
+-- We could share functions but that would lead to extra function calls with many
+-- arguments, redundant tests and confusing messages.
+
+function chainprocs.chainsub(start,stop,kind,chainname,currentcontext,cache,lookuplist,chainlookupname)
+ logwarning("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+
+-- The reversesub is a special case, which is why we need to store the replacements
+-- in a bit weird way. There is no lookup and the replacement comes from the lookup
+-- itself. It is meant mostly for dealing with Urdu.
+
+function chainprocs.reversesub(start,stop,kind,chainname,currentcontext,cache,replacements)
+ local char = start.char
+ local replacement = replacements[char]
+ if replacement then
+ if trace_singles then
+ logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement))
+ end
+ start.char = replacement
+ return start, true
+ else
+ return start, false
+ end
+end
+
+--[[ldx--
+<p>This chain stuff is somewhat tricky since we can have a sequence of actions to be
+applied: single, alternate, multiple or ligature where ligature can be an invalid
+one in the sense that it will replace multiple by one but not neccessary one that
+looks like the combination (i.e. it is the counterpart of multiple then). For
+example, the following is valid:</p>
+
+<typing>
+<line>xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx</line>
+</typing>
+
+<p>Therefore we we don't really do the replacement here already unless we have the
+single lookup case. The efficiency of the replacements can be improved by deleting
+as less as needed but that would also mke the code even more messy.</p>
+--ldx]]--
+
+local function delete_till_stop(start,stop,ignoremarks)
+ if start ~= stop then
+ -- todo keep marks
+ local done = false
+ while not done do
+ done = start == stop
+ delete_node(start,start.next)
+ end
+ end
+end
+
+--[[ldx--
+<p>Here we replace start by a single variant, First we delete the rest of the
+match.</p>
+--ldx]]--
+
+function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex)
+ -- todo: marks ?
+ if not chainindex then
+ delete_till_stop(start,stop) -- ,currentlookup.flags[1])
+ end
+ local current = start
+ local subtables = currentlookup.subtables
+ while current do
+ if current.id == glyph then
+ local currentchar = current.char
+ local lookupname = subtables[1]
+ local replacement = cache.gsub_single[lookupname]
+ if not replacement then
+ if trace_bugs then
+ logwarning("%s: no single hits",cref(kind,chainname,chainlookupname,lookupname,chainindex))
+ end
+ else
+ replacement = replacement[currentchar]
+ if not replacement then
+ if trace_bugs then
+ logwarning("%s: no single for %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar))
+ end
+ else
+ if trace_singles then
+ logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement))
+ end
+ current.char = replacement
+ end
+ end
+ return start, true
+ elseif current == stop then
+ break
+ else
+ current = current.next
+ end
+ end
+ return start, false
+end
+
+chainmores.gsub_single = chainprocs.gsub_single
+
+--[[ldx--
+<p>Here we replace start by a sequence of new glyphs. First we delete the rest of
+the match.</p>
+--ldx]]--
+
+function chainprocs.gsub_multiple(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ delete_till_stop(start,stop)
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local replacements = cache.gsub_multiple[lookupname]
+ if not replacements then
+ if trace_bugs then
+ logwarning("%s: no multiple hits",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ else
+ replacements = replacements[startchar]
+ if not replacements then
+ if trace_bugs then
+ logwarning("%s: no multiple for %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar))
+ end
+ else
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple characters %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar),gref(replacements))
+ end
+ local sn = start.next
+ for k=1,#replacements do
+ if k == 1 then
+ start.char = replacements[k]
+ else
+ local n = copy_node(start) -- maybe delete the components and such
+ n.char = replacements[k]
+ n.next, n.prev = sn, start
+ if sn then
+ sn.prev = n
+ end
+ start.next, start = n, n
+ end
+ end
+ return start, true
+ end
+ end
+ return start, false
+end
+
+--[[ldx--
+<p>Here we replace start by new glyph. First we delete the rest of the match.</p>
+--ldx]]--
+
+function chainprocs.gsub_alternate(start,stop,kind,lookupname,currentcontext,cache,currentlookup)
+ -- todo: marks ?
+ delete_till_stop(start,stop)
+ local current = start
+ local subtables = currentlookup.subtables
+ while current do
+ if current.id == glyph then
+ local currentchar = current.char
+ local lookupname = subtables[1]
+ local alternatives = cache.gsub_alternate[lookupname]
+ if not alternatives then
+ if trace_bugs then
+ logwarning("%s: no alternative hits",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ else
+ alternatives = alternatives[currentchar]
+ if not alternatives then
+ if trace_bugs then
+ logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar))
+ end
+ else
+ local choice, index = alternative_glyph(current,alternatives,kind,chainname,chainlookupname,lookupname)
+ current.char = choice
+ if trace_alternatives then
+ logprocess("%s: replacing single %s by alternative %s (%s)",cref(kind,chainname,chainlookupname,lookupname),index,gref(currentchar),gref(choice),index)
+ end
+ end
+ end
+ return start, true
+ elseif current == stop then
+ break
+ else
+ current = current.next
+ end
+ end
+ return start, false
+end
+
+--[[ldx--
+<p>When we replace ligatures we use a helper that handles the marks. I might change
+this function (move code inline and handle the marks by a separate function). We
+assume rather stupid ligatures (no complex disc nodes).</p>
+--ldx]]--
+
+function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex)
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local ligatures = cache.gsub_ligature[lookupname]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligature hits",cref(kind,chainname,chainlookupname,lookupname,chainindex))
+ end
+ else
+ ligatures = ligatures[startchar]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
+ end
+ else
+ local s, discfound, last, nofreplacements = start.next, false, stop, 0
+ while s do
+ local id = s.id
+ if id == disc then
+ s = s.next
+ discfound = true
+ else
+ local schar = s.char
+ if marks[schar] then -- marks
+ s = s.next
+ else
+ local lg = ligatures[1][schar]
+ if not lg then
+ break
+ else
+ ligatures, last, nofreplacements = lg, s, nofreplacements + 1
+ if s == stop then
+ break
+ else
+ s = s.next
+ end
+ end
+ end
+ end
+ end
+ local l2 = ligatures[2]
+ if l2 then
+ if chainindex then
+ stop = last
+ end
+ if trace_ligatures then
+ if start == stop then
+ logprocess("%s: replacing character %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2))
+ else
+ logprocess("%s: replacing character %s upto %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2))
+ end
+ end
+ start = toligature(kind,lookup,start,stop,l2,currentlookup.flags[1],discfound)
+ return start, true, nofreplacements
+ elseif trace_bugs then
+ if start == stop then
+ logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
+ else
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char))
+ end
+ end
+ end
+ end
+ return start, false, 0
+end
+
+chainmores.gsub_ligature = chainprocs.gsub_ligature
+
+function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local markchar = start.char
+ if marks[markchar] then
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = cache.gpos_mark2base[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = start.prev -- [glyph] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+ end
+ end
+ end
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ local baseanchors = baseanchors['basechar']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s, no matching anchors for mark %s and base %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local markchar = start.char
+ if marks[markchar] then
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = cache.gpos_mark2ligature[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = start.prev -- [glyph] [optional marks] [start=mark]
+ local index = 1
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ else
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",cref(kind,chainname,chainlookupname,lookupname),markchar)
+ end
+ return start, false
+ end
+ end
+ end
+ -- todo: like marks a ligatures hash
+ local i = has_attribute(start,markdone)
+ if i then index = i end
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ local baseanchors = baseanchors['baselig']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ ba = ba[index]
+ if ba then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma,index)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("feature %s, lookup %s: prev node is no char",kind,lookupname)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local markchar = start.char
+ if marks[markchar] then
+--~ local alreadydone = markonce and has_attribute(start,markmark)
+--~ if not alreadydone then
+ -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = cache.gpos_mark2mark[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = start.prev -- [glyph] [basemark] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go
+ local basechar = base.char
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ baseanchors = baseanchors['basemark']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
+--~ elseif trace_marks and trace_details then
+--~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone)
+--~ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
+ end
+ return start, false
+end
+
+-- ! ! ! untested ! ! !
+
+function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local alreadydone = cursonce and has_attribute(start,cursbase)
+ if not alreadydone then
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local exitanchors = cache.gpos_cursive[lookupname]
+ if exitanchors then
+ exitanchors = exitanchors[startchar]
+ end
+ if exitanchors then
+ local done = false
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar))
+ end
+ else
+ local nxt = start.next
+ while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do
+ local nextchar = nxt.char
+ if marks[nextchar] then
+ -- should not happen (maybe warning)
+ nxt = nxt.next
+ else
+ local entryanchors = descriptions[nextchar]
+ if entryanchors then
+ entryanchors = entryanchors.anchors
+ if entryanchors then
+ entryanchors = entryanchors['centry']
+ if entryanchors then
+ local al = anchorlookups[lookupname]
+ for anchor, entry in next, entryanchors do
+ if al[anchor] then
+ local exit = exitanchors[anchor]
+ if exit then
+ local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ end
+ done = true
+ break
+ end
+ end
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(startchar))
+ fonts.register_message(currentfont,startchar,"no entry anchors")
+ end
+ break
+ end
+ end
+ end
+ return start, done
+ else
+ if trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
+ end
+ return start, false
+ end
+ end
+ return start, false
+end
+
+function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ -- untested
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local kerns = cache.gpos_single[lookupname]
+ if kerns then
+ kerns = kerns[startchar]
+ if kerns then
+ local dx, dy = set_pair(start,tfmdata.factor,rlmode,kerns,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting single %s by (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy)
+ end
+ end
+ end
+ return start, false
+end
+
+-- when machines become faster i will make a shared function
+
+function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+-- logwarning("%s: gpos_pair not yet supported",cref(kind,chainname,chainlookupname))
+ local snext = start.next
+ if snext then
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local kerns = cache.gpos_pair[lookupname]
+ if kerns then
+ kerns = kerns[startchar]
+ if kerns then
+ local prev, done = start, false
+ local factor = tfmdata.factor
+ while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do
+ local nextchar = snext.char
+local krn = kerns[nextchar]
+ if not krn and marks[nextchar] then
+ prev = snext
+ snext = snext.next
+ else
+--~ local krn = kerns[nextchar]
+ if not krn then
+ -- skip
+ elseif type(krn) == "table" then
+ if krn[1] == "pair" then
+ local a, b = krn[3], krn[4]
+ if a and #a > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(start,factor,rlmode,a,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b and #b > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(snext,factor,rlmode,b,characters[nextchar])
+ if trace_kerns then
+ logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ else
+ logs.report("%s: check this out (old kern stuff)",cref(kind,chainname,chainlookupname))
+ local a, b = krn[3], krn[7]
+ if a and a ~= 0 then
+ local k = set_kern(snext,factor,rlmode,a)
+ if trace_kerns then
+ logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar))
+ end
+ end
+ if b and b ~= 0 then
+ logwarning("%s: ignoring second kern xoff %s",cref(kind,chainname,chainlookupname),b*factor)
+ end
+ end
+ done = true
+ elseif krn ~= 0 then
+ local k = set_kern(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar))
+ end
+ done = true
+ end
+ break
+ end
+ end
+ return start, done
+ end
+ end
+ end
+ return start, false
+end
+
+-- what pointer to return, spec says stop
+-- to be discussed ... is bidi changer a space?
+-- elseif char == zwnj and sequence[n][32] then -- brrr
+
+-- somehow l or f is global
+-- we don't need to pass the currentcontext, saves a bit
+-- make a slow variant then can be activated but with more tracing
+
+local function normal_handle_contextchain(start,kind,chainname,contexts,sequence,cache)
+ -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6]
+ local flags, done = sequence.flags, false
+ local skipmark, skipligature, skipbase = flags[1], flags[2], flags[3]
+ local someskip = skipmark or skipligature or skipbase -- could be stored in flags for a fast test (hm, flags could be false !)
+ for k=1,#contexts do
+ local match, current, last = true, start, start
+ local ck = contexts[k]
+ local sequence = ck[3]
+ local s = #sequence
+ if s == 1 then
+ -- never happens
+ match = current.id == glyph and current.subtype<256 and current.font == currentfont and sequence[1][current.char]
+ else
+ -- todo: better space check (maybe check for glue)
+ local f, l = ck[4], ck[5]
+ if f == l then
+ -- already a hit
+ match = true
+ else
+ -- no need to test first hit (to be optimized)
+ local n = f + 1
+ last = last.next
+ -- we cannot optimize for n=2 because there can be disc nodes
+ -- if not someskip and n == l then
+ -- -- n=2 and no skips then faster loop
+ -- match = last and last.id == glyph and last.subtype<256 and last.font == currentfont and sequence[n][last.char]
+ -- else
+ while n <= l do
+ if last then
+ local id = last.id
+ if id == glyph then
+ if last.subtype<256 and last.font == currentfont then
+ local char = last.char
+ local ccd = descriptions[char]
+ if ccd then
+ local class = ccd.class
+ if class == skipmark or class == skipligature or class == skipbase then
+--~ if someskip and class == skipmark or class == skipligature or class == skipbase then
+ -- skip 'm
+ last = last.next
+ elseif sequence[n][char] then
+ if n < l then
+ last = last.next
+ end
+ n = n + 1
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ elseif id == disc then -- what to do with kerns?
+ last = last.next
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ end
+ -- end
+ end
+ if match and f > 1 then
+ local prev = start.prev
+ if prev then
+ local n = f-1
+ while n >= 1 do
+ if prev then
+ local id = prev.id
+ if id == glyph then
+ if prev.subtype<256 and prev.font == currentfont then -- normal char
+ local char = prev.char
+ local ccd = descriptions[char]
+ if ccd then
+ local class = ccd.class
+ if class == skipmark or class == skipligature or class == skipbase then
+--~ if someskip and class == skipmark or class == skipligature or class == skipbase then
+ -- skip 'm
+ elseif sequence[n][char] then
+ n = n -1
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ elseif id == disc then
+ -- skip 'm
+ elseif sequence[n][32] then
+ n = n -1
+ else
+ match = false break
+ end
+ prev = prev.prev
+ elseif sequence[n][32] then
+ n = n -1
+ else
+ match = false break
+ end
+ end
+ elseif f == 2 then
+ match = sequence[1][32]
+ else
+ for n=f-1,1 do
+ if not sequence[n][32] then
+ match = false break
+ end
+ end
+ end
+ end
+ if match and s > l then
+ local current = last.next
+ if current then
+ -- removed optimiziation for s-l == 1, we have to deal with marks anyway
+ local n = l + 1
+ while n <= s do
+ if current then
+ local id = current.id
+ if id == glyph then
+ if current.subtype<256 and current.font == currentfont then -- normal char
+ local char = current.char
+ local ccd = descriptions[char]
+ if ccd then
+ local class = ccd.class
+ if class == skipmark or class == skipligature or class == skipbase then
+--~ if someskip and class == skipmark or class == skipligature or class == skipbase then
+ -- skip 'm
+ elseif sequence[n][char] then
+ n = n + 1
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ elseif id == disc then
+ -- skip 'm
+ elseif sequence[n][32] then -- brrr
+ n = n + 1
+ else
+ match = false break
+ end
+ current = current.next
+ elseif sequence[n][32] then
+ n = n + 1
+ else
+ match = false break
+ end
+ end
+ elseif s-l == 1 then
+ match = sequence[s][32]
+ else
+ for n=l+1,s do
+ if not sequence[n][32] then
+ match = false break
+ end
+ end
+ end
+ end
+ end
+ if match then
+ -- ck == currentcontext
+ if trace_contexts then
+ local rule, lookuptype, sequence, f, l = ck[1], ck[2] ,ck[3], ck[4], ck[5]
+ local char = start.char
+ if ck[9] then
+ logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %s (%s=>%s)",cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10])
+ else
+ logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %s",cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype)
+ end
+ end
+ local chainlookups = ck[6]
+ if chainlookups then
+ local nofchainlookups = #chainlookups
+ -- we can speed this up if needed
+ if nofchainlookups == 1 then
+ local chainlookupname = chainlookups[1]
+ local chainlookup = lookuptable[chainlookupname]
+ local cp = chainprocs[chainlookup.type]
+ if cp then
+ start, done = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname)
+ else
+ logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
+ end
+ else
+ -- actually this needs a more complex treatment for which we will use chainmores
+ local i = 1
+ repeat
+ local chainlookupname = chainlookups[i]
+ local chainlookup = lookuptable[chainlookupname]
+ local cp = chainmores[chainlookup.type]
+ if cp then
+ local ok, n
+ start, ok, n = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname,i)
+ -- messy since last can be changed !
+ if ok then
+ done = true
+ start = start.next
+ if n then
+ -- skip next one(s) if ligature
+ i = i + n - 1
+ end
+ end
+ else
+ logprocess("%s: multiple subchains for %s are not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
+ end
+ i = i + 1
+ until i > nofchainlookups
+ end
+ else
+ local replacements = ck[7]
+ if replacements then
+ start, done = chainprocs.reversesub(start,last,kind,chainname,ck,cache,replacements)
+ else
+ done = true -- can be meant to be skipped
+ if trace_contexts then
+ logprocess("%s: skipping match",cref(kind,chainname))
+ end
+ end
+ end
+ end
+ end
+ return start, done
+end
+
+-- Because we want to keep this elsewhere (an because speed is less an issue) we
+-- pass the font id so that the verbose variant can access the relevant helper tables.
+
+local verbose_handle_contextchain = function(font,...)
+ logwarning("no verbose handler installed, reverting to 'normal'")
+ otf.setcontextchain()
+ return normal_handle_contextchain(...)
+end
+
+otf.chainhandlers = {
+ normal = normal_handle_contextchain,
+ verbose = verbose_handle_contextchain,
+}
+
+function otf.setcontextchain(method)
+ if not method or method == "normal" or not otf.chainhandlers[method] then
+ if handlers.contextchain then -- no need for a message while making the format
+ logwarning("installing normal contextchain handler")
+ end
+ handlers.contextchain = normal_handle_contextchain
+ else
+ logwarning("installing contextchain handler '%s'",method)
+ local handler = otf.chainhandlers[method]
+ handlers.contextchain = function(...)
+ return handler(currentfont,...)
+ end
+ end
+ handlers.gsub_context = handlers.contextchain
+ handlers.gsub_contextchain = handlers.contextchain
+ handlers.gsub_reversecontextchain = handlers.contextchain
+ handlers.gpos_contextchain = handlers.contextchain
+ handlers.gpos_context = handlers.contextchain
+end
+
+otf.setcontextchain()
+
+local missing = { } -- we only report once
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf process",...)
+end
+local function logwarning(...)
+ logs.report("otf process",...)
+end
+
+local function report_missing_cache(typ,lookup)
+ local f = missing[currentfont] if not f then f = { } missing[currentfont] = f end
+ local t = f[typ] if not t then t = { } f[typ] = t end
+ if not t[lookup] then
+ t[lookup] = true
+ logwarning("missing cache for lookup %s of type %s in font %s (%s)",lookup,typ,currentfont,tfmdata.fullname)
+ end
+end
+
+local resolved = { } -- we only resolve a font,script,language pair once
+
+function fonts.methods.node.otf.features(head,font,attr)
+ if trace_steps then
+ checkstep(head)
+ end
+ tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ otfdata = shared.otfdata
+ local luatex = otfdata.luatex
+ descriptions = tfmdata.descriptions
+ characters = tfmdata.characters
+ indices = tfmdata.indices
+ unicodes = tfmdata.unicodes
+ marks = tfmdata.marks
+ anchorlookups = luatex.lookup_to_anchor
+ currentfont = font
+ rlmode = 0
+ local featuredata = otfdata.shared.featuredata -- can be made local to closure
+ local sequences = luatex.sequences
+ lookuptable = luatex.lookups
+ local done = false
+ local script, language, s_enabled, a_enabled, dyn
+ local attribute_driven = attr and attr ~= 0
+ if attribute_driven then
+ local features = context_setups[context_numbers[attr]] -- could be a direct list
+ dyn = context_merged[attr] or 0
+ language, script = features.language or "dflt", features.script or "dflt"
+ a_enabled = features -- shared.features -- can be made local to the resolver
+ if dyn == 2 or dyn == -2 then
+ -- font based
+ s_enabled = shared.features
+ end
+ else
+ language, script = tfmdata.language or "dflt", tfmdata.script or "dflt"
+ s_enabled = shared.features -- can be made local to the resolver
+ dyn = 0
+ end
+ -- we can save some runtime by caching feature tests
+ local res = resolved[font] if not res then res = { } resolved[font] = res end
+ local rs = res [script] if not rs then rs = { } res [script] = rs end
+ local rl = rs [language] if not rl then rl = { } rs [language] = rl end
+ local ra = rl [attr] if ra == nil then ra = { } rl [attr] = ra end -- attr can be false
+ -- sequences always > 1 so no need for optimization
+ for s=1,#sequences do
+ local success = false
+ local sequence = sequences[s]
+ local r = ra[s] -- cache
+ if r == nil then
+ --
+ -- this bit will move to font-ctx and become a function
+ ---
+ local chain = sequence.chain or 0
+ local features = sequence.features
+ if not features then
+ -- indirect lookup, part of chain (todo: make this a separate table)
+ r = false -- { false, false, chain }
+ else
+ local valid, attribute, kind, what = false, false
+ for k,v in next, features do
+ -- we can quit earlier but for the moment we want the tracing
+ local s_e = s_enabled and s_enabled[k]
+ local a_e = a_enabled and a_enabled[k]
+ if s_e or a_e then
+ local l = v[script] or v[wildcard]
+ if l then
+ -- not l[language] or l[default] or l[wildcard] because we want tracing
+ -- only first attribute match check, so we assume simple fina's
+ -- default can become a font feature itself
+ if l[language] then
+--~ valid, what = true, language
+ valid, what = s_e or a_e, language
+ -- elseif l[default] then
+ -- valid, what = true, default
+ elseif l[wildcard] then
+--~ valid, what = true, wildcard
+ valid, what = s_e or a_e, wildcard
+ end
+ if valid then
+ kind, attribute = k, special_attributes[k] or false
+ if a_e and dyn < 0 then
+ valid = false
+ end
+ if trace_applied then
+ local typ, action = match(sequence.type,"(.*)_(.*)")
+ logs.report("otf node mode",
+ "%s font: %03i, dynamic: %03i, kind: %s, lookup: %3i, script: %-4s, language: %-4s (%-4s), type: %s, action: %s, name: %s",
+ (valid and "+") or "-",font,attr or 0,kind,s,script,language,what,typ,action,sequence.name)
+ end
+ break
+ end
+ end
+ end
+ end
+ if valid then
+ r = { valid, attribute, chain, kind }
+ else
+ r = false -- { valid, attribute, chain, "generic" } -- false anyway, could be flag instead of table
+ end
+ end
+ ra[s] = r
+ end
+featurevalue = r and r[1] -- toto: pass to function instead
+ if featurevalue then
+ local attribute, chain, typ, subtables = r[2], r[3], sequence.type, sequence.subtables
+ if chain < 0 then
+ -- this is a limited case, no special treatments like 'init' etc
+ local handler = handlers[typ]
+ local thecache = featuredata[typ] or { }
+ -- we need to get rid of this slide !
+ start = slide_node_list(head) -- slow (we can store tail because there's always a skip at the end): todo
+ while start do
+ local id = start.id
+ if id == glyph then
+--~ if start.subtype<256 and start.font == font and (not attr or has_attribute(start,0,attr)) then
+ if start.subtype<256 and start.font == font and has_attribute(start,0,attr) then
+ for i=1,#subtables do
+ local lookupname = subtables[i]
+ local lookupcache = thecache[lookupname]
+ if lookupcache then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ start, success = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,i)
+ if success then
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
+ end
+ end
+ if start then start = start.prev end
+ else
+ start = start.prev
+ end
+ else
+ start = start.prev
+ end
+ end
+ else
+ local handler = handlers[typ]
+ local ns = #subtables
+ local thecache = featuredata[typ] or { }
+ start = head -- local ?
+ rlmode = 0
+ if ns == 1 then
+ local lookupname = subtables[1]
+ local lookupcache = thecache[lookupname]
+ if not lookupcache then
+ report_missing_cache(typ,lookupname)
+ else
+ while start do
+ local id = start.id
+ if id == glyph then
+--~ if start.font == font and start.subtype<256 and (not attr or has_attribute(start,0,attr)) and (not attribute or has_attribute(start,state,attribute)) then
+ if start.font == font and start.subtype<256 and has_attribute(start,0,attr) and (not attribute or has_attribute(start,state,attribute)) then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ -- sequence kan weg
+ local ok
+ start, ok = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,1)
+ if ok then
+ success = true
+ end
+ end
+ if start then start = start.next end
+ else
+ start = start.next
+ end
+ -- elseif id == glue then
+ -- if p[5] then -- chain
+ -- local pc = pp[32]
+ -- if pc then
+ -- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
+ -- if ok then
+ -- done = true
+ -- end
+ -- if start then start = start.next end
+ -- else
+ -- start = start.next
+ -- end
+ -- else
+ -- start = start.next
+ -- end
+ elseif id == whatsit then
+ local subtype = start.subtype
+ if subtype == 7 then
+ local dir = start.dir
+ if dir == "+TRT" then
+ rlmode = -1
+ elseif dir == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ elseif subtype == 6 then
+ local dir = start.dir
+ if dir == "TRT" then
+ rlmode = -1
+ elseif dir == "TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ end
+ start = start.next
+ else
+ start = start.next
+ end
+ end
+
+ end
+ else
+ while start do
+ local id = start.id
+ if id == glyph then
+--~ if start.subtype<256 and start.font == font and (not attr or has_attribute(start,0,attr)) and (not attribute or has_attribute(start,state,attribute)) then
+ if start.subtype<256 and start.font == font and has_attribute(start,0,attr) and (not attribute or has_attribute(start,state,attribute)) then
+ for i=1,ns do
+ local lookupname = subtables[i]
+ local lookupcache = thecache[lookupname]
+ if lookupcache then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ -- we could move all code inline but that makes things even more unreadable
+ local ok
+ start, ok = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,i)
+ if ok then
+ success = true
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
+ end
+ end
+ if start then start = start.next end
+ else
+ start = start.next
+ end
+ -- elseif id == glue then
+ -- if p[5] then -- chain
+ -- local pc = pp[32]
+ -- if pc then
+ -- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
+ -- if ok then
+ -- done = true
+ -- end
+ -- if start then start = start.next end
+ -- else
+ -- start = start.next
+ -- end
+ -- else
+ -- start = start.next
+ -- end
+ elseif id == whatsit then
+ local subtype = start.subtype
+ if subtype == 7 then
+ local dir = start.dir
+ if dir == "+TRT" then
+ rlmode = -1
+ elseif dir == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ elseif subtype == 6 then
+ local dir = start.dir
+ if dir == "TRT" then
+ rlmode = -1
+ elseif dir == "TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ end
+ start = start.next
+ else
+ start = start.next
+ end
+ end
+ end
+ end
+ if success then
+ done = true
+ end
+ if trace_steps then -- ?
+ registerstep(head)
+ end
+ end
+ end
+ return head, done
+end
+
+otf.features.prepare = { }
+
+-- we used to share code in the following functions but that costs a lot of
+-- memory due to extensive calls to functions (easily hundreds of thousands per
+-- document)
+
+local function split(replacement,original,cache,unicodes)
+ -- we can cache this too, but not the same
+ local o, t, n = { }, { }, 0
+ for s in gmatch(original,"[^ ]+") do
+ local us = unicodes[s]
+ if type(us) == "number" then
+ o[#o+1] = us
+ else
+ o[#o+1] = us[1]
+ end
+ end
+ for s in gmatch(replacement,"[^ ]+") do
+ n = n + 1
+ local us = unicodes[s]
+ if type(us) == "number" then
+ t[o[n]] = us
+ else
+ t[o[n]] = us[1]
+ end
+ end
+ return t
+end
+
+local function uncover(covers,result,cache,unicodes)
+ -- lpeg hardly faster (.005 sec on mk)
+ for n=1,#covers do
+ local c = covers[n]
+ local cc = cache[c]
+ if not cc then
+ local t = { }
+ for s in gmatch(c,"[^ ]+") do
+ local us = unicodes[s]
+ if type(us) == "number" then
+ t[us] = true
+ else
+ for i=1,#us do
+ t[us[i]] = true
+ end
+ end
+ end
+ cache[c] = t
+ result[#result+1] = t
+ else
+ result[#result+1] = cc
+ end
+ end
+end
+
+local function prepare_lookups(tfmdata)
+ local otfdata = tfmdata.shared.otfdata
+ local featuredata = otfdata.shared.featuredata
+ local anchor_to_lookup = otfdata.luatex.anchor_to_lookup
+ local lookup_to_anchor = otfdata.luatex.lookup_to_anchor
+ --
+ local multiple = featuredata.gsub_multiple
+ local alternate = featuredata.gsub_alternate
+ local single = featuredata.gsub_single
+ local ligature = featuredata.gsub_ligature
+ local pair = featuredata.gpos_pair
+ local position = featuredata.gpos_single
+ local kerns = featuredata.gpos_pair
+ local mark = featuredata.gpos_mark2mark
+ local cursive = featuredata.gpos_cursive
+ --
+ local unicodes = tfmdata.unicodes -- names to unicodes
+ local indices = tfmdata.indices
+ local descriptions = tfmdata.descriptions
+ --
+ -- we can change the otf table after loading but then we need to adapt base mode
+ -- as well (no big deal)
+ --
+ for unicode, glyph in next, descriptions do
+ local lookups = glyph.lookups
+ if lookups then
+ for lookup, whatever in next, lookups do
+ for i=1,#whatever do -- normaly one
+ local p = whatever[i]
+ local what = p[1]
+ if what == 'substitution' then
+ local old, new = unicode, unicodes[p[2]]
+ if type(new) == "table" then
+ new = new[1]
+ end
+ local s = single[lookup]
+ if not s then s = { } single[lookup] = s end
+ s[old] = new
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: substitution %s => %s",lookup,old,new)
+--~ end
+ break
+ elseif what == 'multiple' then
+ local old, new = unicode, { }
+ local m = multiple[lookup]
+ if not m then m = { } multiple[lookup] = m end
+ m[old] = new
+ for pc in gmatch(p[2],"[^ ]+") do
+ local upc = unicodes[pc]
+ if type(upc) == "number" then
+ new[#new+1] = upc
+ else
+ new[#new+1] = upc[1]
+ end
+ end
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: multiple %s => %s",lookup,old,concat(new," "))
+--~ end
+ break
+ elseif what == 'alternate' then
+ local old, new = unicode, { }
+ local a = alternate[lookup]
+ if not a then a = { } alternate[lookup] = a end
+ a[old] = new
+ for pc in gmatch(p[2],"[^ ]+") do
+ local upc = unicodes[pc]
+ if type(upc) == "number" then
+ new[#new+1] = upc
+ else
+ new[#new+1] = upc[1]
+ end
+ end
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: alternate %s => %s",lookup,old,concat(new,"|"))
+--~ end
+ break
+ elseif what == "ligature" then
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: ligature %s => %s",lookup,p[2],glyph.name)
+--~ end
+ local first = true
+ local t = ligature[lookup]
+ if not t then t = { } ligature[lookup] = t end
+ for s in gmatch(p[2],"[^ ]+") do
+ if first then
+ local u = unicodes[s]
+ if not u then
+ logs.report("define otf","lookup %s: ligature %s => %s ignored due to invalid unicode",lookup,p[2],glyph.name)
+ break
+ elseif type(u) == "number" then
+ if not t[u] then
+ t[u] = { { } }
+ end
+ t = t[u]
+ else
+ local tt = t
+ local tu
+ for i=1,#u do
+ local u = u[i]
+ if i==1 then
+ if not t[u] then
+ t[u] = { { } }
+ end
+ tu = t[u]
+ t = tu
+ else
+ if not t[u] then
+ tt[u] = tu
+ end
+ end
+ end
+ end
+ first = false
+ else
+ s = unicodes[s]
+ local t1 = t[1]
+ if not t1[s] then
+ t1[s] = { { } }
+ end
+ t = t1[s]
+ end
+ end
+ t[2] = unicode
+ elseif what == 'position' then
+ -- not used
+ local s = position[lookup]
+ if not s then s = { } position[lookup] = s end
+ s[unicode] = p[2] -- direct pointer to kern spec
+ elseif what == 'pair' then
+ local s = pair[lookup]
+ if not s then s = { } pair[lookup] = s end
+ local others = s[unicode]
+ if not others then others = { } s[unicode] = others end
+ -- todo: fast check for space
+ local two = p[2]
+ local upc = unicodes[two]
+ if not upc then
+ for pc in gmatch(two,"[^ ]+") do
+ local upc = unicodes[pc]
+ if type(upc) == "number" then
+ others[upc] = p -- direct pointer to main table
+ else
+ for i=1,#upc do
+ others[upc[i]] = p -- direct pointer to main table
+ end
+ end
+ end
+ elseif type(upc) == "number" then
+ others[upc] = p -- direct pointer to main table
+ else
+ for i=1,#upc do
+ others[upc[i]] = p -- direct pointer to main table
+ end
+ end
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: pair for U+%04X",lookup,unicode)
+--~ end
+ end
+ end
+ end
+ end
+ local list = glyph.mykerns
+ if list then
+ for lookup, krn in next, list do
+ local k = kerns[lookup]
+ if not k then k = { } kerns[lookup] = k end
+ k[unicode] = krn -- ref to glyph, saves lookup
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: kern for U+%04X",lookup,unicode)
+--~ end
+ end
+ end
+ local oanchor = glyph.anchors
+ if oanchor then
+ for typ, anchors in next, oanchor do -- types
+ if typ == "mark" then
+ for name, anchor in next, anchors do
+ local lookups = anchor_to_lookup[name]
+ if lookups then
+ for lookup, _ in next, lookups do
+ local f = mark[lookup]
+ if not f then f = { } mark[lookup] = f end
+ f[unicode] = anchors -- ref to glyph, saves lookup
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: mark anchor %s for U+%04X",lookup,name,unicode)
+--~ end
+ end
+ end
+ end
+ elseif typ == "cexit" then -- or entry?
+ for name, anchor in next, anchors do
+ local lookups = anchor_to_lookup[name]
+ if lookups then
+ for lookup, _ in next, lookups do
+ local f = cursive[lookup]
+ if not f then f = { } cursive[lookup] = f end
+ f[unicode] = anchors -- ref to glyph, saves lookup
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: exit anchor %s for U+%04X",lookup,name,unicode)
+--~ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+-- local cache = { }
+luatex = luatex or {} -- this has to change ... we need a better one
+
+function prepare_contextchains(tfmdata)
+ local otfdata = tfmdata.shared.otfdata
+ local lookups = otfdata.lookups
+ if lookups then
+ local featuredata = otfdata.shared.featuredata
+ local contextchain = featuredata.gsub_contextchain -- shared with gpos
+ local reversecontextchain = featuredata.gsub_reversecontextchain -- shared with gpos
+ local characters = tfmdata.characters
+ local unicodes = tfmdata.unicodes
+ local indices = tfmdata.indices
+ local cache = luatex.covers
+ if not cache then
+ cache = { }
+ luatex.covers = cache
+ end
+ --
+ for lookupname, lookupdata in next, otfdata.lookups do
+ local lookuptype = lookupdata.type
+ if not lookuptype then
+ logs.report("otf process","missing lookuptype for %s",lookupname)
+ else
+ local rules = lookupdata.rules
+ if rules then
+ local fmt = lookupdata.format
+ -- contextchain[lookupname][unicode]
+ if fmt == "coverage" then
+ if lookuptype ~= "chainsub" and lookuptype ~= "chainpos" then
+ logs.report("otf process","unsupported coverage %s for %s",lookuptype,lookupname)
+ else
+ local contexts = contextchain[lookupname]
+ if not contexts then
+ contexts = { }
+ contextchain[lookupname] = contexts
+ end
+ local t = { }
+ for nofrules=1,#rules do -- does #rules>1 happen often?
+ local rule = rules[nofrules]
+ local coverage = rule.coverage
+ if coverage and coverage.current then
+ local current, before, after, sequence = coverage.current, coverage.before, coverage.after, { }
+ if before then
+ uncover(before,sequence,cache,unicodes)
+ end
+ local start = #sequence + 1
+ uncover(current,sequence,cache,unicodes)
+ local stop = #sequence
+ if after then
+ uncover(after,sequence,cache,unicodes)
+ end
+ if sequence[1] then
+ t[#t+1] = { nofrules, lookuptype, sequence, start, stop, rule.lookups }
+ for unic, _ in next, sequence[start] do
+ local cu = contexts[unic]
+ if not cu then
+ contexts[unic] = t
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif fmt == "reversecoverage" then
+ if lookuptype ~= "reversesub" then
+ logs.report("otf process","unsupported reverse coverage %s for %s",lookuptype,lookupname)
+ else
+ local contexts = reversecontextchain[lookupname]
+ if not contexts then
+ contexts = { }
+ reversecontextchain[lookupname] = contexts
+ end
+ local t = { }
+ for nofrules=1,#rules do
+ local rule = rules[nofrules]
+ local reversecoverage = rule.reversecoverage
+ if reversecoverage and reversecoverage.current then
+ local current, before, after, replacements, sequence = reversecoverage.current, reversecoverage.before, reversecoverage.after, reversecoverage.replacements, { }
+ if before then
+ uncover(before,sequence,cache,unicodes)
+ end
+ local start = #sequence + 1
+ uncover(current,sequence,cache,unicodes)
+ local stop = #sequence
+ if after then
+ uncover(after,sequence,cache,unicodes)
+ end
+ if replacements then
+ replacements = split(replacements,current[1],cache,unicodes)
+ end
+ if sequence[1] then
+ -- this is different from normal coverage, we assume only replacements
+ t[#t+1] = { nofrules, lookuptype, sequence, start, stop, rule.lookups, replacements }
+ for unic, _ in next, sequence[start] do
+ local cu = contexts[unic]
+ if not cu then
+ contexts[unic] = t
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+function fonts.initializers.node.otf.features(tfmdata,value)
+ if true then -- value then
+ if not tfmdata.shared.otfdata.shared.initialized then
+ local t = trace_preparing and os.clock()
+ local otfdata = tfmdata.shared.otfdata
+ local featuredata = otfdata.shared.featuredata
+ -- caches
+ featuredata.gsub_multiple = { }
+ featuredata.gsub_alternate = { }
+ featuredata.gsub_single = { }
+ featuredata.gsub_ligature = { }
+ featuredata.gsub_contextchain = { }
+ featuredata.gsub_reversecontextchain = { }
+ featuredata.gpos_pair = { }
+ featuredata.gpos_single = { }
+ featuredata.gpos_mark2base = { }
+ featuredata.gpos_mark2ligature = featuredata.gpos_mark2base
+ featuredata.gpos_mark2mark = featuredata.gpos_mark2base
+ featuredata.gpos_cursive = { }
+ featuredata.gpos_contextchain = featuredata.gsub_contextchain
+ featuredata.gpos_reversecontextchain = featuredata.gsub_reversecontextchain
+ --
+ prepare_contextchains(tfmdata)
+ prepare_lookups(tfmdata)
+ otfdata.shared.initialized = true
+ if trace_preparing then
+ logs.report("otf process","preparation time is %0.3f seconds for %s",os.clock()-t,tfmdata.fullname or "?")
+ end
+ end
+ end
+end
diff --git a/tex/context/base/font-otp.lua b/tex/context/base/font-otp.lua
new file mode 100644
index 000000000..3cdc80737
--- /dev/null
+++ b/tex/context/base/font-otp.lua
@@ -0,0 +1,420 @@
+if not modules then modules = { } end modules ['font-otp'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (packing)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: pack math (but not that much to share)
+
+local next = next
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+fonts.otf.enhancers = fonts.otf.enhancers or { }
+fonts.otf.glists = fonts.otf.glists or { "gsub", "gpos" }
+
+local criterium, threshold, tabstr = 1, 0, table.serialize
+
+function fonts.otf.enhancers.pack(data)
+ if data then
+ local h, t, c = { }, { }, { }
+ local hh, tt, cc = { }, { }, { }
+ local function pack_1(v)
+ -- v == table
+ local tag = tabstr(v)
+ local ht = h[tag]
+ if not ht then
+ ht = #t+1
+ t[ht] = v
+ h[tag] = ht
+ c[ht] = 1
+ else
+ c[ht] = c[ht] + 1
+ end
+ return ht
+ end
+ local function pack_2(v)
+ -- v == number
+ if c[v] <= criterium then
+ return t[v]
+ else
+ -- compact hash
+ local hv = hh[v]
+ if not hv then
+ hv = #tt+1
+ tt[hv] = t[v]
+ hh[v] = hv
+ cc[hv] = c[v]
+ end
+ return hv
+ end
+ end
+ local function success(stage,pass)
+ if #t == 0 then
+ if trace_loading then
+ logs.report("load otf","pack quality: nothing to pack")
+ end
+ return false
+ elseif #t >= threshold then
+ local one, two, rest = 0, 0, 0
+ if pass == 1 then
+ for k,v in next, c do
+ if v == 1 then
+ one = one + 1
+ elseif v == 2 then
+ two = two + 1
+ else
+ rest = rest + 1
+ end
+ end
+ else
+ for k,v in next, cc do
+ if v >20 then
+ rest = rest + 1
+ elseif v >10 then
+ two = two + 1
+ else
+ one = one + 1
+ end
+ end
+ data.tables = tt
+ end
+ if trace_loading then
+ logs.report("load otf","pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", stage, pass, one+two+rest, one, two, rest, criterium)
+ end
+ return true
+ else
+ if trace_loading then
+ logs.report("load otf","pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", stage, pass, #t, threshold)
+ end
+ return false
+ end
+ end
+ for pass=1,2 do
+ local pack = (pass == 1 and pack_1) or pack_2
+ for k, v in next, data.glyphs do
+ v.boundingbox = pack(v.boundingbox)
+ local l = v.lookups
+ if l then
+ for k,v in next, l do
+ for kk=1,#v do
+ local vkk = v[kk]
+ local what = vkk[1]
+ if what == "pair" then
+ local t = vkk[3] if t then vkk[3] = pack(t) end
+ local t = vkk[4] if t then vkk[4] = pack(t) end
+ elseif what == "position" then
+ local t = vkk[2] if t then vkk[2] = pack(t) end
+ end
+ -- v[kk] = pack(vkk)
+ end
+ end
+ end
+ local m = v.mykerns
+ if m then
+ for k,v in next, m do
+ m[k] = pack(v)
+ end
+ end
+ local m = v.math
+ if m then
+ local mk = m.kerns
+ if mk then
+ for k,v in next, mk do
+ mk[k] = pack(v)
+ end
+ end
+ end
+ local a = v.anchors
+ if a then
+ for k,v in next, a do
+ if k == "baselig" then
+ for kk, vv in next, v do
+ for kkk=1,#vv do
+ vv[kkk] = pack(vv[kkk])
+ end
+ end
+ else
+ for kk, vv in next, v do
+ v[kk] = pack(vv)
+ end
+ end
+ end
+ end
+ end
+ if data.lookups then
+ for k, v in next, data.lookups do
+ if v.rules then
+ for kk, vv in next, v.rules do
+ local l = vv.lookups
+ if l then
+ vv.lookups = pack(l)
+ end
+ local c = vv.coverage
+ if c then
+ c.before = c.before and pack(c.before )
+ c.after = c.after and pack(c.after )
+ c.current = c.current and pack(c.current)
+ end
+ local c = vv.reversecoverage
+ if c then
+ c.before = c.before and pack(c.before )
+ c.after = c.after and pack(c.after )
+ c.current = c.current and pack(c.current)
+ end
+ end
+ end
+ end
+ end
+ if data.luatex then
+ local la = data.luatex.anchor_to_lookup
+ if la then
+ for lookup, ldata in next, la do
+ la[lookup] = pack(ldata)
+ end
+ end
+ local la = data.luatex.lookup_to_anchor
+ if la then
+ for lookup, ldata in next, la do
+ la[lookup] = pack(ldata)
+ end
+ end
+ local ls = data.luatex.sequences
+ if ls then
+ for feature, fdata in next, ls do
+ local flags = fdata.flags
+ if flags then
+ fdata.flags = pack(flags)
+ end
+ local subtables = fdata.subtables
+ if subtables then
+ fdata.subtables = pack(subtables)
+ end
+ local features = fdata.features
+ if features then
+ for script, sdata in next, features do
+ features[script] = pack(sdata)
+ end
+ end
+ end
+ end
+ local ls = data.luatex.lookups
+ if ls then
+ for lookup, fdata in next, ls do
+ local flags = fdata.flags
+ if flags then
+ fdata.flags = pack(flags)
+ end
+ local subtables = fdata.subtables
+ if subtables then
+ fdata.subtables = pack(subtables)
+ end
+ end
+ end
+ local lf = data.luatex.features
+ if lf then
+ for _, g in next, fonts.otf.glists do
+ local gl = lf[g]
+ if gl then
+ for feature, spec in next, gl do
+ gl[feature] = pack(spec)
+ end
+ end
+ end
+ end
+ end
+ if not success(1,pass) then
+ return
+ end
+ end
+ if #t > 0 then
+ for pass=1,2 do
+ local pack = (pass == 1 and pack_1) or pack_2
+ for k, v in next, data.glyphs do
+ local m = v.mykerns
+ if m then
+ v.mykerns = pack(m)
+ end
+ local m = v.math
+ if m then
+ local mk = m.kerns
+ if mk then
+ m.kerns = pack(mk)
+ end
+ end
+ local a = v.anchors
+ if a then
+ v.anchors = pack(a)
+ end
+ local l = v.lookups
+ if l then
+ for k,v in next, l do
+ for kk=1,#v do
+ v[kk] = pack(v[kk])
+ end
+ end
+ end
+ end
+ local ls = data.luatex.sequences
+ if ls then
+ for feature, fdata in next, ls do
+ fdata.features = pack(fdata.features)
+ end
+ end
+ if not success(2,pass) then
+--~ return
+ end
+ end
+ end
+ end
+end
+
+function fonts.otf.enhancers.unpack(data)
+ if data then
+ local t = data.tables
+ if t then
+ for k, v in next, data.glyphs do
+ local tv = t[v.boundingbox] if tv then v.boundingbox = tv end
+ local l = v.lookups
+ if l then
+ for k,v in next, l do
+ for i=1,#v do
+ local tv = t[v[i]] if tv then v[i] = tv end
+ local vi = v[i]
+ local what = vi[1]
+ if what == "pair" then
+ local tv = t[vi[3]] if tv then vi[3] = tv end
+ local tv = t[vi[4]] if tv then vi[4] = tv end
+ elseif what == "position" then
+ local tv = t[vi[2]] if tv then vi[2] = tv end
+ end
+ end
+ end
+ end
+ local m = v.mykerns
+ if m then
+ local tv = t[m] if tv then m = tv v.mykerns = m end -- secondary optimization
+ for k,v in next, m do
+ local tv = t[v] if tv then m[k] = tv end
+ end
+ end
+ local m = v.math
+ if m then
+ local mk = m.kerns
+ if mk then
+ local tv = t[mk] if tv then mk = tv m.kerns = mk end -- secondary optimization
+ for k,v in next, mk do
+ local tv = t[v] if tv then mk[k] = tv end
+ end
+ end
+ end
+ local a = v.anchors
+ if a then
+ local tv = t[a] if tv then a = tv v.anchors = a end -- secondary optimization
+ for k,v in next, a do
+ if k == "baselig" then
+ for kk, vv in next, v do
+ for kkk=1,#vv do
+ local tv = t[vv[kkk]] if tv then vv[kkk] = tv end
+ end
+ end
+ else
+ for kk, vv in next, v do
+ local tv = t[vv] if tv then v[kk] = tv end
+ end
+ end
+ end
+ end
+ end
+ if data.lookups then
+ for k, v in next, data.lookups do
+ local r = v.rules
+ if r then
+ for kk, vv in next, r do
+ local l = vv.lookups
+ if l then
+ local tv = t[l] if tv then vv.lookups = tv end
+ end
+ local c = vv.coverage
+ if c then
+ local cc = c.before if cc then local tv = t[cc] if tv then c.before = tv end end
+ cc = c.after if cc then local tv = t[cc] if tv then c.after = tv end end
+ cc = c.current if cc then local tv = t[cc] if tv then c.current = tv end end
+ end
+ local c = vv.reversecoverage
+ if c then
+ local cc = c.before if cc then local tv = t[cc] if tv then c.before = tv end end
+ cc = c.after if cc then local tv = t[cc] if tv then c.after = tv end end
+ cc = c.current if cc then local tv = t[cc] if tv then c.current = tv end end
+ end
+ end
+ end
+ end
+ end
+ local luatex = data.luatex
+ if luatex then
+ local la = luatex.anchor_to_lookup
+ if la then
+ for lookup, ldata in next, la do
+ local tv = t[ldata] if tv then la[lookup] = tv end
+ end
+ end
+ local la = luatex.lookup_to_anchor
+ if la then
+ for lookup, ldata in next, la do
+ local tv = t[ldata] if tv then la[lookup] = tv end
+ end
+ end
+ local ls = luatex.sequences
+ if ls then
+ for feature, fdata in next, ls do
+ local flags = fdata.flags
+ if flags then
+ local tv = t[flags] if tv then fdata.flags = tv end
+ end
+ local subtables = fdata.subtables
+ if subtables then
+ local tv = t[subtables] if tv then fdata.subtables = tv end
+ end
+ local features = fdata.features
+ if features then
+ local tv = t[features] if tv then fdata.features = tv features = tv end -- secondary pack
+ for script, sdata in next, features do
+ local tv = t[sdata] if tv then features[script] = tv end
+ end
+ end
+ end
+ end
+ local ls = luatex.lookups
+ if ls then
+ for lookups, fdata in next, ls do
+ local flags = fdata.flags
+ if flags then
+ local tv = t[flags] if tv then fdata.flags = tv end
+ end
+ local subtables = fdata.subtables
+ if subtables then
+ local tv = t[subtables] if tv then fdata.subtables = tv end
+ end
+ end
+ end
+ local lf = luatex.features
+ if lf then
+ for _, g in next, fonts.otf.glists do
+ local gl = lf[g]
+ if gl then
+ for feature, spec in next, gl do
+ local tv = t[spec] if tv then gl[feature] = tv end
+ end
+ end
+ end
+ end
+ end
+ data.tables = nil
+ end
+ end
+end
diff --git a/tex/context/base/font-ott.lua b/tex/context/base/font-ott.lua
new file mode 100644
index 000000000..6676ff64b
--- /dev/null
+++ b/tex/context/base/font-ott.lua
@@ -0,0 +1,935 @@
+if not modules then modules = { } end modules ['font-otf'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (tables)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+local gsub, lower = string.gsub, string.lower
+
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+
+local otf = fonts.otf
+
+otf.tables = otf.tables or { }
+otf.meanings = otf.meanings or { }
+
+otf.tables.scripts = {
+ ['dflt'] = 'Default',
+
+ ['arab'] = 'Arabic',
+ ['armn'] = 'Armenian',
+ ['bali'] = 'Balinese',
+ ['beng'] = 'Bengali',
+ ['bopo'] = 'Bopomofo',
+ ['brai'] = 'Braille',
+ ['bugi'] = 'Buginese',
+ ['buhd'] = 'Buhid',
+ ['byzm'] = 'Byzantine Music',
+ ['cans'] = 'Canadian Syllabics',
+ ['cher'] = 'Cherokee',
+ ['copt'] = 'Coptic',
+ ['cprt'] = 'Cypriot Syllabary',
+ ['cyrl'] = 'Cyrillic',
+ ['deva'] = 'Devanagari',
+ ['dsrt'] = 'Deseret',
+ ['ethi'] = 'Ethiopic',
+ ['geor'] = 'Georgian',
+ ['glag'] = 'Glagolitic',
+ ['goth'] = 'Gothic',
+ ['grek'] = 'Greek',
+ ['gujr'] = 'Gujarati',
+ ['guru'] = 'Gurmukhi',
+ ['hang'] = 'Hangul',
+ ['hani'] = 'CJK Ideographic',
+ ['hano'] = 'Hanunoo',
+ ['hebr'] = 'Hebrew',
+ ['ital'] = 'Old Italic',
+ ['jamo'] = 'Hangul Jamo',
+ ['java'] = 'Javanese',
+ ['kana'] = 'Hiragana and Katakana',
+ ['khar'] = 'Kharosthi',
+ ['khmr'] = 'Khmer',
+ ['knda'] = 'Kannada',
+ ['lao' ] = 'Lao',
+ ['latn'] = 'Latin',
+ ['limb'] = 'Limbu',
+ ['linb'] = 'Linear B',
+ ['math'] = 'Mathematical Alphanumeric Symbols',
+ ['mlym'] = 'Malayalam',
+ ['mong'] = 'Mongolian',
+ ['musc'] = 'Musical Symbols',
+ ['mymr'] = 'Myanmar',
+ ['nko' ] = "N'ko",
+ ['ogam'] = 'Ogham',
+ ['orya'] = 'Oriya',
+ ['osma'] = 'Osmanya',
+ ['phag'] = 'Phags-pa',
+ ['phnx'] = 'Phoenician',
+ ['runr'] = 'Runic',
+ ['shaw'] = 'Shavian',
+ ['sinh'] = 'Sinhala',
+ ['sylo'] = 'Syloti Nagri',
+ ['syrc'] = 'Syriac',
+ ['tagb'] = 'Tagbanwa',
+ ['tale'] = 'Tai Le',
+ ['talu'] = 'Tai Lu',
+ ['taml'] = 'Tamil',
+ ['telu'] = 'Telugu',
+ ['tfng'] = 'Tifinagh',
+ ['tglg'] = 'Tagalog',
+ ['thaa'] = 'Thaana',
+ ['thai'] = 'Thai',
+ ['tibt'] = 'Tibetan',
+ ['ugar'] = 'Ugaritic Cuneiform',
+ ['xpeo'] = 'Old Persian Cuneiform',
+ ['xsux'] = 'Sumero-Akkadian Cuneiform',
+ ['yi' ] = 'Yi'
+}
+
+otf.tables.languages = {
+ ['dflt'] = 'Default',
+
+ ['aba'] = 'Abaza',
+ ['abk'] = 'Abkhazian',
+ ['ady'] = 'Adyghe',
+ ['afk'] = 'Afrikaans',
+ ['afr'] = 'Afar',
+ ['agw'] = 'Agaw',
+ ['als'] = 'Alsatian',
+ ['alt'] = 'Altai',
+ ['amh'] = 'Amharic',
+ ['ara'] = 'Arabic',
+ ['ari'] = 'Aari',
+ ['ark'] = 'Arakanese',
+ ['asm'] = 'Assamese',
+ ['ath'] = 'Athapaskan',
+ ['avr'] = 'Avar',
+ ['awa'] = 'Awadhi',
+ ['aym'] = 'Aymara',
+ ['aze'] = 'Azeri',
+ ['bad'] = 'Badaga',
+ ['bag'] = 'Baghelkhandi',
+ ['bal'] = 'Balkar',
+ ['bau'] = 'Baule',
+ ['bbr'] = 'Berber',
+ ['bch'] = 'Bench',
+ ['bcr'] = 'Bible Cree',
+ ['bel'] = 'Belarussian',
+ ['bem'] = 'Bemba',
+ ['ben'] = 'Bengali',
+ ['bgr'] = 'Bulgarian',
+ ['bhi'] = 'Bhili',
+ ['bho'] = 'Bhojpuri',
+ ['bik'] = 'Bikol',
+ ['bil'] = 'Bilen',
+ ['bkf'] = 'Blackfoot',
+ ['bli'] = 'Balochi',
+ ['bln'] = 'Balante',
+ ['blt'] = 'Balti',
+ ['bmb'] = 'Bambara',
+ ['bml'] = 'Bamileke',
+ ['bos'] = 'Bosnian',
+ ['bre'] = 'Breton',
+ ['brh'] = 'Brahui',
+ ['bri'] = 'Braj Bhasha',
+ ['brm'] = 'Burmese',
+ ['bsh'] = 'Bashkir',
+ ['bti'] = 'Beti',
+ ['cat'] = 'Catalan',
+ ['ceb'] = 'Cebuano',
+ ['che'] = 'Chechen',
+ ['chg'] = 'Chaha Gurage',
+ ['chh'] = 'Chattisgarhi',
+ ['chi'] = 'Chichewa',
+ ['chk'] = 'Chukchi',
+ ['chp'] = 'Chipewyan',
+ ['chr'] = 'Cherokee',
+ ['chu'] = 'Chuvash',
+ ['cmr'] = 'Comorian',
+ ['cop'] = 'Coptic',
+ ['cos'] = 'Corsican',
+ ['cre'] = 'Cree',
+ ['crr'] = 'Carrier',
+ ['crt'] = 'Crimean Tatar',
+ ['csl'] = 'Church Slavonic',
+ ['csy'] = 'Czech',
+ ['dan'] = 'Danish',
+ ['dar'] = 'Dargwa',
+ ['dcr'] = 'Woods Cree',
+ ['deu'] = 'German',
+ ['dgr'] = 'Dogri',
+ ['div'] = 'Divehi',
+ ['djr'] = 'Djerma',
+ ['dng'] = 'Dangme',
+ ['dnk'] = 'Dinka',
+ ['dri'] = 'Dari',
+ ['dun'] = 'Dungan',
+ ['dzn'] = 'Dzongkha',
+ ['ebi'] = 'Ebira',
+ ['ecr'] = 'Eastern Cree',
+ ['edo'] = 'Edo',
+ ['efi'] = 'Efik',
+ ['ell'] = 'Greek',
+ ['eng'] = 'English',
+ ['erz'] = 'Erzya',
+ ['esp'] = 'Spanish',
+ ['eti'] = 'Estonian',
+ ['euq'] = 'Basque',
+ ['evk'] = 'Evenki',
+ ['evn'] = 'Even',
+ ['ewe'] = 'Ewe',
+ ['fan'] = 'French Antillean',
+ ['far'] = 'Farsi',
+ ['fin'] = 'Finnish',
+ ['fji'] = 'Fijian',
+ ['fle'] = 'Flemish',
+ ['fne'] = 'Forest Nenets',
+ ['fon'] = 'Fon',
+ ['fos'] = 'Faroese',
+ ['fra'] = 'French',
+ ['fri'] = 'Frisian',
+ ['frl'] = 'Friulian',
+ ['fta'] = 'Futa',
+ ['ful'] = 'Fulani',
+ ['gad'] = 'Ga',
+ ['gae'] = 'Gaelic',
+ ['gag'] = 'Gagauz',
+ ['gal'] = 'Galician',
+ ['gar'] = 'Garshuni',
+ ['gaw'] = 'Garhwali',
+ ['gez'] = "Ge'ez",
+ ['gil'] = 'Gilyak',
+ ['gmz'] = 'Gumuz',
+ ['gon'] = 'Gondi',
+ ['grn'] = 'Greenlandic',
+ ['gro'] = 'Garo',
+ ['gua'] = 'Guarani',
+ ['guj'] = 'Gujarati',
+ ['hai'] = 'Haitian',
+ ['hal'] = 'Halam',
+ ['har'] = 'Harauti',
+ ['hau'] = 'Hausa',
+ ['haw'] = 'Hawaiin',
+ ['hbn'] = 'Hammer-Banna',
+ ['hil'] = 'Hiligaynon',
+ ['hin'] = 'Hindi',
+ ['hma'] = 'High Mari',
+ ['hnd'] = 'Hindko',
+ ['ho'] = 'Ho',
+ ['hri'] = 'Harari',
+ ['hrv'] = 'Croatian',
+ ['hun'] = 'Hungarian',
+ ['hye'] = 'Armenian',
+ ['ibo'] = 'Igbo',
+ ['ijo'] = 'Ijo',
+ ['ilo'] = 'Ilokano',
+ ['ind'] = 'Indonesian',
+ ['ing'] = 'Ingush',
+ ['inu'] = 'Inuktitut',
+ ['iri'] = 'Irish',
+ ['irt'] = 'Irish Traditional',
+ ['isl'] = 'Icelandic',
+ ['ism'] = 'Inari Sami',
+ ['ita'] = 'Italian',
+ ['iwr'] = 'Hebrew',
+ ['jan'] = 'Japanese',
+ ['jav'] = 'Javanese',
+ ['jii'] = 'Yiddish',
+ ['jud'] = 'Judezmo',
+ ['jul'] = 'Jula',
+ ['kab'] = 'Kabardian',
+ ['kac'] = 'Kachchi',
+ ['kal'] = 'Kalenjin',
+ ['kan'] = 'Kannada',
+ ['kar'] = 'Karachay',
+ ['kat'] = 'Georgian',
+ ['kaz'] = 'Kazakh',
+ ['keb'] = 'Kebena',
+ ['kge'] = 'Khutsuri Georgian',
+ ['kha'] = 'Khakass',
+ ['khk'] = 'Khanty-Kazim',
+ ['khm'] = 'Khmer',
+ ['khs'] = 'Khanty-Shurishkar',
+ ['khv'] = 'Khanty-Vakhi',
+ ['khw'] = 'Khowar',
+ ['kik'] = 'Kikuyu',
+ ['kir'] = 'Kirghiz',
+ ['kis'] = 'Kisii',
+ ['kkn'] = 'Kokni',
+ ['klm'] = 'Kalmyk',
+ ['kmb'] = 'Kamba',
+ ['kmn'] = 'Kumaoni',
+ ['kmo'] = 'Komo',
+ ['kms'] = 'Komso',
+ ['knr'] = 'Kanuri',
+ ['kod'] = 'Kodagu',
+ ['koh'] = 'Korean Old Hangul',
+ ['kok'] = 'Konkani',
+ ['kon'] = 'Kikongo',
+ ['kop'] = 'Komi-Permyak',
+ ['kor'] = 'Korean',
+ ['koz'] = 'Komi-Zyrian',
+ ['kpl'] = 'Kpelle',
+ ['kri'] = 'Krio',
+ ['krk'] = 'Karakalpak',
+ ['krl'] = 'Karelian',
+ ['krm'] = 'Karaim',
+ ['krn'] = 'Karen',
+ ['krt'] = 'Koorete',
+ ['ksh'] = 'Kashmiri',
+ ['ksi'] = 'Khasi',
+ ['ksm'] = 'Kildin Sami',
+ ['kui'] = 'Kui',
+ ['kul'] = 'Kulvi',
+ ['kum'] = 'Kumyk',
+ ['kur'] = 'Kurdish',
+ ['kuu'] = 'Kurukh',
+ ['kuy'] = 'Kuy',
+ ['kyk'] = 'Koryak',
+ ['lad'] = 'Ladin',
+ ['lah'] = 'Lahuli',
+ ['lak'] = 'Lak',
+ ['lam'] = 'Lambani',
+ ['lao'] = 'Lao',
+ ['lat'] = 'Latin',
+ ['laz'] = 'Laz',
+ ['lcr'] = 'L-Cree',
+ ['ldk'] = 'Ladakhi',
+ ['lez'] = 'Lezgi',
+ ['lin'] = 'Lingala',
+ ['lma'] = 'Low Mari',
+ ['lmb'] = 'Limbu',
+ ['lmw'] = 'Lomwe',
+ ['lsb'] = 'Lower Sorbian',
+ ['lsm'] = 'Lule Sami',
+ ['lth'] = 'Lithuanian',
+ ['ltz'] = 'Luxembourgish',
+ ['lub'] = 'Luba',
+ ['lug'] = 'Luganda',
+ ['luh'] = 'Luhya',
+ ['luo'] = 'Luo',
+ ['lvi'] = 'Latvian',
+ ['maj'] = 'Majang',
+ ['mak'] = 'Makua',
+ ['mal'] = 'Malayalam Traditional',
+ ['man'] = 'Mansi',
+ ['map'] = 'Mapudungun',
+ ['mar'] = 'Marathi',
+ ['maw'] = 'Marwari',
+ ['mbn'] = 'Mbundu',
+ ['mch'] = 'Manchu',
+ ['mcr'] = 'Moose Cree',
+ ['mde'] = 'Mende',
+ ['men'] = "Me'en",
+ ['miz'] = 'Mizo',
+ ['mkd'] = 'Macedonian',
+ ['mle'] = 'Male',
+ ['mlg'] = 'Malagasy',
+ ['mln'] = 'Malinke',
+ ['mlr'] = 'Malayalam Reformed',
+ ['mly'] = 'Malay',
+ ['mnd'] = 'Mandinka',
+ ['mng'] = 'Mongolian',
+ ['mni'] = 'Manipuri',
+ ['mnk'] = 'Maninka',
+ ['mnx'] = 'Manx Gaelic',
+ ['moh'] = 'Mohawk',
+ ['mok'] = 'Moksha',
+ ['mol'] = 'Moldavian',
+ ['mon'] = 'Mon',
+ ['mor'] = 'Moroccan',
+ ['mri'] = 'Maori',
+ ['mth'] = 'Maithili',
+ ['mts'] = 'Maltese',
+ ['mun'] = 'Mundari',
+ ['nag'] = 'Naga-Assamese',
+ ['nan'] = 'Nanai',
+ ['nas'] = 'Naskapi',
+ ['ncr'] = 'N-Cree',
+ ['ndb'] = 'Ndebele',
+ ['ndg'] = 'Ndonga',
+ ['nep'] = 'Nepali',
+ ['new'] = 'Newari',
+ ['ngr'] = 'Nagari',
+ ['nhc'] = 'Norway House Cree',
+ ['nis'] = 'Nisi',
+ ['niu'] = 'Niuean',
+ ['nkl'] = 'Nkole',
+ ['nko'] = "N'ko",
+ ['nld'] = 'Dutch',
+ ['nog'] = 'Nogai',
+ ['nor'] = 'Norwegian',
+ ['nsm'] = 'Northern Sami',
+ ['nta'] = 'Northern Tai',
+ ['nto'] = 'Esperanto',
+ ['nyn'] = 'Nynorsk',
+ ['oci'] = 'Occitan',
+ ['ocr'] = 'Oji-Cree',
+ ['ojb'] = 'Ojibway',
+ ['ori'] = 'Oriya',
+ ['oro'] = 'Oromo',
+ ['oss'] = 'Ossetian',
+ ['paa'] = 'Palestinian Aramaic',
+ ['pal'] = 'Pali',
+ ['pan'] = 'Punjabi',
+ ['pap'] = 'Palpa',
+ ['pas'] = 'Pashto',
+ ['pgr'] = 'Polytonic Greek',
+ ['pil'] = 'Pilipino',
+ ['plg'] = 'Palaung',
+ ['plk'] = 'Polish',
+ ['pro'] = 'Provencal',
+ ['ptg'] = 'Portuguese',
+ ['qin'] = 'Chin',
+ ['raj'] = 'Rajasthani',
+ ['rbu'] = 'Russian Buriat',
+ ['rcr'] = 'R-Cree',
+ ['ria'] = 'Riang',
+ ['rms'] = 'Rhaeto-Romanic',
+ ['rom'] = 'Romanian',
+ ['roy'] = 'Romany',
+ ['rsy'] = 'Rusyn',
+ ['rua'] = 'Ruanda',
+ ['rus'] = 'Russian',
+ ['sad'] = 'Sadri',
+ ['san'] = 'Sanskrit',
+ ['sat'] = 'Santali',
+ ['say'] = 'Sayisi',
+ ['sek'] = 'Sekota',
+ ['sel'] = 'Selkup',
+ ['sgo'] = 'Sango',
+ ['shn'] = 'Shan',
+ ['sib'] = 'Sibe',
+ ['sid'] = 'Sidamo',
+ ['sig'] = 'Silte Gurage',
+ ['sks'] = 'Skolt Sami',
+ ['sky'] = 'Slovak',
+ ['sla'] = 'Slavey',
+ ['slv'] = 'Slovenian',
+ ['sml'] = 'Somali',
+ ['smo'] = 'Samoan',
+ ['sna'] = 'Sena',
+ ['snd'] = 'Sindhi',
+ ['snh'] = 'Sinhalese',
+ ['snk'] = 'Soninke',
+ ['sog'] = 'Sodo Gurage',
+ ['sot'] = 'Sotho',
+ ['sqi'] = 'Albanian',
+ ['srb'] = 'Serbian',
+ ['srk'] = 'Saraiki',
+ ['srr'] = 'Serer',
+ ['ssl'] = 'South Slavey',
+ ['ssm'] = 'Southern Sami',
+ ['sur'] = 'Suri',
+ ['sva'] = 'Svan',
+ ['sve'] = 'Swedish',
+ ['swa'] = 'Swadaya Aramaic',
+ ['swk'] = 'Swahili',
+ ['swz'] = 'Swazi',
+ ['sxt'] = 'Sutu',
+ ['syr'] = 'Syriac',
+ ['tab'] = 'Tabasaran',
+ ['taj'] = 'Tajiki',
+ ['tam'] = 'Tamil',
+ ['tat'] = 'Tatar',
+ ['tcr'] = 'TH-Cree',
+ ['tel'] = 'Telugu',
+ ['tgn'] = 'Tongan',
+ ['tgr'] = 'Tigre',
+ ['tgy'] = 'Tigrinya',
+ ['tha'] = 'Thai',
+ ['tht'] = 'Tahitian',
+ ['tib'] = 'Tibetan',
+ ['tkm'] = 'Turkmen',
+ ['tmn'] = 'Temne',
+ ['tna'] = 'Tswana',
+ ['tne'] = 'Tundra Nenets',
+ ['tng'] = 'Tonga',
+ ['tod'] = 'Todo',
+ ['trk'] = 'Turkish',
+ ['tsg'] = 'Tsonga',
+ ['tua'] = 'Turoyo Aramaic',
+ ['tul'] = 'Tulu',
+ ['tuv'] = 'Tuvin',
+ ['twi'] = 'Twi',
+ ['udm'] = 'Udmurt',
+ ['ukr'] = 'Ukrainian',
+ ['urd'] = 'Urdu',
+ ['usb'] = 'Upper Sorbian',
+ ['uyg'] = 'Uyghur',
+ ['uzb'] = 'Uzbek',
+ ['ven'] = 'Venda',
+ ['vit'] = 'Vietnamese',
+ ['wa' ] = 'Wa',
+ ['wag'] = 'Wagdi',
+ ['wcr'] = 'West-Cree',
+ ['wel'] = 'Welsh',
+ ['wlf'] = 'Wolof',
+ ['xbd'] = 'Tai Lue',
+ ['xhs'] = 'Xhosa',
+ ['yak'] = 'Yakut',
+ ['yba'] = 'Yoruba',
+ ['ycr'] = 'Y-Cree',
+ ['yic'] = 'Yi Classic',
+ ['yim'] = 'Yi Modern',
+ ['zhh'] = 'Chinese Hong Kong',
+ ['zhp'] = 'Chinese Phonetic',
+ ['zhs'] = 'Chinese Simplified',
+ ['zht'] = 'Chinese Traditional',
+ ['znd'] = 'Zande',
+ ['zul'] = 'Zulu'
+}
+
+otf.tables.features = {
+ ['aalt'] = 'Access All Alternates',
+ ['abvf'] = 'Above-Base Forms',
+ ['abvm'] = 'Above-Base Mark Positioning',
+ ['abvs'] = 'Above-Base Substitutions',
+ ['afrc'] = 'Alternative Fractions',
+ ['akhn'] = 'Akhands',
+ ['blwf'] = 'Below-Base Forms',
+ ['blwm'] = 'Below-Base Mark Positioning',
+ ['blws'] = 'Below-Base Substitutions',
+ ['c2pc'] = 'Petite Capitals From Capitals',
+ ['c2sc'] = 'Small Capitals From Capitals',
+ ['calt'] = 'Contextual Alternates',
+ ['case'] = 'Case-Sensitive Forms',
+ ['ccmp'] = 'Glyph Composition/Decomposition',
+ ['cjct'] = 'Conjunct Forms',
+ ['clig'] = 'Contextual Ligatures',
+ ['cpsp'] = 'Capital Spacing',
+ ['cswh'] = 'Contextual Swash',
+ ['curs'] = 'Cursive Positioning',
+ ['dflt'] = 'Default Processing',
+ ['dist'] = 'Distances',
+ ['dlig'] = 'Discretionary Ligatures',
+ ['dnom'] = 'Denominators',
+ ['dtls'] = 'Dotless Forms', -- math
+ ['expt'] = 'Expert Forms',
+ ['falt'] = 'Final glyph Alternates',
+ ['fin2'] = 'Terminal Forms #2',
+ ['fin3'] = 'Terminal Forms #3',
+ ['fina'] = 'Terminal Forms',
+ ['flac'] = 'Flattened Accents Over Capitals', -- math
+ ['frac'] = 'Fractions',
+ ['fwid'] = 'Full Width',
+ ['half'] = 'Half Forms',
+ ['haln'] = 'Halant Forms',
+ ['halt'] = 'Alternate Half Width',
+ ['hist'] = 'Historical Forms',
+ ['hkna'] = 'Horizontal Kana Alternates',
+ ['hlig'] = 'Historical Ligatures',
+ ['hngl'] = 'Hangul',
+ ['hojo'] = 'Hojo Kanji Forms',
+ ['hwid'] = 'Half Width',
+ ['init'] = 'Initial Forms',
+ ['isol'] = 'Isolated Forms',
+ ['ital'] = 'Italics',
+ ['jalt'] = 'Justification Alternatives',
+ ['jp04'] = 'JIS2004 Forms',
+ ['jp78'] = 'JIS78 Forms',
+ ['jp83'] = 'JIS83 Forms',
+ ['jp90'] = 'JIS90 Forms',
+ ['kern'] = 'Kerning',
+ ['lfbd'] = 'Left Bounds',
+ ['liga'] = 'Standard Ligatures',
+ ['ljmo'] = 'Leading Jamo Forms',
+ ['lnum'] = 'Lining Figures',
+ ['locl'] = 'Localized Forms',
+ ['mark'] = 'Mark Positioning',
+ ['med2'] = 'Medial Forms #2',
+ ['medi'] = 'Medial Forms',
+ ['mgrk'] = 'Mathematical Greek',
+ ['mkmk'] = 'Mark to Mark Positioning',
+ ['mset'] = 'Mark Positioning via Substitution',
+ ['nalt'] = 'Alternate Annotation Forms',
+ ['nlck'] = 'NLC Kanji Forms',
+ ['nukt'] = 'Nukta Forms',
+ ['numr'] = 'Numerators',
+ ['onum'] = 'Old Style Figures',
+ ['opbd'] = 'Optical Bounds',
+ ['ordn'] = 'Ordinals',
+ ['ornm'] = 'Ornaments',
+ ['palt'] = 'Proportional Alternate Width',
+ ['pcap'] = 'Petite Capitals',
+ ['pnum'] = 'Proportional Figures',
+ ['pref'] = 'Pre-base Forms',
+ ['pres'] = 'Pre-base Substitutions',
+ ['pstf'] = 'Post-base Forms',
+ ['psts'] = 'Post-base Substitutions',
+ ['pwid'] = 'Proportional Widths',
+ ['qwid'] = 'Quarter Widths',
+ ['rand'] = 'Randomize',
+ ['rkrf'] = 'Rakar Forms',
+ ['rlig'] = 'Required Ligatures',
+ ['rphf'] = 'Reph Form',
+ ['rtbd'] = 'Right Bounds',
+ ['rtla'] = 'Right-To-Left Alternates',
+ ['ruby'] = 'Ruby Notation Forms',
+ ['salt'] = 'Stylistic Alternates',
+ ['sinf'] = 'Scientific Inferiors',
+ ['size'] = 'Optical Size',
+ ['smcp'] = 'Small Capitals',
+ ['smpl'] = 'Simplified Forms',
+ ['ss01'] = 'Stylistic Set 1',
+ ['ss02'] = 'Stylistic Set 2',
+ ['ss03'] = 'Stylistic Set 3',
+ ['ss04'] = 'Stylistic Set 4',
+ ['ss05'] = 'Stylistic Set 5',
+ ['ss06'] = 'Stylistic Set 6',
+ ['ss07'] = 'Stylistic Set 7',
+ ['ss08'] = 'Stylistic Set 8',
+ ['ss09'] = 'Stylistic Set 9',
+ ['ss10'] = 'Stylistic Set 10',
+ ['ss11'] = 'Stylistic Set 11',
+ ['ss12'] = 'Stylistic Set 12',
+ ['ss13'] = 'Stylistic Set 13',
+ ['ss14'] = 'Stylistic Set 14',
+ ['ss15'] = 'Stylistic Set 15',
+ ['ss16'] = 'Stylistic Set 16',
+ ['ss17'] = 'Stylistic Set 17',
+ ['ss18'] = 'Stylistic Set 18',
+ ['ss19'] = 'Stylistic Set 19',
+ ['ss20'] = 'Stylistic Set 20',
+ ['ssty'] = 'Script Style', -- math
+ ['subs'] = 'Subscript',
+ ['sups'] = 'Superscript',
+ ['swsh'] = 'Swash',
+ ['titl'] = 'Titling',
+ ['tjmo'] = 'Trailing Jamo Forms',
+ ['tnam'] = 'Traditional Name Forms',
+ ['tnum'] = 'Tabular Figures',
+ ['trad'] = 'Traditional Forms',
+ ['twid'] = 'Third Widths',
+ ['unic'] = 'Unicase',
+ ['valt'] = 'Alternate Vertical Metrics',
+ ['vatu'] = 'Vattu Variants',
+ ['vert'] = 'Vertical Writing',
+ ['vhal'] = 'Alternate Vertical Half Metrics',
+ ['vjmo'] = 'Vowel Jamo Forms',
+ ['vkna'] = 'Vertical Kana Alternates',
+ ['vkrn'] = 'Vertical Kerning',
+ ['vpal'] = 'Proportional Alternate Vertical Metrics',
+ ['vrt2'] = 'Vertical Rotation',
+ ['zero'] = 'Slashed Zero',
+
+ ['trep'] = 'Traditional TeX Replacements',
+ ['tlig'] = 'Traditional TeX Ligatures',
+}
+
+otf.tables.baselines = {
+ ['hang'] = 'Hanging baseline',
+ ['icfb'] = 'Ideographic character face bottom edge baseline',
+ ['icft'] = 'Ideographic character face tope edige baseline',
+ ['ideo'] = 'Ideographic em-box bottom edge baseline',
+ ['idtp'] = 'Ideographic em-box top edge baseline',
+ ['math'] = 'Mathmatical centered baseline',
+ ['romn'] = 'Roman baseline'
+}
+
+-- can be sped up by local tables
+
+function otf.tables.to_tag(id)
+ return stringformat("%4s",lower(id))
+end
+
+local function resolve(tab,id)
+ if tab and id then
+ id = lower(id)
+ return tab[id] or tab[gsub(id," ","")] or tab['dflt'] or ''
+ else
+ return "unknown"
+ end
+end
+
+function otf.meanings.script(id)
+ return resolve(otf.tables.scripts,id)
+end
+function otf.meanings.language(id)
+ return resolve(otf.tables.languages,id)
+end
+function otf.meanings.feature(id)
+ return resolve(otf.tables.features,id)
+end
+function otf.meanings.baseline(id)
+ return resolve(otf.tables.baselines,id)
+end
+
+otf.tables.to_scripts = table.reverse_hash(otf.tables.scripts )
+otf.tables.to_languages = table.reverse_hash(otf.tables.languages)
+otf.tables.to_features = table.reverse_hash(otf.tables.features )
+
+local scripts = otf.tables.scripts
+local languages = otf.tables.languages
+local features = otf.tables.features
+
+local to_scripts = otf.tables.to_scripts
+local to_languages = otf.tables.to_languages
+local to_features = otf.tables.to_features
+
+function otf.meanings.normalize(features)
+ local h = { }
+ for k,v in next, features do
+ k = lower(k)
+ if k == "language" or k == "lang" then
+ v = gsub(lower(v),"[^a-z0-9%-]","")
+ k = language
+ if not languages[v] then
+ h.language = to_languages[v] or "dflt"
+ else
+ h.language = v
+ end
+ elseif k == "script" then
+ v = gsub(lower(v),"[^a-z0-9%-]","")
+ if not scripts[v] then
+ h.script = to_scripts[v] or "dflt"
+ else
+ h.script = v
+ end
+ else
+ if type(v) == "string" then
+ local b = v:is_boolean()
+ if type(b) == "nil" then
+ v = tonumber(v) or lower(v)
+ else
+ v = b
+ end
+ end
+ h[to_features[k] or k] = v
+ end
+ end
+ return h
+end
+
+-- When I feel the need ...
+
+--~ otf.tables.aat = {
+--~ [ 0] = {
+--~ name = "allTypographicFeaturesType",
+--~ [ 0] = "allTypeFeaturesOnSelector",
+--~ [ 1] = "allTypeFeaturesOffSelector",
+--~ },
+--~ [ 1] = {
+--~ name = "ligaturesType",
+--~ [0 ] = "requiredLigaturesOnSelector",
+--~ [1 ] = "requiredLigaturesOffSelector",
+--~ [2 ] = "commonLigaturesOnSelector",
+--~ [3 ] = "commonLigaturesOffSelector",
+--~ [4 ] = "rareLigaturesOnSelector",
+--~ [5 ] = "rareLigaturesOffSelector",
+--~ [6 ] = "logosOnSelector ",
+--~ [7 ] = "logosOffSelector ",
+--~ [8 ] = "rebusPicturesOnSelector",
+--~ [9 ] = "rebusPicturesOffSelector",
+--~ [10] = "diphthongLigaturesOnSelector",
+--~ [11] = "diphthongLigaturesOffSelector",
+--~ [12] = "squaredLigaturesOnSelector",
+--~ [13] = "squaredLigaturesOffSelector",
+--~ [14] = "abbrevSquaredLigaturesOnSelector",
+--~ [15] = "abbrevSquaredLigaturesOffSelector",
+--~ },
+--~ [ 2] = {
+--~ name = "cursiveConnectionType",
+--~ [ 0] = "unconnectedSelector",
+--~ [ 1] = "partiallyConnectedSelector",
+--~ [ 2] = "cursiveSelector ",
+--~ },
+--~ [ 3] = {
+--~ name = "letterCaseType",
+--~ [ 0] = "upperAndLowerCaseSelector",
+--~ [ 1] = "allCapsSelector ",
+--~ [ 2] = "allLowerCaseSelector",
+--~ [ 3] = "smallCapsSelector ",
+--~ [ 4] = "initialCapsSelector",
+--~ [ 5] = "initialCapsAndSmallCapsSelector",
+--~ },
+--~ [ 4] = {
+--~ name = "verticalSubstitutionType",
+--~ [ 0] = "substituteVerticalFormsOnSelector",
+--~ [ 1] = "substituteVerticalFormsOffSelector",
+--~ },
+--~ [ 5] = {
+--~ name = "linguisticRearrangementType",
+--~ [ 0] = "linguisticRearrangementOnSelector",
+--~ [ 1] = "linguisticRearrangementOffSelector",
+--~ },
+--~ [ 6] = {
+--~ name = "numberSpacingType",
+--~ [ 0] = "monospacedNumbersSelector",
+--~ [ 1] = "proportionalNumbersSelector",
+--~ },
+--~ [ 7] = {
+--~ name = "appleReserved1Type",
+--~ },
+--~ [ 8] = {
+--~ name = "smartSwashType",
+--~ [ 0] = "wordInitialSwashesOnSelector",
+--~ [ 1] = "wordInitialSwashesOffSelector",
+--~ [ 2] = "wordFinalSwashesOnSelector",
+--~ [ 3] = "wordFinalSwashesOffSelector",
+--~ [ 4] = "lineInitialSwashesOnSelector",
+--~ [ 5] = "lineInitialSwashesOffSelector",
+--~ [ 6] = "lineFinalSwashesOnSelector",
+--~ [ 7] = "lineFinalSwashesOffSelector",
+--~ [ 8] = "nonFinalSwashesOnSelector",
+--~ [ 9] = "nonFinalSwashesOffSelector",
+--~ },
+--~ [ 9] = {
+--~ name = "diacriticsType",
+--~ [ 0] = "showDiacriticsSelector",
+--~ [ 1] = "hideDiacriticsSelector",
+--~ [ 2] = "decomposeDiacriticsSelector",
+--~ },
+--~ [10] = {
+--~ name = "verticalPositionType",
+--~ [ 0] = "normalPositionSelector",
+--~ [ 1] = "superiorsSelector ",
+--~ [ 2] = "inferiorsSelector ",
+--~ [ 3] = "ordinalsSelector ",
+--~ },
+--~ [11] = {
+--~ name = "fractionsType",
+--~ [ 0] = "noFractionsSelector",
+--~ [ 1] = "verticalFractionsSelector",
+--~ [ 2] = "diagonalFractionsSelector",
+--~ },
+--~ [12] = {
+--~ name = "appleReserved2Type",
+--~ },
+--~ [13] = {
+--~ name = "overlappingCharactersType",
+--~ [ 0] = "preventOverlapOnSelector",
+--~ [ 1] = "preventOverlapOffSelector",
+--~ },
+--~ [14] = {
+--~ name = "typographicExtrasType",
+--~ [0 ] = "hyphensToEmDashOnSelector",
+--~ [1 ] = "hyphensToEmDashOffSelector",
+--~ [2 ] = "hyphenToEnDashOnSelector",
+--~ [3 ] = "hyphenToEnDashOffSelector",
+--~ [4 ] = "unslashedZeroOnSelector",
+--~ [5 ] = "unslashedZeroOffSelector",
+--~ [6 ] = "formInterrobangOnSelector",
+--~ [7 ] = "formInterrobangOffSelector",
+--~ [8 ] = "smartQuotesOnSelector",
+--~ [9 ] = "smartQuotesOffSelector",
+--~ [10] = "periodsToEllipsisOnSelector",
+--~ [11] = "periodsToEllipsisOffSelector",
+--~ },
+--~ [15] = {
+--~ name = "mathematicalExtrasType",
+--~ [ 0] = "hyphenToMinusOnSelector",
+--~ [ 1] = "hyphenToMinusOffSelector",
+--~ [ 2] = "asteriskToMultiplyOnSelector",
+--~ [ 3] = "asteriskToMultiplyOffSelector",
+--~ [ 4] = "slashToDivideOnSelector",
+--~ [ 5] = "slashToDivideOffSelector",
+--~ [ 6] = "inequalityLigaturesOnSelector",
+--~ [ 7] = "inequalityLigaturesOffSelector",
+--~ [ 8] = "exponentsOnSelector",
+--~ [ 9] = "exponentsOffSelector",
+--~ },
+--~ [16] = {
+--~ name = "ornamentSetsType",
+--~ [ 0] = "noOrnamentsSelector",
+--~ [ 1] = "dingbatsSelector ",
+--~ [ 2] = "piCharactersSelector",
+--~ [ 3] = "fleuronsSelector ",
+--~ [ 4] = "decorativeBordersSelector",
+--~ [ 5] = "internationalSymbolsSelector",
+--~ [ 6] = "mathSymbolsSelector",
+--~ },
+--~ [17] = {
+--~ name = "characterAlternativesType",
+--~ [ 0] = "noAlternatesSelector",
+--~ },
+--~ [18] = {
+--~ name = "designComplexityType",
+--~ [ 0] = "designLevel1Selector",
+--~ [ 1] = "designLevel2Selector",
+--~ [ 2] = "designLevel3Selector",
+--~ [ 3] = "designLevel4Selector",
+--~ [ 4] = "designLevel5Selector",
+--~ },
+--~ [19] = {
+--~ name = "styleOptionsType",
+--~ [ 0] = "noStyleOptionsSelector",
+--~ [ 1] = "displayTextSelector",
+--~ [ 2] = "engravedTextSelector",
+--~ [ 3] = "illuminatedCapsSelector",
+--~ [ 4] = "titlingCapsSelector",
+--~ [ 5] = "tallCapsSelector ",
+--~ },
+--~ [20] = {
+--~ name = "characterShapeType",
+--~ [0 ] = "traditionalCharactersSelector",
+--~ [1 ] = "simplifiedCharactersSelector",
+--~ [2 ] = "jis1978CharactersSelector",
+--~ [3 ] = "jis1983CharactersSelector",
+--~ [4 ] = "jis1990CharactersSelector",
+--~ [5 ] = "traditionalAltOneSelector",
+--~ [6 ] = "traditionalAltTwoSelector",
+--~ [7 ] = "traditionalAltThreeSelector",
+--~ [8 ] = "traditionalAltFourSelector",
+--~ [9 ] = "traditionalAltFiveSelector",
+--~ [10] = "expertCharactersSelector",
+--~ },
+--~ [21] = {
+--~ name = "numberCaseType",
+--~ [ 0] = "lowerCaseNumbersSelector",
+--~ [ 1] = "upperCaseNumbersSelector",
+--~ },
+--~ [22] = {
+--~ name = "textSpacingType",
+--~ [ 0] = "proportionalTextSelector",
+--~ [ 1] = "monospacedTextSelector",
+--~ [ 2] = "halfWidthTextSelector",
+--~ [ 3] = "normallySpacedTextSelector",
+--~ },
+--~ [23] = {
+--~ name = "transliterationType",
+--~ [ 0] = "noTransliterationSelector",
+--~ [ 1] = "hanjaToHangulSelector",
+--~ [ 2] = "hiraganaToKatakanaSelector",
+--~ [ 3] = "katakanaToHiraganaSelector",
+--~ [ 4] = "kanaToRomanizationSelector",
+--~ [ 5] = "romanizationToHiraganaSelector",
+--~ [ 6] = "romanizationToKatakanaSelector",
+--~ [ 7] = "hanjaToHangulAltOneSelector",
+--~ [ 8] = "hanjaToHangulAltTwoSelector",
+--~ [ 9] = "hanjaToHangulAltThreeSelector",
+--~ },
+--~ [24] = {
+--~ name = "annotationType",
+--~ [ 0] = "noAnnotationSelector",
+--~ [ 1] = "boxAnnotationSelector",
+--~ [ 2] = "roundedBoxAnnotationSelector",
+--~ [ 3] = "circleAnnotationSelector",
+--~ [ 4] = "invertedCircleAnnotationSelector",
+--~ [ 5] = "parenthesisAnnotationSelector",
+--~ [ 6] = "periodAnnotationSelector",
+--~ [ 7] = "romanNumeralAnnotationSelector",
+--~ [ 8] = "diamondAnnotationSelector",
+--~ },
+--~ [25] = {
+--~ name = "kanaSpacingType",
+--~ [ 0] = "fullWidthKanaSelector",
+--~ [ 1] = "proportionalKanaSelector",
+--~ },
+--~ [26] = {
+--~ name = "ideographicSpacingType",
+--~ [ 0] = "fullWidthIdeographsSelector",
+--~ [ 1] = "proportionalIdeographsSelector",
+--~ },
+--~ [103] = {
+--~ name = "cjkRomanSpacingType",
+--~ [ 0] = "halfWidthCJKRomanSelector",
+--~ [ 1] = "proportionalCJKRomanSelector",
+--~ [ 2] = "defaultCJKRomanSelector",
+--~ [ 3] = "fullWidthCJKRomanSelector",
+--~ },
+--~ }
diff --git a/tex/context/base/font-pat.lua b/tex/context/base/font-pat.lua
index 8f1817ec2..ae91700a9 100644
--- a/tex/context/base/font-pat.lua
+++ b/tex/context/base/font-pat.lua
@@ -6,19 +6,56 @@ if not modules then modules = { } end modules ['font-pat'] = {
license = "see context related readme files"
}
+local match, lower = string.match, string.lower
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
-- older versions of latin modern didn't have the designsize set
-- so for them we get it from the name
-local patches = fonts.otf.enhance.patches
+local patches = fonts.otf.enhancers.patches
local function patch(data,filename)
if data.design_size == 0 then
- local ds = (file.basename(filename:lower())):match("(%d+)")
+ local ds = match(file.basename(lower(filename)),"(%d+)")
if ds then
- logs.report("load otf","patching design size (%s)",ds)
+ if trace_loading then
+ logs.report("load otf","patching design size (%s)",ds)
+ end
data.design_size = tonumber(ds) * 10
end
end
+ local uni_to_ind = data.map.map
+ if not uni_to_ind[0x391] then
+ -- beware, this is a hack, features for latin often don't apply to greek
+ -- but lm has not much features anyway (and only greek for math)
+ if trace_loading then
+ logs.report("load otf","adding 13 greek capitals")
+ end
+ uni_to_ind[0x391] = uni_to_ind[0x41]
+ uni_to_ind[0x392] = uni_to_ind[0x42]
+ uni_to_ind[0x395] = uni_to_ind[0x45]
+ uni_to_ind[0x397] = uni_to_ind[0x48]
+ uni_to_ind[0x399] = uni_to_ind[0x49]
+ uni_to_ind[0x39A] = uni_to_ind[0x4B]
+ uni_to_ind[0x39C] = uni_to_ind[0x4D]
+ uni_to_ind[0x39D] = uni_to_ind[0x4E]
+ uni_to_ind[0x39F] = uni_to_ind[0x4F]
+ uni_to_ind[0x3A1] = uni_to_ind[0x52]
+ uni_to_ind[0x3A4] = uni_to_ind[0x54]
+ uni_to_ind[0x3A7] = uni_to_ind[0x58]
+ uni_to_ind[0x396] = uni_to_ind[0x5A]
+ end
+ -- better make this into a feature
+ --
+ -- local glyphs = data.glyphs
+ -- for i=0x300,0x36F do
+ -- local c = glyphs[uni_to_ind[i]]
+ -- if c and c.width == 0 then
+ -- local boundingbox = c.boundingbox
+ -- c.width = boundingbox[3] - boundingbox[1]
+ -- end
+ -- end
end
patches["^lmroman"] = patch
@@ -30,10 +67,14 @@ patches["^lmtypewriter"] = patch
-- have the mkmk features properly set up
local function patch(data,filename)
- if data.gpos then
- for _, v in ipairs(data.gpos) do
+ local gpos = data.gpos
+ if gpos then
+ for k=1,#gpos do
+ local v = gpos[k]
if not v.features and v.type == "gpos_mark2mark" then
- logs.report("load otf","patching mkmk feature (name: %s)", v.name or "?")
+ if trace_loading then
+ logs.report("load otf","patching mkmk feature (name: %s)", v.name or "?")
+ end
v.features = {
{
scripts = {
diff --git a/tex/context/base/font-run.tex b/tex/context/base/font-run.tex
index 83da04b62..0a0ddd057 100644
--- a/tex/context/base/font-run.tex
+++ b/tex/context/base/font-run.tex
@@ -213,8 +213,7 @@
\processcommalist[#2]\docommand
\egroup
\else\ifsecondargument
- \showfontstyle[#1][#2][\alternativetextlist]%
- \doif{#2}{\c!mm}{\showfontstyle[#1][#2][\alternativemathlist]}%
+ \showfontstyle[#1][#2][\fontalternativelist]% math is gone
\else
\showfontstyle[#1][\c!rm]\showfontstyle[#1][\c!ss]
\showfontstyle[#1][\c!tt]\showfontstyle[#1][\c!mm]
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index 70f859cde..2f4bebbaf 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -6,53 +6,62 @@ if not modules then modules = { } end modules ['font-syn'] = {
license = "see context related readme files"
}
+local next = next
+local gsub, lower, match, find, lower, upper = string.gsub, string.lower, string.match, string.find, string.lower, string.upper
+
+local trace_names = false trackers.register("fonts.names", function(v) trace_names = v end)
+
--[[ldx--
<p>This module implements a name to filename resolver. Names are resolved
using a table that has keys filtered from the font related files.</p>
--ldx]]--
-local texsprint = tex.sprint
+local texsprint = (tex and tex.sprint) or print
fonts = fonts or { }
input = input or { }
texmf = texmf or { }
-fonts.names = { }
-fonts.names.filters = { }
-fonts.names.data = { }
-fonts.names.version = 1.07
-fonts.names.saved = false
-fonts.names.loaded = false
-fonts.names.be_clever = true
-fonts.names.enabled = true
-fonts.names.autoreload = toboolean(os.env['MTX.FONTS.AUTOLOAD'] or os.env['MTX_FONTS_AUTOLOAD'] or "no")
-fonts.names.cache = containers.define("fonts","data",fonts.names.version,true)
-fonts.names.trace = false
+fonts.names = fonts.names or { }
+fonts.names.filters = fonts.names.filters or { }
+fonts.names.data = fonts.names.data or { }
+
+local names = fonts.names
+local filters = fonts.names.filters
+
+names.version = 1.08 -- when adapting this, also changed font-dum.lua
+names.basename = "names"
+names.saved = false
+names.loaded = false
+names.be_clever = true
+names.enabled = true
+names.autoreload = toboolean(os.env['MTX.FONTS.AUTOLOAD'] or os.env['MTX_FONTS_AUTOLOAD'] or "no")
+names.cache = containers.define("fonts","data",names.version,true)
--[[ldx--
<p>It would make sense to implement the filters in the related modules,
but to keep the overview, we define them here.</p>
--ldx]]--
-fonts.names.filters.otf = fontforge.info
-fonts.names.filters.ttf = fontforge.info
-fonts.names.filters.ttc = fontforge.info
+filters.otf = fontloader.info
+filters.ttf = fontloader.info
+filters.ttc = fontloader.info
-function fonts.names.filters.afm(name)
- local pfbname = input.find_file(file.removesuffix(name)..".pfb","pfb") or ""
+function filters.afm(name)
+ local pfbname = resolvers.find_file(file.removesuffix(name)..".pfb","pfb") or ""
if pfbname == "" then
- pfbname = input.find_file(file.removesuffix(file.basename(name))..".pfb","pfb") or ""
+ pfbname = resolvers.find_file(file.removesuffix(file.basename(name))..".pfb","pfb") or ""
end
if pfbname ~= "" then
local f = io.open(name)
if f then
local hash = { }
for line in f:lines() do
- local key, value = line:match("^(.+)%s+(.+)%s*$")
+ local key, value = match(line,"^(.+)%s+(.+)%s*$")
if key and #key > 0 then
- hash[key:lower()] = value
+ hash[lower(key)] = value
end
- if line:find("StartCharMetrics") then
+ if find(line,"StartCharMetrics") then
break
end
end
@@ -63,8 +72,8 @@ function fonts.names.filters.afm(name)
return nil
end
-function fonts.names.filters.pfb(name)
- return fontforge.info(name)
+function filters.pfb(name)
+ return fontloader.info(name)
end
--[[ldx--
@@ -73,101 +82,103 @@ the file databases. Watch how we check not only for the names, but also
for combination with the weight of a font.</p>
--ldx]]--
-fonts.names.filters.list = {
+filters.list = {
"otf", "ttf", "ttc", "afm",
}
-fonts.names.filters.fixes = {
+filters.fixes = {
{ "reg$", "regular", },
{ "ita$", "italic", },
{ "ital$", "italic", },
{ "cond$", "condensed", },
+ { "book$", "", },
}
-fonts.names.xml_configuration_file = "fonts.conf" -- a bit weird format, bonus feature
-fonts.names.environment_path_variable = "OSFONTDIR" -- the official way, in minimals etc
+names.xml_configuration_file = "fonts.conf" -- a bit weird format, bonus feature
+names.environment_path_variable = "OSFONTDIR" -- the official way, in minimals etc
-fonts.names.filters.paths = { }
-fonts.names.filters.names = { }
+filters.paths = { }
+filters.names = { }
-function fonts.names.getpaths()
+function names.getpaths()
local hash, result = { }, { }
local function collect(t)
for i=1, #t do
- local v = input.clean_path(t[i])
- v = v:gsub("/+$","")
- local key = v:lower()
+ local v = resolvers.clean_path(t[i])
+ v = gsub(v,"/+$","")
+ local key = lower(v)
if not hash[key] then
hash[key], result[#result+1] = true, v
end
end
end
- local path = fonts.names.environment_path_variable or ""
+ local path = names.environment_path_variable or ""
if path ~= "" then
- collect(input.expanded_path_list(path))
+ collect(resolvers.expanded_path_list(path))
end
- local name = fonts.names.xml_configuration_file or ""
- if name ~= "" then
- local name = input.find_file(name,"other")
+ if xml then
+ local name = names.xml_configuration_file or ""
if name ~= "" then
- collect(xml.collect_texts(xml.load(name),"dir",true))
+ local name = resolvers.find_file(name,"other")
+ if name ~= "" then
+ collect(xml.collect_texts(xml.load(name),"dir",true))
+ end
end
end
- function fonts.names.getpaths()
+ function names.getpaths()
return result
end
return result
end
-function fonts.names.cleanname(name)
- return ((name:lower()):gsub("[^%a%d]",""))
+function names.cleanname(name)
+ return (gsub(lower(name),"[^%a%d]",""))
end
-function fonts.names.identify(verbose)
- fonts.names.data = {
- version = fonts.names.version,
+function names.identify(verbose) -- lsr is for kpse
+ names.data = {
+ version = names.version,
mapping = { },
-- sorted = { },
fallback_mapping = { },
-- fallback_sorted = { },
}
- local done, mapping, fallback_mapping, nofread, nofok = { }, fonts.names.data.mapping, fonts.names.data.fallback_mapping, 0, 0
- local cleanname = fonts.names.cleanname
+ local done, mapping, fallback_mapping, nofread, nofok = { }, names.data.mapping, names.data.fallback_mapping, 0, 0
+ local cleanname = names.cleanname
local function check(result, filename, suffix, is_sub)
local fontname = result.fullname
if fontname then
local n = cleanname(result.fullname)
if not mapping[n] then
- mapping[n], nofok = { suffix, fontname, filename, is_sub }, nofok + 1
+ mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
end
end
if result.fontname then
fontname = fontname or result.fontname
local n = cleanname(result.fontname)
if not mapping[n] then
- mapping[n], nofok = { suffix, fontname, filename, is_sub }, nofok + 1
+ mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
end
end
if result.familyname and result.weight and result.italicangle == 0 then
local madename = result.familyname .. " " .. result.weight
fontname = fontname or madename
- local n = cleanname(madename)
+ local n = cleanname(fontname)
if not mapping[n] and not fallback_mapping[n] then
- fallback_mapping[n], nofok = { suffix, fontname, filename, is_sub }, nofok + 1
+ fallback_mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
end
end
end
- local trace = verbose or fonts.names.trace
- local filters = fonts.names.filters
- local skip_paths = fonts.names.filters.paths
- local skip_names = fonts.names.filters.names
+ local trace = verbose or trace_names
+ local skip_paths = filters.paths
+ local skip_names = filters.names
local function identify(completename,name,suffix,storedname)
if not done[name] and io.exists(completename) then
nofread = nofread + 1
if #skip_paths > 0 then
local path = file.dirname(completename)
for i=1,#skip_paths do
- if path:find(skip_paths[i]) then
+ if find(path,skip_paths[i]) then
if trace then
logs.report("fontnames","rejecting path of %s font %s",suffix,completename)
logs.push()
@@ -179,7 +190,7 @@ function fonts.names.identify(verbose)
if #skip_names > 0 then
local base = file.basename(completename)
for i=1,#skip_paths do
- if base:find(skip_names[i]) then
+ if find(base,skip_names[i]) then
done[name] = true
if trace then
logs.report("fontnames","rejecting name of %s font %s",suffix,completename)
@@ -189,51 +200,46 @@ function fonts.names.identify(verbose)
end
end
end
- if trace then
+ if trace_names then
logs.report("fontnames","identifying %s font %s",suffix,completename)
logs.push()
end
- local result = filters[suffix:lower()](completename)
+ local result = filters[lower(suffix)](completename)
if trace then
logs.pop()
end
if result then
if not result[1] then
check(result,storedname,suffix,false) -- was name
- else for _, r in ipairs(result) do
- check(r,storedname,suffix,true) -- was name
- end end
+ else
+ for r=1,#result do
+ check(result[r],storedname,suffix,true) -- was name
+ end
+ end
end
done[name] = true
end
end
+ local totalread, totalok = 0, 0
local function traverse(what, method)
- for n, suffix in ipairs(fonts.names.filters.list) do
+ for n, suffix in ipairs(filters.list) do
nofread, nofok = 0, 0
local t = os.gettimeofday() -- use elapser
- suffix = suffix:lower()
+ suffix = lower(suffix)
logs.report("fontnames", "identifying %s font files with suffix %s",what,suffix)
method(suffix)
- suffix = suffix:upper()
+ suffix = upper(suffix)
logs.report("fontnames", "identifying %s font files with suffix %s",what,suffix)
method(suffix)
logs.report("fontnames", "%s %s files identified, %s hash entries added, runtime %0.3f seconds",nofread,what,nofok,os.gettimeofday()-t)
+ totalread, totalok = totalread + nofread, totalok + nofok
end
end
- traverse("tree", function(suffix) -- TEXTREE only
- input.with_files(".*%." .. suffix .. "$", function(method,root,path,name)
- if method == "file" then
- local completename = root .."/" .. path .. "/" .. name
- identify(completename,name,suffix,name,name)
- end
- end)
- end)
- traverse("system", function(suffix) -- OSFONTDIR cum suis
- local pathlist = fonts.names.getpaths()
+ local function walk_tree(pathlist,suffix)
if pathlist then
for _, path in ipairs(pathlist) do
- path = input.clean_path(path .. "/")
- path = path:gsub("/+","/")
+ path = resolvers.clean_path(path .. "/")
+ path = gsub(path,"/+","/")
local pattern = path .. "**." .. suffix -- ** forces recurse
logs.report("fontnames", "globbing path %s",pattern)
local t = dir.glob(pattern)
@@ -242,67 +248,115 @@ function fonts.names.identify(verbose)
end
end
end
+ end
+ traverse("tree", function(suffix) -- TEXTREE only
+ resolvers.with_files(".*%." .. suffix .. "$", function(method,root,path,name)
+ if method == "file" then
+ local completename = root .."/" .. path .. "/" .. name
+ identify(completename,name,suffix,name,name)
+ end
+ end)
end)
+ if texconfig.kpse_init then
+ -- we do this only for a stupid names run, not used for context itself,
+ -- using the vars is to clumsy so we just stick to a full scan instead
+ traverse("lsr", function(suffix) -- all trees
+ local pathlist = resolvers.split_path(resolvers.show_path("ls-R") or "")
+ walk_tree(pathlist,suffix)
+ end)
+ else
+ traverse("system", function(suffix) -- OSFONTDIR cum suis
+ walk_tree(names.getpaths(),suffix)
+ end)
+ end
local t = { }
- for _, f in ipairs(fonts.names.filters.fixes) do
+ for _, f in ipairs(filters.fixes) do
local expression, replacement = f[1], f[2]
- for k,v in pairs(mapping) do
- local fix, pos = k:gsub(expression,replacement)
+ for k,v in next, mapping do
+ local fix, pos = gsub(k,expression,replacement)
if pos > 0 and not mapping[fix] then
t[fix] = v
end
end
end
- for k,v in pairs(t) do
+ local n = 0
+ for k,v in next, t do
mapping[k] = v
+ n = n + 1
end
+ local rejected = 0
+ for k, v in next, mapping do
+ local kind, filename = v[1], v[3]
+ if not file.is_qualified_path(filename) and resolvers.find_file(filename,kind) == "" then
+ mapping[k] = nil
+ rejected = rejected + 1
+ end
+ end
+ if n > 0 then
+ logs.report("fontnames", "%s files read, %s normal and %s extra entries added, %s rejected, %s valid",totalread,totalok,n,rejected,totalok+n-rejected)
+ end
+end
+
+function names.is_permitted(name)
+ return containers.is_usable(names.cache(), name)
+end
+function names.write_data(name,data)
+ containers.write(names.cache(),name,data)
+end
+function names.read_data(name)
+ return containers.read(names.cache(),name)
end
-function fonts.names.load(reload,verbose)
- if not fonts.names.loaded then
+function names.load(reload,verbose)
+ if not names.loaded then
if reload then
- if containers.is_usable(fonts.names.cache(), "names") then
- fonts.names.identify(verbose)
- containers.write(fonts.names.cache(), "names", fonts.names.data)
+ if names.is_permitted(names.basename) then
+ names.identify(verbose)
+ names.write_data(names.basename,names.data)
+ else
+ logs.report("font table", "unable to access database cache")
end
- fonts.names.saved = true
+ names.saved = true
else
- fonts.names.data = containers.read(fonts.names.cache(), "names")
- if not fonts.names.saved then
- if table.is_empty(fonts.names.data) or table.is_empty(fonts.names.data.mapping) then
- fonts.names.load(true)
+ names.data = names.read_data(names.basename)
+ if not names.saved then
+ if table.is_empty(names.data) or table.is_empty(names.data.mapping) then
+ names.load(true)
end
- fonts.names.saved = true
+ names.saved = true
end
end
- local data = fonts.names.data
+ local data = names.data
if data then
data.sorted = table.sortedkeys(data.mapping or { }) or { }
data.fallback_sorted = table.sortedkeys(data.fallback_mapping or { }) or { }
else
logs.report("font table", "accessing the data table failed")
end
- fonts.names.loaded = true
+ names.loaded = true
end
end
-function fonts.names.list(pattern,reload)
- fonts.names.load(reload)
- if fonts.names.loaded then
+function names.list(pattern,reload)
+ names.load(reload)
+ if names.loaded then
local t = { }
local function list_them(mapping,sorted)
if mapping[pattern] then
t[pattern] = mapping[pattern]
else
for k,v in ipairs(sorted) do
- if v:find(pattern) then
+ if find(v,pattern) then
t[v] = mapping[v]
end
end
end
end
- list_them(fonts.names.data.mapping,fonts.names.data.sorted)
- list_them(fonts.names.data.fallback_mapping,fonts.names.data.fallback_sorted)
+ local data = names.data
+ if data then
+ list_them(data.mapping,data.sorted)
+ list_them(data.fallback_mapping,data.fallback_sorted)
+ end
return t
else
return nil
@@ -315,110 +369,81 @@ here is for testing purposes only (it deals with names prefixed by an
encoding name).</p>
--ldx]]--
-do
-
- local function found(name)
- if fonts.names.data then
- name = fonts.names.cleanname(name)
- local function found_indeed(mapping,sorted)
- local mn = mapping[name]
- if mn then
- return mn[2], mn[3], mn[4]
- end
- if fonts.names.be_clever then -- this will become obsolete
- local encoding, tag = name:match("^(.-)[%-%:](.+)$")
- local mt = mapping[tag]
- if tag and fonts.enc.is_known(encoding) and mt then
- return mt[1], encoding .. "-" .. mt[3], mt[4]
- end
- end
- -- name, type, file
- for k,v in pairs(mapping) do
- if k:find(name) then
- return v[2], v[3], v[4]
- end
- end
- local condensed = name:gsub("[^%a%d]","")
- local mc = mapping[condensed]
- if mc then
- return mc[2], mc[3], mc[4]
- end
- for k,v in ipairs(sorted) do
- if v:find(condensed) then
- v = mapping[v]
- return v[2], v[3], v[4]
- end
- end
- return nil, nil, nil
- end
- local data = fonts.names.data
- local fontname, filename, is_sub = found_indeed(data.mapping, data.sorted)
- if not fontname or not filename then
- fontname, filename, is_sub = found_indeed(data.fallback_mapping, data.fallback_sorted)
- end
- return fontname, filename, is_sub
- else
- return nil, nil, nil
+local function found_indeed(mapping,sorted,name)
+ local mn = mapping[name]
+ if mn then
+ return mn[2], mn[3], mn[4]
+ end
+ if names.be_clever then -- this will become obsolete
+ local encoding, tag = match(name,"^(.-)[%-%:](.+)$")
+ local mt = mapping[tag]
+ if tag and fonts.enc.is_known(encoding) and mt then
+ return mt[1], encoding .. "-" .. mt[3], mt[4]
end
end
-
- local reloaded = false
-
- function fonts.names.resolve(askedname, sub)
- if not askedname then
- return nil, nil
- elseif fonts.names.enabled then
- askedname = askedname:lower()
- fonts.names.load()
- local name, filename, is_sub = found(askedname)
- if not filename and not reloaded and fonts.names.autoreload then
- fonts.names.loaded = false
- reloaded = true
- io.flush()
- fonts.names.load(true)
- name, filename, is_sub = found(askedname)
- end
- if is_sub then
- return filename, name
- else
- return filename, sub
- end
- else
- return filename, sub
+ -- name, type, file
+ for k,v in next, mapping do
+ if find(k,name) then
+ return v[2], v[3], v[4]
end
end
+ local condensed = gsub(name,"[^%a%d]","")
+ local mc = mapping[condensed]
+ if mc then
+ return mc[2], mc[3], mc[4]
+ end
+ for k=1,#sorted do
+ local v = sorted[k]
+ if find(v,condensed) then
+ v = mapping[v]
+ return v[2], v[3], v[4]
+ end
+ end
+ return nil, nil, nil
+end
+local function found(name)
+ if name and name ~= "" and names.data then
+ name = names.cleanname(name)
+ local data = names.data
+ local fontname, filename, is_sub = found_indeed(data.mapping, data.sorted, name)
+ if not fontname or not filename then
+ fontname, filename, is_sub = found_indeed(data.fallback_mapping, data.fallback_sorted, name)
+ end
+ return fontname, filename, is_sub
+ else
+ return nil, nil, nil
+ end
end
---[[ldx--
-<p>A handy helper.</p>
---ldx]]--
+local reloaded = false
-function fonts.names.table(pattern,reload,all)
- local t = fonts.names.list(pattern,reload)
- if t then
- texsprint(tex.ctxcatcodes,"\\start\\nonknuthmode\\starttabulate[|T|T|T|T|T|]")
- texsprint(tex.ctxcatcodes,"\\NC hashname\\NC type\\NC fontname\\NC filename\\NC\\NR\\HL")
- for k,v in pairs(table.sortedkeys(t)) do
- if all or v == t[v][2]:lower() then
- local type, name, file = unpack(t[v])
- if type and name and file then
- texsprint(tex.ctxcatcodes,string.format("\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR",v,type, name, file))
- else
- logs.report("font table", "skipping %s", v)
- end
- end
+function names.specification(askedname, sub)
+ if askedname and askedname ~= "" and names.enabled then
+ askedname = lower(askedname)
+ names.load()
+ local name, filename, is_sub = found(askedname)
+ if not filename and not reloaded and names.autoreload then
+ names.loaded = false
+ reloaded = true
+ io.flush()
+ names.load(true)
+ name, filename, is_sub = found(askedname)
end
- texsprint(tex.ctxcatcodes,"\\stoptabulate\\stop")
+ return name, filename, is_sub
end
end
+function names.resolve(askedname, sub)
+ local name, filename, is_sub = names.specification(askedname, sub)
+ return filename, (is_sub and name) or sub
+end
--[[ldx--
<p>Fallbacks, not permanent but a transition thing.</p>
--ldx]]--
-fonts.names.new_to_old = {
+names.new_to_old = {
["lmroman10-capsregular"] = "lmromancaps10-oblique",
["lmroman10-capsoblique"] = "lmromancaps10-regular",
["lmroman10-demi"] = "lmromandemi10-oblique",
@@ -460,19 +485,19 @@ fonts.names.new_to_old = {
["lmtypewritervarwd10-darkoblique"] = "lmmonoproplt10-boldoblique",
}
-fonts.names.old_to_new = table.swapped(fonts.names.new_to_old)
+names.old_to_new = table.swapped(names.new_to_old)
-function fonts.names.exists(name)
- local fna, found = fonts.names.autoreload, false
- fonts.names.autoreload = false
- for k,v in ipairs(fonts.names.filters.list) do
- found = (input.find_file(name,v) or "") ~= ""
+function names.exists(name)
+ local fna, found = names.autoreload, false
+ names.autoreload = false
+ for k,v in ipairs(filters.list) do
+ found = (resolvers.find_file(name,v) or "") ~= ""
if found then
break
end
end
- found = found or (input.find_file(name,"tfm") or "") ~= ""
- found = found or (fonts.names.resolve(name) or "") ~= ""
- fonts.names.autoreload = fna
+ found = found or (resolvers.find_file(name,"tfm") or "") ~= ""
+ found = found or (names.resolve(name) or "") ~= ""
+ names.autoreload = fna
return found
end
diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua
index 1955b58bc..2ee633b77 100644
--- a/tex/context/base/font-tfm.lua
+++ b/tex/context/base/font-tfm.lua
@@ -6,31 +6,51 @@ if not modules then modules = { } end modules ['font-tfm'] = {
license = "see context related readme files"
}
+local utf = unicode.utf8
+
+local next, format, match, lower = next, string.format, string.match, string.lower
+local concat, sortedkeys, utfbyte, serialize = table.concat, table.sortedkeys, utf.byte, table.serialize
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end)
+
+-- tfmdata has also fast access to indices and unicodes
+-- to be checked: otf -> tfm -> tfmscaled
+--
+-- watch out: no negative depths and negative eights permitted in regular fonts
+
--[[ldx--
<p>Here we only implement a few helper functions.</p>
--ldx]]--
fonts = fonts or { }
fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
local tfm = fonts.tfm
-fonts.loaded = fonts.loaded or { }
-fonts.dontembed = fonts.dontembed or { }
-fonts.logger = fonts.logger or { }
-fonts.loadtime = 0
-fonts.triggers = fonts.triggers or { } -- brrr
+fonts.loaded = fonts.loaded or { }
+fonts.dontembed = fonts.dontembed or { }
+fonts.triggers = fonts.triggers or { } -- brrr
+fonts.initializers = fonts.initializers or { }
+fonts.initializers.common = fonts.initializers.common or { }
+
+local fontdata = fonts.ids
+local glyph = node.id('glyph')
+local set_attribute = node.set_attribute
--[[ldx--
<p>The next function encapsulates the standard <l n='tfm'/> loader as
supplied by <l n='luatex'/>.</p>
--ldx]]--
-tfm.resolve_vf = true -- false
+tfm.resolve_vf = true -- false
+tfm.share_base_kerns = false -- true (.5 sec slower on mk but brings down mem from 410M to 310M, beware: then script/lang share too)
+tfm.mathactions = { }
function tfm.enhance(tfmdata,specification)
local name, size = specification.name, specification.size
- local encoding, filename = name:match("^(.-)%-(.*)$") -- context: encoding-name.*
+ local encoding, filename = match(name,"^(.-)%-(.*)$") -- context: encoding-name.*
if filename and encoding and fonts.enc.known[encoding] then
local data = fonts.enc.load(encoding)
if data then
@@ -38,14 +58,14 @@ function tfm.enhance(tfmdata,specification)
tfmdata.encoding = encoding
local vector = data.vector
local original = { }
- for k, v in pairs(characters) do
+ for k, v in next, characters do
v.name = vector[k]
v.index = k
original[k] = v
end
- for k,v in pairs(data.unicodes) do
+ for k,v in next, data.unicodes do
if k ~= v then
- if fonts.trace then
+ if trace_defining then
logs.report("define font","mapping %s onto %s",k,v)
end
characters[k] = original[v]
@@ -56,21 +76,9 @@ function tfm.enhance(tfmdata,specification)
end
function tfm.read_from_tfm(specification)
- local fname, tfmdata = specification.filename, nil
- if fname then
- -- safeguard, we use tfm as fallback
- local suffix = file.extname(fname)
- if suffix ~= "" and suffix ~= "tfm" then
- fname = ""
- end
- end
- if not fname or fname == "" then
- fname = input.findbinfile(specification.name, 'ofm')
- else
- fname = input.findbinfile(fname, 'ofm')
- end
- if fname and fname ~= "" then
- if fonts.trace then
+ local fname, tfmdata = specification.filename or "", nil
+ if fname ~= "" then
+ if trace_defining then
logs.report("define font","loading tfm file %s at size %s",fname,specification.size)
end
tfmdata = font.read_tfm(fname,specification.size) -- not cached, fast enough
@@ -78,12 +86,12 @@ function tfm.read_from_tfm(specification)
tfmdata.descriptions = tfmdata.descriptions or { }
if tfm.resolve_vf then
fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here
- fname = input.findbinfile(specification.name, 'ovf')
+ fname = resolvers.findbinfile(specification.name, 'ovf')
if fname and fname ~= "" then
local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough
if vfdata then
local chars = tfmdata.characters
- for k,v in pairs(vfdata.characters) do -- no ipairs, can have holes
+ for k,v in next, vfdata.characters do
chars[k].commands = v.commands
end
tfmdata.type = 'virtual'
@@ -93,10 +101,8 @@ function tfm.read_from_tfm(specification)
end
tfm.enhance(tfmdata,specification)
end
- else
- if fonts.trace then
- logs.report("define font","loading tfm with name %s fails",specification.name)
- end
+ elseif trace_defining then
+ logs.report("define font","loading tfm with name %s fails",specification.name)
end
return tfmdata
end
@@ -107,21 +113,17 @@ do with the fact that <l n='tex'/> uses a negative multiple of 1000 as
a signal for a font scaled based on the design size.</p>
--ldx]]--
-do
-
- local factors = {
- pt = 65536.0,
- bp = 65781.8,
- }
-
- function tfm.setfactor(f)
- tfm.factor = factors[f or 'pt'] or factors.pt
- end
-
- tfm.setfactor()
+local factors = {
+ pt = 65536.0,
+ bp = 65781.8,
+}
+function tfm.setfactor(f)
+ tfm.factor = factors[f or 'pt'] or factors.pt
end
+tfm.setfactor()
+
function tfm.scaled(scaledpoints, designsize) -- handles designsize in sp as well
if scaledpoints < 0 then
if designsize then
@@ -160,9 +162,11 @@ function tfm.check_virtual_id(tfmdata, id)
if not tfmdata.fonts or #tfmdata.fonts == 0 then
tfmdata.type, tfmdata.fonts = "real", nil
else
- for k,v in ipairs(tfmdata.fonts) do
- if v.id and v.id == 0 then
- v.id = id
+ local vfonts = tfmdata.fonts
+ for f=1,#vfonts do
+ local fnt = vfonts[f]
+ if fnt.id and fnt.id == 0 then
+ fnt.id = id
end
end
end
@@ -177,25 +181,91 @@ excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p>
fonts.trace_scaling = false
+-- the following hack costs a bit of runtime but safes memory
+--
+-- basekerns are scaled and will be hashed by table id
+-- sharedkerns are unscaled and are be hashed by concatenated indexes
+
+function tfm.check_base_kerns(tfmdata)
+ if tfm.share_base_kerns then
+ local sharedkerns = tfmdata.sharedkerns
+ if sharedkerns then
+ local basekerns = { }
+ tfmdata.basekerns = basekerns
+ return sharedkerns, basekerns
+ end
+ end
+ return nil, nil
+end
+
+function tfm.prepare_base_kerns(tfmdata)
+ if tfm.share_base_kerns and not tfmdata.sharedkerns then
+ local sharedkerns = { }
+ tfmdata.sharedkerns = sharedkerns
+ for u, chr in next, tfmdata.characters do
+ local kerns = chr.kerns
+ if kerns then
+ local hash = concat(sortedkeys(kerns), " ")
+ local base = sharedkerns[hash]
+ if not base then
+ sharedkerns[hash] = kerns
+ else
+ chr.kerns = base
+ end
+ end
+ end
+ end
+end
+
+-- we can have cache scaled characters when we are in node mode and don't have
+-- protruding and expansion: hash == fullname @ size @ protruding @ expansion
+-- but in practice (except from mk) the otf hash will be enough already so it
+-- makes no sense to mess up the code now
+
+local charactercache = { }
+
+-- The scaler is only used for otf and afm and virtual fonts. If
+-- a virtual font has italic correction make sur eto set the
+-- has_italic flag. Some more flags will be added in the future.
+
function tfm.do_scale(tfmtable, scaledpoints)
- local trace = fonts.trace_scaling
+ tfm.prepare_base_kerns(tfmtable) -- optimalization
if scaledpoints < 0 then
scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp
end
---~ print(">>>",tfmtable.units)
local delta = scaledpoints/(tfmtable.units or 1000) -- brr, some open type fonts have 2048
local t = { }
- t.factor = delta
- for k,v in pairs(tfmtable) do
- t[k] = (type(v) == "table" and { }) or v
- end
- -- new
+ -- unicoded unique descriptions shared cidinfo characters changed parameters indices
+ for k,v in next, tfmtable do
+ if type(v) == "table" then
+ -- print(k)
+ else
+ t[k] = v
+ end
+ end
+ -- status
+ local isvirtual = tfmtable.type == "virtual" or tfmtable.virtualized
+ local hasmath = tfmtable.math_parameters ~= nil or tfmtable.MathConstants ~= nil
+ local nodemode = tfmtable.mode == "node"
+ local hasquality = tfmtable.auto_expand or tfmtable.auto_protrude
+ local hasitalic = tfmtable.has_italic
+ --
+ t.parameters = { }
+ t.characters = { }
+ t.MathConstants = { }
+ -- fast access
+ local descriptions = tfmtable.descriptions or { }
+ t.unicodes = tfmtable.unicodes
+ t.indices = tfmtable.indices
+ t.marks = tfmtable.marks
+ t.descriptions = descriptions
if tfmtable.fonts then
- t.fonts = table.fastcopy(tfmtable.fonts)
+ t.fonts = table.fastcopy(tfmtable.fonts) -- hm also at the end
end
- -- local zerobox = { 0, 0, 0, 0 }
local tp = t.parameters
+ local mp = t.math_parameters
local tfmp = tfmtable.parameters -- let's check for indexes
+ --
tp.slant = (tfmp.slant or tfmp[1] or 0)
tp.space = (tfmp.space or tfmp[2] or 0)*delta
tp.space_stretch = (tfmp.space_stretch or tfmp[3] or 0)*delta
@@ -205,107 +275,271 @@ function tfm.do_scale(tfmtable, scaledpoints)
tp.extra_space = (tfmp.extra_space or tfmp[7] or 0)*delta
local protrusionfactor = (tp.quad ~= 0 and 1000/tp.quad) or 0
local tc = t.characters
- -- we can loop over (descriptions or characters), in which case
- -- we don't need to init characters in afm/otf (saves some mem)
- -- but then .. beware of protruding etc
- local descriptions = tfmtable.descriptions or { }
- t.descriptions = descriptions
+ local characters = tfmtable.characters
local nameneeded = not tfmtable.shared.otfdata --hack
--- loop over descriptions
- -- afm and otf have descriptions, tfm not
- for k,v in pairs(tfmtable.characters) do
- local description = descriptions[k] or v
- local chr
- -- there is no need (yet) to assign a value to chr.tonunicode
- if nameneeded then
- chr = {
- name = description.name, -- is this used at all?
- index = description.index or k,
- width = delta*(description.width or 0),
- height = delta*(description.height or 0),
- depth = delta*(description.depth or 0),
- }
+ local changed = tfmtable.changed or { } -- for base mode
+ local ischanged = not table.is_empty(changed)
+ local indices = tfmtable.indices
+ local luatex = tfmtable.luatex
+ local tounicode = luatex and luatex.tounicode
+ local defaultwidth = luatex and luatex.defaultwidth or 0
+ local defaultheight = luatex and luatex.defaultheight or 0
+ local defaultdepth = luatex and luatex.defaultdepth or 0
+ -- experimental, sharing kerns (unscaled and scaled) saves memory
+ local sharedkerns, basekerns = tfm.check_base_kerns(tfmtable)
+ -- loop over descriptions (afm and otf have descriptions, tfm not)
+ -- there is no need (yet) to assign a value to chr.tonunicode
+ local scaledwidth = defaultwidth * delta
+ local scaledheight = defaultheight * delta
+ local scaleddepth = defaultdepth * delta
+ local stackmath = tfmtable.ignore_stack_math ~= true
+ for k,v in next, characters do
+ local chr, description, index
+ if ischanged then
+ -- basemode hack
+ local c = changed[k]
+ if c then
+ description = descriptions[c] or v
+ v = characters[c] or v
+ index = (indices and indices[c]) or c
+ else
+ description = descriptions[k] or v
+ index = (indices and indices[k]) or k
+ end
else
- chr = {
- index = description.index or k,
- width = delta*(description.width or 0),
- height = delta*(description.height or 0),
- depth = delta*(description.depth or 0),
- }
- end
- if trace then
- logs.report("define font","t=%s, u=%s, i=%s, n=%s c=%s",k,chr.tounicode or k,description.index,description.name or '-',description.class or '-')
- end
- local ve = v.expansion_factor
- if ve then
- chr.expansion_factor = ve*1000 -- expansionfactor
- end
- local vl = v.left_protruding
- if vl then
- chr.left_protruding = protrusionfactor*chr.width*vl
+ description = descriptions[k] or v
+ index = (indices and indices[k]) or k
+ end
+ local width = description.width
+ local height = description.height
+ local depth = description.depth
+ if width then width = delta*width else width = scaledwidth end
+ if height then height = delta*height else height = scaledheight end
+ -- if depth then depth = delta*depth else depth = scaleddepth end
+ if depth and depth ~= 0 then
+ depth = delta*depth
+ if nameneeded then
+ chr = {
+ name = description.name,
+ index = index,
+ height = height,
+ depth = depth,
+ width = width,
+ }
+ else
+ chr = {
+ index = index,
+ height = height,
+ depth = depth,
+ width = width,
+ }
+ end
+ else
+ -- this saves a little bit of memory time and memory, esp for big cjk fonts
+ if nameneeded then
+ chr = {
+ name = description.name,
+ index = index,
+ height = height,
+ width = width,
+ }
+ else
+ chr = {
+ index = index,
+ height = height,
+ width = width,
+ }
+ end
end
- local vr = v.right_protruding
- if vr then
- chr.right_protruding = protrusionfactor*chr.width*vr
+ -- if trace_scaling then
+ -- logs.report("define font","t=%s, u=%s, i=%s, n=%s c=%s",k,chr.tounicode or k,description.index,description.name or '-',description.class or '-')
+ -- end
+ if tounicode then
+ local tu = tounicode[index]
+ if tu then
+ chr.tounicode = tu
+ end
end
- local vi = description.italic
- if vi then
- chr.italic = vi*delta
+ if hasquality then
+ local ve = v.expansion_factor
+ if ve then
+ chr.expansion_factor = ve*1000 -- expansionfactor, hm, can happen elsewhere
+ end
+ local vl = v.left_protruding
+ if vl then
+ chr.left_protruding = protrusionfactor*width*vl
+ end
+ local vr = v.right_protruding
+ if vr then
+ chr.right_protruding = protrusionfactor*width*vr
+ end
end
- local vk = v.kerns
- if vk then
- local tt = {}
- for k,v in pairs(vk) do tt[k] = v*delta end
- chr.kerns = tt
+ -- todo: hasitalic
+ if hasitalic then
+ local vi = description.italic or v.italic
+ if vi and vi ~= 0 then
+ chr.italic = vi*delta
+ end
end
- local vl = v.ligatures
- if vl then
- if true then
- chr.ligatures = vl -- shared
+ -- to be tested
+ if hasmath then
+ -- todo, just operate on descriptions.math
+ local vn = v.next
+ if vn then
+ chr.next = vn
else
- local tt = { }
- for i,l in pairs(vl) do
- tt[i] = l
+ local vv = v.vert_variants
+ if vv then
+ local t = { }
+ for i=1,#vv do
+ local vvi = vv[i]
+ t[i] = {
+ ["start"] = (vvi["start"] or 0)*delta,
+ ["end"] = (vvi["end"] or 0)*delta,
+ ["advance"] = (vvi["advance"] or 0)*delta,
+ ["extender"] = vvi["extender"],
+ ["glyph"] = vvi["glyph"],
+ }
+ end
+ chr.vert_variants = t
+ else
+ local hv = v.horiz_variants
+ if hv then
+ local t = { }
+ for i=1,#hv do
+ local hvi = hv[i]
+ t[i] = {
+ ["start"] = (hvi["start"] or 0)*delta,
+ ["end"] = (hvi["end"] or 0)*delta,
+ ["advance"] = (hvi["advance"] or 0)*delta,
+ ["extender"] = hvi["extender"],
+ ["glyph"] = hvi["glyph"],
+ }
+ end
+ chr.horiz_variants = t
+ end
+ end
+ end
+ local vt = description.top_accent
+ if vt then
+ chr.top_accent = delta*vt
+ end
+ if stackmath then
+ local mk = v.mathkerns
+ if mk then
+ local kerns = { }
+ -- for k, v in next, mk do
+ -- local kk = { }
+ -- for i=1,#v do
+ -- local vi = v[i]
+ -- kk[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ -- end
+ -- kerns[k] = kk
+ -- end
+ local v = mk.top_right if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.top_right = k end
+ local v = mk.top_left if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.top_left = k end
+ local v = mk.bottom_left if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.bottom_left = k end
+ local v = mk.bottom_right if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.bottom_right = k end
+ chr.mathkern = kerns -- singular
end
- chr.ligatures = tt
end
end
- local vc = v.commands
- if vc then
- -- we assume non scaled commands here
- local ok = false
- for i=1,#vc do
- local key = vc[i][1]
- -- if key == "right" or key == "left" or key == "down" or key == "up" then
- if key == "right" or key == "down" then
- ok = true
- break
+ if not nodemode then
+ local vk = v.kerns
+ if vk then
+ if sharedkerns then
+ local base = basekerns[vk] -- hashed by table id, not content
+ if not base then
+ base = {}
+ for k,v in next, vk do base[k] = v*delta end
+ basekerns[vk] = base
+ end
+ chr.kerns = base
+ else
+ local tt = {}
+ for k,v in next, vk do tt[k] = v*delta end
+ chr.kerns = tt
+ end
+ end
+ local vl = v.ligatures
+ if vl then
+ if true then
+ chr.ligatures = vl -- shared
+ else
+ local tt = { }
+ for i,l in next, vl do
+ tt[i] = l
+ end
+ chr.ligatures = tt
end
end
- if ok then
- local tt = { }
+ end
+ if isvirtual then
+ local vc = v.commands
+ if vc then
+ -- we assume non scaled commands here
+ local ok = false
for i=1,#vc do
- local ivc = vc[i]
- local key = ivc[1]
- -- if key == "right" or key == "left" or key == "down" or key == "up" then
+ local key = vc[i][1]
if key == "right" or key == "down" then
- tt[#tt+1] = { key, ivc[2]*delta }
- else -- not comment
- tt[#tt+1] = ivc -- shared since in cache and untouched
+ ok = true
+ break
end
end
- chr.commands = tt
- else
- chr.commands = vc
+ if ok then
+ local tt = { }
+ for i=1,#vc do
+ local ivc = vc[i]
+ local key = ivc[1]
+ if key == "right" or key == "down" then
+ tt[#tt+1] = { key, ivc[2]*delta }
+ else -- not comment
+ tt[#tt+1] = ivc -- shared since in cache and untouched
+ end
+ end
+ chr.commands = tt
+ else
+ chr.commands = vc
+ end
end
end
tc[k] = chr
end
-- t.encodingbytes, t.filename, t.fullname, t.name: elsewhere
t.size = scaledpoints
+ t.factor = delta
if t.fonts then
t.fonts = table.fastcopy(t.fonts) -- maybe we virtualize more afterwards
end
+ if hasmath then
+ -- mathematics.extras.copy(t) -- can be done elsewhere if needed
+ local ma = tfm.mathactions
+ for i=1,#ma do
+ ma[i](t,tfmtable,delta)
+ end
+ end
+ -- needed for \high cum suis
+ local tpx = tp.x_height
+ if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
+ if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
+ if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
+ if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
+ if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
+ if not tp[22] then tp[22] = 0 end -- mathaxisheight
+ if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
+ t.tounicode = 1
+ -- we have t.name=metricfile and t.fullname=RealName and t.filename=diskfilename
+ -- when collapsing fonts, luatex looks as both t.name and t.fullname as ttc files
+ -- can have multiple subfonts
+--~ collectgarbage("collect")
return t, delta
end
@@ -320,14 +554,25 @@ tfm.auto_cleanup = true
local lastfont = nil
--- we can get rid of the tfm instance when we hav efast access to the
+-- we can get rid of the tfm instance when we have fast access to the
-- scaled character dimensions at the tex end, e.g. a fontobject.width
+--
+-- flushing the kern and ligature tables from memory saves a lot (only
+-- base mode) but it complicates vf building where the new characters
+-- demand this data
+
+--~ for id, f in pairs(fonts.ids) do -- or font.fonts
+--~ local ffi = font.fonts[id]
+--~ f.characters = ffi.characters
+--~ f.kerns = ffi.kerns
+--~ f.ligatures = ffi.ligatures
+--~ end
function tfm.cleanup_table(tfmdata) -- we need a cleanup callback, now we miss the last one
if tfm.auto_cleanup then -- ok, we can hook this into everyshipout or so ... todo
- if tfmdata.type == 'virtual' then
- for k, v in pairs(tfmdata.characters) do
- if v.commands then v.commands = nil end
+ if tfmdata.type == 'virtual' or tfmdata.virtualized then
+ for k, v in next, tfmdata.characters do
+ if v.commands then v.commands = nil end
end
end
end
@@ -349,235 +594,6 @@ function tfm.scale(tfmtable, scaledpoints)
end
--[[ldx--
-<p>The following functions are used for reporting about the fonts
-used. The message itself is not that useful in regular runs but since
-we now have several readers it may be handy to know what reader is
-used for which font.</p>
---ldx]]--
-
-function fonts.logger.save(tfmtable,source,specification) -- save file name in spec here ! ! ! ! ! !
- if tfmtable and specification and specification.specification then
- if fonts.trace then
- logs.report("define font","registering %s as %s",specification.name,source)
- end
- specification.source = source
- fonts.loaded[specification.specification] = specification
- fonts.used[specification.name] = source
- end
-end
-
---~ function fonts.logger.report(separator)
---~ local s = table.sortedkeys(fonts.loaded)
---~ if #s > 0 then
---~ local t = { }
---~ for _,v in ipairs(s) do
---~ t[#t+1] = v .. ":" .. fonts.loaded[v].source
---~ end
---~ return table.concat(t,separator or " ")
---~ else
---~ return "none"
---~ end
---~ end
-
-function fonts.logger.report(separator)
- local s = table.sortedkeys(fonts.used)
- if #s > 0 then
- local t = { }
- for _,v in ipairs(s) do
- t[#t+1] = v .. ":" .. fonts.used[v]
- end
- return table.concat(t,separator or " ")
- else
- return "none"
- end
-end
-
-function fonts.logger.format(name)
- return fonts.used[name] or "unknown"
-end
-
---[[ldx--
-<p>When we implement functions that deal with features, most of them
-will depend of the font format. Here we define the few that are kind
-of neutral.</p>
---ldx]]--
-
-fonts.initializers = fonts.initializers or { }
-fonts.initializers.common = fonts.initializers.common or { }
-
---[[ldx--
-<p>This feature will remove inter-digit kerns.</p>
---ldx]]--
-
-table.insert(fonts.triggers,"equaldigits")
-
-function fonts.initializers.common.equaldigits(tfmdata,value)
- if value then
- local chr = tfmdata.characters
- for i = utf.byte('0'), utf.byte('9') do
- local c = chr[i]
- if c then
- c.kerns = nil
- end
- end
- end
-end
-
---[[ldx--
-<p>This feature will give all glyphs an equal height and/or depth. Valid
-values are <type>none</type>, <type>height</type>, <type>depth</type> and
-<type>both</type>.</p>
---ldx]]--
-
-table.insert(fonts.triggers,"lineheight")
-
-function fonts.initializers.common.lineheight(tfmdata,value)
- if value and type(value) == "string" then
- if value == "none" then
- for _,v in pairs(tfmdata.characters) do
- v.height, v.depth = 0, 0
- end
- else
- local ascender, descender = tfmdata.ascender, tfmdata.descender
- if ascender and descender then
- local ht, dp = ascender or 0, descender or 0
- if value == "height" then
- dp = 0
- elseif value == "depth" then
- ht = 0
- end
- if ht > 0 then
- if dp > 0 then
- for _,v in pairs(tfmdata.characters) do
- v.height, v.depth = ht, dp
- end
- else
- for _,v in pairs(tfmdata.characters) do
- v.height = ht
- end
- end
- elseif dp > 0 then
- for _,v in pairs(tfmdata.characters) do
- v.depth = dp
- end
- end
- end
- end
- end
-end
-
---[[ldx--
-<p>It does not make sense any more to support messed up encoding vectors
-so we stick to those that implement oldstyle and small caps. After all,
-we move on. We can extend the next function on demand. This features is
-only used with <l n='afm'/> files.</p>
---ldx]]--
-
-do
-
- local smallcaps = lpeg.P(".sc") + lpeg.P(".smallcaps") + lpeg.P(".caps") + lpeg.P("small")
- local oldstyle = lpeg.P(".os") + lpeg.P(".oldstyle") + lpeg.P(".onum")
-
- smallcaps = lpeg.Cs((1-smallcaps)^1) * smallcaps^1
- oldstyle = lpeg.Cs((1-oldstyle )^1) * oldstyle ^1
-
- function fonts.initializers.common.encoding(tfmdata,value)
- if value then
- local afmdata = tfmdata.shared.afmdata
- if afmdata then
- local encodingfile = value .. '.enc'
- local encoding = fonts.enc.load(encodingfile)
- if encoding then
- local vector = encoding.vector
- local characters = tfmdata.characters
- local unicodes = afmdata.luatex.unicodes
- local function remap(pattern,name)
- local p = pattern:match(name)
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
- -- logs.report("encoding","%s (%s) -> %s (%s)",p,oldchr or -1,name,newchr or -1)
- characters[oldchr] = characters[newchr]
- end
- end
- return p
- end
- for _, name in pairs(vector) do
- local ok = remap(smallcaps,name) or remap(oldstyle,name)
- end
- if fonts.map.data[tfmdata.name] then
- fonts.map.data[tfmdata.name].encoding = encodingfile
- end
- end
- end
- end
- end
-
- -- when needed we can provide this as features in e.g. afm files
-
- function fonts.initializers.common.remap(tfmdata,value,pattern) -- will go away
- if value then
- local afmdata = tfmdata.shared.afmdata
- if afmdata then
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local unicodes = afmdata.luatex.unicodes
- local done = false
- for u, _ in pairs(characters) do
- local name = descriptions[u].name
- if name then
- local p = pattern:match(name)
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
- characters[oldchr] = characters[newchr]
- end
- end
- end
- end
- end
- end
- end
-
- function fonts.initializers.common.oldstyle(tfmdata,value)
- fonts.initializers.common.remap(tfmdata,value,oldstyle)
- end
- function fonts.initializers.common.smallcaps(tfmdata,value)
- fonts.initializers.common.remap(tfmdata,value,smallcaps)
- end
-
- function fonts.initializers.common.fakecaps(tfmdata,value)
- if value then
- -- todo: scale down
- local afmdata = tfmdata.shared.afmdata
- if afmdata then
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local unicodes = afmdata.luatex.unicodes
- for u, _ in pairs(characters) do
- local name = descriptions[u].name
- if name then
- local p = name:lower()
- if p then
- local oldchr, newchr = unicodes[p], unicodes[name]
- if oldchr and newchr and type(oldchr) == "number" and type(newchr) == "number" then
- characters[oldchr] = characters[newchr]
- end
- end
- end
- end
- end
- end
- end
-
-end
-
---~ function fonts.initializers.common.install(format,feature) -- 'afm','lineheight'
---~ fonts.initializers.base[format][feature] = fonts.initializers.common[feature]
---~ fonts.initializers.node[format][feature] = fonts.initializers.common[feature]
---~ end
-
---[[ldx--
<p>Analyzers run per script and/or language and are needed in order to
process features right.</p>
--ldx]]--
@@ -587,47 +603,31 @@ fonts.analyzers.aux = fonts.analyzers.aux or { }
fonts.analyzers.methods = fonts.analyzers.methods or { }
fonts.analyzers.initializers = fonts.analyzers.initializers or { }
-do
-
- local glyph = node.id('glyph')
- local fontdata = tfm.id
- local set_attribute = node.set_attribute
--- local unset_attribute = node.unset_attribute
--- local has_attribute = node.has_attribute
-
- local state = attributes.numbers['state'] or 100
-
- -- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
- -- e.g. latin -> hyphenate, arab -> 1/2/3 analyze
-
- -- an example analyzer
-
- function fonts.analyzers.aux.setstate(head,font)
- local tfmdata = fontdata[font]
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean
- while current do
- if current.id == glyph and current.font == font then
- local d = descriptions[current.char]
- if d then
- if d.class == "mark" then
- done = true
- set_attribute(current,state,5) -- mark
- elseif n == 0 then
- first, last, n = current, current, 1
- set_attribute(current,state,1) -- init
- else
- last, n = current, n+1
- set_attribute(current,state,2) -- medi
- end
- else -- finish
- if first and first == last then
- set_attribute(last,state,4) -- isol
- elseif last then
- set_attribute(last,state,3) -- fina
- end
- first, last, n = nil, nil, 0
+-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
+-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze
+
+-- an example analyzer (should move to font-ota.lua)
+
+local state = attributes.private('state')
+
+function fonts.analyzers.aux.setstate(head,font)
+ local tfmdata = fontdata[font]
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean
+ while current do
+ if current.id == glyph and current.font == font then
+ local d = descriptions[current.char]
+ if d then
+ if d.class == "mark" then
+ done = true
+ set_attribute(current,state,5) -- mark
+ elseif n == 0 then
+ first, last, n = current, current, 1
+ set_attribute(current,state,1) -- init
+ else
+ last, n = current, n+1
+ set_attribute(current,state,2) -- medi
end
else -- finish
if first and first == last then
@@ -637,132 +637,22 @@ do
end
first, last, n = nil, nil, 0
end
- current = current.next
- end
- if first and first == last then
- set_attribute(last,state,4) -- isol
- elseif last then
- set_attribute(last,state,3) -- fina
- end
- return head, done
- end
-
-end
-
---[[ldx--
-<p>We move marks into the components list. This saves much nasty testing later on.</p>
---ldx]]--
-
-do
-
- local glyph = node.id('glyph')
- local fontdata = tfm.id
- local marknumber = attributes.numbers['mark'] or 200
- local set_attribute = node.set_attribute
-
- function fonts.pushmarks(head,font)
- local tfmdata = fontdata[font]
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local current, last, done, n = head, nil, false, 0
- while current do
- if current.id == glyph and current.font == font then
- local d = descriptions[current.char]
- if d and d.class == "mark" then
- -- check if head
- if last and not last.components then
- last.components = current
- current.prev = nil -- last.components.prev = nil
- done = true
- n = 1
- else
- n = n + 1
- end
- set_attribute(current,marknumber,n)
- current = current.next
- elseif last and last.components then
- -- finish 'm
- current.prev.next = nil
- current.prev = last
- last.next = current
- last = current
- last = nil
- else
- last = current
- current = current.next
- end
- elseif last and last.components then
- current.prev.next = nil
- current.prev = last
- last.next = current
- last = nil
- else
- last = nil
- current = current.next
- end
- end
- if last and last.components then
- last.next = nil
- end
- tfmdata.shared.markspushed = done
- return head, done
- end
-
- function fonts.removemarks(head,font)
- local current, done, characters, descriptions = head, false, tfmdata.characters, tfmdata.descriptions
- while current do
- if current.id == glyph and current.font == font and descriptions[current.char].class == "mark" then
- local next, prev = current.next, current.prev
- if next then
- next.prev = prev
- end
- if prev then
- prev.next = next
- else
- head = next
- end
- node.free(current)
- current = next
- done = true
- else
- current = current.next
+ else -- finish
+ if first and first == last then
+ set_attribute(last,state,4) -- isol
+ elseif last then
+ set_attribute(last,state,3) -- fina
end
+ first, last, n = nil, nil, 0
end
- return head, done
+ current = current.next
end
-
- function fonts.popmarks(head,font)
- local tfmdata = fontdata[font]
- if tfmdata.shared.markspushed then
- local current, done, characters = head, false, tfmdata.characters
- while current do
- if current.id == glyph and current.font == font then
- local components = current.components
- if components then
- local last, next = components, current.next
- while last.next do last = last.next end
- if next then
- next.prev = last
- end
- last.next= next
- current.next = components
- components.prev = current
- current.components = nil
- current = last.next
- done = true
- else
- current = current.next
- end
- else
- current = current.next
- end
- end
- return head, done
- else
- return head, false
- end
+ if first and first == last then
+ set_attribute(last,state,4) -- isol
+ elseif last then
+ set_attribute(last,state,3) -- fina
end
-
+ return head, done
end
function tfm.replacements(tfm,value)
@@ -800,7 +690,7 @@ function tfm.enhance(tfmdata,specification)
tfmdata.filename = specification.name
if not features.encoding then
local name, size = specification.name, specification.size
- local encoding, filename = name:match("^(.-)%-(.*)$") -- context: encoding-name.*
+ local encoding, filename = match(name,"^(.-)%-(.*)$") -- context: encoding-name.*
if filename and encoding and fonts.enc.known[encoding] then
features.encoding = encoding
end
@@ -809,6 +699,7 @@ tfmdata.filename = specification.name
end
function tfm.set_features(tfmdata)
+ -- todo: no local functions
local shared = tfmdata.shared
-- local tfmdata = shared.tfmdata
local features = shared.features
@@ -818,7 +709,8 @@ function tfm.set_features(tfmdata)
if fi and fi.tfm then
local function initialize(list) -- using tex lig and kerning
if list then
- for _, f in ipairs(list) do
+ for i=1,#list do
+ local f = list[i]
local value = features[f]
if value and fi.tfm[f] then -- brr
if tfm.trace_features then
@@ -839,7 +731,8 @@ function tfm.set_features(tfmdata)
if fm and fm.tfm then
local function register(list) -- node manipulations
if list then
- for _, f in ipairs(list) do
+ for i=1,#list do
+ local f = list[i]
if features[f] and fm.tfm[f] then -- brr
if not shared.processors then -- maybe also predefine
shared.processors = { fm.tfm[f] }
@@ -866,13 +759,13 @@ function tfm.reencode(tfmdata,encoding)
if data then
local characters, original, vector = tfmdata.characters, { }, data.vector
tfmdata.encoding = encoding -- not needed
- for k, v in pairs(characters) do
+ for k, v in next, characters do
v.name, v.index, original[k] = vector[k], k, v
end
- for k,v in pairs(data.unicodes) do
+ for k,v in next, data.unicodes do
if k ~= v then
- if fonts.trace then
- logs.report("define font","reencoding %04X to %04X",k,v)
+ if trace_defining then
+ logs.report("define font","reencoding U+%04X to U+%04X",k,v)
end
characters[k] = original[v]
end
@@ -893,13 +786,13 @@ function tfm.remap(tfmdata,remapping)
local vector = remapping and fonts.enc.remappings[remapping]
if vector then
local characters, original = tfmdata.characters, { }
- for k, v in pairs(characters) do
+ for k, v in next, characters do
original[k], characters[k] = v, nil
end
- for k,v in pairs(vector) do
+ for k,v in next, vector do
if k ~= v then
- if fonts.trace then
- logs.report("define font","remapping %04X to %04X",k,v)
+ if trace_defining then
+ logs.report("define font","remapping U+%04X to U+%04X",k,v)
end
local c = original[k]
characters[v] = c
@@ -915,3 +808,11 @@ tfm.features.register('remap')
fonts.initializers.base.tfm.remap = tfm.remap
fonts.initializers.node.tfm.remap = tfm.remap
+
+-- status info
+
+statistics.register("fonts load time", function()
+ if statistics.elapsedindeed(fonts) then
+ return format("%s seconds",statistics.elapsedtime(fonts))
+ end
+end)
diff --git a/tex/context/base/font-tra.mkiv b/tex/context/base/font-tra.mkiv
new file mode 100644
index 000000000..c45e1394d
--- /dev/null
+++ b/tex/context/base/font-tra.mkiv
@@ -0,0 +1,113 @@
+%D \module
+%D [ file=font-tra,
+%D version=2009.01.02, % or so
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=Tracing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 \macros
+%D {doiffontpresentelse}
+%D
+%D \starttyping
+%D \doiffontpresentelse{texnansi-lmr10}{YES}{NO}
+%D \doiffontpresentelse{adam-lindsay-modern-serif}{YES}{NO}
+%D \stoptyping
+
+\def\doiffontpresentelse#1{\ctxlua{commands.doifelse(fonts.names.exists("#1"))}}
+
+% experimental, maybe this becomes a module
+
+\newbox\otfcollector
+
+\def\startotfcollecting{\ctxlua{nodes.tracers.steppers.start()}}
+\def\stopotfcollecting {\ctxlua{nodes.tracers.steppers.stop()}}
+\def\resetotfcollecting{\ctxlua{nodes.tracers.steppers.reset()}}
+
+% Rather experimental:
+%
+% \page \showotfcomposition{arabtype*arab-default at 48pt}{-1}{الضَّرَّ} \page
+% \page \showotfcomposition{arabtype*arab-default at 48pt}{-1}{لِلّٰهِ} \page
+
+\def\showotfstepglyphs#1%
+ {\ctxlua{nodes.tracers.steppers.glyphs(\number\otfcollector,#1)}%
+ \unhbox\otfcollector}
+
+\def\otfstepcharcommand#1#2% font char
+ {\removeunwantedspaces
+ \hskip.5em plus .125em\relax
+ U+\hexnumber{#2}:\ruledhbox{\ctxlua{nodes.tracers.fontchar(#1,#2)}}%
+ \hskip.5em plus .125em\relax}
+
+\def\otfstepmessagecommand#1#2%
+ {\begingroup
+ \tttf\language\minusone
+ \veryraggedright
+ \hangindent1em
+ \hangafter\plusone
+ \dontleavehmode\hbox{\detokenize{#1}}\removeunwantedspaces
+ \doifsomething{#2}{\break\detokenize{#2}}\endgraf
+ \endgroup
+ \blank}
+
+\def\showotfstepchars#1%
+ {\ctxlua{nodes.tracers.steppers.codes(#1,\!!bs\detokenize{\otfstepcharcommand}\!!es)}}
+
+\def\showotfstepmessages#1%
+ {\ctxlua{nodes.tracers.steppers.messages(#1,\!!bs\detokenize{\otfstepmessagecommand}\!!es,true)}}
+
+\def\showotfstepfeatures
+ {\ctxlua{nodes.tracers.steppers.features()}}
+
+\def\showotfsteps
+ {\dontleavehmode\bgroup\tttf \language\minusone features: \showotfstepfeatures\egroup
+ \blank
+ \dontleavehmode\bgroup\tttf result:\egroup
+ \blank
+ \startlinecorrection
+ \ruledhbox\bgroup\box\otfcompositionbox\egroup
+ \stoplinecorrection
+ \dorecurse{\ctxlua{nodes.tracers.steppers.nofsteps()}}
+ {\blank
+ \showotfstepmessages\recurselevel
+ \blank
+ \startlinecorrection
+ \dontleavehmode\bgroup\resetallattributes\pardir TLT\textdir TLT\relax\tttf\recurselevel: \showotfstepchars\recurselevel\egroup
+ \stoplinecorrection
+ \blank
+ \startlinecorrection
+ \ruledhbox % can be mode
+ \bgroup\resetallattributes\showotfstepglyphs\recurselevel\egroup % reset is new, we don't want additional processing
+ \stoplinecorrection
+ \blank}}
+
+\def\startotfsample
+ {\enabletrackers[*otf.sample]% beware, kind of global
+ \startotfcollecting
+ \begingroup}
+
+\def\stopotfsample
+ {\endgroup
+ \stopotfcollecting
+ \disabletrackers[*otf.sample]% beware, kind of global: otf.sample
+ \showotfsteps
+ \resetotfcollecting}
+
+\newbox\otfcompositionbox
+
+\def\showotfcomposition#1#2#3% {font*features at size}, rl=-1, text
+ {\begingroup
+ \setupcolors[\c!state=\v!start]% can be option
+ \startotfsample
+ \global\setbox\otfcompositionbox\hbox{\definedfont[#1]\ifnum#2<0 \textdir TRT\else\ifnum#2>0 \textdir TLT\fi\fi\relax#3}%
+ \stopotfsample
+ \endgroup}
+
+\protect \endinput
diff --git a/tex/context/base/font-uni.tex b/tex/context/base/font-uni.mkii
index 7d4f3e442..1b8ce8e43 100644
--- a/tex/context/base/font-uni.tex
+++ b/tex/context/base/font-uni.mkii
@@ -2,7 +2,7 @@
%D [ file=font-uni,
%D version=1999.10.10,
%D title=\CONTEXT\ Font Macros,
-%D subtitle=\UNICODE\ Initialization,
+%D subtitle=\UNICODE,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,18 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Font Macros / UNICODE Support}
+\writestatus{loading}{ConTeXt Font Macros / Unicode}
+
+%D In \XETEX, unicode support is straightforward, so we
+%D simply output a \type {\char} with a 16||bit number.
+
+\ifnum\texengine=\xetexengine
+ \unexpanded\def\uchar#1#2{\char\numexpr#2+#1*\pluscclvi\relax}
+ \let\uc\uchar
+ \endinput
+\fi
+
+%D Now comes the more traditional 8 bit \TEX\ hackery.
%D I wrote this module when Wang Lei asked me how to use
%D Chinese in \CONTEXT. From the samples he sent me, I deduced
@@ -25,25 +36,6 @@
%D is involved, which is why the macros handling those
%D characters look ahead.
-% \startmessages dutch library: fonts
-% 21: het is veiliger om (pdf)eTeX te gebruiken
-% \stopmessages
-% \startmessages english library: fonts
-% 21: using (pdf)eTeX is more save
-% \stopmessages
-% \startmessages german library: fonts
-% 21: Verwenden von (pdf)eTeX ist sicherer
-% \stopmessages
-% \startmessages italian library: fonts
-% 21: l'uso di (pdf)eTeX è più sicuro
-% \stopmessages
-% \startmessages norwegian library: fonts
-% 21: å bruke (pdf)eTeX er tryggere
-% \stopmessages
-% \startmessages french library: fonts
-% 21: l'utilisation de (pdf)eTeX est plus économe
-% \stopmessages
-
\unprotect
%D \macros
@@ -136,19 +128,6 @@
{\def\dolookaheaduchar{\uchar{#1}{#2}\let\nextutoken\relax}%
\futurelet\nextutoken\dolookaheaduchar}
-%D In \XETEX, unicode support is straightforward, so we
-%D simply output a \type {\char} with a 16||bit number.
-%D
-%D \starttyping
-%D \def\uchar#1#2{\char\numexpr(#2+(#1*256))\relax}
-%D \stoptyping
-
-\beginXETEX \uchar
-
- \unexpanded\def\uchar#1#2{\char\numexpr#2+#1*\@cclvi\relax}
-
-\endXETEX
-
\def\dohandleucflowglyph
{\unicodeposition\numexpr\unicodeone*256+\unicodetwo\relax
\handleunicodeglyph
diff --git a/tex/context/base/font-uni.mkiv b/tex/context/base/font-uni.mkiv
new file mode 100644
index 000000000..40ab75ed6
--- /dev/null
+++ b/tex/context/base/font-uni.mkiv
@@ -0,0 +1,26 @@
+%D \module
+%D [ file=font-uni,
+%D version=2008.11.03, % 1999.10.10,
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=\UNICODE,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Font Macros / Unicode}
+
+%D In \MKIV\ we only provide the \type {\uchar} macro and
+%D implement it as just an \UTF\ converter. We expand it so
+%D best not use not use it for active characters.
+
+\unprotect
+
+\def\uchar#1#2{\ctxlua{commands.uchar(\number#1,\number#2)}}
+
+\let\uc\uchar
+
+\protect \endinput
diff --git a/tex/context/base/font-unk.tex b/tex/context/base/font-unk.mkii
index 4e450ae74..30f824781 100644
--- a/tex/context/base/font-unk.tex
+++ b/tex/context/base/font-unk.mkii
@@ -16,6 +16,8 @@
%D completely independant of real font names. First we map
%D some meaningful names onto unknown filenames.
+\unprotect
+
\definefontsynonym [Serif] [unknown]
\definefontsynonym [SerifBold] [unknown]
\definefontsynonym [SerifItalic] [unknown]
@@ -182,4 +184,4 @@
%D mapped onto real file names (or names that themselves are
%D mapped).
-\endinput
+\protect \endinput
diff --git a/tex/context/base/font-unk.mkiv b/tex/context/base/font-unk.mkiv
new file mode 100644
index 000000000..bd699ef71
--- /dev/null
+++ b/tex/context/base/font-unk.mkiv
@@ -0,0 +1,162 @@
+%D \module
+%D [ file=font-unk,
+%D version=1998.09.10,
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=Unknown Defaults,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 rather important, because it enables us to
+%D define and call for not yet defined fonts in a way
+%D completely independant of real font names. First we map
+%D some meaningful names onto unknown filenames.
+
+\unprotect
+
+\definefontsynonym [Serif] [unknown]
+\definefontsynonym [SerifBold] [unknown]
+\definefontsynonym [SerifItalic] [unknown]
+\definefontsynonym [SerifSlanted] [unknown]
+\definefontsynonym [SerifBoldItalic] [unknown]
+\definefontsynonym [SerifBoldSlanted] [unknown]
+\definefontsynonym [SerifCaps] [unknown]
+
+\definefontsynonym [Sans] [unknown]
+\definefontsynonym [SansBold] [unknown]
+\definefontsynonym [SansItalic] [unknown]
+\definefontsynonym [SansSlanted] [unknown]
+\definefontsynonym [SansBoldItalic] [unknown]
+\definefontsynonym [SansBoldSlanted] [unknown]
+\definefontsynonym [SansCaps] [unknown]
+
+\definefontsynonym [Mono] [unknown]
+\definefontsynonym [MonoBold] [unknown]
+\definefontsynonym [MonoItalic] [unknown]
+\definefontsynonym [MonoSlanted] [unknown]
+\definefontsynonym [MonoBoldItalic] [unknown]
+\definefontsynonym [MonoBoldSlanted] [unknown]
+\definefontsynonym [MonoCaps] [unknown]
+
+\definefontsynonym [MathRoman] [unknown]
+\definefontsynonym [MathExtension] [unknown]
+\definefontsynonym [MathItalic] [unknown]
+\definefontsynonym [MathSymbol] [unknown]
+
+\definefontsynonym [MathNoName] [unknown]
+
+\definefontsynonym [MathAlpha] [unknown]
+\definefontsynonym [MathBeta] [unknown]
+\definefontsynonym [MathGamma] [unknown]
+\definefontsynonym [MathDelta] [unknown]
+
+\definefontsynonym [MathRomanBold] [MathRoman] % todo:
+\definefontsynonym [MathExtensionBold] [MathExtension] % [MathRoman]
+\definefontsynonym [MathItalicBold] [MathItalic] % [MathRoman]
+\definefontsynonym [MathSymbolBold] [MathSymbol] % [MathRoman]
+\definefontsynonym [MathAlphaBold] [MathAlpha] % [MathRoman]
+\definefontsynonym [MathBetaBold] [MathBeta] % [MathRoman]
+\definefontsynonym [MathGammaBold] [MathGamma] % [MathRoman]
+\definefontsynonym [MathDeltaBold] [MathDelta] % [MathRoman]
+
+\definefontsynonym [Handwriting] [unknown]
+\definefontsynonym [Calligraphic] [unknown]
+
+%D This permit us to define (use) fonts that refer to the default
+%D style (so, Bold may expand to SansBold or SerifBold, depending
+%D on the default style in the typeface).
+
+\definefontsynonym[\s!Normal] [\noexpand\fontstringD]
+\definefontsynonym[\s!Bold] [\noexpand\fontstringD\noexpand\s!Bold]
+\definefontsynonym[\s!Italic] [\noexpand\fontstringD\noexpand\s!Italic]
+\definefontsynonym[\s!Slanted] [\noexpand\fontstringD\noexpand\s!Slanted]
+\definefontsynonym[\s!BoldItalic] [\noexpand\fontstringD\noexpand\s!BoldItalic]
+\definefontsynonym[\s!BoldSlanted][\noexpand\fontstringD\noexpand\s!BoldSlanted]
+\definefontsynonym[\s!Caps] [\noexpand\fontstringD\noexpand\s!Caps]
+
+%D Also handy:
+
+\definefontsynonym [Regular] [Serif]
+\definefontsynonym [RegularBold] [SerifBold]
+\definefontsynonym [RegularItalic] [SerifItalic]
+\definefontsynonym [RegularSlanted] [SerifSlanted]
+\definefontsynonym [RegularBoldItalic] [SerifBoldItalic]
+\definefontsynonym [RegularBoldSlanted] [SerifBoldSlanted]
+\definefontsynonym [RegularCaps] [SerifCaps]
+
+\definefontsynonym [Support] [Sans]
+\definefontsynonym [SupportBold] [SansBold]
+\definefontsynonym [SupportItalic] [SansItalic]
+\definefontsynonym [SupportSlanted] [SansSlanted]
+\definefontsynonym [SupportBoldItalic] [SansBoldItalic]
+\definefontsynonym [SupportBoldSlanted] [SansBoldSlanted]
+\definefontsynonym [SupportCaps] [SansCaps]
+
+%D Well, not that good an idea:
+
+\definefontsynonym [Roman] [Serif]
+\definefontsynonym [RomanBold] [SerifBold]
+\definefontsynonym [RomanItalic] [SerifItalic]
+\definefontsynonym [RomanSlanted] [SerifSlanted]
+\definefontsynonym [RomanBoldItalic] [SerifBoldItalic]
+\definefontsynonym [RomanBoldSlanted] [SerifBoldSlanted]
+\definefontsynonym [RomanCaps] [SerifCaps]
+
+\definefontsynonym [Type] [Mono]
+\definefontsynonym [TypeBold] [MonoBold]
+\definefontsynonym [TypeItalic] [MonoItalic]
+\definefontsynonym [TypeSlanted] [MonoSlanted]
+\definefontsynonym [TypeBoldItalic] [MonoBoldItalic]
+\definefontsynonym [TypeBoldSlanted] [MonoBoldSlanted]
+\definefontsynonym [TypeCaps] [MonoCaps]
+
+%D Next we define roman, sans and monospaced font sets.
+
+\definebodyfont [default] [rm]
+ [tf=Serif sa 1,
+ bf=SerifBold sa 1,
+ it=SerifItalic sa 1,
+ sl=SerifSlanted sa 1,
+ bi=SerifBoldItalic sa 1,
+ bs=SerifBoldSlanted sa 1,
+ sc=SerifCaps sa 1]
+
+\definebodyfont [default] [ss]
+ [tf=Sans sa 1,
+ bf=SansBold sa 1,
+ it=SansItalic sa 1,
+ sl=SansSlanted sa 1,
+ bi=SansBoldItalic sa 1,
+ bs=SansBoldSlanted sa 1,
+ sc=SansCaps sa 1]
+
+\definebodyfont [default] [tt]
+ [tf=Mono sa 1,
+ bf=MonoBold sa 1,
+ it=MonoItalic sa 1,
+ sl=MonoSlanted sa 1,
+ bi=MonoBoldItalic sa 1,
+ bs=MonoBoldSlanted sa 1,
+ sc=MonoCaps sa 1]
+
+\definebodyfont [default] [mm]
+ [mr=MathRoman mo 1]
+
+\definebodyfont [bfmath] [mm]
+ [mr=MathRomanBold mo 1]
+
+\definebodyfont [default] [hw]
+ [tf=Handwriting sa 1]
+
+\definebodyfont [default] [cg]
+ [tf=Calligraphy sa 1]
+
+%D These definitions come into action as soon as names are
+%D mapped onto real file names (or names that themselves are
+%D mapped).
+
+\protect \endinput
diff --git a/tex/context/base/font-vf.lua b/tex/context/base/font-vf.lua
index 37e4eeb6e..c103555a3 100644
--- a/tex/context/base/font-vf.lua
+++ b/tex/context/base/font-vf.lua
@@ -64,7 +64,7 @@ end
function vf.aux.combine.process(g,list)
if list then
- for _,v in pairs(list) do
+ for _,v in next, list do
(vf.aux.combine.commands[v[1]] or nop)(g,v)
end
end
@@ -81,7 +81,7 @@ function vf.aux.combine.names(g,name,force)
local fd, gd = f.descriptions, g.descriptions
g.fonts[#g.fonts+1] = { id = id } -- no need to be sparse
local hn = #g.fonts
- for k, v in pairs(fc) do
+ for k, v in next, fc do
if force or not gc[k] then
gc[k] = table.fastcopy(v)
gc[k].commands = { { 'slot', hn, k } }
@@ -113,7 +113,8 @@ vf.aux.combine.commands = {
function vf.combine(specification,tag)
local g = {
name = specification.name,
- type = 'virtual',
+ -- type = 'virtual',
+ virtualized = true,
fonts = { },
characters = { },
descriptions = { },
@@ -180,12 +181,11 @@ fonts.define.methods.install(
fonts.define.methods["demo-1"] = function(specification)
local name = specification.name -- symbolic name
local size = specification.size -- given size
---~ specification.name = 'lmroman10-regular' -- forced base name
---~ specification.features.vtf = { }
local f, id = tfm.read_and_define('lmroman10-regular',size)
if f and id then
local capscale, digscale = 0.85, 0.75
- f.name, f.type = name, 'virtual'
+ -- f.name, f.type = name, 'virtual'
+ f.name, f.virtualized = name, true
f.fonts = {
{ id = id },
{ name = 'lmsans10-regular' , size = size*capscale }, -- forced extra name
@@ -193,65 +193,21 @@ fonts.define.methods["demo-1"] = function(specification)
}
local i_is_of_category = characters.i_is_of_category
local characters, descriptions = f.characters, f.descriptions
- for u,v in pairs(characters) do
+ local red = {'special','pdf: 1 0 0 rg'}
+ local green = {'special','pdf: 0 1 0 rg'}
+ local blue = {'special','pdf: 0 0 1 rg'}
+ local black = {'special','pdf: 0 g'}
+ for u,v in next, characters do
if u and i_is_of_category(u,'lu') then
v.width = capscale*v.width
- v.commands = {
- {'special','pdf: 1 0 0 rg'},
- {'slot',2, u},
- {'special','pdf: 0 g'},
- }
+ v.commands = { red, {'slot',2,u}, black }
elseif u and i_is_of_category(u,'nd') then
v.width = digscale*v.width
- v.commands = {
- {'special','pdf: 0 0 1 rg'},
- {'slot',3,u},
- {'special','pdf: 0 g'},
- }
+ v.commands = { blue, {'slot',3,u}, black }
else
- v.commands = {
- {'special','pdf: 0 1 0 rg'},
- {'slot',1,u},
- {'special','pdf: 0 g'},
- }
+ v.commands = { green, {'slot',1,u}, black }
end
end
end
return f
end
-
--- keep as example, now tfm feature
-
---~ vf.aux.combine.commands["lineheight"] = function(g,v)
---~ if g.ascender and g.descender then
---~ local ht, dp = g.ascender or 0, g.descender or 0
---~ if v[2] == "none" then
---~ for _,v in pairs(g.characters) do
---~ v.height = 0
---~ v.depth = 0
---~ end
---~ else
---~ if v[2] == "height" then
---~ dp = 0
---~ elseif v[2] == "depth" then
---~ ht = 0
---~ end
---~ if ht > 0 then
---~ if dp > 0 then
---~ for _,v in pairs(g.characters) do
---~ v.height = ht
---~ v.depth = dp
---~ end
---~ else
---~ for _,v in pairs(g.characters) do
---~ v.height = ht
---~ end
---~ end
---~ elseif dp > 0 then
---~ for _,v in pairs(g.characters) do
---~ v.depth = dp
---~ end
---~ end
---~ end
---~ end
---~ end
diff --git a/tex/context/base/font-xtx.lua b/tex/context/base/font-xtx.lua
new file mode 100644
index 000000000..63e421fa4
--- /dev/null
+++ b/tex/context/base/font-xtx.lua
@@ -0,0 +1,115 @@
+if not modules then modules = { } end modules ['font-xtx'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local texsprint, count = tex.sprint, tex.count
+local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower
+local tostring, next = tostring, next
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+--[[ldx--
+<p>Choosing a font by name and specififying its size is only part of the
+game. In order to prevent complex commands, <l n='xetex'/> introduced
+a method to pass feature information as part of the font name. At the
+risk of introducing nasty parsing and compatinility problems, this
+syntax was expanded over time.</p>
+
+<p>For the sake of users who have defined fonts using that syntax, we
+will support it, but we will provide additional methods as well.
+Normally users will not use this direct way, but use a more abstract
+interface.</p>
+
+<p>The next one is the official one. However, in the plain
+variant we need to support the crappy [] specification as
+well and that does not work too well with the general design
+of the specifier.</p>
+--ldx]]--
+
+--~ function fonts.define.specify.colonized(specification) -- xetex mode
+--~ local list = { }
+--~ if specification.detail and specification.detail ~= "" then
+--~ for v in gmatch(specification.detail,"%s*([^;]+)%s*") do
+--~ local a, b = match(v,"^(%S*)%s*=%s*(%S*)$")
+--~ if a and b then
+--~ list[a] = b:is_boolean()
+--~ if type(list[a]) == "nil" then
+--~ list[a] = b
+--~ end
+--~ else
+--~ local a, b = match(v,"^([%+%-]?)%s*(%S+)$")
+--~ if a and b then
+--~ list[b] = a ~= "-"
+--~ end
+--~ end
+--~ end
+--~ end
+--~ specification.features.normal = list
+--~ return specification
+--~ end
+
+--~ check("oeps/BI:+a;-b;c=d")
+--~ check("[oeps]/BI:+a;-b;c=d")
+--~ check("file:oeps/BI:+a;-b;c=d")
+--~ check("name:oeps/BI:+a;-b;c=d")
+
+local list = { }
+
+fonts.define.specify.colonized_default_lookup = "file"
+
+local function issome () list.lookup = fonts.define.specify.colonized_default_lookup end
+local function isfile () list.lookup = 'file' end
+local function isname () list.lookup = 'name' end
+local function thename(s) list.name = s end
+local function issub (v) list.sub = v end
+local function iscrap (s) list.crap = string.lower(s) end
+local function istrue (s) list[s] = 'yes' end
+local function isfalse(s) list[s] = 'no' end
+local function iskey (k,v) list[k] = v end
+
+local spaces = lpeg.P(" ")^0
+local namespec = (1-lpeg.S("/: ("))^0
+local crapspec = spaces * lpeg.P("/") * (((1-lpeg.P(":"))^0)/iscrap) * spaces
+local filename = (lpeg.P("file:")/isfile * (namespec/thename)) + (lpeg.P("[") * lpeg.P(true)/isname * (((1-lpeg.P("]"))^0)/thename) * lpeg.P("]"))
+local fontname = (lpeg.P("name:")/isname * (namespec/thename)) + lpeg.P(true)/issome * (namespec/thename)
+local sometext = (lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09"))^1
+local truevalue = lpeg.P("+") * spaces * (sometext/istrue)
+local falsevalue = lpeg.P("-") * spaces * (sometext/isfalse)
+local keyvalue = (lpeg.C(sometext) * spaces * lpeg.P("=") * spaces * lpeg.C(sometext))/iskey
+local somevalue = sometext/istrue
+local subvalue = lpeg.P("(") * (lpeg.C(lpeg.P(1-lpeg.S("()"))^1)/issub) * lpeg.P(")") -- for Kim
+local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces
+local options = lpeg.P(":") * spaces * (lpeg.P(";")^0 * option)^0
+local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0
+
+function fonts.define.specify.colonized(specification) -- xetex mode
+ list = { }
+ pattern:match(specification.specification)
+ for k, v in next, list do
+ list[k] = v:is_boolean()
+ if type(list[a]) == "nil" then
+ list[k] = v
+ end
+ end
+ list.crap = nil -- style not supported, maybe some day
+ if list.name then
+ specification.name = list.name
+ list.name = nil
+ end
+ if list.lookup then
+ specification.lookup = list.lookup
+ list.lookup = nil
+ end
+ if list.sub then
+ specification.sub = list.sub
+ list.sub = nil
+ end
+ specification.features.normal = list
+ return specification
+end
+
+fonts.define.register_split(":", fonts.define.specify.colonized)
diff --git a/tex/context/base/font-xtx.tex b/tex/context/base/font-xtx.tex
new file mode 100644
index 000000000..5f4b85879
--- /dev/null
+++ b/tex/context/base/font-xtx.tex
@@ -0,0 +1,357 @@
+%D \module
+%D [ file=font-xtx,
+%D version=2004.09.11,
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=\XETEX\ Hacks,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifnum\texengine=\xetexengine
+ \writestatus{loading}{ConTeXt Font Macros / XeTeX Hacks}
+\else
+ \endinput
+\fi
+
+\unprotect
+
+%D Loading:
+
+%D for some reason xetex does not support [filename] for tfm files and
+%D quotes also behave kind of strange " vs ' vs [ vs ...
+%D
+%D \starttyping
+%D \font\myfont = msam7 % ok
+%D \font\myfont = "msam7" % also ok
+%D \font\myfont = "msam7" at 8pt % error
+%D \stoptyping
+
+\newconditional\tracexetexfonts
+
+%D Because \XETEX\ is not that fast on locating fonts we cache lookups so
+%D that we minimize the test. It saves a little bit of runtime, depending
+%D on the number of fonts loaded (which is normally not that much).
+
+\def\doiffoundXTXfontelse#1#2%
+ {\ifcsname xtx@fnt@#2\somefontspec\endcsname
+ \ifconditional\tracexetexfonts
+ \writestatus\m!fonts{already checked #1: #2\somefontspec\space (state: \number\csname xtx@fnt@#2\somefontspec\endcsname)}%
+ \fi
+ \else
+ \suppressfontnotfounderror\plusone
+ \font\xetextempfont=#2\somefontspec\relax
+ \suppressfontnotfounderror\zerocount
+ \edef\xetextempfont{\fontname\xetextempfont}%
+ \global\expandafter\chardef\csname xtx@fnt@#2\somefontspec\endcsname
+ \ifx\xetextempfont\nullfontname
+ \zerocount \ifconditional\tracexetexfonts
+ \writestatus\m!fonts{not found #1: #2\somefontspec}%
+ \fi
+ \else
+ \plusone \ifconditional\tracexetexfonts
+ \writestatus\m!fonts{found #1: #2\somefontspec}%
+ \fi
+ \fi
+ \fi
+ \ifcase\csname xtx@fnt@#2\somefontspec\endcsname
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+\def\docheckfontfilenameprefix#1:#2:#3#4\relax
+ {\edef\!!stringa{#1}%
+ \edef\!!stringb{#2}%
+ \ifx\!!stringb\empty
+ % no prefix
+ \let\checkedfontfile\!!stringa
+ \doiffoundXTXfontelse{1a}{\checkedfontfile\checkedfontfeatures}
+ {\edef\checkedfontfile{\checkedfontfile\checkedfontfeatures}}
+ {\doiffoundXTXfontelse{1b}{"\checkedfontfile\checkedfontfeatures"}
+ {\edef\checkedfontfile{"\checkedfontfile\checkedfontfeatures"}}
+ {\doiffoundXTXfontelse{1c}{"[\checkedfontfile]\checkedfontfeatures"}
+ {\edef\checkedfontfile{"[\checkedfontfile]\checkedfontfeatures"}}
+ {}}}%
+ \else\ifx\!!stringa\v!file
+ % force file, only file check when no spaces
+ \let\checkedfontfile\!!stringb
+ \doiffoundXTXfontelse{2a}{"[\checkedfontfile]\checkedfontfeatures"}
+ {\edef\checkedfontfile{"[\checkedfontfile]\checkedfontfeatures"}}
+ {\doiffoundXTXfontelse{2b}{"\checkedfontfile\checkedfontfeatures"}
+ {\edef\checkedfontfile{"\checkedfontfile\checkedfontfeatures"}}
+ {}}%
+ \else\ifx\!!stringa\v!name
+ % force name, always lookup by xetex itself, "" forces otf/ttf/type1
+ \edef\checkedfontfile{"\!!stringb\checkedfontfeatures"}%
+ \ifconditional\tracexetexfonts
+ \writestatus\m!fonts{no checking 3a: \checkedfontfile}%
+ \fi
+ \else
+ % whatever, maybe even xetex spec, forget about features
+ \edef\checkedfontfile{"\!!stringa\!!stringb"}%
+ \ifconditional\tracexetexfonts
+ \writestatus\m!fonts{no checking 3b: \checkedfontfile}%
+ \fi
+ \fi\fi\fi}
+
+\def\checkfontfilename% -- todo: integrate so that we call do.. directly
+ {\expandafter\docheckfontfilename\fontfile*\empty*\relax}
+
+\def\docheckfontfilename#1*#2#3*#4\relax % class overrules file
+ {\edef\checkedfontfeatures
+ {\expandafter\ifx\csname\fontclass\s!features\endcsname\empty
+ \ifx\@@fontfeatures\empty\ifx#2\empty\else#2#3\fi\else\@@fontfeatures\fi
+ \else\expandafter\ifx\csname\fontclass\s!features\endcsname\relax % redundant, will go away
+ \ifx\@@fontfeatures\empty\ifx#2\empty\else#2#3\fi\else\@@fontfeatures\fi
+ \else
+ \csname\fontclass\s!features\endcsname
+ \fi\fi}%
+ \ifx\checkedfontfeatures\empty
+ % done
+ \else
+ \edef\checkedfontfeatures{\executeifdefined{\??fa\checkedfontfeatures}\empty}%
+ \ifx\checkedfontfeatures\empty
+ % done
+ \else
+ \let\convertedfontfeatures\empty
+ \processcommacommand[\checkedfontfeatures]\doconvertfontfeatures % raw
+ \ifx\convertedfontfeatures\empty
+ \let\checkedfontfeatures\empty
+ \else
+ \edef\checkedfontfeatures{:\convertedfontfeatures}%
+ \fi
+ \fi
+ \fi
+ \docheckfontfilenameprefix#1:\empty:\empty\relax
+ \doshowcheckedfontfeatures}
+
+\def\dodoconvertfontfeatures#1=#2#3=#4\relax
+ {\ifx#2\empty
+ % invalid feature
+ \else\ifcsname @xtx@#1@#2#3\endcsname
+ \expandafter\ifx\csname @xtx@#1@#2#3\endcsname\empty\else
+ \edef\convertedfontfeatures{\convertedfontfeatures\csname @xtx@#1@#2#3\endcsname;}%
+ \fi
+ \else
+ \edef\!!stringa{#1}%
+ \edef\!!stringb{#2#3}%
+ \edef\convertedfontfeatures
+ {\convertedfontfeatures
+ \ifx\!!stringb\v!yes
+ +\!!stringa
+ \else\ifx\!!stringb\v!no
+ -\!!stringa
+ \else
+ \!!stringa=\!!stringb
+ \fi\fi;}%
+ \fi\fi}
+
+\def\doconvertfontfeatures#1%
+ {\dodoconvertfontfeatures#1=\empty=\relax}
+
+\def\remapfontfeature #1 #2 #3 {\setevalue{@xtx@#1@#2}{#3}}
+
+% this may move to another file, maybe font-xtx
+
+\remapfontfeature tlig yes mapping=tlig
+%remapfontfeature tlig no mapping=
+\remapfontfeature trep yes {}
+\remapfontfeature trep no {}
+\remapfontfeature texligatures yes mapping=tlig
+%remapfontfeature texligatures no mapping=
+%remapfontfeature texquotes yes mapping=tex-text
+%remapfontfeature texquotes no mapping=
+
+%D Variants:
+
+\unexpanded\def\variant[#1]%
+ {\dosetscaledfont
+ \font\variantfont\truefontname{\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1}} at \scaledfont
+ \variantfont}
+
+%D Possible optimizations:
+
+% \def\updatefontparameters
+% {\edef\@@fontfeatures{\truefontdata\fontfile\s!features}%
+% \edef\@@fontskewchar{\truefontdata\fontfile\s!skewchar}}
+
+% \def\setfontcharacteristics
+% {\updatefontparameters % redundant, will go away, faster too
+% \the\everyfont}
+
+% \let\synchronizepatternswithfont\relax
+
+%D Names:
+
+% We need to move the feature into the filename else it may be
+% overloaded by another reference. For instance the definition of
+% a regular and caps variant can use the same font.
+
+% We could use an indirect method ... store in 'array' and refer to
+% slot.
+
+\def\definefontsynonym[#1]#2[#3]%
+ {\edef\@@fontname{#1}%
+ \edef\@@fontfile{#3}%
+ \doifnextoptionalelse\dodefinefontsynonym\nodefinefontsynonym}
+
+\def\nodefinefontsynonym
+ {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile}
+
+\def\dodefinefontsynonym[#1]%
+ {\edef\@@fontdata{#1}%
+ \ifx\@@fontdata\empty
+ \nodefinefontsynonym
+ \else
+ \ifx\fontclass\empty
+ \getfontparameters
+ \else
+ \getglobalfontparameters
+ \fi
+ \ifcsname\??ff\@@fontfile\s!features\endcsname
+ \@EA\edef\csname\??ff\fontclass\@@fontname\endcsname{\@@fontfile*\csname\??ff\@@fontfile\s!features\endcsname}%
+ \@EA\let\csname\??ff\@@fontfile\s!features\endcsname\undefined
+ \else
+ \nodefinefontsynonym
+ \fi
+ \fi}
+
+\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater
+
+% simple version
+%
+% \def\truefontname#1%
+% {\@EA\dotruefontname#1*\relax}
+%
+% \def\dotruefontname#1*#2\relax
+% {\ifcsname\??ff\fontclass#1\endcsname
+% \@EA\truefontname\csname\??ff\fontclass#1\endcsname
+% \else\ifcsname\??ff#1\endcsname
+% \@EA\truefontname\csname\??ff#1\endcsname
+% \else
+% #1%
+% \fi\fi}
+%
+% last counts
+%
+% \def\truefontname#1%
+% {\@EA\dotruefontname#1*\empty*\relax}
+%
+% \def\dotruefontname#1*#2#3*#4\relax
+% {\ifcsname\??ff\fontclass#1\endcsname
+% \ifx#2\empty
+% \@EA\truefontname\csname\??ff\fontclass#1\endcsname
+% \else
+% \@EA\truefontname\csname\??ff\fontclass#1\endcsname*#2#3%
+% \fi
+% \else\ifcsname\??ff#1\endcsname
+% \ifx#2\empty
+% \@EA\truefontname\csname\??ff#1\endcsname
+% \else
+% \@EA\truefontname\csname\??ff#1\endcsname*#2#3%
+% \fi
+% \else
+% \ifx#2\empty
+% #1%
+% \else
+% #1*#2#3%
+% \fi
+% \fi\fi}
+%
+% first counts
+
+\def\truefontname#1%
+ {\@EA\dotruefontname#1*\empty*\relax}
+
+\def\dotruefontname#1*#2#3*#4\relax
+ {\ifcsname\??ff\fontclass#1\endcsname
+ \ifx#2\empty
+ \@EA\truefontname\csname\??ff\fontclass#1\endcsname
+ \else
+ \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3%
+ \fi
+ \else\ifcsname\??ff#1\endcsname
+ \ifx#2\empty
+ \@EA\truefontname\csname\??ff#1\endcsname
+ \else
+ \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3%
+ \fi
+ \else
+ #1\ifx#2\empty\else*#2#3\fi
+ \fi\fi}
+
+\def\redotruefontname#1%
+ {\@EA\dodotruefontname#1*\relax}
+
+\def\dodotruefontname#1*#2\relax
+ {\ifcsname\??ff\fontclass#1\endcsname
+ \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname
+ \else\ifcsname\??ff#1\endcsname
+ \@EA\redotruefontname\csname\??ff#1\endcsname
+ \else
+ #1%
+ \fi\fi}
+
+%D Default:
+
+\def\defaultfontfile{file:lmmono10-regular}
+
+%D Maybe:
+
+% \def\updatefontparameters
+% {\edef\@@fontfeatures{\truefontdata\fontfile \s!features}%
+% \edef\@@fontskewchar{\truefontdata\fontfile \s!skewchar}}
+
+% \def\setfontcharacteristics
+% {%\updatefontparameters % redundant, will go away, faster too
+% \the\everyfont
+% \synchronizepatternswithfont}
+
+\protect \endinput
+
+% \starttypescript[serif] [myzhfont]
+% \definefontsynonym [Serif] [file:SimSun]
+% \definefontsynonym [SerifBold] [file:SimSun]
+% \definefontsynonym [SerifItalic] [file:SimSun]
+% \definefontsynonym [SerifBoldItalic] [file:SimSun]
+% \stoptypescript
+% \starttypescript[sans] [myzhfont]
+% \definefontsynonym [Sans] [file:SimSun]
+% \definefontsynonym [SansBold] [file:SimSun]
+% \definefontsynonym [SansItalic] [file:SimSun]
+% \definefontsynonym [SansBoldItalic] [file:SimSun]
+% \stoptypescript
+% \starttypescript[mono] [myzhfont]
+% \definefontsynonym [Mono] [file:SimSun]
+% \definefontsynonym [MonoBold] [file:SimSun]
+% \definefontsynonym [MonoItalic] [file:SimSun]
+% \definefontsynonym [MonoBoldItalic] [file:SimSun]
+% \stoptypescript
+% \definetypeface [myzhfont] [rm] [serif][myzhfont] [default]
+% \definetypeface [myzhfont] [ss] [sans] [myzhfont] [default]
+% \definetypeface [myzhfont] [tt] [mono] [myzhfont] [default]
+
+% \starttext
+% % on windows: make sure fonts.conf has no cache mentioned
+% %
+% % 64 sec xetex, 11 sec luatex (56 sec xetex when \nobigmath)
+% %
+% \setupbodyfont[myzhfont] \dorecurse{10000}{{hello {\switchtobodyfont[myzhfont] 你好}}\par}
+% %
+% % 67 sec xetex, 11.5 sec luatex
+% %
+% % \dorecurse{10000}{{hello {\switchtobodyfont[myzhfont] 你好}}\par}
+% %
+% % 5 sec xetex, 7 sec luatex
+% %
+% % \setupbodyfont[myzhfont] \dorecurse{10000}{{hello {你好}}\par}
+% %
+% % 5 sec xetex, 7 sec luatex
+% %
+% % \setupbodyfont[myzhfont] \dorecurse{10000}{{\bf hello {你好}}\par}
+% \stoptext
+
diff --git a/tex/context/base/hand-ini.mkii b/tex/context/base/hand-ini.mkii
index 59c98fa06..42d248df6 100644
--- a/tex/context/base/hand-ini.mkii
+++ b/tex/context/base/hand-ini.mkii
@@ -16,61 +16,21 @@
\unprotect
-\startmessages dutch library: handlings
- title: handling
- 1: font afhandeling --
- 2: font afhandeling -- wordt geladen
- 3: onbekende font afhandeling --
-\stopmessages
-
-\startmessages english library: handlings
- title: handling
- 1: font handling --
- 2: font handling -- is loaded
- 3: unknown font handling --
-\stopmessages
-
-\startmessages german library: handlings % to do
- title: handling
- 1: Font Verarbeitung --
- 2: Font Verarbeitung -- ist geladen
- 3: unknown font handling --
-\stopmessages
-
-\startmessages czech library: handlings % to do
- title: handling
- 1: font handling --
- 2: font handling -- is loaded
- 3: unknown font handling --
-\stopmessages
-
-\startmessages italian library: handlings % to do
- title: handling
- 1: font handling --
- 2: font handling -- is loaded
- 3: unknown font handling --
-\stopmessages
-
-\startmessages norwegian library: handlings % to do
- title: handling
- 1: font handling --
- 2: font handling -- is loaded
- 3: unknown font handling --
-\stopmessages
-
-\startmessages romanian library: handlings % to do
- title: handling
- 1: font handling --
- 2: font handling -- is loaded
- 3: unknown font handling --
-\stopmessages
-
-\startmessages french library: handlings
- title: manipulation
- 1: manipulation -- de police
- 2: la manipulation -- de police est chargée
- 3: manipulation -- inconnue de police
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
\newif\iftracefonthandling % \tracefonthandlingtrue
@@ -81,8 +41,6 @@
% much in common with hz/protruding defs
% todo: fix others
-\let\normalchar\char % also done in enco-ini
-
\def\dosetsomehandling#1#2#3 #4 % no define since directly set
{\ifskiphandlingdef \else
\doifnumberelse{\string#2}
@@ -105,17 +63,6 @@
\let\char\normalchar}}%
\fi}
-% \def\dosettriplethandling#1#2#3 #4 #5 #6 % no define since directly set
-% {\ifskiphandlingdef \else
-% \doifnumberelse{\string#2}
-% {#1{#2#3}{#4}{#5}{#6}}
-% {\doifelsenothing{#3}
-% {#1{`#2}{#4}{#5}{#6}}
-% {\let\char\empty
-% \doifnumberelse{\csname#2#3\endcsname}{#1{\csname#2#3\endcsname}{#4}{#5}{#6}}\donothing
-% \let\char\normalchar}}%
-% \fi}
-
\def\dosetquartethandling#1#2#3 #4 #5 #6 #7 % no define since directly set
{\ifskiphandlingdef \else
\doifnumberelse{\string#2}
@@ -127,14 +74,6 @@
\let\char\normalchar}}%
\fi}
-
-% \def\doinhsomehandling#1#2 #3 %
-% {\ifskiphandlingdef \else
-% \let\char\empty
-% \doifnumberelse{\csname#2\endcsname}{#1{\csname#2\endcsname}{`#3}}\donothing
-% \let\char\normalchar
-% \fi}
-
\def\doinhsomehandling#1#2#3 #4 % to be checked
{\ifskiphandlingdef \else
\if#3\relax\relax
diff --git a/tex/context/base/hand-ini.mkiv b/tex/context/base/hand-ini.mkiv
index 527c32da7..41e9db415 100644
--- a/tex/context/base/hand-ini.mkiv
+++ b/tex/context/base/hand-ini.mkiv
@@ -36,7 +36,7 @@
\appendtoks \disableadjusting \to \everyforgetall % Here or not here?
\appendtoks \disableprotruding \to \everyforgetall % Here or not here?
-\def\startfonthandling #1{\fonthandlingerror\gobbleuntil\stopfonthandling} % can't happen
+\def\startfonthandling #1{\fonthandlingerror\fonthandlingerror\gobbleuntil\stopfonthandling} % can't happen
\def\definefonthandling {\dotripleempty\dodefinefonthandling}
\def\setupfonthandling {\dodoubleempty\dosetupfonthandling }
\def\dodefinefonthandling[#1][#2][#3]{\fonthandlingerror}
diff --git a/tex/context/base/hand-ini.tex b/tex/context/base/hand-ini.tex
deleted file mode 100644
index 4d19b5284..000000000
--- a/tex/context/base/hand-ini.tex
+++ /dev/null
@@ -1,18 +0,0 @@
-%D \module
-%D [ file=hand-ini, % moved from enco-ini / pro
-%D version=2000.12.27, % 1998.12.03,
-%D title=\CONTEXT\ Handling Macros,
-%D subtitle=Initialization,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Handling Macros (ini)}
-
-\loadmarkfile{hand-ini}
-
-\endinput
diff --git a/tex/context/base/java-ini.tex b/tex/context/base/java-ini.mkii
index 7dc2cfe04..e929da108 100644
--- a/tex/context/base/java-ini.tex
+++ b/tex/context/base/java-ini.mkii
@@ -11,10 +11,12 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context JavaScript Macros / Initialization}
+\writestatus{loading}{ConTeXt JavaScript Macros / Initialization}
% BUG: preamble zonder used/used en split
+% todo: lua sanitizer
+
% JavaScript support is under development. In the near future
% a slightly different model will be used. The JScode stuff
% will probably become just auto function inclusion and the
@@ -33,53 +35,21 @@
%D variables to a \JAVASCRIPT\ is closely related to other core
%D macros. First some messages:
-\startmessages dutch library: javascript
- title: javascript
- 1: script set -- wordt geladen
- 2: onbekende preamble --
-\stopmessages
-
-\startmessages english library: javascript
- title: javascript
- 1: loading script set --
- 2: unknown preamble --
-\stopmessages
-
-\startmessages german library: javascript
- title: javascript
- 1: Lade Scriptdatei --
- 2: unbekannte Preamble --
-\stopmessages
-
-\startmessages czech library: javascript
- title: javascript
- 1: nacita se soubor skriptu --
- 2: neznama preambule --
-\stopmessages
-
-\startmessages italian library: javascript
- title: javascript
- 1: caricamento dello script set --
- 2: preambolo sconosciuto --
-\stopmessages
-
-\startmessages norwegian library: javascript
- title: javascript
- 1: leser inn scriptsett --
- 2: ukjent 'preamble' --
-\stopmessages
-
-\startmessages romanian library: javascript
- title: javascript
- 1: se incarca scriptul --
- 2: preambul necunoscut --
-\stopmessages
-
-\startmessages french library: javascript
- title: javascript
- 1: chargement du jeu de script --
- 2: préambule -- inconnu
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
%D \TEX\ is not the right tool to check the \JAVA\ code; the
@@ -428,6 +398,7 @@
{\ifx\allJSpreambles\empty\else
\bgroup
\setverbosecscharacters
+ \obeyspaces \let\obeyedspace\normalspace
\def\par{\delcharacter}% was: { }
\globallet\JSpreamble\empty
\def\@@collectedJSpreamble{\r!java\r!java collected}%
diff --git a/tex/context/base/java-ini.mkiv b/tex/context/base/java-ini.mkiv
new file mode 100644
index 000000000..53c36d65f
--- /dev/null
+++ b/tex/context/base/java-ini.mkiv
@@ -0,0 +1,688 @@
+%D \module
+%D [ file=java-ini,
+%D version=1998.01.30,
+%D title=\CONTEXT\ JavaScript Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 JavaScript Macros / Initialization}
+
+% BUG: preamble zonder used/used en split
+
+% todo: lua sanitizer
+
+% JavaScript support is under development. In the near future
+% a slightly different model will be used. The JScode stuff
+% will probably become just auto function inclusion and the
+% JS_* things will disappear. First I have to find a way to
+% deal with global variables so the 'uses' thing will remain.
+
+% ook p{ref}
+% documentation should be corrected to JS(
+
+% Also, obeylines will be supported.
+
+\unprotect
+
+%D \JAVA\ support is not implemented as a generic support
+%D module. The main reason for this is that passing system
+%D variables to a \JAVASCRIPT\ is closely related to other core
+%D macros. First some messages:
+
+%D \TEX\ is not the right tool to check the \JAVA\ code; the
+%D most we can do is reporting some passed variables:
+
+\newif\iftraceJScode \traceJScodefalse
+
+\let\traceJScode\traceJScodetrue
+
+%D A bit out of place, but not dangerous:
+
+\bgroup
+\catcode127=\@@letter
+\gdef\delcharacter{^^7f}
+\egroup
+
+%D The number of passed variables is minimalized by setting the
+%D next switch.
+
+\newif\ifminimalizeJScode \minimalizeJScodetrue
+
+%D \macros
+%D {JS*}
+%D
+%D Because \JAVASCRIPT's are activated by the user, for
+%D instance by activating on a button, their support is closely
+%D related to the referencing mechanism. Integration takes
+%D place by
+%D
+%D \starttyping
+%D \goto{calculate total}[Sum()]
+%D \stoptyping
+%D
+%D The \type{()} classify this as a script. If they are absent,
+%D the keyword is treated as a normal reference.
+%D
+%D One can pass arguments to such a script by saying:
+%D
+%D \starttyping
+%D \goto{calculate total}[Sum(1.5,2.3)]
+%D \stoptyping
+%D
+%D References are passed by using the \type{R{}} classifier.
+%D
+%D \starttyping
+%D \goto{calculate total}[Sum(1.5,2.3,R{overflow})]
+%D \stoptyping
+%D
+%D The last call calls the script \type{Sum} and passes the
+%D next set of variables:
+%D
+%D \starttyping
+%D JS_S_1="1.5";
+%D JS_S_2="2.3";
+%D JS_R_3="overflow";
+%D JS_P_3=3;
+%D \stoptyping
+%D
+%D The first two parameters are just strings, the third one
+%D however is treated as a reference and results in passing the
+%D reference (if needed this references is prefixed) and the
+%D (real) page number. The alternative:
+%D
+%D \starttyping
+%D \goto{calculate total}[JS(Sum{V{1.5},V{2.3},R{overflow}})]
+%D \stoptyping
+%D
+%D does a verbose passing:
+%D
+%D \starttyping
+%D JS_V_1=1.5;
+%D JS_V_2=2.3;
+%D JS_R_3="overflow";
+%D JS_P_3=3;
+%D \stoptyping
+% %D
+% %D Finally we have a counter that tells\JAVA\ how many
+% %D arguments were passed,
+% %D
+% %D \starttyping
+% %D JS_N
+% %D \stoptyping
+
+%D We will also support direct function calls. In that case
+%D no intermediate variables are used.
+
+%D \macros
+%D {startJScode}
+%D
+%D A piece of \JAVASCRIPT\ code is defined by saying:
+%D
+%D \starttyping
+%D \startJScode{SomeScript}
+%D var Item=this.getField("item");
+%D N=Item.getArray();
+%D Total=this.getField("total");
+%D Total.value=0;
+%D for (j=0; j<N.length; j++)
+%D { if (N[j].value!="")
+%D { Total.value += N[j].value } } ;
+%D if ((JS_N>0) && (JS_R_1!=""))
+%D { gotoNamedDest(JS_R_1) };
+%D \stopJScode
+%D \stoptyping
+%D
+%D Such a piece of code is closely related to the interpreter
+%D used. Watch the last two lines, here the script adapts
+%D itself to the presence of a reference.
+%D
+%D While
+%D
+%D \starttyping
+%D \startJScode{name}
+%D name = 4 ;
+%D \stopJScode
+%D \stoptyping
+%D
+%D assumes uses no preamble or presumes that the preamble is
+%D always loaded, the next definition also tells \CONTEXT\ to
+%D actually include the preamble needed.
+%D
+%D \starttyping
+%D \startJScode{uses} uses {later}
+%D uses = 6 ;
+%D \stopJScode
+%D \stoptyping
+
+\long\def\startJScode#1 #2
+ {\doifelse{#2}{uses}
+ {\dostartJScodeA{#1}}
+ {\dostartJScodeB{#1} #2 }}
+
+\long\def\dostartJScodeA#1#2 #3\stopJScode
+ {\long\setgvalue{\r!java#1}{\do{#2}{#3}}}
+
+\long\def\dostartJScodeB#1#2\stopJScode
+ {\long\setgvalue{\r!java#1}{\do{}{#2}}}
+
+\let\stopJScode\relax
+
+%D \macros
+%D {presetJScode}
+%D
+%D The code can be retrieved by saying
+%D
+%D \starttyping
+%D \presetJScode{SomeScript}{template}
+%D \stoptyping
+%D
+%D Such a template is a comma separated list, where
+%D individual entries can optionally be transformed by
+%D \type{R{}} and \type{V{}}.
+%D
+%D After this call, the code is available in \type{\JScode}.
+
+\newif\ifdirectJScode
+
+\def\presetJScode#1#2% #1=operation #2=arguments
+ {\setverbosecscharacters
+ \def\par{\delcharacter}% was: { }
+ \scratchcounter\zerocount
+ \globallet\JScode\empty
+ \def\do##1##2%
+ {\doifelse{##2}{!}\directJScodetrue\directJScodefalse}%
+ \getvalue{\r!java#1}%
+ \edef\!!stringa{#2}%
+ \ifx\!!stringa\empty \else
+ \processcommacommand[\!!stringa]\dopresetJSvariables
+ \fi
+ \def\docommand##1%
+ {\doifundefinedelse{\r!java\r!java##1}
+ {\showmessage\m!javascript2{##1}}
+ {\useJSpreamblenow{##1}}}%
+% {\doglobal\increment\currentJSpreamble
+% \doglobal\addtocommalist{##1}\allJSpreambles}}%
+ \def\do##1##2%
+ {\xdef\JScode{\ifdirectJScode#1(\JScode)\else\JScode##2\fi}%
+ %\xdef\JScode{JS\string_N=\the\scratchcounter;\JScode}%
+ \processcommalist[##1]\docommand}%
+ \getvalue{\r!java#1}}
+
+\def\dopresetJSvariables#1%
+ {\advance\scratchcounter \plusone
+ \donefalse
+ \dodopresetJSvariables#1\end}%
+
+\def\dodopresetJSvariables
+ {\doifnextcharelse R\dodopresetJSrefvariables
+ {\doifnextcharelse V\dodopresetJSvervariables
+ {\doifnextcharelse S\dodopresetJSstrvariables
+ \dodopresetJSrawvariables}}}
+
+\def\dodopresetJSrefvariables R#1\end
+ {\doifreferencefoundelse{#1}
+ {\donetrue \dododopresetJSvariables R{\referenceprefix#1}%
+ \donefalse\dododopresetJSvariables P{\currentrealreference}}
+ {\unknownreference{#1}}%
+ \ifminimalizeJScode \else
+ \donetrue\dododopresetJSvariables S{#1}%
+ \fi}
+
+\def\dodopresetJSvervariables V#1\end
+ {\donefalse\dododopresetJSvariables V{#1}%
+ \ifminimalizeJScode \else
+ \donetrue\dododopresetJSvariables S{#1}%
+ \fi}
+
+\def\dodopresetJSstrvariables S#1\end
+ {\donetrue\dododopresetJSvariables S{#1}}
+
+\def\dodopresetJSrawvariables #1\end
+ {\donetrue\dododopresetJSvariables S{#1}}
+
+\def\JSprefix#1%
+ {JS\string_#1\string_\the\scratchcounter}
+
+\def\dododopresetJSvariables#1#2%
+ {\iftraceJScode
+ \writestatus{JavaScript}{\JSprefix#1=#2}
+ \xdef\JScode{\JScode console.println("\JSprefix#1=#2"); }%
+ \fi
+ \ifdirectJScode
+ \xdef\JScode{\ifx\JScode\empty\else\JScode,\fi\ifdone"#2"\else#2\fi}%
+ \else
+ \xdef\JScode{\JScode\JSprefix#1=\ifdone"#2"\else#2\fi; }%
+ \fi}
+
+%D \macros
+%D {startJSpreamble, flushJSpreamble}
+%D
+%D One can define insert \JAVASCRIPT\ code at the document level
+%D by using:
+%D
+%D \starttyping
+%D \startJSpreamble{oeps}
+%D oeps = 1 ;
+%D \stopJSpreamble
+%D \stoptyping
+%D
+%D which is the same as:
+%D
+%D \starttyping
+%D \startJSpreamble{now} used now
+%D now = 2 ;
+%D \stopJSpreamble
+%D \stoptyping
+%D
+%D while the next definition is only included when actually
+%D used.
+%D
+%D \starttyping
+%D \startJSpreamble{later} used later
+%D later = 3 ;
+%D \stopJSpreamble
+%D \stoptyping
+%D
+%D This command may be used more that once, but always before
+%D the first page is shipped out.
+
+\newif\ifoneJSpreamble \oneJSpreamblefalse
+
+\let\allJSpreambles\empty
+\newcounter\nofJSpreambles
+\newcounter\currentJSpreamble
+
+\long\def\startJSpreamble#1 #2 %
+ {\bgroup % we need to restore the catcodes
+ \restoreendofline % just in case it happens while reading lists
+ \doifelse{#2}{used}
+ {\dostartJSpreamble#1 }
+ {\dostartJSpreamble#1 now #2 }}
+
+\long\def\dostartJSpreamble#1 #2 %
+ {\processaction
+ [#2]
+ [ later=>\chardef\JSstatus\zerocount,%
+ now=>\chardef\JSstatus\plusone ,%
+ \s!default=>\chardef\JSstatus\plustwo ,%
+ \s!unknown=>\chardef\JSstatus\plustwo ]%
+ \ifaddJSlinebreaks
+ \obeylines \let\obeyedline \normalpar
+ \obeyspaces \let\obeyedspace\normalspace
+ \fi
+ \dodostartJSpreamble{#1}}
+
+\long\def\dodostartJSpreamble#1#2\stopJSpreamble
+ {\presetJSfunctions #2function ()\end
+ \long\setgvalue{\r!java\r!java#1}{#2}%
+ \ifcase\JSstatus \else
+ \useJSpreamblenow{#1}%
+ \fi
+ \egroup}
+
+%D \macros
+%D {setJSpreamble, addtoJSpreamble}
+%D
+%D In addition to the previous preamble definitions, we can
+%D set a preamble \quote {in||line} and add tokens to a
+%D preamble.
+
+\def\setJSpreamble#1#2%
+ {\doifundefined{\r!java\r!java#1}
+ {\setgvalue{\r!java\r!java#1}{#2;}%
+ \doglobal\increment\currentJSpreamble
+ \doglobal\addtocommalist{#1}\allJSpreambles}}
+
+\def\addtoJSpreamble#1#2%
+ {\doifdefinedelse{\r!java\r!java#1}
+ {\edef\!!stringa{\r!java\r!java#1}%
+ \edef\!!stringb{\csname\!!stringa\endcsname}%
+ \@EA\setgvalue\@EA\!!stringa\@EA{\!!stringb #2;}}
+ {\setJSpreamble{#1}{#2}}}
+
+%D \macros
+%D {useJSpreamblenow}
+%D
+%D The next macro can be used to force inclusion of postponed
+%D \JAVASCRIPT\ preambles.
+
+\def\useJSpreamblenow#1%
+ {\doglobal\increment\currentJSpreamble
+ \doglobal\addtocommalist{#1}\allJSpreambles}
+
+%D Because we want to check for valid calls, we preload the
+%D functions. This means that we can call them directly as
+%D well as indirectly when defined by \type {\startJScode} etc.
+
+% \long\def\presetJSfunctions#1function #2(#3)%
+% {\doifelsenothing{#2}
+% {\long\def\presetJSfunctions##1\end{}}
+% {\stripspaces\from#2\to\ascii
+% \doifundefined{\r!java\ascii}{\setgvalue{\r!java\ascii}{\do{}{!}}}}%
+% \presetJSfunctions}
+
+\long\def\presetJSfunctions#1function#2(#3)%
+ {\doifelse{#2}\space
+ {\long\def\presetJSfunctions##1\end{}}
+ {\stripspaces\from#2\to\ascii
+ \doifundefined{\r!java\ascii}{\setgvalue{\r!java\ascii}{\do{}{!}}}}%
+ \presetJSfunctions}
+
+\def\getJSpreamble#1%
+ {\getvalue{\r!java\r!java#1}}
+
+\def\presetJSpreamble
+ {\ifx\allJSpreambles\empty\else
+ \bgroup
+ \setverbosecscharacters
+ \obeyspaces \let\obeyedspace\normalspace
+ \def\par{\delcharacter}% was: { }
+ \globallet\JSpreamble\empty
+ \def\@@collectedJSpreamble{\r!java\r!java collected}%
+ \letvalue{\@@collectedJSpreamble}=\empty
+ \def\docommand##1%
+ {\xdef\JScode{\getvalue{\r!java\r!java##1}}%
+ \ifoneJSpreamble % \global\letcdcsname
+ \@EA\setxvalue\@EA\@@collectedJSpreamble\@EA
+ {\csname\@@collectedJSpreamble\endcsname\JScode}%
+ \else
+ \setxvalue{\r!java\r!java##1}{\JScode}%
+ \fi}%
+ \processcommacommand[\allJSpreambles]\docommand
+ \ifoneJSpreamble
+ \gdef\allJSpreambles{collected}%
+ \fi
+ \globallet\presetJSpreamble\relax
+ \egroup
+ \fi}
+
+\def\flushJSpreamble
+ {\iflocation\ifx\allJSpreambles\empty\else
+ \ifcase\nofJSpreambles\else\ifnum\nofJSpreambles=\currentJSpreamble
+ \bgroup
+ \presetJSpreamble
+ \expanded{\doflushJSpreamble{\allJSpreambles}}%
+ \globallet\flushJSpreamble\relax
+ \globallet\allJSpreambles\empty
+ \egroup
+ \fi\fi
+ \fi\fi}
+
+\def\finalflushJSpreamble
+ {\iflocation
+ \flushJSpreamble
+ \ifcase\currentJSpreamble\relax\else
+ \savecurrentvalue\nofJSpreambles\currentJSpreamble
+ \globallet\currentJSpreamble\nofJSpreambles
+ \fi
+ \fi}
+
+%D \macros
+%D {doPSsanitizeJScode}
+%D
+%D Before the code can be passed to the (\POSTSCRIPT\ or \PDF)
+%D output file, some precautions must be made concerning the
+%D use of \type{(} and~\type{)}. Here we use a beautiful
+%D \type{\aftergroup} trick I discovered in the \TABLE\ format.
+
+\def\doPSsanitizeJScode#1\to#2%
+ {\begingroup
+ \scratchcounter\zerocount % \aftergroup counter
+ \aftergroup\xdef
+ \aftergroup#2%
+ \aftergroup{%
+ \expanded{\defconvertedargument\noexpand\JScode{#1}}%
+ \expandafter\handletokens\JScode\with\dodoPSsanitizeJScode
+ \aftergroup}%
+ \endgroup
+ \iftraceJScode
+ \writestatus{JS trace}{#2}%
+ \fi}
+
+%D I started with:
+%D
+%D \starttyping
+%D \def\dodoPSsanitizeJScode#1%
+%D {\aftergroup\string
+%D \if#1(%
+%D \expandafter\aftergroup\csname#1\endcsname
+%D \else\if#1)%
+%D \expandafter\aftergroup\csname#1\endcsname
+%D \else\if#1;%
+%D \aftergroup;\aftergroup\string\expandafter\aftergroup\
+%D \else
+%D \expandafter\aftergroup#1%
+%D \fi\fi\fi
+%D \advance\scratchcounter by 1
+%D \ifnum\scratchcounter=500
+%D \expandafter\dododoPSsanitizeJScode
+%D \fi}
+%D \stoptyping
+%D
+%D For pretty printing purposes, we need some way to signal
+%D \TEX\ macros. Therefore we introduce a special keyword
+%D \type{TEX}. When followed by a space, this keyword is
+%D ignored, that is, filtered from the stream. Now we have:
+
+\chardef\JSisTEX \zerocount
+\chardef\JScomment\zerocount
+
+\newif\ifaddJSlinebreaks \addJSlinebreakstrue
+
+\def\flushJSisTEX
+ {\ifcase\JSisTEX
+ \or \aftergroup T%
+ \or \aftergroup T\aftergroup E%
+ \or \aftergroup T\aftergroup E\aftergroup X%
+ \fi
+ \chardef\JSisTEX\zerocount}
+
+% \def\doJSlinebreak
+% {\ifaddJSlinebreaks
+% \aftergroup\string\aftergroup\n%
+% \fi}
+%
+% \def\dodoPSsanitizeJScode#1% % input stack>500 & TEX check
+% {\if#1/%
+% \ifnum\JScomment=0
+% \chardef\JScomment\plusone
+% \else\ifnum\JScomment=1
+% \chardef\JScomment\plustwo
+% \fi\fi
+% \else
+% \ifnum\JScomment=1
+% \aftergroup/%
+% \chardef\JScomment\zerocount
+% \fi
+% \ifnum\JScomment=2
+% \if#1\delcharacter
+% \chardef\JScomment\zerocount
+% \fi
+% \else
+% \if#1\delcharacter
+% \flushJSisTEX\doJSlinebreak
+% \else\if#1(%
+% \flushJSisTEX\aftergroup\string\expandafter\aftergroup\csname#1\endcsname
+% \else\if#1)%
+% \flushJSisTEX\aftergroup\string\expandafter\aftergroup\csname#1\endcsname
+% \else\if#1;%
+% \flushJSisTEX\aftergroup;\doJSlinebreak
+% \else\if#1T%
+% \ifnum\JSisTEX=0 \chardef\JSisTEX\plusone \else\flushJSisTEX\aftergroup T\fi
+% \else\if#1E%
+% \ifnum\JSisTEX=1 \chardef\JSisTEX\plustwo \else\flushJSisTEX\aftergroup E\fi
+% \else\if#1X%
+% \ifnum\JSisTEX=2 \chardef\JSisTEX\plusthree \else\flushJSisTEX\aftergroup X\fi
+% \else\if#1\normalspace
+% \ifnum\JSisTEX=3 \chardef\JSisTEX\zerocount \else\flushJSisTEX\aftergroup#1\fi
+% \else
+% \flushJSisTEX\aftergroup\string\expandafter\aftergroup#1%
+% \fi\fi\fi\fi\fi\fi\fi\fi
+% \fi
+% \fi
+% \dododoPSsanitizeJScode}
+
+% todo: "http:\\" -> simple. maar wel \" afvangen
+%
+% use new pdftex escape mechanism or make fully expandable version, not used that often btw
+
+\chardef\JSstring\zerocount
+
+\def\doJSlinebreak
+ {\chardef\JScomment\zerocount
+ \chardef\JSstring\zerocount
+ \ifaddJSlinebreaks
+ \aftergroup\string\aftergroup\n%
+ \fi}
+
+\def\dodoPSsanitizeJScode#1% % input stack>500 & TEX check
+ {\if#1/%
+ \ifnum\JSstring=0
+ \ifnum\JScomment=0
+ \chardef\JScomment\plusone
+ \else\ifnum\JScomment=1
+ \chardef\JScomment\plustwo
+ \fi\fi
+ \else
+ \aftergroup/%
+ \fi
+ \else
+ \ifnum\JScomment=1
+ \aftergroup/%
+ \chardef\JScomment\zerocount
+ \fi
+ % is the delchar trick still needed?
+ \ifnum\JScomment=2
+ \ifnum`#1=13 % brrr
+ \doJSlinebreak
+ \else\if#1\par
+ \doJSlinebreak
+ \else\if#1\delcharacter
+ \doJSlinebreak
+ \fi\fi\fi
+ \else
+ \ifnum`#1=13 % brrr
+ \flushJSisTEX\doJSlinebreak
+ \else\if#1\par
+ \flushJSisTEX\doJSlinebreak
+ \else\if#1\delcharacter
+ \flushJSisTEX\doJSlinebreak
+ \else\if#1(%
+ \flushJSisTEX\aftergroup\string\expandafter\aftergroup\csname#1\endcsname
+ \else\if#1)%
+ \flushJSisTEX\aftergroup\string\expandafter\aftergroup\csname#1\endcsname
+ %\else\if#1;%
+ % \flushJSisTEX\aftergroup;\doJSlinebreak
+ \else\if#1T%
+ \ifnum\JSisTEX=0 \chardef\JSisTEX\plusone \else\flushJSisTEX\aftergroup T\fi
+ \else\if#1E%
+ \ifnum\JSisTEX=1 \chardef\JSisTEX\plustwo \else\flushJSisTEX\aftergroup E\fi
+ \else\if#1X%
+ \ifnum\JSisTEX=2 \chardef\JSisTEX\plusthree \else\flushJSisTEX\aftergroup X\fi
+ \else\if#1\normalspace
+ \ifnum\JSisTEX=3 \chardef\JSisTEX\zerocount \else\flushJSisTEX\aftergroup#1\fi
+ \else
+ % todo: "test\"test"
+ \if#1"%
+ \ifcase\JSstring
+ \chardef\JSstring\plusone
+ \else
+ \chardef\JSstring\zerocount
+ \fi
+ \fi
+ \flushJSisTEX\aftergroup\string\expandafter\aftergroup#1%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi % \fi
+ \fi
+ \fi
+ \dododoPSsanitizeJScode}
+
+%D Close reading learns that one line comments (\type{// ...})
+%D are removed from the stream. This permits switching in
+%D pretty printing \JAVASCRIPT\ sources as well as saves
+%D some bytes.
+
+%D The magic 500 in the next hack prevents the input stack from
+%D overflowing when large scripts are sanitized.
+
+\def\dododoPSsanitizeJScode
+ {\ifcase\JSisTEX\ifcase\JScomment
+ \advance\scratchcounter \plusone
+ \fi\fi
+ \ifnum\scratchcounter=500
+ \expandafter\dodododoPSsanitizeJScode
+ \fi}
+
+\def\dodododoPSsanitizeJScode
+ {\let\next={%
+ \aftergroup}%
+ \endgroup
+ \begingroup
+ \aftergroup\xdef
+ \aftergroup\sanitizedJScode
+ \aftergroup{%
+ \aftergroup\sanitizedJScode
+ \let\next=}}
+
+%D The macro \type{\doPSsanitizeJScode} converts its argument
+%D into the macro \type{\sanitizedJScode}, thereby prefixing
+%D each \type{(} and \type{)} by a slash.
+
+%D Hooking this mechanism into the general \CONTEXT\ reference
+%D mechanism does not take much effort:
+
+\definespecialtest{JS}%
+ {\doifdefinedelse{\r!java\currentreferenceoperation}}
+
+\def\gotojavascriptspecial#1#2#3#4% special operation arguments data
+ {\begingroup
+ \iflocation
+ \bgroup
+ \presetJScode{#2}{#3}%
+ \egroup
+ \dohandlegoto{#4}{\dostartgotoJS\buttonwidth\buttonheight\JScode}{\dostopgotoJS}%
+ \else
+ #4%
+ \fi
+ \endgroup}
+
+%D \macros
+%D {useJSscripts}
+%D
+%D In due time, users will build their collections of scripts,
+%D which can be used (loaded) when applicable. Although not all
+%D public, we will provide some general purpose scripts,
+%D collected in files with names like \type{java-...}. One can
+%D load these scripts with \type{\useJSscripts}, like:
+%D
+%D \starttyping
+%D \useJSscripts[fld]
+%D \stoptyping
+%D
+%D The not so complicated implementation of this macro is:
+
+\def\dodouseJSscripts#1%
+ {\doifelse{#1}\v!reset
+ {\let\allJSpreambles\empty}
+ {\doifundefined{\c!file\f!javascriptprefix#1}
+ {\startnointerference
+ \letgvalueempty{\c!file\f!javascriptprefix#1}%
+ \makeshortfilename[\f!javascriptprefix#1]%
+ \startreadingfile
+ \readsysfile\shortfilename{\showmessage\m!javascript1{#1}}\donothing
+ \stopreadingfile
+ \stopnointerference}}}
+
+\def\douseJSscripts[#1][#2]%
+ {\processcommalist[#1]\dodouseJSscripts
+ \processcommalist[#2]\useJSpreamblenow}
+
+\def\useJSscripts
+ {\dodoubleempty\douseJSscripts}
+
+\protect \endinput
diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua
index 9705fb711..6b1fd67ff 100644
--- a/tex/context/base/l-aux.lua
+++ b/tex/context/base/l-aux.lua
@@ -1,68 +1,94 @@
--- filename : l-aux.lua
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-aux'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-aux'] = 1.001
-if not aux then aux = { } end
+aux = aux or { }
-local concat, format = table.concat, string.format
+local concat, format, gmatch = table.concat, string.format, string.gmatch
local tostring, type = tostring, type
-do
+local space = lpeg.P(' ')
+local equal = lpeg.P("=")
+local comma = lpeg.P(",")
+local lbrace = lpeg.P("{")
+local rbrace = lpeg.P("}")
+local nobrace = 1 - (lbrace+rbrace)
+local nested = lpeg.P{ lbrace * (nobrace + lpeg.V(1))^0 * rbrace }
+local spaces = space^0
- local hash = { }
+local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0)
- local function set(key,value) -- using Carg is slower here
- hash[key] = value
+local key = lpeg.C((1-equal-comma)^1)
+local pattern_a = (space+comma)^0 * (key * equal * value + key * lpeg.C(""))
+
+local key = lpeg.C((1-space-equal-comma)^1)
+local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + lpeg.C("")))
+
+-- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored
+
+local hash = { }
+
+local function set(key,value) -- using Carg is slower here
+ hash[key] = value
+end
+
+local pattern_a_s = (pattern_a/set)^1
+local pattern_b_s = (pattern_b/set)^1
+
+aux.settings_to_hash_pattern_a = pattern_a_s
+aux.settings_to_hash_pattern_b = pattern_b_s
+
+function aux.make_settings_to_hash_pattern(set,moretolerant)
+ if moretolerant then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
end
+end
- local space = lpeg.P(' ')
- local equal = lpeg.P("=")
- local comma = lpeg.P(",")
- local lbrace = lpeg.P("{")
- local rbrace = lpeg.P("}")
- local nobrace = 1 - (lbrace+rbrace)
- local nested = lpeg.P{ lbrace * (nobrace + lpeg.V(1))^0 * rbrace }
-
- local key = lpeg.C((1-equal-comma)^1)
- local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0)
--- local pattern = (((space+comma)^0 * (key * equal * value + key) * comma^0) / set)^1
- local pattern = (((space+comma)^0 * (key * equal * value + key * lpeg.C(""))) / set)^1
-
- -- "a=1, b=2, c=3, d={a{b,c}d}, e=12345, f=xx{a{b,c}d}xx, g={}" : outer {} removes, leading spaces ignored
-
- function aux.settings_to_hash(str)
- if str and str ~= "" then
- hash = { }
- pattern:match(str)
- return hash
+function aux.settings_to_hash(str,moretolerant)
+ if str and str ~= "" then
+ hash = { }
+ if moretolerant then
+ pattern_b_s:match(str)
else
- return { }
+ pattern_a_s:match(str)
end
+ return hash
+ else
+ return { }
end
+end
- local seperator = comma * space^0
- local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0)
- local pattern = lpeg.Ct(value*(seperator*value)^0)
+local seperator = comma * space^0
+local value = lpeg.P(lbrace * lpeg.C((nobrace + nested)^0) * rbrace) + lpeg.C((nested + (1-comma))^0)
+local pattern = lpeg.Ct(value*(seperator*value)^0)
- -- "aap, {noot}, mies" : outer {} removes, leading spaces ignored
+-- "aap, {noot}, mies" : outer {} removes, leading spaces ignored
- function aux.settings_to_array(str)
- return pattern:match(str)
- end
+aux.settings_to_array_pattern = pattern
- local function set(t,v)
- t[#t+1] = v
+function aux.settings_to_array(str)
+ if not str or str == "" then
+ return { }
+ else
+ return pattern:match(str)
end
+end
- local value = lpeg.P(lpeg.Carg(1)*value) / set
- local pattern = value*(seperator*value)^0 * lpeg.Carg(1)
+local function set(t,v)
+ t[#t+1] = v
+end
- function aux.add_settings_to_array(t,str)
- return pattern:match(str, nil, t)
- end
+local value = lpeg.P(lpeg.Carg(1)*value) / set
+local pattern = value*(seperator*value)^0 * lpeg.Carg(1)
+function aux.add_settings_to_array(t,str)
+ return pattern:match(str, nil, t)
end
function aux.hash_to_string(h,separator,yes,no,strict,omit)
@@ -102,9 +128,9 @@ function aux.array_to_string(a,separator)
end
end
-function aux.settings_to_set(str)
- local t = { }
- for s in str:gmatch("%s*([^,]+)") do
+function aux.settings_to_set(str,t)
+ t = t or { }
+ for s in gmatch(str,"%s*([^,]+)") do
t[s] = true
end
return t
@@ -152,7 +178,7 @@ end
function aux.definetable(target) -- defines undefined tables
local composed, t = nil, { }
- for name in target:gmatch("([^%.]+)") do
+ for name in gmatch(target,"([^%.]+)") do
if composed then
composed = composed .. "." .. name
else
@@ -165,7 +191,7 @@ end
function aux.accesstable(target)
local t = _G
- for name in target:gmatch("([^%.]+)") do
+ for name in gmatch(target,"([^%.]+)") do
t = t[name]
end
return t
diff --git a/tex/context/base/l-boolean.lua b/tex/context/base/l-boolean.lua
index 1542238c4..c8c919eda 100644
--- a/tex/context/base/l-boolean.lua
+++ b/tex/context/base/l-boolean.lua
@@ -1,11 +1,14 @@
--- filename : l-boolean.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-boolean'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-boolean'] = 1.001
-if not boolean then boolean = { } end
+boolean = boolean or { }
+
+local type, tonumber = type, tonumber
function boolean.tonumber(b)
if b then return 1 else return 0 end
diff --git a/tex/context/base/l-dimen.lua b/tex/context/base/l-dimen.lua
index 103cb2d88..32becb276 100644
--- a/tex/context/base/l-dimen.lua
+++ b/tex/context/base/l-dimen.lua
@@ -15,6 +15,8 @@ done by using the conversion factors collected in the following
table.</p>
--ldx]]--
+local format, type = string.format, type
+
local dimenfactors = {
["pt"] = 1/65536,
["in"] = ( 100/ 7227)/65536,
@@ -39,7 +41,7 @@ local function todimen(n,unit,fmt)
return n
else
unit = unit or 'pt'
- return (fmt or "%.5f%s"):format(n*dimenfactors[unit],unit)
+ return format(fmt or "%.5f%s",n*dimenfactors[unit],unit)
end
end
@@ -73,10 +75,10 @@ a number and optionally a unit. When no unit is given a constant
capture takes place.</p>
--ldx]]--
-local amount = lpeg.S("+-")^0 * lpeg.R("09")^0 * (lpeg.P(".") * lpeg.R("09")^1)^0
-local unit = lpeg.R("az")^1 / dimenfactors -- produces a capture
+local amount = (lpeg.S("+-")^0 * lpeg.R("09")^0 * lpeg.P(".")^0 * lpeg.R("09")^0) + lpeg.Cc("0")
+local unit = lpeg.R("az")^1
-local pattern = lpeg.C(amount) * (unit^1 + lpeg.Cc(1))
+local pattern = amount/tonumber * (unit^1/dimenfactors + lpeg.Cc(1)) -- tonumber is new
--[[ldx--
<p>We use a metatable to intercept errors. When no key is found in
@@ -96,6 +98,7 @@ function string:todimen()
return self
else
local value, unit = pattern:match(self)
+ print(value,unit)
return value/unit
end
end
@@ -260,7 +263,7 @@ yet be available.</p>
--ldx]]--
function dimensions.texify()
- local fti, fc = fonts and fonts.tfm and fonts.tfm.id, font and font.current
+ local fti, fc = fonts and fonts.ids and fonts.ids, font and font.current
if fti and fc then
dimenfactors["ex"] = function() return fti[fc()].ex_height end
dimenfactors["em"] = function() return fti[fc()].quad end
diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua
index 0a174e18a..5a726303f 100644
--- a/tex/context/base/l-dir.lua
+++ b/tex/context/base/l-dir.lua
@@ -1,202 +1,203 @@
--- filename : l-dir.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-dir'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-dir'] = 1.001
+local type = type
+local find, gmatch = string.find, string.gmatch
-dir = { }
+dir = dir or { }
-- optimizing for no string.find (*) does not save time
-if lfs then do
+local attributes = lfs.attributes
+local walkdir = lfs.dir
- local attributes = lfs.attributes
- local walkdir = lfs.dir
-
- local function glob_pattern(path,patt,recurse,action)
- local ok, scanner
- if path == "/" then
- ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe
- else
- ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
- end
- if ok and type(scanner) == "function" then
- if not path:find("/$") then path = path .. '/' end
- for name in scanner do
- local full = path .. name
- local mode = attributes(full,'mode')
- if mode == 'file' then
- if full:find(patt) then
- action(full)
- end
- elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then
- glob_pattern(full,patt,recurse,action)
+local function glob_pattern(path,patt,recurse,action)
+ local ok, scanner
+ if path == "/" then
+ ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe
+ else
+ ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe
+ end
+ if ok and type(scanner) == "function" then
+ if not find(path,"/$") then path = path .. '/' end
+ for name in scanner do
+ local full = path .. name
+ local mode = attributes(full,'mode')
+ if mode == 'file' then
+ if find(full,patt) then
+ action(full)
end
+ elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then
+ glob_pattern(full,patt,recurse,action)
end
end
end
+end
- dir.glob_pattern = glob_pattern
+dir.glob_pattern = glob_pattern
- local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
+local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V
- local pattern = Ct {
- [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3),
- [2] = C(((1-S("*?/"))^0 * P("/"))^0),
- [3] = C(P(1)^0)
- }
+local pattern = Ct {
+ [1] = (C(P(".") + P("/")^1) + C(R("az","AZ") * P(":") * P("/")^0) + Cc("./")) * V(2) * V(3),
+ [2] = C(((1-S("*?/"))^0 * P("/"))^0),
+ [3] = C(P(1)^0)
+}
- local filter = Cs ( (
- P("**") / ".*" +
- P("*") / "[^/]*" +
- P("?") / "[^/]" +
- P(".") / "%%." +
- P("+") / "%%+" +
- P("-") / "%%-" +
- P(1)
- )^0 )
+local filter = Cs ( (
+ P("**") / ".*" +
+ P("*") / "[^/]*" +
+ P("?") / "[^/]" +
+ P(".") / "%%." +
+ P("+") / "%%+" +
+ P("-") / "%%-" +
+ P(1)
+)^0 )
- local function glob(str,t)
- if type(str) == "table" then
- local t = t or { }
- for _, s in ipairs(str) do
- glob(s,t)
- end
- return t
- elseif lfs.isfile(str) then
+local function glob(str,t)
+ if type(str) == "table" then
+ local t = t or { }
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif lfs.isfile(str) then
+ local t = t or { }
+ t[#t+1] = str
+ return t
+ else
+ local split = pattern:match(str)
+ if split then
local t = t or { }
- t[#t+1] = str
+ local action = action or function(name) t[#t+1] = name end
+ local root, path, base = split[1], split[2], split[3]
+ local recurse = find(base,"%*%*")
+ local start = root .. path
+ local result = filter:match(start .. base)
+ glob_pattern(start,result,recurse,action)
return t
else
- local split = pattern:match(str)
- if split then
- local t = t or { }
- local action = action or function(name) t[#t+1] = name end
- local root, path, base = split[1], split[2], split[3]
- local recurse = base:find("%*%*")
- local start = root .. path
- local result = filter:match(start .. base)
- glob_pattern(start,result,recurse,action)
- return t
- else
- return { }
- end
+ return { }
end
end
+end
- dir.glob = glob
+dir.glob = glob
- --~ list = dir.glob("**/*.tif")
- --~ list = dir.glob("/**/*.tif")
- --~ list = dir.glob("./**/*.tif")
- --~ list = dir.glob("oeps/**/*.tif")
- --~ list = dir.glob("/oeps/**/*.tif")
+--~ list = dir.glob("**/*.tif")
+--~ list = dir.glob("/**/*.tif")
+--~ list = dir.glob("./**/*.tif")
+--~ list = dir.glob("oeps/**/*.tif")
+--~ list = dir.glob("/oeps/**/*.tif")
- local function globfiles(path,recurse,func,files) -- func == pattern or function
- if type(func) == "string" then
- local s = func -- alas, we need this indirect way
- func = function(name) return name:find(s) end
- end
- files = files or { }
- for name in walkdir(path) do
- if name:find("^%.") then
- --- skip
- else
- local mode = attributes(name,'mode')
- if mode == "directory" then
- if recurse then
- globfiles(path .. "/" .. name,recurse,func,files)
- end
- elseif mode == "file" then
- if func then
- if func(name) then
- files[#files+1] = path .. "/" .. name
- end
- else
+local function globfiles(path,recurse,func,files) -- func == pattern or function
+ if type(func) == "string" then
+ local s = func -- alas, we need this indirect way
+ func = function(name) return find(name,s) end
+ end
+ files = files or { }
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ --- skip
+ else
+ local mode = attributes(name,'mode')
+ if mode == "directory" then
+ if recurse then
+ globfiles(path .. "/" .. name,recurse,func,files)
+ end
+ elseif mode == "file" then
+ if func then
+ if func(name) then
files[#files+1] = path .. "/" .. name
end
+ else
+ files[#files+1] = path .. "/" .. name
end
end
end
- return files
end
+ return files
+end
- dir.globfiles = globfiles
+dir.globfiles = globfiles
- -- t = dir.glob("c:/data/develop/context/sources/**/????-*.tex")
- -- t = dir.glob("c:/data/develop/tex/texmf/**/*.tex")
- -- t = dir.glob("c:/data/develop/context/texmf/**/*.tex")
- -- t = dir.glob("f:/minimal/tex/**/*")
- -- print(dir.ls("f:/minimal/tex/**/*"))
- -- print(dir.ls("*.tex"))
+-- t = dir.glob("c:/data/develop/context/sources/**/????-*.tex")
+-- t = dir.glob("c:/data/develop/tex/texmf/**/*.tex")
+-- t = dir.glob("c:/data/develop/context/texmf/**/*.tex")
+-- t = dir.glob("f:/minimal/tex/**/*")
+-- print(dir.ls("f:/minimal/tex/**/*"))
+-- print(dir.ls("*.tex"))
- function dir.ls(pattern)
- return table.concat(glob(pattern),"\n")
- end
+function dir.ls(pattern)
+ return table.concat(glob(pattern),"\n")
+end
- --~ mkdirs("temp")
- --~ mkdirs("a/b/c")
- --~ mkdirs(".","/a/b/c")
- --~ mkdirs("a","b","c")
+--~ mkdirs("temp")
+--~ mkdirs("a/b/c")
+--~ mkdirs(".","/a/b/c")
+--~ mkdirs("a","b","c")
- local make_indeed = true -- false
+local make_indeed = true -- false
- if string.find(os.getenv("PATH"),";") then
+if string.find(os.getenv("PATH"),";") then
- function dir.mkdirs(...)
- local str, pth = "", ""
- for _, s in ipairs({...}) do
- if s ~= "" then
- if str ~= "" then
- str = str .. "/" .. s
- else
- str = s
- end
+ function dir.mkdirs(...)
+ local str, pth = "", ""
+ for _, s in ipairs({...}) do
+ if s ~= "" then
+ if str ~= "" then
+ str = str .. "/" .. s
+ else
+ str = s
end
end
- local first, middle, last
- local drive = false
- first, middle, last = str:match("^(//)(//*)(.*)$")
+ end
+ local first, middle, last
+ local drive = false
+ first, middle, last = str:match("^(//)(//*)(.*)$")
+ if first then
+ -- empty network path == local path
+ else
+ first, last = str:match("^(//)/*(.-)$")
if first then
- -- empty network path == local path
+ middle, last = str:match("([^/]+)/+(.-)$")
+ if middle then
+ pth = "//" .. middle
+ else
+ pth = "//" .. last
+ last = ""
+ end
else
- first, last = str:match("^(//)/*(.-)$")
+ first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$")
if first then
- middle, last = str:match("([^/]+)/+(.-)$")
- if middle then
- pth = "//" .. middle
- else
- pth = "//" .. last
- last = ""
- end
+ pth, drive = first .. middle, true
else
- first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth, drive = first .. middle, true
- else
- middle, last = str:match("^(/*)(.-)$")
- if not middle then
- last = str
- end
+ middle, last = str:match("^(/*)(.-)$")
+ if not middle then
+ last = str
end
end
end
- for s in last:gmatch("[^/]+") do
- if pth == "" then
- pth = s
- elseif drive then
- pth, drive = pth .. s, false
- else
- pth = pth .. "/" .. s
- end
- if make_indeed and not lfs.isdir(pth) then
- lfs.mkdir(pth)
- end
+ end
+ for s in gmatch(last,"[^/]+") do
+ if pth == "" then
+ pth = s
+ elseif drive then
+ pth, drive = pth .. s, false
+ else
+ pth = pth .. "/" .. s
+ end
+ if make_indeed and not lfs.isdir(pth) then
+ lfs.mkdir(pth)
end
- return pth, (lfs.isdir(pth) == true)
end
+ return pth, (lfs.isdir(pth) == true)
+ end
--~ print(dir.mkdirs("","","a","c"))
--~ print(dir.mkdirs("a"))
@@ -210,79 +211,79 @@ if lfs then do
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
- local first, nothing, last = str:match("^(//)(//*)(.*)$")
- if first then
- first = lfs.currentdir() .. "/"
- first = first:gsub("\\","/")
- end
- if not first then
- first, last = str:match("^(//)/*(.*)$")
- end
- if not first then
- first, last = str:match("^([a-zA-Z]:)(.*)$")
- if first and not last:find("^/") then
- local d = lfs.currentdir()
- if lfs.chdir(first) then
- first = lfs.currentdir()
- first = first:gsub("\\","/")
- end
- lfs.chdir(d)
+ function dir.expand_name(str)
+ local first, nothing, last = str:match("^(//)(//*)(.*)$")
+ if first then
+ first = lfs.currentdir() .. "/"
+ first = first:gsub("\\","/")
+ end
+ if not first then
+ first, last = str:match("^(//)/*(.*)$")
+ end
+ if not first then
+ first, last = str:match("^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d = lfs.currentdir()
+ if lfs.chdir(first) then
+ first = lfs.currentdir()
+ first = first:gsub("\\","/")
end
+ lfs.chdir(d)
end
- if not first then
- first, last = lfs.currentdir(), str
- first = first:gsub("\\","/")
- end
- last = last:gsub("//","/")
- last = last:gsub("/%./","/")
- last = last:gsub("^/*","")
- first = first:gsub("/*$","")
- if last == "" then
- return first
- else
- return first .. "/" .. last
- end
end
+ if not first then
+ first, last = lfs.currentdir(), str
+ first = first:gsub("\\","/")
+ end
+ last = last:gsub("//","/")
+ last = last:gsub("/%./","/")
+ last = last:gsub("^/*","")
+ first = first:gsub("/*$","")
+ if last == "" then
+ return first
+ else
+ return first .. "/" .. last
+ end
+ end
- else
+else
- function dir.mkdirs(...)
- local str, pth = "", ""
- for _, s in ipairs({...}) do
- if s ~= "" then
- if str ~= "" then
- str = str .. "/" .. s
- else
- str = s
- end
+ function dir.mkdirs(...)
+ local str, pth = "", ""
+ for _, s in ipairs({...}) do
+ if s ~= "" then
+ if str ~= "" then
+ str = str .. "/" .. s
+ else
+ str = s
end
end
- str = str:gsub("/+","/")
- if str:find("^/") then
- pth = "/"
- for s in str:gmatch("[^/]+") do
- local first = (pth == "/")
- if first then
- pth = pth .. s
- else
- pth = pth .. "/" .. s
- end
- if make_indeed and not first and not lfs.isdir(pth) then
- lfs.mkdir(pth)
- end
- end
- else
- pth = "."
- for s in str:gmatch("[^/]+") do
+ end
+ str = str:gsub("/+","/")
+ if find(str,"^/") then
+ pth = "/"
+ for s in gmatch(str,"[^/]+") do
+ local first = (pth == "/")
+ if first then
+ pth = pth .. s
+ else
pth = pth .. "/" .. s
- if make_indeed and not lfs.isdir(pth) then
- lfs.mkdir(pth)
- end
+ end
+ if make_indeed and not first and not lfs.isdir(pth) then
+ lfs.mkdir(pth)
+ end
+ end
+ else
+ pth = "."
+ for s in gmatch(str,"[^/]+") do
+ pth = pth .. "/" .. s
+ if make_indeed and not lfs.isdir(pth) then
+ lfs.mkdir(pth)
end
end
- return pth, (lfs.isdir(pth) == true)
end
+ return pth, (lfs.isdir(pth) == true)
+ end
--~ print(dir.mkdirs("","","a","c"))
--~ print(dir.mkdirs("a"))
@@ -292,17 +293,15 @@ if lfs then do
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
- if not str:find("^/") then
- str = lfs.currentdir() .. "/" .. str
- end
- str = str:gsub("//","/")
- str = str:gsub("/%./","/")
- return str
+ function dir.expand_name(str)
+ if not find(str,"^/") then
+ str = lfs.currentdir() .. "/" .. str
end
-
+ str = str:gsub("//","/")
+ str = str:gsub("/%./","/")
+ return str
end
- dir.makedirs = dir.mkdirs
+end
-end end
+dir.makedirs = dir.mkdirs
diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua
index ae4cd426a..0782ac676 100644
--- a/tex/context/base/l-file.lua
+++ b/tex/context/base/l-file.lua
@@ -1,23 +1,24 @@
--- filename : l-file.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-file'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-file'] = 1.001
+-- needs a cleanup
-if not file then file = { } end
+file = file or { }
local concat = table.concat
+local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub
function file.removesuffix(filename)
- return (filename:gsub("%.[%a%d]+$",""))
+ return (gsub(filename,"%.[%a%d]+$",""))
end
-file.stripsuffix = file.removesuffix
-
function file.addsuffix(filename, suffix)
- if not filename:find("%.[%a%d]+$") then
+ if not find(filename,"%.[%a%d]+$") then
return filename .. "." .. suffix
else
return filename
@@ -25,23 +26,23 @@ function file.addsuffix(filename, suffix)
end
function file.replacesuffix(filename, suffix)
- return (filename:gsub("%.[%a%d]+$","")) .. "." .. suffix
+ return (gsub(filename,"%.[%a%d]+$","")) .. "." .. suffix
end
-function file.dirname(name)
- return name:match("^(.+)[/\\].-$") or ""
+function file.dirname(name,default)
+ return match(name,"^(.+)[/\\].-$") or (default or "")
end
function file.basename(name)
- return name:match("^.+[/\\](.-)$") or name
+ return match(name,"^.+[/\\](.-)$") or name
end
function file.nameonly(name)
- return ((name:match("^.+[/\\](.-)$") or name):gsub("%..*$",""))
+ return (gsub(match(name,"^.+[/\\](.-)$") or name,"%..*$",""))
end
function file.extname(name)
- return name:match("^.+%.([^/\\]-)$") or ""
+ return match(name,"^.+%.([^/\\]-)$") or ""
end
file.suffix = file.extname
@@ -54,40 +55,20 @@ file.suffix = file.extname
function file.join(...)
local pth = concat({...},"/")
- pth = pth:gsub("\\","/")
- local a, b = pth:match("^(.*://)(.*)$")
+ pth = gsub(pth,"\\","/")
+ local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
- return a .. b:gsub("//+","/")
+ return a .. gsub(b,"//+","/")
end
- a, b = pth:match("^(//)(.*)$")
+ a, b = match(pth,"^(//)(.*)$")
if a and b then
- return a .. b:gsub("//+","/")
- end
- return (pth:gsub("//+","/"))
-end
-
-function file.is_writable(name)
- local f = io.open(name, 'w')
- if f then
- f:close()
- return true
- else
- return false
- end
-end
-
-function file.is_readable(name)
- local f = io.open(name,'r')
- if f then
- f:close()
- return true
- else
- return false
+ return a .. gsub(b,"//+","/")
end
+ return (gsub(pth,"//+","/"))
end
function file.iswritable(name)
- local a = lfs.attributes(name)
+ local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and a.permissions:sub(2,2) == "w"
end
@@ -96,24 +77,18 @@ function file.isreadable(name)
return a and a.permissions:sub(1,1) == "r"
end
---~ function file.split_path(str)
---~ if str:find(';') then
---~ return str:splitchr(";")
---~ else
---~ return str:splitchr(io.pathseparator)
---~ end
---~ end
+file.is_readable = file.isreadable
+file.is_writable = file.iswritable
-- todo: lpeg
function file.split_path(str)
local t = { }
- str = str:gsub("\\", "/")
- str = str:gsub("(%a):([;/])", "%1\001%2")
- for name in str:gmatch("([^;:]+)") do
+ str = gsub(str,"\\", "/")
+ str = gsub(str,"(%a):([;/])", "%1\001%2")
+ for name in gmatch(str,"([^;:]+)") do
if name ~= "" then
- name = name:gsub("\001",":")
- t[#t+1] = name
+ t[#t+1] = gsub(name,"\001",":")
end
end
return t
@@ -124,15 +99,15 @@ function file.join_path(tab)
end
function file.collapse_path(str)
- str = str:gsub("/%./","/")
+ str = gsub(str,"/%./","/")
local n, m = 1, 1
while n > 0 or m > 0 do
- str, n = str:gsub("[^/%.]+/%.%.$","")
- str, m = str:gsub("[^/%.]+/%.%./","")
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
end
- str = str:gsub("([^/])/$","%1")
- str = str:gsub("^%./","")
- str = str:gsub("/%.$","")
+ str = gsub(str,"([^/])/$","%1")
+ str = gsub(str,"^%./","")
+ str = gsub(str,"/%.$","")
if str == "" then str = "." end
return str
end
@@ -145,7 +120,7 @@ end
--~ print(file.collapse_path("a/b/c/../.."))
function file.robustname(str)
- return (str:gsub("[^%a%d%/%-%.\\]+","-"))
+ return (gsub(str,"[^%a%d%/%-%.\\]+","-"))
end
file.readdata = io.loaddata
@@ -175,8 +150,6 @@ end
--~ return pattern:match(name)
--~ end
---~ file.stripsuffix = file.removesuffix
-
--~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1
--~ function file.basename(name)
@@ -230,7 +203,6 @@ end
--~ end
--~ local test = file.extname
---~ local test = file.stripsuffix
--~ local test = file.basename
--~ local test = file.dirname
--~ local test = file.addsuffix
@@ -246,3 +218,41 @@ end
--~ print(7,test("def.xxx","!!!"))
--~ local tim = os.clock() for i=1,250000 do local ext = test("abd.def.xxx","!!!") end print(os.clock()-tim)
+
+-- also rewrite previous
+
+local letter = lpeg.R("az","AZ") + lpeg.S("_-+")
+local separator = lpeg.P("://")
+
+local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/")
+local rootbased = lpeg.P("/") + letter*lpeg.P(":")
+
+-- ./name ../name /name c: :// name/name
+
+function file.is_qualified_path(filename)
+ return qualified:match(filename)
+end
+
+function file.is_rootbased_path(filename)
+ return rootbased:match(filename)
+end
+
+local slash = lpeg.S("\\/")
+local period = lpeg.P(".")
+local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":")
+local path = lpeg.C(((1-slash)^0 * slash)^0)
+local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1))
+local base = lpeg.C((1-suffix)^0)
+
+local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc(""))
+
+function file.splitname(str) -- returns drive, path, base, suffix
+ return pattern:match(str)
+end
+
+-- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end
+--
+-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
+-- test { "c:", "c:aa", "c:aa/bb", "c:aa/bb/cc", "c:aa/bb/cc.dd", "c:aa/bb/cc.dd.ee" }
+-- test { "/aa", "/aa/bb", "/aa/bb/cc", "/aa/bb/cc.dd", "/aa/bb/cc.dd.ee" }
+-- test { "aa", "aa/bb", "aa/bb/cc", "aa/bb/cc.dd", "aa/bb/cc.dd.ee" }
diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua
index 6d773c582..4b937a322 100644
--- a/tex/context/base/l-io.lua
+++ b/tex/context/base/l-io.lua
@@ -1,10 +1,12 @@
--- filename : l-io.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-io'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-io'] = 1.001
+local byte = string.byte
if string.find(os.getenv("PATH"),";") then
io.fileseparator, io.pathseparator = "\\", ";"
@@ -12,8 +14,8 @@ else
io.fileseparator, io.pathseparator = "/" , ":"
end
-function io.loaddata(filename)
- local f = io.open(filename,'rb')
+function io.loaddata(filename,textmode)
+ local f = io.open(filename,(textmode and 'r') or 'rb')
if f then
local data = f:read('*all')
-- garbagecollector.check(data)
@@ -71,146 +73,83 @@ function io.noflines(f)
return n
end
-do
+local nextchar = {
+ [ 4] = function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2] = function(f)
+ return f:read(1,1)
+ end,
+ [ 1] = function(f)
+ return f:read(1)
+ end,
+ [-2] = function(f)
+ local a, b = f:read(1,1)
+ return b, a
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ return d, c, b, a
+ end
+}
- local sb = string.byte
+function io.characters(f,n)
+ if f then
+ return nextchar[n or 1], f
+ else
+ return nil, nil
+ end
+end
- local nextchar = {
- [ 4] = function(f)
- return f:read(1,1,1,1)
- end,
- [ 2] = function(f)
- return f:read(1,1)
- end,
- [ 1] = function(f)
- return f:read(1)
- end,
- [-2] = function(f)
- local a, b = f:read(1,1)
- return b, a
- end,
- [-4] = function(f)
- local a, b, c, d = f:read(1,1,1,1)
- return d, c, b, a
+local nextbyte = {
+ [4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(a), byte(b), byte(c), byte(d)
+ else
+ return nil, nil, nil, nil
end
- }
-
- function io.characters(f,n)
- if f then
- return nextchar[n or 1], f
+ end,
+ [2] = function(f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(a), byte(b)
else
return nil, nil
end
- end
-
-end
-
-do
-
- local sb = string.byte
-
---~ local nextbyte = {
---~ [4] = function(f)
---~ local a = f:read(1)
---~ local b = f:read(1)
---~ local c = f:read(1)
---~ local d = f:read(1)
---~ if d then
---~ return sb(a), sb(b), sb(c), sb(d)
---~ else
---~ return nil, nil, nil, nil
---~ end
---~ end,
---~ [2] = function(f)
---~ local a = f:read(1)
---~ local b = f:read(1)
---~ if b then
---~ return sb(a), sb(b)
---~ else
---~ return nil, nil
---~ end
---~ end,
---~ [1] = function (f)
---~ local a = f:read(1)
---~ if a then
---~ return sb(a)
---~ else
---~ return nil
---~ end
---~ end,
---~ [-2] = function (f)
---~ local a = f:read(1)
---~ local b = f:read(1)
---~ if b then
---~ return sb(b), sb(a)
---~ else
---~ return nil, nil
---~ end
---~ end,
---~ [-4] = function(f)
---~ local a = f:read(1)
---~ local b = f:read(1)
---~ local c = f:read(1)
---~ local d = f:read(1)
---~ if d then
---~ return sb(d), sb(c), sb(b), sb(a)
---~ else
---~ return nil, nil, nil, nil
---~ end
---~ end
---~ }
-
- local nextbyte = {
- [4] = function(f)
- local a, b, c, d = f:read(1,1,1,1)
- if d then
- return sb(a), sb(b), sb(c), sb(d)
- else
- return nil, nil, nil, nil
- end
- end,
- [2] = function(f)
- local a, b = f:read(1,1)
- if b then
- return sb(a), sb(b)
- else
- return nil, nil
- end
- end,
- [1] = function (f)
- local a = f:read(1)
- if a then
- return sb(a)
- else
- return nil
- end
- end,
- [-2] = function (f)
- local a, b = f:read(1,1)
- if b then
- return sb(b), sb(a)
- else
- return nil, nil
- end
- end,
- [-4] = function(f)
- local a, b, c, d = f:read(1,1,1,1)
- if d then
- return sb(d), sb(c), sb(b), sb(a)
- else
- return nil, nil, nil, nil
- end
+ end,
+ [1] = function (f)
+ local a = f:read(1)
+ if a then
+ return byte(a)
+ else
+ return nil
end
- }
-
- function io.bytes(f,n)
- if f then
- return nextbyte[n or 1], f
+ end,
+ [-2] = function (f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(b), byte(a)
else
return nil, nil
end
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(d), byte(c), byte(b), byte(a)
+ else
+ return nil, nil, nil, nil
+ end
end
+}
+function io.bytes(f,n)
+ if f then
+ return nextbyte[n or 1], f
+ else
+ return nil, nil
+ end
end
function io.ask(question,default,options)
diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua
index cd61dc926..88b445717 100644
--- a/tex/context/base/l-lpeg.lua
+++ b/tex/context/base/l-lpeg.lua
@@ -1,9 +1,12 @@
--- filename : l-lpeg.lua
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-lpeg'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-lpeg'] = 1.001
+local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -27,35 +30,33 @@ if not versions then versions = { } end versions['l-lpeg'] = 1.001
local hash = { }
function lpeg.anywhere(pattern) --slightly adapted from website
- return lpeg.P { lpeg.P(pattern) + 1 * lpeg.V(1) }
+ return P { P(pattern) + 1 * lpeg.V(1) }
end
function lpeg.startswith(pattern) --slightly adapted
- return lpeg.P(pattern)
+ return P(pattern)
end
---~ g = lpeg.splitter(" ",function(s) ... end) -- gmatch:lpeg = 3:2
-
function lpeg.splitter(pattern, action)
- return (((1-lpeg.P(pattern))^1)/action+1)^0
+ return (((1-P(pattern))^1)/action+1)^0
end
-- variant:
--~ local parser = lpeg.Ct(lpeg.splitat(newline))
-local crlf = lpeg.P("\r\n")
-local cr = lpeg.P("\r")
-local lf = lpeg.P("\n")
-local space = lpeg.S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto)
+local crlf = P("\r\n")
+local cr = P("\r")
+local lf = P("\n")
+local space = S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto)
local newline = crlf + cr + lf
local spacing = space^0 * newline
-local empty = spacing * lpeg.Cc("")
-local nonempty = lpeg.Cs((1-spacing)^1) * spacing^-1
+local empty = spacing * Cc("")
+local nonempty = Cs((1-spacing)^1) * spacing^-1
local content = (empty + nonempty)^1
-local capture = lpeg.Ct(content^0)
+local capture = Ct(content^0)
function string:splitlines()
return capture:match(self)
@@ -70,19 +71,32 @@ lpeg.linebyline = content -- better make a sublibrary
local splitters_s, splitters_m = { }, { }
-function lpeg.splitat(separator,single)
+local function splitat(separator,single)
local splitter = (single and splitters_s[separator]) or splitters_m[separator]
if not splitter then
- separator = lpeg.P(separator)
+ separator = P(separator)
if single then
- local other, any = lpeg.C((1 - separator)^0), lpeg.P(1)
- splitter = other * (separator * lpeg.C(any^0) + "")
+ local other, any = C((1 - separator)^0), P(1)
+ splitter = other * (separator * C(any^0) + "")
splitters_s[separator] = splitter
else
- local other = lpeg.C((1 - separator)^0)
+ local other = C((1 - separator)^0)
splitter = other * (separator * other)^0
splitters_m[separator] = splitter
end
end
return splitter
end
+
+lpeg.splitat = splitat
+
+local cache = { }
+
+function string:split(separator)
+ local c = cache[separator]
+ if not c then
+ c = Ct(splitat(separator))
+ cache[separator] = c
+ end
+ return c:match(self)
+end
diff --git a/tex/context/base/l-math.lua b/tex/context/base/l-math.lua
index 00b72dba5..bfb3d506b 100644
--- a/tex/context/base/l-math.lua
+++ b/tex/context/base/l-math.lua
@@ -1,12 +1,12 @@
--- filename : l-math.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-math'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-math'] = 1.001
-
-local floor = math.floor
+local floor, sin, cos, tan = math.floor, math.sin, math.cos, math.tan
if not math.round then
function math.round(x)
@@ -25,3 +25,17 @@ if not math.mod then
return n % m
end
end
+
+local pipi = 2*math.pi/360
+
+function math.sind(d)
+ return sin(d*pipi)
+end
+
+function math.cosd(d)
+ return cos(d*pipi)
+end
+
+function math.tand(d)
+ return tan(d*pipi)
+end
diff --git a/tex/context/base/l-md5.lua b/tex/context/base/l-md5.lua
index 4deb9bd74..8640ad54e 100644
--- a/tex/context/base/l-md5.lua
+++ b/tex/context/base/l-md5.lua
@@ -1,18 +1,72 @@
--- filename : l-md5.lua
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-md5'] = {
+ version = 1.001,
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-md5'] = 1.001
+-- This also provides file checksums and checkers.
-if md5 then do
+local gsub, format, byte = string.gsub, string.format, string.byte
- local function convert(str,fmt)
- return (string.gsub(md5.sum(str),".",function(chr) return string.format(fmt,string.byte(chr)) end))
+local function convert(str,fmt)
+ return (gsub(md5.sum(str),".",function(chr) return format(fmt,byte(chr)) end))
+end
+
+if not md5.HEX then function md5.HEX(str) return convert(str,"%02X") end end
+if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
+if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
+
+--~ if not md5.HEX then
+--~ local function remap(chr) return format("%02X",byte(chr)) end
+--~ function md5.HEX(str) return (gsub(md5.sum(str),".",remap)) end
+--~ end
+--~ if not md5.hex then
+--~ local function remap(chr) return format("%02x",byte(chr)) end
+--~ function md5.hex(str) return (gsub(md5.sum(str),".",remap)) end
+--~ end
+--~ if not md5.dec then
+--~ local function remap(chr) return format("%03i",byte(chr)) end
+--~ function md5.dec(str) return (gsub(md5.sum(str),".",remap)) end
+--~ end
+
+file.needs_updating_threshold = 1
+
+function file.needs_updating(oldname,newname) -- size modification access change
+ local oldtime = lfs.attributes(oldname, modification)
+ local newtime = lfs.attributes(newname, modification)
+ if newtime >= oldtime then
+ return false
+ elseif oldtime - newtime < file.needs_updating_threshold then
+ return false
+ else
+ return true
end
+end
- if not md5.HEX then function md5.HEX(str) return convert(str,"%02X") end end
- if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
- if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
+function file.checksum(name)
+ if md5 then
+ local data = io.loaddata(name)
+ if data then
+ return md5.HEX(data)
+ end
+ end
+ return nil
+end
+
+function file.loadchecksum(name)
+ if md5 then
+ local data = io.loaddata(name .. ".md5")
+ return data and data:gsub("%s","")
+ end
+ return nil
+end
-end end
+function file.savechecksum(name, checksum)
+ if not checksum then checksum = file.checksum(name) end
+ if checksum then
+ io.savedata(name .. ".md5",checksum)
+ return checksum
+ end
+ return nil
+end
diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua
index 180b4c544..18d488a1a 100644
--- a/tex/context/base/l-number.lua
+++ b/tex/context/base/l-number.lua
@@ -1,12 +1,14 @@
--- filename : l-number.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-number'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-number'] = 1.001
+local format = string.format
-if not number then number = { } end
+number = number or { }
-- a,b,c,d,e,f = number.toset(100101)
@@ -14,8 +16,6 @@ function number.toset(n)
return (tostring(n)):match("(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)")
end
-local format = string.format
-
function number.toevenhex(n)
local s = format("%X",n)
if #s % 2 == 0 then
@@ -36,11 +36,10 @@ end
--
-- of course dedicated "(.)(.)(.)(.)" matches are even faster
-do
- local one = lpeg.C(1-lpeg.S(''))^1
+local one = lpeg.C(1-lpeg.S(''))^1
- function number.toset(n)
- return one:match(tostring(n))
- end
+function number.toset(n)
+ return one:match(tostring(n))
end
+
diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua
index 1dba5262f..47b47fa4f 100644
--- a/tex/context/base/l-os.lua
+++ b/tex/context/base/l-os.lua
@@ -1,13 +1,12 @@
--- filename : l-os.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-os'] = {
+ version = 1.001,
+ comment = "companion to luat-lub.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-
---~ print(table.serialize(os.uname()))
-
-if not versions then versions = { } end versions['l-os'] = 1.001
+local find = string.find
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -20,7 +19,7 @@ if not os.spawn then os.spawn = os.execute end
--~ os.name : windows | msdos | linux | macosx | solaris | .. | generic (new)
if not io.fileseparator then
- if string.find(os.getenv("PATH"),";") then
+ if find(os.getenv("PATH"),";") then
io.fileseparator, io.pathseparator, os.platform = "\\", ";", os.type or "windows"
else
io.fileseparator, io.pathseparator, os.platform = "/" , ":", os.type or "unix"
@@ -58,11 +57,10 @@ end
os.gettimeofday = os.gettimeofday or os.clock
-do
- local startuptime = os.gettimeofday()
- function os.runtime()
- return os.gettimeofday() - startuptime
- end
+local startuptime = os.gettimeofday()
+
+function os.runtime()
+ return os.gettimeofday() - startuptime
end
--~ print(os.gettimeofday()-os.time())
@@ -70,3 +68,63 @@ end
--~ print (">>",os.runtime())
--~ print(os.date("%H:%M:%S",os.gettimeofday()))
--~ print(os.date("%H:%M:%S",os.time()))
+
+os.arch = os.arch or function()
+ local a = os.resultof("uname -m") or "linux"
+ os.arch = function()
+ return a
+ end
+ return a
+end
+
+local platform
+
+function os.currentplatform(name,default)
+ if not platform then
+ local name = os.name or os.platform or name -- os.name is built in, os.platform is mine
+ if not name then
+ platform = default or "linux"
+ elseif name == "windows" or name == "mswin" or name == "win32" or name == "msdos" then
+ if os.getenv("PROCESSOR_ARCHITECTURE") == "AMD64" then
+ platform = "mswin-64"
+ else
+ platform = "mswin"
+ end
+ else
+ local architecture = os.arch()
+ if name == "linux" then
+ if find(architecture,"x86_64") then
+ platform = "linux-64"
+ elseif find(architecture,"ppc") then
+ platform = "linux-ppc"
+ else
+ platform = "linux"
+ end
+ elseif name == "macosx" then
+ if find(architecture,"i386") then
+ platform = "osx-intel"
+ else
+ platform = "osx-ppc"
+ end
+ elseif name == "sunos" then
+ if find(architecture,"sparc") then
+ platform = "solaris-sparc"
+ else -- if architecture == 'i86pc'
+ platform = "solaris-intel"
+ end
+ elseif name == "freebsd" then
+ if find(architecture,"amd64") then
+ platform = "freebsd-amd64"
+ else
+ platform = "freebsd"
+ end
+ else
+ platform = default or name
+ end
+ end
+ function os.currentplatform()
+ return platform
+ end
+ end
+ return platform
+end
diff --git a/tex/context/base/l-set.lua b/tex/context/base/l-set.lua
index 2bcf664f8..199253ee2 100644
--- a/tex/context/base/l-set.lua
+++ b/tex/context/base/l-set.lua
@@ -1,59 +1,56 @@
--- filename : l-set.lua
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-set'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-set'] = 1.001
+set = set or { }
-if not set then set = { } end
+local nums = { }
+local tabs = { }
+local concat = table.concat
-do
+set.create = table.tohash
- local nums = { }
- local tabs = { }
- local concat = table.concat
-
- set.create = table.tohash
-
- function set.tonumber(t)
- if next(t) then
- local s = ""
- -- we could save mem by sorting, but it slows down
- for k, v in pairs(t) do
- if v then
- -- why bother about the leading space
- s = s .. " " .. k
- end
- end
- if not nums[s] then
- tabs[#tabs+1] = t
- nums[s] = #tabs
+function set.tonumber(t)
+ if next(t) then
+ local s = ""
+ -- we could save mem by sorting, but it slows down
+ for k, v in pairs(t) do
+ if v then
+ -- why bother about the leading space
+ s = s .. " " .. k
end
- return nums[s]
- else
- return 0
end
- end
-
- function set.totable(n)
- if n == 0 then
- return { }
- else
- return tabs[n] or { }
+ if not nums[s] then
+ tabs[#tabs+1] = t
+ nums[s] = #tabs
end
+ return nums[s]
+ else
+ return 0
end
+end
- function set.contains(n,s)
- if type(n) == "table" then
- return n[s]
- elseif n == 0 then
- return false
- else
- local t = tabs[n]
- return t and t[s]
- end
+function set.totable(n)
+ if n == 0 then
+ return { }
+ else
+ return tabs[n] or { }
end
+end
+function set.contains(n,s)
+ if type(n) == "table" then
+ return n[s]
+ elseif n == 0 then
+ return false
+ else
+ local t = tabs[n]
+ return t and t[s]
+ end
end
--~ local c = set.create{'aap','noot','mies'}
diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua
index 90af72c87..ab7d314e4 100644
--- a/tex/context/base/l-string.lua
+++ b/tex/context/base/l-string.lua
@@ -1,137 +1,31 @@
--- filename : l-string.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['l-string'] = 1.001
-
---~ function string.split(str, pat) -- taken from the lua wiki
---~ local t = {n = 0} -- so this table has a length field, traverse with ipairs then!
---~ local fpat = "(.-)"..pat
---~ local last_end = 1
---~ local s, e, cap = string.find(str, fpat, 1)
---~ while s ~= nil do
---~ if s~=1 or cap~="" then
---~ table.insert(t,cap)
---~ end
---~ last_end = e+1
---~ s, e, cap = string.find(str, fpat, last_end)
---~ end
---~ if last_end<=string.len(str) then
---~ table.insert(t,(string.sub(str,last_end)))
---~ end
---~ return t
---~ end
-
---~ function string:split(pat) -- taken from the lua wiki but adapted
---~ local t = { } -- self and colon usage (faster)
---~ local fpat = "(.-)"..pat
---~ local last_end = 1
---~ local s, e, cap = self:find(fpat, 1)
---~ while s ~= nil do
---~ if s~=1 or cap~="" then
---~ t[#t+1] = cap
---~ end
---~ last_end = e+1
---~ s, e, cap = self:find(fpat, last_end)
---~ end
---~ if last_end <= #self then
---~ t[#t+1] = self:sub(last_end)
---~ end
---~ return t
---~ end
-
---~ a piece of brilliant code by Rici Lake (posted on lua list) -- only names changed
---~
---~ function string:splitter(pat)
---~ local st, g = 1, self:gmatch("()"..pat.."()")
---~ local function splitter(self)
---~ if st then
---~ local s, f = g()
---~ local rv = self:sub(st, (s or 0)-1)
---~ st = f
---~ return rv
---~ end
---~ end
---~ return splitter, self
---~ end
-
-function string:splitter(pat)
- -- by Rici Lake (posted on lua list) -- only names changed
- -- p 79 ref man: () returns position of match
- local st, g = 1, self:gmatch("()("..pat..")")
- local function strgetter(self, segs, seps, sep, cap1, ...)
- st = sep and seps + #sep
- return self:sub(segs, (seps or 0) - 1), cap1 or sep, ...
- end
- local function strsplitter(self)
- if st then return strgetter(self, st, g()) end
- end
- return strsplitter, self
-end
+if not modules then modules = { } end modules ['l-string'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-function string:split(separator)
- local t = {}
- for k in self:splitter(separator) do t[#t+1] = k end
- return t
-end
+local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep
--- faster than a string:split:
+if not string.split then
-function string:splitchr(chr)
- if #self > 0 then
- local t = { }
- for s in (self..chr):gmatch("(.-)"..chr) do
- t[#t+1] = s
+ -- this will be overloaded by a faster lpeg variant
+
+ function string:split(pattern)
+ if #self > 0 then
+ local t = { }
+ for s in gmatch(self..pattern,"(.-)"..pattern) do
+ t[#t+1] = s
+ end
+ return t
+ else
+ return { }
end
- return t
- else
- return { }
end
-end
-function string.piecewise(str, pat, fnc) -- variant of split
- for k in string.splitter(str,pat) do fnc(k) end
end
---~ function string.piecewise(str, pat, fnc) -- variant of split
---~ for k in str:splitter(pat) do fnc(k) end
---~ end
-
---~ do if lpeg then
-
---~ -- this alternative is 30% faster esp when we cache them
---~ -- problem: no expressions
-
---~ splitters = { }
-
---~ function string:split(separator)
---~ if #self > 0 then
---~ local split = splitters[separator]
---~ if not split then
---~ -- based on code by Roberto
---~ local p = lpeg.P(separator)
---~ local c = lpeg.C((1-p)^0)
---~ split = lpeg.Ct(c*(p*c)^0)
---~ splitters[separator] = split
---~ end
---~ return split:match(self)
---~ else
---~ return { }
---~ end
---~ end
-
---~ string.splitchr = string.split
-
---~ function string:piecewise(separator,fnc)
---~ for _,v in pairs(self:split(separator)) do
---~ fnc(v)
---~ end
---~ end
-
---~ end end
-
local chr_to_esc = {
["%"] = "%%",
["."] = "%.",
@@ -145,20 +39,20 @@ local chr_to_esc = {
string.chr_to_esc = chr_to_esc
function string:esc() -- variant 2
- return (self:gsub("(.)",chr_to_esc))
+ return (gsub(self,"(.)",chr_to_esc))
end
function string:unquote()
- return (self:gsub("^([\"\'])(.*)%1$","%2"))
+ return (gsub(self,"^([\"\'])(.*)%1$","%2"))
end
-function string:quote()
+function string:quote() -- we could use format("%q")
return '"' .. self:unquote() .. '"'
end
function string:count(pattern) -- variant 3
local n = 0
- for _ in self:gmatch(pattern) do
+ for _ in gmatch(self,pattern) do
n = n + 1
end
return n
@@ -167,29 +61,25 @@ end
function string:limit(n,sentinel)
if #self > n then
sentinel = sentinel or " ..."
- return self:sub(1,(n-#sentinel)) .. sentinel
+ return sub(self,1,(n-#sentinel)) .. sentinel
else
return self
end
end
function string:strip()
- return (self:gsub("^%s*(.-)%s*$", "%1"))
+ return (gsub(self,"^%s*(.-)%s*$", "%1"))
end
---~ function string.strip(str) -- slightly different
---~ return (string.gsub(string.gsub(str,"^%s*(.-)%s*$","%1"),"%s+"," "))
---~ end
-
function string:is_empty()
- return not self:find("%S")
+ return not find(find,"%S")
end
function string:enhance(pattern,action)
local ok, n = true, 0
while ok do
ok = false
- self = self:gsub(pattern, function(...)
+ self = gsub(self,pattern, function(...)
ok, n = true, n + 1
return action(...)
end)
@@ -197,59 +87,19 @@ function string:enhance(pattern,action)
return self, n
end
---~ function string:enhance(pattern,action)
---~ local ok, n = 0, 0
---~ repeat
---~ self, ok = self:gsub(pattern, function(...)
---~ n = n + 1
---~ return action(...)
---~ end)
---~ until ok == 0
---~ return self, n
---~ end
-
---~ function string:to_hex()
---~ if self then
---~ return (self:gsub("(.)",function(c)
---~ return string.format("%02X",c:byte())
---~ end))
---~ else
---~ return ""
---~ end
---~ end
-
---~ function string:from_hex()
---~ if self then
---~ return (self:gsub("(..)",function(c)
---~ return string.char(tonumber(c,16))
---~ end))
---~ else
---~ return ""
---~ end
---~ end
-
-string.chr_to_hex = { }
-string.hex_to_chr = { }
+local chr_to_hex, hex_to_chr = { }, { }
for i=0,255 do
- local c, h = string.char(i), string.format("%02X",i)
- string.chr_to_hex[c], string.hex_to_chr[h] = h, c
+ local c, h = char(i), format("%02X",i)
+ chr_to_hex[c], hex_to_chr[h] = h, c
end
---~ function string:to_hex()
---~ if self then return (self:gsub("(.)",string.chr_to_hex)) else return "" end
---~ end
-
---~ function string:from_hex()
---~ if self then return (self:gsub("(..)",string.hex_to_chr)) else return "" end
---~ end
-
function string:to_hex()
- return ((self or ""):gsub("(.)",string.chr_to_hex))
+ return (gsub(self or "","(.)",chr_to_hex))
end
function string:from_hex()
- return ((self or ""):gsub("(..)",string.hex_to_chr))
+ return (gsub(self or "","(..)",hex_to_chr))
end
if not string.characters then
@@ -263,7 +113,7 @@ if not string.characters then
end
local function nextbyte(str, index)
index = index + 1
- return (index <= #str) and index or nil, string.byte(str:sub(index,index))
+ return (index <= #str) and index or nil, byte(str:sub(index,index))
end
function string:bytes()
return nextbyte, self, 0
@@ -271,9 +121,7 @@ if not string.characters then
end
---~ function string:padd(n,chr)
---~ return self .. self.rep(chr or " ",n-#self)
---~ end
+-- we can use format for this (neg n)
function string:rpadd(n,chr)
local m = n-#self
@@ -295,8 +143,8 @@ end
string.padd = string.rpadd
-function is_number(str)
- return str:find("^[%-%+]?[%d]-%.?[%d+]$") == 1
+function is_number(str) -- tonumber
+ return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1
end
--~ print(is_number("1"))
@@ -308,9 +156,9 @@ end
--~ print(is_number("+.1"))
function string:split_settings() -- no {} handling, see l-aux for lpeg variant
- if self:find("=") then
+ if find(self,"=") then
local t = { }
- for k,v in self:gmatch("(%a+)=([^%,]*)") do
+ for k,v in gmatch(self,"(%a+)=([^%,]*)") do
t[k] = v
end
return t
@@ -332,13 +180,49 @@ local patterns_escapes = {
}
function string:pattesc()
- return (self:gsub(".",patterns_escapes))
+ return (gsub(self,".",patterns_escapes))
end
function string:tohash()
local t = { }
- for s in self:gmatch("([^, ]+)") do -- lpeg
+ for s in gmatch(self,"([^, ]+)") do -- lpeg
t[s] = true
end
return t
end
+
+local pattern = lpeg.Ct(lpeg.C(1)^0)
+
+function string:totable()
+ return pattern:match(self)
+end
+
+--~ for _, str in ipairs {
+--~ "1234567123456712345671234567",
+--~ "a\tb\tc",
+--~ "aa\tbb\tcc",
+--~ "aaa\tbbb\tccc",
+--~ "aaaa\tbbbb\tcccc",
+--~ "aaaaa\tbbbbb\tccccc",
+--~ "aaaaaa\tbbbbbb\tcccccc",
+--~ } do print(string.tabtospace(str)) end
+
+function string.tabtospace(str,tab)
+ -- we don't handle embedded newlines
+ while true do
+ local s = find(str,"\t")
+ if s then
+ if not tab then tab = 7 end -- only when found
+ local d = tab-(s-1)%tab
+ if d > 0 then
+ str = gsub(str,"\t",rep(" ",d),1)
+ else
+ str = gsub(str,"\t","",1)
+ end
+ else
+ break
+ end
+ end
+ return str
+end
+
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 23d4bed63..bfe33ff85 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -1,22 +1,22 @@
--- filename : l-table.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['l-table'] = 1.001
+if not modules then modules = { } end modules ['l-table'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format = string.format
+local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
local getmetatable, setmetatable = getmetatable, setmetatable
-local pairs, ipairs, type, next, tostring = pairs, ipairs, type, next, tostring
+local type, next, tostring, ipairs = type, next, tostring, ipairs
function table.strip(tab)
local lst = { }
for i=1,#tab do
- local s = tab[i]:gsub("^%s*(.-)%s*$","%1")
+ local s = gsub(tab[i],"^%s*(.-)%s*$","%1")
if s == "" then
-- skip this one
else
@@ -28,7 +28,7 @@ end
local function sortedkeys(tab)
local srt, kind = { }, 0 -- 0=unknown 1=string, 2=number 3=mixed
- for key,_ in pairs(tab) do
+ for key,_ in next, tab do
srt[#srt+1] = key
if kind == 3 then
-- no further check
@@ -55,7 +55,7 @@ end
local function sortedhashkeys(tab) -- fast one
local srt = { }
- for key,_ in pairs(tab) do
+ for key,_ in next, tab do
srt[#srt+1] = key
end
sort(srt)
@@ -65,14 +65,25 @@ end
table.sortedkeys = sortedkeys
table.sortedhashkeys = sortedhashkeys
+function table.sortedpairs(t)
+ local s = sortedhashkeys(t) -- maybe just sortedkeys
+ local n = 0
+ local function kv(s)
+ n = n + 1
+ local k = s[n]
+ return k, t[k]
+ end
+ return kv, s
+end
+
function table.append(t, list)
- for _,v in pairs(list) do
+ for _,v in next, list do
insert(t,v)
end
end
function table.prepend(t, list)
- for k,v in pairs(list) do
+ for k,v in next, list do
insert(t,k,v)
end
end
@@ -81,7 +92,7 @@ function table.merge(t, ...) -- first one is target
t = t or {}
local lst = {...}
for i=1,#lst do
- for k, v in pairs(lst[i]) do
+ for k, v in next, lst[i] do
t[k] = v
end
end
@@ -91,7 +102,7 @@ end
function table.merged(...)
local tmp, lst = { }, {...}
for i=1,#lst do
- for k, v in pairs(lst[i]) do
+ for k, v in next, lst[i] do
tmp[k] = v
end
end
@@ -123,13 +134,14 @@ end
local function fastcopy(old) -- fast one
if old then
local new = { }
- for k,v in pairs(old) do
+ for k,v in next, old do
if type(v) == "table" then
new[k] = fastcopy(v) -- was just table.copy
else
new[k] = v
end
end
+ -- optional second arg
local mt = getmetatable(old)
if mt then
setmetatable(new,mt)
@@ -146,7 +158,7 @@ local function copy(t, tables) -- taken from lua wiki, slightly adapted
if not tables[t] then
tables[t] = tcopy
end
- for i,v in pairs(t) do -- brrr, what happens with sparse indexed
+ for i,v in next, t do -- brrr, what happens with sparse indexed
if type(i) == "table" then
if tables[i] then
i = tables[i]
@@ -179,7 +191,7 @@ function table.sub(t,i,j)
end
function table.replace(a,b)
- for k,v in pairs(b) do
+ for k,v in next, b do
a[k] = v
end
end
@@ -201,16 +213,18 @@ end
function table.tohash(t,value)
local h = { }
- if value == nil then value = true end
- for _, v in pairs(t) do -- no ipairs here
- h[v] = value
+ if t then
+ if value == nil then value = true end
+ for _, v in next, t do -- no ipairs here
+ h[v] = value
+ end
end
return h
end
function table.fromhash(t)
local h = { }
- for k, v in pairs(t) do -- no ipairs here
+ for k, v in next, t do -- no ipairs here
if v then h[#h+1] = k end
end
return h
@@ -234,24 +248,10 @@ local reserved = table.tohash { -- intercept a language flaw, no reserved words
'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
}
-local function key(k)
- if type(k) == "number" then -- or k:find("^%d+$") then
- if hexify then
- return ("[0x%04X]"):format(k)
- else
- return "["..k.."]"
- end
- elseif noquotes and not reserved[k] and k:find("^%a[%a%d%_]*$") then
- return k
- else
- return '["'..k..'"]'
- end
-end
-
local function simple_table(t)
if #t > 0 then
local n = 0
- for _,v in pairs(t) do
+ for _,v in next, t do
n = n + 1
end
if n == #t then
@@ -261,14 +261,14 @@ local function simple_table(t)
local tv = type(v)
if tv == "number" then
if hexify then
- tt[#tt+1] = ("0x%04X"):format(v)
+ tt[#tt+1] = format("0x%04X",v)
else
- tt[#tt+1] = tostring(v)
+ tt[#tt+1] = tostring(v) -- tostring not needed
end
elseif tv == "boolean" then
tt[#tt+1] = tostring(v)
elseif tv == "string" then
- tt[#tt+1] = ("%q"):format(v)
+ tt[#tt+1] = format("%q",v)
else
tt = nil
break
@@ -280,21 +280,40 @@ local function simple_table(t)
return nil
end
+-- Because this is a core function of mkiv I moved some function calls
+-- inline.
+--
+-- twice as fast in a test:
+--
+-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
if indexed then
- handle(("%s{"):format(depth))
+ handle(format("%s{",depth))
elseif name then
- handle(("%s%s={"):format(depth,key(name)))
+ --~ handle(format("%s%s={",depth,key(name)))
+ if type(name) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s[0x%04X]={",depth,name))
+ else
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif noquotes and not reserved[name] and find(name,"^%a[%w%_]*$") then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
else
- handle(("%s{"):format(depth))
+ handle(format("%s{",depth))
end
end
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
- for k,v in ipairs(root) do -- NOT: for k=1,#root do (we need to quit at nil)
+ -- NOT: for k=1,#root do (we need to quit at nil)
+ for k,v in ipairs(root) do -- can we use next?
if not first then first = k end
last = last + 1
end
@@ -303,30 +322,30 @@ local function do_serialize(root,name,depth,level,indexed)
for i=1,#sk do
local k = sk[i]
local v = root[k]
---~ if v == root then
- -- circular
---~ else
+ --~ if v == root then
+ -- circular
+ --~ else
local t = type(v)
if compact and first and type(k) == "number" and k >= first and k <= last then
if t == "number" then
if hexify then
- handle(("%s 0x%04X,"):format(depth,v))
+ handle(format("%s 0x%04X,",depth,v))
else
- handle(("%s %s,"):format(depth,v))
+ handle(format("%s %s,",depth,v))
end
elseif t == "string" then
- if reduce and (v:find("^[%-%+]?[%d]-%.?[%d+]$") == 1) then
- handle(("%s %s,"):format(depth,v))
+ if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ handle(format("%s %s,",depth,v))
else
- handle(("%s %q,"):format(depth,v))
+ handle(format("%s %q,",depth,v))
end
elseif t == "table" then
if not next(v) then
- handle(("%s {},"):format(depth))
- elseif inline then
+ handle(format("%s {},",depth))
+ elseif inline then -- and #t > 0
local st = simple_table(v)
if st then
- handle(("%s { %s },"):format(depth,concat(st,", ")))
+ handle(format("%s { %s },",depth,concat(st,", ")))
else
do_serialize(v,k,depth,level+1,true)
end
@@ -334,39 +353,102 @@ local function do_serialize(root,name,depth,level,indexed)
do_serialize(v,k,depth,level+1,true)
end
elseif t == "boolean" then
- handle(("%s %s,"):format(depth,tostring(v)))
+ handle(format("%s %s,",depth,tostring(v)))
elseif t == "function" then
if functions then
- handle(('%s loadstring(%q),'):format(depth,v:dump()))
+ handle(format('%s loadstring(%q),',depth,dump(v)))
else
- handle(('%s "function",'):format(depth))
+ handle(format('%s "function",',depth))
end
else
- handle(("%s %q,"):format(depth,tostring(v)))
+ handle(format("%s %q,",depth,tostring(v)))
end
elseif k == "__p__" then -- parent
if false then
- handle(("%s __p__=nil,"):format(depth))
+ handle(format("%s __p__=nil,",depth))
end
elseif t == "number" then
- if hexify then
- handle(("%s %s=0x%04X,"):format(depth,key(k),v))
+ --~ if hexify then
+ --~ handle(format("%s %s=0x%04X,",depth,key(k),v))
+ --~ else
+ --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ end
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ if hexify then
+ handle(format("%s %s=0x%04X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
else
- handle(("%s %s=%s,"):format(depth,key(k),v))
+ if hexify then
+ handle(format("%s [%q]=0x%04X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
end
elseif t == "string" then
- if reduce and (v:find("^[%-%+]?[%d]-%.?[%d+]$") == 1) then
- handle(("%s %s=%s,"):format(depth,key(k),v))
+ if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ --~ handle(format("%s %s=%s,",depth,key(k),v))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%s,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%s,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
else
- handle(("%s %s=%q,"):format(depth,key(k),v))
+ --~ handle(format("%s %s=%q,",depth,key(k),v))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
end
elseif t == "table" then
if not next(v) then
- handle(("%s %s={},"):format(depth,key(k)))
+ --~ handle(format("%s %s={},",depth,key(k)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
elseif inline then
local st = simple_table(v)
if st then
- handle(("%s %s={ %s },"):format(depth,key(k),concat(st,", ")))
+ --~ handle(format("%s %s={ %s },",depth,key(k),concat(st,", ")))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
else
do_serialize(v,k,depth,level+1)
end
@@ -374,25 +456,58 @@ local function do_serialize(root,name,depth,level,indexed)
do_serialize(v,k,depth,level+1)
end
elseif t == "boolean" then
- handle(("%s %s=%s,"):format(depth,key(k),tostring(v)))
+ --~ handle(format("%s %s=%s,",depth,key(k),tostring(v)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%s,",depth,k,tostring(v)))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%s,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%s,",depth,k,tostring(v)))
+ end
elseif t == "function" then
if functions then
- handle(('%s %s=loadstring(%q),'):format(depth,key(k),v:dump()))
- else
- handle(('%s %s="function",'):format(depth,key(k)))
+ --~ handle(format('%s %s=loadstring(%q),',depth,key(k),dump(v)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=loadstring(%q),",depth,k,dump(v)))
+ else
+ handle(format("%s [%s]=loadstring(%q),",depth,k,dump(v)))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=loadstring(%q),",depth,k,dump(v)))
+ else
+ handle(format("%s [%q]=loadstring(%q),",depth,k,dump(v)))
+ end
end
else
- handle(("%s %s=%q,"):format(depth,key(k),tostring(v)))
- -- handle(('%s %s=loadstring(%q),'):format(depth,key(k),string.dump(function() return v end)))
+ --~ handle(format("%s %s=%q,",depth,key(k),tostring(v)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
end
---~ end
+ --~ end
end
end
if level > 0 then
- handle(("%s},"):format(depth))
+ handle(format("%s},",depth))
end
end
+-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
+-- faster (0.03 on 1.00 for zapfino.tma)
+
local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
noquotes = _noquotes
hexify = _hexify
@@ -410,7 +525,7 @@ local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
end
elseif tname == "number" then
if hexify then
- handle(("[0x%04X]={"):format(name))
+ handle(format("[0x%04X]={",name))
else
handle("[" .. name .. "]={")
end
@@ -561,14 +676,18 @@ function table.insert_after_value(t,value,str)
end
end
-function table.are_equal(a,b,n,m)
+local function are_equal(a,b,n,m) -- indexed
if #a == #b then
n = n or 1
m = m or #a
for i=n,m do
local ai, bi = a[i], b[i]
- if (ai==bi) or (type(ai)=="table" and type(bi)=="table" and table.are_equal(ai,bi)) then
- -- continue
+ if ai==bi then
+ -- same
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
else
return false
end
@@ -579,9 +698,30 @@ function table.are_equal(a,b,n,m)
end
end
+local function identical(a,b) -- assumes same structure
+ for ka, va in next, a do
+ local vb = b[k]
+ if va == vb then
+ -- same
+ elseif type(va) == "table" and type(vb) == "table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+end
+
+table.are_equal = are_equal
+table.identical = identical
+
+-- maybe also make a combined one
+
function table.compact(t)
if t then
- for k,v in pairs(t) do
+ for k,v in next, t do
if not next(v) then
t[k] = nil
end
@@ -610,7 +750,7 @@ end
function table.swapped(t)
local s = { }
- for k, v in pairs(t) do
+ for k, v in next, t do
s[v] = k
end
return s
@@ -632,14 +772,14 @@ end
function table.hexed(t,seperator)
local tt = { }
- for i=1,#t do tt[i] = ("0x%04X"):format(t[i]) end
+ for i=1,#t do tt[i] = format("0x%04X",t[i]) end
return concat(tt,seperator or " ")
end
function table.reverse_hash(h)
local r = { }
- for k,v in pairs(h) do
- r[v] = (k:gsub(" ","")):lower()
+ for k,v in next, h do
+ r[v] = lower(gsub(k," ",""))
end
return r
end
@@ -653,3 +793,19 @@ function table.reverse(t)
end
return tt
end
+
+--~ function table.keys(t)
+--~ local k = { }
+--~ for k,_ in next, t do
+--~ k[#k+1] = k
+--~ end
+--~ return k
+--~ end
+
+--~ function table.keys_as_string(t)
+--~ local k = { }
+--~ for k,_ in next, t do
+--~ k[#k+1] = k
+--~ end
+--~ return concat(k,"")
+--~ end
diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua
index ebd67db1c..124a1e240 100644
--- a/tex/context/base/l-unicode.lua
+++ b/tex/context/base/l-unicode.lua
@@ -1,14 +1,17 @@
--- filename : l-unicode.lua
--- comment : split off from luat-inp
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-unicode'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+utf = utf or unicode.utf8
-if not versions then versions = { } end versions['l-unicode'] = 1.001
-if not unicode then unicode = { } end
+local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub
+local char, byte, find, bytepairs = string.char, string.byte, string.find, string.bytepairs
-local concat, utfchar, utfgsub = table.concat, unicode.utf8.char, unicode.utf8.gsub
-local char, byte = string.char, string.byte
+unicode = unicode or { }
-- 0 EF BB BF UTF-8
-- 1 FF FE UTF-16-little-endian
@@ -29,17 +32,17 @@ function unicode.utftype(f) -- \000 fails !
if not str then
f:seek('set')
return 0
- elseif str:find("^%z%z\254\255") then
+ elseif find(str,"^%z%z\254\255") then
return 4
- elseif str:find("^\255\254%z%z") then
+ elseif find(str,"^\255\254%z%z") then
return 3
- elseif str:find("^\254\255") then
+ elseif find(str,"^\254\255") then
f:seek('set',2)
return 2
- elseif str:find("^\255\254") then
+ elseif find(str,"^\255\254") then
f:seek('set',2)
return 1
- elseif str:find("^\239\187\191") then
+ elseif find(str,"^\239\187\191") then
f:seek('set',3)
return 0
else
@@ -67,7 +70,7 @@ function unicode.utf16_to_utf8(str, endian) -- maybe a gsub is faster or an lpeg
p = 0
end
end
- for l,r in str:bytepairs() do
+ for l,r in bytepairs(str) do
if r then
if endian then
n = l*256 + r
@@ -111,7 +114,7 @@ function unicode.utf32_to_utf8(str, endian)
p = 0
end
end
- for a,b in str:bytepairs() do
+ for a,b in bytepairs(str) do
if a and b then
if m < 0 then
if endian then
@@ -138,28 +141,32 @@ function unicode.utf32_to_utf8(str, endian)
return result
end
+local function little(c)
+ local b = byte(c) -- b = c:byte()
+ if b < 0x10000 then
+ return char(b%256,b/256)
+ else
+ b = b - 0x10000
+ local b1, b2 = b/1024 + 0xD800, b%1024 + 0xDC00
+ return char(b1%256,b1/256,b2%256,b2/256)
+ end
+end
+
+local function big(c)
+ local b = byte(c)
+ if b < 0x10000 then
+ return char(b/256,b%256)
+ else
+ b = b - 0x10000
+ local b1, b2 = b/1024 + 0xD800, b%1024 + 0xDC00
+ return char(b1/256,b1%256,b2/256,b2%256)
+ end
+end
+
function unicode.utf8_to_utf16(str,littleendian)
if littleendian then
- return char(255,254) .. utfgsub(str,".",function(c)
- local b = byte(c) -- b = c:byte()
- if b < 0x10000 then
- return char(b%256,b/256)
- else
- b = b - 0x10000
- local b1, b2 = b/1024 + 0xD800, b%1024 + 0xDC00
- return char(b1%256,b1/256,b2%256,b2/256)
- end
- end)
+ return char(255,254) .. utfgsub(str,".",little)
else
- return char(254,255) .. utfgsub(str,".",function(c)
- local b = byte(c)
- if b < 0x10000 then
- return char(b/256,b%256)
- else
- b = b - 0x10000
- local b1, b2 = b/1024 + 0xD800, b%1024 + 0xDC00
- return char(b1/256,b1%256,b2/256,b2%256)
- end
- end)
+ return char(254,255) .. utfgsub(str,".",big)
end
end
diff --git a/tex/context/base/l-url.lua b/tex/context/base/l-url.lua
index 3bb2b1f11..097c94467 100644
--- a/tex/context/base/l-url.lua
+++ b/tex/context/base/l-url.lua
@@ -1,10 +1,13 @@
--- filename : l-url.lua
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-url'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-url'] = 1.001
-if not url then url = { } end
+local char, gmatch = string.char, string.gmatch
+local tonumber, type = tonumber, type
-- from the spec (on the web):
--
@@ -16,29 +19,28 @@ if not url then url = { } end
-- / \ / \
-- urn:example:animal:ferret:nose
-do
+url = url or { }
- local function tochar(s)
- return string.char(tonumber(s,16))
- end
+local function tochar(s)
+ return char(tonumber(s,16))
+end
- local colon, qmark, hash, slash, percent, endofstring = lpeg.P(":"), lpeg.P("?"), lpeg.P("#"), lpeg.P("/"), lpeg.P("%"), lpeg.P(-1)
+local colon, qmark, hash, slash, percent, endofstring = lpeg.P(":"), lpeg.P("?"), lpeg.P("#"), lpeg.P("/"), lpeg.P("%"), lpeg.P(-1)
- local hexdigit = lpeg.R("09","AF","af")
- local escaped = percent * lpeg.C(hexdigit * hexdigit) / tochar
+local hexdigit = lpeg.R("09","AF","af")
+local plus = lpeg.P("+")
+local escaped = (plus / " ") + (percent * lpeg.C(hexdigit * hexdigit) / tochar)
- local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("")
- local authority = slash * slash * lpeg.Cs((escaped+(1- slash-qmark-hash))^0) + lpeg.Cc("")
- local path = slash * lpeg.Cs((escaped+(1- qmark-hash))^0) + lpeg.Cc("")
- local query = qmark * lpeg.Cs((escaped+(1- hash))^0) + lpeg.Cc("")
- local fragment = hash * lpeg.Cs((escaped+(1- endofstring))^0) + lpeg.Cc("")
+local scheme = lpeg.Cs((escaped+(1-colon-slash-qmark-hash))^0) * colon + lpeg.Cc("")
+local authority = slash * slash * lpeg.Cs((escaped+(1- slash-qmark-hash))^0) + lpeg.Cc("")
+local path = slash * lpeg.Cs((escaped+(1- qmark-hash))^0) + lpeg.Cc("")
+local query = qmark * lpeg.Cs((escaped+(1- hash))^0) + lpeg.Cc("")
+local fragment = hash * lpeg.Cs((escaped+(1- endofstring))^0) + lpeg.Cc("")
- local parser = lpeg.Ct(scheme * authority * path * query * fragment)
-
- function url.split(str)
- return (type(str) == "string" and parser:match(str)) or str
- end
+local parser = lpeg.Ct(scheme * authority * path * query * fragment)
+function url.split(str)
+ return (type(str) == "string" and parser:match(str)) or str
end
function url.hashed(str)
@@ -61,7 +63,7 @@ end
function url.query(str)
if type(str) == "string" then
local t = { }
- for k, v in str:gmatch("([^&=]*)=([^&=]*)") do
+ for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
t[k] = v
end
return t
@@ -76,12 +78,12 @@ end
--~ print(url.filename("file:///etc/test.txt"))
--~ print(url.filename("/oeps.txt"))
--- from the spec on the web (sort of):
+--~ from the spec on the web (sort of):
--~
--~ function test(str)
--~ print(table.serialize(url.hashed(str)))
--~ end
----~
+--~
--~ test("%56pass%20words")
--~ test("file:///c:/oeps.txt")
--~ test("file:///c|/oeps.txt")
diff --git a/tex/context/base/l-utils.lua b/tex/context/base/l-utils.lua
index fa8e31ba8..8d531711f 100644
--- a/tex/context/base/l-utils.lua
+++ b/tex/context/base/l-utils.lua
@@ -1,10 +1,12 @@
--- filename : l-utils.lua
--- comment : split off from luat-lib
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['l-utils'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['l-utils'] = 1.001
+-- hm, quite unreadable
if not utils then utils = { } end
if not utils.merger then utils.merger = { } end
@@ -69,24 +71,52 @@ function utils.merger._self_swap_(data,code)
end
end
+--~ stripper:
+--~
+--~ data = string.gsub(data,"%-%-~[^\n]*\n","")
+--~ data = string.gsub(data,"\n\n+","\n")
+
function utils.merger._self_libs_(libs,list)
- local result, f = { }, nil
+ local result, f, frozen = { }, nil, false
+ result[#result+1] = "\n"
if type(libs) == 'string' then libs = { libs } end
if type(list) == 'string' then list = { list } end
+ local foundpath = nil
for _, lib in ipairs(libs) do
for _, pth in ipairs(list) do
- local name = string.gsub(pth .. "/" .. lib,"\\","/")
- f = io.open(name)
- if f then
- utils.report("merging library %s",name)
- result[#result+1] = f:read("*all")
- f:close()
- list = { pth } -- speed up the search
- break
+ pth = string.gsub(pth,"\\","/") -- file.clean_path
+ utils.report("checking library path %s",pth)
+ local name = pth .. "/" .. lib
+ if lfs.isfile(name) then
+ foundpath = pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ utils.report("using library path %s",foundpath)
+ local right, wrong = { }, { }
+ for _, lib in ipairs(libs) do
+ local fullname = foundpath .. "/" .. lib
+ if lfs.isfile(fullname) then
+ -- right[#right+1] = lib
+ utils.report("merging library %s",fullname)
+ result[#result+1] = "do -- create closure to overcome 200 locals limit"
+ result[#result+1] = io.loaddata(fullname,true)
+ result[#result+1] = "end -- of closure"
else
- utils.report("no library %s",name)
+ -- wrong[#wrong+1] = lib
+ utils.report("no library %s",fullname)
end
end
+ if #right > 0 then
+ utils.report("merged libraries: %s",table.concat(right," "))
+ end
+ if #wrong > 0 then
+ utils.report("skipped libraries: %s",table.concat(wrong," "))
+ end
+ else
+ utils.report("no valid library path found")
end
return table.concat(result, "\n\n")
end
diff --git a/tex/context/base/l-xml.lua b/tex/context/base/l-xml.lua
index cdb9dacc5..d6c48fe7b 100644
--- a/tex/context/base/l-xml.lua
+++ b/tex/context/base/l-xml.lua
@@ -10,6 +10,7 @@ if not modules then modules = { } end modules ['l-xml'] = {
-- some code may move to l-xmlext
-- some day we will really compile the lpaths (just construct functions)
+-- todo: some things per xml file, like namespace remapping
--[[ldx--
<p>The parser used here is inspired by the variant discussed in the lua book, but
@@ -38,15 +39,30 @@ optimize the code.</p>
xml = xml or { }
tex = tex or { }
-xml.trace_lpath = false
-xml.trace_print = false
-xml.trace_remap = false
+local concat, remove, insert = table.concat, table.remove, table.insert
+local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring
+local format, lower, gmatch, gsub, find = string.format, string.lower, string.gmatch, string.gsub, string.find
-local format, concat, remove, insert, type, next = string.format, table.concat, table.remove, table.insert, type, next
+--[[ldx--
+<p>This module can be used stand alone but also inside <l n='mkiv'/> in
+which case it hooks into the tracker code. Therefore we provide a few
+functions that set the tracers.</p>
+--ldx]]--
---~ local pairs, next, type = pairs, next, type
+local trace_lpath, trace_remap = false, false
--- todo: some things per xml file, like namespace remapping
+if trackers then
+ trackers.register("xml.lpath", function(v) trace_lpath = v end)
+ trackers.register("xml.remap", function(v) trace_remap = v end)
+end
+
+function xml.settrace(str,value)
+ if str == "lpath" then
+ trace_lpath = value or false
+ elseif str == "remap" then
+ trace_remap = value or false
+ end
+end
--[[ldx--
<p>First a hack to enable namespace resolving. A namespace is characterized by
@@ -73,7 +89,7 @@ do
--ldx]]--
function xml.registerns(namespace, pattern) -- pattern can be an lpeg
- check = check + lpeg.C(lpeg.P(pattern:lower())) / namespace
+ check = check + lpeg.C(lpeg.P(lower(pattern))) / namespace
parse = lpeg.P { lpeg.P(check) + 1 * lpeg.V(1) }
end
@@ -88,7 +104,7 @@ do
--ldx]]--
function xml.checkns(namespace,url)
- local ns = parse:match(url:lower())
+ local ns = parse:match(lower(url))
if ns and namespace ~= ns then
xml.xmlns[namespace] = ns
end
@@ -106,7 +122,7 @@ do
--ldx]]--
function xml.resolvens(url)
- return parse:match(url:lower()) or ""
+ return parse:match(lower(url)) or ""
end
--[[ldx--
@@ -173,6 +189,9 @@ do
end
local function add_attribute(namespace,tag,value)
+ if cleanup and #value > 0 then
+ value = cleanup(value) -- new
+ end
if tag == "xmlns" then
xmlns[#xmlns+1] = resolvens(value)
at[tag] = value
@@ -245,7 +264,7 @@ dt[0] = top
end
end
local function set_message(txt)
- errorstr = "garbage at the end of the file: " .. txt:gsub("([ \n\r\t]*)","")
+ errorstr = "garbage at the end of the file: " .. gsub(txt,"([ \n\r\t]*)","")
end
local P, S, R, C, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V
@@ -293,7 +312,7 @@ dt[0] = top
local somecomment = C((1 - endcomment )^0)
local somecdata = C((1 - endcdata )^0)
- function entity(k,v) entities[k] = v end
+ local function entity(k,v) entities[k] = v end
local begindoctype = open * P("!DOCTYPE")
local enddoctype = close
@@ -389,7 +408,7 @@ dt[0] = top
return root and not root.error
end
- xml.error_handler = (logs and logs.report) or (input and input.report) or print
+ xml.error_handler = (logs and logs.report) or (input and logs.report) or print
end
@@ -535,16 +554,16 @@ do
local ats = eat and next(eat) and { } -- type test maybe faster
if ats then
if attributeconverter then
- for k,v in pairs(eat) do
+ for k,v in next, eat do
ats[#ats+1] = format('%s=%q',k,attributeconverter(v))
end
else
- for k,v in pairs(eat) do
+ for k,v in next, eat do
ats[#ats+1] = format('%s=%q',k,v)
end
end
end
- if ern and xml.trace_remap and ern ~= ens then
+ if ern and trace_remap and ern ~= ens then
ens = ern
end
if ens ~= "" then
@@ -640,7 +659,8 @@ do
function xml.checkbom(root) -- can be made faster
if root.ri then
local dt, found = root.dt, false
- for k,v in ipairs(dt) do
+ for k=1,#dt do
+ local v = dt[k]
if type(v) == "table" and v.special and v.tg == "@pi" and v.dt:find("xml.*version=") then
found = true
break
@@ -913,8 +933,6 @@ do
local bar = P('|')
local hat = P('^')
local valid = R('az', 'AZ', '09') + S('_-')
---~ local name_yes = C(valid^1 + star) * colon * C(valid^1 + star) -- permits ns:* *:tg *:*
---~ local name_nop = C(P(true)) * C(valid^1)
local name_yes = C(valid^1 + star) * colon * C(valid^1 + star) -- permits ns:* *:tg *:*
local name_nop = Cc("*") * C(valid^1)
local name = name_yes + name_nop
@@ -1051,7 +1069,7 @@ do
if m ~= 11 and m ~= 12 and m ~= 13 and m ~= 14 and m ~= 15 and m ~= 16 then
insert(map, 1, { 16 })
end
- -- print((table.serialize(map)):gsub("[ \n]+"," "))
+ -- print(gsub(table.serialize(map),"[ \n]+"," "))
return map
end
end
@@ -1068,7 +1086,7 @@ do
cache[pattern] = result
lpathcached = lpathcached + 1
end
- if trace or xml.trace_lpath then
+ if trace or trace_lpath then
xml.lshow(result)
end
return result
@@ -1077,14 +1095,17 @@ do
end
end
- function lpath_cached_patterns()
+ function xml.cached_patterns()
return cache
end
- local fallbackreport = (texio and texio.write) or io.write
+-- we run out of locals (limited to 200)
+--
+-- local fallbackreport = (texio and texio.write) or io.write
function xml.lshow(pattern,report)
- report = report or fallbackreport
+-- report = report or fallbackreport
+ report = report or (texio and texio.write) or io.write
local lp = xml.lpath(pattern)
if lp == false then
report(" -: root\n")
@@ -1116,7 +1137,8 @@ do
function xml.xshow(e,...) -- also handy when report is given, use () to isolate first e
local t = { ... }
- local report = (type(t[#t]) == "function" and t[#t]) or fallbackreport
+-- local report = (type(t[#t]) == "function" and t[#t]) or fallbackreport
+ local report = (type(t[#t]) == "function" and t[#t]) or (texio and texio.write) or io.write
if e == nil then
report("<!-- no element -->\n")
elseif type(e) ~= "table" then
@@ -1636,7 +1658,7 @@ do
local rt, dt, dk
traverse(root, lpath(pattern), function(r,d,k) rt, dt, dk = r, d, k return true end)
local ekat = (dt and dt[dk] and dt[dk].at) or (rt and rt.at)
- return (ekat and (ekat[arguments] or ekat[arguments:gsub("^([\"\'])(.*)%1$","%2")])) or ""
+ return (ekat and (ekat[arguments] or ekat[gsub(arguments,"^([\"\'])(.*)%1$","%2")])) or ""
end
function xml.filters.text(root,pattern,arguments) -- ?? why index, tostring slow
local dtk, rt, dt, dk = xml.filters.index(root,pattern,arguments)
@@ -1698,9 +1720,6 @@ do
function xml.filter(root,pattern)
local kind, a, b, c = parser:match(pattern)
---~ if xml.trace_lpath then
---~ print(pattern,kind,a,b,c)
---~ end
if kind == 1 or kind == 3 then
return (filters[b] or default_filter)(root,a,c)
elseif kind == 2 then
@@ -2013,7 +2032,7 @@ do
end
if not name then
if ek.at then
- for a in (attribute or "href"):gmatch("([^|]+)") do
+ for a in gmatch(attribute or "href","([^|]+)") do
name = ek.at[a]
if name then break end
end
@@ -2052,7 +2071,7 @@ do
-- stripped
else
if nolines then
- str = str:gsub("[ \n\r\t]+"," ")
+ str = gsub(str,"[ \n\r\t]+"," ")
end
if str == "" then
-- stripped
@@ -2069,9 +2088,8 @@ do
end)
end
- function xml.rename_space(root, oldspace, newspace) -- fast variant
+ local function rename_space(root, oldspace, newspace) -- fast variant
local ndt = #root.dt
- local rename = xml.rename_space
for i=1,ndt or 0 do
local e = root[i]
if type(e) == "table" then
@@ -2083,12 +2101,14 @@ do
end
local edt = e.dt
if edt then
- rename(edt, oldspace, newspace)
+ rename_space(edt, oldspace, newspace)
end
end
end
end
+ xml.rename_space = rename_space
+
function xml.remap_tag(root, pattern, newtg)
traverse(root, lpath(pattern), function(r,d,k)
d[k].tg = newtg
@@ -2167,10 +2187,12 @@ put them here instead of loading mode modules there then needed.</p>
--ldx]]--
function xml.gsub(t,old,new)
- if t.dt then
- for k,v in ipairs(t.dt) do
+ local dt = t.dt
+ if dt then
+ for k=1,#dt do
+ local v = dt[k]
if type(v) == "string" then
- t.dt[k] = v:gsub(old,new)
+ dt[k] = gsub(v,old,new)
else
xml.gsub(v,old,new)
end
@@ -2195,9 +2217,9 @@ end
--~ xml.escapes = { ['&'] = '&amp;', ['<'] = '&lt;', ['>'] = '&gt;', ['"'] = '&quot;' }
--~ xml.unescapes = { } for k,v in pairs(xml.escapes) do xml.unescapes[v] = k end
---~ function xml.escaped (str) return str:gsub("(.)" , xml.escapes ) end
---~ function xml.unescaped(str) return str:gsub("(&.-;)", xml.unescapes) end
---~ function xml.cleansed (str) return str:gsub("<.->" , '' ) end -- "%b<>"
+--~ function xml.escaped (str) return (gsub(str,"(.)" , xml.escapes )) end
+--~ function xml.unescaped(str) return (gsub(str,"(&.-;)", xml.unescapes)) end
+--~ function xml.cleansed (str) return (gsub(str,"<.->" , '' )) end -- "%b<>"
do
@@ -2229,6 +2251,10 @@ do
local cleansed = Cs(((P("<") * (1-P(">"))^0 * P(">"))/"" + 1)^0)
+ xml.escaped_pattern = escaped
+ xml.unescaped_pattern = unescaped
+ xml.cleansed_pattern = cleansed
+
function xml.escaped (str) return escaped :match(str) end
function xml.unescaped(str) return unescaped:match(str) end
function xml.cleansed (str) return cleansed :match(str) end
@@ -2273,14 +2299,14 @@ do if unicode and unicode.utf8 then
return char(tonumber(s,16))
end
- function utfize(root)
+ local function utfize(root)
local d = root.dt
for k=1,#d do
local dk = d[k]
if type(dk) == "string" then
-- test prevents copying if no match
- if dk:find("&#x.-;") then
- d[k] = dk:gsub("&#x(.-);",toutf)
+ if find(dk,"&#x.-;") then
+ d[k] = gsub(dk,"&#x(.-);",toutf)
end
else
utfize(dk)
@@ -2291,8 +2317,10 @@ do if unicode and unicode.utf8 then
xml.utfize = utfize
local function resolve(e) -- hex encoded always first, just to avoid mkii fallbacks
- if e:find("#x") then
+ if find(e,"^#x") then
return char(tonumber(e:sub(3),16))
+ elseif find(e,"^#") then
+ return char(tonumber(e:sub(2)))
else
local ee = xml.entities[e] -- we cannot shortcut this one (is reloaded)
if ee then
@@ -2310,8 +2338,8 @@ do if unicode and unicode.utf8 then
for k=1,#d do
local dk = d[k]
if type(dk) == "string" then
- if dk:find("&.-;") then
- d[k] = dk:gsub("&(.-);",resolve)
+ if find(dk,"&.-;") then
+ d[k] = gsub(dk,"&(.-);",resolve)
end
else
resolve_entities(dk)
@@ -2323,24 +2351,24 @@ do if unicode and unicode.utf8 then
xml.resolve_entities = resolve_entities
function xml.utfize_text(str)
- if str:find("&#") then
- return (str:gsub("&#x(.-);",toutf))
+ if find(str,"&#") then
+ return (gsub(str,"&#x(.-);",toutf))
else
return str
end
end
function xml.resolve_text_entities(str) -- maybe an lpeg. maybe resolve inline
- if str:find("&") then
- return (str:gsub("&(.-);",resolve))
+ if find(str,"&") then
+ return (gsub(str,"&(.-);",resolve))
else
return str
end
end
function xml.show_text_entities(str)
- if str:find("&") then
- return (str:gsub("&(.-);","[%1]"))
+ if find(str,"&") then
+ return (gsub(str,"&(.-);","[%1]"))
else
return str
end
@@ -2352,7 +2380,7 @@ do if unicode and unicode.utf8 then
local documententities = root.entities
local allentities = xml.entities
if documententities then
- for k, v in pairs(documententities) do
+ for k, v in next, documententities do
allentities[k] = v
end
end
@@ -2386,7 +2414,7 @@ end
--~ </a>
--~ ]])
---~ xml.trace_lpath = true
+--~ xml.settrace("lpath",true)
--~ xml.xshow(xml.first(x,"b[position() > 2 and position() < 5 and text() == 'ok']"))
--~ xml.xshow(xml.first(x,"b[position() > 2 and position() < 5 and text() == upper('ok')]"))
diff --git a/tex/context/base/lang-alt.tex b/tex/context/base/lang-alt.tex
index d59df78bd..e45748ead 100644
--- a/tex/context/base/lang-alt.tex
+++ b/tex/context/base/lang-alt.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Altaic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Altaic Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -37,8 +37,7 @@
\c!rightquote=\upperrightsingleninequote,
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
- \c!date={\v!year,\ ,\v!month,\ ,\v!day},
- \c!state=\v!stop]
+ \c!date={\v!year,\ ,\v!month,\ ,\v!day}]
\installlanguage [turkish] [\s!tr]
diff --git a/tex/context/base/lang-ana.tex b/tex/context/base/lang-ana.tex
index 336be50f2..c108655c4 100644
--- a/tex/context/base/lang-ana.tex
+++ b/tex/context/base/lang-ana.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Anatolian Languages}
+\writestatus{loading}{ConTeXt Language Macros / Anatolian Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -21,6 +21,4 @@
\unprotect
-\protect
-
-\endinput
+\protect \endinput
diff --git a/tex/context/base/lang-ara.tex b/tex/context/base/lang-ara.tex
index 91bd6ae38..3c4d3c522 100644
--- a/tex/context/base/lang-ara.tex
+++ b/tex/context/base/lang-ara.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Arabic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Arabic Languages}
\unprotect
@@ -29,8 +29,7 @@
\c!rightquote=\upperrightsingleninequote,
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
- \c!date={\v!day,\ ,\v!month,{،\ },\v!year},
- \c!state=\v!stop] % elders always preloaded!
+ \c!date={\v!day,\ ,\v!month,{،\ },\v!year}]
\installlanguage [\s!arabic] [\s!ar]
diff --git a/tex/context/base/lang-art.tex b/tex/context/base/lang-art.tex
index 3f857e11e..e8be91630 100644
--- a/tex/context/base/lang-art.tex
+++ b/tex/context/base/lang-art.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Artificial Languages}
+\writestatus{loading}{ConTeXt Language Macros / Artificial Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -23,6 +23,4 @@
\unprotect
-\protect
-
-\endinput
+\protect \endinput
diff --git a/tex/context/base/lang-bal.tex b/tex/context/base/lang-bal.tex
index c4e0f31f7..9b0528a27 100644
--- a/tex/context/base/lang-bal.tex
+++ b/tex/context/base/lang-bal.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Baltic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Baltic Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -23,6 +23,4 @@
\unprotect
-\protect
-
-\endinput
+\protect \endinput
diff --git a/tex/context/base/lang-cel.tex b/tex/context/base/lang-cel.tex
index abbeb10c6..4d93957f1 100644
--- a/tex/context/base/lang-cel.tex
+++ b/tex/context/base/lang-cel.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Celtic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Celtic Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -23,6 +23,4 @@
\unprotect
-\protect
-
-\endinput
+\protect \endinput
diff --git a/tex/context/base/lang-chi.tex b/tex/context/base/lang-chi.tex
index 7458268f7..278e10745 100644
--- a/tex/context/base/lang-chi.tex
+++ b/tex/context/base/lang-chi.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Language Macros / Chinese}
+\writestatus{loading}{ConTeXt Language Macros / Chinese}
%D This module is coded using the \UNICODE\ support built in
%D \CONTEXT. Therefore, \type {\uchar} is used instead of latin
@@ -31,9 +31,7 @@
\c!rightquote=\cnencoding\cnupperrightsinglequote,
\c!leftquotation=\cnencoding\cnupperleftdoublequote,
\c!rightquotation=\cnencoding\cnupperrightdoublequote,
- \c!date={\v!year,\cnyear,\ ,\v!month,\v!day,\cnday},
- \c!state=\v!stop]
-
+ \c!date={\v!year,\cnyear,\ ,\v!month,\v!day,\cnday}]
\setupheadtext [\s!cn] [\v!content={\cnencoding\cnencodedcontents}]
\setupheadtext [\s!cn] [\v!tables={\cnencoding\cnencodedtables}]
diff --git a/tex/context/base/lang-cjk.tex b/tex/context/base/lang-cjk.tex
new file mode 100644
index 000000000..138f6d263
--- /dev/null
+++ b/tex/context/base/lang-cjk.tex
@@ -0,0 +1,328 @@
+%D \module
+%D [ file=lang-chi,
+%D version=2009.03.02,
+%D title=\CONTEXT\ Language Macros,
+%D subtitle=Chinese,
+%D author={Hans Hagen \& Wang Lei},
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Derived from \MKII\ files.
+
+\writestatus{loading}{ConTeXt Language Macros / CJK}
+
+\definesystemconstant {chinese} \definesystemconstant {cn}
+\definesystemconstant {japanese} \definesystemconstant {ja}
+\definesystemconstant {korean} \definesystemconstant {kr}
+
+\unprotect
+
+% Chinese
+
+\installlanguage
+ [\s!cn]
+ [\c!leftsentence=——,
+ \c!rightsentence=——,
+ \c!leftsubsentence=——,
+ \c!rightsubsentence=——,
+ \c!leftquote=‘,
+ \c!rightquote=’,
+ \c!leftquotation=“,
+ \c!rightquotation=”,
+ \c!date={\v!year,年,\ ,\v!month,\v!day,日}]
+
+\setupheadtext [\s!cn] [\v!content=目录]
+\setupheadtext [\s!cn] [\v!tables=表格]
+\setupheadtext [\s!cn] [\v!figures=图形]
+\setupheadtext [\s!cn] [\v!graphics=图]
+\setupheadtext [\s!cn] [\v!intermezzi=퉣]
+\setupheadtext [\s!cn] [\v!index=索引]
+\setupheadtext [\s!cn] [\v!abbreviations=缩略语]
+\setupheadtext [\s!cn] [\v!logos=徽贬]
+\setupheadtext [\s!cn] [\v!units=计量单位]
+
+\setuplabeltext [\s!cn] [\v!table=表]
+\setuplabeltext [\s!cn] [\v!figure=图]
+\setuplabeltext [\s!cn] [\v!intermezzo=퉣]
+\setuplabeltext [\s!cn] [\v!graphic=插图]
+\setuplabeltext [\s!cn] [\v!appendix=附录]
+\setuplabeltext [\s!cn] [\v!part={第,部分}]
+\setuplabeltext [\s!cn] [\v!chapter={第,章}]
+\setuplabeltext [\s!cn] [\v!section={第,节}]
+\setuplabeltext [\s!cn] [\v!line=行]
+\setuplabeltext [\s!cn] [\v!lines=行]
+
+\setuplabeltext [\s!cn] [\v!subsection=]
+\setuplabeltext [\s!cn] [\v!subsubsection=]
+\setuplabeltext [\s!cn] [\v!subsubsubsection=]
+
+\setuplabeltext [\s!cn] [\v!january=一月]
+\setuplabeltext [\s!cn] [\v!february=二月]
+\setuplabeltext [\s!cn] [\v!march=三月]
+\setuplabeltext [\s!cn] [\v!april=四月]
+\setuplabeltext [\s!cn] [\v!may=五月]
+\setuplabeltext [\s!cn] [\v!june=六月]
+\setuplabeltext [\s!cn] [\v!july=七月]
+\setuplabeltext [\s!cn] [\v!august=八月]
+\setuplabeltext [\s!cn] [\v!september=九月]
+\setuplabeltext [\s!cn] [\v!october=十月]
+\setuplabeltext [\s!cn] [\v!november=十一月]
+\setuplabeltext [\s!cn] [\v!december=十二月]
+
+\setuplabeltext [\s!cn] [\v!sunday=星期日]
+\setuplabeltext [\s!cn] [\v!monday=星期一]
+\setuplabeltext [\s!cn] [\v!tuesday=星期二]
+\setuplabeltext [\s!cn] [\v!wednesday=星期三]
+\setuplabeltext [\s!cn] [\v!thursday=星期四]
+\setuplabeltext [\s!cn] [\v!friday=星期五]
+\setuplabeltext [\s!cn] [\v!saturday=星期六]
+
+%D Japanese
+
+\installlanguage
+ [\s!ja]
+ [\c!leftsentence=——,
+ \c!rightsentence=——,
+ \c!leftsubsentence=——,
+ \c!rightsubsentence=——,
+ \c!leftquote=‘,
+ \c!rightquote=’,
+ \c!leftquotation=「,
+ \c!rightquotation=」,
+ \c!date={西暦,\v!year,年,\v!month,月,\v!day,日}]
+
+\setupheadtext [\s!ja] [\v!content=目次]
+\setupheadtext [\s!ja] [\v!tables=机]
+\setupheadtext [\s!ja] [\v!figures=図]
+\setupheadtext [\s!ja] [\v!graphics=グラフ]
+\setupheadtext [\s!ja] [\v!intermezzi=間奏曲]
+\setupheadtext [\s!ja] [\v!index=目次]
+\setupheadtext [\s!ja] [\v!abbreviations=略語]
+\setupheadtext [\s!ja] [\v!logos=理性]
+\setupheadtext [\s!ja] [\v!units=ユニッツ]
+
+\setuplabeltext [\s!ja] [\v!table=表]
+\setuplabeltext [\s!ja] [\v!figure=図]
+\setuplabeltext [\s!ja] [\v!intermezzo=間奏曲]
+\setuplabeltext [\s!ja] [\v!graphic=イラスト]
+\setuplabeltext [\s!ja] [\v!appendix=付録]
+\setuplabeltext [\s!ja] [\v!part={第,パート}]
+\setuplabeltext [\s!ja] [\v!chapter={第,章}]
+\setuplabeltext [\s!ja] [\v!section={第,項}]
+\setuplabeltext [\s!ja] [\v!line=線]
+\setuplabeltext [\s!ja] [\v!lines=線]
+
+\setuplabeltext [\s!ja] [\v!subsection=]
+\setuplabeltext [\s!ja] [\v!subsubsection=]
+\setuplabeltext [\s!ja] [\v!subsubsubsection=]
+
+\setuplabeltext [\s!ja] [\v!january=1]
+\setuplabeltext [\s!ja] [\v!february=2]
+\setuplabeltext [\s!ja] [\v!march=3]
+\setuplabeltext [\s!ja] [\v!april=4]
+\setuplabeltext [\s!ja] [\v!may=5]
+\setuplabeltext [\s!ja] [\v!june=6]
+\setuplabeltext [\s!ja] [\v!july=7]
+\setuplabeltext [\s!ja] [\v!august=8]
+\setuplabeltext [\s!ja] [\v!september=9]
+\setuplabeltext [\s!ja] [\v!october=10]
+\setuplabeltext [\s!ja] [\v!november=11]
+\setuplabeltext [\s!ja] [\v!december=12]
+
+\setuplabeltext [\s!ja] [\v!sunday=月曜日]
+\setuplabeltext [\s!ja] [\v!monday=火曜日]
+\setuplabeltext [\s!ja] [\v!tuesday=水曜日]
+\setuplabeltext [\s!ja] [\v!wednesday=木曜日]
+\setuplabeltext [\s!ja] [\v!thursday=金曜日]
+\setuplabeltext [\s!ja] [\v!friday=土曜日]
+\setuplabeltext [\s!ja] [\v!saturday=日曜日]
+
+%D Korean
+
+% todo
+
+\protect \endinput
+
+cn={
+ ["abbreviations"]="缩略语",
+ ["appendix"]="附录",
+ ["april"]="四月",
+ ["august"]="八月",
+ ["chapter"]="章",
+ ["contents"]="目录",
+ ["day"]="日",
+ ["december"]="十二月",
+ ["febrary"]="二月",
+ ["figure"]="图",
+ ["figures"]="图形",
+ ["friday"]="星期五",
+ ["graphics"]="图",
+ ["illustration"]="插图",
+ ["index"]="索引",
+ ["intermezzo"]="퉣",
+ ["intro"]="第",
+ ["january"]="一月",
+ ["july"]="七月",
+ ["june"]="六月",
+ ["leftsentence"]="——",
+ ["leftsubsentence"]="——",
+ ["line"]="行",
+ ["logos"]="徽贬",
+ ["march"]="三月",
+ ["may"]="五月",
+ ["monday"]="星期一",
+ ["month"]="月",
+ ["november"]="十一月",
+ ["october"]="十月",
+ ["part"]="部分",
+ ["rightsentence"]="——",
+ ["rightsubsentence"]="——",
+ ["saturday"]="星期六",
+ ["section"]="节",
+ ["september"]="九月",
+ ["sunday"]="星期日",
+ ["table"]="表",
+ ["tables"]="表格",
+ ["thursday"]="星期四",
+ ["tuesday"]="星期二",
+ ["units"]="计量单位",
+ ["upperleftdoublequote"]="“",
+ ["upperleftdoublequote-v"]="『",
+ ["upperleftsinglequote"]="‘",
+ ["upperleftsinglequote-v"]="「",
+ ["upperrightdoublequote"]="”",
+ ["upperrightdoublequote-v"]="』",
+ ["upperrightsinglequote"]="’",
+ ["upperrightsinglequote-v"]="」",
+ ["wednesday"]="星期三",
+ ["year"]="年",
+}
+
+ja={
+ ["abbreviations"]="略語",
+ ["abstract"]="概要",
+ ["and"]="、",
+ ["answer"]="答:",
+ ["appendix"]="付録",
+ ["april"]="四月",
+ ["article"]="項目",
+ ["august"]="八月",
+ ["bibliography"]="参考文献",
+ ["book"]="ブック",
+ ["bridgehead"]="項",
+ ["bullet"]="●",
+ ["by"]=":",
+ ["caution"]="注意",
+ ["chapter"]="章",
+ ["christiandate"]="西暦",
+ ["colophon"]="奥付",
+ ["copyright"]="製作著作",
+ ["day"]="日",
+ ["december"]="十二月",
+ ["dedication"]="謝辞",
+ ["edited"]="編者",
+ ["editedby"]="編者:",
+ ["edition"]="編集",
+ ["endquote"]="」",
+ ["equation"]="式",
+ ["example"]="例",
+ ["february"]="二月",
+ ["figure"]="図",
+ ["figures"]="図",
+ ["friday"]="土曜日",
+ ["glossary"]="用語集",
+ ["glosssee"]="参照",
+ ["glossseealso"]="参照",
+ ["graphics"]="グラフ",
+ ["illustration"]="イラスト",
+ ["important"]="重要項目",
+ ["index"]="目次",
+ ["indexsymbols"]="シンボル",
+ ["intermezzo"]="間奏曲",
+ ["intermezzos"]="間奏曲",
+ ["intro"]="第",
+ ["january"]="一月",
+ ["july"]="七月",
+ ["june"]="六月",
+ ["leftsentence"]="——",
+ ["leftsubsentence"]="——",
+ ["line"]="線",
+ ["lines"]="線",
+ ["listofequations"]="式目次",
+ ["listofexamples"]="例目次",
+ ["listoffigures"]="図目次",
+ ["listoftables"]="表目次",
+ ["listofunknown"]="不明目次",
+ ["logos"]="理性",
+ ["march"]="三月",
+ ["may"]="五月",
+ ["monday"]="火曜日",
+ ["month"]="月",
+ ["msgaud"]="対象者",
+ ["msglevel"]="レベル",
+ ["msgorig"]="発信元",
+ ["navhome"]="ホーム",
+ ["navnext"]="次のページ",
+ ["navnextsibling"]="早送り",
+ ["navprev"]="前のページ",
+ ["navprevsibling"]="巻戻し",
+ ["navup"]="上に戻る",
+ ["nestedendquote"]="』",
+ ["nestedstartquote"]="『",
+ ["nonexistantelement"]="要素が存在しません",
+ ["note"]="注意",
+ ["notes"]="注意",
+ ["november"]="十一月",
+ ["october"]="十月",
+ ["pages"]="偧献",
+ ["part"]="パート",
+ ["preface"]="序文",
+ ["procedure"]="手順",
+ ["procedureformal"]="手順",
+ ["productionset"]="プロダクション",
+ ["productionsetformal"]="プロダクション",
+ ["published"]="発行",
+ ["qandadiv"]="問:、答:",
+ ["qandaentry"]="問:",
+ ["question"]="問:",
+ ["reference"]="参照",
+ ["refname"]="名前",
+ ["refsection"]="項",
+ ["refsynopsisdiv"]="概要",
+ ["revhistory"]="改訂履歴",
+ ["revision"]="改訂",
+ ["rightsentence"]="——",
+ ["rightsubsentence"]="——",
+ ["saturday"]="日曜日",
+ ["section"]="項",
+ ["see"]="参照",
+ ["seealso"]="参照",
+ ["separator"]="、",
+ ["september"]="九月",
+ ["set"]="設定",
+ ["setindex"]="目次設定",
+ ["sidebar"]="サイドバー",
+ ["simplesect"]="項",
+ ["singleendquote"]="’",
+ ["singlestartquote"]="‘",
+ ["startquote"]="「",
+ ["step"]="ステップ",
+ ["sunday"]="月曜日",
+ ["table"]="表",
+ ["tablenotes"]="注意",
+ ["tableofcontents"]="目次",
+ ["tables"]="机",
+ ["thursday"]="金曜日",
+ ["tip"]="ティップ",
+ ["tuesday"]="水曜日",
+ ["unexpectedelementname"]="不明な要素名",
+ ["units"]="ユニッツ",
+ ["unsupported"]="サポートしません",
+ ["warning"]="警告",
+ ["wednesday"]="木曜日",
+ ["year"]="年",
+}
diff --git a/tex/context/base/lang-ctx.tex b/tex/context/base/lang-ctx.tex
index 5364c1af6..09f28dda1 100644
--- a/tex/context/base/lang-ctx.tex
+++ b/tex/context/base/lang-ctx.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Language Macros / Generic Patterns}
+\writestatus{loading}{ConTeXt Language Macros / Generic Patterns}
\unprotect
@@ -28,31 +28,26 @@
%D than one font encoding is in use. I can add more defaults here
%D if users let me know what encoding they use.
-\installlanguage [\s!nl] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
-\installlanguage [\s!fr] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
-\installlanguage [\s!de] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
-\installlanguage [\s!it] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
-
-\installlanguage [\s!pt] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
-
-\installlanguage [\s!hr] [\s!mapping=ec,\s!encoding=ec] % no il2, misses cacute characters
-
-\installlanguage [\s!pl] [\s!mapping={pl0,ec,qx},\s!encoding={pl0,ec,qx}] % pl0 may go
-\installlanguage [\s!cs] [\s!mapping={il2,ec},\s!encoding={il2,ec}] % il2 may go
-\installlanguage [\s!sk] [\s!mapping={il2,ec},\s!encoding={il2,ec}] % il2 may go
-\installlanguage [\s!sl] [\s!mapping=ec,\s!encoding=ec] % il2 has gone
-
-\installlanguage [\s!vn] [\s!mapping=t5,\s!encoding=t5]
-
-\installlanguage [\s!ru] [\s!mapping=t2a,\s!encoding=t2a]
+% \installlanguage [\s!nl] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
+% \installlanguage [\s!fr] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
+% \installlanguage [\s!de] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
+% \installlanguage [\s!it] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
+% \installlanguage [\s!pt] [\s!mapping={texnansi,ec},\s!encoding={texnansi,ec}]
+% \installlanguage [\s!hr] [\s!mapping=ec,\s!encoding=ec] % no il2, misses cacute characters
+% \installlanguage [\s!pl] [\s!mapping={pl0,ec,qx},\s!encoding={pl0,ec,qx}] % pl0 may go
+% \installlanguage [\s!cs] [\s!mapping={il2,ec},\s!encoding={il2,ec}] % il2 may go
+% \installlanguage [\s!sk] [\s!mapping={il2,ec},\s!encoding={il2,ec}] % il2 may go
+% \installlanguage [\s!sl] [\s!mapping=ec,\s!encoding=ec] % il2 has gone
+% \installlanguage [\s!vi] [\s!mapping=t5,\s!encoding=t5]
+% \installlanguage [\s!ru] [\s!mapping=t2a,\s!encoding=t2a]
% beware, don't use \setuplanguage here
-\installlanguage[\s!gb][\s!lefthyphenmin=3,\s!righthyphenmin=3] % patterns can only handle this
-\installlanguage[\s!us][\s!lefthyphenmin=2,\s!righthyphenmin=3] % patterns can only handle this
+% \installlanguage[\s!gb][\s!lefthyphenmin=3,\s!righthyphenmin=3] % patterns can only handle this
+% \installlanguage[\s!us][\s!lefthyphenmin=2,\s!righthyphenmin=3] % patterns can only handle this
% greek
-\installlanguage[\s!agr][\s!mapping=\s!agr,\s!encoding=\s!agr]
+% \installlanguage[\s!agr][\s!mapping=\s!agr,\s!encoding=\s!agr]
\protect \endinput
diff --git a/tex/context/base/lang-cyr.tex b/tex/context/base/lang-cyr.tex
index 34b5e78c3..470402bb1 100644
--- a/tex/context/base/lang-cyr.tex
+++ b/tex/context/base/lang-cyr.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Cyrillic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Cyrillic Languages}
%D The cyrillic languages always use a dedicated input regime.
%D Therefore we define the labels using symbolic names.
@@ -37,7 +37,8 @@
\c!leftquotation=\leftguillemot,
\c!rightquotation=\rightguillemot,
\c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping=t2a,
+ \s!encoding=t2a]
\installlanguage
[\s!ua]
@@ -53,11 +54,12 @@
\c!leftquotation=\leftguillemot,
\c!rightquotation=\rightguillemot,
\c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
-
-\installlanguage [russian] [\s!ru]
-\installlanguage [ukrainian] [\s!ua]
+ \s!patterns=\s!uk,
+ \s!mapping=t2a,
+ \s!encoding=t2a]
+\installlanguage [russian] [\s!ru]
+\installlanguage [ukrainian] [\s!ua]
%D Labels and header texts.
diff --git a/tex/context/base/lang-dis.tex b/tex/context/base/lang-dis.tex
index db932d68a..f081bf4a9 100644
--- a/tex/context/base/lang-dis.tex
+++ b/tex/context/base/lang-dis.tex
@@ -15,7 +15,7 @@
%D use more generic pattern files, we decided to isolate these
%D mappings.
-\writestatus{loading}{Context Language Macros / Distribution Patterns}
+\writestatus{loading}{ConTeXt Language Macros / Distribution Patterns}
%D Hyphenation patterns are normally sought in filed named
%D \type {lang-xx.pat}. When present on the system, those
@@ -52,8 +52,8 @@
% \definefilefallback [lang-sk.pat] [skhyphen.tex,skhyph.pat]
% \definefilefallback [lang-deo.pat] [dehypht.tex]
-\definefilesynonym [lang-af.pat] [lang-nl.pat]
-\definefilesynonym [lang-en.pat] [lang-us.pat]
-\definefilesynonym [lang-en.hyp] [lang-us.hyp]
+% \definefilesynonym [lang-af.pat] [lang-nl.pat]
+% \definefilesynonym [lang-en.pat] [lang-us.pat]
+% \definefilesynonym [lang-en.hyp] [lang-us.hyp]
\protect \endinput
diff --git a/tex/context/base/lang-frq.tex b/tex/context/base/lang-frq.tex
index 372813f70..773230e6c 100644
--- a/tex/context/base/lang-frq.tex
+++ b/tex/context/base/lang-frq.tex
@@ -2,7 +2,7 @@
%D [ file=lang-frq,
%D version=2004.01.15,
%D title=\CONTEXT\ Language Macros,
-%D subtitle=Language Frequency Table Support,
+%D subtitle=Frequency Tables,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Language Frequency Table Support}
+\writestatus{loading}{ConTeXt Language Macros / Frequency Tables}
\unprotect
diff --git a/tex/context/base/lang-ger.tex b/tex/context/base/lang-ger.tex
index bdcaa9cb3..b9717ce9a 100644
--- a/tex/context/base/lang-ger.tex
+++ b/tex/context/base/lang-ger.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Germanic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Germanic Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -42,7 +42,8 @@
\c!leftquotation=\lowerleftdoubleninequote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping={texnansi,ec},
+ \s!encoding={texnansi,ec}]
\installlanguage
[\s!en]
@@ -57,11 +58,14 @@
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!month,\ ,\v!day,{,\ },\v!year},
\s!patterns=\s!us,
- \c!state=\v!stop] % elders always preloaded!
+ \s!lefthyphenmin=2,
+ \s!righthyphenmin=3]
\installlanguage
[\s!de]
[\c!spacing=\v!packed,
+ \s!lefthyphenmin=3,
+ \s!righthyphenmin=3,
\c!leftsentence={\hbox{--~}},
\c!rightsentence={\hbox{~--}},
\c!leftsubsentence={--},
@@ -71,7 +75,8 @@
\c!leftquotation=\lowerleftdoubleninequote,
\c!rightquotation=\upperrightdoublesixquote,
\c!date={\v!day,{.},\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping={texnansi,ec},
+ \s!encoding={texnansi,ec}]
\installlanguage
[\s!da]
@@ -84,8 +89,7 @@
\c!rightquote=\upperrightsinglesixquote,
\c!leftquotation=\lowerleftdoubleninequote,
\c!rightquotation=\upperrightdoublesixquote,
- \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year}]
\installlanguage
[\s!sv]
@@ -98,8 +102,7 @@
\c!rightquote=\upperrightsingleninequote,
\c!leftquotation=\upperrightdoubleninequote,
\c!rightquotation=\upperrightdoubleninequote,
- \c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \c!date={\v!day,\ ,\v!month,\ ,\v!year}]
\installlanguage
[\s!af]
@@ -113,7 +116,7 @@
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!year,\ ,\v!month,\ ,\v!day},
- \c!state=\v!stop]
+ \s!patterns=\s!nl]
\installlanguage
[\s!nb]
@@ -180,14 +183,12 @@
\installlanguage % old german
[deo]
[\c!spacing=\v!packed,
- \c!default=\s!de,
- \c!state=\v!stop]
+ \c!default=\s!de]
\installlanguage
[de-de]
[\c!spacing=\v!packed,
- \c!default=\s!de,
- \c!state=\v!stop]
+ \c!default=\s!de]
\installlanguage
[de-at]
@@ -196,14 +197,12 @@
\c!leftquote=\leftguillemot,
\c!rightquote=\rightguillemot,
\c!leftquotation=\leftguillemot,
- \c!rightquotation=\rightguillemot,
- \c!state=\v!stop]
+ \c!rightquotation=\rightguillemot]
\installlanguage
[de-ch]
[\c!spacing=\v!packed,
- \c!default=\s!de,
- \c!state=\v!stop]
+ \c!default=\s!de]
%D And some alternative (but very real) english patterns:
@@ -211,24 +210,23 @@
[en-gb]
[\c!default=\s!en,
\s!patterns=\s!gb,
- \c!state=\v!stop]
+ \s!lefthyphenmin=3,
+ \s!righthyphenmin=3]
\installlanguage
[en-us]
- [\c!default=\s!en,
- %\s!patterns=\s!us,
- \c!state=\v!stop]
+ [\c!default=\s!en]
\installlanguage [\s!uk] [en-gb]
\installlanguage [\s!us] [en-us]
%D For compatibility reasons we also define:
-\installlanguage [du] [\s!de] % old times context
+%installlanguage [du] [\s!de] % old times context
%installlanguage [sp] [\s!es] % old times context /lang-ita
\installlanguage [usenglish] [en-us]
-\installlanguage [ukenglish] [en-uk]
+\installlanguage [ukenglish] [en-gb]
\installlanguage [english] [en-us]
\installlanguage [dutch] [\s!nl]
\installlanguage [german] [\s!de]
diff --git a/tex/context/base/lang-grk.tex b/tex/context/base/lang-grk.tex
index 13cebb207..e4ba781eb 100644
--- a/tex/context/base/lang-grk.tex
+++ b/tex/context/base/lang-grk.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Greek Language}
+\writestatus{loading}{ConTeXt Language Macros / Greek}
%D The framework of this module is set up by Hans Hagen while
%D all the translations have been done by Apostolos Syropoulos
@@ -29,8 +29,7 @@
\c!rightquote=\greekrightquot,
\c!leftquotation=\greekleftquot,
\c!rightquotation=\greekrightquot,
- \c!date={\v!day\ \v!month\ \v!year},
- \c!state=\v!stop]
+ \c!date={\v!day\ \v!month\ \v!year}]
\installlanguage [greek] [\s!gr]
@@ -86,7 +85,9 @@
\installlanguage
[\s!agr]
[\s!default=\s!gr,
- \c!state=\v!stop]
+ \s!patterns=\s!agr,
+ \s!mapping=\s!agr,
+ \s!encoding=\s!agr]
\installlanguage [ancientgreek] [\s!agr]
diff --git a/tex/context/base/lang-ind.tex b/tex/context/base/lang-ind.tex
index f9bbad0d7..9b6e5ff1d 100644
--- a/tex/context/base/lang-ind.tex
+++ b/tex/context/base/lang-ind.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Indo-Iranian Languages}
+\writestatus{loading}{ConTeXt Language Macros / Indo-Iranian Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua
index e9e9af1b6..e188ad36c 100644
--- a/tex/context/base/lang-ini.lua
+++ b/tex/context/base/lang-ini.lua
@@ -6,6 +6,13 @@ if not modules then modules = { } end modules ['lang-ini'] = {
license = "see context related readme files"
}
+-- needs a cleanup (share locals)
+
+local utf = unicode.utf8
+
+local find, lower, format, utfchar = string.find, string.lower, string.format, utf.char
+local concat = table.concat
+
if lang.use_new then lang.use_new(true) end
languages = languages or {}
@@ -13,6 +20,8 @@ languages.version = 1.009
languages.hyphenation = languages.hyphenation or { }
languages.hyphenation.data = languages.hyphenation.data or { }
+local langdata = languages.hyphenation.data
+
-- 002D : hyphen-minus (ascii)
-- 2010 : hyphen
-- 2011 : nonbreakable hyphen
@@ -26,7 +35,7 @@ languages.hyphenation.data = languages.hyphenation.data or { }
-- we can consider hiding data (faster access too)
--~ local function filter(filename,what)
---~ local data = io.loaddata(input.find_file(filename))
+--~ local data = io.loaddata(resolvers.find_file(filename))
--~ local data = data:match(string.format("\\%s%%s*(%%b{})",what or "patterns"))
--~ return data:match("{%s*(.-)%s*}") or ""
--~ end
@@ -47,29 +56,29 @@ local command = lpeg.P("\\patterns")
local parser = (1-command)^0 * command * content
local function filterpatterns(filename)
- if filename:find("%.rpl") then
- return io.loaddata(input.find_file(filename)) or ""
+ if find(filename,"%.rpl") then
+ return io.loaddata(resolvers.find_file(filename)) or ""
else
- return parser:match(io.loaddata(input.find_file(filename)) or "")
+ return parser:match(io.loaddata(resolvers.find_file(filename)) or "")
end
end
-local command = lpeg.P("\\hyphenation")
-local parser = (1-command)^0 * command * content
+local command = lpeg.P("\\hyphenation")
+local parser = (1-command)^0 * command * content
local function filterexceptions(filename)
- if filename:find("%.rhl") then
- return io.loaddata(input.find_file(filename)) or ""
+ if find(filename,"%.rhl") then
+ return io.loaddata(resolvers.find_file(filename)) or ""
else
- return parser:match(io.loaddata(input.find_file(filename)) or {}) -- "" ?
+ return parser:match(io.loaddata(resolvers.find_file(filename)) or {}) -- "" ?
end
end
local function record(tag)
- local data = languages.hyphenation.data[tag]
+ local data = langdata[tag]
if not data then
data = lang.new()
- languages.hyphenation.data[tag] = data or 0
+ langdata[tag] = data or 0
end
return data
end
@@ -82,31 +91,31 @@ function languages.hyphenation.define(tag)
end
function languages.hyphenation.number(tag)
- local d = languages.hyphenation.data[tag]
+ local d = langdata[tag]
return (d and d:id()) or 0
end
-function languages.hyphenation.load(tag, filename, filter, target)
- input.starttiming(languages)
+local function loadthem(tag, filename, filter, target)
+ statistics.starttiming(languages)
local data = record(tag)
- filename = (filename and filename ~= "" and input.find_file(filename)) or ""
+ filename = (filename and filename ~= "" and resolvers.find_file(filename)) or ""
local ok = filename ~= ""
if ok then
lang[target](data,filterpatterns(filename))
else
lang[target](data,"")
end
- languages.hyphenation.data[tag] = data
- input.stoptiming(languages)
+ langdata[tag] = data
+ statistics.stoptiming(languages)
return ok
end
function languages.hyphenation.loadpatterns(tag, patterns)
- return languages.hyphenation.load(tag, patterns, filterpatterns, "patterns")
+ return loadthem(tag, patterns, filterpatterns, "patterns")
end
function languages.hyphenation.loadexceptions(tag, exceptions)
- return languages.hyphenation.load(tag, patterns, filterexceptions, "hyphenation")
+ return loadthem(tag, patterns, filterexceptions, "hyphenation")
end
function languages.hyphenation.exceptions(tag, ...)
@@ -130,16 +139,17 @@ function languages.hyphenation.righthyphenmin(tag, value)
end
function languages.hyphenation.n()
- return table.count(languages.hyphenation.data)
+ return table.count(langdata)
end
-- we can speed this one up with locals if needed
local function tolang(what)
- if type(what) == "number" then
- return languages.hyphenation.data[languages.numbers[what]]
- elseif type(what) == "string" then
- return languages.hyphenation.data[what]
+ local kind = type(what)
+ if kind == "number" then
+ return langdata[languages.numbers[what]]
+ elseif kind == "string" then
+ return langdata[what]
else
return what
end
@@ -158,15 +168,15 @@ languages.registered = languages.registered or { }
languages.associated = languages.associated or { }
languages.numbers = languages.numbers or { }
-input.storage.register(false,"languages/registered",languages.registered,"languages.registered")
-input.storage.register(false,"languages/associated",languages.associated,"languages.associated")
+storage.register("languages/registered",languages.registered,"languages.registered")
+storage.register("languages/associated",languages.associated,"languages.associated")
function languages.register(tag,parent,patterns,exceptions)
parent = parent or tag
languages.registered[tag] = {
parent = parent,
- patterns = patterns or string.format("lang-%s.pat",parent),
- exceptions = exceptions or string.format("lang-%s.hyp",parent),
+ patterns = patterns or format("lang-%s.pat",parent),
+ exceptions = exceptions or format("lang-%s.hyp",parent),
loaded = false,
number = 0,
}
@@ -190,7 +200,7 @@ end
function languages.loadable(tag)
local l = languages.registered[tag]
- if l and l.patterns and input.find_file(patterns) then
+ if l and l.patterns and resolvers.find_file(patterns) then
return true
else
return false
@@ -237,10 +247,10 @@ function languages.hyphenation.loadwords(tag, filename)
local id = languages.hyphenation.number(tag)
if id > 0 then
local l = lang.new(id) or 0
- input.starttiming(languages)
+ statistics.starttiming(languages)
local data = io.loaddata(filename) or ""
l:hyphenation(data)
- input.stoptiming(languages)
+ statistics.stoptiming(languages)
end
end
@@ -257,10 +267,10 @@ function languages.logger.report()
if l.loaded then
local p = (l.patterns and "pat") or '-'
local e = (l.exceptions and "exc") or '-'
- result[#result+1] = string.format("%s:%s:%s:%s:%s", tag, l.parent, p, e, l.number)
+ result[#result+1] = format("%s:%s:%s:%s:%s", tag, l.parent, p, e, l.number)
end
end
- return (#result > 0 and table.concat(result," ")) or "none"
+ return (#result > 0 and concat(result," ")) or "none"
end
languages.words = languages.words or {}
@@ -283,15 +293,15 @@ do
local word = lpeg.Cs((markup/"" + disc/"" + (1-spacing))^1)
function languages.words.load(tag, filename)
- local filename = input.find_file(filename,'other text file') or ""
+ local filename = resolvers.find_file(filename,'other text file') or ""
if filename ~= "" then
- input.starttiming(languages)
+ statistics.starttiming(languages)
local data = io.loaddata(filename) or ""
local words = languages.words.data[tag] or {}
parser = (spacing + word/function(s) words[s] = true end)^0
parser:match(data)
languages.words.data[tag] = words
- input.stoptiming(languages)
+ statistics.stoptiming(languages)
end
end
@@ -301,7 +311,7 @@ function languages.words.found(id, str)
local tag = languages.numbers[id]
if tag then
local data = languages.words.data[tag]
- return data and (data[str] or data[str:lower()])
+ return data and (data[str] or data[lower(str)])
else
return false
end
@@ -314,11 +324,10 @@ do
local glyph, disc, kern = node.id('glyph'), node.id('disc'), node.id('kern')
- local bynode = node.traverse
+ local bynode = node.traverse
+ local chardata = characters.data
local function mark_words(head,found) -- can be optimized
- local cd = characters.data
- local uc = utf.char
local current, start, str, language, n = head, nil, "", nil, 0
local function action()
if #str > 0 then
@@ -347,25 +356,25 @@ do
action()
language = a
end
- if current.subtype > 0 then
+ local components = current.components
+ if components then
start = start or current
n = n + 1
- for g in bynode(current.components) do
- str = str .. uc(g.char)
+ for g in bynode(components) do
+ str = str .. utfchar(g.char)
end
else
local code = current.char
- if cd[code].uccode or cd[code].lccode then
+ if chardata[code].uccode or chardata[code].lccode then
start = start or current
n = n + 1
- str = str .. uc(code)
- else
- if start then
- action()
- end
+ str = str .. utfchar(code)
+ elseif start then
+ action()
end
end
elseif id == disc then
+ if n > 0 then n = n + 1 end
-- ok
elseif id == kern and current.subtype == 0 and start then
-- ok
@@ -383,18 +392,20 @@ do
languages.words.methods = { }
languages.words.method = 1
+ local lw = languages.words
+
languages.words.methods[1] = function(head, attribute, yes, nop)
local set = node.set_attribute
local unset = node.unset_attribute
- local wrong, right = false, false
- if nop then wrong = function(n) set(n,attribute,nop) end end
+ local right, wrong = false, false
if yes then right = function(n) set(n,attribute,yes) end end
+ if nop then wrong = function(n) set(n,attribute,nop) end end
for n in node.traverse(head) do
unset(n,attribute) -- hm
end
local found, done = languages.words.found, false
mark_words(head, function(language,str)
- if #str < languages.words.threshold then
+ if #str < lw.threshold then
return false
elseif found(language,str) then
done = true
@@ -407,11 +418,10 @@ do
return head, done
end
- local lw = languages.words
+ local color = attributes.private('color')
function languages.words.check(head)
if lw.enable and head.next then
- local color = attributes.numbers['color']
local colors = lw.colors
local alc = attributes.list[color]
return lw.methods[lw.method](head, color, alc[colors.known], alc[colors.unknown])
@@ -443,3 +453,16 @@ languages.associate('uk','latn','eng')
languages.associate('nl','latn','nld')
languages.associate('de','latn','deu')
languages.associate('fr','latn','fra')
+
+statistics.register("loaded patterns", function()
+ local result = languages.logger.report()
+ if result ~= "none" then
+ return result
+ end
+end)
+
+statistics.register("language load time", function()
+ if statistics.elapsedindeed(languages) then
+ return format("%s seconds, n=%s", statistics.elapsedtime(languages), languages.hyphenation.n())
+ end
+end)
diff --git a/tex/context/base/lang-ini.mkii b/tex/context/base/lang-ini.mkii
index 46b9f51ce..e5759bc84 100644
--- a/tex/context/base/lang-ini.mkii
+++ b/tex/context/base/lang-ini.mkii
@@ -11,13 +11,159 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+%D This module needs a further cleanup (real split between ii/iv).
+
+%D This module implements the (for the moment still simple)
+%D multi||language support of \CONTEXT, which should not be
+%D confused with the multi||lingual interface. This support
+%D will be extended when needed.
+
+\writestatus{loading}{ConTeXt Language Macros / Initialization}
+
\unprotect
+\ifx\nonfrenchspacing\undefined \let\nonfrenchspacing\relax \fi
+\ifx\frenchspacing \undefined \let\frenchspacing \relax \fi
+
+%D When loading hyphenation patterns, \TEX\ assign a number to
+%D each loaded table, starting with~0. Switching to a specific
+%D table is done by assigning the relevant number to the
+%D predefined \COUNTER\ \type{\language}.
+
+%D We keep track of the last loaded patterns by means of a
+%D pseudo \COUNTER. This just one of those situations in which
+%D we don't want to spent a real one. Language zero has no
+%D patterns, first of all because I like to start numbering
+%D at one. It may come in handy for special purposes as well.
+
+\normallanguage\zerocount \def\loadedlanguage{1}
+
+%D \macros
+%D {currentlanguage, setupcurrentlanguage}
+%D
+%D Instead of numbers,we are going to use symbolic names for
+%D the languages. The current langage is saved in the macro
+%D \type {\currentlanguage}. The setup macro is mainly used
+%D for cosmetic purposes.
+%D
+%D \starttyping
+%D \dorecurse{3}
+%D {\language[nl]
+%D \startmode[*en] english \stopmode
+%D \startmode[*nl] dutch \stopmode
+%D \language[en]
+%D \startmode[*en] english \stopmode
+%D \startmode[*nl] dutch \stopmode}
+%D \stoptyping
+
+\let\currentlanguage \empty
+\let\currentmainlanguage\empty
+
+\def\setupcurrentlanguage[#1]{\setcurrentlanguage\currentmainlanguage{#1}}
+
+\def\setcurrentlanguage#1#2% sets modes: **id (currentmain) *id (current)
+ {\doifsomething{#1}
+ {\ifx\currentmainlanguage\empty\else\resetsystemmode{\systemmodeprefix\currentmainlanguage}\fi
+ \edef\currentmainlanguage{#1}%
+ \setsystemmode{\systemmodeprefix\currentmainlanguage}}%
+ \doifsomething{#2}
+ {\ifx\currentlanguage\empty\else\resetsystemmode\currentlanguage\fi
+ \edef\currentlanguage{#2}%
+ \setsystemmode\currentlanguage}}
+
+%D The internal macros will be defined later.
+
+%D \macros
+%D {installlanguage}
+%D
+%D Hyphenation patterns can only be loaded when the format file
+%D is prepared. The next macro takes care of this loading. A
+%D language is specified with
+%D
+%D \showsetup{installlanguage}
+%D
+%D When \type {state} equals \type {start}, both patterns
+%D and additional hyphenation specifications are loaded. These
+%D files are seached for on the system path and are to be
+%D named:
+%D
+%D \starttyping
+%D \f!languageprefix-identifier.\f!patternsextension
+%D \f!languageprefix-identifier.\f!hyhensextension
+%D \stoptyping
+%D
+%D The \type{spacing} variable specifies how the spaces after
+%D punctuation has to be handled. English is by tradition more
+%D tolerant to inter||sentence spacing than other languages.
+%D
+%D This macro also defines \type {\identifier} as a shortcut
+%D switch to the language. Furthermore the command defined as
+%D being language specific, are executed. With
+%D \type {default} we can default to another language
+%D (patterns) at format generation time. This default language
+%D is overruled when the appropriate patterns are loaded (some
+%D implementations support run time addition of patterns to a
+%D preloaded format).
+
+\def\dodoinstalllanguage#1#2% #2 added
+ {\doifundefined{#1}{\setvalue{#1}{\complexlanguage[#2]}}%
+ \expanded{\noexpand\uppercase{\noexpand\edef\noexpand\ascii{#1}}}%
+ \doifundefined\ascii{\setvalue\ascii{\complexlanguage[#2]}}}
+
+%D \macros
+%D {preloadlanguages}
+%D
+%D We first try to load the files defined as file synonym
+%D for \type {lang-*.pat} and \type {lang-*.hyp}. After that we
+%D fall back on those files. The macro \type {\preloadpatterns}
+%D reports which patterns are loaded and what hyphenmin
+%D values are set.
+
+\let\installedlanguages\empty
+
+\def\doiflanguageelse#1{\doifdefinedelse{\??la#1\c!state}}
+
+\def\doloadlanguagefiles#1%
+ {\doifelsevalue{\??la#1\c!state}\v!start
+ {\edef\languagesuffix{\specificlanguageparameter{#1}\s!patterns}%
+ \ifx\languagesuffix\empty
+ \edef\languagesuffix{\defaultlanguage{#1}}%
+ \else\ifx\languagesuffix\relax
+ \edef\languagesuffix{\defaultlanguage{#1}}%
+ \fi\fi
+ \ifx\languagesuffix\empty
+ \edef\languagesuffix{#1}%
+ \fi
+ \doifundefinedelse{\??la\??la:\currentencoding:\currentmapping:\languagesuffix}
+ {\doloadpatterns{#1}\languagesuffix}
+ {\bgroup
+ \edef\loadedlanguage{\getvalue{\??la\??la:\currentencoding:\currentmapping:\languagesuffix}}%
+ %\showmessage\m!linguals1{\languagesuffix,#1,\loadedlanguage,*,*}%
+ %\showmessage\m!linguals3{\languagesuffix,#1,\loadedlanguage,*,*}%
+ \egroup}}
+ {\showmessage\m!linguals5{#1}}}
+
+\def\doinstalllanguage[#1][#2]%
+ {\doifassignmentelse{#2}
+ {\doiflanguageelse{#1}
+ {\getparameters[\??la#1][#2]}
+ {\setvalue{\l!prefix!#1}{#1}%
+ \addtocommalist{#1}\installedlanguages
+ \dodoinstalllanguage{#1}{#1}%
+ \getparameters[\??la#1][\c!state=\v!start,#2]}%
+ \doloadlanguagefiles{#1}}
+ {\setvalue{\l!prefix!#1}{#2}%
+ \getparameters[\??la#1][\s!default=#2]%
+ \dodoinstalllanguage{#1}{#2}}}
+
+\def\reallanguagetag#1%
+ {\ifcsname\l!prefix!#1\endcsname\csname\l!prefix!#1\endcsname\else#1\fi}
+
\let\preloadedpatterns\empty
\let\preloadedpmessage\empty
\def\doshowpatterns#1#2#3#4% language number encoding mapping
- {#1->#3:#4->#2->\xxlanguageparameter{#1}\s!lefthyphenmin:\xxlanguageparameter{#1}\s!righthyphenmin\space}
+ {#1->#3:#4->#2->\specificlanguageparameter{#1}\s!lefthyphenmin:\specificlanguageparameter{#1}\s!righthyphenmin\space}
\def\preloadlanguages
{\doifsomething\preloadedpmessage{\showmessage\m!linguals{10}\preloadedpmessage}}
@@ -27,16 +173,33 @@
\processcommacommand[\installedlanguages]\preloadallpatterns
\global\let\preloadallpatterns\relax}
-\fetchruntimecommand \showpatterns {\f!languageprefix\s!run}
+% ^^ \language[#1] gave unwanted side effect of loading language specifics
+
+\def\installlanguage
+ {\dodoubleargument\doinstalllanguage}
+
+%D When the second argument is a language identifier, a
+%D synonym is created. This feature is present because we
+%D used dutch mnemonics in the dutch version, but nowadays
+%D conform a standard.
+
+\let \patternencoding \s!default
+\let \patternmapping \s!default
-\def\mkdoloadpatterns#1#2%
- {\expanded{\getcommacommandsize[\getvalue{\??la#2\s!encoding}]}%
+\def\doifpatternselse#1%
+ {\expanded{\doifinsetelse{#1}{\preloadedpatterns}}}
+
+\def\doloadpatterns#1#2%
+ {\edef\askedlanguageencoding{\specificlanguageparameter{#1}\s!encoding}%
+ \edef\askedlanguagemapping {\specificlanguageparameter{#1}\s!mapping}%
+ \expanded{\getcommacommandsize[\askedlanguageencoding]}%
+ % slightly faster: \let\unicodechar\utfunihashglyph
\ifnum\commalistsize>0
- %\message{[nofpatterns #2: \commalistsize/\getvalue{\??la#2\s!encoding}]}%
+ %\message{[nofpatterns #2: \commalistsize/\askedlanguageencoding]}%
\dorecurse\commalistsize
- {\expanded{\getfromcommacommand[\getvalue{\??la#2\s!encoding}][\recurselevel]}%
+ {\expanded{\getfromcommacommand[\askedlanguageencoding][\recurselevel]}%
\let\patternencoding\commalistelement
- \expanded{\getfromcommacommand[\getvalue{\??la#2\s!mapping }][\recurselevel]}%
+ \expanded{\getfromcommacommand[\askedlanguagemapping][\recurselevel]}%
\let\patternmapping \commalistelement
%\message{[patterns: #1/#2/\patternencoding/\patternmapping]}%
\dodoloadpatterns{#1}{#2}\patternencoding\patternmapping}%
@@ -45,14 +208,14 @@
\dodoloadpatterns{#1}{#2}{}{}%
\fi}
-\beginXETEX
+\ifnum\texengine=\xetexengine
-\def\mkdoloadpatterns#1#2%
- {\letvalue{\??la#2\s!encoding}\empty
- \letvalue{\??la#2\s!mapping }\empty
- \dodoloadpatterns{#1}{#2}{}{}}
+ \def\doloadpatterns#1#2%
+ {%\letvalue{\??la#2\s!encoding}\empty
+ %\letvalue{\??la#2\s!mapping }\empty
+ \dodoloadpatterns{#1}{#2}{}{}}
-\endXETEX
+\fi
\def\setuphyppatencoding
{\pathypsettings
@@ -102,6 +265,8 @@
\fi
\egroup}
+\fetchruntimecommand \showpatterns {\f!languageprefix\s!run}
+
%D Since we can only load patterns in ini\TeX, we nil the
%D loading before dumping (which saves a bit of memory, but
%D strangely enough not in the format).
@@ -111,30 +276,130 @@
\globallet\dodoloadpatterns\gobblefourarguments
\to \everydump
-\def\mkdoifpatternselse#1%
- {\expanded{\doifinsetelse{#1}{\preloadedpatterns}}}
+%D \macros
+%D {setuplanguage}
+%D
+%D Quick and dirty, but useful:
+%D
+%D \showsetup{setuplanguage}
+%D
+%D Beware, this command can only be used when a language is installed.
-\def\mkloadlanguagefiles#1%
- {\doifelsevalue{\??la#1\c!state}\v!start
- {\doifelsevaluenothing{\??la#1\s!patterns}
- {\edef\languagesuffix{#1}}
- {\edef\languagesuffix{\getvalue{\??la#1\s!patterns}}}%
- \doifundefinedelse{\??la\??la:\currentencoding:\currentmapping:\languagesuffix}
- {\mkdoloadpatterns{#1}\languagesuffix}
- {\bgroup
- \edef\loadedlanguage{\getvalue{\??la\??la:\currentencoding:\currentmapping:\languagesuffix}}%
- \showmessage\m!linguals1{\languagesuffix,#1,\loadedlanguage,*,*}%
- \showmessage\m!linguals3{\languagesuffix,#1,\loadedlanguage,*,*}%
- \egroup}}
- {\showmessage\m!linguals5{#1}}}
+\unprotected \def\setuplanguage
+ {\dodoubleempty\dosetuplanguage}
+
+\def\dosetuplanguage[#1][#2]% handy patch for testing
+ {\ifsecondargument
+ \getparameters[\??la#1][#2]%
+ \doif{#1}\currentlanguage\docomplexlanguage
+ \else
+ \getparameters[\??la\currentlanguage][#1]%
+ \docomplexlanguage
+ \fi}
+
+\setuplanguage
+ [\s!default]
+ [\s!lefthyphenmin=2,
+ \s!righthyphenmin=2,
+ \s!patterns=,
+ \c!spacing=\v!packed,
+ \s!encoding=,
+ \s!mapping=,
+ \c!lefthyphen=,
+ \c!righthyphen=-,
+ \c!hyphen=-,
+ \c!midsentence=---,
+ \c!leftsentence=---,
+ \c!rightsentence=---,
+ \c!leftsubsentence=---,
+ \c!rightsubsentence=---,
+ \c!leftquote=\upperleftsinglesixquote,
+ \c!rightquote=\upperrightsingleninequote,
+ \c!leftquotation=\upperleftdoublesixquote,
+ \c!rightquotation=\upperrightdoubleninequote,
+ \c!leftspeech=\languageparameter\c!leftquotation,
+ \c!middlespeech=,
+ \c!rightspeech=\languageparameter\c!rightquotation,
+ \c!limittext=\unknown,
+ \c!date={\v!year,\ ,\v!month,\ ,\v!day},
+ \c!text=Ag]
+
+% rather new, split and per language
+
+\setuplanguage
+ [\s!default]
+ [\c!compoundhyphen=\compoundhyphen,
+ \c!leftcompoundhyphen=\compoundhyphen,
+ \c!rightcompoundhyphen=]
-\def\mksetnormallanguage#1#2% current default
+%D The values \type {leftsentence} and \type
+%D {rightsentence} can be (and are) used to implement
+%D automatic subsentence boundary glyphs, like in {\fr
+%D |<|french guillemots|>|} or {\de |<|german guillemots|>|} or
+%D {\nl |<|dutch dashes|>|} like situations. Furthermore \type
+%D {leftquotation} and \type {leftquote} come into view
+%D \quotation {when we quote} or \quote {quote} something.
+
+%D \macros
+%D {currentdatespecification}
+%D
+%D Just to make things easy we can ask for the current date
+%D specification by saying:
+
+\def\currentdatespecification{\languageparameter\c!date}
+
+%D This command is not meant for users.
+
+%D Carefull reading of these macros shows that it's legal to
+%D say
+%D
+%D \starttyping
+%D \installlanguage [du] [de]
+%D \stoptyping
+
+%D \macros
+%D {language,mainlanguage}
+%D
+%D Switching to another language (actually another hyphenation
+%D pattern) is done with:
+%D
+%D \starttyping
+%D \language[identifier]
+%D \stoptyping
+%D
+%D or with \type{\identifier}. Just to be compatible with
+%D \PLAIN\ \TEX, we still support the original meaning, so
+%D
+%D \starttyping
+%D \language=1
+%D \stoptyping
+%D
+%D is a valid operation, where the relation between number
+%D and language depends on the order in installing languages.
+%D
+%D \showsetup{language}
+%D \showsetup{mainlanguage}
+%D
+%D Both commands take a predefined language identifier as
+%D argument. We can use \type{\mainlanguage[identifier]} for
+%D setting the (indeed) main language. This is the language
+%D used for translating labels like {\em figure} and {\em
+%D table}. The main language defaults to the current language.
+%D
+%D We take care of local as well as standardized language
+%D switching (fr and fa, de and du, but nl and nl).
+
+\ifx\synchronizepatterns \undefined \let\synchronizepatterns\relax \fi
+\ifx\synchronizepatternswithfont\undefined \def\synchronizepatternswithfont{\synchronizepatterns} \fi
+
+\def\setnormallanguage#1#2% current default
{% called quite often, so we use \csname
% \def\synchronizepatterns{\setnormallanguage
% {\csname\??la\currentlanguage\s!patterns\endcsname}}% called often
% of even better pre-expand in an ugly way:
- \@EA\def\@EA\synchronizepatterns\@EA{\@EA\dosetnormallanguage
- \csname\??la\currentlanguage\s!patterns\endcsname}%
+% \@EA\def\@EA\synchronizepatterns\@EA{\@EA\dosetnormallanguage
+% \csname\??la\currentlanguage\s!patterns\endcsname}%
+\edef\synchronizepatterns{\noexpand\dosetnormallanguage{\languageparameter\s!patterns}}%
\donefalse
\synchronizepatterns
\ifdone\else
@@ -142,8 +407,9 @@
\synchronizepatterns
\ifdone\else
\ifx\currentdefaultlanguage\empty\else
- \@EA\def\@EA\synchronizepatterns\@EA{\@EA\dosetnormallanguage
- \csname\??la\currentdefaultlanguage\s!patterns\endcsname}%
+% \@EA\def\@EA\synchronizepatterns\@EA{\@EA\dosetnormallanguage
+% \csname\??la\currentdefaultlanguage\s!patterns\endcsname}%
+\edef\synchronizepatterns{\noexpand\dosetnormallanguage{\specificlanguageparameter\currentdefaultlanguage\s!patterns}}%
\synchronizepatterns
\ifdone\else
\dosetnormallanguage\currentdefaultlanguage
@@ -153,11 +419,11 @@
\fi
\fi}
-\def\dosetnormallanguage#1% #1 == \cs
- {\dodosetnormallanguage{:\currentencoding:\currentmapping:}#1{%
- \dodosetnormallanguage{:\currentencoding:\s!default :}#1{%
- \dodosetnormallanguage{:\s!default :\currentmapping:}#1{%
- \dodosetnormallanguage{:\s!default :\s!default :}#1\empty}}}}
+\def\dosetnormallanguage#1% #1 == \cs (no longer)
+ {\dodosetnormallanguage{:\currentencoding:\currentmapping:}{#1}{%
+ \dodosetnormallanguage{:\currentencoding:\s!default :}{#1}{%
+ \dodosetnormallanguage{:\s!default :\currentmapping:}{#1}{%
+ \dodosetnormallanguage{:\s!default :\s!default :}{#1}\empty}}}}
\def\dodosetnormallanguage#1#2%
{\ifcsname\??la\??la#1#2\endcsname
@@ -174,11 +440,251 @@
\@EA\firstofoneargument
\fi}
-\beginXETEX
+\newevery \everylanguage \relax
+
+\def\disablelanguagespecifics
+ {\ignorecompoundcharacter}
+
+\def\sethyphenationvariables
+ {\lefthyphenmin 0\languageparameter\s!lefthyphenmin \relax
+ \righthyphenmin0\languageparameter\s!righthyphenmin\relax
+ \lefthyphenmin \numexpr\lefthyphenmin +\hyphenminoffset\relax
+ \righthyphenmin\numexpr\righthyphenmin+\hyphenminoffset\relax}
+
+\def\docomplexlanguage% assumes that \currentlanguage is set
+ {\edef\currentdefaultlanguage{\defaultlanguage\currentlanguage}%
+ \setnormallanguage\currentlanguage\currentdefaultlanguage
+ \the\everylanguage
+ \enablelanguagespecifics[\currentlanguage]%
+ \sethyphenationvariables
+ \relax
+ % will be definable and move to core-spa !
+ \doifelse{\languageparameter\c!spacing}\v!broad\nonfrenchspacing\frenchspacing}
+
+\ifx\enablelanguagespecifics\undefined \def\enablelanguagespecifics[#1]{} \fi
+
+% The following may be a solution for the fact that one cannot
+% change catcodes of characters like : and ; inside an environment.
+
+\appendtoks
+ \enablelanguagespecifics[\currentlanguage]%
+\to \everystarttext
+
+\def\complexlanguage[#1]%
+ {\edef\askedlanguage{#1}%
+ \ifx\askedlanguage\empty \else
+ \ifcsname\l!prefix!\askedlanguage\endcsname
+ \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
+ \ifx\currentlanguage\askedlanguage \else
+ \setcurrentlanguage\currentmainlanguage\askedlanguage
+ \docomplexlanguage
+ \fi
+ \else
+ \showmessage\m!linguals6{#1}%
+ \fi
+ \fi}
+
+\let\simplelanguage\normallanguage
+
+\definecomplexorsimple\language
+
+\def\mainlanguage[#1]%
+ {\edef\askedlanguage{#1}%
+ \ifx\askedlanguage\empty \else
+ \ifcsname\l!prefix!\askedlanguage\endcsname
+ \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
+ \ifx\currentlanguage\askedlanguage
+ \ifx\currentmainlanguage\askedlanguage
+ \else
+ \setcurrentlanguage\askedlanguage\askedlanguage
+ \docomplexlanguage
+ \fi
+ \else
+ \setcurrentlanguage\askedlanguage\askedlanguage
+ \docomplexlanguage
+ \fi
+ \fi
+ \fi}
+
+%D \macros
+%D {defaultlanguage,languageparameter,specificlanguageparameter}
+
+\def\defaultlanguage#1%
+ {\ifcsname\??la#1\s!default\endcsname
+ \expandafter\defaultlanguage\csname\??la#1\s!default\endcsname
+ \else
+ #1%
+ \fi}
+
+\def\languageparameter#1%
+ {\ifcsname\??la\currentlanguage#1\endcsname
+ \csname\??la\currentlanguage#1\endcsname
+ \else\ifcsname\??la\currentlanguage\s!default\endcsname
+ \expandafter\specificlanguageparameter\csname\??la\currentlanguage\s!default\endcsname{#1}%
+ \else\ifcsname\??la\s!default#1\endcsname
+ \csname\??la\s!default#1\endcsname
+ \fi\fi\fi}
+
+\def\specificlanguageparameter#1#2%
+ {\ifcsname\??la#1#2\endcsname
+ \csname\??la#1#2\endcsname
+ \else\ifcsname\??la#1\s!default\endcsname
+ \expandafter\specificlanguageparameter\csname\??la#1\s!default\endcsname{#2}%
+ \else\ifcsname\??la\s!default#2\endcsname
+ \csname\??la\s!default#2\endcsname
+ \fi\fi\fi}
+
+%D New (see nomarking and nolist):
+
+\def\splitsequence#1#2%
+ {\doifelse{#1}\v!no{#2}{\doifelse{#1}\v!yes{\languageparameter\c!limittext}{#1}}}
+
+\def\splitsymbol#1%
+ {\splitsequence{#1}{\languageparameter\c!limittext}}
+
+%D Just like with subsentence boundary symbols, quotes
+%D placement depends on the current language, therefore we show
+%D the defaults here.
+%D
+%D \def\ShowLanguageValues [#1] [#2] #3 #4
+%D {\blank
+%D \startlinecorrection
+%D \vbox\bgroup
+%D \language[#1]%
+%D \setbox0=\hbox to \hsize{\hss\bf#2 subsentence symbol and quotes\hss}
+%D \dp0=0pt
+%D \box0
+%D \vskip.5em
+%D \hrule
+%D \vskip.5em
+%D \let\normalbar=|
+%D \hbox to \hsize
+%D {\hfil\quotation{#3 #4}\hfil\quote{#2}\hfil
+%D \let|=\normalbar\strut|<||<|#3|>|#4|>|\hfil}
+%D \vskip.5em
+%D \hrule
+%D \egroup
+%D \stoplinecorrection
+%D \blank}
+%D
+%D \ShowLanguageValues [af] [afrikaans] afrikaanse ...
+%D \ShowLanguageValues [ca] [catalan] catalan ...
+%D \ShowLanguageValues [cs] [czech] tjechisch tex
+%D \ShowLanguageValues [cs] [slovak] slowaakse ...
+%D \ShowLanguageValues [da] [danish] deense ...
+%D \ShowLanguageValues [de] [german] duitse degelijkheid
+%D \ShowLanguageValues [en] [english] engelse humor
+%D \ShowLanguageValues [fi] [finnish] finse ...
+%D \ShowLanguageValues [fr] [french] franse slag
+%D \ShowLanguageValues [it] [italian] italiaanse ...
+%D \ShowLanguageValues [la] [latin] latijnse missen
+%D \ShowLanguageValues [nl] [dutch] nederlandse zuinigheid
+%D \ShowLanguageValues [nb] [bokmal] noorse zalm
+%D \ShowLanguageValues [nn] [nnynorsk] noorse zalm
+%D \ShowLanguageValues [pl] [polish] poolse vlag
+%D \ShowLanguageValues [pt] [portuguese] portugese ...
+%D \ShowLanguageValues [es] [spanish] spaans benauwd
+%D \ShowLanguageValues [sv] [swedish] zweedse ...
+%D \ShowLanguageValues [tr] [turkish] turks fruit
+
+%D We support a lot of languages. These are specified and
+%D loaded in separate files, according to their roots. Here
+%D we only take care of (postponed) setting of the current
+%D language.
+%D
+%D \unprotect
+%D \placetable{The germanic languages (\type{lang-ger})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!nl \NC dutch \NC germanic \NC\FR
+%D \NC \s!en \NC english \NC germanic \NC\MR
+%D \NC \s!de \NC german \NC germanic \NC\MR
+%D \NC \s!da \NC danish \NC germanic \NC\MR
+%D \NC \s!sv \NC swedish \NC germanic \NC\MR
+%D \NC \s!af \NC afrikaans \NC germanic \NC\MR
+%D \NC \s!nb \NC bokmal \NC germanic \NC\LR
+%D \NC \s!nn \NC nynorsk \NC germanic \NC\LR
+%D \HL
+%D \stoptable
+%D \protect
+%D
+%D \unprotect
+%D \placetable{The italic languages (\type{lang-ita})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!fr \NC french \NC italic \NC\FR
+%D \NC \s!ca \NC catalan \NC italic \NC\MR
+%D \NC \s!es \NC spanish \NC italic \NC\MR
+%D \NC \s!it \NC italian \NC italic \NC\MR
+%D \NC \s!la \NC latin \NC italic \NC\MR
+%D \NC \s!pt \NC portuguese \NC italic \NC\LR
+%D \HL
+%D \stoptable
+%D \protect
+%D
+%D \unprotect
+%D \placetable{The slavic languages (\type{lang-sla})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!pl \NC polish \NC slavic \NC\FR
+%D \NC \s!cs \NC czech \NC slavic \NC\MR
+%D \NC \s!sk \NC slavik \NC slavic \NC\LR
+%D \HL
+%D \stoptable
+%D \protect
+%D \unprotect
+%D
+%D \placetable{The altaic languages (\type{lang-alt})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!tr \NC turkish \NC altaic \NC\SR
+%D \HL
+%D \stoptable
+%D
+%D \placetable{The uralic languages (\type{lang-ura})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!fi \NC finnish \NC uralic \NC\SR
+%D \HL
+%D \stoptable
+%D \protect
+
+% \bgroup \normallanguage255 \patterns{} \egroup
+% \def\nopatterns{\normallanguage255 }
+
+\def\nopatterns{\normallanguage\minusone}
+
+%D \XETEX\ is \UNICODE:
+
+\ifnum\texengine=\xetexengine
+
\def\synchronizepatternswithfont{}
\def\doloadpatterns #1#2{\dodoloadpatterns{#1}{#2}\s!default\s!default}
- \def\setnormallanguage #1{\dosetnormallanguage{:\s!default:\s!default:}#1\empty}
+ \def\dosetnormallanguage #1{\dodosetnormallanguage{:\s!default:\s!default:}{#1}\empty}
\def\setuphyppatencoding {\pathypsettings}
-\endXETEX
+
+\fi
+
+%D We default to the language belonging to the interface. This
+%D is one of the few places outside the interface modules where
+%D \type{\startinterface} is used.
+
+%D We default to english:
+
+\setupcurrentlanguage[\s!en]
+
+\def\initializemainlanguage
+ {\mainlanguage[\currentlanguage]%
+ \showmessage\m!linguals9\currentlanguage}
\protect \endinput
diff --git a/tex/context/base/lang-ini.mkiv b/tex/context/base/lang-ini.mkiv
index ce82b5a47..7cb945ef9 100644
--- a/tex/context/base/lang-ini.mkiv
+++ b/tex/context/base/lang-ini.mkiv
@@ -11,16 +11,133 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
+%D This module needs a further cleanup (real split between ii/iv).
+
+%D This module implements the (for the moment still simple)
+%D multi||language support of \CONTEXT, which should not be
+%D confused with the multi||lingual interface. This support
+%D will be extended when needed.
+
+\writestatus{loading}{ConTeXt Language Macros / Initialization}
\registerctxluafile{lang-ini}{1.001}
-\let\synchronizepatterns \relax % todo: cleanup
-\let\synchronizepatternswithfont\relax % todo: cleanup
-\let\preloadallpatterns \relax % just for old times sake
-\let\preloadlanguages \relax % just for old times sake
+\unprotect
+
+% \def\testlanguage[#1]%
+% {\start
+% \language[#1]
+% \number\normallanguage/\the\lefthyphenmin/\the\righthyphenmin:
+% \input tufte
+% \hyphenatedword{effetestenofditwerkt}
+% \par
+% \stop}
+%
+% \testlanguage[de] \testlanguage[de-de] \testlanguage[de-at] \testlanguage[de-ch] \page
+% \testlanguage[en] \testlanguage[us] \testlanguage[en-us] \testlanguage[uk] \testlanguage[en-gb] \page
+
+\ifx\nonfrenchspacing\undefined \let\nonfrenchspacing\relax \fi
+\ifx\frenchspacing \undefined \let\frenchspacing \relax \fi
+
+%D When loading hyphenation patterns, \TEX\ assign a number to
+%D each loaded table, starting with~0. Switching to a specific
+%D table is done by assigning the relevant number to the
+%D predefined \COUNTER\ \type{\language}.
+
+%D We keep track of the last loaded patterns by means of a
+%D pseudo \COUNTER. This just one of those situations in which
+%D we don't want to spent a real one. Language zero has no
+%D patterns, first of all because I like to start numbering
+%D at one. It may come in handy for special purposes as well.
+
+\normallanguage\zerocount \def\loadedlanguage{1}
+
+%D \macros
+%D {currentlanguage, setupcurrentlanguage}
+%D
+%D Instead of numbers,we are going to use symbolic names for
+%D the languages. The current langage is saved in the macro
+%D \type {\currentlanguage}. The setup macro is mainly used
+%D for cosmetic purposes.
+%D
+%D \starttyping
+%D \dorecurse{3}
+%D {\language[nl]
+%D \startmode[*en] english \stopmode
+%D \startmode[*nl] dutch \stopmode
+%D \language[en]
+%D \startmode[*en] english \stopmode
+%D \startmode[*nl] dutch \stopmode}
+%D \stoptyping
+
+\let\currentlanguage \empty
+\let\currentmainlanguage\empty
+
+\def\setupcurrentlanguage[#1]{\setcurrentlanguage\currentmainlanguage{#1}}
+
+\def\setcurrentlanguage#1#2% sets modes: **id (currentmain) *id (current)
+ {\doifsomething{#1}
+ {\ifx\currentmainlanguage\empty\else\resetsystemmode{\systemmodeprefix\currentmainlanguage}\fi
+ \edef\currentmainlanguage{#1}%
+ \setsystemmode{\systemmodeprefix\currentmainlanguage}}%
+ \doifsomething{#2}
+ {\ifx\currentlanguage\empty\else\resetsystemmode\currentlanguage\fi
+ \edef\currentlanguage{#2}%
+ \setsystemmode\currentlanguage}}
+
+%D The internal macros will be defined later.
+
+%D \macros
+%D {installlanguage}
+%D
+%D Hyphenation patterns can only be loaded when the format file
+%D is prepared. The next macro takes care of this loading. A
+%D language is specified with
+%D
+%D \showsetup{installlanguage}
+%D
+%D When \type {state} equals \type {start}, both patterns
+%D and additional hyphenation specifications are loaded. These
+%D files are seached for on the system path and are to be
+%D named:
+%D
+%D \starttyping
+%D \f!languageprefix-identifier.\f!patternsextension
+%D \f!languageprefix-identifier.\f!hyhensextension
+%D \stoptyping
+%D
+%D The \type{spacing} variable specifies how the spaces after
+%D punctuation has to be handled. English is by tradition more
+%D tolerant to inter||sentence spacing than other languages.
+%D
+%D This macro also defines \type {\identifier} as a shortcut
+%D switch to the language. Furthermore the command defined as
+%D being language specific, are executed. With
+%D \type {default} we can default to another language
+%D (patterns) at format generation time. This default language
+%D is overruled when the appropriate patterns are loaded (some
+%D implementations support run time addition of patterns to a
+%D preloaded format).
+
+\def\dodoinstalllanguage#1#2% #2 added
+ {\doifundefined{#1}{\setvalue{#1}{\complexlanguage[#2]}}%
+ \expanded{\noexpand\uppercase{\noexpand\edef\noexpand\ascii{#1}}}%
+ \doifundefined\ascii{\setvalue\ascii{\complexlanguage[#2]}}}
+
+%D \macros
+%D {preloadlanguages}
+%D
+%D We first try to load the files defined as file synonym
+%D for \type {lang-*.pat} and \type {lang-*.hyp}. After that we
+%D fall back on those files. The macro \type {\preloadpatterns}
+%D reports which patterns are loaded and what hyphenmin
+%D values are set.
-\def\mkdoloadpatterns#1#2%
+\let\installedlanguages\empty
+
+\def\doiflanguageelse#1{\doifdefinedelse{\??la#1\c!state}}
+
+\def\doloadpatterns#1#2%
{\ctxlua{languages.register(
"#1",
"#2",
@@ -28,43 +145,431 @@
"\truefilename{\f!languageprefix#2.\f!hyphensextension }")
}}
-\def\mkdoifpatternselse#1%
+% \def\doloadlanguagefiles#1%
+% {\doifelsevaluenothing{\??la#1\s!patterns}
+% {\doloadpatterns{#1}{#1}}
+% {\doloadpatterns{#1}{\getvalue{\??la#1\s!patterns}}}}
+
+\def\doloadlanguagefiles#1%
+ {\edef\languagesuffix{\specificlanguageparameter{#1}\s!patterns}%
+ \ifx\languagesuffix\empty
+ \edef\languagesuffix{\defaultlanguage{#1}}%
+ \else\ifx\languagesuffix\relax
+ \edef\languagesuffix{\defaultlanguage{#1}}%
+ \fi\fi
+ \ifx\languagesuffix\empty
+ \edef\languagesuffix{#1}%
+ \fi
+ \doloadpatterns{#1}\languagesuffix}
+
+\def\doinstalllanguage[#1][#2]%
+ {\doifassignmentelse{#2}
+ {\doiflanguageelse{#1}
+ {\getparameters[\??la#1][#2]}
+ {\setvalue{\l!prefix!#1}{#1}%
+ \addtocommalist{#1}\installedlanguages
+ \dodoinstalllanguage{#1}{#1}%
+ \getparameters[\??la#1][\c!state=\v!start,#2]}%
+ \doloadlanguagefiles{#1}}
+ {\setvalue{\l!prefix!#1}{#2}%
+ \getparameters[\??la#1][\s!default=#2]%
+ \dodoinstalllanguage{#1}{#2}}}
+
+\def\reallanguagetag#1%
+ {\ifcsname\l!prefix!#1\endcsname\csname\l!prefix!#1\endcsname\else#1\fi}
+
+% ^^ \language[#1] gave unwanted side effect of loading language specifics
+
+\def\installlanguage
+ {\dodoubleargument\doinstalllanguage}
+
+%D When the second argument is a language identifier, a
+%D synonym is created. This feature is present because we
+%D used dutch mnemonics in the dutch version, but nowadays
+%D conform a standard.
+
+\def\doifpatternselse#1%
{\ctxlua{cs.testcase(languages.loadable("#1"))}}
-\def\mkloadlanguagefiles#1%
- {\doifelsevaluenothing{\??la#1\s!patterns}
- {\mkdoloadpatterns{#1}{#1}}
- {\mkdoloadpatterns{#1}{\getvalue{\??la#1\s!patterns}}}}
+%D \macros
+%D {setuplanguage}
+%D
+%D Quick and dirty, but useful:
+%D
+%D \showsetup{setuplanguage}
+%D
+%D Beware, this command can only be used when a language is installed.
-\def\mksetnormallanguage#1#2% current default / we can freeze the number here
- {\normallanguage=\ctxlua{tex.sprint(languages.enable({
- "\csname\??la#1\s!patterns\endcsname","#1",
- "\csname\??la#2\s!patterns\endcsname","#2",
- }))}\relax}
+\unprotected \def\setuplanguage
+ {\dodoubleempty\dosetuplanguage}
-% to be tested
-%
-% \def\mkdosetnormallanguage#1#2% current default
-% {\normallanguage=\ctxlua{tex.sprint(languages.enable({
-% "\csname\??la#1\s!patterns\endcsname","#1",
-% "\csname\??la#2\s!patterns\endcsname","#2",
-% }))}}%
-% \setxvalue{\??la\??la#1#2}{\number\normallanguage}}
-%
-% \def\mksetnormallanguage#1#2% current default / we can freeze the number here
-% {\normallanguage\executeifdefined{\??la\??la#1#2}{\mkdosetnormallanguage{#1}{#2}}}
+\def\dosetuplanguage[#1][#2]% handy patch for testing
+ {\ifsecondargument
+ \getparameters[\??la#1][#2]%
+ \doif{#1}\currentlanguage\docomplexlanguage
+ \else
+ \getparameters[\??la\currentlanguage][#1]%
+ \docomplexlanguage
+ \fi}
+\setuplanguage
+ [\s!default]
+ [\s!lefthyphenmin=2,
+ \s!righthyphenmin=2,
+ \s!patterns=,
+ \c!spacing=\v!packed,
+ \c!lefthyphen=,
+ \c!righthyphen=-,
+ \c!hyphen=-,
+ \c!midsentence=---,
+ \c!leftsentence=---,
+ \c!rightsentence=---,
+ \c!leftsubsentence=---,
+ \c!rightsubsentence=---,
+ \c!leftquote=\upperleftsinglesixquote,
+ \c!rightquote=\upperrightsingleninequote,
+ \c!leftquotation=\upperleftdoublesixquote,
+ \c!rightquotation=\upperrightdoubleninequote,
+ \c!leftspeech=\languageparameter\c!leftquotation,
+ \c!middlespeech=,
+ \c!rightspeech=\languageparameter\c!rightquotation,
+ \c!limittext=\unknown,
+ \c!date={\v!year,\ ,\v!month,\ ,\v!day},
+ \c!text=Ag]
-\def\loadspellchecklist
- {\dodoubleempty\doloadspellchecklist}
+% rather new, split and per language
+
+\setuplanguage
+ [\s!default]
+ [\c!compoundhyphen=\compoundhyphen,
+ \c!leftcompoundhyphen=\compoundhyphen,
+ \c!rightcompoundhyphen=]
+
+%D The values \type {leftsentence} and \type
+%D {rightsentence} can be (and are) used to implement
+%D automatic subsentence boundary glyphs, like in {\fr
+%D |<|french guillemots|>|} or {\de |<|german guillemots|>|} or
+%D {\nl |<|dutch dashes|>|} like situations. Furthermore \type
+%D {leftquotation} and \type {leftquote} come into view
+%D \quotation {when we quote} or \quote {quote} something.
+
+%D \macros
+%D {currentdatespecification}
+%D
+%D Just to make things easy we can ask for the current date
+%D specification by saying:
+
+\def\currentdatespecification{\languageparameter\c!date}
+
+%D This command is not meant for users.
+
+%D Carefull reading of these macros shows that it's legal to
+%D say
+%D
+%D \starttyping
+%D \installlanguage [du] [de]
+%D \stoptyping
+
+%D \macros
+%D {language,mainlanguage}
+%D
+%D Switching to another language (actually another hyphenation
+%D pattern) is done with:
+%D
+%D \starttyping
+%D \language[identifier]
+%D \stoptyping
+%D
+%D or with \type{\identifier}. Just to be compatible with
+%D \PLAIN\ \TEX, we still support the original meaning, so
+%D
+%D \starttyping
+%D \language=1
+%D \stoptyping
+%D
+%D is a valid operation, where the relation between number
+%D and language depends on the order in installing languages.
+%D
+%D \showsetup{language}
+%D \showsetup{mainlanguage}
+%D
+%D Both commands take a predefined language identifier as
+%D argument. We can use \type{\mainlanguage[identifier]} for
+%D setting the (indeed) main language. This is the language
+%D used for translating labels like {\em figure} and {\em
+%D table}. The main language defaults to the current language.
+%D
+%D We take care of local as well as standardized language
+%D switching (fr and fa, de and du, but nl and nl).
+
+\def\dosetnormallanguage#1#2% current default
+ {\edef\askedlanguagepatterns{\specificlanguageparameter{#1}\s!patterns}%
+ \normallanguage=\ctxlua{tex.sprint(languages.enable({"\askedlanguagepatterns","#1","\askedlanguagepatterns","#2"}))}%
+ \ifproductionrun
+ \setxvalue{\??la\??la#1#2}{\number\normallanguage}%
+ \fi}
+
+\def\setnormallanguage#1#2% current default / we can freeze the number here
+ {\ifcsname\??la\??la#1#2\endcsname
+ \normallanguage\csname\??la\??la#1#2\endcsname % todo: we can set language at the lua end now
+ \else
+ \dosetnormallanguage{#1}{#2}%
+ \fi}
+
+\newtoks \everylanguage
+
+\def\disablelanguagespecifics
+ {\ignorecompoundcharacter}
+
+\def\sethyphenationvariables
+ {\lefthyphenmin 0\languageparameter\s!lefthyphenmin \relax
+ \righthyphenmin0\languageparameter\s!righthyphenmin\relax
+ \lefthyphenmin \numexpr\lefthyphenmin +\hyphenminoffset\relax
+ \righthyphenmin\numexpr\righthyphenmin+\hyphenminoffset\relax}
+
+\def\docomplexlanguage% assumes that \currentlanguage is set
+ {\edef\currentdefaultlanguage{\defaultlanguage\currentlanguage}%
+ \setnormallanguage\currentlanguage\currentdefaultlanguage
+ \the\everylanguage
+ \enablelanguagespecifics[\currentlanguage]%
+ \sethyphenationvariables
+ \relax
+ % will be definable and move to core-spa !
+ \doifelse{\languageparameter\c!spacing}\v!broad\nonfrenchspacing\frenchspacing}
+
+\ifx\enablelanguagespecifics\undefined \def\enablelanguagespecifics[#1]{} \fi
+
+% The following may be a solution for the fact that one cannot
+% change catcodes of characters like : and ; inside an environment.
+
+\appendtoks
+ \enablelanguagespecifics[\currentlanguage]%
+\to \everystarttext
+
+\def\complexlanguage[#1]%
+ {\edef\askedlanguage{#1}%
+ \ifx\askedlanguage\empty \else
+ \ifcsname\l!prefix!\askedlanguage\endcsname
+ \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
+ \ifx\currentlanguage\askedlanguage \else
+ \setcurrentlanguage\currentmainlanguage\askedlanguage
+ \docomplexlanguage
+ \fi
+ \else
+ \showmessage\m!linguals6{#1}%
+ \fi
+ \fi}
+
+\let\simplelanguage\normallanguage
+
+\definecomplexorsimple\language
+
+\def\mainlanguage[#1]%
+ {\edef\askedlanguage{#1}%
+ \ifx\askedlanguage\empty \else
+ \ifcsname\l!prefix!\askedlanguage\endcsname
+ \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
+ \ifx\currentlanguage\askedlanguage
+ \ifx\currentmainlanguage\askedlanguage
+ \else
+ \setcurrentlanguage\askedlanguage\askedlanguage
+ \docomplexlanguage
+ \fi
+ \else
+ \setcurrentlanguage\askedlanguage\askedlanguage
+ \docomplexlanguage
+ \fi
+ \fi
+ \fi}
+
+%D \macros
+%D {defaultlanguage,languageparameter,specificlanguageparameter}
+
+\def\defaultlanguage#1%
+ {\ifcsname\??la#1\s!default\endcsname
+ \expandafter\defaultlanguage\csname\??la#1\s!default\endcsname
+ \else
+ #1%
+ \fi}
+
+\def\languageparameter#1%
+ {\ifcsname\??la\currentlanguage#1\endcsname
+ \csname\??la\currentlanguage#1\endcsname
+ \else\ifcsname\??la\currentlanguage\s!default\endcsname
+ \expandafter\specificlanguageparameter\csname\??la\currentlanguage\s!default\endcsname{#1}%
+ \else\ifcsname\??la\s!default#1\endcsname
+ \csname\??la\s!default#1\endcsname
+ \fi\fi\fi}
+
+\def\specificlanguageparameter#1#2%
+ {\ifcsname\??la#1#2\endcsname
+ \csname\??la#1#2\endcsname
+ \else\ifcsname\??la#1\s!default\endcsname
+ \expandafter\specificlanguageparameter\csname\??la#1\s!default\endcsname{#2}%
+ \else\ifcsname\??la\s!default#2\endcsname
+ \csname\??la\s!default#2\endcsname
+ \fi\fi\fi}
+
+%D New (see nomarking and nolist):
+
+\def\splitsequence#1#2%
+ {\doifelse{#1}\v!no{#2}{\doifelse{#1}\v!yes{\languageparameter\c!limittext}{#1}}}
+
+\def\splitsymbol#1%
+ {\splitsequence{#1}{\languageparameter\c!limittext}}
+
+%D Just like with subsentence boundary symbols, quotes
+%D placement depends on the current language, therefore we show
+%D the defaults here.
+%D
+%D \def\ShowLanguageValues [#1] [#2] #3 #4
+%D {\blank
+%D \startlinecorrection
+%D \vbox\bgroup
+%D \language[#1]%
+%D \setbox0=\hbox to \hsize{\hss\bf#2 subsentence symbol and quotes\hss}
+%D \dp0=0pt
+%D \box0
+%D \vskip.5em
+%D \hrule
+%D \vskip.5em
+%D \let\normalbar=|
+%D \hbox to \hsize
+%D {\hfil\quotation{#3 #4}\hfil\quote{#2}\hfil
+%D \let|=\normalbar\strut|<||<|#3|>|#4|>|\hfil}
+%D \vskip.5em
+%D \hrule
+%D \egroup
+%D \stoplinecorrection
+%D \blank}
+%D
+%D \ShowLanguageValues [af] [afrikaans] afrikaanse ...
+%D \ShowLanguageValues [ca] [catalan] catalan ...
+%D \ShowLanguageValues [cs] [czech] tjechisch tex
+%D \ShowLanguageValues [cs] [slovak] slowaakse ...
+%D \ShowLanguageValues [da] [danish] deense ...
+%D \ShowLanguageValues [de] [german] duitse degelijkheid
+%D \ShowLanguageValues [en] [english] engelse humor
+%D \ShowLanguageValues [fi] [finnish] finse ...
+%D \ShowLanguageValues [fr] [french] franse slag
+%D \ShowLanguageValues [it] [italian] italiaanse ...
+%D \ShowLanguageValues [la] [latin] latijnse missen
+%D \ShowLanguageValues [nl] [dutch] nederlandse zuinigheid
+%D \ShowLanguageValues [nb] [bokmal] noorse zalm
+%D \ShowLanguageValues [nn] [nnynorsk] noorse zalm
+%D \ShowLanguageValues [pl] [polish] poolse vlag
+%D \ShowLanguageValues [pt] [portuguese] portugese ...
+%D \ShowLanguageValues [es] [spanish] spaans benauwd
+%D \ShowLanguageValues [sv] [swedish] zweedse ...
+%D \ShowLanguageValues [tr] [turkish] turks fruit
+
+%D We support a lot of languages. These are specified and
+%D loaded in separate files, according to their roots. Here
+%D we only take care of (postponed) setting of the current
+%D language.
+%D
+%D \unprotect
+%D \placetable{The germanic languages (\type{lang-ger})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!nl \NC dutch \NC germanic \NC\FR
+%D \NC \s!en \NC english \NC germanic \NC\MR
+%D \NC \s!de \NC german \NC germanic \NC\MR
+%D \NC \s!da \NC danish \NC germanic \NC\MR
+%D \NC \s!sv \NC swedish \NC germanic \NC\MR
+%D \NC \s!af \NC afrikaans \NC germanic \NC\MR
+%D \NC \s!nb \NC bokmal \NC germanic \NC\LR
+%D \NC \s!nn \NC nynorsk \NC germanic \NC\LR
+%D \HL
+%D \stoptable
+%D \protect
+%D
+%D \unprotect
+%D \placetable{The italic languages (\type{lang-ita})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!fr \NC french \NC italic \NC\FR
+%D \NC \s!ca \NC catalan \NC italic \NC\MR
+%D \NC \s!es \NC spanish \NC italic \NC\MR
+%D \NC \s!it \NC italian \NC italic \NC\MR
+%D \NC \s!la \NC latin \NC italic \NC\MR
+%D \NC \s!pt \NC portuguese \NC italic \NC\LR
+%D \HL
+%D \stoptable
+%D \protect
+%D
+%D \unprotect
+%D \placetable{The slavic languages (\type{lang-sla})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!pl \NC polish \NC slavic \NC\FR
+%D \NC \s!cs \NC czech \NC slavic \NC\MR
+%D \NC \s!sk \NC slavik \NC slavic \NC\LR
+%D \HL
+%D \stoptable
+%D \protect
+%D \unprotect
+%D
+%D \placetable{The altaic languages (\type{lang-alt})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!tr \NC turkish \NC altaic \NC\SR
+%D \HL
+%D \stoptable
+%D
+%D \placetable{The uralic languages (\type{lang-ura})}
+%D \starttable[||||]
+%D \HL
+%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
+%D \HL
+%D \NC \s!fi \NC finnish \NC uralic \NC\SR
+%D \HL
+%D \stoptable
+%D \protect
+
+% \bgroup \normallanguage255 \patterns{} \egroup
+% \def\nopatterns{\normallanguage255 }
+
+\def\nopatterns{\normallanguage\minusone}
+
+%D We default to the language belonging to the interface. This
+%D is one of the few places outside the interface modules where
+%D \type{\startinterface} is used.
+
+%D We default to english:
+
+\setupcurrentlanguage[\s!en]
+
+\def\initializemainlanguage
+ {\mainlanguage[\currentlanguage]%
+ \showmessage\m!linguals9\currentlanguage}
+
+%D Might be in use:
+
+\let\preloadallpatterns\relax % just for old times sake
+\let\preloadlanguages \relax % just for old times sake
+
+%D This might bexcome a seperate file:
% mkiv only -- todo: internationalize command names
% \loadspellchecklist[en][words-en.txt]
+% \loadspellchecklist[us][words-en.txt]
% \loadspellchecklist[nl][words-nl.txt]
% \setupspellchecking[state=start]
-\def\loadspellchecklist[#1][#2]%
+\def\loadspellchecklist
+ {\dodoubleempty\doloadspellchecklist}
+
+\def\doloadspellchecklist[#1][#2]%
{\ctxlua{languages.words.load("#1","#2")}}
\def\setupspellchecking
diff --git a/tex/context/base/lang-ini.tex b/tex/context/base/lang-ini.tex
deleted file mode 100644
index 17393da33..000000000
--- a/tex/context/base/lang-ini.tex
+++ /dev/null
@@ -1,692 +0,0 @@
-%D \module
-%D [ file=lang-ini,
-%D version=1996.01.25,
-%D title=\CONTEXT\ Language Macros,
-%D subtitle=Initialization,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 needs a further cleanup (real split between ii/iv).
-
-%D This module implements the (for the moment still simple)
-%D multi||language support of \CONTEXT, which should not be
-%D confused with the multi||lingual interface. This support
-%D will be extended when needed.
-
-\writestatus{loading}{Context Language Macros / Initialization}
-
-\startmessages dutch library: linguals
- title: taal
- 1: afbreekpatronen -- voor -- geladen (n=--,e=--,m=--)
- 2: geen afbreekpatronen -- voor -- (n=--,e=--,m=--) (--,--)
- 3: afbreekdefinities -- voor -- geladen (n=--,e=--,m=--)
- 4: geen afbreekdefinities -- voor -- (n=--,e=--,m=--)
- 5: afbreekpatronen voor -- niet geladen
- 6: taal -- is niet gedefinieerd
- 7: taal specifieke opties [--] introduceren een skip van --
- 8: taal specifieke opties [--] naadloos toegevoegd
- 9: taal -- is actief
- 10: patronen --geladen
-\stopmessages
-
-\startmessages english library: linguals
- title: language
- 1: patterns -- for -- loaded (n=--,e=--,m=--)
- 2: no patterns -- for -- (n=--,e=--,m=--) (--,--)
- 3: hyphenations -- for -- loaded (n=--,e=--,m=--)
- 4: no hyphenations -- for -- (n=--,e=--,m=--)
- 5: patterns for -- not loaded
- 6: language -- is undefined
- 7: language specific options [--] introduce a -- skip
- 8: language specific options [--] seamless appended
- 9: language -- is active
- 10: patterns --loaded
-\stopmessages
-
-\startmessages german library: linguals
- title: Sprache
- 1: Trennmuster -- fuer -- geladen (n=--,e=--,m=--)
- 2: Keine Trennmuster -- fuer -- (n=--,e=--,m=--) (--,--)
- 3: Trenndefinitionen -- fuer -- geladen (n=--,e=--,m=--)
- 4: Keine Trenndefinitionen -- fuer -- (n=--,e=--,m=--)
- 5: Trennmuster fuer -- nicht geladen
- 6: Sprache -- ist undefiniert
- 7: Sprachenspezifische Option [--] fuegt eine Luecke von -- ein
- 8: Sprachenspezifische Option [--] nahtlos hinzugefuegt
- 9: Sprache -- ist aktiv
- 10: Trennmuster --geladen
-\stopmessages
-
-% TOM: 9 and 10
-
-\startmessages czech library: linguals
- title: jazyky
- 1: vzory -- pro -- nacteny (n=--,e=--,m=--)
- 2: zadne vzory -- pro -- (n=--,e=--,m=--) (--,--)
- 3: deleni slov -- pro -- nacteno (n=--,e=--,m=--)
- 4: zadne deleni slov -- pro -- (n=--,e=--,m=--)
- 5: vzory pro -- nenacteny
- 6: jazyk -- neni definovan
- 7: specificke volby jazyka [--] zavadeji -- (zavlecenou) mezeru
- 8: specificke volby jazyka [--] bez mezer pripojeny
- 9: language -- is active
- 10: vzory --nacteny
-\stopmessages
-
-\startmessages italian library: linguals
- title: lingua
- 1: schemi -- per -- caricati (n=--,e=--,m=--)
- 2: niente schemi -- per -- (n=--,e=--,m=--) (--,--)
- 3: sillabazione -- per -- caricata (n=--,e=--,m=--)
- 4: niente sillabazione -- per -- (n=--,e=--,m=--)
- 5: schemi per -- non caricati
- 6: lingua -- non definita
- 7: opzioni specifiche per la lingua [--] introducono un salto --
- 8: opzioni specifiche per la lingua [--] aggiunte trasparentemente
- 9: lingua -- attiva
- 10: schemi -- caricati
-\stopmessages
-
-\startmessages norwegian library: linguals
- title: sprøk
- 1: orddelingsmønster -- for -- er lest inn (n=--,e=--,m=--)
- 2: ingen orddelingsmønster -- for -- (n=--,e=--,m=--) (--,--)
- 3: orddelingsdefinisjon -- for -- er lest inn (n=--,e=--,m=--)
- 4: ingen orddelingsdefinisjon -- for -- (n=--,e=--,m=--)
- 5: orddelingsmønster for -- er ikke lest inn
- 6: spràk -- er udefinert
- 7: spràk spesifikk opsjon [--] introduserer et -- hopp
- 8: spràk spesifikk opsjon [--] problemfritt tilføyd
- 9: spràk -- er aktivt
- 10: orddelingsmønster -- er lest inn
-\stopmessages
-
-\startmessages romanian library: linguals
- title: limbi
- 1: sablonul -- pentru -- s-a incarcat (n=--,e=--,m=--)
- 2: nu exista sabloane -- pentru -- (n=--,e=--,m=--) (--,--)
- 3: despartirea in silabe -- pentru -- s-a incarcat (n=--,e=--,m=--)
- 4: nu exista despartire in silabe -- pentru -- (n=--,e=--,m=--)
- 5: sabloanele pentru -- nu sunt incarcate
- 6: limba -- nu este definita
- 7: optiunile specifice ale limbii [--] introduc un spatiu --
- 8: optiunile specifice ale limbii [--] adaugate
- 9: limba -- este activa
- 10: sabloanele -- incarcate
-\stopmessages
-
-\startmessages french library: linguals
- title: langue
- 1: les motifs -- pour -- sont chargés (n=--,e=--,m=--)
- 2: pas de motifs -- pour -- (n=--,e=--,m=--) (--,--)
- 3: hyphenations -- pour -- chargés (n=--,e=--,m=--)
- 4: pas d'hyphenations -- pour -- (n=--,e=--,m=--)
- 5: les motifs pour -- ne sont pas chargés
- 6: langue -- non définie
- 7: les options spécifiques de langue [--] introduisent un -- saut
- 8: les options spécifiques de langue [--] sont ajoutés en douceur
- 9: la langue -- est active
- 10: motifs -- chargés
-\stopmessages
-
-\unprotect
-
-\ifx\nonfrenchspacing\undefined \let\nonfrenchspacing\relax \fi
-\ifx\frenchspacing \undefined \let\frenchspacing \relax \fi
-
-%D When loading hyphenation patterns, \TEX\ assign a number to
-%D each loaded table, starting with~0. Switching to a specific
-%D table is done by assigning the relevant number to the
-%D predefined \COUNTER\ \type{\language}. Unfortunately the
-%D name of this command suits very well the name of the
-%D language switching command we are to define, so let's save
-%D this primitive under another name:
-
-\let\normallanguage\language
-
-%D We keep track of the last loaded patterns by means of a
-%D pseudo \COUNTER. This just one of those situations in which
-%D we don't want to spent a real one. Language zero has no
-%D patterns, first of all because I like to start numbering
-%D at one. It may come in handy for special purposes as well.
-
-\normallanguage\zerocount \def\loadedlanguage{1}
-
-%D \macros
-%D {currentlanguage, setupcurrentlanguage}
-%D
-%D Instead of numbers,we are going to use symbolic names for
-%D the languages. The current langage is saved in the macro
-%D \type {\currentlanguage}. The setup macro is mainly used
-%D for cosmetic purposes.
-%D
-%D \starttyping
-%D \dorecurse{3}
-%D {\language[nl]
-%D \startmode[*en] english \stopmode
-%D \startmode[*nl] dutch \stopmode
-%D \language[en]
-%D \startmode[*en] english \stopmode
-%D \startmode[*nl] dutch \stopmode}
-%D \stoptyping
-
-\let\currentlanguage \empty
-\let\currentmainlanguage\empty
-
-\def\setupcurrentlanguage[#1]{\setcurrentlanguage\currentmainlanguage{#1}}
-
-\def\setcurrentlanguage#1#2% sets modes: **id (currentmain) *id (current)
- {\doifsomething{#1}
- {\ifx\currentmainlanguage\empty\else\resetsystemmode{\systemmodeprefix\currentmainlanguage}\fi
- \edef\currentmainlanguage{#1}%
- \setsystemmode{\systemmodeprefix\currentmainlanguage}}%
- \doifsomething{#2}
- {\ifx\currentlanguage\empty\else\resetsystemmode\currentlanguage\fi
- \edef\currentlanguage{#2}%
- \setsystemmode\currentlanguage}}
-
-%D The internal macros will be defined later.
-
-%D \macros
-%D {installlanguage}
-%D
-%D Hyphenation patterns can only be loaded when the format file
-%D is prepared. The next macro takes care of this loading. A
-%D language is specified with
-%D
-%D \showsetup{installlanguage}
-%D
-%D When \type {state} equals \type {start}, both patterns
-%D and additional hyphenation specifications are loaded. These
-%D files are seached for on the system path and are to be
-%D named:
-%D
-%D \starttyping
-%D \f!languageprefix-identifier.\f!patternsextension
-%D \f!languageprefix-identifier.\f!hyhensextension
-%D \stoptyping
-%D
-%D The \type{spacing} variable specifies how the spaces after
-%D punctuation has to be handled. English is by tradition more
-%D tolerant to inter||sentence spacing than other languages.
-%D
-%D This macro also defines \type {\identifier} as a shortcut
-%D switch to the language. Furthermore the command defined as
-%D being language specific, are executed. With
-%D \type {default} we can default to another language
-%D (patterns) at format generation time. This default language
-%D is overruled when the appropriate patterns are loaded (some
-%D implementations support run time addition of patterns to a
-%D preloaded format).
-
-\def\dodoinstalllanguage#1#2% #2 added
- {\doifundefined{#1}{\setvalue{#1}{\complexlanguage[#2]}}%
- \expanded{\noexpand\uppercase{\noexpand\edef\noexpand\ascii{#1}}}%
- \doifundefined\ascii{\setvalue\ascii{\complexlanguage[#2]}}}
-
-%D \macros
-%D {preloadlanguages}
-%D
-%D We first try to load the files defined as file synonym
-%D for \type {lang-*.pat} and \type {lang-*.hyp}. After that we
-%D fall back on those files. The macro \type {\preloadpatterns}
-%D reports which patterns are loaded and what hyphenmin
-%D values are set.
-
-\let\installedlanguages\empty
-
-\def\doiflanguageelse#1{\doifdefinedelse{\??la#1\c!state}}
-
-\ifx\mkloadlanguagefiles\undefined \let\mkloadlanguagefiles\gobbleoneargument \fi
-
-\def\doinstalllanguage[#1][#2]% some day we will make one for mkii and mkiv
- {\doifassignmentelse{#2}
- {\doiflanguageelse{#1}
- {\getparameters[\??la#1][#2]}
- {\setvalue{\l!prefix!#1}{#1}%
- \addtocommalist{#1}\installedlanguages
- \dodoinstalllanguage{#1}{#1}%
- \getparameters
- [\??la#1]
- [\c!state=\v!stop,
- \c!default=,
- \s!patterns=,
- \s!mapping=,
- \s!encoding=,
- \s!lefthyphenmin=\defaultlanguageparameter\s!lefthyphenmin,
- \s!righthyphenmin=\defaultlanguageparameter\s!righthyphenmin,
- #2]}%
- \doifvalue{\??la#1\c!default}{#1}{\letvalue{\??la#1\c!default}\empty}%
- % loop in deo: \doifvalue{\??la#1\s!patterns}{#1}{\letvalue{\??la#1\c!default}\empty}%
- \mkloadlanguagefiles{#1}}
- {\setvalue{\l!prefix!#1}{#2}%
- \dodoinstalllanguage{#1}{#2}}}
-
-\def\reallanguagetag#1%
- {\ifcsname\l!prefix!#1\endcsname
- %\expandafter\reallanguagetag\csname\l!prefix!#1\endcsname % evt undefined en dan wel
- \csname\l!prefix!#1\endcsname
- \else
- #1%
- \fi}
-
-% ^^ \language[#1] gave unwanted side effect of loading language specifics
-
-\def\installlanguage
- {\dodoubleargument\doinstalllanguage}
-
-%D When the second argument is a language identifier, a
-%D synonym is created. This feature is present because we
-%D used dutch mnemonics in the dutch version, but nowadays
-%D conform a standard.
-
-\let \patternencoding \s!default
-\let \patternmapping \s!default
-
-\ifx\mkloadpatterns \undefined \let\mkloadpatterns \gobbletwoarguments \fi
-\ifx\mkdoifpatternselse\undefined \let\mkdoifpatternselse\gobbletwoarguments \fi
-
-\def\doloadpatterns {\mkdoloadpatterns}
-\def\doifpatternselse{\mkdoifpatternselse}
-
-%D \macros
-%D {setuplanguage}
-%D
-%D Quick and dirty, but useful:
-%D
-%D \showsetup{setuplanguage}
-%D
-%D Beware, this command can only be used when a language is installed.
-
-\unprotected \def\setuplanguage
- {\dodoubleempty\dosetuplanguage}
-
-\def\dosetuplanguage[#1][#2]% handy patch for testing
- {\ifsecondargument
- \getparameters[\??la#1][#2]%
- \doif{#1}\currentlanguage\docomplexlanguage
- \else
- \getparameters[\??la\currentlanguage][#1]%
- \docomplexlanguage
- \fi}
-
-\setuplanguage
- [\s!default]
- [\s!lefthyphenmin=2,
- \s!righthyphenmin=2,
- \c!spacing=\v!packed,
- \c!lefthyphen=,
- \c!righthyphen=-,
- \c!hyphen=-,
- \c!midsentence=---,
- \c!leftsentence=---,
- \c!rightsentence=---,
- \c!leftsubsentence=---,
- \c!rightsubsentence=---,
- \c!leftquote=\upperleftsinglesixquote,
- \c!rightquote=\upperrightsingleninequote,
- \c!leftquotation=\upperleftdoublesixquote,
- \c!rightquotation=\upperrightdoubleninequote,
- \c!leftspeech=\languageparameter\c!leftquotation,
- \c!middlespeech=,
- \c!rightspeech=\languageparameter\c!rightquotation,
- \c!limittext=\unknown,
- \c!date={\v!year,\ ,\v!month,\ ,\v!day},
- \c!text=Ag]
-
-% rather new, split and per language
-
-\setuplanguage
- [\s!default]
- [\c!compoundhyphen=\compoundhyphen,
- \c!leftcompoundhyphen=\compoundhyphen,
- \c!rightcompoundhyphen=]
-
-%D The values \type {leftsentence} and \type
-%D {rightsentence} can be (and are) used to implement
-%D automatic subsentence boundary glyphs, like in {\fr
-%D |<|french guillemots|>|} or {\de |<|german guillemots|>|} or
-%D {\nl |<|dutch dashes|>|} like situations. Furthermore \type
-%D {leftquotation} and \type {leftquote} come into view
-%D \quotation {when we quote} or \quote {quote} something.
-
-%D \macros
-%D {currentdatespecification}
-%D
-%D Just to make things easy we can ask for the current date
-%D specification by saying:
-
-\def\currentdatespecification{\languageparameter\c!date}
-
-%D This command is not meant for users.
-
-%D Carefull reading of these macros shows that it's legal to
-%D say
-%D
-%D \starttyping
-%D \installlanguage [du] [de]
-%D \stoptyping
-
-%D \macros
-%D {language,mainlanguage}
-%D
-%D Switching to another language (actually another hyphenation
-%D pattern) is done with:
-%D
-%D \starttyping
-%D \language[identifier]
-%D \stoptyping
-%D
-%D or with \type{\identifier}. Just to be compatible with
-%D \PLAIN\ \TEX, we still support the original meaning, so
-%D
-%D \starttyping
-%D \language=1
-%D \stoptyping
-%D
-%D is a valid operation, where the relation between number
-%D and language depends on the order in installing languages.
-%D
-%D \showsetup{language}
-%D \showsetup{mainlanguage}
-%D
-%D Both commands take a predefined language identifier as
-%D argument. We can use \type{\mainlanguage[identifier]} for
-%D setting the (indeed) main language. This is the language
-%D used for translating labels like {\em figure} and {\em
-%D table}. The main language defaults to the current language.
-%D
-%D We take care of local as well as standardized language
-%D switching (fr and fa, de and du, but nl and nl).
-
-\ifx\synchronizepatterns \undefined \let\synchronizepatterns\relax \fi
-\ifx\synchronizepatternswithfont\undefined \def\synchronizepatternswithfont{\synchronizepatterns} \fi
-
-\ifx\mksetnormallanguage\undefined \let\mksetnormallanguage\gobbletwoarguments \fi
-
-\def\setnormallanguage{\mksetnormallanguage}
-
-\newevery \everylanguage \relax
-\newevery \everyresetlanguagespecifics \relax
-
-\def\disablelanguagespecifics
- {\ignorecompoundcharacter}
-
-\def\sethyphenationvariables
- {\lefthyphenmin 0\languageparameter\s!lefthyphenmin \relax
- \righthyphenmin0\languageparameter\s!righthyphenmin\relax
- \lefthyphenmin \numexpr\lefthyphenmin +\hyphenminoffset\relax
- \righthyphenmin\numexpr\righthyphenmin+\hyphenminoffset\relax}
-
-\def\docomplexlanguage% assumes that \currentlanguage is set
- {\edef\currentdefaultlanguage{\defaultlanguage\currentlanguage}%
- \mksetnormallanguage\currentlanguage\currentdefaultlanguage
- \the\everylanguage
- \enablelanguagespecifics[\currentlanguage]%
- \sethyphenationvariables
- \relax
- % will be definable and move to core-spa !
- \doifelse{\languageparameter\c!spacing}\v!broad
- \nonfrenchspacing\frenchspacing}
-
-\ifx\enablelanguagespecifics\undefined \def\enablelanguagespecifics[#1]{} \fi
-
-% The following may be a solution for the fact that one cannot
-% change catcodes of characters like : and ; inside an environment.
-
-\appendtoks
- \enablelanguagespecifics[\currentlanguage]%
-\to \everystarttext
-
-\def\complexlanguage[#1]%
- {\edef\askedlanguage{#1}%
- \ifx\askedlanguage\empty \else
- \ifcsname\l!prefix!\askedlanguage\endcsname
- \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
- \ifx\currentlanguage\askedlanguage \else
- \setcurrentlanguage\currentmainlanguage\askedlanguage
- \docomplexlanguage
- \fi
- \else
- \showmessage\m!linguals6{#1}%
- \fi
- \fi}
-
-\let\simplelanguage\normallanguage
-
-\definecomplexorsimple\language
-
-% \def\mainlanguage[#1]%
-% {\edef\askedlanguage{#1}%
-% \ifx\askedlanguage\empty \else
-% \ifcsname\l!prefix!\askedlanguage\endcsname
-% \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
-% \ifx\currentmainlanguage\askedlanguage \else
-% \setcurrentlanguage\askedlanguage\askedlanguage
-% \docomplexlanguage
-% \fi
-% \fi
-% \fi}
-
-\def\mainlanguage[#1]%
- {\edef\askedlanguage{#1}%
- \ifx\askedlanguage\empty \else
- \ifcsname\l!prefix!\askedlanguage\endcsname
- \edef\askedlanguage{\csname\l!prefix!\askedlanguage\endcsname}%
- \ifx\currentlanguage\askedlanguage
- \ifx\currentmainlanguage\askedlanguage
- \else
- \setcurrentlanguage\askedlanguage\askedlanguage
- \docomplexlanguage
- \fi
- \else
- \setcurrentlanguage\askedlanguage\askedlanguage
- \docomplexlanguage
- \fi
- \fi
- \fi}
-
-%D \macros
-%D {defaultlanguage,languagedefault}
-%D
-%D The macro \type {\defaultlanguage{id}} expands into the
-%D default language, when defined, while \type
-%D {\languagedefault{id}\c!parameter} returns the default's
-%D parameter.
-
-\def\defaultlanguage#1%
- {\@EA\ifx\csname\??la#1\c!default\endcsname\empty
- #1%
- \else
- \@EA\defaultlanguage\csname\??la#1\c!default\endcsname
- \fi}
-
-\def\languagedefault#1#2%
- {\csname\??la\defaultlanguage{#1}#2\endcsname}
-
-\def\languageparameter % @EA = speedup
- {\@EA\dolanguageparameter\@EA{\defaultlanguage\currentlanguage}}
-
-\def\specificlanguageparameter#1% @EA = speedup
- {\@EA\dospecificlanguageparameter\@EA{\defaultlanguage{#1}}{#1}}
-
-\def\xxlanguageparameter#1% @EA = speedup
- {\@EA\dolanguageparameter\@EA{\defaultlanguage{#1}}}
-
-\def\defaultlanguageparameter#1%
- {\csname\??la\s!default#1\endcsname}
-
-\def\dolanguageparameter#1#2%
- {\csname\??la
- \ifcsname\??la\currentlanguage#2\endcsname
- \currentlanguage
- \else\ifcsname\??la#1#2\endcsname
- \@EA\ifx\csname\??la#1#2\endcsname\empty\s!default\else#1\fi
- \else
- \s!default
- \fi\fi
- #2\endcsname}
-
-\def\dospecificlanguageparameter#1#2#3%
- {\csname\??la
- \ifcsname\??la#2#3\endcsname
- \@EA\ifx\csname\??la#2#3\endcsname\empty\s!default\else#2\fi
- \else\ifcsname\??la#1#3\endcsname
- \@EA\ifx\csname\??la#1#3\endcsname\empty\s!default\else#1\fi
- \else
- \s!default
- \fi\fi
- #3\endcsname}
-
-%D New (see nomarking and nolist):
-
-\def\splitsequence#1#2%
- {\doifelse{#1}\v!no{#2}{\doifelse{#1}\v!yes{\languageparameter\c!limittext}{#1}}}
-
-\def\splitsymbol#1%
- {\splitsequence{#1}{\languageparameter\c!limittext}}
-
-%D Just like with subsentence boundary symbols, quotes
-%D placement depends on the current language, therefore we show
-%D the defaults here.
-%D
-%D \def\ShowLanguageValues [#1] [#2] #3 #4
-%D {\blank
-%D \startlinecorrection
-%D \vbox\bgroup
-%D \language[#1]%
-%D \setbox0=\hbox to \hsize{\hss\bf#2 subsentence symbol and quotes\hss}
-%D \dp0=0pt
-%D \box0
-%D \vskip.5em
-%D \hrule
-%D \vskip.5em
-%D \let\normalbar=|
-%D \hbox to \hsize
-%D {\hfil\quotation{#3 #4}\hfil\quote{#2}\hfil
-%D \let|=\normalbar\strut|<||<|#3|>|#4|>|\hfil}
-%D \vskip.5em
-%D \hrule
-%D \egroup
-%D \stoplinecorrection
-%D \blank}
-%D
-%D \ShowLanguageValues [af] [afrikaans] afrikaanse ...
-%D \ShowLanguageValues [ca] [catalan] catalan ...
-%D \ShowLanguageValues [cs] [czech] tjechisch tex
-%D \ShowLanguageValues [cs] [slovak] slowaakse ...
-%D \ShowLanguageValues [da] [danish] deense ...
-%D \ShowLanguageValues [de] [german] duitse degelijkheid
-%D \ShowLanguageValues [en] [english] engelse humor
-%D \ShowLanguageValues [fi] [finnish] finse ...
-%D \ShowLanguageValues [fr] [french] franse slag
-%D \ShowLanguageValues [it] [italian] italiaanse ...
-%D \ShowLanguageValues [la] [latin] latijnse missen
-%D \ShowLanguageValues [nl] [dutch] nederlandse zuinigheid
-%D \ShowLanguageValues [nb] [bokmal] noorse zalm
-%D \ShowLanguageValues [nn] [nnynorsk] noorse zalm
-%D \ShowLanguageValues [pl] [polish] poolse vlag
-%D \ShowLanguageValues [pt] [portuguese] portugese ...
-%D \ShowLanguageValues [es] [spanish] spaans benauwd
-%D \ShowLanguageValues [sv] [swedish] zweedse ...
-%D \ShowLanguageValues [tr] [turkish] turks fruit
-
-%D We support a lot of languages. These are specified and
-%D loaded in separate files, according to their roots. Here
-%D we only take care of (postponed) setting of the current
-%D language.
-%D
-%D \unprotect
-%D \placetable{The germanic languages (\type{lang-ger})}
-%D \starttable[||||]
-%D \HL
-%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
-%D \HL
-%D \NC \s!nl \NC dutch \NC germanic \NC\FR
-%D \NC \s!en \NC english \NC germanic \NC\MR
-%D \NC \s!de \NC german \NC germanic \NC\MR
-%D \NC \s!da \NC danish \NC germanic \NC\MR
-%D \NC \s!sv \NC swedish \NC germanic \NC\MR
-%D \NC \s!af \NC afrikaans \NC germanic \NC\MR
-%D \NC \s!nb \NC bokmal \NC germanic \NC\LR
-%D \NC \s!nn \NC nynorsk \NC germanic \NC\LR
-%D \HL
-%D \stoptable
-%D \protect
-%D
-%D \unprotect
-%D \placetable{The italic languages (\type{lang-ita})}
-%D \starttable[||||]
-%D \HL
-%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
-%D \HL
-%D \NC \s!fr \NC french \NC italic \NC\FR
-%D \NC \s!ca \NC catalan \NC italic \NC\MR
-%D \NC \s!es \NC spanish \NC italic \NC\MR
-%D \NC \s!it \NC italian \NC italic \NC\MR
-%D \NC \s!la \NC latin \NC italic \NC\MR
-%D \NC \s!pt \NC portuguese \NC italic \NC\LR
-%D \HL
-%D \stoptable
-%D \protect
-%D
-%D \unprotect
-%D \placetable{The slavic languages (\type{lang-sla})}
-%D \starttable[||||]
-%D \HL
-%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
-%D \HL
-%D \NC \s!pl \NC polish \NC slavic \NC\FR
-%D \NC \s!cs \NC czech \NC slavic \NC\MR
-%D \NC \s!sk \NC slavik \NC slavic \NC\LR
-%D \HL
-%D \stoptable
-%D \protect
-%D \unprotect
-%D
-%D \placetable{The altaic languages (\type{lang-alt})}
-%D \starttable[||||]
-%D \HL
-%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
-%D \HL
-%D \NC \s!tr \NC turkish \NC altaic \NC\SR
-%D \HL
-%D \stoptable
-%D
-%D \placetable{The uralic languages (\type{lang-ura})}
-%D \starttable[||||]
-%D \HL
-%D \NC \bf mnemonic \NC \bf language \NC \bf group \NC\SR
-%D \HL
-%D \NC \s!fi \NC finnish \NC uralic \NC\SR
-%D \HL
-%D \stoptable
-%D \protect
-
-% \bgroup \normallanguage255 \patterns{} \egroup
-% \def\nopatterns{\normallanguage255 }
-
-\def\nopatterns{\normallanguage\minusone}
-
-%D Mark plugin:
-
-\loadmarkfile{lang-ini} % not yet
-
-%D We default to the language belonging to the interface. This
-%D is one of the few places outside the interface modules where
-%D \type{\startinterface} is used.
-
-%D We default to english:
-
-\setupcurrentlanguage[\s!en]
-
-\appendtoks\mainlanguage[\currentlanguage]\to\everyjob
-
-\appendtoks\showmessage\m!linguals9\currentlanguage\to\everyjob
-
-\protect \endinput
diff --git a/tex/context/base/lang-ita.tex b/tex/context/base/lang-ita.tex
index 93a169112..ae3b7a514 100644
--- a/tex/context/base/lang-ita.tex
+++ b/tex/context/base/lang-ita.tex
@@ -13,7 +13,7 @@
% Todo: replace \'.. by \namedglyph
-\writestatus{loading}{Italic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Italic Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -47,7 +47,8 @@
\c!leftquotation=\leftguillemot,
\c!rightquotation=\rightguillemot,
\c!date={\v!day+,\v!space,\v!month,\v!space,\v!year},
- \c!state=\v!stop]
+ \s!mapping={texnansi,ec},
+ \s!encoding={texnansi,ec}]
\installlanguage
[\s!es]
@@ -60,8 +61,7 @@
\c!rightquote=\upperrightsingleninequote,
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
- \c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \c!date={\v!day,\ ,\v!month,\ ,\v!year}]
\installlanguage [sp] [\s!es] % old times context
@@ -76,8 +76,7 @@
\c!rightquote=\upperrightsingleninequote,
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
- \c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \c!date={\v!day,\ ,\v!month,\ ,\v!year}]
% Note GB left|/|right (sub)sentences are for \quote {incisi}.
@@ -96,7 +95,8 @@
\c!middlespeech=\leftguillemot,
\c!rightspeech=\rightguillemot,
\c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping={texnansi,ec},
+ \s!encoding={texnansi,ec}]
\installlanguage % the same as italian
[\s!la]
@@ -109,8 +109,7 @@
\c!rightquote=\lowerrightsingleninequote,
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\lowerrightdoubleninequote,
- \c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \c!date={\v!day,\ ,\v!month,\ ,\v!year}]
\installlanguage
[\s!pt]
@@ -124,7 +123,8 @@
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!year,\ ,\v!month,\ ,\v!day},
- \c!state=\v!stop]
+ \s!mapping={texnansi,ec},
+ \s!encoding={texnansi,ec}]
\installlanguage
[\s!ro]
@@ -137,8 +137,7 @@
\c!rightquote=\rightguillemot,
\c!leftquotation=\lowerrightdoubleninequote,
\c!rightquotation=\upperleftdoublesixquote,
- \c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \c!date={\v!day,\ ,\v!month,\ ,\v!year}]
%D For compatibility reasons we also define:
@@ -227,8 +226,8 @@
\setupheadtext [\s!ro] [\v!units=Unit\u{a}\c{t}i]
\setuplabeltext [\s!fr] [\v!table=Tableau ]
-\setuplabeltext [\s!es] [\v!table=Tablas ]
-\setuplabeltext [\s!ca] [\v!table=Taules ]
+\setuplabeltext [\s!es] [\v!table=Tabla ]
+\setuplabeltext [\s!ca] [\v!table=Taula ]
\setuplabeltext [\s!it] [\v!table=Tabella ]
\setuplabeltext [\s!la] [\v!table=Tabula ]
\setuplabeltext [\s!pt] [\v!table=Tabela ]
@@ -259,48 +258,48 @@
\setuplabeltext [\s!ro] [\v!graphic=Graficul ]
\setuplabeltext [\s!fr] [\v!chapter=]
-\setuplabeltext [\s!es] [\v!chapter=]
-\setuplabeltext [\s!ca] [\v!chapter=]
+\setuplabeltext [\s!es] [\v!chapter=Cap\'\itulo]
+\setuplabeltext [\s!ca] [\v!chapter=Cap\'\itol]
\setuplabeltext [\s!it] [\v!chapter=]
\setuplabeltext [\s!la] [\v!chapter=]
\setuplabeltext [\s!pt] [\v!chapter=]
\setuplabeltext [\s!ro] [\v!chapter=]
\setuplabeltext [\s!fr] [\v!section=]
-\setuplabeltext [\s!es] [\v!section=]
-\setuplabeltext [\s!ca] [\v!section=]
+\setuplabeltext [\s!es] [\v!section=Secci\'on]
+\setuplabeltext [\s!ca] [\v!section=Secci\'o]
\setuplabeltext [\s!it] [\v!section=]
\setuplabeltext [\s!la] [\v!section=]
\setuplabeltext [\s!pt] [\v!section=]
\setuplabeltext [\s!ro] [\v!section=]
\setuplabeltext [\s!fr] [\v!subsection=]
-\setuplabeltext [\s!es] [\v!subsection=]
-\setuplabeltext [\s!ca] [\v!subsection=]
+\setuplabeltext [\s!es] [\v!subsection=Subsecci\'on]
+\setuplabeltext [\s!ca] [\v!subsection=Subsecci\'o]
\setuplabeltext [\s!it] [\v!subsection=]
\setuplabeltext [\s!la] [\v!subsection=]
\setuplabeltext [\s!pt] [\v!subsection=]
\setuplabeltext [\s!ro] [\v!subsection=]
\setuplabeltext [\s!fr] [\v!subsubsection=]
-\setuplabeltext [\s!es] [\v!subsubsection=]
-\setuplabeltext [\s!ca] [\v!subsubsection=]
+\setuplabeltext [\s!es] [\v!subsubsection=Subsubsecci\'on]
+\setuplabeltext [\s!ca] [\v!subsubsection=Subsubsecci\'o]
\setuplabeltext [\s!it] [\v!subsubsection=]
\setuplabeltext [\s!la] [\v!subsubsection=]
\setuplabeltext [\s!pt] [\v!subsubsection=]
\setuplabeltext [\s!ro] [\v!subsubsection=]
\setuplabeltext [\s!fr] [\v!subsubsubsection=]
-\setuplabeltext [\s!es] [\v!subsubsubsection=]
-\setuplabeltext [\s!ca] [\v!subsubsubsection=]
+\setuplabeltext [\s!es] [\v!subsubsubsection=Subsubsubsecci\'on]
+\setuplabeltext [\s!ca] [\v!subsubsubsection=Subsubsubsecci\'o]
\setuplabeltext [\s!it] [\v!subsubsubsection=]
\setuplabeltext [\s!la] [\v!subsubsubsection=]
\setuplabeltext [\s!pt] [\v!subsubsubsection=]
\setuplabeltext [\s!ro] [\v!subsubsubsection=]
\setuplabeltext [\s!fr] [\v!appendix=]
-\setuplabeltext [\s!es] [\v!appendix=]
-\setuplabeltext [\s!ca] [\v!appendix=]
+\setuplabeltext [\s!es] [\v!appendix=Ap\'endice]
+\setuplabeltext [\s!ca] [\v!appendix=Ap\`endix]
\setuplabeltext [\s!it] [\v!appendix=]
\setuplabeltext [\s!la] [\v!appendix=]
\setuplabeltext [\s!pt] [\v!appendix=]
@@ -479,14 +478,12 @@
%D Rather new \unknown
-\setuplabeltext [\s!it] [\v!page=pagina ]
-\setuplabeltext [\s!it] [\v!atpage=a pagina ]
+\setuplabeltext [\s!it] [\v!page=pagina ]
+\setuplabeltext [\s!it] [\v!atpage=a pagina ]
\setuplabeltext [\s!it] [\v!hencefore=come mostrato sopra]
\setuplabeltext [\s!it] [\v!hereafter=come mostrato sotto]
\setuplabeltext [\s!it] [\v!see=cf. ]
-\setuplabeltext[\s!fr] [\v!see=voir ]
-
%D Ordinal converters:
\def\frordinaldaynumber#1% date is masculine
diff --git a/tex/context/base/lang-jap.tex b/tex/context/base/lang-jap.tex
index ffb53ea70..05c9b1d41 100644
--- a/tex/context/base/lang-jap.tex
+++ b/tex/context/base/lang-jap.tex
@@ -13,7 +13,7 @@
% rgabriel@kerio.com
-\writestatus{loading}{Context Language Macros / Japanese}
+\writestatus{loading}{ConTeXt Language Macros / Japanese}
\unprotect
@@ -29,8 +29,7 @@
\c!rightquote=\jaencoding\jaencodedsingleendquote,
\c!leftquotation=\jaencoding\jaencodedstartquote,
\c!rightquotation=\jaencoding\jaencodedendquote,
- \c!date={\jaencodedchristiandate,\v!year,\jaencodedyear,\v!month,\jaencodedmonth,\v!day,\jaencodedday},
- \c!state=\v!stop]
+ \c!date={\jaencodedchristiandate,\v!year,\jaencodedyear,\v!month,\jaencodedmonth,\v!day,\jaencodedday}]
\setupheadtext [\s!ja] [\v!content={\jaencoding\jaencodedtableofcontents}]
\setupheadtext [\s!ja] [\v!tables={\jaencoding\jaencodedtables}]
diff --git a/tex/context/base/lang-lab.tex b/tex/context/base/lang-lab.mkii
index 664460129..269ac249b 100644
--- a/tex/context/base/lang-lab.tex
+++ b/tex/context/base/lang-lab.mkii
@@ -2,7 +2,7 @@
%D [ file=lang-lab,
%D version=1997.08.27,
%D title=\CONTEXT\ Language Macros,
-%D subtitle=Language Head and Label Texts,
+%D subtitle=Labels,
%D author=Hans Hagen / Tobias Burnus,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,8 +11,6 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Language Head and Label Texts}
-
\unprotect
%D In this module we deal with language dependant labels and
@@ -183,21 +181,34 @@
% \csname#2\s!nl#3\endcsname \else
% \reporttextprefixerror{#1}{#2}{#3}%
% \fi\fi\fi\fi\fi}
+%
+% \def\dogetupsometextprefix#1#2#3% must be expandable !
+% {\ifcsname#2#1#3\endcsname
+% \csname#2#1#3\endcsname
+% \else\@EA\ifx\csname\??la#1\c!default\endcsname\empty
+% \ifcsname#2#3\endcsname
+% \csname#2#3\endcsname
+% \else\ifcsname#2\s!en#3\endcsname
+% \csname#2\s!en#3\endcsname
+% \else
+% \reporttextprefixerror{#1}{#2}{#3}%
+% \fi\fi
+% \else
+% \dogetupsometextprefix{\csname\??la#1\c!default\endcsname}{#2}{#3}%
+% \fi\fi}
-\def\dogetupsometextprefix#1#2#3% must be expandable !
+\def\dogetupsometextprefix#1#2#3% must be expandable ! #1 == language
{\ifcsname#2#1#3\endcsname
\csname#2#1#3\endcsname
- \else\@EA\ifx\csname\??la#1\c!default\endcsname\empty
- \ifcsname#2#3\endcsname
- \csname#2#3\endcsname
- \else\ifcsname#2\s!en#3\endcsname
- \csname#2\s!en#3\endcsname
- \else
- \reporttextprefixerror{#1}{#2}{#3}%
- \fi\fi
+ \else\ifcsname\??la#1\s!default\endcsname
+ \expandafter\dogetupsometextprefix\csname\??la#1\s!default\endcsname{#2}{#3}%
+ \else\ifcsname#2#3\endcsname
+ \csname#2#3\endcsname
+ \else\ifcsname#1\s!en#3\endcsname
+ \csname#2\s!en#3\endcsname
\else
- \dogetupsometextprefix{\csname\??la#1\c!default\endcsname}{#2}{#3}%
- \fi\fi}
+ \reporttextprefixerror{#1}{#2}{#3}%
+ \fi\fi\fi\fi}
\ifx\simplifiedcommands\undefined \newtoks\simplifiedcommands \fi
@@ -247,15 +258,15 @@
%D which expands to {\em something} or {\em iets}, depending on
%D de current language.
-\def\dotranslate[#1]% don't group! SLOW if really used: speed up
+\def\dotranslate[#1]%
{\getparameters[\??lg][#1]%
- \doifdefinedelse{\??lg\currentlanguage}%
- {\getvalue{\??lg\currentlanguage}}
- {\doifdefinedelse{\??lg\s!en}
- {\getvalue{\??lg\s!en}}
- {\doifdefinedelse{\??lg\s!nl}
- {\getvalue{\??lg\s!nl}}
- {[translation #1]}}}}
+ \ifcsname\??lg\currentlanguage\endcsname
+ \csname\??lg\currentlanguage\endcsname
+ \else\ifcsname\??lg\s!en\endcsname
+ \csname\??lg\s!en\endcsname
+ \else
+ [translation #1]%
+ \fi\fi}
\unexpanded\def\translate
{\dosingleempty\dotranslate}
diff --git a/tex/context/base/lang-lab.mkiv b/tex/context/base/lang-lab.mkiv
new file mode 100644
index 000000000..60408f787
--- /dev/null
+++ b/tex/context/base/lang-lab.mkiv
@@ -0,0 +1,266 @@
+%D \module
+%D [ file=lang-lab,
+%D version=1997.08.27,
+%D title=\CONTEXT\ Language Macros,
+%D subtitle=Labels,
+%D author=Hans Hagen / Tobias Burnus,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 In this module we deal with language dependant labels and
+%D prefixes, like in {\em Figure~12} and {\em Chapter 1}. In
+%D this file we set the default values. Users can easily
+%D overrule these.
+%D
+%D This module is dedicated to the grandfather of Tobias
+%D Burnus, who's extensive languages oriented library helped us
+%D a lot in finding the right translations. All those labels
+%D are collected in files that reflect their common ancestor.
+%D
+%D Not all languages can be satisfied with the labeling
+%D mechanism as provided here. Chinese for instance put a label
+%D in front as well as after a part number. This is why the
+%D current implementation of labels supports two labels too.
+
+%D \macros
+%D {setupheadtext, setuplabeltext}
+%D
+%D First we present some macros that deal with what we will
+%D call head and label texts. Such texts are defines by:
+%D
+%D \showsetup{setupheadtext}
+%D \showsetup{setuplabeltext}
+%D
+%D In a few paragraphs we'll show quite a lot of examples
+%D of its use.
+
+\let\handletextprefix\relax
+
+\def\setupheadtext {\dosetupsometextprefix[\c!title]}
+\def\setuplabeltext{\dosetupsometextprefix[\c!label]}
+
+\def\dosetupsometextprefix
+ {\let\dodocommand\xdosetupsometextprefix
+ \dotripleempty\dodosetupsometextprefix}
+
+% \def\dodosetupsometextprefix[#1][#2][#3]%
+% {\ifthirdargument
+% \def\docommand##1{\dodocommand[#1#2][##1]}%
+% \processcommalist[#3]\docommand
+% \else
+% \def\docommand##1{\dodocommand[#1\currentmainlanguage][##1]}%
+% \processcommalist[#2]\docommand
+% \fi}
+
+\def\dodosetupsometextprefix[#1][#2][#3]%
+ {\ifthirdargument
+ \def\docommand##1{\expanded{\dodocommand[#1\reallanguagetag{#2}]}[##1]}%
+ \processcommalist[#3]\docommand
+ \else
+ \def\docommand##1{\expanded{\dodocommand[#1\reallanguagetag\currentmainlanguage]}[##1]}%
+ \processcommalist[#2]\docommand
+ \fi}
+
+\def\doassignsometextprefix[#1][#2,#3,#4]%
+ {\setvalue{#1}{\handletextprefix{#2}{#3}}}
+
+\def\xdosetupsometextprefix[#1][#2=#3]%
+ {\doassignsometextprefix[#1#2][#3,,]}
+
+%D By changing the meaning of \type {\handletextprefix} we
+%D can filter the left and right labeltext as well as convert
+%D labels to uppercase.
+%D
+%D These commands accept all kind of inputs:
+%D
+%D \starttyping
+%D \setuplabeltext [language] [labellabel=text]
+%D \setuplabeltext [language] [labellabel=text,labellabel=text,...]
+%D \setuplabeltext [labellabel=text]
+%D \setuplabeltext [labellabel=text,labellabel=text,...]
+%D \stoptyping
+%D
+%D The last two cases concern the current language.
+
+%D \macros
+%D {headtext,
+%D labeltext, leftlabeltext, rightlabeltext, labeltexts,
+%D LABELTEXT, LEFTLABELTEXT, RIGHTLABELTEXT, LABELTEXTS}
+%D
+%D Once defined, head and label texts can be called upon using:
+%D
+%D \showsetup{headtext}
+%D \showsetup{labeltext}
+%D
+%D The latter one has an upcased alternative \type{\LABELTEXT}.
+
+% \def\labellanguage{\currentmainlanguage}
+% \def\headlanguage {\currentmainlanguage}
+
+% \def\labellanguage{\defaultlanguage\currentmainlanguage}
+% \def\headlanguage {\defaultlanguage\currentmainlanguage}
+
+\def\labellanguage{\reallanguagetag{\defaultlanguage\currentmainlanguage}}
+\def\headlanguage {\reallanguagetag{\defaultlanguage\currentmainlanguage}}
+
+\appendtoks \let\labellanguage\currentlanguage \to \everycurrentdate
+
+\unexpanded\def\headtext
+ {\let\handletextprefix\firstoftwoarguments
+ \let\reporttextprefixerror\doreporttextprefixerror
+ \global\labeltextdonetrue
+ \dogetupsometextprefix\headlanguage\c!title}
+
+\unexpanded\def\leftlabeltext
+ {\let\handletextprefix\firstoftwoarguments
+ \let\reporttextprefixerror\doreporttextprefixerror
+ \global\labeltextdonetrue
+ \dogetupsometextprefix\labellanguage\c!label}
+
+\unexpanded\def\rightlabeltext
+ {\let\handletextprefix\secondoftwoarguments
+ \let\reporttextprefixerror\doreporttextprefixerror
+ \global\labeltextdonetrue
+ \dogetupsometextprefix\labellanguage\c!label}
+
+\unexpanded\def\LEFTLABELTEXT
+ {\def\handletextprefix##1##2{\uppercase{##1}}\DOLABELTEXT}
+
+\unexpanded\def\RIGHTLABELTEXT
+ {\def\handletextprefix##1##2{\uppercase{##2}}\DOLABELTEXT}
+
+\def\DOLABELTEXT#1%
+ {\bgroup
+ \the\everyuppercase
+ \let\reporttextprefixerror\doreporttextprefixerror
+ \global\labeltextdonetrue
+ \dogetupsometextprefix\labellanguage\c!label{#1}% not \labeltext (see \MONTH)
+ \egroup}
+
+\let\labeltext \leftlabeltext
+\let\LABELTEXT \LEFTLABELTEXT
+
+\unexpanded\def\labeltexts#1#2{\leftlabeltext{#1}#2\rightlabeltext{#1}}
+\unexpanded\def\LABELTEXTS#1#2{\LEFTLABELTEXT{#1}#2\RIGHTLABELTEXT{#1}}
+
+\newif\iflabeltextdone % needs to be reset elsewhere
+\newif\iftracelabels % shows missing labels
+
+\def\doreporttextprefixerror#1#2#3%
+ {\iftracelabels{\tttf[#2:~#3/#1]~}\fi}
+
+\def\dosetexpandedheadlabeltext#1#2#3%
+ {\bgroup
+ \let\handletextprefix\firstoftwoarguments
+ \let\reporttextprefixerror\gobblethreearguments
+ \keepencodedtokens % test on multilingual pascal, ok in stretched
+ %\dontexpandencodedtokens % not usable in token handler
+ \expanded
+ {\egroup\noexpand\def\noexpand#2% watch out, no \edef
+ {\dogetupsometextprefix{\headlanguage}{#1}{#3}}}}
+
+\def\setexpandedheadtext {\dosetexpandedheadlabeltext\c!title}
+\def\setexpandedlabeltext{\dosetexpandedheadlabeltext\c!label}
+
+\def\dogetupsometextprefix#1#2#3% must be expandable ! #1 == language
+ {\ifcsname#2#1#3\endcsname
+ \csname#2#1#3\endcsname
+ \else\ifcsname\??la#1\s!default\endcsname
+ \expandafter\dogetupsometextprefix\csname\??la#1\s!default\endcsname{#2}{#3}%
+ \else\ifcsname#2#3\endcsname
+ \csname#2#3\endcsname
+ \else\ifcsname#1\s!en#3\endcsname
+ \csname#2\s!en#3\endcsname
+ \else
+ % \doreporttextprefixerror{#1}{#2}{#3}%
+ \fi\fi\fi\fi}
+
+\ifx\simplifiedcommands\undefined \newtoks\simplifiedcommands \fi
+
+\appendtoks
+ \let \headtext \firstofoneargument
+ \let \labeltext \firstofoneargument
+ \let \leftlabeltext \firstofoneargument
+ \let \rightlabeltext \firstofoneargument
+ \let \HEADTEXT \firstofoneargument
+ \let \LABELTEXT \firstofoneargument
+ \let \LEFTLABELTEXT \firstofoneargument
+ \let \RIGHTLABELTEXT \firstofoneargument
+\to \simplifiedcommands
+
+%D \macros
+%D {presetheadtext,presetlabeltext}
+%D
+%D The next two macros enable us to automatically define
+%D head and label texts without replacing predefined ones.
+%D These are internal macros.
+
+\def\xdopresetsometextprefix[#1][#2=#3]%
+ {\ifundefined{#1#2}\doassignsometextprefix[#1\reallanguagetag{#2}][#3,,]\fi}
+
+\def\dopresetsometextprefix
+ {\let\dodocommand\xdopresetsometextprefix
+ \dotripleempty\dodosetupsometextprefix}
+
+\def\presetheadtext {\dopresetsometextprefix[\c!title]}
+\def\presetlabeltext{\dopresetsometextprefix[\c!label]}
+
+%D \macros
+%D {translate}
+%D
+%D Sometismes macros contain language specific words that are to
+%D be typeset. Such macros can be made (more) language
+%D independant by using:
+%D
+%D \showsetup{translate}
+%D
+%D like for instance:
+%D
+%D \starttyping
+%D \translate[en=something,nl=iets]
+%D \stoptyping
+%D
+%D which expands to {\em something} or {\em iets}, depending on
+%D de current language.
+
+\def\dotranslate[#1]%
+ {\getparameters[\??lg][#1]%
+ \ifcsname\??lg\currentlanguage\endcsname
+ \csname\??lg\currentlanguage\endcsname
+ \else\ifcsname\??lg\s!en\endcsname
+ \csname\??lg\s!en\endcsname
+ \else
+ [translation #1]%
+ \fi\fi}
+
+\unexpanded\def\translate
+ {\dosingleempty\dotranslate}
+
+%D When used without argument, the last defined values are
+%D used. This enables repetitive use like
+%D
+%D \starttyping
+%D \en \translate\ means \nl \translate
+%D \stoptyping
+
+%D \macros
+%D {assigntranslation}
+%D
+%D This macro is a system macro, and can be used to assign a
+%D translation to a macro. Its form is:
+%D
+%D \starttyping
+%D \assigntranslation[en=something,nl=iets]\to\command
+%D \stoptyping
+
+\def\assigntranslation[#1]\to#2%
+ {\getparameters[\??lg][#1]%
+ \edef#2{\csname\??lg\currentlanguage\endcsname}}
+
+\protect \endinput
diff --git a/tex/context/base/lang-mis.tex b/tex/context/base/lang-mis.tex
index 41f370974..eb7bb1a04 100644
--- a/tex/context/base/lang-mis.tex
+++ b/tex/context/base/lang-mis.tex
@@ -2,7 +2,7 @@
%D [ file=lang-mis,
%D version=1997.03.20, % used to be supp-lan.tex
%D title=\CONTEXT\ Language Macros,
-%D subtitle=Language Options,
+%D subtitle=Compounds,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Language Macros / Compounds}
+\writestatus{loading}{ConTeXt Language Macros / Compounds}
%D \gdef\starttest
%D {\blank
@@ -181,7 +181,7 @@
%ifx\postwordbreak \undefined \def\postwordbreak{\penalty\zerocount \prewordbreak } \fi
\ifx\postwordbreak \undefined \def\postwordbreak{\penalty\zerocount \hskip\zeropoint\relax} \fi
-\ifx\hspaceamount \undefined \def\hspaceamount#1#2{\kern.16667em} \fi % language specific
+\ifx\hspaceamount \undefined \def\hspaceamount#1#2{.16667em} \fi % language specific
%D \macros
%D {beginofsubsentencespacing,endofsubsentencespacing}
diff --git a/tex/context/base/lang-sla.tex b/tex/context/base/lang-sla.tex
index 50ebed127..0832e3f46 100644
--- a/tex/context/base/lang-sla.tex
+++ b/tex/context/base/lang-sla.tex
@@ -32,7 +32,7 @@
% Lusatian/Sorbian/Wendish, Polish, Slovak, Albanian,
% Illyrian, Armenian
-\writestatus{loading}{Slavic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Slavic Languages}
\unprotect
@@ -77,7 +77,8 @@
\c!leftquotation=\lowerleftdoubleninequote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!day,{.},\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping={pl0,ec,qx},
+ \s!encoding={pl0,ec,qx}]
\installlanguage
[\s!cs]
@@ -91,7 +92,8 @@
\c!leftquotation=\lowerleftdoubleninequote,
\c!rightquotation=\upperrightdoublesixquote,
\c!date={\v!day,{.\,},\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping={il2,ec},
+ \s!encoding={il2,ec}]
\installlanguage
[\s!sk]
@@ -105,7 +107,8 @@
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!day,{.\,},\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping={il2,ec},
+ \s!encoding={il2,ec}]
\installlanguage
[\s!hr]
@@ -119,7 +122,8 @@
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!day,\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping=ec,
+ \s!encoding=ec]
%D The default quotation marks for Slovenian were chosen as
%D \lowerleftdoubleninequote these ones\upperrightdoublesixquote\
@@ -168,7 +172,8 @@
\c!leftquotation=\rightguillemot,
\c!rightquotation=\leftguillemot,
\c!date={\v!day,{.},\ ,\v!month,\ ,\v!year},
- \c!state=\v!stop]
+ \s!mapping=ec,
+ \s!encoding=ec]
\installlanguage [polish] [\s!pl]
\installlanguage [czech] [\s!cs]
@@ -177,6 +182,8 @@
\installlanguage [slovenian] [\s!sl]
\installlanguage [slovene] [\s!sl] % both possible (mojca: still needed?)
+\installlanguage [cz] [\s!cs]
+
% If this is really needed we should make an enco-fhr.
%
% \startlanguagespecifics[\s!hr]
@@ -443,9 +450,7 @@
% \c!rightquote=\upperrightsinglesixquote,
% \c!leftquotation=\lowerleftdoubleninequote,
% \c!rightquotation=\upperrightdoublesixquote,
-% \c!date={\v!day,\ ,\v!month,\ ,\v!year},
-% \c!state=\v!stop]
-
+% \c!date={\v!day,\ ,\v!month,\ ,\v!year}]
\setuplabeltext [\s!sl] [\v!page=stran ]
\setuplabeltext [\s!sl] [\v!atpage=na strani ]
diff --git a/tex/context/base/lang-spa.tex b/tex/context/base/lang-spa.tex
index 1ec45cd69..f6e22aa51 100644
--- a/tex/context/base/lang-spa.tex
+++ b/tex/context/base/lang-spa.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Language Macros / Spacing}
+\writestatus{loading}{ConTeXt Language Macros / Spacing}
%D This module was created in the process of enhancing
%D support for French (with the help of Daniel Flipo).
diff --git a/tex/context/base/lang-spe.tex b/tex/context/base/lang-spe.mkii
index 00b514be2..7911b0c95 100644
--- a/tex/context/base/lang-spe.tex
+++ b/tex/context/base/lang-spe.mkii
@@ -30,7 +30,7 @@
%D this is a good learning experience (catcodes, lccodes, token
%D lists, expansion, \unknown).
-\writestatus{loading}{Context Language Macros / Specifics}
+\writestatus{loading}{ConTeXt Language Macros / Specifics}
\unprotect
@@ -122,10 +122,11 @@
\def\languagespectag#1{\??la\languageencoding#1\??la}
\long\def\dosetlanguagespecifics#1#2%
- {\ifcsname\languagespectag{#2}\endcsname \else
- \expandafter\newtoks\csname\languagespectag{#2}\endcsname
+ {\edef\askedlanguagespecificstag{\languagespectag{#2}}%
+ \ifcsname\askedlanguagespecificstag\endcsname \else
+ \expandafter\newtoks\csname\askedlanguagespecificstag\endcsname
\fi
- \csname\languagespectag{#2}\endcsname\@EA{\the\csname\languagespectag{#2}\endcsname#1}%
+ \csname\askedlanguagespecificstag\endcsname\@EA{\the\csname\askedlanguagespecificstag\endcsname#1}%
\bgroup
\setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}%
\ifdim\wd\scratchbox>\zeropoint
@@ -136,9 +137,6 @@
\egroup
\doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}}
-% \def\forgetlanguagespecifics[#1]%
-% {\letvalue{\??la\languageencoding#1\??la}\empty}
-
\def\forgetlanguagespecifics[#1]%
{\csname\languagespectag{#1}\endcsname\emptytoks}
@@ -146,24 +144,28 @@
%D define \type{\do} in such a way that \type{{ }} is removed
%D and the language key is gobbled.
-\def\enablelanguagespecifics[#1]%
- {\the\executeifdefined{\??la
- \@EA\ifx\csname\??la#1\c!default\endcsname\relax
- \languageencoding
- \else
- \csname\??la#1\c!default\endcsname
- \fi
- \??la}\emptytoks
- \the\executeifdefined{\??la#1\??la}\emptytoks
- \the\executeifdefined{\??la\languageencoding#1\??la}\emptytoks} % dup ?
-
-% check:
-
% \def\enablelanguagespecifics[#1]%
-% {\the\executeifdefined{\??la\executeifdefined{\??la#1\c!default}\languageencoding\??la}\emptytoks
+% {\the\executeifdefined{\??la
+% \@EA\ifx\csname\??la#1\c!default\endcsname\relax
+% \languageencoding
+% \else
+% \csname\??la#1\c!default\endcsname
+% \fi
+% \??la}\emptytoks
% \the\executeifdefined{\??la#1\??la}\emptytoks
% \the\executeifdefined{\??la\languageencoding#1\??la}\emptytoks} % dup ?
+\def\enablelanguagespecifics[#1]%
+ {\edef\askedlanguagespecificslanguage{\defaultlanguage{#1}}%
+ \ifcsname\??la\askedlanguagespecificslanguage\??la\endcsname
+ \the\csname\??la\askedlanguagespecificslanguage\??la\endcsname
+ \fi
+ \ifx\languageencoding\empty\else
+ \ifcsname\??la\languageencoding\askedlanguagespecificslanguage\??la\endcsname
+ \the\csname\??la\languageencoding\askedlanguagespecificslanguage\??la\endcsname
+ \fi
+ \fi}
+
%D \macros
%D {deactivatelanguagespecific}
%D
diff --git a/tex/context/base/lang-spe.mkiv b/tex/context/base/lang-spe.mkiv
new file mode 100644
index 000000000..6f32888e6
--- /dev/null
+++ b/tex/context/base/lang-spe.mkiv
@@ -0,0 +1,111 @@
+%D \module
+%D [ file=lang-spe,
+%D version=2002.05.07, % 1996.01.25,
+%D title=\CONTEXT\ Language Macros,
+%D subtitle=Specifics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Language Macros / Specifics}
+
+%D In \MKIV\ we will get away from this feature. See \MKII\ file
+%D for comments. So, consider this a temporary feature.
+
+\unprotect
+
+%D \macros
+%D {everyresetlanguagespecifics,resetlanguagespecifics}
+%D
+%D Cleanup macros.
+
+\newevery \everyresetlanguagespecifics \relax
+
+\def\resetlanguagespecifics
+ {\ifcase\protectionlevel
+ \the\everyresetlanguagespecifics
+ \fi}
+
+\appendtoks
+ \resetlanguagespecifics
+\to \everycleanupfeatures
+
+%D \macros
+%D {startlanguagespecifics,enablelanguagespecifics}
+
+\def\startlanguagespecifics
+ {\bgroup
+ \catcode`\^^I=\@@ignore
+ \catcode`\^^M=\@@ignore
+ \catcode`\^^L=\@@ignore
+ \dodoubleempty\dostartlanguagespecifics} % get rid of spaces
+
+\long\def\dostartlanguagespecifics[#1][#2]#3\stoplanguagespecifics
+ {\egroup
+ \processcommalist[#1]{\dosetlanguagespecifics{#3}}}
+
+\long\def\dosetlanguagespecifics#1#2% specifics language
+ {\ifcsname\??la#2\??la\endcsname \else
+ \expandafter\newtoks\csname\??la#2\??la\endcsname
+ \fi
+ \csname\??la#2\??la\endcsname\@EA{\the\csname\??la#2\??la\endcsname#1}%
+ \bgroup
+ \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}%
+ \ifdim\wd\scratchbox>\zeropoint
+ \showmessage\m!linguals7{#2,\the\wd\scratchbox\space}\wait
+ \else
+ \showmessage\m!linguals8{#2}%
+ \fi
+ \egroup
+ \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}}
+
+\def\forgetlanguagespecifics[#1]%
+ {\ifcsname\??la#1\??la\endcsname
+ \csname\??la#1\??la\endcsname\emptytoks
+ \fi}
+
+% \def\enablelanguagespecifics[#1]% no default language fallback (yet)
+% {\ifcsname\??la#1\??la\endcsname
+% \the\csname\??la#1\??la\endcsname\relax
+% \fi}
+
+\def\enablelanguagespecifics[#1]%
+ {\edef\askedlanguagespecificslanguage{\defaultlanguage{#1}}%
+ \ifcsname\??la\askedlanguagespecificslanguage\??la\endcsname
+ \the\csname\??la\askedlanguagespecificslanguage\??la\endcsname
+ \fi}
+
+%D \macros
+%D {ordinaldaynumber, highordinalstr, ordinalstr}
+%D
+%D Efficient general ordinal number converters are sometimes
+%D difficult to implement. Fortunately dates never exceed the
+%D number~31.
+
+\ifx\high \undefined \let\high \firstofoneargument \fi % todo
+\ifx\notsmallcapped\undefined \let\notsmallcapped\firstofoneargument \fi % todo
+
+\def\highordinalstr#1{\high{\notsmallcapped{#1}}}
+\def\ordinalstr #1{\notsmallcapped{#1}}
+
+\def\ordinaldaynumber#1% \strippedcsname\ordinaldaynumber
+ {\expanded{\executeifdefined{\currentlanguage ordinaldaynumber}%
+ \noexpand\firstofoneargument{\number#1}}}
+
+%D Language specific converters have definitions like:
+%D
+%D \starttyping
+%D \def\enordinaldaynumber#1{...}
+%D \stoptyping
+%D
+%D Examples can be found in the other \type {lang} modules.
+
+\appendtoks
+ \ifprocessingXML \else \resetlanguagespecifics \fi
+\to \everylanguage
+
+\protect \endinput
diff --git a/tex/context/base/lang-ura.tex b/tex/context/base/lang-ura.tex
index 2ecb31e6b..a2bcd3d2b 100644
--- a/tex/context/base/lang-ura.tex
+++ b/tex/context/base/lang-ura.tex
@@ -13,7 +13,7 @@
% Todo: replace \'.. by \namedglyph
-\writestatus{loading}{Uralic Languages}
+\writestatus{loading}{ConTeXt Language Macros / Uralic Languages}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -42,8 +42,7 @@
\c!rightquote=\upperrightsingleninequote,
\c!leftquotation=\upperleftdoublesixquote,
\c!rightquotation=\upperrightdoubleninequote,
- \c!date={\v!year,\ ,\v!month,\ ,\v!day},
- \c!state=\v!stop]
+ \c!date={\v!year,\ ,\v!month,\ ,\v!day}]
\installlanguage
[\s!hu]
@@ -57,7 +56,6 @@
\c!leftquotation=\lowerleftdoubleninequote,
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!year,.,\ ,\v!month,\ ,\v!day,.},
- \c!state=\v!stop,
\s!mapping=ec,
\s!encoding=ec]
diff --git a/tex/context/base/lang-url.lua b/tex/context/base/lang-url.lua
index b732dcef0..1524878cf 100644
--- a/tex/context/base/lang-url.lua
+++ b/tex/context/base/lang-url.lua
@@ -6,6 +6,12 @@ if not modules then modules = { } end modules ['lang-url'] = {
license = "see context related readme files"
}
+local utf = unicode.utf8
+
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+
+local ctxcatcodes = tex.ctxcatcodes
+
commands = commands or { }
--[[
@@ -76,13 +82,13 @@ do
return "\\a{" .. u(s) .. "}"
end
end )
- tex.sprint(tex.ctxcatcodes,str)
+ tex.sprint(ctxcatcodes,str)
end
-- todo, no interface in mkiv yet
function commands.hyphenatedurl.setcharacters(str,value) -- 1, 2 == before, after
- for s in str:utfcharacters() do
+ for s in utfcharacters(str) do
chars[s] = value or 1
end
end
diff --git a/tex/context/base/lang-url.mkii b/tex/context/base/lang-url.mkii
index f3310cceb..fdf530b45 100644
--- a/tex/context/base/lang-url.mkii
+++ b/tex/context/base/lang-url.mkii
@@ -18,6 +18,29 @@
\ifx\\\undefined \let\\\crlf \fi
+%D \macros
+%D {hyphenatedurl}
+%D
+%D For those who want to put full \URL's in a text, we offer
+%D
+%D \startbuffer
+%D \hyphenatedurl{http://optimist.optimist/optimist/optimist.optimist#optimist}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D which breaks at the appropriate places. Watch the \type{#}
+%D hack.
+%D
+%D When passed as argument, like in \type {\goto}, one needs
+%D to substitute a \type {\\} for each \type{#}.
+%D
+%D \startbuffer
+%D \hyphenatedurl{http://this.is.a.rather/strange/reference#indeed}
+%D \stopbuffer
+%D
+%D \typebuffer
+
\ifx\urlsplitmode\undefined \chardef\urlsplitmode\plusone \fi
% 0 => don't split
@@ -229,4 +252,55 @@
%
% {\hsize1cm\hyphenatedstring{ABXXXXXXXXXXC-12345-12345}}
+%D \macros
+%D {hyphenatedfilename}
+%D
+%D For the moment we treat filenames in a similar way,
+%D
+%D \starttyping
+%D \hyphenatedfilename{here/there/filename.suffix}
+%D \stoptyping
+
+\ifx\hyphenatedfilename\undefined \let\hyphenatedfilename\hyphenatedurl \fi
+
+% \def\test#1%
+% {\dontleavehmode
+% \begingroup
+% \tttf
+% \hyphenatedurl {%
+% \letterampersand #1\letterampersand #1\letterampersand #1\letterampersand #1\letterampersand
+% \letterhash #1\letterhash #1\letterpercent #1\letterslash #1\letterampersand
+% }%
+% \endgroup}
+
+% \dorecurse{100}{\test{a} \test{ab} \test{abc} \test{abcd} \test{abcde} \test{abcdef}}
+
\protect \endinput
+
+% \bgroup
+
+% \gdef\lettercolon{:}
+
+% \catcode`\:=\active
+% \catcode`\^=\active
+% \catcode`\/=\active
+% \catcode`\~=\active
+
+% \gdef\theurlcolon {\nobreak\hbox{\lettercolon}\allowbreak}
+% \gdef\theurlslash#1{\nobreak\hbox{\letterslash}\ifx#1\relax\else\ifnum`/=\expandafter`\string#1\else\allowbreak\fi#1\fi}
+% \gdef\theurlhat {\allowbreak\hbox{\letterhat}\nobreak}
+% \gdef\theurltilde {\allowbreak\hbox{\lettertilde}\nobreak}
+
+% \gdef\ForMojcaWhoLikesHacks#1%
+% {\dontleavehmode
+% \begingroup
+% \mathcode`\:="8000 \let:\theurlcolon
+% \mathcode`\^="8000 \let^\theurlhat
+% \mathcode`\/="8000 \let/\theurlslash
+% \mathcode`\~="8000 \let~\theurltilde
+% \everymath\emptytoks
+% \mathsurround\zeropoint$\tf#1\relax$%
+% \endgroup}
+% \egroup
+
+% \hsize 1mm \ForMojcaWhoLikesHacks{http://www.sil.org//silesr/}
diff --git a/tex/context/base/lang-url.mkiv b/tex/context/base/lang-url.mkiv
index 7479fed68..c22f9f420 100644
--- a/tex/context/base/lang-url.mkiv
+++ b/tex/context/base/lang-url.mkiv
@@ -15,7 +15,30 @@
\unprotect
-% \urlsplitmode is not (yet) supported (not that much needed)
+%D \macros
+%D {hyphenatedurl}
+%D
+%D For those who want to put full \URL's in a text, we offer
+%D
+%D \startbuffer
+%D \hyphenatedurl{http://optimist.optimist/optimist/optimist.optimist#optimist}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D which breaks at the appropriate places. Watch the \type{#}
+%D hack.
+%D
+%D When passed as argument, like in \type {\goto}, one needs
+%D to substitute a \type {\\} for each \type{#}.
+%D
+%D \startbuffer
+%D \hyphenatedurl{http://this.is.a.rather/strange/reference#indeed}
+%D \stopbuffer
+%D
+%D \typebuffer
+
+\ifx\urlsplitmode\undefined \chardef\urlsplitmode\zerocount \fi % not supported in mkiv
\newtoks\everyhyphenatedurl
@@ -54,11 +77,34 @@
\let\n\dohyphenatedurlnormal
\let\b\dohyphenatedurlbefore
\let\a\dohyphenatedurlafter
- \expanded{\ctxlua{commands.hyphenatedurl.action(
+ \normalexpanded{\noexpand\ctxlua{commands.hyphenatedurl.action(
\!!bs\noexpand\detokenize{#1}\!!es,
\number\hyphenatedurllefthyphenmin,
\number\hyphenatedurlrighthyphenmin
)}}%
\endgroup}
+%D \macros
+%D {hyphenatedfilename}
+%D
+%D For the moment we treat filenames in a similar way,
+%D
+%D \starttyping
+%D \hyphenatedfilename{here/there/filename.suffix}
+%D \stoptyping
+
+\ifx\hyphenatedfilename\undefined \let\hyphenatedfilename\hyphenatedurl \fi
+
+% \def\test#1%
+% {\dontleavehmode
+% \begingroup
+% \tttf
+% \hyphenatedurl {%
+% \letterampersand #1\letterampersand #1\letterampersand #1\letterampersand #1\letterampersand
+% \letterhash #1\letterhash #1\letterpercent #1\letterslash #1\letterampersand
+% }%
+% \endgroup}
+
+% \dorecurse{100}{\test{a} \test{ab} \test{abc} \test{abcd} \test{abcde} \test{abcdef}}
+
\protect \endinput
diff --git a/tex/context/base/lang-url.tex b/tex/context/base/lang-url.tex
deleted file mode 100644
index 3eb891914..000000000
--- a/tex/context/base/lang-url.tex
+++ /dev/null
@@ -1,70 +0,0 @@
-%D \module
-%D [ file=lang-url,
-%D version=2008.01.22, % used to be lang-mis
-%D title=\CONTEXT\ Language Macros,
-%D subtitle=Language Options,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Language Macros / URL}
-
-\loadmarkfile{lang-url}
-
-\unprotect
-
-\ifx\urlsplitmode\undefined \chardef\urlsplitmode\zerocount \fi % not supported in mkiv
-
-%D \macros
-%D {hyphenatedurl}
-%D
-%D For those who want to put full \URL's in a text, we offer
-%D
-%D \startbuffer
-%D \hyphenatedurl{http://optimist.optimist/optimist/optimist.optimist#optimist}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D which breaks at the appropriate places. Watch the \type{#}
-%D hack.
-%D
-%D When passed as argument, like in \type {\goto}, one needs
-%D to substitute a \type {\\} for each \type{#}.
-%D
-%D \startbuffer
-%D \hyphenatedurl{http://this.is.a.rather/strange/reference#indeed}
-%D \stopbuffer
-%D
-%D \typebuffer
-
-\ifx\hyphenatedurl\undefined \let\hyphenatedurl\firstofoneargument \fi
-
-%D \macros
-%D {hyphenatedfilename}
-%D
-%D For the moment we treat filenames in a similar way,
-%D
-%D \starttyping
-%D \hyphenatedfilename{here/there/filename.suffix}
-%D \stoptyping
-
-\ifx\hyphenatedfilename\undefined \let\hyphenatedfilename\hyphenatedurl \fi
-
-% \def\test#1%
-% {\dontleavehmode
-% \begingroup
-% \tttf
-% \hyphenatedurl {%
-% \letterampersand #1\letterampersand #1\letterampersand #1\letterampersand #1\letterampersand
-% \letterhash #1\letterhash #1\letterpercent #1\letterslash #1\letterampersand
-% }%
-% \endgroup}
-
-% \dorecurse{100}{\test{a} \test{ab} \test{abc} \test{abcd} \test{abcde} \test{abcdef}}
-
-\protect \endinput
diff --git a/tex/context/base/lang-vn.tex b/tex/context/base/lang-vn.tex
index 22bbe9ff6..27d2a48a1 100644
--- a/tex/context/base/lang-vn.tex
+++ b/tex/context/base/lang-vn.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Vietnamese Language}
+\writestatus{loading}{ConTeXt Language Macros / Vietnamese Language}
%D The framework of this module is set up by Hans Hagen while
%D many of the first translations were done by Tobias. Later
@@ -37,7 +37,8 @@
\c!leftquotation=\quotedblleft,
\c!rightquotation=\quotedblright,
\c!date={{ },dd,{/},mm,{/},yy},
- \c!state=\v!stop]
+ \s!mapping=t5,
+ \s!encoding=t5]
\installlanguage [vietnamese] [\s!vi]
diff --git a/tex/context/base/luat-bas.tex b/tex/context/base/luat-bas.tex
new file mode 100644
index 000000000..a78455173
--- /dev/null
+++ b/tex/context/base/luat-bas.tex
@@ -0,0 +1,64 @@
+%D \module
+%D [ file=luat-bas, % moved from luat-lib,
+%D version=2006.09.11,
+%D title=\CONTEXT\ Lua Macros,
+%D subtitle=Basic \LUA\ Libraries,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 Lua Macros / Basic Lua Libraries}
+
+%D This will move cq. become configurable. The XML like output is just
+%D an example.
+
+% todo \let\normaleverytoks\everytoks \newtoks\everytoke \normaleverytoks{\the\everytoks}
+
+\chardef\statuswidth=15
+\chardef\statuswrite=16
+
+\newtoks\everywritestring
+
+\def\writedirect {\immediate\write\statuswrite}
+\def\writeline {\writedirect{}}
+\def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup}
+
+\ifx\normalwritestatus\undefined \def\normalwritestatus#1#2{\writedirect{#1 : #2}} \fi
+
+% Because all libs are also on bytecodes we can start without stub. However,
+% some initializations need to take place before the \TEX\ engine itself
+% kicks in, especially memory settings and so. In due time we might make the
+% stub smaller and just create a configuration startup file.
+
+\registerctxluafile{l-string} {1.001}
+\registerctxluafile{l-lpeg} {1.001}
+\registerctxluafile{l-boolean}{1.001}
+\registerctxluafile{l-number} {1.001}
+\registerctxluafile{l-math} {1.001}
+\registerctxluafile{l-table} {1.001}
+\registerctxluafile{l-aux} {1.001}
+\registerctxluafile{l-io} {1.001}
+\registerctxluafile{l-os} {1.001}
+\registerctxluafile{l-file} {1.001}
+\registerctxluafile{l-md5} {1.001}
+\registerctxluafile{l-dir} {1.001}
+\registerctxluafile{l-unicode}{1.001}
+\registerctxluafile{l-utils} {1.001}
+\registerctxluafile{l-dimen} {1.001}
+\registerctxluafile{l-url} {1.001}
+\registerctxluafile{l-set} {1.001}
+
+% \registerctxluafile{socket.lua}{}
+% \registerctxluafile{ltn12.lua} {}
+% \registerctxluafile{mime.lua} {}
+% \registerctxluafile{http.lua} {}
+% \registerctxluafile{url.lua} {}
+% \registerctxluafile{tp.lua} {}
+% \registerctxluafile{ftp.lua} {}
+% %registerctxluafile{smtp.lua} {}
+
+\endinput
diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua
index 4069fe61f..d8b508c13 100644
--- a/tex/context/base/luat-cbk.lua
+++ b/tex/context/base/luat-cbk.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['luat-cbk'] = {
license = "see context related readme files"
}
+local trace_checking = false trackers.register("memory.checking", function(v) trace_checking = v end)
+
--[[ldx--
<p>Callbacks are the real asset of <l n='luatex'/>. They permit you to hook
your own code into the <l n='tex'/> engine. Here we implement a few handy
@@ -67,7 +69,6 @@ end)
<p>This does a one-shot.</p>
--ldx]]--
-
--[[ldx--
<p>Callbacks may result in <l n='lua'/> doing some hard work
which takes time and above all resourses. Sometimes it makes
@@ -97,8 +98,8 @@ because messing aroudn with the gc is too unpredictable.</p>
garbagecollector = garbagecollector or { }
-garbagecollector.trace = false
-garbagecollector.enabled = false
+garbagecollector.enabled = false
+garbagecollector.criterium = 4*1024*1024
-- Lua allocates up to 12 times the amount of memory needed for
-- handling a string, and for large binary chunks (like chinese otf
@@ -122,13 +123,11 @@ garbagecollector.enabled = false
-- As a result of this, LuaTeX now uses an optimized version of f:read("*a"),
-- one that does not use the 4K allocations but allocates in one step.
-garbagecollector.criterium = 4*1024*1024
-
function garbagecollector.check(size,criterium)
if garbagecollector.enabled then
criterium = criterium or garbagecollector.criterium
if not size or (criterium and criterium > 0 and size > criterium) then
- if garbagecollector.trace then
+ if trace_checking then
local round = math.round or math.floor
local b = collectgarbage("count")
collectgarbage("collect")
@@ -140,5 +139,3 @@ function garbagecollector.check(size,criterium)
end
end
end
-
-
diff --git a/tex/context/base/luat-cnf.lua b/tex/context/base/luat-cnf.lua
new file mode 100644
index 000000000..9f237b981
--- /dev/null
+++ b/tex/context/base/luat-cnf.lua
@@ -0,0 +1,114 @@
+if not modules then modules = { } end modules ['luat-cnf'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, concat = string.format, table.concat
+
+luatex = luatex or { }
+
+luatex.variablenames = {
+ 'main_memory', 'extra_mem_bot', 'extra_mem_top',
+ 'buf_size','expand_depth',
+ 'font_max', 'font_mem_size',
+ 'hash_extra', 'max_strings', 'pool_free', 'pool_size', 'string_vacancies',
+ 'obj_tab_size', 'pdf_mem_size', 'dest_names_size',
+ 'nest_size', 'param_size', 'save_size', 'stack_size','expand_depth',
+ 'trie_size', 'hyph_size', 'max_in_open',
+ 'ocp_stack_size', 'ocp_list_size', 'ocp_buf_size',
+ 'max_print_line',
+}
+
+function luatex.variables()
+ local t, x = { }, nil
+ for _,v in next, luatex.variablenames do
+ x = resolvers.var_value(v)
+ if x and x:find("^%d+$") then
+ t[v] = tonumber(x)
+ end
+ end
+ return t
+end
+
+if not luatex.variables_set then
+ for k, v in next, luatex.variables() do
+ texconfig[k] = v
+ end
+ luatex.variables_set = true
+end
+
+local stub = [[
+-- checking
+
+storage = storage or {}
+luatex = luatex or {}
+
+-- as soon as possible
+
+luatex.starttime = os.gettimeofday()
+
+-- we provide our own file handling
+
+texconfig.kpse_init = false
+texconfig.shell_escape = 't'
+
+-- this will happen after the format is loaded
+
+function texconfig.init()
+
+ -- shortcut and helper
+
+ local b = lua.bytecode
+
+ local function init(start)
+ local i = start
+ while b[i] do
+ b[i]() ; b[i] = nil ; i = i + 1
+ end
+ return i - start
+ end
+
+ -- the stored tables and modules
+
+ storage.noftables = init(0)
+ storage.nofmodules = init(%s)
+
+end
+
+-- we provide a qualified path
+
+callback.register('find_format_file',function(name)
+ texconfig.formatname = name
+ return name
+end)
+
+-- done, from now on input and callbacks are internal
+]]
+
+function luatex.dumpstate(name,firsttable)
+ if tex and tex.luatexversion < 38 then
+ os.remove(name)
+ elseif true then
+ local t = {
+ "-- this file is generated, don't change it\n",
+ "-- configuration (can be overloaded later)\n"
+ }
+ for _,v in next, luatex.variablenames do
+ local tv = texconfig[v]
+ if tv then
+ t[#t+1] = format("texconfig.%s=%s",v,tv)
+ end
+ end
+ io.savedata(name,format("%s\n\n%s",concat(t,"\n"),format(stub,firsttable or 501)))
+ else
+ io.savedata(name,format(stub,firsttable or 501))
+ end
+end
+
+texconfig.kpse_init = false
+texconfig.max_print_line = 100000
+texconfig.max_in_open = 127
+texconfig.shell_escape = 't'
diff --git a/tex/context/base/luat-cod.tex b/tex/context/base/luat-cod.tex
new file mode 100644
index 000000000..07db36483
--- /dev/null
+++ b/tex/context/base/luat-cod.tex
@@ -0,0 +1,161 @@
+%D \module
+%D [ file=luat-cod,
+%D version=2005.05.26,
+%D title=\CONTEXT\ Lua Macros,
+%D subtitle=Code,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 Lua Macros / Code}
+
+%D Originally we compiled the lua files externally and loaded
+%D then at runtime, but when the amount grew, we realized that
+%D we needed away to store them in the format, which is what
+%D bytecode arrays do. And so the following is obsolete:
+%D
+%D \starttyping
+%D \chardef\ctxluaembeddingmode \plusone
+%D
+%D 0 = external compilation and loading
+%D 1 = runtime compilation and embedding
+%D \stoptyping
+%D
+%D Allocation of \LUA\ engines has changed too. The original idea
+%D was to have multiple \LUA\ instances and it worked that way for
+%D several years. Hoewver in practice we used only one engine because
+%D scripts need to share data anyway. So eventually \LUATEX\ got only
+%D one instance. Because each call is reentrant there is not much
+%D danger for crashes.
+
+\def\ctxdirectlua{\directlua\zerocount}
+\def\ctxlatelua {\latelua \zerocount}
+
+%D Take your choice \unknown
+
+\let\ctxlua \ctxdirectlua
+\let\luacode \ctxdirectlua
+\let\lateluacode \ctxlatelua
+\let\directluacode\ctxdirectlua
+
+%D Reporting the version of \LUA\ that we use is done as follows:
+
+\edef\luaversion{\ctxlua{tex.print(_VERSION)}}
+
+%D We want to define \LUA\ related things in the format but
+%D need to reload code because \LUA\ instances themselves are
+%D not dumped into the format.
+
+\newtoks\everyloadluacode
+\newtoks\everyfinalizeluacode
+
+\normaleveryjob{\the\everyloadluacode\the\everyfinalizeluacode\the\everyjob}
+
+\newif\ifproductionrun
+
+%D Here we operate in the \TEX\ catcode regime as we haven't yet defined
+%D catcode regimes. A chicken or egg problem.
+
+\long\def\startruntimeluacode#1\stopruntimeluacode % only simple code (load +init)
+ {\ifproductionrun
+ \global\let\startruntimeluacode\relax
+ \global\let\stopruntimeluacode \relax
+ \else
+ \global\everyloadluacode\expandafter{\the\everyloadluacode#1}%
+ \fi
+ #1} % maybe no interference
+
+\long\def\startruntimectxluacode#1\stopruntimectxluacode
+ {\startruntimeluacode\ctxlua{#1}\stopruntimeluacode}
+
+%D Next we load the initialization code.
+
+\startruntimectxluacode
+ environment = environment or { }
+ environment.jobname = "\jobname" % tex.jobname
+ environment.initex = \ifproductionrun false \else true \fi % tex.formatname == ""
+ environment.version = "\fmtversion"
+\stopruntimectxluacode
+
+% we start at 500, below this, we store predefined data (dumps)
+
+\newcount\luabytecodecounter \luabytecodecounter=500
+
+\startruntimectxluacode
+ lua.bytedata = lua.bytedata or { }
+\stopruntimectxluacode
+
+%D Handy when we expand:
+
+\let\stopruntimeluacode \relax
+\let\stopruntimectxluacode\relax
+
+\long\def\lastexpanded{} % todo: elsewhere we use \@@expanded
+
+\long\def\expanded#1{\long\xdef\lastexpanded{\noexpand#1}\lastexpanded}
+
+%D More code:
+
+% \def\ctxluabytecode#1% executes an already loaded chunk
+% {\ctxlua {
+% local str = ''
+% if lua.bytedata[#1] then
+% str = " from file " .. lua.bytedata[#1][1] .. " version " .. lua.bytedata[#1][2]
+% end
+% if lua.bytecode[#1] then
+% if environment.initex then
+% texio.write_nl("bytecode: executing blob " .. "#1" .. str)
+% assert(lua.bytecode[#1])()
+% else
+% texio.write_nl("bytecode: initializing blob " .. "#1" .. str)
+% assert(lua.bytecode[#1])()
+% lua.bytecode[#1] = nil
+% end
+% else
+% texio.write_nl("bytecode: invalid blob " .. "#1" .. str)
+% end
+% }}
+
+\def\ctxluabytecode#1% executes an already loaded chunk
+ {\ctxlua {
+ local lbc = lua.bytecode
+ if lbc[#1] then
+ assert(lbc[#1])()
+ if not environment.initex then
+ lbc[#1] = nil
+ end
+ end
+ }}
+
+\def\ctxluabyteload#1#2% registers and compiles chunk
+ {\global\advance\luabytecodecounter \plusone
+ \expanded{\startruntimectxluacode
+ lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" }
+ \stopruntimectxluacode}%
+ \ctxlua {
+ lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" }
+ lua.bytecode[\the\luabytecodecounter] = environment.luafilechunk("#1")
+ }}
+
+\def\ctxloadluafile#1#2% load a (either not compiled) chunk at runtime
+ {\doifelsenothing{#2}
+ {\ctxlua{environment.loadluafile("#1")}}
+ {\ctxlua{environment.loadluafile("#1",#2)}}}
+
+\def\registerctxluafile#1#2% name version
+ {\ifproductionrun
+ \ctxloadluafile{#1}{#2}%
+ \else
+ \ctxluabyteload{#1}{#2}% can go away
+ \fi
+ \global\everyloadluacode\expandafter\expandafter\expandafter{\expandafter\the\expandafter\everyloadluacode
+ \expandafter\ctxluabytecode\expandafter{\the\luabytecodecounter}}%
+ \ctxluabytecode{\the\luabytecodecounter}}
+
+\everydump\expandafter{\the\everydump\ctxlua{luatex.dumpstate(environment.jobname..".lui",501)}}
+
+\endinput
diff --git a/tex/context/base/luat-crl.lua b/tex/context/base/luat-crl.lua
deleted file mode 100644
index 5ebd62d22..000000000
--- a/tex/context/base/luat-crl.lua
+++ /dev/null
@@ -1,53 +0,0 @@
--- filename : luat-crl.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['luat-crl'] = 1.001
-if not curl then curl = { } end
-
-curl.cached = { }
-curl.cachepath = caches.definepath("curl")
-
-function curl.fetch(protocol, name)
- local cachename = curl.cachepath() .. "/" .. name:gsub("[^%a%d%.]+","-")
--- cachename = cachename:gsub("[\\/]", io.fileseparator)
- cachename = cachename:gsub("[\\]", "/")
- if not curl.cached[name] then
- if not io.exists(cachename) then
- curl.cached[name] = cachename
- local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name -- no protocol .. "://"
- os.spawn(command)
- end
- if io.exists(cachename) then
- curl.cached[name] = cachename
- else
- curl.cached[name] = ""
- end
- end
- return curl.cached[name]
-end
-
-function input.finders.curl(protocol,filename)
- local foundname = curl.fetch(protocol, filename)
- return input.finders.generic(protocol,foundname,filetype)
-end
-function input.openers.curl(protocol,filename)
- return input.openers.generic(protocol,filename)
-end
-function input.loaders.curl(protocol,filename)
- return input.loaders.generic(protocol,filename)
-end
-
--- todo: metamethod
-
-function curl.install(protocol)
- input.finders[protocol] = function (filename,filetype) return input.finders.curl(protocol,filename) end
- input.openers[protocol] = function (filename) return input.openers.curl(protocol,filename) end
- input.loaders[protocol] = function (filename) return input.loaders.curl(protocol,filename) end
-end
-
-curl.install('http')
-curl.install('https')
-curl.install('ftp')
diff --git a/tex/context/base/luat-dum.lua b/tex/context/base/luat-dum.lua
new file mode 100644
index 000000000..f2ff50577
--- /dev/null
+++ b/tex/context/base/luat-dum.lua
@@ -0,0 +1,60 @@
+if not modules then modules = { } end modules ['luat-dum'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local dummyfunction = function() end
+
+statistics = {
+ register = dummyfunction,
+ starttiming = dummyfunction,
+ stoptiming = dummyfunction,
+}
+trackers = {
+ register = dummyfunction,
+ enable = dummyfunction,
+ disable = dummyfunction,
+}
+storage = {
+ register = dummyfunction,
+ shared = { },
+}
+logs = {
+ report = dummyfunction,
+ simple = dummyfunction,
+}
+tasks = {
+ new = dummyfunction,
+ actions = dummyfunction,
+ appendaction = dummyfunction,
+ prependaction = dummyfunction,
+}
+
+-- we need to cheat a bit here
+
+texconfig.kpse_init = true
+
+resolvers = resolvers or { } -- no fancy file helpers used
+
+local remapper = {
+ otf = "opentype fonts",
+ ttf = "truetype fonts",
+ ttc = "truetype fonts",
+ cid = "other text files", -- will become "cid files"
+}
+
+function resolvers.find_file(name,kind)
+ name = string.gsub(name,"\\","\/")
+ kind = string.lower(kind)
+ return kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or "tex")
+end
+
+function resolvers.findbinfile(name,kind)
+ if not kind or kind == "" then
+ kind = file.extname(name) -- string.match(name,"%.([^%.]-)$")
+ end
+ return resolvers.find_file(name,(kind and remapper[kind]) or kind)
+end
diff --git a/tex/context/base/luat-env.lua b/tex/context/base/luat-env.lua
index 67e2f7050..9c05b249c 100644
--- a/tex/context/base/luat-env.lua
+++ b/tex/context/base/luat-env.lua
@@ -1,50 +1,217 @@
--- filename : luat-env.lua
--- comment : companion to luat-env.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['luat-env'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
--- here we don't assume any extra libraries
-
--- A former version provides functionality for non embeded core
+-- A former version provided functionality for non embeded core
-- scripts i.e. runtime library loading. Given the amount of
-- Lua code we use now, this no longer makes sense. Much of this
--- evolved before bytecode arrays were available. Much code has
--- disappeared already.
+-- evolved before bytecode arrays were available and so a lot of
+-- code has disappeared already.
-if not versions then versions = { } end versions['luat-env'] = 1.001
+local trace_verbose = false trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v trackers.enable("resolvers.verbose") end)
--- environment
+local format = string.format
+
+-- precautions
+
+os.setlocale(nil,nil) -- useless feature and even dangerous in luatex
+
+function os.setlocale()
+ -- no way you can mess with it
+end
-if not environment then environment = { } end
+-- dirty tricks
-environment.trace = false
+if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
+ arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
+end
+
+if profiler and os.env["MTX_PROFILE_RUN"] == "YES" then
+ profiler.start("luatex-profile.log")
+end
+
+-- environment
--- kpse is overloaded by this time
+environment = environment or { }
+environment.arguments = { }
+environment.files = { }
+environment.sortedflags = nil
if not environment.jobname or environment.jobname == "" then if tex then environment.jobname = tex.jobname end end
if not environment.version or environment.version == "" then environment.version = "unknown" end
+if not environment.jobname then environment.jobname = "unknown" end
+
+function environment.initialize_arguments(arg)
+ local arguments, files = { }, { }
+ environment.arguments, environment.files, environment.sortedflags = arguments, files, nil
+ for index, argument in pairs(arg) do
+ if index > 0 then
+ local flag, value = argument:match("^%-+(.+)=(.-)$")
+ if flag then
+ arguments[flag] = string.unquote(value or "")
+ else
+ flag = argument:match("^%-+(.+)")
+ if flag then
+ arguments[flag] = true
+ else
+ files[#files+1] = argument
+ end
+ end
+ end
+ end
+ environment.ownname = environment.ownname or arg[0] or 'unknown.lua'
+end
+
+function environment.setargument(name,value)
+ environment.arguments[name] = value
+end
+
+-- todo: defaults, better checks e.g on type (boolean versus string)
+--
+-- tricky: too many hits when we support partials unless we add
+-- a registration of arguments so from now on we have 'partial'
+
+function environment.argument(name,partial)
+ local arguments, sortedflags = environment.arguments, environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags = { }
+ for _,v in pairs(table.sortedkeys(arguments)) do
+ sortedflags[#sortedflags+1] = "^" .. v
+ end
+ environment.sortedflags = sortedflags
+ end
+ -- example of potential clash: ^mode ^modefile
+ for _,v in ipairs(sortedflags) do
+ if name:find(v) then
+ return arguments[v:sub(2,#v)]
+ end
+ end
+ end
+ return nil
+end
+
+function environment.split_arguments(separator) -- rather special, cut-off before separator
+ local done, before, after = false, { }, { }
+ for _,v in ipairs(environment.original_arguments) do
+ if not done and v == separator then
+ done = true
+ elseif done then
+ after[#after+1] = v
+ else
+ before[#before+1] = v
+ end
+ end
+ return before, after
+end
+
+function environment.reconstruct_commandline(arg,noquote)
+ arg = arg or environment.original_arguments
+ if noquote and #arg == 1 then
+ local a = arg[1]
+ a = resolvers.resolve(a)
+ a = a:unquote()
+ return a
+ elseif next(arg) then
+ local result = { }
+ for _,a in ipairs(arg) do -- ipairs 1 .. #n
+ a = resolvers.resolve(a)
+ a = a:unquote()
+ a = a:gsub('"','\\"') -- tricky
+ if a:find(" ") then
+ result[#result+1] = a:quote()
+ else
+ result[#result+1] = a
+ end
+ end
+ return table.join(result," ")
+ else
+ return ""
+ end
+end
+
+if arg then
+
+ -- new, reconstruct quoted snippets (maybe better just remnove the " then and add them later)
+ local newarg, instring = { }, false
+
+ for index, argument in ipairs(arg) do
+ if argument:find("^\"") then
+ newarg[#newarg+1] = argument:gsub("^\"","")
+ if not argument:find("\"$") then
+ instring = true
+ end
+ elseif argument:find("\"$") then
+ newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","")
+ instring = false
+ elseif instring then
+ newarg[#newarg] = newarg[#newarg] .. " " .. argument
+ else
+ newarg[#newarg+1] = argument
+ end
+ end
+ for i=1,-5,-1 do
+ newarg[i] = arg[i]
+ end
+
+ environment.initialize_arguments(newarg)
+ environment.original_arguments = newarg
+ environment.raw_arguments = arg
+
+ arg = { } -- prevent duplicate handling
+
+end
+
+-- weird place ... depends on a not yet loaded module
function environment.texfile(filename)
- return input.find_file(filename,'tex')
+ return resolvers.find_file(filename,'tex')
end
function environment.luafile(filename)
- return input.find_file(filename,'tex') or input.find_file(filename,'texmfscripts')
+ local resolved = resolvers.find_file(filename,'tex') or ""
+ if resolved ~= "" then
+ return resolved
+ end
+ resolved = resolvers.find_file(filename,'texmfscripts') or ""
+ if resolved ~= "" then
+ return resolved
+ end
+ return resolvers.find_file(filename,'luatexlibs') or ""
end
-if not environment.jobname then environment.jobname = "unknown" end
-
environment.loadedluacode = loadfile -- can be overloaded
+--~ function environment.loadedluacode(name)
+--~ if os.spawn("texluac -s -o texluac.luc " .. name) == 0 then
+--~ local chunk = loadstring(io.loaddata("texluac.luc"))
+--~ os.remove("texluac.luc")
+--~ return chunk
+--~ else
+--~ environment.loadedluacode = loadfile -- can be overloaded
+--~ return loadfile(name)
+--~ end
+--~ end
+
function environment.luafilechunk(filename) -- used for loading lua bytecode in the format
filename = file.replacesuffix(filename, "lua")
local fullname = environment.luafile(filename)
if fullname and fullname ~= "" then
- input.report("loading file %s", fullname)
+ if trace_verbose then
+ logs.report("fileio","loading file %s", fullname)
+ end
return environment.loadedluacode(fullname)
else
- input.report("unknown file %s", filename)
+ if trace_verbose then
+ logs.report("fileio","unknown file %s", filename)
+ end
return nil
end
end
@@ -62,7 +229,9 @@ function environment.loadluafile(filename, version)
-- when not overloaded by explicit suffix we look for a luc file first
local fullname = (lucname and environment.luafile(lucname)) or ""
if fullname ~= "" then
- input.report("loading %s", fullname)
+ if trace_verbose then
+ logs.report("fileio","loading %s", fullname)
+ end
chunk = loadfile(fullname) -- this way we don't need a file exists check
end
if chunk then
@@ -78,7 +247,9 @@ function environment.loadluafile(filename, version)
if v == version then
return true
else
- input.report("version mismatch for %s: lua=%s, luc=%s", filename, v, version)
+ if trace_verbose then
+ logs.report("fileio","version mismatch for %s: lua=%s, luc=%s", filename, v, version)
+ end
environment.loadluafile(filename)
end
else
@@ -87,10 +258,14 @@ function environment.loadluafile(filename, version)
end
fullname = (luaname and environment.luafile(luaname)) or ""
if fullname ~= "" then
- input.report("loading %s", fullname)
+ if trace_verbose then
+ logs.report("fileio","loading %s", fullname)
+ end
chunk = loadfile(fullname) -- this way we don't need a file exists check
if not chunk then
- input.report("unknown file %s", filename)
+ if verbose then
+ logs.report("fileio","unknown file %s", filename)
+ end
else
assert(chunk)()
return true
@@ -98,82 +273,3 @@ function environment.loadluafile(filename, version)
end
return false
end
-
--- -- -- the next function was posted by Peter Cawley on the lua list -- -- --
--- -- -- -- -- --
--- -- -- stripping makes the compressed format file about 1MB smaller -- -- --
--- -- -- -- -- --
--- -- -- using this trick is at your own risk -- -- --
--- -- -- -- -- --
--- -- -- this is just an experiment, this feature may disappear -- -- --
-
-local function strip_code(dump)
- local version, format, endian, int, size, ins, num = dump:byte(5, 11)
- local subint
- if endian == 1 then
- subint = function(dump, i, l)
- local val = 0
- for n = l, 1, -1 do
- val = val * 256 + dump:byte(i + n - 1)
- end
- return val, i + l
- end
- else
- subint = function(dump, i, l)
- local val = 0
- for n = 1, l, 1 do
- val = val * 256 + dump:byte(i + n - 1)
- end
- return val, i + l
- end
- end
- local strip_function
- strip_function = function(dump)
- local count, offset = subint(dump, 1, size)
- local stripped, dirty = string.rep("\0", size), offset + count
- offset = offset + count + int * 2 + 4
- offset = offset + int + subint(dump, offset, int) * ins
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- local t
- t, offset = subint(dump, offset, 1)
- if t == 1 then
- offset = offset + 1
- elseif t == 4 then
- offset = offset + size + subint(dump, offset, size)
- elseif t == 3 then
- offset = offset + num
- end
- end
- count, offset = subint(dump, offset, int)
- stripped = stripped .. dump:sub(dirty, offset - 1)
- for n = 1, count do
- local proto, off = strip_function(dump:sub(offset, -1))
- stripped, offset = stripped .. proto, offset + off - 1
- end
- offset = offset + subint(dump, offset, int) * int + int
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size + int * 2
- end
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size
- end
- stripped = stripped .. string.rep("\0", int * 3)
- return stripped, offset
- end
- return dump:sub(1,12) .. strip_function(dump:sub(13,-1))
-end
-
-environment.stripcode = false -- true
-
-function environment.loadedluacode(fullname)
- if environment.stripcode then
- return loadstring(strip_code(string.dump(loadstring(io.loaddata(fullname)))))
- else
- return loadfile(fullname)
- end
-end
-
--- -- end of stripping code -- --
diff --git a/tex/context/base/luat-env.tex b/tex/context/base/luat-env.tex
deleted file mode 100644
index 164be174c..000000000
--- a/tex/context/base/luat-env.tex
+++ /dev/null
@@ -1,172 +0,0 @@
-%D \module
-%D [ file=luat-env,
-%D version=2005.05.26,
-%D title=\CONTEXT\ Lua Macros,
-%D subtitle=ConTeXt features,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright=PRAGMA]
-%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 Originally we compiled the lua files externally and loaded
-%D then at runtime, but when the amount grew, we realized that
-%D we needed away to store them in the format, which is what
-%D bytecode arrays do. And so the following is obsolete:
-%D
-%D \starttyping
-%D \chardef\ctxluaembeddingmode \plusone
-%D
-%D 0 = external compilation and loading
-%D 1 = runtime compilation and embedding
-%D \stoptyping
-
-% \writestatus{loading}{Lua Support Macros (environment)}
-
-% print (lua.id)
-% print (lua.version)
-% print (lua.startupfile)
-
-%D Allocation of \LUA\ engines.
-
-\newcount\luadefcounter
-
-\ifx\zerocount\undefined \chardef\zerocount=0 \fi
-\ifx\plusone \undefined \chardef\plusone =1 \fi
-
-\def\newlua#1%
- {\global\advance\luadefcounter\plusone
- \mathchardef#1\luadefcounter}
-
-%D We use a dedicated instance for \CONTEXT\ core functionality. In
-%D \CONTEXT we also use this as callback instance. Instance 0 is
-%D the scratch instance.
-
-\ifx\luastartup\undefined \newcount\luastartup \fi
-
-\chardef\CTXlua\zerocount \luadefcounter\CTXlua \luastartup\CTXlua
-
-\def\ctxdirectlua{\directlua\CTXlua} \let\ctxlua\ctxdirectlua
-\def\ctxlatelua {\latelua \CTXlua}
-
-%D The simple \type {\lua} command is just a shortcut to the
-%D zero instance. Beware, we don't use the 0--9 range for
-%D scratch purposes as we do with other registers. First of all
-%D we want to avoid the overhead, but mostly, users can just define
-%D their own.
-
-\newlua \luadefault
-
-\def \lua {\directlua\luadefault} % zero is the main one, and reserved for ctx
-\edef\luaversion{\ctxlua{tex.print(_VERSION)}}
-
-%D We want to define \LUA\ related things in the format but
-%D need to reluad code because \LUA\ instances are not dumped
-%D into the format.
-
-\ifx\undefined\normaleveryjob \let\normaleveryjob\everyjob \newtoks\everyjob \fi
-
-\newtoks\everyloadluacode
-\newtoks\everyfinalizeluacode
-
-\normaleveryjob{\the\everyloadluacode\the\everyfinalizeluacode\the\everyjob}
-
-\newif\ifproductionrun
-
-\long\def\startruntimeluacode#1\stopruntimeluacode % only simple code (load +init)
- {\ifproductionrun
- \global\let\startruntimeluacode\relax
- \global\let\stopruntimeluacode \relax
- \else
- \global\everyloadluacode\expandafter{\the\everyloadluacode#1}%
- \fi
- #1} % maybe no interference
-
-\long\def\startruntimectxluacode#1\stopruntimectxluacode
- {\startruntimeluacode\ctxlua{#1}\stopruntimeluacode}
-
-%D Next we load the initialization code.
-
-\startruntimectxluacode
- environment = environment or { }
- environment.jobname = "\jobname" % tex.jobname
- environment.initex = \ifproductionrun false \else true \fi % tex.formatname == ""
- environment.version = "\contextversion"
-\stopruntimectxluacode
-
-\chardef\ctxluaexecutionmode \zerocount % private
-
-% we start at 500, below this, we store predefined data (dumps)
-
-\newcount\luabytecodecounter \luabytecodecounter=500
-
-\startruntimectxluacode
- if not lua.bytedata then lua.bytedata = { } end
-\stopruntimectxluacode
-
-%D Handy when we expand:
-
-\let\stopruntimeluacode \relax
-\let\stopruntimectxluacode\relax
-
-\ifx\normalprotected \undefined \let\normalprotected \protected \fi
-\ifx\normalunexpanded\undefined \let\normalunexpanded\unexpanded \fi
-\ifx\normalexpanded \undefined \let\normalexpanded \expanded \fi
-
-\long\def\lastexpanded{} % todo: elsewhere we use \@@expanded
-
-\long\def\expanded#1{\long\xdef\lastexpanded{\noexpand#1}\lastexpanded}
-
-%D More code:
-
-\def\ctxluabytecode#1% executes an already loaded chunk
- {\ctxlua {
- do
- local str = ''
- if lua.bytedata[#1] then
- str = " from file " .. lua.bytedata[#1][1] .. " version " .. lua.bytedata[#1][2]
- end
- if lua.bytecode[#1] then
- if environment.initex then
- % logs.report("bytecode","executing blob " .. "#1" .. str)
- assert(lua.bytecode[#1])()
- else
- assert(lua.bytecode[#1])()
- lua.bytecode[#1] = nil
- end
- else
- % logs.report("bytecode", "invalid blob " .. "#1" .. str)
- end
- end
- }}
-
-\def\ctxluabyteload#1#2% registers and compiles chunk
- {\global\advance\luabytecodecounter \plusone
- \expanded{\startruntimectxluacode
- lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" }
- \stopruntimectxluacode}%
- \ctxlua {
- lua.bytedata[\the\luabytecodecounter] = { "#1", "#2" }
- lua.bytecode[\the\luabytecodecounter] = environment.luafilechunk("#1")
- }}
-
-\def\ctxloadluafile#1#2% load a (either not compiled) chunk at runtime
- {\doifelsenothing{#2}
- {\ctxlua{environment.loadluafile("#1")}}
- {\ctxlua{environment.loadluafile("#1",#2)}}}
-
-\def\registerctxluafile#1#2% name version
- {\ifproductionrun \else
- \ctxluabyteload{#1}{#2}%
- \fi
- \global\everyloadluacode\expandafter\expandafter\expandafter{\expandafter\the\expandafter\everyloadluacode
- \expandafter\ctxluabytecode\expandafter{\the\luabytecodecounter}}%
- \ifcase\ctxluaexecutionmode\or\ctxluabytecode{\the\luabytecodecounter}\fi}
-
-\registerctxluafile{luat-env}{1.001}
-
-\chardef\ctxluaexecutionmode \plusone
-
-\endinput
diff --git a/tex/context/base/luat-exe.lua b/tex/context/base/luat-exe.lua
index c2245d568..fd93ad382 100644
--- a/tex/context/base/luat-exe.lua
+++ b/tex/context/base/luat-exe.lua
@@ -1,10 +1,11 @@
--- filename : luat-exe.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['luat-exe'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['luat-exe'] = 1.001
if not executer then executer = { } end
executer.permitted = { }
diff --git a/tex/context/base/luat-fio.lua b/tex/context/base/luat-fio.lua
new file mode 100644
index 000000000..3f42b4497
--- /dev/null
+++ b/tex/context/base/luat-fio.lua
@@ -0,0 +1,81 @@
+if not modules then modules = { } end modules ['luat-fio'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local texiowrite_nl = (texio and texio.write_nl) or print
+local texiowrite = (texio and texio.write) or print
+
+local format = string.format
+
+texconfig.kpse_init = false
+texconfig.trace_file_names = true -- also influences pdf fonts reporting .. todo
+texconfig.max_print_line = 100000
+
+kpse = { } setmetatable(kpse, { __index = function(k,v) return input[v] end } )
+
+-- if still present, we overload kpse (put it off-line so to say)
+
+if not resolvers.instance then
+
+ resolvers.reset()
+
+ resolvers.instance.progname = 'context'
+ resolvers.instance.engine = 'luatex'
+ resolvers.instance.validfile = resolvers.validctxfile
+
+ resolvers.load()
+
+ if callback then
+
+ callback.register('find_read_file' , function(id,name) return resolvers.findtexfile(name) end)
+ callback.register('open_read_file' , function( name) return resolvers.opentexfile(name) end)
+
+ callback.register('find_data_file' , function(name) return resolvers.findbinfile(name,"tex") end)
+ callback.register('find_enc_file' , function(name) return resolvers.findbinfile(name,"enc") end)
+ callback.register('find_font_file' , function(name) return resolvers.findbinfile(name,"tfm") end)
+ callback.register('find_format_file' , function(name) return resolvers.findbinfile(name,"fmt") end)
+ callback.register('find_image_file' , function(name) return resolvers.findbinfile(name,"tex") end)
+ callback.register('find_map_file' , function(name) return resolvers.findbinfile(name,"map") end)
+ callback.register('find_ocp_file' , function(name) return resolvers.findbinfile(name,"ocp") end)
+ callback.register('find_opentype_file' , function(name) return resolvers.findbinfile(name,"otf") end)
+ callback.register('find_output_file' , function(name) return name end)
+ callback.register('find_pk_file' , function(name) return resolvers.findbinfile(name,"pk") end)
+ callback.register('find_sfd_file' , function(name) return resolvers.findbinfile(name,"sfd") end)
+ callback.register('find_truetype_file' , function(name) return resolvers.findbinfile(name,"ttf") end)
+ callback.register('find_type1_file' , function(name) return resolvers.findbinfile(name,"pfb") end)
+ callback.register('find_vf_file' , function(name) return resolvers.findbinfile(name,"vf") end)
+
+ callback.register('read_data_file' , function(file) return resolvers.loadbinfile(file,"tex") end)
+ callback.register('read_enc_file' , function(file) return resolvers.loadbinfile(file,"enc") end)
+ callback.register('read_font_file' , function(file) return resolvers.loadbinfile(file,"tfm") end)
+ -- format
+ -- image
+ callback.register('read_map_file' , function(file) return resolvers.loadbinfile(file,"map") end)
+ callback.register('read_ocp_file' , function(file) return resolvers.loadbinfile(file,"ocp") end)
+ -- callback.register('read_opentype_file' , function(file) return resolvers.loadbinfile(file,"otf") end)
+ -- output
+ callback.register('read_pk_file' , function(file) return resolvers.loadbinfile(file,"pk") end)
+ callback.register('read_sfd_file' , function(file) return resolvers.loadbinfile(file,"sfd") end)
+ -- callback.register('read_truetype_file' , function(file) return resolvers.loadbinfile(file,"ttf") end)
+ -- callback.register('read_type1_file' , function(file) return resolvers.loadbinfile(file,"pfb") end)
+ callback.register('read_vf_file' , function(file) return resolvers.loadbinfile(file,"vf" ) end)
+
+ callback.register('find_font_file' , function(name) return resolvers.findbinfile(name,"ofm") end)
+ callback.register('read_font_file' , function(file) return resolvers.loadbinfile(file,"ofm") end)
+ callback.register('find_vf_file' , function(name) return resolvers.findbinfile(name,"ovf") end)
+ callback.register('read_vf_file' , function(file) return resolvers.loadbinfile(file,"ovf") end)
+
+ callback.register('find_write_file' , function(id,name) return name end)
+ callback.register('find_format_file' , function(name) return name end)
+
+ end
+
+end
+
+statistics.register("input load time", function()
+ return format("%s seconds", statistics.elapsedtime(resolvers.instance))
+end)
diff --git a/tex/context/base/luat-ini.lua b/tex/context/base/luat-ini.lua
index 092593541..d9f39e61b 100644
--- a/tex/context/base/luat-ini.lua
+++ b/tex/context/base/luat-ini.lua
@@ -6,15 +6,25 @@ if not modules then modules = { } end modules ['luat-ini'] = {
license = "see context related readme files"
}
+--~ local ctxcatcodes = tex.ctxcatcodes
+
--[[ldx--
<p>We cannot load anything yet. However what we will do us reserve a fewtables.
These can be used for runtime user data or third party modules and will not be
cluttered by macro package code.</p>
--ldx]]--
-userdata = userdata or { }
-thirddata = thirddata or { }
-document = document or { }
+userdata = userdata or { } -- might be used
+thirddata = thirddata or { } -- might be used
+moduledata = moduledata or { } -- might be used
+document = document or { }
+
+--[[ldx--
+<p>These can be used/set by the caller program; <t>mtx-context.lua</t> does it.</p>
+--ldx]]--
+
+document.arguments = document.arguments or { }
+document.files = document.files or { }
--[[ldx--
<p>Please create a namespace within these tables before using them!</p>
@@ -24,3 +34,116 @@ userdata ['my.name'] = { }
thirddata['tricks' ] = { }
</typing>
--ldx]]--
+
+--[[ldx--
+<p>We could cook up a readonly model for global tables but it
+makes more sense to invite users to use one of the predefined
+namespaces. One can redefine the protector. After all, it's
+just a lightweight suggestive system, not a watertight
+one.</p>
+--ldx]]--
+
+local string, table, lpeg, math, io, system = string, table, lpeg, math, io, system
+local next, setfenv = next, setfenv
+local format = string.format
+
+local global = _G
+
+global.global = global
+
+local dummy = function() end
+
+local protected = {
+ -- global table
+ global = global,
+ -- user tables
+ userdata = userdata,
+ moduledata = moduledata,
+ thirddata = thirddata,
+ document = document,
+ -- reserved
+ protect = dummy,
+ unprotect = dummy,
+ -- luatex
+ tex = tex,
+ -- lua
+ string = string,
+ table = table,
+ lpeg = lpeg,
+ math = math,
+ io = io,
+ system = system,
+}
+
+userdata, thirddata, moduledata = nil, nil, nil
+
+function protect(name)
+ if name == "isolateddata" then
+ local t = { }
+ for k, v in next, protected do
+ t[k] = v
+ end
+ setfenv(2,t)
+ else
+ if not name then
+ name = "shareddata"
+ end
+ local t = global[name]
+ if not t then
+ t = { }
+ for k, v in next, protected do
+ t[k] = v
+ end
+ global[name] = t
+ end
+ setfenv(2,t)
+ end
+end
+
+lua.numbers = { }
+lua.messages = { }
+
+function lua.registername(name,message)
+ local lnn = lua.numbers[name]
+ if not lnn then
+ lnn = #lua.messages + 1
+ lua.messages[lnn] = message
+ lua.numbers[name] = lnn
+ end
+ lua.name[lnn] = message
+ tex.write(lnn)
+end
+
+--~ function lua.checknames()
+--~ lua.name[0] = "ctx"
+--~ for k, v in next, lua.messages do
+--~ lua.name[k] = v
+--~ end
+--~ end
+
+storage.register("lua/numbers", lua.numbers, "lua.numbers")
+storage.register("lua/messages", lua.messages, "lua.messages")
+
+function document.setargument(key,value)
+ document.arguments[key] = value
+end
+
+function document.setdefaultargument(key,default)
+ local v = document.arguments[key]
+ if v == nil or v == "" then
+ document.arguments[key] = default
+ end
+end
+
+function document.getargument(key,default)
+ local v = document.arguments[key]
+ if type(v) == "boolean" then
+ v = (v and "yes") or "no"
+ document.arguments[key] = v
+ end
+ tex.sprint(tex.ctxcatcodes,v or default or "")
+end
+
+function document.getfilename(i)
+ tex.sprint(tex.ctxcatcodes,document.files[i] or "")
+end
diff --git a/tex/context/base/luat-ini.tex b/tex/context/base/luat-ini.tex
index 1e1e20ebe..265f1b643 100644
--- a/tex/context/base/luat-ini.tex
+++ b/tex/context/base/luat-ini.tex
@@ -11,15 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Lua Support Macros (initialization)}
+\writestatus{loading}{ConTeXt Lua Macros / Initialization}
\unprotect
-%D We have to load this module in a very early stage. Therefore we
-%D cannot rely on support macros being available.
-
-% \long\def\rescan#1{\expanded{\scantextokens{#1}}}
-
%D Loading lua code can be done using \type {startup.lua}. The following
%D method uses the \TEX\ input file locator of kpse. At least we need to
%D use that way of loading when we haven't yet define our own code, which
@@ -30,36 +25,27 @@
\ifx\obeylualines \undefined \let\obeylualines \relax \fi
\ifx\obeyluatokens \undefined \let\obeyluatokens \relax \fi
-% \def\loadluacode#1#2% instance filename
-% {\bgroup
-% \everyeof{\noexpand}% hack to make \input nicely expandable
-% \setnaturalcatcodes
-% \obeylualines
-% %message{[Lua Load: #2]}%
-% \directlua#1\expandafter{\normalinput#2\space}\relax
-% \egroup}
-
%D A few more goodies:
-\long\def\dostartlua#1%
+\long\def\dostartlua
{\begingroup
\obeylualines
- \dodostartlua{#1}}
+ \dodostartlua}
-\long\def\dodostartlua#1#2\stoplua
- {\expanded{\endgroup\noexpand\directlua#1{#2}}}
+\long\def\dodostartlua#1\stoplua
+ {\normalexpanded{\endgroup\noexpand\directlua\zerocount{#1}}}
-\long\def\dostartluacode#1%
+\long\def\dostartluacode
{\begingroup
\obeylualines
\obeyluatokens
- \dodostartluacode{#1}}
+ \dodostartluacode}
-\long\def\dodostartluacode#1#2\stopluacode
- {\expanded{\endgroup\noexpand\directlua#1{#2}}}
+\long\def\dodostartluacode#1\stopluacode
+ {\normalexpanded{\endgroup\noexpand\directlua\zerocount{#1}}}
-\def\startlua {\dostartlua \zerocount}
-\def\startluacode{\dostartluacode\zerocount}
+\def\startlua {\dostartlua } % tex catcodes
+\def\startluacode{\dostartluacode} % lua catcodes
%D Some delayed definitions:
@@ -69,40 +55,164 @@
\ifx\obeyedspace \undefined \let\obeyedspace \relax \fi
\ifx\outputnewlinechar\undefined \let\outputnewlinechar\relax \fi
-\def\obeylualines
- {\obeylines \let\obeyedline \outputnewlinechar
- \obeyspaces \let\obeyedspace\space}
-
-\def\obeyluatokens % todo: make this a proper catcode table, use let's
- {\catcode`\%=12 \catcode`\#=12
- \catcode`\_=12 \catcode`\^=12
- \catcode`\&=12 \catcode`\|=12
- \catcode`\{=12 \catcode`\}=12
- \catcode`\~=12 \catcode`\$=12
- \def\\{\string\\}\def\|{\string\|}\def\-{\string\-}%
- \def\({\string\(}\def\){\string\)}\def\{{\string\{}\def\}{\string\}}%
- \def\'{\string\'}\def\"{\string\"}%
- \def\n{\string\n}\def\r{\string\r}\def\f{\string\f}\def\t{\string\t}%
- \def\a{\string\a}\def\b{\string\b}\def\v{\string\v}\def\s{\string\s}%
- \def\1{\string1}\def\2{\string2}\def\3{\string3}\def\4{\string\4}\def\5{\string\5}%
- \def\6{\string6}\def\7{\string7}\def\8{\string8}\def\9{\string\9}\def\0{\string\0}}
-
+%D A previous version used a bit less code and no catcode table,
+%D simply becaus ethey were not around at the time of writing.
+%
+% we keep it around for archival purposes
+%
+% \def\obeylualines
+% {\obeylines \let\obeyedline \outputnewlinechar
+% \obeyspaces \let\obeyedspace\space}
+%
+% \def\obeyluatokens % todo: make this a proper catcode table, use let's
+% {\catcode`\%=12 \catcode`\#=12
+% \catcode`\_=12 \catcode`\^=12
+% \catcode`\&=12 \catcode`\|=12
+% \catcode`\{=12 \catcode`\}=12
+% \catcode`\~=12 \catcode`\$=12
+% \def\\{\string\\}\def\|{\string\|}\def\-{\string\-}%
+% \def\({\string\(}\def\){\string\)}\def\{{\string\{}\def\}{\string\}}%
+% \def\'{\string\'}\def\"{\string\"}%
+% \def\n{\string\n}\def\r{\string\r}\def\f{\string\f}\def\t{\string\t}%
+% \def\a{\string\a}\def\b{\string\b}\def\v{\string\v}\def\s{\string\s}%
+% \def\1{\string\1}\def\2{\string\2}\def\3{\string\3}\def\4{\string\4}\def\5{\string\5}%
+% \def\6{\string\6}\def\7{\string\7}\def\8{\string\8}\def\9{\string\9}\def\0{\string\0}}
+
+\let\obeylualines\relax
+
+\newtoks\everyluacode
+
+\edef\lualetterbackslash{\string\\}
+\edef\lualetterbar {\string\|} \edef\lualetterdash {\string\-}
+\edef\lualetterlparent {\string\(} \edef\lualetterrparent {\string\)}
+\edef\lualetterlbrace {\string\{} \edef\lualetterrbrace {\string\}}
+\edef\lualettersquote {\string\'} \edef\lualetterdquote {\string\"}
+\edef\lualettern {\string\n} \edef\lualetterr {\string\r}
+\edef\lualetterf {\string\f} \edef\lualettert {\string\t}
+\edef\lualettera {\string\a} \edef\lualetterb {\string\b}
+\edef\lualetterv {\string\v} \edef\lualetters {\string\s}
+\edef\lualetterone {\string\1} \edef\lualettertwo {\string\2}
+\edef\lualetterthree {\string\3} \edef\lualetterfour {\string\4}
+\edef\lualetterfive {\string\5} \edef\lualettersix {\string\6}
+\edef\lualetterseven {\string\7} \edef\lualettereight {\string\8}
+\edef\lualetternine {\string\9} \edef\lualetterzero {\string\0}
+
+\appendtoks
+ \let\\\lualetterbackslash
+ \let\|\lualetterbar \let\-\lualetterdash
+ \let\(\lualetterlparent \let\)\lualetterrparent
+ \let\{\lualetterlbrace \let\}\lualetterrbrace
+ \let\'\lualettersquote \let\"\lualetterdquote
+ \let\n\lualettern \let\r\lualetterr
+ \let\f\lualetterf \let\t\lualettert
+ \let\a\lualettera \let\b\lualetterb
+ \let\v\lualetterv \let\s\lualetters
+ \let\1\lualetterone \let\2\lualettertwo
+ \let\3\lualetterthree \let\4\lualetterfour
+ \let\5\lualetterfive \let\6\lualettersix
+ \let\7\lualetterseven \let\8\lualettereight
+ \let\9\lualetternine \let\0\lualetterzero
+\to \everyluacode
+
+\def\obeyluatokens
+ {\setcatcodetable \luacatcodes
+ \the\everyluacode}
+
+%D \macros
+%D {definenamedlua}
+%D
%D We provide an interface for defining instances:
-\def\s!lua{lua} \def\v!code{code} \let\@EA\expandafter
+\def\s!lua{lua} \def\v!code{code} \def\!!name{name} \def\s!data{data}
-\def\setluainstancename#1#2%
- {\ifproductionrun\else\appendtoks\setluainstancename{#1}{#2}\to\everyjob\fi
- \directlua0{if lua.instancename then lua.instancename[\number#1]="#2" end}}
+%D Beware: because \type {\expanded} is een convert command, the error
+%D message will show \type{<inserted text>} as part of the message.
-\def\definelua[#1]% no ptional arg handling here yet
- {\ifcsname#1\s!lua\endcsname\else\expandafter\newlua\csname#1\s!lua\endcsname\fi
- \setluainstancename{\csname#1\s!lua\endcsname}{#1}%
- \setevalue{\e!start#1\s!lua }{\noexpand\dostartlua \csname#1\s!lua\endcsname}%
- \setevalue{\e!start#1\s!lua\v!code}{\noexpand\dostartluacode\csname#1\s!lua\endcsname}%
- \setvalue {\e!stop #1\s!lua }{\dostoplua }%
- \setvalue {\e!stop #1\s!lua\v!code}{\dostopluacode}}
-
-\definelua[CTX] \setluainstancename\CTXlua{main ctx instance}
+\long\def\dostartnamedluacode#1%
+ {\begingroup
+ \obeylualines
+ \obeyluatokens
+ \csname dodostartnamed#1\v!code\endcsname}
+
+\ifdefined\closelua
+
+ \def\definenamedlua[#1]#2[#3]% no optional arg handling here yet
+ {\expanded{\long\def\csname dodostartnamed#1\v!code\endcsname####1\csname\e!stop#1\v!code\endcsname}%
+ {\normalexpanded{\endgroup\noexpand\directlua\!!name{#3}\zerocount{protect("#1\s!data")##1}}}%
+ \long\expandafter\def\csname\e!start#1\v!code\endcsname {\dostartnamedluacode{#1}}%
+ \long\expandafter\def\csname #1\v!code\endcsname##1{\directlua\!!name{#3}\zerocount{protect("#1\s!data")##1}}}
+
+\else
+
+ \def\definenamedlua[#1]#2[#3]% no optional arg handling here yet
+ {\scratchcounter\ctxlua{lua.registername("#1","#3")}%
+ \expanded{\long\edef\csname dodostartnamed#1\v!code\endcsname####1\csname\e!stop#1\v!code\endcsname}%
+ {\endgroup\noexpand\directlua\the\scratchcounter{protect("#1\s!data")##1}}%
+ \long\expandafter\def \csname\e!start#1\v!code\endcsname {\dostartnamedluacode{#1}}%
+ \long\expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{protect("#1\s!data")##1}}}
+
+\fi
+
+%D We predefine a few.
+
+\definenamedlua[user] [private user instance]
+\definenamedlua[third] [third party module instance]
+\definenamedlua[module] [module instance]
+\definenamedlua[isolated][isolated instance]
+
+%D In practice this works out as follows:
+%D
+%D \startbuffer
+%D \startluacode
+%D tex.print("LUA")
+%D \stopluacode
+%D
+%D \startusercode
+%D global.tex.print("USER 1")
+%D tex.print("USER 2")
+%D if characters then
+%D tex.print("ACCESS")
+%D else
+%D tex.print("NO ACCESS")
+%D end
+%D \stopusercode
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D We need a way to pass strings safely to \LUA\ without the
+%D need for tricky escaping. Compare:
+%D
+%D \starttyping
+%D \ctxlua {something("anything tricky can go here")}
+%D \ctxlua {something([\luastringsep[anything tricky can go here]\luastringsep])}
+%D \stoptyping
+
+\def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems
+
+\edef\!!bs{[\luastringsep[}
+\edef\!!es{]\luastringsep]}
+
+%D We have a the following available as primitive so there is no need
+%D for it:
+%D
+%D \starttyping
+%D \long\edef\luaescapestring#1{\!!bs#1\!!es}
+%D \stoptyping
+
+\def\setdocumentfilename #1#2{\ctxlua{document.setfilename(#1,"#2")}}
+\def\setdocumentargument #1#2{\ctxlua{document.setargument("#1","#2")}}
+\def\setdefaultdocumentargument#1#2{\ctxlua{document.getargument("#1","#2")}}
+\def\getdocumentfilename #1{\ctxlua{document.getfilename(#1)}}
+\def\getdocumentargument #1{\ctxlua{document.getargument(#1)}}
+\def\doifdocumentargumentelse #1{\doifsomethingelse{\getdocumentargument{#1}}}
+\def\doifdocumentargument #1{\doifsomething {\getdocumentargument{#1}}}
+\def\doifnotdocumentargument #1{\doifnothing {\getdocumentargument{#1}}}
+
+\let\doifelsedocumentargument\doifdocumentargumentelse
+
+%D A handy helper:
+
+\def\luaexpanded#1{\luaescapestring\expandafter{\normalexpanded{#1}}}
\protect \endinput
diff --git a/tex/context/base/luat-inp.lua b/tex/context/base/luat-inp.lua
deleted file mode 100644
index d71ab3b73..000000000
--- a/tex/context/base/luat-inp.lua
+++ /dev/null
@@ -1,2300 +0,0 @@
-if not modules then modules = { } end modules ['luat-inp'] = {
- version = 1.001,
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
- comment = "companion to luat-lib.tex",
-}
-
--- TODO: os.getenv -> os.env[]
--- TODO: instances.[hashes,cnffiles,configurations,522] -> ipairs (alles check, sneller)
--- TODO: check escaping in find etc, too much, too slow
-
--- This lib is multi-purpose and can be loaded again later on so that
--- additional functionality becomes available. We will split this
--- module in components once we're done with prototyping. This is the
--- first code I wrote for LuaTeX, so it needs some cleanup. Before changing
--- something in this module one can best check with Taco or Hans first; there
--- is some nasty trickery going on that relates to traditional kpse support.
-
--- To be considered: hash key lowercase, first entry in table filename
--- (any case), rest paths (so no need for optimization). Or maybe a
--- separate table that matches lowercase names to mixed case when
--- present. In that case the lower() cases can go away. I will do that
--- only when we run into problems with names ... well ... Iwona-Regular.
-
--- Beware, loading and saving is overloaded in luat-tmp!
-
-if not input then input = { } end
-if not input.suffixes then input.suffixes = { } end
-if not input.formats then input.formats = { } end
-if not input.aux then input.aux = { } end
-
-if not input.suffixmap then input.suffixmap = { } end
-
-if not input.locators then input.locators = { } end -- locate databases
-if not input.hashers then input.hashers = { } end -- load databases
-if not input.generators then input.generators = { } end -- generate databases
-if not input.filters then input.filters = { } end -- conversion filters
-
-local format, concat, sortedkeys = string.format, table.concat, table.sortedkeys
-
-input.locators.notfound = { nil }
-input.hashers.notfound = { nil }
-input.generators.notfound = { nil }
-
-input.cacheversion = '1.0.1'
-input.banner = nil
-input.verbose = false
-input.debug = false
-input.cnfname = 'texmf.cnf'
-input.luaname = 'texmfcnf.lua'
-input.lsrname = 'ls-R'
-input.homedir = os.env[os.platform == "windows" and 'USERPROFILE'] or os.env['HOME'] or '~'
-
---~ input.luasuffix = 'tma'
---~ input.lucsuffix = 'tmc'
-
--- for the moment we have .local but this will disappear
-input.cnfdefault = '{$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c}'
-
--- chances are low that the cnf file is in the bin path
-input.cnfdefault = '{$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c}'
-
--- we use a cleaned up list / format=any is a wildcard, as is *name
-
-input.formats['afm'] = 'AFMFONTS' input.suffixes['afm'] = { 'afm' }
-input.formats['enc'] = 'ENCFONTS' input.suffixes['enc'] = { 'enc' }
-input.formats['fmt'] = 'TEXFORMATS' input.suffixes['fmt'] = { 'fmt' }
-input.formats['map'] = 'TEXFONTMAPS' input.suffixes['map'] = { 'map' }
-input.formats['mp'] = 'MPINPUTS' input.suffixes['mp'] = { 'mp' }
-input.formats['ocp'] = 'OCPINPUTS' input.suffixes['ocp'] = { 'ocp' }
-input.formats['ofm'] = 'OFMFONTS' input.suffixes['ofm'] = { 'ofm', 'tfm' }
-input.formats['otf'] = 'OPENTYPEFONTS' input.suffixes['otf'] = { 'otf' } -- 'ttf'
-input.formats['opl'] = 'OPLFONTS' input.suffixes['opl'] = { 'opl' }
-input.formats['otp'] = 'OTPINPUTS' input.suffixes['otp'] = { 'otp' }
-input.formats['ovf'] = 'OVFFONTS' input.suffixes['ovf'] = { 'ovf', 'vf' }
-input.formats['ovp'] = 'OVPFONTS' input.suffixes['ovp'] = { 'ovp' }
-input.formats['tex'] = 'TEXINPUTS' input.suffixes['tex'] = { 'tex' }
-input.formats['tfm'] = 'TFMFONTS' input.suffixes['tfm'] = { 'tfm' }
-input.formats['ttf'] = 'TTFONTS' input.suffixes['ttf'] = { 'ttf', 'ttc' }
-input.formats['pfb'] = 'T1FONTS' input.suffixes['pfb'] = { 'pfb', 'pfa' }
-input.formats['vf'] = 'VFFONTS' input.suffixes['vf'] = { 'vf' }
-
-input.formats['fea'] = 'FONTFEATURES' input.suffixes['fea'] = { 'fea' }
-input.formats['cid'] = 'FONTCIDMAPS' input.suffixes['cid'] = { 'cid', 'cidmap' }
-
-input.formats ['texmfscripts'] = 'TEXMFSCRIPTS' -- new
-input.suffixes['texmfscripts'] = { 'rb', 'pl', 'py' } -- 'lua'
-
-input.formats ['lua'] = 'LUAINPUTS' -- new
-input.suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
-
--- here we catch a few new thingies (todo: add these paths to context.tmf)
---
--- FONTFEATURES = .;$TEXMF/fonts/fea//
--- FONTCIDMAPS = .;$TEXMF/fonts/cid//
-
-function input.checkconfigdata() -- not yet ok, no time for debugging now
- local instance = input.instance
- local function fix(varname,default)
- local proname = varname .. "." .. instance.progname or "crap"
- local p = instance.environment[proname]
- local v = instance.environment[varname]
- if not ((p and p ~= "") or (v and v ~= "")) then
- instance.variables[varname] = default -- or environment?
- end
- end
- local name = os.name
- if name == "windows" then
- fix("OSFONTDIR", "c:/windows/fonts//")
- elseif name == "macosx" then
- fix("OSFONTDIR", "$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- else
- -- bad luck
- end
- fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
-end
-
--- backward compatible ones
-
-input.alternatives = { }
-
-input.alternatives['map files'] = 'map'
-input.alternatives['enc files'] = 'enc'
-input.alternatives['cid files'] = 'cid'
-input.alternatives['fea files'] = 'fea'
-input.alternatives['opentype fonts'] = 'otf'
-input.alternatives['truetype fonts'] = 'ttf'
-input.alternatives['truetype collections'] = 'ttc'
-input.alternatives['type1 fonts'] = 'pfb'
-
--- obscure ones
-
-input.formats ['misc fonts'] = ''
-input.suffixes['misc fonts'] = { }
-
-input.formats ['sfd'] = 'SFDFONTS'
-input.suffixes ['sfd'] = { 'sfd' }
-input.alternatives['subfont definition files'] = 'sfd'
-
--- In practice we will work within one tds tree, but i want to keep
--- the option open to build tools that look at multiple trees, which is
--- why we keep the tree specific data in a table. We used to pass the
--- instance but for practical pusposes we now avoid this and use a
--- instance variable.
-
-function input.newinstance()
-
- local instance = { }
-
- instance.rootpath = ''
- instance.treepath = ''
- instance.progname = 'context'
- instance.engine = 'luatex'
- instance.format = ''
- instance.environment = { }
- instance.variables = { }
- instance.expansions = { }
- instance.files = { }
- instance.remap = { }
- instance.configuration = { }
- instance.setup = { }
- instance.order = { }
- instance.found = { }
- instance.foundintrees = { }
- instance.kpsevars = { }
- instance.hashes = { }
- instance.cnffiles = { }
- instance.luafiles = { }
- instance.lists = { }
- instance.remember = true
- instance.diskcache = true
- instance.renewcache = false
- instance.scandisk = true
- instance.cachepath = nil
- instance.loaderror = false
- instance.smallcache = false
- instance.sortdata = false
- instance.savelists = true
- instance.cleanuppaths = true
- instance.allresults = false
- instance.pattern = nil -- lists
- instance.kpseonly = false -- lists
- instance.loadtime = 0
- instance.starttime = 0
- instance.stoptime = 0
- instance.validfile = function(path,name) return true end
- instance.data = { } -- only for loading
- instance.force_suffixes = true
- instance.dummy_path_expr = "^!*unset/*$"
- instance.fakepaths = { }
- instance.lsrmode = false
-
- -- store once, freeze and faster (once reset we can best use instance.environment)
-
- for k,v in pairs(os.env) do
- instance.environment[k] = input.bare_variable(v)
- end
-
- -- cross referencing, delayed because we can add suffixes
-
- for k, v in pairs(input.suffixes) do
- for _, vv in pairs(v) do
- if vv then
- input.suffixmap[vv] = k
- end
- end
- end
-
- return instance
-
-end
-
-input.instance = input.instance or nil
-
-function input.reset()
- input.instance = input.newinstance()
- return input.instance
-end
-
-function input.reset_hashes()
- input.instance.lists = { }
- input.instance.found = { }
-end
-
-function input.bare_variable(str) -- assumes str is a string
- -- return string.gsub(string.gsub(string.gsub(str,"%s+$",""),'^"(.+)"$',"%1"),"^'(.+)'$","%1")
- return (str:gsub("\s*([\"\']?)(.+)%1\s*", "%2"))
-end
-
-function input.settrace(n)
- input.trace = tonumber(n or 0)
- if input.trace > 0 then
- input.verbose = true
- end
-end
-
-input.log = (texio and texio.write_nl) or print
-
-function input.report(...)
- if input.verbose then
- input.log("<<"..format(...)..">>")
- end
-end
-
-function input.report(...)
- if input.trace > 0 then -- extra test
- input.log("<<"..format(...)..">>")
- end
-end
-
-input.settrace(tonumber(os.getenv("MTX.INPUT.TRACE") or os.getenv("MTX_INPUT_TRACE") or input.trace or 0))
-
--- These functions can be used to test the performance, especially
--- loading the database files.
-
-do
- local clock = os.gettimeofday or os.clock
-
- function input.hastimer(instance)
- return instance and instance.starttime
- end
-
- function input.starttiming(instance)
- if instance then
- local it = instance.timing
- if not it then
- it = 0
- end
- if it == 0 then
- instance.starttime = clock()
- if not instance.loadtime then
- instance.loadtime = 0
- end
- end
- instance.timing = it + 1
- end
- end
-
- function input.stoptiming(instance, report)
- if instance then
- local it = instance.timing
- if it > 1 then
- instance.timing = it - 1
- else
- local starttime = instance.starttime
- if starttime then
- local stoptime = clock()
- local loadtime = stoptime - starttime
- instance.stoptime = stoptime
- instance.loadtime = instance.loadtime + loadtime
- if report then
- input.report("load time %0.3f",loadtime)
- end
- instance.timing = 0
- return loadtime
- end
- end
- end
- return 0
- end
-
-end
-
-function input.elapsedtime(instance)
- return format("%0.3f",(instance and instance.loadtime) or 0)
-end
-
-function input.report_loadtime(instance)
- if instance then
- input.report('total load time %s', input.elapsedtime(instance))
- end
-end
-
-input.loadtime = input.elapsedtime
-
-function input.env(key)
- return input.instance.environment[key] or input.osenv(key)
-end
-
-function input.osenv(key)
- local ie = input.instance.environment
- local value = ie[key]
- if value == nil then
- -- local e = os.getenv(key)
- local e = os.env[key]
- if e == nil then
- -- value = "" -- false
- else
- value = input.bare_variable(e)
- end
- ie[key] = value
- end
- return value or ""
-end
-
--- we follow a rather traditional approach:
---
--- (1) texmf.cnf given in TEXMFCNF
--- (2) texmf.cnf searched in default variable
---
--- also we now follow the stupid route: if not set then just assume *one*
--- cnf file under texmf (i.e. distribution)
-
-input.ownpath = input.ownpath or nil
-input.ownbin = input.ownbin or arg[-2] or arg[-1] or arg[0] or "luatex"
-input.autoselfdir = true -- false may be handy for debugging
-
-function input.getownpath()
- if not input.ownpath then
- if input.autoselfdir and os.selfdir then
- input.ownpath = os.selfdir
- else
- local binary = input.ownbin
- if os.platform == "windows" then
- binary = file.replacesuffix(binary,"exe")
- end
- for p in string.gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local b = file.join(p,binary)
- if lfs.isfile(b) then
- -- we assume that after changing to the path the currentdir function
- -- resolves to the real location and use this side effect here; this
- -- trick is needed because on the mac installations use symlinks in the
- -- path instead of real locations
- local olddir = lfs.currentdir()
- if lfs.chdir(p) then
- local pp = lfs.currentdir()
- if input.verbose and p ~= pp then
- input.report("following symlink %s to %s",p,pp)
- end
- input.ownpath = pp
- lfs.chdir(olddir)
- else
- if input.verbose then
- input.report("unable to check path %s",p)
- end
- input.ownpath = p
- end
- break
- end
- end
- end
- if not input.ownpath then input.ownpath = '.' end
- end
- return input.ownpath
-end
-
-function input.identify_own()
- local instance = input.instance
- local ownpath = input.getownpath() or lfs.currentdir()
- local ie = instance.environment
- if ownpath then
- if input.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if input.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if input.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
- else
- input.verbose = true
- input.report("error: unable to locate ownpath")
- os.exit()
- end
- if input.env('TEXMFCNF') == "" then os.env['TEXMFCNF'] = input.cnfdefault end
- if input.env('TEXOS') == "" then os.env['TEXOS'] = input.env('SELFAUTODIR') end
- if input.env('TEXROOT') == "" then os.env['TEXROOT'] = input.env('SELFAUTOPARENT') end
- if input.verbose then
- for _,v in ipairs({"SELFAUTOLOC","SELFAUTODIR","SELFAUTOPARENT","TEXMFCNF"}) do
- input.report("variable %s set to %s",v,input.env(v) or "unknown")
- end
- end
- function input.identify_own() end
-end
-
-function input.identify_cnf()
- local instance = input.instance
- if #instance.cnffiles == 0 then
- -- fallback
- input.identify_own()
- -- the real search
- input.expand_variables()
- local t = input.split_path(input.env('TEXMFCNF'))
- t = input.aux.expanded_path(t)
- input.aux.expand_vars(t) -- redundant
- local function locate(filename,list)
- for _,v in ipairs(t) do
- local texmfcnf = input.normalize_name(file.join(v,filename))
- if lfs.isfile(texmfcnf) then
- table.insert(list,texmfcnf)
- end
- end
- end
- locate(input.luaname,instance.luafiles)
- locate(input.cnfname,instance.cnffiles)
- end
-end
-
-function input.load_cnf()
- local instance = input.instance
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- input.aux.load_cnf(fname)
- end
- end
- -- instance.cnffiles contain complete names now !
- if #instance.cnffiles == 0 then
- input.report("no cnf files found (TEXMFCNF may not be set/known)")
- else
- instance.rootpath = instance.cnffiles[1]
- for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = input.normalize_name(fname:gsub("\\",'/'))
- end
- for i=1,3 do
- instance.rootpath = file.dirname(instance.rootpath)
- end
- instance.rootpath = input.normalize_name(instance.rootpath)
- if instance.lsrmode then
- loadoldconfigdata()
- elseif instance.diskcache and not instance.renewcache then
- input.loadoldconfig(instance.cnffiles)
- if instance.loaderror then
- loadoldconfigdata()
- input.saveoldconfig()
- end
- else
- loadoldconfigdata()
- if instance.renewcache then
- input.saveoldconfig()
- end
- end
- input.aux.collapse_cnf_data()
- end
- input.checkconfigdata()
-end
-
-function input.load_lua()
- local instance = input.instance
- if #instance.luafiles == 0 then
- -- yet harmless
- else
- instance.rootpath = instance.luafiles[1]
- for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = input.normalize_name(fname:gsub("\\",'/'))
- end
- for i=1,3 do
- instance.rootpath = file.dirname(instance.rootpath)
- end
- instance.rootpath = input.normalize_name(instance.rootpath)
- input.loadnewconfig()
- input.aux.collapse_cnf_data()
- end
- input.checkconfigdata()
-end
-
-function input.aux.collapse_cnf_data() -- potential optimization: pass start index (setup and configuration are shared)
- local instance = input.instance
- for _,c in ipairs(instance.order) do
- for k,v in pairs(c) do
- if not instance.variables[k] then
- if instance.environment[k] then
- instance.variables[k] = instance.environment[k]
- else
- instance.kpsevars[k] = true
- instance.variables[k] = input.bare_variable(v)
- end
- end
- end
- end
-end
-
-function input.aux.load_cnf(fname)
- local instance = input.instance
- fname = input.clean_path(fname)
- local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
- local dname = file.dirname(fname)
- if not instance.configuration[dname] then
- input.aux.load_configuration(dname,lname)
- instance.order[#instance.order+1] = instance.configuration[dname]
- end
- else
- f = io.open(fname)
- if f then
- input.report("loading %s", fname)
- local line, data, n, k, v
- local dname = file.dirname(fname)
- if not instance.configuration[dname] then
- instance.configuration[dname] = { }
- instance.order[#instance.order+1] = instance.configuration[dname]
- end
- local data = instance.configuration[dname]
- while true do
- local line, n = f:read(), 0
- if line then
- while true do -- join lines
- line, n = line:gsub("\\%s*$", "")
- if n > 0 then
- line = line .. f:read()
- else
- break
- end
- end
- if not line:find("^[%%#]") then
- local k, v = (line:gsub("%s*%%.*$","")):match("%s*(.-)%s*=%s*(.-)%s*$")
- if k and v and not data[k] then
- data[k] = (v:gsub("[%%#].*",'')):gsub("~", "$HOME")
- instance.kpsevars[k] = true
- end
- end
- else
- break
- end
- end
- f:close()
- else
- input.report("skipping %s", fname)
- end
- end
-end
-
--- database loading
-
-function input.load_hash()
- local instance = input.instance
- input.locatelists()
- if instance.lsrmode then
- input.loadlists()
- elseif instance.diskcache and not instance.renewcache then
- input.loadfiles()
- if instance.loaderror then
- input.loadlists()
- input.savefiles()
- end
- else
- input.loadlists()
- if instance.renewcache then
- input.savefiles()
- end
- end
-end
-
-function input.aux.append_hash(type,tag,name)
- if input.trace > 0 then
- input.logger("= hash append: %s",tag)
- end
- table.insert(input.instance.hashes, { ['type']=type, ['tag']=tag, ['name']=name } )
-end
-
-function input.aux.prepend_hash(type,tag,name)
- if input.trace > 0 then
- input.logger("= hash prepend: %s",tag)
- end
- table.insert(input.instance.hashes, 1, { ['type']=type, ['tag']=tag, ['name']=name } )
-end
-
-function input.aux.extend_texmf_var(specification) -- crap, we could better prepend the hash
- local instance = input.instance
--- local t = input.expanded_path_list('TEXMF') -- full expansion
- local t = input.split_path(input.env('TEXMF'))
- table.insert(t,1,specification)
- local newspec = table.join(t,";")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"] = newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"] = newspec
- else
- -- weird
- end
- input.expand_variables()
- input.reset_hashes()
-end
-
--- locators
-
-function input.locatelists()
- local instance = input.instance
- for _, path in pairs(input.clean_path_list('TEXMF')) do
- input.report("locating list of %s",path)
- input.locatedatabase(input.normalize_name(path))
- end
-end
-
-function input.locatedatabase(specification)
- return input.methodhandler('locators', specification)
-end
-
-function input.locators.tex(specification)
- if specification and specification ~= '' and lfs.isdir(specification) then
- if input.trace > 0 then
- input.logger('! tex locator found: %s',specification)
- end
- input.aux.append_hash('file',specification,filename)
- elseif input.trace > 0 then
- input.logger('? tex locator not found: %s',specification)
- end
-end
-
--- hashers
-
-function input.hashdatabase(tag,name)
- return input.methodhandler('hashers',tag,name)
-end
-
-function input.loadfiles()
- local instance = input.instance
- instance.loaderror = false
- instance.files = { }
- if not instance.renewcache then
- for _, hash in ipairs(instance.hashes) do
- input.hashdatabase(hash.tag,hash.name)
- if instance.loaderror then break end
- end
- end
-end
-
-function input.hashers.tex(tag,name)
- input.aux.load_files(tag)
-end
-
--- generators:
-
-function input.loadlists()
- for _, hash in ipairs(input.instance.hashes) do
- input.generatedatabase(hash.tag)
- end
-end
-
-function input.generatedatabase(specification)
- return input.methodhandler('generators', specification)
-end
-
-local weird = lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
-
-function input.generators.tex(specification)
- local instance = input.instance
- local tag = specification
- if not instance.lsrmode and lfs.dir then
- input.report("scanning path %s",specification)
- instance.files[tag] = { }
- local files = instance.files[tag]
- local n, m, r = 0, 0, 0
- local spec = specification .. '/'
- local attributes = lfs.attributes
- local directory = lfs.dir
- local small = instance.smallcache
- local function action(path)
- local mode, full
- if path then
- full = spec .. path .. '/'
- else
- full = spec
- end
- for name in directory(full) do
- if name:find("^%.") then
- -- skip
- -- elseif name:find("[%~%`%!%#%$%%%^%&%*%(%)%=%{%}%[%]%:%;\"\'%|%<%>%,%?\n\r\t]") then -- too much escaped
- elseif weird:match(name) then
- -- texio.write_nl("skipping " .. name)
- -- skip
- else
- mode = attributes(full..name,'mode')
- if mode == 'directory' then
- m = m + 1
- if path then
- action(path..'/'..name)
- else
- action(name)
- end
- elseif path and mode == 'file' then
- n = n + 1
- local f = files[name]
- if f then
- if not small then
- if type(f) == 'string' then
- files[name] = { f, path }
- else
- f[#f+1] = path
- end
- end
- else
- files[name] = path
- local lower = name:lower()
- if name ~= lower then
- files["remap:"..lower] = name
- r = r + 1
- end
- end
- end
- end
- end
- end
- action()
- input.report("%s files found on %s directories with %s uppercase remappings",n,m,r)
- else
- local fullname = file.join(specification,input.lsrname)
- local path = '.'
- local f = io.open(fullname)
- if f then
- instance.files[tag] = { }
- local files = instance.files[tag]
- local small = instance.smallcache
- input.report("loading lsr file %s",fullname)
- -- for line in f:lines() do -- much slower then the next one
- for line in (f:read("*a")):gmatch("(.-)\n") do
- if line:find("^[%a%d]") then
- local fl = files[line]
- if fl then
- if not small then
- if type(fl) == 'string' then
- files[line] = { fl, path } -- table
- else
- fl[#fl+1] = path
- end
- end
- else
- files[line] = path -- string
- local lower = line:lower()
- if line ~= lower then
- files["remap:"..lower] = line
- end
- end
- else
- path = line:match("%.%/(.-)%:$") or path -- match could be nil due to empty line
- end
- end
- f:close()
- end
- end
-end
-
--- savers, todo
-
-function input.savefiles()
- input.aux.save_data('files', function(k,v)
- return input.instance.validfile(k,v) -- path, name
- end)
-end
-
--- A config (optionally) has the paths split in tables. Internally
--- we join them and split them after the expansion has taken place. This
--- is more convenient.
-
-function input.splitconfig()
- for i,c in ipairs(input.instance) do
- for k,v in pairs(c) do
- if type(v) == 'string' then
- local t = file.split_path(v)
- if #t > 1 then
- c[k] = t
- end
- end
- end
- end
-end
-
-function input.joinconfig()
- for i,c in ipairs(input.instance.order) do
- for k,v in pairs(c) do
- if type(v) == 'table' then
- c[k] = file.join_path(v)
- end
- end
- end
-end
-function input.split_path(str)
- if type(str) == 'table' then
- return str
- else
- return file.split_path(str)
- end
-end
-function input.join_path(str)
- if type(str) == 'table' then
- return file.join_path(str)
- else
- return str
- end
-end
-
-function input.splitexpansions()
- local ie = input.instance.expansions
- for k,v in pairs(ie) do
- local t, h = { }, { }
- for _,vv in pairs(file.split_path(v)) do
- if vv ~= "" and not h[vv] then
- t[#t+1] = vv
- h[vv] = true
- end
- end
- if #t > 1 then
- ie[k] = t
- else
- ie[k] = t[1]
- end
- end
-end
-
--- end of split/join code
-
-function input.saveoldconfig()
- input.splitconfig()
- input.aux.save_data('configuration', nil)
- input.joinconfig()
-end
-
-input.configbanner = [[
--- This is a Luatex configuration file created by 'luatools.lua' or
--- 'luatex.exe' directly. For comment, suggestions and questions you can
--- contact the ConTeXt Development Team. This configuration file is
--- not copyrighted. [HH & TH]
-]]
-
-function input.serialize(files)
- -- This version is somewhat optimized for the kind of
- -- tables that we deal with, so it's much faster than
- -- the generic serializer. This makes sense because
- -- luatools and mtxtools are called frequently. Okay,
- -- we pay a small price for properly tabbed tables.
- local t = { }
- local function dump(k,v,m)
- if type(v) == 'string' then
- return m .. "['" .. k .. "']='" .. v .. "',"
- elseif #v == 1 then
- return m .. "['" .. k .. "']='" .. v[1] .. "',"
- else
- return m .. "['" .. k .. "']={'" .. concat(v,"','").. "'},"
- end
- end
- t[#t+1] = "return {"
- if input.instance.sortdata then
- for _, k in pairs(sortedkeys(files)) do
- local fk = files[k]
- if type(fk) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for _, kk in pairs(sortedkeys(fk)) do
- t[#t+1] = dump(kk,fk[kk],"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,fk,"\t")
- end
- end
- else
- for k, v in pairs(files) do
- if type(v) == 'table' then
- t[#t+1] = "\t['" .. k .. "']={"
- for kk,vv in pairs(v) do
- t[#t+1] = dump(kk,vv,"\t\t")
- end
- t[#t+1] = "\t},"
- else
- t[#t+1] = dump(k,v,"\t")
- end
- end
- end
- t[#t+1] = "}"
- return concat(t,"\n")
-end
-
-if not texmf then texmf = {} end -- no longer needed, at least not here
-
-function input.aux.save_data(dataname, check, makename) -- untested without cache overload
- for cachename, files in pairs(input.instance[dataname]) do
- local name = (makename or file.join)(cachename,dataname)
- local luaname, lucname = name .. ".lua", name .. ".luc"
- input.report("preparing %s for %s",dataname,cachename)
- for k, v in pairs(files) do
- if not check or check(v,k) then -- path, name
- if type(v) == "table" and #v == 1 then
- files[k] = v[1]
- end
- else
- files[k] = nil -- false
- end
- end
- local data = {
- type = dataname,
- root = cachename,
- version = input.cacheversion,
- date = os.date("%Y-%m-%d"),
- time = os.date("%H:%M:%S"),
- content = files,
- }
- local ok = io.savedata(luaname,input.serialize(data))
- if ok then
- input.report("%s saved in %s",dataname,luaname)
- if utils.lua.compile(luaname,lucname,false,true) then -- no cleanup but strip
- input.report("%s compiled to %s",dataname,lucname)
- else
- input.report("compiling failed for %s, deleting file %s",dataname,lucname)
- os.remove(lucname)
- end
- else
- input.report("unable to save %s in %s (access error)",dataname,luaname)
- end
- end
-end
-
-function input.aux.load_data(pathname,dataname,filename,makename) -- untested without cache overload
- local instance = input.instance
- filename = ((not filename or (filename == "")) and dataname) or filename
- filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
- local blob = loadfile(filename .. ".luc") or loadfile(filename .. ".lua")
- if blob then
- local data = blob()
- if data and data.content and data.type == dataname and data.version == input.cacheversion then
- input.report("loading %s for %s from %s",dataname,pathname,filename)
- instance[dataname][pathname] = data.content
- else
- input.report("skipping %s for %s from %s",dataname,pathname,filename)
- instance[dataname][pathname] = { }
- instance.loaderror = true
- end
- else
- input.report("skipping %s for %s from %s",dataname,pathname,filename)
- end
-end
-
--- some day i'll use the nested approach, but not yet (actually we even drop
--- engine/progname support since we have only luatex now)
---
--- first texmfcnf.lua files are located, next the cached texmf.cnf files
---
--- return {
--- TEXMFBOGUS = 'effe checken of dit werkt',
--- }
-
-function input.aux.load_texmfcnf(dataname,pathname)
- local instance = input.instance
- local filename = file.join(pathname,input.luaname)
- local blob = loadfile(filename)
- if blob then
- local data = blob()
- if data then
- input.report("loading configuration file %s",filename)
- if true then
- -- flatten to variable.progname
- local t = { }
- for k, v in pairs(data) do -- v = progname
- if type(v) == "string" then
- t[k] = v
- else
- for kk, vv in pairs(v) do -- vv = variable
- if type(vv) == "string" then
- t[vv.."."..v] = kk
- end
- end
- end
- end
- instance[dataname][pathname] = t
- else
- instance[dataname][pathname] = data
- end
- else
- input.report("skipping configuration file %s",filename)
- instance[dataname][pathname] = { }
- instance.loaderror = true
- end
- else
- input.report("skipping configuration file %s",filename)
- end
-end
-
-function input.aux.load_configuration(dname,lname)
- input.aux.load_data(dname,'configuration',lname and file.basename(lname))
-end
-function input.aux.load_files(tag)
- input.aux.load_data(tag,'files')
-end
-
-function input.resetconfig()
- input.identify_own()
- local instance = input.instance
- instance.configuration, instance.setup, instance.order, instance.loaderror = { }, { }, { }, false
-end
-
-function input.loadnewconfig()
- local instance = input.instance
- for _, cnf in ipairs(instance.luafiles) do
- local dname = file.dirname(cnf)
- input.aux.load_texmfcnf('setup',dname)
- instance.order[#instance.order+1] = instance.setup[dname]
- if instance.loaderror then break end
- end
-end
-
-function input.loadoldconfig()
- local instance = input.instance
- if not instance.renewcache then
- for _, cnf in ipairs(instance.cnffiles) do
- local dname = file.dirname(cnf)
- input.aux.load_configuration(dname)
- instance.order[#instance.order+1] = instance.configuration[dname]
- if instance.loaderror then break end
- end
- end
- input.joinconfig()
-end
-
-function input.expand_variables()
- local instance = input.instance
- local expansions, environment, variables = { }, instance.environment, instance.variables
- local env = input.env
- instance.expansions = expansions
- if instance.engine ~= "" then environment['engine'] = instance.engine end
- if instance.progname ~= "" then environment['progname'] = instance.progname end
- for k,v in pairs(environment) do
- local a, b = k:match("^(%a+)%_(.*)%s*$")
- if a and b then
- expansions[a..'.'..b] = v
- else
- expansions[k] = v
- end
- end
- for k,v in pairs(environment) do -- move environment to expansions
- if not expansions[k] then expansions[k] = v end
- end
- for k,v in pairs(variables) do -- move variables to expansions
- if not expansions[k] then expansions[k] = v end
- end
- while true do
- local busy = false
- for k,v in pairs(expansions) do
- local s, n = v:gsub("%$([%a%d%_%-]+)", function(a)
- busy = true
- return expansions[a] or env(a)
- end)
- local s, m = s:gsub("%$%{([%a%d%_%-]+)%}", function(a)
- busy = true
- return expansions[a] or env(a)
- end)
- if n > 0 or m > 0 then
- expansions[k]= s
- end
- end
- if not busy then break end
- end
- for k,v in pairs(expansions) do
- expansions[k] = v:gsub("\\", '/')
- end
-end
-
-function input.aux.expand_vars(lst) -- simple vars
- local instance = input.instance
- local variables, env = instance.variables, input.env
- for k,v in pairs(lst) do
- lst[k] = v:gsub("%$([%a%d%_%-]+)", function(a)
- return variables[a] or env(a)
- end)
- end
-end
-
-function input.aux.expanded_var(var) -- simple vars
- local instance = input.instance
- return var:gsub("%$([%a%d%_%-]+)", function(a)
- return instance.variables[a] or input.env(a)
- end)
-end
-
-function input.aux.entry(entries,name)
- if name and (name ~= "") then
- local instance = input.instance
- name = name:gsub('%$','')
- local result = entries[name..'.'..instance.progname] or entries[name]
- if result then
- return result
- else
- result = input.env(name)
- if result then
- instance.variables[name] = result
- input.expand_variables()
- return instance.expansions[name] or ""
- end
- end
- end
- return ""
-end
-function input.variable(name)
- return input.aux.entry(input.instance.variables,name)
-end
-function input.expansion(name)
- return input.aux.entry(input.instance.expansions,name)
-end
-
-function input.aux.is_entry(entries,name)
- if name and name ~= "" then
- name = name:gsub('%$','')
- return (entries[name..'.'..input.instance.progname] or entries[name]) ~= nil
- else
- return false
- end
-end
-
-function input.is_variable(name)
- return input.aux.is_entry(input.instance.variables,name)
-end
-
-function input.is_expansion(name)
- return input.aux.is_entry(input.instance.expansions,name)
-end
-
-function input.unexpanded_path_list(str)
- local pth = input.variable(str)
- local lst = input.split_path(pth)
- return input.aux.expanded_path(lst)
-end
-
-function input.unexpanded_path(str)
- return file.join_path(input.unexpanded_path_list(str))
-end
-
-do
- local done = { }
-
- function input.reset_extra_path()
- local instance = input.instance
- local ep = instance.extra_paths
- if not ep then
- ep, done = { }, { }
- instance.extra_paths = ep
- elseif #ep > 0 then
- instance.lists, done = { }, { }
- end
- end
-
- function input.register_extra_path(paths,subpaths)
- local instance = input.instance
- local ep = instance.extra_paths or { }
- local n = #ep
- if paths and paths ~= "" then
- if subpaths and subpaths ~= "" then
- for p in paths:gmatch("[^,]+") do
- -- we gmatch each step again, not that fast, but used seldom
- for s in subpaths:gmatch("[^,]+") do
- local ps = p .. "/" .. s
- if not done[ps] then
- ep[#ep+1] = input.clean_path(ps)
- done[ps] = true
- end
- end
- end
- else
- for p in paths:gmatch("[^,]+") do
- if not done[p] then
- ep[#ep+1] = input.clean_path(p)
- done[p] = true
- end
- end
- end
- elseif subpaths and subpaths ~= "" then
- for i=1,n do
- -- we gmatch each step again, not that fast, but used seldom
- for s in subpaths:gmatch("[^,]+") do
- local ps = ep[i] .. "/" .. s
- if not done[ps] then
- ep[#ep+1] = input.clean_path(ps)
- done[ps] = true
- end
- end
- end
- end
- if #ep > 0 then
- instance.extra_paths = ep -- register paths
- end
- if #ep > n then
- instance.lists = { } -- erase the cache
- end
- end
-
-end
-
-function input.expanded_path_list(str)
- local instance = input.instance
- local function made_list(list)
- local ep = instance.extra_paths
- if not ep or #ep == 0 then
- return list
- else
- local done, new = { }, { }
- -- honour . .. ../.. but only when at the start
- for k, v in ipairs(list) do
- if not done[v] then
- if v:find("^[%.%/]$") then
- done[v] = true
- new[#new+1] = v
- else
- break
- end
- end
- end
- -- first the extra paths
- for k, v in ipairs(ep) do
- if not done[v] then
- done[v] = true
- new[#new+1] = v
- end
- end
- -- next the formal paths
- for k, v in ipairs(list) do
- if not done[v] then
- done[v] = true
- new[#new+1] = v
- end
- end
- return new
- end
- end
- if not str then
- return ep or { }
- elseif instance.savelists then
- -- engine+progname hash
- str = str:gsub("%$","")
- if not instance.lists[str] then -- cached
- local lst = made_list(input.split_path(input.expansion(str)))
- instance.lists[str] = input.aux.expanded_path(lst)
- end
- return instance.lists[str]
- else
- local lst = input.split_path(input.expansion(str))
- return made_list(input.aux.expanded_path(lst))
- end
-end
-
-
-function input.clean_path_list(str)
- local t = input.expanded_path_list(str)
- if t then
- for i=1,#t do
- t[i] = file.collapse_path(input.clean_path(t[i]))
- end
- end
- return t
-end
-
-function input.expand_path(str)
- return file.join_path(input.expanded_path_list(str))
-end
-
-function input.expanded_path_list_from_var(str) -- brrr
- local tmp = input.var_of_format_or_suffix(str:gsub("%$",""))
- if tmp ~= "" then
- return input.expanded_path_list(str)
- else
- return input.expanded_path_list(tmp)
- end
-end
-function input.expand_path_from_var(str)
- return file.join_path(input.expanded_path_list_from_var(str))
-end
-
-function input.format_of_var(str)
- return input.formats[str] or input.formats[input.alternatives[str]] or ''
-end
-function input.format_of_suffix(str)
- return input.suffixmap[file.extname(str)] or 'tex'
-end
-
-function input.variable_of_format(str)
- return input.formats[str] or input.formats[input.alternatives[str]] or ''
-end
-
-function input.var_of_format_or_suffix(str)
- local v = input.formats[str]
- if v then
- return v
- end
- v = input.formats[input.alternatives[str]]
- if v then
- return v
- end
- v = input.suffixmap[file.extname(str)]
- if v then
- return input.formats[isf]
- end
- return ''
-end
-
-function input.expand_braces(str) -- output variable and brace expansion of STRING
- local ori = input.variable(str)
- local pth = input.aux.expanded_path(input.split_path(ori))
- return file.join_path(pth)
-end
-
--- {a,b,c,d}
--- a,b,c/{p,q,r},d
--- a,b,c/{p,q,r}/d/{x,y,z}//
--- a,b,c/{p,q/{x,y,z},r},d/{p,q,r}
--- a,b,c/{p,q/{x,y,z},r},d/{p,q,r}
--- a{b,c}{d,e}f
--- {a,b,c,d}
--- {a,b,c/{p,q,r},d}
--- {a,b,c/{p,q,r}/d/{x,y,z}//}
--- {a,b,c/{p,q/{x,y,z}},d/{p,q,r}}
--- {a,b,c/{p,q/{x,y,z},w}v,d/{p,q,r}}
--- {$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,.local,}/web2c}
-
--- this one is better and faster, but it took me a while to realize
--- that this kind of replacement is cleaner than messy parsing and
--- fuzzy concatenating we can probably gain a bit with selectively
--- applying lpeg, but experiments with lpeg parsing this proved not to
--- work that well; the parsing is ok, but dealing with the resulting
--- table is a pain because we need to work inside-out recursively
-
-function input.aux.splitpathexpr(str, t, validate)
- -- no need for optimization, only called a few times, we can use lpeg for the sub
- t = t or { }
- str = str:gsub(",}",",@}")
- str = str:gsub("{,","{@,")
- -- str = "@" .. str .. "@"
- while true do
- local done = false
- while true do
- local ok = false
- str = str:gsub("([^{},]+){([^{}]+)}", function(a,b)
- local t = { }
- for s in b:gmatch("[^,]+") do t[#t+1] = a .. s end
- ok, done = true, true
- return "{" .. concat(t,",") .. "}"
- end)
- if not ok then break end
- end
- while true do
- local ok = false
- str = str:gsub("{([^{}]+)}([^{},]+)", function(a,b)
- local t = { }
- for s in a:gmatch("[^,]+") do t[#t+1] = s .. b end
- ok, done = true, true
- return "{" .. concat(t,",") .. "}"
- end)
- if not ok then break end
- end
- while true do
- local ok = false
- str = str:gsub("{([^{}]+)}{([^{}]+)}", function(a,b)
- local t = { }
- for sa in a:gmatch("[^,]+") do
- for sb in b:gmatch("[^,]+") do
- t[#t+1] = sa .. sb
- end
- end
- ok, done = true, true
- return "{" .. concat(t,",") .. "}"
- end)
- if not ok then break end
- end
- str = str:gsub("({[^{}]*){([^{}]+)}([^{}]*})", function(a,b,c)
- done = true
- return a .. b.. c
- end)
- if not done then break end
- end
- str = str:gsub("[{}]", "")
- str = str:gsub("@","")
- if validate then
- for s in str:gmatch("[^,]+") do
- s = validate(s)
- if s then t[#t+1] = s end
- end
- else
- for s in str:gmatch("[^,]+") do
- t[#t+1] = s
- end
- end
- return t
-end
-
-function input.aux.expanded_path(pathlist) -- maybe not a list, just a path
- local instance = input.instance
- -- a previous version fed back into pathlist
- local newlist, ok = { }, false
- for _,v in ipairs(pathlist) do
- if v:find("[{}]") then
- ok = true
- break
- end
- end
- if ok then
- for _, v in ipairs(pathlist) do
- input.aux.splitpathexpr(v, newlist, function(s)
- s = file.collapse_path(s)
- return s ~= "" and not s:find(instance.dummy_path_expr) and s
- end)
- end
- else
- for _,v in ipairs(pathlist) do
- for vv in string.gmatch(v..',',"(.-),") do
- vv = file.collapse_path(v)
- if vv ~= "" then newlist[#newlist+1] = vv end
- end
- end
- end
- return newlist
-end
-
-input.is_readable = { }
-
-function input.aux.is_readable(readable, name)
- if input.trace > 2 then
- if readable then
- input.logger("+ readable: %s",name)
- else
- input.logger("- readable: %s", name)
- end
- end
- return readable
-end
-
-function input.is_readable.file(name)
- return input.aux.is_readable(lfs.isfile(name), name)
-end
-
-input.is_readable.tex = input.is_readable.file
-
--- name
--- name/name
-
-function input.aux.collect_files(names)
- local instance = input.instance
- local filelist = { }
- for _, fname in pairs(names) do
- if fname then
- if input.trace > 2 then
- input.logger("? blobpath asked: %s",fname)
- end
- local bname = file.basename(fname)
- local dname = file.dirname(fname)
- if dname == "" or dname:find("^%.") then
- dname = false
- else
- dname = "/" .. dname .. "$"
- end
- for _, hash in ipairs(instance.hashes) do
- local blobpath = hash.tag
- local files = blobpath and instance.files[blobpath]
- if files then
- if input.trace > 2 then
- input.logger('? blobpath do: %s (%s)',blobpath,bname)
- end
- local blobfile = files[bname]
- if not blobfile then
- local rname = "remap:"..bname
- blobfile = files[rname]
- if blobfile then
- bname = files[rname]
- blobfile = files[bname]
- end
- end
- if blobfile then
- if type(blobfile) == 'string' then
- if not dname or blobfile:find(dname) then
- filelist[#filelist+1] = {
- hash.type,
- file.join(blobpath,blobfile,bname), -- search
- input.concatinators[hash.type](blobpath,blobfile,bname) -- result
- }
- end
- else
- for _, vv in pairs(blobfile) do
- if not dname or vv:find(dname) then
- filelist[#filelist+1] = {
- hash.type,
- file.join(blobpath,vv,bname), -- search
- input.concatinators[hash.type](blobpath,vv,bname) -- result
- }
- end
- end
- end
- end
- elseif input.trace > 1 then
- input.logger('! blobpath no: %s (%s)',blobpath,bname)
- end
- end
- end
- end
- if #filelist > 0 then
- return filelist
- else
- return nil
- end
-end
-
-function input.suffix_of_format(str)
- if input.suffixes[str] then
- return input.suffixes[str][1]
- else
- return ""
- end
-end
-
-function input.suffixes_of_format(str)
- if input.suffixes[str] then
- return input.suffixes[str]
- else
- return {}
- end
-end
-
-do
-
- -- called about 700 times for an empty doc (font initializations etc)
- -- i need to weed the font files for redundant calls
-
- local letter = lpeg.R("az","AZ")
- local separator = lpeg.P("://")
-
- local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator
- local rootbased = lpeg.P("/") + letter*lpeg.P(":")
-
- -- ./name ../name /name c: ://
- function input.aux.qualified_path(filename)
- return qualified:match(filename)
- end
- function input.aux.rootbased_path(filename)
- return rootbased:match(filename)
- end
-
- function input.normalize_name(original)
- return original
- end
-
- input.normalize_name = file.collapse_path
-
-end
-
-function input.aux.register_in_trees(name)
- if not name:find("^%.") then
- local instance = input.instance
- instance.foundintrees[name] = (instance.foundintrees[name] or 0) + 1 -- maybe only one
- end
-end
-
--- split the next one up, better for jit
-
-function input.aux.find_file(filename) -- todo : plugin (scanners, checkers etc)
- local instance = input.instance
- local result = { }
- local stamp = nil
- filename = input.normalize_name(filename) -- elsewhere
- filename = file.collapse_path(filename:gsub("\\","/")) -- elsewhere
- -- speed up / beware: format problem
- if instance.remember then
- stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
- if instance.found[stamp] then
- if input.trace > 0 then
- input.logger('! remembered: %s',filename)
- end
- return instance.found[stamp]
- end
- end
- if filename:find('%*') then
- if input.trace > 0 then
- input.logger('! wildcard: %s', filename)
- end
- result = input.find_wildcard_files(filename)
- elseif input.aux.qualified_path(filename) then
- if input.is_readable.file(filename) then
- if input.trace > 0 then
- input.logger('! qualified: %s', filename)
- end
- result = { filename }
- else
- local forcedname, ok = "", false
- if file.extname(filename) == "" then
- if instance.format == "" then
- forcedname = filename .. ".tex"
- if input.is_readable.file(forcedname) then
- if input.trace > 0 then
- input.logger('! no suffix, forcing standard filetype: tex')
- end
- result, ok = { forcedname }, true
- end
- else
- for _, s in pairs(input.suffixes_of_format(instance.format)) do
- forcedname = filename .. "." .. s
- if input.is_readable.file(forcedname) then
- if input.trace > 0 then
- input.logger('! no suffix, forcing format filetype: %s', s)
- end
- result, ok = { forcedname }, true
- break
- end
- end
- end
- end
- if not ok and input.trace > 0 then
- input.logger('? qualified: %s', filename)
- end
- end
- else
- -- search spec
- local filetype, extra, done, wantedfiles, ext = '', nil, false, { }, file.extname(filename)
- if ext == "" then
- if not instance.force_suffixes then
- wantedfiles[#wantedfiles+1] = filename
- end
- else
- wantedfiles[#wantedfiles+1] = filename
- end
- if instance.format == "" then
- if ext == "" then
- local forcedname = filename .. '.tex'
- wantedfiles[#wantedfiles+1] = forcedname
- filetype = input.format_of_suffix(forcedname)
- if input.trace > 0 then
- input.logger('! forcing filetype: %s',filetype)
- end
- else
- filetype = input.format_of_suffix(filename)
- if input.trace > 0 then
- input.logger('! using suffix based filetype: %s',filetype)
- end
- end
- else
- if ext == "" then
- for _, s in pairs(input.suffixes_of_format(instance.format)) do
- wantedfiles[#wantedfiles+1] = filename .. "." .. s
- end
- end
- filetype = instance.format
- if input.trace > 0 then
- input.logger('! using given filetype: %s',filetype)
- end
- end
- local typespec = input.variable_of_format(filetype)
- local pathlist = input.expanded_path_list(typespec)
- if not pathlist or #pathlist == 0 then
- -- no pathlist, access check only / todo == wildcard
- if input.trace > 2 then
- input.logger('? filename: %s',filename)
- input.logger('? filetype: %s',filetype or '?')
- input.logger('? wanted files: %s',concat(wantedfiles," | "))
- end
- for _, fname in pairs(wantedfiles) do
- if fname and input.is_readable.file(fname) then
- filename, done = fname, true
- result[#result+1] = file.join('.',fname)
- break
- end
- end
- -- this is actually 'other text files' or 'any' or 'whatever'
- local filelist = input.aux.collect_files(wantedfiles)
- local fl = filelist and filelist[1]
- if fl then
- filename = fl[3]
- result[#result+1] = filename
- done = true
- end
- else
- -- list search
- local filelist = input.aux.collect_files(wantedfiles)
- local doscan, recurse
- if input.trace > 2 then
- input.logger('? filename: %s',filename)
- -- if pathlist then input.logger('? path list: %s',concat(pathlist," | ")) end
- -- if filelist then input.logger('? file list: %s',concat(filelist," | ")) end
- end
- -- a bit messy ... esp the doscan setting here
- for _, path in pairs(pathlist) do
- if path:find("^!!") then doscan = false else doscan = true end
- if path:find("//$") then recurse = true else recurse = false end
- local pathname = path:gsub("^!+", '')
- done = false
- -- using file list
- if filelist and not (done and not instance.allresults) and recurse then
- -- compare list entries with permitted pattern
- pathname = pathname:gsub("([%-%.])","%%%1") -- this also influences
- pathname = pathname:gsub("/+$", '/.*') -- later usage of pathname
- pathname = pathname:gsub("//", '/.-/') -- not ok for /// but harmless
- local expr = "^" .. pathname
- -- input.debug('?',expr)
- for _, fl in ipairs(filelist) do
- local f = fl[2]
- if f:find(expr) then
- -- input.debug('T',' '..f)
- if input.trace > 2 then
- input.logger('= found in hash: %s',f)
- end
- --- todo, test for readable
- result[#result+1] = fl[3]
- input.aux.register_in_trees(f) -- for tracing used files
- done = true
- if not instance.allresults then break end
- else
- -- input.debug('F',' '..f)
- end
- end
- end
- if not done and doscan then
- -- check if on disk / unchecked / does not work at all / also zips
- if input.method_is_file(pathname) then -- ?
- local pname = pathname:gsub("%.%*$",'')
- if not pname:find("%*") then
- local ppname = pname:gsub("/+$","")
- if input.aux.can_be_dir(ppname) then
- for _, w in pairs(wantedfiles) do
- local fname = file.join(ppname,w)
- if input.is_readable.file(fname) then
- if input.trace > 2 then
- input.logger('= found by scanning: %s',fname)
- end
- result[#result+1] = fname
- done = true
- if not instance.allresults then break end
- end
- end
- else
- -- no access needed for non existing path, speedup (esp in large tree with lots of fake)
- end
- end
- end
- end
- if not done and doscan then
- -- todo: slow path scanning
- end
- if done and not instance.allresults then break end
- end
- end
- end
- for k,v in pairs(result) do
- result[k] = file.collapse_path(v)
- end
- if instance.remember then
- instance.found[stamp] = result
- end
- return result
-end
-
-input.aux._find_file_ = input.aux.find_file -- frozen variant
-
-function input.aux.find_file(filename) -- maybe make a lowres cache too
- local result = input.aux._find_file_(filename)
- if #result == 0 then
- local lowered = filename:lower()
- if filename ~= lowered then
- return input.aux._find_file_(lowered)
- end
- end
- return result
-end
-
-function input.aux.can_be_dir(name)
- local instance = input.instance
- if not instance.fakepaths[name] then
- if lfs.isdir(name) then
- instance.fakepaths[name] = 1 -- directory
- else
- instance.fakepaths[name] = 2 -- no directory
- end
- end
- return (instance.fakepaths[name] == 1)
-end
-
-if not input.concatinators then input.concatinators = { } end
-
-input.concatinators.tex = file.join
-input.concatinators.file = input.concatinators.tex
-
-function input.find_files(filename,filetype,mustexist)
- local instance = input.instance
- if type(mustexist) == boolean then
- -- all set
- elseif type(filetype) == 'boolean' then
- filetype, mustexist = nil, false
- elseif type(filetype) ~= 'string' then
- filetype, mustexist = nil, false
- end
- instance.format = filetype or ''
- local t = input.aux.find_file(filename,true)
- instance.format = ''
- return t
-end
-
-function input.find_file(filename,filetype,mustexist)
- return (input.find_files(filename,filetype,mustexist)[1] or "")
-end
-
-function input.find_given_files(filename)
- local instance = input.instance
- local bname, result = file.basename(filename), { }
- for k, hash in ipairs(instance.hashes) do
- local files = instance.files[hash.tag]
- local blist = files[bname]
- if not blist then
- local rname = "remap:"..bname
- blist = files[rname]
- if blist then
- bname = files[rname]
- blist = files[bname]
- end
- end
- if blist then
- if type(blist) == 'string' then
- result[#result+1] = input.concatinators[hash.type](hash.tag,blist,bname) or ""
- if not instance.allresults then break end
- else
- for kk,vv in pairs(blist) do
- result[#result+1] = input.concatinators[hash.type](hash.tag,vv,bname) or ""
- if not instance.allresults then break end
- end
- end
- end
- end
- return result
-end
-
-function input.find_given_file(filename)
- return (input.find_given_files(filename)[1] or "")
-end
-
-function input.find_wildcard_files(filename) -- todo: remap:
- local instance = input.instance
- local result = { }
- local bname, dname = file.basename(filename), file.dirname(filename)
- local path = dname:gsub("^*/","")
- path = path:gsub("*",".*")
- path = path:gsub("-","%%-")
- if dname == "" then
- path = ".*"
- end
- local name = bname
- name = name:gsub("*",".*")
- name = name:gsub("-","%%-")
- path = path:lower()
- name = name:lower()
- local function doit(blist,bname,hash,allresults)
- local done = false
- if blist then
- if type(blist) == 'string' then
- -- make function and share code
- if (blist:lower()):find(path) then
- result[#result+1] = input.concatinators[hash.type](hash.tag,blist,bname) or ""
- done = true
- end
- else
- for kk,vv in pairs(blist) do
- if (vv:lower()):find(path) then
- result[#result+1] = input.concatinators[hash.type](hash.tag,vv,bname) or ""
- done = true
- if not allresults then break end
- end
- end
- end
- end
- return done
- end
- local files, allresults, done = instance.files, instance.allresults, false
- if name:find("%*") then
- for k, hash in ipairs(instance.hashes) do
- for kk, hh in pairs(files[hash.tag]) do
- if not kk:find("^remap:") then
- if (kk:lower()):find(name) then
- if doit(hh,kk,hash,allresults) then done = true end
- if done and not allresults then break end
- end
- end
- end
- end
- else
- for k, hash in ipairs(instance.hashes) do
- if doit(files[hash.tag][bname],bname,hash,allresults) then done = true end
- if done and not allresults then break end
- end
- end
- -- we can consider also searching the paths not in the database, but then
- -- we end up with a messy search (all // in all path specs)
- return result
-end
-
-function input.find_wildcard_file(filename)
- return (input.find_wildcard_files(filename)[1] or "")
-end
-
--- main user functions
-
-function input.save_used_files_in_trees(filename,jobname)
- local instance = input.instance
- if not filename then filename = 'luatex.jlg' end
- local f = io.open(filename,'w')
- if f then
- f:write("<?xml version='1.0' standalone='yes'?>\n")
- f:write("<rl:job>\n")
- if jobname then
- f:write("\t<rl:name>" .. jobname .. "</rl:name>\n")
- end
- f:write("\t<rl:files>\n")
- for _,v in pairs(sorted(instance.foundintrees)) do -- ipairs
- f:write("\t\t<rl:file n='" .. instance.foundintrees[v] .. "'>" .. v .. "</rl:file>\n")
- end
- f:write("\t</rl:files>\n")
- f:write("</rl:usedfiles>\n")
- f:close()
- end
-end
-
-function input.automount()
- -- implemented later
-end
-
-function input.load()
- input.starttiming(input.instance)
- input.resetconfig()
- input.identify_cnf()
- input.load_lua()
- input.expand_variables()
- input.load_cnf()
- input.expand_variables()
- input.load_hash()
- input.automount()
- input.stoptiming(input.instance)
-end
-
-function input.for_files(command, files, filetype, mustexist)
- if files and #files > 0 then
- local function report(str)
- if input.verbose then
- input.report(str) -- has already verbose
- else
- print(str)
- end
- end
- if input.verbose then
- report('')
- end
- for _, file in pairs(files) do
- local result = command(file,filetype,mustexist)
- if type(result) == 'string' then
- report(result)
- else
- for _,v in pairs(result) do
- report(v)
- end
- end
- end
- end
-end
-
--- strtab
-
-input.var_value = input.variable -- output the value of variable $STRING.
-input.expand_var = input.expansion -- output variable expansion of STRING.
-
-function input.show_path(str) -- output search path for file type NAME
- return file.join_path(input.expanded_path_list(input.format_of_var(str)))
-end
-
--- input.find_file(filename)
--- input.find_file(filename, filetype, mustexist)
--- input.find_file(filename, mustexist)
--- input.find_file(filename, filetype)
-
-function input.aux.register_file(files, name, path)
- if files[name] then
- if type(files[name]) == 'string' then
- files[name] = { files[name], path }
- else
- files[name] = path
- end
- else
- files[name] = path
- end
-end
-
-if not input.finders then input.finders = { } end
-if not input.openers then input.openers = { } end
-if not input.loaders then input.loaders = { } end
-
-input.finders.notfound = { nil }
-input.openers.notfound = { nil }
-input.loaders.notfound = { false, nil, 0 }
-
-function input.splitmethod(filename)
- if not filename then
- return { } -- safeguard
- elseif type(filename) == "table" then
- return filename -- already split
- elseif not filename:find("://") then
- return { scheme="file", path = filename, original=filename } -- quick hack
- else
- return url.hashed(filename)
- end
-end
-
-function input.method_is_file(filename)
- return input.splitmethod(filename).scheme == 'file'
-end
-
-function table.sequenced(t,sep) -- temp here
- local s = { }
- for k, v in pairs(t) do
- s[#s+1] = k .. "=" .. v
- end
- return concat(s, sep or " | ")
-end
-
-function input.methodhandler(what, filename, filetype) -- ...
- local specification = (type(filename) == "string" and input.splitmethod(filename)) or filename -- no or { }, let it bomb
- local scheme = specification.scheme
- if input[what][scheme] then
- if input.trace > 0 then
- input.logger('= handler: %s -> %s -> %s',specification.original,what,table.sequenced(specification))
- end
- return input[what][scheme](filename,filetype) -- todo: specification
- else
- return input[what].tex(filename,filetype) -- todo: specification
- end
-end
-
--- also inside next test?
-
-function input.findtexfile(filename, filetype)
- return input.methodhandler('finders',input.normalize_name(filename), filetype)
-end
-function input.opentexfile(filename)
- return input.methodhandler('openers',input.normalize_name(filename))
-end
-
-function input.findbinfile(filename, filetype)
- return input.methodhandler('finders',input.normalize_name(filename), filetype)
-end
-function input.openbinfile(filename)
- return input.methodhandler('loaders',input.normalize_name(filename))
-end
-
-function input.loadbinfile(filename, filetype)
- local fname = input.findbinfile(input.normalize_name(filename), filetype)
- if fname and fname ~= "" then
- return input.openbinfile(fname)
- else
- return unpack(input.loaders.notfound)
- end
-end
-
-function input.texdatablob(filename, filetype)
- local ok, data, size = input.loadbinfile(filename, filetype)
- return data or ""
-end
-
-input.loadtexfile = input.texdatablob
-
-function input.openfile(filename)
- local fullname = input.findtexfile(filename)
- if fullname and (fullname ~= "") then
- return input.opentexfile(fullname)
- else
- return nil
- end
-end
-
-function input.logmode()
- return (os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex"):lower()
-end
-
--- this is a prelude to engine/progname specific configuration files
--- in which case we can omit files meant for other programs and
--- packages
-
---- ctx
-
--- maybe texinputs + font paths
--- maybe positive selection tex/context fonts/tfm|afm|vf|opentype|type1|map|enc
-
-input.validators = { }
-input.validators.visibility = { }
-
-function input.validators.visibility.default(path, name)
- return true
-end
-
-function input.validators.visibility.context(path, name)
- path = path[1] or path -- some day a loop
- return not (
- path:find("latex") or
--- path:find("doc") or
- path:find("tex4ht") or
- path:find("source") or
--- path:find("config") or
--- path:find("metafont") or
- path:find("lists$") or
- name:find("%.tpm$") or
- name:find("%.bak$")
- )
-end
-
--- todo: describe which functions are public (maybe input.private. ... )
-
--- beware: i need to check where we still need a / on windows:
-
-function input.clean_path(str)
- if str then
- str = str:gsub("\\","/")
- str = str:gsub("^!+","")
- str = str:gsub("^~",input.homedir)
- return str
- else
- return nil
- end
-end
-
-function input.do_with_path(name,func)
- for _, v in pairs(input.expanded_path_list(name)) do
- func("^"..input.clean_path(v))
- end
-end
-
-function input.do_with_var(name,func)
- func(input.aux.expanded_var(name))
-end
-
-function input.with_files(pattern,handle)
- local instance = input.instance
- for _, hash in ipairs(instance.hashes) do
- local blobpath = hash.tag
- local blobtype = hash.type
- if blobpath then
- local files = instance.files[blobpath]
- if files then
- for k,v in pairs(files) do
- if k:find("^remap:") then
- k = files[k]
- v = files[k] -- chained
- end
- if k:find(pattern) then
- if type(v) == "string" then
- handle(blobtype,blobpath,v,k)
- else
- for _,vv in pairs(v) do
- handle(blobtype,blobpath,vv,k)
- end
- end
- end
- end
- end
- end
- end
-end
-
-function input.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix
- local scriptpath = "scripts/context/lua"
- newname = file.addsuffix(newname,"lua")
- local oldscript = input.clean_path(oldname)
- input.report("to be replaced old script %s", oldscript)
- local newscripts = input.find_files(newname) or { }
- if #newscripts == 0 then
- input.report("unable to locate new script")
- else
- for _, newscript in ipairs(newscripts) do
- newscript = input.clean_path(newscript)
- input.report("checking new script %s", newscript)
- if oldscript == newscript then
- input.report("old and new script are the same")
- elseif not newscript:find(scriptpath) then
- input.report("new script should come from %s",scriptpath)
- elseif not (oldscript:find(file.removesuffix(newname).."$") or oldscript:find(newname.."$")) then
- input.report("invalid new script name")
- else
- local newdata = io.loaddata(newscript)
- if newdata then
- input.report("old script content replaced by new content")
- io.savedata(oldscript,newdata)
- break
- else
- input.report("unable to load new script")
- end
- end
- end
- end
-end
-
-
---~ print(table.serialize(input.aux.splitpathexpr("/usr/share/texmf-{texlive,tetex}", {})))
-
--- command line resolver:
-
---~ print(input.resolve("abc env:tmp file:cont-en.tex path:cont-en.tex full:cont-en.tex rel:zapf/one/p-chars.tex"))
-
-do
-
- local resolvers = { }
-
- resolvers.environment = function(str)
- return input.clean_path(os.getenv(str) or os.getenv(str:upper()) or os.getenv(str:lower()) or "")
- end
- resolvers.relative = function(str,n)
- if io.exists(str) then
- -- nothing
- elseif io.exists("./" .. str) then
- str = "./" .. str
- else
- local p = "../"
- for i=1,n or 2 do
- if io.exists(p .. str) then
- str = p .. str
- break
- else
- p = p .. "../"
- end
- end
- end
- return input.clean_path(str)
- end
- resolvers.locate = function(str)
- local fullname = input.find_given_file(str) or ""
- return input.clean_path((fullname ~= "" and fullname) or str)
- end
- resolvers.filename = function(str)
- local fullname = input.find_given_file(str) or ""
- return input.clean_path(file.basename((fullname ~= "" and fullname) or str))
- end
- resolvers.pathname = function(str)
- local fullname = input.find_given_file(str) or ""
- return input.clean_path(file.dirname((fullname ~= "" and fullname) or str))
- end
-
- resolvers.env = resolvers.environment
- resolvers.rel = resolvers.relative
- resolvers.loc = resolvers.locate
- resolvers.kpse = resolvers.locate
- resolvers.full = resolvers.locate
- resolvers.file = resolvers.filename
- resolvers.path = resolvers.pathname
-
- local function resolve(str)
- if type(str) == "table" then
- for k, v in pairs(str) do
- str[k] = resolve(v) or v
- end
- elseif str and str ~= "" then
- str = str:gsub("([a-z]+):([^ \"\']*)", function(method,target)
- if resolvers[method] then
- return resolvers[method](target)
- else
- return method .. ":" .. target
- end
- end)
- end
- return str
- end
-
- if os.uname then
- for k, v in pairs(os.uname()) do
- if not resolvers[k] then
- resolvers[k] = function() return v end
- end
- end
- end
-
- input.resolve = resolve
-
-end
-
-function input.boolean_variable(str,default)
- local b = input.expansion(str)
- if b == "" then
- return default
- else
- b = toboolean(b)
- return (b == nil and default) or b
- end
-end
diff --git a/tex/context/base/luat-iop.lua b/tex/context/base/luat-iop.lua
index 469b7c034..883ec43ce 100644
--- a/tex/context/base/luat-iop.lua
+++ b/tex/context/base/luat-iop.lua
@@ -1,16 +1,16 @@
--- filename : luat-iop.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['luat-iop'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-- this paranoid stuff in web2c ... we cannot hook checks into the
-- input functions because one can always change the callback but
-- we can feed back specific patterns and paths into the next
-- mechanism
-if not versions then versions = { } end versions['luat-exe'] = 1.001
-
if not io.inp then io.inp = { } end
if not io.out then io.out = { } end
@@ -127,11 +127,11 @@ function io.inp.modes.paranoid()
io.inp.inhibit('%.%.')
io.inp.permit('^%./')
io.inp.permit('[^/]')
- input.do_with_path('TEXMF',io.inp.permit)
+ resolvers.do_with_path('TEXMF',io.inp.permit)
end
function io.out.modes.paranoid()
io.out.inhibit('.*')
- input.do_with_path('TEXMFOUTPUT',io.out.permit)
+ resolvers.do_with_path('TEXMFOUTPUT',io.out.permit)
end
-- handy
diff --git a/tex/context/base/luat-kps.lua b/tex/context/base/luat-kps.lua
deleted file mode 100644
index 15dadbb84..000000000
--- a/tex/context/base/luat-kps.lua
+++ /dev/null
@@ -1,102 +0,0 @@
-if not modules then modules = { } end modules ['luat-kps'] = {
- version = 1.001,
- comment = "companion to luatools.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[ldx--
-<p>This file is used when we want the input handlers to behave like
-<type>kpsewhich</type>. What to do with the following:</p>
-
-<typing>
-{$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c}
-$SELFAUTOLOC : /usr/tex/bin/platform
-$SELFAUTODIR : /usr/tex/bin
-$SELFAUTOPARENT : /usr/tex
-</typing>
-
-<p>How about just forgetting abou them?</p>
---ldx]]--
-
-input = input or { }
-input.suffixes = input.suffixes or { }
-input.formats = input.formats or { }
-
-input.suffixes['gf'] = { '<resolution>gf' }
-input.suffixes['pk'] = { '<resolution>pk' }
-input.suffixes['base'] = { 'base' }
-input.suffixes['bib'] = { 'bib' }
-input.suffixes['bst'] = { 'bst' }
-input.suffixes['cnf'] = { 'cnf' }
-input.suffixes['mem'] = { 'mem' }
-input.suffixes['mf'] = { 'mf' }
-input.suffixes['mfpool'] = { 'pool' }
-input.suffixes['mft'] = { 'mft' }
-input.suffixes['mppool'] = { 'pool' }
-input.suffixes['graphic/figure'] = { 'eps', 'epsi' }
-input.suffixes['texpool'] = { 'pool' }
-input.suffixes['PostScript header'] = { 'pro' }
-input.suffixes['ist'] = { 'ist' }
-input.suffixes['web'] = { 'web', 'ch' }
-input.suffixes['cweb'] = { 'w', 'web', 'ch' }
-input.suffixes['cmap files'] = { 'cmap' }
-input.suffixes['lig files'] = { 'lig' }
-input.suffixes['bitmap font'] = { }
-input.suffixes['MetaPost support'] = { }
-input.suffixes['TeX system documentation'] = { }
-input.suffixes['TeX system sources'] = { }
-input.suffixes['dvips config'] = { }
-input.suffixes['type42 fonts'] = { }
-input.suffixes['web2c files'] = { }
-input.suffixes['other text files'] = { }
-input.suffixes['other binary files'] = { }
-input.suffixes['opentype fonts'] = { 'otf' }
-
-input.suffixes['fmt'] = { 'fmt' }
-input.suffixes['texmfscripts'] = { 'rb','lua','py','pl' }
-
-input.suffixes['pdftex config'] = { }
-input.suffixes['Troff fonts'] = { }
-
-input.suffixes['ls-R'] = { }
-
---[[ldx--
-<p>If you wondered abou tsome of the previous mappings, how about
-the next bunch:</p>
---ldx]]--
-
-input.formats['bib'] = ''
-input.formats['bst'] = ''
-input.formats['mft'] = ''
-input.formats['ist'] = ''
-input.formats['web'] = ''
-input.formats['cweb'] = ''
-input.formats['MetaPost support'] = ''
-input.formats['TeX system documentation'] = ''
-input.formats['TeX system sources'] = ''
-input.formats['Troff fonts'] = ''
-input.formats['dvips config'] = ''
-input.formats['graphic/figure'] = ''
-input.formats['ls-R'] = ''
-input.formats['other text files'] = ''
-input.formats['other binary files'] = ''
-
-input.formats['gf'] = ''
-input.formats['pk'] = ''
-input.formats['base'] = 'MFBASES'
-input.formats['cnf'] = ''
-input.formats['mem'] = 'MPMEMS'
-input.formats['mf'] = 'MFINPUTS'
-input.formats['mfpool'] = 'MFPOOL'
-input.formats['mppool'] = 'MPPOOL'
-input.formats['texpool'] = 'TEXPOOL'
-input.formats['PostScript header'] = 'TEXPSHEADERS'
-input.formats['cmap files'] = 'CMAPFONTS'
-input.formats['type42 fonts'] = 'T42FONTS'
-input.formats['web2c files'] = 'WEB2C'
-input.formats['pdftex config'] = 'PDFTEXCONFIG'
-input.formats['texmfscripts'] = 'TEXMFSCRIPTS'
-input.formats['bitmap font'] = ''
-input.formats['lig files'] = 'LIGFONTS'
diff --git a/tex/context/base/luat-lib.lua b/tex/context/base/luat-lib.lua
deleted file mode 100644
index 06d00e778..000000000
--- a/tex/context/base/luat-lib.lua
+++ /dev/null
@@ -1,174 +0,0 @@
-if not modules then modules = { } end modules ['luat-lib'] = {
- version = 1.001,
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
- comment = "companion to luat-lib.tex",
-}
-
--- most code already moved to the l-*.lua and other luat-*.lua files
-
-os.setlocale(nil,nil) -- useless feature and even dangerous in luatex
-
-function os.setlocale()
- -- no way you can mess with it
-end
-
-if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaonly" then
- arg[-1]=arg[0] arg[0]=arg[2] for k=3,#arg do arg[k-2]=arg[k] end arg[#arg]=nil arg[#arg]=nil
-end
-
-environment = environment or { }
-environment.arguments = { }
-environment.files = { }
-environment.sortedflags = nil
-
-function environment.initialize_arguments(arg)
- local arguments, files = { }, { }
- environment.arguments, environment.files, environment.sortedflags = arguments, files, nil
- for index, argument in pairs(arg) do
- if index > 0 then
- local flag, value = argument:match("^%-+(.+)=(.-)$")
- if flag then
- arguments[flag] = string.unquote(value or "")
- else
- flag = argument:match("^%-+(.+)")
- if flag then
- arguments[flag] = true
- else
- files[#files+1] = argument
- end
- end
- end
- end
- environment.ownname = environment.ownname or arg[0] or 'unknown.lua'
-end
-
-function environment.showarguments()
- for k,v in pairs(environment.arguments) do
- print(k .. " : " .. tostring(v))
- end
- if #environment.files > 0 then
- print("files : " .. table.concat(environment.files, " "))
- end
-end
-
-function environment.setargument(name,value)
- environment.arguments[name] = value
-end
-
-function environment.argument(name) -- todo: default (plus typecheck on default)
- local arguments, sortedflags = environment.arguments, environment.sortedflags
- if arguments[name] then
- return arguments[name]
- else
- if not sortedflags then
- sortedflags = { }
- for _,v in pairs(table.sortedkeys(arguments)) do
- sortedflags[#sortedflags+1] = "^" .. v
- end
- environment.sortedflags = sortedflags
- end
- for _,v in ipairs(sortedflags) do
- if name:find(v) then
- return arguments[v:sub(2,#v)]
- end
- end
- end
- return nil
-end
-
-function environment.split_arguments(separator) -- rather special, cut-off before separator
- local done, before, after = false, { }, { }
- for _,v in ipairs(environment.original_arguments) do
- if not done and v == separator then
- done = true
- elseif done then
- after[#after+1] = v
- else
- before[#before+1] = v
- end
- end
- return before, after
-end
-
---~ function environment.reconstruct_commandline(arg)
---~ if not arg then arg = environment.original_arguments end
---~ local result = { }
---~ for _,a in ipairs(arg) do -- ipairs 1 .. #n
---~ local kk, vv = a:match("^(%-+.-)=(.+)$")
---~ if kk and vv then
---~ if vv:find(" ") then
---~ vv = vv:unquote()
---~ vv = vv:gsub('"','\\"')
---~ result[#result+1] = kk .. "=" .. vv:quote()
---~ else
---~ a = a:unquote()
---~ a = a:gsub('"','\\"')
---~ result[#result+1] = a
---~ end
---~ elseif a:find(" ") then
---~ a = a:unquote()
---~ a = a:gsub('"','\\"')
---~ result[#result+1] = a:quote()
---~ else
---~ result[#result+1] = a
---~ end
---~ end
---~ return table.join(result," ")
---~ end
-
-function environment.reconstruct_commandline(arg,noquote)
- if not arg then arg = environment.original_arguments end
- if noquote and #arg == 1 then
- local a = arg[1]
- a = input.resolve(a)
- a = a:unquote()
- return a
- elseif #arg == 1 then
- local result = { }
- for _,a in ipairs(arg) do -- ipairs 1 .. #n
- a = input.resolve(a)
- a = a:unquote()
- a = a:gsub('"','\\"') -- tricky
- if a:find(" ") then
- result[#result+1] = a:quote()
- else
- result[#result+1] = a
- end
- end
- return table.join(result," ")
- end
-end
-
-if arg then
-
- -- new, reconstruct quoted snippets (maybe better just remnove the " then and add them later)
- local newarg, instring = { }, false
-
- for index, argument in ipairs(arg) do
- if argument:find("^\"") then
- newarg[#newarg+1] = argument:gsub("^\"","")
- if not argument:find("\"$") then
- instring = true
- end
- elseif argument:find("\"$") then
- newarg[#newarg] = newarg[#newarg] .. " " .. argument:gsub("\"$","")
- instring = false
- elseif instring then
- newarg[#newarg] = newarg[#newarg] .. " " .. argument
- else
- newarg[#newarg+1] = argument
- end
- end
- for i=1,-5,-1 do
- newarg[i] = arg[i]
- end
-
- environment.initialize_arguments(newarg)
- environment.original_arguments = newarg
- environment.raw_arguments = arg
-
- arg = { } -- prevent duplicate handling
-
-end
diff --git a/tex/context/base/luat-lib.tex b/tex/context/base/luat-lib.tex
index 9693595b2..ec781f3cf 100644
--- a/tex/context/base/luat-lib.tex
+++ b/tex/context/base/luat-lib.tex
@@ -2,7 +2,7 @@
%D [ file=luat-lib,
%D version=2006.09.11,
%D title=\CONTEXT\ Lua Macros,
-%D subtitle=Unicode Support,
+%D subtitle=Libraries,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,60 +11,41 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% \writestatus{loading}{Lua Support Macros (libs)}
+% \writestatus{loading}{ConTeXt Lua Macros / Libraries}
-%D For the moment we only load this lib.
+\registerctxluafile{trac-inf} {1.001}
+\registerctxluafile{trac-tra} {1.001}
+\registerctxluafile{trac-log} {1.001}
-%D This will move cq. become configurable. The XML like output is just
-%D an example.
-
-% todo \let\normaleverytoks\everytoks \newtoks\everytoke \normaleverytoks{\the\everytoks}
-
-\chardef\statuswidth=15
-\chardef\statuswrite=16
-
-\newtoks\everywritestring
-
-\def\writedirect {\immediate\write\statuswrite}
-\def\writeline {\writedirect{}}
-\def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup}
-
-\ifx\normalmessage \undefined \let\normalmessage \message \fi
-\ifx\normalwritestatus\undefined \def\normalwritestatus#1#2{\writedirect{#1 : #2}} \fi
-
-% this will change once we have proper write overloads
+\registerctxluafile{luat-cbk} {1.001}
-\registerctxluafile{l-string} {1.001}
-\registerctxluafile{l-lpeg} {1.001}
-\registerctxluafile{l-boolean}{1.001}
-\registerctxluafile{l-number} {1.001}
-\registerctxluafile{l-set} {1.001}
-\registerctxluafile{l-math} {1.001}
-\registerctxluafile{l-table} {1.001}
-\registerctxluafile{l-md5} {1.001}
-\registerctxluafile{l-aux} {1.001}
-\registerctxluafile{l-io} {1.001}
-\registerctxluafile{l-os} {1.001}
-\registerctxluafile{l-file} {1.001}
-\registerctxluafile{l-dir} {1.001}
-\registerctxluafile{l-unicode}{1.001}
-\registerctxluafile{l-utils} {1.001}
-\registerctxluafile{l-dimen} {1.001}
-\registerctxluafile{l-url} {1.001}
-\registerctxluafile{l-xml} {1.001}
-%registerctxluafile{l-xmlctx} {1.001}
+\registerctxluafile{data-res} {1.001}
+\registerctxluafile{data-tmp} {1.001}
+\registerctxluafile{data-pre} {1.001}
+\registerctxluafile{data-inp} {1.001}
+\registerctxluafile{data-out} {1.001}
+\registerctxluafile{data-tex} {1.001}
+\registerctxluafile{data-bin} {1.001}
+\registerctxluafile{data-zip} {1.001}
+\registerctxluafile{data-crl} {1.001}
+\registerctxluafile{data-tre} {1.001}
+\registerctxluafile{data-lua} {1.001}
+\registerctxluafile{data-ctx} {1.001}
+\registerctxluafile{data-con} {1.001}
+\registerctxluafile{data-use} {1.001}
-\registerctxluafile{luat-cbk} {1.001}
-\registerctxluafile{luat-lib} {1.001}
-\registerctxluafile{luat-inp} {1.001}
-\registerctxluafile{luat-log} {1.001}
-\registerctxluafile{luat-zip} {1.001}
-\registerctxluafile{luat-tex} {1.001}
+\registerctxluafile{luat-run} {1.001}
+\registerctxluafile{luat-fio} {1.001} % not needed, part of startup file
+\registerctxluafile{luat-cnf} {1.001} % not needed, part of startup file
\registerctxluafile{luat-lua} {1.001}
-\registerctxluafile{luat-tre} {1.001}
+\registerctxluafile{luat-sto} {1.001}
+\registerctxluafile{luat-ini} {1.001}
+\registerctxluafile{luat-env} {1.001}
+
+\registerctxluafile{l-xml} {1.001} % we want tracking
\startruntimeluacode
- \edef\asciia{\ctxlua{tex.sprint(input.logmode())}}
+ \edef\asciia{\ctxlua{tex.sprint(logs.mode)}}
\edef\asciib{xml}
\ifx\asciia\asciib % brrr
\long\def\writebanner #1{\writestring {<m t='banner'>#1</m>}}
@@ -77,15 +58,8 @@
\fi
\stopruntimeluacode
-\registerctxluafile{luat-tmp}{1.001}
-\registerctxluafile{luat-crl}{1.001}
+%registerctxluafile{luat-tmp}{1.001}
\registerctxluafile{luat-exe}{1.001}
\registerctxluafile{luat-iop}{1.001}
-% trace used files (only from trees)
-%
-% \ctxlua{input.register_stop_actions(function() input.save_used_files_in_trees() end)}
-% \ctxlua{table.insert(input.stop_actions, function() input.save_used_files_in_trees() end)}
-% \ctxlua{function input.stop_actions.trace_used_files() input.save_used_files_in_trees() end}
-
\endinput
diff --git a/tex/context/base/luat-log.lua b/tex/context/base/luat-log.lua
deleted file mode 100644
index 3704b3999..000000000
--- a/tex/context/base/luat-log.lua
+++ /dev/null
@@ -1,155 +0,0 @@
-if not modules then modules = { } end modules ['luat-log'] = {
- version = 1.001,
- comment = "companion to luat-lib.tex",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[ldx--
-<p>This is a prelude to a more extensive logging module. For the sake
-of parsing log files, in addition to the standard logging we will
-provide an <l n='xml'/> structured file. Actually, any logging that
-is hooked into callbacks will be \XML\ by default.</p>
---ldx]]--
-
--- input.logger -> special tracing, driven by log level (only input)
--- input.report -> goes to terminal, depends on verbose, has banner
--- logs.report -> module specific tracing and reporting, no banner but class
-
-
-input = input or { }
-logs = logs or { }
-
---[[ldx--
-<p>This looks pretty ugly but we need to speed things up a bit.</p>
---ldx]]--
-
-logs.levels = {
- ['error'] = 1,
- ['warning'] = 2,
- ['info'] = 3,
- ['debug'] = 4
-}
-
-logs.functions = {
- 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct'
-}
-
-logs.callbacks = {
- 'start_page_number',
- 'stop_page_number',
- 'report_output_pages',
- 'report_output_log'
-}
-
-logs.tracers = {
-}
-
-logs.xml = logs.xml or { }
-logs.tex = logs.tex or { }
-
-logs.level = 0
-
-local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format
-
-if texlua then
- write_nl = print
- write = io.write
-end
-
-function logs.xml.report(category,fmt,...) -- new
- write_nl(format("<r category='%s'>%s</r>",category,format(fmt,...)))
-end
-function logs.xml.line(fmt,...) -- new
- write_nl(format("<r>%s</r>",format(fmt,...)))
-end
-
-function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end
-function logs.xml.stop () if logs.level > 0 then tw("</%s>") end end
-function logs.xml.push () if logs.level > 0 then tw("<!-- ") end end
-function logs.xml.pop () if logs.level > 0 then tw(" -->" ) end end
-
-function logs.tex.report(category,fmt,...) -- new
- -- write_nl(format("%s | %s",category,format(fmt,...))) -- arg to format can be tex comment so .. .
- write_nl(category .. " | " .. format(fmt,...))
-end
-function logs.tex.line(fmt,...) -- new
- write_nl(format(fmt,...))
-end
-
-function logs.set_level(level)
- logs.level = logs.levels[level] or level
-end
-
-function logs.set_method(method)
- for _, v in pairs(logs.functions) do
- logs[v] = logs[method][v] or function() end
- end
- if callback and input[method] then
- for _, cb in pairs(logs.callbacks) do
- callback.register(cb, input[method][cb])
- end
- end
-end
-
-function logs.xml.start_page_number()
- write_nl(format("<p real='%s' page='%s' sub='%s'", tex.count[0], tex.count[1], tex.count[2]))
-end
-
-function logs.xml.stop_page_number()
- write("/>")
- write_nl("")
-end
-
-function logs.xml.report_output_pages(p,b)
- write_nl(format("<v k='pages' v='%s'/>", p))
- write_nl(format("<v k='bytes' v='%s'/>", b))
- write_nl("")
-end
-
-function logs.xml.report_output_log()
-end
-
-function input.logger(...) -- assumes test for input.trace > n
- if input.trace > 0 then
- logs.report(...)
- end
-end
-
-function input.report(fmt,...)
- if input.verbose then
- logs.report(input.banner or "report",format(fmt,...))
- end
-end
-
-function input.reportlines(str) -- todo: <lines></lines>
- for line in str:gmatch("(.-)[\n\r]") do
- logs.report(input.banner or "report",line)
- end
-end
-
-input.moreinfo = [[
-more information about ConTeXt and the tools that come with it can be found at:
-
-maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
-webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
-wiki : http://contextgarden.net
-]]
-
-function input.help(banner,message)
- if not input.verbose then
- input.verbose = true
- -- input.report(banner,"\n")
- end
- input.report(banner,"\n")
- input.report("")
- input.reportlines(message)
- if input.moreinfo and input.moreinfo ~= "" then
- input.report("")
- input.reportlines(input.moreinfo)
- end
-end
-
-logs.set_level('error')
-logs.set_method('tex')
diff --git a/tex/context/base/luat-lua.lua b/tex/context/base/luat-lua.lua
index 128be2f4b..61be6e9d6 100644
--- a/tex/context/base/luat-lua.lua
+++ b/tex/context/base/luat-lua.lua
@@ -23,7 +23,7 @@ if lua then do
end
function lua.flush(...)
- tex.sprint("\\directlua0{lua.flush_delayed(" .. table.concat({...},',') .. ")}")
+ tex.sprint("\\directlua0{lua.flush_delayed(",table.concat({...},','),")}")
end
end end
diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua
new file mode 100644
index 000000000..09fce32c1
--- /dev/null
+++ b/tex/context/base/luat-run.lua
@@ -0,0 +1,69 @@
+if not modules then modules = { } end modules ['luat-run'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, rpadd = string.format, string.rpadd
+
+main = main or { }
+
+local start_actions = { }
+local stop_actions = { }
+
+function main.register_start_actions(...) table.insert(start_actions, ...) end
+function main.register_stop_actions (...) table.insert(stop_actions, ...) end
+
+main.show_tex_stat = main.show_tex_stat or function() end
+main.show_job_stat = main.show_job_stat or statistics.show_job_stat
+
+function main.start()
+ if logs.start_run then
+ logs.start_run()
+ end
+ for _, action in next, start_actions do
+ action()
+ end
+end
+
+function main.stop()
+ for _, action in next, stop_actions do
+ action()
+ end
+ if main.show_job_stat then
+ statistics.show(logs.report_job_stat)
+ end
+ if main.show_tex_stat then
+ for k,v in next, status.list() do
+ logs.report_tex_stat(k,v)
+ end
+ end
+ if logs.stop_run then
+ logs.stop_run()
+ end
+end
+
+function main.start_shipout_page()
+ logs.start_page_number()
+end
+
+function main.stop_shipout_page()
+ logs.stop_page_number()
+end
+
+function main.report_output_pages()
+end
+
+function main.report_output_log()
+end
+
+-- this can be done later
+
+callback.register('start_run', main.start)
+callback.register('stop_run' , main.stop)
+callback.register('report_output_pages', main.report_output_pages)
+callback.register('report_output_log' , main.report_output_log)
+callback.register('start_page_number' , main.start_shipout_page)
+callback.register('stop_page_number' , main.stop_shipout_page)
diff --git a/tex/context/base/luat-soc.lua b/tex/context/base/luat-soc.lua
new file mode 100644
index 000000000..1095ed087
--- /dev/null
+++ b/tex/context/base/luat-soc.lua
@@ -0,0 +1,11 @@
+-- This is just a loader. The package handler knows about the TEX tree.
+
+--~ require "luatex/lua/socket.lua"
+--~ require "luatex/lua/ltn12.lua"
+--~ require "luatex/lua/mime.lua"
+--~ require "luatex/lua/socket/http.lua"
+--~ require "luatex/lua/socket/url.lua"
+--~ require "luatex/lua/socket/tp.lua"
+--~ require "luatex/lua/socket/ftp.lua"
+
+-- "luatex/lua/socket/smtp.lua"
diff --git a/tex/context/base/luat-sta.lua b/tex/context/base/luat-sta.lua
index 15581222c..12fa18219 100644
--- a/tex/context/base/luat-sta.lua
+++ b/tex/context/base/luat-sta.lua
@@ -5,6 +5,8 @@ if not modules then modules = { } end modules ['luat-sta'] = {
license = "see context related readme files"
}
+-- this code is used in the updater
+
states = states or { }
states.data = states.data or { }
states.hash = states.hash or { }
@@ -31,27 +33,32 @@ end
function states.set_by_tag(tag,key,value,default,persistent)
local d, h = states.data[tag], states.hash[tag]
if d then
- local dkey, hkey = key, key
- local pre, post = key:match("(.+)%.([^%.]+)$")
- if pre and post then
- for k in pre:gmatch("[^%.]+") do
- local dk = d[k]
- if not dk then
- dk = { }
- d[k] = dk
+ if type(d) == "table" then
+ local dkey, hkey = key, key
+ local pre, post = key:match("(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in pre:gmatch("[^%.]+") do
+ local dk = d[k]
+ if not dk then
+ dk = { }
+ d[k] = dk
+ end
+ d = dk
end
- d = dk
+ dkey, hkey = post, key
end
- dkey, hkey = post, key
- end
- if type(value) == nil then
- value = value or default
- elseif persistent then
- value = value or d[dkey] or default
- else
- value = value or default
+ if type(value) == nil then
+ value = value or default
+ elseif persistent then
+ value = value or d[dkey] or default
+ else
+ value = value or default
+ end
+ d[dkey], h[hkey] = value, value
+ elseif type(d) == "string" then
+ -- weird
+ states.data[tag], states.hash[tag] = value, value
end
- d[dkey], h[hkey] = value, value
end
end
@@ -171,7 +178,6 @@ end
--~ },
--~ }
-
--~ states.save("teststate", "update")
--~ states.load("teststate", "update")
diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua
new file mode 100644
index 000000000..10de76b28
--- /dev/null
+++ b/tex/context/base/luat-sto.lua
@@ -0,0 +1,134 @@
+if not modules then modules = { } end modules ['luat-sto'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next = type, next
+local gmatch, format, write_nl = string.gmatch, string.format, texio.write_nl
+
+storage = storage or { }
+storage.min = 0 -- 500
+storage.max = storage.min - 1
+storage.noftables = storage.noftables or 0
+storage.nofmodules = storage.nofmodules or 0
+storage.data = { }
+storage.evaluators = { }
+
+local evaluators = storage.evaluators -- (evaluate,message,names)
+local data = storage.data
+
+function storage.register(...)
+ data[#data+1] = { ... }
+end
+
+-- evaluators .. messy .. to be redone
+
+function storage.evaluate(name)
+ evaluators[#evaluators+1] = name
+end
+
+function storage.finalize() -- we can prepend the string with "evaluate:"
+ for i=1,#evaluators do
+ local t = evaluators[i]
+ for i, v in next, t do
+ local tv = type(v)
+ if tv == "string" then
+ t[i] = loadstring(v)()
+ elseif tv == "table" then
+ for _, vv in next, v do
+ if type(vv) == "string" then
+ t[i] = loadstring(vv)()
+ end
+ end
+ elseif tv == "function" then
+ t[i] = v()
+ end
+ end
+ end
+end
+
+function storage.dump()
+ for i=1,#data do
+ local d = data[i]
+ local message, original, target, evaluate = d[1], d[2] ,d[3] ,d[4]
+ local name, initialize, finalize, code = nil, "", "", ""
+ for str in gmatch(target,"([^%.]+)") do
+ if name then
+ name = name .. "." .. str
+ else
+ name = str
+ end
+ initialize = format("%s %s = %s or {} ", initialize, name, name)
+ end
+ if evaluate then
+ finalize = "storage.evaluate(" .. name .. ")"
+ end
+ storage.max = storage.max + 1
+ if trace_storage then
+ logs.report('storage','saving %s in slot %s',message,storage.max)
+ code =
+ initialize ..
+ format("logs.report('storage','restoring %s from slot %s') ",message,storage.max) ..
+ table.serialize(original,name) ..
+ finalize
+ else
+ code = initialize .. table.serialize(original,name) .. finalize
+ end
+ lua.bytecode[storage.max] = loadstring(code)
+ end
+end
+
+-- we also need to count at generation time (nicer for message)
+
+if lua.bytecode then -- from 0 upwards
+ local i, b = storage.min, lua.bytecode
+ while b[i] do
+ storage.noftables = i
+ b[i]()
+ b[i] = nil
+ i = i + 1
+ end
+end
+
+statistics.register("stored bytecode data", function()
+ local modules = (storage.nofmodules > 0 and storage.nofmodules) or (status.luabytecodes - 500)
+ local dumps = (storage.noftables > 0 and storage.noftables) or storage.max-storage.min + 1
+ return format("%s modules, %s tables, %s chunks",modules,dumps,modules+dumps)
+end)
+
+if lua.bytedata then
+ storage.register("lua/bytedata",lua.bytedata,"lua.bytedata")
+end
+
+-- wrong place, kind of forward reference
+
+function statistics.report_storage(whereto)
+ whereto = whereto or "term and log"
+ write_nl(whereto," ","stored tables:"," ")
+ for k,v in table.sortedpairs(storage.data) do
+ write_nl(whereto,format("%03i %s",k,v[1]))
+ end
+ write_nl(whereto," ","stored modules:"," ")
+ for k,v in table.sortedpairs(lua.bytedata) do
+ write_nl(whereto,format("%03i %s %s",k,v[2],v[1]))
+ end
+ write_nl(whereto," ","stored attributes:"," ")
+ for k,v in table.sortedpairs(attributes.names) do
+ write_nl(whereto,format("%03i %s",k,v))
+ end
+ write_nl(whereto," ","stored catcodetables:"," ")
+ for k,v in table.sortedpairs(catcodes.names) do
+ write_nl(whereto,format("%03i %s",k,v))
+ end
+ write_nl(whereto," ")
+end
+
+storage.shared = storage.shared or { }
+
+-- Because the storage mechanism assumes tables, we define a table for storing
+-- (non table) values.
+
+storage.register("storage/shared", storage.shared, "storage.shared")
diff --git a/tex/context/base/luat-tex.lua b/tex/context/base/luat-tex.lua
deleted file mode 100644
index 8560c528d..000000000
--- a/tex/context/base/luat-tex.lua
+++ /dev/null
@@ -1,588 +0,0 @@
--- filename : luat-zip.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['luat-tex'] = 1.001
-
--- special functions that deal with io
-
-local format = string.format
-
-if texconfig and not texlua then
-
- input.level = input.level or 0
-
- if input.logmode() == 'xml' then
- function input.show_open(name)
- input.level = input.level + 1
- texio.write_nl("<f l='"..input.level.."' n='"..name.."'>")
- end
- function input.show_close(name)
- texio.write("</f> ")
- input.level = input.level - 1
- end
- function input.show_load(name)
- texio.write_nl("<f l='"..(input.level+1).."' n='"..name.."'/>") -- level?
- end
- else
- function input.show_open () end
- function input.show_close() end
- function input.show_load () end
- end
-
- function input.finders.generic(tag,filename,filetype)
- local foundname = input.find_file(filename,filetype)
- if foundname and foundname ~= "" then
- if input.trace > 0 then
- input.logger('+ finder: %s, file: %s', tag,filename)
- end
- return foundname
- else
- if input.trace > 0 then
- input.logger('- finder: %s, file: %s', tag,filename)
- end
- return unpack(input.finders.notfound)
- end
- end
-
- input.filters.dynamic_translator = nil
- input.filters.frozen_translator = nil -- not used here
- input.filters.utf_translator = nil
- input.filters.user_translator = nil
-
- function input.openers.text_opener(filename,file_handle,tag)
- local u = unicode.utftype(file_handle)
- local t = { }
- if u > 0 then
- if input.trace > 0 then
- input.logger('+ opener: %s (%s), file: %s',tag,unicode.utfname[u],filename)
- end
- local l
- if u > 2 then
- l = unicode.utf32_to_utf8(file_handle:read("*a"),u==4)
- else
- l = unicode.utf16_to_utf8(file_handle:read("*a"),u==2)
- end
- file_handle:close()
- t = {
- utftype = u, -- may go away
- lines = l,
- current = 0, -- line number, not really needed
- handle = nil,
- noflines = #l,
- close = function()
- if input.trace > 0 then
- input.logger('= closer: %s (%s), file: %s',tag,unicode.utfname[u],filename)
- end
- input.show_close(filename)
- t = nil
- end,
---~ getline = function(n)
---~ local line = t.lines[n]
---~ if not line or line == "" then
---~ return ""
---~ else
---~ local translator = input.filters.utf_translator
---~ return (translator and translator(line)) or line
---~ end
---~ end,
- reader = function(self)
- self = self or t
- local current, lines = self.current, self.lines
- if current >= #lines then
- return nil
- else
- current = current + 1
- self.current = current
- local line = lines[current]
- if not line then
- return nil
- elseif line == "" then
- return ""
- else
- translator = filters.utf_translator
- if translator then
- line = translator(line)
- translator = filters.user_translator
- if translator then
- line = translator(line)
- end
- end
- return line
- end
- end
- end
- }
- else
- if input.trace > 0 then
- input.logger('+ opener: %s, file: %s',tag,filename)
- end
- -- todo: file;name -> freeze / eerste regel scannen -> freeze
- local filters = input.filters
- t = {
- reader = function(self)
- local line = file_handle:read()
- if not line then
- return nil
- elseif line == "" then
- return ""
- else
- translator = filters.dynamic_translator or filters.utf_translator
- if translator then
- line = translator(line)
- translator = filters.user_translator
- if translator then
- line = translator(line)
- end
- end
- return line
- end
- end,
- close = function()
- if input.trace > 0 then
- input.logger('= closer: %s, file: %s',tag,filename)
- end
- input.show_close(filename)
- file_handle:close()
- t = nil
- end,
- handle = function()
- return file_handle
- end,
- noflines = function()
- t.noflines = io.noflines(file_handle)
- return t.noflines
- end
- }
- end
- return t
- end
-
- function input.openers.generic(tag,filename)
- if filename and filename ~= "" then
- local f = io.open(filename,"r")
- if f then
- input.show_open(filename)
- return input.openers.text_opener(filename,f,tag)
- end
- end
- if input.trace > 0 then
- input.logger('- opener: %s, file: %s',tag,filename)
- end
- return unpack(input.openers.notfound)
- end
-
- function input.loaders.generic(tag,filename)
- if filename and filename ~= "" then
- local f = io.open(filename,"rb")
- if f then
- input.show_load(filename)
- if input.trace > 0 then
- input.logger('+ loader: %s, file: %s',tag,filename)
- end
- local s = f:read("*a")
- if garbagecollector and garbagecollector.check then garbagecollector.check(#s) end
- f:close()
- if s then
- return true, s, #s
- end
- end
- end
- if input.trace > 0 then
- input.logger('- loader: %s, file: %s',tag,filename)
- end
- return unpack(input.loaders.notfound)
- end
-
- function input.finders.tex(filename,filetype)
- return input.finders.generic('tex',filename,filetype)
- end
- function input.openers.tex(filename)
- return input.openers.generic('tex',filename)
- end
- function input.loaders.tex(filename)
- return input.loaders.generic('tex',filename)
- end
-
-end
-
--- callback into the file io and related things; disabling kpse
-
-
-if texconfig and not texlua then do
-
- -- this is not the right place, because we refer to quite some not yet defined tables, but who cares ...
-
- ctx = ctx or { }
-
- function ctx.writestatus(a,b,c,...)
- if c then
- texio.write_nl(("%-15s: %s\n"):format(a,b:format(c,...)))
- else
- texio.write_nl(("%-15s: %s\n"):format(a,b)) -- b can have %'s
- end
- end
-
- -- this will become: ctx.install_statistics(fnc() return ..,.. end) etc
-
- local statusinfo, n = { }, 0
-
- function ctx.register_statistics(tag,pattern,fnc)
- statusinfo[#statusinfo+1] = { tag, pattern, fnc }
- if #tag > n then n = #tag end
- end
-
- function ctx.memused() -- no math.round yet -)
- -- collectgarbage("collect")
- local round = math.round or math.floor
- return string.format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000))
- end
-
- function ctx.show_statistics() -- todo: move calls
- local loadtime, register_statistics = input.loadtime, ctx.register_statistics
- if caches then
- register_statistics("used config path", "%s", function() return caches.configpath() end)
- register_statistics("used cache path", "%s", function() return caches.temp() or "?" end)
- end
- if status.luabytecodes > 0 and input.storage and input.storage.done then
- register_statistics("modules/dumps/instances", "%s/%s/%s", function() return status.luabytecodes-500, input.storage.done, status.luastates end)
- end
- if input.instance then
- register_statistics("input load time", "%s seconds", function() return loadtime(input.instance) end)
- end
- if ctx and input.hastimer(ctx) then
- register_statistics("startup time","%s seconds (including runtime option file processing)", function() return loadtime(ctx) end)
- end
- if job then
- register_statistics("jobdata time","%s seconds saving, %s seconds loading", function() return loadtime(job._save_), loadtime(job._load_) end)
- end
- if fonts then
- register_statistics("fonts load time","%s seconds", function() return loadtime(fonts) end)
- end
- if xml then
- register_statistics("xml load time", "%s seconds, lpath calls: %s, cached calls: %s", function()
- local stats = xml.statistics()
- return loadtime(xml), stats.lpathcalls, stats.lpathcached
- end)
- register_statistics("lxml load time", "%s seconds preparation, backreferences: %i", function()
- return loadtime(lxml), #lxml.self
- end)
- end
- if mptopdf then
- register_statistics("mps conversion time", "%s seconds", function() return loadtime(mptopdf) end)
- end
- if nodes then
- register_statistics("node processing time", "%s seconds including kernel", function() return loadtime(nodes) end)
- end
- if kernel then
- register_statistics("kernel processing time", "%s seconds", function() return loadtime(kernel) end)
- end
- if attributes then
- register_statistics("attribute processing time", "%s seconds", function() return loadtime(attributes) end)
- end
- if languages then
- register_statistics("language load time", "%s seconds, n=%s", function() return loadtime(languages), languages.hyphenation.n() end)
- end
- if figures then
- register_statistics("graphics processing time", "%s seconds including tex, n=%s", function() return loadtime(figures), figures.n or "?" end)
- end
- if metapost then
- register_statistics("metapost processing time", "%s seconds, loading: %s seconds, execution: %s seconds, n: %s", function() return loadtime(metapost), loadtime(mplib), loadtime(metapost.exectime), metapost.n end)
- end
- if status.luastate_bytes and ctx.memused then
- register_statistics("current memory usage", "%s", ctx.memused)
- end
- if nodes then
- register_statistics("cleaned up reserved nodes", "%s nodes, %s lists of %s", function() return nodes.cleanup_reserved(tex.count[24]) end) -- \topofboxstack
- end
- if status.node_mem_usage then
- register_statistics("node memory usage", "%s", function() return status.node_mem_usage end)
- end
- if languages then
- register_statistics("loaded patterns", "%s", function() return languages.logger.report() end)
- end
- if fonts then
- register_statistics("loaded fonts", "%s", function() return fonts.logger.report() end)
- end
- if status.cs_count then
- register_statistics("control sequences", "%s of %s", function() return status.cs_count, status.hash_size+status.hash_extra end)
- end
- if status.callbacks and xml then -- xml for being in context -)
- ctx.register_statistics("callbacks", "direct: %s, indirect: %s, total: %s%s", function()
- local total, indirect = status.callbacks, status.indirect_callbacks
- local pages = tex.count['realpageno'] - 1
- if pages > 1 then
- return total-indirect, indirect, total, format(" (%i per page)",total/pages)
- else
- return total-indirect, indirect, total, ""
- end
- end)
- else
- ctx.register_statistics("callbacks", "direct: %s, indirect: %s, total: %s", function()
- local total, indirect = status.callbacks, status.indirect_callbacks
- return total-indirect, indirect, total
- end)
- end
- if xml then -- so we are in mkiv, we need a different check
- register_statistics("runtime", "%s seconds, %i processed pages, %i shipped pages, %.3f pages/second", function()
- input.stoptiming(input.instance)
- local runtime = loadtime(input.instance)
- local shipped = tex.count['nofshipouts']
- local pages = tex.count['realpageno'] - 1
- local persecond = shipped / runtime
- return runtime, pages, shipped, persecond
- end)
- end
- for _, t in ipairs(statusinfo) do
- local tag, pattern, fnc = t[1], t[2], t[3]
- ctx.writestatus("mkiv lua stats", "%s - %s", tag:rpadd(n," "), pattern:format(fnc()))
- end-- input.expanded_path_list("osfontdir")
- end
-
-end end
-
-if texconfig and not texlua then
-
- texconfig.kpse_init = false
- texconfig.trace_file_names = input.logmode() == 'tex'
- texconfig.max_print_line = 100000
-
- -- if still present, we overload kpse (put it off-line so to say)
-
- input.starttiming(input.instance)
-
- if not input.instance then
-
- if not input.instance then -- prevent a second loading
-
- input.instance = input.reset()
- input.instance.progname = 'context'
- input.instance.engine = 'luatex'
- input.instance.validfile = input.validctxfile
-
- input.load()
-
- end
-
- if callback then
- callback.register('find_read_file' , function(id,name) return input.findtexfile(name) end)
- callback.register('open_read_file' , function( name) return input.opentexfile(name) end)
- end
-
- if callback then
- callback.register('find_data_file' , function(name) return input.findbinfile(name,"tex") end)
- callback.register('find_enc_file' , function(name) return input.findbinfile(name,"enc") end)
- callback.register('find_font_file' , function(name) return input.findbinfile(name,"tfm") end)
- callback.register('find_format_file' , function(name) return input.findbinfile(name,"fmt") end)
- callback.register('find_image_file' , function(name) return input.findbinfile(name,"tex") end)
- callback.register('find_map_file' , function(name) return input.findbinfile(name,"map") end)
- callback.register('find_ocp_file' , function(name) return input.findbinfile(name,"ocp") end)
- callback.register('find_opentype_file' , function(name) return input.findbinfile(name,"otf") end)
- callback.register('find_output_file' , function(name) return name end)
- callback.register('find_pk_file' , function(name) return input.findbinfile(name,"pk") end)
- callback.register('find_sfd_file' , function(name) return input.findbinfile(name,"sfd") end)
- callback.register('find_truetype_file' , function(name) return input.findbinfile(name,"ttf") end)
- callback.register('find_type1_file' , function(name) return input.findbinfile(name,"pfb") end)
- callback.register('find_vf_file' , function(name) return input.findbinfile(name,"vf") end)
-
- callback.register('read_data_file' , function(file) return input.loadbinfile(file,"tex") end)
- callback.register('read_enc_file' , function(file) return input.loadbinfile(file,"enc") end)
- callback.register('read_font_file' , function(file) return input.loadbinfile(file,"tfm") end)
- -- format
- -- image
- callback.register('read_map_file' , function(file) return input.loadbinfile(file,"map") end)
- callback.register('read_ocp_file' , function(file) return input.loadbinfile(file,"ocp") end)
---~ callback.register('read_opentype_file' , function(file) return input.loadbinfile(file,"otf") end)
- -- output
- callback.register('read_pk_file' , function(file) return input.loadbinfile(file,"pk") end)
- callback.register('read_sfd_file' , function(file) return input.loadbinfile(file,"sfd") end)
---~ callback.register('read_truetype_file' , function(file) return input.loadbinfile(file,"ttf") end)
---~ callback.register('read_type1_file' , function(file) return input.loadbinfile(file,"pfb") end)
- callback.register('read_vf_file' , function(file) return input.loadbinfile(file,"vf" ) end)
- end
-
- if input.aleph_mode == nil then environment.aleph_mode = true end -- some day we will drop omega font support
-
- if callback and input.aleph_mode then
- callback.register('find_font_file' , function(name) return input.findbinfile(name,"ofm") end)
- callback.register('read_font_file' , function(file) return input.loadbinfile(file,"ofm") end)
- callback.register('find_vf_file' , function(name) return input.findbinfile(name,"ovf") end)
- callback.register('read_vf_file' , function(file) return input.loadbinfile(file,"ovf") end)
- end
-
- if callback then
- callback.register('find_write_file' , function(id,name) return name end)
- end
-
- if callback and (not config or (#config == 0)) then
- callback.register('find_format_file' , function(name) return name end)
- end
-
- if callback and false then
- for k, v in pairs(callback.list()) do
- if not v then texio.write_nl("<w>callback "..k.." is not set</w>") end
- end
- end
-
- if callback then
-
- input.start_actions = { }
- input.stop_actions = { }
-
- function input.register_start_actions(f) table.insert(input.start_actions, f) end
- function input.register_stop_actions (f) table.insert(input.stop_actions, f) end
-
- --~ callback.register('start_run', function() for _, a in pairs(input.start_actions) do a() end end)
- --~ callback.register('stop_run' , function() for _, a in pairs(input.stop_actions ) do a() end end)
-
- end
-
- if callback then
-
- if input.logmode() == 'xml' then
-
- function input.start_page_number()
- texio.write_nl("<p real='" .. tex.count[0] .. "' page='"..tex.count[1].."' sub='"..tex.count[2].."'")
- end
- function input.stop_page_number()
- texio.write("/>")
- texio.write_nl("")
- end
-
- callback.register('start_page_number' , input.start_page_number)
- callback.register('stop_page_number' , input.stop_page_number )
-
- function input.report_output_pages(p,b)
- texio.write_nl("<v k='pages'>"..p.."</v>")
- texio.write_nl("<v k='bytes'>"..b.."</v>")
- texio.write_nl("")
- end
- function input.report_output_log()
- end
-
- callback.register('report_output_pages', input.report_output_pages)
- callback.register('report_output_log' , input.report_output_log )
-
- function input.start_run()
- texio.write_nl("<?xml version='1.0' standalone='yes'?>")
- texio.write_nl("<job xmlns='www.tug.org/luatex/schemas/context-job.rng'>")
- texio.write_nl("")
- end
- function input.stop_run()
- texio.write_nl("</job>")
- end
- function input.show_statistics()
- for k,v in pairs(status.list()) do
- texio.write_nl("log","<v k='"..k.."'>"..tostring(v).."</v>")
- end
- end
-
- table.insert(input.start_actions, input.start_run)
- table.insert(input.stop_actions , input.show_statistics)
- table.insert(input.stop_actions , input.stop_run)
-
- else
- table.insert(input.stop_actions , input.show_statistics)
- end
-
- callback.register('start_run', function() for _, a in pairs(input.start_actions) do a() end end)
- callback.register('stop_run' , function() for _, a in pairs(input.stop_actions ) do a() end ctx.show_statistics() end)
-
- end
-
- end
-
- if kpse then
-
- function kpse.find_file(filename,filetype,mustexist)
- return input.find_file(filename,filetype,mustexist)
- end
- function kpse.expand_path(variable)
- return input.expand_path(variable)
- end
- function kpse.expand_var(variable)
- return input.expand_var(variable)
- end
- function kpse.expand_braces(variable)
- return input.expand_braces(variable)
- end
-
- end
-
-end
-
--- program specific configuration (memory settings and alike)
-
-if texconfig and not texlua then
-
- luatex = luatex or { }
-
- luatex.variablenames = {
- 'main_memory', 'extra_mem_bot', 'extra_mem_top',
- 'buf_size','expand_depth',
- 'font_max', 'font_mem_size',
- 'hash_extra', 'max_strings', 'pool_free', 'pool_size', 'string_vacancies',
- 'obj_tab_size', 'pdf_mem_size', 'dest_names_size',
- 'nest_size', 'param_size', 'save_size', 'stack_size',
- 'trie_size', 'hyph_size', 'max_in_open',
- 'ocp_stack_size', 'ocp_list_size', 'ocp_buf_size'
- }
-
- function luatex.variables()
- local t, x = { }, nil
- for _,v in pairs(luatex.variablenames) do
- x = input.var_value(v)
- if x and x:find("^%d+$") then
- t[v] = tonumber(x)
- end
- end
- return t
- end
-
- function luatex.setvariables(tab)
- for k,v in pairs(luatex.variables()) do
- tab[k] = v
- end
- end
-
- if not luatex.variables_set then
- luatex.setvariables(texconfig)
- luatex.variables_set = true
- end
-
- texconfig.max_print_line = 100000
- texconfig.max_in_open = 127
-
-end
-
--- some tex basics, maybe this will move to ctx
-
-if tex then
-
- local texsprint, texwrite = tex.sprint, tex.write
-
- if not cs then cs = { } end
-
- function cs.def(k,v)
- texsprint(tex.texcatcodes, "\\def\\" .. k .. "{" .. v .. "}")
- end
-
- function cs.chardef(k,v)
- texsprint(tex.texcatcodes, "\\chardef\\" .. k .. "=" .. v .. "\\relax")
- end
-
- function cs.boolcase(b)
- if b then texwrite(1) else texwrite(0) end
- end
-
- function cs.testcase(b)
- if b then
- texsprint(tex.texcatcodes, "\\firstoftwoarguments")
- else
- texsprint(tex.texcatcodes, "\\secondoftwoarguments")
- end
- end
-
-end
diff --git a/tex/context/base/luat-tmp.lua b/tex/context/base/luat-tmp.lua
deleted file mode 100644
index 1e3f55380..000000000
--- a/tex/context/base/luat-tmp.lua
+++ /dev/null
@@ -1,433 +0,0 @@
-if not modules then modules = { } end modules ['luat-tmp'] = {
- version = 1.001,
- comment = "companion to luat-lib.tex",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[ldx--
-<p>This module deals with caching data. It sets up the paths and
-implements loaders and savers for tables. Best is to set the
-following variable. When not set, the usual paths will be
-checked. Personally I prefer the (users) temporary path.</p>
-
-</code>
-TEXMFCACHE=$TMP;$TEMP;$TMPDIR;$TEMPDIR;$HOME;$TEXMFVAR;$VARTEXMF;.
-</code>
-
-<p>Currently we do no locking when we write files. This is no real
-problem because most caching involves fonts and the chance of them
-being written at the same time is small. We also need to extend
-luatools with a recache feature.</p>
---ldx]]--
-
-local format = string.format
-
-caches = caches or { }
-dir = dir or { }
-texmf = texmf or { }
-
-caches.path = caches.path or nil
-caches.base = caches.base or "luatex-cache"
-caches.more = caches.more or "context"
-caches.direct = false -- true is faster but may need huge amounts of memory
-caches.trace = false
-caches.tree = false
-caches.paths = caches.paths or nil
-caches.force = false
-caches.defaults = { "TEXMFCACHE", "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" }
-
-function caches.temp()
- local cachepath = nil
- local function check(list,isenv)
- if not cachepath then
- for _, v in ipairs(list) do
- cachepath = (isenv and (os.env[v] or "")) or v or ""
- if cachepath == "" then
- -- next
- else
- cachepath = input.clean_path(cachepath)
- if lfs.isdir(cachepath) and file.iswritable(cachepath) then -- lfs.attributes(cachepath,"mode") == "directory"
- break
- elseif caches.force or io.ask(format("\nShould I create the cache path %s?",cachepath), "no", { "yes", "no" }) == "yes" then
- dir.mkdirs(cachepath)
- if lfs.isdir(cachepath) and file.iswritable(cachepath) then
- break
- end
- end
- end
- cachepath = nil
- end
- end
- end
- check(input.clean_path_list("TEXMFCACHE") or { })
- check(caches.defaults,true)
- if not cachepath then
- print("\nfatal error: there is no valid (writable) cache path defined\n")
- os.exit()
- elseif not lfs.isdir(cachepath) then -- lfs.attributes(cachepath,"mode") ~= "directory"
- print(format("\nfatal error: cache path %s is not a directory\n",cachepath))
- os.exit()
- end
- cachepath = input.normalize_name(cachepath)
- function caches.temp()
- return cachepath
- end
- return cachepath
-end
-
-function caches.configpath()
- return table.concat(input.instance.cnffiles,";")
-end
-
-function caches.hashed(tree)
- return md5.hex((tree:lower()):gsub("[\\\/]+","/"))
-end
-
---~ tracing:
-
---~ function caches.hashed(tree)
---~ tree = (tree:lower()):gsub("[\\\/]+","/")
---~ local hash = md5.hex(tree)
---~ if input.verbose then -- temp message
---~ input.report("hashing %s => %s",tree,hash)
---~ end
---~ return hash
---~ end
-
-function caches.treehash()
- local tree = caches.configpath()
- if not tree or tree == "" then
- return false
- else
- return caches.hashed(tree)
- end
-end
-
-function caches.setpath(...)
- if not caches.path then
- if not caches.path then
- caches.path = caches.temp()
- end
- caches.path = input.clean_path(caches.path) -- to be sure
- if lfs then
- caches.tree = caches.tree or caches.treehash()
- if caches.tree then
- caches.path = dir.mkdirs(caches.path,caches.base,caches.more,caches.tree)
- else
- caches.path = dir.mkdirs(caches.path,caches.base,caches.more)
- end
- end
- end
- if not caches.path then
- caches.path = '.'
- end
- caches.path = input.clean_path(caches.path)
- if lfs and not table.is_empty({...}) then
- local pth = dir.mkdirs(caches.path,...)
- return pth
- end
- caches.path = dir.expand_name(caches.path)
- return caches.path
-end
-
-function caches.definepath(category,subcategory)
- return function()
- return caches.setpath(category,subcategory)
- end
-end
-
-function caches.setluanames(path,name)
- return path .. "/" .. name .. ".tma", path .. "/" .. name .. ".tmc"
-end
-
-function caches.loaddata(path,name)
- local tmaname, tmcname = caches.setluanames(path,name)
- local loader = loadfile(tmcname) or loadfile(tmaname)
- if loader then
- return loader()
- else
- return false
- end
-end
-
-function caches.is_writable(filepath,filename)
- local tmaname, tmcname = caches.setluanames(filepath,filename)
- return file.is_writable(tmaname)
-end
-
-function caches.savedata(filepath,filename,data,raw)
- local tmaname, tmcname = caches.setluanames(filepath,filename)
- local reduce, simplify = true, true
- if raw then
- reduce, simplify = false, false
- end
- if caches.direct then
- file.savedata(tmaname, table.serialize(data,'return',true,true,false)) -- no hex
- else
- table.tofile(tmaname, data,'return',true,true,false) -- maybe not the last true
- end
- local cleanup = input.boolean_variable("PURGECACHE", false)
- local strip = input.boolean_variable("LUACSTRIP", true)
- utils.lua.compile(tmaname, tmcname, cleanup, strip)
-end
-
--- here we use the cache for format loading (texconfig.[formatname|jobname])
-
---~ if tex and texconfig and texconfig.formatname and texconfig.formatname == "" then
-if tex and texconfig and (not texconfig.formatname or texconfig.formatname == "") and input and input.instance then
- if not texconfig.luaname then texconfig.luaname = "cont-en.lua" end -- or luc
- texconfig.formatname = caches.setpath("formats") .. "/" .. texconfig.luaname:gsub("%.lu.$",".fmt")
-end
-
---[[ldx--
-<p>Once we found ourselves defining similar cache constructs
-several times, containers were introduced. Containers are used
-to collect tables in memory and reuse them when possible based
-on (unique) hashes (to be provided by the calling function).</p>
-
-<p>Caching to disk is disabled by default. Version numbers are
-stored in the saved table which makes it possible to change the
-table structures without bothering about the disk cache.</p>
-
-<p>Examples of usage can be found in the font related code.</p>
---ldx]]--
-
-containers = { }
-containers.trace = false
-
-do -- local report
-
- local function report(container,tag,name)
- if caches.trace or containers.trace or container.trace then
- logs.report(format("%s cache",container.subcategory),"%s: %s",tag,name or 'invalid')
- end
- end
-
- local allocated = { }
-
- -- tracing
-
- function containers.define(category, subcategory, version, enabled)
- return function()
- if category and subcategory then
- local c = allocated[category]
- if not c then
- c = { }
- allocated[category] = c
- end
- local s = c[subcategory]
- if not s then
- s = {
- category = category,
- subcategory = subcategory,
- storage = { },
- enabled = enabled,
- version = version or 1.000,
- trace = false,
- path = caches.setpath(category,subcategory),
- }
- c[subcategory] = s
- end
- return s
- else
- return nil
- end
- end
- end
-
- function containers.is_usable(container, name)
- return container.enabled and caches.is_writable(container.path, name)
- end
-
- function containers.is_valid(container, name)
- if name and name ~= "" then
- local storage = container.storage[name]
- return storage and not table.is_empty(storage) and storage.cache_version == container.version
- else
- return false
- end
- end
-
- function containers.read(container,name)
- if container.enabled and not container.storage[name] then
- container.storage[name] = caches.loaddata(container.path,name)
- if containers.is_valid(container,name) then
- report(container,"loaded",name)
- else
- container.storage[name] = nil
- end
- end
- if container.storage[name] then
- report(container,"reusing",name)
- end
- return container.storage[name]
- end
-
- function containers.write(container, name, data)
- if data then
- data.cache_version = container.version
- if container.enabled then
- local unique, shared = data.unique, data.shared
- data.unique, data.shared = nil, nil
- caches.savedata(container.path, name, data)
- report(container,"saved",name)
- data.unique, data.shared = unique, shared
- end
- report(container,"stored",name)
- container.storage[name] = data
- end
- return data
- end
-
- function containers.content(container,name)
- return container.storage[name]
- end
-
-end
-
--- since we want to use the cache instead of the tree, we will now
--- reimplement the saver.
-
-local save_data = input.aux.save_data
-local load_data = input.aux.load_data
-
-input.cachepath = nil -- public, for tracing
-input.usecache = true -- public, for tracing
-
-function input.aux.save_data(dataname, check)
- save_data(dataname, check, function(cachename,dataname)
- input.usecache = not toboolean(input.expansion("CACHEINTDS") or "false",true)
- if input.usecache then
- input.cachepath = input.cachepath or caches.definepath("trees")
- return file.join(input.cachepath(),caches.hashed(cachename))
- else
- return file.join(cachename,dataname)
- end
- end)
-end
-
-function input.aux.load_data(pathname,dataname,filename)
- load_data(pathname,dataname,filename,function(dataname,filename)
- input.usecache = not toboolean(input.expansion("CACHEINTDS") or "false",true)
- if input.usecache then
- input.cachepath = input.cachepath or caches.definepath("trees")
- return file.join(input.cachepath(),caches.hashed(pathname))
- else
- if not filename or (filename == "") then
- filename = dataname
- end
- return file.join(pathname,filename)
- end
- end)
-end
-
--- we will make a better format, maybe something xml or just text or lua
-
-input.automounted = input.automounted or { }
-
-function input.automount(usecache)
- local mountpaths = input.clean_path_list(input.expansion('TEXMFMOUNT'))
- if table.is_empty(mountpaths) and usecache then
- mountpaths = { caches.setpath("mount") }
- end
- if not table.is_empty(mountpaths) then
- input.starttiming(input.instance)
- for k, root in pairs(mountpaths) do
- local f = io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if line:find("^[%%#%-]") then -- or %W
- -- skip
- elseif line:find("^zip://") then
- input.report("mounting %s",line)
- table.insert(input.automounted,line)
- input.usezipfile(line)
- end
- end
- end
- f:close()
- end
- end
- input.stoptiming(input.instance)
- end
-end
-
--- store info in format
-
-input.storage = { }
-input.storage.data = { }
-input.storage.min = 0 -- 500
-input.storage.max = input.storage.min - 1
-input.storage.trace = false -- true
-input.storage.done = input.storage.done or 0
-input.storage.evaluators = { }
--- (evaluate,message,names)
-
-function input.storage.register(...)
- input.storage.data[#input.storage.data+1] = { ... }
-end
-
-function input.storage.evaluate(name)
- input.storage.evaluators[#input.storage.evaluators+1] = name
-end
-
-function input.storage.finalize() -- we can prepend the string with "evaluate:"
- for _, t in ipairs(input.storage.evaluators) do
- for i, v in pairs(t) do
- if type(v) == "string" then
- t[i] = loadstring(v)()
- elseif type(v) == "table" then
- for _, vv in pairs(v) do
- if type(vv) == "string" then
- t[i] = loadstring(vv)()
- end
- end
- end
- end
- end
-end
-
-function input.storage.dump()
- for name, data in ipairs(input.storage.data) do
- local evaluate, message, original, target = data[1], data[2], data[3] ,data[4]
- local name, initialize, finalize, code = nil, "", "", ""
- for str in target:gmatch("([^%.]+)") do
- if name then
- name = name .. "." .. str
- else
- name = str
- end
- initialize = format("%s %s = %s or {} ", initialize, name, name)
- end
- if evaluate then
- finalize = "input.storage.evaluate(" .. name .. ")"
- end
- input.storage.max = input.storage.max + 1
- if input.storage.trace then
- logs.report('storage','saving %s in slot %s',message,input.storage.max)
- code =
- initialize ..
- format("logs.report('storage','restoring %s from slot %s') ",message,input.storage.max) ..
- table.serialize(original,name) ..
- finalize
- else
- code = initialize .. table.serialize(original,name) .. finalize
- end
- lua.bytecode[input.storage.max] = loadstring(code)
- end
-end
-
--- we also need to count at generation time (nicer for message)
-
-if lua.bytecode then -- from 0 upwards
- local i = input.storage.min
- while lua.bytecode[i] do
- lua.bytecode[i]()
- lua.bytecode[i] = nil
- i = i + 1
- end
- input.storage.done = i
-end
diff --git a/tex/context/base/luat-tre.lua b/tex/context/base/luat-tre.lua
deleted file mode 100644
index ed1ff59f8..000000000
--- a/tex/context/base/luat-tre.lua
+++ /dev/null
@@ -1,45 +0,0 @@
--- filename : luat-tre.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['luat-tre'] = 1.001
-
--- \input tree://oeps1/**/oeps.tex
-
-do
-
- local done, found = { }, { }
-
- function input.finders.tree(specification,filetype)
- local fnd = found[specification]
- if not fnd then
- local spec = input.splitmethod(specification).path or ""
- if spec ~= "" then
- local path, name = file.dirname(spec), file.basename(spec)
- if path == "" then path = "." end
- local hash = done[path]
- if not hash then
- local pattern = path .. "/*" -- we will use the proper splitter
- hash = dir.glob(pattern)
- done[path] = hash
- end
- local pattern = "/" .. name:gsub("([%.%-%+])", "%%%1") .. "$"
- for k, v in pairs(hash) do
- if v:find(pattern) then
- found[specification] = v
- return v
- end
- end
- end
- fnd = unpack(input.finders.notfound)
- found[specification] = fnd
- end
- return fnd
- end
-
- input.openers.tree = input.openers.generic
- input.loaders.tree = input.loaders.generic
-
-end
diff --git a/tex/context/base/luat-uni.lua b/tex/context/base/luat-uni.lua
deleted file mode 100644
index ef57663bb..000000000
--- a/tex/context/base/luat-uni.lua
+++ /dev/null
@@ -1,21 +0,0 @@
--- filename : luat-uni.lua
--- comment : companion to luat-uni.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['luat-uni'] = 1.001
-
-function unicode.utf8.split(str)
- local t = { }
- for snippet in str:utfcharacters() do
- t[#t+1] = snippet
- end
- return t
-end
-
-function unicode.utf8.each(str,fnc)
- for snippet in str:utfcharacters() do
- fnc(snippet)
- end
-end
diff --git a/tex/context/base/luat-uni.tex b/tex/context/base/luat-uni.tex
deleted file mode 100644
index 453c8e0d8..000000000
--- a/tex/context/base/luat-uni.tex
+++ /dev/null
@@ -1,33 +0,0 @@
-%D \module
-%D [ file=luat-uni,
-%D version=2006.04.25,
-%D title=\CONTEXT\ Lua Macros,
-%D subtitle=Unicode Support,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright=PRAGMA]
-%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}{Lua Support Macros (unicode)}
-
-\registerctxluafile{luat-uni}{1.001}
-
-% \defconvertedargument\ascii{ÀÁÂÃÄÅàáâãäå}
-%
-% \lua{ tex.print ("\ascii")}
-% \lua{ tex.print(unicode.utf8.reverse ("\ascii"))}
-% \lua{ tex.print(unicode.utf8.lower ("\ascii"))}
-% \lua{ tex.print(unicode.utf8.upper ("\ascii"))}
-% \lua{ tex.print(unicode.utf8.len ("\ascii"))}
-% \lua{ tex.print(table.getn(unicode.utf8.split("\ascii"))}}
-%
-% \lua{unicode.utf8.each("\ascii", function(chr) tex.print("["..chr.."]") end)}
-
-\let\UnicodeOne \gobbleoneargument
-\let\UnicodeTwo \gobbleoneargument
-\let\UnicodeThree\gobbleoneargument
-
-\endinput
diff --git a/tex/context/base/luat-zip.lua b/tex/context/base/luat-zip.lua
deleted file mode 100644
index 40386e570..000000000
--- a/tex/context/base/luat-zip.lua
+++ /dev/null
@@ -1,249 +0,0 @@
--- filename : luat-zip.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
-if not versions then versions = { } end versions['luat-zip'] = 1.001
-
-local format = string.format
-
-if zip and input then
- zip.supported = true
-else
- zip = { }
- zip.supported = false
-end
-
-if not zip.supported then
-
- if not input then input = { } end -- will go away
-
- function zip.openarchive (...) return nil end -- needed ?
- function zip.closenarchive (...) end -- needed ?
- function input.usezipfile (...) end -- needed ?
-
-else
-
- -- zip:///oeps.zip?name=bla/bla.tex
- -- zip:///oeps.zip?tree=tex/texmf-local
-
- local function validzip(str)
- if not str:find("^zip://") then
- return "zip:///" .. str
- else
- return str
- end
- end
-
- zip.archives = { }
- zip.registeredfiles = { }
-
- function zip.openarchive(name)
- if not name or name == "" then
- return nil
- else
- local arch = zip.archives[name]
- if arch then
- return arch
- else
- local full = input.find_file(name) or ""
- local arch = (full ~= "" and zip.open(full)) or false
- zip.archives[name] = arch
- return arch
- end
- end
- end
-
- function zip.closearchive(name)
- if not name or name == "" and zip.archives[name] then
- zip.close(zip.archives[name])
- zip.archives[name] = nil
- end
- end
-
- -- zip:///texmf.zip?tree=/tex/texmf
- -- zip:///texmf.zip?tree=/tex/texmf-local
- -- zip:///texmf-mine.zip?tree=/tex/texmf-projects
-
- function input.locators.zip(specification) -- where is this used? startup zips (untested)
- specification = input.splitmethod(specification)
- local zipfile = specification.path
- local zfile = zip.openarchive(name) -- tricky, could be in to be initialized tree
- if input.trace > 0 then
- if zfile then
- input.logger('! zip locator, found: %s',specification.original)
- else
- input.logger('? zip locator, not found: %s',specification.original)
- end
- end
- end
-
- function input.hashers.zip(tag,name)
- input.report("loading zip file %s as %s",name,tag)
- input.usezipfile(tag .."?tree=" .. name)
- end
-
- function input.concatinators.zip(tag,path,name)
- if not path or path == "" then
- return tag .. '?name=' .. name
- else
- return tag .. '?name=' .. path .. "/" .. name
- end
- end
-
- function input.is_readable.zip(name)
- return true
- end
-
- function input.finders.zip(specification,filetype)
- specification = input.splitmethod(specification)
- if specification.path then
- local q = url.query(specification.query)
- if q.name then
- local zfile = zip.openarchive(specification.path)
- if zfile then
- if input.trace > 0 then
- input.logger('! zip finder, path: %s',specification.path)
- end
- local dfile = zfile:open(q.name)
- if dfile then
- dfile = zfile:close()
- if input.trace > 0 then
- input.logger('+ zip finder, name: %s',q.name)
- end
- return specification.original
- end
- elseif input.trace > 0 then
- input.logger('? zip finder, path %s',specification.path)
- end
- end
- end
- if input.trace > 0 then
- input.logger('- zip finder, name: %s',filename)
- end
- return unpack(input.finders.notfound)
- end
-
- function input.openers.zip(specification)
- local zipspecification = input.splitmethod(specification)
- if zipspecification.path then
- local q = url.query(zipspecification.query)
- if q.name then
- local zfile = zip.openarchive(zipspecification.path)
- if zfile then
- if input.trace > 0 then
- input.logger('+ zip starter, path: %s',zipspecification.path)
- end
- local dfile = zfile:open(q.name)
- if dfile then
- input.show_open(specification)
- return input.openers.text_opener(specification,dfile,'zip')
- end
- elseif input.trace > 0 then
- input.logger('- zip starter, path %s',zipspecification.path)
- end
- end
- end
- if input.trace > 0 then
- input.logger('- zip opener, name: %s',filename)
- end
- return unpack(input.openers.notfound)
- end
-
- function input.loaders.zip(specification)
- specification = input.splitmethod(specification)
- if specification.path then
- local q = url.query(specification.query)
- if q.name then
- local zfile = zip.openarchive(specification.path)
- if zfile then
- if input.trace > 0 then
- input.logger('+ zip starter, path: %s',specification.path)
- end
- local dfile = zfile:open(q.name)
- if dfile then
- input.show_load(filename)
- if input.trace > 0 then
- input.logger('+ zip loader, name: %s',filename)
- end
- local s = dfile:read("*all")
- dfile:close()
- return true, s, #s
- end
- elseif input.trace > 0 then
- input.logger('- zip starter, path: %s',specification.path)
- end
- end
- end
- if input.trace > 0 then
- input.logger('- zip loader, name: %s',filename)
- end
- return unpack(input.openers.notfound)
- end
-
- -- zip:///somefile.zip
- -- zip:///somefile.zip?tree=texmf-local -> mount
-
- function input.usezipfile(zipname)
- zipname = validzip(zipname)
- if input.trace > 0 then
- input.logger('! zip use, file: %s',zipname)
- end
- local specification = input.splitmethod(zipname)
- local zipfile = specification.path
- if zipfile and not zip.registeredfiles[zipname] then
- local tree = url.query(specification.query).tree or ""
- if input.trace > 0 then
- input.logger('! zip register, file: %s',zipname)
- end
- local z = zip.openarchive(zipfile)
- if z then
- local instance = input.instance
- if input.trace > 0 then
- input.logger("= zipfile, registering: %s",zipname)
- end
- input.starttiming(instance)
- input.aux.prepend_hash('zip',zipname,zipfile)
- input.aux.extend_texmf_var(zipname) -- resets hashes too
- zip.registeredfiles[zipname] = z
- instance.files[zipname] = input.aux.register_zip_file(z,tree or "")
- input.stoptiming(instance)
- elseif input.trace > 0 then
- input.logger("? zipfile, unknown: %s",zipname)
- end
- elseif input.trace > 0 then
- input.logger('! zip register, no file: %s',zipname)
- end
- end
-
- function input.aux.register_zip_file(z,tree)
- local files, filter = { }, ""
- if tree == "" then
- filter = "^(.+)/(.-)$"
- else
- filter = "^"..tree.."/(.+)/(.-)$"
- end
- if input.trace > 0 then
- input.logger('= zip filter: %s',filter)
- end
- local register, n = input.aux.register_file, 0
- for i in z:files() do
- local path, name = i.filename:match(filter)
- if path then
- if name and name ~= '' then
- register(files, name, path)
- n = n + 1
- else
- -- directory
- end
- else
- register(files, i.filename, '')
- n = n + 1
- end
- end
- input.logger('= zip entries: %s',n)
- return files
- end
-
-end
diff --git a/tex/context/base/lxml-ent.lua b/tex/context/base/lxml-ent.lua
new file mode 100644
index 000000000..c91d12706
--- /dev/null
+++ b/tex/context/base/lxml-ent.lua
@@ -0,0 +1,115 @@
+if not modules then modules = { } end modules ['lxml-ent'] = {
+ version = 1.001,
+ comment = "this module is the basis for the lxml-* ones",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring
+local format, gsub, find = string.format, string.gsub, string.find
+local utfchar = unicode.utf8.char
+
+--[[ldx--
+<p>We provide (at least here) two entity handlers. The more extensive
+resolver consults a hash first, tries to convert to <l n='utf'/> next,
+and finaly calls a handler when defines. When this all fails, the
+original entity is returned.</p>
+--ldx]]--
+
+xml.entities = xml.entities or { } -- xml.entity_handler == function
+
+function xml.entity_handler(e)
+ return format("[%s]",e)
+end
+
+local function toutf(s)
+ return utfchar(tonumber(s,16))
+end
+
+local function utfize(root)
+ local d = root.dt
+ for k=1,#d do
+ local dk = d[k]
+ if type(dk) == "string" then
+ -- test prevents copying if no match
+ if find(dk,"&#x.-;") then
+ d[k] = gsub(dk,"&#x(.-);",toutf)
+ end
+ else
+ utfize(dk)
+ end
+ end
+end
+
+xml.utfize = utfize
+
+local function resolve(e) -- hex encoded always first, just to avoid mkii fallbacks
+ if find(e,"^#x") then
+ return utfchar(tonumber(e:sub(3),16))
+ elseif find(e,"^#") then
+ return utfchar(tonumber(e:sub(2)))
+ else
+ local ee = xml.entities[e] -- we cannot shortcut this one (is reloaded)
+ if ee then
+ return ee
+ else
+ local h = xml.entity_handler
+ return (h and h(e)) or "&" .. e .. ";"
+ end
+ end
+end
+
+local function resolve_entities(root)
+ if not root.special or root.tg == "@rt@" then
+ local d = root.dt
+ for k=1,#d do
+ local dk = d[k]
+ if type(dk) == "string" then
+ if find(dk,"&.-;") then
+ d[k] = gsub(dk,"&(.-);",resolve)
+ end
+ else
+ resolve_entities(dk)
+ end
+ end
+ end
+end
+
+xml.resolve_entities = resolve_entities
+
+function xml.utfize_text(str)
+ if find(str,"&#") then
+ return (gsub(str,"&#x(.-);",toutf))
+ else
+ return str
+ end
+end
+
+function xml.resolve_text_entities(str) -- maybe an lpeg. maybe resolve inline
+ if find(str,"&") then
+ return (gsub(str,"&(.-);",resolve))
+ else
+ return str
+ end
+end
+
+function xml.show_text_entities(str)
+ if find(str,"&") then
+ return (gsub(str,"&(.-);","[%1]"))
+ else
+ return str
+ end
+end
+
+-- experimental, this will be done differently
+
+function xml.merge_entities(root)
+ local documententities = root.entities
+ local allentities = xml.entities
+ if documententities then
+ for k, v in next, documententities do
+ allentities[k] = v
+ end
+ end
+end
diff --git a/tex/context/base/lxml-ini.lua b/tex/context/base/lxml-ini.lua
index 6b8d014a7..0c40a4baf 100644
--- a/tex/context/base/lxml-ini.lua
+++ b/tex/context/base/lxml-ini.lua
@@ -6,10 +6,19 @@ if not modules then modules = { } end modules ['lxml-ini'] = {
license = "see context related readme files"
}
-local texsprint, texprint = tex.sprint or print, tex.print or print
+local utf = unicode.utf8
+
+local texsprint, texprint, utfchar = tex.sprint or print, tex.print or print, utf.char
local format, concat, insert, remove = string.format, table.concat, table.insert, table.remove
local type, next, tonumber = type, next, tonumber
+local ctxcatcodes = tex.ctxcatcodes
+local texcatcodes = tex.texcatcodes
+local vrbcatcodes = tex.vrbcatcodes
+
+local trace_setups = false trackers.register("lxml.setups", function(v) trace_setups = v end)
+local trace_loading = false trackers.register("lxml.loading", function(v) trace_loading = v end)
+
-- for the moment here
function table.insert_before_value(t,value,extra)
@@ -59,10 +68,11 @@ document.xml = document.xml or { }
lxml = lxml or { }
lxml.loaded = { }
lxml.myself = { }
+lxml.n = 0
-local loaded = lxml.loaded
-local myself = lxml.myself
-local stack = lxml.stack
+local loaded = lxml.loaded
+local myself = lxml.myself
+local stack = lxml.stack
lxml.self = myself -- be backward compatible for a while
@@ -88,22 +98,22 @@ do
local lf = lpeg.P("\n")
local space = lpeg.S(" \t\f\v")
local newline = crlf + cr + lf
- local spacing = space^0 * newline * space^0
+ local spacing = newline * space^0
local content = lpeg.C((1-spacing)^1)
local verbose = lpeg.C((1-(space+newline))^1)
+ -- local capture = (
+ -- newline^2 * lpeg.Cc("") / texprint +
+ -- newline * lpeg.Cc(" ") / texsprint +
+ -- content / texsprint
+ -- )^0
+
local capture = (
- newline^2 * lpeg.Cc("") / texprint +
- newline * lpeg.Cc(" ") / texsprint +
- content / texsprint
+ space^0 * newline^2 * lpeg.Cc("") / texprint +
+ space^0 * newline * space^0 * lpeg.Cc(" ") / texsprint +
+ content / texsprint
)^0
---~ local capture = (
---~ newline^2 * lpeg.Cc("") / function(s) texprint (tex.xmlcatcodes,s) end +
---~ newline * lpeg.Cc(" ") / function(s) texsprint(tex.xmlcatcodes,s) end +
---~ content / function(s) texsprint(tex.xmlcatcodes,s) end
---~ )^0
-
local forceraw, rawroot = false, nil
function lxml.startraw()
@@ -136,12 +146,12 @@ do
local function sprint(root)
if not root then
---~ rawroot = false
+ --~ rawroot = false
-- quit
else
local tr = type(root)
if tr == "string" then -- can also be result of lpath
---~ rawroot = false
+ --~ rawroot = false
capture:match(root)
elseif tr == "table" then
rawroot = forceraw and root
@@ -223,15 +233,15 @@ do
local aftercommand = ""
local capture = (
- newline / function( ) texsprint(tex.texcatcodes,linecommand .. "{}") end +
- verbose / function(s) texsprint(tex.vrbcatcodes,s) end +
- space / function( ) texsprint(tex.texcatcodes,spacecommand .. "{}") end
+ newline / function( ) texsprint(texcatcodes,linecommand,"{}") end +
+ verbose / function(s) texsprint(vrbcatcodes,s) end +
+ space / function( ) texsprint(texcatcodes,spacecommand,"{}") end
)^0
local function toverbatim(str)
- if beforecommand then texsprint(tex.texcatcodes,beforecommand .. "{}") end
+ if beforecommand then texsprint(texcatcodes,beforecommand,"{}") end
capture:match(str)
- if aftercommand then texsprint(tex.texcatcodes,aftercommand .. "{}") end
+ if aftercommand then texsprint(texcatcodes,aftercommand,"{}") end
end
function lxml.set_verbatim(before,after,obeyedline,obeyedspace)
@@ -249,23 +259,23 @@ do
-- local capture = (space^0*newline)^0 * capture * (space+newline)^0 * -1
local function toverbatim(str)
- if beforecommand then texsprint(tex.texcatcodes,beforecommand .. "{}") end
+ if beforecommand then texsprint(texcatcodes,beforecommand,"{}") end
-- todo: add this to capture
str = str:gsub("^[ \t]+[\n\r]+","")
str = str:gsub("[ \t\n\r]+$","")
capture:match(str)
- if aftercommand then texsprint(tex.texcatcodes,aftercommand .. "{}") end
+ if aftercommand then texsprint(texcatcodes,aftercommand,"{}") end
end
function lxml.verbatim(id,before,after)
local root = get_id(id)
if root then
- if before then texsprint(tex.ctxcatcodes,format("%s[%s]",before,root.tg)) end
+ if before then texsprint(ctxcatcodes,format("%s[%s]",before,root.tg)) end
-- serialize(root.dt,toverbatim,nil,nil,nil,true) -- was root
local t = { }
serialize(root.dt,function(s) t[#t+1] = s end,nil,nil,nil,true) -- was root
toverbatim(table.concat(t,""))
- if after then texsprint(tex.ctxcatcodes,after) end
+ if after then texsprint(ctxcatcodes,after) end
end
end
function lxml.inlineverbatim(id)
@@ -299,12 +309,12 @@ do
if str then
local a, b, c, d = parser:match(str)
if d then
- texsprint(tex.ctxcatcodes,format("\\xmlcontextdirective{%s}{%s}{%s}{%s}",a,b,c,d))
+ texsprint(ctxcatcodes,format("\\xmlcontextdirective{%s}{%s}{%s}{%s}",a,b,c,d))
end
end
end
- -- print(contextdirective("context-mathml-directive function reduction yes yes "))
+ -- print(contextdirective("context-mathml-directive function reduction yes "))
-- print(contextdirective("context-mathml-directive function "))
function lxml.main(id)
@@ -324,36 +334,46 @@ local xmltprint = xml.tprint
xml.originalload = xml.originalload or xml.load
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+
function xml.load(filename)
- input.starttiming(xml)
- local xmldata = xml.convert((filename and input.loadtexfile(filename)) or "")
- input.stoptiming(xml)
+ lxml.n = lxml.n + 1
+ starttiming(xml)
+ local xmldata = xml.convert((filename and resolvers.loadtexfile(filename)) or "")
+ stoptiming(xml)
return xmldata
end
function lxml.load(id,filename)
+ lxml.n = lxml.n + 1
filename = commands.preparedfile(filename)
- if lxml.trace_load then
- ctx.writestatus("lxml","loading file: %s",filename)
+ if trace_loading then
+ commands.writestatus("lxml","loading file: %s",filename)
end
loaded[id] = xml.load(filename)
return loaded[id], filename
end
+function lxml.register(id,xmltable)
+ lxml.n = lxml.n + 1
+ loaded[id] = xmltable
+ return xmltable
+end
+
function lxml.include(id,pattern,attribute,recurse)
- input.starttiming(xml)
+ starttiming(xml)
xml.include(get_id(id),pattern,attribute,recurse,function(filename)
if filename then
filename = commands.preparedfile(filename)
- if lxml.trace_load then
- ctx.writestatus("lxml","including file: %s",filename)
+ if trace_loading then
+ commands.writestatus("lxml","including file: %s",filename)
end
- return input.loadtexfile(filename) or ""
+ return resolvers.loadtexfile(filename) or ""
else
return ""
end
end)
- input.stoptiming(xml)
+ stoptiming(xml)
end
function lxml.utfize(id)
@@ -373,7 +393,11 @@ function lxml.all(id,pattern)
-- xmltprint(xmlcollect(get_id(id),pattern))
traverse(get_id(id), lpath(pattern), function(r,d,k)
-- to be checked for root::
- xmlsprint(d[k])
+ if d then
+ xmlsprint(d[k])
+ else -- new, maybe wrong
+--~ xmlsprint(r)
+ end
return false
end)
end
@@ -522,7 +546,7 @@ function lxml.name(id) -- or remapped name? -> lxml.info, combine
local r = get_id(id)
local ns = r.rn or r.ns or ""
if ns ~= "" then
- texsprint(ns .. ":" .. r.tg)
+ texsprint(ns,":",r.tg)
else
texsprint(r.tg)
end
@@ -550,9 +574,9 @@ function lxml.concatrange(id,what,start,stop,separator,lastseparator) -- test th
if i == #t then
-- nothing
elseif i == #t-1 and lastseparator ~= "" then
- texsprint(tex.ctxcatcodes,lastseparator)
+ texsprint(ctxcatcodes,lastseparator)
elseif separator ~= "" then
- texsprint(tex.ctxcatcodes,separator)
+ texsprint(ctxcatcodes,separator)
end
end
end
@@ -580,7 +604,7 @@ function xml.command(root, command)
-- setup
local n = #myself + 1
myself[n] = root
- texsprint(tex.ctxcatcodes,format("\\xmlsetup{%i}{%s}",n,command))
+ texsprint(ctxcatcodes,format("\\xmlsetup{%i}{%s}",n,command))
elseif tc == "function" then
-- function
command(root)
@@ -600,11 +624,7 @@ function lxml.setaction(id,pattern,action)
end
end
-lxml.trace_setups = false
-lxml.trace_load = false
-
function lxml.setsetup(id,pattern,setup)
- local trace = lxml.trace_setups
if not setup or setup == "" or setup == "*" or setup == "-" or setup == "+" then
for rt, dt, dk in xmlelements(get_id(id),pattern) do
local dtdk = dt and dt[dk] or rt
@@ -614,17 +634,17 @@ function lxml.setsetup(id,pattern,setup)
if setup == "-" then
dtdk.command = false
if trace then
- texio.write_nl(format("lpath matched -> %s -> skipped", command))
+ logs.report("lxml","lpath matched -> %s -> skipped", command)
end
elseif setup == "+" then
dtdk.command = true
- if trace then
- texio.write_nl(format("lpath matched -> %s -> text", command))
+ if trace_setups then
+ logs.report("lxml","lpath matched -> %s -> text", command)
end
else
dtdk.command = command
- if trace then
- texio.write_nl(format("lpath matched -> %s -> %s", command, command))
+ if trace_setups then
+ logs.report("lxml","lpath matched -> %s -> %s", command, command)
end
end
end
@@ -637,46 +657,46 @@ function lxml.setsetup(id,pattern,setup)
local ns, tg = dtdk.rn or dtdk.ns, dtdk.tg
if b == "-" then
dtdk.command = false
- if trace then
+ if trace_setups then
if ns == "" then
- texio.write_nl(format("lpath matched -> %s -> skipped", tg))
+ logs.report("lxml","lpath matched -> %s -> skipped", tg)
else
- texio.write_nl(format("lpath matched -> %s:%s -> skipped", ns, tg))
+ logs.report("lxml","lpath matched -> %s:%s -> skipped", ns, tg)
end
end
elseif b == "+" then
dtdk.command = true
- if trace then
+ if trace_setups then
if ns == "" then
- texio.write_nl(format("lpath matched -> %s -> text", tg))
+ logs.report("lxml","lpath matched -> %s -> text", tg)
else
- texio.write_nl(format("lpath matched -> %s:%s -> text", ns, tg))
+ logs.report("lxml","lpath matched -> %s:%s -> text", ns, tg)
end
end
else
dtdk.command = a .. tg
- if trace then
+ if trace_setups then
if ns == "" then
- texio.write_nl(format("lpath matched -> %s -> %s", tg, dtdk.command))
+ logs.report("lxml","lpath matched -> %s -> %s", tg, dtdk.command)
else
- texio.write_nl(format("lpath matched -> %s:%s -> %s", ns, tg, dtdk.command))
+ logs.report("lxml","lpath matched -> %s:%s -> %s", ns, tg, dtdk.command)
end
end
end
end
else
- if trace then
- texio.write_nl(format("lpath pattern -> %s -> %s", pattern, setup))
+ if trace_setups then
+ logs.report("lxml","lpath pattern -> %s -> %s", pattern, setup)
end
for rt, dt, dk in xmlelements(get_id(id),pattern) do
local dtdk = (dt and dt[dk]) or rt
dtdk.command = setup
- if trace then
+ if trace_setups then
local ns, tg = dtdk.rn or dtdk.ns, dtdk.tg
if ns == "" then
- texio.write_nl(format("lpath matched -> %s -> %s", tg, setup))
+ logs.report("lxml","lpath matched -> %s -> %s", tg, setup)
else
- texio.write_nl(format("lpath matched -> %s:%s -> %s", ns, tg, setup))
+ logs.report("lxml","lpath matched -> %s:%s -> %s", ns, tg, setup)
end
end
end
@@ -722,7 +742,7 @@ local function command(root,pattern,cmd) -- met zonder ''
if type(m) == "table" then -- probably a bug
local n = #myself + 1
myself[n] = m
- texsprint(tex.ctxcatcodes,format("\\xmlsetup{%s}{%s}",n,cmd))
+ texsprint(ctxcatcodes,format("\\xmlsetup{%s}{%s}",n,cmd))
end
end)
end
@@ -739,98 +759,92 @@ end
xml.filters["function"] = dofunction
-do
+--~ <?xml version="1.0" standalone="yes"?>
+--~ <!-- demo.cdx -->
+--~ <directives>
+--~ <!--
+--~ <directive attribute='id' value="100" setup="cdx:100"/>
+--~ <directive attribute='id' value="101" setup="cdx:101"/>
+--~ -->
+--~ <!--
+--~ <directive attribute='cdx' value="colors" element="cals:table" setup="cdx:cals:table:colors"/>
+--~ <directive attribute='cdx' value="vertical" element="cals:table" setup="cdx:cals:table:vertical"/>
+--~ <directive attribute='cdx' value="noframe" element="cals:table" setup="cdx:cals:table:noframe"/>
+--~ -->
+--~ <directive attribute='cdx' value="*" element="cals:table" setup="cdx:cals:table:*"/>
+--~ </directives>
+
+lxml.directives = { }
+
+local data = {
+ setup = { },
+ before = { },
+ after = { }
+}
- --~ <?xml version="1.0" standalone="yes"?>
- --~ <!-- demo.cdx -->
- --~ <directives>
- --~ <!--
- --~ <directive attribute='id' value="100" setup="cdx:100"/>
- --~ <directive attribute='id' value="101" setup="cdx:101"/>
- --~ -->
- --~ <!--
- --~ <directive attribute='cdx' value="colors" element="cals:table" setup="cdx:cals:table:colors"/>
- --~ <directive attribute='cdx' value="vertical" element="cals:table" setup="cdx:cals:table:vertical"/>
- --~ <directive attribute='cdx' value="noframe" element="cals:table" setup="cdx:cals:table:noframe"/>
- --~ -->
- --~ <directive attribute='cdx' value="*" element="cals:table" setup="cdx:cals:table:*"/>
- --~ </directives>
-
- lxml.directives = { }
-
- local data = {
- setup = { },
- before = { },
- after = { }
- }
-
- function lxml.directives.load(filename)
- if texmf then
- local fullname = input.find_file(filename) or ""
- if fullname ~= "" then
- filename = fullname
- end
- end
- local root = xml.load(filename)
- for r, d, k in xmlelements(root,"directive") do
- local dk = d[k]
- local at = dk.at
- local attribute, value, element = at.attribute or "", at.value or "", at.element or '*'
- local setup, before, after = at.setup or "", at.before or "", at.after or ""
- if attribute ~= "" and value ~= "" then
- local key = format("%s::%s::%s",element,attribute,value)
- local t = data[key] or { }
- if setup ~= "" then t.setup = setup end
- if before ~= "" then t.before = before end
- if after ~= "" then t.after = after end
- data[key] = t
- end
+function lxml.directives.load(filename)
+ local fullname = resolvers.find_file(filename) or ""
+ if fullname ~= "" then
+ filename = fullname
+ end
+ local root = xml.load(filename)
+ for r, d, k in xmlelements(root,"directive") do
+ local dk = d[k]
+ local at = dk.at
+ local attribute, value, element = at.attribute or "", at.value or "", at.element or '*'
+ local setup, before, after = at.setup or "", at.before or "", at.after or ""
+ if attribute ~= "" and value ~= "" then
+ local key = format("%s::%s::%s",element,attribute,value)
+ local t = data[key] or { }
+ if setup ~= "" then t.setup = setup end
+ if before ~= "" then t.before = before end
+ if after ~= "" then t.after = after end
+ data[key] = t
end
end
+end
- function lxml.directives.setup(root,attribute,element)
- lxml.directives.handle_setup('setup',root,attribute,element)
- end
- function lxml.directives.before(root,attribute,element)
- lxml.directives.handle_setup('before',root,attribute,element)
- end
- function lxml.directives.after(root,attribute,element)
- lxml.directives.handle_setup('after',root,attribute,element)
- end
+function lxml.directives.setup(root,attribute,element)
+ lxml.directives.handle_setup('setup',root,attribute,element)
+end
+function lxml.directives.before(root,attribute,element)
+ lxml.directives.handle_setup('before',root,attribute,element)
+end
+function lxml.directives.after(root,attribute,element)
+ lxml.directives.handle_setup('after',root,attribute,element)
+end
- function lxml.directives.handle_setup(category,root,attribute,element)
- root = get_id(root)
- attribute = attribute
- if attribute then
- local value = root.at[attribute]
- if value then
- if not element then
- local ns, tg = root.rn or root.ns, root.tg
- if ns == "" then
- element = tg
- else
- element = ns .. ':' .. tg
- end
+function lxml.directives.handle_setup(category,root,attribute,element)
+ root = get_id(root)
+ attribute = attribute
+ if attribute then
+ local value = root.at[attribute]
+ if value then
+ if not element then
+ local ns, tg = root.rn or root.ns, root.tg
+ if ns == "" then
+ element = tg
+ else
+ element = ns .. ':' .. tg
end
- local setup = data[format("%s::%s::%s",element,attribute,value)]
+ end
+ local setup = data[format("%s::%s::%s",element,attribute,value)]
+ if setup then
+ setup = setup[category]
+ end
+ if setup then
+ texsprint(ctxcatcodes,format("\\directsetup{%s}",setup))
+ else
+ setup = data[format("%s::%s::*",element,attribute)]
if setup then
setup = setup[category]
end
if setup then
- texsprint(tex.ctxcatcodes,format("\\directsetup{%s}",setup))
- else
- setup = data[format("%s::%s::*",element,attribute)]
- if setup then
- setup = setup[category]
- end
- if setup then
- texsprint(tex.ctxcatcodes,format("\\directsetup{%s}",setup:gsub('%*',value)))
- end
+ texsprint(ctxcatcodes,format("\\directsetup{%s}",setup:gsub('%*',value)))
end
end
end
end
-
end
function xml.getbuffer(name) -- we need to make sure that commands are processed
@@ -844,16 +858,20 @@ function lxml.loadbuffer(id,name)
if not name or name == "" then
name = tex.jobname
end
- input.starttiming(xml)
+ starttiming(xml)
loaded[id] = xml.convert(buffers.collect(name or id,"\n"))
- input.stoptiming(xml)
+ stoptiming(xml)
return loaded[id], name or id
end
function lxml.loaddata(id,str)
- input.starttiming(xml)
+ starttiming(xml)
loaded[id] = xml.convert(str or "")
- input.stoptiming(xml)
+ stoptiming(xml)
+ return loaded[id], id
+end
+
+function lxml.loadregistered(id)
return loaded[id], id
end
@@ -862,143 +880,149 @@ end
lxml.set_verbatim("\\xmlcdatabefore", "\\xmlcdataafter", "\\xmlcdataobeyedline", "\\xmlcdataobeyedspace")
lxml.set_cdata()
-do
-
- local traced = { }
+local traced = { }
- function lxml.trace_text_entities(str)
- return str:gsub("&(.-);",function(s)
- traced[s] = (traced[s] or 0) + 1
- return "["..s.."]"
- end)
- end
+function lxml.trace_text_entities(str)
+ return str:gsub("&(.-);",function(s)
+ traced[s] = (traced[s] or 0) + 1
+ return "["..s.."]"
+ end)
+end
- function lxml.show_text_entities()
- for k,v in ipairs(table.sortedkeys(traced)) do
- local h = v:match("^#x(.-)$")
- if h then
- local d = tonumber(h,16)
- local u = unicode.utf8.char(d)
- texio.write_nl(format("entity: %s / %s / %s / n=%s",h,d,u,traced[v]))
- else
- texio.write_nl(format("entity: %s / n=%s",v,traced[v]))
- end
+function lxml.show_text_entities()
+ for k,v in ipairs(table.sortedkeys(traced)) do
+ local h = v:match("^#x(.-)$")
+ if h then
+ local d = tonumber(h,16)
+ local u = utfchar(d)
+ logs.report("lxml","entity: %s / %s / %s / n=%s",h,d,u,traced[v])
+ else
+ logs.report("lxml","entity: %s / n=%s",v,traced[v])
end
end
-
end
--- yes or no ...
+local error_entity_handler = function(s) return format("[%s]",s) end
+local element_entity_handler = function(s) return format("<ctx:e n='%s'/>",s) end
-do
+function lxml.set_mkii_entityhandler()
+ xml.entity_handler = error_entity_handler
+ xml.set_text_cleanup()
+end
+function lxml.set_mkiv_entityhandler()
+ xml.entity_handler = element_entity_handler
+ xml.set_text_cleanup(xml.resolve_text_entities)
+end
+function lxml.reset_entityhandler()
+ xml.entity_handler = error_entity_handler
+ xml.set_text_cleanup()
+end
- local function with_elements_only(e,handle)
- if e and handle then
- local etg = e.tg
- if etg then
- if e.special and etg ~= "@rt@" then
- if resthandle then
- resthandle(e)
- end
- else
- local edt = e.dt
- if edt then
- for i=1,#edt do
- local e = edt[i]
- if type(e) == "table" then
- handle(e)
- with_elements_only(e,handle)
- end
+local function with_elements_only(e,handle)
+ if e and handle then
+ local etg = e.tg
+ if etg then
+ if e.special and etg ~= "@rt@" then
+ if resthandle then
+ resthandle(e)
+ end
+ else
+ local edt = e.dt
+ if edt then
+ for i=1,#edt do
+ local e = edt[i]
+ if type(e) == "table" then
+ handle(e)
+ with_elements_only(e,handle)
end
end
end
end
end
end
+end
- local function with_elements_only(e,handle,depth)
- if e and handle then
- local edt = e.dt
- if edt then
- depth = depth or 0
- for i=1,#edt do
- local e = edt[i]
- if type(e) == "table" then
- handle(e,depth)
- with_elements_only(e,handle,depth+1)
- end
+ local function with_elements_only(e,handle,depth)
+ if e and handle then
+ local edt = e.dt
+ if edt then
+ depth = depth or 0
+ for i=1,#edt do
+ local e = edt[i]
+ if type(e) == "table" then
+ handle(e,depth)
+ with_elements_only(e,handle,depth+1)
end
end
end
end
+end
- xml.with_elements_only = with_elements_only
+xml.with_elements_only = with_elements_only
- local function to_text(e)
- if e.command == nil then
- local etg = e.tg
- if etg and e.special and etg ~= "@rt@" then
- e.command = false -- i.e. skip
- else
- e.command = true -- i.e. no <self></self>
- end
- end
- end
- local function to_none(e)
- if e.command == nil then
+local function to_text(e)
+ if e.command == nil then
+ local etg = e.tg
+ if etg and e.special and etg ~= "@rt@" then
e.command = false -- i.e. skip
+ else
+ e.command = true -- i.e. no <self></self>
end
end
+end
+local function to_none(e)
+ if e.command == nil then
+ e.command = false -- i.e. skip
+ end
+end
- -- can be made faster: just recurse over whole table, todo
+-- can be made faster: just recurse over whole table, todo
- function lxml.set_command_to_text(id)
- xml.with_elements_only(get_id(id),to_text)
- end
+function lxml.set_command_to_text(id)
+ xml.with_elements_only(get_id(id),to_text)
+end
- function lxml.set_command_to_none(id)
- xml.with_elements_only(get_id(id),to_none)
- end
+function lxml.set_command_to_none(id)
+ xml.with_elements_only(get_id(id),to_none)
+end
- function lxml.get_command_status(id)
- local status, stack = {}, {}
- local function get(e,d)
- local ns, tg = e.ns, e.tg
- local name = tg
- if ns ~= "" then name = ns .. ":" .. tg end
- stack[d] = name
- local ec = e.command
- if ec == true then
- ec = "system: text"
- elseif ec == false then
- ec = "system: skip"
- elseif ec == nil then
- ec = "system: not set"
- elseif type(ec) == "string" then
- ec = "setup: " .. ec
- else -- function
- ec = tostring(ec)
- end
- local tag = table.concat(stack," => ",1,d)
- local s = status[tag]
- if not s then
- s = { }
- status[tag] = s
- end
- s[ec] = (s[ec] or 0) + 1
+function lxml.get_command_status(id)
+ local status, stack = {}, {}
+ local function get(e,d)
+ local ns, tg = e.ns, e.tg
+ local name = tg
+ if ns ~= "" then name = ns .. ":" .. tg end
+ stack[d] = name
+ local ec = e.command
+ if ec == true then
+ ec = "system: text"
+ elseif ec == false then
+ ec = "system: skip"
+ elseif ec == nil then
+ ec = "system: not set"
+ elseif type(ec) == "string" then
+ ec = "setup: " .. ec
+ else -- function
+ ec = tostring(ec)
end
- if id then
- xml.with_elements_only(get_id(id),get)
- return status
- else
- local t = { }
- for id, _ in pairs(loaded) do
- t[id] = lxml.get_command_status(id)
- end
- return t
+ local tag = table.concat(stack," => ",1,d)
+ local s = status[tag]
+ if not s then
+ s = { }
+ status[tag] = s
end
+ s[ec] = (s[ec] or 0) + 1
+ end
+ if id then
+ xml.with_elements_only(get_id(id),get)
+ return status
+ else
+ local t = { }
+ for id, _ in pairs(loaded) do
+ t[id] = lxml.get_command_status(id)
+ end
+ return t
end
-
end
local setups = { }
@@ -1011,23 +1035,23 @@ function lxml.installsetup(what,document,setup,where)
if sd[k] == setup then sd[k] = nil break end
end
if what == 1 then
- if lxml.trace_load then
- ctx.writestatus("lxml","prepending setup %s for %s",setup,document)
+ if trace_loading then
+ commands.writestatus("lxml","prepending setup %s for %s",setup,document)
end
insert(sd,1,setup)
elseif what == 2 then
- if lxml.trace_load then
- ctx.writestatus("lxml","appending setup %s for %s",setup,document)
+ if trace_loading then
+ commands.writestatus("lxml","appending setup %s for %s",setup,document)
end
insert(sd,setup)
elseif what == 3 then
- if lxml.trace_load then
- ctx.writestatus("lxml","inserting setup %s for %s before %s",setup,document,where)
+ if trace_loading then
+ commands.writestatus("lxml","inserting setup %s for %s before %s",setup,document,where)
end
table.insert_before_value(sd,setup,where)
elseif what == 4 then
- if lxml.trace_load then
- ctx.writestatus("lxml","inserting setup %s for %s after %s",setup,document,where)
+ if trace_loading then
+ commands.writestatus("lxml","inserting setup %s for %s after %s",setup,document,where)
end
table.insert_after_value(sd,setup,where)
end
@@ -1038,26 +1062,25 @@ function lxml.flushsetups(...)
for _, document in ipairs({...}) do
local sd = setups[document]
if sd then
- local tc = tex.ctxcatcodes
for k=1,#sd do
local v= sd[k]
if not done[v] then
- if lxml.trace_load then
- ctx.writestatus("lxml","applying setup %02i = %s to %s",k,v,document)
+ if trace_loading then
+ commands.writestatus("lxml","applying setup %02i = %s to %s",k,v,document)
end
- texsprint(tc,format("\\directsetup{%s}",v))
+ texsprint(ctxcatcodes,format("\\directsetup{%s}",v))
done[v] = true
end
end
- elseif lxml.trace_load then
- ctx.writestatus("lxml","no setups for %s",document)
+ elseif trace_loading then
+ commands.writestatus("lxml","no setups for %s",document)
end
end
end
function lxml.resetsetups(document)
- if lxml.trace_load then
- ctx.writestatus("lxml","resetting all setups for %s",document)
+ if trace_loading then
+ commands.writestatus("lxml","resetting all setups for %s",document)
end
setups[document] = { }
end
@@ -1067,8 +1090,8 @@ function lxml.removesetup(document,setup)
if s then
for i=1,#s do
if s[i] == setup then
- if lxml.trace_load then
- ctx.writestatus("lxml","removing setup %s for %s",setup,document)
+ if trace_loading then
+ commands.writestatus("lxml","removing setup %s for %s",setup,document)
end
remove(t,i)
break
@@ -1092,3 +1115,24 @@ function lxml.doifelsetext (id,pattern) commands.doifelse(found (get_id(id),pat
-- special case: "*" and "" -> self else lpath lookup
function lxml.doifelseempty(id,pattern) commands.doifelse(isempty(get_id(id),pattern ~= "" and pattern ~= nil)) end -- not yet done, pattern
+
+-- status info
+
+statistics.register("xml load time", function()
+ local n = lxml.n
+ if n > 0 then
+ local stats = xml.statistics()
+ return format("%s seconds, lpath calls: %s, cached calls: %s", statistics.elapsedtime(xml), stats.lpathcalls, stats.lpathcached)
+ else
+ return nil
+ end
+end)
+
+statistics.register("lxml load time", function()
+ local n = #lxml.self
+ if n > 0 then
+ return format("%s seconds preparation, backreferences: %i", statistics.elapsedtime(lxml),n)
+ else
+ return nil
+ end
+end)
diff --git a/tex/context/base/lxml-ini.tex b/tex/context/base/lxml-ini.tex
index 0d03044b2..494e4f0b7 100644
--- a/tex/context/base/lxml-ini.tex
+++ b/tex/context/base/lxml-ini.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=lxml-ini,
%D version=2007.08.17,
-%D title=\CONTEXT\ \LUA\ based \XML\ Support,
+%D title=\CONTEXT\ \XML\ Support,
%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,8 +11,12 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context L-XML Macros (initialization)}
+\writestatus{loading}{ConTeXt XML Support / Initialization}
+\registerctxluafile{lxml-tab}{1.001}
+\registerctxluafile{lxml-pth}{1.001}
+\registerctxluafile{lxml-ent}{1.001}
+\registerctxluafile{lxml-mis}{1.001}
\registerctxluafile{lxml-ini}{1.001}
\unprotect
@@ -31,7 +35,7 @@
\def\xmldirectives #1{\ctxlua{lxml.directives.setup("#1")}}
\def\xmldirectivesbefore #1{\ctxlua{lxml.directives.before("#1")}}
\def\xmldirectivesafter #1{\ctxlua{lxml.directives.after("#1")}}
-\def\xmlfilter #1#2{\ctxlua{lxml.filter("#1","#2")}}
+\def\xmlfilter #1#2{\ctxlua{lxml.filter("#1",\!!bs#2\!!es)}}
\def\xmlfirst #1#2{\ctxlua{lxml.first("#1","#2")}}
\def\xmlflush #1{\ctxlua{lxml.flush("#1")}}
% \def\xmlcontent #1{\ctxlua{lxml.content("#1")}}
@@ -47,6 +51,7 @@
\def\xmlload #1#2{\ctxlua{lxml.load("#1","#2")}}
\def\xmlloadbuffer #1#2{\ctxlua{lxml.loadbuffer("#1","#2")}}
\def\xmlloaddata #1#2{\ctxlua{lxml.loaddata("#1",\!!bs#2\!!es)}}
+\def\xmlloadregistered #1#2{\ctxlua{lxml.loadregistered("#1")}}
\def\xmlloaddirectives #1{\ctxlua{lxml.directives.load("#1")}}
\def\xmlname #1{\ctxlua{lxml.name("#1")}}
\def\xmlnamespace #1{\ctxlua{lxml.namespace("#1")}}
@@ -130,6 +135,8 @@
\let\xmlregistersetup \xmlappendsetup
\let\xmlregisterdocumentsetup\xmlappenddocumentsetup
+\def\xmldocument{main}
+
\def\xmlregisteredsetups
{\xmlstarttiming
\xmlflushsetups
@@ -143,8 +150,8 @@
\xmldefaulttotext{#1}% after include
\xmlstoptiming}
-\def\xmlstarttiming{\ctxlua{input.starttiming(lxml)}}
-\def\xmlstoptiming {\ctxlua{input.stoptiming (lxml)}}
+\def\xmlstarttiming{\ctxlua{statistics.starttiming(lxml)}}
+\def\xmlstoptiming {\ctxlua{statistics.stoptiming (lxml)}}
\def\doxmlprocess#1#2#3#4%
{\begingroup
@@ -160,10 +167,11 @@
{\directsetup{#4}}%
\endgroup}
-\def\xmlprocessfile {\doxmlprocess\xmlload}
-\def\xmlprocessdata {\doxmlprocess\xmlloaddata}
-\def\xmlprocessbuffer{\doxmlprocess\xmlloadbuffer}
-\let\xmlprocess \xmlprocessfile
+\def\xmlprocessfile {\doxmlprocess\xmlload}
+\def\xmlprocessdata {\doxmlprocess\xmlloaddata}
+\def\xmlprocessbuffer {\doxmlprocess\xmlloadbuffer}
+\def\xmlprocessregistered{\doxmlprocess\xmlloadregistered}
+\let\xmlprocess \xmlprocessfile
% beware: \xmlmain takes the real root, so also processing
% instructions preceding the root element; well, in some
@@ -244,14 +252,6 @@
\def\inlinemessage #1{\dontleavehmode{\tttf#1}}
\def\displaymessage#1{\blank\inlinemessage{#1}\blank}
-% entities
-
-\def\xmlresolveentities
- {\ctxlua{xml.set_text_cleanup(xml.resolve_text_entities)}}
-
-\def\xmlkeepentities
- {\ctxlua{xml.set_text_cleanup()}}
-
\def\xmltraceentities
{\ctxlua{xml.set_text_cleanup(lxml.trace_text_entities)}%
\appendtoks\ctxlua{lxml.show_text_entities()}\to\everygoodbye}
@@ -268,6 +268,8 @@
% \setupxml[\c!method=mkiv,\c!default=\v!none] % mkiv only, undefined -> hidden
% \setupxml[\c!method=mkiv,\c!default=\v!text] % mkiv only, undefined -> text
+% \def\xmlctxdirective#1#2#3{\doif{#1}{clue}{\doif{#2}{page}}{\page[#3]}}
+
\chardef\xmlprocessingmode=0 % 0=mixed, 1=mkivonly, 2=mkivonly-default-text, 3=mkivonly-default-none
% \setupxml[method=mkiv,strip=yes,entities=yes,default=text]
@@ -276,26 +278,49 @@
\def\setupxml[#1]{\getparameters[\??xm][#1]\the\everysetupxml}
-\def\c!entities{entities}
+\def\c!entities{entities} % to be internationalized
\def\s!mkiv {mkiv}
\def\s!mkii {mkii}
+% entities
+
+\newif\ifautoXMLentities
+
+\def\xmlkeepentities{\ctxlua{lxml.reset_entityhandler()}}
+\def\xmlmkiientities{\ctxlua{lxml.set_mkii_entityhandler()}\autoXMLentitiestrue}
+\def\xmlmkiventities{\ctxlua{lxml.set_mkiv_entityhandler()}}
+
+\let\xmlresolveentities\xmlmkiventities % will become \xmlmkiventities
+
\letvalue{\??xm:1:\s!mkii }\zerocount
\letvalue{\??xm:1:\s!mkiv }\plusone
+
\letvalue{\??xm:2:\v!none }\plusone
\letvalue{\??xm:2:\v!text }\plustwo
\letvalue{\??xm:2:\v!hidden}\plusthree
+\letvalue{\??xm:ii:\v!yes }\xmlresolveentities
+\letvalue{\??xm:ii:\v!no }\xmlkeepentities
+\letvalue{\??xm:ii:\s!mkii}\xmlmkiientities
+\letvalue{\??xm:ii:\s!mkiv}\xmlmkiventities
+
+\letvalue{\??xm:iv:\v!yes }\xmlresolveentities
+\letvalue{\??xm:iv:\v!no }\xmlkeepentities
+\letvalue{\??xm:iv:\s!mkii}\xmlmkiventities
+\letvalue{\??xm:iv:\s!mkiv}\xmlmkiventities
+
\appendtoks
\chardef\xmlprocessingmode\executeifdefined{\??xm:1:\@@xmmethod}\zerocount
\ifcase\xmlprocessingmode
- % mkii
+ % mkii, permits both methods
+ \executeifdefined{\??xm:ii:\@@xmentities}\xmlkeepentities
\or
- % mkiv
-% \or
+ % mkiv, mkiv exclusively
\chardef\xmlprocessingmode\executeifdefined{\??xm:2:\@@xmdefault}\plusone
+ \executeifdefined{\??xm:iv:\@@xmentities}\xmlresolveentities
+ \else
+ % unset
\fi
- \doifelse\@@xmentities\v!yes\xmlresolveentities\xmlkeepentities
\ifcase\xmlprocessingmode
\ctxlua{characters.setmkiientities()}%
\else
@@ -306,7 +331,7 @@
{\ctxlua{xml.strip_cm_and_dt=false}}%
\to \everysetupxml
-\appendtoks\the\everysetupxml\to\everyjob
+\def\xmlinitialize{\the\everysetupxml}
\newcount\charactersactiveoffset \charactersactiveoffset="10000
diff --git a/tex/context/base/lxml-mis.lua b/tex/context/base/lxml-mis.lua
new file mode 100644
index 000000000..a117b1af9
--- /dev/null
+++ b/tex/context/base/lxml-mis.lua
@@ -0,0 +1,106 @@
+if not modules then modules = { } end modules ['lxml-mis'] = {
+ version = 1.001,
+ comment = "this module is the basis for the lxml-* ones",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local concat = table.concat
+local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring
+local format, gsub = string.format, string.gsub
+
+--[[ldx--
+<p>The following helper functions best belong to the <t>lmxl-ini</t>
+module. Some are here because we need then in the <t>mk</t>
+document and other manuals, others came up when playing with
+this module. Since this module is also used in <l n='mtxrun'/> we've
+put them here instead of loading mode modules there then needed.</p>
+--ldx]]--
+
+function xml.gsub(t,old,new)
+ local dt = t.dt
+ if dt then
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "string" then
+ dt[k] = gsub(v,old,new)
+ else
+ xml.gsub(v,old,new)
+ end
+ end
+ end
+end
+
+function xml.strip_leading_spaces(dk,d,k) -- cosmetic, for manual
+ if d and k and d[k-1] and type(d[k-1]) == "string" then
+ local s = d[k-1]:match("\n(%s+)")
+ xml.gsub(dk,"\n"..string.rep(" ",#s),"\n")
+ end
+end
+
+function xml.serialize_path(root,lpath,handle)
+ local dk, r, d, k = xml.first(root,lpath)
+ dk = xml.copy(dk)
+ xml.strip_leading_spaces(dk,d,k)
+ xml.serialize(dk,handle)
+end
+
+--~ xml.escapes = { ['&'] = '&amp;', ['<'] = '&lt;', ['>'] = '&gt;', ['"'] = '&quot;' }
+--~ xml.unescapes = { } for k,v in pairs(xml.escapes) do xml.unescapes[v] = k end
+
+--~ function xml.escaped (str) return (gsub(str,"(.)" , xml.escapes )) end
+--~ function xml.unescaped(str) return (gsub(str,"(&.-;)", xml.unescapes)) end
+--~ function xml.cleansed (str) return (gsub(str,"<.->" , '' )) end -- "%b<>"
+
+local P, S, R, C, V, Cc, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Cs
+
+-- 100 * 2500 * "oeps< oeps> oeps&" : gsub:lpeg|lpeg|lpeg
+--
+-- 1021:0335:0287:0247
+
+-- 10 * 1000 * "oeps< oeps> oeps& asfjhalskfjh alskfjh alskfjh alskfjh ;al J;LSFDJ"
+--
+-- 1559:0257:0288:0190 (last one suggested by roberto)
+
+-- escaped = Cs((S("<&>") / xml.escapes + 1)^0)
+-- escaped = Cs((S("<")/"&lt;" + S(">")/"&gt;" + S("&")/"&amp;" + 1)^0)
+local normal = (1 - S("<&>"))^0
+local special = P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;"
+local escaped = Cs(normal * (special * normal)^0)
+
+-- 100 * 1000 * "oeps&lt; oeps&gt; oeps&amp;" : gsub:lpeg == 0153:0280:0151:0080 (last one by roberto)
+
+-- unescaped = Cs((S("&lt;")/"<" + S("&gt;")/">" + S("&amp;")/"&" + 1)^0)
+-- unescaped = Cs((((P("&")/"") * (P("lt")/"<" + P("gt")/">" + P("amp")/"&") * (P(";")/"")) + 1)^0)
+local normal = (1 - S"&")^0
+local special = P("&lt;")/"<" + P("&gt;")/">" + P("&amp;")/"&"
+local unescaped = Cs(normal * (special * normal)^0)
+
+-- 100 * 5000 * "oeps <oeps bla='oeps' foo='bar'> oeps </oeps> oeps " : gsub:lpeg == 623:501 msec (short tags, less difference)
+
+local cleansed = Cs(((P("<") * (1-P(">"))^0 * P(">"))/"" + 1)^0)
+
+xml.escaped_pattern = escaped
+xml.unescaped_pattern = unescaped
+xml.cleansed_pattern = cleansed
+
+function xml.escaped (str) return escaped :match(str) end
+function xml.unescaped(str) return unescaped:match(str) end
+function xml.cleansed (str) return cleansed :match(str) end
+
+function xml.join(t,separator,lastseparator)
+ if #t > 0 then
+ local result = { }
+ for k,v in pairs(t) do
+ result[k] = xml.tostring(v)
+ end
+ if lastseparator then
+ return concat(result,separator or "",1,#result-1) .. (lastseparator or "") .. result[#result]
+ else
+ return concat(result,separator)
+ end
+ else
+ return ""
+ end
+end
diff --git a/tex/context/base/lxml-pth.lua b/tex/context/base/lxml-pth.lua
new file mode 100644
index 000000000..b1afc8d64
--- /dev/null
+++ b/tex/context/base/lxml-pth.lua
@@ -0,0 +1,1555 @@
+if not modules then modules = { } end modules ['lxml-pth'] = {
+ version = 1.001,
+ comment = "this module is the basis for the lxml-* ones",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local concat, remove, insert = table.concat, table.remove, table.insert
+local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring
+local format, lower, gmatch, gsub, find = string.format, string.lower, string.gmatch, string.gsub, string.find
+
+--[[ldx--
+<p>This module can be used stand alone but also inside <l n='mkiv'/> in
+which case it hooks into the tracker code. Therefore we provide a few
+functions that set the tracers. Here we overload a previously defined
+function.</p>
+--ldx]]--
+
+local trace_lpath = false
+
+if trackers then
+ trackers.register("xml.lpath", function(v) trace_lpath = v end)
+end
+
+local settrace = xml.settrace -- lxml-tab
+
+function xml.settrace(str,value)
+ if str == "lpath" then
+ trace_lpath = value or false
+ else
+ settrace(str,value) -- lxml-tab
+ end
+end
+
+--[[ldx--
+<p>We've now arrived at an intersting part: accessing the tree using a subset
+of <l n='xpath'/> and since we're not compatible we call it <l n='lpath'/>. We
+will explain more about its usage in other documents.</p>
+--ldx]]--
+
+local lpathcalls = 0 -- statistics
+local lpathcached = 0 -- statistics
+
+xml.functions = xml.functions or { }
+xml.expressions = xml.expressions or { }
+
+local functions = xml.functions
+local expressions = xml.expressions
+
+local actions = {
+ [10] = "stay",
+ [11] = "parent",
+ [12] = "subtree root",
+ [13] = "document root",
+ [14] = "any",
+ [15] = "many",
+ [16] = "initial",
+ [20] = "match",
+ [21] = "match one of",
+ [22] = "match and attribute eq",
+ [23] = "match and attribute ne",
+ [24] = "match one of and attribute eq",
+ [25] = "match one of and attribute ne",
+ [27] = "has attribute",
+ [28] = "has value",
+ [29] = "fast match",
+ [30] = "select",
+ [31] = "expression",
+ [40] = "processing instruction",
+}
+
+-- a rather dumb lpeg
+
+local P, S, R, C, V, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc
+
+-- instead of using functions we just parse a few names which saves a call
+-- later on
+
+local lp_position = P("position()") / "ps"
+local lp_index = P("index()") / "id"
+local lp_text = P("text()") / "tx"
+local lp_name = P("name()") / "(ns~='' and ns..':'..tg)" -- "((rt.ns~='' and rt.ns..':'..rt.tg) or '')"
+local lp_tag = P("tag()") / "tg" -- (rt.tg or '')
+local lp_ns = P("ns()") / "ns" -- (rt.ns or '')
+local lp_noequal = P("!=") / "~=" + P("<=") + P(">=") + P("==")
+local lp_doequal = P("=") / "=="
+local lp_attribute = P("@") / "" * Cc("(at['") * R("az","AZ","--","__")^1 * Cc("'] or '')")
+
+local lp_lua_function = C(R("az","AZ","--","__")^1 * (P(".") * R("az","AZ","--","__")^1)^1) * P("(") / function(t) -- todo: better . handling
+ return t .. "("
+end
+
+local lp_function = C(R("az","AZ","--","__")^1) * P("(") / function(t) -- todo: better . handling
+ if expressions[t] then
+ return "expressions." .. t .. "("
+ else
+ return "expressions.error("
+ end
+end
+
+local lparent = lpeg.P("(")
+local rparent = lpeg.P(")")
+local noparent = 1 - (lparent+rparent)
+local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
+local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
+
+-- if we use a dedicated namespace then we don't need to pass rt and k
+
+local lp_special = (C(P("name")+P("text")+P("tag"))) * value / function(t,s)
+ if expressions[t] then
+ if s then
+ return "expressions." .. t .. "(r,k," .. s ..")"
+ else
+ return "expressions." .. t .. "(r,k)"
+ end
+ else
+ return "expressions.error(" .. t .. ")"
+ end
+end
+
+local converter = lpeg.Cs ( (
+ lp_position +
+ lp_index +
+ lp_text + lp_name + -- fast one
+ lp_special +
+ lp_noequal + lp_doequal +
+ lp_attribute +
+ lp_lua_function +
+ lp_function +
+1 )^1 )
+
+-- expressions,root,rootdt,k,e,edt,ns,tg,idx,hsh[tg] or 1
+
+local template = [[
+ return function(expressions,r,d,k,e,dt,ns,tg,id,ps)
+ local at, tx = e.at or { }, dt[1] or ""
+ return %s
+ end
+]]
+
+local function make_expression(str)
+ str = converter:match(str)
+ return str, loadstring(format(template,str))()
+end
+
+local map = { }
+
+local space = S(' \r\n\t')
+local squote = S("'")
+local dquote = S('"')
+local lparent = P('(')
+local rparent = P(')')
+local atsign = P('@')
+local lbracket = P('[')
+local rbracket = P(']')
+local exclam = P('!')
+local period = P('.')
+local eq = P('==') + P('=')
+local ne = P('<>') + P('!=')
+local star = P('*')
+local slash = P('/')
+local colon = P(':')
+local bar = P('|')
+local hat = P('^')
+local valid = R('az', 'AZ', '09') + S('_-')
+local name_yes = C(valid^1 + star) * colon * C(valid^1 + star) -- permits ns:* *:tg *:*
+local name_nop = Cc("*") * C(valid^1)
+local name = name_yes + name_nop
+local number = C((S('+-')^0 * R('09')^1)) / tonumber
+local names = (bar^0 * name)^1
+local morenames = name * (bar^0 * name)^1
+local instructiontag = P('pi::')
+local spacing = C(space^0)
+local somespace = space^1
+local optionalspace = space^0
+local text = C(valid^0)
+local value = (squote * C((1 - squote)^0) * squote) + (dquote * C((1 - dquote)^0) * dquote)
+local empty = 1-slash
+
+local is_eq = lbracket * atsign * name * eq * value * rbracket
+local is_ne = lbracket * atsign * name * ne * value * rbracket
+local is_attribute = lbracket * atsign * name * rbracket
+local is_value = lbracket * value * rbracket
+local is_number = lbracket * number * rbracket
+
+local nobracket = 1-(lbracket+rbracket) -- must be improved
+local is_expression = lbracket * C(((C(nobracket^1))/make_expression)) * rbracket
+
+local is_expression = lbracket * (C(nobracket^1))/make_expression * rbracket
+
+local is_one = name
+local is_none = exclam * name
+local is_one_of = ((lparent * names * rparent) + morenames)
+local is_none_of = exclam * ((lparent * names * rparent) + morenames)
+
+local stay = (period )
+local parent = (period * period ) / function( ) map[#map+1] = { 11 } end
+local subtreeroot = (slash + hat ) / function( ) map[#map+1] = { 12 } end
+local documentroot = (hat * hat ) / function( ) map[#map+1] = { 13 } end
+local any = (star ) / function( ) map[#map+1] = { 14 } end
+local many = (star * star ) / function( ) map[#map+1] = { 15 } end
+local initial = (hat * hat * hat ) / function( ) map[#map+1] = { 16 } end
+
+local match = (is_one ) / function(...) map[#map+1] = { 20, true , ... } end
+local match_one_of = (is_one_of ) / function(...) map[#map+1] = { 21, true , ... } end
+local dont_match = (is_none ) / function(...) map[#map+1] = { 20, false, ... } end
+local dont_match_one_of = (is_none_of ) / function(...) map[#map+1] = { 21, false, ... } end
+
+local match_and_eq = (is_one * is_eq ) / function(...) map[#map+1] = { 22, true , ... } end
+local match_and_ne = (is_one * is_ne ) / function(...) map[#map+1] = { 23, true , ... } end
+local dont_match_and_eq = (is_none * is_eq ) / function(...) map[#map+1] = { 22, false, ... } end
+local dont_match_and_ne = (is_none * is_ne ) / function(...) map[#map+1] = { 23, false, ... } end
+
+local match_one_of_and_eq = (is_one_of * is_eq ) / function(...) map[#map+1] = { 24, true , ... } end
+local match_one_of_and_ne = (is_one_of * is_ne ) / function(...) map[#map+1] = { 25, true , ... } end
+local dont_match_one_of_and_eq = (is_none_of * is_eq ) / function(...) map[#map+1] = { 24, false, ... } end
+local dont_match_one_of_and_ne = (is_none_of * is_ne ) / function(...) map[#map+1] = { 25, false, ... } end
+
+local has_attribute = (is_one * is_attribute) / function(...) map[#map+1] = { 27, true , ... } end
+local has_value = (is_one * is_value ) / function(...) map[#map+1] = { 28, true , ... } end
+local dont_has_attribute = (is_none * is_attribute) / function(...) map[#map+1] = { 27, false, ... } end
+local dont_has_value = (is_none * is_value ) / function(...) map[#map+1] = { 28, false, ... } end
+local position = (is_one * is_number ) / function(...) map[#map+1] = { 30, true, ... } end
+local dont_position = (is_none * is_number ) / function(...) map[#map+1] = { 30, false, ... } end
+
+local expression = (is_one * is_expression)/ function(...) map[#map+1] = { 31, true, ... } end
+local dont_expression = (is_none * is_expression)/ function(...) map[#map+1] = { 31, false, ... } end
+
+local self_expression = ( is_expression) / function(...) if #map == 0 then map[#map+1] = { 11 } end
+ map[#map+1] = { 31, true, "*", "*", ... } end
+local dont_self_expression = (exclam * is_expression) / function(...) if #map == 0 then map[#map+1] = { 11 } end
+ map[#map+1] = { 31, false, "*", "*", ... } end
+
+local instruction = (instructiontag * text ) / function(...) map[#map+1] = { 40, ... } end
+local nothing = (empty ) / function( ) map[#map+1] = { 15 } end -- 15 ?
+local crap = (1-slash)^1
+
+-- a few ugly goodies:
+
+local docroottag = P('^^') / function( ) map[#map+1] = { 12 } end
+local subroottag = P('^') / function( ) map[#map+1] = { 13 } end
+local roottag = P('root::') / function( ) map[#map+1] = { 12 } end
+local parenttag = P('parent::') / function( ) map[#map+1] = { 11 } end
+local childtag = P('child::')
+local selftag = P('self::')
+
+-- there will be more and order will be optimized
+
+local selector = (
+ instruction +
+-- many + any + -- brrr, not here !
+ parent + stay +
+ dont_position + position +
+ dont_match_one_of_and_eq + dont_match_one_of_and_ne +
+ match_one_of_and_eq + match_one_of_and_ne +
+ dont_match_and_eq + dont_match_and_ne +
+ match_and_eq + match_and_ne +
+ dont_expression + expression +
+ dont_self_expression + self_expression +
+ has_attribute + has_value +
+ dont_match_one_of + match_one_of +
+ dont_match + match +
+ many + any +
+ crap + empty
+)
+
+local grammar = P { "startup",
+ startup = (initial + documentroot + subtreeroot + roottag + docroottag + subroottag)^0 * V("followup"),
+ followup = ((slash + parenttag + childtag + selftag)^0 * selector)^1,
+}
+
+local function compose(str)
+ if not str or str == "" then
+ -- wildcard
+ return true
+ elseif str == '/' then
+ -- root
+ return false
+ else
+ map = { }
+ grammar:match(str)
+ if #map == 0 then
+ return true
+ else
+ local m = map[1][1]
+ if #map == 1 then
+ if m == 14 or m == 15 then
+ -- wildcard
+ return true
+ elseif m == 12 then
+ -- root
+ return false
+ end
+ elseif #map == 2 and m == 12 and map[2][1] == 20 then
+ -- return { { 29, map[2][2], map[2][3], map[2][4], map[2][5] } }
+ map[2][1] = 29
+ return { map[2] }
+ end
+ if m ~= 11 and m ~= 12 and m ~= 13 and m ~= 14 and m ~= 15 and m ~= 16 then
+ insert(map, 1, { 16 })
+ end
+ -- print(gsub(table.serialize(map),"[ \n]+"," "))
+ return map
+ end
+ end
+end
+
+local cache = { }
+
+function xml.lpath(pattern,trace)
+ lpathcalls = lpathcalls + 1
+ if type(pattern) == "string" then
+ local result = cache[pattern]
+ if result == nil then -- can be false which is valid -)
+ result = compose(pattern)
+ cache[pattern] = result
+ lpathcached = lpathcached + 1
+ end
+ if trace or trace_lpath then
+ xml.lshow(result)
+ end
+ return result
+ else
+ return pattern
+ end
+end
+
+function xml.cached_patterns()
+ return cache
+end
+
+-- we run out of locals (limited to 200)
+--
+-- local fallbackreport = (texio and texio.write) or io.write
+
+function xml.lshow(pattern,report)
+-- report = report or fallbackreport
+ report = report or (texio and texio.write) or io.write
+ local lp = xml.lpath(pattern)
+ if lp == false then
+ report(" -: root\n")
+ elseif lp == true then
+ report(" -: wildcard\n")
+ else
+ if type(pattern) == "string" then
+ report(format("pattern: %s\n",pattern))
+ end
+ for k=1,#lp do
+ local v = lp[k]
+ if #v > 1 then
+ local t = { }
+ for i=2,#v do
+ local vv = v[i]
+ if type(vv) == "string" then
+ t[#t+1] = (vv ~= "" and vv) or "#"
+ elseif type(vv) == "boolean" then
+ t[#t+1] = (vv and "==") or "<>"
+ end
+ end
+ report(format("%2i: %s %s -> %s\n", k,v[1],actions[v[1]],concat(t," ")))
+ else
+ report(format("%2i: %s %s\n", k,v[1],actions[v[1]]))
+ end
+ end
+ end
+end
+
+function xml.xshow(e,...) -- also handy when report is given, use () to isolate first e
+ local t = { ... }
+-- local report = (type(t[#t]) == "function" and t[#t]) or fallbackreport
+ local report = (type(t[#t]) == "function" and t[#t]) or (texio and texio.write) or io.write
+ if e == nil then
+ report("<!-- no element -->\n")
+ elseif type(e) ~= "table" then
+ report(tostring(e))
+ elseif e.tg then
+ report(tostring(e) .. "\n")
+ else
+ for i=1,#e do
+ report(tostring(e[i]) .. "\n")
+ end
+ end
+end
+
+--[[ldx--
+<p>An <l n='lpath'/> is converted to a table with instructions for traversing the
+tree. Hoever, simple cases are signaled by booleans. Because we don't know in
+advance what we want to do with the found element the handle gets three arguments:</p>
+
+<lines>
+<t>r</t> : the root element of the data table
+<t>d</t> : the data table of the result
+<t>t</t> : the index in the data table of the result
+</lines>
+
+<p> Access to the root and data table makes it possible to construct insert and delete
+functions.</p>
+--ldx]]--
+
+local functions = xml.functions
+local expressions = xml.expressions
+
+expressions.contains = string.find
+expressions.find = string.find
+expressions.upper = string.upper
+expressions.lower = string.lower
+expressions.number = tonumber
+expressions.boolean = toboolean
+
+expressions.oneof = function(s,...) -- slow
+ local t = {...} for i=1,#t do if s == t[i] then return true end end return false
+end
+
+expressions.error = function(str)
+ xml.error_handler("unknown function in lpath expression",str or "?")
+ return false
+end
+
+functions.text = function(root,k,n) -- unchecked, maybe one deeper
+ local t = type(t)
+ if t == "string" then
+ return t
+ else -- todo n
+ local rdt = root.dt
+ return (rdt and rdt[k]) or root[k] or ""
+ end
+end
+
+functions.name = function(d,k,n) -- ns + tg
+ local found = false
+ n = n or 0
+ if not k then
+ -- not found
+ elseif n == 0 then
+ local dk = d[k]
+ found = dk and (type(dk) == "table") and dk
+ elseif n < 0 then
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
+ end
+ end
+ else
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
+ end
+ end
+ end
+ if found then
+ local ns, tg = found.rn or found.ns or "", found.tg
+ if ns ~= "" then
+ return ns .. ":" .. tg
+ else
+ return tg
+ end
+ else
+ return ""
+ end
+end
+
+functions.tag = function(d,k,n) -- only tg
+ local found = false
+ n = n or 0
+ if not k then
+ -- not found
+ elseif n == 0 then
+ local dk = d[k]
+ found = dk and (type(dk) == "table") and dk
+ elseif n < 0 then
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
+ end
+ end
+ else
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
+ end
+ end
+ end
+ return (found and found.tg) or ""
+end
+
+expressions.text = functions.text
+expressions.name = functions.name
+expressions.tag = functions.tag
+
+local function traverse(root,pattern,handle,reverse,index,parent,wildcard) -- multiple only for tags, not for namespaces
+ if not root then -- error
+ return false
+ elseif pattern == false then -- root
+ handle(root,root.dt,root.ri)
+ return false
+ elseif pattern == true then -- wildcard
+ local rootdt = root.dt
+ if rootdt then
+ local start, stop, step = 1, #rootdt, 1
+ if reverse then
+ start, stop, step = stop, start, -1
+ end
+ for k=start,stop,step do
+ if handle(root,rootdt,root.ri or k) then return false end
+ if not traverse(rootdt[k],true,handle,reverse) then return false end
+ end
+ end
+ return false
+ elseif root.dt then
+ index = index or 1
+ local action = pattern[index]
+ local command = action[1]
+ if command == 29 then -- fast case /oeps
+ local rootdt = root.dt
+ for k=1,#rootdt do
+ local e = rootdt[k]
+ local tg = e.tg
+ if e.tg then
+ local ns = e.rn or e.ns
+ local ns_a, tg_a = action[3], action[4]
+ local matched = (ns_a == "*" or ns == ns_a) and (tg_a == "*" or tg == tg_a)
+ if not action[2] then matched = not matched end
+ if matched then
+ if handle(root,rootdt,k) then return false end
+ end
+ end
+ end
+ elseif command == 11 then -- parent
+ local ep = root.__p__ or parent
+ if index < #pattern then
+ if not traverse(ep,pattern,handle,reverse,index+1,root) then return false end
+ elseif handle(root,rootdt,k) then
+ return false
+ end
+ else
+ if (command == 16 or command == 12) and index == 1 then -- initial
+ -- wildcard = true
+ wildcard = command == 16 -- ok?
+ index = index + 1
+ action = pattern[index]
+ command = action and action[1] or 0 -- something is wrong
+ end
+ if command == 11 then -- parent
+ local ep = root.__p__ or parent
+ if index < #pattern then
+ if not traverse(ep,pattern,handle,reverse,index+1,root) then return false end
+ elseif handle(root,rootdt,k) then
+ return false
+ end
+ else
+ local rootdt = root.dt
+ local start, stop, step, n, dn = 1, #rootdt, 1, 0, 1
+ if command == 30 then
+ if action[5] < 0 then
+ start, stop, step = stop, start, -1
+ dn = -1
+ end
+ elseif reverse and index == #pattern then
+ start, stop, step = stop, start, -1
+ end
+ local idx = 0
+ local hsh = { } -- this will slooow down the lot
+ for k=start,stop,step do -- we used to have functions for all but a case is faster
+ local e = rootdt[k]
+ local ns, tg = e.rn or e.ns, e.tg
+ if tg then
+ -- we can optimize this for simple searches, but it probably does not pay off
+ hsh[tg] = (hsh[tg] or 0) + 1
+ idx = idx + 1
+ if command == 30 then
+ local ns_a, tg_a = action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ if not action[2] then matched = not matched end
+ if matched then
+ n = n + dn
+ if n == action[5] then
+ if index == #pattern then
+ if handle(root,rootdt,root.ri or k) then return false end
+ else
+ if not traverse(e,pattern,handle,reverse,index+1,root) then return false end
+ end
+ break
+ end
+ elseif wildcard then
+ if not traverse(e,pattern,handle,reverse,index,root,true) then return false end
+ end
+ else
+ local matched, multiple = false, false
+ if command == 20 then -- match
+ local ns_a, tg_a = action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ if not action[2] then matched = not matched end
+ elseif command == 21 then -- match one of
+ multiple = true
+ for i=3,#action,2 do
+ local ns_a, tg_a = action[i], action[i+1]
+ if (ns_a == "*" or ns == ns_a) and (tg == "*" or tg == tg_a) then
+ matched = true
+ break
+ end
+ end
+ if not action[2] then matched = not matched end
+ elseif command == 22 then -- eq
+ local ns_a, tg_a = action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ matched = matched and e.at[action[6]] == action[7]
+ elseif command == 23 then -- ne
+ local ns_a, tg_a = action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ if not action[2] then matched = not matched end
+ matched = mached and e.at[action[6]] ~= action[7]
+ elseif command == 24 then -- one of eq
+ multiple = true
+ for i=3,#action-2,2 do
+ local ns_a, tg_a = action[i], action[i+1]
+ if (ns_a == "*" or ns == ns_a) and (tg == "*" or tg == tg_a) then
+ matched = true
+ break
+ end
+ end
+ if not action[2] then matched = not matched end
+ matched = matched and e.at[action[#action-1]] == action[#action]
+ elseif command == 25 then -- one of ne
+ multiple = true
+ for i=3,#action-2,2 do
+ local ns_a, tg_a = action[i], action[i+1]
+ if (ns_a == "*" or ns == ns_a) and (tg == "*" or tg == tg_a) then
+ matched = true
+ break
+ end
+ end
+ if not action[2] then matched = not matched end
+ matched = matched and e.at[action[#action-1]] ~= action[#action]
+ elseif command == 27 then -- has attribute
+ local ns_a, tg_a = action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ if not action[2] then matched = not matched end
+ matched = matched and e.at[action[5]]
+ elseif command == 28 then -- has value
+ local edt, ns_a, tg_a = e.dt, action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ if not action[2] then matched = not matched end
+ matched = matched and edt and edt[1] == action[5]
+ elseif command == 31 then
+ local edt, ns_a, tg_a = e.dt, action[3], action[4]
+ if tg == tg_a then
+ matched = ns_a == "*" or ns == ns_a
+ elseif tg_a == '*' then
+ matched, multiple = ns_a == "*" or ns == ns_a, true
+ else
+ matched = false
+ end
+ if not action[2] then matched = not matched end
+ if matched then
+ matched = action[6](expressions,root,rootdt,k,e,edt,ns,tg,idx,hsh[tg] or 1)
+ end
+ end
+ if matched then -- combine tg test and at test
+ if index == #pattern then
+ if handle(root,rootdt,root.ri or k) then return false end
+ if wildcard then
+ if multiple then
+ if not traverse(e,pattern,handle,reverse,index,root,true) then return false end
+ else
+ -- maybe or multiple; anyhow, check on (section|title) vs just section and title in example in lxml
+ if not traverse(e,pattern,handle,reverse,index,root) then return false end
+ end
+ end
+ else
+ if not traverse(e,pattern,handle,reverse,index+1,root) then return false end
+ end
+ elseif command == 14 then -- any
+ if index == #pattern then
+ if handle(root,rootdt,root.ri or k) then return false end
+ else
+ if not traverse(e,pattern,handle,reverse,index+1,root) then return false end
+ end
+ elseif command == 15 then -- many
+ if index == #pattern then
+ if handle(root,rootdt,root.ri or k) then return false end
+ else
+ if not traverse(e,pattern,handle,reverse,index+1,root,true) then return false end
+ end
+ -- not here : 11
+ elseif command == 11 then -- parent
+ local ep = e.__p__ or parent
+ if index < #pattern then
+ if not traverse(ep,pattern,handle,reverse,root,index+1) then return false end
+ elseif handle(root,rootdt,k) then
+ return false
+ end
+ elseif command == 40 and e.special and tg == "@pi@" then -- pi
+ local pi = action[2]
+ if pi ~= "" then
+ local pt = e.dt[1]
+ if pt and pt:find(pi) then
+ if handle(root,rootdt,k) then
+ return false
+ end
+ end
+ elseif handle(root,rootdt,k) then
+ return false
+ end
+ elseif wildcard then
+ if not traverse(e,pattern,handle,reverse,index,root,true) then return false end
+ end
+ end
+ else
+ -- not here : 11
+ if command == 11 then -- parent
+ local ep = e.__p__ or parent
+ if index < #pattern then
+ if not traverse(ep,pattern,handle,reverse,index+1,root) then return false end
+ elseif handle(root,rootdt,k) then
+ return false
+ end
+ break -- else loop
+ end
+ end
+ end
+ end
+ end
+ end
+ return true
+end
+
+xml.traverse = traverse
+
+--[[ldx--
+<p>Next come all kind of locators and manipulators. The most generic function here
+is <t>xml.filter(root,pattern)</t>. All registers functions in the filters namespace
+can be path of a search path, as in:</p>
+
+<typing>
+local r, d, k = xml.filter(root,"/a/b/c/position(4)"
+</typing>
+--ldx]]--
+
+local traverse, lpath, convert = xml.traverse, xml.lpath, xml.convert
+
+xml.filters = { }
+
+function xml.filters.default(root,pattern)
+ local rt, dt, dk
+ traverse(root, lpath(pattern), function(r,d,k) rt,dt,dk = r,d,k return true end)
+ return dt and dt[dk], rt, dt, dk
+end
+
+function xml.filters.attributes(root,pattern,arguments)
+ local rt, dt, dk
+ traverse(root, lpath(pattern), function(r,d,k) rt, dt, dk = r, d, k return true end)
+ local ekat = (dt and dt[dk] and dt[dk].at) or (rt and rt.at)
+ if ekat then
+ if arguments then
+ return ekat[arguments] or "", rt, dt, dk
+ else
+ return ekat, rt, dt, dk
+ end
+ else
+ return { }, rt, dt, dk
+ end
+end
+
+function xml.filters.reverse(root,pattern)
+ local rt, dt, dk
+ traverse(root, lpath(pattern), function(r,d,k) rt,dt,dk = r,d,k return true end, 'reverse')
+ return dt and dt[dk], rt, dt, dk
+end
+
+function xml.filters.count(root,pattern,everything)
+ local n = 0
+ traverse(root, lpath(pattern), function(r,d,t)
+ if everything or type(d[t]) == "table" then
+ n = n + 1
+ end
+ end)
+ return n
+end
+
+function xml.filters.elements(root, pattern) -- == all
+ local t = { }
+ traverse(root, lpath(pattern), function(r,d,k)
+ local e = d[k]
+ if e then
+ t[#t+1] = e
+ end
+ end)
+ return t
+end
+
+function xml.filters.texts(root, pattern)
+ local t = { }
+ traverse(root, lpath(pattern), function(r,d,k)
+ local e = d[k]
+ if e and e.dt then
+ t[#t+1] = e.dt
+ end
+ end)
+ return t
+end
+
+function xml.filters.first(root,pattern)
+ local rt, dt, dk
+ traverse(root, lpath(pattern), function(r,d,k) rt,dt,dk = r,d,k return true end)
+ return dt and dt[dk], rt, dt, dk
+end
+
+function xml.filters.last(root,pattern)
+ local rt, dt, dk
+ traverse(root, lpath(pattern), function(r,d,k) rt,dt,dk = r,d,k return true end, 'reverse')
+ return dt and dt[dk], rt, dt, dk
+end
+
+function xml.filters.index(root,pattern,arguments)
+ local rt, dt, dk, reverse, i = nil, nil, nil, false, tonumber(arguments or '1') or 1
+ if i and i ~= 0 then
+ if i < 0 then
+ reverse, i = true, -i
+ end
+ traverse(root, lpath(pattern), function(r,d,k) rt, dt, dk, i = r, d, k, i-1 return i == 0 end, reverse)
+ if i == 0 then
+ return dt and dt[dk], rt, dt, dk
+ end
+ end
+ return nil, nil, nil, nil
+end
+
+function xml.filters.attribute(root,pattern,arguments)
+ local rt, dt, dk
+ traverse(root, lpath(pattern), function(r,d,k) rt, dt, dk = r, d, k return true end)
+ local ekat = (dt and dt[dk] and dt[dk].at) or (rt and rt.at)
+ return (ekat and (ekat[arguments] or ekat[gsub(arguments,"^([\"\'])(.*)%1$","%2")])) or ""
+end
+
+function xml.filters.text(root,pattern,arguments) -- ?? why index, tostring slow
+ local dtk, rt, dt, dk = xml.filters.index(root,pattern,arguments)
+ if dtk then -- n
+ local dtkdt = dtk.dt
+ if not dtkdt then
+ return "", rt, dt, dk
+ elseif #dtkdt == 1 and type(dtkdt[1]) == "string" then
+ return dtkdt[1], rt, dt, dk
+ else
+ return xml.tostring(dtkdt), rt, dt, dk
+ end
+ else
+ return "", rt, dt, dk
+ end
+end
+
+function xml.filters.tag(root,pattern,n)
+ local tag = ""
+ traverse(root, lpath(pattern), function(r,d,k)
+ tag = xml.functions.tag(d,k,n and tonumber(n))
+ return true
+ end)
+ return tag
+end
+
+function xml.filters.name(root,pattern,n)
+ local tag = ""
+ traverse(root, lpath(pattern), function(r,d,k)
+ tag = xml.functions.name(d,k,n and tonumber(n))
+ return true
+ end)
+ return tag
+end
+
+--[[ldx--
+<p>For splitting the filter function from the path specification, we can
+use string matching or lpeg matching. Here the difference in speed is
+neglectable but the lpeg variant is more robust.</p>
+--ldx]]--
+
+-- not faster but hipper ... although ... i can't get rid of the trailing / in the path
+
+local P, S, R, C, V, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc
+
+local slash = P('/')
+local name = (R("az","AZ","--","__"))^1
+local path = C(((1-slash)^0 * slash)^1)
+local argument = P { "(" * C(((1 - S("()")) + V(1))^0) * ")" }
+local action = Cc(1) * path * C(name) * argument
+local attribute = Cc(2) * path * P('@') * C(name)
+local direct = Cc(3) * Cc("../*") * slash^0 * C(name) * argument
+
+local parser = direct + action + attribute
+
+local filters = xml.filters
+local attribute_filter = xml.filters.attributes
+local default_filter = xml.filters.default
+
+-- todo: also hash, could be gc'd
+
+function xml.filter(root,pattern)
+ local kind, a, b, c = parser:match(pattern)
+ if kind == 1 or kind == 3 then
+ return (filters[b] or default_filter)(root,a,c)
+ elseif kind == 2 then
+ return attribute_filter(root,a,b)
+ else
+ return default_filter(root,pattern)
+ end
+end
+
+--~ slightly faster, but first we need a proper test file
+--~
+--~ local hash = { }
+--~
+--~ function xml.filter(root,pattern)
+--~ local h = hash[pattern]
+--~ if not h then
+--~ local kind, a, b, c = parser:match(pattern)
+--~ if kind == 1 then
+--~ h = { kind, filters[b] or default_filter, a, b, c }
+--~ elseif kind == 2 then
+--~ h = { kind, attribute_filter, a, b, c }
+--~ else
+--~ h = { kind, default_filter, a, b, c }
+--~ end
+--~ hash[pattern] = h
+--~ end
+--~ local kind = h[1]
+--~ if kind == 1 then
+--~ return h[2](root,h[2],h[4])
+--~ elseif kind == 2 then
+--~ return h[2](root,h[2],h[3])
+--~ else
+--~ return h[2](root,pattern)
+--~ end
+--~ end
+
+--[[ldx--
+<p>The following functions collect elements and texts.</p>
+--ldx]]--
+
+-- still somewhat bugged
+
+function xml.collect_elements(root, pattern, ignorespaces)
+ local rr, dd = { }, { }
+ traverse(root, lpath(pattern), function(r,d,k)
+ local dk = d and d[k]
+ if dk then
+ if ignorespaces and type(dk) == "string" and dk:find("[^%S]") then
+ -- ignore
+ else
+ local n = #rr+1
+ rr[n], dd[n] = r, dk
+ end
+ end
+ end)
+ return dd, rr
+end
+
+function xml.collect_texts(root, pattern, flatten)
+ local t = { } -- no r collector
+ traverse(root, lpath(pattern), function(r,d,k)
+ if d then
+ local ek = d[k]
+ local tx = ek and ek.dt
+ if flatten then
+ if tx then
+ t[#t+1] = xml.tostring(tx) or ""
+ else
+ t[#t+1] = ""
+ end
+ else
+ t[#t+1] = tx or ""
+ end
+ else
+ t[#t+1] = ""
+ end
+ end)
+ return t
+end
+
+function xml.collect_tags(root, pattern, nonamespace)
+ local t = { }
+ xml.traverse(root, xml.lpath(pattern), function(r,d,k)
+ local dk = d and d[k]
+ if dk and type(dk) == "table" then
+ local ns, tg = e.ns, e.tg
+ if nonamespace then
+ t[#t+1] = tg -- if needed we can return an extra table
+ elseif ns == "" then
+ t[#t+1] = tg
+ else
+ t[#t+1] = ns .. ":" .. tg
+ end
+ end
+ end)
+ return #t > 0 and {}
+end
+
+--[[ldx--
+<p>Often using an iterators looks nicer in the code than passing handler
+functions. The <l n='lua'/> book describes how to use coroutines for that
+purpose (<url href='http://www.lua.org/pil/9.3.html'/>). This permits
+code like:</p>
+
+<typing>
+for r, d, k in xml.elements(xml.load('text.xml'),"title") do
+ print(d[k])
+end
+</typing>
+
+<p>Which will print all the titles in the document. The iterator variant takes
+1.5 times the runtime of the function variant which is due to the overhead in
+creating the wrapper. So, instead of:</p>
+
+<typing>
+function xml.filters.first(root,pattern)
+ for rt,dt,dk in xml.elements(root,pattern)
+ return dt and dt[dk], rt, dt, dk
+ end
+ return nil, nil, nil, nil
+end
+</typing>
+
+<p>We use the function variants in the filters.</p>
+--ldx]]--
+
+local wrap, yield = coroutine.wrap, coroutine.yield
+
+function xml.elements(root,pattern,reverse)
+ return wrap(function() traverse(root, lpath(pattern), yield, reverse) end)
+end
+
+function xml.elements_only(root,pattern,reverse)
+ return wrap(function() traverse(root, lpath(pattern), function(r,d,k) yield(d[k]) end, reverse) end)
+end
+
+function xml.each_element(root, pattern, handle, reverse)
+ local ok
+ traverse(root, lpath(pattern), function(r,d,k) ok = true handle(r,d,k) end, reverse)
+ return ok
+end
+
+function xml.process_elements(root, pattern, handle)
+ traverse(root, lpath(pattern), function(r,d,k)
+ local dkdt = d[k].dt
+ if dkdt then
+ for i=1,#dkdt do
+ local v = dkdt[i]
+ if v.tg then handle(v) end
+ end
+ end
+ end)
+end
+
+function xml.process_attributes(root, pattern, handle)
+ traverse(root, lpath(pattern), function(r,d,k)
+ local ek = d[k]
+ local a = ek.at or { }
+ handle(a)
+ if next(a) then -- next is faster than type (and >0 test)
+ ek.at = a
+ else
+ ek.at = nil
+ end
+ end)
+end
+
+--[[ldx--
+<p>We've now arrives at the functions that manipulate the tree.</p>
+--ldx]]--
+
+function xml.inject_element(root, pattern, element, prepend)
+ if root and element then
+ local matches, collect = { }, nil
+ if type(element) == "string" then
+ element = convert(element,true)
+ end
+ if element then
+ collect = function(r,d,k) matches[#matches+1] = { r, d, k, element } end
+ traverse(root, lpath(pattern), collect)
+ for i=1,#matches do
+ local m = matches[i]
+ local r, d, k, element, edt = m[1], m[2], m[3], m[4], nil
+ if element.ri then
+ element = element.dt[element.ri].dt
+ else
+ element = element.dt
+ end
+ if r.ri then
+ edt = r.dt[r.ri].dt
+ else
+ edt = d and d[k] and d[k].dt
+ end
+ if edt then
+ local be, af
+ if prepend then
+ be, af = xml.copy(element), edt
+ else
+ be, af = edt, xml.copy(element)
+ end
+ for i=1,#af do
+ be[#be+1] = af[i]
+ end
+ if r.ri then
+ r.dt[r.ri].dt = be
+ else
+ d[k].dt = be
+ end
+ else
+ -- r.dt = element.dt -- todo
+ end
+ end
+ end
+ end
+end
+
+-- todo: copy !
+
+function xml.insert_element(root, pattern, element, before) -- todo: element als functie
+ if root and element then
+ if pattern == "/" then
+ xml.inject_element(root, pattern, element, before)
+ else
+ local matches, collect = { }, nil
+ if type(element) == "string" then
+ element = convert(element,true)
+ end
+ if element and element.ri then
+ element = element.dt[element.ri]
+ end
+ if element then
+ collect = function(r,d,k) matches[#matches+1] = { r, d, k, element } end
+ traverse(root, lpath(pattern), collect)
+ for i=#matches,1,-1 do
+ local m = matches[i]
+ local r, d, k, element = m[1], m[2], m[3], m[4]
+ if not before then k = k + 1 end
+ if element.tg then
+ insert(d,k,element) -- untested
+--~ elseif element.dt then
+--~ for _,v in ipairs(element.dt) do -- i added
+--~ insert(d,k,v)
+--~ k = k + 1
+--~ end
+--~ end
+ else
+ local edt = element.dt
+ if edt then
+ for i=1,#edt do
+ insert(d,k,edt[i])
+ k = k + 1
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+xml.insert_element_after = xml.insert_element
+xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end
+xml.inject_element_after = xml.inject_element
+xml.inject_element_before = function(r,p,e) xml.inject_element(r,p,e,true) end
+
+function xml.delete_element(root, pattern)
+ local matches, deleted = { }, { }
+ local collect = function(r,d,k) matches[#matches+1] = { r, d, k } end
+ traverse(root, lpath(pattern), collect)
+ for i=#matches,1,-1 do
+ local m = matches[i]
+ deleted[#deleted+1] = remove(m[2],m[3])
+ end
+ return deleted
+end
+
+function xml.replace_element(root, pattern, element)
+ if type(element) == "string" then
+ element = convert(element,true)
+ end
+ if element and element.ri then
+ element = element.dt[element.ri]
+ end
+ if element then
+ traverse(root, lpath(pattern), function(rm, d, k)
+ d[k] = element.dt -- maybe not clever enough
+ end)
+ end
+end
+
+local function load_data(name) -- == io.loaddata
+ local f, data = io.open(name), ""
+ if f then
+ data = f:read("*all",'b') -- 'b' ?
+ f:close()
+ end
+ return data
+end
+
+function xml.include(xmldata,pattern,attribute,recursive,loaddata)
+ -- parse="text" (default: xml), encoding="" (todo)
+ -- attribute = attribute or 'href'
+ pattern = pattern or 'include'
+ loaddata = loaddata or load_data
+ local function include(r,d,k)
+ local ek, name = d[k], nil
+ if not attribute or attribute == "" then
+ local ekdt = ek.dt
+ name = (type(ekdt) == "table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ if ek.at then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name = ek.at[a]
+ if name then break end
+ end
+ end
+ end
+ local data = (name and name ~= "" and loaddata(name)) or ""
+ if data == "" then
+ xml.empty(d,k)
+ elseif ek.at["parse"] == "text" then -- for the moment hard coded
+ d[k] = xml.escaped(data)
+ else
+ local xi = xml.convert(data)
+ if not xi then
+ xml.empty(d,k)
+ else
+ if recursive then
+ xml.include(xi,pattern,attribute,recursive,loaddata)
+ end
+ xml.assign(d,k,xi)
+ end
+ end
+ end
+ xml.each_element(xmldata, pattern, include)
+end
+
+function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and trailing space !
+ traverse(root, lpath(pattern), function(r,d,k)
+ local dkdt = d[k].dt
+ if dkdt then -- can be optimized
+ local t = { }
+ for i=1,#dkdt do
+ local str = dkdt[i]
+ if type(str) == "string" then
+
+ if str == "" then
+ -- stripped
+ else
+ if nolines then
+ str = gsub(str,"[ \n\r\t]+"," ")
+ end
+ if str == "" then
+ -- stripped
+ else
+ t[#t+1] = str
+ end
+ end
+ else
+ t[#t+1] = str
+ end
+ end
+ d[k].dt = t
+ end
+ end)
+end
+
+local function rename_space(root, oldspace, newspace) -- fast variant
+ local ndt = #root.dt
+ for i=1,ndt or 0 do
+ local e = root[i]
+ if type(e) == "table" then
+ if e.ns == oldspace then
+ e.ns = newspace
+ if e.rn then
+ e.rn = newspace
+ end
+ end
+ local edt = e.dt
+ if edt then
+ rename_space(edt, oldspace, newspace)
+ end
+ end
+ end
+end
+
+xml.rename_space = rename_space
+
+function xml.remap_tag(root, pattern, newtg)
+ traverse(root, lpath(pattern), function(r,d,k)
+ d[k].tg = newtg
+ end)
+end
+function xml.remap_namespace(root, pattern, newns)
+ traverse(root, lpath(pattern), function(r,d,k)
+ d[k].ns = newns
+ end)
+end
+function xml.check_namespace(root, pattern, newns)
+ traverse(root, lpath(pattern), function(r,d,k)
+ local dk = d[k]
+ if (not dk.rn or dk.rn == "") and dk.ns == "" then
+ dk.rn = newns
+ end
+ end)
+end
+function xml.remap_name(root, pattern, newtg, newns, newrn)
+ traverse(root, lpath(pattern), function(r,d,k)
+ local dk = d[k]
+ dk.tg = newtg
+ dk.ns = newns
+ dk.rn = newrn
+ end)
+end
+
+function xml.filters.found(root,pattern,check_content)
+ local found = false
+ traverse(root, lpath(pattern), function(r,d,k)
+ if check_content then
+ local dk = d and d[k]
+ found = dk and dk.dt and next(dk.dt) and true
+ else
+ found = true
+ end
+ return true
+ end)
+ return found
+end
+
+--[[ldx--
+<p>Here are a few synonyms.</p>
+--ldx]]--
+
+xml.filters.position = xml.filters.index
+
+xml.count = xml.filters.count
+xml.index = xml.filters.index
+xml.position = xml.filters.index
+xml.first = xml.filters.first
+xml.last = xml.filters.last
+xml.found = xml.filters.found
+
+xml.each = xml.each_element
+xml.process = xml.process_element
+xml.strip = xml.strip_whitespace
+xml.collect = xml.collect_elements
+xml.all = xml.collect_elements
+
+xml.insert = xml.insert_element_after
+xml.inject = xml.inject_element_after
+xml.after = xml.insert_element_after
+xml.before = xml.insert_element_before
+xml.delete = xml.delete_element
+xml.replace = xml.replace_element
+
+--[[ldx--
+<p>The following helper functions best belong to the <t>lmxl-ini</t>
+module. Some are here because we need then in the <t>mk</t>
+document and other manuals, others came up when playing with
+this module. Since this module is also used in <l n='mtxrun'/> we've
+put them here instead of loading mode modules there then needed.</p>
+--ldx]]--
+
+function xml.gsub(t,old,new)
+ local dt = t.dt
+ if dt then
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "string" then
+ dt[k] = gsub(v,old,new)
+ else
+ xml.gsub(v,old,new)
+ end
+ end
+ end
+end
+
+function xml.strip_leading_spaces(dk,d,k) -- cosmetic, for manual
+ if d and k and d[k-1] and type(d[k-1]) == "string" then
+ local s = d[k-1]:match("\n(%s+)")
+ xml.gsub(dk,"\n"..string.rep(" ",#s),"\n")
+ end
+end
+
+function xml.serialize_path(root,lpath,handle)
+ local dk, r, d, k = xml.first(root,lpath)
+ dk = xml.copy(dk)
+ xml.strip_leading_spaces(dk,d,k)
+ xml.serialize(dk,handle)
+end
+
+--~ xml.escapes = { ['&'] = '&amp;', ['<'] = '&lt;', ['>'] = '&gt;', ['"'] = '&quot;' }
+--~ xml.unescapes = { } for k,v in pairs(xml.escapes) do xml.unescapes[v] = k end
+
+--~ function xml.escaped (str) return (gsub(str,"(.)" , xml.escapes )) end
+--~ function xml.unescaped(str) return (gsub(str,"(&.-;)", xml.unescapes)) end
+--~ function xml.cleansed (str) return (gsub(str,"<.->" , '' )) end -- "%b<>"
+
+local P, S, R, C, V, Cc, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Cs
+
+-- 100 * 2500 * "oeps< oeps> oeps&" : gsub:lpeg|lpeg|lpeg
+--
+-- 1021:0335:0287:0247
+
+-- 10 * 1000 * "oeps< oeps> oeps& asfjhalskfjh alskfjh alskfjh alskfjh ;al J;LSFDJ"
+--
+-- 1559:0257:0288:0190 (last one suggested by roberto)
+
+-- escaped = Cs((S("<&>") / xml.escapes + 1)^0)
+-- escaped = Cs((S("<")/"&lt;" + S(">")/"&gt;" + S("&")/"&amp;" + 1)^0)
+local normal = (1 - S("<&>"))^0
+local special = P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;"
+local escaped = Cs(normal * (special * normal)^0)
+
+-- 100 * 1000 * "oeps&lt; oeps&gt; oeps&amp;" : gsub:lpeg == 0153:0280:0151:0080 (last one by roberto)
+
+-- unescaped = Cs((S("&lt;")/"<" + S("&gt;")/">" + S("&amp;")/"&" + 1)^0)
+-- unescaped = Cs((((P("&")/"") * (P("lt")/"<" + P("gt")/">" + P("amp")/"&") * (P(";")/"")) + 1)^0)
+local normal = (1 - S"&")^0
+local special = P("&lt;")/"<" + P("&gt;")/">" + P("&amp;")/"&"
+local unescaped = Cs(normal * (special * normal)^0)
+
+-- 100 * 5000 * "oeps <oeps bla='oeps' foo='bar'> oeps </oeps> oeps " : gsub:lpeg == 623:501 msec (short tags, less difference)
+
+local cleansed = Cs(((P("<") * (1-P(">"))^0 * P(">"))/"" + 1)^0)
+
+function xml.escaped (str) return escaped :match(str) end
+function xml.unescaped(str) return unescaped:match(str) end
+function xml.cleansed (str) return cleansed :match(str) end
+
+function xml.join(t,separator,lastseparator)
+ if #t > 0 then
+ local result = { }
+ for k,v in pairs(t) do
+ result[k] = xml.tostring(v)
+ end
+ if lastseparator then
+ return concat(result,separator or "",1,#result-1) .. (lastseparator or "") .. result[#result]
+ else
+ return concat(result,separator)
+ end
+ else
+ return ""
+ end
+end
+
+function xml.statistics()
+ return {
+ lpathcalls = lpathcalls,
+ lpathcached = lpathcached,
+ }
+end
+
+-- xml.set_text_cleanup(xml.show_text_entities)
+-- xml.set_text_cleanup(xml.resolve_text_entities)
+
+--~ xml.lshow("/../../../a/(b|c)[@d='e']/f")
+--~ xml.lshow("/../../../a/!(b|c)[@d='e']/f")
+--~ xml.lshow("/../../../a/!b[@d!='e']/f")
+
+--~ x = xml.convert([[
+--~ <a>
+--~ <b n='01'>01</b>
+--~ <b n='02'>02</b>
+--~ <b n='03'>03</b>
+--~ <b n='04'>OK</b>
+--~ <b n='05'>05</b>
+--~ <b n='06'>06</b>
+--~ <b n='07'>ALSO OK</b>
+--~ </a>
+--~ ]])
+
+--~ xml.settrace("lpath",true)
+
+--~ xml.xshow(xml.first(x,"b[position() > 2 and position() < 5 and text() == 'ok']"))
+--~ xml.xshow(xml.first(x,"b[position() > 2 and position() < 5 and text() == upper('ok')]"))
+--~ xml.xshow(xml.first(x,"b[@n=='03' or @n=='08']"))
+--~ xml.xshow(xml.all (x,"b[number(@n)>2 and number(@n)<6]"))
+--~ xml.xshow(xml.first(x,"b[find(text(),'ALSO')]"))
+
+--~ str = [[
+--~ <?xml version="1.0" encoding="utf-8"?>
+--~ <story line='mojca'>
+--~ <windows>my secret</mouse>
+--~ </story>
+--~ ]]
+
+--~ x = xml.convert([[
+--~ <a><b n='01'>01</b><b n='02'>02</b><x>xx</x><b n='03'>03</b><b n='04'>OK</b></a>
+--~ ]])
+--~ xml.xshow(xml.first(x,"b[tag(2) == 'x']"))
+--~ xml.xshow(xml.first(x,"b[tag(1) == 'x']"))
+--~ xml.xshow(xml.first(x,"b[tag(-1) == 'x']"))
+--~ xml.xshow(xml.first(x,"b[tag(-2) == 'x']"))
+
+--~ print(xml.filter(x,"b/tag(2)"))
+--~ print(xml.filter(x,"b/tag(1)"))
diff --git a/tex/context/base/lxml-tab.lua b/tex/context/base/lxml-tab.lua
new file mode 100644
index 000000000..a35e64270
--- /dev/null
+++ b/tex/context/base/lxml-tab.lua
@@ -0,0 +1,783 @@
+if not modules then modules = { } end modules ['lxml-tab'] = {
+ version = 1.001,
+ comment = "this module is the basis for the lxml-* ones",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>The parser used here is inspired by the variant discussed in the lua book, but
+handles comment and processing instructions, has a different structure, provides
+parent access; a first version used different trickery but was less optimized to we
+went this route. First we had a find based parser, now we have an <l n='lpeg'/> based one.
+The find based parser can be found in l-xml-edu.lua along with other older code.</p>
+
+<p>Expecially the lpath code is experimental, we will support some of xpath, but
+only things that make sense for us; as compensation it is possible to hook in your
+own functions. Apart from preprocessing content for <l n='context'/> we also need
+this module for process management, like handling <l n='ctx'/> and <l n='rlx'/>
+files.</p>
+
+<typing>
+a/b/c /*/c
+a/b/c/first() a/b/c/last() a/b/c/index(n) a/b/c/index(-n)
+a/b/c/text() a/b/c/text(1) a/b/c/text(-1) a/b/c/text(n)
+</typing>
+
+<p>Beware, the interface may change. For instance at, ns, tg, dt may get more
+verbose names. Once the code is stable we will also remove some tracing and
+optimize the code.</p>
+--ldx]]--
+
+xml = xml or { }
+
+--~ local xml = xml
+
+local concat, remove, insert = table.concat, table.remove, table.insert
+local type, next, setmetatable = type, next, setmetatable
+local format, lower, find = string.format, string.lower, string.find
+
+--[[ldx--
+<p>This module can be used stand alone but also inside <l n='mkiv'/> in
+which case it hooks into the tracker code. Therefore we provide a few
+functions that set the tracers.</p>
+--ldx]]--
+
+local trace_remap = false
+
+if trackers then
+ trackers.register("xml.remap", function(v) trace_remap = v end)
+end
+
+function xml.settrace(str,value)
+ if str == "remap" then
+ trace_remap = value or false
+ end
+end
+
+--[[ldx--
+<p>First a hack to enable namespace resolving. A namespace is characterized by
+a <l n='url'/>. The following function associates a namespace prefix with a
+pattern. We use <l n='lpeg'/>, which in this case is more than twice as fast as a
+find based solution where we loop over an array of patterns. Less code and
+much cleaner.</p>
+--ldx]]--
+
+xml.xmlns = xml.xmlns or { }
+
+local check = lpeg.P(false)
+local parse = check
+
+--[[ldx--
+<p>The next function associates a namespace prefix with an <l n='url'/>. This
+normally happens independent of parsing.</p>
+
+<typing>
+xml.registerns("mml","mathml")
+</typing>
+--ldx]]--
+
+function xml.registerns(namespace, pattern) -- pattern can be an lpeg
+ check = check + lpeg.C(lpeg.P(lower(pattern))) / namespace
+ parse = lpeg.P { lpeg.P(check) + 1 * lpeg.V(1) }
+end
+
+--[[ldx--
+<p>The next function also registers a namespace, but this time we map a
+given namespace prefix onto a registered one, using the given
+<l n='url'/>. This used for attributes like <t>xmlns:m</t>.</p>
+
+<typing>
+xml.checkns("m","http://www.w3.org/mathml")
+</typing>
+--ldx]]--
+
+function xml.checkns(namespace,url)
+ local ns = parse:match(lower(url))
+ if ns and namespace ~= ns then
+ xml.xmlns[namespace] = ns
+ end
+end
+
+--[[ldx--
+<p>Next we provide a way to turn an <l n='url'/> into a registered
+namespace. This used for the <t>xmlns</t> attribute.</p>
+
+<typing>
+resolvedns = xml.resolvens("http://www.w3.org/mathml")
+</typing>
+
+This returns <t>mml</t>.
+--ldx]]--
+
+function xml.resolvens(url)
+ return parse:match(lower(url)) or ""
+end
+
+--[[ldx--
+<p>A namespace in an element can be remapped onto the registered
+one efficiently by using the <t>xml.xmlns</t> table.</p>
+--ldx]]--
+
+--[[ldx--
+<p>This version uses <l n='lpeg'/>. We follow the same approach as before, stack and top and
+such. This version is about twice as fast which is mostly due to the fact that
+we don't have to prepare the stream for cdata, doctype etc etc. This variant is
+is dedicated to Luigi Scarso, who challenged me with 40 megabyte <l n='xml'/> files that
+took 12.5 seconds to load (1.5 for file io and the rest for tree building). With
+the <l n='lpeg'/> implementation we got that down to less 7.3 seconds. Loading the 14
+<l n='context'/> interface definition files (2.6 meg) went down from 1.05 seconds to 0.55.</p>
+
+<p>Next comes the parser. The rather messy doctype definition comes in many
+disguises so it is no surprice that later on have to dedicate quite some
+<l n='lpeg'/> code to it.</p>
+
+<typing>
+<!DOCTYPE Something PUBLIC "... ..." "..." [ ... ] >
+<!DOCTYPE Something PUBLIC "... ..." "..." >
+<!DOCTYPE Something SYSTEM "... ..." [ ... ] >
+<!DOCTYPE Something SYSTEM "... ..." >
+<!DOCTYPE Something [ ... ] >
+<!DOCTYPE Something >
+</typing>
+
+<p>The code may look a bit complex but this is mostly due to the fact that we
+resolve namespaces and attach metatables. There is only one public function:</p>
+
+<typing>
+local x = xml.convert(somestring)
+</typing>
+
+<p>An optional second boolean argument tells this function not to create a root
+element.</p>
+--ldx]]--
+
+xml.strip_cm_and_dt = false -- an extra global flag, in case we have many includes
+
+-- not just one big nested table capture (lpeg overflow)
+
+local nsremap, resolvens = xml.xmlns, xml.resolvens
+
+local stack, top, dt, at, xmlns, errorstr, entities = {}, {}, {}, {}, {}, nil, {}
+
+local mt = { __tostring = xml.text }
+
+function xml.check_error(top,toclose)
+ return ""
+end
+
+local strip = false
+local cleanup = false
+
+function xml.set_text_cleanup(fnc)
+ cleanup = fnc
+end
+
+local function add_attribute(namespace,tag,value)
+ if cleanup and #value > 0 then
+ value = cleanup(value) -- new
+ end
+ if tag == "xmlns" then
+ xmlns[#xmlns+1] = resolvens(value)
+ at[tag] = value
+ elseif namespace == "xmlns" then
+ xml.checkns(tag,value)
+ at["xmlns:" .. tag] = value
+ else
+ at[tag] = value
+ end
+end
+
+local function add_begin(spacing, namespace, tag)
+ if #spacing > 0 then
+ dt[#dt+1] = spacing
+ end
+ local resolved = (namespace == "" and xmlns[#xmlns]) or nsremap[namespace] or namespace
+ top = { ns=namespace or "", rn=resolved, tg=tag, at=at, dt={}, __p__ = stack[#stack] }
+ setmetatable(top, mt)
+ dt = top.dt
+ stack[#stack+1] = top
+ at = { }
+end
+
+local function add_end(spacing, namespace, tag)
+ if #spacing > 0 then
+ dt[#dt+1] = spacing
+ end
+ local toclose = remove(stack)
+ top = stack[#stack]
+ if #stack < 1 then
+ errorstr = format("nothing to close with %s %s", tag, xml.check_error(top,toclose) or "")
+ elseif toclose.tg ~= tag then -- no namespace check
+ errorstr = format("unable to close %s with %s %s", toclose.tg, tag, xml.check_error(top,toclose) or "")
+ end
+ dt = top.dt
+ dt[#dt+1] = toclose
+ dt[0] = top
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
+end
+
+local function add_empty(spacing, namespace, tag)
+ if #spacing > 0 then
+ dt[#dt+1] = spacing
+ end
+ local resolved = (namespace == "" and xmlns[#xmlns]) or nsremap[namespace] or namespace
+ top = stack[#stack]
+ dt = top.dt
+ local t = { ns=namespace or "", rn=resolved, tg=tag, at=at, dt={}, __p__ = top }
+ dt[#dt+1] = t
+ setmetatable(t, mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at = { }
+end
+
+local function add_text(text)
+ if cleanup and #text > 0 then
+ dt[#dt+1] = cleanup(text)
+ else
+ dt[#dt+1] = text
+ end
+end
+
+local function add_special(what, spacing, text)
+ if #spacing > 0 then
+ dt[#dt+1] = spacing
+ end
+ if strip and (what == "@cm@" or what == "@dt@") then
+ -- forget it
+ else
+ dt[#dt+1] = { special=true, ns="", tg=what, dt={text} }
+ end
+end
+
+local function set_message(txt)
+ errorstr = "garbage at the end of the file: " .. gsub(txt,"([ \n\r\t]*)","")
+end
+
+local P, S, R, C, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V
+
+local space = S(' \r\n\t')
+local open = P('<')
+local close = P('>')
+local squote = S("'")
+local dquote = S('"')
+local equal = P('=')
+local slash = P('/')
+local colon = P(':')
+local valid = R('az', 'AZ', '09') + S('_-.')
+local name_yes = C(valid^1) * colon * C(valid^1)
+local name_nop = C(P(true)) * C(valid^1)
+local name = name_yes + name_nop
+
+local utfbom = P('\000\000\254\255') + P('\255\254\000\000') +
+ P('\255\254') + P('\254\255') + P('\239\187\191') -- no capture
+
+local spacing = C(space^0)
+local justtext = C((1-open)^1)
+local somespace = space^1
+local optionalspace = space^0
+
+local value = (squote * C((1 - squote)^0) * squote) + (dquote * C((1 - dquote)^0) * dquote)
+local attribute = (somespace * name * optionalspace * equal * optionalspace * value) / add_attribute
+local attributes = attribute^0
+
+local text = justtext / add_text
+local balanced = P { "[" * ((1 - S"[]") + V(1))^0 * "]" } -- taken from lpeg manual, () example
+
+local emptyelement = (spacing * open * name * attributes * optionalspace * slash * close) / add_empty
+local beginelement = (spacing * open * name * attributes * optionalspace * close) / add_begin
+local endelement = (spacing * open * slash * name * optionalspace * close) / add_end
+
+local begincomment = open * P("!--")
+local endcomment = P("--") * close
+local begininstruction = open * P("?")
+local endinstruction = P("?") * close
+local begincdata = open * P("![CDATA[")
+local endcdata = P("]]") * close
+
+local someinstruction = C((1 - endinstruction)^0)
+local somecomment = C((1 - endcomment )^0)
+local somecdata = C((1 - endcdata )^0)
+
+local function entity(k,v) entities[k] = v end
+
+local begindoctype = open * P("!DOCTYPE")
+local enddoctype = close
+local beginset = P("[")
+local endset = P("]")
+local doctypename = C((1-somespace)^0)
+local elementdoctype = optionalspace * P("<!ELEMENT") * (1-close)^0 * close
+local entitydoctype = optionalspace * P("<!ENTITY") * somespace * (doctypename * somespace * value)/entity * optionalspace * close
+local publicdoctype = doctypename * somespace * P("PUBLIC") * somespace * value * somespace * value * somespace
+local systemdoctype = doctypename * somespace * P("SYSTEM") * somespace * value * somespace
+local definitiondoctype= doctypename * somespace * beginset * P(elementdoctype + entitydoctype)^0 * optionalspace * endset
+local simpledoctype = (1-close)^1 -- * balanced^0
+local somedoctype = C((somespace * (publicdoctype + systemdoctype + definitiondoctype + simpledoctype) * optionalspace)^0)
+
+local instruction = (spacing * begininstruction * someinstruction * endinstruction) / function(...) add_special("@pi@",...) end
+local comment = (spacing * begincomment * somecomment * endcomment ) / function(...) add_special("@cm@",...) end
+local cdata = (spacing * begincdata * somecdata * endcdata ) / function(...) add_special("@cd@",...) end
+local doctype = (spacing * begindoctype * somedoctype * enddoctype ) / function(...) add_special("@dt@",...) end
+
+-- nicer but slower:
+--
+-- local instruction = (lpeg.Cc("@pi@") * spacing * begininstruction * someinstruction * endinstruction) / add_special
+-- local comment = (lpeg.Cc("@cm@") * spacing * begincomment * somecomment * endcomment ) / add_special
+-- local cdata = (lpeg.Cc("@cd@") * spacing * begincdata * somecdata * endcdata ) / add_special
+-- local doctype = (lpeg.Cc("@dt@") * spacing * begindoctype * somedoctype * enddoctype ) / add_special
+
+local trailer = space^0 * (justtext/set_message)^0
+
+-- comment + emptyelement + text + cdata + instruction + V("parent"), -- 6.5 seconds on 40 MB database file
+-- text + comment + emptyelement + cdata + instruction + V("parent"), -- 5.8
+-- text + V("parent") + emptyelement + comment + cdata + instruction, -- 5.5
+
+local grammar = P { "preamble",
+ preamble = utfbom^0 * instruction^0 * (doctype + comment + instruction)^0 * V("parent") * trailer,
+ parent = beginelement * V("children")^0 * endelement,
+ children = text + V("parent") + emptyelement + comment + cdata + instruction,
+}
+
+-- todo: xml.new + properties like entities and strip and such (store in root)
+
+function xml.convert(data, no_root, strip_cm_and_dt, given_entities) -- maybe use table met k/v (given_entities may disapear)
+ strip = strip_cm_and_dt or xml.strip_cm_and_dt
+ stack, top, at, xmlns, errorstr, result, entities = {}, {}, {}, {}, nil, nil, given_entities or {}
+ stack[#stack+1] = top
+ top.dt = { }
+ dt = top.dt
+ if not data or data == "" then
+ errorstr = "empty xml file"
+ elseif not grammar:match(data) then
+ errorstr = "invalid xml file"
+ else
+ errorstr = ""
+ end
+ if errorstr and errorstr ~= "" then
+ result = { dt = { { ns = "", tg = "error", dt = { errorstr }, at={}, er = true } }, error = true }
+ setmetatable(stack, mt)
+ if xml.error_handler then xml.error_handler("load",errorstr) end
+ else
+ result = stack[1]
+ end
+ if not no_root then
+ result = { special = true, ns = "", tg = '@rt@', dt = result.dt, at={}, entities = entities }
+ setmetatable(result, mt)
+ local rdt = result.dt
+ for k=1,#rdt do
+ local v = rdt[k]
+ if type(v) == "table" and not v.special then -- always table -)
+ result.ri = k -- rootindex
+ break
+ end
+ end
+ end
+ return result
+end
+
+--[[ldx--
+<p>Packaging data in an xml like table is done with the following
+function. Maybe it will go away (when not used).</p>
+--ldx]]--
+
+function xml.is_valid(root)
+ return root and root.dt and root.dt[1] and type(root.dt[1]) == "table" and not root.dt[1].er
+end
+
+function xml.package(tag,attributes,data)
+ local ns, tg = tag:match("^(.-):?([^:]+)$")
+ local t = { ns = ns, tg = tg, dt = data or "", at = attributes or {} }
+ setmetatable(t, mt)
+ return t
+end
+
+function xml.is_valid(root)
+ return root and not root.error
+end
+
+xml.error_handler = (logs and logs.report) or (input and logs.report) or print
+
+--[[ldx--
+<p>We cannot load an <l n='lpeg'/> from a filehandle so we need to load
+the whole file first. The function accepts a string representing
+a filename or a file handle.</p>
+--ldx]]--
+
+function xml.load(filename)
+ if type(filename) == "string" then
+ local f = io.open(filename,'r')
+ if f then
+ local root = xml.convert(f:read("*all"))
+ f:close()
+ return root
+ else
+ return xml.convert("")
+ end
+ elseif filename then -- filehandle
+ return xml.convert(filename:read("*all"))
+ else
+ return xml.convert("")
+ end
+end
+
+--[[ldx--
+<p>When we inject new elements, we need to convert strings to
+valid trees, which is what the next function does.</p>
+--ldx]]--
+
+function xml.toxml(data)
+ if type(data) == "string" then
+ local root = { xml.convert(data,true) }
+ return (#root > 1 and root) or root[1]
+ else
+ return data
+ end
+end
+
+--[[ldx--
+<p>For copying a tree we use a dedicated function instead of the
+generic table copier. Since we know what we're dealing with we
+can speed up things a bit. The second argument is not to be used!</p>
+--ldx]]--
+
+function copy(old,tables)
+ if old then
+ tables = tables or { }
+ local new = { }
+ if not tables[old] then
+ tables[old] = new
+ end
+ for k,v in pairs(old) do
+ new[k] = (type(v) == "table" and (tables[v] or copy(v, tables))) or v
+ end
+ local mt = getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ return new
+ else
+ return { }
+ end
+end
+
+xml.copy = copy
+
+--[[ldx--
+<p>In <l n='context'/> serializing the tree or parts of the tree is a major
+actitivity which is why the following function is pretty optimized resulting
+in a few more lines of code than needed. The variant that uses the formatting
+function for all components is about 15% slower than the concatinating
+alternative.</p>
+--ldx]]--
+
+-- todo: add <?xml version='1.0' standalone='yes'?> when not present
+
+local fallbackhandle = (tex and tex.sprint) or io.write
+
+local function serialize(e, handle, textconverter, attributeconverter, specialconverter, nocommands)
+ if not e then
+ return
+ elseif not nocommands then
+ local ec = e.command
+ if ec ~= nil then -- we can have all kind of types
+ if e.special then
+ local etg, edt = e.tg, e.dt
+ local spc = specialconverter and specialconverter[etg]
+ if spc then
+ local result = spc(edt[1])
+ if result then
+ handle(result)
+ return
+ else
+ -- no need to handle any further
+ end
+ end
+ end
+ local xc = xml.command
+ if xc then
+ xc(e,ec)
+ return
+ end
+ end
+ end
+ handle = handle or fallbackhandle
+ local etg = e.tg
+ if etg then
+ if e.special then
+ local edt = e.dt
+ local spc = specialconverter and specialconverter[etg]
+ if spc then
+ local result = spc(edt[1])
+ if result then
+ handle(result)
+ else
+ -- no need to handle any further
+ end
+ elseif etg == "@pi@" then
+ -- handle(format("<?%s?>",edt[1]))
+ handle("<?" .. edt[1] .. "?>")
+ elseif etg == "@cm@" then
+ -- handle(format("<!--%s-->",edt[1]))
+ handle("<!--" .. edt[1] .. "-->")
+ elseif etg == "@cd@" then
+ -- handle(format("<![CDATA[%s]]>",edt[1]))
+ handle("<![CDATA[" .. edt[1] .. "]]>")
+ elseif etg == "@dt@" then
+ -- handle(format("<!DOCTYPE %s>",edt[1]))
+ handle("<!DOCTYPE " .. edt[1] .. ">")
+ elseif etg == "@rt@" then
+ serialize(edt,handle,textconverter,attributeconverter,specialconverter,nocommands)
+ end
+ else
+ local ens, eat, edt, ern = e.ns, e.at, e.dt, e.rn
+ local ats = eat and next(eat) and { } -- type test maybe faster
+ if ats then
+ if attributeconverter then
+ for k,v in next, eat do
+ ats[#ats+1] = format('%s=%q',k,attributeconverter(v))
+ end
+ else
+ for k,v in next, eat do
+ ats[#ats+1] = format('%s=%q',k,v)
+ end
+ end
+ end
+ if ern and trace_remap and ern ~= ens then
+ ens = ern
+ end
+ if ens ~= "" then
+ if edt and #edt > 0 then
+ if ats then
+ -- handle(format("<%s:%s %s>",ens,etg,concat(ats," ")))
+ handle("<" .. ens .. ":" .. etg .. " " .. concat(ats," ") .. ">")
+ else
+ -- handle(format("<%s:%s>",ens,etg))
+ handle("<" .. ens .. ":" .. etg .. ">")
+ end
+ for i=1,#edt do
+ local e = edt[i]
+ if type(e) == "string" then
+ if textconverter then
+ handle(textconverter(e))
+ else
+ handle(e)
+ end
+ else
+ serialize(e,handle,textconverter,attributeconverter,specialconverter,nocommands)
+ end
+ end
+ -- handle(format("</%s:%s>",ens,etg))
+ handle("</" .. ens .. ":" .. etg .. ">")
+ else
+ if ats then
+ -- handle(format("<%s:%s %s/>",ens,etg,concat(ats," ")))
+ handle("<" .. ens .. ":" .. etg .. " " .. concat(ats," ") .. "/>")
+ else
+ -- handle(format("<%s:%s/>",ens,etg))
+ handle("<" .. ens .. ":" .. etg .. "/>")
+ end
+ end
+ else
+ if edt and #edt > 0 then
+ if ats then
+ -- handle(format("<%s %s>",etg,concat(ats," ")))
+ handle("<" .. etg .. " " .. concat(ats," ") .. ">")
+ else
+ -- handle(format("<%s>",etg))
+ handle("<" .. etg .. ">")
+ end
+ for i=1,#edt do
+ local ei = edt[i]
+ if type(ei) == "string" then
+ if textconverter then
+ handle(textconverter(ei))
+ else
+ handle(ei)
+ end
+ else
+ serialize(ei,handle,textconverter,attributeconverter,specialconverter,nocommands)
+ end
+ end
+ -- handle(format("</%s>",etg))
+ handle("</" .. etg .. ">")
+ else
+ if ats then
+ -- handle(format("<%s %s/>",etg,concat(ats," ")))
+ handle("<" .. etg .. " " .. concat(ats," ") .. "/>")
+ else
+ -- handle(format("<%s/>",etg))
+ handle("<" .. etg .. "/>")
+ end
+ end
+ end
+ end
+ elseif type(e) == "string" then
+ if textconverter then
+ handle(textconverter(e))
+ else
+ handle(e)
+ end
+ else
+ for i=1,#e do
+ local ei = e[i]
+ if type(ei) == "string" then
+ if textconverter then
+ handle(textconverter(ei))
+ else
+ handle(ei)
+ end
+ else
+ serialize(ei,handle,textconverter,attributeconverter,specialconverter,nocommands)
+ end
+ end
+ end
+end
+
+xml.serialize = serialize
+
+function xml.checkbom(root) -- can be made faster
+ if root.ri then
+ local dt, found = root.dt, false
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "table" and v.special and v.tg == "@pi" and find(v.dt,"xml.*version=") then
+ found = true
+ break
+ end
+ end
+ if not found then
+ insert(dt, 1, { special=true, ns="", tg="@pi@", dt = { "xml version='1.0' standalone='yes'"} } )
+ insert(dt, 2, "\n" )
+ end
+ end
+end
+
+--[[ldx--
+<p>At the cost of some 25% runtime overhead you can first convert the tree to a string
+and then handle the lot.</p>
+--ldx]]--
+
+function xml.tostring(root) -- 25% overhead due to collecting
+ if root then
+ if type(root) == 'string' then
+ return root
+ elseif next(root) then -- next is faster than type (and >0 test)
+ local result = { }
+ serialize(root,function(s) result[#result+1] = s end)
+ return concat(result,"")
+ end
+ end
+ return ""
+end
+
+--[[ldx--
+<p>The next function operated on the content only and needs a handle function
+that accepts a string.</p>
+--ldx]]--
+
+function xml.string(e,handle)
+ if not handle or (e.special and e.tg ~= "@rt@") then
+ -- nothing
+ elseif e.tg then
+ local edt = e.dt
+ if edt then
+ for i=1,#edt do
+ xml.string(edt[i],handle)
+ end
+ end
+ else
+ handle(e)
+ end
+end
+
+--[[ldx--
+<p>How you deal with saving data depends on your preferences. For a 40 MB database
+file the timing on a 2.3 Core Duo are as follows (time in seconds):</p>
+
+<lines>
+1.3 : load data from file to string
+6.1 : convert string into tree
+5.3 : saving in file using xmlsave
+6.8 : converting to string using xml.tostring
+3.6 : saving converted string in file
+</lines>
+
+<p>The save function is given below.</p>
+--ldx]]--
+
+function xml.save(root,name)
+ local f = io.open(name,"w")
+ if f then
+ xml.serialize(root,function(s) f:write(s) end)
+ f:close()
+ end
+end
+
+--[[ldx--
+<p>A few helpers:</p>
+--ldx]]--
+
+function xml.body(root)
+ return (root.ri and root.dt[root.ri]) or root
+end
+
+function xml.text(root)
+ return (root and xml.tostring(root)) or ""
+end
+
+function xml.content(root) -- bugged
+ return (root and root.dt and xml.tostring(root.dt)) or ""
+end
+
+function xml.isempty(root, pattern)
+ if pattern == "" or pattern == "*" then
+ pattern = nil
+ end
+ if pattern then
+ -- todo
+ return false
+ else
+ return not root or not root.dt or #root.dt == 0 or root.dt == ""
+ end
+end
+
+--[[ldx--
+<p>The next helper erases an element but keeps the table as it is,
+and since empty strings are not serialized (effectively) it does
+not harm. Copying the table would take more time. Usage:</p>
+
+<typing>
+dt[k] = xml.empty() or xml.empty(dt,k)
+</typing>
+--ldx]]--
+
+function xml.empty(dt,k)
+ if dt and k then
+ dt[k] = ""
+ return dt[k]
+ else
+ return ""
+ end
+end
+
+--[[ldx--
+<p>The next helper assigns a tree (or string). Usage:</p>
+
+<typing>
+dt[k] = xml.assign(root) or xml.assign(dt,k,root)
+</typing>
+--ldx]]--
+
+function xml.assign(dt,k,root)
+ if dt and k then
+ dt[k] = (type(root) == "table" and xml.body(root)) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
+end
diff --git a/tex/context/base/m-arabtex.tex b/tex/context/base/m-arabtex.tex
index af7213387..61e56e93a 100644
--- a/tex/context/base/m-arabtex.tex
+++ b/tex/context/base/m-arabtex.tex
@@ -21,7 +21,7 @@
% ......
% \stoparabic
-\writestatus{loading}{Context Font Macros / ArabTeX support}
+\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
diff --git a/tex/context/base/m-chemic.mkii b/tex/context/base/m-chemic.mkii
new file mode 100644
index 000000000..e6980e1ff
--- /dev/null
+++ b/tex/context/base/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 copyright={PRAGMA / Hans Hagen \& Ton Otten},
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten}]
+%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/base/m-chemic.mkiv b/tex/context/base/m-chemic.mkiv
new file mode 100644
index 000000000..4cc1e3bd8
--- /dev/null
+++ b/tex/context/base/m-chemic.mkiv
@@ -0,0 +1,19 @@
+%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 copyright={PRAGMA / Hans Hagen \& Ton Otten},
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten}]
+%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[pictex] % we will get rid of this
+
+\input ppchtex.mkiv \relax
+
+\endinput
diff --git a/tex/context/base/m-chemic.tex b/tex/context/base/m-chemic.tex
index 25eb62db5..7bacf4a90 100644
--- a/tex/context/base/m-chemic.tex
+++ b/tex/context/base/m-chemic.tex
@@ -12,14 +12,6 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\ifx\directlua\undefined
- \ifx\psaxes\undefined \ifx\beginpicture\undefined
- \usemodule[pictex]
- \fi \fi
-\else
- \usemodule[pictex]
-\fi
-
-\input ppchtex.tex \relax
+\loadmarkfile{m-chemic}
\endinput
diff --git a/tex/context/base/m-database.tex b/tex/context/base/m-database.tex
index 6cb9a6b6c..c4fba132a 100644
--- a/tex/context/base/m-database.tex
+++ b/tex/context/base/m-database.tex
@@ -265,7 +265,7 @@
\fi}
\def\doprocessseparatedline
- {\doifnextcharelse\bgroup\xdoprocessseparatedline\ydoprocessseparatedline}
+ {\doifnextbgroupelse\xdoprocessseparatedline\ydoprocessseparatedline}
\def\dodoprocessseparatedline
{\doprocessseparatedline}
diff --git a/tex/context/base/m-educat.tex b/tex/context/base/m-educat.tex
index 38567bf4e..ddfb72ff4 100644
--- a/tex/context/base/m-educat.tex
+++ b/tex/context/base/m-educat.tex
@@ -18,39 +18,6 @@
\unprotect
-\startvariables dutch english
- german czech
- italian romanian
-
- answerarea: antwoordgebied answerarea
- answerarea answerarea
- answerarea answerarea
-
-\stopvariables
-
-\startelements dutch english
- german czech
- italian romanian
-
- answerspace: antwoordruimte answerspace
- answerspace answerspace
- answerspace answerspace
- answerlines: antwoordregels answerlines
- answerlines answerlines
- answerlines answerlines
-
-\stopelements
-
-\startcommands dutch english
- german czech
- italian romanian
-
- setupanswerarea: stelantwoordgebiedin setupanswerarea
- setupanswerarea setupanswerarea
- setupanswerarea setupanswerarea
-
-\stopcommands
-
\definesystemvariable{iv}
\definecolor [answerareacolor] [s=.90]
diff --git a/tex/context/base/m-gamma.tex b/tex/context/base/m-gamma.tex
deleted file mode 100644
index 05f5d3a42..000000000
--- a/tex/context/base/m-gamma.tex
+++ /dev/null
@@ -1,230 +0,0 @@
-%D \module
-%D [ file=m-gamma,
-%D version=2002.05.15,
-%D title=\CONTEXT\ Extra Modules,
-%D subtitle=Basic \OMEGA\ Support,
-%D author={Idris Samawi Hamid, Hans Hagen},
-%D date=\currentdate,
-%D copyright={PRAGMA-ADE, Idris Samawi Hamid}]
-%D
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-%D Most of this module is written by Idris Samawi Hamid.
-
-%D We define a couple of symbolic \OTP\ filters and
-%D sequences. First the filters:
-%D
-%D Todo: better names, no funny abbreviations.
-
-\definefiltersynonym [utf8 to unicode16] [inutf8]
-\definefiltersynonym [IdOCP] [id]
-\definefiltersynonym [BasicLatinTexUni] [lat2uni]
-\definefiltersynonym [BasicLatinUniToFont][uni2lat]
-\definefiltersynonym [GrTexUni] [grpo2uni]
-\definefiltersynonym [GrUniToFont] [uni2greek]
-\definefiltersynonym [ArabUni] [7arb2uni]
-\definefiltersynonym [BerberUni] [7ber2uni]
-\definefiltersynonym [UrduUni] [7urd2uni]
-\definefiltersynonym [AfghaPashtoUni] [7pas2uni]
-\definefiltersynonym [PakiPashtoUni] [7pap2uni]
-\definefiltersynonym [SindhiUni] [7snd2uni]
-\definefiltersynonym [TifinaghUni] [7tbe2uni]
-\definefiltersynonym [LatinBerberUni] [7lbe2uni]
-\definefiltersynonym [UniCUni] [uni2cuni]
-\definefiltersynonym [CUniArab] [cuni2oar]
-\definefiltersynonym [NoKeshidehCUniArab] [cuni2nar]
-
-%D Next we define the sequences.
-
-\definefiltersequence
- [NilOCP]
- [IdOCP]
-
-\definefiltersequence
- [BasicLatinOCP]
- [BasicLatinTexUni,BasicLatinUniToFont]
-
-\definefiltersequence
- [GreekOCP]
- [GrTexUni,GrUniToFont]
-
-\definefiltersequence
- [ArabicOCP]
- [ArabUni,UniCUni,CUniArab]
-
-\definefiltersequence
- [ArabicNoKeshidehOCP]
- [ArabUni,UniCUni,NoKeshidehCUniArab]
-
-\definefiltersequence
- [ArabicBerberOCP]
- [BerberUni,UniCUni,CUniArab]
-
-\definefiltersequence
- [TifinaghOCP]
- [TifinaghUni,BasicLatinUniToFont]
-
-\definefiltersequence
- [LatinBerberOCP]
- [LatinBerberUni,BasicLatinUniToFont]
-
-\definefiltersequence
- [UrduOCP]
- [UrduUni,UniCUni,CUniArab]
-
-\definefiltersequence
- [UrduNoKeshidehOCP]
- [UrduUni,UniCUni,NoKeshidehCUniArab]
-
-\definefiltersequence
- [AfghaPashtoOCP]
- [AfghaPashtoUni,UniCUni,CUniArab]
-
-\definefiltersequence
- [PakiPashtoOCP]
- [PakiPashtoUni,UniCUni,CUniArab]
-
-\definefiltersequence
- [SindhiOCP]
- [SindhiUni,UniCUni,CUniArab]
-
-%D We wrap a couple of languages in environmen tmacros.
-%D beware: this solution is far from perfect!
-%D
-%D Todo: better interface to directional primitives.
-%D
-%D Todo: proper language support (labels etc).
-
-\definestartstop
- [latin]
- [commands=%
- {\usefiltersequence[BasicLatinOCP]%
- \switchtobodyfont[omlgc]}]
-
-\definestartstop
- [greek]
- [commands=%
- {\usefiltersequence[GreekOCP]%
- \switchtobodyfont[omlgc]%
- \language=3\lefthyphenmin2\righthyphenmin=2}]
-
-\definestartstop
- [arab]
- [commands=%
- {\usefiltersequence[ArabicOCP]
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [smallarab]
- [commands=%
- {\usefiltersequence[ArabicNoKeshidehOCP]
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [latberber]
- [commands=%
- {\usefiltersequence[LatinBerberOCP]
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [tifinagh]
- [commands=%
- {\usefiltersequence[TifinaghOCP]
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [berber]
- [commands=%
- {\usefiltersequence[ArabicBerberOCP]
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [urdu]
- [commands=%
- {\usefiltersequence[UrduOCP]%
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [smallurdu]
- [commands=%
- {\usefiltersequence[UrduNoKeshidehOCP]%
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [pashto]
- [commands=%
- {\usefiltersequence[AfghaPashtoOCP]%
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [pashtop]
- [commands=%
- {\usefiltersequence[PakiPashtoOCP]%
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-\definestartstop
- [sindhi]
- [commands=%
- {\usefiltersequence[SindhiOCP]%
- \switchtobodyfont[omarb]%
- \textdir TRT\pardir TRT}]
-
-
-\let\typeout\message \input grlccode.tex
-
-%D We (pre)define a couple of fonts:
-
-\usetypescriptfile[type-omg]
-
-\usetypescript[OmegaArab]
-\usetypescript[OmegaLGC]
-
-%D Dangerous definitions:
-
-\startencoding[omega]
-
- \definecharacter textbraceleft {^^^^f07b}
- \definecharacter textbraceright {^^^^f07d}
- \definecharacter textbackslash {^^^^f05c}
- \definecharacter textbullet {{\clearocplists\mm\sy\char"0F}}
- \definecharacter dotlessi {^^^^0131}
- \definecharacter ssharp {^^^^00df}
-
-\stopencoding
-
-\enableencoding [omega]
-
-%D Some logo's:
-
-\unexpanded \def\OMEGA {{\switchtobodyfont[omlgc]^^^^03a9}}
-\unexpanded \def\OTP {\OMEGA TP}
-
-%D A few funny definitions:
-
-\def\#{^^^^f023}
-\def\${^^^^f024}
-\def\%{^^^^f025}
-\def\&{^^^^f026}
-
-%D I have no idea what this has to do with omega:
-
-\def\heshe {\lohi{he} {she}}
-\def\himher{\lohi{him}{her}}
-\def\hisher{\lohi{his}{her}}
-
-% Brrr
-
-\setuptolerance [verytolerant]
-
-\endinput
diff --git a/tex/context/base/m-mkii.mkiv b/tex/context/base/m-mkii.mkiv
new file mode 100644
index 000000000..cb0da6fcb
--- /dev/null
+++ b/tex/context/base/m-mkii.mkiv
@@ -0,0 +1,21 @@
+% todo
+
+\unprotect
+
+\writestatus\m!systems{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/base/m-newmat.tex b/tex/context/base/m-newmat.tex
index c36119cd4..08ce33b4c 100644
--- a/tex/context/base/m-newmat.tex
+++ b/tex/context/base/m-newmat.tex
@@ -182,7 +182,7 @@
%D defined in Plain \TEX). It allows to get a math character
%D inserted as if it was a text character.
-\gdef\mathhexbox#1#2#3{\mathtext{$\m@th\mathchar"#1#2#3$}}
+\gdef\mathhexbox#1#2#3{\mathtext{$\mathsurround\zeropoint\mathchar"#1#2#3$}}
%D \macros
%D {boxed}
@@ -299,11 +299,11 @@
\def\simplestartsubarray#1%
{\vcenter\bgroup
- \baselineskip\fontdimen10 \scriptfont\tw@
- \advance\baselineskip\fontdimen12 \scriptfont\tw@
- \lineskip\thr@@\fontdimen8 \scriptfont\thr@@
+ \baselineskip\fontdimen10 \scriptfont\plustwo
+ \advance\baselineskip\fontdimen12 \scriptfont\plustwo
+ \lineskip\plusthree\fontdimen8 \scriptfont\plusthree
\lineskiplimit\lineskip
- \ialign\bgroup\ifx c#1\hfil\fi$\m@th\scriptstyle##$\hfil\crcr}
+ \ialign\bgroup\ifx c#1\hfil\fi$\mathsurround\zeropoint\scriptstyle##$\hfil\crcr}
\def\stopsubarray
{\crcr\egroup
@@ -326,8 +326,8 @@
\baselineskip6\ex@
\lineskip1.5\ex@
\lineskiplimit\lineskip
- \ialign\bgroup\hfil$\m@th\scriptstyle##$\hfil&&\thickspace\hfil
- $\m@th\scriptstyle##$\hfil\crcr}
+ \ialign\bgroup\hfil$\mathsurround\zeropoint\scriptstyle##$\hfil&&\thickspace\hfil
+ $\mathsurround\zeropoint\scriptstyle##$\hfil\crcr}
\def\stopsmallmatrix
{\crcr\egroup
diff --git a/tex/context/base/m-pictex.tex b/tex/context/base/m-pictex.tex
index 90bb7b339..abb81b76e 100644
--- a/tex/context/base/m-pictex.tex
+++ b/tex/context/base/m-pictex.tex
@@ -88,11 +88,14 @@
%D redefinition already took place. We save the original
%D meanings, so we can restores them afterwards.
-\let\normalnewdimen = \newdimen
-\let\normalnewskip = \newskip
+% \def\temporarynewdimen {\alloc@1\dimen\dimendef\insc@unt}
+% \def\temporarynewskip {\alloc@2\skip \skipdef \insc@unt}
-\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
diff --git a/tex/context/base/m-subsub.tex b/tex/context/base/m-subsub.tex
index 3fc71cd50..4395ded8a 100644
--- a/tex/context/base/m-subsub.tex
+++ b/tex/context/base/m-subsub.tex
@@ -12,53 +12,6 @@
\unprotect
-\startvariables dutch english
- german czech
- italian romanian
-
- subsubsubsubsubsection: subsubsubsubsubparagraaf subsubsubsubsubsection
- unterunterunterunterunterabsatz podpodpodpodpodsekce
- sottosottosottosottosottocapoverso subsubsubsubsubsectiune
-
- subsubsubsubsubsubsection: subsubsubsubsubsubparagraaf subsubsubsubsubsubsection
- unterunterunterunterunterunterabsatz podpodpodpodpodpodsekce
- sottosottosottosottosottosottocapoverso subsubsubsubsubsubsectiune
-
- subsubsubsubsubsubsubsection: subsubsubsubsubsubsubparagraaf subsubsubsubsubsubsubsection
- unterunterunterunterunterunterunterabsatz podpodpodpodpodpodpodsekce
- sottosottosottosottosottosottosottocapoverso subsubsubsubsubsubsubsectiune
-
- subsubsubsubsubsubsubsubsection: subsubsubsubsubsubsubsubparagraaf subsubsubsubsubsubsubsubsection
- unterunterunterunterunterunterunterunterabsatz podpodpodpodpodpodpodpodsekce
- sottosottosottosottosottosottosottosottocapoverso subsubsubsubsubsubsubsubsectiune
-
-subsubsubsubsubsubsubsubsubsection: subsubsubsubsubsubsubsubsubparagraaf subsubsubsubsubsubsubsubsubsection
- unterunterunterunterunterunterunterunterunterabsatz podpodpodpodpodpodpodpodpodsekce
- sottosottosottosottosottosottosottosottosottocapoverso subsubsubsubsubsubsubsubsubsectiune
-
- subsubsubsubsubsubject: subsubsubsubsubonderwerp subsubsubsubsubsubject
- unterunterunterunterunterthema podpodpodpodpodtema
- sottosottosottosottosottoargomento subsubsubsubsubsubiect
-
- subsubsubsubsubsubsubject: subsubsubsubsubsubonderwerp subsubsubsubsubsubsubject
- unterunterunterunterunterunterthema podpodpodpodpodpodtema
- sottosottosottosottosottosottoargomento subsubsubsubsubsubsubiect
-
- subsubsubsubsubsubsubsubject: subsubsubsubsubsubsubonderwerp subsubsubsubsubsubsubsubject
- unterunterunterunterunterunterunterthema podpodpodpodpodpodpodtema
- sottosottosottosottosottosottosottoargomento subsubsubsubsubsubsubsubiect
-
- subsubsubsubsubsubsubsubsubject: subsubsubsubsubsubsubsubonderwerp subsubsubsubsubsubsubsubsubject
- unterunterunterunterunterunterunterunterthema podpodpodpodpodpodpodpodtema
- sottosottosottosottosottosottosottosottoargomento subsubsubsubsubsubsubsubsubiect
-
-subsubsubsubsubsubsubsubsubsubject: subsubsubsubsubsubsubsubsubonderwerp subsubsubsubsubsubsubsubsubsubject
- unterunterunterunterunterunterunterunterunterthema podpodpodpodpodpodpodpodpodtema
- sottosottosottosottosottosottosottosottosottoargomento subsubsubsubsubsubsubsubsubsubiect
-
-\stopvariables
-
-
\definesection[\s!section-8]
\definesection[\s!section-9]
\definesection[\s!section-10]
diff --git a/tex/context/base/m-timing.tex b/tex/context/base/m-timing.tex
index 5f543042a..f6b0348c8 100644
--- a/tex/context/base/m-timing.tex
+++ b/tex/context/base/m-timing.tex
@@ -33,185 +33,35 @@
\definecolor[usage:time] [darkblue]
\definecolor[usage:frame][darkgray]
-\startluacode
-do
-
- document = document or { }
- document.progress = document.progress or { }
-
- local defaultfilename = tex.jobname .. "-luatex-progress"
-
- local params = {
- "cs_count",
- "dyn_used",
- "elapsed_time",
- "luabytecode_bytes",
- "luastate_bytes",
- "max_buf_stack",
- "obj_ptr",
- "pdf_mem_ptr",
- "pdf_mem_size",
- "pdf_os_cntr",
- "pool_ptr",
- "str_ptr",
- }
-
- -- storage
-
- local last = os.clock()
- local data = { }
-
- function document.progress.save()
- local f = io.open((name or defaultfilename) .. ".lut","w")
- if f then
- f:write(table.serialize(data,true))
- f:close()
- data = { }
- end
- end
-
- function document.progress.store()
- local c = os.clock()
- local t = {
- elapsed_time = c - last,
- node_memory = tex.node_mem_status(),
- }
- for k, v in pairs(params) do
- if status[v] then t[v] = status[v] end
- end
- data[#data+1] = t
- last = c
- end
-
- -- conversion
+\ctxloadluafile{trac-tim}{}
- local processed = { }
-
- function document.progress.bot(name,tag)
- local d = document.progress.convert(name)
- return d.bot[tag] or 0
- end
- function document.progress.top(name,tag)
- local d = document.progress.convert(name)
- return d.top[tag] or 0
- end
- function document.progress.pages(name,tag)
- local d = document.progress.convert(name)
- return d.pages or 0
- end
- function document.progress.path(name,tag)
- local d = document.progress.convert(name)
- return d.paths[tag] or "origin"
- end
- function document.progress.nodes(name)
- local d = document.progress.convert(name)
- return d.names or { }
- end
- function document.progress.parameters(name)
- local d = document.progress.convert(name)
- return params -- shared
- end
+\startluacode
+local progress = goodies.progress
- function document.progress.convert(name)
- name = ((name ~= "") and name) or defaultfilename
- if not processed[name] then
- local names, top, bot, pages, paths, keys = { }, { }, { }, 0, { }, { }
- local data = io.loaddata(name .. ".lut")
- if data then data = loadstring(data) end
- if data then data = data() end
- if data then
- pages = #data
- if pages > 1 then
- local factor = 100
- for k,v in ipairs(data) do
- for k,v in pairs(v.node_memory) do
- keys[k] = true
- end
- end
- for k,v in ipairs(data) do
- local m = v.node_memory
- for k, _ in pairs(keys) do
- if not m[k] then m[k] = 0 end
- end
- end
- local function path(tag,subtag)
- local b, t, s = nil, nil, { }
- for k,v in ipairs(data) do
- local v = (subtag and v[tag][subtag]) or v[tag]
- if v then
- v = tonumber(v)
- if b then
- if v > t then t = v end
- if v < b then b = v end
- else
- t = v
- b = v
- end
- s[k] = v
- else
- s[k] = 0
- end
- end
- local tagname = subtag or tag
- top[tagname] = (string.format("%.3f",t)):gsub("%.000$","")
- bot[tagname] = (string.format("%.3f",b)):gsub("%.000$","")
- local delta = t-b
- if delta == 0 then
- delta = 1
- else
- delta = factor/delta
- end
- for k, v in ipairs(s) do
- s[k] = "(" .. k .. "," .. (v-b)*delta .. ")"
- end
- paths[tagname] = table.concat(s,"--")
- end
- for _, tag in pairs(params) do
- path(tag)
- end
- for tag, _ in pairs(keys) do
- path("node_memory",tag)
- names[#names+1] = tag
- end
- pages = pages - 1
- end
- end
- table.sort(names)
- processed[name] = {
- names = names,
- top = top,
- bot = bot,
- pages = pages,
- paths = paths,
- }
- end
- return processed[name]
+function progress.show(filename,parameters,nodes,other)
+ for n, name in pairs(parameters or progress.parameters(filename)) do
+ tex.sprint(tex.ctxcatcodes,string.format("\\ShowNamedUsage{%s}{%s}{%s}",filename or progress.defaultfilename,name,other or ""))
end
-
- function document.progress.show(filename,parameters,nodes,other)
- for n, name in pairs(parameters or document.progress.parameters(filename)) do
- tex.sprint(tex.ctxcatcodes,string.format("\\ShowNamedUsage{%s}{%s}{%s}",filename or defaultfilename,name,other or ""))
- end
- for n, name in pairs(nodes or document.progress.nodes(filename)) do
- tex.sprint(tex.ctxcatcodes,string.format("\\ShowNamedUsage{%s}{%s}{%s}",filename or defaultfilename,name,other or ""))
- end
+ for n, name in pairs(nodes or progress.nodes(filename)) do
+ tex.sprint(tex.ctxcatcodes,string.format("\\ShowNamedUsage{%s}{%s}{%s}",filename or progress.defaultfilename,name,other or ""))
end
-
end
\stopluacode
% \everyfirstshipout
-\appendtoks\ctxlua{document.progress.store()}\to\everystarttext
-\appendtoks\ctxlua{document.progress.store()}\to\everyshipout
-
-\ctxlua{table.insert(input.stop_actions, function() document.progress.save() end)}
+\startnotmode[no-timing]
+ \appendtoks\ctxlua{goodies.progress.store()}\to\everystarttext
+ \appendtoks\ctxlua{goodies.progress.store()}\to\everyshipout
+ \ctxlua{main.register_stop_actions(function() goodies.progress.save() end)}
+\stopnotmode
\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 := \ctxlua{tex.sprint(document.progress.path("#1","#2"))} ;
+ p := \ctxlua{tex.sprint(goodies.progress.path("#1","#2"))} ;
+% p := p shifted -llcorner p ;
if bbwidth(p) > 1 :
h := 100 ; w := 2 * h ;
w := \the\textwidth-3pt ; % correct for pen
@@ -221,7 +71,8 @@ end
draw b withcolor \MPcolor{usage:frame} ;
draw p withcolor \MPcolor{usage:line} ;
if ("#3" <> "") and ("#3" <> "#2") :
- q := \ctxlua{tex.sprint(document.progress.path("#1","#3"))} ;
+ q := \ctxlua{tex.sprint(goodies.progress.path("#1","#3"))} ;
+% q := q shifted -llcorner q ;
if bbwidth(q) > 1 :
q := q xstretched w ;
pickup pencircle scaled 1.5pt ; linecap := butt ;
@@ -236,16 +87,16 @@ end
\startlinecorrection
\box\scratchbox \endgraf
\hbox to \scratchdimen{\tttf\strut\detokenize{#2}\hss
- min:\ctxlua{tex.sprint(document.progress.bot("#1","\detokenize{#2}"))}, %
- max:\ctxlua{tex.sprint(document.progress.top("#1","\detokenize{#2}"))}, %
- pages:\ctxlua{tex.sprint(document.progress.pages("#1"))}%
+ min:\ctxlua{tex.sprint(goodies.progress.bot("#1","\detokenize{#2}"))}, %
+ max:\ctxlua{tex.sprint(goodies.progress.top("#1","\detokenize{#2}"))}, %
+ pages:\ctxlua{tex.sprint(goodies.progress.pages("#1"))}%
}%
\stoplinecorrection
\fi}
-\def\LoadUsage #1{\ctxlua{document.progress.convert("#1")}}
-\def\ShowUsage #1{\ctxlua{document.progress.show("#1",nil,nil,"elapsed_time")}}
-\def\ShowMemoryUsage#1{\ctxlua{document.progress.show("#1",nil,{}, "elapsed_time")}}
-\def\ShowNodeUsage #1{\ctxlua{document.progress.show("#1",{},nil, "elapsed_time")}}
+\def\LoadUsage #1{\ctxlua{goodies.progress.convert("#1")}}
+\def\ShowUsage #1{\ctxlua{goodies.progress.show("#1",nil,nil,"elapsed_time")}}
+\def\ShowMemoryUsage#1{\ctxlua{goodies.progress.show("#1",nil,{}, "elapsed_time")}}
+\def\ShowNodeUsage #1{\ctxlua{goodies.progress.show("#1",{},nil, "elapsed_time")}}
\endinput
diff --git a/tex/context/base/m-track.tex b/tex/context/base/m-track.tex
new file mode 100644
index 000000000..cfcbbabff
--- /dev/null
+++ b/tex/context/base/m-track.tex
@@ -0,0 +1,5 @@
+\doifnotmode{mkiv} {\endinput}
+
+\starttext
+ \showtrackers
+\stoptext
diff --git a/tex/context/base/m-translate.tex b/tex/context/base/m-translate.tex
index a11eef4bc..a9601bdd5 100644
--- a/tex/context/base/m-translate.tex
+++ b/tex/context/base/m-translate.tex
@@ -44,14 +44,14 @@
end
function translators.reset(s)
- input.filters.user_translator = nil
+ resolvers.filters.user_translator = nil
list, compiled = nil, nil
end
function translators.enable(s)
- input.filters.user_translator = translators.translate
+ resolvers.filters.user_translator = translators.translate
end
function translators.disable(s)
- input.filters.user_translator = nil
+ resolvers.filters.user_translator = nil
end
\stopluacode
diff --git a/tex/context/base/m-visual.tex b/tex/context/base/m-visual.tex
index c35e8a1a4..2be669d19 100644
--- a/tex/context/base/m-visual.tex
+++ b/tex/context/base/m-visual.tex
@@ -272,7 +272,6 @@
#2{#3}}
\let\normalPDFcode\PDFcode
-\let\normalspecial\special
\def\showlowlevelstream
{\def\PDFcode{\lowlevelstream\PDFcode\normalPDFcode}%
diff --git a/tex/context/base/math-ali.mkiv b/tex/context/base/math-ali.mkiv
new file mode 100644
index 000000000..f98eb11df
--- /dev/null
+++ b/tex/context/base/math-ali.mkiv
@@ -0,0 +1,1059 @@
+%D \module
+%D [ file=math-ali,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Math Alignments,
+%D author={Hans Hagen, Taco Hoekwater \& Aditya Mahajan},
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Math Macros / Math Alignments}
+
+\unprotect
+
+%D The code here has been moved from other files. Beware: the \MKII\ and
+%D \MKIV\ code is not gathered in files with the same name.
+
+%D \macros
+%D {\definemathalignment, setupmathalignment, startmathalignment}
+%D
+%D Modules may provide additional alignment features. The following
+%D mechanisms are provided by the core.
+
+% n>1 #### needed, strange # interaction in recurse
+
+\def\presetdisplaymath{\displ@y} % some day i will relocate the plain stuff
+
+\def\buildeqalign
+ {\scratchtoks\emptytoks
+ \dorecurse{\mathalignmentparameter\c!m}
+ {\ifnum\recurselevel>\plusone
+ \appendtoks
+ \tabskip\mathalignmentparameter\c!distance&\tabskip\zeropoint
+ \to\scratchtoks
+ \fi
+ \normalexpanded{\scratchtoks{\the\scratchtoks\the\!!toksa}}%
+ \dorecurse{\numexpr\mathalignmentparameter\c!n-\plusone\relax}
+ {\normalexpanded{\scratchtoks{\the\scratchtoks\the\!!toksb}}}}%
+ \normalexpanded{\scratchtoks{\the\scratchtoks\the\!!toksc}}}
+
+\def\forgetalign
+ {\tabskip\zeropoint\everycr\emptytoks}
+
+\let\firstineqalign\empty
+\let\nextineqalign \empty
+\let\leftofeqalign \empty
+\let\rightofeqalign\empty
+
+\def\mathineqalign#1{$\forgetalign\displaystyle{{}#1{}}$}
+\def\textineqalign#1{$\forgetalign#1$}
+
+\def\eqalign#1% why no halign here, probably because of displaywidth
+ {\null\,\vcenter
+ {\openup.25\bodyfontsize% was: \openup\jot
+ \mathsurround\zeropoint
+ \ialign{\strut\hfil$\displaystyle{##}$&$\displaystyle{{}##{}}$\hfil\crcr#1\crcr}%
+ }\,}
+
+% preamble is scanned for tabskips so we need the span to prevent an error message
+
+\chardef\eqalignmode\plusone
+
+\def\preparereqalignno
+ {\!!toksa{\strut\firstineqalign\hfil\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}%
+ \!!toksb{&\nextineqalign\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}%
+ \ifnum\mathraggedstatus=\plusone
+ \!!toksc{\hfil&\span\textineqalign{##}\tabskip\zeropoint}%
+ \else\ifnum\mathraggedstatus=\plusthree
+ \!!toksc{\hfil\tabskip\zeropoint\!!plus 1\!!fill&\span\textineqalign{##}\tabskip\zeropoint}%
+ \else
+ \!!toksc{\hfil\tabskip\centering&\llap{\span\textineqalign{##}}\tabskip\zeropoint}%
+ \fi\fi
+ \global\chardef\mathnumberstatus\zerocount
+ \buildeqalign
+ \presetdisplaymath
+ \tabskip\centering}
+
+\def\prepareleqalignno
+ {\!!toksa{\strut\firstineqalign\hfil\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}%
+ \!!toksb{&\nextineqalign\leftofeqalign\span\mathineqalign{##}\rightofeqalign\tabskip\zeropoint}%
+ % problem: number is handled after rest and so ends up in the margin
+ \ifnum\mathraggedstatus=\plusone
+ \!!toksc{\hfil&\kern-\displaywidth\rlap{\span\textineqalign{##}}\tabskip\displaywidth}%
+ \else\ifnum\mathraggedstatus=\plusthree
+ \!!toksc{\hfil\tabskip\zeropoint\!!plus 1\!!fill&\kern-\displaywidth\span\mrlap{\span\textineqalign{##}}\tabskip\displaywidth}%
+ \else
+ \!!toksc{\hfil\tabskip\centering&\kern-\displaywidth\rlap{\span\textineqalign{##}}\tabskip\displaywidth}%
+ \fi\fi
+ \global\chardef\mathnumberstatus\zerocount
+ \buildeqalign
+ \presetdisplaymath
+ \tabskip\centering}
+
+\def\dobotheqalignno#1#2%
+ {\ifmmode
+ \displ@y % \let\doplaceformulanumber\relax % strange hack
+ \vcenter\bgroup
+ \let\finishalignno\egroup
+ \else
+ \let\finishalignno\relax
+ \fi
+ #1%
+ \halign \ifcase\eqalignmode \or to \displaywidth \fi \@EA {\the\scratchtoks\crcr#2\crcr}%
+ \finishalignno}
+
+\def\dobothaligneqalignno#1%
+ {\ifmmode
+ \displ@y
+ \global\chardef\mathnumberstatus\plusone
+ \ifcase\mathraggedstatus
+ \def\finishalignno{\crcr\egroup}%
+ \else
+ % we're in a mathbox
+ \vcenter\bgroup
+ \def\finishalignno{\crcr\egroup\egroup}%
+ \fi
+ \fi
+ #1%
+ \halign \ifcase\eqalignmode \or to \displaywidth \fi \@EA \bgroup\the\scratchtoks\crcr}
+
+\def\mrlap#1%
+ {\setbox\scratchbox\hbox{#1}%
+ \ifdim\wd\scratchbox>\mathnumbercorrection
+ \xdef\mathnumbercorrection{\the\wd\scratchbox}%
+ \fi
+ \box\scratchbox
+ \global\chardef\mathnumberstatus\plustwo}
+
+% \def\dobothaligneqalignno#1%
+% {\ifmmode
+% \displ@y
+% \global\chardef\mathnumberstatus\plusone
+% we're in a mathbox
+% \vcenter\bgroup
+% \def\finishalignno{\crcr\egroup\egroup}%
+% \else
+% \def\finishalignno{\crcr\egroup}%
+% \fi
+% #1%
+% \halign \ifcase\eqalignmode \or to \displaywidth \fi \@EA \bgroup\the\scratchtoks\crcr}
+
+\def\reqalignno {\dobotheqalignno \preparereqalignno}
+\def\leqalignno {\dobotheqalignno \prepareleqalignno}
+\def\alignreqalignno{\dobothaligneqalignno\preparereqalignno}
+\def\alignleqalignno{\dobothaligneqalignno\prepareleqalignno}
+\def\finishalignno {\crcr\egroup}
+
+\let \equalignno \reqalignno
+\let\aligneqalignno\alignreqalignno
+
+%D Here we implement the user interface part.
+
+\def\setupmathalignment
+ {\dodoubleempty\dosetupmathalignment}
+
+\def\dosetupmathalignment[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??eq#1][#2]%
+ \else
+ \getparameters[\??eq][#1]%
+ \fi}
+
+\let\currentmathalignment\empty
+
+\def\mathalignmentparameter#1%
+ {\executeifdefined{\??eq\currentmathalignment#1}{\executeifdefined{\??eq#1}\empty}}
+
+\setupmathalignment
+ [\c!n=2,
+ \c!m=1,
+ \c!distance=1em]
+
+\def\numberedeqalign
+ {\doifelse{\formulaparameter\c!location}\v!left\alignleqalignno\alignreqalignno}
+
+\def\doxxdoubleempty#1#2%
+ {\ifx#2[\expandafter\dodoxxdoubleempty\else\expandafter\noxxdoubleempty\fi#1#2}
+
+\def\dodoxxdoubleempty#1[#2]#3%
+ {\ifx#3[\else\expandafter\nonoxxdoubleempty\fi#1[#2]#3}
+
+\def\noxxdoubleempty #1{#1[][]}
+\def\nonoxxdoubleempty#1[#2]{#1[#2][]}
+
+\newcount\eqaligncolumn
+
+\def\firstineqalign{\global\eqaligncolumn\plusone}
+\def\nextineqalign {\global\advance\eqaligncolumn\plusone}
+\def\leftofeqalign {\getvalue{\??eq:\v!left :\number\eqaligncolumn}}
+\def\rightofeqalign{\getvalue{\??eq:\v!right:\number\eqaligncolumn}}
+
+\def\doseteqaligncolumn#1%
+ {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\empty
+ \letvalue{\??eq:\v!right:\number\eqaligncolumn}\empty
+ \doif{#1}\v!left {\letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfill}%
+ \doif{#1}\v!right {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfill}%
+ \doif{#1}\v!middle{\letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfill
+ \letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfill}}
+
+\def\dodoalignNC
+ {\gdef\doalignNC##1{&##1}}
+
+\def\doalignNR[#1][#2]%
+ {\donestedformulanumber{#1}{#2}\crcr}
+
+%D \starttyping
+%D \placeformula[eqn0]\startformula \startalign[n=1] a\NR \stopalign \stopformula See \in[eqn0]
+%D \placeformula[eqn1]\startformula \startalign[n=1] a\NR \stopalign \stopformula See \in[eqn1]
+%D \placeformula \startformula \startalign[n=1] a\NR[eqn2] \stopalign \stopformula See \in[eqn2]
+%D \placeformula[eqn3]\startformula \startalign[n=1] a\NR[+] \stopalign \stopformula See \in[eqn3]
+%D \stoptyping
+
+% todo: pop in cell
+
+\def\dostartmathalignment[#1][#2]%
+ {% \begingroup not permitted ($$...assignments...\halign... )
+ \pushmacro\doalignNC
+ \edef\currentmathalignment{#1}%
+ \doifassignmentelse{#2}{\setupmathalignment[#1][#2]}\donothing
+ \def\NC{\doalignNC}%
+ \global\let\doalignNC\dodoalignNC
+ \def\EQ{&=}%
+ \def\NR{&\global\let\doalignNC\dodoalignNC\doxxdoubleempty\doalignNR}%
+ % amstex compatibility mode: (ugly, will disappear)
+ \def\notag{\def\\{&\crcr}}%
+ \doifelse{#2}{*}{\def\\{&\crcr}}{\def\\{&\doalignNR[+][]\crcr}}%
+ % end of compatibility mode
+ \eqaligncolumn\zerocount
+ \processcommacommand
+ [\mathalignmentparameter\c!align]
+ {\advance\eqaligncolumn\plusone\doseteqaligncolumn}% takes argument
+ % the real action
+ \global\eqaligncolumn\plusone
+ \numberedeqalign}
+
+\def\dostopmathalignment
+ {\finishalignno
+ \popmacro\doalignNC}
+
+\def\definemathalignment
+ {\dodoubleempty\dodefinemathalignment}
+
+\def\dodefinemathalignment[#1]% [#2]%
+ {\setvalue{\e!start#1}{\dodoubleempty\dostartmathalignment[#1]}%
+ \setvalue{\e!stop #1}{\dostopmathalignment}%
+ \setupmathalignment[#1]}% [#2]
+
+%D For the moment we only provide english commands.
+
+\definemathalignment[align] % default case (this is what amstex users expect)
+\definemathalignment[\v!mathalignment] % prefered case (this is cleaner, less clashing)
+
+%D \startbuffer
+%D \placeformula \startformula \eqalignno {
+%D a &= b & \formulanumber \cr
+%D c &= d \cr
+%D &= e \cr
+%D &= f & \formulanumber
+%D } \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign
+%D \NC a \EQ b \NR[+]
+%D \NC c \EQ d \NR
+%D \NC \EQ f \NR[for:demo-a-1]
+%D \NC \EQ g \NR[for:demo-a-2][a]
+%D \NC \EQ h \NR[for:demo-a-3][b]
+%D \NC \EQ i \NR
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign
+%D \NC a \EQ b \NR[+]
+%D \NC c \EQ d \NR
+%D \NC \EQ f \NR
+%D \NC \EQ g \NR
+%D \NC \EQ h \NR
+%D \NC \EQ i \NR[+]
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign
+%D a &= b \\
+%D c &= d \notag \\
+%D &= e \notag \\
+%D &= f \\
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign
+%D \NC a \NC \eq b \NR[+]
+%D \NC c \NC \neq d \NR
+%D \NC \NC \neq f \NR[for:demo-b-1]
+%D \NC \NC \geq g \NR[for:demo-b-2][a]
+%D \NC \NC \leq h \NR[for:demo-b-3][b]
+%D \NC \NC \neq i \NR
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[*]
+%D a &= b \\
+%D c &= d \\
+%D &= e \\
+%D &= f \\
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign
+%D x &= y \\
+%D a &= b \\
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[m=3]
+%D x &= y & x &= y & z &= t \\
+%D a &= b & p &= q & w &= s \\
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[m=3,distance=0pt]
+%D x &= y &= x &= y &= z &= t \\
+%D a &= b &= p &= q &= w &= s \\
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[n=5,distance=0pt]
+%D x &= yy &= xx &= yy &= zz \\
+%D a &= b &= p &= q &= w \\
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[n=3,align={left,middle,right}]
+%D \NC l \NC = \NC r \NR
+%D \NC left \NC = \NC right \NR
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[n=3,align={right,middle,left}]
+%D \NC l \NC = \NC r \NR
+%D \NC left \NC = \NC right \NR
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startalign[n=3,align={middle,middle,middle}]
+%D \NC l \NC = \NC r \NR
+%D \NC left \NC = \NC right \NR
+%D \stopalign \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula
+%D \startformula
+%D \startalign[n=3,align={middle,middle,middle}]
+%D \NC a \NC = \NC b \NR[+]
+%D \NC 2a \NC = \NC 2b \NR
+%D \stopalign
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula
+%D \startformulas
+%D \setupmathalignment[n=3,align={middle,middle,middle}]%
+%D \startformula
+%D \startalign
+%D \NC a \NC = \NC b \NR[+]
+%D \NC 2a \NC = \NC 2b \NR
+%D \stopalign
+%D \stopformula
+%D \startformula
+%D \startalign
+%D \NC a \NC = \NC b \NR[+]
+%D \NC 2a \NC = \NC 2b \NR
+%D \stopalign
+%D \stopformula
+%D \stopformulas
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula
+%D \startformulas
+%D \dorecurse{5}{\startformula
+%D \startalign[n=3,align={middle,middle,middle}]
+%D \NC a \NC = \NC b \NR[+]
+%D \NC 2a \NC = \NC 2b \NR
+%D \stopalign
+%D \stopformula}
+%D \stopformulas
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {definemathcases, setupmathcases, startmathcases}
+%D
+%D Another wish \unknown
+
+\def\setupmathcases
+ {\dodoubleempty\dosetupmathcases}
+
+\def\dosetupmathcases[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??ce#1][#2]%
+ \else
+ \getparameters[\??ce][#1]%
+ \fi}
+
+\let\currentmathcases\empty
+
+\def\mathcasesparameter#1%
+ {\executeifdefined{\??ce\currentmathcases#1}{\executeifdefined{\??ce#1}\empty}}
+
+\setupmathcases
+ [\c!distance=1em,
+ \c!numberdistance=2.5em,
+ \c!left={\left\{\,},
+ \c!right={\right.}]
+
+\def\dodocasesNC
+ {\gdef\docasesNC{\endmath&}}
+
+\let\docasesNR\doalignNR
+
+\def\dostartmathcases[#1][#2]%
+ {\begingroup
+ \edef\currentmathcases{#1}%
+ \doifassignmentelse{#2}{\setupmathcases[#1][#2]}\donothing
+ \mathcasesparameter\c!left
+ \vcenter\bgroup
+ \pushmacro\docasesNC
+ \let\endmath\relax
+ \def\NC{\docasesNC}%
+ \def\MC{\docasesNC\ifmmode\else$\def\endmath{$}\fi}%
+ \global\let\docasesNC\dodocasesNC
+ \def\NR{\unskip\endmath&\global\let\docasesNC\dodocasesNC\doxxdoubleempty\docasesNR}%
+ \normalbaselines
+ \mathsurround\zeropoint
+ \everycr\emptytoks
+ \tabskip\zeropoint
+ \global\eqaligncolumn\plusone
+ \halign\bgroup
+ $\mathcasesparameter\c!style##$\hfil
+ &\hskip\mathcasesparameter\c!distance\relax
+ \popmacro\docasesNC##\hfil
+ &\hskip\mathcasesparameter\c!numberdistance\relax
+ \let\formuladistance\!!zeropoint
+ \span\textineqalign{##}%
+ \crcr} % todo: number
+
+\def\dostopmathcases
+ {\crcr
+ \egroup
+ \popmacro\docasesNC
+ \egroup
+ \mathcasesparameter\c!right
+ \endgroup}
+
+\def\definemathcases
+ {\dodoubleempty\dodefinemathcases}
+
+\def\dodefinemathcases[#1]% [#2]%
+ {\setvalue{\e!start#1}{\dodoubleempty\dostartmathcases[#1]}%
+ \setvalue{\e!stop #1}{\dostopmathcases}%
+ \setupmathcases[#1]}% [#2]
+
+\definemathcases[cases]
+\definemathcases[\v!mathcases]
+
+%D \startbuffer
+%D \placeformula \startformula \startcases
+%D \NC 2 \NC $ y > 0 $ \NR
+%D \NC 7 \NC $ x = 7 $ \NR[+]
+%D \NC 4 \NC otherwise \NR
+%D \stopcases \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula x \startcases
+%D \NC 2 \NC $ y > 0 $ \NR[+]
+%D \NC 7 \NC $ x = 7 $ \NR
+%D \NC 4 \NC otherwise \NR
+%D \stopcases \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula \startcases
+%D \NC 2 \NC $ y > 0 $ \NR
+%D \NC 7 \NC $ x = 7 $ \NR
+%D \NC 4 \NC otherwise \NR
+%D \stopcases \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \placeformula \startformula x \startcases
+%D \NC 2 \NC $ y > 0 $ \NR
+%D \NC 7 \NC $ x = 7 $ \NR
+%D \NC 4 \NC otherwise \NR
+%D \stopcases \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {definemathmatrix, setupmathmatrix, startmathmatrix}
+%D
+%D Yet another one \unknown
+
+\def\setupmathmatrix
+ {\dodoubleempty\dosetupmathmatrix}
+
+\def\dosetupmathmatrix[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??mx#1][#2]%
+ \else
+ \getparameters[\??mx][#1]%
+ \fi}
+
+\let\currentmathmatrix\empty
+
+\def\mathmatrixparameter#1%
+ {\executeifdefined{\??mx\currentmathmatrix#1}{\executeifdefined{\??mx#1}\empty}}
+
+\setupmathmatrix
+ [\c!distance=1em,
+ \c!left=,
+ \c!right=,
+ \c!align=\v!middle]
+
+\def\dosetmatrixcolumn#1% hh: todo: \definematrixalign
+ {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfil
+ \letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfil
+ \doif{#1}\v!left {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\relax
+ \letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfil}%
+ \doif{#1}\v!right {\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfil
+ \letvalue{\??eq:\v!right:\number\eqaligncolumn}\relax }%
+ \doif{#1}\v!middle{\letvalue{\??eq:\v!left :\number\eqaligncolumn}\hfil
+ \letvalue{\??eq:\v!right:\number\eqaligncolumn}\hfil}}
+
+\def\buildmathmatrix % beware: etex only
+ {\scratchtoks\emptytoks
+ \normalexpanded{\scratchtoks{\the\scratchtoks\the\!!toksa}}%
+ \dorecurse{\numexpr\scratchcounter-\plusone\relax}
+ {\normalexpanded{\scratchtoks{\the\scratchtoks\the\!!toksb}}}%
+ \normalexpanded{\scratchtoks{\the\scratchtoks\the\!!toksc }}}
+
+\def\preparemathmatrix
+ {\!!toksa{\strut \firstineqalign\leftofeqalign \span
+ \textineqalign{\mathmatrixparameter\c!style ##}\rightofeqalign}%
+ \!!toksb{&\hskip\mathmatrixparameter\c!distance
+ \nextineqalign\leftofeqalign \span
+ \textineqalign{\mathmatrixparameter\c!style ##}\rightofeqalign}%
+ \!!toksc{&&\hskip\mathmatrixparameter\c!distance
+ \leftofeqalign \span
+ \textineqalign{\mathmatrixparameter\c!style ##}\rightofeqalign}%
+ \buildmathmatrix
+ \halign \@EA \bgroup\the\scratchtoks \crcr}
+
+\def\definemathmatrix
+ {\dodoubleempty\dodefinemathmatrix}
+
+\def\dodefinemathmatrix[#1]% [#2]%
+ {\setvalue{\e!start#1}{\dodoubleempty\dostartmathmatrix[#1]}%
+ \setvalue{\e!stop #1}{\dostopmathmatrix}%
+ \setupmathmatrix[#1]}% [#2]
+
+\definemathmatrix[matrix]
+\definemathmatrix[\v!mathmatrix]
+
+\def\dodomatrixNC
+ {\gdef\domatrixNC{\endmath&}}
+
+\def\installmathmatrixhandler#1#2%
+ {\setvalue{\??mx:#1}{#2}}
+
+% First alternative:
+%
+% \def\processlowhighmathmatrix#1%
+% {\def\mathmatrixleft
+% {\setbox\nextbox}
+% \def\mathmatrixright
+% {#1.5\dimexpr\nextboxdp-\nextboxht\relax
+% \hbox{$\mathmatrixparameter\c!left
+% \vcenter{\unvbox\nextbox}%
+% \mathmatrixparameter\c!right$}}%
+% \let\mathmatrixbox\vbox}
+%
+% \installmathmatrixhandler\v!high {\processlowhighmathmatrix\raise}
+% \installmathmatrixhandler\v!low {\processlowhighmathmatrix\lower}
+%
+% \installmathmatrixhandler\v!top {\processlowhighmathmatrix\raise}
+% \installmathmatrixhandler\v!bottom{\processlowhighmathmatrix\lower}
+%
+% \installmathmatrixhandler\v!lohi
+% {\def\mathmatrixleft {\mathmatrixparameter\c!left}%
+% \def\mathmatrixright{\mathmatrixparameter\c!right}%
+% \let\mathmatrixbox\vcenter}
+%
+% An alternative
+%
+% \let\mathmatrixleft \empty
+% \let\mathmatrixright\empty
+%
+% \def\processlowhighmathmatrix#1%
+% {\dowithnextbox
+% {#1.5\dimexpr\nextboxdp-\nextboxht\relax
+% \hbox{$\mathmatrixparameter\c!left
+% \vcenter{\unvbox\nextbox}%
+% \mathmatrixparameter\c!right$}}%
+% \vbox}
+%
+% \def\processlohimathmatrix
+% {\dowithnextbox
+% {\mathmatrixparameter\c!left
+% \vcenter{\unvbox\nextbox}%
+% \mathmatrixparameter\c!right}%
+% \vbox}
+%
+% \installmathmatrixhandler\v!high {\def\mathmatrixbox{\processlowhighmathmatrix\raise}}
+% \installmathmatrixhandler\v!low {\def\mathmatrixbox{\processlowhighmathmatrix\lower}}
+% \installmathmatrixhandler\v!top {\def\mathmatrixbox{\processlowhighmathmatrix\raise}}
+% \installmathmatrixhandler\v!bottom{\def\mathmatrixbox{\processlowhighmathmatrix\lower}}
+% \installmathmatrixhandler\v!lohi {\let\mathmatrixbox \processlohimathmatrix}
+%
+% Final version
+
+\let\mathmatrixleft \empty % experimental hook
+\let\mathmatrixright\empty % experimental hook
+
+\def\processlowhighmathmatrix#1#2%
+ {\dowithnextbox
+ {\scratchdimen\dimexpr(\nextboxdp-\nextboxht)/2 \ifcase#2\or+\mathaxisheight\textfont2\fi\relax
+ \ifcase#1\relax\or\lower\scratchdimen\or\or\raise\scratchdimen\fi
+ \hbox{$\mathmatrixparameter\c!left
+ \vcenter{\unvbox\nextbox}%
+ \mathmatrixparameter\c!right$}}%
+ \vbox}
+
+\installmathmatrixhandler\v!top {\def\mathmatrixbox{\processlowhighmathmatrix\plusthree\plusone }}
+\installmathmatrixhandler\v!high {\def\mathmatrixbox{\processlowhighmathmatrix\plusthree\zerocount}}
+\installmathmatrixhandler\v!lohi {\def\mathmatrixbox{\processlowhighmathmatrix\plustwo \zerocount}}
+\installmathmatrixhandler\v!low {\def\mathmatrixbox{\processlowhighmathmatrix\plusone \zerocount}}
+\installmathmatrixhandler\v!bottom{\def\mathmatrixbox{\processlowhighmathmatrix\plusone \plusone }}
+
+\def\dostartmathmatrix[#1][#2]%
+ {\begingroup
+ \edef\currentmathmatrix{#1}%
+ \doifassignmentelse{#2}{\setupmathmatrix[#1][#2]}\donothing
+ \null
+ \executeifdefined{\??mx:\mathmatrixparameter\c!location}{\getvalue{\??mx:\v!lohi}}%
+ \mathmatrixleft
+ \mathmatrixbox\bgroup
+ \pushmacro\domatrixNC
+ \let\endmath\relax
+ \def\NC{\domatrixNC}%
+ \def\MC{\domatrixNC\ifmmode\else$\def\endmath{$}\fi}%
+ \global\let\domatrixNC\dodomatrixNC
+ \def\NR{\endmath\global\let\domatrixNC\dodomatrixNC\crcr}%
+ \normalbaselines
+ \mathsurround\zeropoint
+ \everycr\emptytoks
+ \tabskip\zeropoint
+ \eqaligncolumn\zerocount % could be \scratchcounter
+ \processcommacommand[\mathmatrixparameter\c!align]{\advance\eqaligncolumn\plusone\dosetmatrixcolumn}%
+ \scratchcounter=\ifnum\eqaligncolumn>\zerocount \eqaligncolumn \else \plusone \fi
+ \global\eqaligncolumn\plusone
+ \preparemathmatrix } % uses scratchcounter
+
+\def\dostopmathmatrix
+ {\crcr
+ \mathstrut\crcr
+ \noalign{\kern-\baselineskip}%
+ \egroup
+ \popmacro\domatrixNC
+ \egroup
+ \mathmatrixright
+ \endgroup}
+
+%D \startbuffer
+%D \placeformula \startformula[-] \startmatrix
+%D \NC 1 \NC x \NC a \NR
+%D \NC 2 \NC y \NC b \NR
+%D \NC 3 \NC z \NC c \NR
+%D \stopmatrix \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \definemathmatrix[bmatrix][left={\left[\,},right={\,\right]}]
+%D
+%D \startbuffer
+%D \placeformula \startformula[-] \startbmatrix
+%D \NC 1 \NC x \NC a \NR
+%D \NC 2 \NC y \NC b \NR
+%D \NC 3 \NC z \NC c \NR
+%D \stopbmatrix \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D Taco added some code (dedicated to Aditya Mahajan) that gives more
+%D control over aligments:
+
+%D \startbuffer
+%D \startformula
+%D \startmatrix
+%D \NC a + x \NC = \NC a + d \NR
+%D \NC y \NC = \NC d \NR
+%D \stopmatrix
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \startbuffer
+%D \startformula
+%D \startmatrix [distance=3pt,align={right,left}]
+%D \NC a + x \NC = a + d \NR
+%D \NC y \NC = d \NR
+%D \stopmatrix
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \startbuffer
+%D \startformula
+%D \startmatrix [left=\left(,right=\right)]
+%D \NC a + x \NR
+%D \NC y \NR
+%D \stopmatrix
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D A bit more complex code:
+%D
+%D \startbuffer
+%D \startformula
+%D \text{Let }{\cal R} = \bigcup_{P_{X_1},P_{X_2}}
+%D \left\{ (R_1, R_2) :
+%D \startmatrix[distance=1em,align={left,left,right}]
+%D \NC R_1 \NC < I(X_1 ; Y \mid X_2) \NC R_1 \NR
+%D \NC \hfill Q_2 \NC < I(X_2 ; Y \mid X_1) \NC R_2 \NR
+%D \NC R_1 + R_2 \NC < I(X_1 ; Y) \NC R_1 + R_2 \NR
+%D \stopmatrix
+%D \right\}
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {startmatrices}
+%D
+%D Just a handy keystroke safer:
+
+\def\startmatrices
+ {\begingroup
+ \setupmathmatrix}
+
+\def\stopmatrices
+ {\endgroup}
+
+%D \startbuffer
+%D \startformula
+%D \startmatrix[left={\left(},right={\right)}]
+%D \NC A \NC B \NR \NC C \NC D \NR
+%D \stopmatrix
+%D =
+%D \startmatrix[left={\left(},right={\right)},location=low]
+%D \NC A \NC B \NR \NC C \NC D \NR
+%D \stopmatrix
+%D =
+%D \startmatrix[left={\left(},right={\right)},location=high]
+%D \NC A \NC B \NR \NC C \NC D \NR
+%D \stopmatrix
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \startformula
+%D \startmatrices[left={\left(},right={\right)}]
+%D \startmatrix
+%D \NC A \NC B \NR \NC C \NC D \NR
+%D \stopmatrix
+%D =
+%D \startmatrix[location=bottom]
+%D \NC A \NC B \NR \NC C \NC D \NR
+%D \stopmatrix
+%D =
+%D \startmatrix[location=top]
+%D \NC A \NC B \NR \NC C \NC D \NR
+%D \stopmatrix
+%D \stopmatrices
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {startintertext}
+%D
+%D Preliminary feature:
+%D
+%D {\em example code}
+
+\def\startintertext#1\stopintertext
+ {\noalign{\dointertext{#1}}}
+
+\def\intertext#1%
+ {\noalign{\dointertext{#1}}}
+
+\unexpanded\def\dointertext#1%
+ {\penalty\postdisplaypenalty
+ \afterdisplayspace
+ \vbox{\forgetall\noindent#1\par}%
+ \penalty\predisplaypenalty
+ \beforedisplayspace}
+
+% %D \macros
+% %D {substack}
+% %D
+% %D Preliminary code:
+% %D
+% %D \starttyping
+% %D \startformula
+% %D \sum_{%
+% %D \startsubstack
+% %D i = 1 \NR
+% %D i \neq n \NR
+% %D i \neq m
+% %D \stopsubstack
+% %D }a_i
+% %D \stopformula
+% %D \stoptyping
+
+% \def\startsubstack
+% {\begingroup
+% \null
+% \vcenter\bgroup
+% \pushmacro\domatrixNC
+% \let\stopmathmode\relax
+% \def\NC{\domatrixNC}%
+% \def\MC{\domatrixNC\startmathmode}%
+% \global\let\domatrixNC\dodomatrixNC
+% \def\NR
+% {\stopmathmode
+% \global\let\domatrixNC\dodomatrixNC
+% \crcr\noalign{\nointerlineskip}}%
+% \mathsurround\zeropoint
+% \everycr\emptytoks
+% \halign\bgroup\hfil$\scriptstyle\mathstrut##$\hfil\crcr}
+
+% \def\stopsubstack
+% {\crcr
+% \egroup
+% \popmacro\domatrixNC
+% \egroup
+% \endgroup}
+
+%D \macros
+%D {substack}
+%D
+%D Preliminary code:
+%D
+%D \startbuffer
+%D \startformula
+%D \sum_{%
+%D \startsubstack
+%D i = 1 \NR
+%D i \neq n \NR
+%D i \neq m
+%D \stopsubstack
+%D }a_i
+%D \stopformula
+%D \stopbuffer
+%D
+%D \getbuffer which was typed as \typebuffer
+%D
+%D Notice that these macros give the correct spacing for
+%D subscripts. Compare for example
+%D
+%D \startbuffer
+%D \startformula
+%D \sum_{\startsubstack a \NR b \NR \stopsubstack}
+%D \text{ and }
+%D \sum_{\scriptstyle a \atop \scriptstyle}
+%D \stopformula
+%D \typebuffer which gives \getbuffer
+
+\def\startsubstack
+ {\begingroup
+ \vcenter\bgroup
+ \baselineskip\mathstacktotal
+ \lineskip\mathstackvgap
+ \lineskiplimit\lineskip
+ \let\stopmathmode\relax
+ \def\NC{\domatrixNC}%
+ \def\MC{\domatrixNC\startmathmode}%
+ \global\let\domatrixNC\dodomatrixNC
+ \def\NR
+ {\stopmathmode
+ \global\let\domatrixNC\dodomatrixNC
+ \crcr}%
+ \mathsurround\zeropoint
+ \everycr\emptytoks
+ \halign\bgroup\hfil$\scriptstyle##$\hfil\crcr}
+
+\def\stopsubstack
+ {\crcr
+ \egroup
+ \egroup
+ \endgroup}
+
+%D \macros
+%D {bordermatrix}
+%D
+%D In \PLAIN\ \TEX\ the width of a parenthesis is stored in
+%D the \DIMENSION\ \type{\mathparentwd}. This value is derived from
+%D the width of \type{\tenrm B}, so let's take care of it now:
+
+\ifx\mathparentwd\undefined \newdimen\mathparentwd \fi
+
+\let\normalbordermatrix\bordermatrix
+
+\def\bordermatrix
+ {\begingroup
+ \setbox\scratchbox\hbox{\mr\char"239C}%
+ \global\mathparentwd\wd\scratchbox\relax
+ \endgroup
+ \normalbordermatrix}
+
+% to be tested
+%
+% \def\bordermatrix
+% {\begingroup\mr\global\mathparentwd\fontcharwd\font"239C\relax\endgroup
+% \normalbordermatrix}
+
+%D \macros{overset, underset}
+%D
+%D The macros \type{\overset} and \type{\underset} are provided by
+%D \AMS\ packages in \LATEX. These macro allows you to place a symbol
+%D above or below another symbol, irrespective of whether the other
+%D symbol is a relation or something else, and without influencing the
+%D spacing. For most cases there is a better way to do such things
+%D (declaring a math command with limop option, or using accents), but
+%D occasionally these macros can be useful, for example:
+%D
+%D \startbuffer
+%D \startformula
+%D \overset{*}{X} \underset{*}{X}
+%D \stopformula
+%D \stopbuffer
+%D \typebuffer \getbuffer
+%D
+%D Use these macros sparingly. Remember, \TEX\ was designed for
+%D mathematics, so there is usually a proper method for typesetting
+%D common math notation.
+
+%D These macros are a clearer version of \type{\binrel@} and
+%D \type{\binrel@@} macros in \AMSTEX\ packages.
+
+\def\preparebinrel#1%
+ {\begingroup
+ \setbox\scratchbox\hbox
+ {\thinmuskip 0mu
+ \medmuskip -1mu
+ \thickmuskip -1mu
+ \setbox\scratchbox\hbox{$#1\mathsurround\zeropoint$}%
+ \kern-\wd\scratchbox
+ ${}#1{}\mathsurround\zeropoint$}%
+ \normalexpanded
+ {\endgroup
+ \let\noexpand\currentbinrel
+ \ifdim\wd\scratchbox<\zeropoint
+ \mathbin
+ \else\ifdim\wd\scratchbox>\zeropoint
+ \mathrel
+ \else
+ \relax
+ \fi\fi}}
+
+\unexpanded\def\overset#1#2%
+ {\preparebinrel{#2}%
+ \currentbinrel{\mathop{\kern\zeropoint#2}\limits^{#1}}}
+
+\unexpanded\def\underset#1#2%
+ {\preparebinrel{#2}%
+ \currentbinrel{\mathop{\kern\zeropoint#2}\limits_{#1}}}
+
+\protect \endinput
+
+% \placeformula \startformula[-] \startmatrix
+% \NC 1 \NC x \NC a \NR
+% \NC 2 \NC y \NC b \NR
+% \NC 3 \NC z \NC c \NR
+% \stopmatrix \stopformula
+
+% \definemathmatrix[bordermatrix][left={\left[\,},right={\,\right]}]
+
+% \placeformula \startformula[-] \startbordermatrix
+% \NC 1 \NC x \NC a \NR
+% \NC 2 \NC y \NC b \NR
+% \NC 3 \NC z \NC c \NR
+% \stopbordermatrix \stopformula
diff --git a/tex/context/base/math-ams.tex b/tex/context/base/math-ams.tex
index 29fe19e0b..83070d01a 100644
--- a/tex/context/base/math-ams.tex
+++ b/tex/context/base/math-ams.tex
@@ -311,7 +311,7 @@
\stopmathcollection
\def\AMSwidehat#1%
- {\setbox\scratchbox\hbox{$\m@th#1$}%
+ {\setbox\scratchbox\hbox{$\mathsurround\zeropoint#1$}%
\ifdim\wd\scratchbox>2em
\mathaccent"0\purefamilyhex{mb}5B{#1}%
\else
@@ -319,7 +319,7 @@
\fi}
\def\AMSwidetilde#1%
- {\setbox\scratchbox\hbox{$\m@th#1$}%
+ {\setbox\scratchbox\hbox{$\mathsurround\zeropoint#1$}%
\ifdim\wd\scratchbox>2em
\mathaccent"0\purefamilyhex{mb}5D{#1}%
\else
diff --git a/tex/context/base/math-arr.mkii b/tex/context/base/math-arr.mkii
new file mode 100644
index 000000000..3b9abaa91
--- /dev/null
+++ b/tex/context/base/math-arr.mkii
@@ -0,0 +1,391 @@
+%D \module
+%D [ file=math-ext,
+%D version=2007.07.19,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Arrows,
+%D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan},
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Arrows}
+
+\unprotect
+
+%D These will be generalized! Is it still needed in \MKIV?
+
+%D We next define extensible arrows. Extensible arrows are arrows that
+%D change their length according to the width of the text to be placed
+%D above and below the arrow. Since we need to define a lot of arrows,
+%D we first define some helper macros. The basic idea is to measure
+%D the width of the box to be placed above and below the arrow, and
+%D make the \quotation{body} of the arrow as long as the bigger of the
+%D two widths.
+
+\def\mtharrfactor{1}
+\def\mtharrextra {0}
+
+\def\domthxarr#1#2#3#4#5% hm, looks like we do a double mathrel
+ {\begingroup
+ \def\mtharrfactor{1}%
+ \def\mtharrextra {0}%
+ \processaction[#1] % will be sped up
+ [ \v!none=>\def\mtharrfactor{0},
+ \v!small=>\def\mtharrextra{10},
+ \v!medium=>\def\mtharrextra{15},
+ \v!big=>\def\mtharrextra{20},
+ \v!normal=>,
+ \v!default=>,
+ \v!unknown=>\doifnumberelse{#1}{\def\mtharrextra{#1}}\donothing]%
+ \mathsurround\zeropoint
+ \muskip0=\thirdoffourarguments #2mu
+ \muskip2=\fourthoffourarguments #2mu
+ \muskip4=\firstoffourarguments #2mu
+ \muskip6=\secondoffourarguments #2mu
+ \muskip0=\mtharrfactor\muskip0 \advance\muskip0 \mtharrextra mu
+ \muskip2=\mtharrfactor\muskip2 \advance\muskip2 \mtharrextra mu
+ \setbox0\hbox{$\scriptstyle
+ \mkern\muskip4\relax
+ \mkern\muskip0\relax
+ #5\relax
+ \mkern\muskip2\relax
+ \mkern\muskip6\relax
+ $}%
+ \setbox4\hbox{#3\displaystyle}%
+ \dimen0\wd0
+ \ifdim\wd4>\dimen0 \dimen0\wd4 \fi
+ \setbox2\hbox{$\scriptstyle
+ \mkern\muskip4\relax
+ \mkern\muskip0\relax
+ #4\relax
+ \mkern\muskip2\relax
+ \mkern\muskip6\relax
+ $}%
+ \ifdim\wd2>\dimen0 \dimen0\wd2 \fi
+ \setbox4\hbox to \dimen0{#3\displaystyle}%
+ \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}\limits^{\box0}_{\box2}}
+ \endgroup}
+
+\let\domthxarrsingle\domthxarr
+
+%D There are some arrows which are created by stacking two arrows. The next
+%D macro helps in defining such \quotation{double arrows}.
+
+\def\domthxarrdouble#1#2#3#4#5#6#7% opt l r sp rs top bot
+ {\mathrel
+ {\scratchdimen.32ex\relax % was .22, todo: make configurable
+ \setbox0\hbox{$\domthxarr{#1}{#2}{#4}{\phantom{#6}}{#7}$}%
+ \setbox2\hbox{$\domthxarr{#1}{#3}{#5}{#6}{\phantom{#7}}$}%
+ \raise\scratchdimen\box0
+ \kern-\wd2
+ \lower\scratchdimen\box2}}
+
+%D \macros{definematharrow}
+%D
+%D Macro for defining new arrows. We can define two types of
+%D arrows|<|single arrows and double arrows. Single arrows are defined
+%D as
+%D
+%D \starttyping
+%D \definematharrow [xrightarrow] [0359] [\rightarrowfill]
+%D \stoptyping
+%D
+%D The first argument is the name of the arrow (\tex{xrightarrow} in
+%D this case.) The second argument consists of a set of 4 numbers and
+%D specify the spacing correction in math units~\type{mu}. These
+%D numbers define:
+%D
+%D \startlines
+%D 1st number: arrow||tip correction
+%D 2nd number: arrow||tip correction
+%D 3rd number: space (multiplied by \tex{matharrfactor} and advanced by \tex{matharrextra})
+%D 4th number: space (multiplied by \tex{matharrfactor} and advanced by \tex{matharrextra})
+%D \stoplines
+%D
+%D The third argument is the name of the extensible fill. The third
+%D argument is optional when the arrow is redefined later (this is
+%D useful for font specific tweaking of the skips.) For example,
+%D
+%D \startbuffer
+%D \math{\xrightarrow{above}}
+%D \definematharrow[xrightarrow][0000]
+%D \math{\xrightarrow{above}}
+%D \definematharrow[xrightarrow][55{50}{50}]
+%D \math{\xrightarrow{above}}
+%D \stopbuffer
+%D \typebuffer gives {\getbuffer}
+%D
+%D The double arrows are defined as follows
+%D
+%D \starttyping
+%D \definematharrow [xrightleftharpoons] [3095,0359]
+%D [\rightharpoonupfill,\leftharpoondownfill]
+%D \stoptyping
+%D
+%D The second and the third set of arguments consist of comma
+%D separated values. The first element of the second argument
+%D (\type{3095}) corresponds to the spacing correction of top arrow
+%D fill (\tex{rightarrowupfill}). Similarly, \type{0359} corresponds
+%D to bottom arrow fill \tex{leftharpoondownfill}). Stacking them on
+%D top of each other we get $\xrightleftharpoons[big]{above}{below}$.
+%D The following math arrows are defined
+%D
+%D \placetable[none]{}{\starttable[|l|m|]
+%D \NC \tex{xrightarrow } \NC \xrightarrow [big] \NC \NR
+%D \NC \tex{xleftarrow } \NC \xleftarrow [big] \NC \NR
+%D \NC \tex{xequal } \NC \xequal [big] \NC \NR
+%D \NC \tex{xRightarrow } \NC \xRightarrow [big] \NC \NR
+%D \NC \tex{xLeftarrow } \NC \xLeftarrow [big] \NC \NR
+%D \NC \tex{xLeftrightarrow } \NC \xLeftrightarrow [big] \NC \NR
+%D \NC \tex{xleftrightarrow } \NC \xleftrightarrow [big] \NC \NR
+%D \NC \tex{xmapsto } \NC \xmapsto [big] \NC \NR
+%D \NC \tex{xtwoheadrightarrow } \NC \xtwoheadrightarrow [big] \NC \NR
+%D \NC \tex{xtwoheadleftarrow } \NC \xtwoheadleftarrow [big] \NC \NR
+%D \NC \tex{xrightharpoondown } \NC \xrightharpoondown [big] \NC \NR
+%D \NC \tex{xrightharpoonup } \NC \xrightharpoonup [big] \NC \NR
+%D \NC \tex{xleftharpoondown } \NC \xleftharpoondown [big] \NC \NR
+%D \NC \tex{xleftharpoonup } \NC \xleftharpoonup [big] \NC \NR
+%D \NC \tex{xhookleftarrow } \NC \xhookleftarrow [big] \NC \NR
+%D \NC \tex{xhookrightarrow } \NC \xhookrightarrow [big] \NC \NR
+%D \NC \tex{xleftrightharpoons } \NC \xleftrightharpoons [big] \NC \NR
+%D \NC \tex{xrightleftharpoons } \NC \xrightleftharpoons [big] \NC \NR
+%D \stoptable}
+
+\def\definematharrow
+ {\doquadrupleargument\dodefinematharrow}
+
+\def\dodefinematharrow[#1][#2][#3][#4]% name type[none|both] template command
+ {\iffourthargument
+ \executeifdefined{dodefine#2arrow}\gobblethreearguments{#1}{#3}{#4}%
+ \else\ifthirdargument
+ \dodefinebotharrow{#1}{#2}{#3}%
+ \else\ifsecondargument
+ \redefinebotharrow{#1}{#2}{#3}%
+ \fi\fi\fi}
+
+\def\redefinebotharrow#1#2#3% real dirty, this overload!
+ {\doifdefined{#1}
+ {\pushmacro\dohandlemtharrow
+ \def\dohandlemtharrow[##1][##2]{\setvalue{#1}{\dohandlemtharrow[#2][##2]}}%
+ % == \def\dohandlemtharrow[##1][##2]{\dodefinebotharrow{#1}{#2}{##2}}%
+ \getvalue{#1}%
+ \popmacro\dohandlemtharrow}}
+
+\def\dodefinebotharrow#1#2#3%
+ {\setvalue{#1}{\dohandlemtharrow[#2][#3]}}
+
+\def\dohandlemtharrow
+ {\dotripleempty\doxmtharrow}
+
+\def\doxmtharrow[#1][#2][#3]% #3 == optional arg
+ {\def\dodoxmtharrow{\dododoxmtharrow[#1,\empty,\empty][#2,\empty,\empty][#3]}% {##1}{##2}
+ \dodoublegroupempty\dodoxmtharrow}
+
+\def\dododoxmtharrow[#1,#2,#3][#4,#5,#6][#7]#8#9% [3] is the optional arg
+ {\edef\!!stringa{#2}%
+ \ifx\!!stringa\empty
+ \ifsecondargument
+ \mathrel{\domthxarrsingle{#7}{#1}{#4}{#8}{#9}}%
+ \else
+ \mathrel{\domthxarrsingle{#7}{#1}{#4}{}{#8}}%
+ \fi
+ \else
+ \ifsecondargument
+ \mathrel{\domthxarrdouble{#7}{#1}{#2}{#4}{#5}{#8}{#9}}%
+ \else
+ \mathrel{\domthxarrdouble{#7}{#1}{#2}{#4}{#5}{}{#8}}%
+ \fi
+ \fi}
+
+% Adapted from amsmath.
+
+%D \macros{mtharrowfill,defaultmtharrowfill}
+%D
+%D To extend the arrows we need to define a \quotation{math arrow
+%D fill}. This command takes 8 arguments: the first four correspond
+%D the second argument of \tex{definematharrow} explained above. The
+%D other three specify the tail, body and head of the arrow. The last
+%D argument specifies the math-mode in which the arrow is drawn.
+%D \tex{defaultmtharrowfill} has values tweaked to match Latin Modern
+%D fonts. For fonts that are significantly different (e.g. cows) a
+%D different set of values need to be determined.
+
+\def\mtharrowfill#1#2#3#4#5#6#7#8%
+ {$\mathsurround 0pt
+ \thickmuskip0mu\medmuskip\thickmuskip\thinmuskip\thickmuskip
+ \relax#8#5%
+ \mkern-#1mu
+ \cleaders\hbox{$#8\mkern -#2mu#6\mkern -#3mu$}\hfill
+ \mkern-#4mu#7$}
+
+\def\defaultmtharrowfill{\mtharrowfill 7227}
+
+%D We now define some arrow fills that will be used for defining the
+%D arrows. Plain \TEX\ already defines \tex{leftarrowfill} and
+%D \tex{rightarrowfill}. The \tex{defaultmtharrowfill} command defines an
+%D arrowfill that takes an argument (so that it can also be used
+%D with over and under arrows). However the Plain \TEX\ definitions of
+%D \tex{leftarrowfill} and \tex{rightarrowfill} do not take this extra
+%D argument. To be backward compatible with Plain \TEX, we define two
+%D arrowfills: \tex{specrightarrowfill} which takes an extra argument, and
+%D \tex{rightarrowfill} which does not.
+
+\def\specrightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow}
+\def\specleftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar}
+
+\def\rightarrowfill {\specrightarrowfill \textstyle}
+\def\leftarrowfill {\specleftarrowfill \textstyle}
+
+\def\equalfill {\defaultmtharrowfill \Relbar \Relbar \Relbar}
+\def\Rightarrowfill {\defaultmtharrowfill \Relbar \Relbar \Rightarrow}
+\def\Leftarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Relbar}
+\def\Leftrightarrowfill {\defaultmtharrowfill \Leftarrow \Relbar \Rightarrow}
+\def\leftrightarrowfill {\defaultmtharrowfill \leftarrow \relbar \rightarrow}
+\def\mapstofill {\defaultmtharrowfill{\mapstochar\relbar} \relbar \rightarrow}
+\def\twoheadrightarrowfill{\defaultmtharrowfill \relbar \relbar \twoheadrightarrow}
+\def\twoheadleftarrowfill {\defaultmtharrowfill \twoheadleftarrow \relbar \relbar}
+\def\rightharpoondownfill {\defaultmtharrowfill \relbar \relbar \rightharpoondown}
+\def\rightharpoonupfill {\defaultmtharrowfill \relbar \relbar \rightharpoonup}
+\def\leftharpoondownfill {\defaultmtharrowfill \leftharpoondown \relbar \relbar}
+\def\leftharpoonupfill {\defaultmtharrowfill \leftharpoonup \relbar \relbar}
+\def\hookleftfill {\defaultmtharrowfill \leftarrow \relbar{\relbar\joinrel\rhook}}
+\def\hookrightfill {\defaultmtharrowfill{\lhook\joinrel\relbar}\relbar \rightarrow}
+\def\relfill {\defaultmtharrowfill \relbar \relbar \relbar}
+
+\def\triplerelbar {\mathrel\equiv}
+\def\triplerelfill{\defaultmtharrowfill\triplerelbar\triplerelbar\triplerelbar}
+
+\def\singlebond{{\xrel}} % or \def\singlebond{{\xrel[2]}}
+\def\doublebond{{\xequal}}
+\def\triplebond{{\xtriplerel}}
+
+%D Now we define most commonly used arrows. These include arrows
+%D defined in \filename{amsmath.sty}, \filename{extarrows.sty},
+%D \filename{extpfel.sty} and \filename{mathtools.sty} packages for
+%D \LATEX\ (plus a few more).
+
+\definematharrow [xrightarrow] [0359] [\specrightarrowfill]
+\definematharrow [xleftarrow] [3095] [\specleftarrowfill]
+\definematharrow [xequal] [0099] [\equalfill]
+\definematharrow [xRightarrow] [0359] [\Rightarrowfill]
+\definematharrow [xLeftarrow] [3095] [\Leftarrowfill]
+\definematharrow [xLeftrightarrow] [0099] [\Leftrightarrowfill]
+\definematharrow [xleftrightarrow] [0099] [\leftrightarrowfill]
+\definematharrow [xmapsto] [3599] [\mapstofill]
+\definematharrow [xtwoheadrightarrow] [5009] [\twoheadrightarrowfill]
+\definematharrow [xtwoheadleftarrow] [0590] [\twoheadleftarrowfill]
+\definematharrow [xrightharpoondown] [0359] [\rightharpoondownfill]
+\definematharrow [xrightharpoonup] [0359] [\rightharpoonupfill]
+\definematharrow [xleftharpoondown] [3095] [\leftharpoondownfill]
+\definematharrow [xleftharpoonup] [3095] [\leftharpoonupfill]
+\definematharrow [xhookleftarrow] [3095] [\hookleftfill]
+\definematharrow [xhookrightarrow] [0395] [\hookrightfill]
+\definematharrow [xrel] [0099] [\relfill]
+\definematharrow [xtriplerel] [0099] [\triplerelfill]
+\definematharrow [xrightoverleftarrow] [0359,3095] [\specrightarrowfill,\specleftarrowfill]
+\definematharrow [xleftrightharpoons] [3399,3399] [\leftharpoonupfill,\rightharpoondownfill]
+\definematharrow [xrightleftharpoons] [3399,3399] [\rightharpoonupfill,\leftharpoondownfill]
+
+%D These arrows can be used as follows:
+%D
+%D \startbuffer
+%D \startformula \xrightarrow{stuff on top}\stopformula
+%D \startformula \xrightarrow{}{stuff on top}\stopformula
+%D \startformula \xrightarrow{stuff below}{}\stopformula
+%D \startformula \xrightarrow{stuff below}{stuff on top}\stopformula
+%D
+%D \startformula \xleftarrow [none]{stuff below}{stuff on top}\stopformula
+%D \startformula \xleftarrow [small]{stuff below}{stuff on top}\stopformula
+%D \startformula \xleftarrow [medium]{stuff below}{stuff on top}\stopformula
+%D \startformula \xleftarrow [big]{stuff below}{stuff on top}\stopformula
+%D \stopbuffer
+%D
+%D \typebuffer which gives \getbuffer
+
+%D \macros{definemathoverarrow,defineunderarrow}
+%D
+%D These macros for define math-overarrows are adapted from
+%D \filename{amsmath.sty}
+
+\def\definemathoverarrow
+ {\dotripleargument\dodefinemathoverarrow}
+
+\def\dodefinemathoverarrow[#1][#2][#3]%
+ {\ifthirdargument
+ \setvalue{#1}{\dohandlemathoverarrow[#2][#3]}%
+ \else
+ \setvalue{#1}{\dohandlemathoverarrow[\zeropoint][#2]}%
+ \fi}
+
+\def\dohandlemathoverarrow[#1][#2]%
+ {\mathpalette{\dodohandlemathoverarrow{#1}{#2}}}
+
+%D Note: \filename{math-pln.tex} has \type{\kern-\onepoint} and
+%D \filename{amsmath.sty} does not. We keep the kern amount
+%D configurable. This is useful for harpoons.
+
+\def\dodohandlemathoverarrow#1#2#3#4%
+ {\vbox{\ialign{##\crcr
+ #2#3\crcr
+ \noalign{\kern#1\nointerlineskip}%
+ $\mathsurround\zeropoint\hfil#3#4\hfil$\crcr}}}
+
+%D Now the under arrows
+
+\def\definemathunderarrow
+ {\dotripleargument\dodefinemathunderarrow}
+
+%D For underarrows the default kern is 0.3ex
+
+\def\dodefinemathunderarrow[#1][#2][#3]%
+ {\ifthirdargument
+ \setvalue{#1}{\dohandlemathunderarrow[#2][#3]}%
+ \else
+ \setvalue{#1}{\dohandlemathunderarrow[0.3ex][#2]}%
+ \fi}
+
+\def\dohandlemathunderarrow[#1][#2]%
+ {\mathpalette{\dodohandlemathunderarrow{#1}{#2}}}
+
+\def\dodohandlemathunderarrow#1#2#3#4%
+ {\vtop{\ialign{##\crcr
+ $\mathsurround\zeropoint\hfil#3#4\hfil$\crcr
+ \noalign{\nointerlineskip\kern#1}%
+ #2#3\crcr}}}
+
+%D Now we define the arrows
+
+\definemathoverarrow [overleftarrow] [\specleftarrowfill]
+\definemathoverarrow [overrightarrow] [\specrightarrowfill]
+\definemathoverarrow [overleftrightarrow] [\leftrightarrowfill]
+\definemathoverarrow [overtwoheadrightarrow] [\twoheadrightarrowfill]
+\definemathoverarrow [overtwoheadleftarrow] [\twoheadleftarrowfill]
+\definemathoverarrow [overrightharpoondown] [1pt] [\rightharpoondownfill]
+\definemathoverarrow [overrightharpoonup] [\rightharpoonupfill]
+\definemathoverarrow [overleftharpoondown] [1pt] [\leftharpoondownfill]
+\definemathoverarrow [overleftharpoonup] [\leftharpoonupfill]
+
+\definemathunderarrow [underleftarrow] [\specleftarrowfill]
+\definemathunderarrow [underrightarrow] [\specrightarrowfill]
+\definemathunderarrow [underleftrightarrow] [\leftrightarrowfill]
+\definemathunderarrow [undertwoheadrightarrow][\twoheadrightarrowfill]
+\definemathunderarrow [undertwoheadleftarrow] [\twoheadleftarrowfill]
+\definemathunderarrow [underrightharpoondown] [\rightharpoondownfill]
+\definemathunderarrow [underrightharpoonup] [\rightharpoonupfill]
+\definemathunderarrow [underleftharpoondown] [\leftharpoondownfill]
+\definemathunderarrow [underleftharpoonup] [\leftharpoonupfill]
+
+%D These can be used as follows:
+%D
+%D \startbuffer
+%D $\overleftarrow{A}$ $\overleftarrow{ABC}$
+%D $a_{\overleftarrow{A}}$ $b_{\overleftarrow{ABC}}$
+%D \stopbuffer
+%D \typebuffer which gives \getbuffer
+
+%D TODO: Possibly have a single arrow command define all the arrows.
+
+\protect \endinput
diff --git a/tex/context/base/math-ext.tex b/tex/context/base/math-arr.mkiv
index cf332ba00..5c6cfc294 100644
--- a/tex/context/base/math-ext.tex
+++ b/tex/context/base/math-arr.mkiv
@@ -1,8 +1,8 @@
%D \module
-%D [ file=math-ext,
+%D [ file=math-arr,
%D version=2007.07.19,
%D title=\CONTEXT\ Math Macros,
-%D subtitle=Extra Macros,
+%D subtitle=Arrows,
%D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan},
%D date=\currentdate,
%D copyright=\PRAGMA]
@@ -11,9 +11,11 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Math Macros / Arrows}
+
\unprotect
-%D These will be generalized!
+%D These will be generalized! Is it still needed in \MKIV?
\def\exmthfont#1{\symbolicsizedfont#1\plusone{MathExtension}}
@@ -271,19 +273,19 @@
%D We now define some arrow fills that will be used for defining the
%D arrows. Plain \TEX\ already defines \tex{leftarrowfill} and
-%D \tex{rightarrowfill}. The \tex{defaultmtharrowfill} command defines an
+%D \tex{rightarrowfill}. The \tex{defaultmtharrowfill} command defines an
%D arrowfill that takes an argument (so that it can also be used
-%D with over and under arrows). However the Plain \TEX\ definitions of
+%D with over and under arrows). However the Plain \TEX\ definitions of
%D \tex{leftarrowfill} and \tex{rightarrowfill} do not take this extra
%D argument. To be backward compatible with Plain \TEX, we define two
-%D arrowfills: \tex{specrightarrowfill} which takes an extra argument, and
+%D arrowfills: \tex{specrightarrowfill} which takes an extra argument, and
%D \tex{rightarrowfill} which does not.
\def\specrightarrowfill {\defaultmtharrowfill \relbar \relbar \rightarrow}
\def\specleftarrowfill {\defaultmtharrowfill \leftarrow \relbar \relbar}
-\def\rightarrowfill {\specrightarrowfill \textstyle}
-\def\leftarrowfill {\specleftarrowfill \textstyle}
+\def\rightarrowfill {\specrightarrowfill \textstyle}
+\def\leftarrowfill {\specleftarrowfill \textstyle}
\def\equalfill {\defaultmtharrowfill \Relbar \Relbar \Relbar}
\def\Rightarrowfill {\defaultmtharrowfill \Relbar \Relbar \Rightarrow}
@@ -377,7 +379,7 @@
{\vbox{\ialign{##\crcr
#2#3\crcr
\noalign{\kern#1\nointerlineskip}%
- $\m@th\hfil#3#4\hfil$\crcr}}}
+ $\mathsurround\zeropoint\hfil#3#4\hfil$\crcr}}}
%D Now the under arrows
@@ -398,7 +400,7 @@
\def\dodohandlemathunderarrow#1#2#3#4%
{\vtop{\ialign{##\crcr
- $\m@th\hfil#3#4\hfil$\crcr
+ $\mathsurround\zeropoint\hfil#3#4\hfil$\crcr
\noalign{\nointerlineskip\kern#1}%
#2#3\crcr}}}
diff --git a/tex/context/base/math-def.mkiv b/tex/context/base/math-def.mkiv
new file mode 100644
index 000000000..9e6ad28c1
--- /dev/null
+++ b/tex/context/base/math-def.mkiv
@@ -0,0 +1,338 @@
+%D \module
+%D [ file=math-tex,
+%D version=2001.04.12,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Definitions,
+%D author={Hans Hagen, Taco Hoekwater \& Aditya Mahajan},
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Definitions}
+
+\unprotect
+
+\ifx\mrfam\undefined \chardef\mrfam\plusone \fi
+
+\startluacode
+ mathematics.define()
+ mathematics.register_xml_entities()
+\stopluacode
+
+% special .. todo
+
+\mathcode`\ ="8000 \mathcode`\_="8000 \mathcode`\'="8000
+
+% will be attributes
+
+\setfalse \automathpunctuation
+
+\def\enablemathpunctuation {\settrue \automathpunctuation}
+\def\disablemathpunctuation{\setfalse\automathpunctuation}
+
+\def\v!autopunctuation{autopunctuation}
+
+\appendtoks
+ \doifelse{\mathematicsparameter\v!autopunctuation}\v!yes\enablemathpunctuation\disablemathpunctuation
+\to \everysetupmathematics
+
+\appendtoks
+ \ifconditional\automathpunctuation\dosetattribute{mathpunc}\plusone\fi
+\to \everymathematics
+
+\setupmathematics[\v!autopunctuation=\v!yes]
+
+% will go to math-ext
+
+\Umathchardef\braceld=0 \mrfam "FF07A
+\Umathchardef\bracerd=0 \mrfam "FF07B
+\Umathchardef\bracelu=0 \mrfam "FF07C
+\Umathchardef\braceru=0 \mrfam "FF07D
+
+% ctx specific
+
+\def\|{|} % still letter
+
+% The \mfunction macro is an alternative for \hbox with a
+% controlable font switch.
+
+\definemathcommand [arccos] [nolop] {\mfunction{arccos}}
+\definemathcommand [arcsin] [nolop] {\mfunction{arcsin}}
+\definemathcommand [arctan] [nolop] {\mfunction{arctan}}
+\definemathcommand [arg] [nolop] {\mfunction{arg}}
+\definemathcommand [cosh] [nolop] {\mfunction{cosh}}
+\definemathcommand [cos] [nolop] {\mfunction{cos}}
+\definemathcommand [coth] [nolop] {\mfunction{coth}}
+\definemathcommand [cot] [nolop] {\mfunction{cot}}
+\definemathcommand [csc] [nolop] {\mfunction{csc}}
+\definemathcommand [deg] [nolop] {\mfunction{deg}}
+\definemathcommand [det] [limop] {\mfunction{det}}
+\definemathcommand [dim] [nolop] {\mfunction{dim}}
+\definemathcommand [exp] [nolop] {\mfunction{exp}}
+\definemathcommand [gcd] [limop] {\mfunction{gcd}}
+\definemathcommand [hom] [nolop] {\mfunction{hom}}
+\definemathcommand [inf] [limop] {\mfunction{inf}}
+\definemathcommand [injlim] [limop] {\mfunction{inj\,lim}}
+\definemathcommand [ker] [nolop] {\mfunction{ker}}
+\definemathcommand [lg] [nolop] {\mfunction{lg}}
+\definemathcommand [liminf] [limop] {\mfunction{lim\,inf}}
+\definemathcommand [limsup] [limop] {\mfunction{lim\,sup}}
+\definemathcommand [lim] [limop] {\mfunction{lim}}
+\definemathcommand [ln] [nolop] {\mfunction{ln}}
+\definemathcommand [log] [nolop] {\mfunction{log}}
+\definemathcommand [median] [limop] {\mfunction{median}}
+\definemathcommand [max] [limop] {\mfunction{max}}
+\definemathcommand [min] [limop] {\mfunction{min}}
+\definemathcommand [mod] [limop] {\mfunction{mod}}
+\definemathcommand [div] [limop] {\mfunction{div}}
+\definemathcommand [projlim] [limop] {\mfunction{proj\,lim}}
+\definemathcommand [Pr] [limop] {\mfunction{Pr}}
+\definemathcommand [sec] [nolop] {\mfunction{sec}}
+\definemathcommand [sinh] [nolop] {\mfunction{sinh}}
+\definemathcommand [sin] [nolop] {\mfunction{sin}}
+\definemathcommand [sup] [limop] {\mfunction{sup}}
+\definemathcommand [tanh] [nolop] {\mfunction{tanh}}
+\definemathcommand [tan] [nolop] {\mfunction{tan}}
+
+\definemathcommand [integers] {{\mathblackboard Z}}
+\definemathcommand [reals] {{\mathblackboard R}}
+\definemathcommand [rationals] {{\mathblackboard Q}}
+\definemathcommand [naturalnumbers]{{\mathblackboard N}}
+\definemathcommand [complexes] {{\mathblackboard C}}
+\definemathcommand [primes] {{\mathblackboard P}}
+
+% using attributes
+
+\def\choosemathbig#1#2{\dosetattribute{mathsize}{#1}\left#2\right.\doresetattribute{mathsize}}
+
+\definemathcommand [big] {\choosemathbig\plusone }
+\definemathcommand [Big] {\choosemathbig\plustwo }
+\definemathcommand [bigg] {\choosemathbig\plusthree}
+\definemathcommand [Bigg] {\choosemathbig\plusfour }
+
+\definemathcommand [bigl] [open] [one] {\big}
+\definemathcommand [bigm] [rel] [one] {\big}
+\definemathcommand [bigr] [close] [one] {\big}
+\definemathcommand [Bigl] [open] [one] {\Big}
+\definemathcommand [Bigm] [rel] [one] {\Big}
+\definemathcommand [Bigr] [close] [one] {\Big}
+\definemathcommand [biggl] [open] [one] {\bigg}
+\definemathcommand [biggm] [rel] [one] {\bigg}
+\definemathcommand [biggr] [close] [one] {\bigg}
+\definemathcommand [Biggl] [open] [one] {\Bigg}
+\definemathcommand [Biggm] [rel] [one] {\Bigg}
+\definemathcommand [Biggr] [close] [one] {\Bigg}
+
+% special
+
+%AM: Optimize this! Add similar options for sums.
+
+\def\setoperatorlimits#1#2% operator limits
+ {\savenormalmeaning{#1}%
+ \def#1{\getvalue{normal\strippedcsname#1}#2}}
+
+\setoperatorlimits\int \intlimits
+\setoperatorlimits\iint \intlimits
+\setoperatorlimits\iiint \intlimits
+\setoperatorlimits\oint \intlimits
+\setoperatorlimits\oiint \intlimits
+\setoperatorlimits\oiiint \intlimits
+\setoperatorlimits\intclockwise \intlimits
+\setoperatorlimits\ointclockwise \intlimits
+\setoperatorlimits\ointctrclockwise \intlimits
+
+%D This is a temporary hack until we figure out how to do this correctly.
+
+\unexpanded\def\implies {\mathrel{\;\Longrightarrow\;}}
+\unexpanded\def\impliedby{\mathrel{\;\Longleftarrow\;}}
+\unexpanded\def\And {\mathrel{\;\internalAnd\;}}
+\unexpanded\def\iff {\;\Longleftrightarrow\;}
+
+% todo: virtual in math-vfu
+
+% \definemathcommand [mapsto] {\mapstochar\rightarrow}
+% \definemathcommand [hookrightarrow] {\lhook\joinrel\rightarrow}
+% \definemathcommand [hookleftarrow] {\leftarrow\joinrel\rhook}
+% \definemathcommand [bowtie] {\mathrel\triangleright\joinrel\mathrel\triangleleft}
+% \definemathcommand [models] {\mathrel|\joinrel=}
+% \definemathcommand [iff] {\;\Longleftrightarrow\;}
+
+% hm
+
+% ldots = 2026
+% vdots = 22EE
+% cdots = 22EF
+% ddots = 22F1
+% udots = 22F0
+
+% \def\PLAINldots{\ldotp\ldotp\ldotp}
+% \def\PLAINcdots{\cdotp\cdotp\cdotp}
+
+% \def\PLAINvdots
+% {\vbox{\baselineskip.4\bodyfontsize\lineskiplimit\zeropoint\kern.6\bodyfontsize\hbox{.}\hbox{.}\hbox{.}}}
+
+% \def\PLAINddots
+% {\mkern1mu%
+% \raise.7\bodyfontsize\vbox{\kern.7\bodyfontsize\hbox{.}}%
+% \mkern2mu%
+% \raise.4\bodyfontsize\relax\hbox{.}%
+% \mkern2mu%
+% \raise.1\bodyfontsize\hbox{.}%
+% \mkern1mu}
+
+% \definemathcommand [ldots] [inner] {\PLAINldots}
+% \definemathcommand [cdots] [inner] {\PLAINcdots}
+% \definemathcommand [vdots] [nothing] {\PLAINvdots}
+% \definemathcommand [ddots] [inner] {\PLAINddots}
+
+%D \starttyping
+%D $\sqrt[3]{10}$
+%D \stoptyping
+
+\def\rootradical{\Uroot 0 "221A } % can be done in char-def
+
+\def\root#1\of{\rootradical{#1}} % #2
+
+\unexpanded\def\sqrt{\doifnextoptionalelse\rootwithdegree\rootwithoutdegree}
+
+\def\rootwithdegree [#1]{\rootradical{#1}}
+\def\rootwithoutdegree {\rootradical {}}
+
+\def\PLAINmatrix#1%
+ {\null\,\vcenter{\normalbaselines\mathsurround\zeropoint
+ \ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
+ \mathstrut\crcr\noalign{\kern-\baselineskip}
+ #1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}\,}
+
+\definemathcommand [mathstrut] {\vphantom{(}}
+\definemathcommand [joinrel] {\mathrel{\mkern-3mu}}
+
+% \definemathcommand [matrix] {\PLAINmatrix}
+% \definemathcommand [over] {\normalover} % hack, to do
+
+\unexpanded\def\{{\mathortext\lbrace\letterleftbrace }
+\unexpanded\def\}{\mathortext\rbrace\letterrightbrace}
+
+%D The following colon related definitions are provided by Aditya
+%D Mahajan who derived them from \type {mathtools.sty} and \type
+%D {colonequals.sty}.
+
+%D \macros
+%D {centercolon, colonminus, minuscolon, colonequals, equalscolon,
+%D colonapprox, approxcolon, colonsim, simcolon, coloncolon,
+%D coloncolonminus, minuscoloncolon, coloncolonequals,
+%D equalscoloncolon, coloncolonapprox, approxcoloncolon,
+%D colonsim, simcoloncolon}
+%D
+%D In $a := b$ the colon is not vertically centered with the equal
+%D to. Also the distance between colon and equal to is a bit large.
+%D So, we define a vertically centered colon \tex {centercolon} and
+%D a few macros for colon and double colon relation symbols.
+%D
+%D \startlines
+%D \formula {A \centercolon B}
+%D \formula {A \colonminus B}
+%D \formula {A \minuscolon B}
+%D \formula {A \colonequals B}
+%D \formula {A \equalscolon B}
+%D \formula {A \colonapprox B}
+%D \formula {A \approxcolon B}
+%D \formula {A \colonsim B}
+%D \formula {A \simcolon B}
+%D \formula {A \coloncolon B}
+%D \formula {A \coloncolonminus B}
+%D \formula {A \minuscoloncolon B}
+%D \formula {A \coloncolonequals B}
+%D \formula {A \equalscoloncolon B}
+%D \formula {A \coloncolonapprox B}
+%D \formula {A \approxcoloncolon B}
+%D \formula {A \colonsim B}
+%D \formula {A \simcoloncolon B}
+%D \stoplines
+
+%D The next macros take care of the space between the colon and the
+%D relation symbol.
+
+\definemathcommand [colonsep] {\mkern-1.2mu}
+\definemathcommand [doublecolonsep] {\mkern-0.9mu}
+
+%D The next macro vertically centeres its contents.
+
+\def\@center@math#1%
+ {\vcenter{\hbox{$\mathsurround\zeropoint#1$}}}
+
+\def\@center@colon
+ {\mathpalette\@center@math{\colon}}
+
+%D Now we define all the colon relations.
+
+\definemathcommand [centercolon] [rel] {\@center@colon}
+\definemathcommand [colonminus] [rel] {\centercolon\colonsep\mathrel{-}}
+\definemathcommand [minuscolon] [rel] {\mathrel{-}\colonsep\centercolon}
+\definemathcommand [colonequals] [rel] {\centercolon\colonsep=}
+\definemathcommand [equalscolon] [rel] {=\centercolon\colonsep}
+\definemathcommand [colonapprox] [rel] {\centercolon\colonsep\approx}
+\definemathcommand [approxcolon] [rel] {\approx\centercolon\colonsep}
+\definemathcommand [colonsim] [rel] {\centercolon\colonsep\sim}
+\definemathcommand [simcolon] [rel] {\sim\centercolon\colonsep}
+
+\definemathcommand [coloncolon] [rel] {\centercolon\doublecolonsep\centercolon}
+\definemathcommand [coloncolonminus] [rel] {\coloncolon\colonsep\mathrel{-}}
+\definemathcommand [minuscoloncolon] [rel] {\mathrel{-}\colonsep\coloncolon}
+\definemathcommand [coloncolonequals] [rel] {\coloncolon\colonsep=}
+\definemathcommand [equalscoloncolon] [rel] {=\coloncolon\colonsep}
+\definemathcommand [coloncolonapprox] [rel] {\coloncolon\colonsep\approx}
+\definemathcommand [approxcoloncolon] [rel] {\approx\coloncolon\colonsep}
+\definemathcommand [colonsim] [rel] {\coloncolon\colonsep\sim}
+\definemathcommand [simcoloncolon] [rel] {\sim\coloncolon\colonsep}
+
+%D Goodies. We might move this elsewhere.
+
+\def\underleftarrow #1{\mathop{\Uunderdelimiter 0 "2190 {#1}}}
+\def\overleftarrow #1{\mathop{\Uoverdelimiter 0 "2190 {#1}}}
+\def\underrightarrow#1{\mathop{\Uunderdelimiter 0 "2192 {#1}}}
+\def\overrightarrow #1{\mathop{\Uoverdelimiter 0 "2192 {#1}}}
+
+% todo: \Udelimiterover, \Udelimiterunder
+
+\def\normaldoublebrace {\Umathaccents 0 0 "23DE 0 0 "23DF }
+\def\normaldoubleparent{\Umathaccents 0 0 "23DC 0 0 "23DD }
+
+\let\normaloverbrace \overbrace
+\let\normalunderbrace \underbrace
+\let\normaloverparent \overparent
+\let\normalunderparent \underparent
+\let\normalunderleftarrow \underleftarrow
+\let\normaloverleftarrow \overleftarrow
+\let\normalunderrightarrow\underrightarrow
+\let\normaloverrightarrow \overrightarrow
+
+\unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits}
+\unexpanded\def\stackrel #1#2{\mathrel{\mathop{#2}\limits^{#1}}}
+
+\unexpanded\def\overbrace {\mathopwithlimits\normaloverbrace }
+\unexpanded\def\underbrace {\mathopwithlimits\normalunderbrace }
+\unexpanded\def\doublebrace {\mathopwithlimits\normaldoublebrace }
+\unexpanded\def\overparent {\mathopwithlimits\normaloverparent }
+\unexpanded\def\underparent {\mathopwithlimits\normalunderparent }
+\unexpanded\def\doubleparent {\mathopwithlimits\normaldoubleparent }
+\unexpanded\def\underleftarrow {\mathopwithlimits\normalunderleftarrow }
+\unexpanded\def\overleftarrow {\mathopwithlimits\normaloverleftarrow }
+\unexpanded\def\underrightarrow{\mathopwithlimits\normalunderrightarrow}
+\unexpanded\def\overrightarrow {\mathopwithlimits\normaloverrightarrow }
+
+% todo mathclass=punctuation ord
+
+% \Umathcode"02C="6 "0 "02C
+% \Umathcode"02E="0 "0 "02E
+
+% tricky .. todo
+
+\appendtoks
+ \def\over{\primitive\over}%
+\to \everymathematics
+
+\protect \endinput
diff --git a/tex/context/base/math-del.mkiv b/tex/context/base/math-del.mkiv
new file mode 100644
index 000000000..5ffda1919
--- /dev/null
+++ b/tex/context/base/math-del.mkiv
@@ -0,0 +1,63 @@
+%D \module
+%D [ file=math-del,
+%D version=2007.07.19,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Delimiters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Delimiters}
+
+\unprotect
+
+%D \macros
+%D {checkdelimiters, fakeleftdelimiter, fakerightdelimiter}
+%D
+%D Handy for non matching situations (as with mathml):
+%D
+%D \starttyping
+%D \checkdelimiters{... bla bla ...}
+%D \fakeleftdelimiter
+%D ... bla bla ...
+%D \fakerightdelimiter
+%D \stoptyping
+
+\newcount\delimitercount
+
+\def\leftfakedelimiter {\advance\delimitercount\minusone\gobbleoneargument}%
+\def\rightfakedelimiter{\advance\delimitercount\plusone \gobbleoneargument}%
+
+\def\checkdelimiters#1%
+ {\delimitercount\zerocount
+ \setbox\scratchbox\hbox\bgroup
+ \let\left \leftfakedelimiter
+ \let\right\rightfakedelimiter
+ $#1\expandafter$\expandafter
+ \egroup
+ \expandafter\delimitercount\the\delimitercount\relax}
+
+\def\fakeleftdelimiter {\ifnum\delimitercount>\zerocount\left .\fi}
+\def\fakerightdelimiter{\ifnum\delimitercount<\zerocount\right.\fi}
+
+%D The following macros are used in the MathML interpreter, so
+%D there is a good change of them never being documented for
+%D other usage.
+
+\let\normalordelimiter\secondoftwoarguments
+\let\normalorfiller \firstoftwoarguments
+
+\def\enabledelimiter {\let\normalordelimiter\secondoftwoarguments}
+\def\disabledelimiter{\let\normalordelimiter\firstoftwoarguments}
+
+\def\enablefiller {\let\normalorfiller\secondoftwoarguments}
+\def\disablefiller {\let\normalorfiller\firstoftwoarguments}
+
+\def\mathopnolimits#1{\mathop{\mr#1}\nolimits} % was \rm, which follows text fonts (used in mml parser)
+\def\mathopdolimits#1{\mathop{\mr#1}} % was \rm, which follows text fonts (used in mml parser)
+
+\protect \endinput
diff --git a/tex/context/base/math-dim.lua b/tex/context/base/math-dim.lua
new file mode 100644
index 000000000..a536f0309
--- /dev/null
+++ b/tex/context/base/math-dim.lua
@@ -0,0 +1,310 @@
+if not modules then modules = { } end modules ['math-dim'] = {
+ version = 1.001,
+ comment = "companion to math-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Beware: only Taco really understands in depth what these dimensions do so
+-- if you run into problems ...
+
+local abs, next = math.abs, next
+
+mathematics = mathematics or { }
+
+local defaults = {
+ ['axis']={
+ ['default']={ "AxisHeight", "axis_height" },
+ },
+ ['accent_base_height']={
+ ['default']={ "AccentBaseHeight", "x_height" },
+ },
+ ['fraction_del_size']={
+ ['default']={ "0", "delim2" },
+ ['cramped_display_style']={ "0", "delim1" },
+ ['display_style']={ "0", "delim1" },
+ },
+ ['fraction_denom_down']={
+ ['default']={ "FractionDenominatorShiftDown", "denom2" },
+ ['cramped_display_style']={ "FractionDenominatorDisplayStyleShiftDown", "denom1" },
+ ['display_style']={ "FractionDenominatorDisplayStyleShiftDown", "denom1" },
+ },
+ ['fraction_denom_vgap']={
+ ['default']={ "FractionDenominatorGapMin", "default_rule_thickness" },
+ ['cramped_display_style']={ "FractionDenominatorDisplayStyleGapMin", "3*default_rule_thickness" },
+ ['display_style']={ "FractionDenominatorDisplayStyleGapMin", "3*default_rule_thickness" },
+ },
+ ['fraction_num_up']={
+ ['default']={ "FractionNumeratorShiftUp", "num2" },
+ ['cramped_display_style']={ "FractionNumeratorDisplayStyleShiftUp", "num1" },
+ ['display_style']={ "FractionNumeratorDisplayStyleShiftUp", "num1" },
+ },
+ ['fraction_num_vgap']={
+ ['default']={ "FractionNumeratorGapMin", "default_rule_thickness" },
+ ['cramped_display_style']={ "FractionNumeratorDisplayStyleGapMin", "3*default_rule_thickness" },
+ ['display_style']={ "FractionNumeratorDisplayStyleGapMin", "3*default_rule_thickness" },
+ },
+ ['fraction_rule']={
+ ['default']={ "FractionRuleThickness", "default_rule_thickness" },
+ },
+ ['limit_above_bgap']={
+ ['default']={ "UpperLimitBaselineRiseMin", "big_op_spacing3" },
+ },
+ ['limit_above_kern']={
+ ['default']={ "0", "big_op_spacing5" },
+ },
+ ['limit_above_vgap']={
+ ['default']={ "UpperLimitGapMin", "big_op_spacing1" },
+ },
+ ['limit_below_bgap']={
+ ['default']={ "LowerLimitBaselineDropMin", "big_op_spacing4" },
+ },
+ ['limit_below_kern']={
+ ['default']={ "0", "big_op_spacing5" },
+ },
+ ['limit_below_vgap']={
+ ['default']={ "LowerLimitGapMin", "big_op_spacing2" },
+ },
+
+--~ ['....']={
+--~ ['default']={ "DisplayOperatorMinHeight", "....." },
+--~ },
+
+ ['overbar_kern']={
+ ['default']={ "OverbarExtraAscender", "default_rule_thickness" },
+ },
+ ['overbar_rule']={
+ ['default']={ "OverbarRuleThickness", "default_rule_thickness" },
+ },
+ ['overbar_vgap']={
+ ['default']={ "OverbarVerticalGap", "3*default_rule_thickness" },
+ },
+ ['quad']={
+ ['default']={ "font_size(f)", "math_quad" },
+ },
+ ['radical_kern']={
+ ['default']={ "RadicalExtraAscender", "default_rule_thickness" },
+ },
+ ['radical_rule']={
+ ['default']={ "RadicalRuleThickness", "<not set>" },
+ },
+ ['radical_vgap']={
+ ['default']={ "RadicalVerticalGap", "default_rule_thickness+(abs(default_rule_thickness)/4)" },
+ ['display_style']={ "RadicalDisplayStyleVerticalGap", "default_rule_thickness+(abs(math_x_height)/4)" },
+ },
+ ['space_after_script']={
+ ['default']={ "SpaceAfterScript", "script_space" },
+ },
+ ['stack_denom_down']={
+ ['default']={ "StackBottomShiftDown", "denom2" },
+ ['cramped_display_style']={ "StackBottomDisplayStyleShiftDown", "denom1" },
+ ['display_style']={ "StackBottomDisplayStyleShiftDown", "denom1" },
+ },
+ ['stack_num_up']={
+ ['default']={ "StackTopShiftUp", "num3" },
+ ['cramped_display_style']={ "StackTopDisplayStyleShiftUp", "num1" },
+ ['display_style']={ "StackTopDisplayStyleShiftUp", "num1" },
+ },
+ ['stack_vgap']={
+ ['default']={ "StackGapMin", "3*default_rule_thickness" },
+ ['cramped_display_style']={ "StackDisplayStyleGapMin", "7*default_rule_thickness" },
+ ['display_style']={ "StackDisplayStyleGapMin", "7*default_rule_thickness" },
+ },
+ ['sub_shift_down']={
+ ['default']={ "SubscriptShiftDown", "sub1" },
+ },
+ ['sub_shift_drop']={
+ ['default']={ "SubscriptBaselineDropMin", "sub_drop" },
+ },
+ ['sub_sup_shift_down']={
+ ['default']={ "SubscriptShiftDown", "sub2" },
+ },
+ ['sub_top_max']={
+ ['default']={ "SubscriptTopMax", "abs(math_x_height*4)/5" },
+ },
+ ['subsup_vgap']={
+ ['default']={ "SubSuperscriptGapMin", "4*default_rule_thickness" },
+ },
+ ['sup_bottom_min']={
+ ['default']={ "SuperscriptBottomMin", "abs(math_x_height)/4" },
+ },
+ ['sup_shift_drop']={
+ ['default']={ "SuperscriptBaselineDropMax", "sup_drop" },
+ },
+ ['sup_shift_up']={
+ ['cramped_display_style']={ "SuperscriptShiftUpCramped", "sup3" },
+ ['cramped_script_script_style']={ "SuperscriptShiftUpCramped", "sup3" },
+ ['cramped_script_style']={ "SuperscriptShiftUpCramped", "sup3" },
+ ['cramped_text_style']={ "SuperscriptShiftUpCramped", "sup3" },
+ ['display_style']={ "SuperscriptShiftUp", "sup1" },
+ ['script_script_style']={ "SuperscriptShiftUp", "sup2" },
+ ['script_style']={ "SuperscriptShiftUp", "sup2" },
+ ['text_style']={ "SuperscriptShiftUp", "sup2" },
+ },
+ ['sup_sub_bottom_max']={
+ ['default']={ "SuperscriptBottomMaxWithSubscript", "abs(math_x_height*4)/5" },
+ },
+ ['underbar_kern']={
+ ['default']={ "UnderbarExtraDescender", "0" },
+ },
+ ['underbar_rule']={
+ ['default']={ "UnderbarRuleThickness", "default_rule_thickness" },
+ },
+ ['underbar_vgap']={
+ ['default']={ "UnderbarVerticalGap", "3*default_rule_thickness" },
+ },
+ ['connector_overlap_min']={
+ ['default']={ "MinConnectorOverlap", "0.25*default_rule_thickness" },
+ },
+ ['over_delimiter_vgap']={
+ ['default']={ "StretchStackGapBelowMin", "big_op_spacing1" },
+ },
+ ['over_delimiter_bgap']={
+ ['default']={ "StretchStackTopShiftUp", "big_op_spacing3" },
+ },
+ ['under_delimiter_vgap']={
+ ['default']={ "StretchStackGapAboveMin", "big_op_spacing2" },
+ },
+ ['under_delimiter_bgap']={
+ ['default']={ "StretchStackBottomShiftDown", "big_op_spacing4" },
+ },
+ ['radical_degree_before']={
+ ['default']={ "RadicalKernBeforeDegree", "(5/18)*quad" },
+ },
+ ['radical_degree_after']={
+ ['default']={ "RadicalKernAfterDegree", "(-10/18)*quad" },
+ },
+ ['radical_degree_raise']={
+ ['default']={ "RadicalDegreeBottomRaisePercent", "60" },
+ },
+}
+
+local styles = {
+ 'cramped_display_style',
+ 'cramped_script_script_style',
+ 'cramped_script_style',
+ 'cramped_text_style',
+ 'display_style',
+ 'script_script_style',
+ 'script_style',
+ 'text_style',
+}
+
+for k, v in next, defaults do
+ for _, s in next, styles do
+ if not v[s] then
+ v[s] = v.default
+ end
+ end
+end
+
+-- we cannot use a metatable because we do a copy (takes a bit more work)
+--
+-- local mt = { } setmetatable(defaults,mt)
+--
+-- mt.__index = function(t,s)
+-- texio.write_nl("GETTING " .. s)
+-- return t.default or t.text_style or 0
+-- end
+
+function mathematics.dimensions(dimens)
+ if dimens.SpaceAfterScript then
+ return { }, table.fastcopy(dimens)
+ elseif dimens.AxisHeight or dimens.axis_height then
+ local t = { }
+ local math_x_height = dimens.x_height or 10*65526
+ local math_quad = dimens.quad or 10*65526
+ local default_rule_thickness = dimens.FractionDenominatorGapMin or dimens.default_rule_thickness or 0.4*65526
+ dimens["0"] = 0
+ dimens["60"] = 60
+ dimens["0.25*default_rule_thickness"] = default_rule_thickness / 4
+ dimens["3*default_rule_thickness"] = 3 * default_rule_thickness
+ dimens["4*default_rule_thickness"] = 4 * default_rule_thickness
+ dimens["7*default_rule_thickness"] = 7 * default_rule_thickness
+ dimens["(5/18)*quad"] = (math_quad * 5) / 18
+ dimens["(-10/18)*quad"] = - (math_quad * 10) / 18
+ dimens["abs(math_x_height*4)/5"] = abs(math_x_height * 4) / 5
+ dimens["default_rule_thickness+(abs(default_rule_thickness)/4)"] = default_rule_thickness+(abs(default_rule_thickness) / 4)
+ dimens["default_rule_thickness+(abs(math_x_height)/4)"] = default_rule_thickness+(abs(math_x_height) / 4)
+ dimens["abs(math_x_height)/4"] = abs(math_x_height) / 4
+ dimens["abs(math_x_height*4)/5"] = abs(math_x_height * 4) / 5
+ dimens["<not set>"] = false
+ dimens["script_space"] = false -- at macro level
+ for variable, styles in next, defaults do
+ local tt = { }
+ for style, default in next, styles do
+ local one, two = default[1], default[2]
+ local value = dimens[one]
+ if value then
+ tt[style] = value
+ else
+ value = dimens[two]
+ if value == false then
+ tt[style] = nil
+ else
+ tt[style] = value or 0
+ end
+ end
+ end
+ t[variable] = tt
+ end
+ local d = {
+ AxisHeight = t . axis . text_style,
+ AccentBaseHeight = t . accent_base_height . text_style,
+ FractionDenominatorDisplayStyleGapMin = t . fraction_denom_vgap . display_style,
+ FractionDenominatorDisplayStyleShiftDown = t . fraction_denom_down . display_style,
+ FractionDenominatorGapMin = t . fraction_denom_vgap . text_style,
+ FractionDenominatorShiftDown = t . fraction_denom_down . text_style,
+ FractionNumeratorDisplayStyleGapMin = t . fraction_num_vgap . display_style,
+ FractionNumeratorDisplayStyleShiftUp = t . fraction_num_up . display_style,
+ FractionNumeratorGapMin = t . fraction_num_vgap . text_style,
+ FractionNumeratorShiftUp = t . fraction_num_up . text_style,
+ FractionRuleThickness = t . fraction_rule . text_style,
+ LowerLimitBaselineDropMin = t . limit_below_bgap . text_style,
+ LowerLimitGapMin = t . limit_below_vgap . text_style,
+ OverbarExtraAscender = t . overbar_kern . text_style,
+ OverbarRuleThickness = t . overbar_rule . text_style,
+ OverbarVerticalGap = t . overbar_vgap . text_style,
+ RadicalDisplayStyleVerticalGap = t . radical_vgap . display_style,
+ RadicalExtraAscender = t . radical_kern . text_style,
+ RadicalRuleThickness = t . radical_rule . text_style,
+ RadicalVerticalGap = t . radical_vgap . text_style,
+ RadicalKernBeforeDegree = t . radical_degree_before . display_style,
+ RadicalKernAfterDegree = t . radical_degree_after . display_style,
+ RadicalDegreeBottomRaisePercent = t . radical_degree_raise . display_style,
+ SpaceAfterScript = t . space_after_script . text_style,
+ StackBottomDisplayStyleShiftDown = t . stack_denom_down . display_style,
+ StackBottomShiftDown = t . stack_denom_down . text_style,
+ StackDisplayStyleGapMin = t . stack_vgap . display_style,
+ StackGapMin = t . stack_vgap . text_style,
+ StackTopDisplayStyleShiftUp = t . stack_num_up . display_style,
+ StackTopShiftUp = t . stack_num_up . text_style,
+ SubscriptBaselineDropMin = t . sub_shift_drop . text_style,
+ SubscriptShiftDown = t . sub_shift_down . text_style,
+ SubscriptTopMax = t . sub_top_max . text_style,
+ SubSuperscriptGapMin = t . subsup_vgap . text_style,
+ SuperscriptBaselineDropMax = t . sup_shift_drop . text_style,
+ SuperscriptBottomMaxWithSubscript = t . sup_sub_bottom_max . text_style,
+ SuperscriptBottomMin = t . sup_bottom_min . text_style,
+ SuperscriptShiftUp = t . sup_shift_up . text_style,
+ SuperscriptShiftUpCramped = t . sup_shift_up . cramped_text_style,
+ UnderbarExtraDescender = t . underbar_kern . text_style,
+ UnderbarRuleThickness = t . underbar_rule . text_style,
+ UnderbarVerticalGap = t . underbar_vgap . text_style,
+ UpperLimitBaselineRiseMin = t . limit_above_bgap . text_style,
+ UpperLimitGapMin = t . limit_above_vgap . text_style,
+ MinConnectorOverlap = t . connector_overlap_min . text_style,
+ StretchStackGapBelowMin = t . over_delimiter_vgap . text_style,
+ StretchStackTopShiftUp = t . over_delimiter_bgap . text_style,
+ StretchStackGapAboveMin = t . under_delimiter_vgap . text_style,
+ StretchStackBottomShiftDown = t . under_delimiter_bgap . text_style,
+ }
+ d.AccentBaseHeight = 0
+ -- texio.write_nl(table.serialize(d))
+ return t, d -- this might change
+ else
+ return { }, { }
+ end
+end
+
diff --git a/tex/context/base/math-dis.mkiv b/tex/context/base/math-dis.mkiv
new file mode 100644
index 000000000..3eed2b162
--- /dev/null
+++ b/tex/context/base/math-dis.mkiv
@@ -0,0 +1,20 @@
+%D \module
+%D [ file=math-ali,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Display,
+%D author={Hans Hagen, Taco Hoekwater \& Aditya Mahajan},
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Math Macros / Display}
+
+\unprotect
+
+% display spacing code will move here
+
+\protect \endinput
diff --git a/tex/context/base/math-ext.lua b/tex/context/base/math-ext.lua
new file mode 100644
index 000000000..52dce0255
--- /dev/null
+++ b/tex/context/base/math-ext.lua
@@ -0,0 +1,143 @@
+if not modules then modules = { } end modules ['math-ext'] = {
+ version = 1.001,
+ comment = "companion to math-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end)
+
+mathematics = mathematics or { }
+characters = characters or { }
+
+mathematics.extras = mathematics.extras or { }
+characters.math = characters.math or { }
+
+local chardata = characters.data
+local mathdata = characters.math
+
+function mathematics.extras.add(unicode,t)
+ local min, max = mathematics.extrabase, mathematics.privatebase - 1
+ if unicode >= min and unicode <= max then
+ mathdata[unicode], chardata[unicode] = t, t
+ else
+ logs.report("math extra","extra U+%04X should be in range U+%04X - U+%04X",unicode,min,max)
+ end
+end
+
+function mathematics.extras.copy(tfmdata)
+ local math_parameters = tfmdata.math_parameters
+ local MathConstants = tfmdata.MathConstants
+ if (math_parameters and next(math_parameters)) or (MathConstants and next(MathConstants)) then
+ local characters = tfmdata.characters
+ for unicode, extradesc in next, mathdata do
+ -- always, because in an intermediate step we can have a non math font
+ local extrachar = characters[unicode]
+ local nextinsize = extradesc.nextinsize
+ if nextinsize then
+ for i=1,#nextinsize do
+ local nextslot = nextinsize[i]
+ local nextbase = characters[nextslot]
+ if nextbase then
+ local nextnext = nextbase and nextbase.next
+ if nextnext then
+ local nextchar = characters[nextnext]
+ if nextchar then
+ if trace_virtual then
+ logs.report("math extra","extra U+%04X in %s at %s maps on U+%04X (class: %s, name: %s)",unicode,file.basename(tfmdata.fullname),tfmdata.size,nextslot,extradesc.mathclass or "?",extradesc.mathname or "?")
+ end
+ characters[unicode] = nextchar
+ break
+ end
+ end
+ end
+ end
+ if not characters[unicode] then
+ for i=1,#nextinsize do
+ local nextbase = characters[nextinsize[i]]
+ if nextbase then
+ characters[unicode] = nextchar
+ break
+ end
+ end
+ end
+ end
+ end
+ else
+ -- let's not waste time on non-math
+ end
+end
+
+table.insert(fonts.tfm.mathactions,mathematics.extras.copy)
+
+-- 0xFE302 -- 0xFE320 for accents
+
+mathematics.extras.add(0xFE302, {
+ category="mn",
+ description="WIDE MATHEMATICAL HAT",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="accent",
+ mathname="widehat",
+ mathstretch="h",
+ unicodeslot=0xFE302,
+ nextinsize={ 0x00302, 0x0005E },
+} )
+
+mathematics.extras.add(0xFE303, {
+ category="mn",
+ cjkwd="a",
+ description="WIDE MATHEMATICAL TILDE",
+ direction="nsm",
+ linebreak="cm",
+ mathclass="accent",
+ mathname="widetilde",
+ mathstretch="h",
+ unicodeslot=0xFE303,
+ nextinsize={ 0x00303, 0x0007E },
+} )
+
+-- 0xFE321 -- 0xFE340 for missing characters
+
+-- mathematics.extras.add(0xFE321, {
+-- category="sm",
+-- description="SHORT BAR",
+-- -- direction="on",
+-- -- linebreak="nu",
+-- mathclass="relation",
+-- mathname="mapstochar",
+-- unicodeslot=0xFE321,
+-- } )
+
+
+
+
+
+--~ mathematics.extras.add(0xFE304, {
+--~ category="sm",
+--~ description="TOP AND BOTTOM PARENTHESES",
+--~ direction="on",
+--~ linebreak="al",
+--~ mathclass="doubleaccent",
+--~ mathname="doubleparent",
+--~ unicodeslot=0xFE304,
+--~ accents={ 0x023DC, 0x023DD },
+--~ } )
+
+--~ mathematics.extras.add(0xFE305, {
+--~ category="sm",
+--~ description="TOP AND BOTTOM BRACES",
+--~ direction="on",
+--~ linebreak="al",
+--~ mathclass="doubleaccent",
+--~ mathname="doublebrace",
+--~ unicodeslot=0xFE305,
+--~ accents={ 0x023DE, 0x023DF },
+--~ } )
+
+--~ \Umathchardef\braceld="0 "1 "FF07A
+--~ \Umathchardef\bracerd="0 "1 "FF07B
+--~ \Umathchardef\bracelu="0 "1 "FF07C
+--~ \Umathchardef\braceru="0 "1 "FF07D
+
diff --git a/tex/context/base/math-for.mkiv b/tex/context/base/math-for.mkiv
new file mode 100644
index 000000000..87aeaa4e0
--- /dev/null
+++ b/tex/context/base/math-for.mkiv
@@ -0,0 +1,73 @@
+%D \module
+%D [ file=strc-mat,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Math Numbering,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Math Formulas}
+
+%D This module only provides the code for defining formulas and
+%D fetching parameters. The action takes place later.
+
+\unprotect
+
+\let\currentformula\s!unknown
+
+\def\formulaparameter #1{\csname\doformulaparameter{\??fm\currentformula}#1\endcsname}
+\def\formulaparameterhash#1{\doformulaparameterhash {\??fm\currentformula}#1}
+
+\def\doformulaparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doformulaparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\doformulaparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doformulaparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\detokenizedformulaparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??fm\currentformula#1\endcsname}}
+
+\def\doformulaparentparameter #1#2{\ifx#1\relax\s!empty\else\doformulaparameter #1#2\fi}
+\def\doformulaparentparameterhash#1#2{\ifx#1\relax \else\doformulaparameterhash#1#2\fi}
+
+\def\dosetformulaattributes#1#2% style color
+ {\edef\fontattributehash {\formulaparameterhash#1}%
+ \edef\colorattributehash{\formulaparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+%D \macros
+%D {setupformulas}
+
+\newtoks \everysetupformulas
+
+\def\setupformulas
+ {\dodoubleempty\dosetupformulas}
+
+\def\dosetupformulas[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??fm#1][#2]%
+ \else
+ \getparameters[\??fm][#1]%
+ \fi
+ \the\everysetupformulas}
+
+%D Not yet cleanup up:
+
+%D \macros
+%D {setuptextformulas}
+%D
+%D This command sets up in||line math. Most features deals
+%D with grid snapping and are experimental.
+
+\newtoks \everysetuptextformulas
+
+\def\setuptextformulas
+ {\dosingleempty\dosetuptextformulas}
+
+\def\dosetuptextformulas[#1]%
+ {\getparameters[\??mt][#1]%
+ \the\everysetuptextformulas}
+
+\protect \endinput
diff --git a/tex/context/base/math-frc.mkii b/tex/context/base/math-frc.mkii
new file mode 100644
index 000000000..fa319bc4a
--- /dev/null
+++ b/tex/context/base/math-frc.mkii
@@ -0,0 +1,66 @@
+%D \module
+%D [ file=math-frc,
+%D version=2007.07.19,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Fractions,
+%D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan},
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Fractions}
+
+\unprotect
+
+\def\exmthfont#1{\symbolicsizedfont#1\plusone{MathExtension}}
+
+\def\domthfrac#1#2#3#4#5#6#7%
+ {\begingroup
+ \mathsurround\zeropoint
+ \setbox0\hbox{$#1 #6$}%
+ \setbox2\hbox{$#1 #7$}%
+ \dimen0\wd0
+ \ifdim\wd2>\dimen0 \dimen0\wd2 \fi
+ \setbox4\hbox to \dimen0{\exmthfont#2#3\leaders\hbox{#4}\hss#5}%
+ \mathord{\vcenter{{\offinterlineskip
+ \hbox to \dimen0{\hss\box0\hss}%
+ \kern \ht4%
+ \hbox to \dimen0{\hss\copy4\hss}%
+ \kern \ht4%
+ \hbox to \dimen0{\hss\box2\hss}}}}%
+ \endgroup}
+
+\def\domthsqrt#1#2#3#4#5%
+ {\begingroup
+ \mathsurround\zeropoint
+ \setbox0\hbox{$#1 #5$}%
+ \dimen0=1.05\ht0 \advance\dimen0 1pt \ht0 \dimen0
+ \dimen0=1.05\dp0 \advance\dimen0 1pt \dp0 \dimen0
+ \dimen0\wd0
+ \setbox4\hbox to \dimen0{\exmthfont#2\leaders\hbox{#3}\hfill#4}%
+ \delimitershortfall=0pt
+ \nulldelimiterspace=0pt
+ \setbox2\hbox{$\left\delimiter"0270370 \vrule height\ht0 depth \dp0 width0pt
+ \right.$}%
+ \mathord{\vcenter{\hbox{\copy2
+ \rlap{\raise\dimexpr\ht2-\ht4\relax\copy4}\copy0}}}%
+ \endgroup}
+
+\def\mthfrac#1#2#3#4#5{\mathchoice
+ {\domthfrac\displaystyle \textface {#1}{#2}{#3}{#4}{#5}}
+ {\domthfrac\textstyle \textface {#1}{#2}{#3}{#4}{#5}}
+ {\domthfrac\scriptstyle \scriptface {#1}{#2}{#3}{#4}{#5}}
+ {\domthfrac\scriptscriptstyle\scriptscriptface{#1}{#2}{#3}{#4}{#5}}}
+
+\def\mthsqrt#1#2#3{\mathchoice
+ {\domthsqrt\displaystyle \textface {#1}{#2}{#3}}
+ {\domthsqrt\textstyle \textface {#1}{#2}{#3}}
+ {\domthsqrt\scriptstyle \textface {#1}{#2}{#3}}
+ {\domthsqrt\scriptscriptstyle\textface {#1}{#2}{#3}}}
+
+% temp here
+
+\protect \endinput
diff --git a/tex/context/base/math-frc.mkiv b/tex/context/base/math-frc.mkiv
new file mode 100644
index 000000000..d40306199
--- /dev/null
+++ b/tex/context/base/math-frc.mkiv
@@ -0,0 +1,209 @@
+%D \module
+%D [ file=math-frc,
+%D version=2007.07.19,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Fractions,
+%D author={Hans Hagen \& Taco Hoekwater},
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Fractions}
+
+\unprotect
+
+%D \macros
+%D {frac, xfrac, xxfrac}
+%D
+%D This is another one Tobias asked for. It replaces the
+%D primitive \type {\over}. We also take the opportunity to
+%D handle math style restoring, which makes sure units and
+%D chemicals come out ok.
+%D The \type {\frac} macro kind of replaces the awkward \type
+%D {\over} primitive. Say that we have the following formulas:
+%D
+%D \startbuffer[sample]
+%D test $\frac {1}{2}$ test $$1 + \frac {1}{2} = 1.5$$
+%D test $\xfrac {1}{2}$ test $$1 + \xfrac {1}{2} = 1.5$$
+%D test $\xxfrac{1}{2}$ test $$1 + \xxfrac{1}{2} = 1.5$$
+%D \stopbuffer
+%D
+%D \typebuffer[sample]
+%D
+%D With the most straightforward definitions, we get:
+%D
+%D \startbuffer[code]
+%D \def\dofrac#1#2#3{\relax\mathematics{{{#1{#2}}\over{#1{#3}}}}}
+%D
+%D \def\frac {\dofrac\mathstyle}
+%D \def\xfrac {\dofrac\scriptstyle}
+%D \def\xxfrac{\dofrac\scriptscriptstyle}
+%D \stopbuffer
+%D
+%D \typebuffer[code] \getbuffer[code,sample]
+%D
+%D Since this does not work well, we can try:
+%D
+%D \startbuffer[code]
+%D \def\xfrac #1#2{\hbox{$\dofrac\scriptstyle {#1}{#2}$}}
+%D \def\xxfrac#1#2{\hbox{$\dofrac\scriptscriptstyle{#1}{#2}$}}
+%D \stopbuffer
+%D
+%D \typebuffer[code] \getbuffer[code,sample]
+%D
+%D This for sure looks better than:
+%D
+%D \startbuffer[code]
+%D \def\xfrac #1#2{{\scriptstyle \dofrac\relax{#1}{#2}}}
+%D \def\xxfrac#1#2{{\scriptscriptstyle\dofrac\relax{#1}{#2}}}
+%D \stopbuffer
+%D
+%D \typebuffer[code] \getbuffer[code,sample]
+%D
+%D So we stick to the next definitions (watch the local
+%D overloading of \type {\xfrac}).
+
+% \def\dofrac#1#2#3{\relax\mathematics{{{#1{#2}}\over{#1{#3}}}}}
+
+\def\dofrac#1#2#3{\relax\mathematics{\Ustack{{#1{#2}}\normalover{#1{#3}}}}}
+\def\nofrac #1#2{\relax\mathematics{\Ustack{{#1}\normalover{#2}}}}
+
+% \chardef\mathfracmode=0 $\frac{1}{2}$
+% \chardef\mathfracmode=1 $\frac{1}{2}$
+% \chardef\mathfracmode=2 $\frac{1}{2}$
+% \chardef\mathfracmode=3 $\frac{1}{2}$
+% \chardef\mathfracmode=4 $\frac{1}{2}$
+% \chardef\mathfracmode=5 $\frac{1}{2}$
+
+\chardef\mathfracmode=0 % 0=auto, 1=displaystyle, 2=textstyle, 3=scriptstyle, 4=scriptscriptstyle, 5=mathstyle
+
+\unexpanded\def\frac
+ {\ifcase\mathfracmode
+ \expandafter\nofrac
+ \or
+ \expandafter\dofrac\expandafter\displaystyle
+ \or
+ \expandafter\dofrac\expandafter\textstyle
+ \or
+ \expandafter\dofrac\expandafter\scriptstyle
+ \or
+ \expandafter\dofrac\expandafter\scriptscriptstyle
+ \else
+ \expandafter\dofrac\expandafter\mathstyle
+ \fi}
+
+\unexpanded\def\xfrac#1#2%
+ {\begingroup
+ \let\xfrac\xxfrac
+ \dofrac\scriptstyle{#1}{#2}%
+ \endgroup}
+
+\unexpanded\def\xxfrac#1#2%
+ {\begingroup
+ \dofrac\scriptscriptstyle{#1}{#2}%
+ \endgroup}
+
+%D The \type {xx} variant looks still ugly, so maybe it's
+%D best to say:
+
+\unexpanded\def\xxfrac#1#2%
+ {\begingroup
+ \dofrac\scriptscriptstyle{#1}{\raise.25ex\hbox{$\scriptscriptstyle#2$}}%
+ \endgroup}
+
+%D Something low level for scientific calculator notation:
+
+\unexpanded\def\scinot#1#2%
+ {#1\times10^{#2}}
+
+%D The next macro, \type {\ch}, is \PPCHTEX\ aware. In
+%D formulas one can therefore best use \type {\ch} instead of
+%D \type {\chemical}, especially in fractions.
+
+% let's see who complains ... \mathstyle is now a primitive
+%
+% \unexpanded\def\ch#1%
+% {\ifundefined\@@chemicalletter
+% \mathstyle{\rm#1}%
+% \else
+% \dosetsubscripts
+% \mathstyle{\@@chemicalletter{#1}}%
+% \doresetsubscripts
+% \fi}
+
+% \unexpanded\def\ch#1%
+% {\ifundefined\@@chemicalletter
+% \mathematics{\rm#1}%
+% \else
+% \dosetsubscripts
+% \mathematics{\@@chemicalletter{#1}}%
+% \doresetsubscripts
+% \fi}
+
+%D \macros
+%D {/}
+%D
+%D Just to be sure, we restore the behavior of some typical
+%D math characters.
+
+\bgroup
+
+\catcode`\/=\@@other \global \let\normalforwardslash/
+\catcode`\/=\@@active \doglobal\appendtoks\let/\normalforwardslash\to\everymathematics
+
+\egroup
+
+% to be checked:
+
+\def\exmthfont#1{\symbolicsizedfont#1\plusone{MathExtension}}
+
+\def\domthfrac#1#2#3#4#5#6#7%
+ {\begingroup
+ \mathsurround\zeropoint
+ \setbox0\hbox{$#1 #6$}%
+ \setbox2\hbox{$#1 #7$}%
+ \dimen0\wd0
+ \ifdim\wd2>\dimen0 \dimen0\wd2 \fi
+ \setbox4\hbox to \dimen0{\exmthfont#2#3\leaders\hbox{#4}\hss#5}%
+ \mathord{\vcenter{{\offinterlineskip
+ \hbox to \dimen0{\hss\box0\hss}%
+ \kern \ht4%
+ \hbox to \dimen0{\hss\copy4\hss}%
+ \kern \ht4%
+ \hbox to \dimen0{\hss\box2\hss}}}}%
+ \endgroup}
+
+\def\domthsqrt#1#2#3#4#5%
+ {\begingroup
+ \mathsurround\zeropoint
+ \setbox0\hbox{$#1 #5$}%
+ \dimen0=1.05\ht0 \advance\dimen0 1pt \ht0 \dimen0
+ \dimen0=1.05\dp0 \advance\dimen0 1pt \dp0 \dimen0
+ \dimen0\wd0
+ \setbox4\hbox to \dimen0{\exmthfont#2\leaders\hbox{#3}\hfill#4}%
+ \delimitershortfall=0pt
+ \nulldelimiterspace=0pt
+ \setbox2\hbox{$\left\delimiter"0270370 \vrule height\ht0 depth \dp0 width0pt
+ \right.$}%
+ \mathord{\vcenter{\hbox{\copy2
+ \rlap{\raise\dimexpr\ht2-\ht4\relax\copy4}\copy0}}}%
+ \endgroup}
+
+\def\mthfrac#1#2#3#4#5{\mathchoice
+ {\domthfrac\displaystyle \textface {#1}{#2}{#3}{#4}{#5}}
+ {\domthfrac\textstyle \textface {#1}{#2}{#3}{#4}{#5}}
+ {\domthfrac\scriptstyle \scriptface {#1}{#2}{#3}{#4}{#5}}
+ {\domthfrac\scriptscriptstyle\scriptscriptface{#1}{#2}{#3}{#4}{#5}}}
+
+\def\mthsqrt#1#2#3{\mathchoice
+ {\domthsqrt\displaystyle \textface {#1}{#2}{#3}}
+ {\domthsqrt\textstyle \textface {#1}{#2}{#3}}
+ {\domthsqrt\scriptstyle \textface {#1}{#2}{#3}}
+ {\domthsqrt\scriptscriptstyle\textface {#1}{#2}{#3}}}
+
+% temp here
+
+\protect \endinput
diff --git a/tex/context/base/math-ini.lua b/tex/context/base/math-ini.lua
index 73b8852b3..5a6889410 100644
--- a/tex/context/base/math-ini.lua
+++ b/tex/context/base/math-ini.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['math-ini'] = {
+if not modules then modules = { } end modules ['math-ext'] = {
version = 1.001,
comment = "companion to math-ini.tex",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -6,443 +6,249 @@ if not modules then modules = { } end modules ['math-ini'] = {
license = "see context related readme files"
}
---[[ldx--
-<p>Math definitions. This code may move.</p>
---ldx]]--
-
-- if needed we can use the info here to set up xetex definition files
-- the "8000 hackery influences direct characters (utf) as indirect \char's
+local utf = unicode.utf8
+
local texsprint, format, utfchar, utfbyte = tex.sprint, string.format, utf.char, utf.byte
-mathematics = mathematics or { }
-mathematics.data = mathematics.data or { }
-mathematics.slots = mathematics.slots or { }
+local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
-mathematics.classes = {
- ord = 0, -- mathordcomm mathord
- op = 1, -- mathopcomm mathop
- bin = 2, -- mathbincomm mathbin
- rel = 3, -- mathrelcomm mathrel
- open = 4, -- mathopencomm mathopen
- close = 5, -- mathclosecomm mathclose
- punct = 6, -- mathpunctcomm mathpunct
- alpha = 7, -- mathalphacomm firstofoneargument
- accent = 8,
- radical = 9,
- inner = 0, -- mathinnercomm mathinner
- nothing = 0, -- mathnothingcomm firstofoneargument
- choice = 0, -- mathchoicecomm @@mathchoicecomm
- box = 0, -- mathboxcomm @@mathboxcomm
- limop = 1, -- mathlimopcomm @@mathlimopcomm
- nolop = 1, -- mathnolopcomm @@mathnolopcomm
-}
+mathematics = mathematics or { }
-mathematics.classes.alphabetic = mathematics.classes.alpha
-mathematics.classes.unknown = mathematics.classes.nothing
-mathematics.classes.punctuation = mathematics.classes.punct
-mathematics.classes.normal = mathematics.classes.nothing
-mathematics.classes.opening = mathematics.classes.open
-mathematics.classes.closing = mathematics.classes.close
-mathematics.classes.binary = mathematics.classes.bin
-mathematics.classes.relation = mathematics.classes.rel
-mathematics.classes.fence = mathematics.classes.unknown
-mathematics.classes.diacritic = mathematics.classes.accent
-mathematics.classes.large = mathematics.classes.op
-mathematics.classes.variable = mathematics.classes.alphabetic
-mathematics.classes.number = mathematics.classes.nothing
+mathematics.extrabase = 0xFE000 -- here we push some virtuals
+mathematics.privatebase = 0xFF000 -- here we push the ex
-mathematics.families = {
- mr = 0, bs = 8,
- mi = 1, bi = 9,
- sy = 2, sc = 10,
- ex = 3, tf = 11,
- it = 4, ma = 12,
- sl = 5, mb = 13,
- bf = 6, mc = 14,
- nn = 7, md = 15,
+local families = {
+ tf = 0, it = 1, sl = 2, bf = 3, bi = 4, bs = 5, -- virtual fonts or unicode otf
}
-mathematics.families.letters = mathematics.families.mr
-mathematics.families.numbers = mathematics.families.mr
-mathematics.families.variables = mathematics.families.mi
-mathematics.families.operators = mathematics.families.sy
-mathematics.families.lcgreek = mathematics.families.mi
-mathematics.families.ucgreek = mathematics.families.mr
-mathematics.families.vargreek = mathematics.families.mi
-mathematics.families.mitfamily = mathematics.families.mi
-mathematics.families.calfamily = mathematics.families.sy
-
-mathematics.families[0] = mathematics.families.mr
-mathematics.families[1] = mathematics.families.mi
-mathematics.families[2] = mathematics.families.sy
-mathematics.families[3] = mathematics.families.ex
+local classes = {
+ ord = 0, -- mathordcomm mathord
+ op = 1, -- mathopcomm mathop
+ bin = 2, -- mathbincomm mathbin
+ rel = 3, -- mathrelcomm mathrel
+ open = 4, -- mathopencomm mathopen
+ close = 5, -- mathclosecomm mathclose
+ punct = 6, -- mathpunctcomm mathpunct
+ alpha = 7, -- mathalphacomm firstofoneargument
+ accent = 8, -- class 0
+ radical = 9,
+ xaccent = 10, -- class 3
+ topaccent = 11, -- class 0
+ botaccent = 12, -- class 0
+ under = 13,
+ over = 14,
+ delimiter = 15,
+ inner = 0, -- mathinnercomm mathinner
+ nothing = 0, -- mathnothingcomm firstofoneargument
+ choice = 0, -- mathchoicecomm @@mathchoicecomm
+ box = 0, -- mathboxcomm @@mathboxcomm
+ limop = 1, -- mathlimopcomm @@mathlimopcomm
+ nolop = 1, -- mathnolopcomm @@mathnolopcomm
+}
-function mathematics.mathcode(target,class,family,slot)
- if class <= 7 then
- return ("\\omathcode%s=\"%X%02X%04X "):format(target,class,family,slot)
- end
+mathematics.families = families
+mathematics.classes = classes
+
+classes.alphabetic = classes.alpha
+classes.unknown = classes.nothing
+classes.default = classes.nothing
+classes.punctuation = classes.punct
+classes.normal = classes.nothing
+classes.opening = classes.open
+classes.closing = classes.close
+classes.binary = classes.bin
+classes.relation = classes.rel
+classes.fence = classes.unknown
+classes.diacritic = classes.accent
+classes.large = classes.op
+classes.variable = classes.alphabetic
+classes.number = classes.alphabetic
+
+-- there will be proper functions soon (and we will move this code in-line)
+
+local function delcode(target,family,slot)
+ return format('\\Udelcode%s="%X "%X ',target,family,slot)
+end
+local function mathchar(class,family,slot)
+ return format('\\Umathchar "%X "%X "%X ',class,family,slot)
+end
+local function mathaccent(class,family,slot)
+ return format('\\Umathaccent "%X "%X "%X ',0,family,slot) -- no class
+end
+local function delimiter(class,family,slot)
+ return format('\\Udelimiter "%X "%X "%X ',class,family,slot)
end
-function mathematics.delcode(target,small_family,small_slot,large_family,large_slot)
- return ("\\odelcode%s=\"%02X%04X\"%02X%04X "):format(target,small_family,small_slot,large_family,large_slot)
+local function radical(family,slot)
+ return format('\\Uradical "%X "%X ',family,slot)
end
-function mathematics.radical(small_family,small_slot,large_family,large_slot)
- return ("\\radical%s=\"%02X%04X%\"02X%04X "):format(target,small_family,small_slot,large_family,large_slot)
+local function mathchardef(name,class,family,slot)
+ return format('\\Umathchardef\\%s "%X "%X "%X ',name,class,family,slot)
end
-function mathematics.mathchar(class,family,slot)
- return ("\\omathchar\"%X%02X%04X "):format(class,family,slot)
+local function mathcode(target,class,family,slot)
+ return format('\\Umathcode%s="%X "%X "%X ',target,class,family,slot)
end
-function mathematics.mathaccent(class,family,slot)
- return ("\\omathaccent\"%X%02X%04X "):format(class,family,slot)
+local function mathtopaccent(class,family,slot)
+ return format('\\Umathaccent "%X "%X "%X ',0,family,slot) -- no class
end
-function mathematics.delimiter(class,family,slot,largefamily,largeslot)
- return ("\\odelimiter\"%X%02X%04X\"%02X%04X "):format(class,family,slot,largefamily,largeslot)
+local function mathbotaccent(class,family,slot)
+ return format('\\Umathbotaccent "%X "%X "%X ',0,family,slot) -- no class
end
-function mathematics.mathchardef(name,class,family,slot) -- we can avoid this one
- return ("\\omathchardef\\%s\"%X%02X%04X "):format(name,class,family,slot)
+local function mathtopdelimiter(class,family,slot)
+ return format('\\Uoverdelimiter "%X "%X ',0,family,slot) -- no class
+end
+local function mathbotdelimiter(class,family,slot)
+ return format('\\Uunderdelimiter "%X "%X ',0,family,slot) -- no class
end
-function mathematics.setmathsymbol(name,class,family,slot,largefamily,largeslot,unicode)
- class = mathematics.classes[class] or class -- no real checks needed
- family = mathematics.families[family] or family
- -- \unexpanded ? \relax needed for the codes?
- local classes = mathematics.classes
- if largefamily and largeslot then
- largefamily = mathematics.families[largefamily] or largefamily
- if class == classes.radical then
- texsprint(("\\unexpanded\\xdef\\%s{%s }"):format(name,mathematics.radical(class,family,slot,largefamily,largeslot)))
- elseif class == classes.open or class == classes.close then
- texsprint(("\\unexpanded\\xdef\\%s{%s}"):format(name,mathematics.delimiter(class,family,slot,largefamily,largeslot)))
- end
- elseif class == classes.accent then
- texsprint(("\\unexpanded\\xdef\\%s{%s }"):format(name,mathematics.mathaccent(class,family,slot)))
- elseif unicode then
- -- beware, open/close and other specials should not end up here
- local ch = utfchar(unicode)
- if characters.filters.utf.private.escapes[ch] then
- texsprint(("\\xdef\\%s{\\char%s }"):format(name,unicode))
- else
- texsprint(("\\xdef\\%s{%s}"):format(name,ch))
- end
+local escapes = characters.filters.utf.private.escapes
+
+local function setmathsymbol(name,class,family,slot)
+ if class == classes.accent then
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,mathaccent(class,family,slot)))
+ elseif class == classes.topaccent then
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,mathtopaccent(class,family,slot)))
+ elseif class == classes.botaccent then
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,mathbotaccent(class,family,slot)))
+ elseif class == classes.over then
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,mathtopdelimiter(class,family,slot)))
+ elseif class == classes.under then
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,mathbotdelimiter(class,family,slot)))
+ elseif class == classes.open or class == classes.close then
+ texsprint(delcode(slot,family,slot))
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,delimiter(class,family,slot)))
+ elseif class == classes.delimiter then
+ texsprint(delcode(slot,family,slot))
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,delimiter(0,family,slot)))
+ elseif class == classes.radical then
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,radical(family,slot)))
else
- texsprint(mathematics.mathchardef(name,class,family,slot))
+ -- beware, open/close and other specials should not end up here
+--~ local ch = utfchar(slot)
+--~ if escapes[ch] then
+--~ texsprint(format("\\xdef\\%s{\\char%s }",name,slot))
+--~ else
+ texsprint(format("\\unexpanded\\xdef\\%s{%s}",name,mathchar(class,family,slot)))
+--~ end
end
end
--- direct sub call
-
-function mathematics.setmathcharacter(target,class,family,slot,largefamily,largeslot)
- class = mathematics.classes[class] or class -- no real checks needed
- family = mathematics.families[family] or family
- if largefamily and largeslot then
- largefamily = mathematics.families[largefamily] or largefamily
- texsprint(mathematics.delcode(target,family,slot,largefamily,largeslot))
- else
- texsprint(mathematics.mathcode(target,class,family,slot))
+local function setmathcharacter(class,family,slot,unicode,firsttime)
+ if not firsttime and class <= 7 then
+ texsprint(mathcode(slot,class,family,unicode or slot))
end
end
--- definitions (todo: expand commands to utf instead of codes)
-
-mathematics.trace = false -- false
+local function setmathsynonym(class,family,slot,unicode,firsttime)
+ if not firsttime and class <= 7 then
+ texsprint(mathcode(slot,class,family,unicode))
+ end
+ if class == classes.open or class == classes.close then
+ texsprint(delcode(slot,family,unicode))
+ end
+end
-function mathematics.define(slots)
- local slots = slots or mathematics.slots.current
- local setmathcharacter = mathematics.setmathcharacter
- local setmathsymbol = mathematics.setmathsymbol
- local trace = mathematics.trace
- local function report(k,m,c,f,i,fe,ie)
- local mc = mathematics.classes[m] or m
- if fe then
- logs.report("mathematics","a - %s:%s 0x%05X -> %s -> %s %s (%s %s) -> %s",mc,m,k,c,f,i,fe,ie,utfchar(k))
- elseif c then
- logs.report("mathematics","b - %s:%s 0x%05X -> %s -> %s %s -> %s",mc,m,k,c,f,i,utfchar(k))
- else
- logs.report("mathematics","c - %s:%s 0x%05X -> %s %s -> %s",mc,m,k,f,i,utfchar(k))
- end
+local function report(class,family,unicode,name)
+ local nametype = type(name)
+ if nametype == "string" then
+ logs.report("mathematics","%s:%s %s U+%05X (%s) => %s",classname,class,family,unicode,utfchar(unicode),name)
+ elseif nametype == "number" then
+ logs.report("mathematics","%s:%s %s U+%05X (%s) => U+%05X",classname,class,family,unicode,utfchar(unicode),name)
+ else
+ logs.report("mathematics","%s:%s %s U+%05X (%s)", classname,class,family,unicode,utfchar(unicode))
end
- for k,v in pairs(characters.data) do
- local m = v.mathclass
- -- i need to clean this up a bit
- if m then
- local c = v.mathname
- if c == false then
- -- no command
- local s = slots[k]
- if s then
- local f, i, fe, ie = s[1], s[2], s[3], s[4]
- if trace then
- report(k,m,c,f,i,fe,ie)
- end
- setmathcharacter(k,m,f,i,fe,ie)
+end
+
+-- there will be a combined \(math)chardef
+
+function mathematics.define(slots,family)
+ family = family or 0
+ family = families[family] or family
+ local data = characters.data
+ for unicode, character in next, data do
+ local symbol = character.mathsymbol
+ if symbol then
+ local other = data[symbol]
+ local class = other.mathclass
+ if class then
+ class = classes[class] or class -- no real checks needed
+ if trace_defining then
+ report(class,family,unicode,symbol)
end
- elseif c then
- local s = slots[k]
- if s then
- local f, i, fe, ie = s[1], s[2], s[3], s[4]
- if trace then
- report(k,m,c,f,i,fe,ie)
+ setmathsynonym(class,family,unicode,symbol)
+ end
+ local spec = other.mathspec
+ if spec then
+ for i, m in next, spec do
+ local class = m.class
+ if class then
+ class = classes[class] or class -- no real checks needed
+ setmathsynonym(class,family,unicode,symbol,i)
end
- setmathsymbol(c,m,f,i,fe,ie,k)
- setmathcharacter(k,m,f,i,fe,ie)
end
- elseif v.contextname then
- local s = slots[k]
- local c = v.contextname
- if s then
- local f, i, fe, ie = s[1], s[2], s[3], s[4]
- if trace then
- report(k,m,c,f,i,fe,ie)
+ end
+ end
+ local mathclass = character.mathclass
+ local mathspec = character.mathspec
+ if mathspec then
+ for i, m in next, mathspec do
+ local name = m.name
+ local class = m.class
+ if not class then
+ class = mathclass
+ elseif not mathclass then
+ mathclass = class
+ end
+ if class then
+ class = classes[class] or class -- no real checks needed
+ if name then
+ if trace_defining then
+ report(class,family,unicode,name)
+ end
+ setmathsymbol(name,class,family,unicode)
+ -- setmathcharacter(class,family,unicode,unicode,i)
+ else
+ name = class == classes.variable or class == classes.number and character.adobename
+ if name then
+ if trace_defining then
+ report(class,family,unicode,name)
+ end
+ -- setmathcharacter(class,family,unicode,unicode,i)
+ end
end
- -- todo: mathortext
- setmathsymbol(c,m,f,i,fe,ie,k)
- setmathcharacter(k,m,f,i,fe,ie)
+ setmathcharacter(class,family,unicode,unicode,i)
end
+ end
+ end
+ if mathclass then
+ local name = character.mathname
+ local class = classes[mathclass] or mathclass -- no real checks needed
+ if name == false then
+ if trace_defining then
+ report(class,family,unicode,name)
+ end
+ setmathcharacter(class,family,unicode)
else
- local a = v.adobename
- if a and m then
- local s, f, i, fe, ie = slots[k], nil, nil, nil, nil
- if s then
- f, i, fe, ie = s[1], s[2], s[3], s[4]
- elseif m == "variable" then
- f, i = mathematics.families.variables, k
- elseif m == "number" then
- f, i = mathematics.families.numbers, k
+ name = name or character.contextname
+ if name then
+ if trace_defining then
+ report(class,family,unicode,name)
end
- if f and i then
- if trace then
- report(k,m,a,f,i,fe,ie)
- end
- setmathcharacter(k,m,f,i,fe,ie)
+ setmathsymbol(name,class,family,unicode)
+ else
+ if trace_defining then
+ report(class,family,unicode,character.adobename)
end
end
+ setmathcharacter(class,family,unicode,unicode)
end
end
end
end
--- temporary here: will become separate
-
--- maybe we should define a nice virtual font so that we have
--- just the base n families repeated for different styles
-
-mathematics.slots.traditional = {
-
- [0x03B1] = { "lcgreek", 0x0B }, -- alpha
- [0x03B2] = { "lcgreek", 0x0C }, -- beta
- [0x03B3] = { "lcgreek", 0x0D }, -- gamma
- [0x03B4] = { "lcgreek", 0x0E }, -- delta
- [0x03B5] = { "lcgreek", 0x0F }, -- epsilon
- [0x03B6] = { "lcgreek", 0x10 }, -- zeta
- [0x03B7] = { "lcgreek", 0x11 }, -- eta
- [0x03B8] = { "lcgreek", 0x12 }, -- theta
- [0x03B9] = { "lcgreek", 0x13 }, -- iota
- [0x03BA] = { "lcgreek", 0x14 }, -- kappa
- [0x03BB] = { "lcgreek", 0x15 }, -- lambda
- [0x03BC] = { "lcgreek", 0x16 }, -- mu
- [0x03BD] = { "lcgreek", 0x17 }, -- nu
- [0x03BE] = { "lcgreek", 0x18 }, -- xi
- [0x03BF] = { "lcgreek", 0x6F }, -- omicron
- [0x03C0] = { "lcgreek", 0x19 }, -- pi
- [0x03C1] = { "lcgreek", 0x1A }, -- rho
--- [0x03C2] = { "lcgreek", 0x00 }, -- varsigma
- [0x03C3] = { "lcgreek", 0x1B }, -- sigma
- [0x03C4] = { "lcgreek", 0x1C }, -- tau
- [0x03C5] = { "lcgreek", 0x1D }, -- upsilon
--- [0x03C6] = { "lcgreek", 0x1E }, -- varphi
- [0x03C7] = { "lcgreek", 0x1F }, -- chi
- [0x03C8] = { "lcgreek", 0x20 }, -- psi
- [0x03C9] = { "lcgreek", 0x21 }, -- omega
-
- [0x0391] = { "ucgreek", 0x41 }, -- Alpha
- [0x0392] = { "ucgreek", 0x42 }, -- Beta
- [0x0393] = { "ucgreek", 0x00 }, -- Gamma
- [0x0394] = { "ucgreek", 0x01 }, -- Delta
- [0x0395] = { "ucgreek", 0x45 }, -- Epsilon
- [0x0396] = { "ucgreek", 0x5A }, -- Zeta
- [0x0397] = { "ucgreek", 0x48 }, -- Eta
- [0x0398] = { "ucgreek", 0x02 }, -- Theta
- [0x0399] = { "ucgreek", 0x49 }, -- Iota
- [0x039A] = { "ucgreek", 0x4B }, -- Kappa
- [0x039B] = { "ucgreek", 0x03 }, -- Lambda
- [0x039C] = { "ucgreek", 0x4D }, -- Mu
- [0x039D] = { "ucgreek", 0x4E }, -- Nu
- [0x039E] = { "ucgreek", 0x04 }, -- Xi
- [0x039F] = { "ucgreek", 0x4F }, -- Omicron
- [0x03A0] = { "ucgreek", 0x05 }, -- Pi
- [0x03A1] = { "ucgreek", 0x52 }, -- Rho
- [0x03A3] = { "ucgreek", 0x06 }, -- Sigma
- [0x03A4] = { "ucgreek", 0x54 }, -- Tau
- [0x03A5] = { "ucgreek", 0x07 }, -- Upsilon
- [0x03A6] = { "ucgreek", 0x08 }, -- Phi
- [0x03A7] = { "ucgreek", 0x58 }, -- Chi
- [0x03A8] = { "ucgreek", 0x09 }, -- Psi
- [0x03A9] = { "ucgreek", 0x0A }, -- Omega
-
- [0x03F5] = { "vargreek", 0x22 }, -- varepsilon
- [0x03D1] = { "vargreek", 0x23 }, -- vartheta
- [0x03D6] = { "vargreek", 0x24 }, -- varpi
- [0x03F1] = { "vargreek", 0x25 }, -- varrho
- [0x03C2] = { "vargreek", 0x26 }, -- varsigma
-
- -- varphi is part of the alphabet, contrary to the other var*s'
-
- [0x03C6] = { "vargreek", 0x27 }, -- varphi
- [0x03D5] = { "lcgreek", 0x1E }, -- phi
-
- [0x03F0] = { "lcgreek", 0x14 }, -- varkappa, not in tex fonts
-
- [0x0021] = { "mr", 0x21 }, -- !
- [0x0028] = { "mr", 0x28 }, -- (
- [0x0029] = { "mr", 0x29 }, -- )
- [0x002A] = { "sy", 0x03 }, -- *
- [0x002B] = { "mr", 0x2B }, -- +
- [0x002C] = { "mi", 0x3B }, -- ,
- [0x002D] = { "sy", 0x00 }, -- -
- [0x2212] = { "sy", 0x00 }, -- -
- [0x002E] = { "mi", 0x3A }, -- .
- [0x002F] = { "mi", 0x3D }, -- /
- [0x003A] = { "mr", 0x3A }, -- :
- [0x003B] = { "mr", 0x3B }, -- ;
- [0x003C] = { "mi", 0x3C }, -- <
- [0x003D] = { "mr", 0x3D }, -- =
- [0x003E] = { "mi", 0x3E }, -- >
- [0x003F] = { "mr", 0x3F }, -- ?
- [0x005C] = { "sy", 0x6E }, -- \
- [0x007B] = { "sy", 0x66 }, -- {
- [0x007C] = { "sy", 0x6A }, -- |
- [0x007D] = { "sy", 0x67 }, -- }
- [0x00AC] = { "sy", 0x3A }, -- lnot
- [0x00B1] = { "sy", 0x06 }, -- pm
- [0x00B7] = { "sy", 0x01 }, -- cdot
- [0x00D7] = { "sy", 0x02 }, -- times
- [0x00F7] = { "sy", 0x04 }, -- div
- [0x2022] = { "sy", 0x0F }, -- bullet
- [0x2111] = { "sy", 0x3D }, -- Im
- [0x2118] = { "mi", 0x7D }, -- wp
- [0x211C] = { "sy", 0x3C }, -- Re
- [0x2190] = { "sy", 0x20 }, -- leftarrow
- [0x2191] = { "sy", 0x22, "ex", 0x78 }, -- uparrow
- [0x2192] = { "sy", 0x21 }, -- rightarrow
- [0x2193] = { "sy", 0x23, "ex", 0x79 }, -- downarrow
- [0x2194] = { "sy", 0x24 }, -- leftrightarrow
- [0x2195] = { "sy", 0x6C, "ex", 0x3F }, -- updownarrow
- [0x2196] = { "sy", 0x2D }, -- nwarrow
- [0x2197] = { "sy", 0x25 }, -- nearrow
- [0x2198] = { "sy", 0x2E }, -- swarrow
- [0x2199] = { "sy", 0x26 }, -- searrow
- [0x21D0] = { "sy", 0x28 }, -- Leftarrow
- [0x21D1] = { "sy", 0x6C, "ex", 0x7E }, -- Uparrow
- [0x21D2] = { "sy", 0x29 }, -- Rightarrow
- [0x21D3] = { "sy", 0x2B, "ex", 0x7F }, -- Downarrow
- [0x21D4] = { "sy", 0x2C }, -- Leftrightarrow
- [0x21D5] = { "sy", 0x6D, "ex", 0x77 }, -- Updownarrow
- [0x2135] = { "sy", 0x40 }, -- aleph
- [0x2113] = { "mi", 0x60 }, -- ell
--- ...
- [0x2200] = { "sy", 0x38 }, -- forall
--- [0x2201] = { "sy", 0x00 }, -- complement
- [0x2202] = { "mi", 0x40 }, -- partial
- [0x2203] = { "sy", 0x39 }, -- exists
--- [0x2204] = { "sy", 0x00 }, -- not exists
- [0x2205] = { "sy", 0x3B }, -- empty set
--- [0x2206] = { "sy", 0x00 }, -- increment
- [0x2207] = { "sy", 0x72 }, -- nabla
- [0x2208] = { "sy", 0x32 }, -- in
- [0x2209] = { "sy", 0x33 }, -- ni
- [0x220F] = { "ex", 0x51 }, -- prod
- [0x2210] = { "ex", 0x60 }, -- coprod
- [0x2211] = { "ex", 0x50 }, -- sum
--- [0x2212] = { "sy", 0x00 }, -- -
- [0x2213] = { "sy", 0x07 }, -- mp
- [0x2215] = { "sy", 0x3D }, -- / AM: Not sure
- [0x2216] = { "sy", 0x6E }, -- setminus
- [0x2217] = { "sy", 0x03 }, -- *
- [0x2218] = { "sy", 0x0E }, -- circ
- [0x2219] = { "sy", 0x0F }, -- bullet
--- [0x221A] = { "sy", 0x70, "ex", 0x70 }, -- sqrt. AM: Check surd??
--- ...
- [0x221D] = { "sy", 0x2F }, -- propto
- [0x221E] = { "sy", 0x31 }, -- infty
- [0x2225] = { "sy", 0x6B }, -- parallel
- [0x2227] = { "sy", 0x5E }, -- wedge
- [0x2228] = { "sy", 0x5F }, -- vee
- [0x2229] = { "sy", 0x5C }, -- cap
- [0x222A] = { "sy", 0x5B }, -- cup
- [0x222B] = { "ex", 0x52 }, -- intop
--- ... other integrals
- [0x2236] = { "mr", 0x3A }, -- colon
- [0x223C] = { "sy", 0x18 }, -- sim
- [0x2243] = { "sy", 0x27 }, -- simeq
- [0x2248] = { "sy", 0x19 }, -- approx
- [0x225C] = { "ma", 0x2C }, -- triangleq
- [0x2261] = { "sy", 0x11 }, -- equiv
- [0x2264] = { "sy", 0x14 }, -- leq
- [0x2265] = { "sy", 0x15 }, -- geq
- [0x226A] = { "sy", 0x1C }, -- ll
- [0x226B] = { "sy", 0x1D }, -- gg
- [0x227A] = { "sy", 0x1E }, -- prec
- [0x227B] = { "sy", 0x1F }, -- succ
--- [0x227C] = { "sy", 0x16 }, -- preceq, AM:No see 2AAF
--- [0x227D] = { "sy", 0x17 }, -- succeq, AM:No see 2AB0
- [0x2282] = { "sy", 0x1A }, -- subset
- [0x2283] = { "sy", 0x1B }, -- supset
- [0x2286] = { "sy", 0x12 }, -- subseteq
- [0x2287] = { "sy", 0x13 }, -- supseteq
- [0x2293] = { "sy", 0x75 }, -- sqcap
- [0x2294] = { "sy", 0x74 }, -- sqcup
- [0x2295] = { "sy", 0x08 }, -- oplus
- [0x2296] = { "sy", 0x09 }, -- ominus
- [0x2297] = { "sy", 0x0A }, -- otimes
- [0x2298] = { "sy", 0x0B }, -- oslash
- [0x2299] = { "sy", 0x0C }, -- odot
- [0x22A4] = { "sy", 0x3E }, -- top
- [0x22A5] = { "sy", 0x3F }, -- bop
- [0x22C0] = { "ex", 0x56 }, -- bigwedge
- [0x22C1] = { "ex", 0x57 }, -- bigvee
- [0x22C2] = { "ex", 0x54 }, -- bigcap
- [0x22C3] = { "ex", 0x53 }, -- bigcup
- [0x22C4] = { "sy", 0x05 }, -- diamond
- [0x22C5] = { "sy", 0x01 }, -- cdot
- [0x22C6] = { "mi", 0x3F }, -- star
- [0x25B3] = { "sy", 0x34 }, -- triangle up
-
- [0x2220] = { "ma", 0x5C }, -- angle
- [0x2221] = { "ma", 0x5D }, -- measuredangle
- [0x2222] = { "ma", 0x5E }, -- sphericalangle
-
- [0x2245] = { "ma", 0x75 }, -- aproxeq
-
- [0x1D6A4] = { "mi", 0x7B }, -- imath
- [0x1D6A5] = { "mi", 0x7C }, -- jmath
-
- [0x0028] = { "mr", 0x28, "ex", 0x00 }, -- (
- [0x0029] = { "mr", 0x29, "ex", 0x01 }, -- )
- [0x002F] = { "mr", 0x2F, "ex", 0x0E }, -- /
- [0x003C] = { "sy", 0x3C, "ex", 0x0A }, -- <
- [0x003E] = { "sy", 0x3E, "ex", 0x0B }, -- >
- [0x005B] = { "mr", 0x5B, "ex", 0x02 }, -- [
- [0x005D] = { "mr", 0x5D, "ex", 0x03 }, -- ]
- [0x007C] = { "sy", 0x6A, "ex", 0x0C }, -- |
- [0x005C] = { "sy", 0x6E, "ex", 0x0F }, -- \
- [0x007B] = { "sy", 0x66, "ex", 0x08 }, -- {
- [0x007D] = { "sy", 0x67, "ex", 0x09 }, -- }
-
- [0x005E] = { "mr", 0x5E, "ex", 0x62 }, -- widehat
- [0x007E] = { "mr", 0x7E, "ex", 0x65 }, -- widetilde
-
- [0x2AAF] = { "sy", 0x16 }, -- preceq
- [0x2AB0] = { "sy", 0x17 }, -- succeq
-
- [0x2145] = { "mr", 0x44 },
- [0x2146] = { "mr", 0x64 },
- [0x2147] = { "mr", 0x65 },
-
- -- please let lm/gypre math show up soon
-
-}
-
-mathematics.slots.current = mathematics.slots.traditional
+-- needed for mathml analysis
function mathematics.utfmathclass(chr, default)
local cd = characters.data[utfbyte(chr)]
@@ -473,3 +279,42 @@ function mathematics.register_xml_entities()
end
end
end
+
+-- helpers
+
+function mathematics.big(tfmdata,unicode,n)
+ local t = tfmdata.characters
+ local c = t[unicode]
+ if c then
+ local next = c.next
+ while next do
+ if n <= 1 then
+ return next
+ else
+ n = n - 1
+ next = t[next].next
+ end
+ end
+ end
+ return unicode
+end
+
+-- plugins
+
+function mathematics.scaleparameters(t,tfmtable,delta)
+ local math_parameters = tfmtable.math_parameters
+ if math_parameters and next(math_parameters) then
+ delta = delta or 1
+ local _, mp = mathematics.dimensions(math_parameters)
+ for name, value in next, mp do
+ if name ~= "RadicalDegreeBottomRaisePercent" then
+ mp[name] = delta*value
+ else
+ mp[name] = value
+ end
+ end
+ t.MathConstants = mp
+ end
+end
+
+table.insert(fonts.tfm.mathactions,mathematics.scaleparameters)
diff --git a/tex/context/base/math-ini.mkii b/tex/context/base/math-ini.mkii
index 6b0cd71d7..7d87fb365 100644
--- a/tex/context/base/math-ini.mkii
+++ b/tex/context/base/math-ini.mkii
@@ -1,14 +1,681 @@
%D \module
%D [ file=math-ini,
-%D version=2008.01.02,
-%D title=\CONTEXT\ Lua Macros,
-%D subtitle=Math Initializations,
-%D author=Hans Hagen,
+%D version=2001.04.12,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Initializations,
+%D author={Hans Hagen \& Taco Hoekwater},
%D date=\currentdate,
-%D copyright=PRAGMA]
+%D copyright=\PRAGMA]
%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
+\writestatus{loading}{ConTeXt Math Macros / Initializations}
+
+% todo: make all definitions global since file loaded only once
+
+%D This module provides namespaces for math fonts, thereby
+%D permitting mixed usage of math fonts. Although not strictly
+%D needed, we also provide a family name mapping mechanism as
+%D used in the (original) AMS math definition files, but here
+%D these names can recursively be remapped and if needed,
+%D dynamically be changed. We've tried to minimize the number
+%D of definition commands and use plain \TEX\ definitions as
+%D fallback. We've tried to follow a couple of conventions
+%D from plain and AMS math in order to achieve backward
+%D compatinility. We also kept an eye on future usage of these
+%D modules in the perspective of MathML and unicode fonts.
+
+\unprotect
+
+\def\@ml@{@ml@} % math list (used for collection)
+\def\@mf@{@mf@} % math family
+%def\@mh@{@mh@} % math handler (not used)
+\def\@mt@{@mt@} % math token
+\def\@mc@{@mc@} % math collection
+
+\def\@@mathlimopcomm#1{\mathop{#1}} %no \limits
+\def\@@mathnolopcomm#1{\mathop{#1}\nolimits}
+\def\@@mathboxcomm #1{\dontleavehmode\hbox{$\mathsurround\zeropoint#1$}}
+
+\chardef\mathordcode = 0 \let\mathordcomm \mathord
+\chardef\mathopcode = 1 \let\mathopcomm \mathop
+\chardef\mathbincode = 2 \let\mathbincomm \mathbin
+\chardef\mathrelcode = 3 \let\mathrelcomm \mathrel
+\chardef\mathopencode = 4 \let\mathopencomm \mathopen
+\chardef\mathclosecode = 5 \let\mathclosecomm \mathclose
+\chardef\mathpunctcode = 6 \let\mathpunctcomm \mathpunct
+\chardef\mathalphacode = 7 \let\mathalphacomm \firstofoneargument
+\chardef\mathinnercode = 0 \let\mathinnercomm \mathinner
+\chardef\mathnothingcode= 0 \let\mathnothingcomm \firstofoneargument
+\chardef\mathlimopcode = 1 \let\mathlimopcomm \@@mathlimopcomm
+\chardef\mathnolopcode = 1 \let\mathnolopcomm \@@mathnolopcomm
+\chardef\mathchoicecode = 0 \let\mathchoicecomm \@@mathchoicecomm
+\chardef\mathboxcode = 0 \let\mathboxcomm \@@mathboxcomm
+
+\chardef\mathaccentcode = 8
+\chardef\mathradicalcode= 9
+
+\def\@@mathchoicecomm#1{[todo #1]}
+
+\def\puremathcode#1{\the\csname math#1code\endcsname}
+\def\puremathcomm#1{\csname math#1comm\endcsname}
+
+\newif\iftracemathcollection
+
+% Simple variant:
+%
+% \def\dohandlemathtoken#1%
+% {\csname\@mt@
+% \ifcsname\@mt@\mathcollection#1\endcsname
+% \mathcollection
+% \else\ifcsname\@mt@\nomathcollection#1\endcsname
+% \nomathcollection
+% \fi\fi
+% #1\endcsname}
+
+%D Because a command can have a different meaning in math
+%D and in text mode, we provide a selector. We also provide
+%D the pure alternatives as \type {\mathcharacter} and \type
+%D {\textcharacter}.
+
+% \ifx\dohandlecommand\undefined \wait \fi % troubles ! but not in mkiv so ...
+
+\let\mathcharacter\dohandlemathtoken
+\let\textcharacter\dohandlecommand % better \dohandletexttoken
+
+% More clever layout:
+%
+% \def\dohandlemathtoken#1%
+% {\csname
+% \ifmmode
+% \ifcsname\@mt@\mathcollection#1\endcsname
+% \@mt@\mathcollection
+% \else\ifcsname\@mt@\nomathcollection#1\endcsname
+% \@mt@\nomathcollection
+% \else\ifcsname\characterencoding#1\endcsname
+% \characterencoding
+% \else
+% \nocharacterencoding
+% \fi\fi\fi
+% \else
+% \ifcsname\characterencoding#1\endcsname
+% \characterencoding
+% \else
+% \nocharacterencoding
+% \fi
+% \fi
+% #1\endcsname}
+%
+% fallback to math when in text mode (handy for unicode vectors)
+
+\def\dohandlemathtoken#1%
+ {\csname
+ \ifmmode
+ \ifcsname\@mt@\mathcollection#1\endcsname
+ \@mt@\mathcollection
+ \else\ifcsname\@mt@\nomathcollection#1\endcsname
+ \@mt@\nomathcollection
+ \else\ifcsname\characterencoding#1\endcsname
+ \characterencoding
+ \else
+ \nocharacterencoding
+ \fi\fi\fi
+ \else
+ \ifcsname\characterencoding#1\endcsname
+ \characterencoding
+ \else\ifcsname\nocharacterencoding#1\endcsname
+ \nocharacterencoding
+ \else\ifcsname\@mt@\mathcollection#1\endcsname
+ \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\mathcollection
+ \else\ifcsname\@mt@\nomathcollection#1\endcsname
+ \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\nomathcollection
+ \else
+ \nocharacterencoding
+ \fi\fi\fi\fi
+ \fi
+ #1\endcsname}
+
+%D Now we redefine the text encoding handler.
+
+%D A better fallback:
+
+% Just ETEX which is the default nowadays.
+
+\def\dohandlemathtoken#1%
+ {\csname
+ \ifmmode
+ \ifcsname\@mt@\mathcollection:\outerencoding#1\endcsname
+ \@mt@\mathcollection:\outerencoding
+ \else\ifcsname\@mt@\mathcollection#1\endcsname
+ \@mt@\mathcollection
+ \else\ifcsname\@mt@\nomathcollection#1\endcsname
+ \@mt@\nomathcollection
+ \else\ifcsname\characterencoding#1\endcsname
+ \characterencoding
+ \else
+ \nocharacterencoding
+ \fi\fi\fi\fi
+ \else
+ \ifcsname\characterencoding#1\endcsname
+ \characterencoding
+ \else\ifcsname\nocharacterencoding#1\endcsname
+ \nocharacterencoding
+ \else\ifcsname\@mt@\mathcollection:\outerencoding#1\endcsname
+ \@mt@\mathcollection:\outerencoding
+ \else\ifcsname\@mt@\mathcollection#1\endcsname
+ \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\mathcollection
+ \else\ifcsname\@mt@\nomathcollection#1\endcsname
+ \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\nomathcollection
+ \else
+ \nocharacterencoding
+ \fi\fi\fi\fi\fi
+ \fi
+ #1\endcsname}
+
+\let\dohandlecommand\dohandlemathtoken
+
+\def\definefamilysynonym
+ {\dotripleempty\dodefinefamilysynonym}
+
+\def\dodefinefamilysynonym[#1][#2][#3]% [mathcollection] [] []
+ {\ifthirdargument
+ \setvalue{\@mf@#1#2}{#3}%
+ \else
+ \setvalue{\@mf@ #1}{#2}%
+ \fi}
+
+\let\mathsubfamily\empty
+
+\def\purefamily #1{\csname \truefamily{#1}\mathsubfamily\s!fam\endcsname}
+\def\purefamilyhex#1{\csname hex\truefamily{#1}\mathsubfamily\s!fam\endcsname}
+
+\def\truefamily#1%
+ {\ifcsname\@mf@\mathcollection#1\endcsname
+ \@EA\truefamily\csname\@mf@\mathcollection#1\endcsname
+ \else\ifcsname\@mf@#1\endcsname
+ \@EA\truefamily\csname\@mf@#1\endcsname
+ \else\ifcsname\@mf@\nomathcollection#1\endcsname
+ \@EA\truefamily\csname\@mf@\nomathcollection#1\endcsname
+ \else
+ #1%
+ \fi\fi\fi}
+
+\newif\ifdynamicmathfamilies \dynamicmathfamiliestrue % true per 2003.11.25; needed for mixed bold math
+
+\let\normalpurefamilyhex\purefamilyhex
+
+% todo: reset collection (tok legen) en opnieuw laden met true
+
+\def\definemathsymbol
+ {\dosixtupleempty\dodefinemathsymbol}
+
+\def\dodefinemathsymbol[#1][#2][#3][#4][#5][#6]%
+ {\unexpanded\setgvalue{#1}{\dohandlemathtoken{#1}}%
+ \ifdynamicmathfamilies \let\purefamilyhex\relax \fi
+ \setevalue{\@mt@\mathcollection#1}%
+ {\ifsixthargument
+ \ifnum\puremathcode{#2}=\mathradicalcode
+ \radical"%
+ \else
+ \delimiter"%
+ \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
+ \fi
+ \purefamilyhex{#3}\uchexnumbers{#4}%
+ \purefamilyhex{#5}\uchexnumbers{#6}\space
+ \else\iffourthargument
+ \ifnum\puremathcode{#2}=\mathaccentcode
+ \mathaccent\else\mathchar
+ \fi
+ "\ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
+ \purefamilyhex{#3}\uchexnumbers{#4}\space
+ \fi\fi}%
+ \let\purefamilyhex\normalpurefamilyhex
+ \tracemathsymbol{#1}}
+
+\def\tracemathsymbol#1%
+ {\iftracemathcollection
+ {\endgraf
+ \hbox{\tex{#1}~:~{\mathematics{\getvalue{#1}{}}}}
+ \endgraf}%
+ \fi}
+
+\def\definemathcharacter
+ {\dosixtupleempty\dodefinemathcharacter}
+
+% \def\dodefinemathcharacter[#1][#2][#3][#4][#5][#6]%
+% {\setmathtoks
+% \ifdynamicmathfamilies \let\purefamilyhex\relax \fi
+% \doifnumberelse{#1}
+% {\scratchcounter#1}
+% {\scratchcounter\@EA`\string#1}%
+% \appendetoks
+% \ifsixthargument
+% \delcode\the\scratchcounter="%
+% \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
+% \purefamilyhex{#3}\uchexnumbers{#4}%
+% \purefamilyhex{#5}\uchexnumbers{#6}\space
+% \else\iffourthargument
+% \mathcode\the\scratchcounter="%
+% \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
+% \purefamilyhex{#3}\uchexnumbers{#4}\space
+% \fi\fi\to\mathtoks
+% \let\purefamilyhex\normalpurefamilyhex
+% \tracemathcharacter{#1}}
+
+\newtoks\mathscratchtoks
+
+\def\definemathcharacter
+ {\chardef\mathcharactermode\zerocount
+ \dosixtupleempty\dodefinemathcharacter}
+
+\def\redefinemathcharacter
+ {\chardef\mathcharactermode\plusone
+ \dosixtupleempty\dodefinemathcharacter}
+
+\def\dodefinemathcharacter[#1][#2][#3][#4][#5][#6]%
+ {\ifcase\mathcharactermode
+ \setmathtoks
+ \or
+ \let\mathtoks\mathscratchtoks \mathtoks\emptytoks
+ \fi
+ \ifdynamicmathfamilies \let\purefamilyhex\relax \fi
+ \doifnumberelse{#1}
+ {\scratchcounter#1}
+ {\scratchcounter\@EA`\string#1}%
+ \appendetoks
+ \ifsixthargument
+ \delcode\the\scratchcounter="%
+ \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
+ \purefamilyhex{#3}\uchexnumbers{#4}%
+ \purefamilyhex{#5}\uchexnumbers{#6}\space
+ \else\iffourthargument
+ \mathcode\the\scratchcounter="%
+ \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
+ \purefamilyhex{#3}\uchexnumbers{#4}\space
+ \fi\fi
+ \to \mathtoks
+ \let\purefamilyhex\normalpurefamilyhex
+ \ifcase\mathcharactermode
+ \expandafter\tracemathcharacter
+ \or
+ \the\mathtoks
+ \mathtoks\emptytoks
+ \expandafter\gobbleoneargument
+ \fi{#1}} % maybe lookahead
+
+\def\tracemathcharacter#1%
+ {\iftracemathcollection
+ {\endgraf
+ \doifnumberelse{#1}
+ {\hbox{\tttf\rawcharacter{#1}~:~{\mathematics{\rawcharacter{#1}}}}}
+ {\hbox{\type{#1}~:~{\mathematics{#1}}}}
+ \endgraf}%
+ \fi}
+
+\def\definemathcommand
+ {\dotripleempty\dodefinemathcommand}
+
+\def\dodefinemathcommand[#1][#2][#3]#4% command class args meaning
+ {\unexpanded\setgvalue{#1}{\dohandlemathtoken{#1}}%
+ \ifthirdargument
+ \processaction
+ [#3]
+ [one=>\setvalue{\@mt@\mathcollection#1}##1{\puremathcomm{#2}{#4{##1}}},
+ two=>\setvalue{\@mt@\mathcollection#1}##1##2{\puremathcomm{#2}{#4{##1}{##2}}}]%
+ \else\ifsecondargument
+ \setvalue{\@mt@\mathcollection#1}{\puremathcomm{#2}{#4}}%
+ \else
+ \setvalue{\@mt@\mathcollection#1}{\puremathcomm{nothing}{#4}}%
+ \fi\fi
+ \tracemathcommand{#1}}
+
+\def\tracemathcommand#1%
+ {\iftracemathcollection
+ \endgraf\hbox{\tex{#1}~:~{\mathematics{\getvalue{#1}{}}}}\endgraf
+ \fi}
+
+\def\startmathcollection[#1]%
+ {\pushmacro\mathcollection
+ \setmathcollection{#1}}
+
+\def\setmathcollection#1%
+ {\edef\mathcollection{#1}%
+ \doifundefined{\@ml@\mathcollection}
+ {\expandafter\newtoks\csname\@ml@\mathcollection\endcsname}}
+
+\def\stopmathcollection
+ {\popmacro\mathcollection}
+
+\def\startrawmathcollection
+ {\startmathcollection}
+
+\def\stoprawmathcollection
+ {\stopmathcollection}
+
+\newtoks\mathtoks
+
+\def\setmathtoks
+ {\@EA\let\@EA\mathtoks\csname\@ml@\mathcollection\endcsname}
+
+\def\currentmathcollection{\mathcollection}
+
+\let\nomathcollection\s!default
+
+\def\enablemathcollection[#1]%
+ {\doifnot{#1}\s!default
+ {\setmathcollection\s!default
+ \the\csname\@ml@\mathcollection\endcsname}%
+ \setmathcollection{#1}%
+ \the\csname\@ml@\mathcollection\endcsname}
+
+% hook 'm into the font mechanism
+
+\definefilesynonym[\f!mathprefix\s!default][\f!mathprefix tex]
+
+\def\usemathcollection
+ {\dodoubleempty\dousemathcollection}
+
+\def\dousemathcollection[#1][#2]%
+ {\pushmacro\fontclass
+ \pushmacro\mathclass
+ \ifsecondargument
+ \edef\fontclass{#1}%
+ \edef\mathclass{#2}%
+ \else
+ \edef\mathclass{#1}%
+ \fi
+ \doinputonce{\truefilename{\f!mathprefix\mathclass}}%
+ \doifsomething\fontclass{\setevalue{\@mc@\fontclass\@mc@}{\mathclass}}%
+ \popmacro\mathclass
+ \popmacro\fontclass}
+
+\let\mathclass\nomathcollection
+
+\letvalue{\@mc@\@mc@}\nomathcollection
+
+% \def\autoenablemathcollection
+% {\doifdefinedelse{\@mc@\fontclass\@mc@}
+% {\enablemathcollection[\getvalue{\@mc@\fontclass\@mc@}]}
+% {\enablemathcollection[\s!default]}} % ? ? ?
+
+\def\autoenablemathcollection
+ {\expanded{\enablemathcollection[\executeifdefined{\@mc@\fontclass\@mc@}\nomathcollection]}}
+
+\appendtoks\autoenablemathcollection\to\mathstrategies
+
+\fetchruntimecommand \showmathcharacters {\f!mathprefix\s!run.mkii}
+\fetchruntimecommand \showmathtoken {\f!mathprefix\s!run.mkii}
+
+\def\resetmathcollection[#1]%
+ {\def\mathcollection{#1}%
+ \forgetdoingonce{\f!mathprefix\mathcollection}%
+ \setmathtoks
+ \ifx\mathtoks\relax\else\mathtoks\emptytoks\fi}
+
+%D \macros
+%D {ifmathpunctuation, enablemathpunctuation,
+%D definemathpunctuation}
+%D
+%D This will replace periods by comma's:
+%D
+%D \starttyping
+%D \definemathpunctuation . textcomma textperiod
+%D \definemathpunctuation , textcomma textcomma
+%D
+%D \appendtoks
+%D \redefinemathcharacter [.] [ord] [mi] ["3B]%
+%D \to \everymathpunctuation
+%D \stoptyping
+
+% \newif\ifmathpunctuation
+%
+% \def\enablemathpunctuation{\mathpunctuationtrue}
+%
+% \def\definemathpunctuation #1 #2 #3 %
+% {\appendtoks
+% \initializemathpunctuation{#1}{#2}{#3}%
+% \to\everymathematics}
+%
+% \def\initializemathpunctuation#1#2#3% sloowww
+% {\ifmathpunctuation % hm move this test to everymath, or better a separate token list
+% \mathcode`#1="8000
+% \defineactivecharacter #1 {\dohandlemathpunctuation{#2}{#3}}%
+% \fi}
+%
+% \unexpanded\def\dohandlemathpunctuation#1#2% \if fails in mathml interval
+% {\def\next{\csname\ifx\space\nexttoken#2\else#1\fi\endcsname}%
+% \futurelet\nexttoken\next}
+
+\newtoks\everymathpunctuation
+
+\def\enablemathpunctuation % can be called inside math, so after \everymathematics
+ {\the\everymathpunctuation
+ \appendtoksonce
+ \the\everymathpunctuation
+ \to\everymathematics}
+
+\def\definemathpunctuation #1 #2 #3 %
+ {\appendtoks
+ \initializemathpunctuation{#1}{#2}{#3}%
+ \to\everymathpunctuation}
+
+\def\initializemathpunctuation#1#2#3% sloowww
+ {\mathcode`#1="8000
+ \defineactivecharacter #1 {\dohandlemathpunctuation{#2}{#3}}}
+
+\unexpanded\def\dohandlemathpunctuation#1#2% \if fails in mathml interval
+ {\def\next{\csname\ifx\space\nexttoken#2\else#1\fi\endcsname}%
+ \futurelet\nexttoken\next}
+
+%D \startbuffer
+%D \enablemathpunctuation$(1,2) (1, 2) (1{,}2) \hbox{foo, not bar}$
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \blank{\getbuffer}\blank
+
+%D needed for sin, cos etc
+
+\def\mfunction #1{{\mr#1}}
+
+% \def\mlimitsfunction #1{\mathlimopcomm{{\mr#1}}
+% \def\mnolimitsfunction#1{\mathnolopcomm{{\mr#1}}
+
+%D Taco posted this solution as response to a mail by Olivier, so
+%D let's integrate it here.
+
+% \def\setmathfunctionstyle#1% rm ss tt
+% {\def\mfunction##1% no families, just scaling a la text
+% {\mathchoice
+% {\hbox{\csname#1\endcsname\tf ##1}}
+% {\hbox{\csname#1\endcsname\tf ##1}}
+% {\hbox{\csname#1\endcsname\tfx ##1}}
+% {\hbox{\csname#1\endcsname\tfxx##1}}}}
+
+\def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option
+
+\def\setmathfunctionstyle#1% rm ss tt
+ {\doifsomething{#1}
+ {\def\currentmscaledstyle{#1}%
+ \def\mathopnolimits##1{\mathop{\mscaledtext{##1}}\nolimits}%
+ \def\mfunction##1{\mscaledtext{##1}}}}
+
+\def\mscaledtext#1%
+ {\mathchoice
+ {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}}
+ {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}}
+ {\hbox{\csname\currentmscaledstyle\endcsname\tfx #1}}
+ {\hbox{\csname\currentmscaledstyle\endcsname\tfxx#1}}}
+
+%D We can force the way functions are typeset by manipulating the text
+%D option:
+%D
+%D \starttyping
+%D \definetypeface[iwona][ss][sans][iwona][default][encoding=texnansi]
+%D \definetypeface[iwona][mm][math][iwona][default][encoding=texnansi,text=ss]
+%D \stoptyping
+%D
+%D This hooks into the math handler with:
+
+\appendtoks
+ \setmathfunctionstyle\currentmathtextstyle
+\to \everybodyfont
+
+%D Usage:
+%D
+%D \starttyping
+%D \setmathfunctionstyle\fontstyle % or {rm} or {ss} or ..
+%D \rm test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
+%D \ss test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
+%D \tt test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
+%D \stoptyping
+
+\edef\hexmrfam {0} \edef\hexbsfam {8}
+\edef\hexmifam {1} \edef\hexbifam {9}
+\edef\hexsyfam {2} \edef\hexscfam {A}
+\edef\hexexfam {3} \edef\hextffam {B}
+\edef\hexitfam {4} \edef\hexmafam {C}
+\edef\hexslfam {5} \edef\hexmbfam {D}
+\edef\hexbffam {6} \edef\hexmcfam {E}
+\edef\hexnnfam {7} \edef\hexmdfam {F}
+
+\definefamilysynonym [default] [letters] [mr]
+\definefamilysynonym [default] [operators] [sy]
+\definefamilysynonym [default] [lcgreek] [mi]
+\definefamilysynonym [default] [ucgreek] [mr]
+\definefamilysynonym [default] [vargreek] [mi]
+\definefamilysynonym [default] [mitfamily] [mi]
+\definefamilysynonym [default] [calfamily] [sy]
+
+\definefamilysynonym [default] [0] [mr]
+\definefamilysynonym [default] [1] [mi]
+\definefamilysynonym [default] [2] [sy]
+\definefamilysynonym [default] [3] [ex]
+
+\enablemathcollection[default]
+
+\usemathcollection [default] [tex]
+\usemathcollection [default] [ams]
+\usemathcollection [default] [uni]
+
+\enablemathcollection[default]
+
+%D Some goodies:
+
+\def\Angstrom{\nomathematics{\Aring}}
+
+%D Bold math:
+%D
+%D \starttyping
+%D \usetypescript [lucida] [texnansi]
+%D
+%D \definetypeface [boldmath] [rm] [serif]
+%D [lucida] [default] [encoding=texnansi]
+%D \definetypeface [boldmath] [tt] [mono]
+%D [lucida] [default] [encoding=texnansi]
+%D \definetypeface [boldmath] [ss] [sans]
+%D [lucida] [default] [encoding=texnansi]
+%D \definetypeface [boldmath] [mm] [boldmath]
+%D [lucida] [default] [encoding=texnansi]
+%D
+%D \switchtobodyfont[lucida,10pt]
+%D
+%D \showmathtoken{Gamma} $\Gamma \Delta \alpha \delta \zeta$
+%D
+%D \switchtobodyfont[boldmath,10pt]
+%D
+%D \showmathtoken{Gamma} $\Gamma \Delta \alpha \delta \zeta$
+%D \stoptyping
+
+%D \macros
+%D {nonknuthmode, donknuthmode}
+%D
+%D The underscore is frequently used in manuals but unfortunately \TEX\ prefers
+%D it to be a math specific character. And since computer modern fonts didn't
+%D have an underscore, one had to use commands to fake one. Nowadays we do
+%D have underscores in latin modern, and since all other fonts have them, we
+%D decided to get away from the restriction to use the underscore character in
+%D text mode.
+%D
+%D \starttyping
+%D \def\test#1{#1}
+%D
+%D \nonknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
+%D
+%D \donknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
+%D \stoptyping
+%D
+%D The result is as expected: the first line typesets ok, while the second
+%D one triggers an error message.
+
+\bgroup
+
+ \ifx\normalsuber\undefined \def\normalsuber{_} \fi
+ \ifx\normalsuper\undefined \def\normalsuper{^} \fi
+
+ \catcode`_=\active
+ \catcode`^=\active
+
+ \gdef\nonknuthmode
+ {\appendtoks\let_\normalsuber\let^\normalsuper\to\everymathematics
+ \mathcode`_="8000
+ \mathcode`^="8000
+ \catcode`_=\@@other
+ \catcode`^=\@@other
+ \let\nonknuthmode\relax}
+
+ \gdef\donknuthmode
+ {\catcode`_=\@@subscript
+ \catcode`^=\@@superscript}
+
+\egroup
+
+%D \macros
+%D {checkdelimiters, fakeleftdelimiter, fakerightdelimiter}
+%D
+%D Handy for non matching situations (as with mathml):
+%D
+%D \starttyping
+%D \checkdelimiters{... bla bla ...}
+%D \fakeleftdelimiter
+%D ... bla bla ...
+%D \fakerightdelimiter
+%D \stoptyping
+
+\newcount\delimitercount
+
+\def\leftfakedelimiter {\advance\delimitercount\minusone\gobbleoneargument}%
+\def\rightfakedelimiter{\advance\delimitercount\plusone \gobbleoneargument}%
+
+\def\checkdelimiters#1%
+ {\delimitercount\zerocount
+ \setbox\scratchbox\hbox\bgroup
+ \let\left \leftfakedelimiter
+ \let\right\rightfakedelimiter
+ $#1\expandafter$\expandafter
+ \egroup
+ \expandafter\delimitercount\the\delimitercount\relax}
+
+\def\fakeleftdelimiter {\ifnum\delimitercount>\zerocount\left .\fi}
+\def\fakerightdelimiter{\ifnum\delimitercount<\zerocount\right.\fi}
+
+%D Needed for unicode:
+
+\def\nulloperator{\mathortext{\mathop{\null}}{\null}}
+
+%D To be dealt with ...
+
+\mathcode`\ ="8000 % \space
+\mathcode`\'="8000 % ^\prime
+\mathcode`\_="8000 % \_
+
+\protect \endinput
+
+\tracemathcollectiontrue
+ \input math-tex \page
+\setupbodyfont[ams] \enablemathcollection[default] \input math-ams \page
+\setupbodyfont[lbr] \enablemathcollection[lbr] \input math-lbr \page
+\setupbodyfont[eul] \enablemathcollection[eul] \input math-eul \stoptext
diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv
index 062631b39..b87096661 100644
--- a/tex/context/base/math-ini.mkiv
+++ b/tex/context/base/math-ini.mkiv
@@ -1,8 +1,8 @@
%D \module
%D [ file=math-ini,
%D version=2008.01.02,
-%D title=\CONTEXT\ Lua Macros,
-%D subtitle=Math Initializations,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Initializations,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,39 +11,549 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Math Macros / Initializations}
+
+%D This module provides namespaces for math fonts, thereby
+%D permitting mixed usage of math fonts. Although not strictly
+%D needed, we also provide a family name mapping mechanism as
+%D used in the (original) AMS math definition files, but here
+%D these names can recursively be remapped and if needed,
+%D dynamically be changed. We've tried to minimize the number
+%D of definition commands and use plain \TEX\ definitions as
+%D fallback. We've tried to follow a couple of conventions
+%D from plain and AMS math in order to achieve backward
+%D compatinility. We also kept an eye on future usage of these
+%D modules in the perspective of MathML and unicode fonts.
+
\unprotect
+\ifx\v!compact\undefined \def\v!compact{compact} \fi
+
%D We move these definitions into the format:
% test [[\char948 \ctxlua{tex.sprint(utf.char(948))}]]
% test $[[\char948 \ctxlua{tex.sprint(utf.char(948))}]]$
\registerctxluafile{math-ini}{1.001}
+\registerctxluafile{math-dim}{1.001}
\registerctxluafile{math-ent}{1.001}
+\registerctxluafile{math-ext}{1.001}
+\registerctxluafile{math-vfu}{1.001}
+\registerctxluafile{math-map}{1.001}
+\registerctxluafile{math-noa}{1.001}
+
+\definesystemattribute[mathalph]
+\definesystemattribute[mathsize]
+\definesystemattribute[mathpunc]
+
+% todo: only in mmode
+
+% \def\setmathattribute#1#2{\dosetattribute{mathalph}{\ctxlua{tex.sprint(mathematics.sync_a_both (\number\dogetattribute{mathalph},"#1","#2"))}}}
+% \def\setmathalphabet #1{\dosetattribute{mathalph}{\ctxlua{tex.sprint(mathematics.sync_a_name (\number\dogetattribute{mathalph},"#1"))}}}
+% \def\setmathstyle #1{\dosetattribute{mathalph}{\ctxlua{tex.sprint(mathematics.sync_a_style(\number\dogetattribute{mathalph},"#1"))}}}
+
+\def\setmathattribute#1#2{\ctxlua{mathematics.sync_a_both ("#1","#2")}}
+\def\setmathalphabet #1{\ctxlua{mathematics.sync_a_name ("#1")}}
+\def\setmathstyle #1{\ctxlua{mathematics.sync_a_style("#1")}}
+
+\unexpanded\def\mr {\setmathattribute{regular}{tf}}
+
+\unexpanded\def\mathdefault {\setmathattribute{regular}{it}}
+\unexpanded\def\mathscript {\setmathalphabet{script}}
+\unexpanded\def\mathfraktur {\setmathalphabet{fraktur}}
+\unexpanded\def\mathblackboard{\setmathalphabet{blackboard}}
+
+\unexpanded\def\mathrm{\setmathattribute{rm}{tf}}
+\unexpanded\def\mathss{\setmathattribute{ss}{tf}}
+\unexpanded\def\mathtt{\setmathattribute{tt}{tf}}
+
+\unexpanded\def\mathtf{\setmathstyle{tf}}
+\unexpanded\def\mathbf{\setmathstyle{bf}}
+\unexpanded\def\mathsl{\setmathstyle{sl}}
+\unexpanded\def\mathit{\setmathstyle{it}}
+\unexpanded\def\mathbs{\setmathstyle{bs}}
+\unexpanded\def\mathbi{\setmathstyle{bi}}
+
+\let\tfmath\mathtf % maybe a grouped command
+\let\bfmath\mathbf
+\let\slmath\mathsl
+\let\itmath\mathit
+\let\bsmath\mathbs
+\let\bimath\mathbi
-% \registerctxluafile{math-def}{1.001}
-% \ctxlua{mathematics.traditional()}
+\let\Bbb\mathblackboard
-\ctxlua{mathematics.define()}
-\ctxlua{mathematics.register_xml_entities()}
+\unexpanded\def\frak {\ifmmode\expandafter\mathfraktur \fi}
+\unexpanded\def\cal {\ifmmode\expandafter\mathscript \fi}
+\unexpanded\def\bbd {\ifmmode\expandafter\mathblackboard\fi}
+\unexpanded\def\blackboard{\ifmmode\expandafter\mathblackboard\fi}
+\unexpanded\def\fraktur {\ifmmode\expandafter\mathfraktur \fi}
+\unexpanded\def\gothic {\ifmmode\expandafter\mathfraktur \fi}
+
+\unexpanded\def\mathcal #1{{\setmathalphabet{script}#1}} % for AMS compatibility
+\unexpanded\def\mathfrak#1{{\setmathalphabet{fraktur}#1}} % for AMS compatibility
+\unexpanded\def\mathbb #1{{\setmathalphabet{blackboard}#1}} % for AMS compatibility
+
+\let\normalmr\mr
+
+\prependtoks
+ \let\mr\normalmr
+ \let\rm\mathrm \let\ss\mathss \let\tt\mathtt
+ \let\tf\mathtf \let\bf\mathbf \let\it\mathit \let\sl\mathsl \let\bi\mathbi \let\bs\mathbs
+ \let\frak\mathfraktur \let\cal\mathscript \let\bbd\mathblackboard
+ \mathdefault
+\to \everymathematics
+
+%D \macros
+%D {boldsymbol}
+%D
+%D The math definition is inspired by amsmath.
+%D
+%D \startbuffer
+%D \definetypeface [boldmath] [mm] [boldmath] [latin-modern] [modern] [encoding=texnansi]
+%D
+%D $a \times b$ $a \boldsymbol{\times} b$
+%D \stopbuffer
+%D
+%D \typebuffer \start \getbuffer \stop
+
+\let\mathboldsymbol\relax % yet unsupported, will be
+
+\def\boldsymbol
+ {\mathortext\mathboldsymbol\bold}
+
+%D Helpers:
\def\utfmathclass #1{\ctxlua{tex.sprint(mathematics.utfmathclass ("#1"))}}
\def\utfmathstretch#1{\ctxlua{tex.sprint(mathematics.utfmathstretch("#1"))}}
\def\utfmathcommand#1{\ctxlua{tex.sprint(mathematics.utfmathcommand("#1"))}}
\def\utfmathfiller #1{\ctxlua{tex.sprint(mathematics.utfmathfiller ("#1"))}}
-\def\utfmathclassdefault #1#2{\ctxlua{
- tex.sprint(mathematics.utfmathclass("#1","#2"))
-}}
+% \def\utfmathclassdefault #1#2{\ctxlua{
+% tex.sprint(mathematics.utfmathclass("#1","#2"))
+% }}
+%
+% \def\utfmathcommanddefault#1#2#3{\ctxlua{
+% local cmd = mathematics.utfmathcommand("#1","") or ""
+% if cmd == "" then
+% commands.cs("#2","#3")
+% else
+% commands.cs(cmd)
+% end}}
+
+% % %
+
+\def\@@mathlimopcomm #1{\mathop{#1}} %no \limits
+\def\@@mathnolopcomm #1{\mathop{#1}\nolimits}
+\def\@@mathboxcomm #1{\dontleavehmode\hbox{$\mathsurround\zeropoint#1$}}
+\def\@@mathchoicecomm#1{[todo #1]}
+
+\chardef\mathordcode = 0 \let\mathordcomm \mathord
+\chardef\mathopcode = 1 \let\mathopcomm \mathop
+\chardef\mathbincode = 2 \let\mathbincomm \mathbin
+\chardef\mathrelcode = 3 \let\mathrelcomm \mathrel
+\chardef\mathopencode = 4 \let\mathopencomm \mathopen
+\chardef\mathclosecode = 5 \let\mathclosecomm \mathclose
+\chardef\mathpunctcode = 6 \let\mathpunctcomm \mathpunct
+\chardef\mathalphacode = 7 \let\mathalphacomm \firstofoneargument
+\chardef\mathinnercode = 0 \let\mathinnercomm \mathinner
+\chardef\mathnothingcode= 0 \let\mathnothingcomm \firstofoneargument
+\chardef\mathlimopcode = 1 \let\mathlimopcomm \@@mathlimopcomm
+\chardef\mathnolopcode = 1 \let\mathnolopcomm \@@mathnolopcomm
+\chardef\mathchoicecode = 0 \let\mathchoicecomm \@@mathchoicecomm
+\chardef\mathboxcode = 0 \let\mathboxcomm \@@mathboxcomm
+
+\chardef\mathaccentcode = 8
+\chardef\mathradicalcode= 9
+
+\def\puremathcode#1{\the\csname math#1code\endcsname}
+\def\puremathcomm#1{\csname math#1comm\endcsname}
+
+% \startlines
+% $\mathopnolimits{\rm d}x$
+% $\mathopnolimits{\kern\zeropoint \rm d}x$
+% $\puremathcomm{nolop}{\rm d}x$
+% $\puremathcomm{nolop}{\kern\zeropoint\rm d}x$
+% \blank
+% $\puremathcomm{nolop}{\mr d}x$
+% $\puremathcomm{nolop}{\kern\zeropoint\mr d}x$
+% $\mathop{\kern\zeropoint\mr d}x$
+% $\mathopnolimits{\kern\zeropoint d}x$
+% \stoplines
+
+\newif\iftracemathcollection
+
+% this will be sorted out:
+
+\let\mathcharacter \getvalue
+\let\textcharacter \getvalue
+\def\definefamilysynonym {\dotripleempty\dodefinefamilysynonym}
+\def\dodefinefamilysynonym [#1][#2][#3]{}
+\def\definemathsymbol {\dosixtupleempty\dodefinemathsymbol}
+\def\dodefinemathsymbol [#1][#2][#3][#4][#5][#6]{}
+\def\definemathcharacter {\dosixtupleempty\dodefinemathcharacter}
+\def\redefinemathcharacter {\dosixtupleempty\dodefinemathcharacter}
+\def\dodefinemathcharacter [#1][#2][#3][#4][#5][#6]{}
+\def\startmathcollection [#1]{}
+\def\setmathcollection #1{}
+\def\stopmathcollection {}
+\def\startrawmathcollection {}
+\def\stoprawmathcollection {}
+\def\setmathtoks {}
+\let\currentmathcollection \s!default
+\let\nomathcollection \s!default
+\let\mathcollection \s!default
+\def\enablemathcollection [#1]{}
+\def\usemathcollection {\dodoubleempty\dousemathcollection}
+\def\dousemathcollection [#1][#2]{}
+\let\mathclass \nomathcollection
+\let\autoenablemathcollection\relax
+\def\resetmathcollection [#1]{}
+
+\def\definemathcommand
+ {\dotripleempty\dodefinemathcommand}
+
+\def\dodefinemathcommand[#1][#2][#3]#4% command class args meaning
+ {\ifthirdargument
+ \processaction
+ [#3]
+ [one=>\unexpanded\setvalue{#1}##1{\puremathcomm{#2}{#4{##1}}},
+ two=>\unexpanded\setvalue{#1}##1##2{\puremathcomm{#2}{#4{##1}{##2}}}]%
+ \else\ifsecondargument
+ \unexpanded\setvalue{#1}{\puremathcomm{#2}{#4}}%
+ \else
+ \unexpanded\setvalue{#1}{\puremathcomm{nothing}{#4}}%
+ \fi\fi}
+
+%D Moved from font-ini.mkiv:
+%D
+%D \macros
+%D {mf,mbox,enablembox,mathop}
+%D
+%D Todo:
+
+\unexpanded\def\mf
+ {\csname\fontalternative\endcsname}
+
+\let\normalmathop\mathop
+
+\unexpanded\def\mathop
+ {\normalmathop
+ \bgroup
+ \let\rm\mf
+ \let\next=}
+
+\def\normalmbox
+ {\normalhbox\bgroup\mf
+ \dowithnextbox{\flushnextbox\egroup}\normalhbox}
+
+\def\mbox
+ {\ifmmode\normalmbox\else\normalhbox\fi}
+
+\def\enablembox
+ {\appendtoks
+ \ifx\normalhbox\undefined\let\normalhbox\hbox\fi
+ \let\hbox\mbox
+ \to\everymathematics}
+
+%D needed for sin, cos etc
+
+\def\mfunction#1{{\mr#1}}
+
+% \def\mlimitsfunction #1{\mathlimopcomm{{\mr#1}}
+% \def\mnolimitsfunction#1{\mathnolopcomm{{\mr#1}}
+
+%D Taco posted this solution as response to a mail by Olivier, so
+%D let's integrate it here.
+
+\def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option
+
+\def\setmathfunctionstyle#1% rm ss tt
+ {\doifsomething{#1}
+ {\def\currentmscaledstyle{#1}%
+ \def\mathopnolimits##1{\mathop{\mscaledtext{##1}}\nolimits}%
+ \def\mfunction##1{\mscaledtext{##1}}}}
+
+\def\mscaledtext#1%
+ {\mathchoice
+ {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}}
+ {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}}
+ {\hbox{\csname\currentmscaledstyle\endcsname\tfx #1}}
+ {\hbox{\csname\currentmscaledstyle\endcsname\tfxx#1}}}
+
+%D We can force the way functions are typeset by manipulating the text
+%D option:
+%D
+%D \starttyping
+%D \definetypeface[iwona][ss][sans][iwona][default][encoding=texnansi]
+%D \definetypeface[iwona][mm][math][iwona][default][encoding=texnansi,text=ss]
+%D \stoptyping
+%D
+%D This hooks into the math handler with:
+
+\appendtoks
+ \setmathfunctionstyle\currentmathtextstyle
+\to \everybodyfont
+
+%D Usage:
+%D
+%D \starttyping
+%D \setmathfunctionstyle\fontstyle % or {rm} or {ss} or ..
+%D \rm test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
+%D \ss test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
+%D \tt test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
+%D \stoptyping
+
+%D Some goodies:
+
+\def\Angstrom{\nomathematics{\Aring}}
+
+%D \macros
+%D {nonknuthmode, donknuthmode}
+%D
+%D The underscore is frequently used in manuals but unfortunately \TEX\ prefers
+%D it to be a math specific character. And since computer modern fonts didn't
+%D have an underscore, one had to use commands to fake one. Nowadays we do
+%D have underscores in latin modern, and since all other fonts have them, we
+%D decided to get away from the restriction to use the underscore character in
+%D text mode.
+%D
+%D \starttyping
+%D \def\test#1{#1}
+%D
+%D \nonknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
+%D
+%D \donknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
+%D \stoptyping
+%D
+%D The result is as expected: the first line typesets ok, while the second
+%D one triggers an error message.
+
+\bgroup
+
+ \ifx\normalsuber\undefined \def\normalsuber{_} \fi
+ \ifx\normalsuper\undefined \def\normalsuper{^} \fi
+
+ \catcode`_=\active
+ \catcode`^=\active
+
+ \gdef\nonknuthmode
+ {\appendtoks\let_\normalsuber\let^\normalsuper\to\everymathematics
+ \mathcode`_="8000
+ \mathcode`^="8000
+ \catcode`_=\@@other
+ \catcode`^=\@@other
+ \let\nonknuthmode\relax}
+
+ \gdef\donknuthmode
+ {\catcode`_=\@@subscript
+ \catcode`^=\@@superscript}
+
+\egroup
+
+%D Needed for unicode:
+
+\def\nulloperator{\mathortext{\mathop{\null}}{\null}}
+
+%D To be dealt with ...
+
+\mathcode`\ ="8000 % \space
+\mathcode`\'="8000 % ^\prime
+\mathcode`\_="8000 % \_
+
+%D \macros
+%D {\setupmathematics}
+%D
+%D Configuration for integrals. (If needed we can speed this up and make it
+%D installable; no processaction is needed then).
+
+\newtoks\everysetupmathematics
+
+\def\setupmathematics
+ {\dosingleargument\dosetupmathematics}
+
+\def\dosetupmathematics[#1]%
+ {\getparameters[\??mo][#1]%
+ \the\everysetupmathematics}
+
+\def\mathematicsparameter#1{\ifcsname\??mo#1\endcsname\csname\??mo#1\endcsname\fi}
+
+%D Memory saver:
+
+\appendtoks
+ \doifelse{\mathematicsparameter\v!compact}\v!yes
+ {\ctxlua{fonts.vf.math.optional=true}}
+ {\ctxlua{fonts.vf.math.optional=false}}%
+\to \everysetupmathematics
+
+\setupmathematics
+ [\v!compact=no]
+
+%D \macros
+%D {enablemathpunctuation,disablemathpunctuation}
+%D
+%D \startbuffer
+%D \enablemathpunctuation$(1,2) (1, 2) (1{,}2) \hbox{foo, not bar}$
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \blank{\getbuffer}\blank
+
+\setfalse \automathpunctuation
+
+\def\enablemathpunctuation {\settrue \automathpunctuation}
+\def\disablemathpunctuation{\setfalse\automathpunctuation}
+
+\ifx\v!autopunctuation\undefined \def\v!autopunctuation{autopunctuation} \fi
+
+\appendtoks
+ \doifelse{\mathematicsparameter\v!autopunctuation}\v!yes\enablemathpunctuation\disablemathpunctuation
+\to \everysetupmathematics
+
+\appendtoks
+ \ifconditional\automathpunctuation\dosetattribute{mathpunc}\plusone\fi
+\to \everymathematics
+
+\setupmathematics
+ [\v!autopunctuation=\v!no]
+
+%D \macros
+%D {mathstyle}
+%D
+%D If one want to be sure that something is typeset in the
+%D appropriate style, \type {\mathstyle} can be used:
+%D
+%D \starttyping
+%D \mathstyle{something}
+%D \stoptyping
+
+% \def\mathstyle#1%
+% {\mathchoice
+% {\displaystyle #1}%
+% {\textstyle #1}%
+% {\scriptstyle #1}%
+% {\scriptscriptstyle#1}}
+%
+% We now have a primitive operation for this. As the
+% macro overloads a new primitive introduced in \LUATEX,
+% we need to use \type {\normalmathstyle} when we consult
+% the current math style.
+%
+% \let \mathstyle \Ustack % spoils cramped
+%
+% \let \mathstyle \firstofoneargument
+%
+% 0 = display
+% 1 = crampeddisplay
+% 2 = text
+% 3 = crampedtext
+% 4 = script
+% 5 = crampedscript
+% 6 = scriptscript
+% 7 = crampedscriptscript
+
+\def\uncramped#1%
+ {{\ifcase\normalmathstyle
+ \or \displaystyle \or
+ \or \textstyle \or
+ \or \scriptstyle \or
+ \or \scriptscriptstyle \fi
+ #1}}
+
+\def\cramped#1%
+ {{\ifcase\normalmathstyle
+ \crampeddisplaystyle \or \or % 0 -> 1
+ \crampedtextstyle \or \or % 2 -> 3
+ \crampedscriptstyle \or \or % 4 -> 5
+ \crampedscriptscriptstyle \fi % 6 -> 7
+ #1}}
+
+\def\triggermathstyle#1% #1 is number
+ {\ifcase#1\relax
+ \displaystyle \or
+ \crampeddisplaystyle \or
+ \textstyle \or
+ \crampedtextstyle \or
+ \scriptstyle \or
+ \crampedscriptstyle \or
+ \scriptscriptstyle \or
+ \crampedscriptscriptstyle \else
+ % error
+ \fi}
+
+\def\cramped#1%
+ {{\ifcase\normalmathstyle
+ \crampeddisplaystyle \or \or % 0 -> 1
+ \crampedtextstyle \or \or % 2 -> 3
+ \crampedscriptstyle \or \or % 4 -> 5
+ \crampedscriptscriptstyle \fi % 6 -> 7
+ #1}}
+
+%D Something similar can be used in the (re|)|definition
+%D of \type {\text}. This version is a variation on the one
+%D in the math module (see \type{m-math} and|/|or \type
+%D {m-newmat}).
+
+\unexpanded\def\mathtext
+ {\mathortext\domathtext\hbox}
+
+\def\domathtext#1%
+ {\mathchoice
+ {\dodomathtext\displaystyle\textface {#1}}%
+ {\dodomathtext\textstyle \textface {#1}}%
+ {\dodomathtext\textstyle \scriptface {#1}}%
+ {\dodomathtext\textstyle \scriptscriptface{#1}}}
+
+\def\dodomathtext#1#2#3% no \everymath !
+ %{\hbox{\everymath{#1}\switchtobodyfont [#2]#3}} % 15 sec
+ {\hbox{\everymath{#1}\setcurrentfontbody{#2}#3}} % 3 sec (no math)
+
+%D Because we may overload \type {\text} in other (structuring)
+%D macros, we say:
+
+\appendtoks \let\text\mathtext \to \everymathematics
+
+%D The next code is derived from plain \TEX.
+
+\newcount\interdisplaylinepenalty \interdisplaylinepenalty=100
+
+\newif\ifdt@p
+
+\def\displ@y
+ {\global\dt@ptrue
+ \openup\displayopenupvalue % was \openup\jot
+ \everycr
+ {\noalign
+ {\ifdt@p
+ \global\dt@pfalse
+ \ifdim\prevdepth>-\thousandpoint
+ \vskip-\lineskiplimit
+ \vskip\normallineskiplimit
+ \fi
+ \else
+ \penalty\interdisplaylinepenalty
+ \fi}}}
+
+\let\normaldispl@y\displ@y
+
+\def\displ@y{\resetdisplaymatheq\normaldispl@y}
+
+\def\m@th{\mathsurround\zeropoint} % obsolete
+
+%D Text in math:
+
+\def\mathortext
+ {\ifmmode
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+% \defineactivecharacter _ {\mathortext{_}{\_}} text_text $a^2$
-\def\utfmathcommanddefault#1#2#3{\ctxlua{
- local cmd = mathematics.utfmathcommand("#1","") or ""
- if cmd == "" then
- commands.cs("#2","#3")
- else
- commands.cs(cmd)
- end}}
+% force text mode, will be overloaded later
-% \let\math@normal@int\int \def\int{\math@normal@int\intlimits}
+\ifx\text\undefined \let\text\hbox \fi
\protect \endinput
diff --git a/tex/context/base/math-ini.tex b/tex/context/base/math-ini.tex
deleted file mode 100644
index 98738e500..000000000
--- a/tex/context/base/math-ini.tex
+++ /dev/null
@@ -1,688 +0,0 @@
-%D \module
-%D [ file=math-ini,
-%D version=2001.04.12,
-%D title=\CONTEXT\ Math Macros,
-%D subtitle=Basic Macros,
-%D author={Hans Hagen \& Taco Hoekwater},
-%D date=\currentdate,
-%D copyright=\PRAGMA]
-%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 all definitions global since file loaded only once
-
-%D This module provides namespaces for math fonts, thereby
-%D permitting mixed usage of math fonts. Although not strictly
-%D needed, we also provide a family name mapping mechanism as
-%D used in the (original) AMS math definition files, but here
-%D these names can recursively be remapped and if needed,
-%D dynamically be changed. We've tried to minimize the number
-%D of definition commands and use plain \TEX\ definitions as
-%D fallback. We've tried to follow a couple of conventions
-%D from plain and AMS math in order to achieve backward
-%D compatinility. We also kept an eye on future usage of these
-%D modules in the perspective of MathML and unicode fonts.
-
-\unprotect
-
-\def\@ml@{@ml@} % math list (used for collection)
-\def\@mf@{@mf@} % math family
-%def\@mh@{@mh@} % math handler (not used)
-\def\@mt@{@mt@} % math token
-\def\@mc@{@mc@} % math collection
-
-\def\@@mathlimopcomm#1{\mathop{#1}} %no \limits
-\def\@@mathnolopcomm#1{\mathop{#1}\nolimits}
-\def\@@mathboxcomm #1{\dontleavehmode\hbox{$\m@th#1$}}
-
-\chardef\mathordcode = 0 \let\mathordcomm \mathord
-\chardef\mathopcode = 1 \let\mathopcomm \mathop
-\chardef\mathbincode = 2 \let\mathbincomm \mathbin
-\chardef\mathrelcode = 3 \let\mathrelcomm \mathrel
-\chardef\mathopencode = 4 \let\mathopencomm \mathopen
-\chardef\mathclosecode = 5 \let\mathclosecomm \mathclose
-\chardef\mathpunctcode = 6 \let\mathpunctcomm \mathpunct
-\chardef\mathalphacode = 7 \let\mathalphacomm \firstofoneargument
-\chardef\mathinnercode = 0 \let\mathinnercomm \mathinner
-\chardef\mathnothingcode= 0 \let\mathnothingcomm \firstofoneargument
-\chardef\mathlimopcode = 1 \let\mathlimopcomm \@@mathlimopcomm
-\chardef\mathnolopcode = 1 \let\mathnolopcomm \@@mathnolopcomm
-\chardef\mathchoicecode = 0 \let\mathchoicecomm \@@mathchoicecomm
-\chardef\mathboxcode = 0 \let\mathboxcomm \@@mathboxcomm
-
-\chardef\mathaccentcode = 8
-\chardef\mathradicalcode= 9
-
-\def\@@mathchoicecomm#1{[todo #1]}
-
-\def\puremathcode#1{\the\csname math#1code\endcsname}
-\def\puremathcomm#1{\csname math#1comm\endcsname}
-
-\newif\iftracemathcollection
-
-% Simple variant:
-%
-% \def\dohandlemathtoken#1%
-% {\csname\@mt@
-% \ifcsname\@mt@\mathcollection#1\endcsname
-% \mathcollection
-% \else\ifcsname\@mt@\nomathcollection#1\endcsname
-% \nomathcollection
-% \fi\fi
-% #1\endcsname}
-
-%D Because a command can have a different meaning in math
-%D and in text mode, we provide a selector. We also provide
-%D the pure alternatives as \type {\mathcharacter} and \type
-%D {\textcharacter}.
-
-\ifx\dohandlecommand\undefined \wait \fi % troubles !
-
-\def\mathcharacter\dohandlemathtoken
-\def\textcharacter\dohandlecommand % better \dohandletexttoken
-
-% More clever layout:
-%
-% \def\dohandlemathtoken#1%
-% {\csname
-% \ifmmode
-% \ifcsname\@mt@\mathcollection#1\endcsname
-% \@mt@\mathcollection
-% \else\ifcsname\@mt@\nomathcollection#1\endcsname
-% \@mt@\nomathcollection
-% \else\ifcsname\characterencoding#1\endcsname
-% \characterencoding
-% \else
-% \nocharacterencoding
-% \fi\fi\fi
-% \else
-% \ifcsname\characterencoding#1\endcsname
-% \characterencoding
-% \else
-% \nocharacterencoding
-% \fi
-% \fi
-% #1\endcsname}
-%
-% fallback to math when in text mode (handy for unicode vectors)
-
-\def\dohandlemathtoken#1%
- {\csname
- \ifmmode
- \ifcsname\@mt@\mathcollection#1\endcsname
- \@mt@\mathcollection
- \else\ifcsname\@mt@\nomathcollection#1\endcsname
- \@mt@\nomathcollection
- \else\ifcsname\characterencoding#1\endcsname
- \characterencoding
- \else
- \nocharacterencoding
- \fi\fi\fi
- \else
- \ifcsname\characterencoding#1\endcsname
- \characterencoding
- \else\ifcsname\nocharacterencoding#1\endcsname
- \nocharacterencoding
- \else\ifcsname\@mt@\mathcollection#1\endcsname
- \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\mathcollection
- \else\ifcsname\@mt@\nomathcollection#1\endcsname
- \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\nomathcollection
- \else
- \nocharacterencoding
- \fi\fi\fi\fi
- \fi
- #1\endcsname}
-
-%D Now we redefine the text encoding handler.
-
-%D A better fallback:
-
-% Just ETEX which is the default nowadays.
-
-\def\dohandlemathtoken#1%
- {\csname
- \ifmmode
- \ifcsname\@mt@\mathcollection:\outerencoding#1\endcsname
- \@mt@\mathcollection:\outerencoding
- \else\ifcsname\@mt@\mathcollection#1\endcsname
- \@mt@\mathcollection
- \else\ifcsname\@mt@\nomathcollection#1\endcsname
- \@mt@\nomathcollection
- \else\ifcsname\characterencoding#1\endcsname
- \characterencoding
- \else
- \nocharacterencoding
- \fi\fi\fi\fi
- \else
- \ifcsname\characterencoding#1\endcsname
- \characterencoding
- \else\ifcsname\nocharacterencoding#1\endcsname
- \nocharacterencoding
- \else\ifcsname\@mt@\mathcollection:\outerencoding#1\endcsname
- \@mt@\mathcollection:\outerencoding
- \else\ifcsname\@mt@\mathcollection#1\endcsname
- \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\mathcollection
- \else\ifcsname\@mt@\nomathcollection#1\endcsname
- \strippedcsname\mathematics\expandafter\endcsname\csname\@mt@\nomathcollection
- \else
- \nocharacterencoding
- \fi\fi\fi\fi\fi
- \fi
- #1\endcsname}
-
-\let\dohandlecommand\dohandlemathtoken
-
-\def\definefamilysynonym
- {\dotripleempty\dodefinefamilysynonym}
-
-\def\dodefinefamilysynonym[#1][#2][#3]% [mathcollection] [] []
- {\ifthirdargument
- \setvalue{\@mf@#1#2}{#3}%
- \else
- \setvalue{\@mf@ #1}{#2}%
- \fi}
-
-\let\mathsubfamily\empty
-
-\def\purefamily #1{\csname \truefamily{#1}\mathsubfamily\s!fam\endcsname}
-\def\purefamilyhex#1{\csname hex\truefamily{#1}\mathsubfamily\s!fam\endcsname}
-
-\def\truefamily#1%
- {\ifcsname\@mf@\mathcollection#1\endcsname
- \@EA\truefamily\csname\@mf@\mathcollection#1\endcsname
- \else\ifcsname\@mf@#1\endcsname
- \@EA\truefamily\csname\@mf@#1\endcsname
- \else\ifcsname\@mf@\nomathcollection#1\endcsname
- \@EA\truefamily\csname\@mf@\nomathcollection#1\endcsname
- \else
- #1%
- \fi\fi\fi}
-
-\newif\ifdynamicmathfamilies \dynamicmathfamiliestrue % true per 2003.11.25; needed for mixed bold math
-
-\let\normalpurefamilyhex\purefamilyhex
-
-% todo: reset collection (tok legen) en opnieuw laden met true
-
-\def\definemathsymbol
- {\dosixtupleempty\dodefinemathsymbol}
-
-\def\dodefinemathsymbol[#1][#2][#3][#4][#5][#6]%
- {\unexpanded\setgvalue{#1}{\dohandlemathtoken{#1}}%
- \ifdynamicmathfamilies \let\purefamilyhex\relax \fi
- \setevalue{\@mt@\mathcollection#1}%
- {\ifsixthargument
- \ifnum\puremathcode{#2}=\mathradicalcode
- \radical"%
- \else
- \delimiter"%
- \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
- \fi
- \purefamilyhex{#3}\uchexnumbers{#4}%
- \purefamilyhex{#5}\uchexnumbers{#6}\space
- \else\iffourthargument
- \ifnum\puremathcode{#2}=\mathaccentcode
- \mathaccent\else\mathchar
- \fi
- "\ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
- \purefamilyhex{#3}\uchexnumbers{#4}\space
- \fi\fi}%
- \let\purefamilyhex\normalpurefamilyhex
- \tracemathsymbol{#1}}
-
-\def\tracemathsymbol#1%
- {\iftracemathcollection
- {\endgraf
- \hbox{\tex{#1}~:~{\mathematics{\getvalue{#1}{}}}}
- \endgraf}%
- \fi}
-
-\def\definemathcharacter
- {\dosixtupleempty\dodefinemathcharacter}
-
-% \def\dodefinemathcharacter[#1][#2][#3][#4][#5][#6]%
-% {\setmathtoks
-% \ifdynamicmathfamilies \let\purefamilyhex\relax \fi
-% \doifnumberelse{#1}
-% {\scratchcounter#1}
-% {\scratchcounter\@EA`\string#1}%
-% \appendetoks
-% \ifsixthargument
-% \delcode\the\scratchcounter="%
-% \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
-% \purefamilyhex{#3}\uchexnumbers{#4}%
-% \purefamilyhex{#5}\uchexnumbers{#6}\space
-% \else\iffourthargument
-% \mathcode\the\scratchcounter="%
-% \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
-% \purefamilyhex{#3}\uchexnumbers{#4}\space
-% \fi\fi\to\mathtoks
-% \let\purefamilyhex\normalpurefamilyhex
-% \tracemathcharacter{#1}}
-
-\newtoks\mathscratchtoks
-
-\def\definemathcharacter
- {\chardef\mathcharactermode\zerocount
- \dosixtupleempty\dodefinemathcharacter}
-
-\def\redefinemathcharacter
- {\chardef\mathcharactermode\plusone
- \dosixtupleempty\dodefinemathcharacter}
-
-\def\dodefinemathcharacter[#1][#2][#3][#4][#5][#6]%
- {\ifcase\mathcharactermode
- \setmathtoks
- \or
- \let\mathtoks\mathscratchtoks \mathtoks\emptytoks
- \fi
- \ifdynamicmathfamilies \let\purefamilyhex\relax \fi
- \doifnumberelse{#1}
- {\scratchcounter#1}
- {\scratchcounter\@EA`\string#1}%
- \appendetoks
- \ifsixthargument
- \delcode\the\scratchcounter="%
- \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
- \purefamilyhex{#3}\uchexnumbers{#4}%
- \purefamilyhex{#5}\uchexnumbers{#6}\space
- \else\iffourthargument
- \mathcode\the\scratchcounter="%
- \ifnum\puremathcode{#2}>7 0\else\puremathcode{#2}\fi
- \purefamilyhex{#3}\uchexnumbers{#4}\space
- \fi\fi
- \to \mathtoks
- \let\purefamilyhex\normalpurefamilyhex
- \ifcase\mathcharactermode
- \expandafter\tracemathcharacter
- \or
- \the\mathtoks
- \mathtoks\emptytoks
- \expandafter\gobbleoneargument
- \fi{#1}} % maybe lookahead
-
-\def\tracemathcharacter#1%
- {\iftracemathcollection
- {\endgraf
- \doifnumberelse{#1}
- {\hbox{\tttf\rawcharacter{#1}~:~{\mathematics{\rawcharacter{#1}}}}}
- {\hbox{\type{#1}~:~{\mathematics{#1}}}}
- \endgraf}%
- \fi}
-
-\def\definemathcommand
- {\dotripleempty\dodefinemathcommand}
-
-\def\dodefinemathcommand[#1][#2][#3]#4% command class args meaning
- {\unexpanded\setgvalue{#1}{\dohandlemathtoken{#1}}%
- \ifthirdargument
- \processaction
- [#3]
- [one=>\setvalue{\@mt@\mathcollection#1}##1{\puremathcomm{#2}{#4{##1}}},
- two=>\setvalue{\@mt@\mathcollection#1}##1##2{\puremathcomm{#2}{#4{##1}{##2}}}]%
- \else\ifsecondargument
- \setvalue{\@mt@\mathcollection#1}{\puremathcomm{#2}{#4}}%
- \else
- \setvalue{\@mt@\mathcollection#1}{\puremathcomm{nothing}{#4}}%
- \fi\fi
- \tracemathcommand{#1}}
-
-\def\tracemathcommand#1%
- {\iftracemathcollection
- \endgraf\hbox{\tex{#1}~:~{\mathematics{\getvalue{#1}{}}}}\endgraf
- \fi}
-
-\def\startmathcollection[#1]%
- {\pushmacro\mathcollection
- \setmathcollection{#1}}
-
-\def\setmathcollection#1%
- {\edef\mathcollection{#1}%
- \doifundefined{\@ml@\mathcollection}
- {\expandafter\newtoks\csname\@ml@\mathcollection\endcsname}}
-
-\def\stopmathcollection
- {\popmacro\mathcollection}
-
-\def\startrawmathcollection
- {\startmathcollection}
-
-\def\stoprawmathcollection
- {\stopmathcollection}
-
-\newtoks\mathtoks
-
-\def\setmathtoks
- {\@EA\let\@EA\mathtoks\csname\@ml@\mathcollection\endcsname}
-
-\def\currentmathcollection{\mathcollection}
-
-\let\nomathcollection\s!default
-
-\def\enablemathcollection[#1]%
- {\doifnot{#1}\s!default
- {\setmathcollection\s!default
- \the\csname\@ml@\mathcollection\endcsname}%
- \setmathcollection{#1}%
- \the\csname\@ml@\mathcollection\endcsname}
-
-% hook 'm into the font mechanism
-
-\definefilesynonym[\f!mathprefix\s!default][\f!mathprefix tex]
-
-\def\usemathcollection
- {\dodoubleempty\dousemathcollection}
-
-\def\dousemathcollection[#1][#2]%
- {\pushmacro\fontclass
- \pushmacro\mathclass
- \ifsecondargument
- \edef\fontclass{#1}%
- \edef\mathclass{#2}%
- \else
- \edef\mathclass{#1}%
- \fi
- \doinputonce{\truefilename{\f!mathprefix\mathclass}}%
- \doifsomething\fontclass{\setevalue{\@mc@\fontclass\@mc@}{\mathclass}}%
- \popmacro\mathclass
- \popmacro\fontclass}
-
-\let\mathclass\nomathcollection
-
-\letvalue{\@mc@\@mc@}\nomathcollection
-
-% \def\autoenablemathcollection
-% {\doifdefinedelse{\@mc@\fontclass\@mc@}
-% {\enablemathcollection[\getvalue{\@mc@\fontclass\@mc@}]}
-% {\enablemathcollection[\s!default]}} % ? ? ?
-
-\def\autoenablemathcollection
- {\expanded{\enablemathcollection[\executeifdefined{\@mc@\fontclass\@mc@}\nomathcollection]}}
-
-\appendtoks\autoenablemathcollection\to\mathstrategies
-
-\fetchruntimecommand \showmathcharacters {\f!mathprefix\s!run}
-\fetchruntimecommand \showmathtoken {\f!mathprefix\s!run}
-
-\def\resetmathcollection[#1]%
- {\def\mathcollection{#1}%
- \forgetdoingonce{\f!mathprefix\mathcollection}%
- \setmathtoks
- \ifx\mathtoks\relax\else\mathtoks\emptytoks\fi}
-
-%D \macros
-%D {ifmathpunctuation, enablemathpunctuation,
-%D definemathpunctuation}
-%D
-%D This will replace periods by comma's:
-%D
-%D \starttyping
-%D \definemathpunctuation . textcomma textperiod
-%D \definemathpunctuation , textcomma textcomma
-%D
-%D \appendtoks
-%D \redefinemathcharacter [.] [ord] [mi] ["3B]%
-%D \to \everymathpunctuation
-%D \stoptyping
-
-% \newif\ifmathpunctuation
-%
-% \def\enablemathpunctuation{\mathpunctuationtrue}
-%
-% \def\definemathpunctuation #1 #2 #3 %
-% {\appendtoks
-% \initializemathpunctuation{#1}{#2}{#3}%
-% \to\everymathematics}
-%
-% \def\initializemathpunctuation#1#2#3% sloowww
-% {\ifmathpunctuation % hm move this test to everymath, or better a separate token list
-% \mathcode`#1="8000
-% \defineactivecharacter #1 {\dohandlemathpunctuation{#2}{#3}}%
-% \fi}
-%
-% \unexpanded\def\dohandlemathpunctuation#1#2% \if fails in mathml interval
-% {\def\next{\csname\ifx\space\nexttoken#2\else#1\fi\endcsname}%
-% \futurelet\nexttoken\next}
-
-\newtoks\everymathpunctuation
-
-\def\enablemathpunctuation % can be called inside math, so after \everymathematics
- {\the\everymathpunctuation
- \appendtoksonce
- \the\everymathpunctuation
- \to\everymathematics}
-
-\def\definemathpunctuation #1 #2 #3 %
- {\appendtoks
- \initializemathpunctuation{#1}{#2}{#3}%
- \to\everymathpunctuation}
-
-\def\initializemathpunctuation#1#2#3% sloowww
- {\mathcode`#1="8000
- \defineactivecharacter #1 {\dohandlemathpunctuation{#2}{#3}}}
-
-\unexpanded\def\dohandlemathpunctuation#1#2% \if fails in mathml interval
- {\def\next{\csname\ifx\space\nexttoken#2\else#1\fi\endcsname}%
- \futurelet\nexttoken\next}
-
-%D \startbuffer
-%D \enablemathpunctuation$(1,2) (1, 2) (1{,}2) \hbox{foo, not bar}$
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \blank{\getbuffer}\blank
-
-%D needed for sin, cos etc
-
-\def\mfunction #1{{\mr#1}}
-
-% \def\mlimitsfunction #1{\mathlimopcomm{{\mr#1}}
-% \def\mnolimitsfunction#1{\mathnolopcomm{{\mr#1}}
-
-%D Taco posted this solution as response to a mail by Olivier, so
-%D let's integrate it here.
-
-% \def\setmathfunctionstyle#1% rm ss tt
-% {\def\mfunction##1% no families, just scaling a la text
-% {\mathchoice
-% {\hbox{\csname#1\endcsname\tf ##1}}
-% {\hbox{\csname#1\endcsname\tf ##1}}
-% {\hbox{\csname#1\endcsname\tfx ##1}}
-% {\hbox{\csname#1\endcsname\tfxx##1}}}}
-
-\def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option
-
-\def\setmathfunctionstyle#1% rm ss tt
- {\doifsomething{#1}
- {\def\currentmscaledstyle{#1}%
- \def\mathopnolimits##1{\mathop{\mscaledtext{##1}}\nolimits}%
- \def\mfunction##1{\mscaledtext{##1}}}}
-
-\def\mscaledtext#1%
- {\mathchoice
- {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}}
- {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}}
- {\hbox{\csname\currentmscaledstyle\endcsname\tfx #1}}
- {\hbox{\csname\currentmscaledstyle\endcsname\tfxx#1}}}
-
-%D We can force the way functions are typeset by manipulating the text
-%D option:
-%D
-%D \starttyping
-%D \definetypeface[iwona][ss][sans][iwona][default][encoding=texnansi]
-%D \definetypeface[iwona][mm][math][iwona][default][encoding=texnansi,text=ss]
-%D \stoptyping
-%D
-%D This hooks into the math handler with:
-
-\appendtoks
- \setmathfunctionstyle\currentmathtextstyle
-\to \everybodyfont
-
-%D Usage:
-%D
-%D \starttyping
-%D \setmathfunctionstyle\fontstyle % or {rm} or {ss} or ..
-%D \rm test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
-%D \ss test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
-%D \tt test $\sin{(x^{\sin(x^{\sin(x)})})}$ test
-%D \stoptyping
-
-\edef\hexmrfam {0} \edef\hexbsfam {8}
-\edef\hexmifam {1} \edef\hexbifam {9}
-\edef\hexsyfam {2} \edef\hexscfam {A}
-\edef\hexexfam {3} \edef\hextffam {B}
-\edef\hexitfam {4} \edef\hexmafam {C}
-\edef\hexslfam {5} \edef\hexmbfam {D}
-\edef\hexbffam {6} \edef\hexmcfam {E}
-\edef\hexnnfam {7} \edef\hexmdfam {F}
-
-\definefamilysynonym [default] [letters] [mr]
-\definefamilysynonym [default] [operators] [sy]
-\definefamilysynonym [default] [lcgreek] [mi]
-\definefamilysynonym [default] [ucgreek] [mr]
-\definefamilysynonym [default] [vargreek] [mi]
-\definefamilysynonym [default] [mitfamily] [mi]
-\definefamilysynonym [default] [calfamily] [sy]
-
-\definefamilysynonym [default] [0] [mr]
-\definefamilysynonym [default] [1] [mi]
-\definefamilysynonym [default] [2] [sy]
-\definefamilysynonym [default] [3] [ex]
-
-\enablemathcollection[default]
-
-\usemathcollection [default] [tex]
-\usemathcollection [default] [ams]
-\usemathcollection [default] [uni]
-
-\enablemathcollection[default]
-
-%D Some goodies:
-
-\def\Angstrom{\nomathematics{\Aring}}
-
-%D Bold math:
-%D
-%D \starttyping
-%D \usetypescript [lucida] [texnansi]
-%D
-%D \definetypeface [boldmath] [rm] [serif]
-%D [lucida] [default] [encoding=texnansi]
-%D \definetypeface [boldmath] [tt] [mono]
-%D [lucida] [default] [encoding=texnansi]
-%D \definetypeface [boldmath] [ss] [sans]
-%D [lucida] [default] [encoding=texnansi]
-%D \definetypeface [boldmath] [mm] [boldmath]
-%D [lucida] [default] [encoding=texnansi]
-%D
-%D \switchtobodyfont[lucida,10pt]
-%D
-%D \showmathtoken{Gamma} $\Gamma \Delta \alpha \delta \zeta$
-%D
-%D \switchtobodyfont[boldmath,10pt]
-%D
-%D \showmathtoken{Gamma} $\Gamma \Delta \alpha \delta \zeta$
-%D \stoptyping
-
-%D \macros
-%D {nonknuthmode, donknuthmode}
-%D
-%D The underscore is frequently used in manuals but unfortunately \TEX\ prefers
-%D it to be a math specific character. And since computer modern fonts didn't
-%D have an underscore, one had to use commands to fake one. Nowadays we do
-%D have underscores in latin modern, and since all other fonts have them, we
-%D decided to get away from the restriction to use the underscore character in
-%D text mode.
-%D
-%D \starttyping
-%D \def\test#1{#1}
-%D
-%D \nonknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
-%D
-%D \donknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2}
-%D \stoptyping
-%D
-%D The result is as expected: the first line typesets ok, while the second
-%D one triggers an error message.
-
-\bgroup
-
- \ifx\normalsuber\undefined \def\normalsuber{_} \fi
- \ifx\normalsuper\undefined \def\normalsuper{^} \fi
-
- \catcode`_=\active
- \catcode`^=\active
-
- \gdef\nonknuthmode
- {\appendtoks\let_\normalsuber\let^\normalsuper\to\everymathematics
- \mathcode`_="8000
- \mathcode`^="8000
- \catcode`_=\@@other
- \catcode`^=\@@other
- \let\nonknuthmode\relax}
-
- \gdef\donknuthmode
- {\catcode`_=\@@subscript
- \catcode`^=\@@superscript}
-
-\egroup
-
-%D \macros
-%D {checkdelimiters, fakeleftdelimiter, fakerightdelimiter}
-%D
-%D Handy for non matching situations (as with mathml):
-%D
-%D \starttyping
-%D \checkdelimiters{... bla bla ...}
-%D \fakeleftdelimiter
-%D ... bla bla ...
-%D \fakerightdelimiter
-%D \stoptyping
-
-\newcount\delimitercount
-
-\def\leftfakedelimiter {\advance\delimitercount\minusone\gobbleoneargument}%
-\def\rightfakedelimiter{\advance\delimitercount\plusone \gobbleoneargument}%
-
-\def\checkdelimiters#1%
- {\delimitercount\zerocount
- \setbox\scratchbox\hbox\bgroup
- \let\left \leftfakedelimiter
- \let\right\rightfakedelimiter
- $#1\expandafter$\expandafter
- \egroup
- \expandafter\delimitercount\the\delimitercount\relax}
-
-\def\fakeleftdelimiter {\ifnum\delimitercount>\zerocount\left .\fi}
-\def\fakerightdelimiter{\ifnum\delimitercount<\zerocount\right.\fi}
-
-% \def\scaledmathdelimiter#1#2%
-% {\begingroup
-% \scratchdimen\lineheight
-% \hbox{$\left#2\vbox\!!to#1\scratchdimen{}\right.\n@space$}%
-% \endgroup}
-%
-% \let\scaledmathdelimiter\@@dobig
-%
-% \def\scaledmathopen #1#2{\mathopen {\scaledmathdelimiter{#1}{#2}}}
-% \def\scaledmathclose#1#2{\mathclose{\scaledmathdelimiter{#1}{#2}}}
-
-%D Needed for unicode:
-
-\def\nulloperator{\mathortext{\mathop{\null}}{\null}}
-
-%D Plugins.
-
-\loadmarkfile{math-ini}
-
-\protect \endinput
-
-\tracemathcollectiontrue
- \input math-tex \page
-\setupbodyfont[ams] \enablemathcollection[default] \input math-ams \page
-\setupbodyfont[lbr] \enablemathcollection[lbr] \input math-lbr \page
-\setupbodyfont[eul] \enablemathcollection[eul] \input math-eul \stoptext
diff --git a/tex/context/base/math-inl.mkiv b/tex/context/base/math-inl.mkiv
new file mode 100644
index 000000000..acbf02de7
--- /dev/null
+++ b/tex/context/base/math-inl.mkiv
@@ -0,0 +1,357 @@
+%D \module
+%D [ file=math-inl,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Inline,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Math Macros / Inline}
+
+\unprotect
+
+%D \macros
+%D {...}
+%D
+%D New and experimental: snapping big inline math!
+
+\newconditional\halfcrazymathlines % \settrue\halfcrazymathlines
+\newconditional\crazymathsnapping % \settrue\crazymathsnapping
+
+\appendtoks
+ \doifelse\@@mtgrid\v!yes \settrue\setfalse\crazymathsnapping
+ \doifelse\@@mtstep\v!halfline\settrue\setfalse\halfcrazymathlines
+\to \everysetuptextformulas
+
+\setuptextformulas
+ [\c!grid=\v!yes,
+ \c!step=\v!line]
+
+\newcount\crazymathhack
+
+\let\lastcrazymathline \!!zeropoint
+\let\lastcrazymathpage \!!zerocount
+\let\lastcrazymathprelines \!!zerocount
+\let\lastcrazymathpostlines\!!zerocount
+
+\def\crazymathtag{amh:\the\crazymathhack}
+\def\crazytexttag{\v!text:\lastcrazymathpage}
+
+\def\crazymathindent{\hskip\MPx\crazymathtag\hskip-\MPx\crazytexttag}
+
+\def\flushcrazymathbox
+ {\nextboxht\strutheight
+ \nextboxdp\strutdepth
+ \hbox{\iftracegridsnapping\ruledhbox\fi{\flushnextbox}}}
+
+\def\snappedinlineformula
+ {\dosingleempty\dosnappedinlineformula}
+
+%D \starttabulate[|Tl|l|]
+%D \NC - \NC half lines \NC \NR
+%D \NC + \NC full lines \NC \NR
+%D \NC = \NC force \NC \NR
+%D \NC < \NC force, minus pre \NC \NR
+%D \NC > \NC force, minus post \NC \NR
+%D \stoptabulate
+
+\def\inlinemathmargin{1pt}
+
+\settrue\autocrazymathsnapping
+
+% FROM NOW ON, CHANGES AS OPTIONS
+
+% TODO: SKYLINE (PREV LINE POS SCAN)
+
+% we can rewrite this in lua but maybe we don't need it
+% any more when we have proper snapping anyway
+
+\def\dosnappedinlineformula[#1]#2%
+ {\ifvmode\dontleavehmode\fi % tricky
+ \strut % prevents funny space at line break
+ \begingroup % interesting: \bgroup can make \vadjust disappear
+ \ifconditional\crazymathsnapping
+ \ifgridsnapping
+ \checktextbackgrounds % we need pos tracking, to be made less redundant
+ \donetrue
+ \else
+ \donefalse
+ \fi
+ \else
+ \donefalse
+ \fi
+ \!!doneafalse % forced or not auto
+ \!!donebfalse % too heigh
+ \!!donecfalse % too low
+ \!!donedfalse % less before
+ \!!doneefalse % less after
+ \ifdone
+ \setbox\nextbox\hbox{$#2$}%
+ \iftracegridsnapping
+ \setbox\nextbox\ruledhbox
+ {\incolortrue\localcolortrue
+ \backgroundline[gray]{\showstruts\strut\flushnextbox}}%
+ \fi
+ \def\docommand##1%
+ {\doif{##1}-{\settrue \halfcrazymathlines}%
+ \doif{##1}+{\setfalse\halfcrazymathlines}%
+ \doif{##1}={\!!doneatrue}%
+ \doif{##1}<{\!!donedtrue}%
+ \doif{##1}>{\!!doneetrue}}%
+ \processcommalist[#1]\docommand
+ \if!!doneb
+ \if!!donec \else
+ \setfalse\halfcrazymathlines
+ \fi
+ \else
+ \if!!donec
+ \setfalse\halfcrazymathlines
+ \fi
+ \fi
+ \donefalse
+ \if!!donea
+ \donetrue
+ \scratchdimen \nextboxht
+ \advance\scratchdimen .5\lineheight
+ \nextboxht\scratchdimen
+ \scratchdimen \nextboxdp
+ \advance\scratchdimen .5\lineheight
+ \nextboxdp\scratchdimen
+ \else\ifdim\nextboxht>\strutht
+ \donetrue
+ \else\ifdim\nextboxdp>\strutdp
+ \donetrue
+ \fi\fi\fi
+ \ifconditional\autocrazymathsnapping \else \if!!donea \else
+ % don't compensate, just snap to strut
+ \donefalse
+ % signal for next else, snap line to strut
+ \!!doneatrue
+ \fi \fi
+ \fi
+ \ifdone
+ % analyze height
+ \scratchdimen\inlinemathmargin
+ \advance\scratchdimen \strutht
+ \ifdim\nextboxht<\scratchdimen \else \!!donebtrue \fi
+ % analyze depth
+ \scratchdimen\inlinemathmargin
+ \advance\scratchdimen \strutdp
+ \ifdim\nextboxdp<\scratchdimen \else \!!donectrue \fi
+ % analyzed or forced
+ \ifdone
+ \global\advance\crazymathhack\plusone
+ \donefalse
+ \ifnum\MPp\crazymathtag=\lastcrazymathpage\relax
+ \ifdim\MPy\crazymathtag=\lastcrazymathline\relax
+ \donetrue
+ \fi
+ \fi
+ \ifnum\MPp\crazymathtag=\zerocount \donefalse \fi
+ \ifdim\MPy\crazymathtag=\zeropoint \donefalse \fi
+ \ifdone
+ % same page and same line
+ \else
+ \global\let\lastcrazymathprelines \!!zerocount
+ \global\let\lastcrazymathpostlines\!!zerocount
+ \xdef\lastcrazymathpage{\MPp\crazymathtag}%
+ \xdef\lastcrazymathline{\MPy\crazymathtag}%
+ \fi
+ \if!!doneb
+ % \getrawnoflines\nextboxht
+ \scratchdimen\nextboxht
+ \advance\scratchdimen-\strutht
+ \getnoflines\scratchdimen
+ \if!!doned \advance\noflines\minusone \fi
+ \scratchcounter\noflines
+ \advance\noflines-\lastcrazymathprelines\relax
+ \ifnum\noflines>\zerocount
+ \xdef\lastcrazymathprelines{\the\scratchcounter}%
+ \scratchdimen\noflines\lineheight
+ \ifconditional\halfcrazymathlines
+ \advance\scratchdimen-.5\lineheight
+ \fi
+ \advance\scratchdimen-\strutdepth
+ \setbox\scratchbox\null
+ \wd\scratchbox2\bodyfontsize
+ \ht\scratchbox\scratchdimen
+ \dp\scratchbox\strutdepth
+ %%% top correction code (see below)
+ \normalvadjust pre
+ {%\allowbreak % sometimes breaks spacing
+ \forgetall
+ \crazymathindent
+ \iftracegridsnapping
+ \setbox\scratchbox\hbox
+ {\incolortrue\localcolortrue\green
+ \ruledhbox{\box\scratchbox}}%
+ \fi
+ \box\scratchbox
+ \endgraf
+ \nobreak}%
+ \else\ifnum\scratchcounter>\zerocount
+ \normalvadjust pre
+ {\nobreak}%
+ \fi\fi
+ \fi
+ \if!!donec
+ % \getrawnoflines\nextboxdp
+ \scratchdimen\nextboxdp
+ \advance\scratchdimen-\strutdp
+ \getnoflines\scratchdimen
+ \if!!donee \advance\noflines\minusone \fi
+ \scratchcounter\noflines
+ \advance\noflines-\lastcrazymathpostlines\relax
+ \ifnum\noflines>\zerocount
+ \donetrue
+ \else\ifnum\lastcrazymathpostlines=\zerocount
+ \donetrue
+ \else
+ \donefalse
+ \fi\fi
+ \else
+ \donefalse
+ \fi
+ \ifdone
+ \xdef\lastcrazymathpostlines{\the\scratchcounter}%
+ \ifnum\lastcrazymathpostlines=\zerocount
+ \global\let\lastcrazymathpostlines\!!plusone
+ \fi
+ \hbox{\setposition\crazymathtag\flushcrazymathbox}%
+ \scratchdimen\noflines\lineheight
+ \advance\scratchdimen-\lineheight
+ \advance\scratchdimen+\strutheight
+ \ifdim\scratchdimen>\zeropoint \else
+ \scratchdimen\strutheight % todo : test for half lines
+ \fi
+ \ifconditional\halfcrazymathlines
+ \advance\scratchdimen-.5\lineheight
+ \fi
+ \setbox\scratchbox\null
+ \wd\scratchbox2\bodyfontsize
+ \ht\scratchbox\scratchdimen
+ \dp\scratchbox\strutdepth
+ \normalvadjust
+ {\forgetall
+ \crazymathindent
+ \iftracegridsnapping
+ \setbox\scratchbox\hbox
+ {\incolortrue\localcolortrue\color[blue]{\ruledhbox{\box\scratchbox}}}%
+ \fi
+ \box\scratchbox
+ \endgraf
+ % precaution: else we stick below the text bottom
+ \ifconditional\halfcrazymathlines
+ \allowbreak
+ \else
+ \vskip-\lineheight
+ \vskip \lineheight
+ \fi}%
+ \else
+ \hbox{\setposition\crazymathtag\flushcrazymathbox}%
+ \fi
+ \else
+ \flushcrazymathbox
+ \fi
+ \else\if!!donea
+ \flushcrazymathbox
+ \else
+ \mathematics{#2}%
+ \fi\fi
+ \endgroup}
+
+\let\tform\mathematics
+\let\gform\snappedinlineformula
+
+% test set:
+%
+% \startbuffer
+% Crazy math \gform {1+x} or \gform {\dorecurse {100} {1+} 1 =
+% 101} and even gore crazy \gform {2^{2^2}_{1_1}}
+% again\dorecurse {20} { and again} \gform {\sqrt {\frac
+% {x^{5^5}} {\frac {1} {2}}}} even gore\dorecurse {50} { and
+% gore} \tform {\dorecurse {12} {\gform {\sqrt {\frac
+% {x^{5^5}} {3}}}+\gform {\sqrt {\frac {x^{5^5}} {\frac {1}
+% {2}}}}+}x=10}\dorecurse{20} { super crazy math}: \tform
+% {\dorecurse {30} {\gform {\sqrt {\frac {x^{5^5}} {3}}}+
+% \gform {\sqrt {\frac {x^{5^5}} {\frac {1} {2}}}}+ }x = 10},
+% and we're\dorecurse {20} { done}!
+% \stopbuffer
+%
+% \setupcolors[state=start] \setuppapersize[S6][S6]
+%
+% \showgrid \tracegridsnappingtrue \showstruts
+%
+% \starttext
+% \setuplayout[grid=yes,lines=15]\getbuffer \page
+% \setuplayout[grid=yes,lines=16]\getbuffer \page
+% \setuplayout[grid=yes,lines=17]\getbuffer \page
+% \setuplayout[grid=yes,lines=18]\getbuffer \page
+% \setuplayout[grid=yes,lines=19]\getbuffer \page
+% \stoptext
+%
+% test
+%
+% \startregels
+% \gform[<]{35 \cdot p^{\frac{3}{4}} = 70}
+% \gform{12{,}4 \cdot d^3 = 200}
+% \gform{a \cdot x^b}.
+% \gform{12x^6 \cdot \negative 3x^4}
+% \gform{\frac{12x^6}{\negative 3x^4}}
+% \gform{(4x^2)^3}
+% \gform{4x \sqrt{x} \cdot 3x^2}
+% \gform{\frac{2x^4}{4x \sqrt{x}}}
+% \gform{y = a \cdot x^b}.
+% \gform{y_1 = \frac{15x^2}{x}}
+% \gform{y_2 = x \cdot \sqrt{x}}
+% \gform{y_3 = \frac{6x^3}{x^2}}
+% \gform[<]{y_4 = \left(2x^2\right)^{\frac{1}{2}}}
+% \gform{y_1 = \frac{4x^5}{x^2}}
+% \gform{y_2 = 4 \cdot \sqrt{x}}
+% \gform{y_3 = 4x^3}
+% \gform{y_4 = \frac{100x}{\sqrt{x}}}
+% \gform[<]{y_5 = 4 \cdot x^{\frac{1}{2}}}
+% \gform{y_6 = \frac{1}{2} x \cdot 4x^2}
+% \gform{y_7 = 2 \cdot x^3}
+% \gform{y_8 = 100 \cdot x^{\frac{1}{2}}}
+% \gform{4x^8 \cdot 8x^3}
+% \gform{\frac{4x^8}{8x^3}}
+% \gform{\left(\negative3x^4\right)^3}
+% \gform{x^3 \sqrt{x} \cdot 3x^2}
+% \gform{\frac{6x^3}{x^2 \sqrt{x}}}
+% \gform{\frac{6}{2x^4}}
+% \gform{\frac{1}{3x^6}}
+% \gform{\frac{12x^8}{4x^{10}}}
+% \gform{\frac{4}{\sqrt{x}}}
+% \gform{\frac{1}{2x \sqrt{x}}}
+% \gform{\frac{2{,}25}{p} = 0{,}35}
+% \gform{4{,}50 + \frac{300}{k} = 4{,}70}
+% \gform{\frac{1200}{k+12} - 42 = 6}
+% \stopregels
+
+%D \macros
+%D {enableautomath}
+%D
+%D The next one can be dangerous, but handy in controlled
+%D situations.
+
+\bgroup \catcode`\$=\active
+
+\gdef\enableautomath
+ {\catcode`\$=\active
+ \def$##1${\snappedinlineformula{##1}}}
+
+% \gdef\enableautomath
+% {\catcode`\$=\active
+% \def${\doifnextcharelse$\doautodmath\doautoimath}%
+% \def\doautoimath##1${\snappedinlineformula{##1}}%
+% \def\doautodmath$##1$${\startformula##1\stopformula}}
+
+\egroup
+
+\protect \endinput
diff --git a/tex/context/base/math-int.mkiv b/tex/context/base/math-int.mkiv
new file mode 100644
index 000000000..8ac2d4776
--- /dev/null
+++ b/tex/context/base/math-int.mkiv
@@ -0,0 +1,87 @@
+%D \module
+%D [ file=math-int,
+%D version=2007.07.19,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Scripts,
+%D author={Hans Hagen \& Taco Hoekwater \& Aditya Mahajan},
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Integrals}
+
+\unprotect
+
+%D \startbuffer
+%D $\int_a^b f(x) dx$ and also
+%D $\iint_a^b f(x,y) dxdy$, $\iiint_a^b f(x,y) dxdy$,
+%D $\iiiint_a^b f(x) dx$
+%D \startformula
+%D \int_a^b f(x) dx \quad
+%D \iint_a^b f(x) dx \quad
+%D \iiint_a^b f(x) dx \quad
+%D \iiiint_a^b f(x) dx \quad
+%D \stopformula
+%D \stopbuffer
+%D
+%D Default: \getbuffer
+%D
+%D Displaylimits: \setupmathematics[integral=displaylimits] \getbuffer
+%D
+%D Limits: \setupmathematics[integral=limits] \getbuffer
+
+\chardef\intlimitcode\zerocount % 0 nolimits 1 displaylimits 2 limits
+
+\def\intlimits
+ {\ifcase\intlimitcode \nolimits \or \displaylimits \or \limits \fi}
+
+\ifx\v!integral\undefined \def\v!integral{integral} \fi
+
+\appendtoks
+ \processaction
+ [\mathematicsparameter\v!integral]
+ [ nolimits=>\chardef\intlimitcode\zerocount,
+ displaylimits=>\chardef\intlimitcode\plusone,
+ limits=>\chardef\intlimitcode\plustwo]%
+\to \everysetupmathematics
+
+\setupmathematics
+ [\v!integral=nolimits]
+
+%D More integrals (AM):
+
+\definemathcommand [iint] {\repeatintegral\plusone }
+\definemathcommand [iiint] {\repeatintegral\plustwo }
+\definemathcommand [iiiint] {\repeatintegral\plusthree}
+
+\def\repeatintegral#1%
+ {\scratchtoks\emptytoks
+ \let\dointlimits\donothing
+ \let\dodointlimits\intlimits
+ \dorecurse{#1}{\appendtoks \intop \dointkern \to \scratchtoks}
+ \appendtoks \intop \dointlimits \dodointlimits \to \scratchtoks
+ \edef\dodorepeatintegral{\the\scratchtoks}%
+ \futurelet\next\dorepeatintegral}
+
+%D If the \type{\limits} option is used after \type{\iint}, use
+%D \type{\mathop} and fudge the left hand space a bit to make the
+%D subscript visually centered.
+
+\def\dointkern
+ {\mkern-6mu\mathchoice{\mkern-3mu}{}{}{}}
+
+\def\dorepeatintegral
+ {\ifx\next\limits \dointlimitcorrection \else
+ \ifx\next\displaylimits \dointlimitcorrection \else
+ \ifx\next\nolimits \donothing \else
+ \ifcase\intlimitcode\else \dointlimitcorrection \fi\fi\fi\fi
+ \dodorepeatintegral}
+
+\def\dointlimitcorrection
+ {\mkern-7mu\mathchoice{\mkern-2mu}{}{}{}%
+ \mathop\bgroup\mkern7mu\mathchoice{\mkern2mu}{}{}{}\let\dointlimits\egroup}
+
+\protect \endinput
diff --git a/tex/context/base/math-lbr.tex b/tex/context/base/math-lbr.tex
index ecc3632b1..7ac7c3aff 100644
--- a/tex/context/base/math-lbr.tex
+++ b/tex/context/base/math-lbr.tex
@@ -394,12 +394,12 @@
\stopmathcollection
\def\LBRroot#1#2%
- {\setbox\z@\hbox{$\m@th#1\sqrt{#2}$}
- \dimen@\ht\z@ \advance\dimen@-\dp\z@
- \mkern5mu\raise.6\dimen@\copy\rootbox \mkern-7.5mu \box\z@}
+ {\setbox\zerocount\hbox{$\mathsurround\zeropoint#1\sqrt{#2}$}
+ \dimen@\ht\zerocount \advance\dimen@-\dp\zerocount
+ \mkern5mu\raise.6\dimen@\copy\rootbox \mkern-7.5mu \box\zerocount}
\def\LBRmatrix#1%
- {\null\,\vcenter{\normalbaselines\m@th
+ {\null\,\vcenter{\normalbaselines\mathsurround\zeropoint
\ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
\mathstrut\crcr\noalign{\kern-0.9\baselineskip}
#1\crcr\mathstrut\crcr\noalign{\kern-0.9\baselineskip}}}\,}
diff --git a/tex/context/base/math-map.lua b/tex/context/base/math-map.lua
new file mode 100644
index 000000000..0229790c2
--- /dev/null
+++ b/tex/context/base/math-map.lua
@@ -0,0 +1,365 @@
+if not modules then modules = { } end modules ['math-map'] = {
+ version = 1.001,
+ comment = "companion to math-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Remapping mathematics alphabets.</p>
+--ldx]]--
+
+-- oldstyle: not really mathematics but happened to be part of
+-- the mathematics fonts in cmr
+--
+-- persian: we will also provide mappers for other
+-- scripts
+
+-- todo: alphabets namespace
+-- maybe: script/scriptscript dynamic,
+
+local type, next = type, next
+
+mathematics = mathematics or { }
+
+-- we could use one level less and have tf etc be tables directly but the
+-- following approach permits easier remapping of a-a, A-Z and 0-9 to
+-- fallbacks; symbols is currently mostly greek
+
+mathematics.alphabets = {
+ regular = {
+ tf = {
+ digits = 0x00030,
+ ucletters = 0x00041,
+ lcletters = 0x00061,
+ symbols = {
+ [0x0391]=0x0391, [0x0392]=0x0392, [0x0393]=0x0393, [0x0394]=0x0394, [0x0395]=0x0395,
+ [0x0396]=0x0396, [0x0397]=0x0397, [0x0398]=0x0398, [0x0399]=0x0399, [0x039A]=0x039A,
+ [0x039B]=0x039B, [0x039C]=0x039C, [0x039D]=0x039D, [0x039E]=0x039E, [0x039F]=0x039F,
+ [0x03A0]=0x03A0, [0x03A1]=0x03A1, [0x03A3]=0x03A3, [0x03A4]=0x03A4, [0x03A5]=0x03A5,
+ [0x03A6]=0x03A6, [0x03A7]=0x03A7, [0x03A8]=0x03A8, [0x03A9]=0x03A9, [0x03B1]=0x03B1,
+ [0x03B2]=0x03B2, [0x03B3]=0x03B3, [0x03B4]=0x03B4, [0x03B5]=0x03B5, [0x03B6]=0x03B6,
+ [0x03B7]=0x03B7, [0x03B8]=0x03B8, [0x03B9]=0x03B9, [0x03BA]=0x03BA, [0x03BB]=0x03BB,
+ [0x03BC]=0x03BC, [0x03BD]=0x03BD, [0x03BE]=0x03BE, [0x03BF]=0x03BF, [0x03C0]=0x03C0,
+ [0x03C1]=0x03C1, [0x03C2]=0x03C2, [0x03C3]=0x03C3, [0x03C4]=0x03C4, [0x03C5]=0x03C5,
+ [0x03C6]=0x03C6, [0x03C7]=0x03C7, [0x03C8]=0x03C8, [0x03C9]=0x03C9, [0x03D1]=0x03D1,
+ [0x03D5]=0x03D5, [0x03D6]=0x03D6, [0x03F0]=0x03F0, [0x03F1]=0x03F1, [0x03F4]=0x03F4,
+ [0x03F5]=0x03F5, [0x2202]=0x2202, [0x2207]=0x2207,
+ },
+ },
+ it = {
+ ucletters = 0x1D434,
+ lcletters = { -- H
+ [0x00061]=0x1D44E, [0x00062]=0x1D44F, [0x00063]=0x1D450, [0x00064]=0x1D451, [0x00065]=0x1D452,
+ [0x00066]=0x1D453, [0x00067]=0x1D454, [0x00068]=0x0210E, [0x00069]=0x1D456, [0x0006A]=0x1D457,
+ [0x0006B]=0x1D458, [0x0006C]=0x1D459, [0x0006D]=0x1D45A, [0x0006E]=0x1D45B, [0x0006F]=0x1D45C,
+ [0x00070]=0x1D45D, [0x00071]=0x1D45E, [0x00072]=0x1D45F, [0x00073]=0x1D460, [0x00074]=0x1D461,
+ [0x00075]=0x1D462, [0x00076]=0x1D463, [0x00077]=0x1D464, [0x00078]=0x1D465, [0x00079]=0x1D466,
+ [0x0007A]=0x1D467,
+ },
+ symbols = {
+ [0x0391]=0x1D6E2, [0x0392]=0x1D6E3, [0x0393]=0x1D6E4, [0x0394]=0x1D6E5, [0x0395]=0x1D6E6,
+ [0x0396]=0x1D6E7, [0x0397]=0x1D6E8, [0x0398]=0x1D6E9, [0x0399]=0x1D6EA, [0x039A]=0x1D6EB,
+ [0x039B]=0x1D6EC, [0x039C]=0x1D6ED, [0x039D]=0x1D6EE, [0x039E]=0x1D6EF, [0x039F]=0x1D6F0,
+ [0x03A0]=0x1D6F1, [0x03A1]=0x1D6F2, [0x03A3]=0x1D6F4, [0x03A4]=0x1D6F5, [0x03A5]=0x1D6F6,
+ [0x03A6]=0x1D6F7, [0x03A7]=0x1D6F8, [0x03A8]=0x1D6F9, [0x03A9]=0x1D6FA, [0x03B1]=0x1D6FC,
+ [0x03B2]=0x1D6FD, [0x03B3]=0x1D6FE, [0x03B4]=0x1D6FF, [0x03B5]=0x1D700, [0x03B6]=0x1D701,
+ [0x03B7]=0x1D702, [0x03B8]=0x1D703, [0x03B9]=0x1D704, [0x03BA]=0x1D705, [0x03BB]=0x1D706,
+ [0x03BC]=0x1D707, [0x03BD]=0x1D708, [0x03BE]=0x1D709, [0x03BF]=0x1D70A, [0x03C0]=0x1D70B,
+ [0x03C1]=0x1D70C, [0x03C2]=0x1D70D, [0x03C3]=0x1D70E, [0x03C4]=0x1D70F, [0x03C5]=0x1D710,
+ [0x03C6]=0x1D711, [0x03C7]=0x1D712, [0x03C8]=0x1D713, [0x03C9]=0x1D714, [0x03D1]=0x1D717,
+ [0x03D5]=0x1D719, [0x03D6]=0x1D71B, [0x03F0]=0x1D718, [0x03F1]=0x1D71A, [0x03F4]=0x1D6F3,
+ [0x03F5]=0x1D716, [0x2202]=0x1D715, [0x2207]=0x1D6FB,
+ },
+ },
+ bf= {
+ digits = 0x1D7CE,
+ ucletters = 0x1D400,
+ lcletters = 0x1D41A,
+ symbols = {
+ [0x0391]=0x1D6A8, [0x0392]=0x1D6A9, [0x0393]=0x1D6AA, [0x0394]=0x1D6AB, [0x0395]=0x1D6AC,
+ [0x0396]=0x1D6AD, [0x0397]=0x1D6AE, [0x0398]=0x1D6AF, [0x0399]=0x1D6B0, [0x039A]=0x1D6B1,
+ [0x039B]=0x1D6B2, [0x039C]=0x1D6B3, [0x039D]=0x1D6B4, [0x039E]=0x1D6B5, [0x039F]=0x1D6B6,
+ [0x03A0]=0x1D6B7, [0x03A1]=0x1D6B8, [0x03A3]=0x1D6BA, [0x03A4]=0x1D6BB, [0x03A5]=0x1D6BC,
+ [0x03A6]=0x1D6BD, [0x03A7]=0x1D6BE, [0x03A8]=0x1D6BF, [0x03A9]=0x1D6C0, [0x03B1]=0x1D6C2,
+ [0x03B2]=0x1D6C3, [0x03B3]=0x1D6C4, [0x03B4]=0x1D6C5, [0x03B5]=0x1D6C6, [0x03B6]=0x1D6C7,
+ [0x03B7]=0x1D6C8, [0x03B8]=0x1D6C9, [0x03B9]=0x1D6CA, [0x03BA]=0x1D6CB, [0x03BB]=0x1D6CC,
+ [0x03BC]=0x1D6CD, [0x03BD]=0x1D6CE, [0x03BE]=0x1D6CF, [0x03BF]=0x1D6D0, [0x03C0]=0x1D6D1,
+ [0x03C1]=0x1D6D2, [0x03C2]=0x1D6D3, [0x03C3]=0x1D6D4, [0x03C4]=0x1D6D5, [0x03C5]=0x1D6D6,
+ [0x03C6]=0x1D6D7, [0x03C7]=0x1D6D8, [0x03C8]=0x1D6D9, [0x03C9]=0x1D6DA, [0x03D1]=0x1D6DD,
+ [0x03D5]=0x1D6DF, [0x03D6]=0x1D6E1, [0x03F0]=0x1D6DE, [0x03F1]=0x1D6E0, [0x03F4]=0x1D6B9,
+ [0x03F5]=0x1D6DC, [0x2202]=0x1D6DB, [0x2207]=0x1D6C1,
+ },
+ },
+ bi = {
+ ucletters = 0x1D468,
+ lcletters = 0x1D482,
+ symbols = {
+ [0x0391]=0x1D71C, [0x0392]=0x1D71D, [0x0393]=0x1D71E, [0x0394]=0x1D71F, [0x0395]=0x1D720,
+ [0x0396]=0x1D721, [0x0397]=0x1D722, [0x0398]=0x1D723, [0x0399]=0x1D724, [0x039A]=0x1D725,
+ [0x039B]=0x1D726, [0x039C]=0x1D727, [0x039D]=0x1D728, [0x039E]=0x1D729, [0x039F]=0x1D72A,
+ [0x03A0]=0x1D72B, [0x03A1]=0x1D72C, [0x03A3]=0x1D72E, [0x03A4]=0x1D72F, [0x03A5]=0x1D730,
+ [0x03A6]=0x1D731, [0x03A7]=0x1D732, [0x03A8]=0x1D733, [0x03A9]=0x1D734, [0x03B1]=0x1D736,
+ [0x03B2]=0x1D737, [0x03B3]=0x1D738, [0x03B4]=0x1D739, [0x03B5]=0x1D73A, [0x03B6]=0x1D73B,
+ [0x03B7]=0x1D73C, [0x03B8]=0x1D73D, [0x03B9]=0x1D73E, [0x03BA]=0x1D73F, [0x03BB]=0x1D740,
+ [0x03BC]=0x1D741, [0x03BD]=0x1D742, [0x03BE]=0x1D743, [0x03BF]=0x1D744, [0x03C0]=0x1D745,
+ [0x03C1]=0x1D746, [0x03C2]=0x1D747, [0x03C3]=0x1D748, [0x03C4]=0x1D749, [0x03C5]=0x1D74A,
+ [0x03C6]=0x1D74B, [0x03C7]=0x1D74C, [0x03C8]=0x1D74D, [0x03C9]=0x1D74E, [0x03D1]=0x1D751,
+ [0x03D5]=0x1D753, [0x03D6]=0x1D755, [0x03F0]=0x1D752, [0x03F1]=0x1D754, [0x03F4]=0x1D72D,
+ [0x03F5]=0x1D750, [0x2202]=0x1D74F, [0x2207]=0x1D735,
+ },
+ },
+ },
+ sansserif = {
+ tf = {
+ digits = 0x1D7E2,
+ ucletters = 0x1D5A0,
+ lcletters = 0x1D5BA,
+ },
+ it = {
+ ucletters = 0x1D608,
+ lcletters = 0x1D622,
+ },
+ bf = {
+ digits = 0x1D7EC,
+ ucletters = 0x1D5D4,
+ lcletters = 0x1D5EE,
+ symbols = {
+ [0x0391]=0x1D756, [0x0392]=0x1D757, [0x0393]=0x1D758, [0x0394]=0x1D759, [0x0395]=0x1D75A,
+ [0x0396]=0x1D75B, [0x0397]=0x1D75C, [0x0398]=0x1D75D, [0x0399]=0x1D75E, [0x039A]=0x1D75F,
+ [0x039B]=0x1D760, [0x039C]=0x1D761, [0x039D]=0x1D762, [0x039E]=0x1D763, [0x039F]=0x1D764,
+ [0x03A0]=0x1D765, [0x03A1]=0x1D766, [0x03A3]=0x1D768, [0x03A4]=0x1D769, [0x03A5]=0x1D76A,
+ [0x03A6]=0x1D76B, [0x03A7]=0x1D76C, [0x03A8]=0x1D76D, [0x03A9]=0x1D76E, [0x03B1]=0x1D770,
+ [0x03B2]=0x1D771, [0x03B3]=0x1D772, [0x03B4]=0x1D773, [0x03B5]=0x1D774, [0x03B6]=0x1D775,
+ [0x03B7]=0x1D776, [0x03B8]=0x1D777, [0x03B9]=0x1D778, [0x03BA]=0x1D779, [0x03BB]=0x1D77A,
+ [0x03BC]=0x1D77B, [0x03BD]=0x1D77C, [0x03BE]=0x1D77D, [0x03BF]=0x1D77E, [0x03C0]=0x1D77F,
+ [0x03C1]=0x1D780, [0x03C2]=0x1D781, [0x03C3]=0x1D782, [0x03C4]=0x1D783, [0x03C5]=0x1D784,
+ [0x03C6]=0x1D785, [0x03C7]=0x1D786, [0x03C8]=0x1D787, [0x03C9]=0x1D788, [0x03D1]=0x1D78B,
+ [0x03D5]=0x1D78D, [0x03D6]=0x1D78F, [0x03F0]=0x1D78C, [0x03F1]=0x1D78E, [0x03F4]=0x1D767,
+ [0x03F5]=0x1D78A, [0x2202]=0x1D789, [0x2207]=0x1D76F,
+ },
+ },
+ bi = {
+ ucletters = 0x1D63C,
+ lcletters = 0x1D656,
+ symbols = {
+ [0x0391]=0x1D790, [0x0392]=0x1D791, [0x0393]=0x1D792, [0x0394]=0x1D793, [0x0395]=0x1D794,
+ [0x0396]=0x1D795, [0x0397]=0x1D796, [0x0398]=0x1D797, [0x0399]=0x1D798, [0x039A]=0x1D799,
+ [0x039B]=0x1D79A, [0x039C]=0x1D79B, [0x039D]=0x1D79C, [0x039E]=0x1D79D, [0x039F]=0x1D79E,
+ [0x03A0]=0x1D79F, [0x03A1]=0x1D7A0, [0x03A3]=0x1D7A2, [0x03A4]=0x1D7A3, [0x03A5]=0x1D7A4,
+ [0x03A6]=0x1D7A5, [0x03A7]=0x1D7A6, [0x03A8]=0x1D7A7, [0x03A9]=0x1D7A8, [0x03B1]=0x1D7AA,
+ [0x03B2]=0x1D7AB, [0x03B3]=0x1D7AC, [0x03B4]=0x1D7AD, [0x03B5]=0x1D7AE, [0x03B6]=0x1D7AF,
+ [0x03B7]=0x1D7B0, [0x03B8]=0x1D7B1, [0x03B9]=0x1D7B2, [0x03BA]=0x1D7B3, [0x03BB]=0x1D7B4,
+ [0x03BC]=0x1D7B5, [0x03BD]=0x1D7B6, [0x03BE]=0x1D7B7, [0x03BF]=0x1D7B8, [0x03C0]=0x1D7B9,
+ [0x03C1]=0x1D7BA, [0x03C2]=0x1D7BB, [0x03C3]=0x1D7BC, [0x03C4]=0x1D7BD, [0x03C5]=0x1D7BE,
+ [0x03C6]=0x1D7BF, [0x03C7]=0x1D7C0, [0x03C8]=0x1D7C1, [0x03C9]=0x1D7C2, [0x03D1]=0x1D7C5,
+ [0x03D5]=0x1D7C7, [0x03D6]=0x1D7C9, [0x03F0]=0x1D7C6, [0x03F1]=0x1D7C8, [0x03F4]=0x1D7A1,
+ [0x03F5]=0x1D7C4, [0x2202]=0x1D7C3, [0x2207]=0x1D7A9,
+ },
+ },
+ },
+ monospaced = {
+ tf = {
+ digits = 0x1D7F6,
+ ucletters = 0x1D670,
+ lcletters = 0x1D68A,
+ },
+ },
+ blackboard = { -- ok
+ tf = {
+ digits = 0x1D7D8,
+ ucletters = { -- C H N P Q R Z
+ [0x00041]=0x1D538, [0x00042]=0x1D539, [0x00043]=0x02102, [0x00044]=0x1D53B, [0x00045]=0x1D53C,
+ [0x00046]=0x1D53D, [0x00047]=0x1D53E, [0x00048]=0x0210D, [0x00049]=0x1D540, [0x0004A]=0x1D541,
+ [0x0004B]=0x1D542, [0x0004C]=0x1D543, [0x0004D]=0x1D544, [0x0004E]=0x02115, [0x0004F]=0x1D546,
+ [0x00050]=0x02119, [0x00051]=0x0211A, [0x00052]=0x0211D, [0x00053]=0x1D54A, [0x00054]=0x1D54B,
+ [0x00055]=0x1D54C, [0x00056]=0x1D54D, [0x00057]=0x1D54E, [0x00058]=0x1D54F, [0x00059]=0x1D550,
+ [0x0005A]=0x02124,
+ },
+ lcletters = 0x1D552,
+ },
+ },
+ fraktur = { -- ok
+ tf= {
+ ucletters = { -- C H I R Z
+ [0x00041]=0x1D504, [0x00042]=0x1D505, [0x00043]=0x0212D, [0x00044]=0x1D507, [0x00045]=0x1D508,
+ [0x00046]=0x1D509, [0x00047]=0x1D50A, [0x00048]=0x0210C, [0x00049]=0x02111, [0x0004A]=0x1D50D,
+ [0x0004B]=0x1D50E, [0x0004C]=0x1D50F, [0x0004D]=0x1D510, [0x0004E]=0x1D511, [0x0004F]=0x1D512,
+ [0x00050]=0x1D513, [0x00051]=0x1D514, [0x00052]=0x0211C, [0x00053]=0x1D516, [0x00054]=0x1D517,
+ [0x00055]=0x1D518, [0x00056]=0x1D519, [0x00057]=0x1D51A, [0x00058]=0x1D51B, [0x00059]=0x1D51C,
+ [0x0005A]=0x02128,
+ },
+ lcletters = 0x1D51E,
+ },
+ bf = {
+ ucletters = 0x1D56C,
+ lcletters = 0x1D586,
+ },
+ },
+ script = {
+ tf= {
+ ucletters = { -- B E F H I L M R -- P 2118
+ [0x00041]=0x1D49C, [0x00042]=0x0212C, [0x00043]=0x1D49E, [0x00044]=0x1D49F, [0x00045]=0x02130,
+ [0x00046]=0x02131, [0x00047]=0x1D4A2, [0x00048]=0x0210B, [0x00049]=0x02110, [0x0004A]=0x1D4A5,
+ [0x0004B]=0x1D4A6, [0x0004C]=0x02112, [0x0004D]=0x02133, [0x0004E]=0x1D4A9, [0x0004F]=0x1D4AA,
+ [0x00050]=0x1D4AB, [0x00051]=0x1D4AC, [0x00052]=0x0211B, [0x00053]=0x1D4AE, [0x00054]=0x1D4AF,
+ [0x00055]=0x1D4B0, [0x00056]=0x1D4B1, [0x00057]=0x1D4B2, [0x00058]=0x1D4B3, [0x00059]=0x1D4B4,
+ [0x0005A]=0x1D4B5,
+ },
+ lcletters = { -- E G O -- L 2113
+ [0x00061]=0x1D4B6, [0x00062]=0x1D4B7, [0x00063]=0x1D4B8, [0x00064]=0x1D4B9, [0x00065]=0x0212F,
+ [0x00066]=0x1D4BB, [0x00067]=0x0210A, [0x00068]=0x1D4BD, [0x00069]=0x1D4BE, [0x0006A]=0x1D4BF,
+ [0x0006B]=0x1D4C0, [0x0006C]=0x1D4C1, [0x0006D]=0x1D4C2, [0x0006E]=0x1D4C3, [0x0006F]=0x02134,
+ [0x00070]=0x1D4C5, [0x00071]=0x1D4C6, [0x00072]=0x1D4C7, [0x00073]=0x1D4C8, [0x00074]=0x1D4C9,
+ [0x00075]=0x1D4CA, [0x00076]=0x1D4CB, [0x00077]=0x1D4CC, [0x00078]=0x1D4CD, [0x00079]=0x1D4CE,
+ [0x0007A]=0x1D4CF,
+ }
+ },
+ bf = {
+ ucletters = 0x1D4D0,
+ lcletters = 0x1D4EA,
+ },
+ },
+}
+
+local alphabets = mathematics.alphabets
+local attribs = { }
+
+for alphabet, styles in next, alphabets do
+ for style, data in next, styles do
+ -- let's keep the long names (for tracing)
+ local n = #attribs+1
+ data.attribute = n
+ data.alphabet = alphabet
+ data.style = style
+ attribs[n] = data
+ end
+end
+
+-- beware, these are shared tables (no problem since they're not
+-- in unicode)
+
+alphabets.regular.it.digits = alphabets.regular.tf.digits
+alphabets.regular.bi.digits = alphabets.regular.bf.digits
+
+alphabets.sansserif.tf.symbols = alphabets.regular.tf.symbols
+alphabets.sansserif.tf.digits = alphabets.regular.tf.digits
+alphabets.sansserif.it.symbols = alphabets.regular.tf.symbols
+alphabets.sansserif.bi.digits = alphabets.regular.bf.digits
+
+alphabets.monospaced.tf.symbols = alphabets.sansserif.tf.symbols
+alphabets.monospaced.it = alphabets.sansserif.tf
+alphabets.monospaced.bf = alphabets.sansserif.tf
+alphabets.monospaced.bi = alphabets.sansserif.bf
+
+alphabets.blackboard.tf.symbols = alphabets.regular.tf.symbols
+alphabets.blackboard.it = alphabets.blackboard.tf
+alphabets.blackboard.bf = alphabets.blackboard.tf
+alphabets.blackboard.bi = alphabets.blackboard.bf
+
+alphabets.fraktur.tf.digits = alphabets.regular.tf.digits
+alphabets.fraktur.tf.symbols = alphabets.regular.tf.symbols
+alphabets.fraktur.bf.digits = alphabets.regular.bf.digits
+alphabets.fraktur.bf.symbols = alphabets.regular.bf.symbols
+alphabets.fraktur.it = alphabets.fraktur.tf
+alphabets.fraktur.bi = alphabets.fraktur.bf
+
+alphabets.script.tf.digits = alphabets.regular.tf.digits
+alphabets.script.tf.symbols = alphabets.regular.tf.symbols
+alphabets.script.bf.digits = alphabets.regular.bf.digits
+alphabets.script.bf.symbols = alphabets.regular.bf.symbols
+alphabets.script.it = alphabets.script.tf
+alphabets.script.bi = alphabets.script.bf
+
+alphabets.tt = alphabets.monospaced
+alphabets.ss = alphabets.sansserif
+alphabets.rm = alphabets.regular
+alphabets.bb = alphabets.blackboard
+alphabets.fr = alphabets.fraktur
+alphabets.sr = alphabets.script
+
+alphabets.serif = alphabets.regular
+alphabets.type = alphabets.monospaced
+alphabets.teletype = alphabets.monospaced
+
+function mathematics.to_a_style(attribute)
+ local r = attribs[attribute]
+ return r and r.style or "tf"
+end
+
+function mathematics.to_a_name(attribute)
+ local r = attribs[attribute]
+ return r and r.alphabet or "regular"
+end
+
+-- of course we could do some div/mod trickery instead
+
+--~ function mathematics.sync_a_both(attribute,alphabet,style)
+--~ local data = alphabets[alphabet or "regular"] or alphabets.regular
+--~ data = data[style or "tf"] or data.tf
+--~ return data and data.attribute or attribute
+--~ end
+
+--~ function mathematics.sync_a_style(attribute,style)
+--~ local r = attribs[attribute]
+--~ local alphabet = r and r.alphabet or "regular"
+--~ local data = alphabets[alphabet][style]
+--~ return data and data.attribute or attribute
+--~ end
+
+--~ function mathematics.sync_a_name(attribute,alphabet)
+--~ local r = attribs[attribute]
+--~ local style = r and r.style or "tf"
+--~ local data = alphabets[alphabet][style]
+--~ return data and data.attribute or attribute
+--~ end
+
+local mathalph = attributes.private("mathalph")
+
+local texattribute = tex.attribute
+
+function mathematics.sync_a_both(alphabet,style)
+ local data = alphabets[alphabet or "regular"] or alphabets.regular
+ data = data[style or "tf"] or data.tf
+ texattribute[mathalph] = data and data.attribute or texattribute[mathalph]
+end
+
+function mathematics.sync_a_style(style)
+ local r = attribs[attribute]
+ local alphabet = r and r.alphabet or "regular"
+ local data = alphabets[alphabet][style]
+ texattribute[mathalph] = data and data.attribute or texattribute[mathalph]
+end
+
+function mathematics.sync_a_name(alphabet)
+ local r = attribs[attribute]
+ local style = r and r.style or "tf"
+ local data = alphabets[alphabet][style]
+ texattribute[mathalph] = data and data.attribute or texattribute[mathalph]
+end
+
+local issymbol = mathematics.alphabets.regular.tf.symbols
+
+function mathematics.remap_alphabets(attribute,char)
+ -- we could use a map[attribute][char] => newchar but first we have
+ -- to finish the table
+ local offset = attribs[attribute]
+ if offset then
+ local newchar
+ if char >= 0x030 and char <= 0x039 then
+ local o = offset.digits
+ newchar = (type(o) == "table" and (o[char] or char)) or (char - 0x030 + o)
+ elseif char >= 0x041 and char <= 0x05A then
+ local o = offset.ucletters
+ newchar = (type(o) == "table" and (o[char] or char)) or (char - 0x041 + o)
+ elseif char >= 0x061 and char <= 0x07A then
+ local o = offset.lcletters
+ newchar = (type(o) == "table" and (o[char] or char)) or (char - 0x061 + o)
+ elseif issymbol[char] then
+ newchar = offset.symbols[char]
+ end
+ return newchar ~= char and newchar
+ end
+ return nil
+end
diff --git a/tex/context/base/math-mis.tex b/tex/context/base/math-mis.tex
deleted file mode 100644
index 1b1193fd4..000000000
--- a/tex/context/base/math-mis.tex
+++ /dev/null
@@ -1,49 +0,0 @@
-%D \module
-%D [ file=math-mis,
-%D version=2001.04.12,
-%D title=\CONTEXT\ Math Macros,
-%D subtitle=Miscelaneous Symbols,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright=\PRAGMA]
-%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 \starttyping
-%D \usemathcollection[mis]
-%D \stoptyping
-
-\def\styledmathcommand#1%
- {\mathchoice
- {\let\currentmathstyle\displaystyle#1}%
- {\let\currentmathstyle\textstyle#1}%
- {\let\currentmathstyle\scriptstyle#1}%
- {\let\currentmathstyle\scriptscriptstyle#1}}
-
-%D For Hong Feng:
-
-\def\geneq
- {\styledmathcommand\dogeneq}
-
-\def\dogeneq
- {\begingroup
- \setbox\scratchbox\hbox{$\currentmathstyle=$}%
- \hbox to \wd\scratchbox
- {\copy\scratchbox
- \hskip-\wd\scratchbox
- \hss\incolortrue\localcolortrue
- \color[white]{\vrule\!!height.6\ht\scratchbox\!!depth\zeropoint\!!width.2\wd\scratchbox}%
- \hss}%
- \endgroup}
-
-%D \startbuffer
-%D $a\string\geneq b^{a\string\geneq b^{a\string\geneq b}}$
-%D \stopbuffer
-%D
-%D \typebuffer \getbuffer
-
-\protect \endinput
diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua
new file mode 100644
index 000000000..6cdcc0114
--- /dev/null
+++ b/tex/context/base/math-noa.lua
@@ -0,0 +1,336 @@
+if not modules then modules = { } end modules ['math-noa'] = {
+ version = 1.001,
+ comment = "companion to math-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- beware: this is experimental code and there will be a more
+-- generic (attribute value driven) interface too but for the
+-- moment this is ok
+
+local utf = unicode.utf8
+
+local set_attribute = node.set_attribute
+local has_attribute = node.has_attribute
+local mlist_to_hlist = node.mlist_to_hlist
+local font_of_family = node.family_font
+local fontdata = fonts.ids
+
+local format, rep = string.format, string.rep
+local utfchar, utfbyte = utf.char, utf.byte
+
+noads = noads or { }
+
+local trace_remapping = false trackers.register("math.remapping", function(v) trace_remapping = v end)
+local trace_processing = false trackers.register("math.processing", function(v) trace_processing = v end)
+local trace_analyzing = false trackers.register("math.analyzing", function(v) trace_analyzing = v end)
+
+local noad_ord = 0
+local noad_op_displaylimits = 1
+local noad_op_limits = 2
+local noad_op_nolimits = 3
+local noad_bin = 4
+local noad_rel = 5
+local noad_open = 6
+local noad_close = 7
+local noad_punct = 8
+local noad_inner = 9
+local noad_under = 10
+local noad_over = 11
+local noad_vcenter = 12
+
+-- obsolete:
+--
+-- math_ord = node.id("ord") -- attr nucleus sub sup
+-- math_op = node.id("op") -- attr nucleus sub sup subtype
+-- math_bin = node.id("bin") -- attr nucleus sub sup
+-- math_rel = node.id("rel") -- attr nucleus sub sup
+-- math_punct = node.id("punct") -- attr nucleus sub sup
+--
+-- math_open = node.id("open") -- attr nucleus sub sup
+-- math_close = node.id("close") -- attr nucleus sub sup
+--
+-- math_inner = node.id("inner") -- attr nucleus sub sup
+-- math_vcenter = node.id("vcenter") -- attr nucleus sub sup
+-- math_under = node.id("under") -- attr nucleus sub sup
+-- math_over = node.id("over") -- attr nucleus sub sup
+
+local math_noad = node.id("noad") -- attr nucleus sub sup
+
+local math_accent = node.id("accent") -- attr nucleus sub sup accent
+local math_radical = node.id("radical") -- attr nucleus sub sup left degree
+local math_fraction = node.id("fraction") -- attr nucleus sub sup left right
+
+local math_box = node.id("sub_box") -- attr list
+local math_sub = node.id("sub_mlist") -- attr list
+local math_char = node.id("math_char") -- attr fam char
+local math_text_char = node.id("math_text_char") -- attr fam char
+local math_delim = node.id("delim") -- attr small_fam small_char large_fam large_char
+local math_style = node.id("style") -- attr style
+local math_choice = node.id("choice") -- attr display text script scriptscript
+local math_fence = node.id("fence") -- attr subtype
+
+local simple_noads = table.tohash {
+ math_noad,
+}
+
+local all_noads = {
+ math_noad,
+ math_box, math_sub,
+ math_char, math_text_char, math_delim, math_style,
+ math_accent, math_radical, math_fraction, math_choice, math_fence,
+}
+
+noads.processors = noads.processors or { }
+
+local function process(start,what,n)
+ if n then n = n + 1 else n = 0 end
+ while start do
+ if trace_processing then
+ texio.write_nl(format("%s%s",rep(" ",n or 0),tostring(start)))
+ end
+ local id = start.id
+ local proc = what[id]
+ if proc then
+ proc(start,what,n)
+ elseif id == math_char or id == math_text_char or id == math_delim then
+ break
+ elseif id == math_style then
+ -- has a next
+ elseif id == math_noad then
+ local noad = start.nucleus if noad then process(noad,what,n) end -- list
+ noad = start.sup if noad then process(noad,what,n) end -- list
+ noad = start.sub if noad then process(noad,what,n) end -- list
+ elseif id == math_box or id == math_sub then
+ local noad = start.list if noad then process(noad,what,n) end -- list
+ elseif id == math_fraction then
+ local noad = start.num if noad then process(noad,what,n) end -- list
+ noad = start.denom if noad then process(noad,what,n) end -- list
+ noad = start.left if noad then process(noad,what,n) end -- delimiter
+ noad = start.right if noad then process(noad,what,n) end -- delimiter
+ elseif id == math_choice then
+ local noad = start.display if noad then process(noad,what,n) end -- list
+ noad = start.text if noad then process(noad,what,n) end -- list
+ noad = start.script if noad then process(noad,what,n) end -- list
+ noad = start.scriptscript if noad then process(noad,what,n) end -- list
+ elseif id == math_fence then
+ local noad = start.delim if noad then process(noad,what,n) end -- delimiter
+ elseif id == math_radical then
+ local noad = start.nucleus if noad then process(noad,what,n) end -- list
+ noad = start.sup if noad then process(noad,what,n) end -- list
+ noad = start.sub if noad then process(noad,what,n) end -- list
+ noad = start.left if noad then process(noad,what,n) end -- delimiter
+ noad = start.degree if noad then process(noad,what,n) end -- list
+ elseif id == math_accent then
+ local noad = start.nucleus if noad then process(noad,what,n) end -- list
+ noad = start.sup if noad then process(noad,what,n) end -- list
+ noad = start.sub if noad then process(noad,what,n) end -- list
+ noad = start.accent if noad then process(noad,what,n) end -- list
+ noad = start.bot_accent if noad then process(noad,what,n) end -- list
+ else
+ -- glue, penalty, etc
+ end
+ start = start.next
+ end
+end
+
+noads.process = process
+
+-- character remapping
+
+local attribute = attributes.private("mathalph")
+
+noads.processors.relocate = { }
+
+local function report_remap(tag,id,old,new,extra)
+ logs.report("math","remapping %s in font %s from U+%04X (%s) to U+%04X (%s)%s",tag,id,old,utfchar(old),new,utfchar(new),extra or "")
+end
+
+local remap_alphabets = mathematics.remap_alphabets
+local fcs = fonts.color.set
+
+noads.processors.relocate[math_char] = function(pointer)
+ local a = has_attribute(pointer,attribute)
+ if a and a > 0 then
+ local fam = pointer.fam
+ set_attribute(pointer,attribute,0)
+ local char = pointer.char
+ local newchar = remap_alphabets(a,char)
+ if newchar then
+ local id = font_of_family(fam)
+ local tfmdata = fontdata[id]
+ if tfmdata and tfmdata.characters[newchar] then -- we could probably speed this up
+ if trace_remapping then
+ report_remap("char",id,char,newchar)
+ end
+ if trace_analyzing then
+ fcs(pointer,"font:isol")
+ end
+ pointer.char = newchar
+ return
+ elseif trace_remapping then
+ report_remap("char",id,char,newchar," fails")
+ end
+ end
+ end
+ if trace_analyzing then
+ fcs(pointer,"font:medi")
+ end
+end
+
+noads.processors.relocate[math_text_char] = function(pointer)
+ if trace_analyzing then
+ fcs(pointer,"font:init")
+ end
+end
+
+noads.processors.relocate[math_delim] = function(pointer)
+ if trace_analyzing then
+ fcs(pointer,"font:fina")
+ end
+end
+
+function noads.relocate_characters(head,tail,style,penalties)
+ process(head,noads.processors.relocate)
+ return true
+end
+
+-- some resize options (this works ok because the content is
+-- empty and no larger next will be forced)
+--
+-- beware: we don't use \delcode but \Udelcode and as such have
+-- no large_fam; also, we need to check for subtype and/or
+-- small_fam not being 0 because \. sits in 0,0 by default
+--
+-- todo: just replace the character by an ord noad
+-- and remove the right delimiter as well
+
+local attribute = attributes.private("mathsize")
+
+noads.processors.resize = { }
+
+noads.processors.resize[math_fence] = function(pointer)
+ if pointer.subtype == 1 then -- left
+ local a = has_attribute(pointer,attribute)
+ if a and a > 0 then
+ set_attribute(pointer,attribute,0)
+ local d = pointer.delim
+ local df = d.small_fam
+ local id = font_of_family(df)
+ if id > 0 then
+ local ch = d.small_char
+ d.small_char = mathematics.big(fontdata[id],ch,a)
+ end
+ end
+ end
+end
+
+function noads.resize_characters(head,tail,style,penalties)
+ process(head,noads.processors.resize)
+ return true
+end
+
+-- respacing
+
+local attribute = attributes.private("mathpunc")
+
+noads.processors.respace = { }
+
+local chardata = characters.data
+
+-- only [nd,ll,ul][po][nd,ll,ul]
+
+noads.processors.respace[math_noad] = function(pointer)
+ if pointer.subtype == noad_ord then
+ local a = has_attribute(pointer,attribute)
+ if a and a > 0 then
+ set_attribute(pointer,attribute,0)
+ local current_nucleus = pointer.nucleus
+ if current_nucleus.id == math_char then
+ local current_char = current_nucleus.char
+ local fc = chardata[current_char]
+ fc = fc and fc.category
+ if fc == "nd" or fc == "ll" or fc == "lu" then
+ local next_noad = pointer.next
+ if next_noad and next_noad.id == math_noad and next_noad.subtype == noad_punct then
+ local next_nucleus = next_noad.nucleus
+ if next_nucleus.id == math_char then
+ local next_char = next_nucleus.char
+ local nc = chardata[next_char]
+ nc = nc and nc.category
+ if nc == "po" then
+ local last_noad = next_noad.next
+ if last_noad and last_noad.id == math_noad and last_noad.subtype == noad_ord then
+ local last_nucleus = last_noad.nucleus
+ if last_nucleus.id == math_char then
+ local last_char = last_nucleus.char
+ local lc = chardata[last_char]
+ lc = lc and lc.category
+ if lc == "nd" or lc == "ll" or lc == "lu" then
+ local ord = node.new(math_noad) -- todo: pool
+ ord.subtype, ord.nucleus, ord.sub, ord.sup, ord.attr = noad_ord, next_noad.nucleus, next_noad.sub, next_noad.sup, next_noad.attr
+ -- next_noad.nucleus, next_noad.sub, next_noad.sup, next_noad.attr = nil, nil, nil, nil
+ next_noad.nucleus, next_noad.sub, next_noad.sup = nil, nil, nil -- else crash with attributes ref count
+ --~ next_noad.attr = nil
+ ord.next = last_noad
+ pointer.next = ord
+ node.free(next_noad)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+
+function noads.respace_characters(head,tail,style,penalties)
+ noads.process(head,noads.processors.respace)
+ return true
+end
+
+-- the normal builder
+
+function noads.mlist_to_hlist(head,tail,style,penalties)
+ return mlist_to_hlist(head,style,penalties), true
+end
+
+tasks.new (
+ "math",
+ {
+ "normalizers",
+ "builders",
+ }
+)
+
+--~ tasks.appendaction("math", "normalizers", "noads.relocate_characters", nil, "nohead")
+--~ tasks.appendaction("math", "normalizers", "noads.resize_characters", nil, "nohead")
+--~ tasks.appendaction("math", "normalizers", "noads.respace_characters", nil, "nohead")
+--~ tasks.appendaction("math", "builders", "noads.mlist_to_hlist", nil, "notail")
+
+local actions = tasks.actions("math")
+
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+
+function nodes.processors.mlist_to_hlist(head,style,penalties)
+ starttiming(noads)
+ local head, done = actions(head,nil,style,penalties)
+ stoptiming(noads)
+ return head, done
+end
+
+callback.register('mlist_to_hlist',nodes.processors.mlist_to_hlist)
+
+-- tracing
+
+statistics.register("math processing time", function()
+ if statistics.elapsedindeed(noads) then
+ return format("%s seconds", statistics.elapsedtime(noads))
+ end
+end)
diff --git a/tex/context/base/math-pln.tex b/tex/context/base/math-pln.mkii
index ffa16c8f5..0bacc40a2 100644
--- a/tex/context/base/math-pln.tex
+++ b/tex/context/base/math-pln.mkii
@@ -1,8 +1,8 @@
%D \module
%D [ file=math-pln,
%D version=2001.11.16,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Efficient \PLAIN\ \TEX\ loading,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Plain Helpers,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,38 +11,41 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% \points should become \bodyfontsize
+
%D This is a temporary module, some of this code will move to
%D the other math modules.
+\writestatus{loading}{ConTeXt Math Macros / Plain Helpers}
+
\unprotect
-\ifx\displ@y\unefined \let\displ@y\relax\fi
-\ifx\m@th \unefined \let\m@th \relax\fi
+\ifx\displ@y\undefined \let\displ@y\relax\fi
\newbox\rootbox
-\def\root#1\of%
- {\setbox\rootbox\hbox{$\m@th\scriptscriptstyle{#1}$}%
+\def\root#1\of
+ {\setbox\rootbox\hbox{$\mathsurround\zeropoint\scriptscriptstyle{#1}$}%
\mathpalette\r@@t}
\def\r@@t#1#2% will be overloaded
- {\setbox\z@\hbox{$\m@th#1\sqrt{#2}$}\dimen@\ht\z@
- \advance\dimen@-\dp\z@
+ {\setbox\zerocount\hbox{$\mathsurround\zeropoint#1\sqrt{#2}$}\dimen@\ht\zerocount
+ \advance\dimen@-\dp\zerocount
\mkern5mu\raise.6\dimen@\copy\rootbox
- \mkern-10mu\box\z@}
+ \mkern-10mu\box\zerocount}
\def\mathhexbox#1#2#3%
{\leavevmode
- \hbox{$\m@th\mathchar"#1#2#3$}}
+ \hbox{$\mathsurround\zeropoint\mathchar"#1#2#3$}}
\def\oalign#1%
{\leavevmode
\vtop
- {\baselineskip\z@skip \lineskip.25ex%
+ {\baselineskip\zeroskip \lineskip.25ex%
\ialign{##\crcr#1\crcr}}}
\def\o@lign
- {\lineskiplimit\z@ \oalign}
+ {\lineskiplimit\zeropoint \oalign}
\def\ooalign % chars over each other
{\lineskiplimit-\maxdimen
@@ -54,40 +57,55 @@
\dimen@}
\def\dots
- {\relax\ifmmode\ldots\else$\m@th\ldots\,$\fi}
+ {\relax\ifmmode\ldots\else$\mathsurround\zeropoint\ldots\,$\fi}
\def\hrulefill
{\leaders\hrule\hfill}
\def\dotfill
- {\cleaders\hbox{$\m@th \mkern1.5mu.\mkern1.5mu$}\hfill}
+ {\cleaders\hbox{$\mathsurround\zeropoint \mkern1.5mu.\mkern1.5mu$}\hfill}
\def\rightarrowfill
- {$\m@th\smash-\mkern-7mu%
+ {$\mathsurround\zeropoint\smash-\mkern-7mu%
\cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill
\mkern-7mu\mathord\rightarrow$}
\def\leftarrowfill
- {$\m@th\mathord\leftarrow\mkern-7mu%
+ {$\mathsurround\zeropoint\mathord\leftarrow\mkern-7mu%
\cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill
\mkern-7mu\smash-$}
% must go to math-tex
-\mathchardef\braceld="37A
-\mathchardef\bracerd="37B
-\mathchardef\bracelu="37C
-\mathchardef\braceru="37D
+\ifx\braceld\undefined
+ % mkii values
+ \mathchardef\braceld="37A
+ \mathchardef\bracerd="37B
+ \mathchardef\bracelu="37C
+ \mathchardef\braceru="37D
+\fi
\def\downbracefill
- {$\m@th\setbox\z@\hbox{$\braceld$}%
- \braceld\leaders\vrule\!!height\ht\z@\!!depth\z@\hfill\braceru
- \bracelu\leaders\vrule\!!height\ht\z@\!!depth\z@\hfill\bracerd$}
+ {$\mathsurround\zeropoint\setbox\zerocount\hbox{$\braceld$}%
+ \braceld\leaders\vrule\!!height\ht\zerocount\!!depth\zeropoint\hfill\braceru
+ \bracelu\leaders\vrule\!!height\ht\zerocount\!!depth\zeropoint\hfill\bracerd$}
\def\upbracefill
- {$\m@th\setbox\z@\hbox{$\braceld$}%
- \bracelu\leaders\vrule\!!height\ht\z@\!!depth\z@\hfill\bracerd
- \braceld\leaders\vrule\!!height\ht\z@\!!depth\z@\hfill\braceru$}
+ {$\mathsurround\zeropoint\setbox\zerocount\hbox{$\braceld$}%
+ \bracelu\leaders\vrule\!!height\ht\zerocount\!!depth\zeropoint\hfill\bracerd
+ \braceld\leaders\vrule\!!height\ht\zerocount\!!depth\zeropoint\hfill\braceru$}
+
+% hm, shouldn't that be \kern3\bodyfontsize
+
+\def\overbrace#1%
+ {\mathop{\vbox{\mathsurround\zeropoint\ialign{##\crcr\noalign{\kern3\points}
+ \downbracefill\crcr\noalign{\kern3\points\nointerlineskip}
+ $\hfil\displaystyle{#1}\hfil$\crcr}}}\limits}
+
+\def\underbrace#1%
+ {\mathop{\vtop{\mathsurround\zeropoint\ialign{##\crcr
+ $\hfil\displaystyle{#1}\hfil$\crcr\noalign{\kern3\points\nointerlineskip}
+ \upbracefill\crcr\noalign{\kern3\points}}}}\limits}
\let\sp=^ % will become obsolete
\let\sb=_ % will become obsolete
@@ -136,31 +154,18 @@
\def\Longleftrightarrow{\Leftarrow\joinrel\Rightarrow}
\def\overrightarrow#1%
- {\vbox{\m@th\ialign{##\crcr
- \rightarrowfill\crcr\noalign{\kern-\p@\nointerlineskip}
+ {\vbox{\mathsurround\zeropoint\ialign{##\crcr
+ \rightarrowfill\crcr\noalign{\kern-\onepoint\nointerlineskip}
$\hfil\displaystyle{#1}\hfil$\crcr}}}
\def\overleftarrow#1%
- {\vbox{\m@th\ialign{##\crcr
- \leftarrowfill\crcr\noalign{\kern-\p@\nointerlineskip}
+ {\vbox{\mathsurround\zeropoint\ialign{##\crcr
+ \leftarrowfill\crcr\noalign{\kern-\onepoint\nointerlineskip}
$\hfil\displaystyle{#1}\hfil$\crcr}}}
-\def\overbrace#1%
- {\mathop{\vbox{\m@th\ialign{##\crcr\noalign{\kern3\p@}
- \downbracefill\crcr\noalign{\kern3\p@\nointerlineskip}
- $\hfil\displaystyle{#1}\hfil$\crcr}}}\limits}
-
-\def\underbrace#1%
- {\mathop{\vtop{\m@th\ialign{##\crcr
- $\hfil\displaystyle{#1}\hfil$\crcr\noalign{\kern3\p@\nointerlineskip}
- \upbracefill\crcr\noalign{\kern3\p@}}}}\limits}
-
\def\skew#1#2#3%
- {{\muskip\z@#1mu\divide\muskip\z@\tw@ \mkern\muskip\z@
- #2{\mkern-\muskip\z@{#3}\mkern\muskip\z@}\mkern-\muskip\z@}{}}
-
-\def\n@space
- {\nulldelimiterspace\z@ \m@th}
+ {{\muskip\zerocount#1mu\divide\muskip\zerocount\plustwo \mkern\muskip\zerocount
+ #2{\mkern-\muskip\zerocount{#3}\mkern\muskip\zerocount}\mkern-\muskip\zerocount}{}}
\def\choose{\atopwithdelims()}
\def\brack {\atopwithdelims[]}
@@ -173,32 +178,32 @@
{#1\scriptstyle {#2}}%
{#1\scriptscriptstyle{#2}}}
-\def\cong%
+\def\cong
{\mathrel{\mathpalette\@vereq\sim}} % congruence sign
\def\@vereq#1#2%
- {\lower.5\p@\vbox{\lineskiplimit\maxdimen\lineskip-.5\p@
- \ialign{$\m@th#1\hfil##\hfil$\crcr#2\crcr=\crcr}}}
+ {\lower.5\points\vbox{\lineskiplimit\maxdimen\lineskip-.5\points
+ \ialign{$\mathsurround\zeropoint#1\hfil##\hfil$\crcr#2\crcr=\crcr}}}
-\def\notin%
+\def\notin% can be mkiv'd
{\mathrel{\mathpalette\c@ncel\in}}
\def\c@ncel#1#2%
- {\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}
+ {\mathsurround\zeropoint\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}
\def\rightleftharpoons%
{\mathrel{\mathpalette\rlh@{}}}
\def\rlh@#1%
{\vcenter
- {\m@th
+ {\mathsurround\zeropoint
\hbox
{\ooalign
{\raise2pt\hbox{$#1\rightharpoonup$}\crcr
$#1\leftharpoondown$}}}}
\def\buildrel#1\over#2%
- {\mathrel{\mathop{\kern\z@#2}\limits^{#1}}}
+ {\mathrel{\mathop{\kern\zerocount#2}\limits^{#1}}}
\def\doteq
{\buildrel\textstyle.\over=}
@@ -225,7 +230,7 @@
\,%
\vcenter
{\normalbaselines
- \m@th
+ \mathsurround\zeropoint
\ialign{$##\hfil$&\quad##\hfil\crcr#1\crcr}}%
\right.}
@@ -233,7 +238,7 @@
{\null
\,%
\vcenter
- {\normalbaselines\m@th
+ {\normalbaselines\mathsurround\zeropoint
\ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
\mathstrut\crcr\noalign{\kern-\baselineskip}
#1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}%
@@ -242,30 +247,30 @@
\def\pmatrix#1%
{\left(\matrix{#1}\right)}
-\newdimen\p@renwd
+\newdimen\mathparentwd
-% \setbox0=\hbox{\tenex B} \p@renwd=\wd0 % width of the big left (
+% \setbox0=\hbox{\tenex B} \mathparentwd=\wd0 % width of the big left (
\def\bordermatrix#1%
{\begingroup
- \m@th
- \setbox\z@\vbox
- {\def\cr{\crcr\noalign{\kern2\p@\global\let\cr\endline}}%
- \ialign{$##$\hfil\kern2\p@\kern\p@renwd&\thinspace\hfil$##$\hfil
+ \mathsurround\zeropoint
+ \setbox\zerocount\vbox
+ {\def\cr{\crcr\noalign{\kern2\points\global\let\cr\endline}}%
+ \ialign{$##$\hfil\kern2\points\kern\mathparentwd&\thinspace\hfil$##$\hfil
&&\quad\hfil$##$\hfil\crcr
\omit\strut\hfil\crcr\noalign{\kern-\baselineskip}%
#1\crcr\omit\strut\cr}}%
- \setbox\tw@\vbox
- {\unvcopy\z@\global\setbox\@ne\lastbox}%
- \setbox\tw@\hbox
- {\unhbox\@ne\unskip\global\setbox\@ne\lastbox}%
- \setbox\tw@\hbox
- {$\kern\wd\@ne\kern-\p@renwd\left(\kern-\wd\@ne
- \global\setbox\@ne\vbox{\box\@ne\kern2\p@}%
- \vcenter{\kern-\ht\@ne\unvbox\z@\kern-\baselineskip}\,\right)$}%
+ \setbox\plustwo\vbox
+ {\unvcopy\zerocount\global\setbox\plusone\lastbox}%
+ \setbox\plustwo\hbox
+ {\unhbox\plusone\unskip\global\setbox\plusone\lastbox}%
+ \setbox\plustwo\hbox
+ {$\kern\wd\plusone\kern-\mathparentwd\left(\kern-\wd\plusone
+ \global\setbox\plusone\vbox{\box\plusone\kern2\points}%
+ \vcenter{\kern-\ht\plusone\unvbox\zerocount\kern-\baselineskip}\,\right)$}%
\null
\;%
- \vbox{\kern\ht\@ne\box\tw@}%
+ \vbox{\kern\ht\plusone\box\plustwo}%
\endgroup}
% \def\openup{\afterassignment\@penup\dimen@=}
@@ -291,19 +296,19 @@
\,%
\vcenter
{\openup\displayopenupvalue % was \openup\jot
- \m@th
+ \mathsurround\zeropoint
\ialign
{\strut\hfil$\displaystyle{##}$&$\displaystyle{{}##}$\hfil\crcr
#1\crcr}}%
\,}
\def\@lign % restore inside \displ@y
- {\tabskip\z@skip
+ {\tabskip\zeroskip
\everycr{}}
\def\displaylines#1%
{\displ@y
- \tabskip\z@skip
+ \tabskip\zeroskip
\halign
{\hbox to \displaywidth{$\@lign\hfil\displaystyle##\hfil$}\crcr
#1\crcr}}
@@ -312,16 +317,16 @@
{\displ@y
\tabskip\centering
\halign to \displaywidth
- {\hfil$\@lign\displaystyle{##}$\tabskip\z@skip
+ {\hfil$\@lign\displaystyle{##}$\tabskip\zeroskip
&$\@lign\displaystyle{{}##}$\hfil\tabskip\centering
- &\llap{$\@lign##$}\tabskip\z@skip\crcr
+ &\llap{$\@lign##$}\tabskip\zeroskip\crcr
#1\crcr}}
\def\leqalignno#1%
{\displ@y
\tabskip\centering
\halign to \displaywidth
- {\hfil$\@lign\displaystyle{##}$\tabskip\z@skip
+ {\hfil$\@lign\displaystyle{##}$\tabskip\zeroskip
&$\@lign\displaystyle{{}##}$\hfil\tabskip\centering
&\kern-\displaywidth\rlap{$\@lign##$}\tabskip\displaywidth\crcr
#1\crcr}}
diff --git a/tex/context/base/math-pln.mkiv b/tex/context/base/math-pln.mkiv
new file mode 100644
index 000000000..23d7d935c
--- /dev/null
+++ b/tex/context/base/math-pln.mkiv
@@ -0,0 +1,298 @@
+%D \module
+%D [ file=math-pln,
+%D version=2001.11.16,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Plain Helpers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 temporary module, some of this code will move to
+%D the other math modules. Much is copied from Plain \TEX.
+
+% \points should become \bodyfontsize
+
+\writestatus{loading}{ConTeXt Math Macros / Plain Helpers}
+
+\unprotect
+
+\ifx\displ@y\undefined \let\displ@y\relax\fi
+
+\def\oalign#1%
+ {\leavevmode
+ \vtop
+ {\baselineskip\zeroskip \lineskip.25ex%
+ \ialign{##\crcr#1\crcr}}}
+
+\def\o@lign
+ {\lineskiplimit\zeropoint \oalign}
+
+\def\ooalign % chars over each other
+ {\lineskiplimit-\maxdimen
+ \oalign}
+
+\def\sh@ft#1% kern by #1 times the current slant
+ {\dimen@#1%
+ \kern\expandafter\withoutpt\the\slantperpoint
+ \dimen@}
+
+\def\dots
+ {\relax\ifmmode\ldots\else$\mathsurround\zeropoint\ldots\,$\fi}
+
+\def\hrulefill
+ {\leaders\hrule\hfill}
+
+\def\dotfill
+ {\cleaders\hbox{$\mathsurround\zeropoint \mkern1.5mu.\mkern1.5mu$}\hfill}
+
+\def\rightarrowfill
+ {$\mathsurround\zeropoint\smash-\mkern-7mu%
+ \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill
+ \mkern-7mu\mathord\rightarrow$}
+
+\def\leftarrowfill
+ {$\mathsurround\zeropoint\mathord\leftarrow\mkern-7mu%
+ \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill
+ \mkern-7mu\smash-$}
+
+\let\sp=^ % will become obsolete
+\let\sb=_ % will become obsolete
+
+\ifx\,\undefined \def\,{\mskip \thinmuskip } \fi
+\ifx\>\undefined \def\>{\mskip \medmuskip } \fi
+\ifx\;\undefined \def\;{\mskip \thickmuskip} \fi
+\ifx\!\undefined \def\!{\mskip-\thinmuskip } \fi
+\ifx\*\undefined \def\*{\discretionary{\thinspace\the\textfont2\char2}{}{}} \fi
+
+% {\catcode`\'=\active \gdef'{^\bgroup\prim@s}}
+
+\def\activemathquote{^\bgroup\prim@s}
+
+\def\prim@s
+ {\prime\futurelet\next\pr@m@s}
+
+\def\pr@m@s
+ {\ifx'\next
+ \@EA\pr@@@s
+ \else\ifx^\next
+ \@EAEAEA\pr@@@t
+ \else
+ \@EAEAEA\egroup
+ \fi\fi}
+
+\def\pr@@@s#1%
+ {\prim@s}
+
+\def\pr@@@t#1#2%
+ {#2\egroup}
+
+% {\catcode`\_=\active \global\let_=\_} % _ in math is either subscript or \_
+
+\let\activemathunderscore\_
+
+\def\relbar {\mathrel{\smash-}} % - has the same height as +
+\def\Relbar {\mathrel=}
+
+\def\Longrightarrow {\Relbar\joinrel\Rightarrow}
+\def\longrightarrow {\relbar\joinrel\rightarrow}
+\def\longleftarrow {\leftarrow\joinrel\relbar}
+\def\Longleftarrow {\Leftarrow\joinrel\Relbar}
+\def\longmapsto {\mapstochar\longrightarrow}
+\def\longleftrightarrow{\leftarrow\joinrel\rightarrow}
+\def\Longleftrightarrow{\Leftarrow\joinrel\Rightarrow}
+
+\def\choose{\atopwithdelims()}
+\def\brack {\atopwithdelims[]}
+\def\brace {\atopwithdelims\{\}}
+
+\def\mathpalette#1#2%
+ {\mathchoice
+ {#1\displaystyle {#2}}%
+ {#1\textstyle {#2}}%
+ {#1\scriptstyle {#2}}%
+ {#1\scriptscriptstyle{#2}}}
+
+\def\cong
+ {\mathrel{\mathpalette\@vereq\sim}} % congruence sign
+
+\def\@vereq#1#2%
+ {\lower.5\points\vbox{\lineskiplimit\maxdimen\lineskip-.5\points
+ \ialign{$\mathsurround\zeropoint#1\hfil##\hfil$\crcr#2\crcr=\crcr}}}
+
+\def\notin
+ {\mathrel{\mathpalette\c@ncel\in}}
+
+\def\c@ncel#1#2%
+ {\mathsurround\zeropoint\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}
+
+\def\rightleftharpoons
+ {\mathrel{\mathpalette\rlh@{}}}
+
+\def\rlh@#1%
+ {\vcenter
+ {\mathsurround\zeropoint
+ \hbox
+ {\ooalign
+ {\raise2pt\hbox{$#1\rightharpoonup$}\crcr
+ $#1\leftharpoondown$}}}}
+
+\def\buildrel#1\over#2%
+ {\mathrel{\mathop{\kern\zeropoint#2}\limits^{#1}}}
+
+\def\doteq
+ {\buildrel\textstyle.\over=}
+
+\ifx\mfunction\undefined \def\mfunction#1{\mathbin{\rm#1}} \fi
+
+\def\bmod
+ {\nonscript
+ \mskip-\medmuskip
+ \mkern5mu
+ \mfunction{mod}%
+ \penalty900
+ \mkern5mu
+ \nonscript
+ \mskip-\medmuskip}
+
+\def\pmod#1%
+ {\allowbreak
+ \mkern18mu
+ (\mfunction{mod}\,\,#1)}
+
+\def\cases#1%
+ {\left\{%
+ \,%
+ \vcenter
+ {\normalbaselines
+ \mathsurround\zeropoint
+ \ialign{$##\hfil$&\quad##\hfil\crcr#1\crcr}}%
+ \right.}
+
+\def\matrix#1%
+ {\null
+ \,%
+ \vcenter
+ {\normalbaselines\mathsurround\zeropoint
+ \ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
+ \mathstrut\crcr\noalign{\kern-\baselineskip}
+ #1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}%
+ \,}
+
+\def\pmatrix#1%
+ {\left(\matrix{#1}\right)}
+
+\newdimen\mathparentwd
+
+% \setbox0=\hbox{\tenex B} \mathparentwd=\wd0 % width of the big left (
+
+\def\bordermatrix#1%
+ {\begingroup
+ \mathsurround\zeropoint
+ \setbox\zerocount\vbox
+ {\def\cr{\crcr\noalign{\kern2\points\global\let\cr\endline}}%
+ \ialign{$##$\hfil\kern2\points\kern\mathparentwd&\thinspace\hfil$##$\hfil
+ &&\quad\hfil$##$\hfil\crcr
+ \omit\strut\hfil\crcr\noalign{\kern-\baselineskip}%
+ #1\crcr\omit\strut\cr}}%
+ \setbox\plustwo\vbox
+ {\unvcopy\zerocount\global\setbox\plusone\lastbox}%
+ \setbox\plustwo\hbox
+ {\unhbox\plusone\unskip\global\setbox\plusone\lastbox}%
+ \setbox\plustwo\hbox
+ {$\kern\wd\plusone\kern-\mathparentwd\left(\kern-\wd\plusone
+ \global\setbox\plusone\vbox{\box\plusone\kern2\points}%
+ \vcenter{\kern-\ht\plusone\unvbox\zerocount\kern-\baselineskip}\,\right)$}%
+ \null
+ \;%
+ \vbox{\kern\ht\plusone\box\plustwo}%
+ \endgroup}
+
+% \def\openup{\afterassignment\@penup\dimen@=}
+%
+% \def\@penup{\advance\lineskip\dimen@
+% \advance\baselineskip\dimen@
+% \advance\lineskiplimit\dimen@}
+
+\def\openup
+ {\afterassignment\doopenup\scratchdimen=}
+
+\def\doopenup
+ {\advance\lineskip \scratchdimen
+ \advance\baselineskip \scratchdimen
+ \advance\lineskiplimit\scratchdimen}
+
+% \def\jot{.25\bodyfontsize} % plain tex: 3 pt (todo: better name and configurable)
+
+\def\displayopenupvalue{.25\bodyfontsize}
+
+\def\eqalign#1%
+ {\null
+ \,%
+ \vcenter
+ {\openup\displayopenupvalue % was \openup\jot
+ \mathsurround\zeropoint
+ \ialign
+ {\strut\hfil$\displaystyle{##}$&$\displaystyle{{}##}$\hfil\crcr
+ #1\crcr}}%
+ \,}
+
+\def\@lign % restore inside \displ@y
+ {\tabskip\zeroskip
+ \everycr{}}
+
+\def\displaylines#1%
+ {\displ@y
+ \tabskip\zeroskip
+ \halign
+ {\hbox to \displaywidth{$\@lign\hfil\displaystyle##\hfil$}\crcr
+ #1\crcr}}
+
+\def\eqalignno#1%
+ {\displ@y
+ \tabskip\centering
+ \halign to \displaywidth
+ {\hfil$\@lign\displaystyle{##}$\tabskip\zeroskip
+ &$\@lign\displaystyle{{}##}$\hfil\tabskip\centering
+ &\llap{$\@lign##$}\tabskip\zeroskip\crcr
+ #1\crcr}}
+
+\def\leqalignno#1%
+ {\displ@y
+ \tabskip\centering
+ \halign to \displaywidth
+ {\hfil$\@lign\displaystyle{##}$\tabskip\zeroskip
+ &$\@lign\displaystyle{{}##}$\hfil\tabskip\centering
+ &\kern-\displaywidth\rlap{$\@lign##$}\tabskip\displaywidth\crcr
+ #1\crcr}}
+
+% temporary here
+
+% \startcatcodetable \mthcatcodes
+% \setcatcodetable\ctxcatcodes
+% \catcode`\_ = 13
+% \catcode`\' = 13
+% \stopcatcodetable
+%
+% \letcatcodecommand \mthcatcodes `\_ \activemathunderscore
+% \letcatcodecommand \mthcatcodes `\' \activemathquote
+
+% \appendtoks \setcatcodetable\mthcatcodes \to \everymath : spoils xml
+
+% tricky, but some day we will reimplement math
+
+\bgroup
+ \catcode`\_ = 13
+ \catcode`\' = 13
+ \doglobal\appendtoks
+ \let_\activemathunderscore
+ \let'\activemathquote
+ \to \everymathematics
+\egroup
+
+% so far
+
+\protect \endinput
diff --git a/tex/context/base/math-run.tex b/tex/context/base/math-run.mkii
index affa8d5af..afe5b18b4 100644
--- a/tex/context/base/math-run.tex
+++ b/tex/context/base/math-run.mkii
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Math Macros / Runtime Macros}
+
\unprotect
\ifx\showmathmodern\undefined \global\chardef\showmathmodern\zerocount \fi
diff --git a/tex/context/base/math-scr.mkiv b/tex/context/base/math-scr.mkiv
new file mode 100644
index 000000000..43355679f
--- /dev/null
+++ b/tex/context/base/math-scr.mkiv
@@ -0,0 +1,215 @@
+%D \module
+%D [ file=math-scr,
+%D version=2007.07.19,
+%D title=\CONTEXT\ Math Macros,
+%D subtitle=Scripts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Math Macros / Scripts}
+
+\unprotect
+
+%D \macros
+%D {super, sub}
+%D
+%D \TEX\ uses \type{^} and \type{_} for entering super- and
+%D subscript mode. We want however a bit more control than
+%D normally provided, and therefore provide \type {\super}
+%D and \type{sub}.
+
+\global\let\normalsuper=^
+\global\let\normalsuber=_
+
+\newcount\supersubmode
+
+\newevery\everysupersub \EverySuperSub
+
+\appendtoks \advance\supersubmode \plusone \to \everysupersub
+
+\appendtoks
+ \gridsupsubstyle
+\to \everysupersub
+
+\appendtoks
+ \doifelse\@@mtsize\v!small
+ {\let\gridsupsubstyle \scriptscriptstyle
+ \let\gridsupsubbodyfont \setsmallbodyfont}%
+ {\let\gridsupsubstyle \scriptstyle
+ \let\gridsupsubbodyfont \relax}%
+\to \everysetuptextformulas
+
+\setuptextformulas
+ [\c!size=\v!normal]
+
+\def\dogridsupsub#1#2%
+ {\begingroup
+ \setbox\nextbox\iftracegridsnapping\ruledhbox\else\hbox\fi
+ {\gridsupsubbodyfont
+ $\strut^{\the\everysupersub#1}_{\the\everysupersub#2}$}%
+ \nextboxht\strutheight
+ \nextboxdp\strutdepth
+ \flushnextbox
+ \endgroup}
+
+\def\gridsupsub
+ {\ifconditional\crazymathsnapping
+ \ifgridsnapping
+ \@EAEAEA\dogridsupsub
+ \else
+ \@EAEAEA\normalsupsub
+ \fi
+ \else
+ \@EA\normalsupsub
+ \fi}
+
+\def\normalsupsub#1#2%
+ {^{\the\everysupersub#1}_{\the\everysupersub#2}}
+
+\appendtoks
+ \let\gridsupsubstyle \relax
+ \let\gridsupsubbodyfont\relax
+ \let\gridsupsub \normalsupsub
+\to \everydisplay
+
+\def\super#1{^{\the\everysupersub#1}}
+\def\suber#1{_{\the\everysupersub#1}}
+\def\supsub#1#2{\super{#1}\suber{#2}}
+\def\subsup#1#2{\suber{#1}\super{#2}}
+
+%\def\super#1{\gridsupsub{#1}{}} %
+%\def\suber#1{\gridsupsub{}{#1}} %
+%
+%\def\supsub#1#2{\gridsupsub{#1}{#2}}
+%\def\subsup#1#2{\gridsupsub{#2}{#1}}
+
+\def\gridsuper#1{\gridsupsub{#1}{}}
+\def\gridsuber#1{\gridsupsub{}{#1}}
+
+% \let\sup\super % math char
+% \let\sub\suber
+
+% test set:
+%
+% \startbuffer
+% \sform{x\frac{1}{2}}
+% \sform{x\sup{\frac{1}{2}} + x\sup{2} + 2}
+% \sform{x\supsub{\frac{1}{2}}{\frac{1}{2}} + x\sup{2} + 2}
+% \stopbuffer
+%
+% \typebuffer
+%
+% \startlines
+% \getbuffer
+% \stoplines
+%
+% \startbuffer
+% $x\frac{1}{2}$
+% $x\sup{\frac{1}{2}} + x^2 + 2$
+% $x\supsub{\frac{1}{2}}{\frac{1}{2}} + x^2 + 2$
+% \stopbuffer
+%
+% \typebuffer
+%
+% \start
+% \enablesupersub
+% \enableautomath
+% \startlines
+% \getbuffer
+% \stoplines
+% \stop
+
+%D \macros
+%D {enablesupersub,enablesimplesupersub}
+%D
+%D We can let \type {^} and \type {_} act like \type {\super}
+%D and \type {\sub} by saying \type {\enablesupersub}.
+
+\bgroup
+\catcode`\^=\@@active
+\catcode`\_=\@@active
+\gdef\enablesupersub
+ {\catcode`\^=\@@active
+ \def^{\ifmmode\expandafter\super\else\expandafter\normalsuper\fi}%
+ \catcode`\_=\@@active
+ \def_{\ifmmode\expandafter\suber\else\expandafter\normalsuber\fi}}
+\egroup
+
+%D \macros
+%D {restoremathstyle}
+%D
+%D We can pick up the current math style by calling \type
+%D {\restoremathstyle}.
+
+\def\restoremathstyle
+ {\ifmmode
+ \ifcase\supersubmode
+ \textstyle
+ \or
+ \scriptstyle
+ \else
+ \scriptscriptstyle
+ \fi
+ \fi}
+
+%D These macros were first needed by Frits Spijker (also
+%D known as Gajes) for typesetting the minus sign that is
+%D keyed into scientific calculators.
+
+% This is the first alternative, which works okay for the
+% minus, but less for the plus.
+%
+% \def\dodoraisedmathord#1#2#3%
+% {\mathord{{#2\raise.#1ex\hbox{#2#3}}}}
+%
+% \def\doraisedmathord#1%
+% {\mathchoice
+% {\dodoraisedmathord5\tf #1}%
+% {\dodoraisedmathord5\tf #1}%
+% {\dodoraisedmathord4\tfx #1}%
+% {\dodoraisedmathord3\tfxx#1}}
+%
+% \def\negative{\doraisedmathord-}
+% \def\positive{\doraisedmathord+}
+%
+% So, now we use the monospaced signs, that we also
+% define as symbol, so that they can be overloaded.
+
+\def\dodoraisedmathord#1#2#3%
+ {\mathord{{#2\raise.#1ex\hbox{#2\symbol[#3]}}}}
+
+\def\doraisedmathord#1%
+ {\mathchoice
+ {\dodoraisedmathord5\tf {#1}}%
+ {\dodoraisedmathord5\tf {#1}}%
+ {\dodoraisedmathord4\tx {#1}}%
+ {\dodoraisedmathord3\txx{#1}}}
+
+\def\dodonumbermathord#1#2%
+ {\setbox\scratchbox\hbox{0}%
+ \mathord{\hbox to \wd\scratchbox{\hss#1\symbol[#2]\hss}}}
+
+\def\donumbermathord#1%
+ {\mathchoice
+ {\dodonumbermathord\tf {#1}}%
+ {\dodonumbermathord\tf {#1}}%
+ {\dodonumbermathord\tx {#1}}%
+ {\dodonumbermathord\txx{#1}}}
+
+\definesymbol[positive] [\getglyph{Mono}{+}]
+\definesymbol[negative] [\getglyph{Mono}{-}]
+\definesymbol[zeroamount][\getglyph{Mono}{-}]
+
+\def\negative {\doraisedmathord{negative}}
+\def\positive {\doraisedmathord{positive}}
+\def\zeroamount{\donumbermathord{zeroamount}}
+
+%D How negative such a symbol looks is demonstrated in:
+%D $\negative 10^{\negative 10^{\negative 10}}$.
+
+\protect \endinput
diff --git a/tex/context/base/math-tex.tex b/tex/context/base/math-tex.tex
index 752f113b7..c833db956 100644
--- a/tex/context/base/math-tex.tex
+++ b/tex/context/base/math-tex.tex
@@ -232,7 +232,7 @@
\stopmathcollection
\def\PLAINangle
- {{\vbox{\ialign{$\m@th\scriptstyle##$\crcr
+ {{\vbox{\ialign{$\mathsurround\zeropoint\scriptstyle##$\crcr
\not\mathrel{\mkern14mu}\crcr
\noalign{\nointerlineskip}
\mkern2.5mu\leaders\hrule height.34pt\hfill\mkern2.5mu\crcr}}}}
@@ -424,12 +424,12 @@
{\cdotp\cdotp\cdotp}
\def\PLAINvdots
- {\vbox{\baselineskip4\p@ \lineskiplimit\z@
- \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
+ {\vbox{\baselineskip.4\bodyfontsize\lineskiplimit\zeropoint
+ \kern.6\bodyfontsize\hbox{.}\hbox{.}\hbox{.}}}
\def\PLAINddots
- {\mkern1mu\raise7\p@\vbox{\kern7\p@\hbox{.}}\mkern2mu
- \raise4\p@\hbox{.}\mkern2mu\raise\p@\hbox{.}\mkern1mu}
+ {\mkern1mu\raise.7\bodyfontsize\vbox{\kern.7\bodyfontsize\hbox{.}}\mkern2mu
+ \raise.4\bodyfontsize\hbox{.}\mkern2mu\raise.1\bodyfontsize\hbox{.}\mkern1mu}
\startmathcollection[default]
@@ -521,7 +521,7 @@
\def\notsosqrt[#1]{\root#1\of}
-\unexpanded\def\sqrt{\doifnextcharelse[\notsosqrt\normalsqrt}
+\unexpanded\def\sqrt{\doifnextoptionalelse\notsosqrt\normalsqrt}
\def\PLAINbig {\@@dobig{0.85}}
\def\PLAINBig {\@@dobig{1.15}}
@@ -561,12 +561,12 @@
\stopmathcollection
\def\PLAINroot#1#2%
- {\setbox\z@\hbox{$\m@th#1\sqrt{#2}$}\dimen@\ht\z@
- \advance\dimen@-\dp\z@
- \mkern5mu\raise.6\dimen@\copy\rootbox \mkern-10mu\box\z@}
+ {\setbox\zerocount\hbox{$\mathsurround\zeropoint#1\sqrt{#2}$}\dimen@\ht\zerocount
+ \advance\dimen@-\dp\zerocount
+ \mkern5mu\raise.6\dimen@\copy\rootbox \mkern-10mu\box\zerocount}
\def\PLAINmatrix#1%
- {\null\,\vcenter{\normalbaselines\m@th
+ {\null\,\vcenter{\normalbaselines\mathsurround\zeropoint
\ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
\mathstrut\crcr\noalign{\kern-\baselineskip}
#1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}\,}
@@ -651,7 +651,7 @@
%D The next macro vertically centeres its contents.
\def\@center@math#1%
- {\vcenter{\hbox{$\m@th#1$}}}
+ {\vcenter{\hbox{$\mathsurround\zeropoint#1$}}}
\def\@center@colon
{\mathpalette\@center@math{\colon}}
@@ -712,7 +712,6 @@
\mkern7mu\mathchoice{\mkern2mu}{}{}{}%
\let\dointlimits\egroup}
-
\setupmathematics
[integral=nolimits]
diff --git a/tex/context/base/math-tim.tex b/tex/context/base/math-tim.tex
index de6561ba7..3b9aea103 100644
--- a/tex/context/base/math-tim.tex
+++ b/tex/context/base/math-tim.tex
@@ -1,6 +1,6 @@
%D \module
%D [ file=math-tim,
-%D version=2001.04.12,
+%D version=2001.04.12,
%D title=\CONTEXT\ Math Macros,
%D subtitle=Mathtime Specials,
%D author={Hans Hagen \& Taco Hoekwater},
@@ -13,24 +13,24 @@
\endinput % i will clean this up after taco has gone over it
-%D With thanks to Berthold Horn from YandY for providing me
-%D evaluation copies of the MathTimePlus fonts.
+%D With thanks to Berthold Horn from YandY for providing me
+%D evaluation copies of the MathTimePlus fonts.
% version 0 : Michael Spivak
% version 1 : Taco Hoekwater
% version 2 : Hans Hagen
-% version 3 : etc etc etc
+% version 3 : etc etc etc
\unprotect
%D We use the predefined spare families \type {\mcfam} and
-%D \type {\mdfam}.
+%D \type {\mdfam}.
\let\cafam\mcfam \let\hexcafam\hexmcfam
\let\gbfam\mdfam \let\hexgbfam\hexmdfam
\let\gkfam\mdfam \let\hexgkfam\hexmdfam
-% Why is this needed?
+% Why is this needed?
% \font\tenmd =mtgu at 10pt
% \font\sevenmd=mtgu at 7.6pt
@@ -38,7 +38,7 @@
% \font\tenmc =mtms at 10pt
% \font\sevenmc=mtms at 7.6pt
% \font\fivemc =mtms at 6pt
-%
+%
% \textfont \mcfam\tenmc \textfont \mdfam\tenmd
% \scriptfont \mcfam\sevenmc \scriptfont \mdfam\sevenmd
% \scriptscriptfont\mcfam\fivemc \scriptscriptfont\mdfam\fivemd
@@ -52,7 +52,7 @@
% \definealternativestyle[script] [\ca][\ca]
% \definealternativestyle[greek] [\gk][\gk]
-% \definealternativestyle[boldgreek][\gb][\gb]
+% \definealternativestyle[boldgreek][\gb][\gb]
% \definebodyfont
% [5pt,6pt,7pt,8pt,9pt,10pt,11pt,12pt,14.4pt] [rm]
@@ -60,9 +60,9 @@
% gk=mtgu sa 1,
% gb=mtgub sa 1]
-%D Since a font size is a rather fuzzy thing, it will be no
-%D surprise that the Math Times fonts have different specs
-%D than the Computer Modern Roman fonts.
+%D Since a font size is a rather fuzzy thing, it will be no
+%D surprise that the Math Times fonts have different specs
+%D than the Computer Modern Roman fonts.
%D
%D \starttabulate[|Bl|c|c|c|c|c|c|c|c|c|c|]
%D \NC Computer Modern\NC
@@ -71,9 +71,9 @@
%D 6.0\NC6.8\NC7.6\NC8.4\NC9.2\NC10.0\NC10.8\NC11.6\NC13.2\NC--\NC\NR
%D \stoptabulate
%D
-%D The following definitions presume the existence of \type
-%D {tio} and \type {tibio} font alternatives. Definitions for
-%D \type {\tf.} etc and \type {\sc} are left as they are.
+%D The following definitions presume the existence of \type
+%D {tio} and \type {tibio} font alternatives. Definitions for
+%D \type {\tf.} etc and \type {\sc} are left as they are.
%D moved code
@@ -100,10 +100,10 @@
\def\tildehex{7E}
\def\ddothex {7F}
-%D The \type {mtex} fonts need a recalculation of \type
+%D The \type {mtex} fonts need a recalculation of \type
%D {\p@renwd}, which in \CONTEXT\ is done automatically.
-%D The following definitions are mostly copied from the file
+%D The following definitions are mostly copied from the file
%D \type {mtmacs.tex}, which banner said:
%D
%D \starttyping
@@ -112,9 +112,9 @@
%D ALL RIGHTS RESERVED
%D \stoptyping
%D
-%D We reformatted the macros and changed a few bits and
-%D pieces. A further cleanup with regards to the scratch
-%D registers will be done later.
+%D We reformatted the macros and changed a few bits and
+%D pieces. A further cleanup with regards to the scratch
+%D registers will be done later.
\mathchardef\Gamma = "0130
\mathchardef\Delta = "0131
@@ -171,7 +171,7 @@
% like \rm (cf. the texbook page 290)
\def\ifdefaultfamelse#1#2%
- {\ifnum\fam=\m@ne\mathaccent#1\else\mathaccent#2\fi}
+ {\ifnum\fam=\minusone\mathaccent#1\else\mathaccent#2\fi}
\let\noaccents@\relax
@@ -190,10 +190,10 @@
\def\mathhexbox@#1#2#3%
{\relax
\ifmmode
- \mathpalette{}{\m@th\rm\mathchar"#1#2#3}%
+ \mathpalette{}{\mathsurround\zeropoint\rm\mathchar"#1#2#3}%
\else
\leavevmode
- \hbox{$\m@th\rm\mathchar"#1#2#3$}%
+ \hbox{$\mathsurround\zeropoint\rm\mathchar"#1#2#3$}%
\fi}
\def\dag {\edef\next@{0\daghex }\expandafter\mathhexbox@\next@}
@@ -204,16 +204,16 @@
\def\vdots%
{\vbox
- {\baselineskip4\p@
- \lineskiplimit\z@
- \kern6\p@\hbox{$\m@th.$}\hbox{$\m@th.$}\hbox{$\m@th.$}}}
+ {\baselineskip4\points
+ \lineskiplimit\zeropoint
+ \kern6\points\hbox{$\mathsurround\zeropoint.$}\hbox{$\mathsurround\zeropoint.$}\hbox{$\mathsurround\zeropoint.$}}}
\def\ddots%
{\mathinner
{\mkern1mu
- \raise7\p@\vbox{\kern 7\p@\hbox{$\m@th.$}}\mkern2mu
- \raise4\p@\hbox{$\m@th.$}\mkern2mu
- \raise \p@\hbox{$\m@th.$}\mkern1mu}}
+ \raise7\points\vbox{\kern 7\points\hbox{$\mathsurround\zeropoint.$}}\mkern2mu
+ \raise4\points\hbox{$\mathsurround\zeropoint.$}\mkern2mu
+ \raise \points\hbox{$\mathsurround\zeropoint.$}\mkern1mu}}
\def\hbar
{{\mathchoice
@@ -224,10 +224,10 @@
\mkern-6.3muh}}
\def\angle%
- {{\vbox{\ialign{$\m@th\scriptstyle##$\crcr
+ {{\vbox{\ialign{$\mathsurround\zeropoint\scriptstyle##$\crcr
\not\mathrel{\mkern14mu}\crcr
\noalign{\nointerlineskip}
- \mkern2.5mu\leaders\hrule height.48\p@\hfill\mkern2.5mu\crcr}}}}
+ \mkern2.5mu\leaders\hrule height.48\points\hfill\mkern2.5mu\crcr}}}}
\newdimen\amstexex
@@ -235,25 +235,25 @@
\def\varinjlim%
{\mathop{\vtop{\ialign{##\crcr
- \hfil\the\textfont\z@ lim\hfil\crcr
+ \hfil\the\textfont\zerocount lim\hfil\crcr
\noalign{\nointerlineskip}\rightarrowfill\crcr
\noalign{\nointerlineskip\kern-\amstexex}\crcr}}}}
\def\varprojlim%
{\mathop{\vtop{\ialign{##\crcr
- \hfil\the\textfont\z@ lim\hfil\crcr
+ \hfil\the\textfont\zerocount lim\hfil\crcr
\noalign{\nointerlineskip}\leftarrowfill\crcr
\noalign{\nointerlineskip\kern-\amstexex}\crcr}}}}
\def\varliminf{\mathop{\underbar {lim}}} % context-ified
\def\varlimsup{\mathop{\overstrike{lim}}} % context-ified
-\def\spdot {^{\hbox{\raise\amstexex\hbox{\the\textfont\z@ .}}}}
-\def\spddot {^{\hbox{\raise\amstexex\hbox{\the\textfont\z@ ..}}}}
-\def\spdddot {^{\hbox{\raise\amstexex\hbox{\the\textfont\z@ ...}}}}
-\def\spddddot{^{\hbox{\raise\amstexex\hbox{\the\textfont\z@....}}}}
+\def\spdot {^{\hbox{\raise\amstexex\hbox{\the\textfont\zerocount .}}}}
+\def\spddot {^{\hbox{\raise\amstexex\hbox{\the\textfont\zerocount ..}}}}
+\def\spdddot {^{\hbox{\raise\amstexex\hbox{\the\textfont\zerocount ...}}}}
+\def\spddddot{^{\hbox{\raise\amstexex\hbox{\the\textfont\zerocount....}}}}
-%D Here some code is merged in order to save strings.
+%D Here some code is merged in order to save strings.
\def\domultidot#1#2%
{\setbox0\hbox{$#1#2$}%
@@ -303,29 +303,29 @@
\fi}
\def\root#1\of#2%
- {\setbox\rootbox=\hbox{$\m@th\scriptscriptstyle{#1}$}%
+ {\setbox\rootbox=\hbox{$\mathsurround\zeropoint\scriptscriptstyle{#1}$}%
\mathpalette\r@@t{#2}}
\def\r@@t#1#2%
- {\setbox\z@=\hbox{$\uproot@\z@\leftroot\z@\m@th#1\sqrt{#2}$}%
- \dimen@\ht\z@\advance\dimen@-\dp\z@
+ {\setbox\zerocount\hbox{$\uproot@\zerocount\leftroot\zerocount\mathsurround\zeropoint#1\sqrt{#2}$}%
+ \dimen@\ht\zerocount\advance\dimen@-\dp\zerocount
\dimen@ii\dimen@
- \ifdim\dimen@>30\p@ \advance\dimen@ii-16\p@ \else
- \ifdim\dimen@>24\p@ \advance\dimen@ii -8\p@ \else
- \ifdim\dimen@>18\p@ \advance\dimen@ii -6\p@ \else
- \ifdim\dimen@>12\p@ \advance\dimen@ii -4\p@ \else
- \ifdim\dimen@>10\p@ \advance\dimen@ii -2\p@ \fi\fi\fi\fi\fi
- \setbox\tw@=\hbox{$\m@th#1\mskip\uproot@ mu$}%
- \advance\dimen@ii by1.667\wd\tw@
+ \ifdim\dimen@>30\points \advance\dimen@ii-16\points \else
+ \ifdim\dimen@>24\points \advance\dimen@ii -8\points \else
+ \ifdim\dimen@>18\points \advance\dimen@ii -6\points \else
+ \ifdim\dimen@>12\points \advance\dimen@ii -4\points \else
+ \ifdim\dimen@>10\points \advance\dimen@ii -2\points \fi\fi\fi\fi\fi
+ \setbox\plustwo=\hbox{$\mathsurround\zeropoint#1\mskip\uproot@ mu$}%
+ \advance\dimen@ii by1.667\wd\plustwo
\mkern-\leftroot@ mu\mkern5mu\raise.6\dimen@ii\copy\rootbox
- \mkern-8mu\mkern\leftroot@ mu\box\z@\leftroot\z@\uproot\z@}
+ \mkern-8mu\mkern\leftroot@ mu\box\zerocount\leftroot\zerocount\uproot\zerocount}
\def\space@.{\futurelet\space@\relax} \space@. % really needed ?
\def\jadjust%
- {\mkern-\tw@ mu}
+ {\mkern-\plustwo mu}
-%D For the moment the following code is left unchanged. It is
+%D For the moment the following code is left unchanged. It is
%D not used anyway.
\newif\ifsubscriptcorrection \subscriptcorrectionfalse
@@ -358,11 +358,11 @@
\else
\def\next@.%
{\ifx\next j%
- \mkern-\tw@ mu\else
+ \mkern-\plustwo mu\else
\ifx\next f%
- \mkern-\tw@ mu\else
+ \mkern-\plustwo mu\else
\ifx\next p%
- \mkern-\@ne mu\fi\fi\fi}%
+ \mkern-\plusone mu\fi\fi\fi}%
\fi
\next@.}
diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua
new file mode 100644
index 000000000..35d18d77a
--- /dev/null
+++ b/tex/context/base/math-vfu.lua
@@ -0,0 +1,1534 @@
+if not modules then modules = { } end modules ['math-vfu'] = {
+ version = 1.001,
+ comment = "companion to math-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- All these math vectors .. thanks to Aditya and Mojca they become
+-- better and better.
+
+local type, next = type, next
+
+local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end)
+local trace_timings = false trackers.register("math.timings", function(v) trace_timings = v end)
+
+fonts.enc.math = fonts.enc.math or { }
+
+local shared = { }
+
+fonts.vf.math = fonts.vf.math or { }
+fonts.vf.math.optional = false
+
+local push, pop, back = { "push" }, { "pop" }, { "slot", 1, 0x2215 }
+
+local function negate(main,unicode,basecode)
+ local characters = main.characters
+ if not characters[unicode] then
+ local basechar = characters[basecode]
+ if basechar then
+ local ht, wd = basechar.height, basechar.width
+ characters[unicode] = {
+ width = wd,
+ height = ht,
+ depth = basechar.depth,
+ italic = basechar.italic,
+ kerns = basechar.kerns,
+ commands = {
+ { "slot", 1, basecode },
+ push,
+ { "down", ht/5},
+ { "right", - wd/2},
+ back,
+ push,
+ }
+ }
+ end
+ end
+end
+
+--~ \Umathchardef\braceld="0 "1 "FF07A
+--~ \Umathchardef\bracerd="0 "1 "FF07B
+--~ \Umathchardef\bracelu="0 "1 "FF07C
+--~ \Umathchardef\braceru="0 "1 "FF07D
+
+local function brace(main,unicode,first,rule,left,right,rule,last)
+ local characters = main.characters
+ if not characters[unicode] then
+ characters[unicode] = {
+ horiz_variants = {
+ { extender = 0, glyph = first },
+ { extender = 1, glyph = rule },
+ { extender = 0, glyph = left },
+ { extender = 0, glyph = right },
+ { extender = 1, glyph = rule },
+ { extender = 0, glyph = last },
+ }
+ }
+ end
+end
+
+local function arrow(main,unicode,arrow,minus,isleft)
+ if isleft then
+ t = {
+ { extender = 0, glyph = arrow },
+ { extender = 1, glyph = minus },
+ }
+ else
+ t = {
+ { extender = 0, glyph = minus },
+ { extender = 1, glyph = arrow },
+ }
+ end
+--~ main.characters[unicode] = { horiz_variants = t }
+ main.characters[unicode].horiz_variants = t
+end
+
+local function parent(main,unicode,first,rule,last)
+ local characters = main.characters
+ if not characters[unicode] then
+ characters[unicode] = {
+ horiz_variants = {
+ { extender = 0, glyph = first },
+ { extender = 1, glyph = rule },
+ { extender = 0, glyph = last },
+ }
+ }
+ end
+end
+
+local push, pop, step = { "push" }, { "pop" }, 0.2 -- 0.1 is nicer but gives larger files
+
+local function make(main,id,size,n,m)
+ local characters = main.characters
+ local xu = main.parameters.x_height + 0.3*size
+ local xd = 0.3*size
+ local old, upslot, dnslot, uprule, dnrule = 0xFF000+n, 0xFF100+n, 0xFF200+n, 0xFF300+m, 0xFF400+m
+ local c = characters[old]
+ if c then
+ local w, h, d = c.width, c.height, c.depth
+ local thickness = h - d
+ local rulewidth = step*size -- we could use an overlap
+ local slot = { "slot", id, old }
+ local rule = { "rule", thickness, rulewidth }
+ local up = { "down", -xu }
+ local dn = { "down", xd }
+ local ht, dp = xu + 3*thickness, 0
+ if not characters[uprule] then
+ characters[uprule] = { width = rulewidth, height = ht, depth = dp, commands = { push, up, rule, pop } }
+ end
+ characters[upslot] = { width = w, height = ht, depth = dp, commands = { push, up, slot, pop } }
+ local ht, dp = 0, xd + 3*thickness
+ if not characters[dnrule] then
+ characters[dnrule] = { width = rulewidth, height = ht, depth = dp, commands = { push, dn, rule, pop } }
+ end
+ characters[dnslot] = { width = w, height = ht, depth = dp, commands = { push, dn, slot, pop } }
+ end
+end
+
+local function minus(main,id,size,unicode)
+ local characters = main.characters
+ local mu = size/18
+ local minus = characters[0x002D]
+ local width = minus.width - 5*mu
+ characters[unicode] = {
+ width = width, height = minus.height, depth = minus.depth,
+ commands = { push, { "right", -3*mu }, { "slot", id, 0x002D }, pop }
+ }
+end
+
+local function dots(main,id,size,unicode)
+ local characters = main.characters
+ local c = characters[0x002E]
+ local w, h, d = c.width, c.height, c.depth
+ local mu = size/18
+ local right3mu = { "right", 3*mu }
+ local right1mu = { "right", 1*mu }
+ local up1size = { "down", -.1*size }
+ local up4size = { "down", -.4*size }
+ local up7size = { "down", -.7*size }
+ local right2muw = { "right", 2*mu + w }
+ local slot = { "slot", id, 0x002E }
+ if unicode == 0x22EF then
+ local c = characters[0x022C5]
+ if c then
+ local w, h, d = c.width, c.height, c.depth
+ local slot = { "slot", id, 0x022C5 }
+ characters[unicode] = {
+ width = 3*w + 2*3*mu, height = h, depth = d,
+ commands = { push, slot, right3mu, slot, right3mu, slot, pop }
+ }
+ end
+ elseif unicode == 0x22EE then
+ -- weird height !
+ characters[unicode] = {
+ width = w, height = h+(1.4)*size, depth = 0,
+ commands = { push, push, slot, pop, up4size, push, slot, pop, up4size, slot, pop }
+ }
+ elseif unicode == 0x22F1 then
+ characters[unicode] = {
+ width = 3*w + 6*size/18, height = 1.5*size, depth = 0,
+ commands = {
+ push,
+ right1mu,
+ push, up7size, slot, pop,
+ right2muw,
+ push, up4size, slot, pop,
+ right2muw,
+ push, up1size, slot, pop,
+ right1mu,
+ pop
+ }
+ }
+ elseif unicode == 0x22F0 then
+ characters[unicode] = {
+ width = 3*w + 6*size/18, height = 1.5*size, depth = 0,
+ commands = {
+ push,
+ right1mu,
+ push, up1size, slot, pop,
+ right2muw,
+ push, up4size, slot, pop,
+ right2muw,
+ push, up7size, slot, pop,
+ right1mu,
+ pop
+ }
+ }
+ else
+ characters[unicode] = {
+ width = 3*w + 2*3*mu, height = h, depth = d,
+ commands = { push, slot, right3mu, slot, right3mu, slot, pop }
+ }
+ end
+end
+
+function fonts.vf.math.alas(main,id,size)
+ for i=0x7A,0x7D do
+ make(main,id,size,i,1)
+ end
+ brace (main,0x23DE,0xFF17A,0xFF301,0xFF17D,0xFF17C,0xFF301,0xFF17B)
+ brace (main,0x23DF,0xFF27C,0xFF401,0xFF27B,0xFF27A,0xFF401,0xFF27D)
+ parent(main,0x23DC,0xFF17A,0xFF301,0xFF17B)
+ parent(main,0x23DD,0xFF27C,0xFF401,0xFF27D)
+ negate(main,0x2260,0x003D)
+ dots(main,id,size,0x2026) -- ldots
+ dots(main,id,size,0x22EE) -- vdots
+ dots(main,id,size,0x22EF) -- cdots
+ dots(main,id,size,0x22F1) -- ddots
+ dots(main,id,size,0x22F0) -- udots
+ minus(main,id,size,0xFF501)
+ arrow(main,0x2190,0xFE190,0xFF501,true) -- left
+ arrow(main,0x2192,0xFE192,0xFF501,false) -- right
+end
+
+local reverse -- index -> unicode
+
+function fonts.basecopy(tfmtable)
+ local t, c, p = { }, { }, { }
+ for k, v in next, tfmtable do
+ t[k] = v
+ end
+ for k, v in next, tfmtable.characters do
+ c[k] = v
+ end
+ for k, v in next, tfmtable.parameters do
+ p[k] = v
+ end
+ t.characters, t.parameters = c, p
+ return t
+end
+
+function fonts.vf.math.define(specification,set)
+ if not reverse then
+ reverse = { }
+ for k, v in next, fonts.enc.math do
+ local r = { }
+ for u, i in next, v do
+ r[i] = u
+ end
+ reverse[k] = r
+ end
+ end
+ local name = specification.name -- symbolic name
+ local size = specification.size -- given size
+ local fnt, lst, main = { }, { }, nil
+ local start = (trace_virtual or trace_timings) and os.clock()
+--~ texio.write_nl("defining font " .. name .. " " .. size)
+ local okset, n = { }, 0
+ for s=1,#set do
+ local ss = set[s]
+ local ssname = ss.name
+ if ss.optional and fonts.vf.math.optional then
+ if trace_virtual then
+ logs.report("math virtual","loading font %s subfont %s with name %s at %s is skipped",name,s,ssname,size)
+ end
+ else
+ if ss.features then ssname = ssname .. "*" .. ss.features end
+ if ss.main then main = s end
+ local f, id = fonts.tfm.read_and_define(ssname,size)
+ if not f then
+ logs.report("math virtual","loading font %s subfont %s with name %s at %s is skipped, not found",name,s,ssname,size)
+ else
+ n = n + 1
+ okset[n] = ss
+ fnt[n] = f
+ lst[n] = { id = id, size = size }
+ if not shared[s] then shared[n] = { } end
+ if trace_virtual then
+ logs.report("math virtual","loading font %s subfont %s with name %s at %s as id %s using encoding %s",name,s,ssname,size,id,ss.vector or "none")
+ end
+ end
+ end
+ end
+ -- beware, fnt[1] is already passed to tex (we need to make a simple copy then .. todo)
+ main = fonts.basecopy(fnt[1])
+ main.name, main.fonts, main.virtualized, main.math_parameters = name, lst, true, { }
+ local characters, descriptions = main.characters, main.descriptions
+ main.parameters.x_height = main.parameters.x_height or 0
+ for s=1,n do
+ local ss, fs = okset[s], fnt[s]
+ if not fs then
+ -- skip, error
+ elseif ss.optional and fonts.vf.math.optional then
+ -- skip, redundant
+ else
+ local mm, fp = main.math_parameters, fs.parameters
+ if ss.extension then
+ mm.math_x_height = fp.x_height or 0 -- math_x_height height of x
+ mm.default_rule_thickness = fp[ 8] or 0 -- default_rule_thickness thickness of \over bars
+ mm.big_op_spacing1 = fp[ 9] or 0 -- big_op_spacing1 minimum clearance above a displayed op
+ mm.big_op_spacing2 = fp[10] or 0 -- big_op_spacing2 minimum clearance below a displayed op
+ mm.big_op_spacing3 = fp[11] or 0 -- big_op_spacing3 minimum baselineskip above displayed op
+ mm.big_op_spacing4 = fp[12] or 0 -- big_op_spacing4 minimum baselineskip below displayed op
+ mm.big_op_spacing5 = fp[13] or 0 -- big_op_spacing5 padding above and below displayed limits
+ -- logs.report("math virtual","loading and virtualizing font %s at size %s, setting ex parameters",name,size)
+ elseif ss.parameters then
+ main.parameters.x_height = fp.x_height or main.parameters.x_height
+ mm.x_height = mm.x_height or fp.x_height or 0 -- x_height height of x
+ mm.num1 = fp[ 8] or 0 -- num1 numerator shift-up in display styles
+ mm.num2 = fp[ 9] or 0 -- num2 numerator shift-up in non-display, non-\atop
+ mm.num3 = fp[10] or 0 -- num3 numerator shift-up in non-display \atop
+ mm.denom1 = fp[11] or 0 -- denom1 denominator shift-down in display styles
+ mm.denom2 = fp[12] or 0 -- denom2 denominator shift-down in non-display styles
+ mm.sup1 = fp[13] or 0 -- sup1 superscript shift-up in uncramped display style
+ mm.sup2 = fp[14] or 0 -- sup2 superscript shift-up in uncramped non-display
+ mm.sup3 = fp[15] or 0 -- sup3 superscript shift-up in cramped styles
+ mm.sub1 = fp[16] or 0 -- sub1 subscript shift-down if superscript is absent
+ mm.sub2 = fp[17] or 0 -- sub2 subscript shift-down if superscript is present
+ mm.sup_drop = fp[18] or 0 -- sup_drop superscript baseline below top of large box
+ mm.sub_drop = fp[19] or 0 -- sub_drop subscript baseline below bottom of large box
+ mm.delim1 = fp[20] or 0 -- delim1 size of \atopwithdelims delimiters in display styles
+ mm.delim2 = fp[21] or 0 -- delim2 size of \atopwithdelims delimiters in non-displays
+ mm.axis_height = fp[22] or 0 -- axis_height height of fraction lines above the baseline
+ -- logs.report("math virtual","loading and virtualizing font %s at size %s, setting sy parameters",name,size)
+ end
+ local vectorname = ss.vector
+ if vectorname then
+ local offset = 0xFF000
+ local vector = fonts.enc.math[vectorname]
+ local rotcev = reverse[vectorname]
+ if vector then
+ local fc, fd, si = fs.characters, fs.descriptions, shared[s]
+ local skewchar = ss.skewchar
+ for unicode, index in next, vector do
+ local fci = fc[index]
+ if not fci then
+ -- if trace_virtual then
+ logs.report("math virtual", "unicode point U+%04X has no index %04X in %s",unicode,index,vectorname)
+ -- end
+ else
+ local ref = si[index]
+ if not ref then
+ ref = { { 'slot', s, index } }
+ si[index] = ref
+ end
+ local kerns = fci.kerns
+ if kerns then
+ local width = fci.width
+ local krn = { }
+ for k=1,#kerns do
+ local rk = rotcev[k]
+ if rk then
+ krn[rk] = kerns[k]
+ end
+ end
+ if not next(krn) then
+ krn = nil
+ end
+ local t = {
+ width = width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ kerns = krn,
+ commands = ref,
+ }
+ if skewchar and kerns then
+ local k = kerns[skewchar]
+ if k then
+ t.top_accent = width/2 + k
+ end
+ end
+ characters[unicode] = t
+ else
+ characters[unicode] = {
+ width = fci.width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ commands = ref,
+ }
+ end
+ end
+ end
+ if ss.extension then
+ -- todo: if multiple ex, then 256 offsets per instance
+ local extension = fonts.enc.math["large-to-small"]
+ local variants_done = fs.variants_done
+ for index, fci in next, fc do -- the raw ex file
+ if type(index) == "number" then
+ local ref = si[index]
+ if not ref then
+ ref = { { 'slot', s, index } }
+ si[index] = ref
+ end
+ local t = {
+ width = fci.width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ commands = ref,
+ }
+ local n = fci.next
+ if n then
+ t.next = offset + n
+ elseif variants_done then
+ local vv = fci.vert_variants
+ if vv then
+ t.vert_variants = vv
+ end
+ local hv = fci.horiz_variants
+ if hv then
+ t.horiz_variants = hv
+ end
+ else
+ local vv = fci.vert_variants
+ if vv then
+ for i=1,#vv do
+ local vvi = vv[i]
+ vvi.glyph = vvi.glyph + offset
+ end
+ t.vert_variants = vv
+ end
+ local hv = fci.horiz_variants
+ if hv then
+ for i=1,#hv do
+ local hvi = hv[i]
+ hvi.glyph = hvi.glyph + offset
+ end
+ t.horiz_variants = hv
+ end
+ end
+ characters[offset + index] = t
+ end
+ end
+ fs.variants_done = true
+ for unicode, index in next, extension do
+ local cu = characters[unicode]
+ if cu then
+ cu.next = offset + index
+ --~ local n, c, d = unicode, cu, { }
+ --~ print("START", unicode)
+ --~ while n do
+ --~ n = c.next
+ --~ if n then
+ --~ print("NEXT", n)
+ --~ c = characters[n]
+ --~ if not c then
+ --~ print("EXIT")
+ --~ elseif d[n] then
+ --~ print("LOOP")
+ --~ break
+ --~ end
+ --~ d[n] = true
+ --~ end
+ --~ end
+ else
+ local fci = fc[index]
+ local ref = si[index]
+ if not ref then
+ ref = { { 'slot', s, index } }
+ si[index] = ref
+ end
+ local kerns = fci.kerns
+ if kerns then
+ local krn = { }
+ for k=1,#kerns do
+ krn[offset + k] = kerns[k]
+ end
+ characters[unicode] = {
+ width = fci.width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ commands = ref,
+ kerns = krn,
+ next = offset + index,
+ }
+ else
+ characters[unicode] = {
+ width = fci.width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ commands = ref,
+ next = offset + index,
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ mathematics.extras.copy(main) --not needed here (yet)
+ end
+ end
+ lst[#lst+1] = { id = font.nextid(), size = size }
+ fonts.vf.math.alas(main,#lst,size)
+ if trace_virtual or trace_timings then
+ logs.report("math virtual","loading and virtualizing font %s at size %s took %0.3f seconds",name,size,os.clock()-start)
+ end
+ main.has_italic = true
+ main.type = "virtual" -- not needed
+ mathematics.scaleparameters(main,main,1)
+ return main
+end
+
+function mathematics.make_font(name, set)
+ fonts.define.methods[name] = function(specification)
+ return fonts.vf.math.define(specification,set)
+ end
+end
+
+-- varphi is part of the alphabet, contrary to the other var*s'
+
+fonts.enc.math["large-to-small"] = {
+ [0x00028] = 0x00, -- (
+ [0x00029] = 0x01, -- )
+ [0x0005B] = 0x02, -- [
+ [0x0005D] = 0x03, -- ]
+ [0x0230A] = 0x04, -- lfloor
+ [0x0230B] = 0x05, -- rfloor
+ [0x02308] = 0x06, -- lceil
+ [0x02309] = 0x07, -- rceil
+ [0x0007B] = 0x08, -- {
+ [0x0007D] = 0x09, -- }
+ [0x027E8] = 0x0A, -- <
+ [0x027E9] = 0x0B, -- >
+ [0x0007C] = 0x0C, -- |
+--~ [0x0] = 0x0D, -- lVert rVert Vert
+-- [0x0002F] = 0x0E, -- /
+ [0x0005C] = 0x0F, -- \
+--~ [0x0] = 0x3A, -- lgroup
+--~ [0x0] = 0x3B, -- rgroup
+--~ [0x0] = 0x3C, -- arrowvert
+--~ [0x0] = 0x3D, -- Arrowvert
+ [0x02195] = 0x3F, -- updownarrow
+--~ [0x0] = 0x40, -- lmoustache
+--~ [0x0] = 0x41, -- rmoustache
+ [0x0221A] = 0x70, -- sqrt
+ [0x021D5] = 0x77, -- Updownarrow
+ [0x02191] = 0x78, -- uparrow
+ [0x02193] = 0x79, -- downarrow
+ [0x021D1] = 0x7E, -- Uparrow
+ [0x021D3] = 0x7F, -- Downarrow
+ [0x0220F] = 0x59, -- prod
+ [0x02210] = 0x61, -- coprod
+ [0x02211] = 0x58, -- sum
+ [0x0222B] = 0x5A, -- intop
+ [0x0222E] = 0x49, -- ointop
+ [0xFE302] = 0x62, -- widehat
+ [0xFE303] = 0x65, -- widetilde
+ [0x022C0] = 0x5E, -- bigwedge
+ [0x022C1] = 0x5F, -- bigvee
+ [0x022C2] = 0x5C, -- bigcap
+ [0x022C3] = 0x5B, -- bigcup
+ [0x02044] = 0x0E, -- /
+}
+
+fonts.enc.math["tex-ex"] = {
+ [0x0220F] = 0x51, -- prod
+ [0x0222B] = 0x52, -- intop
+ [0x02210] = 0x60, -- coprod
+ [0x02211] = 0x50, -- sum
+ [0x022C0] = 0x56, -- bigwedge
+ [0x022C1] = 0x57, -- bigvee
+ [0x022C2] = 0x54, -- bigcap
+ [0x022C3] = 0x53, -- bigcup
+ [0x02A04] = 0x55, -- biguplus
+ [0x02A02] = 0x4E, -- bigotimes
+ [0x02A01] = 0x4C, -- bigoplus
+ [0x02A03] = 0x4A, -- bigodot
+ [0x0222E] = 0x48, -- ointop
+ [0x02A06] = 0x46, -- bigsqcup
+}
+
+-- only math stuff is needed, since we always use an lm or gyre
+-- font as main font
+
+fonts.enc.math["tex-mr"] = {
+ [0x00393] = 0x00, -- Gamma
+ [0x00394] = 0x01, -- Delta
+ [0x00398] = 0x02, -- Theta
+ [0x0039B] = 0x03, -- Lambda
+ [0x0039E] = 0x04, -- Xi
+ [0x003A0] = 0x05, -- Pi
+ [0x003A3] = 0x06, -- Sigma
+ [0x003A5] = 0x07, -- Upsilon
+ [0x003A6] = 0x08, -- Phi
+ [0x003A8] = 0x09, -- Psi
+ [0x003A9] = 0x0A, -- Omega
+-- [0x00060] = 0x12, -- [math]grave
+-- [0x000B4] = 0x13, -- [math]acute
+-- [0x002C7] = 0x14, -- [math]check
+-- [0x002D8] = 0x15, -- [math]breve
+-- [0x000AF] = 0x16, -- [math]bar
+-- [0x00021] = 0x21, -- !
+-- [0x00028] = 0x28, -- (
+-- [0x00029] = 0x29, -- )
+-- [0x0002B] = 0x2B, -- +
+-- [0x0002F] = 0x2F, -- /
+-- [0x0003A] = 0x3A, -- :
+-- [0x02236] = 0x3A, -- colon
+-- [0x0003B] = 0x3B, -- ;
+-- [0x0003C] = 0x3C, -- <
+-- [0x0003D] = 0x3D, -- =
+-- [0x0003E] = 0x3E, -- >
+-- [0x0003F] = 0x3F, -- ?
+ [0x00391] = 0x41, -- Alpha
+ [0x00392] = 0x42, -- Beta
+ [0x02145] = 0x44,
+ [0x00395] = 0x45, -- Epsilon
+ [0x00397] = 0x48, -- Eta
+ [0x00399] = 0x49, -- Iota
+ [0x0039A] = 0x4B, -- Kappa
+ [0x0039C] = 0x4D, -- Mu
+ [0x0039D] = 0x4E, -- Nu
+ [0x0039F] = 0x4F, -- Omicron
+ [0x003A1] = 0x52, -- Rho
+ [0x003A4] = 0x54, -- Tau
+ [0x003A7] = 0x58, -- Chi
+ [0x00396] = 0x5A, -- Zeta
+-- [0x0005B] = 0x5B, -- [
+-- [0x0005D] = 0x5D, -- ]
+-- [0x0005E] = 0x5E, -- [math]hat -- the text one
+ [0x00302] = 0x5E, -- [math]hat -- the real math one
+-- [0x002D9] = 0x5F, -- [math]dot
+ [0x02146] = 0x64,
+ [0x02147] = 0x65,
+-- [0x002DC] = 0x7E, -- [math]tilde -- the text one
+ [0x00303] = 0x7E, -- [math]tilde -- the real one
+-- [0x000A8] = 0x7F, -- [math]ddot
+}
+
+fonts.enc.math["tex-mi"] = {
+ [0x1D6E4] = 0x00, -- Gamma
+ [0x1D6E5] = 0x01, -- Delta
+ [0x1D6E9] = 0x02, -- Theta
+ [0x1D6F3] = 0x02, -- varTheta (not present in TeX)
+ [0x1D6EC] = 0x03, -- Lambda
+ [0x1D6EF] = 0x04, -- Xi
+ [0x1D6F1] = 0x05, -- Pi
+ [0x1D6F4] = 0x06, -- Sigma
+ [0x1D6F6] = 0x07, -- Upsilon
+ [0x1D6F7] = 0x08, -- Phi
+ [0x1D6F9] = 0x09, -- Psi
+ [0x1D6FA] = 0x0A, -- Omega
+ [0x1D6FC] = 0x0B, -- alpha
+ [0x1D6FD] = 0x0C, -- beta
+ [0x1D6FE] = 0x0D, -- gamma
+ [0x1D6FF] = 0x0E, -- delta
+ [0x1D716] = 0x0F, -- epsilon TODO: 1D716
+ [0x1D701] = 0x10, -- zeta
+ [0x1D702] = 0x11, -- eta
+ [0x1D703] = 0x12, -- theta TODO: 1D703
+ [0x1D704] = 0x13, -- iota
+ [0x1D705] = 0x14, -- kappa
+ [0x1D718] = 0x14, -- varkappa, not in tex fonts
+ [0x1D706] = 0x15, -- lambda
+ [0x1D707] = 0x16, -- mu
+ [0x1D708] = 0x17, -- nu
+ [0x1D709] = 0x18, -- xi
+ [0x1D70B] = 0x19, -- pi
+ [0x1D70C] = 0x1A, -- rho
+ [0x1D70E] = 0x1B, -- sigma
+ [0x1D70F] = 0x1C, -- tau
+ [0x1D710] = 0x1D, -- upsilon
+ [0x1D719] = 0x1E, -- phi
+ [0x1D712] = 0x1F, -- chi
+ [0x1D713] = 0x20, -- psi
+ [0x1D714] = 0x21, -- omega
+ [0x1D700] = 0x22, -- varepsilon (the other way around)
+ [0x1D717] = 0x23, -- vartheta
+ [0x1D71B] = 0x24, -- varpi
+ [0x1D71A] = 0x25, -- varrho
+ [0x1D70D] = 0x26, -- varsigma
+ [0x1D711] = 0x27, -- varphi (the other way around)
+ [0x021BC] = 0x28, -- leftharpoonup
+ [0x021BD] = 0x29, -- leftharpoondown
+ [0x021C0] = 0x2A, -- righttharpoonup
+ [0x021C1] = 0x2B, -- rightharpoondown
+ -- 0x2C, -- lhook (hook for combining arrows)
+ -- 0x2D, -- rhook (hook for combining arrows)
+ [0x022B3] = 0x2E, -- triangleright (TODO: which one is right?)
+ [0x022B2] = 0x2F, -- triangleleft (TODO: which one is right?)
+-- [0x00041] = 0x30, -- 0
+-- [0x00041] = 0x31, -- 1
+-- [0x00041] = 0x32, -- 2
+-- [0x00041] = 0x33, -- 3
+-- [0x00041] = 0x34, -- 4
+-- [0x00041] = 0x35, -- 5
+-- [0x00041] = 0x36, -- 6
+-- [0x00041] = 0x37, -- 7
+-- [0x00041] = 0x38, -- 8
+-- [0x00041] = 0x39, -- 9
+--~ [0x0002E] = 0x3A, -- .
+ [0x0002C] = 0x3B, -- ,
+ [0x0003C] = 0x3C, -- <
+-- [0x0002F] = 0x3D, -- /, slash, solidus
+ [0x02044] = 0x3D, -- / AM: Not sure
+ [0x0003E] = 0x3E, -- >
+ [0x022C6] = 0x3F, -- star
+ [0x02202] = 0x40, -- partial
+-- [0x00041] = 0x41, -- A
+ [0x1D6E2] = 0x41, -- Alpha
+-- [0x00042] = 0x42, -- B
+ [0x1D6E3] = 0x42, -- Beta
+-- [0x00043] = 0x43, -- C
+-- [0x00044] = 0x44, -- D
+-- [0x00045] = 0x45, -- E
+ [0x1D6E6] = 0x45, -- Epsilon
+-- [0x00046] = 0x46, -- F
+-- [0x00047] = 0x47, -- G
+-- [0x00048] = 0x48, -- H
+ [0x1D6E8] = 0x48, -- Eta
+-- [0x00049] = 0x49, -- I
+ [0x1D6EA] = 0x49, -- Iota
+-- [0x0004A] = 0x4A, -- J
+-- [0x0004B] = 0x4B, -- K
+ [0x1D6EB] = 0x4B, -- Kappa
+-- [0x0004C] = 0x4C, -- L
+-- [0x0004D] = 0x4D, -- M
+ [0x1D6ED] = 0x4D, -- Mu
+-- [0x0004E] = 0x4E, -- N
+ [0x1D6EE] = 0x4E, -- Nu
+-- [0x0004F] = 0x4F, -- O
+ [0x1D6F0] = 0x4F, -- Omicron
+-- [0x00050] = 0x50, -- P
+ [0x1D6F2] = 0x50, -- Rho
+-- [0x00051] = 0x51, -- Q
+-- [0x00052] = 0x52, -- R
+-- [0x00053] = 0x53, -- S
+-- [0x00054] = 0x54, -- T
+ [0x1D6F5] = 0x54, -- Tau
+-- [0x00055] = 0x55, -- U
+-- [0x00056] = 0x56, -- V
+-- [0x00057] = 0x57, -- W
+-- [0x00058] = 0x58, -- X
+ [0x1D6F8] = 0x58, -- Chi
+-- [0x00059] = 0x59, -- Y
+-- [0x0005A] = 0x5A, -- Z
+ [0x1D6E7] = 0x5A, -- Zeta
+ [0x0266D] = 0x5B, -- flat
+ [0x0266E] = 0x5C, -- natural
+ [0x0266F] = 0x5D, -- sharp
+ [0x02323] = 0x5E, -- smile
+ [0x02322] = 0x5F, -- frown
+ [0x02113] = 0x60, -- ell
+-- [0x00061] = 0x61, -- a
+-- [0x00062] = 0x62, -- b
+-- [0x00063] = 0x63, -- c
+-- [0x00064] = 0x64, -- d
+-- [0x00065] = 0x65, -- e
+-- [0x00066] = 0x66, -- f
+-- [0x00067] = 0x67, -- g
+-- [0x00068] = 0x68, -- h
+ [0x0210E] = 0x68, -- plant constant
+-- [0x00069] = 0x69, -- i
+-- [0x0006A] = 0x6A, -- j
+-- [0x0006B] = 0x6B, -- k
+-- [0x0006C] = 0x6C, -- l
+-- [0x0006D] = 0x6D, -- m
+-- [0x0006E] = 0x6E, -- n
+-- [0x0006F] = 0x6F, -- o
+ [0x1D70A] = 0x6F, -- omicron
+-- [0x00070] = 0x70, -- p
+-- [0x00071] = 0x71, -- q
+-- [0x00072] = 0x72, -- r
+-- [0x00073] = 0x73, -- s
+-- [0x00074] = 0x74, -- t
+-- [0x00075] = 0x75, -- u
+-- [0x00076] = 0x76, -- v
+-- [0x00077] = 0x77, -- w
+-- [0x00078] = 0x78, -- x
+-- [0x00079] = 0x79, -- y
+-- [0x0007A] = 0x7A, -- z
+ [0x1D6A4] = 0x7B, -- imath (TODO: also 0131)
+ [0x1D6A5] = 0x7C, -- jmath (TODO: also 0237)
+ [0x02118] = 0x7D, -- wp
+ [0x020D7] = 0x7E, -- vec (TODO: not sure)
+-- 0x7F, -- (no idea what that could be)
+}
+
+fonts.enc.math["tex-ss"] = { }
+fonts.enc.math["tex-tt"] = { }
+fonts.enc.math["tex-bf"] = { }
+fonts.enc.math["tex-bi"] = { }
+fonts.enc.math["tex-fraktur"] = { }
+fonts.enc.math["tex-fraktur-bold"] = { }
+
+function fonts.vf.math.set_letters(font_encoding, name, uppercase, lowercase)
+ local enc = font_encoding[name]
+ for i = 0,25 do
+ enc[uppercase+i] = i + 0x41
+ enc[lowercase+i] = i + 0x61
+ end
+end
+
+function fonts.vf.math.set_digits(font_encoding, name, digits)
+ local enc = font_encoding[name]
+ for i = 0,9 do
+ enc[digits+i] = i + 0x30
+ end
+end
+
+fonts.enc.math["tex-sy"] = {
+ [0x0002D] = 0x00, -- -
+ [0x02212] = 0x00, -- -
+-- [0x02201] = 0x00, -- complement
+-- [0x02206] = 0x00, -- increment
+-- [0x02204] = 0x00, -- not exists
+--~ [0x000B7] = 0x01, -- cdot
+ [0x022C5] = 0x01, -- cdot
+ [0x000D7] = 0x02, -- times
+ [0x0002A] = 0x03, -- *
+ [0x02217] = 0x03, -- *
+ [0x000F7] = 0x04, -- div
+ [0x022C4] = 0x05, -- diamond
+ [0x000B1] = 0x06, -- pm
+ [0x02213] = 0x07, -- mp
+ [0x02295] = 0x08, -- oplus
+ [0x02296] = 0x09, -- ominus
+ [0x02297] = 0x0A, -- otimes
+ [0x02298] = 0x0B, -- oslash
+ [0x02299] = 0x0C, -- odot
+ [0x025EF] = 0x0D, -- bigcirc, Orb (either 25EF or 25CB) -- todo
+ [0x02218] = 0x0E, -- circ
+ [0x02219] = 0x0F, -- bullet
+ [0x02022] = 0x0F, -- bullet
+ [0x0224D] = 0x10, -- asymp
+ [0x02261] = 0x11, -- equiv
+ [0x02286] = 0x12, -- subseteq
+ [0x02287] = 0x13, -- supseteq
+ [0x02264] = 0x14, -- leq
+ [0x02265] = 0x15, -- geq
+ [0x02AAF] = 0x16, -- preceq
+-- [0x0227C] = 0x16, -- preceq, AM:No see 2AAF
+ [0x02AB0] = 0x17, -- succeq
+-- [0x0227D] = 0x17, -- succeq, AM:No see 2AB0
+ [0x0223C] = 0x18, -- sim
+ [0x02248] = 0x19, -- approx
+ [0x02282] = 0x1A, -- subset
+ [0x02283] = 0x1B, -- supset
+ [0x0226A] = 0x1C, -- ll
+ [0x0226B] = 0x1D, -- gg
+ [0x0227A] = 0x1E, -- prec
+ [0x0227B] = 0x1F, -- succ
+ [0x02190] = 0x20, -- leftarrow
+ [0x02192] = 0x21, -- rightarrow
+--~ [0xFE190] = 0x20, -- leftarrow
+--~ [0xFE192] = 0x21, -- rightarrow
+ [0x02191] = 0x22, -- uparrow
+ [0x02193] = 0x23, -- downarrow
+ [0x02194] = 0x24, -- leftrightarrow
+ [0x02197] = 0x25, -- nearrow
+ [0x02198] = 0x26, -- searrow
+ [0x02243] = 0x27, -- simeq
+ [0x021D0] = 0x28, -- Leftarrow
+ [0x021D2] = 0x29, -- Rightarrow
+ [0x021D1] = 0x2A, -- Uparrow
+ [0x021D3] = 0x2B, -- Downarrow
+ [0x021D4] = 0x2C, -- Leftrightarrow
+ [0x02196] = 0x2D, -- nwarrow
+ [0x02199] = 0x2E, -- swarrow
+ [0x0221D] = 0x2F, -- propto
+ [0x02032] = 0x30, -- prime
+ [0x0221E] = 0x31, -- infty
+ [0x02208] = 0x32, -- in
+ [0x0220B] = 0x33, -- ni
+ [0x025B3] = 0x34, -- triangle, bigtriangleup
+ [0x025BD] = 0x35, -- bigtriangledown
+ [0x00338] = 0x36, -- not
+-- 0x37, -- (beginning of arrow)
+ [0x02200] = 0x38, -- forall
+ [0x02203] = 0x39, -- exists
+ [0x000AC] = 0x3A, -- neg, lnot
+ [0x02205] = 0x3B, -- empty set
+ [0x0211C] = 0x3C, -- Re
+ [0x02111] = 0x3D, -- Im
+ [0x022A4] = 0x3E, -- top
+ [0x022A5] = 0x3F, -- bot, perp
+ [0x02135] = 0x40, -- aleph
+ [0x1D49C] = 0x41, -- script A
+ [0x0212C] = 0x42, -- script B
+ [0x1D49E] = 0x43, -- script C
+ [0x1D49F] = 0x44, -- script D
+ [0x02130] = 0x45, -- script E
+ [0x02131] = 0x46, -- script F
+ [0x1D4A2] = 0x47, -- script G
+ [0x0210B] = 0x48, -- script H
+ [0x02110] = 0x49, -- script I
+ [0x1D4A5] = 0x4A, -- script J
+ [0x1D4A6] = 0x4B, -- script K
+ [0x02112] = 0x4C, -- script L
+ [0x02133] = 0x4D, -- script M
+ [0x1D4A9] = 0x4E, -- script N
+ [0x1D4AA] = 0x4F, -- script O
+ [0x1D4AB] = 0x50, -- script P
+ [0x1D4AC] = 0x51, -- script Q
+ [0x0211B] = 0x52, -- script R
+ [0x1D4AE] = 0x53, -- script S
+ [0x1D4AF] = 0x54, -- script T
+ [0x1D4B0] = 0x55, -- script U
+ [0x1D4B1] = 0x56, -- script V
+ [0x1D4B2] = 0x57, -- script W
+ [0x1D4B3] = 0x58, -- script X
+ [0x1D4B4] = 0x59, -- script Y
+ [0x1D4B5] = 0x5A, -- script Z
+ [0x0222A] = 0x5B, -- cup
+ [0x02229] = 0x5C, -- cap
+ [0x0228E] = 0x5D, -- uplus
+ [0x02227] = 0x5E, -- wedge, land
+ [0x02228] = 0x5F, -- vee, lor
+ [0x022A2] = 0x60, -- vdash
+ [0x022A3] = 0x61, -- dashv
+ [0x0230A] = 0x62, -- lfloor
+ [0x0230B] = 0x63, -- rfloor
+ [0x02308] = 0x64, -- lceil
+ [0x02309] = 0x65, -- rceil
+ [0x0007B] = 0x66, -- {, lbrace
+ [0x0007D] = 0x67, -- }, rbrace
+ [0x027E8] = 0x68, -- <, langle
+ [0x027E9] = 0x69, -- >, rangle
+ [0x0007C] = 0x6A, -- |, mid, lvert, rvert
+ [0x02225] = 0x6B, -- parallel, Vert, lVert, rVert, arrowvert
+ [0x02195] = 0x6C, -- updownarrow
+ [0x021D5] = 0x6D, -- Updownarrow
+ [0x0005C] = 0x6E, -- \, backslash, setminus
+ [0x02216] = 0x6E, -- setminus
+ [0x02240] = 0x6F, -- wr
+ [0x0221A] = 0x70, -- sqrt. AM: Check surd??
+ [0x02A3F] = 0x71, -- amalg
+ [0x1D6FB] = 0x72, -- nabla
+-- [0x0222B] = 0x73, -- smallint (TODO: what about intop?)
+ [0x02294] = 0x74, -- sqcup
+ [0x02293] = 0x75, -- sqcap
+ [0x02291] = 0x76, -- sqsubseteq
+ [0x02292] = 0x77, -- sqsupseteq
+ [0x000A7] = 0x78, -- S
+ [0x02020] = 0x79, -- dagger, dag
+ [0x02021] = 0x7A, -- ddagger, ddag
+ [0x000B6] = 0x7B, -- P
+ [0x02663] = 0x7C, -- clubsuit
+ [0x02662] = 0x7D, -- diamondsuit
+ [0x02661] = 0x7E, -- heartsuit
+ [0x02660] = 0x7F, -- spadesuit
+ [0xFE321] = 0x37, -- mapstochar
+}
+
+-- The names in masm10.enc can be trusted best and are shown in the first
+-- column, while in the second column we show the tex/ams names. As usual
+-- it costs hours to figure out such a table.
+
+fonts.enc.math["tex-ma"] = {
+ [0x022A1] = 0x00, -- squaredot \boxdot
+ [0x0229E] = 0x01, -- squareplus \boxplus
+ [0x022A0] = 0x02, -- squaremultiply \boxtimes
+ [0x025A1] = 0x03, -- square \square \Box
+ [0x025A0] = 0x04, -- squaresolid \blacksquare
+ [0x000B7] = 0x05, -- squaresmallsolid \centerdot
+ [0x022C4] = 0x06, -- diamond \Diamond \lozenge
+ [0x029EB] = 0x07, -- diamondsolid \blacklozenge
+ [0x021BA] = 0x08, -- clockwise \circlearrowright
+ [0x021BB] = 0x09, -- anticlockwise \circlearrowleft
+ [0x021CC] = 0x0A, -- harpoonleftright \rightleftharpoons
+ [0x021CB] = 0x0B, -- harpoonrightleft \leftrightharpoons
+ [0x0229F] = 0x0C, -- squareminus \boxminus
+ [0x022A9] = 0x0D, -- forces \Vdash
+ [0x022AA] = 0x0E, -- forcesbar \Vvdash
+ [0x022A8] = 0x0F, -- satisfies \vDash
+ [0x021A0] = 0x10, -- dblarrowheadright \twoheadrightarrow
+ [0x0219E] = 0x11, -- dblarrowheadleft \twoheadleftarrow
+ [0x021C7] = 0x12, -- dblarrowleft \leftleftarrows
+ [0x021C9] = 0x13, -- dblarrowright \rightrightarrows
+ [0x021C8] = 0x14, -- dblarrowup \upuparrows
+ [0x021CA] = 0x15, -- dblarrowdwn \downdownarrows
+ [0x021BE] = 0x16, -- harpoonupright \upharpoonright \restriction
+ [0x021C2] = 0x17, -- harpoondownright \downharpoonright
+ [0x021BF] = 0x18, -- harpoonupleft \upharpoonleft
+ [0x021C3] = 0x19, -- harpoondownleft \downharpoonleft
+ [0x021A3] = 0x1A, -- arrowtailright \rightarrowtail
+ [0x021A2] = 0x1B, -- arrowtailleft \leftarrowtail
+ [0x021C6] = 0x1C, -- arrowparrleftright \leftrightarrows
+-- [0x021C5] = 0x00, -- \updownarrows (missing in lm)
+ [0x021C4] = 0x1D, -- arrowparrrightleft \rightleftarrows
+ [0x021B0] = 0x1E, -- shiftleft \Lsh
+ [0x021B1] = 0x1F, -- shiftright \Rsh
+ [0x021DD] = 0x20, -- squiggleright \leadsto \rightsquigarrow
+ [0x021AD] = 0x21, -- squiggleleftright \leftrightsquigarrow
+ [0x021AB] = 0x22, -- curlyleft \looparrowleft
+ [0x021AC] = 0x23, -- curlyright \looparrowright
+ [0x02257] = 0x24, -- circleequal \circeq
+ [0x0227F] = 0x25, -- followsorequal \succsim
+ [0x02273] = 0x26, -- greaterorsimilar \gtrsim
+ [0x02A86] = 0x27, -- greaterorapproxeql \gtrapprox
+ [0x022B8] = 0x28, -- multimap \multimap
+ [0x02234] = 0x29, -- therefore \therefore
+ [0x02235] = 0x2A, -- because \because
+ [0x02251] = 0x2B, -- equalsdots \Doteq \doteqdot
+ [0x0225C] = 0x2C, -- defines \triangleq
+ [0x0227E] = 0x2D, -- precedesorequal \precsim
+ [0x02272] = 0x2E, -- lessorsimilar \lesssim
+ [0x02A85] = 0x2F, -- lessorapproxeql \lessapprox
+ [0x02A95] = 0x30, -- equalorless \eqslantless
+ [0x02A96] = 0x31, -- equalorgreater \eqslantgtr
+ [0x022DE] = 0x32, -- equalorprecedes \curlyeqprec
+ [0x022DF] = 0x33, -- equalorfollows \curlyeqsucc
+ [0x0227C] = 0x34, -- precedesorcurly \preccurlyeq
+ [0x02266] = 0x35, -- lessdblequal \leqq
+ [0x02A7D] = 0x36, -- lessorequalslant \leqslant
+ [0x02276] = 0x37, -- lessorgreater \lessgtr
+ [0x02035] = 0x38, -- primereverse \backprime
+ -- [0x0] = 0x39, -- axisshort \dabar
+ [0x02253] = 0x3A, -- equaldotrightleft \risingdotseq
+ [0x02252] = 0x3B, -- equaldotleftright \fallingdotseq
+ [0x0227D] = 0x3C, -- followsorcurly \succcurlyeq
+ [0x02267] = 0x3D, -- greaterdblequal \geqq
+ [0x02A7E] = 0x3E, -- greaterorequalslant \geqslant
+ [0x02277] = 0x3F, -- greaterorless \gtrless
+ [0x0228F] = 0x40, -- squareimage \sqsubset
+ [0x02290] = 0x41, -- squareoriginal \sqsupset
+ -- wrong:
+ [0x022B3] = 0x42, -- triangleright \rhd \vartriangleright
+ [0x022B2] = 0x43, -- triangleleft \lhd \vartriangleleft
+ [0x022B5] = 0x44, -- trianglerightequal \unrhd \trianglerighteq
+ [0x022B4] = 0x45, -- triangleleftequal \unlhd \trianglelefteq
+ --
+ [0x02605] = 0x46, -- star \bigstar
+ [0x0226C] = 0x47, -- between \between
+ [0x025BC] = 0x48, -- triangledownsld \blacktriangledown
+ [0x025B6] = 0x49, -- trianglerightsld \blacktriangleright
+ [0x025C0] = 0x4A, -- triangleleftsld \blacktriangleleft
+ -- [0x0] = 0x4B, -- arrowaxisright
+ -- [0x0] = 0x4C, -- arrowaxisleft
+ [0x025B2] = 0x4D, -- triangle \triangleup \vartriangle
+ [0x025B2] = 0x4E, -- trianglesolid \blacktriangle
+ [0x025BC] = 0x4F, -- triangleinv \triangledown
+ [0x02256] = 0x50, -- ringinequal \eqcirc
+ [0x022DA] = 0x51, -- lessequalgreater \lesseqgtr
+ [0x022DB] = 0x52, -- greaterlessequal \gtreqless
+ [0x02A8B] = 0x53, -- lessdbleqlgreater \lesseqqgtr
+ [0x02A8C] = 0x54, -- greaterdbleqlless \gtreqqless
+ [0x000A5] = 0x55, -- Yen \yen
+ [0x021DB] = 0x56, -- arrowtripleright \Rrightarrow
+ [0x021DA] = 0x57, -- arrowtripleleft \Lleftarrow
+ [0x02713] = 0x58, -- check \checkmark
+ [0x022BB] = 0x59, -- orunderscore \veebar
+ [0x022BC] = 0x5A, -- nand \barwedge
+ [0x02306] = 0x5B, -- perpcorrespond \doublebarwedge
+ [0x02220] = 0x5C, -- angle \angle
+ [0x02221] = 0x5D, -- measuredangle \measuredangle
+ [0x02222] = 0x5E, -- sphericalangle \sphericalangle
+ -- [0x0] = 0x5F, -- proportional \varpropto
+ -- [0x0] = 0x60, -- smile \smallsmile
+ -- [0x0] = 0x61, -- frown \smallfrown
+ [0x022D0] = 0x62, -- subsetdbl \Subset
+ [0x022D1] = 0x63, -- supersetdbl \Supset
+ [0x022D3] = 0x64, -- uniondbl \doublecup \Cup
+ [0x00100] = 0x65, -- intersectiondbl \doublecap \Cap
+ [0x022CF] = 0x66, -- uprise \curlywedge
+ [0x022CE] = 0x67, -- downfall \curlyvee
+ [0x022CB] = 0x68, -- multiopenleft \leftthreetimes
+ [0x022CC] = 0x69, -- multiopenright \rightthreetimes
+ [0x02AC5] = 0x6A, -- subsetdblequal \subseteqq
+ [0x02AC6] = 0x6B, -- supersetdblequal \supseteqq
+ [0x0224F] = 0x6C, -- difference \bumpeq
+ [0x0224E] = 0x6D, -- geomequivalent \Bumpeq
+ [0x022D8] = 0x6E, -- muchless \lll \llless
+ [0x022D9] = 0x6F, -- muchgreater \ggg \gggtr
+ [0x0231C] = 0x70, -- rightanglenw \ulcorner
+ [0x0231D] = 0x71, -- rightanglene \urcorner
+ [0x024C7] = 0x72, -- circleR \circledR
+ [0x024C8] = 0x73, -- circleS \circledS
+ [0x022D4] = 0x74, -- fork \pitchfork
+ [0x02245] = 0x75, -- dotplus \dotplus
+ [0x0223D] = 0x76, -- revsimilar \backsim
+ [0x022CD] = 0x77, -- revasymptequal \backsimeq -- AM: Check this! I mapped it to simeq.
+ [0x0231E] = 0x78, -- rightanglesw \llcorner
+ [0x0231F] = 0x79, -- rightanglese \lrcorner
+ [0x02720] = 0x7A, -- maltesecross \maltese
+ [0x02201] = 0x7B, -- complement \complement
+ [0x022BA] = 0x7C, -- intercal \intercal
+ [0x0229A] = 0x7D, -- circlering \circledcirc
+ [0x0229B] = 0x7E, -- circleasterisk \circledast
+ [0x0229D] = 0x7F, -- circleminus \circleddash
+}
+
+fonts.enc.math["tex-mb"] = {
+ -- [0x0] = 0x00, -- lessornotequal \lvertneqq
+ -- [0x0] = 0x01, -- greaterornotequal \gvertneqq
+ [0x02270] = 0x02, -- notlessequal \nleq
+ [0x02271] = 0x03, -- notgreaterequal \ngeq
+ [0x0226E] = 0x04, -- notless \nless
+ [0x0226F] = 0x05, -- notgreater \ngtr
+ [0x02280] = 0x06, -- notprecedes \nprec
+ [0x02281] = 0x07, -- notfollows \nsucc
+ [0x02268] = 0x08, -- lessornotdbleql \lneqq
+ [0x02269] = 0x09, -- greaterornotdbleql \gneqq
+ -- [0x0] = 0x0A, -- notlessorslnteql \nleqslant
+ -- [0x0] = 0x0B, -- notgreaterorslnteql \ngeqslant
+ [0x02A87] = 0x0C, -- lessnotequal \lneq
+ [0x02A88] = 0x0D, -- greaternotequal \gneq
+ -- [0x0] = 0x0E, -- notprecedesoreql \npreceq
+ -- [0x0] = 0x0F, -- notfollowsoreql \nsucceq
+ [0x022E8] = 0x10, -- precedeornoteqvlnt \precnsim
+ [0x022E9] = 0x11, -- followornoteqvlnt \succnsim
+ [0x022E6] = 0x12, -- lessornotsimilar \lnsim
+ [0x022E7] = 0x13, -- greaterornotsimilar \gnsim
+ -- [0x0] = 0x14, -- notlessdblequal \nleqq
+ -- [0x0] = 0x15, -- notgreaterdblequal \ngeqq
+ [0x02AB5] = 0x16, -- precedenotslnteql \precneqq
+ [0x02AB6] = 0x17, -- follownotslnteql \succneqq
+ [0x02AB9] = 0x18, -- precedenotdbleqv \precnapprox
+ [0x02ABA] = 0x19, -- follownotdbleqv \succnapprox
+ [0x02A89] = 0x1A, -- lessnotdblequal \lnapprox
+ [0x02A8A] = 0x1B, -- greaternotdblequal \gnapprox
+ [0x02241] = 0x1C, -- notsimilar \nsim
+ [0x02247] = 0x1D, -- notapproxequal \ncong
+ -- [0x0] = 0x1E, -- upslope \diagup
+ -- [0x0] = 0x1F, -- downslope \diagdown
+ -- [0x0] = 0x20, -- notsubsetoreql \varsubsetneq
+ -- [0x0] = 0x21, -- notsupersetoreql \varsupsetneq
+ -- [0x0] = 0x22, -- notsubsetordbleql \nsubseteqq
+ -- [0x0] = 0x23, -- notsupersetordbleql \nsupseteqq
+ [0x02ACB] = 0x24, -- subsetornotdbleql \subsetneqq
+ [0x02ACC] = 0x25, -- supersetornotdbleql \supsetneqq
+ -- [0x0] = 0x26, -- subsetornoteql \varsubsetneqq
+ -- [0x0] = 0x27, -- supersetornoteql \varsupsetneqq
+ [0x0228A] = 0x28, -- subsetnoteql \subsetneq
+ [0x0228B] = 0x29, -- supersetnoteql \supsetneq
+ [0x02288] = 0x2A, -- notsubseteql \nsubseteq
+ [0x02289] = 0x2B, -- notsuperseteql \nsupseteq
+ [0x02226] = 0x2C, -- notparallel \nparallel
+ [0x02224] = 0x2D, -- notbar \nmid \ndivides
+ -- [0x0] = 0x2E, -- notshortbar \nshortmid
+ -- [0x0] = 0x2F, -- notshortparallel \nshortparallel
+ [0x022AC] = 0x30, -- notturnstile \nvdash
+ [0x022AE] = 0x31, -- notforces \nVdash
+ [0x022AD] = 0x32, -- notsatisfies \nvDash
+ [0x022AF] = 0x33, -- notforcesextra \nVDash
+ [0x022ED] = 0x34, -- nottriangeqlright \ntrianglerighteq
+ [0x022EC] = 0x35, -- nottriangeqlleft \ntrianglelefteq
+ [0x022EA] = 0x36, -- nottriangleleft \ntriangleleft
+ [0x022EB] = 0x37, -- nottriangleright \ntriangleright
+ [0x0219A] = 0x38, -- notarrowleft \nleftarrow
+ [0x0219B] = 0x39, -- notarrowright \nrightarrow
+ [0x021CD] = 0x3A, -- notdblarrowleft \nLeftarrow
+ [0x021CF] = 0x3B, -- notdblarrowright \nRightarrow
+ [0x021CE] = 0x3C, -- notdblarrowboth \nLeftrightarrow
+ [0x021AE] = 0x3D, -- notarrowboth \nleftrightarrow
+ [0x022C7] = 0x3E, -- dividemultiply \divideontimes
+ [0x02300] = 0x3F, -- diametersign \varnothing
+ [0x02204] = 0x40, -- notexistential \nexists
+ [0x1D538] = 0x41, -- A (blackboard A)
+ [0x1D539] = 0x42, -- B
+ [0x02102] = 0x43, -- C
+ [0x1D53B] = 0x44, -- D
+ [0x1D53C] = 0x45, -- E
+ [0x1D53D] = 0x46, -- F
+ [0x1D53E] = 0x47, -- G
+ [0x0210D] = 0x48, -- H
+ [0x1D540] = 0x49, -- I
+ [0x1D541] = 0x4A, -- J
+ [0x1D542] = 0x4B, -- K
+ [0x1D543] = 0x4C, -- L
+ [0x1D544] = 0x4D, -- M
+ [0x02115] = 0x4E, -- N
+ [0x1D546] = 0x4F, -- O
+ [0x02119] = 0x50, -- P
+ [0x0211A] = 0x51, -- Q
+ [0x0211D] = 0x52, -- R
+ [0x1D54A] = 0x53, -- S
+ [0x1D54B] = 0x54, -- T
+ [0x1D54C] = 0x55, -- U
+ [0x1D54D] = 0x56, -- V
+ [0x1D54E] = 0x57, -- W
+ [0x1D54F] = 0x58, -- X
+ [0x1D550] = 0x59, -- Y
+ [0x02124] = 0x5A, -- Z (blackboard Z)
+ [0x02132] = 0x60, -- hatwide \Finv
+ [0x02141] = 0x61, -- hatwider \Game
+ -- [0x0] = 0x62, tildewide
+ -- [0x0] = 0x63, tildewider
+ -- [0x0] = 0x64, Finv
+ -- [0x0] = 0x65, Gmir
+ [0x02127] = 0x66, -- Omegainv \mho
+ [0x000F0] = 0x67, -- eth \eth
+ [0x02242] = 0x68, -- equalorsimilar \eqsim
+ [0x02136] = 0x69, -- beth \beth
+ [0x02137] = 0x6A, -- gimel \gimel
+ [0x02138] = 0x6B, -- daleth \daleth
+ [0x022D6] = 0x6C, -- lessdot \lessdot
+ [0x022D7] = 0x6D, -- greaterdot \gtrdot
+ [0x022C9] = 0x6E, -- multicloseleft \ltimes
+ [0x022CA] = 0x6F, -- multicloseright \rtimes
+ -- [0x0] = 0x70, -- barshort \shortmid
+ -- [0x0] = 0x71, -- parallelshort \shortparallel
+ -- [0x02216] = 0x72, -- integerdivide \smallsetminus (2216 already part of tex-sy
+ -- [0x0] = 0x73, -- similar \thicksim
+ -- [0x0] = 0x74, -- approxequal \thickapprox
+ [0x0224A] = 0x75, -- approxorequal \approxeq
+ [0x02AB8] = 0x76, -- followsorequal \succapprox
+ [0x02AB7] = 0x77, -- precedesorequal \precapprox
+ [0x021B6] = 0x78, -- archleftdown \curvearrowleft
+ [0x021B7] = 0x79, -- archrightdown \curvearrowright
+ [0x003DC] = 0x7A, -- Digamma \digamma
+ [0x003F0] = 0x7B, -- kappa \varkappa
+ [0x1D55C] = 0x7C, -- k \Bbbk (blackboard k)
+ [0x0210F] = 0x7D, -- planckover2pi \hslash
+ [0x00127] = 0x7E, -- planckover2pi1 \hbar
+ [0x003F6] = 0x7F, -- epsiloninv \backepsilon
+}
+
+fonts.enc.math["tex-fraktur"] = {
+-- [0x1D504] = 0x41, -- A (fraktur A)
+-- [0x1D505] = 0x42, -- B
+ [0x0212D] = 0x43, -- C
+-- [0x1D507] = 0x44, -- D
+-- [0x1D508] = 0x45, -- E
+-- [0x1D509] = 0x46, -- F
+-- [0x1D50A] = 0x47, -- G
+ [0x0210C] = 0x48, -- H
+ [0x02111] = 0x49, -- I
+-- [0x1D50D] = 0x4A, -- J
+-- [0x1D50E] = 0x4B, -- K
+-- [0x1D50F] = 0x4C, -- L
+-- [0x1D510] = 0x4D, -- M
+-- [0x1D511] = 0x4E, -- N
+-- [0x1D512] = 0x4F, -- O
+-- [0x1D513] = 0x50, -- P
+-- [0x1D514] = 0x51, -- Q
+ [0x0211C] = 0x52, -- R
+-- [0x1D516] = 0x53, -- S
+-- [0x1D517] = 0x54, -- T
+-- [0x1D518] = 0x55, -- U
+-- [0x1D519] = 0x56, -- V
+-- [0x1D51A] = 0x57, -- W
+-- [0x1D51B] = 0x58, -- X
+-- [0x1D51C] = 0x59, -- Y
+ [0x02128] = 0x5A, -- Z (fraktur Z)
+-- [0x1D51E] = 0x61, -- a (fraktur a)
+-- [0x1D51F] = 0x62, -- b
+-- [0x1D520] = 0x63, -- c
+-- [0x1D521] = 0x64, -- d
+-- [0x1D522] = 0x65, -- e
+-- [0x1D523] = 0x66, -- f
+-- [0x1D524] = 0x67, -- g
+-- [0x1D525] = 0x68, -- h
+-- [0x1D526] = 0x69, -- i
+-- [0x1D527] = 0x6A, -- j
+-- [0x1D528] = 0x6B, -- k
+-- [0x1D529] = 0x6C, -- l
+-- [0x1D52A] = 0x6D, -- m
+-- [0x1D52B] = 0x6E, -- n
+-- [0x1D52C] = 0x6F, -- o
+-- [0x1D52D] = 0x70, -- p
+-- [0x1D52E] = 0x71, -- q
+-- [0x1D52F] = 0x72, -- r
+-- [0x1D530] = 0x73, -- s
+-- [0x1D531] = 0x74, -- t
+-- [0x1D532] = 0x75, -- u
+-- [0x1D533] = 0x76, -- v
+-- [0x1D534] = 0x77, -- w
+-- [0x1D535] = 0x78, -- x
+-- [0x1D536] = 0x79, -- y
+-- [0x1D537] = 0x7A, -- z
+}
+
+-- now that all other vectors are defined ...
+
+fonts.vf.math.set_letters(fonts.enc.math, "tex-mi", 0x1D434, 0x1D44E)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-ss", 0x1D5A0, 0x1D5BA)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-tt", 0x1D670, 0x1D68A)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-bf", 0x1D400, 0x1D41A)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-bi", 0x1D468, 0x1D482)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-fraktur", 0x1D504, 0x1D51E)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-fraktur-bold", 0x1D56C, 0x1D586)
+
+fonts.vf.math.set_digits (fonts.enc.math, "tex-ss", 0x1D7E2)
+fonts.vf.math.set_digits (fonts.enc.math, "tex-tt", 0x1D7F6)
+fonts.vf.math.set_digits (fonts.enc.math, "tex-bf", 0x1D7CE)
+
+-- fonts.vf.math.set_digits (fonts.enc.math, "tex-bi", 0x1D7CE)
+
+-- todo: add ss, tt, bf etc vectors
+-- we can make ss tt etc an option
+
+-- rm-lmr5 : LMMathRoman5-Regular
+-- rm-lmbx5 : LMMathRoman5-Bold ]
+-- lmbsy5 : LMMathSymbols5-BoldItalic
+-- lmsy5 : LMMathSymbols5-Italic
+-- lmmi5 : LMMathItalic5-Italic
+-- lmmib5 : LMMathItalic5-BoldItalic
+
+mathematics.make_font ( "lmroman5-math", {
+ { name = "lmroman5-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr5.tfm", vector = "tex-mr" } ,
+ { name = "lmmi5.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy5.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam5.tfm", vector = "tex-ma" },
+ { name = "msbm5.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx5.tfm", vector = "tex-bf" } ,
+ { name = "lmroman5-bold", "tex-bf" } ,
+ { name = "lmmib5.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans8-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono8-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm5.tfm", vector = "tex-fraktur", optional=true },
+} )
+
+-- rm-lmr6 : LMMathRoman6-Regular
+-- rm-lmbx6 : LMMathRoman6-Bold
+-- lmsy6 : LMMathSymbols6-Italic
+-- lmmi6 : LMMathItalic6-Italic
+
+mathematics.make_font ( "lmroman6-math", {
+ { name = "lmroman6-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr6.tfm", vector = "tex-mr" } ,
+ { name = "lmmi6.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy6.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam5.tfm", vector = "tex-ma" },
+ { name = "msbm5.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx6.tfm", vector = "tex-bf" } ,
+ { name = "lmroman6-bold.otf", "tex-bf" } ,
+ { name = "lmmib5.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans8-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono8-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm6.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb6.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- rm-lmr7 : LMMathRoman7-Regular
+-- rm-lmbx7 : LMMathRoman7-Bold
+-- lmbsy7 : LMMathSymbols7-BoldItalic
+-- lmsy7 : LMMathSymbols7-Italic
+-- lmmi7 : LMMathItalic7-Italic
+-- lmmib7 : LMMathItalic7-BoldItalic
+
+mathematics.make_font ( "lmroman7-math", {
+ { name = "lmroman7-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr7.tfm", vector = "tex-mr" } ,
+ { name = "lmmi7.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy7.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam7.tfm", vector = "tex-ma" },
+ { name = "msbm7.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx7.tfm", vector = "tex-bf" } ,
+ { name = "lmroman7-bold.otf", "tex-bf" } ,
+ { name = "lmmib7.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans8-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono8-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm7.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb7.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- rm-lmr8 : LMMathRoman8-Regular
+-- rm-lmbx8 : LMMathRoman8-Bold
+-- lmsy8 : LMMathSymbols8-Italic
+-- lmmi8 : LMMathItalic8-Italic
+
+mathematics.make_font ( "lmroman8-math", {
+ { name = "lmroman8-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr8.tfm", vector = "tex-mr" } ,
+ { name = "lmmi8.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy8.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam7.tfm", vector = "tex-ma" },
+ { name = "msbm7.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx8.tfm", vector = "tex-bf" } ,
+ { name = "lmroman8-bold.otf", "tex-bf" } ,
+ { name = "lmmib7.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans8-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono8-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm8.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb8.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- rm-lmr9 : LMMathRoman9-Regular
+-- rm-lmbx9 : LMMathRoman9-Bold
+-- lmsy9 : LMMathSymbols9-Italic
+-- lmmi9 : LMMathItalic9-Italic
+
+mathematics.make_font ( "lmroman9-math", {
+ { name = "lmroman9-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr9.tfm", vector = "tex-mr" } ,
+ { name = "lmmi9.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy9.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx9.tfm", vector = "tex-bf" } ,
+ { name = "lmroman9-bold.otf", "tex-bf" } ,
+ { name = "lmmib10.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans9-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono9-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm9.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb9.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- rm-lmr10 : LMMathRoman10-Regular
+-- rm-lmbx10 : LMMathRoman10-Bold
+-- lmbsy10 : LMMathSymbols10-BoldItalic
+-- lmsy10 : LMMathSymbols10-Italic
+-- lmex10 : LMMathExtension10-Regular
+-- lmmi10 : LMMathItalic10-Italic
+-- lmmib10 : LMMathItalic10-BoldItalic
+
+mathematics.make_font ( "lmroman10-math", {
+ { name = "lmroman10-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr10.tfm", vector = "tex-mr" } ,
+ { name = "lmmi10.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx10.tfm", vector = "tex-bf" } ,
+ { name = "lmroman10-bold.otf", "tex-bf" } ,
+ { name = "lmmib10.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans10-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono10-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm10.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb10.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- rm-lmr12 : LMMathRoman12-Regular
+-- rm-lmbx12 : LMMathRoman12-Bold
+-- lmmi12 : LMMathItalic12-Italic
+
+mathematics.make_font ( "lmroman12-math", {
+ { name = "lmroman12-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr12.tfm", vector = "tex-mr" } ,
+ { name = "lmmi12.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx12.tfm", vector = "tex-bf" } ,
+ { name = "lmroman12-bold.otf", "tex-bf" } ,
+ { name = "lmmib10.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans12-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono12-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm10.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb10.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- rm-lmr17 : LMMathRoman17-Regular
+
+mathematics.make_font ( "lmroman17-math", {
+ { name = "lmroman17-regular.otf", features = "virtualmath", main = true },
+ -- { name = "rm-lmr12.tfm", vector = "tex-mr" } ,
+ { name = "lmmi12.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+ -- { name = "rm-lmbx12.tfm", vector = "tex-bf" } ,
+ { name = "lmroman12-bold.otf", "tex-bf" } ,
+ { name = "lmmib10.tfm", vector = "tex-bi", skewchar=0x7F } ,
+ { name = "lmsans17-regular.otf", vector = "tex-ss", optional=true },
+ { name = "lmmono17-regular.otf", vector = "tex-tt", optional=true },
+ { name = "eufm10.tfm", vector = "tex-fraktur", optional=true },
+ { name = "eufb10.tfm", vector = "tex-fraktur-bold", optional=true },
+} )
+
+-- pxr/txr messes up the accents
+
+mathematics.make_font ( "px-math", {
+ { name = "texgyrepagella-regular.otf", features = "virtualmath", main = true },
+ { name = "pxr.tfm", vector = "tex-mr" } ,
+ { name = "pxmi.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "pxsy.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "pxex.tfm", vector = "tex-ex", extension = true } ,
+ { name = "pxsya.tfm", vector = "tex-ma" },
+ { name = "pxsyb.tfm", vector = "tex-mb" },
+} )
+
+mathematics.make_font ( "tx-math", {
+ { name = "texgyretermes-regular.otf", features = "virtualmath", main = true },
+ { name = "txr.tfm", vector = "tex-mr" } ,
+ { name = "txmi.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "txsy.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "txex.tfm", vector = "tex-ex", extension = true } ,
+ { name = "txsya.tfm", vector = "tex-ma" },
+ { name = "txsyb.tfm", vector = "tex-mb" },
+} )
+
+mathematics.make_font ( "iwona-math", {
+ { name = "file:Iwona-Regular", features = "virtualmath", main = true },
+ { name = "mi-iwonari.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "sy-iwonarz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "ex-iwonar.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+} )
+
+mathematics.make_font ( "iwona-light-math", {
+ { name = "file:IwonaLight-Regular", features = "virtualmath", main = true },
+ { name = "mi-iwonali.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "sy-iwonalz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "ex-iwonal.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+} )
+
+mathematics.make_font ( "iwona-medium-math", {
+ { name = "file:IwonaMedium-Regular", features = "virtualmath", main = true },
+ { name = "mi-iwonami.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "sy-iwonamz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "ex-iwonam.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+} )
+
+mathematics.make_font ( "iwona-heavy-math", {
+ { name = "file:IwonaHeavy-Regular", features = "virtualmath", main = true },
+ { name = "mi-iwonahi.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "sy-iwonahz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
+ { name = "ex-iwonah.tfm", vector = "tex-ex", extension = true } ,
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+} )
+
+-- not ok, we need adapted vectors !
+
+mathematics.make_font ( "mathtimes-math", {
+ { name = "file:texgyretermes-regular.otf", features = "virtualmath", main = true },
+ { name = "mtmiz.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mtsyn.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
+ { name = "mtex.tfm", vector = "tex-ex", extension = true },
+ { name = "msam10.tfm", vector = "tex-ma" },
+ { name = "msbm10.tfm", vector = "tex-mb" },
+} )
diff --git a/tex/context/base/meta-ini.mkii b/tex/context/base/meta-ini.mkii
index cb59ed44b..ee7e8a38b 100644
--- a/tex/context/base/meta-ini.mkii
+++ b/tex/context/base/meta-ini.mkii
@@ -20,45 +20,21 @@
\unprotect
-\startmessages dutch library: metapost
- title: metapost
- 1: metapost bibliotheek -- wordt geladen
-\stopmessages
-
-\startmessages english library: metapost
- title: metapost
- 1: loading metapost library --
-\stopmessages
-
-\startmessages german library: metapost
- title: metapost
- 1: Lade metapost Bibliothek --
-\stopmessages
-
-\startmessages czech library: metapost
- title: metapost
- 1: loading metapost library --
-\stopmessages
-
-\startmessages italian library: metapost
- title: metapost
- 1: caricamento della libreria metapost --
-\stopmessages
-
-\startmessages norwegian library: metapost
- title: metapost
- 1: metapost bibliotek -- blir lest inn
-\stopmessages
-
-\startmessages romanian library: metapost
- title: metapost
- 1: se incarca biblioteca metapost --
-\stopmessages
-
-\startmessages french library: metapost
- title: metapost
- 1: chargement de la bibliothèque metapost --
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
%D This module extends the functionality of the support module
%D \type {supp-mps}, the module that is responsible for
@@ -69,49 +45,48 @@
\maxnofMPgraphics = 4000 % metafun disables the 4K boundary
-\appendtoks \runMPgraphicsfalse \to \everyfastmode
-\appendtoks \insertMPgraphicsfalse \to \everyfastmode
-\appendtoks \flushMPgraphics \to \everygoodbye % \everylastshipout
+\appendtoks \flushMPgraphics \to \everygoodbye % \everylastshipout
\def\@@MPG{@MPG@}
\startMPextensions
- if unknown context_tool: input mp-tool; fi;
- if unknown context_spec: input mp-spec; fi;
- if unknown context_grph: input mp-grph; fi;
+ if unknown context_tool: input mp-tool; fi;
+ if unknown context_spec: input mp-spec; fi;
+ if unknown context_grph: input mp-grph; fi;
\stopMPextensions
%D Since we want lables to follow the document settings, we
%D also set the font related variables.
-\startMPinitializations % scale is not yet ok
- defaultfont:="\truefontname{Regular}";
- defaultscale:=\the\bodyfontsize/10pt;
-\stopMPinitializations
-
-\beginNEWTEX
+\ifnum\texengine=\xetexengine
\startMPinitializations % scale is not yet ok
- defaultfont:="rm-lmtt10";
+ defaultfont:="rm-lmtt10";
+ defaultscale:=\the\bodyfontsize/10pt;
\stopMPinitializations
-\endNEWTEX
+\else
+ \startMPinitializations % scale is not yet ok
+ defaultfont:="\truefontname{Regular}";
+ defaultscale:=\the\bodyfontsize/10pt;
+ \stopMPinitializations
+\fi
%D In order to support fancy text features (like outline
%D fonts), we set:
\startMPextensions
- graphictextformat:="context";
- graphictextdirective "\the\everyMPTEXgraphic";
+ graphictextformat:="context";
+ graphictextdirective "\the\everyMPTEXgraphic";
\stopMPextensions
% \startMPextensions
-% textextdirective "\the\everyMPTEXgraphic";
+% textextdirective "\the\everyMPTEXgraphic";
% \stopMPextensions
%D A signal that we're in combines \CONTEXT||\METAFUN mode:
\startMPextensions
- string contextversion;
- contextversion:="\contextversion";
+ string contextversion;
+ contextversion:="\contextversion";
\stopMPextensions
%D Some safeguards:
diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv
index 8d2f7a724..bcd82c4ed 100644
--- a/tex/context/base/meta-ini.mkiv
+++ b/tex/context/base/meta-ini.mkiv
@@ -15,46 +15,6 @@
\unprotect
-\startmessages dutch library: metapost
- title: metapost
- 1: metapost bibliotheek -- wordt geladen
-\stopmessages
-
-\startmessages english library: metapost
- title: metapost
- 1: loading metapost library --
-\stopmessages
-
-\startmessages german library: metapost
- title: metapost
- 1: Lade metapost Bibliothek --
-\stopmessages
-
-\startmessages czech library: metapost
- title: metapost
- 1: loading metapost library --
-\stopmessages
-
-\startmessages italian library: metapost
- title: metapost
- 1: caricamento della libreria metapost --
-\stopmessages
-
-\startmessages norwegian library: metapost
- title: metapost
- 1: metapost bibliotek -- blir lest inn
-\stopmessages
-
-\startmessages romanian library: metapost
- title: metapost
- 1: se incarca biblioteca metapost --
-\stopmessages
-
-\startmessages french library: metapost
- title: metapost
- 1: chargement de la bibliothèque metapost --
-\stopmessages
-
%D Instead of sharing code with \MKII, I decided to copy
%D the code. Otherwise maintainance becomes a pain and after all,
%D the \MKII\ code will not change.
@@ -77,6 +37,20 @@
\newtoks \everyMPgraphic % mp
\newtoks \everyMPTEXgraphic % tex
+% The next command is, of course, dedicated to Mojca, who
+% needs it for gnuplot. Anyway, the whole multiple engine
+% mechanism is to keep her gnuplot from interfering.
+
+\def\startMPdefinitions
+ {\dosinglegroupempty\dostartMPdefinitions}
+
+\long\def\dostartMPdefinitions#1#2\stopMPdefinitions
+ {\edef\currentMPgraphicinstance{#1}%
+ \ifx\currentMPgraphicinstance\empty
+ \let\currentMPgraphicinstance\defaultMPgraphicinstance
+ \fi
+ \global\MPinstancetoks\expandafter{\the\MPinstancetoks#2}}
+
\long\def\startMPextensions#1\stopMPextensions
{\global\MPextensions\expandafter{\the\MPextensions#1}}
@@ -110,31 +84,163 @@
\def\currentMPformat{metafun}
+% todo:
+%
+% \splitMPgraphicname[a::b] (\currentMPgraphicformat,\currentMPgraphicname)
+% \splitMPgraphicname[a] (\currentMPgraphicformat,\currentMPgraphicname)
+% \splitMPgraphicname[a::b::c] (\currentMPgraphicformat,\currentMPgraphicname)
+%
+% \resetMPformat[extrafun]
+%
+% MPinclusions etc only for metafun, randomseed for all
+%
+% todo: \resetMPformat[instance] -> unload and nil
+% todo: geen page stats
+% todo: textext in plain mp
+
+% test:
+%
+% \let\processMPgraphic\extendedprocessMPgraphic \setupcolors[state=start]
+%
+% \startMPdefinitions{metafun}
+% color MyColor ; MyColor = red ;
+% \stopMPdefinitions
+% \startuseMPgraphic{test1}
+% fill fullcircle scaled 1cm withcolor MyColor ;
+% \stopuseMPgraphic
+% \startuseMPgraphic{test2}
+% color MyColor ; MyColor = green ;
+% fill fullcircle scaled 1cm withcolor MyColor ;
+% \stopuseMPgraphic
+% \startuseMPgraphic{test3}
+% fill fullcircle scaled 1cm withcolor MyColor ;
+% \stopuseMPgraphic
+% \startuseMPgraphic{test4}
+% color MyColor ; MyColor = blue ;
+% \stopuseMPgraphic
+%
+% \useMPgraphic{metafun::test1}
+% \useMPgraphic{metafun::test2}
+% \useMPgraphic{metafun::test3}
+% \useMPgraphic{extrafun::test4}
+% \useMPgraphic{extrafun::test3}
+% \useMPgraphic{metafun::test3}
+% \useMPgraphic{nofun::test4}
+% \useMPgraphic{nofun::test3}
+%
+% \startMPcode
+% fill fullsquare scaled 1cm ;
+% \stopMPcode
+% \startMPcode{metafun}
+% fill fullsquare scaled 1cm withcolor MyColor ;
+% \stopMPcode
+
+\def\@@MPF{@MPF@}
+
+\def\MPinstancetoks{\csname\@@MPF::\currentMPgraphicinstance\endcsname}
+
+\def\defineMPinstance
+ {\dodoubleargument\dodefineMPinstance}
+
+\def\dodefineMPinstance[#1][#2]%
+ {\ifcsname\@@MPF::#1\endcsname\else\expandafter\newtoks\csname\@@MPF::#1\endcsname\fi
+ \MPinstancetoks\emptytoks % in case we redefine
+ \getparameters[\@@MPF#1][\s!format=mpost,\s!extensions=\v!no,\s!initializations=\v!no,#2]}
+
+\def\resetMPinstance[#1]%
+ {\writestatus\m!metapost{reset will be implemented when needed}}
+
+\def\defaultMPgraphicinstance{metafun}
+
+\def\splitMPgraphicname[#1]%
+ {\dosplitMPgraphicname[#1::::]}
+
+\def\dosplitMPgraphicname[#1::#2::#3]% instance ::
+ {\edef\currentMPgraphicname{#2}%
+ \ifx\currentMPgraphicname\empty
+ \edef\currentMPgraphicname{#1}%
+ \let\currentMPgraphicinstance\defaultMPgraphicinstance
+ \else
+ \edef\currentMPgraphicinstance{#1}%
+ \fi
+ \edef\currentMPgraphicformat{\csname\@@MPF\currentMPgraphicinstance\s!format\endcsname}}
+
+\def\currentMPgraphicinstance{\defaultMPgraphicinstance}
+\def\currentMPgraphicformat {\currentMPgraphicinstance}
+
+\defineMPinstance[metafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes]
+\defineMPinstance[extrafun][\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes]
+\defineMPinstance[metapost][\s!format=mpost]
+\defineMPinstance[nofun] [\s!format=mpost]
+
+\def\beginMPgraphicgroup#1%
+ {\begingroup
+ \splitMPgraphicname[#1]}
+
+\def\endMPgraphicgroup
+ {\endgroup}
+
+%
+
\newconditional \METAFUNinitialized
+% maybe we need to force black, i.e. fake nodes
+
\long\def\processMPgraphic#1% todo: extensions and inclusions outside beginfig
- {\blabelgroup
+ {\begingroup
\enableincludeMPgraphics
\the\everyMPgraphic
\presetMPdefinitions
\setMPrandomseed % this has to change
% we need to preexpand the token lists
\setbox\MPgraphicbox\hbox\bgroup
- \ifconditional\METAFUNinitialized
- \ctxlua { metapost.graphic(
- "\currentMPformat", \@EA\!!bs\the\MPinitializations;#1;\!!es,
- ""
- ) }%
- \else
- \ctxlua { metapost.graphic(
- "\currentMPformat", \@EA\!!bs\the\MPinitializations;\theMPrandomseed;#1;\!!es, % code
- \@EA\@EA\@EA\!!bs\@EA\the\@EA\MPextensions\@EA;\the\MPuserinclusions;\!!es % optional preamble
- ) }%
- \global\settrue\METAFUNinitialized
- \fi
+ \ctxlua{metapost.graphic("\currentMPformat", "\currentMPformat",
+ \@EA\!!bs\the\MPinitializations;\theMPrandomseed;#1;\!!es, % code
+ \@EA\@EA\@EA\!!bs\@EA\the\@EA\MPextensions\@EA;\the\MPuserinclusions;\!!es % optional preamble
+ )}%
+ \global\settrue\METAFUNinitialized
+ \global\MPextensions\emptytoks
+ \global\MPuserinclusions\emptytoks
\egroup
\placeMPgraphic
- \elabelgroup}
+ \endgroup}
+
+% ! ! ! ! begin temporary ! ! ! !
+
+\let\normalprocessMPgraphic\processMPgraphic
+
+\long\def\processMPgraphic#1% todo: extensions and inclusions outside beginfig
+ {\begingroup % needed?
+ \enableincludeMPgraphics
+ \the\everyMPgraphic
+ \presetMPdefinitions
+ \setMPrandomseed % this has to change
+ % we need to preexpand the token lists
+ \doifelsevalue{\@@MPF\currentMPgraphicinstance\s!extensions}\v!yes
+ {\settrue\includeMPextensions\letgvalue{\@@MPF\currentMPgraphicinstance\s!extensions}\v!no}
+ {\setfalse\includeMPextensions}%
+ \doifelsevalue{\@@MPF\currentMPgraphicinstance\s!initializations}\v!yes
+ {\settrue\includeMPinitializations\letgvalue{\@@MPF\currentMPgraphicinstance\s!initializations}\v!no}
+ {\setfalse\includeMPinitializations}%
+ \setbox\MPgraphicbox\hbox\bgroup
+ \normalexpanded{\noexpand\ctxlua{metapost.graphic("\currentMPgraphicinstance", "\currentMPgraphicformat",
+ \!!bs\ifconditional\includeMPinitializations\the\MPinitializations;\fi\theMPrandomseed;#1;\!!es,
+ \!!bs\ifconditional\includeMPextensions\the\MPextensions;\the\MPuserinclusions;\fi\the\MPinstancetoks;\!!es
+ )}}%
+ \egroup
+ \global\MPinstancetoks\emptytoks
+ \global\settrue\METAFUNinitialized % becomes obsolete
+ %\global\MPextensions\emptytoks % multipls instances
+ %\global\MPuserinclusions\emptytoks % multipls instances
+ \placeMPgraphic
+ \endgroup}
+
+\let\extendedprocessMPgraphic\processMPgraphic
+
+\let\processMPgraphic\normalprocessMPgraphic
+% \let\processMPgraphic\extendedprocessMPgraphic
+
+% ! ! ! ! end temporary ! ! ! !
\newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default
@@ -150,10 +256,7 @@
\def\@@MPG{@MPG@}
\def\doifMPgraphicelse#1%
- {\blabelgroup
- \doifdefinedelse{\@@MPG#1}%
- {\elabelgroup\firstoftwoarguments}
- {\elabelgroup\secondoftwoarguments}}
+ {\ifcsname\@@MPG#1\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi}
\def\includeMPgraphic#1%
{\executeifdefined{\@@MPG#1};} % ; if not found
@@ -165,7 +268,6 @@
\let\MPdrawingdata\empty
\newif\ifMPdrawingdone \MPdrawingdonefalse
-\newif\ifMPshiftdrawing \MPshiftdrawingfalse
\def\resetMPdrawing
{\globallet\MPdrawingdata\empty
@@ -178,9 +280,25 @@
\def\popMPdrawing
{\globalpopmacro\MPdrawingdata}
-\def\getMPdrawing
+\def\getMPdrawing{\dosinglegroupempty\dogetMPdrawing}
+
+\def\nodogetMPdrawing#1%
+ {\ifMPdrawingdone
+ \expandafter\processMPgraphic\expandafter{\MPdrawingdata}%
+ \fi}
+
+\def\dostartMPcode
+ {\iffirstargument
+ \expandafter\dodogetMPdrawing
+ \else
+ \expandafter\nodogetMPdrawing
+ \fi}
+
+\def\dodogetMPdrawing#1%
{\ifMPdrawingdone
+ \beginMPgraphicgroup{#1::\s!dummy}% name does not matter
\expandafter\processMPgraphic\expandafter{\MPdrawingdata}%
+ \endMPgraphicgroup
\fi}
\def\startMPdrawing
@@ -199,7 +317,6 @@
\let\MPdrawingdata\empty
-\newif\ifMPdrawingdone \MPdrawingdonefalse
\newif\ifMPshiftdrawing \MPshiftdrawingfalse
\def\resetMPdrawing
@@ -233,24 +350,24 @@
\let\stopMPdrawing\relax
\long\def\startMPclip#1#2\stopMPclip
- {\blabelgroup
- \long\setgvalue{MPC:#1}{\ctxlua{metapost.getclippath(\!!bs#2\!!es)}}%
- \elabelgroup}
+ {\long\setgvalue{MPC:#1}{\ctxlua{metapost.getclippath(\!!bs#2\!!es)}}}
\let\stopMPclip\relax
\def\grabMPclippath#1#2#3#4#5% #5 is alternative
- {\blabelgroup
+ {\begingroup
\edef\width {#3\space}\let\overlaywidth \width
\edef\height{#4\space}\let\overlayheight\height
- \doifdefinedelse{MPC:#1}
- {\xdef\MPclippath{\getvalue{MPC:#1}}%
- \ifx\MPclippath\empty\xdef\MPclippath{#5}\fi
- \setxvalue{MPC:#1}{\MPclippath}}
- {\xdef\MPclippath{#5}}%
+ \ifcsname MPC:#1\endcsname
+ \xdef\MPclippath{\getvalue{MPC:#1}}%
+ \ifx\MPclippath\empty\xdef\MPclippath{#5}\fi
+ \setxvalue{MPC:#1}{\MPclippath}%
+ \else
+ \xdef\MPclippath{#5}%
+ \fi
% #2 : method is obsolete, only pdf now, we can always
% gsub the result to ps
- \elabelgroup}
+ \endgroup}
%D Next we will use these support macros.
@@ -268,6 +385,8 @@
defaultscale:=\the\bodyfontsize/10pt;
\stopMPinitializations
+% watch out, this is a type1 font because mp can only handle 8 bit fonts
+
\startMPinitializations % scale is not yet ok
defaultfont:="rm-lmtt10";
\stopMPinitializations
@@ -386,18 +505,36 @@
%D \stoptyping
\newcount\MPobjectcounter
-\newif \ifMPshiftdrawing \MPshiftdrawingfalse
\newbox \MPgraphicbox
+%newif \ifMPshiftdrawing \MPshiftdrawingfalse
+
+\chardef\MPboxmode\zerocount
+
+\def\doobeyMPboxdepth % mode = 1
+ {\setbox\MPgraphicbox\hbox{\hskip\MPllx\onebasepoint\raise\MPlly\onebasepoint\box\MPgraphicbox}}
+
+\def\doignoreMPboxdepth % mode = 2
+ {\normalexpanded
+ {\noexpand\doobeyMPboxdepth
+ \wd\MPgraphicbox\the\wd\MPgraphicbox
+ \ht\MPgraphicbox\the\ht\MPgraphicbox
+ \dp\MPgraphicbox\the\dp\MPgraphicbox}}
+
+\def\obeyMPboxdepth {\chardef\MPboxmode\plusone}
+\def\ignoreMPboxdepth{\chardef\MPboxmode\plustwo}
+\def\normalMPboxdepth{\chardef\MPboxmode\zerocount}
+
+% compatibility hack:
+
+\let\MPshiftdrawingtrue \ignoreMPboxdepth
+\let\MPshiftdrawingfalse\normalMPboxdepth
\def\placeMPgraphic
- {\ifMPshiftdrawing
- \edef\next
- {\wd\MPgraphicbox\the\wd\MPgraphicbox
- \ht\MPgraphicbox\the\ht\MPgraphicbox
- \dp\MPgraphicbox\the\dp\MPgraphicbox}%
- \setbox\MPgraphicbox\hbox
- {\hskip\MPllx\onebasepoint\raise\MPlly\onebasepoint\box\MPgraphicbox}%
- \next
+ {\ifcase\MPboxmode
+ \or % 1
+ \doobeyMPboxdepth
+ \or % 2
+ \doignoreMPboxdepth
\fi
\box\MPgraphicbox}
@@ -409,10 +546,10 @@
\getobject{MP}{#1}}
\long\def\handleuniqueMPgraphic#1#2#3%
- {\blabelgroup
+ {\begingroup
\def\@@meta{#1:}%
\extendMPoverlaystamp{#2}% incl prepare
- \ifundefined{\@@MPG\overlaystamp:#1}%
+ \ifcsname\@@MPG\overlaystamp:#1\endcsname\else
\enableincludeMPgraphics
\forgetall
\global\advance\MPobjectcounter\plusone
@@ -420,57 +557,51 @@
\setxvalue{\@@MPG\overlaystamp:#1}{\noexpand\reuseMPbox{\number\MPobjectcounter}{\MPllx}{\MPlly}{\MPurx}{\MPury}}%
\fi
\getvalue{\@@MPG\overlaystamp:#1}%
- \elabelgroup}
+ \endgroup}
\long\def\startuniqueMPgraphic
- {\blabelgroup
- \dodoublegroupempty\dostartuniqueMPgraphic}
+ {\dodoublegroupempty\dostartuniqueMPgraphic}
\long\def\dostartuniqueMPgraphic#1#2#3\stopuniqueMPgraphic%
- {\long\setgvalue{\@@MPG#1}{\handleuniqueMPgraphic{#1}{#2}{#3}}%
- \elabelgroup}
+ {\long\setgvalue{\@@MPG#1}{\handleuniqueMPgraphic{#1}{#2}{#3}}}
\unexpanded\def\uniqueMPgraphic
{\dodoublegroupempty\douniqueMPgraphic}
\def\douniqueMPgraphic#1#2%
- {\blabelgroup
- \setupMPvariables[#1][#2]%
- \getvalue{\@@MPG#1}\empty
- \elabelgroup}
+ {\beginMPgraphicgroup{#1}%
+ \setupMPvariables[\currentMPgraphicname][#2]%
+ \getvalue{\@@MPG\currentMPgraphicname}\empty
+ \endMPgraphicgroup}
\let\stopuniqueMPcode \relax % so that we can use it in \expanded
\long\def\handleuseMPgraphic#1#2#3%
- {\blabelgroup
+ {\begingroup
\forgetall % check this
\def\@@meta{#1:}%
\prepareMPvariables{#2}%
\enableincludeMPgraphics
\processMPgraphic{#3}%
- \elabelgroup}
+ \endgroup}
\long\def\startuseMPgraphic
- {\blabelgroup
- \dodoublegroupempty\dostartuseMPgraphic}
+ {\dodoublegroupempty\dostartuseMPgraphic}
\long\def\dostartuseMPgraphic#1#2#3\stopuseMPgraphic
- {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}%
- \elabelgroup}
+ {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}}
\long\def\startusableMPgraphic % redundant but handy
- {\blabelgroup
- \dodoublegroupempty\dostartusableMPgraphic}
+ {\dodoublegroupempty\dostartusableMPgraphic}
\long\def\dostartusableMPgraphic#1#2#3\stopusableMPgraphic
- {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}%
- \elabelgroup}
+ {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}}
\let\stopuseMPgraphic \relax % so that we can use it in \expanded
\let\stopusableMPgraphic \relax % so that we can use it in \expanded
\long\def\handlereusableMPgraphic#1#2#3%
- {\blabelgroup
+ {\begingroup
\def\@@meta{#1:}%
\prepareMPvariables{#2}%
\enableincludeMPgraphics
@@ -478,15 +609,13 @@
\setobject{MP}{\number\MPobjectcounter}\hbox{\processMPgraphic{#3}}% was vbox, graphic must end up as hbox
\setxvalue{\@@MPG#1}{\noexpand\reuseMPbox{\number\MPobjectcounter}{\MPllx}{\MPlly}{\MPurx}{\MPury}}%
\getvalue{\@@MPG#1}%
- \elabelgroup}
+ \endgroup}
\long\def\startreusableMPgraphic
- {\blabelgroup
- \dodoublegroupempty\dostartreusableMPgraphic}
+ {\dodoublegroupempty\dostartreusableMPgraphic}
\long\def\dostartreusableMPgraphic#1#2#3\stopreusableMPgraphic
- {\long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}{#3}}%
- \elabelgroup}
+ {\long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}{#3}}}
\let\stopreusableMPgraphic \relax % so that we can use it in \expanded
@@ -494,10 +623,10 @@
{\dodoublegroupempty\douseMPgraphic}
\def\douseMPgraphic#1#2%
- {\blabelgroup
- \doifsomething{#2}{\setupMPvariables[#1][#2]}%
- \getvalue{\@@MPG#1}\empty
- \elabelgroup}
+ {\beginMPgraphicgroup{#1}%
+ \doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}%
+ \getvalue{\@@MPG\currentMPgraphicname}\empty
+ \endMPgraphicgroup}
\let\reuseMPgraphic \useMPgraphic % we can save a setup here if needed
\let\reusableMPgraphic\reuseMPgraphic % we can save a setup here if needed
@@ -522,23 +651,21 @@
{\MPpageprefix\overlaywidth:\overlayheight:\overlaydepth:\MPcolor\overlaycolor:\MPcolor\overlaylinecolor}
\long\def\startuniqueMPpagegraphic
- {\blabelgroup
- \dodoublegroupempty\dostartuniqueMPpagegraphic}
+ {\dodoublegroupempty\dostartuniqueMPpagegraphic}
\long\def\dostartuniqueMPpagegraphic#1#2#3\stopuniqueMPpagegraphic
{\long\setgvalue{\@@MPG o:#1}{\handleuniqueMPgraphic{o:#1}{#2}{#3}}%
- \long\setgvalue{\@@MPG e:#1}{\handleuniqueMPgraphic{e:#1}{#2}{#3}}%
- \elabelgroup}
+ \long\setgvalue{\@@MPG e:#1}{\handleuniqueMPgraphic{e:#1}{#2}{#3}}}
\unexpanded\def\uniqueMPpagegraphic
{\dodoublegroupempty\douniqueMPpagegraphic}
\def\douniqueMPpagegraphic#1#2%
- {\blabelgroup
+ {\beginMPgraphicgroup{#1}%
\let\overlaystamp\overlaypagestamp
- \setupMPvariables[\MPpageprefix#1][#2]% prefix is new here
- \getvalue{\@@MPG\MPpageprefix#1}{}%
- \elabelgroup}
+ \setupMPvariables[\MPpageprefix\currentMPgraphicname][#2]% prefix is new here
+ \getvalue{\@@MPG\MPpageprefix\currentMPgraphicname}{}%
+ \endMPgraphicgroup}
%D One way of defining a stamp is:
%D
@@ -553,10 +680,10 @@
%D we introduce a dedicated expansion engine.
\def\prepareMPvariable#1%
- {\ifundefined{\@@framed\@@meta#1}%
- \doprepareMPvariable{\@@meta#1}%
- \else
+ {\ifcsname\@@framed\@@meta#1\endcsname
\doprepareMPvariable{\@@framed\@@meta#1}%
+ \else
+ \doprepareMPvariable{\@@meta#1}%
\fi}
% \startlines
@@ -637,15 +764,35 @@
%D For the moment, the next one is a private macro:
-% TODO ! ! ! ! ! !
-
\def\processMPbuffer
{\dosingleempty\doprocessMPbuffer}
+% this fails (keep):
+%
+% \def\doprocessMPbuffer[#1]%
+% {\doifelsenothing{#1}
+% {\doprocessMPbuffer[\jobname]}
+% {\processMPgraphic{\ctxlua{tex.sprint(tex.ctxcatcodes,buffers.collect("#1"))}}}} % "\\n"
+%
+% this works (keep):
+%
+% \def\doprocessMPbuffer[#1]%
+% {\doifelsenothing{#1}
+% {\doprocessMPbuffer[\jobname]} % #1 can be a list of buffers, otherwise we could use:
+% {\processMPgraphic{\ctxlua{tex.sprint(tex.ctxcatcodes,unpack(buffers.data["#1"]))}}}}
+%
+% this we use:
+
+\newtoks\mpbuffertoks
+
\def\doprocessMPbuffer[#1]%
{\doifelsenothing{#1}
{\doprocessMPbuffer[\jobname]}
- {\processMPgraphic{\ctxlua{tex.sprint(tex.ctxcatcodes,buffers.collect(string.split("#1",",")))}}}}
+ {\beginMPgraphicgroup{#1}%
+ % we need this trick because tex.sprint does not interprets newlines
+ \ctxlua{tex.toks.mpbuffertoks=buffers.collect("\currentMPgraphicname")}%
+ \processMPgraphic{\the\mpbuffertoks}%
+ \endMPgraphicgroup}}
\def\runMPbuffer
{\dosingleempty\dorunMPbuffer}
@@ -718,8 +865,22 @@
%D
%D The most simple case:
-\long\def\startMPcode#1\stopMPcode
- {\processMPgraphic{#1}}
+\def\startMPcode{\dosinglegroupempty\dostartMPcode}
+
+\def\dostartMPcode
+ {\iffirstargument
+ \expandafter\dodostartMPcode
+ \else
+ \expandafter\nodostartMPcode
+ \fi}
+
+\def\dodostartMPcode#1#2\stopMPcode
+ {\beginMPgraphicgroup{#1::\s!dummy}% name does not matter
+ \processMPgraphic{#2}%
+ \endMPgraphicgroup}
+
+\def\nodostartMPcode#1#2\stopMPcode
+ {\processMPgraphic{#2}}
\let\stopMPcode\relax
@@ -749,7 +910,7 @@
%D accomplished by:
\def\douseMPlibrary#1%
- {\ifundefined{\c!file\f!metapostprefix#1}%
+ {\ifcsname\c!file\f!metapostprefix#1\endcsname\else
\letvalueempty{\c!file\f!metapostprefix#1}%
\makeshortfilename[\truefilename{\f!metapostprefix#1}]%
\startreadingfile
@@ -839,7 +1000,7 @@
\to \everyMPgraphic
\appendtoks
- \expanded{\definecolor[currentcolor][\currentcolorname]}%
+ \normalexpanded{\noexpand\definecolor[currentcolor][\currentcolorname]}%
\to \everyMPgraphic
\appendtoks
@@ -1003,9 +1164,9 @@
\long\def\dostartMPcolor[#1][#2]#3\stopMPcolor % slow but sometimes handy
{\startnointerference
- \def\handleMPgraycolor{\expanded{\defineglobalcolor[#1][s=\!MPgMPa1,#2]}}%
- \def\handleMPrgbcolor {\expanded{\defineglobalcolor[#1][r=\!MPgMPa1,g=\!MPgMPa2,b=\!MPgMPa3,#2]}}%
- \def\handleMPcmykcolor{\expanded{\defineglobalcolor[#1][c=\!MPgMPa1,m=\!MPgMPa2,y=\!MPgMPa3,k=\!MPgMPa4,#2]}}%
+ \def\handleMPgraycolor{\normalexpanded{\noexpand\defineglobalcolor[#1][s=\!MPgMPa1,#2]}}%
+ \def\handleMPrgbcolor {\normalexpanded{\noexpand\defineglobalcolor[#1][r=\!MPgMPa1,g=\!MPgMPa2,b=\!MPgMPa3,#2]}}%
+ \def\handleMPcmykcolor{\normalexpanded{\noexpand\defineglobalcolor[#1][c=\!MPgMPa1,m=\!MPgMPa2,y=\!MPgMPa3,k=\!MPgMPa4,#2]}}%
\processMPgraphic{#3}%
\stopnointerference}
@@ -1095,12 +1256,10 @@
{\startreusableMPgraphic{\@@MPG#1@S@}#2\stopreusableMPgraphic}
\long\def\startstaticMPgraphic
- {\blabelgroup
- \dodoublegroupempty\dostartstaticMPgraphic}
+ {\dodoublegroupempty\dostartstaticMPgraphic}
\long\def\dostartstaticMPgraphic#1#2#3\stopstaticMPgraphic
- {\long\setgvalue{\@@MPG#1@S@}{\handlereusableMPgraphic{#1}{#2}{#3}}%
- \elabelgroup}
+ {\long\setgvalue{\@@MPG#1@S@}{\handlereusableMPgraphic{#1}{#2}{#3}}}
%D New:
diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua
index 39f24aa5b..240778bfa 100644
--- a/tex/context/base/meta-pdf.lua
+++ b/tex/context/base/meta-pdf.lua
@@ -1,228 +1,94 @@
--- filename : meta-pdf.lua
--- comment : companion to meta-pdf.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
-
--- This is the third version. Version 1 converted to Lua code,
--- version 2 gsubbed the file into TeX code, and version 3 uses
--- the new lpeg functionality and streams the result into TeX.
-
--- We will move old stuff to edu.
-
---~ old lpeg 0.4 lpeg 0.5
---~ 100 times test graphic 2.45 (T:1.07) 0.72 (T:0.24) 0.580 (0.560 no table) -- 0.54 optimized for one space (T:0.19)
---~ 100 times big graphic 10.44 4.30/3.35 nogb 2.914 (2.050 no table) -- 1.99 optimized for one space (T:0.85)
---~ 500 times test graphic T:1.29 T:1.16 (T:1.10 no table) -- T:1.10
-
-if not versions then versions = { } end versions['meta-pdf'] = 1.003
-
-mptopdf = { }
-mptopdf.parsers = { }
-mptopdf.parser = 'none'
-
-function mptopdf.reset()
- mptopdf.data = ""
- mptopdf.path = { }
- mptopdf.stack = { }
- mptopdf.texts = { }
- mptopdf.version = 0
- mptopdf.shortcuts = false
- mptopdf.resetpath()
-end
-
-function mptopdf.resetpath()
- mptopdf.stack.close = false
- mptopdf.stack.path = { }
- mptopdf.stack.concat = nil
- mptopdf.stack.special = false
-end
+if not modules then modules = { } end modules ['meta-pdf'] = {
+ version = 1.001,
+ comment = "companion to meta-pdf.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-mptopdf.reset()
+-- Finally we used an optimized version. The test code can be found in
+-- meta-pdh.lua but since we no longer want to overload functione we
+-- use more locals now.
-function mptopdf.parsers.none()
- -- no parser set
-end
+local concat, format, gsub, find = table.concat, string.format, string.gsub, string.find
+local byte = string.byte
+local texsprint = tex.sprint
-function mptopdf.parse()
- mptopdf.parsers[mptopdf.parser]()
-end
+local ctxcatcodes = tex.ctxcatcodes
--- old code
+mptopdf = { }
+mptopdf.n = 0
-mptopdf.steps = { }
+local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false
-mptopdf.descapes = {
- ['('] = "\\\\char40 ",
- [')'] = "\\\\char41 ",
- ['"'] = "\\\\char92 "
-}
+local m_stack_close, m_stack_path, m_stack_concat = false, { }, nil
-function mptopdf.descape(str)
- str = str:gsub("\\(%d%d%d)",function(n)
- return "\\char" .. tonumber(n,8) .. " "
- end)
- return str:gsub("\\([%(%)\\])",mptopdf.descapes)
+local function resetpath()
+ m_stack_close = false
+ m_stack_path = { }
+ m_stack_concat = nil
end
-function mptopdf.steps.descape(str)
- str = str:gsub("\\(%d%d%d)",function(n)
- return "\\\\char" .. tonumber(n,8) .. " "
- end)
- return str:gsub("\\([%(%)\\])",mptopdf.descapes)
+local function resetall()
+ m_path, m_stack, m_texts, m_version, m_shortcuts = { }, { }, { }, 0, false
+ resetpath()
end
-function mptopdf.steps.strip() -- .3 per expr
- mptopdf.data = mptopdf.data:gsub("^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic)
- local bbox = "0 0 0 0"
- for b in preamble:gmatch("%%%%%a+oundingBox: +(.-)%c+") do
- bbox = b
- end
- local name, version = preamble:gmatch("%%%%Creator: +(.-) +(.-) ")
- mptopdf.version = tostring(version or "0")
- if preamble:find("/hlw{0 dtransform") then
- mptopdf.shortcuts = true
- end
- -- the boundingbox specification needs to come before data, well, not really
- return bbox .. " boundingbox\n" .. "\nbegindata\n" .. graphic .. "\nenddata\n"
- end, 1)
- mptopdf.data = mptopdf.data:gsub("%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1)
- mptopdf.data = mptopdf.data:gsub("%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n")
- mptopdf.data = mptopdf.data:gsub("%%.-%c+", "")
-end
-
-function mptopdf.steps.cleanup()
- if not mptopdf.shortcuts then
- mptopdf.data = mptopdf.data:gsub("gsave%s+fill%s+grestore%s+stroke", "both")
- mptopdf.data = mptopdf.data:gsub("([%d%.]+)%s+([%d%.]+)%s+dtransform%s+exch%s+truncate%s+exch%s+idtransform%s+pop%s+setlinewidth", function(wx,wy)
- if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
- end)
- mptopdf.data = mptopdf.data:gsub("([%d%.]+)%s+([%d%.]+)%s+dtransform%s+truncate%s+idtransform%s+setlinewidth%s+pop", function(wx,wy)
- if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
- end)
- end
-end
+resetall()
-function mptopdf.steps.convert()
- mptopdf.data = mptopdf.data:gsub("%c%((.-)%) (.-) (.-) fshow", function(str,font,scale)
- mptopdf.texts[mptopdf.texts+1] = {mptopdf.steps.descape(str), font, scale}
- return "\n" .. #mptopdf.texts .. " textext"
- end)
- mptopdf.data = mptopdf.data:gsub("%[%s*(.-)%s*%]", function(str)
- return str:gsub("%s+"," ")
- end)
- local t
- mptopdf.data = mptopdf.data:gsub("%s*([^%a]-)%s*(%a+)", function(args,cmd)
- if cmd == "textext" then
- t = mptopdf.texts[tonumber(args)]
- return "mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n"
- else
- return "mps." .. cmd .. "(" .. args:gsub(" +",",") .. ")\n"
- end
- end)
-end
+-- code injection, todo: collect and flush packed using node injection
-function mptopdf.steps.process()
- assert(loadstring(mptopdf.data))() -- () runs the loaded chunk
+local function pdfcode(str) -- not used
+ texsprint(ctxcatcodes,"\\MPScode{",str,"}")
end
-
-function mptopdf.parsers.gsub()
- mptopdf.steps.strip()
- mptopdf.steps.cleanup()
- mptopdf.steps.convert()
- mptopdf.steps.process()
-end
-
--- end of old code
-
--- from lua to tex
-
-function mptopdf.pdfcode(str)
- tex.sprint(tex.ctxcatcodes,"\\PDFcode{" .. str .. "}")
-end
-
-function mptopdf.texcode(str)
- tex.sprint(tex.ctxcatcodes,str)
+local function texcode(str)
+ texsprint(ctxcatcodes,str)
end
-- auxiliary functions
-function mptopdf.flushconcat()
- if mptopdf.stack.concat then
- mptopdf.pdfcode(table.concat(mptopdf.stack.concat," ") .. " cm")
- mptopdf.stack.concat = nil
+local function flushconcat()
+ if m_stack_concat then
+ texsprint(ctxcatcodes,"\\MPScode{",concat(m_stack_concat," ")," cm}")
+ m_stack_concat = nil
end
end
-function mptopdf.flushpath(cmd)
- if #mptopdf.stack.path > 0 then
+local function flushpath(cmd)
+ -- faster: no local function
+ if #m_stack_path > 0 then
local path = { }
- if mptopdf.stack.concat then
- local sx, sy = mptopdf.stack.concat[1], mptopdf.stack.concat[4]
- local rx, ry = mptopdf.stack.concat[2], mptopdf.stack.concat[3]
- local tx, ty = mptopdf.stack.concat[5], mptopdf.stack.concat[6]
+ if m_stack_concat then
+ local sx, sy = m_stack_concat[1], m_stack_concat[4]
+ local rx, ry = m_stack_concat[2], m_stack_concat[3]
+ local tx, ty = m_stack_concat[5], m_stack_concat[6]
local d = (sx*sy) - (rx*ry)
- local function concat(px, py)
- return (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d
- end
- for _,v in ipairs(mptopdf.stack.path) do
- v[1],v[2] = concat(v[1],v[2])
+ -- local function mpconcat(px, py) -- move this inline
+ -- return (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d
+ -- end
+ for k=1,#m_stack_path do
+ local v = m_stack_path[k]
+ local px, py = v[1], v[2] ; v[1], v[2] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[1],v[2])
if #v == 7 then
- v[3],v[4] = concat(v[3],v[4])
- v[5],v[6] = concat(v[5],v[6])
+ local px, py = v[3], v[4] ; v[3], v[4] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[3],v[4])
+ local px, py = v[5], v[6] ; v[5], v[6] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[5],v[6])
end
- path[#path+1] = table.concat(v," ")
+ path[#path+1] = concat(v," ")
end
else
- for _,v in ipairs(mptopdf.stack.path) do
- path[#path+1] = table.concat(v," ")
+ for k=1,#m_stack_path do
+ path[#path+1] = concat(m_stack_path[k]," ")
end
end
- mptopdf.flushconcat()
- mptopdf.texcode("\\MPSpath{" .. table.concat(path," ") .. "}")
- if mptopdf.stack.close then
- mptopdf.texcode("\\MPScode{h " .. cmd .. "}")
+ flushconcat()
+ texcode("\\MPSpath{" .. concat(path," ") .. "}")
+ if m_stack_close then
+ texcode("\\MPScode{h " .. cmd .. "}")
else
- mptopdf.texcode("\\MPScode{" .. cmd .."}")
+ texcode("\\MPScode{" .. cmd .."}")
end
end
- mptopdf.resetpath()
-end
-
-if input and input.instance then
- function mptopdf.loaded(name)
- local ok, n
- mptopdf.reset()
- ok, mptopdf.data, n = input.loadbinfile(name, 'tex') -- we need a binary load !
- return ok
- end
-else
- function mptopdf.loaded(name)
- local f = io.open(name, 'rb')
- if f then
- mptopdf.reset()
- mptopdf.data = f:read('*all')
- f:close()
- return true
- else
- return false
- end
- end
-end
-
-if not mptopdf.parse then
- function mptopdf.parse() end -- forward declaration
-end
-
-function mptopdf.convertmpstopdf(name)
- if mptopdf.loaded(name) then
- input.starttiming(mptopdf)
- mptopdf.parse()
- mptopdf.reset()
- input.stoptiming(mptopdf)
- else
- tex.print("file " .. name .. " not found")
- end
+ resetpath()
end
-- mp interface
@@ -230,171 +96,133 @@ end
mps = mps or { }
function mps.creator(a, b, c)
- mptopdf.version = tonumber(b)
+ m_version = tonumber(b)
end
function mps.creationdate(a)
- mptopdf.date= a
+ m_date = a
end
function mps.newpath()
- mptopdf.stack.path = { }
+ m_stack_path = { }
end
function mps.boundingbox(llx, lly, urx, ury)
- mptopdf.texcode("\\MPSboundingbox{" .. llx .. "}{" .. lly .. "}{" .. urx .. "}{" .. ury .. "}")
+ texcode("\\MPSboundingbox{" .. llx .. "}{" .. lly .. "}{" .. urx .. "}{" .. ury .. "}")
end
function mps.moveto(x,y)
- mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"m"}
+ m_stack_path[#m_stack_path+1] = {x,y,"m"}
end
function mps.curveto(ax, ay, bx, by, cx, cy)
- mptopdf.stack.path[#mptopdf.stack.path+1] = {ax,ay,bx,by,cx,cy,"c"}
+ m_stack_path[#m_stack_path+1] = {ax,ay,bx,by,cx,cy,"c"}
end
function mps.lineto(x,y)
- mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"l"}
+ m_stack_path[#m_stack_path+1] = {x,y,"l"}
end
function mps.rlineto(x,y)
local dx, dy = 0, 0
- if #mptopdf.stack.path > 0 then
- dx, dy = mptopdf.stack.path[#mptopdf.stack.path][1], mptopdf.stack.path[#mptopdf.stack.path][2]
+ if #m_stack_path > 0 then
+ dx, dy = m_stack_path[#m_stack_path][1], m_stack_path[#m_stack_path][2]
end
- mptopdf.stack.path[#mptopdf.stack.path+1] = {dx,dy,"l"}
+ m_stack_path[#m_stack_path+1] = {dx,dy,"l"}
end
function mps.translate(tx,ty)
- mptopdf.pdfcode("1 0 0 0 1 " .. tx .. " " .. ty .. " cm")
+ texsprint(ctxcatcodes,"\\MPScode{1 0 0 0 1 ",tx," ",ty," cm}")
end
function mps.scale(sx,sy)
- mptopdf.stack.concat = {sx,0,0,sy,0,0}
+ m_stack_concat = {sx,0,0,sy,0,0}
end
function mps.concat(sx, rx, ry, sy, tx, ty)
- mptopdf.stack.concat = {sx,rx,ry,sy,tx,ty}
+ m_stack_concat = {sx,rx,ry,sy,tx,ty}
end
function mps.setlinejoin(d)
- mptopdf.pdfcode(d .. " j")
+ texsprint(ctxcatcodes,"\\MPScode{",d," j}")
end
function mps.setlinecap(d)
- mptopdf.pdfcode(d .. " J")
+ texsprint(ctxcatcodes,"\\MPScode{",d," J}")
end
function mps.setmiterlimit(d)
- mptopdf.pdfcode(d .. " M")
+ texsprint(ctxcatcodes,"\\MPScode{",d," M}")
end
function mps.gsave()
- mptopdf.pdfcode("q")
+ texsprint(ctxcatcodes,"\\MPScode{q}")
end
function mps.grestore()
- mptopdf.pdfcode("Q")
+ texsprint(ctxcatcodes,"\\MPScode{Q}")
end
-function mps.setdash(...)
+function mps.setdash(...) -- can be made faster, operate on t = { ... }
local n = select("#",...)
- mptopdf.pdfcode("[" .. table.concat({...}," ",1,n-1) .. "] " .. select(n,...) .. " d")
+ texsprint(ctxcatcodes,"\\MPScode{","[",concat({...}," ",1,n-1),"] ",select(n,...)," d}")
end
function mps.resetdash()
- mptopdf.pdfcode("[ ] 0 d")
+ texsprint(ctxcatcodes,"\\MPScode{[ ] 0 d}")
end
function mps.setlinewidth(d)
- mptopdf.pdfcode(d .. " w")
+ texsprint(ctxcatcodes,"\\MPScode{",d," w}")
end
function mps.closepath()
- mptopdf.stack.close = true
+ m_stack_close = true
end
function mps.fill()
- mptopdf.flushpath('f')
+ flushpath('f')
end
function mps.stroke()
- mptopdf.flushpath('S')
+ flushpath('S')
end
function mps.both()
- mptopdf.flushpath('B')
+ flushpath('B')
end
function mps.clip()
- mptopdf.flushpath('W n')
+ flushpath('W n')
end
function mps.textext(font, scale, str) -- old parser
local dx, dy = 0, 0
- if #mptopdf.stack.path > 0 then
- dx, dy = mptopdf.stack.path[1][1], mptopdf.stack.path[1][2]
+ if #m_stack_path > 0 then
+ dx, dy = m_stack_path[1][1], m_stack_path[1][2]
end
- mptopdf.flushconcat()
- mptopdf.texcode("\\MPStextext{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
- mptopdf.resetpath()
+ flushconcat()
+ texcode("\\MPStextext{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
+ resetpath()
end
---~ function mps.handletext(font,scale.str,dx,dy)
---~ local one, two = string.match(str, "^(%d+)::::(%d+)")
---~ if one and two then
---~ mptopdf.texcode("\\MPTOPDFtextext{"..font.."}{"..scale.."}{"..one.."}{"..two.."}{"..dx.."}{"..dy.."}")
---~ else
---~ mptopdf.texcode("\\MPTOPDFtexcode{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
---~ end
---~ end
-
-if false and ctx and ctx.aux and ctx.aux.definecolor then
-
- logs.report("mptopdf", "using attribute based mps colors")
-
- -- does not work due to Q-q mess-up
-
- function mps.setrgbcolor(r,g,b) -- extra check
- r, g, b = tonumber(r), tonumber(g), tonumber(b) -- needed when we use lpeg
- if r == 0.0123 and g < 0.1 then -- g is extra check
- mptopdf.texcode("\\doresetattribute{transparency}\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
- elseif r == 0.123 and g < 0.1 then -- g is extra check
- mptopdf.texcode("\\doresetattribute{transparency}\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
- else
- mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'rgb',r,g,b) .. "}")
- end
- end
-
- function mps.setcmykcolor(c,m,y,k)
- mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'cmyk',tonumber(c),tonumber(m),tonumber(y),tonumber(k)) .. "}")
- end
-
- function mps.setgray(s)
- mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'gray',tonumber(s)) .. "}")
- end
-
-else
-
- function mps.setrgbcolor(r,g,b) -- extra check
- r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
- if r == 0.0123 and g < 0.1 then
- mptopdf.texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
- elseif r == 0.123 and g < 0.1 then
- mptopdf.texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
- else
- mptopdf.texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
- end
- end
-
- function mps.setcmykcolor(c,m,y,k)
- mptopdf.texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
+function mps.setrgbcolor(r,g,b) -- extra check
+ r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
+ if r == 0.0123 and g < 0.1 then
+ texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
+ elseif r == 0.123 and g < 0.1 then
+ texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
+ else
+ texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
end
+end
- function mps.setgray(s)
- mptopdf.texcode("\\MPSgray{" .. s .. "}")
- end
+function mps.setcmykcolor(c,m,y,k)
+ texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
+end
+function mps.setgray(s)
+ texcode("\\MPSgray{" .. s .. "}")
end
function mps.specials(version,signal,factor) -- 2.0 123 1000
@@ -402,7 +230,7 @@ end
function mps.special(...) -- 7 1 0.5 1 0 0 1 3
local n = select("#",...)
- mptopdf.texcode("\\MPSbegin\\MPSset{" .. table.concat({...},"}\\MPSset{",2,n) .. "}\\MPSend")
+ texcode("\\MPSbegin\\MPSset{" .. concat({...},"}\\MPSset{",2,n) .. "}\\MPSend")
end
function mps.begindata()
@@ -414,43 +242,8 @@ end
function mps.showpage()
end
-mps.n = mps.newpath -- n
-mps.p = mps.closepath -- h
-mps.l = mps.lineto -- l
-mps.r = mps.rlineto -- r
-mps.m = mps.moveto -- m
-mps.c = mps.curveto -- c
-mps.hlw = mps.setlinewidth
-mps.vlw = mps.setlinewidth
-
-mps.C = mps.setcmykcolor -- k
-mps.G = mps.setgray -- g
-mps.R = mps.setrgbcolor -- rg
-
-mps.lj = mps.setlinejoin -- j
-mps.ml = mps.setmiterlimit -- M
-mps.lc = mps.setlinecap -- J
-mps.sd = mps.setdash -- d
-mps.rd = mps.resetdash
-
-mps.S = mps.stroke -- S
-mps.F = mps.fill -- f
-mps.B = mps.both -- B
-mps.W = mps.clip -- W
-
-mps.q = mps.gsave -- q
-mps.Q = mps.grestore -- Q
-
-mps.s = mps.scale -- (not in pdf)
-mps.t = mps.concat -- (not the same as pdf anyway)
-
-mps.P = mps.showpage
-
--- experimental
-
function mps.attribute(id,value)
- mptopdf.texcode("\\attribute " .. id .. "=" .. value .. " ")
--- mptopdf.texcode("\\dompattribute{" .. id .. "}{" .. value .. "}")
+ texcode("\\attribute " .. id .. "=" .. value .. " ")
end
-- lpeg parser
@@ -459,160 +252,178 @@ end
-- that MetaPost produces. It's my first real lpeg code, which may
-- show. Because the parser binds to functions, we define it last.
-do -- assumes \let\c\char
+local lpegP, lpegR, lpegS, lpegC, lpegCc, lpegCs = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs
+
+local digit = lpegR("09")
+local eol = lpegS('\r\n')^1
+local sp = lpegP(' ')^1
+local space = lpegS(' \r\n')^1
+local number = lpegS('0123456789.-+')^1
+local nonspace = lpegP(1-lpegS(' \r\n'))^1
+
+local spec = digit^2 * lpegP("::::") * digit^2
+local text = lpegCc("{") * (
+ lpegP("\\") * ( (digit * digit * digit) / function(n) return "c" .. tonumber(n,8) end) +
+ lpegP(" ") / function(n) return "\\c32" end + -- never in new mp
+ lpegP(1) / function(n) return "\\c" .. byte(n) end
+ ) * lpegCc("}")
+local package = lpegCs(spec + text^0)
+
+function mps.fshow(str,font,scale) -- lpeg parser
+ mps.textext(font,scale,package:match(str))
+end
+
+local cnumber = lpegC(number)
+local cstring = lpegC(nonspace)
+
+local specials = (lpegP("%%MetaPostSpecials:") * sp * (cstring * sp^0)^0 * eol) / mps.specials
+local special = (lpegP("%%MetaPostSpecial:") * sp * (cstring * sp^0)^0 * eol) / mps.special
+local boundingbox = (lpegP("%%BoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
+local highresboundingbox = (lpegP("%%HiResBoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
+
+local setup = lpegP("%%BeginSetup") * (1 - lpegP("%%EndSetup") )^1
+local prolog = lpegP("%%BeginProlog") * (1 - lpegP("%%EndProlog"))^1
+local comment = lpegP('%')^1 * (1 - eol)^1
+
+local curveto = ((cnumber * sp)^6 * lpegP("curveto") ) / mps.curveto
+local lineto = ((cnumber * sp)^2 * lpegP("lineto") ) / mps.lineto
+local rlineto = ((cnumber * sp)^2 * lpegP("rlineto") ) / mps.rlineto
+local moveto = ((cnumber * sp)^2 * lpegP("moveto") ) / mps.moveto
+local setrgbcolor = ((cnumber * sp)^3 * lpegP("setrgbcolor") ) / mps.setrgbcolor
+local setcmykcolor = ((cnumber * sp)^4 * lpegP("setcmykcolor") ) / mps.setcmykcolor
+local setgray = ((cnumber * sp)^1 * lpegP("setgray") ) / mps.setgray
+local newpath = ( lpegP("newpath") ) / mps.newpath
+local closepath = ( lpegP("closepath") ) / mps.closepath
+local fill = ( lpegP("fill") ) / mps.fill
+local stroke = ( lpegP("stroke") ) / mps.stroke
+local clip = ( lpegP("clip") ) / mps.clip
+local both = ( lpegP("gsave fill grestore")) / mps.both
+local showpage = ( lpegP("showpage") )
+local setlinejoin = ((cnumber * sp)^1 * lpegP("setlinejoin") ) / mps.setlinejoin
+local setlinecap = ((cnumber * sp)^1 * lpegP("setlinecap") ) / mps.setlinecap
+local setmiterlimit = ((cnumber * sp)^1 * lpegP("setmiterlimit") ) / mps.setmiterlimit
+local gsave = ( lpegP("gsave") ) / mps.gsave
+local grestore = ( lpegP("grestore") ) / mps.grestore
+
+local setdash = (lpegP("[") * (cnumber * sp^0)^0 * lpegP("]") * sp * cnumber * sp * lpegP("setdash")) / mps.setdash
+local concat = (lpegP("[") * (cnumber * sp^0)^6 * lpegP("]") * sp * lpegP("concat") ) / mps.concat
+local scale = ( (cnumber * sp^0)^6 * sp * lpegP("concat") ) / mps.concat
+
+local fshow = (lpegP("(") * lpegC((1-lpegP(")"))^1) * lpegP(")") * space * cstring * space * cnumber * space * lpegP("fshow")) / mps.fshow
+local fshow = (lpegP("(") * lpegCs( ( lpegP("\\(")/"\\050" + lpegP("\\)")/"\\051" + (1-lpegP(")")) )^1 )
+ * lpegP(")") * space * cstring * space * cnumber * space * lpegP("fshow")) / mps.fshow
+
+local setlinewidth_x = (lpegP("0") * sp * cnumber * sp * lpegP("dtransform truncate idtransform setlinewidth pop")) / mps.setlinewidth
+local setlinewidth_y = (cnumber * sp * lpegP("0 dtransform exch truncate exch idtransform pop setlinewidth") ) / mps.setlinewidth
+
+local c = ((cnumber * sp)^6 * lpegP("c") ) / mps.curveto -- ^6 very inefficient, ^1 ok too
+local l = ((cnumber * sp)^2 * lpegP("l") ) / mps.lineto
+local r = ((cnumber * sp)^2 * lpegP("r") ) / mps.rlineto
+local m = ((cnumber * sp)^2 * lpegP("m") ) / mps.moveto
+local vlw = ((cnumber * sp)^1 * lpegP("vlw")) / mps.setlinewidth
+local hlw = ((cnumber * sp)^1 * lpegP("hlw")) / mps.setlinewidth
+
+local R = ((cnumber * sp)^3 * lpegP("R") ) / mps.setrgbcolor
+local C = ((cnumber * sp)^4 * lpegP("C") ) / mps.setcmykcolor
+local G = ((cnumber * sp)^1 * lpegP("G") ) / mps.setgray
+
+local lj = ((cnumber * sp)^1 * lpegP("lj") ) / mps.setlinejoin
+local ml = ((cnumber * sp)^1 * lpegP("ml") ) / mps.setmiterlimit
+local lc = ((cnumber * sp)^1 * lpegP("lc") ) / mps.setlinecap
+
+local n = lpegP("n") / mps.newpath
+local p = lpegP("p") / mps.closepath
+local S = lpegP("S") / mps.stroke
+local F = lpegP("F") / mps.fill
+local B = lpegP("B") / mps.both
+local W = lpegP("W") / mps.clip
+local P = lpegP("P") / mps.showpage
+
+local q = lpegP("q") / mps.gsave
+local Q = lpegP("Q") / mps.grestore
+
+local sd = (lpegP("[") * (cnumber * sp^0)^0 * lpegP("]") * sp * cnumber * sp * lpegP("sd")) / mps.setdash
+local rd = ( lpegP("rd")) / mps.resetdash
+
+local s = ( (cnumber * sp^0)^2 * lpegP("s") ) / mps.scale
+local t = (lpegP("[") * (cnumber * sp^0)^6 * lpegP("]") * sp * lpegP("t") ) / mps.concat
- local byte = string.byte
- local digit = lpeg.R("09")
- local spec = digit^2 * lpeg.P("::::") * digit^2
- local text = lpeg.Cc("{") * (
- lpeg.P("\\") * ( (digit * digit * digit) / function(n) return "c" .. tonumber(n,8) end) +
- lpeg.P(" ") / function(n) return "\\c32" end + -- never in new mp
- lpeg.P(1) / function(n) return "\\c" .. byte(n) end
- ) * lpeg.Cc("}")
- local package = lpeg.Cs(spec + text^0)
+-- experimental
- function mps.fshow(str,font,scale) -- lpeg parser
- mps.textext(font,scale,package:match(str))
+local attribute = ((cnumber * sp)^2 * lpegP("attribute")) / mps.attribute
+local A = ((cnumber * sp)^2 * lpegP("A")) / mps.attribute
+
+local preamble = (
+ prolog + setup +
+ boundingbox + highresboundingbox + specials + special +
+ comment
+)
+
+local procset = (
+ lj + ml + lc +
+ c + l + m + n + p + r +
+ A +
+ R + C + G +
+ S + F + B + W +
+ vlw + hlw +
+ Q + q +
+ sd + rd +
+ t + s +
+ fshow +
+ P
+)
+
+local verbose = (
+ curveto + lineto + moveto + newpath + closepath + rlineto +
+ setrgbcolor + setcmykcolor + setgray +
+ attribute +
+ setlinejoin + setmiterlimit + setlinecap +
+ stroke + fill + clip + both +
+ setlinewidth_x + setlinewidth_y +
+ gsave + grestore +
+ concat + scale +
+ fshow +
+ setdash + -- no resetdash
+ showpage
+)
+
+-- order matters in terms of speed / we could check for procset first
+
+local captures_old = ( space + verbose + preamble )^0
+local captures_new = ( space + procset + preamble + verbose )^0
+
+local function parse(m_data)
+ if find(m_data,"%%%%BeginResource: procset mpost") then
+ captures_new:match(m_data)
+ else
+ captures_old:match(m_data)
end
-
end
-do
-
- local eol = lpeg.S('\r\n')^1
- local sp = lpeg.P(' ')^1
- local space = lpeg.S(' \r\n')^1
- local number = lpeg.S('0123456789.-+')^1
- local nonspace = lpeg.P(1-lpeg.S(' \r\n'))^1
-
- local cnumber = lpeg.C(number)
- local cstring = lpeg.C(nonspace)
-
- local specials = (lpeg.P("%%MetaPostSpecials:") * sp * (cstring * sp^0)^0 * eol) / mps.specials
- local special = (lpeg.P("%%MetaPostSpecial:") * sp * (cstring * sp^0)^0 * eol) / mps.special
- local boundingbox = (lpeg.P("%%BoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
- local highresboundingbox = (lpeg.P("%%HiResBoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
-
- local setup = lpeg.P("%%BeginSetup") * (1 - lpeg.P("%%EndSetup") )^1
- local prolog = lpeg.P("%%BeginProlog") * (1 - lpeg.P("%%EndProlog"))^1
- local comment = lpeg.P('%')^1 * (1 - eol)^1
-
- local curveto = ((cnumber * sp)^6 * lpeg.P("curveto") ) / mps.curveto
- local lineto = ((cnumber * sp)^2 * lpeg.P("lineto") ) / mps.lineto
- local rlineto = ((cnumber * sp)^2 * lpeg.P("rlineto") ) / mps.rlineto
- local moveto = ((cnumber * sp)^2 * lpeg.P("moveto") ) / mps.moveto
- local setrgbcolor = ((cnumber * sp)^3 * lpeg.P("setrgbcolor") ) / mps.setrgbcolor
- local setcmykcolor = ((cnumber * sp)^4 * lpeg.P("setcmykcolor") ) / mps.setcmykcolor
- local setgray = ((cnumber * sp)^1 * lpeg.P("setgray") ) / mps.setgray
- local newpath = ( lpeg.P("newpath") ) / mps.newpath
- local closepath = ( lpeg.P("closepath") ) / mps.closepath
- local fill = ( lpeg.P("fill") ) / mps.fill
- local stroke = ( lpeg.P("stroke") ) / mps.stroke
- local clip = ( lpeg.P("clip") ) / mps.clip
- local both = ( lpeg.P("gsave fill grestore")) / mps.both
- local showpage = ( lpeg.P("showpage") )
- local setlinejoin = ((cnumber * sp)^1 * lpeg.P("setlinejoin") ) / mps.setlinejoin
- local setlinecap = ((cnumber * sp)^1 * lpeg.P("setlinecap") ) / mps.setlinecap
- local setmiterlimit = ((cnumber * sp)^1 * lpeg.P("setmiterlimit") ) / mps.setmiterlimit
- local gsave = ( lpeg.P("gsave") ) / mps.gsave
- local grestore = ( lpeg.P("grestore") ) / mps.grestore
-
- local setdash = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("setdash")) / mps.setdash
- local concat = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("concat") ) / mps.concat
- local scale = ( (cnumber * sp^0)^6 * sp * lpeg.P("concat") ) / mps.concat
-
- local fshow = (lpeg.P("(") * lpeg.C((1-lpeg.P(")"))^1) * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
- local fshow = (lpeg.P("(") *
- lpeg.Cs( ( lpeg.P("\\(")/"\\050" + lpeg.P("\\)")/"\\051" + (1-lpeg.P(")")) )^1 )
- * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
-
- local setlinewidth_x = (lpeg.P("0") * sp * cnumber * sp * lpeg.P("dtransform truncate idtransform setlinewidth pop")) / mps.setlinewidth
- local setlinewidth_y = (cnumber * sp * lpeg.P("0 dtransform exch truncate exch idtransform pop setlinewidth") ) / mps.setlinewidth
-
- local c = ((cnumber * sp)^6 * lpeg.P("c") ) / mps.curveto -- ^6 very inefficient, ^1 ok too
- local l = ((cnumber * sp)^2 * lpeg.P("l") ) / mps.lineto
- local r = ((cnumber * sp)^2 * lpeg.P("r") ) / mps.rlineto
- local m = ((cnumber * sp)^2 * lpeg.P("m") ) / mps.moveto
- local vlw = ((cnumber * sp)^1 * lpeg.P("vlw")) / mps.setlinewidth
- local hlw = ((cnumber * sp)^1 * lpeg.P("hlw")) / mps.setlinewidth
-
- local R = ((cnumber * sp)^3 * lpeg.P("R") ) / mps.setrgbcolor
- local C = ((cnumber * sp)^4 * lpeg.P("C") ) / mps.setcmykcolor
- local G = ((cnumber * sp)^1 * lpeg.P("G") ) / mps.setgray
-
- local lj = ((cnumber * sp)^1 * lpeg.P("lj") ) / mps.setlinejoin
- local ml = ((cnumber * sp)^1 * lpeg.P("ml") ) / mps.setmiterlimit
- local lc = ((cnumber * sp)^1 * lpeg.P("lc") ) / mps.setlinecap
-
- local n = lpeg.P("n") / mps.newpath
- local p = lpeg.P("p") / mps.closepath
- local S = lpeg.P("S") / mps.stroke
- local F = lpeg.P("F") / mps.fill
- local B = lpeg.P("B") / mps.both
- local W = lpeg.P("W") / mps.clip
- local P = lpeg.P("P") / mps.showpage
-
- local q = lpeg.P("q") / mps.gsave
- local Q = lpeg.P("Q") / mps.grestore
-
- local sd = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("sd")) / mps.setdash
- local rd = ( lpeg.P("rd")) / mps.resetdash
-
- local s = ( (cnumber * sp^0)^2 * lpeg.P("s") ) / mps.scale
- local t = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("t") ) / mps.concat
-
- -- experimental
-
- local attribute = ((cnumber * sp)^2 * lpeg.P("attribute")) / mps.attribute
- local A = ((cnumber * sp)^2 * lpeg.P("A")) / mps.attribute
-
- local preamble = (
- prolog + setup +
- boundingbox + highresboundingbox + specials + special +
- comment
- )
-
- local procset = (
- lj + ml + lc +
- c + l + m + n + p + r +
- A +
- R + C + G +
- S + F + B + W +
- vlw + hlw +
- Q + q +
- sd + rd +
- t + s +
- fshow +
- P
- )
-
- local verbose = (
- curveto + lineto + moveto + newpath + closepath + rlineto +
- setrgbcolor + setcmykcolor + setgray +
- attribute +
- setlinejoin + setmiterlimit + setlinecap +
- stroke + fill + clip + both +
- setlinewidth_x + setlinewidth_y +
- gsave + grestore +
- concat + scale +
- fshow +
- setdash + -- no resetdash
- showpage
- )
-
- -- order matters in terms of speed / we could check for procset first
-
- local captures_old = ( space + verbose + preamble )^0
- local captures_new = ( space + procset + preamble + verbose )^0
-
- function mptopdf.parsers.lpeg()
- if mptopdf.data:find("%%%%BeginResource: procset mpost") then
- captures_new:match(mptopdf.data)
- else
- captures_old:match(mptopdf.data)
- end
- end
+-- main converter
+function mptopdf.convertmpstopdf(name)
+ resetall()
+ local ok, m_data, n = resolvers.loadbinfile(name, 'tex') -- we need a binary load !
+ if ok then
+ statistics.starttiming(mptopdf)
+ mptopdf.n = mptopdf.n + 1
+ parse(m_data)
+ resetall()
+ statistics.stoptiming(mptopdf)
+ else
+ tex.print("file " .. name .. " not found")
+ end
end
-mptopdf.parser = 'lpeg'
+
+-- status info
+
+statistics.register("mps conversion time",function()
+ local n = mptopdf.n
+ if n > 0 then
+ return format("%s seconds, %s conversions", statistics.elapsedtime(mptopdf),n)
+ else
+ return nil
+ end
+end)
diff --git a/tex/context/base/meta-pdf.mkii b/tex/context/base/meta-pdf.mkii
index d1a803604..2099b0d37 100644
--- a/tex/context/base/meta-pdf.mkii
+++ b/tex/context/base/meta-pdf.mkii
@@ -1,8 +1,8 @@
%D \module
%D [ file=meta-pdf,
%D version=2006.06.07,
-%D title=\CONTEXT\ Support Macros,
-%D subtitle=\METAPOST\ to \PDF\ conversion,
+%D title=\METAPOST\ Graphics,
+%D subtitle=Conversion to \PDF,
%D author=Hans Hagen \& others (see text),
%D date=\currentdate,
%D copyright=\PRAGMA]
@@ -11,12 +11,171 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+%D Formerly known as supp-pdf.tex and supp-mpe.tex.
+
+%D We will clean up the color mess later.
+
+%D These macros are written as generic as possible. Some
+%D general support macro's are loaded from a small module
+%D especially made for non \CONTEXT\ use. In this module I
+%D use a matrix transformation macro written by Tanmoy
+%D Bhattacharya. Thanks to extensive testing by Sebastian
+%D Ratz I was able to complete this module within reasonable
+%D time. This module has support for \METAPOST\ extensions
+%D built in.
+%D
+%D Daniel H. Luecking came up with a better (more precise)
+%D transformation method. You can recognize his comment by
+%D his initials. (We keep the old code around because it's a
+%D nice illustration on how a module like this evolves.)
+
+% Beware, we cannot use 0pt here by defaukt since it may be
+% defined in the range \dimen 0 - 20 which we happen to use
+% as scratch registers; for this reason we start allocating
+% scratch registers > 20
+
+%D This module handles some \PDF\ conversion and insertions
+%D topics. By default, the macros use the \PDFTEX\ primitive
+%D \type{\pdfliteral} when available. Since \PDFTEX\ is now the
+%D default engine for \TEX\ distributions, we need a more complex
+%D test.
+
+\writestatus{loading}{MetaPost Graphics / MPS to PDF}
+
\unprotect
-%D These are the main macros.
+\ifx\PDFcode \undefined \let\PDFcode \gobbleoneargument \fi
+\ifx\PDFcomment\undefined \def\PDFcomment#1{\PDFcode{\letterpercent\space#1}} \fi
+
+%D First we define a handy constant:
+
+\bgroup \catcode`\%=\@@other \xdef\letterpercent{\string%} \egroup
+
+%D \macros
+%D {pdfimage,pdfimages,pdfclippedimage}
+%D
+%D Starting with pdftex version 14, images are included more
+%D natural to the form embedding. This enables alternative
+%D images to be embedded.
+%D
+%D \starttyping
+%D \pdfimage <optional dimensions> {file}
+%D \pdfimages <optional dimensions> {high res file} {low res file}
+%D \stoptyping
+%D
+%D The first one replaces the pre||version||14 original,
+%D while the latter provides alternative images.
+%D
+%D The next macro is dedicated to Maarten Gelderman, who
+%D needed to paste prepared \PDF\ pages into conference
+%D proceedings.
+%D
+%D \starttyping
+%D \pdfclippedimage <optional dimensions> {file} {l} {r} {t} {b}
+%D \stoptyping
+
+\ifx\pdftexversion\undefined \else \ifnum\pdftexversion>13 % still relevant?
+
+ \def\pdfimage#1#%
+ {\dopdfimage{#1}}
+
+ \def\dopdfimage#1#2%
+ {\immediate\pdfximage#1{#2}%
+ \pdfrefximage\pdflastximage}
+
+ \def\pdfimages#1#%
+ {\dopdfimages{#1}}
+
+ \def\dopdfimages#1#2#3%
+ {\immediate\pdfximage#1{#2}%
+ \immediate\pdfobj{[ << /Image \the\pdflastximage\space0 R /DefaultForPrinting true >> ]}%
+ \immediate\pdfximage#1 attr {/Alternates \the\pdflastobj\space0 R}{#3}%
+ \pdfrefximage\pdflastximage}
+
+ \def\pdfclippedimage#1#% specs {file}{left}{right}{top}{bottom}
+ {\dopdfclippedimage{#1}}
+
+ \def\dopdfclippedimage#1#2#3#4#5#6%
+ {\bgroup
+ \pdfximage#1{#2}%
+ \setbox\scratchbox\hbox{\pdfrefximage\pdflastximage}%
+ \hsize\dimexpr\wd\scratchbox-#3-#4\relax
+ \vsize\dimexpr\ht\scratchbox-#5-#6\relax
+ \setbox\scratchbox\vbox to \vsize
+ {\vskip-#5\hbox to \hsize{\hskip-#3\box\scratchbox\hss}}%
+ \pdfxform\scratchbox
+ \pdfrefxform\pdflastxform
+ \egroup}
-\def\mkconvertMPtoPDF % #1#2#3%
- {\vbox\bgroup
+\fi \fi
+
+%D \macros
+%D {convertMPtoPDF}
+%D
+%D The next set of macros implements \METAPOST\ to \PDF\
+%D conversion. The traditional method is in the MkII file.
+
+%D The main conversion command is:
+%D
+%D \starttyping
+%D \convertMPtoPDF {filename} {x scale} {y scale}
+%D \stoptyping
+%D
+%D The dimensions are derived from the bounding box. So we
+%D only have to say:
+%D
+%D \starttyping
+%D \convertMPtoPDF{mp-pra-1.eps}{1}{1}
+%D \convertMPtoPDF{mp-pra-1.eps}{.5}{.5}
+%D \stoptyping
+
+%D \macros
+%D {makeMPintoPDFobject,lastPDFMPobject}
+%D
+%D For experts there are a few more options. When attributes
+%D are to be added, the code must be embedded in an object
+%D accompanied with the appropriate directives. One can
+%D influence this process with \type {\makeMPintoPDFobject}.
+%D
+%D This option defaults to~0, because \CONTEXT\ takes care
+%D of objects at another level, which saves some bytes.
+%D
+%D \starttabulate[|l|l|p|]
+%D \NC 0 \NC never \NC don't use an object \NC\NR
+%D \NC 1 \NC always \NC always use an object \NC\NR
+%D \NC 2 \NC optional \NC use object when needed \NC\NR
+%D \stoptabulate
+%D
+%D The last object number used is avaliable in the macro
+%D \type {\lastPDFMPobject}.
+
+\ifx\makeMPintoPDFobject \undefined \chardef\makeMPintoPDFobject \zerocount \fi
+\ifx\blackoutMPgraphic \undefined \chardef\blackoutMPgraphic \plusone \fi
+\ifx\everyMPtoPDFconversion\undefined \newtoks\everyMPtoPDFconversion \fi
+
+\let\lastPDFMPobject \!!zerocount
+\let\currentPDFresources\empty
+\let\setMPextensions \relax
+
+\def\PDFMPformoffset
+ {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi}
+
+\def\resetMPvariables#1#2#3%
+ {\global\let\MPwidth \!!zeropoint
+ \global\let\MPheight\!!zeropoint
+ \global\let\MPllx \!!zerocount
+ \global\let\MPlly \!!zerocount
+ \global\let\MPurx \!!zerocount
+ \global\let\MPury \!!zerocount
+ \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi
+ \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi
+ \xdef\MPfilename {#1}}
+
+%D The main macro:
+
+\def\convertMPtoPDF#1#2#3%
+ {\resetMPvariables{#1}{#2}{#3}%
+ \vbox\bgroup
\forgetall
\offinterlineskip
\ifx\pdfdecimaldigits\undefined\else \pdfdecimaldigits=5 \fi % new
@@ -31,6 +190,12 @@
\ifcase\blackoutMPgraphic\or\PDFcode{0 g 0 G}\fi
\doprocessMPtoPDFfile}
+\def\processMPtoPDFfile#1#2#3% obsolete
+ {\resetMPvariables{#1}{#2}{#3}%
+ \bgroup
+ \let\finishMPgraphic\egroup
+ \doprocessMPtoPDFfile}
+
\def\doprocessMPtoPDFfile
{\setMPspecials
\setMPextensions
@@ -64,16 +229,764 @@
\egroup
\endinput}
-\def\mkprocessMPtoPDFfile % file xscale yscale / obsolete
+%D A common hook.
+
+\let\MPfshowcommand\empty
+
+%D Objects.
+
+\def\dopackageMPgraphic#1% #1 = boxregister
+ {\ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else
+ % an existing value of 2 signals object support (set elsewhere)
+ \chardef\makeMPintoPDFobject\plusone
+ \fi\fi
+ \ifcase\makeMPintoPDFobject
+ \box#1%
+ \or
+ \scratchdimen\PDFMPformoffset\relax
+ \ifdim\scratchdimen>\zeropoint % compensate for error
+ \setbox#1\vbox spread 2\scratchdimen
+ {\forgetall\vss\hbox spread 2\scratchdimen{\hss\box#1\hss}\vss}%
+ \fi
+ \setMPPDFobject{\currentPDFresources}{#1}%
+ \ifdim\scratchdimen>\zeropoint % compensate for error
+ \vbox to \MPheight
+ {\forgetall\vss\hbox to \MPwidth{\hss\getMPPDFobject\hss}\vss}%
+ \else
+ \getMPPDFobject
+ \fi
+ \global\let\currentPDFresources\empty
+ \else
+ \box#1%
+ \fi}
+
+\def\setMPPDFobject#1#2% resources boxnumber
+ {\ifx\pdfxform\undefined
+ \def\getMPPDFobject{\box#2}%
+ \else\ifx\pdftexversion\undefined
+ \def\getMPPDFobject{\box#2}%
+ \else\ifnum\pdftexversion<14
+ \def\getMPPDFobject{\box#2}%
+ \else
+ \ifx\everyPDFxform\undefined\else\the\everyPDFxform\fi
+ \immediate\pdfxform resources{#1}#2%
+ \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}%
+ \fi\fi\fi}
+
+\let\getMPPDFobject\relax
+
+%D \macros
+%D {deleteMPgraphic,
+%D startMPresources,
+%D stopMPresources}
+
+\ifx\deleteMPgraphic\undefined
+ \def\deleteMPgraphic#1{}
+\fi
+
+\ifx\startMPresources\undefined
+ \let\startMPresources\relax
+ \let\stopMPresources\relax
+\fi
+
+%D We implement extensions by using the \METAPOST\ special
+%D mechanism. Opposite to \TEX's specials, the \METAPOST\ ones
+%D are flushed before or after the graphic data, but thereby
+%D are no longer connected to a position.
+%D
+%D We implement specials by overloading the \type {fill}
+%D operator. By counting the fills, we can let the converter
+%D treat the appropriate fill in a special way. The
+%D specification of the speciality can have two forms,
+%D determined by the setting of a boolean variable:
+%D
+%D \starttyping
+%D _inline_specials_ := false ; % comment like code (default)
+%D _inline_specials_ := true ; % command like code
+%D \stoptyping
+%D
+%D When the specification is embedded as comment, it looks
+%D like:
+%D
+%D \starttyping
+%D %%MetaPostSpecial <size> <data> <number> <identifier>
+%D \stoptyping
+%D
+%D The in||line alternative is more tuned for \POSTSCRIPT,
+%D since it permits us to define a macro \type {special}.
+%D
+%D \starttyping
+%D inline : <data> <number> <identifier> <size> special
+%D \stoptyping
+%D
+%D The \type {identifier} determines what to do, and the data
+%D can be used to accomplish this. A type~2 shading function
+%D has identifier~2. Alltogether, the number of parameters is
+%D specified in \type {size}. The \type {number} is the number
+%D of the fill that needs the special treatment. For a type~2
+%D and~3 shaded fill, the datablock contains the following
+
+%D data:
+%D
+%D \starttyping
+%D from to n inner_r g b x y outer_r g b x y
+%D from to n inner_r g b x y radius outer_r g b x y radius
+%D \stoptyping
+
+\newconditional\manyMPspecials \settrue\manyMPspecials
+
+%D In case of \PDF, we need to prepare resourcs.
+
+\newtoks\MPstartresources
+\newtoks\MPstopresources
+
+\def\startMPresources
+ {\the\MPstartresources}
+
+\def\stopMPresources
+ {\the\MPstopresources}
+
+%D Some day we may consider collecting local resources.
+
+\appendtoks
+ \global\let\currentPDFresources\empty % kind of redundant
+\to \MPstartresources
+
+% \appendtoks
+% \collectPDFresources
+% \global\let\currentPDFresources\collectedPDFresources
+% \to \MPstopresources
+
+\appendtoksonce
+ \the\everyPDFxform
+\to \MPstopresources
+
+%D Since colors are not subjected to transformations, we can
+%D only use colors as signal. In our case, we use a dummy colored
+%D path with a red color component of \type {0.n}, so \type
+%D {0.001} is the first path and \type {0.010} the tenth. Since
+%D \METAPOST strips trailing zeros, we have to padd the string.
+
+\newif\ifMPcmykcolors
+\newif\ifMPspotcolors
+
+\def\dohandleMPrgb #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od}
+\def\dohandleMPcmyk#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od}
+\def\dohandleMPgray #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od}
+\def\dohandleMPspot#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od}
+
+%D Specials:
+
+\settrue \manyMPspecials \newcount\nofMParguments \let\extraMPpathcode\empty
+
+\def\@@MP {@@MP}
+\def\@@MPSK{@MPSK@}
+
+\def\MPspecial{\@@MPSK\@@MPSK\gMPs\nofMParguments}
+
+\def\defineMPspecial#1#2%
+ {\setvalue{\@@MPSK\@@MPSK#1}{#2}}
+
+%D Special number~1 is dedicated to \CMYK\ support. If you
+%D want to know why: look at this:
+%D
+%D \startbuffer[mp]
+%D fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ;
+%D \stopbuffer
+%D
+%D \startbuffer[cmyk]
+%D \startcombination[4*1]
+%D {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3}
+%D {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15}
+%D {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8}
+%D {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1}
+%D \stopcombination
+%D \stopbuffer
+%D
+%D \placefigure
+%D {\CMYK\ support disabled,
+%D conversion to \RGB.}
+%D {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]}
+%D
+%D \placefigure
+%D {\CMYK\ support enabled,
+%D no support in \METAPOST.}
+%D {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]}
+%D
+%D \placefigure
+%D {\CMYK\ support enabled,
+%D no conversion to \RGB,
+%D support in \METAPOST}
+%D {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]}
+
+\defineMPspecial{1}
+ {\ifMPcmykcolors
+ \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPcmykcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}%
+ \fi}
+
+\defineMPspecial{2}
+ {\ifMPspotcolors
+ \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPspotcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}%
+% \checkMPspot{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}%
+ \fi}
+
+% \def\checkMPspot#1#2#3#4%
+% {\expanded{\resolveMPspotcolor#1 #2 #3 #4}\end
+% \ifx\MPspotspace\MPresolvedspace
+% \edef\MPspotspacespec{/\MPspotspace\space}%
+% \doifinstringelse\MPspotspacespec\currentMPcolorspaces
+% \donothing\registerMPcolorspace
+% \fi}
+
+\let\revokeMPtransparencyspecial\relax
+
+\def\dohandleMPrgbcolor #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od}
+\def\dohandleMPcmykcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od}
+\def\dohandleMPgraycolor #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od}
+\def\dohandleMPspotcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od}
+
+%D Transparency support used specials 60 (rgb) and 61
+%D (cmyk).
+%D
+%D \startbufferFshade
+
+%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
+%D
+%D fill p rotated 90 withcolor transparent(1,.5,yellow) ;
+%D fill p rotated 210 withcolor transparent(1,.5,green) ;
+%D fill p rotated 330 withcolor transparent(1,.5,blue) ;
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection \processMPbuffer \stoplinecorrection
+%D
+%D One can also communicate colors between \CONTEXT\ and
+%D \METAPOST:
+%D
+%D \startbuffer
+%D \definecolor[tcyan] [c=1,k=.2,t=.5]
+%D \definecolor[tmagenta][m=1,k=.2,t=.5]
+%D \definecolor[tyellow] [y=1,k=.2,t=.5]
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
+%D
+%D fill p rotated 90 withcolor \MPcolor{tcyan} ;
+%D fill p rotated 210 withcolor \MPcolor{tmagenta} ;
+%D fill p rotated 330 withcolor \MPcolor{tyellow} ;
+%D \stopbuffer
+%D
+%D \startlinecorrection \processMPbuffer \stoplinecorrection
+%D
+%D We save all the three components needed in one macro,
+%D just to save hash space.
+
+\def\dohandleMPrgbtransparency #1#2#3#4#5{\execcolorR #1:#2:#3:#4:#5\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+\def\dohandleMPcmyktransparency#1#2#3#4#5#6{\execcolorC#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+\def\dohandleMPgraytransparency #1#2#3{\execcolorS #1:#2:#3\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+\def\dohandleMPspottransparency#1#2#3#4#5#6{\execcolorP#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+
+\def\dorevokeMPtransparencyspecial
+ {\PDFcode{\PDFtransparencyresetidentifier\space gs}%
+ \let\revokeMPtransparencyspecial\relax}
+
+\defineMPspecial{3} % rgb
+ {\setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPrgbtransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs1}{\gMPs2}}}
+
+\defineMPspecial{4} % cmyk
+ {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPcmyktransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}}
+
+\defineMPspecial{5} % spot
+ {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPspottransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}%
+ }%\checkMPspot{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}
+
+%D Shading is an example of a more advanced graphic feature,
+%D but users will seldom encounter those complications. Here
+%D we only show a few simple examples, but many other
+%D alternatives are possible by setting up the functions built
+%D in \PDF\ in the appropriate way.
+%D
+%D Shading has to do with interpolation between two or more
+%D points or user supplied ranges. In \PDF, the specifications
+%D of a shade has to be encapsulated in objects and passed on
+%D as resources. This is a \PDF\ level 1.3. feature. One can
+%D simulate three dimensional shades as well and define simple
+%D functions using a limited set of \POSTSCRIPT\ primitives.
+%D Given the power of \METAPOST\ and these \PDF\ features, we
+%D can achieve superb graphic effects.
+%D
+%D Since everything is hidden in \TEX\ and \METAPOST\ graphics,
+%D we can stick to high level \CONTEXT\ command, as shown in
+%D the following exmples.
+%D
+%D \startbuffer
+%D \startuniqueMPgraphic{CircularShade}
+%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+%D circular_shade(p,0,.2red,.9red) ;
+%D \stopuniqueMPgraphic
+%D
+%D \startuniqueMPgraphic{LinearShade}
+%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+%D linear_shade(p,0,.2blue,.9blue) ;
+%D \stopuniqueMPgraphic
+%D
+%D \startuniqueMPgraphic{DuotoneShade}
+%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+%D linear_shade(p,2,.5green,.5red) ;
+%D \stopuniqueMPgraphic
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D These graphics can be hooked into the overlay mechanism,
+%D which is available in many commands.
+%D
+%D \startbuffer
+%D \defineoverlay[demo 1][\uniqueMPgraphic{CircularShade}]
+%D \defineoverlay[demo 2][\uniqueMPgraphic {LinearShade}]
+%D \defineoverlay[demo 3][\uniqueMPgraphic {DuotoneShade}]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D These backgrounds can for instance be applied to \type
+%D {\framed}:
+%D
+%D \startbuffer
+%D \setupframed[width=3cm,height=2cm,frame=off]
+%D \startcombination[3*1]
+%D {\framed[backgroundachtergrond=demo 1]{\bfd \white Demo 1}} {}
+%D {\framed[backgroundachtergrond=demo 2]{\bfd \white Demo 2}} {}
+%D {\framed[backgroundachtergrond=demo 3]{\bfd \white Demo 3}} {}
+%D \stopcombination
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D There are a few more alternatives, determined by the second
+%D parameter passed to \type {circular_shade} and alike.
+%D
+%D \def\SomeShade#1#2#3#4#5%
+%D {\startuniqueMPgraphic{Shade-#1}
+%D width := \overlaywidth ;
+%D height := \overlayheight ;
+%D path p ; p := unitsquare xscaled width yscaled height ;
+%D #2_shade(p,#3,#4,#5) ;
+%D \stopuniqueMPgraphic
+%D \defineoverlay[Shade-#1][\uniqueMPgraphic{Shade-#1}]%
+%D \framed[backgroundachtergrond=Shade-#1,width=2cm,height=2cm,frame=off]{}}
+%D
+%D \startlinecorrection
+%D \startcombination[5*1]
+%D {\SomeShade{10}{circular}{0}{.3blue}{.9blue}} {circular 0}
+%D {\SomeShade{11}{circular}{1}{.3blue}{.9blue}} {circular 1}
+%D {\SomeShade{12}{circular}{2}{.3blue}{.9blue}} {circular 2}
+%D {\SomeShade{13}{circular}{3}{.3blue}{.9blue}} {circular 3}
+%D {\SomeShade{14}{circular}{4}{.3blue}{.9blue}} {circular 4}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D \blank
+%D
+%D \startlinecorrection
+%D \startcombination[5*1]
+%D {\SomeShade{20}{circular}{0}{.9green}{.3green}} {circular 0}
+%D {\SomeShade{21}{circular}{1}{.9green}{.3green}} {circular 1}
+%D {\SomeShade{22}{circular}{2}{.9green}{.3green}} {circular 2}
+%D {\SomeShade{23}{circular}{3}{.9green}{.3green}} {circular 3}
+%D {\SomeShade{24}{circular}{4}{.9green}{.3green}} {circular 4}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D \blank
+%D
+%D \startlinecorrection
+%D \startcombination[4*1]
+%D {\SomeShade{30}{linear}{0}{.3red}{.9red}} {linear 0}
+%D {\SomeShade{31}{linear}{1}{.3red}{.9red}} {linear 1}
+%D {\SomeShade{32}{linear}{2}{.3red}{.9red}} {linear 2}
+%D {\SomeShade{33}{linear}{3}{.3red}{.9red}} {linear 3}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D These macros closely cooperate with the \METAPOST\ module
+%D \type {mp-spec.mp}, which is part of the \CONTEXT\
+%D distribution.
+%D
+%D The low level (\PDF) implementation is based on the \TEX\
+%D based \METAPOST\ to \PDF\ converter. Shading is supported
+%D by overloading the \type {fill} operator as implemented
+%D earlier. In \PDF\ type~2 and~3 shading functions are
+%D specified in terms of:
+%D
+%D \starttabulate[|Tl|l|]
+%D \NC /Domain \NC sort of meeting range \NC \NR
+%D \NC /C0 \NC inner shade \NC \NR
+%D \NC /C1 \NC outer shade \NC \NR
+%D \NC /N \NC smaller values, bigger inner circles \NC \NR
+%D \stoptabulate
+
+\newcount\currentPDFshade % 0 % global (document wide) counter
+
+% \def\dosetMPsomePDFshade#1#2% generic but needs refs
+% {\global\advance\currentPDFshade \plusone
+% \doPDFdictionaryobject{FDF}{ftn:Sh:\the\currentPDFshade}
+% {/FunctionType 2
+% /Domain [\gMPs1 \gMPs2]
+% /C0 [\MPshadeA]
+% /C1 [\MPshadeB]
+% /N \gMPs3}%
+% \doPDFgetobjectreference{FDF}{ftn:Sh:\the\currentPDFshade}\PDFobjectreference
+% \doPDFdictionaryobject{FDF}{obj:Sh:\the\currentPDFshade}
+% {/ShadingType #1
+% /ColorSpace /\MPresolvedspace
+% /Function \PDFobjectreference\space
+% /Coords [\MPshadeC]
+% /Extend [true true]}%
+% \doPDFgetobjectreference{FDF}{obj:Sh:\the\currentPDFshade}\PDFobjectreference
+% \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\PDFobjectreference}%
+% \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}
+
+\def\dosetMPsomePDFshade#1#2%
+ {\immediate\pdfobj
+ {<</FunctionType 2
+ /Domain [\gMPs1 \gMPs2]
+ /C0 [\MPshadeA]
+ /C1 [\MPshadeB]
+ /N \gMPs3>>}%
+ \immediate\pdfobj
+ {<</ShadingType #1
+ /ColorSpace /\MPresolvedspace
+ /Function \the\pdflastobj\space 0 R
+ /Coords [\MPshadeC]
+ /Extend [true true]>>}%
+ \global\advance\currentPDFshade \plusone
+ \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }%
+ \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}
+
+\def\dosetMPlinearshade {\dosetMPsomePDFshade2}% #1
+\def\dosetMPcircularshade{\dosetMPsomePDFshade3}% #1
+
+\defineMPspecial{30}
+ {\expanded{\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
+ \expanded{\resolveMPrgbcolor{\gMPs{9}}{\gMPs{10}}{\gMPs{11}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}}%
+ \dosetMPlinearshade{\gMPs{14}}}
+
+\defineMPspecial{31}
+ {\expanded{\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
+ \expanded{\resolveMPrgbcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}}%
+ \dosetMPcircularshade{\gMPs{16}}}
+
+\defineMPspecial{32}
+ {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \expanded{\resolveMPcmykcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
+ \dosetMPlinearshade{\gMPs{16}}}
+
+\defineMPspecial{33}
+ {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \expanded{\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
+ \dosetMPcircularshade{\gMPs{18}}}
+
+\defineMPspecial{34}
+ {\expanded{\resolveMPspotcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \expanded{\resolveMPspotcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
+ \dosetMPlinearshade{\gMPs{16}}}
+
+\defineMPspecial{35}
+ {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \expanded{\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
+ \dosetMPcircularshade{\gMPs{18}}}
+
+
+\newconditional\ignoreMPpath
+
+\def\dohandleMPshade#1%
+ {\revokeMPtransparencyspecial
+ \settrue\ignoreMPpath
+ \def\extraMPpathcode{/Sh#1 sh Q}%
+ \chardef\finiMPpath\zerocount
+ \PDFcode{q /Pattern cs}}
+
+%D Figure inclusion is kind of strange to \METAPOST, but when
+%D Santiago Muelas started discussing this with me, I was able
+%D to cook up a solution using specials.
+
+\defineMPspecial{10}
+ {\setxvalue{\@@MPSK\gMPs8}%
+ {\noexpand\handleMPfigurespecial{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}{\gMPs8}}}
+
+\def\handleMPfigurespecial#1#2#3#4#5#6#7#8% todo : combine with ext fig
+ {\global\letvalue{\@@MPSK#8}\empty
+ \vbox to \zeropoint
+ {\vss
+ \hbox to \zeropoint
+ {\ifcase\pdfoutput\or % will be hooked into the special driver
+ \doiffileelse{#7}
+ {\doifundefinedelse{mps:x:#7}
+ {\immediate\pdfximage\!!width\onebasepoint\!!height\onebasepoint{#7}%
+ \setxvalue{mps:x:#7}{\pdfrefximage\the\pdflastximage}}%
+ {\message{[reusing figure #7]}}%
+ \PDFcode{q #1 #2 #3 #4 #5 #6 cm}%
+ \rlap{\getvalue{mps:x:#7}}%
+ \PDFcode{Q}}
+ {\message{[unknown figure #7]}}%
+ \fi
+ \hss}}}
+
+%D An example of using both special features is the
+%D following.
+%D
+%D \starttyping
+%D \startMPpage
+%D externalfigure "hakker1b.png" scaled 22cm rotated 10 shifted (-2cm,0cm);
+%D externalfigure "hakker1b.png" scaled 10cm rotated -10 ;
+%D externalfigure "hakker1b.png" scaled 7cm rotated 45 shifted (8cm,12cm) ;
+%D path p ; p := unitcircle xscaled 15cm yscaled 20cm;
+%D path q ; q := p rotatedaround(center p,90) ;
+%D path r ; r := buildcycle(p,q) ; clip currentpicture to r ;
+%D path s ; s := boundingbox currentpicture enlarged 5mm ;
+%D picture c ; c := currentpicture ; currentpicture := nullpicture ;
+%D circular_shade(s,0,.2red,.9red) ;
+%D addto currentpicture also c ;
+%D \stopMPpage
+%D \stoptyping
+
+%D This is some experimental hyperlink driver that I wrote
+%D for Mark Wicks.
+
+\defineMPspecial{20}
+ {\setxvalue{\@@MPSK\gMPs6}%
+ {\noexpand\handleMPhyperlink{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}}
+
+\def\handleMPhyperlink#1#2#3#4#5#6%
+ {\global\letvalue{\@@MPSK#6}\empty
+ \setbox\scratchbox\hbox
+ {\setbox\scratchbox\null
+ \wd\scratchbox\dimexpr-#1\onebasepoint+#3\onebasepoint\relax
+ \ht\scratchbox\dimexpr-#2\onebasepoint+#4\onebasepoint\relax
+ \incolorfalse
+ \gotobox{\box\scratchbox}[#5]}%
+ \setbox\scratchbox\hbox
+ {\hskip\dimexpr\MPxoffset\onebasepoint+#1\onebasepoint\relax
+ \raise\dimexpr\MPyoffset\onebasepoint+#2\onebasepoint\relax
+ \box\scratchbox}%
+ \smashbox\scratchbox
+ \box\scratchbox}
+
+%D This special (number 50) passes positions to a tex file.
+%D This method uses a two||pass approach an (mis|)|used the
+%D context positioning macros. In \type {core-pos} we will
+%D implement the low level submacro needed.
+%D
+%D \startbuffer
+%D \definelayer[test]
+%D
+%D \setlayer
+%D [test]
+%D [x=\MPx{somepos-1},y=\MPy{somepos-1}]
+%D {Whatever we want here!}
+%D
+%D \setlayer
+%D [test]
+%D [x=\MPx{somepos-2},y=\MPy{somepos-2}]
+%D {Whatever we need there!}
+%D
+%D \startuseMPgraphic{oeps}
+%D draw fullcircle scaled 6cm withcolor red ;
+%D register ("somepos-1",1cm,2cm,center currentpicture) ;
+%D register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ;
+%D \stopuseMPgraphic
+%D
+%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Here the width and height are not realy used, but one can
+%D imagine situations where tex has to work with values
+%D calculated by \METAPOST.
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D Later we will implement a more convenient macro:
+%D
+%D \starttyping
+%D \setMPlayer [test] [somepos-1] {Whatever we want here!}
+%D \setMPlayer [test] [somepos-2] {Whatever we need there!}
+%D \stoptyping
+
+\defineMPspecial{50} % x y width height label
+ {\dosavepositionwhd
+ {\gMPs5}%
+ {0}%
+ {\the\dimexpr-\MPllx\onebasepoint+\gMPs1\onebasepoint\relax}
+ {\the\dimexpr\gMPs2\onebasepoint-\scratchdimen+\MPury\onebasepoint\relax}%
+ {\the\dimexpr\gMPs3\onebasepoint\relax}%
+ {\the\dimexpr\gMPs4\onebasepoint\relax}%
+ {0pt}}
+
+%D A few auxiliary macros. This will move to colo-ini.
+
+\def\MPgrayspace{DeviceGray}
+\def\MPrgbspace {DeviceRGB}
+\def\MPcmykspace{DeviceCMYK}
+\let\MPspotspace\MPgrayspace
+
+\def\MPcmykBlack{0 0 0 0}
+\def\MPcmykWhite{0 0 0 1}
+
+\def\startMPcolorresolve
{\bgroup
- \let\finishMPgraphic\egroup
- \doprocessMPtoPDFfile}
+ \def\dostartgraycolormode##1%
+ {\global\let\MPresolvedspace\MPgrayspace
+ \xdef\MPresolvedcolor{##1}}%
+ \def\dostartrgbcolormode ##1##2##3%
+ {\global\let\MPresolvedspace\MPrgbspace
+ \xdef\MPresolvedcolor{##1 ##2 ##3}}%
+ \def\dostartcmykcolormode##1##2##3##4%
+ {\global\let\MPresolvedspace\MPcmykspace
+ \xdef\MPresolvedcolor{##1 ##2 ##3 ##4}}%
+ \def\dostartspotcolormode##1##2%
+ {\global\let\MPspotspace\empty % left over ?
+ \xdef\MPresolvedspace{##1}%
+ \xdef\MPresolvedcolor{##2}%
+ \global\let\MPspotspace\MPresolvedspace}% signal
+ \dostartgraycolormode\!!zerocount} % kind of hackery initialization
+
+\let\stopMPcolorresolve\egroup
+
+\def\resolveMPrgbcolor#1#2#3\to#4%
+ {\startMPcolorresolve
+ \execcolorR#1:#2:#3:0:0\od
+ \stopMPcolorresolve
+ \let#4\MPresolvedcolor}
+
+\def\resolveMPcmykcolor#1#2#3#4\to#5%
+ {\startMPcolorresolve
+ \execcolorC#1:#2:#3:#4:0:0\od
+ \stopMPcolorresolve
+ \let#5\MPresolvedcolor}
+
+\def\resolveMPgraycolor#1\end\to#2%
+ {\startMPcolorresolve
+ \execcolorS#1:0:0\od
+ \stopMPcolorresolve
+ \let#2\MPresolvedcolor}
+
+\def\resolveMPspotcolor#1#2#3#4\end\to#5%
+ {\startMPcolorresolve
+ \ifnum#2>\plusone
+ \checkmultitonecolor{#1}%
+ \fi
+ \execcolorP#1:#2:#3:#4:0:0\od
+ \stopMPcolorresolve
+ \let#5\MPresolvedcolor}
+
+%D \macros
+%D {dogetPDFmediabox}
+%D
+%D The next macro can be used to find the mediabox of a \PDF\
+%D illustration.
+%D
+%D \starttyping
+%D \dogetPDFmediabox
+%D {filename}
+%D {new dimen}{new dimen}{new dimen}{new dimen}
+%D \stoptyping
+%D
+%D Beware of dimen clashes: this macro uses the 5~default
+%D scratch registers! When no file or mediabox is found, the
+%D dimensions are zeroed.
+\def\dogetPDFmediabox#1#2#3#4#5%
+ {\bgroup
+ \def\PDFxscale{1}%
+ \def\PDFyscale{1}%
+ \uncatcodespecials
+ \endlinechar\minusone
+ \def\checkPDFtypepage##1/Type /Page##2##3\done%
+ {\ifx##2\relax
+ \else\if##2s% accept /Page and /Pages
+ \let\doprocessPDFline\findPDFmediabox
+ \else
+ \let\doprocessPDFline\findPDFmediabox
+ \fi\fi}%
+ \def\findPDFtypepage
+ {\expandafter\checkPDFtypepage\fileline/Type /Page\relax\done}%
+ \def\checkPDFmediabox##1/MediaBox##2##3\done%
+ {\ifx##2\relax \else
+ \setPDFmediabox##2##3\done
+ \fileprocessedtrue
+ \fi}%
+ \def\findPDFmediabox
+ {\expandafter\checkPDFmediabox\fileline/MediaBox\relax\done}%
+ \let\doprocessPDFline\findPDFtypepage
+ \doprocessfile\scratchread{#1}\doprocessPDFline
+ \egroup
+ \ifx\PDFxoffset\undefined
+ #2=\zeropoint
+ #3=\zeropoint
+ #4=\zeropoint
+ #5=\zeropoint
+ \else
+ #2=\PDFxoffset\onebasepoint
+ #3=\PDFyoffset\onebasepoint
+ #4=\PDFwidth
+ #5=\PDFheight
+ \fi}
+
+\def\setPDFboundingbox#1#2#3#4#5#6%
+ {\dimen0=#1\dimen0=#5\dimen0
+ \ScaledPointsToBigPoints{\number\dimen0}\PDFxoffset
+ \dimen0=#3\dimen0=#5\dimen0
+ \xdef\PDFwidth{\the\dimen0}%
+ \dimen0=#2\dimen0=#6\dimen0
+ \ScaledPointsToBigPoints{\number\dimen0}\PDFyoffset
+ \dimen0=#4\dimen0=#6\dimen0
+ \xdef\PDFheight{\the\dimen0}%
+ \global\let\PDFxoffset\PDFxoffset
+ \global\let\PDFyoffset\PDFyoffset}
+
+\def\setPDFmediabox#1[#2 #3 #4 #5]#6\done
+ {\dimen2=#2\onebasepoint\dimen2=-\dimen2 % \dimen2=-#2\onebasepoint also works since tex handles --
+ \dimen4=#3\onebasepoint\dimen4=-\dimen4 % \dimen4=-#3\onebasepoint also works since tex handles --
+ \dimen6=#4\onebasepoint\advance\dimen6 \dimen2
+ \dimen8=#5\onebasepoint\advance\dimen8 \dimen4
+ \setPDFboundingbox{\dimen2}{\dimen4}{\dimen6}{\dimen8}\PDFxscale\PDFyscale}
+
+%D End of soon obsolete code.
+
+\startMPinitializations
+ mp_shade_version := 2 ;
+\stopMPinitializations
+
+%D Here comes the traditional \MKII\ converter.
+%D
%D Because we want to test as fast as possible, we first
%D define the \POSTSCRIPT\ operators that \METAPOST\ uses.
%D We don't define irrelevant ones, because these are
%D skipped anyway.
-
+%D
%D The converter can be made a bit faster by replacing the
%D two test macros (the ones with the many \type {\if's}) by
%D a call to named branch macros (something \typ {\getvalue
@@ -1215,9 +2128,6 @@
%D
%D But, this one is still too inaccurate, so we now have:
-%D We cannot use \type {\beginETEX} here since in plain we
-%D get \type {\outer} problems, sigh.
-
%D DHL: Ideally, $r_x$, $r_y$, $s_x$, $s_y$ should be in macros, not
%D dimensions (they are scalar quantities after all, not lengths). I
%D suppose the authors decided to do calculations with integer
@@ -1726,7 +2636,7 @@
{\ifcase\inlineMPspecials\or
\advance\nofMParguments \minusone % pop the size
\fi
- \ifundefined\MPspecial
+ \ifundefined\MPspecial % beware, no real \if
\message{[unknown \MPspecial]}%
\else
\csname\MPspecial\endcsname
diff --git a/tex/context/base/meta-pdf.mkiv b/tex/context/base/meta-pdf.mkiv
index eded7d59d..23981815c 100644
--- a/tex/context/base/meta-pdf.mkiv
+++ b/tex/context/base/meta-pdf.mkiv
@@ -1,8 +1,8 @@
%D \module
%D [ file=meta-pdf,
-%D version=2006.29.09,
-%D title=\CONTEXT\ Support Macros,
-%D subtitle=\METAPOST\ to \PDF\ conversion,
+%D version=2006.06.07,
+%D title=\METAPOST\ Graphics,
+%D subtitle=Conversion to \PDF,
%D author=Hans Hagen \& others (see text),
%D date=\currentdate,
%D copyright=\PRAGMA]
@@ -11,10 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
+%D Formerly known as supp-pdf.tex and supp-mpe.tex.
-% Using test case at end of meta-pdf.tex:
-%
% \useMPgraphic{1}
% \testfeatureonce{250}{\setbox0\hbox{\convertMPtoPDF{test-mps-mpgraph.1}{1}{1}}}
%
@@ -26,10 +24,86 @@
\registerctxluafile{meta-pdf}{1.003}
-%D Plugin.
+%D We will clean up the color mess later.
+
+\writestatus{loading}{MetaPost Graphics / MPS to PDF}
+
+\unprotect
+
+\ifx\PDFcode \undefined \let\PDFcode \gobbleoneargument \fi
+\ifx\PDFcomment\undefined \def\PDFcomment#1{\PDFcode{\letterpercent\space#1}} \fi
+
+%D First we define a handy constant:
+
+\bgroup \catcode`\%=\@@other \xdef\letterpercent{\string%} \egroup
+
+%D \macros
+%D {convertMPtoPDF}
+%D
+%D The next set of macros implements \METAPOST\ to \PDF\
+%D conversion. The traditional method is in the MkII file.
+%D
+%D The main conversion command is:
+%D
+%D \starttyping
+%D \convertMPtoPDF {filename} {x scale} {y scale}
+%D \stoptyping
+%D
+%D The dimensions are derived from the bounding box. So we
+%D only have to say:
+%D
+%D \starttyping
+%D \convertMPtoPDF{mp-pra-1.eps}{1}{1}
+%D \convertMPtoPDF{mp-pra-1.eps}{.5}{.5}
+%D \stoptyping
+
+%D \macros
+%D {makeMPintoPDFobject,lastPDFMPobject}
+%D
+%D For experts there are a few more options. When attributes
+%D are to be added, the code must be embedded in an object
+%D accompanied with the appropriate directives. One can
+%D influence this process with \type {\makeMPintoPDFobject}.
+%D
+%D This option defaults to~0, because \CONTEXT\ takes care
+%D of objects at another level, which saves some bytes.
+%D
+%D \starttabulate[|l|l|p|]
+%D \NC 0 \NC never \NC don't use an object \NC\NR
+%D \NC 1 \NC always \NC always use an object \NC\NR
+%D \NC 2 \NC optional \NC use object when needed \NC\NR
+%D \stoptabulate
+%D
+%D The last object number used is avaliable in the macro
+%D \type {\lastPDFMPobject}.
+
+\ifx\makeMPintoPDFobject \undefined \chardef\makeMPintoPDFobject \zerocount \fi
+\ifx\blackoutMPgraphic \undefined \chardef\blackoutMPgraphic \plusone \fi
+\ifx\everyMPtoPDFconversion\undefined \newtoks\everyMPtoPDFconversion \fi
+
+\let\lastPDFMPobject \!!zerocount
+\let\currentPDFresources\empty
+\let\setMPextensions \relax
+
+\def\PDFMPformoffset
+ {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi}
-\def\mkconvertMPtoPDF % watch the transparency reset
- {\vbox\bgroup
+\def\resetMPvariables#1#2#3%
+ {\global\let\MPwidth \!!zeropoint
+ \global\let\MPheight\!!zeropoint
+ \global\let\MPllx \!!zerocount
+ \global\let\MPlly \!!zerocount
+ \global\let\MPurx \!!zerocount
+ \global\let\MPury \!!zerocount
+ \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi
+ \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi
+ \xdef\MPfilename {#1}}
+
+%D The main macro:
+
+\def\convertMPtoPDF#1#2#3% watch the transparency reset
+ {\resetMPvariables{#1}{#2}{#3}%
+ \vbox\bgroup
\forgetall
\offinterlineskip
%\ifcase\blackoutMPgraphic\or\PDFcode{0 g 0 G}\fi % fixed in mp
@@ -61,19 +135,657 @@
\dopackageMPgraphic\scratchbox
\egroup}
-\let\mkprocessMPtoPDFfile\mkconvertMPtoPDF
+\let\processMPtoPDFfile\convertMPtoPDF
+
+%D A common hook.
+
+\let\MPfshowcommand\empty
+
+%D Objects.
+
+\def\dopackageMPgraphic#1% #1 = boxregister
+ {\ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else
+ % an existing value of 2 signals object support (set elsewhere)
+ \chardef\makeMPintoPDFobject\plusone
+ \fi\fi
+ \ifcase\makeMPintoPDFobject
+ \box#1%
+ \or
+ \scratchdimen\PDFMPformoffset\relax
+ \ifdim\scratchdimen>\zeropoint % compensate for error
+ \setbox#1\vbox spread 2\scratchdimen
+ {\forgetall\vss\hbox spread 2\scratchdimen{\hss\box#1\hss}\vss}%
+ \fi
+ \setMPPDFobject{\currentPDFresources}{#1}%
+ \ifdim\scratchdimen>\zeropoint % compensate for error
+ \vbox to \MPheight
+ {\forgetall\vss\hbox to \MPwidth{\hss\getMPPDFobject\hss}\vss}%
+ \else
+ \getMPPDFobject
+ \fi
+ \global\let\currentPDFresources\empty
+ \else
+ \box#1%
+ \fi}
+
+\def\setMPPDFobject#1#2% resources boxnumber
+ {\ifx\pdfxform\undefined
+ \def\getMPPDFobject{\box#2}%
+ \else\ifx\pdftexversion\undefined
+ \def\getMPPDFobject{\box#2}%
+ \else\ifnum\pdftexversion<14
+ \def\getMPPDFobject{\box#2}%
+ \else
+ \ifx\everyPDFxform\undefined\else\the\everyPDFxform\fi
+ \immediate\pdfxform resources{#1}#2%
+ \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}%
+ \fi\fi\fi}
+
+\let\getMPPDFobject\relax
+
+%D \macros
+%D {deleteMPgraphic,
+%D startMPresources,
+%D stopMPresources}
+
+\ifx\deleteMPgraphic\undefined
+ \def\deleteMPgraphic#1{}
+\fi
+
+\ifx\startMPresources\undefined
+ \let\startMPresources\relax
+ \let\stopMPresources\relax
+\fi
+
+%D We implement extensions by using the \METAPOST\ special
+%D mechanism. Opposite to \TEX's specials, the \METAPOST\ ones
+%D are flushed before or after the graphic data, but thereby
+%D are no longer connected to a position.
+%D
+%D We implement specials by overloading the \type {fill}
+%D operator. By counting the fills, we can let the converter
+%D treat the appropriate fill in a special way. The
+%D specification of the speciality can have two forms,
+%D determined by the setting of a boolean variable:
+%D
+%D \starttyping
+%D _inline_specials_ := false ; % comment like code (default)
+%D _inline_specials_ := true ; % command like code
+%D \stoptyping
+%D
+%D When the specification is embedded as comment, it looks
+%D like:
+%D
+%D \starttyping
+%D %%MetaPostSpecial <size> <data> <number> <identifier>
+%D \stoptyping
+%D
+%D The in||line alternative is more tuned for \POSTSCRIPT,
+%D since it permits us to define a macro \type {special}.
+%D
+%D \starttyping
+%D inline : <data> <number> <identifier> <size> special
+%D \stoptyping
+%D
+%D The \type {identifier} determines what to do, and the data
+%D can be used to accomplish this. A type~2 shading function
+%D has identifier~2. Alltogether, the number of parameters is
+%D specified in \type {size}. The \type {number} is the number
+%D of the fill that needs the special treatment. For a type~2
+%D and~3 shaded fill, the datablock contains the following
+
+%D data:
+%D
+%D \starttyping
+%D from to n inner_r g b x y outer_r g b x y
+%D from to n inner_r g b x y radius outer_r g b x y radius
+%D \stoptyping
+
+\newconditional\manyMPspecials \settrue\manyMPspecials
+
+%D In case of \PDF, we need to prepare resourcs.
+
+\newtoks\MPstartresources
+\newtoks\MPstopresources
+
+\def\startMPresources
+ {\the\MPstartresources}
+
+\def\stopMPresources
+ {\the\MPstopresources}
+
+%D Some day we may consider collecting local resources.
+
+\appendtoks
+ \global\let\currentPDFresources\empty % kind of redundant
+\to \MPstartresources
+
+% \appendtoks
+% \collectPDFresources
+% \global\let\currentPDFresources\collectedPDFresources
+% \to \MPstopresources
+
+\appendtoksonce
+ \the\everyPDFxform
+\to \MPstopresources
+
+%D Since colors are not subjected to transformations, we can
+%D only use colors as signal. In our case, we use a dummy colored
+%D path with a red color component of \type {0.n}, so \type
+%D {0.001} is the first path and \type {0.010} the tenth. Since
+%D \METAPOST strips trailing zeros, we have to padd the string.
+
+\newif\ifMPcmykcolors
+\newif\ifMPspotcolors
+
+\def\dohandleMPrgb #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od}
+\def\dohandleMPcmyk#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od}
+\def\dohandleMPgray #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od}
+\def\dohandleMPspot#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od}
+
+%D Specials:
+
+\settrue \manyMPspecials \newcount\nofMParguments \let\extraMPpathcode\empty
+
+\def\@@MP {@@MP}
+\def\@@MPSK{@MPSK@}
+
+\def\MPspecial{\@@MPSK\@@MPSK\gMPs\nofMParguments}
+
+\def\defineMPspecial#1#2%
+ {\setvalue{\@@MPSK\@@MPSK#1}{#2}}
+
+%D Special number~1 is dedicated to \CMYK\ support. If you
+%D want to know why: look at this:
+%D
+%D \startbuffer[mp]
+%D fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ;
+%D \stopbuffer
+%D
+%D \startbuffer[cmyk]
+%D \startcombination[4*1]
+%D {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3}
+%D {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15}
+%D {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8}
+%D {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1}
+%D \stopcombination
+%D \stopbuffer
+%D
+%D \placefigure
+%D {\CMYK\ support disabled,
+%D conversion to \RGB.}
+%D {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]}
+%D
+%D \placefigure
+%D {\CMYK\ support enabled,
+%D no support in \METAPOST.}
+%D {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]}
+%D
+%D \placefigure
+%D {\CMYK\ support enabled,
+%D no conversion to \RGB,
+%D support in \METAPOST}
+%D {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]}
+
+\defineMPspecial{1}
+ {\ifMPcmykcolors
+ \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPcmykcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}%
+ \fi}
+
+\defineMPspecial{2}
+ {\ifMPspotcolors
+ \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPspotcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}%
+% \checkMPspot{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}%
+ \fi}
+
+% \def\checkMPspot#1#2#3#4%
+% {\normalexpanded{\noexpand\resolveMPspotcolor#1 #2 #3 #4}\end
+% \ifx\MPspotspace\MPresolvedspace
+% \edef\MPspotspacespec{/\MPspotspace\space}%
+% \doifinstringelse\MPspotspacespec\currentMPcolorspaces
+% \donothing\registerMPcolorspace
+% \fi}
+
+\let\revokeMPtransparencyspecial\relax
+
+\def\dohandleMPrgbcolor #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od}
+\def\dohandleMPcmykcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od}
+\def\dohandleMPgraycolor #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od}
+\def\dohandleMPspotcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od}
+
+%D Transparency support used specials 60 (rgb) and 61
+%D (cmyk).
+%D
+%D \startbufferFshade
+
+%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
+%D
+%D fill p rotated 90 withcolor transparent(1,.5,yellow) ;
+%D fill p rotated 210 withcolor transparent(1,.5,green) ;
+%D fill p rotated 330 withcolor transparent(1,.5,blue) ;
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection \processMPbuffer \stoplinecorrection
+%D
+%D One can also communicate colors between \CONTEXT\ and
+%D \METAPOST:
+%D
+%D \startbuffer
+%D \definecolor[tcyan] [c=1,k=.2,t=.5]
+%D \definecolor[tmagenta][m=1,k=.2,t=.5]
+%D \definecolor[tyellow] [y=1,k=.2,t=.5]
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
+%D
+%D fill p rotated 90 withcolor \MPcolor{tcyan} ;
+%D fill p rotated 210 withcolor \MPcolor{tmagenta} ;
+%D fill p rotated 330 withcolor \MPcolor{tyellow} ;
+%D \stopbuffer
+%D
+%D \startlinecorrection \processMPbuffer \stoplinecorrection
+%D
+%D We save all the three components needed in one macro,
+%D just to save hash space.
+
+\def\dohandleMPrgbtransparency #1#2#3#4#5{\execcolorR #1:#2:#3:#4:#5\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+\def\dohandleMPcmyktransparency#1#2#3#4#5#6{\execcolorC#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+\def\dohandleMPgraytransparency #1#2#3{\execcolorS #1:#2:#3\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+\def\dohandleMPspottransparency#1#2#3#4#5#6{\execcolorP#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
+
+\def\dorevokeMPtransparencyspecial
+ {\PDFcode{\PDFtransparencyresetidentifier\space gs}%
+ \let\revokeMPtransparencyspecial\relax}
+
+\defineMPspecial{3} % rgb
+ {\setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPrgbtransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs1}{\gMPs2}}}
+
+\defineMPspecial{4} % cmyk
+ {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPcmyktransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}}
+
+\defineMPspecial{5} % spot
+ {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPspottransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}%
+ }%\checkMPspot{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}
+
+%D Shading is an example of a more advanced graphic feature,
+%D but users will seldom encounter those complications. Here
+%D we only show a few simple examples, but many other
+%D alternatives are possible by setting up the functions built
+%D in \PDF\ in the appropriate way.
+%D
+%D Shading has to do with interpolation between two or more
+%D points or user supplied ranges. In \PDF, the specifications
+%D of a shade has to be encapsulated in objects and passed on
+%D as resources. This is a \PDF\ level 1.3. feature. One can
+%D simulate three dimensional shades as well and define simple
+%D functions using a limited set of \POSTSCRIPT\ primitives.
+%D Given the power of \METAPOST\ and these \PDF\ features, we
+%D can achieve superb graphic effects.
+%D
+%D Since everything is hidden in \TEX\ and \METAPOST\ graphics,
+%D we can stick to high level \CONTEXT\ command, as shown in
+%D the following exmples.
+%D
+%D \startbuffer
+%D \startuniqueMPgraphic{CircularShade}
+%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+%D circular_shade(p,0,.2red,.9red) ;
+%D \stopuniqueMPgraphic
+%D
+%D \startuniqueMPgraphic{LinearShade}
+%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+%D linear_shade(p,0,.2blue,.9blue) ;
+%D \stopuniqueMPgraphic
+%D
+%D \startuniqueMPgraphic{DuotoneShade}
+%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+%D linear_shade(p,2,.5green,.5red) ;
+%D \stopuniqueMPgraphic
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D These graphics can be hooked into the overlay mechanism,
+%D which is available in many commands.
+%D
+%D \startbuffer
+%D \defineoverlay[demo 1][\uniqueMPgraphic{CircularShade}]
+%D \defineoverlay[demo 2][\uniqueMPgraphic {LinearShade}]
+%D \defineoverlay[demo 3][\uniqueMPgraphic {DuotoneShade}]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D These backgrounds can for instance be applied to \type
+%D {\framed}:
+%D
+%D \startbuffer
+%D \setupframed[width=3cm,height=2cm,frame=off]
+%D \startcombination[3*1]
+%D {\framed[backgroundachtergrond=demo 1]{\bfd \white Demo 1}} {}
+%D {\framed[backgroundachtergrond=demo 2]{\bfd \white Demo 2}} {}
+%D {\framed[backgroundachtergrond=demo 3]{\bfd \white Demo 3}} {}
+%D \stopcombination
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D There are a few more alternatives, determined by the second
+%D parameter passed to \type {circular_shade} and alike.
+%D
+%D \def\SomeShade#1#2#3#4#5%
+%D {\startuniqueMPgraphic{Shade-#1}
+%D width := \overlaywidth ;
+%D height := \overlayheight ;
+%D path p ; p := unitsquare xscaled width yscaled height ;
+%D #2_shade(p,#3,#4,#5) ;
+%D \stopuniqueMPgraphic
+%D \defineoverlay[Shade-#1][\uniqueMPgraphic{Shade-#1}]%
+%D \framed[backgroundachtergrond=Shade-#1,width=2cm,height=2cm,frame=off]{}}
+%D
+%D \startlinecorrection
+%D \startcombination[5*1]
+%D {\SomeShade{10}{circular}{0}{.3blue}{.9blue}} {circular 0}
+%D {\SomeShade{11}{circular}{1}{.3blue}{.9blue}} {circular 1}
+%D {\SomeShade{12}{circular}{2}{.3blue}{.9blue}} {circular 2}
+%D {\SomeShade{13}{circular}{3}{.3blue}{.9blue}} {circular 3}
+%D {\SomeShade{14}{circular}{4}{.3blue}{.9blue}} {circular 4}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D \blank
+%D
+%D \startlinecorrection
+%D \startcombination[5*1]
+%D {\SomeShade{20}{circular}{0}{.9green}{.3green}} {circular 0}
+%D {\SomeShade{21}{circular}{1}{.9green}{.3green}} {circular 1}
+%D {\SomeShade{22}{circular}{2}{.9green}{.3green}} {circular 2}
+%D {\SomeShade{23}{circular}{3}{.9green}{.3green}} {circular 3}
+%D {\SomeShade{24}{circular}{4}{.9green}{.3green}} {circular 4}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D \blank
+%D
+%D \startlinecorrection
+%D \startcombination[4*1]
+%D {\SomeShade{30}{linear}{0}{.3red}{.9red}} {linear 0}
+%D {\SomeShade{31}{linear}{1}{.3red}{.9red}} {linear 1}
+%D {\SomeShade{32}{linear}{2}{.3red}{.9red}} {linear 2}
+%D {\SomeShade{33}{linear}{3}{.3red}{.9red}} {linear 3}
+%D \stopcombination
+%D \stoplinecorrection
+%D
+%D These macros closely cooperate with the \METAPOST\ module
+%D \type {mp-spec.mp}, which is part of the \CONTEXT\
+%D distribution.
+%D
+%D The low level (\PDF) implementation is based on the \TEX\
+%D based \METAPOST\ to \PDF\ converter. Shading is supported
+%D by overloading the \type {fill} operator as implemented
+%D earlier. In \PDF\ type~2 and~3 shading functions are
+%D specified in terms of:
+%D
+%D \starttabulate[|Tl|l|]
+%D \NC /Domain \NC sort of meeting range \NC \NR
+%D \NC /C0 \NC inner shade \NC \NR
+%D \NC /C1 \NC outer shade \NC \NR
+%D \NC /N \NC smaller values, bigger inner circles \NC \NR
+%D \stoptabulate
+
+\newcount\currentPDFshade % 0 % global (document wide) counter
+
+\def\dosetMPsomePDFshade#1#2%
+ {\immediate\pdfobj
+ {<</FunctionType 2
+ /Domain [\gMPs1 \gMPs2]
+ /C0 [\MPshadeA]
+ /C1 [\MPshadeB]
+ /N \gMPs3>>}%
+ \immediate\pdfobj
+ {<</ShadingType #1
+ /ColorSpace /\MPresolvedspace
+ /Function \the\pdflastobj\space 0 R
+ /Coords [\MPshadeC]
+ /Extend [true true]>>}%
+ \global\advance\currentPDFshade \plusone
+ \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }%
+ \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}
+
+\def\dosetMPlinearshade {\dosetMPsomePDFshade2}% #1
+\def\dosetMPcircularshade{\dosetMPsomePDFshade3}% #1
+
+\defineMPspecial{30}
+ {\normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
+ \normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs{9}}{\gMPs{10}}{\gMPs{11}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}}%
+ \dosetMPlinearshade{\gMPs{14}}}
+
+\defineMPspecial{31}
+ {\normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
+ \normalexpanded{\noexpand\resolveMPrgbcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}}%
+ \dosetMPcircularshade{\gMPs{16}}}
+
+\defineMPspecial{32}
+ {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
+ \dosetMPlinearshade{\gMPs{16}}}
+
+\defineMPspecial{33}
+ {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
+ \dosetMPcircularshade{\gMPs{18}}}
+
+\defineMPspecial{34}
+ {\normalexpanded{\noexpand\resolveMPspotcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \normalexpanded{\noexpand\resolveMPspotcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
+ \dosetMPlinearshade{\gMPs{16}}}
+
+\defineMPspecial{35}
+ {\normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
+ \normalexpanded{\noexpand\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
+ \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
+ \dosetMPcircularshade{\gMPs{18}}}
+
+\newconditional\ignoreMPpath
+
+\def\dohandleMPshade#1%
+ {\revokeMPtransparencyspecial
+ \settrue\ignoreMPpath
+ \def\extraMPpathcode{/Sh#1 sh Q}%
+ \chardef\finiMPpath\zerocount
+ \PDFcode{q /Pattern cs}}
+
+\defineMPspecial{10}
+ {\setxvalue{\@@MPSK\gMPs8}%
+ {\noexpand\handleMPfigurespecial{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}{\gMPs8}}}
+
+\def\handleMPfigurespecial#1#2#3#4#5#6#7#8% todo : combine with ext fig
+ {\global\letvalue{\@@MPSK#8}\empty
+ \vbox to \zeropoint
+ {\vss
+ \hbox to \zeropoint
+ {\ifcase\pdfoutput\or % will be hooked into the special driver
+ \doiffileelse{#7}
+ {\doifundefinedelse{mps:x:#7}
+ {\immediate\pdfximage\!!width\onebasepoint\!!height\onebasepoint{#7}%
+ \setxvalue{mps:x:#7}{\pdfrefximage\the\pdflastximage}}%
+ {\message{[reusing figure #7]}}%
+ \PDFcode{q #1 #2 #3 #4 #5 #6 cm}%
+ \rlap{\getvalue{mps:x:#7}}%
+ \PDFcode{Q}}
+ {\message{[unknown figure #7]}}%
+ \fi
+ \hss}}}
+
+%D An example of using both special features is the
+%D following.
+%D
+%D \starttyping
+%D \startMPpage
+%D externalfigure "hakker1b.png" scaled 22cm rotated 10 shifted (-2cm,0cm);
+%D externalfigure "hakker1b.png" scaled 10cm rotated -10 ;
+%D externalfigure "hakker1b.png" scaled 7cm rotated 45 shifted (8cm,12cm) ;
+%D path p ; p := unitcircle xscaled 15cm yscaled 20cm;
+%D path q ; q := p rotatedaround(center p,90) ;
+%D path r ; r := buildcycle(p,q) ; clip currentpicture to r ;
+%D path s ; s := boundingbox currentpicture enlarged 5mm ;
+%D picture c ; c := currentpicture ; currentpicture := nullpicture ;
+%D circular_shade(s,0,.2red,.9red) ;
+%D addto currentpicture also c ;
+%D \stopMPpage
+%D \stoptyping
-% \def\TEXcode#1#2#3#4#5%
-% {\setbox\scratchbox\hbox
-% {\font\temp=#1\space at #2\onebasepoint
-% \temp
-% \MPfshowcommand{#3}}%
-% \setbox\scratchbox\hbox
-% {\hskip#4\onebasepoint
-% \raise#5\onebasepoint
-% \box\scratchbox}%
-% \smashbox\scratchbox
-% \box\scratchbox}
+\defineMPspecial{20}
+ {\setxvalue{\@@MPSK\gMPs6}%
+ {\noexpand\handleMPhyperlink{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}}
+
+\def\handleMPhyperlink#1#2#3#4#5#6%
+ {\global\letvalue{\@@MPSK#6}\empty
+ \setbox\scratchbox\hbox
+ {\setbox\scratchbox\null
+ \wd\scratchbox\dimexpr-#1\onebasepoint+#3\onebasepoint\relax
+ \ht\scratchbox\dimexpr-#2\onebasepoint+#4\onebasepoint\relax
+ \incolorfalse
+ \gotobox{\box\scratchbox}[#5]}%
+ \setbox\scratchbox\hbox
+ {\hskip\dimexpr\MPxoffset\onebasepoint+#1\onebasepoint\relax
+ \raise\dimexpr\MPyoffset\onebasepoint+#2\onebasepoint\relax
+ \box\scratchbox}%
+ \smashbox\scratchbox
+ \box\scratchbox}
+
+%D This special (number 50) passes positions to a tex file.
+%D This method uses a two||pass approach an (mis|)|used the
+%D context positioning macros. In \type {core-pos} we will
+%D implement the low level submacro needed.
+%D
+%D \startbuffer
+%D \definelayer[test]
+%D
+%D \setlayer
+%D [test]
+%D [x=\MPx{somepos-1},y=\MPy{somepos-1}]
+%D {Whatever we want here!}
+%D
+%D \setlayer
+%D [test]
+%D [x=\MPx{somepos-2},y=\MPy{somepos-2}]
+%D {Whatever we need there!}
+%D
+%D \startuseMPgraphic{oeps}
+%D draw fullcircle scaled 6cm withcolor red ;
+%D register ("somepos-1",1cm,2cm,center currentpicture) ;
+%D register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ;
+%D \stopuseMPgraphic
+%D
+%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Here the width and height are not realy used, but one can
+%D imagine situations where tex has to work with values
+%D calculated by \METAPOST.
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+%D
+%D Later we will implement a more convenient macro:
+%D
+%D \starttyping
+%D \setMPlayer [test] [somepos-1] {Whatever we want here!}
+%D \setMPlayer [test] [somepos-2] {Whatever we need there!}
+%D \stoptyping
+
+\defineMPspecial{50} % x y width height label
+ {\dosavepositionwhd
+ {\gMPs5}%
+ {0}%
+ {\the\dimexpr-\MPllx\onebasepoint+\gMPs1\onebasepoint\relax}
+ {\the\dimexpr\gMPs2\onebasepoint-\scratchdimen+\MPury\onebasepoint\relax}%
+ {\the\dimexpr\gMPs3\onebasepoint\relax}%
+ {\the\dimexpr\gMPs4\onebasepoint\relax}%
+ {0pt}}
+
+%D A few auxiliary macros. This will move to colo-ini.
+
+\def\MPgrayspace{DeviceGray}
+\def\MPrgbspace {DeviceRGB}
+\def\MPcmykspace{DeviceCMYK}
+\let\MPspotspace\MPgrayspace
+
+\def\MPcmykBlack{0 0 0 0}
+\def\MPcmykWhite{0 0 0 1}
+
+\def\startMPcolorresolve
+ {\bgroup
+ \def\dostartgraycolormode##1%
+ {\global\let\MPresolvedspace\MPgrayspace
+ \xdef\MPresolvedcolor{##1}}%
+ \def\dostartrgbcolormode ##1##2##3%
+ {\global\let\MPresolvedspace\MPrgbspace
+ \xdef\MPresolvedcolor{##1 ##2 ##3}}%
+ \def\dostartcmykcolormode##1##2##3##4%
+ {\global\let\MPresolvedspace\MPcmykspace
+ \xdef\MPresolvedcolor{##1 ##2 ##3 ##4}}%
+ \def\dostartspotcolormode##1##2%
+ {\global\let\MPspotspace\empty % left over ?
+ \xdef\MPresolvedspace{##1}%
+ \xdef\MPresolvedcolor{##2}%
+ \global\let\MPspotspace\MPresolvedspace}% signal
+ \dostartgraycolormode\!!zerocount} % kind of hackery initialization
+
+\let\stopMPcolorresolve\egroup
+
+\def\resolveMPrgbcolor#1#2#3\to#4%
+ {\startMPcolorresolve
+ \execcolorR#1:#2:#3:0:0\od
+ \stopMPcolorresolve
+ \let#4\MPresolvedcolor}
+
+\def\resolveMPcmykcolor#1#2#3#4\to#5%
+ {\startMPcolorresolve
+ \execcolorC#1:#2:#3:#4:0:0\od
+ \stopMPcolorresolve
+ \let#5\MPresolvedcolor}
+
+\def\resolveMPgraycolor#1\end\to#2%
+ {\startMPcolorresolve
+ \execcolorS#1:0:0\od
+ \stopMPcolorresolve
+ \let#2\MPresolvedcolor}
+
+\def\resolveMPspotcolor#1#2#3#4\end\to#5%
+ {\startMPcolorresolve
+ \ifnum#2>\plusone
+ \checkmultitonecolor{#1}%
+ \fi
+ \execcolorP#1:#2:#3:#4:0:0\od
+ \stopMPcolorresolve
+ \let#5\MPresolvedcolor}
+
+\startMPinitializations
+ mp_shade_version := 2 ;
+\stopMPinitializations
% will be done better
@@ -152,4 +864,83 @@
\let\MPSgray\dohandleMPgray
\let\MPSspot\dohandleMPspot
+%D Test code:
+
+% \startMPcode
+% fill fullcircle scaled 3cm withcolor red ;
+% fill fullcircle scaled 2cm withcolor green ;
+% fill fullcircle scaled 1cm withcolor blue ;
+% currentpicture := currentpicture shifted (-4cm,0) ;
+% fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ;
+% fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ;
+% fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ;
+% currentpicture := currentpicture shifted (-4cm,0) ;
+% draw fullcircle scaled 3cm dashed evenly ;
+% draw fullcircle scaled 2cm dashed withdots ;
+% draw origin withpen pencircle scaled 3mm;
+% currentpicture := currentpicture shifted (-4cm,0) ;
+% fill fullcircle scaled 2cm shifted (-.5cm,+.5cm) withcolor transparent(1,.5,red);
+% fill fullcircle scaled 2cm shifted (-.5cm,-.5cm) withcolor transparent(1,.5,red);
+% fill fullcircle scaled 2cm shifted (+.5cm,+.5cm) withcolor transparent(1,.5,green);
+% fill fullcircle scaled 2cm shifted (+.5cm,-.5cm) withcolor transparent(1,.5,cmyk(1,0,1,.5));
+% currentpicture := currentpicture shifted (12cm,-4cm) ;
+% draw "o e p s" infont defaultfont scaled 2 shifted (-1cm,0) ;
+% currentpicture := currentpicture shifted (-4cm,0) ;
+% % bug: shift
+% draw fullcircle scaled 3cm withpen pencircle yscaled 3mm xscaled 2mm rotated 30 ;
+% draw fullcircle scaled 2cm withpen pencircle yscaled 3mm xscaled 2mm rotated 20 withcolor red ;
+% filldraw fullcircle scaled 1cm withpen pencircle yscaled 3mm xscaled 2mm rotated 10 withcolor green ;
+% currentpicture := currentpicture shifted (-4cm,0) ;
+% % shade cannot handle shift
+% circular_shade(fullcircle scaled 3cm,0,.2red,.9green) ;
+% circular_shade(fullcircle scaled 3cm shifted(+4cm,0),0,cmyk(1,0,0,0),cmyk(0,1,0,0)) ;
+% filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ;
+% \stopMPcode
+
+% We cannot use attributes for switching colors in mp literals because
+% grouping (qQ) interferes.
+
+\ifx\colorversion\undefined \else \ifnum\colorversion>\plusone
+
+ \def\dohandleMPgraycolor #1{\ctxlua{ctx.pdffinishtransparency()
+ ctx.pdfgrayliteral(\the\currentcolormodel,#1)}}
+ \def\dohandleMPrgbcolor #1#2#3{\ctxlua{ctx.pdffinishtransparency()
+ ctx.pdfrgbliteral (\the\currentcolormodel,#1,#2,#3)}}
+ \def\dohandleMPcmykcolor#1#2#3#4{\ctxlua{ctx.pdffinishtransparency()
+ ctx.pdfcmykliteral(\the\currentcolormodel,#1,#2,#3,#4)}}
+ \def\dohandleMPspotcolor#1#2#3#4{\ctxlua{ctx.pdffinishtransparency()
+ ctx.pdfspotliteral(\the\currentcolormodel,"#1",#2,"#3","#4")}}
+
+ % we can combine the next calls
+
+ \def\dohandleMPgraytransparency #1#2#3{\ctxlua{ctx.pdfgrayliteral(\the\currentcolormodel,#1)
+ ctx.pdftransparencyliteral(#2,#3)}}
+ \def\dohandleMPrgbtransparency #1#2#3#4#5{\ctxlua{ctx.pdfrgbliteral (\the\currentcolormodel,#1,#2,#3)
+ ctx.pdftransparencyliteral(#4,#5)}}
+ \def\dohandleMPcmyktransparency#1#2#3#4#5#6{\ctxlua{ctx.pdfcmykliteral(\the\currentcolormodel,#1,#2,#3,#4)
+ ctx.pdftransparencyliteral(#5,#6)}}
+ \def\dohandleMPspottransparency#1#2#3#4#5#6{\ctxlua{ctx.pdfspotliteral(\the\currentcolormodel,"#1",#2,"#3","#4")
+ ctx.pdftransparencyliteral(#5,#6)}}
+
+ \def\dohandleMPresettransparency {\ctxlua{ctx.pdffinishtransparency()}}
+
+ \def\resolveMPgraycolor #1\to#2{\ctxlua{ctx.resolvempgraycolor("\strippedcsname#2","MPresolvedspace",\number\currentcolormodel,#1)}}
+ \def\resolveMPrgbcolor #1#2#3\to#4{\ctxlua{ctx.resolvemprgbcolor ("\strippedcsname#4","MPresolvedspace",\number\currentcolormodel,#1,#2,#3)}}
+ \def\resolveMPcmykcolor#1#2#3#4\to#5{\ctxlua{ctx.resolvempcmykcolor("\strippedcsname#5","MPresolvedspace",\number\currentcolormodel,#1,#2,#3,#4)}}
+
+ \def\resolveMPspotcolor#1#2#3#4\to#5% unchecked
+ {\ctxlua{ctx.resolvempspotcolor("\strippedcsname#5","MPresolvedspace",\number\currentcolormodel,"#1",#2,"#3","#4")}%
+ \xdef\MPresolvedspace{#1}%
+ \xdef\MPresolvedcolor{#4}%
+ \global\let\MPspotspace\MPresolvedspace}
+
+ % used as callers
+
+ \let\MPSgray\dohandleMPgraycolor
+ \let\MPSrgb \dohandleMPrgbcolor
+ \let\MPScmyk\dohandleMPcmykcolor
+ \let\MPspot \dohandleMPspotcolor
+
+\fi \fi
+
\protect \endinput
diff --git a/tex/context/base/meta-pdf.tex b/tex/context/base/meta-pdf.tex
deleted file mode 100644
index 8bf976f97..000000000
--- a/tex/context/base/meta-pdf.tex
+++ /dev/null
@@ -1,1020 +0,0 @@
-%D \module
-%D [ file=meta-pdf,
-%D version=2006.06.07,
-%D title=\CONTEXT\ Support Macros,
-%D subtitle=\METAPOST\ to \PDF\ conversion,
-%D author=Hans Hagen \& others (see text),
-%D date=\currentdate,
-%D copyright=\PRAGMA]
-%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 Formerly known as supp-pdf.tex and supp-mpe.tex.
-
-%D We will clean up the color mess later.
-
-%D These macros are written as generic as possible. Some
-%D general support macro's are loaded from a small module
-%D especially made for non \CONTEXT\ use. In this module I
-%D use a matrix transformation macro written by Tanmoy
-%D Bhattacharya. Thanks to extensive testing by Sebastian
-%D Ratz I was able to complete this module within reasonable
-%D time. This module has support for \METAPOST\ extensions
-%D built in.
-%D
-%D Daniel H. Luecking came up with a better (more precise)
-%D transformation method. You can recognize his comment by
-%D his initials. (We keep the old code around because it's a
-%D nice illustration on how a module like this evolves.)
-
-% Beware, we cannot use 0pt here by defaukt since it may be
-% defined in the range \dimen 0 - 20 which we happen to use
-% as scratch registers; for this reason we start allocating
-% scratch registers > 20
-
-%D This module handles some \PDF\ conversion and insertions
-%D topics. By default, the macros use the \PDFTEX\ primitive
-%D \type{\pdfliteral} when available. Since \PDFTEX\ is now the
-%D default engine for \TEX\ distributions, we need a more complex
-%D test.
-
-\writestatus{loading}{Context Support Macros / MPS to PDF}
-
-\unprotect
-
-\ifx\PDFcode \undefined \let\PDFcode \gobbleoneargument \fi
-\ifx\PDFcomment\undefined \def\PDFcomment#1{\PDFcode{\letterpercent\space#1}} \fi
-
-%D First we define a handy constant:
-
-\bgroup \catcode`\%=\@@other \xdef\letterpercent{\string%} \egroup
-
-%D \macros
-%D {pdfimage,pdfimages,pdfclippedimage}
-%D
-%D Starting with pdftex version 14, images are included more
-%D natural to the form embedding. This enables alternative
-%D images to be embedded.
-%D
-%D \starttyping
-%D \pdfimage <optional dimensions> {file}
-%D \pdfimages <optional dimensions> {high res file} {low res file}
-%D \stoptyping
-%D
-%D The first one replaces the pre||version||14 original,
-%D while the latter provides alternative images.
-%D
-%D The next macro is dedicated to Maarten Gelderman, who
-%D needed to paste prepared \PDF\ pages into conference
-%D proceedings.
-%D
-%D \starttyping
-%D \pdfclippedimage <optional dimensions> {file} {l} {r} {t} {b}
-%D \stoptyping
-
-\ifx\pdftexversion\undefined \else \ifnum\pdftexversion>13 % still relevant?
-
- \def\pdfimage#1#%
- {\dopdfimage{#1}}
-
- \def\dopdfimage#1#2%
- {\immediate\pdfximage#1{#2}%
- \pdfrefximage\pdflastximage}
-
- \def\pdfimages#1#%
- {\dopdfimages{#1}}
-
- \def\dopdfimages#1#2#3%
- {\immediate\pdfximage#1{#2}%
- \immediate\pdfobj{[ << /Image \the\pdflastximage\space0 R /DefaultForPrinting true >> ]}%
- \immediate\pdfximage#1 attr {/Alternates \the\pdflastobj\space0 R}{#3}%
- \pdfrefximage\pdflastximage}
-
- \def\pdfclippedimage#1#% specs {file}{left}{right}{top}{bottom}
- {\dopdfclippedimage{#1}}
-
- \def\dopdfclippedimage#1#2#3#4#5#6%
- {\bgroup
- \pdfximage#1{#2}%
- \setbox\scratchbox\hbox{\pdfrefximage\pdflastximage}%
- \hsize\dimexpr\wd\scratchbox-#3-#4\relax
- \vsize\dimexpr\ht\scratchbox-#5-#6\relax
- \setbox\scratchbox\vbox to \vsize
- {\vskip-#5\hbox to \hsize{\hskip-#3\box\scratchbox\hss}}%
- \pdfxform\scratchbox
- \pdfrefxform\pdflastxform
- \egroup}
-
-\fi \fi
-
-%D \macros
-%D {convertMPtoPDF}
-%D
-%D The next set of macros implements \METAPOST\ to \PDF\
-%D conversion. The traditional method is in the MkII file.
-
-%D The main conversion command is:
-%D
-%D \starttyping
-%D \convertMPtoPDF {filename} {x scale} {y scale}
-%D \stoptyping
-%D
-%D The dimensions are derived from the bounding box. So we
-%D only have to say:
-%D
-%D \starttyping
-%D \convertMPtoPDF{mp-pra-1.eps}{1}{1}
-%D \convertMPtoPDF{mp-pra-1.eps}{.5}{.5}
-%D \stoptyping
-
-%D \macros
-%D {makeMPintoPDFobject,lastPDFMPobject}
-%D
-%D For experts there are a few more options. When attributes
-%D are to be added, the code must be embedded in an object
-%D accompanied with the appropriate directives. One can
-%D influence this process with \type {\makeMPintoPDFobject}.
-%D
-%D This option defaults to~0, because \CONTEXT\ takes care
-%D of objects at another level, which saves some bytes.
-%D
-%D \starttabulate[|l|l|p|]
-%D \NC 0 \NC never \NC don't use an object \NC\NR
-%D \NC 1 \NC always \NC always use an object \NC\NR
-%D \NC 2 \NC optional \NC use object when needed \NC\NR
-%D \stoptabulate
-%D
-%D The last object number used is avaliable in the macro
-%D \type {\lastPDFMPobject}.
-
-\ifx\makeMPintoPDFobject \undefined \chardef\makeMPintoPDFobject \zerocount \fi
-\ifx\blackoutMPgraphic \undefined \chardef\blackoutMPgraphic \plusone \fi
-\ifx\everyMPtoPDFconversion\undefined \newtoks\everyMPtoPDFconversion \fi
-
-\let\lastPDFMPobject \!!zerocount
-\let\currentPDFresources\empty
-\let\setMPextensions \relax
-
-\def\PDFMPformoffset
- {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi}
-
-\def\resetMPvariables#1#2#3%
- {\global\let\MPwidth \!!zeropoint
- \global\let\MPheight\!!zeropoint
- \global\let\MPllx \!!zerocount
- \global\let\MPlly \!!zerocount
- \global\let\MPurx \!!zerocount
- \global\let\MPury \!!zerocount
- \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi
- \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi
- \xdef\MPfilename {#1}}
-
-%D The main macro:
-
-\def\convertMPtoPDF#1#2#3%
- {\resetMPvariables{#1}{#2}{#3}%
- \mkconvertMPtoPDF}
-
-\def\processMPtoPDFfile#1#2#3% obsolete
- {\resetMPvariables{#1}{#2}{#3}%
- \mkprocessMPtoPDFfile}
-
-%D A common hook.
-
-\let\MPfshowcommand\empty
-
-%D Objects.
-
-\def\dopackageMPgraphic#1% #1 = boxregister
- {\ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else
- % an existing value of 2 signals object support (set elsewhere)
- \chardef\makeMPintoPDFobject\plusone
- \fi\fi
- \ifcase\makeMPintoPDFobject
- \box#1%
- \or
- \scratchdimen\PDFMPformoffset\relax
- \ifdim\scratchdimen>\zeropoint % compensate for error
- \setbox#1\vbox spread 2\scratchdimen
- {\forgetall\vss\hbox spread 2\scratchdimen{\hss\box#1\hss}\vss}%
- \fi
- \setMPPDFobject{\currentPDFresources}{#1}%
- \ifdim\scratchdimen>\zeropoint % compensate for error
- \vbox to \MPheight
- {\forgetall\vss\hbox to \MPwidth{\hss\getMPPDFobject\hss}\vss}%
- \else
- \getMPPDFobject
- \fi
- \global\let\currentPDFresources\empty
- \else
- \box#1%
- \fi}
-
-\def\setMPPDFobject#1#2% resources boxnumber
- {\ifx\pdfxform\undefined
- \def\getMPPDFobject{\box#2}%
- \else\ifx\pdftexversion\undefined
- \def\getMPPDFobject{\box#2}%
- \else\ifnum\pdftexversion<14
- \def\getMPPDFobject{\box#2}%
- \else
- \ifx\everyPDFxform\undefined\else\the\everyPDFxform\fi
- \immediate\pdfxform resources{#1}#2%
- \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}%
- \fi\fi\fi}
-
-\let\getMPPDFobject\relax
-
-%D \macros
-%D {deleteMPgraphic,
-%D startMPresources,
-%D stopMPresources}
-
-\ifx\deleteMPgraphic\undefined
- \def\deleteMPgraphic#1{}
-\fi
-
-\ifx\startMPresources\undefined
- \let\startMPresources\relax
- \let\stopMPresources\relax
-\fi
-
-%D We implement extensions by using the \METAPOST\ special
-%D mechanism. Opposite to \TEX's specials, the \METAPOST\ ones
-%D are flushed before or after the graphic data, but thereby
-%D are no longer connected to a position.
-%D
-%D We implement specials by overloading the \type {fill}
-%D operator. By counting the fills, we can let the converter
-%D treat the appropriate fill in a special way. The
-%D specification of the speciality can have two forms,
-%D determined by the setting of a boolean variable:
-%D
-%D \starttyping
-%D _inline_specials_ := false ; % comment like code (default)
-%D _inline_specials_ := true ; % command like code
-%D \stoptyping
-%D
-%D When the specification is embedded as comment, it looks
-%D like:
-%D
-%D \starttyping
-%D %%MetaPostSpecial <size> <data> <number> <identifier>
-%D \stoptyping
-%D
-%D The in||line alternative is more tuned for \POSTSCRIPT,
-%D since it permits us to define a macro \type {special}.
-%D
-%D \starttyping
-%D inline : <data> <number> <identifier> <size> special
-%D \stoptyping
-%D
-%D The \type {identifier} determines what to do, and the data
-%D can be used to accomplish this. A type~2 shading function
-%D has identifier~2. Alltogether, the number of parameters is
-%D specified in \type {size}. The \type {number} is the number
-%D of the fill that needs the special treatment. For a type~2
-%D and~3 shaded fill, the datablock contains the following
-
-%D data:
-%D
-%D \starttyping
-%D from to n inner_r g b x y outer_r g b x y
-%D from to n inner_r g b x y radius outer_r g b x y radius
-%D \stoptyping
-
-\newconditional\manyMPspecials \settrue\manyMPspecials
-
-%D In case of \PDF, we need to prepare resourcs.
-
-\newtoks\MPstartresources
-\newtoks\MPstopresources
-
-\def\startMPresources
- {\the\MPstartresources}
-
-\def\stopMPresources
- {\the\MPstopresources}
-
-%D Some day we may consider collecting local resources.
-
-\appendtoks
- \global\let\currentPDFresources\empty % kind of redundant
-\to \MPstartresources
-
-% \appendtoks
-% \collectPDFresources
-% \global\let\currentPDFresources\collectedPDFresources
-% \to \MPstopresources
-
-\appendtoksonce
- \the\everyPDFxform
-\to \MPstopresources
-
-%D Since colors are not subjected to transformations, we can
-%D only use colors as signal. In our case, we use a dummy colored
-%D path with a red color component of \type {0.n}, so \type
-%D {0.001} is the first path and \type {0.010} the tenth. Since
-%D \METAPOST strips trailing zeros, we have to padd the string.
-
-\newif\ifMPcmykcolors
-\newif\ifMPspotcolors
-
-\def\dohandleMPrgb #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od}
-\def\dohandleMPcmyk#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od}
-\def\dohandleMPgray #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od}
-\def\dohandleMPspot#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od}
-
-%D Specials:
-
-\settrue \manyMPspecials \newcount\nofMParguments \let\extraMPpathcode\empty
-
-\def\@@MP {@@MP}
-\def\@@MPSK{@MPSK@}
-
-\def\MPspecial{\@@MPSK\@@MPSK\gMPs\nofMParguments}
-
-\def\defineMPspecial#1#2%
- {\setvalue{\@@MPSK\@@MPSK#1}{#2}}
-
-%D Special number~1 is dedicated to \CMYK\ support. If you
-%D want to know why: look at this:
-%D
-%D \startbuffer[mp]
-%D fill fullcircle xyscaled (3cm,1cm) withcolor \MPcolor{test} ;
-%D \stopbuffer
-%D
-%D \startbuffer[cmyk]
-%D \startcombination[4*1]
-%D {\definecolor[test][c=1,y=.3,k=.3] \processMPbuffer[mp]} {c=1 y=.3 k=.3}
-%D {\definecolor[test][c=.9,y=.15] \processMPbuffer[mp]} {c=.9 y=.15}
-%D {\definecolor[test][c=.25,y=.8] \processMPbuffer[mp]} {c=.25 y=.8}
-%D {\definecolor[test][c=.45,y=.1] \processMPbuffer[mp]} {c=.45 y=.1}
-%D \stopcombination
-%D \stopbuffer
-%D
-%D \placefigure
-%D {\CMYK\ support disabled,
-%D conversion to \RGB.}
-%D {\setupcolors[cmyk=nee,state=start]\getbuffer[cmyk]}
-%D
-%D \placefigure
-%D {\CMYK\ support enabled,
-%D no support in \METAPOST.}
-%D {\setupcolors[cmyk=ja,mpcmyk=nee,state=start]\getbuffer[cmyk]}
-%D
-%D \placefigure
-%D {\CMYK\ support enabled,
-%D no conversion to \RGB,
-%D support in \METAPOST}
-%D {\setupcolors[cmyk=ja,state=start]\getbuffer[cmyk]}
-
-\defineMPspecial{1}
- {\ifMPcmykcolors
- \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPcmykcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}%
- \fi}
-
-\defineMPspecial{2}
- {\ifMPspotcolors
- \setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPspotcolor{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}}%
-% \checkMPspot{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}%
- \fi}
-
-% \def\checkMPspot#1#2#3#4%
-% {\expanded{\resolveMPspotcolor#1 #2 #3 #4}\end
-% \ifx\MPspotspace\MPresolvedspace
-% \edef\MPspotspacespec{/\MPspotspace\space}%
-% \doifinstringelse\MPspotspacespec\currentMPcolorspaces
-% \donothing\registerMPcolorspace
-% \fi}
-
-\let\revokeMPtransparencyspecial\relax
-
-\def\dohandleMPrgbcolor #1#2#3{\revokeMPtransparencyspecial\execcolorR #1:#2:#3:0:0\od}
-\def\dohandleMPcmykcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorC#1:#2:#3:#4:0:0\od}
-\def\dohandleMPgraycolor #1{\revokeMPtransparencyspecial\execcolorS #1:0:0\od}
-\def\dohandleMPspotcolor#1#2#3#4{\revokeMPtransparencyspecial\execcolorP#1:#2:#3:#4:0:0\od}
-
-%D Transparency support used specials 60 (rgb) and 61
-%D (cmyk).
-%D
-%D \startbufferFshade
-
-%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
-%D
-%D fill p rotated 90 withcolor transparent(1,.5,yellow) ;
-%D fill p rotated 210 withcolor transparent(1,.5,green) ;
-%D fill p rotated 330 withcolor transparent(1,.5,blue) ;
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection \processMPbuffer \stoplinecorrection
-%D
-%D One can also communicate colors between \CONTEXT\ and
-%D \METAPOST:
-%D
-%D \startbuffer
-%D \definecolor[tcyan] [c=1,k=.2,t=.5]
-%D \definecolor[tmagenta][m=1,k=.2,t=.5]
-%D \definecolor[tyellow] [y=1,k=.2,t=.5]
-%D \stopbuffer
-%D
-%D \typebuffer \getbuffer
-%D
-%D \startbuffer
-%D u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
-%D
-%D fill p rotated 90 withcolor \MPcolor{tcyan} ;
-%D fill p rotated 210 withcolor \MPcolor{tmagenta} ;
-%D fill p rotated 330 withcolor \MPcolor{tyellow} ;
-%D \stopbuffer
-%D
-%D \startlinecorrection \processMPbuffer \stoplinecorrection
-%D
-%D We save all the three components needed in one macro,
-%D just to save hash space.
-
-\def\dohandleMPrgbtransparency #1#2#3#4#5{\execcolorR #1:#2:#3:#4:#5\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
-\def\dohandleMPcmyktransparency#1#2#3#4#5#6{\execcolorC#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
-\def\dohandleMPgraytransparency #1#2#3{\execcolorS #1:#2:#3\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
-\def\dohandleMPspottransparency#1#2#3#4#5#6{\execcolorP#1:#2:#3:#4:#5:#6\od\let\revokeMPtransparencyspecial\dorevokeMPtransparencyspecial}
-
-\def\dorevokeMPtransparencyspecial
- {\PDFcode{\PDFtransparencyresetidentifier\space gs}%
- \let\revokeMPtransparencyspecial\relax}
-
-\defineMPspecial{3} % rgb
- {\setxvalue{\@@MPSK\gMPs6}{\noexpand\dohandleMPrgbtransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs1}{\gMPs2}}}
-
-\defineMPspecial{4} % cmyk
- {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPcmyktransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}}
-
-\defineMPspecial{5} % spot
- {\setxvalue{\@@MPSK\gMPs7}{\noexpand\dohandleMPspottransparency{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs1}{\gMPs2}}%
- }%\checkMPspot{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}
-
-%D Shading is an example of a more advanced graphic feature,
-%D but users will seldom encounter those complications. Here
-%D we only show a few simple examples, but many other
-%D alternatives are possible by setting up the functions built
-%D in \PDF\ in the appropriate way.
-%D
-%D Shading has to do with interpolation between two or more
-%D points or user supplied ranges. In \PDF, the specifications
-%D of a shade has to be encapsulated in objects and passed on
-%D as resources. This is a \PDF\ level 1.3. feature. One can
-%D simulate three dimensional shades as well and define simple
-%D functions using a limited set of \POSTSCRIPT\ primitives.
-%D Given the power of \METAPOST\ and these \PDF\ features, we
-%D can achieve superb graphic effects.
-%D
-%D Since everything is hidden in \TEX\ and \METAPOST\ graphics,
-%D we can stick to high level \CONTEXT\ command, as shown in
-%D the following exmples.
-%D
-%D \startbuffer
-%D \startuniqueMPgraphic{CircularShade}
-%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
-%D circular_shade(p,0,.2red,.9red) ;
-%D \stopuniqueMPgraphic
-%D
-%D \startuniqueMPgraphic{LinearShade}
-%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
-%D linear_shade(p,0,.2blue,.9blue) ;
-%D \stopuniqueMPgraphic
-%D
-%D \startuniqueMPgraphic{DuotoneShade}
-%D path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
-%D linear_shade(p,2,.5green,.5red) ;
-%D \stopuniqueMPgraphic
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \getbuffer
-%D
-%D These graphics can be hooked into the overlay mechanism,
-%D which is available in many commands.
-%D
-%D \startbuffer
-%D \defineoverlay[demo 1][\uniqueMPgraphic{CircularShade}]
-%D \defineoverlay[demo 2][\uniqueMPgraphic {LinearShade}]
-%D \defineoverlay[demo 3][\uniqueMPgraphic {DuotoneShade}]
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \getbuffer
-%D
-%D These backgrounds can for instance be applied to \type
-%D {\framed}:
-%D
-%D \startbuffer
-%D \setupframed[width=3cm,height=2cm,frame=off]
-%D \startcombination[3*1]
-%D {\framed[backgroundachtergrond=demo 1]{\bfd \white Demo 1}} {}
-%D {\framed[backgroundachtergrond=demo 2]{\bfd \white Demo 2}} {}
-%D {\framed[backgroundachtergrond=demo 3]{\bfd \white Demo 3}} {}
-%D \stopcombination
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D \startlinecorrection
-%D \getbuffer
-%D \stoplinecorrection
-%D
-%D There are a few more alternatives, determined by the second
-%D parameter passed to \type {circular_shade} and alike.
-%D
-%D \def\SomeShade#1#2#3#4#5%
-%D {\startuniqueMPgraphic{Shade-#1}
-%D width := \overlaywidth ;
-%D height := \overlayheight ;
-%D path p ; p := unitsquare xscaled width yscaled height ;
-%D #2_shade(p,#3,#4,#5) ;
-%D \stopuniqueMPgraphic
-%D \defineoverlay[Shade-#1][\uniqueMPgraphic{Shade-#1}]%
-%D \framed[backgroundachtergrond=Shade-#1,width=2cm,height=2cm,frame=off]{}}
-%D
-%D \startlinecorrection
-%D \startcombination[5*1]
-%D {\SomeShade{10}{circular}{0}{.3blue}{.9blue}} {circular 0}
-%D {\SomeShade{11}{circular}{1}{.3blue}{.9blue}} {circular 1}
-%D {\SomeShade{12}{circular}{2}{.3blue}{.9blue}} {circular 2}
-%D {\SomeShade{13}{circular}{3}{.3blue}{.9blue}} {circular 3}
-%D {\SomeShade{14}{circular}{4}{.3blue}{.9blue}} {circular 4}
-%D \stopcombination
-%D \stoplinecorrection
-%D
-%D \blank
-%D
-%D \startlinecorrection
-%D \startcombination[5*1]
-%D {\SomeShade{20}{circular}{0}{.9green}{.3green}} {circular 0}
-%D {\SomeShade{21}{circular}{1}{.9green}{.3green}} {circular 1}
-%D {\SomeShade{22}{circular}{2}{.9green}{.3green}} {circular 2}
-%D {\SomeShade{23}{circular}{3}{.9green}{.3green}} {circular 3}
-%D {\SomeShade{24}{circular}{4}{.9green}{.3green}} {circular 4}
-%D \stopcombination
-%D \stoplinecorrection
-%D
-%D \blank
-%D
-%D \startlinecorrection
-%D \startcombination[4*1]
-%D {\SomeShade{30}{linear}{0}{.3red}{.9red}} {linear 0}
-%D {\SomeShade{31}{linear}{1}{.3red}{.9red}} {linear 1}
-%D {\SomeShade{32}{linear}{2}{.3red}{.9red}} {linear 2}
-%D {\SomeShade{33}{linear}{3}{.3red}{.9red}} {linear 3}
-%D \stopcombination
-%D \stoplinecorrection
-%D
-%D These macros closely cooperate with the \METAPOST\ module
-%D \type {mp-spec.mp}, which is part of the \CONTEXT\
-%D distribution.
-%D
-%D The low level (\PDF) implementation is based on the \TEX\
-%D based \METAPOST\ to \PDF\ converter. Shading is supported
-%D by overloading the \type {fill} operator as implemented
-%D earlier. In \PDF\ type~2 and~3 shading functions are
-%D specified in terms of:
-%D
-%D \starttabulate[|Tl|l|]
-%D \NC /Domain \NC sort of meeting range \NC \NR
-%D \NC /C0 \NC inner shade \NC \NR
-%D \NC /C1 \NC outer shade \NC \NR
-%D \NC /N \NC smaller values, bigger inner circles \NC \NR
-%D \stoptabulate
-
-\newcount\currentPDFshade % 0 % global (document wide) counter
-
-% \def\dosetMPsomePDFshade#1#2% generic but needs refs
-% {\global\advance\currentPDFshade \plusone
-% \doPDFdictionaryobject{FDF}{ftn:Sh:\the\currentPDFshade}
-% {/FunctionType 2
-% /Domain [\gMPs1 \gMPs2]
-% /C0 [\MPshadeA]
-% /C1 [\MPshadeB]
-% /N \gMPs3}%
-% \doPDFgetobjectreference{FDF}{ftn:Sh:\the\currentPDFshade}\PDFobjectreference
-% \doPDFdictionaryobject{FDF}{obj:Sh:\the\currentPDFshade}
-% {/ShadingType #1
-% /ColorSpace /\MPresolvedspace
-% /Function \PDFobjectreference\space
-% /Coords [\MPshadeC]
-% /Extend [true true]}%
-% \doPDFgetobjectreference{FDF}{obj:Sh:\the\currentPDFshade}\PDFobjectreference
-% \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\PDFobjectreference}%
-% \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}
-
-\def\dosetMPsomePDFshade#1#2%
- {\immediate\pdfobj
- {<</FunctionType 2
- /Domain [\gMPs1 \gMPs2]
- /C0 [\MPshadeA]
- /C1 [\MPshadeB]
- /N \gMPs3>>}%
- \immediate\pdfobj
- {<</ShadingType #1
- /ColorSpace /\MPresolvedspace
- /Function \the\pdflastobj\space 0 R
- /Coords [\MPshadeC]
- /Extend [true true]>>}%
- \global\advance\currentPDFshade \plusone
- \appendtoPDFdocumentshades{/Sh\the\currentPDFshade\space\the\pdflastobj\space0 R }%
- \setxvalue{\@@MPSK#2}{\noexpand\dohandleMPshade{\the\currentPDFshade}}}
-
-\def\dosetMPlinearshade {\dosetMPsomePDFshade2}% #1
-\def\dosetMPcircularshade{\dosetMPsomePDFshade3}% #1
-
-\defineMPspecial{30}
- {\expanded{\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
- \expanded{\resolveMPrgbcolor{\gMPs{9}}{\gMPs{10}}{\gMPs{11}}}\to\MPshadeB
- \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs{12} \gMPs{13}}%
- \dosetMPlinearshade{\gMPs{14}}}
-
-\defineMPspecial{31}
- {\expanded{\resolveMPrgbcolor{\gMPs4}{\gMPs5}{\gMPs6}}\to\MPshadeA
- \expanded{\resolveMPrgbcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}}\to\MPshadeB
- \edef\MPshadeC{\gMPs7 \gMPs8 \gMPs9 \gMPs{13} \gMPs{14} \gMPs{15}}%
- \dosetMPcircularshade{\gMPs{16}}}
-
-\defineMPspecial{32}
- {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
- \expanded{\resolveMPcmykcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
- \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
- \dosetMPlinearshade{\gMPs{16}}}
-
-\defineMPspecial{33}
- {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
- \expanded{\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
- \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
- \dosetMPcircularshade{\gMPs{18}}}
-
-\defineMPspecial{34}
- {\expanded{\resolveMPspotcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
- \expanded{\resolveMPspotcolor{\gMPs{10}}{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}}\to\MPshadeB
- \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{14} \gMPs{15}}%
- \dosetMPlinearshade{\gMPs{16}}}
-
-\defineMPspecial{35}
- {\expanded{\resolveMPcmykcolor{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}}\to\MPshadeA
- \expanded{\resolveMPcmykcolor{\gMPs{11}}{\gMPs{12}}{\gMPs{13}}{\gMPs{14}}}\to\MPshadeB
- \edef\MPshadeC{\gMPs8 \gMPs9 \gMPs{10} \gMPs{15} \gMPs{16} \gMPs{17}}%
- \dosetMPcircularshade{\gMPs{18}}}
-
-
-\newconditional\ignoreMPpath
-
-\def\dohandleMPshade#1%
- {\revokeMPtransparencyspecial
- \settrue\ignoreMPpath
- \def\extraMPpathcode{/Sh#1 sh Q}%
- \chardef\finiMPpath\zerocount
- \PDFcode{q /Pattern cs}}
-
-%D Figure inclusion is kind of strange to \METAPOST, but when
-%D Santiago Muelas started discussing this with me, I was able
-%D to cook up a solution using specials.
-
-\defineMPspecial{10}
- {\setxvalue{\@@MPSK\gMPs8}%
- {\noexpand\handleMPfigurespecial{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}{\gMPs7}{\gMPs8}}}
-
-\def\handleMPfigurespecial#1#2#3#4#5#6#7#8% todo : combine with ext fig
- {\global\letvalue{\@@MPSK#8}\empty
- \vbox to \zeropoint
- {\vss
- \hbox to \zeropoint
- {\ifcase\pdfoutput\or % will be hooked into the special driver
- \doiffileelse{#7}
- {\doifundefinedelse{mps:x:#7}
- {\immediate\pdfximage\!!width\onebasepoint\!!height\onebasepoint{#7}%
- \setxvalue{mps:x:#7}{\pdfrefximage\the\pdflastximage}}%
- {\message{[reusing figure #7]}}%
- \PDFcode{q #1 #2 #3 #4 #5 #6 cm}%
- \rlap{\getvalue{mps:x:#7}}%
- \PDFcode{Q}}
- {\message{[unknown figure #7]}}%
- \fi
- \hss}}}
-
-%D An example of using both special features is the
-%D following.
-%D
-%D \starttyping
-%D \startMPpage
-%D externalfigure "hakker1b.png" scaled 22cm rotated 10 shifted (-2cm,0cm);
-%D externalfigure "hakker1b.png" scaled 10cm rotated -10 ;
-%D externalfigure "hakker1b.png" scaled 7cm rotated 45 shifted (8cm,12cm) ;
-%D path p ; p := unitcircle xscaled 15cm yscaled 20cm;
-%D path q ; q := p rotatedaround(center p,90) ;
-%D path r ; r := buildcycle(p,q) ; clip currentpicture to r ;
-%D path s ; s := boundingbox currentpicture enlarged 5mm ;
-%D picture c ; c := currentpicture ; currentpicture := nullpicture ;
-%D circular_shade(s,0,.2red,.9red) ;
-%D addto currentpicture also c ;
-%D \stopMPpage
-%D \stoptyping
-
-%D This is some experimental hyperlink driver that I wrote
-%D for Mark Wicks.
-
-\defineMPspecial{20}
- {\setxvalue{\@@MPSK\gMPs6}%
- {\noexpand\handleMPhyperlink{\gMPs1}{\gMPs2}{\gMPs3}{\gMPs4}{\gMPs5}{\gMPs6}}}
-
-\def\handleMPhyperlink#1#2#3#4#5#6%
- {\global\letvalue{\@@MPSK#6}\empty
- \setbox\scratchbox\hbox
- {\setbox\scratchbox\null
- \wd\scratchbox\dimexpr-#1\onebasepoint+#3\onebasepoint\relax
- \ht\scratchbox\dimexpr-#2\onebasepoint+#4\onebasepoint\relax
- \incolorfalse
- \gotobox{\box\scratchbox}[#5]}%
- \setbox\scratchbox\hbox
- {\hskip\dimexpr\MPxoffset\onebasepoint+#1\onebasepoint\relax
- \raise\dimexpr\MPyoffset\onebasepoint+#2\onebasepoint\relax
- \box\scratchbox}%
- \smashbox\scratchbox
- \box\scratchbox}
-
-%D This special (number 50) passes positions to a tex file.
-%D This method uses a two||pass approach an (mis|)|used the
-%D context positioning macros. In \type {core-pos} we will
-%D implement the low level submacro needed.
-%D
-%D \startbuffer
-%D \definelayer[test]
-%D
-%D \setlayer
-%D [test]
-%D [x=\MPx{somepos-1},y=\MPy{somepos-1}]
-%D {Whatever we want here!}
-%D
-%D \setlayer
-%D [test]
-%D [x=\MPx{somepos-2},y=\MPy{somepos-2}]
-%D {Whatever we need there!}
-%D
-%D \startuseMPgraphic{oeps}
-%D draw fullcircle scaled 6cm withcolor red ;
-%D register ("somepos-1",1cm,2cm,center currentpicture) ;
-%D register ("somepos-2",4cm,3cm,(-1cm,-2cm)) ;
-%D \stopuseMPgraphic
-%D
-%D \framed[background=test,offset=overlay]{\useMPgraphic{oeps}}
-%D \stopbuffer
-%D
-%D \typebuffer
-%D
-%D Here the width and height are not realy used, but one can
-%D imagine situations where tex has to work with values
-%D calculated by \METAPOST.
-%D
-%D \startlinecorrection
-%D \getbuffer
-%D \stoplinecorrection
-%D
-%D Later we will implement a more convenient macro:
-%D
-%D \starttyping
-%D \setMPlayer [test] [somepos-1] {Whatever we want here!}
-%D \setMPlayer [test] [somepos-2] {Whatever we need there!}
-%D \stoptyping
-
-\defineMPspecial{50} % x y width height label
- {\dosavepositionwhd
- {\gMPs5}%
- {0}%
- {\the\dimexpr-\MPllx\onebasepoint+\gMPs1\onebasepoint\relax}
- {\the\dimexpr\gMPs2\onebasepoint-\scratchdimen+\MPury\onebasepoint\relax}%
- {\the\dimexpr\gMPs3\onebasepoint\relax}%
- {\the\dimexpr\gMPs4\onebasepoint\relax}%
- {0pt}}
-
-%D A few auxiliary macros. This will move to colo-ini.
-
-\def\MPgrayspace{DeviceGray}
-\def\MPrgbspace {DeviceRGB}
-\def\MPcmykspace{DeviceCMYK}
-\let\MPspotspace\MPgrayspace
-
-\def\MPcmykBlack{0 0 0 0}
-\def\MPcmykWhite{0 0 0 1}
-
-\def\startMPcolorresolve
- {\bgroup
- \def\dostartgraycolormode##1%
- {\global\let\MPresolvedspace\MPgrayspace
- \xdef\MPresolvedcolor{##1}}%
- \def\dostartrgbcolormode ##1##2##3%
- {\global\let\MPresolvedspace\MPrgbspace
- \xdef\MPresolvedcolor{##1 ##2 ##3}}%
- \def\dostartcmykcolormode##1##2##3##4%
- {\global\let\MPresolvedspace\MPcmykspace
- \xdef\MPresolvedcolor{##1 ##2 ##3 ##4}}%
- \def\dostartspotcolormode##1##2%
- {\global\let\MPspotspace\empty % left over ?
- \xdef\MPresolvedspace{##1}%
- \xdef\MPresolvedcolor{##2}%
- \global\let\MPspotspace\MPresolvedspace}% signal
- \dostartgraycolormode\!!zerocount} % kind of hackery initialization
-
-\let\stopMPcolorresolve\egroup
-
-\def\resolveMPrgbcolor#1#2#3\to#4%
- {\startMPcolorresolve
- \execcolorR#1:#2:#3:0:0\od
- \stopMPcolorresolve
- \let#4\MPresolvedcolor}
-
-\def\resolveMPcmykcolor#1#2#3#4\to#5%
- {\startMPcolorresolve
- \execcolorC#1:#2:#3:#4:0:0\od
- \stopMPcolorresolve
- \let#5\MPresolvedcolor}
-
-\def\resolveMPgraycolor#1\end\to#2%
- {\startMPcolorresolve
- \execcolorS#1:0:0\od
- \stopMPcolorresolve
- \let#2\MPresolvedcolor}
-
-\def\resolveMPspotcolor#1#2#3#4\end\to#5%
- {\startMPcolorresolve
- \ifnum#2>\plusone
- \checkmultitonecolor{#1}%
- \fi
- \execcolorP#1:#2:#3:#4:0:0\od
- \stopMPcolorresolve
- \let#5\MPresolvedcolor}
-
-%D \macros
-%D {dogetPDFmediabox}
-%D
-%D The next macro can be used to find the mediabox of a \PDF\
-%D illustration.
-%D
-%D \starttyping
-%D \dogetPDFmediabox
-%D {filename}
-%D {new dimen}{new dimen}{new dimen}{new dimen}
-%D \stoptyping
-%D
-%D Beware of dimen clashes: this macro uses the 5~default
-%D scratch registers! When no file or mediabox is found, the
-%D dimensions are zeroed.
-
-\def\dogetPDFmediabox#1#2#3#4#5%
- {\bgroup
- \def\PDFxscale{1}%
- \def\PDFyscale{1}%
- \uncatcodespecials
- \endlinechar\minusone
- \def\checkPDFtypepage##1/Type /Page##2##3\done%
- {\ifx##2\relax
- \else\if##2s% accept /Page and /Pages
- \let\doprocessPDFline\findPDFmediabox
- \else
- \let\doprocessPDFline\findPDFmediabox
- \fi\fi}%
- \def\findPDFtypepage
- {\expandafter\checkPDFtypepage\fileline/Type /Page\relax\done}%
- \def\checkPDFmediabox##1/MediaBox##2##3\done%
- {\ifx##2\relax \else
- \setPDFmediabox##2##3\done
- \fileprocessedtrue
- \fi}%
- \def\findPDFmediabox
- {\expandafter\checkPDFmediabox\fileline/MediaBox\relax\done}%
- \let\doprocessPDFline\findPDFtypepage
- \doprocessfile\scratchread{#1}\doprocessPDFline
- \egroup
- \ifx\PDFxoffset\undefined
- #2=\zeropoint
- #3=\zeropoint
- #4=\zeropoint
- #5=\zeropoint
- \else
- #2=\PDFxoffset\onebasepoint
- #3=\PDFyoffset\onebasepoint
- #4=\PDFwidth
- #5=\PDFheight
- \fi}
-
-\def\setPDFboundingbox#1#2#3#4#5#6%
- {\dimen0=#1\dimen0=#5\dimen0
- \ScaledPointsToBigPoints{\number\dimen0}\PDFxoffset
- \dimen0=#3\dimen0=#5\dimen0
- \xdef\PDFwidth{\the\dimen0}%
- \dimen0=#2\dimen0=#6\dimen0
- \ScaledPointsToBigPoints{\number\dimen0}\PDFyoffset
- \dimen0=#4\dimen0=#6\dimen0
- \xdef\PDFheight{\the\dimen0}%
- \global\let\PDFxoffset\PDFxoffset
- \global\let\PDFyoffset\PDFyoffset}
-
-\def\setPDFmediabox#1[#2 #3 #4 #5]#6\done
- {\dimen2=#2\onebasepoint\dimen2=-\dimen2 % \dimen2=-#2\onebasepoint also works since tex handles --
- \dimen4=#3\onebasepoint\dimen4=-\dimen4 % \dimen4=-#3\onebasepoint also works since tex handles --
- \dimen6=#4\onebasepoint\advance\dimen6 \dimen2
- \dimen8=#5\onebasepoint\advance\dimen8 \dimen4
- \setPDFboundingbox{\dimen2}{\dimen4}{\dimen6}{\dimen8}\PDFxscale\PDFyscale}
-
-%D End of soon obsolete code.
-
-%D The plugins:
-
-\startMPinitializations
- mp_shade_version := 2 ;
-\stopMPinitializations
-
-\loadmarkfile{meta-pdf}
-
-%D Test code:
-
-% \startMPcode
-% fill fullcircle scaled 3cm withcolor red ;
-% fill fullcircle scaled 2cm withcolor green ;
-% fill fullcircle scaled 1cm withcolor blue ;
-% currentpicture := currentpicture shifted (-4cm,0) ;
-% fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ;
-% fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ;
-% fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ;
-% currentpicture := currentpicture shifted (-4cm,0) ;
-% draw fullcircle scaled 3cm dashed evenly ;
-% draw fullcircle scaled 2cm dashed withdots ;
-% draw origin withpen pencircle scaled 3mm;
-% currentpicture := currentpicture shifted (-4cm,0) ;
-% fill fullcircle scaled 2cm shifted (-.5cm,+.5cm) withcolor transparent(1,.5,red);
-% fill fullcircle scaled 2cm shifted (-.5cm,-.5cm) withcolor transparent(1,.5,red);
-% fill fullcircle scaled 2cm shifted (+.5cm,+.5cm) withcolor transparent(1,.5,green);
-% fill fullcircle scaled 2cm shifted (+.5cm,-.5cm) withcolor transparent(1,.5,cmyk(1,0,1,.5));
-% currentpicture := currentpicture shifted (12cm,-4cm) ;
-% draw "o e p s" infont defaultfont scaled 2 shifted (-1cm,0) ;
-% currentpicture := currentpicture shifted (-4cm,0) ;
-% % bug: shift
-% draw fullcircle scaled 3cm withpen pencircle yscaled 3mm xscaled 2mm rotated 30 ;
-% draw fullcircle scaled 2cm withpen pencircle yscaled 3mm xscaled 2mm rotated 20 withcolor red ;
-% filldraw fullcircle scaled 1cm withpen pencircle yscaled 3mm xscaled 2mm rotated 10 withcolor green ;
-% currentpicture := currentpicture shifted (-4cm,0) ;
-% % shade cannot handle shift
-% circular_shade(fullcircle scaled 3cm,0,.2red,.9green) ;
-% circular_shade(fullcircle scaled 3cm shifted(+4cm,0),0,cmyk(1,0,0,0),cmyk(0,1,0,0)) ;
-% filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ;
-% \stopMPcode
-
-% This code will move to meta-pdf.mkiv and the call to lua will move to the
-% converter code (saves a lua call). We will do this when we made the final
-% move to attribute bases color. Actually, we cannot use attributes for
-% switching colors in mp literals because grouping (qQ) interferes.
-
-\ifx\colorversion\undefined \else \ifnum\colorversion>\plusone
-
- \def\dohandleMPgraycolor #1{\ctxlua{ctx.pdffinishtransparency()
- ctx.pdfgrayliteral(\the\currentcolormodel,#1)}}
- \def\dohandleMPrgbcolor #1#2#3{\ctxlua{ctx.pdffinishtransparency()
- ctx.pdfrgbliteral (\the\currentcolormodel,#1,#2,#3)}}
- \def\dohandleMPcmykcolor#1#2#3#4{\ctxlua{ctx.pdffinishtransparency()
- ctx.pdfcmykliteral(\the\currentcolormodel,#1,#2,#3,#4)}}
- \def\dohandleMPspotcolor#1#2#3#4{\ctxlua{ctx.pdffinishtransparency()
- ctx.pdfspotliteral(\the\currentcolormodel,"#1",#2,"#3","#4")}}
-
- % we can combine the next calls
-
- \def\dohandleMPgraytransparency #1#2#3{\ctxlua{ctx.pdfgrayliteral(\the\currentcolormodel,#1)
- ctx.pdftransparencyliteral(#2,#3)}}
- \def\dohandleMPrgbtransparency #1#2#3#4#5{\ctxlua{ctx.pdfrgbliteral (\the\currentcolormodel,#1,#2,#3)
- ctx.pdftransparencyliteral(#4,#5)}}
- \def\dohandleMPcmyktransparency#1#2#3#4#5#6{\ctxlua{ctx.pdfcmykliteral(\the\currentcolormodel,#1,#2,#3,#4)
- ctx.pdftransparencyliteral(#5,#6)}}
- \def\dohandleMPspottransparency#1#2#3#4#5#6{\ctxlua{ctx.pdfspotliteral(\the\currentcolormodel,"#1",#2,"#3","#4")
- ctx.pdftransparencyliteral(#5,#6)}}
-
- \def\dohandleMPresettransparency {\ctxlua{ctx.pdffinishtransparency()}}
-
- \def\resolveMPgraycolor #1\to#2{\ctxlua{ctx.resolvempgraycolor("\strippedcsname#2","MPresolvedspace",\number\currentcolormodel,#1)}}
- \def\resolveMPrgbcolor #1#2#3\to#4{\ctxlua{ctx.resolvemprgbcolor ("\strippedcsname#4","MPresolvedspace",\number\currentcolormodel,#1,#2,#3)}}
- \def\resolveMPcmykcolor#1#2#3#4\to#5{\ctxlua{ctx.resolvempcmykcolor("\strippedcsname#5","MPresolvedspace",\number\currentcolormodel,#1,#2,#3,#4)}}
-
- \def\resolveMPspotcolor#1#2#3#4\to#5% unchecked
- {\ctxlua{ctx.resolvempspotcolor("\strippedcsname#5","MPresolvedspace",\number\currentcolormodel,"#1",#2,"#3","#4")}%
- \xdef\MPresolvedspace{#1}%
- \xdef\MPresolvedcolor{#4}%
- \global\let\MPspotspace\MPresolvedspace}
-
- % used as callers
-
- \let\MPSgray\dohandleMPgraycolor
- \let\MPSrgb \dohandleMPrgbcolor
- \let\MPScmyk\dohandleMPcmykcolor
- \let\MPspot \dohandleMPspotcolor
-
-\fi \fi
-
-\protect \endinput
diff --git a/tex/context/base/meta-pdh.lua b/tex/context/base/meta-pdh.lua
new file mode 100644
index 000000000..e05529cc8
--- /dev/null
+++ b/tex/context/base/meta-pdh.lua
@@ -0,0 +1,630 @@
+if not modules then modules = { } end modules ['meta-pdf'] = {
+ version = 1.001,
+ comment = "companion to meta-pdf.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This file contains the history of the converter. We keep it around as it
+-- relates to the development of luatex.
+
+-- This is the third version. Version 1 converted to Lua code,
+-- version 2 gsubbed the file into TeX code, and version 3 uses
+-- the new lpeg functionality and streams the result into TeX.
+
+-- We will move old stuff to edu.
+
+--~ old lpeg 0.4 lpeg 0.5
+--~ 100 times test graphic 2.45 (T:1.07) 0.72 (T:0.24) 0.580 (0.560 no table) -- 0.54 optimized for one space (T:0.19)
+--~ 100 times big graphic 10.44 4.30/3.35 nogb 2.914 (2.050 no table) -- 1.99 optimized for one space (T:0.85)
+--~ 500 times test graphic T:1.29 T:1.16 (T:1.10 no table) -- T:1.10
+
+-- only needed for mp output on disk
+
+local concat, format = table.concat, string.format
+
+local ctxcatcodes = tex.ctxcatcodes
+
+mptopdf = { }
+mptopdf.parsers = { }
+mptopdf.parser = 'none'
+mptopdf.n = 0
+
+function mptopdf.reset()
+ mptopdf.data = ""
+ mptopdf.path = { }
+ mptopdf.stack = { }
+ mptopdf.texts = { }
+ mptopdf.version = 0
+ mptopdf.shortcuts = false
+ mptopdf.resetpath()
+end
+
+function mptopdf.resetpath()
+ mptopdf.stack.close = false
+ mptopdf.stack.path = { }
+ mptopdf.stack.concat = nil
+ mptopdf.stack.special = false
+end
+
+mptopdf.reset()
+
+function mptopdf.parsers.none()
+ -- no parser set
+end
+
+function mptopdf.parse()
+ mptopdf.parsers[mptopdf.parser]()
+end
+
+-- old code
+
+mptopdf.steps = { }
+
+mptopdf.descapes = {
+ ['('] = "\\\\char40 ",
+ [')'] = "\\\\char41 ",
+ ['"'] = "\\\\char92 "
+}
+
+function mptopdf.descape(str)
+ str = str:gsub("\\(%d%d%d)",function(n)
+ return "\\char" .. tonumber(n,8) .. " "
+ end)
+ return str:gsub("\\([%(%)\\])",mptopdf.descapes)
+end
+
+function mptopdf.steps.descape(str)
+ str = str:gsub("\\(%d%d%d)",function(n)
+ return "\\\\char" .. tonumber(n,8) .. " "
+ end)
+ return str:gsub("\\([%(%)\\])",mptopdf.descapes)
+end
+
+function mptopdf.steps.strip() -- .3 per expr
+ mptopdf.data = mptopdf.data:gsub("^(.-)%%+Page:.-%c+(.*)%s+%a+%s+%%+EOF.*$", function(preamble, graphic)
+ local bbox = "0 0 0 0"
+ for b in preamble:gmatch("%%%%%a+oundingBox: +(.-)%c+") do
+ bbox = b
+ end
+ local name, version = preamble:gmatch("%%%%Creator: +(.-) +(.-) ")
+ mptopdf.version = tostring(version or "0")
+ if preamble:find("/hlw{0 dtransform") then
+ mptopdf.shortcuts = true
+ end
+ -- the boundingbox specification needs to come before data, well, not really
+ return bbox .. " boundingbox\n" .. "\nbegindata\n" .. graphic .. "\nenddata\n"
+ end, 1)
+ mptopdf.data = mptopdf.data:gsub("%%%%MetaPostSpecials: +(.-)%c+", "%1 specials\n", 1)
+ mptopdf.data = mptopdf.data:gsub("%%%%MetaPostSpecial: +(.-)%c+", "%1 special\n")
+ mptopdf.data = mptopdf.data:gsub("%%.-%c+", "")
+end
+
+function mptopdf.steps.cleanup()
+ if not mptopdf.shortcuts then
+ mptopdf.data = mptopdf.data:gsub("gsave%s+fill%s+grestore%s+stroke", "both")
+ mptopdf.data = mptopdf.data:gsub("([%d%.]+)%s+([%d%.]+)%s+dtransform%s+exch%s+truncate%s+exch%s+idtransform%s+pop%s+setlinewidth", function(wx,wy)
+ if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
+ end)
+ mptopdf.data = mptopdf.data:gsub("([%d%.]+)%s+([%d%.]+)%s+dtransform%s+truncate%s+idtransform%s+setlinewidth%s+pop", function(wx,wy)
+ if tonumber(wx) > 0 then return wx .. " setlinewidth" else return wy .. " setlinewidth" end
+ end)
+ end
+end
+
+function mptopdf.steps.convert()
+ mptopdf.data = mptopdf.data:gsub("%c%((.-)%) (.-) (.-) fshow", function(str,font,scale)
+ mptopdf.texts[mptopdf.texts+1] = {mptopdf.steps.descape(str), font, scale}
+ return "\n" .. #mptopdf.texts .. " textext"
+ end)
+ mptopdf.data = mptopdf.data:gsub("%[%s*(.-)%s*%]", function(str)
+ return str:gsub("%s+"," ")
+ end)
+ local t
+ mptopdf.data = mptopdf.data:gsub("%s*([^%a]-)%s*(%a+)", function(args,cmd)
+ if cmd == "textext" then
+ t = mptopdf.texts[tonumber(args)]
+ return "mps.textext(" .. "\"" .. t[2] .. "\"," .. t[3] .. ",\"" .. t[1] .. "\")\n"
+ else
+ return "mps." .. cmd .. "(" .. args:gsub(" +",",") .. ")\n"
+ end
+ end)
+end
+
+function mptopdf.steps.process()
+ assert(loadstring(mptopdf.data))() -- () runs the loaded chunk
+end
+
+function mptopdf.parsers.gsub()
+ mptopdf.steps.strip()
+ mptopdf.steps.cleanup()
+ mptopdf.steps.convert()
+ mptopdf.steps.process()
+end
+
+-- end of old code
+
+-- from lua to tex
+
+function mptopdf.pdfcode(str)
+ tex.sprint(ctxcatcodes,"\\PDFcode{" .. str .. "}") -- \\MPScode
+end
+
+function mptopdf.texcode(str)
+ tex.sprint(ctxcatcodes,str)
+end
+
+-- auxiliary functions
+
+function mptopdf.flushconcat()
+ if mptopdf.stack.concat then
+ mptopdf.pdfcode(concat(mptopdf.stack.concat," ") .. " cm")
+ mptopdf.stack.concat = nil
+ end
+end
+
+function mptopdf.flushpath(cmd)
+ -- faster: no local function and ipairs
+ if #mptopdf.stack.path > 0 then
+ local path = { }
+ if mptopdf.stack.concat then
+ local sx, sy = mptopdf.stack.concat[1], mptopdf.stack.concat[4]
+ local rx, ry = mptopdf.stack.concat[2], mptopdf.stack.concat[3]
+ local tx, ty = mptopdf.stack.concat[5], mptopdf.stack.concat[6]
+ local d = (sx*sy) - (rx*ry)
+ local function mpconcat(px, py)
+ return (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d
+ end
+ local stackpath = mptopdf.stack.path
+ for k=1,#stackpath do
+ local v = stackpath[k]
+ v[1],v[2] = mpconcat(v[1],v[2])
+ if #v == 7 then
+ v[3],v[4] = mpconcat(v[3],v[4])
+ v[5],v[6] = mpconcat(v[5],v[6])
+ end
+ path[#path+1] = concat(v," ")
+ end
+ else
+ local stackpath = mptopdf.stack.path
+ for k=1,#stackpath do
+ path[#path+1] = concat(stackpath[k]," ")
+ end
+ end
+ mptopdf.flushconcat()
+ mptopdf.texcode("\\MPSpath{" .. concat(path," ") .. "}")
+ if mptopdf.stack.close then
+ mptopdf.texcode("\\MPScode{h " .. cmd .. "}")
+ else
+ mptopdf.texcode("\\MPScode{" .. cmd .."}")
+ end
+ end
+ mptopdf.resetpath()
+end
+
+function mptopdf.loaded(name)
+ local ok, n
+ mptopdf.reset()
+ ok, mptopdf.data, n = resolvers.loadbinfile(name, 'tex') -- we need a binary load !
+ return ok
+end
+
+if not mptopdf.parse then
+ function mptopdf.parse() end -- forward declaration
+end
+
+function mptopdf.convertmpstopdf(name)
+ if mptopdf.loaded(name) then
+ mptopdf.n = mptopdf.n + 1
+ statistics.starttiming(mptopdf)
+ mptopdf.parse()
+ mptopdf.reset()
+ statistics.stoptiming(mptopdf)
+ else
+ tex.print("file " .. name .. " not found")
+ end
+end
+
+-- mp interface
+
+mps = mps or { }
+
+function mps.creator(a, b, c)
+ mptopdf.version = tonumber(b)
+end
+
+function mps.creationdate(a)
+ mptopdf.date= a
+end
+
+function mps.newpath()
+ mptopdf.stack.path = { }
+end
+
+function mps.boundingbox(llx, lly, urx, ury)
+ mptopdf.texcode("\\MPSboundingbox{" .. llx .. "}{" .. lly .. "}{" .. urx .. "}{" .. ury .. "}")
+end
+
+function mps.moveto(x,y)
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"m"}
+end
+
+function mps.curveto(ax, ay, bx, by, cx, cy)
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {ax,ay,bx,by,cx,cy,"c"}
+end
+
+function mps.lineto(x,y)
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {x,y,"l"}
+end
+
+function mps.rlineto(x,y)
+ local dx, dy = 0, 0
+ if #mptopdf.stack.path > 0 then
+ dx, dy = mptopdf.stack.path[#mptopdf.stack.path][1], mptopdf.stack.path[#mptopdf.stack.path][2]
+ end
+ mptopdf.stack.path[#mptopdf.stack.path+1] = {dx,dy,"l"}
+end
+
+function mps.translate(tx,ty)
+ mptopdf.pdfcode("1 0 0 0 1 " .. tx .. " " .. ty .. " cm")
+end
+
+function mps.scale(sx,sy)
+ mptopdf.stack.concat = {sx,0,0,sy,0,0}
+end
+
+function mps.concat(sx, rx, ry, sy, tx, ty)
+ mptopdf.stack.concat = {sx,rx,ry,sy,tx,ty}
+end
+
+function mps.setlinejoin(d)
+ mptopdf.pdfcode(d .. " j")
+end
+
+function mps.setlinecap(d)
+ mptopdf.pdfcode(d .. " J")
+end
+
+function mps.setmiterlimit(d)
+ mptopdf.pdfcode(d .. " M")
+end
+
+function mps.gsave()
+ mptopdf.pdfcode("q")
+end
+
+function mps.grestore()
+ mptopdf.pdfcode("Q")
+end
+
+function mps.setdash(...)
+ local n = select("#",...)
+ mptopdf.pdfcode("[" .. concat({...}," ",1,n-1) .. "] " .. select(n,...) .. " d")
+end
+
+function mps.resetdash()
+ mptopdf.pdfcode("[ ] 0 d")
+end
+
+function mps.setlinewidth(d)
+ mptopdf.pdfcode(d .. " w")
+end
+
+function mps.closepath()
+ mptopdf.stack.close = true
+end
+
+function mps.fill()
+ mptopdf.flushpath('f')
+end
+
+function mps.stroke()
+ mptopdf.flushpath('S')
+end
+
+function mps.both()
+ mptopdf.flushpath('B')
+end
+
+function mps.clip()
+ mptopdf.flushpath('W n')
+end
+
+function mps.textext(font, scale, str) -- old parser
+ local dx, dy = 0, 0
+ if #mptopdf.stack.path > 0 then
+ dx, dy = mptopdf.stack.path[1][1], mptopdf.stack.path[1][2]
+ end
+ mptopdf.flushconcat()
+ mptopdf.texcode("\\MPStextext{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
+ mptopdf.resetpath()
+end
+
+--~ function mps.handletext(font,scale.str,dx,dy)
+--~ local one, two = string.match(str, "^(%d+)::::(%d+)")
+--~ if one and two then
+--~ mptopdf.texcode("\\MPTOPDFtextext{"..font.."}{"..scale.."}{"..one.."}{"..two.."}{"..dx.."}{"..dy.."}")
+--~ else
+--~ mptopdf.texcode("\\MPTOPDFtexcode{"..font.."}{"..scale.."}{"..str.."}{"..dx.."}{"..dy.."}")
+--~ end
+--~ end
+
+if false and ctx and ctx.aux and ctx.aux.definecolor then
+
+ logs.report("mptopdf", "using attribute based mps colors")
+
+ -- does not work due to Q-q mess-up
+
+ function mps.setrgbcolor(r,g,b) -- extra check
+ r, g, b = tonumber(r), tonumber(g), tonumber(b) -- needed when we use lpeg
+ if r == 0.0123 and g < 0.1 then -- g is extra check
+ mptopdf.texcode("\\doresetattribute{transparency}\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
+ elseif r == 0.123 and g < 0.1 then -- g is extra check
+ mptopdf.texcode("\\doresetattribute{transparency}\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
+ else
+ mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'rgb',r,g,b) .. "}")
+ end
+ end
+
+ function mps.setcmykcolor(c,m,y,k)
+ mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'cmyk',tonumber(c),tonumber(m),tonumber(y),tonumber(k)) .. "}")
+ end
+
+ function mps.setgray(s)
+ mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'gray',tonumber(s)) .. "}")
+ end
+
+else
+
+ function mps.setrgbcolor(r,g,b) -- extra check
+ r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
+ if r == 0.0123 and g < 0.1 then
+ mptopdf.texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
+ elseif r == 0.123 and g < 0.1 then
+ mptopdf.texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
+ else
+ mptopdf.texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
+ end
+ end
+
+ function mps.setcmykcolor(c,m,y,k)
+ mptopdf.texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
+ end
+
+ function mps.setgray(s)
+ mptopdf.texcode("\\MPSgray{" .. s .. "}")
+ end
+
+end
+
+function mps.specials(version,signal,factor) -- 2.0 123 1000
+end
+
+function mps.special(...) -- 7 1 0.5 1 0 0 1 3
+ local n = select("#",...)
+ mptopdf.texcode("\\MPSbegin\\MPSset{" .. concat({...},"}\\MPSset{",2,n) .. "}\\MPSend")
+end
+
+function mps.begindata()
+end
+
+function mps.enddata()
+end
+
+function mps.showpage()
+end
+
+mps.n = mps.newpath -- n
+mps.p = mps.closepath -- h
+mps.l = mps.lineto -- l
+mps.r = mps.rlineto -- r
+mps.m = mps.moveto -- m
+mps.c = mps.curveto -- c
+mps.hlw = mps.setlinewidth
+mps.vlw = mps.setlinewidth
+
+mps.C = mps.setcmykcolor -- k
+mps.G = mps.setgray -- g
+mps.R = mps.setrgbcolor -- rg
+
+mps.lj = mps.setlinejoin -- j
+mps.ml = mps.setmiterlimit -- M
+mps.lc = mps.setlinecap -- J
+mps.sd = mps.setdash -- d
+mps.rd = mps.resetdash
+
+mps.S = mps.stroke -- S
+mps.F = mps.fill -- f
+mps.B = mps.both -- B
+mps.W = mps.clip -- W
+
+mps.q = mps.gsave -- q
+mps.Q = mps.grestore -- Q
+
+mps.s = mps.scale -- (not in pdf)
+mps.t = mps.concat -- (not the same as pdf anyway)
+
+mps.P = mps.showpage
+
+-- experimental
+
+function mps.attribute(id,value)
+ mptopdf.texcode("\\attribute " .. id .. "=" .. value .. " ")
+-- mptopdf.texcode("\\dompattribute{" .. id .. "}{" .. value .. "}")
+end
+
+-- lpeg parser
+
+-- The lpeg based parser is rather optimized for the kind of output
+-- that MetaPost produces. It's my first real lpeg code, which may
+-- show. Because the parser binds to functions, we define it last.
+
+do -- assumes \let\c\char
+
+ local byte = string.byte
+ local digit = lpeg.R("09")
+ local spec = digit^2 * lpeg.P("::::") * digit^2
+ local text = lpeg.Cc("{") * (
+ lpeg.P("\\") * ( (digit * digit * digit) / function(n) return "c" .. tonumber(n,8) end) +
+ lpeg.P(" ") / function(n) return "\\c32" end + -- never in new mp
+ lpeg.P(1) / function(n) return "\\c" .. byte(n) end
+ ) * lpeg.Cc("}")
+ local package = lpeg.Cs(spec + text^0)
+
+ function mps.fshow(str,font,scale) -- lpeg parser
+ mps.textext(font,scale,package:match(str))
+ end
+
+end
+
+do
+
+ local eol = lpeg.S('\r\n')^1
+ local sp = lpeg.P(' ')^1
+ local space = lpeg.S(' \r\n')^1
+ local number = lpeg.S('0123456789.-+')^1
+ local nonspace = lpeg.P(1-lpeg.S(' \r\n'))^1
+
+ local cnumber = lpeg.C(number)
+ local cstring = lpeg.C(nonspace)
+
+ local specials = (lpeg.P("%%MetaPostSpecials:") * sp * (cstring * sp^0)^0 * eol) / mps.specials
+ local special = (lpeg.P("%%MetaPostSpecial:") * sp * (cstring * sp^0)^0 * eol) / mps.special
+ local boundingbox = (lpeg.P("%%BoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
+ local highresboundingbox = (lpeg.P("%%HiResBoundingBox:") * sp * (cnumber * sp^0)^4 * eol) / mps.boundingbox
+
+ local setup = lpeg.P("%%BeginSetup") * (1 - lpeg.P("%%EndSetup") )^1
+ local prolog = lpeg.P("%%BeginProlog") * (1 - lpeg.P("%%EndProlog"))^1
+ local comment = lpeg.P('%')^1 * (1 - eol)^1
+
+ local curveto = ((cnumber * sp)^6 * lpeg.P("curveto") ) / mps.curveto
+ local lineto = ((cnumber * sp)^2 * lpeg.P("lineto") ) / mps.lineto
+ local rlineto = ((cnumber * sp)^2 * lpeg.P("rlineto") ) / mps.rlineto
+ local moveto = ((cnumber * sp)^2 * lpeg.P("moveto") ) / mps.moveto
+ local setrgbcolor = ((cnumber * sp)^3 * lpeg.P("setrgbcolor") ) / mps.setrgbcolor
+ local setcmykcolor = ((cnumber * sp)^4 * lpeg.P("setcmykcolor") ) / mps.setcmykcolor
+ local setgray = ((cnumber * sp)^1 * lpeg.P("setgray") ) / mps.setgray
+ local newpath = ( lpeg.P("newpath") ) / mps.newpath
+ local closepath = ( lpeg.P("closepath") ) / mps.closepath
+ local fill = ( lpeg.P("fill") ) / mps.fill
+ local stroke = ( lpeg.P("stroke") ) / mps.stroke
+ local clip = ( lpeg.P("clip") ) / mps.clip
+ local both = ( lpeg.P("gsave fill grestore")) / mps.both
+ local showpage = ( lpeg.P("showpage") )
+ local setlinejoin = ((cnumber * sp)^1 * lpeg.P("setlinejoin") ) / mps.setlinejoin
+ local setlinecap = ((cnumber * sp)^1 * lpeg.P("setlinecap") ) / mps.setlinecap
+ local setmiterlimit = ((cnumber * sp)^1 * lpeg.P("setmiterlimit") ) / mps.setmiterlimit
+ local gsave = ( lpeg.P("gsave") ) / mps.gsave
+ local grestore = ( lpeg.P("grestore") ) / mps.grestore
+
+ local setdash = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("setdash")) / mps.setdash
+ local concat = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("concat") ) / mps.concat
+ local scale = ( (cnumber * sp^0)^6 * sp * lpeg.P("concat") ) / mps.concat
+
+ local fshow = (lpeg.P("(") * lpeg.C((1-lpeg.P(")"))^1) * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
+ local fshow = (lpeg.P("(") *
+ lpeg.Cs( ( lpeg.P("\\(")/"\\050" + lpeg.P("\\)")/"\\051" + (1-lpeg.P(")")) )^1 )
+ * lpeg.P(")") * space * cstring * space * cnumber * space * lpeg.P("fshow")) / mps.fshow
+
+ local setlinewidth_x = (lpeg.P("0") * sp * cnumber * sp * lpeg.P("dtransform truncate idtransform setlinewidth pop")) / mps.setlinewidth
+ local setlinewidth_y = (cnumber * sp * lpeg.P("0 dtransform exch truncate exch idtransform pop setlinewidth") ) / mps.setlinewidth
+
+ local c = ((cnumber * sp)^6 * lpeg.P("c") ) / mps.curveto -- ^6 very inefficient, ^1 ok too
+ local l = ((cnumber * sp)^2 * lpeg.P("l") ) / mps.lineto
+ local r = ((cnumber * sp)^2 * lpeg.P("r") ) / mps.rlineto
+ local m = ((cnumber * sp)^2 * lpeg.P("m") ) / mps.moveto
+ local vlw = ((cnumber * sp)^1 * lpeg.P("vlw")) / mps.setlinewidth
+ local hlw = ((cnumber * sp)^1 * lpeg.P("hlw")) / mps.setlinewidth
+
+ local R = ((cnumber * sp)^3 * lpeg.P("R") ) / mps.setrgbcolor
+ local C = ((cnumber * sp)^4 * lpeg.P("C") ) / mps.setcmykcolor
+ local G = ((cnumber * sp)^1 * lpeg.P("G") ) / mps.setgray
+
+ local lj = ((cnumber * sp)^1 * lpeg.P("lj") ) / mps.setlinejoin
+ local ml = ((cnumber * sp)^1 * lpeg.P("ml") ) / mps.setmiterlimit
+ local lc = ((cnumber * sp)^1 * lpeg.P("lc") ) / mps.setlinecap
+
+ local n = lpeg.P("n") / mps.newpath
+ local p = lpeg.P("p") / mps.closepath
+ local S = lpeg.P("S") / mps.stroke
+ local F = lpeg.P("F") / mps.fill
+ local B = lpeg.P("B") / mps.both
+ local W = lpeg.P("W") / mps.clip
+ local P = lpeg.P("P") / mps.showpage
+
+ local q = lpeg.P("q") / mps.gsave
+ local Q = lpeg.P("Q") / mps.grestore
+
+ local sd = (lpeg.P("[") * (cnumber * sp^0)^0 * lpeg.P("]") * sp * cnumber * sp * lpeg.P("sd")) / mps.setdash
+ local rd = ( lpeg.P("rd")) / mps.resetdash
+
+ local s = ( (cnumber * sp^0)^2 * lpeg.P("s") ) / mps.scale
+ local t = (lpeg.P("[") * (cnumber * sp^0)^6 * lpeg.P("]") * sp * lpeg.P("t") ) / mps.concat
+
+ -- experimental
+
+ local attribute = ((cnumber * sp)^2 * lpeg.P("attribute")) / mps.attribute
+ local A = ((cnumber * sp)^2 * lpeg.P("A")) / mps.attribute
+
+ local preamble = (
+ prolog + setup +
+ boundingbox + highresboundingbox + specials + special +
+ comment
+ )
+
+ local procset = (
+ lj + ml + lc +
+ c + l + m + n + p + r +
+ A +
+ R + C + G +
+ S + F + B + W +
+ vlw + hlw +
+ Q + q +
+ sd + rd +
+ t + s +
+ fshow +
+ P
+ )
+
+ local verbose = (
+ curveto + lineto + moveto + newpath + closepath + rlineto +
+ setrgbcolor + setcmykcolor + setgray +
+ attribute +
+ setlinejoin + setmiterlimit + setlinecap +
+ stroke + fill + clip + both +
+ setlinewidth_x + setlinewidth_y +
+ gsave + grestore +
+ concat + scale +
+ fshow +
+ setdash + -- no resetdash
+ showpage
+ )
+
+ -- order matters in terms of speed / we could check for procset first
+
+ local captures_old = ( space + verbose + preamble )^0
+ local captures_new = ( space + procset + preamble + verbose )^0
+
+ function mptopdf.parsers.lpeg()
+ if mptopdf.data:find("%%%%BeginResource: procset mpost") then
+ captures_new:match(mptopdf.data)
+ else
+ captures_old:match(mptopdf.data)
+ end
+ end
+
+end
+
+mptopdf.parser = 'lpeg'
+
+-- status info
+
+statistics.register("mps conversion time",function()
+ local n = mptopdf.n
+ if n > 0 then
+ return format("%s seconds, %s conversions", statistics.elapsedtime(mptopdf),n)
+ else
+ return nil
+ end
+end)
diff --git a/tex/context/base/meta-tex.mkii b/tex/context/base/meta-tex.mkii
index 5766f659f..bf733d550 100644
--- a/tex/context/base/meta-tex.mkii
+++ b/tex/context/base/meta-tex.mkii
@@ -191,7 +191,7 @@
\filtersometxt}
\long\def\filtersometxt#1\sometxt
- {\doifnextcharelse[\redofiltersometxt\dodofiltersometxt}
+ {\doifnextoptionalelse\redofiltersometxt\dodofiltersometxt}
% cleaner in mkiv
%
diff --git a/tex/context/base/metatex.tex b/tex/context/base/metatex.tex
new file mode 100644
index 000000000..c7ceb005d
--- /dev/null
+++ b/tex/context/base/metatex.tex
@@ -0,0 +1,145 @@
+%D \module
+%D [ file=metatex,
+%D version=2008.10.10,
+%D title=\METATEX,
+%D subtitle=\METATEX\ Format Generation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=Hans Hagen / \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 format is just a minimal layer on top of the \LUATEX\
+%D engine and will not provide high level functionality. It can
+%D be used as basis for dedicated (specialized) macro packages.
+%D
+%D A format is generated with the command;
+%D
+%D \starttyping
+%D luatools --make --compile metatex
+%D \stoptyping
+%D
+%D Remark: this is far from complete. We will gradually add
+%D more. Also, it's not yet clean what exactly will be part
+%D of it. This is a prelude to a configureable macro package.
+
+\catcode`\{=1 \catcode`\}=2 \catcode`\#=6
+
+\edef\metatexformat {\jobname}
+\edef\metatexversion{2007.04.03 13:01}
+
+\let\fmtname \metatexformat
+\let\fmtversion\metatexversion
+
+\ifx\normalinput\undefined \let\normalinput\input \fi
+
+\def\loadcorefile#1{\normalinput#1\relax}
+
+\loadcorefile{syst-ini.tex} % some basic commands and allocations that are expected down the line
+\loadcorefile{syst-pln.tex} % plain tex initializations of internal registers (no further code)
+
+\loadcorefile{luat-cod.tex} %
+\loadcorefile{luat-bas.tex} %
+\loadcorefile{luat-lib.tex} %
+
+% needs stripping:
+
+\loadcorefile{catc-ini.mkiv} % catcode table management
+\loadcorefile{catc-act.tex} % active character definition mechanisms
+\loadcorefile{catc-def.tex} % some generic catcode tables
+\loadcorefile{catc-ctx.tex} % a couple of context specific tables but expected by later modules
+\loadcorefile{catc-sym.tex} % some definitions related to \letter<tokens>
+
+% helpers, maybe less
+
+\loadcorefile{syst-aux.tex} % a whole lot of auxiliary macros
+%loadcorefile{syst-lua.tex} % some helpers using lua instead
+%loadcorefile{syst-con.mkiv} % some rather basic conversions
+%loadcorefile{syst-fnt.mkiv}
+%loadcorefile{syst-str.mkiv}
+%loadcorefile{syst-rtp.mkiv}
+
+% not needed
+
+% \loadmarkfile{supp-fil}
+% \loadmarkfile{supp-dir}
+
+% characters
+
+\loadcorefile{char-utf.tex}
+\loadcorefile{char-ini.tex}
+\loadcorefile{char-enc.tex} % \registerctxluafile{char-enc}{1.001}
+
+% nodes
+
+\loadcorefile{node-ini.tex}
+%loadcorefile{node-fin.tex}
+%loadcorefile{node-par.tex}
+
+% attributes, not needed:
+
+%loadcorefile{attr-ini.tex}
+
+% regimes
+
+% \loadcorefile{regi-ini.mkiv}
+% \loadcorefile{regi-syn.tex}
+
+% languages
+
+% fonts
+
+% \loadcorefile{enco-ini.mkiv}
+% \loadcorefile{hand-ini.mkiv}
+
+\registerctxluafile{font-ini}{1.001}
+
+\registerctxluafile{node-fnt}{1.001}
+
+\registerctxluafile{font-enc}{1.001}
+\registerctxluafile{font-map}{1.001}
+\registerctxluafile{font-syn}{1.001}
+\registerctxluafile{font-tfm}{1.001}
+\registerctxluafile{font-afm}{1.001}
+\registerctxluafile{font-cid}{1.001}
+\registerctxluafile{font-ott}{1.001}
+\registerctxluafile{font-otf}{1.001}
+\registerctxluafile{font-otb}{1.001}
+\registerctxluafile{font-otn}{1.001}
+\registerctxluafile{font-ota}{1.001}
+\registerctxluafile{font-otp}{1.001}
+\registerctxluafile{font-otc}{1.001}
+%registerctxluafile{font-vf} {1.001}
+\registerctxluafile{font-def}{1.001}
+%registerctxluafile{font-ctx}{1.001}
+\registerctxluafile{font-xtx}{1.001}
+%registerctxluafile{font-fbk}{1.001}
+%registerctxluafile{font-ext}{1.001}
+\registerctxluafile{font-pat}{1.001}
+%registerctxluafile{font-chk}{1.001}
+
+%registerctxluafile{math-ini}{1.001}
+%registerctxluafile{math-dim}{1.001}
+%registerctxluafile{math-ent}{1.001}
+%registerctxluafile{math-ext}{1.001}
+%registerctxluafile{math-vfu}{1.001}
+%registerctxluafile{math-map}{1.001}
+%registerctxluafile{math-noa}{1.001}
+
+\registerctxluafile{task-ini}{1.001}
+
+%registerctxluafile{l-xml}{1.001} % needed for font database
+
+% plain
+
+%loadcorefile{syst-stp.tex} % stripped plain
+
+% why not ...
+
+\pdfoutput\plusone
+
+% done
+
+\errorstopmode \dump \endinput
diff --git a/tex/context/base/mlib-ctx.lua b/tex/context/base/mlib-ctx.lua
index 6ada8ad19..8109003ca 100644
--- a/tex/context/base/mlib-ctx.lua
+++ b/tex/context/base/mlib-ctx.lua
@@ -14,8 +14,8 @@ local sprint = tex.sprint
metapost = metapost or {}
metapost.defaultformat = "metafun"
-function metapost.graphic(mpsformat,str,preamble)
- local mpx = metapost.format(mpsformat or metapost.defaultformat)
+function metapost.graphic(instance,mpsformat,str,preamble)
+ local mpx = metapost.format(instance,mpsformat or metapost.defaultformat)
metapost.graphic_base_pass(mpx,str,preamble)
end
@@ -29,7 +29,7 @@ function metapost.filterclippath(result)
for o=1,#objects do
local object = objects[o]
if object.type == "start_clip" then
- return join(flushnormalpath(object.path,{ }),"\n")
+ return join(metapost.flushnormalpath(object.path,{ }),"\n")
end
end
end
@@ -37,3 +37,13 @@ function metapost.filterclippath(result)
end
return ""
end
+
+statistics.register("metapost processing time", function()
+ local n = metapost.n
+ if n > 0 then
+ return format("%s seconds, loading: %s seconds, execution: %s seconds, n: %s",
+ statistics.elapsedtime(metapost), statistics.elapsedtime(mplib), statistics.elapsedtime(metapost.exectime),n)
+ else
+ return nil
+ end
+end)
diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua
index a12db3d82..9c5775a2d 100644
--- a/tex/context/base/mlib-pdf.lua
+++ b/tex/context/base/mlib-pdf.lua
@@ -6,10 +6,14 @@ if not modules then modules = { } end modules ['mlib-pdf'] = {
license = "see context related readme files",
}
-local format, join = string.format, table.concat
-local sprint = tex.sprint
+local format, concat = string.format, table.concat
+local texsprint = tex.sprint
local abs, sqrt, round = math.abs, math.sqrt, math.round
+local copy_node, write_node = node.copy, node.write
+
+local ctxcatcodes = tex.ctxcatcodes
+
metapost = metapost or { }
metapost.multipass = false
metapost.n = 0
@@ -52,35 +56,71 @@ function metapost.convert(result, trialrun, flusher, multipass)
return true -- done
end
-function metapost.comment(message)
- if message then
- sprint(tex.ctxcatcodes,format("\\MPLIBtoPDF{\\letterpercent\\space mps graphic %s: %s}", metapost.n, message))
+metapost.flushers = { }
+metapost.flushers.pdf = { }
+
+local savedliterals = nil
+
+local mpsliteral = nodes.register(node.new("whatsit",8))
+
+function metapost.flush_literal(d) -- \def\MPLIBtoPDF#1{\ctxlua{metapost.flush_literal(#1)}}
+ if savedliterals then
+ local literal = copy_node(mpsliteral)
+ literal.data = savedliterals[d]
+ write_node(literal)
+ else
+ logs.report("metapost","problem flushing literal %s",d)
end
end
-metapost.flushers = { }
-metapost.flushers.pdf = { }
+function metapost.flush_reset()
+ savedliterals = nil
+end
+
+function metapost.flushers.pdf.comment(message)
+ if message then
+ message = format("%% mps graphic %s: %s", metapost.n, message)
+ if savedliterals then
+ local last = #savedliterals + 1
+ savedliterals[last] = message
+ texsprint(ctxcatcodes,"\\MPLIBtoPDF{",last,"}")
+ else
+ savedliterals = { message }
+ texsprint(ctxcatcodes,"\\MPLIBtoPDF{1}")
+ end
+ end
+end
function metapost.flushers.pdf.startfigure(n,llx,lly,urx,ury,message)
+ savedliterals = nil
metapost.n = metapost.n + 1
- sprint(tex.ctxcatcodes,format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury))
- if message then metapost.comment(message) end
+ texsprint(ctxcatcodes,format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury))
+ if message then metapost.flushers.pdf.comment(message) end
end
function metapost.flushers.pdf.stopfigure(message)
- if message then metapost.comment(message) end
- sprint(tex.ctxcatcodes,"\\stopMPLIBtoPDF")
+ if message then metapost.flushers.pdf.comment(message) end
+ texsprint(ctxcatcodes,"\\stopMPLIBtoPDF")
+ texsprint(ctxcatcodes,"\\ctxlua{metapost.flush_reset()}") -- maybe just at the beginning
end
function metapost.flushers.pdf.flushfigure(pdfliterals) -- table
if #pdfliterals > 0 then
- sprint(tex.ctxcatcodes,"\\MPLIBtoPDF{",join(pdfliterals,"\n"),"}")
+ pdfliterals = concat(pdfliterals,"\n")
+ if savedliterals then
+ local last = #savedliterals + 1
+ savedliterals[last] = pdfliterals
+ texsprint(ctxcatcodes,"\\MPLIBtoPDF{",last,"}")
+ else
+ savedliterals = { pdfliterals }
+ texsprint(ctxcatcodes,"\\MPLIBtoPDF{1}")
+ end
end
end
function metapost.flushers.pdf.textfigure(font,size,text,width,height,depth) -- we could save the factor
text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost (i have to check if this is true for mplib)
- sprint(tex.ctxcatcodes,format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-number.dimenfactors.bp*depth))
+ texsprint(ctxcatcodes,format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-number.dimenfactors.bp*depth))
end
local bend_tolerance = 131/65536
@@ -99,15 +139,15 @@ local function pen_characteristics(object)
end
end
-local function concat(px, py) -- no tx, ty here
+local function mpconcat(px, py) -- no tx, ty here / we can move this one inline if needed
return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
end
local function curved(ith,pth)
local d = pth.left_x - ith.right_x
- if abs(ith.right_x-ith.x_coord-d) <= bend_tolerance and abs(pth.x_coord-pth.left_x-d) <= bend_tolerance then
+ if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
d = pth.left_y - ith.right_y
- if abs(ith.right_y-ith.y_coord-d) <= bend_tolerance and abs(pth.y_coord-pth.left_y-d) <= bend_tolerance then
+ if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
return false
end
end
@@ -148,33 +188,35 @@ local function flushconcatpath(path, t, open)
for i=1,#path do
pth = path[i]
if not ith then
- t[#t+1] = format("%f %f m",concat(pth.x_coord,pth.y_coord))
+ t[#t+1] = format("%f %f m",mpconcat(pth.x_coord,pth.y_coord))
elseif curved(ith,pth) then
- local a, b = concat(ith.right_x,ith.right_y)
- local c, d = concat(pth.left_x,pth.left_y)
- t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
+ local a, b = mpconcat(ith.right_x,ith.right_y)
+ local c, d = mpconcat(pth.left_x,pth.left_y)
+ t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,mpconcat(pth.x_coord,pth.y_coord))
else
- t[#t+1] = format("%f %f l",concat(pth.x_coord, pth.y_coord))
+ t[#t+1] = format("%f %f l",mpconcat(pth.x_coord, pth.y_coord))
end
ith = pth
end
if not open then
local one = path[1]
if curved(pth,one) then
- local a, b = concat(pth.right_x,pth.right_y)
- local c, d = concat(one.left_x,one.left_y)
- t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
+ local a, b = mpconcat(pth.right_x,pth.right_y)
+ local c, d = mpconcat(one.left_x,one.left_y)
+ t[#t+1] = format("%f %f %f %f %f %f c",a,b,c,d,mpconcat(one.x_coord, one.y_coord))
else
- t[#t+1] = format("%f %f l",concat(one.x_coord,one.y_coord))
+ t[#t+1] = format("%f %f l",mpconcat(one.x_coord,one.y_coord))
end
elseif #path == 1 then
-- special case .. draw point
local one = path[1]
- t[#t+1] = format("%f %f l",concat(one.x_coord,one.y_coord))
+ t[#t+1] = format("%f %f l",mpconcat(one.x_coord,one.y_coord))
end
return t
end
+metapost.flushnormalpath = flushnormalpath
+
metapost.specials = metapost.specials or { }
-- we have two extension handlers, one for pre and postscripts, and one for colors
@@ -287,7 +329,7 @@ function metapost.flush(result,flusher) -- pdf flusher, table en dan concat is s
end
local dl = currentobject.dash
if dl then
- local d = format("[%s] %i d",join(dl.dashes or {}," "),dl.offset)
+ local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset)
if d ~= dashed then
dashed = d
t[#t+1] = dashed
@@ -404,7 +446,7 @@ do
local flusher = {
startfigure = function()
t = { }
- sprint(tex.ctxcatcodes,"\\startnointerference")
+ texsprint(ctxcatcodes,"\\startnointerference")
end,
flushfigure = function(literals)
for i=1, #literals do
@@ -412,7 +454,7 @@ do
end
end,
stopfigure = function()
- sprint(tex.ctxcatcodes,"\\stopnointerference")
+ texsprint(ctxcatcodes,"\\stopnointerference")
end
}
@@ -428,9 +470,12 @@ function metapost.totable(result)
if figure then
local t = { }
local objects = figure:objects()
- for _, object in ipairs(objects) do
+ for o=1,#objects do
+ local object = objects[o]
local tt = { }
- for _, field in ipairs(mplib.fields(object)) do
+ local fields = mplib.fields(object)
+ for f=1,#fields do
+ local field = fields[f]
tt[field] = object[field]
end
t[#t+1] = tt
@@ -460,105 +505,3 @@ function metapost.colorconverter()
end
end
end
-
---~ -- obsolete code
---~
---~ -- the pen calculations are taken from metapost, first converted by
---~ -- taco from c to lua, and then optimized by hans, so all errors are his
---~
---~ local aspect_bound = 10/65536
---~ local aspect_default = 1/65536
---~ local eps = 0.0001
---~
---~ local function pyth(a,b)
---~ return sqrt(a*a + b*b) -- much faster than sqrt(a^2 + b^2)
---~ end
---~
---~ local function coord_range_x(h, dz) -- direction x
---~ local zlo, zhi = 0, 0
---~ for i=1, #h do
---~ local p = h[i]
---~ local z = p.x_coord
---~ if z < zlo then zlo = z elseif z > zhi then zhi = z end
---~ z = p.right_x
---~ if z < zlo then zlo = z elseif z > zhi then zhi = z end
---~ z = p.left_x
---~ if z < zlo then zlo = z elseif z > zhi then zhi = z end
---~ end
---~ return (zhi - zlo <= dz and aspect_bound) or aspect_default
---~ end
---~
---~ local function coord_range_y(h, dz) -- direction y
---~ local zlo, zhi = 0, 0
---~ for i=1, #h do
---~ local p = h[i]
---~ local z = p.y_coord
---~ if z < zlo then zlo = z elseif z > zhi then zhi = z end
---~ z = p.right_y
---~ if z < zlo then zlo = z elseif z > zhi then zhi = z end
---~ z = p.left_y
---~ if z < zlo then zlo = z elseif z > zhi then zhi = z end
---~ end
---~ return (zhi - zlo <= dz and aspect_bound) or aspect_default
---~ end
---~
---~ local function pen_characteristics(object)
---~ local p = object.pen[1]
---~ local x_coord, y_coord, left_x, left_y, right_x, right_y = p.x_coord, p.y_coord, p.left_x, p.left_y, p.right_x, p.right_y
---~ local wx, wy, width
---~ if right_x == x_coord and left_y == y_coord then
---~ wx = abs(left_x - x_coord)
---~ wy = abs(right_y - y_coord)
---~ else
---~ wx = pyth(left_x - x_coord, right_x - x_coord)
---~ wy = pyth(left_y - y_coord, right_y - y_coord)
---~ end
---~ if wy/coord_range_x(object.path, wx) >= wx/coord_range_y(object.path, wy) then
---~ width = wy
---~ else
---~ width = wx
---~ end
---~ sx, rx, ry, sy, tx, ty = left_x, left_y, right_x, right_y, x_coord, y_coord
---~ sx, rx, ry, sy = (sx-tx), (rx-ty), (ry-tx), (sy-ty) -- combine with previous
---~ if width ~= 1 then
---~ if width == 0 then
---~ sx, sy = 1, 1
---~ else
---~ rx, ry, sx, sy = rx/width, ry/width, sx/width, sy/width
---~ end
---~ end
---~ -- sx rx ry sy tx ty -> 1 0 0 1 0 0 is ok, but 0 0 0 0 0 0 not
---~ if true then
---~ if abs(sx) < eps then sx = eps end
---~ if abs(sy) < eps then sy = eps end
---~ else
---~ -- this block looks complicated but it only captures invalid transforms
---~ -- to be checked rx vs sx and so
---~ local det = sx/sy - ry/rx
---~ local aspect = 4*aspect_bound + aspect_default
---~ if abs(det) < aspect then
---~ local s
---~ if det >= 0 then
---~ s, aspect = 1, aspect - det
---~ else
---~ s, aspect = -1, -aspect - det -- - ?
---~ end
---~ local absrx, absry, abssy, abssx = abs(rx), abs(ry), abs(sy), abs(sx)
---~ if abssx + abssy >= absry + absrx then -- was yy
---~ if abssx > abssy then
---~ sy = sy + (aspect + s*abssx) / sx
---~ else
---~ sx = sx + (aspect + s*abssy) / sy
---~ end
---~ else
---~ if absry > absrx then
---~ rx = rx + (aspect + s*absry) / ry
---~ else
---~ ry = ry + (aspect + s*absrx) / rx
---~ end
---~ end
---~ end
---~ end
---~ divider = sx*sy - rx*ry
---~ return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), width
---~ end
diff --git a/tex/context/base/mlib-pdf.tex b/tex/context/base/mlib-pdf.tex
index b7b8506ad..9a04d188f 100644
--- a/tex/context/base/mlib-pdf.tex
+++ b/tex/context/base/mlib-pdf.tex
@@ -15,7 +15,9 @@
\registerctxluafile{mlib-pdf}{1.001}
-\let\MPLIBtoPDF\pdfliteral
+% \let\MPLIBtoPDF\pdfliteral
+
+\def\MPLIBtoPDF#1{\ctxlua{metapost.flush_literal(#1)}}
\def\MPLIBboundingbox#1#2#3#4%
{\xdef\MPllx{#1}%
@@ -26,7 +28,7 @@
\xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}}
\def\startMPLIBtoPDF#1#2#3#4% watch the transparency reset
- {\hbox\bgroup
+ {\naturalhbox\bgroup
\MPLIBboundingbox{#1}{#2}{#3}{#4}%
\forgetall
\setbox\scratchbox\vbox\bgroup
diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua
index 3d5187c0f..e210e4ee1 100644
--- a/tex/context/base/mlib-pps.lua
+++ b/tex/context/base/mlib-pps.lua
@@ -9,8 +9,13 @@ if not modules then modules = { } end modules ['mlib-pps'] = { -- prescript, pos
-- current limitation: if we have textext as well as a special color then due to
-- prescript/postscript overload we can have problems
-local format, concat, round = string.format, table.concat, math.round
+local format, gmatch, concat, round, match = string.format, string.gmatch, table.concat, math.round, string.match
local sprint = tex.sprint
+local tonumber, type = tonumber, type
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end)
colors = colors or { }
@@ -35,10 +40,11 @@ local colordata = { {}, {}, {}, {}, {} }
--~ => rest : r=123 g=n>10 b=whatever
function metapost.specials.register(str) -- only colors
- local size, content, n, class = str:match("^%%%%MetaPostSpecial: (%d+) (.*) (%d+) (%d+)$")
+ local size, content, n, class = match(str,"^%%%%MetaPostSpecial: (%d+) (.*) (%d+) (%d+)$")
if class then
+ -- use lpeg splitter
local data = { }
- for s in content:gmatch("[^ ]+") do
+ for s in gmatch(content,"[^ ]+") do
data[#data+1] = s
end
class, n = tonumber(class), tonumber(n)
@@ -110,7 +116,7 @@ function metapost.colorspec(cs)
end
function metapost.specials.tr(specification,object,result)
- local a, t = specification:match("^(.+),(.+)$")
+ local a, t = match(specification,"^(.+),(.+)$")
local before = a and t and function()
result[#result+1] = format("/Tr%s gs",transparencies.register('mp',a,t))
return object, result
@@ -122,23 +128,8 @@ function metapost.specials.tr(specification,object,result)
return object, before, nil, after
end
---~ -- possible speedup: hash registered colors
---~
---~ function metapost.specials.sp(specification,object,result) -- todo: color conversion
---~ local s = object.color[1]
---~ object.color = nil
---~ local before = function()
---~ local spec = specification:split(" ")
---~ ctx.registerspotcolor(spec[1])
---~ result[#result+1] = ctx.pdfcolor(colors.model,colors.register('color',nil,'spot',spec[1],spec[2],spec[3],s))
---~ return object, result
---~ end
---~ local after = function()
---~ result[#result+1] = "0 g 0 G"
---~ return object, result
---~ end
---~ return object, before, nil, nil
---~ end
+local specificationsplitter = lpeg.Ct(lpeg.splitat(" "))
+local colorsplitter = lpeg.Ct(lpeg.splitat(":"))
-- Unfortunately we cannot use cmyk colors natively because there is no
-- generic color allocation primitive ... it's just an rgbcolor color.. This
@@ -151,11 +142,11 @@ end
-- This is also an example of a simple plugin.
--~ function metapost.specials.cc(specification,object,result)
---~ object.color = specification:split(" ")
+--~ object.color = specificationsplitter:match(specification)
--~ return object, nil, nil, nil
--~ end
--~ function metapost.specials.cc(specification,object,result)
---~ local c = specification:split(" ")
+--~ local c = specificationsplitter:match(specification)
--~ local o = object.color[1]
--~ c[1],c[2],c[3],c[4] = o*c[1],o*c[2],o*c[3],o*c[4]
--~ return object, nil, nil, nil
@@ -176,7 +167,7 @@ function metapost.specials.fg(specification,object,result,flusher)
if sy == 0 then sy = 0.00001 end
local before = specification and function()
flusher.flushfigure(result)
- sprint(tex.ctxcatcodes,format("\\MPLIBfigure{%f}{%f}{%f}{%f}{%f}{%f}{%s}",sx,rx,ry,sy,tx,ty,specification))
+ sprint(ctxcatcodes,format("\\MPLIBfigure{%f}{%f}{%f}{%f}{%f}{%f}{%s}",sx,rx,ry,sy,tx,ty,specification))
return object, { }
end
return { } , before, nil, nil -- replace { } by object for tracing
@@ -210,22 +201,22 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color
nofshades = nofshades + 1
flusher.flushfigure(result)
result = { }
- local t = specification:split(" ")
+ local t = specificationsplitter:match(specification)
-- we need a way to move/scale
- local ca = t[4]:split(":")
- local cb = t[8]:split(":")
+ local ca = colorsplitter:match(t[4])
+ local cb = colorsplitter:match(t[8])
if round(ca[1]*10000) == 123 then ca = metapost.colorspec(ca) end
if round(cb[1]*10000) == 123 then cb = metapost.colorspec(cb) end
if type(ca) == "string" then
-- spot color, not supported, maybe at some point use the fallbacks
- sprint(tex.ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s %s %s}",
nofshades,
t[1], t[2], 0, 1, 1, "DeviceGray",
t[5], t[6], t[7], t[9], t[10], t[11]))
-- terrible hack, somehow does not work
--~ local a = ca:match("^([^ ]+)")
--~ local b = cb:match("^([^ ]+)")
---~ sprint(tex.ctxcatcodes,format("\\xMPLIBcircularshade{%s}{%s %s}{%s}{%s}{%s}{%s}{%s %s %s %s %s %s}",
+--~ sprint(ctxcatcodes,format("\\xMPLIBcircularshade{%s}{%s %s}{%s}{%s}{%s}{%s}{%s %s %s %s %s %s}",
--~ nofshades,
--~ --~ t[1], t[2], a, b, 1, "DeviceN",
--~ 0, 1, a, b, 1, "DeviceN",
@@ -250,7 +241,7 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color
ca[1], ca[2], ca[3] = a, a, a
cb[1], cb[2], cb[3] = b, b, b
end
- sprint(tex.ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f %.3f %.3f}{%.3f %.3f %.3f}{%s}{%s}{%s %s %s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f %.3f %.3f}{%.3f %.3f %.3f}{%s}{%s}{%s %s %s %s %s %s}",
nofshades,
t[1], t[2], ca[1], ca[2], ca[3], cb[1], cb[2], cb[3], 1, "DeviceRGB",
t[5], t[6], t[7], t[9], t[10], t[11]))
@@ -262,7 +253,7 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color
ca[1], ca[2], ca[3], ca[4] = 0, 0, 0, ca[1]
cb[1], cb[2], cb[3], ca[4] = 0, 0, 0, ca[1]
end
- sprint(tex.ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f %.3f %.3f %.3f}{%.3f %.3f %.3f %.3f}{%s}{%s}{%s %s %s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f %.3f %.3f %.3f}{%.3f %.3f %.3f %.3f}{%s}{%s}{%s %s %s %s %s %s}",
nofshades,
t[1], t[2], ca[1], ca[2], ca[3], ca[4], cb[1], cb[2], cb[3], cb[4], 1, "DeviceCMYK",
t[5], t[6], t[7], t[9], t[10], t[11]))
@@ -274,7 +265,7 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color
ca[1] = rgbtogray(ca[1],ca[2],ca[3])
cb[1] = rgbtogray(cb[1],cb[2],cb[3])
end
- sprint(tex.ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBcircularshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s %s %s}",
nofshades,
t[1], t[2], ca[1], cb[1], 1, "DeviceGray",
t[5], t[6], t[7], t[9], t[10], t[11]))
@@ -296,15 +287,15 @@ function metapost.specials.ls(specification,object,result,flusher)
nofshades = nofshades + 1
flusher.flushfigure(result)
result = { }
- local t = specification:split(" ")
+ local t = specificationsplitter:match(specification)
-- we need a way to move/scale
- local ca = t[4]:split(":")
- local cb = t[7]:split(":")
+ local ca = colorsplitter:match(t[4])
+ local cb = colorsplitter:match(t[7])
if round(ca[1]*10000) == 123 then ca = metapost.colorspec(ca) end
if round(cb[1]*10000) == 123 then cb = metapost.colorspec(cb) end
if type(ca) == "string" then
-- spot color, not supported, maybe at some point use the fallbacks
- sprint(tex.ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s}",
nofshades,
t[1], t[2], 0, 1, 1, "DeviceGray",
t[5], t[6], t[8], t[9]))
@@ -327,7 +318,7 @@ function metapost.specials.ls(specification,object,result,flusher)
ca[1], ca[2], ca[3] = a, a, a
cb[1], cb[2], cb[3] = b, b, b
end
- sprint(tex.ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f %.3f %.3f}{%.3f %.3f %.3f}{%s}{%s}{%s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f %.3f %.3f}{%.3f %.3f %.3f}{%s}{%s}{%s %s %s %s}",
nofshades,
t[1], t[2], ca[1], ca[2], ca[3], cb[1], cb[2], cb[3], 1, "DeviceRGB",
t[5], t[6], t[8], t[9]))
@@ -339,7 +330,7 @@ function metapost.specials.ls(specification,object,result,flusher)
ca[1], ca[2], ca[3], ca[4] = 0, 0, 0, ca[1]
cb[1], cb[2], cb[3], ca[4] = 0, 0, 0, ca[1]
end
- sprint(tex.ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f %.3f %.3f %.3f}{%.3f %.3f %.3f %.3f}{%s}{%s}{%s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f %.3f %.3f %.3f}{%.3f %.3f %.3f %.3f}{%s}{%s}{%s %s %s %s}",
nofshades,
t[1], t[2], ca[1], ca[2], ca[3], ca[4], cb[1], cb[2], cb[3], cb[4], 1, "DeviceCMYK",
t[5], t[6], t[8], t[9]))
@@ -351,7 +342,7 @@ function metapost.specials.ls(specification,object,result,flusher)
ca[1] = rgbtogray(ca[1],ca[2],ca[3])
cb[1] = rgbtogray(cb[1],cb[2],cb[3])
end
- sprint(tex.ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s}",
+ sprint(ctxcatcodes,format("\\MPLIBlinearshade{%s}{%s %s}{%.3f}{%.3f}{%s}{%s}{%s %s %s %s}",
nofshades,
t[1], t[2], ca[1], cb[1], 1, "DeviceGray",
t[5], t[6], t[8], t[9]))
@@ -373,10 +364,9 @@ end
local current_format, current_graphic
---~ metapost.first_box, metapost.last_box = 1000, 1100
-
+metapost.first_box = metapost.first_box or 1000
+metapost.last_box = metapost.last_box or 1100
metapost.textext_current = metapost.first_box
-metapost.trace_texttexts = false
metapost.multipass = false
function metapost.free_boxes()
@@ -393,49 +383,55 @@ end
function metapost.specials.tf(specification,object)
--~ print("setting", metapost.textext_current)
- local n, str = specification:match("^(%d+):(.+)$")
- if metapost.textext_current < metapost.last_box then
- metapost.textext_current = metapost.first_box + n - 1
- end
- if metapost.trace_texttexts then
- print("metapost", format("first pass: order %s, box %s",n,metapost.textext_current))
+ local n, str = match(specification,"^(%d+):(.+)$")
+ if n and str then
+ if metapost.textext_current < metapost.last_box then
+ metapost.textext_current = metapost.first_box + n - 1
+ end
+ if trace_textexts then
+ logs.report("metapost","first pass: order %s, box %s",n,metapost.textext_current)
+ end
+ sprint(ctxcatcodes,format("\\MPLIBsettext{%s}{%s}",metapost.textext_current,str))
+ metapost.multipass = true
end
- sprint(tex.ctxcatcodes,format("\\MPLIBsettext{%s}{%s}",metapost.textext_current,str))
- metapost.multipass = true
return { }, nil, nil, nil
end
function metapost.specials.ts(specification,object,result,flusher)
-- print("getting", metapost.textext_current)
- local n, str = specification:match("^(%d+):(.+)$")
- if metapost.trace_texttexts then
- print("metapost", format("second pass: order %s, box %s",n,metapost.textext_current))
- end
- local op = object.path
- local first, second, fourth = op[1], op[2], op[4]
- local tx, ty = first.x_coord , first.y_coord
- local sx, sy = second.x_coord - tx, fourth.y_coord - ty
- local rx, ry = second.y_coord - ty, fourth.x_coord - tx
- if sx == 0 then sx = 0.00001 end
- if sy == 0 then sy = 0.00001 end
- if not metapost.trace_texttexts then
- object.path = nil
- end
- local before = function() -- no need for function
- --~ flusher.flushfigure(result)
- --~ sprint(tex.ctxcatcodes,format("\\MPLIBgettext{%f}{%f}{%f}{%f}{%f}{%f}{%s}",sx,rx,ry,sy,tx,ty,metapost.textext_current))
- --~ result = { }
- result[#result+1] = format("q %f %f %f %f %f %f cm", sx,rx,ry,sy,tx,ty)
- flusher.flushfigure(result)
- if metapost.textext_current < metapost.last_box then
- metapost.textext_current = metapost.first_box + n - 1
+ local n, str = match(specification,"^(%d+):(.+)$")
+ if n and str then
+ if trace_textexts then
+ logs.report("metapost","second pass: order %s, box %s",n,metapost.textext_current)
end
- local b = metapost.textext_current
- sprint(tex.ctxcatcodes,format("\\MPLIBgettextscaled{%s}{%s}{%s}",b, metapost.sxsy(tex.wd[b],tex.ht[b],tex.dp[b])))
- result = { "Q" }
- return object, result
+ local op = object.path
+ local first, second, fourth = op[1], op[2], op[4]
+ local tx, ty = first.x_coord , first.y_coord
+ local sx, sy = second.x_coord - tx, fourth.y_coord - ty
+ local rx, ry = second.y_coord - ty, fourth.x_coord - tx
+ if sx == 0 then sx = 0.00001 end
+ if sy == 0 then sy = 0.00001 end
+ if not trace_textexts then
+ object.path = nil
+ end
+ local before = function() -- no need for function
+ --~ flusher.flushfigure(result)
+ --~ sprint(ctxcatcodes,format("\\MPLIBgettext{%f}{%f}{%f}{%f}{%f}{%f}{%s}",sx,rx,ry,sy,tx,ty,metapost.textext_current))
+ --~ result = { }
+ result[#result+1] = format("q %f %f %f %f %f %f cm", sx,rx,ry,sy,tx,ty)
+ flusher.flushfigure(result)
+ if metapost.textext_current < metapost.last_box then
+ metapost.textext_current = metapost.first_box + n - 1
+ end
+ local b = metapost.textext_current
+ sprint(ctxcatcodes,format("\\MPLIBgettextscaled{%s}{%s}{%s}",b, metapost.sxsy(tex.wd[b],tex.ht[b],tex.dp[b])))
+ result = { "Q" }
+ return object, result
+ end
+ return { }, before, nil, nil -- replace { } by object for tracing
+ else
+ return { }, nil, nil, nil -- replace { } by object for tracing
end
- return { }, before, nil, nil -- replace { } by object for tracing
end
function metapost.colorconverter()
@@ -689,24 +685,25 @@ do
end
---~ local factor = 65536*(7200/7227)
local factor = 65536*(7227/7200)
function metapost.edefsxsy(wd,ht,dp) -- helper for figure
- commands.edef("sx",(wd ~= 0 and 1/( wd /(factor))) or 0)
- commands.edef("sy",(wd ~= 0 and 1/((ht+dp)/(factor))) or 0)
+ local hd = ht + dp
+ commands.edef("sx",(wd ~= 0 and factor/wd) or 0)
+ commands.edef("sy",(hd ~= 0 and factor/hd) or 0)
end
function metapost.sxsy(wd,ht,dp) -- helper for text
- return (wd ~= 0 and 1/(wd/(factor))) or 0, (wd ~= 0 and 1/((ht+dp)/(factor))) or 0
+ local hd = ht + dp
+ return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0
end
function metapost.text_texts_data()
local t, n = { }, 0
for i = metapost.first_box, metapost.last_box do
n = n + 1
- if metapost.trace_texttexts then
- print("metapost", format("passed data: order %s, box %s",n,i))
+ if trace_textexts then
+ logs.report("metapost","passed data: order %s, box %s",n,i)
end
if tex.box[i] then
t[#t+1] = format("_tt_w_[%i]:=%f;_tt_h_[%i]:=%f;_tt_d_[%i]:=%f;", n,tex.wd[i]/factor, n,tex.ht[i]/factor, n,tex.dp[i]/factor)
@@ -740,7 +737,7 @@ function metapost.graphic_base_pass(mpsformat,str,preamble)
local flushed = metapost.process(mpsformat, {
preamble,
"beginfig(1); ",
- "_trial_run_ := true ;",
+ "if unknown _trial_run_ : boolean _trial_run_ fi ; _trial_run_ := true ;",
str,
"endfig ;"
-- }, true, nil, true )
@@ -753,7 +750,7 @@ function metapost.graphic_base_pass(mpsformat,str,preamble)
if not flushed or not metapost.optimize then
-- tricky, we can only ask once for objects and therefore
-- we really need a second run when not optimized
- sprint(tex.ctxcatcodes,"\\ctxlua{metapost.graphic_extra_pass()}")
+ sprint(ctxcatcodes,"\\ctxlua{metapost.graphic_extra_pass()}")
end
else
metapost.process(mpsformat, {
@@ -782,17 +779,17 @@ end
function metapost.getclippath(data)
local mpx = metapost.format("metafun")
if mpx and data then
- input.starttiming(metapost)
- input.starttiming(metapost.exectime)
+ statistics.starttiming(metapost)
+ statistics.starttiming(metapost.exectime)
local result = mpx:execute(format("beginfig(1);%s;endfig;",data))
- input.stoptiming(metapost.exectime)
+ statistics.stoptiming(metapost.exectime)
if result.status > 0 then
print("error", result.status, result.error or result.term or result.log)
result = ""
else
result = metapost.filterclippath(result)
end
- input.stoptiming(metapost)
+ statistics.stoptiming(metapost)
sprint(result)
end
end
@@ -842,7 +839,7 @@ do -- not that beautiful but ok, we could save a md5 hash in the tui file !
local result = { }
if io.exists(mpyfile) then
local data = io.loaddata(mpyfile)
- for figure in data:gmatch("beginfig(.-)endfig") do
+ for figure in gmatch(data,"beginfig(.-)endfig") do
result[#result+1] = format("begingraphictextfig%sendgraphictextfig ;\n", figure)
end
io.savedata(mpyfile,concat(result,""))
diff --git a/tex/context/base/mlib-pps.tex b/tex/context/base/mlib-pps.tex
index 546b94f28..beaef044e 100644
--- a/tex/context/base/mlib-pps.tex
+++ b/tex/context/base/mlib-pps.tex
@@ -20,11 +20,6 @@
\immediate\pdfobj{<</ShadingType 3 /ColorSpace /#6 /Function \the\pdflastobj\space 0 R /Coords [#7] /Extend [true true]>>}%
\appendtoPDFdocumentshades{/MpSh#1 \the\pdflastobj\space0 R }}
-% \def\xMPLIBcircularshade#1#2#3#4#5#6#7% nr domain color-a color-b ? colorspace oordinates
-% {\immediate\pdfobj{<</FunctionType 2 /Domain [#2] /C0 #3 /C1 #4 /N #5>>}%
-% \immediate\pdfobj{<</ShadingType 3 /ColorSpace /#6 /Function \the\pdflastobj\space 0 R /Coords [#7] /Extend [true true]>>}%
-% \appendtoPDFdocumentshades{/MpSh#1 \the\pdflastobj\space0 R }}
-
\def\MPLIBlinearshade#1#2#3#4#5#6#7% nr domain color-a color-b ? colorspace oordinates
{\immediate\pdfobj{<</FunctionType 2 /Domain [#2] /C0 [#3] /C1 [#4] /N #5>>}%
\immediate\pdfobj{<</ShadingType 2 /ColorSpace /#6 /Function \the\pdflastobj\space 0 R /Coords [#7] /Extend [true true]>>}%
@@ -50,20 +45,17 @@
% \pdfliteral{Q}}
\def\MPLIBgettextscaled#1#2#3%
- {\vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[sx=#2,sy=#3]{\raise\dp#1\copy#1}\hss}}}
+ {\vbox to \zeropoint{\vss\hbox to \zeropoint{\black\scale[sx=#2,sy=#3]{\raise\dp#1\copy#1}\hss}}}
\def\MPLIBallocate#1%
{\newbox\MPLIBfirst
- \dorecurse{\numexpr#1-1\relax}{\newbox\MPLIBlast}%
+ \dorecurse{\numexpr#1-1\relax}{\let\MPLIBlast\relax\newbox\MPLIBlast}%
\MPLIBregister}
-\def\MPLIBregister
+\def\MPLIBregister % after allocate!
{\ctxlua{metapost.first_box, metapost.last_box = \number\MPLIBfirst, \number\MPLIBlast}}
-\appendtoks \MPLIBallocate{1000}\to \everydump
-\appendtoks \MPLIBregister \to \everyjob
-
\def\MPLIBgraphictext#1%
- {\startTEXpage[scale=10000]#1\stopTEXpage}
+ {\startTEXpage[\c!scale=10000]#1\stopTEXpage}
\protect \endinput
diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua
index 1edd00be7..9a7ed6f39 100644
--- a/tex/context/base/mlib-run.lua
+++ b/tex/context/base/mlib-run.lua
@@ -23,7 +23,7 @@ if not modules then modules = { } end modules ['mlib-run'] = {
<p>The directional helpers and pen analysis are more or less translated from the
<l n='c'/> code. It really helps that Taco know that source so well. Taco and I spent
quite some time on speeding up the <l n='lua'/> and <l n='c'/> code. There is not
-much to gain, especially if on ekeeps in mind that when integrated in <l n='tex'/>
+much to gain, especially if one keeps in mind that when integrated in <l n='tex'/>
only a part of the time is spent in <l n='metapost'/>. Of course an integrated
approach is way faster than an external <l n='metapost'/> and processing time
nears zero.</p>
@@ -33,13 +33,20 @@ local format = string.format
metapost = metapost or { }
+metapost.showlog = false
+metapost.lastlog = ""
+
+function metapost.resetlastlog()
+ metapost.lastlog = ""
+end
+
local function finder(name, mode, ftype)
if mode=="w" then
return name
- elseif input.aux.qualified_path(name) then
+ elseif file.is_qualified_path(name) then
return name
else
- return input.find_file(name,ftype)
+ return resolvers.find_file(name,ftype)
end
end
@@ -80,27 +87,27 @@ input %s ; dump ;
end
function metapost.make(name, target, version)
- input.starttiming(mplib)
+ statistics.starttiming(mplib)
target = file.replacesuffix(target or name, "mem")
local mpx = mplib.new ( table.merged (
metapost.parameters,
{
ini_version = true,
find_file = finder,
- job_name = file.stripsuffix(target),
+ job_name = file.removesuffix(target),
}
) )
if mpx then
- input.starttiming(metapost.exectime)
+ statistics.starttiming(metapost.exectime)
local result = mpx:execute(format(preamble,version or "unknown",name))
- input.stoptiming(metapost.exectime)
+ statistics.stoptiming(metapost.exectime)
mpx:finish()
end
- input.stoptiming(mplib)
+ statistics.stoptiming(mplib)
end
function metapost.load(name)
- input.starttiming(mplib)
+ statistics.starttiming(mplib)
local mpx = mplib.new ( table.merged (
metapost.parameters,
{
@@ -111,24 +118,24 @@ function metapost.load(name)
) )
local result
if mpx then
-if not mplib.pen_info then -- temp compatibility hack
- input.starttiming(metapost.exectime)
- result = mpx:execute("\\")
- input.stoptiming(metapost.exectime)
-end
+ if not mplib.pen_info then -- temp compatibility hack
+ statistics.starttiming(metapost.exectime)
+ result = mpx:execute("\\")
+ statistics.stoptiming(metapost.exectime)
+ end
else
result = { status = 99, error = "out of memory"}
end
- input.stoptiming(mplib)
+ statistics.stoptiming(mplib)
return mpx, result
end
function metapost.unload(mpx)
- input.starttiming(mplib)
+ statistics.starttiming(mplib)
if mpx then
mpx:finish()
end
- input.stoptiming(mplib)
+ statistics.stoptiming(mplib)
end
function metapost.reporterror(result)
@@ -143,6 +150,7 @@ function metapost.reporterror(result)
metapost.report("mp error: %s",(e=="" and "?") or e)
end
if not t and not e and l then
+ metapost.lastlog = metapost.lastlog .. "\n" .. l
metapost.report("mp log: %s",l)
else
metapost.report("mp error: unknown, no error, terminal or log messages")
@@ -153,21 +161,21 @@ function metapost.reporterror(result)
return true
end
-function metapost.checkformat(mpsinput, mpsformat)
+function metapost.checkformat(mpsinput, mpsformat, dirname)
mpsinput = file.addsuffix(mpsinput or "metafun", "mp")
- mpsformat = file.stripsuffix(file.basename(mpsformat or texconfig.formatname or tex.formatname or mpsinput))
- local mpsbase = file.stripsuffix(file.basename(mpsinput))
+ mpsformat = file.removesuffix(file.basename(mpsformat or texconfig.formatname or (tex and tex.formatname) or mpsinput))
+ local mpsbase = file.removesuffix(file.basename(mpsinput))
if mpsbase ~= mpsformat then
mpsformat = mpsformat .. "-" .. mpsbase
end
mpsformat = file.addsuffix(mpsformat, "mem")
- local pth = file.dirname(texconfig.formatname or "")
+ local pth = dirname or file.dirname(texconfig.formatname or "")
if pth ~= "" then
mpsformat = file.join(pth,mpsformat)
end
local the_version = environment.version or "unset version"
if lfs.isfile(mpsformat) then
- commands.writestatus("mplib","loading format: %s, name: %s", mpsinput, mpsformat)
+ commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformat)
local mpx, result = metapost.load(mpsformat)
if mpx then
local result = mpx:execute("show mp_parent_version ;")
@@ -183,31 +191,28 @@ function metapost.checkformat(mpsinput, mpsformat)
end
end
else
- commands.writestatus("mplib","error in loading format: %s, name: %s", mpsinput, mpsformat)
+ commands.writestatus("mplib","error in loading '%s' from '%s'", mpsinput, mpsformat)
metapost.reporterror(result)
end
end
- commands.writestatus("mplib","making format: %s, name: %s", mpsinput, mpsformat)
+ commands.writestatus("mplib","making '%s' into '%s'", mpsinput, mpsformat)
metapost.make(mpsinput,mpsformat,the_version) -- somehow return ... fails here
if lfs.isfile(mpsformat) then
- commands.writestatus("mplib","loading format: %s, name: %s", mpsinput, mpsformat)
+ commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformat)
return metapost.load(mpsformat)
else
- commands.writestatus("mplib","problems with format: %s, name: %s", mpsinput, mpsformat)
+ commands.writestatus("mplib","problems with '%s' from '%s'", mpsinput, mpsformat)
end
end
---~ if environment.initex then
---~ metapost.unload(metapost.checkformat("metafun"))
---~ end
-
-local mpxformats = {}
+local mpxformats = { }
-function metapost.format(name)
- local mpx = mpxformats[name]
+function metapost.format(instance,name)
+ name = name or instance
+ local mpx = mpxformats[instance]
if not mpx then
mpx = metapost.checkformat(name)
- mpxformats[name] = mpx
+ mpxformats[instance] = mpx
end
return mpx
end
@@ -231,26 +236,25 @@ function metapost.reset(mpx)
end
end
-metapost.showlog = false
-
function metapost.process(mpx, data, trialrun, flusher, multipass)
local converted, result = false, {}
if type(mpx) == "string" then
mpx = metapost.format(mpx) -- goody
end
if mpx and data then
- input.starttiming(metapost)
+ statistics.starttiming(metapost)
if type(data) == "table" then
for i=1,#data do
local d = data[i]
if d then
- input.starttiming(metapost.exectime)
+ statistics.starttiming(metapost.exectime)
result = mpx:execute(d)
- input.stoptiming(metapost.exectime)
+ statistics.stoptiming(metapost.exectime)
if not metapost.reporterror(result) then
if metapost.showlog then
local str = (result.term ~= "" and result.term) or "no terminal output"
if not str:is_empty() then
+ metapost.lastlog = metapost.lastlog .. "\n" .. str
metapost.report("mp log: %s",str)
end
end
@@ -263,21 +267,25 @@ function metapost.process(mpx, data, trialrun, flusher, multipass)
end
end
else
- input.starttiming(metapost.exectime)
+ statistics.starttiming(metapost.exectime)
result = mpx:execute(data)
- input.stoptiming(metapost.exectime)
+ statistics.stoptiming(metapost.exectime)
-- todo: error message
if not result then
metapost.report("mp error: no result object returned")
elseif result.status > 0 then
metapost.report("mp error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error"))
- elseif metapost.showlog then
- metapost.report("mp info: %s",result.term or "no-term")
- elseif result.fig then
- converted = metapost.convert(result, trialrun, flusher, multipass)
+ else
+ if metapost.showlog then
+ metapost.lastlog = metapost.lastlog .. "\n" .. result.term
+ metapost.report("mp info: %s",result.term or "no-term")
+ end
+ if result.fig then
+ converted = metapost.convert(result, trialrun, flusher, multipass)
+ end
end
end
- input.stoptiming(metapost)
+ statistics.stoptiming(metapost)
end
return converted, result
end
@@ -289,3 +297,64 @@ end
function metapost.report(...)
logs.report("mplib",...)
end
+
+-- handy
+
+function metapost.directrun(formatname,filename,outputformat,astable,mpdata)
+ local fullname = file.addsuffix(filename,"mp")
+ local data = mpdata or io.loaddata(fullname)
+ if outputformat ~= "svg" then
+ outputformat = "mps"
+ end
+ if not data then
+ logs.simple("unknown file '%s'",filename or "?")
+ else
+ local mpx = metapost.checkformat(formatname,formatname,caches.setpath("formats"))
+ if not mpx then
+ logs.simple("unknown format '%s'",formatname or "?")
+ else
+ logs.simple("processing '%s'",(mpdata and (filename or "data")) or fullname)
+ local result = mpx:execute(data)
+ if not result then
+ logs.simple("error: no result object returned")
+ elseif result.status > 0 then
+ logs.simple("error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error"))
+ else
+ if metapost.showlog then
+ metapost.lastlog = metapost.lastlog .. "\n" .. result.term
+ logs.simple("info: %s",result.term or "no-term")
+ end
+ local figures = result.fig
+ if figures then
+ local sorted = table.sortedkeys(figures)
+ if astable then
+ local result = { }
+ logs.simple("storing %s figures in table",#sorted)
+ for k, v in ipairs(sorted) do
+ if outputformat == "mps" then
+ result[v] = figures[v]:postscript()
+ else
+ result[v] = figures[v]:svg() -- (3) for prologues
+ end
+ end
+ return result
+ else
+ local basename = file.removesuffix(file.basename(filename))
+ for k, v in ipairs(sorted) do
+ local output
+ if outputformat == "mps" then
+ output = figures[v]:postscript()
+ else
+ output = figures[v]:svg() -- (3) for prologues
+ end
+ local outname = format("%s-%s.%s",basename,v,outputformat)
+ logs.simple("saving %s bytes in '%s'",#output,outname)
+ io.savedata(outname,output)
+ end
+ return #sorted
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/tex/context/base/mtx-context-arrange.tex b/tex/context/base/mtx-context-arrange.tex
new file mode 100644
index 000000000..9d0bb901b
--- /dev/null
+++ b/tex/context/base/mtx-context-arrange.tex
@@ -0,0 +1,105 @@
+% engine=luatex
+
+%D \module
+%D [ file=mtx-context-arrange,
+%D version=2009.03.21,
+%D title=\CONTEXT\ Extra Trickry,
+%D subtitle=Arrange Files,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 \TEXEXEC\ features that has been moved to \MKIV.
+
+% begin help
+%
+% usage: context --extra=arrange [options] list-of-files
+%
+% --sort : sort filenames first
+% --paperoffset=dimension : left-top-offset
+% --noduplex : singlesided (doublesided is default)
+% --backspace=dimension : extra left offset
+% --topspace=dimension : extra top offset
+% --marking : add cutmarks
+% --addempty=list : add empty pages at/after (comma separated list)
+% --printformat : 2UP, etc
+%
+% end help
+
+\doifdocumentargument {paperoffset} {
+ \definepapersize
+ [offset=\getdocumentargument{paperoffset}]
+}
+
+\doifdocumentargumentelse {noduplex} {yes} {
+ \setuppagenumbering
+ [alternative=doublesided]
+ \setdocumentargument{sided}{doublesided}
+} {
+ \setdocumentargument{sided}{singlesided}
+}
+
+\setdefaultdocumentargument {textwidth} {0cm}
+\setdefaultdocumentargument {backspace} {0cm}
+\setdefaultdocumentargument {topspace} {0cm}
+
+\setuplayout
+ [backspace=\getdocumentargument{backspace},
+ topspace=\getdocumentargument{topspace},
+ width=middle,
+ height=middle,
+ location=middle,
+ header=0pt,
+ footer=0pt]
+
+\doifdocumentargument {marking} {yes} {
+ \setuplayout
+ [marking=on]
+}
+
+\startluacode
+ local printformat = document.arguments.printformat or ""
+ if printformat == "" then
+ printformat = "normal"
+ elseif string.find(printformat,".*up") then
+ printformat = "2UP,\\v!rotated"
+ elseif string.find(printformat,".*down") then
+ printformat = "2DOWN,\\v!rotated"
+ elseif string.find(printformat,".*side") then
+ printformat = "2SIDE,\\v!rotated"
+ end
+ document.setargument("printformat",printformat)
+\stopluacode
+
+\setuparranging
+ [\getdocumentargument{sided},
+ \getdocumentargument{printformat}]
+
+\starttext
+
+\startluacode
+ local format = string.format
+ local fprint = function(...) tex.sprint(tex.ctxcatcodes,format(...)) end
+
+ if #document.files > 0 then
+ if document.arguments.sort then
+ table.sort(document.files)
+ end
+ local emptypages = document.arguments.addempty or ""
+ local textwidth = document.arguments.textwidth or "0cm"
+ for _, filename in ipairs(document.files) do
+ if not string.find(filename,"^mtx%-context%-") then
+ fprint("\\insertpages[%s][%s][width=%s]",filename,emptypages,textwidth)
+ end
+ end
+ else
+ fprint("no files given")
+ end
+\stopluacode
+
+\stoptext
+
diff --git a/tex/context/base/mtx-context-combine.tex b/tex/context/base/mtx-context-combine.tex
new file mode 100644
index 000000000..991e974ae
--- /dev/null
+++ b/tex/context/base/mtx-context-combine.tex
@@ -0,0 +1,146 @@
+% engine=luatex
+
+%D \module
+%D [ file=mtx-context-combine,
+%D version=2009.03.21,
+%D title=\CONTEXT\ Extra Trickry,
+%D subtitle=Combine Files,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 \TEXEXEC\ features that has been moved to \MKIV.
+
+% begin help
+%
+% usage: context --extra=combine [options] list-of-files
+%
+% --sort : sort filenames first
+% --paperoffset=dimension : left-top-offset
+% --nobanner : no footer etc
+% --combination : h*v or hxv
+% --paperformat : paper*print or paperxprint
+% --nobanner : no footerlines
+% --bannerheight : height of banner
+% --bannerstring : height of bannerstring
+%
+% end help
+
+\doifdocumentargumentelse {paperoffset} {
+
+ \setuplayout
+ [topspace=\getdocumentargument{paperoffset},
+ backspace=\getdocumentargument{paperoffset}]
+
+} {
+
+ \setuplayout
+ [topspace=0pt,
+ backspace=0pt]
+
+}
+
+\setuplayout
+ [header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\startluacode
+ local combination = document.arguments['combination'] or '2*2'
+ local nx, ny = string.match(combination,"^(%d+)%s*[%*x]%s*(%d+)$")
+ if not nx then
+ nx, ny = 2, 2
+ elseif not ny then
+ nx = tonumber(combination) or 2
+ ny = nx
+ else
+ nx = tonumber(nx) or 2
+ ny = tonumber(ny) or nx or 2
+ end
+ document.setargument("nx",nx)
+ document.setargument("ny",ny)
+\stopluacode
+
+\startluacode
+ local paperformat = document.arguments['paperformat'] or 'A4*A4'
+ paperformat = string.upper(paperformat)
+ local f, t = string.match(paperformat,"^(.-)%s*[%*xX]%s*(.-)$")
+ if not f then
+ f, t = "A4", "A4"
+ elseif not t then
+ t = f
+ end
+ document.setargument("from",f)
+ document.setargument("to",t)
+\stopluacode
+
+\setuppapersize
+ [\getdocumentargument{from}]
+ [\getdocumentargument{to}]
+
+\doifnotdocumentargument {bannerheight} {
+ \setuplayout
+ [footer=1cm]
+}
+
+\doifdocumentargumentelse {nobanner} {yes} {
+ \setuplayout
+ [footer=0cm]
+ \setupbackgrounds
+ [page]
+ [background=]
+} {
+ \definelayer
+ [page]
+ [width=\paperwidth,
+ height=\paperheight]
+
+ \setupbackgrounds
+ [page]
+ [background=page]
+}
+
+\setupexternalfigures
+ [directory=]
+
+\starttext
+
+\startluacode
+ local format = string.format
+ local fprint = function(...) tex.sprint(tex.ctxcatcodes,format(...)) end
+
+ if #document.files > 0 then
+ if document.arguments["sort"] then
+ table.sort(document.files)
+ end
+ local dobanner = not document.arguments["nobanner"]
+ local bannerheight = document.arguments["bannerheight"]
+ local nx = document.arguments.nx or 2
+ local ny = document.arguments.ny or 2
+ for _, filename in ipairs(document.files) do
+ if not string.find(filename,"^mtx%-context%-") then
+ -- could be a macro
+ local bannerstring = format("\\tttf\\detokenize{%s}\\quad\\quad\\currentdate\\quad\\quad\\pagenumber",file.basename(filename))
+ if dobanner then
+ if bannerheight then
+ fprint("\\setuptexttexts[{\\setlayerframed[page][preset=middlebottom][frame=off,height=%s]{%s}}]",bannerheight,bannerstring)
+ else
+ fprint("\\setupfootertexts[{%s}]",bannerstring)
+ end
+ end
+ fprint("\\combinepages[%s][nx=%s,ny=%s]",filename,nx,ny)
+ fprint("\\page")
+ end
+ end
+ else
+ fprint("no files given")
+ end
+\stopluacode
+
+\stoptext
+
diff --git a/tex/context/base/mtx-context-ideas.tex b/tex/context/base/mtx-context-ideas.tex
new file mode 100644
index 000000000..f1ef1d35f
--- /dev/null
+++ b/tex/context/base/mtx-context-ideas.tex
@@ -0,0 +1,54 @@
+% engine=luatex
+
+%D \module
+%D [ file=mtx-context-ideas,
+%D version=2009.03.21,
+%D title=\CONTEXT\ Extra Trickry,
+%D subtitle=Placeholder File,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% The hard coded goodies in texexec are now external. We also use this
+% opportunity to explore mixed tex/lua user interfacing so you will see
+% some old and new tricks here that might disappear or become extended.
+%
+% if users want to add their own ... go ahead but use a different
+% namespace:
+%
+% mtx-context-third-somename.tex
+% mtx-context-user-somename.tex
+
+% \startluacode
+% -- some day we might move the whole ui to lua
+% context = context or { }
+% function interfaces.tosetups(setups)
+% if not setups then
+% return ""
+% elseif type(setups) == "table" then
+% local t = { }
+% for k,v in next, setups do
+% t[k] = "{" .. v .. "}"
+% end
+% return table.concat(t,",")
+% else
+% return setups
+% end
+% end
+% function context.setuplayout(category,setups)
+% setups = setups or category
+% tex.sprint(string.format("\\setuplayout[%s]",interfaces.tosetups(setups))
+% end
+% local topspace = document.arguments["topspace"] or 0
+% if dimen(topspace) > dimen(0) then
+% context.setuplayout { topspace = dimen(topspace) }
+% end
+% local backspace = document.arguments["backspace"] or 0
+% if dimen(topspace) > dimen(0) then
+% context.setuplayout { backspace = dimen(backspace) }
+% end
+% \stopluacode
diff --git a/tex/context/base/mtx-context-listing.tex b/tex/context/base/mtx-context-listing.tex
new file mode 100644
index 000000000..5c978fc6a
--- /dev/null
+++ b/tex/context/base/mtx-context-listing.tex
@@ -0,0 +1,76 @@
+% engine=luatex
+
+%D \module
+%D [ file=mtx-context-listing,
+%D version=2008.11.10, % about that time i started playing with this
+%D title=\CONTEXT\ Extra Trickry,
+%D subtitle=Listing Files,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 \TEXEXEC\ features that has been moved to \MKIV.
+
+% begin help
+%
+% usage: context --extra=listing [options] list-of-files
+%
+% --sort : sort filenames first
+% --topspace=dimension : distance above first line
+% --backspace=dimension : distance before left margin
+% --pretty : pretty print comform suffix (temporarily disabled)
+%
+% end help
+
+\setupbodyfont
+ [11pt,tt]
+
+\setuplayout
+ [header=0cm,
+ footer=1.5cm,
+ width=middle,
+ height=middle]
+
+% todo: use \arguments{topspace}
+
+\startluacode
+ local topspace = document.arguments["topspace"] or 0
+ if dimen(topspace) > dimen(0) then
+ tex.sprint(string.format("\\setuplayout[topspace=%s]",dimen(topspace)))
+ end
+ local backspace = document.arguments["backspace"] or 0
+ if dimen(topspace) > dimen(0) then
+ tex.sprint(string.format("\\setuplayout[backspace=%s]",dimen(backspace)))
+ end
+\stopluacode
+
+\setuptyping
+ [lines=yes]
+
+\setuptyping
+ [option=color]
+
+\starttext
+
+\startluacode
+ if #document.files > 0 then
+ if document.arguments["sort"] then
+ table.sort(document.files)
+ end
+ for _, filename in ipairs(document.files) do
+ if not string.find(filename,"^mtx%-context%-") then
+ tex.sprint("\\page\n")
+ tex.sprint(string.format("\\setupfootertexts[\\detokenize{%s}][\\pagenumber]\n",file.basename(filename)))
+ tex.sprint(string.format("\\typefile{%s}",filename))
+ end
+ end
+ else
+ tex.sprint(tex.ctxcatcodes,"no files given")
+ end
+\stopluacode
+
+\stoptext
diff --git a/tex/context/base/mtx-context-timing.tex b/tex/context/base/mtx-context-timing.tex
new file mode 100644
index 000000000..51e6427f6
--- /dev/null
+++ b/tex/context/base/mtx-context-timing.tex
@@ -0,0 +1,46 @@
+% engine=luatex
+
+%D \module
+%D [ file=mtx-context-timing,
+%D version=2009.03.21,
+%D title=\CONTEXT\ Extra Trickry,
+%D subtitle=Timing Runs,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 help
+%
+% usage: context --extra=timing filename
+%
+% end help
+
+\enablemode[no-timing] \usemodule[timing]
+
+\setuplayout
+ [topspace=1cm,
+ bottomspace=.5cm,
+ header=0pt,
+ width=middle,
+ height=middle,
+ style=\tt]
+
+\setupfootertexts
+ [\getdocumentfilename{1}-luatex-progress.lut -- \pagenumber]
+
+\setupcolors
+ [state=start]
+
+\starttext
+
+ \doifsomething {\getdocumentfilename{1}} {
+ \LoadUsage{\getdocumentfilename{1}-luatex-progress}
+ \ShowUsage{\getdocumentfilename{1}-luatex-progress}
+ }
+
+\stoptext
+
diff --git a/tex/context/base/mult-chk.lua b/tex/context/base/mult-chk.lua
new file mode 100644
index 000000000..1c74d2e38
--- /dev/null
+++ b/tex/context/base/mult-chk.lua
@@ -0,0 +1,66 @@
+if not modules then modules = { } end modules ['mult-chk'] = {
+ version = 1.001,
+ comment = "companion to mult-chk.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+local type = type
+local texsprint = tex.sprint
+local ctxcatcodes = tex.ctxcatcodes
+
+interfaces = interfaces or { }
+
+interfaces.syntax = {
+ test = { keys = table.tohash { "a","b","c","d","e","f","g" } }
+}
+
+function interfaces.invalidkey(kind,key)
+ commands.writestatus("syntax","invalid key '%s' for '%s' in line %s",key,kind,tex.inputlineno)
+end
+
+function interfaces.setvalidkeys(kind,list)
+ local s = interfaces.syntax[kind]
+ if not s then
+ interfaces.syntax[kind] = {
+ keys = aux.settings_to_set(list)
+ }
+ else
+ s.keys = aux.settings_to_set(list)
+ end
+end
+
+function interfaces.addvalidkeys(kind,list)
+ local s = interfaces.syntax[kind]
+ if not s then
+ interfaces.syntax[kind] = {
+ keys = aux.settings_to_set(list)
+ }
+ else
+ aux.settings_to_set(list,s.keys)
+ end
+end
+
+local prefix, kind, keys
+
+local function set(key,value)
+ if keys and not keys[key] then
+ interfaces.invalidkey(kind,key)
+ else
+ texsprint(ctxcatcodes,format("\\setsomevalue{%s}{%s}{%s}",prefix,key,value))
+ end
+end
+
+local pattern = aux.make_settings_to_hash_pattern(set,true)
+
+function commands.getcheckedparameters(k,p,s)
+ if s and s ~= "" then
+ prefix, kind = p, k
+ keys = k and k ~= "" and interfaces.syntax[k].keys
+ pattern:match(s)
+ end
+end
+
+_gcp_ = commands.getcheckedparameters
diff --git a/tex/context/base/mult-chk.mkii b/tex/context/base/mult-chk.mkii
new file mode 100644
index 000000000..6299d0cda
--- /dev/null
+++ b/tex/context/base/mult-chk.mkii
@@ -0,0 +1,26 @@
+%D \module
+%D [ file=mult-chk,
+%D version=2009.04.13,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Checking,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Multilingual Macros / Checking}
+
+%D No checking in \MKII.
+
+\def\setvalidparameterkeys{\gobbleparameters} % forward reference, so no \let
+\def\addvalidparameterkeys{\gobbleparameters} % forward reference, so no \let
+
+\let\enablecheckparameters \relax
+\let\disablecheckparameters\relax
+
+\def\getcheckedparameters[#1]{\getparameters} % just ignore the checking
+
+\endinput
diff --git a/tex/context/base/mult-chk.mkiv b/tex/context/base/mult-chk.mkiv
new file mode 100644
index 000000000..7b40bd64a
--- /dev/null
+++ b/tex/context/base/mult-chk.mkiv
@@ -0,0 +1,103 @@
+%D \module
+%D [ file=mult-chk,
+%D version=2009.04.13,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Checking,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Multilingual Macros / Checking}
+
+%D This is very experimental code that eventually might be used
+%D once we have split the whole code base.
+
+%D \startbuffer
+%D \getcheckedparameters[MyTest][MyNamespace][a=1,b=2,c=3,d=4,crap=whatever]
+%D
+%D \MyNamespacea\quad
+%D \MyNamespaceb\quad
+%D \MyNamespacec\quad
+%D \MyNamespaced\quad
+%D crap is \ifdefined\MyNamespacecrap\else un\fi defined
+%D \stopbuffer
+%D
+%D \enablecheckparameters
+%D
+%D \setvalidparameterkeys[MyTest][a,b,c,d] \getbuffer \par
+%D \addvalidparameterkeys[MyTest][crap] \getbuffer \par
+
+\unprotect
+
+\registerctxluafile{mult-chk}{1.001}
+
+\def\setvalidparameterkeys{\dodoubleargument\dosetvalidparameterkeys}
+\def\addvalidparameterkeys{\dodoubleargument\doaddvalidparameterkeys}
+
+\def\dosetvalidparameterkeys[#1][#2]{\ctxlua{interfaces.setvalidkeys("#1",\!!bs#2\!!es)}}
+\def\doaddvalidparameterkeys[#1][#2]{\ctxlua{interfaces.addvalidkeys("#1",\!!bs#2\!!es)}}
+
+\def\getcheckedparametersyes[#1]#2[#3]#4[#5%
+ {\if\noexpand#5]%
+ \expandafter\gobblethreearguments
+ \else
+ \let\setsomevalue\dosetvalue
+ \expandafter\dogetcheckedparametersyes
+ \fi{#1}{#3}#5}
+
+\def\dogetcheckedparametersyes#1#2#3]%
+ {\ctxlua{_gcp_("#1","#2",\!!bs\detokenize{#3}\!!es)}}
+
+\def\getcheckedparametersnop[#1]#2[#3]#4[#5%
+ {\if\noexpand#5]%
+ \expandafter\gobbletwoarguments
+ \else
+ \let\setsomevalue\dosetvalue
+ \expandafter\dogetcheckedparametersnop
+ \fi{#3}#5}
+
+\def\dogetcheckedparametersnop#1#2]%
+ {\def\p!dogetparameter{\p!doassign#1}%
+ \xprocesscommaitem#2,],\@relax@}
+
+\def\disablecheckparameters{\let\getcheckedparameters\getcheckedparametersnop}
+\def\enablecheckparameters {\let\getcheckedparameters\getcheckedparametersyes}
+
+\disablecheckparameters
+
+\protect \endinput
+
+\starttext
+
+\testfeatureonce{10000}{\getcheckedparameters[test][xx][a=b,c= d, e = f]} % 0.20 seconds
+
+\enablecheckparameters
+
+\testfeatureonce{10000}{\getcheckedparameters[test][xx][a=b,c= d, e = f]} % 0.35 seconds
+
+\getcheckedparameters[test][xx][a=a]
+\getcheckedparameters[test][xx][b= b]
+\getcheckedparameters[test][xx][c = c]
+\getcheckedparameters[test][xx][d = d d , e = e ,f = f ]
+\getcheckedparameters[test][xx][g={oeps {oeps}}]
+\getcheckedparameters[test][xx][crap=whatever]
+
+\startlines
+[a:\getvalue{xxa}][a]
+[b:\getvalue{xxb}][b]
+[c:\getvalue{xxc}][c]
+[d:\getvalue{xxd}][d d ]
+[e:\getvalue{xxe}][e ]
+[f:\getvalue{xxf}][f ]
+[g:\getvalue{xxg}][\detokenize\expandafter{\xxg}]
+\stoplines
+
+\setvalidparameterkeys[test][crap]
+
+\getcheckedparameters[test][xx][crap=whatever]
+
+\stoptext
diff --git a/tex/context/base/mult-de.tex b/tex/context/base/mult-de.tex
index b408dad2f..8c47126fe 100644
--- a/tex/context/base/mult-de.tex
+++ b/tex/context/base/mult-de.tex
@@ -68,6 +68,7 @@
\setinterfacevariable{after}{nach}
\setinterfacevariable{all}{alles}
\setinterfacevariable{always}{immer}
+\setinterfacevariable{answerarea}{answerarea}
\setinterfacevariable{appendices}{anhaenge}
\setinterfacevariable{appendix}{anhang}
\setinterfacevariable{april}{April}
@@ -237,6 +238,7 @@
\setinterfacevariable{lefthanging}{lefthanging}
\setinterfacevariable{leftmargin}{linkerrand}
\setinterfacevariable{leftpage}{linkerseite}
+\setinterfacevariable{lefttoright}{lefttoright}
\setinterfacevariable{legend}{legende}
\setinterfacevariable{lesshyphenation}{lesshyphenation}
\setinterfacevariable{line}{zeile}
@@ -295,6 +297,7 @@
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{nospacing}
\setinterfacevariable{not}{nicht}
+\setinterfacevariable{note}{note}
\setinterfacevariable{nothanging}{nothanging}
\setinterfacevariable{nothyphenated}{nothyphenated}
\setinterfacevariable{november}{November}
@@ -359,6 +362,7 @@
\setinterfacevariable{righthanging}{righthanging}
\setinterfacevariable{rightmargin}{rechterrand}
\setinterfacevariable{rightpage}{rechterseite}
+\setinterfacevariable{righttoleft}{righttoleft}
\setinterfacevariable{roman}{antiqua}
\setinterfacevariable{romannumerals}{roemischezahlen}
\setinterfacevariable{rotate}{drehe}
@@ -428,6 +432,14 @@
\setinterfacevariable{subsubsubsubsubject}{unterunterunterunterthema}
\setinterfacevariable{subsubsubsubsubsection}{unterunterunterunterunterabsatz}
\setinterfacevariable{subsubsubsubsubsubject}{unterunterunterunterunterthema}
+\setinterfacevariable{subsubsubsubsubsubsection}{unterunterunterunterunterunterabsatz}
+\setinterfacevariable{subsubsubsubsubsubsubject}{unterunterunterunterunterunterthema}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{unterunterunterunterunterunterunterabsatz}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{unterunterunterunterunterunterunterthema}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{unterunterunterunterunterunterunterunterabsatz}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{unterunterunterunterunterunterunterunterthema}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{unterunterunterunterunterunterunterunterunterabsatz}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{unterunterunterunterunterunterunterunterunterthema}
\setinterfacevariable{sunday}{sonntag}
\setinterfacevariable{support}{support}
\setinterfacevariable{sym}{sym}
@@ -520,6 +532,8 @@
\setinterfaceconstant{bodyfont}{fliesstext}
\setinterfaceconstant{bookmark}{bookmark}
\setinterfaceconstant{bottom}{unten}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
\setinterfaceconstant{bottomdistance}{abstandunten}
\setinterfaceconstant{bottomframe}{untenrahmen}
\setinterfaceconstant{bottomoffset}{untenoffset}
@@ -547,6 +561,7 @@
\setinterfaceconstant{component}{component}
\setinterfaceconstant{compoundhyphen}{compoundhyphen}
\setinterfaceconstant{compress}{compress}
+\setinterfaceconstant{connector}{connector}
\setinterfaceconstant{continue}{fortsetzen}
\setinterfaceconstant{contrastcolor}{kontrastfarbe}
\setinterfaceconstant{controls}{controls}
@@ -593,6 +608,7 @@
\setinterfaceconstant{fieldlayer}{fieldlayer}
\setinterfaceconstant{fieldoffset}{feldoffset}
\setinterfaceconstant{file}{datei}
+\setinterfaceconstant{filtercommand}{filtercommand}
\setinterfaceconstant{focus}{focus}
\setinterfaceconstant{focusin}{focusin}
\setinterfaceconstant{focusout}{focusout}
@@ -626,6 +642,7 @@
\setinterfaceconstant{height}{hoehe}
\setinterfaceconstant{hfactor}{hfaktor}
\setinterfaceconstant{hfil}{hfil}
+\setinterfaceconstant{hidenumber}{hidenumber}
\setinterfaceconstant{hoffset}{hoffset}
\setinterfaceconstant{horoffset}{rumpfabstand}
\setinterfaceconstant{hyphen}{hyphen}
@@ -714,9 +731,17 @@
\setinterfaceconstant{number}{nummer}
\setinterfaceconstant{numbercolor}{nummernfarbe}
\setinterfaceconstant{numbercommand}{nummerbefehl}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
\setinterfaceconstant{numberdistance}{numberdistance}
\setinterfaceconstant{numbering}{nummerierung}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
\setinterfaceconstant{numberseparator}{nummernseperator}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstopper}{numberstopper}
\setinterfaceconstant{numberstyle}{nummernstil}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -736,8 +761,22 @@
\setinterfaceconstant{pageboundaries}{seitenbegrenzung}
\setinterfaceconstant{pagecolor}{seitenfarbe}
\setinterfaceconstant{pagecommand}{seitenbefehl}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
\setinterfaceconstant{pagenumber}{seitennummer}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
\setinterfaceconstant{pagestate}{pagestate}
+\setinterfaceconstant{pagestopper}{pagestopper}
\setinterfaceconstant{pagestyle}{seitenstil}
\setinterfaceconstant{palet}{palette}
\setinterfaceconstant{paper}{papier}
@@ -747,6 +786,13 @@
\setinterfaceconstant{placestopper}{setzetrenner}
\setinterfaceconstant{position}{position}
\setinterfaceconstant{prefix}{prefix}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
\setinterfaceconstant{preset}{voreinstellung}
\setinterfaceconstant{preview}{vorschau}
\setinterfaceconstant{previous}{vorige}
@@ -757,6 +803,7 @@
\setinterfaceconstant{reduction}{reduktion}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{reference}{referenz}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{referieren}
\setinterfaceconstant{regionin}{regionin}
\setinterfaceconstant{regionout}{regionaus}
@@ -788,11 +835,18 @@
\setinterfaceconstant{rulethickness}{liniendicke}
\setinterfaceconstant{samepage}{selbeseite}
\setinterfaceconstant{sample}{muster}
+\setinterfaceconstant{saveinlist}{saveinlist}
\setinterfaceconstant{scale}{format}
\setinterfaceconstant{scope}{bereich}
\setinterfaceconstant{screen}{raster}
\setinterfaceconstant{section}{abschnitt}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
\setinterfaceconstant{sectionnumber}{abschnittsnummer}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
\setinterfaceconstant{separator}{seperator}
\setinterfaceconstant{set}{set}
\setinterfaceconstant{setups}{setups}
@@ -892,6 +946,8 @@
\setinterfaceconstant{ystep}{yschritt}
% definitions for interface elements for language de
%
+\setinterfaceelement{answerlines}{answerlines}
+\setinterfaceelement{answerspace}{answerspace}
\setinterfaceelement{begin}{anfang}
\setinterfaceelement{complete}{vollende}
\setinterfaceelement{coupled}{verknuepft}
@@ -1277,6 +1333,7 @@
\setinterfacecommand{settextcontent}{settext}
\setinterfacecommand{settextvariable}{settextvariable}
\setinterfacecommand{setupalign}{stelleausrichtungein}
+\setinterfacecommand{setupanswerarea}{setupanswerarea}
\setinterfacecommand{setuparranging}{stelleanordnenein}
\setinterfacecommand{setupbackground}{stellehintergrundein}
\setinterfacecommand{setupbackgrounds}{stellehintergruendeein}
diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua
index b0999fd2e..b447f2467 100644
--- a/tex/context/base/mult-def.lua
+++ b/tex/context/base/mult-def.lua
@@ -3571,6 +3571,16 @@ return {
["pe"]="بارگذاری‌تنظیم",
["ro"]="seteazaalinierea",
},
+ ["setupanswerarea"]={
+ ["cs"]="setupanswerarea",
+ ["de"]="setupanswerarea",
+ ["en"]="setupanswerarea",
+ ["fr"]="setupanswerarea",
+ ["it"]="setupanswerarea",
+ ["nl"]="stelantwoordgebiedin",
+ ["pe"]="setupanswerarea",
+ ["ro"]="setupanswerarea",
+ },
["setuparranging"]={
["cs"]="nastavusporadani",
["de"]="stelleanordnenein",
@@ -6912,6 +6922,12 @@ return {
["pe"]="پایین",
["ro"]="jos",
},
+ ["bottomafter"]={
+ ["en"]="bottomafter",
+ },
+ ["bottombefore"]={
+ ["en"]="bottombefore",
+ },
["bottomdistance"]={
["cs"]="vzdalenostspodku",
["de"]="abstandunten",
@@ -7182,6 +7198,9 @@ return {
["pe"]="فشردن",
["ro"]="compress",
},
+ ["connector"]={
+ ["en"]="connector",
+ },
["continue"]={
["cs"]="pokracovat",
["de"]="fortsetzen",
@@ -7642,6 +7661,9 @@ return {
["pe"]="پرونده",
["ro"]="fisier",
},
+ ["filtercommand"]={
+ ["en"]="filtercommand",
+ },
["focus"]={
["cs"]="zaostreni",
["de"]="focus",
@@ -7710,7 +7732,6 @@ return {
["it"]="coloreprimopiano",
["nl"]="voorgrondkleur",
["pe"]="رنگ‌پیش‌زمینه",
-
["ro"]="foregroundcolor",
},
["foregroundstyle"]={
@@ -7973,6 +7994,9 @@ return {
["pe"]="پرکردن‌ارتفاع",
["ro"]="hfil",
},
+ ["hidenumber"]={
+ ["en"]="hidenumber",
+ },
["hoffset"]={
["cs"]="hoffset",
["de"]="hoffset",
@@ -8853,6 +8877,12 @@ return {
["pe"]="فرمان‌شماره",
["ro"]="comandanumar",
},
+ ["numberconversion"]={
+ ["en"]="numberconversion",
+ },
+ ["numberconversionset"]={
+ ["en"]="numberconversionset",
+ },
["numberdistance"]={
["cs"]="numberdistance",
["de"]="numberdistance",
@@ -8873,6 +8903,15 @@ return {
["pe"]="شماره‌گذاری",
["ro"]="numerotare",
},
+ ["numberorder"]={
+ ["en"]="numberorder",
+ },
+ ["numberprefix"]={
+ ["en"]="numberprefix",
+ },
+ ["numbersegments"]={
+ ["en"]="numbersegments",
+ },
["numberseparator"]={
["cs"]="oddelovaccisla",
["de"]="nummernseperator",
@@ -8883,6 +8922,15 @@ return {
["pe"]="جداکننده‌شماره",
["ro"]="separatornumar",
},
+ ["numberseparatorset"]={
+ ["en"]="numberseparatorset",
+ },
+ ["numberset"]={
+ ["en"]="numberset",
+ },
+ ["numberstopper"]={
+ ["en"]="numberstopper",
+ },
["numberstyle"]={
["cs"]="stylcisla",
["de"]="nummernstil",
@@ -9073,6 +9121,12 @@ return {
["pe"]="فرمان‌صفحه",
["ro"]="comandapagina",
},
+ ["pageconversion"]={
+ ["en"]="pageconversion",
+ },
+ ["pageconversionset"]={
+ ["en"]="pageconversionset",
+ },
["pagenumber"]={
["cs"]="cislostranky",
["de"]="seitennummer",
@@ -9083,6 +9137,39 @@ return {
["pe"]="شماره‌صفحه",
["ro"]="numarpagina",
},
+ ["pageprefix"]={
+ ["en"]="pageprefix",
+ },
+ ["pageprefixconnector"]={
+ ["en"]="pageprefixconnector",
+ },
+ ["pageprefixconversion"]={
+ ["en"]="pageprefixconversion",
+ },
+ ["pageprefixconversionset"]={
+ ["en"]="pageprefixconversionset",
+ },
+ ["pageprefixsegments"]={
+ ["en"]="pageprefixsegments",
+ },
+ ["pageprefixseparatorset"]={
+ ["en"]="pageprefixseparatorset",
+ },
+ ["pageprefixset"]={
+ ["en"]="pageprefixset",
+ },
+ ["pageprefixstopper"]={
+ ["en"]="pageprefixstopper",
+ },
+ ["pagesegments"]={
+ ["en"]="pagesegments",
+ },
+ ["pageseparatorset"]={
+ ["en"]="pageseparatorset",
+ },
+ ["pageset"]={
+ ["en"]="pageset",
+ },
["pagestate"]={
["cs"]="pagestate",
["de"]="pagestate",
@@ -9093,6 +9180,9 @@ return {
["pe"]="وضعیت‌صفحه",
["ro"]="pagestate",
},
+ ["pagestopper"]={
+ ["en"]="pagestopper",
+ },
["pagestyle"]={
["cs"]="stylstranky",
["de"]="seitenstil",
@@ -9183,6 +9273,27 @@ return {
["pe"]="پیشوند",
["ro"]="prefix",
},
+ ["prefixconnector"]={
+ ["en"]="prefixconnector",
+ },
+ ["prefixconversion"]={
+ ["en"]="prefixconversion",
+ },
+ ["prefixconversionset"]={
+ ["en"]="prefixconversionset",
+ },
+ ["prefixsegments"]={
+ ["en"]="prefixsegments",
+ },
+ ["prefixseparatorset"]={
+ ["en"]="prefixseparatorset",
+ },
+ ["prefixset"]={
+ ["en"]="prefixset",
+ },
+ ["prefixstopper"]={
+ ["en"]="prefixstopper",
+ },
["preset"]={
["cs"]="prednastaveni",
["de"]="voreinstellung",
@@ -9283,6 +9394,9 @@ return {
["pe"]="مرجع",
["ro"]="referinta",
},
+ ["referenceprefix"]={
+ ["en"]="referenceprefix",
+ },
["referencing"]={
["cs"]="odkazujici",
["de"]="referieren",
@@ -9593,6 +9707,9 @@ return {
["pe"]="نمونه",
["ro"]="exemplu",
},
+ ["saveinlist"]={
+ ["en"]="saveinlist",
+ },
["scale"]={
["cs"]="meritko",
["de"]="format",
@@ -9633,6 +9750,12 @@ return {
["pe"]="بخش",
["ro"]="sectiune",
},
+ ["sectionconversion"]={
+ ["en"]="sectionconversion",
+ },
+ ["sectionconversionset"]={
+ ["en"]="sectionconversionset",
+ },
["sectionnumber"]={
["cs"]="cislooddilu",
["de"]="abschnittsnummer",
@@ -9643,6 +9766,18 @@ return {
["pe"]="شماره‌بخش",
["ro"]="numarsectiune",
},
+ ["sectionsegments"]={
+ ["en"]="sectionsegments",
+ },
+ ["sectionseparatorset"]={
+ ["en"]="sectionseparatorset",
+ },
+ ["sectionset"]={
+ ["en"]="sectionset",
+ },
+ ["sectionstopper"]={
+ ["en"]="sectionstopper",
+ },
["separator"]={
["cs"]="oddelovac",
["de"]="seperator",
@@ -10615,6 +10750,26 @@ return {
},
},
["elements"]={
+ ["answerlines"]={
+ ["cs"]="answerlines",
+ ["de"]="answerlines",
+ ["en"]="answerlines",
+ ["fr"]="answerlines",
+ ["it"]="answerlines",
+ ["nl"]="antwoordregels",
+ ["pe"]="answerlines",
+ ["ro"]="answerlines",
+ },
+ ["answerspace"]={
+ ["cs"]="answerspace",
+ ["de"]="answerspace",
+ ["en"]="answerspace",
+ ["fr"]="answerspace",
+ ["it"]="answerspace",
+ ["nl"]="antwoordruimte",
+ ["pe"]="answerspace",
+ ["ro"]="answerspace",
+ },
["begin"]={
["cs"]="zacatek",
["de"]="anfang",
@@ -11537,6 +11692,16 @@ return {
["pe"]="همواره",
["ro"]="totdeauna",
},
+ ["answerarea"]={
+ ["cs"]="answerarea",
+ ["de"]="answerarea",
+ ["en"]="answerarea",
+ ["fr"]="answerarea",
+ ["it"]="answerarea",
+ ["nl"]="antwoordgebied",
+ ["pe"]="answerarea",
+ ["ro"]="answerarea",
+ },
["appendices"]={
["cs"]="dodatky",
["de"]="anhaenge",
@@ -13227,6 +13392,16 @@ return {
["pe"]="صفحه‌چپ",
["ro"]="paginastanga",
},
+ ["lefttoright"]={
+ ["cs"]="lefttoright",
+ ["de"]="lefttoright",
+ ["en"]="lefttoright",
+ ["fr"]="lefttoright",
+ ["it"]="lefttoright",
+ ["nl"]="lefttoright",
+ ["pe"]="lefttoright",
+ ["ro"]="lefttoright",
+ },
["legend"]={
["cs"]="legenda",
["de"]="legende",
@@ -13807,6 +13982,9 @@ return {
["pe"]="بدون",
["ro"]="nu",
},
+ ["note"]={
+ ["en"]="note",
+ },
["nothanging"]={
["cs"]="nothanging",
["de"]="nothanging",
@@ -14447,6 +14625,16 @@ return {
["pe"]="صفحه‌راست",
["ro"]="paginadreapta",
},
+ ["righttoleft"]={
+ ["cs"]="righttoleft",
+ ["de"]="righttoleft",
+ ["en"]="righttoleft",
+ ["fr"]="righttoleft",
+ ["it"]="righttoleft",
+ ["nl"]="righttoleft",
+ ["pe"]="righttoleft",
+ ["ro"]="righttoleft",
+ },
["roman"]={
["cs"]="antikva",
["de"]="antiqua",
@@ -15137,6 +15325,86 @@ return {
["pe"]="زیرزیرزیرزیرزیرموضوع",
["ro"]="subsubsubsubsubsubiect",
},
+ ["subsubsubsubsubsubsection"]={
+ ["cs"]="podpodpodpodpodpodsekce",
+ ["de"]="unterunterunterunterunterunterabsatz",
+ ["en"]="subsubsubsubsubsubsection",
+ ["fr"]="soussoussoussoussoussoussection",
+ ["it"]="sottosottosottosottosottosottocapoverso",
+ ["nl"]="subsubsubsubsubsubparagraaf",
+ ["pe"]="زیرزیرزیرزیرزیرزیربخش",
+ ["ro"]="subsubsubsubsubsubsectiune",
+ },
+ ["subsubsubsubsubsubsubject"]={
+ ["cs"]="podpodpodpodpodpodtema",
+ ["de"]="unterunterunterunterunterunterthema",
+ ["en"]="subsubsubsubsubsubsubject",
+ ["fr"]="soussoussoussoussoussoussujet",
+ ["it"]="sottosottosottosottosottosottoargomento",
+ ["nl"]="subsubsubsubsubsubonderwerp",
+ ["pe"]="زیرزیرزیرزیرزیرزیرموضوع",
+ ["ro"]="subsubsubsubsubsubsubiect",
+ },
+ ["subsubsubsubsubsubsubsection"]={
+ ["cs"]="podpodpodpodpodpodpodsekce",
+ ["de"]="unterunterunterunterunterunterunterabsatz",
+ ["en"]="subsubsubsubsubsubsubsection",
+ ["fr"]="soussoussoussoussoussoussoussection",
+ ["it"]="sottosottosottosottosottosottosottocapoverso",
+ ["nl"]="subsubsubsubsubsubsubparagraaf",
+ ["pe"]="زیرزیرزیرزیرزیرزیرزیربخش",
+ ["ro"]="subsubsubsubsubsubsubsectiune",
+ },
+ ["subsubsubsubsubsubsubsubject"]={
+ ["cs"]="podpodpodpodpodpodpodtema",
+ ["de"]="unterunterunterunterunterunterunterthema",
+ ["en"]="subsubsubsubsubsubsubsubject",
+ ["fr"]="soussoussoussoussoussoussoussujet",
+ ["it"]="sottosottosottosottosottosottosottoargomento",
+ ["nl"]="subsubsubsubsubsubsubonderwerp",
+ ["pe"]="زیرزیرزیرزیرزیرزیرزیرموضوع",
+ ["ro"]="subsubsubsubsubsubsubsubiect",
+ },
+ ["subsubsubsubsubsubsubsubsection"]={
+ ["cs"]="podpodpodpodpodpodpodpodsekce",
+ ["de"]="unterunterunterunterunterunterunterunterabsatz",
+ ["en"]="subsubsubsubsubsubsubsubsection",
+ ["fr"]="soussoussoussoussoussoussoussoussection",
+ ["it"]="sottosottosottosottosottosottosottosottocapoverso",
+ ["nl"]="subsubsubsubsubsubsubsubparagraaf",
+ ["pe"]="زیرزیرزیرزیرزیرزیرزیرزیربخش",
+ ["ro"]="subsubsubsubsubsubsubsubsectiune",
+ },
+ ["subsubsubsubsubsubsubsubsubject"]={
+ ["cs"]="podpodpodpodpodpodpodpodtema",
+ ["de"]="unterunterunterunterunterunterunterunterthema",
+ ["en"]="subsubsubsubsubsubsubsubsubject",
+ ["fr"]="soussoussoussoussoussoussoussoussujet",
+ ["it"]="sottosottosottosottosottosottosottosottoargomento",
+ ["nl"]="subsubsubsubsubsubsubsubonderwerp",
+ ["pe"]="زیرزیرزیرزیرزیرزیرزیرزیرموضوع",
+ ["ro"]="subsubsubsubsubsubsubsubsubiect",
+ },
+ ["subsubsubsubsubsubsubsubsubsection"]={
+ ["cs"]="podpodpodpodpodpodpodpodpodsekce",
+ ["de"]="unterunterunterunterunterunterunterunterunterabsatz",
+ ["en"]="subsubsubsubsubsubsubsubsubsection",
+ ["fr"]="soussoussoussoussoussoussoussoussoussection",
+ ["it"]="sottosottosottosottosottosottosottosottosottocapoverso",
+ ["nl"]="subsubsubsubsubsubsubsubsubparagraaf",
+ ["pe"]="زیرزیرزیرزیرزیرزیرزیرزیرزیربخش",
+ ["ro"]="subsubsubsubsubsubsubsubsubsectiune",
+ },
+ ["subsubsubsubsubsubsubsubsubsubject"]={
+ ["cs"]="podpodpodpodpodpodpodpodpodtema",
+ ["de"]="unterunterunterunterunterunterunterunterunterthema",
+ ["en"]="subsubsubsubsubsubsubsubsubsubject",
+ ["fr"]="soussoussoussoussoussoussoussoussoussujet",
+ ["it"]="sottosottosottosottosottosottosottosottosottoargomento",
+ ["nl"]="subsubsubsubsubsubsubsubsubonderwerp",
+ ["pe"]="زیرزیرزیرزیرزیرزیرزیرزیرزیرموضوع",
+ ["ro"]="subsubsubsubsubsubsubsubsubsubiect",
+ },
["sunday"]={
["cs"]="nedele",
["de"]="sonntag",
diff --git a/tex/context/base/mult-def.tex b/tex/context/base/mult-def.tex
index c49e6ffac..cff9fb074 100644
--- a/tex/context/base/mult-def.tex
+++ b/tex/context/base/mult-def.tex
@@ -22,6 +22,14 @@
\setvalue{@interface@persian@}{pe}
\setvalue{@interface@romanian@}{ro}
-\input mult-\ifcsname @interface@\defaultinterface @\endcsname\csname @interface@\defaultinterface @\endcsname\else en\fi\relax
+% \def\userinterfacetag
+% {\ifcsname @interface@\defaultinterface @\endcsname\csname @interface@\defaultinterface @\endcsname\else en\fi}
+\def\userinterfacetag
+ {\ifcsname @interface@\currentinterface @\endcsname\csname @interface@\currentinterface @\endcsname\else en\fi}
+\def\userresponsestag
+ {\ifcsname @interface@\currentresponses @\endcsname\csname @interface@\currentresponses @\endcsname\else en\fi}
+
+\input mult-\userinterfacetag \relax
+\input mult-m\userresponsestag \relax
\protect \endinput
diff --git a/tex/context/base/mult-en.tex b/tex/context/base/mult-en.tex
index 1fdc9799e..16058f794 100644
--- a/tex/context/base/mult-en.tex
+++ b/tex/context/base/mult-en.tex
@@ -68,6 +68,7 @@
\setinterfacevariable{after}{after}
\setinterfacevariable{all}{all}
\setinterfacevariable{always}{always}
+\setinterfacevariable{answerarea}{answerarea}
\setinterfacevariable{appendices}{appendices}
\setinterfacevariable{appendix}{appendix}
\setinterfacevariable{april}{April}
@@ -237,6 +238,7 @@
\setinterfacevariable{lefthanging}{lefthanging}
\setinterfacevariable{leftmargin}{leftmargin}
\setinterfacevariable{leftpage}{leftpage}
+\setinterfacevariable{lefttoright}{lefttoright}
\setinterfacevariable{legend}{legend}
\setinterfacevariable{lesshyphenation}{lesshyphenation}
\setinterfacevariable{line}{line}
@@ -295,6 +297,7 @@
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{nospacing}
\setinterfacevariable{not}{not}
+\setinterfacevariable{note}{note}
\setinterfacevariable{nothanging}{nothanging}
\setinterfacevariable{nothyphenated}{nothyphenated}
\setinterfacevariable{november}{November}
@@ -359,6 +362,7 @@
\setinterfacevariable{righthanging}{righthanging}
\setinterfacevariable{rightmargin}{rightmargin}
\setinterfacevariable{rightpage}{rightpage}
+\setinterfacevariable{righttoleft}{righttoleft}
\setinterfacevariable{roman}{roman}
\setinterfacevariable{romannumerals}{romannumerals}
\setinterfacevariable{rotate}{rotate}
@@ -428,6 +432,14 @@
\setinterfacevariable{subsubsubsubsubject}{subsubsubsubsubject}
\setinterfacevariable{subsubsubsubsubsection}{subsubsubsubsubsection}
\setinterfacevariable{subsubsubsubsubsubject}{subsubsubsubsubsubject}
+\setinterfacevariable{subsubsubsubsubsubsection}{subsubsubsubsubsubsection}
+\setinterfacevariable{subsubsubsubsubsubsubject}{subsubsubsubsubsubsubject}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsection}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubject}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsubsection}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubsubject}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsubsubsection}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubsubsubject}
\setinterfacevariable{sunday}{sunday}
\setinterfacevariable{support}{support}
\setinterfacevariable{sym}{sym}
@@ -520,6 +532,8 @@
\setinterfaceconstant{bodyfont}{bodyfont}
\setinterfaceconstant{bookmark}{bookmark}
\setinterfaceconstant{bottom}{bottom}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
\setinterfaceconstant{bottomdistance}{bottomdistance}
\setinterfaceconstant{bottomframe}{bottomframe}
\setinterfaceconstant{bottomoffset}{bottomoffset}
@@ -547,6 +561,7 @@
\setinterfaceconstant{component}{component}
\setinterfaceconstant{compoundhyphen}{compoundhyphen}
\setinterfaceconstant{compress}{compress}
+\setinterfaceconstant{connector}{connector}
\setinterfaceconstant{continue}{continue}
\setinterfaceconstant{contrastcolor}{contrastcolor}
\setinterfaceconstant{controls}{controls}
@@ -593,6 +608,7 @@
\setinterfaceconstant{fieldlayer}{fieldlayer}
\setinterfaceconstant{fieldoffset}{fieldoffset}
\setinterfaceconstant{file}{file}
+\setinterfaceconstant{filtercommand}{filtercommand}
\setinterfaceconstant{focus}{focus}
\setinterfaceconstant{focusin}{focusin}
\setinterfaceconstant{focusout}{focusout}
@@ -626,6 +642,7 @@
\setinterfaceconstant{height}{height}
\setinterfaceconstant{hfactor}{hfactor}
\setinterfaceconstant{hfil}{hfil}
+\setinterfaceconstant{hidenumber}{hidenumber}
\setinterfaceconstant{hoffset}{hoffset}
\setinterfaceconstant{horoffset}{horoffset}
\setinterfaceconstant{hyphen}{hyphen}
@@ -714,9 +731,17 @@
\setinterfaceconstant{number}{number}
\setinterfaceconstant{numbercolor}{numbercolor}
\setinterfaceconstant{numbercommand}{numbercommand}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
\setinterfaceconstant{numberdistance}{numberdistance}
\setinterfaceconstant{numbering}{numbering}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
\setinterfaceconstant{numberseparator}{numberseparator}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstopper}{numberstopper}
\setinterfaceconstant{numberstyle}{numberstyle}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -736,8 +761,22 @@
\setinterfaceconstant{pageboundaries}{pageboundaries}
\setinterfaceconstant{pagecolor}{pagecolor}
\setinterfaceconstant{pagecommand}{pagecommand}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
\setinterfaceconstant{pagenumber}{pagenumber}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
\setinterfaceconstant{pagestate}{pagestate}
+\setinterfaceconstant{pagestopper}{pagestopper}
\setinterfaceconstant{pagestyle}{pagestyle}
\setinterfaceconstant{palet}{palet}
\setinterfaceconstant{paper}{paper}
@@ -747,6 +786,13 @@
\setinterfaceconstant{placestopper}{placestopper}
\setinterfaceconstant{position}{position}
\setinterfaceconstant{prefix}{prefix}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
\setinterfaceconstant{preset}{preset}
\setinterfaceconstant{preview}{preview}
\setinterfaceconstant{previous}{previous}
@@ -757,6 +803,7 @@
\setinterfaceconstant{reduction}{reduction}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{reference}{reference}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{referencing}
\setinterfaceconstant{regionin}{regionin}
\setinterfaceconstant{regionout}{regionout}
@@ -788,11 +835,18 @@
\setinterfaceconstant{rulethickness}{rulethickness}
\setinterfaceconstant{samepage}{samepage}
\setinterfaceconstant{sample}{sample}
+\setinterfaceconstant{saveinlist}{saveinlist}
\setinterfaceconstant{scale}{scale}
\setinterfaceconstant{scope}{scope}
\setinterfaceconstant{screen}{screen}
\setinterfaceconstant{section}{section}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
\setinterfaceconstant{sectionnumber}{sectionnumber}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
\setinterfaceconstant{separator}{separator}
\setinterfaceconstant{set}{set}
\setinterfaceconstant{setups}{setups}
@@ -892,6 +946,8 @@
\setinterfaceconstant{ystep}{ystep}
% definitions for interface elements for language en
%
+\setinterfaceelement{answerlines}{answerlines}
+\setinterfaceelement{answerspace}{answerspace}
\setinterfaceelement{begin}{begin}
\setinterfaceelement{complete}{complete}
\setinterfaceelement{coupled}{coupled}
@@ -1277,6 +1333,7 @@
\setinterfacecommand{settextcontent}{settextcontent}
\setinterfacecommand{settextvariable}{settextvariable}
\setinterfacecommand{setupalign}{setupalign}
+\setinterfacecommand{setupanswerarea}{setupanswerarea}
\setinterfacecommand{setuparranging}{setuparranging}
\setinterfacecommand{setupbackground}{setupbackground}
\setinterfacecommand{setupbackgrounds}{setupbackgrounds}
diff --git a/tex/context/base/mult-fr.tex b/tex/context/base/mult-fr.tex
index 1dc2b2b4f..11a305ac8 100644
--- a/tex/context/base/mult-fr.tex
+++ b/tex/context/base/mult-fr.tex
@@ -68,6 +68,7 @@
\setinterfacevariable{after}{apres}
\setinterfacevariable{all}{tout}
\setinterfacevariable{always}{toujours}
+\setinterfacevariable{answerarea}{answerarea}
\setinterfacevariable{appendices}{annexes}
\setinterfacevariable{appendix}{annexe}
\setinterfacevariable{april}{avril}
@@ -237,6 +238,7 @@
\setinterfacevariable{lefthanging}{lefthanging}
\setinterfacevariable{leftmargin}{margegauche}
\setinterfacevariable{leftpage}{pagegauche}
+\setinterfacevariable{lefttoright}{lefttoright}
\setinterfacevariable{legend}{legende}
\setinterfacevariable{lesshyphenation}{lesshyphenation}
\setinterfacevariable{line}{ligne}
@@ -295,6 +297,7 @@
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{sansespacement}
\setinterfacevariable{not}{pas}
+\setinterfacevariable{note}{note}
\setinterfacevariable{nothanging}{nonsuspendu}
\setinterfacevariable{nothyphenated}{nothyphenated}
\setinterfacevariable{november}{novembre}
@@ -359,6 +362,7 @@
\setinterfacevariable{righthanging}{righthanging}
\setinterfacevariable{rightmargin}{margedroite}
\setinterfacevariable{rightpage}{pagedroite}
+\setinterfacevariable{righttoleft}{righttoleft}
\setinterfacevariable{roman}{roman}
\setinterfacevariable{romannumerals}{chiffresromains}
\setinterfacevariable{rotate}{oriente}
@@ -428,6 +432,14 @@
\setinterfacevariable{subsubsubsubsubject}{soussoussoussoussujet}
\setinterfacevariable{subsubsubsubsubsection}{soussoussoussoussoussection}
\setinterfacevariable{subsubsubsubsubsubject}{soussoussoussoussoussujet}
+\setinterfacevariable{subsubsubsubsubsubsection}{soussoussoussoussoussoussection}
+\setinterfacevariable{subsubsubsubsubsubsubject}{soussoussoussoussoussoussujet}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{soussoussoussoussoussoussoussection}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{soussoussoussoussoussoussoussujet}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{soussoussoussoussoussoussoussoussection}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{soussoussoussoussoussoussoussoussujet}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{soussoussoussoussoussoussoussoussoussection}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{soussoussoussoussoussoussoussoussoussujet}
\setinterfacevariable{sunday}{dimanche}
\setinterfacevariable{support}{support}
\setinterfacevariable{sym}{sym}
@@ -520,6 +532,8 @@
\setinterfaceconstant{bodyfont}{policecorps}
\setinterfaceconstant{bookmark}{marquepage}
\setinterfaceconstant{bottom}{inf}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
\setinterfaceconstant{bottomdistance}{distanceinf}
\setinterfaceconstant{bottomframe}{cadreinf}
\setinterfaceconstant{bottomoffset}{decalageinf}
@@ -547,6 +561,7 @@
\setinterfaceconstant{component}{composant}
\setinterfaceconstant{compoundhyphen}{compoundhyphen}
\setinterfaceconstant{compress}{compress}
+\setinterfaceconstant{connector}{connector}
\setinterfaceconstant{continue}{continue}
\setinterfaceconstant{contrastcolor}{coleurcontraste}
\setinterfaceconstant{controls}{controles}
@@ -593,6 +608,7 @@
\setinterfaceconstant{fieldlayer}{calquechamp}
\setinterfaceconstant{fieldoffset}{offsetchamp}
\setinterfaceconstant{file}{fichier}
+\setinterfaceconstant{filtercommand}{filtercommand}
\setinterfaceconstant{focus}{focus}
\setinterfaceconstant{focusin}{focusin}
\setinterfaceconstant{focusout}{focusout}
@@ -626,6 +642,7 @@
\setinterfaceconstant{height}{hauteur}
\setinterfaceconstant{hfactor}{facteurhauteur}
\setinterfaceconstant{hfil}{hfil}
+\setinterfaceconstant{hidenumber}{hidenumber}
\setinterfaceconstant{hoffset}{decalagehauteur}
\setinterfaceconstant{horoffset}{horoffset}
\setinterfaceconstant{hyphen}{hyphen}
@@ -714,9 +731,17 @@
\setinterfaceconstant{number}{numero}
\setinterfaceconstant{numbercolor}{couleurnumero}
\setinterfaceconstant{numbercommand}{commandenumero}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
\setinterfaceconstant{numberdistance}{numberdistance}
\setinterfaceconstant{numbering}{numerotation}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
\setinterfaceconstant{numberseparator}{separateurnumbero}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstopper}{numberstopper}
\setinterfaceconstant{numberstyle}{stylenumero}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -736,8 +761,22 @@
\setinterfaceconstant{pageboundaries}{limitespage}
\setinterfaceconstant{pagecolor}{couleurpage}
\setinterfaceconstant{pagecommand}{commandepage}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
\setinterfaceconstant{pagenumber}{numeropage}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
\setinterfaceconstant{pagestate}{etatpage}
+\setinterfaceconstant{pagestopper}{pagestopper}
\setinterfaceconstant{pagestyle}{stylepage}
\setinterfaceconstant{palet}{palette}
\setinterfaceconstant{paper}{papier}
@@ -747,6 +786,13 @@
\setinterfaceconstant{placestopper}{emplacementstopper}
\setinterfaceconstant{position}{position}
\setinterfaceconstant{prefix}{prefixe}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
\setinterfaceconstant{preset}{prereglage}
\setinterfaceconstant{preview}{previsualisation}
\setinterfaceconstant{previous}{precedent}
@@ -757,6 +803,7 @@
\setinterfaceconstant{reduction}{reduction}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{reference}{reference}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{referencing}
\setinterfaceconstant{regionin}{entreregion}
\setinterfaceconstant{regionout}{regionexterieure}
@@ -788,11 +835,18 @@
\setinterfaceconstant{rulethickness}{epaisseurligne}
\setinterfaceconstant{samepage}{memepage}
\setinterfaceconstant{sample}{echantillon}
+\setinterfaceconstant{saveinlist}{saveinlist}
\setinterfaceconstant{scale}{echelle}
\setinterfaceconstant{scope}{scope}
\setinterfaceconstant{screen}{ecran}
\setinterfaceconstant{section}{section}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
\setinterfaceconstant{sectionnumber}{numerosection}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
\setinterfaceconstant{separator}{separateur}
\setinterfaceconstant{set}{set}
\setinterfaceconstant{setups}{reglages}
@@ -892,6 +946,8 @@
\setinterfaceconstant{ystep}{ystep}
% definitions for interface elements for language fr
%
+\setinterfaceelement{answerlines}{answerlines}
+\setinterfaceelement{answerspace}{answerspace}
\setinterfaceelement{begin}{debut}
\setinterfaceelement{complete}{complete}
\setinterfaceelement{coupled}{couple}
@@ -1277,6 +1333,7 @@
\setinterfacecommand{settextcontent}{settext}
\setinterfacecommand{settextvariable}{affectevariabletexte}
\setinterfacecommand{setupalign}{reglealignement}
+\setinterfacecommand{setupanswerarea}{setupanswerarea}
\setinterfacecommand{setuparranging}{reglearrangement}
\setinterfacecommand{setupbackground}{reglearriereplan}
\setinterfacecommand{setupbackgrounds}{reglearriereplans}
diff --git a/tex/context/base/mult-his.tex b/tex/context/base/mult-his.tex
index 40010499d..fe87d4bcf 100644
--- a/tex/context/base/mult-his.tex
+++ b/tex/context/base/mult-his.tex
@@ -33,7 +33,7 @@
%D message : floatblocks/13
%D variables : sorttype compress autohang
-\writestatus{loading}{Context Multilingual Macros / Initialization}
+\writestatus{loading}{ConTeXt Multilingual Macros / Initialization}
\unprotect
@@ -328,11 +328,7 @@
%D example of a library.
%D
%D \starttyping
-%D \startmessages english library: alfa
-%D title: something
-%D 1: first message
-%D 2: second (--) message --
-%D \stopmessages
+%D % messages moved
%D \stoptyping
%D
%D The first message is a simple one and can be shown with:
@@ -361,9 +357,7 @@
%D once. We can add messages to a library in the following way:
%D
%D \starttyping
-%D \startmessages english library: alfa
-%D 10: tenth message
-%D \stopmessages
+%D % messages moved
%D \stoptyping
%D
%D Because such definitions can take place in different
@@ -1141,9 +1135,7 @@
{\writeline\writebanner{\contextbanner}\writeline}
\edef\formatversion
- {\ifx\normalyear \undefined\the\year \else\the\normalyear \fi.%
- \ifx\normalmonth\undefined\the\month\else\the\normalmonth\fi.%
- \ifx\normalday \undefined\the\day \else\the\normalday \fi}
+ {\the\normalyear.\the\normalmonth.\the\normalday}
\ifx\contextversion\undefined
\def\contextversion {unknown}
@@ -1153,9 +1145,8 @@
\edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark}
\fi
-\ifx\undefined\normaldump
+\ifx\undefined\everydump
\newtoks\everydump
- \let\normaldump\dump
\def\dump{\the\everydump\normaldump}
\fi
diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua
index 9133633eb..1eee9a656 100644
--- a/tex/context/base/mult-ini.lua
+++ b/tex/context/base/mult-ini.lua
@@ -6,47 +6,56 @@ if not modules then modules = { } end modules ['mult-ini'] = {
license = "see context related readme files"
}
-local format = string.format
+local format, gmatch = string.format, string.gmatch
interfaces = interfaces or { }
interfaces.messages = interfaces.messages or { }
interfaces.constants = interfaces.constants or { }
interfaces.variables = interfaces.variables or { }
-input.storage.register(false,"interfaces/messages", interfaces.messages, "interfaces.messages" )
-input.storage.register(false,"interfaces/constants", interfaces.constants, "interfaces.constants")
-input.storage.register(false,"interfaces/variables", interfaces.variables, "interfaces.variables")
+storage.register("interfaces/messages", interfaces.messages, "interfaces.messages" )
+storage.register("interfaces/constants", interfaces.constants, "interfaces.constants")
+storage.register("interfaces/variables", interfaces.variables, "interfaces.variables")
-function interfaces.setmessage(category,str)
+function interfaces.setmessages(category,str)
local m = interfaces.messages[category] or { }
- for k, v in str:gmatch("(%S+) *: *(.-) *[\n\r]") do
+ for k, v in gmatch(str,"(%S+) *: *(.-) *[\n\r]") do
m[k] = v:gsub("%-%-","%%s")
end
interfaces.messages[category] = m
end
+function interfaces.setmessage(category,tag,message)
+ local m = interfaces.messages[category]
+ if not m then
+ m = { }
+ interfaces.messages[category] = m
+ end
+ m[tag] = message:gsub("%-%-","%%s")
+end
+
function interfaces.getmessage(category,tag)
local m = interfaces.messages[category]
return (m and m[tag]) or "unknown message"
end
+local messagesplitter = lpeg.splitat(",")
+
function interfaces.makemessage(category,tag,arguments)
local m = interfaces.messages[category]
- m = (m and m[tag] ) or "unknown message"
+ m = (m and m[tag] ) or format("unknown message, category '%s', tag '%s'",category,tag)
if not m then
return m .. " " .. tag
elseif not arguments then
return m
- elseif arguments:find(",") then
- return format(m,unpack(arguments:splitchr(",")))
else
- return format(m,arguments)
+ return format(m,messagesplitter:match(arguments))
end
end
function interfaces.showmessage(category,tag,arguments)
local m = interfaces.messages[category]
- ctx.writestatus((m and m.title) or "unknown title",interfaces.makemessage(category,tag,arguments))
+ commands.writestatus((m and m.title) or "unknown title",interfaces.makemessage(category,tag,arguments))
end
function interfaces.setvariable(variable,given)
diff --git a/tex/context/base/mult-ini.mkii b/tex/context/base/mult-ini.mkii
index 8697057c8..c2bb40861 100644
--- a/tex/context/base/mult-ini.mkii
+++ b/tex/context/base/mult-ini.mkii
@@ -15,7 +15,7 @@
%D which we keep around as \type {mult-kep.tex} for sentimental
%D reasons. There you will find some more historic information.
-\writestatus{loading}{Context Multilingual Macros / Initialization}
+\writestatus{loading}{ConTeXt Multilingual Macros / Initialization}
\unprotect
@@ -438,7 +438,7 @@
{\definemessageconstant{#2}% handy for modules
\bgroup
\obeylines
- \doifundefined{\m!prefix!#2}{\setgvalue{\m!prefix!#2}{#2}}%
+ \ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi
\doifinsetelse{#1}{\currentresponses,all}
{\def\next
{\def\currentmessagelibrary{#2}%
@@ -460,6 +460,10 @@
\setxvalue{\??ms\currentmessagelibrary#1}{#2}%
\futurelet\next\getinterfacemessage}
+\def\setinterfacemessage#1#2#3%
+ {\ifcsname\m!prefix!#1\endcsname\else\setgvalue{\m!prefix!#1}{#1}\fi
+ \expandafter\def\csname\??ms#1#2\endcsname{#3}}
+
%D \macros
%D {ifshowwarnings, ifshowmessages}
%D
@@ -911,9 +915,7 @@
{\writeline\writebanner{\contextbanner}\writeline}
\edef\formatversion
- {\ifx\normalyear \undefined\the\year \else\the\normalyear \fi.%
- \ifx\normalmonth\undefined\the\month\else\the\normalmonth\fi.%
- \ifx\normalday \undefined\the\day \else\the\normalday \fi}
+ {\the\normalyear.\the\normalmonth.\the\normalday}
\ifx\contextversion\undefined
\def\contextversion {unknown}
@@ -923,9 +925,8 @@
\edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark}
\fi
-\ifx\undefined\normaldump
+\ifx\undefined\everydump
\newtoks\everydump
- \let\normaldump\dump
\def\dump{\the\everydump\normaldump}
\fi
diff --git a/tex/context/base/mult-ini.mkiv b/tex/context/base/mult-ini.mkiv
index c83a0b61d..2d1e2cc0e 100644
--- a/tex/context/base/mult-ini.mkiv
+++ b/tex/context/base/mult-ini.mkiv
@@ -15,7 +15,7 @@
%D which we keep around as \type {mult-kep.tex} for sentimental
%D reasons. There you will find some more historic information.
-\writestatus{loading}{Context Multilingual Macros / Initialization}
+\writestatus{loading}{ConTeXt Multilingual Macros / Initialization}
\unprotect
@@ -107,13 +107,14 @@
%D used more than once. Savings like this should of course be
%D implemented in english, just because \TEX\ is english.
-\def\!!width {width}
-\def\!!height {height}
-\def\!!depth {depth}
-\def\!!plus {plus}
-\def\!!minus {minus}
-\def\!!fill {fill}
-\def\!!to {to}
+\def\!!width {width}
+\def\!!height{height}
+\def\!!depth {depth}
+\def\!!plus {plus}
+\def\!!minus {minus}
+\def\!!fill {fill}
+\def\!!to {to}
+\def\!!spread{spread}
%D \macros
%D {defineinterfaceconstant,
@@ -240,8 +241,8 @@
\fi
-\ifx\currentinterface\undefined \let\currentinterface=\defaultinterface \fi
-\ifx\currentresponses\undefined \let\currentresponses=\defaultinterface \fi
+\ifx\currentinterface\undefined \let\currentinterface\defaultinterface \fi
+\ifx\currentresponses\undefined \let\currentresponses\defaultinterface \fi
%D \macros
%D {startinterface}
@@ -356,12 +357,16 @@
\doifinsetelse{#1}{\currentresponses,all}\dostartmessages\nostartmessages{#2}}
\def\dostartmessages#1#2\stopmessages
- {\ctxlua{interfaces.setmessage("#1",[[#2]])}%
+ {\ctxlua{interfaces.setmessages("#1",\!!bs#2\!!es)}%
\egroup}
\def\nostartmessages#1#2\stopmessages
{\egroup}
+\def\setinterfacemessage#1#2#3%
+ {\ifcsname\m!prefix!#1\endcsname\else\setgvalue{\m!prefix!#1}{#1}\fi
+ \ctxlua{interfaces.setmessage("#1","#2",\!!bs#3\!!es)}}
+
\unexpanded\def\setmessagetext #1#2{\edef\currentmessagetext{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2"))}}}
\unexpanded\def\getmessage #1#2{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.getmessage("#1","#2"))}}
\unexpanded\def\makemessage #1#2#3{\ctxlua{tex.sprint(tex.ctxcatcodes,interfaces.makemessage("#1","#2","#3"))}}
@@ -821,9 +826,7 @@
{\writeline\writebanner{\contextbanner}\writeline}
\edef\formatversion
- {\ifx\normalyear \undefined\the\year \else\the\normalyear \fi.%
- \ifx\normalmonth\undefined\the\month\else\the\normalmonth\fi.%
- \ifx\normalday \undefined\the\day \else\the\normalday \fi}
+ {\the\normalyear .\the\normalmonth.\the\normalday}
\ifx\contextversion\undefined
\def\contextversion {unknown}
@@ -833,9 +836,8 @@
\edef\contextversionnumber{\expandafter\contextversionnumber\contextversion\relax\space\contextmark}
\fi
-\ifx\undefined\normaldump
+\ifx\undefined\everydump
\newtoks\everydump
- \let\normaldump\dump
\def\dump{\the\everydump\normaldump}
\fi
diff --git a/tex/context/base/mult-it.tex b/tex/context/base/mult-it.tex
index e08d169d1..b62c5bdb3 100644
--- a/tex/context/base/mult-it.tex
+++ b/tex/context/base/mult-it.tex
@@ -68,6 +68,7 @@
\setinterfacevariable{after}{dopo}
\setinterfacevariable{all}{tutti}
\setinterfacevariable{always}{sempre}
+\setinterfacevariable{answerarea}{answerarea}
\setinterfacevariable{appendices}{appendici}
\setinterfacevariable{appendix}{appendice}
\setinterfacevariable{april}{aprile}
@@ -237,6 +238,7 @@
\setinterfacevariable{lefthanging}{lefthanging}
\setinterfacevariable{leftmargin}{marginesinistro}
\setinterfacevariable{leftpage}{paginasinistra}
+\setinterfacevariable{lefttoright}{lefttoright}
\setinterfacevariable{legend}{legenda}
\setinterfacevariable{lesshyphenation}{lesshyphenation}
\setinterfacevariable{line}{riga}
@@ -295,6 +297,7 @@
\setinterfacevariable{normal}{normale}
\setinterfacevariable{nospacing}{nospacing}
\setinterfacevariable{not}{non}
+\setinterfacevariable{note}{note}
\setinterfacevariable{nothanging}{nonsospeso}
\setinterfacevariable{nothyphenated}{nonsillabato}
\setinterfacevariable{november}{novembre}
@@ -359,6 +362,7 @@
\setinterfacevariable{righthanging}{righthanging}
\setinterfacevariable{rightmargin}{marginedestro}
\setinterfacevariable{rightpage}{paginadestra}
+\setinterfacevariable{righttoleft}{righttoleft}
\setinterfacevariable{roman}{roman}
\setinterfacevariable{romannumerals}{numeriromani}
\setinterfacevariable{rotate}{ruota}
@@ -428,6 +432,14 @@
\setinterfacevariable{subsubsubsubsubject}{sottosottosottosottoargomento}
\setinterfacevariable{subsubsubsubsubsection}{sottosottosottosottosottocapoverso}
\setinterfacevariable{subsubsubsubsubsubject}{sottosottosottosottosottoargomento}
+\setinterfacevariable{subsubsubsubsubsubsection}{sottosottosottosottosottosottocapoverso}
+\setinterfacevariable{subsubsubsubsubsubsubject}{sottosottosottosottosottosottoargomento}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{sottosottosottosottosottosottosottocapoverso}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{sottosottosottosottosottosottosottoargomento}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{sottosottosottosottosottosottosottosottocapoverso}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{sottosottosottosottosottosottosottosottoargomento}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{sottosottosottosottosottosottosottosottosottocapoverso}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{sottosottosottosottosottosottosottosottosottoargomento}
\setinterfacevariable{sunday}{domenica}
\setinterfacevariable{support}{supporto}
\setinterfacevariable{sym}{sim}
@@ -520,6 +532,8 @@
\setinterfaceconstant{bodyfont}{fonttesto}
\setinterfaceconstant{bookmark}{segnalibro}
\setinterfaceconstant{bottom}{fondo}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
\setinterfaceconstant{bottomdistance}{distanzafondo}
\setinterfaceconstant{bottomframe}{cornicefondo}
\setinterfaceconstant{bottomoffset}{offsetfondo}
@@ -547,6 +561,7 @@
\setinterfaceconstant{component}{component}
\setinterfaceconstant{compoundhyphen}{compoundhyphen}
\setinterfaceconstant{compress}{compress}
+\setinterfaceconstant{connector}{connector}
\setinterfaceconstant{continue}{continua}
\setinterfaceconstant{contrastcolor}{colorecontrasto}
\setinterfaceconstant{controls}{controlli}
@@ -593,6 +608,7 @@
\setinterfaceconstant{fieldlayer}{fieldlayer}
\setinterfaceconstant{fieldoffset}{offsetcampo}
\setinterfaceconstant{file}{file}
+\setinterfaceconstant{filtercommand}{filtercommand}
\setinterfaceconstant{focus}{focus}
\setinterfaceconstant{focusin}{focusin}
\setinterfaceconstant{focusout}{focusout}
@@ -626,6 +642,7 @@
\setinterfaceconstant{height}{altezza}
\setinterfaceconstant{hfactor}{hfactor}
\setinterfaceconstant{hfil}{hfil}
+\setinterfaceconstant{hidenumber}{hidenumber}
\setinterfaceconstant{hoffset}{hoffset}
\setinterfaceconstant{horoffset}{horoffset}
\setinterfaceconstant{hyphen}{hyphen}
@@ -714,9 +731,17 @@
\setinterfaceconstant{number}{numero}
\setinterfaceconstant{numbercolor}{colorenumero}
\setinterfaceconstant{numbercommand}{comandonumero}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
\setinterfaceconstant{numberdistance}{numberdistance}
\setinterfaceconstant{numbering}{numerazione}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
\setinterfaceconstant{numberseparator}{separatorenumero}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstopper}{numberstopper}
\setinterfaceconstant{numberstyle}{stilenumero}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -736,8 +761,22 @@
\setinterfaceconstant{pageboundaries}{limitipagina}
\setinterfaceconstant{pagecolor}{colorepagina}
\setinterfaceconstant{pagecommand}{comandopagina}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
\setinterfaceconstant{pagenumber}{numeropagina}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
\setinterfaceconstant{pagestate}{statopagina}
+\setinterfaceconstant{pagestopper}{pagestopper}
\setinterfaceconstant{pagestyle}{stilepagina}
\setinterfaceconstant{palet}{tavolozza}
\setinterfaceconstant{paper}{carta}
@@ -747,6 +786,13 @@
\setinterfaceconstant{placestopper}{mettistopper}
\setinterfaceconstant{position}{posizione}
\setinterfaceconstant{prefix}{prefisso}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
\setinterfaceconstant{preset}{preimpostato}
\setinterfaceconstant{preview}{anteprima}
\setinterfaceconstant{previous}{precedente}
@@ -757,6 +803,7 @@
\setinterfaceconstant{reduction}{riduzione}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{reference}{riferimento}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{referencing}
\setinterfaceconstant{regionin}{entraregione}
\setinterfaceconstant{regionout}{esciregione}
@@ -788,11 +835,18 @@
\setinterfaceconstant{rulethickness}{spessorelinea}
\setinterfaceconstant{samepage}{stessapagina}
\setinterfaceconstant{sample}{campione}
+\setinterfaceconstant{saveinlist}{saveinlist}
\setinterfaceconstant{scale}{scala}
\setinterfaceconstant{scope}{scope}
\setinterfaceconstant{screen}{schermo}
\setinterfaceconstant{section}{sezione}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
\setinterfaceconstant{sectionnumber}{numerosezione}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
\setinterfaceconstant{separator}{separatore}
\setinterfaceconstant{set}{set}
\setinterfaceconstant{setups}{setups}
@@ -892,6 +946,8 @@
\setinterfaceconstant{ystep}{ystep}
% definitions for interface elements for language it
%
+\setinterfaceelement{answerlines}{answerlines}
+\setinterfaceelement{answerspace}{answerspace}
\setinterfaceelement{begin}{inizio}
\setinterfaceelement{complete}{completo}
\setinterfaceelement{coupled}{accoppiato}
@@ -1277,6 +1333,7 @@
\setinterfacecommand{settextcontent}{settext}
\setinterfacecommand{settextvariable}{setvariabiletesto}
\setinterfacecommand{setupalign}{impostaallineamento}
+\setinterfacecommand{setupanswerarea}{setupanswerarea}
\setinterfacecommand{setuparranging}{impostaparranging}
\setinterfacecommand{setupbackground}{impostasfondo}
\setinterfacecommand{setupbackgrounds}{impostasfondi}
diff --git a/tex/context/base/mult-mcs.tex b/tex/context/base/mult-mcs.tex
new file mode 100644
index 000000000..bee7b777d
--- /dev/null
+++ b/tex/context/base/mult-mcs.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{neznama reference --}
+\setinterfacemessage{references}{3}{neznamy typ reference --}
+\setinterfacemessage{references}{2}{duplicitni reference -- na strane --}
+\setinterfacemessage{references}{4}{nedovolena reference --}
+\setinterfacemessage{references}{title}{reference}
+\setinterfacemessage{references}{30}{neznamy objekt --}
+\setinterfacemessage{references}{31}{duplicitni object --}
+\setinterfacemessage{references}{21}{dokument -- nacten}
+\setinterfacemessage{references}{22}{dokument -- neni interaktivni}
+\setinterfacemessage{references}{23}{obskurni (nejasna) reference -- (prefix=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{font handling --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{font handling -- is loaded}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{system}
+\setinterfacemessage{systems}{41}{externi soubor -- ve skupine -- neexistuje}
+\setinterfacemessage{systems}{9}{-- nenalezeno/nezpracovano}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{nova verze pomocneho souboru, je treba druheho behu}
+\setinterfacemessage{systems}{21}{pomocny soubor necten}
+\setinterfacemessage{systems}{20}{vyznam (trideni) -- nacten}
+\setinterfacemessage{systems}{5}{makra z -- nactena}
+\setinterfacemessage{systems}{4}{prikaz -- je jiz definovan}
+\setinterfacemessage{systems}{27}{verze}
+\setinterfacemessage{systems}{26}{registry}
+\setinterfacemessage{systems}{25}{reference}
+\setinterfacemessage{systems}{24}{plovouci bloky}
+\setinterfacemessage{systems}{1}{nacteni pomocneho souboru odlozeno (typemode)}
+\setinterfacemessage{systems}{23}{-- upraveno na --}
+\setinterfacemessage{systems}{22}{pouzijte platny pomocny soubor}
+\setinterfacemessage{systems}{2}{-- nacteno}
+\setinterfacemessage{systems}{19}{vyznam (synonyma) -- nacten}
+\setinterfacemessage{systems}{18}{synonymum -- -- neexistuje}
+\setinterfacemessage{systems}{7}{makra z -- jsou jiz nactena}
+\setinterfacemessage{systems}{6}{zadna makra v -- nenalezena}
+\setinterfacemessage{systems}{14}{vynucena nova stranka v seznamu na --}
+\setinterfacemessage{systems}{15}{uklada se buffer --}
+\setinterfacemessage{systems}{16}{sazi se buffer --}
+\setinterfacemessage{systems}{17}{sazi se doslovny (verbatim) buffer --}
+\setinterfacemessage{systems}{13}{znacka -- definovana --}
+\setinterfacemessage{systems}{12}{pomosny soubor neni setriden, pouzijte texutil}
+\setinterfacemessage{systems}{11}{vytvarim jednoduchy pomocny soubor}
+\setinterfacemessage{systems}{10}{nepouzivejte em v --}
+\setinterfacemessage{floatblocks}{1}{-- precislovano / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- presunuto}
+\setinterfacemessage{floatblocks}{2}{-- ulozeno}
+\setinterfacemessage{floatblocks}{5}{poradi prizpusobeno}
+\setinterfacemessage{floatblocks}{4}{-- umisteno}
+\setinterfacemessage{floatblocks}{7}{pocet spodnich plovoucich objektu je omezen na --}
+\setinterfacemessage{floatblocks}{6}{pocet hornich plovoucich objektu je omezen na --}
+\setinterfacemessage{floatblocks}{9}{poradi naruseno}
+\setinterfacemessage{floatblocks}{8}{radku je mene nez --}
+\setinterfacemessage{floatblocks}{title}{plovouciobjekty}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{nedefinovano}
+\setinterfacemessage{floatblocks}{11}{nedan zadny blok}
+\setinterfacemessage{floatblocks}{10}{-- omezeno}
+\setinterfacemessage{interactions}{1}{pomer -- x -- (s x v)}
+\setinterfacemessage{interactions}{3}{neaktivni}
+\setinterfacemessage{interactions}{2}{aktivni}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{zadna strankova synchronizace (--) v hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{interakce}
+\setinterfacemessage{interactions}{21}{-- kod vlozen}
+\setinterfacemessage{structures}{1}{zacatek oddilu (sekce) --}
+\setinterfacemessage{structures}{title}{struktury}
+\setinterfacemessage{structures}{2}{konec oddilu (sekce) --}
+\setinterfacemessage{linguals}{1}{vzory -- pro -- nacteny (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{deleni slov -- pro -- nacteno (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{zadne vzory -- pro -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{vzory pro -- nenacteny}
+\setinterfacemessage{linguals}{4}{zadne deleni slov -- pro -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{specificke volby jazyka [--] zavadeji -- (zavlecenou) mezeru}
+\setinterfacemessage{linguals}{6}{jazyk -- neni definovan}
+\setinterfacemessage{linguals}{9}{language -- is active}
+\setinterfacemessage{linguals}{8}{specificke volby jazyka [--] bez mezer pripojeny}
+\setinterfacemessage{linguals}{title}{jazyky}
+\setinterfacemessage{linguals}{10}{vzory --nacteny}
+\setinterfacemessage{regimes}{1}{kodovani --}
+\setinterfacemessage{regimes}{3}{nezname kodovani --}
+\setinterfacemessage{regimes}{2}{je nacteno kodovani --}
+\setinterfacemessage{regimes}{title}{kodovani}
+\setinterfacemessage{filters}{1}{filter -- is loaded}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{unknown filter --}
+\setinterfacemessage{verbatims}{1}{soubor -- neexistuje}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{kodovani --}
+\setinterfacemessage{encodings}{3}{nezname kodovani --}
+\setinterfacemessage{encodings}{2}{je nacteno kodovani --}
+\setinterfacemessage{encodings}{title}{kodovani}
+\setinterfacemessage{columns}{1}{je mozno pouze -- sloupcu}
+\setinterfacemessage{columns}{3}{problem, vypina se vyvazovani}
+\setinterfacemessage{columns}{2}{pouzijte \string\filbreak\space jako alternativu}
+\setinterfacemessage{columns}{5}{spodni plovouci objekt jeste neni podporovan}
+\setinterfacemessage{columns}{4}{horni plovouci objekt jeste neni podporovan}
+\setinterfacemessage{columns}{7}{vyvazovani ukonceno po 100 krocich}
+\setinterfacemessage{columns}{6}{-- plovouci objekt(y) odlozeny}
+\setinterfacemessage{columns}{9}{kontrola nerovnost}
+\setinterfacemessage{columns}{8}{vyvazeno v -- krocich}
+\setinterfacemessage{columns}{title}{sloupce}
+\setinterfacemessage{columns}{13}{siroky plovouci objekt je presunut nad sloupce}
+\setinterfacemessage{columns}{12}{plovouci objekt je presunut do nasledujiciho sloupce / --}
+\setinterfacemessage{columns}{11}{plovouci objekt je pro sloupec prilis siroky}
+\setinterfacemessage{columns}{10}{zbyl (mene nez) 1 radek}
+\setinterfacemessage{textblocks}{1}{nova verze, je treba druhy beh}
+\setinterfacemessage{textblocks}{3}{ctu bloky z --}
+\setinterfacemessage{textblocks}{2}{zapisuji bloky do --}
+\setinterfacemessage{textblocks}{5}{-- neni skryto}
+\setinterfacemessage{textblocks}{4}{je treba druhy beh}
+\setinterfacemessage{textblocks}{7}{-- skryto}
+\setinterfacemessage{textblocks}{6}{-- skryto a zpracovano}
+\setinterfacemessage{textblocks}{9}{-- nevysazeno}
+\setinterfacemessage{textblocks}{8}{-- vysazeno}
+\setinterfacemessage{textblocks}{title}{textovyblok}
+\setinterfacemessage{textblocks}{12}{-- preskoceno}
+\setinterfacemessage{textblocks}{11}{-- nacteno a vysazeno}
+\setinterfacemessage{textblocks}{10}{-- nacteno a zpracovano}
+\setinterfacemessage{symbols}{1}{nacita se soubor symbolu --}
+\setinterfacemessage{symbols}{title}{symboly}
+\setinterfacemessage{versions}{1}{postradam @+}
+\setinterfacemessage{versions}{3}{oznacene strany: --}
+\setinterfacemessage{versions}{2}{oznacuji se strany}
+\setinterfacemessage{versions}{title}{verze}
+\setinterfacemessage{specials}{1}{-- nacteno}
+\setinterfacemessage{specials}{3}{-- je resetovano}
+\setinterfacemessage{specials}{2}{neni dovoleno hlubsi zanoreni --}
+\setinterfacemessage{specials}{5}{nacita se definicni soubor --}
+\setinterfacemessage{specials}{4}{prikaz -- neexistuje}
+\setinterfacemessage{specials}{7}{neznamy ovladac (driver) --}
+\setinterfacemessage{specials}{6}{zanoreni neni dovoleno}
+\setinterfacemessage{specials}{title}{speciality}
+\setinterfacemessage{javascript}{1}{nacita se soubor skriptu --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{neznama preambule --}
+\setinterfacemessage{fonts}{1}{kodovani --}
+\setinterfacemessage{fonts}{3}{neznama varianta --}
+\setinterfacemessage{fonts}{2}{varianta -- je nactena}
+\setinterfacemessage{fonts}{5}{styl -- neni definovan}
+\setinterfacemessage{fonts}{4}{zakladni font -- neni definovan}
+\setinterfacemessage{fonts}{7}{neznamy format --}
+\setinterfacemessage{fonts}{6}{-- je nacten}
+\setinterfacemessage{fonts}{14}{bodyfont -- is defined (can better be done global)}
+\setinterfacemessage{fonts}{8}{styl -- definovan}
+\setinterfacemessage{fonts}{title}{zakladnifont}
+\setinterfacemessage{fonts}{10}{neznamy font --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{global file --}
+\setinterfacemessage{databases}{2}{local file --}
+\setinterfacemessage{databases}{4}{unknown file --}
+\setinterfacemessage{databases}{title}{databases}
+\setinterfacemessage{colors}{1}{system -- je globalne aktivovana}
+\setinterfacemessage{colors}{3}{-- neni definovana --}
+\setinterfacemessage{colors}{2}{system -- je lokalne activovana}
+\setinterfacemessage{colors}{5}{neznamy system --}
+\setinterfacemessage{colors}{4}{system -- je nacten}
+\setinterfacemessage{colors}{7}{palette -- neni k dispozici}
+\setinterfacemessage{colors}{6}{palette -- je k dispozici}
+\setinterfacemessage{colors}{9}{-- prostor barev neni podporovan}
+\setinterfacemessage{colors}{8}{specifikace -- v barve -- bude cerna}
+\setinterfacemessage{colors}{title}{barva}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{barva je prevedena na sed}
+\setinterfacemessage{colors}{10}{-- prostor barev je podporovan}
+\setinterfacemessage{layouts}{1}{vyska textu prizpusobena s -- na strane --}
+\setinterfacemessage{layouts}{3}{-- krat text odlozen}
+\setinterfacemessage{layouts}{2}{-- krat odlozeny text umisten}
+\setinterfacemessage{layouts}{5}{okrajove bloky neaktivni}
+\setinterfacemessage{layouts}{4}{okrajove bloky aktivni}
+\setinterfacemessage{layouts}{7}{pocita se misto pro logo}
+\setinterfacemessage{layouts}{6}{sada stran -- zpracovana (velikost --)}
+\setinterfacemessage{layouts}{9}{aktualne ne vice nez -- urovne/urovni vyctu}
+\setinterfacemessage{layouts}{8}{pocita se pozadi}
+\setinterfacemessage{layouts}{title}{layout}
+\setinterfacemessage{layouts}{11}{svisla mezera -- neni povolena v pevnem radkovem rejstriku}
+\setinterfacemessage{layouts}{10}{-- a -- nedava dohromady 1.0}
+\setinterfacemessage{check}{1}{postradam '=' po '--' na radku --}
+\setinterfacemessage{check}{3}{-- -- nahrazuje makro, uzijte VERZALKY!}
+\setinterfacemessage{check}{2}{ocekavam -- argument(y) na radku --}
+\setinterfacemessage{check}{title}{kontrola}
+\setinterfacemessage{metapost}{1}{loading metapost library --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{synonymum souboru -- je jiz pouzito pro --}
+\setinterfacemessage{files}{title}{soubory}
+\setinterfacemessage{figures}{1}{obraz -- nelze nalezt}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{obraz -- nepritomen}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{dimenze obrazu -- nacteny primo z jeho souboru}
+\setinterfacemessage{figures}{6}{dimenze obrazu -- spocteny programem rlxtools}
+\setinterfacemessage{figures}{8}{obrazovy objekt -- je znovu pouzit}
+\setinterfacemessage{figures}{title}{obrazy}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mde.tex b/tex/context/base/mult-mde.tex
new file mode 100644
index 000000000..a80ac4306
--- /dev/null
+++ b/tex/context/base/mult-mde.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{unbekannte Referenz --}
+\setinterfacemessage{references}{3}{unbekannte Referenz Typ --}
+\setinterfacemessage{references}{2}{doppelte Referenz -- auf Seite --}
+\setinterfacemessage{references}{4}{illegale Referenz --}
+\setinterfacemessage{references}{title}{referenzen}
+\setinterfacemessage{references}{30}{unbekanntes Object --}
+\setinterfacemessage{references}{31}{doppeltes Object --}
+\setinterfacemessage{references}{21}{Dokument -- geladen}
+\setinterfacemessage{references}{22}{Dokument -- ist nicht aktiv}
+\setinterfacemessage{references}{23}{Obskure Referenz -- (Prefix=--)}
+\setinterfacemessage{documents}{1}{Blatt --}
+\setinterfacemessage{documents}{title}{Blaetter}
+\setinterfacemessage{documents}{2}{Nummer --}
+\setinterfacemessage{handlings}{1}{Font Verarbeitung --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{Font Verarbeitung -- ist geladen}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{system}
+\setinterfacemessage{systems}{41}{Externe Datei -- in Gruppe -- existiert nicht}
+\setinterfacemessage{systems}{9}{-- nicht gefunden/verarbeitet}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{Neue Version der Hilfsdatei, zweiter Durchlauf benoetigt}
+\setinterfacemessage{systems}{21}{Die Hilfsdatei ist nicht geladen}
+\setinterfacemessage{systems}{20}{Bedeutung (sortieren) von -- geladen}
+\setinterfacemessage{systems}{5}{Modul -- geladen}
+\setinterfacemessage{systems}{4}{Befehl -- ist bereits definiert}
+\setinterfacemessage{systems}{27}{Version}
+\setinterfacemessage{systems}{26}{Register}
+\setinterfacemessage{systems}{25}{Referenzen}
+\setinterfacemessage{systems}{24}{Fliessbloecke}
+\setinterfacemessage{systems}{1}{Laden der Hilfsdatei aufgeschoben (Eingabe-Modus)}
+\setinterfacemessage{systems}{23}{-- angeordnet auf --}
+\setinterfacemessage{systems}{22}{Benoetige gueltige Hilfsdateie}
+\setinterfacemessage{systems}{2}{-- geladen}
+\setinterfacemessage{systems}{19}{Bedeutung (synonyme) von -- geladen}
+\setinterfacemessage{systems}{18}{Synonym -- -- existiert nicht}
+\setinterfacemessage{systems}{7}{Modul -- bereits geladen}
+\setinterfacemessage{systems}{6}{Modul -- gefunden}
+\setinterfacemessage{systems}{14}{Erzwungendes Seitenumbruch in Liste bei --}
+\setinterfacemessage{systems}{15}{Speichere Buffer --}
+\setinterfacemessage{systems}{16}{Setzte Buffer --}
+\setinterfacemessage{systems}{17}{Setzte tippen-Buffer --}
+\setinterfacemessage{systems}{13}{Beschriftung -- definiert --}
+\setinterfacemessage{systems}{12}{Die Hilfdatei ist nicht sortiert, verwende texutil}
+\setinterfacemessage{systems}{11}{Erstelle einfache Hilfdatei}
+\setinterfacemessage{systems}{10}{Benutzte kein em in --}
+\setinterfacemessage{floatblocks}{1}{-- neu nummeriert / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- verschoben}
+\setinterfacemessage{floatblocks}{2}{-- gespeichert}
+\setinterfacemessage{floatblocks}{5}{Reihenfolge angepasst}
+\setinterfacemessage{floatblocks}{4}{-- plaziert}
+\setinterfacemessage{floatblocks}{7}{Anz. der unteren Gleitobjekte beschraengt auf --}
+\setinterfacemessage{floatblocks}{6}{Anz. der oberen Gleitobjekte beschraengt auf --}
+\setinterfacemessage{floatblocks}{9}{Reigenfolge gestoert}
+\setinterfacemessage{floatblocks}{8}{weniger als -- zeilen}
+\setinterfacemessage{floatblocks}{title}{Gleitobjektbloecke}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{undefiniert}
+\setinterfacemessage{floatblocks}{11}{kein Block gegeben}
+\setinterfacemessage{floatblocks}{10}{-- begrenzt}
+\setinterfacemessage{interactions}{1}{Seitenverhaeltnis -- x -- (B x H)}
+\setinterfacemessage{interactions}{3}{inaktiv}
+\setinterfacemessage{interactions}{2}{aktiv}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{keine Seitensynchronisation (--) im hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{Interaktion}
+\setinterfacemessage{interactions}{21}{-- Code eingefuegt}
+\setinterfacemessage{structures}{1}{Begin des Abschnittsblocks --}
+\setinterfacemessage{structures}{title}{struktur}
+\setinterfacemessage{structures}{2}{Ende des Abschnittsblocks --}
+\setinterfacemessage{linguals}{1}{Trennmuster -- fuer -- geladen (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{Trenndefinitionen -- fuer -- geladen (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{Keine Trennmuster -- fuer -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{Trennmuster fuer -- nicht geladen}
+\setinterfacemessage{linguals}{4}{Keine Trenndefinitionen -- fuer -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{Sprachenspezifische Option [--] fuegt eine Luecke von -- ein}
+\setinterfacemessage{linguals}{6}{Sprache -- ist undefiniert}
+\setinterfacemessage{linguals}{9}{Sprache -- ist aktiv}
+\setinterfacemessage{linguals}{8}{Sprachenspezifische Option [--] nahtlos hinzugefuegt}
+\setinterfacemessage{linguals}{title}{Sprache}
+\setinterfacemessage{linguals}{10}{Trennmuster --geladen}
+\setinterfacemessage{regimes}{1}{Kodierung --}
+\setinterfacemessage{regimes}{3}{Unbekannte Kodierung --}
+\setinterfacemessage{regimes}{2}{Kodierung -- ist geladen}
+\setinterfacemessage{regimes}{title}{Kodierung}
+\setinterfacemessage{filters}{1}{filter -- ist geladen}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{unknown filter --}
+\setinterfacemessage{verbatims}{1}{Datei -- existiert nicht}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{Kodierung --}
+\setinterfacemessage{encodings}{3}{Unbekannte Kodierung --}
+\setinterfacemessage{encodings}{2}{Kodierung -- ist geladen}
+\setinterfacemessage{encodings}{title}{Kodierung}
+\setinterfacemessage{columns}{1}{nur -- Spalten moeglich}
+\setinterfacemessage{columns}{3}{Problem, verwende [ausgleich=nein]}
+\setinterfacemessage{columns}{2}{benutzte \string\filbreak\space als Alternative}
+\setinterfacemessage{columns}{5}{Gleitobjekt unten ncoh nicht unterstuetzt}
+\setinterfacemessage{columns}{4}{Gleitobjekt oben ncoh nicht unterstuetzt}
+\setinterfacemessage{columns}{7}{ausgleich nach 100 Schritten abgebrocheb}
+\setinterfacemessage{columns}{6}{-- Gleitobjekt(e) verschoben}
+\setinterfacemessage{columns}{9}{Ausrichtung ueberpruefen}
+\setinterfacemessage{columns}{8}{ausgeglichen nach -- Schritt(en)}
+\setinterfacemessage{columns}{title}{Spalten}
+\setinterfacemessage{columns}{13}{breites Gleitobjekt an den Anfang der Spalten verschoben}
+\setinterfacemessage{columns}{12}{Gleitobjekt in naechste Zeile verschoben / --}
+\setinterfacemessage{columns}{11}{Gleitobjekt zu breit fuer Spalte}
+\setinterfacemessage{columns}{10}{(weniger als) 1 Zeile uebrig}
+\setinterfacemessage{textblocks}{1}{neue Version, zweiter Durchlauf benoetigt}
+\setinterfacemessage{textblocks}{3}{lese Bloecke von --}
+\setinterfacemessage{textblocks}{2}{schreibe Bloecke zu --}
+\setinterfacemessage{textblocks}{5}{-- nicht verborgen}
+\setinterfacemessage{textblocks}{4}{zweiter Durchlauf benoetigt}
+\setinterfacemessage{textblocks}{7}{-- verborgen}
+\setinterfacemessage{textblocks}{6}{-- verborgen und verarbeitet}
+\setinterfacemessage{textblocks}{9}{-- nicht gesetzt}
+\setinterfacemessage{textblocks}{8}{-- gesetzt}
+\setinterfacemessage{textblocks}{title}{textblock}
+\setinterfacemessage{textblocks}{12}{-- ausgelassen}
+\setinterfacemessage{textblocks}{11}{-- geladen und gesetzt}
+\setinterfacemessage{textblocks}{10}{-- geladen und verarbeitet}
+\setinterfacemessage{symbols}{1}{Lade Symboldatei --}
+\setinterfacemessage{symbols}{title}{Symbole}
+\setinterfacemessage{versions}{1}{fehlendes @+}
+\setinterfacemessage{versions}{3}{Ausgewaehlte Seiten: --}
+\setinterfacemessage{versions}{2}{Erstelle Seiten}
+\setinterfacemessage{versions}{title}{Version}
+\setinterfacemessage{specials}{1}{-- geladen}
+\setinterfacemessage{specials}{3}{-- ist zurueckgesetzt}
+\setinterfacemessage{specials}{2}{keine tiefere Verschachtelung erlaubt --}
+\setinterfacemessage{specials}{5}{lade Definitionsdatei --}
+\setinterfacemessage{specials}{4}{Befehl -- existiert nicht}
+\setinterfacemessage{specials}{7}{unbekante Driver --}
+\setinterfacemessage{specials}{6}{Verschachtelung nicht erlaubt}
+\setinterfacemessage{specials}{title}{spezielles}
+\setinterfacemessage{javascript}{1}{Lade Scriptdatei --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{unbekannte Preamble --}
+\setinterfacemessage{fonts}{1}{Kodierung --}
+\setinterfacemessage{fonts}{3}{Unbekannte Variante --}
+\setinterfacemessage{fonts}{2}{Variante -- ist geladen}
+\setinterfacemessage{fonts}{5}{Stil -- ist nicht definiert}
+\setinterfacemessage{fonts}{4}{Fliesstext -- ist nicht definiert}
+\setinterfacemessage{fonts}{7}{unbekanntes Format --}
+\setinterfacemessage{fonts}{6}{-- ist geladen}
+\setinterfacemessage{fonts}{14}{Fliesstext -- wurde definiert (besser waere globale Definition)}
+\setinterfacemessage{fonts}{8}{Stil -- definiert}
+\setinterfacemessage{fonts}{title}{Fliesstext}
+\setinterfacemessage{fonts}{10}{unbekanntes Font --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{globale Datei --}
+\setinterfacemessage{databases}{2}{lokale Datei --}
+\setinterfacemessage{databases}{4}{unbekannte Datei --}
+\setinterfacemessage{databases}{title}{Datenbank}
+\setinterfacemessage{colors}{1}{system -- ist global aktiviert}
+\setinterfacemessage{colors}{3}{-- ist undefiniert --}
+\setinterfacemessage{colors}{2}{system -- ist lokal aktiviert}
+\setinterfacemessage{colors}{5}{unbekanntes System --}
+\setinterfacemessage{colors}{4}{system -- ist geladen}
+\setinterfacemessage{colors}{7}{palette -- ist nicht verfuegbar}
+\setinterfacemessage{colors}{6}{palette -- ist verfuegbar}
+\setinterfacemessage{colors}{9}{-- Farbraum wird nicht unterstuetzt}
+\setinterfacemessage{colors}{8}{Spezifikation -- bei Farbe -- wird schwarz}
+\setinterfacemessage{colors}{title}{farbe}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{Farbe wird in Grau umgewandelt}
+\setinterfacemessage{colors}{10}{-- Farbraum wird unterstuetzt}
+\setinterfacemessage{layouts}{1}{Texthoehe angepasst mit -- auf Seite --}
+\setinterfacemessage{layouts}{3}{-- mal Text verschoben}
+\setinterfacemessage{layouts}{2}{-- mal verschobener Text plaziert}
+\setinterfacemessage{layouts}{5}{marginalbloecke inaktiv}
+\setinterfacemessage{layouts}{4}{marginalbloecke aktiv}
+\setinterfacemessage{layouts}{7}{berechne Platzbedarf des Logos}
+\setinterfacemessage{layouts}{6}{Unterseitenfolge -- verarbeitet (Groesse --)}
+\setinterfacemessage{layouts}{9}{z.Z. nicht mehr als -- Ebenen in Aufzaehlungen}
+\setinterfacemessage{layouts}{8}{berechne Hintergrund}
+\setinterfacemessage{layouts}{title}{Layout}
+\setinterfacemessage{layouts}{11}{Zwischenraum -- nicht im Grittermoduserlau}
+\setinterfacemessage{layouts}{10}{-- und -- ergeben zusammen nicht 1.0}
+\setinterfacemessage{check}{1}{Fehlendes '=' nach '--' in Zeile --}
+\setinterfacemessage{check}{3}{-- -- ersetzt ein Makro, verwende VERSALIEN!}
+\setinterfacemessage{check}{2}{-- Argument(e) in Zeile -- erwartet}
+\setinterfacemessage{check}{title}{check}
+\setinterfacemessage{metapost}{1}{Lade metapost Bibliothek --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{Dateisynonym -- wird bereits fuer -- benutzt}
+\setinterfacemessage{files}{title}{files}
+\setinterfacemessage{figures}{1}{Abbildung -- kann nicht gefunden werden}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{Abbildung -- wird nicht erstellt}
+\setinterfacemessage{figures}{5}{Dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{Dimensionen von -- geladen aus der Abbildungsdatei selbst}
+\setinterfacemessage{figures}{6}{Dimensionen von -- ausgerechnet durch rlxtools}
+\setinterfacemessage{figures}{8}{Abbildungobjekt -- wurde wiederverwandt}
+\setinterfacemessage{figures}{title}{Abbildungen}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-men.tex b/tex/context/base/mult-men.tex
new file mode 100644
index 000000000..8335d2911
--- /dev/null
+++ b/tex/context/base/mult-men.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{unknown reference --}
+\setinterfacemessage{references}{3}{unknown reference type --}
+\setinterfacemessage{references}{2}{duplicate reference -- on page --}
+\setinterfacemessage{references}{4}{illegal reference --}
+\setinterfacemessage{references}{title}{references}
+\setinterfacemessage{references}{30}{unknown object --}
+\setinterfacemessage{references}{31}{duplicate object --}
+\setinterfacemessage{references}{21}{document -- loaded}
+\setinterfacemessage{references}{22}{document -- is not interactive}
+\setinterfacemessage{references}{23}{obscure reference -- (prefix=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{font handling --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{font handling -- is loaded}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{system}
+\setinterfacemessage{systems}{41}{external file -- in group -- does not exist}
+\setinterfacemessage{systems}{9}{-- not found/processed}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{new version of utility file, second pass needed}
+\setinterfacemessage{systems}{21}{no utility data is loaded}
+\setinterfacemessage{systems}{20}{meaning (sorts) of -- loaded}
+\setinterfacemessage{systems}{5}{module -- loaded}
+\setinterfacemessage{systems}{4}{command -- is already defined}
+\setinterfacemessage{systems}{27}{Version}
+\setinterfacemessage{systems}{26}{Registers}
+\setinterfacemessage{systems}{25}{References}
+\setinterfacemessage{systems}{24}{Floatblocks}
+\setinterfacemessage{systems}{1}{loading utility-file postponed (typemode)}
+\setinterfacemessage{systems}{23}{-- arranged at --}
+\setinterfacemessage{systems}{22}{use a valid utilityfile}
+\setinterfacemessage{systems}{2}{-- loaded}
+\setinterfacemessage{systems}{19}{meaning (synonyms) of -- loaded}
+\setinterfacemessage{systems}{18}{synonym -- -- does not exist}
+\setinterfacemessage{systems}{7}{module -- already loaded}
+\setinterfacemessage{systems}{6}{module -- not found}
+\setinterfacemessage{systems}{14}{forced newpage in list at --}
+\setinterfacemessage{systems}{15}{saving buffer --}
+\setinterfacemessage{systems}{16}{typesetting buffer --}
+\setinterfacemessage{systems}{17}{typesetting verbatim buffer --}
+\setinterfacemessage{systems}{13}{mark -- defined --}
+\setinterfacemessage{systems}{12}{the utility-file is not sorted, use texutil}
+\setinterfacemessage{systems}{11}{building simple util}
+\setinterfacemessage{systems}{10}{don't use em in --}
+\setinterfacemessage{floatblocks}{1}{-- renumbered / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- moved}
+\setinterfacemessage{floatblocks}{2}{-- saved}
+\setinterfacemessage{floatblocks}{5}{order adapted}
+\setinterfacemessage{floatblocks}{4}{-- placed}
+\setinterfacemessage{floatblocks}{7}{n of bottom floats limited to --}
+\setinterfacemessage{floatblocks}{6}{n of top floats limited to --}
+\setinterfacemessage{floatblocks}{9}{order disturbed}
+\setinterfacemessage{floatblocks}{8}{less than -- lines}
+\setinterfacemessage{floatblocks}{title}{floatblocks}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{undefined}
+\setinterfacemessage{floatblocks}{11}{no block given}
+\setinterfacemessage{floatblocks}{10}{-- limited}
+\setinterfacemessage{interactions}{1}{aspect ratio -- x -- (b x h)}
+\setinterfacemessage{interactions}{3}{inactive}
+\setinterfacemessage{interactions}{2}{active}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{no pagesynchronisation (--) in hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{interaction}
+\setinterfacemessage{interactions}{21}{-- code inserted}
+\setinterfacemessage{structures}{1}{begin of sectionblock --}
+\setinterfacemessage{structures}{title}{structure}
+\setinterfacemessage{structures}{2}{end of sectionblock --}
+\setinterfacemessage{linguals}{1}{patterns -- for -- loaded (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{hyphenations -- for -- loaded (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{no patterns -- for -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{patterns for -- not loaded}
+\setinterfacemessage{linguals}{4}{no hyphenations -- for -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{language specific options [--] introduce a -- skip}
+\setinterfacemessage{linguals}{6}{language -- is undefined}
+\setinterfacemessage{linguals}{9}{language -- is active}
+\setinterfacemessage{linguals}{8}{language specific options [--] seamless appended}
+\setinterfacemessage{linguals}{title}{language}
+\setinterfacemessage{linguals}{10}{patterns --loaded}
+\setinterfacemessage{regimes}{1}{regime --}
+\setinterfacemessage{regimes}{3}{unknown regime --}
+\setinterfacemessage{regimes}{2}{regime -- is loaded}
+\setinterfacemessage{regimes}{title}{regime}
+\setinterfacemessage{filters}{1}{filter -- is loaded}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{unknown filter --}
+\setinterfacemessage{verbatims}{1}{file -- does not exist}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{coding --}
+\setinterfacemessage{encodings}{3}{unknown coding --}
+\setinterfacemessage{encodings}{2}{coding -- is loaded}
+\setinterfacemessage{encodings}{title}{encoding}
+\setinterfacemessage{columns}{1}{only -- columns possible}
+\setinterfacemessage{columns}{3}{problems, disable balancing}
+\setinterfacemessage{columns}{2}{use \string\filbreak\space as alternative}
+\setinterfacemessage{columns}{5}{bottom float not yet supported}
+\setinterfacemessage{columns}{4}{top float not yet supported}
+\setinterfacemessage{columns}{7}{balancing aborted after 100 steps}
+\setinterfacemessage{columns}{6}{-- float(s) postponed}
+\setinterfacemessage{columns}{9}{check raggedness}
+\setinterfacemessage{columns}{8}{balanced in -- step(s)}
+\setinterfacemessage{columns}{title}{columns}
+\setinterfacemessage{columns}{13}{wide float moved to top of columns}
+\setinterfacemessage{columns}{12}{float moved to next column / --}
+\setinterfacemessage{columns}{11}{float too wide for column}
+\setinterfacemessage{columns}{10}{(less than) 1 line left}
+\setinterfacemessage{textblocks}{1}{new version, second pass needed}
+\setinterfacemessage{textblocks}{3}{reading blocks from --}
+\setinterfacemessage{textblocks}{2}{writing blocks to --}
+\setinterfacemessage{textblocks}{5}{-- not hidden}
+\setinterfacemessage{textblocks}{4}{second pass needed}
+\setinterfacemessage{textblocks}{7}{-- hidden}
+\setinterfacemessage{textblocks}{6}{-- hidden and processed}
+\setinterfacemessage{textblocks}{9}{-- not typeset}
+\setinterfacemessage{textblocks}{8}{-- typeset}
+\setinterfacemessage{textblocks}{title}{textblocks}
+\setinterfacemessage{textblocks}{12}{-- skipped}
+\setinterfacemessage{textblocks}{11}{-- loaded and typeset}
+\setinterfacemessage{textblocks}{10}{-- loaded and processed}
+\setinterfacemessage{symbols}{1}{loading symbolset --}
+\setinterfacemessage{symbols}{title}{symbols}
+\setinterfacemessage{versions}{1}{missing @+}
+\setinterfacemessage{versions}{3}{selected pages: --}
+\setinterfacemessage{versions}{2}{marking pages}
+\setinterfacemessage{versions}{title}{version}
+\setinterfacemessage{specials}{1}{-- loaded}
+\setinterfacemessage{specials}{3}{-- is reset}
+\setinterfacemessage{specials}{2}{no deeper nesting is permitted --}
+\setinterfacemessage{specials}{5}{loading definition file --}
+\setinterfacemessage{specials}{4}{command -- does not exist}
+\setinterfacemessage{specials}{7}{unknown driver --}
+\setinterfacemessage{specials}{6}{nesting is not permitted}
+\setinterfacemessage{specials}{title}{specials}
+\setinterfacemessage{javascript}{1}{loading script set --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{unknown preamble --}
+\setinterfacemessage{fonts}{1}{coding --}
+\setinterfacemessage{fonts}{3}{unknown variant --}
+\setinterfacemessage{fonts}{2}{variant -- is loaded}
+\setinterfacemessage{fonts}{5}{style -- is not defined}
+\setinterfacemessage{fonts}{4}{bodyfont -- is not defined}
+\setinterfacemessage{fonts}{7}{unknown format --}
+\setinterfacemessage{fonts}{6}{-- is loaded}
+\setinterfacemessage{fonts}{14}{bodyfont -- is defined (can better be done global)}
+\setinterfacemessage{fonts}{8}{style -- defined}
+\setinterfacemessage{fonts}{title}{bodyfont}
+\setinterfacemessage{fonts}{10}{unknown font file --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{global file --}
+\setinterfacemessage{databases}{2}{local file --}
+\setinterfacemessage{databases}{4}{unknown file --}
+\setinterfacemessage{databases}{title}{databases}
+\setinterfacemessage{colors}{1}{system -- is global activated}
+\setinterfacemessage{colors}{3}{-- is not defined --}
+\setinterfacemessage{colors}{2}{system -- is local activated}
+\setinterfacemessage{colors}{5}{unknown system --}
+\setinterfacemessage{colors}{4}{system -- is loaded}
+\setinterfacemessage{colors}{7}{palette -- is not available}
+\setinterfacemessage{colors}{6}{palette -- is available}
+\setinterfacemessage{colors}{9}{-- color space is not supported}
+\setinterfacemessage{colors}{8}{specification -- at color -- becomes black}
+\setinterfacemessage{colors}{title}{color}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{color is converted to gray}
+\setinterfacemessage{colors}{10}{-- color space is supported}
+\setinterfacemessage{layouts}{1}{textheight adapted with -- at page --}
+\setinterfacemessage{layouts}{3}{-- times text postponed}
+\setinterfacemessage{layouts}{2}{-- times postponed text placed}
+\setinterfacemessage{layouts}{5}{marginblocks inactive}
+\setinterfacemessage{layouts}{4}{marginblocks active}
+\setinterfacemessage{layouts}{7}{calculating logospace}
+\setinterfacemessage{layouts}{6}{subpage set -- processed (size --)}
+\setinterfacemessage{layouts}{9}{currently no more than -- levels in itemizations}
+\setinterfacemessage{layouts}{8}{calculating backgrounds}
+\setinterfacemessage{layouts}{title}{layout}
+\setinterfacemessage{layouts}{11}{spacing -- not permitted in gridmode}
+\setinterfacemessage{layouts}{10}{-- and -- don't add up to 1.0}
+\setinterfacemessage{check}{1}{missing or ungrouped '=' after '--' in line --}
+\setinterfacemessage{check}{3}{-- -- replaces a macro, use CAPITALS!}
+\setinterfacemessage{check}{2}{-- argument(s) expected in line --}
+\setinterfacemessage{check}{title}{check}
+\setinterfacemessage{metapost}{1}{loading metapost library --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{file synonym -- is already used for --}
+\setinterfacemessage{files}{title}{files}
+\setinterfacemessage{figures}{1}{figure -- can not be found}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{figure -- is not preset}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{dimensions of -- loaded from figurefile itself}
+\setinterfacemessage{figures}{6}{dimensions of -- calculated by rlxtools}
+\setinterfacemessage{figures}{8}{figureobject -- is reused}
+\setinterfacemessage{figures}{title}{figures}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mes.lua b/tex/context/base/mult-mes.lua
new file mode 100644
index 000000000..6d177fd8f
--- /dev/null
+++ b/tex/context/base/mult-mes.lua
@@ -0,0 +1,2005 @@
+return {
+ ["check"]={
+ ["1"]={
+ ["cs"]="postradam '=' po '--' na radku --",
+ ["de"]="Fehlendes '=' nach '--' in Zeile --",
+ ["en"]="missing or ungrouped '=' after '--' in line --",
+ ["fr"]="manquant ou dégroupé '=' après '--' à la ligne --",
+ ["it"]="'=' mancante o non raggruppato dopo '--' alla riga --",
+ ["nl"]="'=' ontbreekt of zonder {} na '--' in regel --",
+ ["no"]="manglende '=' etter '--' i linje --",
+ ["ro"]="lipseste '=' dupa '--' in linia --",
+ },
+ ["2"]={
+ ["cs"]="ocekavam -- argument(y) na radku --",
+ ["de"]="-- Argument(e) in Zeile -- erwartet",
+ ["en"]="-- argument(s) expected in line --",
+ ["fr"]="-- argument(s) attendu(s) à la ligne --",
+ ["it"]="-- argomento/i attesi alla riga --",
+ ["nl"]="-- argument(en) verwacht in regel --",
+ ["no"]="-- argument forventet i linje --",
+ ["ro"]="argumentul(ele) -- sunt asteptate in linia --",
+ },
+ ["3"]={
+ ["cs"]="-- -- nahrazuje makro, uzijte VERZALKY!",
+ ["de"]="-- -- ersetzt ein Makro, verwende VERSALIEN!",
+ ["en"]="-- -- replaces a macro, use CAPITALS!",
+ ["fr"]="-- -- remplace une macro, utilisez des MAJUSCULES !",
+ ["it"]="-- -- sostituisce una macro, usare le MAIUSCOLE!",
+ ["nl"]="-- -- vervangt een macro, gebruik HOOFDLETTERS!",
+ ["no"]="-- -- overskygger en makro, bruk STORE BOKSTAVER!",
+ ["ro"]="-- -- inlocuieste un macro, folositi MAJUSCULE!",
+ },
+ ["files"]={ "mult-sys.tex" },
+ ["title"]={
+ ["cs"]="kontrola",
+ ["de"]="check",
+ ["en"]="check",
+ ["fr"]="vérification",
+ ["it"]="controllo",
+ ["nl"]="controle",
+ ["no"]="kontroll",
+ ["ro"]="verificari",
+ },
+ },
+ ["colors"]={
+ ["1"]={
+ ["cs"]="system -- je globalne aktivovana",
+ ["de"]="system -- ist global aktiviert",
+ ["en"]="system -- is global activated",
+ ["fr"]="le système -- est globalement activé",
+ ["it"]="sistema -- attivato globalmente",
+ ["nl"]="systeem -- is globaal actief",
+ ["no"]="system -- er aktivert globalt",
+ ["ro"]="sistem -- este activata global",
+ },
+ ["10"]={
+ ["cs"]="-- prostor barev je podporovan",
+ ["de"]="-- Farbraum wird unterstuetzt",
+ ["en"]="-- color space is supported",
+ ["fr"]="-- l'espace de couleur est supporté",
+ ["it"]="spazio dei colori -- supportato",
+ ["nl"]="-- kleurruimte wordt ondersteund",
+ ["no"]="-- fargerom er støttet",
+ ["ro"]="spatiul de culoare -- este suportat",
+ },
+ ["11"]={
+ ["cs"]="barva je prevedena na sed",
+ ["de"]="Farbe wird in Grau umgewandelt",
+ ["en"]="color is converted to gray",
+ ["fr"]="la couleur est convertie en niveau de gris",
+ ["it"]="il colore ø convertito in grigio",
+ ["nl"]="kleur wordt vertaald in grijs",
+ ["no"]="fargen vil bli vist som grø",
+ ["ro"]="culoarea este convertita la gri",
+ },
+ ["12"]={
+ ["cs"]="-- is registered",
+ ["de"]="-- is registered",
+ ["en"]="-- is registered",
+ ["fr"]="-- est enregistré",
+ ["it"]="-- is registered",
+ ["nl"]="-- is geregistreerd",
+ ["no"]="-- is registered",
+ ["ro"]="-- is registered",
+ },
+ ["2"]={
+ ["cs"]="system -- je lokalne activovana",
+ ["de"]="system -- ist lokal aktiviert",
+ ["en"]="system -- is local activated",
+ ["fr"]="le système -- est localement activé",
+ ["it"]="sistema -- attivato localmente",
+ ["nl"]="systeem -- is lokaal actief",
+ ["no"]="system -- er aktivert lokalt",
+ ["ro"]="sistem -- este activata local",
+ },
+ ["3"]={
+ ["cs"]="-- neni definovana --",
+ ["de"]="-- ist undefiniert --",
+ ["en"]="-- is not defined --",
+ ["fr"]="-- n'est pas défini --",
+ ["it"]="-- non definito --",
+ ["nl"]="-- is niet gedefinieerd --",
+ ["no"]="-- er udefinert --",
+ ["ro"]="-- nu este definita --",
+ },
+ ["4"]={
+ ["cs"]="system -- je nacten",
+ ["de"]="system -- ist geladen",
+ ["en"]="system -- is loaded",
+ ["fr"]="le système -- est chargé",
+ ["it"]="sistema -- caricato",
+ ["nl"]="systeem -- wordt geladen",
+ ["no"]="system -- er lest inn",
+ ["ro"]="sistem -- este incarcata",
+ },
+ ["5"]={
+ ["cs"]="neznamy system --",
+ ["de"]="unbekanntes System --",
+ ["en"]="unknown system --",
+ ["fr"]="système -- inconnu",
+ ["it"]="sistema -- sconosciuto",
+ ["nl"]="onbekend systeem --",
+ ["no"]="ukjent system --",
+ ["ro"]="sistem -- necunoscuta",
+ },
+ ["6"]={
+ ["cs"]="palette -- je k dispozici",
+ ["de"]="palette -- ist verfuegbar",
+ ["en"]="palette -- is available",
+ ["fr"]="la palette -- est disponible",
+ ["it"]="tavolozza -- resa disponibile",
+ ["nl"]="palet -- is beschikbaar",
+ ["no"]="palett -- er tilgjengelig",
+ ["ro"]="paleta -- este disponibila",
+ },
+ ["7"]={
+ ["cs"]="palette -- neni k dispozici",
+ ["de"]="palette -- ist nicht verfuegbar",
+ ["en"]="palette -- is not available",
+ ["fr"]="le palette -- n'est pas disponible",
+ ["it"]="tavolozza -- non disponibile",
+ ["nl"]="palet -- is niet beschikbaar",
+ ["no"]="palett -- er ikke tilgjengelig",
+ ["ro"]="palette -- nu este disponibila",
+ },
+ ["8"]={
+ ["cs"]="specifikace -- v barve -- bude cerna",
+ ["de"]="Spezifikation -- bei Farbe -- wird schwarz",
+ ["en"]="specification -- at color -- becomes black",
+ ["fr"]="la spécification -- de la couleur -- devient noire",
+ ["it"]="specifica -- del colore -- convertita in nero",
+ ["nl"]="specificatie -- bij -- wordt zwart",
+ ["no"]="spesifikasjon -- for farge -- gir kun svart",
+ ["ro"]="specificatia -- la culoarea -- devine neagra",
+ },
+ ["9"]={
+ ["cs"]="-- prostor barev neni podporovan",
+ ["de"]="-- Farbraum wird nicht unterstuetzt",
+ ["en"]="-- color space is not supported",
+ ["fr"]="l'espace de couleur -- n'est pas supporté",
+ ["it"]="spazio dei colori -- non supportato",
+ ["nl"]="-- kleurruimte wordt niet ondersteund",
+ ["no"]="-- fargerom er ikke støttet",
+ ["ro"]="spatiul de culoare -- nu este suportat",
+ },
+ ["files"]={ "colo-ini.tex" },
+ ["title"]={
+ ["cs"]="barva",
+ ["de"]="farbe",
+ ["en"]="color",
+ ["fr"]="couleurs",
+ ["it"]="colore",
+ ["nl"]="kleur",
+ ["no"]="farge",
+ ["ro"]="culori",
+ },
+ },
+ ["columns"]={
+ ["1"]={
+ ["cs"]="je mozno pouze -- sloupcu",
+ ["de"]="nur -- Spalten moeglich",
+ ["en"]="only -- columns possible",
+ ["fr"]="seules -- colonnes possibles",
+ ["it"]="solo -- colonne possibili",
+ ["nl"]="maximaal -- kolommen",
+ ["no"]="maksimalt -- kolonner",
+ ["ro"]="este posibil numai -- coloane",
+ },
+ ["10"]={
+ ["cs"]="zbyl (mene nez) 1 radek",
+ ["de"]="(weniger als) 1 Zeile uebrig",
+ ["en"]="(less than) 1 line left",
+ ["fr"]="(moins de) 1 ligne restante",
+ ["it"]="(meno di) una riga rimasta",
+ ["nl"]="(minder dan) 1 regel over",
+ ["no"]="(mindre enn) 1 linje igjen",
+ ["ro"]="a mai ramas (mai putin de) 1 linie",
+ },
+ ["11"]={
+ ["cs"]="plovouci objekt je pro sloupec prilis siroky",
+ ["de"]="Gleitobjekt zu breit fuer Spalte",
+ ["en"]="float too wide for column",
+ ["fr"]="flottant mis à la largeur de la colonne",
+ ["it"]="oggetto mobile troppo ampio per la colonna",
+ ["nl"]="plaatsblok te breed voor kolom",
+ ["no"]="flytblokk for bredt for kolonna",
+ ["ro"]="blocul este prea lat pentru coloana",
+ },
+ ["12"]={
+ ["cs"]="plovouci objekt je presunut do nasledujiciho sloupce / --",
+ ["de"]="Gleitobjekt in naechste Zeile verschoben / --",
+ ["en"]="float moved to next column / --",
+ ["fr"]="flottant déplacé à la colonne suivante / --",
+ ["it"]="oggetto mobile spostata alla colonna successiva / --",
+ ["nl"]="plaatsblok verplaatst naar volgende kolom / --",
+ ["no"]="flytblokk forskjøvet til neste kolonne / --",
+ ["ro"]="blocul este mutat pe urmatoarea coloana / --",
+ },
+ ["13"]={
+ ["cs"]="siroky plovouci objekt je presunut nad sloupce",
+ ["de"]="breites Gleitobjekt an den Anfang der Spalten verschoben",
+ ["en"]="wide float moved to top of columns",
+ ["fr"]="flottant large déplacé dans la partie supérieure de la colonne",
+ ["it"]="oggetto mobile ampio spostato sopra le colonne",
+ ["nl"]="breed figuur geplaatst boven kolommen",
+ ["no"]="bred flytblokk forksjøvet til toppen av kolonnene",
+ ["ro"]="blocul lat este mutat in partea de sus a coloanelor",
+ },
+ ["2"]={
+ ["cs"]="pouzijte \\string\\filbreak\\space jako alternativu",
+ ["de"]="benutzte \\string\\filbreak\\space als Alternative",
+ ["en"]="use \\string\\filbreak\\space as alternative",
+ ["fr"]="utilisez \\string\\filbreak\\space en tant qu'alternative",
+ ["it"]="in alternativa, usare \\string\\filbreak",
+ ["nl"]="gebruik eventueel \\string\\filbreak",
+ ["no"]="bruk \\string\\filbreak\\space som et alternativ",
+ ["ro"]="folositi \\string\\filbreak\\space ca alternativa",
+ },
+ ["3"]={
+ ["cs"]="problem, vypina se vyvazovani",
+ ["de"]="Problem, verwende [ausgleich=nein]",
+ ["en"]="problems, disable balancing",
+ ["fr"]="problèmes, désactive l'équilibrage",
+ ["it"]="problemi, disabilitare il bilanciamento",
+ ["nl"]="probleempje, probeer [balanceren=nee]",
+ ["no"]="problemer, slår av balansering",
+ ["ro"]="probleme, se dezactiveaza alinierea",
+ },
+ ["4"]={
+ ["cs"]="horni plovouci objekt jeste neni podporovan",
+ ["de"]="Gleitobjekt oben ncoh nicht unterstuetzt",
+ ["en"]="top float not yet supported",
+ ["fr"]="flottant en partie supérieure pas encore supporté",
+ ["it"]="float in cima non ancora supportato",
+ ["nl"]="plaatsblok boven nog niet mogelijk",
+ ["no"]="flytblokker øverst er ikke støttet enda",
+ ["ro"]="cadrele top (top float) nu sunt inca suportate",
+ },
+ ["5"]={
+ ["cs"]="spodni plovouci objekt jeste neni podporovan",
+ ["de"]="Gleitobjekt unten ncoh nicht unterstuetzt",
+ ["en"]="bottom float not yet supported",
+ ["fr"]="flottant en partie inférieure pas encore supporté",
+ ["it"]="float in fondo non ancora supportato",
+ ["nl"]="plaatsblok onder nog niet mogelijk",
+ ["no"]="flytblokker nedert er ikke støttet enda",
+ ["ro"]="cadrele bottom (bottom float) nu sunt inca suportate",
+ },
+ ["6"]={
+ ["cs"]="-- plovouci objekt(y) odlozeny",
+ ["de"]="-- Gleitobjekt(e) verschoben",
+ ["en"]="-- float(s) postponed",
+ ["fr"]="-- flottant(s) reporté(s)",
+ ["it"]="-- float(s) posticipate",
+ ["nl"]="-- plaatsblok(en) opgeschort",
+ ["no"]="-- flytblokk forskjøvet",
+ ["ro"]="-- blocurile sunt amanate",
+ },
+ ["7"]={
+ ["cs"]="vyvazovani ukonceno po 100 krocich",
+ ["de"]="ausgleich nach 100 Schritten abgebrocheb",
+ ["en"]="balancing aborted after 100 steps",
+ ["fr"]="équilibrage abandonné après 100 pas",
+ ["it"]="bilanciamento annullato dopo 100 passi",
+ ["nl"]="balanceren afgebroken na 100 stappen",
+ ["no"]="balansering avbrutt etter 100 iterasjoner",
+ ["ro"]="alinierea este oprita dupa 100 de incercari",
+ },
+ ["8"]={
+ ["cs"]="vyvazeno v -- krocich",
+ ["de"]="ausgeglichen nach -- Schritt(en)",
+ ["en"]="balanced in -- step(s)",
+ ["fr"]="équilibré en -- pas",
+ ["it"]="bilanciamento in -- passo/i",
+ ["nl"]="gebalanceerd in -- stap(pen)",
+ ["no"]="balansert etter -- iterasjoner",
+ ["ro"]="aliniat in -- pas(i)",
+ },
+ ["9"]={
+ ["cs"]="kontrola nerovnost",
+ ["de"]="Ausrichtung ueberpruefen",
+ ["en"]="check raggedness",
+ ["fr"]="vérification des irrégularités",
+ ["it"]="controllare seghettamento",
+ ["nl"]="uitlijnen controleren!",
+ ["no"]="kontroller tekstlayout!",
+ ["ro"]="verificat alinierea",
+ },
+ ["files"]={ "page-ini.tex" },
+ ["title"]={
+ ["cs"]="sloupce",
+ ["de"]="Spalten",
+ ["en"]="columns",
+ ["fr"]="colonnes",
+ ["it"]="colonne",
+ ["nl"]="kolommen",
+ ["no"]="kolonner",
+ ["ro"]="coloane",
+ },
+ },
+ ["databases"]={
+ ["1"]={
+ ["cs"]="--",
+ ["de"]="--",
+ ["en"]="--",
+ ["fr"]="--",
+ ["it"]="--",
+ ["nl"]="--",
+ ["no"]="--",
+ ["ro"]="--",
+ },
+ ["2"]={
+ ["cs"]="local file --",
+ ["de"]="lokale Datei --",
+ ["en"]="local file --",
+ ["fr"]="fichier local --",
+ ["it"]="file locale --",
+ ["nl"]="lokaal bestand --",
+ ["no"]="lokal fil --",
+ ["ro"]="fisier local --",
+ },
+ ["3"]={
+ ["cs"]="global file --",
+ ["de"]="globale Datei --",
+ ["en"]="global file --",
+ ["fr"]="fichier global --",
+ ["it"]="file globale --",
+ ["nl"]="globaal bestand --",
+ ["no"]="global fil --",
+ ["ro"]="fisier global --",
+ },
+ ["4"]={
+ ["cs"]="unknown file --",
+ ["de"]="unbekannte Datei --",
+ ["en"]="unknown file --",
+ ["fr"]="fichier inconnu --",
+ ["it"]="file sconosciuto --",
+ ["nl"]="onbekend bestand --",
+ ["no"]="ukjent fil --",
+ ["ro"]="fisier necunoscut --",
+ },
+ ["files"]={ "core-dat.tex" },
+ ["title"]={
+ ["cs"]="databases",
+ ["de"]="Datenbank",
+ ["en"]="databases",
+ ["fr"]="bases de données",
+ ["it"]="database",
+ ["nl"]="database",
+ ["no"]="databaser",
+ ["ro"]="baze de date",
+ },
+ },
+ ["documents"]={
+ ["1"]={
+ ["de"]="Blatt --",
+ ["en"]="sheet --",
+ ["nl"]="sheet --",
+ },
+ ["2"]={
+ ["de"]="Nummer --",
+ ["en"]="number --",
+ ["nl"]="nummer --",
+ },
+ ["files"]={ "docs-bri.tex", "docs-she.tex" },
+ ["title"]={
+ ["de"]="Blaetter",
+ ["en"]="sheets",
+ ["nl"]="sheets",
+ },
+ },
+ ["encodings"]={
+ ["1"]={
+ ["cs"]="kodovani --",
+ ["de"]="Kodierung --",
+ ["en"]="coding --",
+ ["fr"]="encodage --",
+ ["it"]="codifica --",
+ ["nl"]="codering --",
+ ["no"]="koding --",
+ ["ro"]="codificarea --",
+ },
+ ["2"]={
+ ["cs"]="je nacteno kodovani --",
+ ["de"]="Kodierung -- ist geladen",
+ ["en"]="coding -- is loaded",
+ ["fr"]="l'encodage -- est chargé",
+ ["it"]="codifica -- caricata",
+ ["nl"]="codering -- wordt geladen",
+ ["no"]="koding -- er lest inn",
+ ["ro"]="codificarea -- este Encarcata",
+ },
+ ["3"]={
+ ["cs"]="nezname kodovani --",
+ ["de"]="Unbekannte Kodierung --",
+ ["en"]="unknown coding --",
+ ["fr"]="encodage -- inconnu",
+ ["it"]="codifica sconosciuta --",
+ ["nl"]="onbekende codering --",
+ ["no"]="ukjent koding --",
+ ["ro"]="codificarea -- este necunoscuta",
+ },
+ ["files"]={ "enco-ini.mkii" },
+ ["title"]={
+ ["cs"]="kodovani",
+ ["de"]="Kodierung",
+ ["en"]="encoding",
+ ["fr"]="encodage",
+ ["it"]="codifica",
+ ["nl"]="encoding",
+ ["no"]="koding",
+ ["ro"]="codificari",
+ },
+ },
+ ["figures"]={
+ ["1"]={
+ ["cs"]="obraz -- nelze nalezt",
+ ["de"]="Abbildung -- kann nicht gefunden werden",
+ ["en"]="figure -- can not be found",
+ ["fr"]="la figure -- ne peut être trouvée",
+ ["it"]="figura -- non trovata",
+ ["nl"]="figuur -- is niet te vinden",
+ ["ro"]="figura -- nu poate fi gasita",
+ },
+ ["2"]={
+ ["cs"]="obraz -- nepritomen",
+ ["de"]="Abbildung -- wird nicht erstellt",
+ ["en"]="figure -- is not preset",
+ ["fr"]="la figure -- n'est pas pré-sélectionnée",
+ ["it"]="la figura -- non è preimpostata",
+ ["nl"]="figuur -- wordt niet preset",
+ ["ro"]="figura -- nu este presetata",
+ },
+ ["3"]={
+ ["cs"]="dimensions of -- are determined externally",
+ ["de"]="dimensions of -- are determined externally",
+ ["en"]="dimensions of -- are determined externally",
+ ["fr"]="dimensions of -- are determined externally",
+ ["it"]="dimensions of -- are determined externally",
+ ["nl"]="maten van -- worden extern vastgesteld",
+ ["ro"]="dimensions of -- are determined externally",
+ },
+ ["4"]={
+ ["cs"]="dimenze obrazu -- nacteny primo z jeho souboru",
+ ["de"]="Dimensionen von -- geladen aus der Abbildungsdatei selbst",
+ ["en"]="dimensions of -- loaded from figurefile itself",
+ ["fr"]="les dimensions de -- chargées implicitement à partir du fichier de figure",
+ ["it"]="dimensioni di -- caricate dal file di immagini stesso",
+ ["nl"]="maten van -- geladen uit figuurfile zelf",
+ ["ro"]="dimensiunea figurii -- se incarca din fisierul insusi",
+ },
+ ["5"]={
+ ["cs"]="dimensions of -- are unknown",
+ ["de"]="Dimensions of -- are unknown",
+ ["en"]="dimensions of -- are unknown",
+ ["fr"]="dimensions of -- are unknown",
+ ["it"]="dimensions of -- are unknown",
+ ["nl"]="maten van -- zijn onbekend",
+ ["ro"]="dimensions of -- are unknown",
+ },
+ ["6"]={
+ ["cs"]="dimenze obrazu -- spocteny programem rlxtools",
+ ["de"]="Dimensionen von -- ausgerechnet durch rlxtools",
+ ["en"]="dimensions of -- calculated by rlxtools",
+ ["fr"]="les dimensions de -- calculées par rlxtools",
+ ["it"]="dimensioni di -- calcolate da rlxtools",
+ ["nl"]="maten van -- berekend door rlxtools",
+ ["ro"]="dimensiunea figurii -- este calculata de rlxtools",
+ },
+ ["8"]={
+ ["cs"]="obrazovy objekt -- je znovu pouzit",
+ ["de"]="Abbildungobjekt -- wurde wiederverwandt",
+ ["en"]="figureobject -- is reused",
+ ["fr"]="figureobject -- est réutilisé",
+ ["it"]="oggetto-figura -- riutilizzato",
+ ["nl"]="figuurobject -- wordt opnieuw gebruikt",
+ ["ro"]="obiectul figura -- este refolosit",
+ },
+ ["files"]={ "core-inc.mkii" },
+ ["title"]={
+ ["cs"]="obrazy",
+ ["de"]="Abbildungen",
+ ["en"]="figures",
+ ["fr"]="figures",
+ ["it"]="figure",
+ ["nl"]="figuren",
+ ["ro"]="figuri",
+ },
+ },
+ ["files"]={
+ ["1"]={
+ ["cs"]="synonymum souboru -- je jiz pouzito pro --",
+ ["de"]="Dateisynonym -- wird bereits fuer -- benutzt",
+ ["en"]="file synonym -- is already used for --",
+ ["fr"]="le synonyme de fichier -- est déjà utilisé pour --",
+ ["it"]="sinonimo file -- già in uso per --",
+ ["nl"]="file synoniem -- is al in gebruik voor --",
+ ["no"]="filesynonym -- er allerede brukt for --",
+ ["ro"]="sinonimul fisierelor -- este folosit deja pentru --",
+ },
+ ["files"]={ "core-fil.tex" },
+ ["title"]={
+ ["cs"]="soubory",
+ ["de"]="files",
+ ["en"]="files",
+ ["fr"]="fichiers",
+ ["it"]="file",
+ ["nl"]="files",
+ ["no"]="filer",
+ ["ro"]="fisiere",
+ },
+ },
+ ["filters"]={
+ ["1"]={
+ ["cs"]="filter -- is loaded",
+ ["de"]="filter -- ist geladen",
+ ["en"]="filter -- is loaded",
+ ["fr"]="le filtre -- est chargé",
+ ["it"]="filtro -- caricato",
+ ["nl"]="filter -- wordt geladen",
+ },
+ ["2"]={
+ ["cs"]="unknown filter --",
+ ["de"]="unknown filter --",
+ ["en"]="unknown filter --",
+ ["fr"]="filtre -- inconnu",
+ ["it"]="filtro sconosciuto --",
+ ["nl"]="onbekend filter --",
+ },
+ ["files"]={ "filt-ini.tex" },
+ ["title"]={
+ ["cs"]="filter",
+ ["de"]="filter",
+ ["en"]="filter",
+ ["fr"]="filtre",
+ ["it"]="filtri",
+ ["nl"]="filter",
+ },
+ },
+ ["floatblocks"]={
+ ["1"]={
+ ["cs"]="-- precislovano / -- => --",
+ ["de"]="-- neu nummeriert / -- => --",
+ ["en"]="-- renumbered / -- => --",
+ ["fr"]="-- renuméroté / -- => --",
+ ["it"]="-- rinumerato / -- => --",
+ ["nl"]="-- hernummerd / -- => --",
+ ["no"]="-- renummerert / -- => --",
+ ["ro"]="-- renumerotat / -- => --",
+ },
+ ["10"]={
+ ["cs"]="-- omezeno",
+ ["de"]="-- begrenzt",
+ ["en"]="-- limited",
+ ["fr"]="-- limité",
+ ["it"]="-- limitato",
+ ["nl"]="-- begrensd",
+ ["no"]="-- begrenset",
+ ["ro"]="-- limitat",
+ },
+ ["11"]={
+ ["cs"]="nedan zadny blok",
+ ["de"]="kein Block gegeben",
+ ["en"]="no block given",
+ ["fr"]="pas de bloc donné",
+ ["it"]="nessun oggetto specificato",
+ ["nl"]="geen blok opgegeven",
+ ["no"]="ingen blokk oppgitt",
+ ["ro"]="nu este dat nici un bloc",
+ },
+ ["12"]={
+ ["cs"]="nedefinovano",
+ ["de"]="undefiniert",
+ ["en"]="undefined",
+ ["fr"]="indéfini",
+ ["it"]="non definito",
+ ["nl"]="niet gedefinieerd",
+ ["no"]="udefinert",
+ ["ro"]="nedefinit",
+ },
+ ["13"]={
+ ["cs"]="there is nothing to split",
+ ["de"]="there is nothing to split",
+ ["en"]="there is nothing to split",
+ ["fr"]="there is nothing to split",
+ ["it"]="there is nothing to split",
+ ["nl"]="er is niets te splitsen",
+ ["no"]="there is nothing to split",
+ ["ro"]="there is nothing to split",
+ },
+ ["2"]={
+ ["cs"]="-- ulozeno",
+ ["de"]="-- gespeichert",
+ ["en"]="-- saved",
+ ["fr"]="-- sauvegardé",
+ ["it"]="-- salvato",
+ ["nl"]="-- bewaard",
+ ["no"]="-- lagret",
+ ["ro"]="-- salvat",
+ },
+ ["3"]={
+ ["cs"]="-- presunuto",
+ ["de"]="-- verschoben",
+ ["en"]="-- moved",
+ ["fr"]="-- déplacé",
+ ["it"]="-- mosso",
+ ["nl"]="-- verplaatst",
+ ["no"]="-- flyttet",
+ ["ro"]="-- mutat",
+ },
+ ["4"]={
+ ["cs"]="-- umisteno",
+ ["de"]="-- plaziert",
+ ["en"]="-- placed",
+ ["fr"]="-- placé",
+ ["it"]="-- sistemato",
+ ["nl"]="-- geplaatst",
+ ["no"]="-- plassert",
+ ["ro"]="-- plasat",
+ },
+ ["5"]={
+ ["cs"]="poradi prizpusobeno",
+ ["de"]="Reihenfolge angepasst",
+ ["en"]="order adapted",
+ ["fr"]="ordre adapté",
+ ["it"]="ordine aggiustato",
+ ["nl"]="volgorde aangepast",
+ ["no"]="rekkefølge tilpasset",
+ ["ro"]="ordinea adaptata",
+ },
+ ["6"]={
+ ["cs"]="pocet hornich plovoucich objektu je omezen na --",
+ ["de"]="Anz. der oberen Gleitobjekte beschraengt auf --",
+ ["en"]="n of top floats limited to --",
+ ["fr"]="n flottants de haut de page limité à --",
+ ["it"]="n di top floats limitato a --",
+ ["nl"]="maximaal -- boven",
+ ["no"]="maksimalt -- flytblokker øverst",
+ ["ro"]="nr. cadrelor de sus limitat la --",
+ },
+ ["7"]={
+ ["cs"]="pocet spodnich plovoucich objektu je omezen na --",
+ ["de"]="Anz. der unteren Gleitobjekte beschraengt auf --",
+ ["en"]="n of bottom floats limited to --",
+ ["fr"]="n flottants de bas de page limité à --",
+ ["it"]="n di bottom floats limitato a --",
+ ["nl"]="maximaal -- onder",
+ ["no"]="maksimalt -- flytblokker nederst",
+ ["ro"]="nr. blocurilor de jos limitat la --",
+ },
+ ["8"]={
+ ["cs"]="radku je mene nez --",
+ ["de"]="weniger als -- zeilen",
+ ["en"]="less than -- lines",
+ ["fr"]="moins de -- lignes",
+ ["it"]="meno di -- righe",
+ ["nl"]="minder dan -- regels",
+ ["no"]="mindre enn -- linjer",
+ ["ro"]="mai putin de -- linii",
+ },
+ ["9"]={
+ ["cs"]="poradi naruseno",
+ ["de"]="Reigenfolge gestoert",
+ ["en"]="order disturbed",
+ ["fr"]="ordre perturbé",
+ ["it"]="ordine disturbato",
+ ["nl"]="volgorde verstoord",
+ ["no"]="rekkefølge endret",
+ ["ro"]="ordinea deranjata",
+ },
+ ["files"]={ "page-flt.tex", "strc-flt.tex" },
+ ["title"]={
+ ["cs"]="plovouciobjekty",
+ ["de"]="Gleitobjektbloecke",
+ ["en"]="floatblocks",
+ ["fr"]="blocs de flottants",
+ ["it"]="oggetti mobili",
+ ["nl"]="plaatsblokken",
+ ["no"]="flytblokker",
+ ["ro"]="Blocuri",
+ },
+ },
+ ["fonts"]={
+ ["1"]={
+ ["cs"]="kodovani --",
+ ["de"]="Kodierung --",
+ ["en"]="coding --",
+ ["fr"]="encodage --",
+ ["it"]="codifica --",
+ ["nl"]="codering --",
+ ["no"]="koding --",
+ ["ro"]="codificarea --",
+ },
+ ["10"]={
+ ["cs"]="neznamy font --",
+ ["de"]="unbekanntes Font --",
+ ["en"]="unknown font file --",
+ ["fr"]="fichier de police -- inconnu",
+ ["it"]="file di font sconosciuto --",
+ ["nl"]="onbekende font file --",
+ ["no"]="ukjent fontfil --",
+ ["ro"]="fisier font necunoscut --",
+ },
+ ["14"]={
+ ["cs"]="bodyfont -- is defined (can better be done global)",
+ ["de"]="Fliesstext -- wurde definiert (besser waere globale Definition)",
+ ["en"]="bodyfont -- is defined (can better be done global)",
+ ["fr"]="policecorps -- est défini (une définition globale pourrait être plus adéquat)",
+ ["it"]="corpo del testo -- definito (sarebbe meglio globale)",
+ ["nl"]="korps -- is gedefinieerd (kan beter globaal plaatsvinden)",
+ ["no"]="bodyfont -- is defined (can better be done global)",
+ ["ro"]="bodyfont -- is defined (can better be done global)",
+ },
+ ["2"]={
+ ["cs"]="varianta -- je nactena",
+ ["de"]="Variante -- ist geladen",
+ ["en"]="variant -- is loaded",
+ ["fr"]="la variante -- est chargée",
+ ["it"]="variante -- caricata",
+ ["nl"]="variant -- wordt geladen",
+ ["no"]="variant -- er lest inn",
+ ["ro"]="varianta -- este incarcata",
+ },
+ ["3"]={
+ ["cs"]="neznama varianta --",
+ ["de"]="Unbekannte Variante --",
+ ["en"]="unknown variant --",
+ ["fr"]="variante -- inconnue",
+ ["it"]="variante sconosciuta --",
+ ["nl"]="onbekende variant --",
+ ["no"]="ukjent variant --",
+ ["ro"]="varianta necunoscuta --",
+ },
+ ["4"]={
+ ["cs"]="zakladni font -- neni definovan",
+ ["de"]="Fliesstext -- ist nicht definiert",
+ ["en"]="bodyfont -- is not defined",
+ ["fr"]="policecorps -- n'est pas définie",
+ ["it"]="corpo del testo -- non definito",
+ ["nl"]="korps -- is niet gedefinieerd",
+ ["no"]="hovedfont -- er ikke definert",
+ ["ro"]="corpul de litere -- nu este definit",
+ },
+ ["5"]={
+ ["cs"]="styl -- neni definovan",
+ ["de"]="Stil -- ist nicht definiert",
+ ["en"]="style -- is not defined",
+ ["fr"]="le style -- n'est pas défini",
+ ["it"]="stile -- non definito",
+ ["nl"]="stijl -- is niet gedefinieerd",
+ ["no"]="stil -- er ikke definert",
+ ["ro"]="stilul -- nu este definit",
+ },
+ ["6"]={
+ ["cs"]="-- je nacten",
+ ["de"]="-- ist geladen",
+ ["en"]="-- is loaded",
+ ["fr"]="-- est chargé",
+ ["it"]="-- caricato",
+ ["nl"]="-- wordt geladen",
+ ["no"]="-- er lest inn",
+ ["ro"]="-- este incarcat",
+ },
+ ["7"]={
+ ["cs"]="neznamy format --",
+ ["de"]="unbekanntes Format --",
+ ["en"]="unknown format --",
+ ["fr"]="format -- inconnu",
+ ["it"]="formato sconosciuto --",
+ ["nl"]="onbekend formaat --",
+ ["no"]="ukjent format --",
+ ["ro"]="format necunoscut --",
+ },
+ ["8"]={
+ ["cs"]="styl -- definovan",
+ ["de"]="Stil -- definiert",
+ ["en"]="style -- defined",
+ ["fr"]="style -- défini",
+ ["it"]="stile -- definito",
+ ["nl"]="stijl -- gedefinieerd",
+ ["no"]="stil -- definert",
+ ["ro"]="stilul -- definit",
+ },
+ ["files"]={ "font-ini.mkii", "font-ini.mkiv" },
+ ["title"]={
+ ["cs"]="zakladnifont",
+ ["de"]="Fliesstext",
+ ["en"]="bodyfont",
+ ["fr"]="corps de texte",
+ ["it"]="font del corpo",
+ ["nl"]="korps",
+ ["no"]="hovedfont",
+ ["ro"]="corp de litere",
+ },
+ },
+ ["handlings"]={
+ ["1"]={
+ ["cs"]="font handling --",
+ ["de"]="Font Verarbeitung --",
+ ["en"]="font handling --",
+ ["fr"]="manipulation -- de police",
+ ["it"]="font handling --",
+ ["nl"]="font afhandeling --",
+ ["no"]="font handling --",
+ ["ro"]="font handling --",
+ },
+ ["2"]={
+ ["cs"]="font handling -- is loaded",
+ ["de"]="Font Verarbeitung -- ist geladen",
+ ["en"]="font handling -- is loaded",
+ ["fr"]="la manipulation -- de police est chargée",
+ ["it"]="font handling -- is loaded",
+ ["nl"]="font afhandeling -- wordt geladen",
+ ["no"]="font handling -- is loaded",
+ ["ro"]="font handling -- is loaded",
+ },
+ ["3"]={
+ ["cs"]="unknown font handling --",
+ ["de"]="unknown font handling --",
+ ["en"]="unknown font handling --",
+ ["fr"]="manipulation -- inconnue de police",
+ ["it"]="unknown font handling --",
+ ["nl"]="onbekende font afhandeling --",
+ ["no"]="unknown font handling --",
+ ["ro"]="unknown font handling --",
+ },
+ ["files"]={ "hand-ini.mkii" },
+ ["title"]={
+ ["cs"]="handling",
+ ["de"]="handling",
+ ["en"]="handling",
+ ["fr"]="manipulation",
+ ["it"]="handling",
+ ["nl"]="handling",
+ ["no"]="handling",
+ ["ro"]="handling",
+ },
+ },
+ ["interactions"]={
+ ["1"]={
+ ["cs"]="pomer -- x -- (s x v)",
+ ["de"]="Seitenverhaeltnis -- x -- (B x H)",
+ ["en"]="aspect ratio -- x -- (b x h)",
+ ["fr"]="ratio d'aspect -- x -- (b x h)",
+ ["it"]="rapporto -- x -- (b x a)",
+ ["nl"]="aspect ratio -- x -- (b x h)",
+ ["no"]="forholdstall -- x -- (b x h)",
+ ["ro"]="aspectul -- x -- (b x h)",
+ },
+ ["2"]={
+ ["cs"]="aktivni",
+ ["de"]="aktiv",
+ ["en"]="active",
+ ["fr"]="actif",
+ ["it"]="attiva",
+ ["nl"]="actief",
+ ["no"]="aktiv",
+ ["ro"]="activ",
+ },
+ ["21"]={
+ ["cs"]="-- kod vlozen",
+ ["de"]="-- Code eingefuegt",
+ ["en"]="-- code inserted",
+ ["fr"]="-- code inseré",
+ ["it"]="codice -- inserito",
+ ["nl"]="-- code tussengevoegd",
+ ["no"]="-- kode satt inn / tilføyd",
+ ["ro"]="-- cod inserat",
+ },
+ ["3"]={
+ ["cs"]="neaktivni",
+ ["de"]="inaktiv",
+ ["en"]="inactive",
+ ["fr"]="inactif",
+ ["it"]="inattiva",
+ ["nl"]="niet actief",
+ ["no"]="inaktiv",
+ ["ro"]="inactiv",
+ },
+ ["4"]={
+ ["cs"]="zadna strankova synchronizace (--) v hmode",
+ ["de"]="keine Seitensynchronisation (--) im hmode",
+ ["en"]="no pagesynchronisation (--) in hmode",
+ ["fr"]="pas de synchronisation de page (--) dans le hmode",
+ ["it"]="sincronizzazione di pagina (--) non disponibile in hmode",
+ ["nl"]="geen paginasynchronisatie (--) in hmode",
+ ["no"]="ingen sidesynkronisering (--) i hmode",
+ ["ro"]="nu exista sincronizare pt. pagini (--) in hmode",
+ },
+ ["5"]={
+ ["cs"]="unknown attachment --",
+ ["de"]="unknown attachment --",
+ ["en"]="unknown attachment --",
+ ["fr"]="le fichier joint -- est inconnu",
+ ["it"]="unknown attachment --",
+ ["nl"]="onbekend attachment --",
+ ["no"]="unknown attachment --",
+ ["ro"]="unknown attachment --",
+ },
+ ["6"]={
+ ["cs"]="attachment file -- does not exist",
+ ["de"]="attachment file -- does not exist",
+ ["en"]="attachment file -- does not exist",
+ ["fr"]="le fichier joint -- n'existe pas",
+ ["it"]="attachment file -- does not exist",
+ ["nl"]="attachment file -- bestaat niet",
+ ["no"]="attachment file -- does not exist",
+ ["ro"]="attachment file -- does not exist",
+ },
+ ["files"]={ "core-int.tex", "spec-ini.tex" },
+ ["title"]={
+ ["cs"]="interakce",
+ ["de"]="Interaktion",
+ ["en"]="interaction",
+ ["fr"]="interaction",
+ ["it"]="interazione",
+ ["nl"]="interactie",
+ ["no"]="interaksjon",
+ ["ro"]="interactiuni",
+ },
+ },
+ ["javascript"]={
+ ["1"]={
+ ["cs"]="nacita se soubor skriptu --",
+ ["de"]="Lade Scriptdatei --",
+ ["en"]="loading script set --",
+ ["fr"]="chargement du jeu de script --",
+ ["it"]="caricamento dello script set --",
+ ["nl"]="script set -- wordt geladen",
+ ["no"]="leser inn scriptsett --",
+ ["ro"]="se incarca scriptul --",
+ },
+ ["2"]={
+ ["cs"]="neznama preambule --",
+ ["de"]="unbekannte Preamble --",
+ ["en"]="unknown preamble --",
+ ["fr"]="préambule -- inconnu",
+ ["it"]="preambolo sconosciuto --",
+ ["nl"]="onbekende preamble --",
+ ["no"]="ukjent 'preamble' --",
+ ["ro"]="preambul necunoscut --",
+ },
+ ["files"]={ "java-ini.tex" },
+ ["title"]={
+ ["cs"]="javascript",
+ ["de"]="javascript",
+ ["en"]="javascript",
+ ["fr"]="javascript",
+ ["it"]="javascript",
+ ["nl"]="javascript",
+ ["no"]="javascript",
+ ["ro"]="javascript",
+ },
+ },
+ ["layouts"]={
+ ["1"]={
+ ["cs"]="vyska textu prizpusobena s -- na strane --",
+ ["de"]="Texthoehe angepasst mit -- auf Seite --",
+ ["en"]="textheight adapted with -- at page --",
+ ["fr"]="hauteurtexte adaptée avec -- à la page --",
+ ["it"]="altezza del testo adattata con -- a pagina --",
+ ["nl"]="teksthoogte aangepast met -- op pagina --",
+ ["no"]="teksthøyde tilpasset med -- på side --",
+ ["ro"]="textheight adaptat cu -- la pagina --",
+ },
+ ["10"]={
+ ["cs"]="-- a -- nedava dohromady 1.0",
+ ["de"]="-- und -- ergeben zusammen nicht 1.0",
+ ["en"]="-- and -- don't add up to 1.0",
+ ["fr"]="-- et -- ne sont pas ajoutés à 1.0",
+ ["it"]="-- e -- non sommano a 1.0",
+ ["nl"]="-- en -- tellen niet op tot 1.0",
+ ["no"]="-- og -- er ikke 1.0 til sammen",
+ ["ro"]="-- si -- nu se adauga pana la 1.0",
+ },
+ ["11"]={
+ ["cs"]="svisla mezera -- neni povolena v pevnem radkovem rejstriku",
+ ["de"]="Zwischenraum -- nicht im Grittermoduserlau",
+ ["en"]="spacing -- not permitted in gridmode",
+ ["fr"]="espacement -- non permis en modegrille",
+ ["it"]="spaziatura -- non permessa in modo griglia",
+ ["nl"]="interlinie -- niet toegestaan in gridmode",
+ ["no"]="mellomrom -- ikke tillatt i gridmodus",
+ ["ro"]="spatierea -- nu este permisa in gridmode",
+ },
+ ["2"]={
+ ["cs"]="-- krat odlozeny text umisten",
+ ["de"]="-- mal verschobener Text plaziert",
+ ["en"]="-- times postponed text placed",
+ ["fr"]="-- times postponed text placed",
+ ["it"]="posizionato testo posticipato -- volte",
+ ["nl"]="-- maal uitgestelde tekst tussengevoegd",
+ ["no"]="-- ganger forskjøvet tekst plassert",
+ ["ro"]="textul amanat de -- ori a fost plasat",
+ },
+ ["3"]={
+ ["cs"]="-- krat text odlozen",
+ ["de"]="-- mal Text verschoben",
+ ["en"]="-- times text postponed",
+ ["fr"]="-- times text postponed",
+ ["it"]="testo posticipato -- volte",
+ ["nl"]="-- maal tekst plaatsen uitstellen",
+ ["no"]="-- ganger tekst forskjøvet",
+ ["ro"]="textul amanat de -- ori",
+ },
+ ["4"]={
+ ["cs"]="okrajove bloky aktivni",
+ ["de"]="marginalbloecke aktiv",
+ ["en"]="marginblocks active",
+ ["fr"]="blocsmarge actifs",
+ ["it"]="blocchi in margine attivi",
+ ["nl"]="margeblokken actief",
+ ["no"]="margblokker aktive",
+ ["ro"]="blocuri marginale active",
+ },
+ ["5"]={
+ ["cs"]="okrajove bloky neaktivni",
+ ["de"]="marginalbloecke inaktiv",
+ ["en"]="marginblocks inactive",
+ ["fr"]="blocsmarge inactifs",
+ ["it"]="blocchi in margine inattivi",
+ ["nl"]="margeblokken inactief",
+ ["no"]="margblokker inaktive",
+ ["ro"]="blocuri marginale inactive",
+ },
+ ["6"]={
+ ["cs"]="sada stran -- zpracovana (velikost --)",
+ ["de"]="Unterseitenfolge -- verarbeitet (Groesse --)",
+ ["en"]="subpage set -- processed (size --)",
+ ["fr"]="jeu de souspage -- traité (taille --)",
+ ["it"]="gruppo di sottopagine -- elaborato (dimensione --)",
+ ["nl"]="subpagina reeks -- verwerkt (aantal --)",
+ ["no"]="delside sett -- behandlet (størrelse --)",
+ ["ro"]="setul -- de subpagini procesat (dimensiunea --)",
+ },
+ ["7"]={
+ ["cs"]="pocita se misto pro logo",
+ ["de"]="berechne Platzbedarf des Logos",
+ ["en"]="calculating logospace",
+ ["fr"]="calcul de l'espace pour le logo",
+ ["it"]="calcolo dello spazio per logo",
+ ["nl"]="beeldmerken berekenen",
+ ["no"]="beregner plass for logo",
+ ["ro"]="se calculeaza spatiul pentru logo",
+ },
+ ["8"]={
+ ["cs"]="pocita se pozadi",
+ ["de"]="berechne Hintergrund",
+ ["en"]="calculating backgrounds",
+ ["fr"]="calcul des arrières-plans",
+ ["it"]="calcolo dello sfondo",
+ ["nl"]="achtergronden berekenen",
+ ["no"]="beregner bakgrunn",
+ ["ro"]="se calculeaza fundalurile",
+ },
+ ["9"]={
+ ["cs"]="aktualne ne vice nez -- urovne/urovni vyctu",
+ ["de"]="z.Z. nicht mehr als -- Ebenen in Aufzaehlungen",
+ ["en"]="currently no more than -- levels in itemizations",
+ ["fr"]="pas plus de -- niveaux pour l'instant dans les élémentarisations",
+ ["it"]="attualmente non più di -- livelli di elencazione",
+ ["nl"]="momenteel maximaal -- niveaus in opsommingen",
+ ["no"]="for øyeblikket maksimalt -- nivåer i opplisting",
+ ["ro"]="acum nu se supota mai mult de -- nivele de adancime la iteratii",
+ },
+ ["files"]={ "core-itm.tex", "page-bck.mkii", "page-bck.mkiv", "page-ini.tex", "page-log.tex", "strc-itm.tex" },
+ ["title"]={
+ ["cs"]="layout",
+ ["de"]="Layout",
+ ["en"]="layout",
+ ["fr"]="calque",
+ ["it"]="layout",
+ ["nl"]="layout",
+ ["no"]="layout",
+ ["ro"]="aranjamente",
+ },
+ },
+ ["linguals"]={
+ ["1"]={
+ ["cs"]="vzory -- pro -- nacteny (n=--,e=--,m=--)",
+ ["de"]="Trennmuster -- fuer -- geladen (n=--,e=--,m=--)",
+ ["en"]="patterns -- for -- loaded (n=--,e=--,m=--)",
+ ["fr"]="les motifs -- pour -- sont chargés (n=--,e=--,m=--)",
+ ["it"]="schemi -- per -- caricati (n=--,e=--,m=--)",
+ ["nl"]="afbreekpatronen -- voor -- geladen (n=--,e=--,m=--)",
+ ["no"]="orddelingsmønster -- for -- er lest inn (n=--,e=--,m=--)",
+ ["ro"]="sablonul -- pentru -- s-a incarcat (n=--,e=--,m=--)",
+ },
+ ["10"]={
+ ["cs"]="vzory --nacteny",
+ ["de"]="Trennmuster --geladen",
+ ["en"]="patterns --loaded",
+ ["fr"]="motifs -- chargés",
+ ["it"]="schemi -- caricati",
+ ["nl"]="patronen --geladen",
+ ["no"]="orddelingsmønster -- er lest inn",
+ ["ro"]="sabloanele -- incarcate",
+ },
+ ["2"]={
+ ["cs"]="zadne vzory -- pro -- (n=--,e=--,m=--) (--,--)",
+ ["de"]="Keine Trennmuster -- fuer -- (n=--,e=--,m=--) (--,--)",
+ ["en"]="no patterns -- for -- (n=--,e=--,m=--) (--,--)",
+ ["fr"]="pas de motifs -- pour -- (n=--,e=--,m=--) (--,--)",
+ ["it"]="niente schemi -- per -- (n=--,e=--,m=--) (--,--)",
+ ["nl"]="geen afbreekpatronen -- voor -- (n=--,e=--,m=--) (--,--)",
+ ["no"]="ingen orddelingsmønster -- for -- (n=--,e=--,m=--) (--,--)",
+ ["ro"]="nu exista sabloane -- pentru -- (n=--,e=--,m=--) (--,--)",
+ },
+ ["3"]={
+ ["cs"]="deleni slov -- pro -- nacteno (n=--,e=--,m=--)",
+ ["de"]="Trenndefinitionen -- fuer -- geladen (n=--,e=--,m=--)",
+ ["en"]="hyphenations -- for -- loaded (n=--,e=--,m=--)",
+ ["fr"]="hyphenations -- pour -- chargés (n=--,e=--,m=--)",
+ ["it"]="sillabazione -- per -- caricata (n=--,e=--,m=--)",
+ ["nl"]="afbreekdefinities -- voor -- geladen (n=--,e=--,m=--)",
+ ["no"]="orddelingsdefinisjon -- for -- er lest inn (n=--,e=--,m=--)",
+ ["ro"]="despartirea in silabe -- pentru -- s-a incarcat (n=--,e=--,m=--)",
+ },
+ ["4"]={
+ ["cs"]="zadne deleni slov -- pro -- (n=--,e=--,m=--)",
+ ["de"]="Keine Trenndefinitionen -- fuer -- (n=--,e=--,m=--)",
+ ["en"]="no hyphenations -- for -- (n=--,e=--,m=--)",
+ ["fr"]="pas d'hyphenations -- pour -- (n=--,e=--,m=--)",
+ ["it"]="niente sillabazione -- per -- (n=--,e=--,m=--)",
+ ["nl"]="geen afbreekdefinities -- voor -- (n=--,e=--,m=--)",
+ ["no"]="ingen orddelingsdefinisjon -- for -- (n=--,e=--,m=--)",
+ ["ro"]="nu exista despartire in silabe -- pentru -- (n=--,e=--,m=--)",
+ },
+ ["5"]={
+ ["cs"]="vzory pro -- nenacteny",
+ ["de"]="Trennmuster fuer -- nicht geladen",
+ ["en"]="patterns for -- not loaded",
+ ["fr"]="les motifs pour -- ne sont pas chargés",
+ ["it"]="schemi per -- non caricati",
+ ["nl"]="afbreekpatronen voor -- niet geladen",
+ ["no"]="orddelingsmønster for -- er ikke lest inn",
+ ["ro"]="sabloanele pentru -- nu sunt incarcate",
+ },
+ ["6"]={
+ ["cs"]="jazyk -- neni definovan",
+ ["de"]="Sprache -- ist undefiniert",
+ ["en"]="language -- is undefined",
+ ["fr"]="langue -- non définie",
+ ["it"]="lingua -- non definita",
+ ["nl"]="taal -- is niet gedefinieerd",
+ ["no"]="spràk -- er udefinert",
+ ["ro"]="limba -- nu este definita",
+ },
+ ["7"]={
+ ["cs"]="specificke volby jazyka [--] zavadeji -- (zavlecenou) mezeru",
+ ["de"]="Sprachenspezifische Option [--] fuegt eine Luecke von -- ein",
+ ["en"]="language specific options [--] introduce a -- skip",
+ ["fr"]="les options spécifiques de langue [--] introduisent un -- saut",
+ ["it"]="opzioni specifiche per la lingua [--] introducono un salto --",
+ ["nl"]="taal specifieke opties [--] introduceren een skip van --",
+ ["no"]="spràk spesifikk opsjon [--] introduserer et -- hopp",
+ ["ro"]="optiunile specifice ale limbii [--] introduc un spatiu --",
+ },
+ ["8"]={
+ ["cs"]="specificke volby jazyka [--] bez mezer pripojeny",
+ ["de"]="Sprachenspezifische Option [--] nahtlos hinzugefuegt",
+ ["en"]="language specific options [--] seamless appended",
+ ["fr"]="les options spécifiques de langue [--] sont ajoutés en douceur",
+ ["it"]="opzioni specifiche per la lingua [--] aggiunte trasparentemente",
+ ["nl"]="taal specifieke opties [--] naadloos toegevoegd",
+ ["no"]="spràk spesifikk opsjon [--] problemfritt tilføyd",
+ ["ro"]="optiunile specifice ale limbii [--] adaugate",
+ },
+ ["9"]={
+ ["cs"]="language -- is active",
+ ["de"]="Sprache -- ist aktiv",
+ ["en"]="language -- is active",
+ ["fr"]="la langue -- est active",
+ ["it"]="lingua -- attiva",
+ ["nl"]="taal -- is actief",
+ ["no"]="spràk -- er aktivt",
+ ["ro"]="limba -- este activa",
+ },
+ ["files"]={ "lang-ini.mkii", "lang-ini.mkiv" },
+ ["title"]={
+ ["cs"]="jazyky",
+ ["de"]="Sprache",
+ ["en"]="language",
+ ["fr"]="langue",
+ ["it"]="lingua",
+ ["nl"]="taal",
+ ["no"]="sprøk",
+ ["ro"]="limbi",
+ },
+ },
+ ["metapost"]={
+ ["1"]={
+ ["cs"]="loading metapost library --",
+ ["de"]="Lade metapost Bibliothek --",
+ ["en"]="loading metapost library --",
+ ["fr"]="chargement de la bibliothèque metapost --",
+ ["it"]="caricamento della libreria metapost --",
+ ["nl"]="metapost bibliotheek -- wordt geladen",
+ ["no"]="metapost bibliotek -- blir lest inn",
+ ["ro"]="se incarca biblioteca metapost --",
+ },
+ ["files"]={ "meta-ini.mkii", "meta-ini.mkiv" },
+ ["title"]={
+ ["cs"]="metapost",
+ ["de"]="metapost",
+ ["en"]="metapost",
+ ["fr"]="metapost",
+ ["it"]="metapost",
+ ["nl"]="metapost",
+ ["no"]="metapost",
+ ["ro"]="metapost",
+ },
+ },
+ ["references"]={
+ ["1"]={
+ ["cs"]="neznama reference --",
+ ["de"]="unbekannte Referenz --",
+ ["en"]="unknown reference --",
+ ["fr"]="réference -- inconnue",
+ ["it"]="riferimento sconosciuto --",
+ ["nl"]="onbekende verwijzing --",
+ ["no"]="ukjent referanse --",
+ ["ro"]="referinta necunoscuta --",
+ },
+ ["2"]={
+ ["cs"]="duplicitni reference -- na strane --",
+ ["de"]="doppelte Referenz -- auf Seite --",
+ ["en"]="duplicate reference -- on page --",
+ ["fr"]="réference -- dupliquée à la page --",
+ ["it"]="riferimento duplicato -- a pagina --",
+ ["nl"]="dubbele verwijzing -- op pagina --",
+ ["no"]="duplikat referanse -- pø side --",
+ ["ro"]="referinta duplicat -- la pagina --",
+ },
+ ["21"]={
+ ["cs"]="dokument -- nacten",
+ ["de"]="Dokument -- geladen",
+ ["en"]="document -- loaded",
+ ["fr"]="document -- chargé",
+ ["it"]="documento -- caricato",
+ ["nl"]="document -- geladen",
+ ["no"]="dokument -- er lest inn",
+ ["ro"]="documentul -- este incarcat",
+ },
+ ["22"]={
+ ["cs"]="dokument -- neni interaktivni",
+ ["de"]="Dokument -- ist nicht aktiv",
+ ["en"]="document -- is not interactive",
+ ["fr"]="le document -- n'est pas interactif",
+ ["it"]="il documento -- non ø interattivo",
+ ["nl"]="document -- is niet interactief",
+ ["no"]="dokument -- er ikke interaktivt",
+ ["ro"]="documentul -- nu este interactiv",
+ },
+ ["23"]={
+ ["cs"]="obskurni (nejasna) reference -- (prefix=--)",
+ ["de"]="Obskure Referenz -- (Prefix=--)",
+ ["en"]="obscure reference -- (prefix=--)",
+ ["fr"]="reference -- indéterminé (préfixe=--)",
+ ["it"]="riferimento ambiguo -- (prefisso=--)",
+ ["nl"]="onduidelijke verwijzing -- (prefix=--)",
+ ["no"]="obskur referanse -- (Prefix=--)",
+ ["ro"]="referinta obscura -- (prefix=--)",
+ },
+ ["3"]={
+ ["cs"]="neznamy typ reference --",
+ ["de"]="unbekannte Referenz Typ --",
+ ["en"]="unknown reference type --",
+ ["fr"]="type -- de réference inconnu",
+ ["it"]="riferimento di tipo sconosciuto --",
+ ["nl"]="type verwijzing -- onbekend",
+ ["no"]="ukjent referansetype --",
+ ["ro"]="tip necunoscut de referinta --",
+ },
+ ["30"]={
+ ["cs"]="neznamy objekt --",
+ ["de"]="unbekanntes Object --",
+ ["en"]="unknown object --",
+ ["fr"]="objet -- inconnu",
+ ["it"]="oggetto sconosciuto --",
+ ["nl"]="onbekend object --",
+ ["no"]="ukjent objekt --",
+ ["ro"]="obiect necunoscut --",
+ },
+ ["31"]={
+ ["cs"]="duplicitni object --",
+ ["de"]="doppeltes Object --",
+ ["en"]="duplicate object --",
+ ["fr"]="objet -- dupliqué",
+ ["it"]="oggetto duplicato --",
+ ["nl"]="dubbel object --",
+ ["no"]="duplikat objekt --",
+ ["ro"]="obiect duplicat --",
+ },
+ ["4"]={
+ ["cs"]="nedovolena reference --",
+ ["de"]="illegale Referenz --",
+ ["en"]="illegal reference --",
+ ["fr"]="réference -- inconnue",
+ ["it"]="riferimento illecito --",
+ ["nl"]="verboden verwijzing --",
+ ["no"]="ulovlig referanse --",
+ ["ro"]="referinta eronata --",
+ },
+ ["files"]={ "core-obj.tex", "core-ref.tex", "strc-ref.tex" },
+ ["title"]={
+ ["cs"]="reference",
+ ["de"]="referenzen",
+ ["en"]="references",
+ ["fr"]="réferences",
+ ["it"]="riferimenti",
+ ["nl"]="verwijzingen",
+ ["no"]="referanser",
+ ["ro"]="referinte",
+ },
+ },
+ ["regimes"]={
+ ["1"]={
+ ["cs"]="kodovani --",
+ ["de"]="Kodierung --",
+ ["en"]="regime --",
+ ["fr"]="encodage --",
+ ["it"]="codifica --",
+ ["nl"]="regime --",
+ ["no"]="koding --",
+ ["ro"]="codificarea --",
+ },
+ ["2"]={
+ ["cs"]="je nacteno kodovani --",
+ ["de"]="Kodierung -- ist geladen",
+ ["en"]="regime -- is loaded",
+ ["fr"]="l'encodage -- est chargé",
+ ["it"]="codifica -- caricata",
+ ["nl"]="regime -- wordt geladen",
+ ["no"]="koding -- er lest inn",
+ ["ro"]="codificarea -- este Encarcata",
+ },
+ ["3"]={
+ ["cs"]="nezname kodovani --",
+ ["de"]="Unbekannte Kodierung --",
+ ["en"]="unknown regime --",
+ ["fr"]="encodage -- inconnu",
+ ["it"]="codifica sconosciuta --",
+ ["nl"]="onbekend regime --",
+ ["no"]="ukjent koding --",
+ ["ro"]="codificarea -- este necunoscuta",
+ },
+ ["files"]={ "regi-ini.mkii" },
+ ["title"]={
+ ["cs"]="kodovani",
+ ["de"]="Kodierung",
+ ["en"]="regime",
+ ["fr"]="encodage",
+ ["it"]="codifica",
+ ["nl"]="regime",
+ ["no"]="koding",
+ ["ro"]="codificari",
+ },
+ },
+ ["specials"]={
+ ["1"]={
+ ["cs"]="-- nacteno",
+ ["de"]="-- geladen",
+ ["en"]="-- loaded",
+ ["fr"]="-- chargé",
+ ["it"]="-- caricato",
+ ["nl"]="-- geladen",
+ ["no"]="-- er lest inn",
+ ["ro"]="-- incarcat",
+ },
+ ["2"]={
+ ["cs"]="neni dovoleno hlubsi zanoreni --",
+ ["de"]="keine tiefere Verschachtelung erlaubt --",
+ ["en"]="no deeper nesting is permitted --",
+ ["fr"]="pas d'imbracations plus profondes ne sont permises --",
+ ["it"]="non ø permesso un annidamento maggiore --",
+ ["nl"]="verdere nesting is niet toegestaan --",
+ ["no"]="dypere 'nesting' er ikke tillatt --",
+ ["ro"]="nu este permis un nivel de imbricare mai mare --",
+ },
+ ["3"]={
+ ["cs"]="-- je resetovano",
+ ["de"]="-- ist zurueckgesetzt",
+ ["en"]="-- is reset",
+ ["fr"]="-- est remis à zéro",
+ ["it"]="-- reimpostato",
+ ["nl"]="-- gereset",
+ ["no"]="-- er tilbakestilt",
+ ["ro"]="-- s-a resetat",
+ },
+ ["4"]={
+ ["cs"]="prikaz -- neexistuje",
+ ["de"]="Befehl -- existiert nicht",
+ ["en"]="command -- does not exist",
+ ["fr"]="la commande -- n'existe pas",
+ ["it"]="il comando -- non esiste",
+ ["nl"]="commando -- bestaat niet",
+ ["no"]="kommando -- eksisterer ikke",
+ ["ro"]="comanda -- nu exista",
+ },
+ ["5"]={
+ ["cs"]="nacita se definicni soubor --",
+ ["de"]="lade Definitionsdatei --",
+ ["en"]="loading definition file --",
+ ["fr"]="chargement du fichier de définition --",
+ ["it"]="caricamento del file di definizione --",
+ ["nl"]="definitiefile -- wordt geladen",
+ ["no"]="leser inn definisjonsfil for --",
+ ["ro"]="se incarca fisierul de definitii --",
+ },
+ ["6"]={
+ ["cs"]="zanoreni neni dovoleno",
+ ["de"]="Verschachtelung nicht erlaubt",
+ ["en"]="nesting is not permitted",
+ ["fr"]="l'imbrication n'est pas permise",
+ ["it"]="annidamento non permesso",
+ ["nl"]="nesting is niet toegestaan",
+ ["no"]="'nesting' er ikke tillatt",
+ ["ro"]="imbricarea nu este permisa",
+ },
+ ["7"]={
+ ["cs"]="neznamy ovladac (driver) --",
+ ["de"]="unbekante Driver --",
+ ["en"]="unknown driver --",
+ ["fr"]="pilote -- inconnu",
+ ["it"]="driver sconosciuto --",
+ ["nl"]="onbekende driver --",
+ ["no"]="ukjent driver --",
+ ["ro"]="driver necunoscut --",
+ },
+ ["files"]={ "spec-ini.tex" },
+ ["title"]={
+ ["cs"]="speciality",
+ ["de"]="spezielles",
+ ["en"]="specials",
+ ["fr"]="specials",
+ ["it"]="specialitø",
+ ["nl"]="specials",
+ ["no"]="specials",
+ ["ro"]="specials",
+ },
+ },
+ ["structures"]={
+ ["1"]={
+ ["cs"]="zacatek oddilu (sekce) --",
+ ["de"]="Begin des Abschnittsblocks --",
+ ["en"]="begin of sectionblock --",
+ ["fr"]="début de blocsection --",
+ ["it"]="inizio del blocco (sezione) --",
+ ["nl"]="begin van sectieblok --",
+ ["no"]="starten av blokk -- (seksjon)",
+ ["ro"]="inceput de bloc sectiune --",
+ },
+ ["2"]={
+ ["cs"]="konec oddilu (sekce) --",
+ ["de"]="Ende des Abschnittsblocks --",
+ ["en"]="end of sectionblock --",
+ ["fr"]="fin de blocsection --",
+ ["it"]="fine del blocco (sezione) --",
+ ["nl"]="eind van sectieblok --",
+ ["no"]="slutten av blokk -- (seksjon)",
+ ["ro"]="sfarsit de bloc sectiune --",
+ },
+ ["files"]={ "core-sec.mkii", "core-sec.mkiv", "strc-sbe.tex" },
+ ["title"]={
+ ["cs"]="struktury",
+ ["de"]="struktur",
+ ["en"]="structure",
+ ["fr"]="structure",
+ ["it"]="struttura",
+ ["nl"]="structuur",
+ ["no"]="struktur",
+ ["ro"]="structuri",
+ },
+ },
+ ["symbols"]={
+ ["1"]={
+ ["cs"]="nacita se soubor symbolu --",
+ ["de"]="Lade Symboldatei --",
+ ["en"]="loading symbolset --",
+ ["fr"]="chargement du jeu de symbole --",
+ ["it"]="caricamento gruppo di simboli --",
+ ["nl"]="symboolset -- wordt geladen",
+ ["no"]="leser inn symbolsett --",
+ ["ro"]="se incarca setul de simboluri --",
+ },
+ ["files"]={ "symb-ini.tex" },
+ ["title"]={
+ ["cs"]="symboly",
+ ["de"]="Symbole",
+ ["en"]="symbols",
+ ["fr"]="symboles",
+ ["it"]="simboli",
+ ["nl"]="symbolen",
+ ["no"]="symboler",
+ ["ro"]="simboluri",
+ },
+ },
+ ["systems"]={
+ ["1"]={
+ ["cs"]="nacteni pomocneho souboru odlozeno (typemode)",
+ ["de"]="Laden der Hilfsdatei aufgeschoben (Eingabe-Modus)",
+ ["en"]="loading utility-file postponed (typemode)",
+ ["fr"]="chargement de fichier utilitaire reporté (typemode)",
+ ["it"]="caricamento dei file supplementari posticipato (typemode)",
+ ["nl"]="laden hulpfile uitgesteld (typemode)",
+ ["no"]="innlesning av hjelpefila utsatt (typemode)",
+ ["ro"]="se incarca utilitarul-fisierul este amanat (typemode)",
+ },
+ ["10"]={
+ ["cs"]="nepouzivejte em v --",
+ ["de"]="Benutzte kein em in --",
+ ["en"]="don't use em in --",
+ ["fr"]="n'utilisez pas em dans --",
+ ["it"]="non usare em in --",
+ ["nl"]="gebruik geen em in --",
+ ["no"]="ikke bruk em i --",
+ ["ro"]="nu folositi em in --",
+ },
+ ["11"]={
+ ["cs"]="vytvarim jednoduchy pomocny soubor",
+ ["de"]="Erstelle einfache Hilfdatei",
+ ["en"]="building simple util",
+ ["fr"]="construction util simple",
+ ["it"]="costruzione di un semplice supplemento",
+ ["nl"]="aanmaken basale hulpfile",
+ ["no"]="lager enkel hjelpefil",
+ ["ro"]="se creeaza un utilitar simplu",
+ },
+ ["12"]={
+ ["cs"]="pomosny soubor neni setriden, pouzijte texutil",
+ ["de"]="Die Hilfdatei ist nicht sortiert, verwende texutil",
+ ["en"]="the utility-file is not sorted, use texutil",
+ ["fr"]="le fichier utilitaire n'est pas trié, utilise texutil",
+ ["it"]="file di supplemento non ordinato, usare texutil",
+ ["nl"]="de hulpfile is niet gesorteerd, gebruik texutil",
+ ["no"]="hjelpefila er ikke sortert, bruk texutil",
+ ["ro"]="fisierul utilitar nu este sortat, folositi texutil",
+ },
+ ["13"]={
+ ["cs"]="znacka -- definovana --",
+ ["de"]="Beschriftung -- definiert --",
+ ["en"]="mark -- defined --",
+ ["fr"]="marquage -- defini --",
+ ["it"]="marcatura -- definita --",
+ ["nl"]="markering -- gedefinieerd --",
+ ["no"]="markering -- definert --",
+ ["ro"]="marcajul -- definit --",
+ },
+ ["14"]={
+ ["cs"]="vynucena nova stranka v seznamu na --",
+ ["de"]="Erzwungendes Seitenumbruch in Liste bei --",
+ ["en"]="forced newpage in list at --",
+ ["fr"]="nouvellepage forcée dans la liste à --",
+ ["it"]="nuova pagina obbligata in lista a --",
+ ["nl"]="geforceerde paginaovergang in lijst voor --",
+ ["no"]="tvunget sideskift i liste ved --",
+ ["ro"]="s-a fortat trecere pa pagina noua in lista la --",
+ },
+ ["15"]={
+ ["cs"]="uklada se buffer --",
+ ["de"]="Speichere Buffer --",
+ ["en"]="saving buffer --",
+ ["fr"]="sauvegarde du tampon (buffer) --",
+ ["it"]="salvataggio del buffer --",
+ ["nl"]="wegschrijven buffer --",
+ ["no"]="lagrer Buffer --",
+ ["ro"]="buffer salvat --",
+ },
+ ["16"]={
+ ["cs"]="sazi se buffer --",
+ ["de"]="Setzte Buffer --",
+ ["en"]="typesetting buffer --",
+ ["fr"]="composition du tampon (buffer) --",
+ ["it"]="composizione del buffer --",
+ ["nl"]="inlezen buffer --",
+ ["no"]="tegnsetter buffer --",
+ ["ro"]="buffer-ul -- s-a cules",
+ },
+ ["17"]={
+ ["cs"]="sazi se doslovny (verbatim) buffer --",
+ ["de"]="Setzte tippen-Buffer --",
+ ["en"]="typesetting verbatim buffer --",
+ ["fr"]="composition textuelle du tampon (buffer) --",
+ ["it"]="composizione verbatim del buffer --",
+ ["nl"]="verbatim inlezen buffer --",
+ ["no"]="tegnsetter verbatim-buffer --",
+ ["ro"]="se culege buffer-ul verbatim --",
+ },
+ ["18"]={
+ ["cs"]="synonymum -- -- neexistuje",
+ ["de"]="Synonym -- -- existiert nicht",
+ ["en"]="synonym -- -- does not exist",
+ ["fr"]="le synonyme -- -- n'existe pas",
+ ["it"]="sinonimo -- -- non esistente",
+ ["nl"]="synoniem -- -- bestaat niet",
+ ["no"]="synonym -- -- eksisterer ikke",
+ ["ro"]="sinonimul -- -- nu exista",
+ },
+ ["19"]={
+ ["cs"]="vyznam (synonyma) -- nacten",
+ ["de"]="Bedeutung (synonyme) von -- geladen",
+ ["en"]="meaning (synonyms) of -- loaded",
+ ["fr"]="signification (synonymes) de -- chargée",
+ ["it"]="significato (sinonimi) di -- caricato",
+ ["nl"]="betekenissen (synoniemen) van -- geladen",
+ ["no"]="betydning (synonymer) av -- er lest inn",
+ ["ro"]="intelesul (sinonimele) pentru -- incarcat",
+ },
+ ["2"]={
+ ["cs"]="-- nacteno",
+ ["de"]="-- geladen",
+ ["en"]="-- loaded",
+ ["fr"]="-- chargé",
+ ["it"]="-- caricato",
+ ["nl"]="-- geladen",
+ ["no"]="-- er lest inn",
+ ["ro"]="-- s-a incarcat",
+ },
+ ["20"]={
+ ["cs"]="vyznam (trideni) -- nacten",
+ ["de"]="Bedeutung (sortieren) von -- geladen",
+ ["en"]="meaning (sorts) of -- loaded",
+ ["fr"]="signification (tris) de -- chargée",
+ ["it"]="significato (specie) di -- caricato",
+ ["nl"]="betekenissen (sorteren) van -- geladen",
+ ["no"]="betydning (sorterer) av -- er lest inn",
+ ["ro"]="intelesul (ordinea) pentru -- incarcat",
+ },
+ ["21"]={
+ ["cs"]="pomocny soubor necten",
+ ["de"]="Die Hilfsdatei ist nicht geladen",
+ ["en"]="no utility data is loaded",
+ ["fr"]="pas de données utilitaires chargées",
+ ["it"]="nessuna informazione supplementare caricata",
+ ["nl"]="de hulpfile is niet geladen",
+ ["no"]="hjelpefila er ikke lest inn",
+ ["ro"]="nici o data utilitara nu este incarcata",
+ },
+ ["22"]={
+ ["cs"]="pouzijte platny pomocny soubor",
+ ["de"]="Benoetige gueltige Hilfsdateie",
+ ["en"]="use a valid utilityfile",
+ ["fr"]="utilise un fichier utilitaire valide",
+ ["it"]="usare un file supplementare valido",
+ ["nl"]="gebruik een goede hulpfile",
+ ["no"]="bruk en gyldig hjelpefil",
+ ["ro"]="folositi un fisier utilitar valid",
+ },
+ ["23"]={
+ ["cs"]="-- upraveno na --",
+ ["de"]="-- angeordnet auf --",
+ ["en"]="-- arranged at --",
+ ["fr"]="-- arrangé à --",
+ ["it"]="-- sistemato a --",
+ ["nl"]="-- gearrangeerd op --",
+ ["no"]="-- arrangert på --",
+ ["ro"]="-- aranjat la --",
+ },
+ ["24"]={
+ ["cs"]="plovouci bloky",
+ ["de"]="Fliessbloecke",
+ ["en"]="Floatblocks",
+ ["fr"]="blocsflottants",
+ ["it"]="Oggetti mobili",
+ ["nl"]="Plaatsblokken",
+ ["no"]="Flytblokker",
+ ["ro"]="Blocuri",
+ },
+ ["25"]={
+ ["cs"]="reference",
+ ["de"]="Referenzen",
+ ["en"]="References",
+ ["fr"]="Réferences",
+ ["it"]="Riferimenti",
+ ["nl"]="Verwijzingen",
+ ["no"]="Referanser",
+ ["ro"]="Referinte",
+ },
+ ["26"]={
+ ["cs"]="registry",
+ ["de"]="Register",
+ ["en"]="Registers",
+ ["fr"]="Registres",
+ ["it"]="Registri",
+ ["nl"]="Registers",
+ ["no"]="Registere",
+ ["ro"]="Registri",
+ },
+ ["27"]={
+ ["cs"]="verze",
+ ["de"]="Version",
+ ["en"]="Version",
+ ["fr"]="Version",
+ ["it"]="Versione",
+ ["nl"]="Versie",
+ ["no"]="Versjon",
+ ["ro"]="Versiune",
+ },
+ ["4"]={
+ ["cs"]="prikaz -- je jiz definovan",
+ ["de"]="Befehl -- ist bereits definiert",
+ ["en"]="command -- is already defined",
+ ["fr"]="la commande -- est déjà définie",
+ ["it"]="comando -- già definito",
+ ["nl"]="commando -- is al gedefinieerd",
+ ["no"]="kommando -- er allerede definert",
+ ["ro"]="comanda -- este deja definita",
+ },
+ ["41"]={
+ ["cs"]="externi soubor -- ve skupine -- neexistuje",
+ ["de"]="Externe Datei -- in Gruppe -- existiert nicht",
+ ["en"]="external file -- in group -- does not exist",
+ ["fr"]="le fichier externe -- du groupe -- n'existe pas",
+ ["it"]="il file esterno -- del gruppo -- non esiste",
+ ["nl"]="externe file -- in groep -- bestaat niet",
+ ["no"]="ekstern fil -- i gruppe -- eksisterer ikke",
+ ["ro"]="fisierul extern -- din grupul -- nu exista",
+ },
+ ["5"]={
+ ["cs"]="makra z -- nactena",
+ ["de"]="Modul -- geladen",
+ ["en"]="module -- loaded",
+ ["fr"]="module -- chargé",
+ ["it"]="macro del modulo -- caricate",
+ ["nl"]="module -- geladen",
+ ["no"]="makroene i modul -- er lest inn",
+ ["ro"]="macro-urile din modulul -- s-au incarcat",
+ },
+ ["6"]={
+ ["cs"]="zadna makra v -- nenalezena",
+ ["de"]="Modul -- gefunden",
+ ["en"]="module -- not found",
+ ["fr"]="module -- non trouvé",
+ ["it"]="nessuna macro trovata nel modulo --",
+ ["nl"]="geen module -- gevonden",
+ ["no"]="ingen makroer funnet i modul ---",
+ ["ro"]="nu s-au gasit macro-uri in modulul --",
+ },
+ ["7"]={
+ ["cs"]="makra z -- jsou jiz nactena",
+ ["de"]="Modul -- bereits geladen",
+ ["en"]="module -- already loaded",
+ ["fr"]="module -- déjà chargé",
+ ["it"]="macro del modulo -- già caricate",
+ ["nl"]="module -- reeds geladen",
+ ["no"]="makroene i modul -- er allerede lest inn",
+ ["ro"]="macro-urile din modulul -- s-au incarcat deja",
+ },
+ ["8"]={
+ ["cs"]="nova verze pomocneho souboru, je treba druheho behu",
+ ["de"]="Neue Version der Hilfsdatei, zweiter Durchlauf benoetigt",
+ ["en"]="new version of utility file, second pass needed",
+ ["fr"]="nouvelle version de fichier utilitaire, seconde passe nécessaire",
+ ["it"]="nuova versione del file supplementare, seconda passata necessaria",
+ ["nl"]="nieuwe versie hulpfile, tweede run nodig",
+ ["no"]="ny versjon av hjelpefil, andre gjennomkjøring nødvendig",
+ ["ro"]="o noua versiune de fisier utilitar, este necesara o noua trecere",
+ },
+ ["9"]={
+ ["cs"]="-- nenalezeno/nezpracovano",
+ ["de"]="-- nicht gefunden/verarbeitet",
+ ["en"]="-- not found/processed",
+ ["fr"]="-- non trouvé/traité",
+ ["it"]="-- non trovato/elaborato",
+ ["nl"]="-- niet gevonden/geplaatst",
+ ["no"]="-- ikke funnet/behandlet",
+ ["ro"]="-- nu este gasit/procesat",
+ },
+ ["91"]={
+ ["en"]="papertray --",
+ ["nl"]="papierlade --",
+ },
+ ["files"]={ "core-mis.tex", "page-ini.tex", "prag-gen.tex", "strc-mar.tex" },
+ ["title"]={
+ ["cs"]="system",
+ ["de"]="system",
+ ["en"]="system",
+ ["fr"]="système",
+ ["it"]="sistema",
+ ["nl"]="systeem",
+ ["no"]="system",
+ ["ro"]="sistem",
+ },
+ },
+ ["textblocks"]={
+ ["1"]={
+ ["cs"]="nova verze, je treba druhy beh",
+ ["de"]="neue Version, zweiter Durchlauf benoetigt",
+ ["en"]="new version, second pass needed",
+ ["fr"]="nouvelle version, une seconde passe est nécessaire",
+ ["it"]="nuova versione, seconda passata necessaria",
+ ["nl"]="nieuwe versie, tweede run nodig",
+ ["no"]="ny versjon, andre gjennomkjøring nødvendig",
+ ["ro"]="o noua versiune, este nevoie de inca o trecere",
+ },
+ ["10"]={
+ ["cs"]="-- nacteno a zpracovano",
+ ["de"]="-- geladen und verarbeitet",
+ ["en"]="-- loaded and processed",
+ ["fr"]="-- chargé et traité",
+ ["it"]="-- caricato ed elaborato",
+ ["nl"]="-- geladen en verwerkt",
+ ["no"]="-- lest inn og behandlet",
+ ["ro"]="-- incarcat si procesat",
+ },
+ ["11"]={
+ ["cs"]="-- nacteno a vysazeno",
+ ["de"]="-- geladen und gesetzt",
+ ["en"]="-- loaded and typeset",
+ ["fr"]="-- chargé et composé",
+ ["it"]="-- caricato e composto",
+ ["nl"]="-- geladen en geplaatst",
+ ["no"]="-- lest inn og tegnsatt",
+ ["ro"]="-- incarcat si cules",
+ },
+ ["12"]={
+ ["cs"]="-- preskoceno",
+ ["de"]="-- ausgelassen",
+ ["en"]="-- skipped",
+ ["fr"]="-- sauté",
+ ["it"]="-- saltato",
+ ["nl"]="-- overgeslagen",
+ ["no"]="-- utelatt",
+ ["ro"]="-- sarit peste",
+ },
+ ["2"]={
+ ["cs"]="zapisuji bloky do --",
+ ["de"]="schreibe Bloecke zu --",
+ ["en"]="writing blocks to --",
+ ["fr"]="ecriture des blocs vers --",
+ ["it"]="scrittura dei blocchi su --",
+ ["nl"]="wegschrijven blokken naar --",
+ ["no"]="skriver blokker til --",
+ ["ro"]="se scriu blocurile in --",
+ },
+ ["3"]={
+ ["cs"]="ctu bloky z --",
+ ["de"]="lese Bloecke von --",
+ ["en"]="reading blocks from --",
+ ["fr"]="lecture des blocs en provenance de --",
+ ["it"]="lettura dei blocchi da --",
+ ["nl"]="inlezen blokken uit --",
+ ["no"]="leser blokker fra --",
+ ["ro"]="se citesc blocurile din --",
+ },
+ ["4"]={
+ ["cs"]="je treba druhy beh",
+ ["de"]="zweiter Durchlauf benoetigt",
+ ["en"]="second pass needed",
+ ["fr"]="seconde passe nécessaire",
+ ["it"]="seconda passata necessaria",
+ ["nl"]="er is een tweede run nodig",
+ ["no"]="andre gjennomkjøring nødvendig",
+ ["ro"]="este nevoie de inca o trecere",
+ },
+ ["5"]={
+ ["cs"]="-- neni skryto",
+ ["de"]="-- nicht verborgen",
+ ["en"]="-- not hidden",
+ ["fr"]="-- non caché",
+ ["it"]="-- non nascosto",
+ ["nl"]="-- niet verborgen",
+ ["no"]="-- ikke skjult",
+ ["ro"]="-- nu este ascuns",
+ },
+ ["6"]={
+ ["cs"]="-- skryto a zpracovano",
+ ["de"]="-- verborgen und verarbeitet",
+ ["en"]="-- hidden and processed",
+ ["fr"]="-- caché et traité",
+ ["it"]="-- nascosto ed elaborato",
+ ["nl"]="-- verborgen en verwerkt",
+ ["no"]="-- skjult og behandlet",
+ ["ro"]="-- ascuns si procesat",
+ },
+ ["7"]={
+ ["cs"]="-- skryto",
+ ["de"]="-- verborgen",
+ ["en"]="-- hidden",
+ ["fr"]="-- caché",
+ ["it"]="-- nascosto",
+ ["nl"]="-- verborgen",
+ ["no"]="-- skjult",
+ ["ro"]="-- ascuns",
+ },
+ ["8"]={
+ ["cs"]="-- vysazeno",
+ ["de"]="-- gesetzt",
+ ["en"]="-- typeset",
+ ["fr"]="-- composé",
+ ["it"]="-- composto",
+ ["nl"]="-- gehandhaafd",
+ ["no"]="-- tegnsatt",
+ ["ro"]="-- cules",
+ },
+ ["9"]={
+ ["cs"]="-- nevysazeno",
+ ["de"]="-- nicht gesetzt",
+ ["en"]="-- not typeset",
+ ["fr"]="-- non composé",
+ ["it"]="-- non composto",
+ ["nl"]="-- niet gehandhaafd",
+ ["no"]="-- ikke tegnsatt",
+ ["ro"]="-- nu este cules",
+ },
+ ["files"]={ "core-blk.tex" },
+ ["title"]={
+ ["cs"]="textovyblok",
+ ["de"]="textblock",
+ ["en"]="textblocks",
+ ["fr"]="blocs de texte",
+ ["it"]="blocchi di testo",
+ ["nl"]="tekstblokken",
+ ["no"]="tekstblokker",
+ ["ro"]="blocuri de text",
+ },
+ },
+ ["verbatims"]={
+ ["1"]={
+ ["cs"]="soubor -- neexistuje",
+ ["de"]="Datei -- existiert nicht",
+ ["en"]="file -- does not exist",
+ ["fr"]="le fichier -- n'existe pas",
+ ["it"]="il file -- non esiste",
+ ["nl"]="file -- bestaat niet",
+ ["no"]="fil -- eksisterer ikke",
+ ["ro"]="fisierul -- nu exista",
+ },
+ ["files"]={ "core-ver.tex" },
+ ["title"]={
+ ["cs"]="verbatim",
+ ["de"]="verbatim",
+ ["en"]="verbatim",
+ ["fr"]="verbatim",
+ ["it"]="verbatim",
+ ["nl"]="typen",
+ ["no"]="verbatim",
+ ["ro"]="verbatim",
+ },
+ },
+ ["versions"]={
+ ["1"]={
+ ["cs"]="postradam @+",
+ ["de"]="fehlendes @+",
+ ["en"]="missing @+",
+ ["fr"]="@+ manquant",
+ ["it"]="@+ mancante",
+ ["nl"]="er mankeert een @+",
+ ["no"]="manglende @+",
+ ["ro"]="lipseste @+",
+ },
+ ["2"]={
+ ["cs"]="oznacuji se strany",
+ ["de"]="Erstelle Seiten",
+ ["en"]="marking pages",
+ ["fr"]="marquage des pages",
+ ["it"]="marcatura pagine",
+ ["nl"]="markeren pagina's",
+ ["no"]="markerer sider",
+ ["ro"]="pagini marcate",
+ },
+ ["3"]={
+ ["cs"]="oznacene strany: --",
+ ["de"]="Ausgewaehlte Seiten: --",
+ ["en"]="selected pages: --",
+ ["fr"]="pages sélectionnées : --",
+ ["it"]="pagine selezionate: --",
+ ["nl"]="geselecteerde pagina's: --",
+ ["no"]="valgte sider: --",
+ ["ro"]="pagini selectate: --",
+ },
+ ["files"]={ "core-int.tex" },
+ ["title"]={
+ ["cs"]="verze",
+ ["de"]="Version",
+ ["en"]="version",
+ ["fr"]="version",
+ ["it"]="version",
+ ["nl"]="versie",
+ ["no"]="versjon",
+ ["ro"]="versiuni",
+ },
+ },
+} \ No newline at end of file
diff --git a/tex/context/base/mult-mfr.tex b/tex/context/base/mult-mfr.tex
new file mode 100644
index 000000000..ecfd88ecc
--- /dev/null
+++ b/tex/context/base/mult-mfr.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{réference -- inconnue}
+\setinterfacemessage{references}{3}{type -- de réference inconnu}
+\setinterfacemessage{references}{2}{réference -- dupliquée à la page --}
+\setinterfacemessage{references}{4}{réference -- inconnue}
+\setinterfacemessage{references}{title}{réferences}
+\setinterfacemessage{references}{30}{objet -- inconnu}
+\setinterfacemessage{references}{31}{objet -- dupliqué}
+\setinterfacemessage{references}{21}{document -- chargé}
+\setinterfacemessage{references}{22}{le document -- n'est pas interactif}
+\setinterfacemessage{references}{23}{reference -- indéterminé (préfixe=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{manipulation -- de police}
+\setinterfacemessage{handlings}{3}{manipulation -- inconnue de police}
+\setinterfacemessage{handlings}{2}{la manipulation -- de police est chargée}
+\setinterfacemessage{handlings}{title}{manipulation}
+\setinterfacemessage{systems}{title}{système}
+\setinterfacemessage{systems}{41}{le fichier externe -- du groupe -- n'existe pas}
+\setinterfacemessage{systems}{9}{-- non trouvé/traité}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{nouvelle version de fichier utilitaire, seconde passe nécessaire}
+\setinterfacemessage{systems}{21}{pas de données utilitaires chargées}
+\setinterfacemessage{systems}{20}{signification (tris) de -- chargée}
+\setinterfacemessage{systems}{5}{module -- chargé}
+\setinterfacemessage{systems}{4}{la commande -- est déjà définie}
+\setinterfacemessage{systems}{27}{Version}
+\setinterfacemessage{systems}{26}{Registres}
+\setinterfacemessage{systems}{25}{Réferences}
+\setinterfacemessage{systems}{24}{blocsflottants}
+\setinterfacemessage{systems}{1}{chargement de fichier utilitaire reporté (typemode)}
+\setinterfacemessage{systems}{23}{-- arrangé à --}
+\setinterfacemessage{systems}{22}{utilise un fichier utilitaire valide}
+\setinterfacemessage{systems}{2}{-- chargé}
+\setinterfacemessage{systems}{19}{signification (synonymes) de -- chargée}
+\setinterfacemessage{systems}{18}{le synonyme -- -- n'existe pas}
+\setinterfacemessage{systems}{7}{module -- déjà chargé}
+\setinterfacemessage{systems}{6}{module -- non trouvé}
+\setinterfacemessage{systems}{14}{nouvellepage forcée dans la liste à --}
+\setinterfacemessage{systems}{15}{sauvegarde du tampon (buffer) --}
+\setinterfacemessage{systems}{16}{composition du tampon (buffer) --}
+\setinterfacemessage{systems}{17}{composition textuelle du tampon (buffer) --}
+\setinterfacemessage{systems}{13}{marquage -- defini --}
+\setinterfacemessage{systems}{12}{le fichier utilitaire n'est pas trié, utilise texutil}
+\setinterfacemessage{systems}{11}{construction util simple}
+\setinterfacemessage{systems}{10}{n'utilisez pas em dans --}
+\setinterfacemessage{floatblocks}{1}{-- renuméroté / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- déplacé}
+\setinterfacemessage{floatblocks}{2}{-- sauvegardé}
+\setinterfacemessage{floatblocks}{5}{ordre adapté}
+\setinterfacemessage{floatblocks}{4}{-- placé}
+\setinterfacemessage{floatblocks}{7}{n flottants de bas de page limité à --}
+\setinterfacemessage{floatblocks}{6}{n flottants de haut de page limité à --}
+\setinterfacemessage{floatblocks}{9}{ordre perturbé}
+\setinterfacemessage{floatblocks}{8}{moins de -- lignes}
+\setinterfacemessage{floatblocks}{title}{blocs de flottants}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{indéfini}
+\setinterfacemessage{floatblocks}{11}{pas de bloc donné}
+\setinterfacemessage{floatblocks}{10}{-- limité}
+\setinterfacemessage{interactions}{1}{ratio d'aspect -- x -- (b x h)}
+\setinterfacemessage{interactions}{3}{inactif}
+\setinterfacemessage{interactions}{2}{actif}
+\setinterfacemessage{interactions}{5}{le fichier joint -- est inconnu}
+\setinterfacemessage{interactions}{4}{pas de synchronisation de page (--) dans le hmode}
+\setinterfacemessage{interactions}{6}{le fichier joint -- n'existe pas}
+\setinterfacemessage{interactions}{title}{interaction}
+\setinterfacemessage{interactions}{21}{-- code inseré}
+\setinterfacemessage{structures}{1}{début de blocsection --}
+\setinterfacemessage{structures}{title}{structure}
+\setinterfacemessage{structures}{2}{fin de blocsection --}
+\setinterfacemessage{linguals}{1}{les motifs -- pour -- sont chargés (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{hyphenations -- pour -- chargés (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{pas de motifs -- pour -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{les motifs pour -- ne sont pas chargés}
+\setinterfacemessage{linguals}{4}{pas d'hyphenations -- pour -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{les options spécifiques de langue [--] introduisent un -- saut}
+\setinterfacemessage{linguals}{6}{langue -- non définie}
+\setinterfacemessage{linguals}{9}{la langue -- est active}
+\setinterfacemessage{linguals}{8}{les options spécifiques de langue [--] sont ajoutés en douceur}
+\setinterfacemessage{linguals}{title}{langue}
+\setinterfacemessage{linguals}{10}{motifs -- chargés}
+\setinterfacemessage{regimes}{1}{encodage --}
+\setinterfacemessage{regimes}{3}{encodage -- inconnu}
+\setinterfacemessage{regimes}{2}{l'encodage -- est chargé}
+\setinterfacemessage{regimes}{title}{encodage}
+\setinterfacemessage{filters}{1}{le filtre -- est chargé}
+\setinterfacemessage{filters}{title}{filtre}
+\setinterfacemessage{filters}{2}{filtre -- inconnu}
+\setinterfacemessage{verbatims}{1}{le fichier -- n'existe pas}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{encodage --}
+\setinterfacemessage{encodings}{3}{encodage -- inconnu}
+\setinterfacemessage{encodings}{2}{l'encodage -- est chargé}
+\setinterfacemessage{encodings}{title}{encodage}
+\setinterfacemessage{columns}{1}{seules -- colonnes possibles}
+\setinterfacemessage{columns}{3}{problèmes, désactive l'équilibrage}
+\setinterfacemessage{columns}{2}{utilisez \string\filbreak\space en tant qu'alternative}
+\setinterfacemessage{columns}{5}{flottant en partie inférieure pas encore supporté}
+\setinterfacemessage{columns}{4}{flottant en partie supérieure pas encore supporté}
+\setinterfacemessage{columns}{7}{équilibrage abandonné après 100 pas}
+\setinterfacemessage{columns}{6}{-- flottant(s) reporté(s)}
+\setinterfacemessage{columns}{9}{vérification des irrégularités}
+\setinterfacemessage{columns}{8}{équilibré en -- pas}
+\setinterfacemessage{columns}{title}{colonnes}
+\setinterfacemessage{columns}{13}{flottant large déplacé dans la partie supérieure de la colonne}
+\setinterfacemessage{columns}{12}{flottant déplacé à la colonne suivante / --}
+\setinterfacemessage{columns}{11}{flottant mis à la largeur de la colonne}
+\setinterfacemessage{columns}{10}{(moins de) 1 ligne restante}
+\setinterfacemessage{textblocks}{1}{nouvelle version, une seconde passe est nécessaire}
+\setinterfacemessage{textblocks}{3}{lecture des blocs en provenance de --}
+\setinterfacemessage{textblocks}{2}{ecriture des blocs vers --}
+\setinterfacemessage{textblocks}{5}{-- non caché}
+\setinterfacemessage{textblocks}{4}{seconde passe nécessaire}
+\setinterfacemessage{textblocks}{7}{-- caché}
+\setinterfacemessage{textblocks}{6}{-- caché et traité}
+\setinterfacemessage{textblocks}{9}{-- non composé}
+\setinterfacemessage{textblocks}{8}{-- composé}
+\setinterfacemessage{textblocks}{title}{blocs de texte}
+\setinterfacemessage{textblocks}{12}{-- sauté}
+\setinterfacemessage{textblocks}{11}{-- chargé et composé}
+\setinterfacemessage{textblocks}{10}{-- chargé et traité}
+\setinterfacemessage{symbols}{1}{chargement du jeu de symbole --}
+\setinterfacemessage{symbols}{title}{symboles}
+\setinterfacemessage{versions}{1}{@+ manquant}
+\setinterfacemessage{versions}{3}{pages sélectionnées : --}
+\setinterfacemessage{versions}{2}{marquage des pages}
+\setinterfacemessage{versions}{title}{version}
+\setinterfacemessage{specials}{1}{-- chargé}
+\setinterfacemessage{specials}{3}{-- est remis à zéro}
+\setinterfacemessage{specials}{2}{pas d'imbracations plus profondes ne sont permises --}
+\setinterfacemessage{specials}{5}{chargement du fichier de définition --}
+\setinterfacemessage{specials}{4}{la commande -- n'existe pas}
+\setinterfacemessage{specials}{7}{pilote -- inconnu}
+\setinterfacemessage{specials}{6}{l'imbrication n'est pas permise}
+\setinterfacemessage{specials}{title}{specials}
+\setinterfacemessage{javascript}{1}{chargement du jeu de script --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{préambule -- inconnu}
+\setinterfacemessage{fonts}{1}{encodage --}
+\setinterfacemessage{fonts}{3}{variante -- inconnue}
+\setinterfacemessage{fonts}{2}{la variante -- est chargée}
+\setinterfacemessage{fonts}{5}{le style -- n'est pas défini}
+\setinterfacemessage{fonts}{4}{policecorps -- n'est pas définie}
+\setinterfacemessage{fonts}{7}{format -- inconnu}
+\setinterfacemessage{fonts}{6}{-- est chargé}
+\setinterfacemessage{fonts}{14}{policecorps -- est défini (une définition globale pourrait être plus adéquat)}
+\setinterfacemessage{fonts}{8}{style -- défini}
+\setinterfacemessage{fonts}{title}{corps de texte}
+\setinterfacemessage{fonts}{10}{fichier de police -- inconnu}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{fichier global --}
+\setinterfacemessage{databases}{2}{fichier local --}
+\setinterfacemessage{databases}{4}{fichier inconnu --}
+\setinterfacemessage{databases}{title}{bases de données}
+\setinterfacemessage{colors}{1}{le système -- est globalement activé}
+\setinterfacemessage{colors}{3}{-- n'est pas défini --}
+\setinterfacemessage{colors}{2}{le système -- est localement activé}
+\setinterfacemessage{colors}{5}{système -- inconnu}
+\setinterfacemessage{colors}{4}{le système -- est chargé}
+\setinterfacemessage{colors}{7}{le palette -- n'est pas disponible}
+\setinterfacemessage{colors}{6}{la palette -- est disponible}
+\setinterfacemessage{colors}{9}{l'espace de couleur -- n'est pas supporté}
+\setinterfacemessage{colors}{8}{la spécification -- de la couleur -- devient noire}
+\setinterfacemessage{colors}{title}{couleurs}
+\setinterfacemessage{colors}{12}{-- est enregistré}
+\setinterfacemessage{colors}{11}{la couleur est convertie en niveau de gris}
+\setinterfacemessage{colors}{10}{-- l'espace de couleur est supporté}
+\setinterfacemessage{layouts}{1}{hauteurtexte adaptée avec -- à la page --}
+\setinterfacemessage{layouts}{3}{-- times text postponed}
+\setinterfacemessage{layouts}{2}{-- times postponed text placed}
+\setinterfacemessage{layouts}{5}{blocsmarge inactifs}
+\setinterfacemessage{layouts}{4}{blocsmarge actifs}
+\setinterfacemessage{layouts}{7}{calcul de l'espace pour le logo}
+\setinterfacemessage{layouts}{6}{jeu de souspage -- traité (taille --)}
+\setinterfacemessage{layouts}{9}{pas plus de -- niveaux pour l'instant dans les élémentarisations}
+\setinterfacemessage{layouts}{8}{calcul des arrières-plans}
+\setinterfacemessage{layouts}{title}{calque}
+\setinterfacemessage{layouts}{11}{espacement -- non permis en modegrille}
+\setinterfacemessage{layouts}{10}{-- et -- ne sont pas ajoutés à 1.0}
+\setinterfacemessage{check}{1}{manquant ou dégroupé '=' après '--' à la ligne --}
+\setinterfacemessage{check}{3}{-- -- remplace une macro, utilisez des MAJUSCULES !}
+\setinterfacemessage{check}{2}{-- argument(s) attendu(s) à la ligne --}
+\setinterfacemessage{check}{title}{vérification}
+\setinterfacemessage{metapost}{1}{chargement de la bibliothèque metapost --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{le synonyme de fichier -- est déjà utilisé pour --}
+\setinterfacemessage{files}{title}{fichiers}
+\setinterfacemessage{figures}{1}{la figure -- ne peut être trouvée}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{la figure -- n'est pas pré-sélectionnée}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{les dimensions de -- chargées implicitement à partir du fichier de figure}
+\setinterfacemessage{figures}{6}{les dimensions de -- calculées par rlxtools}
+\setinterfacemessage{figures}{8}{figureobject -- est réutilisé}
+\setinterfacemessage{figures}{title}{figures}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mit.tex b/tex/context/base/mult-mit.tex
new file mode 100644
index 000000000..0efb03e90
--- /dev/null
+++ b/tex/context/base/mult-mit.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{riferimento sconosciuto --}
+\setinterfacemessage{references}{3}{riferimento di tipo sconosciuto --}
+\setinterfacemessage{references}{2}{riferimento duplicato -- a pagina --}
+\setinterfacemessage{references}{4}{riferimento illecito --}
+\setinterfacemessage{references}{title}{riferimenti}
+\setinterfacemessage{references}{30}{oggetto sconosciuto --}
+\setinterfacemessage{references}{31}{oggetto duplicato --}
+\setinterfacemessage{references}{21}{documento -- caricato}
+\setinterfacemessage{references}{22}{il documento -- non ø interattivo}
+\setinterfacemessage{references}{23}{riferimento ambiguo -- (prefisso=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{font handling --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{font handling -- is loaded}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{sistema}
+\setinterfacemessage{systems}{41}{il file esterno -- del gruppo -- non esiste}
+\setinterfacemessage{systems}{9}{-- non trovato/elaborato}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{nuova versione del file supplementare, seconda passata necessaria}
+\setinterfacemessage{systems}{21}{nessuna informazione supplementare caricata}
+\setinterfacemessage{systems}{20}{significato (specie) di -- caricato}
+\setinterfacemessage{systems}{5}{macro del modulo -- caricate}
+\setinterfacemessage{systems}{4}{comando -- già definito}
+\setinterfacemessage{systems}{27}{Versione}
+\setinterfacemessage{systems}{26}{Registri}
+\setinterfacemessage{systems}{25}{Riferimenti}
+\setinterfacemessage{systems}{24}{Oggetti mobili}
+\setinterfacemessage{systems}{1}{caricamento dei file supplementari posticipato (typemode)}
+\setinterfacemessage{systems}{23}{-- sistemato a --}
+\setinterfacemessage{systems}{22}{usare un file supplementare valido}
+\setinterfacemessage{systems}{2}{-- caricato}
+\setinterfacemessage{systems}{19}{significato (sinonimi) di -- caricato}
+\setinterfacemessage{systems}{18}{sinonimo -- -- non esistente}
+\setinterfacemessage{systems}{7}{macro del modulo -- già caricate}
+\setinterfacemessage{systems}{6}{nessuna macro trovata nel modulo --}
+\setinterfacemessage{systems}{14}{nuova pagina obbligata in lista a --}
+\setinterfacemessage{systems}{15}{salvataggio del buffer --}
+\setinterfacemessage{systems}{16}{composizione del buffer --}
+\setinterfacemessage{systems}{17}{composizione verbatim del buffer --}
+\setinterfacemessage{systems}{13}{marcatura -- definita --}
+\setinterfacemessage{systems}{12}{file di supplemento non ordinato, usare texutil}
+\setinterfacemessage{systems}{11}{costruzione di un semplice supplemento}
+\setinterfacemessage{systems}{10}{non usare em in --}
+\setinterfacemessage{floatblocks}{1}{-- rinumerato / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- mosso}
+\setinterfacemessage{floatblocks}{2}{-- salvato}
+\setinterfacemessage{floatblocks}{5}{ordine aggiustato}
+\setinterfacemessage{floatblocks}{4}{-- sistemato}
+\setinterfacemessage{floatblocks}{7}{n di bottom floats limitato a --}
+\setinterfacemessage{floatblocks}{6}{n di top floats limitato a --}
+\setinterfacemessage{floatblocks}{9}{ordine disturbato}
+\setinterfacemessage{floatblocks}{8}{meno di -- righe}
+\setinterfacemessage{floatblocks}{title}{oggetti mobili}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{non definito}
+\setinterfacemessage{floatblocks}{11}{nessun oggetto specificato}
+\setinterfacemessage{floatblocks}{10}{-- limitato}
+\setinterfacemessage{interactions}{1}{rapporto -- x -- (b x a)}
+\setinterfacemessage{interactions}{3}{inattiva}
+\setinterfacemessage{interactions}{2}{attiva}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{sincronizzazione di pagina (--) non disponibile in hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{interazione}
+\setinterfacemessage{interactions}{21}{codice -- inserito}
+\setinterfacemessage{structures}{1}{inizio del blocco (sezione) --}
+\setinterfacemessage{structures}{title}{struttura}
+\setinterfacemessage{structures}{2}{fine del blocco (sezione) --}
+\setinterfacemessage{linguals}{1}{schemi -- per -- caricati (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{sillabazione -- per -- caricata (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{niente schemi -- per -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{schemi per -- non caricati}
+\setinterfacemessage{linguals}{4}{niente sillabazione -- per -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{opzioni specifiche per la lingua [--] introducono un salto --}
+\setinterfacemessage{linguals}{6}{lingua -- non definita}
+\setinterfacemessage{linguals}{9}{lingua -- attiva}
+\setinterfacemessage{linguals}{8}{opzioni specifiche per la lingua [--] aggiunte trasparentemente}
+\setinterfacemessage{linguals}{title}{lingua}
+\setinterfacemessage{linguals}{10}{schemi -- caricati}
+\setinterfacemessage{regimes}{1}{codifica --}
+\setinterfacemessage{regimes}{3}{codifica sconosciuta --}
+\setinterfacemessage{regimes}{2}{codifica -- caricata}
+\setinterfacemessage{regimes}{title}{codifica}
+\setinterfacemessage{filters}{1}{filtro -- caricato}
+\setinterfacemessage{filters}{title}{filtri}
+\setinterfacemessage{filters}{2}{filtro sconosciuto --}
+\setinterfacemessage{verbatims}{1}{il file -- non esiste}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{codifica --}
+\setinterfacemessage{encodings}{3}{codifica sconosciuta --}
+\setinterfacemessage{encodings}{2}{codifica -- caricata}
+\setinterfacemessage{encodings}{title}{codifica}
+\setinterfacemessage{columns}{1}{solo -- colonne possibili}
+\setinterfacemessage{columns}{3}{problemi, disabilitare il bilanciamento}
+\setinterfacemessage{columns}{2}{in alternativa, usare \string\filbreak}
+\setinterfacemessage{columns}{5}{float in fondo non ancora supportato}
+\setinterfacemessage{columns}{4}{float in cima non ancora supportato}
+\setinterfacemessage{columns}{7}{bilanciamento annullato dopo 100 passi}
+\setinterfacemessage{columns}{6}{-- float(s) posticipate}
+\setinterfacemessage{columns}{9}{controllare seghettamento}
+\setinterfacemessage{columns}{8}{bilanciamento in -- passo/i}
+\setinterfacemessage{columns}{title}{colonne}
+\setinterfacemessage{columns}{13}{oggetto mobile ampio spostato sopra le colonne}
+\setinterfacemessage{columns}{12}{oggetto mobile spostata alla colonna successiva / --}
+\setinterfacemessage{columns}{11}{oggetto mobile troppo ampio per la colonna}
+\setinterfacemessage{columns}{10}{(meno di) una riga rimasta}
+\setinterfacemessage{textblocks}{1}{nuova versione, seconda passata necessaria}
+\setinterfacemessage{textblocks}{3}{lettura dei blocchi da --}
+\setinterfacemessage{textblocks}{2}{scrittura dei blocchi su --}
+\setinterfacemessage{textblocks}{5}{-- non nascosto}
+\setinterfacemessage{textblocks}{4}{seconda passata necessaria}
+\setinterfacemessage{textblocks}{7}{-- nascosto}
+\setinterfacemessage{textblocks}{6}{-- nascosto ed elaborato}
+\setinterfacemessage{textblocks}{9}{-- non composto}
+\setinterfacemessage{textblocks}{8}{-- composto}
+\setinterfacemessage{textblocks}{title}{blocchi di testo}
+\setinterfacemessage{textblocks}{12}{-- saltato}
+\setinterfacemessage{textblocks}{11}{-- caricato e composto}
+\setinterfacemessage{textblocks}{10}{-- caricato ed elaborato}
+\setinterfacemessage{symbols}{1}{caricamento gruppo di simboli --}
+\setinterfacemessage{symbols}{title}{simboli}
+\setinterfacemessage{versions}{1}{@+ mancante}
+\setinterfacemessage{versions}{3}{pagine selezionate: --}
+\setinterfacemessage{versions}{2}{marcatura pagine}
+\setinterfacemessage{versions}{title}{version}
+\setinterfacemessage{specials}{1}{-- caricato}
+\setinterfacemessage{specials}{3}{-- reimpostato}
+\setinterfacemessage{specials}{2}{non ø permesso un annidamento maggiore --}
+\setinterfacemessage{specials}{5}{caricamento del file di definizione --}
+\setinterfacemessage{specials}{4}{il comando -- non esiste}
+\setinterfacemessage{specials}{7}{driver sconosciuto --}
+\setinterfacemessage{specials}{6}{annidamento non permesso}
+\setinterfacemessage{specials}{title}{specialitø}
+\setinterfacemessage{javascript}{1}{caricamento dello script set --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{preambolo sconosciuto --}
+\setinterfacemessage{fonts}{1}{codifica --}
+\setinterfacemessage{fonts}{3}{variante sconosciuta --}
+\setinterfacemessage{fonts}{2}{variante -- caricata}
+\setinterfacemessage{fonts}{5}{stile -- non definito}
+\setinterfacemessage{fonts}{4}{corpo del testo -- non definito}
+\setinterfacemessage{fonts}{7}{formato sconosciuto --}
+\setinterfacemessage{fonts}{6}{-- caricato}
+\setinterfacemessage{fonts}{14}{corpo del testo -- definito (sarebbe meglio globale)}
+\setinterfacemessage{fonts}{8}{stile -- definito}
+\setinterfacemessage{fonts}{title}{font del corpo}
+\setinterfacemessage{fonts}{10}{file di font sconosciuto --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{file globale --}
+\setinterfacemessage{databases}{2}{file locale --}
+\setinterfacemessage{databases}{4}{file sconosciuto --}
+\setinterfacemessage{databases}{title}{database}
+\setinterfacemessage{colors}{1}{sistema -- attivato globalmente}
+\setinterfacemessage{colors}{3}{-- non definito --}
+\setinterfacemessage{colors}{2}{sistema -- attivato localmente}
+\setinterfacemessage{colors}{5}{sistema -- sconosciuto}
+\setinterfacemessage{colors}{4}{sistema -- caricato}
+\setinterfacemessage{colors}{7}{tavolozza -- non disponibile}
+\setinterfacemessage{colors}{6}{tavolozza -- resa disponibile}
+\setinterfacemessage{colors}{9}{spazio dei colori -- non supportato}
+\setinterfacemessage{colors}{8}{specifica -- del colore -- convertita in nero}
+\setinterfacemessage{colors}{title}{colore}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{il colore ø convertito in grigio}
+\setinterfacemessage{colors}{10}{spazio dei colori -- supportato}
+\setinterfacemessage{layouts}{1}{altezza del testo adattata con -- a pagina --}
+\setinterfacemessage{layouts}{3}{testo posticipato -- volte}
+\setinterfacemessage{layouts}{2}{posizionato testo posticipato -- volte}
+\setinterfacemessage{layouts}{5}{blocchi in margine inattivi}
+\setinterfacemessage{layouts}{4}{blocchi in margine attivi}
+\setinterfacemessage{layouts}{7}{calcolo dello spazio per logo}
+\setinterfacemessage{layouts}{6}{gruppo di sottopagine -- elaborato (dimensione --)}
+\setinterfacemessage{layouts}{9}{attualmente non più di -- livelli di elencazione}
+\setinterfacemessage{layouts}{8}{calcolo dello sfondo}
+\setinterfacemessage{layouts}{title}{layout}
+\setinterfacemessage{layouts}{11}{spaziatura -- non permessa in modo griglia}
+\setinterfacemessage{layouts}{10}{-- e -- non sommano a 1.0}
+\setinterfacemessage{check}{1}{'=' mancante o non raggruppato dopo '--' alla riga --}
+\setinterfacemessage{check}{3}{-- -- sostituisce una macro, usare le MAIUSCOLE!}
+\setinterfacemessage{check}{2}{-- argomento/i attesi alla riga --}
+\setinterfacemessage{check}{title}{controllo}
+\setinterfacemessage{metapost}{1}{caricamento della libreria metapost --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{sinonimo file -- già in uso per --}
+\setinterfacemessage{files}{title}{file}
+\setinterfacemessage{figures}{1}{figura -- non trovata}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{la figura -- non è preimpostata}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{dimensioni di -- caricate dal file di immagini stesso}
+\setinterfacemessage{figures}{6}{dimensioni di -- calcolate da rlxtools}
+\setinterfacemessage{figures}{8}{oggetto-figura -- riutilizzato}
+\setinterfacemessage{figures}{title}{figure}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mnl.tex b/tex/context/base/mult-mnl.tex
new file mode 100644
index 000000000..5c52f7aff
--- /dev/null
+++ b/tex/context/base/mult-mnl.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{onbekende verwijzing --}
+\setinterfacemessage{references}{3}{type verwijzing -- onbekend}
+\setinterfacemessage{references}{2}{dubbele verwijzing -- op pagina --}
+\setinterfacemessage{references}{4}{verboden verwijzing --}
+\setinterfacemessage{references}{title}{verwijzingen}
+\setinterfacemessage{references}{30}{onbekend object --}
+\setinterfacemessage{references}{31}{dubbel object --}
+\setinterfacemessage{references}{21}{document -- geladen}
+\setinterfacemessage{references}{22}{document -- is niet interactief}
+\setinterfacemessage{references}{23}{onduidelijke verwijzing -- (prefix=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{nummer --}
+\setinterfacemessage{handlings}{1}{font afhandeling --}
+\setinterfacemessage{handlings}{3}{onbekende font afhandeling --}
+\setinterfacemessage{handlings}{2}{font afhandeling -- wordt geladen}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{systeem}
+\setinterfacemessage{systems}{41}{externe file -- in groep -- bestaat niet}
+\setinterfacemessage{systems}{9}{-- niet gevonden/geplaatst}
+\setinterfacemessage{systems}{91}{papierlade --}
+\setinterfacemessage{systems}{8}{nieuwe versie hulpfile, tweede run nodig}
+\setinterfacemessage{systems}{21}{de hulpfile is niet geladen}
+\setinterfacemessage{systems}{20}{betekenissen (sorteren) van -- geladen}
+\setinterfacemessage{systems}{5}{module -- geladen}
+\setinterfacemessage{systems}{4}{commando -- is al gedefinieerd}
+\setinterfacemessage{systems}{27}{Versie}
+\setinterfacemessage{systems}{26}{Registers}
+\setinterfacemessage{systems}{25}{Verwijzingen}
+\setinterfacemessage{systems}{24}{Plaatsblokken}
+\setinterfacemessage{systems}{1}{laden hulpfile uitgesteld (typemode)}
+\setinterfacemessage{systems}{23}{-- gearrangeerd op --}
+\setinterfacemessage{systems}{22}{gebruik een goede hulpfile}
+\setinterfacemessage{systems}{2}{-- geladen}
+\setinterfacemessage{systems}{19}{betekenissen (synoniemen) van -- geladen}
+\setinterfacemessage{systems}{18}{synoniem -- -- bestaat niet}
+\setinterfacemessage{systems}{7}{module -- reeds geladen}
+\setinterfacemessage{systems}{6}{geen module -- gevonden}
+\setinterfacemessage{systems}{14}{geforceerde paginaovergang in lijst voor --}
+\setinterfacemessage{systems}{15}{wegschrijven buffer --}
+\setinterfacemessage{systems}{16}{inlezen buffer --}
+\setinterfacemessage{systems}{17}{verbatim inlezen buffer --}
+\setinterfacemessage{systems}{13}{markering -- gedefinieerd --}
+\setinterfacemessage{systems}{12}{de hulpfile is niet gesorteerd, gebruik texutil}
+\setinterfacemessage{systems}{11}{aanmaken basale hulpfile}
+\setinterfacemessage{systems}{10}{gebruik geen em in --}
+\setinterfacemessage{floatblocks}{1}{-- hernummerd / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- verplaatst}
+\setinterfacemessage{floatblocks}{2}{-- bewaard}
+\setinterfacemessage{floatblocks}{5}{volgorde aangepast}
+\setinterfacemessage{floatblocks}{4}{-- geplaatst}
+\setinterfacemessage{floatblocks}{7}{maximaal -- onder}
+\setinterfacemessage{floatblocks}{6}{maximaal -- boven}
+\setinterfacemessage{floatblocks}{9}{volgorde verstoord}
+\setinterfacemessage{floatblocks}{8}{minder dan -- regels}
+\setinterfacemessage{floatblocks}{title}{plaatsblokken}
+\setinterfacemessage{floatblocks}{13}{er is niets te splitsen}
+\setinterfacemessage{floatblocks}{12}{niet gedefinieerd}
+\setinterfacemessage{floatblocks}{11}{geen blok opgegeven}
+\setinterfacemessage{floatblocks}{10}{-- begrensd}
+\setinterfacemessage{interactions}{1}{aspect ratio -- x -- (b x h)}
+\setinterfacemessage{interactions}{3}{niet actief}
+\setinterfacemessage{interactions}{2}{actief}
+\setinterfacemessage{interactions}{5}{onbekend attachment --}
+\setinterfacemessage{interactions}{4}{geen paginasynchronisatie (--) in hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- bestaat niet}
+\setinterfacemessage{interactions}{title}{interactie}
+\setinterfacemessage{interactions}{21}{-- code tussengevoegd}
+\setinterfacemessage{structures}{1}{begin van sectieblok --}
+\setinterfacemessage{structures}{title}{structuur}
+\setinterfacemessage{structures}{2}{eind van sectieblok --}
+\setinterfacemessage{linguals}{1}{afbreekpatronen -- voor -- geladen (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{afbreekdefinities -- voor -- geladen (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{geen afbreekpatronen -- voor -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{afbreekpatronen voor -- niet geladen}
+\setinterfacemessage{linguals}{4}{geen afbreekdefinities -- voor -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{taal specifieke opties [--] introduceren een skip van --}
+\setinterfacemessage{linguals}{6}{taal -- is niet gedefinieerd}
+\setinterfacemessage{linguals}{9}{taal -- is actief}
+\setinterfacemessage{linguals}{8}{taal specifieke opties [--] naadloos toegevoegd}
+\setinterfacemessage{linguals}{title}{taal}
+\setinterfacemessage{linguals}{10}{patronen --geladen}
+\setinterfacemessage{regimes}{1}{regime --}
+\setinterfacemessage{regimes}{3}{onbekend regime --}
+\setinterfacemessage{regimes}{2}{regime -- wordt geladen}
+\setinterfacemessage{regimes}{title}{regime}
+\setinterfacemessage{filters}{1}{filter -- wordt geladen}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{onbekend filter --}
+\setinterfacemessage{verbatims}{1}{file -- bestaat niet}
+\setinterfacemessage{verbatims}{title}{typen}
+\setinterfacemessage{encodings}{1}{codering --}
+\setinterfacemessage{encodings}{3}{onbekende codering --}
+\setinterfacemessage{encodings}{2}{codering -- wordt geladen}
+\setinterfacemessage{encodings}{title}{encoding}
+\setinterfacemessage{columns}{1}{maximaal -- kolommen}
+\setinterfacemessage{columns}{3}{probleempje, probeer [balanceren=nee]}
+\setinterfacemessage{columns}{2}{gebruik eventueel \string\filbreak}
+\setinterfacemessage{columns}{5}{plaatsblok onder nog niet mogelijk}
+\setinterfacemessage{columns}{4}{plaatsblok boven nog niet mogelijk}
+\setinterfacemessage{columns}{7}{balanceren afgebroken na 100 stappen}
+\setinterfacemessage{columns}{6}{-- plaatsblok(en) opgeschort}
+\setinterfacemessage{columns}{9}{uitlijnen controleren!}
+\setinterfacemessage{columns}{8}{gebalanceerd in -- stap(pen)}
+\setinterfacemessage{columns}{title}{kolommen}
+\setinterfacemessage{columns}{13}{breed figuur geplaatst boven kolommen}
+\setinterfacemessage{columns}{12}{plaatsblok verplaatst naar volgende kolom / --}
+\setinterfacemessage{columns}{11}{plaatsblok te breed voor kolom}
+\setinterfacemessage{columns}{10}{(minder dan) 1 regel over}
+\setinterfacemessage{textblocks}{1}{nieuwe versie, tweede run nodig}
+\setinterfacemessage{textblocks}{3}{inlezen blokken uit --}
+\setinterfacemessage{textblocks}{2}{wegschrijven blokken naar --}
+\setinterfacemessage{textblocks}{5}{-- niet verborgen}
+\setinterfacemessage{textblocks}{4}{er is een tweede run nodig}
+\setinterfacemessage{textblocks}{7}{-- verborgen}
+\setinterfacemessage{textblocks}{6}{-- verborgen en verwerkt}
+\setinterfacemessage{textblocks}{9}{-- niet gehandhaafd}
+\setinterfacemessage{textblocks}{8}{-- gehandhaafd}
+\setinterfacemessage{textblocks}{title}{tekstblokken}
+\setinterfacemessage{textblocks}{12}{-- overgeslagen}
+\setinterfacemessage{textblocks}{11}{-- geladen en geplaatst}
+\setinterfacemessage{textblocks}{10}{-- geladen en verwerkt}
+\setinterfacemessage{symbols}{1}{symboolset -- wordt geladen}
+\setinterfacemessage{symbols}{title}{symbolen}
+\setinterfacemessage{versions}{1}{er mankeert een @+}
+\setinterfacemessage{versions}{3}{geselecteerde pagina's: --}
+\setinterfacemessage{versions}{2}{markeren pagina's}
+\setinterfacemessage{versions}{title}{versie}
+\setinterfacemessage{specials}{1}{-- geladen}
+\setinterfacemessage{specials}{3}{-- gereset}
+\setinterfacemessage{specials}{2}{verdere nesting is niet toegestaan --}
+\setinterfacemessage{specials}{5}{definitiefile -- wordt geladen}
+\setinterfacemessage{specials}{4}{commando -- bestaat niet}
+\setinterfacemessage{specials}{7}{onbekende driver --}
+\setinterfacemessage{specials}{6}{nesting is niet toegestaan}
+\setinterfacemessage{specials}{title}{specials}
+\setinterfacemessage{javascript}{1}{script set -- wordt geladen}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{onbekende preamble --}
+\setinterfacemessage{fonts}{1}{codering --}
+\setinterfacemessage{fonts}{3}{onbekende variant --}
+\setinterfacemessage{fonts}{2}{variant -- wordt geladen}
+\setinterfacemessage{fonts}{5}{stijl -- is niet gedefinieerd}
+\setinterfacemessage{fonts}{4}{korps -- is niet gedefinieerd}
+\setinterfacemessage{fonts}{7}{onbekend formaat --}
+\setinterfacemessage{fonts}{6}{-- wordt geladen}
+\setinterfacemessage{fonts}{14}{korps -- is gedefinieerd (kan beter globaal plaatsvinden)}
+\setinterfacemessage{fonts}{8}{stijl -- gedefinieerd}
+\setinterfacemessage{fonts}{title}{korps}
+\setinterfacemessage{fonts}{10}{onbekende font file --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{globaal bestand --}
+\setinterfacemessage{databases}{2}{lokaal bestand --}
+\setinterfacemessage{databases}{4}{onbekend bestand --}
+\setinterfacemessage{databases}{title}{database}
+\setinterfacemessage{colors}{1}{systeem -- is globaal actief}
+\setinterfacemessage{colors}{3}{-- is niet gedefinieerd --}
+\setinterfacemessage{colors}{2}{systeem -- is lokaal actief}
+\setinterfacemessage{colors}{5}{onbekend systeem --}
+\setinterfacemessage{colors}{4}{systeem -- wordt geladen}
+\setinterfacemessage{colors}{7}{palet -- is niet beschikbaar}
+\setinterfacemessage{colors}{6}{palet -- is beschikbaar}
+\setinterfacemessage{colors}{9}{-- kleurruimte wordt niet ondersteund}
+\setinterfacemessage{colors}{8}{specificatie -- bij -- wordt zwart}
+\setinterfacemessage{colors}{title}{kleur}
+\setinterfacemessage{colors}{12}{-- is geregistreerd}
+\setinterfacemessage{colors}{11}{kleur wordt vertaald in grijs}
+\setinterfacemessage{colors}{10}{-- kleurruimte wordt ondersteund}
+\setinterfacemessage{layouts}{1}{teksthoogte aangepast met -- op pagina --}
+\setinterfacemessage{layouts}{3}{-- maal tekst plaatsen uitstellen}
+\setinterfacemessage{layouts}{2}{-- maal uitgestelde tekst tussengevoegd}
+\setinterfacemessage{layouts}{5}{margeblokken inactief}
+\setinterfacemessage{layouts}{4}{margeblokken actief}
+\setinterfacemessage{layouts}{7}{beeldmerken berekenen}
+\setinterfacemessage{layouts}{6}{subpagina reeks -- verwerkt (aantal --)}
+\setinterfacemessage{layouts}{9}{momenteel maximaal -- niveaus in opsommingen}
+\setinterfacemessage{layouts}{8}{achtergronden berekenen}
+\setinterfacemessage{layouts}{title}{layout}
+\setinterfacemessage{layouts}{11}{interlinie -- niet toegestaan in gridmode}
+\setinterfacemessage{layouts}{10}{-- en -- tellen niet op tot 1.0}
+\setinterfacemessage{check}{1}{'=' ontbreekt of zonder {} na '--' in regel --}
+\setinterfacemessage{check}{3}{-- -- vervangt een macro, gebruik HOOFDLETTERS!}
+\setinterfacemessage{check}{2}{-- argument(en) verwacht in regel --}
+\setinterfacemessage{check}{title}{controle}
+\setinterfacemessage{metapost}{1}{metapost bibliotheek -- wordt geladen}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{file synoniem -- is al in gebruik voor --}
+\setinterfacemessage{files}{title}{files}
+\setinterfacemessage{figures}{1}{figuur -- is niet te vinden}
+\setinterfacemessage{figures}{3}{maten van -- worden extern vastgesteld}
+\setinterfacemessage{figures}{2}{figuur -- wordt niet preset}
+\setinterfacemessage{figures}{5}{maten van -- zijn onbekend}
+\setinterfacemessage{figures}{4}{maten van -- geladen uit figuurfile zelf}
+\setinterfacemessage{figures}{6}{maten van -- berekend door rlxtools}
+\setinterfacemessage{figures}{8}{figuurobject -- wordt opnieuw gebruikt}
+\setinterfacemessage{figures}{title}{figuren}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mno.tex b/tex/context/base/mult-mno.tex
new file mode 100644
index 000000000..676c2cb2c
--- /dev/null
+++ b/tex/context/base/mult-mno.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{ukjent referanse --}
+\setinterfacemessage{references}{3}{ukjent referansetype --}
+\setinterfacemessage{references}{2}{duplikat referanse -- pø side --}
+\setinterfacemessage{references}{4}{ulovlig referanse --}
+\setinterfacemessage{references}{title}{referanser}
+\setinterfacemessage{references}{30}{ukjent objekt --}
+\setinterfacemessage{references}{31}{duplikat objekt --}
+\setinterfacemessage{references}{21}{dokument -- er lest inn}
+\setinterfacemessage{references}{22}{dokument -- er ikke interaktivt}
+\setinterfacemessage{references}{23}{obskur referanse -- (Prefix=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{font handling --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{font handling -- is loaded}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{system}
+\setinterfacemessage{systems}{41}{ekstern fil -- i gruppe -- eksisterer ikke}
+\setinterfacemessage{systems}{9}{-- ikke funnet/behandlet}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{ny versjon av hjelpefil, andre gjennomkjøring nødvendig}
+\setinterfacemessage{systems}{21}{hjelpefila er ikke lest inn}
+\setinterfacemessage{systems}{20}{betydning (sorterer) av -- er lest inn}
+\setinterfacemessage{systems}{5}{makroene i modul -- er lest inn}
+\setinterfacemessage{systems}{4}{kommando -- er allerede definert}
+\setinterfacemessage{systems}{27}{Versjon}
+\setinterfacemessage{systems}{26}{Registere}
+\setinterfacemessage{systems}{25}{Referanser}
+\setinterfacemessage{systems}{24}{Flytblokker}
+\setinterfacemessage{systems}{1}{innlesning av hjelpefila utsatt (typemode)}
+\setinterfacemessage{systems}{23}{-- arrangert på --}
+\setinterfacemessage{systems}{22}{bruk en gyldig hjelpefil}
+\setinterfacemessage{systems}{2}{-- er lest inn}
+\setinterfacemessage{systems}{19}{betydning (synonymer) av -- er lest inn}
+\setinterfacemessage{systems}{18}{synonym -- -- eksisterer ikke}
+\setinterfacemessage{systems}{7}{makroene i modul -- er allerede lest inn}
+\setinterfacemessage{systems}{6}{ingen makroer funnet i modul ---}
+\setinterfacemessage{systems}{14}{tvunget sideskift i liste ved --}
+\setinterfacemessage{systems}{15}{lagrer Buffer --}
+\setinterfacemessage{systems}{16}{tegnsetter buffer --}
+\setinterfacemessage{systems}{17}{tegnsetter verbatim-buffer --}
+\setinterfacemessage{systems}{13}{markering -- definert --}
+\setinterfacemessage{systems}{12}{hjelpefila er ikke sortert, bruk texutil}
+\setinterfacemessage{systems}{11}{lager enkel hjelpefil}
+\setinterfacemessage{systems}{10}{ikke bruk em i --}
+\setinterfacemessage{floatblocks}{1}{-- renummerert / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- flyttet}
+\setinterfacemessage{floatblocks}{2}{-- lagret}
+\setinterfacemessage{floatblocks}{5}{rekkefølge tilpasset}
+\setinterfacemessage{floatblocks}{4}{-- plassert}
+\setinterfacemessage{floatblocks}{7}{maksimalt -- flytblokker nederst}
+\setinterfacemessage{floatblocks}{6}{maksimalt -- flytblokker øverst}
+\setinterfacemessage{floatblocks}{9}{rekkefølge endret}
+\setinterfacemessage{floatblocks}{8}{mindre enn -- linjer}
+\setinterfacemessage{floatblocks}{title}{flytblokker}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{udefinert}
+\setinterfacemessage{floatblocks}{11}{ingen blokk oppgitt}
+\setinterfacemessage{floatblocks}{10}{-- begrenset}
+\setinterfacemessage{interactions}{1}{forholdstall -- x -- (b x h)}
+\setinterfacemessage{interactions}{3}{inaktiv}
+\setinterfacemessage{interactions}{2}{aktiv}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{ingen sidesynkronisering (--) i hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{interaksjon}
+\setinterfacemessage{interactions}{21}{-- kode satt inn / tilføyd}
+\setinterfacemessage{structures}{1}{starten av blokk -- (seksjon)}
+\setinterfacemessage{structures}{title}{struktur}
+\setinterfacemessage{structures}{2}{slutten av blokk -- (seksjon)}
+\setinterfacemessage{linguals}{1}{orddelingsmønster -- for -- er lest inn (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{orddelingsdefinisjon -- for -- er lest inn (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{ingen orddelingsmønster -- for -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{orddelingsmønster for -- er ikke lest inn}
+\setinterfacemessage{linguals}{4}{ingen orddelingsdefinisjon -- for -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{spràk spesifikk opsjon [--] introduserer et -- hopp}
+\setinterfacemessage{linguals}{6}{spràk -- er udefinert}
+\setinterfacemessage{linguals}{9}{spràk -- er aktivt}
+\setinterfacemessage{linguals}{8}{spràk spesifikk opsjon [--] problemfritt tilføyd}
+\setinterfacemessage{linguals}{title}{sprøk}
+\setinterfacemessage{linguals}{10}{orddelingsmønster -- er lest inn}
+\setinterfacemessage{regimes}{1}{koding --}
+\setinterfacemessage{regimes}{3}{ukjent koding --}
+\setinterfacemessage{regimes}{2}{koding -- er lest inn}
+\setinterfacemessage{regimes}{title}{koding}
+\setinterfacemessage{filters}{1}{filter -- is loaded}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{unknown filter --}
+\setinterfacemessage{verbatims}{1}{fil -- eksisterer ikke}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{koding --}
+\setinterfacemessage{encodings}{3}{ukjent koding --}
+\setinterfacemessage{encodings}{2}{koding -- er lest inn}
+\setinterfacemessage{encodings}{title}{koding}
+\setinterfacemessage{columns}{1}{maksimalt -- kolonner}
+\setinterfacemessage{columns}{3}{problemer, slår av balansering}
+\setinterfacemessage{columns}{2}{bruk \string\filbreak\space som et alternativ}
+\setinterfacemessage{columns}{5}{flytblokker nedert er ikke støttet enda}
+\setinterfacemessage{columns}{4}{flytblokker øverst er ikke støttet enda}
+\setinterfacemessage{columns}{7}{balansering avbrutt etter 100 iterasjoner}
+\setinterfacemessage{columns}{6}{-- flytblokk forskjøvet}
+\setinterfacemessage{columns}{9}{kontroller tekstlayout!}
+\setinterfacemessage{columns}{8}{balansert etter -- iterasjoner}
+\setinterfacemessage{columns}{title}{kolonner}
+\setinterfacemessage{columns}{13}{bred flytblokk forksjøvet til toppen av kolonnene}
+\setinterfacemessage{columns}{12}{flytblokk forskjøvet til neste kolonne / --}
+\setinterfacemessage{columns}{11}{flytblokk for bredt for kolonna}
+\setinterfacemessage{columns}{10}{(mindre enn) 1 linje igjen}
+\setinterfacemessage{textblocks}{1}{ny versjon, andre gjennomkjøring nødvendig}
+\setinterfacemessage{textblocks}{3}{leser blokker fra --}
+\setinterfacemessage{textblocks}{2}{skriver blokker til --}
+\setinterfacemessage{textblocks}{5}{-- ikke skjult}
+\setinterfacemessage{textblocks}{4}{andre gjennomkjøring nødvendig}
+\setinterfacemessage{textblocks}{7}{-- skjult}
+\setinterfacemessage{textblocks}{6}{-- skjult og behandlet}
+\setinterfacemessage{textblocks}{9}{-- ikke tegnsatt}
+\setinterfacemessage{textblocks}{8}{-- tegnsatt}
+\setinterfacemessage{textblocks}{title}{tekstblokker}
+\setinterfacemessage{textblocks}{12}{-- utelatt}
+\setinterfacemessage{textblocks}{11}{-- lest inn og tegnsatt}
+\setinterfacemessage{textblocks}{10}{-- lest inn og behandlet}
+\setinterfacemessage{symbols}{1}{leser inn symbolsett --}
+\setinterfacemessage{symbols}{title}{symboler}
+\setinterfacemessage{versions}{1}{manglende @+}
+\setinterfacemessage{versions}{3}{valgte sider: --}
+\setinterfacemessage{versions}{2}{markerer sider}
+\setinterfacemessage{versions}{title}{versjon}
+\setinterfacemessage{specials}{1}{-- er lest inn}
+\setinterfacemessage{specials}{3}{-- er tilbakestilt}
+\setinterfacemessage{specials}{2}{dypere 'nesting' er ikke tillatt --}
+\setinterfacemessage{specials}{5}{leser inn definisjonsfil for --}
+\setinterfacemessage{specials}{4}{kommando -- eksisterer ikke}
+\setinterfacemessage{specials}{7}{ukjent driver --}
+\setinterfacemessage{specials}{6}{'nesting' er ikke tillatt}
+\setinterfacemessage{specials}{title}{specials}
+\setinterfacemessage{javascript}{1}{leser inn scriptsett --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{ukjent 'preamble' --}
+\setinterfacemessage{fonts}{1}{koding --}
+\setinterfacemessage{fonts}{3}{ukjent variant --}
+\setinterfacemessage{fonts}{2}{variant -- er lest inn}
+\setinterfacemessage{fonts}{5}{stil -- er ikke definert}
+\setinterfacemessage{fonts}{4}{hovedfont -- er ikke definert}
+\setinterfacemessage{fonts}{7}{ukjent format --}
+\setinterfacemessage{fonts}{6}{-- er lest inn}
+\setinterfacemessage{fonts}{14}{bodyfont -- is defined (can better be done global)}
+\setinterfacemessage{fonts}{8}{stil -- definert}
+\setinterfacemessage{fonts}{title}{hovedfont}
+\setinterfacemessage{fonts}{10}{ukjent fontfil --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{global fil --}
+\setinterfacemessage{databases}{2}{lokal fil --}
+\setinterfacemessage{databases}{4}{ukjent fil --}
+\setinterfacemessage{databases}{title}{databaser}
+\setinterfacemessage{colors}{1}{system -- er aktivert globalt}
+\setinterfacemessage{colors}{3}{-- er udefinert --}
+\setinterfacemessage{colors}{2}{system -- er aktivert lokalt}
+\setinterfacemessage{colors}{5}{ukjent system --}
+\setinterfacemessage{colors}{4}{system -- er lest inn}
+\setinterfacemessage{colors}{7}{palett -- er ikke tilgjengelig}
+\setinterfacemessage{colors}{6}{palett -- er tilgjengelig}
+\setinterfacemessage{colors}{9}{-- fargerom er ikke støttet}
+\setinterfacemessage{colors}{8}{spesifikasjon -- for farge -- gir kun svart}
+\setinterfacemessage{colors}{title}{farge}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{fargen vil bli vist som grø}
+\setinterfacemessage{colors}{10}{-- fargerom er støttet}
+\setinterfacemessage{layouts}{1}{teksthøyde tilpasset med -- på side --}
+\setinterfacemessage{layouts}{3}{-- ganger tekst forskjøvet}
+\setinterfacemessage{layouts}{2}{-- ganger forskjøvet tekst plassert}
+\setinterfacemessage{layouts}{5}{margblokker inaktive}
+\setinterfacemessage{layouts}{4}{margblokker aktive}
+\setinterfacemessage{layouts}{7}{beregner plass for logo}
+\setinterfacemessage{layouts}{6}{delside sett -- behandlet (størrelse --)}
+\setinterfacemessage{layouts}{9}{for øyeblikket maksimalt -- nivåer i opplisting}
+\setinterfacemessage{layouts}{8}{beregner bakgrunn}
+\setinterfacemessage{layouts}{title}{layout}
+\setinterfacemessage{layouts}{11}{mellomrom -- ikke tillatt i gridmodus}
+\setinterfacemessage{layouts}{10}{-- og -- er ikke 1.0 til sammen}
+\setinterfacemessage{check}{1}{manglende '=' etter '--' i linje --}
+\setinterfacemessage{check}{3}{-- -- overskygger en makro, bruk STORE BOKSTAVER!}
+\setinterfacemessage{check}{2}{-- argument forventet i linje --}
+\setinterfacemessage{check}{title}{kontroll}
+\setinterfacemessage{metapost}{1}{metapost bibliotek -- blir lest inn}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{filesynonym -- er allerede brukt for --}
+\setinterfacemessage{files}{title}{filer}
+\setinterfacemessage{figures}{1}{figure -- can not be found}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{figure -- is not preset}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{dimensions of -- loaded from figurefile itself}
+\setinterfacemessage{figures}{6}{dimensions of -- calculated by rlxtools}
+\setinterfacemessage{figures}{8}{figureobject -- is reused}
+\setinterfacemessage{figures}{title}{figures}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mpe.tex b/tex/context/base/mult-mpe.tex
new file mode 100644
index 000000000..8335d2911
--- /dev/null
+++ b/tex/context/base/mult-mpe.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{unknown reference --}
+\setinterfacemessage{references}{3}{unknown reference type --}
+\setinterfacemessage{references}{2}{duplicate reference -- on page --}
+\setinterfacemessage{references}{4}{illegal reference --}
+\setinterfacemessage{references}{title}{references}
+\setinterfacemessage{references}{30}{unknown object --}
+\setinterfacemessage{references}{31}{duplicate object --}
+\setinterfacemessage{references}{21}{document -- loaded}
+\setinterfacemessage{references}{22}{document -- is not interactive}
+\setinterfacemessage{references}{23}{obscure reference -- (prefix=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{font handling --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{font handling -- is loaded}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{system}
+\setinterfacemessage{systems}{41}{external file -- in group -- does not exist}
+\setinterfacemessage{systems}{9}{-- not found/processed}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{new version of utility file, second pass needed}
+\setinterfacemessage{systems}{21}{no utility data is loaded}
+\setinterfacemessage{systems}{20}{meaning (sorts) of -- loaded}
+\setinterfacemessage{systems}{5}{module -- loaded}
+\setinterfacemessage{systems}{4}{command -- is already defined}
+\setinterfacemessage{systems}{27}{Version}
+\setinterfacemessage{systems}{26}{Registers}
+\setinterfacemessage{systems}{25}{References}
+\setinterfacemessage{systems}{24}{Floatblocks}
+\setinterfacemessage{systems}{1}{loading utility-file postponed (typemode)}
+\setinterfacemessage{systems}{23}{-- arranged at --}
+\setinterfacemessage{systems}{22}{use a valid utilityfile}
+\setinterfacemessage{systems}{2}{-- loaded}
+\setinterfacemessage{systems}{19}{meaning (synonyms) of -- loaded}
+\setinterfacemessage{systems}{18}{synonym -- -- does not exist}
+\setinterfacemessage{systems}{7}{module -- already loaded}
+\setinterfacemessage{systems}{6}{module -- not found}
+\setinterfacemessage{systems}{14}{forced newpage in list at --}
+\setinterfacemessage{systems}{15}{saving buffer --}
+\setinterfacemessage{systems}{16}{typesetting buffer --}
+\setinterfacemessage{systems}{17}{typesetting verbatim buffer --}
+\setinterfacemessage{systems}{13}{mark -- defined --}
+\setinterfacemessage{systems}{12}{the utility-file is not sorted, use texutil}
+\setinterfacemessage{systems}{11}{building simple util}
+\setinterfacemessage{systems}{10}{don't use em in --}
+\setinterfacemessage{floatblocks}{1}{-- renumbered / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- moved}
+\setinterfacemessage{floatblocks}{2}{-- saved}
+\setinterfacemessage{floatblocks}{5}{order adapted}
+\setinterfacemessage{floatblocks}{4}{-- placed}
+\setinterfacemessage{floatblocks}{7}{n of bottom floats limited to --}
+\setinterfacemessage{floatblocks}{6}{n of top floats limited to --}
+\setinterfacemessage{floatblocks}{9}{order disturbed}
+\setinterfacemessage{floatblocks}{8}{less than -- lines}
+\setinterfacemessage{floatblocks}{title}{floatblocks}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{undefined}
+\setinterfacemessage{floatblocks}{11}{no block given}
+\setinterfacemessage{floatblocks}{10}{-- limited}
+\setinterfacemessage{interactions}{1}{aspect ratio -- x -- (b x h)}
+\setinterfacemessage{interactions}{3}{inactive}
+\setinterfacemessage{interactions}{2}{active}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{no pagesynchronisation (--) in hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{interaction}
+\setinterfacemessage{interactions}{21}{-- code inserted}
+\setinterfacemessage{structures}{1}{begin of sectionblock --}
+\setinterfacemessage{structures}{title}{structure}
+\setinterfacemessage{structures}{2}{end of sectionblock --}
+\setinterfacemessage{linguals}{1}{patterns -- for -- loaded (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{hyphenations -- for -- loaded (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{no patterns -- for -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{patterns for -- not loaded}
+\setinterfacemessage{linguals}{4}{no hyphenations -- for -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{language specific options [--] introduce a -- skip}
+\setinterfacemessage{linguals}{6}{language -- is undefined}
+\setinterfacemessage{linguals}{9}{language -- is active}
+\setinterfacemessage{linguals}{8}{language specific options [--] seamless appended}
+\setinterfacemessage{linguals}{title}{language}
+\setinterfacemessage{linguals}{10}{patterns --loaded}
+\setinterfacemessage{regimes}{1}{regime --}
+\setinterfacemessage{regimes}{3}{unknown regime --}
+\setinterfacemessage{regimes}{2}{regime -- is loaded}
+\setinterfacemessage{regimes}{title}{regime}
+\setinterfacemessage{filters}{1}{filter -- is loaded}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{unknown filter --}
+\setinterfacemessage{verbatims}{1}{file -- does not exist}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{coding --}
+\setinterfacemessage{encodings}{3}{unknown coding --}
+\setinterfacemessage{encodings}{2}{coding -- is loaded}
+\setinterfacemessage{encodings}{title}{encoding}
+\setinterfacemessage{columns}{1}{only -- columns possible}
+\setinterfacemessage{columns}{3}{problems, disable balancing}
+\setinterfacemessage{columns}{2}{use \string\filbreak\space as alternative}
+\setinterfacemessage{columns}{5}{bottom float not yet supported}
+\setinterfacemessage{columns}{4}{top float not yet supported}
+\setinterfacemessage{columns}{7}{balancing aborted after 100 steps}
+\setinterfacemessage{columns}{6}{-- float(s) postponed}
+\setinterfacemessage{columns}{9}{check raggedness}
+\setinterfacemessage{columns}{8}{balanced in -- step(s)}
+\setinterfacemessage{columns}{title}{columns}
+\setinterfacemessage{columns}{13}{wide float moved to top of columns}
+\setinterfacemessage{columns}{12}{float moved to next column / --}
+\setinterfacemessage{columns}{11}{float too wide for column}
+\setinterfacemessage{columns}{10}{(less than) 1 line left}
+\setinterfacemessage{textblocks}{1}{new version, second pass needed}
+\setinterfacemessage{textblocks}{3}{reading blocks from --}
+\setinterfacemessage{textblocks}{2}{writing blocks to --}
+\setinterfacemessage{textblocks}{5}{-- not hidden}
+\setinterfacemessage{textblocks}{4}{second pass needed}
+\setinterfacemessage{textblocks}{7}{-- hidden}
+\setinterfacemessage{textblocks}{6}{-- hidden and processed}
+\setinterfacemessage{textblocks}{9}{-- not typeset}
+\setinterfacemessage{textblocks}{8}{-- typeset}
+\setinterfacemessage{textblocks}{title}{textblocks}
+\setinterfacemessage{textblocks}{12}{-- skipped}
+\setinterfacemessage{textblocks}{11}{-- loaded and typeset}
+\setinterfacemessage{textblocks}{10}{-- loaded and processed}
+\setinterfacemessage{symbols}{1}{loading symbolset --}
+\setinterfacemessage{symbols}{title}{symbols}
+\setinterfacemessage{versions}{1}{missing @+}
+\setinterfacemessage{versions}{3}{selected pages: --}
+\setinterfacemessage{versions}{2}{marking pages}
+\setinterfacemessage{versions}{title}{version}
+\setinterfacemessage{specials}{1}{-- loaded}
+\setinterfacemessage{specials}{3}{-- is reset}
+\setinterfacemessage{specials}{2}{no deeper nesting is permitted --}
+\setinterfacemessage{specials}{5}{loading definition file --}
+\setinterfacemessage{specials}{4}{command -- does not exist}
+\setinterfacemessage{specials}{7}{unknown driver --}
+\setinterfacemessage{specials}{6}{nesting is not permitted}
+\setinterfacemessage{specials}{title}{specials}
+\setinterfacemessage{javascript}{1}{loading script set --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{unknown preamble --}
+\setinterfacemessage{fonts}{1}{coding --}
+\setinterfacemessage{fonts}{3}{unknown variant --}
+\setinterfacemessage{fonts}{2}{variant -- is loaded}
+\setinterfacemessage{fonts}{5}{style -- is not defined}
+\setinterfacemessage{fonts}{4}{bodyfont -- is not defined}
+\setinterfacemessage{fonts}{7}{unknown format --}
+\setinterfacemessage{fonts}{6}{-- is loaded}
+\setinterfacemessage{fonts}{14}{bodyfont -- is defined (can better be done global)}
+\setinterfacemessage{fonts}{8}{style -- defined}
+\setinterfacemessage{fonts}{title}{bodyfont}
+\setinterfacemessage{fonts}{10}{unknown font file --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{global file --}
+\setinterfacemessage{databases}{2}{local file --}
+\setinterfacemessage{databases}{4}{unknown file --}
+\setinterfacemessage{databases}{title}{databases}
+\setinterfacemessage{colors}{1}{system -- is global activated}
+\setinterfacemessage{colors}{3}{-- is not defined --}
+\setinterfacemessage{colors}{2}{system -- is local activated}
+\setinterfacemessage{colors}{5}{unknown system --}
+\setinterfacemessage{colors}{4}{system -- is loaded}
+\setinterfacemessage{colors}{7}{palette -- is not available}
+\setinterfacemessage{colors}{6}{palette -- is available}
+\setinterfacemessage{colors}{9}{-- color space is not supported}
+\setinterfacemessage{colors}{8}{specification -- at color -- becomes black}
+\setinterfacemessage{colors}{title}{color}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{color is converted to gray}
+\setinterfacemessage{colors}{10}{-- color space is supported}
+\setinterfacemessage{layouts}{1}{textheight adapted with -- at page --}
+\setinterfacemessage{layouts}{3}{-- times text postponed}
+\setinterfacemessage{layouts}{2}{-- times postponed text placed}
+\setinterfacemessage{layouts}{5}{marginblocks inactive}
+\setinterfacemessage{layouts}{4}{marginblocks active}
+\setinterfacemessage{layouts}{7}{calculating logospace}
+\setinterfacemessage{layouts}{6}{subpage set -- processed (size --)}
+\setinterfacemessage{layouts}{9}{currently no more than -- levels in itemizations}
+\setinterfacemessage{layouts}{8}{calculating backgrounds}
+\setinterfacemessage{layouts}{title}{layout}
+\setinterfacemessage{layouts}{11}{spacing -- not permitted in gridmode}
+\setinterfacemessage{layouts}{10}{-- and -- don't add up to 1.0}
+\setinterfacemessage{check}{1}{missing or ungrouped '=' after '--' in line --}
+\setinterfacemessage{check}{3}{-- -- replaces a macro, use CAPITALS!}
+\setinterfacemessage{check}{2}{-- argument(s) expected in line --}
+\setinterfacemessage{check}{title}{check}
+\setinterfacemessage{metapost}{1}{loading metapost library --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{file synonym -- is already used for --}
+\setinterfacemessage{files}{title}{files}
+\setinterfacemessage{figures}{1}{figure -- can not be found}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{figure -- is not preset}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{dimensions of -- loaded from figurefile itself}
+\setinterfacemessage{figures}{6}{dimensions of -- calculated by rlxtools}
+\setinterfacemessage{figures}{8}{figureobject -- is reused}
+\setinterfacemessage{figures}{title}{figures}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-mro.tex b/tex/context/base/mult-mro.tex
new file mode 100644
index 000000000..3f52fbc70
--- /dev/null
+++ b/tex/context/base/mult-mro.tex
@@ -0,0 +1,198 @@
+\setinterfacemessage{references}{1}{referinta necunoscuta --}
+\setinterfacemessage{references}{3}{tip necunoscut de referinta --}
+\setinterfacemessage{references}{2}{referinta duplicat -- la pagina --}
+\setinterfacemessage{references}{4}{referinta eronata --}
+\setinterfacemessage{references}{title}{referinte}
+\setinterfacemessage{references}{30}{obiect necunoscut --}
+\setinterfacemessage{references}{31}{obiect duplicat --}
+\setinterfacemessage{references}{21}{documentul -- este incarcat}
+\setinterfacemessage{references}{22}{documentul -- nu este interactiv}
+\setinterfacemessage{references}{23}{referinta obscura -- (prefix=--)}
+\setinterfacemessage{documents}{1}{sheet --}
+\setinterfacemessage{documents}{title}{sheets}
+\setinterfacemessage{documents}{2}{number --}
+\setinterfacemessage{handlings}{1}{font handling --}
+\setinterfacemessage{handlings}{3}{unknown font handling --}
+\setinterfacemessage{handlings}{2}{font handling -- is loaded}
+\setinterfacemessage{handlings}{title}{handling}
+\setinterfacemessage{systems}{title}{sistem}
+\setinterfacemessage{systems}{41}{fisierul extern -- din grupul -- nu exista}
+\setinterfacemessage{systems}{9}{-- nu este gasit/procesat}
+\setinterfacemessage{systems}{91}{papertray --}
+\setinterfacemessage{systems}{8}{o noua versiune de fisier utilitar, este necesara o noua trecere}
+\setinterfacemessage{systems}{21}{nici o data utilitara nu este incarcata}
+\setinterfacemessage{systems}{20}{intelesul (ordinea) pentru -- incarcat}
+\setinterfacemessage{systems}{5}{macro-urile din modulul -- s-au incarcat}
+\setinterfacemessage{systems}{4}{comanda -- este deja definita}
+\setinterfacemessage{systems}{27}{Versiune}
+\setinterfacemessage{systems}{26}{Registri}
+\setinterfacemessage{systems}{25}{Referinte}
+\setinterfacemessage{systems}{24}{Blocuri}
+\setinterfacemessage{systems}{1}{se incarca utilitarul-fisierul este amanat (typemode)}
+\setinterfacemessage{systems}{23}{-- aranjat la --}
+\setinterfacemessage{systems}{22}{folositi un fisier utilitar valid}
+\setinterfacemessage{systems}{2}{-- s-a incarcat}
+\setinterfacemessage{systems}{19}{intelesul (sinonimele) pentru -- incarcat}
+\setinterfacemessage{systems}{18}{sinonimul -- -- nu exista}
+\setinterfacemessage{systems}{7}{macro-urile din modulul -- s-au incarcat deja}
+\setinterfacemessage{systems}{6}{nu s-au gasit macro-uri in modulul --}
+\setinterfacemessage{systems}{14}{s-a fortat trecere pa pagina noua in lista la --}
+\setinterfacemessage{systems}{15}{buffer salvat --}
+\setinterfacemessage{systems}{16}{buffer-ul -- s-a cules}
+\setinterfacemessage{systems}{17}{se culege buffer-ul verbatim --}
+\setinterfacemessage{systems}{13}{marcajul -- definit --}
+\setinterfacemessage{systems}{12}{fisierul utilitar nu este sortat, folositi texutil}
+\setinterfacemessage{systems}{11}{se creeaza un utilitar simplu}
+\setinterfacemessage{systems}{10}{nu folositi em in --}
+\setinterfacemessage{floatblocks}{1}{-- renumerotat / -- => --}
+\setinterfacemessage{floatblocks}{3}{-- mutat}
+\setinterfacemessage{floatblocks}{2}{-- salvat}
+\setinterfacemessage{floatblocks}{5}{ordinea adaptata}
+\setinterfacemessage{floatblocks}{4}{-- plasat}
+\setinterfacemessage{floatblocks}{7}{nr. blocurilor de jos limitat la --}
+\setinterfacemessage{floatblocks}{6}{nr. cadrelor de sus limitat la --}
+\setinterfacemessage{floatblocks}{9}{ordinea deranjata}
+\setinterfacemessage{floatblocks}{8}{mai putin de -- linii}
+\setinterfacemessage{floatblocks}{title}{Blocuri}
+\setinterfacemessage{floatblocks}{13}{there is nothing to split}
+\setinterfacemessage{floatblocks}{12}{nedefinit}
+\setinterfacemessage{floatblocks}{11}{nu este dat nici un bloc}
+\setinterfacemessage{floatblocks}{10}{-- limitat}
+\setinterfacemessage{interactions}{1}{aspectul -- x -- (b x h)}
+\setinterfacemessage{interactions}{3}{inactiv}
+\setinterfacemessage{interactions}{2}{activ}
+\setinterfacemessage{interactions}{5}{unknown attachment --}
+\setinterfacemessage{interactions}{4}{nu exista sincronizare pt. pagini (--) in hmode}
+\setinterfacemessage{interactions}{6}{attachment file -- does not exist}
+\setinterfacemessage{interactions}{title}{interactiuni}
+\setinterfacemessage{interactions}{21}{-- cod inserat}
+\setinterfacemessage{structures}{1}{inceput de bloc sectiune --}
+\setinterfacemessage{structures}{title}{structuri}
+\setinterfacemessage{structures}{2}{sfarsit de bloc sectiune --}
+\setinterfacemessage{linguals}{1}{sablonul -- pentru -- s-a incarcat (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{3}{despartirea in silabe -- pentru -- s-a incarcat (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{2}{nu exista sabloane -- pentru -- (n=--,e=--,m=--) (--,--)}
+\setinterfacemessage{linguals}{5}{sabloanele pentru -- nu sunt incarcate}
+\setinterfacemessage{linguals}{4}{nu exista despartire in silabe -- pentru -- (n=--,e=--,m=--)}
+\setinterfacemessage{linguals}{7}{optiunile specifice ale limbii [--] introduc un spatiu --}
+\setinterfacemessage{linguals}{6}{limba -- nu este definita}
+\setinterfacemessage{linguals}{9}{limba -- este activa}
+\setinterfacemessage{linguals}{8}{optiunile specifice ale limbii [--] adaugate}
+\setinterfacemessage{linguals}{title}{limbi}
+\setinterfacemessage{linguals}{10}{sabloanele -- incarcate}
+\setinterfacemessage{regimes}{1}{codificarea --}
+\setinterfacemessage{regimes}{3}{codificarea -- este necunoscuta}
+\setinterfacemessage{regimes}{2}{codificarea -- este Encarcata}
+\setinterfacemessage{regimes}{title}{codificari}
+\setinterfacemessage{filters}{1}{filter -- is loaded}
+\setinterfacemessage{filters}{title}{filter}
+\setinterfacemessage{filters}{2}{unknown filter --}
+\setinterfacemessage{verbatims}{1}{fisierul -- nu exista}
+\setinterfacemessage{verbatims}{title}{verbatim}
+\setinterfacemessage{encodings}{1}{codificarea --}
+\setinterfacemessage{encodings}{3}{codificarea -- este necunoscuta}
+\setinterfacemessage{encodings}{2}{codificarea -- este Encarcata}
+\setinterfacemessage{encodings}{title}{codificari}
+\setinterfacemessage{columns}{1}{este posibil numai -- coloane}
+\setinterfacemessage{columns}{3}{probleme, se dezactiveaza alinierea}
+\setinterfacemessage{columns}{2}{folositi \string\filbreak\space ca alternativa}
+\setinterfacemessage{columns}{5}{cadrele bottom (bottom float) nu sunt inca suportate}
+\setinterfacemessage{columns}{4}{cadrele top (top float) nu sunt inca suportate}
+\setinterfacemessage{columns}{7}{alinierea este oprita dupa 100 de incercari}
+\setinterfacemessage{columns}{6}{-- blocurile sunt amanate}
+\setinterfacemessage{columns}{9}{verificat alinierea}
+\setinterfacemessage{columns}{8}{aliniat in -- pas(i)}
+\setinterfacemessage{columns}{title}{coloane}
+\setinterfacemessage{columns}{13}{blocul lat este mutat in partea de sus a coloanelor}
+\setinterfacemessage{columns}{12}{blocul este mutat pe urmatoarea coloana / --}
+\setinterfacemessage{columns}{11}{blocul este prea lat pentru coloana}
+\setinterfacemessage{columns}{10}{a mai ramas (mai putin de) 1 linie}
+\setinterfacemessage{textblocks}{1}{o noua versiune, este nevoie de inca o trecere}
+\setinterfacemessage{textblocks}{3}{se citesc blocurile din --}
+\setinterfacemessage{textblocks}{2}{se scriu blocurile in --}
+\setinterfacemessage{textblocks}{5}{-- nu este ascuns}
+\setinterfacemessage{textblocks}{4}{este nevoie de inca o trecere}
+\setinterfacemessage{textblocks}{7}{-- ascuns}
+\setinterfacemessage{textblocks}{6}{-- ascuns si procesat}
+\setinterfacemessage{textblocks}{9}{-- nu este cules}
+\setinterfacemessage{textblocks}{8}{-- cules}
+\setinterfacemessage{textblocks}{title}{blocuri de text}
+\setinterfacemessage{textblocks}{12}{-- sarit peste}
+\setinterfacemessage{textblocks}{11}{-- incarcat si cules}
+\setinterfacemessage{textblocks}{10}{-- incarcat si procesat}
+\setinterfacemessage{symbols}{1}{se incarca setul de simboluri --}
+\setinterfacemessage{symbols}{title}{simboluri}
+\setinterfacemessage{versions}{1}{lipseste @+}
+\setinterfacemessage{versions}{3}{pagini selectate: --}
+\setinterfacemessage{versions}{2}{pagini marcate}
+\setinterfacemessage{versions}{title}{versiuni}
+\setinterfacemessage{specials}{1}{-- incarcat}
+\setinterfacemessage{specials}{3}{-- s-a resetat}
+\setinterfacemessage{specials}{2}{nu este permis un nivel de imbricare mai mare --}
+\setinterfacemessage{specials}{5}{se incarca fisierul de definitii --}
+\setinterfacemessage{specials}{4}{comanda -- nu exista}
+\setinterfacemessage{specials}{7}{driver necunoscut --}
+\setinterfacemessage{specials}{6}{imbricarea nu este permisa}
+\setinterfacemessage{specials}{title}{specials}
+\setinterfacemessage{javascript}{1}{se incarca scriptul --}
+\setinterfacemessage{javascript}{title}{javascript}
+\setinterfacemessage{javascript}{2}{preambul necunoscut --}
+\setinterfacemessage{fonts}{1}{codificarea --}
+\setinterfacemessage{fonts}{3}{varianta necunoscuta --}
+\setinterfacemessage{fonts}{2}{varianta -- este incarcata}
+\setinterfacemessage{fonts}{5}{stilul -- nu este definit}
+\setinterfacemessage{fonts}{4}{corpul de litere -- nu este definit}
+\setinterfacemessage{fonts}{7}{format necunoscut --}
+\setinterfacemessage{fonts}{6}{-- este incarcat}
+\setinterfacemessage{fonts}{14}{bodyfont -- is defined (can better be done global)}
+\setinterfacemessage{fonts}{8}{stilul -- definit}
+\setinterfacemessage{fonts}{title}{corp de litere}
+\setinterfacemessage{fonts}{10}{fisier font necunoscut --}
+\setinterfacemessage{databases}{1}{--}
+\setinterfacemessage{databases}{3}{fisier global --}
+\setinterfacemessage{databases}{2}{fisier local --}
+\setinterfacemessage{databases}{4}{fisier necunoscut --}
+\setinterfacemessage{databases}{title}{baze de date}
+\setinterfacemessage{colors}{1}{sistem -- este activata global}
+\setinterfacemessage{colors}{3}{-- nu este definita --}
+\setinterfacemessage{colors}{2}{sistem -- este activata local}
+\setinterfacemessage{colors}{5}{sistem -- necunoscuta}
+\setinterfacemessage{colors}{4}{sistem -- este incarcata}
+\setinterfacemessage{colors}{7}{palette -- nu este disponibila}
+\setinterfacemessage{colors}{6}{paleta -- este disponibila}
+\setinterfacemessage{colors}{9}{spatiul de culoare -- nu este suportat}
+\setinterfacemessage{colors}{8}{specificatia -- la culoarea -- devine neagra}
+\setinterfacemessage{colors}{title}{culori}
+\setinterfacemessage{colors}{12}{-- is registered}
+\setinterfacemessage{colors}{11}{culoarea este convertita la gri}
+\setinterfacemessage{colors}{10}{spatiul de culoare -- este suportat}
+\setinterfacemessage{layouts}{1}{textheight adaptat cu -- la pagina --}
+\setinterfacemessage{layouts}{3}{textul amanat de -- ori}
+\setinterfacemessage{layouts}{2}{textul amanat de -- ori a fost plasat}
+\setinterfacemessage{layouts}{5}{blocuri marginale inactive}
+\setinterfacemessage{layouts}{4}{blocuri marginale active}
+\setinterfacemessage{layouts}{7}{se calculeaza spatiul pentru logo}
+\setinterfacemessage{layouts}{6}{setul -- de subpagini procesat (dimensiunea --)}
+\setinterfacemessage{layouts}{9}{acum nu se supota mai mult de -- nivele de adancime la iteratii}
+\setinterfacemessage{layouts}{8}{se calculeaza fundalurile}
+\setinterfacemessage{layouts}{title}{aranjamente}
+\setinterfacemessage{layouts}{11}{spatierea -- nu este permisa in gridmode}
+\setinterfacemessage{layouts}{10}{-- si -- nu se adauga pana la 1.0}
+\setinterfacemessage{check}{1}{lipseste '=' dupa '--' in linia --}
+\setinterfacemessage{check}{3}{-- -- inlocuieste un macro, folositi MAJUSCULE!}
+\setinterfacemessage{check}{2}{argumentul(ele) -- sunt asteptate in linia --}
+\setinterfacemessage{check}{title}{verificari}
+\setinterfacemessage{metapost}{1}{se incarca biblioteca metapost --}
+\setinterfacemessage{metapost}{title}{metapost}
+\setinterfacemessage{files}{1}{sinonimul fisierelor -- este folosit deja pentru --}
+\setinterfacemessage{files}{title}{fisiere}
+\setinterfacemessage{figures}{1}{figura -- nu poate fi gasita}
+\setinterfacemessage{figures}{3}{dimensions of -- are determined externally}
+\setinterfacemessage{figures}{2}{figura -- nu este presetata}
+\setinterfacemessage{figures}{5}{dimensions of -- are unknown}
+\setinterfacemessage{figures}{4}{dimensiunea figurii -- se incarca din fisierul insusi}
+\setinterfacemessage{figures}{6}{dimensiunea figurii -- este calculata de rlxtools}
+\setinterfacemessage{figures}{8}{obiectul figura -- este refolosit}
+\setinterfacemessage{figures}{title}{figuri}
+%
+\endinput \ No newline at end of file
diff --git a/tex/context/base/mult-nl.tex b/tex/context/base/mult-nl.tex
index 827b8fd80..30f0b36e6 100644
--- a/tex/context/base/mult-nl.tex
+++ b/tex/context/base/mult-nl.tex
@@ -68,6 +68,7 @@
\setinterfacevariable{after}{na}
\setinterfacevariable{all}{alles}
\setinterfacevariable{always}{altijd}
+\setinterfacevariable{answerarea}{antwoordgebied}
\setinterfacevariable{appendices}{bijlagen}
\setinterfacevariable{appendix}{bijlage}
\setinterfacevariable{april}{april}
@@ -237,6 +238,7 @@
\setinterfacevariable{lefthanging}{linkshangend}
\setinterfacevariable{leftmargin}{linkermarge}
\setinterfacevariable{leftpage}{linkerpagina}
+\setinterfacevariable{lefttoright}{lefttoright}
\setinterfacevariable{legend}{legenda}
\setinterfacevariable{lesshyphenation}{lesshyphenation}
\setinterfacevariable{line}{regel}
@@ -295,6 +297,7 @@
\setinterfacevariable{normal}{normaal}
\setinterfacevariable{nospacing}{geenspatiering}
\setinterfacevariable{not}{niet}
+\setinterfacevariable{note}{note}
\setinterfacevariable{nothanging}{niethangend}
\setinterfacevariable{nothyphenated}{nietafgebroken}
\setinterfacevariable{november}{november}
@@ -359,6 +362,7 @@
\setinterfacevariable{righthanging}{rechtshangend}
\setinterfacevariable{rightmargin}{rechtermarge}
\setinterfacevariable{rightpage}{rechterpagina}
+\setinterfacevariable{righttoleft}{righttoleft}
\setinterfacevariable{roman}{romaan}
\setinterfacevariable{romannumerals}{romeins}
\setinterfacevariable{rotate}{roteer}
@@ -428,6 +432,14 @@
\setinterfacevariable{subsubsubsubsubject}{subsubsubsubonderwerp}
\setinterfacevariable{subsubsubsubsubsection}{subsubsubsubsubparagraaf}
\setinterfacevariable{subsubsubsubsubsubject}{subsubsubsubsubonderwerp}
+\setinterfacevariable{subsubsubsubsubsubsection}{subsubsubsubsubsubparagraaf}
+\setinterfacevariable{subsubsubsubsubsubsubject}{subsubsubsubsubsubonderwerp}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{subsubsubsubsubsubsubparagraaf}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubonderwerp}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsubparagraaf}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubonderwerp}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsubsubparagraaf}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubsubonderwerp}
\setinterfacevariable{sunday}{zondag}
\setinterfacevariable{support}{support}
\setinterfacevariable{sym}{sym}
@@ -520,6 +532,8 @@
\setinterfaceconstant{bodyfont}{korps}
\setinterfaceconstant{bookmark}{bookmark}
\setinterfaceconstant{bottom}{onder}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
\setinterfaceconstant{bottomdistance}{onderafstand}
\setinterfaceconstant{bottomframe}{onderkader}
\setinterfaceconstant{bottomoffset}{onderoffset}
@@ -547,6 +561,7 @@
\setinterfaceconstant{component}{component}
\setinterfaceconstant{compoundhyphen}{koppelteken}
\setinterfaceconstant{compress}{comprimeren}
+\setinterfaceconstant{connector}{connector}
\setinterfaceconstant{continue}{doorgaan}
\setinterfaceconstant{contrastcolor}{contrastkleur}
\setinterfaceconstant{controls}{sturing}
@@ -593,6 +608,7 @@
\setinterfaceconstant{fieldlayer}{veldlaag}
\setinterfaceconstant{fieldoffset}{veldoffset}
\setinterfaceconstant{file}{file}
+\setinterfaceconstant{filtercommand}{filtercommand}
\setinterfaceconstant{focus}{focus}
\setinterfaceconstant{focusin}{focusin}
\setinterfaceconstant{focusout}{focusuit}
@@ -626,6 +642,7 @@
\setinterfaceconstant{height}{hoogte}
\setinterfaceconstant{hfactor}{hfactor}
\setinterfaceconstant{hfil}{hfil}
+\setinterfaceconstant{hidenumber}{hidenumber}
\setinterfaceconstant{hoffset}{hoffset}
\setinterfaceconstant{horoffset}{rugoffset}
\setinterfaceconstant{hyphen}{hyphen}
@@ -714,9 +731,17 @@
\setinterfaceconstant{number}{nummer}
\setinterfaceconstant{numbercolor}{nummerkleur}
\setinterfaceconstant{numbercommand}{nummercommando}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
\setinterfaceconstant{numberdistance}{nummerafstand}
\setinterfaceconstant{numbering}{nummeren}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
\setinterfaceconstant{numberseparator}{nummerscheider}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstopper}{numberstopper}
\setinterfaceconstant{numberstyle}{nummerletter}
\setinterfaceconstant{numberwidth}{nummerbreedte}
\setinterfaceconstant{nx}{nx}
@@ -736,8 +761,22 @@
\setinterfaceconstant{pageboundaries}{paginaovergangen}
\setinterfaceconstant{pagecolor}{paginakleur}
\setinterfaceconstant{pagecommand}{paginacommando}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
\setinterfaceconstant{pagenumber}{paginanummer}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
\setinterfaceconstant{pagestate}{paginastatus}
+\setinterfaceconstant{pagestopper}{pagestopper}
\setinterfaceconstant{pagestyle}{paginaletter}
\setinterfaceconstant{palet}{palet}
\setinterfaceconstant{paper}{papier}
@@ -747,6 +786,13 @@
\setinterfaceconstant{placestopper}{plaatsafsluiter}
\setinterfaceconstant{position}{positie}
\setinterfaceconstant{prefix}{prefix}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
\setinterfaceconstant{preset}{preset}
\setinterfaceconstant{preview}{preview}
\setinterfaceconstant{previous}{vorige}
@@ -757,6 +803,7 @@
\setinterfaceconstant{reduction}{reductie}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{reference}{verwijzing}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{refereren}
\setinterfaceconstant{regionin}{gebiedin}
\setinterfaceconstant{regionout}{gebieduit}
@@ -788,11 +835,18 @@
\setinterfaceconstant{rulethickness}{lijndikte}
\setinterfaceconstant{samepage}{zelfdepagina}
\setinterfaceconstant{sample}{monster}
+\setinterfaceconstant{saveinlist}{saveinlist}
\setinterfaceconstant{scale}{schaal}
\setinterfaceconstant{scope}{scope}
\setinterfaceconstant{screen}{raster}
\setinterfaceconstant{section}{sectie}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
\setinterfaceconstant{sectionnumber}{sectienummer}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
\setinterfaceconstant{separator}{scheider}
\setinterfaceconstant{set}{set}
\setinterfaceconstant{setups}{setups}
@@ -892,6 +946,8 @@
\setinterfaceconstant{ystep}{ystap}
% definitions for interface elements for language nl
%
+\setinterfaceelement{answerlines}{antwoordregels}
+\setinterfaceelement{answerspace}{antwoordruimte}
\setinterfaceelement{begin}{beginvan}
\setinterfaceelement{complete}{volledige}
\setinterfaceelement{coupled}{gekoppelde}
@@ -1277,6 +1333,7 @@
\setinterfacecommand{settextcontent}{steltekstinhoudin}
\setinterfacecommand{settextvariable}{kentekstvariabeletoe}
\setinterfacecommand{setupalign}{steluitlijnenin}
+\setinterfacecommand{setupanswerarea}{stelantwoordgebiedin}
\setinterfacecommand{setuparranging}{stelarrangerenin}
\setinterfacecommand{setupbackground}{stelachtergrondin}
\setinterfacecommand{setupbackgrounds}{stelachtergrondenin}
diff --git a/tex/context/base/mult-ro.tex b/tex/context/base/mult-ro.tex
index 297a57be9..ed3cf7e22 100644
--- a/tex/context/base/mult-ro.tex
+++ b/tex/context/base/mult-ro.tex
@@ -68,6 +68,7 @@
\setinterfacevariable{after}{dupa}
\setinterfacevariable{all}{tot}
\setinterfacevariable{always}{totdeauna}
+\setinterfacevariable{answerarea}{answerarea}
\setinterfacevariable{appendices}{apendixuri}
\setinterfacevariable{appendix}{apendix}
\setinterfacevariable{april}{aprilie}
@@ -237,6 +238,7 @@
\setinterfacevariable{lefthanging}{lefthanging}
\setinterfacevariable{leftmargin}{marginestanga}
\setinterfacevariable{leftpage}{paginastanga}
+\setinterfacevariable{lefttoright}{lefttoright}
\setinterfacevariable{legend}{legenda}
\setinterfacevariable{lesshyphenation}{lesshyphenation}
\setinterfacevariable{line}{linie}
@@ -295,6 +297,7 @@
\setinterfacevariable{normal}{normal}
\setinterfacevariable{nospacing}{nospacing}
\setinterfacevariable{not}{nu}
+\setinterfacevariable{note}{note}
\setinterfacevariable{nothanging}{nothanging}
\setinterfacevariable{nothyphenated}{nedespsilabe}
\setinterfacevariable{november}{noiembrie}
@@ -359,6 +362,7 @@
\setinterfacevariable{righthanging}{righthanging}
\setinterfacevariable{rightmargin}{marginedreapta}
\setinterfacevariable{rightpage}{paginadreapta}
+\setinterfacevariable{righttoleft}{righttoleft}
\setinterfacevariable{roman}{roman}
\setinterfacevariable{romannumerals}{numereromane}
\setinterfacevariable{rotate}{rotit}
@@ -428,6 +432,14 @@
\setinterfacevariable{subsubsubsubsubject}{subsubsubsubsubiect}
\setinterfacevariable{subsubsubsubsubsection}{subsubsubsubsubsectiune}
\setinterfacevariable{subsubsubsubsubsubject}{subsubsubsubsubsubiect}
+\setinterfacevariable{subsubsubsubsubsubsection}{subsubsubsubsubsubsectiune}
+\setinterfacevariable{subsubsubsubsubsubsubject}{subsubsubsubsubsubsubiect}
+\setinterfacevariable{subsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsectiune}
+\setinterfacevariable{subsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubiect}
+\setinterfacevariable{subsubsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsubsectiune}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubsubiect}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsection}{subsubsubsubsubsubsubsubsubsectiune}
+\setinterfacevariable{subsubsubsubsubsubsubsubsubsubject}{subsubsubsubsubsubsubsubsubsubiect}
\setinterfacevariable{sunday}{duminica}
\setinterfacevariable{support}{suport}
\setinterfacevariable{sym}{sym}
@@ -520,6 +532,8 @@
\setinterfaceconstant{bodyfont}{fonttext}
\setinterfaceconstant{bookmark}{semncarte}
\setinterfaceconstant{bottom}{jos}
+\setinterfaceconstant{bottomafter}{bottomafter}
+\setinterfaceconstant{bottombefore}{bottombefore}
\setinterfaceconstant{bottomdistance}{distantajos}
\setinterfaceconstant{bottomframe}{framejos}
\setinterfaceconstant{bottomoffset}{offsetjos}
@@ -547,6 +561,7 @@
\setinterfaceconstant{component}{component}
\setinterfaceconstant{compoundhyphen}{compoundhyphen}
\setinterfaceconstant{compress}{compress}
+\setinterfaceconstant{connector}{connector}
\setinterfaceconstant{continue}{continua}
\setinterfaceconstant{contrastcolor}{culoarecontrast}
\setinterfaceconstant{controls}{controale}
@@ -593,6 +608,7 @@
\setinterfaceconstant{fieldlayer}{fieldlayer}
\setinterfaceconstant{fieldoffset}{offsetcamp}
\setinterfaceconstant{file}{fisier}
+\setinterfaceconstant{filtercommand}{filtercommand}
\setinterfaceconstant{focus}{focus}
\setinterfaceconstant{focusin}{focusin}
\setinterfaceconstant{focusout}{focusout}
@@ -626,6 +642,7 @@
\setinterfaceconstant{height}{inaltime}
\setinterfaceconstant{hfactor}{hfactor}
\setinterfaceconstant{hfil}{hfil}
+\setinterfaceconstant{hidenumber}{hidenumber}
\setinterfaceconstant{hoffset}{hoffset}
\setinterfaceconstant{horoffset}{offsetoriz}
\setinterfaceconstant{hyphen}{hyphen}
@@ -714,9 +731,17 @@
\setinterfaceconstant{number}{numar}
\setinterfaceconstant{numbercolor}{culoarenumar}
\setinterfaceconstant{numbercommand}{comandanumar}
+\setinterfaceconstant{numberconversion}{numberconversion}
+\setinterfaceconstant{numberconversionset}{numberconversionset}
\setinterfaceconstant{numberdistance}{numberdistance}
\setinterfaceconstant{numbering}{numerotare}
+\setinterfaceconstant{numberorder}{numberorder}
+\setinterfaceconstant{numberprefix}{numberprefix}
+\setinterfaceconstant{numbersegments}{numbersegments}
\setinterfaceconstant{numberseparator}{separatornumar}
+\setinterfaceconstant{numberseparatorset}{numberseparatorset}
+\setinterfaceconstant{numberset}{numberset}
+\setinterfaceconstant{numberstopper}{numberstopper}
\setinterfaceconstant{numberstyle}{stilnumar}
\setinterfaceconstant{numberwidth}{numberwidth}
\setinterfaceconstant{nx}{nx}
@@ -736,8 +761,22 @@
\setinterfaceconstant{pageboundaries}{marginipagina}
\setinterfaceconstant{pagecolor}{culoarepagina}
\setinterfaceconstant{pagecommand}{comandapagina}
+\setinterfaceconstant{pageconversion}{pageconversion}
+\setinterfaceconstant{pageconversionset}{pageconversionset}
\setinterfaceconstant{pagenumber}{numarpagina}
+\setinterfaceconstant{pageprefix}{pageprefix}
+\setinterfaceconstant{pageprefixconnector}{pageprefixconnector}
+\setinterfaceconstant{pageprefixconversion}{pageprefixconversion}
+\setinterfaceconstant{pageprefixconversionset}{pageprefixconversionset}
+\setinterfaceconstant{pageprefixsegments}{pageprefixsegments}
+\setinterfaceconstant{pageprefixseparatorset}{pageprefixseparatorset}
+\setinterfaceconstant{pageprefixset}{pageprefixset}
+\setinterfaceconstant{pageprefixstopper}{pageprefixstopper}
+\setinterfaceconstant{pagesegments}{pagesegments}
+\setinterfaceconstant{pageseparatorset}{pageseparatorset}
+\setinterfaceconstant{pageset}{pageset}
\setinterfaceconstant{pagestate}{pagestate}
+\setinterfaceconstant{pagestopper}{pagestopper}
\setinterfaceconstant{pagestyle}{stilpagina}
\setinterfaceconstant{palet}{paleta}
\setinterfaceconstant{paper}{hartie}
@@ -747,6 +786,13 @@
\setinterfaceconstant{placestopper}{punestopper}
\setinterfaceconstant{position}{pozitie}
\setinterfaceconstant{prefix}{prefix}
+\setinterfaceconstant{prefixconnector}{prefixconnector}
+\setinterfaceconstant{prefixconversion}{prefixconversion}
+\setinterfaceconstant{prefixconversionset}{prefixconversionset}
+\setinterfaceconstant{prefixsegments}{prefixsegments}
+\setinterfaceconstant{prefixseparatorset}{prefixseparatorset}
+\setinterfaceconstant{prefixset}{prefixset}
+\setinterfaceconstant{prefixstopper}{prefixstopper}
\setinterfaceconstant{preset}{preset}
\setinterfaceconstant{preview}{previzualizare}
\setinterfaceconstant{previous}{precendent}
@@ -757,6 +803,7 @@
\setinterfaceconstant{reduction}{reducere}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{reference}{referinta}
+\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{referinta}
\setinterfaceconstant{regionin}{regiuneintrare}
\setinterfaceconstant{regionout}{regiuneiesire}
@@ -788,11 +835,18 @@
\setinterfaceconstant{rulethickness}{grosimerigla}
\setinterfaceconstant{samepage}{aceeasipagina}
\setinterfaceconstant{sample}{exemplu}
+\setinterfaceconstant{saveinlist}{saveinlist}
\setinterfaceconstant{scale}{scala}
\setinterfaceconstant{scope}{scop}
\setinterfaceconstant{screen}{ecran}
\setinterfaceconstant{section}{sectiune}
+\setinterfaceconstant{sectionconversion}{sectionconversion}
+\setinterfaceconstant{sectionconversionset}{sectionconversionset}
\setinterfaceconstant{sectionnumber}{numarsectiune}
+\setinterfaceconstant{sectionsegments}{sectionsegments}
+\setinterfaceconstant{sectionseparatorset}{sectionseparatorset}
+\setinterfaceconstant{sectionset}{sectionset}
+\setinterfaceconstant{sectionstopper}{sectionstopper}
\setinterfaceconstant{separator}{separator}
\setinterfaceconstant{set}{set}
\setinterfaceconstant{setups}{setups}
@@ -892,6 +946,8 @@
\setinterfaceconstant{ystep}{ystep}
% definitions for interface elements for language ro
%
+\setinterfaceelement{answerlines}{answerlines}
+\setinterfaceelement{answerspace}{answerspace}
\setinterfaceelement{begin}{inceput}
\setinterfaceelement{complete}{complet}
\setinterfaceelement{coupled}{cuplat}
@@ -1277,6 +1333,7 @@
\setinterfacecommand{settextcontent}{settextcontent}
\setinterfacecommand{settextvariable}{setvariabilatext}
\setinterfacecommand{setupalign}{seteazaalinierea}
+\setinterfacecommand{setupanswerarea}{setupanswerarea}
\setinterfacecommand{setuparranging}{seteazaaranjareapag}
\setinterfacecommand{setupbackground}{seteazafundal}
\setinterfacecommand{setupbackgrounds}{seteazafundaluri}
diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.tex
index 407146901..0fb64d98a 100644
--- a/tex/context/base/mult-sys.tex
+++ b/tex/context/base/mult-sys.tex
@@ -15,7 +15,7 @@
%D system constants. By doing so we save lots of memory while
%D at the same time we prevent ourself from typing errors.
-\writestatus{loading}{Context Multilingual Macros / System}
+\writestatus{loading}{ConTeXt Multilingual Macros / System}
\unprotect
@@ -39,7 +39,7 @@
\definesystemconstant {arabic} \definesystemconstant {ar}
\definesystemconstant {catalan} \definesystemconstant {ca}
\definesystemconstant {chinese} \definesystemconstant {cn}
-\definesystemconstant {croation} \definesystemconstant {hr}
+\definesystemconstant {croatian} \definesystemconstant {hr}
\definesystemconstant {czech} \definesystemconstant {cs} \definesystemconstant {cz}
\definesystemconstant {danish} \definesystemconstant {da}
\definesystemconstant {dutch} \definesystemconstant {nl}
@@ -116,10 +116,16 @@
\definemessageconstant {textblocks}
\definemessageconstant {verbatims}
\definemessageconstant {versions}
+\definemessageconstant {metapost}
+\definemessageconstant {chemicals}
%D Net come some \CONTEXT\ constants, used in the definition
%D of private commands:
+\definesystemconstant {tex}
+\definesystemconstant {xml}
+\definesystemconstant {lua}
+
\definesystemconstant {next}
\definesystemconstant {pickup}
\definesystemconstant {ascii}
@@ -144,6 +150,12 @@
\definesystemconstant {section} \let\v!sectionlevel\s!section % for old times sake
\definesystemconstant {handler}
\definesystemconstant {counter}
+\definesystemconstant {single}
+\definesystemconstant {multi}
+
+\definesystemconstant {hasnumber}
+\definesystemconstant {hastitle}
+\definesystemconstant {hascaption}
%D A more experienced \TEX\ user will recognize the next four
%D constants. We need these because font-definitions are
@@ -184,6 +196,10 @@
\definesystemconstant {black}
\definesystemconstant {white}
+\definesystemconstant {format}
+\definesystemconstant {extensions}
+\definesystemconstant {initializations}
+
%D Just to be complete we define the standard \TEX\ units.
\definesystemconstant {cm}
@@ -210,8 +226,11 @@
\definesystemconstant {see}
\definesystemconstant {from}
\definesystemconstant {to}
-\definesystemconstant {page}
\definesystemconstant {line}
+\definesystemconstant {page}
+\definesystemconstant {realpage}
+\definesystemconstant {userpage}
+\definesystemconstant {subpage}
\definesystemconstant {synonym}
@@ -332,22 +351,11 @@
\def\!!twelvepoint {12pt}
\def\!!fourteenpointfour {14.4pt}
-\newdimen \onepoint \onepoint = 1pt
-\newdimen \onebasepoint \onebasepoint = 1bp
-\chardef \scaledpoint = 1
-
\let\onerealpoint\onepoint % needed for latex
-\newcount\medcard \medcard\!!medcard % used in font module
-\newcount\maxcard \maxcard\!!maxcard % used in font module
-
-\ifx\thousandpoint\undefined \newdimen\thousandpoint \fi
-
-\thousandpoint=1000pt
-
-%D Another optimization is:
-
-\let\points\onepoint
+% D Another optimization is:
+%
+% \let\points\onepoint
%D A rough test is:
%D
@@ -402,6 +410,7 @@
\definesystemvariable {ck} % Character Kerning
\definesystemvariable {cl} % kleur (CoLor setup)
\definesystemvariable {cn} % CollumN
+\definesystemvariable {cm} % CheMical
\definesystemvariable {co} % COmbinaties
\definesystemvariable {cp} % CliP
\definesystemvariable {cr} % kleur (ColoR)
@@ -438,9 +447,11 @@
\definesystemvariable {fm} % ForMules
\definesystemvariable {fn} % subformulas
\definesystemvariable {fp} % FilegroeP
+\definesystemvariable {fq} % Features
\definesystemvariable {fr} % ForM
\definesystemvariable {fs} % FileSynonym
\definesystemvariable {ft} % FonTs
+\definesystemvariable {fu} % FontSolution
\definesystemvariable {fv} % FontVariant
\definesystemvariable {fx} % FoXet
\definesystemvariable {ha} % HAng
@@ -484,6 +495,7 @@
\definesystemvariable {ln} % LijNen
\definesystemvariable {lo} % LOgos
\definesystemvariable {lt} % LiTeratuur
+\definesystemvariable {ls} % languageScript
\definesystemvariable {ly} % LaYout
\definesystemvariable {ma} % MargeAchtergrond
\definesystemvariable {mb} % MargeBlokken
@@ -492,14 +504,16 @@
\definesystemvariable {mk} % MarKering
\definesystemvariable {mt} % inline MaTh
\definesystemvariable {mo} % Math Options
-\definesystemvariable {nm} % Nummering
\definesystemvariable {mx} % MatriX
\definesystemvariable {ng} % parbuilders
+\definesystemvariable {nh} % new heads (structure)
+\definesystemvariable {nm} % Nummering
\definesystemvariable {np} % NaastPlaatsen
\definesystemvariable {nr} % Nummeren
\definesystemvariable {of} % OFfset
\definesystemvariable {oi} % OmlijndInstellingen
\definesystemvariable {ol} % OmLijnd
+\definesystemvariable {od} % Omlijnd Defaults (simple)
\definesystemvariable {on} % ONderstreep
\definesystemvariable {oo} % OpsOmmingen
\definesystemvariable {op} % OPsomming
@@ -786,63 +800,23 @@
% \ifinterfacetranslation \else % interfacetranslation is obsolete
-\startmessages dutch library: check
- title: controle
- 1: '=' ontbreekt of zonder {} na '--' in regel --
- 2: -- argument(en) verwacht in regel --
- 3: -- -- vervangt een macro, gebruik HOOFDLETTERS!
-\stopmessages
+% messages moved
-\startmessages english library: check
- title: check
- 1: missing or ungrouped '=' after '--' in line --
- 2: -- argument(s) expected in line --
- 3: -- -- replaces a macro, use CAPITALS!
-\stopmessages
+% messages moved
% 1: to be adapted
-\startmessages german library: check
- title: check
- 1: Fehlendes '=' nach '--' in Zeile --
- 2: -- Argument(e) in Zeile -- erwartet
- 3: -- -- ersetzt ein Makro, verwende VERSALIEN!
-\stopmessages
-
-\startmessages czech library: check
- title: kontrola
- 1: postradam '=' po '--' na radku --
- 2: ocekavam -- argument(y) na radku --
- 3: -- -- nahrazuje makro, uzijte VERZALKY!
-\stopmessages
-
-\startmessages italian library: check
- title: controllo
- 1: '=' mancante o non raggruppato dopo '--' alla riga --
- 2: -- argomento/i attesi alla riga --
- 3: -- -- sostituisce una macro, usare le MAIUSCOLE!
-\stopmessages
-
-\startmessages norwegian library: check
- title: kontroll
- 1: manglende '=' etter '--' i linje --
- 2: -- argument forventet i linje --
- 3: -- -- overskygger en makro, bruk STORE BOKSTAVER!
-\stopmessages
-
-\startmessages romanian library: check
- title: verificari
- 1: lipseste '=' dupa '--' in linia --
- 2: argumentul(ele) -- sunt asteptate in linia --
- 3: -- -- inlocuieste un macro, folositi MAJUSCULE!
-\stopmessages
-
-\startmessages french library: check
- title: vérification
- 1: manquant ou dégroupé '=' après '--' à la ligne --
- 2: -- argument(s) attendu(s) à la ligne --
- 3: -- -- remplace une macro, utilisez des MAJUSCULES !
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
% \fi
diff --git a/tex/context/base/node-dum.lua b/tex/context/base/node-dum.lua
new file mode 100644
index 000000000..274e0cdd6
--- /dev/null
+++ b/tex/context/base/node-dum.lua
@@ -0,0 +1,24 @@
+if not modules then modules = { } end modules ['node-dum'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+nodes = nodes or { }
+
+function nodes.simple_font_dummy(head,tail)
+ return tail
+end
+
+function nodes.simple_font_handler(head)
+ local tail = node.slide(head)
+-- lang.hyphenate(head,tail)
+ head = nodes.process_characters(head,tail)
+ nodes.inject_kerns(head)
+ nodes.protect_glyphs(head)
+ tail = node.ligaturing(head,tail)
+ tail = node.kerning(head,tail)
+ return head
+end
diff --git a/tex/context/base/node-ext.lua b/tex/context/base/node-ext.lua
new file mode 100644
index 000000000..b098829cd
--- /dev/null
+++ b/tex/context/base/node-ext.lua
@@ -0,0 +1,30 @@
+if not modules then modules = { } end modules ['node-ext'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Serializing nodes can be handy for tracing. Also, saving and
+loading node lists can come in handy as soon we are going to
+use external applications to process node lists.</p>
+--ldx]]--
+
+function nodes.show(stack)
+-- texio.write_nl(table.serialize(stack))
+end
+
+function nodes.save(stack,name) -- *.ltn : luatex node file
+-- if name then
+-- file.savedata(name,table.serialize(stack))
+-- else
+-- texio.write_nl('log',table.serialize(stack))
+-- end
+end
+
+function nodes.load(name)
+-- return file.loaddata(name)
+-- -- todo
+end
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
new file mode 100644
index 000000000..3810b7a85
--- /dev/null
+++ b/tex/context/base/node-fin.lua
@@ -0,0 +1,363 @@
+if not modules then modules = { } end modules ['node-fin'] = {
+ version = 1.001,
+ comment = "companion to node-fin.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this module is being reconstructed
+
+local next, type, format = next, type, string.format
+local texsprint = tex.sprint
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local rule = node.id('rule')
+local whatsit = node.id('whatsit')
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+
+local has_attribute = node.has_attribute
+local copy_node = node.copy
+
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+
+states = states or { }
+shipouts = shipouts or { }
+
+local numbers = attributes.numbers
+local trigger = attributes.private('trigger')
+local triggering = false
+
+-- these two will be like trackers
+
+function states.enabletriggering()
+ triggering = true
+end
+function states.disabletriggering()
+ triggering = false
+end
+
+--
+
+states.collected = states.collected or { }
+
+storage.register("states/collected", states.collected, "states.collected")
+
+local collected = states.collected
+
+function states.collect(str)
+ collected[#collected+1] = str
+end
+
+function states.flush()
+ if #collected > 0 then
+ for i=1,#collected do
+ texsprint(ctxcatcodes,collected[i]) -- we're in context mode anyway
+ end
+ collected = { }
+ states.collected = collected
+ end
+end
+
+function states.check()
+ texio.write_nl(concat(collected,"\n"))
+end
+
+-- we used to do the main processor loop here and call processor for each node
+-- but eventually this was too much a slow down (1 sec on 23 for 120 pages mk)
+-- so that we moved looping to the processor itself; this may lead to a bit of
+-- duplicate code once that we have more state handlers
+
+local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer
+ starttiming(attributes)
+ local done, used, ok = false, nil, false
+ local attribute = numbers[plugin.name] -- todo: plugin.attribute
+ local namespace = plugin.namespace
+ if namespace.enabled then
+ local processor = plugin.processor
+ if processor then
+ local initializer = plugin.initializer
+ local resolver = plugin.resolver
+ local inheritance = (resolver and resolver()) or -0x7FFFFFFF -- we can best use nil and skip !
+ if initializer then
+ initializer(namespace,attribute,head)
+ end
+ head, ok = processor(namespace,attribute,head,inheritance)
+ if ok then
+ local finalizer = plugin.finalizer
+ if finalizer then
+ head, ok, used = finalizer(namespace,attribute,head)
+ if used then
+ local flusher = plugin.flusher
+ if flusher then
+ local h, d = flusher(namespace,attribute,head,used)
+ head = h
+ end
+ end
+ end
+ done = true
+ end
+ end
+ end
+ stoptiming(attributes)
+ return head, done
+end
+
+nodes.process_attribute = process_attribute
+
+function nodes.install_attribute_handler(plugin)
+ return function(head)
+ return process_attribute(head,plugin)
+ end
+end
+
+-- a few handlers
+
+local current, current_selector, used, done = 0, 0, { }, false
+
+local function insert(n,stack,previous,head) -- there is a helper, we need previous because we are not slided
+ if n then
+ if type(n) == "function" then
+ n = n()
+ end
+ if n then
+ n = copy_node(n)
+ n.next = stack
+ if previous then
+ previous.next = n
+ else
+ head = n
+ end
+ previous = n -- ?
+ else
+ -- weird
+ end
+ end
+ return stack, head
+end
+
+function states.initialize(what, attribute, stack)
+ current, current_selector, used, done = 0, 0, { }, false
+end
+
+function states.finalize(namespace,attribute,head) -- is this one ok?
+ if current > 0 then
+ local nn = namespace.none
+ if nn then
+ local id = head.id
+ if id == hlist or id == vlist then
+ local list = head.list
+ if list then
+ local _, h = insert(nn,list,nil,list)
+ head.list = h
+ end
+ else
+ stack, head = insert(nn,head,nil,head)
+ end
+ return head, true, true
+ end
+ end
+ return head, false, false
+end
+
+local function process(namespace,attribute,head,inheritance,default) -- one attribute
+ local trigger = triggering and namespace.triggering and trigger
+ local stack, previous, done = head, nil, false
+ local nsdata, nsreviver, nsnone = namespace.data, namespace.reviver, namespace.none
+ while stack do
+ local id = stack.id
+ -- we need to deal with literals too (reset as well as oval)
+--~ if id == glyph or (id == whatsit and stack.subtype == 8) or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc
+ if id == glyph or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc
+ local c = has_attribute(stack,attribute)
+ if c then
+ if default and c == inheritance then
+ if current ~= default then
+ local data = nsdata[default] or nsreviver(default)
+ stack, head = insert(data,stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
+ elseif current ~= c then
+ local data = nsdata[c] or nsreviver(c)
+ stack, head = insert(data,stack,previous,head)
+ current, done, used[c] = c, true, true
+ end
+ -- here ? compare selective
+ if id == glue then --leader
+ -- same as *list
+ local content = stack.leader
+ if content then
+ local savedcurrent = current
+ local ci = content.id
+ if ci == hlist or ci == vlist then
+ -- else we reset inside a box unneeded, okay, the downside is
+ -- that we trigger color in each repeated box, so there is room
+ -- for improvement here
+ current = 0
+ end
+ local ok = false
+ if trigger and has_attribute(stack,trigger) then
+ local outer = has_attribute(stack,attribute)
+ if outer ~= inheritance then
+ stack.leader, ok = process(namespace,attribute,content,inheritance,outer)
+ else
+ stack.leader, ok = process(namespace,attribute,content,inheritance,default)
+ end
+ else
+ stack.leader, ok = process(namespace,attribute,content,inheritance,default)
+ end
+ current = savedcurrent
+ done = done or ok
+ end
+ end
+ elseif default and inheritance then
+ if current ~= default then
+ local data = nsdata[default] or nsreviver(default)
+ stack, head = insert(data,stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
+ elseif current > 0 then
+ stack, head = insert(nsnone,stack,previous,head)
+ current, done, used[0] = 0, true, true
+ end
+ elseif id == hlist or id == vlist then
+ local content = stack.list
+ if content then
+ local ok = false
+ if trigger and has_attribute(stack,trigger) then
+ local outer = has_attribute(stack,attribute)
+ if outer ~= inheritance then
+ stack.list, ok = process(namespace,attribute,content,inheritance,outer)
+ else
+ stack.list, ok = process(namespace,attribute,content,inheritance,default)
+ end
+ else
+ stack.list, ok = process(namespace,attribute,content,inheritance,default)
+ end
+ done = done or ok
+ end
+ end
+ previous = stack
+ stack = stack.next
+ end
+ -- we need to play safe
+-- i need a proper test set for this, maybe controlled per feature
+--~ if current > 0 then
+--~ stack, head = insert(nsnone,stack,previous,head)
+--~ current, current_selector, done, used[0] = 0, 0, true, true
+--~ end
+ return head, done
+end
+
+states.process = process
+
+-- we can force a selector, e.g. document wide color spaces, saves a little
+-- watch out, we need to check both the selector state (like colorspace) and
+-- the main state (like color), otherwise we get into troubles when a selector
+-- state changes while the main state stays the same (like two glyphs following
+-- each other with the same color but different color spaces e.g. \showcolor)
+
+local function selective(namespace,attribute,head,inheritance,default) -- two attributes
+ local trigger = triggering and namespace.triggering and trigger
+ local stack, previous, done = head, nil, false
+ local nsforced, nsselector = namespace.forced, namespace.selector
+ local nsdata, nsreviver, nsnone = namespace.data, namespace.reviver, namespace.none
+ while stack do
+ local id = stack.id
+ -- we need to deal with literals too (reset as well as oval)
+--~ if id == glyph or (id == whatsit and stack.subtype == 8) or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc
+ if id == glyph or (id == rule and stack.width ~= 0) or (id == glue and stack.leader) then -- or disc
+ local c = has_attribute(stack,attribute)
+ if c then
+ if default and c == inheritance then
+ if current ~= default then
+ local data = nsdata[default] or nsreviver(default)
+ stack, head = insert(data[nsforced or has_attribute(stack,nsselector) or nsselector],stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
+ else
+ local s = has_attribute(stack,nsselector)
+ if current ~= c or current_selector ~= s then
+ local data = nsdata[c] or nsreviver(c)
+ stack, head = insert(data[nsforced or has_attribute(stack,nsselector) or nsselector],stack,previous,head)
+ current, current_selector, done, used[c] = c, s, true, true
+ end
+ end
+ elseif default and inheritance then
+ if current ~= default then
+ local data = nsdata[default] or nsreviver(default)
+ stack, head = insert(data[nsforced or has_attribute(stack,nsselector) or nsselector],stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
+ elseif current > 0 then
+ stack, head = insert(nsnone,stack,previous,head)
+ current, current_selector, done, used[0] = 0, 0, true, true
+ end
+ if id == glue then -- leader
+ -- same as *list
+ local content = stack.leader
+ if content then
+ local savedcurrent = current
+ local ci = content.id
+ if ci == hlist or ci == vlist then
+ -- else we reset inside a box unneeded, okay, the downside is
+ -- that we trigger color in each repeated box, so there is room
+ -- for improvement here
+ current = 0
+ end
+ local ok = false
+ if trigger and has_attribute(stack,trigger) then
+ local outer = has_attribute(stack,attribute)
+ if outer ~= inheritance then
+ stack.leader, ok = selective(namespace,attribute,content,inheritance,outer)
+ else
+ stack.leader, ok = selective(namespace,attribute,content,inheritance,default)
+ end
+ else
+ stack.leader, ok = selective(namespace,attribute,content,inheritance,default)
+ end
+ current = savedcurrent
+ done = done or ok
+ end
+ end
+ elseif id == hlist or id == vlist then
+ local content = stack.list
+ if content then
+ local ok = false
+ if trigger and has_attribute(stack,trigger) then
+ local outer = has_attribute(stack,attribute)
+ if outer ~= inheritance then
+ stack.list, ok = selective(namespace,attribute,content,inheritance,outer)
+ else
+ stack.list, ok = selective(namespace,attribute,content,inheritance,default)
+ end
+ else
+ stack.list, ok = selective(namespace,attribute,content,inheritance,default)
+ end
+ done = done or ok
+ end
+ end
+ previous = stack
+ stack = stack.next
+ end
+ -- we need to play safe, this is subptimal since now we end each box
+ -- even if it's not needed
+-- i need a proper test set for this, maybe controlled per feature
+--~ if current > 0 then
+--~ stack, head = insert(nsnone,stack,previous,head)
+--~ current, current_selector, done, used[0] = 0, 0, true, true
+--~ end
+ return head, done
+end
+
+states.selective = selective
+
+statistics.register("attribute processing time", function()
+ if statistics.elapsedindeed(attributes) then
+ return format("%s seconds",statistics.elapsedtime(attributes))
+ end
+end)
diff --git a/tex/context/base/node-fin.tex b/tex/context/base/node-fin.tex
new file mode 100644
index 000000000..787706ff2
--- /dev/null
+++ b/tex/context/base/node-fin.tex
@@ -0,0 +1,78 @@
+%D \module
+%D [ file=attr-ini,
+%D version=2007.06.06, % probably a bit older
+%D title=\CONTEXT\ Node Macros,
+%D subtitle=Finalizing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE]
+%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 Node Support / Finalizing}
+
+% Objects are processed indepently \unknown\ actually we may
+% need a proper callback.
+
+\unprotect
+
+\registerctxluafile{node-fin}{1.001} % we might generalize this one
+
+\definesystemattribute[trigger] % feature inheritance
+
+\newbox\finalizedshipoutbox
+
+\def\finalizeobjectbox#1{\ctxlua{nodes.process_page(tex.box[\number#1])}}
+
+\def\finalizeshipoutbox#1% % hack till we have access to pdf backend
+ {\global\setbox\finalizedshipoutbox\hbox{#1}%
+ \finalizeobjectbox\finalizedshipoutbox
+ \hbox{\ctxlua{states.flush()}\box\finalizedshipoutbox}}
+
+% tricky stuff:
+
+\newcount\attributeboxcount
+
+\edef\startinheritattributes{\dosetattribute {trigger}{1}}
+\edef\stopinheritattributes {\doresetattribute{trigger}}
+
+\def\doattributedcopy {\afterassignment\dodoattributedcopy\attributeboxcount}
+\def\doattributedbox {\afterassignment\dodoattributedbox \attributeboxcount}
+
+\def\dodoattributedcopy
+ {\startinheritattributes
+ \ifvbox\attributeboxcount
+ \vbox{\unvcopy\attributeboxcount}%
+ \else
+ \hbox{\unhcopy\attributeboxcount}%
+ \fi
+ \stopinheritattributes}
+
+\def\dodoattributedbox
+ {\startinheritattributes
+ \ifvbox\attributeboxcount
+ \vbox{\unvbox\attributeboxcount}%
+ \else
+ \hbox{\unhbox\attributeboxcount}%
+ \fi
+ \stopinheritattributes}
+
+\def\enableattributeinheritance
+ {\ctxlua{states.enabletriggering()}%
+ \let\attributedcopy\doattributedcopy
+ \let\attributedbox \doattributedbox}
+
+\def\disableattributeinheritance
+ {\ctxlua{states.disabletriggering()}%
+ \let\attributedcopy\copy
+ \let\attributedbox \box}
+
+\disableattributeinheritance
+
+% \appendtoks
+% \enableattributeinheritance % will become default
+% \to\everyjob
+
+\protect \endinput
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
new file mode 100644
index 000000000..3ad9060c3
--- /dev/null
+++ b/tex/context/base/node-fnt.lua
@@ -0,0 +1,206 @@
+if not modules then modules = { } end modules ['node-fnt'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+
+local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end)
+
+local glyph = node.id('glyph')
+
+local traverse_id = node.traverse_id
+local has_attribute = node.has_attribute
+
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+
+fonts = fonts or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+
+local fontdata = fonts.ids
+
+-- some tests with using an array of dynamics[id] and processes[id] demonstrated
+-- that there was nothing to gain (unless we also optimize other parts)
+--
+-- maybe getting rid of the intermediate shared can save some time
+
+-- potential speedup: check for subtype < 256 so that we can remove that test
+-- elsewhere, danger: injected nodes will not be dealt with but that does not
+-- happen often; we could consider processing sublists but that might need mor
+-- checking later on; the current approach also permits variants
+
+if tex.attribute[0] < 0 then
+
+ texio.write_nl("log","!")
+ texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+ texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+ texio.write_nl("log","! purposed so setting them at the TeX end might break the font handler.")
+ texio.write_nl("log","!")
+
+ tex.attribute[0] = 0 -- else no features
+
+end
+
+function nodes.process_characters(head)
+ -- either next or not, but definitely no already processed list
+ starttiming(nodes)
+ local usedfonts, attrfonts, done = { }, { }, false
+ local a, u, prevfont, prevattr = 0, 0, nil, 0
+ for n in traverse_id(glyph,head) do
+ local font, attr = n.font, has_attribute(n,0) -- zero attribute is reserved for fonts, preset to 0 is faster (first match)
+ if attr and attr > 0 then
+ if font ~= prevfont or attr ~= prevattr then
+ local used = attrfonts[font]
+ if not used then
+ used = { }
+ attrfonts[font] = used
+ end
+ if not used[attr] then
+ -- we do some testing outside the function
+ local tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ if shared then
+ local dynamics = shared.dynamics
+ if dynamics then
+ local d = shared.set_dynamics(font,dynamics,attr) -- still valid?
+ if d then
+ used[attr] = d
+ a = a + 1
+ end
+ end
+ end
+ end
+ prevfont, prevattr = font, attr
+ end
+ elseif font ~= prevfont then
+ prevfont, prevattr = font, 0
+ local used = usedfonts[font]
+ if not used then
+ local tfmdata = fontdata[font]
+ if tfmdata then
+ local shared = tfmdata.shared -- we need to check shared, only when same features
+ if shared then
+ local processors = shared.processes
+ if processors and #processors > 0 then
+ usedfonts[font] = processors
+ u = u + 1
+ end
+ end
+ else
+ -- probably nullfont
+ end
+ end
+ else
+ prevattr = attr
+ end
+ end
+ -- we could combine these and just make the attribute nil
+ if u == 1 then
+ local font, processors = next(usedfonts)
+ local n = #processors
+ if n > 0 then
+ local h, d = processors[1](head,font,false)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,0) -- false)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ elseif u > 0 then
+ for font, processors in next, usedfonts do
+ local n = #processors
+ local h, d = processors[1](head,font,false)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,0) -- false)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ end
+ if a == 1 then
+ local font, dynamics = next(attrfonts)
+ for attribute, processors in next, dynamics do -- attr can switch in between
+ local n = #processors
+ local h, d = processors[1](head,font,attribute)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,attribute)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ elseif a > 0 then
+ for font, dynamics in next, attrfonts do
+ for attribute, processors in next, dynamics do -- attr can switch in between
+ local n = #processors
+ local h, d = processors[1](head,font,attribute)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,attribute)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ end
+ end
+ stoptiming(nodes)
+ if trace_characters then
+ nodes.report(head,done)
+ end
+ return head, true
+end
+
+if node.protect_glyphs then
+
+ nodes.protect_glyphs = node.protect_glyphs
+ nodes.unprotect_glyphs = node.unprotect_glyphs
+
+else do
+
+ -- initial value subtype : X000 0001 = 1 = 0x01 = char
+ --
+ -- expected before linebreak : X000 0000 = 0 = 0x00 = glyph
+ -- X000 0010 = 2 = 0x02 = ligature
+ -- X000 0100 = 4 = 0x04 = ghost
+ -- X000 1010 = 10 = 0x0A = leftboundary lig
+ -- X001 0010 = 18 = 0x12 = rightboundary lig
+ -- X001 1010 = 26 = 0x1A = both boundaries lig
+ -- X000 1100 = 12 = 0x1C = leftghost
+ -- X001 0100 = 20 = 0x14 = rightghost
+
+
+ function nodes.protect_glyphs(head)
+ local done = false
+ for g in traverse_id(glyph,head) do
+ local s = g.subtype
+ if s == 1 then
+ done, g.subtype = true, 256
+ elseif s <= 256 then
+ done, g.subtype = true, 256 + s
+ end
+ end
+ return done
+ end
+
+ function nodes.unprotect_glyphs(head)
+ local done = false
+ for g in traverse_id(glyph,head) do
+ local s = g.subtype
+ if s > 256 then
+ done, g.subtype = true, s - 256
+ end
+ end
+ return done
+ end
+
+end end
diff --git a/tex/context/base/node-ini.lua b/tex/context/base/node-ini.lua
index 8b451124e..8185e3033 100644
--- a/tex/context/base/node-ini.lua
+++ b/tex/context/base/node-ini.lua
@@ -7,225 +7,68 @@ if not modules then modules = { } end modules ['node-ini'] = {
}
--[[ldx--
-<p>Access to nodes is what gives <l n='luatex'/> its power. Here we
-implement a few helper functions. These functions are rather optimized.</p>
+<p>Most of the code that had accumulated here is now separated in
+modules.</p>
--ldx]]--
-local format = string.format
-
-nodes = nodes or { }
-nodes.trace = false
-nodes.ignore = nodes.ignore or false
-
-local hlist = node.id('vlist')
-local vlist = node.id('hlist')
-local glyph = node.id('glyph')
-local disc = node.id('disc')
-local mark = node.id('mark')
-local glue = node.id('glue')
-local whatsit = node.id('whatsit')
-
--- handy helpers
-
-if node.protect_glyphs then
-
- nodes.protect_glyphs = node.protect_glyphs
- nodes.unprotect_glyphs = node.unprotect_glyphs
+-- this module is being reconstructed
-else do
+local utf = unicode.utf8
+local next, type = next, type
+local format, concat, match, utfchar = string.format, table.concat, string.match, utf.char
- -- initial value subtype : X000 0001 = 1 = 0x01 = char
- --
- -- expected before linebreak : X000 0000 = 0 = 0x00 = glyph
- -- X000 0010 = 2 = 0x02 = ligature
- -- X000 0100 = 4 = 0x04 = ghost
- -- X000 1010 = 10 = 0x0A = leftboundary lig
- -- X001 0010 = 18 = 0x12 = rightboundary lig
- -- X001 1010 = 26 = 0x1A = both boundaries lig
- -- X000 1100 = 12 = 0x1C = leftghost
- -- X001 0100 = 20 = 0x14 = rightghost
+local chardata = characters and characters.data
+--[[ldx--
+<p>We start with a registration system for atributes so that we can use the
+symbolic names later on.</p>
+--ldx]]--
- local traverse_id = node.traverse_id
-
- function nodes.protect_glyphs(head)
- local done = false
- for g in traverse_id(glyph,head) do
- local s = g.subtype
- if s == 1 then
- done, g.subtype = true, 256
- elseif s <= 256 then
- done, g.subtype = true, 256 + s
- end
- end
- return done
- end
-
- function nodes.unprotect_glyphs(head)
- local done = false
- for g in traverse_id(glyph,head) do
- local s = g.subtype
- if s > 256 then
- done, g.subtype = true, s - 256
- end
- end
- return done
- end
-
-end end
-
-do
-
- local remove, free = node.remove, node.free
-
- function nodes.remove(head, current, free_too)
- local t = current
- head, current = remove(head,current)
- if t then
- if free_too then
- free(t)
- t = nil
- else
- t.next, t.prev = nil, nil
- end
- end
- return head, current, t
- end
-
---~ function nodes.remove(head, current, delete)
---~ local t = current
---~ if current == head then
---~ current = current.next
---~ if current then
---~ current.prev = nil
---~ end
---~ head = current
---~ else
---~ local prev, next = current.prev, current.next
---~ if prev then
---~ prev.next = next
---~ end
---~ if next then
---~ next.prev = prev
---~ end
---~ current = next -- not: or next
---~ end
---~ if t then
---~ if free_too then
---~ free(t)
---~ t = nil
---~ else
---~ t.next, t.prev = nil, nil
---~ end
---~ end
---~ return head, current, t
---~ end
-
+attributes = attributes or { }
- function nodes.delete(head,current)
- return nodes.remove(head,current,true)
- end
+attributes.names = attributes.names or { }
+attributes.numbers = attributes.numbers or { }
+attributes.list = attributes.list or { }
+attributes.unsetvalue = -0x7FFFFFFF
- nodes.before = node.insert_before -- broken
- nodes.after = node.insert_after
+storage.register("attributes/names", attributes.names, "attributes.names")
+storage.register("attributes/numbers", attributes.numbers, "attributes.numbers")
+storage.register("attributes/list", attributes.list, "attributes.list")
- function nodes.before(h,c,n)
- if c then
- if c == h then
- n.next = h
- n.prev = nil
- h.prev = n
- else
- local cp = c.prev
- n.next = c
- n.prev = cp
- if cp then
- cp.next = n
- end
- c.prev = n
- return h, n
- end
- end
- return n, n
- end
+local names, numbers, list = attributes.names, attributes.numbers, attributes.list
- function nodes.after(h,c,n)
- if c then
- local cn = c.next
- if cn then
- n.next = cn
- cn.prev = n
- else
- n.next = nil
- end
- c.next = n
- n.prev = c
---~ if c ~= h then
- return h, n
---~ end
- end
- return n, n
+function attributes.define(name,number) -- at the tex end
+ if not numbers[name] then
+ numbers[name], names[number], list[number] = number, name, { }
end
-
- function nodes.show_list(head, message)
- if message then
- texio.write_nl(message)
- end
- for n in node.traverse(head) do
- texio.write_nl(tostring(n))
- end
- end
-
end
--- will move
+--[[ldx--
+<p>We can use the attributes in the range 127-255 (outside user space). These
+are only used when no attribute is set at the \TEX\ end which normally
+happens in <l n='context'/>.</p>
+--ldx]]--
-nodes.processors = { }
-nodes.processors.char = { }
-nodes.processors.char.proc = { }
+storage.shared.attributes_last_private = storage.shared.attributes_last_private or 127
-function nodes.report(t,done)
- if nodes.trace then -- best also test this before calling
- if done then
- if status.output_active then
- texio.write(format("<++ %s>",nodes.count(t)))
- else
- texio.write(format("<+ %s>",nodes.count(t)))
- end
- else
- if status.output_active then
- texio.write(format("<-- %s>",nodes.count(t)))
- else
- texio.write(format("<- %s>",nodes.count(t)))
- end
+function attributes.private(name) -- at the lua end (hidden from user)
+ local number = numbers[name]
+ if not number then
+ local last = storage.shared.attributes_last_private or 127
+ if last < 255 then
+ last = last + 1
+ storage.shared.attributes_last_private = last
end
+ number = last
+ numbers[name], names[number], list[number] = number, name, { }
end
+ return number
end
-do
-
- local function count(stack,flat)
- local n = 0
- while stack do
- local id = stack.id
- if not flat and id == hlist or id == vlist then
- local list = stack.list
- if list then
- n = n + 1 + count(list) -- self counts too
- else
- n = n + 1
- end
- else
- n = n + 1
- end
- stack = stack.next
- end
- return n
- end
-
- nodes.count = count
-
-end
+--[[ldx--
+<p>Access to nodes is what gives <l n='luatex'/> its power. Here we
+implement a few helper functions. These functions are rather optimized.</p>
+--ldx]]--
--[[ldx--
<p>When manipulating node lists in <l n='context'/>, we will remove
@@ -255,963 +98,136 @@ into the <l n='tex'/> engine, but this is a not so natural extension.</p>
also ignore the empty nodes. [This is obsolete!]</p>
--ldx]]--
+nodes = nodes or { }
---[[ldx--
-<p>Serializing nodes can be handy for tracing. Also, saving and
-loading node lists can come in handy as soon we are going to
-use external applications to process node lists.</p>
---ldx]]--
-
-function nodes.show(stack)
---~ texio.write_nl(table.serialize(stack))
-end
-
-function nodes.save(stack,name) -- *.ltn : luatex node file
---~ if name then
---~ file.savedata(name,table.serialize(stack))
---~ else
---~ texio.write_nl('log',table.serialize(stack))
---~ end
-end
-
-function nodes.load(name)
---~ return file.loaddata(name)
-end
-
--- node-cap.lua
-
---~ nodes.capture = { } -- somehow fails
-
---~ function nodes.capture.start(cbk)
---~ local head, tail = nil, nil
---~ callbacks.push(cbk, function(t)
---~ if tail then
---~ tail.next = t
---~ else
---~ head, tail = t, t
---~ end
---~ while tail.next do
---~ tail = tail.next
---~ end
---~ return false
---~ end)
---~ function nodes.capture.stop()
---~ function nodes.capture.stop() end
---~ function nodes.capture.get()
---~ function nodes.capture.get() end
---~ return head
---~ end
---~ callbacks.pop(cbk)
---~ end
---~ function nodes.capture.get() end -- error
---~ end
-
---~ nodes.capture.stop = function() end
---~ nodes.capture.get = function() end
-
--- node-gly.lua
-
-fonts = fonts or { }
-fonts.otf = fonts.otf or { }
-fonts.tfm = fonts.tfm or { }
-fonts.tfm.id = fonts.tfm.id or { }
-
-local tfm = fonts.tfm
-local otf = fonts.otf
-local tfmid = fonts.tfm.id
-
-do
-
- local has_attribute = node.has_attribute
- local traverse_id = node.traverse_id
-
- local pairs = pairs
-
- local starttiming, stoptiming = input.starttiming, input.stoptiming
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local penalty = node.id('penalty')
+local kern = node.id('kern')
+local whatsit = node.id('whatsit')
- function nodes.process_characters(head)
- -- not ok yet; we need a generic blocker
- -- if status.output_active then
- if false then -- status.output_active then
- return head, false -- true
+local traverse_id = node.traverse_id
+local traverse = node.traverse
+local slide_nodes = node.slide
+local free_node = node.free
+local remove_node = node.remove
+
+function nodes.remove(head, current, free_too)
+ local t = current
+ head, current = remove_node(head,current)
+ if t then
+ if free_too then
+ free_node(t)
+ t = nil
else
- -- either next or not, but definitely no already processed list
- starttiming(nodes)
- local usedfonts, attrfonts, done = { }, { }, false
- -- todo: should be independent of otf
- local set_dynamics = otf.set_dynamics -- todo: font-var.lua so that we can global this one
- local a, u, prevfont, prevattr = 0, 0, nil, 0
- for n in traverse_id(glyph,head) do
- local font, attr = n.font, has_attribute(n,0) -- zero attribute is reserved for fonts, preset to 0 is faster (first match)
- if attr and attr > 0 then
- if font ~= prevfont or attr ~= prevattr then
- local used = attrfonts[font]
- if not used then
- used = { }
- attrfonts[font] = used
- end
- if not used[attr] then
- local d = set_dynamics(tfmid[font],attr) -- todo, script, language -> n.language also axis
- if d then
- used[attr] = d
- a = a + 1
- end
- end
- prevfont, prevattr = font, attr
- end
- elseif font ~= prevfont then
- prevfont, prevattr = font, 0
- local used = usedfonts[font]
- if not used then
- local data = tfmid[font]
- if data then
- local shared = data.shared -- we need to check shared, only when same features
- if shared then
- local processors = shared.processors
- if processors and #processors > 0 then
- usedfonts[font] = processors
- u = u + 1
- end
- end
- else
- -- probably nullfont
- end
- end
- else
- prevattr = attr
- end
- end
- -- we could combine these and just make the attribute nil
- if u > 0 then
- for font, processors in pairs(usedfonts) do
- local n = #processors
- if n == 1 then
- local h, d = processors[1](head,font,false)
- head, done = h or head, done or d
- else
- for i=1,#processors do
- local h, d = processors[i](head,font,false)
- head, done = h or head, done or d
- end
- end
- end
- end
- if a > 0 then -- we need to get rid of a loop here
- for font, dynamics in pairs(attrfonts) do
- for attribute, processors in pairs(dynamics) do -- attr can switch in between
- local n = #processors
- if n == 1 then
- local h, d = processors[1](head,font,attribute)
- head, done = h or head, done or d
- else
- for i=1,n do
- local h, d = processors[i](head,font,attribute)
- head, done = h or head, done or d
- end
- end
- end
- end
- end
- stoptiming(nodes)
- if nodes.trace then
- nodes.report(head,done)
- end
- return head, true
- end
- end
-
-end
-
--- vbox: grouptype: vbox vtop output split_off split_keep | box_type: exactly|aditional
--- hbox: grouptype: hbox adjusted_hbox(=hbox_in_vmode) | box_type: exactly|aditional
-
-do
-
- local has_attribute, set, attribute = node.has_attribute, node.set_attribute, tex.attribute
-
- function nodes.inherit_attributes(n) -- still ok ?
- if n then
- local i = 1
- while true do
- local a = attribute[i]
- if a < 0 then
- break
- else
- local ai = has_attribute(n,i)
- if not ai then
- set(n,i,a)
- end
- i = i + 1
- end
- end
+ t.next, t.prev = nil, nil
end
- end
-
+ end
+ return head, current, t
end
-function nodes.length(head)
- if head then
- local m = 0
- for n in node.traverse(head) do
- m = m + 1
- end
- return m
- else
- return 0
- end
+function nodes.delete(head,current)
+ return nodes.remove(head,current,true)
end
-lists = lists or { }
-chars = chars or { }
-words = words or { } -- not used yet
-
-callbacks.trace = false
-
-do
+nodes.before = node.insert_before -- broken
+nodes.after = node.insert_after
- kernel = kernel or { }
+-- we need to test this, as it might be fixed
- local starttiming, stoptiming = input.starttiming, input.stoptiming
- local hyphenate, ligaturing, kerning = lang.hyphenate, node.ligaturing, node.kerning
-
- function kernel.hyphenation(head,tail) -- lang.hyphenate returns done
- if head == tail then
- return head, tail, false
- else
- starttiming(kernel)
- local done = head ~= tail and hyphenate(head,tail)
- stoptiming(kernel)
- return head, tail, done
- end
- end
- function kernel.ligaturing(head,tail) -- node.ligaturing returns head,tail,done
- if head == tail then
- return head, tail, false
+function nodes.before(h,c,n)
+ if c then
+ if c == h then
+ n.next = h
+ n.prev = nil
+ h.prev = n
else
- starttiming(kernel)
- local head, tail, done = ligaturing(head,tail)
- stoptiming(kernel)
- return head, tail, done
- end
- end
- function kernel.kerning(head,tail) -- node.kerning returns head,tail,done
- if head == tail then
- return head, tail, false
- else
- starttiming(kernel)
- local head, tail, done = kerning(head,tail)
- stoptiming(kernel)
- return head, tail, done
- end
- end
-
-end
-
-callback.register('hyphenate' , function(head,tail) return tail end)
-callback.register('ligaturing', function(head,tail) return tail end)
-callback.register('kerning' , function(head,tail) return tail end)
-
-nodes.tasks = nodes.tasks or { }
-nodes.tasks.data = nodes.tasks.data or { }
-
-function nodes.tasks.new(name,list)
- local tasklist = sequencer.reset()
- nodes.tasks.data[name] = { list = tasklist, runner = false }
- for _, task in ipairs(list) do
- sequencer.appendgroup(tasklist,task)
- end
-end
-
-function nodes.tasks.appendaction(name,group,action,where,kind)
- local data = nodes.tasks.data[name]
- sequencer.appendaction(data.list,group,action,where,kind)
- data.runner = false
-end
-
-function nodes.tasks.prependaction(name,group,action,where,kind)
- local data = nodes.tasks.data[name]
- sequencer.prependaction(data.list,group,action,where,kind)
- data.runner = false
-end
-
-function nodes.tasks.removeaction(name,group,action)
- local data = nodes.tasks.data[name]
- sequencer.removeaction(data.list,group,action)
- data.runner = false
-end
-
-function nodes.tasks.showactions(name,group,action,where,kind)
- local data = nodes.tasks.data[name]
- logs.report("nodes","task %s, list:\n%s",name,sequencer.nodeprocessor(data.list))
-end
-
-function nodes.tasks.actions(name)
- local data = nodes.tasks.data[name]
- return function(head,tail)
- local runner = data.runner
- if not runner then
- if nodes.trace_tasks then
- logs.report("nodes","creating task runner '%s'",name)
+ local cp = c.prev
+ n.next = c
+ n.prev = cp
+ if cp then
+ cp.next = n
end
- runner = sequencer.compile(data.list,sequencer.nodeprocessor)
- data.runner = runner
+ c.prev = n
+ return h, n
end
- return runner(head,tail)
end
+ return n, n
end
-nodes.tasks.new (
- "processors",
- {
- "before", -- for users
- "normalizers",
- "characters",
- "words",
- "fonts",
- "lists",
- "after", -- for users
- }
-)
-
--- these definitions will move
-
-nodes.tasks.appendaction("processors", "normalizers", "nodes.normalize_fonts", nil)
-nodes.tasks.appendaction("processors", "characters", "chars.handle_mirroring", nil, "notail")
-nodes.tasks.appendaction("processors", "characters", "chars.handle_casing", nil, "notail")
-nodes.tasks.appendaction("processors", "characters", "chars.handle_breakpoints", nil, "notail")
-nodes.tasks.appendaction("processors", "words", "kernel.hyphenation", nil)
-nodes.tasks.appendaction("processors", "words", "languages.words.check", nil, "notail")
-nodes.tasks.appendaction("processors", "fonts", "nodes.process_characters", nil, "notail")
-nodes.tasks.appendaction("processors", "fonts", "nodes.protect_glyphs", nil, "nohead")
-nodes.tasks.appendaction("processors", "fonts", "kernel.ligaturing", nil)
-nodes.tasks.appendaction("processors", "fonts", "kernel.kerning", nil)
-nodes.tasks.appendaction("processors", "lists", "lists.handle_spacing", nil, "notail")
-nodes.tasks.appendaction("processors", "lists", "lists.handle_kerning", nil, "notail")
-
-
-local free = node.free
-
-local function cleanup_page(head) -- rough
- local prev, start = nil, head
- while start do
- local id, nx = start.id, start.next
- if id == disc or id == mark then
- if prev then
- prev.next = nx
- end
- if start == head then
- head = nx
- end
- local tmp = start
- start = nx
- free(tmp)
- elseif id == hlist or id == vlist then
- local sl = start.list
- if sl then
- start.list = cleanup_page(sl)
- end
- prev, start = start, nx
+function nodes.after(h,c,n)
+ if c then
+ local cn = c.next
+ if cn then
+ n.next = cn
+ cn.prev = n
else
- prev, start = start, nx
+ n.next = nil
end
+ c.next = n
+ n.prev = c
+ return h, n
end
- return head
-end
-
-nodes.cleanup_page_first = false
-
-function nodes.cleanup_page(head)
- if nodes.cleanup_page_first then
- head = cleanup_page(head)
- end
- return head, false
-end
-
-nodes.tasks.new (
- "shipouts",
- {
- "before", -- for users
- "normalizers",
- "finishers",
- "after", -- for users
- }
-)
-
-nodes.tasks.appendaction("shipouts", "normalizers", "nodes.cleanup_page", nil, "notail")
-nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_color", nil, "notail")
-nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_transparency", nil, "notail")
-nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_overprint", nil, "notail")
-nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_negative", nil, "notail")
-nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_effect", nil, "notail")
-nodes.tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer", nil, "notail")
-
-local actions = nodes.tasks.actions("shipouts")
-
-function nodes.process_page(head) -- problem, attr loaded before node, todo ...
- return actions(head) -- no tail
+ return n, n
end
--- or just: nodes.process_page = nodes.tasks.actions("shipouts")
-
-
-do -- remove these
-
- local actions = nodes.tasks.actions("processors")
- local first_character = node.first_character
- local slide = node.slide
-
- local n = 0
-
- local function reconstruct(head)
- local t = { }
- local h = head
- while h do
- local id = h.id
- if id == glyph then
- t[#t+1] = utf.char(h.char)
- else
- t[#t+1] = "[]"
- end
- h = h.next
- end
- return table.concat(t)
- end
-
- local function tracer(what,state,head,groupcode,before,after,show)
- if not groupcode then
- groupcode = "unknown"
- elseif groupcode == "" then
- groupcode = "mvl"
- end
- n = n + 1
- if show then
- texio.write_nl(format("%s %s: %s, group: %s, nodes: %s -> %s, string: %s",what,n,state,groupcode,before,after,reconstruct(head)))
+function nodes.replace(head,current,new)
+ if current and next then
+ local p, n = current.prev, current.next
+ new.prev, new.next = p, n
+ if p then
+ p.next = new
else
- texio.write_nl(format("%s %s: %s, group: %s, nodes: %s -> %s",what,n,state,groupcode,before,after))
- end
- end
-
- function nodes.processors.pre_linebreak_filter(head,groupcode) -- todo: tail
- local first, found = first_character(head)
- if found then
- if callbacks.trace then
- local before = nodes.count(head,true)
- local head, tail, done = actions(head,slide(head))
- local after = nodes.count(head,true)
- if done then
- tracer("pre_linebreak","changed",head,groupcode,before,after,true)
- else
- tracer("pre_linebreak","unchanged",head,groupcode,before,after,true)
- end
- return (done and head) or true
- else
- local head, tail, done = actions(head,slide(head))
- return (done and head) or true
- end
- else
- if callbacks.trace then
- local n = nodes.count(head,false)
- tracer("pre_linebreak","no chars",head,groupcode,n,n)
- end
- return true
- end
- end
-
- function nodes.processors.hpack_filter(head,groupcode) -- todo: tail
- local first, found = first_character(head)
- if found then
- if callbacks.trace then
- local before = nodes.count(head,true)
- local head, tail, done = actions(head,slide(head))
- local after = nodes.count(head,true)
- if done then
- tracer("hpack","changed",head,groupcode,before,after,true)
- else
- tracer("hpack","unchanged",head,groupcode,before,after,true)
- end
- return (done and head) or true
- else
- local head, tail, done = actions(head,slide(head))
- return (done and head) or true
- end
- end
- if callbacks.trace then
- local n = nodes.count(head,false)
- tracer("hpack","no chars",head,groupcode,n,n)
- end
- return true
- end
-
-end
-
-callback.register('pre_linebreak_filter', nodes.processors.pre_linebreak_filter)
-callback.register('hpack_filter' , nodes.processors.hpack_filter)
-
-do
-
- -- beware, some field names will change in a next release of luatex
-
- local expand = table.tohash {
- "list", -- list_ptr & ins_ptr & adjust_ptr
- "pre", --
- "post", --
- "spec", -- glue_ptr
- "top_skip", --
- "attr", --
- "replace", -- nobreak
- "components", -- lig_ptr
- "box_left", --
- "box_right", --
- "glyph", -- margin_char
- "leader", -- leader_ptr
- "action", -- action_ptr
- "value", -- user_defined nodes with subtype 'a' en 'n'
- }
-
- -- page_insert: "height", "last_ins_ptr", "best_ins_ptr"
- -- split_insert: "height", "last_ins_ptr", "best_ins_ptr", "broken_ptr", "broken_ins"
-
- local ignore = table.tohash {
- "page_insert",
- "split_insert",
- "ref_count",
- }
-
- local dimension = table.tohash {
- "width", "height", "depth", "shift",
- "stretch", "shrink",
- "xoffset", "yoffset",
- "surround",
- "kern",
- "box_left_width", "box_right_width"
- }
-
- -- flat: don't use next, but indexes
- -- verbose: also add type
- -- can be sped up
-
- nodes.dimensionfields = dimension
- nodes.listablefields = expand
- nodes.ignorablefields = ignore
-
- -- not ok yet:
-
- function nodes.astable(n,sparse) -- not yet ok
- local f, t = node.fields(n.id,n.subtype), { }
- for i=1,#f do
- local v = f[i]
- local d = n[v]
- if d then
- if ignore[v] or v == "id" then
- -- skip
- elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number" or type(n[v]) ~= "table"
- t[v] = "pointer to list"
- elseif sparse then
- if (type(d) == "number" and d ~= 0) or (type(d) == "string" and d ~= "") then
- t[v] = d
- end
- else
- t[v] = d
- end
- end
- end
- t.type = node.type(n.id)
- return t
- end
-
- local nodefields = node.fields
- local nodetype = node.type
-
- -- under construction:
-
- local function totable(n,flat,verbose)
- local function to_table(n)
- local f = nodefields(n.id,n.subtype)
- local tt = { }
- for k=1,#f do
- local v = f[k]
- local nv = n[v]
- if nv then
- if ignore[v] then
- -- skip
- elseif expand[v] then
- if type(nv) == "number" or type(nv) == "string" then
- tt[v] = nv
- else
- tt[v] = totable(nv,flat,verbose)
- end
- elseif type(nv) == "table" then
- tt[v] = nv -- totable(nv,flat,verbose) -- data
- else
- tt[v] = nv
- end
- end
- end
- if verbose then
- tt.type = nodetype(tt.id)
- end
- return tt
+ head = new
end
if n then
- if flat then
- local t = { }
- while n do
- t[#t+1] = to_table(n)
- n = n.next
- end
- return t
- else
- local t = to_table(n)
- if n.next then
- t.next = totable(n.next,flat,verbose)
- end
- return t
- end
- else
- return { }
+ n.prev = new
end
+ free_node(current)
end
+ return head, current
+end
- nodes.totable = totable
-
- local function key(k)
- return ((type(k) == "number") and "["..k.."]") or k
- end
-
- -- not ok yet; this will become a module
+-- will move
- local function serialize(root,name,handle,depth,m)
- handle = handle or print
- if depth then
- depth = depth .. " "
- handle(("%s%s={"):format(depth,key(name)))
- else
- depth = ""
- local tname = type(name)
- if tname == "string" then
- if name == "return" then
- handle("return {")
- else
- handle(name .. "={")
- end
- elseif tname == "number"then
- handle("[" .. name .. "]={")
- else
- handle("t={")
- end
- end
- if root then
- local fld
- if root.id then
- fld = nodefields(root.id,root.subtype) -- we can cache these (todo)
+local function count(stack,flat)
+ local n = 0
+ while stack do
+ local id = stack.id
+ if not flat and id == hlist or id == vlist then
+ local list = stack.list
+ if list then
+ n = n + 1 + count(list) -- self counts too
else
- fld = table.sortedkeys(root)
- end
- if type(root) == 'table' and root['type'] then -- userdata or table
- handle(("%s %s=%q,"):format(depth,'type',root['type']))
- end
- for _,k in ipairs(fld) do
- if k == "ref_count" then
- -- skip
- elseif k then
- local v = root[k]
- local t = type(v)
- if t == "number" then
- if v == 0 then
- -- skip
- else
- handle(("%s %s=%s,"):format(depth,key(k),v))
- end
- elseif t == "string" then
- if v == "" then
- -- skip
- else
- handle(("%s %s=%q,"):format(depth,key(k),v))
- end
- elseif v then -- userdata or table
- serialize(v,k,handle,depth,m+1)
- end
- end
- end
- if root['next'] then -- userdata or table
- serialize(root['next'],'next',handle,depth,m+1)
+ n = n + 1
end
- end
- if m and m > 0 then
- handle(("%s},"):format(depth))
else
- handle(("%s}"):format(depth))
+ n = n + 1
end
+ stack = stack.next
end
-
- function nodes.serialize(root,name)
- local t = { }
- local function flush(s)
- t[#t+1] = s
- end
- serialize(root, name, flush, nil, 0)
- return table.concat(t,"\n")
- end
-
- function nodes.serializebox(n,flat,verbose)
- return nodes.serialize(nodes.totable(tex.box[n],flat,verbose))
- -- return nodes.serialize(tex.box[n])
- end
-
- function nodes.visualizebox(...)
- -- tex.sprint(tex.ctxcatcodes,"\\starttyping\n" .. nodes.serializebox(...) .. "\n\\stoptyping\n")
- tex.print(tex.ctxcatcodes,"\\starttyping")
- tex.print(nodes.serializebox(...))
- tex.print("\\stoptyping")
- end
-
- function nodes.list(head,n) -- name might change to nodes.type
- if not n then
- tex.print(tex.ctxcatcodes,"\\starttyping")
- end
- while head do
- local id = head.id
- tex.print(string.rep(" ",n or 0) .. tostring(head) .. "\n")
- if id == hlist or id == vlist then
- nodes.list(head.list,(n or 0)+1)
- end
- head = head.next
- end
- if not n then
- tex.print("\\stoptyping")
- end
- end
-
- function nodes.print(head,n)
- while head do
- local id = head.id
- texio.write_nl(string.rep(" ",n or 0) .. tostring(head))
- if id == hlist or id == vlist then
- nodes.print(head.list,(n or 0)+1)
- end
- head = head.next
- end
- end
-
- function nodes.check_for_leaks(sparse)
- local l = { }
- local q = node.usedlist()
- for p in node.traverse(q) do
- local s = table.serialize(nodes.astable(p,sparse),node.type(p.id))
- l[s] = (l[s] or 0) + 1
- end
- node.flush_list(q)
- for k, v in pairs(l) do
- texio.write_nl(format("%s * %s", v, k))
- end
- end
-
-end
-
-if not node.list_has_attribute then -- no longer needed
-
- function node.list_has_attribute(list,attribute)
- if list and attribute then
- for n in node.traverse(list) do
- local a = has_attribute(n,attribute)
- if a then return a end
- end
- end
- return false
- end
-
+ return n
end
-function nodes.pack_list(head)
- local t = { }
- for n in node.traverse(head) do
- t[#t+1] = tostring(n)
- end
- return t
-end
+nodes.count = count
-do
+-- new
- function nodes.leftskip(n)
- while n do
- local id = n.id
- if id == glue then
- if n.subtype == 8 then -- 7 in c/web source
- return (n.spec and n.spec.width) or 0
- else
- return 0
- end
- elseif id == whatsit then
- n = n.next
- elseif id == hlist then
- return n.width
- else
- break
- end
- end
- return 0
- end
- function nodes.rightskip(n)
- if n then
- n = node.slide(n)
- while n do
- local id = n.id
- if id == glue then
- if n.subtype == 9 then -- 8 in the c/web source
- return (n.spec and n.spec.width) or 0
- else
- return 0
- end
- elseif id == whatsit then
- n = n.prev
- else
- break
- end
- end
+function attributes.ofnode(n)
+ local a = n.attr
+ if a then
+ local names = attributes.names
+ a = a.next
+ while a do
+ local number, value = a.number, a.value
+ texio.write_nl(format("%s : attribute %3i, value %4i, name %s",tostring(n),number,value,names[number] or '?'))
+ a = a.next
end
- return false
- end
-
+ end
end
--- goodie
---
--- if node.valid(tex.box[0]) then print("valid node") end
-
---~ do
---~ local n = node.new(0,0)
---~ local m = getmetatable(n)
---~ m.__metatable = 'node'
---~ node.free(n)
-
---~ function node.valid(n)
---~ return n and getmetatable(n) == 'node'
---~ end
---~ end
+local left, space = lpeg.P("<"), lpeg.P(" ")
--- for the moment we put this here:
-
-do
-
- nodes.tracers = { }
- nodes.tracers.characters = { }
-
- local function collect(head,list,tag,n)
- n = n or 0
- local ok, fn = false, nil
- while head do
- local id = head.id
- if id == glyph then
- local f = head.font
- if f ~= fn then
- ok, fn = false, f
- end
- local c = head.char
- local d = tfmid[f].descriptions[c]
- local i = (d and d.index) or -1
- if not ok then
- ok = true
- n = n + 1
- list[n] = list[n] or { }
- list[n][tag] = { }
- end
- local l = list[n][tag]
- l[#l+1] = { c, f, i }
- elseif id == disc then
- -- skip
- else
- ok = false
- end
- head = head.next
- end
- end
-
- function nodes.tracers.characters.equal(ta, tb)
- if #ta ~= #tb then
- return false
- else
- for i=1,#ta do
- local a, b = ta[i], tb[i]
- if a[1] ~= b[1] or a[2] ~= b[2] or a[3] ~= b[3] then
- return false
- end
- end
- end
- return true
- end
- function nodes.tracers.characters.string(t)
- local tt = { }
- for i=1,#t do
- tt[i] = utf.char(t[i][1])
- end
- return table.concat(tt,"")
- end
- function nodes.tracers.characters.unicodes(t,decimal)
- local tt = { }
- for i=1,#t do
- if decimal then
- tt[i] = t[i][1]
- else
- tt[i] = format("%04X",t[i][1])
- end
- end
- return table.concat(tt," ")
- end
- function nodes.tracers.characters.indices(t,decimal)
- local tt = { }
- for i=1,#t do
- if decimal then
- tt[i] = t[i][3]
- else
- tt[i] = format("%04X",t[i][3])
- end
- end
- return table.concat(tt," ")
- end
- function nodes.tracers.characters.fonts(t)
- local f = t[1] and t[1][2]
- return (f and file.basename(tfmid[f].filename or "unknown")) or "unknown"
- end
-
- function nodes.tracers.characters.start()
- local npc = nodes.process_characters
- local list = { }
- function nodes.process_characters(head)
- local n = #list
- collect(head,list,'before',n)
- local h, d = npc(head)
- collect(head,list,'after',n)
- if #list > n then
- list[#list+1] = { }
- end
- return h, d
- end
- function nodes.tracers.characters.stop()
- tracers.list['characters'] = list
- lmx.set('title', 'ConTeXt Character Processing Information')
- lmx.set('color-background-one', lmx.get('color-background-yellow'))
- lmx.set('color-background-two', lmx.get('color-background-purple'))
- lmx.show('context-characters.lmx')
- lmx.restore()
- nodes.process_characters = npc
- end
- end
-
- local stack = { }
-
- function nodes.tracers.start(tag)
- stack[#stack+1] = tag
- local tracer = nodes.tracers[tag]
- if tracer and tracer.start then
- tracer.start()
- end
- end
- function nodes.tracers.stop()
- local tracer = stack[#stack]
- if tracer and tracer.stop then
- tracer.stop()
- end
- stack[#stack] = nil
- end
-
-end
+nodes.filterkey = left * (1-left)^0 * left * space^0 * lpeg.C((1-space)^0)
diff --git a/tex/context/base/node-ini.tex b/tex/context/base/node-ini.tex
index c033a1f7b..210f21229 100644
--- a/tex/context/base/node-ini.tex
+++ b/tex/context/base/node-ini.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=node-ini,
%D version=2006.08.20,
-%D title=\CONTEXT\ Character Macros,
-%D subtitle=Node Support (Initialization),
+%D title=\CONTEXT\ Node Macros,
+%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,10 +11,59 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Node Support (initialization)}
+\writestatus{loading}{ConTeXt Node Support / Initialization}
+
+\unprotect
+
+\newcount\filterstate \filterstate\plusone
-\registerctxluafile{node-seq}{1.001}
\registerctxluafile{node-ini}{1.001}
+\registerctxluafile{node-tst}{1.001}
+\registerctxluafile{node-tra}{1.001} % we might split it off (module)
+\registerctxluafile{node-seq}{1.001} % we might generalize this one
+\registerctxluafile{node-tsk}{1.001}
+\registerctxluafile{node-tex}{1.001}
+\registerctxluafile{node-res}{1.001}
+\registerctxluafile{node-pro}{1.001}
+\registerctxluafile{node-shp}{1.001}
+\registerctxluafile{node-ser}{1.001}
+\registerctxluafile{node-ext}{1.001}
+\registerctxluafile{node-inj}{1.001} % we might split it off
+
+\newtoks \attributesresetlist
+
+\ifdefined \v!global \else \def\v!global{global} \fi % for metatex
+
+\def\defineattribute
+ {\dodoubleempty\dodefineattribute}
+
+\def\dodefineattribute[#1][#2]% alternatively we can let lua do the housekeeping
+ {\expandafter\newattribute\csname @attr@#1\endcsname
+ \expandafter \xdef\csname :attr:#1\endcsname{\number\lastallocatedattribute}%
+ \ctxlua{attributes.define("#1",\number\lastallocatedattribute)}%
+ %\writestatus\m!systems{defining attribute #1 with number \number\lastallocatedattribute}%
+ \doifnotinset\v!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}}
+
+\def\definesystemattribute
+ {\dodoubleempty\dodefinesystemattribute}
+
+\def\dodefinesystemattribute[#1][#2]% alternatively we can let lua do the housekeeping
+ {\scratchcounter\ctxlua{tex.print(attributes.private("#1"))}\relax
+ \global\expandafter\attributedef\csname @attr@#1\endcsname\scratchcounter
+ \expandafter \xdef\csname :attr:#1\endcsname{\number\scratchcounter}%
+ %\writestatus\m!systems{defining system attribute #1 with number \number\scratchcounter}%
+ \doifnotinset\v!global{#2}{\appendetoks\csname @attr@#1\endcsname\attributeunsetvalue\to\attributesresetlist}}
+
+% expandable so we can \edef them for speed
+
+\def\dosetattribute#1#2{\csname @attr@#1\endcsname#2\relax}
+\def\doresetattribute#1{\csname @attr@#1\endcsname\attributeunsetvalue}
+\def\dogetattribute #1{\number\csname @attr@#1\endcsname}
+\def\dogetattributeid#1{\csname :attr:#1\endcsname}
+
+\let\dompattribute\gobbletwoarguments
+
+\def\resetallattributes{\the\attributesresetlist}
% \appendtoks
% \ctxlua {
@@ -54,4 +103,4 @@
% \stoptracingnodes
% \stoptext
-\endinput
+\protect \endinput
diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua
new file mode 100644
index 000000000..6ba21b39d
--- /dev/null
+++ b/tex/context/base/node-inj.lua
@@ -0,0 +1,608 @@
+if not modules then modules = { } end modules ['node-inj'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- tricky ... fonts.ids is not yet defined .. to be solved (maybe general tex ini)
+
+-- This is very experimental (this will change when we have luatex > .50 and
+-- a few pending thingies are available. Also, Idris needs to make a few more
+-- test fonts.
+
+local next = next
+
+local trace_injections = false trackers.register("nodes.injections", function(v) trace_injections = v end)
+
+fonts = fonts or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+
+local fontdata = fonts.ids
+
+local glyph = node.id('glyph')
+local kern = node.id('kern')
+
+local traverse_id = node.traverse_id
+local has_attribute = node.has_attribute
+local set_attribute = node.set_attribute
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+
+local newkern = nodes.kern
+
+local markbase = attributes.private('markbase')
+local markmark = attributes.private('markmark')
+local markdone = attributes.private('markdone')
+local cursbase = attributes.private('cursbase')
+local curscurs = attributes.private('curscurs')
+local cursdone = attributes.private('cursdone')
+local kernpair = attributes.private('kernpair')
+
+local cursives = { }
+local marks = { }
+local kerns = { }
+
+-- currently we do gpos/kern in a bit inofficial way but when we
+-- have the extra fields in glyphnodes to manipulate ht/dp/wd
+-- explicitly i will provide an alternative; also, we can share
+-- tables
+
+function nodes.set_cursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext)
+ local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2])
+ local ws, wn = tfmstart.width, tfmnext.width
+ local bound = #cursives + 1
+ set_attribute(start,cursbase,bound)
+ set_attribute(nxt,curscurs,bound)
+ cursives[bound] = { rlmode, dx, dy, ws, wn }
+ return dx, dy, bound
+end
+
+function nodes.set_pair(current,factor,rlmode,spec,tfmchr)
+ local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4]
+ -- dy = y - h
+ if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then
+ local bound = has_attribute(current,kernpair)
+ if bound then
+ local kb = kerns[bound]
+ kb[2], kb[3], kb[4], kb[5] = kb[2] + x, kb[3] + y, kb[4] + w, kb[5] + h
+ else
+ bound = #kerns + 1
+ set_attribute(current,kernpair,bound)
+ kerns[bound] = { rlmode, x, y, w, h }
+ end
+ return x, y, w, h, bound
+ end
+ return x, y, w, h -- no bound
+end
+
+function nodes.set_kern(current,factor,rlmode,x,tfmchr)
+ local dx = factor*x
+ if dx ~= 0 then
+ local bound = #kerns + 1
+ set_attribute(current,kernpair,bound)
+ kerns[bound] = { rlmode, dx }
+ end
+ return dx, bound
+end
+
+function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, ma=markanchor
+ local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2])
+ local bound = has_attribute(base,markbase)
+ if bound then
+ local mb = marks[bound]
+ if mb then
+ if not index then index = #mb + 1 end
+ mb[index] = { dx, dy }
+ set_attribute(start,markmark,bound)
+ set_attribute(start,markdone,index)
+ return dx, dy, bound
+ else
+ logs.report("nodes mark", "possible problem, U+%04X is base without data (id: %s)",base.char,bound)
+ end
+ end
+ index = index or 1
+ bound = #marks + 1
+ set_attribute(base,markbase,bound)
+ set_attribute(start,markmark,bound)
+ set_attribute(start,markdone,index)
+ marks[bound] = { [index] = { dx, dy } }
+ return dx, dy, bound
+end
+
+function nodes.trace_injection(head)
+ local function dir(n)
+ return (n<0 and "r-to-l") or (n>0 and "l-to-r") or ("unset")
+ end
+ local function report(...)
+ logs.report("nodes finisher",...)
+ end
+ report("begin run")
+ for n in traverse_id(glyph,head) do
+ if n.subtype < 256 then
+ local kp = has_attribute(n,kernpair)
+ local mb = has_attribute(n,markbase)
+ local mm = has_attribute(n,markmark)
+ local md = has_attribute(n,markdone)
+ local cb = has_attribute(n,cursbase)
+ local cc = has_attribute(n,curscurs)
+ report("char U+%05X, font=%s",n.char,n.font)
+ if kp then
+ local k = kerns[kp]
+ if k[3] then
+ report(" pairkern: dir=%s, x=%s, y=%s, w=%s, h=%s",dir(k[1]),k[2],k[3],k[4],k[5])
+ else
+ report(" kern: dir=%s, dx=%s",dir(k[1]),k[2])
+ end
+ end
+ if mb then
+ report(" markbase: bound=%s",mb)
+ end
+ if mm then
+ local m = marks[mm]
+ if mb then
+ local m = m[mb]
+ if m then
+ report(" markmark: bound=%s, index=%s, dx=%s, dy=%s",mm,j,m[1],m[2])
+ else
+ report(" markmark: bound=%s, missing index",mm)
+ end
+ else
+ m = m[1]
+ report(" markmark: bound=%s, dx=%s, dy=%s",mm,m[1],m[2])
+ end
+ end
+ if cb then
+ report(" cursbase: bound=%s",cb)
+ end
+ if cc then
+ local c = cursives[cc]
+ report(" curscurs: bound=%s, dir=%s, dx=%s, dy=%s",cc,dir(c[1]),c[2],c[3])
+ end
+ end
+ end
+ report("end run")
+end
+
+-- todo: reuse tables (i.e. no collection), but will be extra fields anyway
+
+function nodes.inject_kerns(head,tail,keep)
+ if trace_injections then
+ nodes.trace_injection(head)
+ end
+ local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns)
+ if has_marks or has_cursives then
+ -- in the future variant we will not copy items but refs to tables
+ local done, ky, rl, valid, cx, wx = false, { }, { }, { }, { }, { }
+ for n in traverse_id(glyph,head) do
+ if n.subtype < 256 then
+ valid[#valid+1] = n
+ if has_kerns then -- move outside loop
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ local x, y, w, h = kk[2], kk[3], kk[4], kk[5]
+ local dy = y - h
+ if dy ~= 0 then
+ ky[n] = dy
+ end
+ if w ~= 0 or x ~= 0 then
+ wx[n] = kk
+ end
+ rl[n] = kk[1] -- could move in test
+ end
+ end
+ end
+ end
+ end
+ if #valid > 0 then
+ -- we can assume done == true because we have cursives and marks
+ local cx = { }
+ if has_kerns and next(ky) then
+ for n, k in next, ky do
+ n.yoffset = k
+ end
+ end
+ -- todo: reuse t and use maxt
+ if has_cursives then
+ local n_cursbase, n_curscurs, p_cursbase, n, p, nf, tm = nil, nil, nil, nil, nil, nil, nil
+ -- since we need valid[n+1] we can also use a "while true do"
+ local t, d, maxt = { }, { }, 0
+ for i=1,#valid do -- valid == glyphs
+ n = valid[i]
+ if n.font ~= nf then
+ nf = n.font
+ tm = fontdata[nf].marks
+ -- maybe flush
+ maxt = 0
+ end
+ if not tm[n.char] then
+ n_cursbase = has_attribute(n,cursbase)
+ n_curscurs = has_attribute(n,curscurs)
+ if p_cursbase then
+ if p_cursbase == n_curscurs then
+ local c = cursives[n_curscurs]
+ if c then
+ local rlmode, dx, dy, ws, wn = c[1], c[2], c[3], c[4], c[5]
+ if rlmode >= 0 then
+ dx = dx - ws
+ else
+ dx = dx + wn
+ end
+ if dx ~= 0 then
+ cx[n] = dx
+ rl[n] = rlmode
+ end
+ -- if rlmode and rlmode < 0 then
+ dy = -dy
+ -- end
+ maxt = maxt + 1
+ t[maxt] = p
+ d[maxt] = dy
+ else
+ maxt = 0
+ end
+ end
+ elseif maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = t[i].yoffset + ny
+ end
+ maxt = 0
+ end
+ if not n_cursbase and maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ p_cursbase, p = n_cursbase, n
+ end
+ end
+ if maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ if not keep then
+ cursives = { }
+ end
+ end
+ if has_marks then
+ local p_markbase, n_markmark = nil, nil
+ for i=1,#valid do
+ local p = valid[i]
+ p_markbase = has_attribute(p,markbase)
+ if p_markbase then
+ local mrks = marks[p_markbase]
+ for n in traverse_id(glyph,p.next) do
+ n_markmark = has_attribute(n,markmark)
+ if p_markbase == n_markmark then
+ local index = has_attribute(n,markdone) or 1
+ local d = mrks[index]
+ if d then
+ -- local rlmode = d[3] -- not used
+ -- if rlmode and rlmode < 0 then
+ -- n.xoffset = p.xoffset + d[1]
+ -- else
+ n.xoffset = p.xoffset - d[1]
+ -- end
+ n.yoffset = p.yoffset + d[2]
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ if not keep then
+ marks = { }
+ end
+ end
+ -- todo : combine
+ if next(wx) then
+ for n, k in next, wx do
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, w = k[1], k[2] or 0, k[4] or 0
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ if next(cx) then
+ for n, k in next, cx do
+ if k ~= 0 then
+ local rln = rl[n]
+ if rln and rln < 0 then
+ insert_node_before(head,n,newkern(-k))
+ else
+ insert_node_before(head,n,newkern(k))
+ end
+ end
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ elseif not keep then
+ kerns, cursives, marks = { }, { }, { }
+ end
+ elseif has_kerns then
+ -- we assume done is true because there are kerns
+ for n in traverse_id(glyph,head) do
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, y, w = kk[1], kk[2] or 0, kk[3] or 0, kk[4] or 0
+ if y ~= 0 then
+ n.yoffset = y -- todo: h ?
+ end
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ end
+ return head, false
+end
+
+-- -- -- KEEP OLD ONE, THE NEXT IS JUST OPTIMIZED -- -- --
+
+function nodes.XXXXXXXxinject_kerns(head,tail,keep)
+ if trace_injections then
+ nodes.trace_injection(head)
+ end
+ local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns)
+ if has_marks or has_cursives then
+ -- in the future variant we will not copy items but refs to tables
+ local done, ky, valid, cx, wx = false, { }, { }, { }, { }
+ for n in traverse_id(glyph,head) do
+ if n.subtype < 256 then
+ valid[#valid+1] = n
+ if has_kerns then -- move outside loop
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ local x, y, w, h = kk[2], kk[3], kk[4], kk[5]
+ local dy = y - h
+ if dy ~= 0 then
+ ky[n] = dy
+ end
+ if w ~= 0 or x ~= 0 then
+ wx[n] = kk
+ end
+ end
+ end
+ end
+ end
+ end
+ if #valid > 0 then
+ -- we can assume done == true because we have cursives and marks
+ local cx = { }
+ if has_kerns and next(ky) then
+ for n, k in next, ky do
+ n.yoffset = k
+ end
+ end
+ -- todo: reuse t and use maxt
+ if has_cursives then
+ local n_cursbase, n_curscurs, p_cursbase, n, p, nf, tm = nil, nil, nil, nil, nil, nil, nil
+ -- since we need valid[n+1] we can also use a "while true do"
+ local t, d, maxt = { }, { }, 0
+ for i=1,#valid do -- valid == glyphs
+ n = valid[i]
+ if n.font ~= nf then
+ nf = n.font
+ tm = fontdata[nf].marks
+ -- maybe flush
+ maxt = 0
+ end
+ if not tm[n.char] then
+ n_cursbase = has_attribute(n,cursbase)
+ n_curscurs = has_attribute(n,curscurs)
+ if p_cursbase then
+ if p_cursbase == n_curscurs then
+ local c = cursives[n_curscurs]
+ if c then
+ local rlmode, dx, dy, ws, wn = c[1], c[2], c[3], c[4], c[5]
+ if rlmode >= 0 then
+ dx = dx - ws
+ else
+ dx = dx + wn
+ end
+ if dx ~= 0 then
+if rlmode < 0 then
+ cx[n] = -dx
+else
+ cx[n] = dx
+end
+ end
+ -- if rlmode and rlmode < 0 then
+ dy = -dy
+ -- end
+ maxt = maxt + 1
+ t[maxt] = p
+ d[maxt] = dy
+ else
+ maxt = 0
+ end
+ end
+ elseif maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = t[i].yoffset + ny
+ end
+ maxt = 0
+ end
+ if not n_cursbase and maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ p_cursbase, p = n_cursbase, n
+ end
+ end
+ if maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ if not keep then
+ cursives = { }
+ end
+ end
+ if has_marks then
+ local p_markbase, n_markmark = nil, nil
+ for i=1,#valid do
+ local p = valid[i]
+ p_markbase = has_attribute(p,markbase)
+ if p_markbase then
+ local mrks = marks[p_markbase]
+ for n in traverse_id(glyph,p.next) do
+ n_markmark = has_attribute(n,markmark)
+ if p_markbase == n_markmark then
+ local index = has_attribute(n,markdone) or 1
+ local d = mrks[index]
+ if d then
+ local d1, d2 = d[1], d[2]
+ if d1 ~= 0 then
+ n.xoffset = p.xoffset - d[1]
+ end
+ if d2 ~= 0 then
+ n.yoffset = p.yoffset + d[2]
+ end
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ if not keep then
+ marks = { }
+ end
+ end
+ -- todo : combine
+ if next(wx) then
+ for n, k in next, wx do
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, w = k[1], k[2] or 0, k[4] or 0
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ if next(cx) then
+ for n, k in next, cx do
+ insert_node_before(head,n,newkern(k))
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ elseif not keep then
+ kerns, cursives, marks = { }, { }, { }
+ end
+ elseif has_kerns then
+ -- we assume done is true because there are kerns
+ for n in traverse_id(glyph,head) do
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, y, w = kk[1], kk[2] or 0, kk[3] or 0, kk[4] or 0
+ if y ~= 0 then
+ n.yoffset = y -- todo: h ?
+ end
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ end
+ return head, false
+end
diff --git a/tex/context/base/node-par.lua b/tex/context/base/node-par.lua
index 7dd95ea5d..f275a1035 100644
--- a/tex/context/base/node-par.lua
+++ b/tex/context/base/node-par.lua
@@ -11,7 +11,7 @@ parbuilders.constructors = parbuilders.constructors or { }
parbuilders.names = parbuilders.names or { }
parbuilders.attribute = attributes.numbers['parbuilder'] or 999
-input.storage.register(false, "parbuilders.names", parbuilders.names, "parbuilders.names")
+storage.register("parbuilders.names", parbuilders.names, "parbuilders.names")
-- store parbuilders.names
diff --git a/tex/context/base/node-par.tex b/tex/context/base/node-par.tex
index 2e628c066..7f7ca9977 100644
--- a/tex/context/base/node-par.tex
+++ b/tex/context/base/node-par.tex
@@ -1,5 +1,5 @@
%D \module
-%D [ file=core-spa,
+%D [ file=node-par,
%D version=2008.09.30,
%D title=\CONTEXT\ Node Macros,
%D subtitle=Paragraph Building,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Paragraph Building}
+\writestatus{loading}{ConTeXt Node Macros / Paragraph Building}
%D This is very experimental, undocumented, subjected to changes, etc. just as
%D the underlying interfaces.
@@ -30,7 +30,7 @@
\registerctxluafile{node-par}{1.001}
-\defineattribute[parbuilder]
+\definesystemattribute[parbuilder]
\newcount\nofparbuilders
diff --git a/tex/context/base/node-pro.lua b/tex/context/base/node-pro.lua
new file mode 100644
index 000000000..575941fe5
--- /dev/null
+++ b/tex/context/base/node-pro.lua
@@ -0,0 +1,155 @@
+if not modules then modules = { } end modules ['node-pro'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utf = unicode.utf8
+local format, concat = string.format, table.concat
+
+local trace_callbacks = false trackers.register("nodes.callbacks", function(v) trace_callbacks = v end)
+
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+local glyph = node.id('glyph')
+local disc = node.id('disc')
+local mark = node.id('mark')
+
+local slide_nodes = node.slide
+local free_node = node.free
+local first_character = node.first_character
+
+nodes.processors = nodes.processors or { }
+
+-- vbox: grouptype: vbox vtop output split_off split_keep | box_type: exactly|aditional
+-- hbox: grouptype: hbox adjusted_hbox(=hbox_in_vmode) | box_type: exactly|aditional
+
+lists = lists or { }
+chars = chars or { }
+words = words or { } -- not used yet
+
+-- or just:
+--
+-- nodes.process_page = tasks.actions("shipouts")
+
+local actions = tasks.actions("processors")
+
+local n = 0
+
+local function reconstruct(head)
+ local t = { }
+ local h = head
+ while h do
+ local id = h.id
+ if id == glyph then
+ t[#t+1] = utf.char(h.char)
+ else
+ t[#t+1] = "[]"
+ end
+ h = h.next
+ end
+ return concat(t)
+end
+
+local function tracer(what,state,head,groupcode,before,after,show)
+ if not groupcode then
+ groupcode = "unknown"
+ elseif groupcode == "" then
+ groupcode = "mvl"
+ end
+ n = n + 1
+ if show then
+ texio.write_nl(format("%s %s: %s, group: %s, nodes: %s -> %s, string: %s",what,n,state,groupcode,before,after,reconstruct(head)))
+ else
+ texio.write_nl(format("%s %s: %s, group: %s, nodes: %s -> %s",what,n,state,groupcode,before,after))
+ end
+end
+
+nodes.processors.enabled = true -- thsi will become a proper state (like trackers)
+
+function nodes.processors.pre_linebreak_filter(head,groupcode) -- todo: tail
+ local first, found = first_character(head)
+ if found then
+ if trace_callbacks then
+ local before = nodes.count(head,true)
+ local head, tail, done = actions(head,slide_nodes(head))
+ local after = nodes.count(head,true)
+ if done then
+ tracer("pre_linebreak","changed",head,groupcode,before,after,true)
+ else
+ tracer("pre_linebreak","unchanged",head,groupcode,before,after,true)
+ end
+ return (done and head) or true
+ else
+ local head, tail, done = actions(head,slide_nodes(head))
+ return (done and head) or true
+ end
+ elseif trace_callbacks then
+ local n = nodes.count(head,false)
+ tracer("pre_linebreak","no chars",head,groupcode,n,n)
+ end
+ return true
+end
+
+function nodes.processors.hpack_filter(head,groupcode) -- todo: tail
+ local first, found = first_character(head)
+ if found then
+ if trace_callbacks then
+ local before = nodes.count(head,true)
+ local head, tail, done = actions(head,slide_nodes(head))
+ local after = nodes.count(head,true)
+ if done then
+ tracer("hpack","changed",head,groupcode,before,after,true)
+ else
+ tracer("hpack","unchanged",head,groupcode,before,after,true)
+ end
+ return (done and head) or true
+ else
+ local head, tail, done = actions(head,slide_nodes(head))
+ return (done and head) or true
+ end
+ elseif trace_callbacks then
+ local n = nodes.count(head,false)
+ tracer("hpack","no chars",head,groupcode,n,n)
+ end
+ return true
+end
+
+callback.register('pre_linebreak_filter', nodes.processors.pre_linebreak_filter)
+callback.register('hpack_filter' , nodes.processors.hpack_filter)
+
+local actions = tasks.actions("finalizers")
+
+function nodes.processors.post_linebreak_filter(head,groupcode) -- todo: tail
+ local first, found = first_character(head)
+ if found then
+ if trace_callbacks then
+ local before = nodes.count(head,true)
+ local head, tail, done = actions(head,slide_nodes(head))
+ local after = nodes.count(head,true)
+ if done then
+ tracer("finalizer","changed",head,groupcode,before,after,true)
+ else
+ tracer("finalizer","unchanged",head,groupcode,before,after,true)
+ end
+ return (done and head) or true
+ else
+ local head, tail, done = actions(head,slide_nodes(head))
+ return (done and head) or true
+ end
+ elseif trace_callbacks then
+ local n = nodes.count(head,false)
+ tracer("finalizer","no chars",head,groupcode,n,n)
+ end
+ return true
+end
+
+callback.register('post_linebreak_filter', nodes.processors.post_linebreak_filter)
+
+statistics.register("h-node processing time", function()
+ if statistics.elapsedindeed(nodes) then
+ return format("%s seconds including kernel", statistics.elapsedtime(nodes))
+ end
+end)
diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua
new file mode 100644
index 000000000..c8d815be4
--- /dev/null
+++ b/tex/context/base/node-res.lua
@@ -0,0 +1,110 @@
+if not modules then modules = { } end modules ['node-res'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local gmatch, format = string.gmatch, string.format
+local copy_node, free_node, new_node = node.copy, node.free, node.new
+
+--[[ldx--
+<p>The next function is not that much needed but in <l n='context'/> we use
+for debugging <l n='luatex'/> node management.</p>
+--ldx]]--
+
+nodes = nodes or { }
+
+local reserved = { }
+
+function nodes.register(n)
+ reserved[#reserved+1] = n
+ return n
+end
+
+function nodes.cleanup_reserved(nofboxes) -- todo
+ nodes.tracers.steppers.reset() -- todo: make a registration subsystem
+ local nr, nl = #reserved, 0
+ for i=1,nr do
+ free_node(reserved[i])
+ end
+ if nofboxes then
+ local tb = tex.box
+ for i=0,nofboxes do
+ local l = tb[i]
+ if l then
+ free_node(tb[i])
+ nl = nl + 1
+ end
+ end
+ end
+ reserved = { }
+ return nr, nl, nofboxes -- can be nil
+end
+
+function nodes.usage()
+ local t = { }
+ for n, tag in gmatch(status.node_mem_usage,"(%d+) ([a-z_]+)") do
+ t[tag] = n
+ end
+ return t
+end
+
+local pdfliteral = nodes.register(new_node("whatsit",8)) pdfliteral.mode = 1
+local disc = nodes.register(new_node("disc"))
+local kern = nodes.register(new_node("kern",1))
+local penalty = nodes.register(new_node("penalty"))
+local glue = nodes.register(new_node("glue"))
+local glue_spec = nodes.register(new_node("glue_spec"))
+local glyph = nodes.register(new_node("glyph",0))
+local textdir = nodes.register(new_node("whatsit",7))
+
+function nodes.glyph(fnt,chr)
+ local n = copy_node(glyph)
+ if fnt then n.font = fnt end
+ if chr then n.char = chr end
+ return n
+end
+function nodes.penalty(p)
+ local n = copy_node(penalty)
+ n.penalty = p
+ return n
+end
+function nodes.kern(k)
+ local n = copy_node(kern)
+ n.kern = k
+ return n
+end
+function nodes.glue(width,stretch,shrink)
+ local n, s = copy_node(glue), copy_node(glue_spec)
+ s.width, s.stretch, s.shrink = width, stretch, shrink
+ n.spec = s
+ return n
+end
+function nodes.glue_spec(width,stretch,shrink)
+ local s = copy_node(glue_spec)
+ s.width, s.stretch, s.shrink = width, stretch, shrink
+ return s
+end
+function nodes.disc()
+ return copy_node(disc)
+end
+function nodes.pdfliteral(str)
+ local t = copy_node(pdfliteral)
+ t.data = str
+ return t
+end
+function nodes.textdir(dir)
+ local t = copy_node(textdir)
+ t.dir = dir
+ return t
+end
+
+statistics.register("cleaned up reserved nodes", function()
+ return format("%s nodes, %s lists of %s", nodes.cleanup_reserved(tex.count["lastallocatedbox"]))
+end) -- \topofboxstack
+
+statistics.register("node memory usage", function() -- comes after cleanup !
+ return status.node_mem_usage
+end)
diff --git a/tex/context/base/node-seq.lua b/tex/context/base/node-seq.lua
index 2fd4f81aa..2794c34b9 100644
--- a/tex/context/base/node-seq.lua
+++ b/tex/context/base/node-seq.lua
@@ -6,12 +6,28 @@ if not modules then modules = { } end modules ['node-seq'] = {
license = "see context related readme files"
}
--- we assume namespace usage, i.e. unique names for functions
+--[[ldx--
+<p>Here we implement a mechanism for chaining the special functions
+that we use in <l n="context"> to deal with mode list processing. We
+assume that namespaces for the functions are used, but for speed we
+use locals to refer to them when compiling the chain.</p>
+--ldx]]--
-local format, concat = string.format, table.concat
+local format, gsub, concat, gmatch = string.format, string.gsub, table.concat, string.gmatch
sequencer = sequencer or { }
+local function validaction(action)
+ local g = _G
+ for str in gmatch(action,"[^%.]+") do
+ g = g[str]
+ if not g then
+ return false
+ end
+ end
+ return true
+end
+
function sequencer.reset()
return {
list = { },
@@ -34,18 +50,18 @@ function sequencer.appendgroup(t,group,where)
list[group] = { }
end
-function sequencer.prependaction(t,group,action,where,kind)
+function sequencer.prependaction(t,group,action,where,kind,force)
local g = t.list[group]
- if g then
+ if g and (force or validaction(action)) then
table.remove_value(g,action)
table.insert_before_value(g,where,action)
t.kind[action] = kind
end
end
-function sequencer.appendaction(t,group,action,where,kind)
+function sequencer.appendaction(t,group,action,where,kind,force)
local g = t.list[group]
- if g then
+ if g and (force or validaction(action)) then
table.remove_value(g,action)
table.insert_after_value(g,where,action)
t.kind[action] = kind
@@ -56,9 +72,9 @@ function sequencer.setkind(t,action,kind)
t.kind[action] = kind
end
-function sequencer.removeaction(t,group,action)
+function sequencer.removeaction(t,group,action,force)
local g = t.list[group]
- if g then
+ if g and (force or validaction(action)) then
table.remove_value(g,action)
end
end
@@ -75,7 +91,7 @@ function sequencer.compile(t,compiler)
end
local function localize(str)
- return str:gsub("%.","_")
+ return (gsub(str,"%.","_"))
end
local template = [[
@@ -96,12 +112,12 @@ function sequencer.tostring(t)
calls[#calls+1] = format(" %s(...) -- %s %i", localized, group, i)
end
end
- return template:format(concat(vars,"\n"),concat(calls,"\n"))
+ return format(template,concat(vars,"\n"),concat(calls,"\n"))
end
local template = [[
%s
-return function(head,tail)
+return function(head,tail,...)
local ok, done = false, false
%s
return head, tail, done
@@ -117,15 +133,16 @@ function sequencer.nodeprocessor(t)
local localized = localize(action)
vars[#vars+1] = format("local %s = %s",localized,action)
if kind[action] == "nohead" then
- calls[#calls+1] = format(" ok = %s(head,tail) done = done or ok -- %s %i",localized,group,i)
+ calls[#calls+1] = format(" ok = %s(head,tail,...) done = done or ok -- %s %i",localized,group,i)
elseif kind[action] == "notail" then
- calls[#calls+1] = format(" head, ok = %s(head,tail) done = done or ok -- %s %i",localized,group,i)
+ calls[#calls+1] = format(" head, ok = %s(head,tail,...) done = done or ok -- %s %i",localized,group,i)
else
- calls[#calls+1] = format(" head, tail, ok = %s(head,tail) done = done or ok -- %s %i",localized,group,i)
+ calls[#calls+1] = format(" head, tail, ok = %s(head,tail,...) done = done or ok -- %s %i",localized,group,i)
end
end
end
- return template:format(concat(vars,"\n"),concat(calls,"\n"))
+ local processor = format(template,concat(vars,"\n"),concat(calls,"\n"))
+ return processor
end
--~ hans = {}
diff --git a/tex/context/base/node-ser.lua b/tex/context/base/node-ser.lua
new file mode 100644
index 000000000..65c071c00
--- /dev/null
+++ b/tex/context/base/node-ser.lua
@@ -0,0 +1,274 @@
+if not modules then modules = { } end modules ['node-ser'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- beware, some field names will change in a next releases
+-- of luatex; this is pretty old code that needs an overhaul
+
+local type, format, concat = type, string.format, table.concat
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+
+local traverse = node.traverse
+local node_fields = node.fields
+local node_type = node.type
+
+local expand = table.tohash {
+ "list", -- list_ptr & ins_ptr & adjust_ptr
+ "pre", --
+ "post", --
+ "spec", -- glue_ptr
+ "top_skip", --
+ "attr", --
+ "replace", -- nobreak
+ "components", -- lig_ptr
+ "box_left", --
+ "box_right", --
+ "glyph", -- margin_char
+ "leader", -- leader_ptr
+ "action", -- action_ptr
+ "value", -- user_defined nodes with subtype 'a' en 'n'
+}
+
+-- page_insert: "height", "last_ins_ptr", "best_ins_ptr"
+-- split_insert: "height", "last_ins_ptr", "best_ins_ptr", "broken_ptr", "broken_ins"
+
+local ignore = table.tohash {
+ "page_insert",
+ "split_insert",
+ "ref_count",
+}
+
+local dimension = table.tohash {
+ "width", "height", "depth", "shift",
+ "stretch", "shrink",
+ "xoffset", "yoffset",
+ "surround",
+ "kern",
+ "box_left_width", "box_right_width"
+}
+
+-- flat: don't use next, but indexes
+-- verbose: also add type
+-- can be sped up
+
+nodes.dimensionfields = dimension
+nodes.listablefields = expand
+nodes.ignorablefields = ignore
+
+-- not ok yet:
+
+function nodes.astable(n,sparse) -- not yet ok
+ local f, t = node_fields(n.id,n.subtype), { }
+ for i=1,#f do
+ local v = f[i]
+ local d = n[v]
+ if d then
+ if ignore[v] or v == "id" then
+ -- skip
+ elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number" or type(n[v]) ~= "table"
+ t[v] = "pointer to list"
+ elseif sparse then
+ if (type(d) == "number" and d ~= 0) or (type(d) == "string" and d ~= "") then
+ t[v] = d
+ end
+ else
+ t[v] = d
+ end
+ end
+ end
+ t.type = node_type(n.id)
+ return t
+end
+
+-- under construction:
+
+local function totable(n,flat,verbose)
+ -- todo: no local function
+ local function to_table(n,flat,verbose)
+ local f = node_fields(n.id,n.subtype)
+ local tt = { }
+ for k=1,#f do
+ local v = f[k]
+ local nv = n[v]
+ if nv then
+ if ignore[v] then
+ -- skip
+ elseif expand[v] then
+ if type(nv) == "number" or type(nv) == "string" then
+ tt[v] = nv
+ else
+ tt[v] = totable(nv,flat,verbose)
+ end
+ elseif type(nv) == "table" then
+ tt[v] = nv -- totable(nv,flat,verbose) -- data
+ else
+ tt[v] = nv
+ end
+ end
+ end
+ if verbose then
+ tt.type = node_type(tt.id)
+ end
+ return tt
+ end
+ if n then
+ if flat then
+ local t = { }
+ while n do
+ t[#t+1] = to_table(n,flat,verbise)
+ n = n.next
+ end
+ return t
+ else
+ local t = to_table(n)
+ if n.next then
+ t.next = totable(n.next,flat,verbose)
+ end
+ return t
+ end
+ else
+ return { }
+ end
+end
+
+nodes.totable = totable
+
+local function key(k)
+ return ((type(k) == "number") and "["..k.."]") or k
+end
+
+-- not ok yet; this will become a module
+
+local function serialize(root,name,handle,depth,m)
+ handle = handle or print
+ if depth then
+ depth = depth .. " "
+ handle(format("%s%s={",depth,key(name)))
+ else
+ depth = ""
+ local tname = type(name)
+ if tname == "string" then
+ if name == "return" then
+ handle("return {")
+ else
+ handle(name .. "={")
+ end
+ elseif tname == "number" then
+ handle("[" .. name .. "]={")
+ else
+ handle("t={")
+ end
+ end
+ if root then
+ local fld
+ if root.id then
+ fld = node_fields(root.id,root.subtype) -- we can cache these (todo)
+ else
+ fld = table.sortedkeys(root)
+ end
+ if type(root) == 'table' and root['type'] then -- userdata or table
+ handle(format("%s %s=%q,",depth,'type',root['type']))
+ end
+ for f=1,#fld do
+ local k = fld[f]
+ if k == "ref_count" then
+ -- skip
+ elseif k then
+ local v = root[k]
+ local t = type(v)
+ if t == "number" then
+ if v == 0 then
+ -- skip
+ else
+ handle(format("%s %s=%s,",depth,key(k),v))
+ end
+ elseif t == "string" then
+ if v == "" then
+ -- skip
+ else
+ handle(format("%s %s=%q,",depth,key(k),v))
+ end
+ elseif v then -- userdata or table
+ serialize(v,k,handle,depth,m+1)
+ end
+ end
+ end
+ if root['next'] then -- userdata or table
+ serialize(root['next'],'next',handle,depth,m+1)
+ end
+ end
+ if m and m > 0 then
+ handle(format("%s},",depth))
+ else
+ handle(format("%s}",depth))
+ end
+end
+
+function nodes.serialize(root,name)
+ local t = { }
+ local function flush(s)
+ t[#t+1] = s
+ end
+ serialize(root, name, flush, nil, 0)
+ return concat(t,"\n")
+end
+
+function nodes.serializebox(n,flat,verbose,name)
+ return nodes.serialize(nodes.totable(tex.box[n],flat,verbose),name)
+end
+
+function nodes.visualizebox(...)
+ tex.print(ctxcatcodes,"\\starttyping")
+ tex.print(nodes.serializebox(...))
+ tex.print("\\stoptyping")
+end
+
+function nodes.list(head,n) -- name might change to nodes.type
+ if not n then
+ tex.print(ctxcatcodes,"\\starttyping")
+ end
+ while head do
+ local id = head.id
+ tex.print(string.rep(" ",n or 0) .. tostring(head) .. "\n")
+ if id == hlist or id == vlist then
+ nodes.list(head.list,(n or 0)+1)
+ end
+ head = head.next
+ end
+ if not n then
+ tex.print("\\stoptyping")
+ end
+end
+
+function nodes.print(head,n)
+ while head do
+ local id = head.id
+ texio.write_nl(string.rep(" ",n or 0) .. tostring(head))
+ if id == hlist or id == vlist then
+ nodes.print(head.list,(n or 0)+1)
+ end
+ head = head.next
+ end
+end
+
+function nodes.check_for_leaks(sparse)
+ local l = { }
+ local q = node.usedlist()
+ for p in traverse(q) do
+ local s = table.serialize(nodes.astable(p,sparse),node_type(p.id))
+ l[s] = (l[s] or 0) + 1
+ end
+ node.flush_list(q)
+ for k, v in next, l do
+ texio.write_nl(format("%s * %s", v, k))
+ end
+end
+
diff --git a/tex/context/base/node-shp.lua b/tex/context/base/node-shp.lua
new file mode 100644
index 000000000..0383d8c40
--- /dev/null
+++ b/tex/context/base/node-shp.lua
@@ -0,0 +1,66 @@
+if not modules then modules = { } end modules ['node-shp'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+local disc = node.id('disc')
+local mark = node.id('mark')
+
+local free_node = node.free
+
+local function cleanup_page(head) -- rough
+ local prev, start = nil, head
+ while start do
+ local id, nx = start.id, start.next
+ if id == disc or id == mark then
+ if prev then
+ prev.next = nx
+ end
+ if start == head then
+ head = nx
+ end
+ local tmp = start
+ start = nx
+ free_node(tmp)
+ elseif id == hlist or id == vlist then
+ local sl = start.list
+ if sl then
+ start.list = cleanup_page(sl)
+ prev, start = start, nx
+ else
+ if prev then
+ prev.next = nx
+ end
+ if start == head then
+ head = nx
+ end
+ local tmp = start
+ start = nx
+ free_node(tmp)
+ end
+ else
+ prev, start = start, nx
+ end
+ end
+ return head
+end
+
+nodes.cleanup_page_first = false
+
+function nodes.cleanup_page(head)
+ if nodes.cleanup_page_first then
+ head = cleanup_page(head)
+ end
+ return head, false
+end
+
+local actions = tasks.actions("shipouts")
+
+function nodes.process_page(head) -- problem, attr loaded before node, todo ...
+ return actions(head) -- no tail
+end
diff --git a/tex/context/base/node-tex.lua b/tex/context/base/node-tex.lua
new file mode 100644
index 000000000..563e6a397
--- /dev/null
+++ b/tex/context/base/node-tex.lua
@@ -0,0 +1,54 @@
+if not modules then modules = { } end modules ['node-tex'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+
+kernel = kernel or { }
+
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+local hyphenate, ligaturing, kerning = lang.hyphenate, node.ligaturing, node.kerning
+
+function kernel.hyphenation(head,tail) -- lang.hyphenate returns done
+ if head == tail then
+ return head, tail, false
+ else
+ -- starttiming(kernel)
+ -- local done = hyphenate(head,tail)
+ -- stoptiming(kernel)
+ -- return head, tail, done
+ return head, tail, hyphenate(head,tail)
+ end
+end
+
+function kernel.ligaturing(head,tail) -- node.ligaturing returns head,tail,done
+ if head == tail then
+ return head, tail, false
+ else
+ -- starttiming(kernel)
+ -- local head, tail, done = ligaturing(head,tail)
+ -- stoptiming(kernel)
+ -- return head, tail, done
+ return ligaturing(head,tail)
+ end
+end
+
+function kernel.kerning(head,tail) -- node.kerning returns head,tail,done
+ if head == tail then
+ return head, tail, false
+ else
+ -- starttiming(kernel)
+ -- local head, tail, done = kerning(head,tail)
+ -- stoptiming(kernel)
+ -- return head, tail, done
+ return kerning(head,tail)
+ end
+end
+
+callback.register('hyphenate' , false)
+callback.register('ligaturing', false)
+callback.register('kerning' , false)
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua
new file mode 100644
index 000000000..ef13499f9
--- /dev/null
+++ b/tex/context/base/node-tra.lua
@@ -0,0 +1,399 @@
+if not modules then modules = { } end modules ['node-tra'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>This is rather experimental. We need more control and some of this
+might become a runtime module instead.</p>
+--ldx]]--
+
+local utf = unicode.utf8
+local format, match, concat, utfchar = string.format, string.match, table.concat, utf.char
+
+local ctxcatcodes = tex.ctxcatcodes
+
+fonts = fonts or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+
+nodes = nodes or { }
+nodes.tracers = nodes.tracers or { }
+nodes.tracers.characters = nodes.tracers.characters or { }
+nodes.tracers.steppers = nodes.tracers.steppers or { }
+
+local glyph = node.id('glyph')
+local disc = node.id('disc')
+local glue = node.id('glue')
+local kern = node.id('kern')
+local whatsit = node.id('whatsit')
+
+local copy_node_list = node.copy_list
+local hpack_node_list = node.hpack
+local free_node_list = node.flush_list
+local first_character = node.first_character
+local node_type = node.type
+local traverse_nodes = node.traverse
+
+local texsprint = tex.sprint
+local fontdata = fonts.ids
+
+function nodes.tracers.characters.collect(head,list,tag,n)
+ n = n or 0
+ local ok, fn = false, nil
+ while head do
+ local id = head.id
+ if id == glyph then
+ local f = head.font
+ if f ~= fn then
+ ok, fn = false, f
+ end
+ local c = head.char
+ local i = fontdata[f].indices[c] or 0
+ if not ok then
+ ok = true
+ n = n + 1
+ list[n] = list[n] or { }
+ list[n][tag] = { }
+ end
+ local l = list[n][tag]
+ l[#l+1] = { c, f, i }
+ elseif id == disc then
+ -- skip
+ else
+ ok = false
+ end
+ head = head.next
+ end
+end
+
+function nodes.tracers.characters.equal(ta, tb)
+ if #ta ~= #tb then
+ return false
+ else
+ for i=1,#ta do
+ local a, b = ta[i], tb[i]
+ if a[1] ~= b[1] or a[2] ~= b[2] or a[3] ~= b[3] then
+ return false
+ end
+ end
+ end
+ return true
+end
+
+function nodes.tracers.characters.string(t)
+ local tt = { }
+ for i=1,#t do
+ tt[i] = utfchar(t[i][1])
+ end
+ return concat(tt,"")
+end
+
+function nodes.tracers.characters.unicodes(t,decimal)
+ local tt = { }
+ for i=1,#t do
+ local n = t[i][1]
+ if n == 0 then
+ tt[i] = "-"
+ elseif decimal then
+ tt[i] = n
+ else
+ tt[i] = format("U+%04X",n)
+ end
+ end
+ return concat(tt," ")
+end
+
+function nodes.tracers.characters.indices(t,decimal)
+ local tt = { }
+ for i=1,#t do
+ local n = t[i][3]
+ if n == 0 then
+ tt[i] = "-"
+ elseif decimal then
+ tt[i] = n
+ else
+ tt[i] = format("U+%04X",n)
+ end
+ end
+ return concat(tt," ")
+end
+
+function nodes.tracers.characters.start()
+ local npc = nodes.process_characters
+ local list = { }
+ function nodes.process_characters(head)
+ local n = #list
+ nodes.tracers.characters.collect(head,list,'before',n)
+ local h, d = npc(head)
+ nodes.tracers.characters.collect(head,list,'after',n)
+ if #list > n then
+ list[#list+1] = { }
+ end
+ return h, d
+ end
+ function nodes.tracers.characters.stop()
+ tracers.list['characters'] = list
+ lmx.set('title', 'ConTeXt Character Processing Information')
+ lmx.set('color-background-one', lmx.get('color-background-yellow'))
+ lmx.set('color-background-two', lmx.get('color-background-purple'))
+ lmx.show('context-characters.lmx')
+ lmx.restore()
+ nodes.process_characters = npc
+ tasks.restart("processors", "characters")
+ end
+ tasks.restart("processors", "characters")
+end
+
+local stack = { }
+
+function nodes.tracers.start(tag)
+ stack[#stack+1] = tag
+ local tracer = nodes.tracers[tag]
+ if tracer and tracer.start then
+ tracer.start()
+ end
+end
+function nodes.tracers.stop()
+ local tracer = stack[#stack]
+ if tracer and tracer.stop then
+ tracer.stop()
+ end
+ stack[#stack] = nil
+end
+
+-- experimental
+
+local collection, collecting, messages = { }, false, { }
+
+function nodes.tracers.steppers.start()
+ collecting = true
+end
+
+function nodes.tracers.steppers.stop()
+ collecting = false
+end
+
+function nodes.tracers.steppers.reset()
+ for i=1,#collection do
+ local c = collection[i]
+ if c then
+ free_node_list(c)
+ end
+ end
+ collection, messages = { }, { }
+end
+
+function nodes.tracers.steppers.nofsteps()
+ return tex.write(#collection)
+end
+
+function nodes.tracers.steppers.glyphs(n,i)
+ local c = collection[i]
+ if c then
+ tex.box[n] = hpack_node_list(copy_node_list(c))
+ end
+end
+
+function nodes.tracers.steppers.features()
+-- local f = first_character(collection[1])
+-- if f then -- something fishy with first_character
+ local f = collection[1]
+ while f do
+ if f.id == glyph then
+ local tfmdata, t = fontdata[f.font], { }
+ for feature, value in table.sortedpairs(tfmdata.shared.features) do
+ if feature == "number" or feature == "features" then
+ -- private
+ elseif type(value) == "boolean" then
+ if value then
+ t[#t+1] = format("%s=yes",feature)
+ else
+ -- skip
+ end
+ else
+ t[#t+1] = format("%s=%s",feature,value)
+ end
+ end
+ if #t > 0 then
+ texsprint(ctxcatcodes,concat(t,", "))
+ else
+ texsprint(ctxcatcodes,"no features")
+ end
+ return
+ end
+ f = f.next
+ end
+end
+
+function nodes.tracers.fontchar(font,char)
+ local n = nodes.glyph()
+ n.font, n.char, n.subtype = font, char, 256
+ node.write(n)
+end
+
+function nodes.tracers.steppers.codes(i,command)
+ local c = collection[i]
+ while c do
+ local id = c.id
+ if id == glyph then
+ if command then
+ texsprint(ctxcatcodes,format("%s{%s}{%s}",command,c.font,c.char))
+ else
+ texsprint(ctxcatcodes,format("[%s:U+%04X]",c.font,c.char))
+ end
+ elseif id == whatsit and (c.subtype == 6 or c.subtype == 7) then
+ texsprint(ctxcatcodes,format("[%s]",c.dir))
+ else
+ texsprint(ctxcatcodes,format("[%s]",node_type(id)))
+ end
+ c = c.next
+ end
+end
+
+function nodes.tracers.steppers.messages(i,command,split)
+ local list = messages[i] -- or { "no messages" }
+ if list then
+ for i=1,#list do
+ local l = list[i]
+ if split then
+ local a, b = match(l,"^(.-)%s*:%s*(.*)$")
+ texsprint(ctxcatcodes,format("%s{%s}{%s}",command,a or l,b or ""))
+ else
+ texsprint(ctxcatcodes,format("%s{%s}",command,l))
+ end
+ end
+ end
+end
+
+-- hooks into the node list processor (see otf)
+
+function nodes.tracers.steppers.check(head)
+ if collecting then
+ nodes.tracers.steppers.reset()
+ local n = copy_node_list(head)
+ nodes.inject_kerns(n,nil,true)
+ nodes.protect_glyphs(n) -- can be option
+ collection[1] = n
+ end
+end
+
+function nodes.tracers.steppers.register(head)
+ if collecting then
+ local nc = #collection+1
+ if messages[nc] then
+ local n = copy_node_list(head)
+ nodes.inject_kerns(n,nil,true)
+ nodes.protect_glyphs(n) -- can be option
+ collection[nc] = n
+ end
+ end
+end
+
+function nodes.tracers.steppers.message(str,...)
+ str = format(str,...)
+ if collecting then
+ local n = #collection + 1
+ local m = messages[n]
+ if not m then m = { } messages[n] = m end
+ m[#m+1] = str
+ end
+ return str -- saves an intermediate var in the caller
+end
+
+-- this will be reorganized:
+
+function nodes.show_list(head, message)
+ if message then
+ texio.write_nl(message)
+ end
+ for n in traverse(head) do
+ texio.write_nl(tostring(n))
+ end
+end
+
+function nodes.check_glyphs(head,message)
+ local t = { }
+ for g in traverse_id(glyph,head) do
+ t[#t+1] = format("U+%04X:%s",g.char,g.subtype)
+ end
+ if #t > 0 then
+ logs.report(message or "nodes","%s glyphs: %s",#t,concat(t," "))
+ end
+ return false
+end
+
+function nodes.tosequence(start,stop)
+ if start then
+ local t = { }
+ while start do
+ if start.id == glyph then
+ t[#t+1] = format("U+%04X:%s",start.char,utfchar(start.char))
+ else
+ t[#t+1] = match(tostring(start),": (%S+)")
+ end
+ if start == stop then
+ break
+ else
+ start = start.next
+ end
+ end
+ return concat(t," ")
+ else
+ return "<empty>"
+ end
+end
+
+function nodes.report(t,done)
+ if done then
+ if status.output_active then
+ texio.write(format("<++ %s>",count(t)))
+ else
+ texio.write(format("<+ %s>",count(t)))
+ end
+ else
+ if status.output_active then
+ texio.write(format("<-- %s>",count(t)))
+ else
+ texio.write(format("<- %s>",count(t)))
+ end
+ end
+end
+
+function nodes.pack_list(head)
+ local t = { }
+ for n in traverse(head) do
+ t[#t+1] = tostring(n)
+ end
+ return t
+end
+
+function nodes.ids_to_string(head)
+ local t, last_id, last_n = { }, nil, 0
+ for n in traverse_nodes(head) do
+ local id = n.id
+ if not last_id then
+ last_id, last_n = id, 1
+ elseif last_id == id then
+ last_n = last_n + 1
+ else
+ if last_n > 1 then
+ t[#t+1] = format("[%s*%s]",last_n,node_type(last_id) or "?")
+ else
+ t[#t+1] = format("[%s]",node_type(last_id) or "?")
+ end
+ last_id, last_n = id, 1
+ end
+ end
+ if not last_id then
+ t[#t+1] = "no nodes"
+ elseif last_n > 1 then
+ t[#t+1] = format("[%s*%s]",last_n,node_type(last_id) or "?")
+ else
+ t[#t+1] = format("[%s]",node_type(last_id) or "?")
+ end
+ return concat(t," ")
+end
diff --git a/tex/context/base/node-tsk.lua b/tex/context/base/node-tsk.lua
new file mode 100644
index 000000000..f20c544c4
--- /dev/null
+++ b/tex/context/base/node-tsk.lua
@@ -0,0 +1,113 @@
+if not modules then modules = { } end modules ['node-tsk'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local trace_tasks = false trackers.register("tasks", function(v) trace_tasks = v end)
+
+tasks = tasks or { }
+tasks.data = tasks.data or { }
+
+function tasks.new(name,list)
+ local tasklist = sequencer.reset()
+ tasks.data[name] = { list = tasklist, runner = false }
+ for l=1,#list do
+ sequencer.appendgroup(tasklist,list[l])
+ end
+end
+
+function tasks.restart(name,group)
+ local data = tasks.data[name]
+ if data then
+ data.runner = false
+ end
+end
+
+function tasks.appendaction(name,group,action,where,kind)
+ local data = tasks.data[name]
+ if data then
+ sequencer.appendaction(data.list,group,action,where,kind)
+ data.runner = false
+ end
+end
+
+function tasks.prependaction(name,group,action,where,kind)
+ local data = tasks.data[name]
+ if data then
+ sequencer.prependaction(data.list,group,action,where,kind)
+ data.runner = false
+ end
+end
+
+function tasks.removeaction(name,group,action)
+ local data = tasks.data[name]
+ if data then
+ sequencer.removeaction(data.list,group,action)
+ data.runner = false
+ end
+end
+
+function tasks.showactions(name,group,action,where,kind)
+ local data = tasks.data[name]
+ if data then
+ logs.report("nodes","task %s, list:\n%s",name,sequencer.nodeprocessor(data.list))
+ end
+end
+
+function tasks.actions(name)
+ local data = tasks.data[name]
+ if data then
+ return function(head,tail,...)
+ local runner = data.runner
+ if not runner then
+ if trace_tasks then
+ logs.report("nodes","creating task runner '%s'",name)
+ end
+ runner = sequencer.compile(data.list,sequencer.nodeprocessor)
+ data.runner = runner
+ end
+ return runner(head,tail,...)
+ end
+ else
+ return nil
+ end
+end
+
+tasks.new (
+ "processors",
+ {
+ "before", -- for users
+ "normalizers",
+ "characters",
+ "words",
+ "fonts",
+ "lists",
+ "after", -- for users
+ }
+)
+
+tasks.new (
+ "finalizers",
+ {
+ "before", -- for users
+ "normalizers",
+-- "characters",
+-- "finishers",
+ "fonts",
+-- "lists",
+ "after", -- for users
+ }
+)
+
+tasks.new (
+ "shipouts",
+ {
+ "before", -- for users
+ "normalizers",
+ "finishers",
+ "after", -- for users
+ }
+)
diff --git a/tex/context/base/node-tst.lua b/tex/context/base/node-tst.lua
new file mode 100644
index 000000000..e8b1146f8
--- /dev/null
+++ b/tex/context/base/node-tst.lua
@@ -0,0 +1,108 @@
+if not modules then modules = { } end modules ['node-tst'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+function nodes.leftskip(n)
+ while n do
+ local id = n.id
+ if id == glue then
+ if n.subtype == 8 then -- 7 in c/web source
+ return (n.spec and n.spec.width) or 0
+ else
+ return 0
+ end
+ elseif id == whatsit then
+ n = n.next
+ elseif id == hlist then
+ return n.width
+ else
+ break
+ end
+ end
+ return 0
+end
+
+function nodes.rightskip(n)
+ if n then
+ n = slide_nodes(n)
+ while n do
+ local id = n.id
+ if id == glue then
+ if n.subtype == 9 then -- 8 in the c/web source
+ return (n.spec and n.spec.width) or 0
+ else
+ return 0
+ end
+ elseif id == whatsit then
+ n = n.prev
+ else
+ break
+ end
+ end
+ end
+ return false
+end
+
+function nodes.somespace(n,all)
+ if n then
+ local id = n.id
+ if id == glue then
+ return (all or (n.spec.width ~= 0)) and glue
+ elseif id == kern then
+ return (all or (n.kern ~= 0)) and kern
+ elseif id == glyph then
+ local category = chardata[n.char].category
+ -- maybe more category checks are needed
+ return (category == "zs") and glyph
+ end
+ end
+ return false
+end
+
+function nodes.somepenalty(n,value)
+ if n then
+ local id = n.id
+ if id == penalty then
+ if value then
+ return n.penalty == value
+ else
+ return true
+ end
+ end
+ end
+ return false
+end
+
+function nodes.is_display_math(head)
+ local n = head.prev
+ while n do
+ local id = n.id
+ if id == penalty then
+ elseif id == glue then
+ if n.subtype == 6 then -- above_display_short_skip
+ return true
+ end
+ else
+ break
+ end
+ n = n.prev
+ end
+ n = head.next
+ while n do
+ local id = n.id
+ if id == penalty then
+ elseif id == glue then
+ if n.subtype == 7 then -- below_display_short_skip
+ return true
+ end
+ else
+ break
+ end
+ n = n.next
+ end
+ return false
+end
diff --git a/tex/context/base/norm-alo.tex b/tex/context/base/norm-alo.tex
new file mode 100644
index 000000000..d47f49037
--- /dev/null
+++ b/tex/context/base/norm-alo.tex
@@ -0,0 +1,36 @@
+%D \module
+%D [ file=norm-alo,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\ALEPH\ and \OMEGA,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 will become obsolete!
+
+% omega primitives
+
+\let\textdir = \textdir
+\let\pagedir = \pagedir
+\let\mathdir = \mathdir
+\let\pardir = \pardir
+\let\bodydir = \bodydir
+\let\leftghost = \leftghost
+\let\rightghost = \rightghost
+\let\localleftbox = \localleftbox
+\let\localrightbox = \localrightbox
+\let\localinterlinepenalty = \localinterlinepenalty
+\let\localbrokenpenalty = \localbrokenpenalty
+
+% aleph primitives
+
+\let\boxdir = \boxdir
+\let\pagebottomoffset = \pagebottomoffset
+\let\pagerightoffset = \pagerightoffset
+
+\endinput
diff --git a/tex/context/base/norm-ctx.tex b/tex/context/base/norm-ctx.tex
new file mode 100644
index 000000000..707705d89
--- /dev/null
+++ b/tex/context/base/norm-ctx.tex
@@ -0,0 +1,16 @@
+%D \module
+%D [ file=norm-ctx,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\ALEPH\ and \OMEGA,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 A few more might end up here (like the weird ones in syst-ini).
+
+\let\normalreqno = \normaleqno
diff --git a/tex/context/base/norm-etx.tex b/tex/context/base/norm-etx.tex
new file mode 100644
index 000000000..3edd8e7ef
--- /dev/null
+++ b/tex/context/base/norm-etx.tex
@@ -0,0 +1,79 @@
+%D \module
+%D [ file=norm-etx,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\ETEX,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% etex primitives
+
+\let \normalbotmarks = \botmarks
+\let \normalclubpenalties = \clubpenalties
+\let \normalcurrentgrouplevel = \currentgrouplevel
+\let \normalcurrentgrouptype = \currentgrouptype
+\let \normalcurrentifbranch = \currentifbranch
+\let \normalcurrentiflevel = \currentiflevel
+\let \normalcurrentiftype = \currentiftype
+\let \normaldetokenize = \detokenize
+\let \normaldimexpr = \dimexpr
+\let \normaldisplaywidowpenalties = \displaywidowpenalties
+\let \normaleTeXVersion = \eTeXVersion
+\let \normaleTeXminorversion = \eTeXminorversion
+\let \normaleTeXrevision = \eTeXrevision
+\let \normaleTeXversion = \eTeXversion
+\let \normaleveryeof = \everyeof
+\let \normalfirstmarks = \firstmarks
+\let \normalfontchardp = \fontchardp
+\let \normalfontcharht = \fontcharht
+\let \normalfontcharic = \fontcharic
+\let \normalfontcharwd = \fontcharwd
+\let \normalglueexpr = \glueexpr
+\let \normalglueshrink = \glueshrink
+\let \normalglueshrinkorder = \glueshrinkorder
+\let \normalgluestretch = \gluestretch
+\let \normalgluestretchorder = \gluestretchorder
+\let \normalgluetomu = \gluetomu
+\let \normalifcsname = \ifcsname
+\let \normalifdefined = \ifdefined
+\let \normaliffontchar = \iffontchar
+\let \normalinteractionmode = \interactionmode
+\let \normalinterlinepenalties = \interlinepenalties
+\let \normallastlinefit = \lastlinefit
+\let \normallastnodetype = \lastnodetype
+\let \normalmarks = \marks
+\let \normalmuexpr = \muexpr
+\let \normalmutoglue = \mutoglue
+\let \normalnumexpr = \numexpr
+\let \normalpagediscards = \pagediscards
+\let \normalparshapedimen = \parshapedimen
+\let \normalparshapeindent = \parshapeindent
+\let \normalparshapelength = \parshapelength
+\let \normalpredisplaydirection = \predisplaydirection
+\let \normalprotected = \protected
+\let \normalreadline = \readline
+\let \normalsavinghyphcodes = \savinghyphcodes
+\let \normalsavingvdiscards = \savingvdiscards
+\let \normalscantokens = \scantokens
+\let \normalshowgroups = \showgroups
+\let \normalshowifs = \showifs
+\let \normalshowtokens = \showtokens
+\let \normalsplitbotmarks = \splitbotmarks
+\let \normalsplitdiscards = \splitdiscards
+\let \normalsplitfirstmarks = \splitfirstmarks
+\let \normaltopmarks = \topmarks
+\let \normaltracingassigns = \tracingassigns
+\let \normaltracinggroups = \tracinggroups
+\let \normaltracingifs = \tracingifs
+\let \normaltracingnesting = \tracingnesting
+\let \normaltracingscantokens = \tracingscantokens
+\let \normalunexpanded = \unexpanded
+\let \normalunless = \unless
+\let \normalwidowpenalties = \widowpenalties
+
+\endinput
diff --git a/tex/context/base/norm-ltx.tex b/tex/context/base/norm-ltx.tex
new file mode 100644
index 000000000..c83a49b90
--- /dev/null
+++ b/tex/context/base/norm-ltx.tex
@@ -0,0 +1,177 @@
+%D \module
+%D [ file=norm-ltx,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\LUATEX,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 will become obsolete!
+
+% luatex primitives
+
+\let \normalUdelcode = \Udelcode
+\let \normalUdelcodenum = \Udelcodenum
+\let \normalUdelimiter = \Udelimiter
+\let \normalUmathaccent = \Umathaccent
+\let \normalUmathaccents = \Umathaccents
+\let \normalUmathaxis = \Umathaxis
+\let \normalUmathbinbinspacing = \Umathbinbinspacing
+\let \normalUmathbinclosespacing = \Umathbinclosespacing
+\let \normalUmathbininnerspacing = \Umathbininnerspacing
+\let \normalUmathbinopenspacing = \Umathbinopenspacing
+\let \normalUmathbinopspacing = \Umathbinopspacing
+\let \normalUmathbinordspacing = \Umathbinordspacing
+\let \normalUmathbinpunctspacing = \Umathbinpunctspacing
+\let \normalUmathbinrelspacing = \Umathbinrelspacing
+\let \normalUmathbotaccent = \Umathbotaccent
+\let \normalUmathchar = \Umathchar
+\let \normalUmathchardef = \Umathchardef
+\let \normalUmathcharnum = \Umathcharnum
+\let \normalUmathclosebinspacing = \Umathclosebinspacing
+\let \normalUmathcloseclosespacing = \Umathcloseclosespacing
+\let \normalUmathcloseinnerspacing = \Umathcloseinnerspacing
+\let \normalUmathcloseopenspacing = \Umathcloseopenspacing
+\let \normalUmathcloseopspacing = \Umathcloseopspacing
+\let \normalUmathcloseordspacing = \Umathcloseordspacing
+\let \normalUmathclosepunctspacing = \Umathclosepunctspacing
+\let \normalUmathcloserelspacing = \Umathcloserelspacing
+\let \normalUmathcode = \Umathcode
+\let \normalUmathcodenum = \Umathcodenum
+\let \normalUmathconnectoroverlapmin = \Umathconnectoroverlapmin
+\let \normalUmathfractiondelsize = \Umathfractiondelsize
+\let \normalUmathfractiondenomdown = \Umathfractiondenomdown
+\let \normalUmathfractiondenomvgap = \Umathfractiondenomvgap
+\let \normalUmathfractionnumup = \Umathfractionnumup
+\let \normalUmathfractionnumvgap = \Umathfractionnumvgap
+\let \normalUmathfractionrule = \Umathfractionrule
+\let \normalUmathinnerbinspacing = \Umathinnerbinspacing
+\let \normalUmathinnerclosespacing = \Umathinnerclosespacing
+\let \normalUmathinnerinnerspacing = \Umathinnerinnerspacing
+\let \normalUmathinneropenspacing = \Umathinneropenspacing
+\let \normalUmathinneropspacing = \Umathinneropspacing
+\let \normalUmathinnerordspacing = \Umathinnerordspacing
+\let \normalUmathinnerpunctspacing = \Umathinnerpunctspacing
+\let \normalUmathinnerrelspacing = \Umathinnerrelspacing
+\let \normalUmathlimitabovebgap = \Umathlimitabovebgap
+\let \normalUmathlimitabovekern = \Umathlimitabovekern
+\let \normalUmathlimitabovevgap = \Umathlimitabovevgap
+\let \normalUmathlimitdownbgap = \Umathlimitdownbgap
+\let \normalUmathlimitdownkern = \Umathlimitdownkern
+\let \normalUmathlimitdownvgap = \Umathlimitdownvgap
+\let \normalUmathopbinspacing = \Umathopbinspacing
+\let \normalUmathopclosespacing = \Umathopclosespacing
+\let \normalUmathopenbinspacing = \Umathopenbinspacing
+\let \normalUmathopenclosespacing = \Umathopenclosespacing
+\let \normalUmathopeninnerspacing = \Umathopeninnerspacing
+\let \normalUmathopenopenspacing = \Umathopenopenspacing
+\let \normalUmathopenopspacing = \Umathopenopspacing
+\let \normalUmathopenordspacing = \Umathopenordspacing
+\let \normalUmathopenpunctspacing = \Umathopenpunctspacing
+\let \normalUmathopenrelspacing = \Umathopenrelspacing
+\let \normalUmathoperatorsize = \Umathoperatorsize
+\let \normalUmathopinnerspacing = \Umathopinnerspacing
+\let \normalUmathopopenspacing = \Umathopopenspacing
+\let \normalUmathopopspacing = \Umathopopspacing
+\let \normalUmathopordspacing = \Umathopordspacing
+\let \normalUmathoppunctspacing = \Umathoppunctspacing
+\let \normalUmathoprelspacing = \Umathoprelspacing
+\let \normalUmathordbinspacing = \Umathordbinspacing
+\let \normalUmathordclosespacing = \Umathordclosespacing
+\let \normalUmathordinnerspacing = \Umathordinnerspacing
+\let \normalUmathordopenspacing = \Umathordopenspacing
+\let \normalUmathordopspacing = \Umathordopspacing
+\let \normalUmathordordspacing = \Umathordordspacing
+\let \normalUmathordpunctspacing = \Umathordpunctspacing
+\let \normalUmathordrelspacing = \Umathordrelspacing
+\let \normalUmathoverbarkern = \Umathoverbarkern
+\let \normalUmathoverbarrule = \Umathoverbarrule
+\let \normalUmathoverbarvgap = \Umathoverbarvgap
+\let \normalUmathoverdelimiterbgap = \Umathoverdelimiterbgap
+\let \normalUmathoverdelimitervgap = \Umathoverdelimitervgap
+\let \normalUmathpunctbinspacing = \Umathpunctbinspacing
+\let \normalUmathpunctclosespacing = \Umathpunctclosespacing
+\let \normalUmathpunctinnerspacing = \Umathpunctinnerspacing
+\let \normalUmathpunctopenspacing = \Umathpunctopenspacing
+\let \normalUmathpunctopspacing = \Umathpunctopspacing
+\let \normalUmathpunctordspacing = \Umathpunctordspacing
+\let \normalUmathpunctpunctspacing = \Umathpunctpunctspacing
+\let \normalUmathpunctrelspacing = \Umathpunctrelspacing
+\let \normalUmathquad = \Umathquad
+\let \normalUmathradicaldegreeafter = \Umathradicaldegreeafter
+\let \normalUmathradicaldegreebefore = \Umathradicaldegreebefore
+\let \normalUmathradicaldegreeraise = \Umathradicaldegreeraise
+\let \normalUmathradicalkern = \Umathradicalkern
+\let \normalUmathradicalrule = \Umathradicalrule
+\let \normalUmathradicalvgap = \Umathradicalvgap
+\let \normalUmathrelbinspacing = \Umathrelbinspacing
+\let \normalUmathrelclosespacing = \Umathrelclosespacing
+\let \normalUmathrelinnerspacing = \Umathrelinnerspacing
+\let \normalUmathrelopenspacing = \Umathrelopenspacing
+\let \normalUmathrelopspacing = \Umathrelopspacing
+\let \normalUmathrelordspacing = \Umathrelordspacing
+\let \normalUmathrelpunctspacing = \Umathrelpunctspacing
+\let \normalUmathrelrelspacing = \Umathrelrelspacing
+\let \normalUmathspaceafterscript = \Umathspaceafterscript
+\let \normalUmathstackdenomdown = \Umathstackdenomdown
+\let \normalUmathstacknumup = \Umathstacknumup
+\let \normalUmathstackvgap = \Umathstackvgap
+\let \normalUmathsubshiftdown = \Umathsubshiftdown
+\let \normalUmathsubshiftdrop = \Umathsubshiftdrop
+\let \normalUmathsubsupshiftdown = \Umathsubsupshiftdown
+\let \normalUmathsubsupvgap = \Umathsubsupvgap
+\let \normalUmathsubtopmax = \Umathsubtopmax
+\let \normalUmathsupbottommin = \Umathsupbottommin
+\let \normalUmathsupshiftdrop = \Umathsupshiftdrop
+\let \normalUmathsupshiftup = \Umathsupshiftup
+\let \normalUmathsupsubbottommax = \Umathsupsubbottommax
+\let \normalUmathunderbarkern = \Umathunderbarkern
+\let \normalUmathunderbarrule = \Umathunderbarrule
+\let \normalUmathunderbarvgap = \Umathunderbarvgap
+\let \normalUmathunderdelimiterbgap = \Umathunderdelimiterbgap
+\let \normalUmathunderdelimitervgap = \Umathunderdelimitervgap
+\let \normalUoverdelimiter = \Uoverdelimiter
+\let \normalUradical = \Uradical
+\let \normalUroot = \Uroot
+\let \normalUunderdelimiter = \Uunderdelimiter
+\let \normalattribute = \attribute
+\let \normalattributedef = \attributedef
+\let \normalcatcodetable = \catcodetable
+\let \normalclearmarks = \clearmarks
+\let \normalcrampeddisplaystyle = \crampeddisplaystyle
+\let \normalcrampedscriptscriptstyle = \crampedscriptscriptstyle
+\let \normalcrampedscriptstyle = \crampedscriptstyle
+\let \normalcrampedtextstyle = \crampedtextstyle
+\let \normalformatname = \formatname
+\let \normalifabsdim = \ifabsdim
+\let \normalifabsnum = \ifabsnum
+\let \normalifprimitive = \ifprimitive
+\let \normalinitcatcodetable = \initcatcodetable
+\let \normallatelua = \latelua
+\let \normalluaescapestring = \luaescapestring
+\let \normalluastartup = \luastartup
+\let \normalluatexdatestamp = \luatexdatestamp
+\let \normalluatexrevision = \luatexrevision
+\let \normalluatexversion = \luatexversion
+\let \normalnokerns = \nokerns
+\let \normalnoligs = \noligs
+\let \normalpageleftoffset = \pageleftoffset
+\let \normalpagetopoffset = \pagetopoffset
+\let \normalpostexhyphenchar = \postexhyphenchar
+\let \normalposthyphenchar = \posthyphenchar
+\let \normalpreexhyphenchar = \preexhyphenchar
+\let \normalprehyphenchar = \prehyphenchar
+\let \normalprimitive = \primitive
+\let \normalsavecatcodetable = \savecatcodetable
+\let \normalscantextokens = \scantextokens
+\let \normalsuppressfontnotfounderror = \suppressfontnotfounderror
+\let \normalsuppressifcsnameerror = \suppressifcsnameerror
+\let \normalsuppresslongerror = \suppresslongerror
+\let \normalsynctex = \synctex
+
+\endinput
diff --git a/tex/context/base/norm-ptx.tex b/tex/context/base/norm-ptx.tex
new file mode 100644
index 000000000..992fd38ff
--- /dev/null
+++ b/tex/context/base/norm-ptx.tex
@@ -0,0 +1,130 @@
+%D \module
+%D [ file=norm-ptx,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\PDFTEX,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\let \normalefcode = \efcode
+\let \normalexpanded = \expanded
+\let \normalifincsname = \ifincsname
+\let \normalifpdfabsdim = \ifpdfabsdim
+\let \normalifpdfabsnum = \ifpdfabsnum
+\let \normalifpdfprimitive = \ifpdfprimitive
+\let \normalleftmarginkern = \leftmarginkern
+\let \normalletterspacefont = \letterspacefont
+\let \normallpcode = \lpcode
+\let \normalpdfadjustspacing = \pdfadjustspacing
+\let \normalpdfannot = \pdfannot
+\let \normalpdfcatalog = \pdfcatalog
+\let \normalpdfcolorstack = \pdfcolorstack
+\let \normalpdfcolorstackinit = \pdfcolorstackinit
+\let \normalpdfcompresslevel = \pdfcompresslevel
+\let \normalpdfcopyfont = \pdfcopyfont
+\let \normalpdfcreationdate = \pdfcreationdate
+\let \normalpdfdecimaldigits = \pdfdecimaldigits
+\let \normalpdfdest = \pdfdest
+\let \normalpdfdestmargin = \pdfdestmargin
+\let \normalpdfdraftmode = \pdfdraftmode
+\let \normalpdfeachlinedepth = \pdfeachlinedepth
+\let \normalpdfeachlineheight = \pdfeachlineheight
+\let \normalpdfendlink = \pdfendlink
+\let \normalpdfendthread = \pdfendthread
+\let \normalpdffirstlineheight = \pdffirstlineheight
+\let \normalpdffontattr = \pdffontattr
+\let \normalpdffontexpand = \pdffontexpand
+\let \normalpdffontname = \pdffontname
+\let \normalpdffontobjnum = \pdffontobjnum
+\let \normalpdffontsize = \pdffontsize
+\let \normalpdfforcepagebox = \pdfforcepagebox
+\let \normalpdfgamma = \pdfgamma
+\let \normalpdfgentounicode = \pdfgentounicode
+\let \normalpdfglyphtounicode = \pdfglyphtounicode
+\let \normalpdfhorigin = \pdfhorigin
+\let \normalpdfignoreddimen = \pdfignoreddimen
+\let \normalpdfimageapplygamma = \pdfimageapplygamma
+\let \normalpdfimagegamma = \pdfimagegamma
+\let \normalpdfimagehicolor = \pdfimagehicolor
+\let \normalpdfimageresolution = \pdfimageresolution
+\let \normalpdfincludechars = \pdfincludechars
+\let \normalpdfinclusioncopyfonts = \pdfinclusioncopyfonts
+\let \normalpdfinclusionerrorlevel = \pdfinclusionerrorlevel
+\let \normalpdfinfo = \pdfinfo
+\let \normalpdfinsertht = \pdfinsertht
+\let \normalpdflastannot = \pdflastannot
+\let \normalpdflastlinedepth = \pdflastlinedepth
+\let \normalpdflastlink = \pdflastlink
+\let \normalpdflastobj = \pdflastobj
+\let \normalpdflastxform = \pdflastxform
+\let \normalpdflastximage = \pdflastximage
+\let \normalpdflastximagecolordepth = \pdflastximagecolordepth
+\let \normalpdflastximagepages = \pdflastximagepages
+\let \normalpdflastxpos = \pdflastxpos
+\let \normalpdflastypos = \pdflastypos
+\let \normalpdflinkmargin = \pdflinkmargin
+\let \normalpdfliteral = \pdfliteral
+\let \normalpdfmapfile = \pdfmapfile
+\let \normalpdfmapline = \pdfmapline
+\let \normalpdfminorversion = \pdfminorversion
+\let \normalpdfmovechars = \pdfmovechars
+\let \normalpdfnames = \pdfnames
+\let \normalpdfnoligatures = \pdfnoligatures
+\let \normalpdfnormaldeviate = \pdfnormaldeviate
+\let \normalpdfobj = \pdfobj
+\let \normalpdfobjcompresslevel = \pdfobjcompresslevel
+\let \normalpdfoptionalwaysusepdfpagebox = \pdfoptionalwaysusepdfpagebox
+\let \normalpdfoptionpdfinclusionerrorlevel = \pdfoptionpdfinclusionerrorlevel
+\let \normalpdfoptionpdfminorversion = \pdfoptionpdfminorversion
+\let \normalpdfoutline = \pdfoutline
+\let \normalpdfoutput = \pdfoutput
+\let \normalpdfpageattr = \pdfpageattr
+\let \normalpdfpagebox = \pdfpagebox
+\let \normalpdfpageheight = \pdfpageheight
+\let \normalpdfpageref = \pdfpageref
+\let \normalpdfpageresources = \pdfpageresources
+\let \normalpdfpagesattr = \pdfpagesattr
+\let \normalpdfpagewidth = \pdfpagewidth
+\let \normalpdfpkmode = \pdfpkmode
+\let \normalpdfpkresolution = \pdfpkresolution
+\let \normalpdfprimitive = \pdfprimitive
+\let \normalpdfprotrudechars = \pdfprotrudechars
+\let \normalpdfpxdimen = \pdfpxdimen
+\let \normalpdfrandomseed = \pdfrandomseed
+\let \normalpdfrefobj = \pdfrefobj
+\let \normalpdfrefxform = \pdfrefxform
+\let \normalpdfrefximage = \pdfrefximage
+\let \normalpdfreplacefont = \pdfreplacefont
+\let \normalpdfrestore = \pdfrestore
+\let \normalpdfretval = \pdfretval
+\let \normalpdfsave = \pdfsave
+\let \normalpdfsavepos = \pdfsavepos
+\let \normalpdfsetmatrix = \pdfsetmatrix
+\let \normalpdfsetrandomseed = \pdfsetrandomseed
+\let \normalpdfstartlink = \pdfstartlink
+\let \normalpdfstartthread = \pdfstartthread
+\let \normalpdftexbanner = \pdftexbanner
+\let \normalpdftexrevision = \pdftexrevision
+\let \normalpdftexversion = \pdftexversion
+\let \normalpdfthread = \pdfthread
+\let \normalpdfthreadmargin = \pdfthreadmargin
+\let \normalpdftracingfonts = \pdftracingfonts
+\let \normalpdftrailer = \pdftrailer
+\let \normalpdfuniformdeviate = \pdfuniformdeviate
+\let \normalpdfuniqueresname = \pdfuniqueresname
+\let \normalpdfvorigin = \pdfvorigin
+\let \normalpdfxform = \pdfxform
+\let \normalpdfxformname = \pdfxformname
+\let \normalpdfximage = \pdfximage
+\let \normalpdfximagebbox = \pdfximagebbox
+\let \normalquitvmode = \quitvmode
+\let \normalrightmarginkern = \rightmarginkern
+\let \normalrpcode = \rpcode
+\let \normaltagcode = \tagcode
+
+\endinput
diff --git a/tex/context/base/norm-tex.tex b/tex/context/base/norm-tex.tex
new file mode 100644
index 000000000..61f9740ef
--- /dev/null
+++ b/tex/context/base/norm-tex.tex
@@ -0,0 +1,351 @@
+%D \module
+%D [ file=norm-etx,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\TEX,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 Since \LUATEX\ can generate these lists internally it started
+%D to make sense to cleanup this \type {\normalstuff} for \MKII\ as
+%D well. The tables are generated with a \LUA\ script.
+
+% tex primitives
+
+% Beware, we already redefined \dump, \outer and \everyjob !
+
+% \normal = \
+% \normal- = \-
+% \normal/ = \/
+\let \normalabove = \above
+\let \normalabovedisplayshortskip = \abovedisplayshortskip
+\let \normalabovedisplayskip = \abovedisplayskip
+\let \normalabovewithdelims = \abovewithdelims
+\let \normalaccent = \accent
+\let \normaladjdemerits = \adjdemerits
+\let \normaladvance = \advance
+\let \normalafterassignment = \afterassignment
+\let \normalaftergroup = \aftergroup
+\let \normalatop = \atop
+\let \normalatopwithdelims = \atopwithdelims
+\let \normalbadness = \badness
+\let \normalbaselineskip = \baselineskip
+\let \normalbatchmode = \batchmode
+\let \normalbegingroup = \begingroup
+\let \normalbelowdisplayshortskip = \belowdisplayshortskip
+\let \normalbelowdisplayskip = \belowdisplayskip
+\let \normalbinoppenalty = \binoppenalty
+\let \normalbotmark = \botmark
+\let \normalbox = \box
+\let \normalboxmaxdepth = \boxmaxdepth
+\let \normalbrokenpenalty = \brokenpenalty
+\let \normalcatcode = \catcode
+\let \normalchar = \char
+\let \normalchardef = \chardef
+\let \normalcleaders = \cleaders
+\let \normalclosein = \closein
+\let \normalcloseout = \closeout
+\let \normalclubpenalty = \clubpenalty
+\let \normalcopy = \copy
+\let \normalcount = \count
+\let \normalcountdef = \countdef
+\let \normalcr = \cr
+\let \normalcrcr = \crcr
+\let \normalcsname = \csname
+\let \normalday = \day
+\let \normaldeadcycles = \deadcycles
+\let \normaldef = \def
+\let \normaldefaulthyphenchar = \defaulthyphenchar
+\let \normaldefaultskewchar = \defaultskewchar
+\let \normaldelcode = \delcode
+\let \normaldelimiter = \delimiter
+\let \normaldelimiterfactor = \delimiterfactor
+\let \normaldelimitershortfall = \delimitershortfall
+\let \normaldimen = \dimen
+\let \normaldimendef = \dimendef
+\let \normaldirectlua = \directlua
+\let \normaldiscretionary = \discretionary
+\let \normaldisplayindent = \displayindent
+\let \normaldisplaylimits = \displaylimits
+\let \normaldisplaystyle = \displaystyle
+\let \normaldisplaywidowpenalty = \displaywidowpenalty
+\let \normaldisplaywidth = \displaywidth
+\let \normaldivide = \divide
+\let \normaldoublehyphendemerits = \doublehyphendemerits
+\let \normaldp = \dp
+% \normaldump = \dump
+\let \normaledef = \edef
+\let \normalelse = \else
+\let \normalemergencystretch = \emergencystretch
+\let \normalend = \end
+\let \normalendcsname = \endcsname
+\let \normalendgroup = \endgroup
+\let \normalendinput = \endinput
+\let \normalendlinechar = \endlinechar
+\let \normaleqno = \eqno
+\let \normalerrhelp = \errhelp
+\let \normalerrmessage = \errmessage
+\let \normalerrorcontextlines = \errorcontextlines
+\let \normalerrorstopmode = \errorstopmode
+\let \normalescapechar = \escapechar
+\let \normaleverycr = \everycr
+\let \normaleverydisplay = \everydisplay
+\let \normaleveryhbox = \everyhbox
+% \normaleveryjob = \everyjob
+\let \normaleverymath = \everymath
+\let \normaleverypar = \everypar
+\let \normaleveryvbox = \everyvbox
+\let \normalexhyphenchar = \exhyphenchar
+\let \normalexhyphenpenalty = \exhyphenpenalty
+\let \normalexpandafter = \expandafter
+\let \normalfam = \fam
+\let \normalfi = \fi
+\let \normalfinalhyphendemerits = \finalhyphendemerits
+\let \normalfirstmark = \firstmark
+\let \normalfloatingpenalty = \floatingpenalty
+\let \normalfont = \font
+\let \normalfontdimen = \fontdimen
+\let \normalfontname = \fontname
+\let \normalfuturelet = \futurelet
+\let \normalgdef = \gdef
+\let \normalglobal = \global
+\let \normalglobaldefs = \globaldefs
+\let \normalhalign = \halign
+\let \normalhangafter = \hangafter
+\let \normalhangindent = \hangindent
+\let \normalhbadness = \hbadness
+\let \normalhbox = \hbox
+\let \normalhfil = \hfil
+\let \normalhfill = \hfill
+\let \normalhfilneg = \hfilneg
+\let \normalhfuzz = \hfuzz
+\let \normalhoffset = \hoffset
+\let \normalholdinginserts = \holdinginserts
+\let \normalhrule = \hrule
+\let \normalhsize = \hsize
+\let \normalhskip = \hskip
+\let \normalhss = \hss
+\let \normalht = \ht
+\let \normalhyphenation = \hyphenation
+\let \normalhyphenchar = \hyphenchar
+\let \normalhyphenpenalty = \hyphenpenalty
+\let \normalif = \if
+\let \normalifcase = \ifcase
+\let \normalifcat = \ifcat
+\let \normalifdim = \ifdim
+\let \normalifeof = \ifeof
+\let \normaliffalse = \iffalse
+\let \normalifhbox = \ifhbox
+\let \normalifhmode = \ifhmode
+\let \normalifinner = \ifinner
+\let \normalifmmode = \ifmmode
+\let \normalifnum = \ifnum
+\let \normalifodd = \ifodd
+\let \normaliftrue = \iftrue
+\let \normalifvbox = \ifvbox
+\let \normalifvmode = \ifvmode
+\let \normalifvoid = \ifvoid
+\let \normalifx = \ifx
+\let \normalignorespaces = \ignorespaces
+\let \normalimmediate = \immediate
+\let \normalindent = \indent
+% \normalinput = \input
+\let \normalinputlineno = \inputlineno
+\let \normalinsert = \insert
+\let \normalinsertpenalties = \insertpenalties
+\let \normalinterlinepenalty = \interlinepenalty
+\let \normaljobname = \jobname
+\let \normalkern = \kern
+\let \normallanguage = \language
+\let \normallastbox = \lastbox
+\let \normallastkern = \lastkern
+\let \normallastpenalty = \lastpenalty
+\let \normallastskip = \lastskip
+\let \normallccode = \lccode
+\let \normalleaders = \leaders
+\let \normalleft = \left
+\let \normallefthyphenmin = \lefthyphenmin
+\let \normalleftskip = \leftskip
+\let \normalleqno = \leqno
+\let \normallet = \let
+\let \normallimits = \limits
+\let \normallinepenalty = \linepenalty
+\let \normallineskip = \lineskip
+\let \normallineskiplimit = \lineskiplimit
+\let \normallong = \long
+\let \normallooseness = \looseness
+\let \normallower = \lower
+\let \normallowercase = \lowercase
+\let \normalmag = \mag
+\let \normalmark = \mark
+\let \normalmathaccent = \mathaccent
+\let \normalmathbin = \mathbin
+\let \normalmathchar = \mathchar
+\let \normalmathchardef = \mathchardef
+\let \normalmathchoice = \mathchoice
+\let \normalmathclose = \mathclose
+\let \normalmathcode = \mathcode
+\let \normalmathinner = \mathinner
+\let \normalmathop = \mathop
+\let \normalmathopen = \mathopen
+\let \normalmathord = \mathord
+\let \normalmathpunct = \mathpunct
+\let \normalmathrel = \mathrel
+\let \normalmathsurround = \mathsurround
+\let \normalmaxdeadcycles = \maxdeadcycles
+\let \normalmaxdepth = \maxdepth
+\let \normalmeaning = \meaning
+\let \normalmedmuskip = \medmuskip
+\let \normalmessage = \message
+\let \normalmiddle = \middle
+\let \normalmkern = \mkern
+\let \normalmonth = \month
+\let \normalmoveleft = \moveleft
+\let \normalmoveright = \moveright
+\let \normalmskip = \mskip
+\let \normalmultiply = \multiply
+\let \normalmuskip = \muskip
+\let \normalmuskipdef = \muskipdef
+\let \normalnewlinechar = \newlinechar
+\let \normalnoalign = \noalign
+\let \normalnoboundary = \noboundary
+\let \normalnoexpand = \noexpand
+\let \normalnoindent = \noindent
+\let \normalnolimits = \nolimits
+\let \normalnonscript = \nonscript
+\let \normalnonstopmode = \nonstopmode
+\let \normalnulldelimiterspace = \nulldelimiterspace
+\let \normalnullfont = \nullfont
+\let \normalnumber = \number
+\let \normalomit = \omit
+\let \normalopenin = \openin
+\let \normalopenout = \openout
+\let \normalor = \or
+% \normalouter = \outer
+\let \normaloutput = \output
+\let \normaloutputpenalty = \outputpenalty
+\let \normalover = \over
+\let \normaloverfullrule = \overfullrule
+\let \normaloverline = \overline
+\let \normaloverwithdelims = \overwithdelims
+\let \normalpagedepth = \pagedepth
+\let \normalpagefilllstretch = \pagefilllstretch
+\let \normalpagefillstretch = \pagefillstretch
+\let \normalpagefilstretch = \pagefilstretch
+\let \normalpagegoal = \pagegoal
+\let \normalpageshrink = \pageshrink
+\let \normalpagestretch = \pagestretch
+\let \normalpagetotal = \pagetotal
+\let \normalpar = \par
+\let \normalparfillskip = \parfillskip
+\let \normalparindent = \parindent
+\let \normalparshape = \parshape
+\let \normalparskip = \parskip
+\let \normalpatterns = \patterns
+\let \normalpausing = \pausing
+\let \normalpenalty = \penalty
+\let \normalpostdisplaypenalty = \postdisplaypenalty
+\let \normalpredisplaypenalty = \predisplaypenalty
+\let \normalpredisplaysize = \predisplaysize
+\let \normalpretolerance = \pretolerance
+\let \normalprevdepth = \prevdepth
+\let \normalprevgraf = \prevgraf
+\let \normalradical = \radical
+\let \normalraise = \raise
+\let \normalread = \read
+\let \normalrelax = \relax
+\let \normalrelpenalty = \relpenalty
+\let \normalright = \right
+\let \normalrighthyphenmin = \righthyphenmin
+\let \normalrightskip = \rightskip
+\let \normalromannumeral = \romannumeral
+\let \normalscriptfont = \scriptfont
+\let \normalscriptscriptfont = \scriptscriptfont
+\let \normalscriptscriptstyle = \scriptscriptstyle
+\let \normalscriptspace = \scriptspace
+\let \normalscriptstyle = \scriptstyle
+\let \normalscrollmode = \scrollmode
+\let \normalsetbox = \setbox
+\let \normalsetlanguage = \setlanguage
+\let \normalsfcode = \sfcode
+\let \normalshipout = \shipout
+\let \normalshow = \show
+\let \normalshowbox = \showbox
+\let \normalshowboxbreadth = \showboxbreadth
+\let \normalshowboxdepth = \showboxdepth
+\let \normalshowlists = \showlists
+\let \normalshowthe = \showthe
+\let \normalskewchar = \skewchar
+\let \normalskip = \skip
+\let \normalskipdef = \skipdef
+\let \normalspacefactor = \spacefactor
+\let \normalspaceskip = \spaceskip
+\let \normalspan = \span
+\let \normalspecial = \special
+\let \normalsplitbotmark = \splitbotmark
+\let \normalsplitfirstmark = \splitfirstmark
+\let \normalsplitmaxdepth = \splitmaxdepth
+\let \normalsplittopskip = \splittopskip
+\let \normalstring = \string
+\let \normaltabskip = \tabskip
+\let \normaltextfont = \textfont
+\let \normaltextstyle = \textstyle
+\let \normalthe = \the
+\let \normalthickmuskip = \thickmuskip
+\let \normalthinmuskip = \thinmuskip
+\let \normaltime = \time
+\let \normaltoks = \toks
+\let \normaltoksdef = \toksdef
+\let \normaltolerance = \tolerance
+\let \normaltopmark = \topmark
+\let \normaltopskip = \topskip
+\let \normaltracingcommands = \tracingcommands
+\let \normaltracinglostchars = \tracinglostchars
+\let \normaltracingmacros = \tracingmacros
+\let \normaltracingonline = \tracingonline
+\let \normaltracingoutput = \tracingoutput
+\let \normaltracingpages = \tracingpages
+\let \normaltracingparagraphs = \tracingparagraphs
+\let \normaltracingrestores = \tracingrestores
+\let \normaltracingstats = \tracingstats
+\let \normaluccode = \uccode
+\let \normaluchyph = \uchyph
+\let \normalunderline = \underline
+\let \normalunhbox = \unhbox
+\let \normalunhcopy = \unhcopy
+\let \normalunkern = \unkern
+\let \normalunpenalty = \unpenalty
+\let \normalunskip = \unskip
+\let \normalunvbox = \unvbox
+\let \normalunvcopy = \unvcopy
+\let \normaluppercase = \uppercase
+\let \normalvadjust = \vadjust
+\let \normalvalign = \valign
+\let \normalvbadness = \vbadness
+\let \normalvbox = \vbox
+\let \normalvcenter = \vcenter
+\let \normalvfil = \vfil
+\let \normalvfill = \vfill
+\let \normalvfilneg = \vfilneg
+\let \normalvfuzz = \vfuzz
+\let \normalvoffset = \voffset
+\let \normalvrule = \vrule
+\let \normalvsize = \vsize
+\let \normalvskip = \vskip
+\let \normalvsplit = \vsplit
+\let \normalvss = \vss
+\let \normalvtop = \vtop
+\let \normalwd = \wd
+\let \normalwidowpenalty = \widowpenalty
+\let \normalwrite = \write
+\let \normalxdef = \xdef
+\let \normalxleaders = \xleaders
+\let \normalxspaceskip = \xspaceskip
+\let \normalyear = \year
+
+\endinput
diff --git a/tex/context/base/sort-def.mkiv b/tex/context/base/norm-xtx.tex
index 8cc92a02e..3da944656 100644
--- a/tex/context/base/sort-def.mkiv
+++ b/tex/context/base/norm-xtx.tex
@@ -1,16 +1,18 @@
%D \module
-%D [ file=sort-def,
-%D version=2005.08.08,
-%D title=\CONTEXT\ Sort Macros,
-%D subtitle=Defaults,
+%D [ file=norm-xtx,
+%D version=2009.03.19,
+%D title=\CONTEXT\ Norm Macros,
+%D subtitle=\XETEX,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%D copyright=PRAGMA]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% nothing here
+% xetex primitives
+
+% nothing yet (also defined pdftex primitives)
\endinput
diff --git a/tex/context/base/page-app.tex b/tex/context/base/page-app.tex
index 6e477903c..005ea6dd4 100644
--- a/tex/context/base/page-app.tex
+++ b/tex/context/base/page-app.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-app, % from meta-fig
%D version=1998.01.15,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Independent page building,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Applications}
+\writestatus{loading}{ConTeXt Page Macros / Applications}
%D The fitting page code is moved from \type {meta-fig} to
%D here.
diff --git a/tex/context/base/page-bck.tex b/tex/context/base/page-bck.mkii
index 10123fec6..0b4ad779a 100644
--- a/tex/context/base/page-bck.tex
+++ b/tex/context/base/page-bck.mkii
@@ -11,43 +11,27 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Backgrounds}
+\writestatus{loading}{ConTeXt Page Macros / Backgrounds}
% \chardef\kindofpagetextareas=1 will isolate graphics from backgrounds
\unprotect
-\startmessages dutch library: layouts
- 8: achtergronden berekenen
-\stopmessages
+% messages moved
-\startmessages english library: layouts
- 8: calculating backgrounds
-\stopmessages
+% messages moved
-\startmessages german library: layouts
- 8: berechne Hintergrund
-\stopmessages
+% messages moved
-\startmessages czech library: layouts
- 8: pocita se pozadi
-\stopmessages
+% messages moved
-\startmessages italian library: layouts
- 8: calcolo dello sfondo
-\stopmessages
+% messages moved
-\startmessages norwegian library: layouts
- 8: beregner bakgrunn
-\stopmessages
+% messages moved
-\startmessages romanian library: layouts
- 8: se calculeaza fundalurile
-\stopmessages
+% messages moved
-\startmessages french library: layouts
- 8: calcul des arrières-plans
-\stopmessages
+% messages moved
%D \macros
%D {recalculatebackgrounds}
@@ -384,9 +368,7 @@
\processcommalist[#1]\docommand
\else\ifsecondargument
\global\somebackgroundtrue
- \doifcommonelse{#1}{\v!text,\v!hidden,%
- %\v!linkertekst,\v!rechtertekst,%
- \v!paper,\v!page,\v!leftpage,\v!rightpage}
+ \doifcommonelse{#1}{\v!text,\v!hidden,\v!paper,\v!page,\v!leftpage,\v!rightpage}
{\def\docommand##1{\getparameters[\??ma##1][#2]\checkbackground{##1}}%
\processcommalist[#1]\docommand}%
{\setupbackgrounds
@@ -409,8 +391,6 @@
\let\pagebackgroundoffset\!!zeropoint
\let\pagebackgrounddepth \!!zeropoint
-\appendtoks\global\newbackgroundfalse\to\everyjob
-
%D Each areas (currently there are $1+3+25+1=30$ of them)
%D has its own low level framed object associated.
@@ -470,10 +450,8 @@
%D The stand alone text area inherits from the page too.
-\dodocommand\v!text \empty
-%dodocommand\v!linkertekst \empty
-%dodocommand\v!rechtertekst\empty
-\dodocommand\v!hidden \empty
+\dodocommand\v!text \empty
+\dodocommand\v!hidden\empty
%D We now define all 25 main areas in a row.
diff --git a/tex/context/base/page-bck.mkiv b/tex/context/base/page-bck.mkiv
new file mode 100644
index 000000000..2522c882d
--- /dev/null
+++ b/tex/context/base/page-bck.mkiv
@@ -0,0 +1,521 @@
+%D \module
+%D [ file=page-bck, % copied from main-001
+%D version=1997.03.31,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Backgrounds,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Page Macros / Backgrounds}
+
+% \chardef\kindofpagetextareas=1 will isolate graphics from backgrounds
+
+\unprotect
+
+%D \macros
+%D {recalculatebackgrounds}
+%D
+%D We use a couple of switches so that we can minimize the
+%D amount of background calculations. The main switch is set
+%D by the recalculate directive.
+%D
+%D \starttyping
+%D \recalculatebackgrounds
+%D \stoptyping
+%D
+%D Other modules may not directly set the switches
+%D themselves.
+
+\newif\ifnewbackground
+\newif\ifsomebackground
+
+%D For special purposes, users can question the \type
+%D {*background} mode. This mode is only available when
+%D typesetting the pagebody.
+%D
+%D \starttyping
+%D \startmode[*background] ...
+%D \stoptyping
+
+\appendtoks
+ \ifsomebackground \ifnewbackground \setsystemmode\v!background \fi \fi
+\to \everybeforepagebody
+
+%D \macros
+%D {addmainbackground, addtextbackground,
+%D addpagebackground, addprintbackground}
+%D
+%D Apart from the previously mentioned directive, the
+%D interface between this module and the other modules
+%D is made up by four macros that add background to parts of
+%D the layout.
+%D
+%D \starttyping
+%D \addmainbackground <box>
+%D \addtextbackground <box>
+%D \addpagebackground <box>
+%D \addprintbackground <box>
+%D \stoptyping
+
+%D To minimize calculations, we keep track of the state of the
+%D background of each area. A previous implementation did
+%D check each call to the background calculation macro, but
+%D using an intermediate usage flag instead of testing each
+%D time saves about 3\% on a run with a couple of backgrounds.
+%D (On the 824 pages maps bibliography runtime went down from
+%D 309 to 299 seconds.)
+
+\let\currentotrbackground\empty
+
+\def\@@docheckbackground#1#2%
+ {\ifcsname\currentotrbackground#1\endcsname
+ \edef\!!stringa{\csname\currentotrbackground#1\endcsname}\ifx\!!stringa#2\!!doneatrue\fi
+ \fi}
+
+\def\@@nocheckbackground#1#2%
+ {\ifcsname\currentotrbackground#1\endcsname
+ \edef\!!stringa{\csname\currentotrbackground#1\endcsname}\ifx\!!stringa#2\else\!!doneatrue\fi
+ \fi}
+
+\def\checkbackground#1%
+ {\edef\currentotrbackground{\??ma#1}%
+ \begingroup
+ \!!doneafalse
+ \if!!donea\else\@@nocheckbackground\c!background \empty
+ \if!!donea\else\@@docheckbackground\c!frame \v!on
+ \if!!donea\else\@@nocheckbackground\c!foregroundcolor\empty
+ \if!!donea\else\@@docheckbackground\c!leftframe \v!on
+ \if!!donea\else\@@docheckbackground\c!rightframe \v!on
+ \if!!donea\else\@@docheckbackground\c!topframe \v!on
+ \if!!donea\else\@@docheckbackground\c!bottomframe \v!on \fi\fi\fi\fi\fi\fi\fi
+ \if!!donea
+ \endgroup\setusage \currentotrbackground
+ \else
+ \endgroup\resetusage\currentotrbackground
+ \fi}
+
+\def\ifsomebackgroundfound#1%
+ {\ifusage{\??ma#1}}
+
+\def\doifsomebackgroundelse#1%
+ {\ifusage{\??ma#1}%
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D The background mechanism falls back on the \type {\framed}
+%D macro. This means that all normal frame and overlay
+%D features can be used.
+
+\def\addsomebackground#1#2#3#4% area box width height / zero test added
+ {\ifsomebackgroundfound#1\ifdim#3>\zeropoint\ifdim#4>\zeropoint
+ \ifcsname\??ma#1\c!setups\endcsname % to be done
+ \doifvaluesomething{\??ma#1\c!setups}{\setups[\getvalue{\??ma#1\c!setups}]}% should not produce funny spaces !
+ \fi
+ \setbox#2\vbox\fastlocalframed
+ [\??ma#1]
+ [\c!component=#1,\c!width=#3,\c!height=#4]% are width and height used?
+ {\dp#2\zeropoint\box#2}%
+ \fi\fi\fi}
+
+%D There are quite some backgrounds. At the bottom layer,
+%D there is the {\em paper} background. This one is only
+%D used for special purposes, like annotations to documents.
+
+\def\addprintbackground#1%
+ {\addsomebackground\v!paper#1\printpaperwidth\printpaperheight}
+
+%D The page backgrounds can be put behind the {\em left
+%D page}, the {\em right page} or {\em each page}. As with
+%D the paper background, these are calculated on each page.
+
+\def\addpagebackground#1%
+ {\doifbothsidesoverruled
+ {\addsomebackground\v!rightpage#1\paperwidth\paperheight}
+ {\addsomebackground\v!rightpage#1\paperwidth\paperheight}
+ {\addsomebackground\v!leftpage #1\paperwidth\paperheight}%
+ \addsomebackground\v!page #1\paperwidth\paperheight}
+
+%D Then there are the 25 areas that make up the layout: {\em
+%D top, header, text, footer, bottom} times {\em left edge,
+%D left margin, text, right margin, right edge}. These are
+%D only recalculated when they change or when the \type
+%D {status} is set to \type {repeat}.
+
+\newbox\leftbackground
+\newbox\rightbackground
+
+\def\addmainbackground#1% todo: dimension spec
+ {\ifsomebackground
+ \ifnewbackground \setbackgroundboxes \fi
+ \setbox#1\vbox
+ {\offinterlineskip
+ \doifmarginswapelse{\copy\leftbackground}{\copy\rightbackground}%
+ \box#1}%
+ \fi}
+
+%D Finaly there is an aditional {\em text} background, again
+%D useful for special purposes only. This one is calculated
+%D each time. The hidden backgrounds are not meant for users!
+
+\newconditional\hiddenbackgroundenabled
+
+\def\addtextbackground#1%
+ {\ifconditional\hiddenbackgroundenabled
+ \addsomebackground\v!hidden#1\makeupwidth\textheight % mine !
+ \fi
+ \addsomebackground\v!text#1\makeupwidth\textheight}
+
+%D The next couple of macros implement the area backgrounds.
+%D As said, these are cached in dedicated boxes. The offsets
+%D and depth of the page are used for alignment purposes.
+
+\newdimen\pageoffset % bleed
+\newdimen\pagedepth
+
+\let\pagebackgroundhoffset\!!zeropoint
+\let\pagebackgroundvoffset\!!zeropoint
+\let\pagebackgrounddepth \!!zeropoint
+
+% \def\setbackgroundboxes
+% {\showmessage\m!layouts8\empty
+% \setbackgroundbox\leftbackground\relax
+% \ifdoublesided
+% \setbackgroundbox\rightbackground\doswapmargins
+% \fi
+% \doifnot\@@mastatus\v!herhaal{\global\newbackgroundfalse}}
+
+%D We need a bit more clever mechanism in order to handle
+%D layers well. This means that we cannot calculate both
+%D background at the same time since something may have
+%D changed halfway a page.
+
+\chardef\newrightbackground\zerocount
+\chardef\newleftbackground \zerocount
+
+\def\recalculatebackgrounds
+ {\global\newbackgroundtrue}
+
+\def\setbackgroundboxes
+ {\ifnewbackground
+ \global\chardef\newrightbackground\plusone
+ \global\chardef\newleftbackground\plusone
+ \global\setbox\leftbackground\emptybox
+ \global\setbox\rightbackground\emptybox
+ \fi
+ \doifbothsides
+ {\ifcase\newleftbackground \else
+ % \showmessage\m!layouts8\empty
+ \setbackgroundbox\leftbackground\relax
+ \global\chardef\newleftbackground\zerocount
+ \global\chardef\newrightbackground\zerocount
+ \fi}
+ {\ifcase\newleftbackground \else
+ % \showmessage\m!layouts8\empty
+ \setbackgroundbox\leftbackground\relax
+ \global\chardef\newleftbackground\zerocount
+ \fi}
+ {\ifcase\newrightbackground \else
+ % \showmessage\m!layouts8\empty
+ \setbackgroundbox\rightbackground\doswapmargins
+ \global\chardef\newrightbackground\zerocount
+ \fi}%
+ \ifx\@@mastate\v!repeat\else\global\newbackgroundfalse\fi}
+
+\def\addmainbackground#1% todo: dimension spec
+ {\ifsomebackground
+ \setbackgroundboxes
+ \setbox#1\vbox
+ {\offinterlineskip
+ \doifmarginswapelse{\copy\leftbackground}{\copy\rightbackground}%
+ \box#1}%
+ \fi}
+
+\def\setbackgroundoffsets
+ {\ifsomebackground \ifnewbackground
+ \global\let\pagebackgroundhoffset\!!zeropoint
+ \global\let\pagebackgroundvoffset\!!zeropoint
+ \global\let\pagebackgrounddepth \!!zeropoint
+ \doifsomebackgroundelse{\v!text\v!text}\donetrue\donefalse
+ \ifdone\else\doifsomebackgroundelse\v!text\donetrue\donothing\fi
+ \ifdone
+ \bgroup
+ \scratchdimen\getvalue{\??ma\v!page\c!offset}%
+ \doifsomebackgroundelse{\v!top\v!text}\donothing
+ {\doifsomebackgroundelse{\v!bottom\v!text}\donothing
+ {\xdef\pagebackgroundhoffset{\the\scratchdimen}}}%
+ \doifsomebackgroundelse{\v!text\v!rightedge}\donothing
+ {\doifsomebackgroundelse{\v!text\v!leftedge}\donothing
+ {\xdef\pagebackgroundvoffset{\the\scratchdimen}%
+ \scratchdimen\getvalue{\??ma\v!page\c!depth}%
+ \xdef\pagebackgrounddepth{\the\scratchdimen}}}%
+ \egroup
+ \fi
+ \fi \fi}
+
+\appendtoks \setbackgroundoffsets \to \everybeforepagebody
+
+\newconditional\swapbackgroundmargins \settrue\swapbackgroundmargins
+
+\def\setbackgroundbox#1#2%
+ {\global\setbox#1\vbox
+ {\dontcomplain
+ \swapmargins
+ \ifconditional\swapbackgroundmargins
+ \doifmarginswapelse \donothing
+ {\swapmacros\v!rightmargin\v!leftmargin
+ \swapmacros\v!rightedge \v!leftedge}%
+ \fi
+ \calculatereducedvsizes
+ \offinterlineskip
+ #2\relax
+ \vskip\dimexpr-\topheight-\topdistance\relax
+ \dodopagebodybackground\v!top\topheight
+ \vskip\topdistance
+ \dodopagebodybackground\v!header\headerheight
+ \vskip\headerdistance
+ \dodopagebodybackground\v!text\textheight
+ \vskip\footerdistance
+ \dodopagebodybackground\v!footer\footerheight
+ \vskip\bottomdistance
+ \dodopagebodybackground\v!bottom\bottomheight
+ \vfilll}%
+ \smashbox#1}
+
+\def\dodopagebodybackground#1#2%
+ {\ifdim#2>\zeropoint % added, faster
+ \setbox\scratchbox\vbox to #2
+ \bgroup\hbox\bgroup
+ % \swapmargins
+ \goleftonpage
+ \dododopagebodybackground\leftedgewidth #2#1\v!leftedge
+ \hskip\leftedgedistance
+ \dododopagebodybackground\leftmarginwidth #2#1\v!leftmargin
+ \hskip\leftmargindistance
+ \dododopagebodybackground\makeupwidth #2#1\v!text
+ \hskip\rightmargindistance
+ \dododopagebodybackground\rightmarginwidth#2#1\v!rightmargin
+ \hskip\rightedgedistance
+ \dododopagebodybackground\rightedgewidth #2#1\v!rightedge
+ \egroup\egroup
+ \wd\scratchbox\zeropoint
+ \box\scratchbox\relax
+ \fi}
+
+\def\dododopagebodybackground#1#2#3#4% width height pos pos
+ {\ifsomebackgroundfound{#3#4}%
+ \ifdim#2>\zeropoint\relax
+ \ifdim#1>\zeropoint\relax
+ \ifcsname\??ma#3#4\c!setups\endcsname % to be done
+ \doifvaluesomething{\??ma#3#4\c!setups}{\setups[\getvalue{\??ma#3#4\c!setups}]}% should not produce funny spaces !
+ \fi
+ \fastlocalframed
+ [\??ma#3#4]
+ [\c!component=#3-#4]
+ {\vbox to #2{\vss\hbox to#1{\hss\getvalue{\??ma#3#4\c!command}\hss}\vss}}%
+ \else
+ \hskip#1%
+ \fi
+ \else
+ \hskip#1%
+ \fi
+ \else
+ \hskip#1%
+ \fi}
+
+%D The background mechanism is quite demanding in terms or
+%D resources. We used to delay these definitions till runtime
+%D usage, but since today's \TEX's are large, we now do the
+%D work on forehand.
+%D
+%D \starttyping
+%D \setupbackgrounds [settings]
+%D \setupbackgrounds [paper,page,text,..] [settings]
+%D \setupbackgrounds [top,...] [leftedge,...] [settings]
+%D \stoptyping
+%D
+%D \showsetup{setupbackgrounds}
+%D
+%D Because the number of arguments runs from one to three,
+%D we need to check for it.
+
+\def\setupbackgrounds
+ {\dotripleempty\dosetupbackgrounds}
+
+\def\dosetupbackgrounds[#1][#2][#3]%
+ {\ifthirdargument
+ \global\somebackgroundtrue
+ \def\docommand##1%
+ {\doifinsetelse{##1}{\v!paper,\v!page,\v!leftpage,\v!rightpage}
+ {\getparameters[\??ma##1][#3]\checkbackground{##1}}
+ {\def\dodocommand####1{\getparameters[\??ma##1####1][#3]\checkbackground{##1####1}}%
+ \processcommalist[#2]\dodocommand}}%
+ \processcommalist[#1]\docommand
+ \else\ifsecondargument
+ \global\somebackgroundtrue
+ \doifcommonelse{#1}{\v!text,\v!hidden,\v!paper,\v!page,\v!leftpage,\v!rightpage}
+ {\def\docommand##1{\getparameters[\??ma##1][#2]\checkbackground{##1}}%
+ \processcommalist[#1]\docommand}%
+ {\setupbackgrounds
+ [#1]%
+ [\v!leftedge,\v!leftmargin,\v!text,\v!rightmargin,\v!rightedge]%
+ [#2]}%
+ \else\iffirstargument
+ \getparameters[\??ma][#1]%
+ \fi\fi\fi
+ \doifelsevalue{\??ma\v!page\c!offset}\v!overlay
+ {\global\pageoffset\zeropoint}
+ {\global\pageoffset\getvalue{\??ma\v!page\c!offset}}%
+ \global\pagedepth\getvalue{\??ma\v!page\c!depth}%
+ \xdef\pagebackgroundoffset{\the\pageoffset}%
+ \xdef\pagebackgrounddepth {\the\pagedepth }%
+ \doifelse\@@mastate\v!stop
+ {\global\newbackgroundfalse}
+ {\global\newbackgroundtrue }}
+
+\let\pagebackgroundoffset\!!zeropoint
+\let\pagebackgrounddepth \!!zeropoint
+
+%D Each areas (currently there are $1+3+25+1=30$ of them)
+%D has its own low level framed object associated.
+
+\def\installsomebackground#1#2{\inheritlocalframed[\??ma#1#2][\??od]}
+
+\installsomebackground \v!paper \empty
+\installsomebackground \v!page \empty
+\installsomebackground \v!leftpage \empty
+\installsomebackground \v!rightpage \empty
+
+%D The stand alone text area inherits from the page too.
+
+\installsomebackground \v!text \empty
+\installsomebackground \v!hidden \empty
+
+%D We save some keying by defining the areas using a helper:
+
+\def\docommand#1%
+ {\installsomebackground#1\v!leftedge
+ \installsomebackground#1\v!leftmargin
+ \installsomebackground#1\v!text
+ \installsomebackground#1\v!rightmargin
+ \installsomebackground#1\v!rightedge}
+
+\docommand \v!top
+\docommand \v!header
+\docommand \v!text
+\docommand \v!footer
+\docommand \v!bottom
+
+%D We need some cleanup now.
+
+\let\docommand\relax
+
+%D We now set up the individual areas to use reasonable
+%D defaults.
+
+\installsomebackground \v!paper \empty
+\installsomebackground \v!page \empty
+\installsomebackground \v!leftpage \empty
+\installsomebackground \v!rightpage \empty
+
+\getparameters
+ [\??ma\v!page]
+ [\c!offset=\!!zeropoint, % hm, so we need to force overlay elsewhere
+ \c!depth=\!!zeropoint]
+
+%D General setup:
+
+\setupbackgrounds
+ [\c!state=\c!start]
+
+%D The hidden layer can be populated by extending the
+%D following comma separated list. This only happens in core
+%D modules.
+
+% todo page-2 .. page+2 achter pagina -> bleed
+% spread-2 .. spread+2 achter spread -> spread (repeat 2 times)
+
+\def\enablehiddenbackground
+ {\global\settrue\hiddenbackgroundenabled
+ \global\somebackgroundtrue
+ \recalculatebackgrounds}
+
+\def\disablehiddenbackground
+ {\global\setfalse\hiddenbackgroundenabled}
+
+\def\hiddenbackground
+ {\v!text-2,\v!text-1,\v!foreground,\v!text+1,\v!text+2}
+
+\setupbackgrounds
+ [\v!hidden]
+ [\c!background=\hiddenbackground]
+
+% The next series is used in local (for instance floating)
+% backgrounds.
+
+\installsomebackground \v!local \empty % not really a background, invisible for users
+
+\getparameters
+ [\??ma\v!local]
+ [\c!component=local,
+ \c!background=\localbackground]
+
+\def\localbackground
+ {\v!local-2,\v!local-1,\v!foreground,\v!local+1,\v!local+2}
+
+\defineoverlay[\v!local-2][\positionoverlay{\v!local-2}]
+\defineoverlay[\v!local-1][\positionoverlay{\v!local-1}]
+\defineoverlay[\v!local+1][\positionoverlay{\v!local+1}]
+\defineoverlay[\v!local+2][\positionoverlay{\v!local+2}]
+
+\def\addlocalbackgroundtobox
+ {\ifconditional\hiddenbackgroundenabled
+ \expandafter\doaddlocalbackground
+ \else
+ \resetglobal \expandafter\gobbleoneargument
+ \fi}
+
+\def\doaddlocalbackground#1%
+ {\dodoglobal\setbox#1\hbox{\fastlocalframed[\??ma\v!local][]{\registerMPlocaltextarea{\box#1}}}%
+ \resetglobal % redundant
+ \doglobal\increment\localpositionnumber\relax} % afterwards !
+
+% Test how previous macro behaves with depth:
+%
+% \startcolumnset
+% \input tufte
+% \placefigure{none}{\framed[lines=5]{xxx}}
+% \input tufte
+% \placefigure{none}{\starttabulate\NC test\nc test\NC\NR\stoptabulate}
+% \input tufte
+% \stopcolumnset
+
+%D Because we haven't really set up backgrounds yet, we set
+%D the main efficiency switch to false.
+
+\somebackgroundfalse
+
+\protect \endinput
+
+%D Removed \quote {features}:
+%D
+%D \starttyping
+%D \startinteraction
+%D \doifmarginswapelse
+%D {\copy\leftbackground}
+%D {\copy\rightbackground}%
+%D \stopinteraction
+%D \stoptyping
+%D
+%D \starttyping
+%D \edef\setpagebackgrounddepth%
+%D {\dp#2=\the\dp#2}%
+%D \setbox#2=\vbox\localframed[\??ma#1]{...}
+%D \setpagebackgrounddepth
+%D \stoptyping
diff --git a/tex/context/base/page-flt.tex b/tex/context/base/page-flt.tex
index a0b297981..91cb25e6b 100644
--- a/tex/context/base/page-flt.tex
+++ b/tex/context/base/page-flt.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-flt,
%D version=2000.10.20,
-%D title=\CONTEXT\ OTR Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Floating Bodies,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context OTR Macros / Floating Bodies}
+\writestatus{loading}{ConTeXt Page Macros / Floating Bodies}
%D Some of the sidefloat settings should move to page-sid; now it's quite
%D fuzzy the way the variables are set/reset.
@@ -19,169 +19,24 @@
\unprotect
\ifx\addlocalbackgroundtobox\undefined \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi
-
-% naar supp-box.tex
-
-\def\voidbox{\box\voidb@x}
-
-\def\spreadhbox#1% rebuilds \hbox{<box><hss><box><hss><box>}
- {\bgroup
- \ifhbox#1\relax
- \setbox2\voidbox
- \unhbox#1%
- \doloop
- {\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip
- \setbox0\lastbox
- \ifvoid0
- \exitloop
- \else
- \setbox2\hbox
- {\ifhbox0 \spreadhbox0\else\box0\fi
- \ifvoid2 \else\hss\unhbox2\fi}%
- \fi}%
- \ifvoid2\else\unhbox2\fi
- \else
- \box#1%
- \fi
- \egroup}
\def\placefloats{\doflushfloats} % keep this one
-\startmessages dutch library: floatblocks
- title: plaatsblokken
- 1: -- hernummerd / -- => --
- 2: -- bewaard
- 3: -- verplaatst
- 4: -- geplaatst
- 5: volgorde aangepast
- 6: maximaal -- boven
- 7: maximaal -- onder
- 8: minder dan -- regels
- 9: volgorde verstoord
- 10: -- begrensd
- 11: geen blok opgegeven
- 12: niet gedefinieerd
- 13: er is niets te splitsen
-\stopmessages
-
-\startmessages english library: floatblocks
- title: floatblocks
- 1: -- renumbered / -- => --
- 2: -- saved
- 3: -- moved
- 4: -- placed
- 5: order adapted
- 6: n of top floats limited to --
- 7: n of bottom floats limited to --
- 8: less than -- lines
- 9: order disturbed
- 10: -- limited
- 11: no block given
- 12: undefined
- 13: there is nothing to split
-\stopmessages
-
-\startmessages german library: floatblocks
- title: Gleitobjektbloecke
- 1: -- neu nummeriert / -- => --
- 2: -- gespeichert
- 3: -- verschoben
- 4: -- plaziert
- 5: Reihenfolge angepasst
- 6: Anz. der oberen Gleitobjekte beschraengt auf --
- 7: Anz. der unteren Gleitobjekte beschraengt auf --
- 8: weniger als -- zeilen
- 9: Reigenfolge gestoert
- 10: -- begrenzt
- 11: kein Block gegeben
- 12: undefiniert
- 13: there is nothing to split
-\stopmessages
-
-\startmessages czech library: floatblocks
- title: plovouciobjekty
- 1: -- precislovano / -- => --
- 2: -- ulozeno
- 3: -- presunuto
- 4: -- umisteno
- 5: poradi prizpusobeno
- 6: pocet hornich plovoucich objektu je omezen na --
- 7: pocet spodnich plovoucich objektu je omezen na --
- 8: radku je mene nez --
- 9: poradi naruseno
- 10: -- omezeno
- 11: nedan zadny blok
- 12: nedefinovano
- 13: there is nothing to split
-\stopmessages
-
-\startmessages italian library: floatblocks
- title: oggetti mobili
- 1: -- rinumerato / -- => --
- 2: -- salvato
- 3: -- mosso
- 4: -- sistemato
- 5: ordine aggiustato
- 6: n di top floats limitato a --
- 7: n di bottom floats limitato a --
- 8: meno di -- righe
- 9: ordine disturbato
- 10: -- limitato
- 11: nessun oggetto specificato
- 12: non definito
- 13: there is nothing to split
-\stopmessages
-
-\startmessages norwegian library: floatblocks
- title: flytblokker
- 1: -- renummerert / -- => --
- 2: -- lagret
- 3: -- flyttet
- 4: -- plassert
- 5: rekkefølge tilpasset
- 6: maksimalt -- flytblokker øverst
- 7: maksimalt -- flytblokker nederst
- 8: mindre enn -- linjer
- 9: rekkefølge endret
- 10: -- begrenset
- 11: ingen blokk oppgitt
- 12: udefinert
- 13: there is nothing to split
-\stopmessages
-
-\startmessages romanian library: floatblocks
- title: Blocuri
- 1: -- renumerotat / -- => --
- 2: -- salvat
- 3: -- mutat
- 4: -- plasat
- 5: ordinea adaptata
- 6: nr. cadrelor de sus limitat la --
- 7: nr. blocurilor de jos limitat la --
- 8: mai putin de -- linii
- 9: ordinea deranjata
- 10: -- limitat
- 11: nu este dat nici un bloc
- 12: nedefinit
- 13: there is nothing to split
-\stopmessages
-
-\startmessages french library: floatblocks
- title: blocs de flottants
- 1: -- renuméroté / -- => --
- 2: -- sauvegardé
- 3: -- déplacé
- 4: -- placé
- 5: ordre adapté
- 6: n flottants de haut de page limité à --
- 7: n flottants de bas de page limité à --
- 8: moins de -- lignes
- 9: ordre perturbé
- 10: -- limité
- 11: pas de bloc donné
- 12: indéfini
- 13: there is nothing to split
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
\def\floatparameter #1{\csname\??fl\currentfloat#1\endcsname}
\def\floatcaptionparameter#1{\csname\??kj\currentfloat#1\endcsname}
@@ -395,8 +250,6 @@
\hsize\localhsize
\fi}
-\newevery \everyinsidefloat \relax
-
\appendtoks
\everyinsidefloat\emptytoks % in case it's called earlier
\dogetfloatdata
@@ -618,6 +471,7 @@
\c!leftframe=\@@bkleftframe,
\c!rightframe=\@@bkrightframe,
\c!frameoffset=\@@bkframeoffset,
+ \c!framecolor=\@@bkframecolor,
%\c!local=\@@bklocal,
\c!textmethod=\@@bktextmethod,
\c!sidemethod=\@@bksidemethod,
@@ -687,32 +541,6 @@
% \setupfloat[...][leftmargindistance=1cm,default={left,none}]
-% \def\redodefinefloat[#1][#2][#3]% same label/number
-% {\presetlocalframed[\??fl#1]%
-% \copylocalframed[\??fl#1][\??fl#3]%
-% \copyparameters[\??fl#1][\??fl#3]
-% [\c!width,\c!height,%\c!local,
-% \c!maxwidth,\c!maxheight,\c!minwidth,
-% \c!margin,\c!sidespacebefore,\c!sidespaceafter,\c!sidealign,
-% \c!leftmargindistance,\c!rightmargindistance,\c!criterium,
-% \c!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin,
-% \c!frame,\c!radius,\c!corner,\c!location,\c!background,\c!framecolor,
-% \c!backgroundscreen,\c!backgroundcolor,\c!backgroundoffset,
-% \c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe,
-% \c!frameoffset,\c!pageboundaries,\c!default,
-% \c!textmethod,\c!sidemethod,\c!method]%
-% \copyparameters[\??kj#1][\??kj#3]
-% [\c!location,\c!before,\c!inbetween,\c!after,
-% \c!spacebefore,\c!spaceinbetween,\c!spaceafter,
-% \c!width,\c!headstyle,\c!headcolor,\c!style,\c!color,
-% \c!textstyle,\c!textcolor,\c!minwidth,
-% \c!align,\c!number,\c!way,\c!blockway,\c!setups,
-% \c!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin,
-% \c!sectionnumber,\c!separator,\c!stopper,\c!suffix,\c!distance,\c!conversion]%
-% \definenumber[#1][#3]%
-% \presetlabeltext[#1=\labeltext{#3}]%
-% \dodefinefloatcommands[#1][#2]}
-
\def\redodefinefloat[#1][#2][#3]% same label/number
{\presetlocalframed[\??fl#1]%
\copylocalframed[\??fl#1][\??fl#3]%
@@ -906,7 +734,7 @@
\fi
\else
\global\savednoffloats\zerocount
- \global\setbox\floatbox\box\voidb@x
+ \global\setbox\floatbox\emptybox
\fi}
\def\uncenteredfloatbox
@@ -2126,257 +1954,8 @@
\fi
\global\insidefloatfalse}
-\newif\ifmargeblokken
-
-\def\dosetupmarginblocks[#1]%
- {\getparameters[\??mb][#1]%
- \doifelse\@@mbstate\v!start
- {\showmessage\m!layouts4\empty
- \margeblokkentrue
- \let\somenextfloat\dosomenextfloat
- \let\startmarginblock\dostartmarginblock
- \let\stopmarginblock\dostopmarginblock}%
- {\showmessage\m!layouts5\empty
- \margeblokkenfalse
- \def\somenextfloat[##1]%
- {\someelsefloat[##1,\v!here]}%
- \let\startmarginblock\dontstartmargeblok
- \let\stopmarginblock\dontstopmargeblok}}
-
-\def\setupmarginblocks
- {\dosingleargument\dosetupmarginblocks}
-
-\newbox\marginbox
-
-\def\dosomenextfloat[#1]%
- {\global\setbox\marginbox\vbox
- {\hsize\@@mbwidth
- \unvcopy\marginbox
- \ifvoid\marginbox\else\expandafter\@@mbinbetween\fi
- \box\floatbox\filbreak}%
- \ifdim\ht\marginbox>\textheight
- \dosavefloatinfo
- \else
- \doinsertfloatinfo
- \fi}
-
-\newbox\preparedmarginbox
-
-\def\reshapemargin
- {\ifdim\ht\preparedmarginbox>\zeropoint
- \beginofshapebox
- \unvbox\preparedmarginbox
- \endofshapebox
- \reshapebox
- {\box\shapebox}%
- \setbox\preparedmarginbox\vbox to \textheight
- {\@@mbtop
- \flushshapebox
- \@@mbbottom}%
- \fi}
-
-\def\plaatsrechtermargeblok
- {\hskip\rightmarginwidth}
-
-\def\plaatslinkermargeblok
- {\hskip\leftmarginwidth}
-
-\def\checkmargeblokken
- {\ifvoid\marginbox\else\docheckmargeblokken\fi}
-
-\def\docheckmargeblokken % erg inefficient
- {\setbox\preparedmarginbox\vbox
- {\forgetall
- \splittopskip\topskip
- \ifvoid\marginbox\else
- \ifdim\ht\marginbox>\textheight
- \vsplit\marginbox to \textheight
- \else
- \unvbox\marginbox
- \fi
- \fi}%
- \reshapemargin
- \setbox\preparedmarginbox\vbox
- {\@@mbbefore\box\preparedmarginbox\@@mbafter}%
- \def\rightmarginbox
- {\def\plaatsrechtermargeblok
- {\setbox\preparedmarginbox\hbox to \rightmarginwidth
- {\@@mbleft\box\preparedmarginbox\@@mbright}%
- \vsmashbox\preparedmarginbox
- \box\preparedmarginbox}}%
- \def\leftmarginbox
- {\def\plaatslinkermargeblok
- {\setbox\preparedmarginbox\hbox to \leftmarginwidth
- {\@@mbright\box\preparedmarginbox\@@mbleft}%
- \vsmashbox\preparedmarginbox
- \box\preparedmarginbox}}%
- \processaction % traag
- [\@@mblocation]
- [ \v!inmargin=>\doifbothsidesoverruled\rightmarginbox\rightmarginbox\leftmarginbox,
- \v!middle=>\doifbothsidesoverruled\rightmarginbox\leftmarginbox\rightmarginbox,
- \v!left=>\leftmarginbox,
- \v!right=>\rightmarginbox,
- \s!unknown=>\setbox\preparedmarginbox\hbox{}]}
-
-\def\dostartmarginblock % 2 maal \vbox ivm \unvbox elders
- {\global\setbox\marginbox\vtop\bgroup\vbox\bgroup
- \hsize\@@mbwidth
- \ifvoid\marginbox\else
- \unvbox\marginbox
- \@@mbinbetween
- \fi
- \setupalign[\@@mbalign]%
- \dostartattributes\??mb\c!style\c!color{}%
- \begstrut\ignorespaces}
-
-\def\dostopmarginblock
- {\unskip\endstrut
- \dostopattributes
- \egroup
- \egroup}
-
-\def\dontstartmargeblok
- {\@@mbbefore
- \bgroup
- \dostartattributes\??mb\c!style\c!color\empty}
-
-\def\dontstopmargeblok
- {\dostopattributes
- \egroup
- \@@mbafter}
-
-\newcounter\nofpostponedblocks
-
-\newif\ifinpostponing
-
-\newevery\everytopofpage\relax
-
-\appendtoks \the\everytopofpage \to\everystarttext
-\appendtoks\global\everytopofpage\emptytoks\to\everystoptext
-
-% \startpostponing [pagenumber] [+pageoffset]
-%
-% \startpostponing[2]
-% PAGE 2 \blank
-% \stoppostponing
-%
-% \startpostponing[+1]
-% PAGE +1 \blank
-% \stoppostponing
-%
-% \startpostponing[+2]
-% PAGE +2 \blank
-% \stoppostponing
-%
-% \starttext \dorecurse{4}{\input tufte \page} \stoptext
-
-\newtoks \postponedpageblocks
-\newcounter\nofpostponedpageblocks
-
-% \ifinpostponing: handhaven, want gebruikt in stijlen ! ! ! ! !
-
-\def\flushpagefloats
- {\doifoddpageelse
- {\ifvoid\collectedleftpagefloats
- \ifvoid\collectedrightpagefloats\else
- \unvbox\collectedrightpagefloats
- \page
- %\the\everytopofpage
- \fi
- \fi}
- {\ifvoid\collectedleftpagefloats\else
- \unvbox\collectedleftpagefloats
- \page
- %\the\everytopofpage
- \fi
- \ifvoid\collectedrightpagefloats\else
- \unvbox\collectedrightpagefloats
- \page
- %\the\everytopofpage
- \fi}%
- \ifvoid\collectedpagefloats\else
- % message
- \unvbox\collectedpagefloats
- \fi}
-
-% \def\flushrestfloats
-% {\doif\@@bkcache\v!no\doflushfloats}
-
-% \let\flushrestfloats\relax
-
-\def\dopostponeblock
- {\bgroup % new may 2004
- \setsystemmode\v!postponing % new may 2004
- \the\everytopofpage
-% \flushrestfloats
- \flushpagefloats
- \donefalse
- \ifinpostponing \else
- \ifcase\nofpostponedblocks \else \donetrue \fi
- \ifcase\nofpostponedpageblocks \else \donetrue \fi
- \fi
- \ifdone
- \bgroup % we need the color/font switch, else problems inside split verbatim
- \setnormalcatcodes % postponing in verbatim
- \pushpostponedpagecolor
- \restoreglobalbodyfont % The \nof-test is
- \global\pagetotal\zeropoint % recently added and
- \global\inpostponingtrue % definitely needed else
- \the\postponedpageblocks % we can loose or disorder
- \dorecurse\nofpostponedblocks % floats; anyhow, this
- {\getbuffer[pbuf-\recurselevel]}% % mechanism is still
- \doflushfloats % new but potential dangerous % suboptimal and needs a
- \doglobal\newcounter\nofpostponedblocks % proper analysis
- \global\inpostponingfalse
- \poppostponedpagecolor
- \egroup
- \fi
- \egroup} % new may 2004
-
-\def\getpostponedblock#1#2%
- {\doif{#1}\realfolio{\getbuffer[rbuf-#2]}} % no \ifnum, avoid \fi
-
-% beware, \dosingleempty conflicts with buffers (feeds back the \par)
-
-\setvalue{\e!start\v!postponing}%
- {\bgroup
- \obeylines
- \doifnextcharelse[%
- {\egroup\nodostartpostponing}{\egroup\dodostartpostponing}}
-
-\def\nodostartpostponing[#1]%
- {\doglobal\increment\nofpostponedpageblocks
- \bgroup % a little bit of misusing grouping
- \doifinstring{+}{#1}\advance \realpageno#1\relax % ugly but efficient
- \doglobal\appendetoks\noexpand\getpostponedblock
- {\realfolio}{\nofpostponedpageblocks}\to\postponedpageblocks
- \egroup
- \showmessage\m!layouts3\nofpostponedpageblocks
- \dostartbuffer[rbuf-\nofpostponedpageblocks]%
- [\e!start\v!postponing][\e!stop\v!postponing]}
-
-\def\dodostartpostponing
- {\doglobal\increment\nofpostponedblocks
- \showmessage\m!layouts3\nofpostponedblocks
- \expanded{\dostartbuffer[pbuf-\nofpostponedblocks][\e!start\v!postponing][\e!stop\v!postponing]}}
-
\def\dooutput{\sidefloatoutput} % redefinition of \dooutput
-\setupmarginblocks
- [\c!state=\v!start,
- \c!location=\v!inmargin,
- \c!width=\rightmarginwidth,
- \c!style=,
- \c!color=,
- \c!align=,
- \c!left=,
- \c!right=,
- \c!top=,
- \c!inbetween=\blank,
- \c!bottom=\vfill,
- \c!before=,
- \c!after=]
-
\definefloat
[\v!figure]
[\v!figures]
@@ -2447,6 +2026,7 @@
\c!bottomframe=,
\c!leftframe=,
\c!rightframe=,
+ \c!framecolor=,
\c!frameoffset=\!!zeropoint,
\c!before=,
\c!after=,
diff --git a/tex/context/base/page-flw.tex b/tex/context/base/page-flw.tex
index 1a8ffd3c4..3eb867a78 100644
--- a/tex/context/base/page-flw.tex
+++ b/tex/context/base/page-flw.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-flw,
%D version=2003.04.19, % from test-002 (1997) profile experiment
-%D title=\CONTEXT\ OTR Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Text Flows,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context OTR Macros / Text Flows}
+\writestatus{loading}{ConTeXt Page Macros / Text Flows}
%D This is high experimental and especially flushing may change (proper
%D spacing is the driving force here).
diff --git a/tex/context/base/page-imp.tex b/tex/context/base/page-imp.tex
index a16f0031f..e4ece04a6 100644
--- a/tex/context/base/page-imp.tex
+++ b/tex/context/base/page-imp.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-imp, % was: core-pag,
%D version=1998.01.15,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Pagebody Building (Imposition),
%D author=Hans Hagen,
%D date=\currentdate,
@@ -13,7 +13,7 @@
% much of this can more to run time loading !
-\writestatus{loading}{Context Core Macros / Pagebody Building}
+\writestatus{loading}{ConTeXt Page Macros / Pagebody Building}
\unprotect
@@ -115,13 +115,26 @@
% moved code:
+% \def\myshipout#1%
+% {\beforeshipout % voor de pagebody dus !
+% \dontshowcomposition
+% \ifarrangingpages\@EA\actualarrange\else\@EA\actualshipout\fi
+% {\thisisrealpage\realfolio#1}%
+% \gotonextrealpage
+% \aftershipout}
+
+\def\installpagehandler#1#2% % a handler takes one argument: something to be boxed
+ {\setvalue{\??pp:\c!method:#1}{#2}} % and shipped out (don't depend on the exact package)
+
+\installpagehandler\v!normal
+ {\ifarrangingpages\expandafter\actualarrange\else\expandafter\actualshipout\fi}
+
\def\myshipout#1%
- {\beforeshipout % voor de pagebody dus !
- \dontshowcomposition
- \ifarrangingpages\@EA\actualarrange\else\@EA\actualshipout\fi
- {\thisisrealpage\realfolio#1}%
- \gotonextrealpage
- \aftershipout}
+ {\beforeshipout % voor de pagebody dus !
+ \dontshowcomposition
+ \executeifdefined{\??pp:\c!method:\@@ppmethod}\gobbleoneargument{\thisisrealpage\realfolio#1}%
+ \gotonextrealpage
+ \aftershipout}
\newbox\postponedcontent
diff --git a/tex/context/base/page-ini.tex b/tex/context/base/page-ini.mkii
index 61cd91b2b..e5c3aa41a 100644
--- a/tex/context/base/page-ini.tex
+++ b/tex/context/base/page-ini.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Initializations}
+\writestatus{loading}{ConTeXt Page Macros / Initializations}
% still a dutch/english mess
@@ -25,368 +25,6 @@
%D mechanism use a different way of looping over columns.
\unprotect
-
-% message will be distributed
-
-\startmessages dutch library: systems
- title: systeem
- 1: laden hulpfile uitgesteld (typemode)
- 2: -- geladen
-% 3: probeer LaTeX eens
- 4: commando -- is al gedefinieerd
- 5: module -- geladen
- 6: geen module -- gevonden
- 7: module -- reeds geladen
- 8: nieuwe versie hulpfile, tweede run nodig
- 9: -- niet gevonden/geplaatst
- 10: gebruik geen em in --
- 11: aanmaken basale hulpfile
- 12: de hulpfile is niet gesorteerd, gebruik texutil
- 13: markering -- gedefinieerd --
- 14: geforceerde paginaovergang in lijst voor --
- 15: wegschrijven buffer --
- 16: inlezen buffer --
- 17: verbatim inlezen buffer --
- 18: synoniem -- -- bestaat niet
- 19: betekenissen (synoniemen) van -- geladen
- 20: betekenissen (sorteren) van -- geladen
- 21: de hulpfile is niet geladen
- 22: gebruik een goede hulpfile
- 23: -- gearrangeerd op --
- 24: Plaatsblokken
- 25: Verwijzingen
- 26: Registers
- 27: Versie
-\stopmessages
-
-\startmessages english library: systems
- title: system
- 1: loading utility-file postponed (typemode)
- 2: -- loaded
-% 3: try LaTeX
- 4: command -- is already defined
- 5: module -- loaded
- 6: module -- not found
- 7: module -- already loaded
- 8: new version of utility file, second pass needed
- 9: -- not found/processed
- 10: don't use em in --
- 11: building simple util
- 12: the utility-file is not sorted, use texutil
- 13: mark -- defined --
- 14: forced newpage in list at --
- 15: saving buffer --
- 16: typesetting buffer --
- 17: typesetting verbatim buffer --
- 18: synonym -- -- does not exist
- 19: meaning (synonyms) of -- loaded
- 20: meaning (sorts) of -- loaded
- 21: no utility data is loaded
- 22: use a valid utilityfile
- 23: -- arranged at --
- 24: Floatblocks
- 25: References
- 26: Registers
- 27: Version
-\stopmessages
-
-\startmessages german library: systems
- title: system
- 1: Laden der Hilfsdatei aufgeschoben (Eingabe-Modus)
- 2: -- geladen
-% 3: Versuche LaTeX
- 4: Befehl -- ist bereits definiert
- 5: Modul -- geladen
- 6: Modul -- gefunden
- 7: Modul -- bereits geladen
- 8: Neue Version der Hilfsdatei, zweiter Durchlauf benoetigt
- 9: -- nicht gefunden/verarbeitet
- 10: Benutzte kein em in --
- 11: Erstelle einfache Hilfdatei
- 12: Die Hilfdatei ist nicht sortiert, verwende texutil
- 13: Beschriftung -- definiert --
- 14: Erzwungendes Seitenumbruch in Liste bei --
- 15: Speichere Buffer --
- 16: Setzte Buffer --
- 17: Setzte tippen-Buffer --
- 18: Synonym -- -- existiert nicht
- 19: Bedeutung (synonyme) von -- geladen
- 20: Bedeutung (sortieren) von -- geladen
- 21: Die Hilfsdatei ist nicht geladen
- 22: Benoetige gueltige Hilfsdateie
- 23: -- angeordnet auf --
- 24: Fliessbloecke
- 25: Referenzen
- 26: Register
- 27: Version
-\stopmessages
-
-\startmessages czech library: systems
- title: system
- 1: nacteni pomocneho souboru odlozeno (typemode)
- 2: -- nacteno
-% 3: zkuste LaTeX
- 4: prikaz -- je jiz definovan
- 5: makra z -- nactena
- 6: zadna makra v -- nenalezena
- 7: makra z -- jsou jiz nactena
- 8: nova verze pomocneho souboru, je treba druheho behu
- 9: -- nenalezeno/nezpracovano
- 10: nepouzivejte em v --
- 11: vytvarim jednoduchy pomocny soubor
- 12: pomosny soubor neni setriden, pouzijte texutil
- 13: znacka -- definovana --
- 14: vynucena nova stranka v seznamu na --
- 15: uklada se buffer --
- 16: sazi se buffer --
- 17: sazi se doslovny (verbatim) buffer --
- 18: synonymum -- -- neexistuje
- 19: vyznam (synonyma) -- nacten
- 20: vyznam (trideni) -- nacten
- 21: pomocny soubor necten
- 22: pouzijte platny pomocny soubor
- 23: -- upraveno na --
- 24: plovouci bloky
- 25: reference
- 26: registry
- 27: verze
-\stopmessages
-
-\startmessages italian library: systems
- title: sistema
- 1: caricamento dei file supplementari posticipato (typemode)
- 2: -- caricato
-% 3: provare LaTeX
- 4: comando -- già definito
- 5: macro del modulo -- caricate
- 6: nessuna macro trovata nel modulo --
- 7: macro del modulo -- già caricate
- 8: nuova versione del file supplementare, seconda passata necessaria
- 9: -- non trovato/elaborato
- 10: non usare em in --
- 11: costruzione di un semplice supplemento
- 12: file di supplemento non ordinato, usare texutil
- 13: marcatura -- definita --
- 14: nuova pagina obbligata in lista a --
- 15: salvataggio del buffer --
- 16: composizione del buffer --
- 17: composizione verbatim del buffer --
- 18: sinonimo -- -- non esistente
- 19: significato (sinonimi) di -- caricato
- 20: significato (specie) di -- caricato
- 21: nessuna informazione supplementare caricata
- 22: usare un file supplementare valido
- 23: -- sistemato a --
- 24: Oggetti mobili
- 25: Riferimenti
- 26: Registri
- 27: Versione
-\stopmessages
-
-\startmessages norwegian library: systems
- title: system
- 1: innlesning av hjelpefila utsatt (typemode)
- 2: -- er lest inn
-% 3: forsøker LaTeX
- 4: kommando -- er allerede definert
- 5: makroene i modul -- er lest inn
- 6: ingen makroer funnet i modul ---
- 7: makroene i modul -- er allerede lest inn
- 8: ny versjon av hjelpefil, andre gjennomkjøring nødvendig
- 9: -- ikke funnet/behandlet
- 10: ikke bruk em i --
- 11: lager enkel hjelpefil
- 12: hjelpefila er ikke sortert, bruk texutil
- 13: markering -- definert --
- 14: tvunget sideskift i liste ved --
- 15: lagrer Buffer --
- 16: tegnsetter buffer --
- 17: tegnsetter verbatim-buffer --
- 18: synonym -- -- eksisterer ikke
- 19: betydning (synonymer) av -- er lest inn
- 20: betydning (sorterer) av -- er lest inn
- 21: hjelpefila er ikke lest inn
- 22: bruk en gyldig hjelpefil
- 23: -- arrangert på --
- 24: Flytblokker
- 25: Referanser
- 26: Registere
- 27: Versjon
-\stopmessages
-
-\startmessages romanian library: systems
- title: sistem
- 1: se incarca utilitarul-fisierul este amanat (typemode)
- 2: -- s-a incarcat
-% 3: incercati LaTeX
- 4: comanda -- este deja definita
- 5: macro-urile din modulul -- s-au incarcat
- 6: nu s-au gasit macro-uri in modulul --
- 7: macro-urile din modulul -- s-au incarcat deja
- 8: o noua versiune de fisier utilitar, este necesara o noua trecere
- 9: -- nu este gasit/procesat
- 10: nu folositi em in --
- 11: se creeaza un utilitar simplu
- 12: fisierul utilitar nu este sortat, folositi texutil
- 13: marcajul -- definit --
- 14: s-a fortat trecere pa pagina noua in lista la --
- 15: buffer salvat --
- 16: buffer-ul -- s-a cules
- 17: se culege buffer-ul verbatim --
- 18: sinonimul -- -- nu exista
- 19: intelesul (sinonimele) pentru -- incarcat
- 20: intelesul (ordinea) pentru -- incarcat
- 21: nici o data utilitara nu este incarcata
- 22: folositi un fisier utilitar valid
- 23: -- aranjat la --
- 24: Blocuri
- 25: Referinte
- 26: Registri
- 27: Versiune
-\stopmessages
-
-\startmessages french library: systems
- title: système
- 1: chargement de fichier utilitaire reporté (typemode)
- 2: -- chargé
-% 3: try LaTeX
- 4: la commande -- est déjà définie
- 5: module -- chargé
- 6: module -- non trouvé
- 7: module -- déjà chargé
- 8: nouvelle version de fichier utilitaire, seconde passe nécessaire
- 9: -- non trouvé/traité
- 10: n'utilisez pas em dans --
- 11: construction util simple
- 12: le fichier utilitaire n'est pas trié, utilise texutil
- 13: marquage -- defini --
- 14: nouvellepage forcée dans la liste à --
- 15: sauvegarde du tampon (buffer) --
- 16: composition du tampon (buffer) --
- 17: composition textuelle du tampon (buffer) --
- 18: le synonyme -- -- n'existe pas
- 19: signification (synonymes) de -- chargée
- 20: signification (tris) de -- chargée
- 21: pas de données utilitaires chargées
- 22: utilise un fichier utilitaire valide
- 23: -- arrangé à --
- 24: blocsflottants
- 25: Réferences
- 26: Registres
- 27: Version
-\stopmessages
-
-\startmessages dutch library: layouts
- title: layout
- 1: teksthoogte aangepast met -- op pagina --
- 2: -- maal uitgestelde tekst tussengevoegd
- 3: -- maal tekst plaatsen uitstellen
- 4: margeblokken actief
- 5: margeblokken inactief
- 6: subpagina reeks -- verwerkt (aantal --)
-% 7: beeldmerken berekenen
-% 8: achtergronden berekenen
- 10: -- en -- tellen niet op tot 1.0
- 11: interlinie -- niet toegestaan in gridmode
-\stopmessages
-
-\startmessages english library: layouts
- title: layout
- 1: textheight adapted with -- at page --
- 2: -- times postponed text placed
- 3: -- times text postponed
- 4: marginblocks active
- 5: marginblocks inactive
- 6: subpage set -- processed (size --)
-% 7: calculating logospace
-% 8: calculating backgrounds
- 10: -- and -- don't add up to 1.0
- 11: spacing -- not permitted in gridmode
-\stopmessages
-
-\startmessages german library: layouts
- title: Layout
- 1: Texthoehe angepasst mit -- auf Seite --
- 2: -- mal verschobener Text plaziert
- 3: -- mal Text verschoben
- 4: marginalbloecke aktiv
- 5: marginalbloecke inaktiv
- 6: Unterseitenfolge -- verarbeitet (Groesse --)
-% 7: berechne Platz des Logo
-% 8: berechne Hintergrund
- 10: -- und -- ergeben zusammen nicht 1.0
- 11: Zwischenraum -- nicht im Grittermoduserlau
-\stopmessages
-
-\startmessages czech library: layouts
- title: layout
- 1: vyska textu prizpusobena s -- na strane --
- 2: -- krat odlozeny text umisten
- 3: -- krat text odlozen
- 4: okrajove bloky aktivni
- 5: okrajove bloky neaktivni
- 6: sada stran -- zpracovana (velikost --)
-% 7: pocita se misto pro logo
-% 8: pocita se pozadi
- 10: -- a -- nedava dohromady 1.0
- 11: svisla mezera -- neni povolena v pevnem radkovem rejstriku
-\stopmessages
-
-\startmessages italian library: layouts
- title: layout
- 1: altezza del testo adattata con -- a pagina --
- 2: posizionato testo posticipato -- volte
- 3: testo posticipato -- volte
- 4: blocchi in margine attivi
- 5: blocchi in margine inattivi
- 6: gruppo di sottopagine -- elaborato (dimensione --)
-% 7: calcolo dello spazio per logo
-% 8: calcolo dello sfondo
- 10: -- e -- non sommano a 1.0
- 11: spaziatura -- non permessa in modo griglia
-\stopmessages
-
-\startmessages norwegian library: layouts
- title: layout
- 1: teksthøyde tilpasset med -- på side --
- 2: -- ganger forskjøvet tekst plassert
- 3: -- ganger tekst forskjøvet
- 4: margblokker aktive
- 5: margblokker inaktive
- 6: delside sett -- behandlet (størrelse --)
-% 7: beregner plass for logo
-% 8: beregner bakgrunn
- 10: -- og -- er ikke 1.0 til sammen
- 11: mellomrom -- ikke tillatt i gridmodus
-\stopmessages
-
-\startmessages romanian library: layouts
- title: aranjamente
- 1: textheight adaptat cu -- la pagina --
- 2: textul amanat de -- ori a fost plasat
- 3: textul amanat de -- ori
- 4: blocuri marginale active
- 5: blocuri marginale inactive
- 6: setul -- de subpagini procesat (dimensiunea --)
-% 7: se calculeaza spatiul pentru logo
-% 8: se calculeaza fundalurile
- 10: -- si -- nu se adauga pana la 1.0
- 11: spatierea -- nu este permisa in gridmode
-\stopmessages
-
-\startmessages french library: layouts
- title: calque
- 1: hauteurtexte adaptée avec -- à la page --
- 2: -- times postponed text placed
- 3: -- times text postponed
- 4: blocsmarge actifs
- 5: blocsmarge inactifs
- 6: jeu de souspage -- traité (taille --)
-% 7: calculating logospace
-% 8: calculating backgrounds
- 10: -- et -- ne sont pas ajoutés à 1.0
- 11: espacement -- non permis en modegrille
-\stopmessages
\def\m!otr{otr}
@@ -420,7 +58,12 @@
\ifx\realpageno\undefined
- \countdef\realpageno\zerocount \realpageno\plusone
+ \countdef\realpageno = 0 \realpageno = 1
+ \countdef\userpageno = 1 \userpageno = 1
+ \countdef\subpageno = 2 \subpageno = 0 % !!
+ \countdef\arrangeno = 3 \arrangeno = 0 % !!
+
+ \let\pageno\userpageno
\fi
@@ -490,141 +133,21 @@
%
% tricky in balancing mode, a la huidige multi columns
-\startmessages dutch library: columns
- title: kolommen
- 1: maximaal -- kolommen
- 2: gebruik eventueel \string\filbreak
- 3: probleempje, probeer [balanceren=nee]
- 4: plaatsblok boven nog niet mogelijk
- 5: plaatsblok onder nog niet mogelijk
- 6: -- plaatsblok(en) opgeschort
- 7: balanceren afgebroken na 100 stappen
- 8: gebalanceerd in -- stap(pen)
- 9: uitlijnen controleren!
- 10: (minder dan) 1 regel over
- 11: plaatsblok te breed voor kolom
- 12: plaatsblok verplaatst naar volgende kolom / --
- 13: breed figuur geplaatst boven kolommen
-\stopmessages
-
-\startmessages english library: columns
- title: columns
- 1: only -- columns possible
- 2: use \string\filbreak\space as alternative
- 3: problems, disable balancing
- 4: top float not yet supported
- 5: bottom float not yet supported
- 6: -- float(s) postponed
- 7: balancing aborted after 100 steps
- 8: balanced in -- step(s)
- 9: check raggedness
- 10: (less than) 1 line left
- 11: float too wide for column
- 12: float moved to next column / --
- 13: wide float moved to top of columns
-\stopmessages
-
-\startmessages german library: columns
- title: Spalten
- 1: nur -- Spalten moeglich
- 2: benutzte \string\filbreak\space als Alternative
- 3: Problem, verwende [ausgleich=nein]
- 4: Gleitobjekt oben ncoh nicht unterstuetzt
- 5: Gleitobjekt unten ncoh nicht unterstuetzt
- 6: -- Gleitobjekt(e) verschoben
- 7: ausgleich nach 100 Schritten abgebrocheb
- 8: ausgeglichen nach -- Schritt(en)
- 9: Ausrichtung ueberpruefen
- 10: (weniger als) 1 Zeile uebrig
- 11: Gleitobjekt zu breit fuer Spalte
- 12: Gleitobjekt in naechste Zeile verschoben / --
- 13: breites Gleitobjekt an den Anfang der Spalten verschoben
-\stopmessages
-
-\startmessages czech library: columns
- title: sloupce
- 1: je mozno pouze -- sloupcu
- 2: pouzijte \string\filbreak\space jako alternativu
- 3: problem, vypina se vyvazovani
- 4: horni plovouci objekt jeste neni podporovan
- 5: spodni plovouci objekt jeste neni podporovan
- 6: -- plovouci objekt(y) odlozeny
- 7: vyvazovani ukonceno po 100 krocich
- 8: vyvazeno v -- krocich
- 9: kontrola nerovnost
- 10: zbyl (mene nez) 1 radek
- 11: plovouci objekt je pro sloupec prilis siroky
- 12: plovouci objekt je presunut do nasledujiciho sloupce / --
- 13: siroky plovouci objekt je presunut nad sloupce
-\stopmessages
-
-\startmessages italian library: columns
- title: colonne
- 1: solo -- colonne possibili
- 2: in alternativa, usare \string\filbreak
- 3: problemi, disabilitare il bilanciamento
- 4: float in cima non ancora supportato
- 5: float in fondo non ancora supportato
- 6: -- float(s) posticipate
- 7: bilanciamento annullato dopo 100 passi
- 8: bilanciamento in -- passo/i
- 9: controllare seghettamento
- 10: (meno di) una riga rimasta
- 11: oggetto mobile troppo ampio per la colonna
- 12: oggetto mobile spostata alla colonna successiva / --
- 13: oggetto mobile ampio spostato sopra le colonne
-\stopmessages
-
-\startmessages norwegian library: columns
- title: kolonner
- 1: maksimalt -- kolonner
- 2: bruk \string\filbreak\space som et alternativ
- 3: problemer, slår av balansering
- 4: flytblokker øverst er ikke støttet enda
- 5: flytblokker nedert er ikke støttet enda
- 6: -- flytblokk forskjøvet
- 7: balansering avbrutt etter 100 iterasjoner
- 8: balansert etter -- iterasjoner
- 9: kontroller tekstlayout!
- 10: (mindre enn) 1 linje igjen
- 11: flytblokk for bredt for kolonna
- 12: flytblokk forskjøvet til neste kolonne / --
- 13: bred flytblokk forksjøvet til toppen av kolonnene
-\stopmessages
-
-\startmessages romanian library: columns
- title: coloane
- 1: este posibil numai -- coloane
- 2: folositi \string\filbreak\space ca alternativa
- 3: probleme, se dezactiveaza alinierea
- 4: cadrele top (top float) nu sunt inca suportate
- 5: cadrele bottom (bottom float) nu sunt inca suportate
- 6: -- blocurile sunt amanate
- 7: alinierea este oprita dupa 100 de incercari
- 8: aliniat in -- pas(i)
- 9: verificat alinierea
- 10: a mai ramas (mai putin de) 1 linie
- 11: blocul este prea lat pentru coloana
- 12: blocul este mutat pe urmatoarea coloana / --
- 13: blocul lat este mutat in partea de sus a coloanelor
-\stopmessages
-
-\startmessages french library: columns
- title: colonnes
- 1: seules -- colonnes possibles
- 2: utilisez \string\filbreak\space en tant qu'alternative
- 3: problèmes, désactive l'équilibrage
- 4: flottant en partie supérieure pas encore supporté
- 5: flottant en partie inférieure pas encore supporté
- 6: -- flottant(s) reporté(s)
- 7: équilibrage abandonné après 100 pas
- 8: équilibré en -- pas
- 9: vérification des irrégularités
- 10: (moins de) 1 ligne restante
- 11: flottant mis à la largeur de la colonne
- 12: flottant déplacé à la colonne suivante / --
- 13: flottant large déplacé dans la partie supérieure de la colonne
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
\ifx\dosetuplayout\undefined % overloaded in page-lay !
@@ -636,8 +159,8 @@
\ifx\mkprocesspagecontents \undefined\let\mkprocesspagecontents \gobbleoneargument\fi
\ifx\mkprocessboxcontents \undefined\let\mkprocessboxcontents \gobbleoneargument\fi
-\def\normalejectpenalty{-\@M} \let\ejectpenalty\normalejectpenalty
-\def\normalsuperpenalty{-\@MM} \let\superpenalty\normalsuperpenalty
+\def\normalejectpenalty{-\plustenthousand } \let\ejectpenalty\normalejectpenalty
+\def\normalsuperpenalty{-\plustwentythousand} \let\superpenalty\normalsuperpenalty
%D In case we're not running \ETEX, we need to bypass a
%D couple of primitives.
@@ -707,7 +230,7 @@
\newtoks \mainoutput
\newcount\otrlevel
-% When issuing two \par\penalty-\@M's, only the first
+% When issuing two \par\penalty-\plustenthousand's, only the first
% triggers the otr; obscure feature or optimization?
\def\outputcounter{-100010} % -10010
@@ -919,8 +442,8 @@
% to be replaced by \page[now] \page[final] / merged
-% \def\eject {\par\penalty-\@M } % == {\par\break} % plain
-% \def\supereject {\par\penalty-\@MM} % also plain
+% \def\eject {\par\penalty-\plustenthousand } % == {\par\break} % plain
+% \def\supereject {\par\penalty-\plustwentythousand} % also plain
\def\eject {\par\ifvmode\penalty\ejectpenalty\fi\resetpagebreak} % == {\par\break} % plain
\def\supereject {\par\ifvmode\penalty\superpenalty\fi\resetpagebreak} % also plain
@@ -1382,7 +905,7 @@
% not here
-\newif\ifpaginageblokkeerd \paginageblokkeerdfalse
+\newif\ifpagebreakdisabled \pagebreakdisabledfalse
% \chardef\testpagemethod=0 % todo: \testnewpage[method=,lines=,voffset=]
%
@@ -1392,7 +915,7 @@
% \def\dotestpage[#1][#2][#3]%
% {%\relax % needed before \if
% \endgraf
-% \ifpaginageblokkeerd
+% \ifpagebreakdisabled
% % do nothing
% \else
% %ifnum#1=\plusone\synchronizeoutput\fi
@@ -1446,7 +969,7 @@
\def\dotestpage[#1][#2][#3]% don't change, only add more methods
{\relax % needed before \if
- \ifpaginageblokkeerd
+ \ifpagebreakdisabled
\endgraf
\else
% new from here
@@ -1545,7 +1068,7 @@
\def\page{\pagebreak} % the short form of \pagebreak (mult-com one)
\def\resetpagebreak
- {\global\paginageblokkeerdfalse}
+ {\global\pagebreakdisabledfalse}
\def\simplifypagebreak
{\def\dopagebreak[##1]{\goodbreak}}
@@ -1628,10 +1151,10 @@
\resetpagebreak}
\installpagebreakhandler \v!disable
- {\global\paginageblokkeerdtrue}
+ {\global\pagebreakdisabledtrue}
\installpagebreakhandler \v!yes
- {\ifpaginageblokkeerd\else
+ {\ifpagebreakdisabled\else
\ejectinsert
\gotonextpage
\ifinsidecolumns % this will move to MUL
@@ -1640,7 +1163,7 @@
\fi}
\installpagebreakhandler \v!makeup % ??
- {\ifpaginageblokkeerd\else
+ {\ifpagebreakdisabled\else
\eject
\fi}
@@ -1650,12 +1173,12 @@
\fi}
\installpagebreakhandler \v!no
- {\ifpaginageblokkeerd\else
+ {\ifpagebreakdisabled\else
\dosomebreak\nobreak
\fi}
\installpagebreakhandler \v!preference
- {\ifpaginageblokkeerd\else
+ {\ifpagebreakdisabled\else
\ifinsidecolumns % this will move to MUL
\dosomebreak\goodbreak
\else
@@ -1664,7 +1187,7 @@
\fi}
\installpagebreakhandler \v!bigpreference
- {\ifpaginageblokkeerd\else
+ {\ifpagebreakdisabled\else
\ifinsidecolumns % this will move to MUL
\dosomebreak\goodbreak
\else
@@ -1817,8 +1340,6 @@
% We don't want spurious last pages (due to left over marks):
-\ifx\undefined\normalshipout \let\normalshipout=\shipout \fi
-
\def\noshipout
{\writestatus\m!systems{ignoring further shipouts}%
\global\advance\realpageno\minusone % else no flush of resources
diff --git a/tex/context/base/page-ini.mkiv b/tex/context/base/page-ini.mkiv
new file mode 100644
index 000000000..4aedf171e
--- /dev/null
+++ b/tex/context/base/page-ini.mkiv
@@ -0,0 +1,1549 @@
+%D \module
+%D [ file=page-ini,
+%D version=2000.10.20,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Initializations,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Page Macros / Initializations}
+
+% still a dutch/english mess
+
+%D This class of modules implements the output routines and
+%D floating body support. Although the modules are relatively
+%D new, the code herein is rather old. This reordering was
+%D needed when column sets were implemented and sharing code
+%D started to make sense.
+
+%D The history shows from the code, since both column
+%D mechanism use a different way of looping over columns.
+
+\unprotect
+
+\def\m!otr{otr}
+
+\chardef\normalpagebox=255
+
+\newbox\pagebox
+
+\ifx\recalculatelayout\undefined
+
+ \let \recalculatelayout \relax
+
+\fi
+
+\ifx\recalculatelogos\undefined
+
+ \let \recalculatelogos \relax
+ \let \addlogobackground \gobbleoneargument % <box>
+
+\fi
+
+\ifx\recalculatebackgrounds\undefined
+
+ \let \recalculatebackgrounds \relax
+ \let \addmainbackground \gobbleoneargument % <box>
+ \let \addtextbackground \gobbleoneargument % <box>
+ \let \addpagebackground \gobbleoneargument % <box>
+ \let \addprintbackground \gobbleoneargument % <box>
+ \let \addstatusinfo \gobbleoneargument % <box>
+
+\fi
+
+\ifx\realpageno\undefined
+
+ \countdef\realpageno = 0 \realpageno = 1
+ \countdef\userpageno = 1 \userpageno = 1
+ \countdef\subpageno = 2 \subpageno = 0 % !!
+ \countdef\arrangeno = 3 \arrangeno = 0 % !!
+
+ \let\pageno\userpageno
+
+\fi
+
+\ifx\realfolio\undefined
+
+ \def\realfolio{\the\realpageno}
+
+\fi
+
+\newcount\nofshipouts
+
+\appendtoks
+ \global\advance\nofshipouts\plusone
+\to \everyaftershipout
+
+% principle:
+%
+% multiple otr's
+%
+% (1) single column, simple routine (old one)
+% (2) multi column, collect and split routine (old one)
+% (3) multi column, page by page (new one, needed for taco)
+% (4) single column, spread handling (for fun)
+% (5) multi column, page by page, spread handling (as challenge)
+%
+% common components
+%
+% (1) float placement
+% (2) float flushing
+% (3) page body building
+% (4) ...
+%
+% ort
+%
+% + balancing
+% - mixed / one / multi / balancetofit
+% + backgrounds
+% + pre / post
+% + distances / heights
+% + ragged / baseline / normal
+% - pos sync
+% - last page
+%
+% - itemize / subtexts -> old mechanism
+%
+% floats
+%
+% - top / bottom / side / page / column / spead
+% - flush / packed flush / current page / next page / area
+%
+% footnotes
+%
+% + carry over pre column / local to column
+% + last column / pre last column / each column
+% - multiple classes
+% - area / page / end
+%
+% areas
+%
+% - top / bottom / mid in spread
+%
+% IMPORTANT
+%
+% switchtobodyfont in between ivm top
+
+% floats:
+%
+% tricky in balancing mode, a la huidige multi columns
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+\ifx\dosetuplayout\undefined % overloaded in page-lay !
+
+ \def\setuplayout{\dodoubleempty\getparameters[\??ly]}
+
+\fi
+
+\ifx\mkprocesscolumncontents\undefined\let\mkprocesscolumncontents\gobbleoneargument\fi
+\ifx\mkprocesspagecontents \undefined\let\mkprocesspagecontents \gobbleoneargument\fi
+\ifx\mkprocessboxcontents \undefined\let\mkprocessboxcontents \gobbleoneargument\fi
+
+\def\normalejectpenalty{-\plustenthousand } \let\ejectpenalty\normalejectpenalty
+\def\normalsuperpenalty{-\plustwentythousand} \let\superpenalty\normalsuperpenalty
+
+%D In case we're not running \ETEX, we need to bypass a
+%D couple of primitives.
+
+% ONE = single column
+% MUL = multi column
+% SET = columns sets
+
+\def\@@OTR{OTR}
+
+\let\OTRdefault\empty
+
+\def\OTRcommand#1%
+ {\csname\@@OTR
+ \ifcsname\@@OTR\OTRidentifier\strippedcsname#1\endcsname
+ \OTRidentifier
+ \else\ifcsname\@@OTR\OTRdefault\strippedcsname#1\endcsname % fallback
+ \OTRdefault
+ \fi\fi
+ \strippedcsname#1\endcsname}
+
+% obsolete
+
+\def\installotr#1% andere naam, beter \connectotr of zo
+ {\def\OTRidentifier{#1}}
+
+\def\activateotr#1#2%
+ {\def\OTRidentifier{#1}%
+ \def\OTRdefault {#2}}
+
+%D The initialization of the \type {\hsize} and \type {\vsize}
+%D depends on the OTR used.
+
+\def\setvsize {\OTRcommand\setvsize}
+\def\sethsize {\OTRcommand\sethsize}
+\def\finalsidefloatoutput {\OTRcommand\finalsidefloatoutput}
+\def\dopagecontents {\OTRcommand\dopagecontents}
+
+\def\dosettopinserts {\OTRcommand\dosettopinserts}
+\def\dosetbotinserts {\OTRcommand\dosetbotinserts}
+\def\dotopinsertions {\OTRcommand\dotopinsertions}
+\def\dobotinsertions {\OTRcommand\dobotinsertions}
+\def\dosetbothinserts {\OTRcommand\dosetbothinserts}
+
+\def\doflushfloats {\OTRcommand\doflushfloats}
+\def\flushfloatbox {\OTRcommand\flushfloatbox}
+\def\docheckiffloatfits {\OTRcommand\docheckiffloatfits}
+
+\def\someherefloat {\OTRcommand\someherefloat}
+\def\somefixdfloat {\OTRcommand\somefixdfloat}
+\def\somepagefloat {\OTRcommand\somepagefloat}
+\def\sometopsfloat {\OTRcommand\sometopsfloat}
+\def\somebotsfloat {\OTRcommand\somebotsfloat}
+\def\somesidefloat {\OTRcommand\somesidefloat}
+
+\def\flushsavedfloats {\OTRcommand\flushsavedfloats}
+
+\def\synchronizehsize {\OTRcommand\synchronizehsize}
+
+\def\gotonextpage {\OTRcommand\gotonextpage }
+\def\gotonextpageX{\OTRcommand\gotonextpageX} % will become obsolete
+
+% beter een \installotr#1 met #1 = macro en auto test
+
+\newif \iftraceotr
+\newif \ifinotr
+\newtoks \mainoutput
+\newcount\otrlevel
+
+% When issuing two \par\penalty-\plustenthousand's, only the first
+% triggers the otr; obscure feature or optimization?
+
+\def\outputcounter{-100010} % -10010
+
+\def\doinvokeoutput
+ {\iftraceotr
+ \expandafter\dodotracedoutput
+ \else
+ \expandafter\dodoinvokeoutput
+ \fi}
+
+\def\outputmessage#1#2#3%
+ {\iftraceotr\writestatus\m!otr{#1 #2 \number#3}\fi}
+
+\def\dodoinvokeoutput#1%
+ {\outputmessage+{special}{#1}%
+ \bgroup\par\penalty#1\relax\egroup
+ \outputmessage-{special}{#1}}
+
+\def\dodotracedoutput#1%
+ {\outputmessage+{traced}{#1/\the\outputpenalty}%
+ \writestatus\m!otr{c:\number\mofcolumns,v:\the\vsize,g:\the\pagegoal,t:\the\pagetotal}%
+ \dodoinvokeoutput{#1}%
+ \writestatus\m!otr{c:\number\mofcolumns,v:\the\vsize,g:\the\pagegoal,t:\the\pagetotal}%
+ \outputmessage-{traced}{#1/\the\outputpenalty}}
+
+\def\installoutput#1#2% \invoke \action
+ {\decrement\outputcounter
+ \edef#1{\noexpand\doinvokeoutput{\outputcounter}}%
+ \setvalue{\@@OTR\outputcounter}{#2}}
+
+\def\invokeoutputroutine
+ {\outputmessage+{trying}\outputpenalty
+ \executeifdefined{\@@OTR\the\outputpenalty}\dodonormaloutput
+ \outputmessage-{trying}\outputpenalty}
+
+\def\dodonormaloutput
+ {\outputmessage+{normal}\outputpenalty
+ \the\OTRcommand\output
+ \outputmessage-{normal}\outputpenalty}
+
+\mainoutput{\invokeoutputroutine} \output{\inotrtrue\the\mainoutput}
+
+%D Some hooks:
+
+\output{\inotrtrue\the\everybeforeoutput\the\mainoutput\the\everyafteroutput}
+
+\ifx\pagediscards\undefined \let\pagediscards\relax \fi
+
+\installoutput\synchronizeoutput % maybe add pagediscards
+ {\ifvoid\normalpagebox\else
+ \unvbox\normalpagebox
+ \pagediscards % maybe not needed ?
+ \fi}
+
+\installoutput\discardpage
+ {\setbox\scratchbox\box\normalpagebox}
+
+%D In order to force consistent use of variables, we
+%D predefine a lot of them here.
+
+%D The next two registers can be used to store pre column
+%D material as well as footnotes or so.
+
+\newbox\precolumnbox \newdimen\precolumnboxheight
+\newbox\postcolumnbox \newdimen\postcolumnboxheight
+
+%D We reserve a counter for the number of columns as well as
+%D the current column. Both are not to be changed by users!
+
+\newcount\nofcolumns \nofcolumns = 1
+\newcount\mofcolumns \mofcolumns = 1
+
+\chardef\maxnofcolumns = 50
+\chardef\allocatednofcolumns = 0
+
+%D The next dimensions reports the final column height
+
+\newdimen\finalcolumnheights
+\newcount\finalcolumnlines
+
+%D During initialization the temporary boxes are allocated.
+%D This enables us to use as much columns as we want, without
+%D exhausting the pool of boxes too fast. We could have packed
+%D them in one box, but we've got enough boxes.
+%D
+%D Two sets of boxes are declared, the txtboxes are used for
+%D the text, the topboxes are for moved column floats.
+
+\def\@col@{@col@}
+
+\def\initializecolumns#1%
+ {\ifnum#1>\maxnofcolumns
+ \showmessage\m!columns1\maxnofcolumns
+ \nofcolumns\maxnofcolumns
+ \else
+ \nofcolumns#1\relax
+ \fi
+ \ifnum\nofcolumns>\allocatednofcolumns
+ \dorecurse\nofcolumns
+ {\ifnum\recurselevel>\allocatednofcolumns\relax
+ % \newbox\next \letgvalue{\@col@-\recurselevel-t}=\next
+ \@EA\newbox\csname\@col@-\recurselevel-t\endcsname % text
+ \@EA\newbox\csname\@col@-\recurselevel-f\endcsname % foot
+ \@EA\newbox\csname\@col@-\recurselevel-h\endcsname % top insert
+ \@EA\newbox\csname\@col@-\recurselevel-l\endcsname % top insert
+ \fi}%
+ \global\chardef\allocatednofcolumns=\nofcolumns
+ \fi}
+
+\def\firstcolumnbox {\columntextbox\plusone}
+\def\currentcolumnbox {\columntextbox\mofcolumns}
+\def\lastcolumnbox {\columntextbox\nofcolumns}
+
+\def\firsttopcolumnbox {\columntopbox \plusone}
+\def\currenttopcolumnbox{\columntopbox \mofcolumns}
+\def\lasttopcolumnbox {\columntopbox \nofcolumns}
+
+\def\columntextbox#1{\csname\@col@-\number#1-t\endcsname}
+\def\columnfootbox#1{\csname\@col@-\number#1-f\endcsname}
+\def\columntopbox #1{\csname\@col@-\number#1-h\endcsname}
+\def\columnbotbox #1{\csname\@col@-\number#1-l\endcsname}
+
+\def\columnsettextbox{\global\setbox\columntextbox}
+\def\columnsetfootbox{\global\setbox\columnfootbox}
+\def\columnsettopbox {\global\setbox\columntopbox}
+\def\columnsetbotbox {\global\setbox\columnbotbox}
+
+\def\columngettextbox{\copy\columntextbox}
+\def\columngetfootbox{\copy\columnfootbox}
+\def\columngettopbox {\copy\columntopbox}
+\def\columngetbotbox {\copy\columnbotbox}
+
+\def\columnerasetextboxes{\dorecurse\allocatednofcolumns{\columnsettextbox\recurselevel\emptybox}}
+\def\columnerasefootboxes{\dorecurse\allocatednofcolumns{\columnsetfootbox\recurselevel\emptybox}}
+\def\columnerasetopboxes {\dorecurse\allocatednofcolumns{\columnsettopbox \recurselevel\emptybox}}
+\def\columnerasebotboxes {\dorecurse\allocatednofcolumns{\columnsetbotbox \recurselevel\emptybox}}
+
+%D Without going in details we present two macro's which handle
+%D the columns. The action which is transfered by the the first
+%D and only parameter can do something with \type
+%D {\currentcolumnbox}. In case of the mid columns, \type
+%D {\firstcolumnbox} and \type {\lastcolumnbox} are handled
+%D outside these macro's.
+
+\def\dohandlecolumn#1%
+ {\mofcolumns\recurselevel
+ \let\currentcolumn\recurselevel
+ #1\relax}
+
+\def\dohandleallcolumns#1%
+ {\dorecurse\nofcolumns{\dohandlecolumn{#1}}}
+
+\def\dohandlerevcolumns#1%
+ {\dostepwiserecurse\nofcolumns\plusone\minusone{\dohandlecolumn{#1}}}
+
+\def\dohandlemidcolumns#1%
+ {\dohandleallcolumns
+ {\ifnum\recurselevel>\plusone
+ \ifnum\recurselevel<\nofcolumns
+ \dohandlecolumn{#1}%
+ \fi
+ \fi}}
+
+%D This register can be used as a temporary storage for page
+%D content.
+
+\newbox\restofpage
+
+%D Features.
+
+\newif\ifintermediatefootnotes
+\newif\ifcarryoverfootnotes %\carryoverfootnotestrue
+\newif\iflastcolumnfootnotes %\lastcolumnfootnotestrue
+\newif\ifbalancecolumns %\balancecolumnstrue
+\newif\ifbalancetoheight %\balancetoheighttrue
+\newif\ifforcecolumngrid \forcecolumngridtrue
+\newif\ifstretchcolumns \stretchcolumnsfalse
+\newif\ifinheritcolumns \inheritcolumnsfalse
+\newif\ifheightencolumns \heightencolumnsfalse
+
+\newif\ifbalancingcolumns
+\newif\ifcollectingcontent
+\newif\ifcolumnoverflow
+\newif\iffinalflushingfloats
+\newif\ifpackflushedfloats \packflushedfloatstrue % for the moment
+
+\newdimen\intercolumnwidth
+\newdimen\localcolumnwidth
+\newdimen\savedpagetotal
+
+\chardef\columndirection=0 % 0:lr 1:rl
+
+\def\minbalancetoplines {1}
+\def\minfreecolumnlines {2}
+
+\newif\ifrecentercolumnbox \recentercolumnboxtrue
+\newif\ifrerecentercolumnbox \rerecentercolumnboxtrue
+\newif\ifpackcolumnfloats \packcolumnfloatstrue
+
+\newbox\collectedpagefloats
+\newbox\collectedleftpagefloats
+\newbox\collectedrightpagefloats
+
+%D The \type {\ifdim} test is needed, because otherwise the
+%D last line of a text end up on top of the baseline instead of
+%D on the baseline, as is the case with preceding pages.
+%D Also, a \type {\vfil} better than a \type {\vfill}.
+
+% to be replaced by \page[now] \page[final] / merged
+
+% \def\eject {\par\penalty-\plustenthousand } % == {\par\break} % plain
+% \def\supereject {\par\penalty-\plustwentythousand} % also plain
+
+\def\eject {\par\ifvmode\penalty\ejectpenalty\fi\resetpagebreak} % == {\par\break} % plain
+\def\supereject {\par\ifvmode\penalty\superpenalty\fi\resetpagebreak} % also plain
+
+\def\doejectpage {\par\ifvmode\ifdim\pagetotal>\pagegoal\else\normalvfil\fi\fi} % pg set to \textheight
+\def\ejectpage {\doejectpage\eject}
+\def\superejectpage{\doejectpage\supereject}
+
+\ifx\bye\undefined \def\bye{\par\vfill\supereject\end} \fi % plain tex command
+
+% floats
+%
+% \def\ejectinsert
+% {\flushnotes
+% \bgroup
+% \noftopfloats\plusthousand
+% \nofbotfloats\zerocount
+% \doflushfloats
+% \egroup}
+
+\def\ejectinsert
+ {\flushnotes
+ \bgroup
+ \noftopfloats\plusthousand
+ \nofbotfloats\zerocount
+ % this is needed in case a float that has been stored
+ % ends up at the current page; this border case occurs when
+ % the calculated room is 'eps' smaller that the room available
+ % when just flushing; so now we have (maybe optional):
+ \pagebaselinecorrection
+ % alas, this is tricky but needed (first surfaced in prikkels)
+ \doflushfloats
+ \egroup}
+
+\def\ejectdummypage
+ {\endgraf \ifvmode
+ \ejectinsert
+ \hardespatie % will be different
+ \vfill
+ \gotonextpage
+ \fi}
+
+\def\beforefinaloutput
+ {}
+
+\def\afterfinaloutput
+ {\forgetall
+ \vskip\zeropoint\relax
+ \ifvoid\normalpagebox \else
+ \unvbox\normalpagebox
+ \penalty\outputpenalty
+ \fi
+ % not really needed, replaced by \flushsavedfloats
+ \ifnum\outputpenalty>\superpenalty \else % better use a proper otr signal
+ \dosupereject
+ \fi
+ % but does not hurt either (we're still in the otr!)
+ \inpagebodytrue % needed for enabling \blank !
+ \flushsavedfloats % was \dosetbothinserts; only otr one !
+ \setvsize % this is needed for interacting components, like floats and multicolumns
+ \adaptfuzzypagegoal} % watch this hack!
+
+\def\dofinaloutput#1#2% \vbox: prevents spurious spaces in every..pagebody
+ {\beforefinaloutput
+ \the\everybeforeshipout % brrr not in shipout
+ \the\pageboundsettings
+ \myshipout{\hbox{\vbox{\dopagebody#1#2\setpagecounters}}}%
+ \the\everyaftershipout
+ \afterfinaloutput
+ \popproperties} % ... and here ...
+
+\def\donofinaloutput#1#2%
+ {\beforefinaloutput
+ \the\everybeforeshipout
+ \setpagecounters
+ \message{[-\the\realpageno]}%
+ \setbox\scratchbox\hbox
+ {%\the\everyshipout % still needed here ?
+ \dopagebody#1#2}%
+ \deadcycles\zerocount
+ \gotonextrealpage
+ \the\everyaftershipout
+ \afterfinaloutput
+ \popproperties} % ... and here
+
+% beware: \ifprocessingpages is in use
+
+\ifx\checkpageversion\undefined \let\checkpageversion\relax \fi % todo: hook into \everybeforeshipout
+\ifx\doflushspread \undefined \let\doflushspread \relax \fi % todo
+
+\def\finaloutput#1#2%
+ {\checkpageversion
+ \ifprocessingpages
+ \ifpageselected
+ \@EAEAEA\dofinaloutput
+ \else
+ \@EAEAEA\donofinaloutput
+ \fi
+ \else
+ \ifpageselected
+ \@EAEAEA\donofinaloutput
+ \else
+ \@EAEAEA\dofinaloutput
+ \fi
+ \fi#1#2%
+ \resetselectiepagina
+ \incrementpagenumber
+ \checkpagedimensions
+ \ifnum\outputpenalty>\superpenalty \else
+ \dosupereject
+ \fi
+ \doflushspread
+ \dopostponeblock}
+
+\def\dooutput
+ {\finaloutput\unvbox\normalpagebox}
+
+\maxdeadcycles=1000
+
+% will be installable tracer; better use chardef
+
+% this needs a real cleanup
+
+\def\doplaceversiontext#1#2%
+ {\doifsomething{#2}
+ {\defconvertedcommand\ascii{#2}%
+ \space#1:\space\ascii\space
+ \!!doneatrue}}
+
+\def\placeversioninfo % nog engels maken
+ {\ifcase\conceptmode
+ % 0 : nothing
+ \or
+ % 1 : simple
+ \vskip\!!sixpoint
+ \hbox to \makeupwidth
+ {\infofont
+ \v!concept:\space\currentdate
+ \hss\reportpagedimensions}%
+ \else
+ % 2/3 : extensive
+ \vskip\!!sixpoint
+ \hbox to \makeupwidth
+ {\infofont
+ \getmessage\m!systems{27}:\space\currentdate\space
+ \doplaceversiontext\v!project \currentproject
+ \doplaceversiontext\v!product \currentproduct
+ \doplaceversiontext\v!component\currentcomponent
+ \if!!donea\else\space\v!file:\space\jobname\fi
+ \hss\reportpagedimensions}%
+ \fi}
+
+% tot hier
+
+\def\doversion[#1]%
+ {\chardef\conceptmode\zerocount
+ \overfullrule\zeropoint
+ \processaction % \v!final=>
+ [#1]
+ [ \v!concept=>\chardef\conceptmode\plusone, % simple banner
+ \v!file=>\chardef\conceptmode\plustwo, % full banner
+ \v!temporary=>\chardef\conceptmode\plusthree % full banner plus
+ \overfullrule5\points]} % info in the margin
+
+\def\version
+ {\dosingleargument\doversion}
+
+\def\addstatusinfo
+ {\ifcase\conceptmode
+ \@EA\gobbleoneargument
+ \else
+ \@EA\doaddstatusinfo
+ \fi}
+
+\def\doaddstatusinfo#1%
+ {\setbox#1\vbox to \paperheight
+ {\vsmashbox#1\box#1%
+ \offinterlineskip
+ \vskip\topspace
+ \hsize\paperwidth
+ \hfill\hbox{\placetestinfo\hskip.5cm}\vss
+ \settexthoffset\hskip\texthoffset % brrrr
+ %\tlap{\placeversioninfo}\vskip.5cm
+ \vbox to 1cm{\vss\placeversioninfo\vss}}}
+
+\def\dotestinfo#1#2#3%
+ {\ifinpagebody\else\ifnum\conceptmode=\plusthree
+ \begingroup
+ \defconvertedcommand\ascii{#3}%
+ \xdef\extratestinfo
+ {#2\space\ascii}%
+ \gdef\totaltestinfo
+ {\global\setbox#1\vbox
+ {\unvbox#1\relax
+ \infofont \setupinterlinespace
+ \hbox
+ {\strut
+ \expanded{\doboundtext{\extratestinfo}{12em}{..}}%
+ \quad}}}%
+ \endgroup
+ \ifinner
+ \aftergroup\totaltestinfo
+ \else
+ \totaltestinfo
+ \fi
+ \fi\fi}
+
+% this will be inserts some day
+
+% \installinsertion\referenceinfobox
+% \installinsertion\registerinfobox
+% \installinsertion\floatinfobox
+
+\newbox\referenceinfobox
+\newbox\registerinfobox
+\newbox\floatinfobox
+
+\def\referenceinfo{\dotestinfo\referenceinfobox}
+\def\registerinfo {\dotestinfo\registerinfobox}
+\def\floatinfo {\dotestinfo\floatinfobox}
+
+\def\placetestinfo
+ {\vbox to \makeupheight
+ {\forgetall
+ \infofont
+ \hsize10em
+ \ifvoid\floatinfobox\else
+ \strut \getmessage\m!systems{24}%
+ \vskip\!!sixpoint
+ \unvbox\floatinfobox
+ \vskip\!!twelvepoint
+ \fi
+ \ifvoid\referenceinfobox\else
+ \strut \getmessage\m!systems{25}%
+ \vskip\!!sixpoint
+ \unvbox\referenceinfobox
+ \vskip\!!twelvepoint
+ \fi
+ \ifvoid\registerinfobox\else
+ \strut \getmessage\m!systems{26}%
+ \vskip\!!sixpoint
+ \unvbox\registerinfobox
+ \fi
+ \vss}}
+
+\version[\v!final]
+
+% bewaren tvb documentatie
+%
+% \hbox to \hsize
+% {\en
+% \switchnaarkorps[5pt]%
+% \emergencystretch2em
+% \dimen0=\baselineskip
+% \baselineskip=\dimen0 plus 1pt
+% \hsize=.2\hsize
+% \vsize=2\hsize
+% \ruledvbox to \vsize{\input tufte \par}\hss
+% \ruledvbox to \vsize{\input tufte \par\kern-\prevdepth}\hss
+% \ruledvbox to \vsize{\input tufte \par\kern0pt}\hss
+% \ruledvbox to \vsize{\input tufte \par\vfill}\hss
+% \ruledvbox to \vsize{\input tufte \par\kern-\prevdepth\vfill}}
+%
+% \hbox to \hsize
+% {\en
+% \switchnaarkorps[5pt]%
+% \emergencystretch2em
+% \dimen0=\baselineskip
+% \baselineskip=\dimen0 plus 1pt
+% \hsize=.18\hsize
+% \vsize=2.5\hsize
+% \setbox0=\vbox{\input tufte\relax}%
+% \ruledvbox to \vsize{\unvcopy0}\hss
+% \ruledvbox to \vsize{\unvcopy0\kern-\dp0}\hss
+% \ruledvbox to \vsize{\unvcopy0\kern0pt}\hss
+% \ruledvbox to \vsize{\unvcopy0\vfill}\hss
+% \ruledvbox to \vsize{\unvcopy0\kern-\dp0\vfill}}
+
+\newtoks\afterpage \newtoks\aftereverypage
+\newtoks\beforepage \newtoks\beforeeverypage
+
+\chardef\showgridstate=0
+
+\def\showgrid
+ {\dosingleempty\doshowgrid}
+
+\def\doshowgrid[#1]%
+ {\chardef\showgridstate \plusone % downward compatible default
+ \chardef\gridboxlinemode \plusone
+ \chardef\gridboxlinenomode\plusone
+ \processallactionsinset
+ [#1]%
+ [ \v!reset=>\chardef\showgridstate \zerocount,
+ \v!bottom=>\chardef\showgridstate \plusone,
+ \v!top=>\chardef\showgridstate \plustwo,
+ \v!none=>\chardef\gridboxlinemode \zerocount,
+ \v!all=>\chardef\gridboxlinemode \plusone,
+ \v!lines=>\chardef\gridboxlinemode \plustwo,
+ \v!frame=>\chardef\gridboxlinemode \plusthree,
+ \v!nonumber=>\chardef\gridboxlinenomode\zerocount,
+ \v!right=>\chardef\gridboxlinenomode\plusone,
+ \v!left=>\chardef\gridboxlinenomode\plustwo]}
+
+\def\buildpagebox#1%
+ {\setbox#1\vbox to \paperheight
+ {\hsize\paperwidth
+ \vskip\topspace
+ \doifbothsides
+ {\hskip\backspace}
+ {\hskip\backspace}
+ {\hskip\paperwidth \hskip-\backspace \hskip-\makeupwidth}%
+ \box#1}%
+ \dp#1\zeropoint}
+
+% \newif\ifpagebodyornaments \pagebodyornamentstrue
+%
+% \appendtoks
+% \global\pagebodyornamentstrue
+% \to \everyaftershipout
+
+\newif\ifarrangingpages \arrangingpagesfalse
+
+\chardef\pageornamentstate\zerocount % 0=on 1=one-off 2=always-off
+
+\def\pagebodyornamentstrue {\chardef\pageornamentstate\zerocount} % for a while
+\def\pagebodyornamentsfalse{\chardef\pageornamentstate\plusone} % for a while
+
+\appendtoks
+ \ifcase\pageornamentstate\or
+ \chardef\pageornamentstate\zerocount
+ \fi
+\to \everyaftershipout
+
+\let\poparrangedpages\relax
+\let\pusharrangedpage\relax
+
+\ifx\shiftprintpagebox\undefined
+ \let\shiftprintpagebox\gobbleoneargument
+ \let\shiftpaperpagebox\gobbleoneargument
+\fi
+
+\ifx\registerpageposition\undefined
+ \let\registerpageposition\gobbleoneargument
+\fi
+
+\def\reportarrangedpage#1%
+ {\showmessage\m!systems
+ {23}{\the\realpageno.\the\pageno\ifnum\subpageno>0 .\the\subpageno\fi,#1}}
+
+\newif\ifsavepagebody \newbox\savedpagebody
+
+% beware, \??ly is used before defined, i.e. bad module design
+
+\setuplayout[\c!method=\v!normal]
+
+\def\buildpagebody#1#2%
+ {\ifsavepagebody\global\setbox\savedpagebody\fi
+ \vbox
+ {\beginrestorecatcodes
+ \forgetall % igv problemen, check: \boxmaxdepth\maxdimen
+ \boxmaxdepth\maxdimen % new
+ \dontcomplain
+ % the following plugin uses and sets pagebox; beware: this
+ % will change and is for my (hh) personal experiments
+ \executeifdefined{\??ly\c!method\@@lymethod}%
+ {\getvalue{\??ly\c!method\v!normal}}#1#2%
+ % the finishing touch
+ \ifcase\pageornamentstate
+ \addpagebackground \pagebox
+ \fi
+ \registerpageposition\pagebox
+ \ifarrangingpages
+ \shiftpaperpagebox \pagebox % \v!paper
+ \else
+ \clippagebox \pagebox
+ \addpagecutmarks \pagebox
+ \replicatepagebox \pagebox
+ \scalepagebox \pagebox
+ \mirrorpaperbox \pagebox
+ \orientpaperbox \pagebox
+ \addpagecolormarks \pagebox
+ \centerpagebox \pagebox
+ \addprintbackground\pagebox
+ \mirrorprintbox \pagebox
+ \orientprintbox \pagebox
+ \shiftprintpagebox \pagebox % \v!page
+ \offsetprintbox \pagebox
+ \negateprintbox \pagebox
+ \fi
+ \box\pagebox
+ \endrestorecatcodes}%
+ \ifsavepagebody\copy\savedpagebody\fi}
+
+\setvalue{\??ly\c!method\v!normal}#1#2%
+ {\setbox\pagebox\vbox
+ {\offinterlineskip
+ \ifcase\pageornamentstate
+ \bgroup % else footnotes get inconsistent font/baseline
+ \dostartattributes\??ly\c!style\c!color\empty
+ \offinterlineskip
+ \gettextboxes
+ \dostopattributes
+ \egroup
+ \fi
+ \getmainbox#1#2}% including footnotes
+ \ifcase\pageornamentstate
+ \addmainbackground \pagebox
+ \addlogobackground \pagebox
+ \fi
+ \buildpagebox \pagebox
+ \addstatusinfo \pagebox}
+
+\def\finishpagebox#1%
+ {\ifarrangingpages
+ \addpagecutmarks #1%
+ \addpagecolormarks#1%
+ \centerpagebox #1%
+ \mirrorprintbox #1%
+ \orientprintbox #1%
+ \offsetprintbox #1%
+ \negateprintbox #1%
+ \fi}
+
+\appendtoks \restoreglobalbodyfont \to \everybeforepagebody
+\appendtoks \restorecolumnsettings \to \everybeforepagebody
+
+\ifx\nestednewbox\undefined \newbox\nestednextbox \fi
+
+\prependtoks \let\nextbox\nestednextbox \to \everybeforepagebody
+
+\def\dopagebody#1#2%
+ {%\getallmarks % now in following token register
+ \the\everybeforepagebody
+ \starttextproperties
+ \gotonextsubpage % nog eens: als in pagina (tbv standaard opmaak)
+ \dontshowboxes % dan hier blokkeren en verderop resetten
+% \shipoutfacingpage
+ \checkmargeblokken
+ \the\beforeeverypage
+ \flushtoks\beforepage
+ \inpagebodytrue\buildpagebody#1#2%
+ \flushtoks\afterpage
+ \the\aftereverypage
+ \resetpagebreak
+ %updatelistreferences % now in aftereverypage
+ \resetlayouttextlines % will go to \aftereverypage
+ \stoptextproperties
+ \the\everyafterpagebody}
+
+\newtoks\pageboundsettings
+
+\prependtoks \initializepaper \to \pageboundsettings
+
+% not here
+
+\newif\ifpagebreakdisabled \pagebreakdisabledfalse
+
+% \chardef\testpagemethod=0 % todo: \testnewpage[method=,lines=,voffset=]
+%
+% \def\testpage {\dotripleempty\dotestpage[\plusone]}
+% \def\testpageonly{\dotripleempty\dotestpage[\plustwo]}
+%
+% \def\dotestpage[#1][#2][#3]%
+% {%\relax % needed before \if
+% \endgraf
+% \ifpagebreakdisabled
+% % do nothing
+% \else
+% %ifnum#1=\plusone\synchronizeoutput\fi
+% \ifdim\pagegoal<\maxdimen \relax
+% \ifdim\pagetotal<\pagegoal \relax
+% \scratchdimen\lineheight
+% \multiply\scratchdimen#2\relax
+% \advance\scratchdimen \pagetotal
+% \ifdim\lastskip<\parskip
+% \advance\scratchdimen \parskip
+% \fi
+% \ifthirdargument
+% \advance\scratchdimen#3\relax
+% \fi
+% \ifcase\testpagemethod
+% \ifdim\scratchdimen>.99\pagegoal
+% \vfill\eject % \penalty-\!!tenthousand\relax
+% \fi
+% \or
+% \advance\scratchdimen-\pagegoal
+% \ifdim\scratchdimen>-\lineheight
+% \vfill\eject % \penalty-\!!tenthousand\relax
+% \fi
+% \or
+% \getnoflines\pagegoal
+% \advance\scratchdimen-\noflines\lineheight \relax
+% \ifdim\scratchdimen>-\lineheight
+% \vfill\eject % \penalty-\!!tenthousand\relax
+% \fi
+% \or % same as 0 but more accurate
+% \advance\scratchdimen-10\s!sp\relax
+% \ifdim\scratchdimen>\pagegoal
+% \vfill\eject % \penalty-\!!tenthousand\relax
+% \fi
+% \fi
+% \else
+% % force page break / new
+% % \vfill\eject % \penalty-\!!tenthousand\relax
+% \fi
+% \else
+% \ifnum#1=\plusone\goodbreak\fi
+% \fi
+% \fi}
+
+\chardef\testpagemethod \zerocount % todo: \testnewpage[method=,lines=,voffset=]
+\chardef\testpagetrigger\zerocount
+
+\def\testpage {\dotripleempty\dotestpage[\plusone ]} %
+\def\testpageonly{\dotripleempty\dotestpage[\plustwo ]} % no penalties added to the mvl
+\def\testpagesync{\dotripleempty\dotestpage[\plusthree]} % force sync
+
+\def\dotestpage[#1][#2][#3]% don't change, only add more methods
+ {\relax % needed before \if
+ \ifpagebreakdisabled
+ \endgraf
+ \else
+ % new from here
+ \ifcase\testpagetrigger
+ \endgraf
+ \or
+ \ifvmode
+ \dosomebreak\allowbreak
+ \else % indeed?
+ \vadjust{\allowbreak}%
+ \endgraf
+ \fi
+ \fi
+ % till here
+ \ifdim\pagegoal<\maxdimen \relax
+ \ifdim\pagetotal<\pagegoal \relax
+ \scratchdimen\lineheight
+ \multiply\scratchdimen#2\relax
+ \advance\scratchdimen \pagetotal
+ \ifdim\lastskip<\parskip
+ \advance\scratchdimen \parskip
+ \fi
+ \ifthirdargument
+ \advance\scratchdimen#3\relax
+ \fi
+ \ifcase\testpagemethod
+ \ifdim\scratchdimen>.99\pagegoal
+ \penalty-\!!tenthousand\relax
+ \fi
+ \or
+ \advance\scratchdimen-\pagegoal
+ \ifdim\scratchdimen>-\lineheight
+ \penalty-\!!tenthousand\relax
+ \fi
+ \or
+ \getnoflines\pagegoal
+ \advance\scratchdimen-\noflines\lineheight \relax
+ \ifdim\scratchdimen>-\lineheight
+ \penalty-\!!tenthousand\relax
+ \fi
+ \or % same as 0 but more accurate
+ \advance\scratchdimen-10\s!sp\relax
+ \ifdim\scratchdimen>\pagegoal
+ \penalty-\!!tenthousand\relax
+ \fi
+ \fi
+ \else
+ \ifnum#1=\plusthree
+ \flushpagesofar
+ \fi
+ \fi
+ \else
+ \ifnum#1=\plusone\goodbreak\fi
+ \fi
+ \fi}
+
+\def\flushpagesofar
+ {\endgraf
+ \ifdim\pagetotal>\pagegoal
+ \ifdim\dimexpr\pagetotal-\pageshrink\relax>\pagegoal
+ \goodbreak % \penalty0
+ \else
+ \page
+ \fi
+ \else
+ \fi}
+
+\def\testcolumn
+ {\dodoubleempty\dotestcolumn}
+
+\def\dotestcolumn[#1][#2]%
+ {%\relax % needed before \if !
+ \endgraf
+ \ifdim\pagegoal<\maxdimen \ifdim\pagetotal<\pagegoal % \relax
+ \scratchdimen\pagegoal
+ \advance\scratchdimen-\pagetotal
+ \ifdim\lastskip<\parskip
+ \advance\scratchdimen \parskip
+ \fi
+ \ifsecondargument
+ \advance\scratchdimen#2%
+ \fi
+ \getrawnoflines\scratchdimen % raw !
+ % \message{[\number#1>\number\noflines ?}\wait
+ \ifnum#1>\noflines
+ \column
+ \fi
+ \else
+ \penalty-\!!tenthousand % untested ! ! \column
+ \fi \fi}
+
+\let\resetcurrentsectionmarks\relax
+
+% was: \resetsectionmarks\firstsection, zie \handlepagebreak
+
+\def\page{\pagebreak} % the short form of \pagebreak (mult-com one)
+
+\def\resetpagebreak
+ {\global\pagebreakdisabledfalse}
+
+\def\simplifypagebreak
+ {\def\dopagebreak[##1]{\goodbreak}}
+
+\def\disablepagebreaks
+ {\def\dopagebreak[##1]{}}
+
+\def\executepagebreakhandler#1%
+ {\edef\@@pagespecification{#1}%
+ \doifdefinedelse{\??pe:\@@pagespecification}
+ {\getvalue{\??pe:\@@pagespecification}}
+ {\doifdefinedelse{\??pe::\@@pagespecification}
+ {\executepagebreakhandlers{\getvalue{\??pe::\@@pagespecification}}}
+ {\getvalue{\??pe:\s!unknown}}}}
+
+\long\def\installpagebreakhandler#1#2%
+ {\long\setvalue{\??pe:#1}{#2}}
+
+% \definecomplexorsimple\pagebreak
+
+% \def\simplepagebreak
+% {\executepagebreakhandler\v!ja}
+
+% \def\complexpagebreak[#1]% if empty, do nothing and avoid processing,
+% {\flushnotes % see head's; watch how we group
+% \doifsomething{#1}{\bgroup\executepagebreakhandlers{#1}\egroup}}
+
+\unexpanded\def\pagebreak
+ {\dosingleempty\dopagebreak}
+
+\def\dopagebreak[#1]% so, page ornaments are reset after a pagebreak command, unless set
+ {\bgroup
+ \edef\prevrealpageno{\the\realpageno}%
+ \ifcase\pageornamentstate \or
+ % disable reset after shipout
+ \global\chardef\pageornamentstate\plustwo
+ \fi
+ \iffirstargument % or if empty i.e. []
+ \flushnotes\executepagebreakhandlers{#1}%
+ \else % so, no pagebreak when \pagebreak[] ! ! !
+ \flushnotes\executepagebreakhandler\v!yes
+ \fi
+ \ifnum\prevrealpageno<\realpageno
+ \global\chardef\pageornamentstate\zerocount
+ \fi
+ \egroup}
+
+\def\executepagebreakhandlers#1%
+ {\processcommacommand[#1]\executepagebreakhandler}
+
+\installpagebreakhandler \s!dummy
+ {\ejectinsert
+ \gotonextpage
+ \ejectdummypage}
+
+\installpagebreakhandler \v!frame
+ {\page\bgroup\showframe\page[\v!empty]\egroup}
+
+\installpagebreakhandler \s!unknown
+ {\doifinstringelse{+}\@@pagespecification
+ {\ejectinsert
+ \gotonextpage
+ \dorecurse\@@pagespecification\ejectdummypage}
+ {\doifnumberelse\@@pagespecification
+ {\ejectinsert
+ \gotonextpage
+ \doloop
+ {\ifnum\userpageno<\@@pagespecification\relax
+ \ejectdummypage
+ \else
+ \exitloop
+ \fi}}
+ {}}}
+
+\installpagebreakhandler \s!default
+ {} % do nothing if empty
+
+\installpagebreakhandler \v!reset
+ {% better not: \global\chardef\pageornamentstate\zerocount
+ \resetpagebreak}
+
+\installpagebreakhandler \v!disable
+ {\global\pagebreakdisabledtrue}
+
+\installpagebreakhandler \v!yes
+ {\ifpagebreakdisabled\else
+ \ejectinsert
+ \gotonextpage
+ \ifinsidecolumns % this will move to MUL
+ \ejectpage % anders soms geen overgang
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!makeup % ??
+ {\ifpagebreakdisabled\else
+ \eject
+ \fi}
+
+\installpagebreakhandler \v!blank
+ {\ifcase\pageornamentstate
+ \global\chardef\pageornamentstate\plusone
+ \fi}
+
+\installpagebreakhandler \v!no
+ {\ifpagebreakdisabled\else
+ \dosomebreak\nobreak
+ \fi}
+
+\installpagebreakhandler \v!preference
+ {\ifpagebreakdisabled\else
+ \ifinsidecolumns % this will move to MUL
+ \dosomebreak\goodbreak
+ \else
+ \testpage[3][\zeropoint]%
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!bigpreference
+ {\ifpagebreakdisabled\else
+ \ifinsidecolumns % this will move to MUL
+ \dosomebreak\goodbreak
+ \else
+ \testpage[5][\zeropoint]%
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!empty
+ {\ejectinsert
+ \gotonextpage
+ \doifnotvalue{\??tk\v!header\c!state}\v!stop{\setupheader[\c!state=\v!empty]}%
+ \doifnotvalue{\??tk\v!footer\c!state}\v!stop{\setupfooter[\c!state=\v!empty]}%
+ \ejectdummypage}
+
+\installpagebreakhandler \v!left
+ {\ejectinsert
+ \gotonextpageX % will become \gotonextpage
+ \doifbothsidesoverruled{}{\resetcurrentsectionmarks\ejectdummypage}{}}
+
+\installpagebreakhandler \v!right
+ {\ejectinsert
+ \gotonextpageX % will become \gotonextpage
+ \doifbothsidesoverruled{}{}{\resetcurrentsectionmarks\ejectdummypage}}
+
+\installpagebreakhandler \v!even
+ {\page
+ \doifoddpageelse{\resetcurrentsectionmarks\ejectdummypage}\donothing}
+
+\installpagebreakhandler \v!odd
+ {\page
+ \doifoddpageelse\donothing{\resetcurrentsectionmarks\ejectdummypage}}
+
+\installpagebreakhandler \v!quadruple % not yet ok inside columnsets
+ {\ifdoublesided
+ \!!counta\realpageno
+ \!!countb\realpageno
+ \divide\!!counta 4
+ \divide\!!countb 2
+ \ifnum\!!counta=\!!countb
+ \else
+ \executepagebreakhandler\v!yes
+ \executepagebreakhandler\v!empty
+ \executepagebreakhandler\v!empty
+ \fi
+ \fi}
+
+\installpagebreakhandler \v!last
+ {\ejectinsert
+ \gotonextpageX % will become \gotonextpage
+ \relax
+ \doifbothsidesoverruled
+ {\shipoutfacingpage}
+ {}
+ {\noheaderandfooterlines \ejectdummypage}%
+ \filluparrangedpages}
+
+\installpagebreakhandler \v!lastpage % handy for backpage preceded by empty pages
+ {\executepagebreakhandler\v!yes
+ \ifdoublesided
+ \executepagebreakhandler\v!left
+ \executepagebreakhandler\v!empty
+ \executepagebreakhandler\v!empty
+ \fi}
+
+\installpagebreakhandler \v!start
+ {\globallet\shipout\normalshipout}
+
+\installpagebreakhandler \v!stop
+ {\globallet\shipout\noshipout}
+
+% nb: \executepagebreakhandler\v!hoofd in other ones
+
+\installpagebreakhandler \v!header
+ {\doifnotvalue{\??tk\v!header\c!state}\v!stop{\setupheader[\c!state=\v!empty]}}
+
+\installpagebreakhandler \v!footer
+ {\doifnotvalue{\??tk\v!footer\c!state}\v!stop{\setupfooter[\c!state=\v!empty]}}
+
+% \definepagebreak
+% [chapter]
+% [yes,header,right]
+%
+% \setuphead
+% [chapter]
+% [page=chapter,
+% header=empty,
+% footer=chapter]
+%
+% \definepagebreak % untested
+% [lastpage]
+% [left,{empty,right},{empty,left}]
+
+% public page handler, beware: definepage already in use (core-ref)
+%
+% \definepagebreak[instance][forsure]
+% \definepagebreak[forsure][yes,+4]
+
+\def\definepagebreak
+ {\dodoubleargument\dodefinepagebreak}
+
+\def\dodefinepagebreak[#1][#2]% non recursive, meant for simple mappings
+ {\setvalue{\??pe::#1}{#2}}
+
+% hier nog uti blokkeren
+
+% don't change this / test case:
+%
+% \setupbackgrounds[state=repeat]
+% \setupbackgrounds[text][text][background=whatever]
+% \couplepage[chapter][before={\defineoverlay[whatever][ON]}]
+% \setuphead[chapter][before={\pagetype[chapter]}]
+% \chapter{First} \page test \chapter{second} \page test
+
+\long\def\installcolumnbreakhandler#1#2#3% #1=otr-id #2=tag
+ {\long\setvalue{\??cn:#1:#2}{#3}}
+
+\def\definecolumnbreak
+ {\dodoubleargument\dodefinecolumnbreak}
+
+\def\dodefinecolumnbreak[#1][#2]% non recursive, meant for simple mappings
+ {\setvalue{\??cn::#1}{#2}}
+
+%\def\columnbreak
+% {\dosingleempty\docolumnbreak}
+%
+%\def\docolumnbreak[#1]%
+% {\expanded{\nextcolumn[\executeifdefined{\??cn::#1}{#1}]}}
+
+\definecomplexorsimple\columnbreak
+
+\def\simplecolumnbreak
+ {\executecolumnbreakhandler\v!yes}
+
+\def\complexcolumnbreak[#1]% if empty, do nothing and avoid processing
+ {\doifsomething{#1}{\executecolumnbreakhandlers{#1}}}
+
+\def\executecolumnbreakhandlers#1%
+ {\processcommacommand[#1]\executecolumnbreakhandler}
+
+\def\executecolumnbreakhandler#1% here no commalist
+ {\edef\@@columnspecification{#1}%
+ \doifdefinedelse{\??cn:\OTRidentifier:\@@columnspecification}
+ {\getvalue{\??cn:\OTRidentifier:\@@columnspecification}}
+ {\doifdefinedelse{\??cn::\@@columnspecification}
+ {\executecolumnbreakhandlers{\getvalue{\??cn::\@@columnspecification}}}
+ {\getvalue{\??cn:\OTRidentifier:\s!unknown}}}}
+
+%let\nextcolumn\columnbreak
+\let\column \columnbreak
+
+% We don't want spurious last pages (due to left over marks):
+
+\def\noshipout
+ {\writestatus\m!systems{ignoring further shipouts}%
+ \global\advance\realpageno\minusone % else no flush of resources
+ \dowithnextbox{\deadcycles\zerocount}}
+
+% \def\doignorerestoftext
+% {\ifarrangingpages \else \ifnum\textlevel>\zerocount \else
+% \globallet\shipout\noshipout
+% \fi \fi}
+%
+% better:
+
+\def\doignorerestoftext
+ {\ifarrangingpages \else \ifnum\textlevel=\plusone
+ \globallet\shipout\noshipout
+ \fi \fi}
+
+\let\ignorerestoftext\donothing
+
+\prependtoks % only ignore in a symmetrical doc
+ \globallet\ignorerestoftext\doignorerestoftext
+\to \everystarttext
+
+% \appendtoks
+% \ignorerestoftext
+% \to \everylastshipout
+
+\newif\ifpageselected \pageselectedtrue
+\newif\ifselectingpages \selectingpagesfalse
+\newif\ifprocessingpages\processingpagestrue
+
+\let\pageselection \empty
+\let\currentpageselection\empty
+\let\aftershipout \relax
+\let\beforeshipout \relax
+
+\def\dodobeforeshipout#1%
+ {\global\let\beforeshipout\relax
+ \getvalue{\??pg#1\c!before}}
+
+\def\dobeforeshipout
+ {\doifsomething\currentpageselection
+ {\processcommacommand[\currentpageselection]\dodobeforeshipout}}
+
+\def\dododoaftershipout#1%
+ {\global\let\aftershipout\relax
+ \global\let\currentpageselection\empty
+ \getvalue{\??pg#1\c!after}}
+
+\def\dodoaftershipout#1%
+ {\doifelsevalue{\??pg#1\c!option}\v!doublesided
+ {\doifbothsidesoverruled
+ {\dododoaftershipout{#1}}
+ {\dododoaftershipout{#1}}
+ {}}
+ {\dododoaftershipout{#1}}}
+
+\def\doaftershipout
+ {\doifsomething\currentpageselection
+ {\processcommacommand[\currentpageselection]\dodoaftershipout}}
+
+% Dit wordt eigenlijk nooit en moet worden vervangen door
+% het meer algemene mechanisme.
+
+\def\dopagetype[#1]%
+ {\edef\desoortpagina{#1}%
+ \ifx\desoortpagina\empty \else
+ \@EA\doglobal\@EA\addtocommalist\@EA{\desoortpagina}\currentpageselection
+ \ifselectingpages
+ \fullexpandtwoargsafter\doifcommon\desoortpagina\pageselection
+ {\global\pageselectedtrue}%
+ \fi
+ \gdef\beforeshipout{\dobeforeshipout}%
+ \gdef\aftershipout {\doaftershipout}%
+ \fi}
+
+\def\pagetype
+ {\dosingleargument\dopagetype}
+
+\def\docouplepage[#1][#2]%
+ {\getparameters
+ [\??pg]
+ [\c!before=,
+ \c!after=,
+ \c!option=,
+ #2]%
+ \def\docommand##1%
+ {\getparameters
+ [\??pg##1]
+ [\c!before=\@@pgbefore,
+ \c!after=\@@pgafter,
+ \c!option=\@@pgoption]}%
+ \processcommalist[#1]\docommand}%
+
+\def\couplepage
+ {\dodoubleargument\docouplepage}
+
+\def\doprocesspage[#1][#2]%
+ {\processaction
+ [#2]
+ [\v!yes=>\global\processingpagestrue,
+ \v!no=>\global\processingpagesfalse]%
+ \gdef\pageselection{#1}%
+ \global\selectingpagestrue
+ \global\pageselectedfalse}
+
+\def\processpage
+ {\dodoubleargument\doprocesspage}
+
+\def\resetselectiepagina
+ {\ifselectingpages
+ \doifbothsidesoverruled{\global\pageselectedfalse}{}{\global\pageselectedfalse}%
+ \fi}
+
+\newif\ifregistertextareas
+\newif\iftracetextareas
+
+\newbox\registertextbox
+
+% \def\registeredtextarea#1#2#3% #1=lower-dp #2=correct-ht #3=box
+% {\hbox{\box#3}}
+
+\def\enabletextarearegistration{\global\registertextareastrue}
+
+\def\registeredtextarea#1#2#3% #1=lower-dp #2=correct-ht #3=box
+ {\hbox\bgroup
+ \ifregistertextareas \ifx\registerMPtextarea\undefined \else
+ \setbox\registertextbox\null
+ \wd\registertextbox\wd#3%
+ \ht\registertextbox\ht#3%
+ \dp\registertextbox\dp#3%
+ \ifcase#1\or % 1
+ \setbox\registertextbox\hbox{\lower\strutdp\box\registertextbox}%
+ \fi
+ \ifcase#2\or % 1
+ \setbox\registertextbox\hbox{\raise\topskip\hbox{\lower\strutht\box\registertextbox}}%
+ \dp\registertextbox\strutdp
+ \fi
+ \dp\registertextbox\strutdp % needed
+ %\setbox\registertextbox\hbox
+ % {\iftracetextareas\gray\boxrulewidth2pt\ruledhbox\fi
+ % {\registerMPtextarea{\box\registertextbox}}}%
+ \setbox\registertextbox\hbox
+ {\registerMPtextarea{\box\registertextbox}}%
+ \smashbox\registertextbox
+ \box\registertextbox
+ \fi \fi
+ \box#3%
+ \egroup}
+
+%D \macros
+%D {setupoppositeplacing,startopposite}
+%D
+%D \starttyping
+%D \starttext
+%D test \startopposite \blackrule[width=3cm,height=4cm] \stopopposite test
+%D test \startopposite \blackrule[width=3cm,height=4cm] \stopopposite test
+%D \stoptext
+%D \stoptyping
+
+% Moved from page-mar.tex, made english, cleaned up, but still to be
+% redesigned
+
+\newbox\facingpage
+
+\def\setupoppositeplacing
+ {\dodoubleargument\getparameters[\??np]}
+
+\def\startopposite
+ {\dowithnextboxcontent
+ {\hsize\makeupwidth}%
+ {\global\setbox\facingpage\vbox
+ {\ifvoid\facingpage
+ \@@npbefore
+ \else
+ \@@npinbetween
+ \unvbox\facingpage
+ \fi
+ \box\nextbox}}%
+ \vbox\bgroup}
+
+\def\stopopposite
+ {\egroup}
+
+\def\finishfacingpage
+ {\ifvoid\facingpage\else
+ \global\setbox\facingpage\vbox to \makeupheight
+ {\unvbox\facingpage
+ \@@npafter
+ \vss}%
+ \fi}
+
+\def\shipoutfacingpage
+ {\doif\@@npstate\v!start
+ {\ifvoid\facingpage\else
+ \ifnum\realpageno>\plusone
+ \bgroup
+ \chardef\pageornamentstate\plusone
+ \finishfacingpage
+ \myshipout{\buildpagebody\box\facingpage}%
+ \egroup
+ \else
+ \global\setbox\facingpage\emptybox
+ \fi
+ \fi}}
+
+\setupoppositeplacing
+ [\c!state=\v!start,
+ \c!before=,
+ \c!inbetween=\blank,
+ \c!after=]
+
+\protect \endinput
diff --git a/tex/context/base/page-lay.tex b/tex/context/base/page-lay.tex
index 9e86bcae2..0db7fc167 100644
--- a/tex/context/base/page-lay.tex
+++ b/tex/context/base/page-lay.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Layout Specification}
+\writestatus{loading}{ConTeXt Page Macros / Layout Specification}
%D This module is now etex dependent.
@@ -1241,7 +1241,8 @@
\c!dx=\zeropoint,
\c!dy=\zeropoint,
\c!nx=1,
- \c!ny=1]
+ \c!ny=1,
+ \c!method=\v!normal]
\setuppapersize
[\c!option=\v!max,
diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua
index a8d868f36..0efb6314e 100644
--- a/tex/context/base/page-lin.lua
+++ b/tex/context/base/page-lin.lua
@@ -8,95 +8,103 @@ if not modules then modules = { } end modules ['page-lin'] = {
-- experimental
+local format = string.format
+local texsprint, texbox = tex.sprint, tex.box
+
+local ctxcatcodes = tex.ctxcatcodes
+
nodes = nodes or { }
nodes.lines = nodes.lines or { }
nodes.lines.data = nodes.lines.data or { } -- start step tag
-do
-
- -- if there is demand for it, we can support multiple numbering streams
- -- and use more than one attibute
+-- if there is demand for it, we can support multiple numbering streams
+-- and use more than one attibute
- local hlist, vlist, whatsit = node.id('hlist'), node.id('vlist'), node.id('whatsit')
+local hlist, vlist, whatsit = node.id('hlist'), node.id('vlist'), node.id('whatsit')
- local display_math = attributes.numbers['display-math'] or 121
- local line_number = attributes.numbers['line-number'] or 131
- local line_reference = attributes.numbers['line-reference'] or 132
+local display_math = attributes.private('display-math')
+local line_number = attributes.private('line-number')
+local line_reference = attributes.private('line-reference')
- local current_list = { }
- local cross_references = { }
- local chunksize = 250 -- not used in boxed
+local current_list = { }
+local cross_references = { }
+local chunksize = 250 -- not used in boxed
- local has_attribute = node.has_attribute
- local traverse_id = node.traverse_id
- local copy = node.copy
- local format = string.format
- local sprint = tex.sprint
+local has_attribute = node.has_attribute
+local traverse_id = node.traverse_id
+local traverse = node.traverse
+local copy_node = node.copy
- local data = nodes.lines.data
+local data = nodes.lines.data
- nodes.lines.scratchbox = nodes.lines.scratchbox or 0
+nodes.lines.scratchbox = nodes.lines.scratchbox or 0
- -- cross referencing
+-- cross referencing
- function nodes.lines.number(n)
- local cr = cross_references[n] or 0
- cross_references[n] = nil
- return cr
- end
+function nodes.lines.number(n)
+ local cr = cross_references[n] or 0
+ cross_references[n] = nil
+ return cr
+end
- local function resolve(n,m)
- while n do
- local id = n.id
- if id == whatsit then
- local a = has_attribute(n,line_reference)
- if a then
- cross_references[a] = m
- end
- elseif id == hlist or id == vlist then
- resolve(n.list,m)
+local function resolve(n,m)
+ while n do
+ local id = n.id
+ if id == whatsit then
+ local a = has_attribute(n,line_reference)
+ if a then
+ cross_references[a] = m
end
- n = n.next
+ elseif id == hlist or id == vlist then
+ resolve(n.list,m)
end
+ n = n.next
end
+end
- -- boxed variant
+-- boxed variant
- nodes.lines.boxed = { }
+nodes.lines.boxed = { }
- function nodes.lines.boxed.register(configuration)
- data[#data+1] = configuration
- return #data
+function nodes.lines.boxed.register(configuration)
+ data[#data+1] = configuration
+ return #data
+end
+function nodes.lines.boxed.setup(n,configuration)
+ local d = data[n]
+ if d then
+ for k,v in pairs(configuration) do d[k] = v end
+ else
+ data[n] = configuration
end
- function nodes.lines.boxed.setup(n,configuration)
- local d = data[n]
- if d then
- for k,v in pairs(configuration) do d[k] = v end
+ return n
+end
+
+local leftskip = nodes.leftskip
+
+local function check_number(n,a) -- move inline
+ local d = data[a]
+ if d then
+ local s = d.start
+ current_list[#current_list+1] = { n, s }
+ if d.start % d.step == 0 then
+ texsprint(ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}\\endgraf", d.tag or "", s, n.shift, n.width, leftskip(n.list)))
else
- data[n] = configuration
+ texsprint(ctxcatcodes, "\\skipnumber\\endgraf")
end
- return n
+ d.start = s + 1 -- (d.step or 1)
end
+end
- local leftskip = nodes.leftskip
-
- function nodes.lines.boxed.stage_one(n)
- current_list = { }
- local head = tex.box[n].list
- local function check_number(n,a) -- move inline
- local d = data[a]
- if d then
- local s = d.start
- current_list[#current_list+1] = { n, s }
- if d.start % d.step == 0 then
- sprint(tex.ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}\\endgraf", d.tag or "", s, n.shift, n.width, leftskip(n.list)))
- else
- sprint(tex.ctxcatcodes, "\\skipnumber\\endgraf")
- end
- d.start = s + 1 -- (d.step or 1)
- end
- end
- for n in traverse_id(hlist,head) do -- attr test here and quit as soon as zero found
+function nodes.lines.boxed.stage_one(n)
+ current_list = { }
+ local head = texbox[n]
+ if head then
+ local list = head.list
+ --~ while list.id == vlist and not list.next do
+ --~ list = list.list
+ --~ end
+ for n in traverse_id(hlist,list) do -- attr test here and quit as soon as zero found
if n.height == 0 and n.depth == 0 then
-- skip funny hlists
else
@@ -115,14 +123,17 @@ do
end
end
end
+end
- function nodes.lines.boxed.stage_two(n,m)
+function nodes.lines.boxed.stage_two(n,m)
+ if #current_list > 0 then
m = m or nodes.lines.scratchbox
local t, i = { }, 0
- for l in traverse_id(hlist,tex.box[m].list) do
- t[#t+1] = copy(l)
+ for l in traverse_id(hlist,texbox[m].list) do
+ t[#t+1] = copy_node(l)
end
- for _, l in ipairs(current_list) do
+ for j=1,#current_list do
+ local l = current_list[j]
local n, m = l[1], l[2]
i = i + 1
t[i].next = n.list
@@ -130,107 +141,107 @@ do
resolve(n,m)
end
end
+end
- -- flow variant
- --
- -- it's too hard to make this one robust, so for the moment it's not
- -- available; todo: line refs
+-- flow variant
+--
+-- it's too hard to make this one robust, so for the moment it's not
+-- available; todo: line refs
- if false then
+if false then
- nodes.lines.flowed = { }
+ nodes.lines.flowed = { }
- function nodes.lines.flowed.prepare()
- for i=1,#data do
- sprint(tex.ctxcatcodes,format("\\ctxlua{nodes.lines.flowed.prepare_a(%s)}\\ctxlua{nodes.lines.flowed.prepare_b(%s)}",i, i))
- end
+ function nodes.lines.flowed.prepare(tag)
+ for i=1,#data do -- ??
+ texsprint(ctxcatcodes,format("\\ctxlua{nodes.lines.flowed.prepare_a(%s)}\\ctxlua{nodes.lines.flowed.prepare_b(%s)}",i,i))
end
+ end
- function nodes.lines.flowed.prepare_a(i)
- local d = data[i]
- local p = d.present
- if p < chunksize then
- local b = nodes.lines.scratchbox
- sprint(tex.ctxcatcodes, format("{\\forgetall\\global\\setbox%s=\\vbox{\\unvbox%s\\relax\\offinterlineskip", b, b))
- while p < chunksize do
- sprint(tex.ctxcatcodes, format("\\mkmaketextlinenumber{%s}{%s}\\endgraf",d.start,1))
- p = p + 1
- d.start = d.start + d.step
- end
- d.present = p
- sprint(tex.ctxcatcodes, "}}")
+ function nodes.lines.flowed.prepare_a(i)
+ local d = data[i]
+ local p = d.present
+ if p and p < chunksize then
+ local b = nodes.lines.scratchbox
+ texsprint(ctxcatcodes, format("{\\forgetall\\global\\setbox%s=\\vbox{\\unvbox%s\\relax\\offinterlineskip", b, b))
+ while p < chunksize do
+ texsprint(ctxcatcodes, format("\\mkmaketextlinenumber{%s}{%s}\\endgraf",d.start,1))
+ p = p + 1
+ d.start = d.start + d.step
end
+ d.present = p
+ texsprint(ctxcatcodes, "}}")
end
+ end
- function nodes.lines.flowed.prepare_b(i)
- local d = data[i]
- local b = nodes.lines.scratchbox
- local l = tex.box[b]
- if l then
- l = l.list
- local n = d.numbers
- while l do
- if l.id == hlist then
- local m = node.copy(l)
- m.next = nil
- if n then
- n.next = m
- else
- d.numbers = m
- end
- n = m
+ function nodes.lines.flowed.prepare_b(i)
+ local d = data[i]
+ local b = nodes.lines.scratchbox
+ local l = texbox[b]
+ if l then
+ l = l.list
+ local n = d.numbers
+ while l do
+ if l.id == hlist then
+ local m = copy_node(l)
+ m.next = nil
+ if n then
+ n.next = m
+ else
+ d.numbers = m
end
- l = l.next
+ n = m
end
+ l = l.next
end
- tex.box[b] = nil
end
+ tex.box[b] = nil
+ end
- function nodes.lines.flowed.cleanup(i)
- if i then
+ function nodes.lines.flowed.cleanup(i)
+ if i then
+ node.flush_list(data[i].numbers)
+ else
+ for i=1,#data do
node.flush_list(data[i].numbers)
- else
- for i=1,#data do
- node.flush_list(data[i].numbers)
- end
end
end
+ end
- function nodes.lines.flowed.apply(head)
- local function check_number(n,a)
- local d = data[a]
- if d then
- local m = d.numbers
- if m then
- d.numbers = m.next
- m.next = n.list
- n.list = m
- d.present = d.present - 1
- end
- end
+ local function check_number(n,a)
+ local d = data[a]
+ if d then
+ local m = d.numbers
+ if m then
+ d.numbers = m.next
+ m.next = n.list
+ n.list = m
+ d.present = d.present - 1
end
- for n in node.traverse(head) do
- local id = n.id
- if id == hlist then
- if n.height == 0 and n.depth == 0 then
- -- skip funny hlists
- else
- local a = has_attribute(n,line_number)
- if a and a > 0 then
- if has_attribute(n,display_math) then
- if nodes.is_display_math(n) then
- check_number(n,a)
- end
- else
+ end
+ end
+
+ function nodes.lines.flowed.apply(head)
+ for n in node.traverse(head) do
+ local id = n.id
+ if id == hlist then
+ if n.height == 0 and n.depth == 0 then
+ -- skip funny hlists
+ else
+ local a = has_attribute(n,line_number)
+ if a and a > 0 then
+ if has_attribute(n,display_math) then
+ if nodes.is_display_math(n) then
check_number(n,a)
end
+ else
+ check_number(n,a)
end
end
end
end
- return head, true
end
-
+ return head, true
end
end
diff --git a/tex/context/base/page-lin.mkii b/tex/context/base/page-lin.mkii
index 357283252..a04804ce6 100644
--- a/tex/context/base/page-lin.mkii
+++ b/tex/context/base/page-lin.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Line Numbering}
+\writestatus{loading}{ConTeXt Core Macros / Line Numbering}
\unprotect
diff --git a/tex/context/base/page-lin.mkiv b/tex/context/base/page-lin.mkiv
index f803c206d..ad84fc8b2 100644
--- a/tex/context/base/page-lin.mkiv
+++ b/tex/context/base/page-lin.mkiv
@@ -13,17 +13,16 @@
% generic or not ... maybe not bother too much and simplify to mkiv only
-\writestatus{loading}{Context Core Macros / Line Numbering}
+\writestatus{loading}{ConTeXt Core Macros / Line Numbering}
\unprotect
% low level interface
-\defineattribute[line-number]
-\defineattribute[line-reference]
-
\registerctxluafile{page-lin}{1.001}
-% \ctxluafileload{page-lin}{1.001}
+
+\definesystemattribute[line-number]
+\definesystemattribute[line-reference]
\appendtoksonce\doresetattribute{line-number}\to\everyforgetall
\appendtoksonce\dosetattribute{display-math}{1}\to\everybeforedisplayformula
@@ -64,6 +63,8 @@
\def\makenumber#1#2{\hbox{\llap{#1\quad\hskip#2\scaledpoint}}\endgraf}%
+\newconditional\boxcontentneedsprocessing
+
\def\mkdoprocesspagecontents #1{\mkaddtextlinenumbers{#1}\plusone \plusone}
\def\mkdoprocessboxcontents #1{\mkaddtextlinenumbers{#1}\plusone \plusone}
\def\mkdoprocesscolumncontents#1{\mkaddtextlinenumbers{#1}\currentcolumn\nofcolumns}
@@ -80,6 +81,7 @@
\def\mkstarttextlinenumbering#1#2%
{\globallet\mkprocesspagecontents \mkdoprocesspagecontents
\globallet\mkprocesscolumncontents\mkdoprocesscolumncontents
+ \global\settrue\boxcontentneedsprocessing % see core-rul.mkiv
\ifcase#2\relax
% continue
\or
@@ -409,8 +411,8 @@
\appendtoks\ctxlua{nodes.lines.flowed.cleanup()}\to\everybye
\def\mkstarttextlinenumbering#1#2%
- {\ctxlua{nodes.lines.flowed.prepare(#1)}%
- \dosetattribute{line-number}{#1}}
+ {\ctxlua{nodes.lines.flowed.prepare("#1")}%
+ \dosetattribute{line-number}{#2}}
\def\mkstoptextlinenumbering
{\doresetattribute{line-number}}
diff --git a/tex/context/base/page-log.tex b/tex/context/base/page-log.tex
index ad8a37a9b..e52c36288 100644
--- a/tex/context/base/page-log.tex
+++ b/tex/context/base/page-log.tex
@@ -11,41 +11,25 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Logos}
+\writestatus{loading}{ConTeXt Page Macros / Logos}
\unprotect
-\startmessages dutch library: layouts
- 7: beeldmerken berekenen
-\stopmessages
+% messages moved
-\startmessages english library: layouts
- 7: calculating logospace
-\stopmessages
+% messages moved
-\startmessages german library: layouts
- 7: berechne Platzbedarf des Logos
-\stopmessages
+% messages moved
-\startmessages czech library: layouts
- 7: pocita se misto pro logo
-\stopmessages
+% messages moved
-\startmessages italian library: layouts
- 7: calcolo dello spazio per logo
-\stopmessages
+% messages moved
-\startmessages norwegian library: layouts
- 7: beregner plass for logo
-\stopmessages
+% messages moved
-\startmessages romanian library: layouts
- 7: se calculeaza spatiul pentru logo
-\stopmessages
+% messages moved
-\startmessages french library: layouts
- 7: calcul de l'espace pour le logo
-\stopmessages
+% messages moved
%D Although logos can conveniently be implemented on top of
%D background and text areas, we provide a dedicated mechanism
diff --git a/tex/context/base/page-lyr.tex b/tex/context/base/page-lyr.tex
index af84900b2..fe542233f 100644
--- a/tex/context/base/page-lyr.tex
+++ b/tex/context/base/page-lyr.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Layers}
+\writestatus{loading}{ConTeXt Page Macros / Layers}
%D This module is now etex dependent.
@@ -138,8 +138,8 @@
{\edef\currentlayerwidth {\thelayerwidth {#2#1}}%
\edef\currentlayerheight{\thelayerheight{#2#1}}}
-\def\thelayerwidth #1{\the\wd\executeifdefined{\@@layerbox#1}\voidbox}
-\def\thelayerheight#1{\the\ht\executeifdefined{\@@layerbox#1}\voidbox}
+\def\thelayerwidth #1{\the\wd\executeifdefined{\@@layerbox#1}\emptybox}
+\def\thelayerheight#1{\the\ht\executeifdefined{\@@layerbox#1}\emptybox}
\def\setlayer
{\dotripleempty\dosetlayer}
@@ -620,7 +620,7 @@
\newskip\xdimension \newskip\ydimension
\newskip\xoffset \newskip\yoffset
-\newbox\positionbox
+% already defined \newbox\positionbox
\def\startpositioning
{\bgroup
diff --git a/tex/context/base/page-mak.tex b/tex/context/base/page-mak.tex
index 1637e6327..040feb1d2 100644
--- a/tex/context/base/page-mak.tex
+++ b/tex/context/base/page-mak.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / MakeUp}
+\writestatus{loading}{ConTeXt Page Macros / MakeUp}
\unprotect
@@ -164,8 +164,11 @@
\global\pageselectedfalse
\fi}
+% \def\pushpagestate{\globalpushmacro\@@pnstate}
+% \def\poppagestate {\globalpopmacro \@@pnstate}
+
\def\doshipoutmakeup
- {\globalpushmacro\@@pnstate % new
+ {\pushpagestate % new
\makeupparameter\c!before
\setbox\makeupbox\vbox{\hbox{\color[\makeupparameter\c!color]{\box\makeupbox}}}%
% \ifgridsnapping
@@ -190,7 +193,7 @@
\null
\page}]%
\fi \fi
- \globalpopmacro\@@pnstate} % new
+ \poppagestate} % new
%D The text surrounding the main body text can be influenced
%D by setting their associated status variables. The
diff --git a/tex/context/base/page-mar.tex b/tex/context/base/page-mar.tex
index 2ca82a79e..f7c5328f3 100644
--- a/tex/context/base/page-mar.tex
+++ b/tex/context/base/page-mar.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-mar, % moved here from main-001
%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Marginal Things,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -16,7 +16,7 @@
%D extended en enhanced. Therefore it's always good to watch
%D out for unexpected side effects.
-\writestatus{loading}{Context Core Macros / Maginal Things}
+\writestatus{loading}{ConTeXt Page Macros / Maginal Things}
\unprotect
@@ -599,7 +599,7 @@
% \def\dodoinmargin[#1][#2][#3][#4][#5]#6%
% {\bgroup
% \forgetall % otherwise sidefloat problems, added 2005/07/20, maybe dangerous
-% \postponefootnotes % group is (somehow) needed
+% \postponenotes % group is (somehow) needed
% \doifinsetelse\v!low{#4}
% {\chardef\margincontentdisplacement\plusone}
% {\chardef\margincontentdisplacement\zerocount}%
@@ -645,7 +645,7 @@
\chardef\marginpagecheckmethod \executeifdefined{\??im\currentmargincontent\c!splitmethod}\plusone
% so far
\forgetall % otherwise sidefloat problems, added 2005/07/20, maybe dangerous
- \postponefootnotes % group is (somehow) needed
+ \postponenotes % group is (somehow) needed
\doifinsetelse\v!low{#4}
{\chardef\margincontentdisplacement\plusone}
{\chardef\margincontentdisplacement\zerocount}%
@@ -693,7 +693,7 @@
\def\marginword {\margintext}
\def\margintitle{\margintext} % txt mark as well
-\newtoks\collectedmargintexts
+\newtoks\collectedmargintexts % so .. delayed!
\chardef\margintextcollected \zerocount
\def\domargincontent[#1][#2]#3% we used to check for #2/#1 being number, no longer now
diff --git a/tex/context/base/page-mis.tex b/tex/context/base/page-mis.tex
new file mode 100644
index 000000000..bd029f896
--- /dev/null
+++ b/tex/context/base/page-mis.tex
@@ -0,0 +1,268 @@
+%D \module
+%D [ file=page-mis,
+%D version=2008.11.17, % was part of page-flt.tex / 2000.10.20
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Misc Float Things,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Page Macros / Misc Float Things}
+
+\unprotect
+
+\newif\ifmargeblokken
+
+\def\dosetupmarginblocks[#1]%
+ {\getparameters[\??mb][#1]%
+ \doifelse\@@mbstate\v!start
+ {\showmessage\m!layouts4\empty
+ \margeblokkentrue
+ \let\somenextfloat\dosomenextfloat
+ \let\startmarginblock\dostartmarginblock
+ \let\stopmarginblock\dostopmarginblock}%
+ {\showmessage\m!layouts5\empty
+ \margeblokkenfalse
+ \def\somenextfloat[##1]%
+ {\someelsefloat[##1,\v!here]}%
+ \let\startmarginblock\dontstartmargeblok
+ \let\stopmarginblock\dontstopmargeblok}}
+
+\def\setupmarginblocks
+ {\dosingleargument\dosetupmarginblocks}
+
+\newbox\marginbox
+
+\def\dosomenextfloat[#1]%
+ {\global\setbox\marginbox\vbox
+ {\hsize\@@mbwidth
+ \unvcopy\marginbox
+ \ifvoid\marginbox\else\expandafter\@@mbinbetween\fi
+ \box\floatbox\filbreak}%
+ \ifdim\ht\marginbox>\textheight
+ \dosavefloatinfo
+ \else
+ \doinsertfloatinfo
+ \fi}
+
+\newbox\preparedmarginbox
+
+\def\reshapemargin
+ {\ifdim\ht\preparedmarginbox>\zeropoint
+ \beginofshapebox
+ \unvbox\preparedmarginbox
+ \endofshapebox
+ \reshapebox
+ {\box\shapebox}%
+ \setbox\preparedmarginbox\vbox to \textheight
+ {\@@mbtop
+ \flushshapebox
+ \@@mbbottom}%
+ \fi}
+
+\def\plaatsrechtermargeblok
+ {\hskip\rightmarginwidth}
+
+\def\plaatslinkermargeblok
+ {\hskip\leftmarginwidth}
+
+\def\checkmargeblokken
+ {\ifvoid\marginbox\else\docheckmargeblokken\fi}
+
+\def\docheckmargeblokken % erg inefficient
+ {\setbox\preparedmarginbox\vbox
+ {\forgetall
+ \splittopskip\topskip
+ \ifvoid\marginbox\else
+ \ifdim\ht\marginbox>\textheight
+ \vsplit\marginbox to \textheight
+ \else
+ \unvbox\marginbox
+ \fi
+ \fi}%
+ \reshapemargin
+ \setbox\preparedmarginbox\vbox
+ {\@@mbbefore\box\preparedmarginbox\@@mbafter}%
+ \def\rightmarginbox
+ {\def\plaatsrechtermargeblok
+ {\setbox\preparedmarginbox\hbox to \rightmarginwidth
+ {\@@mbleft\box\preparedmarginbox\@@mbright}%
+ \vsmashbox\preparedmarginbox
+ \box\preparedmarginbox}}%
+ \def\leftmarginbox
+ {\def\plaatslinkermargeblok
+ {\setbox\preparedmarginbox\hbox to \leftmarginwidth
+ {\@@mbright\box\preparedmarginbox\@@mbleft}%
+ \vsmashbox\preparedmarginbox
+ \box\preparedmarginbox}}%
+ \processaction % traag
+ [\@@mblocation]
+ [ \v!inmargin=>\doifbothsidesoverruled\rightmarginbox\rightmarginbox\leftmarginbox,
+ \v!middle=>\doifbothsidesoverruled\rightmarginbox\leftmarginbox\rightmarginbox,
+ \v!left=>\leftmarginbox,
+ \v!right=>\rightmarginbox,
+ \s!unknown=>\setbox\preparedmarginbox\hbox{}]}
+
+\def\dostartmarginblock % 2 maal \vbox ivm \unvbox elders
+ {\global\setbox\marginbox\vtop\bgroup\vbox\bgroup
+ \hsize\@@mbwidth
+ \ifvoid\marginbox\else
+ \unvbox\marginbox
+ \@@mbinbetween
+ \fi
+ \setupalign[\@@mbalign]%
+ \dostartattributes\??mb\c!style\c!color{}%
+ \begstrut\ignorespaces}
+
+\def\dostopmarginblock
+ {\unskip\endstrut
+ \dostopattributes
+ \egroup
+ \egroup}
+
+\def\dontstartmargeblok
+ {\@@mbbefore
+ \bgroup
+ \dostartattributes\??mb\c!style\c!color\empty}
+
+\def\dontstopmargeblok
+ {\dostopattributes
+ \egroup
+ \@@mbafter}
+
+\newcounter\nofpostponedblocks
+
+\newif\ifinpostponing
+
+\newevery\everytopofpage\relax
+
+\appendtoks \the\everytopofpage \to\everystarttext
+\appendtoks\global\everytopofpage\emptytoks\to\everystoptext
+
+% \startpostponing [pagenumber] [+pageoffset]
+%
+% \startpostponing[2]
+% PAGE 2 \blank
+% \stoppostponing
+%
+% \startpostponing[+1]
+% PAGE +1 \blank
+% \stoppostponing
+%
+% \startpostponing[+2]
+% PAGE +2 \blank
+% \stoppostponing
+%
+% \starttext \dorecurse{4}{\input tufte \page} \stoptext
+
+\newtoks \postponedpageblocks
+\newcounter\nofpostponedpageblocks
+
+% \ifinpostponing: handhaven, want gebruikt in stijlen ! ! ! ! !
+
+\def\flushpagefloats
+ {\doifoddpageelse
+ {\ifvoid\collectedleftpagefloats
+ \ifvoid\collectedrightpagefloats\else
+ \unvbox\collectedrightpagefloats
+ \page
+ %\the\everytopofpage
+ \fi
+ \fi}
+ {\ifvoid\collectedleftpagefloats\else
+ \unvbox\collectedleftpagefloats
+ \page
+ %\the\everytopofpage
+ \fi
+ \ifvoid\collectedrightpagefloats\else
+ \unvbox\collectedrightpagefloats
+ \page
+ %\the\everytopofpage
+ \fi}%
+ \ifvoid\collectedpagefloats\else
+ % message
+ \unvbox\collectedpagefloats
+ \fi}
+
+% \def\flushrestfloats
+% {\doif{\floatsharedparameter\c!cache}\v!no\doflushfloats}
+
+% \let\flushrestfloats\relax
+
+\def\dopostponeblock
+ {\bgroup % new may 2004
+ \setsystemmode\v!postponing % new may 2004
+ \the\everytopofpage
+ %\flushrestfloats
+ \flushpagefloats
+ \donefalse
+ \ifinpostponing \else
+ \ifcase\nofpostponedblocks \else \donetrue \fi
+ \ifcase\nofpostponedpageblocks \else \donetrue \fi
+ \fi
+ \ifdone
+ \bgroup % we need the color/font switch, else problems inside split verbatim
+ \setnormalcatcodes % postponing in verbatim
+ \pushpostponedpagecolor
+ \restoreglobalbodyfont % The \nof-test is
+ \global\pagetotal\zeropoint % recently added and
+ \global\inpostponingtrue % definitely needed else
+ \the\postponedpageblocks % we can loose or disorder
+ \dorecurse\nofpostponedblocks % floats; anyhow, this
+ {\getbuffer[pbuf-\recurselevel]}% % mechanism is still
+ \doflushfloats % new but potential dangerous % suboptimal and needs a
+ \doglobal\newcounter\nofpostponedblocks % proper analysis
+ \global\inpostponingfalse
+ \poppostponedpagecolor
+ \egroup
+ \fi
+ \egroup} % new may 2004
+
+\def\getpostponedblock#1#2%
+ {\doif{#1}\realfolio{\getbuffer[rbuf-#2]}} % no \ifnum, avoid \fi
+
+% beware, \dosingleempty conflicts with buffers (feeds back the \par)
+
+\setvalue{\e!start\v!postponing}%
+ {\bgroup
+ \obeylines
+ \doifnextoptionalelse{\egroup\nodostartpostponing}{\egroup\dodostartpostponing}}
+
+\def\nodostartpostponing[#1]%
+ {\doglobal\increment\nofpostponedpageblocks
+ \bgroup % a little bit of misusing grouping
+ \doifinstring{+}{#1}\advance \realpageno#1\relax % ugly but efficient
+ \doglobal\appendetoks\noexpand\getpostponedblock
+ {\realfolio}{\nofpostponedpageblocks}\to\postponedpageblocks
+ \egroup
+ \showmessage\m!layouts3\nofpostponedpageblocks
+ \dostartbuffer[rbuf-\nofpostponedpageblocks]%
+ [\e!start\v!postponing][\e!stop\v!postponing]}
+
+\def\dodostartpostponing
+ {\doglobal\increment\nofpostponedblocks
+ \showmessage\m!layouts3\nofpostponedblocks
+ \expanded{\dostartbuffer[pbuf-\nofpostponedblocks][\e!start\v!postponing][\e!stop\v!postponing]}}
+
+% Setups:
+
+\setupmarginblocks
+ [\c!state=\v!start,
+ \c!location=\v!inmargin,
+ \c!width=\rightmarginwidth,
+ \c!style=,
+ \c!color=,
+ \c!align=,
+ \c!left=,
+ \c!right=,
+ \c!top=,
+ \c!inbetween=\blank,
+ \c!bottom=\vfill,
+ \c!before=,
+ \c!after=]
+
+\protect \endinput
diff --git a/tex/context/base/page-mul.tex b/tex/context/base/page-mul.tex
index 5c98d7226..c78af074a 100644
--- a/tex/context/base/page-mul.tex
+++ b/tex/context/base/page-mul.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-mul, % was: core-mul
%D version=1998.03.15,
-%D title=\CONTEXT\ OTR Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Multi Column Output,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context OTR Macros / Simple Multi Column}
+\writestatus{loading}{ConTeXt Page Macros / Simple Multi Column}
%D This module is mostly a copy from the original multi column
%D routine as implemented in \type {core-mul}. When the main
@@ -464,7 +464,7 @@
\global\output{\continuousmulticolumnsout}%
\setcolumnfloats
\dohandleallcolumns
- {\global\setbox\currenttopcolumnbox\box\voidb@x}%
+ {\global\setbox\currenttopcolumnbox\emptybox}%
\checkbegincolumnfootnotes
\activateotr{MUL}{ONE}% todo ! ! ! !
\let\sethsize\setcolumnhsize
@@ -642,7 +642,7 @@
{\ifdim-\ht\currenttopcolumnbox<\scratchdimen
\scratchdimen-\ht\currenttopcolumnbox
\fi
- \global\setbox\currenttopcolumnbox\box\voidb@x}%
+ \global\setbox\currenttopcolumnbox\emptybox}%
\advance\scratchdimen \ht\columnpagebox
\setbox\scratchbox\hbox to \columntextwidth
{\vrule
diff --git a/tex/context/base/page-not.tex b/tex/context/base/page-not.tex
index 151f957f4..9c67f18f1 100644
--- a/tex/context/base/page-not.tex
+++ b/tex/context/base/page-not.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Footnotes}
+\writestatus{loading}{ConTeXt Page Macros / Footnotes}
%D Terrible hacks: we need to share save/restore
diff --git a/tex/context/base/page-num.tex b/tex/context/base/page-num.tex
index cad7d6790..95eeea806 100644
--- a/tex/context/base/page-num.tex
+++ b/tex/context/base/page-num.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-num, % moved here from main-001
%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Numbering,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Numbering}
+\writestatus{loading}{ConTeXt Page Macros / Numbering}
% todo: {}{}{} ipv ...--...-...-...--... in pag ref
@@ -171,6 +171,8 @@
\countdef\subpageno = 2 \subpageno = 0 % !!
\countdef\arrangeno = 3 \arrangeno = 0 % !!
+\let\pageno\userpageno
+
% we don't want conflicts when \pageno is used by other
% packages, like CWEB, so we redefine \pageno
@@ -279,7 +281,10 @@
% \@@pnstatus global, but \@@nmstatus local and only start/stop
-\global\let\@@pnstate\@@pnstate
+\global\let\@@pnstate\@@pnstate % brrr
+
+\def\pushpagestate{\globalpushmacro\@@pnstate}
+\def\poppagestate {\globalpopmacro \@@pnstate}
\def\dosetuppagenumber[#1]%
{\getparameters[\??pn][\c!number=,#1]%
@@ -432,11 +437,11 @@
\def\preparepageprefix#1%
{\def\dopreparepageprefix##1%
- {\letvalue{#1\getvalue{\??by##1}\v!number}\v!no}% %v
+ {\ifcsname\??by##1\endcsname\letvalue{#1\csname\??by##1\endcsname\v!number}\v!no\fi}% %v
\rawprocesscommalist[\@@kolist]\dopreparepageprefix
\def\dopreparepageprefix##1%
{\doifvalue{#1##1\v!number}\v!yes %v
- {\letvalue{#1\getvalue{\??by##1}\v!number}\v!yes}}%
+ {\ifcsname\??by##1\endcsname\letvalue{#1\csname\??by##1\endcsname\v!number}\v!yes\fi}}%
\rawprocesscommalist[\@@kolist]\dopreparepageprefix}
\def\dodopageprefix#1% uti seperator --
diff --git a/tex/context/base/page-one.tex b/tex/context/base/page-one.mkii
index f33aa4602..1affc24d0 100644
--- a/tex/context/base/page-one.tex
+++ b/tex/context/base/page-one.mkii
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-one,
%D version=2000.10.20,
-%D title=\CONTEXT\ OTR Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Default Routine,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context OTR Macros / Default Routine}
+\writestatus{loading}{ConTeXt Page Macros / Default Routine}
%D This is just the good old \CONTEXT\ output routine, which
%D has been there right from the start.
diff --git a/tex/context/base/page-one.mkiv b/tex/context/base/page-one.mkiv
new file mode 100644
index 000000000..19ab43889
--- /dev/null
+++ b/tex/context/base/page-one.mkiv
@@ -0,0 +1,662 @@
+%D \module
+%D [ file=page-one,
+%D version=2000.10.20,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Default Routine,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Page Macros / Default Routine}
+
+%D This is just the good old \CONTEXT\ output routine, which
+%D has been there right from the start.
+
+\unprotect
+
+% OTRONE: basic single column
+
+\activateotr{ONE}{} % the default one
+
+\newtoks\OTRONEoutput
+
+\def\OTRONEgotonextpage
+ {\ejectpage}
+
+\def\OTRONEgotonextpageX % will become obsolete
+ {\superejectpage}
+
+\def\OTRONEsethsize
+ {\global\hsize\textwidth}
+
+% keep (original one)
+%
+% \def\OTRONEsetvsize
+% {\ifdim\vsize=\teksthoogte \else
+% \bgroup
+% \scratchdimen-\vsize
+% \advance\scratchdimen \teksthoogte
+% \global\advance\vsize \scratchdimen
+% \relax \ifdim\pagegoal<\maxdimen
+% \advance\scratchdimen \pagegoal
+% \global\pagegoal\scratchdimen
+% \fi
+% \egroup
+% \fi}
+%
+% no (keep)
+%
+% \def\OTRONEsetvsize
+% {\ifdim\vsize=\teksthoogte \else
+% \bgroup
+% \scratchdimen-\vsize
+% \advance\scratchdimen \teksthoogte
+% \ifgridsnapping
+% \getrawnoflines\scratchdimen
+% \scratchdimen\noflines\openlineheight
+% \ifdim\scratchdimen>\noflinesheight % available afterwards
+% \advance\scratchdimen-\openlineheight
+% \fi
+% \ifdim\scratchdimen<\zeropoint
+% \scratchdimen\zeropoint
+% \fi
+% \fi
+% \global\advance\vsize \scratchdimen
+% \relax \ifdim\pagegoal<\maxdimen
+% \advance\scratchdimen \pagegoal
+% \global\pagegoal\scratchdimen
+% \fi
+% \egroup
+% \fi}
+
+% \def\OTRONEsetvsize
+% {\ifgridsnapping
+% \ifcase\layoutlines
+% \getrawnoflines\teksthoogte
+% \else
+% \noflines\layoutlines
+% \fi
+% \global\vsize\noflines\openlineheight
+% \else
+% \global\vsize\teksthoogte
+% \fi
+% \ifdim\pagegoal<\maxdimen
+% \global\pagegoal\vsize
+% \fi}
+
+\newdimen\oldvsize
+
+\def\OTRONEsetvsize
+ {\ifgridsnapping
+ \ifcase\layoutlines
+ \getrawnoflines\textheight
+ \else
+ \noflines\layoutlines
+ \fi
+ \global\vsize\noflines\openlineheight
+ \else
+ \global\vsize\textheight
+ \fi
+ \ifdim\pagegoal<\maxdimen
+ \ifdim\oldvsize=\vsize
+ % let's assume that the layout didn't change
+ \else
+ \bgroup
+ \global\oldvsize\vsize
+ \advance\vsize-\topinserted
+ \advance\vsize-\botinserted
+ \global\pagegoal\vsize
+ \egroup
+ \fi
+ \fi}
+
+\chardef\kindofpagetextareas=2 % whole page (public variable! never change)
+
+\def\OTRONEregisteredtextarea#1%
+ {\ifregistertextareas
+ \setbox0\vbox{#1}%
+ \wd0\makeupwidth % somehow a space creeps in
+ \vbox{\registeredtextarea000}%
+ \else
+ #1%
+ \fi}
+
+% \chardef\kindofpagetextareas\plusone
+
+\def\doOTRONEregisteredtextareaA#1%
+ {\ifregistertextareas
+ \xypos{pbd:\realfolio:b}% we could save bytes by only saving the y
+ \endgraf
+ \begingroup
+ \scratchdimen\MPy{pbd:\realfolio:b}%
+ \advance\scratchdimen-\MPy{pbd:\realfolio:e}%
+ \setbox\scratchbox\null
+ \wd\scratchbox\makeupwidth
+ \ht\scratchbox\scratchdimen
+ \vsmash{\registeredtextarea00\scratchbox}%
+ \endgroup
+ #1%
+ \endgraf
+ \xypos{pbd:\realfolio:e}%
+ \else
+ #1%
+ \fi}
+
+\def\doOTRONEregisteredtextareaB#1%
+ {\ifregistertextareas
+ \setbox0\vbox{#1}%
+ \wd0\makeupwidth % somehow a space creeps in
+ \vbox{\registeredtextarea000}%
+ \else
+ #1%
+ \fi}
+
+\let\OTRONEregisteredtextareaA\firstofoneargument
+\let\OTRONEregisteredtextareaB\firstofoneargument
+
+\def\OTRONEdopagecontents#1#2% \box<n> \unvbox<n>
+ {\bgroup % niet breedte zetten, kan fractie zijn!
+ \ifcase\kindofpagetextareas
+ \or % partial page (experimental)
+ \let\OTRONEregisteredtextareaA\doOTRONEregisteredtextareaA
+ \or % whole page (default)
+ \let\OTRONEregisteredtextareaB\doOTRONEregisteredtextareaB
+ \or % partial page (only works well with no stretch!)
+ \let\OTRONEregisteredtextareaA\doOTRONEregisteredtextareaB
+ \fi
+ \setbox0\vbox \ifbottomnotes to \textheight \fi
+ {\edef\currentpagedepth{\the\dp#2}% still to be derived from #1
+ \dotopinsertions
+ \ifgridsnapping
+ \OTRONEregisteredtextareaA{#1#2}%
+ \vskip-\currentpagedepth\vskip\openstrutdepth
+ \pushproperties % moved from just after #1#2
+ \prevdepth\openstrutdepth
+ \dobotinsertions
+ \vfil
+ \else\ifr@ggedbottom
+ \OTRONEregisteredtextareaA{#1#2}%
+ \vskip-\currentpagedepth\vskip\openstrutdepth
+ \pushproperties % moved from just after #1#2
+ \prevdepth\openstrutdepth
+ \dobotinsertions
+ \vfil
+ \else\ifb@selinebottom
+ \OTRONEregisteredtextareaA{#1#2}%
+ \kern-\currentpagedepth\kern\maxdepth
+ \pushproperties % moved from just after #1#2
+ \dobotinsertions
+ \else
+ \OTRONEregisteredtextareaA{#1#2}%
+ \pushproperties % moved from just after #1#2
+ \dobotinsertions % added
+ \fi\fi\fi
+ \fakepagenotes}% was \fakenotes, but wrong! (check with \setupalign[height])
+ \ifbottomnotes
+ \ifgridsnapping
+\ifcase\layoutlines % todo: make macro of this
+ \getrawnoflines\textheight
+\else
+ \noflines\layoutlines
+\fi
+% \getnoflines\textheight
+ \advance\noflines \minusone
+ \scratchdimen\noflines\lineheight
+ \advance\scratchdimen \topskip
+ \else
+ \scratchdimen\ht0
+ \fi
+ \else
+ \scratchdimen\zeropoint
+ \fi
+ \setbox2\hbox
+ {\checksinglecolumnfootnotes
+ \lower\scratchdimen\vbox{\placebottomnotes}}%
+ \smashbox2% % needed here
+ \ifbottomnotes
+ \ht0\zeropoint
+ \fi
+ \OTRONEregisteredtextareaB
+ {\vbox to \textheight
+ {\box0\box2\ifbottomnotes\else\vfill\fi}}%
+ \egroup}
+
+\def\OTRONEfinalsidefloatoutput
+ {\finaloutput\unvbox\normalpagebox}
+
+\OTRONEoutput
+ {\sidefloatoutput}
+
+%D Insertions
+
+\newif\iftopofinsert
+
+% \def\OTRONEdosettopinserts
+% {\bgroup
+% \ifsomefloatwaiting
+% \noffloatinserts\zerocount
+% \let\totaltopinserted\!!zeropoint
+% \OTRONEdodosettopinserts
+% \ifnum\@@bknbottom=\zerocount
+% \ifnum\@@bknlines>\zerocount
+% \ifdim\totaltopinserted>\zeropoint\relax
+% \dimen0=\lineheight
+% \dimen0=\@@bknlines\dimen0
+% \advance\dimen0 \totaltopinserted\relax
+% \ifdim\dimen0>\textheight
+% \showmessage\m!floatblocks8\@@bknlines
+% \vfilll\eject
+% \fi
+% \fi
+% \fi
+% \fi
+% \fi
+% \egroup}
+
+\def\OTRONEdosettopinserts
+ {\bgroup
+ \ifsomefloatwaiting
+ \noffloatinserts\zerocount
+ \let\totaltopinserted\!!zeropoint
+ \OTRONEdodosettopinserts
+ \ifnum\@@bknbottom=\zerocount
+ \ifnum\@@bknlines>\zerocount
+ \ifdim\totaltopinserted>\zeropoint\relax
+ \ifdim\dimexpr\@@bknlines\lineheight+\totaltopinserted\relax>\textheight
+ \showmessage\m!floatblocks8\@@bknlines
+ \vfilll\eject
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \egroup}
+
+\def\OTRONEdodosettopinserts
+ {\ifnum\noffloatinserts<\noftopfloats
+ \dogetfloat
+ \ifdim\topinserted=\zeropoint
+ \topofinserttrue
+ \else
+ \topofinsertfalse
+ \fi
+ \global\advance\topinserted\dimexpr\ht\floatbox+\dp\floatbox+\floatbottomskip\relax
+ \ifdim\topinserted<\textheight\relax
+ \xdef\totaltopinserted{\the\topinserted}%
+ \insert\topins
+ {\forgetall
+ \iftopofinsert
+ \topskipcorrection % [xx] new: see icare topbleed
+ \kern-\lineskip\par
+ \prevdepth\maxdimen
+ \else
+ %\blank[-\@@bkspaceafter,\@@bkspacebefore]% inserts can't look back
+ \betweenfloatblanko
+ \fi
+ \flushfloatbox
+ \blank[\@@bkspaceafter]}%
+ \ifsomefloatwaiting
+ \advance\noffloatinserts \plusone
+ \else
+ \noffloatinserts\noftopfloats\relax
+ \fi
+ \dofloatflushedinfo
+ \else
+ \doresavefloat
+ \noffloatinserts\noftopfloats\relax
+ \fi
+ \else
+ \ifsomefloatwaiting
+ \showmessage\m!floatblocks6{\the\noftopfloats}%
+ \fi
+ \let\OTRONEdodosettopinserts\relax
+ \fi
+ \OTRONEdodosettopinserts}
+
+\def\OTRONEdosetbotinserts
+ {\bgroup
+ \ifsomefloatwaiting
+ \noffloatinserts\zerocount
+ \OTRONEdodosetbotinserts
+ \fi
+ \egroup}
+
+\def\OTRONEdodosetbotinserts
+ {\ifnum\noffloatinserts<\nofbotfloats\relax
+ \dogetfloat
+ \global\advance\botinserted \ht\floatbox\relax
+ \global\advance\botinserted \dp\floatbox\relax
+ \global\advance\botinserted \floattopskip\relax
+ \ifdim\botinserted<\pagegoal\relax
+ \insert\botins
+ {\forgetall
+ \blank[\@@bkspacebefore]%
+ \flushfloatbox}%
+ \ifsomefloatwaiting
+ \advance\noffloatinserts \plusone
+ \else
+ \noffloatinserts\nofbotfloats
+ \fi
+ \dofloatflushedinfo
+ \else
+ \doresavefloat
+ \noffloatinserts\nofbotfloats\relax
+ \fi
+ \global\nofloatpermittedtrue % vgl topfloats s!
+ \else
+ \ifsomefloatwaiting
+ \showmessage\m!floatblocks7{\the\nofbotfloats}%
+ \fi
+ \let\OTRONEdodosetbotinserts\relax
+ \fi
+ \OTRONEdodosetbotinserts}
+
+\def\OTRONEdosetbothinserts
+ {\global\topinserted\zeropoint
+ \global\botinserted\zeropoint
+ \ifflushingfloats \else
+ \OTRONEdosettopinserts
+ \OTRONEdosetbotinserts
+ \ifsomefloatwaiting
+ \doif\@@bkcache\v!no\doflushfloats
+ \fi
+ \fi}
+
+% \def\OTRONEdotopinsertions
+% {\ifvoid\topins\else
+% \ifgridsnapping
+% \box\topins
+% \vskip-\topskip \vskip\strutheight % [xx] new: see icare topbleed
+% \else
+% \unvbox\topins
+% \fi
+% \fi
+% \global\topinserted\zeropoint}
+
+\chardef\topinserttopskipmode=0 % 1 no topskip
+
+\def\OTRONEdotopinsertions
+ {\ifvoid\topins\else
+ \ifgridsnapping
+ \box\topins
+ \vskip-\topskip
+ \vskip\strutheight % [xx] new: see icare topbleed
+ \else
+ \ifcase\topinserttopskipmode
+ % 0: default, do nothing
+ \or
+ % 1: no topskip (crossed fingers)
+ \vskip-\topskip
+ \vskip\strutheight
+ \fi
+ \unvbox\topins
+ \fi
+ \fi
+ \global\topinserted\zeropoint}
+
+\def\OTRONEdobotinsertions
+ {\ifvoid\botins\else
+ \ifgridsnapping
+ % \floatparameter\c!bottombefore
+ \snaptogrid\hbox{\box\botins}%
+ % \floatparameter\c!bottomafter
+ \else
+ \floatparameter\c!bottombefore
+ \unvbox\botins
+ \floatparameter\c!bottomafter
+ \fi
+ \fi
+ \global\botinserted\zeropoint
+ \global\nofloatpermittedfalse}
+
+\def\OTRONEdoflushfloats
+ {\global\flushingfloatstrue
+ \ifsomefloatwaiting
+ \par
+ % if kept, then option and definitely off in gridmode ! ! ! !
+ % \ifvmode \prevdepth\maxdimen \fi % prevents whitespace; problematic in icare tests
+ \OTRONEdodoflushfloats
+ \fi
+ \global\savednoffloats\zerocount
+ \global\somefloatwaitingfalse
+ \global\flushingfloatsfalse}
+
+\def\OTRONEflushfloatbox % nog verder doorvoeren en meer info in marge
+ {\ifcenterfloatbox \ifdim\wd\floatbox<\hsize
+ \setbox\floatbox\hbox to \hsize{\hss\box\floatbox\hss}%
+ \fi \fi
+ \snaptogrid\hbox{\iftestfloatbox\ruledhbox\fi{\copy\floatbox}}}
+
+\def\OTRONEdodoflushfloats % much in common with OTRSET
+ {\ifsomefloatwaiting
+ \ifpackflushedfloats
+ \centerfloatboxfalse
+ \dogetfloat
+ \ifdim\wd\floatbox>\makeupwidth
+ \global\setbox\floatbox\hbox to \makeupwidth{\hss\box\floatbox\hss}%
+ \fi
+ \OTRONEsetvsize
+ \!!widtha\wd\floatbox
+ \dofloatflushedinfo
+ \doloop
+ {\ifsomefloatwaiting
+ \dosavefloatstatus
+ \dogetfloat
+ \advance\!!widtha 1em % variable
+ \advance\!!widtha \wd\floatbox\relax
+ \ifdim\!!widtha>\hsize
+ \dorestorefloatstatus
+ \global\somefloatwaitingtrue
+ \exitloop
+ \else
+ \global\setbox\floatbox\hbox
+ {\ifcase\columndirection % nog document wide
+ \ifvoid\savedfloatbox\else
+ \ifhbox\savedfloatbox\unhbox\else\box\fi\savedfloatbox\hfil
+ \fi
+ \ifhbox\floatbox\unhbox\else\box\fi\floatbox
+ \else
+ \ifhbox\floatbox\unhbox\else\box\fi\floatbox
+ \ifvoid\savedfloatbox\else
+ \hfil\ifhbox\savedfloatbox\unhbox\else\box\fi\savedfloatbox
+ \fi
+ \fi}%
+ \dofloatflushedinfo
+ \fi
+ \else
+ \exitloop
+ \fi}%
+ \global\setbox\floatbox\hbox to \hsize
+ {\hfil\ifhbox\floatbox\unhbox\else\box\fi\floatbox\hfil}%
+ \else
+ %\bgroup % \box\floatbox can be in use!? messy
+ \dogetfloat
+ %\doplacefloatbox
+ %\egroup
+ \dofloatflushedinfo
+ \fi
+ % there is a chance that due to rounding errors, the float
+ % fits on a page where it was first rejected, in which case
+ % the prevdepth is -maxdimen and we cannot obey the grid
+ \doplacefloatbox
+ \expandafter\OTRONEdodoflushfloats
+ \fi}
+
+\def\OTRONEdocheckiffloatfits % vervangen ivm downward comp
+ {\ifnofloatpermitted
+ \global\roomforfloatfalse
+ \else
+ % new per 31/5/2004, should be an option, only one column mode
+ \begingroup
+ \scratchdimen\dimexpr\pagetotal+\lineheight\relax
+ \ifdim\scratchdimen>\pagegoal
+ \goodbreak % hack ? needed in icare-az
+ \fi
+ % should be an option
+ \endgroup
+ \dimen0\dimexpr\pagetotal+\ht\floatbox+\dp\floatbox+\floattopskip-\pageshrink\relax
+ %\message{c:\the\mofcolumns,t:\the\pagetotal,g:\the\pagegoal}%\wait
+ \dimen2\pagegoal
+ \relax % needed
+ \ifcase\textfloatmethod
+ % method 0 : raw
+ \or
+ % method 1 : safe
+ \dimen2 .99\pagegoal
+ \or
+ % method 2 : tight
+ \advance\dimen0 -\onepoint
+ \fi
+ \relax % really needed ! ! ! !
+ \ifdim\dimen0>\dimen2
+ \global\roomforfloatfalse
+ \else
+ \global\roomforfloattrue
+ \fi
+ \fi}
+
+\def\OTRONEflushsavedfloats
+ {\dosetbothinserts}
+
+% TODO: TEST FIRST, NO CORRECTION NEEDED IN GRID MODE, EVT OPTION
+
+\def\OTRONEsomeherefloat[#1]% spacing between two successive must be better
+ {\baselinecorrection % not really needed in grid mode:
+ %\ifgridsnapping \else \baselinecorrection \fi % ! ! ! test test test ! ! ! !
+ \doplacefloatbox
+ \doinsertfloatinfo
+ \dohandlenextfloatindent}
+
+% \def\OTRONEsomefixdfloat % [#1]
+% {\docheckiffloatfits
+% \ifroomforfloat\else
+% \goodbreak
+% \fi
+% \showmessage\m!floatblocks9\empty
+% \someherefloat} % [#1]
+%
+% better:
+%
+% \dorecurse{50}
+% {[before normal] \input thuan
+% \placefigure{normal}{\framed[height=1cm,width=8cm]{}}
+% \placefigure{normal}{\framed[height=2cm,width=8cm]{}}
+% [before force] \input thuan
+% \placefigure[force]{force}{\framed[height=8cm,width=8cm]{}}}
+
+\chardef\fixedfloatmethod=3
+
+% \def\OTRONEsomefixdfloat % [#1]
+% {\docheckiffloatfits
+% \ifroomforfloat\else
+% \ifzeropt\pagetotal
+% % let's assume that there is room
+% \else
+% \ifcase\fixedfloatmethod
+% % disabled
+% \or % 1 (old method)
+% \goodbreak
+% \or % 2 (safe method)
+% \page
+% \or % 3 (keeps in stream)
+% \vskip\textheight
+% \vskip-\textheight
+% \or % 4 (also keeps in place)
+% \dosomebreak\nobreak
+% \fi
+% \fi
+% \fi
+% \showmessage\m!floatblocks9\empty
+% \someherefloat} % [#1]
+
+\def\OTRONEsomefixdfloat % [#1]
+ {% there is (in mkii) no good way to prevent a break
+ % so better fail than mess, we can get loose from
+ % heads, so be it
+ \showmessage\m!floatblocks9\empty
+ \OTRONEsomeherefloat} % [#1]
+
+\def\OTRONEsomesidefloat[#1]% links, rechts NOG TESTEN EN AANPASSEN
+ {\ifinsidecolumns
+ \someelsefloat[\v!here]%
+ \else
+ %\checkwaitingfloats{#1}%
+ \def\logsidefloat
+ {\doinsertfloatinfo}%
+ \setbox\floatbox\vbox{\box\floatbox}%
+ \wd\floatbox\floatwidth
+ \processfirstactioninset
+ [#1]
+ [ \v!left=>\leftfloat {\box\floatbox},
+ \v!right=>\rightfloat {\box\floatbox},
+ \v!inleft=>\leftmarginfloat {\box\floatbox},
+ \v!inright=>\rightmarginfloat{\box\floatbox},
+ \v!leftmargin=>\leftmarginfloat {\box\floatbox},
+ \v!rightmargin=>\rightmarginfloat{\box\floatbox},
+ \v!leftedge=>\leftedgefloat {\box\floatbox},
+ \v!rightedge=>\rightedgefloat {\box\floatbox},
+ \v!backspace=>\backspacefloat {\box\floatbox},
+ \v!cutspace=>\cutspacefloat {\box\floatbox},
+ \v!inmargin=>\cutspacefloat {\box\floatbox}]%
+ \doifinset\v!tall{#1}\flushsidefloatsafterpar
+ \fi}
+
+\def\OTRONEdosomepagefloat#1[#2]%
+ {%\checkwaitingfloats{#1}%
+ \global\setbox#1\vbox
+ {\unvbox#1%
+ \vbox to \textheight
+ {\doifnotinset\v!high{#2}\vfill
+ \box\floatbox
+ \doifnotinset\v!low{#2}\vfill}%
+ \goodbreak}%
+ \doinsertfloatinfo}
+
+\def\OTRONEsomepagefloat {\OTRONEdosomepagefloat\collectedpagefloats}
+\def\OTRONEsomeleftpagefloat {\OTRONEdosomepagefloat\collectedleftpagefloats}
+\def\OTRONEsomerightpagefloat{\OTRONEdosomepagefloat\collectedrightpagefloats}
+
+\def\OTRONEsometopsfloat[#1]%
+ {\ifdim\topinserted=\zeropoint
+ \topofinserttrue
+ \else
+ \topofinsertfalse
+ \fi
+ \global\advance\topinserted \ht\floatbox
+ \global\advance\topinserted \dp\floatbox
+ \global\advance\topinserted \floatbottomskip
+ \insert\topins
+ {\forgetall
+ \iftopofinsert
+ \topskipcorrection % [xx] new: see icare topbleed
+ \kern-\lineskip\par\prevdepth\maxdimen
+ \else
+ %\blank[-\@@bkspaceafter,\@@bkspacebefore]% inserts can't look back
+ \betweenfloatblanko
+ \fi
+ \flushfloatbox
+ \blank[\@@bkspaceafter]}%
+ \doinsertfloatinfo}
+
+\def\OTRONEsomebotsfloat[#1]%
+ {\global\advance\botinserted \ht\floatbox
+ \global\advance\botinserted \dp\floatbox
+ \global\advance\botinserted \floattopskip
+ \insert\botins
+ {\forgetall
+ \blank[\@@bkspacebefore]%
+ \flushfloatbox}%
+ %\global\nofloatpermittedtrue
+ \doinsertfloatinfo}
+
+\def\OTRONEsomefacefloat[#1]% untested
+ {\startopposite\flushfloatbox\stopopposite}
+
+\def\OTRONEnextcolumn[#1]%
+ {}
+
+\protect \endinput
diff --git a/tex/context/base/page-par.tex b/tex/context/base/page-par.tex
index fa1723d37..a5dea2e63 100644
--- a/tex/context/base/page-par.tex
+++ b/tex/context/base/page-par.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-par, % copied from page-lin
%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Line Numbering,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Paragraph Numbering}
+\writestatus{loading}{ConTeXt Page Macros / Paragraph Numbering}
\unprotect
diff --git a/tex/context/base/page-plg.tex b/tex/context/base/page-plg.tex
index 486d4e183..3203b923c 100644
--- a/tex/context/base/page-plg.tex
+++ b/tex/context/base/page-plg.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-pls,
%D version=2003.03.16,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Page Setup,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -13,7 +13,7 @@
\ifx\pageareabox\undefined \else \endinput \fi
-\writestatus{loading}{Context Core Macros / Extra Page Building}
+\writestatus{loading}{ConTeXt Page Macros / Extra Page Building}
%D This feature has been present for a while but has never been
%D exploited: pluggable pagebuilders. The next example code
diff --git a/tex/context/base/page-run.tex b/tex/context/base/page-run.tex
index 302a1b5a0..ae5af81e9 100644
--- a/tex/context/base/page-run.tex
+++ b/tex/context/base/page-run.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Runtime Macros}
+\writestatus{loading}{ConTeXt Page Macros / Runtime Macros}
\unprotect
diff --git a/tex/context/base/page-set.tex b/tex/context/base/page-set.tex
index 16a9dcc99..a9d42bce8 100644
--- a/tex/context/base/page-set.tex
+++ b/tex/context/base/page-set.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-set,
%D version=2000.10.20,
-%D title=\CONTEXT\ OTR Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Column Sets,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -15,7 +15,7 @@
% some day: cleanup and go etex
-\writestatus{loading}{Context OTR Macros / Column Sets}
+\writestatus{loading}{ConTeXt Page Macros / Column Sets}
% todo : last longer than previous
% todo : block span over last column if footnotes
@@ -217,13 +217,13 @@
\edef\!!stringb{\the\scratchcounter}%
\dostepwiserecurse \zerocount \columnmaxcells \plusone
{\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname
- \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box
+ \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname
\ifcsname\@otr@:\!!stringb:\recurselevel\endcsname
- \csname\@otr@:\!!stringb:\recurselevel\endcsname
+ \box\csname\@otr@:\!!stringb:\recurselevel\endcsname
%\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\csname\@otr@:\!!stringb:\recurselevel\endcsname
\else
- \voidb@x
- %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\voidb@x
+ \emptybox
+ %\global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox
\expandafter\newbox\csname\@otr@:\!!stringb:\recurselevel\endcsname
\fi
\else
@@ -239,7 +239,7 @@
{\let\!!stringa\recurselevel
\dostepwiserecurse \zerocount \columnmaxcells \plusone
{\ifcsname\@otr@:\!!stringa:\recurselevel\endcsname
- \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\box\voidb@x
+ \global\setbox\csname\@otr@:\!!stringa:\recurselevel\endcsname\emptybox
\else
\expandafter\newbox\csname\@otr@:\!!stringa:\recurselevel\endcsname
\fi}}%
@@ -266,7 +266,7 @@
{\doOTRSETsetgridcells{\copy\placeholderboxb}}
\def\OTRSETerasegridcells#1#2#3#4%
- {\doOTRSETsetgridcells{\box\voidb@x}{#1}{#2}{#3}{#4}{\box\voidb@x}}
+ {\doOTRSETsetgridcells{\emptybox}{#1}{#2}{#3}{#4}{\emptybox}}
\def\setupcolumnsetlines{\doquintupleempty\dosetupcolumnsettrick[l]}
\def\setupcolumnsetstart{\doquintupleempty\dosetupcolumnsettrick[s]}
@@ -298,15 +298,15 @@
\ifnum\csname#1\mofcolumns\endcsname=\zerocount
#2%
\else
- \number\numexpr(\ifnum\csname#1\mofcolumns\endcsname<\zerocount
- \columnmaxcells+\fi\csname#1\mofcolumns\endcsname)%
+ \number\numexpr\ifnum\csname#1\mofcolumns\endcsname<\zerocount
+ \columnmaxcells+\fi\csname#1\mofcolumns\endcsname\relax
\fi
\else\ifcsname#10\endcsname
\ifnum\csname#10\endcsname=\zerocount
#2%
\else
- \number\numexpr(\ifnum\csname#10\endcsname<\zerocount
- \columnmaxcells+\fi\csname#10\endcsname)%
+ \number\numexpr\ifnum\csname#10\endcsname<\zerocount
+ \columnmaxcells+\fi\csname#10\endcsname\relax
\fi
\else
#2%
diff --git a/tex/context/base/page-sid.tex b/tex/context/base/page-sid.tex
index 02c4261fb..90d6ec1a7 100644
--- a/tex/context/base/page-sid.tex
+++ b/tex/context/base/page-sid.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-sid,
%D version=2000.10.20,
-%D title=\CONTEXT\ OTR Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Side Floats,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context OTR Macros / Side Floats}
+\writestatus{loading}{ConTeXt Page Macros / Side Floats}
\unprotect
diff --git a/tex/context/base/page-spr.tex b/tex/context/base/page-spr.tex
index 53d508752..06947a36a 100644
--- a/tex/context/base/page-spr.tex
+++ b/tex/context/base/page-spr.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Spreading}
+\writestatus{loading}{ConTeXt Page Macros / Spreading}
% This module is experimental and not yet official!
diff --git a/tex/context/base/page-str.tex b/tex/context/base/page-str.tex
index 1a68adf52..2fb53bc6a 100644
--- a/tex/context/base/page-str.tex
+++ b/tex/context/base/page-str.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=page-str,
%D version=2006.03.21,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Page Macros,
%D subtitle=Page Streams,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Page Macros / Page Streams}
+\writestatus{loading}{ConTeXt Page Macros / Page Streams}
%D The first version of this component of \CONTEXT\ was written
%D for Thomas Schmitz who asked for parallel page streams. While
@@ -92,7 +92,7 @@
\def\saveoutputstream[#1]%
{\writestatus{otr}{saving otr stream #1}%
\ifvoid\normalpagebox
- \global\setbox\outputstreamtag{#1}\voidbox
+ \global\setbox\outputstreamtag{#1}\emptybox
\else
\global\setbox\outputstreamtag{#1}\vbox
{\presetoutputstream
diff --git a/tex/context/base/page-txt.tex b/tex/context/base/page-txt.mkii
index b40ecb16e..9fe73bec1 100644
--- a/tex/context/base/page-txt.tex
+++ b/tex/context/base/page-txt.mkii
@@ -13,7 +13,7 @@
% \setuplayouttext in manual
-\writestatus{loading}{Context Page Macros / Texts}
+\writestatus{loading}{ConTeXt Page Macros / Texts}
\unprotect
@@ -430,9 +430,9 @@
\stoplayoutcomponent}%
\addtextbackground\scratchpagebox
\addtextgridlayer\scratchpagebox
- \localstarttextcolor
+ \localstarttextcolor % does not work in mkiv
\box\scratchpagebox
- \localstoptextcolor
+ \localstoptextcolor % so we have to change this
\bgroup
\hskip\rightmargindistance
\ifdim\rightmarginwidth>\zeropoint
diff --git a/tex/context/base/page-txt.mkiv b/tex/context/base/page-txt.mkiv
new file mode 100644
index 000000000..57bc02882
--- /dev/null
+++ b/tex/context/base/page-txt.mkiv
@@ -0,0 +1,808 @@
+%D \module
+%D [ file=page-txt, % copied from main-001,
+%D version=1997.03.31,
+%D title=\CONTEXT\ Page Macros,
+%D subtitle=Texts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% where we can do some mkiv cleanup
+
+% \setuplayouttext in manual
+
+\writestatus{loading}{ConTeXt Page Macros / Texts}
+
+\unprotect
+
+\let\dodummypageskip\gobbleoneargument % obsolete
+
+%D Interfacing between this and other modules is handled by
+%D the following macros. The current state of a text line
+%D (header, footer, etc.) is checked by:
+%D
+%D \starttyping
+%D \resetlayouttextlines
+%D \stoptyping
+%D
+%D The main text box is finished by the following macro:
+%D
+%D \starttyping
+%D \getmainbox <box> <\vbox|\unvbox>
+%D \stoptyping
+%D
+%D The text lines are collected with:
+%D
+%D \starttyping
+%D \gettextboxes
+%D \stoptyping
+%D
+%D It is possible to extens the default content of the text
+%D areas by appending content to the following token list
+%D registers:
+
+\newtoks\toptextcontent \newtoks\leftedgetextcontent
+\newtoks\headertextcontent \newtoks\leftmargintextcontent
+\newtoks\footertextcontent \newtoks\rightmargintextcontent
+\newtoks\bottomtextcontent \newtoks\rightedgetextcontent
+
+\newtoks\texttextcontent
+
+%D \macros
+%D {setuptop, setupheader, setuptext,
+%D setupfooter, setupbottom}
+%D
+%D The macros in this module sometimes look a bit more complicated
+%D than needed, which is a direct result of the fact that their
+%D ancestors are quite old and upward compatibility is a must.
+%D
+%D \showsetup{setuptop}
+%D \showsetup{setupheader}
+%D \showsetup{setuptext}
+%D \showsetup{setupfooter}
+%D \showsetup{setupbottom}
+
+\def\setuplayouttext
+ {\dotripleempty\dosetuplayouttext}
+
+\def\dosetuplayouttext[#1][#2][#3]% beware, non global
+ {\ifthirdargument
+ \getparameters[\??tk#1#2][#3]%
+ \else
+ %\getparameters[\??tk#1\v!text][#2]%
+ \edef\previoustextstate{\getvalue{\??tk#1\c!state}}%
+ \getparameters[\??tk#1][#2]%
+ \doifnotvalue{\??tk#1\c!state}\previoustextstate
+ {%\checkcurrentlayout % no
+ \edef\currenttextstate{\getvalue{\??tk#1\c!state}}%
+ % speed optimization (calculating backgrounds takes time)
+ \doifcommon{\previoustextstate,\currenttextstate}{\v!high,\v!none}
+ {\calculatevsizes
+ \recalculatebackgrounds
+ \recalculatelogos}}%
+ \fi}
+
+\def\setuptop {\dotripleempty\dosetuplayouttext[\v!top]}
+\def\setupheader {\dotripleempty\dosetuplayouttext[\v!header]}
+\def\setuptext {\dotripleempty\dosetuplayouttext[\v!text]}
+\def\setupfooter {\dotripleempty\dosetuplayouttext[\v!footer]}
+\def\setupbottom {\dotripleempty\dosetuplayouttext[\v!bottom]}
+
+%D \macros
+%D {noheaderandfooterlines,notopandbottomlines}
+%D
+%D Although not really needed, the following shortcuts
+%D sometimes come in handy.
+%D
+%D \showsetup{noheaderandfooterlines}
+%D \showsetup{notopandbottomlines}
+
+\def\noheaderandfooterlines
+ {\setupheader[\c!state=\v!empty]%
+ \setupfooter[\c!state=\v!empty]}
+
+\def\notopandbottomlines
+ {\setuptop [\c!state=\v!empty]%
+ \setupbottom[\c!state=\v!empty]}
+
+%D \macros
+%D {setuptoptexts, setupheadertexts, setuptexttexts,
+%D setupfootertexts, setupbottomtexts}
+%D
+%D The next macros take one or more arguments. The exact setup
+%D depends on the number of arguments. Although not that
+%D intuitive, the current scheme evolved out of the original.
+%D When margin and edge texts as well as middle texts showed
+%D up, the current odd|/|even scheme surfaced.
+%D
+%D \showsetup{setuptoptexts}
+%D \showsetup{setupheadertexts}
+%D \showsetup{setuptexttexts}
+%D \showsetup{setupfootertexts}
+%D \showsetup{setupbottomtexts}
+
+\def\setuptoptexts {\dosixtupleempty\dosetuptexts[\v!top]}
+\def\setupheadertexts {\dosixtupleempty\dosetuptexts[\v!header]}
+\def\setuptexttexts {\dosixtupleempty\dosetuptexts[\v!text]}
+\def\setupfootertexts {\dosixtupleempty\dosetuptexts[\v!footer ]}
+\def\setupbottomtexts {\dosixtupleempty\dosetuptexts[\v!bottom]}
+
+%D The left, right and center variables can also be set
+%D directly using the previously discussed macros.
+
+\def\dosetuptexts[#1][#2][#3][#4][#5][#6]%
+ {\ifsixthargument
+ \setvalue{\??tk#1#2\c!lefttext}%
+ {\dodoubletexts{\??tk#1}{#2}%
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#3}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#6}}%
+ \setvalue{\??tk#1#2\c!righttext}%
+ {\dodoubletexts{\??tk#1}{#2}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}%
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#5}}%
+ \else\iffifthargument
+ \setvalue{\??tk#1\v!text\c!lefttext}%
+ {\dodoubletexts{\??tk#1}\v!text
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#2}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#5}}%
+ \setvalue{\??tk#1\v!text\c!righttext}%
+ {\dodoubletexts{\??tk#1}\v!text
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}%
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#4}}%
+ \else\iffourthargument
+ \setvalue{\??tk#1#2\c!lefttext}%
+ {\dodoubletexts{\??tk#1}{#2}
+ {\c!leftstyle\c!leftcolor\c!leftwidth}{#3}%
+ {\c!leftstyle\c!leftcolor\c!leftwidth}{#3}}%
+ \setvalue{\??tk#1#2\c!righttext}%
+ {\dodoubletexts{\??tk#1}{#2}
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}}%
+ \else\ifthirdargument
+ \setvalue{\??tk#1\v!text\c!lefttext}%
+ {\dodoubletexts{\??tk#1}\v!text
+ {\c!leftstyle\c!leftcolor\c!leftwidth}{#2}%
+ {\c!leftstyle\c!leftcolor\c!leftwidth}{#2}}%
+ \setvalue{\??tk#1\v!text\c!righttext}%
+ {\dodoubletexts{\??tk#1}\v!text
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}}%
+ \else\ifsecondargument % new
+ \letvalue{\??tk#1\v!text\c!lefttext }\empty
+ \letvalue{\??tk#1\v!text\c!righttext}\empty
+ \setvalue{\??tk#1\v!text\c!middletext }%
+ {\dosingletexts{\??tk#1}\v!text\c!style\c!color\c!width{#2}}%
+ \else
+ \dosixtupleempty\dosetuptexts[#1][\v!text][][][][]%
+ \dosixtupleempty\dosetuptexts[#1][\v!margin][][][][]%
+ \dosixtupleempty\dosetuptexts[#1][\v!edge ][][][][]%
+ \fi\fi\fi\fi\fi}
+
+%D Left and right texts are swapped on odd and even pages, but
+%D only when double sided typesetting is enabled.
+
+\def\dodoubletexts#1#2#3#4#5#6%
+ {\doifoddpageelse
+ {\dosingletexts{#1}{#2}#3{#4}} % #3 => provides three arguments
+ {\dosingletexts{#1}{#2}#5{#6}}} % #5 => provides three arguments
+
+%D The next macro will be cleaned up amd made less messy and
+%D dependent.
+
+\def\placetextlinestrut#1%
+ {\doifvalue{#1\c!strut}\v!yes{\setstrut\strut}}
+
+% \def\dosingletexts#1#2#3#4#5#6%
+% {\bgroup
+% \defconvertedargument\ascii{#6}%
+% \doifsomething\ascii
+% {\doattributes{#1#2}#3#4%
+% {\placetextlinestrut{#1}% here !
+% %\doifdefinedelse{\??mk\ascii\c!coupling} % brrr
+% \doifelsemarking\ascii
+% {\dolimitatetexts{#1#2#5}{\getmarking[\ascii][\v!first]}}
+% {\ConvertConstantAfter\doifelse\v!pagenumber{#6}
+% \placelocationpagenumber % pretty low level
+% {\ConvertConstantAfter\doifelse\v!date{#6}
+% {\currentdate}
+% {% #6{}{}{} -> {} needed for macros that look
+% % ahead, like \uniqueMPgraphic
+% \ignorecrlf\dolimitatetexts{#1#2#5}{#6{}{}{}}}}}}}%
+% \egroup}
+
+\def\dosingletexts#1#2#3#4#5#6%
+ {\bgroup
+ \defconvertedargument\ascii{#6}% no longer \defconvertedargument
+ \ifx\ascii\empty\else
+ \dostartattributes{#1#2}#3#4\empty
+ \placetextlinestrut{#1}% here !
+ \doifelsemarking\ascii
+ {\dolimitatetexts{#1#2#5}{\getmarking[\ascii][\v!first]}}%
+ {\ifcsname\??tk->\ascii\endcsname
+ \csname\??tk->\ascii\endcsname
+ \else
+ % #6{}{}{} -> {} needed for macros that look
+ % ahead, like \uniqueMPgraphic
+ \ignorecrlf\dolimitatetexts{#1#2#5}{#6{}{}{}}%
+ \fi}%
+ \dostopattributes
+ \fi
+ \egroup}
+
+\setvalue{\??tk->\v!pagenumber}{\placelocationpagenumber}
+\setvalue{\??tk->\v!date }{\currentdate}
+
+%D When specified, the texts are automatically limited in
+%D length.
+
+\def\dolimitatetexts#1#2%
+ {\doifelsevaluenothing{#1}{#2}{\limitatetext{#2}{\getvalue{#1}}{\unknown}}}
+
+%D The placement of text is hooked into the token lists
+%D associated to the area at hand.
+
+\appendtoks \placelayouttextline\v!top \topheight \to \toptextcontent
+\appendtoks \placelayouttextline\v!header\headerheight \to \headertextcontent
+\appendtoks \placelayouttextline\v!text \textheight \to \texttextcontent
+\appendtoks \placelayouttextline\v!footer\footerheight \to \footertextcontent
+\appendtoks \placelayouttextline\v!bottom\bottomheight \to \bottomtextcontent
+
+%D Texts can be disabled, moved up and ignored, depending in
+%D the \type {status} variable. This is handled by the next
+%D couple of macros.
+
+\def\settextlinestatus #1{\edef\textlinestatus{\csname\??tk#1\c!state\endcsname}}
+%def\resettextlinestatus#1{\letgvalue{\??tk#1\c!state}\v!normal}
+
+\def\resettextlinestatus#1% postpone
+ {\setgvalue{\??tk#1\s!reset}{\letgvalue{\??tk#1\c!state}\v!normal}}
+
+\def\placelayouttextline#1% #2
+ {\settextlinestatus{#1}%
+ \csname\string\placelayouttextline
+ \ifcsname\string\placelayouttextline\textlinestatus\endcsname
+ \textlinestatus
+ \else
+ \s!unknown
+ \fi
+ \endcsname{#1}} % {#2}
+
+\def\doifelselayouttextline#1% shown or not
+ {\doifinsetelse{\getvalue{\??tk#1\c!state}}{\v!normal,\v!start}}
+
+\def\doifelselayoutsomeline#1% present or not
+ {\edef\!!stringa{\csname\??tk#1\c!state\endcsname}%
+ \ifx\!!stringa\v!none
+ \@EA\secondoftwoarguments
+ \else\ifx\!!stringa\v!high
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \@EAEAEA\firstoftwoarguments
+ \fi\fi}
+
+% \doplacelayouttextline does the actual placement (when a non-zero height)
+
+\newconditional\resyncaftertextline
+
+\setvalue{\string\placelayouttextline\v!normal }{\doplacelayouttextline}
+\setvalue{\string\placelayouttextline }{\doplacelayouttextline}
+
+\setvalue{\string\placelayouttextline\v!none}#1#2%
+ {}
+
+\setvalue{\string\placelayouttextline\v!high}#1#2%
+ {\global\settrue\resyncaftertextline
+ \resettextlinestatus{#1}}
+
+\setvalue{\string\placelayouttextline\v!empty}#1#2%
+ {\resettextlinestatus{#1}}
+
+\setvalue{\string\placelayouttextline\v!start}#1#2%
+ {\resettextlinestatus{#1}%
+ \doplacelayouttextline{#1}{#2}}
+
+\setvalue{\string\placelayouttextline\v!stop}#1#2%
+ {}
+
+\setvalue{\string\placelayouttextline\v!nomarking}#1#2%
+ {\bgroup
+ \resettextlinestatus{#1}%
+ \let\dogetmarking\nogetmarking
+ \doplacelayouttextline{#1}{#2}%
+ \egroup}
+
+\setvalue{\string\placelayouttextline\s!unknown}#1#2%
+ {\global\settrue\resyncaftertextline
+ \bgroup % new
+ \resettextlinestatus{#1}%
+ \getvalue{\??tk#1\textlinestatus}%
+ \getvalue{\??tk#1\v!text \textlinestatus}%
+ \getvalue{\??tk#1\v!margin\textlinestatus}%
+ \getvalue{\??tk#1\v!edge \textlinestatus}%
+ \doplacelayouttextline{#1}{#2}%
+ \egroup}
+
+%D The following macro has to be called after a page
+%D is flushed.
+
+\def\resetlayouttextline#1%
+ {\getvalue {\??tk#1\s!reset}%
+ \letgvalue{\??tk#1\s!reset}\relax}
+
+\def\resetlayouttextlines
+ {\resetlayouttextline\v!top
+ \resetlayouttextline\v!header
+ \resetlayouttextline\v!text
+ \resetlayouttextline\v!footer
+ \resetlayouttextline\v!bottom
+ \ifconditional\resyncaftertextline
+ \doglobal\calculatevsizes
+ \recalculatebackgrounds
+ \recalculatelogos
+ \global\setfalse\resyncaftertextline
+ \fi}
+
+% \settext[header][text][middle][xxx][yyy]
+
+\def\settextcontent
+ {\doquintupleempty\dosettextcontent}
+
+\def\dosettextcontent[#1][#2][#3][#4][#5]% header text middle text/text
+ {\iffifthargument
+ \setvalue{\??tk#1#2\executeifdefined{:\c!text:#3:}\c!middletext}%
+ {\dodoubletexts{\??tk#1}{#2}%
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#4}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#5}}%
+ \else\iffourthargument
+ \setvalue{\??tk#1#2\executeifdefined{:\c!text:#3:}\c!middletext}%
+ {\dodoubletexts{\??tk#1}{#2}%
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#4}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}}%
+ \else\ifthirdargument
+ \setvalue{\??tk#1#2\c!middletext}%
+ {\dodoubletexts{\??tk#1}{#2}%
+ {\c!leftstyle \c!leftcolor \c!leftwidth }{#3}%
+ {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}}%
+ \fi\fi\fi}
+
+\def\resettextcontent
+ {\dotripleempty\doresettextcontent}
+
+\def\doresettextcontent[#1][#2][#3]% header text middle
+ {\ifthirdargument
+ \letvalue{\??tk#1#2\executeifdefined{:\c!text:#3:}\c!middletext}\empty
+ \else\ifsecondargument
+ \letvalue{\??tk#1#2\c!lefttext }\empty
+ \letvalue{\??tk#1#2\c!middletext}\empty
+ \letvalue{\??tk#1#2\c!righttext }\empty
+ \fi\fi}
+
+\let\settext \settextcontent % downward compatibility
+\let\resettext\resettextcontent % downward compatibility
+
+\setvalue{:\c!middle:\c!text:}{\c!middletext}
+\setvalue{:\c!left :\c!text:}{\c!lefttext }
+\setvalue{:\c!right :\c!text:}{\c!righttext }
+
+%D The next series of macros is not that easy to read,
+%D because they hook into the main page building macros. By
+%D using token list registers for the text content, we can
+%D easily hook in other code, like menu generators.
+%D
+%D Beware: the token lists are always expanded, also when the
+%D height of an area is zero. This is because reset actions can
+%D be part of them.
+
+\newbox\scratchpagebox
+
+\def\gettextboxes
+ {\setbox\scratchpagebox\vbox
+ {\dontcomplain
+ \calculatereducedvsizes
+ \swapmargins
+ \offinterlineskip
+ \vskip\dimexpr-\topheight-\topdistance\relax
+ \the\toptextcontent
+ \vskip\dimexpr\topheight+\topdistance\relax
+ \the\headertextcontent
+ \vskip\dimexpr\headerheight+\headerdistance\relax
+ \placepositionanchors
+ \vskip-\textheight
+ \the\texttextcontent
+ \vskip\textheight
+ \the\everyendoftextbody
+ \vskip\footerdistance
+ \the\footertextcontent
+ \vskip\dimexpr\footerheight+\bottomdistance\relax
+ \the\bottomtextcontent
+ \vskip\bottomheight
+ \vfilll}%
+ \smashbox\scratchpagebox
+ \box\scratchpagebox}
+
+\def\getmainbox#1#2%
+ {\setbox\scratchpagebox\vbox
+ {\offinterlineskip % na \paginaletter !
+ \calculatereducedvsizes
+ \calculatehsizes
+ \swapmargins
+ \vskip\dimexpr\headerheight+\headerdistance+\layoutparameter\c!textdistance\relax
+ \hbox to \makeupwidth
+ {\bgroup
+ \swapmargins
+ \goleftonpage
+ \ifdim\leftedgewidth>\zeropoint
+ \the\leftedgetextcontent
+ \hskip\leftedgewidth
+ \fi
+ \hskip\leftedgedistance
+ \ifdim\leftmarginwidth>\zeropoint
+ \the\leftmargintextcontent
+ \hskip\leftmarginwidth
+ \fi
+ \hskip\leftmargindistance
+ \egroup
+ \mkprocesspagecontents{#2}%
+ \settextpagecontent\scratchpagebox{#1}{#2}%
+ \setbox\scratchpagebox\vbox % can we avoid this extra box
+ {\startlayoutcomponent{textbody}{text body}%
+ \box\scratchpagebox
+ \stoplayoutcomponent}%
+ \addtextbackground\scratchpagebox
+ \addtextgridlayer\scratchpagebox
+ \localstarttextcolor % does not work in mkiv
+ \box\scratchpagebox
+ \localstoptextcolor % so we have to change this
+ \bgroup
+ \hskip\rightmargindistance
+ \ifdim\rightmarginwidth>\zeropoint
+ \the\rightmargintextcontent
+ \hskip\rightmarginwidth
+ \fi
+ \hskip\rightedgedistance
+ \ifdim\rightedgewidth>\zeropoint
+ \the\rightedgetextcontent
+ \hskip\rightedgewidth
+ \fi
+ \egroup
+ \hss}}%
+ \smashbox\scratchpagebox
+ \box\scratchpagebox}
+
+%D The main text area has to be combined with some additional
+%D (tracing) information.
+
+% will be overloaded in page-lyr
+
+\def\settextpagecontent#1#2#3% #2 and #3 will disappear
+ {\setbox#1\hbox to \makeupwidth
+ {\hss % so don't change this
+ \vbox to \textheight
+ {\offinterlineskip
+ \freezetextwidth
+ \hsize\textwidth % local variant of \sethsize
+ \boxmaxdepth\maxdepth
+ \noindent % content can be < \hsize
+ \dopagecontents#2#3}%
+ \hss}%
+ \dp#1\zeropoint}
+
+\definepalet
+ [layout]
+ [grid=red,
+ page=green]
+
+\def\addtextgridlayer#1% tzt run time
+ {\ifcase\showgridstate\else % 1=bottom 2=top
+ \setgridbox\scratchbox\makeupwidth\textheight
+ \setbox#1\hbox
+ {\ifcase\showgridstate\or\or\box#1\hskip-\makeupwidth\fi
+ \bgroup % color
+ \startlayoutcomponent{gridcolumns}{grid columns}%
+ \incolortrue
+ \ifcase\layoutcolumns\else
+ \gray
+ \hbox to \makeupwidth
+ {\dorecurse\layoutcolumns
+ {\hskip\layoutcolumnwidth
+ \ifnum\recurselevel<\layoutcolumns
+ \vrule
+ \!!height\ht\scratchbox
+ \!!depth\dp\scratchbox
+ \!!width\layoutcolumndistance
+ \fi}}%
+ \hskip-\makeupwidth
+ \fi
+ \stoplayoutcomponent
+ \startlayoutcomponent{gridlines}{grid lines}%
+ \startcolor[layout:grid]\box\scratchbox\stopcolor
+ \stoplayoutcomponent
+ \egroup
+ \ifcase\showgridstate\or\hskip-\makeupwidth\box#1\fi}%
+ \fi}
+
+%D The placement of a whole line is handled by the next two
+%D macros. These are hooked into the general purpose token
+%D list registers mentioned before.
+
+\def\ignoredlinebreak{\unskip\space\ignorespaces}
+
+\def\doplacelayouttextline#1#2%
+ {\ifdim#2>\zeropoint\relax % prevents pagenumbers when zero height
+ \goleftonpage
+ \hbox
+ {\setbox\scratchpagebox\vbox to #2
+ {%\forgetall
+ \vsize#2\relax
+ \normalbaselines
+ \let\\\ignoredlinebreak
+ \let\crlf\ignoredlinebreak
+ %\getvalue{\??tk#1\v!text\c!before}%
+ \getvalue{\??tk#1\c!before}%
+ \doifbothsidesoverruled
+ {\dodoplacelayouttextline#1\c!lefttext \c!middletext\c!righttext\gobbleoneargument\getvalue}
+ {\dodoplacelayouttextline#1\c!lefttext \c!middletext\c!righttext\gobbleoneargument\getvalue}
+ {\dodoplacelayouttextline#1\c!righttext\c!middletext\c!lefttext \getvalue\gobbleoneargument}%
+ %\getvalue{\??tk#1\v!text\c!after}%
+ \getvalue{\??tk#1\c!after}%
+ \kern\zeropoint}% keep the \dp, beware of \vtops, never change this!
+ \dp\scratchpagebox\zeropoint
+ \box\scratchpagebox}%
+ \vskip-#2\relax
+ \fi}
+
+\def\dodoplacelayouttextline#1#2#3#4#5#6% \hsize toegevoegd, \hss's niet meer wijzigen
+ {\hbox
+ {\ifdim\leftedgewidth>\zeropoint
+ \dododoplacelayouttextline\leftedgewidth{#1}\v!edge
+ {\hss\getvalue{\??tk#1\v!edge#2}}%
+ \hskip\leftedgedistance
+ \fi
+ \ifdim\leftmarginwidth>\zeropoint
+ \dododoplacelayouttextline\leftmarginwidth{#1}\v!margin
+ {\hbox to \leftmarginwidth
+ {\hss\getvalue{\??tk#1\v!margin#2}}%
+ \hskip-\leftmarginwidth
+ \hbox to \leftmarginwidth
+ {\hss#5{\??tk#1\v!margin\c!margintext}}}%
+ \hskip\leftmargindistance
+ \fi
+ \ifdim\makeupwidth>\zeropoint
+ \dododoplacelayouttextline\makeupwidth{#1}\v!text
+ {\hbox to \makeupwidth
+ {\@@nmpre{#5{\??tk#1\v!text\c!marginedgetext}}%
+ \getvalue{\??tk#1\v!text#2}\hss}%
+ \hskip-\makeupwidth
+ \hbox to \makeupwidth
+ {\hss\getvalue{\??tk#1\v!text#3}\hss}%
+ \hskip-\makeupwidth
+ \hbox to \makeupwidth
+ {\hss\getvalue{\??tk#1\v!text#4}%
+ \@@nmpos{#6{\??tk#1\v!text\c!marginedgetext}}}}%
+ \fi
+ \ifdim\rightmarginwidth>\zeropoint
+ \hskip\rightmargindistance
+ \dododoplacelayouttextline\rightmarginwidth{#1}\v!margin
+ {\hbox to \rightmarginwidth
+ {\getvalue{\??tk#1\v!margin#4}\hss}%
+ \hskip-\rightmarginwidth
+ \hbox to \rightmarginwidth
+ {#6{\??tk#1\v!margin\c!margintext}\hss}}%
+ \fi
+ \ifdim\rightedgewidth>\zeropoint
+ \hskip\rightedgedistance
+ \dododoplacelayouttextline\rightedgewidth{#1}\v!edge
+ {\getvalue{\??tk#1\v!edge#4}\hss}%
+ \fi}}
+
+% \def\dododoplacelayouttextline#1#2#3#4%
+% {\vbox % to \vsize
+% {\hsize#1\relax
+% \getvalue{\??tk#2#3\c!voor}
+% \hbox to #1{#4}%
+% \getvalue{\??tk#2#3\c!na}}}
+
+\def\dododoplacelayouttextline#1#2#3#4%
+ {\vbox % to \vsize
+ {\hsize#1\relax
+ \getvalue{\??tk#2#3\c!before}%
+ \startlayoutcomponent{t:#2:#3}{area #2 #3}%
+ \hbox to #1{#4}%
+ \stoplayoutcomponent
+ \getvalue{\??tk#2#3\c!after}}}
+
+%D Although it is far better to use backgrounds for this
+%D purpose, one can add a rule in the following way. This
+%D method makes the rules disappear in case of an empty text
+%D line. Consider this a feature.
+%D
+%D \starttyping
+%D \setupheadertexts[left][right]
+%D
+%D \setupheader[text][after=\hrule,style=bold]
+%D
+%D \starttext
+%D \input tufte \page
+%D \setupheader[state=empty]
+%D \input tufte \page
+%D \stoptext
+%D \stoptyping
+
+%D The next twosome will be done differently (using an
+%D existing auxiliary macro).
+
+% \def\@@nmpre#1{\setbox0\hbox{#1}\ifdim\wd0=\zeropoint\else\unhbox0\tfskip\fi}
+% \def\@@nmpos#1{\setbox0\hbox{#1}\ifdim\wd0=\zeropoint\else\tfskip\unhbox0\fi}
+
+% cleaner
+
+\def\@@nmpre#1{\doiftext{#1}{{#1}\tfskip}}
+\def\@@nmpos#1{\doiftext{#1}{\tfskip{#1}}}
+
+% newer
+
+\def\@@nmprepos#1#2#3#4#5%
+ {\doifelsenothing\@@nmwidth
+ {\doiftext{#5}{#1{#5}#2}}
+ {\doiftext{#5}{\hbox to \@@nmwidth{#3{#5}#4}}}}
+
+\def\@@nmpre{\@@nmprepos\empty\tfskip\relax\hss}
+\def\@@nmpos{\@@nmprepos\tfskip\empty\hss\relax}
+
+%D This code will move to \type {page-flt.tex}.
+
+\appendtoks
+ \plaatsrechtermargeblok \hskip-\rightmarginwidth
+\to \rightmargintextcontent
+
+\appendtoks
+ \plaatslinkermargeblok \hskip-\leftmarginwidth
+\to \leftmargintextcontent
+
+%D The next hook will later be used for keeping track of
+%D positions, i.e.\ it will provide a proper (page
+%D dependent) reference point.
+
+\ifx\undefined\placepositionanchors
+ \def\placepositionanchors{\vskip\textheight}
+\fi
+
+%D \macros
+%D {definetext}
+%D
+%D Some macros ago, we implemented the \type {status} option
+%D \type {unknown}. This one is used to take care of
+%D symbolic texts handlers.
+%D
+%D \showsetup{definetext}
+%D
+%D The next example demonstrates how we can use this
+%D mechanism to provide page (event) dependent text lines.
+%D
+%D \starttyping
+%D \definetext[chapter][footer][pagenumber]
+%D \setuphead[chapter][header=high,footer=chapter]
+%D \setupheadertexts[pagenumber]
+%D \setupfootertexts[left][right]
+%D \chapter{eerste} \dorecurse{20}{\input tufte \relax}
+%D \chapter{tweede} \dorecurse{20}{\input tufte \relax}
+%D \stoptyping
+
+\def\definetext
+ {\doseventupleempty\dodefinetext}
+
+\def\dodefinetext[#1][#2][#3][#4][#5][#6][#7]%
+ {\ifseventhargument
+ \setvalue{\??tk#2#3#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4][#5][#6][#7]}%
+ \else\ifsixthargument
+ \setvalue{\??tk #2#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4][#5][#6]}%
+ \else\iffifthargument
+ \setvalue{\??tk#2#3#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4][#5]}%
+ \else\iffourthargument
+ \setvalue{\??tk #2#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4]}%
+ \else
+ \setvalue{\??tk #2#1}{\dosixtupleempty\dosetuptexts[#2][#3]}%
+ \fi\fi\fi\fi}
+
+%D The rest of this file is dedicated to setting up the
+%D texts. This code is not that impressive.
+
+\setupheadertexts [\v!text] [] []
+\setupheadertexts [\v!margin] [] []
+\setupheadertexts [\v!edge] [] []
+
+\setupfootertexts [\v!text] [] []
+\setupfootertexts [\v!margin] [] []
+\setupfootertexts [\v!edge] [] []
+
+\setuptexttexts [\v!text] [] []
+\setuptexttexts [\v!margin] [] []
+\setuptexttexts [\v!edge] [] []
+
+\setupbottomtexts [\v!text] [] []
+\setupbottomtexts [\v!margin] [] []
+\setupbottomtexts [\v!edge] [] []
+
+\setuptoptexts [\v!text] [] []
+\setuptoptexts [\v!margin] [] []
+\setuptoptexts [\v!edge] [] []
+
+% alternative
+%
+% \def\resetlayouttekst%
+% {\dodoubleempty\doresetlayouttekst}
+%
+% \def\doresetlayouttekst[#1][#2]%
+% {\ifsecondargument
+% \dodoresetlayouttekst[#1][#2]%
+% \else
+% \dodoresetlayouttekst[#1][\v!tekst]%
+% \fi}
+%
+% \def\dodoresetlayouttekst[#1][#2]%
+% {...}
+%
+% \def\docommand#1%
+% {\resetlayouttekst[#1][\v!tekst]%
+% \resetlayouttekst[#1][\v!marge]%
+% \resetlayouttekst[#1][\v!rand]}
+
+%D We combine a lot of similar settings in a macro that
+%D we will later dispose.
+
+\def\dodocommand[#1][#2]%
+ {\getparameters
+ [\??tk#1#2]
+ [%\c!state=\v!normal, % moved
+ \c!before=, % both global and local are used
+ \c!after=, % both global and local are used
+ \c!strut=, % the local one, not (yet) used
+ \c!style=\getvalue{\??tk#1\c!style},% hm, got lost
+ \c!color=\getvalue{\??tk#1\c!color}, % hm, got lost
+ \c!lefttext=,
+ \c!middletext=,
+ \c!righttext=,
+ \c!marginedgetext=,
+ \c!margintext=,
+ \c!width=]%
+ \inheritparameter[\??tk#1#2][\c!leftstyle ][\c!style ]%
+ \inheritparameter[\??tk#1#2][\c!rightstyle ][\c!style ]%
+ \inheritparameter[\??tk#1#2][\c!leftcolor ][\c!color ]%
+ \inheritparameter[\??tk#1#2][\c!rightcolor ][\c!color ]%
+ \inheritparameter[\??tk#1#2][\c!leftwidth ][\c!width]%
+ \inheritparameter[\??tk#1#2][\c!rightwidth][\c!width]}
+
+\def\docommand#1%
+ {\dodocommand[#1][\v!text]%
+ \dodocommand[#1][\v!margin]%
+ \dodocommand[#1][\v!edge]}
+
+\docommand\v!top
+\docommand\v!header
+\docommand\v!footer
+\docommand\v!text
+\docommand\v!bottom
+
+\let\docommand \relax
+\let\dodocommand\relax
+
+%D While the header and footer lines are moved away from the
+%D main text, the top and bottom lines are centered.
+
+\setuptop [\c!state=\v!normal,\c!before=\vss,\c!after=\vss,\c!strut=]
+\setupheader[\c!state=\v!normal,\c!before=, \c!after=\vss,\c!strut=\v!yes]
+\setuptext [\c!state=\v!normal,\c!before=\vss,\c!after=\vss,\c!strut=]
+\setupfooter[\c!state=\v!normal,\c!before=\vss,\c!after=, \c!strut=\v!yes]
+\setupbottom[\c!state=\v!normal,\c!before=\vss,\c!after=\vss,\c!strut=]
+
+\setuptop [\c!style=,\c!color=]
+\setupheader[\c!style=,\c!color=]
+\setuptext [\c!style=,\c!color=]
+\setupfooter[\c!style=,\c!color=]
+\setupbottom[\c!style=,\c!color=]
+
+\protect \endinput
diff --git a/tex/context/base/ppchtex.tex b/tex/context/base/ppchtex.mkii
index a7800acd4..285b0004e 100644
--- a/tex/context/base/ppchtex.tex
+++ b/tex/context/base/ppchtex.mkii
@@ -56,7 +56,7 @@
% getoont. Buiten Context genereren we een melding:
\doifundefined{usemodule}
- {\writestatus{loading}{Context Chemical Macro's / 1996.3.1}}
+ {\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.
@@ -337,6 +337,13 @@
\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}
@@ -404,7 +411,7 @@
\def\doifchemicalnumber#1#2#3%
{\doifnumberelse{#1}
- {\ifnum#1>\maxchemical
+ {\ifnum#1>\maxchemical\relax
\writestatus{ppchtex}{number #1 is skipped}%
\else
#3%
@@ -1161,14 +1168,15 @@
{\def\@@chemicalframe{\chemicalframe}}
{\def\@@chemicalframe{}}%
\dosetsubscripts
- \setbox2=\hbox{$\@@dochemicalstyle{\@@localchemicalformat \chemicaltext}$}%
+ \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{\@@dochemicalcolor\box2}}%
+ \setbox2=\hbox{\@@chemicalframe{\box2}}%
\ifdim\wd2>\wd6
\doifelse{#1}{0}
{\doifnot{#2}{0}{\wd2=\wd6}}
@@ -3374,24 +3382,35 @@ RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{},
%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\@@chemicalchemicalrulethickness
+ {\scratchdimen\@@chemicalrulethickness
\def\chemicalattributes
{withpen pencircle scaled \the\scratchdimen\space
withcolor }%
- \doifelsenothing\@@chemicalchemicalrulecolor
+ \doifelsenothing\@@chemicalrulecolor
{\edef\chemicalattributes{\chemicalattributes black}}
- {\edef\chemicalattributes
- {\chemicalattributes \MPcolor{\@@chemicalchemicalrulecolor}}}%
+ {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalrulecolor}}}%
\startMPdrawing
drawoptions (\chemicalattributes) ;
\stopMPdrawing}
-\let\@@chemicalcolor\empty
-
\def\@@dochemicalcolor
{\doifsomething\@@chemicalcolor{\color[\@@chemicalcolor]}}
diff --git a/tex/context/base/ppchtex.mkiv b/tex/context/base/ppchtex.mkiv
new file mode 100644
index 000000000..fb9e610e9
--- /dev/null
+++ b/tex/context/base/ppchtex.mkiv
@@ -0,0 +1,3359 @@
+%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 copyright={PRAGMA / Hans Hagen \& Ton Otten},
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten}]
+%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
+
+%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}
+
+\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
+ \dostartchemical}
+
+\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]%
+ {\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 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\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% % 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},
+ 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}
+
+\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/base/prop-ini.tex b/tex/context/base/prop-ini.mkii
index 084842fdd..035a40c93 100644
--- a/tex/context/base/prop-ini.tex
+++ b/tex/context/base/prop-ini.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Property Macros / initialization}
+\writestatus{loading}{ConTeXt Property Macros / Initialization}
%D Welcome to the third alternative of this yet undocumented module,
%D which means that there is no public interface yet!
@@ -28,7 +28,7 @@
% more efficient:
-\def\currentproperty {\csname\??py:c:\number\propertylevel\endcsname} % string
+\def\currentproperty {\csname\??py:c:\number\propertylevel\endcsname} % string
\def\currentpropertytype {\csname\??py\currentproperty\c!type\endcsname}
\def\docheckproperty % watch the s instead of e
@@ -73,14 +73,11 @@
\def\defineproperty
{\dotripleempty\dodefineproperty}
-\def\defineproperty
- {\dotripleempty\dodefineproperty}
-
\def\dodefineproperty[#1]%
- {\ifundefined{\??py#1\c!global}%
- \expandafter\dododefineproperty
- \else
+ {\ifcsname\??py#1\c!global\endcsname
\expandafter\nododefineproperty
+ \else
+ \expandafter\dododefineproperty
\fi[#1]}
% due to initializations/counters, definitions are always global
@@ -92,10 +89,12 @@
\def\dododefineproperty[#1][#2][#3]% global ! ! !
{\getgparameters[\??py#1][\c!global=\v!no,\c!type=#2,\c!method=\v!none,#3]% global ! ! ! !
- \expandafter\newcount\csname\??py:l:#2\endcsname % current level
- \expandafter\newcount\csname\??py:p:#2\endcsname % previous level
- \global\csname\??py:p:#2\endcsname\minusone
- \global\expandafter\expandafter\let\csname\??py:c:0\endcsname\empty
+ \ifcsname\??py:l:#2\endcsname \else
+ \expandafter\newcount\csname\??py:l:#2\endcsname % current level
+ \expandafter\newcount\csname\??py:p:#2\endcsname % previous level
+ \global\csname\??py:p:#2\endcsname\minusone
+ \global\expandafter\expandafter\let\csname\??py:c:0\endcsname\empty
+ \fi
\letgvalue{\??py\s!check#1}\docheckproperty
\doifelsevalue{\??py#1\c!method}\v!command
{\doifelsevalue{\??py#1\c!global}\v!yes
diff --git a/tex/context/base/prop-ini.mkiv b/tex/context/base/prop-ini.mkiv
new file mode 100644
index 000000000..2320f1069
--- /dev/null
+++ b/tex/context/base/prop-ini.mkiv
@@ -0,0 +1,150 @@
+%D \module
+%D [ file=prop-ini,
+%D version=2003.04.20,
+%D title=\CONTEXT\ Property Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Property Macros / Initialization}
+
+%D Welcome to the third alternative of this yet undocumented module,
+%D which means that there is no public interface yet!
+
+\unprotect
+
+\newcount\propertylevel
+
+\def\currentpropertylevel {\csname\??py:l:\currentpropertytype\endcsname} % counter
+\def\previouspropertylevel{\csname\??py:p:\currentpropertytype\endcsname} % counter
+
+\def\currentproperty {\csname\??py:c:\number\currentpropertylevel \endcsname} % string
+\def\previousproperty {\csname\??py:c:\number\previouspropertylevel\endcsname} % string
+
+% more efficient:
+
+\def\currentproperty {\csname\??py:c:\number\propertylevel\endcsname} % string
+\def\currentpropertytype {\csname\??py\currentproperty\c!type\endcsname}
+
+\def\docheckproperty % watch the s instead of e
+ {\csname\s!check\currentpropertytype property\endcsname
+ \global\expandafter\let\csname\??py\s!check\currentproperty\endcsname\empty}
+
+\def\checkproperty[#1]%
+ {\bgroup
+ \def\currentproperty{#1}%
+ \csname\??py\s!check\currentproperty\endcsname
+ \egroup}
+
+\unexpanded\def\property[#1]%
+ {\groupedcommand{\dostartproperty{#1}}\dostopproperty}
+
+\unexpanded\def\startproperty[#1]%
+ {\dostartproperty{#1}}
+
+\unexpanded\def\stopproperty
+ {\dostopproperty}
+
+\def\dostartgproperty
+ {\begingroup\dostartproperty}
+
+\def\dostopgproperty
+ {\dostopproperty\endgroup}
+
+\def\dostartproperty#1% evt pack: {current}{level}{
+ {\global\advance\propertylevel\plusone
+ \@EAEAEA\xdef\currentproperty{#1}%
+ \global\advance\previouspropertylevel\plusone
+ \global\advance\currentpropertylevel\plusone
+ \csname\??py\s!check\currentproperty\endcsname
+ \csname\s!start\currentpropertytype\s!property\endcsname}
+
+\def\dostopproperty
+ {\csname\s!stop\currentpropertytype\s!property\endcsname
+ \global\advance\currentpropertylevel\minusone
+ \global\advance\previouspropertylevel\minusone
+ \global\advance\propertylevel\minusone}
+
+\def\defineproperty
+ {\dotripleempty\dodefineproperty}
+
+\def\dodefineproperty[#1]%
+ {\ifcsname\??py#1\c!global\endcsname
+ \expandafter\nododefineproperty
+ \else
+ \expandafter\dododefineproperty
+ \fi[#1]}
+
+% due to initializations/counters, definitions are always global
+%
+% global : yes : ungrouped
+% no : grouped
+% method : command : define commands
+% none : no commands
+
+\def\dododefineproperty[#1][#2][#3]% global ! ! !
+ {\getgparameters[\??py#1][\c!global=\v!no,\c!type=#2,\c!method=\v!none,#3]% global ! ! ! !
+ \ifcsname\??py:l:#2\endcsname \else
+ \expandafter\newcount\csname\??py:l:#2\endcsname % current level
+ \expandafter\newcount\csname\??py:p:#2\endcsname % previous level
+ \global\csname\??py:p:#2\endcsname\minusone
+ \global\expandafter\expandafter\let\csname\??py:c:0\endcsname\empty
+ \fi
+ \letgvalue{\??py\s!check#1}\docheckproperty
+ \doifelsevalue{\??py#1\c!method}\v!command
+ {\doifelsevalue{\??py#1\c!global}\v!yes
+ {\unexpanded\setgvalue{\e!start#1}{\dostartproperty{#1}}%
+ \unexpanded\setgvalue{\e!stop #1}{\dostopproperty}}%
+ {\unexpanded\setgvalue{\e!start#1}{\dostartgproperty{#1}}%
+ \unexpanded\setgvalue{\e!stop #1}{\dostopgproperty}}}%
+ {\doifelsevalue{\??py#1\c!global}\v!yes
+ {\unexpanded\setgvalue{\e!start#2}[##1]{\dostartproperty{##1}}%
+ \unexpanded\setgvalue{\e!stop #2}{\dostopproperty}}%
+ {\unexpanded\setgvalue{\e!start#2}[##1]{\dostartgproperty{##1}}%
+ \unexpanded\setgvalue{\e!stop #2}{\dostopgproperty}}}}
+
+\def\nododefineproperty[#1][#2][#3]%
+ {}
+
+\def\doifelseproperty#1{\doifdefinedelse{\??py#1\c!global}}
+
+\def\setupproperty
+ {\dodoubleempty\dosetupproperty}
+
+\def\dosetupproperty[#1][#2]% local
+ {\ifsecondargument
+ \getparameters[\??py#1][#2]%
+ \else
+ \getparameters[\??py][#1]%
+ \fi}
+
+\letvalue{\??py\s!empty}\empty
+
+% beware, normally \*parameter concerns the current one
+
+\def\propertyparameter#1#2% expands to #1 when not defined (see \define...)
+ {\csname\??py
+ \ifcsname\??py#1#2\endcsname
+ #1#2%
+ \else\ifcsname\??py\csname\??py#1\c!type\endcsname#2\endcsname
+ \csname\??py#1\c!type\endcsname#2%
+ \else
+ \s!empty
+ \fi\fi
+ \endcsname}
+
+\def\currentpropertyparameter % self and class
+ {\propertyparameter\currentproperty}
+
+\def\checkedpropertyparameter#1% only self
+ {\executeifdefined{\??py\currentproperty#1}}
+
+\def\definepropertyhandler#1{\setvalue{\??py*#1}}
+\def\propertyhandler #1{\getvalue{\??py*#1}}
+
+\protect \endinput
diff --git a/tex/context/base/prop-lay.mkii b/tex/context/base/prop-lay.mkii
index 5dce6c33b..aeec94bb2 100644
--- a/tex/context/base/prop-lay.mkii
+++ b/tex/context/base/prop-lay.mkii
@@ -11,6 +11,11 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Property Macros / Layers}
+
+%D Highly experimental, will probably change/evolve. Also, quite certainly
+%D we will no longer share code between mkii and mkiv.
+
\unprotect
\let\currentlayerproperty\empty
@@ -41,4 +46,98 @@
\expandafter\gobbleoneargument
\fi}
+\setglobalsystemreference \rt!exec \v!HideLayer {hidelayer}
+\setglobalsystemreference \rt!exec \v!VideLayer {videlayer}
+\setglobalsystemreference \rt!exec \v!ToggleLayer {togglelayer}
+
+\setexecutecommandcheck {hidelayer} \domakelayerpropertylist
+\setexecutecommandcheck {videlayer} \domakelayerpropertylist
+\setexecutecommandcheck {togglelayer} \domakelayerpropertylist
+
+% \currentlayerproperty
+% \checklayerproperty
+% \startlayerproperty
+% \stoplayerproperty
+% \domakelayerpropertylist
+
+%D \starttext
+%D
+%D \setuppapersize[S4][S4]
+%D \setuplayout[middle]
+%D \setupcolors[state=start]
+%D \setupinteraction[state=start,color=,contrastcolor=]
+%D
+%D \defineproperty [L1] [layer] [title=layer 1]
+%D \defineproperty [L2] [layer] [title=layer 2]
+%D
+%D \button{HIDE L1}[HideLayer{L1}]
+%D \button{VIDE L1}[VideLayer{L1}]
+%D \button{TOGGLE L1}[ToggleLayer{L1}]
+%D
+%D \button{HIDE L2}[HideLayer{L2}]
+%D \button{VIDE L2}[VideLayer{L2}]
+%D \button{TOGGLE L2}[ToggleLayer{L2}]
+%D
+%D \noheaderandfooterlines \centerbox{\startoverlay
+%D {\definedfont[Mono at 150pt]%
+%D \startproperty[L1]\red TEST\stopproperty}
+%D {\definedfont[Mono at 150pt]%
+%D \startproperty[L2]\green TEST\stopproperty}
+%D \stopoverlay} \page
+%D
+%D \noheaderandfooterlines \centerbox{\startoverlay
+%D {\definedfont[Mono at 15pt]%
+%D \goto{\startproperty[L1]\red TEST\stopproperty}[CloseDocument]}
+%D {\definedfont[Mono at 15pt]%
+%D \goto{\startproperty[L2]\green TEST\stopproperty}[CloseDocument]}
+%D \stopoverlay} \page
+%D
+%D \startproperty[L1]
+%D level 1 \startproperty[L2]level 2 \stopproperty level 1
+%D \stopproperty
+%D
+%D \startproperty[L1]
+%D level 1 \page \startproperty[L2]level 2 \stopproperty level 1
+%D \stopproperty
+%D
+%D \stoptext
+
+%D Handy for tracing:
+
+\def\showlayoutcomponents
+ {\let\startlayoutcomponent\dostartlayoutcomponent
+ \let\stoplayoutcomponent \dostoplayoutcomponent}
+
+\def\dodefinelayoutcomponent#1#2%
+ {\doifelsenothing{#2}%
+ {\defineproperty[#1][\s!layer]}%
+ {\defineproperty[#1][\s!layer][\c!title=#2]}}
+
+\def\dostartlayoutcomponent#1#2%
+ {\doifelseproperty{#1}\donothing{\dodefinelayoutcomponent{#1}{#2}}%
+ \startproperty[#1]}
+
+\def\dostoplayoutcomponent
+ {\stopproperty}
+
+\let\startlayoutcomponent\gobbletwoarguments
+\let\stoplayoutcomponent \relax
+
\protect \endinput
+
+% \def\remaplayering
+% {\dodoubleargument\doremaplayering}
+%
+% \def\remaplayering[#1][#2]%
+% {\setvalue{\??lm#1}{#2}}
+%
+% \def\remappedlayering#1%
+% {\ifcsname\??lm#1\endcsname
+% \@EA\remappedlayering\csname\??lm#1\endcsname\else#1%
+% \fi}
+%
+% \def\startshowlayering#1#2%
+% {\ifshowlayering
+% \defineproperty[\remappedlayering{#1}][\s!layer][\c!titel=#2]%
+% \startproperty[\remappedlayering{#1}]%
+% \fi}
diff --git a/tex/context/base/prop-lay.mkiv b/tex/context/base/prop-lay.mkiv
index 051e2e5be..0cd4bc2c8 100644
--- a/tex/context/base/prop-lay.mkiv
+++ b/tex/context/base/prop-lay.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=prop-lay,
-%D version=2008.09.16,
+%D version=2003.04.20,
%D title=\CONTEXT\ Property Macros,
%D subtitle=Layers,
%D author=Hans Hagen,
@@ -11,6 +11,11 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Property Macros / Layers}
+
+%D Highly experimental, will probably change/evolve. Also, quite certainly
+%D we will no longer share code between mkii and mkiv.
+
% test, nesting is somewhat special with layers
%
% \defineproperty[hans][layer]
@@ -49,4 +54,106 @@
\expandafter\gobbleoneargument
\fi}
+\ifdefined\setglobalsystemreference
+
+ \setglobalsystemreference \rt!exec \v!HideLayer {hidelayer}
+ \setglobalsystemreference \rt!exec \v!VideLayer {videlayer}
+ \setglobalsystemreference \rt!exec \v!ToggleLayer {togglelayer}
+
+ \setexecutecommandcheck {hidelayer} \domakelayerpropertylist
+ \setexecutecommandcheck {videlayer} \domakelayerpropertylist
+ \setexecutecommandcheck {togglelayer} \domakelayerpropertylist
+
+\else
+
+ % todo, but after a full split (saves dev time)
+
+\fi
+
+% \currentlayerproperty
+% \checklayerproperty
+% \startlayerproperty
+% \stoplayerproperty
+% \domakelayerpropertylist
+
+%D \starttext
+%D
+%D \setuppapersize[S4][S4]
+%D \setuplayout[middle]
+%D \setupcolors[state=start]
+%D \setupinteraction[state=start,color=,contrastcolor=]
+%D
+%D \defineproperty [L1] [layer] [title=layer 1]
+%D \defineproperty [L2] [layer] [title=layer 2]
+%D
+%D \button{HIDE L1}[HideLayer{L1}]
+%D \button{VIDE L1}[VideLayer{L1}]
+%D \button{TOGGLE L1}[ToggleLayer{L1}]
+%D
+%D \button{HIDE L2}[HideLayer{L2}]
+%D \button{VIDE L2}[VideLayer{L2}]
+%D \button{TOGGLE L2}[ToggleLayer{L2}]
+%D
+%D \noheaderandfooterlines \centerbox{\startoverlay
+%D {\definedfont[Mono at 150pt]%
+%D \startproperty[L1]\red TEST\stopproperty}
+%D {\definedfont[Mono at 150pt]%
+%D \startproperty[L2]\green TEST\stopproperty}
+%D \stopoverlay} \page
+%D
+%D \noheaderandfooterlines \centerbox{\startoverlay
+%D {\definedfont[Mono at 15pt]%
+%D \goto{\startproperty[L1]\red TEST\stopproperty}[CloseDocument]}
+%D {\definedfont[Mono at 15pt]%
+%D \goto{\startproperty[L2]\green TEST\stopproperty}[CloseDocument]}
+%D \stopoverlay} \page
+%D
+%D \startproperty[L1]
+%D level 1 \startproperty[L2]level 2 \stopproperty level 1
+%D \stopproperty
+%D
+%D \startproperty[L1]
+%D level 1 \page \startproperty[L2]level 2 \stopproperty level 1
+%D \stopproperty
+%D
+%D \stoptext
+
+%D Handy for tracing:
+
+\def\showlayoutcomponents
+ {\let\startlayoutcomponent\dostartlayoutcomponent
+ \let\stoplayoutcomponent \dostoplayoutcomponent}
+
+\def\dodefinelayoutcomponent#1#2%
+ {\doifelsenothing{#2}%
+ {\defineproperty[#1][\s!layer]}%
+ {\defineproperty[#1][\s!layer][\c!title=#2]}}
+
+\def\dostartlayoutcomponent#1#2%
+ {\doifelseproperty{#1}\donothing{\dodefinelayoutcomponent{#1}{#2}}%
+ \startproperty[#1]}
+
+\def\dostoplayoutcomponent
+ {\stopproperty}
+
+\let\startlayoutcomponent\gobbletwoarguments
+\let\stoplayoutcomponent \relax
+
\protect \endinput
+
+% \def\remaplayering
+% {\dodoubleargument\doremaplayering}
+%
+% \def\remaplayering[#1][#2]%
+% {\setvalue{\??lm#1}{#2}}
+%
+% \def\remappedlayering#1%
+% {\ifcsname\??lm#1\endcsname
+% \@EA\remappedlayering\csname\??lm#1\endcsname\else#1%
+% \fi}
+%
+% \def\startshowlayering#1#2%
+% {\ifshowlayering
+% \defineproperty[\remappedlayering{#1}][\s!layer][\c!titel=#2]%
+% \startproperty[\remappedlayering{#1}]%
+% \fi}
diff --git a/tex/context/base/prop-lay.tex b/tex/context/base/prop-lay.tex
deleted file mode 100644
index 2f6b2ef02..000000000
--- a/tex/context/base/prop-lay.tex
+++ /dev/null
@@ -1,105 +0,0 @@
-%D \module
-%D [ file=prop-lay,
-%D version=2003.04.20,
-%D title=\CONTEXT\ Property Macros,
-%D subtitle=Layers,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Property Macros / layers}
-
-%D Highly experimental, will probably change/evolve. Also, quite certainly
-%D we will no longer share code between mkii and mkiv.
-
-\unprotect
-
-%D Plugin:
-
-\loadmarkfile{prop-lay}
-
-% \currentlayerproperty
-% \checklayerproperty
-% \startlayerproperty
-% \stoplayerproperty
-% \domakelayerpropertylist
-
-%D shared interface, rest in mk files
-
-\setglobalsystemreference \rt!exec \v!HideLayer {hidelayer}
-\setglobalsystemreference \rt!exec \v!VideLayer {videlayer}
-\setglobalsystemreference \rt!exec \v!ToggleLayer {togglelayer}
-
-\setexecutecommandcheck {hidelayer} \domakelayerpropertylist
-\setexecutecommandcheck {videlayer} \domakelayerpropertylist
-\setexecutecommandcheck {togglelayer} \domakelayerpropertylist
-
-% \defineproperty [debugging] [\s!layer] [title=debugging]
-% \defineproperty [navigation] [\s!layer] [title=navigation]
-
-%D \starttext
-%D
-%D \setuppapersize[S4][S4]
-%D \setuplayout[middle]
-%D \setupcolors[state=start]
-%D \setupinteraction[state=start,color=,contrastcolor=]
-%D
-%D \defineproperty [L1] [layer] [title=layer 1]
-%D \defineproperty [L2] [layer] [title=layer 2]
-%D
-%D \button{HIDE L1}[HideLayer{L1}]
-%D \button{VIDE L1}[VideLayer{L1}]
-%D \button{TOGGLE L1}[ToggleLayer{L1}]
-%D
-%D \button{HIDE L2}[HideLayer{L2}]
-%D \button{VIDE L2}[VideLayer{L2}]
-%D \button{TOGGLE L2}[ToggleLayer{L2}]
-%D
-%D \noheaderandfooterlines \centerbox{\startoverlay
-%D {\definedfont[Mono at 150pt]%
-%D \startproperty[L1]\red TEST\stopproperty}
-%D {\definedfont[Mono at 150pt]%
-%D \startproperty[L2]\green TEST\stopproperty}
-%D \stopoverlay} \page
-%D
-%D \noheaderandfooterlines \centerbox{\startoverlay
-%D {\definedfont[Mono at 15pt]%
-%D \goto{\startproperty[L1]\red TEST\stopproperty}[CloseDocument]}
-%D {\definedfont[Mono at 15pt]%
-%D \goto{\startproperty[L2]\green TEST\stopproperty}[CloseDocument]}
-%D \stopoverlay} \page
-%D
-%D \startproperty[L1]
-%D level 1 \startproperty[L2]level 2 \stopproperty level 1
-%D \stopproperty
-%D
-%D \startproperty[L1]
-%D level 1 \page \startproperty[L2]level 2 \stopproperty level 1
-%D \stopproperty
-%D
-%D \stoptext
-
-\fetchruntimecommand \showlayoutcomponents {\f!propprefix\s!run}
-
-\protect \endinput
-
-% \def\remaplayering
-% {\dodoubleargument\doremaplayering}
-%
-% \def\remaplayering[#1][#2]%
-% {\setvalue{\??lm#1}{#2}}
-%
-% \def\remappedlayering#1%
-% {\ifcsname\??lm#1\endcsname
-% \@EA\remappedlayering\csname\??lm#1\endcsname\else#1%
-% \fi}
-%
-% \def\startshowlayering#1#2%
-% {\ifshowlayering
-% \defineproperty[\remappedlayering{#1}][\s!layer][\c!titel=#2]%
-% \startproperty[\remappedlayering{#1}]%
-% \fi}
diff --git a/tex/context/base/prop-mis.mkii b/tex/context/base/prop-mis.mkii
index 3b372546d..d8e9ab173 100644
--- a/tex/context/base/prop-mis.mkii
+++ b/tex/context/base/prop-mis.mkii
@@ -11,8 +11,41 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Property Macros / Miscelaneous}
+
+%D This module contains some code that has been in use in some
+%D private modules (p-*). These features depend on the fact
+%D that pdftex writes the page content as one stream.
+
+%D EXPERIMENTAL
+
\unprotect
+%D Stream based overprint and knockout:
+
+\defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command]
+\defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command]
+
+%D Negation.
+
+\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command]
+\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command]
+
+%D Special font effects.
+
+\setupproperty
+ [\s!effect]
+ [\c!rulethickness=\zeropoint,
+ \c!stretch=0]
+
+\defineproperty [\v!inner] [\s!effect] [\c!rulethickness=.25pt]
+\defineproperty [\v!outer] [\s!effect] [\c!rulethickness=.25pt]
+\defineproperty [\v!both] [\s!effect] [\c!rulethickness=.25pt]
+\defineproperty [\v!normal] [\s!effect]
+\defineproperty [\v!hidden] [\s!effect]
+
+\defineproperty [\v!stretch] [\s!effect] [\c!stretch=1]
+
%D Overprint cum suis.
\definepropertyhandler \v!overprint {\dostartoverprint}
@@ -110,6 +143,7 @@
\definepropertyhandler \v!outer {1}
\definepropertyhandler \v!both {2}
\definepropertyhandler \v!hidden {3}
+\definepropertyhandler \v!stretch{0}
\def\effectpropertydata#1%
{{\propertyhandler{#1}}%
diff --git a/tex/context/base/prop-mis.mkiv b/tex/context/base/prop-mis.mkiv
index ee292155e..623b10f13 100644
--- a/tex/context/base/prop-mis.mkiv
+++ b/tex/context/base/prop-mis.mkiv
@@ -11,8 +11,41 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt Property Macros / Miscelaneous}
+
+%D This module contains some code that has been in use in some
+%D private modules (p-*). These features depend on the fact
+%D that pdftex writes the page content as one stream.
+
+%D EXPERIMENTAL
+
\unprotect
+%D Stream based overprint and knockout:
+
+\defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command]
+\defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command]
+
+%D Negation.
+
+\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command]
+\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command]
+
+%D Special font effects.
+
+\setupproperty
+ [\s!effect]
+ [\c!rulethickness=\zeropoint,
+ \c!stretch=0]
+
+\defineproperty [\v!inner] [\s!effect] [\c!rulethickness=.25pt]
+\defineproperty [\v!outer] [\s!effect] [\c!rulethickness=.25pt]
+\defineproperty [\v!both] [\s!effect] [\c!rulethickness=.25pt]
+\defineproperty [\v!normal] [\s!effect]
+\defineproperty [\v!hidden] [\s!effect]
+
+\defineproperty [\v!stretch] [\s!effect] [\c!stretch=1]
+
%D Overprint cum suis.
\definepropertyhandler \v!overprint {\dotriggeroverprint\v!overprint}
@@ -39,6 +72,7 @@
\definepropertyhandler \v!outer {\mktriggereffect\v!outer }
\definepropertyhandler \v!both {\mktriggereffect\v!both }
\definepropertyhandler \v!hidden {\mktriggereffect\v!hidden}
+\definepropertyhandler \v!stretch{\mktriggereffect\v!normal}
\def\starteffectproperty{\mktriggereffect\currentproperty}
\def\stopeffectproperty {\mktriggereffect\v!normal }
diff --git a/tex/context/base/prop-mis.tex b/tex/context/base/prop-mis.tex
deleted file mode 100644
index d78e0c584..000000000
--- a/tex/context/base/prop-mis.tex
+++ /dev/null
@@ -1,53 +0,0 @@
-%D \module
-%D [ file=prop-mis,
-%D version=2004.05.29, % some code moved from private modules
-%D title=\CONTEXT\ Property Macros,
-%D subtitle=Miscelaneous,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Property Macros / initialization}
-
-%D This module contains some code that has been in use in some
-%D private modules (p-*). These features depend on the fact
-%D that pdftex writes the page content as one stream.
-
-%D EXPERIMENTAL
-
-\unprotect
-
-%D Stream based overprint and knockout:
-
-\defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command]
-\defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command]
-
-%D Negation.
-
-\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command]
-\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command]
-
-%D Special font effects.
-
-\setupproperty
- [\s!effect]
- [\c!rulethickness=\zeropoint,
- \c!stretch=0]
-
-\defineproperty [\v!inner] [\s!effect] [\c!rulethickness=.25pt]
-\defineproperty [\v!outer] [\s!effect] [\c!rulethickness=.25pt]
-\defineproperty [\v!both] [\s!effect] [\c!rulethickness=.25pt]
-\defineproperty [\v!normal] [\s!effect]
-\defineproperty [\v!hidden] [\s!effect]
-
-\defineproperty [\v!stretch] [\s!effect] [\c!stretch=1]
-
-%D Plugin:
-
-\loadmarkfile{prop-mis}
-
-\protect \endinput
diff --git a/tex/context/base/prop-run.tex b/tex/context/base/prop-run.tex
deleted file mode 100644
index 4eb853b42..000000000
--- a/tex/context/base/prop-run.tex
+++ /dev/null
@@ -1,39 +0,0 @@
-%D \module
-%D [ file=prop-run,
-%D version=2003.04.20,
-%D title=\CONTEXT\ Property Macros,
-%D subtitle=Runtime Macros,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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
-
-\doglobal\newif\ifshowcomponents
-
-\gdef\showlayoutcomponents
- {\showcomponentstrue}
-
-% By postponing loading of the next two macro's till their usage, we
-% don't put a burden on the system when they are not used.
-
-\gdef\startlayoutcomponent#1#2%
- {\ifshowcomponents
- \doifelseproperty{#1}
- \donothing
- {\doifelsenothing{#2}%
- {\defineproperty[#1][\s!layer]}% [\c!title=#1]
- {\defineproperty[#1][\s!layer][\c!title=#2]}}%
- \startproperty[#1]%
- \fi}
-
-\gdef\stoplayoutcomponent
- {\ifshowcomponents
- \stopproperty
- \fi}
-
-\protect \endinput
diff --git a/tex/context/base/regi-ini.lua b/tex/context/base/regi-ini.lua
index 72e93e67d..04b93db35 100644
--- a/tex/context/base/regi-ini.lua
+++ b/tex/context/base/regi-ini.lua
@@ -6,59 +6,60 @@ if not modules then modules = { } end modules ['regi-ini'] = {
license = "see context related readme files"
}
+local utf = unicode.utf8
+local char, utfchar = string.char, utf.char
+local texsprint = tex.sprint
+
+local ctxcatcodes = tex.ctxcatcodes
+
--[[ldx--
<p>Regimes take care of converting the input characters into
<l n='utf'/> sequences. The conversion tables are loaded at
runtime.</p>
--ldx]]--
-regimes = regimes or { }
-regimes.data = regimes.data or { }
-regimes.utf = regimes.utf or { }
-regimes.context = regimes.context or { }
+regimes = regimes or { }
+regimes.data = regimes.data or { }
+regimes.utf = regimes.utf or { }
+regimes.synonyms = regimes.synonyms or { }
-local char, utfchar = string.char, unicode.utf8.char
+storage.register("regimes/synonyms", regimes.synonyms, "regimes.synonyms")
-- setmetatable(regimes.data,_empty_table_)
-regimes.currentregime = ""
+regimes.currentregime = "utf"
--[[ldx--
<p>We will hook regime handling code into the input methods.</p>
--ldx]]--
-input = input or { }
-input.filters = input.filters or { }
-
function regimes.number(n)
if type(n) == "string" then return tonumber(n,16) else return n end
end
-function regimes.define(c) -- is this used at all?
- local r, u, s = c.regime, c.unicodeslot, c.slot
- regimes.data[r] = regimes.data[r] or { }
- if s then
- if u then
- regimes.data[r][regimes.number(s)] = regimes.number(u)
- else
- regimes.data[r][regimes.number(s)] = 0
- end
- else
- logs.report("regime","unknown vector %s/%s",r,s) -- ctx.statusmessage
- end
+function regimes.setsynonym(synonym,target)
+ regimes.synonyms[synonym] = target
+end
+
+function regimes.truename(regime)
+ texsprint(ctxcatcodes,(regime and regimes.synonyms[synonym] or regime) or regimes.currentregime)
end
function regimes.load(regime)
- environment.loadluafile("regi-"..regime, 1.001)
- if regimes.data[regime] then
- regimes.utf[regime] = { }
- for k,v in pairs(regimes.data[regime]) do
- regimes.utf[regime][char(k)] = utfchar(v)
+ regime = regimes.synonyms[regime] or regime
+ if not regimes.data[regime] then
+ environment.loadluafile("regi-"..regime, 1.001)
+ if regimes.data[regime] then
+ regimes.utf[regime] = { }
+ for k,v in pairs(regimes.data[regime]) do
+ regimes.utf[regime][char(k)] = utfchar(v)
+ end
end
end
end
function regimes.translate(line,regime)
+ regime = regimes.synonyms[regime] or regime
if regime and line then
local rur = regimes.utf[regime]
if rur then
@@ -69,44 +70,19 @@ function regimes.translate(line,regime)
end
function regimes.enable(regime)
+ regime = regimes.synonyms[regime] or regime
if regimes.data[regime] then
regimes.currentregime = regime
local translate = regimes.translate
- input.filters.dynamic_translator = function(s)
+ resolvers.install_text_filter('input',function(s)
return translate(s,regime)
- end
+ end)
else
regimes.disable()
end
end
function regimes.disable()
- regimes.currentregime = ""
- input.filters.dynamic_translator = nil
-end
-
-function input.filters.frozen_translator(regime)
- return function(s)
- return regimes.translate(s,regime)
- end
-end
-
---[[ldx--
-<p>The following code is rather <l n='context'/> specific.</p>
---ldx]]--
-
-function regimes.context.show(regime)
- local flush, tc = tex.sprint, tex.ctxcatcodes
- local r = regimes.data[regime]
- if r then
- flush(tc, "\\starttabulate[|rT|T|rT|lT|lT|lT|]")
- for k, v in ipairs(r) do
- flush(tc, string.format("\\NC %s\\NC\\getvalue{%s}\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR", k,
- characters.contextname(v), characters.hexindex(v), characters.contextname(v),
- characters.category(v), characters.description(v)))
- end
- flush(tc, "\\stoptabulate")
- else
- flush(tc, "unknown regime " .. regime)
- end
+ regimes.currentregime = "utf"
+ resolvers.install_text_filter('input',nil)
end
diff --git a/tex/context/base/regi-ini.mkii b/tex/context/base/regi-ini.mkii
index 538db3bcf..9ba567145 100644
--- a/tex/context/base/regi-ini.mkii
+++ b/tex/context/base/regi-ini.mkii
@@ -13,51 +13,25 @@
\unprotect
-%D Plugs into the common interface.
-
-\beginOLDTEX
-
- \def\mkloadregime#1%
- {\makeshortfilename[\truefilename{\f!regimeprefix#1}]%
- \startreadingfile
- \readsysfile\shortfilename
- {\showmessage\m!regimes2{#1}}
- {\showmessage\m!regimes3{#1}}%
- \stopreadingfile}
-
- \def\mkenableregime#1%
- {\the\executeifdefined{\@reg@#1}\emptytoks}
-
- \def\mkwalkregime#1%
- {\the\executeifdefined{\@reg@\currentregime}\emptytoks}
-
- \def\mkautosetregime#1#2%
- {\ifnum#2>127
- \expanded{\defineactivetoken #2 \@EA\noexpand\csname#1\endcsname}%
- \fi}
+%D Remark: regimes accumulate, so there is no explicit reset in
+%D mkii mode.
-\endOLDTEX
+%D Variables.
-\beginXETEX
+\def\@reg@{@r@eg@} % regime prefix
- \let\mkloadregime \gobbleoneargument
- \let\mkenableregime \gobbleoneargument
- \let\mkwalkregime \gobbleoneargument
- \let\mkautosetregime\gobbletwoarguments
+%D \macros
+%D {currentregime}
- % \def\mkenableregime#1%
- % {\XeTeXinputencoding "#1"\relax}
+\let\currentregime\empty
+\let\defaultregime\s!default
- \def\mkenableregime#1%
- {\doifelse{#1}{utf}%
- {\writestatus\m!regimes{mapping utf to utf-8}%
- \XeTeXinputencoding{utf-8}}
- {\XeTeXinputencoding{#1}}}
+%D Some low level inheritance stuff (mkii).
-\endXETEX
-
-%D Remark: regimes accumulate, so there is no explicit reset in
-%D mkii mode.
+\def\doautosetregime#1#2%
+ {\ifnum#2>127
+ \expanded{\defineactivetoken #2 \@EA\noexpand\csname#1\endcsname}%
+ \fi}
%D \macros
%D {startregime}
@@ -153,27 +127,104 @@
{\setregimetoks
\regimetoks\expandafter{\the\regimetoks\defineactivecharacter#1 {#2}}}
-% D This is kind of obsolete (replaced by previous code).
-%
-% \def\definetoken #1 % #1 = rawtoken or number
-% {\doifnumberelse{\string#1}
-% {\expanded{\dodefinetoken{\rawcharacter{#1}}}}
-% {\expanded{\dodefinetoken{\string#1}}}}
-%
-% \def\dodefinetoken#1#2%
-% {\defineactivecharacter#1 {\dohandletoken{#1}} %
-% \setvalue{\@reg@:t:\currentregime#1}{#2}}
-%
-% \def\dohandletoken#1%
-% {\csname\ifcsname \@reg@:t:\currentregime#1\endcsname % regi-def sets the defaults
-% \@reg@:t:\currentregime\else\defaultregime\fi#1\endcsname}
-
-%D Preloading:
-
-\beginOLDTEX
+%D \macros
+%D {defineregimesynonym,trueregimename}
+
+\def\defineregimesynonym
+ {\dodoubleargument\dodefineregimesynonym}
+
+\def\dodefineregimesynonym[#1][#2]%
+ {\setevalue{\@reg@:s:#1}{#2}}
+
+\def\trueregimename#1%
+ {\executeifdefined{\@reg@:s:#1}{#1}}
+
+%D \macros
+%D {useregime}
+
+\def\useregime[#1]%
+ {\processcommalist[#1]\douseregime}
+
+\def\douseregime#1%
+ {\doifundefined{\c!file\f!regimeprefix#1}%
+ {\letgvalue{\c!file\f!regimeprefix#1}\empty
+ \makeshortfilename[\truefilename{\f!regimeprefix#1}]%
+ \startreadingfile
+ \readsysfile\shortfilename
+ {\showmessage\m!regimes2{#1}}
+ {\showmessage\m!regimes3{#1}}%
+ \stopreadingfile}}
+
+%D \macros
+%D {enableregime,disableregime}
+
+\let\enabledregime\empty
+
+\def\enableregime[#1]%
+ {\edef\currentregime{\trueregimename{#1}}%
+ \doifelsenothing\currentregime
+ {\disableregime}
+ {\douseregime\currentregime
+ \the\executeifdefined{\@reg@\currentregime}\emptytoks}}
+
+\def\disableregime
+ {\let\currentregime\empty}
+
+%D \macros
+%D {protectregime, settoletterunlessactive, settocodeunlessactive}
+%D
+%D The next boolean is used later on to prevent unwanted
+%D catcode changes. Use it with care.
+
+\newif\ifprotectregime \protectregimetrue
+
+\def\settoletterunlessactive#1%
+ {\ifprotectregime\ifnum\catcode#1=\active\else
+ \catcode#1\@@letter
+ \fi\else
+ \catcode#1\@@letter
+ \fi}
+
+\def\settootherunlessactive#1%
+ {\ifprotectregime\ifnum\catcode#1=\active\else
+ \catcode#1=\@@other
+ \fi\else
+ \catcode#1=\@@other
+ \fi}
+
+\def\settocodeunlessactive#1#2%
+ {\ifprotectregime\ifnum\catcode#1=\active\else
+ \catcode#1=#2\relax
+ \fi\else
+ \catcode#1=#2\relax
+ \fi}
+
+%D Sort related:
+
+\def\dowalkregime#1%
+ {\the\executeifdefined{\@reg@#1}\emptytoks}
+
+%D Simplify matters for \XETEX.
+
+\ifnum\texengine=\xetexengine
+
+ \def\enableregime[#1]%
+ {\doifelse{#1}{utf}%
+ {\writestatus\m!regimes{mapping utf to utf-8}%
+ \XeTeXinputencoding{utf-8}}
+ {\XeTeXinputencoding{#1}}}
+
+ \def\disableregime
+ {\XeTeXinputencoding{utf-8}}
+
+ \def\loadregime[#1]{}
+ \let\walkregime \gobbleoneargument
+ \let\doautosetregime \gobbletwoarguments
+
+\else
\useregime[def,uni,utf] % we load the rest runtime
-\endOLDTEX
+\fi
\protect \endinput
diff --git a/tex/context/base/regi-ini.mkiv b/tex/context/base/regi-ini.mkiv
index 763903fa1..5a3be77a2 100644
--- a/tex/context/base/regi-ini.mkiv
+++ b/tex/context/base/regi-ini.mkiv
@@ -1,7 +1,7 @@
%D \module
-%D [ file=char-reg,
+%D [ file=regi-ini,
%D version=2005.04.25,
-%D title=\CONTEXT\ Lua Macros,
+%D title=\CONTEXT\ Regime Macros,
%D subtitle=Regime Support,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -17,25 +17,39 @@
\registerctxluafile{regi-ini}{1.001}
-\def\mkloadregime #1{\ctxlua{regimes.load("#1")}}
-\def\mkenableregime #1{\ctxlua{regimes.enable("#1")}}
-\def\mkdisableregime {\ctxlua{regimes.disable()}}
-\def\mkshowregime #1{\ctxlua{regimes.context.show("#1")}}
+%D \macros
+%D {currentregime}
-% hm, this kind of disables regimes .. too tricky
-%
-% \appendtoks
-% \pushmacro\currentregime
-% \disableregime
-% \to \everystartreadingfile
+\def\currentregime{utf}
-% \appendtoks
-% \popmacro\currentregime
-% \enableregime[\currentregime]%
-% \to \everystopreadingfile
+%D \macros
+%D {defineregimesynonym,trueregimename}
-\protect \endinput
+\def\defineregimesynonym
+ {\dodoubleargument\dodefineregimesynonym}
+
+\def\dodefineregimesynonym[#1][#2]%
+ {\ctxlua{regimes.setsynonym("#1","#2")}}
+
+\def\trueregimename#1%
+ {\ctxlua{regimes.truename("#1")}}
+
+%D \macros
+%D {useregime}
+
+\def\useregime[#1]%
+ {\processcommalist[#1]\douseregime}
-% \starttext
-% \showregimetable{cp1250}
-% \stoptext
+\def\douseregime#1%
+ {\ctxlua{regimes.load("#1")}}
+
+%D \macros
+%D {enableregime,disableregime}
+
+\def\enableregime[#1]%
+ {\edef\currentregime{\ctxlua{regimes.load("#1") regimes.enable("#1") regimes.truename()}}}
+
+\def\disableregime
+ {\edef\currentregime{\ctxlua{regimes.disable()}}}
+
+\protect \endinput
diff --git a/tex/context/base/regi-ini.tex b/tex/context/base/regi-ini.tex
deleted file mode 100644
index 42bbf9718..000000000
--- a/tex/context/base/regi-ini.tex
+++ /dev/null
@@ -1,182 +0,0 @@
-%D \module
-%D [ file=regi-ini,
-%D version=2000.12.27, % 1998.12.03,
-%D title=\CONTEXT\ Regime Macros,
-%D subtitle=Initialization,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Messages (to be translated).
-
-\startmessages dutch library: regimes
- title: regime
- 1: regime --
- 2: regime -- wordt geladen
- 3: onbekend regime --
-\stopmessages
-
-\startmessages english library: regimes
- title: regime
- 1: regime --
- 2: regime -- is loaded
- 3: unknown regime --
-\stopmessages
-
-\startmessages german library: regimes
- title: Kodierung
- 1: Kodierung --
- 2: Kodierung -- ist geladen
- 3: Unbekannte Kodierung --
-\stopmessages
-
-\startmessages czech library: regimes
- title: kodovani
- 1: kodovani --
- 2: je nacteno kodovani --
- 3: nezname kodovani --
-\stopmessages
-
-\startmessages italian library: regimes
- title: codifica
- 1: codifica --
- 2: codifica -- caricata
- 3: codifica sconosciuta --
-\stopmessages
-
-\startmessages norwegian library: regimes
- title: koding
- 1: koding --
- 2: koding -- er lest inn
- 3: ukjent koding --
-\stopmessages
-
-\startmessages romanian library: regimes
- title: codificari
- 1: codificarea --
- 2: codificarea -- este Encarcata
- 3: codificarea -- este necunoscuta
-\stopmessages
-
-\startmessages french library: regimes
- title: encodage
- 1: encodage --
- 2: l'encodage -- est chargé
- 3: encodage -- inconnu
-\stopmessages
-
-%D Variables.
-
-\def\@reg@{@r@eg@} % regime prefix
-
-%D \macros
-%D {currentregime}
-
-\let\currentregime\empty
-\let\defaultregime\s!default
-
-%D Plugin interface.
-
-\let\mkloadregime \gobbleoneargument
-\let\mkenableregime \gobbleoneargument
-\let\mkdisableregime\relax
-\let\mkshowregime \gobbleoneargument
-\let\mkwalkregime \gobbleoneargument
-\let\mkautosetregime\gobbletwoarguments
-
-%D Some low level inheritance stuff (mkii).
-
-\def\doautosetregime{\mkautosetregime}
-
-%D \macros
-%D {defineregimesynonym,trueregimename}
-
-\def\defineregimesynonym
- {\dodoubleargument\dodefineregimesynonym}
-
-\def\dodefineregimesynonym[#1][#2]%
- {\setevalue{\@reg@:s:#1}{#2}}
-
-\def\trueregimename#1%
- {\executeifdefined{\@reg@:s:#1}{#1}}
-
-%D \macros
-%D {useregime}
-
-\def\useregime[#1]%
- {\processcommalist[#1]\douseregime}
-
-\def\douseregime#1%
- {\doifundefined{\c!file\f!regimeprefix#1}%
- {\letgvalue{\c!file\f!regimeprefix#1}\empty
- \mkloadregime{#1}}}
-
-%D \macros
-%D {enableregime,disableregime}
-
-\let\enabledregime\empty
-
-\def\enableregime[#1]%
- {\edef\currentregime{\trueregimename{#1}}%
- \doifelsenothing\currentregime
- {\disableregime}
- {\douseregime\currentregime
- \mkenableregime\currentregime}}
-
-\def\disableregime
- {\let\currentregime\empty
- \mkdisableregime}
-
-%D \macros
-%D {protectregime, settoletterunlessactive, settocodeunlessactive}
-%D
-%D The next boolean is used later on to prevent unwanted
-%D catcode changes. Use it with care.
-
-\newif\ifprotectregime \protectregimetrue
-
-\def\settoletterunlessactive#1%
- {\ifprotectregime\ifnum\catcode#1=\active\else
- \catcode#1\@@letter
- \fi\else
- \catcode#1\@@letter
- \fi}
-
-\def\settootherunlessactive#1%
- {\ifprotectregime\ifnum\catcode#1=\active\else
- \catcode#1=\@@other
- \fi\else
- \catcode#1=\@@other
- \fi}
-
-\def\settocodeunlessactive#1#2%
- {\ifprotectregime\ifnum\catcode#1=\active\else
- \catcode#1=#2\relax
- \fi\else
- \catcode#1=#2\relax
- \fi}
-
-%D Sort related:
-
-\def\dowalkregime{\mkwalkregime} % #1
-
-%D \macros
-%D {showregime}
-
-\def\showregime
- {\dosingleempty\doshowregime}
-
-\def\doshowregime[#1]%
- {\mkshowregime{#1}}
-
-%D Plugins.
-
-\loadmarkfile{regi-ini}
-
-\protect \endinput
diff --git a/tex/context/base/regi-syn.tex b/tex/context/base/regi-syn.tex
index b29c06775..7a8a9c146 100644
--- a/tex/context/base/regi-syn.tex
+++ b/tex/context/base/regi-syn.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Regime Macros (synonyms)}
+\writestatus{loading}{ConTeXt Regime Macros / Synonyms}
\unprotect
diff --git a/tex/context/base/regi-utf.tex b/tex/context/base/regi-utf.tex
index 2662c0017..5b30e85ee 100644
--- a/tex/context/base/regi-utf.tex
+++ b/tex/context/base/regi-utf.tex
@@ -11,6 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\ifnum\texengine>\pdftexengine
+ \endinput
+\fi
+
%D This regime activates the characters $>192$ and let them
%D handle \UTF\ encoded content streams. This regime runs on
%D top of the \type {unic} modules. We use an active inspector
@@ -29,14 +33,6 @@
% Ýýÿ
% ß
-\beginXETEX
- \expandafter \endinput
-\endXETEX
-
-\beginLUATEX
- \expandafter \endinput
-\endLUATEX
-
\unprotect
\startregime[utf]
diff --git a/tex/context/base/s-fnt-01.tex b/tex/context/base/s-fnt-01.tex
index a0ff16a22..69c8efab9 100644
--- a/tex/context/base/s-fnt-01.tex
+++ b/tex/context/base/s-fnt-01.tex
@@ -1,5 +1,5 @@
%D \module
-%D [ file=s-tnf-01,
+%D [ file=s-fnt-01,
%D version=2001.08.22,
%D title=\CONTEXT\ Style File,
%D subtitle=Font Environment 1,
@@ -12,7 +12,7 @@
%C details.
%D This file is used by the \type {texfont.pl} installation
-%D script.
+%D script. It is of no use for \MKIV.
%D Modes: compact
diff --git a/tex/context/base/s-fnt-10.tex b/tex/context/base/s-fnt-10.tex
index 86fffd7b6..95e9282b8 100644
--- a/tex/context/base/s-fnt-10.tex
+++ b/tex/context/base/s-fnt-10.tex
@@ -1,6 +1,102 @@
-% engine=luatex
+%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 / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
-\ctxloadluafile{s-fnt-10}{}
+\startluacode
+local format, sprint = string.format, tex.sprint
+
+function fonts.otf.show_all()
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata and tfmdata.shared then
+ local otfdata = tfmdata.shared.otfdata
+ if otfdata and otfdata.luatex then
+ local unicodes = otfdata.luatex.unicodes
+ sprint(tex.ctxcatcodes,format("\\starttabulate[|l|r|c|]"))
+ for i, name in ipairs(table.sortedkeys(unicodes)) do
+ local unicode = unicodes[name]
+ if unicode >= 0 then
+ sprint(tex.ctxcatcodes,format("\\NC %s \\NC %s \\NC \\char%s \\NC\\NR",name,unicode,unicode))
+ end
+ end
+ sprint(tex.ctxcatcodes,format("\\stoptabulate"))
+ end
+ end
+end
+
+function fonts.show_all()
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata then
+ local chars = tfmdata.characters
+ local descs = tfmdata.descriptions or { }
+ local data = characters.data
+ sprint(tex.ctxcatcodes,format("\\setuptabulate[header=repeat]"))
+ sprint(tex.ctxcatcodes,format("\\starttabulatehead"))
+ sprint(tex.ctxcatcodes,"\\NC\\bf unicode\\NC\\bf visual\\NC\\bf index\\NC\\bf glyph\\NC\\bf adobe\\NC\\bf context\\NC\\NR")
+ sprint(tex.ctxcatcodes,"\\HL")
+ sprint(tex.ctxcatcodes,format("\\stoptabulatehead"))
+ sprint(tex.ctxcatcodes,format("\\starttabulate[|l|c|l|p|p|p|]"))
+ for k, unicode in ipairs(table.sortedkeys(chars)) do
+ if unicode >= 0 then
+ local chr, des, dat = chars[unicode], descs[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
+ sprint(tex.ctxcatcodes,format("\\NC\\tttf U+%05X\\NC\\char%s\\NC\\tttf %05X\\NC\\tttf %s\\NC\\tttf %s\\NC\\tttf %s\\NC\\NR",unicode,unicode,index,gname,aname,cname))
+ end
+ end
+ sprint(tex.ctxcatcodes,format("\\stoptabulate"))
+ else
+ sprint(tex.ctxcatcodes,"problems")
+ end
+end
+
+function fonts.show_glyphs()
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata then
+ local chars = tfmdata.characters
+ for k, v in ipairs(table.sortedkeys(chars)) do
+ if v >=0 then
+ sprint(tex.ctxcatcodes,format("\\dontleavehmode{\\strut\\char%s}\\endgraf",v))
+ end
+ end
+ end
+end
+\stopluacode
\def\ShowCompleteFont#1#2#3%
{\bgroup
diff --git a/tex/context/base/s-fnt-11.tex b/tex/context/base/s-fnt-11.tex
new file mode 100644
index 000000000..8f855cc72
--- /dev/null
+++ b/tex/context/base/s-fnt-11.tex
@@ -0,0 +1,61 @@
+%D \module
+%D [ file=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 / Hans Hagen \& Ton Otten}]
+%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[officinasans.*][all]
+%D \showinstalledfonts[officinaserif.*][all]
+%D \showinstalledfonts[officina.*itc.*][all]
+%D
+%D \showinstalledfonts[officina.*itc.*][all,new]
+%D \stoptyping
+
+\startluacode
+function fonts.names.table(pattern,reload,all)
+ local t = fonts.names.list(pattern,reload)
+ if t then
+ tex.sprint(tex.ctxcatcodes,"\\start\\nonknuthmode\\starttabulate[|T|T|T|T|T|]")
+ tex.sprint(tex.ctxcatcodes,"\\NC hashname\\NC type\\NC fontname\\NC filename\\NC\\NR\\HL")
+ for v,tv in table.sortedpairs(t) do
+ local kind, name, file = tv[1], tv[2], tv[3]
+ if all or v == string.lower(name) then
+ if kind and name and file then
+ tex.sprint(tex.ctxcatcodes,string.format("\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR",v,kind,name,file))
+ else
+ logs.report("font table", "skipping %s", v)
+ end
+ end
+ end
+ tex.sprint(tex.ctxcatcodes,"\\stoptabulate\\stop")
+ end
+end
+\stopluacode
+
+\unprotect
+
+\def\showinstalledfonts
+ {\dodoubleempty\doshowinstalledfonts}
+
+\def\doshowinstalledfonts[#1][#2]%
+ {\bgroup
+ \def\pattern{#1}%
+ \def\all{false}%
+ \def\reload{false}%
+ \doifnothing\pattern{\def\pattern{.*}}%
+ \processallactionsinset[#2][\v!new=>\def\reload{true},\v!all=>\def\all{true}]%
+ \ctxlua{fonts.names.table("#1",\reload,\all)}%
+ \egroup}
+
+\protect \endinput
diff --git a/tex/context/base/s-fnt-20.tex b/tex/context/base/s-fnt-20.tex
new file mode 100644
index 000000000..a57c0ba47
--- /dev/null
+++ b/tex/context/base/s-fnt-20.tex
@@ -0,0 +1,140 @@
+%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 / Hans Hagen \& Ton Otten}]
+%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\checkedfeature#1#2{\ifnum\featureattribute{#1}=\zerocount#2\else#1\fi}
+
+% 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,ccmp=no,
+ 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
+ % ss11=yes, % full 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,ss25=yes,ss26=yes, % BX, LH_im, 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
+ % js06=yes,js08=yes,js10=yes,js11=yes,js17=yes,
+ % ttwl=yes,
+ 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,curs=yes]
+
+\setvalue{otftracker-direction-arabtype}{-1}
+\setvalue{otftracker-direction-husayni}{-1}
+\setvalue{otftracker-direction-simplenaskhi}{-1}
+
+\setvariables
+ [otftracker]
+ [font=Serif,
+ features=\checkedfeature{otftracker-\getvariable{otftracker}{font}}{otftracker-default},
+ size=48pt,
+ figure=,
+ title=Feature Check,
+ sample=no sample,
+ direction=\executeifdefined{otftracker-direction-\getvariable{otftracker}{font}}{0},
+ 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
+ \chapter{\getvariable{otftracker}{title}}
+ \doifsomething {\getvariable{otftracker}{figure}} {
+ \startlinecorrection
+ \externalfigure[\getvariable{otftracker}{figure}]
+ \stoplinecorrection
+ }
+ \showotfcomposition
+ {\getvariable{otftracker}{font}*\getvariable{otftracker}{features} at \getvariable{otftracker}{size}}
+ {\getvariable{otftracker}{direction}}
+ {\getvariable{otftracker}{sample}}
+ \stoptext
+\stopsetups
diff --git a/tex/context/base/s-fnt-21.tex b/tex/context/base/s-fnt-21.tex
new file mode 100644
index 000000000..dd8de398d
--- /dev/null
+++ b/tex/context/base/s-fnt-21.tex
@@ -0,0 +1,46 @@
+%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 / Hans Hagen \& Ton Otten}]
+%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
+
+\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}}
diff --git a/tex/context/base/s-fnt-23.tex b/tex/context/base/s-fnt-23.tex
new file mode 100644
index 000000000..096c8fbf5
--- /dev/null
+++ b/tex/context/base/s-fnt-23.tex
@@ -0,0 +1,272 @@
+%D \module
+%D [ file=s-fnt-23,
+%D version=2009.03.04,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Tracing Feature Application (3),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startluacode
+ local last_data = nil
+ local format = string.format
+ local function tpf(...)
+-- print("!!!!",...)
+ tex.print(tex.ctxcatcodes,format(...))
+ end
+ function fonts.otf.show_shape(n)
+ local tfmdata = fonts.ids[font.current()]
+ lastdata = tfmdata
+ local charnum = tonumber(n)
+ if not charnum then
+ charnum = tfmdata.unicodes[n]
+ end
+ local c = tfmdata.characters[charnum]
+ local d = tfmdata.descriptions[charnum]
+ if d then
+ local factor = (tfmdata.size/tfmdata.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
+ tpf("\\startMPcode")
+ tpf("pickup pencircle scaled .25bp ; ")
+ tpf('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum)
+ tpf('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury)
+ tpf('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0)
+ tpf('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
+ tpf("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] = format("((%s,%s) shifted (%s,%s))",xsign*k*factor,ysign*h*factor,dx,dy)
+ end
+ end
+ tpf("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled .25) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1])
+ tpf("draw laddered (%s) withcolor .5white ;",table.concat(l,".."))
+ tpf("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled .25) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l])
+ for k, v in ipairs(l) do
+ tpf("draw %s withcolor blue withpen pencircle scaled 1bp;",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] = format("((%s,%s) shifted (%s,%s))",xsign*k*factor,ysign*h*factor,dx,dy)
+ end
+ end
+ if loc == "top" then
+ tpf('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[#l])
+ else
+ tpf('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
+ tpf('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
+ tpf("draw (%s,%s) withcolor blue withpen pencircle scaled 1bp;",xx,yy)
+ tpf('label.top("\\type{%s}",(%s,%s-2bp)) ;',txt,xx,yy)
+ tpf('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
+ tpf('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury)
+ tpf('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury)
+ tpf('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,ury)
+ tpf('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury)
+ tpf('label.rt("%s",(%s-2bp,%s-1bp));',d.italic,width+italic,ury)
+ end
+ if top_accent ~= 0 then
+ tpf('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,ury)
+ tpf('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,ury)
+ tpf('label.top("%s",(%s,%s-1bp));',d.top_accent,top_accent,ury)
+ end
+ if bot_accent ~= 0 then
+ tpf('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,lly)
+ tpf('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,ury)
+ tpf('label.bot("%s",(%s,%s+1bp));',d.bot_accent,bot_accent,lly)
+ end
+ tpf('draw origin withcolor red withpen pencircle scaled 1bp;')
+ tpf("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
+ tpf("currentpicture := currentpicture scaled 8 ;")
+ tpf("\\stopMPcode")
+ elseif c then
+ local factor = (7200/7227)/65536
+ tpf("\\startMPcode")
+ tpf("pickup pencircle scaled .25bp ; ")
+ tpf('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum)
+ tpf('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
+ tpf("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
+ tpf('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury)
+ tpf('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury)
+ tpf('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,height)
+ tpf('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,height)
+ tpf('label.rt("%6.3f bp",(%s-2bp,%s-1bp));',italic,width+italic,height)
+ end
+ if top_accent ~= 0 then
+ tpf('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,height)
+ tpf('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,height)
+ tpf('label.top("%6.3f bp",(%s,%s-1bp));',top_accent,top_accent,height)
+ end
+ if bot_accent ~= 0 then
+ tpf('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,height)
+ tpf('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,height)
+ tpf('label.bot("%6.3f bp",(%s,%s+1bp));',bot_accent,bot_accent,height)
+ end
+ tpf('draw origin withcolor red withpen pencircle scaled 1bp;')
+ tpf("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
+ tpf("currentpicture := currentpicture scaled 8 ;")
+ tpf("\\stopMPcode")
+ else
+ tpf("no such shape: %s",n)
+ end
+ end
+ function fonts.otf.show_all_shapes(start,stop)
+ local tfmdata = fonts.ids[font.current()]
+ lastdata = tfmdata
+ start, stop = start or "\\startTEXpage\\gobbleoneargument", stop or "\\stopTEXpage"
+ local unicodes, indices, descriptions = tfmdata.unicodes, tfmdata.indices, tfmdata.descriptions
+ for _, unicode in next, table.sortedkeys(descriptions) do
+ local d = descriptions[unicode]
+ local name = d.name
+ tpf("%s{%s}%%",start,unicode)
+ tpf("\\writestatus{glyph}{U+%04X -> %s}%%",unicode,name)
+ fonts.otf.show_shape(unicode)
+ tpf(stop)
+ end
+ end
+ function fonts.otf.show_shape_field(unicode,name)
+ local tfmdata = lastdata or fonts.ids[font.current()]
+ local d = tfmdata.descriptions[unicode]
+ if d then
+ if name == "unicode" then
+ tpf("U+%04X",unicode)
+ else
+ d = d[name]
+ if d then
+ tpf(d)
+ end
+ end
+ end
+ end
+\stopluacode
+
+\setupcolors
+ [state=start]
+
+\def\GetGlyphField#1#2%
+ {\ctxlua{fonts.otf.show_shape_field(#1,"#2")}}
+
+\def\StartShowGlyphShape#1%
+ {\startTEXpage
+ \nonknuthmode
+ \def\GlyphUnicode{#1}}
+
+\def\StopShowGlyphShape
+ {\par
+ \midaligned{\tttf\setstrut\strut\GetGlyphField\GlyphUnicode{unicode}: \GetGlyphField\GlyphUnicode{name}}%
+ \stopTEXpage}
+
+\def\ShowGlyphShape#1#2#3% name size glyph
+ {\begingroup
+ \definedfont[#1 at #2]%
+ \obeyMPboxdepth
+ \ctxlua{fonts.otf.show_shape("#3")}%
+ \endgroup}
+
+\def\ShowAllGlyphShapes#1#2% name size
+ {\begingroup
+ \nonknuthmode
+ \definedfont[#1 at #2]%
+ \ctxlua{fonts.otf.show_all_shapes("\\StartShowGlyphShape","\\StopShowGlyphShape")}%
+ \endgroup}
+
+\setupcolors
+ [state=start]
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\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
+
+\ShowAllGlyphShapes{simplenaskhi}{100bp}
+
+\stoptext
diff --git a/tex/context/base/s-fnt-24.tex b/tex/context/base/s-fnt-24.tex
new file mode 100644
index 000000000..073588033
--- /dev/null
+++ b/tex/context/base/s-fnt-24.tex
@@ -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 / Hans Hagen \& Ton Otten}]
+%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
+ tex.sprint(tex.ctxcatcodes,string.format("\\ShowChineseCombiChar{%s}{%s}{%s}{%s}",v,vv,k,kk))
+ end
+ end
+ end
+ end
+end
+\stopluacode
+
+\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}
+
+\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/base/s-fnt-25.tex b/tex/context/base/s-fnt-25.tex
new file mode 100644
index 000000000..83a3ee586
--- /dev/null
+++ b/tex/context/base/s-fnt-25.tex
@@ -0,0 +1,162 @@
+%D \module
+%D [ file=s-fnt-25,
+%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 / Hans Hagen \& Ton Otten}]
+%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\showmathfontcharacters
+ {\dodoubleempty\doshowmathfontcharacters}
+
+\def\doshowmathfontcharacters[#1][#2]%
+ {\begingroup
+ \doifelsenothing{#1}
+ {\definedfont[MathRoman*math-text]}
+ {\definedfont[#1]}%
+ \doifelsenothing{#2}
+ {\ctxlua{document.showmathfont(font.current())}}
+ {\def\dodoshowmathfontcharacters##1{\ctxlua{document.showmathfont(font.current(),##1)}}%
+ \processcommalist[#2]\dodoshowmathfontcharacters}%
+ \endgroup}
+
+\def\startmathfontlist
+ {\startpacked}
+
+\def\stopmathfontlist
+ {\stoppacked}
+
+\def\startmathfontlistentry
+ {\blank
+ \begingroup}
+
+\def\stopmathfontlistentry
+ {\endgroup
+ \blank}
+
+\def\mathfontlistentryhexdectit#1#2#3%
+ {#1: \ruledhbox{\char#2}\enspace#3\par
+ \advance\leftskip 1em\relax}
+
+\def\mathfontlistentrywdhtdpic#1#2#3#4%
+ {width: #1, height: #2, depth: #3, italic: #4\par}
+
+\def\mathfontlistentrynext#1#2%
+ {#1~\ruledhbox{\char#2}}
+
+\def\mathfontlistentrynextlist#1%
+ {next: #1\par}
+
+\def\fontlistentryvariants#1#2%
+ {#1~\ruledhbox{\char#2}}
+
+\def\mathfontlistentryvariantslist#1%
+ {variants: #1\par}
+
+\def\mathfontlistentrynextvariantslist#1#2%
+ {next: #1 => variants: #2\par}
+
+\def\mathfontlistentryclassname#1#2%
+ {mathclass: #1, mathname: #2\par}
+
+\def\mathfontlistentrysymbol#1#2%
+ {mathsymbol: #1~\ruledhbox{\char#2}\par}
+
+\startluacode
+function document.showmathfont(id,slot)
+ local data = characters.data
+ local tfmdata = fonts.ids[id]
+ local characters = tfmdata.characters
+ local sorted = (slot and { slot }) or table.sortedkeys(characters)
+ local function report(...)
+ tex.sprint(tex.ctxcatcodes,string.format(...))
+ end
+ for _, s in next, sorted do
+ local char = characters[s]
+ if char then
+ local info = data[s]
+ local cnext, cvert_variants, choriz_variants = char.next, char.vert_variants, char.horiz_variants
+ report("\\startmathfontlistentry")
+ report("\\mathfontlistentryhexdectit{U+%05X}{%s}{%s}",s,s,string.lower(info.description or "no description, private to font"))
+ report("\\mathfontlistentrywdhtdpic{%s}{%s}{%s}{%s}",char.width or 0,char.height or 0,char.depth or 0,char.italic or 0)
+ if info.mathclass then
+ report("\\mathfontlistentryclassname{%s}{%s}",info.mathclass,info.mathname or "no name")
+ end
+ if info.mathspec then
+ for i=1,#info.mathspec do
+ report("\\mathfontlistentryclassname{%s}{%s}",info.mathspec[i].class,info.mathspec[i].name or "no name")
+ end
+ end
+ if info.mathsymbol then
+ report("\\mathfontlistentrysymbol{U+%05X}{%s}",info.mathsymbol,info.mathsymbol)
+ end
+ if cnext then
+ local t, done = { }, { }
+ while cnext do
+ if done[cnext] then
+ t[#t+1] = "CYCLE"
+ break
+ else
+ done[cnext] = true
+ t[#t+1] = string.format("\\mathfontlistentrynext{U+%05X}{%s}",cnext,cnext)
+ cnext = characters[cnext]
+ cvert_variants = cnext.vert_variants or cvert_variants
+ choriz_variants = cnext.horiz_variants or choriz_variants
+ if cnext then
+ cnext = cnext.next
+ end
+ end
+ end
+ cnext = t
+ end
+ if cvert_variants then
+ local t = { }
+ for k, v in next, cvert_variants do
+ t[#t+1] = string.format("\\fontlistentryvariants{U+%05X}{%s}",v.glyph,v.glyph)
+ end
+ cvert_variants = t
+ end
+ if choriz_variants then
+ local t = { }
+ for k, v in next, choriz_variants do
+ t[#t+1] = string.format("\\fontlistentryvariants{%s}",v.glyph)
+ end
+ choriz_variants = t
+ end
+ local cvariants = choriz_variants or cvert_variants
+ if cvariants and cnext then
+ report("\\mathfontlistentrynextvariantslist{%s}{%s}",table.concat(cnext," => "),table.concat(cvariants," => "))
+ else
+ if cnext then
+ report("\\mathfontlistentrynextlist{%s}",table.concat(cnext," => "))
+ end
+ if variants then
+ report("\\mathfontlistentryvariantslist{%s}",table.concat(cvariants," "))
+ end
+ end
+ report("\\stopmathfontlistentry")
+ end
+ end
+end
+\stopluacode
+
+\endinput
+
+\startbuffer mathtest
+ \begingroup\mm\mr\showmathfontcharacters\endgroup
+\stopbuffer
+
+\starttext
+ \usetypescript[cambria] \setupbodyfont[cambria, 12pt] \getbuffer[mathtest]
+ \usetypescript[lmvirtual] \setupbodyfont[lmvirtual,12pt] \getbuffer[mathtest]
+ \usetypescript[pxvirtual] \setupbodyfont[pxvirtual,12pt] \getbuffer[mathtest]
+ \usetypescript[txvirtual] \setupbodyfont[txvirtual,12pt] \getbuffer[mathtest]
+ \usetypescript[palatino] \setupbodyfont[palatino, 10pt] \getbuffer[mathtest]
+ \usetypescript[mathtimes] \setupbodyfont[mathtimes,12pt] \getbuffer[mathtest]
+\stoptext
+
diff --git a/tex/context/base/s-fnt-30.tex b/tex/context/base/s-fnt-30.tex
new file mode 100644
index 000000000..81b6c8d19
--- /dev/null
+++ b/tex/context/base/s-fnt-30.tex
@@ -0,0 +1,42 @@
+%D \module
+%D [ file=s-fnt-30,
+%D version=2006.05.10, % abou tthen, quite old already
+%D title=\CONTEXT\ Style File,
+%D subtitle=Showing Character Data,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startluacode
+function document.show_character_data(n)
+ local n = characters.number(n)
+ local d = characters.data[n]
+ if d then
+ local function entry(label,name)
+ texsprint(tex.ctxcatcodes,format("\\NC %s\\NC %s\\NC\\NR",label,characters.valid(d[name])))
+ end
+ texsprint(tex.ctxcatcodes,"\\starttabulate[|Tl|Tl|]")
+ entry("unicode index" , "unicodeslot")
+ entry("context name" , "contextname")
+ entry("adobe name" , "adobename")
+ entry("category" , "category")
+ entry("description" , "description")
+ entry("uppercase code", "uccode")
+ entry("lowercase code", "lccode")
+ entry("specials" , "specials")
+ texsprint(tex.ctxcatcodes,"\\stoptabulate ")
+ end
+end
+\stopluacode
+
+\def\ShowCharacterData#1%
+ {\ctxlua{document.show_character_data(#1)}}
+
+% \ShowCharacterData{123}
+% \ShowCharacterData{0x7B}
+
+% \dostepwiserecurse{`A}{`Z}{1}{\ShowCharacterData{#1}}
diff --git a/tex/context/base/s-pre-60.tex b/tex/context/base/s-pre-60.tex
index bd6b6ae4f..89ddbbba4 100644
--- a/tex/context/base/s-pre-60.tex
+++ b/tex/context/base/s-pre-60.tex
@@ -45,7 +45,7 @@
[set=\setups{set-stepper},
nofsteps=50]
-\defineproperty[step:busy][layer][state=start]
+\defineproperty[step:busy][layer][state=start,global=no]
\definereference [SetupStepper] [JS(SetupStepper{step,\StepMaximum})]
\definereference [ResetStepper] [JS(ResetStepper)]
@@ -62,20 +62,36 @@
\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}
+\startmode[mkiv]
+
+ \def\StartStep
+ {\startproperty[\StepLayer]%
+ \ignorespaces}
+
+ \def\StopStep
+ {\removeunwantedspaces
+ \stopproperty}
+
+\stopmode
+
+\startnotmode[mkiv]
+
+ \def\StartStep
+ {\ifvmode
+ \scratchskip\lastskip
+ \vskip-\scratchskip
+ \startproperty[\StepLayer]%
+ \vskip\scratchskip
+ \else
+ \startproperty[\StepLayer]%
+ \fi
+ \ignorespaces}
+
+ \def\StopStep
+ {\removeunwantedspaces
+ \stopproperty}
+
+\stopnotmode
\def\StartSteps{\iftrialtypesetting\else\ResetStep\NextStep\StartStep\fi}
\def\StopSteps {\iftrialtypesetting\else\StopStep \PrevStep \fi}
diff --git a/tex/context/base/s-pre-61.tex b/tex/context/base/s-pre-61.tex
index c2040a0d9..216bb9a00 100644
--- a/tex/context/base/s-pre-61.tex
+++ b/tex/context/base/s-pre-61.tex
@@ -15,9 +15,13 @@
\usemodule[pre-60]
-\usetypescriptfile[type-ghz]
-
-\definetypeface[mainface][ss][sans][optima-nova][default][encoding=\defaultencoding]
+\doifmodeelse {mkiv} {
+ \usetypescriptfile[type-hgz]
+ \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]
@@ -168,9 +172,7 @@
style=\HeadFont]
\setupheadertexts
- [\doiftextelse{\placeheadtext[Topic]}
- {\placeheadtext[Topic]}
- {\placeheadtext[Nopic]}]
+ [\doiftextelse{\currentheadnumber}{\placeheadtext[Topic]}{\placeheadtext[Nopic]}]
[]
\setuppagenumbering
diff --git a/tex/context/base/s-pre-62.tex b/tex/context/base/s-pre-62.tex
index c3683cbfa..64bb3495b 100644
--- a/tex/context/base/s-pre-62.tex
+++ b/tex/context/base/s-pre-62.tex
@@ -207,4 +207,22 @@
\def\TitlePage {\doTitlePage\TitleFont\relax}
\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont}
-\endinput
+\doifnotmode{demo} {\endinput}
+
+\starttext
+
+\StartTitlePage
+bla\\bla bla\\bla
+\StopTitlePage
+
+\StartRemark {Bla Bla}
+ Bla Bla Bla. \FlushStep
+ Bla Bla Bla. \FlushStep
+\StopRemark
+
+\StartRemark {Bla Bla}
+ Bla Bla Bla. \FlushStep
+ Bla Bla Bla. \FlushStep
+\StopRemark
+
+\stoptext
diff --git a/tex/context/base/s-pre-66.tex b/tex/context/base/s-pre-66.tex
new file mode 100644
index 000000000..916a7de66
--- /dev/null
+++ b/tex/context/base/s-pre-66.tex
@@ -0,0 +1,133 @@
+%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=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.
+
+%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}
diff --git a/tex/context/base/s-pre-71.tex b/tex/context/base/s-pre-71.tex
index 3d92830b9..91075d54d 100644
--- a/tex/context/base/s-pre-71.tex
+++ b/tex/context/base/s-pre-71.tex
@@ -28,11 +28,11 @@
\setuplayout[page]
-\setupbodyfont[15pt]
+% \setupbodyfont[15pt]
\usetypescriptfile[type-hgz]
\usetypescript[palatino-informal]
-\setupbodyfont[palatino-informal]
+\setupbodyfont[palatino-informal,15pt]
\setupsorting[logo][style=]
@@ -57,7 +57,8 @@
\definecolor[TopicColor-0][t=.5,a=1,s=.5]
\definecolor[TopicColor] [s=1]
-\setupcolors[state=start,textcolor=TopicColor]
+\setupcolors[state=start]
+\setupcolors[textcolor=TopicColor]
\startluacode
local locations = {
@@ -182,6 +183,7 @@
\logo [METAPOST] {MetaPost}
\definefont[TitleFont][SansBold at 60pt]
+\definefont[TempFont] [SansBold at 12pt]
\doifnotmode{demo}{\endinput}
diff --git a/tex/context/base/s-reg-01.tex b/tex/context/base/s-reg-01.tex
new file mode 100644
index 000000000..123b97384
--- /dev/null
+++ b/tex/context/base/s-reg-01.tex
@@ -0,0 +1,50 @@
+%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]
+%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
+ tex.sprint(tc,"\\starttabulate[|rT|T|rT|lT|lT|lT|]")
+ for k, v in ipairs(r) do
+ tex.sprint(tex.ctxcatcodes, string.format("\\NC %s\\NC\\getvalue{%s}\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR", k,
+ characters.contextname(v), characters.hexindex(v), characters.contextname(v),
+ characters.category(v), characters.description(v)))
+ end
+ tex.sprint(tex.ctxcatcodes,"\\stoptabulate")
+ else
+ tex.sprint(tex.ctxcatcodes,"unknown regime " .. regime)
+ end
+end
+\stopluacode
+
+\unprotect
+
+\def\showregime
+ {\dosingleempty\doshowregime}
+
+\def\doshowregime[#1]%
+ {\ctxlua{regimes.show("#1")}}
+
+\protect \endinput
diff --git a/tex/context/base/scrp-cjk.lua b/tex/context/base/scrp-cjk.lua
new file mode 100644
index 000000000..a452673fa
--- /dev/null
+++ b/tex/context/base/scrp-cjk.lua
@@ -0,0 +1,576 @@
+if not modules then modules = { } end modules ['scrp-cjk'] = {
+ version = 1.001,
+ comment = "companion to scrp-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local has_attribute = node.has_attribute
+local make_glue_node = nodes.glue
+local make_penalty_node = nodes.penalty
+local insert_node_after = node.insert_after
+local insert_node_before = node.insert_before
+local remove_node = nodes.remove
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local penalty = node.id('penalty')
+
+local preproc = attributes.private('preproc')
+local prestat = attributes.private('prestat')
+
+scripts.cjk = scripts.cjk or { }
+
+local kind_to_number = scripts.kind_to_number
+local number_to_kind = scripts.number_to_kind
+local hash = scripts.hash
+local cjk = scripts.cjk
+local fontdata = fonts.ids
+
+-- raggedleft is controlled by leftskip and we might end up with a situation where
+-- the intercharacter spacing interferes with this; the solution is to patch the
+-- nodelist but better is to use veryraggedleft
+
+local inter_char_stretch = 0
+local inter_char_half_shrink = 0
+local inter_char_hangul_penalty = 0
+
+local function set_parameters(font,data)
+ -- beware: parameters can be nil in e.g. punk variants
+ local parameters = fontdata[font].parameters
+ local quad = (parameters and parameters.quad or parameters[6]) or 0
+ inter_char_half_shrink = data.inter_char_half_shrink_factor * quad
+ inter_char_stretch = data.inter_char_stretch_factor * quad
+ inter_char_hangul_penalty = data.inter_char_hangul_penalty
+end
+
+-- a test version did compensate for crappy halfwidth but we can best do that
+-- at font definition time and/or just assume a correct font
+
+local function nobreak(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+end
+local function stretch_break(head,current)
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+local function shrink_break(head,current)
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+end
+local function nobreak_stretch(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+local function korean_break(head,current)
+ insert_node_before(head,current,make_penalty_node(inter_char_hangul_penalty))
+end
+
+local function nobreak_shrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+end
+local function nobreak_autoshrink(head,current)
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+end
+
+local function nobreak_stretch_nobreak_shrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+end
+local function nobreak_stretch_nobreak_autoshrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+end
+
+local function nobreak_shrink_nobreak_stretch(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+local function nobreak_autoshrink_nobreak_stretch(head,current)
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+
+local function nobreak_shrink_break_stretch(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+local function nobreak_autoshrink_break_stretch(head,current)
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+
+local function nobreak_shrink_break_stretch_nobreak_shrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+end
+local function nobreak_autoshrink_break_stretch_nobreak_autoshrink(head,current)
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+end
+local function nobreak_autoshrink_break_stretch_nobreak_shrink(head,current)
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+end
+local function nobreak_shrink_break_stretch_nobreak_autoshrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ if true then
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ end
+end
+
+local function nobreak_stretch_break_shrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+end
+local function nobreak_stretch_break_autoshrink(head,current)
+ insert_node_before(head,current,make_penalty_node(10000))
+ insert_node_before(head,current,make_glue_node(0,inter_char_stretch,0))
+ if true then
+ insert_node_before(head,current,make_glue_node(0,0,inter_char_half_shrink))
+ end
+end
+
+-- hangul (korean)
+
+local injectors = { -- [previous] [current]
+ jamo_final = {
+ jamo_initial = korean_break,
+ korean = korean_break,
+ chinese = korean_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak,
+ full_width_open = stretch_break,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = korean_break,
+ other = korean_break,
+ },
+ korean = {
+ jamo_initial = korean_break,
+ korean = korean_break,
+ chinese = korean_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak,
+ full_width_open = stretch_break,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = korean_break,
+ other = korean_break,
+ },
+ chinese = {
+ jamo_initial = korean_break,
+ korean = korean_break,
+ chinese = korean_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak,
+ full_width_open = stretch_break,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = korean_break,
+ other = korean_break,
+ },
+ hyphen = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak,
+ full_width_open = stretch_break,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = stretch_break,
+ other = stretch_break,
+ },
+ start = {
+ -- jamo_initial = nil,
+ -- korean = nil,
+ -- chinese = nil,
+ -- half_width_open = nil,
+ -- half_width_close = nil,
+ -- full_width_open = nil,
+ -- full_width_close = nil,
+ -- hyphen = nil,
+ -- non_starter = nil,
+ -- other = nil,
+ },
+ other = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak,
+ full_width_open = stretch_break,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = stretch_break,
+ other = stretch_break,
+ },
+ non_starter = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak,
+ full_width_open = stretch_break,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = nobreak,
+ other = nobreak,
+ },
+ full_width_open = {
+ jamo_initial = nobreak,
+ korean = nobreak,
+ chinese = nobreak,
+ half_width_open = nobreak,
+ half_width_close = nobreak,
+ full_width_open = nobreak,
+ full_width_close = nobreak,
+ hyphen = nobreak,
+ non_starter = nobreak,
+ other = nobreak,
+ },
+ half_width_open = {
+ jamo_initial = nobreak,
+ korean = nobreak,
+ chinese = nobreak,
+ half_width_open = nobreak,
+ half_width_close = nobreak,
+ full_width_open = nobreak,
+ full_width_close = nobreak,
+ hyphen = nobreak,
+ non_starter = nobreak,
+ other = nobreak,
+ },
+ full_width_close = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak_stretch,
+ full_width_open = stretch_break,
+ full_width_close = nobreak_stretch,
+ hyphen = nobreak_stretch,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ half_width_close = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = stretch_break,
+ half_width_close = nobreak_stretch,
+ full_width_open = stretch_break,
+ full_width_close = nobreak_stretch,
+ hyphen = nobreak_stretch,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+}
+
+local dataset = {
+ inter_char_stretch_factor = 0.50, -- of quad
+ inter_char_half_shrink_factor = 0.50, -- of quad
+ inter_char_hangul_penalty = 50,
+}
+
+local function process(head,first,last)
+ if first ~= last then
+ local lastfont, previous, originals, last = nil, "start", nil, nil
+ while true do
+ local upcoming, id = first.next, first.id
+ if id == glyph then
+ local a = has_attribute(first,prestat)
+ local current = number_to_kind[a]
+ local action = injectors[previous]
+ if action then
+ action = action[current]
+ if action then
+ local font = first.font
+ if font ~= lastfont then
+ lastfont, done = font, true
+ set_parameters(font,dataset)
+ end
+ action(head,first)
+ end
+ end
+ previous = current
+ else -- glue
+ local p, n = first.prev, upcoming
+ if p and n then
+ local pid, nid = p.id, n.id
+ if pid == glyph and nid == glyph then
+ local pa, na = has_attribute(p,prestat), has_attribute(n,prestat)
+ local pcjk, ncjk = pa and number_to_kind[pa], na and number_to_kind[na]
+ if not pcjk or not ncjk
+ or pcjk == "korean" or ncjk == "korean"
+ or pcjk == "other" or ncjk == "other"
+ or pcjk == "jamo_final" or ncjk == "jamo_initial" then
+ previous = "start"
+ else -- if head ~= first then
+ remove_node(head,first,true)
+ previous = pcjk
+ -- else
+ -- previous = pcjk
+ end
+ else
+ previous = "start"
+ end
+ else
+ previous = "start"
+ end
+ end
+ if upcoming == stop then
+ break
+ else
+ first = upcoming
+ end
+ end
+ end
+end
+
+scripts.install {
+ name = "hangul",
+ process = process,
+}
+
+-- hanzi (chinese)
+
+local injectors = { -- [previous] [current]
+ jamo_final = {
+ jamo_initial = korean_break,
+ korean = korean_break,
+ chinese = stretch_break,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ -- hyphen = nil,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ korean = {
+ jamo_initial = korean_break,
+ korean = korean_break,
+ chinese = stretch_break,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ -- hyphen = nil,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ chinese = {
+ jamo_initial = korean_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ hyphen = nobreak_stretch,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ hyphen = {
+ jamo_initial = korean_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ -- hyphen = nil,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ start = {
+ -- jamo_initial = nil,
+ -- korean = nil,
+ -- chinese = nil,
+ half_width_open = nobreak_autoshrink,
+ half_width_close = nil,
+ full_width_open = nobreak_shrink,
+ full_width_close = nobreak,
+ -- hyphen = nil,
+ non_starter = nobreak,
+ -- other = nil,
+ },
+ other = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ -- hyphen = nil,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ non_starter = {
+ jamo_initial = stretch_break,
+ korean = stretch_break,
+ chinese = stretch_break,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ -- hyphen = nil,
+ non_starter = nobreak_stretch,
+ other = stretch_break,
+ },
+ full_width_open = {
+ jamo_initial = nobreak_stretch,
+ korean = nobreak_stretch,
+ chinese = nobreak_stretch,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_break_shrink,
+ full_width_close = nobreak_stretch,
+ hyphen = nobreak_stretch,
+ non_starter = nobreak_stretch,
+ other = nobreak_stretch,
+ },
+ half_width_open = {
+ jamo_initial = nobreak_stretch,
+ korean = nobreak_stretch,
+ chinese = nobreak_stretch,
+ half_width_open = nobreak_stretch_break_autoshrink,
+ half_width_close = nobreak_stretch,
+ full_width_open = nobreak_stretch_nobreak_shrink,
+ full_width_close = nobreak_stretch,
+ hyphen = nobreak_stretch,
+ non_starter = nobreak_stretch,
+ other = nobreak_stretch,
+ },
+ full_width_close = {
+ jami_initial = nobreak_shrink_break_stretch,
+ korean = nobreak_shrink_break_stretch,
+ chinese = nobreak_shrink_break_stretch,
+ half_width_open = nobreak_shrink_break_stretch_nobreak_autoshrink,
+ half_width_close = nobreak_shrink_nobreak_stretch,
+ full_width_open = nobreak_shrink_break_stretch_nobreak_shrink,
+ full_width_close = nobreak_shrink_nobreak_stretch,
+ hyphen = nobreak_shrink_break_stretch,
+ non_starter = nobreak_shrink_break_stretch,
+ other = nobreak_shrink_break_stretch,
+ },
+ half_width_close = {
+ jami_initial = nobreak_shrink_break_stretch,
+ korean = nobreak_autoshrink_break_stretch,
+ chinese = nobreak_autoshrink_break_stretch,
+ half_width_open = nobreak_autoshrink_break_stretch_nobreak_autoshrink,
+ half_width_close = nobreak_autoshrink_nobreak_stretch,
+ full_width_open = nobreak_autoshrink_break_stretch_nobreak_shrink,
+ full_width_close = nobreak_autoshrink_nobreak_stretch,
+ hyphen = nobreak_autoshrink_break_stretch,
+ non_starter = nobreak_autoshrink_break_stretch,
+ other = nobreak_autoshrink_break_stretch,
+ },
+}
+
+local dataset = {
+ inter_char_stretch_factor = 0.50, -- of quad
+ inter_char_half_shrink_factor = 0.50, -- of quad
+ inter_char_hangul_penalty = 50,
+}
+
+local function process(head,first,last)
+ if first ~= last then
+ local lastfont, previous, originals, last = nil, "start", nil, nil
+ while true do
+ local upcoming, id = first.next, first.id
+ if id == glyph then
+ local a = has_attribute(first,prestat)
+ local current = number_to_kind[a]
+ local action = injectors[previous]
+ if action then
+ action = action[current]
+ if action then
+ local font = first.font
+ if font ~= lastfont then
+ lastfont, done = font, true
+ set_parameters(font,dataset)
+ end
+ action(head,first)
+ end
+ end
+ previous = current
+ else -- glue
+ local p, n = first.prev, upcoming
+ if p and n then
+ local pid, nid = p.id, n.id
+ if pid == glyph and nid == glyph then
+ local pa, na = has_attribute(p,prestat), has_attribute(n,prestat)
+ local pcjk, ncjk = pa and number_to_kind[pa], na and number_to_kind[na]
+ if not pcjk or not ncjk
+ or pcjk == "korean" or ncjk == "korean"
+ or pcjk == "other" or ncjk == "other"
+ or pcjk == "jamo_final" or ncjk == "jamo_initial" then
+ previous = "start"
+ else -- if head ~= first then
+ remove_node(head,first,true)
+ previous = pcjk
+ -- else
+ -- previous = pcjk
+ end
+ else
+ previous = "start"
+ end
+ else
+ previous = "start"
+ end
+ end
+ if upcoming == stop then
+ break
+ else
+ first = upcoming
+ end
+ end
+ end
+end
+
+scripts.install {
+ name = "hanzi",
+ process = process,
+}
diff --git a/tex/context/base/scrp-ini.lua b/tex/context/base/scrp-ini.lua
new file mode 100644
index 000000000..a55573284
--- /dev/null
+++ b/tex/context/base/scrp-ini.lua
@@ -0,0 +1,386 @@
+if not modules then modules = { } end modules ['scrp-ini'] = {
+ version = 1.001,
+ comment = "companion to scrp-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local trace_analyzing = false trackers.register("scripts.analyzing", function(v) trace_analyzing = v end)
+local trace_injections = false trackers.register("scripts.injections", function(v) trace_injections = v end)
+
+local set_attribute = node.set_attribute
+local has_attribute = node.has_attribute
+local first_character = node.first_character
+local traverse_id = node.traverse_id
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local penalty = node.id('penalty')
+
+local fcs = (fonts.color and fonts.color.set) or function() end
+local fcr = (fonts.color and fonts.color.reset) or function() end
+
+local state = attributes.private('state')
+local preproc = attributes.private('preproc')
+local prestat = attributes.private('prestat')
+
+local fontdata = fonts.ids
+
+scripts = scripts or { }
+scripts.handlers = scripts.handlers or { }
+
+scripts.names = scripts.names or { }
+scripts.numbers = scripts.numbers or { }
+scripts.hash = scripts.hash or { }
+
+storage.register("scripts/hash", scripts.hash, "scripts.hash")
+
+if not next(scripts.hash) then
+
+ local hash = {
+ --
+ -- half width opening parenthesis
+ [0x0028] = "half_width_open",
+ [0x005B] = "half_width_open",
+ [0x007B] = "half_width_open",
+ [0x2018] = "half_width_open", -- ‘
+ [0x201C] = "half_width_open", -- “
+ --
+ -- full width opening parenthesis
+ --
+ [0x3008] = "full_width_open", -- 〈 Left book quote
+ [0x300A] = "full_width_open", -- 《 Left double book quote
+ [0x300C] = "full_width_open", -- 「 left quote
+ [0x300E] = "full_width_open", -- 『 left double quote
+ [0x3010] = "full_width_open", -- 【 left double book quote
+ [0x3014] = "full_width_open", -- 〔 left book quote
+ [0x3016] = "full_width_open", --〖 left double book quote
+ [0x3018] = "full_width_open", -- left tortoise bracket
+ [0x301A] = "full_width_open", -- left square bracket
+ [0x301D] = "full_width_open", -- reverse double prime qm
+ [0xFF08] = "full_width_open", -- ( left parenthesis
+ [0xFF3B] = "full_width_open", -- [ left square brackets
+ [0xFF5B] = "full_width_open", -- { left curve bracket
+ [0xFF62] = "full_width_open", -- left corner bracket
+ --
+ -- half width closing parenthesis
+ [0x0029] = "half_width_close",
+ [0x005D] = "half_width_close",
+ [0x007D] = "half_width_close",
+ [0x2019] = "half_width_close", -- ’ right quote, right
+ [0x201D] = "half_width_close", -- ” right double quote
+ --
+ -- full width closing parenthesis
+ --
+ [0x3009] = "full_width_close", -- 〉 book quote
+ [0x300B] = "full_width_close", -- 》 double book quote
+ [0x300D] = "full_width_close", -- 」 right quote, right
+ [0x300F] = "full_width_close", -- 』 right double quote
+ [0x3011] = "full_width_close", -- 】 right double book quote
+ [0x3015] = "full_width_close", -- 〕 right book quote
+ [0x3017] = "full_width_close", -- 〗 right double book quote
+ [0x3019] = "full_width_close", -- right tortoise bracket
+ [0x301B] = "full_width_close", -- right square bracket
+ [0x301E] = "full_width_close", -- double prime qm
+ [0x301F] = "full_width_close", -- low double prime qm
+ [0xFF09] = "full_width_close", -- ) right parenthesis
+ [0xFF3D] = "full_width_close", -- ] right square brackets
+ [0xFF5D] = "full_width_close", -- } right curve brackets
+ [0xFF63] = "full_width_close", -- right corner bracket
+ --
+ -- vertical opening vertical
+ --
+ -- 0xFE35, 0xFE37, 0xFE39, 0xFE3B, 0xFE3D, 0xFE3F, 0xFE41, 0xFE43, 0xFE47,
+ --
+ -- vertical closing
+ --
+ -- 0xFE36, 0xFE38, 0xFE3A, 0xFE3C, 0xFE3E, 0xFE40, 0xFE42, 0xFE44, 0xFE48,
+ --
+ -- half width opening punctuation
+ --
+ -- <empty>
+ --
+ -- full width opening punctuation
+ --
+ -- 0x2236, -- ∶
+ -- 0xFF0C, -- ,
+ --
+ -- half width closing punctuation_hw
+ --
+ [0x0021] = "half_width_close", -- !
+ [0x002C] = "half_width_close", -- ,
+ [0x002E] = "half_width_close", -- .
+ [0x003A] = "half_width_close", -- :
+ [0x003B] = "half_width_close", -- ;
+ [0x003F] = "half_width_close", -- ?
+ [0xFF61] = "half_width_close", -- hw full stop
+ --
+ -- full width closing punctuation
+ [0x3001] = "full_width_close", -- 、
+ [0x3002] = "full_width_close", -- 。
+ [0xFF01] = "full_width_close", -- !
+ [0xFF0C] = "full_width_close", -- ,
+ [0xFF0E] = "full_width_close", -- .
+ [0xFF1A] = "full_width_close", -- :
+ [0xFF1B] = "full_width_close", -- ;
+ [0xFF1F] = "full_width_close", -- ?
+ --
+ -- non starter
+ --
+ [0x3005] = "non_starter", [0x3041] = "non_starter", [0x3043] = "non_starter", [0x3045] = "non_starter", [0x3047] = "non_starter",
+ [0x3049] = "non_starter", [0x3063] = "non_starter", [0x3083] = "non_starter", [0x3085] = "non_starter", [0x3087] = "non_starter",
+ [0x308E] = "non_starter", [0x3095] = "non_starter", [0x3096] = "non_starter", [0x309B] = "non_starter", [0x309C] = "non_starter",
+ [0x309D] = "non_starter", [0x309E] = "non_starter", [0x30A0] = "non_starter", [0x30A1] = "non_starter", [0x30A3] = "non_starter",
+ [0x30A5] = "non_starter", [0x30A7] = "non_starter", [0x30A9] = "non_starter", [0x30C3] = "non_starter", [0x30E3] = "non_starter",
+ [0x30E5] = "non_starter", [0x30E7] = "non_starter", [0x30EE] = "non_starter", [0x30F5] = "non_starter", [0x30F6] = "non_starter",
+ [0x30FC] = "non_starter", [0x30FD] = "non_starter", [0x30FE] = "non_starter", [0x31F0] = "non_starter", [0x31F1] = "non_starter",
+ [0x30F2] = "non_starter", [0x30F3] = "non_starter", [0x30F4] = "non_starter", [0x31F5] = "non_starter", [0x31F6] = "non_starter",
+ [0x30F7] = "non_starter", [0x30F8] = "non_starter", [0x30F9] = "non_starter", [0x31FA] = "non_starter", [0x31FB] = "non_starter",
+ [0x30FC] = "non_starter", [0x30FD] = "non_starter", [0x30FE] = "non_starter", [0x31FF] = "non_starter",
+ --
+ -- hyphenation
+ --
+ [0x2026] = "hyphen", -- … ellipsis
+ [0x2014] = "hyphen", -- — hyphen
+ }
+
+ for i=0x03040,0x0309F do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x030A0,0x030FF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x031F0,0x031FF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x03400,0x04DFF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x04E00,0x09FFF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x0F900,0x0FAFF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x0FF00,0x0FFEF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x20000,0x2A6DF do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x2F800,0x2FA1F do if not hash[i] then hash[i] = "chinese" end end
+ for i=0x0AC00,0x0D7A3 do if not hash[i] then hash[i] = "korean" end end
+ for i=0x01100,0x0115F do if not hash[i] then hash[i] = "jamo_initial" end end
+ for i=0x01160,0x011A7 do if not hash[i] then hash[i] = "jamo_medial" end end
+ for i=0x011A8,0x011FF do if not hash[i] then hash[i] = "jamo_final" end end
+
+ scripts.hash = hash
+
+end
+
+scripts.colors = { -- todo: just named colors
+ korean = "font:isol",
+ chinese = "font:rest",
+ full_width_open = "font:init",
+ full_width_close = "font:fina",
+ half_width_open = "font:init",
+ half_width_close = "font:fina",
+ hyphen = "font:medi",
+ non_starter = "font:isol",
+ jamo_initial = "font:init",
+ jamo_medial = "font:medi",
+ jamo_final = "font:fina",
+
+}
+
+scripts.number_to_kind = {
+ "korean",
+ "chinese",
+ "full_width_open",
+ "full_width_close",
+ "half_width_open",
+ "half_width_close",
+ "hyphen",
+ "non_starter",
+ "jamo_initial",
+ "jamo_medial",
+ "jamo_final",
+}
+
+scripts.kind_to_number = {
+ korean = 1,
+ chinese = 2,
+ full_width_open = 3,
+ full_width_close = 4,
+ half_width_open = 5,
+ half_width_close = 6,
+ hyphen = 7,
+ non_starter = 8,
+ jamo_initial = 9,
+ jamo_medial = 10,
+ jamo_final = 11,
+}
+
+local kind_to_number = scripts.kind_to_number
+local number_to_kind = scripts.number_to_kind
+
+-- no, this time loading the lua always precedes the definitions
+--
+-- storage.register("scripts/names", scripts.names, "scripts.names")
+-- storage.register("scripts/numbers", scripts.numbers, "scripts.numbers")
+
+local handlers = scripts.handlers
+local names = scripts.names
+local numbers = scripts.numbers
+local hash = scripts.hash
+local colors = scripts.colors
+
+-- maybe also process
+
+function scripts.install(handler)
+ local name = handler.name
+ if not names[name] then
+ local n = #numbers + 1
+ numbers[n] = name
+ names[name] = n
+ handlers[n] = handler
+ end
+ return names[name]
+end
+
+function scripts.define(name)
+ tex.write(names[name] or attributes.unsetvalue)
+end
+
+-- some time i will make a fonts.originals[id]
+
+local function colorize(start,stop)
+ for n in traverse_id(glyph,start) do
+ local kind = number_to_kind[has_attribute(n,prestat)]
+ if kind then
+ local ac = colors[kind]
+ if ac then
+ fcs(n,ac)
+ end
+ end
+ if n == stop then
+ break
+ end
+ end
+end
+
+local function traced_process(head,first,last,process,a)
+ if start ~= last then
+ local f, l = first, last
+ logs.report("preprocess","before %s: %s",names[a] or "?",nodes.tosequence(f,l))
+ process(head,first,last)
+ logs.report("preprocess","after %s: %s", names[a] or "?",nodes.tosequence(f,l))
+ end
+end
+
+-- eventually we might end up with more extensive parsing
+-- todo: pass t[start..stop] == original
+
+function scripts.preprocess(head)
+ local start = first_character(head)
+ if not start then
+ return head, false
+ else
+ local last_a, normal_process, lastfont, originals = nil, nil, nil, nil
+ local done, first, last, ok = false, nil, nil, false
+ while start do
+ local id = start.id
+ if id == glyph then
+ local a = has_attribute(start,preproc)
+ if a then
+ if a ~= last_a then
+ if first then
+ if ok then
+ if trace_analyzing then
+ colorize(first,last)
+ end
+ if trace_injections then
+ traced_process(head,first,last,normal_process,last_a)
+ else
+ normal_process(head,first,last)
+ end
+ ok, done = false, true
+ end
+ first, last = nil, nil
+ end
+ last_a = a
+ local handler = handlers[a]
+ normal_process = handler.process
+ end
+ if normal_process then
+ local f = start.font
+ if f ~= lastfont then
+ originals = fontdata[f].originals
+ lastfont = f
+ end
+ local c = start.char
+ if originals then c = originals[c] or c end
+ local h = hash[c]
+ if h then
+ set_attribute(start,prestat,kind_to_number[h])
+ if not first then
+ first, last = start, start
+ else
+ last = start
+ end
+ -- if cjk == "chinese" or cjk == "korean" then -- we need to prevent too much ( ) processing
+ ok = true
+ -- end
+ elseif first then
+ if ok then
+ if trace_analyzing then
+ colorize(first,last)
+ end
+ if trace_injections then
+ traced_process(head,first,last,normal_process,last_a)
+ else
+ normal_process(head,first,last)
+ end
+ ok, done = false, true
+ end
+ first, last = nil, nil
+ end
+ end
+ elseif first then
+ if ok then
+ if trace_analyzing then
+ colorize(first,last)
+ end
+ if trace_injections then
+ traced_process(head,first,last,normal_process,last_a)
+ else
+ normal_process(head,first,last)
+ end
+ ok, done = false, true
+ end
+ first, last = nil, nil
+ end
+ elseif id == glue then
+ if ok then
+ -- continue
+ elseif first then
+ -- no chinese or korean
+ first, last = nil, nil
+ end
+ elseif first then
+ if ok then
+ -- some chinese or korean
+ if trace_analyzing then
+ colorize(first,last)
+ end
+ if trace_injections then
+ traced_process(head,first,last,normal_process,last_a)
+ else
+ normal_process(head,first,last)
+ end
+ first, last, ok, done = nil, nil, false, true
+ elseif first then
+ first, last = nil, nil
+ end
+ end
+ start = start.next
+ end
+ if ok then
+ if trace_analyzing then
+ colorize(first,last)
+ end
+ if trace_injections then
+ traced_process(head,first,last,normal_process,last_a)
+ else
+ normal_process(head,first,last)
+ end
+ done = true
+ end
+ return head, done
+ end
+end
diff --git a/tex/context/base/scrp-ini.tex b/tex/context/base/scrp-ini.tex
new file mode 100644
index 000000000..3382ef4b6
--- /dev/null
+++ b/tex/context/base/scrp-ini.tex
@@ -0,0 +1,91 @@
+%D \module
+%D [ file=scrp-ini,
+%D version=2009.02.06,
+%D title=\CONTEXT\ Script Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA / 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.
+
+% here we collect code from other places (was organized differently)
+
+\registerctxluafile{scrp-ini}{1.001}
+\registerctxluafile{scrp-cjk}{1.001}
+
+\definesystemattribute[preproc]
+\definesystemattribute[prestat]
+
+%D Since scripts need specific \LUA\ code we use hard coded attribute
+%D values, but we might have more tricks at some time, so we use a
+%D proper define macro too.
+
+\unprotect
+
+\def\s!attribute{attribute}
+
+\def\namedscriptparameter#1#2%
+ {\csname\doscriptparameter{\??ls#1}#2\endcsname}
+
+\def\scriptparameter#1%
+ {\csname\doscriptparameter{\??ls\currentscript}#1\endcsname}
+
+\def\doscriptparameter#1#2%
+ {\ifcsname#1#2\endcsname#1#2\else\expandafter\doscriptparentparameter\csname#1\s!parent\endcsname#2\fi}
+
+\def\doscriptparentparameter#1#2%
+ {\ifx#1\relax\s!empty\else\doscriptparameter#1#2\fi}
+
+% \def\scriptparameterhash#1%
+% {\doscriptparameterhash{\??ls\currentscript}#1}
+%
+% \def\doscriptparameterhash#1#2%
+% {\ifcsname#1#2\endcsname#1\else\expandafter\doscriptparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+%
+% \def\doscriptparentparameterhash#1#2%
+% {\ifx#1\relax\else\doscriptparameterhash#1#2\fi}
+
+% when #2 == string, then only synonym, no settings
+
+\def\definescript
+ {\dodoubleargument\dodefinescript}
+
+\def\dodefinescript[#1][#2]%
+ {\doifassignmentelse{#2}
+ {\getparameters[\??ls#1][\c!method=,\s!parent=,#2]%
+ \doifelsenothing{\namedscriptparameter{#1}\c!method}
+ {\letvalue {\??ls#1\s!attribute}\attributeunsetvalue}%
+ {\setevalue{\??ls#1\s!attribute}{\ctxlua{scripts.define("\namedscriptparameter{#1}\c!method")}}}}%
+ {\getparameters[\??ls#1][\s!parent=#2]}%
+ \setvalue{#1}{\dosetscript{#1}}}
+
+\def\setupscript
+ {\dodoubleargument\dosetupscript}
+
+\def\dosetupscript[#1][#2]%
+ {\getparameters[\??ls#1][#2]}
+
+\def\dosetscript#1%
+ {\def\currentscript{#1}%
+ \edef\currentscriptattribute{\scriptparameter\s!attribute}%
+ \ifx\currentscriptattribute\empty
+ \let\currentscript\empty
+ \doresetattribute{preproc}%
+ \else
+ \dosetattribute{preproc}\currentscriptattribute % we can speed this up by storing the attribute in ??ls:a:#1
+ \fi}
+
+\def\setscript [#1]{\dosetscript{#1}}
+\def\startscript[#1]{\begingroup\dosetscript{#1}}
+\def\stopscript {\endgroup}
+
+% \setscript[hangul] \hangul \startscript[hangul]
+
+\definescript[latin] [\c!method=] % resets the attribute
+\definescript[hangul][\c!method=hangul]
+\definescript[hanzi] [\c!method=hanzi]
+
+\protect \endinput
diff --git a/tex/context/base/sort-def.mkii b/tex/context/base/sort-def.mkii
deleted file mode 100644
index 10dc31b14..000000000
--- a/tex/context/base/sort-def.mkii
+++ /dev/null
@@ -1,450 +0,0 @@
-%D \module
-%D [ file=sort-def,
-%D version=2005.08.08,
-%D title=\CONTEXT\ Sort Macros,
-%D subtitle=Defaults,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 replaces existing sort key handling and is meant to be
-%D used with the new texutil functionality. Here we define the default
-%D mappings
-
-\exportsortexpansion{aeligature} {ae}
-\exportsortexpansion{AEligature} {AE}
-\exportsortexpansion{ijligature} {ij}
-\exportsortexpansion{IJligature} {IJ}
-\exportsortexpansion{oeligature} {oe}
-\exportsortexpansion{OEligature} {OE}
-
-\exportsortexpansion{ssharp} {ss}
-\exportsortexpansion{Ssharp} {SS}
-
-\exportsortexpansion{thorn} {}
-\exportsortexpansion{Thorn} {}
-
-\exportsortexpansion{eth} {}
-\exportsortexpansion{Eth} {}
-
-\exportsortexpansion{dj} {dstroke}
-\exportsortexpansion{Dj} {Dstroke}
-
-\exportsortexpansion{Acircumflex} {}
-\exportsortexpansion{acircumflex} {}
-\exportsortexpansion{Ccircumflex} {}
-\exportsortexpansion{ccircumflex} {}
-\exportsortexpansion{Ecircumflex} {}
-\exportsortexpansion{ecircumflex} {}
-\exportsortexpansion{Gcircumflex} {}
-\exportsortexpansion{gcircumflex} {}
-\exportsortexpansion{Hcircumflex} {}
-\exportsortexpansion{hcircumflex} {}
-\exportsortexpansion{Icircumflex} {}
-\exportsortexpansion{icircumflex} {}
-\exportsortexpansion{Jcircumflex} {}
-\exportsortexpansion{jcircumflex} {}
-\exportsortexpansion{Ocircumflex} {}
-\exportsortexpansion{ocircumflex} {}
-\exportsortexpansion{Scircumflex} {}
-\exportsortexpansion{scircumflex} {}
-\exportsortexpansion{Ucircumflex} {}
-\exportsortexpansion{ucircumflex} {}
-\exportsortexpansion{Wcircumflex} {}
-\exportsortexpansion{wcircumflex} {}
-\exportsortexpansion{Ycircumflex} {}
-\exportsortexpansion{ycircumflex} {}
-
-\exportsortexpansion{Agrave} {}
-\exportsortexpansion{agrave} {}
-\exportsortexpansion{Egrave} {}
-\exportsortexpansion{egrave} {}
-\exportsortexpansion{Igrave} {}
-\exportsortexpansion{igrave} {}
-\exportsortexpansion{Ograve} {}
-\exportsortexpansion{ograve} {}
-\exportsortexpansion{Ugrave} {}
-\exportsortexpansion{ugrave} {}
-\exportsortexpansion{Ygrave} {}
-\exportsortexpansion{ygrave} {}
-
-\exportsortexpansion{Atilde} {}
-\exportsortexpansion{atilde} {}
-\exportsortexpansion{Itilde} {}
-\exportsortexpansion{itilde} {}
-\exportsortexpansion{Ntilde} {}
-\exportsortexpansion{ntilde} {}
-\exportsortexpansion{Otilde} {}
-\exportsortexpansion{otilde} {}
-\exportsortexpansion{Utilde} {}
-\exportsortexpansion{utilde} {}
-\exportsortexpansion{Ytilde} {}
-\exportsortexpansion{ytilde} {}
-
-\exportsortexpansion{Adiaeresis} {}
-\exportsortexpansion{adiaeresis} {}
-\exportsortexpansion{Ediaeresis} {}
-\exportsortexpansion{ediaeresis} {}
-\exportsortexpansion{Idiaeresis} {}
-\exportsortexpansion{idiaeresis} {}
-\exportsortexpansion{Odiaeresis} {}
-\exportsortexpansion{odiaeresis} {}
-\exportsortexpansion{Udiaeresis} {}
-\exportsortexpansion{udiaeresis} {}
-\exportsortexpansion{Ydiaeresis} {}
-\exportsortexpansion{ydiaeresis} {}
-
-\exportsortexpansion{Aacute} {}
-\exportsortexpansion{aacute} {}
-\exportsortexpansion{Cacute} {}
-\exportsortexpansion{cacute} {}
-\exportsortexpansion{Eacute} {}
-\exportsortexpansion{eacute} {}
-\exportsortexpansion{Iacute} {}
-\exportsortexpansion{iacute} {}
-\exportsortexpansion{Lacute} {}
-\exportsortexpansion{lacute} {}
-\exportsortexpansion{Nacute} {}
-\exportsortexpansion{nacute} {}
-\exportsortexpansion{Oacute} {}
-\exportsortexpansion{oacute} {}
-\exportsortexpansion{Racute} {}
-\exportsortexpansion{racute} {}
-\exportsortexpansion{Sacute} {}
-\exportsortexpansion{sacute} {}
-\exportsortexpansion{Uacute} {}
-\exportsortexpansion{uacute} {}
-\exportsortexpansion{Yacute} {}
-\exportsortexpansion{yacute} {}
-\exportsortexpansion{Zacute} {}
-\exportsortexpansion{zacute} {}
-
-\exportsortexpansion{dstroke} {}
-\exportsortexpansion{Dstroke} {}
-\exportsortexpansion{Hstroke} {}
-\exportsortexpansion{hstroke} {}
-\exportsortexpansion{Tstroke} {}
-\exportsortexpansion{tstroke} {}
-
-\exportsortexpansion{Cdotaccent} {}
-\exportsortexpansion{cdotaccent} {}
-\exportsortexpansion{Edotaccent} {}
-\exportsortexpansion{edotaccent} {}
-\exportsortexpansion{Gdotaccent} {}
-\exportsortexpansion{gdotaccent} {}
-\exportsortexpansion{Idotaccent} {}
-\exportsortexpansion{idotaccent} {}
-\exportsortexpansion{Zdotaccent} {}
-\exportsortexpansion{zdotaccent} {}
-
-\exportsortexpansion{Amacron} {}
-\exportsortexpansion{amacron} {}
-\exportsortexpansion{Emacron} {}
-\exportsortexpansion{emacron} {}
-\exportsortexpansion{Imacron} {}
-\exportsortexpansion{imacron} {}
-\exportsortexpansion{Omacron} {}
-\exportsortexpansion{omacron} {}
-\exportsortexpansion{Umacron} {}
-\exportsortexpansion{umacron} {}
-
-\exportsortexpansion{Ccedilla} {}
-\exportsortexpansion{ccedilla} {}
-\exportsortexpansion{Kcedilla} {}
-\exportsortexpansion{kcedilla} {}
-\exportsortexpansion{Lcedilla} {}
-\exportsortexpansion{lcedilla} {}
-\exportsortexpansion{Ncedilla} {}
-\exportsortexpansion{ncedilla} {}
-\exportsortexpansion{Rcedilla} {}
-\exportsortexpansion{rcedilla} {}
-\exportsortexpansion{Scedilla} {}
-\exportsortexpansion{scedilla} {}
-\exportsortexpansion{Tcedilla} {}
-\exportsortexpansion{tcedilla} {}
-
-\exportsortexpansion{Ohungarumlaut} {}
-\exportsortexpansion{ohungarumlaut} {}
-\exportsortexpansion{Uhungarumlaut} {}
-\exportsortexpansion{uhungarumlaut} {}
-
-\exportsortexpansion{Aogonek} {}
-\exportsortexpansion{aogonek} {}
-\exportsortexpansion{Eogonek} {}
-\exportsortexpansion{eogonek} {}
-\exportsortexpansion{Iogonek} {}
-\exportsortexpansion{iogonek} {}
-\exportsortexpansion{Uogonek} {}
-\exportsortexpansion{uogonek} {}
-
-\exportsortexpansion{Aring} {}
-\exportsortexpansion{aring} {}
-\exportsortexpansion{Uring} {}
-\exportsortexpansion{uring} {}
-
-\exportsortexpansion{Abreve} {}
-\exportsortexpansion{abreve} {}
-\exportsortexpansion{Ebreve} {}
-\exportsortexpansion{ebreve} {}
-\exportsortexpansion{Gbreve} {}
-\exportsortexpansion{gbreve} {}
-\exportsortexpansion{Ibreve} {}
-\exportsortexpansion{ibreve} {}
-\exportsortexpansion{Obreve} {}
-\exportsortexpansion{obreve} {}
-\exportsortexpansion{Ubreve} {}
-\exportsortexpansion{ubreve} {}
-
-\exportsortexpansion{Ccaron} {}
-\exportsortexpansion{ccaron} {}
-\exportsortexpansion{Dcaron} {}
-\exportsortexpansion{dcaron} {}
-\exportsortexpansion{Ecaron} {}
-\exportsortexpansion{ecaron} {}
-\exportsortexpansion{Lcaron} {}
-\exportsortexpansion{lcaron} {}
-\exportsortexpansion{Ncaron} {}
-\exportsortexpansion{ncaron} {}
-\exportsortexpansion{Rcaron} {}
-\exportsortexpansion{rcaron} {}
-\exportsortexpansion{Scaron} {}
-\exportsortexpansion{scaron} {}
-\exportsortexpansion{Tcaron} {}
-\exportsortexpansion{tcaron} {}
-\exportsortexpansion{Ycaron} {}
-\exportsortexpansion{ycaron} {}
-\exportsortexpansion{Zcaron} {}
-\exportsortexpansion{zcaron} {}
-
-\exportsortexpansion{Lstroke} {}
-\exportsortexpansion{lstroke} {}
-\exportsortexpansion{Ostroke} {}
-\exportsortexpansion{ostroke} {}
-
-\exportsortexpansion{aumlaut} {}
-\exportsortexpansion{eumlaut} {}
-\exportsortexpansion{iumlaut} {}
-\exportsortexpansion{oumlaut} {}
-\exportsortexpansion{uumlaut} {}
-
-\exportsortexpansion{Aumlaut} {}
-\exportsortexpansion{Eumlaut} {}
-\exportsortexpansion{Iumlaut} {}
-\exportsortexpansion{Oumlaut} {}
-\exportsortexpansion{Uumlaut} {}
-
-\exportsortexpansion{scommaaccent} {}
-\exportsortexpansion{Scommaaccent} {}
-\exportsortexpansion{tcommaaccent} {}
-\exportsortexpansion{Tcommaaccent} {}
-
-\exportsortexpansion{Etilde} {}
-\exportsortexpansion{etilde} {}
-
-\exportsortexpansion{Ahook} {}
-\exportsortexpansion{ahook} {}
-\exportsortexpansion{Ehook} {}
-\exportsortexpansion{ehook} {}
-\exportsortexpansion{Ihook} {}
-\exportsortexpansion{ihook} {}
-\exportsortexpansion{Ohook} {}
-\exportsortexpansion{ohook} {}
-\exportsortexpansion{Uhook} {}
-\exportsortexpansion{uhook} {}
-\exportsortexpansion{Yhook} {}
-\exportsortexpansion{yhook} {}
-
-\exportsortexpansion{Acircumflexgrave} {}
-\exportsortexpansion{Acircumflexacute} {}
-\exportsortexpansion{Acircumflextilde} {}
-\exportsortexpansion{Acircumflexhook} {}
-\exportsortexpansion{acircumflexgrave} {}
-\exportsortexpansion{acircumflexacute} {}
-\exportsortexpansion{acircumflextilde} {}
-\exportsortexpansion{acircumflexhook} {}
-\exportsortexpansion{Ecircumflexgrave} {}
-\exportsortexpansion{Ecircumflexacute} {}
-\exportsortexpansion{Ecircumflextilde} {}
-\exportsortexpansion{Ecircumflexhook} {}
-\exportsortexpansion{ecircumflexgrave} {}
-\exportsortexpansion{ecircumflexacute} {}
-\exportsortexpansion{ecircumflextilde} {}
-\exportsortexpansion{ecircumflexhook} {}
-\exportsortexpansion{Ocircumflexgrave} {}
-\exportsortexpansion{Ocircumflexacute} {}
-\exportsortexpansion{Ocircumflextilde} {}
-\exportsortexpansion{Ocircumflexhook} {}
-\exportsortexpansion{ocircumflexgrave} {}
-\exportsortexpansion{ocircumflexacute} {}
-\exportsortexpansion{ocircumflextilde} {}
-\exportsortexpansion{ocircumflexhook} {}
-
-\exportsortexpansion{Abrevegrave} {}
-\exportsortexpansion{Abreveacute} {}
-\exportsortexpansion{Abrevetilde} {}
-\exportsortexpansion{Abrevehook} {}
-\exportsortexpansion{abrevegrave} {}
-\exportsortexpansion{abreveacute} {}
-\exportsortexpansion{abrevetilde} {}
-\exportsortexpansion{abrevehook} {}
-
-\exportsortexpansion{Adotbelow} {}
-\exportsortexpansion{adotbelow} {}
-\exportsortexpansion{Edotbelow} {}
-\exportsortexpansion{edotbelow} {}
-\exportsortexpansion{Idotbelow} {}
-\exportsortexpansion{idotbelow} {}
-\exportsortexpansion{Odotbelow} {}
-\exportsortexpansion{odotbelow} {}
-\exportsortexpansion{Udotbelow} {}
-\exportsortexpansion{udotbelow} {}
-\exportsortexpansion{Ydotbelow} {}
-\exportsortexpansion{ydotbelow} {}
-\exportsortexpansion{Ohorndotbelow} {}
-\exportsortexpansion{ohorndotbelow} {}
-\exportsortexpansion{Uhorndotbelow} {}
-\exportsortexpansion{uhorndotbelow} {}
-
-\exportsortexpansion{Acircumflexdotbelow} {}
-\exportsortexpansion{acircumflexdotbelow} {}
-\exportsortexpansion{Ecircumflexdotbelow} {}
-\exportsortexpansion{ecircumflexdotbelow} {}
-\exportsortexpansion{Ocircumflexdotbelow} {}
-\exportsortexpansion{ocircumflexdotbelow} {}
-\exportsortexpansion{Abrevedotbelow} {}
-\exportsortexpansion{abrevedotbelow} {}
-
-\exportsortexpansion{Ohorn} {}
-\exportsortexpansion{Ohorngrave} {}
-\exportsortexpansion{Ohornacute} {}
-\exportsortexpansion{Ohorntilde} {}
-\exportsortexpansion{Ohornhook } {}
-\exportsortexpansion{ohorn} {}
-\exportsortexpansion{ohorngrave} {}
-\exportsortexpansion{ohornacute} {}
-\exportsortexpansion{ohorntilde} {}
-\exportsortexpansion{ohornhook } {}
-\exportsortexpansion{Uhorn} {}
-\exportsortexpansion{Uhorngrave} {}
-\exportsortexpansion{Uhornacute} {}
-\exportsortexpansion{Uhorntilde} {}
-\exportsortexpansion{Uhornhook } {}
-\exportsortexpansion{uhorn} {}
-\exportsortexpansion{uhorngrave} {}
-\exportsortexpansion{uhornacute} {}
-\exportsortexpansion{uhorntilde} {}
-\exportsortexpansion{uhornhook} {}
-
-\exportsortexpansion{eszett} {ssharp}
-\exportsortexpansion{Eszett} {Ssharp}
-
-\exportsortexpansion{lslash} {lstroke}
-\exportsortexpansion{Lslash} {Lstroke}
-\exportsortexpansion{dslash} {dstroke}
-\exportsortexpansion{Dslash} {Dstroke}
-\exportsortexpansion{oslash} {ostroke}
-\exportsortexpansion{Oslash} {Ostroke}
-
-\exportsortexpansion{dcroat} {dstroke}
-\exportsortexpansion{Dcroat} {Dstroke}
-
-% more
-
-\exportsortshortcut{\^ A} {\Acircumflex} \exportsortshortcut{\^ a} {\acircumflex}
-\exportsortshortcut{\^ C} {\Ccircumflex} \exportsortshortcut{\^ c} {\ccircumflex}
-\exportsortshortcut{\^ E} {\Ecircumflex} \exportsortshortcut{\^ e} {\ecircumflex}
-\exportsortshortcut{\^ G} {\Gcircumflex} \exportsortshortcut{\^ g} {\gcircumflex}
-\exportsortshortcut{\^ H} {\Hcircumflex} \exportsortshortcut{\^ h} {\hcircumflex}
-\exportsortshortcut{\^ I} {\Icircumflex} \exportsortshortcut{\^ i} {\icircumflex} \exportsortshortcut{\^\i} {\icircumflex}
-\exportsortshortcut{\^ J} {\Jcircumflex} \exportsortshortcut{\^ j} {\jcircumflex} \exportsortshortcut{\^\j} {\jcircumflex}
-\exportsortshortcut{\^ O} {\Ocircumflex} \exportsortshortcut{\^ o} {\ocircumflex}
-\exportsortshortcut{\^ S} {\Scircumflex} \exportsortshortcut{\^ s} {\scircumflex}
-\exportsortshortcut{\^ U} {\Ucircumflex} \exportsortshortcut{\^ u} {\ucircumflex}
-\exportsortshortcut{\^ W} {\Wcircumflex} \exportsortshortcut{\^ w} {\wcircumflex}
-\exportsortshortcut{\^ Y} {\Ycircumflex} \exportsortshortcut{\^ y} {\ycircumflex}
-
-\exportsortshortcut{\` A} {\Agrave} \exportsortshortcut{\` a} {\agrave}
-\exportsortshortcut{\` E} {\Egrave} \exportsortshortcut{\` e} {\egrave}
-\exportsortshortcut{\` I} {\Igrave} \exportsortshortcut{\` i} {\igrave} \exportsortshortcut{\`\i} {\igrave}
-\exportsortshortcut{\` O} {\Ograve} \exportsortshortcut{\` o} {\ograve}
-\exportsortshortcut{\` U} {\Ugrave} \exportsortshortcut{\` u} {\ugrave}
-\exportsortshortcut{\` Y} {\Ygrave} \exportsortshortcut{\` y} {\ygrave}
-
-\exportsortshortcut{\~ A} {\Atilde} \exportsortshortcut{\~ a} {\atilde}
-\exportsortshortcut{\~ I} {\Itilde} \exportsortshortcut{\~ i} {\itilde} \exportsortshortcut{\~\i} {\itilde}
-\exportsortshortcut{\~ O} {\Otilde} \exportsortshortcut{\~ o} {\otilde}
-\exportsortshortcut{\~ U} {\Utilde} \exportsortshortcut{\~ u} {\utilde}
-
-\exportsortshortcut{\" A} {\Adiaeresis} \exportsortshortcut{\" a} {\adiaeresis}
-\exportsortshortcut{\" E} {\Ediaeresis} \exportsortshortcut{\" e} {\ediaeresis}
-\exportsortshortcut{\" I} {\Idiaeresis} \exportsortshortcut{\" i} {\idiaeresis} \exportsortshortcut{\"\i} {\idiaeresis}
-\exportsortshortcut{\" O} {\Odiaeresis} \exportsortshortcut{\" o} {\odiaeresis}
-\exportsortshortcut{\" U} {\Udiaeresis} \exportsortshortcut{\" u} {\udiaeresis}
-\exportsortshortcut{\" Y} {\Ydiaeresis} \exportsortshortcut{\" y} {\ydiaeresis}
-
-\exportsortshortcut{\' A} {\Aacute} \exportsortshortcut{\' a} {\aacute}
-\exportsortshortcut{\' C} {\Cacute} \exportsortshortcut{\' c} {\cacute}
-\exportsortshortcut{\' E} {\Eacute} \exportsortshortcut{\' e} {\eacute}
-\exportsortshortcut{\' I} {\Iacute} \exportsortshortcut{\' i} {\iacute} \exportsortshortcut{\'\i} {\iacute}
-\exportsortshortcut{\' L} {\Lacute} \exportsortshortcut{\' l} {\lacute}
-\exportsortshortcut{\' N} {\Nacute} \exportsortshortcut{\' n} {\nacute}
-\exportsortshortcut{\' O} {\Oacute} \exportsortshortcut{\' o} {\oacute}
-\exportsortshortcut{\' R} {\Racute} \exportsortshortcut{\' r} {\racute}
-\exportsortshortcut{\' S} {\Sacute} \exportsortshortcut{\' s} {\sacute}
-\exportsortshortcut{\' U} {\Uacute} \exportsortshortcut{\' u} {\uacute}
-\exportsortshortcut{\' Y} {\Yacute} \exportsortshortcut{\' y} {\yacute}
-\exportsortshortcut{\' Z} {\Zacute} \exportsortshortcut{\' z} {\zacute}
-
-\exportsortshortcut{\. C} {\Cdotaccent} \exportsortshortcut{\. c} {\cdotaccent}
-\exportsortshortcut{\. E} {\Edotaccent} \exportsortshortcut{\. e} {\edotaccent}
-\exportsortshortcut{\. G} {\Gdotaccent} \exportsortshortcut{\. g} {\gdotaccent}
-\exportsortshortcut{\. I} {\Idotaccent} \exportsortshortcut{\. i} {\idotaccent} \exportsortshortcut{\.\i} {\idotaccent}
-\exportsortshortcut{\. Z} {\Zdotaccent} \exportsortshortcut{\. z} {\zdotaccent}
-
-\exportsortshortcut{\= A} {\Amacron} \exportsortshortcut{\= a} {\amacron}
-\exportsortshortcut{\= E} {\Emacron} \exportsortshortcut{\= e} {\emacron}
-\exportsortshortcut{\= I} {\Imacron} \exportsortshortcut{\= i} {\imacron} \exportsortshortcut{\=\i} {\imacron}
-\exportsortshortcut{\= O} {\Omacron} \exportsortshortcut{\= o} {\omacron}
-\exportsortshortcut{\= U} {\Umacron} \exportsortshortcut{\= u} {\umacron}
-
-\exportsortshortcut{\c C} {\Ccedilla} \exportsortshortcut{\c c} {\ccedilla}
-\exportsortshortcut{\c K} {\Kcedilla} \exportsortshortcut{\c k} {\kcedilla}
-\exportsortshortcut{\c L} {\Lcedilla} \exportsortshortcut{\c l} {\lcedilla}
-\exportsortshortcut{\c N} {\Ncedilla} \exportsortshortcut{\c n} {\ncedilla}
-\exportsortshortcut{\c R} {\Rcedilla} \exportsortshortcut{\c r} {\rcedilla}
-\exportsortshortcut{\c S} {\Scedilla} \exportsortshortcut{\c s} {\scedilla}
-\exportsortshortcut{\c T} {\Tcedilla} \exportsortshortcut{\c t} {\tcedilla}
-
-\exportsortshortcut{\H O} {\Ohungarumlaut} \exportsortshortcut{\H o} {\ohungarumlaut}
-\exportsortshortcut{\H u} {\uhungarumlaut} \exportsortshortcut{\H U} {\Uhungarumlaut}
-
-\exportsortshortcut{\k A} {\Aogonek} \exportsortshortcut{\k a} {\aogonek}
-\exportsortshortcut{\k E} {\Eogonek} \exportsortshortcut{\k e} {\eogonek}
-\exportsortshortcut{\k I} {\Iogonek} \exportsortshortcut{\k i} {\iogonek}
-\exportsortshortcut{\k U} {\Uogonek} \exportsortshortcut{\k u} {\uogonek}
-
-\exportsortshortcut{\r A} {\Aring} \exportsortshortcut{\r a} {\aring}
-\exportsortshortcut{\r U} {\Uring} \exportsortshortcut{\r u} {\uring}
-
-\exportsortshortcut{\u A} {\Abreve} \exportsortshortcut{\u a} {\abreve}
-\exportsortshortcut{\u E} {\Ebreve} \exportsortshortcut{\u e} {\ebreve}
-\exportsortshortcut{\u G} {\Gbreve} \exportsortshortcut{\u g} {\gbreve}
-\exportsortshortcut{\u I} {\Ibreve} \exportsortshortcut{\u i} {\ibreve} \exportsortshortcut{\u\i} {\ibreve}
-\exportsortshortcut{\u O} {\Obreve} \exportsortshortcut{\u o} {\obreve}
-\exportsortshortcut{\u U} {\Ubreve} \exportsortshortcut{\u u} {\ubreve}
-
-\exportsortshortcut{\v C} {\Ccaron} \exportsortshortcut{\v c} {\ccaron}
-\exportsortshortcut{\v D} {\Dcaron} \exportsortshortcut{\v d} {\dcaron}
-\exportsortshortcut{\v E} {\Ecaron} \exportsortshortcut{\v e} {\ecaron}
-\exportsortshortcut{\v L} {\Lcaron} \exportsortshortcut{\v l} {\lcaron}
-\exportsortshortcut{\v N} {\Ncaron} \exportsortshortcut{\v n} {\ncaron}
-\exportsortshortcut{\v R} {\Rcaron} \exportsortshortcut{\v r} {\rcaron}
-\exportsortshortcut{\v S} {\Scaron} \exportsortshortcut{\v s} {\scaron}
-\exportsortshortcut{\v T} {\Tcaron} \exportsortshortcut{\v t} {\tcaron}
-\exportsortshortcut{\v Z} {\Zcaron} \exportsortshortcut{\v z} {\zcaron}
-
-\endinput
diff --git a/tex/context/base/sort-def.tex b/tex/context/base/sort-def.tex
index 502fb787f..10dc31b14 100644
--- a/tex/context/base/sort-def.tex
+++ b/tex/context/base/sort-def.tex
@@ -15,6 +15,436 @@
%D used with the new texutil functionality. Here we define the default
%D mappings
-\loadmarkfile{sort-def}
+\exportsortexpansion{aeligature} {ae}
+\exportsortexpansion{AEligature} {AE}
+\exportsortexpansion{ijligature} {ij}
+\exportsortexpansion{IJligature} {IJ}
+\exportsortexpansion{oeligature} {oe}
+\exportsortexpansion{OEligature} {OE}
+
+\exportsortexpansion{ssharp} {ss}
+\exportsortexpansion{Ssharp} {SS}
+
+\exportsortexpansion{thorn} {}
+\exportsortexpansion{Thorn} {}
+
+\exportsortexpansion{eth} {}
+\exportsortexpansion{Eth} {}
+
+\exportsortexpansion{dj} {dstroke}
+\exportsortexpansion{Dj} {Dstroke}
+
+\exportsortexpansion{Acircumflex} {}
+\exportsortexpansion{acircumflex} {}
+\exportsortexpansion{Ccircumflex} {}
+\exportsortexpansion{ccircumflex} {}
+\exportsortexpansion{Ecircumflex} {}
+\exportsortexpansion{ecircumflex} {}
+\exportsortexpansion{Gcircumflex} {}
+\exportsortexpansion{gcircumflex} {}
+\exportsortexpansion{Hcircumflex} {}
+\exportsortexpansion{hcircumflex} {}
+\exportsortexpansion{Icircumflex} {}
+\exportsortexpansion{icircumflex} {}
+\exportsortexpansion{Jcircumflex} {}
+\exportsortexpansion{jcircumflex} {}
+\exportsortexpansion{Ocircumflex} {}
+\exportsortexpansion{ocircumflex} {}
+\exportsortexpansion{Scircumflex} {}
+\exportsortexpansion{scircumflex} {}
+\exportsortexpansion{Ucircumflex} {}
+\exportsortexpansion{ucircumflex} {}
+\exportsortexpansion{Wcircumflex} {}
+\exportsortexpansion{wcircumflex} {}
+\exportsortexpansion{Ycircumflex} {}
+\exportsortexpansion{ycircumflex} {}
+
+\exportsortexpansion{Agrave} {}
+\exportsortexpansion{agrave} {}
+\exportsortexpansion{Egrave} {}
+\exportsortexpansion{egrave} {}
+\exportsortexpansion{Igrave} {}
+\exportsortexpansion{igrave} {}
+\exportsortexpansion{Ograve} {}
+\exportsortexpansion{ograve} {}
+\exportsortexpansion{Ugrave} {}
+\exportsortexpansion{ugrave} {}
+\exportsortexpansion{Ygrave} {}
+\exportsortexpansion{ygrave} {}
+
+\exportsortexpansion{Atilde} {}
+\exportsortexpansion{atilde} {}
+\exportsortexpansion{Itilde} {}
+\exportsortexpansion{itilde} {}
+\exportsortexpansion{Ntilde} {}
+\exportsortexpansion{ntilde} {}
+\exportsortexpansion{Otilde} {}
+\exportsortexpansion{otilde} {}
+\exportsortexpansion{Utilde} {}
+\exportsortexpansion{utilde} {}
+\exportsortexpansion{Ytilde} {}
+\exportsortexpansion{ytilde} {}
+
+\exportsortexpansion{Adiaeresis} {}
+\exportsortexpansion{adiaeresis} {}
+\exportsortexpansion{Ediaeresis} {}
+\exportsortexpansion{ediaeresis} {}
+\exportsortexpansion{Idiaeresis} {}
+\exportsortexpansion{idiaeresis} {}
+\exportsortexpansion{Odiaeresis} {}
+\exportsortexpansion{odiaeresis} {}
+\exportsortexpansion{Udiaeresis} {}
+\exportsortexpansion{udiaeresis} {}
+\exportsortexpansion{Ydiaeresis} {}
+\exportsortexpansion{ydiaeresis} {}
+
+\exportsortexpansion{Aacute} {}
+\exportsortexpansion{aacute} {}
+\exportsortexpansion{Cacute} {}
+\exportsortexpansion{cacute} {}
+\exportsortexpansion{Eacute} {}
+\exportsortexpansion{eacute} {}
+\exportsortexpansion{Iacute} {}
+\exportsortexpansion{iacute} {}
+\exportsortexpansion{Lacute} {}
+\exportsortexpansion{lacute} {}
+\exportsortexpansion{Nacute} {}
+\exportsortexpansion{nacute} {}
+\exportsortexpansion{Oacute} {}
+\exportsortexpansion{oacute} {}
+\exportsortexpansion{Racute} {}
+\exportsortexpansion{racute} {}
+\exportsortexpansion{Sacute} {}
+\exportsortexpansion{sacute} {}
+\exportsortexpansion{Uacute} {}
+\exportsortexpansion{uacute} {}
+\exportsortexpansion{Yacute} {}
+\exportsortexpansion{yacute} {}
+\exportsortexpansion{Zacute} {}
+\exportsortexpansion{zacute} {}
+
+\exportsortexpansion{dstroke} {}
+\exportsortexpansion{Dstroke} {}
+\exportsortexpansion{Hstroke} {}
+\exportsortexpansion{hstroke} {}
+\exportsortexpansion{Tstroke} {}
+\exportsortexpansion{tstroke} {}
+
+\exportsortexpansion{Cdotaccent} {}
+\exportsortexpansion{cdotaccent} {}
+\exportsortexpansion{Edotaccent} {}
+\exportsortexpansion{edotaccent} {}
+\exportsortexpansion{Gdotaccent} {}
+\exportsortexpansion{gdotaccent} {}
+\exportsortexpansion{Idotaccent} {}
+\exportsortexpansion{idotaccent} {}
+\exportsortexpansion{Zdotaccent} {}
+\exportsortexpansion{zdotaccent} {}
+
+\exportsortexpansion{Amacron} {}
+\exportsortexpansion{amacron} {}
+\exportsortexpansion{Emacron} {}
+\exportsortexpansion{emacron} {}
+\exportsortexpansion{Imacron} {}
+\exportsortexpansion{imacron} {}
+\exportsortexpansion{Omacron} {}
+\exportsortexpansion{omacron} {}
+\exportsortexpansion{Umacron} {}
+\exportsortexpansion{umacron} {}
+
+\exportsortexpansion{Ccedilla} {}
+\exportsortexpansion{ccedilla} {}
+\exportsortexpansion{Kcedilla} {}
+\exportsortexpansion{kcedilla} {}
+\exportsortexpansion{Lcedilla} {}
+\exportsortexpansion{lcedilla} {}
+\exportsortexpansion{Ncedilla} {}
+\exportsortexpansion{ncedilla} {}
+\exportsortexpansion{Rcedilla} {}
+\exportsortexpansion{rcedilla} {}
+\exportsortexpansion{Scedilla} {}
+\exportsortexpansion{scedilla} {}
+\exportsortexpansion{Tcedilla} {}
+\exportsortexpansion{tcedilla} {}
+
+\exportsortexpansion{Ohungarumlaut} {}
+\exportsortexpansion{ohungarumlaut} {}
+\exportsortexpansion{Uhungarumlaut} {}
+\exportsortexpansion{uhungarumlaut} {}
+
+\exportsortexpansion{Aogonek} {}
+\exportsortexpansion{aogonek} {}
+\exportsortexpansion{Eogonek} {}
+\exportsortexpansion{eogonek} {}
+\exportsortexpansion{Iogonek} {}
+\exportsortexpansion{iogonek} {}
+\exportsortexpansion{Uogonek} {}
+\exportsortexpansion{uogonek} {}
+
+\exportsortexpansion{Aring} {}
+\exportsortexpansion{aring} {}
+\exportsortexpansion{Uring} {}
+\exportsortexpansion{uring} {}
+
+\exportsortexpansion{Abreve} {}
+\exportsortexpansion{abreve} {}
+\exportsortexpansion{Ebreve} {}
+\exportsortexpansion{ebreve} {}
+\exportsortexpansion{Gbreve} {}
+\exportsortexpansion{gbreve} {}
+\exportsortexpansion{Ibreve} {}
+\exportsortexpansion{ibreve} {}
+\exportsortexpansion{Obreve} {}
+\exportsortexpansion{obreve} {}
+\exportsortexpansion{Ubreve} {}
+\exportsortexpansion{ubreve} {}
+
+\exportsortexpansion{Ccaron} {}
+\exportsortexpansion{ccaron} {}
+\exportsortexpansion{Dcaron} {}
+\exportsortexpansion{dcaron} {}
+\exportsortexpansion{Ecaron} {}
+\exportsortexpansion{ecaron} {}
+\exportsortexpansion{Lcaron} {}
+\exportsortexpansion{lcaron} {}
+\exportsortexpansion{Ncaron} {}
+\exportsortexpansion{ncaron} {}
+\exportsortexpansion{Rcaron} {}
+\exportsortexpansion{rcaron} {}
+\exportsortexpansion{Scaron} {}
+\exportsortexpansion{scaron} {}
+\exportsortexpansion{Tcaron} {}
+\exportsortexpansion{tcaron} {}
+\exportsortexpansion{Ycaron} {}
+\exportsortexpansion{ycaron} {}
+\exportsortexpansion{Zcaron} {}
+\exportsortexpansion{zcaron} {}
+
+\exportsortexpansion{Lstroke} {}
+\exportsortexpansion{lstroke} {}
+\exportsortexpansion{Ostroke} {}
+\exportsortexpansion{ostroke} {}
+
+\exportsortexpansion{aumlaut} {}
+\exportsortexpansion{eumlaut} {}
+\exportsortexpansion{iumlaut} {}
+\exportsortexpansion{oumlaut} {}
+\exportsortexpansion{uumlaut} {}
+
+\exportsortexpansion{Aumlaut} {}
+\exportsortexpansion{Eumlaut} {}
+\exportsortexpansion{Iumlaut} {}
+\exportsortexpansion{Oumlaut} {}
+\exportsortexpansion{Uumlaut} {}
+
+\exportsortexpansion{scommaaccent} {}
+\exportsortexpansion{Scommaaccent} {}
+\exportsortexpansion{tcommaaccent} {}
+\exportsortexpansion{Tcommaaccent} {}
+
+\exportsortexpansion{Etilde} {}
+\exportsortexpansion{etilde} {}
+
+\exportsortexpansion{Ahook} {}
+\exportsortexpansion{ahook} {}
+\exportsortexpansion{Ehook} {}
+\exportsortexpansion{ehook} {}
+\exportsortexpansion{Ihook} {}
+\exportsortexpansion{ihook} {}
+\exportsortexpansion{Ohook} {}
+\exportsortexpansion{ohook} {}
+\exportsortexpansion{Uhook} {}
+\exportsortexpansion{uhook} {}
+\exportsortexpansion{Yhook} {}
+\exportsortexpansion{yhook} {}
+
+\exportsortexpansion{Acircumflexgrave} {}
+\exportsortexpansion{Acircumflexacute} {}
+\exportsortexpansion{Acircumflextilde} {}
+\exportsortexpansion{Acircumflexhook} {}
+\exportsortexpansion{acircumflexgrave} {}
+\exportsortexpansion{acircumflexacute} {}
+\exportsortexpansion{acircumflextilde} {}
+\exportsortexpansion{acircumflexhook} {}
+\exportsortexpansion{Ecircumflexgrave} {}
+\exportsortexpansion{Ecircumflexacute} {}
+\exportsortexpansion{Ecircumflextilde} {}
+\exportsortexpansion{Ecircumflexhook} {}
+\exportsortexpansion{ecircumflexgrave} {}
+\exportsortexpansion{ecircumflexacute} {}
+\exportsortexpansion{ecircumflextilde} {}
+\exportsortexpansion{ecircumflexhook} {}
+\exportsortexpansion{Ocircumflexgrave} {}
+\exportsortexpansion{Ocircumflexacute} {}
+\exportsortexpansion{Ocircumflextilde} {}
+\exportsortexpansion{Ocircumflexhook} {}
+\exportsortexpansion{ocircumflexgrave} {}
+\exportsortexpansion{ocircumflexacute} {}
+\exportsortexpansion{ocircumflextilde} {}
+\exportsortexpansion{ocircumflexhook} {}
+
+\exportsortexpansion{Abrevegrave} {}
+\exportsortexpansion{Abreveacute} {}
+\exportsortexpansion{Abrevetilde} {}
+\exportsortexpansion{Abrevehook} {}
+\exportsortexpansion{abrevegrave} {}
+\exportsortexpansion{abreveacute} {}
+\exportsortexpansion{abrevetilde} {}
+\exportsortexpansion{abrevehook} {}
+
+\exportsortexpansion{Adotbelow} {}
+\exportsortexpansion{adotbelow} {}
+\exportsortexpansion{Edotbelow} {}
+\exportsortexpansion{edotbelow} {}
+\exportsortexpansion{Idotbelow} {}
+\exportsortexpansion{idotbelow} {}
+\exportsortexpansion{Odotbelow} {}
+\exportsortexpansion{odotbelow} {}
+\exportsortexpansion{Udotbelow} {}
+\exportsortexpansion{udotbelow} {}
+\exportsortexpansion{Ydotbelow} {}
+\exportsortexpansion{ydotbelow} {}
+\exportsortexpansion{Ohorndotbelow} {}
+\exportsortexpansion{ohorndotbelow} {}
+\exportsortexpansion{Uhorndotbelow} {}
+\exportsortexpansion{uhorndotbelow} {}
+
+\exportsortexpansion{Acircumflexdotbelow} {}
+\exportsortexpansion{acircumflexdotbelow} {}
+\exportsortexpansion{Ecircumflexdotbelow} {}
+\exportsortexpansion{ecircumflexdotbelow} {}
+\exportsortexpansion{Ocircumflexdotbelow} {}
+\exportsortexpansion{ocircumflexdotbelow} {}
+\exportsortexpansion{Abrevedotbelow} {}
+\exportsortexpansion{abrevedotbelow} {}
+
+\exportsortexpansion{Ohorn} {}
+\exportsortexpansion{Ohorngrave} {}
+\exportsortexpansion{Ohornacute} {}
+\exportsortexpansion{Ohorntilde} {}
+\exportsortexpansion{Ohornhook } {}
+\exportsortexpansion{ohorn} {}
+\exportsortexpansion{ohorngrave} {}
+\exportsortexpansion{ohornacute} {}
+\exportsortexpansion{ohorntilde} {}
+\exportsortexpansion{ohornhook } {}
+\exportsortexpansion{Uhorn} {}
+\exportsortexpansion{Uhorngrave} {}
+\exportsortexpansion{Uhornacute} {}
+\exportsortexpansion{Uhorntilde} {}
+\exportsortexpansion{Uhornhook } {}
+\exportsortexpansion{uhorn} {}
+\exportsortexpansion{uhorngrave} {}
+\exportsortexpansion{uhornacute} {}
+\exportsortexpansion{uhorntilde} {}
+\exportsortexpansion{uhornhook} {}
+
+\exportsortexpansion{eszett} {ssharp}
+\exportsortexpansion{Eszett} {Ssharp}
+
+\exportsortexpansion{lslash} {lstroke}
+\exportsortexpansion{Lslash} {Lstroke}
+\exportsortexpansion{dslash} {dstroke}
+\exportsortexpansion{Dslash} {Dstroke}
+\exportsortexpansion{oslash} {ostroke}
+\exportsortexpansion{Oslash} {Ostroke}
+
+\exportsortexpansion{dcroat} {dstroke}
+\exportsortexpansion{Dcroat} {Dstroke}
+
+% more
+
+\exportsortshortcut{\^ A} {\Acircumflex} \exportsortshortcut{\^ a} {\acircumflex}
+\exportsortshortcut{\^ C} {\Ccircumflex} \exportsortshortcut{\^ c} {\ccircumflex}
+\exportsortshortcut{\^ E} {\Ecircumflex} \exportsortshortcut{\^ e} {\ecircumflex}
+\exportsortshortcut{\^ G} {\Gcircumflex} \exportsortshortcut{\^ g} {\gcircumflex}
+\exportsortshortcut{\^ H} {\Hcircumflex} \exportsortshortcut{\^ h} {\hcircumflex}
+\exportsortshortcut{\^ I} {\Icircumflex} \exportsortshortcut{\^ i} {\icircumflex} \exportsortshortcut{\^\i} {\icircumflex}
+\exportsortshortcut{\^ J} {\Jcircumflex} \exportsortshortcut{\^ j} {\jcircumflex} \exportsortshortcut{\^\j} {\jcircumflex}
+\exportsortshortcut{\^ O} {\Ocircumflex} \exportsortshortcut{\^ o} {\ocircumflex}
+\exportsortshortcut{\^ S} {\Scircumflex} \exportsortshortcut{\^ s} {\scircumflex}
+\exportsortshortcut{\^ U} {\Ucircumflex} \exportsortshortcut{\^ u} {\ucircumflex}
+\exportsortshortcut{\^ W} {\Wcircumflex} \exportsortshortcut{\^ w} {\wcircumflex}
+\exportsortshortcut{\^ Y} {\Ycircumflex} \exportsortshortcut{\^ y} {\ycircumflex}
+
+\exportsortshortcut{\` A} {\Agrave} \exportsortshortcut{\` a} {\agrave}
+\exportsortshortcut{\` E} {\Egrave} \exportsortshortcut{\` e} {\egrave}
+\exportsortshortcut{\` I} {\Igrave} \exportsortshortcut{\` i} {\igrave} \exportsortshortcut{\`\i} {\igrave}
+\exportsortshortcut{\` O} {\Ograve} \exportsortshortcut{\` o} {\ograve}
+\exportsortshortcut{\` U} {\Ugrave} \exportsortshortcut{\` u} {\ugrave}
+\exportsortshortcut{\` Y} {\Ygrave} \exportsortshortcut{\` y} {\ygrave}
+
+\exportsortshortcut{\~ A} {\Atilde} \exportsortshortcut{\~ a} {\atilde}
+\exportsortshortcut{\~ I} {\Itilde} \exportsortshortcut{\~ i} {\itilde} \exportsortshortcut{\~\i} {\itilde}
+\exportsortshortcut{\~ O} {\Otilde} \exportsortshortcut{\~ o} {\otilde}
+\exportsortshortcut{\~ U} {\Utilde} \exportsortshortcut{\~ u} {\utilde}
+
+\exportsortshortcut{\" A} {\Adiaeresis} \exportsortshortcut{\" a} {\adiaeresis}
+\exportsortshortcut{\" E} {\Ediaeresis} \exportsortshortcut{\" e} {\ediaeresis}
+\exportsortshortcut{\" I} {\Idiaeresis} \exportsortshortcut{\" i} {\idiaeresis} \exportsortshortcut{\"\i} {\idiaeresis}
+\exportsortshortcut{\" O} {\Odiaeresis} \exportsortshortcut{\" o} {\odiaeresis}
+\exportsortshortcut{\" U} {\Udiaeresis} \exportsortshortcut{\" u} {\udiaeresis}
+\exportsortshortcut{\" Y} {\Ydiaeresis} \exportsortshortcut{\" y} {\ydiaeresis}
+
+\exportsortshortcut{\' A} {\Aacute} \exportsortshortcut{\' a} {\aacute}
+\exportsortshortcut{\' C} {\Cacute} \exportsortshortcut{\' c} {\cacute}
+\exportsortshortcut{\' E} {\Eacute} \exportsortshortcut{\' e} {\eacute}
+\exportsortshortcut{\' I} {\Iacute} \exportsortshortcut{\' i} {\iacute} \exportsortshortcut{\'\i} {\iacute}
+\exportsortshortcut{\' L} {\Lacute} \exportsortshortcut{\' l} {\lacute}
+\exportsortshortcut{\' N} {\Nacute} \exportsortshortcut{\' n} {\nacute}
+\exportsortshortcut{\' O} {\Oacute} \exportsortshortcut{\' o} {\oacute}
+\exportsortshortcut{\' R} {\Racute} \exportsortshortcut{\' r} {\racute}
+\exportsortshortcut{\' S} {\Sacute} \exportsortshortcut{\' s} {\sacute}
+\exportsortshortcut{\' U} {\Uacute} \exportsortshortcut{\' u} {\uacute}
+\exportsortshortcut{\' Y} {\Yacute} \exportsortshortcut{\' y} {\yacute}
+\exportsortshortcut{\' Z} {\Zacute} \exportsortshortcut{\' z} {\zacute}
+
+\exportsortshortcut{\. C} {\Cdotaccent} \exportsortshortcut{\. c} {\cdotaccent}
+\exportsortshortcut{\. E} {\Edotaccent} \exportsortshortcut{\. e} {\edotaccent}
+\exportsortshortcut{\. G} {\Gdotaccent} \exportsortshortcut{\. g} {\gdotaccent}
+\exportsortshortcut{\. I} {\Idotaccent} \exportsortshortcut{\. i} {\idotaccent} \exportsortshortcut{\.\i} {\idotaccent}
+\exportsortshortcut{\. Z} {\Zdotaccent} \exportsortshortcut{\. z} {\zdotaccent}
+
+\exportsortshortcut{\= A} {\Amacron} \exportsortshortcut{\= a} {\amacron}
+\exportsortshortcut{\= E} {\Emacron} \exportsortshortcut{\= e} {\emacron}
+\exportsortshortcut{\= I} {\Imacron} \exportsortshortcut{\= i} {\imacron} \exportsortshortcut{\=\i} {\imacron}
+\exportsortshortcut{\= O} {\Omacron} \exportsortshortcut{\= o} {\omacron}
+\exportsortshortcut{\= U} {\Umacron} \exportsortshortcut{\= u} {\umacron}
+
+\exportsortshortcut{\c C} {\Ccedilla} \exportsortshortcut{\c c} {\ccedilla}
+\exportsortshortcut{\c K} {\Kcedilla} \exportsortshortcut{\c k} {\kcedilla}
+\exportsortshortcut{\c L} {\Lcedilla} \exportsortshortcut{\c l} {\lcedilla}
+\exportsortshortcut{\c N} {\Ncedilla} \exportsortshortcut{\c n} {\ncedilla}
+\exportsortshortcut{\c R} {\Rcedilla} \exportsortshortcut{\c r} {\rcedilla}
+\exportsortshortcut{\c S} {\Scedilla} \exportsortshortcut{\c s} {\scedilla}
+\exportsortshortcut{\c T} {\Tcedilla} \exportsortshortcut{\c t} {\tcedilla}
+
+\exportsortshortcut{\H O} {\Ohungarumlaut} \exportsortshortcut{\H o} {\ohungarumlaut}
+\exportsortshortcut{\H u} {\uhungarumlaut} \exportsortshortcut{\H U} {\Uhungarumlaut}
+
+\exportsortshortcut{\k A} {\Aogonek} \exportsortshortcut{\k a} {\aogonek}
+\exportsortshortcut{\k E} {\Eogonek} \exportsortshortcut{\k e} {\eogonek}
+\exportsortshortcut{\k I} {\Iogonek} \exportsortshortcut{\k i} {\iogonek}
+\exportsortshortcut{\k U} {\Uogonek} \exportsortshortcut{\k u} {\uogonek}
+
+\exportsortshortcut{\r A} {\Aring} \exportsortshortcut{\r a} {\aring}
+\exportsortshortcut{\r U} {\Uring} \exportsortshortcut{\r u} {\uring}
+
+\exportsortshortcut{\u A} {\Abreve} \exportsortshortcut{\u a} {\abreve}
+\exportsortshortcut{\u E} {\Ebreve} \exportsortshortcut{\u e} {\ebreve}
+\exportsortshortcut{\u G} {\Gbreve} \exportsortshortcut{\u g} {\gbreve}
+\exportsortshortcut{\u I} {\Ibreve} \exportsortshortcut{\u i} {\ibreve} \exportsortshortcut{\u\i} {\ibreve}
+\exportsortshortcut{\u O} {\Obreve} \exportsortshortcut{\u o} {\obreve}
+\exportsortshortcut{\u U} {\Ubreve} \exportsortshortcut{\u u} {\ubreve}
+
+\exportsortshortcut{\v C} {\Ccaron} \exportsortshortcut{\v c} {\ccaron}
+\exportsortshortcut{\v D} {\Dcaron} \exportsortshortcut{\v d} {\dcaron}
+\exportsortshortcut{\v E} {\Ecaron} \exportsortshortcut{\v e} {\ecaron}
+\exportsortshortcut{\v L} {\Lcaron} \exportsortshortcut{\v l} {\lcaron}
+\exportsortshortcut{\v N} {\Ncaron} \exportsortshortcut{\v n} {\ncaron}
+\exportsortshortcut{\v R} {\Rcaron} \exportsortshortcut{\v r} {\rcaron}
+\exportsortshortcut{\v S} {\Scaron} \exportsortshortcut{\v s} {\scaron}
+\exportsortshortcut{\v T} {\Tcaron} \exportsortshortcut{\v t} {\tcaron}
+\exportsortshortcut{\v Z} {\Zcaron} \exportsortshortcut{\v z} {\zcaron}
\endinput
diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua
index 3e367173d..b75950860 100644
--- a/tex/context/base/sort-ini.lua
+++ b/tex/context/base/sort-ini.lua
@@ -1,8 +1,10 @@
--- filename : sort-ini.lua
--- comment : companion to sort-ini.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['sort-ini'] = {
+ version = 1.001,
+ comment = "companion to sort-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-- todo:
--
@@ -11,7 +13,9 @@
-- texutil compatible
-- always expand to utf
-if not versions then versions = { } end versions['sort-ini'] = 1.001
+local utf = unicode.utf8
+local gsub = string.gsub
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
sorters = { }
sorters.comparers = { }
@@ -21,8 +25,7 @@ sorters.mappings = { }
sorters.replacements = { }
sorters.language = 'en'
-function sorters.comparers.basic(a,b,i) -- [2] has entry, key, cmp
- local sort_a, sort_b = a[2][i][3], b[2][i][3]
+function sorters.comparers.basic(sort_a,sort_b)
if #sort_a > #sort_b then
if #sort_b == 0 then
return 1
@@ -62,67 +65,35 @@ function sorters.comparers.basic(a,b,i) -- [2] has entry, key, cmp
return -1
end
end
- sort_a, sort_b = a[2][i][2], b[2][i][2]
- if sort_a == "" then sort_a = a[2][i][1] end
- if sort_b == "" then sort_b = b[2][i][1] end
- if sort_a < sort_b then
- return -1
- elseif sort_a > sort_b then
- return 1
- else
- return 0
- end
- end
-end
-
-function sorters.prepare(data,split,n)
- local strip = sorters.strip
- for k,v in ipairs(data) do
- for i=1,n do
- local vv = v[2][i]
- if vv then
- if vv[2] then
- if vv[2] ~= "" then
- vv[3] = split(strip(vv[2]))
- else
- vv[3] = split(strip(vv[1]))
- end
- else
- vv[2] = { }
- vv[3] = split(strip(vv[1]))
- end
- else
- v[2][i] = { {}, {}, {} }
- end
- end
+ return 0
end
end
function sorters.strip(str) -- todo: only letters and such utf.gsub("([^%w%d])","")
- str = str:gsub("\\%S*","")
- str = str:gsub("[%s%[%](){}%$\"\']*","")
- str = str:gsub("(%d+)",function(s) return (" "):rep(10-#s) .. s end) -- sort numbers properly
+ str = gsub(str,"\\%S*","")
+ str = gsub(str,"[%s%[%](){}%$\"\']*","")
+ str = gsub(str,"(%d+)",function(s) return (" "):rep(10-#s) .. s end) -- sort numbers properly
return str
end
sorters.defaultlanguage = 'en'
-function sorters.splitters.utf(str)
+function sorters.splitters.utf(str) -- brrr, todo: language
local r = sorters.replacements[sorters.language] or sorters.replacements[sorters.defaultlanguage] or { }
local m = sorters.mappings [sorters.language] or sorters.mappings [sorters.defaultlanguage] or { }
local u = characters.uncompose
local b = utf.byte
local t = { }
- for _,v in pairs(r) do
- str = str:gsub(v[1],v[2])
+ for _,v in next, r do
+ str = gsub(str,v[1],v[2])
end
- for c in str:utfcharacters() do
+ for c in utfcharacters(str) do
if m[c] then
t[#t+1] = m[c]
elseif #c == 1 then
t[#t+1] = b(c)
else
- for cc in string.characters(u(c)) do
+ for cc in string.characters(u(c)) do -- utf ?
t[#t+1] = m[cc] or b(cc)
end
end
@@ -130,52 +101,30 @@ function sorters.splitters.utf(str)
return t
end
-function sorters.sort(data,cmp)
- table.sort(data,function(a,b) return cmp(a,b) == -1 end)
+function sorters.sort(entries,cmp)
+ table.sort(entries,function(a,b) return cmp(a,b) == -1 end)
end
-function sorters.cleanup(data)
- for k,v in ipairs(data) do
- for kk,vv in ipairs(v[2]) do
- if vv and #vv[1] == 0 then
- v[1][kk] = nil
- else
- vv[3] = nil
- end
- end
- for kk,vv in pairs(v) do
- if vv == "" then
- v[kk] = nil
- end
- end
- end
-end
+-- temp workaround (is gone)
-function sorters.unique(data)
- local prev, last = nil, 0
- for _,v in ipairs(data) do
- if not prev or not table.are_equal(prev,v,2,3) then -- check range
- last = last + 1
- data[last] = v
- prev = v
- end
- end
- for i=last+1,#data do
- data[i] = nil
- end
+function sorters.process()
+ -- gone
end
-function sorters.process(kind,data)
- if data.entries then
- if not data.sorted then
- sorters.language = data.language or sorters.language
- sorters[kind].prepare(data.entries)
- sorters[kind].sort(data.entries)
- sorters[kind].unique(data.entries)
- data.sorted = true
- end
- return sorters[kind].flush(sorters[kind].finalize(data.entries),data.class,data.flush)
- else
- return { }
- end
-end
+-- was:
+
+--~ function sorters.process(kind,data)
+--~ if data.entries then
+--~ if not data.sorted then
+--~ sorters.language = data.language or sorters.language
+--~ sorters[kind].prepare(data.entries)
+--~ sorters[kind].sort(data.entries)
+--~ sorters[kind].unique(data.entries)
+--~ data.sorted = true
+--~ end
+--~ return sorters[kind].flush(sorters[kind].finalize(data.entries),data.class,data.flush)
+--~ else
+--~ return { }
+--~ end
+--~ end
+
diff --git a/tex/context/base/sort-ini.mkii b/tex/context/base/sort-ini.mkii
index 1a8a5a543..f26f4febe 100644
--- a/tex/context/base/sort-ini.mkii
+++ b/tex/context/base/sort-ini.mkii
@@ -1,7 +1,7 @@
%D \module
%D [ file=sort-ini,
%D version=2005.08.08,
-%D title=\CONTEXT\ Sort Macros,
+%D title=\CONTEXT\ Sorting Macros,
%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -17,6 +17,12 @@
%D used with the new texutil functionality. This module defines a few
%D auxiliary macros.
+\writestatus{loading}{ConTeXt Sorting Macros / Initialization}
+
+%D This module replaces existing sort key handling and is meant to be
+%D used with the new texutil functionality. This module defines a few
+%D auxiliary macros.
+
\ifx\exportsortaction\undefined \else \endinput \fi
%D The sorting method is largely bases on the one used in the old version
@@ -72,6 +78,14 @@
\unprotect
+\def\savesortkeys
+ {\ifproductionrun
+ \the\everysavesortkeys
+ \global\everysavesortkeys\emptytoks
+ \fi}
+
+\appendtoks \savesortkeys \to \everyshipout
+
\let\currentexportclass\empty
\def\exportsortaction#1#2#3%
diff --git a/tex/context/base/sort-ini.mkiv b/tex/context/base/sort-ini.mkiv
index 9c87edb11..a4dc2f6ba 100644
--- a/tex/context/base/sort-ini.mkiv
+++ b/tex/context/base/sort-ini.mkiv
@@ -11,11 +11,9 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\registerctxluafile{sort-ini}{1.001}
-
-\let\savesortlanguage\gobbleoneargument
+\writestatus{loading}{ConTeXt Sorting Macros / Initialization}
-\readfile{sort-def.tex}{}{} % runtime loaded in mkii
-\readfile{sort-lan.tex}{}{} % runtime loaded in mkii
+\registerctxluafile{sort-ini}{1.001}
+\registerctxluafile{sort-lan}{1.001}
\endinput
diff --git a/tex/context/base/sort-ini.tex b/tex/context/base/sort-ini.tex
deleted file mode 100644
index 2baa609fb..000000000
--- a/tex/context/base/sort-ini.tex
+++ /dev/null
@@ -1,32 +0,0 @@
-%D \module
-%D [ file=sort-ini,
-%D version=2005.08.08,
-%D title=\CONTEXT\ Sort Macros,
-%D subtitle=Initialization,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 replaces existing sort key handling and is meant to be
-%D used with the new texutil functionality. This module defines a few
-%D auxiliary macros.
-
-\writestatus{loading}{Context Sorting Macros (ini)}
-
-\newevery \everysavesortkeys \relax
-
-\def\savesortkeys
- {\ifproductionrun
- \the\everysavesortkeys
- \global\everysavesortkeys\emptytoks
- \fi}
-
-\appendtoks \savesortkeys \to \everyshipout
-
-\loadmarkfile{sort-ini}
-
-\endinput
diff --git a/tex/context/base/sort-lan.lua b/tex/context/base/sort-lan.lua
index 8d8fdb1a0..394cbabe1 100644
--- a/tex/context/base/sort-lan.lua
+++ b/tex/context/base/sort-lan.lua
@@ -1,10 +1,12 @@
--- filename : sort-lan.lua
--- comment : companion to sort-lan.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['sort-lan'] = {
+ version = 1.001,
+ comment = "companion to sort-lan.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['sort-lan'] = 1.001
+local utf = unicode.utf8
-- this is a rather preliminary and incomplete file
-- maybe we should load this kind of stuff runtime
@@ -51,9 +53,8 @@ sorters.mappings ['nl'] = sorters.mappings['en']
-- czech
-
-local uc = unicode.utf8.char
-local ub = unicode.utf8.byte
+local uc = utf.char
+local ub = utf.byte
sorters.replacements['cz'] = {
[1] = { "ch", uc(0xFF01) }
diff --git a/tex/context/base/sort-lan.mkii b/tex/context/base/sort-lan.mkii
deleted file mode 100644
index ad5232b02..000000000
--- a/tex/context/base/sort-lan.mkii
+++ /dev/null
@@ -1,203 +0,0 @@
-%D \module
-%D [ file=sort-lan,
-%D version=2005.08.08,
-%D title=\CONTEXT\ Sort Macros,
-%D subtitle=Language Definitions,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% for testing:
-
-\startmode[sortorder-en]
- \exportsortexpansion{aacute}{a+1}
- \exportsortexpansion{Aacute}{A+2}
- \exportsortexpansion{agrave}{a+1}
- \exportsortexpansion{Agrave}{A+2}
-\stopmode
-
-%D This module replaces existing sort key handling and is meant to be
-%D used with the new texutil functionality. Here we define the language
-%D specific sort rules.
-
-% slovenian
-%
-% a-c, ccaron, cacute, d, dstroke, e-s, scaron, t-z, zcaron
-
-% \enableregime[utf]
-% \mainlanguage[sl]
-% \starttext
-% \ccaron\index{\ccaron\space 1}
-% \Ccaron\index{\Ccaron\space 1}
-% č\index{č 2}
-% Č\index{Č 2}
-% \v c\index{\v c 3}
-% \v C\index{\v C 3}
-% \placeindex
-% \stoptext
-
-% \startmode[sortorder-sl]
-% \exportsortexpansion {ccaron} {cz}
-% \exportsortexpansion {cacute} {czz}
-% \exportsortexpansion {dstroke} {dz}
-% \exportsortexpansion {scaron} {sz}
-% \exportsortexpansion {zacron} {zz}
-
-% \exportsortdivision {cz} {ccaron}
-% \exportsortdivision {czz} {cacute}
-% \exportsortdivision {dz} {dstroke}
-% \exportsortdivision {sz} {scaron}
-% \exportsortdivision {zz} {zacron}
-% \stopmode
-%
-% \startmode[sortorder-sl]
-% \exportsortexpansion {ccaron} {c+1}
-% \exportsortexpansion {cacute} {c+2}
-% \exportsortexpansion {dstroke} {d+1}
-% \exportsortexpansion {scaron} {s+1}
-% \exportsortexpansion {zacron} {z+1}
-%
-% \exportsortdivision {c+1} {ccaron}
-% \exportsortdivision {c+2} {cacute}
-% \exportsortdivision {d+1} {dstroke}
-% \exportsortdivision {s+1} {scaron}
-% \exportsortdivision {z+1} {zacron}
-% \stopmode
-
-\startmode[sortorder-sl]
- \exportsortrule {ccaron} {c+1}
- \exportsortrule {cacute} {c+2}
- \exportsortrule {dstroke} {d+1}
- \exportsortrule {scaron} {s+1}
- \exportsortrule {zacron} {z+1}
-\stopmode
-
-% finnish
-%
-% a-u, v+w sorted together, x-z, aring, adiaeresis, odiaeresis
-
-\startmode[sortorder-fi]
- \exportsortrule {v} {w}
- \exportsortrule {aring} {z+1}
- \exportsortrule {adiaeresis} {z+2}
- \exportsortrule {odiaeresis} {z+3}
-\stopmode
-
-% swedish
-%
-% a-z, aring, adiaeresis, odiaeresis
-
-% \mainlanguage[sv]
-% \starttext
-% a\index{a}
-% a\index{a}
-% z\index{z}
-% z\index{z}
-% q\index{q}
-% q\index{q}
-% \index{}
-% \index{}
-% \index{}
-% \index{}
-% \index{}
-% \index{}
-% \index{}
-% \index{}
-% \index{}
-% \aring\index{\aring}
-% \adiaeresis\index{\adiaeresis}
-% \odiaeresis\index{\odiaeresis}
-% A\index{A}
-% \index{}
-% \index{}
-% \index{}
-% \Aring\index{\Aring}
-% \Adiaeresis\index{\Adiaeresis}
-% \Odiaeresis\index{\Odiaeresis}
-% \placeindex
-% \stoptext
-
-\startmode[sortorder-sv]
- \exportsortrule {aring} {z+1}
- \exportsortrule {adiaeresis} {z+2}
- \exportsortrule {odiaeresis} {z+3}
-\stopmode
-
-% norwegian, danish
-%
-% a-z, aeligature, oslash, aring
-
-\startmode[sortorder-no,sortorder-da]
- \exportsortrule {aeligature} {z+1}
- \exportsortrule {oslash} {z+2}
- \exportsortrule {aring} {z+3}
-\stopmode
-
-% islandic
-%
-% a, aacute, b, c, d, eth, e, eacute, f-i, iacute, j-o, oacute, p-u, uacute, v, w (?), x, y, yacute, z, aeligature, oslash, thorn
-
-% estonian
-%
-% a-s, scaron, z, zcaron, t-w, otilde, adiaeresis, odiaeresis, udiaeresis, x, y
-
-% czech
-%
-% a) make a single group for: "a", "", "A", ""
-% b) make a different two groups for: "c", "C" and "c", "C"
-% c) sorting rule: "A" < "" < "a" < "" < "C" < "c" < "C" < "c"
-% d) sorting rule: "h" < "ch" < "i" ("c" < "h")
-
-\gdef\czsortdivisionch{ch}
-\gdef\czsortdivisionCh{Ch}
-
-\startmode[sortorder-cz]
- \exportsortexpansion {aacute} {a+1}
- \exportsortexpansion {Aacute} {A+1}
- \exportsortexpansion {ccaron} {c+1}
- \exportsortexpansion {Ccaron} {C+1}
- \exportsortdivision {c+1} {ccaron}
- \exportsortexpansion {dcaron} {d+1}
- \exportsortexpansion {Dcaron} {D+1}
- \exportsortdivision {d+1} {dcaron}
- \exportsortexpansion {eacute} {e+1}
- \exportsortexpansion {Eacute} {E+1}
- \exportsortexpansion {ecaron} {e+2}
- \exportsortexpansion {Ecaron} {E+2}
- \exportsortreduction {ch} {h+1}
- \exportsortexpansion {ch} {h+1}
- \exportsortreduction {Ch} {H+1}
- \exportsortexpansion {Ch} {H+1}
- \exportsortdivision {h+1} {czsortdivisionch}
- \exportsortexpansion {iacute} {i+1}
- \exportsortexpansion {Iacute} {I+1}
- \exportsortexpansion {ncaron} {n+1}
- \exportsortexpansion {Ncaron} {N+1}
- \exportsortdivision {n+1} {ncaron}
- \exportsortexpansion {oacute} {o+1}
- \exportsortexpansion {Oacute} {O+1}
- \exportsortexpansion {rcaron} {r+1}
- \exportsortexpansion {Rcaron} {R+1}
- \exportsortdivision {r+1} {rcaron}
- \exportsortexpansion {scaron} {s+1}
- \exportsortexpansion {Scaron} {S+1}
- \exportsortdivision {s+1} {scaron}
- \exportsortexpansion {tcaron} {t+1}
- \exportsortexpansion {Tcaron} {T+1}
- \exportsortdivision {t+1} {tcaron}
- \exportsortexpansion {uacute} {u+1}
- \exportsortexpansion {Uacute} {U+1}
- \exportsortexpansion {uring} {u+2}
- \exportsortexpansion {Uring} {U+2}
- \exportsortexpansion {yacute} {y+1}
- \exportsortexpansion {Yacute} {Y+1}
- \exportsortexpansion {zcaron} {z+1}
- \exportsortexpansion {Zcaron} {Z+1}
- \exportsortdivision {z+1} {zcaron}
-\stopmode
-
-\endinput
diff --git a/tex/context/base/sort-lan.mkiv b/tex/context/base/sort-lan.mkiv
deleted file mode 100644
index 918f7f9b7..000000000
--- a/tex/context/base/sort-lan.mkiv
+++ /dev/null
@@ -1,16 +0,0 @@
-%D \module
-%D [ file=sort-lan,
-%D version=2005.08.08,
-%D title=\CONTEXT\ Sort Macros,
-%D subtitle=Language Definitions,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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{sort-lan}{1.001}
-
-\endinput
diff --git a/tex/context/base/sort-lan.tex b/tex/context/base/sort-lan.tex
index 1eadae407..ad5232b02 100644
--- a/tex/context/base/sort-lan.tex
+++ b/tex/context/base/sort-lan.tex
@@ -11,8 +11,193 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Sorting Macros (languages)}
+% for testing:
-\loadmarkfile{sort-lan}
+\startmode[sortorder-en]
+ \exportsortexpansion{aacute}{a+1}
+ \exportsortexpansion{Aacute}{A+2}
+ \exportsortexpansion{agrave}{a+1}
+ \exportsortexpansion{Agrave}{A+2}
+\stopmode
+
+%D This module replaces existing sort key handling and is meant to be
+%D used with the new texutil functionality. Here we define the language
+%D specific sort rules.
+
+% slovenian
+%
+% a-c, ccaron, cacute, d, dstroke, e-s, scaron, t-z, zcaron
+
+% \enableregime[utf]
+% \mainlanguage[sl]
+% \starttext
+% \ccaron\index{\ccaron\space 1}
+% \Ccaron\index{\Ccaron\space 1}
+% č\index{č 2}
+% Č\index{Č 2}
+% \v c\index{\v c 3}
+% \v C\index{\v C 3}
+% \placeindex
+% \stoptext
+
+% \startmode[sortorder-sl]
+% \exportsortexpansion {ccaron} {cz}
+% \exportsortexpansion {cacute} {czz}
+% \exportsortexpansion {dstroke} {dz}
+% \exportsortexpansion {scaron} {sz}
+% \exportsortexpansion {zacron} {zz}
+
+% \exportsortdivision {cz} {ccaron}
+% \exportsortdivision {czz} {cacute}
+% \exportsortdivision {dz} {dstroke}
+% \exportsortdivision {sz} {scaron}
+% \exportsortdivision {zz} {zacron}
+% \stopmode
+%
+% \startmode[sortorder-sl]
+% \exportsortexpansion {ccaron} {c+1}
+% \exportsortexpansion {cacute} {c+2}
+% \exportsortexpansion {dstroke} {d+1}
+% \exportsortexpansion {scaron} {s+1}
+% \exportsortexpansion {zacron} {z+1}
+%
+% \exportsortdivision {c+1} {ccaron}
+% \exportsortdivision {c+2} {cacute}
+% \exportsortdivision {d+1} {dstroke}
+% \exportsortdivision {s+1} {scaron}
+% \exportsortdivision {z+1} {zacron}
+% \stopmode
+
+\startmode[sortorder-sl]
+ \exportsortrule {ccaron} {c+1}
+ \exportsortrule {cacute} {c+2}
+ \exportsortrule {dstroke} {d+1}
+ \exportsortrule {scaron} {s+1}
+ \exportsortrule {zacron} {z+1}
+\stopmode
+
+% finnish
+%
+% a-u, v+w sorted together, x-z, aring, adiaeresis, odiaeresis
+
+\startmode[sortorder-fi]
+ \exportsortrule {v} {w}
+ \exportsortrule {aring} {z+1}
+ \exportsortrule {adiaeresis} {z+2}
+ \exportsortrule {odiaeresis} {z+3}
+\stopmode
+
+% swedish
+%
+% a-z, aring, adiaeresis, odiaeresis
+
+% \mainlanguage[sv]
+% \starttext
+% a\index{a}
+% a\index{a}
+% z\index{z}
+% z\index{z}
+% q\index{q}
+% q\index{q}
+% \index{}
+% \index{}
+% \index{}
+% \index{}
+% \index{}
+% \index{}
+% \index{}
+% \index{}
+% \index{}
+% \aring\index{\aring}
+% \adiaeresis\index{\adiaeresis}
+% \odiaeresis\index{\odiaeresis}
+% A\index{A}
+% \index{}
+% \index{}
+% \index{}
+% \Aring\index{\Aring}
+% \Adiaeresis\index{\Adiaeresis}
+% \Odiaeresis\index{\Odiaeresis}
+% \placeindex
+% \stoptext
+
+\startmode[sortorder-sv]
+ \exportsortrule {aring} {z+1}
+ \exportsortrule {adiaeresis} {z+2}
+ \exportsortrule {odiaeresis} {z+3}
+\stopmode
+
+% norwegian, danish
+%
+% a-z, aeligature, oslash, aring
+
+\startmode[sortorder-no,sortorder-da]
+ \exportsortrule {aeligature} {z+1}
+ \exportsortrule {oslash} {z+2}
+ \exportsortrule {aring} {z+3}
+\stopmode
+
+% islandic
+%
+% a, aacute, b, c, d, eth, e, eacute, f-i, iacute, j-o, oacute, p-u, uacute, v, w (?), x, y, yacute, z, aeligature, oslash, thorn
+
+% estonian
+%
+% a-s, scaron, z, zcaron, t-w, otilde, adiaeresis, odiaeresis, udiaeresis, x, y
+
+% czech
+%
+% a) make a single group for: "a", "", "A", ""
+% b) make a different two groups for: "c", "C" and "c", "C"
+% c) sorting rule: "A" < "" < "a" < "" < "C" < "c" < "C" < "c"
+% d) sorting rule: "h" < "ch" < "i" ("c" < "h")
+
+\gdef\czsortdivisionch{ch}
+\gdef\czsortdivisionCh{Ch}
+
+\startmode[sortorder-cz]
+ \exportsortexpansion {aacute} {a+1}
+ \exportsortexpansion {Aacute} {A+1}
+ \exportsortexpansion {ccaron} {c+1}
+ \exportsortexpansion {Ccaron} {C+1}
+ \exportsortdivision {c+1} {ccaron}
+ \exportsortexpansion {dcaron} {d+1}
+ \exportsortexpansion {Dcaron} {D+1}
+ \exportsortdivision {d+1} {dcaron}
+ \exportsortexpansion {eacute} {e+1}
+ \exportsortexpansion {Eacute} {E+1}
+ \exportsortexpansion {ecaron} {e+2}
+ \exportsortexpansion {Ecaron} {E+2}
+ \exportsortreduction {ch} {h+1}
+ \exportsortexpansion {ch} {h+1}
+ \exportsortreduction {Ch} {H+1}
+ \exportsortexpansion {Ch} {H+1}
+ \exportsortdivision {h+1} {czsortdivisionch}
+ \exportsortexpansion {iacute} {i+1}
+ \exportsortexpansion {Iacute} {I+1}
+ \exportsortexpansion {ncaron} {n+1}
+ \exportsortexpansion {Ncaron} {N+1}
+ \exportsortdivision {n+1} {ncaron}
+ \exportsortexpansion {oacute} {o+1}
+ \exportsortexpansion {Oacute} {O+1}
+ \exportsortexpansion {rcaron} {r+1}
+ \exportsortexpansion {Rcaron} {R+1}
+ \exportsortdivision {r+1} {rcaron}
+ \exportsortexpansion {scaron} {s+1}
+ \exportsortexpansion {Scaron} {S+1}
+ \exportsortdivision {s+1} {scaron}
+ \exportsortexpansion {tcaron} {t+1}
+ \exportsortexpansion {Tcaron} {T+1}
+ \exportsortdivision {t+1} {tcaron}
+ \exportsortexpansion {uacute} {u+1}
+ \exportsortexpansion {Uacute} {U+1}
+ \exportsortexpansion {uring} {u+2}
+ \exportsortexpansion {Uring} {U+2}
+ \exportsortexpansion {yacute} {y+1}
+ \exportsortexpansion {Yacute} {Y+1}
+ \exportsortexpansion {zcaron} {z+1}
+ \exportsortexpansion {Zcaron} {Z+1}
+ \exportsortdivision {z+1} {zcaron}
+\stopmode
\endinput
diff --git a/tex/context/base/spec-def.mkii b/tex/context/base/spec-def.mkii
deleted file mode 100644
index a151461c4..000000000
--- a/tex/context/base/spec-def.mkii
+++ /dev/null
@@ -1,20 +0,0 @@
-%D \module
-%D [ file=spec-def,
-%D version=1996.01.25,
-%D title=\CONTEXT\ Special Macros,
-%D subtitle=Definitions,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 empty.
-
-\appendtoks
- \setupoutput[dvips]%
-\to \everydump
-
-\endinput
diff --git a/tex/context/base/spec-def.mkiv b/tex/context/base/spec-def.mkiv
deleted file mode 100644
index eaf20753c..000000000
--- a/tex/context/base/spec-def.mkiv
+++ /dev/null
@@ -1,23 +0,0 @@
-%D \module
-%D [ file=spec-def,
-%D version=2006.09.18,
-%D title=\CONTEXT\ Special Macros,
-%D subtitle=Definitions,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 load the lua scripts here because we don't want to load
-%D them multiple times.
-
-\registerctxluafile{spec-pdf}{1.001}
-
-\appendtoks
- \setupoutput[pdftex]%
-\to \everydump
-
-\endinput
diff --git a/tex/context/base/spec-def.tex b/tex/context/base/spec-def.tex
index 74fac733a..ad1a9bb1d 100644
--- a/tex/context/base/spec-def.tex
+++ b/tex/context/base/spec-def.tex
@@ -14,7 +14,7 @@
%D This module used to be integrated in \type {spec-ini},
%D but testing optimization is more convenient this way.
-\writestatus{loading}{Context Special Macros / Definitions}
+\writestatus{loading}{ConTeXt Special Macros / Definitions}
\unprotect
@@ -1006,11 +1006,11 @@
%D \setupoutput [pdftex]
%D \stoptyping
-\loadmarkfile{spec-def}
-
%D Please let me know if we need more. From now on we default
%D to:
-% \setupoutput [dvips] % see mkii/mkiv files
+\appendtoks
+ \setupoutput[dvips]%
+\to \everydump
\protect \endinput
diff --git a/tex/context/base/spec-dpx.tex b/tex/context/base/spec-dpx.tex
index 0753d173c..ed49ea843 100644
--- a/tex/context/base/spec-dpx.tex
+++ b/tex/context/base/spec-dpx.tex
@@ -84,6 +84,8 @@
%D
%D A simple one.
+\let\PDFpagexyzspec\relax \def\PDFpagexyzspec{@xpos @ypos 0} % untested
+
\definespecial\dosetuppaper#1#2#3%
{\bgroup
\scratchdimen#2\edef\width {\the\scratchdimen\space}%
@@ -733,7 +735,7 @@
{\vbox to \the\ht#2%
{\vss
\hbox to \the\wd#2%
- {\scratchdimen\wd#2\scratchdimen.5\scratchdimen\hskip-\the\scratchdimen
+ {%\scratchdimen\wd#2\scratchdimen.5\scratchdimen\hskip-\the\scratchdimen
\special{pdf:uxobj @MPPDF::\MPPDFobjectcounter}}}}%
\expanded{\doDVIPDFMXstartobject\zerocount{MPPDF}\MPPDFobjectcounter{\the\wd#2}{\the\ht#2}{\the\dp#2}}%
\finalizeobjectbox#2%
diff --git a/tex/context/base/spec-fdf.mkii b/tex/context/base/spec-fdf.mkii
deleted file mode 100644
index 1ada3e880..000000000
--- a/tex/context/base/spec-fdf.mkii
+++ /dev/null
@@ -1,146 +0,0 @@
-%D \module
-%D [ file=spec-fdf,
-%D version=1998.05.18,
-%D title=\CONTEXT\ \PDF\ Macros,
-%D subtitle=Support Macros,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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
-
-\chardef\safePDFcode=`-
-
-\def\setPDFdestination#1%
- {\bgroup
- \retainlccodes
- \lccode`\/\safePDFcode \lccode`\#\safePDFcode
- \lccode`\<\safePDFcode \lccode`\>\safePDFcode
- \lccode`\[\safePDFcode \lccode`\]\safePDFcode
- \lccode`\(\safePDFcode \lccode`\)\safePDFcode
- \ifovercomePDFspace
- \lccode`\ \safePDFcode
- \fi
- \ifovercomePDFbugs
- \xdef\PDFdestination{'#1'}%
- \else
- \xdef\PDFdestination{#1}%
- \fi
- % nicer \xdef\PDFdestination{\ifovercomePDFbugs'\fi#1\ifovercomePDFbugs'\fi}%
- \lowercase\@EA{\@EA\xdef\@EA\PDFdestination\@EA{\PDFdestination}}%
- \egroup}
-
-%D This is much faster since we don't have to set the full
-%D range of lc-codes; about 5 sec on a 1000mhz PIII for
-%D 20K named destinations "x(x) x"). Of course when you use
-%D page destinations, the saving is nil.
-
-% \doifnotmode{atpragma}{\let\next\setPDFdestination} % experimental
-%
-% \catcode`\/=\@@active \catcode`\#=\@@active
-% \catcode`\<=\@@active \catcode`\>=\@@active
-% \catcode`\[=\@@active \catcode`\]=\@@active
-% \catcode`\(=\@@active \catcode`\)=\@@active
-%
-% \gdef\PDFrepchar{-}
-%
-% \gdef\setPDFdcharacters
-% {\catcode`\/=\@@active \let/\PDFrepchar
-% \catcode`\#=\@@active \let#\PDFrepchar
-% \catcode`\<=\@@active \let<\PDFrepchar
-% \catcode`\>=\@@active \let>\PDFrepchar
-% \catcode`\[=\@@active \let[\PDFrepchar
-% \catcode`\]=\@@active \let]\PDFrepchar
-% \catcode`\(=\@@active \let(\PDFrepchar
-% \catcode`\)=\@@active \let)\PDFrepchar}
-%
-% \egroup
-%
-% \def\setPDFdestination#1% expansion is needed, otherwise embedded
-% {\bgroup % macros will not expand under the new
-% \setPDFdcharacters % catcode regime
-% \ifovercomePDFspace
-% \catcode32=\@@ignore
-% \fi
-% \xdef\PDFdestination{\ifovercomePDFbugs'\fi#1\ifovercomePDFbugs'\fi}%
-% \scantokens\@EA{\@EA\xdef\@EA\PDFdestination\@EA{\PDFdestination}}%
-% \egroup}
-%
-% \doifnotmode{atpragma}{\let\setPDFdestination\next} % experimental
-
-%D This is a slow one, that uses \type{\lccode}'s to
-%D change the glyph as well as converts sensisitve ones into a
-%D \PDF\ command sequence, so \type{(} becomes \type{\(}. In
-%D fact we translate the string to lowercase inactive and non
-%D special characters, limit their number and finaly convert
-%D some of the characters to save ones.
-
-\chardef\maxPDFstringsize=60
-
-\def\sanitizePDFstring#1\to#2% bugged
- {\bgroup
- \retainlccodes
- \lccode`( \zerocount \lccode`) \zerocount
- \lccode`< \zerocount \lccode`> \zerocount
- \lccode`[ \zerocount \lccode`] \zerocount
- \lccode`\\\zerocount \lccode`/ \zerocount
- \lowercase{\defconvertedargument\ascii{#1}}%
- % by integrating the split in the loop below
- % \splitofftokens\maxPDFstringsize\from\ascii\to\ascii
- % we diminish the processing time considerably
- \scratchcounter\maxPDFstringsize
- \def\docommand##1%
- {\ifcase\scratchcounter\else
- \advance\scratchcounter \minusone
- \ifcase\lccode`##1\relax
- \xdef#2{#2\expandafter\string\csname##1\endcsname}%
- \else
- \xdef#2{#2##1}%
- \fi
- \fi}%
- %\global\let#2=\empty
- % or to permit #2 to be \ascii too:
- \global\@EA\let\@EA#2\@EA\empty
- \@EA\handletokens\ascii\with\docommand
- \egroup}
-
-% \doifnotmode{atpragma}{\let\next\sanitizePDFstring} % experimental
-%
-% \bgroup
-%
-% \catcode`\.=\@@escape
-%
-% .catcode`./=.@@active
-% .catcode`.<=.@@active .catcode`.>=.@@active
-% .catcode`.[=.@@active .catcode`.]=.@@active
-% .catcode`.(=.@@active .catcode`.)=.@@active
-%
-% .gdef.setPDFscharacters%
-% {.catcode`.\=.@@other
-% .catcode`./=.@@active .def/{.noexpand./}%
-% .catcode`.<=.@@active .def<{.noexpand.<}%
-% .catcode`.>=.@@active .def>{.noexpand.>}%
-% .catcode`.[=.@@active .def[{.noexpand.[}%
-% .catcode`.]=.@@active .def]{.noexpand.]}%
-% .catcode`.(=.@@active .def({.noexpand.(}%
-% .catcode`.)=.@@active .def){.noexpand.)}}
-%
-% .gdef.sanitizePDFstring#1.to#2%
-% {.bgroup
-% .setPDFscharacters
-% .catcode`=.@@escape
-% .edef.next{.strippedcsname#2}%
-% .scantokens{setxvalue{next}{#1}}%
-% .egroup}
-%
-% .egroup
-%
-% \doifnotmode{atpragma}{\let\sanitizePDFstring\next} % experimental
-%
-% There is an unicode variant in spec-tst!
-
-\protect \endinput
diff --git a/tex/context/base/spec-fdf.mkiv b/tex/context/base/spec-fdf.mkiv
deleted file mode 100644
index d6937ec1b..000000000
--- a/tex/context/base/spec-fdf.mkiv
+++ /dev/null
@@ -1,31 +0,0 @@
-%D \module
-%D [ file=spec-fdf,
-%D version=2006.09.18,
-%D title=\CONTEXT\ \PDF\ Macros,
-%D subtitle=Support Macros,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% \setupinteraction[
-% state=start,
-% title={ÀÂÆ ÇÉÈÊË ÎÏÔŒ ÙÜŸ},
-% subtitle={àâæ çéèêë îïôœ ùûüÿ},
-% author={àâæ ÀÂÆ},
-% keyword={àâæ çéèêë îïôœ ùûüÿ}]
-
-\unprotect
-
-\ctxloadluafile{spec-pdf}{}
-
-\PDFunicodetrue \let\enablePDFdocencoding\PDFunicodetrue
-
-\def\setPDFdestination #1{\xdef\PDFdestination{\ctxlua{pdf.cleandestination("\luaescapestring{#1}")}}}
-\def\sanitizePDFencoding#1\to#2{\xdef#2{\ctxlua{pdf.hexify("\luaescapestring{#1}")}}}
-\def\hexifiedPDFstring #1{\ctxlua{pdf.hexify("\luaescapestring{#1}")}}
-
-\protect \endinput
diff --git a/tex/context/base/spec-fdf.tex b/tex/context/base/spec-fdf.tex
index ff801c95f..da29a5b38 100644
--- a/tex/context/base/spec-fdf.tex
+++ b/tex/context/base/spec-fdf.tex
@@ -337,11 +337,14 @@
\def\flushPDFwhateverbox#1#2%
{\doifsomething{#1}{\doPDFpageattribute{/#2Box #1}}}
+\def\flushPDFpageboxes
+ {\flushPDFwhateverbox\currentPDFartbox {Art}%
+ \flushPDFwhateverbox\currentPDFcropbox {Crop}%
+ \flushPDFwhateverbox\currentPDFbleedbox{Bleed}%
+ \flushPDFwhateverbox\currentPDFtrimbox {Trim}}
+
\appendtoksonce
- \flushPDFwhateverbox\currentPDFartbox {Art}%
- \flushPDFwhateverbox\currentPDFcropbox {Crop}%
- \flushPDFwhateverbox\currentPDFbleedbox{Bleed}%
- \flushPDFwhateverbox\currentPDFtrimbox {Trim}%
+ \flushPDFpageboxes
\to \everyshipout
\def\doPDFsetupidentity#1#2#3#4#5#6%
@@ -470,8 +473,6 @@
\def\doPDFstartthisislocation#1%
{\bgroup
\setPDFdestination{#1}%
- %\doifsomething{\PDFdestination}
- % {\doPDFdestination{\PDFdestination}}%
\ifx\PDFdestination\empty \else
\doPDFdestination{\PDFdestination}%
\fi
@@ -701,9 +702,14 @@
\def\doPDFstartexecutecommand#1#2#3#4%
{\doifdefined{PDFexecute#3}
{\bgroup
- \@EA\dogetcommalistelement\@EA1\@EA\from#4\to\argumentA
- \@EA\dogetcommalistelement\@EA2\@EA\from#4\to\argumentB
\edef\argument{#4}%
+ \ifx\argument\empty
+ \let\argumentA\empty
+ \let\argumentB\empty
+ \else
+ \@EA\dogetcommalistelement\@EA1\@EA\from#4\to\argumentA
+ \@EA\dogetcommalistelement\@EA2\@EA\from#4\to\argumentB
+ \fi
\edef\action%
{/S \getvalue{PDFexecute#3}}%
\ifsecondaryreference
@@ -1653,7 +1659,7 @@
\def\PDFpageviewkey{fit}
\def\PDFpageviewwrd{/Fit}
\def\PDFpageview {/View [\PDFpageviewwrd] }
-\def\PDFpagexyzspec{0 0 0} % hack, pdftex does handle this
+\let\PDFpagexyzspec\relax % 0 0 0 hack, pdftex does handle this, for dvipdfmx we need height
\def\dosetuppageview#1% watch the v-h swapping here
{\processaction
@@ -1663,9 +1669,16 @@
\v!height=>\def\PDFpageviewkey {fitv}\def\PDFpageviewwrd{/FitV},
\v!minwidth=>\def\PDFpageviewkey{fitbh}\def\PDFpageviewwrd{/FitBH},
\v!minheight=>\def\PDFpageviewkey{fitbv}\def\PDFpageviewwrd{/FitBV},
- \v!standard=>\def\PDFpageviewkey{xyz \PDFpagexyzspec}\def\PDFpageviewwrd{/XYZ \PDFpagexyzspec},
+ \v!standard=>\ifx\PDFpagexyzspec\relax
+ % empty does not work too wel with dpx
+ \def\PDFpageviewkey{fit}%
+ \def\PDFpageviewwrd{/Fit}%
+ \else
+ \edef\PDFpageviewkey{xyz \PDFpagexyzspec}%
+ \edef\PDFpageviewwrd{/XYZ \PDFpagexyzspec}%
+ \fi,
\s!unknown=>\def\PDFpageviewkey {fit}\def\PDFpageviewwrd{/Fit}]%
- \edef\PDFpageview{/View [\PDFpageviewwrd]}}
+ \edef\PDFpageview{\ifx\PDFpageviewwrd\empty\else/View [\PDFpageviewwrd]\fi}}
%D \macros
%D {setFDFkids}
@@ -2148,7 +2161,6 @@
% we can (in etex) share more by testing on this
\def\savesecondaryPDFreference#1%
- %{\setxvalue{PDF-SR:\the\nofsecondaryreferences}{#1}}
{\@EA\xdef\csname PDF-SR:\the\nofsecondaryreferences\endcsname{#1}}
\def\savesecondaryPDFreference % #1 == \action
@@ -2350,7 +2362,7 @@
%D A bit out of place, but useful:
-\newevery\everysetfield\relax
+\ifdefined\everysetfield \else \newtoks\everysetfield \fi
\appendtoksonce
\enablePDFdocencoding
@@ -2574,7 +2586,8 @@
\PointsToBigPoints{\dimen2}#3}
\def\doPDFovalbox#1#2#3#4#5#6#7#8% todo: \scratchdimen/\scatchbox
- {\bgroup
+ {\forcecolorhack
+ \bgroup
\dimen0=#4\divide\dimen0 \plustwo
\doPDFovalcalc{0pt}{+\dimen0}\xmin
\doPDFovalcalc{#1}{-\dimen0}\xmax
@@ -2973,10 +2986,8 @@
% 180=>\PDFcode{-1 0 0 -1 0 0 cm},
% 270=>\PDFcode{ 0 -1 1 0 0 0 cm},
% 360=>\PDFcode{ 1 0 0 1 0 0 cm},
-% #1=>%\calculatecos{#1}% already calculated in core macro
-% %\calculatesin{#1}% already calculated in core macro
-% \edef\cos{\calculatedcos{#1}}%
-% \edef\sin{\calculatedsin{#1}}%
+% #1=>\setcalculatedcos\cos{#1}%
+% \setcalculatedsin\sin{#1}%
% \PDFcode{\cos \space % cos
% \sin \space % sin
% \negated\sin\space % -sin
@@ -2987,10 +2998,9 @@
% can use the next alternative without running into inaccuracies.
\def\doPDFstartrotation#1% grouped
- {\calculatecos{#1}% already calculated in core macro
- \calculatesin{#1}% already calculated in core macro
- \edef\cos{\calculatedcos{#1}}%
- \edef\sin{\calculatedsin{#1}}%
+ {\setcalculatedcos\cos{#1}%
+ \setcalculatedsin\sin{#1}%
+ \forcecolorhack
\PDFcode{q \cos\space\sin\space\negated\sin\space\cos\space0 0 cm}}
\def\doPDFstoprotation
@@ -3004,7 +3014,8 @@
\def\@@PDFzeroscale{.0001}
\def\doPDFstartscaling#1#2% the test is needed because acrobat is bugged!
- {\PDFcode{q \ifdim#1\points=\zeropoint\@@PDFzeroscale\else#1\fi\space 0 0
+ {\forcecolorhack
+ \PDFcode{q \ifdim#1\points=\zeropoint\@@PDFzeroscale\else#1\fi\space 0 0
\ifdim#2\points=\zeropoint\@@PDFzeroscale\else#2\fi\space 0 0 cm}}
% \def\doPDFstartscaling#1#2% the test is needed because acrobat is bugged!
@@ -3253,8 +3264,8 @@
%D Handy for the \METAPOST\ to \PDF\ converter:
-\newevery \everyPDFximage \relax
-\newevery \everyPDFxform \relax
+\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi
+\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi
\appendtoksonce
\collectPDFresources
@@ -3275,7 +3286,7 @@
\xdef\collectedPDFresources{\collectedPDFresources/ColorSpace \PDFobjectreference}}\donothing
\global\let\collectPDFresources\relax}
-%D And that was all.
+%D And that was about all.
\stopspecials
@@ -3290,6 +3301,146 @@
\fi
-\loadmarkfile{spec-fdf}
+%D Temporary hack:
+
+\def\TransparencyHack % png: /CS /DeviceRGB /I true
+ {\appendtoks
+ \doPDFpageattribute{/Group << /S /Transparency /I true /K true>>}%
+ \to \everyPDFxform
+ \appendtoks
+ \doPDFpageattribute{/Group << /S /Transparency /I true /K true>>}%
+ \to \everyshipout}
+
+%D We still need to implement a few helpers:
+
+\chardef\safePDFcode=`-
+
+\def\setPDFdestination#1%
+ {\bgroup
+ \retainlccodes
+ \lccode`\/\safePDFcode \lccode`\#\safePDFcode
+ \lccode`\<\safePDFcode \lccode`\>\safePDFcode
+ \lccode`\[\safePDFcode \lccode`\]\safePDFcode
+ \lccode`\(\safePDFcode \lccode`\)\safePDFcode
+ \ifovercomePDFspace
+ \lccode`\ \safePDFcode
+ \fi
+ \ifovercomePDFbugs
+ \xdef\PDFdestination{'#1'}%
+ \else
+ \xdef\PDFdestination{#1}%
+ \fi
+ % nicer \xdef\PDFdestination{\ifovercomePDFbugs'\fi#1\ifovercomePDFbugs'\fi}%
+ \lowercase\@EA{\@EA\xdef\@EA\PDFdestination\@EA{\PDFdestination}}%
+ \egroup}
+
+%D This is much faster since we don't have to set the full
+%D range of lc-codes; about 5 sec on a 1000mhz PIII for
+%D 20K named destinations "x(x) x"). Of course when you use
+%D page destinations, the saving is nil.
+
+% \doifnotmode{atpragma}{\let\next\setPDFdestination} % experimental
+%
+% \catcode`\/=\@@active \catcode`\#=\@@active
+% \catcode`\<=\@@active \catcode`\>=\@@active
+% \catcode`\[=\@@active \catcode`\]=\@@active
+% \catcode`\(=\@@active \catcode`\)=\@@active
+%
+% \gdef\PDFrepchar{-}
+%
+% \gdef\setPDFdcharacters
+% {\catcode`\/=\@@active \let/\PDFrepchar
+% \catcode`\#=\@@active \let#\PDFrepchar
+% \catcode`\<=\@@active \let<\PDFrepchar
+% \catcode`\>=\@@active \let>\PDFrepchar
+% \catcode`\[=\@@active \let[\PDFrepchar
+% \catcode`\]=\@@active \let]\PDFrepchar
+% \catcode`\(=\@@active \let(\PDFrepchar
+% \catcode`\)=\@@active \let)\PDFrepchar}
+%
+% \egroup
+%
+% \def\setPDFdestination#1% expansion is needed, otherwise embedded
+% {\bgroup % macros will not expand under the new
+% \setPDFdcharacters % catcode regime
+% \ifovercomePDFspace
+% \catcode32=\@@ignore
+% \fi
+% \xdef\PDFdestination{\ifovercomePDFbugs'\fi#1\ifovercomePDFbugs'\fi}%
+% \scantokens\@EA{\@EA\xdef\@EA\PDFdestination\@EA{\PDFdestination}}%
+% \egroup}
+%
+% \doifnotmode{atpragma}{\let\setPDFdestination\next} % experimental
+
+%D This is a slow one, that uses \type{\lccode}'s to
+%D change the glyph as well as converts sensisitve ones into a
+%D \PDF\ command sequence, so \type{(} becomes \type{\(}. In
+%D fact we translate the string to lowercase inactive and non
+%D special characters, limit their number and finaly convert
+%D some of the characters to save ones.
+
+\chardef\maxPDFstringsize=60
+
+\def\sanitizePDFstring#1\to#2% bugged
+ {\bgroup
+ \retainlccodes
+ \lccode`( \zerocount \lccode`) \zerocount
+ \lccode`< \zerocount \lccode`> \zerocount
+ \lccode`[ \zerocount \lccode`] \zerocount
+ \lccode`\\\zerocount \lccode`/ \zerocount
+ \lowercase{\defconvertedargument\ascii{#1}}%
+ % by integrating the split in the loop below
+ % \splitofftokens\maxPDFstringsize\from\ascii\to\ascii
+ % we diminish the processing time considerably
+ \scratchcounter\maxPDFstringsize
+ \def\docommand##1%
+ {\ifcase\scratchcounter\else
+ \advance\scratchcounter \minusone
+ \ifcase\lccode`##1\relax
+ \xdef#2{#2\expandafter\string\csname##1\endcsname}%
+ \else
+ \xdef#2{#2##1}%
+ \fi
+ \fi}%
+ %\global\let#2=\empty
+ % or to permit #2 to be \ascii too:
+ \global\@EA\let\@EA#2\@EA\empty
+ \@EA\handletokens\ascii\with\docommand
+ \egroup}
+
+% \doifnotmode{atpragma}{\let\next\sanitizePDFstring} % experimental
+%
+% \bgroup
+%
+% \catcode`\.=\@@escape
+%
+% .catcode`./=.@@active
+% .catcode`.<=.@@active .catcode`.>=.@@active
+% .catcode`.[=.@@active .catcode`.]=.@@active
+% .catcode`.(=.@@active .catcode`.)=.@@active
+%
+% .gdef.setPDFscharacters%
+% {.catcode`.\=.@@other
+% .catcode`./=.@@active .def/{.noexpand./}%
+% .catcode`.<=.@@active .def<{.noexpand.<}%
+% .catcode`.>=.@@active .def>{.noexpand.>}%
+% .catcode`.[=.@@active .def[{.noexpand.[}%
+% .catcode`.]=.@@active .def]{.noexpand.]}%
+% .catcode`.(=.@@active .def({.noexpand.(}%
+% .catcode`.)=.@@active .def){.noexpand.)}}
+%
+% .gdef.sanitizePDFstring#1.to#2%
+% {.bgroup
+% .setPDFscharacters
+% .catcode`=.@@escape
+% .edef.next{.strippedcsname#2}%
+% .scantokens{setxvalue{next}{#1}}%
+% .egroup}
+%
+% .egroup
+%
+% \doifnotmode{atpragma}{\let\sanitizePDFstring\next} % experimental
+%
+% There is an unicode variant in spec-tst!
\protect \endinput
diff --git a/tex/context/base/spec-ini.tex b/tex/context/base/spec-ini.tex
index 221b8f4a2..4f3d884be 100644
--- a/tex/context/base/spec-ini.tex
+++ b/tex/context/base/spec-ini.tex
@@ -31,129 +31,41 @@
%D tried to overcome this problem by implementing specials as
%D a sort of drivers themselves.
-\writestatus{loading}{Context Special Macros / Initialization}
+\writestatus{loading}{ConTeXt Special Macros / Initialization}
\unprotect
-\startmessages dutch library: specials
- title: specials
- 1: -- geladen
- 2: verdere nesting is niet toegestaan --
- 3: -- gereset
- 4: commando -- bestaat niet
- 5: definitiefile -- wordt geladen
- 6: nesting is niet toegestaan
- 7: onbekende driver --
-\stopmessages
-
-\startmessages english library: specials
- title: specials
- 1: -- loaded
- 2: no deeper nesting is permitted --
- 3: -- is reset
- 4: command -- does not exist
- 5: loading definition file --
- 6: nesting is not permitted
- 7: unknown driver --
-\stopmessages
-
-\startmessages german library: specials
- title: spezielles
- 1: -- geladen
- 2: keine tiefere Verschachtelung erlaubt --
- 3: -- ist zurueckgesetzt
- 4: Befehl -- existiert nicht
- 5: lade Definitionsdatei --
- 6: Verschachtelung nicht erlaubt
- 7: unbekante Driver --
-\stopmessages
-
-\startmessages czech library: specials
- title: speciality
- 1: -- nacteno
- 2: neni dovoleno hlubsi zanoreni --
- 3: -- je resetovano
- 4: prikaz -- neexistuje
- 5: nacita se definicni soubor --
- 6: zanoreni neni dovoleno
- 7: neznamy ovladac (driver) --
-\stopmessages
-
-\startmessages italian library: specials
- title: specialitø
- 1: -- caricato
- 2: non ø permesso un annidamento maggiore --
- 3: -- reimpostato
- 4: il comando -- non esiste
- 5: caricamento del file di definizione --
- 6: annidamento non permesso
- 7: driver sconosciuto --
-\stopmessages
-
-\startmessages norwegian library: specials
- title: specials
- 1: -- er lest inn
- 2: dypere 'nesting' er ikke tillatt --
- 3: -- er tilbakestilt
- 4: kommando -- eksisterer ikke
- 5: leser inn definisjonsfil for --
- 6: 'nesting' er ikke tillatt
- 7: ukjent driver --
-\stopmessages
-
-\startmessages romanian library: specials
- title: specials
- 1: -- incarcat
- 2: nu este permis un nivel de imbricare mai mare --
- 3: -- s-a resetat
- 4: comanda -- nu exista
- 5: se incarca fisierul de definitii --
- 6: imbricarea nu este permisa
- 7: driver necunoscut --
-\stopmessages
-
-\startmessages french library: specials
- title: specials
- 1: -- chargé
- 2: pas d'imbracations plus profondes ne sont permises --
- 3: -- est remis à zéro
- 4: la commande -- n'existe pas
- 5: chargement du fichier de définition --
- 6: l'imbrication n'est pas permise
- 7: pilote -- inconnu
-\stopmessages
-
-\startmessages dutch library: interactions
- 21: -- code tussengevoegd
-\stopmessages
-
-\startmessages english library: interactions
- 21: -- code inserted
-\stopmessages
-
-\startmessages german library: interactions
- 21: -- Code eingefuegt
-\stopmessages
-
-\startmessages czech library: interactions
- 21: -- kod vlozen
-\stopmessages
-
-\startmessages italian library: interactions
- 21: codice -- inserito
-\stopmessages
-
-\startmessages norwegian library: interactions
- 21: -- kode satt inn / tilføyd
-\stopmessages
-
-\startmessages romanian library: interactions
- 21: -- cod inserat
-\stopmessages
-
-\startmessages french library: interactions
- 21: -- code inseré
-\stopmessages
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
+
+% messages moved
%D \TEX\ produces files in the \DVI\ format. This format is
%D well defined and stable. In this format one||byte commands
@@ -201,7 +113,7 @@
%D
%D Now what will this one do? We'll see in a few lines.
-\newevery \everyresetspecials \relax
+\newtoks \everyresetspecials
\appendtoksonce
\ifx\setjobsuffix\undefined\else\setjobsuffix{dvi}\fi
diff --git a/tex/context/base/spec-mis.tex b/tex/context/base/spec-mis.tex
index bfd253205..3d263eace 100644
--- a/tex/context/base/spec-mis.tex
+++ b/tex/context/base/spec-mis.tex
@@ -16,7 +16,7 @@
%D Acrobat Distiller. This module implements some common
%D features.
-\writestatus{loading}{Context Special Macros / Miscellaneous Macros}
+\writestatus{loading}{ConTeXt Special Macros / Miscellaneous Macros}
\unprotect
@@ -93,8 +93,6 @@
\def\dofileinsertion#1#2{\executeifdefined{do#1insert#2}\donothing}
\def\dofilechecker #1#2{\executeifdefined{do#1check#2} \donothing}
-\newevery \everyresetspecials \relax
-
\appendtoks \let\supportedfileinsertions\empty \to \everyresetspecials
\appendtoks \let\supportedfilecheckers \empty \to \everyresetspecials
@@ -234,13 +232,17 @@
\noexpand\installprogram{dvipos -o \jobname.tuo \jobname.dvi }%
\global\noexpand\let\noexpand\flushDVIpositionpapersize\relax}}
- \beginXETEX
- \def\dosetpositionpapersize#1#2%
- {\xdef\flushDVIpositionpapersize
- {\special{pos:papersize \number#1 \number#2}%
- \noexpand\installprogram{dvipos -o \jobname.tuo \jobname.xdv }%
- \global\noexpand\let\noexpand\flushDVIpositionpapersize\relax}}
- \endXETEX
+ % kind of obsolete since nowadays xetex supports \pdfsavepos as well
+
+ \ifnum\texengine=\xetexengine
+
+ \def\dosetpositionpapersize#1#2%
+ {\xdef\flushDVIpositionpapersize
+ {\special{pos:papersize \number#1 \number#2}%
+ \noexpand\installprogram{dvipos -o \jobname.tuo \jobname.xdv }%
+ \global\noexpand\let\noexpand\flushDVIpositionpapersize\relax}}
+
+ \fi
\prependtoksonce \flushDVIpositionpapersize \to \everyshipout
@@ -278,7 +280,7 @@
%D Handy to have this available asap:
-\newevery \everyPDFxform \relax
-\newevery \everyPDFximage \relax
+\ifdefined\everyPDFxform \newtoks\everyPDFxform \fi
+\ifdefined\everyPDFximage \newtoks\everyPDFximage \fi
\protect \endinput
diff --git a/tex/context/base/spec-pdf.lua b/tex/context/base/spec-pdf.lua
deleted file mode 100644
index 051a8794f..000000000
--- a/tex/context/base/spec-pdf.lua
+++ /dev/null
@@ -1,67 +0,0 @@
-if not modules then modules = { } end modules ['spec-pdf'] = {
- version = 1.001,
- comment = "companion to spec-fdf.tex",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
---[[ldx--
-<p>This module implements a couple of cleanup methods. We need these
-in order to meet the <l n='pdf'/> specification. Watch the double
-parenthesis; they are needed because otherwise we would pass more
-than one argument to <l n='tex'/>.</p>
---ldx]]--
-
-local char, byte, format = string.char, string.byte, string.format
-local texsprint, texwrite = tex.sprint, tex.write
-
-pdf = pdf or { }
-
-function pdf.cleandestination(str)
- texsprint((str:gsub("[%/%#%<%>%[%]%(%)%-%s]+","-")))
-end
-
-function pdf.cleandestination(str)
- texsprint((str:gsub("[%/%#%<%>%[%]%(%)%-%s]+","-")))
-end
-
-function pdf.sanitizedstring(str)
- texsprint((str:gsub("([\\/#<>%[%]%(%)])","\\%1")))
-end
-
---~ function pdf.hexify(str)
---~ texwrite("feff" .. utf.gsub(str,".",function(c)
---~ local b = byte(c)
---~ if b < 0x10000 then
---~ return ("%04x"):format(b)
---~ else
---~ return ("%04x%04x"):format(b/1024+0xD800,b%1024+0xDC00)
---~ end
---~ end))
---~ end
-
-function pdf.hexify(str)
- texwrite("feff")
- for b in str:utfvalues() do
- if b < 0x10000 then
- texwrite(("%04x"):format(b))
- else
- texwrite(("%04x%04x"):format(b/1024+0xD800,b%1024+0xDC00))
- end
- end
-end
-
-function pdf.utf8to16(s,offset) -- derived from j. sauter's post on the list
- offset = (offset and 0x110000) or 0 -- so, only an offset when true
- texwrite(char(offset+254,offset+255))
- for c in string.utfvalues(s) do
- if c < 0x10000 then
- texwrite(char(offset+c/256,offset+c%256))
- else
- c = c - 0x10000
- local c1, c2 = c / 1024 + 0xD800, c % 1024 + 0xDC00
- texwrite(char(offset+c1/256,offset+c1%256,offset+c2/256,offset+c2%256))
- end
- end
-end
diff --git a/tex/context/base/spec-tpd.mkii b/tex/context/base/spec-tpd.mkii
deleted file mode 100644
index 918dafb8e..000000000
--- a/tex/context/base/spec-tpd.mkii
+++ /dev/null
@@ -1,18 +0,0 @@
-%D \module
-%D [ file=spec-tpd,
-%D version=1996.01.25,
-%D title=\CONTEXT\ Special Macros,
-%D subtitle=\PDFTEX,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 some point I will really rewrite the drivers.
-
-\unprotect
-
-\protect \endinput
diff --git a/tex/context/base/spec-tpd.mkiv b/tex/context/base/spec-tpd.mkiv
deleted file mode 100644
index c2f6b27b5..000000000
--- a/tex/context/base/spec-tpd.mkiv
+++ /dev/null
@@ -1,37 +0,0 @@
-%D \module
-%D [ file=spec-tpd,
-%D version=1996.01.25,
-%D title=\CONTEXT\ Special Macros,
-%D subtitle=\PDFTEX,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Sorry for the mess. Some day I will clean it up.
-
-\unprotect
-
-\def\doPDFinsertbookmark#1#2#3#4#5% level sublevels text page open=1
- {\bgroup
- \doPDFgetpagereference{#4}\PDFobjectreference
- \pdfoutline
- user {<</S /GoTo /D [\PDFobjectreference\space\PDFpageviewwrd]>>}%
- \ifcase#2 \else count \ifcase#5-\fi#2 \fi
- {<\hexifiedPDFstring{#3}>}%
- \egroup}
-
-\def\doPDFsetupidentity#1#2#3#4#5#6%
- {\expanded{\doPDFaddtoinfo
- {/Title <\hexifiedPDFstring{#1}>
- /Subject <\hexifiedPDFstring{#2}>
- /Author <\hexifiedPDFstring{#3}>
- /Creator <\hexifiedPDFstring{#4}>
- /ModDate (#4)
- /ID (\jobname.#5) % needed for pdf/x
- /Keywords <\hexifiedPDFstring{#6}>}}}
-
-\protect \endinput
diff --git a/tex/context/base/spec-tpd.tex b/tex/context/base/spec-tpd.tex
index 49aabb3f6..597993e0a 100644
--- a/tex/context/base/spec-tpd.tex
+++ b/tex/context/base/spec-tpd.tex
@@ -75,17 +75,17 @@
\unprotect
\ifx\pdftexversion\undefined
- \writestatus{\m!systems}{you should use pdfTeX binaries}\wait
+ \writestatus\m!systems{you should use pdfTeX binaries}\wait
\protect\expandafter\endinput
\fi
\ifnum\pdftexversion<13
- \writestatus{\m!systems}{your pdfTeX version is much too old}\wait
+ \writestatus\m!systems{your pdfTeX version is much too old}\wait
\protect\expandafter\endinput
\fi
\ifnum\pdftexversion<14
- \writestatus{\m!systems}{please update your pdfTeX binaries}
+ \writestatus\m!systems{please update your pdfTeX binaries}
\fi
\ifnum\pdftexversion>19
@@ -206,8 +206,8 @@
%D
%D This token register is flushed before an ximage is loaded.
-\newevery \everyPDFximage \relax
-\newevery \everyPDFxform \relax
+\ifdefined\everyPDFximage \else \newtoks\everyPDFximage \fi
+\ifdefined\everyPDFxform \else \newtoks\everyPDFxform \fi
%D \macros
%D {dosetuppaper}
@@ -740,7 +740,7 @@
\definespecial\dostartgotorealpage{\doPDFstartgotorealpage}
\definespecial\dostartgotoJS {\doPDFstartgotoJS}
-\let\PDFpagexyzspec\empty % hack, pdftex does not accept spec
+\let\PDFpagexyzspec\empty % pdftex does not accept spec
%D \macros
%D {doflushJSpreamble}
@@ -1048,32 +1048,6 @@
\ifnum\pdftexversion>13
\def\doPDFaction#1#2#3%
- {\ifcollectreferenceactions
- \xdef\lastPDFaction{#3}%
- \else
- \ifsharePDFactions
- \ifcase\similarreference\relax
- \xdef\lastPDFaction{<<#3>>}%
- \or
- \immediate\pdfobj{<<#3>>}%
- \xdef\lastPDFaction{\PDFobjref\pdflastobj}%
- \else
- % leave \lastPDFaction untouched
- \fi
- \else
- \xdef\lastPDFaction{<<#3>>}%
- \fi
- \pdfannot
- width #1 height #2 depth \zeropoint
- {/Subtype /Link
- /Border [0 0 0]
- \ifhighlighthyperlinks \else /H /N \fi
- /A \lastPDFaction}%
- \fi}
-
- % less #2 passing
-
- \def\doPDFaction#1#2#3%
{\xdef\lastPDFcontent{#3}%
\ifcollectreferenceactions
\global\let\lastPDFaction\lastPDFcontent
@@ -1355,8 +1329,6 @@
%D Now we can finish this module.
-\loadmarkfile{spec-tpd}
-
\stopspecials
\protect \endinput
diff --git a/tex/context/base/spec-var.tex b/tex/context/base/spec-var.tex
index ba04565a2..8d561dc6f 100644
--- a/tex/context/base/spec-var.tex
+++ b/tex/context/base/spec-var.tex
@@ -14,7 +14,7 @@
%D This module used to be integrated in \type {spec-ini},
%D but testing optimization is more convenient this way.
-\writestatus{loading}{Context Special Macros / Variables}
+\writestatus{loading}{ConTeXt Special Macros / Variables}
% new approach, 'global' variables, since we run out of
% arguments
diff --git a/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua
new file mode 100644
index 000000000..1104157bd
--- /dev/null
+++ b/tex/context/base/strc-bkm.lua
@@ -0,0 +1,133 @@
+if not modules then modules = { } end modules ['strc-bkm'] = {
+ version = 0.200,
+ comment = "companion to strc-bkm.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: move some code to backend
+
+local format, concat, gsub = string.format, table.concat, string.gsub
+local texsprint, utfvalues = tex.sprint, string.utfvalues
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local lists = structure.lists
+
+-- todo: backend code
+
+local function pdfhexified(str)
+ local t = { }
+ t[#t+1] = "feff"
+ for b in utfvalues(str) do
+ if b < 0x10000 then
+ t[#t+1] = format("%04x",b)
+ else
+ t[#t+1] = format("%04x%04x",b/1024+0xD800,b%1024+0xDC00)
+ end
+ end
+ return concat(t)
+end
+
+-- todo: lpeg cleaner
+
+local function pdfbookmark(level,n,text,page,open)
+ text = gsub(text,"\\([A-Z]+)","%1") -- \LOGO
+ text = gsub(text,"\\ "," ") -- \
+ text = gsub(text,"\\([A-Za-z]+) *{(.-)}","%1") -- \bla{...}
+ text = gsub(text," +"," ") -- spaces
+ text = pdfhexified(text) -- somehow must happen here
+ texsprint(ctxcatcodes,format("\\doinsertbookmark{%s}{%s}{%s}{%s}{%s}",level,n,text,page,open))
+end
+
+-- end of todo
+
+local levelmap = structure.sections.levelmap
+
+structure.bookmarks = structure.bookmarks or { }
+
+local bookmarks = structure.bookmarks
+
+local function nofchildren(list,current,currentlevel)
+ local i = current + 1
+ local li = list[i]
+ if li then
+ local nextlevel = levelmap[li.metadata.name]
+ if nextlevel and nextlevel > currentlevel then
+ local n = 1
+ i = i + 1
+ li = list[i]
+ while li do
+ local somelevel = levelmap[li.metadata.name]
+ if somelevel then
+ if somelevel == nextlevel then
+ n = n + 1
+ elseif somelevel < nextlevel then
+ break
+ end
+ end
+ i = i + 1
+ li = list[i]
+ end
+ return n
+ end
+ end
+ return 0
+end
+
+local names, opened = "", ""
+
+function bookmarks.register(n,o)
+ if names == "" then names = n else names = names .. "," .. n end
+ if opened == "" then opened = o else opened = opened .. "," .. o end
+end
+
+function bookmarks.place()
+ if name ~= "" then
+ local list = lists.filter(names,"all",nil,lists.collected)
+ if #list > 0 then
+ local allopen = (opened == interfaces.variables.all) and 1
+ opened = aux.settings_to_set(opened)
+ for i=1,#list do
+ local li = list[i]
+ local metadata = li.metadata
+ if not metadata.nolist and levelmap[metadata.name] then
+ local name, titledata = metadata.name, li.titledata
+ if titledata then
+ local level = levelmap[name]
+ local children = nofchildren(list,i,level)
+ local title = titledata.bookmark or titledata.title or "?"
+ local realpage = li.references and li.references.realpage
+ if realpage then
+ local open = allopen or (opened[name] and 1)
+ pdfbookmark(level,children,title,realpage,allopen or open or 0)
+ end
+ end
+ end
+ end
+ bookmarks.place = function() end
+ end
+ end
+end
+
+function bookmarks.overload(name,text)
+ local l, ls = lists.tobesaved, nil
+ if #l == 0 then
+ -- no entries
+ elseif name == "" then
+ ls = l[#l]
+ else
+ for i=#l,0,-1 do
+ local li = l[i]
+ local metadata = li.metadata
+ if metadata and not metadata.nolist and metadata.name == name then
+ ls = li
+ break
+ end
+ end
+ end
+ if ls then
+ ls.titledata.bookmark = text
+ end
+end
diff --git a/tex/context/base/strc-bkm.tex b/tex/context/base/strc-bkm.tex
new file mode 100644
index 000000000..dd6352356
--- /dev/null
+++ b/tex/context/base/strc-bkm.tex
@@ -0,0 +1,90 @@
+%D \module
+%D [ file=strc-bkm,
+%D version=2009.04.01,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Bookmarks,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Structure Macros / Bookmarks}
+
+\registerctxluafile{strc-bkm}{1.001}
+
+\unprotect
+
+%D Due to requests I finally decided to support bookmarks, a
+%D driver dependant way of showing tables of content. The most
+%D simple way of support is hooking bookmark generation into
+%D the existing list mechanisms. That way users can generate
+%D bookmarks automatically, although its entirely valid to add
+%D bookmarks by defining alternative ones. These will be added
+%D at the appropriate place in the list.
+
+% \hoofdstuk{het eerste hoofdstuk}
+%
+% \bookmark {de eerste bookmark} % optional overruled hoofdstuk
+%
+% .... text ....
+%
+% \placebookmarks [hoofdstuk,paragraaf,subparagraaf,subsubparagraaf,mylist]
+% [open list]
+%
+% \bookmark[mylist]{whatever}
+
+%D This will go away.
+
+\let\flushpostponedbookmark\relax
+
+%D We have better ways now.
+
+\unexpanded\def\bookmark
+ {\dosingleempty\dobookmark}
+
+\def\dobookmark[#1]#2%
+ {\begingroup
+ \simplifycommands
+ \ctxlua{structure.bookmarks.overload("#1",\!!bs\detokenize\expandafter{\normalexpanded{#2}}\!!es)}%
+ \endgroup}
+
+%D Placement \unknown\ look how simple compared to \MKII:
+
+\def\placebookmarks
+ {\dodoubleempty\doplacebookmarks}
+
+\def\doplacebookmarks[#1][#2]%
+ {\iflocation
+ \iffirstargument
+ \ctxlua{structure.bookmarks.register("#1","#2")}%
+ \else
+ \normalexpanded{\noexpand\placebookmarks[\getvalue{\??ih\v!content\c!list}]}%
+ \fi
+ \fi}
+
+\appendtoks\ctxlua{structure.bookmarks.place()}\to\everystoptext
+
+\protect \endinput
+
+% \starttext
+% \setupinteraction[state=start]\setupinteractionscreen[option=bookmark]
+% \placebookmarks[chapter,section,subsection][chapter]
+% \chapter{First}
+% \bookmark{The First Indeed}
+% \section{alpha}
+% \bookmark[chapter]{The First Indeed Again}
+% \section{beta}
+% \chapter{Second}
+% \bookmark{The Second Indeed}
+% \section{gamma \tex{radiation}}
+% \subsection{a}
+% \subsection{b}
+% \section{delta}
+% \section{epsilon}
+% \chapter{Third \relax}
+% \chapter{我〈能吞下玻璃而不傷身〉體。} % whatever that means
+% \chapter{Idris Samawi Hamid ادريس سماوي حامد}
+% \stoptext
diff --git a/tex/context/base/core-blk.lua b/tex/context/base/strc-blk.lua
index 1007273d5..33dbb0b7c 100644
--- a/tex/context/base/core-blk.lua
+++ b/tex/context/base/strc-blk.lua
@@ -1,6 +1,6 @@
-if not modules then modules = { } end modules ['core-blk'] = {
+if not modules then modules = { } end modules ['strc--blk'] = {
version = 1.001,
- comment = "companion to core-blk.mkiv",
+ comment = "companion to strc--blk.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
@@ -8,7 +8,9 @@ if not modules then modules = { } end modules ['core-blk'] = {
-- this one runs on top of buffers and structure
-local texprint, format = tex.print, string.format
+local texprint, format, gmatch = tex.print, string.format, string.gmatch
+
+local ctxcatcodes = tex.ctxcatcodes
structure = structure or { }
structure.blocks = structure.blocks or { }
@@ -22,20 +24,18 @@ blocks.states = blocks.states or { }
local tobesaved, collected, states = blocks.tobesaved, blocks.collected, blocks.states
local function initializer()
- tobesaved, collected, states = blocks.tobesaved, blocks.collected, blocks.states
+ collected, tobesaved = blocks.collected, blocks.tobesaved
end
--- not used, todo: option to do single or double pass
-
--- job.register('structure.blocks.collected', structure.blocks.tobesaved, initializer, nil)
+job.register('structure.blocks.collected', structure.blocks.tobesaved, initializer)
local printer = (lpeg.linebyline/texprint)^0
function blocks.print(name,data,hide)
if hide then
- texprint(tex.ctxcatcodes,format("\\dostarthiddenblock{%s}",name))
+ texprint(ctxcatcodes,format("\\dostarthiddenblock{%s}",name))
else
- texprint(tex.ctxcatcodes,format("\\dostartnormalblock{%s}",name))
+ texprint(ctxcatcodes,format("\\dostartnormalblock{%s}",name))
end
if type(data) == "table" then
for i=1,#data do
@@ -45,9 +45,9 @@ function blocks.print(name,data,hide)
printer:match(data)
end
if hide then
- texprint(tex.ctxcatcodes,"\\dostophiddenblock")
+ texprint(ctxcatcodes,"\\dostophiddenblock")
else
- texprint(tex.ctxcatcodes,"\\dostopnormalblock")
+ texprint(ctxcatcodes,"\\dostopnormalblock")
end
end
@@ -58,7 +58,7 @@ end
function blocks.setstate(state,name,tag)
local all = tag == ""
local tags = not all and aux.settings_to_array(tag)
- for n in name:gmatch("%s*([^,]+)") do
+ for n in gmatch(name,"%s*([^,]+)") do
local sn = states[n]
if not sn then
-- error
@@ -72,6 +72,8 @@ function blocks.setstate(state,name,tag)
end
end
+--~ filter_collected(names, criterium, number, collected)
+
function blocks.select(state,name,tag,criterium)
criterium = criterium or "text"
if tag:find("=") then tag = "" end
@@ -80,17 +82,18 @@ function blocks.select(state,name,tag,criterium)
local tags = not all and aux.settings_to_set(tag)
local hide = state == "process"
local n = structure.sections.number_at_depth(criterium)
- local result = structure.lists.filter_collected("all", criterium, n, tobesaved)
+ local result = structure.lists.filter_collected("all", criterium, n, collected)
for i=1,#result do
- local b = result[i].entry
- if names[b.name] then
- local btags = b.tags
+ local ri = result[i]
+ local metadata = ri.metadata
+ if names[metadata.name] then
if all then
- blocks.print(name,b.data,hide)
+ blocks.print(name,ri.data,hide)
else
+ local mtags = metadata.tags
for tag, sta in pairs(tags) do
- if btags[tag] then
- blocks.print(name,b.data,hide)
+ if mtags[tag] then
+ blocks.print(name,ri.data,hide)
break
end
end
@@ -99,22 +102,23 @@ function blocks.select(state,name,tag,criterium)
end
end
-function blocks.save(name,tag,buffer)
+function blocks.save(name,tag,buffer) -- wrong, not yet adapted
local data = buffers.data[buffer]
local tags = aux.settings_to_set(tag)
local plus, minus = false, false
if tags['+'] then plus = true tags['+'] = nil end
if tags['-'] then minus = true tags['-'] = nil end
- local slt = structure.lists.tobesaved
tobesaved[#tobesaved+1] = {
- entry = {
+ metadata = {
name = name,
tags = tags,
- data = data or "error",
plus = plus,
minus = minus,
},
- sectionnumber = slt[#slt] and slt[#slt].sectionnumber
+ references = {
+ section = structure.sections.currentid(),
+ },
+ data = data or "error",
}
local allstate = states[name].all
if not next(tags) then
@@ -139,7 +143,3 @@ function blocks.save(name,tag,buffer)
end
buffers.data[buffer] = nil
end
-
--- function sections.getnumber()
--- structure.sections.number(entry, { }, "sectionnumber", "sectionnumber")
--- end
diff --git a/tex/context/base/core-blk.mkiv b/tex/context/base/strc-blk.tex
index 9d1f4deb4..90d2ff9ab 100644
--- a/tex/context/base/core-blk.mkiv
+++ b/tex/context/base/strc-blk.tex
@@ -1,20 +1,21 @@
%D \module
-%D [ file=core-blk,
+%D [ file=strc-blk,
%D version=2008.10.20,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Structure Macros,
%D subtitle=Blockmoves,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%D copyright=PRAGMA-ADE / 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
+\writestatus{loading}{ConTeXt Structure Macros / Blockmoves}
+
+\registerctxluafile{strc-blk}{1.001}
-% \registerctxluafile{core-blk}{1.001}
-\ctxloadluafile{core-blk}{}
+\unprotect
% we run on top of buffers and sections
%
@@ -45,7 +46,7 @@
\letvalue{\e!end#1}\relax}
\long\def\dobeginofblock[#1][#2]%
- {\expanded{\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}}
+ {\normalexpanded{\noexpand\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}}
{}{\ctxlua{structure.blocks.save("#1","#2","@block@")}}}% before after
\def\dostarthiddenblock
@@ -106,4 +107,4 @@
\def\processblocks{\doquadrupleempty\doselectblocks[process]}
\def\selectblocks {\doquadrupleempty\doselectblocks[use]}
-\protect
+\protect \endinput
diff --git a/tex/context/base/strc-def.tex b/tex/context/base/strc-def.tex
new file mode 100644
index 000000000..f24ee2023
--- /dev/null
+++ b/tex/context/base/strc-def.tex
@@ -0,0 +1,302 @@
+%D [ file=strc-def,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Definitions}
+
+% \registerctxluafile{strc-def}{1.001}
+
+\unprotect
+
+% \def\installparameterhandler#1#2#3#4#5#6#7#8#9{%
+% \def#3##1{\csname#5{#1#2}##1\endcsname}%
+% \def#4##1{#6{#1#2}##1}%
+% %
+% \def#5##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#7\csname##1\s!parent\endcsname##2\fi}%
+% \def#6##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#8\csname##1\s!parent\endcsname##2\fi}%
+% %
+% \def#7##1##2{\ifx##1\relax\s!empty\else#5##1##2\fi}%
+% \def#8##1##2{\ifx##1\relax \else#6##1##2\fi}%
+% %
+% \def#9##1##2% style color
+% {\edef\fontattributehash {#4##1}%
+% \edef\colorattributehash{#4##2}%
+% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash ##1\fi
+% \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash##2\fi}%
+% %
+% }
+
+% \installparameterhandler
+% \empty
+% \@@framed
+% \framedparameter
+% \framedparameterhash
+% \doframedparameter
+% \doframedparameterhash
+% \doframedparentparameter
+% \doframedparentparameterhash
+% \dosetframedattributes
+
+
+% \setupheads
+
+\setupstructureheads[%
+ %\c!after=,
+ %\c!align=,
+ %\c!aligntitle=,
+ \c!alternative=\v!normal,
+ %\c!before=,
+ %\c!color=,
+ \c!command=\normalplacehead,
+ \c!continue=\v!yes,
+ %\c!coupling=,
+ %\c!deepnumbercommand=,
+ %\c!deeptextcommand=,
+ %\c!default=,
+ \c!distance=\!!zeropoint,
+ \c!expansion=\v!no,
+ %\c!file=,
+ %\c!footer=,
+ %\c!grid=,
+ \c!hang=\v!none,
+ %\c!header=,
+ \c!incrementnumber=\v!yes,
+ \c!indentnext=\v!no,
+ %\c!label=,
+ \c!limittext=\v!yes,
+ \c!margin=\zeropoint,
+ %\c!margintext=,
+ \c!number=\v!yes,
+ \c!numbercolor=\structureheadparameter\c!color,
+ %\c!numbercommand=,
+ \c!numberstyle=\structureheadparameter\c!style,
+ \c!ownnumber=\v!no,
+ %\c!page=,
+ \c!placehead=\v!yes,
+ %\c!prefix=,
+ \c!previousnumber=\v!yes,
+ \c!resetnumber=\v!yes,
+ %\c!section=,
+ \c!sectionconversionset=\s!default,
+ \c!sectionnumber=\v!yes,
+ %\c!sectionsegments=,
+ \c!sectionseparatorset=\s!default,
+ \c!sectionset=\v!all,
+ %\c!sectionstopper=,
+ %\c!strut=,
+ %\c!style=,
+ %\c!text=,
+ \c!textcolor=\structureheadparameter\c!color,
+ %\c!textcommand=,
+ \c!textstyle=\structureheadparameter\c!style,
+ %\c!tolerance=
+ ]
+
+% \setupstructureblock[appendix][sectionconversionset=appendix]
+% \setupstructurehead[chapter][sectionconversionset=\structureblockparameter\c!sectionconversionset] % \structureblockparameter]
+
+\definestructureseparatorset [\s!default] [] [.]
+\definestructureconversionset [\s!default] [] [numbers]
+\definestructureresetset [\s!default] [] [0]
+\definestructureprefixset [\s!default] [section-1,section-2,section-3] []
+
+\definestructureprefixset [\v!all] [section-1,section-2,section-3,section-4,section-5,section-6,section-7,section-8] []
+
+\definestructureprefixset [\v!part] [section-1] []
+\definestructureprefixset [\v!chapter] [section-2] []
+
+\definestructureseparatorset [\v!appendix:\s!default] [] [.]
+\definestructureconversionset [\v!appendix:\s!default] [Romannumerals,Characters] [numbers]
+\definestructureresetset [\v!appendix:\s!default] [] [0]
+
+% \definesectionblock
+
+\definestructureblock [\v!frontpart] [\v!frontmatter] [\c!number=\v!no]
+\definestructureblock [\v!bodypart] [\v!bodymatter] [\c!number=\v!yes]
+\definestructureblock [\v!appendix] [\v!appendices] [\c!number=\v!yes]
+\definestructureblock [\v!backpart] [\v!backmatter] [\c!number=\v!no]
+
+\setstructureblock [\v!bodypart] % default
+
+\appendtoks
+ \setstructureblock [\v!bodypart]% default
+\to \everyjob
+
+% \definesection
+
+\definestructuresection[\s!section-1] % part
+\definestructuresection[\s!section-2] % chapter
+\definestructuresection[\s!section-3] % section
+\definestructuresection[\s!section-4] % subsection
+\definestructuresection[\s!section-5] % subsubsection
+\definestructuresection[\s!section-6] % subsubsubsection
+\definestructuresection[\s!section-7] % subsubsubsubsection
+
+% \definehead
+
+\definestructurehead
+ [\v!part]
+ [\c!section=\s!section-1]
+
+\definestructurehead
+ [\v!chapter]
+ [\c!section=\s!section-2]
+
+\definestructurehead
+ [\v!section]
+ [\c!section=\s!section-3]
+
+\definestructurehead
+ [\v!subsection]
+ [\c!section=\s!section-4,
+ \c!default=\v!section]
+
+\definestructurehead
+ [\v!subsubsection]
+ [\c!section=\s!section-5,
+ \c!default=\v!subsection]
+
+\definestructurehead
+ [\v!subsubsubsection]
+ [\c!section=\s!section-6,
+ \c!default=\v!subsubsection]
+
+\definestructurehead
+ [\v!subsubsubsubsection]
+ [\c!section=\s!section-7,
+ \c!default=\v!subsubsubsection]
+
+\definestructurehead
+ [\v!title]
+ [\c!coupling=\v!chapter,
+ \c!default=\v!chapter,
+ \c!incrementnumber=\v!no]
+
+\definestructurehead
+ [\v!subject]
+ [\c!coupling=\v!section,
+ \c!default=\v!section,
+ \c!incrementnumber=\v!no]
+
+\definestructurehead
+ [\v!subsubject]
+ [\c!coupling=\v!subsection,
+ \c!default=\v!subsection,
+ \c!incrementnumber=\v!no]
+
+\definestructurehead
+ [\v!subsubsubject]
+ [\c!coupling=\v!subsubsection,
+ \c!default=\v!subsubsection,
+ \c!incrementnumber=\v!no]
+
+\definestructurehead
+ [\v!subsubsubsubject]
+ [\c!coupling=\v!subsubsubsection,
+ \c!default=\v!subsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definestructurehead
+ [\v!subsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsection,
+ \c!default=\v!subsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\setupstructurehead
+ [\v!part]
+ [\c!placehead=\v!no]
+
+\setupstructurehead
+ [\v!chapter]
+ [\v!appendix\c!label=\v!appendix,
+ \v!bodypart\c!label=\v!chapter] % bijlageconversie=\Character
+
+\setupstructurehead
+ [\v!section]
+ [\v!appendix\c!label=\v!section,
+ \v!bodypart\c!label=\v!section] % bijlageconversie=\Character
+
+\setupstructurehead
+ [\v!subsection]
+ [\v!appendix\c!label=\v!subsection,
+ \v!bodypart\c!label=\v!subsection] % bijlageconversie=\Character
+
+\setupstructurehead
+ [\v!subsubsection]
+ [\v!appendix\c!label=\v!subsubsection,
+ \v!bodypart\c!label=\v!subsubsection] % bijlageconversie=\Character
+
+% \setuphead
+
+\setupstructurehead
+ [\v!part,\v!chapter]
+ [%\c!align=,
+ %\c!indentnext=\v!no,
+ \c!continue=\v!no,
+ \c!page=\v!right,
+ \c!header=,
+ \c!style=\tfc,
+ \c!distance=.75em,
+ \c!before={\blank[2*\v!big]},
+ \c!after={\blank[2*\v!big]}]
+
+\setupstructurehead
+ [\v!section]
+ [%\c!align=,
+ %\c!indentnext=\v!no,
+ \c!style=\tfa,
+ \c!distance=.75em,
+ \c!before={\blank[2*\v!big]},
+ \c!after=\blank]
+
+\setupstructurehead % nieuw
+ [\v!subsection]
+ [\c!page=]
+
+% brrr
+
+% \definestructurecounter[\v!page][\c!start=1] % todo: setup
+
+% lists
+
+\definecombinedlist
+ [\v!content]
+ [\v!part,
+ \v!chapter,
+ \v!section,
+ \v!subsection,
+ \v!subsubsection,
+ \v!subsubsubsection,
+ \v!subsubsubsubsection]
+ [\c!level=\v!subsubsubsubsection,
+ \c!criterium=\v!local]
+
+\setuplist
+ [\v!part]
+ [\c!before={\blank\page[\v!preference]},
+ \c!after=\blank,
+ \c!label=\v!yes,
+ \c!distance=1em]
+
+\setuplist
+ [\v!chapter]
+ [\c!before={\blank\page[\v!preference]},
+ \c!after=]
+
+\setuplist [\v!part] [\c!width=0em]
+\setuplist [\v!chapter] [\c!width=2em]
+\setuplist [\v!section] [\c!width=3em]
+\setuplist [\v!subsection] [\c!width=4em]
+\setuplist [\v!subsubsection] [\c!width=5em]
+\setuplist [\v!subsubsubsection] [\c!width=6em]
+\setuplist [\v!subsubsubsubsection] [\c!width=7em]
+
+\protect \endinput
diff --git a/tex/context/base/strc-des.lua b/tex/context/base/strc-des.lua
new file mode 100644
index 000000000..0d548e61f
--- /dev/null
+++ b/tex/context/base/strc-des.lua
@@ -0,0 +1,9 @@
+if not modules then modules = { } end modules ['strc-des'] = {
+ version = 1.001,
+ comment = "companion to strc-des.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- empty
diff --git a/tex/context/base/strc-des.tex b/tex/context/base/strc-des.tex
new file mode 100644
index 000000000..1b196974a
--- /dev/null
+++ b/tex/context/base/strc-des.tex
@@ -0,0 +1,1018 @@
+%D \module
+%D [ file=strc-blk,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Descriptions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Descriptions}
+
+\registerctxluafile{strc-des}{1.001}
+
+%D In order to be more flexible with theorems Aditya Mahajan added
+%D support for titles and endsymbols. At the same time we added more
+%D flexible support for inheriting numbers.
+%D
+%D \startbuffer
+%D \defineenumeration[one]
+%D \defineenumeration[two] [one]
+%D \defineenumeration[three] [number=one,style=slanted]
+%D \defineenumeration[four] [three]
+%D \defineenumeration[five] [three] [number=five]
+%D
+%D \startone test test 1 \stopone
+%D \starttwo test test 2 \stoptwo
+%D \startthree test test 3 \stopthree
+%D \startfour test test 4 \stopfour
+%D \startfive test test 1 \stopfive
+%D \stopbuffer
+%D
+%D \typebuffer \start \getbuffer \stop
+
+% list and titles are experimental
+%
+% \definedescription[test] [location=left,hang=4,headalign={right},distance=1em,list=test]
+% \defineenumeration[lemma][title=yes,right=:,textdistance=1em, location=top, titlestyle=\bs,list=lemma]
+% \defineenumeration[ammel][title=yes,right=:,textdistance=.5em,location=left,titlestyle=\it,width=9em]
+%
+% \placelist[enumeration:lemma]
+% \placelist[description:test][width=0pt]
+%
+% \starttest {something something something} \input zapf \stoptest
+% \startlemma {with a title of a certain length} \input tufte \stoplemma
+% \startammel {with a title} \input zapf \stopammel
+%
+% \defineenumeration[lemma][...]
+% \defineenumeration[titledlemma][lemma][title=yes,right=:,text=lemma,list=lemma]
+
+\unprotect
+
+% description parameters
+
+\def\descriptionparameter #1{\csname\dodescriptionparameter{\??dd\currentdescription }#1\endcsname}
+\def\descriptionmainparameter #1{\csname\dodescriptionparameter{\??dd\currentdescriptionmain }#1\endcsname}
+\def\descriptionnumberparameter#1{\csname\dodescriptionparameter{\??dd\currentdescriptionnumber}#1\endcsname}
+
+\def\detokenizeddescriptionparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??dd\currentdescription#1\endcsname}}
+
+\def\dodescriptionparameter#1#2%
+ {\ifcsname#1#2\endcsname#1#2\else\expandafter\dodescriptionparentparameter\csname#1\s!parent\endcsname#2\fi}
+
+\def\dodescriptionparentparameter#1#2%
+ {\ifx#1\relax\s!empty\else\dodescriptionparameter#1#2\fi}
+
+% description hashes (needed for style/color)
+
+\def\descriptionparameterhash #1{\dodescriptionparameterhash{\??dd\currentdescription }#1}
+\def\descriptionmainparameterhash#1{\dodescriptionparameterhash{\??dd\currentdescriptionmain}#1}
+
+\def\dodescriptionparameterhash#1#2%
+ {\ifcsname#1#2\endcsname#1\else\expandafter\dodescriptionparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dodescriptionparentparameterhash#1#2%
+ {\ifx#1\relax\else\dodescriptionparameterhash#1#2\fi}
+
+\def\dosetdescriptionattributes#1#2% style color
+ {\edef\fontattributehash {\descriptionparameterhash#1}%
+ \edef\colorattributehash{\descriptionparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+% typesetting code
+
+\newbox \descriptionheadbox
+\newskip \leftdescriptionskip
+\newskip \rightdescriptionskip
+\newdimen \descriptionsheadwidth % replaces \!!widtha
+\newdimen \descriptionsheaddistance % replaces \!!widthb
+
+\setvalue{@@description\v!left }{\@@descriptionhang\@@descriptionleftpure \@@descriptionlefthang \@@descriptionleftmargin }
+\setvalue{@@description\v!right}{\@@descriptionhang\@@descriptionrightpure\@@descriptionrighthang\@@descriptionrightmargin}
+
+\def\@@descriptionhang#1#2#3% \next still needed?
+ {\processaction
+ [\descriptionparameter\c!hang]
+ [ \v!none=>\let\next#1,%
+ 0=>\let\next#1,%
+ \v!margin=>\let\next#3,%
+ \s!unknown=>\let\next#2,%
+ \s!default=>\let\next#1]%
+ \next}
+
+\def\@@descriptionleftpure
+ {\def\\{\crlf}%
+ \noindent
+ \leftskip\dimexpr\leftdescriptionskip+\descriptionsheadwidth\relax
+ \rightskip\rightdescriptionskip
+ \@@makedescriptionpurebox\raggedright
+ \advance\leftskip\descriptionsheaddistance
+ \llap
+ {\hbox to \leftskip
+ {\hskip\leftdescriptionskip
+ \copy\descriptionheadbox\hss}}%
+ \@@dodescription}
+
+\def\@@descriptionrightpure
+ {\def\\{\crlf}%
+ \noindent
+ \leftskip\leftdescriptionskip
+ \rightskip\dimexpr\rightdescriptionskip+\descriptionsheadwidth\relax
+ \@@makedescriptionpurebox\raggedleft
+ \rlap
+ {\hskip\dimexpr\hsize-\leftskip-\rightskip\relax
+ \copy\descriptionheadbox
+ \hskip\rightdescriptionskip}%
+ \advance\rightskip \descriptionsheaddistance
+ \@@dodescription}
+
+\def\@@descriptionleftmargin
+ {\def\\{\crlf}%
+ \noindent
+ \llap
+ {\@@makedescriptionpurebox\raggedright
+ \hbox to \descriptionparameter\c!width{\copy\descriptionheadbox\hss}%
+ \hskip\descriptionparameter\c!distance}%
+ \@@dodescription}
+
+\def\@@descriptionrightmargin % whatever this means
+ {\def\\{\crlf}%
+ \noindent
+ \rlap
+ {\hskip\descriptionparameter\c!distance
+ \@@makedescriptionpurebox\raggedright
+ \hbox to \descriptionparameter\c!width{\copy\descriptionheadbox\hss}}%
+ \@@dodescription}
+
+\def\@@makedescriptionpurebox#1%
+ {\setbox\descriptionheadbox\vtop
+ {\dontcomplain
+ \hsize\descriptionsheadwidth
+ \leftskip\zeropoint
+ \rightskip\zeropoint
+ #1\setupalign[\descriptionparameter\c!align]%
+ \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}%
+ \ht\descriptionheadbox\strutht
+ \dp\descriptionheadbox\strutdp}
+
+\def\@@descriptionlefthang
+ {\def\\{\crlf}%
+ \dontcomplain
+ \advance\descriptionsheadwidth \descriptionsheaddistance
+ \hangindent\descriptionsheadwidth
+ \@@makedescriptionhangbox\raggedright{\advance\rightskip \descriptionsheaddistance}%
+ \noindent
+ \llap
+ {\dontshowcomposition
+ \vtop to \zeropoint{\box\descriptionheadbox}}%
+ \@@dodescription}
+
+\def\@@descriptionrighthang
+ {\def\\{\crlf}%
+ \dontcomplain
+ \advance\descriptionsheadwidth \descriptionsheaddistance
+ \hangindent-\descriptionsheadwidth
+ \@@makedescriptionhangbox\raggedleft{\advance\leftskip \descriptionsheaddistance}%
+ \noindent
+ \rlap
+ {\dontcomplain
+ \dontshowcomposition
+ \hbox to \dimexpr\hsize-\leftskip-\rightskip\relax % can be a macro
+ {\hss\vtop to \zeropoint{\box\descriptionheadbox}}}%
+ \@@dodescription}
+
+\def\@@makedescriptionhangbox#1#2%
+ {\setbox\descriptionheadbox\vtop % \vbox gaat fout in hang
+ {\forgetall
+ \dontcomplain
+ \hsize\descriptionsheadwidth
+ #1\setupalign[\descriptionparameter\c!align]#2%
+ \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}%
+ \ht\descriptionheadbox\strutht
+ \dp\descriptionheadbox\strutdp
+ \doifsomething{\descriptionparameter\c!hang}
+ {\doifinsetelse{\descriptionparameter\c!hang}{\v!fit,\v!broad}
+ {\scratchdimen\htdp\descriptionheadbox
+ \doif{\descriptionparameter\c!hang}\v!broad
+ {\advance\scratchdimen .5\strutht}%
+ \getnoflines\scratchdimen
+ \hangafter-\noflines}
+ {\hangafter-\descriptionparameter\c!hang}}}
+
+\setvalue{@@description\v!top}%
+ {%\page[\v!preference]% % Weg ermee!
+ %\dosomebreak{\goodbreak}% % Dit is beter en nodig!
+ \dohandlepagebreakX\plusone % En dit moet het maar worden.
+ \let\\=\space
+ \noindent
+ \copy\descriptionheadbox\par
+ \nobreak
+ %\descriptionparameter\c!inbetween % .. brrrr ... :
+ \doifelsenothing{\descriptionparameter\c!inbetween}{\blank}{\descriptionparameter\c!inbetween}%
+ \nobreak
+ \@@dodescription}
+
+\def\do@@description#1%
+ {\def\\{\crlf}%
+ \noindent
+ #1{\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}%
+ \@@dodescription}
+
+\setvalue{@@description\v!inmargin }{\do@@description\inmargin}
+\setvalue{@@description\v!inleft }{\do@@description\inleft }
+\setvalue{@@description\v!inright }{\do@@description\inright }
+\setvalue{@@description\v!margin }{\do@@description\inmargin}
+\setvalue{@@description\v!leftmargin }{\do@@description\inleft }
+\setvalue{@@description\v!rightmargin }{\do@@description\inright }
+\setvalue{@@description\v!innermargin }{\do@@description\ininner }
+\setvalue{@@description\v!outermargin }{\do@@description\inouter }
+
+\setvalue{@@description\v!serried\v!fit}%
+ {\def\\{\crlf}%
+ \noindent
+ \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox
+ \hskip\descriptionsheaddistance % toegevoegd
+ \@@dodescription}
+
+\setvalue{@@description\v!serried\v!broad}%
+ {\def\\{\crlf}%
+ \noindent
+ \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox
+ \hskip\descriptionsheaddistance \!!plus .5\descriptionsheaddistance \!!minus .25\descriptionsheaddistance
+ \@@dodescription}
+
+\setvalue{@@description\v!serried\v!wide}%
+ {\def\\{\crlf}%
+ \noindent
+ \hbox to \descriptionsheadwidth
+ {\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox\hss}%
+ \hskip\descriptionsheaddistance
+ \@@dodescription}
+
+\setvalue{@@description\v!serried}%
+ {\processaction
+ [\descriptionparameter\c!width]
+ [ \v!fit=>\let\next\v!fit,
+ \v!broad=>\let\next\v!broad,
+ \s!unknown=>\let\next\v!wide,
+ \s!default=>\let\next\v!broad]%
+ \getvalue{@@description\v!serried\next}}
+
+\setvalue{@@description\v!hanging}%
+ {\def\\{\crlf}%
+ \noindent
+ \advance\leftskip -\leftskipadaption \relax
+ \ifdim\leftskipadaption=\zeropoint
+ \leftskipadaption1.5em\relax % just some default
+ \ifnum\nesteddescriptionstate=\plusone
+ \ifdim\leftskip>\zeropoint \relax
+ \leftskipadaption\leftskip
+ \fi
+ \fi
+ \fi
+ \ifnum\nesteddescriptionstate>\zerocount % was \ifnum\nesteddescriptionstate=\plusone
+ \advance\leftskip \leftskipadaption % but we're already further on
+ \fi
+ \hskip-\leftskipadaption
+ \ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox
+ \kern\ifdim\descriptionsheaddistance=\zeropoint .75em\else\descriptionsheaddistance\fi
+ \@@dodescription}
+
+%D A bonus definition
+%D
+%D \starttyping
+%D \setupfootnotedefinition[location=command,headcommand=\llap]
+%D \stoptyping
+
+% \setvalue{@@description\v!command}%
+% {\do@@description{\executeifdefined{\descriptionparameterhash\c!headcommand}\framed}}
+
+\setvalue{@@description\v!command}%
+ {\noindent
+ \descriptionparameter\c!headcommand{\ifhbox\descriptionheadbox\unhcopy\else\copy\fi\descriptionheadbox}%
+ \@@dodescription}
+
+%D A new key 'headalign' in definitions.
+
+\def\resetdescriptions % to be used in e.g. footnotes
+ {\chardef\nesteddescriptionstate\zerocount}
+
+\resetdescriptions
+
+\def\@@dostartdescription
+ {\descriptionparameter\c!before
+ \begingroup
+ \doadaptleftskip{\descriptionparameter\c!margin}%
+ \showcomposition
+ \descriptionsheaddistance\descriptionparameter\c!distance\relax
+ \ifdim\descriptionsheaddistance=\zeropoint\relax
+ \doif{\descriptionparameter\c!width}\v!broad{\descriptionsheaddistance=1em}%
+ \fi
+ \setbox\descriptionheadbox\hbox
+ {\forgetall\dontcomplain
+ \trialtypesettingtrue
+ \doifelsenothing{\descriptionparameter\c!sample}
+ {\dodescriptionhandler
+ {\begstrut\descriptionparameter\c!text\ignorespaces\currentdescriptiontext\endstrut}}%
+ {\dodescriptionhandler
+ {\begstrut\descriptionparameter\c!text\descriptionparameter\c!sample\endstrut}}}%
+ \assignwidth
+ \descriptionsheadwidth
+ {\descriptionparameter\c!width}
+ {\unhcopy\descriptionheadbox}
+ \descriptionsheaddistance
+ \setbox\descriptionheadbox\hbox
+ {\forgetall\dontcomplain
+ \doifelse{\descriptionparameter\c!location}\v!serried % brrr, hack
+ {\dodescriptionhandler
+ {\begstrut\descriptionparameter\c!text\currentdescriptiontext\endstrut}}
+ {\dodescriptionhandler
+ {\vtop
+ {\hsize\dimexpr\descriptionsheadwidth-\descriptionsheaddistance\relax
+ \begstrut\descriptionparameter\c!text\ignorespaces\currentdescriptiontext\endstrut}}}}%
+ \doifelse{\descriptionparameter\c!aligntitle}\v!no
+ {\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip}
+ {\ifcase\nesteddescriptionstate\leftdescriptionskip\leftskip\rightdescriptionskip\rightskip\fi}%
+ \normalexpanded{\noexpand\indenting[\descriptionparameter\c!indenting]}%
+ % better a system mode
+ \ifcase\nesteddescriptionstate
+ \chardef\nesteddescriptionstate\plusone
+ \or
+ \chardef\nesteddescriptionstate\plustwo
+ \fi % now happens elsewhere : \noindent\ignorespaces
+ \@@resetdescriptionclosesymbol}
+
+\def\@@stopdescription
+ {\@@placedescriptionclosesymbol
+ \par % else we loose
+ \endgroup
+ \descriptionparameter\c!after % which currentdescription is taken here?
+ \egroup % temporary hack
+ \checknextindentation[\descriptionparameter\c!indentnext]
+ \dorechecknextindentation}
+
+\def\@@dodescription
+ {\dosetdescriptionattributes\c!style\c!color
+ \ignorespaces}
+
+% starters:
+
+\def\@@startdescription[#1]%
+ {\doifelse{\descriptionparameter\c!title}\v!yes
+ {\permitspacesbetweengroups
+ \dodoublegroupempty{\dohandledescriptionstart[#1]}}
+ {\dohandledescriptionstart[#1]{}}}
+
+\def\@@description[#1]%
+ {\doifelse{\descriptionparameter\c!title}\v!yes
+ {\permitspacesbetweengroups
+ \dodoublegroupempty{\dohandledescriptiondo[#1]}}
+ {\dohandledescriptiondo[#1]{}}}
+
+% these call:
+
+\long\def\@@somedescription[#1]#2%
+ {\dowithpar
+ {\bgroup % temporary hack
+ \@@makedescription[#1]{#2}}%
+ {\@@stopdescription}}
+
+\long\def\@@startsomedescription[#1]#2%
+ {\bgroup % temporary hack
+ \BeforePar{\@@makedescription[#1]{#2}}%
+ \GotoPar}
+
+\def\@@dostartdescriptionindeed
+ {\edef\currentdescriptionlocation{\descriptionparameter\c!location}%
+ \ifx\currentdescriptionlocation\empty
+ \let\currentdescriptionlocation\v!left
+ \fi
+ \ifcsname @@description\currentdescriptionlocation\endcsname \else
+ \let\currentdescriptionlocation\v!left
+ \fi
+ \@@dostartdescription
+ \csname @@description\currentdescriptionlocation\endcsname} % args not needed
+
+\def\@@makedescription[#1]#2%
+ {\postponenotes % new, assumes grouping
+ \doenumerationcheckconditions
+ \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#2},\c!bookmark=,][]%
+ \@@dostartdescriptionindeed}
+
+\def\dostartstoreddescription
+ {\@@dostartdescriptionindeed}
+
+\def\dostopstoreddescription
+ {\@@stopdescription}
+
+% % % % % % % % % % % %
+
+% helpers
+
+% todo: \dosetfontattributewithhash \descriptionparameterhash\c!headstyle
+
+% setup descriptions
+
+\def\setupdescriptions
+ {\dodoubleempty\dosetupdescriptions}
+
+\def\dosetupdescriptions[#1][#2]% % beter: \iffirstargument
+ {\ifsecondargument
+ \dodoubleargumentwithset\dodosetupdescriptions[#1][#2]%
+ \else
+ \dodosetupdescriptions[][#1]%
+ \fi}
+
+\def\dodosetupdescriptions[#1]% [#2]%
+ {\getparameters[\??dd#1]} % [#2]}
+
+% define descriptions
+
+\def\definedescription
+ {\dotripleemptywithset\dodefinedescription}
+
+\def\dodefinedescription[#1][#2][#3]% to be simplified cf enumeration
+ {\dodescriptioninit{#1}%
+ \getparameters[\??dd#1][\c!text=,\s!handler=\v!description,\c!title=\v!yes]%
+ \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi
+ \ifdone
+ \getparameters[\??dd#1][\s!parent=\??dd,\c!text=,\s!handler=\v!description,#2]%
+ \dodefinedescriptioncommands{#1}{\??dd}%
+ \else % clone
+ \getparameters[\??dd#1][\s!parent=\??dd#2,\c!text=,\s!handler=\v!description,#3]% clone
+ \dodefinedescriptioncommands{#1}{\??dd#2}%
+ \fi}
+
+\def\dodefinedescriptioncommands#1#2%
+ {\unexpanded\setevalue {#1}{\noexpand\dodescriptioncommand{#1}}%
+ \unexpanded\setevalue{\e!start#1}{\noexpand\dodescriptionstart {#1}}%
+ \unexpanded\setevalue{\e!stop #1}{\noexpand\dodescriptionstop {#1}}}
+
+% handle descriptions
+
+\def\dodescriptioninit#1%
+ {\let\currentdescriptionmain \empty
+ \let\currentdescriptionlevel \empty
+ \edef\currentdescriptionname {#1}%
+ \edef\currentdescription {#1}}
+
+\def\dodescriptioncommand#1{\dodescriptioninit{#1}\dosingleempty\@@description}
+\def\dodescriptionstart #1{\dodescriptioninit{#1}\dosingleempty\@@startdescription}
+\def\dodescriptionstop #1{\dodescriptioninit{#1}\@@stopdescription}
+
+\def\dodescriptionhandler {\csname\??dd:\descriptionparameter\s!handler:\s!handler \endcsname}
+\def\dohandledescriptiondo {\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!do \endcsname}
+\def\dohandledescriptionstart{\csname\??dd:\descriptionparameter\s!handler:\s!handler:\s!start\endcsname}
+
+% implementation
+
+% beware: with footnotes #2 can be something messy but then #1 is
+% empty anyway, so we have an extra safeguard
+
+\newtoks \everydescription
+
+\setvalue{\??dd:\v!description:\s!handler }{\@@dodescriptionhandler}
+\setvalue{\??dd:\v!description:\s!handler:\s!do }{\@@somedescription}
+\setvalue{\??dd:\v!description:\s!handler:\s!start}{\@@startsomedescription}
+
+\def\@@dodescriptionhandler#1%
+ {\strut
+ \dodescriptionheadtext{#1}%
+ \iftrialtypesetting \else
+ \currentdescriptionsynchronize
+ \fi}
+
+\def\dodescriptionheadtext#1% title
+ {\begingroup
+ \dosetdescriptionattributes\c!headstyle\c!headcolor
+ \the\everydescription
+ \descriptionparameter\c!command{\strut#1}% probably incomplete
+ \endgroup}
+
+% setup enumerations
+
+\def\setupenumerations
+ {\dodoubleempty\dosetupenumerations}
+
+\def\dodosetupenumerations[#1][#2]%
+ {\doenumerationinit{#1}{1}\empty
+ \getparameters[\??dd#1][#2]%
+ \dosetupenumerationcounter{#1}}
+
+\def\dosetupenumerations[#1][#2]%
+ {\ifsecondargument
+ \dodoubleargumentwithset\dodosetupenumerations[#1][#2]%
+ \else
+ \getparameters[\??dn][#1]%
+ \fi}
+
+% define enumerations
+
+\def\defineenumeration
+ {\dotripleemptywithset\dodefineenumeration}
+
+\def\dodefineenumeration[#1][#2][#3]% #2 or #3 assignment
+ {\doenumerationinit{#1}{1}\empty
+ \getparameters[\??dd#1][\c!text=#1,\c!state=\v!start,\s!handler=\v!enumeration,\c!levels=4]%
+ \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi
+ \ifdone % independent
+ \getparameters[\??dd#1][\s!counter=#1,#2]%
+ \dodefineenumerationcommands{#1}{1}{}{\??dn}%
+ \let\@@subslevel\empty
+ \dostepwiserecurse{2}{\descriptionparameter\c!levels}{1}
+ {\normalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel\v!sub}{\??dd\@@subslevel#1}}%
+ \edef\@@subslevel{\@@subslevel\v!sub}}%
+ \else % clone
+ \getparameters[\??dd#1][\s!counter=#2,#3]%
+ \let\@@subslevel\empty
+ \dorecurse{\descriptionparameter\c!levels}
+ {\noemalexpanded{\noexpand\dodefineenumerationcommands{#1}{\recurselevel}{\@@subslevel}{\??dd\@@subslevel#2}}%
+ \edef\@@subslevel{\@@subslevel\v!sub}}%
+ \fi
+ \edef\currentdescriptioncounter{\descriptionparameter\c!number}%
+ \ifx\currentdescriptioncounter\empty
+ \ifdone\dodefineenumerationcounter{#1}\fi
+ \else\ifx\currentdescriptioncounter\v!yes
+ \ifdone\dodefineenumerationcounter{#1}\fi
+ \else\ifx\currentdescriptioncounter\v!no
+ \ifdone\dodefineenumerationcounter{#1}\fi
+ \else
+ \letvalue{\??dd#1\s!counter}\currentdescriptioncounter % ?
+ \doifstructurecounterelse{\currentdescriptioncounter}{}{\dodefineenumerationcounter\currentdescriptioncounter}%
+ \fi\fi\fi}
+
+\newtoks\everysetupenumerationcounter
+\let\currentenumerationcountername\empty
+
+\def\dosetupenumerationcounter#1%
+ {\edef\currentenumerationcountername{#1}% only used in the token list
+ \edef\currentdiscription{#1}%
+ \the\everysetupenumerationcounter}
+
+\appendtoks
+ \dostructurecountersetup\currentenumerationcountername\descriptionparameter
+\to \everysetupenumerationcounter
+
+\def\dodefineenumerationcounter#1% todo: fast inheritance (was mainparameter
+ {\definestructurecounter[#1]%
+ \dosetupenumerationcounter{#1}}
+
+\def\dodefineenumerationcommands#1#2#3#4% since we use \currentdescription, we need an edef
+ {\setevalue{\??dd#3#1\s!parent}{#4}%
+ \unexpanded\setevalue {#3#1}{\noexpand\doenumerationcommand{#1}{#2}{#3}}%
+ \unexpanded\setevalue{\e!start#3#1}{\noexpand\doenumerationstart {#1}{#2}{#3}}%
+ \unexpanded\setevalue{\e!stop #3#1}{\noexpand\doenumerationstop {#1}{#2}{#3}}}
+
+% handle enumeration
+
+\def\currentdescriptionnumber {\csname\??dd\currentdescriptionmain\s!counter\endcsname}% no edef (yet)
+\def\specificdescriptionnumber#1{\csname\??dd#1\s!counter\endcsname}% no edef (yet)
+
+\def\doenumerationinit#1#2#3%
+ {\edef\currentdescriptionmain {#1}%
+ \edef\currentdescriptionlevel{#2}%
+ \edef\currentdescriptionname {#1}%
+ \edef\currentdescription {#3#1}}
+
+\def\doenumerationcommand#1#2#3{\doenumerationinit{#1}{#2}{#3}\dosingleempty\@@description}
+\def\doenumerationstart #1#2#3{\doenumerationinit{#1}{#2}{#3}\dosingleempty\@@startdescription}
+\def\doenumerationstop #1#2#3{\doenumerationinit{#1}{#2}{#3}\@@stopdescription}
+
+\def\doresetenumerationnumber#1#2#3{\doresetsubstructurecounter [\specificdescriptionnumber{#1}][#2]}
+\def\dosetenumerationnumber#1#2#3#4{\dosetsubstructurecounter [\specificdescriptionnumber{#1}][#2]{#4}}
+\def\donextenumerationnumber #1#2#3{\doincrementsubstructurecounter[\specificdescriptionnumber{#1}][#2]}
+
+% implementation
+
+\newtoks \everyenumeration
+\newconditional\enumerationnumberenabled
+\chardef \enumerationcouplingmode \zerocount
+\def \enumerationdisablenumbersignal {-}
+
+\appendtoks \disablepseudocaps \to \everyenumeration % sorry, uppercase causes troubles
+
+\letvalue{\??dd:\c!couplingway:\v!local }\plusone
+\letvalue{\??dd:\c!couplingway:\v!global}\plustwo
+
+\setvalue{\??dd:\v!enumeration:\s!handler }{\@@doenumerationhandler}
+\setvalue{\??dd:\v!enumeration:\s!handler:\s!do }{\@@somedescription}
+\setvalue{\??dd:\v!enumeration:\s!handler:\s!start}{\@@startsomedescription}
+
+\def\@@doenumerationhandler#1%
+ {\strut
+ \ifconditional\enumerationnumberenabled
+ \iftrialtypesetting
+ \doenumerationfullnumber\showdntext{#1}%
+ \doenumerationcouplingsymbol
+ \else
+ \doenumerationregistercoupling
+ \doenumerationfullnumber\showdntext{#1}%
+ \doenumerationcouplingsymbol
+ \fi
+ \else
+ \doenumerationfullnumber\showdnpuretext{#1}%
+ \fi
+ \iftrialtypesetting \else
+ \currentdescriptionsynchronize
+ \fi}
+
+\def\doenumerationsavecounter {\savestructurecounter[\currentdescriptionnumber]}
+\def\doenumerationrestorecounter {\restorestructurecounter[\currentdescriptionnumber]}
+\def\doenumerationincrementcounter{\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]}
+
+\def\doenumerationcheckconditions
+ {\doifelse{\descriptionparameter\c!number}\v!yes
+ {\ifx\currentdescriptionreference\enumerationdisablenumbersignal
+ \setfalse\enumerationnumberenabled \else \settrue\enumerationnumberenabled
+ \fi}%
+ {\setfalse\enumerationnumberenabled}%
+ \chardef\enumerationcouplingmode \iflocation
+ \executeifdefined{\??dd:\c!couplingway:\descriptionparameter\c!coupling}\zerocount
+ \else
+ \zerocount
+ \fi}
+
+\def\doenumerationregistercoupling
+ {\iflocation
+ \ifcase\enumerationcouplingmode
+ \or
+ % todo
+ \or
+ % todo
+ \fi
+ \fi}
+
+\def\doenumerationcouplingsymbol
+ {\iflocation\ifcase\enumerationcouplingmode \else
+ % todo
+ \fi\fi}
+
+\def\currentdescriptiontext
+ {\ctxlua{structure.lists.savedtitle("\currentdescriptionmain",\currentdescriptionnumberentry)}}
+
+\def\currentenumerationfullnumber
+ {\ctxlua{structure.lists.savednumber("\currentdescriptionmain",\currentdescriptionnumberentry)}}
+
+\def\doenumerationfullnumber#1#2% text, title
+ {\begingroup
+ \dosetdescriptionattributes\c!headstyle\c!headcolor
+ \the\everyenumeration
+ \descriptionparameter\c!command
+ {\strut
+ #1%
+ \descriptionparameter\c!left
+ \currentenumerationfullnumber
+ % save cq. treat expansion etc
+ \doifsomething{#2}
+ {\doif{\descriptionparameter\c!title}\v!yes
+ {\begingroup
+ \dosetdescriptionattributes\c!titlestyle\c!titlecolor
+ \hskip\descriptionparameter\c!titledistance
+ \descriptionparameter\c!titlecommand
+ {\descriptionparameter\c!titleleft
+ \begstrut#2\endstrut
+ \descriptionparameter\c!titleright}%
+ \endgroup}}%
+ %
+ \descriptionparameter\c!stopper
+ \descriptionparameter\c!right}%
+ \endgroup}
+
+\def\showdnpuretext{\strut\descriptionparameter\c!text} % geen spatie
+\def\showdnlisttext{\descriptionparameter\c!listtext} % space in default
+\def\showdntext {\doifsomething{\descriptionparameter\c!text}{\descriptionparameter\c!text\removeunwantedspaces\fixedspace}}
+
+\unexpanded\def\structurecounterreference#1%
+ {[enumref: #1]}
+
+% you can use \placeclosesymbol or \qed to place a symbol at the end of a
+% description
+
+\def\@@resetdescriptionclosesymbol
+ {\global\@EA\settrue\csname\??dd\currentdescription:mrk\endcsname
+ \let\placeclosesymbol\@@placedescriptionclosesymbol
+ \let\qed \@@placedescriptionclosesymbol}
+
+\def\@@placedescriptionclosesymbol
+ {\ifconditional\csname\??dd\currentdescription:mrk\endcsname
+ \global\@EA\setfalse\csname\??dd\currentdescription:mrk\endcsname
+ \doifsomething{\descriptionparameter\c!closesymbol}{\descriptionparameter\c!closecommand{\descriptionparameter\c!closesymbol}}%
+ \fi}
+
+\newif\ifnodescriptioncaption
+
+\def\doifelsedescriptioncomponent
+ {\ctxlua{structure.lists.doifstoredelse(currentdescriptionnumberentry)}}
+
+\def\dodescriptioncomponent
+ {\doifelsedescriptioncomponent\nododescriptioncomponent\dododescriptioncomponent}
+
+\def\nododescriptioncomponent[#1][#2]% #1=interfaced-settings, #2=optional user data
+ {}
+
+\def\dododescriptioncomponent[#1][#2]% #1=interfaced-settings, #2=optional user data
+ {\begingroup % similar to structure so we might generalize this
+ \getparameters[\??dd\currentdescription][#1]%
+ \edef\currentdescriptionexpansion{\descriptionparameter\c!expansion}%
+ \ifx\currentdescriptionexpansion\s!xml
+ \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}%
+ \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}%
+ \xmlstartraw
+ \xdef\currentdescriptionlisttitle {\descriptionparameter\c!title}%
+ \xmlstopraw
+ \globallet\currentdescriptioncoding\s!xml
+ \else
+ \ifx\currentdescriptionexpansion\v!yes
+ \xdef\currentdescriptiontitle {\descriptionparameter\c!title}%
+ \xdef\currentdescriptionbookmark{\descriptionparameter\c!bookmark}%
+ \else
+ \xdef\currentdescriptiontitle {\detokenizeddescriptionparameter\c!title}%
+ \xdef\currentdescriptionbookmark{\detokenizeddescriptionparameter\c!bookmark}%
+ \fi
+ \globallet\currentdescriptionlisttitle \currentdescriptiontitle
+ \globallet\currentdescriptioncoding\s!tex
+ \fi
+ \xdef\currentdescriptionlabel {\descriptionparameter\c!label}%
+ \xdef\currentdescriptionreference {\descriptionparameter\c!reference}%
+ %
+ \doif{\descriptionparameter\c!title}\v!none{\global\nodescriptioncaptiontrue\global\nodescriptionnumbertrue}% will become obsolete
+ %
+ \ifconditional\enumerationnumberenabled
+ \doifelsedescriptioncomponent\donothing\doenumerationincrementcounter
+ \fi
+ %
+ \ifnodescriptioncaption
+ \glet\currentdescriptionlistnumber \relax
+ \glet\currentdescriptionsynchronize\relax
+ \else
+ \setnextinternalreference
+ \xdef\currentdescriptionnumberentry{\ctxlua{structure.lists.push{
+ metadata = {
+ kind = "description",
+ name = "\currentdescriptionname",
+ level = structure.sections.currentlevel(),
+ catcodes = \the\catcodetable,
+ },
+ references = {
+ internal = \nextinternalreference,
+ reference = "\currentdescriptionreference",
+ referenceprefix = "\referenceprefix",
+ block = "\currentstructureblock",
+ section = structure.sections.currentid(),
+ },
+ titledata = {
+ label = \!!bs\detokenize\expandafter{\currentdescriptionlabel }\!!es,
+ title = \!!bs\detokenize\expandafter{\currentdescriptiontitle }\!!es,
+ \ifx\currentdescriptionbookmark\currentdescriptiontitle \else
+ bookmark = \!!bs\detokenize\expandafter{\currentdescriptionbookmark}\!!es,
+ \fi
+ \ifx\currentdescriptionlisttitle\currentdescriptiontitle \else % \ifx\currentdescriptionsaveinlist\v!no
+ list = \!!bs\detokenize\expandafter{\currentdescriptionlisttitle }\!!es,
+ \fi % \fi
+ },
+ \ifconditional\enumerationnumberenabled
+ prefixdata = {
+ prefix = "\descriptionparameter\c!prefix",
+ separatorset = "\descriptionparameter\c!prefixseparatorset",
+ conversion = \!!bs\descriptionparameter\c!prefixconversion\!!es,
+ conversionset = "\descriptionparameter\c!prefixconversionset",
+ set = "\descriptionparameter\c!prefixset",
+ segments = "\descriptionparameter\c!prefixsegments",
+ connector = \!!bs\descriptionparameter\c!prefixconnector\!!es,
+ },
+ numberdata = {
+ numbers = structure.counters.compact("\currentdescriptionname",nil,true),
+ separatorset = "\descriptionparameter\c!numberseparatorset",
+ conversion = "\descriptionparameter\c!numberconversion",
+ conversionset = "\descriptionparameter\c!numberconversionset",
+ stopper = \!!bs\descriptionparameter\c!numberstopper\!!es,
+ segments = "\descriptionparameter\c!numbersegments",
+ },
+ \fi
+ userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es)
+ }
+ }}%
+ \xdef\currentdescriptionsynchronize % make this a macro because shared
+ {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}%
+ \noexpand\ctxlatelua{structure.lists.enhance(\currentdescriptionnumberentry)}}%
+ \fi
+ \endgroup}
+
+\installstructurelistprocessor{description}{\usestructurelistprocessor{number+title}}
+
+% labels, we could share with enumerations and forget about the text; anyhow, figure
+% labels etc can use enumerations; we keep labels for compatibility reasons; we need
+% the slightly different namespace; we can still define structure counters directly
+% (multiple levels) and use an enumeration without following text
+
+% unfinished
+
+\def\setuplabels
+ {\getparameters[\??db]}
+
+\def\definelabel
+ {\dotripleargumentwithset\dodefinelabel}
+
+\def\dodefinelabel[#1][#2][#3]% #2 or #3 assignment
+ {\doenumerationinit{#1}{1}\empty
+ \getparameters[\??dd#1][\c!command=,\c!state=\v!start,\c!location=,\c!text=#1]%
+ \ifsecondargument\doifassignmentelse{#2}\donetrue\donefalse\else\donetrue\fi
+ \ifdone
+ % an independent one
+ \getparameters[\??dd#1][\s!counter=#1,\s!parent=\??db,#2]%
+ \dodefinelabelcommands{#1}{\??db}%
+ \dodefineenumerationcounter{#1}%
+ \else
+ \getparameters[\??dd#1][\s!counter=#1,\s!parent=\??dd#2,#3]%
+ \dodefinelabelcommands{#1}{\??dd#2}%
+ \fi}
+
+\def\dodefinelabelcommands#1#2%
+ {\unexpanded\setevalue {#1}{\noexpand\dolabelnumbercommand {#1}}%
+ \unexpanded\setevalue{\c!reset #1}{\noexpand\doresetlabelnumber {#1}}%
+ %\unexpanded\setevalue{\c!set #1}{\noexpand\dosetlabelnumber {#1}}% [#2] or {#2} ?
+ \unexpanded\setevalue{\e!next #1}{\noexpand\donextlabelnumber {#1}}%
+ \unexpanded\setevalue{\e!increment#1}{\noexpand\doincrementlabelnumber{#1}}%
+ \unexpanded\setevalue{\c!current #1}{\noexpand\docurrentlabelnumber {#1}}}
+
+% this is just for downward compatibility, we might drop it
+
+\setvalue{\??db:\c!location:\v!inmargin}{\inmargin}
+\setvalue{\??db:\c!location:\v!inleft }{\inleft}
+\setvalue{\??db:\c!location:\v!inright }{\inright}
+\setvalue{\??db:\c!location:\v!margin }{\inmargin}
+
+\def\dolabelinit#1%
+ {\def\currentdescriptionmain{#1}%
+ \def\currentdescription {#1}%
+ \def\currentdescriptionlevel{1}}
+
+\def\docurrentlabelnumber #1{\dolabelinit{#1}\dosingleempty\dodocurrentlabelnumber}
+\def\donextlabelnumber #1{\dolabelinit{#1}\dosingleempty\dodonextlabelnumber}
+\def\dolabelnumbercommand #1{\dolabelinit{#1}\dosingleempty\dodolabelnumbercommand}
+
+\def\doresetlabelnumber #1{\dolabelinit{#1}\doresetsubstructurecounter [\currentdescriptionnumber][\currentdescriptionlevel]}
+\def\dosetlabelnumber #1#2{\dolabelinit{#1}\dosetsubstructurecounter [\currentdescriptionnumber][\currentdescriptionlevel]{#2}}
+\def\doincrementlabelnumber #1{\dolabelinit{#1}\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]}
+
+\def\dodocurrentlabelnumber[#1]%
+ {\dontleavehmode
+ \writestatus{!!!}{todo: reference of label}%
+% \rawreference{lab}{#1}{\composedsectionnumber}%
+ \dotextprefix{\descriptionparameter\c!text}%
+ \convertedsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]}
+
+\def\dodonextlabelnumber[#1]% todo: ref
+ {\doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]%
+ \dodocurrentlabelnumber[\currentdescriptionnumber]}
+
+\def\dodolabelnumbercommand[#1]% todo: ref
+ {\dontleavehmode
+ \descriptionparameter\c!before
+ \begingroup
+ \doincrementsubstructurecounter[\currentdescriptionnumber][\currentdescriptionlevel]%
+ \dosetdescriptionattributes\c!headstyle\c!headcolor
+ \executeifdefined{\??db:\c!location:\descriptionparameter\c!location}{\descriptionparameter\c!command}{\dodocurrentlabelnumber[#1]}%
+ \endgroup
+ \descriptionparameter\c!after}
+
+% to be reimplmented
+
+\def\setupindentations
+ {\dodoubleempty\dosetupindentations}
+
+\def\dosetupindentations[#1][#2]%
+ {\ifsecondargument
+ \dodoubleargumentwithset\dodosetupindentations[#1][#2]%
+ \else
+ \dodosetupindentations[][#1]%
+ \fi}
+
+\def\dodosetupindentations[#1][#2]%
+ {\getparameters[\??ds#1][#2]}
+
+\def\defineindenting
+ {\dodoubleargumentwithset\dodefineindenting}
+
+\def\dodefineindenting[#1][#2]%
+ {\copyparameters[\??ds#1][\??ds]
+ [\c!text,\c!separator,\c!width,\c!style,\c!color,
+ \c!headstyle,\c!sample,\c!before,\c!after,\c!distance]%
+ \getparameters[\??ds#1][#2]%
+ \unexpanded\setvalue {#1}{\dododefineindenting{#1}{0}{1}}%
+ \unexpanded\setvalue {\v!sub#1}{\dododefineindenting{#1}{1}{2}}%
+ \unexpanded\setvalue{\v!sub\v!sub#1}{\dododefineindenting{#1}{2}{3}}}
+
+\def\dododefineindenting#1#2#3%
+ {\par
+ \getvalue{\??ds#1\c!before}%
+ \begingroup
+ \doifvaluenothing{\??ds#1\c!sample}
+ {\setvalue{\??ds#1\c!sample}{\getvalue{\??ds#1\c!text}}}%
+ \assignwidth
+ {\descriptionsheadwidth}
+ {\getvalue{\??ds#1\c!width}}
+ {\doattributes
+ {\??ds#1}\c!headstyle\c!headcolor
+ {\getvalue{\??ds#1\c!sample}%
+ \spr{\getvalue{\??ds#1\c!separator}}}}
+ {\getvalue{\??ds#1\c!distance}}%
+ \advance\descriptionsheadwidth \getvalue{\??ds#1\c!distance}%
+ \setbox\scratchbox\hbox to \descriptionsheadwidth
+ {\doattributes
+ {\??ds#1}\c!headstyle\c!headcolor
+ {\strut
+ \getvalue{\??ds#1\c!text}%
+ \hss
+ \spr{\getvalue{\??ds#1\c!separator}}%
+ \hskip\getvalue{\??ds#1\c!distance}}}%
+ \parindent\zeropoint
+ \hskip#2\descriptionsheadwidth\indent\box\scratchbox
+ \hangindent#3\descriptionsheadwidth
+ \doattributes{\??ds#1}\c!style\c!color\empty
+ \AfterPar{\endgroup\getvalue{\??ds#1\c!after}}% must be redone
+ \GetPar}
+
+\setupdescriptions
+ [\c!location=\v!left,
+ \c!headstyle=\v!bold,
+ \c!titlestyle=\v!bold,
+ \c!style=\v!normal,
+ \c!color=,
+ \c!headcolor=,
+ \c!titlecolor=,
+ \c!width=8em,
+ \c!distance=0pt,
+ \c!titledistance=0.5em,
+ \c!hang=,
+ \c!sample=,
+ \c!align=,
+ \c!margin=\v!no,
+ \c!before=\blank,
+ \c!inbetween=\blank,
+ \c!after=\blank,
+ \c!indentnext=\v!yes,
+ \c!indenting=\v!never,
+ \c!titleleft=(,
+ \c!titleright=),
+ \c!closesymbol=,
+ \c!closecommand=\wordright,
+ \c!command=,
+ \c!titlecommand=]
+
+\setupenumerations
+ [\c!location=\v!top,
+% \c!headstyle=\v!bold,
+% \c!titlestyle=\v!bold,
+% \c!style=\v!normal,
+% \c!headcolor=,
+% \c!titlecolor=,
+% \c!color=,
+% \c!width=8em,
+% \c!distance=0pt,
+% \c!titledistance=0.5em,
+% \c!hang=,
+% \c!sample=,
+% \c!align=,
+% \c!margin=\v!no,
+% \c!before=\blank,
+% \c!inbetween=\blank,
+% \c!after=\blank,
+% \c!indentnext=\v!yes,
+% \c!indenting=\v!never,
+% \c!titleleft=(,
+% \c!titleright=),
+% \c!closesymbol=,
+% \c!closecommand=\wordright,
+% \c!command=,
+% \c!titlecommand=,
+ \c!text=,
+ \c!way=\v!by\v!text,
+ \c!prefixconnector=.,
+ \c!stopper=,
+ \c!number=\v!yes, % else description
+ \c!start=0,
+ \s!parent=\??dd]
+
+\setuplabels
+ [\s!parent=\??dn]
+
+\setupindentations
+ [\c!style=\v!normal,
+ \c!headstyle=\v!normal,
+ \c!color=,
+ \c!headcolor=,
+ \c!width=\v!fit,
+ \c!text=\unknown,
+ \c!sample=,
+ \c!before=\blank,
+ \c!after=\blank,
+ \c!distance=1em,
+ \c!separator={ :}]
+
+\protect \endinput
diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua
new file mode 100644
index 000000000..e0df8294a
--- /dev/null
+++ b/tex/context/base/strc-doc.lua
@@ -0,0 +1,569 @@
+if not modules then modules = { } end modules ['strc-doc'] = {
+ version = 1.001,
+ comment = "companion to strc-doc.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+local format, gsub, find, concat = string.format, string.gsub, string.find, table.concat
+local texsprint, texwrite = tex.sprint, tex.write
+
+local ctxcatcodes = tex.ctxcatcodes
+
+if not trackers then trackers = { register = function() end } end
+
+local trace_sectioning = false trackers.register("structure.sectioning", function(v) trace_sectioning = v end)
+
+local function report(...)
+--~ print(...)
+ logs.report("sectioning:",...)
+end
+
+structure = structure or { }
+structure.helpers = structure.helpers or { }
+structure.documents = structure.documents or { }
+structure.sections = structure.sections or { }
+structure.sets = structure.sets or { }
+structure.processors = structure.processors or { }
+
+local helpers = structure.helpers
+local documents = structure.documents
+local sections = structure.sections
+local sets = structure.sets
+local processors = structure.processors
+
+-- -- -- document -- -- --
+
+local data
+
+function documents.initialize()
+ data = {
+ numbers = { },
+ ownnumbers = { },
+ status = { },
+ checkers = { },
+ depth = 0,
+ blocks = { },
+ block = "",
+ }
+ documents.data = data
+end
+
+function documents.reset()
+ data.numbers = { }
+ data.ownnumbers = { }
+ data.status = { }
+ data.checkers = { }
+ data.depth = 0
+end
+
+documents.initialize()
+
+-- -- -- sections -- -- --
+
+jobsections = jobsections or { }
+jobsections.collected = jobsections.collected or { }
+jobsections.tobesaved = jobsections.tobesaved or { }
+
+local collected, tobesaved = jobsections.collected, jobsections.tobesaved
+
+--~ local function initializer()
+--~ collected, tobesaved = jobsections.collected, jobsections.tobesaved
+--~ end
+
+--~ job.register('jobsections.collected', jobsections.tobesaved, initializer)
+
+function sections.currentid()
+ return #tobesaved
+end
+
+function sections.save(sectiondata)
+-- local sectionnumber = helpers.simplify(section.sectiondata) -- maybe done earlier
+ local numberdata = sectiondata.numberdata
+ if not numberdata or sectiondata.metadata.nolist then
+ return #tobesaved
+ else
+ local n = #tobesaved + 1
+ tobesaved[n] = numberdata
+ if not collected[n] then
+ collected[n] = numberdata
+ end
+ return n
+ end
+end
+
+function sections.load()
+ setmetatable(collected,nil)
+ local l = structure.lists.collected
+ for i=1,#l do
+ local li = l[i]
+ local lm = li.metadata
+ if lm and lm.kind == "section" and not lm.nolist then
+ local ln = li.numberdata
+ if ln then
+ collected[#collected+1] = ln
+ end
+ end
+ end
+ sections.load = nil
+end
+
+setmetatable(collected, {
+ __index = function(t,i)
+ sections.load()
+ return t[i] or { }
+ end
+})
+
+--
+
+structure.sections.levelmap = structure.sections.levelmap or { }
+
+local levelmap = structure.sections.levelmap
+
+storage.register("structure/sections/levelmap", structure.sections.levelmap, "structure.sections.levelmap")
+
+sections.verbose = true
+
+function sections.setlevel(name,level) -- level can be number or parent (=string)
+ local l = tonumber(level)
+ if not l then
+ l = levelmap[level]
+ end
+ if l and l > 0 then
+ levelmap[name] = l
+ else
+ -- error
+ end
+end
+
+function sections.getlevel(name)
+ return levelmap[name] or 0
+end
+
+function sections.way(way,by)
+ texsprint(ctxcatcodes,(gsub(way,"^"..by,"")))
+end
+
+function sections.setblock(name)
+ local block = name or data.block or "unknown" -- can be used to set the default
+ data.block = block
+ texwrite(block)
+end
+
+function sections.pushblock(name)
+ local block = name or data.block
+ data.blocks[#data.blocks+1] = block
+ data.block = block
+ documents.reset()
+ texwrite(block)
+end
+
+function sections.popblock()
+ data.blocks[#data.blocks] = nil
+ local block = data.blocks[#data.blocks] or data.block
+ data.block = block
+ documents.reset()
+ texwrite(block)
+end
+
+function sections.currentblock()
+ return data.block or data.blocks[#data.blocks] or "unknown"
+end
+
+function sections.currentlevel()
+ return data.depth
+end
+
+function sections.getcurrentlevel()
+ texwrite(data.depth)
+end
+
+function sections.nextlevel()
+ local depth = data.depth + 1
+ data.depth = depth
+ return depth
+end
+
+function sections.prevlevel()
+ local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth
+ local resetter = sets.getall("structure:resets",data.block,status[depth].resets or "")
+ local rd = resetter and resetter[depth]
+ numbers[depth] = (rd and rd > 0 and rd < depth and numbers[depth]) or 0
+ status[depth] = nil
+ depth = depth - 1
+ data.depth = depth
+ return depth
+end
+
+function sections.somelevel(t)
+ local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth
+ local d = tonumber(levelmap[t.metadata.name] or (depth > 0 and depth) or 1)
+ local resetter = sets.getall("structure:resets",data.block,(t and t.resets) or "")
+ local previous = { }
+ if d > depth then
+ local rd = resetter and resetter[i]
+ for i=depth+1,d do
+ numbers[i] = (rd and rd[i] and rd[i] > 0 and rd[i] < i and numbers[i]) or 0
+ status[i] = { }
+ end
+ elseif d < depth then
+ local rd = resetter and resetter[i]
+ for i=depth,d+1,-1 do
+ numbers[i] = (rd and rd[i] and rd[i] > 0 and rd[i] < i and numbers[i]) or 0
+ status[i] = nil
+ end
+ end
+ for i=1,d do
+ -- selective resetter
+ if numbers[i] == 0 then
+ ownnumbers[i] = ""
+ end
+ end
+ -- a trick to permits userdata to overload title, ownnumber and reference
+ -- normally these are passed as argument but nowadays we provide several
+ -- interfaces (we need this because we want to be compatible)
+ local u = t.userdata
+ if u then
+ if u.reference and u.reference ~= "" then t.metadata.reference = u.reference ; u.reference = nil end
+ if u.ownnumber and u.ownnumber ~= "" then t.numberdata.ownnumber = u.ownnumber ; u.ownnumber = nil end
+ if u.title and u.title ~= "" then t.titledata.title = u.title ; u.title = nil end
+ if u.bookmark and u.bookmark ~= "" then t.titledata.bookmark = u.bookmark ; u.bookmark = nil end
+ if u.label and u.label ~= "" then t.titledata.label = u.label ; u.label = nil end
+ end
+ -- so far for the trick
+ ownnumbers[d] = t.numberdata.ownnumber or ""
+ t.numberdata.ownnumber = nil
+-- t.numberdata = helpers.simplify(t.numberdata)
+ data.depth = d
+ sections.pluslevel(t)
+end
+
+function sections.writestatus()
+ if sections.verbose then
+ local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth
+ local d = status[depth]
+ local o = concat(ownnumbers,".",1,depth)
+ local n = (numbers and concat(numbers,".",1,depth)) or 0
+ local l = d.titledata.title or ""
+ local t = (l ~= "" and l) or d.titledata.title or "[no title]"
+ local m = d.metadata.name
+ if o and not find(o,"^%.*$") then
+ commands.writestatus("structure","%s @ level %i : (%s) %s -> %s",m,depth,n,o,t)
+ elseif d.directives and d.directives.hidenumber then
+ commands.writestatus("structure","%s @ level %i : (%s) -> %s",m,depth,n,t)
+ else
+ commands.writestatus("structure","%s @ level %i : %s -> %s",m,depth,n,t)
+ end
+ end
+end
+
+function sections.pluslevel(t)
+ -- data has saved level data
+ local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth
+ local directives = t.directives
+ local resetter = sets.getall("structure:resets",data.block, (directives and directives.resetset) or "")
+ if not (directives and directives.hidenumber) then
+ if numbers[depth] then
+ numbers[depth] = numbers[depth] + 1
+ else
+ numbers[depth] = 1
+ end
+ end
+ for k, v in pairs(resetter) do -- sparse
+ if v > 0 and depth == v then
+ numbers[k] = 0
+ end
+ end
+ status[depth] = t or { }
+ for k, v in pairs(data.checkers) do
+ if v[1] == depth and v[2] then
+ v[2](k)
+ end
+ end
+ local numberdata= t.numberdata
+ if not numberdata then
+ -- probably simplified to nothing
+ numberdata = { }
+ t.numberdata = numberdata
+ end
+ numberdata.numbers = table.fastcopy(numbers)
+ if #ownnumbers > 0 then
+ numberdata.ownnumbers = table.fastcopy(ownnumbers)
+ end
+ t.references.section = sections.save(t)
+--~ t.numberdata = nil
+end
+
+function sections.setnumber(depth,n)
+ local numbers, depth = data.numbers, data.depth
+ local d = numbers[depth]
+ if type(n) == "string" then
+ if n:find("^[%+%-]") then
+ d = d + tonumber(n)
+ else
+ d = tonumber(n)
+ end
+ else
+ d = n
+ end
+ numbers[depth] = d
+ -- todo reset
+end
+
+function sections.number_at_depth(depth)
+ return data.numbers[tonumber(depth) or sections.getlevel(depth) or 0] or 0
+end
+
+function sections.getnumber(depth)
+ return texwrite(data.numbers[depth] or 0)
+end
+
+function sections.set(key,value)
+ data.status[data.depth][key] = value -- may be nil for a reset
+end
+
+function sections.cct()
+ local metadata = data.status[data.depth].metadata
+ texsprint((metadata and metadata.catcodes) or ctxcatcodes)
+end
+
+function sections.get(key,default,honorcatcodetable)
+ local data = data.status[data.depth]
+ local d = data
+ for k in key:gmatch("([^.]+)") do
+ if type(d) == "table" then
+ d = d[k]
+ if not d then
+ -- unknown key
+ break
+ end
+ end
+ if type(d) == "string" then
+ if honorcatcodetable then
+ local metadata = data.metadata
+ texsprint((metadata and metadata.catcodes) or ctxcatcodes,d)
+ else
+ texsprint(ctxcatcodes,d)
+ end
+ return
+ end
+ end
+ if default then
+ texsprint(ctxcatcodes,default)
+ end
+end
+
+function sections.getuser(key,default)
+ local userdata = data.status[data.depth].userdata
+ local str = (userdata and userdata[key]) or default
+ if str then
+ texsprint(ctxcatcodes,str)
+ end
+end
+
+function sections.setchecker(name,level,command)
+ data.checkers[name] = (name and command and level > 0 and { level, command }) or nil
+end
+
+function sections.current()
+ return data.status[data.depth]
+end
+
+function sections.depthnumber(n)
+ local depth = data.depth
+ if not n or n == 0 then
+ n = depth
+ elseif n < 0 then
+ n = depth + n
+ end
+ return texwrite(data.numbers[n] or 0)
+end
+
+function sections.autodepth(numbers)
+ for i=#numbers,1,-1 do
+ if numbers[i] ~= 0 then
+ return i
+ end
+ end
+ return 0
+end
+
+--
+
+function structure.currentsectionnumber() -- brr, namespace wrong
+ local sc = sections.current()
+ return sc and sc.numberdata
+end
+
+-- \dorecurse{3} {
+-- \chapter{Blabla} \subsection{bla 1 1} \subsection{bla 1 2}
+-- \section{bla 2} \subsection{bla 2 1} \subsection{bla 2 2}
+-- }
+
+function sections.typesetnumber(entry,kind,...) -- kind='section','number','prefix'
+ if entry then
+ local separatorset = ""
+ local conversionset = ""
+ local conversion = ""
+ local stopper = ""
+ local connector = ""
+ local set = ""
+ local segments = ""
+ for _, data in ipairs { ... } do
+ if data then
+ if separatorset == "" then separatorset = data.separatorset or "" end
+ if conversionset == "" then conversionset = data.conversionset or "" end
+ if conversion == "" then conversion = data.conversion or "" end
+ if stopper == "" then stopper = data.stopper or "" end
+ if connector == "" then connector = data.connector or "" end
+ if set == "" then set = data.set or "" end
+ if segments == "" then segments = data.segments or "" end
+ end
+ end
+ if separatorset == "" then separatorset = "default" end
+ if conversionset == "" then conversionset = "default" end
+ if conversion == "" then conversion = nil end
+ if stopper == "" then stopper = nil end
+ if connector == "" then connector = nil end
+ if set == "" then set = "default" end
+ if segments == "" then segments = nil end
+ --
+ local firstprefix, lastprefix = 0, 100
+ if segments then
+ local f, l = (tostring(segments)):match("^(.-):(.+)$")
+ if f and l then
+ -- 0:100, chapter:subsubsection
+ firstprefix = tonumber(f) or sections.getlevel(f) or 0
+ lastprefix = tonumber(l) or sections.getlevel(l) or 100
+ else
+ -- 3, section
+ local fl = tonumber(segments) or sections.getlevel(segments) -- generalize
+ if fl then
+ firstprefix, lastprefix = fl, fl
+ end
+ end
+ end
+ --
+ local numbers, ownnumbers = entry.numbers, entry.ownnumbers
+ if numbers then
+ local done, preceding = false, false
+ local function process(index) -- move to outer
+ local number = numbers and (numbers[index] or 0)
+ local ownnumber = ownnumbers and ownnumbers[index] or ""
+ if number > 0 or (ownnumber ~= "") then
+ local block = entry.block
+ if preceding then
+ local separator = sets.get("structure:separators",b,s,preceding,".")
+ if separator then
+ processors.sprint(ctxcatcodes,separator)
+ end
+ preceding = false
+ end
+ if ownnumber ~= "" then
+ processors.sprint(ctxcatcodes,ownnumber)
+ -- elseif conversion and conversion ~= "" then
+ -- tex.sprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
+ elseif conversion and conversion ~= "" then
+ -- traditional (e.g. used in itemgroups)
+ tex.sprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
+ else
+ local theconversion = sets.get("structure:conversions",block,conversion,index,"numbers")
+ processors.sprint(ctxcatcodes,theconversion,function(str)
+ return format("\\convertnumber{%s}{%s}",str or "numbers",number)
+ end)
+ end
+ preceding, done = index, true
+ else
+ preceding = preceding or false
+ end
+ end
+ --
+ local prefixlist = set and sets.getall("structure:prefixes","",set) -- "" == block
+ --
+ if prefixlist and (kind == 'section' or kind == 'prefix') then
+ -- find valid set (problem: for sectionnumber we should pass the level)
+ -- if kind == "section" then
+ -- no holes
+ local b, e, bb, ee = 1, #prefixlist, 0, 0
+ -- find last valid number
+ for k=e,b,-1 do
+ local prefix = prefixlist[k]
+ local index = sections.getlevel(prefix) or k
+ if index >= firstprefix and index <= lastprefix then
+ local number = numbers and numbers[index]
+ if number then
+ local ownnumber = ownnumbers and ownnumbers[index] or ""
+ if number > 0 or (ownnumber ~= "") then
+ break
+ else
+ e = k -1
+ end
+ end
+ end
+ end
+ -- find valid range
+ for k=b,e do
+ local prefix = prefixlist[k]
+ local index = sections.getlevel(prefix) or k
+ if index >= firstprefix and index <= lastprefix then
+ local number = numbers and numbers[index]
+ if number then
+ local ownnumber = ownnumbers and ownnumbers[index] or ""
+ if number > 0 or (ownnumber ~= "") then
+ if bb == 0 then bb = k end
+ ee = k
+ else
+ bb, ee = 0, 0
+ end
+ else
+ break
+ end
+ end
+ end
+ -- print valid range
+ for k=bb,ee do
+ local prefix = prefixlist[k]
+ local index = sections.getlevel(prefix) or k
+ if index >= firstprefix and index <= lastprefix then
+ process(index)
+ end
+ end
+ -- else
+ -- for k=1,#prefixlist do
+ -- local prefix = prefixlist[k]
+ -- local index = sections.getlevel(prefix) or k
+ -- if index >= firstprefix and index <= lastprefix then
+ -- process(index)
+ -- end
+ -- end
+ -- end
+ else
+ -- also holes check
+ for prefix=firstprefix,lastprefix do
+ process(prefix)
+ end
+ end
+ --
+ if done and connector and kind == 'prefix' then
+ processors.sprint(ctxcatcodes,connector)
+ elseif done and stopper then
+ processors.sprint(ctxcatcodes,stopper)
+ end
+ else
+ report("error: no numbers")
+ end
+ end
+end
+
+function sections.fullnumber(depth)
+ local data = data.status[depth or data.depth]
+ if data then
+ local sectiondata = jobsections.collected[data.references.section]
+ if sectiondata then
+ sections.typesetnumber(sectiondata,'section',sectiondata)
+ end
+ end
+end
diff --git a/tex/context/base/strc-doc.tex b/tex/context/base/strc-doc.tex
new file mode 100644
index 000000000..e76e015a9
--- /dev/null
+++ b/tex/context/base/strc-doc.tex
@@ -0,0 +1,166 @@
+%D \module
+%D [ file=strc-doc,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Document Structure,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Document Structure}
+
+\registerctxluafile{strc-doc}{1.001}
+
+\unprotect
+
+% We operate in a \type {@@ns} namespace. All data is passed through
+% variables. Of course we can built another interface on top of this
+% that accepts multiple arguments. We might change this approach and
+% remove this layer.
+
+\def\currentstructurecounter{0}
+
+\definesystemvariable {ns}
+
+\def\structureparameter#1{\csname\??ns#1\endcsname}
+
+\def\detokenizedstructureparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??ns#1\endcsname}}
+
+\def\structurecomponent{\dodoubleempty\dostructurecomponent}
+
+\getparameters % initialization, used not grouped anyway
+ [\??ns]
+ [\c!number=,\c!level=,\c!name=,\c!title=,\c!bookmark=,\c!label=,\c!coupling=,\c!ownnumber=,
+ \c!sectionseparatorset=\s!default,\c!sectionconversionset=\s!default,
+ \c!sectionstopper=,\c!sectionsegments=,
+ \c!reset=,\c!reference=,
+ \c!expansion=\v!no,
+ \c!saveinlist=\v!yes,
+ \c!command=\showstructuredata]
+
+\def\dostructurecomponent[#1][#2]% #1=interfaced-settings, #2=optional user data (not yet supported)
+ {\begingroup
+ \getparameters[\??ns][#1]%
+ \xdef\currentstructurename {\structureparameter\c!name}%
+ \xdef\currentstructurecoupling {\structureparameter\c!coupling}%
+ \xdef\currentstructureownnumber{\structureparameter\c!ownnumber}% optional own number
+ \xdef\currentstructurelevel {\structureparameter\c!level}%
+ \edef\currentstructureexpansion{\structureparameter\c!expansion}
+ \ifx\currentstructureexpansion\s!xml
+ % goes via lua anyway
+ \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}%
+ \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}%
+ %
+ \xmlstartraw
+ \xdef\currentstructurelisttitle {\structureparameter\c!title}%
+ \xmlstopraw
+ \globallet\currentstructurecoding\s!xml
+ \else
+ \ifx\currentstructureexpansion\v!yes
+ \xdef\currentstructuretitle {\structureparameter\c!title}%
+ \xdef\currentstructurebookmark{\structureparameter\c!bookmark}%
+ \else
+ \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}%
+ \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}%
+ \iflocation \ifx\currentstructurebookmark\empty
+ \begingroup
+ \simplifycommands
+ \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}%
+ \endgroup
+ \fi \fi
+ \fi
+ \globallet\currentstructurelisttitle \currentstructuretitle
+ \globallet\currentstructurecoding\s!tex
+ \fi
+ \xdef\currentstructurelabel {\structureparameter\c!label}%
+ \xdef\currentstructurereference {\structureparameter\c!reference}%
+ \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}%
+ \xdef\currentstructureshownumber {\structureparameter\c!number}%
+ \xdef\currentstructuresaveinlist {\structureparameter\c!saveinlist}%
+ \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}%
+ \setnextinternalreference
+ \xdef\currentstructurenumber{\ctxlua{ % todo: combine with next call, adapt marks accordingly
+ structure.sections.somelevel {
+ references = {
+ internal = \nextinternalreference,
+ block = "\currentstructureblock",
+ reference = "\currentstructurereference",
+ referenceprefix = "\currentstructurereferenceprefix",
+ },
+ directives = {
+ resetset = "\structureparameter\c!reset",
+ hidenumber = not toboolean("\currentstructureincrementnumber",true), % incremented but hidden
+ },
+ metadata = {
+ kind = "section",
+ name = "\currentstructurename",
+ catcodes = \the\catcodetable,
+ coding = "\currentstructurecoding",
+ xmlroot = \ifx\currentstructurecoding\s!xml "\xmldocument" \else nil \fi,
+ \ifx\currentstructuresaveinlist\v!no
+ nolist = true,
+ \fi
+ },
+ titledata = { % we can add mark and reference
+ label = \!!bs\detokenize\expandafter{\currentstructurelabel }\!!es,
+ title = \!!bs\detokenize\expandafter{\currentstructuretitle }\!!es,
+ \ifx\currentstructurebookmark\currentstructuretitle \else
+ bookmark = \!!bs\detokenize\expandafter{\currentstructurebookmark }\!!es,
+ \fi
+ \ifx\currentstructurelisttitle\currentstructuretitle \else \ifx\currentstructuresaveinlist\v!no
+ list = \!!bs\detokenize\expandafter{\currentstructurelisttitle}\!!es,
+ \fi \fi
+ },
+ numberdata = {
+ separatorset = "\structureparameter\c!sectionseparatorset",
+ conversion = "\structureparameter\c!sectionconversion", % for good old times sake
+ conversionset = "\structureparameter\c!sectionconversionset",
+ stopper = \!!bs\structureparameter\c!sectionstopper\!!es,
+ set = "\structureparameter\c!sectionset",
+ segments = "\structureparameter\c!sectionsegments",
+ ownnumber = "\currentstructureownnumber",
+ hidenumber = \ifx\currentstructureshownumber\v!no true\else nil\fi, % titles
+ },
+ userdata = structure.helpers.touserdata(\!!bs\detokenize{#2}\!!es)
+ }
+ }}%
+ \xdef\currentstructurelistnumber{\ctxlua{structure.lists.push(structure.sections.current())}}%
+ % \currentstructuresynchronize has to be called someplace, since it introduces a node
+ \setstructuresynchronization\currentstructurelistnumber
+ \structureparameter\c!command
+ \endgroup}
+
+\let\currentstructurenumber \!!zerocount
+\let\currentstructurecounter \!!zerocount
+\let\previousstructurecounter\!!zerocount
+
+\def\setstructuresynchronization#1%
+ {\xdef\currentstructuresynchronize
+ {\noexpand\ctxlua{jobreferences.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference)}%
+ \noexpand\ctxlatelua{structure.lists.enhance(#1)}}}
+
+\def\reportcurrentstructure{\ctxlua{structure.sections.writestatus()}}
+
+% Beware: we need to flush the data to the list explicitly. This is because
+% node in inserted and we may want control over when that happens.
+
+\def\showstructuredata
+ {\par
+ \dontleavehmode
+ \currentstructuresynchronize
+ [\currentstructurename: \showstructurelevel: \currentstructuretitle]
+ \par}
+
+% We can access the (stored) data with the following macros.
+
+\def\structurevalue #1{\ctxlua{structure.sections.get("#1")}}
+\def\structureuservalue#1{\ctxlua{structure.sections.getuser("#1")}}
+\def\structurenumber {\ctxlua{structure.sections.fullnumber()}}
+
+\def\structurecctvalue #1{\ctxlua{structure.sections.get("#1",nil,true)}}
+
+\protect \endinput
diff --git a/tex/context/base/strc-flt.lua b/tex/context/base/strc-flt.lua
new file mode 100644
index 000000000..f6f3e19cc
--- /dev/null
+++ b/tex/context/base/strc-flt.lua
@@ -0,0 +1,9 @@
+if not modules then modules = { } end modules ['strc-flt'] = {
+ version = 1.001,
+ comment = "companion to strc-flt.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- nothing
diff --git a/tex/context/base/strc-flt.tex b/tex/context/base/strc-flt.tex
new file mode 100644
index 000000000..b0ff9893b
--- /dev/null
+++ b/tex/context/base/strc-flt.tex
@@ -0,0 +1,2173 @@
+%D \module
+%D [ file=strc-flt,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Float Numbering,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Float Numbering}
+
+\registerctxluafile{strc-flt}{1.001}
+
+\unprotect
+
+%D This module needs a cleanup and will be split in
+%D strc-flt.tex and page-flt.mkiv cq. page-flt.mkii.
+
+\ifx\addlocalbackgroundtobox\undefined \def\addlocalbackgroundtobox{\resetglobal\gobbleoneargument} \fi
+
+\def\placefloats{\doflushfloats} % keep this one
+
+\let\currentfloat\empty
+
+\def\letfloatparameter #1{\expandafter\csname\??fl\currentfloat#1\endcsname}
+
+\def\floatparameter #1{\csname\dofloatparameter{\??fl\currentfloat}#1\endcsname}
+\def\floatsharedparameter#1{\csname \??fl #1\endcsname}
+\def\floatparameterhash #1{\dofloatparameterhash {\??fl\currentfloat}#1}
+
+\def\dofloatparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dofloatparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\dofloatparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dofloatparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dofloatparentparameter #1#2{\ifx#1\relax\s!empty\else\dofloatparameter #1#2\fi}
+\def\dofloatparentparameterhash#1#2{\ifx#1\relax \else\dofloatparameterhash#1#2\fi}
+
+\def\detokenizedfloatparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??fl\currentfloat#1\endcsname}}
+
+\def\dosetfloatattributes#1#2% style color
+ {\edef\fontattributehash {\floatparameterhash#1}%
+ \edef\colorattributehash{\floatparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+\def\floatcaptionparameter #1{\csname\dofloatcaptionparameter{\??kj\currentfloat}#1\endcsname}
+\def\floatcaptionparameterhash#1{\dofloatcaptionparameterhash {\??kj\currentfloat}#1}
+
+\def\dofloatcaptionparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dofloatcaptionparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\dofloatcaptionparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dofloatcaptionparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dofloatcaptionparentparameter #1#2{\ifx#1\relax\s!empty\else\dofloatcaptionparameter #1#2\fi}
+\def\dofloatcaptionparentparameterhash#1#2{\ifx#1\relax \else\dofloatcaptionparameterhash#1#2\fi}
+
+\def\detokenizedcaptionparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??kj\currentfloat#1\endcsname}}
+
+\def\dosetfloatcaptionattributes#1#2% style color
+ {\edef\fontattributehash {\floatcaptionparameterhash#1}%
+ \edef\colorattributehash{\floatcaptionparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+\def\dohandlenextfloatindent
+ {\checknextindentation[\floatparameter\c!indentnext]%
+ \dorechecknextindentation}
+
+%D The two shared (parent) definitions:
+
+% todo: everysetupfloat everysetupcaption for all floats
+
+\def\setupfloats {\dosingleargument\dosetupfloats} % was \??bk
+\def\setupcaptions{\dosingleargument\dosetupcaptions}
+
+\let\alldefinedfloats\empty
+
+\def\doprocessallfloats#1%
+ {\def\doprocesssomefloat##1{\def\currentfloat{##1}#1}%
+ \processcommacommand[\alldefinedfloats]\doprocesssomefloat}
+
+\def\dosetupfloats [#1]{\getparameters[\??fl][#1]\doprocessallfloats{\the\everysetupfloat}}
+\def\dosetupcaptions[#1]{\getparameters[\??kj][#1]\doprocessallfloats{\the\everysetupcaption}}
+
+% \def\dosetupfloats [#1]{\getparameters[\??fl][#1]}
+% \def\dosetupcaptions[#1]{\getparameters[\??kj][#1]}
+
+\setupcaptions
+ [\c!location=\v!bottom,
+ \c!grid=,
+ \c!before=, % not used (yet)
+ \c!inbetween={\blank[\v!medium]},
+ \c!after=, % not used (yet)
+ \c!spacebefore=,
+ \c!spaceinbetween=, % replaces fuzzy inbetween dual usage
+ \c!spaceafter=,
+ \c!width=\v!fit,
+ \c!minwidth=\v!fit, % id est: the width of the floatbox in some cases
+ \c!headstyle=\v!bold,
+ \c!headcolor=,
+ \c!leftmargin=\zeropoint,
+ \c!rightmargin=\zeropoint,
+ \c!outermargin=\zeropoint,
+ \c!innermargin=\zeropoint,
+ \c!setups=,
+ \c!style=\v!normal,
+ \c!color=,
+ \c!textstyle=,
+ \c!textcolor=,
+ \c!align=,
+ \c!number=\v!yes,
+\c!prefix=\v!no,
+\c!prefixconnector=.,
+\c!way=bychapter,
+\c!prefixsegments=2:2,
+% \c!way=\@@nrway,
+% \c!blockway=\@@nrblockway,
+% \c!sectionnumber=\@@nrsectionnumber,
+% \c!separator=\@@koseparator,
+% \c!stopper=\@@kostopper,
+% \c!suffix=\floatcaptionsuffix, % hook
+ \c!distance=1em,
+ \c!conversion=\v!numbers,
+ \c!command=]
+
+% we can comment some of these
+
+\setupfloats
+ [\c!location=\v!middle,
+ \c!width=8\lineheight,
+ \c!height=6\lineheight,
+ \c!offset=\v!overlay,
+ \c!frame=\v!off,
+ \c!strut=\v!no,
+ \c!radius=.5\bodyfontsize,
+ \c!corner=\v!rectangular,
+ \c!background=,
+ \c!backgroundscreen=,
+ \c!backgroundcolor=,
+ \c!backgroundoffset=\!!zeropoint,
+ \c!topframe=,
+ \c!bottomframe=,
+ \c!leftframe=,
+ \c!rightframe=,
+ \c!frameoffset=\!!zeropoint,
+ \c!before=,
+ \c!after=,
+ \c!spacebefore=\v!big,
+ \c!spaceafter=\v!big,
+ \c!sidespacebefore=\floatsharedparameter\c!spacebefore,
+ \c!sidespaceafter=\floatsharedparameter\c!spaceafter,
+ \c!sidealign=\v!normal,
+ \c!textmethod=\ifgridsnapping2\else0\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt)
+ \c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt)
+ \c!indentnext=\v!no,
+ \c!margin=1em,
+ \c!method=1,
+ \c!cache=\v!yes, % when no, then intermediate flush
+ \c!leftmargin=\zeropoint, % displacement in 'normal floats'
+ \c!rightmargin=\zeropoint, % idem
+ \c!innermargin=\zeropoint, % idem
+ \c!outermargin=\zeropoint, % idem
+ \c!leftmargindistance=\zeropoint,
+ \c!rightmargindistance=\floatparameter\c!leftmargindistance,
+ \c!ntop=2,
+ \c!nbottom=0,
+ \c!nlines=4,
+ \c!local=,
+ \c!bottombefore=, % e.g. \vfill
+ \c!bottomafter=,
+ \c!default=\v!figure,
+ \c!numbering=\v!yes]
+
+\def\@@bknumbering {\floatsharedparameter\c!numbering } % global one
+\def\@@bkspaceafter {\floatsharedparameter\c!spaceafter } % global one
+\def\@@bkspacebefore{\floatsharedparameter\c!spacebefore} % global one
+\def\@@bknbottom {\floatsharedparameter\c!nbottom } % global one
+\def\@@bkntop {\floatsharedparameter\c!ntop } % global one
+\def\@@bknlines {\floatsharedparameter\c!nlines } % global one
+\def\@@bkmargin {\floatsharedparameter\c!margin } % global one
+\def\@@bkcache {\floatsharedparameter\c!cache } % global one
+
+% float
+%
+% [%\c!width=8\lineheight, % 15\bodyfontsize,
+% %\c!height=6\lineheight, % 10\bodyfontsize,
+% \c!offset=\v!overlay,
+% \c!width=\v!fit,
+% \c!height=\v!fit,
+% \c!minwidth=,
+% \c!maxwidth=,
+% \c!maxheight=,
+% \c!criterium=,
+% % inherited
+% \c!pageboundaries=,
+% \c!default=]%
+
+% number
+%
+% [\c!text=#1,
+% \c!location=\v!intext,
+% \c!way=\floatcaptionparameter\c!way,
+% \c!blockway=\floatcaptionparameter\c!blockway,
+% \c!sectionnumber=\floatcaptionparameter\c!sectionnumber,
+% \c!conversion=\floatcaptionparameter\c!conversion]%
+
+
+%D Individial settings:
+
+\def\setupfloat {\dodoubleargument\dosetupfloat}
+\def\setupcaption{\dodoubleargument\dosetupcaption}
+
+\newtoks\everysetupfloat
+\newtoks\everysetupcaption
+
+\def\dosetupfloat[#1][#2]%
+ {\def\docommand##1{\getparameters[\??fl##1][#2]\the\everysetupfloat}%
+ \processcommalist[#1]\docommand}
+
+\def\dosetupcaption[#1][#2]%
+ {\def\docommand##1{\getparameters[\??kj##1][#2]\the\everysetupcaption}%
+ \processcommalist[#1]\docommand}
+
+\appendtoks
+ \dostructurecountersetup\currentfloat\floatcaptionparameter
+\to \everysetupcaption
+
+%D Definitions:
+
+\def\definefloat
+ {\dotripleempty\dodefinefloat}
+
+\def\dodefinefloat[#1][#2][#3]% #1=naam #2=meervoud #3=parent
+ {\ifthirdargument
+ \redodefinefloat[#1][#2][#3]%
+ \else\ifsecondargument
+ \dododefinefloat[#1][#2]%
+ \else
+ \dododefinefloat[#1][#1]%
+ \fi\fi}
+
+\presetlocalframed[\??fl]
+
+\def\dododefinefloat[#1][#2]%
+ {\copylocalframed[\??fl#1][\??fl]%
+ \definestructurecounter[#1]%
+ \addtocommalist{#1}\alldefinedfloats
+ \setupfloat[#1][\s!parent=\??fl]%
+ \setupcaption[#1][\s!parent=\??kj]%
+ \definelist[#1]%
+ \presetlabeltext[#1=\Word{#1}~]%
+ \presetheadtext[#2=\Word{#2}]%
+ \dodefinefloatcommands[#1][#2]%
+ }% \newnodelocation{\v!float\@@thenumber{#1}}}
+
+\def\redodefinefloat[#1][#2][#3]%
+ {\copylocalframed[\??fl#1][\??fl#3]%
+ \setupfloat[#1][\s!parent=\??fl#3]%
+ \setupcaption[#1][\s!parent=\??kj#3]%
+ \definestructurecounter[#1][#3]%
+ \definelist[#1][#3]%
+ \presetlabeltext[#1=\Word{#3}]%
+ \presetheadtext[#2=\Word{#2}]%
+ \dodefinefloatcommands[#1][#2]}
+
+\def\dodefinefloatcommands[#1][#2]%
+ {\setvalue {\e!place\e!listof#2}{\dodoubleempty\doplacelist[#1]}%
+ \setvalue {\e!complete\e!listof#2}{\dotripleempty\dodocompletelist[#1][#2]}%
+ \setvalue {\e!place#1}{\dotripleempty\docomplexplacefloat[#1]}%
+ \setvalue {\e!reserve#1}{\doquadrupleempty\docomplexreserveblock[#1]}%
+ \setvalue {\e!start#1\e!text}{\dotripleempty\docomplexstarttextblock[#1]}%
+ \setvalue {\e!stop#1\e!text}{\dostoptextfloat}%
+ \setvalue{\e!start\e!reserve#1\e!text}{\doquadrupleempty\docomplexstartreservetextblock[#1]}%
+ \setvalue {\e!stop\e!reserve#1\e!text}{\dostoptextfloat}%
+ \setvalue {\e!emptyone#1}{\doemptyfloatblock{#1}}%
+ \setvalue {\e!emptytwo#1}{\doemptyfloatblock{#1}}}
+
+%D Fallback float body:
+
+\def\doemptyfloatblock#1%
+ {\framed
+ [\c!frame=\v!on,
+ \c!width=\floatsharedparameter\c!width,
+ \c!height=\floatsharedparameter\c!height,
+ \c!location=\v!normal,
+ \c!offset=\floatsharedparameter\c!offset]%
+ {\getmessage\m!floatblocks{12}\empty}}
+
+%D Data. We can generalize this to lists.
+
+\newif\ifnofloatcaption
+\newif\ifnofloatnumber
+\newif\ifemptyfloatcaption
+
+\def\getfloatparameters {\getparameters[\??fl\currentfloat]}
+\def\getcaptionparameters{\getparameters[\??kj\currentfloat]}
+
+\installstructurelistprocessor{float}{\usestructurelistprocessor{number+title}}
+
+\def\thecurrentfloatnumber
+ {\ifnofloatcaption \else \ifnofloatnumber \else
+% \labeltexts\currentfloat{\convertedstructurecounter[\currentfloat]}% ! ! todo: use a lua call instead
+\ifx\currentfloatnumber\relax\else
+ \labeltexts\currentfloat{\ctxlua{structure.lists.savednumber("\currentfloat",\currentfloatnumber)}}%
+\fi
+ \fi \fi}
+
+\def\thecurrentfloatcaption
+ {\ifnofloatcaption \else
+\ifx\currentfloatnumber\relax\else
+ \ctxlua{structure.lists.savedtitle("\currentfloat",\currentfloatnumber)}%
+\fi
+ \fi}
+
+%D Captions.
+
+\let\floatcaptionsuffix\empty % an optional suffix
+\let\floatcaptionnumber\empty % a logical counter
+
+% the split is needed when for instance the float goes into
+% a multi page field and the list of figs becomes larger than
+% one page: cycle between 'only flush when object ref ok'
+% and 'one/many page fig list'; see "uguide finometer"
+%
+% potential sync bug with sectionblocks, see uguide.tex
+
+% NOT YET REDONE ! ! ! ! !
+
+ \def\placefloatcaption
+ {\dodoubleempty\doplacefloatcaption}
+
+ \long\def\doplacefloatcaption[#1][#2]#3%
+ {\setfloatcaption[#1][#2]{#3}%
+ \placefloatcaptiontext[#1]%
+ \placefloatcaptionreference[#1]}
+
+ \def\setfloatcaption % \dosetfloatcaption already in use
+ {\dodoubleempty\dodosetfloatcaption} % beware, name clash
+
+ \long\def\dodosetfloatcaption[#1][#2]#3% to do namespace for number/ascii
+ {\ifnofloatnumber % also handle trialtypesetting
+ \letgvalue{@fl@r@#1}\relax
+ \letgvalue{@fl@t@#1}\relax
+ \else
+ \preparefloatnumber{#1}%
+ \letgvalue{@fl@n@#1}\composedsectionnumber
+ % indirect macro can be more efficient
+ \setgvalue{@fl@r@#1}%
+ {\tracefloatnumber{#1}%
+ \ifconditional\retainfloatnumber\else
+ % \dowritetolist{#1}{\getvalue{@fl@n@#1}}{#3}{#1}%
+ % \gdefconvertedargument\flasciititle{#3}% \asciititle is global
+ % \doifsomething{#2}{\rawreference\s!flt{#2}{{\getvalue{@fl@n@#1}}{\flasciititle}}}%
+ \fi
+ \letgvalue{@fl@r@#1}\relax}% nils
+ \setgvalue{@fl@t@#1}%
+ {\preparefullnumber{\??kj#1}{\getvalue{@fl@n@#1}}\preparednumber
+ \begingroup
+ \dosetfloatcaptionattributes\c!style\c!color
+ \begingroup
+ \dosetfloatcaptionattributes\c!headstyle\c!headcolor
+ \labeltexts{#1}{\preparednumber}%
+ \endgroup
+ \begingroup
+ \dosetfloatcaptionattributes\c!textstyle\c!textcolor
+ \dotfskip{\floatcaptionparameter\c!distance}#3%
+ \endgroup
+ \endgroup}%
+ \fi}
+
+ \long\def\dodosetfloatcaption[#1][#2]#3% to do namespace for number/ascii
+ {\letgvalue{@fl@r@#1}\relax
+ \letgvalue{@fl@t@#1}\relax}
+
+ \def\placefloatcaptiontext [#1]{\getvalue{@fl@t@#1}}
+ \def\placefloatcaptionnumber [#1]{\getvalue{@fl@n@#1}}
+ \def\placefloatcaptionreference[#1]{\getvalue{@fl@r@#1}}
+
+ % still needed for uguide
+
+ \let\placefloatlabel \placefloatcaption
+ \let\placefloatlabeltext \placefloatcaptiontext
+ \let\placefloatlabelreference \placefloatcaptionreference
+
+% TILL HERE
+
+\newbox\captionbox
+
+\long\def\putcompletecaption#1#2%
+ {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}%
+ %\floatcaptionparameter\c!before % test for side effects first
+ \noindent
+ \gdef\lastcaptiontag{\strut#1}% was xdef
+ \begingroup
+ \dosetfloatcaptionattributes\c!style\c!color
+ \ifnofloatnumber
+ \else
+ \hbox{\dosetfloatcaptionattributes\c!headstyle\c!headcolor\strut#1}%
+ \ifnofloatcaption \else \ifemptyfloatcaption \else
+ \doifelsenothing{\floatcaptionparameter\c!spaceinbetween}
+ {\scratchskip\floatcaptionparameter\c!distance\relax
+ \dotfskip\scratchskip\emergencystretch.5\scratchskip}
+ {\blank[\floatcaptionparameter\c!spaceinbetween]}%
+ \fi \fi
+ \fi
+ \ifnofloatcaption
+ \globallet\lastcaptionht\!!zeropoint
+ \globallet\lastcaptiondp\!!zeropoint
+ \else
+ \dosetfloatcaptionattributes\c!textstyle\c!textcolor
+ \xdef\lastcaptionht{\strutheight}%
+ \xdef\lastcaptiondp{\strutdepth}%
+ \begstrut#2\endstrut\endgraf
+ \fi
+ \endgroup
+ %\floatcaptionparameter\c!after % test for side effects first
+ \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}}
+
+\let\lastcaptionht\!!zeropoint
+\let\lastcaptiondp\!!zeropoint
+
+\newbox\tempcaptionbox
+
+\newif\iftracecaptions
+
+\def\settracedcaptionbox
+ {\iftracecaptions\setbox\tempcaptionbox\ruledhbox{\box\tempcaptionbox}\fi}
+
+% \definefloat [figure-1] [figure]
+% \definefloat [figure-2] [figure]
+% \setupfloat [figure-1] [location=left,leftmargin=10mm]
+% \setupfloat [figure-2] [location=left,leftmargin=-5mm]
+% \setupcaption [figure-1] [align=flushleft]
+% \setupcaption [figure-2] [align=flushleft,leftmargin=15mm]
+%
+% \startsetups somefigure
+% \ifdim\wd\nextbox>\textwidth
+% \placefloat[figure-2][][]{}{\box\nextbox}
+% \else
+% \placefloat[figure-1][][]{}{\box\nextbox}
+% \fi
+% \stopsetups
+%
+% \def\setupswithbox[#1]{\dowithnextbox{\setups[#1]}\vbox}
+%
+% test \setupswithbox[somefigure]{\framed[width=3cm] {}} test
+% test \setupswithbox[somefigure]{\framed[width=\dimexpr\textwidth+3cm\relax]{}} test
+
+\def\dosetcaptionthings
+ {\setups[\floatcaptionparameter\c!setups]% expanded ?
+ %\advance\leftskip \floatcaptionparameter\c!leftmargin
+ %\advance\rightskip\floatcaptionparameter\c!rightmargin
+ \relax}
+
+\def\dofakecaptionthings
+ {\hbox{\dosetcaptionthings\hskip\leftskip\hskip\rightskip}}
+
+\long\def\docheckcaptioncontent#1#2%
+ {\ifnofloatcaption \else
+ \setbox\tempcaptionbox\hbox
+ {\trialtypesettingtrue
+ \notesenabledfalse
+ \putcompletecaption{#1}{#2}}%
+ % new, \placefigure{\XMLflush{somecaption}}{} passes earlier empty check
+ % so here we misuse the scratch box; actually this means that the previous
+ % test can go away (some day, when i redo this module)
+ \ifdim\wd\tempcaptionbox=\zeropoint
+ \global\emptyfloatcaptiontrue
+ \ifnofloatnumber
+ \global\nofloatcaptiontrue
+ \fi
+ \else
+ \setbox\tempcaptionbox\hbox{\dosetcaptionthings\hskip\leftskip\box\tempcaptionbox}% yet incomplete
+ \fi
+ \fi}
+
+% the tricky part of getting float related two pass data is
+% that we should fetch is early but can only save it with
+% the composed float box; this determines the order: get it
+% before saving it
+
+\definetwopasslist{\s!float\s!data} \newcounter\noffloatdata
+
+\let\twopassfloatdata\realpageno % used for odd/even determination, can be combined with nodelocation
+
+\def\dosavefloatdata % \expanded
+ {\doglobal\increment\noffloatdata
+ \lazysavetaggedtwopassdata{\s!float\s!data}{\noffloatdata}{\noffloatpages}{\noexpand\realfolio}}% later {}{}{}{} and \getfirst...
+
+\def\dogetfloatdata % precedes save !
+ {\doglobal\increment\noffloatpages
+ \findtwopassdata{\s!float\s!data}{\noffloatpages}%
+ \iftwopassdatafound
+ \globallet\twopassfloatdata\twopassdata
+ \else
+ \globallet\twopassfloatdata\realpageno % \realfolio
+ \fi}
+
+\def\tracefloatnumber#1%
+ {\doifnot{\floatsharedparameter\c!numbering}\v!nocheck{\tagnodelocation{\v!float\@@thenumber{#1}}}}
+
+\newconditional\retainfloatnumber
+
+\def\preparefloatnumber#1%
+ {\xdef\floatcaptionnumber{#1}%
+ \doifelsenodelocation{\v!float\@@thenumber{#1}}
+ \donothing {\chardef\nodelocationmode\zerocount}%
+ \doifelse{\floatsharedparameter\c!numbering}\v!nocheck
+ {\incrementnumber[#1]%
+ \makesectionnumber[#1]%
+ \ifconditional\retainfloatnumber\decrementnumber[#1]\fi}
+ {\ifinsidecolumns
+ \chardef\nodelocationmode\zerocount
+ % to be perfected:
+ % \chardef\nodelocationmode\plustwo
+ \fi
+% FOR THE MOMENT NOT AVAILABLE
+\chardef\nodelocationmode\zerocount
+% BUT NOT THAT HARD TO DO
+ \ifcase\nodelocationmode
+ \incrementnumber[#1]%
+ \makesectionnumber[#1]%
+ \ifconditional\retainfloatnumber\decrementnumber[#1]\fi
+ \else
+ % force check, so that we get a proper way-sync and
+ % can use the accumulated number
+ % \checknumber[#1]% \incrementnumber does this
+ \incrementnumber[#1]%
+ \savenumber[#1]%
+ % the real work is done here
+ \nextnodelocation{\v!float\@@thenumber{#1}}% better \nextfloatnumber
+ \analyzenodelocation{\v!float\@@thenumber{#1}}%
+ \scratchcounter\getnodelocationo{\v!float\@@thenumber{#1}}%
+ \advance\scratchcounter\minusone
+ % here we correct for 'per whatever handling'
+ \advance\scratchcounter-\accumulatednumber[#1]%
+ \setnumber[#1]\scratchcounter
+ \incrementnumber[#1]%
+ \makesectionnumber[#1]%
+ \restorenumber[#1]%
+ % now we're back to normal numbering
+ \fi}}
+
+%D test case:
+%D
+%D \starttyping
+%D \setupfloat[figure][criterium=\marginwidth,fallback=bottom]
+%D \dorecurse{3}{
+%D \chapter{test}
+%D \placefigure[bottom]{1}{\framed{bottom}}
+%D test
+%D \placetable[bottom]{1}{\framed{table}}
+%D test
+%D \placetable{2}{\framed{table}}
+%D test
+%D \placefigure[left]{2}{\framed{left but way too wide}}
+%D \input tufte
+%D \placefigure[left]{3}{\framed{left but ok}}
+%D \input tufte }
+%D \stoptyping
+
+% A complication is that we may have to handle a pagebreak
+% first, which in turn may issue a (postponed) float.
+% Therefore we may not trust on variable assignments before
+% we're realy dealing with the float. Some day I'll root out
+% the global settings.
+
+\def\docomplexplacefloat[#1][#2]% [#3]#4%
+ {\edef\currentfloat{#1}%
+ \doifnothing\currentfloat{\let\currentfloat\v!figure}%
+ \doifelsenothing{#2}
+ {\edef\floatlocation{\floatparameter\c!default}}
+ {\edef\floatlocation{#2}}%
+ \doifinsetelse\v!split{#2}
+ {\normalexpanded{\noexpand\dodocomplexsplitfloat[\currentfloat][\floatlocation]}}
+ {\normalexpanded{\noexpand\dodocomplexplacefloat[\currentfloat][\floatlocation]}}}
+
+\long\def\dodocomplexsplitfloat[#1][#2][#3]#4%
+ {\splitfloat{\dodocomplexplacefloat[#1][#2][#3]{#4}}}
+
+\def\flushfloatslist
+ {\v!left,\v!right,\v!inner,\v!outer,%
+ \v!backspace,\v!cutspace,%
+ \v!inleft,\v!inright,\v!inmargin,%
+ \v!leftmargin,\v!rightmargin,\v!leftedge,\v!rightedge,%
+ \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,%
+ \v!text,\v!opposite}% \v!page
+
+\long\def\dodocomplexplacefloat[#1][#2][#3]#4%
+ {\flushnotes
+ \flushsidefloats % here !
+ \ifsomefloatwaiting
+ % this was \checkwaitingfloats spread all over
+ \doifinsetelse\v!always{#2}
+ {\showmessage\m!floatblocks5\empty}
+ {\normalexpanded{\noexpand\doifcommonelse{#2}{\flushfloatslist}}\doflushfloats\donothing}%
+ % but which should be done before using box \floatbox
+ \fi
+ \ifmargeblokken
+ \doifinset\v!margin{#2}\endgraf
+ \fi
+ \global\insidefloattrue
+ \begingroup % **
+ \ifmargeblokken
+ \doifinset\v!margin{#2}{\hsize\@@mbwidth}%
+ \fi
+ \the\everyinsidefloat
+ \let\@@extrafloat\empty
+ \presetmorefloatvariables{#2}%
+ \dowithnextboxcontent % better a \the\everyfloattoks
+ {\setlocalfloathsize
+ \floatparameter\c!inner
+ \fuzzysnappingfalse
+ \postponenotes} % new
+ {\doifsomething{\floatparameter\c!criterium}
+ {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax
+ \edef\forcedfloatmethod{\floatvariable\c!fallback}%
+ \ifx\forcedfloatmethod\empty\let\forcedfloatmethod\v!here\fi
+ \fi}%
+ \xdocompletefloat{#1}{#3}{#2}{#4}% ** not yet done
+ % we need to carry over the par because of side floats
+ \doifnotinset\v!text{#2}{\carryoverpar\endgroup}%
+ \global\sidefloatdownshift \zeropoint
+ \global\sidefloatextrashift\zeropoint
+ \ifparfloat
+ \doifinset\v!reset{#2}\forgetsidefloats
+ \doinhibitblank
+ \fi}% better move this to side floats
+ \vbox}
+
+\def\xxdocompletefloat#1#2%
+ {\rightorleftpageaction{\let\@@extrafloat#1}{\let\@@extrafloat#2}}
+
+\chardef\textfloatmethod=0 % 0=raw 1=safe (.99) 2=tight (-1pt)
+\chardef\sidefloatmethod=1 % 0=raw 1=safe (.99) 2=tight (-1pt)
+
+\let\floatrotation\!!zerocount
+
+\long\def\presetfloatvariables#1#2#3#4%
+ {\doifcommonelse
+ {#2}
+ {\v!left,\v!right,\v!inner,\v!outer,%
+ \v!inleft,\v!inright,\v!inmargin,%
+ \v!backspace,\v!cutspace,%
+ \v!innermargin,\v!outermargin,\v!inneredge,\v!outeredge,%
+ \v!leftmargin,\v!leftedge,\v!rightmargin,\v!rightedge}
+ {\global\parfloattrue}
+ {\global\parfloatfalse}%
+ \ifinsidecolumns
+ \global\parfloatfalse
+ \fi
+ \global\sidefloatshift\zeropoint
+ \global\sidefloatmaximum\zeropoint
+ \global\chardef\sidefloatmethod\floatparameter\c!sidemethod
+ \global\chardef\textfloatmethod\floatparameter\c!textmethod
+ \global\chardef\sidefloatalign\zerocount
+ \globallet\floatrotation\!!zerocount
+ \calculatefloatskips
+ \ifparfloat
+ \processaction
+ [\floatparameter\c!sidealign]
+ [\v!height=>\global\chardef\sidefloatalign\plusone,%
+ \v!line=>\global\chardef\sidefloatalign\plustwo,% (***)
+ \v!depth=>\global\chardef\sidefloatalign\plusthree,%
+ \v!grid=>\global\chardef\sidefloatalign\plusfour,%
+ \v!halfline=>\global\chardef\sidefloatalign\plusfive]%
+ % todo (test first): \doifinset\v!lokaal{#2}{\chardef\sidefloatalign\zerocount}%
+ \ifcase\sidefloatalign\relax % todo: optie v!lokaal => \else
+ \doifinset\v!height {#2}{\global\chardef\sidefloatalign\plusone}%
+ \doifinset\v!line {#2}{\global\chardef\sidefloatalign\plustwo}%
+ \doifinset\v!depth {#2}{\global\chardef\sidefloatalign\plusthree}%
+ \doifinset\v!grid {#2}{\global\chardef\sidefloatalign\plusfour}%
+ \doifinset\v!halfline{#2}{\global\chardef\sidefloatalign\plusfive}% meant for 'none'
+ \fi
+ \doifinset\v!high{#2}{\global\sidefloattopskip \zeropoint}%
+ \doifinset\v!low {#2}{\global\sidefloatbottomskip\zeropoint}%
+ \doifinset\v!fit {#2}
+ {\global\sidefloattopskip \zeropoint
+ \global\sidefloatbottomskip\zeropoint
+ \global\floatsideskip \zeropoint}%
+ \else
+ \processallactionsinset
+ [#2]
+ [ 90=>\globallet\floatrotation\commalistelement,%
+ 180=>\globallet\floatrotation\commalistelement,%
+ 270=>\globallet\floatrotation\commalistelement]%
+ \fi
+ \doifinsetelse\v!nonumber{#2}
+ {\global\nofloatnumbertrue}
+ {\doifelse{\floatcaptionparameter\c!number}\v!yes
+ {\global\nofloatnumberfalse}
+ {\global\nofloatnumbertrue}}%
+ % this has to change
+ \ConvertToConstant\doifelse{#4}{}
+ {\global\emptyfloatcaptiontrue}
+ {\global\emptyfloatcaptionfalse}%
+ \doifinsetelse\v!none{#2}
+ {\global\nofloatcaptiontrue}
+ {\ConvertToConstant\doifelse{#4}\v!none
+ {\global\nofloatcaptiontrue}
+ {\global\nofloatcaptionfalse}}%
+ \doif{\floatcaptionparameter\c!number}\v!none % new
+ {\global\nofloatcaptiontrue}%
+ \ifemptyfloatcaption \ifnofloatnumber
+ \global\nofloatcaptiontrue
+ \fi \fi}
+
+% documenteren in details
+
+\def\presetmorefloatvariables#1%
+ {\doifelse{\floatparameter\c!local}\v!yes % fout keyword
+ \globalcenterfloatboxtrue
+ \globalcenterfloatboxfalse
+ \ifglobalcenterfloatbox
+ \localcenterfloatboxtrue
+ \else
+ \doifinsetelse\v!local{#1}
+ \localcenterfloatboxtrue
+ \localcenterfloatboxfalse
+ \fi
+ \doifnotcommon{\v!always,\v!here,\v!force}{#1} % ! ! ! ! ! !
+ {\globalcenterfloatboxfalse
+ \localcenterfloatboxfalse}}
+
+\let\naturalfloatheight\!!zeropoint
+\let\naturalfloatwidth \!!zeropoint
+\let\naturalfloatdepth \!!zeropoint
+
+\def\setnaturalfloatdimensions#1%
+ {\xdef\naturalfloatheight{\the\ht#1}%
+ \xdef\naturalfloatwidth {\the\wd#1}%
+ \xdef\naturalfloatdepth {\the\dp#1}}
+
+\long\def\doifelsemainfloatbody#1#2%
+ {\ifinsidesplitfloat\ifconditional\splitfloatfirstdone#2\else#1\fi\else#1\fi}
+
+% todo: optional user pars
+
+\long\def\docompletefloat#1#2#3#4#5% #1:floatclass #2:reference #3:optionlist #4:caption #5:box number
+ {\presetfloatvariables{#1}{#3}{#2}{#5}% check this one
+ \bgroup
+ % prepare structure data
+ %
+ % \dofloatcomponent[\c!name=#1,\c!reference=#2,\c!bookmark=,\c!title={#4}][]% ifnofloatnumber ifnofloatcaption \tracefloatnumber{#1}%
+ %
+ \dostructurecountercomponent
+ {float}%
+ \getcaptionparameters
+ \floatcaptionparameter
+ \detokenizedcaptionparameter
+ \relax
+ \relax
+ \relax
+ [\c!name=\currentfloat,\s!counter=\currentfloat,%
+ \s!hascaption=\ifnofloatcaption \v!no\else\v!yes\fi,%
+ \s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,%
+ \s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi,%
+ \c!reference=#2,\c!title={#4},\c!bookmark=]%
+ []%
+ \globallet\currentfloatnumber \laststructurecounternumber
+ \globallet\currentfloatsynchronize\laststructurecountersynchronize
+ %
+ % check float box
+ \setnaturalfloatdimensions#5%
+ \global\setbox\floatbox\vbox{\floatparameter\c!command{\box#5}}%
+ \setnaturalfloatdimensions\floatbox
+ \ifdim\htdp\floatbox=\zeropoint
+ \showmessage\m!floatblocks{11}\empty
+ \global\setbox\floatbox\vbox{\doemptyfloatblock{#1}}%
+ \fi
+ % deal with lack of caption
+ \global\setbox\floatbox\vbox
+ {\doifelsemainfloatbody\currentfloatsynchronize\donothing
+ \unvbox\floatbox
+ \ifnofloatcaption
+ \vss
+ \fi}% gets rid of the depth (unless tabulate)
+ \egroup
+ % place the float
+ \dofloat{#3}{\thecurrentfloatnumber}{\thecurrentfloatcaption}%
+ \global\insidefloatfalse}
+
+\def\setlocalfloathsize
+ {\iflocalcenterfloatbox
+ \seteffectivehsize
+ \hsize\localhsize
+ \fi}
+
+\newevery \everyinsidefloat \relax
+
+\appendtoks
+ \everyinsidefloat\emptytoks % in case it's called earlier
+ \dogetfloatdata
+\to \everyinsidefloat
+
+%\appendtoks
+% \fuzzysnappingfalse
+%\to \everyinsidefloat
+
+\def\doifrightpagefloatelse
+ {\ifdoublesided
+ \ifsinglesided
+ \@EAEAEA\firstoftwoarguments
+ \else
+ \@EAEAEA\doifoddfloatpageelse
+ \fi
+ \else
+ \@EA\firstoftwoarguments
+ \fi}
+
+\def\doifoddfloatpageelse
+ {\ifodd\purenumber\twopassfloatdata\space
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\appendtoks
+ \let\rightorleftpageaction\doifrightpagefloatelse
+\to \everyinsidefloat
+
+\newif\ifextrafloatactions \extrafloatactionstrue
+
+% \let\movesidefloat\gobbleoneargument
+
+% new : \place...[leftmargin,-2*line]; we need to catch fxtb:2*3
+% watch out: line alone aligns on the line ! ! !
+
+\def\movesidefloat[#1]% (-)n*line|x=,y=
+ {\global\sidefloatdownshift \zeropoint
+ \global\sidefloatextrashift\zeropoint
+ \doifassignmentelse{#1}%
+ {\bgroup
+ \getparameters[\??fl][\c!x=\zeropoint,\c!y=\zeropoint,#1]%
+ \ifgridsnapping
+ \getnoflines\@@fly
+ \global\sidefloatdownshift\noflines\lineheight
+ \else
+ \global\sidefloatdownshift\@@fly
+ \fi
+ \global\sidefloatextrashift\@@flx
+ \egroup}
+ {\movedownsidefloat[#1]}}
+
+\def\movedownsidefloat[#1]% already in core
+ {\bgroup
+ \cleanupfeatures
+ \doifinstringelse{:}{#1}
+ \donothing
+ {\def\docommand##1%
+ {\processaction
+ [##1]%
+ [ \v!line=>\dodocommand+,%
+ +\v!line=>\dodocommand+,%
+ -\v!line=>\dodocommand-]}%
+ \def\dodocommand##1%
+ {\ifdone\else\global\sidefloatdownshift\zeropoint\donetrue\fi
+ \global\advance\sidefloatdownshift##1\lineheight}%
+ \donefalse\normalexpanded{\noexpand\dorepeatwithcommand[#1]}\docommand
+ \def\docommand##1%
+ {\processaction
+ [##1]%
+ [ \v!hang=>\dodocommand+,%
+ +\v!hang=>\dodocommand+,%
+ -\v!hang=>\dodocommand-]}%
+ \def\dodocommand##1% inefficient but who cares
+ {\ifdone\else\global\sidefloatsidelines\zeropoint\donetrue\fi
+ \global\advance\sidefloatsidelines\plusone\relax}%
+ \donefalse\normalexpanded{\noexpand\dorepeatwithcommand[#1]}\docommand}%
+ \egroup}
+
+\def\hangsidefloat[#1]%
+ {\global\sidefloatsidelines#1\relax}
+
+\long\def\xdocompletefloat#1#2#3#4%
+ {\ifextrafloatactions
+ \doifinsetelse\v!text{#3}
+ {% fuzzy, text overloads left, since then it's a directive
+ \docompletefloat{#1}{#2}{#3}{#4}\nextbox}
+ {\let\@@extrafloat\empty
+ % \sidefloatdownshift will be reset afterwards, and can
+ % already be set at this point
+ \processallactionsinset
+ [#3] % ininner/inouter : for old times sake
+ [ \v!inner=>\xxdocompletefloat\v!left \v!right,
+ \v!outer=>\xxdocompletefloat\v!right \v!left,
+ \v!innermargin=>\xxdocompletefloat\v!leftmargin \v!rightmargin,
+ \v!outermargin=>\xxdocompletefloat\v!rightmargin\v!leftmargin,
+ \v!inneredge=>\xxdocompletefloat\v!leftedge \v!rightedge,
+ \v!outeredge=>\xxdocompletefloat\v!rightedge \v!leftedge,
+ \v!backspace=>\xxdocompletefloat\v!backspace \v!cutspace,
+ \v!cutspace=>\xxdocompletefloat\v!cutspace \v!backspace,
+% \v!margin=>\xxdocompletefloat\v!cutspace \v!backspace,
+ \v!left=>\xxdocompletefloat\v!left \v!left,
+ \v!right=>\xxdocompletefloat\v!right \v!right,
+ \v!line=>, % only -n*line is handled (see ***)
+ \s!unknown=>{\movedownsidefloat[\commalistelement]}]%
+ \ifx\@@extrafloat\empty
+ \docompletefloat{#1}{#2}{#3}{#4}\nextbox
+ \else
+ \docompletefloat{#1}{#2}{\@@extrafloat,#3}{#4}\nextbox
+ \fi}%
+ \else % downward compatible
+ \docompletefloat{#1}{#2}{#3}{#4}\nextbox
+ \fi}
+
+% pas op, maxbreedte niet instellen als plaats=links/rechts
+
+\def\setlocalfloatdimensions#1%
+ {\global\sidefloatshift \zeropoint % duplicate
+ \global\sidefloatmaximum\zeropoint\relax % duplicate
+ \ifextrafloatactions
+ \ifdim\sidefloatdownshift=\zeropoint\else
+ \global\setbox\floatbox\vbox
+ {\vskip\sidefloatdownshift\nointerlineskip\box\floatbox}%
+ \fi
+ \doifsomething{\floatparameter\c!minwidth}
+ {\scratchdimen\floatparameter\c!minwidth\relax
+ \ifdim\wd\floatbox<\scratchdimen
+ \global\setbox\floatbox\hbox to \scratchdimen
+ {\doifnot{\floatparameter\c!location}\v!left \hss
+ \box\floatbox%
+ \doifnot{\floatparameter\c!location}\v!right\hss}%
+ \fi}%
+ % todo: rand / rug
+ \doifinset\v!hanging{#1}
+ {\doifcommonelse{\v!inleft,\v!leftmargin}{#1}
+ {\letfloatparameter\c!maxwidth\leftmarginwidth}%
+ {\doifcommon{\v!inright,\v!rightmargin}{#1}
+ {\letfloatparameter\c!maxwidth\rightmarginwidth}}}%
+ \doifsomething{\floatparameter\c!maxwidth}
+ {\scratchdimen\floatparameter\c!maxwidth\relax
+ \ifdim\wd\floatbox>\scratchdimen
+ \doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge
+ \v!inleft,\v!leftmargin,\v!leftedge}{#1}
+ {\global\sidefloatmaximum\scratchdimen}
+ {\global\setbox\floatbox\hbox to \scratchdimen
+ {\doifcommonelse{\v!right,\v!left}{#1}
+ {\doifnotinset\v!right{#1}\hss
+ \box\floatbox
+ \doifnotinset\v!left{#1}\hss}%
+ {\doifnot{\floatparameter\c!location}\v!left\hss
+ \box\floatbox
+ \doifnot{\floatparameter\c!location}\v!right\hss}}}%
+ \fi}%
+ \fi}
+
+\def\docomplexstarttextblock[#1][#2][#3]%
+ {\flushnotes
+ \flushsidefloats % hoort eigenlijk niet hier
+ \docomplexplacefloat[#1][\v!text,#2,\v!left][#3]}
+
+\long\def\docomplexreserveblock[#1][#2][#3][#4]#5%
+ {\getvalue{\e!place#1}[#3][#4]{#5}{\localframed[\??fl#1][#2]{#1}}}
+
+\def\docomplexstartreservetextblock[#1][#2][#3][#4]%
+ {\flushsidefloats % hoort eigenlijk niet hier
+ \docomplexreserveblock[#1][#2][\v!text,#3,\v!left][#4]}
+
+\def\placefloat
+ {\dotripleempty\docomplexplacefloat}
+
+\installinsertion\topins
+\installinsertion\botins
+
+\newdimen\botinserted
+\newdimen\topinserted
+
+%D Extra float registers.
+
+\newif\ifsomefloatwaiting \somefloatwaitingfalse
+\newif\ifroomforfloat \roomforfloattrue
+\newif\ifnofloatpermitted \nofloatpermittedfalse
+
+\newcount\totalnoffloats \totalnoffloats =0
+\newcount\savednoffloats \savednoffloats =0
+\newcount\noffloatinserts \noffloatinserts=0
+
+\newbox\floatlist
+\newbox\savedfloatlist
+
+\newif\ifflushingfloats \flushingfloatsfalse
+
+\newbox\floattext
+
+\newdimen\floattextwidth
+\newdimen\floattextheight
+
+\newbox\floatbox
+\newbox\savedfloatbox
+
+\newdimen\floatwidth
+\newdimen\floatheight
+
+% In \dofloatinfomessage wordt {{ }} gebruikt omdat anders
+% binnen \startpostponing...\stoppostponing geen goede
+% melding in de marge volgt: \ifinner is dan namelijk true.
+
+\def\dofloatinfomessage#1#2#3%
+ {\bgroup
+ \showmessage\m!floatblocks{#2}{#3}%
+ \setmessagetext\m!floatblocks{#2}%
+ \@EA\floatinfo\@EA#1\@EA{\currentmessagetext}%
+ \egroup}
+
+\def\dosavefloatinfo
+ {\dofloatinfomessage>2{\the\totalnoffloats}}
+
+\def\dofloatflushedinfo
+ {\bgroup
+ \!!counta\totalnoffloats
+ \advance\!!counta -\savednoffloats
+ \dofloatinfomessage<3{\the\!!counta}%
+ \egroup}
+
+\def\doinsertfloatinfo
+ {\dofloatinfomessage<4{\the\totalnoffloats}}
+
+\def\dogetfloat
+ {\ifsomefloatwaiting
+ \global\setbox\floatlist\vbox
+ {\unvbox\floatlist
+ \global\setbox\globalscratchbox\lastbox}%
+ \ifcenterfloatbox
+ \ifdim\wd\globalscratchbox<\hsize
+ \setbox\floatbox\hbox to \hsize{\hss\box\globalscratchbox\hss}%
+ \else
+ \setbox\floatbox\box\globalscratchbox % local !
+ % retain special alignments
+ \ifinsidecolumns
+ \ifdim\wd\floatbox>\makeupwidth
+ \wd\floatbox\makeupwidth
+ \fi
+ \fi
+ \fi
+ \else
+ \setbox\floatbox\box\globalscratchbox % local !
+ \fi
+ \global\advance\savednoffloats \minusone
+ \ifcase\savednoffloats
+ \global\somefloatwaitingfalse
+ \fi
+ \else
+ \global\savednoffloats\zerocount
+ \global\setbox\floatbox\emptybox
+ \fi}
+
+\def\uncenteredfloatbox
+ {\ifcenterfloatbox
+ \ifhbox\floatbox\relax % remove centering
+ \ifdim\wd\floatbox=\hsize
+ \ifhbox\floatbox
+ \setbox\scratchbox\hbox
+ {\unhbox\floatbox
+ \unskip\unskip
+ \global\setbox\globalscratchbox\lastbox}%
+ \box\globalscratchbox
+ \else
+ \box\floatbox
+ \fi
+ \else
+ \box\floatbox
+ \fi
+ \else
+ \box\floatbox
+ \fi
+ \else
+ \box\floatbox
+ \fi}
+
+\def\dosavefloat
+ {\global\setbox\floatlist\vbox
+ {\nointerlineskip
+ \uncenteredfloatbox
+ \unvbox\floatlist}%
+ \global\advance\savednoffloats \plusone
+ \global\somefloatwaitingtrue
+ \dosavefloatinfo
+ \nonoindentation}
+
+\def\doresavefloat
+ {\global\setbox\floatlist\vbox
+ {\nointerlineskip
+ \unvbox\floatlist
+ \uncenteredfloatbox}%
+ \global\advance\savednoffloats \plusone
+ \global\somefloatwaitingtrue}
+
+\def\doreversesavefloat
+ {\global\setbox\floatlist\vbox
+ {\nointerlineskip
+ \unvbox\floatlist
+ \uncenteredfloatbox}%
+ \global\advance\savednoffloats \plusone
+ \global\somefloatwaitingtrue
+ \dosavefloatinfo}
+
+% better (todo): \savednofsavedfloats
+
+\def\dosavefloatstatus
+ {\global\setbox\savedfloatlist\copy\floatlist
+ \global\setbox\savedfloatbox \copy\floatbox
+ \xdef\dorestorefloatstatus
+ {\global\setbox\floatlist\box\savedfloatlist
+ \global\setbox\floatbox \box\savedfloatbox
+ \global\savednoffloats\the\savednoffloats}}
+
+\let\dorestorefloatstatus\relax
+
+\ifx\doflushfloats\undefined \let\doflushfloats\relax \fi
+\ifx\flushfloatbox\undefined \let\flushfloatbox\relax \fi
+
+% needed in the splitter:
+
+\newcount\savedsavednoffloats
+
+\let\dopopsavedfloats\relax
+
+\def\dopushsavedfloats
+ {\global\setbox\savedfloatlist\box\floatlist
+ \global\savedsavednoffloats\savednoffloats
+ \global\savednoffloats\savednoffloats
+ \global\somefloatwaitingfalse
+ \gdef\dopopsavedfloats
+ {\global\advance\savednoffloats\savedsavednoffloats
+ \global\setbox\floatlist\vbox\bgroup
+ \ifvoid\floatlist \else\unvbox\floatlist \fi
+ \ifvoid\savedfloatlist\else\unvbox\savedfloatlist\fi
+ \egroup
+ \global\ifcase\savednoffloats
+ \somefloatwaitingfalse\else\somefloatwaitingtrue\fi
+ \globallet\dopopsavedfloats\relax}}
+
+\def\doflushsavedfloats % simplified \OTRONEdodoflushfloats
+ {\doloop
+ {\ifsomefloatwaiting
+ \dogetfloat
+ \dofloatflushedinfo
+ \docheckiffloatfits
+ \ifroomforfloat
+ \doplacefloatbox
+ \else
+ \doreversesavefloat
+ \exitloop
+ \fi
+ \else
+ \exitloop
+ \fi}}
+
+% top and bottom
+
+\newif\iftopofinsert
+\newif\iftestfloatbox
+\newif\ifcenterfloatbox \centerfloatboxtrue
+\newif\iflocalcenterfloatbox \localcenterfloatboxfalse
+\newif\ifglobalcenterfloatbox \globalcenterfloatboxfalse
+
+% beter de laatste skip buiten de \insert uitvoeren,
+% bovendien bij volle flush onder baseline.
+
+\def\betweenfloatblanko% assumes that spaceafter is present
+ {\bgroup
+ \setbox0\vbox{\strut\blank[\floatsharedparameter\c!spacebefore]\strut}%
+ \setbox2\vbox{\strut\blank[\floatsharedparameter\c!spaceafter]\strut}%
+ \ifdim\ht0>\ht2
+ \blank[-\floatsharedparameter\c!spaceafter,\floatsharedparameter\c!spacebefore]%
+ \fi
+ \egroup}
+
+\def\doplacefloatbox
+ {%\forgetall % NO
+ \whitespace
+ \blank[\floatsharedparameter\c!spacebefore]
+ \flushfloatbox
+ \blank[\floatsharedparameter\c!spaceafter]}
+
+\ifx\someherefloat\undefined \let\someherefloat\doplacefloatbox \fi
+\ifx\somefixdfloat\undefined \let\somefixdfloat\doplacefloatbox \fi
+\ifx\somepagefloat\undefined \let\somepagefloat\doplacefloatbox \fi
+\ifx\sometopsfloat\undefined \let\sometopsfloat\doplacefloatbox \fi
+\ifx\somebotsfloat\undefined \let\somebotsfloat\doplacefloatbox \fi
+
+\ifx\somesidefloat\undefined \let\somesidefloat\doplacefloatbox \fi
+\ifx\somefacefloat\undefined \let\somefacefloat\doplacefloatbox \fi
+\ifx\sometextfloat\undefined \let\sometextfloat\doplacefloatbox \fi
+
+% brr, wordt deze niet overladen in page-one? weg er mee
+
+% \def\somepagefloat[#1]% links, rechts, midden, hoog, midden, laag
+% {%\checkwaitingfloats{#1}%
+% \global\setbox\collectedpagefloats\vbox
+% {\unvbox\collectedpagefloats
+% \vbox to \textheight
+% {\doifnotinset\v!high{#1}\vfill
+% \box\floatbox
+% \doifnotinset\v!low{#1}\vfill}%
+% \goodbreak}%
+% \doinsertfloatinfo}
+
+% \def\OTRONEsomepagefloat[#1]%
+% {%\checkwaitingfloats{#1}%
+% \global\setbox\collectedpagefloats\vbox
+% {\ifvoid\collectedpagefloats\else\unvbox\collectedpagefloats\fi
+% \vbox to \textheight % vss and unvbox catch too high and limited floats
+% {\vss
+% \doifnotinset\v!high{#1}\vfill
+% \unvbox\floatbox
+% \doifnotinset\v!low{#1}\vfill
+% \vss}%
+% \goodbreak}%
+% \doinsertfloatinfo}
+
+% test case:
+%
+% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=0.9\textheight,color=green]}
+% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.0\textheight,color=green]}
+% \placefigure[page,none]{}{\blackrule[width=\textwidth,height=1.1\textheight,color=green]}
+
+\def\sometextfloat[#1]% lang, links, rechts, hoog, midden, laag, offset
+ {%\checkwaitingfloats{#1}%
+ \gdef\dostoptextfloat{\dodostoptextfloat[#1]}% brr global
+ \global\floattextwidth\hsize
+ \global\floatwidth\wd\floatbox
+ \global\floatheight\ht\floatbox % forget about the depth
+ \global\advance\floattextwidth -\floatwidth
+ \global\advance\floattextwidth -\floatsharedparameter\c!margin\relax % was \tfskipsize
+ \doifinsetelse\v!tall{#1}
+ {\floattextheight\pagegoal
+ \advance\floattextheight -\pagetotal
+ \advance\floattextheight -\bigskipamount % lelijk
+ \ifdim\floattextheight>\textheight
+ \floattextheight\textheight
+ \fi
+ \boxmaxdepth\zeropoint \relax % toegevoegd
+ \ifdim\floattextheight<\floatheight
+ \floattextheight\floatheight
+ \fi
+ \setbox\floattext\vbox to \floattextheight}
+ {\setbox\floattext\vbox}%
+ \bgroup
+ \forgetall \setupblank \setupwhitespace % new, also needed for footnotes
+ \blank[\v!disable]
+ \hsize\floattextwidth
+ \ignorespaces}
+
+\def\dodostoptextfloat[#1]% % de tekst kan beter in een soort
+ {\egroup % kadertekst zonder kader, is flexibeler
+ \doifnotinset\v!tall{#1}% en beter
+ {\ifdim\ht\floattext<\floatheight
+ \floattextheight\floatheight
+ \else
+ \floattextheight\ht\floattext
+ \fi}%
+ \setbox\floatbox\vbox to \floattextheight
+ {\hsize\floatwidth
+ \doifinsetelse\v!both{#1}%
+ {\doifinsetelse\v!low{#1}
+ {\vfill\box\floatbox}
+ {\doifinsetelse\v!middle{#1}
+ {\vfill\box\floatbox\vfill}
+ {\box\floatbox\vfill}}}
+ {\box\floatbox\vfill}}%
+ \setbox\floattext\vbox to \floattextheight
+ {\hsize\floattextwidth
+ \doifinsetelse\v!low{#1}
+ {\vfill
+ \box\floattext
+ \doifinset\c!offset{#1}{\whitespace\blank}}
+ {\doifinsetelse\v!middle{#1}
+ {\vfill
+ \box\floattext
+ \vfill}
+ {\doifinset\v!offset{#1}{\whitespace\blank}%
+ \box\floattext
+ \vfill}}}%
+ \doifinsetelse\v!right{#1}% \floatmethod
+ {\setbox\floatbox\hbox to \hsize
+ {\box\floattext
+ \hfill
+ \box\floatbox}}
+ {\setbox\floatbox\hbox to \hsize
+ {\box\floatbox
+ \hfill
+ \box\floattext}}%
+ \baselinecorrection
+ \whitespace
+ \blank[\floatsharedparameter\c!spacebefore]%
+ \doifnotinset\v!tall{#1}%
+ {\dp\floatbox\openstrutdepth}% dp\strutbox}% % toegevoegd
+ \box\floatbox
+ \blank[\floatsharedparameter\c!spaceafter]%
+ \endgroup % **
+ \doinsertfloatinfo}
+
+\def\somefacefloat[#1]% links, rechts, midden, hoog, midden, laag
+ {%\checkwaitingfloats{#1}%
+ \startopposite\box\floatbox\stopopposite
+ \doinsertfloatinfo}
+
+\def\someelsefloat[#1]%
+ {\doifinsetelse\v!here{#1}
+ {\doifinsetelse\v!always{#1}
+ {\page[\v!preference]%
+ \docheckiffloatfits
+ \ifroomforfloat
+ \placesomeherefloat[#1]%
+ \else
+ \showmessage\m!floatblocks9\empty
+ \doreversesavefloat
+ \fi}
+ {\ifsomefloatwaiting
+ \dosavefloat
+ \else
+ \page[\v!preference]%
+ \docheckiffloatfits
+ \ifroomforfloat
+ \placesomeherefloat[#1]%
+ \else
+ \dosavefloat
+ \fi
+ \fi}}
+ {\doifinsetelse\v!always{#1}
+ {\docheckiffloatfits
+ \ifroomforfloat
+ \sometopbottomfloat[#1]
+ \else
+ \showmessage\m!floatblocks9\empty
+ \doreversesavefloat
+ \fi}
+ {\docheckiffloatfits
+ \ifroomforfloat
+ \sometopbottomfloat[#1]
+ \else
+ \dosavefloat
+ \fi}}}
+
+\def\floatautofactor{.5}
+
+\def\sometopbottomfloat[#1]%
+ {\doifelse\floatmethod\v!auto
+ {\ifdim\pagetotal<\floatautofactor\pagegoal % when empty page, maxdimen
+ \placesometopsfloat[#1]%
+ \else
+ \placesomebotsfloat[#1]%
+ \fi}
+ {\doifelse\floatmethod\v!top
+ {\placesometopsfloat[#1]}
+ {\doifelse\floatmethod\v!bottom
+ {\placesomebotsfloat[#1]}
+ {\placesomeherefloat[#1]}}}}
+
+% De onderstaande macro wordt gebruikt bij de macros
+% voor het plaatsen van tabellen en figuren (klopt niet
+% meer).
+%
+% \dofloat {plaats} {label1} {label2}
+% \docompletefloat {nummer} {referentie} {plaats} {label} {inhoud}
+% \box\floatbox inhoud+referentie
+% \do???float#1 #1 = boxnummer
+
+\newdimen\floatsideskip \floatsideskip =12pt
+\newdimen\floattopskip \floattopskip =\floattopskip
+\newdimen\floatbottomskip \floatbottomskip=\floattopskip
+
+\newdimen\sidefloattopskip \sidefloattopskip =\floattopskip
+\newdimen\sidefloatbottomskip \sidefloatbottomskip=\floatbottomskip
+
+\newskip\sidefloatdownshift
+\newskip\sidefloatleftshift
+\newskip\sidefloatrightshift
+
+\def\sidefloattopoffset {\openstrutdepth} % {\strutdp}
+
+\newcount\noftopfloats \noftopfloats=2
+\newcount\nofbotfloats \nofbotfloats=0
+
+\def\docalculatefloatskip#1#2%
+ {\doifelsenothing{#2}
+ {\global#1\zeropoint}
+ {\doifelse{#2}\v!none
+ {\global#1\zeropoint}
+ {\setbox\scratchbox\vbox{\whitespace\normalexpanded{\noexpand\blank[#2]}}%
+ \global#1\ht\scratchbox}}}
+
+\def\calculatefloatskips
+ {{\docalculatefloatskip\floattopskip{\floatsharedparameter\c!spacebefore}%
+ \docalculatefloatskip\floatbottomskip{\floatsharedparameter\c!spaceafter}%
+ \docalculatefloatskip\sidefloattopskip{\floatsharedparameter\c!sidespacebefore}%
+ \docalculatefloatskip\sidefloatbottomskip{\floatsharedparameter\c!sidespaceafter}%
+ \gdef\sidefloattopoffset{\openstrutdepth}% was \def
+ \global\floatsideskip\floatsharedparameter\c!margin
+ \global\sidefloatleftshift\floatparameter\c!leftmargindistance
+ \global\sidefloatrightshift\floatparameter\c!rightmargindistance
+ \global\noftopfloats\floatsharedparameter\c!ntop\relax
+ \global\nofbotfloats\floatsharedparameter\c!nbottom\relax}}
+
+\def\borderedfloatbox
+ {\localframed
+ [\??fl\currentfloat]
+ [\c!location=\v!normal,\c!width=\wd\floatbox,\c!height=\htdp\floatbox]
+ {\box\floatbox}}
+
+\newbox\tempfloatbox
+
+% minwidth=fit,width=max : no overshoot, as wide as graphic
+
+\ifx\moveboxontogrid\undefined \let\movecaptionontogrid\gobblethreearguments \fi
+
+\def\locatefloatbox
+ {\chardef\alignstrutmode\zerocount
+ \shiftalignedline
+ {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}%
+ {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}%
+ \alignedline{\floatparameter\c!location}\v!middle}
+
+\def\locatecaptionbox
+ {\chardef\alignstrutmode\zerocount
+ \shiftalignedline
+ {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}%
+ {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}%
+ \alignedline{\floatparameter\c!location}\v!middle}
+
+\long\def\dosetpagfloat#1#2#3% \copy wegwerken
+ {\bgroup
+ \setlocalfloathsize
+ \ifnum\floatrotation>0
+ \swapdimens\hsize\vsize
+ \fi
+ \forgetall
+ \postponenotes
+ \dontcomplain
+ \setbox\tempfloatbox\vbox{\borderedfloatbox}%
+ \let\locatefloat \locatefloatbox
+ \let\locatecaption\locatecaptionbox
+ \docheckcaptioncontent{#2}{#3}%
+ \ifcase\floatparameter\c!method
+ \or % automatic
+ \ifnofloatcaption
+ \dopreparenocaption{#1}{#2}{#3}%
+ \edef\width{\the\wd\floatbox}%
+ \doglobal\addlocalbackgroundtobox\floatbox
+ \else
+ % todo: installable maken, variant/method=auto vs macro
+ \dopreparedocaption{#1}{#2}{#3}%
+ \settracedcaptionbox
+ \edef\width{\the\wd\tempfloatbox}%
+ \addlocalbackgroundtobox\tempfloatbox
+ \setbox\tempcaptionbox\hbox
+ {\dosetcaptionthings
+ \floatcaptionparameter\c!command{\box\tempcaptionbox}}%
+ \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht
+ \addlocalbackgroundtobox\tempcaptionbox
+ \buildfloatbox
+ \fi
+ \or % semi automatic
+ \or % manual
+ \fi
+ \ifnum\floatrotation>0
+ \global\setbox\floatbox\vbox
+ {\rotate[\c!rotation=\floatrotation]{\box\floatbox}}%
+ \edef\width{\the\wd\tempfloatbox}%
+ \else
+ \postcenterfloatbox\width
+ \fi
+ \egroup}
+
+\def\captionminwidth {15\bodyfontsize}
+\def\captionovershoot {2em}
+
+\def\dopreparenocaption#1#2#3%
+ {\global\setbox\floatbox\vbox % pas op als wd groter dan hsize
+ {\ifinsidecolumns\ifdim\wd\tempfloatbox>\hsize
+ \let\locatefloat\relax
+ \fi\fi
+ \locatefloat{\copy\tempfloatbox}}}
+
+\def\dopreparedocaption#1#2#3%
+ {\doifinsetelse{\floatcaptionparameter\c!location}{\v!top,\v!bottom}
+ {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max}
+ {\doifelse{\floatcaptionparameter\c!minwidth}\v!fit
+ {\doifelse{\floatcaptionparameter\c!width}\v!max
+ {\dopreparestackcaptionmax{#1}{#2}{#3}}
+ {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox % wider caption
+ \doifelse{\floatcaptionparameter\c!width}\v!fit
+ {\dopreparestackcaptionaut{#1}{#2}{#3}}
+ {\dopreparestackcaptionwid{#1}{#2}{#3}}%
+ \else
+ \dopreparestackcaptionmin{#1}{#2}{#3}%
+ \fi}}
+ {\dopreparestackcaptionfix{#1}{#2}{#3}}}%
+ {\dopreparesidewidthcaption{#1}{#2}{#3}}}% new, special effects (see icare)
+ {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max}
+ {\dopreparesideautocaption{#1}{#2}{#3}}
+ {\dopreparesidewidthcaption{#1}{#2}{#3}}}}
+
+% \def\dosettempcaptionbox
+% {\dosetraggedvbox{\floatcaptionparameter\c!align}%
+% \setbox\tempcaptionbox\raggedbox}
+
+\def\dosettempcaptionbox
+ {\setbox\tempcaptionbox\vbox\bgroup
+ %expanded{\setupalign[\v!new,\v!reset,\floatcaptionparameter\c!align,\v!old]}% wrong! see icare
+ \normalexpanded{\noexpand\setupalign[\v!reset,\floatcaptionparameter\c!align]}% i need to check what reset does
+ \dosetcaptionthings
+ \let\next}
+
+\def\dopreparesideautocaption#1#2#3%
+ {\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\floatparameter\c!margin\relax % was \tfskipsize\relax
+ \ifdim\wd\tempcaptionbox>\scratchdimen
+ \ifdim\wd\tempcaptionbox<1.3\scratchdimen
+ \scratchdimen0.8\scratchdimen
+ \fi
+ \fi
+ \dosettempcaptionbox
+ {\hsize\scratchdimen
+ \putcompletecaption{#2}{#3}}}
+
+\def\dopreparesidewidthcaption#1#2#3%
+ {\dosettempcaptionbox
+ {\hsize\floatcaptionparameter\c!width
+ \putcompletecaption{#2}{#3}}}
+
+\def\dopreparestackcaptionfix#1#2#3%
+ {\dosettempcaptionbox
+ {\hsize\floatcaptionparameter\c!minwidth % special effects
+ \putcompletecaption{#2}{#3}}}
+
+\def\dopreparestackcaptionmax#1#2#3%
+ {\dosettempcaptionbox
+ {\hsize\wd\tempfloatbox
+ \putcompletecaption{#2}{#3}}}
+
+\def\dopreparestackcaptionwid#1#2#3%
+ {\dosettempcaptionbox
+ {\hsize\floatcaptionparameter\c!width
+ \putcompletecaption{#2}{#3}}}
+
+\def\dopreparestackcaptionmin#1#2#3%
+ {\dosettempcaptionbox
+ {\hsize\wd\tempfloatbox
+ \doifnothing{\floatcaptionparameter\c!align}\raggedcenter % on purpose overloads align !
+ \putcompletecaption{#2}{#3}}}
+
+\def\dopreparestackcaptionaut#1#2#3%
+ {\doifsomething{\floatcaptionparameter\c!align}
+ {\doifnotinset{\v!middle}{\floatcaptionparameter\c!align}%
+ {\let\captionovershoot\!!zeropoint}}%
+ \edef\captionhsize{\the\wd\tempfloatbox}%
+ \ifdim\captionhsize>\hsize
+ % float is wider than \hsize
+ \dosettempcaptionbox
+ {\trialtypesettingtrue
+ \hsize\captionhsize
+ \notesenabledfalse
+ \putcompletecaption{#2}{#3}}%
+ \ifdim\ht\scratchbox>\lineheight % more lines
+ \dosettempcaptionbox
+ {\hsize\captionhsize
+ \advance\hsize -\captionovershoot\relax
+ \ifdim\hsize<\captionminwidth\relax
+ \hsize\captionhsize
+ \fi
+ \putcompletecaption{#2}{#3}}%
+ \else
+ \dosettempcaptionbox
+ {\hsize\captionhsize
+ \putcompletecaption{#2}{#3}}%
+ \fi
+ \else
+ % float is smaller of equal to \hsize
+ \ifdim\captionhsize<\captionminwidth\relax
+ \scratchdimen\captionminwidth % float smaller than min width
+ \edef\captionhsize{\the\scratchdimen}%
+ \fi
+ \setbox\scratchbox\vbox % test with overshoot
+ {\trialtypesettingtrue
+ \scratchdimen\captionhsize
+ \advance\scratchdimen \captionovershoot
+ \advance\scratchdimen 3em % an average word length
+ \ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi
+ \notesenabledfalse
+ \putcompletecaption{#2}{#3}}%
+ \ifdim\ht\scratchbox>\lineheight
+ % at least an average word longer than a line
+ \dosettempcaptionbox
+ {\scratchdimen\captionhsize
+ \advance\scratchdimen \captionovershoot
+ \ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi
+ \putcompletecaption{#2}{#3}}%
+ \else
+ % just over a line, don't use an overshoot % % % todo: outer/inner and such
+ \doifcommonelse{\floatcaptionparameter\c!align}{\v!left,\v!right,\v!flushleft,\v!flushright}
+ {\dosettempcaptionbox
+ {\hsize\captionhsize
+ % strange : \raggedcenter
+ \putcompletecaption{#2}{#3}}}
+ {% nicer
+ \dosettempcaptionbox
+ {\hsize\captionhsize
+ \doifnothing{\floatcaptionparameter\c!align}\raggedcenter% overloads
+ \putcompletecaption{#2}{#3}}}%
+ \fi
+ \fi}
+
+\def\dopreparesidecaption#1#2#3%
+ {\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\floatparameter\c!margin\relax % was \tfskipsize\relax
+ \ifdim\wd\tempcaptionbox>\scratchdimen
+ \ifdim\wd\tempcaptionbox<1.3\scratchdimen
+ \scratchdimen0.8\scratchdimen
+ \fi
+ \fi
+ \dosettempcaptionbox % \setbox\tempcaptionbox\vbox
+ {\hsize\scratchdimen
+ \doifnothing{\floatcaptionparameter\c!align}\raggedright % on purpose overloads align !
+ \putcompletecaption{#2}{#3}}}
+
+\newdimen\tempfloatheight
+\newdimen\tempfloatwidth
+
+\def\dofloatboxbetweenstack
+ {\endgraf\nointerlineskip\floatcaptionparameter\c!inbetween\endgraf}
+
+\def\dofloatboxdefaultbuilder % done
+ {\locatefloat{\box\tempfloatbox}}
+
+\def\dofloatboxnextrightbuilder#1%
+ {\ifparfloat \hbox \else \expandafter \locatefloat \fi
+ {\tempfloatheight\ht\tempfloatbox
+ \box\tempfloatbox
+ \normalexpanded{\noexpand\doifnotinset{\v!hang}{\floatcaptionparameter\c!location}}{\dotfskip{\floatcaptionparameter\c!distance}}%
+ \vbox to\tempfloatheight{#1}}}
+
+\def\dofloatboxnextleftbuilder#1%
+ {\ifparfloat \hbox \else \expandafter \locatefloat \fi
+ {\tempfloatheight\ht\tempfloatbox
+ \vbox to\tempfloatheight{#1}%
+ \normalexpanded{\noexpand\doifnotinset{\v!hang}{\floatcaptionparameter\c!location}}{\dotfskip{\floatcaptionparameter\c!distance}}%
+ \box\tempfloatbox}}
+
+\def\dofloatboxnextouterbuilder
+ {\doifrightpagefloatelse\dofloatboxnextrightbuilder\dofloatboxnextleftbuilder}
+\def\dofloatboxnextinnerbuilder
+ {\doifrightpagefloatelse\dofloatboxnextleftbuilder\dofloatboxnextrightbuilder}
+
+\def\dofloatboxnextrighthangbuilder#1%
+ {\ifparfloat \hbox \else \expandafter \locatefloat \fi
+ {\tempfloatheight\ht\tempfloatbox
+ \box\tempfloatbox
+ \vbox to\tempfloatheight{#1}}}
+
+\def\dofloatboxnextlefthangbuilder#1%
+ {\ifparfloat \hbox \else \expandafter \locatefloat \fi
+ {\tempfloatheight\ht\tempfloatbox
+ \vbox to\tempfloatheight{#1}%
+ \box\tempfloatbox}}
+
+\def\dodofloatboxnextrightmarginbuilder#1#2%
+ {\ifparfloat
+ \hbox\bgroup
+ \tempfloatheight\ht\tempfloatbox
+ \box\tempfloatbox
+ \hsmash{\hskip#1\vbox to\tempfloatheight{#2}}%
+ \egroup
+ \else
+ \begingroup
+ \tempfloatheight\ht\tempfloatbox
+ \everyrightofalignedline{\hsmash{\hskip#1\vbox to\tempfloatheight{#2}}}%
+ \locatefloat{\box\tempfloatbox}%
+ \endgroup
+ \fi}
+
+\def\dodofloatboxnextleftmarginbuilder#1#2%
+ {\ifparfloat
+ \hbox\bgroup
+ \tempfloatheight\ht\tempfloatbox
+ \hsmash{\hskip-\dimexpr#1+\wd\tempcaptionbox\relax\vbox to\tempfloatheight{#2}}%
+ \box\tempfloatbox
+ \egroup
+ \else
+ \begingroup
+ \tempfloatheight\ht\tempfloatbox
+ \everyleftofalignedline{\hsmash{\hskip-\dimexpr#1+\wd\tempcaptionbox\relax\vbox to\tempfloatheight{#2}}}%
+ \locatefloat{\box\tempfloatbox}%
+ \endgroup
+ \fi}
+
+\def\dofloatboxnextrightmarginbuilder{\dodofloatboxnextrightmarginbuilder\rightmargindistance}
+\def\dofloatboxnextleftmarginbuilder {\dodofloatboxnextleftmarginbuilder \leftmargindistance }
+
+\def\dofloatboxnextoutermarginbuilder
+ {\doifrightpagefloatelse
+ {\dodofloatboxnextrightmarginbuilder\rightmargindistance}
+ {\dodofloatboxnextleftmarginbuilder \rightmargindistance}}
+
+\def\dofloatboxnextinnermarginbuilder
+ {\doifrightpagefloatelse
+ {\dodofloatboxnextleftmarginbuilder \leftmargindistance}
+ {\dodofloatboxnextrightmarginbuilder\leftmargindistance}}
+
+\def\dofloatboxnextbuilder % beware, we first check on left/rightmargin because there can be left/right also
+ {\let\next\dofloatboxnextleftbuilder
+ \normalexpanded{\noexpand\processallactionsinset[\floatcaptionparameter\c!location]}
+ [ \v!outermargin=>\let\next\dofloatboxnextoutermarginbuilder,
+ \v!innermargin=>\let\next\dofloatboxnextinnermarginbuilder,
+ \v!leftmargin=>\let\next\dofloatboxnextleftmarginbuilder,
+ \v!rightmargin=>\let\next\dofloatboxnextrightmarginbuilder,
+ \v!lefthanging=>\let\next\dofloatboxnextlefthangbuilder,
+ \v!righthanging=>\let\next\dofloatboxnextrighthangbuilder,
+ \v!outer=>\let\next\dofloatboxnextouterbuilder,
+ \v!inner=>\let\next\dofloatboxnextinnerbuilder,
+ \v!left=>\let\next\dofloatboxnextleftbuilder,
+ \v!right=>\let\next\dofloatboxnextrightbuilder]%
+ \next}
+
+\def\dofloatboxsidebuilder
+ {\ifparfloat
+ \let\next\dofloatboxhighbuilder
+ \else
+ \let\next\dofloatboxmiddlebuilder
+ \expanded{\processallactionsinset[\floatcaptionparameter\c!location]}
+ [ \v!low=>\let\next\dofloatboxlowbuilder,
+ \v!middle=>\let\next\dofloatboxmiddlebuilder,
+ \v!high=>\let\next\dofloatboxhighbuilder]%
+ \fi
+ \next}
+
+\def\doflushfloatleftcaptionhang
+ {\hsmash{\llap{\box\tempcaptionbox\dotfskip{\floatcaptionparameter\c!distance}}}}
+\def\doflushfloatrightcaptionhang
+ {\hsmash{\rlap{\dotfskip{\floatcaptionparameter\c!distance}\box\tempcaptionbox}}}
+
+\def\doflushfloatcaptionhang
+ {\expanded{\doifinsetelse{\v!righthanging}{\floatcaptionparameter\c!location}}
+ {\doflushfloatrightcaptionhang}
+ {\expanded{\doifinsetelse{\v!lefthanging}{\floatcaptionparameter\c!location}}
+ {\doflushfloatleftcaptionhang}
+ {\expanded{\doifinsetelse{\v!hang}{\floatcaptionparameter\c!location}}
+ {\expanded{\doifinsetelse{\v!outer}{\floatcaptionparameter\c!location}}
+ {\doifrightpagefloatelse{\doflushfloatrightcaptionhang}{\doflushfloatleftcaptionhang}}
+ {\expanded{\doifinsetelse{\v!right}{\floatcaptiondirectives}}
+ {\doflushfloatrightcaptionhang}
+ {\doflushfloatleftcaptionhang}}}
+ {\box\tempcaptionbox}}}}
+
+\def\dofloatboxhighbuilder
+ {\dofloatboxnextbuilder{\dofloatboxbetweenstack\doflushfloatcaptionhang\vfill}}
+
+\def\dofloatboxlowbuilder
+ {\dofloatboxnextbuilder{\vfill\doflushfloatcaptionhang\dofloatboxbetweenstack}}
+
+\def\dofloatboxmiddlebuilder
+ {\dofloatboxnextbuilder{\vfill\box\tempcaptionbox\vfill}}
+
+% \definefloat
+% [lefty][lefties][figure]
+% \setupfloat
+% [lefty]
+% [default=left,
+% rightmargindistance=-2cm,
+% leftmargindistance=-2cm]
+% \setupcaption
+% [lefty]
+% [location={bottom,overlay}]
+%
+% \starttext
+% \placelefty{}{} \input tufte \input tufte
+% \placelefty{}{} \input tufte \input tufte
+% \stoptext
+
+\def\bothangfloat#1{\ruledvbox to \ht\tempfloatbox{#1\vss}}
+\def\tophangfloat#1{\ruledvbox to \ht\tempfloatbox{\vss#1}}
+
+\def\dofloatboxnormaltopstackbuilder
+ {\expanded{\doifinset{\v!overlay}{\floatcaptionparameter\c!location}}\tophangfloat
+ {\tempfloatwidth\wd\tempfloatbox
+ \ifparfloat
+ \hbox{\locatesidefloat{\box\tempcaptionbox}}%
+ \dofloatboxbetweenstack
+ \hbox{\hbox {\box\tempfloatbox }}%
+ \else
+ \hbox{\locatetextfloat{\box\tempcaptionbox}}
+ \dofloatboxbetweenstack
+ \hbox{\locatefloat {\box\tempfloatbox }}%
+ \fi}}
+
+\def\dofloatboxnormalbotstackbuilder
+ {\expanded{\doifinset{\v!overlay}{\floatcaptionparameter\c!location}}\bothangfloat
+ {\tempfloatwidth\wd\tempfloatbox
+ \ifparfloat
+ \hbox{\hbox {\box\tempfloatbox }}%
+ \dofloatboxbetweenstack
+ \hbox{\locatesidefloat{\box\tempcaptionbox}}%
+ \else
+ \hbox{\locatefloat {\box\tempfloatbox }}%
+ \dofloatboxbetweenstack
+ \hbox{\locatetextfloat{\box\tempcaptionbox}}%
+ \fi}}
+
+\def\dofloatboxgridtopstackbuilder
+ {\dp\tempcaptionbox\strutdepth
+ \setbox\scratchbox\vbox
+ {\tempfloatwidth\wd\tempfloatbox
+ \ifparfloat
+ \locatesidefloat{\box\tempcaptionbox}%
+ \vss\dofloatboxbetweenstack
+ \hbox {\box\tempfloatbox }%
+ \else
+ \locatetextfloat{\box\tempcaptionbox}%
+ \vss\dofloatboxbetweenstack
+ \locatefloat {\box\tempfloatbox }%
+ \fi}%
+ \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
+ \vbox to \noflines\lineheight{\unvbox\scratchbox}}
+
+\def\dofloatboxgridbotstackbuilder
+ {\dp\tempcaptionbox\strutdepth
+ \setbox\scratchbox\vbox
+ {\tempfloatwidth\wd\tempfloatbox
+ \ifparfloat
+ \hbox {\box\tempfloatbox }%
+ \vss\dofloatboxbetweenstack
+ \locatesidefloat{\box\tempcaptionbox}%
+ \else
+ \locatefloat {\box\tempfloatbox }%
+ \vss\dofloatboxbetweenstack
+ \locatetextfloat{\box\tempcaptionbox}%
+ \fi}%
+ \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
+ \vbox to \noflines\lineheight{\unvbox\scratchbox}}
+
+\def\dofloatboxstretchtopstackbuilder
+ {\dp\tempcaptionbox\strutdepth
+ \setbox\scratchbox\vbox
+ {\locatecaption{\copy\tempcaptionbox}%
+ \locatefloat {\copy\tempfloatbox }}%
+ \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
+ \vbox to \noflines\lineheight
+ {\tempfloatwidth\wd\tempfloatbox
+ \ifparfloat
+ \locatesidefloat{\box\tempcaptionbox}%
+ \vss\dofloatboxbetweenstack\vss
+ \hbox {\box\tempfloatbox }%
+ \else
+ \locatetextfloat{\box\tempcaptionbox}%
+ \vss\dofloatboxbetweenstack\vss
+ \locatefloat {\box\tempfloatbox }%
+ \fi}}
+
+\def\dofloatboxstretchbotstackbuilder
+ {\dp\tempcaptionbox\strutdepth
+ \setbox\scratchbox\vbox
+ {\locatefloat {\copy\tempfloatbox }%
+ \locatecaption{\copy\tempcaptionbox}}%
+ \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
+ \vbox to \noflines\lineheight
+ {\tempfloatwidth\wd\tempfloatbox
+ \ifparfloat
+ \hbox {\box\tempfloatbox }%
+ \vss\dofloatboxbetweenstack\vss
+ \locatesidefloat{\box\tempcaptionbox}
+ \else
+ \locatefloat {\box\tempfloatbox }%
+ \vss\dofloatboxbetweenstack\vss
+ \locatetextfloat{\box\tempcaptionbox}%
+ \fi}}
+
+\def\dofloatboxtopbuilder
+ {\let\next\dofloatboxnormaltopstackbuilder
+ \expanded{\processfirstactioninset[\floatcaptionparameter\c!location]}
+ [ \v!grid=>\let\next\dofloatboxgridstackbuilder,
+ \v!stretch=>\let\next\dofloatboxstretchstackbuilder]%
+ \next}
+
+\def\dofloatboxbottombuilder
+ {\let\next\dofloatboxnormalbotstackbuilder
+ \expanded{\processfirstactioninset[\floatcaptionparameter\c!location]}
+ [ \v!grid=>\let\next\dofloatboxgridstackbuilder,
+ \v!stretch=>\let\next\dofloatboxstretchstackbuilder]%
+ \next}
+
+\def\relocatecaptionright#1{\locatecaption{\hbox to \tempfloatwidth{\hss#1}}}
+\def\relocatecaptionleft #1{\locatecaption{\hbox to \tempfloatwidth{#1\hss}}}
+
+\long\def\installfloatboxbuilder#1#2{\setvalue{\??kj:#1}{#2}}
+
+\def\buildfloatbox
+ {\global\setbox\floatbox\vbox
+ {\setlocalfloathsize
+ \forgetall
+ \let\floatcaptionarrangement\s!default
+ \def\docommand##1%
+ {\doifdefined{\??kj:##1}{\def\floatcaptionarrangement{##1}\quitcommalist}}%
+ \processcommacommand[\floatcaptionparameter\c!location]\docommand
+ \executeifdefined{\??kj:\floatcaptionarrangement}{\getvalue{\??kj:\s!default}}}}
+
+\def\locatetextfloat
+ {\let\next\locatecaption
+ \expanded{\processallactionsinset[\floatcaptionparameter\c!location]}
+ [ \v!left=>\let\next\relocatecaptionleft,
+ \v!right=>\let\next\relocatecaptionright,
+ \v!inner=>\doifrightpagefloatelse{\let\next\relocatecaptionleft }{\let\next\relocatecaptionright},
+ \v!outer=>\doifrightpagefloatelse{\let\next\relocatecaptionright}{\let\next\relocatecaptionleft }]%
+ \next}
+
+\installfloatboxbuilder \v!none \dofloatboxdefaultbuilder
+\installfloatboxbuilder \s!default \dofloatboxdefaultbuilder
+\installfloatboxbuilder \v!high \dofloatboxhighbuilder
+\installfloatboxbuilder \v!low \dofloatboxlowbuilder
+\installfloatboxbuilder \v!middle \dofloatboxmiddlebuilder
+
+\installfloatboxbuilder \v!left \dofloatboxsidebuilder
+\installfloatboxbuilder \v!right \dofloatboxsidebuilder
+
+\installfloatboxbuilder \v!top \dofloatboxtopbuilder
+\installfloatboxbuilder \v!bottom \dofloatboxbottombuilder
+
+% \setuplayout[grid=yes] \showgrid \setupcaptions[style=smallbodyfont,location=grid,inbetween=]
+%
+% \starttext
+% test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=yes]} test \page
+% test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=yes]} test \page
+% test \placefigure{} {\externalfigure[cow.pdf][frame=on,grid=depth]} test \page
+% test \placefigure{\input zapf\relax}{\externalfigure[cow.pdf][frame=on,grid=depth]} test \page
+% \stoptext
+
+\newif\ifpostponecolumnfloats \postponecolumnfloatsfalse % don't change
+
+\chardef\postcenterfloatmethod\plusone
+
+\def\postcenterfloatbox#1%
+ {\scratchdimen
+ \ifcase\postcenterfloatmethod
+ #1% \wd\floatbox
+ \or\ifinsidecolumns
+ \ifpostponecolumnfloats\makeupwidth\else#1\fi
+ \else\ifdim#1>\hsize
+ \hsize
+ \else
+ \wd\floatbox
+ \fi\fi\fi
+ \global\setbox\floatbox\hbox to \scratchdimen
+ % {\hfill\box\floatbox\hfill}} % geen \hss, gaat mis in kolommen !
+ % {\hss \box\floatbox\hss }} % wel \hss, anders mis in colset
+ {\ifglobalcenterfloatbox
+ \donetrue
+ \else\iflocalcenterfloatbox
+ \donetrue
+ \else
+ \donefalse
+ \fi\fi
+ \ifdim\scratchdimen>\effectivehsize
+ \donefalse
+ \fi
+ \hss\ifdone\hskip\effectiveleftskip\fi
+ \box\floatbox
+ \ifdone\hskip\effectiverightskip\fi\hss}}
+
+\long\def\dosetparfloat#1#2#3%
+ {\bgroup
+ \forgetall
+ \postponenotes
+ \dontcomplain
+ %\showcomposition
+ \setbox\tempfloatbox\vbox{\borderedfloatbox}%
+ \addlocalbackgroundtobox\tempfloatbox % no \doglobal
+ \docheckcaptioncontent{#2}{#3}%
+ \ifnofloatcaption
+ \global\setbox\floatbox\vbox{\box\tempfloatbox}%
+ \else
+ \dopreparedosidecaption{#1}{#2}{#3}%
+ \settracedcaptionbox
+ \setbox\tempcaptionbox\hbox{\floatcaptionparameter\c!command{\box\tempcaptionbox}}%
+ \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht
+ \addlocalbackgroundtobox\tempcaptionbox % no \doglobal
+ \buildsidefloatbox
+ \fi
+ \egroup}
+
+\def\dopreparedosidecaption#1#2#3% will be enhanced
+ {\doifelse{\floatcaptionparameter\c!width}\v!max
+ {\dosettempcaptionbox
+ {\hsize\wd\tempfloatbox
+ \putcompletecaption{#2}{#3}}}%
+ {\doifelse{\floatcaptionparameter\c!width}\v!fit
+ {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox\relax
+ \setbox\tempcaptionbox\vbox
+ {\forgetall % needed?
+ \hsize\wd\tempfloatbox
+ \dosetcaptionthings
+ \putcompletecaption{#2}{#3}}%
+ \else
+ \setbox\tempcaptionbox\hbox to \wd\tempfloatbox
+ {\hss\box\tempcaptionbox\hss}%
+ \fi}
+ {\dosettempcaptionbox
+ {\hsize\floatcaptionparameter\c!width % \wd\tempfloatbox
+ \putcompletecaption{#2}{#3}}}}}
+
+\def\buildsidefloatbox
+ {\let\locatefloat \relax
+ \let\locatecaption\relax
+ \def\locatesidefloat##1%
+ {\begingroup
+ \chardef\alignstrutmode\zerocount
+ \hsize\tempfloatwidth \forgetall
+ \alignedline{\floatparameter\c!location}\v!middle{##1}%
+ \endgroup}%
+ \buildfloatbox}
+
+\newif\ifparfloat
+
+\long\def\dosetfloatbox#1#2#3% todo : \global\setbox
+ {\ifvisible
+ \par
+ \edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}%
+ \ifparfloat\@EA\dosetparfloat\else\@EA\dosetpagfloat\fi{#1}{#2}{#3}%
+ \setlocalfloatdimensions{#1}%
+ \setbox\floatbox\hbox
+ {\dosavefloatdata\restoretextcolor{\box\floatbox}}%
+ \global\floatheight\ht\floatbox
+ \global\advance\floatheight \dp\floatbox
+ \global\floatwidth\wd\floatbox
+ \global\advance\totalnoffloats \plusone
+ \doifnotinset\v!margin{#1} % gaat namelijk nog fout
+ {\setbox\floatbox\vbox
+ {\parindent\zeropoint
+ \doifconcepttracing{\inleftmargin{\framed{\infofont\the\totalnoffloats}}}%
+ \box\floatbox}}%
+ \wd\floatbox\floatwidth
+ \dimen0=\floatheight
+ \advance\dimen0 \lineheight
+ \ifdim\dimen0<\textheight
+ \else
+ \global\floatheight\textheight
+ \global\advance\floatheight -\lineheight
+ \ht\floatbox\floatheight
+ \dp\floatbox\zeropoint
+ \showmessage\m!floatblocks{10}{\the\totalnoffloats}%
+ \fi
+ \fi}
+
+\newcounter\noxfloatlocations
+
+\long\def\dofloat#1#2#3% #1 is optionlist
+ {\dosetfloatbox{#1}{#2}{#3}%
+ \dogetfloatbox{#1}\empty}
+
+\def\dooutput{\sidefloatoutput} % redefinition of \dooutput
+
+\definefloat
+ [\v!figure]
+ [\v!figures]
+
+\definefloat
+ [\v!table]
+ [\v!tables]
+
+\setupfloat
+ [\v!table]
+ [\c!frame=\v!off]
+
+\definefloat
+ [\v!intermezzo]
+ [\v!intermezzi]
+
+\definefloat
+ [\v!graphic]
+ [\v!graphics]
+
+% float strategy, replaces some of the above macros
+
+\let\floatmethod \empty
+\let\floatcolumn \empty
+\let\floatrow \empty
+\let\forcedfloatmethod\empty
+
+\def\dogetfloatbox#1#2%
+ {\ifvisible
+ \doifelsenothing{#2}
+ {\getfromcommalist[#1][1]%
+ \@EA\beforesplitstring\commalistelement\at:\to\floatmethod
+ \@EA\aftersplitstring \commalistelement\at:\to\floatcolumn
+ \@EA\aftersplitstring \floatcolumn\at*\to\floatrow
+ \@EA\beforesplitstring\floatcolumn\at*\to\floatcolumn
+ % todo: nog algemeen otr
+ \ifx\OTRSETsetpreferedcolumnslot\undefined\else
+ \OTRSETsetpreferedcolumnslot\floatcolumn\floatrow
+ \fi}
+ {\let\floatcolumn\empty
+ \let\floatrow\empty
+ \edef\floatmethod{#2}}%
+ \doifundefined{\string\floatmethod\floatmethod}
+ {\let\floatmethod\v!here}%
+ \doifsomething\forcedfloatmethod
+ {\edef\floatmethod{\forcedfloatmethod}}%
+ %\getvalue{\string\floatmethod\floatmethod}[#1]%
+ \getvalue{\string\floatmethod\floatmethod}[\floatmethod,#1]%
+ \fi}
+
+\def\installfloathandler#1#2% #1=keyword #2=handler
+ {\setvalue{\string\floatmethod#1}{#2}}
+
+\installfloathandler \v!here \someherefloat
+\installfloathandler \v!force \somefixdfloat
+\installfloathandler \v!left \someleftsidefloat
+\installfloathandler \v!right \somerightsidefloat
+\installfloathandler \v!text \sometextfloat
+\installfloathandler \v!top \sometopfloat
+\installfloathandler \v!bottom \somebottomfloat
+\installfloathandler \v!auto \someautofloat
+\installfloathandler \v!margin \somemarginfloat
+\installfloathandler \v!opposite \somefacefloat
+\installfloathandler \v!page \somepagefloat
+\installfloathandler \v!leftpage \someleftpagefloat
+\installfloathandler \v!rightpage \somerightpagefloat
+\installfloathandler \v!inmargin \someinmarginfloat
+\installfloathandler \v!inleft \someinleftmarginfloat
+\installfloathandler \v!inright \someinrightmarginfloat
+\installfloathandler \v!leftmargin \someinleftmarginfloat
+\installfloathandler \v!rightmargin \someinrightmarginfloat
+\installfloathandler \v!leftedge \someinleftedgefloat
+\installfloathandler \v!rightedge \someinrightedgefloat
+
+\installfloathandler \v!backspace \somebackspacefloat
+\installfloathandler \v!cutspace \somecutspacefloat
+
+\installfloathandler {tblr} \someslotfloat
+\installfloathandler {lrtb} \someslotfloat
+\installfloathandler {tbrl} \someslotfloat
+\installfloathandler {rltb} \someslotfloat
+\installfloathandler {btlr} \someslotfloat
+\installfloathandler {lrbt} \someslotfloat
+\installfloathandler {btrl} \someslotfloat
+\installfloathandler {rlbt} \someslotfloat
+\installfloathandler {fxtb} \someslotfloat
+\installfloathandler {fxbt} \someslotfloat
+
+\def\placesomeslotfloat {\OTRcommand\someslotfloat}
+\def\placesomeherefloat {\OTRcommand\someherefloat}
+\def\placesomefixdfloat {\OTRcommand\somefixdfloat}
+\def\placesomepagefloat {\OTRcommand\somepagefloat}
+\def\placesomeleftpagefloat {\OTRcommand\someleftpagefloat}
+\def\placesomerightpagefloat{\OTRcommand\somerightpagefloat}
+\def\placesometopsfloat {\OTRcommand\sometopsfloat}
+\def\placesomebotsfloat {\OTRcommand\somebotsfloat}
+\def\placesomesidefloat {\OTRcommand\somesidefloat}
+\def\placesomefacefloat {\OTRcommand\somefacefloat}
+
+\def\someleftsidefloat [#1]{\somesidefloat[#1]\presetindentation}
+\def\somerightsidefloat [#1]{\somesidefloat[#1]}
+\def\sometopfloat [#1]{\someelsefloat[#1]\nonoindentation}
+\def\somebottomfloat [#1]{\someelsefloat[#1]}
+\def\someautofloat [#1]{\someelsefloat[#1]}
+\def\somemarginfloat [#1]{\somenextfloat[#1]\nonoindentation}
+\def\someinleftmarginfloat [#1]{\somesidefloat[#1]}
+\def\someinrightmarginfloat[#1]{\somesidefloat[#1]}
+\def\someinleftedgefloat [#1]{\somesidefloat[#1]}
+\def\someinrightedgefloat [#1]{\somesidefloat[#1]}
+\def\someinmarginfloat [#1]{\somesidefloat[#1]}
+\def\someherefloat [#1]{\someelsefloat[\v!here,#1]}
+
+\def\somebackspacefloat [#1]{\somesidefloat[#1]}
+\def\somecutspacefloat [#1]{\somesidefloat[#1]}
+
+\def\somefixdfloat {\placesomefixdfloat}
+\def\somepagefloat {\placesomepagefloat}
+\def\someleftpagefloat {\placesomeleftpagefloat}
+\def\somerightpagefloat{\placesomerightpagefloat}
+\def\somefacefloat {\placesomefacefloat}
+\def\someslotfloat {\placesomeslotfloat}
+
+\protect \endinput
diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua
new file mode 100644
index 000000000..552435e81
--- /dev/null
+++ b/tex/context/base/strc-ini.lua
@@ -0,0 +1,276 @@
+if not modules then modules = { } end modules ['strc-ini'] = {
+ version = 1.001,
+ comment = "companion to strc-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[
+
+The restructuring is the (intermediate) result of quite some experiments. I started
+with the basic structure, followed by lists, numbers, enumerations, itemgroups
+and floats. All these have something in common, like pagenumbers and section
+prefixes. I played with some generic datastructure (in order to save space) but
+the code at both the lua and tex end then quickly becomes messy due to the fact
+that access to variables is too different. So, eventually I ended up with
+dedicated structures combined with sharing data. In lua this is quite efficient
+because tables are referenced. However, some precautions are to be taken in
+order to keep the utility file small. Utility data and process data share much
+but it does not make sense to store all processdata.
+
+]]--
+
+local format, concat, match = string.format, table.concat, string.match
+local count, texwrite, texprint, texsprint = tex.count, tex.write, tex.print, tex.sprint
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+
+local ctxcatcodes = tex.ctxcatcodes
+
+-- move this
+
+commands = commands or { }
+
+function commands.first_in_list(str)
+ local first = match(str,"^([^,]+),")
+ texsprint(ctxcatcodes,first or str)
+end
+
+-- -- -- namespace -- -- --
+
+structure = structure or { }
+
+-- -- -- cache -- -- --
+
+structure.shares = structure.shares or { }
+structure.shares.cache = structure.shares.cache or { }
+
+local shares = structure.shares
+local cache = shares.cache
+
+function shares.put(data)
+ cache[#cache+1] = data
+ return #cache
+end
+
+function shares.get(n) -- n can be string
+ n = tonumber(n) or -1
+ return cache[n]
+end
+
+-- -- -- specials -- -- --
+
+-- we can store information and get back a reference; this permits
+-- us to store rather raw data in references
+
+local specials = { } structure.specials = specials
+
+specials.collected = specials.collected or { }
+specials.tobesaved = specials.collected or { }
+
+local collected, tobesaved = specials.collected, specials.tobesaved
+
+local function initializer()
+ collected, tobesaved = specials.collected, specials.tobesaved
+end
+
+if job then
+ job.register('structure.specials.collected', structure.specials.tobesaved, initializer)
+end
+
+function specials.store(class,data)
+ if class and data then
+ local s = tobesaved[class]
+ if not s then
+ s = { }
+ tobesaved[class] = s
+ end
+ s[#s+1] = data
+ texwrite(#s)
+ else
+ texwrite(0)
+ end
+end
+
+function specials.retrieve(class,n)
+ if class and n then
+ local c = collected[class]
+ return c and c[n]
+ end
+end
+
+-- -- -- helpers -- -- --
+
+structure.helpers = structure.helpers or { }
+
+local helpers = structure.helpers
+
+function helpers.touserdata(str)
+ local hash = str and str ~= "" and aux.settings_to_hash(str)
+ if hash and next(hash) then
+ return hash
+ end
+end
+
+local function simplify(d,nodefault)
+ if d then
+ local t = { }
+ for k, v in next, d do
+ local tv = type(v)
+ if tv == "table" then
+ if next(v) then t[k] = simplify(v) end
+ elseif tv == "string" then
+ if v ~= "" and v ~= "default" then t[k] = v end
+ elseif tv == "boolean" then
+ if v then t[k] = v end
+ else
+ t[k] = v
+ end
+ end
+--~ print(table.serialize(d,"before"))
+--~ print(table.serialize(t,"after"))
+ return next(t) and t
+ elseif nodefault then
+ return nil
+ else
+ return { }
+ end
+end
+
+helpers.simplify = simplify
+
+function helpers.merged(...)
+ local h, t = { ... }, { }
+ for k=1, #h do
+ local v = h[k]
+ if v and v ~= "" and not t[k] then
+ t[k] = v
+ end
+ end
+ return t
+end
+
+local tag = "ctx:tocentry"
+
+function helpers.title(title,metadata)
+ if title and title ~= "" then
+ if metadata then
+ if metadata.coding == "xml" then
+ buffers.set(tag,format("<?xml version='1.0'?><%s>%s</%s>",tag,title,tag))
+ texsprint(ctxcatcodes,format("\\xmlprocessbuffer{%s}{%s}{}",metadata.xmlroot or "main",tag))
+ else
+ texsprint(metadata.catcodes,title)
+ end
+ else
+ texsprint(title) -- no catcode switch
+ end
+ end
+end
+
+-- -- -- processors -- -- -- syntax: processor->data
+
+local processors = { } structure.processors = processors
+
+local registered = { }
+
+function processors.register(p)
+ registered[p] = true
+end
+
+function processors.reset(p)
+ registered[p] = nil
+end
+
+local splitter = lpeg.splitat("->",true)
+
+function processors.split(str)
+ local p, s = splitter:match(str)
+ if registered[p] then
+ return p, s
+ else
+ return false, str
+ end
+end
+
+function processors.sprint(catcodes,str,fnc,...)
+ local p, s = splitter:match(str)
+ if registered[p] then
+ texsprint(catcodes,format("\\applyprocessor{%s}{%s}",p,(fnc and fnc(s,...)) or s))
+ else
+ texsprint(catcodes,(fnc and fnc(str,...)) or str)
+ end
+end
+
+function processors.apply(str)
+ local p, s = splitter:match(str)
+ if registered[p] then
+ return format("\\applyprocessor{%s}{%s}",p,s)
+ else
+ return str
+ end
+end
+
+-- -- -- sets -- -- --
+
+structure.sets = structure.sets or { }
+structure.sets.setlist = structure.sets.setlist or { }
+
+storage.register("structure/sets/setlist", structure.sets.setlist, "structure.sets.setlist")
+
+local sets = structure.sets
+local setlist = sets.setlist
+
+function sets.define(namespace,name,values,default,numbers)
+ local dn = setlist[namespace]
+ if not dn then
+ dn = { }
+ setlist[namespace] = dn
+ end
+ if values == "" then
+ dn[name] = { { }, default }
+ else
+ local split = aux.settings_to_array(values)
+ if numbers then
+ -- convert to numbers (e.g. for reset)
+ for i=1,#split do
+ split[i] = tonumber(split[i]) or 0
+ end
+ end
+ dn[name] = { split, default }
+ end
+end
+
+function sets.getall(namespace,block,name)
+ local ds = setlist[namespace]
+ if not ds then
+ return { }
+ else
+ local dn
+ if block and block ~= "" then
+ dn = ds[block..":"..name] or ds[name] or ds[block] or ds.default
+ else
+ dn = ds[name] or ds.default
+ end
+ return (dn and dn[1]) or { }
+ end
+end
+
+function sets.get(namespace,block,name,level,default)
+ local ds = setlist[namespace]
+ if not ds then
+ return default
+ end
+ local dn
+ if name and name ~= "" then
+ if block and block ~= "" then
+ dn = ds[block..":"..name] or ds[name] or ds[block] or ds.default
+ else
+ dn = ds[name] or ds.default
+ end
+ end
+ if not dn then
+ return default
+ end
+ local dl = dn[1][level]
+ return dl or dn[2] or default
+end
diff --git a/tex/context/base/strc-ini.tex b/tex/context/base/strc-ini.tex
new file mode 100644
index 000000000..619442998
--- /dev/null
+++ b/tex/context/base/strc-ini.tex
@@ -0,0 +1,88 @@
+%D \module
+%D [ file=strc-flt,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Initialization \& Helpers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Initialization & Helpers}
+
+\registerctxluafile{strc-ini}{1.001}
+
+\unprotect
+
+% \def\zerosection{0}
+% \def\resetsectionmarks{}
+% \setuppagenumbering
+
+% maybe use structurecomponent more consistently as name below
+
+% segments: 0:100 2:3 chapter:subsection 3 (=self+2) (alternative: sectionset)
+
+% section : [sectionnumber(s)]
+% sectionseparatorset (default) sectionconversionset (default) sectionstopper () sectionset sectionsegments
+
+% lists : [sectionnumber(s)] [text] [prefix(es)[separator]][pagenumber(s)]
+% sectionseparatorset (default) sectionconversionset (default) sectionstopper sectionset sectionsegments
+% prefixseparatorset (default) prefixconversionset (default) prefixstopper (.) prefixset prefixsegments
+% pageseparatorset (default) pageconversionset (default) pagestopper () pagesegments
+% prefix (no)
+
+% counter : [prefix(es)[separator]][number(s)]
+% prefixseparatorset (default) prefixconversionset (default) prefixstopper (.) prefixset prefixsegments
+% numberseparatorset (default) numberconversionset (default) numberstopper () numbersegments
+% prefix (no)
+
+% pagenumber: [prefix(es)[separator]][pagenumber(s)]
+% prefixseparatorset (default) prefixconversionset (default) prefixstopper (.) prefixset prefixsegments
+% pageseparatorset (default) pageconversionset (default) pagestopper ()
+% prefix (no)
+
+% text mark reference list
+% section P P P P
+% float P.N P.N P.N
+% itemize P.N P.N
+% enumerate P.N P.N P.N
+% formula P.N P.N
+% footnote P.N P.N P.N
+% number P.N P.N
+
+% number prefix section page
+
+% [text|marking|reference|list]:[number|prefix|pagenumber|pageprefix]:[separatorset|conversionset|conversion|stopper|set|segments|resetset|order]
+
+% figure caption : text:number:* text:prefix:* -> \setupcaption[figure][...]; stores defaults
+% figure list : list:number:* list:prefix:* list:pagenumber:* list:pageprefix:* -> \setuplist[figure][...]; takes stored defaults for number and pagenumber]
+% figure reference: reference:number:* reference:prefix:* reference:pagenumber:* reference:pageprefix:* -> \setupreference[figure]]...]; takes stored defaults
+
+% This module deals with structure: section headers, list and
+% numbering and eventually cross referencing. These components are
+% rather interwoven and therefore an inbetween layer is used.
+% Eventually this will replace the corresponding code in core-sec,
+% core-lst, core-num and core-ref.
+
+% We collect operations that deal with things like formatting on each
+% level of a number in sets. This is all handles at the \LUA\ end.
+% References to such sets travel with the multipass information.
+
+\def\definestructureresetset {\dotripleempty\dodefinestructureresetset}
+\def\definestructureseparatorset {\dotripleempty\dodefinestructureseparatorset}
+\def\definestructureconversionset{\dotripleempty\dodefinestructureconversionset}
+\def\definestructureprefixset {\dotripleempty\dodefinestructureprefixset}
+
+\def\dodefinestructureresetset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:resets", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}",true)}}
+\def\dodefinestructureseparatorset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:separators", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}}
+\def\dodefinestructureconversionset[#1][#2][#3]{\ctxlua{structure.sets.define("structure:conversions","#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}}
+\def\dodefinestructureprefixset [#1][#2][#3]{\ctxlua{structure.sets.define("structure:prefixes", "#1","\luaescapestring{\detokenize{#2}}","\luaescapestring{\detokenize{#3}}")}}
+
+% \definestructureseparatorset [weird][!,?,*][:] % tex content
+% \definestructureconversionset[weird][numbers,characters,romannumerals][numbers] % symbolic names
+% \definestructureresetset [weird][0,0,1][0] % numbers
+
+\protect \endinput
diff --git a/tex/context/base/strc-itm.lua b/tex/context/base/strc-itm.lua
new file mode 100644
index 000000000..fc609b448
--- /dev/null
+++ b/tex/context/base/strc-itm.lua
@@ -0,0 +1,24 @@
+if not modules then modules = { } end modules ['strc-itm'] = {
+ version = 1.001,
+ comment = "companion to strc-itm.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+structure = structure or { }
+structure.itemgroups = structure.itemgroups or { }
+
+local itemgroups = structure.itemgroups
+
+function itemgroups.register(name,nofitems,maxwidth)
+ jobpasses.savedata("itemgroup", { nofitems, maxwidth })
+end
+
+function itemgroups.nofitems(name,index)
+ jobpasses.getfield("itemgroup", index, 1, 0)
+end
+
+function itemgroups.maxwidth(name,index)
+ jobpasses.getfield("itemgroup", index, 2, 0)
+end
diff --git a/tex/context/base/strc-itm.tex b/tex/context/base/strc-itm.tex
new file mode 100644
index 000000000..dd639d72b
--- /dev/null
+++ b/tex/context/base/strc-itm.tex
@@ -0,0 +1,1195 @@
+%D \module
+%D [ file=strc-itm,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Itemgroups,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Itemgroups}
+
+\registerctxluafile{strc-itm}{1.001}
+
+\unprotect
+
+\newconditional\sublistitem \setfalse\sublistitem
+\newconditional\symbollistitem \setfalse\symbollistitem
+\newconditional\headlistitem \setfalse\headlistitem
+\newconditional\introlistitem \setfalse\introlistitem
+\newconditional\randomizeitems \setfalse\randomizeitems
+\newconditional\autointrolistitem \setfalse\autointrolistitem
+\newconditional\optimizelistitem \settrue \optimizelistitem
+\newconditional\packlistitem \setfalse\packlistitem
+\newconditional\paragraphlistitem \setfalse\paragraphlistitem
+\newconditional\textlistitem \setfalse\textlistitem
+\newconditional\firstlistitem \setfalse\firstlistitem
+\newconditional\beforelistitem \setfalse\beforelistitem
+\newconditional\afterlistitem \setfalse\afterlistitem
+\newconditional\nowhitelistitem \setfalse\nowhitelistitem
+\newconditional\joinedlistitem \setfalse\joinedwhitelistitem
+\newconditional\reverselistitem \setfalse\reverselistitem
+\newconditional\continuelistitems \setfalse\continuelistitems
+\newconditional\fittinglistitems \setfalse\fittinglistitems
+
+\newcount\noflists
+\newcount\currentnoflists
+\newcount\noflistelements
+\newcount\itemcolumndepth
+\newcount\itemdepth
+\newcount\maxitemdepth \maxitemdepth=6
+
+\newdimen\itemgrouplistwidth
+\newdimen\itemgroupaskedwidth
+\newbox \itemgroupitembox
+
+\def\currentitemgroupcounter{itemgroup:\currentitemgroup}
+
+\let\currentitemlevel \!!zerocount
+\let\currentitemgroup \empty
+\let\currentnofitems \!!zerocount
+\def\currentitemnumber {\dorawsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]}
+\let\currentrepeatstart \empty
+
+\def\dolistreference
+ {\iftrialtypesetting \else % no need for different treatment of \continuelistitems
+ \ctxlua{structure.itemgroups.register("\currentitemgroup",\number\noflistelements,"\getitemparameter\currentitemlevel\c!maxwidth")}%
+ \fi}
+
+\def\checkcurrentnofitems % we could do this at the lua end and save a call
+ {\edef\currentnofitems {\ctxlua{structure.itemgroups.nofitems("\currentitemgroup",\number\currentnoflists)}}%
+ \edef\currentitemmaxwidth{\ctxlua{structure.itemgroups.maxwidth("\currentitemgroup",\number\currentnoflists)}\scaledpoint}}
+
+\def\dohandleitemreference % we will make a decent number helper
+ {\ifx\currentitemreference \empty \else
+ \setnextinternalreference
+ \ctxlua {
+ jobreferences.set("\s!full", "\referenceprefix","\currentitemreference",
+ {
+ metadata = {
+ kind = "list",
+ catcodes = \the\catcodetable,
+ xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text
+ },
+ references = {
+ internal = \nextinternalreference,
+ section = structure.sections.currentid(),
+ },
+ numberdata = structure.helpers.simplify {
+ numbers = structure.counters.compact("\currentitemgroupcounter",nil,true),
+ separatorset = "\structurecounterparameter\currentitemgroupcounter\c!numberseparatorset",
+ conversion = "\structurecounterparameter\currentitemgroupcounter\c!numberconversion",
+ conversionset = "\structurecounterparameter\currentitemgroupcounter\c!numberconversionset",
+ % for the moment no stopper, we need to make references configurable first
+ % stopper = \!!bs\structurecounterparameter\currentitemgroupcounter\c!numberstopper\!!es,
+ segments = "\structurecounterparameter\currentitemgroupcounter\c!numbersegments",
+ },
+ })
+ jobreferences.setinternalreference("\referenceprefix","\currentitemreference",\nextinternalreference)
+ }%
+ \fi}
+
+% \startitemize[n,packed]
+% \item test \item test \item test
+% \stopitemize
+%
+% \startitemize[n,packed,reverse]
+% \item test \item test \item test
+% \stopitemize
+%
+% \startitemize[n,packed,reverse] \item test \item test \stopitemize
+% \startitemize[continue]
+% \item test \startitemize[n,packed] \item test \item test \stopitemize
+% \item test
+% \item test
+% \stopitemize
+% \startitemize[continue] \item test \stopitemize
+%
+% \startitemize[n,packed] \item test \item test \stopitemize
+% \startitemize[continue] \item test \stopitemize
+% \startitemize[continue] \item test \stopitemize
+
+\def\itemparameter #1#2{\csname\doitemparameter{\??op\currentitemgroup#1}#2\endcsname}
+\def\itemparameterhash#1#2{\doitemparameterhash {\??op\currentitemgroup#1}#2}
+
+
+\def\doitemparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doitemparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\doitemparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doitemparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\doitemparentparameter #1#2{\ifx#1\relax\s!empty\else\doitemparameter #1#2\fi}
+\def\doitemparentparameterhash#1#2{\ifx#1\relax \else\doitemparameterhash#1#2\fi}
+
+\def\dosetitemattributes#1#2#3% style color
+ {\edef\fontattributehash {\itemparameterhash#1#2}%
+ \edef\colorattributehash{\itemparameterhash#1#3}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #2\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#3\fi}
+
+\def\setitemparameter #1#2{\@EA \def\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3}
+\def\esetitemparameter#1#2{\@EA\edef\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3}
+\def\xsetitemparameter#1#2{\@EA\xdef\csname\??op\currentitemgroup#1#2\endcsname} % #3 -> {#3}
+\def\letitemparameter #1#2{\@EA \let\csname\??op\currentitemgroup#1#2\endcsname}
+\let\getitemparameter \itemparameter
+
+\def\@@globalitemsymbol #1{\??op\currentitemgroup\c!symbol\s!global#1}
+\def\@@localitemsymbol #1{\??op\currentitemgroup\c!symbol\s!local #1}
+\def\@@currentitemsymbol#1{\??op\currentitemgroup\c!symbol #1}
+
+\def\@@itemcounter{\s!itemcount\currentitemgroup}
+
+\def\doitembreak#1{\ifconditional\optimizelistitem\ifconditional\textlistitem\else\dosomebreak#1\fi\fi}
+
+\def\allowitembreak {\doitembreak\allowbreak}
+\def\noitembreak {\doitembreak\nobreak}
+\def\itembreakspecial {\doitembreak\itembreak}
+\def\noitembreakspecial{\doitembreak\itemnobreak}
+
+\def\itembreak {\flushnotes\penalty-5\relax} % -10
+\def\itemnobreak{\flushnotes\penalty+5\ifinsidecolumns\else00\fi\relax} % +5
+
+\def\initializeitemgrouplevel#1%
+ {\ifcsname\??op\currentitemgroup#1\s!parent\endcsname
+ % ok
+ \else\ifnum#1>\plusone
+ \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup\the\numexpr#1-1\relax}%
+ \else
+ \setevalue{\??op\currentitemgroup#1\s!parent}{\??op\currentitemgroup}%
+ \fi\fi}
+
+\def\defineitemgroup
+ {\dotripleempty\dodefineitemgroup}
+
+\def\dodefineitemgroup[#1][#2][#3]% todo: clone
+ {\doifsomething{#1}
+ {\pushmacro\currentitemgroup
+ \def\currentitemgroup{#1}%
+ \setvalue{\e!start#1}{\startitemgroup[#1]}%
+ \setvalue{\e!stop#1}{\stopitemgroup}%
+ \setvalue{\e!setup#1\e!endsetup}{\setupitemgroup[#1]}% for old times sake
+ \doifelsenothing{#2}
+ {\getparameters[\??op#1][\s!parent=\??oo,#3]}%
+ {\doifassignmentelse{#2}
+ {\getparameters[\??op#1][\s!parent=\??oo,#2]}%
+ {\getparameters[\??op#1][\s!parent=\??op#2,#3]}}%
+ \dorecurse\maxitemdepth{\initializeitemgrouplevel\recurselevel}%
+ \definestructurecounter[itemgroup:#1]%
+ \popmacro\currentitemgroup}}
+
+\def\setupitemgroups % [#1]
+ {\dodoubleargument\getparameters[\??oo]} % [#1]
+
+\def\packitems
+ {\ifcase\currentitemlevel \else \settrue\packlistitem \fi}
+
+\def\dosetupitemgroupvariable[#1]% [#2]% niveau instellingen
+ {\doifelsenothing{#1}
+ {\getparameters[\??op\currentitemgroup\currentitemlevel]}%
+ {\getparameters[\??op\currentitemgroup#1]}}
+
+\def\dosetupitemgroupconstant#1%
+ {\global\setitemparameter\currentitemlevel\c!maxwidth{0}%
+ \processcommacommand[#1]\dodosetupitemgroupconstant} % expansion of #2 is handy for xml
+
+\def\dodosetupitemgroupconstant#1%
+ {\edef\itemgroupconstantvalue{#1}%
+ \ifx\itemgroupconstantvalue\empty\else
+ \splitstring\itemgroupconstantvalue\at*\to\itemgroupfirst\and\itemgroupsecond
+ \ifcsname\??op:::\itemgroupfirst\endcsname\csname\??op:::\itemgroupfirst\endcsname\fi
+ \fi}
+
+\newconditional\inlinelistitem \setfalse\inlinelistitem
+
+\setvalue{\??op:::\v!packed }{\packitems}
+\setvalue{\??op:::\v!intro }{\settrue\introlistitem} % here? not set to false
+\setvalue{\??op:::\v!autointro}{\settrue\autointrolistitem}
+\setvalue{\??op:::\v!broad }{\ifx\itemgroupsecond\empty\def\itemgroupsecond{1}\fi
+ \letitemparameter\currentitemlevel\c!factor\itemgroupsecond}
+\setvalue{\??op:::\v!text }{\settrue\textlistitem
+ \settrue\inlinelistitem
+ \settrue\joinedlistitem
+ \packitems}
+\setvalue{\??op:::\v!columns }{\packitems}
+\setvalue{\??op:::\v!before }{\settrue\beforelistitem}
+\setvalue{\??op:::\v!after }{\settrue\afterlistitem}
+\setvalue{\??op:::\v!nowhite }{\settrue\nowhitelistitem}
+\setvalue{\??op:::\v!margin }{\setitemparameter\currentitemlevel\c!width{-2em}} % signal
+\setvalue{\??op:::\v!inmargin }{\setitemparameter\currentitemlevel\c!width{-2em}} % signal
+\setvalue{\??op:::\v!atmargin }{\doifnot\currentitemlevel{1}{\setitemparameter\currentitemlevel\c!width{0em}}} % signal
+\setvalue{\??op:::\v!intext }{\settrue\inlinelistitem}
+\setvalue{\??op:::\v!loose }{\setfalse\optimizelistitem}
+\setvalue{\??op:::\v!fit }{\settrue\fittinglistitems}
+\setvalue{\??op:::\v!nofit }{\setfalse\fittinglistitems}
+\setvalue{\??op:v:\v!paragraph}{\settrue\paragraphlistitem
+ \packitems}
+\setvalue{\??op:::\v!joinedup }{\settrue\joinedlistitem
+ \packitems}
+\setvalue{\??op:::\v!serried }{\edef\itemgroupsecond{-\ifx\itemgroupsecond\empty1\else\itemgroupsecond\fi}%
+ \letitemparameter\currentitemlevel\c!factor\itemgroupsecond}
+\setvalue{\??op:::\v!stopper }{\letitemparameter\currentitemlevel\c!placestopper\v!yes} % keep {}
+\setvalue{\??op:::\v!unpacked }{\setfalse\packlistitem}
+\setvalue{\??op:::\v!repeat }{\settrue\repeatlistitem}
+\setvalue{\??op:::\v!reverse }{\settrue\reverselistitem}
+\setvalue{\??op:::\v!standard }{\dosetupstandarditemgroup\currentitemlevel}
+
+\def\dosetupstandarditemgroup#1%
+ {\getparameters
+ [\??op\currentitemgroup#1]
+ [\c!width=1.5em,\c!factor=0,\c!distance=.5em,\c!inner=,
+ \c!beforehead=,\c!afterhead=\blank,\c!before=\blank,\c!inbetween=\blank,\c!after=\blank]}
+
+% \def\packeditemspacing{\empty}
+
+% \setupwhitespace[big]
+% \starttext
+% test \startitemize[joinedup] \item test \item test \stopitemize test \par
+% test \startitemize[joinedup,nowhite] \item test \item test \stopitemize test \par
+% test \startitemize[joinedup,nowhite,before] \item test \item test \stopitemize test \par
+% test \startitemize[joinedup,nowhite,after] \item test \item test \stopitemize test \par
+% \stoptext
+
+\def\itembeforecommand
+ {\ifconditional\nowhitelistitem
+ \ifconditional\beforelistitem
+ \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!before\fi
+ \else
+ \nowhitespace
+ \fi
+ \else\ifconditional\joinedlistitem
+ % \empty
+ \else
+ \getitemparameter\currentitemlevel\c!before
+ \fi\fi}
+
+\def\itemaftercommand
+ {\ifconditional\nowhitelistitem
+ \ifconditional\afterlistitem
+ \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!after\fi
+ \else
+ \nowhitespace
+ \fi
+ \else\ifconditional\joinedlistitem
+ % \empty
+ \else
+ \getitemparameter\currentitemlevel\c!after
+ \fi\fi}
+
+\def\iteminbetweencommand
+ {\ifconditional\nowhitelistitem
+ \nowhitespace
+ \else\ifconditional\joinedlistitem
+ % \empty
+ \else
+ \getitemparameter\currentitemlevel\c!inbetween
+ \fi\fi}
+
+\def\itembeforeheadcommand
+ {\ifconditional\nowhitelistitem
+ \nowhitespace
+ \else\ifconditional\joinedlistitem
+ % \empty
+ \else
+ \getitemparameter\currentitemlevel\c!beforehead
+ \fi\fi}
+
+\def\itemafterheadcommand
+ {\ifconditional\nowhitelistitem
+ \nowhitespace
+ \else\ifconditional\joinedlistitem
+ % \empty
+ \else
+ \getitemparameter\currentitemlevel\c!afterhead
+ \fi\fi}
+
+\def\dododododosetupitemgroup[#1][#2]%
+ {\doifassignmentelse{#2}%
+ {\dosetupitemgroupvariable[#1][#2]}%
+ {\setitemparameter{#1}\c!option{#2}}}%
+
+\def\dodododosetupitemgroup[#1][#2]%
+ {\doifsomething{#2}
+ {\doifelse{#1}\v!each
+ {\dorecurse\maxitemdepth{\normalexpanded{\noexpand\dododododosetupitemgroup[\recurselevel]}[#2]}}
+ {\normalexpanded{\noexpand\dododododosetupitemgroup[#1]}[#2]}}}
+
+% \def\dododosetupitemgroup[#1][#2]%
+% {\doifelsenothing{#2}
+% {\doifelsenothing{#1}
+% {\dodododosetupitemgroup[\currentitemlevel][#2]}
+% {\dodododosetupitemgroup[#1][#2]}}
+% {\ifcase\currentitemlevel\relax
+% \dodododosetupitemgroup[\v!each][#1]%
+% \else
+% \dodododosetupitemgroup[\currentitemlevel][#1]%
+% \fi}}
+
+\def\dododosetupitemgroup[#1][#2]%
+ {\doifelsenothing{#2}
+ {\doifsomething{#1}
+ {\ifcase\currentitemlevel\relax
+ \dodododosetupitemgroup[\v!each][#1]%
+ \else
+ \dodododosetupitemgroup[\currentitemlevel][#1]%
+ \fi}}%
+ {\doifelsenothing{#1}
+ {\ifcase\currentitemlevel\relax
+ \dodododosetupitemgroup[\v!each][#2]%
+ \else
+ \dodododosetupitemgroup[\currentitemlevel][#2]%
+ \fi}
+ {\dodododosetupitemgroup[#1][#2]}}}
+
+\def\dodosetupitemgroup[#1][#2][#3][#4]%
+ {\pushmacro\currentitemgroup
+ \def\currentitemgroup{#1}%
+ \dododosetupitemgroup[#2][#3]%
+ \doifsomething{#4}{\dododosetupitemgroup[#2][#4]}%
+ \popmacro\currentitemgroup}
+
+\def\dosetupitemgroup[#1][#2][#3][#4]%
+ {\def\docommand##1{\dodosetupitemgroup[##1][#2][#3][#4]}%
+ \processcommalist[#1]\docommand}
+
+\def\setupitemgroup
+ {\doquadrupleempty\dosetupitemgroup}
+
+\def\doadvanceitem
+ {\ifconditional\sublistitem\else\ifconditional\symbollistitem\else
+ \doincrementsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]%
+ \fi\fi}
+
+\def\setitemlevel#1%
+ {\ifnum\currentitemlevel>\zerocount
+ \settrue\firstlistitem
+ \ifconditional\continuelistitems\else
+ \dorestartsubstructurecounter[\currentitemgroupcounter][\currentitemlevel]{\the\numexpr\getitemparameter\currentitemlevel\c!start-1\relax}%
+ \fi
+ \fi}
+
+\unexpanded\def\actualitemnumber
+ {\ifconditional\repeatlistitem
+ \ifcase\currentitemlevel\or\else
+ \doactualitemnumber
+ \fi
+ \else
+ \doactualitemnumber
+ \fi}
+
+\def\doactualitemnumber
+ {\begingroup
+ \setupstructurecounter
+ [\currentitemgroupcounter]
+ [\c!prefix=\v!no,
+ \c!numberorder=\ifconditional\reverselistitem\v!reverse\else\v!normal\fi,
+ \c!numberstopper=\expdoif{\getitemparameter\currentitemlevel\c!placestopper}\v!yes{\getitemparameter\currentitemlevel\c!stopper},
+ %\c!numberseparatorset=,
+ %\c!numberconversionset=,
+ \c!numberconversion=\currentitemsymbol,
+ \c!numbersegments=\ifx\currentrepeatstart\empty\else\currentrepeatstart:\fi\number\currentitemlevel]%
+ \ifconditional\reverselistitem
+ \convertedstructurecounter[\currentitemgroupcounter]% [\number\currentitemlevel]%
+ \else
+ \convertedstructurecounter[\currentitemgroupcounter]% [\number\currentitemlevel]%
+ \fi
+ \dohandleitemreference
+ \endgroup}
+
+\def\unknownitemsymbol{?}
+
+\def\setitemmark#1% % en pas op: resets \docommand ; todo: conversionset
+ {\doifsymboldefinedelse{#1}
+ {\edef\currentitemsymbol{#1}%
+ \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}%
+ \setgvalue{\@@localitemsymbol \currentitemlevel}{\unknownitemsymbol}%
+ \def\listitem{\symbol[\currentitemsymbol]}%
+ \let\@@opsymbol\empty}%
+ {\doifconversiondefinedelse{#1}
+ {\edef\currentitemsymbol{#1}%
+ \setxvalue{\@@globalitemsymbol\currentitemlevel}{\currentitemsymbol}%
+ \setgvalue{\@@localitemsymbol\currentitemlevel }{\actualitemnumber }%
+ \def\listitem
+ {\ifconditional\textlistitem
+ % maybe block stopper here, but one can as well clone an
+ % itemgroup then
+ \getitemparameter\currentitemlevel\c!lefttext
+ \getvalue{\@@localitemsymbol\currentitemlevel}%
+ \getitemparameter\currentitemlevel\c!righttext
+ \else
+ \getitemparameter\currentitemlevel\c!left
+ \getvalue{\@@localitemsymbol\currentitemlevel}%
+ \getitemparameter\currentitemlevel\c!right
+ \fi}%
+ \let\@@opsymbol\empty}%
+ {}}}
+
+\def\calculatelistwidth#1% distance deals with 'broad'
+ {\itemgrouplistwidth\getitemparameter#1\c!distance\relax
+ \ifnum\getitemparameter#1\c!factor>\zerocount
+ \ifdim\itemgrouplistwidth=\zeropoint \itemgrouplistwidth=.5em\fi
+ \fi
+ \multiply\itemgrouplistwidth \getitemparameter#1\c!factor
+ \advance \itemgrouplistwidth \getitemparameter#1\c!width\relax}
+
+% The next conditionals deal with \item \startitemgroup. It
+% looks like a hack to skip back, but that way we preserve
+% the indentation and bullet placement. It's a rather
+% untested feature.
+
+\newconditional\concatnextitem \setfalse\concatnextitem
+\newconditional\autoconcatnextitem \settrue \autoconcatnextitem
+\newsignal \itemsignal
+
+\def\startitemgroup
+ {\dotripleempty\dostartitemgroup}
+
+\def\dostartitemgroup[#1][#2][#3]%
+ {\bgroup
+ \ifnum\currentitemlevel=\zerocount
+ \def\currentitemgroup{#1}% no nested mixing of itemgroups
+ \fi
+ \ifthirdargument
+ \dodostartitemgroup[#2][#3]%
+ \else
+ \doifassignmentelse{#2}
+ {\dodostartitemgroup[][#2]}
+ {\dodostartitemgroup[#2][]}%
+ \fi}
+
+\def\dodostartitemgroup[#1]% [#2]%
+ {\relax % prevents lookahead
+ \ifnum\currentitemlevel=\maxitemdepth\relax
+ \showmessage\m!layouts9{\number\maxitemdepth}%
+ \let\itemincrement\zerocount
+ \else
+ \let\itemincrement\plusone
+ \fi
+ \global\advance\itemdepth\itemincrement
+ \xdef\currentitemlevel{\number\itemdepth}%
+ \edef\itemgroupoptions{\getitemparameter\currentitemlevel\c!option}%
+ \ifx\itemgroupoptions\empty
+ \edef\itemgroupoptions{#1}%
+ \else
+ \doifsomething{#1}{\edef\itemgroupoptions{\itemgroupoptions,#1}}%
+ \fi
+ \normalexpanded{\noexpand\redostartitemgroup[\itemgroupoptions]}}% [#2]
+
+\let\startcollectitems\relax
+\let\stopcollectitems \relax
+
+%D A nice example of a plugin:
+%D
+%D \startbuffer
+%D \startitemize[a,random,packed]
+%D \startitem first \stopitem \startitem second \stopitem
+%D \startitem third \stopitem \startitem fourth \stopitem
+%D \stopitemize
+%D
+%D \startitemize[a,random,packed]
+%D \startitem first \stopitem \startitem second \stopitem
+%D \startitem third \stopitem \startitem fourth \stopitem
+%D \stopitemize
+%D
+%D \startitemize[a,packed]
+%D \startitem first \stopitem \startitem second \stopitem
+%D \startitem third \stopitem \startitem fourth \stopitem
+%D \stopitemize
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+% better collectitems als conditional and a real plugin mechanism (some day)
+
+\@EA\long\@EA\def\@EA\collectitemgroupitem\@EA#\@EA1\csname\e!stop\v!item\endcsname
+ {\increment\itemcollectcounter
+ \long\setvalue{\v!item*\itemcollectcounter}{\item#1\par}}
+
+\def\flushcollecteditems
+ {\ifconditional\randomizeitems
+ \getrandomnumber\itemcollectcounternow\plusone\itemcollectcounter
+ \else
+ \increment\itemcollectcounternow
+ \fi
+ \doifdefined{\v!item*\itemcollectcounternow}
+ {\getvalue{\v!item*\itemcollectcounternow}%
+ \letbeundefined{\v!item*\itemcollectcounternow}%
+ \increment\itemcollectcounterdone}%
+ \ifnum\itemcollectcounterdone<\itemcollectcounter\relax
+ \expandafter\flushcollecteditems
+ \fi}
+
+\def\stopcollectitems
+ {\ifconditional\randomizeitems
+ \newcounter\itemcollectcounterdone
+ \ifnum\itemcollectcounter>\zerocount
+ \@EAEAEA\flushcollecteditems
+ \fi
+ \fi}
+
+\def\startcollectitems
+ {\ifconditional\randomizeitems
+ \newcounter\itemcollectcounter
+ \letvalue{\e!start\v!item}\collectitemgroupitem
+ \fi}
+
+%D End of plugin.
+
+\ifx\startcolumns\undefined \def\startcolumns[#1]{} \fi
+\ifx\stopcolumns \undefined \let\stopcolumns\relax \fi
+
+\def\dosetsymalign#1% hm, we should use one of the core-spa macros or make a helper
+ {\processaction
+ [#1]
+ [ \v!flushleft=>\let\symalignleft\relax,
+ \v!right=>\let\symalignleft\relax,
+ \v!flushright=>\let\symalignleft\hfill,
+ \v!left=>\let\symalignleft\hfill,
+ \v!middle=>\let\symalignleft\hfil,
+ \v!center=>\let\symalignleft\hfil]}
+
+\def\redostartitemgroup[#1][#2]%
+ {\setfalse\inlinelistitem % new, no indent (leftskip)
+ \setfalse\concatnextitem % new, concat
+ \setfalse\txtlistitem
+ \ifhmode
+ \ifconditional\autoconcatnextitem % new, concat
+ \ifdim\lastskip=\itemsignal % new, concat
+ \settrue\concatnextitem % new, concat
+ \fi % new, concat
+ \fi % new, concat
+ \ifconditional\textlistitem\else\doifnotinset\v!text{#1}\par\fi % suboptimal
+ \fi
+ \begingroup
+ % new where, ok or not / we should integrate random, intro, continue here
+ % beware, the following no longer inherit from the previous level, is this ok?
+ \setfalse\reverselistitem
+ \setfalse\introlistitem
+ \setfalse\autointrolistitem
+ \setfalse\beforelistitem
+ \setfalse\afterlistitem
+ \setfalse\nowhitelistitem
+ \setfalse\randomizeitems
+ %
+ \doifinsetelse\v!intro {#1}{\settrue\introlistitem }{\setfalse\introlistitem }%
+ \doifinsetelse\v!random {#1}{\settrue\randomizeitems }{\setfalse\randomizeitems }%
+ \doifinsetelse\v!continue{#1}{\settrue\continuelistitems}{\setfalse\continuelistitems}%
+ % == \doifinsetelse\v!intro{#1}\settrue\setfalse\introlistitem
+ \global\advance\noflists\plusone
+ \currentnoflists\noflists
+ \noflistelements\zerocount
+ \setfalse\headlistitem
+ \setfalse\sublistitem
+ \setfalse\symbollistitem
+ \let\marsymbol\relax
+ \globallet\doitemdestination\empty
+ \let\symsymbol\empty
+ \let\symalignleft\relax
+ \the\itemgroupcommands
+ \checkcurrentnofitems
+ % \getitemparameter\currentitemlevel\empty
+ \let\listitem\empty % ** start value
+ \doifelsenothing{#1} % iffirstargument
+ {\edef\@@opsymbol{\noexpand\getitemparameter\currentitemlevel\noexpand\c!symbol}%
+ \letgvalueempty{\@@globalitemsymbol\currentitemlevel}%
+ \global\letitemparameter\currentitemlevel\v!continue\empty
+ \dosetupitemgroupvariable[\currentitemlevel][#2]}
+ {\dosetupitemgroupconstant{#1}%
+ \dosetupitemgroupvariable[\currentitemlevel][#2]%
+ \ifconditional\continuelistitems
+ \edef\@@opsymbol{\executeifdefined{\@@globalitemsymbol\currentitemlevel}{\currentitemlevel}}%
+ \getitemparameter\currentitemlevel\v!continue
+ \else
+ \edef\@@opsymbol{\noexpand\getitemparameter\currentitemlevel\noexpand\c!symbol}%
+ \global\setitemparameter\currentitemlevel\v!continue
+ {\dosetupitemgroupconstant{#1}%
+ \dosetupitemgroupvariable[\currentitemlevel][#2]}%
+ \fi
+ \def\docommand##1% \setitemmark resets \docommand
+ {\doifnot{##1}{0}{\setitemmark{##1}}}%
+ % \processcommalist[#1,\@@opsymbol]\docommand
+ \processcommalist[#1]\docommand}% ** preset sequence or provided sequence
+ % moved to here, after settings
+ \ifnum\currentitemlevel=\plusone % NIEUW
+ \doadaptleftskip {\getitemparameter\currentitemlevel\c!margin}%
+ \doadaptleftskip {\getitemparameter\currentitemlevel\c!leftmargin}%
+ \doadaptrightskip{\getitemparameter\currentitemlevel\c!rightmargin}%
+ \fi
+ \dosetraggedcommand{\getitemparameter\currentitemlevel\c!align}\raggedcommand
+ \dosetsymalign{\getitemparameter\currentitemlevel\c!symalign}%
+ \doifsomething{\getitemparameter\currentitemlevel\c!indenting}
+ {\normalexpanded{\noexpand\setupindenting[\getitemparameter\currentitemlevel\c!indenting]}}%
+ %
+ \setitemlevel{#1}% moved to here
+ \ifx\listitem\empty
+ \setitemmark\@@opsymbol % ** default value
+ \ifx\listitem\empty
+ \edef\currentitemsymbol{\currentitemlevel}% ** fall back
+ \fi
+ \fi
+ \ifconditional\autointrolistitem\ifnum\prevgraf<3
+ \settrue\introlistitem
+ \fi\fi
+ \ifconditional\paragraphlistitem
+ \ifnum\currentitemlevel>\plusone
+ \letitemparameter\currentitemlevel\c!inbetween\empty
+ \fi
+ \fi
+ \ifconditional\packlistitem
+ \letitemparameter\currentitemlevel\c!inbetween\empty
+ \fi
+ \doifinset\v!columns{#1}%
+ {\ifinsidecolumns\else\ifcase\itemcolumndepth
+ \global\itemcolumndepth\currentitemlevel\relax
+ \itembeforecommand
+ \processfirstactioninset
+ [#1]
+ [ \v!one=>\setitemparameter\currentitemlevel\c!n{1},
+ \v!two=>\setitemparameter\currentitemlevel\c!n{2},
+ \v!three=>\setitemparameter\currentitemlevel\c!n{3},
+ \v!four=>\setitemparameter\currentitemlevel\c!n{4},
+ \v!five=>\setitemparameter\currentitemlevel\c!n{5},
+ \s!unknown=>\@EA\!!counta\getitemparameter\currentitemlevel\c!n]%
+ \startcolumns
+ [\c!n=\getitemparameter\currentitemlevel\c!n,
+ \c!height=,
+ \c!rule=\v!off,
+ \c!balance=\v!yes,
+ \c!align=\v!no]%
+ \fi\fi}%
+ \ifconditional\fittinglistitems
+ \ifdim\currentitemmaxwidth>\zeropoint
+ \esetitemparameter\currentitemlevel\c!width{\currentitemmaxwidth}%
+ \fi
+ \fi
+ \calculatelistwidth\currentitemlevel
+ \ifdim\itemgrouplistwidth>\zeropoint\relax
+ \ifconditional\inlinelistitem\else
+ \advance\leftskip\itemgrouplistwidth\relax
+ \fi
+ \fi
+ \startcollectitems}
+
+% test / example
+%
+% \startnarrower[left] \startcolumns[n=3] \startitemize
+% \item \input ward \item \input ward \item \input ward
+% \stopitemize \stopcolumns\stopnarrower \blank
+%
+% \startnarrower[left] \startitemize[columns,three]
+% \item \input ward \item \input ward \item \input ward
+% \stopitemize \stopnarrower \blank
+%
+% \setupitemize[leftmargin=1.5em] \startitemize[columns,three]
+% \item \input ward \item \input ward \item \input ward
+% \stopitemize \blank
+
+\def\stopitemgroup
+ {\stopcollectitems
+ \ifconditional\textlistitem
+ \removeunwantedspaces\space\ignorespaces
+ \else
+ \par
+ \fi
+ \dolistreference
+ \ifconditional\firstlistitem \else \endgroup \fi % toegevoegd, eerste \som opent groep
+ \ifnum\itemcolumndepth=\currentitemlevel\relax
+ \stopcolumns
+ \global\itemcolumndepth\zerocount
+ \itemaftercommand
+ \dontrechecknextindentation
+ \else
+ \ifnum\currentitemlevel=\plusone
+ \allowitembreak
+ \itemaftercommand
+ \checknextindentation[\getitemparameter\currentitemlevel\c!indentnext]%
+ \else
+ % nieuw, not yet nobreak handling
+ \ifcase\autoitemgroupspacing
+ \itemaftercommand
+ \or
+ \itemaftercommand
+ \fi
+ \dontrechecknextindentation
+ \fi
+ \fi
+ % new test, needed in sidefloats (surfaced in volker's proceedings)
+ \ifconditional\textlistitem % else forgotten
+ \endgroup
+ \global\advance\itemdepth-\itemincrement
+ \xdef\currentitemlevel{\number\itemdepth}%
+ \egroup
+ \else
+ \endgroup
+ \global\advance\itemdepth-\itemincrement
+ \xdef\currentitemlevel{\number\itemdepth}%
+ \egroup
+ \par
+ \fi
+ \dorechecknextindentation}
+
+\newtoks\itemgroupcommands
+
+\def\itemgroupitem
+ {\doitemgroupitem}
+
+\def\itemgroupnoitem
+ {\doitemgroupnoitem}
+
+\def\itemgroupbutton[#1]%
+ {\gdef\doitemdestination{#1}%
+ \itemgroupitem}
+
+\def\itemgroupdummy
+ {\itemgroupsymbol{\strut}\strut}
+
+\def\itemgroupsubitem
+ {\settrue\sublistitem
+ \itemgroupitem}
+
+\def\itemgroupsymbol#1%
+ {\def\symsymbol{#1}%
+ \settrue\symbollistitem
+ \itemgroupitem}
+
+\def\itemgroupedge#1%
+ {\itemgroupsymbol
+ {\calculatelistwidth\currentitemlevel
+ \hbox to \itemgrouplistwidth
+ {#1\hskip\getitemparameter\currentitemlevel\c!distance}}}
+
+\def\itemgrouphead
+ {\settrue\headlistitem\doitemgrouphead}
+
+\def\itemgroupitems
+ {\dosingleempty\doitemgroupitems}
+
+\def\doitemgroupitems[#1]%
+ {\itemgroupedge
+ {\dorecurse{0\getitemparameter\currentitemlevel\c!items}{\listitem\hss}%
+ \unskip}}
+
+\def\itemgroupmargin#1%
+ {\def\marsymbol
+ {\llap
+ {\dosetitemattributes\currentitemlevel\c!marstyle\c!marcolor{#1}%
+ \hskip\leftskip\hskip\leftmargindistance}}%
+ \itemgroupitem}
+
+\appendtoks \let\item \itemgroupitem \to \itemgroupcommands
+\appendtoks \let\noitem \itemgroupnoitem \to \itemgroupcommands
+\appendtoks \letvalue\v!item \itemgroupitem \to \itemgroupcommands
+\appendtoks \let\itm \itemgroupitem \to \itemgroupcommands
+\appendtoks \let\but \itemgroupbutton \to \itemgroupcommands
+\appendtoks \let\nop \itemgroupdummy \to \itemgroupcommands
+\appendtoks \letvalue\v!sub \itemgroupsubitem \to \itemgroupcommands
+\appendtoks \letvalue\v!sym \itemgroupsymbol \to \itemgroupcommands
+\appendtoks \letvalue\v!ran \itemgroupedge \to \itemgroupcommands
+\appendtoks \letvalue\v!head \itemgrouphead \to \itemgroupcommands
+\appendtoks \letvalue\v!its \itemgroupitems \to \itemgroupcommands
+\appendtoks \letvalue\v!mar \itemgroupmargin \to \itemgroupcommands
+
+% todo : \startitem .. \stopitem
+
+\appendtoks
+ \letvalue{\e!start\v!item}\itemgroupitem
+ \letvalue{\e!stop \v!item}\endgraf
+\to \itemgroupcommands
+
+\appendtoks
+ \setvalue{\e!start\v!head}#1{\itemgrouphead#1\par}%
+ \letvalue{\e!stop \v!head}\endgraf
+\to \itemgroupcommands
+
+% \startitemize
+% \starthead {xx} test \stophead
+% \startitem test \stopitem
+% \startitem test \stopitem
+% \stopitemize
+
+% Sometimes the user demands get pretty weird:
+%
+% \startitemize
+% \item test
+% \item test
+% \headsym{xx} test \par test
+% \stopitemize
+
+% aligned items
+%
+% \startitemize[n,fit,broad][itemalign=flushright]
+% \dorecurse{100}{\item The first item.}
+% \stopitemize
+%
+% \setupitemgroup[itemize][each][fit]
+% \setupitemgroup[itemize][each][distance=.5em,factor=1,itemalign=flushright]
+%
+% \startitemize[n]
+% \dorecurse{100}{\item The first item.}
+% \stopitemize
+
+\appendtoks \let\headsym \itemgroupheadsym \to \itemgroupcommands
+
+\def\itemgroupheadsym#1%
+ {\def\symsymbol{#1}%
+ \settrue\symbollistitem
+ \settrue\headlistitem
+ \doitemgrouphead}
+
+% \defineitemgroup[gbitemize]
+% \setupitemgroup[gbitemize][each][headstyle=bold]
+
+% \startgbitemize
+% \txt{italian} some italians like this kind of cross||breed between
+% an itemize and a description
+% \txt{sicilians} i wonder how many sicilian mathematicians do a thesis
+% on the math involved in predicting the next big bang of the vulcano
+% \stopgbitemize
+
+\appendtoks \letvalue\v!txt\itemgrouptext \to \itemgroupcommands
+
+\newconditional\txtlistitem \setfalse\txtlistitem
+
+\def\itemgrouptext#1%
+ {\def\symsymbol{#1}%
+ \settrue\symbollistitem
+ \settrue\txtlistitem
+ \itemgroupitem}
+
+\def\dodotxtitem
+ {\scratchdimen\wd\itemgroupitembox
+ \advance \scratchdimen \getitemparameter\currentitemlevel\c!distance\relax
+ \ifdim\scratchdimen>\itemgrouplistwidth
+ \advance\scratchdimen -\itemgrouplistwidth
+ \else
+ \scratchdimen\zeropoint
+ \fi
+ \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hss}}% was: \hfill
+ \hskip\scratchdimen}
+
+\def\optimizelistitemsbreak
+ {\ifcase\itemcolumndepth \ifconditional\optimizelistitem
+ \ifcase \currentnofitems \else
+ \ifnum\currentnofitems=\plusthree
+ \ifnum\noflistelements>\plusone
+ \noitembreakspecial
+ \fi
+ \else\ifnum\currentnofitems>\plusthree
+ \ifnum\noflistelements=\plustwo
+ \ifconditional\introlistitem
+ \noitembreak
+ \else
+ \noitembreakspecial
+ \fi
+ \else\ifnum\currentnofitems=\noflistelements\relax
+ \noitembreakspecial
+ \else\ifnum\noflistelements>\plustwo
+ \itembreakspecial
+ \else
+ \ifconditional\introlistitem\else\itembreakspecial\fi
+ \fi\fi\fi
+ \fi\fi
+ \fi
+ \fi\fi}
+
+\def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken
+ {\ifconditional\textlistitem
+ % begin of item
+ \else
+ \par
+ \fi
+ \advance\noflistelements\plusone
+ \optimizelistitemsbreak
+ \noindent
+ \setbox\itemgroupitembox\hbox
+ {\ifconditional\headlistitem
+ \ifconditional\symbollistitem
+ \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}%
+ \else
+ \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor{\listitem}%
+ \fi
+ \else
+ \ifconditional\symbollistitem
+ \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}%
+ \else
+ \dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}%
+ \fi
+ \fi}%
+ \ifconditional\fittinglistitems
+ \ifdim\wd\itemgroupitembox>\getitemparameter\currentitemlevel\c!maxwidth sp\relax
+ \xsetitemparameter\currentitemlevel\c!maxwidth{\number\wd\itemgroupitembox}%
+ \fi
+ \ifdim\currentitemmaxwidth>\zeropoint
+ \setbox\itemgroupitembox\simplealignedbox{\getitemparameter\currentitemlevel\c!itemalign}{\currentitemmaxwidth}{\box\itemgroupitembox}%
+ \fi
+ \fi
+ \doifsomething\doitemdestination
+ {\setbox\itemgroupitembox\hbox{\goto{\box\itemgroupitembox}[\doitemdestination]}}%
+ \globallet\doitemdestination\empty
+ \itemgroupaskedwidth\getitemparameter\currentitemlevel\c!width\relax
+ % new, prevents loops when symbol is (not yet found) graphic
+ \ht\itemgroupitembox\strutheight
+ \dp\itemgroupitembox\strutdepth
+ % so that content differs per run (esp mp graphics afterwards)
+ \checkforrepeatedlistitem
+ \ifdim\itemgroupaskedwidth<\zeropoint\relax
+ \llap{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hskip\leftmargindistance}%
+ \else
+ \ifdim\itemgroupaskedwidth=\zeropoint\relax
+ \calculatelistwidth1%
+ \else
+ \calculatelistwidth\currentitemlevel
+ \fi
+ \ifconditional\textlistitem
+ \hbox{\ifconditional\sublistitem+\fi\box\itemgroupitembox\hskip\interwordspace}\nobreak
+ \else\ifconditional\inlinelistitem
+ \hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi\box\itemgroupitembox\hss}% was: \hfill
+ \else\ifconditional\txtlistitem
+ \dodotxtitem
+ \else
+ % todo: align+marge binnen de hbox
+ \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+}\fi
+ \symalignleft
+ \box\itemgroupitembox\hfil
+ \hskip\getitemparameter\currentitemlevel\c!distance% T h
+ }}%
+ \fi\fi\fi
+ \fi
+ \forceunexpanded % needed for m conversion (\os) / i need to look into this
+ \setevalue{\@@currentitemsymbol\currentitemlevel}%
+ {\getvalue{\@@localitemsymbol\currentitemlevel}}% still problems with \uchar ?
+ %{\noexpand\getvalue{\@@localitemsymbol\currentitemlevel}}% no, spoils subrefs
+ \resetunexpanded
+ \setfalse\headlistitem
+ \setfalse\sublistitem
+ \setfalse\symbollistitem
+ \EveryPar{\ignorespaces}% needed ?
+ \ignorespaces}
+
+% For Wolfgang Schuster
+
+% \startitemize[n,repeat]
+% \noitem \startitemize[a] \item Item 1.a. \item Item 1.b. \stopitemize
+% \noitem \startitemize[a] \item Item 2.a. \item Item 2.b. \stopitemize
+% \stopitemize
+
+\def\donolistitem % reduced \dolistitem
+ {\advance\noflistelements\plusone
+ \setbox\itemgroupitembox\hbox
+ {\dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}}%
+ \checkforrepeatedlistitem
+ \ignorespaces}
+
+\def\doitemgroupnoitem
+ {\doadvanceitem\donolistitem}
+
+% For Frank Grieshaber and Mojca Miklavec:
+
+\newconditional\repeatlistitem
+
+\def\checkforrepeatedlistitem
+ {\ifconditional\repeatlistitem
+ \ifx\currentrepeatstart\empty
+ \edef\currentrepeatstart{\the\numexpr\currentitemlevel-1}%
+ \fi
+ \setbox\itemgroupitembox\hbox to \wd\itemgroupitembox{\hskip-\itemgroupaskedwidth\box\itemgroupitembox}% what a hack !
+ \fi}
+
+% \startbuffer
+% \item
+% \startitemize[n]
+% \item item 1.1
+% \item item 1.2
+% \startitemize[n] \item item 1.2.1 \item item 1.2.2 \stopitemize
+% \item item 1.3
+% \stopitemize
+% \item
+% \startitemize[n] \item item 2.1 \item item 2.2 \stopitemize
+% \item item 3
+% \startitemize[n] \item item 3.1 \item item 3.2 \stopitemize
+% \item
+% \startitemize[n] \item item 4.1 \item item 4.2 \stopitemize
+% \stopbuffer
+%
+% \startitemize[n,repeat,6*broad,packed] \getbuffer \stopitemize \blank[3*big]
+% \startitemize[n,repeat,packed] \getbuffer \stopitemize \blank[3*big]
+% \setupitemize[each][atmargin][width=3em]
+% \startitemize[n,repeat,packed] \getbuffer \stopitemize
+
+\chardef\autoitemgroupspacing=2 % 0 = voor/na, 1=tussen als geen voor 2=(prev)tussen=old/normal
+
+\def\complexdoitemgroupitem[#1]%
+ {\def\currentitemreference{#1}%
+ \ifconditional\textlistitem
+ % begin of item
+ \else
+ \par
+ \fi
+ \ifconditional\concatnextitem % new, concat
+ \noitembreak % new, concat
+ \fi % new, concat
+ \doadvanceitem
+ \ifconditional\firstlistitem
+ \setfalse\firstlistitem
+ \begingroup
+ \ifcase\currentitemlevel
+ \or % 1
+ \ifcase\itemcolumndepth
+ \ifconditional\introlistitem\noitembreak\fi
+ \itembeforecommand
+ \ifconditional\introlistitem\noitembreak\fi
+ \fi
+ \else % 2 en hoger
+ \ifconditional\paragraphlistitem \else
+ \edef\previtemlevel{\the\numexpr\currentitemlevel-1}%
+ \ifcase\autoitemgroupspacing\relax % nieuw
+ \itembeforecommand
+ \or
+ \doifelsenothing\itembeforecommand\itembeforecommand{\getitemparameter\previtemlevel\c!inbetween}%
+ \else
+ \getitemparameter\previtemlevel\c!inbetween
+ \fi
+ \fi
+ \fi
+ \else
+ \ifconditional\textlistitem % was bugged: \inlinelistitem
+ \removeunwantedspaces\hskip\emwidth\!!plus\interwordstretch\!!minus\interwordshrink\relax % new per 2006/10/20
+ \else
+ \iteminbetweencommand
+ \fi
+ \fi
+ \ifconditional\concatnextitem
+ \vskip-\dimexpr\lastskip+\lineheight\relax
+ \nobreak
+ \fi
+ \dolistitem
+ \relax
+ \ifconditional\packlistitem
+ \setupwhitespace[\v!none]%
+ \fi
+ \getitemparameter\currentitemlevel\c!inner
+ \marsymbol
+ \let\marsymbol\relax
+ \strut % added 11-08-99
+% \dohandleitemreference
+ \setfalse\concatnextitem % new, concat
+ \nobreak % else problems with intext items
+ \hskip\itemsignal % new, concat
+ \getitemparameter\currentitemlevel\c!command} % \defaultitemcommand
+
+\def\defaultitemcommand
+ {\EveryPar{\ignorespaces}% needed ?
+ \ignorespaces}
+
+% For Giuseppe "Oblomov" Bilotta, inspired on a suggestion by Taco
+% Hoekwater.
+%
+% \def\MyItemCommand#1{{\bf#1}\quad}
+% \setupitemgroup[itemize][command=\MyItemCommand]
+%
+% \startitemize
+% \item {test} is this okay?
+% \item {test} is this okay?
+% \item {test} is this okay?
+% \stopitemize
+
+\def\complexitem[#1]#2\par % todo: no two pass data
+ {\startitemgroup[#1]%
+ \complexdoitemgroupitem[]\begstrut#2\endstrut\par
+ \stopitemgroup}
+
+\definecomplexorsimpleempty\item
+\definecomplexorsimpleempty\doitemgroupitem
+
+\def\complexhead[#1]#2\par#3\par
+ {\startitemgroup[#1]%
+ \complexdoitemgrouphead[]\begstrut#2\endstrut\par\begstrut#3\endstrut\par
+ \stopitemgroup}
+
+% the next solution accepts \head test \type{x{x}x} test ...
+
+\def\complexdoitemgrouphead[#1]% beter in \complexdosom hangen met een if
+ {\ifconditional\firstlistitem\else\allowitembreak\fi
+ \ifconditional\packlistitem\else\itembeforeheadcommand\fi
+ \ifconditional\firstlistitem\ifconditional\introlistitem\else\ifcase\currentitemlevel % incr in \complexdosom
+ \allowitembreak
+ \fi\fi\fi
+ \complexdoitemgroupitem[#1]%
+ \bgroup
+ \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor\empty
+ \ignorespaces
+ \let\par\enditemhead} % brrrr but simple anyway
+
+\def\enditemhead
+ {\removeunwantedspaces
+ \egroup
+ \ifconditional\textlistitem
+ \space\ignorespaces
+ \else
+ \par
+ \fi
+ \noitembreak
+ \ifconditional\packlistitem\else\itemafterheadcommand\fi
+ \noitembreak
+ \noindentation}
+
+\definecomplexorsimpleempty\head
+\definecomplexorsimpleempty\doitemgrouphead
+
+\def\sym#1%
+ {\noindent
+ \begingroup
+ \setbox\scratchbox\hbox{\trialtypesettingtrue#1}%
+ \setbox\scratchbox\hbox
+ \ifdim\wd\scratchbox<1em to 1.5\else spread 1\fi em{#1\hfil}%
+ \normalexpanded{\box\scratchbox\endgroup\hangindent\the\wd\scratchbox}%
+ \ignorespaces}
+
+\setupitemgroups
+ [\c!margin=\zeropoint,
+ \c!leftmargin=\zeropoint,
+ \c!rightmargin=\zeropoint,
+ \c!indentnext=\v!yes,
+ \c!width=1.5em,
+ \c!factor=0,
+ \c!distance=.5em,
+ %\c!align=\v!normal, % definitely not \v!normal, see mails and
+ %\c!align=, % debug reports of David A & Patrick G on context list
+ %\c!symalign=,
+ %\c!color=,
+ %\c!indenting=, % untouched if empty
+ %\c!style=,
+ \c!marstyle=\c!type, % \c! ???
+ %\c!symstyle=,
+ %\c!headstyle=,
+ %\c!marcolor=,
+ %\c!symcolor=,
+ %\c!headcolor=,
+ %\c!beforehead=,
+ \c!afterhead=\blank,
+ \c!before=\blank,
+ \c!inbetween=\blank,
+ \c!after=\blank,
+ %\c!stopper=.,
+ \c!placestopper=\v!yes,
+ \c!stopper=.,
+ %\c!inner=,
+ \c!n=2,
+ \c!items=4,
+ \c!lefttext=(,
+ \c!righttext=),
+ \c!start=1,
+ %\c!option=,
+ \c!command=\defaultitemcommand,
+ \c!symbol=\currentitemlevel]
+
+\setupitemgroups
+ [\c!numberseparatorset=,
+ \c!numberconversionset=,
+ \c!numberstopper=.,
+ \c!numbersegments=1]
+
+\defineitemgroup [\v!itemize]
+
+\protect \endinput
diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua
new file mode 100644
index 000000000..48e2bf07d
--- /dev/null
+++ b/tex/context/base/strc-lst.lua
@@ -0,0 +1,392 @@
+if not modules then modules = { } end modules ['strc-lst'] = {
+ version = 1.001,
+ comment = "companion to strc-lst.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- when all datastructures are stable a packer will be added which will
+-- bring down memory consumption a bit; we can use for instance a pagenumber,
+-- section, metadata cache (internal then has to move up one level) or a
+-- shared cache [we can use a fast and stupid serializer]
+
+local format, tonumber = string.format, tonumber
+local texsprint, texprint, texwrite, count = tex.sprint, tex.print, tex.write, tex.count
+
+local ctxcatcodes = tex.ctxcatcodes
+
+structure.lists = structure.lists or { }
+structure.sections = structure.sections or { }
+structure.helpers = structure.helpers or { }
+structure.documents = structure.documents or { }
+structure.pages = structure.pages or { }
+
+local lists = structure.lists
+local sections = structure.sections
+local helpers = structure.helpers
+local documents = structure.documents
+local pages = structure.pages
+
+lists.collected = lists.collected or { }
+lists.tobesaved = lists.tobesaved or { }
+lists.enhancers = lists.enhancers or { }
+lists.internals = lists.internals or { }
+lists.ordered = lists.ordered or { }
+
+local variables = interfaces.variables
+
+local function initializer()
+ -- create a cross reference between internal references
+ -- and list entries
+ local collected = lists.collected
+ local internals = lists.internals
+ local ordered = lists.ordered
+ for i=1,#collected do
+ local c = collected[i]
+ local m = c.metadata
+ local r = c.references
+ if m then
+ -- access by internal reference
+ local internal = r and r.internal
+ if internal then
+ internals[internal] = c
+ end
+ -- access by order in list
+ local kind, name = m.kind, m.name
+ if kind and name then
+ local ok = ordered[kind]
+ if ok then
+ local on = ok[name]
+ if on then
+ on[#on+1] = c
+ else
+ ok[name] = { c }
+ end
+ else
+ ordered[kind] = { [name] = { c } }
+ end
+ end
+ end
+ end
+end
+
+if job then
+ job.register('structure.lists.collected', structure.lists.tobesaved, initializer)
+end
+
+local cached = { }
+local pushed = { }
+
+function lists.push(t)
+ local r = t.references
+ local i = (r and r.internal) or 0 -- brrr
+ local p = pushed[i]
+ if not p then
+ p = #cached + 1
+ cached[p] = helpers.simplify(t)
+ pushed[i] = p
+ end
+ texwrite(p)
+end
+
+function lists.doifstoredelse(n)
+ commands.doifelse(cached[tonumber(n)])
+end
+
+-- this is the main pagenumber enhancer
+
+function lists.enhance(n)
+ -- todo: symbolic names for counters
+ local l = cached[n]
+ if l then
+ -- save space
+ l.directives = nil
+ -- save in the right order (happen sat shipout)
+ lists.tobesaved[#lists.tobesaved+1] = l
+ -- default enhancer (cross referencing)
+ l.references.realpage = count[0]
+ -- specific enhancer (kind of obsolete)
+ local kind = l.metadata.kind
+ local enhancer = kind and lists.enhancers[kind]
+ if enhancer then
+ enhancer(l)
+ end
+ end
+end
+
+-- we can use level instead but we can also decide to remove level from the metadata
+
+-- we need level instead of cnumbers and we also need to deal with inbetween
+
+local function filter_collected(names, criterium, number, collected)
+ local numbers, depth = documents.data.numbers, documents.data.depth
+ local hash, result, all = { }, { }, not names or names == "" or names == variables.all
+ if not all then
+ for s in names:gmatch("[^, ]+") do
+ hash[s] = true
+ end
+ end
+ if criterium == variables.all or criterium == variables.text then
+ for i=1,#collected do
+ local v = collected[i]
+ local r = v.references
+ if r then
+ local sectionnumber = (r.section == 0) or jobsections.collected[r.section]
+ if sectionnumber then -- and not sectionnumber.hidenumber then
+ local metadata = v.metadata
+ if metadata and not metadata.nolist and (all or hash[metadata.name or false]) then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ elseif criterium == variables.current then
+ for i=1,#collected do
+ local v = collected[i]
+ local r = v.references
+ if r then
+ local sectionnumber = jobsections.collected[r.section]
+ if sectionnumber then -- and not sectionnumber.hidenumber then
+ local cnumbers = sectionnumber.numbers
+ local metadata = v.metadata
+ if cnumbers then
+ if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers > depth then
+ local ok = true
+ for d=1,depth do
+ local cnd = cnumbers[d]
+ if not (cnd == 0 or cnd == numbers[d]) then
+ ok = false
+ break
+ end
+ end
+ if ok then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif criterium == variables.here then
+ for i=1,#collected do
+ local v = collected[i]
+ local r = v.references
+ if r then
+ local sectionnumber = jobsections.collected[r.section]
+ if sectionnumber then -- and not sectionnumber.hidenumber then
+ local cnumbers = sectionnumber.numbers
+ local metadata = v.metadata
+ if cnumbers then
+ if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers >= depth then
+ local ok = true
+ for d=1,depth do
+ local cnd = cnumbers[d]
+ if not (cnd == 0 or cnd == numbers[d]) then
+ ok = false
+ break
+ end
+ end
+ if ok then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif criterium == variables.previous then
+ for i=1,#collected do
+ local v = collected[i]
+ local r = v.references
+ if r then
+ local sectionnumber = jobsections.collected[r.section]
+ if sectionnumber then -- and not sectionnumber.hidenumber then
+ local cnumbers = sectionnumber.numbers
+ local metadata = v.metadata
+ if cnumbers then
+ if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers >= depth then
+ local ok = true
+ for d=1,depth-1 do
+ local cnd = cnumbers[d]
+ if not (cnd == 0 or cnd == numbers[d]) then
+ ok = false
+ break
+ end
+ end
+ if ok then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif criterium == variables["local"] then
+ if sections.autodepth(documents.data.numbers) == 0 then
+ return filter_collected(names,variables.all,number,collected)
+ else
+ return filter_collected(names,variables.current,number,collected)
+ end
+ else -- sectionname, number
+ local depth = sections.getlevel(criterium)
+ local number = tonumber(number) or 0
+ for i=1,#collected do
+ local v = collected[i]
+ local r = v.references
+ if r then
+ local sectionnumber = jobsections.collected[r.section]
+ if sectionnumber then -- and not sectionnumber.hidenumber then
+ local cnumbers = sectionnumber.numbers
+ local metadata = v.metadata
+ if cnumbers then
+ if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers >= depth and cnumbers[depth] == number then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ end
+ end
+ return result
+end
+
+lists.filter_collected = filter_collected
+
+function lists.filter(names, criterium, number)
+ return filter_collected(names, criterium, number, lists.collected)
+end
+
+lists.result = { }
+
+function lists.process(...)
+ lists.result = lists.filter(...)
+ for i=1,#lists.result do
+ local r = lists.result[i]
+ local m = r.metadata
+ texsprint(ctxcatcodes,format("\\processlistofstructure{%s}{%s}{%i}",m.name,m.kind,i))
+ end
+end
+
+function lists.analyze(...)
+ lists.result = lists.filter(...)
+end
+
+function lists.userdata(name,r,tag)
+ local str = lists.result[r]
+ str = str and str.userdata
+ str = str and str[tag]
+ if str then
+ texsprint(ctxcatcodes,str)
+ end
+end
+
+function lists.uservalue(name,r,tag,default)
+ local str = lists.result[r]
+ str = str and str.userdata
+ str = str and str[tag]
+ return str or default
+end
+
+function lists.size()
+ texprint(#lists.result)
+end
+
+function lists.location(name,n)
+ local l = lists.result[n]
+ texsprint(l.references.internal or n)
+end
+
+function lists.sectionnumber(name,n,spec)
+ local data = lists.result[n]
+ local sectiondata = jobsections.collected[data.references.section]
+ sections.typesetnumber(sectiondata,"prefix",spec,sectiondata) -- data happens to contain the spec too
+end
+
+-- some basics (todo: helpers for pages)
+
+function lists.title(name,n,tag) -- tag becomes obsolete
+ local data = lists.result[n]
+ if data then
+ local titledata = data.titledata
+ if titledata then
+ texsprint(ctxcatcodes,titledata[tag] or titledata.title or "")
+ end
+ end
+end
+
+function lists.savedtitle(name,n,tag)
+ local data = cached[tonumber(n)]
+ if data then
+ local titledata = data.titledata
+ if titledata then
+ texsprint(ctxcatcodes,titledata[tag] or titledata.title or "")
+ end
+ end
+end
+
+function lists.savednumber(name,n)
+ local data = cached[tonumber(n)]
+ if data then
+ local numberdata = data.numberdata
+ if numberdata then
+ sections.typesetnumber(numberdata,"number",numberdata or false)
+ end
+ end
+end
+
+function lists.savedprefixednumber(name,n)
+ local data = cached[tonumber(n)]
+ if data then
+ helpers.prefix(data,data.prefixdata)
+ local numberdata = data.numberdata
+ if numberdata then
+ sections.typesetnumber(numberdata,"number",numberdata or false)
+ end
+ end
+end
+
+function lists.prefix(name,n,spec)
+ helpers.prefix(lists.result[n],spec)
+end
+
+function lists.page(name,n,pagespec)
+ helpers.page(lists.result[n],pagespec)
+end
+
+function lists.prefixedpage(name,n,prefixspec,pagespec)
+ helpers.prefixpage(lists.result[n],prefixspec,pagespec)
+end
+
+function lists.realpage(name,n)
+ local data = lists.result[n]
+ if data then
+ local references = data.references
+ texsprint(references and references.realpage or 0)
+ else
+ texsprint(0)
+ end
+end
+
+-- numbers stored in entry.numberdata + entry.numberprefix
+
+function lists.number(name,n,spec)
+ local data = lists.result[n]
+ if data then
+ local numberdata = data.numberdata
+ if numberdata then
+ sections.typesetnumber(numberdata,"number",spec or false,numberdata or false)
+ end
+ end
+end
+
+function lists.prefixednumber(name,n,prefixspec,numberspec)
+ local data = lists.result[n]
+ if data then
+ helpers.prefix(data,prefixspec)
+ local numberdata = data.numberdata
+ if numberdata then
+ sections.typesetnumber(numberdata,"number",spec or false,numberdata or false)
+ end
+ end
+end
diff --git a/tex/context/base/strc-lst.tex b/tex/context/base/strc-lst.tex
new file mode 100644
index 000000000..22c189c77
--- /dev/null
+++ b/tex/context/base/strc-lst.tex
@@ -0,0 +1,944 @@
+%D \module
+%D [ file=strc-lst,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Lists,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Lists}
+
+\registerctxluafile{strc-lst}{1.001}
+
+\unprotect
+
+\def\currentstructurelistnumber{0}
+
+% nmstate -> no pagenumber if not start
+% autocrossdocument -> todo
+% expansion -> todo
+% auto refs to lists (chain) -> todo (\dododowritetolist)
+% todo: \normalexpanded{\noexpand\everylistentry\emptytoks\the\everylistentry}% \emptytoks, else loop
+
+% \def\linklisttoelement#1#2#3#4{#4}% list location format page data
+
+\def\linklisttoelement#1#2#3#4% % list location format page data
+ {\gotonextinternal\currentlist{#1}{#3}{#4}}
+
+% interface to lua
+
+% we have to deal with compatible processing, i.e. list elements that have two
+% elements plus a pagenumber
+
+\let\listentry\gobblesixarguments
+
+\def\currentlist {\s!unknown}
+\def\currentlistmethod{entry}
+\def\currentlistindex {0}
+
+\def\setlistparameter#1#2#3{\@EA\def\csname\??li#1#2\endcsname{#3}} % often
+%def\listparameter #1{\ifcsname\??li\currentlist#1\endcsname\csname\??li\currentlist#1\endcsname\fi}
+
+% interface
+
+\def\listparameter #1{\csname\dolistparameter{\??li\currentlist}#1\endcsname}
+\def\namedlistparameter#1#2{\csname\dolistparameter{\??li #1}#2\endcsname}
+\def\listparameterhash #1{\dolistparameterhash {\??li\currentlist}#1}
+
+\def\dolistparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dolistparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\dolistparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dolistparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dolistparentparameter #1#2{\ifx#1\relax\s!empty\else\dolistparameter #1#2\fi}
+\def\dolistparentparameterhash#1#2{\ifx#1\relax \else\dolistparameterhash#1#2\fi}
+
+\def\dosetlistattributes#1#2% style color
+ {\edef\fontattributehash {\listparameterhash#1}%
+ \edef\colorattributehash{\listparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+\def\donestedlistattributes#1#2%
+ {\dosetlistattributes#1#2%
+ \ifx\colorattributehash\empty \else
+ \resetinteractionparameter\c!color
+ \resetinteractionparameter\c!contrastcolor
+ \fi}
+
+% handling
+
+
+% The next code injects data into the list at the current level.
+
+\def\structurelistinject{\dotripleempty\dostructurelistinject}
+
+\def\dostructurelistinject[#1][#2][#3]%
+ {\begingroup
+ \edef\currentlistname{#1}%
+ \setnextinternalreference
+ \edef\currentlistnumber{\ctxlua{structure.lists.push{
+ references = {
+ internal = \nextinternalreference,
+ section = structure.sections.currentid(),
+ },
+ metadata = {
+ kind = "#2",
+ name = "\currentlistname",
+ level = structure.sections.currentlevel(),
+ catcodes = \the\catcodetable,
+ },
+ userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es)
+ }}}%
+ \expanded{\ctxlatelua{structure.lists.enhance(\currentlistnumber)}}%
+ \endgroup}
+
+\def\structurelistlocation
+ {\ctxlua{structure.lists.location("\currentlist",\currentlistindex)}}
+
+\def\structurelistpagenumber
+ {\ctxlua{structure.lists.prefixedpage(
+ "\currentlist",
+ \currentlistindex,
+ {
+ separatorset = "\listparameter\c!pageprefixseparatorset",
+ conversionset = "\listparameter\c!pageprefixconversionset",
+ set = "\listparameter\c!pageprefixset",
+ segments = "\listparameter\c!pageprefixsegments",
+ connector = \!!bs\listparameter\c!pageprefixconnector\!!es,
+ },
+ {
+ prefix = "\listparameter\c!pageprefix",
+ conversionset = "\listparameter\c!pageconversionset",
+ stopper = \!!bs\listparameter\c!pagestopper\!!es,
+ }
+ )}}
+
+\def\structurelistrealpagenumber
+ {\ctxlua{structure.lists.realpage("\currentlist",\currentlistindex)}}
+
+\def\structurelistfirst
+ {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"first")}}
+
+\def\structurelistsecond
+ {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"second")}}
+
+% \appendtoks
+% \to \everystructurelist
+
+\def\placestructurelist#1#2#3%
+ {\ctxlua{structure.lists.process("#1","#2","#3")}}
+
+\def\analysestructurelist#1#2#3%
+ {\ctxlua{structure.lists.analyze("#1","#2","#3")}}
+
+\def\firststructureelementinlist#1%
+ {\ctxlua{commands.first_in_list("#1")}}
+
+\def\structurelistsize
+ {\ctxlua{structure.lists.size()}}
+
+\def\@@structurelistprocess{structurelist:process:}
+
+\def\installstructurelistprocessor#1#2%
+ {\expandafter\def\csname\@@structurelistprocess#1\endcsname{#2}}
+
+\def\usestructurelistprocessor#1%
+ {\csname\@@structurelistprocess#1\endcsname}
+
+\installstructurelistprocessor\s!default
+ {no list method}
+
+\def\processlistofstructure#1#2#3% name, method, n
+ {\edef\currentlist {#1}%
+ \edef\currentlistmethod{#2}%
+ \edef\currentlistindex {#3}%
+ \csname\@@structurelistprocess
+ \ifcsname\@@structurelistprocess\currentlist:\currentlistmethod\endcsname\currentlist:\currentlistmethod\else
+ \ifcsname\@@structurelistprocess\currentlistmethod \endcsname\currentlistmethod \else
+ \ifcsname\@@structurelistprocess\currentlist \endcsname\currentlist \else
+ \s!default \fi\fi\fi
+ \endcsname}
+
+% \installstructcurelistprocessor{pubs:userdata}
+% {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"bibref")}}
+
+\installstructurelistprocessor{command}
+ {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"command")}}
+
+\installstructurelistprocessor{section}
+ {\dodolistelement
+ \currentlist
+ \structurelistlocation
+ \structurelistgenericnumber
+ \structurelistgenerictitle
+ \structurelistpagenumber
+ \structurelistrealpagenumber}
+
+% so far (todo: also recursive)
+
+\def\listalternativeparameter#1%
+ {\csname\??li\??li\listparameter\c!alternative#1\endcsname}
+
+\def\setuplistalternative[#1]%
+ {\dodoubleargument\getparameters[\??li\??li#1]}
+
+\def\listfill {\listalternativeparameter\c!command }
+\def\listskip {\listalternativeparameter\c!distance}
+\def\listwidth {\listalternativeparameter\c!width }
+\def\liststretch{\listalternativeparameter\c!stretch }
+
+% a : nr - tit - pag
+% b : nr - tit - fill - pag
+% c : nr - tit - dots - pag
+
+\setuplistalternative[a][\c!distance=0pt,\c!width=2em,\c!stretch=10em,\c!command=\hskip.25em\relax]
+\setuplistalternative[b][\c!distance=5em,\c!width=2em,\c!stretch=10em,\c!command=\hfill]
+\setuplistalternative[c][\c!distance=5em,\c!width=0pt,\c!stretch=10em,\c!command=\hskip.5em\listdots\hskip.5em\relax]
+
+\def\listdots{\leaders\hbox to .5em{\hss.\hss}\hfill}
+
+\setvalue{\??li\c!alternative}{\getvalue{\??li\c!alternative b}}
+\getvalue{\??li\c!alternative}
+
+\def\dosetuplist[#1][#2]% slow -)
+ {\def\docommand##1{\getparameters[\??li##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+\def\setuplist
+ {\dodoubleargument\dosetuplist}
+
+\def\dodefinelist[#1][#2][#3]%
+ {\presetlocalframed[\??li#1]% still inefficient (will change when we redu core-rul)
+ \doifassignmentelse{#2}
+ {\getparameters[\??li#1][\s!parent=\??li,#2]}
+ {\doifelsenothing{#2}
+ {\getparameters[\??li#1][\s!parent=\??li]}
+ {\getparameters[\??li#1][\s!parent=\??li#2,#3]}}}
+
+\def\setuplists % new, but not for users (hardly handy)
+ {\dodoubleargument\getparameters[\??li]}
+
+\setuplists
+ [\c!height=\v!broad,
+ \c!depth=\v!broad,
+ \c!offset=0.25em,
+ %\c!maxwidth=,
+ \c!state=\v!start,
+ \c!coupling=\v!off,
+ \c!criterium=\v!local,
+ \c!number=0,
+ \c!width=3em,
+ \c!alternative=\c!b,
+ \c!style=\v!normal,
+ \c!textstyle=\listparameter\c!style,
+ \c!numberstyle=\listparameter\c!style,
+ \c!pagestyle=\listparameter\c!style,
+ %\c!color=,
+ \c!textcolor=\listparameter\c!color,
+ \c!numbercolor=\listparameter\c!color,
+ \c!pagecolor=\listparameter\c!color,
+ \c!numbercommand=\listnumbercommand,
+ \c!textcommand=\listtextcommand,
+ \c!pagecommand=\listpagecommand,
+ \c!pagenumber=\v!yes,
+ \c!headnumber=\v!yes,
+ %\c!pageboundaries=,
+ \c!margin=\!!zeropoint,
+ %\c!aligntitle=,
+ %\c!before=,
+ %\c!after=,
+ %\c!inbetween=,
+ %\c!symbol=,
+ \c!interaction=\v!sectionnumber,
+ \c!label=\v!no,
+ \c!distance=\!!zeropoint,
+ \c!limittext=\@@kolimittext,
+ %\c!sectionseparatorset=,
+ %\c!sectionconversionset=,
+ %\c!sectionstopper=,
+ %\c!sectionset=,
+ %\c!sectionsegments=,
+ %\c!prefix=\v!no,
+ %\c!prefixseparatorset=,
+ %\c!prefixconversionset=,
+ %\c!prefixstopper=.,
+ %\c!prefixset=,
+ %\c!prefixsegments=,
+ %\c!pageseparatorset=,
+ %\c!pageconversionset=,
+ %\c!pagestopper=,
+ %\c!expansion=,
+ % \c!prefixconnector=., % maybe inherit from setupheads
+ % \c!pageprefix=\v!no, % is unset, inherits
+ % \c!pageprefixconnector=\listparameter\c!prefixconnector,
+ ]% \c!pagesegments=2:2]
+
+\def\definelist
+ {\dotripleempty\dodefinelist}
+
+\def\placelist
+ {\dodoubleempty\doplacelist}
+
+\def\placerawlist
+ {\dodoubleempty\doplacerawlist}
+
+\def\dobeginoflist
+ {\begingroup
+ \startpacked[\v!blank]}
+
+\def\doendoflist
+ {\stoppacked
+ \endgroup}
+
+\def\doplacelist[#1][#2]%
+ {\dobeginoflist
+ \doplacerawlist[#1][#2]%
+ \doendoflist}
+
+\newtoks\everystructurelist
+
+% writing to lists
+
+\def\writetolist[#1]{\gobbletwoarguments}
+\let\dowritetolist \gobblefourarguments
+\let\dodowritetolist\gobblefourarguments
+
+\def\writebetweenlist[#1]#2%
+ {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][command][command={#2}]}}
+
+\def\writedatatolist
+ {\dodoubleargument\dowritedatatolist}
+
+\def\dowritedatatolist[#1][#2]%
+ {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][userdata][#2]}}
+
+\def\writetolist[#1]#2#3%
+ {\doif{\namedlistparameter{#1}\c!state}\v!start{\structurelistinject[#1][simple][first={#2},second={#3}]}}
+
+\installstructurelistprocessor{simple}
+ {\dodolistelement
+ \currentlist
+ \structurelistlocation
+ \structurelistfirst
+ \structurelistsecond
+ \structurelistpagenumber
+ \structurelistrealpagenumber}
+
+% % %
+
+\def\doplacerawlist[#1][#2]% listreferences will be redone
+ {\begingroup
+ \dosetuplist[#1][#2]%
+ \edef\currentlist{\firststructureelementinlist{#1}}%
+ \the\everystructurelist
+ \doif{\listparameter\c!coupling}\v!on{\startlistreferences{#1}}%
+ \placestructurelist{#1}{\listparameter\c!criterium}{\listparameter\c!number}%
+ \stoplistreferences
+ \endgroup
+ \dosetlistmode}
+
+\def\dosetlistmode % utilitydone will disappear
+ {\ifcase\structurelistsize\relax
+ \utilitydonefalse \resetsystemmode\v!list
+ \else
+ \utilitydonetrue \setsystemmode \v!list
+ \fi}
+
+\def\systemsuppliedchapter {\getvalue{\v!chapter}} % brrr
+\def\systemsuppliedtitle {\getvalue{\v!title}} % brrr
+
+\def\dodocompletelist[#1][#2][#3]% enkelvoud, meervoud, instellingen
+ {\normalexpanded{\noexpand\systemsuppliedtitle[#2]{\noexpand\headtext{#2}}}% expansion needed for v! vs french !
+ \doplacelist[#1][#3]}
+
+\def\docompletelist[#1][#2]%
+ {\dodocompletelist[#1][#1][#2]}
+
+\def\completelist
+ {\dodoubleempty\docompletelist}
+
+\def\listelements {} % list of page breaks
+\def\listnumbercommand #1{#1} % no strut due to interactive version
+\def\listtextcommand #1{\begstrut#1\endstrut}
+\def\listpagecommand #1{\strut#1}
+
+\def\doassigndimen#1#2#3%
+ {\doifinsetelse{#2}{\v!fit,\v!broad}{#1=#3}{#1=#2}\relax}
+
+\def\listsymbol[#1]#2%
+ {\begingroup
+ \edef\currentlist{#1}%
+ \edef\currentlistnumber{#2}%
+ \currentlistsymbol
+ \endgroup}
+
+% Beware, the list symbol macro gets an argument passed, i.e. when this
+% argument is not picked up, the symbol becomes a kind of prefix.
+
+% for historical reasons we're stuck to symbols, so in order to generalize,
+% we have to hook it into the symbol handler; we need a beter clean up later
+%
+% < 2005
+%
+% \def\dosetlistsymbol % #1
+% {\executeifdefined{listsymbol@\listparameter\c!symbol}\listsymbol@default} % {#1}
+%
+% >= 2005
+%
+% at this symbol level, we have access to the raw 'number' in
+% \currentlistnumber
+
+\definesymbol[\v!list][\v!none ][\listsymbol@none ]
+\definesymbol[\v!list][\v!one ][\listsymbol@one ]
+\definesymbol[\v!list][\v!two ][\listsymbol@two ]
+\definesymbol[\v!list][\v!three ][\listsymbol@three ]
+\definesymbol[\v!list][\s!default][\listsymbol@default]
+\definesymbol[\v!list][\s!unknown][\listsymbol@unknown]
+
+\def\currentlistsymbol
+ {\doifinsymbolsetelse\v!list{\listparameter\c!symbol}
+ {\directsymbol\v!list{\listparameter\c!symbol}}
+ {\directsymbol\v!list\s!default}}
+
+\def\listsymbol@none
+ {\doassigndimen\scratchdimen{\listparameter\c!width}{1.5em}%
+ \hbox to \scratchdimen{}}
+
+\def\listsymbol@one
+ {\strut$\bullet$}
+
+\def\listsymbol@two
+ {\vrule\!!width1em\!!height1ex\!!depth\zeropoint}
+
+\def\listsymbol@three
+ {\begingroup
+ \doassigndimen{\dimen0}{\listparameter\c!width }{1.5em}%
+ \doassigndimen{\dimen2}{\listparameter\c!height}{1ex}%
+ \doassigndimen{\dimen4}{\listparameter\c!depth }\zeropoint
+ \vrule\!!width\dimen0\!!height\dimen2\!!depth\dimen4%
+ \endgroup}
+
+\def\listsymbol@default
+ {% prefix = no, none, yes
+ \strut
+ \doif{\listparameter\c!label}\v!yes{\leftlabeltext\currentlist}%
+ \currentlistnumber
+ \listparameter\c!stopper
+ \doif{\listparameter\c!label}\v!yes{\rightlabeltext\currentlist}}
+
+\def\listsymbol@default
+ {% todo:
+ % prefix=no (first gone)|none (all gone)|yes
+ % number=no|yes
+ \strut
+ \doifelse{\listparameter\c!label}\v!yes
+ {\leftlabeltext\currentlist
+ \currentlistnumber
+ \listparameter\c!stopper
+ \rightlabeltext\currentlist}
+ {\currentlistnumber
+ \listparameter\c!stopper}}
+
+\def\listsymbol@unknown
+ {\listparameter\c!symbol}
+
+% so far for list symbols
+
+\def\@@dodolistelement{dodolistelement}
+
+\def\dosomelistelement#1#2#3{#1 #2 #3}
+
+\setvalue{\@@dodolistelement a}{\let\dosomelistelement\dodofixdlistelementABC}
+\setvalue{\@@dodolistelement b}{\let\dosomelistelement\dodofixdlistelementABC}
+\setvalue{\@@dodolistelement c}{\let\dosomelistelement\dodofixdlistelementABC}
+\setvalue{\@@dodolistelement d}{\let\dosomelistelement\dodofixdlistelementD}
+\setvalue{\@@dodolistelement e}{\let\dosomelistelement\dodofixdlistelementE}
+\setvalue{\@@dodolistelement f}{\let\dosomelistelement\dodofixdlistelementF}
+\setvalue{\@@dodolistelement g}{\let\dosomelistelement\dodofixdlistelementG}
+
+\setvalue{\@@dodolistelement\v!none }{\def\dosomelistelement{\dodofreevlistelement}}
+\setvalue{\@@dodolistelement\v!vertical }{\def\dosomelistelement{\dodofreevlistelement}}
+\setvalue{\@@dodolistelement\v!horizontal}{\def\dosomelistelement{\dodofreehlistelement}}
+\setvalue{\@@dodolistelement\v!command }{\let\dosomelistelement\dodocommandlistelement}
+
+% \setuplist
+% [section]
+% [alternative=MyListItem,
+% after=\blank,
+% before=\blank]
+%
+% \definelistplacement[MyListItem][none]#1#2#3%
+% {(#1) (#2) (#3)}
+
+\def\definelistplacement
+ {\dodoubleempty\dodefinelistplacement}
+
+\def\dodefinelistplacement[#1][#2]%
+ {\setvalue{\@@dodolistelement#1}%
+ {\doifelsenothing{#2}
+ {\getvalue{\@@dodolistelement\v!command}}%
+ {\executeifdefined{\@@dodolistelement#2}{\getvalue{\@@dodolistelement\v!command}}}%
+ \setvalue{\??li\currentlist\c!command}{\getvalue{\@@dodolistelement::#1}}}%
+ \setvalue{\@@dodolistelement::#1}}
+
+% don't mess arround with endgraf/grouping else we loose leftskip
+
+% \strippedcsname\dodolistelement
+
+\def\newlineinlist{\space}
+
+\let\currentlist\s!unknown
+
+\def\docurrentlistalternative
+ {\edef\currentlistalternative{\listparameter\c!alternative}%
+ \ifx\currentlistalternative\empty
+ [unknown list alternative]%
+ \else
+ \executeifdefined{\@@dodolistelement\currentlistalternative}{[unknown list alternative: \currentlistalternative]}%
+ \fi}
+
+\def\dodolistelement#1#2#3#4#5#6%
+ {\edef\currentlist{#1}%
+ \edef\currentlistnumber{#3}%
+ \docurrentlistalternative
+ %\showcomposition
+ \let\@@iawidth\!!zeropoint % moet boolean worden
+ \begingroup
+ \edef\listelements{\listparameter\c!pageboundaries}%
+ \normalexpanded{\noexpand\doifinset{#3}{\listelements}}
+ {\showmessage\m!systems{14}{#3}%
+ \page}%
+ \endgroup
+ \dontcomplain
+ %\setfullsectionnumber{\??li\currentlist}% todo
+ \dosomelistelement{#1}{#2}{#3}{#4}{#5}{#6}%
+ \global\utilitydonetrue} % ?
+
+\def\dodocommandlistelement#1#2#3#4#5#6%
+ {\doifdefinedelse{\??li#1\c!command}
+ {\listparameter\c!command{#3}{#4}{#5}}
+ {[\currentlist: #3 -- #4 -- #5]}}
+
+\def\dodofreelistelement#1#2#3#4#5#6#7#8%
+ {\def\makelistelement##1##2%
+ {\noindent % new and needed
+ \hbox
+ {\doifelse{\listparameter\c!interaction}{##1} % \??li ipv \??ia
+ {\setbox0\hbox{\showcontrastlocation{\??li\currentlist}{#6}{##2}}%
+ \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}%
+ {##2}}}%
+ \listparameter\c!before% can be \hskip
+ \doifdefinedelse{\??li#1\c!command}
+ {\makelistelement{\listparameter\c!interaction}% this forces all
+ {\listparameter\c!command
+ {#3}% geen conversies etc
+ {#4}% geen conversies etc
+ {#5}}}% geen command
+ {#7%
+ \vbox
+ {\forgetall
+ \makelistelement\v!all
+ {\doif{\listparameter\c!headnumber}\v!yes
+ {\makelistelement\v!sectionnumber
+ {\donestedlistattributes\c!numberstyle\c!numbercolor
+ {\listparameter\c!numbercommand{\currentlistsymbol}}}}%
+ \makelistelement\v!text
+ {\donestedlistattributes\c!textstyle\c!textcolor
+ {\let\\=\newlineinlist
+ \dontconvertfont
+ \listparameter\c!textcommand{#4}}}%
+ \doif{\listparameter\c!pagenumber}\v!yes
+ {\doifsomething{#5}
+ {\makelistelement\v!pagenumber
+ {\donestedlistattributes\c!pagestyle\c!pagecolor
+ {\listparameter\c!pagecommand{#5}}}}}}}%
+ #8}%
+ \listparameter\c!after}
+
+\def\dodofreehlistelement#1#2#3#4#5#6%
+ {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6}
+ {\noindent}{}}
+
+\def\dodofreevlistelement#1#2#3#4#5#6% % \nointerlineskip needed,
+ {\dodofreelistelement{#1}{#2}{#3}{#4}{#5}{#6} % otherwise wrong spacing
+ {\ifvmode\nointerlineskip\fi} % at multi-line lists
+ {\ifvmode\nointerlineskip\fi\endgraf\allowbreak}} % test is saveguard
+
+% to be documented: align, hang
+
+\def\limitatedlistentry#1%
+ {\doifelsenothing{\listparameter\c!maxwidth}
+ {\listparameter\c!textcommand{#1}}
+ {\listparameter\c!textcommand
+ {\limitatetext
+ {#1}%
+ {\listparameter\c!maxwidth}%
+ {\splitsymbol{\listparameter\c!limittext}}}}}
+
+\def\dodofixdlistelementABC#1#2#3#4#5#6% weeden
+ {\endgraf
+ \leftskip\listparameter\c!margin% na de \endgraf !
+ \listparameter\c!before
+ \!!widthc\listparameter\c!distance
+ \doifelse{\listparameter\c!width}\v!fit
+ {\!!widtha\zeropoint}
+ {\doifelsenothing{#3}
+ {\doifelse{\listparameter\c!aligntitle}\v!yes
+ {\!!widtha\zeropoint
+ \!!widthc\zeropoint}
+ {\!!widtha\listparameter\c!width}}
+ {\!!widtha\listparameter\c!width}}%
+ \getvalue{\??li\c!alternative\listparameter\c!alternative}%
+ \endgraf
+ \def\makelistelement##1##2%
+ {\doifelse{\listparameter\c!interaction}{##1}
+ {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}%
+ \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}%
+ {\hbox{##2}}}%
+ \doif{\listparameter\c!interaction}\v!text % not supported ! ! ! ! ! ! text == all
+ {\setlistparameter\currentlist\c!interaction\v!all}%
+ % \dontleavehmode % new, else no margin, but wrong, better (else \indent as well):
+ \noindent
+ \makelistelement\v!all
+ {\setlocalhsize
+ \hsize\localhsize
+ \hbox to \hsize
+ {\forgetall
+ \dosetlistattributes\c!style\c!color
+ \!!widthb\hsize
+ \doifelse{\listparameter\c!headnumber}\v!yes
+ {\setbox2\hbox \ifdim\!!widtha>\zeropoint to \!!widtha \fi
+ {\makelistelement\v!sectionnumber
+ {\donestedlistattributes\c!numberstyle\c!numbercolor
+ {\listparameter\c!numbercommand{\currentlistsymbol}}%
+ \hfill}}}
+ {\!!widtha\zeropoint
+ \!!widthc\zeropoint
+ \setbox2\hbox{}}%
+ \setbox4\hbox
+ {\doif{\listparameter\c!pagenumber}\v!yes
+ {\doifsomething{#5} % \listwidth is new ; temp hack
+ {\hbox \ifdim\listwidth>\zeropoint to \listwidth\fi
+ {\hfill
+ \makelistelement\v!pagenumber
+ {\donestedlistattributes\c!pagestyle\c!pagecolor
+ {\listparameter\c!pagecommand{#5}}}}}}}%
+ \vbox
+ {\hsize\!!widthb
+ \setupalign[\listparameter\c!align]%
+ \ifdim\!!widtha<\hsize
+ \hangindent\wd2
+ \dimen2=\!!widthc % \listparameter\c!distance
+ \advance\hangindent \dimen2
+ \hangafter\plusone
+ \doif{\listparameter\c!hang}\v!no{\hangafter\zerocount}%
+ \ifdim\wd4=\zeropoint % \ifvoid4
+ % we kunnen gewoon afbreken aan het eind
+ \else
+ \ifdim\listskip>\zeropoint\relax
+ \rightskip\listskip\!!plus\liststretch\relax
+ \parfillskip-\rightskip
+ \fi
+ \fi
+ \else
+ \dimen2\zeropoint
+ \fi
+ \parindent\zeropoint\relax
+ \leavevmode
+ \box2\relax
+ \hskip\dimen2
+ \bgroup
+ \donestedlistattributes\c!textstyle\c!textcolor
+ {\let\\=\newlineinlist
+ \dontconvertfont
+ %\listparameter\c!textcommand{#4}}%
+ \limitatedlistentry{#4}}%
+ %\carryoverpar % new otherwise wrong linespacing
+ \egroup
+ \ifdim\wd4=\zeropoint\relax % \ifvoid4
+ % \ifdim\!!widtha<\hsize \hfill\strut \fi % spoils align
+ \else
+ \nobreak\listfill
+ \box4\relax
+ \relax
+ \fi}%
+ \hss}}% new
+ \endgraf % new, else problems with nointerlinespace and prevdepth
+ \nointerlineskip % anders verkeerde spatiering bij multi-line
+ \endgraf
+ \allowbreak
+ \listparameter\c!after}
+
+% % example from the context list
+%
+% \setuphead [part] [page=right,placehead=yes]
+% \setuplist [chapter] [alternative=d,before=\blank,after=\blank]
+% \setuplist [part] [before=\blank,after=\blank]
+%
+% \starttext
+% \startnarrower[2*right] \placecontent \stopnarrower
+% \blank[4*big]
+% \startsetups chapter
+% \blank \startnarrower[3*middle] \placecontent[criterium=local] \stopnarrower
+% \stopsetups
+% \placelist[part][criterium=text,after=\setups{chapter}]
+%
+% \part{First part} \chapter{Chapter one} \chapter{Chapter two}
+% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
+% \part{Second part} \chapter{Chapter one} \chapter{Chapter two}
+% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
+% \part{Third part} \chapter{Chapter one} \chapter{Chapter two}
+% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
+% \stoptext
+
+% overrulen interactie kan sneller, bv door hulpconstanten
+% te gebruiken en die te letten
+
+\def\dodofixdlistelementD#1#2#3#4#5#6%
+ {%\leftskip=\listparameter\c!margin
+ \ifvmode
+ \advance\leftskip\listparameter\c!margin% AANGEPAST
+ \fi
+ \bgroup
+ \ifvmode
+ \noindent\leavevmode % leavevmode ? ? ?
+ \fi
+ \doif{\listparameter\c!interaction}\v!text % not supported
+ {\setlistparameter\currentlist\c!interaction\v!sectionnumber}%
+ \doif{\listparameter\c!interaction}\v!all % not supported
+ {\setlistparameter\currentlist\c!interaction\v!sectionnumber}%
+ \def\makelistelement##1##2%
+ {\doifelse{\listparameter\c!interaction}{##1}
+ {\setbox0\hbox{\showcontrastlocation\??ia{#6}{##2}}%
+ \linklisttoelement{#2}{#5}{#6}{\box0}}%{\copy0}}%
+ {\hbox{##2}}}%
+ \setbox4\hbox
+ {\doif{\listparameter\c!pagenumber}\v!yes
+ {\doifsomething{#5}
+ {\makelistelement\v!pagenumber
+ {\donestedlistattributes\c!pagestyle\c!pagecolor
+ {\listparameter\c!pagecommand{#5}}}}}}%
+ \doif{\listparameter\c!headnumber}\v!yes
+ {\donetrue
+ \doifnothing{#3}{\doifnothing{\listparameter\c!symbol}\donefalse}%
+ % == \doifnothing{#3\listparameter\c!symbol}\donefalse
+ \ifdone
+ \hbox
+ {\listparameter\c!left
+ \makelistelement\v!sectionnumber
+ {\donestedlistattributes\c!numberstyle\c!numbercolor
+ {\listparameter\c!numbercommand{\currentlistsymbol}}}%
+ \listparameter\c!right
+ \hskip.5em}%
+ \nobreak
+ \fi}%
+ \tolerance3500 % niet zomaar veranderen
+ \donestedlistattributes\c!textstyle\c!textcolor
+ {\let\\=\newlineinlist
+ \dontconvertfont
+ %\listparameter\c!textcommand{#4}}%
+ \limitatedlistentry{#4}}%
+ \ifvoid4\else
+ \nobreak
+ \hskip.75em\relax
+ \nobreak
+ \box4
+ \fi
+ \dimen0=\listparameter\c!distance\relax
+ \ifdim\dimen0<1em\relax
+ \hskip1em\!!plus1em\!!minus.25em\relax
+ \else
+ \hskip\dimen0\!!plus.5\dimen0\!!minus.25\dimen0\relax
+ \fi
+ \egroup}
+
+\def\dodofixdlistelementE#1%
+ {\dodofixdlistelementEFG
+ {\setupinteraction[\c!strut=\v!no]}
+ {\localframed[\??li\currentlist][\c!depth=\!!zeropoint,\c!color=]}
+ {}}
+
+\def\dodofixdlistelementF#1%
+ {\dodofixdlistelementEFG
+ {}
+ {\dosetraggedhbox{\listparameter\c!align}\raggedbox}
+ {}}
+
+\def\dodofixdlistelementG#1%
+ {\dodofixdlistelementEFG
+ {}
+ \midaligned
+ {}}
+
+\def\dodofixdlistelementEFG#1#2#3#4#5#6#7#8%
+ {\noindent
+ \bgroup
+ \def\makelistelement##1##2% isolated by Wolfgang Schuster
+ {\doifelse{\listparameter\c!interaction}{##1}
+ {#2{##2}}
+ {\setbox0\hbox{#2{\showcontrastlocation\??ia{#8}{##2}}}%
+ \linklisttoelement{#4}{#7}{#8}{\box0}}}%
+ \makelistelement\v!no
+ {\let\\=\newlineinlist
+ #1% in case E nils the strut (still needed?)
+ \dosetlistattributes\c!style\c!color
+ \ignorespaces\dontconvertfont\setstrut
+ \begstrut
+ \limitatedlistentry{#6}%
+ \endstrut}%
+ \egroup
+ \par
+ \listparameter\c!inbetween}
+
+\def\listlength{\utilitylistlength}
+\def\listwidth {\utilitylistwidth}
+\def\listheight{\utilitylistheight}
+
+\def\utilitylistlength {0}
+\def\utilitylistwidth {0pt} % no longer supported
+\def\utilitylistheight {0pt} % no longer supported
+
+\def\dodeterminelistcharacteristics[#1][#2]%
+ {\begingroup
+ \dosetuplist[#1][#2]%
+ \edef\currentlist{\firststructureelementinlist{#1}}%
+ \the\everystructurelist
+ \analysestructurelist{#1}{\listparameter\c!criterium}{\listparameter\c!number}%
+ \xdef\utilitylistlength{\structurelistsize}%
+ \endgroup
+ \dosetlistmode}
+
+\def\determinelistcharacteristics
+ {\dodoubleempty\dodeterminelistcharacteristics}
+
+\def\combinedlistparameter#1{\csname\??ih\currentcombinedlist#1\endcsname}
+
+\def\setupcombinedlist
+ {\dodoubleargument\dosetupcombinedlist}
+
+\def\dosetupcombinedlist[#1][#2]%
+ {\getparameters[\??ih#1][#2]%
+ \edef\currentcombinedlist{#1}%
+ \normalexpanded{\noexpand\setuplist[\combinedlistparameter\c!list]}[#2]}
+
+\def\definecombinedlist
+ {\dotripleempty\dodefinecombinedlist}
+
+\def\dodefinecombinedlist[#1][#2][#3]%
+ {\getparameters
+ [\??ih#1]
+ [\c!criterium=\v!local,\c!number=0,\c!list={#2},#3]%
+ \setvalue{\e!setup#1\e!endsetup}{\dodoubleempty\dosetupcombinedlist[#1]}%
+ \setvalue{\e!place#1}{\dodoubleempty\doplacecombinedlist[#1]}%
+ \setvalue{\e!complete#1}{\dodoubleempty\docompletecombinedlist[#1]}}
+
+\def\placecombinedlist
+ {\dodoubleempty\doplacecombinedlist}
+
+\def\doplacecombinedlist[#1][#2]% we can move much of the analysis to lua
+ {\begingroup
+ % level is no longer supported
+ \def\currentcombinedlist{#1}%
+ \getparameters[\??ih#1][#2]%
+ \edef\combinedlist{\combinedlistparameter\c!list}%
+ \the\everystructurelist
+ \doif{\combinedlistparameter\c!coupling}\v!on{\startlistreferences{#1}}%
+ \dobeginoflist
+ \normalexpanded{\noexpand\dosetuplist[\combinedlist][#2]}%
+ \placestructurelist{\combinedlist}{\combinedlistparameter\c!criterium}{\combinedlistparameter\c!number}%
+ \doendoflist
+ \stoplistreferences
+ \endgroup
+ \dosetlistmode}
+
+\def\docompletecombinedlist[#1][#2]%
+ {\normalexpanded{\noexpand\systemsuppliedtitle[#1]{\noexpand\headtext{#1}}}% expansion due to v! vs french !
+ \doplacecombinedlist[#1][#2]}
+
+% lists that have a number/title are kind of generic and can share code
+
+\installstructurelistprocessor{number+title}
+ {\dodolistelement
+ \currentlist
+ \structurelistlocation
+ \structurelistgenericnumber
+ \structurelistgenerictitle
+ \structurelistpagenumber
+ \structurelistrealpagenumber}
+
+\def\structurelistgenerictitle
+ {\ctxlua{structure.lists.title("\currentlist",\currentlistindex)}}
+
+\def\structurelistgenericnumber{\ctxlua{
+ structure.lists.prefixednumber("\currentlist",\currentlistindex, {
+ prefix = "\listparameter\c!prefix",
+ separatorset = "\listparameter\c!prefixseparatorset",
+ conversionset = "\listparameter\c!prefixconversionset",
+ stopper = \!!bs\listparameter\c!prefixstopper\!!es,
+ set = "\listparameter\c!prefixset",
+ segments = "\listparameter\c!prefixsegments",
+ connector = \!!bs\listparameter\c!prefixconnector\!!es,
+ },
+ {
+ separatorset = "\listparameter\c!numberseparatorset",
+ conversionset = "\listparameter\c!numberconversionset",
+ stopper = \!!bs\listparameter\c!numberstopper\!!es,
+ segments = "\listparameter\c!numbersegments",
+ } )}}
+
+% new and yet undocumented (used in cocoa qa), temporarily disabled in mkiv
+%
+% \setupremaininglistlength
+% [left=\hss nog~,right=~ingangen]
+%
+% \resetremaininglistlength
+% [section][settings]
+%
+% \placelist
+% [section]
+% [before=\showremaininglistlength]
+%
+% \dorecurse{100}{\section{hans}}
+%
+% \definesystemvariable {ll} % ListLength
+%
+% \def\setupremaininglistlength[#1]%
+% {\getparameters[\??ll][#1]%
+% \globallet\listlengthcounter\!!zerocount}
+%
+% \setupremaininglistlength
+% [\c!left=\hss,\c!right=,\c!number=\v!yes,
+% \c!before=\blank,\c!after=\page,
+% \c!style=\v!smallnormal,\c!color=]
+%
+% \def\resetremaininglistlength
+% {\dodoubleempty\doresetremaininglistlength}
+%
+% \def\doresetremaininglistlength[#1][#2]%
+% {\determinelistcharacteristics[#1][#2]%
+% \xdef\listlengthcounter{\number\utilitylistlength}}
+%
+% \def\showremaininglistlength
+% {\bgroup
+% \ifnum\listlengthcounter>\plusone
+% \setbox\scratchbox\vbox
+% {\@@llbefore\par\horizontalstrut\par\horizontalstrut\par\@@llafter}%
+% \scratchdimen\pagetotal
+% \advance\scratchdimen \ht\scratchbox
+% \advance\scratchdimen \dp\scratchbox
+% \ifdim\scratchdimen>\pagegoal
+% \@@llbefore
+% \nobreak\hbox to \hsize
+% {\doifnot\@@llnumber\v!yes{\let\listlengthcounter\empty}%
+% \doattributes\??ll\c!style\c!color{\@@llleft\listlengthcounter\@@llright}}
+% \@@llafter
+% \fi
+% \fi
+% \doglobal\decrement\listlengthcounter\relax
+% \egroup}
+
+\protect \endinput
diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua
new file mode 100644
index 000000000..14eac8c2c
--- /dev/null
+++ b/tex/context/base/strc-mar.lua
@@ -0,0 +1,18 @@
+if not modules then modules = { } end modules ['strc-mar'] = {
+ version = 1.001,
+ comment = "companion to strc-mar.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+structure.marks = structure.marks or { }
+
+function structure.marks.title(tag,n)
+ structure.lists.savedtitle(tag,n,"mark")
+end
+
+function structure.marks.number(tag,n) -- no spec
+ -- no prefix (as it is the prefix)
+ structure.lists.savednumber(tag,n)
+end
diff --git a/tex/context/base/strc-mar.tex b/tex/context/base/strc-mar.tex
new file mode 100644
index 000000000..8dbbb232c
--- /dev/null
+++ b/tex/context/base/strc-mar.tex
@@ -0,0 +1,493 @@
+%D \module
+%D [ file=strc-mar,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Markings,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Markings}
+
+\registerctxluafile{strc-mar}{1.001}
+
+\unprotect
+
+%D Old stuff.
+
+\newtoks \listofmarks
+
+\let \getmarks \gobbleoneargument
+\let \getallmarks \relax
+\let \getsplitmarks \gobbleoneargument
+\let \getallsplitmarks \relax
+
+%D \macros
+%D {expandmarks}
+%D
+%D We can force expansion of marks with the following switch.
+
+% Synchronizing marks is a rather tricky and messy business. When
+% setting a mark, a node is added to the list in order for to \TEX\
+% be able to figure out the 3 current marks when a page is made
+% (last mark on previous page, first on current page, last on
+% current page; in \LUATEX\ we might at one point have the first on
+% the next page as well).
+
+% Resetting a mark is not easy. An empty one will not erase the last
+% one on the previous page for instance. In \LUATEX\ we can clear a
+% marks state register with \type {\clearmarks} but since this is an
+% immediate operation it might have unwanted side effects when \TEX\
+% has collected several pages of text and finishing off these pages
+% uses marks.
+
+% In \MKIV\ we provide a model that permits some control over the
+% way marks are used. It is not entirely compatible with \MKII\ but
+% in practice this is not a real problem. Quality has a price.
+
+% In fact we define multiple marks per visible mark and define
+% additional ones on the fly. This has some price in terms of used
+% mark registers but given the way that we fill marks in \MKIV\
+% their accumulated content is not really the issue. Also,
+% periodically we cleanup any leftovers.
+
+\newif\ifexpandmarks \expandmarkstrue
+
+\def\marksomecs #1#2{\csname\string#1:m:\number#2\endcsname}
+\def\markautocs #1{\csname\string#1:m:\number\csname\string#1:s\endcsname\endcsname}
+\def\markmaincs #1{\csname\string#1:m\endcsname}
+\def\markresetcs #1{\csname\string#1:r\endcsname}
+\def\markstatecs #1{\csname\string#1:s\endcsname}
+\def\markcurrentcs#1{\csname\string#1:c\endcsname}
+\def\marktokscs #1{\csname\string#1:t\endcsname}
+
+\def\renewmarks#1%
+ {\ifx#1\relax
+ % \writestatus\m!systems{defining low level mark: \string#1}%
+ \newmarks#1%
+ \else
+ \clearmarks#1%
+ \fi}
+
+\def\definenewmark#1%
+ {\ifcsname\string#1:m\endcsname\else
+ \@EA\@EA\@EA\newcount \markstatecs #1\global\markstatecs#1\plusone
+ \@EA\@EA\@EA\renewmarks\markautocs #1%
+ \@EA\@EA\@EA\renewmarks\markmaincs #1%
+ \@EA\@EA\@EA\renewmarks\markresetcs #1%
+ \@EA\@EA\@EA\newtoks \marktokscs #1%
+ \@EA\@EA\@EA\let \markcurrentcs#1\empty
+ \listofmarks\expandafter{\the\listofmarks\checkmark#1}%
+ \fi}
+
+\long\def\setmark#1#2% marks expand
+ {\@EA\@EA\@EA\xdef \markcurrentcs#1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}%
+ \marks\markautocs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level
+ \marks\markmaincs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level
+ \marks\markresetcs #1{\number\markstatecs#1}}
+
+\def\resetmark#1%
+ {\global\advance\markstatecs#1\plusone
+ \@EA\@EA\@EA\glet\markcurrentcs#1\empty
+ \@EA\@EA\@EA\renewmarks\markautocs#1%
+ \the\marktokscs#1\relax}
+
+\def\addmarkreset#1#2%
+ {\global\marktokscs#2\@EA{\the\marktokscs#2\resetmark#1}}
+
+% already there: \prependtoks \getallmarks \to \everybeforepagebody
+%
+% \def\getallmarks{\the\listofmarks}
+
+\let\checkmark\gobbleoneargument
+
+\prependtoks \clearmarkswhenemptypage \to \everybeforepagebody
+
+\def\clearmarkswhenemptypage
+ {\iffalse % check if page is empty
+ \clearallmarks
+ \fi}
+
+\def\clearallmarks
+ {\let\checkmark\clearmarkchain
+ \the\listofmarks
+ \let\checkmark\gobbleoneargument}
+
+\def\clearmarkchain#1%
+ {\@EA\@EA\@EA\clearmarks\markmaincs#1%
+ \@EA\@EA\@EA\clearmarks\markresetcs#1%
+ \@EA\doclearmarkchain\@EA{\number\csname\string#1:s\endcsname}#1%
+ \@EA\@EA\@EA\glet\markcurrentcs#1\empty
+ \global\markstatecs#1\plusone}
+
+\def\doclearmarkchain#1#2%
+ {\@EA\@EA\@EA\clearmarks\marksomecs#1{#2}%
+ \@EA\doclearmarkchain\@EA#1\@EA{\number\numexpr#2+\minusone}}
+
+% Fetching (expandable versions, so no intermediate counter):
+
+\def\currenttopmarknumber #1{\number0\topmarks \markresetcs#1}
+\def\currentfirstmarknumber#1{\number0\firstmarks\markresetcs#1}
+\def\currentbotmarknumber #1{\number0\botmarks \markresetcs#1}
+
+\def\checkedcurrentmarkrange#1{[\currenttopmarknumber#1,\currentfirstmarknumber#1,\currentbotmarknumber#1]}
+
+\def\checkedcurrentmarks{\markcurrentcs} % #1 shared current mark
+
+\let\currentsplittopmarknumber\currenttopmarknumber
+\let\normalsplittopmarks \normaltopmarks
+
+\def\uncheckedautotopmark {\normaltopmarks \markautocs} % #1
+\def\uncheckedautofirstmark {\normalfirstmarks \markautocs} % #1
+\def\uncheckedautobotmark {\normalbotmarks \markautocs} % #1
+\def\uncheckedautosplittopmark {\normalsplittopmarks \markautocs} % #1
+\def\uncheckedautosplitfirstmark {\normalsplitfirstmarks\markautocs} % #1
+\def\uncheckedautosplitbotmark {\normalsplitbotmarks \markautocs} % #1
+
+\def\uncheckedmaintopmark {\normaltopmarks \markmaincs} % #1
+\def\uncheckedmainfirstmark {\normalfirstmarks \markmaincs} % #1
+\def\uncheckedmainbotmark {\normalbotmarks \markmaincs} % #1
+\def\uncheckedmainsplittopmark {\normalsplittopmarks \markmaincs} % #1
+\def\uncheckedmainsplitfirstmark {\normalsplitfirstmarks\markmaincs} % #1
+\def\uncheckedmainsplitbotmark {\normalsplitbotmarks \markmaincs} % #1
+
+\def\checkedpagetopmarks #1{\ifcase\currentbotmarknumber #1\else\normaltopmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedpagefirstmarks #1{\ifcase\currentbotmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedpagebotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedpagesplittopmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+\def\checkedpagesplitfirstmarks#1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+\def\checkedpagesplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+
+\def\checkedfulltopmarks #1{\ifcase\currenttopmarknumber #1\else\normaltopmarks \marksomecs#1{\currenttopmarknumber #1}\fi}
+\def\checkedfullfirstmarks #1{\ifcase\currentfirstmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentfirstmarknumber #1}\fi}
+\def\checkedfullbotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedfullsplittopmarks #1{\ifcase\currentsplittopmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplittopmarknumber #1}\fi}
+\def\checkedfullsplitfirstmarks#1{\ifcase\currentsplitfirstmarknumber#1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitfirstmarknumber#1}\fi}
+\def\checkedfullsplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+
+% Interface macros:
+
+\def\getcurrentmark {\checkedcurrentmarks }
+\def\gettopmark {\checkedfulltopmarks }
+\def\getfirstmark {\checkedfullfirstmarks }
+\def\getbotmark {\checkedfullbotmarks }
+\def\getsplittopmark {\checkedfullsplittopmarks }
+\def\getsplitfirstmark {\checkedfullsplitfirstmarks}
+\def\getsplitbotmark {\checkedfullsplitbotmarks }
+
+\def\getbottommark {\getbotmark}
+\def\getsplitbottommark{\getsplitbotmark}
+
+%D Some of these will go away (in the process of rewriting).
+
+\let \newmark \definenewmark
+\let \newpersistentmark \newmarks
+\let \normalsetmark \setmark
+\let \rawnewmark \newmarks
+\let \rawdefinemark \newmarks
+\let \rawsetmark \normalmarks
+\let \rawgettopmark \normaltopmarks
+\let \rawgetfirstmark \normalfirstmarks
+\let \rawgetbotmark \normalbotmarks
+\let \rawgetsplitbotmark \normalsplitbotmarks
+\let \rawgetsplitfirstmark \normalsplitfirstmarks
+\let \rawgetsplittopmark \normalsplitfirstmarks
+
+\let \noninterferingmarks \relax % old color interference related hack
+
+%D Next comes the layer around the previous mechanism.
+%D
+%D Parameters
+
+\def\markingparameter #1#2{\csname\domarkingparameter{\??mk#1}#2\endcsname}
+\def\domarkingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\@EA\domarkingparentparameter\csname#1\s!parent\endcsname#2\fi}
+\def\domarkingparentparameter#1#2{\ifx#1\relax\s!empty\else\domarkingparameter#1#2\fi}
+\def\markingcoupling #1{\ifcsname\??mk#1\c!coupling\endcsname\@EA\markingcoupling\csname\??mk#1\c!coupling\endcsname\else#1\fi}
+
+\let\mainmarking\markingcoupling % compatibility
+
+\def\doifelsemarking#1%
+ {\ifcsname\??mk#1\c!coupling\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\dowithmarkcommandone#1#2% \command {mark}
+ {\expandafter#1\csname\??mk:\markingcoupling{#2}\endcsname}
+
+\def\dowithmarkcommandtwo#1#2#3% \command {mark} {mark}
+ {\expandafter#1\csname\??mk:\markingcoupling{#2}\expandafter\endcsname\csname\??mk:\markingcoupling{#3}\endcsname}
+
+\def\setupmarking
+ {\dodoubleargument\dosetupmarking}
+
+\def\dosetupmarking[#1][#2]%
+ {\def\docommand##1{\getparameters[\??mk##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+%D The filtercommand key is used to hook in a filtering command. Users are
+%D adviced not to misuse this key.
+
+\getparameters
+ [\??mk]
+ [\c!expansion=\v!no, % saves a macro
+ \c!separator={\space\emdash\space},
+ \c!limittext=\@@kolimittext,
+ \c!filtercommand=\firstofoneargument,
+ \c!state=\v!start]
+
+\let\alldefinedmarks\empty
+
+\def\definemarking
+ {\dodoubleempty\dodefinemarking}
+
+\def\dodefinemarking[#1][#2]%
+ {\doifelsenothing{#2}\donormaldefinemarking\docloneddefinemarking[#1][#2]}
+
+\def\donormaldefinemarking[#1][#2]% #2 empty
+ {\ifcsname\??mk#1\s!parent\endcsname
+ % already defined
+ \else
+ \letgvalue{\??mk#1\s!parent}\??mk
+ \dowithmarkcommandone\newmark{#1}%
+ \doglobal\addtocommalist{#2}\alldefinedmarks
+ \ifproductionrun\showmessage\m!systems{13}{#1,[#1]}\fi
+ \fi}
+
+\def\docloneddefinemarking[#1][#2]%
+ {\ifcsname\??mk#1\s!parent\endcsname \else \ifcsname\??mk#2\s!parent\endcsname
+ \doifnot{#1}{#2}%
+ {\setxvalue{\??mk#1\s!parent}{\??mk#2}%
+ \setxvalue{\??mk#1\c!coupling}{#2}%
+ \ifproductionrun\showmessage\m!systems{13}{#1,[#2]}\fi}%
+ \fi \fi}
+
+\def\decouplemarking[#1]%
+ {\letbeundefined{\??mk#1\c!coupling}}
+
+\def\couplemarking[#1]#2[#3]% couple 1 to 2 (this macro is not really needed)
+ {\setvalue{\??mk#1\c!coupling}{#3}}
+
+\def\relatemarking[#1]#2[#3]% define 1 as child of 2
+ {\dowithmarkcommandtwo\addmarkreset{#1}{#3}}
+
+\def\definerawmarking[#1]%
+ {\dododefinemarking[#1][#1]%
+ \getgparameters[\??mk#1][\c!limittext=]} % global !
+
+% \decouplemarking[#1]% % no coupling with sections
+
+\def\fastresetmarker#1%
+ {\ifcsname\??mk#1\s!parent\endcsname
+ \dowithmarkcommandone\resetmark{#1}%
+ \fi}
+
+\def\fastresetmarkerlist[#1]%
+ {\normalexpanded{\noexpand\rawprocesscommalist[#1]}\fastresetmarker}
+
+\def\resetmarking
+ {\dosingleargument\doresetmarking}
+
+\def\doresetmarking[#1]%
+ {\processcommalist[#1]\fastresetmarker}
+
+%D Used elsewhere:
+
+\let\nomarking\empty
+
+%D Basic fetching:
+
+\letvalue{\??mk::\??mk::\v!previous}\firstoffourarguments
+\letvalue{\??mk::\??mk::\v!first }\secondoffourarguments
+\letvalue{\??mk::\??mk::\v!last }\thirdoffourarguments
+\letvalue{\??mk::\??mk::\v!current }\fourthoffourarguments
+
+\letvalue{\??mk\??mk\v!previous}\gettopmark
+\letvalue{\??mk\??mk\v!first }\getfirstmark
+\letvalue{\??mk\??mk\v!last }\getbotmark
+\letvalue{\??mk\??mk\v!current }\getcurrentmark
+
+\letvalue{\??mk\??mk\v!column:\v!first}\getsplitfirstmark
+\letvalue{\??mk\??mk\v!column:\v!last }\getsplitbottommark
+
+\def\fetchmark[#1]#2[#3]% % expandable / never use \unexpanded
+ {\ifcsname\??mk::#1\endcsname % saved mark
+ \markingparameter{#1}\c!filtercommand{\csname\??mk::\??mk::#3\@EA\@EA\@EA\endcsname\csname\??mk::#1\endcsname}%
+ \else\ifcsname\??mk#1\s!parent\endcsname % real mark
+ \markingparameter{#1}\c!filtercommand{\expandafter\dowithmarkcommandone\csname\??mk\??mk#3\endcsname{#1}}%
+ \fi\fi}
+
+\def\fetchtwomarks[#1]%
+ {\dofetchtwomarks[#1][#1]}
+
+\def\fetchallmarks[#1]%
+ {\dofetchallmarks[#1][#1]}
+
+\def\dofetchtwomarks[#1][#2]% class class:tag
+ {\doifsomething{\fetchmark[#2][\v!first]}
+ {\fetchmark[#2][\v!first]%
+ \doifsomething{\fetchmark[#2][\v!last]}
+ {\doifnot{\fetchmark[#2][\v!first]}{\fetchmark[#2][\v!last]}
+ {\markingparameter{#1}\c!separator\fetchmark[#2][\v!last]}}}}
+
+\def\dofetchallmarks[#1][#2]%
+ {\doifsomething{\fetchmark[#2][\v!first]}
+ {\doifsomething{\fetchmark[#2][\v!previous]}
+ {\doifnot{\fetchmark[#2][\v!previous]}{\fetchmark[#2][\v!first]}
+ {\fetchmark[#2][\v!previous]\markingparameter{#1}\c!separator}}}%
+ \fetchtwomarks[#1][#2]}
+
+% \newtoks \everymarking
+
+% \def\Interesting{\doifmodeelse{*\v!marking}{Interesting}{Boring}}
+% \setupheadertexts[chapter]
+% \starttext
+% \chapter{This Is \Interesting}
+% \stoptext
+
+\def\markingnomarking#1{\splitsequence{\markingparameter{#1}\c!limittext}} % #2
+
+\def\dogetmarking[#1][#2][#3]%
+ {\doif{\markingparameter{#1}\c!state}\v!start
+ {\bgroup
+ \setsystemmode\v!marking
+ \the\everymarking
+ \def\nomarking{\markingnomarking{#1}}% just for good old times, might disappear
+ \ifthirdargument
+ \dodogetmarking{#3}{#1}{#1:#2}{#3}%
+ \else
+ \dodogetmarking{#2}{#1}{#1}{#2}%
+ \fi
+ \egroup}}
+
+\def\dodogetmarking#1#2#3#4% to be made faster
+ {\processaction % slow
+ [#1]
+ [ \v!both=>{\dofetchtwomarks[#2][#3]},
+ \v!all=>{\dofetchallmarks[#2][#3]},
+ \s!default=>{\fetchmark[#3][\v!first]},
+ \s!unknown=>{\fetchmark[#3][#4]}]}
+
+\def\nogetmarking[#1][#2][#3]%
+ {}
+
+\unexpanded\def\getmarking
+ {\dotripleargument\dogetmarking}
+
+\let\setsomemark\setmark
+
+\def\setmarking
+ {\dosingleargument\dosetmarking}
+
+\def\dosetmarking[#1]#2%
+ {\ifcsname\??mk#1\s!parent\endcsname
+ \begingroup
+ \doifelse{\markingparameter{#1}\c!expansion}\v!yes\expandmarkstrue\expandmarksfalse
+ \dowithmarkcommandone\setsomemark{#1}{#2}%
+ \endgroup
+ \fi}
+
+\let\marking\setmarking
+
+% to be adapted for mkiv:
+%
+% this version can be used when a page is built up in steps without
+% feedback of the otr'd list to the mvl (i.e.\ a page made of pages,
+% as in column sets where content is buffered)
+
+% reset at begin
+% preset before page
+% bubble in column
+% refresh at end
+
+% marks is a kind of toks, so maybe we need a low level \the\marks
+%
+% use \normalunexpanded here
+
+\def\refreshsavedmark[#1][#2]% mark tag (packing saves many hash entries)
+ {\setxvalue{\??mk::#1:#2}%
+ {{\@EA\ifx\csname\??mk::#1:pp\endcsname\relax
+ % empty
+ \else
+ \csname\??mk::#1:pp\endcsname
+ \fi}%
+ {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax
+ \fetchmark[#1][\v!first]%
+ \else
+ \csname\??mk::#1:ff\endcsname
+ \fi}%
+ {\fetchmark[#1][\v!last]}%
+ {\fetchmark[#1][\v!current]}}%
+ \setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!first]}%
+ \letgvalue{\??mk::#1:ff}\relax
+ }
+
+\def\bubblesavedmark[#1][#2]% no packing (not now, maybe make a six-pack later)
+ {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax
+ \setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}%
+ \fi}
+
+\def\resetsavedmark[#1][#2]% mark tag
+ {\doifelsenothing{\fetchmark[#1][\v!previous]}
+ {\letgvalue{\??mk::#1:pp}\relax}
+ {\setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!previous]}}%
+ \doifelsenothing{\fetchmark[#1][\v!first]}
+ {\letgvalue{\??mk::#1:ff}\relax}
+ {\setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}}%
+ \letgvalue{\??mk::#1:#2}\emptysavedmark}
+
+\def\presetsavedmark[#1][#2]% mark tag
+ {\letgvalue{\??mk::#1:#2}\emptysavedmark}
+
+\def\emptysavedmark{{}{}{}{}}
+
+% new (can be used in column sets)
+%
+% \getsavedmarking[M][previous]
+% \getsavedmarking[M][first]
+% \getsavedmarking[M][last]
+
+\def\getsavedmarking
+ {\dodoubleargument\dogetsavedmarking}
+
+\def\dogetsavedmarking[#1][#2]%
+ {\doifelse{#2}\v!previous
+ {\getmarking[#1][1][\v!previous]}
+ {\doifelse{#2}\v!first
+ {\getmarking[#1][1][\v!first]}
+ {\getmarking[#1][\v!last]}}}
+
+%D And then \unknown\ we had a chaptertitle packaged in a
+%D makeup environment. And we don't want to loose marks there!
+
+\newbox\collectedmarks
+
+\def\flushmarks % use with care to avoid empty pages
+ {\ifvoid\collectedmarks\else\unhbox\collectedmarks\fi}
+
+\def\postponemarks
+ {\let\setsomemark\postponemark}
+
+\def\postponemark#1#2%
+ {\global\setbox\collectedmarks\hbox{\unhbox\collectedmarks\setmark{#1}{#2}}}
+
+\protect \endinput
+
+% todo: make it work in balancing
+%
+% \definemarking[vers][]
+% \setupheadertexts
+% [\doiftext{\getmarking[vers][first]}
+% {\doiftextelse{\getmarking[vers][column:last]}
+% {\getmarking[vers][first] -- \getmarking[vers][column:last]}
+% {\getmarking[vers][first]}}]
+% \starttext
+% \startcolumns[n=2,balance=no]
+% \dorecurse{10}{\normalexpanded{\noexpand\marking[vers]{\recurselevel}} \recurselevel:\dorecurse{4}{\input ward } \endgraf}
+% \stopcolumns
+% \stoptext
diff --git a/tex/context/base/strc-mat.lua b/tex/context/base/strc-mat.lua
new file mode 100644
index 000000000..ba64bf9db
--- /dev/null
+++ b/tex/context/base/strc-mat.lua
@@ -0,0 +1,51 @@
+if not modules then modules = { } end modules ['strc-mat'] = {
+ version = 1.001,
+ comment = "companion to strc-mat.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+structure = structure or { }
+structure.helpers = structure.helpers or { }
+structure.lists = structure.lists or { }
+structure.lists.enhancers = structure.lists.enhancers or { }
+structure.sections = structure.sections or { }
+structure.helpers = structure.helpers or { }
+structure.formulas = structure.formulas or { }
+
+local lists = structure.lists
+local sections = structure.sections
+local floats = structure.floats
+local helpers = structure.helpers
+local formulas = structure.formulas
+
+-- maybe we want to do clever things with formulas, the store might go away
+
+local formuladata = { }
+
+function formulas.store(data)
+ formuladata[#formuladata+1] = data
+ tex.write(#formuladata)
+end
+
+function formulas.current()
+ return formuladata[#formuladata]
+end
+
+function helpers.formulanumber(data,spec)
+ if data then
+ local formulanumber = data.formulanumber
+ if formulanumber then
+ sections.number(data,spec,"formulanumber","formulanumber",'number')
+ end
+ end
+end
+
+function formulas.simplify(entry)
+ return helpers.simplify(table.copy(entry or formuladata[#formuladata]))
+end
+
+function lists.formulanumber(name,n,spec)
+ helpers.formulanumber(lists.result[n])
+end
diff --git a/tex/context/base/strc-mat.tex b/tex/context/base/strc-mat.tex
new file mode 100644
index 000000000..482426b48
--- /dev/null
+++ b/tex/context/base/strc-mat.tex
@@ -0,0 +1,933 @@
+%D \module
+%D [ file=strc-mat,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Math Numbering,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Math Numbering}
+
+\registerctxluafile{strc-mat}{1.001}
+
+\unprotect
+
+\definestructureconversionset[\v!formula][number,characters]
+
+\setupformulas
+ [%\c!way=\@@nrway,
+ %\c!blockway=,
+ %\c!sectionnumber=\@@nrsectionnumber,
+ %\c!conversion=\v!numbers,
+ \c!location=\v!right,
+ \c!left=(,
+ \c!right=),
+ %\c!numberstyle=,
+ %\c!numbercolor=,
+ %\c!numbercommand=,
+ \c!spacebefore=\v!big,
+ \c!spaceafter=\formulaparameter\c!spacebefore,
+ \c!leftmargin=\!!zeropoint,
+ \c!rightmargin=\!!zeropoint,
+ %\c!margin=,
+ \c!indentnext=\v!no,
+ \c!alternative=\s!default,
+ %\c!align=,
+ \c!strut=\v!no,
+ %\c!separator=\@@koseparator,
+ %\c!grid=,
+ \c!distance=1em]
+
+\definestructurecounter
+ [\v!formula]
+
+\setupstructurecounter
+ [\v!formula]
+ [\c!numberconversionset=\v!formula]
+
+\def\storecurrentformulanumber#1#2#3% ref, todo:str, \sync % todo: title etc (like float)
+ {\dostructurecountercomponent
+ {formula}%
+ \getfloatparameters
+ \formulaparameter
+ \detokenizedformulaparameter
+ \relax
+ \relax
+ \relax
+ [\c!name=\currentformula,\s!counter=\currentformula,%
+ \s!hascaption=\v!yes,\s!hasnumber=\v!yes,\s!hastitle=\v!yes,%
+ \c!reference=#1,\c!title=,\c!bookmark=]%
+ [#2]%
+ \globallet\currentformulanumber\laststructurecounternumber
+ \globallet#3\laststructurecountersynchronize}
+
+\def\thecurrentformulanumber
+ {%\ifnoformulacaption \else \ifnoformulanumber \else
+ \labeltexts\currentformula{\convertedstructurecounter[formula]}% ! ! todo: use a lua call instead
+ }%\fi \fi}
+
+\def\placecurrentformulanumber
+ {\currentformulassynchronize
+ \currentformulasynchronize
+ \currentsubformulasynchronize
+ \thecurrentformulanumber} %\convertedstructurecounter[\v!formula]\relax}
+
+\def\doformulareference#1#2%
+ {\doifsomething{#1}{\doifnotinset{#1}{+,-}{\rawreference\s!for{#1}{#2}}}}
+
+\def\doformulanumber
+ {\dotripleempty\dodoformulanumber}
+
+\def\dodoformulanumber[#1][#2][#3]%
+ {\doquadruplegroupempty\dododoformulanumber{#1}{#2}{#3}}
+
+\let\subformulasreference\empty % temp hack
+
+\let\currentformulasynchronize \relax
+\let\currentformulassynchronize\relax
+
+\def\dododoformulanumber#1#2#3#4% (#1,#2)=outer(ref,sub) (#3,#4)=inner(ref,sub)
+ {\hbox\bgroup
+ \ifconditional\handleformulanumber
+ \ifconditional\incrementformulanumber
+ \ifconditional\insidesubformulas
+ \incrementsubstructurecounter[\v!formula][2]%
+ \else
+ \incrementstructurecounter[\v!formula]%
+ \fi
+ \fi
+ %
+ % main counter
+ \setbox0\hbox{\ignorespaces#2\unskip}%
+ \ifdim\wd0>\zeropoint
+ \setsubstructurecounterown[\v!formula][2]{#2}% \detokenize?
+ \fi
+ \edef\currentformulareference{#1}%
+ \ifx\currentformulareference\empty
+ \glet\currentformulasynchronize\relax
+ \else
+ \storecurrentformulanumber\currentformulareference\empty\currentformulasynchronize
+ \fi
+ % subcounter
+ \setbox0\hbox{\ignorespaces#4\unskip}%
+ \ifdim\wd0>\zeropoint
+ \setsubstructurecounterown[\v!formula][2]{#4}% \detokenize?
+ \fi
+ \edef\currentsubformulareference{#3}%
+ \ifx\currentsubformulareference\empty
+ \glet\currentsubformulasynchronize\relax
+ \else
+ \storecurrentformulanumber\currentsubformulareference\empty\currentsubformulasynchronize
+ \fi
+ %
+ \rm % nodig ?
+ \doif{\formulaparameter\c!location}\v!right{\hskip\formulaparameter\c!distance}%
+ \formulaparameter\c!numbercommand
+ {\dosetformulaattributes\c!numberstyle\c!numbercolor
+ \strut
+ \formulaparameter\c!left
+ \labeltexts\v!formula{\ignorespaces\placecurrentformulanumber\unskip}%
+ \formulaparameter\c!right}%
+ \doif{\formulaparameter\c!location}\v!left{\hskip\formulaparameter\c!distance}%
+ \fi
+ \egroup}
+
+\let\donestedformulanumber\gobbletwoarguments
+
+\definelist[\v!formula]
+
+\global\let\doflushformulalistentry\gobbleoneargument
+
+\def\setformulalistentry#1%
+ {\gdef\doflushformulalistentry##1%
+ {\normalexpanded{\noexpand\writetolist[\v!formula]{##1}}{#1}%
+ \global\let\doflushformulalistentry\gobbleoneargument}}
+
+\newconditional\handleformulanumber
+\newconditional\incrementformulanumber
+\newconditional\insidesubformulas
+
+\newif\ifinformula
+
+\let\doplaceformulanumber\empty
+
+%D We need a hook into the plain math alignment macros
+%D
+%D \starttyping
+%D \displaylines
+%D \eqalignno
+%D \eqalignno
+%D \stoptyping
+%D
+%D Otherwise we get a missing \type {$$} error reported.
+
+\def\resetdisplaymatheq
+ {\let\normalleqno\relax \let\leqno\relax
+ \let\normalreqno\relax \let\eqno \relax
+ \let\doplaceformulanumber\empty}
+
+%D
+
+\def\defineformula
+ {\dodoubleempty\dodefineformula}
+
+\def\dodefineformula[#1][#2]%
+ {\doifsomething{#1}
+ {\getparameters[\??fm#1][\s!parent=\??fm,#2]%
+ \definelist[#1]%
+ \setvalue{\e!start#1\v!formula}{\dostartformula{#1}}%
+ \setvalue{\e!stop #1\v!formula}{\dostopformula}}}
+
+\def\defineformulaalternative
+ {\dotripleargument\dodefineformulaalternative}
+
+\def\dodefineformulaalternative[#1][#2][#3]%
+ {\setvalue{\e!start#1\v!formula}{#2}%
+ \setvalue{\e!stop #1\v!formula}{#3}}
+
+% sp = single line paragraph sd = single line display
+% mp = multi line paragraph md = multy line display
+
+\defineformulaalternative[\s!default][\startdisplaymath][\stopdisplaymath]
+\defineformulaalternative[\s!single] [\startdisplaymath][\stopdisplaymath]
+\defineformulaalternative[\s!multi] [\startdisplaymath][\stopdisplaymath]
+
+\defineformula
+ [sp]
+ [\c!spacebefore=\v!none,
+ \c!spaceafter=\v!none,
+ \c!indentnext=\v!no,
+ \c!alternative=\s!single]
+
+\defineformula
+ [sd]
+ [\c!spacebefore=\v!none,
+ \c!spaceafter=\v!none,
+ \c!indentnext=\v!yes,
+ \c!alternative=\s!single]
+
+\defineformula
+ [mp]
+ [\c!indentnext=\v!no,
+ \c!alternative=\s!multi]
+
+\defineformula
+ [md]
+ [\c!indentnext=\v!yes,
+ \c!alternative=\s!multi]
+
+%D \macros
+%D {setupsubformulas, startsubformulas}
+
+\def\subformulaparameter#1{\ifcname\??fn#1\endcsname\cname\??fn#1\endcsname\fi}
+
+\def\setupsubformulas
+ {\dodoubleargument\getparameters[\??fn]}
+
+\setupsubformulas
+ [\c!indentnext=\formulaparameter\c!indentnext]
+
+% \setupsubformulas[conversion=romannumerals]
+%
+% \placeformula
+% \startsubformulas[Maxwell]
+% \startformulas
+% \startformula \startalign
+% \NC \nabla\cdot\bf E \NC = \frac{\rho}{\varepsilon_0} \NR[Maxwell 1]
+% \NC \nabla\times\bf E \NC = - \frac{\partial\bf B}{\partial t} \NR[Maxwell II]
+% \stopalign \stopformula
+% \startformula \startalign
+% \NC \nabla\cdot \bf B \NC = 0 \NR[Maxwell III]
+% \NC \nabla\times\bf B \NC = \mu_0{\bf j}+\varepsilon_0\mu_0\frac{\partial\bf E}{\partial t} \NR[Maxwell IV]
+% \stopalign \stopformula
+% \stopformulas
+% \stopsubformulas
+%
+% Maxwell : \in [Maxwell] and II : \in [Maxwell II]
+
+%D Tricky stuff:
+
+\newdimen\lastlinewidth
+
+% test \par \dorecurse{10}{test } \moveformula \startformula test \stopformula test \endgraf
+% test \par \dorecurse{10}{test } \startformula test \stopformula test \endgraf
+% \dorecurse{30}{\bpar \dorecurse\recurselevel{test } \epar \startformula formula \stopformula}
+
+\def\setlastlinewidth
+ {\resetlastlinewidth
+ \ifoptimizedisplayspacing\ifmmode\else\ifhmode
+ \bgroup
+ \forgetdisplayskips
+ \displaywidowpenalty\widowpenalty % brrr, else widowpenalty does not work
+ \everymath \emptytoks
+ \everydisplay\emptytoks
+ $$\strut\global\lastlinewidth\predisplaysize$$
+ \vskip-\lineheight
+ \vskip\zeropoint
+ \egroup
+ \fi\fi\fi}
+
+\def\resetlastlinewidth
+ {\global\lastlinewidth\zeropoint\relax}
+
+\abovedisplayskip \zeropoint
+\abovedisplayshortskip \zeropoint % evt. 0pt minus 3pt
+\belowdisplayskip \zeropoint
+\belowdisplayshortskip \zeropoint % evt. 0pt minus 3pt
+
+\predisplaypenalty \zerocount
+\postdisplaypenalty \zerocount % -5000 gaat mis, zie penalty bij \paragraaf
+
+% we don't use the skip's
+
+\def\displayskipsize#1#2% obsolete
+ {\ifdim\ctxparskip>\zeropoint
+ #1\ctxparskip\!!plus#2\ctxparskip\!!minus#2\ctxparskip\relax
+ \else
+ #1\lineheight\!!plus#2\lineheight\!!minus#2\lineheight\relax
+ \fi}
+
+\def\forgetdisplayskips % to do
+ {\abovedisplayskip \zeropoint
+ \belowdisplayskip \zeropoint
+ \abovedisplayshortskip\zeropoint
+ \belowdisplayshortskip\zeropoint}
+
+\setvalue{\e!start\v!formula}{\dostartformula{}}
+\setvalue{\e!stop \v!formula}{\dostopformula}
+
+\def\predisplaysizethreshhold{2em} % was 3em
+
+\def\leftdisplayskip {\leftskip}
+\def\rightdisplayskip {\rightskip}
+\def\leftdisplaymargin {\formulaparameter\c!leftmargin}
+\def\rightdisplaymargin {\formulaparameter\c!rightmargin}
+\def\displaygridsnapping{\formulaparameter\c!grid}
+
+\def\beforedisplayspace
+ {\doifnot{\formulaparameter\c!spacebefore}\v!none{\blank[\formulaparameter\c!spacebefore]}}
+
+\def\afterdisplayspace
+ {\doifnot{\formulaparameter\c!spaceafter }\v!none{\blank[\formulaparameter\c!spaceafter ]}}
+
+\def\setpredisplaysize#1%
+ {\predisplaysize#1\relax
+ \ifdim\predisplaysize<\maxdimen
+ \ifdim\predisplaysize>\zeropoint
+ \advance\predisplaysize \predisplaysizethreshhold
+ \fi
+ \advance\predisplaysize \displayindent % needed ?
+ \ifdim\predisplaysize>\hsize
+ \predisplaysize\hsize
+ \fi
+ \else
+ \predisplaysize\zeropoint
+ \fi}
+
+\def\setdisplaydimensions
+ {\displayindent\leftdisplayskip
+ \advance\displayindent\leftdisplaymargin
+ \displaywidth\hsize
+% \setlocalhsize
+% \displaywidth\localhsize
+ \ifdim\hangindent>\zeropoint
+ \advance\displayindent\hangindent
+ \else
+ \advance\displaywidth\hangindent
+ \fi
+ \advance\displaywidth\dimexpr-\displayindent-\rightdisplayskip-\rightdisplaymargin\relax
+ \hsize\displaywidth} % new, else overfull in itemize
+
+\newif\ifoptimizedisplayspacing
+
+\def\dostartformula#1%
+ {\dodoubleempty\dodostartformula[#1]}
+
+\newskip\formulaparskip
+\newskip\formulastrutht
+\newskip\formulastrutdp
+
+% hm, invoke otr in hmode in order to move skips to mvl, could be an option
+
+%D \startbuffer
+%D \startformula[9pt] x = 1 \stopformula
+%D \startformula[7pt] x = 1 \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\dodostartformula[#1][#2]% setting leftskip adaption is slow !
+ {% todo: test first
+ %
+ % \ifdim\lastskip>\zeropoint
+ % \resetlastlinewidth % else problems with in between stuff without \epar
+ % \fi
+ \bgroup % HERE
+ \def\currentformula{#1}%
+ \the\everybeforedisplayformula
+ \formulaparskip\parskip
+ \formulastrutdp\strutdepth
+ \formulastrutht\strutheight
+ \doifsomething{#2}{\switchtoformulabodyfont[#2]}%
+ \parskip\formulaparskip
+ % may look better in itemizations
+ \doif{\formulaparameter\c!option}\v!middle
+ {\def\leftdisplayskip{\zeropoint}%
+ \def\rightdisplayskip{\zeropoint}}%
+ % this was an experiment
+ \doifsomething{\formulaparameter\c!margin}% so we test first
+ {\dosetleftskipadaption{\formulaparameter\c!margin}%
+ \edef\leftdisplaymargin{\the\leftskipadaption}}% overloaded
+ \long\def\dostartformula##1{\bgroup\let\dostopformula\egroup}%
+ \freezedimenmacro\leftdisplayskip
+ \freezedimenmacro\rightdisplayskip
+ \freezedimenmacro\leftdisplaymargin
+ \freezedimenmacro\rightdisplaymargin
+ \freezedimenmacro\predisplaysizethreshhold
+ \forgetdisplayskips
+ \ifoptimizedisplayspacing
+ \ifdim\lastlinewidth>\zeropoint
+ \abovedisplayshortskip-\strutht\relax
+ \fi
+ \else
+ \resetlastlinewidth
+ \fi
+ \getvalue{\e!start\formulaparameter\c!alternative\v!formula}}
+
+\def\switchtoformulabodyfont{\switchtobodyfont}
+
+\setvalue{\v!formula}{\dosingleempty\doformula}
+
+\def\doformula[#1]#2%
+ {\begingroup
+ \doifsomething{#1}{\switchtoformulabodyfont[#1]}%
+ % not : \def\doformula[##1]##2{\mathematics{##2}}%
+ \mathematics{#2}%
+ \endgroup}
+
+\def\dostopformula
+ {\doplaceformulanumber
+ \getvalue{\e!stop\formulaparameter\c!alternative\v!formula}%
+ \resetlastlinewidth
+ \nonoindentation
+ \checknextindentation[\formulaparameter\c!indentnext]%
+ \egroup
+ \hangafter\minusone % added for side floats
+ \hangindent\zeropoint % added for side floats
+ \setfalse\handleformulanumber
+ \dorechecknextindentation} % here ?
+
+\def\startdisplaymath
+ {\ifgridsnapping
+ \beforedisplayspace
+ \snapmathtogrid\vbox
+ \bgroup
+ \informulatrue
+ %\forgetall % breaks side floats
+ \else
+ \bgroup
+ \parskip\formulaparskip % ! !
+ \informulatrue
+ %\forgetall % otherwise backgrounds fail
+ \ifdim\lastskip<\zeropoint\else
+ \par
+ \ifvmode \ifdim\parskip>\zeropoint\relax
+ \whitespace \vskip-\parskip % kind of forces and cancels again
+ \fi \fi
+ \fi
+ \doif\displaygridcorrection{-\v!top}{\kern-\strutht}% new, currently only option/default
+ \beforedisplayspace
+ \par
+ \ifvmode
+ \prevdepth-\maxdimen % texbook pagina 79-80
+ % otherwise problems at the top of a page
+ \verticalstrut
+ \vskip-\struttotal
+ \vskip-\baselineskip
+ \fi
+ \fi
+ $$\setdisplaydimensions
+ \setpredisplaysize\lastlinewidth
+ \startinnermath}
+
+\def\stopdisplaymath
+ {\stopinnermath
+ $$%
+ \ifgridsnapping
+ \egroup
+ \afterdisplayspace
+ \else
+ \par\ifvmode\ifdim\parskip>\zeropoint\whitespace\vskip-\parskip\fi\fi
+ \afterdisplayspace
+ \egroup
+ \fi
+ \globallet\displaylinecorrection\empty
+ \gdef\displaygridcorrection{\displaygridsnapping}}
+
+\newif\ifclipdisplaymath \clipdisplaymathtrue
+\def\displaymathclipfactor{1.1}
+
+\def\snapmathtogrid % to do \dp
+ {\dowithnextbox
+ {\bgroup
+ \donefalse
+ \ifclipdisplaymath
+ \ifdim\nextboxht<\displaymathclipfactor\lineheight
+ \donetrue
+ \fi
+ \fi
+ \ifdone
+ \nextboxht\lineheight
+ \else
+ \getnoflines\nextboxht
+ \setbox\nextbox\vbox to \noflines\lineheight{\vfill\flushnextbox\vfill}%
+ \setbox\nextbox\hbox{\lower\strutdepth\flushnextbox}%
+ \fi
+ \snaptogrid[\displaygridcorrection]\hbox{\flushnextbox}%
+ \egroup}}
+
+\def\displaygridcorrection{\displaygridsnapping}
+\let\displaygridcorrection\empty
+
+\def\moveformula
+ {\dosingleempty\domoveformula}
+
+\def\domoveformula[#1]% brr gaat mogelijk fout
+ {\iffirstargument
+ \xdef\displaygridcorrection{#1}%
+ \else
+ \gdef\displaygridcorrection{-\v!top}% handy with short preline
+ \fi
+ \globallet\displaylinecorrection\displaygridcorrection}
+
+\let\startinnermath\empty
+\let\stopinnermath \empty
+
+% \defineformulaalternative[multi][\begindmath][\enddmath]
+%
+% \fakewords{20}{40}\epar
+% \placeformula {a} $$ \fakespacingformula $$
+% \fakewords{20}{40}\epar
+% \placeformula {b} \startformule \fakespacingformula \stopformule
+% \placeformula {b} \startformule \fakespacingformula \stopformule
+% \fakewords{20}{40}\epar
+% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
+% \placeformula {c} \startmdformule \fakespacingformula \stopmdformule
+% \fakewords{20}{40}\epar
+% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
+% \placeformula {d} \startmpformule \fakespacingformula \stopmpformule
+% \fakewords{20}{40}\epar
+% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
+% \placeformula {e} \startsdformule \fakespacingformula \stopsdformule
+% \fakewords{20}{40}\epar
+% \placeformula {f} \startspformule \fakespacingformula \stopspformule
+% \placeformula {f} \startspformule \fakespacingformula \stopspformule
+% \fakewords{20}{40}
+
+\def\placeformula
+ {\settrue\incrementformulanumber
+ \dodoubleempty\doplaceformula}
+
+\def\placesubformula
+ {\setfalse\incrementformulanumber
+ \dodoubleempty\doplaceformula}
+
+\def\startsubformulas
+ {\dosingleempty\dostartsubformulas}
+
+\def\dostartsubformulas[#1]%
+ {\ifconditional\incrementformulanumber
+ \incrementstructurecounter[\v!formula]%
+ \edef\subformulasreference{#1}% messy
+ \ifx\subformulasreference\empty
+ \glet\currentformulassynchronize\relax
+ \else
+ \storecurrentformulanumber\subformulasreference\empty\currentformulassynchronize
+ \fi
+ \fi
+ \settrue\insidesubformulas}
+
+\def\stopsubformulas
+ {\setfalse\insidesubformulas
+ \resetlastlinewidth
+ \nonoindentation
+ \checknextindentation[\formulaparameter\c!indentnext]%
+ \dorechecknextindentation} % here ?
+
+%D Named subformulas
+
+\def\startnamedsubformulas
+ {\dosingleempty\dostartnamedsubformulas}
+
+\def\dostartnamedsubformulas[#1]#2%
+ {\setformulalistentry{#2}%
+ \startsubformulas[#1]}
+
+\def\stopnamedsubformulas
+ {\stopsubformulas}
+
+%D Experimental goodie:
+%D
+%D \startbuffer
+%D \placelist[formula][criterium=text] \blank[2*big]
+%D \placenamedformula[one]{first} \startformula a = 1 \stopformula \endgraf
+%D \placeformula \startformula a = 2 \stopformula \endgraf
+%D \placenamedformula {second} \startformula a = 3 \stopformula \endgraf
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\placenamedformula
+ {\dosingleempty\doplacenamedformula}
+
+\def\doplacenamedformula[#1]#2%
+ {\iffirstargument
+ \def\next{\placeformula[#1]}%
+ \else
+ \let\next\placeformula
+ \fi
+ \setformulalistentry{#2}%
+ \next}
+
+%D The implementation of placement is a bit ugly:
+
+\def\doplaceformula[#1][#2]% #2 = dummy, gobbles spaces
+ {\def\redoplaceformula
+ {\bgroup
+ \ifx\next\bgroup
+ \egroup \@EA\moreplaceformula % [ref]{}
+ \else
+ \let\nextnext$% no def
+ \ifx\next\nextnext
+ \egroup \@EAEAEA\dispplaceformula % [ref]$$
+ \else
+ \egroup \@EAEAEA\dodoplaceformula % [ref]\start
+ \fi
+ \fi[#1]{}}%
+ \futurelet\next\redoplaceformula}
+
+\long\def\moreplaceformula[#1]#2#3#4% #2 dummy #4 gobbles spaces
+ {\def\redoplaceformula
+ {\bgroup
+ \let\nextnext$% no def
+ \ifx\next\nextnext
+ \egroup \@EA\dispplaceformula % [ref]$$
+ \else
+ \egroup \@EA\dodoplaceformula % [ref]\start
+ \fi
+ [#1]{#3}}%
+ \futurelet\next\redoplaceformula#4}
+
+\let\startplaceformula\placeformula
+\let\stopplaceformula \relax
+
+\def\startformulas#1\stopformulas % new / to be internationalized
+ {\bgroup
+ \let\currentformula\empty
+ \forgetdisplayskips
+ \startdisplaymath
+ \setlocalhsize
+ \long\def\startformula##1\stopformula
+ {\advance\scratchcounter\plusone}%
+ \scratchcounter\zerocount
+ #1% preroll
+ \ifcase\scratchcounter\else
+ \divide \hsize \scratchcounter
+ \fi
+ \hbox to \localhsize \bgroup
+ \hss
+ \def\normalstartformula{\vskip-\strutdepth$$}% i hate this
+ \def\normalstopformula {$$}%
+ \def\startformula {$\vcenter\bgroup\normalstartformula}%
+ \def\stopformula {\normalstopformula\egroup$\hss}%
+ #1%
+ \egroup
+ \stopdisplaymath
+ \egroup
+ \hangafter\minusone % added for side floats
+ \hangindent\zeropoint} % added for side floats
+
+\def\dispplaceformula[#1]#2$$#3$$%
+ {\dodoplaceformula[#1]{#2}\dostartformula{}#3\dostopformula}
+
+\def\dodoplaceformula[#1]#2% messy, needs a clean up
+ {\doifelse{#1}{-}
+ {\setfalse\handleformulanumber}
+ {\doifelse{#2}{-}
+ {\setfalse\handleformulanumber}
+ {\settrue\handleformulanumber}}%
+ \ifconditional\handleformulanumber
+ \def\formulanumber
+ {%\global\let\subformulanumber\doformulanumber % no, bug
+ \doformulanumber[#1][#2]}%
+ \def\donestedformulanumber##1##2%
+ {\doifsomething{##1}
+ {\doifelse{##1}{+}{\doformulanumber[#1]}{\doformulanumber[##1]}[##2][]{}}}%
+ \def\subformulanumber
+ {\setfalse\incrementformulanumber
+ \formulanumber}%
+ \gdef\doplaceformulanumber
+ {\global\let\doplaceformulanumber\empty
+ \doifelse{\formulaparameter\c!location}\v!left
+ {\normalleqno{\doformulanumber[#1][#2][]{}}}
+ {\normalreqno{\doformulanumber[#1][#2][]{}}}}%
+ \else
+ \def\formulanumber{\doformulanumber[#1][#2]}%
+ \let\donestedformulanumber\gobbletwoarguments
+ \let\subformulanumber\doformulanumber % was \global
+ \global\let\doplaceformulanumber\empty
+ \fi}
+
+%D Here we implement a basic math alignment mechanism. Numbers
+%D are also handled. The macros \type {\startinnermath} and
+%D \type {\stopinnermath} can be overloaded in specialized
+%D modules.
+
+\def\startinnermath
+ {\getvalue{\e!start\??fm\formulaparameter\c!align}}
+
+\def\stopinnermath
+ {\getvalue{\e!stop \??fm\formulaparameter\c!align}}
+
+\def\mathinnerstrut
+ {\doif{\formulaparameter\c!strut}\v!yes\strut}
+
+\long\def\defineinnermathhandler#1#2#3%
+ {\setvalue{\e!start\??fm#1}{#2}%
+ \setvalue{\e!stop \??fm#1}{#3}}
+
+\newif\iftracemath
+
+\def\mathhbox
+ {\iftracemath\ruledhbox\else\hbox\fi}
+
+\chardef\mathraggedstatus=0 % normal left center right
+\chardef\mathnumberstatus=0 % nothing normal shift_right
+\let\mathnumbercorrection\!!zeropoint
+
+\def\startmathbox#1%
+ {\hsize\displaywidth
+ \global\chardef\mathnumberstatus\plusone
+ \chardef\mathraggedstatus#1\relax
+ \let\mathnumbercorrection\!!zeropoint
+ \global\let\@eqno \empty \def\eqno {\gdef\@eqno }%
+ \global\let\@leqno\empty \def\leqno{\gdef\@leqno}%
+ % added
+ \let\normalreqno\eqno
+ \let\normalleqno\leqno
+ % added
+ \doplaceformulanumber
+ \setbox\scratchbox\mathhbox to \displaywidth\bgroup
+ \mathinnerstrut
+ $%
+ \displaystyle
+ \ifcase\mathraggedstatus\or\hfill\or\hfill\fi}
+
+\def\llappedmathno
+ {\ifcase\mathraggedstatus\or
+ \@eqno
+ \or
+ \llap{\@eqno}%
+ \or
+ \llap{\@eqno}%
+ \fi}
+
+\def\rlappedmathno
+ {\ifcase\mathraggedstatus\or
+ \rlap{\@leqno}%
+ \or
+ \rlap{\@leqno}%
+ \or
+ \@leqno
+ \fi}
+
+\def\stopmathbox
+ {$%
+ \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi
+ \egroup
+ \setbox0\hbox{\unhcopy\scratchbox}%
+ \scratchdimen\wd0
+ \ifdim\scratchdimen>\displaywidth
+ \donetrue
+ \else
+ \donefalse
+ \fi
+ \hbox to \displaywidth\bgroup
+ \ifcase\mathnumberstatus
+ \box\scratchbox
+ \or
+ \ifx\@leqno\empty
+ \ifx\@eqno\empty
+ \box\scratchbox
+ \else
+ \ifdone
+ \vbox{\box\scratchbox\hbox to \displaywidth{\hss\llappedmathno}}%
+ \else
+ \hss\box\scratchbox\llappedmathno % hss makes room for number
+ \fi
+ \fi
+ \else
+ \ifdone
+ \vbox{\hbox to \displaywidth{\rlappedmathno\hss}\box\scratchbox}%
+ \else
+ \rlappedmathno\box\scratchbox\hss % hss makes room for number
+ \fi
+ \fi
+ \or
+ \hskip\mathnumbercorrection
+ \box\scratchbox
+ \hss
+ \else
+ \box\scratchbox
+ \fi
+ \egroup}
+
+\defineinnermathhandler\v!left {\startmathbox\plusone }{\stopmathbox}
+\defineinnermathhandler\v!middle {\startmathbox\plustwo }{\stopmathbox}
+\defineinnermathhandler\v!right {\startmathbox\plusthree}{\stopmathbox}
+\defineinnermathhandler\v!flushleft {\startmathbox\plusthree}{\stopmathbox}
+\defineinnermathhandler\v!center {\startmathbox\plustwo }{\stopmathbox}
+\defineinnermathhandler\v!flushright{\startmathbox\plusone }{\stopmathbox}
+
+%D [The examples below are in english and don't process in the
+%D documentation style, which will be english some day.]
+%D
+%D Normally a formula is centered, but in case you want to
+%D align it left or right, you can set up formulas to behave
+%D that way. Normally a formula will adapt is left indentation
+%D to the environment:
+%D
+%D \startbuffer
+%D \fakewords{20}{40}\epar
+%D \startitemize
+%D \item \fakewords{20}{40}\epar
+%D \placeformula \startformula \fakeformula \stopformula
+%D \item \fakewords{20}{40}\epar
+%D \stopitemize
+%D \fakewords{20}{40}\epar
+%D \stopbuffer
+%D
+%D % \getbuffer
+%D
+%D In the next examples we explicitly align formulas to the
+%D left (\type {\raggedleft}), center and right (\type
+%D {\raggedright}):
+%D
+%D \startbuffer
+%D \setupformulas[align=left]
+%D \startformula\fakeformula\stopformula
+%D \setupformulas[align=middle]
+%D \startformula\fakeformula\stopformula
+%D \setupformulas[align=right]
+%D \startformula\fakeformula\stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Or in print:
+%D
+%D % {\getbuffer}
+%D
+%D With formula numbers these formulas look as follows:
+%D
+%D \startbuffer
+%D \setupformulas[align=left]
+%D \placeformula \startformula\fakeformula\stopformula
+%D \setupformulas[align=middle]
+%D \placeformula \startformula\fakeformula\stopformula
+%D \setupformulas[align=right]
+%D \placeformula \startformula\fakeformula\stopformula
+%D \stopbuffer
+%D
+%D % {\getbuffer}
+%D
+%D This was keyed in as:
+%D
+%D \typebuffer
+%D
+%D When tracing is turned on (\type {\tracemathtrue}) you can
+%D visualize the bounding box of the formula,
+%D
+%D % {\tracemathtrue\getbuffer}
+%D
+%D As you can see, the dimensions are the natural ones, but if
+%D needed you can force a normalized line:
+%D
+%D \startbuffer
+%D \setupformulas[strut=yes]
+%D \placeformula \startformula \fakeformula \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This time we get a more spacy result.
+%D
+%D % {\tracemathtrue\getbuffer}
+%D
+%D We will now show a couple of more settings and combinations
+%D of settings. In centered formulas, the number takes no space
+%D
+%D \startbuffer
+%D \setupformulas[align=middle]
+%D \startformula \fakeformula \stopformula
+%D \placeformula \startformula \fakeformula \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer % {\tracemathtrue\getbuffer}
+%D
+%D You can influence the placement of the whole box with the
+%D parameters \type {leftmargin} and \type {rightmargin}.
+%D
+%D \startbuffer
+%D \setupformulas[align=right,leftmargin=3em]
+%D \startformula \fakeformula \stopformula
+%D \placeformula \startformula \fakeformula \stopformula
+%D
+%D \setupformulas[align=left,rightmargin=1em]
+%D \startformula \fakeformula \stopformula
+%D \placeformula \startformula \fakeformula \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer % {\tracemathtrue\getbuffer}
+%D
+%D You can also inherit the margin from the environment.
+%D
+%D \startbuffer
+%D \setupformulas[align=right,margin=standard]
+%D \startformula \fakeformula \stopformula
+%D \placeformula \startformula \fakeformula \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer % {\tracemathtrue\getbuffer}
+%D
+%D The distance between the formula and the number is only
+%D applied when the formula is left or right aligned.
+%D
+%D \startbuffer
+%D \setupformulas[align=left,distance=2em]
+%D \startformula \fakeformula \stopformula
+%D \placeformula \startformula \fakeformula \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer % {\tracemathtrue\getbuffer}
+
+\protect \endinput
+
+% \abovedisplayshortskip0pt \belowdisplayshortskip0pt \abovedisplayskip0pt \belowdisplayskip0pt \forgetall
+%
+% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+% test plus \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+%
+% \parskip\baselineskip
+%
+% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+% test \par $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+% test plus \par \prevdepth \maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
+% test minus \par \prevdepth-\maxdimen $$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$$ \par test \par
diff --git a/tex/context/base/strc-not.lua b/tex/context/base/strc-not.lua
new file mode 100644
index 000000000..78e7b6acd
--- /dev/null
+++ b/tex/context/base/strc-not.lua
@@ -0,0 +1,248 @@
+if not modules then modules = { } end modules ['strc-not'] = {
+ version = 1.001,
+ comment = "companion to strc-not.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+local next = next
+local texsprint, texwrite = tex.sprint, tex.write
+
+local ctxcatcodes = tex.ctxcatcodes
+
+structure = structure or { }
+structure.helpers = structure.helpers or { }
+structure.lists = structure.lists or { }
+structure.sections = structure.sections or { }
+structure.counters = structure.counters or { }
+structure.notes = structure.notes or { }
+
+structure.notes.states = structure.notes.states or { }
+structure.lists.enhancers = structure.lists.enhancers or { }
+
+storage.register("structure/notes/states", structure.notes.states, "structure.notes.states")
+
+local helpers = structure.helpers
+local lists = structure.lists
+local sections = structure.sections
+local counters = structure.counters
+local notes = structure.notes
+
+local notestates = structure.notes.states
+local notedata = { }
+
+-- state: store, insert, postpone
+
+function notes.store(tag,n)
+ local nd = notedata[tag]
+ if not nd then
+ nd = { }
+ notedata[tag] = nd
+ end
+ nd[#nd+1] = n
+ local state = notestates[tag]
+ if state.kind ~= "insert" then
+ state.start = #nd
+ end
+ tex.write(#nd)
+end
+
+function notes.get(tag,n)
+ local nd = notedata[tag]
+ if nd then
+ nd = nd[n or #notedata]
+ if nd then
+ return structure.lists.collected[nd]
+ end
+ end
+end
+
+function notes.define(tag,kind,number)
+ local state = notes.setstate(tag,kind)
+ state.number = number
+end
+
+function notes.save(tag,newkind)
+ local state = notestates[tag]
+ if state and not state.saved then
+ state.saved = notedata[tag]
+ state.savedkind = state.kind
+ state.kind = newkind or state.kind
+ notedata[tag] = { }
+ end
+end
+
+function notes.restore(tag)
+ local state = notestates[tag]
+ if state and state.saved then
+ state.saved = nil
+ state.kind = state.savedkind
+ notedata[tag] = state.saved
+ end
+end
+
+function notes.setstate(tag,newkind)
+ local state = notestates[tag]
+ if not state then
+ state = {
+ kind = newkind
+ }
+ notestates[tag] = state
+ elseif newkind == "insert" then
+ if not state.start then
+ state.kind = newkind
+ end
+ else
+ state.kind = newkind
+ end
+ return state
+end
+
+function notes.getstate(tag)
+ local state = notestates[tag]
+ texsprint((state and state.kind ) or "unknown")
+end
+
+function notes.doifcontent(tag)
+ local ok = notestates[tag]
+ if ok then
+ if ok.kind == "insert" then
+ ok = tex.box[ok.number]
+ if ok then
+ ok = tbs.list
+ ok = lst and lst.next
+ end
+ else
+ ok = ok.start
+ end
+ end
+ commands.doif(ok)
+end
+
+local function internal(tag,n)
+ local nd = notes.get(tag,n)
+ if nd then
+ local r = nd.references
+ if r then
+ local i = r.internal
+ return i and lists.internals[i]
+ end
+ end
+ return nil
+end
+
+local function ordered(kind,name,n)
+ local o = lists.ordered[kind]
+ o = o and o[name]
+ return o and o[n]
+end
+
+function notes.checkpagechange(tag) -- called before increment !
+ local nd = notedata[tag] -- can be unset at first entry
+ if nd then
+ local current = ordered("note",tag,#nd)
+ local nextone = ordered("note",tag,#nd+1)
+ if nextone then
+ -- we can use data from the previous pass
+ if nextone.pagenumber.number > current.pagenumber.number then
+ counters.reset(tag)
+ end
+ elseif current then
+ -- we need to locate the next one, best guess
+ if tex.count[0] > current.pagenumber.number then
+ counters.reset(tag)
+ end
+ end
+ end
+end
+
+function notes.deltapage(tag,n)
+ -- 0:unknown 1:textbefore, 2:textafter, 3:samepage
+ local what = 0
+ local li = internal(tag,n)
+ if li then
+ local metadata, pagenumber = li.metadata, li.pagenumber
+ if metadata and pagenumber then
+ local symbolpage = metadata.symbolpage or 0
+ local notepage = pagenumber.number or 0
+ if notepage > 0 and symbolpage > 0 then
+ if notepage < symbolpage then
+ what = 1
+ elseif notepage > symbolpage then
+ what = 2
+ else
+ what = 3
+ end
+ end
+ else
+ -- might be a note that is not flushed due to to deep
+ -- nesting in a vbox
+ what = 3
+ end
+ end
+ tex.write(what)
+end
+
+function notes.postpone()
+ for tag, state in next, notestates do
+ if state.kind ~= "store" then
+ notes.setstate(tag,"postpone")
+ end
+ end
+end
+
+function notes.setsymbolpage(tag,n)
+ local nd = notes.get(tag,n)
+ if nd then
+ nd.metadata.symbolpage = tex.count[0] -- realpage
+ end
+end
+
+function notes.getsymbolpage(tag,n)
+ local nd = notes.get(tag,n)
+ nd = nd and nd.metadata.symbolpage
+ texwrite(nd or 0)
+end
+
+function notes.getnumberpage(tag,n)
+ local li = internal(tag,n)
+ li = li and li.pagenumber
+ li = li and li.numbers
+ li = li and li[1]
+ texwrite(li or 0)
+end
+
+function notes.flush(tag,whatkind) -- store and postpone
+ local nd = notedata[tag]
+ if nd then
+ local state = notestates[tag]
+ local ns = state and state.start -- first index
+ if ns then
+ local kind = state.kind
+ if kind == whatkind then
+ if kind == "postpone" then
+ for i=ns,#nd do
+ texsprint(ctxcatcodes,format("\\handlenoteinsert{%s}{%s}",tag,i))
+ end
+ state.start = nil
+ state.kind = "insert"
+ elseif kind == "store" then
+ for i=ns,#nd do
+ texsprint(ctxcatcodes,format("\\handlenoteitself{%s}{%s}",tag,i))
+ end
+ state.start = nil
+ end
+ end
+ end
+ end
+end
+
+function notes.title(tag,n)
+ structure.lists.savedtitle(tag,notedata[tag][n])
+end
+
+function notes.number(tag,n,spec)
+ structure.lists.savedprefixednumber(tag,notedata[tag][n])
+end
diff --git a/tex/context/base/strc-not.tex b/tex/context/base/strc-not.tex
new file mode 100644
index 000000000..ca0d3c0a4
--- /dev/null
+++ b/tex/context/base/strc-not.tex
@@ -0,0 +1,1154 @@
+%D \module
+%D [ file=strc-not,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Note Handling,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Note Handling}
+
+\registerctxluafile{strc-not}{1.001}
+
+\unprotect
+
+% obsolete
+
+\let\autopostponenotes\relax
+
+% removed:
+%
+% \pushsomestates
+%
+% core-ins -> obsolete
+%
+% saveinsertiondata
+% restoreinsertiondata
+% saveinsertionbox
+% eraseinsertionbackup
+% restoreinsertionbackup
+%
+% \def\doprocessnotescs#1#2% #1 == \cs that takes arg
+% {\def\currentnote{#2}\@EA#1\csname\??vn:\currentnote\endcsname}
+% \def\processnotescs#1{\processcommacommand[\noteinsertions]{\doprocessnotescs#1}}
+% \def\noteinsertion #1{\csname\??vn:#1\endcsname}
+
+\def\savenotedata {\writestatus{todo}{save note data}}
+\def\restorenotedata {\writestatus{todo}{restore note data}}
+\def\savenotecontent {\writestatus{todo}{save note content}}
+\def\restorenotecontent{\writestatus{todo}{restore note content}}
+\def\erasenotebackup {\writestatus{todo}{erase note backup}}
+
+% page-set:
+
+\def\enablenotes {\writestatus{todo}{enable notes}}
+\def\disablenotes {\writestatus{todo}{disable notes}}
+\def\savenotes {\writestatus{todo}{save notes}}
+\def\flushsavednotes{\writestatus{todo}{flush notes}}
+
+% experiment: (compare scope=text and scope=page)
+%
+% \definenote[mynote][way=bytext,location=text,width=\leftmarginwidth,scope=page,rule=,before=,after=,factor=0]
+% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][]
+
+%D Footnotes are can be characterized by three components:
+%D
+%D \startitemize[packed]
+%D \item a small number \footnote {a footnote number} or
+%D symbol {\setupfootnotes [conversion=set 2]\footnote
+%D {a footnote}}
+%D \item and a similar mark at the bottom of the page
+%D \item followed by some additional text
+%D \stopitemize
+%D
+%D Because footnotes are declared at the location of their
+%D reference they can be seen as a special kind of
+%D floating bodies. Their placement is postponed but has to be
+%D taken into account in the pagebreak calculations. This kind
+%D of calculations are forced by using \type{\insert}s and dealing
+%D with all cases is not trivial.
+
+%D \macros
+%D {notesenabled}
+%D
+%D We need a couple of states because at some moments we don't want
+%D to mess around with inserts at all. Take for instance a table
+%D of contents. And so we can temporary disable footnotes by saying
+%D
+%D \starttyping
+%D \notesenabledfalse
+%D \stoptyping
+
+\newif\ifnotesenabled \notesenabledtrue
+
+\appendtoks \notesenabledfalse \to \everymarking
+
+%D Often we need to process the whole set of notes and to make that
+%D fast, we use a token register:
+
+\newtoks\tobeprocessednotes
+
+\def\processnotes#1% #1: \macro that uses \currentnote
+ {\def\doprocesssomenote##1{\edef\currentdescription{##1}\edef\currentnote{##1}#1}%
+ \the\tobeprocessednotes}
+
+%D Notes have their own paremater handlers. The complication here
+%D is that we use descriptions to typeset the note, so we have several
+%D resolvers.
+
+\let\currentnote\v!footnote
+
+\def\noteparameter #1{\csname\donoteparameter{\??vn\currentnote}#1\endcsname}
+\def\noteparameterhash#1{\donoteparameterhash {\??vn\currentnote}#1}
+
+\def\donoteparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\donoteparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\donoteparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\donoteparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\donoteparentparameter #1#2{\ifx#1\relax\s!empty\else\donoteparameter #1#2\fi}
+\def\donoteparentparameterhash#1#2{\ifx#1\relax \else\donoteparameterhash#1#2\fi}
+
+\def\detokenizednoteparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??vn#1\endcsname}}
+
+\def\dosetnoteattributes#1#2% style color
+ {\edef\fontattributehash {\noteparameterhash#1}%
+ \edef\colorattributehash{\noteparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+%D \macros
+%D {setupnote,setupnotedefinition}
+%D
+%D We can influence footnote typesetting with the setup
+%D command:
+%D
+%D \showsetup{setupnotes}
+%D \showsetup{setupnote}
+%D
+%D The definition command indicate that we can frame the footnote
+%D area. The footnotes themselves are treated as descriptions.
+%D
+%D \showsetup{definenote}
+%D
+%D It's sort of a custom to precede footnotes by a horizontal
+%D rule and although fancy rules like
+%D
+%D \starttyping
+%D \hbox to 10em{\hskip-3em\dotfill}
+%D \stoptyping
+%D
+%D Are quite ligitimate, we default to a simple one 20\% of the
+%D text width.
+
+\def\setupnotes
+ {\dodoubleargument\getparameters[\??vn]}
+
+\setupnotes
+ [\c!location=\v!page,
+ \c!way=\v!by\v!part,
+ \c!sectionnumber=\v!no,
+ %\c!conversion=,
+ \c!rule=\v!on,
+ \c!before=\blank,
+ \c!bodyfont=\v!small,
+ %\c!style=,
+ %\c!color=,
+ %\c!after=,
+ %\c!rulecolor=,
+ \c!rulethickness=\linewidth,
+ \c!frame=\v!off,
+ \c!margindistance=.5em,
+ \c!columndistance=1em,
+ \c!distance=.125em,
+ \c!align=\v!normal,
+ \c!tolerance=\v!tolerant,
+ \c!split=\v!tolerant,
+ %\c!width=\makeupwidth,
+ %\c!width=\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi,
+ \c!width=\defaultnotewidth,
+ \c!height=\textheight,
+ \c!numbercommand=\high,
+ \c!command=\noteparameter\c!numbercommand, % downward compatible
+ \c!separator=,% \@@koseparator,
+ \c!textcommand=\high,
+ \c!textstyle=\tx,
+ %\c!textcolor=,
+ \c!interaction=\v!yes,
+ %\c!factor=,
+ %\c!scope=, % \v!text \v!page
+\c!prefixconnector=.,
+\c!prefix=\v!no,
+ \c!next=\autoinsertnextspace, % new, experimental with startnotes
+ \c!n=1]
+
+\def\@@defaultnotedefloc{\v!inleft}
+\def\@@defaultnotedefdis{\!!zeropoint}
+
+% also s!root
+%
+% \definedescription
+% [\??vn\??vn]
+% [\c!location=\@@defaultnotedefloc,
+% \c!distance=\@@defaultnotedefdis,
+% \c!width=\v!fit,
+% \c!headstyle=\noteparameter\c!style,
+% \c!headcolor=\noteparameter\c!color,
+% \c!before=,
+% \c!after=]
+
+\def\startnotedef{\resetdescriptions\csname\e!start\??vn\??vn\currentnote\endcsname}
+\def\stopnotedef {\csname\e!stop \??vn\??vn\currentnote\endcsname}
+
+\def\currentnoteins{\csname\??vn:\currentnote\endcsname}
+
+\newtoks \everysetupnote
+
+\def\definenote
+ {\dodoubleempty\dodefinenote}
+
+\def\dodefinenote[#1][#2]%
+ {\edef\currentnote{#1}%
+ \ifcsname\??vn:\currentnote\endcsname\else
+ \@EA\installinsertion\csname\??vn:\currentnote\endcsname\relax
+ \appendtoks\doprocesssomenote{#1}\to\tobeprocessednotes
+ \fi
+ \defineenumeration % description
+ [\currentnote]
+ [\c!location=\@@defaultnotedefloc,
+ \c!distance=\@@defaultnotedefdis,
+ \c!width=\v!fit,
+ \c!headstyle=\noteparameter\c!style,
+ \c!headcolor=\noteparameter\c!color,
+\s!handler=\v!note,
+ \c!text=,
+ \c!before=,
+ \c!after=]%
+ \setupenumerations
+ [\currentnote]
+ [\s!parent=\??vn\currentnote,
+ \c!number=\v!yes] % no inheritance from decriptions which is okay
+ \presetlocalframed
+ [\??vn\currentnote]%
+ \getparameters
+ [\??vn\currentnote]
+ [\s!parent=\??vn,#2]%
+ \definestructurecounter
+ [\currentnote]%
+ \ctxlua{structure.notes.define("\currentnote","insert",\number\csname\??vn:\currentnote\endcsname)}%
+ \the\everysetupnote}
+
+\let\setupnotedefinition\setupenumerations
+
+\appendtoks
+ \setupenumerations[\currentnote][]%
+\to \everysetupnote
+
+\def\setupnote
+ {\dodoubleempty\dosetupnote}
+
+\def\dosetupnote[#1][#2]%
+ {\edef\currentnote{#1}%
+ \ifsecondargument
+ \getparameters[\??vn\currentnote][#2]%
+ \the\everysetupnote
+ \fi
+ \dochecknote}
+
+\appendtoks
+ \letvalue{\??vn\c!rule:\currentnote}\normalnoterule % hm
+\to \everysetupnote
+
+\appendtoks
+ \processaction
+ [\noteparameter\c!rule]
+ [ \v!on=>\letvalue{\??vn\c!rule:\currentnote}\normalnoterule,
+ \v!off=>\letvalue{\??vn\c!rule:\currentnote}\relax,
+ \s!default=>\letvalue{\??vn\c!rule:\currentnote}\relax,
+ \s!unknown=>\setvalue{\??vn\c!rule:\currentnote}{\noteparameter\c!rule}]%
+\to \everysetupnote
+
+\appendtoks
+ \processaction % todo
+ [\noteparameter\c!split]
+ [ \v!tolerant=>\notepenalty\zeropoint,
+ \v!strict=>\notepenalty9999,
+ \v!verystrict=>\notepenalty\maxdimen,
+ \s!default=>\notepenalty\zeropoint,
+ \s!unknown=>\notepenalty\commalistelement]%
+\to \everysetupnote
+
+%D The following switch can be used to disable limiting the
+%D height of the footnote area, something that is needed in
+%D multi column balancing. Use this switch with care.
+
+\newif\ifnotelimit \notelimittrue % shared
+
+% bottomnotes endnotes
+% clevernotes
+
+\appendtoks
+ \doifsomething{\noteparameter\c!factor}
+ {\ifnum\noteparameter\c!factor<\zerocount\else
+ \count\currentnoteins\noteparameter\c!factor
+ \fi}%
+\to \everysetupnote
+
+% compatibility (will go away)
+
+\newif\ifendnotes
+\newif\ifbottomnotes
+
+% locations:
+
+\def\s!noteloc{nodeloc} % 1=page 2=columns 3=lastcolumn 4=firstcolumn 5=none
+\def\s!notepos{nodepos} % 0=nothing 1=high 2=bottom
+\def\s!notefmt{nodefmt} % 1 text
+\def\s!notecol{nodecol}
+
+\def\clevernotes % compatibility hack
+ {\numexpr\ifcase\noteparameter\s!noteloc\or0\or2\or2\or1\else0\fi\relax}
+
+\def\setnotelocation #1{\expandafter\chardef\csname\??vn\currentnote\s!noteloc\endcsname#1\relax}
+\def\setnoteposition #1{\expandafter\chardef\csname\??vn\currentnote\s!notepos\endcsname#1\relax}
+\def\setnoteformatting#1{\expandafter\chardef\csname\??vn\currentnote\s!notefmt\endcsname#1\relax}
+\def\setnotecolumns #1{\expandafter\chardef\csname\??vn\currentnote\s!notecol\endcsname#1\relax}
+
+\def\currentnofcolumns{\@@kln}
+
+\def\dochecknote
+ {% node states
+ \setnotelocation\plusone
+ \setnoteposition\plustwo
+ \processallactionsinset
+ [\noteparameter\c!location]
+ [ \v!page=>\setnotelocation \plusone,
+ \v!columns=>\setnotelocation \plustwo,
+ \v!firstcolumn=>\setnotelocation \plusthree,
+ \v!lastcolumn=>\setnotelocation \plusfour,
+ \v!none=>\setnotelocation \plusfive,
+ \v!text=>\setnotelocation \plusfive
+ \setnoteformatting\plusone, % test
+ \v!high=>\setnoteposition \plusone,
+ \v!bottom=>\setnoteposition \plustwo]%
+ % compatibility hack
+ \ifnum\noteparameter\s!noteloc=\plusfive \endnotestrue \else \endnotesfalse \fi
+ \ifnum\noteparameter\s!notepos=\plustwo \bottomnotestrue \else \bottomnotesfalse \fi
+ % set column multiplier
+ \edef\currentnotenofcolumns{\noteparameter\c!n}%
+ \ifx\currentnotenofcolumns\empty
+ \let\currentnotenofcolumns\!!plusone
+ \fi
+ \ifcase\noteparameter\s!noteloc\or
+ % page
+ \scratchcounter \currentnotenofcolumns
+ \or
+ % columns
+ \scratchcounter\ifnum\currentnofcolumns=\zerocount \plusone \else \currentnotenofcolumns \fi \relax
+ \or
+ % firstcolumn
+ \scratchcounter\plusone
+ \or
+ % lastcolumn
+ \scratchcounter\plusone
+ \or
+ % text
+ \scratchcounter\currentnotenofcolumns
+ \fi
+ % column factor
+ \global\count\currentnoteins\plusthousand
+ \global\count\currentnoteins\numexpr\plusthousand/\scratchcounter\relax
+ % maximize height
+ \ifnotelimit
+ \global\dimen\currentnoteins\dimexpr\noteparameter\c!height*\scratchcounter\relax
+ \fi
+ % distance
+ \begingroup
+ \setbox\scratchbox\vbox
+ {\forgetall
+ \noteparameter\c!before
+ \placenoterule
+ \noteparameter\c!after}%
+ \global\skip\currentnoteins\ht\scratchbox
+ \endgroup
+ % play safe
+ \ifnum\noteparameter\s!noteloc=\plusfive
+ \ctxlua{structure.notes.setstate("\currentnote","store")}%
+ % text notes (e.g. end notes) but we don't use inserts anyway
+ \global\dimen\currentnoteins\maxdimen
+ \global\count\currentnoteins\zerocount
+ \global\skip \currentnoteins\zeropoint
+ \fi}
+
+\def\checknotes
+ {\processnotes\dochecknote}
+
+% D When \type{n} exceeds~1, footnotes are typeset in
+% D multi||columns, using the algoritm presented on page~397
+% D of \TEX book. Footnotes can be places on a per page basis
+% D or whereever suitable. When we set~\type{n} to~0, we get a
+% D rearanged paragraph, typeset by the algoritms on pages 398
+% D and~389 (at least in \MKII). We definitely did not reinvent
+% D that wheel.
+
+% Example of using factor:
+%
+% \definenote[mynote][way=bypage,location=text,width=\marginwidth,rule=,before=,factor=0]
+% \setuplayout[backspace=5cm,margin=3cm,margindistance=.5cm,width=middle]
+% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][]
+% \starttext
+% \dorecurse{10}{test \mynote{one one one one one one} \input zapf \mynote{one one one one one one} }
+% \stoptext
+
+%D The noterule can be a graphic and therefore calling this
+%D setup macro at every skipswitch is tricky (many many MP
+%D runs). Let's just reserve a few points, that probably match
+%D those of the stretch component.
+
+\def\placenoterule
+ {\getvalue{\??vn\c!rule:\currentnote}}
+
+\def\normalnoterule
+ {\ifvmode
+ \color
+ [\noteparameter\c!rulecolor]
+ {\hrule\!!width .2\hsize\!!height\noteparameter\c!rulethickness\!!depth \zeropoint}%
+ \kern\strutdepth
+ \fi}
+
+\ifx\setnotehsize\undefined
+
+ \def\setnotehsize{\hsize\noteparameter\c!width\relax} % can be overloaded
+
+\fi
+
+%D The formatting depends on the width of the table, so we
+%D have to set \type {n} to zero.
+%D
+%D \starttyping
+%D \startbuffer
+%D \bTABLE
+%D \bTR \bTD one \footnote{\dorecurse{10}{abcd }} \eTD \bTD two \eTD \eTR
+%D \bTR \bTD three fout five six seven eight nine \eTD \bTD ten \eTD \eTR
+%D \eTABLE
+%D \stopbuffer
+%D
+%D \startlocalfootnotes[n=0,location={text,none}]
+%D \placelegend[n=2]{\getbuffer}{\placelocalfootnotes}
+%D \stoplocalfootnotes
+%D \stoptyping
+
+%D \macros
+%D {footnote}
+%D
+%D A footnote can have a reference as optional argument and
+%D therefore its formal specification looks like:
+%D
+%D \showsetup{footnote}
+%D
+%D This command has one optional command: the reference. By
+%D saying \type{[-]} the number is omitted. The footnote
+%D command is not that sensitive to spacing, so it's quite
+%D legal to say:
+%D
+%D \startbuffer
+%D Users of \CONTEXT\ must keep both feet \footnote{Given they
+%D have two.} on the ground and not get confused \footnote{Or
+%D even crazy.} by all those obscure \footnote{But fortunately
+%D readable.} parameters.
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D When setting the \type{conversion} to \type{set 2} we get
+%D something like:
+%D
+%D \bgroup
+%D \startnarrower
+%D \setupfootnotes[conversion=set 1]
+%D \getbuffer
+%D \stopnarrower
+%D \egroup
+%D
+%D Typesetting footnotes is, at least for the moment, disabled
+%D when reshaping boxes.
+%D
+%D The additional macro \type {\footnotetext} and the
+%D associated \type {\note} macro were implemented at
+%D request of users on the mailing list and a suggestion by
+%D taco to split of the symbol placement. I decided to
+%D merge this functionality with the existing \type {\note}
+%D functionality.
+
+%D The next implementation runs on top of enumerations (only in \MKIV).
+
+% TODO: \ifnotesenabled
+
+\newif\ifnotesymbol \notesymboltrue
+
+\def\setnote [#1]{\getvalue{#1}}
+\def\setnotetext[#1]{\global\settrue\skipnoteplacement\getvalue{#1}}
+
+\def\domovednote#1#2#3#4%
+ {\ifcase\ctxlua{structure.notes.deltapage("#1",#2)}\or\symbol[#3]\or\symbol[#4]\fi}
+
+\setvalue{\??dd:\v!note:\s!handler }{\@@doenumerationhandler}
+\setvalue{\??dd:\v!note:\s!handler:\s!do }{\@@somenotedescription}
+\setvalue{\??dd:\v!note:\s!handler:\s!start}{\@@startsomenotedescription}
+
+\def\@@somenotedescription {\@@notemakedescription}
+\def\@@startsomenotedescription{\@@notemakedescription}
+
+\newconditional\skipnoteplacement
+
+\def\@@notemakedescription[#1]#2#3% todo ... proper [key=value] etc
+ {\begingroup
+ \doenumerationcheckconditions
+ \let\currentnote\currentdescriptionmain
+ \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#3},\c!bookmark=,][]%
+ \xdef\currentnotenumber{\ctxlua{structure.notes.store("\currentnote",\currentdescriptionnumberentry)}}%
+ \settrue\processingnote
+ \ifconditional\skipnoteplacement
+ \globallet\lastnotesymbol\dolastnotesymbol
+ \else
+ \iftypesettinglines % otherwise problems with \type <crlf> {xxx}
+ \ignorelines % makes footnotes work in \startlines ... \stoplines
+ \fi
+ \ifnotesymbol
+ \dolastnotesymbol
+ \else
+ \unskip\unskip
+ \globallet\lastnotesymbol\dolastnotesymbol
+ \fi
+ \fi
+ \ifconditional\postponingnotes
+ \global\settrue\postponednote
+ \else
+ \handlenoteinsert\currentnote\currentnotenumber
+ \fi
+ \ifconditional\skipnoteplacement \else
+ \kern\notesignal\relax % \relax is needed to honor spaces
+ \iftrialtypesetting \else \global\setfalse\skipnoteplacement \fi
+ \fi
+ \endgroup}
+
+\def\dolastnotesymbol{\typesetsomenotesymbol\currentnote\currentnotenumber}
+
+\def\dotypesetsomenotesymbol#1#2%
+ {\dodonotesymbol
+ {\synchronizesomenotesymbol{#1}{#2}%
+ \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry
+ \domovednote{#1}{#2}\v!previouspage\v!nextpage}}
+
+\def\typesetsomenotesymbol#1#2%
+ {\removeunwantedspaces
+ \doifitalicelse\/\donothing % Charles IV \footnote{the fourth}
+ \ifdim\lastkern=\notesignal
+ \dodonotesymbol{\kern\noteparameter\c!distance}% gets the font right, hack !
+ \fi
+ \nobreak
+ \doifelse{\noteparameter\c!interaction}\v!no
+ {\dotypesetsomenotesymbol{#1}{#2}}
+ {\gotobox{\dotypesetsomenotesymbol{#1}{#2}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f:
+ \globallet\lastnotesymbol\relax}
+
+\def\currentnotedescriptiontext % todo: can be other number
+ {\ctxlua{structure.notes.title("\currentnote",\currentdescriptionnumberentry)}}
+
+\def\currentnoteenumerationfullnumber
+ {\doifelse{\noteparameter\c!interaction}\v!no
+ {\docurrentnoteenumerationfullnumber}%
+ {\gotobox
+ {\docurrentnoteenumerationfullnumber}%
+ [page(\ctxlua{structure.notes.getsymbolpage("\currentnote",\currentdescriptionnumberentry)})]}}
+
+\def\docurrentnoteenumerationfullnumber
+ {\noteparameter\c!numbercommand
+ {\ctxlua{structure.notes.number("\currentnote",\currentdescriptionnumberentry)}%
+ \domovednote\currentdescription\currentdescriptionnumberentry\v!nextpage\v!previouspage}}
+
+\def\synchronizesomenotesymbol#1#2% called more often than needed
+ {\expanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2)}}}
+
+\def\handlenoteinsert#1#2%
+ {\begingroup
+ \edef\currentnote{#1}%
+ \the\everybeforenoteinsert
+ \insert\currentnoteins\bgroup
+ \the\everyinsidenoteinsert
+ \handlenoteitself{#1}{#2}%
+ \egroup
+ \the\everyafternoteinsert
+ \endgroup}
+
+\def\handlenoteitself#1#2% tg, id
+ {\edef\currentdescription{#1}%
+ \edef\currentnote{#1}%
+ \edef\currentdescriptionnumberentry{#2}%
+ \let\currentdescriptiontext\currentnotedescriptiontext
+ \let\currentenumerationfullnumber\currentnoteenumerationfullnumber
+ \dostartstoreddescription\begstrut\currentnotedescriptiontext\endstrut\dostopstoreddescription}
+
+\def\dostartstoreddescription
+ {\bgroup\@@dostartdescriptionindeed}
+
+\def\dostopstoreddescription
+ {\@@stopdescription}
+
+%D The main typesetting routine is more or less the same as the
+%D \PLAIN\ \TEX\ one, except that we only handle one type while
+%D \PLAIN\ also has something \type{\v...}. In most cases
+%D footnotes can be handled by a straight insert, but we do so
+%D by using an indirect call to the \type{\insert} primitive.
+
+%D Making footnote numbers active is not always that logical,
+%D Making footnote numbers active is not always that logical,
+%D especially when we keep the reference and text at one page.
+%D On the other hand we need interactivity when we refer to
+%D previous notes or use end notes. Therefore we support
+%D interactive footnote numbers in two ways \footnote{This
+%D feature was implemented years after we were able to do so,
+%D mainly because endnotes had to be supported.} that is,
+%D automatically (vise versa) and by user supplied reference.
+
+\newcount\internalnotereference
+
+\let\startpushnote=\relax
+\let\stoppushnote =\relax
+
+\newsignal\notesignal
+\newcount \notepenalty
+
+\notepenalty=0 % needed in order to split in otrset
+
+\newconditional\processingnote
+\newconditional\postponednote
+
+\newtoks\everybeforenoteinsert
+\newtoks\everyinsidenoteinsert
+\newtoks\everyafternoteinsert
+
+\appendtoks
+ \let\doflushnotes\relax
+ \let\postponenotes\relax
+ \forgetall
+\to \everybeforenoteinsert
+
+\appendtoks
+ \doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
+ \penalty\notepenalty
+ \forgetall
+ \setnotebodyfont
+ \redoconvertfont % to undo \undo calls in in headings etc
+ \splittopskip\strutht % not actually needed here
+ \splitmaxdepth\strutdp % not actually needed here
+ \leftmargindistance\noteparameter\c!margindistance
+ \rightmargindistance\leftmargindistance
+ \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
+ \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
+ \fi
+\to \everyinsidenoteinsert
+
+\let\lastnotesymbol\relax
+
+%D \macros
+%D {note}
+%D
+%D Refering to a note is accomplished by the rather short
+%D command:
+%D
+%D \showsetup{note}
+%D
+%D This command is implemented rather straightforward as:
+
+\def\notesymbol
+ {\dodoubleempty\donotesymbol}
+
+\def\donotesymbol[#1][#2]%
+ {\bgroup
+ \ifnotesenabled
+ \edef\currentnote{#1}%
+ \ifsecondargument
+ \unskip
+ \dodonotesymbol{\in[#2]}%
+ \else
+ \dodonotesymbol\lastnotesymbol
+ \fi
+ \fi
+ \egroup}
+
+\def\dodonotesymbol#1%
+ {\noteparameter\c!textcommand{\dosetnoteattributes\c!textstyle\c!textcolor#1}}
+
+%D Normally footnotes are saved as inserts that are called upon
+%D as soon as the pagebody is constructed. The footnote
+%D insertion routine looks just like the \PLAIN\ \TEX\ one,
+%D except that we check for the end note state.
+
+% testcase for split bottom alignment see (a) below
+%
+% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}}
+
+\def\placenoteinserts
+ {\processnotes\doplacenoteinserts}
+
+\def\unvboxed {\ifvmode\unvbox \else\box \fi}
+\def\unvcopied{\ifvmode\unvcopy\else\copy\fi}
+
+\def\doplacenoteinserts
+ {\relax\ifdim\ht\currentnoteins>\zeropoint\relax
+ \ifnum\noteparameter\s!noteloc=\plusfive
+ \else
+ \endgraf
+ \ifvmode
+ \whitespace
+ \noteparameter\c!before
+ \fi
+ \placenoterule % alleen in ..mode
+ \bgroup
+ \setnotebodyfont
+ \setbox\scratchbox\hbox
+ {% this should be checked, smells like a mix-up
+ % does not split: \ifcase\noteparameter\c!n\unvbox\else\box\fi\currentnoteins
+ \ifcase\noteparameter\c!n\relax
+ \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins
+ \or
+ \iftrialtypesetting\copy\else\box\fi\currentnoteins
+ \obeydepth % (a) added , since split footnotes will not align properly
+ \else
+ \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins
+ \fi}%
+ \setbox\scratchbox\hbox
+ {\localframed
+ [\??vn\currentnote]
+ [\c!width=\v!fit,
+ \c!height=\v!fit,
+ \c!strut=\v!no,
+ \c!offset=\v!overlay]
+ {\ifdim\dp\scratchbox=\zeropoint % this hack is needed because \vadjust
+ \hbox{\lower\strutdp\box\scratchbox}% % in margin number placement
+ \else % hides the (always) present depth
+ \box\scratchbox
+ \fi}}%
+ \setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}%
+ \dp\scratchbox\strutdepth % so we know that it has the note bodyfont depth
+ \box\scratchbox
+ \egroup
+ \endgraf
+ \ifvmode
+ \noteparameter\c!after
+ \fi
+ \fi
+ \fi}
+
+%D Supporting end notes is surprisingly easy. Even better, we
+%D can combine this feature with solving the common \TEX\
+%D problem of disappearing inserts when they're called for in
+%D deeply nested boxes. The general case looks like:
+%D
+%D \starttyping
+%D \postponenotes
+%D \.box{whatever we want with footnotes}
+%D \flushnotes
+%D \stoptyping
+%D
+%D This alternative can be used in headings, captions, tables
+%D etc. The latter one sometimes calls for notes local to
+%D the table, which can be realized by saying
+%D
+%D \starttyping
+%D \setlocalfootnotes
+%D some kind of table with local footnotes
+%D \placelocalfootnotes
+%D \stoptyping
+%D
+%D Postponing is accomplished by simply redefining the (local)
+%D insert operation. A not too robust method uses the
+%D \type{\insert} primitive when possible. This method fails in
+%D situations where it's not entirely clear in what mode \TEX\
+%D is. Therefore the auto method can is to be overruled when
+%D needed.
+
+\newconditional\postponingnotes
+
+% we need a proper state: normal, postponing, flushing
+
+\def\postponenotes
+ {\ifconditional\postponingnotes\else
+ \global\settrue\postponingnotes
+ \ctxlua{structure.notes.postpone()}%
+ \fi}
+
+% \def\flushnotes
+% {\ifconditional\processingnote \else
+% \ifconditional\postponednote
+% \ifinner \else
+% \ifinpagebody \else
+% %ifvmode % less interference, but also less secure
+% \doflushnotes
+% %fi
+% \fi
+% \fi
+% \fi
+% \fi}
+
+\def\flushnotes
+ {\ifconditional\postponednote
+ \flushnotesindeed
+ \fi}
+
+\def\flushnotesindeed
+ {\ifconditional\processingnote \else
+ \ifinner \else
+ \ifinpagebody \else
+ %ifvmode % less interference, but also less secure
+ \doflushnotes
+ %fi
+ \fi
+ \fi
+ \fi}
+
+\def\doflushnotes % also called directly, \ifvoid is needed !
+ {\begingroup
+ \let\doflushnotes\relax
+ \let\postponenotes\relax
+ \ifconditional\processingnote \else
+ \ifconditional\postponednote
+ \processnotes\dodoflushnotes
+ \global\setfalse\postponednote
+ \setfalse\postponingnotes
+ \fi
+ \fi
+ \endgroup}
+
+\def\dodoflushnotes % per class, todo: handle endnotes here
+ {%\writestatus{notes}{flushing \currentnote}%
+ \global\setfalse\postponingnotes
+ \ctxlua{structure.notes.flush("\currentnote","postpone")}}
+
+%D \macros
+%D {startlocalfootnotes,placelocalfootnotes}
+%D
+%D The next two macros can be used in for instance tables, as
+%D we'll demonstrate later on.
+%D
+%D \showsetup{startlocalfootnotes}
+%D \showsetup{placelocalfootnotes}
+
+% todo: compatibility mode: when first arg is assignment or missing, then all
+
+\newtoks\everyplacelocalnotes
+
+\appendtoks
+ \let\doflushnotes\relax
+ \let\postponenotes\relax
+\to \everyplacelocalnotes
+
+\def\defaultnotewidth{\makeupwidth} % {\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi}
+
+\def\startlocalnotes
+ {\dosingleempty\dostartlocalnotes}
+
+\def\dostartlocalnotes[#1]%
+ {\def\localnoteslist{#1}%
+ \processcommacommand[\localnoteslist]\dodostartlocalnotes}
+
+\def\stoplocalnotes
+ {\processcommacommand[\localnoteslist]\dodostoplocalnotes}
+
+\def\dodostartlocalnotes#1%
+ {\savestructurecounter[#1]%
+ \resetstructurecounter[#1]%
+ \ctxlua{structure.notes.save("#1","store")}}
+
+\def\dodostoplocalnotes#1%
+ {\restorestructurecounter[#1]%
+ \ctxlua{structure.notes.restore("#1")}}
+
+\def\placelocalnotes
+ {\dodoubleempty\doplacelocalnotes}
+
+\def\doplacelocalnotes[#1][#2]%
+ {\doif{\ctxlua{structure.notes.getstate("#1")}}{store}{\dodoplacelocalnotes{#2}{#1}}}
+
+\def\dodoplacelocalnotes#1#2% settings note
+ {\begingroup
+ \the\everyplacelocalnotes
+ % beware, we cannot trust setting \currentnote here
+ \getparameters[\??vn#2][\c!width=\v!fit,\c!height=\v!fit,\c!strut=\v!no,\c!offset=\v!overlay,#1]% we only need a selective one
+ \donotealternative{#2}%
+ \endgroup
+ \dochecknote} % we need to restore the old state
+
+%D These commands can be used like:
+%D
+%D \startbuffer
+%D \startlocalnotes[width=.3\hsize,n=0]
+%D \placetable
+%D {Some Table}
+%D \placeontopofeachother
+%D {\starttable[|l|r|]
+%D \HL
+%D \VL Nota\footnote{Bene} \VL Bene\footnote{Nota} \VL\SR
+%D \VL Bene\footnote{Nota} \VL Nota\footnote{Bene} \VL\SR
+%D \HL
+%D \stoptable}
+%D {\placelocalnotes}
+%D \stoplocalnotes
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Because this table placement macro expect box content, and
+%D thanks to the grouping of the local footnotes, we don't need
+%D additional braces.
+%D
+%D \getbuffer
+
+%D \macros
+%D {placefootnotes}
+%D
+%D We still have no decent command for placing footnotes
+%D somewhere else than at the bottom of the page (for which no
+%D user action is needed). Footnotes (endnotes) can be
+%D placed by using
+%D
+%D \showsetup{placefootnotes}
+
+\def\placebottomnotes
+ {\processnotes\placenoteinserts}
+
+\def\placenotes
+ {\dodoubleempty\doplacenotes}
+
+\def\doplacenotes[#1][#2]%
+ {\processcommalist[#1]{\dodoplacenotes{#2}}}
+
+\def\dodoplacenotes#1#2% settings note
+ {\edef\currentnote{#2}%
+ \doifelse{\ctxlua{structure.notes.getstate("#1")}}{store}
+ \dodoplacelocalnotes
+ \dodoplaceglobalnotes
+ {#1}{#2}}
+
+\def\dodoplaceglobalnotes#1#2%
+ {\begingroup
+ \setupnote[#2][#1]%
+ \doplacenoteinserts
+ \endgroup
+ \the\everysetupnote} % to be checkes
+
+%D Placement
+
+\long\def\installnotealternative#1#2%
+ {\setvalue{\??vn:\c!alternative:#1}{#2}}
+
+\def\doifnotescollected#1%
+ {\ctxlua{structure.notes.doifcontent("#1")}}
+
+\def\donotealternative#1%
+ {\edef\currentnote{#1}%
+ \doifnotescollected\currentnote
+ {\endgraf
+ \ifvmode
+ \whitespace
+ \noteparameter\c!before
+ \fi
+ \begingroup
+ \setnotebodyfont
+ \getvalue{\??vn:\c!alternative:\noteparameter\c!alternative}%
+ \endgroup
+ \ifvmode
+ \noteparameter\c!after
+ \fi}}
+
+\setvalue{\??vn:\c!alternative:}{\getvalue{\??vn:\c!alternative:\v!none}}
+
+%D A stupid alternative is also provided:
+%D
+%D \starttyping
+%D \setupfootnotes[location=text,alternative=none]
+%D \stoptyping
+
+\def\flushlocalnotes#1{\ctxlua{structure.notes.flush("#1","store")}}
+
+\installnotealternative \v!none
+ {\flushlocalnotes\currentnote}
+
+\installnotealternative \v!grid % test if n > 0
+ {\snaptogrid\hbox
+ {\localframed
+ [\??vn\currentnote]
+ {\flushlocalnotes\currentnote}}}
+
+\installnotealternative \v!fixed % test if n > 0
+ {\localframed
+ [\??vn\currentnote]
+ {\flushlocalnotes\currentnote}}
+
+\installnotealternative \v!columns % redundant
+ {\localframed
+ [\??vn\currentnote]
+ {\edef\currentnotewidth{\noteparameter\c!width}%
+ \doifdimensionelse\currentnotewidth\donothing
+ {\edef\currentnotewidth{\the\hsize}}%
+% \setupinmargin[\c!align=\v!left]%
+ \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\currentnotewidth]%
+ \flushlocalnotes\currentnote
+ \stopsimplecolumns}}
+
+%D \macros
+%D {fakenotes}
+
+ \def\fakenotes
+ {\ifhmode\endgraf\fi\ifvmode
+ \calculatetotalclevernoteheight
+ \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi
+ \fi}
+
+ \def\fakepagenotes
+ {\ifhmode\endgraf\fi\ifvmode
+ \calculatetotalpagenoteheight
+ \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi
+ \fi}
+
+ \newdimen\totalnoteheight
+
+ \def\doaddtototalnoteheight#1%
+ {\ifdim\ht#1>\zeropoint
+ \advance\totalnoteheight\ht #1%
+ \advance\totalnoteheight\skip#1%
+ \fi}
+
+ \def\docalculatetotalnoteheight
+ {\ifcase\clevernotes % tricky here ! ! ! to be sorted out ! ! !
+ \doaddtototalnoteheight\currentnoteins
+ \else
+ \doaddtototalnoteheight\currentbackupnoteins
+ \fi}
+
+ \def\docalculatetotalclevernoteheight
+ {\ifcase\clevernotes \else % tricky here ! ! ! to be sorted out ! ! !
+ \doaddtototalnoteheight\currentnoteins
+ \fi}
+
+ \def\docalculatetotalpagenoteheight
+ {\doaddtototalnoteheight\currentnoteins}
+
+ \def\calculatetotalnoteheight {\totalnoteheight\zeropoint\processnotes\docalculatetotalnoteheight}
+ \def\calculatetotalclevernoteheight{\totalnoteheight\zeropoint\processnotes\docalculatetotalclevernoteheight}
+ \def\calculatetotalpagenoteheight {\totalnoteheight\zeropoint\processnotes\docalculatetotalpagenoteheight}
+
+ \newif\ifnotespresent
+
+ \def\dochecknotepresence
+ {\ifdim\ht\currentnoteins>\zeropoint
+ \notespresenttrue
+ \fi}
+
+ \def\checknotepresence
+ {\notespresentfalse
+ \processnotes\dochecknotepresence}
+
+%D Now how can this mechanism be hooked into \CONTEXT\ without
+%D explictly postponing footnotes? The solution turned out to
+%D be rather simple:
+%D
+%D \starttyping
+%D \everypar {...\flushnotes...}
+%D \neverypar {...\postponenotes}
+%D \stoptyping
+%D
+%D and
+%D
+%D \starttyping
+%D \def\ejectinsert%
+%D {...
+%D \flushnotes
+%D ...}
+%D \stoptyping
+%D
+%D We can use \type{\neverypar} because in most commands
+%D sensitive to footnote gobbling we disable \type{\everypar}
+%D in favor for \type{\neverypar}. In fact, this footnote
+%D implementation is the first to use this scheme.
+
+%D This is a nasty and new secondary footnote flusher. It
+%D can be hooked into \type {\everypar} like:
+%D
+%D \starttyping
+%D \appendtoks \synchronizenotes \to \everypar
+%D \stoptyping
+
+ % \def\dosynchronizenotes
+ % {\ifvoid\currentnoteins\else\insert\currentnoteins{\unvbox\currentnoteins}\fi}
+ %
+ % \def\synchronizenotes
+ % {\processnotes\dosynchronizenotes}
+
+\let\synchronizenotes\relax
+
+%D When typesetting footnotes, we have to return to the
+%D footnote specific bodyfont size, which is in most cases derived
+%D from the global document bodyfont size. In the previous macros
+%D we already used a footnote specific font setting macro.
+
+\def\setnotebodyfont
+ {\let\setnotebodyfont\relax
+ \restoreglobalbodyfont
+ \switchtobodyfont[\noteparameter\c!bodyfont]%
+ \setuptolerance[\noteparameter\c!tolerance]%
+ \setupalign[\noteparameter\c!align]}
+
+%D The footnote mechanism defaults to a traditional one
+%D column way of showing them. By default we precede them by
+%D a small line.
+
+\ifx\v!endnote\undefined \def\v!endnote{endnote} \fi
+
+\definenote [\v!footnote]
+\definenote [\v!endnote ] [\c!location=\v!none] % else no break
+
+%D Compatibility macros:
+
+ \def\setupfootnotedefinition{\setupnotedefinition [\v!footnote]}
+ \def\setupfootnotes {\setupnote [\v!footnote]}
+%unexpanded \def\footnote {\setnote [\v!footnote]}
+\unexpanded \def\footnotetext {\setnotetext [\v!footnote]}
+ %def\note {\dodoubleempty\notesymbol [\v!footnote]} % alleen footnote
+ \def\placefootnotes {\dodoubleempty\doplacefootnotes [\v!footnote]}
+ \def\placelocalfootnotes {\dodoubleempty\doplacelocalfootnotes[\v!footnote]}
+ \def\startlocalfootnotes {\startlocalnotes [\v!footnote]} % alleen footnote
+ \def\stoplocalfootnotes {\stoplocalnotes }
+ \def\flushfootnotes {\flushnotes}
+ \def\doflushfootnotes {\doflushnotes}
+
+\def\doplacefootnotes [#1][#2]{\ifsecondargument\placenotes [#1][#2,\c!height=\textheight]\else\placenotes [#1]\fi}
+\def\doplacelocalfootnotes[#1][#2]{\ifsecondargument\placelocalnotes[#1][#2,\c!height=\textheight]\else\placelocalnotes[#1]\fi}
+
+\def\note{\dodoubleempty\donote}
+
+\def\donote[#1][#2]{\ifsecondargument\donotesymbol[#1][#2]\else\secondargumenttrue\donotesymbol[\v!footnote][#1]\fi}
+
+%D New trickery:
+
+\def\ownnotesymbol#1% #1 gets number passed
+ {\executeifdefined{\??vn::\currentnote}\empty}
+
+\def\setnotesymbol[#1]#2#3%
+ {\prewordbreak % prevent lookback
+ \setgvalue{\??vn::#1}{#3}
+ \dolastnotesymbol}
+
+\def\ownnote[#1]#2#3#4%
+ {\setnotesymbol[#1]{#2}{#3}%
+ \setnotetext [#1]{#4}}
+
+\defineconversion
+ [ownnote]
+ [\ownnotesymbol]
+
+\protect \endinput
diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua
new file mode 100644
index 000000000..8918346c6
--- /dev/null
+++ b/tex/context/base/strc-num.lua
@@ -0,0 +1,457 @@
+if not modules then modules = { } end modules ['strc-num'] = {
+ version = 1.001,
+ comment = "companion to strc-num.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+local next, type = next, type
+local texsprint = tex.sprint
+
+structure = structure or { }
+structure.helpers = structure.helpers or { }
+structure.sections = structure.sections or { }
+structure.counters = structure.counters or { }
+structure.documents = structure.documents or { }
+
+structure.counters = structure.counters or { }
+structure.counters.data = structure.counters.data or { }
+
+local helpers = structure.helpers
+local sections = structure.sections
+local counters = structure.counters
+local documents = structure.documents
+
+local variables = interfaces.variables
+
+-- state: start stop none reset
+
+local counterdata = counters.data
+local counterranges, tbs = { }, 0
+
+counters.collected = counters.collected or { }
+counters.tobesaved = counters.tobesaved or { }
+
+storage.register("structure/counters/data", structure.counters.data, "structure.counters.data")
+storage.register("structure/counters/tobesaved", structure.counters.tobesaved, "structure.counters.tobesaved")
+
+local collected, tobesaved = counters.collected, counters.tobesaved
+
+local function finalizer()
+ local ct = counters.tobesaved
+ for name, cd in next, counterdata do
+ local cs = tobesaved[name]
+ local data = cd.data
+ for i=1,#data do
+ local d = data[i]
+ local r = d.range
+ cs[i][r] = d.number
+ d.range = r + 1
+ end
+ end
+end
+
+local function initializer()
+ collected, tobesaved = counters.collected, counters.tobesaved
+end
+
+if job then
+ job.register('structure.counters.collected', structure.counters.tobesaved, initializer, finalizer)
+end
+
+local function constructor(t,s,name,i)
+ if s == "last" then
+ local cc = collected[name]
+ t.stop = (cc and cc[i] and cc[i][t.range]) or 0 -- stop is available for diagnostics purposes only
+ if t.offset then
+ return t.stop - t.step
+ else
+ return t.stop
+ end
+ elseif s == "first" then
+ if t.offset then
+ return t.start + t.step + 1
+ else
+ return t.start + 1
+ end
+ elseif s == "prev" or s == "previous" then
+ return math.max(t.first,t.number-1) -- todo: step
+ elseif s == "next" then
+ return math.min(t.last,t.number+1) -- todo: step
+ elseif s == "subs" then
+ local cc = collected[name]
+ t.subs = (cc and cc[i+1] and cc[i+1][t.range]) or 0
+ return t.subs
+ else
+ return nil -- was 0, but that is fuzzy in testing for e.g. own
+ end
+end
+
+local enhance = function()
+ for name, cd in next, counterdata do
+ local data = cd.data
+ for i=1,#data do
+ local ci = data[i]
+ setmetatable(ci, { __index = function(t,s) return constructor(t,s,name,i) end })
+ end
+ end
+ enhance = nil
+end
+
+local function allocate(name,i)
+ local cd = counterdata[name]
+ if not cd then
+ cd = {
+ level = 1,
+ numbers = nil,
+ state = interfaces.variables.start, -- true
+ data = { }
+ }
+ tobesaved[name] = { }
+ counterdata[name] = cd
+ end
+ cd = cd.data
+ local ci = cd[i]
+ if not ci then
+ ci = {
+ number = 0,
+ start = 0,
+ saved = 0,
+ step = 1,
+ range = 1,
+ offset = false,
+ -- via metatable: last, first, and for tracing:
+ stop = 0,
+ }
+ setmetatable(ci, { __index = function(t,s) return constructor(t,s,name,i) end })
+ cd[i] = ci
+ tobesaved[name][i] = { }
+ else
+ if enhance then enhance() end -- not stored in bytecode
+ end
+ return ci
+end
+
+local function savevalue(name,i)
+ local cd = counterdata[name].data[i]
+ local cs = tobesaved[name][i]
+ local cc = collected[name]
+ local cr = cd.range
+ local old = (cc and cc[i] and cc[i][cr]) or 0
+ cs[cr] = cd.number
+ cd.range = cr + 1
+ return old
+end
+
+function counters.define(name, start, counter) -- todo: step
+ local d = allocate(name,1)
+ d.start = start
+ if counter and counter > 0 then
+ d.counter = counter -- only for special purposes
+ end
+end
+
+function counters.trace(name)
+ local cd = counterdata[name]
+ if cd then
+ texsprint(format("[%s:",name))
+ local data = cd.data
+ for i=1,#data do
+ local d = data[i]
+ texsprint(format(" (%s: %s,%s,%s s:%s r:%s)",i,(d.start or 0),d.number or 0,d.last,d.step or 0,d.range or 0))
+ end
+ texsprint("]")
+ end
+end
+
+function counters.raw(name)
+ return counterdata[name]
+end
+
+function counters.compact(name,level,onlynumbers)
+ local cd = counterdata[name]
+--~ print(name,cd)
+ if cd then
+ local data = cd.data
+ local compact = { }
+ for i=1,level or #data do
+ local d = data[i]
+ if d.number ~= 0 then
+ compact[i] = (onlynumbers and d.number) or d
+ end
+ end
+ return compact
+ end
+end
+
+-- depends on when incremented, before or after (driven by d.offset)
+
+function counters.doifelse(name)
+ commands.doifelse(counterdata[name])
+end
+
+function counters.previous(name,n)
+ texsprint(allocate(name,n).previous)
+end
+
+function counters.next(name,n)
+ texsprint(allocate(name,n).next)
+end
+
+counters.prev = counters.previous
+
+function counters.current(name,n)
+ texsprint(allocate(name,n).number)
+end
+
+function counters.first(name,n)
+ texsprint(allocate(name,n).first)
+end
+
+function counters.last(name,n)
+ texsprint(allocate(name,n).last)
+end
+
+function counters.subs(name,n)
+ texsprint(counterdata[name].data[n].subs or 0)
+end
+
+function counters.setvalue(name,tag,value)
+ local cd = counterdata[name]
+ if cd then
+ cd[tag] = value
+ end
+end
+
+function counters.setstate(name,value) -- true/false
+ value = interfaces.variables[value]
+ if value then
+ counters.setvalue(name,"state",value)
+ end
+end
+
+function counters.setlevel(name,value)
+ counters.setvalue(name,"level",value)
+end
+
+function counters.setoffset(name,value)
+ counters.setvalue(name,"offset",value)
+end
+
+function counters.reset(name,n)
+ local cd = counterdata[name]
+ if cd then
+ for i=n or 1,#cd.data do
+ local d = cd.data[i]
+ savevalue(name,i)
+ d.number = d.start or 0
+ d.own = nil
+ -- if d.counter then tex.count[d.counter] = d.number end
+ end
+ cd.numbers = nil
+ end
+end
+
+function counters.set(name,n,value)
+ local cd = counterdata[name]
+ if cd then
+ local d = allocate(name,n)
+ d.number = value or 0
+ d.own = nil
+ -- if d.counter then tex.count[d.counter] = d.number end
+ end
+end
+
+local function check(name,data,start,stop)
+ for i=start or 1,stop or #data do
+ local d = data[i]
+ savevalue(name,i)
+ d.number = d.start or 0
+ d.own = nil
+ -- if d.counter then tex.count[d.counter] = d.number end
+ end
+end
+
+function counters.setown(name,n,value)
+ local cd = counterdata[name]
+ if cd then
+ local d = allocate(name,n)
+ d.own = value
+ d.number = (d.number or d.start or 0) + (d.step or 0)
+ if cd.level and cd.level > 0 then -- 0 is signal that we reset manually
+ check(name,data,n+1) -- where is check defined
+ end
+ end
+end
+
+function counters.restart(name,n,newstart)
+ local cd = counterdata[name]
+ if cd then
+ newstart = tonumber(newstart)
+ if newstart then
+ local d = allocate(name,n)
+ d.start = newstart
+ counters.reset(name,n)
+ end
+ end
+end
+
+function counters.save(name) -- or just number
+ local cd = counterdata[name]
+ if cd then
+ cd.saved = table.copy(cd.data)
+ end
+end
+
+function counters.restore(name)
+ local cd = counterdata[name]
+ if cd and cd.saved then
+ cd.data = cd.saved
+ cd.saved = nil
+ end
+end
+
+function counters.add(name,n,delta)
+ local cd = counterdata[name]
+ if cd and cd.state == interfaces.variables.start then
+ local data = cd.data
+ local d = allocate(name,n)
+ d.number = (d.number or d.start or 0) + delta*(d.step or 0)
+ if cd.level and cd.level > 0 then -- 0 is signal that we reset manually
+ check(name,data,n+1)
+ end
+ return d.number
+ end
+ return 0
+end
+
+function counters.check(level)
+ for _, v in next, counterdata do
+ if v.level == level then -- is level for whole counter!
+ local data = v.data
+ check(name,data)
+ end
+ end
+end
+
+function counters.get(name,n,key)
+ local d = allocate(name,n)
+ d = d and d[key]
+ if not d then
+ return 0
+ elseif type(d) == "function" then
+ return d()
+ else
+ return d
+ end
+end
+
+function counters.value(name,n) -- what to do with own
+ tex.write(counters.get(name,n or 1,'number') or 0)
+end
+
+function counters.converted(name,spec) -- name can be number and reference to storage
+ local cd
+ if type(name) == "number" then
+ cd = specials.retrieve("counter",name)
+ cd = cd and cd.counter
+ else
+ cd = counterdata[name]
+ end
+ if cd then
+ local vars = interfaces.variables
+ local spec = spec or { }
+ local numbers, ownnumbers = { }, { }
+ local reverse = spec.order == vars["reverse"]
+ local kind = spec.type or "number"
+ local v_first, v_next, v_previous, v_last = vars.first, vars.next, vars.previous, vars.last
+ local data = cd.data
+ for k=1,#data do
+ local v = data[k]
+ -- somewhat messy, what if subnr? only last must honour kind?
+ local vn
+ if v.own then
+ numbers[k], ownnumbers[k] = v.number, v.own
+ else
+ if kind == v_first then
+ vn = v.first
+ elseif kind == v_next then
+ vn = v.next
+ elseif kind == v_previous then
+ vn = v.prev
+ elseif kind == v_last then
+ vn = v.last
+ else
+ vn = v.number
+ if reverse then
+ local vf = v.first
+ local vl = v.last
+ if vl > 0 then
+ vn = vl - vn + 1 + vf
+ end
+ end
+ end
+ numbers[k], ownnumbers[k] = vn or v.number, nil
+ end
+ end
+ cd.numbers = numbers
+ cd.ownnumbers = ownnumbers
+ sections.typesetnumber(cd,'number',spec)
+ cd.numbers = nil
+ cd.ownnumbers = nil
+ end
+end
+
+-- move to strc-pag.lua
+
+function counters.analyse(name,counterspecification)
+ local cd = counterdata[name]
+ -- safeguard
+ if not cd then
+ return false, false, "no counter data"
+ end
+ -- section data
+ local sectiondata = sections.current()
+ if not sectiondata then
+ return cd, false, "not in section"
+ end
+ local references = sectiondata.references
+ if not references then
+ return cd, false, "no references"
+ end
+ local section = references.section
+ if not section then
+ return cd, false, "no section"
+ end
+ sectiondata = jobsections.collected[references.section]
+ if not sectiondata then
+ return cd, false, "no section data"
+ end
+ -- local preferences
+ local no = variables.no
+ if counterspecification and counterspecification.prefix == no then
+ return cd, false, "current spec blocks prefix"
+ end
+ -- stored preferences (not used)
+ if cd.prefix == no then
+ return cd, false, "entry blocks prefix"
+ end
+ -- sectioning
+ -- if sectiondata.prefix == no then
+ -- return false, false, "sectiondata blocks prefix"
+ -- end
+ -- final verdict
+ return cd, sectiondata, "okay"
+end
+
+function counters.prefixedconverted(name,prefixspec,numberspec)
+ local cd, prefixdata, result = counters.analyse(name,prefixspec)
+ if cd then
+ if prefixdata then
+ sections.typesetnumber(prefixdata,"prefix",prefixspec or false,cd or false)
+ end
+ counters.converted(name,numberspec)
+ end
+end
diff --git a/tex/context/base/strc-num.tex b/tex/context/base/strc-num.tex
new file mode 100644
index 000000000..8b723575b
--- /dev/null
+++ b/tex/context/base/strc-num.tex
@@ -0,0 +1,440 @@
+%D \module
+%D [ file=strc-num,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Basic Numbering,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Basic Numbering}
+
+\registerctxluafile{strc-num}{1.001}
+
+\unprotect
+
+% we need to rework this, i.e. clone like itm, des etc with \s!parent
+
+% numbering
+
+% \definestructurecounter[name]
+% \setupstructurecounter[name][wijze=,blok=,tekst=,plaats=,conversie=,start=]
+% \setstructurecounter[name]{value}
+% \resetstructurecounter[name]
+% \incrementstructurecounter[name]
+% \decrementstructurecounter[name]
+% \savestructurecounter[name]
+% \restorestructurecounter[name]
+% \convertedstructurecounter[name] % depricated: \getstructurecounter[name]
+% \rawstructurecounter[name]
+
+% private (defined in core-sec.tex)
+%
+% \nextstructurecounter[name][tag][reference]
+% \currentstructurecounter[name]
+
+% todo: better inheritane system
+
+\definesystemvariable {nn}
+
+\def\setupstructurecountering{\dodoubleempty\getparameters[\??nn]}
+
+\setupstructurecountering
+ [\c!way=\v!by\v!chapter,
+% \c!blockway=,
+% \c!prefixstopper=,
+\c!prefixconnector=.,
+\c!prefixsegments=\thenamedstructurecounterlevel\currentstructurecounter,
+\c!start=0,
+\c!state=\v!start,
+ \c!prefix=\v!yes,
+ \c!state=\v!start]
+
+% \letvalue{\??nn\s!empty}\empty
+
+\def\structurecounterparameter#1#2%
+ {\csname
+ \ifcsname\??nn#1#2\endcsname
+ \??nn#1#2%
+ \else\ifcsname\??nn\@@thestructurecounter{#1}#2\endcsname
+ \??nn\@@thestructurecounter{#1}#2%
+ \else\ifcsname\??nn#2\endcsname
+ \??nn#2%
+ \else
+ \s!empty
+ \fi\fi\fi
+ \endcsname}
+
+\def\@@thestructurecounter#1%
+ {\ifcsname\??nn#1\c!number\endcsname
+ \expandafter\@@thestructurecounter\csname\??nn#1\c!number\endcsname
+ \else
+ #1%
+ \fi}
+
+% \def\structurecounterparameter #1#2{\csname\dostructurecounterparameter{\??nn#1}#2\endcsname}
+% \def\dostructurecounterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructurecounterparentparameter\csname#1\s!number\endcsname#2\fi}
+% \def\dostructurecounterparentparameter#1#2{\ifx#1\relax\s!empty\else\dostructurecounterparameter#1#2\fi}
+
+%
+
+\def\definestructurecounter
+ {\dodoubleempty\dodefinestructurecounter}
+
+\def\dodefinestructurecounter[#1][#2]%
+ {\doifassignmentelse{#2}
+ {\dododefinestructurecounter[#1][#2]}
+ {\doifelsenothing{#2}
+ {\dododefinestructurecounter[#1][]}
+ {\donodefinestructurecounter[#1][#2]}}}
+
+\def\dododefinestructurecounter[#1][#2]%
+ {\getparameters
+ [\??nn#1]
+ [\s!counter=,#2]% counter is for internal purposes
+ \ctxlua{structure.counters.define("#1",
+ tonumber("\structurecounterparameter{#1}\c!start") or 0,
+ tonumber("\structurecounterparameter{#1}\s!counter") or 0
+ )}%
+ \docheckstructurecountersetup{#1}}
+
+\def\donodefinestructurecounter[#1][#2]%
+ {\getparameters[\??nn#1][\c!number=#2]%
+ \docheckstructurecountersetup{#1}}
+
+\def\setupstructurecounter
+ {\dodoubleargument\dosetupstructurecounter}
+
+\def\dosetupstructurecounter[#1][#2]%
+ {\getparameters[\??nn#1][\c!start=,#2]%
+ \docheckstructurecountersetup{#1}}
+
+\def\structurecounterway#1% slow, we need to store it at the tex end
+ {\ctxlua{structure.sections.way("\structurecounterparameter{#1}\c!way","\v!by")}}
+
+\def\thenamedstructurecounterlevel#1%
+% {\thenamedstructureheadlevel{\structurecounterway{\structurecounterparameter{#1}\c!way}}}
+ {\thenamedstructureheadlevel{\structurecounterway{#1}}}
+
+\def\docheckstructurecountersetup#1%
+ {% this can be done at the lua end / a bit messy here ... todo ...
+ \ifcsname\??nn#1\c!number\endcsname
+ \doifelsevalue {\??nn#1\c!number}{#1} {\letbeundefined{\??nn#1\c!number}}%
+ {\doifvaluenothing{\??nn#1\c!number} {\letbeundefined{\??nn#1\c!number}}}%
+ \fi
+ \ifcsname\??nn#1\c!number\endcsname
+ % it's a clone
+ \else
+ \edef\currentstructurecounterlevel{\thenamedstructurecounterlevel{#1}}%
+ \ctxlua{
+ structure.counters.restart("#1",1,"\structurecounterparameter{#1}\c!start")
+ structure.counters.setstate("#1","\structurecounterparameter{#1}\c!state")
+ structure.counters.setlevel("#1",\currentstructurecounterlevel)
+ structure.sections.setchecker("#1",\currentstructurecounterlevel,structure.counters.reset)
+ }%
+ \fi}
+
+\def\doifstructurecounterelse#1{\ctxlua{structure.counters.doifelse("\@@thestructurecounter{#1}")}}
+\def\doifstructurecounter #1{\ctxlua{structure.counters.doif ("\@@thestructurecounter{#1}")}}
+\def\doifnotstructurecounter #1{\ctxlua{structure.counters.doifnot ("\@@thestructurecounter{#1}")}}
+
+\def\setstructurecounter [#1]#2{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",1,\number#2)}}
+\def\setstructurecounterown [#1]#2{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",1,"#2")}}
+\def\resetstructurecounter [#1]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",1)}}
+\def\restartstructurecounter [#1]#2{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",1,#2)}}
+\def\savestructurecounter [#1]{\ctxlua{structure.counters.save ("\@@thestructurecounter{#1}")}}
+\def\restorestructurecounter [#1]{\ctxlua{structure.counters.restore("\@@thestructurecounter{#1}")}}
+\def\incrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,1)}}
+\def\decrementstructurecounter [#1]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",1,-1)}}
+\def\rawstructurecounter [#1]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",1)}}
+\def\laststructurecounter [#1]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",1)}}
+\def\firststructurecounter [#1]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",1)}}
+\def\nextstructurecounter [#1]{\ctxlua{structure.counters.next ("\@@thestructurecounter{#1}",1)}}
+\def\prevstructurecounter [#1]{\ctxlua{structure.counters.prev ("\@@thestructurecounter{#1}",1)}}
+\def\structurecountersubs [#1]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",1)}}
+
+\def\tracestructurecounter [#1]{\ctxlua{structure.counters.trace ("\@@thestructurecounter{#1}")}}
+
+\def\incrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,1))}}
+\def\decrementedstructurecounter[#1]{\ctxlua{tex.write(structure.counters.add("\@@thestructurecounter{#1}",1,-1))}}
+
+\def\setsubstructurecounter {\dodoubleargument\dosetsubstructurecounter}
+\def\setsubstructurecounterown {\dodoubleargument\dosetsubstructurecounterown}
+\def\resetsubstructurecounter {\dodoubleargument\doresetsubstructurecounter}
+\def\restartsubstructurecounter {\dodoubleargument\dorestartsubstructurecounter}
+\def\incrementsubstructurecounter {\dodoubleargument\doincrementsubstructurecounter}
+\def\decrementsubstructurecounter {\dodoubleargument\dodecrementsubstructurecounter}
+\def\rawsubstructurecounter {\dodoubleargument\dorawsubstructurecounter}
+
+\def\dosetsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.set ("\@@thestructurecounter{#1}",#2,\number#3)}}
+\def\dosetsubstructurecounterown [#1][#2]#3{\ctxlua{structure.counters.setown ("\@@thestructurecounter{#1}",#2,"#3")}}
+\def\doresetsubstructurecounter [#1][#2]{\ctxlua{structure.counters.reset ("\@@thestructurecounter{#1}",#2)}}
+\def\dorestartsubstructurecounter [#1][#2]#3{\ctxlua{structure.counters.restart("\@@thestructurecounter{#1}",#2,#3)}}
+\def\doincrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,1)}}
+\def\dodecrementsubstructurecounter [#1][#2]{\ctxlua{structure.counters.add ("\@@thestructurecounter{#1}",#2,-1)}}
+\def\dorawsubstructurecounter [#1][#2]{\ctxlua{structure.counters.value ("\@@thestructurecounter{#1}",#2)}}
+\def\dolastsubstructurecounter [#1][#2]{\ctxlua{structure.counters.last ("\@@thestructurecounter{#1}",#2)}}
+\def\dofirstsubstructurecounter [#1][#2]{\ctxlua{structure.counters.first ("\@@thestructurecounter{#1}",#2)}}
+\def\dosubstructurecountersubs [#1][#2]{\ctxlua{structure.counters.subs ("\@@thestructurecounter{#1}",#2)}}
+
+% The bypage check needs a multipass reference and therefore
+% we only check for it when we increment and know that some
+% content will be placed. We could also check for spreads.
+
+% to be checked !
+
+\def\docheckstructurecounterbypage#1% since we call lua to get the way we can as well do all in lua
+ {\doif{\structurecounterway{#1}}\v!page{\checkpagechange{#1}\ifpagechanged\resetstructurecounter[#1]\fi}}
+
+\def\incrementstructurecounter[#1]%
+ {\docheckstructurecounterbypage{#1}%
+ \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",1,1)}}
+
+\def\doincrementsubstructurecounter[#1][#2]%
+ {\docheckstructurecounterbypage{#1}
+ \ctxlua{structure.counters.add("\@@thestructurecounter{#1}",#2,1)}}
+
+\def\convertedstructurecounter
+ {\dodoubleempty\doconvertedstructurecounter}
+
+\def\doconvertedstructurecounter[#1][#2]%
+ {\begingroup
+ \ifsecondargument\getparameters[\??nn#1][#2]\fi
+ \ctxlua{structure.counters.prefixedconverted(
+ "\@@thestructurecounter{#1}",
+ {
+ prefix = "\structurecounterparameter{#1}\c!prefix",
+ separatorset = "\structurecounterparameter{#1}\c!prefixseparatorset",
+ conversion = "\structurecounterparameter{#1}\c!prefixconversion",
+ conversionset = "\structurecounterparameter{#1}\c!prefixconversionset",
+ stopper = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es,
+ set = "\structurecounterparameter{#1}\c!prefixset",
+ segments = "\structurecounterparameter{#1}\c!prefixsegments",
+ connector = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es,
+ },
+ {
+ order = "\structurecounterparameter{#1}\c!numberorder",
+ separatorset = "\structurecounterparameter{#1}\c!numberseparatorset",
+ conversion = \!!bs\structurecounterparameter{#1}\c!numberconversion\!!es,
+ conversionset = "\structurecounterparameter{#1}\c!numberconversionset",
+ stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es,
+ segments = "\structurecounterparameter{#1}\c!numbersegments",
+ type = "\structurecounterparameter{#1}\c!type",
+ }
+ )}%
+ \endgroup}
+
+\def\convertedsubstructurecounter
+ {\dotripleempty\doconvertedsubstructurecounter}
+
+\def\doconvertedsubstructurecounter[#1][#2][#3]% #2 can be n or n:m
+ {\ifsecondargument
+ \doconvertedstructurecounter[#1][\c!numbersegments=#2,#3]%
+ \else
+ \secondargumentfalse\doconvertedstructurecounter[#1][]%
+ \fi}
+
+\let\getstructurecounter\convertedstructurecounter
+
+\def\doifdefinedstructurecounter #1{\doifdefined {\csname\s!structurecounter#1\c!number\endcsname}}
+\def\doifundefinedstructurecounter #1{\doifundefined {\csname\s!number#1\c!number\endcsname}}
+\def\doifdefinedstructurecounterelse#1{\doifdefinedelse{\csname\s!number#1\c!number\endcsname}}
+
+\ifx\checkstructurecounter\undefined \def\checkstructurecounter[#1]{} \fi
+
+\def\checkstructurecounter[#1]{}
+
+%D What follows is a compatibility layer. This will be phased out (at
+%D least from core usage).
+
+\def\reset
+ {\dosingleargument\doreset}
+
+\def\doreset[#1]%
+ {\processcommalist[#1]\dodoreset}
+
+\def\dodoreset#1%
+ {\csname\s!reset#1\endcsname}%
+
+\let \numberparameter \structurecounterparameter % {name}\c!key
+
+\let \definenumber \definestructurecounter % [name]
+\let \setupnumber \setupstructurecounter % [name][setups]
+
+\let \setnumber \setstructurecounter % [name]{value}
+\let \resetnumber \resetstructurecounter % [name]
+\let \savenumber \savestructurecounter % [name]
+\let \restorenumber \restorestructurecounter % [name]
+\let \incrementnumber \incrementstructurecounter % [name]
+\let \decrementnumber \decrementstructurecounter % [name]
+\let \rawnumber \rawstructurecounter % [name]
+\let \getnumber \getstructurecounter % [name]
+\let \convertednumber \getstructurecounter % [name]
+
+\let \doifdefinednumber \doifstructurecounter % {number}{true}
+\let \doifundefinednumber \doifnotstructurecounter % {number}{true}
+\let \doifdefinednumberelse \doifstructurecounterelse % {number}{true}{false}
+
+% weird one
+
+\def\accumulatednumber[#1]{}
+
+% funny, here, todo: these are the defaults
+
+\def\setupnumbering
+ {\dodoubleempty\getparameters[\??nr]}
+
+\setupnumbering
+ [\c!way=\v!by\v!chapter,
+ \c!blockway=,
+ \c!sectionnumber=\v!yes,
+ \c!state=\v!start]
+
+%D Helpers:
+
+% call:
+%
+% \dostructurecountercomponent
+% \currentfloat
+% \getfloatparameters \floatparameter \detokenizedfloatparameter
+% \hascaption \hastitle \hasnumber
+% [settings][userdata]
+%
+% sets:
+%
+% \laststructurecounternumber
+% \laststructurecountersynchronize
+
+\newconditional\hasstructurecountercaption
+\newconditional\hasstructurecountertitle
+\newconditional\hasstructurecounternumber
+
+\def\dostructurecountercomponent#1#2#3#4#5#6#7[#8][#9]%
+ {\begingroup
+ %
+ #2[#8]%
+ \edef\hasstructurecountercaption{#3\s!hascaption}%
+ \edef\hasstructurecountertitle{#3\s!hastitle}%
+ \edef\hasstructurecounternumber{#3\s!hasnumber}%
+ %
+ \edef\currentname{#3\c!name}%
+ \ifx\currentname\empty
+ \edef\currentname{#1}%
+ \fi
+ \edef\currentcounter{#3\s!counter}%
+ \ifx\currentcounter\empty
+ \let\currentcounter\currentname
+ \fi
+ %
+ \doif{#3\c!title}\v!none{\setfalse\hasstructurecountercaption\setfalse\hasstructurecounternumber}% will become obsolete
+ %
+ \ifx\hasstructurecounternumber\v!yes
+ \incrementstructurecounter[\currentcounter]%
+ \fi
+ %
+ \ifx\hasstructurecountercaption\v!yes
+ \edef\currentexpansion{#3\c!expansion}%
+ \ifx\currentexpansion\s!xml
+ \edef\currenttitle{#4\c!title}%
+ \edef\currentbookmark{#4\c!bookmark}%
+ \xmlstartraw
+ \edef\currentlisttitle{#3\c!title}%
+ \xmlstopraw
+ \let\currentcoding\s!xml
+ \else
+ \ifx\currentexpansion\v!yes
+ \edef\currenttitle{#3\c!title}%
+ \edef\currentbookmark{#3\c!bookmark}%
+ \else
+ \edef\currenttitle{#4\c!title}%
+ \edef\currentbookmark{#4\c!bookmark}%
+ \fi
+ \let\currentlisttitle\currenttitle
+ \let\currentcoding\s!tex
+ \fi
+ \edef\currentlabel{#3\c!label}%
+ \edef\currentreference{#3\c!reference}%
+ \setnextinternalreference
+ \xdef\laststructurecounternumber{\ctxlua{structure.lists.push{
+ metadata = {
+ kind = "#1",
+ name = "\currentname",
+ level = structure.sections.currentlevel(),
+ catcodes = \the\catcodetable,
+ },
+ references = {
+ internal = \nextinternalreference,
+ reference = "\currentreference",
+ referenceprefix = "\referenceprefix",
+ block = "\currentstructureblock",
+ section = structure.sections.currentid(),
+ },
+ titledata = {
+ label = \!!bs\detokenize\expandafter{\currentlabel }\!!es,
+ title = \!!bs\detokenize\expandafter{\currenttitle }\!!es,
+ \ifx\currentbookmark\currenttitle \else
+ bookmark = \!!bs\detokenize\expandafter{\currentbookmark }\!!es,
+ \fi
+ \ifx\currentlisttitle\currenttitle \else
+ list = \!!bs\detokenize\expandafter{\currentlisttitle}\!!es,
+ \fi
+ },
+ \ifx\hasstructurecountercaption\v!yes
+ prefixdata = {
+ prefix = "#3\c!prefix",
+ separatorset = "#3\c!prefixseparatorset",
+ conversion = \!!bs#3\c!prefixconversion\!!es,
+ conversionset = "#3\c!prefixconversionset",
+ set = "#3\c!prefixset",
+ segments = "#3\c!prefixsegments",
+ connector = \!!bs#3\c!prefixconnector\!!es,
+ },
+ numberdata = {
+ numbers = structure.counters.compact("\currentcounter",nil,true),
+ separatorset = "#3\c!numberseparatorset",
+ conversion = \!!bs#3\c!numberconversion\!!es,
+ conversionset = "#3\c!numberconversionset",
+ stopper = \!!bs#3\c!numberstopper\!!es,
+ segments = "#3\c!numbersegments",
+ },
+ \fi
+ userdata = structure.helpers.touserdata(\!!bs\detokenize{#9}\!!es)
+ }
+ }}%
+ \xdef\laststructurecountersynchronize % make this a macro because shared
+ {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}%
+ \noexpand\ctxlatelua{structure.lists.enhance(\laststructurecounternumber)}}%
+ \else
+ \glet\laststructurecounternumber \relax
+ \glet\laststructurecountersynchronize\relax
+ \fi
+ \endgroup}
+
+\def\dostructurecountersetup#1#2% name \someparameter
+ {\setupstructurecounter
+ [#1]
+ [ \c!start=#2\c!start,
+ \c!state=#2\c!state,
+ \c!way=#2\c!way,
+ %
+ \c!prefix=#2\c!prefix,
+ \c!prefixseparatorset=#2\c!prefixseparatorset,
+ \c!prefixconversion=#2\c!prefixconversion,
+ \c!prefixconversionset=#2\c!prefixconversionset,
+ \c!prefixstopper=#2\c!prefixstopper,
+ \c!prefixset=#2\c!prefixset,
+ \c!prefixsegments=#2\c!prefixsegments,
+ \c!prefixset=#2\c!prefixset,
+ \c!prefixconnector=#2\c!prefixconnector,
+ %
+ \c!numberseparatorset=#2\c!numberseparatorset,
+ \c!numberconversion=#2\c!numberconversion,
+ \c!numberconversionset=#2\c!numberconversionset,
+ \c!numberstopper=#2\c!numberstopper,
+ \c!numbersegments=#2\c!numbersegments]}
+
+\protect \endinput
diff --git a/tex/context/base/strc-pag.lua b/tex/context/base/strc-pag.lua
new file mode 100644
index 000000000..bb2de7881
--- /dev/null
+++ b/tex/context/base/strc-pag.lua
@@ -0,0 +1,206 @@
+if not modules then modules = { } end modules ['strc-pag'] = {
+ version = 1.001,
+ comment = "companion to strc-pag.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local count, format = tex.count, string.format
+
+local ctxcatcodes = tex.ctxcatcodes
+local texsprint = tex.sprint
+
+structure.pages = structure.pages or { }
+
+local helpers = structure.helpers or { }
+local sections = structure.sections or { }
+local pages = structure.pages or { }
+local processors = structure.processors or { }
+local sets = structure.sets or { }
+
+local variables = interfaces.variables
+
+-- storage
+
+jobpages = jobpages or { }
+jobpages.collected = jobpages.collected or { }
+jobpages.tobesaved = jobpages.tobesaved or { }
+
+local collected, tobesaved = jobpages.collected, jobpages.tobesaved
+
+local function initializer()
+ collected, tobesaved = jobpages.collected, jobpages.tobesaved
+end
+
+job.register('jobpages.collected', jobpages.tobesaved, initializer)
+
+local specification = { }
+
+function pages.save(userspec)
+ local realpage, userpage = count[0], count[1]
+ local data = {
+ number = userpage,
+ specification = helpers.simplify(userspec or specification),
+ block = sections.currentblock(),
+ }
+ tobesaved[realpage] = data
+ if not collected[realpage] then
+ collected[realpage] = data
+ end
+end
+
+function pages.pagenumber(localspec)
+ local deltaspec
+ if localspec then
+ for k,v in next, localspec do
+ if v ~= "" and v ~= specification[k] then
+ if not deltaspec then deltaspec = { } end
+ deltaspec[k] = v
+ end
+ end
+ end
+ if deltaspec then
+ return { realpage = count[0], specification = deltaspec }
+ else
+ return { realpage = count[0] }
+ end
+end
+
+--
+
+local function convertnumber(str,n)
+ return format("\\convertnumber{%s}{%s}",str or "numbers",n)
+end
+
+function pages.number(realdata,pagespecification)
+ local userpage, block = realdata.number, realdata.block or ""
+ local conversionset = (pagespecification and pagespecification.conversionset) or realdata.conversionset or ""
+ local conversion = (pagespecification and pagespecification.conversion ) or realdata.conversion or ""
+ local stopper = (pagespecification and pagespecification.stopper ) or realdata.stopper or ""
+ if conversion ~= "" then
+ texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
+ else
+ if conversionset == "" then conversionset = "default" end
+ local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
+ processors.sprint(ctxcatcodes,theconversion,convertnumber,userpage)
+ end
+ if stopper ~= "" then
+ processors.sprint(ctxcatcodes,stopper)
+ end
+end
+
+-- (pagespec.prefix == yes|unset) and (pages.prefix == yes) => prefix
+
+function pages.analyse(entry,pagespecification)
+ -- safeguard
+ if not entry then
+ return false, false, "no entry"
+ end
+ local references = entry.references
+ if not references then
+ return false, false, "no references"
+ end
+ local realpage = references.realpage
+ if not realpage then
+ return false, false, "no realpage"
+ end
+ local pagedata = collected[realpage]
+ if not pagedata then
+ return false, false, "no pagedata"
+ end
+ local section = references.section
+ if not section then
+ return pagedata, false, "no section"
+ end
+ local no = variables.no
+ -- local preferences
+ if pagespecification and pagespecification.prefix == no then
+ return pagedata, false, "current spec blocks prefix"
+ end
+ -- stored preferences
+ if entry.prefix == no then
+ return pagedata, false, "entry blocks prefix"
+ end
+ -- stored page state
+ pagespecification = pagedata.specification
+ if pagespecification and pagespecification.prefix == no then
+ return pagedata, false, "pagedata blocks prefix"
+ end
+ -- final verdict
+ return pagedata, jobsections.collected[references.section], "okay"
+end
+
+function helpers.page(data,pagespec)
+ if data then
+ local pagedata = pages.analyse(data,pagespec)
+ if pagedata then
+ pages.number(pagedata,pagespec)
+ end
+ end
+end
+
+function helpers.prefixpage(data,prefixspec,pagespec)
+ if data then
+ local pagedata, prefixdata = pages.analyse(data,pagespec)
+ if pagedata then
+ if prefixdata then
+ sections.typesetnumber(prefixdata,"prefix",prefixspec or false,prefixdata or false,pagedata.specification or false)
+ end
+ pages.number(pagedata,pagespec)
+ end
+ end
+end
+
+function helpers.prefixlastpage(data,prefixspec,pagespec)
+ if data then
+ local r = data.references
+ local ls, lr = r.section, r.realpage
+ r.section, r.realpage = r.lastsection, r.lastrealpage
+ helpers.prefixpage(data,prefixspec,pagespec)
+ r.section, r.realpage = ls, lr
+ end
+end
+
+--
+
+function helpers.analyse(entry,specification)
+ -- safeguard
+ if not entry then
+ return false, false, "no entry"
+ end
+ local no = variables.no
+ -- section data
+ local references = entry.references
+ if not references then
+ return entry, false, "no references"
+ end
+ local section = references.section
+ if not section then
+ return entry, false, "no section"
+ end
+ sectiondata = jobsections.collected[references.section]
+ if not sectiondata then
+ return entry, false, "no section data"
+ end
+ -- local preferences
+ if specification and specification.prefix == no then
+ return entry, false, "current spec blocks prefix"
+ end
+ -- stored preferences (not used)
+ local prefixdata = entry.prefixdata
+ if prefixdata and prefixdata.prefix == no then
+ return entry, false, "entry blocks prefix"
+ end
+ -- final verdict
+ return entry, sectiondata, "okay"
+end
+
+function helpers.prefix(data,prefixspec)
+ if data then
+ local _, prefixdata = helpers.analyse(data,prefixspec)
+ if prefixdata then
+ sections.typesetnumber(prefixdata,"prefix",prefixspec or false,data.prefixdata or false,prefixdata or false)
+ end
+ end
+end
diff --git a/tex/context/base/strc-pag.tex b/tex/context/base/strc-pag.tex
new file mode 100644
index 000000000..2b7c3fc21
--- /dev/null
+++ b/tex/context/base/strc-pag.tex
@@ -0,0 +1,506 @@
+%D \module
+%D [ file=strc-pag,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Pagenumbering,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Pagenumbering}
+
+\registerctxluafile{strc-pag}{1.001}
+
+\unprotect
+
+% Hacks:
+
+\let\preparepageprefix\gobbleoneargument
+\let\checkrealpage \relax
+\let\checksubpages \relax
+\let\setpagecounters \relax
+
+% Allocation:
+
+\countdef\realpageno = 0 \realpageno = 1
+\countdef\userpageno = 1 \userpageno = 1
+\countdef\subpageno = 2 \subpageno = 0 % !!
+\countdef\arrangeno = 3 \arrangeno = 0 % !!
+
+\let\pageno\userpageno
+
+\def\realfolio{\the\realpageno}
+\def\userfolio{\the\userpageno}
+\def\subfolio {\the\subpageno }
+
+\newtoks\everyinitializepagecounters
+
+\def\initializepagecounters{\the\everyinitializepagecounters}
+
+\appendtoks
+ \initializepagecounters
+\to \everyjob
+
+% Page numbers are kind of independent of each other and therefore they
+% all get their own counter. After all, it's easier to combine them in
+% a pseudo counterset than to deal with a complex set itself.
+
+% \definestructureprefixset [mine][section-1,section-2]
+% \definestructureseparatorset[mine][:]
+%
+% \setupuserpagenumber
+% [way=bypart,
+% prefix=yes,
+% prefixset=mine,
+% prefixseparatorset=mine]
+
+\definestructurecounter[\s!realpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=0]
+\definestructurecounter[\s!userpage][\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=1]
+\definestructurecounter[\s!subpage] [\c!prefix=\v!no,\c!start=1,\c!prefixsegments=] % [\s!counter=2]
+
+\newtoks\everysetuprealpagenumber % todo: set state: none, start, stop, reset
+\newtoks\everysetupuserpagenumber % todo: set state: none, start, stop, reset
+\newtoks\everysetupsubpagenumber % todo: set state: none, start, stop, reset
+
+\def\setuprealpagenumber{\dosingleargument\dosetuprealpagenumber}
+\def\setupuserpagenumber{\dosingleargument\dosetupuserpagenumber}
+\def\setupsubpagenumber {\dosingleargument\dosetupsubpagenumber}
+
+\def\dosavepagenumberstate#1{\edef\oldpagenumberstate{\structurecounterparameter#1\c!state}}
+
+\def\dosetuprealpagenumber[#1]{\dosavepagenumberstate\s!realpage\dosetupstructurecounter[\s!realpage][#1]\the\everysetuprealpagenumber}
+\def\dosetupuserpagenumber[#1]{\dosavepagenumberstate\s!userpage\dosetupstructurecounter[\s!userpage][#1]\the\everysetupuserpagenumber}
+\def\dosetupsubpagenumber [#1]{\dosavepagenumberstate\s!subpage \dosetupstructurecounter[\s!subpage ][#1]\the\everysetupsubpagenumber }
+
+\def\resetrealpagenumber {} % not permitted
+\def\resetuserpagenumber {\resetstructurecounter[\s!userpage]}
+\def\resetsubpagenumber {\resetstructurecounter[\s!subpage]}
+
+\appendtoks
+ \setstructurecounter[\s!realpage]\realpageno
+ \setstructurecounter[\s!userpage]\userpageno
+ \setstructurecounter[\s!subpage] \subpageno
+\to \everyinitializepagecounters
+
+\let\setuppagenumber\setupuserpagenumber
+\let\resetpagenumber\resetuserpagenumber
+
+% {
+% prefix = "\structurecounterparameter{#1}\c!prefix",
+% separatorset = "\structurecounterparameter{#1}\c!prefixseparatorset",
+% conversion = "\structurecounterparameter{#1}\c!prefixconversion",
+% conversionset = "\structurecounterparameter{#1}\c!prefixconversionset",
+% stopper = \!!bs\structurecounterparameter{#1}\c!prefixstopper\!!es,
+% set = "\structurecounterparameter{#1}\c!prefixset",
+% segments = "\structurecounterparameter{#1}\c!prefixsegments",
+% connector = \!!bs\structurecounterparameter{#1}\c!prefixconnector\!!es,
+% },
+% {
+% order = "\structurecounterparameter{#1}\c!numberorder",
+% separatorset = "\structurecounterparameter{#1}\c!numberseparatorset",
+% conversion = "\structurecounterparameter{#1}\c!numberconversion",
+% conversionset = "\structurecounterparameter{#1}\c!numberconversionset",
+% stopper = \!!bs\structurecounterparameter{#1}\c!numberstopper\!!es,
+% segments = "\structurecounterparameter{#1}\c!numbersegments",
+% type = "\structurecounterparameter{#1}\c!type",
+% }
+
+\def\savecurrentpagestate
+ {\ctxlua{structure.pages.save {
+ prefix = "\structurecounterparameter\s!userpage\c!prefix",
+ separatorset = "\structurecounterparameter\s!userpage\c!prefixseparatorset",
+ conversion = "\structurecounterparameter\s!userpage\c!prefixconversion",
+ conversionset = "\structurecounterparameter\s!userpage\c!prefixconversionset",
+ set = "\structurecounterparameter\s!userpage\c!prefixset",
+ stopper = \!!bs\structurecounterparameter\s!userpage\c!prefixstopper\!!es,
+ segments = "\structurecounterparameter\s!userpage\c!prefixsegments",
+ connector = \!!bs\structurecounterparameter\s!userpage\c!prefixconnector\!!es,
+ }}}
+
+\prependtoks
+ \savecurrentpagestate
+\to \everyshipout
+
+\def\pushpagestate{\setxvalue{\??nm:\s!userpage:\c!state}{\structurecounterparameter\s!userpage\c!state}}
+\def\poppagestate {\normalexpanded{\noexpand\setuppagenumber[\c!state=\getvalue{\??nm:\s!userpage:\c!state}]}}
+
+\setuppagenumber
+ [\c!way=\v!by\v!text,
+ \c!prefix=\v!no,
+ \c!prefixset=\v!part,
+ \c!prefixconnector=\endash,
+ \c!state=\v!start]
+
+\setupsubpagenumber
+ [\c!way=\v!by\v!part,
+ \c!state=\v!stop]
+
+% We don't want conflicts when \type {\pageno} is used by other
+% packages, like \CWEB, so we redefine \type {\pageno}.
+
+\newcount\pageno \pageno\userpageno \let\folio\userfolio
+
+\appendtoks
+ \global\pageno\userpageno
+\to \everyinitializepagecounters
+
+% Counters
+
+\def\firstpage {1} \def\prevpage {1} \def\nextpage {1} \def\lastpage {1}
+\def\firstuserpage{1} \def\prevuserpage{1} \def\nextuserpage{1} \def\lastuserpage{1}
+\def\firstsubpage {1} \def\prevsubpage {1} \def\nextsubpage {1} \def\lastsubpage {1}
+
+% Renderers:
+
+\def\realpagenumber{\convertedstructurecounter[\s!realpage]}
+\def\userpagenumber{\convertedstructurecounter[\s!userpage]}
+\def\subpagenumber {\convertedstructurecounter[\s!subpage]}
+
+\def\pagenumber {\rawstructurecounter[\s!userpage]}
+\def\prefixedpagenumber{\convertedstructurecounter[\s!userpage]} % \userpagenumber
+
+\def\firstrealpagenumber{\convertedstructurecounter[\s!realpage][\c!type=\v!first]}
+\def\firstuserpagenumber{\convertedstructurecounter[\s!userpage][\c!type=\v!first]}
+\def\firstsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!first]}
+
+\def\lastrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!last]}
+\def\lastuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!last]}
+\def\lastsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!last]}
+
+\def\prevrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!previous]}
+\def\prevuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!previous]}
+\def\prevsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!previous]}
+
+\def\nextrealpagenumber {\convertedstructurecounter[\s!realpage][\c!type=\v!next]}
+\def\nextuserpagenumber {\convertedstructurecounter[\s!userpage][\c!type=\v!next]}
+\def\nextsubpagenumber {\convertedstructurecounter[\s!subpage ][\c!type=\v!next]}
+
+\appendtoks
+ \decrementstructurecounter[\s!realpage]%
+ \decrementstructurecounter[\s!userpage]%
+ \decrementstructurecounter[\s!subpage]%
+\to\everygoodbye
+
+% Equivalents (compatibility):
+%
+% todo: maybe leave lastpage etc lua calls
+
+\def\realpage{\realfolio}
+\def\userpage{\userfolio}
+\def\subpage {\subfolio}
+
+% \def\firstrealpage{\firstpage}
+% \def\prevrealpage {\prevpage}
+% \def\nextrealpage {\nextpage}
+% \def\lastrealpage {\lastpage}
+
+\def\firstrealpage{\firststructurecounter[\s!realpage]}
+\def\prevrealpage {\prevstructurecounter[\s!realpage]}
+\def\nextrealpage {\nextstructurecounter[\s!realpage]}
+\def\lastrealpage {\laststructurecounter[\s!realpage]}
+
+\let\firstpage\firstrealpage
+\let\prevpage \prevrealpage
+\let\nextpage \nextrealpage
+\let\lastpage \lastrealpage
+
+\def\nofrealpages {\lastrealpage} \def\totalnumberofpages{\lastrealpage}
+\def\nofuserpages {\lastuserpage} \def\lastpagenumber {\lastuserpage}
+\def\nofsubpages {\lastsubpage }
+
+% Hooks:
+
+\appendtoks
+% \xdef\lastpage{\laststructurecounter[\s!realpage]}%
+ \xdef\currentpage{\the\realpageno}%
+ \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage\fi
+\to \everyinitializepagecounters
+
+% \def\savenofpages
+% {\global\realpageno\decrementedstructurecounter[\s!realpage]\relax
+% \global\pageno \decrementedstructurecounter[\s!userpage]\relax}
+
+\let\savenofpages\relax
+
+% States:
+
+\newif\ifrightpage \rightpagetrue
+\newif\ifdoublesided
+\newif\ifsinglesided
+
+% Real page numbers:
+
+\def\gotonextrealpage
+ {\global\realpageno\incrementedstructurecounter[\s!realpage]\relax
+ \ifnum\realpageno>\lastpage
+ \xdef\lastpage{\realfolio}%
+ \fi
+ \setpagereference\v!firstpage\firstpage
+ \setpagereference\v!lastpage\lastpage
+ \ifnum\realpageno>\plusone
+ \xdef\prevpage{\the\numexpr\realpageno+\minusone}%
+ \setpagereference\v!backward\prevpage
+ \else
+ \global\let\prevpage\firstpage
+ \setpagereference\v!backward\lastpage
+ \fi
+ \setpagereference\v!previouspage\prevpage
+ \ifnum\realpageno<\lastpage\relax
+ \xdef\nextpage{\the\numexpr\realpageno+\plusone}%
+ \setpagereference\v!page\nextpage
+ \setpagereference\v!forward\nextpage
+ \glet\nextnextpage\nextpage
+ \ifodd\nextpage\relax
+ \setpagereference\v!nextoddpage\nextnextpage
+ \else
+ \setpagereference\v!nextevenpage\nextnextpage
+ \fi
+ \xdef\nextnextpage{\the\numexpr\realpageno+\plustwo}%
+ \ifnum\nextnextpage>\lastpage\else
+ \ifodd\nextnextpage\relax
+ \setpagereference\v!nextoddpage\nextnextpage
+ \else
+ \setpagereference\v!nextevenpage\nextnextpage
+ \fi
+ \fi
+ \else
+ \glet\nextpage\lastpage
+ \setpagereference\v!page\firstpage
+ \setpagereference\v!forward\firstpage
+ \setpagereference\v!nextoddpage\lastpage
+ \setpagereference\v!nextevenpage\lastpage
+ \fi
+ \setpagereference\v!nextpage\realfolio}
+
+% Pagenumbers:
+
+\def\dodecrementpagenumber{\global\userpageno\decrementedstructurecounter[\s!userpage]\relax\global\pageno\userpageno}
+\def\doincrementpagenumber{\global\userpageno\incrementedstructurecounter[\s!userpage]\relax\global\pageno\userpageno}
+
+\def\dosynchronizepagenumber{\global\let\@@pnstate\v!start}
+
+\def\decrementpagenumber{\getvalue{\??pn-\structurecounterparameter\s!userpage\c!state}}
+\def\incrementpagenumber{\getvalue{\??pn+\structurecounterparameter\s!userpage\c!state}}
+
+\letvalue{\??pn-\v!start}\dodecrementpagenumber
+\letvalue{\??pn-\v!none }\dodecrementpagenumber
+\letvalue{\??pn-\v!empty}\dodecrementpagenumber
+
+\letvalue{\??pn+\v!start}\doincrementpagenumber
+\letvalue{\??pn+\v!none }\doincrementpagenumber
+\setvalue{\??pn+\v!empty}{\doincrementpagenumber\dosynchronizepagenumber}
+\letvalue{\??pn+\v!keep }\dosynchronizepagenumber
+
+% todo: check if number set, and reset it after testing; also take care of \global\shiftedrealpagenotrue
+
+% Subpagenumbers:
+
+\def\gotonextsubpage
+ {\global\subpageno\incrementedstructurecounter[\s!subpage]\relax
+ \ifnum\subpageno>\lastsubpage
+ \xdef\lastsubpage{\subfolio}%
+ \fi
+ \setpagereference\v!firstsubpage\firstsubpage
+ \setpagereference\v!lastsubpage\lastsubpage
+ \ifnum\subpageno>\plusone
+ \xdef\prevsubpage{\the\numexpr\subpageno+\minusone}%
+ \setpagereference\v!subbackward\prevsubpage
+ \else
+ \global\let\prevsubpage\firstsubpage
+ \setpagereference\v!subbackward\lastsubpage
+ \fi
+ \setpagereference\v!previoussubpage\prevsubpage
+ \ifnum\subpageno<\lastsubpage\relax
+ \xdef\nextsubpage{\the\numexpr\subpageno+\plusone}%
+ \setpagereference\v!subpage\nextsubpage
+ \setpagereference\v!subforward\nextsubpage
+ \glet\nextnextpage\nextsubpage
+ \xdef\nextnextpage{\the\numexpr\subpageno+\plustwo}%
+ \else
+ \glet\nextsubpage\lastsubpage
+ \setpagereference\v!subpage\firstsubpage
+ \setpagereference\v!subforward\firstsubpage
+ \fi
+ \setpagereference\v!nextsubpage\subfolio}
+
+% Control:
+
+\def\getpagestatus % hierboven gebruiken
+ {\ifdoublesided
+ \global\rightpagetrue
+ % todo: \global\rightpagetrue or \global\rightpagefalse
+ \else
+ \global\rightpagetrue
+ \fi}
+
+% Setup general page numbering
+
+\newtoks\everysetuppagenumbering
+
+\def\setuppagenumbering
+ {\dosingleempty\dosetuppagenumbering}
+
+\def\dosetuppagenumbering[#1]%
+ {\getparameters[\??nm][#1]\the\everysetuppagenumbering}
+
+\appendtoks
+ \singlesidedfalse
+ \doublesidedfalse
+ \ExpandFirstAfter\processallactionsinset
+ [\@@nmalternative]
+ [ \v!singlesided=>\singlesidedtrue,
+ \v!doublesided=>\doublesidedtrue]%
+ \ifx\trackingmarginnotestrue\undefined\else
+ \ifdoublesided
+ \trackingmarginnotestrue
+ \else
+ \trackingmarginnotesfalse
+ \fi
+ \fi
+ \dosetpagenumberlocation
+\to \everysetuppagenumbering
+
+\appendtoks
+ \ifdefined \recalculatebackgrounds \recalculatebackgrounds \fi
+\to \everysetuppagenumbering
+
+% The numbered location handler is there because we need to be downward
+% compatible. So, in fact there can be multiple handlers active at the
+% same time, but only the current one does something.
+%
+% thsi code might move to page-txt
+
+\newcount\currentpagenumberlocation
+
+\def\dosetpagenumberlocation
+ {\advance\currentpagenumberlocation\plusone
+ \ifx\@@nmlocation\empty \else
+ \let\@@pagenumbervlocation\v!footer
+ \let\@@pagenumberhlocation\v!text
+ \let\@@pagenumberxlocation\c!middletext
+ \normalexpanded{\noexpand\processallactionsinset[\@@nmlocation]}
+ [ \v!header=>\let\@@pagenumbervlocation\v!header,
+ \v!footer=>\let\@@pagenumbervlocation\v!footer,
+ \v!middle=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!middletext,
+ \v!left=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!lefttext,
+ \v!right=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!righttext,
+ \v!inleft=>\let\@@pagenumberhlocation\v!margin\let\@@pagenumberxlocation\c!lefttext,
+ \v!inright=>\let\@@pagenumberhlocation\v!margin\let\@@pagenumberxlocation\c!righttext,
+ \v!inmargin=>\let\@@pagenumberhlocation\v!margin\def\@@pagenumberxlocation{\ifdoublesided\c!margintext\else\c!righttext\fi},
+ \v!margin=>\let\@@pagenumberhlocation\v!margin\def\@@pagenumberxlocation{\ifdoublesided\c!margintext\else\c!righttext\fi},
+ \v!atmargin=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!marginedgetext,
+ \v!marginedge=>\let\@@pagenumberhlocation\v!text \let\@@pagenumberxlocation\c!marginedgetext]%
+ \normalexpanded{\noexpand\setspecificlayouttext
+ {\@@pagenumbervlocation}{\@@pagenumberhlocation}{\@@pagenumberxlocation}%
+ {\noexpand\doplacepagenumberatlocation{\number\currentpagenumberlocation}}}%
+ \fi}
+
+\def\setspecificlayouttext#1#2#3#4{\setvalue{\??tk#1#2#3}{#4}} % weird place
+
+\appendtoks
+ \dosetpagenumberlocation
+\to \everyinitializepagecounters
+
+\def\doplacepagenumberatlocation#1%
+ {\ifnum#1=\currentpagenumberlocation\relax\expandafter\placelocationpagenumber\fi}
+
+% Rendering:
+
+\unexpanded\def\placelocationpagenumber
+ {\ifnum\userpagenumberstate=\plustwo
+ \ifnum\overallpagenumberstate=\plusone
+ \doif\@@nmstrut\v!yes\strut
+ \@@nmcommand{\doattributes\??nm\c!style\c!color{\@@nmleft\labeltexts\v!pagenumber{\prefixedpagenumber}\@@nmright}}%
+ \fi
+ \fi}
+
+\unexpanded\def\completepagenumber
+ {\ifnum\userpagenumberstate=\plustwo
+ \ifnum\overallpagenumberstate=\plusone
+ \@@nmleft\labeltexts\v!pagenumber\prefixedpagenumber\@@nmright
+ \fi
+ \fi}
+
+\unexpanded\def\placepagenumber
+ {\ifnum\userpagenumberstate=\plustwo
+ \ifnum\overallpagenumberstate=\plusone
+ \labeltexts\v!pagenumber\pagenumber
+ \fi
+ \fi}
+
+\unexpanded\def\referencepagenumber[#1]%
+ {\doifelsenothing{#1}{?}{}}
+
+% The numbered location handler is there because we need to be downward
+% compatible. So, in fact there can be multiple handlers active at the
+% same time, but only the current one does something.
+
+\chardef\realpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible
+\chardef\userpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible
+\chardef\subpagenumberstate =2 % counter state : 0=stop, 1=start, 2=start and visible
+\chardef\overallpagenumberstate=1 % general number: 0=invisible, 1=visible
+
+\def\checkpagenumberstatechange#1#2%
+ {\edef\newpagenumberstate{\structurecounterparameter#1\c!state}%
+ \ifx\newpagenumberstate\oldpagenumberstate \else
+ \doifelse\newpagenumberstate\v!start
+ {\chardef#2\plustwo}%
+ {\chardef#2\zerocount}%
+ \fi}
+
+\appendtoks % todo: set state: none, start, stop, reset
+ \checkpagenumberstatechange\s!realpage\realpagenumberstate
+\to \everysetuprealpagenumber
+
+\appendtoks % todo: set state: none, start, stop, reset
+ \checkpagenumberstatechange\s!userpage\userpagenumberstate
+\to \everysetupuserpagenumber
+
+\appendtoks % todo: set state: none, start, stop, reset
+ \checkpagenumberstatechange\s!subpage\subpagenumberstate
+\to \everysetupsubpagenumber
+
+\appendtoks % todo: set state: none, start, stop, reset
+ \doifelse\@@nmstate\v!start
+ {\chardef\overallpagenumberstate\plusone}%
+ {\chardef\overallpagenumberstate\zerocount}%
+\to \everysetuppagenumbering
+
+% Done
+
+% \c!way=\v!by\v!part
+% \c!text=
+% \v!chapter\v!number=\v!no
+% \v!part\v!number=\v!yes
+% \c!numberseparator=--
+% \c!conversion=\v!numbers
+
+\setuppagenumbering
+ [\c!alternative=\v!singlesided,
+ \c!location={\v!header,\v!middle},
+ \c!width=, % in geval van \v!marginedge
+ \c!left=,
+ \c!right=,
+ \c!textseparator=\tfskip,
+ \c!state=\v!start,
+ \c!command=,
+ \c!strut=\v!yes,
+ \c!style=, % empty, otherwise conflict
+ \c!color=]
+
+% just for downward compatbility
+
+\appendtoks
+ \edef\askeduserpagenumber{\structurecounterparameter\s!userpage\c!number}%
+ \ifx\askeduserpagenumber\empty \else
+ \normalexpanded{\noexpand\setuppagenumber[\c!start=\structurecounterparameter\s!userpage\c!number,\c!number=]}%
+ \fi
+\to\everysetupuserpagenumber % todo: set state: none, start, stop, reset
+
+\initializepagecounters
+
+\protect \endinput
diff --git a/tex/context/base/strc-prc.lua b/tex/context/base/strc-prc.lua
new file mode 100644
index 000000000..35e7000db
--- /dev/null
+++ b/tex/context/base/strc-prc.lua
@@ -0,0 +1,9 @@
+if not modules then modules = { } end modules ['strc-prc'] = {
+ version = 1.001,
+ comment = "companion to strc-prc.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- code will move from strc-ini to here
diff --git a/tex/context/base/strc-prc.tex b/tex/context/base/strc-prc.tex
new file mode 100644
index 000000000..a81cfddd1
--- /dev/null
+++ b/tex/context/base/strc-prc.tex
@@ -0,0 +1,84 @@
+%D \module
+%D [ file=strc-prc,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Processors,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Processors}
+
+\registerctxluafile{strc-prc}{1.001}
+
+\unprotect
+
+%D Processors are used when we cannot easily associate typesetting directives
+%D with (for instance) structural elements. Instead of ending up with numerous
+%D additional definitions we can group treatments in so called processors.
+%D
+%D An example of where processors can be used is in separator sets (these are
+%D related to typesetting numbers using structure).
+%D
+%D \starttyping
+%D \defineprocessor[demo][style=\bfb,color=red]
+%D \stoptyping
+%D
+%D This defines a processor named \type {demo}. Such a name ends up as prefix in
+%D for instance:
+%D
+%D \starttyping
+%D \definestructureseparatorset [demosep] [demo->!,demo->?,demo->!,demo->?] [demo->@]
+%D \stoptyping
+%D
+%D Here the \type {!} and \type {?} are just the seperator characters that end
+%D up between part, chapter, section, etc.\ numbers. The third argument defines the
+%D default. When a separator is inserted, the \type{demo} processor will be applied.
+%D Here the number will be separated by red slightly bigger than normal bold
+%D exclamation marks and questionmarks
+%D
+%D Valid keys for defining a processor are \type {style}, \type {color}, \type {left},
+%D \type {right}, and \type {command} (the given command takes one argument).
+
+\def\defineprocessor
+ {\dodoubleargument\dodefineprocessor}
+
+\def\dodefineprocessor[#1][#2]%
+ {\ifsecondargument
+ \letbeundefined{\??po#1\c!command}%
+ \ctxlua{structure.processors.register("#1")}%
+ \getparameters[\??po#1][\c!style=,\c!color=,\c!left=,\c!right=,#2]%
+ \else
+ \letbeundefined{\??po#1\c!style}%
+ \ctxlua{structure.processors.reset("#1")}%
+ \fi}
+
+%D The following command can be used by users but normally it will be
+%D invoked behind the screens. After all, processor prefixes need to
+%D be split off first.
+
+\unexpanded\def\applyprocessor#1%
+ {\ifcsname\??po#1\c!style\endcsname
+ \expandafter\dodoapplyprocessor
+ \else
+ \expandafter\secondoftwoarguments
+ \fi{#1}}
+
+\def\dodoapplyprocessor#1#2%
+ {\begingroup
+ \dostartattributes{\??po#1}\c!style\c!color
+ \csname\??po#1\c!left\endcsname
+ \ifcsname\??po#1\c!command\endcsname
+ \csname\??po#1\c!command\endcsname{#2}%
+ \else
+ #2%
+ \fi
+ \csname\??po#1\c!right\endcsname
+ \dostopattributes
+ \endgroup}
+
+\protect \endinput
diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua
new file mode 100644
index 000000000..3ee01b127
--- /dev/null
+++ b/tex/context/base/strc-ref.lua
@@ -0,0 +1,875 @@
+if not modules then modules = { } end modules ['strc-ref'] = {
+ version = 1.001,
+ comment = "companion to strc-ref.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, gmatch, texsprint, texwrite, count = string.format, string.gmatch, tex.sprint, tex.write, tex.count
+
+local ctxcatcodes = tex.ctxcatcodes
+
+-- beware, this is a first step in the rewrite (just getting rid of
+-- the tuo file); later all access and parsing will also move to lua
+
+jobreferences = jobreferences or { }
+jobreferences.tobesaved = jobreferences.tobesaved or { }
+jobreferences.collected = jobreferences.collected or { }
+jobreferences.documents = jobreferences.documents or { }
+jobreferences.defined = jobreferences.defined or { } -- indirect ones
+jobreferences.derived = jobreferences.derived or { } -- taken from lists
+jobreferences.specials = jobreferences.specials or { } -- system references
+jobreferences.runners = jobreferences.runners or { }
+jobreferences.internals = jobreferences.internals or { }
+
+storage.register("jobreferences/defined", jobreferences.defined, "jobreferences.defined")
+
+local tobesaved, collected = jobreferences.tobesaved, jobreferences.collected
+local defined, derived, specials, runners = jobreferences.defined, jobreferences.derived, jobreferences.specials, jobreferences.runners
+
+local currentreference = nil
+
+jobreferences.initializers = jobreferences.initializers or { }
+
+function jobreferences.registerinitializer(func) -- we could use a token register instead
+ jobreferences.initializers[#jobreferences.initializers+1] = func
+end
+
+local function initializer()
+ tobesaved, collected = jobreferences.tobesaved, jobreferences.collected
+ for k,v in ipairs(jobreferences.initializers) do
+ v(tobesaved,collected)
+ end
+end
+
+if job then
+ job.register('jobreferences.collected', jobreferences.tobesaved, initializer)
+end
+
+function jobreferences.set(kind,prefix,tag,data)
+ for ref in gmatch(tag,"[^,]+") do
+ local p, r = ref:match("^(%-):(.-)$")
+ if p and r then
+ prefix, ref = p, r
+ else
+ prefix = ""
+ end
+ if ref ~= "" then
+ local pd = tobesaved[prefix]
+ if not pd then
+ pd = { }
+ tobesaved[prefix] = pd
+ end
+ pd[ref] = data
+ texsprint(ctxcatcodes,format("\\dofinish%sreference{%s}{%s}",kind,prefix,ref))
+ end
+ end
+end
+
+function jobreferences.enhance(prefix,tag,spec)
+ local l = tobesaved[prefix][tag]
+ if l then
+ l.references.realpage = tex.count[0]
+ end
+end
+
+-- this reference parser is just an lpeg version of the tex based one
+
+local result = { }
+
+local lparent, rparent, lbrace, rbrace, dcolon = lpeg.P("("), lpeg.P(")"), lpeg.P("{"), lpeg.P("}"), lpeg.P("::")
+
+local reset = lpeg.P("") / function (s) result = { } end
+local outer = (1-dcolon-lparent-lbrace )^1 / function (s) result.outer = s end
+local operation = (1-rparent-rbrace-lparent-lbrace)^1 / function (s) result.operation = s end
+local arguments = (1-rbrace )^0 / function (s) result.arguments = s end
+local special = (1-lparent-lbrace-lparent-lbrace)^1 / function (s) result.special = s end
+local inner = (1-lparent-lbrace )^1 / function (s) result.inner = s end
+
+local outer_reference = (outer * dcolon)^0
+
+operation = outer_reference * operation -- special case: page(file::1) and file::page(1)
+
+local optional_arguments = (lbrace * arguments * rbrace)^0
+local inner_reference = inner * optional_arguments
+local special_reference = special * lparent * (operation * optional_arguments + operation^0) * rparent
+
+local scanner = (reset * outer_reference * (special_reference + inner_reference)^-1 * -1) / function() return result end
+
+function jobreferences.analyse(str)
+ return scanner:match(str)
+end
+
+local splittemplate = "\\setreferencevariables{%s}{%s}{%s}{%s}{%s}" -- will go away
+
+function jobreferences.split(str)
+ local t = scanner:match(str or "")
+ texsprint(ctxcatcodes,format(splittemplate,t.special or "",t.operation or "",t.arguments or "",t.outer or "",t.inner or ""))
+ return t
+end
+
+--~ print(table.serialize(jobreferences.analyse("")))
+--~ print(table.serialize(jobreferences.analyse("inner")))
+--~ print(table.serialize(jobreferences.analyse("special(operation{argument,argument})")))
+--~ print(table.serialize(jobreferences.analyse("special(operation)")))
+--~ print(table.serialize(jobreferences.analyse("special()")))
+--~ print(table.serialize(jobreferences.analyse("inner{argument}")))
+--~ print(table.serialize(jobreferences.analyse("outer::")))
+--~ print(table.serialize(jobreferences.analyse("outer::inner")))
+--~ print(table.serialize(jobreferences.analyse("outer::special(operation{argument,argument})")))
+--~ print(table.serialize(jobreferences.analyse("outer::special(operation)")))
+--~ print(table.serialize(jobreferences.analyse("outer::special()")))
+--~ print(table.serialize(jobreferences.analyse("outer::inner{argument}")))
+--~ print(table.serialize(jobreferences.analyse("special(outer::operation)")))
+
+-- -- -- related to strc-ini.lua -- -- --
+
+jobreferences.resolvers = jobreferences.resolvers or { }
+
+function jobreferences.resolvers.section(var)
+ local vi = structure.lists.collected[var.i[2]]
+ if vi then
+ var.i = vi
+ var.r = (vi.references and vi.references.realpage) or 1
+ else
+ var.i = nil
+ var.r = 1
+ end
+end
+
+jobreferences.resolvers.float = jobreferences.resolvers.section
+jobreferences.resolvers.description = jobreferences.resolvers.section
+jobreferences.resolvers.formula = jobreferences.resolvers.section
+jobreferences.resolvers.note = jobreferences.resolvers.section
+
+function jobreferences.resolvers.reference(var)
+ local vi = var.i[2]
+ if vi then
+ var.i = vi
+ var.r = (vi.references and vi.references.realpage) or 1
+ else
+ var.i = nil
+ var.r = 1
+ end
+end
+
+local function register_from_lists(collected,derived)
+ for i=1,#collected do
+ local entry = collected[i]
+ local m, r = entry.metadata, entry.references
+ if m and r then
+ local prefix, reference = r.referenceprefix or "", r.reference or ""
+ if reference ~= "" then
+ local kind, realpage = m.kind, r.realpage
+ if kind and realpage then
+ local d = derived[prefix] if not d then d = { } derived[prefix] = d end
+ d[reference] = { kind, i }
+ end
+ end
+ end
+ end
+end
+
+jobreferences.registerinitializer(function() register_from_lists(structure.lists.collected,derived) end)
+
+-- urls
+
+jobreferences.urls = jobreferences.urls or { }
+jobreferences.urls.data = jobreferences.urls.data or { }
+
+local urls = jobreferences.urls.data
+
+function jobreferences.urls.define(name,url,file,description)
+ if name and name ~= "" then
+ urls[name] = { url or "", file or "", description or url or file or ""}
+ end
+end
+
+function jobreferences.urls.get(name,method,space) -- method: none, before, after, both, space: yes/no
+ local u = urls[name]
+ if u then
+ local url, file = u[1], u[2]
+ if file ~= "" then
+ texsprint(ctxcatcodes,url,"/",file)
+ else
+ texsprint(ctxcatcodes,url)
+ end
+ end
+end
+
+-- files
+
+jobreferences.files = jobreferences.files or { }
+jobreferences.files.data = jobreferences.files.data or { }
+
+local files = jobreferences.files.data
+
+function jobreferences.files.define(name,file,description)
+ if name and name ~= "" then
+ files[name] = { file or "", description or file or ""}
+ end
+end
+
+function jobreferences.files.get(name,method,space) -- method: none, before, after, both, space: yes/no
+ local f = files[name]
+ if f then
+ texsprint(ctxcatcodes,f[1])
+ end
+end
+
+-- programs
+
+jobreferences.programs = jobreferences.programs or { }
+jobreferences.programs.data = jobreferences.programs.data or { }
+
+local programs = jobreferences.programs.data
+
+function jobreferences.programs.define(name,file,description)
+ if name and name ~= "" then
+ programs[name] = { file or "", description or file or ""}
+ end
+end
+
+function jobreferences.programs.get(name)
+ local f = programs[name]
+ if f then
+ texsprint(ctxcatcodes,f[1])
+ end
+end
+
+-- shared by urls and files
+
+function jobreferences.from(name,method,space)
+ local u = urls[name]
+ if u then
+ local url, file, description = u[1], u[2], u[3]
+ if description ~= "" then
+ texsprint(ctxcatcodes,description)
+ elseif file then
+ texsprint(ctxcatcodes,url,"/",file)
+ else
+ texsprint(ctxcatcodes,url)
+ end
+ else
+ local f = files[name]
+ if f then
+ local description, file = f[1], f[2]
+ if description ~= "" then
+ texsprint(ctxcatcodes,description)
+ else
+ texsprint(ctxcatcodes,file)
+ end
+ end
+ end
+end
+
+function jobreferences.load(name)
+ if name then
+ local jdn = jobreferences.documents[name]
+ if not jdn then
+ jdn = { }
+ local fn = files[name]
+ if fn then
+ jdn.filename = fn[1]
+ local data = io.loaddata(file.replacesuffix(fn[1],"tuc")) or ""
+ if data ~= "" then
+ -- quick and dirty, assume sane { } usage inside strings
+ local lists = data:match("structure%.lists%.collected=({.-[\n\r]+})[\n\r]")
+ if lists and lists ~= "" then
+ lists = loadstring("return" .. lists)
+ if lists then
+ jdn.lists = lists()
+ jdn.derived = { }
+ register_from_lists(jdn.lists,jdn.derived)
+ else
+ commands.writestatus("error","invalid structure data in %s",filename)
+ end
+ end
+ local references = data:match("jobreferences%.collected=({.-[\n\r]+})[\n\r]")
+ if references and references ~= "" then
+ references = loadstring("return" .. references)
+ if references then
+ jdn.references = references()
+ else
+ commands.writestatus("error","invalid reference data in %s",filename)
+ end
+ end
+ end
+ end
+ jobreferences.documents[name] = jdn
+ end
+ return jdn
+ else
+ return nil
+ end
+end
+
+function jobreferences.define(prefix,reference,list)
+ local d = defined[prefix] if not d then d = { } defined[prefix] = d end
+ d[reference] = { "defined", list }
+end
+
+--~ function jobreferences.registerspecial(name,action,...)
+--~ specials[name] = { action, ... }
+--~ end
+
+function jobreferences.reset(prefix,reference)
+ local d = defined[prefix]
+ if d then
+ d[reference] = nil
+ end
+end
+
+-- \primaryreferencefoundaction
+-- \secondaryreferencefoundaction
+-- \referenceunknownaction
+
+-- t.special t.operation t.arguments t.outer t.inner
+
+local settings_to_array = aux.settings_to_array
+
+local function resolve(prefix,reference,args,set) -- we start with prefix,reference
+ if reference and reference ~= "" then
+ set = set or { }
+ local r = settings_to_array(reference)
+ for i=1,#r do
+ local ri = r[i]
+ local d = defined[prefix][ri] or defined[""][ri]
+ if d then
+ resolve(prefix,d[2],nil,set)
+ else
+ local var = scanner:match(ri)
+ if var then
+ var.reference = ri
+ if not var.outer and var.inner then
+ local d = defined[prefix][var.inner] or defined[""][var.inner]
+ if d then
+ resolve(prefix,d[2],var.arguments,set) -- args can be nil
+ else
+ if args then var.arguments = args end
+ set[#set+1] = var
+ end
+ else
+ if args then var.arguments = args end
+ set[#set+1] = var
+ end
+ else
+ -- logs.report("references","funny pattern: %s",ri or "?")
+ end
+ end
+ end
+ return set
+ else
+ return { }
+ end
+end
+
+-- prefix == "" is valid prefix which saves multistep lookup
+
+local function identify(prefix,reference)
+ local set = resolve(prefix,reference)
+ local bug = false
+ for i=1,#set do
+ local var = set[i]
+ local special, inner, outer, arguments, operation = var.special, var.inner, var.outer, var.arguments, var.operation
+ if special then
+ local s = specials[special]
+--~ print(table.serialize(specials))
+ if s then
+ if outer then
+ if operation then
+ -- special(outer::operation)
+ var.kind = "special outer with operation"
+ else
+ -- special()
+ var.kind = "special outer"
+ end
+ elseif operation then
+ if arguments then
+ -- special(operation{argument,argument})
+ var.kind = "special operation with arguments"
+ else
+ -- special(operation)
+ var.kind = "special operation"
+ end
+ else
+ -- special()
+ var.kind = "special"
+ end
+ else
+ var.error = "unknown special"
+ end
+ elseif outer then
+ local e = jobreferences.load(outer)
+ if e then
+ local f = e.filename
+ if f then
+ if inner then
+ local r = e.references
+ if r then
+ r = r[prefix]
+ if r then
+ r = r[inner]
+ if r then
+ if arguments then
+ -- outer::inner{argument}
+ var.kind = "outer with inner with arguments"
+ else
+ -- outer::inner
+ var.kind = "outer with inner"
+ end
+ var.i = { "reference", r }
+ jobreferences.resolvers.reference(var)
+ var.f = f
+ end
+ end
+ end
+ if not r then
+ r = e.derived
+ if r then
+ r = r[prefix]
+ if r then
+ r = r[inner]
+ if r then
+ -- outer::inner
+ if arguments then
+ -- outer::inner{argument}
+ var.kind = "outer with inner with arguments"
+ else
+ -- outer::inner
+ var.kind = "outer with inner"
+ end
+ var.i = r
+ jobreferences.resolvers[r[1]](var)
+ var.f = f
+ end
+ end
+ end
+ end
+ if not r then
+ var.error = "unknown outer"
+ end
+ elseif special then
+ local s = specials[special]
+ if s then
+ if operation then
+ if arguments then
+ -- outer::special(operation{argument,argument})
+ var.kind = "outer with special and operation and arguments"
+ else
+ -- outer::special(operation)
+ var.kind = "outer with special and operation"
+ end
+ else
+ -- outer::special()
+ var.kind = "outer with special"
+ end
+ var.f = f
+ else
+ var.error = "unknown outer with special"
+ end
+ else
+ -- outer::
+ var.kind = "outer"
+ var.f = f
+ end
+ else
+ var.error = "unknown outer"
+ end
+ else
+ var.error = "unknown outer"
+ end
+ else
+ if arguments then
+ local s = specials[inner]
+ if s then
+ -- inner{argument}
+ var.kind = "special with arguments"
+ else
+ var.error = "unknown inner or special"
+ end
+ else
+ -- inner
+--~ local i = tobesaved[prefix]
+ local i = collected[prefix]
+ i = i and i[inner]
+ if i then
+ var.i = { "reference", i }
+ jobreferences.resolvers.reference(var)
+ var.kind = "inner"
+ var.p = prefix
+ else
+ i = derived[prefix]
+ i = i and i[inner]
+ if i then
+ var.kind = "inner"
+ var.i = i
+ jobreferences.resolvers[i[1]](var)
+ var.p = prefix
+ else
+ i = collected[prefix]
+ i = i and i[inner]
+ if i then
+ var.kind = "inner"
+ var.i = { "reference", i }
+ jobreferences.resolvers.reference(var)
+ var.p = prefix
+ else
+ local s = specials[inner]
+ if s then
+ var.kind = "special"
+ else
+--~ i = (tobesaved[""] and tobesaved[""][inner]) or
+--~ (derived [""] and derived [""][inner]) or
+--~ (collected[""] and collected[""][inner])
+ i = (collected[""] and collected[""][inner]) or
+ (derived [""] and derived [""][inner]) or
+ (tobesaved[""] and tobesaved[""][inner])
+ if i then
+ var.kind = "inner"
+ var.i = { "reference", i }
+ jobreferences.resolvers.reference(var)
+ var.p = ""
+ else
+ var.error = "unknown inner or special"
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ bug = bug or var.error
+ set[i] = var
+ end
+--~ print(prefix,reference,table.serialize(set))
+ return set, bug
+end
+
+jobreferences.identify = identify
+
+function jobreferences.doifelse(prefix,reference)
+ local set, bug = identify(prefix,reference)
+ local unknown = bug or #set == 0
+ if unknown then
+ currentreference = nil
+ else
+ currentreference = set[1]
+ end
+ commands.doifelse(not unknown)
+end
+
+function jobreferences.analysis(prefix,reference)
+ local set, bug = identify(prefix,reference)
+ local unknown = bug or #set == 0
+ if unknown then
+ currentreference = nil
+ texwrite(0) -- unknown
+ else
+ currentreference = set[1]
+ texwrite(1) -- whatever
+--~ texwrite(2) -- forward, following page
+--~ texwrite(3) -- backward, preceding page
+--~ texwrite(4) -- forward, same page
+--~ texwrite(5) -- backward, same page
+ end
+end
+
+function jobreferences.handle(prefix,reference) -- todo: use currentreference is possible
+ local set, bug = identify(prefix,reference)
+ if bug or #set == 0 then
+ texsprint(ctxcatcodes,"\\referenceunknownaction")
+ else
+ for i=2,#set do
+ local s = set[i]
+currentreference = s
+ -- not that needed, but keep it for a while
+ texsprint(ctxcatcodes,format(splittemplate,s.special or "",s.operation or "",s.arguments or "",s.outer or "",s.inner or ""))
+ --
+ if s.error then
+ texsprint(ctxcatcodes,"\\referenceunknownaction")
+ else
+ local runner = runners[s.kind]
+ if runner then
+ texsprint(ctxcatcodes,runner(s,"\\secondaryreferencefoundaction"))
+ end
+ end
+ end
+ local s = set[1]
+currentreference = s
+ -- not that needed, but keep it for a while
+ texsprint(ctxcatcodes,format(splittemplate,s.special or "",s.operation or "",s.arguments or "",s.outer or "",s.inner or ""))
+ --
+ if s.error then
+ texsprint(ctxcatcodes,"\\referenceunknownaction")
+ else
+ local runner = runners[s.kind]
+ if runner then
+ texsprint(ctxcatcodes,runner(s,"\\primaryreferencefoundaction"))
+ end
+ end
+ end
+end
+
+local thisdestinationyes = "\\thisisdestination{%s:%s}"
+local thisdestinationnop = "\\thisisdestination{%s}"
+local thisdestinationaut = "\\thisisdestination{aut:%s}"
+
+function jobreferences.setinternalreference(prefix,tag,internal)
+ if tag then
+ for ref in gmatch(tag,"[^,]+") do
+ if not prefix or prefix == "" then
+ texsprint(ctxcatcodes,format(thisdestinationnop,ref))
+ else
+ texsprint(ctxcatcodes,format(thisdestinationyes,prefix,ref))
+ end
+ end
+ end
+ texsprint(ctxcatcodes,format(thisdestinationaut,internal))
+ -- texsprint(ctxcatcodes,"[["..internal.."]]")
+end
+
+--
+
+jobreferences.filters = jobreferences.filters or { }
+
+local filters = jobreferences.filters
+local helpers = structure.helpers
+local sections = structure.sections
+
+function jobreferences.filter(name) -- number page title ...
+ local data = currentreference and currentreference.i
+ if data then
+ local kind = data.metadata and data.metadata.kind
+ if kind then
+ local filter = filters[kind] or filters.generic
+ filter = filter and (filter[name] or filters.generic[name])
+ if filter then
+ filter(data)
+ end
+ end
+ end
+end
+
+filters.generic = { }
+
+function filters.generic.title(data)
+ if data then
+ local titledata = data.titledata
+ if titledata then
+ helpers.title(titledata.title or "?",data.metadata)
+ end
+ end
+end
+
+function filters.generic.number(data) -- todo: spec and then no stopper
+ if data then
+ helpers.prefix(data)
+ local numberdata = data.numberdata
+ if numberdata then
+ sections.typesetnumber(numberdata,"number",numberdata or false)
+ end
+ end
+end
+
+function filters.generic.page(data,prefixspec,pagespec)
+ helpers.prefixpage(data,prefixspec,pagespec)
+end
+
+filters.text = { }
+
+function filters.text.title(data)
+-- texsprint(ctxcatcodes,"[text title]")
+ helpers.title(data.entries.text or "?",data.metadata)
+end
+
+function filters.text.number(data)
+-- texsprint(ctxcatcodes,"[text number]")
+ helpers.title(data.entries.text or "?",data.metadata)
+end
+
+function filters.text.page(data,prefixspec,pagespec)
+ helpers.prefixpage(data,prefixspec,pagespec)
+end
+
+--~ filters.section = { }
+
+--~ filters.section.title = filters.generic.title
+--~ filters.section.number = filters.generic.number
+--~ filters.section.page = filters.generic.page
+
+--~ filters.float = { }
+
+--~ filters.float.title = filters.generic.title
+--~ filters.float.number = filters.generic.number
+--~ filters.float.page = filters.generic.page
+
+-- each method gets its own call, so that we can later move completely to lua
+
+local gotoinner = "\\gotoinner{%s}{%s}{%s}{%s}" -- prefix inner page data
+local gotoouterfilelocation = "\\gotoouterfilelocation{%s}{%s}{%s}{%s}" -- file location page data
+local gotoouterfilepage = "\\gotoouterfilepage{%s}{%s}{%s}" -- file page data
+local gotoouterurl = "\\gotoouterurl{%s}{%s}{%s}" -- url args data
+local gotoinnerpage = "\\gotoinnerpage{%s}{%s}" -- page data
+local gotospecial = "\\gotospecial{%s}{%s}{%s}{%s}{%s}" -- action, special, operation, arguments, data
+
+runners["inner"] = function(var,content)
+ -- inner
+ currentreference = var
+ local r = var.r
+ return (r and format(gotoinner,var.p or "",var.inner,r,content)) or "error"
+end
+
+runners["inner with arguments"] = function(var,content)
+ -- inner{argument}
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["outer"] = function(var,content)
+ -- outer::
+ -- todo: resolve url/file name
+ currentreference = var
+ local url = ""
+ local file = var.o
+ return format(gotoouterfilepage,url,file,1,content)
+end
+
+runners["outer with inner"] = function(var,content)
+ -- outer::inner
+ -- todo: resolve url/file name
+ currentreference = var
+ local r = var.r
+ return (r and format(gotoouterfilelocation,var.f,var.inner,r,content)) or "error"
+end
+
+runners["special outer with operation"] = function(var,content)
+ -- special(outer::operation)
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["special outer"] = function(var,content)
+ -- special()
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["special"] = function(var,content)
+ -- special(operation)
+ currentreference = var
+ local handler = specials[var.special]
+ if handler then
+ return handler(var,content) -- var.special wegwerken
+ else
+ return ""
+ end
+end
+
+runners["outer with inner with arguments"] = function(var,content)
+ -- outer::inner{argument}
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["outer with special and operation and arguments"] = function(var,content)
+ -- outer::special(operation{argument,argument})
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["outer with special"] = function(var,content)
+ -- outer::special()
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["outer with special and operation"] = function(var,content)
+ -- outer::special(operation)
+ currentreference = var
+ return "todo: " .. var.kind or "?"
+end
+
+runners["special operation"] = runners["special"]
+runners["special operation with arguments"] = runners["special"]
+
+local gotoactionspecial = "\\gotoactionspecial{%s}{%s}{%s}{%s}"
+local gotopagespecial = "\\gotopagespecial{%s}{%s}{%s}{%s}"
+local gotourlspecial = "\\gotourlspecial{%s}{%s}{%s}{%s}"
+local gotofilespecial = "\\gotofilespecial{%s}{%s}{%s}{%s}"
+local gotoprogramspecial = "\\gotoprogramspecial{%s}{%s}{%s}{%s}"
+local gotojavascriptspecial = "\\gotojavascriptspecial{%s}{%s}{%s}{%s}"
+
+function specials.action(var,content)
+ return format(gotoactionspecial,var.special,var.operation,var.arguments or "",content)
+end
+
+function specials.page(var,content)
+ -- we need to deal with page(inner) and page(outer::1) and outer::page(1)
+ return format(gotopagespecial,var.special,var.operation,var.arguments or "",content)
+end
+
+function specials.url(var,content)
+ local url = var.operation
+ if url then
+ local u = urls[url]
+ if u then
+ local u, f = u[1], u[2]
+ if f and f ~= "" then
+ url = u .. "/" .. f
+ else
+ url = u
+ end
+ end
+ end
+ return format(gotourlspecial,var.special,url,var.arguments or "",content)
+end
+
+function specials.file(var,content)
+ local file = var.operation
+ if file then
+ local f = files[file]
+ if f then
+ file = f[1]
+ end
+ end
+ return format(gotofilespecial,var.special,file,var.arguments or "",content)
+end
+
+function specials.program(var,content)
+ local program = var.operation
+ if program then
+ local p = programs[program]
+ if p then
+ programs = p[1]
+ end
+ end
+ return format(gotoprogramspecial,var.special,program,var.arguments or "",content)
+end
+
+function specials.javascript(var,content)
+ -- todo: store js code in lua
+ return format(gotojavascriptspecial,var.special,var.operation,var.arguments or "",content)
+end
+
+specials.JS = specials.javascript
+
+structure.references = structure.references or { }
+structure.helpers = structure.helpers or { }
+
+local references = structure.references
+local helpers = structure.helpers
+
+function references.sectiontitle(n)
+ helpers.sectiontitle(lists.collected[tonumber(n) or 0])
+end
+
+function references.sectionnumber(n)
+ helpers.sectionnumber(lists.collected[tonumber(n) or 0])
+end
+
+function references.sectionpage(n,prefixspec,pagespec)
+ helpers.prefixedpage(lists.collected[tonumber(n) or 0],prefixspec,pagespec)
+end
+
diff --git a/tex/context/base/strc-ref.tex b/tex/context/base/strc-ref.tex
new file mode 100644
index 000000000..23fc3e01e
--- /dev/null
+++ b/tex/context/base/strc-ref.tex
@@ -0,0 +1,1905 @@
+%D \module
+%D [ file=strc-ref,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Cross Referencing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Cross Referencing}
+
+\registerctxluafile{strc-ref}{1.001}
+
+\unprotect
+
+%D This module is a (partial) rewrite of core-ref.tex for \MKIV. As
+%D such it will be a moving target for a while.
+
+%D Later we will do a further cleanup and move much of the code to
+%D \LUA\ (i.e.\ better backend integration).
+
+\let\mainreference\gobblefivearguments
+
+% this will go when we got rid of the tuo file
+
+\let\currentfolioreference \!!zerocount % only used in xml-fo
+\let\resetreferences \relax
+\let\setreferences \relax
+\let\showcurrentreference \relax
+\let\setexecutecommandcheck\gobbletwoarguments
+
+\def\s!full{full}
+\def\s!text{text}
+\def\s!page{page}
+
+% todo : unknown/illegal reference no arg
+% todo : +n pages check on 'samepage' (contrastcolor)
+% todo : multiple text in reference
+
+% Makes more sense to build action data first, especially now
+% openaction etc are supported.
+%
+% \definespecial\doexecuteactionchain w h
+% \definespecial\dosetgotolocation
+% \definespecial\dosetexecuteJScode
+% ...
+
+%D This module deals with referencing. In \CONTEXT\ referencing
+%D is one of the core features, although at a first glance
+%D probably nobody will notice. This is good, because
+%D referencing should be as hidden as possible.
+%D
+%D In paper documents, referencing comes down to cross
+%D referencing, but in their interactive counterparts, is also
+%D involves navigation. Many features implemented here are
+%D therefore closely related to navigation.
+%D
+%D Many \CONTEXT\ commands can optionally be fed with a
+%D reference. Such a reference, when called upon, returns the
+%D number of a figure, table, chapter etc, a piece of text, or
+%D a pagenumber.
+%D
+%D There are three ways of defining a reference:
+%D
+%D \starttyping
+%D \pagereference[here]
+%D \textreference[here]{some text}
+%D \stoptyping
+%D
+%D the third alternative combines them in:
+%D
+%D \starttyping
+%D \reference[here]{some text}
+%D \stoptyping
+
+\def\textreference {\dosingleargument\dotextreference}
+\def\pagereference {\dosingleargument\dopagereference}
+\def\reference {\dosingleargument\doreference }
+
+%D These are implemented in a low level form as:
+
+\def\dotextreference[#1]{\dosetreference\s!text{#1}}
+\def\dopagereference[#1]{\dosetreference\s!page{#1}{}}
+\def\doreference [#1]{\dosetreference\s!full{#1}}
+
+%D Actually there is not much difference between a text and a
+%D full reference, but it's the concept that counts. The low
+%D level implementation is:
+
+\newcount\crossreferencenumber
+
+\def\dofinishfullreference#1#2%
+ {\normalexpanded{\noexpand\ctxlatelua{jobreferences.enhance("#1","#2")}}%
+ \referenceinfo>{#1\letterbar#2}}
+
+\let\dofinishpagereference\dofinishfullreference
+
+\def\dofinishtextreference#1#2%
+ {\normalexpanded{\noexpand\ctxlatelua{jobreferences.enhance("#1","#2",{})}}%
+ \referenceinfo>{#1\letterbar#2}}
+
+\def\dosetreference#1#2#3% kind labels text -> todo: userdata
+ {\ifreferencing
+ \global\advance\crossreferencenumber\plusone
+ \edef\currentreferencekind{#1}%
+ \edef\currentreferencelabels{#2}%
+ \edef\currentreferenceexpansion{\@@rfexpansion}% {\referenceparameter\c!expansion}
+ \ifx\currentreferencelabels\empty \else
+ \ifx\currentreferenceexpansion\s!xml
+ \xmlstartraw
+ \xdef\currentreferencetext{#3}%
+ \xmlstopraw
+ \globallet\currentreferencecoding\s!xml
+ \else
+ \ifx\currentreferenceexpansion\v!yes
+ \xdef\currentreferencetext{#3}%
+ \else
+ \xdef\currentreferencetext{\detokenize{#3}}%
+ \fi
+ \globallet\currentreferencecoding\s!tex
+ \fi
+ \setnextinternalreference
+ \ctxlua {
+ jobreferences.set("\currentreferencekind", "\referenceprefix","\currentreferencelabels",
+ {
+ references = {
+ internal = \nextinternalreference,
+ block = "\currentstructureblock",
+ section = structure.sections.currentid(),
+ },
+ metadata = {
+ kind = "#1",
+ catcodes = \the\catcodetable,
+ xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text
+ },
+ entries = {
+ text = \!!bs\currentreferencetext\!!es
+ }
+ })
+ jobreferences.setinternalreference("\referenceprefix","\currentreferencelabels",\nextinternalreference)
+ }%
+ \fi
+ \fi}
+
+%D For compatibility we provide:
+
+\def\rawreference #1#2#3{\dosetreference\s!full{#2}{#3}} % tag, labels, text
+\def\rawpagereference #1#2{\dosetreference\s!page{#2}{}} % tag, labels
+\def\rawtextreference#1#2#3{\dosetreference\s!text{#2}{#3}} % tag, labels, text
+
+\def\defaultreferencepage#1{[[[#1]]]}
+\def\defaultreferencetext#1{[[[#1]]]}
+
+%D These macros depend on three other ones,
+%D \type {\makesectionformat}, that generated \type
+%D {\sectionformat}, \type {\pagenumber}. The not yet used
+%D argument \type{#1} is a tag that specifies the type of
+%D reference.
+
+%D \macros
+%D {everyreference}
+%D
+%D For rather tricky purposes, one can assign sanitizing
+%D macros to \type{\everyreference} (no longer that relevant).
+
+\newevery \everyreference \relax
+
+%D This is really needed, since for instance Polish has a
+%D different alphabet and needs accented entries in registers.
+
+\appendtoks
+ \cleanupfeatures
+\to \everyreference
+
+%D We did not yet discuss prefixing. Especially in interactive
+%D documents, it's not always easy to keep track of duplicate
+%D references. The prefix mechanism, which we will describe
+%D later on, solves this problem. By (automatically) adding a
+%D prefix one keeps references local, but the global ones in
+%D view. To enable this feature, we explictly split the prefix
+%D from the reference.
+
+\let\referenceprefix\empty
+
+%D For a long time the only way to access an external file was
+%D to use the file prefix (\type {somefile::}. However, when
+%D you split up a document, redefining the references may be
+%D such a pain, that another approach is feasible. By setting
+%D the \type {autofile} variable to \type {yes} or \type
+%D {page}, you can access the reference directly.
+%D
+%D \starttabulate[||||]
+%D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR
+%D \NC $\star$ \NC \NC \NC\NR
+%D \NC $\star$ \NC $\star$ \NC $\star$ \NC\NR
+%D \NC \NC $\star$ \NC \NC\NR
+%D \stoptabulate
+
+\def\usereferences[#1]%
+ {\writestatus\m!systems{references from other files are handled automatically}}
+
+%D As mentioned we will also use the cross reference mechanism
+%D for navigational purposes. The main reason for this is that
+%D we want to treat both categories alike:
+%D
+%D \starttyping
+%D \goto{go back}[PreviousJump]
+%D \goto{colofon}[colofon page]
+%D \stoptyping
+%D
+%D Here \type{PreviousJump} is handled by the viewer, while the
+%D \type{colofon page} reference is, apart from hyperlinking, a
+%D rather normal reference.
+%D
+%D We already saw that cross refences are written to and read
+%D from a file. The pure navigational ones don't need to be
+%D written to file, but both for fast processing and
+%D transparant integration, they are saved internally as a sort
+%D of reference. We can easily distinguish such system
+%D references from real cross reference ones by their tag.
+%D
+%D We also use the odd/even characteristic to determine the
+%D page state.
+
+\let\currentrealreference \empty
+\let\currentpagereference \empty
+\let\currenttextreference \empty
+\let\currentreferenceorder \empty
+\let\currentsubtextreference \empty
+\let\currentsubsubtextreference\empty
+
+%D System references only have one component:
+
+\newif\ifforwardreference
+\newif\ifrealreferencepage
+
+\def\docheckrealreferencepage#1% todo
+ {\doifnumberelse{#1}
+ {\ifnum#1=\realpageno
+ \realreferencepagetrue
+ \else
+ \realreferencepagefalse
+ \fi}
+ {\realreferencepagefalse}}
+
+%D Text references can contain more than one entry and
+%D therefore we check for
+%D
+%D \starttyping
+%D {entry}
+%D \stoptyping
+%D
+%D or
+%D
+%D \starttyping
+%D {{entry}{entry}{entry}}
+%D \stoptyping
+%D
+%D and split accordingly.
+
+% todo:
+
+\def\doifforwardreferenceelse#1#2% todo
+ {\iffalse}
+
+%D Cross references appear as numbers (figure~1.1, chapter~2)
+%D or pagenumbers (page~2, page 3--2), and are called with
+%D \type{\in} and \type{\at}. In interactive documents we also
+%D have \type{\goto}, \type{\button} and alike. These are more
+%D versatile and look like:
+%D
+%D \starttyping
+%D \goto[reference]
+%D \goto[outer reference::]
+%D \goto[outer reference::inner reference]
+%D \goto[operation(argument)]
+%D \goto[operation(action{argument,argument})]
+%D \goto[action]
+%D \goto[action{argument}]
+%D \stoptyping
+%D
+%D The first one is a normal reference, the second and third
+%D are references to a file or \URL. The brace delimited
+%D references for instance refer to a \JAVASCRIPT. The last
+%D example shows that we can pass arguments to the actions.
+%D
+%D When we split off the components of such a reference, the
+%D results are available in:
+%D
+%D \starttyping
+%D \currentreferencespecial
+%D \currentreferenceoperation
+%D \currentreferencearguments
+%D \currentinnerreference
+%D \currentouterreference
+%D \currentfullreference
+%D \stoptyping
+
+\newif\ifreferencefound
+
+\let\currentfullreference \empty
+\let\currentreferencespecial \empty
+\let\currentreferenceoperation\empty
+\let\currentreferencearguments\empty
+\let\currentouterreference \empty
+\let\currentinnerreference \empty
+
+\def\setreferencevariables#1#2#3#4#5%
+ {\def\currentreferencespecial {#1}%
+ \def\currentreferenceoperation{#2}%
+ \def\currentreferencearguments{#3}%
+ \def\currentouterreference {#4}%
+ \def\currentinnerreference {#5}}
+
+%D Now we've come to the testing step. As we can see below,
+%D this macro does bit more than testing: it also resolves
+%D the reference. This means that whenever we test for the
+%D existance of a reference at an outer level, we have all the
+%D relevant properties of that reference avaliable inside the
+%D true branche~(\type{#2}).
+%D
+%D The prefix has to do with localizing references. When a
+%D prefix is set, looking for a reference comes to looking for
+%D the prefixed one, and when not found, looking for the non
+%D prefixed one. Consider for instance the prefix set to
+%D \type{sidetrack}.
+%D
+%D \starttyping
+%D \pagereference[important]
+%D \pagereference[unimportant]
+%D \setupreferencing[prefix=sidetrack]
+%D \pagereference[important]
+%D \stoptyping
+%D
+%D results in saving (writing) the references
+%D
+%D \starttyping
+%D ...{}{important}
+%D ...{}{unimportant}
+%D ...{sidetrack}{important}...
+%D \stoptyping
+%D
+%D Now when we call for \type{unimportant}, we will indeed get
+%D the pagenumber associated to this reference. But when we
+%D call for \type{important}, while the prefix is still set, we
+%D will get the pagenumber bound to the prefixed one.
+%D
+%D {\em Some day, when processing time and memory are no longer
+%D performance factors, we will introduce multi||level
+%D prefixes.}
+%D
+%D Before we start analyzing, I introduce a general
+%D definition macro. Consider:
+%D
+%D \starttyping
+%D \goto{do}[JS(My_Script{"test",123}),titlepage]
+%D \stoptyping
+%D
+%D This can also be achieved by:
+%D
+%D \starttyping
+%D \definereference[startup][JS(My_Script{"test",123}),titlepage]
+%D \goto{do}[REF(startup)]
+%D \stoptyping
+%D
+%D Now is this is a handy feature or not?
+%D
+%D \showsetup{definereference}
+%D
+%D We can trace references by setting the next switch to
+%D true.
+
+\def\definereference
+ {\dodoubleempty\dodefinereference}
+
+\def\dodefinereference[#1][#2]%
+ {\ctxlua{jobreferences.define("\referenceprefix","#1",\!!bs\detokenize{#2}\!!es)}}
+
+\def\resetreference[#1]%
+ {\ctxlua{jobreferences.reset("\referenceprefix","#1")}}
+
+\def\setpagereference#1#2% name, specification
+ {\ctxlua{jobreferences.define("","#1",\!!bs\v!page(\luaescapestring{#2})\!!es)}}
+
+%D Chained references are defined as:
+%D
+%D \starttyping
+%D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)]
+%D \stoptyping
+%D
+%D Actually supporting chains is up to the special driver. Here
+%D we only provide the hooks.
+
+\newif \ifsecondaryreference
+\newcount\nofsecondaryreferences
+
+% the counter stuff should move to the (mkiv) backend
+
+\def\doifreferencefoundelse#1%
+ {\ctxlua{jobreferences.doifelse("\referenceprefix","#1")}}
+
+\def\doprocessreferenceelse#1#2#3%
+ {\doresetgotowhereever
+ \nofsecondaryreferences\zerocount
+ \def\primaryreferencefoundaction {\secondaryreferencefalse#2}%
+ \def\secondaryreferencefoundaction{\advance\nofsecondaryreferences\plusone\secondaryreferencetrue#2}%
+ \def\referenceunknownaction {#3}%
+ \ctxlua{jobreferences.handle("\referenceprefix","#1")}%
+ \doresetgotowhereever} % to prevent problems with direct goto's
+
+%D The inner case is simple. Only two cases have to be taken
+%D care of:
+%D
+%D \starttyping
+%D \goto{some text}[reference]
+%D \goto{some text}[prefix:reference]
+%D \stoptyping
+%D
+%D References to other files however are treated strict or
+%D tolerant, depending on their loading and availability:
+%D
+%D \starttyping
+%D \useexternaldocument[somefile][filename][a nice description]
+%D
+%D \goto{checked reference}[somefile::reference]
+%D \goto{unchecked reference}[somefile::]
+%D \goto{unchecked reference}[anotherfile::reference]
+%D \stoptyping
+%D
+%D An unknown reference is reported on the screen, in the log
+%D file and, when enabled, in the left margin of the text.
+
+\def\reportreferenceerror#1#2% only once (keep track in lua)
+ {\ifinpagebody \else
+ \doifconcepttracing{\doifsomething{#2}{\inleft{\infofont\doboundtext{#2}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}%
+ \fi
+ \showmessage\m!references{#1}{[\referenceprefix][#2]}}
+
+\def\unknownreference{\reportreferenceerror1}
+\def\illegalreference{\reportreferenceerror4}
+
+%D When a reference is not found, we typeset a placeholder
+%D (two glyphs are often enough to represent the reference
+%D text).
+
+\def\dummyreference{{\tttf ??}}
+
+%D To prevent repetitive messages concerning a reference
+%D being defined, we set such an unknown reference to an empty
+%D one after the first encounter.
+
+%D Sometimes we want to temporary put a reference out of
+%D order. An example can be found in the menu macros.
+%D
+%D \starttyping
+%D \doifreferencepermittedelse{reference}{set}{true}{false}
+%D \stoptyping
+%D
+%D The second argument can be a comma seperated list.
+
+\let\permittedreferences\empty
+
+ \def\doifreferencepermittedelse#1#2#3% ref found notfound
+ {\doprocessreferenceelse{#1}
+ {\donetrue
+ \ifx\permittedreferences\empty \else
+ \docheckifreferencepermitted{#1}%
+ \fi
+ \ifdone#2\else#3\fi}
+ {#3\unknownreference{#1}}}
+
+ \def\docheckifreferencepermitted#1%
+ {\ifx\currentinnerreference\empty
+ \ifx\currentouterreference\empty \else
+ \doifinstring{\currentouterreference::}\permittedreferences\donefalse
+ \fi
+ \else\ifx\currentouterreference\empty
+ \doifinstring{\currentinnerreference}\permittedreferences\donefalse
+ \else
+ \doifinstring{\currentouterreference::\currentinnerreference}\permittedreferences\donefalse
+ \fi\fi}
+
+%D Apart from cross references supplied by the user, \CONTEXT\
+%D generates cross references itself. Most of them are not
+%D saved as a reference, but stored with their source, for
+%D instance a list or an index entry. Such automatically
+%D generated, for the user invisible, references are called
+%D {\em internal references}. The user supplied ones are
+%D labeled as {\em external references}.
+%D
+%D A second important characteristic is that when we want to
+%D support different backends (viewers), we need to support
+%D named destinations as well as page numbers. I invite readers
+%D to take a glance at the special driver modules to understand
+%D the fine points of this. As a result we will deal with {\em
+%D locations} as well as {\em real page numbers}. We explictly
+%D call this pagenumber a real one, because it is independant
+%D of the page numbering scheme used in the document.
+%D
+%D One of the reasons for \CONTEXT\ being the first \TEX\ base
+%D macropackage to support sophisticated interactive \PDF\
+%D files, lays in the mere fact that real page numbers are
+%D available in most two pass data, like references, list data
+%D and index entries.
+%D
+%D We will speak of \type{thisis...} when we are marking a
+%D location, and \type{goto...} when we point to such a
+%D location. The latter one can be seen as a hyperlink to the
+%D former one. In the next macros one we use constructs like:
+%D
+%D \starttyping
+%D \dostart...
+%D \dostop...
+%D \stoptyping
+%D
+%D Such macros are used to invoke the relevant specials from
+%D the special driver modules (see \type{spec-ini}). The flag
+%D \type{\iflocation} signals if we're in interactive mode.
+
+\def\thisisdestination#1% destination
+ {\iflocation \ifusepagedestinations \else
+ \dostartthisislocation{#1}\dostopthisislocation
+ \fi \fi}
+
+\def\thisisrealpage#1% pagenumber
+ {\iflocation
+ \dostartthisisrealpage{#1}\dostopthisisrealpage
+ \fi}
+
+%D The previous tho macros were easy ones, opposite to their
+%D counterparts. A common component in these is:
+%D
+%D \starttyping
+%D \dohandlegoto{..}{..}{..}
+%D \stoptyping
+%D
+%D Here data can be whatever needs highlighting, e.g. {\em
+%D figure 2.4}, and the start and stop entries handle the
+%D specials. The two \DIMENSIONS\ \type{\buttonwidth} and
+%D \type{\buttonheight} have to be set when handling the
+%D data~(\type{#2}).
+
+\ifx\buttonheight\undefined \newdimen\buttonheight \fi
+\ifx\buttonwidth \undefined \newdimen\buttonwidth \fi
+
+\def\gotodestination#1#2#3#4#5% url file destination page data
+ {\iflocation
+ \ifusepagedestinations
+ \gotorealpage{#1}{#2}{\number#4}{#5}%
+ \else
+ \dohandlegoto
+ {#5}%
+ {\the\everyreference\dostartgotolocation\buttonwidth\buttonheight{#1}{#2}{#3}{\number#4}}%
+ {\dostopgotolocation}%
+ \fi
+ \else
+ {#5}%
+ \fi}
+
+ \def\gotorealpage#1#2#3#4% url file page data
+ {\iflocation
+ \dohandlegoto
+ {#4}%
+ {\dostartgotorealpage\buttonwidth\buttonheight{#1}{#2}{\number#3}}%
+ {\dostopgotorealpage}%
+ \else
+ {#4}%
+ \fi}
+
+\def\gotoinnerpage#1#2% page data
+ {\iflocation
+ \dohandlegoto
+ {#2}%
+ {\dostartgotorealpage\buttonwidth\buttonheight\empty\empty{\number#1}}%
+ {\dostopgotorealpage}%
+ \else
+ {#2}%
+ \fi}
+
+\def\gotoouterfilepage#1#2#3% file page data
+ {\iflocation
+ \dohandlegoto
+ {#3}%
+ {\dostartgotorealpage\buttonwidth\buttonheight\empty{#1}{\number#2}}%
+ {\dostopgotorealpage}%
+ \else
+ {#3}%
+ \fi}
+
+%D \macros
+%D {setreferencefilename}
+%D
+%D This command can be used in the special drivers to
+%D uppercase filenames. This is needed when one wants to
+%D produce \CDROM's conforming to ISO9660. We consider is the
+%D savest to enable this feature by default. We cannot handle
+%D uppercase here, since the suffix is handled in the special
+%D driver. Conversion is taken care of by:
+%D
+%D \starttyping
+%D \setreferencefilename somefilename\to\SomeFileName
+%D \stoptyping
+
+\chardef\referencefilecase=0
+
+ \def\setreferencefilename#1\to#2%
+ {\ifcase\referencefilecase
+ \edef#2{#1}%
+ \or
+ \uppercasestring#1\to#2%
+ \or
+ \lowercasestring#1\to#2%
+ \else
+ \edef#2{#1}%
+ \fi}
+
+%D Internal references can best be set using the next few
+%D macros. Setting such references to unique values is
+%D completely up to the macros that call them.
+%D
+%D \starttyping
+%D \thisissomeinternal{tag}{identifier}
+%D \gotosomeinternal {tag}{identifier}{pagenumber}{text}
+%D \stoptyping
+
+\def\thisissomeinternal#1#2% tag reference
+ {\doifsomething{#2}{\thisisdestination{#1:#2}}}
+
+\def\gotosomeinternal#1#2% #3#4
+ {\gotodestination\empty\empty{#1:#2}}
+
+%D An automatic mechanism is provided too:
+%D
+%D \starttyping
+%D \thisisnextinternal{tag}
+%D \gotonextinternal {tag}{number}{pagenumber}{text}
+%D \stoptyping
+%D
+%D The first macro increments a counter. The value of this
+%D counter is available in the macro \type{\nextinternalreference}
+%D and should be saved somewhere (for instance in a file) for
+%D future reference. The second argument of
+%D \type {\gotonextinternal} takes such a saved number. One can
+%D turn on tracing these references, in which case the
+%D references are a bit more verbose.
+
+\newcount\locationcount
+
+\newif\ifinternalnamedreferences \internalnamedreferencestrue
+
+\def\nextinternalreference
+ {\the\locationcount}
+
+\def\setnextinternalreference
+ {\global\advance\locationcount\plusone}
+
+\def\thisisnextinternal#1% #1 will be removed when we are done with mkiv
+ {\ifinternalnamedreferences
+ \thisisdestination{\s!aut:\nextinternalreference}%
+ \fi}
+
+\def\insertnextinternal#1%
+ {\ifinternalnamedreferences
+ \thisisdestination{\s!aut:\number#1}%
+ \fi}
+
+\def\gotonextinternal#1#2#3#4% #1 will be removed when we are done with mkiv
+ {\ifinternalnamedreferences
+ \gotodestination\empty\empty{\s!aut:#2}{#3}{#4}%
+ \else
+ \gotorealpage\empty\empty{#3}{#4}%
+ \fi}
+
+%D We already went through a lot of problems to sort out what
+%D kind of reference we're dealing with. Sorting out the user
+%D supplied cross references (show/goto this or that) as well
+%D as user supplied system references (invoke this or that) is
+%D already taken care of in the test routine, but we still have
+%D to direct the request to the right (first) routine.
+
+\def\gotolocation#1#2{\doprocessreferenceelse{#1}{#2}{\unknownreference{#1}}} % obsolete
+
+%D An inner reference refers to some place in the document
+%D itself.
+
+ \def\gotoinnerlocation#1% #2%
+ {\gotodestination\empty\empty{\referenceprefix\currentinnerreference}\currentrealreference} % {#2}
+
+\def\gotoinner#1#2#3% prefix inner page data
+ {\gotodestination\empty\empty{#1#2}{#3}} % {#4}
+
+%D The outer location refers to another document, specified as
+%D file or \URL.
+
+ \def\gotoouterlocation#1#2% % page checken!
+ {\bgroup
+ \let\referenceprefix\empty
+ \setouterlocation\currentouterreference
+ \ifx\currentinnerreference\empty
+ \gotorealpage\otherURL\otherfile1{#2}%
+ \else
+ \gotodestination\otherURL\otherfile\currentinnerreference\currentrealreference{#2}%
+ \fi
+ \egroup}
+
+\def\gotoouterfile#1#2% file location page data #3 #4
+ {\doifelsenothing{#2}{\gotorealpage\empty{#1}}{\gotodestination\empty{#1}{#2}}}
+
+\def\gotoouterfilepage#1% file page data
+ {\gotorealpage\empty{#1}\empty}
+
+\def\gotoouterfilelocation% file location page data
+ {\gotodestination\empty}
+
+\def\gotoouterurl#1#2% url args data #2
+ {\gotodestination{#1}\empty{#2}1}
+
+%D Special locations are those that are accessed by saying
+%D things like:
+%D
+%D \starttyping
+%D \goto{calculate total}[JS(summarize{10,23,56}]
+%D \stoptyping
+%D
+%D After several intermediate steps this finally arrives at
+%D the next macro and expands into (simplified):
+%D
+%D \starttyping
+%D \gotoJSlocation{total{summarize{10,23,56}}}{calculate total}
+%D \stoptyping
+%D
+%D The first argument is the full reference, the second one
+%D is the text, in some kind of manipulated form. In practice
+%D we split references, so we get:
+%D
+%D \starttyping
+%D \gotoJSlocation{summarize{10,23,56}}{calculate}
+%D \gotoJSlocation{summarize{10,23,56}}{total}
+%D \stoptyping
+%D
+%D where \type{calculate} and \type{total} are colored, boxed
+%D or whatever \type{\goto} is told to do.
+%D
+%D The macro \type{\gotoJSlocation} can use \type
+%D {\currentreferenceoperation} (in our example
+%D \type{summarize}) and \type{\currentreference} (here
+%D being \type {10,23,56}) to perform its task.
+
+ \def\gotospeciallocation
+ {\executeifdefined{goto\currentreferencespecial location}\gobbleoneargument}
+
+%D Such special macros can be defined by:
+
+ \def\definespeciallocation#1%
+ {\setvalue{goto#1location}}
+
+%D The associated test is to be defined by:
+
+\def\definespecialtest#1%
+ {\setvalue{\s!do:\v!test:#1}}
+
+%D This \type{\def} alike macro is to be used as:
+%D
+%D \starttyping
+%D \definespeciallocation{JS}#1#2{... #1 ... #2 ...}
+%D \stoptyping
+%D
+%D In module \type {java-ini} one can see that \type
+%D {\gotoJSlocation} looks much like the previous goto
+%D definitions.
+
+%D In this module we define three system references: one for
+%D handling navigational, viewer specific, commands, another
+%D for jumping to special pages, like the first or last one,
+%D and a third reference for linking tree like lists, like
+%D tables of contents. The latter two adapt themselves to the
+%D current state.
+%D
+%D An example of an action is:
+%D
+%D \starttyping
+%D \goto{some action}[PreviousJump]
+%D \stoptyping
+%D
+%D as well as:
+%D
+%D \starttyping
+%D \goto{some text}[\v!action(PreviousJump]
+%D \stoptyping
+
+% compatibility hack
+
+\def\setglobalsystemreference#1#2#3{\definereference[#2][\v!action(#3)]}
+
+% action actions
+
+\def\gotoactionspecial#1#2#3#4% special operation arguments data
+ {\begingroup
+ \iflocation
+ \dohandlegoto
+ {#4}%
+ {\dostartexecutecommand\buttonwidth\buttonheight{#2}{#3}}%
+ {\dostopexecutecommand}%
+ \else
+ #4%
+ \fi
+ \endgroup}
+
+\def\gotopagespecial#1#2#3#4% page(n) page(+n) page(-n) page(file::1)
+ {\begingroup
+ \iflocation
+ \doifnonzeropositiveelse{#2}
+ {\doifinstringelse+{#2}
+ {\edef\currenttargetpage{\the\numexpr\realpageno#2}}
+ {\doifinstringelse-{#2}
+ {\edef\currenttargetpage{\the\numexpr\realpageno#2}}
+ {\edef\currenttargetpage{#2}}}}%
+ {\edef\currenttargetpage{1}}%
+ \docheckrealreferencepage\currenttargetpage % new
+ \gotorealpage\empty\empty\currenttargetpage{#4}%
+ \else
+ #4%
+ \fi
+ \endgroup}
+
+%D It is possible to disable the writing of references to the
+%D utility file by setting:
+
+\newif\ifreferencing \referencingtrue
+
+%D One can also activate an automatic prefix mechanism. By
+%D setting the \type{\prefix} variable to \type{+}, the prefix
+%D is incremented, when set to \type{-} or empty, the prefix is
+%D reset. Other values become the prefix.
+
+\newcount\prefixcounter
+
+%D These settings are accomplished by:
+%D
+%D \showsetup{setupreferencing}
+%D
+%D In interactive documents verbose references don't always
+%D make sense (what is a page number in an unnumbered
+%D document). By setting the \type{interaction} variable, one
+%D can influences the way interactive references are set.
+
+\chardef\autocrossfilereferences=0
+
+\def\setupreferencing
+ {\dosingleargument\dosetupreferencing}
+
+\def\dosetupreferencing[#1]%
+ {\getparameters
+ [\??rf]
+ [\c!prefix=\s!unknown,#1]%
+ \processaction
+ [\@@rfstate]
+ [ \v!stop=>\referencingfalse,
+ \v!start=>\referencingtrue]%
+ \processaction
+ [\@@rfinteraction]
+ [ \v!all=>\let\dowantedreference\docompletereference,
+ \v!label=>\let\dowantedreference\dolabelonlyreference,
+ \v!text=>\let\dowantedreference\dotextonlyreference,
+ \v!symbol=>\let\dowantedreference\dosymbolreference]%
+ \chardef\autocrossfilereferences\zerocount
+ \processaction
+ [\@@rfautofile]
+ [ \v!yes=>\chardef\autocrossfilereferences\plusone,
+ \v!page=>\chardef\autocrossfilereferences\plustwo]%
+ \chardef\referencefilecase\zerocount
+ \processaction[\@@rfconvertfile]
+ [ \v!yes=>\chardef\referencefilecase\plusone,
+ \v!big=>\chardef\referencefilecase\plusone,
+ \v!small=>\chardef\referencefilecase\plustwo]%
+ \setupreferenceprefix[\@@rfprefix]%
+ \doifelse\@@rfglobal\v!yes
+ {\settrue \autoglobalfilereferences}
+ {\setfalse\autoglobalfilereferences}}
+
+\def\incrementreferenceprefix{+}
+\def\decrementreferenceprefix{-}
+
+\def\setupreferenceprefix[#1]%
+ {\edef\@@rfprefix{#1}%
+ \ifx\@@rfprefix\empty
+ \let\referenceprefix\empty
+ \else\ifx\@@rfprefix\incrementreferenceprefix
+ \advance\prefixcounter \plusone % should be global
+ \edef\referenceprefix{\the\prefixcounter:}%
+ \let\@@rfprefix\s!unknown
+ \else\ifx\@@rfprefix\decrementreferenceprefix
+ \let\referenceprefix\empty
+ \let\@@rfprefix\s!unknown
+ \else\ifx\@@rfprefix\s!unknown
+ % forget about it
+ \else
+ \edef\referenceprefix{\@@rfprefix:}%
+ \fi\fi\fi\fi}
+
+%D \macros
+%D {handlereferenceactions,
+%D collectreferenceactions}
+%D
+%D Sometimes we need to pass the actions connected to
+%D references to variables instead of rectangular areas on
+%D which one can click. The next macro collects the actions
+%D and passes them to a handle. This is a rather dreadfull
+%D hack!
+%D
+%D \starttyping
+%D \handlereferenceactions{references}\handle
+%D \stoptyping
+%D
+%D So, \type {\handle} does the final job, which in for
+%D instance the \PDF\ drivers comes down to doing something
+%D with \type {\lastPDFaction}.
+
+\newif\ifcollectreferenceactions
+
+\def\handlereferenceactions#1#2%
+ {\doifsomething{#1}
+ {\bgroup
+ \collectreferenceactionstrue
+ \doprocessreferenceelse{#1}{#2}{\unknownreference{#1}}%
+ \egroup}}
+
+%D The most straightforward way of retrieving references is
+%D using \type{\ref}. Consider the reference:
+%D
+%D \startbuffer
+%D \reference[my ref]{{Look}{Here}{I am}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D We can ask for upto five reference components:
+%D
+%D \startbuffer
+%D user page reference: \ref[p][my ref]
+%D text reference: \ref[t][my ref]
+%D real page reference: \ref[r][my ref]
+%D sub text reference: \ref[s][my ref]
+%D extra text reference: \ref[e][my ref]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D And get back:
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+\def\ref{\dodoubleargument\doref}
+
+\def\reftypep{\currentpagereference}
+\def\reftypet{\currenttextreference}
+\def\reftyper{\currentrealreference}
+\def\reftypes{\currentsubtextreference}
+\def\reftypee{\currentsubsubtextreference}
+
+\def\doref[#1][#2]%
+ {\ifsecondargument
+% \doifreferencefoundelse{#2}
+% {\executeifdefined{reftype#1}\reftypep}
+% {\unknownreference{#2}\dummyreference}%
+ \else
+ \dummyreference
+ \fi}
+
+%D We can typeset a reference using \type{\in}, \type{\at} and
+%D \type{\about} and goto specific locations using
+%D \type{\goto}. The last one does not make that much sense in
+%D a paper document. To complicate things, \PLAIN\ \TEX\ also
+%D implements an \type {\in} but fortunately that one only
+%D makes sense in math mode.
+%D
+%D Typesetting the reference is a bit more complicated than one
+%D would at first sight expect. This is due to the fact that we
+%D distinguish three (five) alternative calls:
+%D
+%D \placefigure
+%D [here][three calls]
+%D {Three alternatives reference calls.}
+%D {\startcombination[1*3]
+%D {\framed{\type{ \in }}} {a}
+%D {\framed{\type{ \at }}} {b}
+%D {\framed{\type{\goto}}} {c}
+%D \stopcombination}
+%D
+%D \startbuffer
+%D \in figure[fig:three calls]
+%D \in{figure}[fig:three calls]
+%D \in figure a[fig:three calls]
+%D \in{figure}{a}[fig:three calls]
+%D figure~\in[fig:three calls]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This turns up as:
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D
+%D The dual \type{{}} results in a split reference. In a
+%D document meant for paper, one is tempted to use the last
+%D (most straightforward) alternative. When a document is also
+%D meant voor electronic distribution, the former alternatives
+%D have preference, because everything between the \type{\in}
+%D and~\type{[} becomes active (and when asked for, typeset
+%D in a different color and typeface).
+
+\definecommand in {\dospecialin}
+\definecommand at {\dospecialat}
+\definecommand about {\dospecialabout}
+\definecommand from {\dospecialfrom}
+\definecommand over {\dospecialabout} % needed here, else math problems
+
+\def\currentreferencenumber{\ctxlua{jobreferences.filter("number")}}
+\def\currentreferencepage {\ctxlua{jobreferences.filter("page")}}
+\def\currentreferencetitle {\ctxlua{jobreferences.filter("title")}}
+
+\unexpanded\def\dospecialin{\doinatreference\currentreferencenumber}
+\unexpanded\def\dospecialat{\doinatreference\currentreferencepage}
+
+\def\doinatreference#1%
+ {\doifnextoptionalelse{\dodoinatreference{#1}{}}{\dodoinatreference{#1}}}
+
+\def\dodoinatreference#1%
+ {\def\dododoinatreference{\dodododoinatreference{#1}}%
+ \futurelet\next\dododoinatreference}
+
+\unexpanded\def\dospecialabout[#1]%
+ {\dontleavehmode
+ \bgroup
+ \@@rfleft
+ \doprocessreferenceelse{#1}
+ {\let\crlf\space
+ \let\\\space
+ \let\dogotofixed\dogotospace
+ \dogotospace{\limitatetext\currentreferencetitle\@@rfwidth\unknown}[#1]}
+ {\unknownreference{#1}\dummyreference}%
+ \@@rfright
+ \referenceinfo{<}{#1}%
+ \egroup}
+
+%D We arrived at the last step. Before we do the typesetting,
+%D we forget all previous (paragraph bound) settings and make
+%D sure that we remain in horizontal mode. Next we choose
+%D among the several representations.
+
+%D The previously discussed setup macro lets us specify the
+%D representation of references. A symbol reference does not
+%D show the specific data, like the number of a figure, but
+%D shows one of: \hbox {$^\goforwardcharacter$
+%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending
+%D on the direction to go.
+
+ \def\dosymbolreference#1#2[#3]% todo
+ {\bgroup
+ \setupsymbolset[\@@iasymbolset]%
+ \removelastskip
+ \ifx\currentreferencespecial\empty
+ \ifx\currentouterreference\empty
+ \ifnum0\currentrealreference=\zerocount
+ \ifhmode\strut\high{\symbol[\v!nowhere]}\fi
+ \else\ifnum0\currentrealreference>\realpageno
+ \dodosymbolreference{#2}{\high{\symbol[\v!next]}}%
+ \else\ifnum0\currentrealreference<\realpageno
+ \dodosymbolreference{#2}{\high{\symbol[\v!previous]}}%
+ \else
+ \ifhmode\strut\high{\symbol[\v!nowhere]}\fi
+ \fi\fi\fi
+ \else
+ \gotoouterlocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}%
+ \fi
+ \else
+ \gotospeciallocation{#3}{\showlocation{\high{\symbol[\v!somewhere]}}}%
+ \fi
+ \egroup}
+
+ \def\dodosymbolreference#1#2% todo
+ {#1\hbox{\gotorealpage\empty\empty\currentrealreference{\dolocationattributes\??ia\c!style\c!color{#2}}}}
+
+%D The other alternatives just conform their names: only the
+%D label, only the text, or the label and the text.
+
+\def\dounknownreference#1#2[#3]%
+ {\unknownreference{#3}\dotextprefix{#2}\dummyreference}%
+
+\def\docompletereference#1#2[#3]%
+ {\iflocationsplit
+ \doifsomespaceelse{#2}\dogotospace\dogotofixed{\dotextprefix{#2}#1}[#3]%
+ \else
+ \dogotofixed{\dotextprefix{#2}#1}[#3]%
+ \fi}
+
+\def\dolabelonlyreference#1#2[#3]%
+ {\doifsomespaceelse{#2}
+ {\doifsomething{#2}{\dogotospace{#2}[#3]}}
+ {\dogotofixed{\dotextprefix{#2}}[#3]}}
+
+\def\dotextonlyreference#1#2[#3]%
+ {\dotextprefix{#2}\dogotofixed{#1}[#3]}
+
+\let\dowantedreference\docompletereference
+
+%D \macros
+%D {definereferenceformat}
+%D
+%D The next few macros were made for for David Arnold and Taco
+%D Hoekwater. They can be used for predefining reference
+%D texts, and thereby stimulate efficiency.
+%D
+%D [more documentation will be added]
+%D
+%D \starttyping
+%D \definereferenceformat[informula] [left=(,right=),text=formula]
+%D \definereferenceformat[informulas] [left=(,right=),text=formulas]
+%D \definereferenceformat[andformula] [left=(,right=),text=and]
+%D \definereferenceformat[andformulas][left=(,right=),text=and]
+%D
+%D \informula [b] and \informula [for:c]
+%D the \informula {formulas}[b] \informula {and} [for:c]
+%D the \informulas {formulas}[b] \informula {and} [for:c]
+%D the \informulas [b] \informula {en} [for:c]
+%D the \informulas [b] \andformula [for:c]
+%D \stoptyping
+%D
+%D Instead of a text, one can specify a label, which should
+%D be defined with \type {\setuplabeltext}.
+
+% todo: inherit
+
+\def\definereferenceformat
+ {\dodoubleargument\dodefinereferenceformat}
+
+\def\dodefinereferenceformat[#1][#2]%
+ {\iffirstargument
+ \getparameters[\??rf#1]
+ [\c!left=, % of the number
+ \c!right=, % of the number
+ \c!text=, % before the number
+ \c!label=, % can be {left}{right}
+ \c!command=\in,
+ #2]%
+ \unexpanded\setvalue{#1}%
+ {\dontleavehmode\doexecutereferenceformat{#1}}%
+ \fi}
+
+\def\noexecutelabelreferenceformat#1%
+ {\doifvaluesomething{\??rf#1\c!text}
+ {\gdef\textofreference{\csname\??rf#1\c!text\endcsname}}%
+ \csname\??rf#1\c!command\endcsname}
+
+\def\doexecutelabelreferenceformat#1%
+ {\csname\??rf#1\c!command\endcsname
+ {\leftlabeltext {\csname\??rf#1\c!label\endcsname}}%
+ {\rightlabeltext{\csname\??rf#1\c!label\endcsname}}}
+
+\def\doexecutereferenceformat#1%
+ {\gdef\leftofreference {\csname\??rf#1\c!left \endcsname}%
+ \gdef\rightofreference{\csname\??rf#1\c!right\endcsname}%
+ \global\let\textofreference\empty % otherwise ~ added
+ \doifelsevaluenothing{\??rf#1\c!label}
+ \noexecutelabelreferenceformat\doexecutelabelreferenceformat{#1}}
+
+\let\leftofreference \relax
+\let\rightofreference\relax
+\let\textofreference \relax
+
+% fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]%
+
+\def\dodododoinatreference#1#2#3[#4]% no \removeunwantedspaces (fails on metafun)
+ {\ifx\next\bgroup
+ \dododododoinatreference{\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]%
+ \else
+ \dododododoinatreference{\leftofreference#1\rightofreference}{#2#3}[#4]%
+ \fi}
+
+\let\dosymbolreference\dowantedreference
+
+\def\dododododoinatreference#1#2[#3]%
+ {\dontleavehmode % replaces \leaveoutervmode
+ \begingroup
+ \forgetall
+ \postponenotes
+ \doifreferencefoundelse{#3}
+ {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#3]}%
+ {\dounknownreference{#1}{#2}[#3]}%
+ \referenceinfo<{#3}%
+ \endgroup}
+
+
+%D In interactive documents going to a specific location is not
+%D bound to cross references. The \type{\goto} commands can be
+%D used to let users access another part of the document. In
+%D this respect, interactive tables of contents and registers
+%D can be considered goto's. Because in fact a \type{\goto} is
+%D just a reference without reference specific data, the
+%D previous macros are implemented using the goto
+%D functionality.
+%D
+%D \showsetup{goto}
+%D
+%D One important chaacteristic is that the first argument of
+%D \type{\goto} (and therefore \type{\at} and \type{\in} is
+%D split at spaces. This means that, although hyphenation is
+%D prevented, long references can cross line endings.
+
+\newif\ifsharesimilarreferences \sharesimilarreferencestrue
+\newcount\similarreference % 0=noppes 1=create/refer 2,3,..=refer
+
+\unexpanded\def\goto#1#2%
+ {\dogoto{#1}#2}
+
+\def\dogoto#1[#2]%
+ {\dontleavehmode
+ \bgroup
+ \postponenotes
+ % todo: handle empty #1
+ \doifelsenothing{#1}
+ {\dosymbolreference{}{}[#2]}
+ {\dogotospace{#1}[#2]}%
+ \egroup
+ \referenceinfo{<}{#2}}
+
+% inefficient, we need to save the shared one (just reuse last command in lua)
+
+\def\dogotospace#1[#2]%
+ {\iflocationsplit
+ \ifsecondaryreference
+ \setbox\scratchbox\hbox % will change anyway
+ \fi % due to space insertion
+ {\let\dogotospace\dogotofixed
+ \iflocation
+ \def\processisolatedword##1%
+ {\ifisolatedwords\ifsharesimilarreferences
+ \global\advance\similarreference \plusone
+ \fi\fi
+ \hbox\bgroup
+ \doprocessreferenceelse{#2}{##1\presetgoto}{\unknownreference{#2}##1\relax}%
+ \egroup}%
+ \doattributes\??ia\c!style\c!color{\processisolatedwords{#1}\processisolatedword}%
+ \else
+ #1\relax % \relax prevents #1's next macros from gobbling \fi
+ \fi}%
+ \else
+ \iflocation
+ \hbox{\doattributes\??ia\c!style\c!color{\doprocessreferenceelse{#2}{#1\presetgoto}{\unknownreference{#2}#1\relax}}}%
+ \else
+ #1\relax % \relax prevents #1's next macros from gobbling \fi
+ \fi
+ \fi
+ \global\similarreference\zerocount}
+
+\def\dogotofixed#1[#2]%
+ {{\iflocation
+ \hbox{\doattributes\??ia\c!style\c!color{\doprocessreferenceelse{#2}{#1\presetgoto}{\unknownreference{#2}#1\relax}}}%
+ \else
+ #1%
+ \fi}}
+
+%D In case the auto split feature is not needed or even not
+%D even wanted, \type{\gotobox} can be used.
+
+\unexpanded\def\gotobox#1[#2]%
+ {\dontleavehmode
+ \bgroup
+ \locationstrutfalse
+ \doprocessreferenceelse{#2}
+ {\dogotofixed{#1}[#2]}
+ {\hbox{\unknownreference{#2}#1}}%
+ \referenceinfo{<}{#2}%
+ \egroup}
+
+%D An reference to another document can be specified as a file
+%D or as an \URL. Both are handled by the same mechanism and
+%D can be issued by saying something like:
+%D
+%D \starttyping
+%D \goto[dictionary::the letter a]
+%D \stoptyping
+%D
+%D One can imagine that many references to such a dictionary
+%D are made, so in most cases such a document reference in an
+%D indirect one.
+%D
+%D \showsetup{useexternaldocument}
+%D
+%D For example:
+%D
+%D \starttyping
+%D \useexternaldocument
+%D [dictionary][engldict]
+%D [The Famous English Dictionary]
+%D \stoptyping
+%D
+%D The next macro implements these relations, and also take
+%D care of loading the document specific references.
+%D
+%D The \URL\ alternative takes four arguments:
+%D
+%D \showsetup{useURL}
+%D
+%D like:
+%D
+%D \starttyping
+%D \useURL
+%D [dictionary][http://www.publisher.com/public][engldict]
+%D [The Famous English Dictionary]
+%D \stoptyping
+%D
+%D Several specifications are possible:
+%D
+%D \starttyping
+%D \useURL [id] [url] [file] [description]
+%D \useURL [id] [url] [file]
+%D \useURL [id] [url]
+%D \stoptyping
+%D
+%D This time we don't load the references when no file is
+%D specified. This is logical when one keeps in mind that a
+%D valid \URL\ can also be a mail address.
+
+\def\usefile{\dotripleargument\dousefile}
+\def\useurl {\doquadrupleempty\douseurl}
+
+\let\useURL \useurl
+\let\useexternaldocument\usefile
+
+\def\douseurl[#1][#2][#3][#4]%
+ {\ctxlua{jobreferences.urls.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es,\!!bs\detokenize{#4}\!!es)}}
+
+\def\dousefile[#1][#2][#3]%
+ {\ctxlua{jobreferences.files.define("#1",\!!bs\detokenize{#2}\!!es,\!!bs\detokenize{#3}\!!es)}}
+
+% \doifsomething\@@urstyle{\let\@@iastyle\@@urstyle\let\@@urstyle\empty}%
+% \doifsomething\@@urcolor{\let\@@iacolor\@@urcolor\let\@@urcolor\empty}%
+
+%D \macros
+%D {url,setupurl}
+%D
+%D We also have: \type{\url} for directly calling the
+%D description. So we can say:
+%D
+%D \starttyping
+%D \useURL [one] [http://www.test.nl]
+%D \useURL [two] [http://www.test.nl] [] [Some Site]
+%D
+%D \url[one] or \from[two] or \goto{Whatever Site}[URL(two)]
+%D \stoptyping
+%D
+%D An \URL\ can be set up with
+%D
+%D \showsetup{setupurl}
+
+\def\setupurl
+ {\dodoubleargument\getparameters[\??ur]}
+
+\unexpanded\def\url[#1]%
+ {\dontleavehmode
+ \begingroup
+ \dosetfontattribute\??ur\c!style
+ \dosetcolorattribute\??ur\c!color
+ \ctxlua{jobreferences.urls.get("#1","\@@uralternative","\@@urspace")}%
+ \dostopattributes
+ \endgroup}
+
+%D This macro is hooked into a support macro, and thereby
+%D \URL's break ok, according to the setting of a switch,
+%D
+%D \startbuffer
+%D \useURL
+%D [test]
+%D [sentence_sentence%sentence#sentence~sentence/sentence//sentence:sentence.sentence]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Such an \URL\ is, depending on the settings, hyphenated as:
+%D
+%D \getbuffer
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {\hss\en
+%D \setupreferencing[urlalternative=both]%
+%D \vbox{\hsize.25cm\hbox{\bf both}\prewordbreak\url[test]}%
+%D \hss
+%D \setupreferencing[urlalternative=before]%
+%D \vbox{\hsize.25cm\hbox{\bf before}\prewordbreak\url[test]}%
+%D \hss
+%D \setupreferencing[urlalternative=after]%
+%D \vbox{\hsize.25cm\hbox{\bf after}\prewordbreak\url[test]}%
+%D \hss}
+%D \stoplinecorrection
+%D
+%D By setting \type{urlspace=yes} one can get slightly better
+%D spacing when using very long \URL's.
+%D
+%D When defining the external source of information, one can
+%D also specify a suitable name (the last argument). This name
+%D can be called upon with:
+%D
+%D \showsetup{from}
+
+\def\dospecialfrom
+ {\dosingleempty\dodospecialfrom}
+
+\def\dodospecialfrom[#1]%
+ {\dontleavehmode\ctxlua{jobreferences.from("#1","","")}}
+
+%D We also support:
+%D
+%D \starttyping
+%D \goto{some text}[file(identifier{location}]
+%D \stoptyping
+%D
+%D which is completely equivalent with
+%D
+%D \starttyping
+%D \goto{some text}[identifier::location]
+%D \stoptyping
+
+\def\gotofilespecial#1#2#3#4% special operation arguments data
+ {\begingroup\iflocation\gotoouterfile{#2}{#3}{#4}\else#4\fi\endgroup}
+
+\def\gotourlspecial#1#2#3#4% special operation arguments data
+ {\begingroup\iflocation\gotoouterurl{#2}{#3}{#4}\else#4\fi\endgroup}
+
+%D A special case of references are those to programs. These,
+%D very system dependant references are implemented by abusing
+%D some of the previous macros.
+%D
+%D \showsetup{setupprograms}
+%D \showsetup{defineprogram}
+%D \showsetup{program} % changed functionality !
+%D
+%D The latter gives access to the description of the program,
+%D being the last argument to the definition command.
+
+% also lua, like urls and files
+
+\def\setupprograms
+ {\dodoubleargument\getparameters[\??pr]}
+
+\def\defineprogram
+ {\dotripleargument\dodefineprogram}
+
+\def\dodefineprogram[#1][#2][#3]%
+ {\ctxlua{jobreferences.programs.define("#1","#2","#3")}}
+
+\def\program[#1]% incompatible, more consistent, hardy used anyway
+ {\dontleavehmode
+ \begingroup
+ \dosetfontattribute\??pr\c!style
+ \dosetcolorattribute\??pr\c!color
+ \ctxlua{jobreferences.programs.get("#1","\@@pralternative","\@@prspace")}%
+ \endgroup}
+
+% needs an update: program(abc{arg})
+
+\def\gotoprogramspecial#1#2#3#4% special operation arguments data
+ {\begingroup
+ \iflocation
+ \dohandlegoto
+ {#4}%
+ {\dostartrunprogram\buttonwidth\buttonheight{\@@prdirectory#2}{#3}}%
+ {\dostoprunprogram}%
+ \else
+ #4%
+ \fi
+ \endgroup}
+
+%D As we can see, we directly use the special reference
+%D mechanism, which means that
+%D
+%D \starttyping
+%D \goto{some text}[program(name{args})]
+%D \stoptyping
+%D
+%D is valid.
+
+%D The next macro provides access to the actual pagenumbers.
+%D When documenting and sanitizing the original reference
+%D macros, I decided to keep the present meaning as well as to
+%D make this meaning available as a special reference method.
+%D So now one can use:
+%D
+%D \starttyping
+%D \gotopage{some text}[location]
+%D \gotopage{some text}[number]
+%D \gotopage{some text}[file::number]
+%D \stoptyping
+%D
+%D as well as:
+%D
+%D \starttyping
+%D \goto{some text}[page(location)]
+%D \goto{some text}[page(number)]
+%D \goto{some text}[file::page(number)]
+%D \stoptyping
+%D
+%D Here location is a keyword like \type{nextpage}.
+%D
+%D \showsetup{gotopage}
+
+\def\definepage
+ {\dodoubleargument\dodefinepage}
+
+\def\dodefinepage[#1][#2]%
+ {\definereference[#1][page(#1)]}
+
+\def\gotopage#1[#2]%
+ {\goto{#1}[\v!page(#2)]}
+
+%D The previous definitions are somewhat obsolete so we don't
+%D use it here.
+
+%D A still very rudimentary|/|experimental forward|/|backward
+%D reference mechanism is provided by the macro \type{\atpage}:
+%D
+%D \starttyping
+%D ... \somewhere{backward text}{forward text}[someref] ...
+%D ... \atpage[someref] ...
+%D \stoptyping
+%D
+%D In future versions there will be more sophisticated
+
+%D support, also suitable for references to floating bodies.
+
+\def\analysedreference#1%
+ {\ctxlua{jobreferences.analysis("\referenceprefix","#1")}}
+
+\unexpanded\def\somewhere#1#2#3[#4]% #3 gobbles space around #2 % todo
+ {\dontleavehmode
+ \ifcase\analysedreference{#4}\relax
+ \unknownreference{#4}#1/#2%
+ \or
+ \doifelsenothing{#2}{\dosymbolreference{}{}[#4]}{\dogotospace{#2}[#4]}%
+ \or % forward
+ \doifelsenothing{#1}{\dosymbolreference{}{}[#4]}{\dogotospace{#1}[#4]}%
+ \or % backward
+ \doifelsenothing{#2}{\dosymbolreference{}{}[#4]}{\dogotospace{#2}[#4]}%
+ \fi
+ \referenceinfo{<}{#4}}
+
+\unexpanded\def\atpage[#1]% todo
+ {\dontleavehmode
+% \docheckrealreferencepage{}%
+% \doifreferencefoundelse{#1}
+% {\ifrealreferencepage
+% \ifforwardreference
+% \dogotofixed{\labeltext\v!hencefore}[#1]%
+% \else
+% \dogotofixed{\labeltext\v!hereafter}[#1]%
+% \fi
+% \else
+% \dogotofixed{\labeltexts\v!atpage\currentpagereference}[#1]%
+% \fi}
+% {\unknownreference{#1}%
+% \labeltexts\v!page\dummyreference}%
+ \referenceinfo{<}{#1}}
+
+%D We can cross link documents by using:
+%D
+%D \showsetup{coupledocument}
+%D
+%D like:
+%D
+%D \starttyping
+%D \coupledocument[print][somefile][chapter,section]
+%D \stoptyping
+%D
+%D After which when applicable, we have available the
+%D references:
+%D
+%D \starttyping
+%D \goto{print version}[print::chapter]
+%D \stoptyping
+%D
+%D and alike. The title placement definition macros have a
+%D key \type{file}, which is interpreted as the file to jump
+%D to, that is, when one clicks on the title.
+
+\newif\ifautocrossdocument
+
+\def\coupledocument
+ {\doquadrupleempty\docoupledocument}
+
+\def\docoupledocument[#1][#2][#3][#4]% [name] [file] [sections] [description]
+ {\ifthirdargument
+ % this will be done differently (when it's needed)
+ \fi}
+
+%D Buttons are just what their names says: things that can be
+%D clicked (pushed) on. They are similar to \type{\goto},
+%D except that the text argument is not interpreted.
+%D Furthermore one can apply anything to them that can be done
+%D with \type{\framed}.
+%D
+%D \startbuffer
+%D \button[width=3cm,height=1.5cm]{Exit}[ExitViewer]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives
+%D
+%D \getbuffer
+%D
+%D This command is formally specified as:
+%D
+%D \showsetup{button}
+%D
+%D The characteristics can be set with:
+%D
+%D \showsetup{setupbuttons}
+
+\def\setupbuttons
+ {\dodoubleargument\getparameters[\??bt]}
+
+\definecomplexorsimpleempty\button
+
+\def\complexbutton
+ {\docomplexbutton\??bt}
+
+\presetlocalframed[\??bt]
+
+\long\def\docomplexbutton#1[#2]#3#4% get rid of possible space before [#4]
+ {\dodocomplexbutton#1[#2]{#3}#4} % #4 == [
+
+\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie
+
+\long\def\dodocomplexbutton#1[#2]#3[#4]% #3 can contain [] -> {#3} later
+ {\begingroup
+ \doifvalue{#1\c!state}\v!stop\locationfalse
+ \iflocation
+ \resetgoto
+ \ConvertConstantAfter\doifelse{#3}\v!none\hphantom\hbox
+ {\doifelsenothing{#4}
+ {\setlocationboxnop#1[#2]{#3}[#4]}
+ {\doifreferencefoundelse{#4} % INEFFICIENT
+ {\setlocationboxyes#1[#2]{#3}[#4]}
+ {\unknownreference{#4}%
+ \setlocationboxnop#1[#2]{#3}[#4]}}}%
+ \fi
+ \endgroup}
+
+%D Interaction buttons, in fact a row of tiny buttons, are
+%D typically only used for navigational purposed. The next
+%D macro builds such a row based on a specification list.
+%D
+%D \startbuffer
+%D \interactionbuttons
+%D [width=\hsize][page,PreviousJump,ExitViewer]
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D gives
+%D
+%D \getbuffer
+%D
+%D Apart from individual entries, one can use \type{page} and
+%D \type {subpage} as shortcuts to their four associated buttons.
+%D The symbols are derived from the symbols linked to the
+%D entries.
+
+% does not work well with for instance SomeRef{whatever}
+
+\def\interactionbuttons
+ {\dodoubleempty\dointeractionbuttons}
+
+\def\dointeractionbuttons[#1][#2]% er is een verdeel macro \horizontalfractions
+ {\iflocation
+ % BUG: fails when frame=off; best is to rewrite this macro
+ \bgroup
+ \doif\@@ibstate\v!stop\locationfalse
+ \iflocation
+ \ifsecondargument
+ \setupinteractionbar[#1]%
+ \checkinteractionbar{1.5em}\v!broad\!!zeropoint % brrrrr
+ \setbox2\hbox{\localframed[\??ib][\c!background=]{\symbol[\@@iasymbolset][\v!previouspage]}}%
+ \!!heighta\ht2 % needed because we default to nothing
+ \setupinteractionbar[\c!strut=\v!no]%
+ \setinteractionparameter\c!width\!!zeropoint
+ \!!counta\zerocount % new, was 1
+ \processallactionsinset
+ [#2]
+ [ \v!page=>\advance\!!counta 4,
+ \v!subpage=>\advance\!!counta 4,
+ \s!unknown=>\advance\!!counta 1]%
+ \ifdim\@@ibwidth=\zeropoint
+ \!!widtha2em
+ \advance\!!widtha \@@ibdistance % new
+ \!!widthb\!!counta\!!widtha
+ \advance\!!widthb -\@@ibdistance % new
+ \else
+ \!!widtha\@@ibwidth
+ \!!widthb\@@ibdistance % new
+ \multiply\!!widthb \!!counta % new
+ \advance\!!widthb -\@@ibdistance % new
+ \advance\!!widtha -\!!widthb % new
+ \divide\!!widtha \!!counta
+ \!!widthb\@@ibwidth
+ \fi
+ \def\goto##1% clash ?
+ {\setnostrut
+ \edef\localreference{##1}%
+ \normalexpanded{\noexpand\dodocomplexbutton\??ib[\c!height=\the\!!heighta,\c!width=\the\!!widtha]}%
+ {\dontleavehmode\symbol[\@@iasymbolset][\localreference]}%
+ [\localreference]%
+ \hss}%
+ \hbox to \!!widthb
+ {\processallactionsinset
+ [#2]
+ [ \v!page=>\goto\v!firstpage
+ \goto\v!nextpage
+ \goto\v!previouspage
+ \goto\v!lastpage,
+ \v!subpage=>\goto\v!firstsubpage
+ \goto\v!nextsubpage
+ \goto\v!previoussubpage
+ \goto\v!lastsubpage,
+ \s!unknown=>\goto\commalistelement]%
+ \unskip}%
+ \else
+ \interactionbuttons[][#1]%
+ \fi
+ \fi
+ \egroup
+ \fi}
+
+%D \macros
+%D {overlaybutton}
+%D
+%D For converience we provide:
+%D
+%D \starttyping
+%D \overlaybutton[reference]
+%D \stoptyping
+%D
+%D This command can be used to define overlays an/or can be
+%D used in the whatevertext areas, like:
+%D
+%D \starttyping
+%D \defineoverlay[PrevPage][\overlaybutton{PrevPage}]
+%D \setupbackgrounds[page][background=PrevPage]
+%D \setuptexttexts[\overlaybutton{NextPage}]
+%D \stoptyping
+%D
+%D For practical reasons, this macro accepts square brackets
+%D as well as braces.
+
+\definecomplexorsimple\overlaybutton
+
+\def\simpleoverlaybutton#1%
+ {\complexoverlaybutton[#1]}
+
+\def\complexoverlaybutton[#1]%
+ {\iflocation
+ \doprocessreferenceelse{#1}
+ {\overlayfakebox {#1}}
+ {\unknownreference{#1}}%
+ \fi}
+
+\def\overlayfakebox#1%
+ {\hbox
+ {\setbox\scratchbox\null
+ \wd\scratchbox\overlaywidth
+ \ht\scratchbox\overlayheight
+ \locationstrutfalse
+ \box\scratchbox}}
+
+%D \macros
+%D {dotextprefix}
+%D
+%D In previous macros we used \type {\dotextprefix} to
+%D generate a space between a label and a number.
+%D
+%D \starttyping
+%D \dotextprefix{text}
+%D \stoptyping
+%D
+%D Only when \type {text} is not empty, a space is inserted.
+
+\def\dotextprefix#1%
+ {\begingroup
+ \global\labeltextdonefalse % this is an ugly dependancy,
+ \setbox\scratchbox\hbox{#1}% to be solved some day
+ \ifdim\wd\scratchbox>\zeropoint
+ \unhbox\scratchbox
+ \iflabeltextdone\else\@@rfseparator\fi
+ \else
+ \unhbox\scratchbox
+ \fi
+ \endgroup}
+
+%D In the next settings we see some variables that were not
+%D used here and that concern the way the pagenumbers refered
+%D to are typeset.
+
+\setupreferencing
+ [\c!state=\v!start,
+ \c!autofile=\v!no,
+ \v!part\c!number=\v!yes,
+ \v!chapter\c!number=\v!no,
+ \c!interaction=\v!all,
+ \c!convertfile=\v!no,
+ %\c!strut=\v!no, % some day an option
+ \c!prefix=,
+ \c!width=.75\makeupwidth,
+ \c!left=\quotation\bgroup,
+ \c!right=\egroup,
+ \c!global=\v!no,
+ \c!expansion=\v!no,
+ \c!separator=\nonbreakablespace]
+
+\setupurl
+ [\c!alternative=\v!both,
+ \c!space=\v!no,
+ \c!style=\v!type,
+ \c!color=]
+
+\setupprograms
+ [\c!directory=,
+ \c!alternative=\v!both,
+ \c!space=\v!no,
+ \c!style=\v!type,
+ \c!color=]
+
+\definereference [\v!CloseDocument ] [action(close)]
+\definereference [\v!ExitViewer ] [action(exit)]
+\definereference [\v!FirstPage ] [action(first)]
+\definereference [\v!LastPage ] [action(last)]
+\definereference [\v!NextJump ] [action(forward)]
+\definereference [\v!NextPage ] [action(next)]
+\definereference [\v!PauseMovie ] [action(pausemovie)]
+\definereference [\v!PauseSound ] [action(pausesound)]
+\definereference [\v!PauseRendering ] [action(pauserendering)]
+\definereference [\v!PreviousJump ] [action(backward)]
+\definereference [\v!PreviousPage ] [action(previous)]
+\definereference [\v!PrintDocument ] [action(print)]
+\definereference [\v!SaveForm ] [action(exportform)]
+\definereference [\v!LoadForm ] [action(importform)]
+\definereference [\v!ResetForm ] [action(resetform)]
+\definereference [\v!ResumeMovie ] [action(resumemovie)]
+\definereference [\v!ResumeSound ] [action(resumesound)]
+\definereference [\v!ResumeRendering ] [action(resumerendering)]
+\definereference [\v!SaveDocument ] [action(save)]
+\definereference [\v!SaveNamedDocument] [action(savenamed)]
+\definereference [\v!OpenNamedDocument] [action(opennamed)]
+\definereference [\v!SearchDocument ] [action(search)]
+\definereference [\v!SearchAgain ] [action(searchagain)]
+\definereference [\v!StartMovie ] [action(startmovie)]
+\definereference [\v!StartSound ] [action(startsound)]
+\definereference [\v!StartRendering ] [action(startrendering)]
+\definereference [\v!StopMovie ] [action(stopmovie)]
+\definereference [\v!StopSound ] [action(stopsound)]
+\definereference [\v!StopRendering ] [action(stoprendering)]
+\definereference [\v!SubmitForm ] [action(submitform)]
+\definereference [\v!ToggleViewer ] [action(toggle)]
+\definereference [\v!ViewerHelp ] [action(help)]
+\definereference [\v!HideField ] [action(hide)]
+\definereference [\v!ShowField ] [action(show)]
+\definereference [\v!GotoPage ] [action(gotopage)]
+\definereference [\v!GotoPage ] [action(gotopage)]
+\definereference [\v!Query ] [action(query)]
+\definereference [\v!QueryAgain ] [action(queryagain)]
+\definereference [\v!FitWidth ] [action(fitwidth)]
+\definereference [\v!FitHeight ] [action(fitheight)]
+\definereference [\v!ShowThumbs ] [action(thumbnails)]
+\definereference [\v!ShowBookmarks ] [action(bookmarks)]
+
+\definereference [\v!firstpage] [page(\firstpage)]
+\definereference [\v!previouspage] [page(\prevpage)]
+\definereference [\v!nextpage] [page(\nextpage)]
+\definereference [\v!lastpage] [page(\lastpage)]
+\definereference [\v!firstsubpage] [page(\firstsubpage)]
+\definereference [\v!previoussubpage] [page(\prevsubpage)]
+\definereference [\v!nextsubpage] [page(\nextsubpage)]
+\definereference [\v!lastsubpage] [page(\lastsubpage)]
+\definereference [\v!first] [page(\firstpage)]
+\definereference [\v!previous] [page(\prevpage)]
+\definereference [\v!next] [page(\nextpage)]
+\definereference [\v!last] [page(\lastpage)]
+\definereference [\v!first\v!sub] [page(\firstsubpage)]
+\definereference [\v!previous\v!sub] [page(\prevsubpage)]
+\definereference [\v!next\v!sub] [page(\nextsubpage)]
+\definereference [\v!last\v!sub] [page(\lastsubpage)]
+
+%D We cannot set up buttons (not yet, this one calls a menu macro):
+
+\protect \endinput
diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua
new file mode 100644
index 000000000..74dbf90e2
--- /dev/null
+++ b/tex/context/base/strc-reg.lua
@@ -0,0 +1,578 @@
+if not modules then modules = { } end modules ['strc-reg'] = {
+ version = 1.001,
+ comment = "companion to strc-reg.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local texwrite, texsprint, count, format, gmatch = tex.write, tex.sprint, tex.count, string.format, string.gmatch
+
+local ctxcatcodes = tex.ctxcatcodes
+
+local variables = interfaces.variables
+
+local helpers = structure.helpers
+local sections = structure.sections
+local documents = structure.documents
+local pages = structure.pages
+
+-- to be shared, but tested first
+
+local function filter_collected(names,criterium,number,collected,prevmode)
+ if not criterium or criterium == "" then criterium = variables.all end
+ local data = documents.data
+ local numbers, depth = data.numbers, data.depth
+ local hash, result, all = { }, { }, not names or names == "" or names == variables.all
+ if not all then
+ for s in gmatch(names,"[^, ]+") do
+ hash[s] = true
+ end
+ end
+ if criterium == variables.all or criterium == variables.text then
+ for i=1,#collected do
+ local v = collected[i]
+ if all then
+ result[#result+1] = v
+ else
+ local vmn = v.metadata and v.metadata.name
+ if hash[vmn] then
+ result[#result+1] = v
+ end
+ end
+ end
+ elseif criterium == variables.current then
+ for i=1,#collected do
+ local v = collected[i]
+ local sectionnumber = jobsections.collected[v.references.section]
+ if sectionnumber then
+ local cnumbers = sectionnumber.numbers
+ if prevmode then
+ if (all or hash[v.metadata.name]) and #cnumbers >= depth then -- is the = ok for lists as well?
+ local ok = true
+ for d=1,depth do
+ if not (cnumbers[d] == numbers[d]) then -- no zero test
+ ok = false
+ break
+ end
+ end
+ if ok then
+ result[#result+1] = v
+ end
+ end
+ else
+ if (all or hash[v.metadata.name]) and #cnumbers > depth then
+ local ok = true
+ for d=1,depth do
+ local cnd = cnumbers[d]
+ if not (cnd == 0 or cnd == numbers[d]) then
+ ok = false
+ break
+ end
+ end
+ if ok then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ end
+ elseif criterium == variables.previous then
+ for i=1,#collected do
+ local v = collected[i]
+ local sectionnumber = jobsections.collected[v.references.section]
+ if sectionnumber then
+ local cnumbers = sectionnumber.numbers
+ if (all or hash[v.metadata.name]) and #cnumbers >= depth then
+ local ok = true
+ if prevmode then
+ for d=1,depth do
+ if not (cnumbers[d] == numbers[d]) then
+ ok = false
+ break
+ end
+ end
+ else
+ for d=1,depth do
+ local cnd = cnumbers[d]
+ if not (cnd == 0 or cnd == numbers[d]) then
+ ok = false
+ break
+ end
+ end
+ end
+ if ok then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ elseif criterium == variables["local"] then
+ if sections.autodepth(data.numbers) == 0 then
+ return filter_collected(names,variables.all,number,collected,prevmode)
+ else
+ return filter_collected(names,variables.current,number,collected,prevmode)
+ end
+ else -- sectionname, number
+ local depth = sections.getlevel(criterium)
+ local number = tonumber(number) or 0
+ for i=1,#collected do
+ local v = collected[i]
+ local sectionnumber = jobsections.collected[v.references.section]
+ if sectionnumber then
+ local cnumbers = sectionnumber.numbers
+ if (all or hash[v.metadata.name]) and #cnumbers >= depth then -- was >
+ if cnumbers[depth] == number then
+ result[#result+1] = v
+ end
+ end
+ end
+ end
+ end
+ return result
+end
+
+structure.filter_collected = filter_collected
+
+-- we follow a different strategy than by lists, where we have a global
+-- result table; we might do that here as well but since sorting code is
+-- older we delay that decision
+
+jobregisters = jobregisters or { }
+jobregisters.collected = jobregisters.collected or { }
+jobregisters.tobesaved = jobregisters.tobesaved or { }
+
+local tobesaved, collected = jobregisters.tobesaved, jobregisters.collected
+
+local function initializer()
+ tobesaved, collected = jobregisters.tobesaved, jobregisters.collected
+end
+
+job.register('jobregisters.collected', jobregisters.tobesaved, initializer)
+
+local function allocate(class)
+ local d = tobesaved[class]
+ if not d then
+ d = {
+ metadata = {
+ language = 'en',
+ sorted = false,
+ class = class
+ },
+ entries = { },
+ }
+ tobesaved[class] = d
+ end
+ return d
+end
+
+jobregisters.define = allocate
+
+local entrysplitter = lpeg.Ct(lpeg.splitat('+'))
+
+function jobregisters.store(rawdata)
+ local data = allocate(rawdata.metadata.name).entries
+ local entries = rawdata.entries
+ local et = entrysplitter:match(entries[1]) -- alse &
+ local kt = entrysplitter:match(entries[2]) -- alse &
+ entries = { }
+ for k=1,#et do
+ entries[k] = { et[k] or "", kt[k] or "" }
+ end
+ rawdata.list = entries
+ rawdata.entries = nil
+ data[#data+1] = rawdata
+ texwrite(#data)
+end
+
+function jobregisters.enhance(name,n)
+ local r = tobesaved[name].entries[n]
+ if r then
+ r.references.realpage = tex.count[0]
+ end
+end
+
+function jobregisters.extend(name,n,lastsection)
+ local r = tobesaved[name].entries[n]
+ if r then
+ r.references.lastrealpage = tex.count[0]
+ r.references.lastsection = lastsection
+
+ end
+end
+
+-- sorting and rendering
+
+function jobregisters.compare(a,b)
+ local result = 0
+ local compare = sorters.comparers.basic
+ local ea, eb = a.split, b.split
+ local na, nb = #ea, #eb
+ local max = na
+ if nb < max then max = nb end
+ for i=1,max do
+ if result == 0 then
+ result = compare(ea[i],eb[i])
+ else
+ return result
+ end
+ end
+ if result ~= 0 then
+ return result
+ elseif na > nb then
+ return 1
+ elseif nb > na then
+ return -1
+ elseif a.metadata.kind == 'entry' then -- e/f/t
+ local page_a, page_b = a.references.realpage, b.references.realpage
+ if page_a < page_b then
+ return -1
+ elseif page_a > page_b then
+ return 1
+ end
+ else
+ return 0
+ end
+end
+
+function jobregisters.filter(data,options)
+ data.result = structure.filter_collected(nil,options.criterium,options.number,data.entries,true)
+end
+
+function jobregisters.prepare(data)
+ -- data has 'list' table
+ local strip = sorters.strip
+ local splitter = sorters.splitters.utf
+ local result = data.result
+ if result then
+ for i=1, #result do
+ local entry, split = result[i], { }
+ local list = entry.list
+ for l=1,#list do
+ local ll = list[l]
+ local key, word = ll[1], ll[2]
+ if key == "" then
+ key = word
+ end
+ split[l] = splitter(strip(key))
+ end
+ entry.split = split
+ end
+ end
+end
+
+function jobregisters.sort(data,options)
+ sorters.sort(data.entries,jobregisters.compare)
+end
+
+function jobregisters.unique(data,options)
+ local result, prev, equal = { }, nil, table.are_equal
+ for _,v in ipairs(data.result) do
+ if not prev then
+ result[#result+1], prev = v, v
+ else
+ local pr, vr = prev.references, v.references
+ if not equal(prev.list,v.list) then
+ result[#result+1], prev = v, v
+ elseif pr.realpage ~= vr.realpage then
+ result[#result+1], prev = v, v
+ else
+ local pl, vl = pr.lastrealpage, vr.lastrealpage
+ if pl or vl then
+ if not vl then
+ result[#result+1], prev = v, v
+ elseif not pl then
+ result[#result+1], prev = v, v
+ elseif pl ~= vl then
+ result[#result+1], prev = v, v
+ end
+ end
+ end
+ end
+ end
+ data.result = result
+end
+
+function jobregisters.finalize(data,options)
+ local result = data.result
+ data.metadata.nofsorted = #result
+ local split = { }
+ -- maps character to index (order)
+ local se = sorters.entries[options.language or sorters.defaultlanguage] or sorters.entries[sorters.defaultlanguage]
+ for k=1,#result do
+ local v = result[k]
+ local entry, tag = v.split[1][1], ""
+ if se and se[entry] then
+ if type(se[entry]) == "number" then
+ entry = se[entry]
+ end
+ tag = se[entry]
+ else
+ entry = 0
+ tag = "unknown"
+ end
+ local s = split[entry]
+ if not s then
+ s = { tag = tag, data = { } }
+ split[entry] = s
+ end
+ s.data[#s.data+1] = v
+ end
+ data.result = split
+end
+
+function jobregisters.analysed(class,options)
+ local data = collected[class]
+ if data and data.entries then
+ jobregisters.filter(data,options) -- filter entries into results (criteria)
+ jobregisters.prepare(data,options) -- adds split table parallel to list table
+ jobregisters.sort(data,options) -- sorts results
+ jobregisters.unique(data,options) -- get rid of duplicates
+ jobregisters.finalize(data,options) -- split result in ranges
+ data.metadata.sorted = true
+ return data.metadata.nofsorted or 0
+ else
+ return 0
+ end
+end
+
+-- todo take conversion from index
+
+function jobregisters.flush(data,options,prefixspec,pagespec)
+ local equal = table.are_equal
+ texsprint(ctxcatcodes,"\\startregisteroutput")
+ local collapse_singles = options.compress == interfaces.variables.yes
+ local collapse_ranges = options.compress == interfaces.variables.all
+ local result = data.result
+ -- todo ownnumber
+ local function pagenumber(entry)
+ texsprint(ctxcatcodes,"\\registeronepage{")
+ helpers.prefixpage(entry,prefixspec,pagespec)
+ texsprint(ctxcatcodes,"}")
+ end
+ local function pagerange(f_entry,t_entry,is_last)
+ texsprint(ctxcatcodes,"\\registerpagerange{")
+ helpers.prefixpage(f_entry,prefixspec,pagespec)
+ texsprint(ctxcatcodes,"}{")
+ if is_last then
+ helpers.prefixpage(t_entry,prefixspec,pagespec)
+ else
+ helpers.prefixlastpage(t_entry,prefixspec,pagespec)
+ end
+ texsprint(ctxcatcodes,"}")
+ end
+ -- ranges need checking !
+ for k, letter in ipairs(table.sortedkeys(result)) do
+ local sublist = result[letter]
+ local done = { false, false, false, false }
+ local data = sublist.data
+ local d, n = 0, 0
+ texsprint(ctxcatcodes,format("\\startregistersection{%s}",sublist.tag))
+ while d < #data do
+ d = d + 1
+ local entry = data[d]
+ local e = { false, false, false, false }
+ for i=1,4 do -- max 4
+ if entry.list[i] then
+ e[i] = entry.list[i][1]
+ end
+ if e[i] ~= done[i] then
+ if e[i] and e[i] ~= "" then
+ done[i] = e[i]
+ if n == i then
+ texsprint(ctxcatcodes,format("\\stopregisterentries\\startregisterentries{%s}",n))
+ else
+ while n > i do
+ n = n - 1
+ texsprint(ctxcatcodes,"\\stopregisterentries")
+ end
+ while n < i do
+ n = n + 1
+ texsprint(ctxcatcodes,format("\\startregisterentries{%s}",n))
+ end
+ end
+ texsprint(ctxcatcodes,format("\\registerentry{%s}",e[i]))
+ else
+ done[i] = false
+ end
+ end
+ end
+ local kind = entry.metadata.kind
+ if kind == 'entry' then
+ texsprint(ctxcatcodes,"\\startregisterpages")
+ if collapse_singles or collapse_ranges then
+ -- we collapse ranges and keep existing ranges as they are
+ -- so we get prebuilt as well as built ranges
+ local first, last, prev = entry, nil, entry
+ local pages = { }
+ local dd = d
+ while dd < #data do
+ dd = dd + 1
+ local next = data[dd]
+ local el, nl = entry.list, next.list
+ if not equal(el,nl) then
+ dd = dd - 1
+ --~ first = nil
+ break
+ elseif next.references.lastrealpage then
+ if first then
+ pages[#pages+1] = { first, last or first }
+ else
+ pages[#pages+1] = { entry, entry }
+ end
+ pages[#pages+1] = { next, next }
+ first, last, prev = nil, nil, nil
+ elseif not first then
+ first, prev = next, next
+ elseif next.references.realpage - prev.references.realpage == 1 then
+ last, prev = next, next
+ else
+ pages[#pages+1] = { first, last or first }
+ first, last, prev = next, nil, next
+ end
+ end
+ if first then
+ pages[#pages+1] = { first, last or first }
+ end
+ if collapse_ranges and #pages > 1 then
+ -- ok, not that efficient
+ local function doit()
+ local function bubble(i)
+ for j=i,#pages-1 do
+ pages[j] = pages[j+1]
+ end
+ pages[#pages] = nil
+ end
+ for i=2,#pages do
+ local first, second = pages[i-1], pages[i]
+ local first_first, first_last, second_first, second_last = first[1], first[2], second[1], second[2]
+ local first_last_pn = first_last .references.realpage
+ local second_first_pn = second_first.references.realpage
+ local second_last_pn = second_last .references.realpage
+ local first_last_last = first_last.references.lastrealpage
+ local second_first_last = second_first.references.lastrealpage
+ if first_last_last then
+ first_last_pn = first_last_last
+ if second_first == second_last and second_first_pn <= first_last_pn then
+ -- 2=8, 5 -> 12=8
+ bubble(i)
+ return true
+ elseif second_first == second_last and second_first_pn > first_last_pn then
+ -- 2=8, 9 -> 2-9
+ pages[i-1] = { first_first, second_last }
+ bubble(i)
+ return true
+ elseif second_last_pn < first_last_pn then
+ -- 2=8, 3-4 -> 2=8
+ bubble(i)
+ return true
+ elseif first_last_pn < second_last_pn then
+ -- 2=8, 3-9 -> 2-9
+ pages[i-1] = { first_first, second_last }
+ bubble(i)
+ return true
+ elseif first_last_pn + 1 == second_first_pn and second_last_pn > first_last_pn then
+ -- 2=8, 9-11 -> 2-11
+ pages[i-1] = { first_first, second_last }
+ bubble(i)
+ return true
+ elseif second_first.references.lastrealpage then
+ -- 2=8, 9=11 -> 2-11
+ pages[i-1] = { first_first, second_last }
+ bubble(i)
+ return true
+ end
+ elseif second_first_last then
+ second_first_pn = second_first_last
+ if first_last_pn == second_first_pn then
+ -- 2-4, 5=9 -> 2-9
+ pages[i-1] = { first_first, second_last }
+ bubble(i)
+ return true
+ end
+ elseif first_last_pn == second_first_pn then
+ -- 2-3, 3-4 -> 2-4
+ pages[i-1] = { first_last, second_last }
+ bubble(i)
+ return true
+ end
+ end
+ return false
+ end
+ while doit() do end
+ end
+ --
+ if #pages > 0 then -- or 0
+ d = dd
+ for p=1,#pages do
+ local first, last = pages[p][1], pages[p][2]
+ if first == last then
+ if first.references.lastrealpage then
+ pagerange(first,first,true)
+ else
+ pagenumber(first)
+ end
+ elseif last.references.lastrealpage then
+ pagerange(first,last,true)
+ else
+ pagerange(first,last,false)
+ end
+ end
+ else
+ if entry.references.lastrealpage then
+ pagerange(entry,entry,true)
+ else
+ pagenumber(entry)
+ end
+ end
+ else
+ while true do
+ if entry.references.lastrealpage then
+ pagerange(entry,entry,true)
+ else
+ pagenumber(entry)
+ end
+ if d == #data then
+ break
+ else
+ d = d + 1
+ local next = data[d]
+ if not equal(entry.list,next.list) then
+ d = d - 1
+ break
+ else
+ entry = next
+ end
+ end
+ end
+ end
+ texsprint(ctxcatcodes,"\\stopregisterpages")
+ elseif kind == 'see' then
+ -- maybe some day more words
+ texsprint(ctxcatcodes,"\\startregisterseewords")
+ texsprint(ctxcatcodes,format("\\registeroneword{%s}",entry.seeword.text))
+ texsprint(ctxcatcodes,"\\stopregisterseewords")
+ end
+ end
+ while n > 0 do
+ texsprint(ctxcatcodes,"\\stopregisterentries")
+ n = n - 1
+ end
+ texsprint(ctxcatcodes,"\\stopregistersection")
+ end
+ texsprint(ctxcatcodes,"\\stopregisteroutput")
+ -- for now, maybe at some point we will do a multipass or so
+ data.result = nil
+ data.metadata.sorted = false
+end
+
+function jobregisters.analyse(class,options)
+ texwrite(jobregisters.analysed(class,options))
+end
+
+function jobregisters.process(class,...)
+ if jobregisters.analysed(class,...) > 0 then
+ jobregisters.flush(collected[class],...)
+ end
+end
+
diff --git a/tex/context/base/strc-reg.tex b/tex/context/base/strc-reg.tex
new file mode 100644
index 000000000..b764525e1
--- /dev/null
+++ b/tex/context/base/strc-reg.tex
@@ -0,0 +1,907 @@
+%D \module
+%D [ file=strc-reg,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Registers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Registers}
+
+\registerctxluafile{strc-reg}{1.001}
+
+\unprotect
+
+% todo: tag:: becomes rendering
+% todo: language, character, linked, location
+
+%D Helper:
+
+\def\doflushatpar{\ifvmode\expandafter\dogotopar\else\expandafter\firstofoneargument\fi}
+
+% In plaats van + kan een & worden gebruikt. Ook kan als
+% eerste karakter worden opgegeven wat de scheider is.
+%
+% \index {entry}
+% \index[key] {entry}
+% \index[pageclass::] {entry}
+% \index[pageclass::key]{entry}
+% \index {textclass::entry}
+% \index[key] {textclass::entry}
+% \index[pageclass::] {textclass::entry}
+% \index[pageclass::key]{textclass::entry}
+
+%D Parameters:
+
+\let\currentregister\empty
+
+\def\registerparameter#1{\csname\??id\currentregister#1\endcsname}
+
+\def\registerparameter #1{\csname\doregisterparameter{\??id\currentregister}#1\endcsname}
+\def\registerparameterhash#1{\doregisterparameterhash {\??id\currentregister}#1}
+
+\def\doregisterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doregisterparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\doregisterparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doregisterparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\doregisterparentparameter #1#2{\ifx#1\relax\s!empty\else\doregisterparameter #1#2\fi}
+\def\doregisterparentparameterhash#1#2{\ifx#1\relax \else\doregisterparameterhash#1#2\fi}
+
+\def\dosetregisterattributes#1#2% style color
+ {\edef\fontattributehash {\registerparameterhash#1}%
+ \edef\colorattributehash{\registerparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+%D Setup:
+
+\newtoks\everysetupregister
+
+\def\setupregisters
+ {\dotripleempty\dosetupregisters}
+
+\def\dosetupregisters[#1][#2][#3]%
+ {\ifthirdargument
+ \def\dodosetupregister##1{\getparameters[\??id##1#2][#3]}%
+ \processcommalist[#1]\dodosetupregister
+ \else\ifsecondargument
+ \def\dodosetupregister##1{\edef\currentregister{##1}\getparameters[\??id##1][#2]\the\everysetupregister}%
+ \processcommalist[#1]\dodosetupregister
+ \else
+ \getparameters[\??id][#1]%
+ \fi\fi}
+
+\let\setupregister\setupregisters
+
+\setupregisters
+ [\c!n=2,
+ \c!balance=\v!yes, % \v!no komt niet zo vaak voor
+ \c!align=\v!flushleft,
+ \c!tolerance=\v!stretch,
+ \c!before=\blank,
+ %\c!after=,
+ %\c!symbol=,
+ \c!compress=\v!no,
+ \c!interaction=\v!pagenumber,
+ \c!alternative=\v!a,
+ \c!distance=1em,
+ \c!style=\v!bold,
+ \c!pagestyle=\v!slanted,
+ \c!indicator=\v!yes,
+ \c!criterium=\v!all,
+ %\c!command=,
+ \c!referencing=\v!on,
+ \c!location=\v!middle,
+ %\c!maxwidth=,
+ \c!number=\v!no,
+ \c!unknownreference=\v!empty,
+ \c!prefix=\v!both,
+ %\c!expansion=,
+ \c!pageprefixconnector=\endash,
+ \c!pagesegments=2:2,
+ \c!file=\jobname,
+ %\c!deeptextcommand=, % undefined by default !
+ \s!language=\currentmainlanguage]%
+
+%D Definition:
+
+\def\defineregister
+ {\dodoubleargument\dodefineregister}
+
+\def\dodefineregister[#1][#2]% #2?
+ {\setupregister[#1][\s!parent=\??id]%
+ \ctxlua{jobregisters.define('#1')}%
+ \presetheadtext[#1=\Word{#1}]%
+ \unexpanded\setvalue{#1}{\dodoubleempty\doregister[#1]}%
+ \unexpanded\setvalue{\e!see#1}{\dodoubleempty\doseeregister[#1]}%
+% \unexpanded\setvalue{\e!coupled#1}{\dolinkedregister{#1}}%
+ \setvalue{\e!place#1}{\placeregister[#1]}%
+ \setvalue{\e!complete#1}{\completeregister[#1]}%
+ \setvalue{\e!setup#1\e!endsetup}[##1]{\getparameters[\??id#1][##1]}}
+
+%D Registering:
+
+\newif\ifwritetoregister \writetoregistertrue
+
+% tzt variant met n entries, parameters en userdata (altnum)
+
+\def\doprocesspageregister#1#2#3#4#5% register tag key altnum entry
+ {\begingroup
+ \edef\currentregister{#1}%
+ \edef\currentregistertag{#2}%
+ \edef\currentregisterexpansion{\registerparameter\c!expansion}%
+ \edef\currentregisterownnumber{\registerparameter\c!ownnumber}%
+ \ifx\currentregisterexpansion\s!xml
+ \xmlstartraw
+ \xdef\currentregisterentries{\detokenize{#5}}% not ok yet
+ \xmlstopraw
+ \globallet\currentregistercoding\s!xml
+ \else
+ \ifx\currentregisterexpansion\v!yes
+ \xdef\currentregisterentries{#5}% not ok yet
+ \else
+ \xdef\currentregisterentries{\detokenize{#5}}% not ok yet
+ \fi
+ \globallet\currentregistercoding\s!tex
+ \fi
+ \setnextinternalreference
+ % we could consider storing register entries in list
+ \xdef\currentregisternumber{\ctxlua{
+ jobregisters.store {
+ metadata = {
+ kind = "entry",
+ name = "\currentregister",
+ level = structure.sections.currentlevel(),
+ catcodes = \the\catcodetable,
+ own = \ifx\currentregisterownnumber\v!yes "#4" \else nil \fi, % can be used instead of pagenumber
+ },
+ references = {
+ internal = \nextinternalreference,
+ section = structure.sections.currentid(),
+ },
+ entries = {
+ % we need a special one for xml, this is just a single one
+ \!!bs\currentregisterentries\!!es, \!!bs#3\!!es
+ },
+ }
+ } }%
+ \xdef\currentregistersynchronize % make this a macro because shared
+ {\noexpand\ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}%
+ \ifx\currentregisterownnumber\v!yes \else
+ \noexpand\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}%
+ \fi}%
+ \ifx\currentregistertag\empty \else
+ \setxvalue{\??id#1->#2}{\noexpand\dofinishpageregister{\currentregister}{\currentregisternumber}}%
+ \fi
+ \currentregistersynchronize % here?
+ \endgroup}
+
+\def\dofinishpageregister#1#2%
+ {\ctxlatelua{jobregisters.extend("#1",#2,\ctxlua{tex.write(structure.currentsectionnumber())}}}
+
+\def\doregister[#1][#2]%
+ {\def\currentregister{#1}%
+ \doifelse{\registerparameter\c!ownnumber}\v!yes\dodoregister\donoregister{#1}{#2}}
+
+\def\donoregister #1#2{\doflushatpar{\doprocesspageregister{#1}{}{}{#2}}} % register key - entry
+\def\dodoregister#1#2#3{\doflushatpar{\doprocesspageregister{#1}{}{#2}{#3}}} % register key altnum entry
+
+\def\startregister{\doquadrupleempty\dostartregister}
+\def\stopregister {\dodoubleargument\dostopregister}
+
+% a synonym, so that we can nest with overlap without syntax check problems
+
+\let\openregisterrange \startregister
+\let\closeregisterrange\stopregister
+
+\def\dostartregister[#1][#2][#3][#4]#5%
+ {\iffourthargument
+ % #1=register #2=tag #3=own #4=sortkey #5=entry
+ \doflushatpar{\doprocesspageregister{#1}{#2}{#4}{#3}{#5}}%
+ \else
+ % #1=register #2=tag #3=sortkey #5=entry
+ \doflushatpar{\doprocesspageregister{#1}{#2}{#3}{}{#5}}%
+ \fi}
+
+\def\dostopregister[#1][#2]%
+ {\ifcsname\??id#1->#2\endcsname
+ \getvalue{\??id#1->#2}%
+ \letgvalue{\??id#1->#2}\relax
+ \fi}
+
+\def\doseeregister[#1][#2]#3#4%
+ {\doflushatpar{\doprocessseeregister{#1}{#2}{#3}{#4}}}
+
+\def\doprocessseeregister#1#2#3#4% register key entry seeword
+ {\begingroup
+ \edef\currentregister{#1}%
+ \edef\currentregisterexpansion{\registerparameter\c!expansion}%
+ \ifx\currentregisterexpansion\s!xml
+ \xmlstartraw
+ \xdef\currentregisterentries{\detokenize{#3}}% not ok yet
+ \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
+ \xmlstopraw
+ \globallet\currentregistercoding\s!xml
+ \else
+ \ifx\currentregisterexpansion\v!yes
+ \xdef\currentregisterentries{#3}% not ok yet
+ \xdef\currentregisterseeword{#4}% not ok yet
+ \else
+ \xdef\currentregisterentries{\detokenize{#3}}% not ok yet
+ \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet
+ \fi
+ \globallet\currentregistercoding\s!tex
+ \fi
+ \setnextinternalreference
+ % we could consider storing register entries in list
+ \ctxlua{ jobregisters.store {
+ metadata = {
+ kind = "see",
+ name = "\currentregister",
+ level = structure.sections.currentlevel(),
+ catcodes = \the\catcodetable,
+ },
+ references = {
+ internal = \nextinternalreference,
+ section = structure.sections.currentid(),
+ },
+ entries = {
+ % we need a special one for xml, this is just a single one
+ "\currentregisterentries", "#2"
+ },
+ seeword = {
+ text = "\currentregisterseeword"
+ },
+ }
+ }%
+ \endgroup}
+
+%D Rendering:
+
+\let\utilityregisterlength\!!zerocount
+
+\def\determineregistercharacteristics
+ {\dodoubleempty\dodetermineregistercharacteristics}
+
+\def\dodetermineregistercharacteristics[#1][#2]%
+ {\edef\utilityregisterlength{\ctxlua{jobregisters.analyse('\currentregister')}}%
+ \ifcase\utilityregisterlength\relax
+ \resetsystemmode\v!register
+ \else
+ \setsystemmode \v!register
+ \fi}
+
+\newtoks\everyplaceregister
+
+\appendtoks
+ \dontcomplain
+\to \everyplaceregister
+
+\def\placeregister
+ {\dodoubleempty\doplaceregister}
+
+\def\doplaceregister[#1][#2]%
+ {\iffirstargument
+ \begingroup
+ \edef\currentregister{#1}%
+ \setupregister[\currentregister][#2]%
+ \the\everyplaceregister
+ \startcolumns
+ [\c!n=\registerparameter\c!n,
+ \c!balance=\registerparameter\c!balance,
+ \c!align=\registerparameter\c!align,
+ \c!tolerance=\registerparameter\c!tolerance]%
+ \startpacked[\v!blank]%
+ \ctxlua{jobregisters.process('\currentregister',{
+ language = "\registerparameter\s!language",
+ compress = "\registerparameter\c!compress",
+ criterium = "\registerparameter\c!criterium",
+ },
+ {
+% prefix = "\registerparameter\c!pageprefix",
+ separatorset = "\registerparameter\c!pageprefixseparatorset",
+ conversionset = "\registerparameter\c!pageprefixconversionset",
+ stopper = \!!bs\registerparameter\c!pageprefixstopper\!!es,
+ set = "\registerparameter\c!pageprefixset",
+ segments = "\registerparameter\c!pageprefixsegments",
+ connector = \!!bs\registerparameter\c!pageprefixconnector\!!es,
+ },
+ {
+ prefix = "\registerparameter\c!pageprefix",
+ separatorset = "\registerparameter\c!pageseparatorset",
+ conversionset = "\registerparameter\c!pageconversionset",
+ stopper = \!!bs\registerparameter\c!pagestopper\!!es,
+ segments = "\registerparameter\c!pagesegments",
+ }
+ )}%
+ \stoppacked
+ \stopcolumns
+ \endgroup
+ \fi}
+
+\def\dolimitedregisterentry#1{\limitatetext{#1}\currentregistermaxwidth\unknown}%
+
+\appendtoks
+ \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}%
+ \ifx\currentregistermaxwidth\empty
+ \let\limitedregisterentry\firstofoneargument
+ \else
+ \let\limitedregisterentry\dolimitedregisterentry
+ \fi
+\to \everyplaceregister
+
+\def\completeregister
+ {\dodoubleempty\docompleteregister}
+
+\def\docompleteregister[#1][#2]%
+ {\iffirstargument
+ \begingroup
+ \edef\currentregister{#1}%
+ % the expansion is needed because we don't want \v!'s in the tuo file (french)
+ \normalexpanded{\noexpand\systemsuppliedchapter[\currentregister]{\noexpand\headtext{\currentregister}}}%
+ \placeregister[\currentregister][#2]%
+ \page[\v!yes]%
+ \endgroup
+ \fi}
+
+% test case for collapsing (experimental, for Steffen Wolfrum)
+%
+% \starttext
+% \placeregister[index][collapse=no] \blank[2*big]
+% \placeregister[index][collapse=yes] \blank[2*big]
+% \placeregister[index][collapse=akk] \page
+% \dorecurse{10}{test 1:!\index{test} test \page}
+% \dorecurse{5} {test 2:\recurselevel \page}
+% \dorecurse{10}{test 3:!\index{test} test \page}
+% \dorecurse{5} {test 4:\recurselevel \page}
+% \dorecurse{1} {test 5:!\index{test} test \page}
+% \dorecurse{5} {test 6:\recurselevel \page}
+% \dorecurse{10}{test 7:!\index{test} test \page}
+% \dorecurse{5} {test 8:\recurselevel \page}
+% oeps \index{oeps}
+% xxxx \index{xxxx}
+% todo \index{todo}
+% \stoptext
+
+%D Character rendering (sections):
+
+\def\defaultregistercharacter#1%
+ {\doifsomething{#1}
+ {\doifelse{\registerparameter\c!indicator}\v!yes
+ {\executeifdefined{\strippedcsname\doregistercharacter\registerparameter\c!alternative}\doregistercharactera{#1}}
+ {\noregistercharacter{#1}}}}
+
+\def\noregistercharacter#1%
+ {\registerparameter\c!before
+ \goodbreak}
+
+% a = <before> <goodbreak> <character> <par> <after> <nobreak>
+
+\def\doregistercharactera#1%
+ {\registerparameter\c!before
+ \vskip\lineheight\goodbreak\vskip-\lineheight
+ \ifhmode\unskip\else\noindent\fi % brrr
+ \begingroup\dosetregisterattributes\c!style\c!color
+ \registerparameter\c!command{\strut#1}%
+ \endgroup
+ \registerparameter\c!after
+ \par\nobreak}
+
+% b = <goodbreak> <before> <character> <after> <nobreak>
+
+\def\doregistercharacterb#1% here no lineheight hackery ! ! !
+ {\registerparameter\c!before
+ \ifhmode\unskip\else\noindent\fi % brrr
+ \begingroup\dosetregisterattributes\c!style\c!color
+ \registerparameter\c!command{\strut#1}%
+ \endgroup
+ \registerparameter\c!after
+ \nobreak}
+
+% extra:
+
+\def\doregistercharacterA#1{\doregistercharactera{\WORD{#1}}}
+\def\doregistercharacterB#1{\doregistercharacterb{\WORD{#1}}}
+
+%D The following macros are the interface to the rendering. These are
+%D generated by \LUA. This might change.
+
+\def\startregisteroutput
+ {\endgraf}
+
+\def\stopregisteroutput
+ {\endgraf}
+
+\def\startregisterentries#1% depth
+ {\endgraf
+ \begingroup
+ \dosetregisterattributes\c!textstyle\c!textcolor
+ \advance\leftskip\numexpr#1-1\relax\dimexpr\registerparameter\c!distance\relax
+ \hangindent\registerparameter\c!distance\hangafter\plusone}
+
+\def\stopregisterentries
+ {\endgraf
+ \endgroup}
+
+\def\startregistersection#1% title
+ {\registercharacter{#1}\endgraf}
+
+\def\stopregistersection
+ {\endgraf}
+
+\newconditional\registerpagedone
+
+\def\startregisterpages
+ {\begingroup
+ \setfalse\registerpagedone
+ \dosetregisterattributes\c!pagestyle\c!pagecolor}
+
+\def\stopregisterpages
+ {\endgroup}
+
+\def\startregisterseewords
+ {\begingroup
+ \setfalse\registerpagedone
+ \dosetregisterattributes\c!pagestyle\c!pagecolor}
+
+\def\stopregisterseewords
+ {\endgroup}
+
+\def\registerpageseparator% todo: , configurable
+ {\ifconditional\registerpagedone
+ \registerpageseparatorsymbol
+ \else
+ \hskip\registerparameter\c!distance\relax
+ \settrue\registerpagedone
+ \fi}
+
+\def\registeronepage#1% content
+ {\registerpageseparator\registerparameter\c!pagecommand{#1}}
+
+\def\registerpagerange#1#2% content, content todo: -- configurable
+ {\registerpageseparator\registerparameter\c!pagecommand{#1}|--|\registerparameter\c!pagecommand{#2}}
+
+\def\registeroneword#1% content
+ {\registerpageseparator\registerseeword{#1}}
+
+\def\defaultregisterentry #1{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#1}}}}
+\def\defaultregisterseeword#1{\labeltexts\v!see{#1}}
+
+\let\registerseeword \defaultregisterseeword
+\let\registerentry \defaultregisterentry
+\let\registercharacter\defaultregistercharacter
+
+%D A few specific rendering variants:
+
+% \def\doregisterpagelocation#1#2%
+% {\nextregisterpage
+% \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}}
+
+% todo: \installregisterpagehandler
+
+\def\registerpagebuttonsymbol{\vrule\!!width1em\!!height1ex\!!depth\zeropoint\relax}
+
+\setvalue{\??id:\c!symbol :\c!n}{\def\registerpageseparatorsymbol{, }\let\registerpagenumberhandler\firstofoneargument}
+\setvalue{\??id:\c!symbol :\c!a}{\def\registerpageseparatorsymbol{, }\let\registerpagenumberhandler\firstofoneargument} % now done via conversion
+\setvalue{\??id:\c!symbol:\v!none}{\let\registerpageseparatorsymbol\empty\let\registerpagenumberhandler\gobbleoneargument}
+\setvalue{\??id:\c!symbol :1}{\let\registerpageseparatorsymbol\space\def\registerpagenumberhandler{\symbol[1]\gobbleoneargument}}
+\setvalue{\??id:\c!symbol :2}{\let\registerpageseparatorsymbol\space\def\registerpagenumberhandler{\registerpagebuttonsymbol\gobbleoneargument}}
+
+\def\setregisterpagerendering
+ {\edef\currentregisterpagesymbol{\registerparameter\c!symbol}%
+ \ifx\currentregisterpagesymbol\empty
+ \csname\??id:\c!symbol:\c!n\endcsname
+ \else\ifcsname\??id:\c!symbol:\currentregisterpagesymbol\endcsname
+ \csname\??id:\c!symbol:\currentregisterpagesymbol\endcsname
+ \else
+ \let\registerpageseparatorsymbol\space
+ \def\registerpagenumberhandle{\registerparameter\c!symbol\gobbleoneargument}%
+ \fi\fi}
+
+\appendtoks
+ \setregisterpagerendering
+\to \everyplaceregister
+
+%D Don't use \type{\string#2}; another hack is needed, since
+%D \type {#2} can be \type {\string} itself.
+%
+% \def\doregisterreference[#1]#2%
+% {\doifsomething{#2}
+% {\doif{\registerparameter\c!referencing}\v!on
+% {\pagereference[#1:\strippedcsname#2]}}}
+
+% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
+% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
+% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
+
+%D The following code will be reimplemented (not that hard) when it's needed
+%D again and/or when I'm bored.
+
+% \def\getalllistreferences#1#2%
+% {\gdefconvertexpanded\currentregisterentry{\getvalue{\??id#1\c!expansion}}{#2}%
+% \doifdefinedelse{\??id#1\??id\currentregisterentry}
+% {\edef\alllistreferences%
+% {\getvalue{\??id#1\??id\currentregisterentry}}%
+% \beforesplitstring\alllistreferences\at::\to\internallistreference
+% \aftersplitstring \alllistreferences\at::\to\alllistreferences}
+% {\let\alllistreferences\empty
+% \def\internallistreference{0}}}
+
+% \def\dosetlinkregister#1% is die page reference echt nodig?
+% {\setregisterpage{#1}%
+% \global\let\currentregisterentry\empty
+% \global\firstsubentrytrue % not needed
+% \global\firstsubsubentrytrue % not needed too
+% \setvalue{#1\s!entrya}##1{\dosetlinkregisterentrya{#1}{##1}}%
+% \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}}
+
+% \def\dosetlinkregisterentrya#1#2%
+% {\global\utilitydonetrue
+% \c!entryletter
+% \iflocation
+% \getalllistreferences{#1}{#2}%
+% % no \endgraf
+% \hangindent1em\noindent\c!entryreference
+% %
+% %\thisissomeinternal{\s!lin}{\internallistreference}%
+% %
+% \pagereference[-:\s!lin:\internallistreference]% -: added
+% %
+% \getcommacommandsize[\alllistreferences]%
+% \getfromcommacommand[\alllistreferences][1]%
+% \ifnum\commalistsize=1
+% \let\firstlistreference\empty
+% \let\midlistreference\commalistelement
+% \let\lastlistreference\empty
+% \else
+% \let\firstlistreference\commalistelement
+% \getfromcommacommand[\alllistreferences][\commalistsize]%
+% \let\lastlistreference\commalistelement
+% \ifnum\commalistsize=2
+% \let\midlistreference\empty
+% \else
+% \!!counta\commalistsize
+% \divide\!!counta 2
+% \getfromcommacommand[\alllistreferences][\!!counta]%
+% \let\midlistreference\commalistelement
+% \fi
+% \fi
+% % aangepast
+% \def\dodocommand[##1-##2]%
+% {\gotonextinternal{\s!ind}{##1}{##2}{\box0}}%
+% \doifelsevalue{\??id#1\c!interaction}\v!pagenumber
+% {\limitedregisterentry{#1}{#2}} % paginanummer
+% {{\setbox0\hbox{\limitedregisterentry{#1}{\begstrut#2}}%
+% \ifx\firstlistreference\empty % tekst,alles
+% \ifx\midlistreference\empty
+% \box0
+% \else
+% \expandafter\dodocommand\expandafter[\midlistreference]%
+% \fi
+% \else
+% \expandafter\dodocommand\expandafter[\firstlistreference]%
+% \fi}}%
+% \doifvalue{\??id#1\c!number}\v!yes
+% {\hskip\getvalue{\??id#1\c!distance}(\commalistsize)}%
+% \doifnotvalue{\??id#1\c!interaction}\v!text % paginanummer,alles
+% {\def\docommand##1##2%
+% {{\setbox0\hbox{\showlocation{\hbox to 1em{\hss\symbol[##2]\hss}}}%
+% \ifx##1\empty
+% % \hskip\wd0 % (optioneel maken)
+% \else
+% \expandafter\dodocommand\expandafter[##1]%
+% \fi}}%
+% \hskip\getvalue{\??id#1\c!distance}%
+% \docommand\firstlistreference\v!previous
+% \docommand\midlistreference\v!somewhere
+% \docommand\lastlistreference\v!next}%
+% % tot hier
+% \else
+% % no \endgraf
+% \noindent\c!entryreference
+% \limitedregisterentry{#1}{#2}%
+% \fi
+% \endgraf}
+
+% \def\dosetregister#1%
+% {\doifelsevalue{\??id#1\c!coupling}\v!yes
+% {\ifautoregisterhack
+% \dosetautoregister{#1}%
+% \else
+% \dosetlinkregister{#1}%
+% \fi}
+% {\dosetpageregister{#1}}}
+
+\def\dosetregister#1%
+ {\dosetpageregister{#1}}
+
+% \newcounter\internallistreference
+
+% \def\doloadregisterlinks#1%
+% {\setregisterpage{#1}%
+% \global\let\currentregisterentry\empty
+% \global\firstregisterpagetrue
+% \setvalue{#1\s!entrya}##1%
+% {\global\firstregisterpagetrue
+% \gdefconvertedargument\currentregisterentry{##1}% global nodig?
+% \doglobal\increment\internallistreference}%
+% \setvalue{#1\s!from}%
+% {\getvalue{#1\s!page}}%
+% \ifautoregisterhack
+% \setvalue{#1\s!page}##1##2##3##4%
+% {\doifreglevelelse[##3]
+% {\global\utilitydonetrue
+% \iffirstregisterpage
+% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
+% {\internallistreference::##4}%
+% \else % catches errors in index
+% \ifcsname\??id#1\??id\currentregisterentry\endcsname
+% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
+% {\csname\??id#1\??id\currentregisterentry\endcsname,##4}%
+% \fi
+% \fi}
+% {}}%
+% \else
+% \setvalue{#1\s!page}##1##2##3##4%
+% {\doifreglevelelse[##3]
+% {\global\utilitydonetrue
+% \iffirstregisterpage
+% \global\firstregisterpagefalse
+% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
+% {\internallistreference::##2-##4}%
+% \else % catches errors in index
+% \ifcsname\??id#1\??id\currentregisterentry\endcsname
+% \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname
+% {\csname\??id#1\??id\currentregisterentry\endcsname,##2-##4}%
+% \fi
+% \fi}
+% {}}%
+% \fi}
+
+% \def\docoupleregister[#1][#2]%
+% {\iflocation
+% \ifcase0\countervalue{autolink:#1}\relax % only once
+% \begingroup
+% \let\dosetregister\doloadregisterlinks
+% \def\currentregister{#1}%
+% \setupregister[#1][#2]%
+% \mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister
+% \endgroup
+% \ifautoregisterhack
+% \doinitializeautoregister{#1}%
+% \else
+% \doinitializelinkregister{#1}%
+% \fi
+% \fi
+% \fi}
+
+% \def\coupleregister
+% {\dodoubleempty\docoupleregister}
+
+% \def\dodocommandprolinrefAA[#1-#2]%
+% {\def\lastlistreference{#1-#2}}
+
+% \def\dodocommandprolinrefA[#1-#2]%
+% {\def\lastlistreference{#1-#2}%
+% \ifx\firstlistreference\empty
+% \let\firstlistreference\lastlistreference
+% \fi
+% \ifnum#1<\nextinternalreference\relax
+% \let\prevlistreference\lastlistreference
+% \else\ifnum#1>\nextinternalreference\relax
+% \let\nextlistreference\lastlistreference
+% \let\dodocommandprolinrefA\dodocommandprolinrefAA
+% \else
+% \let\selflistreference\lastlistreference
+% \fi\fi}
+
+% \def\docommandprolinrefA#1%
+% {\dodocommandprolinrefA[#1]}
+
+% \def\dodocommandprolinrefB[#1-#2]%
+% {\gotonextinternal{\s!ind}{#1}{#2}{\box0}}
+
+% \def\docommandprolinrefB#1#2#3%
+% {\bgroup
+% \ifx#2\empty
+% \doifvalue{\??id#1\c!unknownreference}\v!empty{\hskip1em}%
+% \else
+% \setbox0\hbox to 1em{\hss\showlocation{\symbol[#3]}\hss}%
+% \expandafter\dodocommandprolinrefB\expandafter[#2]%
+% \fi
+% \egroup}
+
+% \def\doprocesslinkregister[#1][#2]#3%
+% {\hbox
+% {\doprocesspageregister{}{#2}{}{#3}%
+% \let\firstlistreference\empty
+% \let\lastlistreference\empty
+% \let\selflistreference\empty
+% \let\prevlistreference\empty
+% \let\nextlistreference\empty
+% \getalllistreferences{#1}{#3}%
+% \ifx\alllistreferences\empty \else
+% \normalexpanded{\noexpand\rawprocesscommalist[\alllistreferences]}\docommandprolinrefA
+% \fi
+% \ifx\prevlistreference\empty
+% \let\prevlistreference\lastlistreference
+% \fi
+% \ifx\nextlistreference\empty
+% \let\nextlistreference\firstlistreference
+% \fi
+% \ifx\prevlistreference\selflistreference
+% \let\prevlistreference\empty
+% \let\nextlistreference\empty
+% \fi
+% \setalignmentswitch{\getvalue{\??id#1\c!location}}%
+% \ifcase\alignmentswitch
+% % links
+% \docommandprolinrefB{#1}\prevlistreference\v!previous
+% \docommandprolinrefB{#1}\nextlistreference\v!next
+% \or
+% % midden
+% \docommandprolinrefB{#1}\prevlistreference\v!previous
+% \or
+% % rechts
+% \fi
+% \doifreferencefoundelse{\s!lin:\internallistreference}
+% {\gotosomeinternal
+% \s!lin \internallistreference \currentrealreference
+% {\showlocation{\limitedregisterentry{#1}{#3}}}}
+% {\hbox{\limitedregisterentry{#1}{#3}}}%
+% \ifcase\alignmentswitch
+% % links
+% \or
+% % midden
+% \docommandprolinrefB{#1}\nextlistreference\v!next
+% \or
+% % rechts
+% \docommandprolinrefB{#1}\prevlistreference\v!previous
+% \docommandprolinrefB{#1}\nextlistreference\v!next
+% \fi}}
+
+% \def\doprocesslinkedregister[#1][#2]#3% page auto link
+% {\bgroup
+% \chardef\registerpagestatus\plusone
+% \def\currentregister{#1}%
+% \iflocation % \next is not needed
+% \ifautoregisterhack
+% \def\next{\doprocessautoregister[#1][#2]}%
+% \else
+% \def\next{\doprocesslinkregister[#1][#2]}%
+% \fi
+% \else
+% \def\next{\doprocesspageregister{}{#2}{}}%
+% \fi
+% \next{#3}%
+% \egroup}
+
+% \def\dodolinkedregister[#1][#2]#3% page auto link
+% {\doflushatpar{\doprocesslinkedregister[#1][#2]{#3}}}
+
+% \def\dolinkedregister#1%
+% {\dodoubleempty\dodolinkedregister[#1]}
+
+% \def\dosetautoregister#1%
+% {\makecounter{autolink:#1}%
+% \setregisterpage{#1}%
+% \global\let\currentregisterentry\empty
+% \global\firstsubentrytrue % not needed
+% \global\firstsubsubentrytrue % not needed too
+% \setvalue{#1\s!entrya}##1{\dosetautoregisterentrya{#1}{##1}}%
+% \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}}
+
+% \def\dosetautoregisterentrya#1#2%
+% {\global\utilitydonetrue
+% \c!entryletter
+% \iflocation
+% \getalllistreferences{#1}{#2}%
+% \endgraf\hangindent1em\noindent\c!entryreference
+% \pagereference[-:\s!lin:\internallistreference]%
+% \pluscounter{autolink:#1}%
+% \bgroup
+% %\setupinteraction[\c!color=,\c!contrastcolor=,\c!style=]% kan sneller
+% \resetinteractionparameter\c!color
+% \resetinteractionparameter\c!contrastcolor
+% \resetinteractionparameter\c!style
+% \gotobox
+% {\limitedregisterentry{#1}{\begstrut#2}}%
+% [JS(SetRegisterEntry{\v!register,\countervalue{autolink:#1},#2,{\alllistreferences}})]%
+% \egroup
+% \else
+% \endgraf\noindent\c!entryreference
+% \limitedregisterentry{#1}{#2}%
+% \fi}
+
+% \def\doprocessautoregister[#1][#2]#3%
+% {\hbox
+% {\doprocesspageregister{}{#2}{}{#3}%
+% \doifreferencefoundelse{\s!lin:\internallistreference}
+% {\gotosomeinternal \s!lin
+% {\internallistreference}{\currentrealreference}
+% {\showlocation{\limitedregisterentry{#1}{#3}}}}
+% {\hbox{\limitedregisterentry{#1}{#3}}}}}
+
+% \appendmacro aan openpaginaactie (in shipout)
+
+%D The first implementation used one main field with clones.
+%D In a 2500 page document this resulted in a rather (anoying)
+%D long start||up time. This \quote {every page its own field}
+%D solution, combined with a \quote {page open action}, works
+%D much faster, but is conceptually pretty weak.
+
+% \def\complexregisterfield[#1]%
+% {\definefield[#1:\realfolio][line][\v!register]%
+% \field[#1:\realfolio]}
+
+% \def\simpleregisterfield
+% {\complexregisterfield[\v!register]}
+
+% \definecomplexorsimple\registerfield
+
+% \appendtoks
+% % for now
+% \setupfield
+% [\v!register]
+% [\c!width=10em,
+% \c!height=3ex,
+% \c!align=\v!middle,
+% \c!option=\v!readonly,
+% \c!location=\v!low]
+% \to \everydump
+
+% \def\doinitializeautoregister#1%
+% {\useJSscripts[reg]%
+% \useJSpreamblenow{LinkedRegisters}%
+% \setupinteraction[\c!openpageaction=JS(UpdateRegisterField{\v!register})]%
+% \definereference[\v!reset\v!register][JS(ResetRegisterEntry{\v!register})]%
+% \definereference[\v!first\v!register][JS(GotoFirstRegisterEntry{\v!register})]%
+% \definereference[\v!previous\v!register][JS(GotoPreviousRegisterEntry{\v!register})]%
+% \definereference[\v!next\v!register][JS(GotoNextRegisterEntry{\v!register})]%
+% \definereference[\v!last\v!register][JS(GotoLastRegisterEntry{\v!register})]}
+
+% \def\doinitializelinkregister#1%
+% {}
+
+% todo ruwe register
+
+%D Default index:
+
+\defineregister
+ [\v!index]
+ [\v!indices]
+
+% \setupregister[index][koppeling=ja]
+%
+% \stelveldenin
+% [register][achtergrond=raster,kader=uit]
+%
+% \stelvoettekstenin
+% [{\field[index]}]
+%
+% \stelhoofdtekstenin
+% [{\naar {first}[eersteindex]\quad
+% \naar{previous}[vorigeindex]\quad
+% \naar {next}[volgendeindex]\quad
+% \naar {last}[laatsteindex]\quad\quad
+% \naar {index}[index]}]
+%
+% \starttekst
+%
+% oeps~~~\gekoppeldeindex{oeps} \blanko
+% flop~~~\gekoppeldeindex{flop} \blanko
+% test~~~\gekoppeldeindex{test} \pagina
+% flop~~~\gekoppeldeindex{flop} \blanko
+% test~~~\gekoppeldeindex{test} \pagina
+% oeps~~~\gekoppeldeindex{oeps} \blanko
+% test~~~\gekoppeldeindex{test} \pagina
+% flop~~~\gekoppeldeindex{flop} \blanko
+% oeps~~~\gekoppeldeindex{oeps} \pagina
+%
+% \volledigeindex
+
+\protect \endinput
diff --git a/tex/context/base/strc-ren.tex b/tex/context/base/strc-ren.tex
new file mode 100644
index 000000000..c2b8ffd83
--- /dev/null
+++ b/tex/context/base/strc-ren.tex
@@ -0,0 +1,467 @@
+%D \module
+%D [ file=strc-ren,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Section Rendering,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Section Rendering}
+
+\unprotect
+
+\chardef\headtimingmode=0
+
+% \chardef\headtimingmode=1 % 0 also works ok now too
+%
+% Martin Kolarik's problem:
+%
+% \setuphead[section][command=\doTitle]
+% \def\doTitle#1#2{\ruledvbox{\forgetall \hsize=4cm \ruledhbox{\ruledvtop{#1}\ruledvtop{#2}}}}
+% \section{test test test test test test test test test test test test test test test test test}
+
+\newevery \everyheadstart \relax
+
+\def\placeheadmargintexts
+ {\the\everyheadstart
+ \doif{\structureheadparameter\c!margintext}\v!yes\placemargincontent}
+
+\def\doplaceheadtextcomponent#1#2%
+ {\begingroup
+ \dosetstructureheadattributes\c!style\c!color
+ \dosetstructureheadattributes\c!textstyle\c!textcolor
+ \dontconvertfont
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \setupinterlinespace
+ \else
+ \setupspacing
+ \fi
+ % \ifcase\headtimingmode#1\fi % can introduce cr
+ \structureheadparameter\c!commandbefore
+ \placeheadmargintexts
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \structureheadparameter\c!textcommand% struts can be nilled with \setnostrut
+ {\setstrut
+ \begstrut
+ \ifcase\headtimingmode\hbox{#1}\fi
+ \executeifdefined{\??nh\currentstructurehead\c!deeptextcommand}\firstofoneargument{#2}%
+ \endstrut}% \hbox prevents break
+ \xdef\localheadheight {\the\strutht}%
+ \xdef\localheaddepth {\the\strutdp}%
+ \xdef\localheadlineheight{\the\lineheight}%
+ % == \globallet\localheaddepth\strutdepth
+ \else
+ \ifcase\headtimingmode#1\fi
+ \structureheadparameter\c!textcommand
+ {\executeifdefined{\??nh\currentstructurehead\c!deeptextcommand}\firstofoneargument{#2}}%
+ \fi
+ \structureheadparameter\c!commandafter
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \endgraf
+ \fi
+ \endgroup}
+
+\def\doplaceheadnumbercomponent#1#2%
+ {\begingroup
+ \dosetstructureheadattributes\c!style\c!color
+ \dosetstructureheadattributes\c!numberstyle\c!numbercolor
+ % \getvalue{\??ko\currentstructurehead\c!commandbefore}% strange, why here? moved 21/11/2005
+ \placeheadmargintexts
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ % can be nilled with \setnostrut
+ \structureheadparameter\c!numbercommand
+ {\setstrut
+ \begstrut
+ \executeifdefined{\??nh\currentstructurehead\c!deepnumbercommand}\firstofoneargument{#2}%
+ \endstrut}%
+ \else
+ \structureheadparameter\c!numbercommand
+ {\executeifdefined{\??nh\currentstructurehead\c!deepnumbercommand}\firstofoneargument{#2}}%
+ \fi
+ \endgroup}
+
+% \newif\ifheadnumbercontent
+% \newif\ifemptyhead
+% \newif\ifdisplaysectionhead
+
+\def\doplacestructureheadtext#1#2#3% nodes, text, endstuff
+ {\beginheadplacement
+\postponenotes
+ \doresettructureheadnumbercontent
+ \ifconditional\structureheadleaveempty % \ifemptyhead
+ \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi to \zeropoint{#1}%
+ \makestrutofbox\sectionheadbox
+ \else
+ \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi
+ {\doresettructureheadnumbercontent
+ \ifcase\headtimingmode\or#1\fi % outerside font determines distance
+ \dosetfontattribute{\??nh\currentstructurehead}\c!style % but we don't want color to influence user command, todo: get the if-else out of it
+ \structureheadparameter\c!command{}{\doplaceheadtextcomponent{#1}{#2}}}%
+ \fi
+ \endheadplacement{#3}}
+
+\def\doplacestructureheadnumbertext#1#2#3#4% nodes number text nodes
+ {\beginheadplacement
+\postponenotes
+ \doiftextelse{#2}\dosettructureheadnumbercontent\doresettructureheadnumbercontent
+ \ifconditional\structureheadleaveempty % \ifemptyhead % = needed
+ \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi to \zeropoint{#1}%
+ \makestrutofbox\sectionheadbox
+ \else % = needed
+ \setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi
+ {\ifcase\headtimingmode\or#1\fi
+ \dosetfontattribute{\??nh\currentstructurehead}\c!style
+ \structureheadparameter\c!command{\doplaceheadnumbercomponent{#1}{#2}}{\doplaceheadtextcomponent{#1}{#3}}}%
+ \fi
+ \endheadplacement{#4}}
+
+\def\placestructureheadnumbertext
+ {\doplacestructureheadnumbertext\empty\getstructureheadnumber\getstructureheadtitle\getstructureheadsyncs}
+
+\def\placestructureheadtext
+ {\doplacestructureheadtext\empty\getstructureheadtitle\getstructureheadsyncs}
+
+\def\placestructureheadnothing
+ {\getstructureheadsyncs}
+
+%D \starttyping
+%D \def\StretchedBox#1%
+%D {\framed
+%D [frame=off,offset=.5em,align=middle,width=broad]
+%D {\sc\def\stretchedspaceamount{.3em}\stretchednormalcase{#1}}}
+%D
+%D \definehead[MySubject][subject]
+%D \setuphead [MySubject][deeptextcommand=\StretchedBox]
+%D
+%D \MySubject{feeling stretched feeling stretched feeling stretched feeling stretched}
+%D \stoptyping
+
+\let\headlastlinewidth\!!zeropoint
+
+\def\localheadheight {\strutht}
+\def\localheaddepth {\strutdp}
+\def\localheadlineheight{\lineheight}
+
+\def\dolocalheadsetup % koppeling met standaard kopcommando / engels
+ {\forgetall % traag dus ...
+ \doifsomething{\structureheadparameter\c!align } {\normalexpanded{\noexpand\setupalign [\structureheadparameter\c!align ]}}%
+ \doifsomething{\structureheadparameter\c!tolerance} {\normalexpanded{\noexpand\setuptolerance[\structureheadparameter\c!tolerance]}}%
+ \doif {\structureheadparameter\c!strut }\v!no{\setnostrut}% new
+ \def\\{\crlf\strut\ignorespaces}}
+
+\def\beginheadplacement
+ {\bgroup
+ \setsystemmode\currentstructurehead
+ \ifgridsnapping\iftracegridsnapping\showstruts\fi\fi
+ \xdef\localheadheight {\the\strutht}%
+ \xdef\localheaddepth {\the\strutdp}%
+ \xdef\localheadlineheight{\the\lineheight}%
+ % == \globallet\localheaddepth\strutdp
+ \everypar\emptytoks % needed indeed
+ \noindent % ipv \whitespace elders, na \forgetall !
+ \bgroup
+ \doifinsetelse{\structureheadparameter\c!aligntitle}{\v!yes,\v!float}% new
+ {\skip0 1\leftskip
+ \skip2 1\rightskip
+ \xdef\localheadskip{\the\skip0}%
+ \forgetall
+ \leftskip\skip0
+ \rightskip\skip2
+ \setlocalhsize\hsize\localhsize
+ \forgetbothskips}
+ {\globallet\localheadskip\!!zeropoint
+ \forgetall}%
+ \dontcomplain
+ \postponenotes
+ \iflocation
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \else
+ \noninterferingmarks
+ \fi
+ \fi
+ \resetinteractionparameter\c!style
+ \resetinteractionparameter\c!color
+ \resetinteractionparameter\c!contrastcolor
+ %\strictouterreferencestrue % tzt instelling
+ \let\localheadsetup\dolocalheadsetup
+ \startsynchronization}
+
+% \setuphead[chapter] [style=\bfd,after=,hang=line] % fit broad 2
+% \setuphead[section] [style=\bfc,after=,hang=line]
+% \setuphead[subsection] [style=\bfb,after=,hang=line]
+% \setuphead[subsubsection] [style=\bfa,after=,hang=line]
+% \setuphead[subsubsubsection][style=\bf ,after=,hang=line]
+%
+% \chapter {Test} \input tufte \page
+% \section {Test} \input tufte \page
+% \subsection {Test} \input tufte \page
+% \subsubsection {Test} \input tufte \page
+% \subsubsubsection{Test} \input tufte \page
+%
+% \chapter {Test\\Test} \input tufte \page
+% \section {Test\\Test} \input tufte \page
+% \subsection {Test\\Test} \input tufte \page
+% \subsubsection {Test\\Test} \input tufte \page
+% \subsubsubsection{Test\\Test} \input tufte \page
+
+\def\hangheadplacement
+ {\scratchdimen\localheadlineheight
+ \bgroup
+ \openlineheight\scratchdimen
+ \scratchdimen\htdp0%
+ \getnoflines\scratchdimen
+ \advance\noflines\minusone
+ \normalexpanded{\egroup\noflines\the\noflines}% brrr
+ \setbox0\hbox{\lower\noflines\scratchdimen\box0}%
+ \scratchdimen\dimexpr\htdp0-\localheadheight+\strutdp\relax
+ \ht0 \strutht
+ \dp0 \strutdp
+ \edef\localheaddepth{\the\strutdp}}
+
+\newconditional\continuoussectionhead % oeps, \newif\ifcontinuoushead got lost
+\newbox\sectionheadbox
+
+\def\endheadplacement#1%
+ {\doifelse{\structureheadparameter\c!state}\v!start
+ {\doifnothing{\structureheadparameter\c!file}{\autocrossdocumentfalse}}
+ {\autocrossdocumentfalse}%
+ % no message needed here, should be a proper switch
+ \noflines\zerocount
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ % new (tod tight == one following line up)
+ \processaction
+ [\structureheadparameter\c!hang]
+ [ \v!line=>\hangheadplacement\noflines\zerocount,
+ \v!broad=>\hangheadplacement\getnoflines\scratchdimen,
+ \v!fit=>\hangheadplacement\getrawnoflines\scratchdimen,
+ \v!none=>\noflines\zerocount,
+ \v!default=>\noflines\zerocount,
+ \v!unknown=>\hangheadplacement\noflines\numexpr0\commalistelement-1\relax]%
+ % so far
+ \let\headlastlinewidth\!!zeropoint
+ \snaptogrid[\structureheadparameter\c!grid]\hbox
+ {\hskip\localheadskip
+ \hskip\structureheadparameter\c!margin\relax
+ \iflocation
+% \ifautocrossdocument
+% \doifreferencefoundelse{\structureheadparameter\c!file::\currentstructurehead}
+% {\edef\currentinnerreference{\s!aut:\currenttextreference}% stored in
+% \gotoouterlocation{}{\box\sectionheadbox}} % text slot
+% {\hbox{\box\sectionheadbox}}%
+% \else
+ \hbox{\box\sectionheadbox}%
+% \fi
+ \else
+ \hbox{\box\sectionheadbox}%
+ \fi}%
+ \doflushnotes % new, not really needed
+ \endgraf
+ \ifvmode
+ \ifnum\noflines>\zerocount
+ \dorecurse\noflines{\nointerlineskip\dosomebreak\nobreak\strut\endgraf}% to be checked
+ \fi
+ \nointerlineskip
+ \dosomebreak\nobreak
+ \fi
+ #1%
+ \else
+ \strut
+ \doflushnotes % new, here since we're in par mode
+ \iflocation
+ \ifautocrossdocument
+ \hhboxindent=\ifconditional\continuoussectionhead\headlastlinewidth\else\zeropoint\fi
+ \unhhbox\sectionheadbox\with{\gotobox{\box\hhbox}[\structureheadparameter\c!file::\currentstructurehead]}%
+ \advance\lasthhboxwidth by \numberheaddistance
+ \xdef\headlastlinewidth{\the\lasthhboxwidth}%
+ \else
+ \unhbox\sectionheadbox
+ \globallet\headlastlinewidth\!!zeropoint
+ \fi
+ \else
+ \unhbox\sectionheadbox
+ \globallet\headlastlinewidth\!!zeropoint
+ \fi
+ #1%
+ \hskip\numberheaddistance\!!plus\numberheaddistance\!!minus.25\dimexpr\numberheaddistance\relax
+ \hskip\continuousstructureheadsignal\ignorespaces
+ \fi
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \ifvmode
+ \ifgridsnapping % important, font related depth, see comment
+ \prevdepth\strutdp
+ \else
+ \prevdepth\localheaddepth
+ \fi
+ \fi
+ \fi
+ \stopsynchronization
+ \egroup
+ \egroup
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \checknextindentation[\structureheadparameter\c!indentnext]%
+ \else
+ \nonoindentation % recently added, was a bug
+ \fi}
+
+% nice testcase
+%
+% \setupheads[aligntitle=yes]
+%
+% \startnarrower
+% \subject{\dorecurse{100}{x }}
+% \section{\dorecurse{100}{x }}
+% \input tufte \par
+% \setupheads[alternative=inmargin]
+% \subject{\dorecurse{100}{x }}
+% \section{\dorecurse{100}{x }}
+% \input tufte \par
+% \stopnarrower
+
+\let\numberheadalternative\v!normal
+
+\def\defineheadplacement
+ {\dodoubleargument\dodefineheadplacement}
+
+\def\dodefineheadplacement[#1][#2]% #3#4
+ {\setvalue{\??ns:#1}{#2}%
+ \setvalue{\??ns::#1}}
+
+\def\normalplacehead
+ {\executeifdefined
+ {\??ns::\numberheadalternative}
+ {\getvalue{\??ns::\v!normal}}}
+
+\defineheadplacement[\v!paragraph][\v!vertical]#1#2%
+ {\vbox
+ {\localheadsetup
+ \begstrut
+ \ifconditional\structureheadshownumber % \ifheadnumbercontent
+ #1\hskip\numberheaddistance
+ \fi
+ #2}}
+
+% \defineheadplacement[\v!normal][\v!vertical]#1#2%
+% {\ifconditional\structureheadshownumber % \ifheadnumbercontent
+% \setbox0\hbox{{#1}\hskip\numberheaddistance}%
+% \vbox
+% {\localheadsetup
+% \hangindent 1\wd0
+% \hangafter 1
+% \noindent
+% \unhbox0 % don't use \strut's here!
+% #2}%
+% \else
+% \vbox
+% {\localheadsetup\noindent#2}%
+% \fi}
+%
+% enhanced version:
+
+% \setuphead
+% [chapter]
+% [numberwidth=2cm,hang=line,after={\blank[3*line]}]
+%
+% \chapter{Oeps oeps oeps} \input tufte \section{Oeps}
+% \chapter{Oeps oeps oeps} \section{Oeps} \input tufte
+
+\defineheadplacement[\v!normal][\v!vertical]#1#2%
+ {\vbox
+ {\localheadsetup
+ \edef\headwidth {\structureheadparameter\c!width }%
+ \edef\headnumberwidth{\structureheadparameter\c!numberwidth}%
+ \edef\headtextwidth {\structureheadparameter\c!textwidth }%
+ \ifconditional\structureheadshownumber % \ifheadnumbercontent
+ \ifx\headwidth\empty
+ \else
+ \ifx\headnumberwidth\empty
+ \ifx\headtextwidth\empty\else
+ \edef\headnumberwidth{\the\dimexpr\headwidth-\headtextwidth\relax}%
+ \fi
+ \else
+ \ifx\headtextwidth\empty
+ \edef\headtextwidth{\the\dimexpr\headwidth-\headnumberwidth\relax}%
+ \fi
+ \fi
+ \hsize\headwidth
+ \fi
+ \ifx\headnumberwidth\empty\else
+ \let\numberheaddistance\!!zeropoint
+ \fi
+ \setbox\scratchbox\hbox \ifx\headnumberwidth\empty\else to \headnumberwidth\fi{{#1}}%
+ \scratchdimen\dimexpr\wd\scratchbox+\numberheaddistance\relax
+ \ifx\headtextwidth\empty\else
+ \hsize\dimexpr\scratchdimen+\headparameter\c!textwidth\relax
+ \fi
+ \hangindent\scratchdimen
+ \hangafter \plusone
+ \noindent
+ \box\scratchbox\hskip\numberheaddistance
+ \else
+ \ifx\headtextwidth\empty
+ \ifx\headwidth\empty
+ \else
+ \hsize\headwidth
+ \fi
+ \else
+ \hsize\headtextwidth
+ \fi
+ \noindent
+ \fi
+ #2}}
+
+\def\placeheadmargin#1#2%
+ {\vbox
+ {\localheadsetup
+ \begstrut % use one \strut here!
+ \dontleavehmode % in case there is no strut, else side effects with llap
+ \ifconditional\structureheadshownumber % \ifheadnumbercontent
+ \llap{\hbox to 5em{\hfill{#1}\hskip\localheadskip\hskip\leftmargindistance}}% introduces whitespace
+ % maybe better:
+ % \inleftmargin{\hbox{\hss{#1}\hskip\localheadskip}}%
+ \fi
+ {#2}}}
+
+\defineheadplacement[\v!inmargin][\v!vertical]#1#2{\placeheadmargin{#1}{#2}}
+\defineheadplacement[\v!margin] [\v!vertical]#1#2{\placeheadmargin{#1}{#2}}
+
+\defineheadplacement[\v!middle][\v!vertical]#1#2%
+ {\vbox
+ {\localheadsetup
+ \veryraggedcenter
+ \let\\\endgraf
+ \let\crlf\endgraf
+ \ifconditional\structureheadshownumber % \ifheadnumbercontent
+ \strut#1\par
+ \fi
+ \begstrut#2}}
+
+\defineheadplacement[\v!text][\v!horizontal]#1#2%
+ {\bgroup
+ \localheadsetup % no stretch in distance
+ \ifconditional\structureheadshownumber % \ifheadnumbercontent
+ {#1}\kern\numberheaddistance
+ \fi
+ {\begstrut#2}%
+ \egroup}
+
+\def\placeheadlohi#1#2#3%
+ {\ifconditional\structureheadshownumber % \ifheadnumbercontent
+ \setbox0\hbox{#2}
+ \setbox2=#1{\localheadsetup\advance\hsize-\wd0\relax#3}%
+ \hbox{\box0\hskip\numberheaddistance\box2}%
+ \else
+ #1{\localheadsetup\noindent#3}%
+ \fi}
+
+% onder/boven lijnt het nummer op de onderste/bovenste regel
+% uit van een meerregelige kop
+
+\defineheadplacement[\v!bottom][\v!vertical]#1#2{\placeheadlohi\vbox{#1}{#2}}
+\defineheadplacement[\v!top] [\v!vertical]#1#2{\placeheadlohi\vtop{#1}{#2}}
+
+\protect \endinput
diff --git a/tex/context/base/strc-sbe.tex b/tex/context/base/strc-sbe.tex
new file mode 100644
index 000000000..de7c2af63
--- /dev/null
+++ b/tex/context/base/strc-sbe.tex
@@ -0,0 +1,137 @@
+%D \module
+%D [ file=strc-sbe,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Section Block Environments,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Section Block Environments}
+
+\unprotect
+
+% \def\ChapterEntry#1#2#3%
+% {chapter : \hbox to \hsize{\strut\bf#2\hss#3}\endgraf\placelist[section]}
+%
+% \startfrontmatter % optional
+% \placelist[chapter][alternative=command,command=\ChapterEntry,criterium=text] \page
+% \stopfrontmatter % optional
+%
+% \startbodymatter % optional
+% \chapter{first} \section{one} test \section{two} test \page
+% \chapter{second} \section{alpha} test \section{beta} test \page
+% \stopbodymatter % optional
+
+\definesystemvariable {nb}
+
+\def\v!structureblockenvironment{structureblockenvironment}
+
+\def\definestructureblock{\dotripleargument\dodefinestructureblock}
+\def\setupstructureblock {\dodoubleargument\dosetupstructureblock}
+\def\setstructureblock {\dosingleargument\dosetstructureblock}
+
+% \def\structureblockparameter#1{\executeifdefined{\??nb\currentstructureblock#1}\empty}
+
+\def\structureblockparameter#1%
+ {\csname
+ \ifcsname\??nb\currentstructureblock#1\endcsname\??nb\currentstructureblock#1\else\s!empty\fi
+ \endcsname}
+
+\newtoks \everybeforestructureblock
+\newtoks \everyafterstructureblock
+
+\def\dodefinestructureblock[#1][#2][#3]% singular plural settings
+ {\getparameters
+ [\??nb#1]
+ [\c!number=\v!yes,
+ \c!page=\v!right, % anders worden marks te vroeg gereset !
+ #3]%
+ \expandafter\newif\csname if#2\endcsname % better a mode
+ \setstructureblockenvironment{#1}\empty
+ \setvalue {\e!start#2}{\startstructureblock[#1]}%
+ \setvalue {\e!stop #2}{\stopstructureblock}}
+
+\appendtoks
+ \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}%
+% TODO \resetsectionmarks\zerosection
+ \getstructureblockenvironment\currentstructureblock
+ \structureblockparameter\c!before % don't move
+\to \everybeforestructureblock
+
+\appendtoks
+ \structureblockparameter\c!after % don't move
+ \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}%
+% TODO \resetsectionmarks\zerosection
+\to \everyafterstructureblock
+
+\def\dosetupstructureblock[#1]%
+ {\getparameters[\??nb#1]}% [#2]
+
+\def\dosetstructureblock[#1]% used to set the default
+ {\edef\currentstructureblock{\ctxlua{structure.sections.setblock("#1")}}}
+
+\let\currentstructureblock\s!unknown
+
+\def\startstructureblock[#1]%
+ {\begingroup
+ \edef\currentstructureblock{\ctxlua{structure.sections.pushblock("#1")}}%
+ \csname #1true\endcsname % for old times sake
+ \setsystemmode\currentstructureblock
+ \the\everybeforestructureblock\relax
+ \showmessage\m!structures1\currentstructureblock}
+
+\def\stopstructureblock
+ {\showmessage\m!structures2\currentstructureblock
+ \the\everyafterstructureblock\relax
+ \edef\currentstructureblock{\ctxlua{structure.sections.popblock()}}%
+ \endgroup}
+
+\long\def\setstructureblockenvironment#1#2%
+ {\long\setvalue{\??nb\s!do#1}{\do{#2}}}
+
+\def\getstructureblockenvironment#1%
+ {\let\do\firstofoneargument
+ \structureblockparameter{\s!do#1}}
+
+%D \starttyping
+%D \startsectionblockenvironment[frontpart]
+%D \setuppagenumbering[conversion=romannumerals]
+%D \stopsectionblockenvironment
+%D
+%D \startsectionblockenvironment[bodypart]
+%D \setuppagenumber[number=1]
+%D \stopsectionblockenvironment
+%D
+%D \startsectionblockenvironment[frontpart]
+%D \setuppagenumbering[conversion=character]
+%D \stopsectionblockenvironment
+%D
+%D \starttext
+%D \startfrontmatter \chapter{test} \stopfrontmatter
+%D \startbodymatter \chapter{test} \stopbodymatter
+%D \startappendices \chapter{test} \stopappendices
+%D \stoptext
+%D \stoptyping
+
+\setvalue{\e!start\v!structureblockenvironment}%
+ {\dosingleargument\dostartstructureblockenvironment}
+
+\def\dostartstructureblockenvironment[#1]% evt \pushendofline \popendofline
+ {\long\def\do##1##2{\setstructureblockenvironment{#1}{##1##2}}%
+ \grabuntil{\e!stop\v!structureblockenvironment}{\structureblockparameter{\s!do#1}}}
+
+% this will become: (we ran in parallel for a while during transition)
+
+\setvalue{\e!start\v!sectionblockenvironment}%
+ {\dosingleargument\dostartsectionblockenvironment}
+
+\def\dostartsectionblockenvironment[#1]% evt \pushendofline \popendofline
+ {\long\def\do##1##2{\setstructureblockenvironment{#1}{##1##2}}%
+ \grabuntil{\e!stop\v!sectionblockenvironment}{\structureblockparameter{\s!do#1}}}
+
+\protect \endinput
diff --git a/tex/context/base/strc-sec.tex b/tex/context/base/strc-sec.tex
new file mode 100644
index 000000000..a45564c43
--- /dev/null
+++ b/tex/context/base/strc-sec.tex
@@ -0,0 +1,667 @@
+%D \module
+%D [ file=strc-sec,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Sectioning,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Sectioning}
+
+\unprotect
+
+% compatibility issue:
+%
+% \def\setfullsectionnumber #1{}
+% \def\preparefullnumber #1{}
+% \def\fullsectionnumber {1--1--1}
+% \def\makesectionnumber [#1]{}
+% \def\makesectionformat {}
+% \def\sectionformat {1--1-1-1-1-1-1}
+% \def\composedsectionnumber{}
+% \def\@@kolist{}
+
+% \setuphead[section] [separator=\separatorlist{?,!,*}]
+% \setuphead[subsection][separator=\separatorlist{??,!!,**}]
+%
+% \let\spr\separatorlist % this will enable this feature
+%
+% \setuphead[section] [separator={?,!,*}]
+% \setuphead[subsection][separator={??,!!,**}]
+%
+% \setupheads[separator={A,B,C,D,E,F}]
+% \chapter{test}
+% \section{test} \subsection{test} \subsection{test}
+% \section{test} \subsection{test} \subsection{test}
+
+% lua interface
+
+\def\setstructurelevel #1#2{\ctxlua{structure.sections.setlevel("#1","#2")}} % name, level|parent
+\def\getstructurelevel #1{\ctxlua{structure.sections.getcurrentlevel("#1")}}% name
+\def\setstructurenumber #1#2{\ctxlua{structure.sections.setnumber(#1,"#2")}} % level, number (+/-)
+\def\getstructurenumber #1{\ctxlua{structure.sections.getnumber(#1)}} % level
+\def\getfullstructurenumber#1{\ctxlua{structure.sections.fullnumber(#1)}} % level
+
+% interface
+
+\def\structureheadparameter #1{\csname\dostructureheadparameter{\??nh\currentstructurehead}#1\endcsname}
+\def\structureheadparameterhash#1{\dostructureheadparameterhash {\??nh\currentstructurehead}#1}
+
+\def\dostructureheadparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructureheadparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\dostructureheadparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dostructureheadparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dostructureheadparentparameter #1#2{\ifx#1\relax\s!empty\else\dostructureheadparameter #1#2\fi}
+\def\dostructureheadparentparameterhash#1#2{\ifx#1\relax \else\dostructureheadparameterhash#1#2\fi}
+
+\def\dosetstructureheadattributes#1#2% style color
+ {\edef\fontattributehash {\structureheadparameterhash#1}%
+ \edef\colorattributehash{\structureheadparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+% so far
+
+\newcount\maxstructuredepth
+
+\let\laststructuresectionname\empty
+
+\def\definestructuresection[#1]%
+ {\doifundefined{\??nh#1}
+ {\global\advance\maxstructuredepth\plusone
+ \setevalue{\??nh#1\c!level}{\the\maxstructuredepth}%
+ \setstructurelevel{#1}{\the\maxstructuredepth}%
+% \letvalue{\??nh#1\c!marking}\empty % ?
+ %\writestatus{structure}{#1\ifx\laststructuresectionname\empty\else\space->\space\laststructuresectionname\fi}%
+ \normalexpanded{\noexpand\getparameters[\??nh#1][\s!parent=\??nh\laststructuresectionname]}%
+ \definemarking[#1]%
+ \ifnum\maxstructuredepth>\plusone
+% \normalexpanded{\noexpand\couplemarking[#1][\laststructuresectionname]}% so, the child inherits settings from the parent
+ \normalexpanded{\noexpand\relatemarking[#1][\laststructuresectionname]}% so, the parent will reset the child
+ \fi
+ \xdef\laststructuresectionname{#1}}}
+
+\def\setupstructuresection
+ {\dotripleempty\dosetupstructuresection}
+
+\def\dosetupstructuresection[#1]%
+ {\doifdefinedelse{\??nh#1}
+ {\dodosetupstructuresection[#1]}
+ {\dodosetupstructuresection[\structuresectionheadsection{#1}]}}
+
+\def\dodosetupstructuresection[#1][#2][#3]%
+ {\ifthirdargument
+ \getparameters[\??nh#1#2][#3]% ? probably sectionblock
+ \else
+ \getparameters[\??nh#1][#2]%
+ \fi}
+
+\def\structuresectionlevel#1%
+ {\executeifdefined{\??nh#1\c!level}0}
+
+% head -> structurehead
+
+\let\currentstructurehead\empty
+\newtoks\everystructureheadsetup
+
+\def\setupstructureheads{\dosingleargument\dosetupstructureheads}
+\def\setupstructurehead {\dodoubleempty\dosetupstructurehead}
+\def\definestructurehead{\dodoubleempty\dodefinestructurehead}
+
+\newif\ifsectionnumber % maybe conditional
+
+\def\dosetupstructureheads[#1]%
+ {\getparameters[\??nh][#1]%
+ \doifelse{\structureheadparameter\c!sectionnumber}\v!yes\sectionnumbertrue\sectionnumberfalse}
+
+\def\dosetupstructurehead[#1][#2]% we move the test for command being nothing elsewhere (needed, else hard to trace)
+ {\processcommalist[#1]{\dodosetupstructurehead{#2}}}
+
+\def\dodosetupstructurehead#1#2%
+ {\getparameters[\??nh#2][#1]%
+ \the\everystructureheadsetup}
+
+\def\dodefinestructurehead[#1][#2]%
+ {\processcommalist[#1]{\dododefinestructurehead{#2}}}
+
+\def\dododefinestructurehead#1#2% #1: parameters|parent, #2: self
+ {\doifsomethingelse{#2}
+ {\doifassignmentelse{#1}
+ \dodefineuniquestructurehead
+ {\doifdefinedelse{\??nh#1\s!parent} % just a check
+ \dodefineclonedstructurehead
+ \dodefineerrorstructurehead}}
+ \dodefineerrorstructurehead
+ {#2}{#1}}
+
+\def\dodefineerrorstructurehead#1#2%
+ {\setvalue{#1}{\par error: #1 is undefined\par}}
+
+% deeptextcommand and deepnumbercommand are left undefined !
+
+\def\dodefineuniquestructurehead#1#2% class, parameters
+ {\def\currentstructurehead{#1}%
+ \presetlabeltext[#1=]%
+ \getparameters[\??nh#1][\c!label=#1,#2]%
+ \edef\currentstructureheaddefault{\structureheadparameter\c!default}%
+ \edef\currentstructureheadsection{\structureheadparameter\c!section}%
+ \edef\currentstructureheadparent
+ {\??nh
+ \ifx\currentstructurehead\currentstructureheaddefault
+ \currentstructureheadsection
+ \else\ifx\currentstructureheaddefault\empty
+ \currentstructureheadsection
+ \else
+ \currentstructureheaddefault
+ \fi\fi}%
+ \normalexpanded{\noexpand\getparameters[\??nh#1][\s!parent=\currentstructureheadparent]}% \setevalue{\??nh#1\s!parent}{\currentstructureheadparent}%
+ \ifx\currentstructureheadsection\empty
+ %\writestatus{structure}{#1->\currentstructureheadparent}%
+ \else
+ %\writestatus{structure}{#1->\currentstructureheadparent\space(\currentstructureheadsection)}%
+ % todo: filtercommand
+ \definemarking[#1][\currentstructureheadsection]%
+ \definemarking[#1\v!number][#1]%
+ \setupmarking[#1][\c!filtercommand=\sectionheadmarkingtitle{#1}]%
+ \setupmarking[#1\c!number][\c!filtercommand=\sectionheadmarkingnumber{#1}]%
+ \fi
+ \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}% definestructurelist ?
+ \the\everystructureheadsetup}
+
+\def\sectionheadmarkingtitle #1#2{\ctxlua{structure.marks.title("#1","#2")}}
+\def\sectionheadmarkingnumber#1#2{\ctxlua{structure.marks.number("#1","#2")}}
+
+\def\dodefineclonedstructurehead#1#2% class parent
+ {\def\currentstructurehead{#1}%
+ \presetlabeltext[#1=]%
+ \doifelse{#1}{#2}
+ {\getparameters[\??nh#1][\c!label=#1]%
+ \doifundefined{\??li#1}{\definelist[#1][\c!prefix=\v!no]}}% definestructurelist ?
+ {\getparameters[\??nh#1][\s!parent=\??nh#2,\c!label=#1]%
+ \definemarking[#1][#2]%
+ \definemarking[#1\v!number][#2\c!number]%
+ \doifundefined{\??li#1}{\definelist[#1][#2][\c!prefix=\v!no]}}% definestructurelist ?
+ \the\everystructureheadsetup}
+
+\appendtoks
+ \setstructurelevel\currentstructurehead{\structuresectionheadsection{\structuresectionheadcoupling\currentstructurehead}}%
+ \doifelse{\structureheadparameter\c!ownnumber}\v!yes
+ {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadown[\currentstructurehead]}}
+ {\setevalue\currentstructurehead{\noexpand\dohandlestructureheadnop[\currentstructurehead]}}%
+ \setevalue{\e!start\currentstructurehead}{\noexpand\dostartstructurehead[\currentstructurehead]}%
+ \setevalue{\e!stop\currentstructurehead }{\noexpand\dostopstructurehead[\currentstructurehead]}%
+\to \everystructureheadsetup
+
+% todo, check if section is defined
+
+\def\structuresectionheadcoupling#1%
+ {\ifcsname\??nh#1\c!coupling\endcsname
+ \expandafter\structuresectionheadcoupling\csname\??nh#1\c!coupling\endcsname\else#1%
+ \fi}
+
+\def\structuresectionheadsection#1%
+ {\ifcsname\??nh#1\c!section\endcsname
+ \expandafter\structuresectionheadcoupling\csname\??nh#1\c!section\endcsname\else#1%
+ \fi}
+
+% head construction
+
+\def\dohandlestructureheadown{\dodoubleempty\dodohandlestructureheadown} % [ref] {nr} {title}
+\def\dohandlestructureheadnop{\dodoubleempty\dodohandlestructureheadnop} % [ref] {title}
+\def\dostartstructurehead {\dotripleempty\dodostartstructurehead} % [settings] [userdata]
+
+\newconditional\currentstructureown
+
+\def\dodohandlestructureheadown[#1][#2]#3#4%
+ {\settrue\currentstructureown
+ \dohandlestructurehead{#1}{\c!reference=#2,\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title --
+
+\def\dodohandlestructureheadnop[#1][#2]#3%
+ {\setfalse\currentstructureown
+ \dohandlestructurehead{#1}{\c!reference=#2,\c!title={#3}}{}} % name ref nr title --
+
+\newtoks\everybeforestructurehead % hook, todo: before/after keys
+\newtoks\everyafterstructurehead % hook, todo: before/after keys
+
+\def\dodostartstructurehead[#1][#2][#3]% for the moment no grouping, too annoying with page breaks
+ {\setfalse\currentstructureown
+ \globalpushmacro\currentstructurehead
+ \xdef\currentstructurehead{#1}%
+ \the\everybeforestructurehead
+ \dohandlestructurehead{#1}{#2}{#3}} % name -- -- -- userdata
+
+\def\dostopstructurehead[#1]%
+ {\globalpopmacro\currentstructurehead
+ \doifnot{#1}\currentstructurehead{\writestatus\m!systems{missing \letterbackslash\e!stop#1}}%
+ \xdef\currentstructurehead{#1}% recover
+ \the\everyafterstructurehead}
+
+% \newconditional\structurereversesectionnumbers % todo: key/val
+
+\newconditional\structureheadtolist
+\newconditional\structureheaddoincrement
+\newconditional\structureheaddoplace
+\newconditional\structureheadleaveempty
+\newconditional\structureheadshownumber
+\newconditional\structureheadisdisplay
+
+\let\structureheadprefix\empty \def\structureheadprefixplus{+}
+
+% When do we reset the referenceprefix? This needs to be checked. Does it work
+% at all?
+
+\def\setstructureheadreference#1% reference
+ {\edef\structureheadreference{#1}%
+ \edef\structureheadreferenceprefix{\structureheadparameter\c!prefix}%
+ \ifx\structureheadreferenceprefix\empty
+ \setupreferenceprefix[]% yes or no?
+ \else\ifx\structureheadreferenceprefix\structureheadreferenceprefixplus
+ \ifx\structureheadreference\empty
+ \setupreferenceprefix[\structureheadreferenceprefixplus]
+ \else
+ \setupreferenceprefix[#1]% we assume just one reference
+ \fi
+ \else
+ \setupreferenceprefix[\structureheadreferenceprefix]%
+ \fi\fi}
+
+\setvalue{\??nh:\c!incrementnumber:\v!yes }{\settrue \structureheaddoincrement\settrue \structureheadtolist}
+\setvalue{\??nh:\c!incrementnumber:\v!no }{\setfalse\structureheaddoincrement\setfalse\structureheadtolist}
+\setvalue{\??nh:\c!incrementnumber:\v!list }{\setfalse\structureheaddoincrement\settrue \structureheadtolist}
+\setvalue{\??nh:\c!incrementnumber:\s!empty}{\settrue \structureheaddoincrement\settrue \structureheadtolist}
+
+\def\setstructureheadincrement
+ {\edef\currentstructureheadincrement{\structureheadparameter\c!incrementnumber}%
+ \ifcsname\??nh:\c!incrementnumber:\currentstructureheadincrement\endcsname
+ \csname\??nh:\c!incrementnumber:\currentstructureheadincrement\endcsname
+ \else
+ \settrue \structureheaddoincrement\settrue \structureheadtolist
+ % \filterstructureheadnumber
+ \fi}
+
+\def\filterstructureheadnumber
+ {\settrue\structureheaddoincrement
+ \settrue\structureheadtolist
+ \ifx\currentproduct\empty
+ % todo : filter from other toc (number, file, title)
+ % use : \currentstructureheadincrement as spec
+ \fi}
+
+\def\setstructureheadplacement
+ {\settrue\structureheaddoplace
+ \setfalse\structureheadleaveempty
+ \processaction
+ [\structureheadparameter\c!placehead]
+ [ \v!yes=>,
+ \v!empty=>\settrue\structureheadleaveempty,
+ \v!no=>\settrue\structureheadleaveempty\setfalse\structureheaddoplace]}
+
+\def\setstructureheadreset % todo, also set resetset here
+ {\doifelse{\structureheadparameter\c!resetnumber}\v!no
+ {\setfalse\@@resetsubheadnumbers}%
+ {\settrue \@@resetsubheadnumbers}}
+
+\def\setstructureheaddisplay
+ {\doifelsevalue{\??nh:\structureheadparameter\c!alternative}\v!horizontal
+ {\setfalse\structureheadisdisplay}
+ {\settrue \structureheadisdisplay}}
+
+\def\dosettructureheadnumbercontent
+ {\setsystemmode \v!sectionnumber
+ \settrue\structureheadshownumber}
+
+\def\doresettructureheadnumbercontent
+ {\resetsystemmode\v!sectionnumber
+ \setfalse\structureheadshownumber}
+
+\def\setstructureheadnumber
+ {\ifsectionnumber
+ \doifelse{\structureblockparameter\c!number}\v!yes % todo
+ {\doifelse{\structureheadparameter\c!number}\v!yes
+ {\settrue\structureheadshownumber}
+ {\setfalse\structureheadshownumber}}
+ {\setfalse\structureheadshownumber}%
+ \else
+ \setfalse\structureheadshownumber
+ \fi}
+
+% \defconvertexpanded\asciititle{\getvalue{\??ko#1\c!expansion}}{#4}%
+
+% \unexpanded\def\\{\space}
+
+\def\thestructureheadsynchonization
+ {\pagetype[\currentstructureheadcoupling]% hm also number
+ \normalexpanded{\noexpand\setmarking[\currentstructureheadcoupling]{\currentstructurelistnumber}}%
+ \currentstructuresynchronize}
+
+\def\thestructureheadnumber{\labeltexts{\structureheadparameter\c!label}{\structurenumber}}
+\def\thestructureheadtitle {\structurecctvalue{titledata.title}}
+
+\let\currentstructurehead \empty
+\let\currentstructureheadcoupling\empty
+\let\currentstructureheadsection \empty
+\let\currentstructureheadlevel \!!zerocount
+\let\currentstructureheadcounter \!!zerocount
+
+\def\doregisterstructurehead#1#2#3% name data userdata
+ {\structurecomponent
+ [\c!label={\structureheadparameter\c!label},
+ \c!incrementnumber=\ifconditional\structureheaddoincrement\v!yes\else\v!no\fi, % not that needed
+ \c!saveinlist=\ifconditional\structureheadtolist\v!yes\else\v!no\fi,
+ \c!level=\currentstructureheadlevel,
+ \c!name=#1,
+ \c!number=\ifconditional\structureheadshownumber\v!yes\else\v!no\fi,
+ \c!bookmark=,
+ \c!expansion=\structureheadparameter\c!expansion,
+ \c!reset=\structureheadparameter\c!reset,
+ \c!sectionseparatorset=\structureheadparameter\c!sectionseparatorset,
+ \c!sectionconversionset=\structureheadparameter\c!sectionconversionset,
+ \c!sectionconversion=\structureheadparameter\c!conversion, % just for compatibility
+ \c!sectionstopper=\structureheadparameter\c!sectionstopper,
+ \c!sectionset=\structureheadparameter\c!sectionset,
+ \c!sectionsegments=\structureheadparameter\c!sectionsegments,
+ \c!reference=\structureheadreference,
+ \c!referenceprefix=\structureheadreferenceprefix,
+ \c!command=,
+ #2]%
+ [#3]%
+ \reportcurrentstructure}
+
+\unexpanded\def\placeheadtext {\doquintupleempty\doplaceheadtextornumber[\c!textstyle] [\c!textcolor] [\empty]}
+\unexpanded\def\placeheadnumber{\doquintupleempty\doplaceheadtextornumber[\c!numberstyle][\c!numbercolor][\v!number]}
+
+\def\doplaceheadtextornumber[#1][#2][#3][#4][#5]%
+ {\dontleavehmode
+ \begingroup
+ \xdef\currentstructurehead {\iffifthargument#5\else#4\fi}%
+ \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}%
+ \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}%
+ \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}%
+ \dosetstructureheadattributes\c!style\c!color
+ \dosetstructureheadattributes#1#2%
+ \dontconvertfont
+ \setupinterlinespace
+ % temp hack most be fixed (see s-pre-61)
+ % \begstrut\getmarking[#4#3]\endstrut
+ \doifelse{#3}\v!number\currentheadnumber\currentheadtext
+ \endgraf
+ \endgroup}
+
+\def\dohandlestructurehead#1#2#3% name data userdata
+ {\xdef\currentstructurehead {#1}%
+ \xdef\currentstructureheadcoupling{\structuresectionheadcoupling\currentstructurehead}%
+ \xdef\currentstructureheadsection {\structuresectionheadsection \currentstructureheadcoupling}%
+ \xdef\currentstructureheadlevel {\structuresectionlevel \currentstructureheadsection}%
+ %writestatus\m!systems{setup: \currentstructurehead,\currentstructureheadcoupling,\currentstructureheadsection,\currentstructureheadlevel}%
+ %
+ \setstructureheadreference{#3}% will change
+ \setstructureheadincrement
+ \setstructureheadplacement
+ \setstructureheadreset
+ \setstructureheaddisplay
+ \setstructureheadnumber
+ %
+ \unexpanded\def\\{\space}%
+ \flushingcolumnfloatsfalse
+ %
+ % todo: also mark (for header)
+ %
+ % we might remove the lower level
+ %
+ % not here, after optional \page: \doregisterstructurehead{#1}{#2}{#3}%
+ %
+% \xdef\currentstructureheadcounter{\currentstructurecounter}% lua call
+ %
+ % \currentstructuresynchronize % will move
+ %
+ \edef\numberheaddistance {\structureheadparameter\c!distance }% compatibility
+ \edef\numberheadalternative{\structureheadparameter\c!alternative}% compatibility
+ %
+ \let\getstructureheadnumber\empty
+ \let\getstructureheadtitle \empty
+ \let\getstructureheadsyncs \empty
+ \ifconditional\structureheaddoincrement
+ \ifconditional\structureheaddoplace
+ \dostructureheadspacingbeforeyes
+ \doregisterstructurehead{#1}{#2}{#3}% after optional \page
+ \let\getstructureheadsyncs\thestructureheadsynchonization
+ \let\getstructureheadtitle\thestructureheadtitle
+ \ifconditional\structureheadshownumber
+ \let\getstructureheadnumber\thestructureheadnumber
+ \placestructureheadnumbertext
+ \else
+ \placestructureheadtext
+ \fi
+ \dostructureheadspacingafteryes
+ \else
+ \dostructureheadspacingbeforenop % toegevoegd ivm subpaginanr / tug sheets
+ \doregisterstructurehead{#1}{#2}{#3}% after optional \page
+ \let\getstructureheadsyncs\thestructureheadsynchonization
+ \placestructureheadnothing % just flush 'm
+ \dostructureheadspacingafternop
+ \fi
+ \else
+ \ifconditional\structureheaddoplace
+ \dostructureheadspacingbeforeyes
+ \doregisterstructurehead{#1}{#2}{#3}% after optional \page
+ \let\getstructureheadtitle\thestructureheadtitle
+ \let\getstructureheadsyncs\thestructureheadsynchonization
+ \placestructureheadtext
+ \dostructureheadspacingafteryes
+ \else
+ % do nothing / should be vbox to 0pt
+ \dostructureheadspacingbeforenop
+ \doregisterstructurehead{#1}{#2}{#3}% after optional \page
+ \let\getstructureheadsyncs\thestructureheadsynchonization
+ \placestructureheadnothing % just flush 'm
+ \dostructureheadspacingafternop
+ \fi
+ \fi
+ \flushingcolumnfloatstrue
+ \setfalse\ignorehandlepagebreak
+ % ignorespaces prevents spaces creeping in when after=\dontleavehmode
+ \ifconditional\structureheadisdisplay % \ifdisplaysectionhead
+ \ignorespaces
+ \else
+ \expandafter\GotoPar
+ \fi}
+
+% typesetting
+
+\def\placestructureheadnumbertext
+ {\getstructureheadnumber/\getstructureheadtitle
+ \getstructureheadsyncs}
+
+\def\placestructureheadtext
+ {\getstructureheadtitle
+ \getstructureheadsyncs}
+
+\def\placestructureheadnothing
+ {\getstructureheadsyncs}
+
+% pagebreaks
+
+\newcount\precedingstructurelevel \precedingstructurelevel\plusone
+\newconditional\ignorehandlepagebreak
+
+\def\dostructureheadspacingbeforeyes
+ {\docheckstructureheadbefore\dohandlestructureheadpagebreak
+ \structureheadparameter\c!inbetween}
+
+\def\dostructureheadspacingbeforenop
+ {\docheckstructureheadbefore\docheckstructureheadlayout
+ \structureheadparameter\c!inbetween}
+
+\def\dostructureheadspacingafteryes
+ {\ifconditional\structureheadisdisplay
+ \dosomebreak\nobreak
+ \ifconditional\structureheadleaveempty % inlined \emptyheadcorrection (with after=\blank)
+ \vskip-\lineheight
+ \dosomebreak\nobreak
+ \kern\zeropoint
+ \prevdepth\strutdepth
+ \fi
+ \structureheadparameter\c!after
+ \fi}
+
+\def\dostructureheadspacingafternop
+ {}
+
+\newsignal\continuousstructureheadsignal
+
+\def\docheckstructureheadbefore#1%
+ {\ifhmode
+ \scratchcounter\lastpenalty\unpenalty % no beauty in this
+ \ifdim\lastskip=\continuousstructureheadsignal
+ % no page break
+ \ifconditional\ignorehandlepagebreak
+ \setfalse\ignorehandlepagebreak
+ \else
+ \global\precedingstructurelevel\currentstructureheadlevel
+ \nobreak
+ \fi
+ \global\settrue\continuoussectionhead
+ \else
+ \penalty\scratchcounter
+ \global\setfalse\continuoussectionhead
+ #1%
+ \fi
+ \else
+ \global\setfalse\continuoussectionhead
+ #1%
+ \fi}
+
+\def\dodocheckstructureheadlayout#1#2%
+ {\doifelselayouttextline{#1}
+ {\doifsomething{\structureheadparameter#2}{\expanded{\setuplayouttext[#1][\c!state=\structureheadparameter#2]}}}
+ \donothing}
+
+\def\docheckstructureheadlayout
+ {\doifsomething{\structureheadparameter\c!page}
+ {\page[\structureheadparameter\c!page]%
+ \dodocheckstructureheadlayout\v!header\c!header
+ \dodocheckstructureheadlayout\v!text \c!text
+ \dodocheckstructureheadlayout\v!footer\c!footer}}
+
+\def\currentstructurecounter {\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead)}}
+\def\previousstructurecounter{\ctxlua{structure.sections.depthnumber(\thenamedstructureheadlevel\currentstructurehead-1)}}
+
+\def\dohandlestructureheadpagebreak
+ {%[[\currentstructurehead @\thenamedstructureheadlevel\currentstructurehead/prev:\previousstructurecounter/curr:\currentstructurecounter]]
+ \ifconditional\ignorehandlepagebreak
+ \setfalse\ignorehandlepagebreak
+ \else
+ \ifnum\lastpenalty>\zerocount
+ \global\pagebreakdisabledtrue
+ \fi
+ % beware, these numbers are not yet know here
+ \doifelse{\structureheadparameter\c!continue}\v!yes
+ {\ifnum\previousstructurecounter=\zerocount
+ \docheckstructureheadlayout
+ \else\ifnum\currentstructurecounter>\zerocount
+ \docheckstructureheadlayout
+ \fi\fi}%
+ {\docheckstructureheadlayout}%
+ \doifnot{\structureheadparameter\c!aligntitle}\v!float\flushsidefloats
+ \structureheadparameter\c!before
+ \relax
+ \ifpagebreakdisabled
+ \global\pagebreakdisabledfalse
+ \else
+ \dopreventbreakafterstructureheadauto
+ \fi
+ \doif{\structureheadparameter\c!aligntitle}\v!float\indent
+ \global\precedingstructurelevel\currentstructureheadlevel
+ \fi}
+
+% the next one was: \somebreakmethod
+
+\chardef\somestructureheadbreakmethod\plusone % 0=nothing, 1=weighted, 2=strict, 3=vspacing
+
+\def\dopreventbreakafterstructureheadauto % used after \c!before
+ {\ifcase\somestructureheadbreakmethod
+ % 0 = nothing
+ \or
+ % 1 = old weighted version
+ \ifnum\currentstructureheadlevel>\precedingstructurelevel
+ \dosomebreak{\penalty\numexpr20000+500*\currentstructureheadlevel\relax}%
+ \else
+ \dosomebreak\allowbreak % brr
+ \fi
+ \or
+ % 2 = strict version
+ \dosomebreak{\penalty\maxdimen}%
+ \or
+ % 3 = vspacing
+ \vspacing[\v!samepage]% if preceded by ! then a loop
+ \else
+ % nothing
+ \fi}
+
+\def\dopreventbreakafterstructureheadspec#1% see enumerations etc
+ {\ifcase\somestructureheadbreakmethod
+ % 0 = nothing
+ \or
+ % 1 = old weighted version
+ \dosomebreak{\penalty\numexpr20000+500*(\currentstructureheadlevel+#1)\relax}%
+ \or
+ % 2 = strict version
+ \dosomebreak{\penalty\maxdimen}%
+ \or
+ % 3 = vspacing
+ \vspacing[\v!samepage]%
+ \else
+ % nothing
+ \fi}
+
+\def\dohandlepagebreakX{\dopreventbreakafterstructureheadspec} % no \let so we can redefind
+
+% todo:
+
+\def\thecurrentstructureheadlevel#1%
+ {\getstructurelevel{#1}}
+
+\def\thenamedstructureheadlevel#1%
+ {\structuresectionlevel{\structuresectionheadsection{\structuresectionheadcoupling{#1}}}}
+
+\def\setupheadnumber
+ {\dodoubleargument\dosetupheadnumber}
+
+\def\dosetupheadnumber[#1][#2]% todo: reset if at other level
+ {\setstructurenumber{\thecurrentstructureheadlevel{#1}}{#2}}
+
+\def\currentstructureheadnumber{0} % ==> \currentheadnumber
+
+\def\determineheadnumber[#1]%
+ {\xdef\currentstructureheadnumber{\getstructurenumber{\thecurrentstructureheadlevel{#1}}}}
+
+\def\structureheadnumber
+ {\dosingleempty\dostructureheadnumber}
+
+\def\dostructureheadnumber[#1]% simple case is just a number
+ {\getfullstructurenumber{\iffirstargument\thecurrentstructureheadlevel{#1}\fi}}
+
+% compatibility code (after all, we might offer different structure handlers as well
+
+\let\definesectionblock \definestructureblock
+\let\definesection \definestructuresection
+\let\setupsection \setupstructuresection
+\let\setupheads \setupstructureheads
+\let\definehead \definestructurehead
+\let\setuphead \setupstructurehead
+\let\headnumber \structureheadnumber
+\let\setupsectionblock \setupstructureblock
+\let\currentheadnumber \thestructureheadnumber
+\let\currentheadtext \thestructureheadtitle
+\let\sectioncountervalue\structurevalue
+
+% list references, will be redone in lua when we need it
+
+\let\startlistreferences\relax
+\let\stoplistreferences \relax
+
+\protect \endinput
diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua
new file mode 100644
index 000000000..00ee2fdc2
--- /dev/null
+++ b/tex/context/base/strc-syn.lua
@@ -0,0 +1,185 @@
+if not modules then modules = { } end modules ['str-syn'] = {
+ version = 1.001,
+ comment = "companion to str-syn.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+local texwrite, texsprint, format = tex.write, tex.sprint, string.format
+
+local ctxcatcodes = tex.ctxcatcodes
+
+-- interface to tex end
+
+joblists = joblists or { }
+joblists.collected = joblists.collected or { }
+joblists.tobesaved = joblists.tobesaved or { }
+
+local collected, tobesaved = joblists.collected, joblists.tobesaved
+
+local function initializer()
+ collected, tobesaved = joblists.collected, joblists.tobesaved
+end
+
+local function finalizer()
+ tobesaved.hash = nil
+end
+
+job.register('joblists.collected', joblists.tobesaved, initializer, finalizer)
+
+local function allocate(class)
+ local d = tobesaved[class]
+ if not d then
+ d = {
+ metadata = {
+ language = 'en',
+ sorted = false,
+ class = class
+ },
+ entries = {
+ },
+ hash = {
+ }
+ }
+ tobesaved[class] = d
+ end
+ return d
+end
+
+function joblists.define(class,kind)
+ local data = allocate(class)
+ data.metadata.kind = kind
+end
+
+function joblists.register(class,kind,spec)
+ local data = allocate(class)
+ data.metadata.kind = kind -- runtime, not saved in format (yet)
+ data.entries[#data.entries+1] = spec
+ data.hash[spec.definition.tag or ""] = spec
+end
+
+function joblists.synonym(class,tag)
+ local data = allocate(class).hash
+ local d = data[tag]
+ if d then
+ local de = d.definition
+ de.used = true
+ texsprint(ctxcatcodes,de.synonym)
+ end
+end
+
+function joblists.meaning(class,tag)
+ local data = allocate(class).hash
+ local d = data[tag]
+ if d then
+ local de = d.definition
+ de.used = true
+ texsprint(ctxcatcodes,de.meaning)
+ end
+end
+
+function joblists.compare(a,b)
+ return sorters.comparers.basic(a.split,b.split)
+end
+
+function joblists.filter(data,options)
+ local result = { }
+ local entries = data.entries
+ local all = options and options.criterium == interfaces.variables.all
+ for i=1,#entries do
+ local entry = entries[i]
+ if all or entry.definition.used then
+ result[#result+1] = entry
+ end
+ end
+ data.result = result
+end
+
+function joblists.prepare(data)
+ local strip = sorters.strip
+ local splitter = sorters.splitters.utf
+ local result = data.result
+ if result then
+ for i=1, #result do
+ local r = result[i]
+ local rd = r.definition
+ if rd then
+ local rt = rd.tag
+ local sortkey = (rt and rt ~= "" and rt) or rd.synonym
+ r.split = splitter(strip(sortkey))
+ end
+ end
+ end
+end
+
+function joblists.sort(data,options)
+ sorters.sort(data.result,joblists.compare)
+end
+
+function joblists.finalize(data,options)
+ local result = data.result
+ data.metadata.nofsorted = #result
+ local split = { }
+ local se = sorters.entries[options.language or sorters.defaultlanguage] or sorters.entries[sorters.defaultlanguage]
+ for k=1,#result do
+ local v = result[k]
+ local entry, tag = v.split[1], ""
+ if se and se[entry] then
+ if type(se[entry]) == "number" then
+ entry = se[entry]
+ end
+ tag = se[entry]
+ else
+ entry = 0
+ tag = "unknown"
+ end
+ local s = split[entry]
+ if not s then
+ s = { tag = tag, data = { } }
+ split[entry] = s
+ end
+ s.data[#s.data+1] = v
+ end
+ data.result = split
+end
+
+function joblists.flush(data,options) -- maybe pass the settings differently
+ local kind = data.metadata.kind -- hack, will be done better
+ texsprint(ctxcatcodes,format("\\start%soutput",kind))
+ local result = data.result
+ for k, letter in ipairs(table.sortedkeys(result)) do
+ local sublist = result[letter]
+ local data = sublist.data
+ texsprint(ctxcatcodes,format("\\start%ssection{%s}",kind,sublist.tag))
+ for d=1,#data do
+ local entry = data[d].definition
+ texsprint(ctxcatcodes,format("\\%sentry{%s}{%s}{%s}",kind,d,entry.synonym,entry.meaning))
+ end
+ texsprint(ctxcatcodes,format("\\stop%ssection",kind))
+ end
+ texsprint(ctxcatcodes,format("\\stop%soutput",kind))
+ -- for now, maybe at some point we will do a multipass or so
+ data.result = nil
+ data.metadata.sorted = false
+end
+
+function joblists.analysed(class,options)
+ local data = joblists.collected[class]
+ if data and data.entries then
+ joblists.filter(data,options) -- filters entries to result
+ joblists.prepare(data,options) -- adds split table parallel to list table
+ joblists.sort(data,options) -- sorts entries in result
+ joblists.finalize(data,options) -- do things with data.entries
+ data.metadata.sorted = true
+ end
+ return data and data.metadata.sorted and data.result and next(data.result)
+end
+
+function joblists.process(class,options)
+ if joblists.analysed(class,options) then
+ joblists.flush(joblists.collected[class],options)
+ end
+end
+
diff --git a/tex/context/base/strc-syn.tex b/tex/context/base/strc-syn.tex
new file mode 100644
index 000000000..a739be902
--- /dev/null
+++ b/tex/context/base/strc-syn.tex
@@ -0,0 +1,392 @@
+%D \module
+%D [ file=strc-syn,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Synonyms and Sorting,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / Synonyms and Sorting}
+
+\registerctxluafile{strc-syn}{1.001}
+
+\unprotect
+
+% general help, can be shared
+
+% simplifiedcommands -> flag in lua
+%
+% expansion
+% criterium -> when start, then flag in list
+% command-> wanneer?
+% state -> flagging enabled
+% conversion ?
+% todo: register xml mode etc
+
+% split but common in lua
+
+\def\preprocessexpansion#1#2#3#4%
+ {\ifx#1\s!xml
+ \xmlstartraw
+ \xdef#2{#4}%
+ \xmlstopraw
+ \globallet#3\s!xml
+ \else
+ \ifx#1\v!yes
+ \xdef#2{#4}%
+ \else
+ \xdef#2{\detokenize{#4}}%
+ \fi
+ \globallet#3\s!tex
+ \fi}
+
+\let\currentsynonym\empty
+
+\def\synonymparameter #1{\csname\dosynonymparameter{\??sm\currentsynonym}#1\endcsname}
+\def\synonymparameterhash#1{\dosynonymparameterhash {\??sm\currentsynonym}#1}
+
+\def\dosynonymparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dosynonymparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\dosynonymparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dosynonymparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dosynonymparentparameter #1#2{\ifx#1\relax\s!empty\else\dosynonymparameter #1#2\fi}
+\def\dosynonymparentparameterhash#1#2{\ifx#1\relax \else\dosynonymparameterhash#1#2\fi}
+
+\def\dosetsynonymattributes#1#2% style color
+ {\edef\fontattributehash {\synonymparameterhash#1}%
+ \edef\colorattributehash{\synonymparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+\newtoks\everysetupsynonyms
+
+\def\setupsynonyms
+ {\dodoubleargument\dosetupsynonyms}
+
+\def\dosetupsynonyms[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??sm#1][#2]%
+ \else
+ \getparameters[\??sm][#1]%
+ \fi
+ \the\everysetupsynonyms}
+
+\setupsynonyms
+ [\c!state=\v!start,
+ %\c!synonymstyle=,
+ %\c!textstyle=,
+ %\c!headstyle=,
+ %\c!headcolor=,
+ %\c!criterium=,
+ \c!location=\v!left,
+ \c!width=5em,
+ \c!distance=0pt,
+ %\c!sample=,
+ %\c!hang=,
+ %\c!align=,
+ %\c!before=,
+ %\c!inbetween=,
+ %\c!after=,
+ \c!indentnext=\v!no,
+ %\c!expansion=,
+ \s!language=\currentmainlanguage]
+
+\def\definesynonyms
+ {\doquadrupleempty\dodefinesynonyms}
+
+\def\dodefinesynonyms[#1][#2][#3][#4]% name plural \meaning \use
+ {\iffourthargument
+ \unexpanded\def#4##1{\doinsertsynonym{#1}{##1}}% name tag
+ \ifthirdargument
+ \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning
+ \fi
+ \setvalue{#1}{\definesynonym[\v!no][#1]}% \name
+ \else
+ \ifthirdargument
+ \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning
+ \fi
+ \setvalue{#1}{\definesynonym[\v!yes][#1]}% \name
+ \fi
+ \getparameters[\??sm#1][\s!parent=\??sm]%
+ \presetheadtext[#2=\Word{#2}]% changes the \if...argument
+ %\ctxlua{joblists.define('#1')}%
+ \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??sm#1]}% to be obsolete
+ \setvalue{\e!place \e!listof#2}{\doplacelistofsynonyms{#1}{#2}}%
+ \setvalue{\e!complete\e!listof#2}{\docompletelistofsynonyms{#1}{#2}}}
+
+\def\definesynonym
+ {\dotripleempty\dodefinesynonym}
+
+\def\dodefinesynonym[#1][#2][#3]#4#5%
+ {\begingroup
+ \edef\currentsynonym{#2}%
+ \edef\currentsynonymtag{#3}%
+ \ifx\currentsynonymtag\empty
+ \edef\currentsynonymtag{#4}%
+ \fi
+ \ifx\currentsynonymtag\empty
+ % todo: error message
+ \else
+ \edef\currentsynonymexpansion{\synonymparameter\c!expansion}%
+ \preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}%
+ \preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}%
+ \ctxlua{joblists.register("\currentsynonym", "synonym", {
+ metadata = {
+ catcodes = \the\catcodetable,
+ coding = "\currentsynonymcoding",
+ xmlroot = \ifx\currentsynonymcoding\s!xml "\xmldocument" \else nil \fi,
+ },
+ definition = {
+ tag = "\currentsynonymtag",
+ synonym = \!!bs\currentsynonymtext\!!es,
+ meaning = \!!bs\currentsynonymmeaning\!!es,
+ used = false,
+ }
+ })}%
+ \doif{#1}\v!yes{\unexpanded\setxvalue\currentsynonymtag{\noexpand\doinsertsynonym{\currentsynonym}{\currentsynonymtag}}}%
+ \fi
+ \endgroup}
+
+\def\doinsertsynonym#1#2% name tag
+ {\begingroup
+ % no kap currently, of .. we need to map cap onto WORD
+ \dosetsynonymattributes\c!synonymstyle\c!synonymcolor
+ \ctxlua{joblists.synonym("#1","#2")}%
+ \endgroup}
+
+\def\doinsertsynonymmeaning#1#2% name tag
+ {\begingroup
+ % no kap currently, of .. we need to map cap onto WORD
+ \dosetsynonymattributes\c!textstyle\c!textcolor
+ \ctxlua{joblists.meaning("#1","#2")}%
+ \endgroup}
+
+\def\doplacelistofsynonyms#1#2%
+ {\begingroup
+ \def\currentsynonym{#1}%
+\definedescription % todo, per class
+ [syndef]
+ [\c!location=\synonymparameter\c!location,
+ \c!width=\synonymparameter\c!width,
+ \c!distance=\synonymparameter\c!distance,
+ \c!sample=\synonymparameter\c!sample,
+ \c!hang=\synonymparameter\c!hang,
+ \c!align=\synonymparameter\c!align,
+ \c!before=\synonymparameter\c!before,
+ \c!inbetween=\synonymparameter\c!inbetween,
+ \c!after=\synonymparameter\c!after,
+ \c!indentnext=\synonymparameter\c!indentnext,
+ \c!headstyle=\synonymparameter\c!headstyle,
+ \c!headcolor=\synonymparameter\c!headcolor,
+ \c!style=,
+ \c!color=]%
+ \startpacked
+ \ctxlua{joblists.process('#1',{ criterium = "\synonymparameter\c!criterium" })}%
+ \stoppacked
+ \endgroup}
+
+\def\docompletelistofsynonyms#1#2% expansion needed to avoid v! (due to french active !)
+ {\normalexpanded{\noexpand\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}%
+ \doplacelistofsynonyms{#1}{#2}%
+ \page[\v!yes]}
+
+\let\startsynonymoutput \relax
+\let\stopsynonymoutput \relax
+\let\startsynonymsection\gobbleoneargument
+\let\stopsynonymsection \relax
+
+\def\synonymentry#1#2#3%
+ {\syndef{\dosetsynonymattributes\c!textstyle\c!textcolor#2}#3\par}
+
+\let\currentsorting\empty
+
+% we can share if we also have synonymprefix = so
+
+\def\sortingparameter #1{\csname\dosortingparameter{\??so\currentsorting}#1\endcsname}
+\def\sortingparameterhash#1{\dosortingparameterhash {\??so\currentsorting}#1}
+
+\def\dosortingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dosortingparentparameter \csname#1\s!parent\endcsname#2\fi}
+\def\dosortingparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dosortingparentparameterhash\csname#1\s!parent\endcsname#2\fi}
+
+\def\dosortingparentparameter #1#2{\ifx#1\relax\s!empty\else\dosortingparameter #1#2\fi}
+\def\dosortingparentparameterhash#1#2{\ifx#1\relax \else\dosortingparameterhash#1#2\fi}
+
+\def\dosetsortingattributes#1#2% style color
+ {\edef\fontattributehash {\sortingparameterhash#1}%
+ \edef\colorattributehash{\sortingparameterhash#2}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi}
+
+\newtoks\everysetupsorting
+
+\def\setupsorting
+ {\dodoubleargument\dosetupsorting}
+
+\def\dosetupsorting[#1][#2]%
+ {\ifsecondargument
+ \getparameters[\??so#1][#2]%
+ \else
+ \getparameters[\??so][#1]%
+ \fi
+ \the\everysetupsorting}
+
+\setupsorting
+ [\c!state=\v!start,
+ %\c!command=, % we test for defined !
+ %\c!criterium=,
+ %\c!style=,
+ %\c!before=,
+ \c!after=\endgraf,
+ %\c!expansion=,
+ \s!language=\currentmainlanguage]
+
+\def\definesorting
+ {\dotripleempty\dodefinesorting}
+
+% if #3=\relax or \v!none, then no command but still protected
+
+\def\dodefinesorting[#1][#2][#3]%
+ {\ifthirdargument
+ \doifnot{#3}\v!none
+ {\ifx#3\relax \else
+ \def#3##1{\doinsertsort{#1}{##1}}%
+ \fi}%
+ \setvalue{#1}{\definesort[\v!no][#1]}%
+ \else
+ \setvalue{#1}{\definesort[\v!yes][#1]}%
+ \fi
+ \getparameters[\??so#1][\s!parent=\??so]%
+ \presetheadtext[#2=\Word{#2}]% after \ifthirdargument -)
+ %\ctxlua{joblists.define('#1')}%
+ \setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??so#1]}% to be obsolete
+ \setvalue{\e!place \e!listof#2}{\doplacelistofsortings{#1}{#2}}%
+ \setvalue{\e!complete\e!listof#2}{\docompletelistofsortings{#1}{#2}}}
+
+
+\def\definesort
+ {\dotripleempty\dodefinesort}
+
+\def\dodefinesort[#1][#2][#3]#4%
+ {\begingroup
+ \edef\currentsorting{#2}%
+ \edef\currentsortingtag{#3}%
+ \ifx\currentsortingtag\empty
+ \edef\currentsortingtag{#4}%
+ \fi
+ \ifx\currentsortingtag\empty
+ % todo: error message
+ \else
+ \edef\currentsortingexpansion{\sortingparameter\c!expansion}%
+ \preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}%
+ \ctxlua{joblists.register("\currentsorting", "sorting", {
+ metadata = {
+ catcodes = \the\catcodetable,
+ coding = "\currentsortingcoding",
+ xmlroot = \ifx\currentsortingcoding\s!xml "\xmldocument" \else nil \fi,
+ },
+ definition = {
+ tag = "\currentsortingtag",
+ synonym = \!!bs\currentsortingtext\!!es,
+ % used = false,
+ }
+ })}%
+ \doif{#1}\v!yes{\unexpanded\setxvalue\currentsortingtag{\noexpand\doinsertsort{\currentsorting}{\currentsortingtag}}}%
+ \fi
+ \endgroup}
+
+\def\doinsertsort#1#2% name tag
+ {\begingroup
+ % no kap currently, of .. we need to map cap onto WORD
+ \dosetsynonymattributes\c!style\c!color
+ \ctxlua{joblists.synonym("#1","#2")}%
+ \endgroup}
+
+% before after
+%
+% maybe just 'commandset' and then combine
+
+\def\doplacelistofsorts#1% NOG EEN RUWE VERSIE MAKEN ZONDER WITRUIMTE ETC ETC
+ {\begingroup
+ \def\currentsorting{#1}%
+ \startpacked
+ \ctxlua{joblists.process('#1',{})}%
+ \stoppacked
+ \endgroup}
+
+\def\docompletelistofsorts#1#2%
+ {\normalexpanded{\noexpand\systemsuppliedchapter[#1]{\noexpand\headtext{#2}}}%
+ \doplacelistofsorts{#1}%
+ \page[\v!yes]}
+
+\let\startsortingoutput \relax
+\let\stopsortingoutput \relax
+\let\startsortingsection\gobbleoneargument
+\let\stopsortingsection \relax
+
+\def\sortingentry#1#2#3%
+ {\begingroup\dosetsortingattributes\c!style\c!color#2\endgroup\par} % todo
+
+%D Here we define a support macro that can sort simple comma
+%D separated lists. It's a multi-list variant of a prototype
+%D written by Taco.
+
+% \def\mkloadsortedlist#1% class
+% {\bgroup
+% \getvalue{\s!set#1}%
+% \ctxlua{joblists.process('#1')}%
+% \getvalue{\s!reset#1}%
+% \egroup}
+
+% \def\processlistofsorts[#1]%
+% {\mkloadsortedlist{#1}}
+
+% \newcounter\nofsortedalphalists
+
+% \def\sortalphacommacommand#1%
+% {\begingroup
+% \doglobal\increment\nofsortedalphalists
+% \edef\currentsortedalphalist{alpha:\nofsortedalphalists}%
+% \definesorting[\currentsortedalphalist][\currentsortedalphalist]%
+% \processcommacommand[#1]{\getvalue\currentsortedalphalist}%
+% \global\let\sortedcommalist\empty
+% \def\makesortedlist##1{\doglobal\appendtocommalist{##1}\sortedcommalist}%
+% \setupsorting[\currentsortedalphalist][\c!criterium=\v!all,\c!command=\makesortedlist]%
+% \processlistofsorts[\currentsortedalphalist]%
+% \endgroup
+% \dodoglobal\let#1\sortedcommalist}
+
+% \starttext
+% \def\whatever{a,b,q,d,r,f} \sortalphacommacommand\whatever \whatever \endgraf
+% \def\whatever{ax,bx,qx,dx,rx,fx} \sortalphacommacommand\whatever \whatever \endgraf
+% \stoptext
+
+%D Presets.
+
+\definesynonyms
+ [\v!abbreviation]
+ [\v!abbreviations]
+ [\infull]
+
+\setupsynonyms
+ [\v!abbreviation]
+ [\c!textstyle=\v!capital]
+
+\definesorting
+ [\v!logo]
+ [\v!logos]
+ % no [\logogram]
+
+\definesynonyms
+ [\v!unit]
+ [\v!units]
+ [\unitmeaning]
+
+\setupsynonyms
+ [\v!unit]
+ [\c!textstyle=\dimension]
+
+\protect \endinput
diff --git a/tex/context/base/strc-xml.tex b/tex/context/base/strc-xml.tex
new file mode 100644
index 000000000..04c5e71b8
--- /dev/null
+++ b/tex/context/base/strc-xml.tex
@@ -0,0 +1,87 @@
+%D \module
+%D [ file=strc-xml,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=XML Processing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE / 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.
+
+\writestatus{loading}{ConTeXt Structure Macros / XML Processing}
+
+\unprotect
+
+\startxmlsetups xml:ctx:tocentry
+ \xmlsetsetup{\xmldocument}{ctx:tocentry}{xml:ctx:tocentry}
+\stopxmlsetups
+
+\xmlregistersetup{xml:ctx:tocentry}
+
+\startxmlsetups xml:ctx:tocentry
+ \xmlflush{#1}
+\stopxmlsetups
+
+\protect \endinput
+
+% test.xml
+
+<?xml version='1.0' standalone='yes?>
+
+<document>
+ <section>
+ <title>Some <b>bold</b> title <b>bold <i>bold</i> oeps</b> and more</title>
+ <content>
+ <p>a paragraph of text</p>
+ <p>another paragraph of text</p>
+ </content>
+ </section>
+ <section>
+ <title>Another <b>bold</b> title <b>bold <i>bold</i> oeps</b> and more</title>
+ <content>
+ <p>a paragraph of text</p>
+ <p>another paragraph of text</p>
+ </content>
+ </section>
+</document>
+
+% test.tex
+
+\setupstructurehead[chapter][expansion=xml]
+
+\startxmlsetups xml:demo:define:base
+ \xmlsetsetup{demo}{document|section|p|b|i}{xml:demo:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{demo}{xml:demo:define:base}
+
+\startxmlsetups xml:demo:document
+ \title{Contents}
+ \placelist[chapter]
+ \page
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:demo:section
+ \chapter{\xmltext{#1}{/title}}
+ \xmlfirst{#1}{/content}
+\stopxmlsetups
+
+\startxmlsetups xml:demo:p
+ \xmlflush{#1}\endgraf
+\stopxmlsetups
+
+\startxmlsetups xml:demo:b
+ \bgroup\bf\xmlflush{#1}\egroup
+\stopxmlsetups
+
+\startxmlsetups xml:demo:i
+ \bgroup\it\xmlflush{#1}\egroup
+\stopxmlsetups
+
+\starttext
+ \xmlprocessfile{demo}{oeps.xml}{}
+\stoptext
diff --git a/tex/context/base/supp-box.tex b/tex/context/base/supp-box.tex
index 02a28cb4e..dc6833e6a 100644
--- a/tex/context/base/supp-box.tex
+++ b/tex/context/base/supp-box.tex
@@ -15,27 +15,12 @@
%D are quite simple, some are more advanced and when understood
%D well, all can be of use.
-\writestatus{loading}{Context Support Macros / Boxes}
+%D No longer generic, why bother.
-\unprotect
-
-% watch this: \setbox4\emptybox \wd4\onepoint \the\wd4, no dimensions for void
+\writestatus{loading}{ConTeXt Support Macros / Boxes}
-%D First a couple of hacks to make this module loadable
-%D in plain \TEX.
-
-\ifx\myalloc@\undefined % seems like we're not in context
- \def\newbox{\alloc@4\box\chardef\insc@unt}
-\fi
-
-\ifx \scratchbox\undefined \newbox \scratchbox \fi
-\ifx\globalscratchbox\undefined \newbox\globalscratchbox \fi
+\unprotect
-\ifx\normalhbox \undefined \let\normalhbox \hbox \fi
-\ifx\normalvbox \undefined \let\normalvbox \vbox \fi
-\ifx\normalvtop \undefined \let\normalvtop \vtop \fi
-\ifx\normalvcenter\undefined \let\normalvcenter\vcenter \fi
-
%D \macros
%D {strutdp,strutht,strutwd}
%D
@@ -55,8 +40,12 @@
%D Let's start with an easy one. The next macro hides the
%D ugly \type {@} in \type {\voidb@x}.
-\def\emptybox {\box\voidb@x}
-\def\resetbox#1{\setbox#1\box\voidb@x}
+\ifx\voidbox\undefined \newbox\voidbox \fi
+\ifx\voidb@x\undefined \let\voidb@x\voidbox \fi
+
+\def\emptybox {\box \voidbox}
+\def\unvoidbox {\unhbox\voidbox}
+\def\resetbox#1{\setbox#1\box\voidbox}
%D \macros
%D {nextdepth}
@@ -211,7 +200,7 @@
\next}
\def\mathsm@sh#1#2% redefined plain macro
- {\finsm@sh{$\m@th#1{#2}$}}
+ {\finsm@sh{$\mathsurround\zeropoint#1{#2}$}}
\def\makesm@sh#1% redefined plain macro (handles t b h d w)
{\if#1w\nextboxwd\zeropoint\else
@@ -239,8 +228,8 @@
%D not grab an argument in the non||math case, which is better.
\unexpanded\def\phantom {\ph@nt\nextbox\nextbox\nextbox}
-\unexpanded\def\vphantom{\ph@nt\nextbox\nextbox\voidb@x}
-\unexpanded\def\hphantom{\ph@nt\voidb@x\voidb@x\nextbox}
+\unexpanded\def\vphantom{\ph@nt\nextbox\nextbox\voidbox}
+\unexpanded\def\hphantom{\ph@nt\voidbox\voidbox\nextbox}
%D Due to a complicated call to \type {\mathpallete} and
%D thereby \type {\mathchoice}, the next macro looks ugly.
@@ -249,7 +238,7 @@
\def\ph@nt#1#2#3%
{\def\doph@nt
{\ifmmode
- \def\mathph@nt####1####2{\makeph@nt#1#2#3{$\m@th####1{####2}$}}%
+ \def\mathph@nt####1####2{\makeph@nt#1#2#3{$\mathsurround\zeropoint####1{####2}$}}%
\def\nextph@nt{\mathpalette\mathph@nt}%
\else\ifx\nextph@nt\bgroup
\def\nextph@nt{\makeph@nt#1#2#3}%
@@ -260,7 +249,7 @@
\futurelet\nextph@nt\doph@nt}
\def\makeph@nt#1#2#3%
- {\begingroup % why no \bgroup
+ {\begingroup
\dowithnextbox
{\setbox\scratchbox\null
\ht\scratchbox\ht#1%
@@ -470,9 +459,11 @@
%D \doiftext {data} {then branch}
%D \stoptyping
+\newif\iftrialtypesetting
+
\def\doiftextelse#1%
{\bgroup
- \setbox\scratchbox\normalhbox{\ignorespaces#1\removeunwantedspaces}%
+ \setbox\scratchbox\normalhbox{\trialtypesettingtrue\ignorespaces#1\removeunwantedspaces}%
\ifzeropt\wd\scratchbox
\egroup\@EA\secondoftwoarguments
\else
@@ -637,9 +628,9 @@
\def\doclap{\begingroup\dowithnextbox{\normalhbox to \zeropoint
{\normalhss\flushnextbox\normalhss}\endgroup}\normalhbox}
-\def\domathclap{\mathpalette\dodomathclap} \def\dodomathclap#1#2{\doclap{$\m@th#1#2$}}
-\def\domathllap{\mathpalette\dodomathllap} \def\dodomathllap#1#2{\dollap{$\m@th#1#2$}}
-\def\domathrlap{\mathpalette\dodomathrlap} \def\dodomathrlap#1#2{\dorlap{$\m@th#1#2$}}
+\def\domathclap{\mathpalette\dodomathclap} \def\dodomathclap#1#2{\doclap{$\mathsurround\zeropoint#1#2$}}
+\def\domathllap{\mathpalette\dodomathllap} \def\dodomathllap#1#2{\dollap{$\mathsurround\zeropoint#1#2$}}
+\def\domathrlap{\mathpalette\dodomathrlap} \def\dodomathrlap#1#2{\dorlap{$\mathsurround\zeropoint#1#2$}}
\unexpanded\def\rlap{\mathortext\domathrlap\dorlap}
\unexpanded\def\llap{\mathortext\domathllap\dollap}
@@ -817,73 +808,65 @@
\ifx\originalshapebox\undefined \let\originalshapebox\oldshapebox \fi
-\beginTEX
-
-\def\insertshapesignal
- {\normalhbox to \shapesignal{\strut\hss}% plus \strut
- \prevdepth\strutdp} % never \nointerlineskip
-
-% \def\restoreshapebox
-% {\global\setbox\tmpshapebox\copy\originalshapebox} % \oldshapebox
-
-\def\restoreshapebox % compensates for the signal
- {\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}}
-
-\def\shapeboxstrut % put this in front if needed !
- {\vrule\!!width\zeropoint\!!height\ht\shapebox\!!depth\dp\shapebox}
-
-\def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
- {\ifzeropt\lastskip % \ifdim\lastskip=\zeropoint\relax
- \ifzeropt\lastkern % \ifdim\lastkern=\zeropoint\relax
- \ifcase\lastpenalty % \ifnum\lastpenalty=\zerocount
- \setbox\shapebox\lastbox
- \ifvoid\shapebox
- \unskip\unpenalty\unkern
- \else
- \ifdim\wd\shapebox=\shapesignal\relax
- \exitloop
- \else
- \shapecounter\zerocount
- \global\setbox\tmpshapebox\normalvbox{#1\unvbox\tmpshapebox}%
- \fi
- \fi
- \else
- \shapepenalty\lastpenalty
- \global\setbox\tmpshapebox\normalvbox{#2\unvbox\tmpshapebox}%
- \unpenalty
- \fi
- \else
- \shapekern\lastkern
- \global\setbox\tmpshapebox\normalvbox{#3\unvbox\tmpshapebox}%
- \unkern
- \fi
- \else
- \shapeskip\lastskip
- \global\setbox\tmpshapebox\normalvbox{#4\unvbox\tmpshapebox}%
- \unskip
- \fi
- \ifnum\shapecounter>100 % can be less
- \global\reshapingfailedtrue
- \message{!!forced exit from shapebox!!}%
- \restoreshapebox
- \exitloop
- \else
- \advance\shapecounter \plusone
- \fi}
-
-\endTEX
-
-% Now that the lastnode bugfixes are wide spread we can use:
-
-\beginETEX \lastnodetype
+% %D The old traditional tex variant:
+%
+% \def\insertshapesignal
+% {\normalhbox to \shapesignal{\strut\hss}% plus \strut
+% \prevdepth\strutdp} % never \nointerlineskip
+%
+% \def\restoreshapebox % compensates for the signal
+% {\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}}
+%
+% \def\shapeboxstrut % put this in front if needed !
+% {\vrule\!!width\zeropoint\!!height\ht\shapebox\!!depth\dp\shapebox}
+%
+% \def\dodoreshapebox#1#2#3#4% \shapebox, \shapepenalty, \shapekern, \shapeskip
+% {\ifzeropt\lastskip % \ifdim\lastskip=\zeropoint\relax
+% \ifzeropt\lastkern % \ifdim\lastkern=\zeropoint\relax
+% \ifcase\lastpenalty % \ifnum\lastpenalty=\zerocount
+% \setbox\shapebox\lastbox
+% \ifvoid\shapebox
+% \unskip\unpenalty\unkern
+% \else
+% \ifdim\wd\shapebox=\shapesignal\relax
+% \exitloop
+% \else
+% \shapecounter\zerocount
+% \global\setbox\tmpshapebox\normalvbox{#1\unvbox\tmpshapebox}%
+% \fi
+% \fi
+% \else
+% \shapepenalty\lastpenalty
+% \global\setbox\tmpshapebox\normalvbox{#2\unvbox\tmpshapebox}%
+% \unpenalty
+% \fi
+% \else
+% \shapekern\lastkern
+% \global\setbox\tmpshapebox\normalvbox{#3\unvbox\tmpshapebox}%
+% \unkern
+% \fi
+% \else
+% \shapeskip\lastskip
+% \global\setbox\tmpshapebox\normalvbox{#4\unvbox\tmpshapebox}%
+% \unskip
+% \fi
+% \ifnum\shapecounter>100 % can be less
+% \global\reshapingfailedtrue
+% \message{!!forced exit from shapebox!!}%
+% \restoreshapebox
+% \exitloop
+% \else
+% \advance\shapecounter \plusone
+% \fi}
+%
+% But now that the lastnode bugfixes are wide spread we can use:
+%
+% We will turn this into a \MKIV\ variant.
\def\insertshapesignal
{\normalhbox to \shapesignal{\strut\hss}% plus \strut
\prevdepth\strutdp} % never \nointerlineskip
-% \def\restoreshapebox
-% {\global\setbox\tmpshapebox\copy\originalshapebox} % \oldshapebox
-
\def\restoreshapebox % compensates for the signal
{\global\setbox\tmpshapebox\vbox{\vskip-\lineheight\unvcopy\oldshapebox}}
@@ -921,8 +904,6 @@
\advance\shapecounter \plusone
\fi}
-\endETEX
-
\def\beginofshapebox
{\setbox\oldshapebox\normalvbox
\bgroup
@@ -1038,8 +1019,22 @@
%D preparing a long list of words we decided to show the
%D hyphens, but had to find out that the \PLAIN\ alternative
%D can hardly be used and|/|or adapted to typesetting. The next
-%D two macros do the job and a little more.
-%D
+%D two macros do the job and a little more. First we define the
+%D (slightly adapted) plain variant:
+
+\def\showhyphens#1%
+ {\begingroup
+ \setbox\scratchbox\vbox
+ {\parfillskip\zerocount
+ \hsize\maxdimen
+ %\tenrm
+ \pretolerance\minusone
+ \tolerance\minusone
+ \hbadness\zerocount
+ \showboxdepth\zerocount
+ \ #1}%
+ \endgroup}
+
%D The simple command \type{\hyphenatedword} accepts one
%D argument and gives the hyphenated word. This macro calls for
%D
@@ -2262,11 +2257,13 @@
\hskip-\scratchdimen
\normalhbox to \scratchdimen{\hss\flushnextbox\hss}}}
-\def\startoverlay
+\unexpanded\def\startoverlay
{\bgroup
\let\stopoverlay\egroup
\processboxes\dooverlaybox}
+\let\stopoverlay\relax
+
% %D \macros
% %D {starthspread}
% %D
@@ -2700,31 +2697,35 @@
%D \normalhbox{y:\foundbox{two}{a}} \par
%D \stoptyping
-% a first version
+% we keep it around as a demonstration of good old tex code:
%
% \def\@@stackbox{boxstack:b:}
% \def\@@stackmax{boxstack:m:}
% \def\@@stacktag{boxstack:t:}
+% \def\@@stacklst{boxstack:l:}
%
% \def\initializeboxstack#1%
% {\ifundefined{\@@stackbox#1}%
% \@EA\newbox\csname\@@stackbox#1\endcsname
% \else
% \global\setbox\csname\@@stackbox#1\endcsname\normalvbox{}%
+% \def\docommand##1{\global\letbeundefined{\@@stacktag#1:##1}}%
+% \processcommacommand[\getvalue{\@@stacklst#1}]\docommand
% \fi
-% % actually we should erase the old values
-% \setgvalue{\@@stackmax#1}{0}}
+% \global\letvalue{\@@stacklst#1}\empty
+% \global\letvalue{\@@stackmax#1}\!!zeropoint}
%
% \def\savebox#1#2% stack name
% {\dowithnextbox
% {\doifdefined{\@@stackbox#1}
% {\@EA\doglobal\@EA\increment\csname\@@stackmax#1\endcsname
-% \setxvalue{\@@stacktag#2}{\csname\@@stackmax#1\endcsname}%
-% \global\setbox\csname\@@stackbox#1\endcsname=\normalvbox
+% \setxvalue{\@@stacktag#1:#2}{\csname\@@stackmax#1\endcsname}%
+% \setxvalue{\@@stacklst#1}{\getvalue{\@@stacklst#1},#2}%
+% \global\setbox\csname\@@stackbox#1\endcsname\normalvbox
% {\forgetall
-% \setbox\scratchbox=\normalvbox{\flushnextbox}
-% \ht\scratchbox=\onepoint
-% \dp\scratchbox=\zeropoint
+% \setbox\scratchbox\normalvbox{\flushnextbox}
+% \ht\scratchbox\onepoint
+% \dp\scratchbox\zeropoint
% \unvbox\csname\@@stackbox#1\endcsname
% \offinterlineskip
% \allowbreak
@@ -2734,76 +2735,21 @@
% \def\foundbox#1#2%
% {\normalvbox
% {\doifdefined{\@@stackbox#1}
-% {\doifdefined{\@@stacktag#2}
-% {\setbox\scratchbox=\normalvbox
+% {\doifdefined{\@@stacktag#1:#2}
+% {\setbox\scratchbox\normalvbox
% {\splittopskip\zeropoint
-% \setbox0=\copy\csname\@@stackbox#1\endcsname
-% \dimen0=\getvalue{\@@stacktag#2}pt
-% \advance\dimen0 by -\onepoint
-% \setbox2=\vsplit0 to \dimen0
+% \setbox0\copy\csname\@@stackbox#1\endcsname
+% \dimen0=\getvalue{\@@stacktag#1:#2}\points
+% \advance\dimen0 -\onepoint
+% \setbox2\vsplit0 to \dimen0
% \ifdim\ht0>\onepoint
-% \setbox0=\vsplit0 to \onepoint
+% \setbox0\vsplit0 to \onepoint
% \fi
-% \unvbox0\setbox0=\lastbox\unvbox0}%
+% \unvbox0\setbox0\lastbox\unvbox0}%
% \unvbox\scratchbox}}}}
-
-\beginTEX \newbox
-
-\def\@@stackbox{boxstack:b:}
-\def\@@stackmax{boxstack:m:}
-\def\@@stacktag{boxstack:t:}
-\def\@@stacklst{boxstack:l:}
-
-\def\initializeboxstack#1%
- {\ifundefined{\@@stackbox#1}%
- \@EA\newbox\csname\@@stackbox#1\endcsname
- \else
- \global\setbox\csname\@@stackbox#1\endcsname\normalvbox{}%
- \def\docommand##1{\global\letbeundefined{\@@stacktag#1:##1}}%
- \processcommacommand[\getvalue{\@@stacklst#1}]\docommand
- \fi
- \global\letvalue{\@@stacklst#1}\empty
- \global\letvalue{\@@stackmax#1}\!!zeropoint}
-
-\def\savebox#1#2% stack name
- {\dowithnextbox
- {\doifdefined{\@@stackbox#1}
- {\@EA\doglobal\@EA\increment\csname\@@stackmax#1\endcsname
- \setxvalue{\@@stacktag#1:#2}{\csname\@@stackmax#1\endcsname}%
- \setxvalue{\@@stacklst#1}{\getvalue{\@@stacklst#1},#2}%
- \global\setbox\csname\@@stackbox#1\endcsname\normalvbox
- {\forgetall
- \setbox\scratchbox\normalvbox{\flushnextbox}
- \ht\scratchbox\onepoint
- \dp\scratchbox\zeropoint
- \unvbox\csname\@@stackbox#1\endcsname
- \offinterlineskip
- \allowbreak
- \box\scratchbox}}}%
- \normalvbox}
-
-\def\foundbox#1#2%
- {\normalvbox
- {\doifdefined{\@@stackbox#1}
- {\doifdefined{\@@stacktag#1:#2}
- {\setbox\scratchbox\normalvbox
- {\splittopskip\zeropoint
- \setbox0\copy\csname\@@stackbox#1\endcsname
- \dimen0=\getvalue{\@@stacktag#1:#2}\points
- \advance\dimen0 -\onepoint
- \setbox2\vsplit0 to \dimen0
- \ifdim\ht0>\onepoint
- \setbox0\vsplit0 to \onepoint
- \fi
- \unvbox0\setbox0\lastbox\unvbox0}%
- \unvbox\scratchbox}}}}
-
-\def\doifboxelse#1#2%
- {\doifdefinedelse{\@@stacktag#1:#2}}
-
-\endTEX
-
-\beginETEX \newbox
+%
+% \def\doifboxelse#1#2%
+% {\doifdefinedelse{\@@stacktag#1:#2}}
\def\@@stackbox{@box@}
\def\@@stacklst{@xob@}
@@ -2992,13 +2938,6 @@
\def\setdimentoatleast#1#2%
{\ifdim#1>\zeropoint\else#1=#2\fi}
-%D We need'm raw.
-
-\ifx \normalhbox \undefined \let \normalhbox = \hbox \fi
-\ifx \normalvbox \undefined \let \normalvbox = \vbox \fi
-\ifx \normalvtop \undefined \let \normalvtop = \vtop \fi
-\ifx \normalvcenter \undefined \let \normalvcenter = \vcenter \fi
-
%D And even rawer:
\let\naturalhbox \normalhbox
@@ -3006,13 +2945,13 @@
\let\naturalvtop \normalvtop
\let\naturalvcenter \normalvtop
-\beginOMEGA dir
+\ifdefined\textdir
-\def\naturalhbox{\normalhbox dir TLT}
-\def\naturalvbox{\normalvbox dir TLT}
-%def\naturalvtop{\normalvtop dir TLT}
+ \def\naturalhbox{\normalhbox dir TLT}
+ \def\naturalvbox{\normalvbox dir TLT}
+ %def\naturalvtop{\normalvtop dir TLT}
-\endOMEGA
+\fi
%D \macros
%D {vcenter}
@@ -3044,27 +2983,17 @@
%D
%D A prelude to an extended \TEX:
-% it's about time to drop tex in favour of etex / TEX VERSION TO BE TESTED
-
-\beginTEX
-
- \def\setboxllx #1#2{\bgroup\scratchdimen#2\expanded{\egroup\noexpand\setevalue{b@@x\number#1}{\the\scratchdimen}}}
- \def\setboxlly #1#2{\bgroup\scratchdimen#2\expanded{\egroup\noexpand\setevalue{b@@y\number#1}{\the\scratchdimen}}}
-
- \def\gsetboxllx#1#2{\bgroup\scratchdimen#2\setxvalue{b@@x\number#1}{\the\scratchdimen}\egroup}
- \def\gsetboxlly#1#2{\bgroup\scratchdimen#2\setxvalue{b@@y\number#1}{\the\scratchdimen}\egroup}
-
-\endTEX
-
-\beginETEX
-
- \def\setboxllx#1#2{\setevalue{b@@x\number#1}{\the\dimexpr(#2)}}
- \def\setboxlly#1#2{\setevalue{b@@y\number#1}{\the\dimexpr(#2)}}
+% \def\setboxllx #1#2{\bgroup\scratchdimen#2\expanded{\egroup\noexpand\setevalue{b@@x\number#1}{\the\scratchdimen}}}
+% \def\setboxlly #1#2{\bgroup\scratchdimen#2\expanded{\egroup\noexpand\setevalue{b@@y\number#1}{\the\scratchdimen}}}
+%
+% \def\gsetboxllx#1#2{\bgroup\scratchdimen#2\setxvalue{b@@x\number#1}{\the\scratchdimen}\egroup}
+% \def\gsetboxlly#1#2{\bgroup\scratchdimen#2\setxvalue{b@@y\number#1}{\the\scratchdimen}\egroup}
- \def\gsetboxllx{\global\setboxllx}
- \def\gsetboxlly{\global\setboxlly}
+\def\setboxllx#1#2{\setevalue{b@@x\number#1}{\the\dimexpr#2\relax}}
+\def\setboxlly#1#2{\setevalue{b@@y\number#1}{\the\dimexpr#2\relax}}
-\endETEX
+\def\gsetboxllx{\global\setboxllx}
+\def\gsetboxlly{\global\setboxlly}
\def\getboxllx#1{\executeifdefined{b@@x\number#1}\zeropoint}
\def\getboxlly#1{\executeifdefined{b@@y\number#1}\zeropoint}
@@ -3094,6 +3023,32 @@
\interactionmode\scratchcounter
\egroup}}
+\def\spreadhbox#1% rebuilds \hbox{<box><hss><box><hss><box>}
+ {\bgroup
+ \ifhbox#1\relax
+ \setbox2\emptybox
+ \unhbox#1%
+ \doloop
+ {\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip
+ \setbox0\lastbox
+ \ifvoid0
+ \exitloop
+ \else
+ \setbox2\hbox
+ {\ifhbox0 \spreadhbox0\else\box0\fi
+ \ifvoid2 \else\hss\unhbox2\fi}%
+ \fi}%
+ \ifvoid2\else\unhbox2\fi
+ \else
+ \box#1%
+ \fi
+ \egroup}
+
+% makes sense:
+
+\showboxbreadth\maxdimen
+\showboxdepth \maxdimen
+
\protect \endinput
% a bit of test code:
diff --git a/tex/context/base/supp-dir.mkii b/tex/context/base/supp-dir.mkii
new file mode 100644
index 000000000..41cd1b56f
--- /dev/null
+++ b/tex/context/base/supp-dir.mkii
@@ -0,0 +1,41 @@
+%D \module
+%D [ file=supp-dir,
+%D version=2004.11.11,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Directional Things,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Inspired by and needed for Adam Lindsay's \XETEX\ efforts:
+%D
+%D \starttyping
+%D \starttext
+%D \input tufte \par
+%D \pardir TRT \input tufte \par \input tufte \par
+%D \pardir TLT \input tufte \par
+%D \stoptext
+%D \stoptyping
+
+\unprotect
+
+\chardef\inlinedirection\zerocount % 0==notset 1==LR 2==RL
+
+\def\pardir#1#2#3% messages end up in a higher level command
+ {\global\TeXXeTstate\plusone
+ \if#2L\chardef\inlinedirection\plusone\else
+ \if#2R\chardef\inlinedirection\plustwo\fi\fi
+ \checkinlinedirection} % needed / added
+
+\def\checkinlinedirection
+ {\ifcase\inlinedirection\or\beginL\or\beginR\fi}
+
+% see core-ini.tex
+%
+% \appendtoks \checkinlinedirection \to \everypar
+
+\protect \endinput
diff --git a/tex/context/base/supp-dir.mkiv b/tex/context/base/supp-dir.mkiv
new file mode 100644
index 000000000..7d2e10070
--- /dev/null
+++ b/tex/context/base/supp-dir.mkiv
@@ -0,0 +1,21 @@
+%D \module
+%D [ file=supp-dir,
+%D version=2004.11.11,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Directional Things,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 no longer have the \ETEX\ direction primitives.
+
+\unprotect
+
+\chardef \inlinedirection \zerocount % 0==notset 1==LR 2==RL
+\let \checkinlinedirection \donothing
+
+\protect \endinput
diff --git a/tex/context/base/supp-dir.tex b/tex/context/base/supp-dir.tex
deleted file mode 100644
index ad14eab1d..000000000
--- a/tex/context/base/supp-dir.tex
+++ /dev/null
@@ -1,70 +0,0 @@
-%D \module
-%D [ file=supp-dir,
-%D version=2004.11.11,
-%D title=\CONTEXT\ Support Macros,
-%D subtitle=Directional Things,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Inspired by and needed for Adam Lindsay's \XETEX\ efforts:
-%D
-%D \starttyping
-%D \starttext
-%D \input tufte \par
-%D \pardir TRT \input tufte \par \input tufte \par
-%D \pardir TLT \input tufte \par
-%D \stoptext
-%D \stoptyping
-
-\unprotect
-
-\chardef \inlinedirection \zerocount % 0==notset 1==LR 2==RL
-\let \checkinlinedirection \donothing
-
-\beginETEX \beginL
-
- \ifx\pardir \undefined
-
- \def\pardir#1#2#3% messages end up in a higher level command
- {\global\TeXXeTstate\plusone
- \if#2L\chardef\inlinedirection\plusone\else
- \if#2R\chardef\inlinedirection\plustwo\fi\fi
- \checkinlinedirection} % needed / added
-
- \let\normalpardir\pardir
-
- \def\checkinlinedirection
- {\ifcase\inlinedirection\or\beginL\or\beginR\fi}
-
- \else
-
-% \let\normalpardir\pardir
-
-% \def\pardir#1#2#3%
-% {\if#2L\chardef\inlinedirection\plusone\else
-% \if#2R\chardef\inlinedirection\plustwo\fi\fi
-% \normalpardir#1#2#3}
-
-% \def\beginL
-% {} % todo: \normalpardir...
-
-% \def\beginR
-% {} % todo: \normalpardir...
-
-% \def\checkinlinedirection
-% {\ifcase\inlinedirection\or\beginL\or\beginR\fi}
-
- \fi
-
-\endETEX
-
-% see core-ini.tex
-%
-% \appendtoks \checkinlinedirection \to \everypar
-
-\protect \endinput
diff --git a/tex/context/base/supp-eps.tex b/tex/context/base/supp-eps.tex
index 0a3cfa2b6..5684b25dd 100644
--- a/tex/context/base/supp-eps.tex
+++ b/tex/context/base/supp-eps.tex
@@ -19,7 +19,7 @@
%D were put in \type{supp-pdf}, I considered it more suitable
%D to give the \EPS\ macros their own module.
-\writestatus{loading}{Context Support Macros / EPS}
+\writestatus{loading}{ConTeXt Support Macros / EPS}
%D \macros
%D {dogetEPSboundingbox}
diff --git a/tex/context/base/supp-fil.lua b/tex/context/base/supp-fil.lua
index 32c5fb865..a93b0bce9 100644
--- a/tex/context/base/supp-fil.lua
+++ b/tex/context/base/supp-fil.lua
@@ -12,26 +12,30 @@ if not modules then modules = { } end modules ['supp-fil'] = {
at the <l n='tex'/> side.</p>
--ldx]]--
+local find, gsub, match = string.find, string.gsub, string.match
+
+local ctxcatcodes = tex.ctxcatcodes
+
support = support or { }
environment = environment or { }
environment.outputfilename = environment.outputfilename or environment.jobname
function support.checkfilename(str) -- "/whatever..." "c:..." "http://..."
- cs.chardef("kindoffile",boolean.tonumber(str:find("^/") or str:find("[%a]:")))
+ commands.chardef("kindoffile",boolean.tonumber(find(str,"^/") or find(str,"[%a]:")))
end
function support.thesanitizedfilename(str)
- tex.write((str:gsub("\\","/")))
+ tex.write((gsub(str,"\\","/")))
end
function support.splitfilename(fullname)
local path, name, base, suffix, kind = '', fullname, fullname, '', 0
- local p, n = fullname:match("^(.+)/(.-)$")
+ local p, n = match(fullname,"^(.+)/(.-)$")
if p and n then
path, name, base = p, n, n
end
- local b, s = base:match("^(.+)%.(.-)$")
+ local b, s = match(base,"^(.+)%.(.-)$")
if b and s then
name, suffix = b, s
end
@@ -42,38 +46,43 @@ function support.splitfilename(fullname)
else
kind = 2
end
---~ print(fullname,path,base,name,suffix)
- cs.def("splitofffull", fullname)
- cs.def("splitoffpath", path)
- cs.def("splitoffbase", base)
- cs.def("splitoffname", name)
- cs.def("splitofftype", suffix)
- cs.chardef("splitoffkind", kind)
+ commands.def("splitofffull", fullname)
+ commands.def("splitoffpath", path)
+ commands.def("splitoffbase", base)
+ commands.def("splitoffname", name)
+ commands.def("splitofftype", suffix)
+ commands.chardef("splitoffkind", kind)
end
function support.splitfiletype(fullname)
local name, suffix = fullname, ''
- local n, s = fullname:match("^(.+)%.(.-)$")
+ local n, s = match(fullname,"^(.+)%.(.-)$")
if n and s then
name, suffix = n, s
end
- cs.def("splitofffull", fullname)
- cs.def("splitoffpath", "")
- cs.def("splitoffname", name)
- cs.def("splitofftype", suffix)
+ commands.def("splitofffull", fullname)
+ commands.def("splitoffpath", "")
+ commands.def("splitoffname", name)
+ commands.def("splitofftype", suffix)
end
function support.doifparentfileelse(n)
- cs.testcase(n==environment.jobname or n==environment.jobname..'.tex' or n==environment.outputfilename)
+ commands.testcase(n==environment.jobname or n==environment.jobname..'.tex' or n==environment.outputfilename)
end
-- saves some .15 sec on 12 sec format generation
+local lastexistingfile = ""
+
function support.doiffileexistelse(name)
if not name or name == "" then
- return cs.testcase(false)
+ lastexistingfile = ""
else
- local n = input.findtexfile(name)
- return cs.testcase(n and n ~= "")
+ lastexistingfile = resolvers.findtexfile(name) or ""
end
+ return commands.testcase(lastexistingfile ~= "")
+end
+
+function support.lastexistingfile()
+ tex.sprint(ctxcatcodes,lastexistingfile)
end
diff --git a/tex/context/base/supp-fil.mkii b/tex/context/base/supp-fil.mkii
index ff4a2ab01..1e86498e4 100644
--- a/tex/context/base/supp-fil.mkii
+++ b/tex/context/base/supp-fil.mkii
@@ -9,12 +9,185 @@
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details
+%C details.
+
+%D \TEX\ operates on files, so one wouldn't wonder that there
+%D is a separate module for file support. In \CONTEXT\ files
+%D are used for several purposes:
+%D
+%D \startitemize[packed]
+%D \item general textual input
+%D \item logging status information
+%D \item saving registers, lists and references
+%D \item buffering defered textual input
+%D \stopitemize
+%D
+%D When dealing with files we can load them as a whole, using
+%D the \type{\input} primitive or load them on a line||by||line
+%D basis, using \type{\read}. Writing is always done line by
+%D line, using \type{\write}.
+
+\writestatus{loading}{ConTeXt Support Macros / Files}
\unprotect
+\ifx\undefined\f!pathseparator
+ \def\f!pathseparator{/}
+ \def\f!currentpath {.}
+ \def\f!parentpath {..}
+\fi
+
\def\openinputfile #1#2{\immediate\openin #1="#2"\relax} \def\closeinputfile #1{\immediate\closein #1}
\def\openoutputfile#1#2{\immediate\openout#1="#2"\relax} \def\closeoutputfile#1{\immediate\closeout#1}
+
+%D \macros
+%D {pushendofline,popendofline}
+%D
+%D When we are loading files in the middle of the typesetting
+%D process, for instance when we load references, we have to be
+%D sure that the reading process does not generate so called
+%D 'spurious spaces'. This can be prevented by assigning the
+%D line ending character the \CATCODE\ comment. This is
+%D accomplished by
+%D
+%D \starttyping
+%D \pushendofline
+%D ... reading ...
+%D \popendofline
+%D \stoptyping
+%D
+%D Just to be sure, we save the current meaning of \type{^^M}
+%D in \type{\poppedendofline}.
+
+% \chardef\poppedendofline\catcode`\^^M
+%
+% \def\pushendofline
+% {\chardef\poppedendofline\catcode`\^^M\relax
+% \catcode`\^^M\@@comment\relax}
+%
+% \def\popendofline
+% {\catcode`\^^M\poppedendofline}
+%
+% support for nested usage:
+
+\newcount \endoflinelevel
+
+\ifx\newlinecode\undefined \chardef\newlinecode=`\^^M \fi
+
+\def\pushendofline
+ {\advance\endoflinelevel\plusone
+ \expandafter\chardef\csname :eol:\number\endoflinelevel\endcsname\catcode\newlinecode
+ \catcode\newlinecode\@@comment\relax}
+
+\def\popendofline
+ {\catcode\newlinecode\csname :eol:\number\endoflinelevel\endcsname
+ \advance\endoflinelevel\minusone}
+
+\def\restoreendofline
+ {\catcode\newlinecode\@@endofline}
+
+%D \macros
+%D {scratchread, scratchwrite}
+%D
+%D We define a scratch file for reading. Keep in mind that
+%D the number of files is limited to~16, so use this one when
+%D possible. We also define a scratch output file.
+
+\ifx\undefined\scratchread \newread \scratchread \fi
+\ifx\undefined\scratchwrite \newwrite\scratchwrite \fi
+
+%D \macros
+%D {unlinkfile}
+%D
+%D Sometimes we want to make sure a file is deleted, so here
+%D is a macro that does the job. It's named after the \PERL\
+%D one.
+
+\def\unlinkfile#1%
+ {\openoutputfile \scratchwrite{#1}%
+ \closeoutputfile\scratchwrite}
+
+%D \macros
+%D {writeln}
+%D
+%D This saves a few tokens:
+
+\def\writeln#1{\write#1{}}
+
+\def\doiffileexistselse#1%
+ {\doifelsenothing{#1}
+ {\secondoftwoarguments}
+ {\openinputfile\scratchread{#1}%
+ \ifeof\scratchread
+ \closeinputfile\scratchread
+ \expandafter\secondoftwoarguments
+ \else
+ \closeinputfile\scratchread
+ \expandafter\firstoftwoarguments
+ \fi}}
+
+%D \macros
+%D {doprocessfile,fileline,fileprocessedtrue,dofinishfile}
+%D
+%D The next macro offers a framework for processing files on a
+%D line by line basis.
+%D
+%D \starttyping
+%D \doprocessfile \identifier {name} \action
+%D \stoptyping
+%D
+%D The first argument can for instance be \type{\scratchread}.
+%D The action must do something with \type{\fileline}, which
+%D holds the current line. One can halfway step out using
+%D \type{\dofinishfile} and ise \type{\iffileprocessed} to
+%D see if indeed some content was found.
+
+\newif\iffileprocessed
+
+\let\fileline\empty
+
+\def\doprocessfile#1#2#3%
+ {\openinputfile{#1}{#2}%
+ \ifeof#1%
+ \fileprocessedfalse
+ \closeinputfile#1%
+ \else
+ \fileprocessedtrue
+ \gdef\dofinishfile
+ {\closeinputfile#1%
+ \global\let\doprocessline\relax}%
+ \gdef\doprocessline
+ {\ifeof#1%
+ \expandafter\dofinishfile
+ \else
+ \global\read#1 to \fileline
+ #3\relax
+ \expandafter\doprocessline
+ \fi}%
+ \expandafter\doprocessline
+ \fi}
+
+%D \macros
+%D {pathplusfile,assignfullfilename,sanitizefilename}
+%D
+%D Use \type{\pathplusfile} to compose a full file name, like
+%D in:
+%D
+%D \starttyping
+%D \pathplusfile{path}{file}
+%D \stoptyping
+%D
+%D By default, this expands into {\tt \pathplusfile{path}{file}}.
+
+\def\pathplusfile#1#2{#1\f!pathseparator#2}
+
+%D This one constructs a filename from a (possible empty)
+%D path and filename.
+
+\def\assignfullfilename#1#2\to#3%
+ {\doifelsenothing{#1}
+ {\edef#3{#2}}
+ {\edef#3{#1\f!pathseparator#2}}}
%D For the moment, we limit sanitizing to taking care of
%D active \type {/}.
@@ -40,6 +213,10 @@
\egroup
+%D NEW:
+
+\chardef\kindoffile=0 % 0=normal 1=full path spec (or http)
+
\def\checkfilename#1%
{\doifinstringelse{@@/}{@@#1}% unix: /full/path
{\chardef\kindoffile\plusone}
@@ -47,6 +224,443 @@
{\chardef\kindoffile\plusone}
{\chardef\kindoffile\zerocount}}}
+%D \macros
+%D {input, normalinput}
+%D
+%D Sometimes we run into troubles when \type {\input} wants to get
+%D expanded, e.g. in a \type {\write} (which happens in the metafun
+%D manual when we permit long MP lines). So, instead of fixing that,
+%D we go for a redefinition of \type {\input}. Of course it's better
+%D to use \type {\readfile} or \type {\processfile}.
+
+\unexpanded\def\input{\normalinput}
+
+\def\inputgivenfile#1{\normalinput"#1"\relax}
+
+%D \macros
+%D {readfile,ReadFile,maxreadlevel}
+%D
+%D One cannot be sure if a file exists. When no file can be
+%D found, the \type{\input} primitive gives an error message
+%D and switches to interactive mode. The macro \type{\readfile}
+%D takes care of non||existing files. This macro has two faces.
+%D
+%D \starttyping
+%D \ReadFile {filename}
+%D \readfile {filename} {before loading} {not found}
+%D \stoptyping
+%D
+%D Many \TEX\ implementations have laid out some strategy for
+%D locating files. This can lead to unexpected results,
+%D especially when one loads files that are not found in the
+%D current directory. Let's give an example of this. In
+%D \CONTEXT\ illustrations can be defined in an external file.
+%D The resizing macro first looks if an illustration is defined
+%D in the local definitions file. When no such file is found,
+%D it searches for a global file and when this file is not
+%D found either, the illustration itself is scanned for
+%D dimensions. One can imagine what happens if an adapted,
+%D localy stored illustration, is scaled according to
+%D dimensions stored somewhere else.
+%D
+%D When some \TEX\ implementation starts looking for a file, it
+%D normally first looks in the current directory. When no file
+%D is found, \TEX\ starts searching on the path where format
+%D and|/|or style files are stored. Depending on the implementation
+%D this can considerably slow down processing speed.
+%D
+%D In \CONTEXT, we support a project||wise ordening of files.
+%D In such an approach it seems feasible to store common files
+%D in a lower directory. When for instance searching for a
+%D general layout file, we therefore have to backtrack.
+%D
+%D These three considerations have lead to a more advanced
+%D approach for loading files.
+%D
+%D We first present an earlier implementation of
+%D \type{\readfile}. This command backtracks parent
+%D directories, upto a predefined level. Users can change this
+%D level, but we default to~3.
+%D
+%D \starttyping
+%D \def\maxreadlevel {3}
+%D \stoptyping
+%D
+%D This is a pseudo \COUNTER.
+%D
+%D We use \type{\normalinput} instead of \type{\input}
+%D because we want to be able to redefine the original
+%D \type{\input} when needed, for instance when loading third
+%D party libraries.
+
+\newevery \everybeforereadfile \EveryBeforeReadFile
+\newevery \everyafterreadfile \EveryAfterReadFile
+
+\let \everyreadfile \everybeforereadfile
+
+\newif\iftracefiles
+
+\newcount\readlevel
+
+\def\maxreadlevel{3}
+
+\newconditional\trackfilenames
+\let\trackedfilename\empty
+
+% We need to postpone loading, else we got frozen type-* files and so when
+% a format is generated on a source path.
+
+\def\doreadfile#1#2#3#4%
+ {\sanitizefilename#2\to\readfilename
+ \ifx\readfilename\empty
+ % silently ignore
+ \else
+ \let\trackedfilename\readfilename
+ \ifconditional\trackfilenames
+ \doifundefinedelse{fn..\trackedfilename}\donetrue\donefalse
+ \else
+ \donetrue
+ \fi
+ \ifdone
+ \checkfilename\readfilename
+ \ifcase\kindoffile
+ \iftracefiles\writestatus\m!systems{searching for \readfilename\space on #1}\fi
+ % not a full path or url, check for existence
+ \doifelsenothing{#1}
+ {\def\next{\redoreadfile\readfilename{#3}{#4}}}%
+ {\def\next{\redoreadfile{\pathplusfile{#1}{\readfilename}}{#3}{#4}}}%
+ \else
+ % a full path or url, no further checking done
+ \doiffileexistselse\readfilename
+ {\iftracefiles\writestatus\m!systems{located \readfilename}\fi
+ \def\next{#3\dodoreadfile}}%
+ {\iftracefiles\writestatus\m!systems{not found \readfilename}\fi
+ \def\next{#4}}%
+ \fi
+ \else
+ \edef\readfilename{\getvalue{fn..\readfilename}}%
+ \iftracefiles\writestatus\m!systems{already located \readfilename}\fi
+ \def\next{#3\dodoreadfile}%
+ \fi
+ \expandafter\next
+ \fi}
+
+\def\redoreadfile#1#2#3%
+ {\doiffileexistselse{#1}%
+ {\edef\readfilename{#1}%
+ \iftracefiles\writestatus\m!systems{#1 located}\fi
+ \def\next{#2\dodoreadfile}}%
+ {\iftracefiles\writestatus\m!systems{cannot locate #1}\fi
+ \advance\readlevel\minusone
+ \ifnum\readlevel>\zerocount
+ \edef\readfilename{\pathplusfile{\f!parentpath}{\readfilename}}%
+ \def\next{\redoreadfile\readfilename{#2}{#3}}%
+ \else
+ \def\next{#3}%
+ \fi}%
+ \next}
+
+\def\dodoreadfile % we provide hooks, for instance for \enableXML
+ {\ifconditional\trackfilenames
+ \setxvalue{fn..\trackedfilename}{\readfilename}%
+ \fi
+ \the\everybeforereadfile
+% \normalinput\readfilename\relax
+ \relax\inputgivenfile\readfilename\relax
+ \the\everyafterreadfile}
+
+% too less:
+%
+% \unexpanded\def\readfile% #1%
+% {\readlevel\maxreadlevel
+% \doreadfile\empty} % {#1}
+%
+% too much:
+%
+% \unexpanded\def\readfile#1#2#3%
+% {\readlocfile{#1}{#2}
+% {\readjobfile{#1}{#2}
+% {\readsysfile{#1}{#2}{#3}}}}
+%
+% just ok:
+
+\unexpanded\def\readfile#1#2#3%
+ {\readlocfile{#1}{#2}{\readsysfile{#1}{#2}{#3}}}
+
+\def\readtexfile#1#2#3%
+ {\pushcatcodetable \catcodetable \ctxcatcodes
+ \readfile{#1}{#2}{#3}%
+ \popcatcodetable}
+
+\def\readxmlfile#1#2#3%
+ {\pushcatcodetable \catcodetable \xmlcatcodes
+ \readfile{#1}{#2}{#3}%
+ \popcatcodetable}
+
+\unexpanded\def\ReadFile#1%
+ {\readfile{#1}\donothing\donothing}
+
+%D \macros
+%D {readjobfile,readlocfile,readsysfile,
+%D readfixfile,readsetfile}
+%D
+%D This implementation honnors the third situation, but we
+%D still can get unwanted files loaded and/or can get involved
+%D in extensive searching.
+%D
+%D Due to different needs, we decided to offer four alternative
+%D loading commands. With \type{\readjobfile} we load a local
+%D file and do no backtracking, while \type{\readlocfile}
+%D backtracks~\number\readlevel\ directories, including the current
+%D one.
+
+\unexpanded\def\readjobfile % #1% current path, no backtracking
+ {\readlevel\zerocount
+ \doreadfile\f!currentpath} % {#1}}
+
+\unexpanded\def\readlocfile % #1% current path, backtracking
+ {\readlevel\maxreadlevel
+ \doreadfile\f!currentpath} % {#1}}
+
+%D System files can be anywhere and therefore
+%D \type{\readsysfile} is not bound to the current directory
+%D and obeys the \TEX\ implementation.
+
+\unexpanded\def\readsysfile % #1% current path, obeys tex search
+ {\readlevel\zerocount
+ \doreadfile\empty} % {#1}}
+
+%D Of the last two, \type{\readfixfile} searches on the
+%D directory specified and backtracks too, while
+%D \type{\readsetfile} does only search on the specified path.
+
+\unexpanded\def\readfixfile % #1#2% specified path, backtracking
+ {\readlevel\maxreadlevel
+ \doreadfile} % {#1}{#2}}
+
+\unexpanded\def\readsetfile % #1#2% specified path, no backtracking
+ {\readlevel\zerocount
+ \doreadfile} % {#1}{#2}}
+
+%D After having defined this commands, we reconsidered the
+%D previously defined \type{\readfile}. This time we more or
+%D less impose the search order.
+
+\unexpanded\def\readfile#1#2#3%
+ {\readlocfile{#1}{#2}
+ {\readjobfile{#1}{#2}
+ {\readsysfile{#1}{#2}{#3}}}}
+
+%D So now we've got ourselves five file loading commands:
+%D
+%D \starttyping
+%D \readfile {filename} {before loading} {not found}
+%D
+%D \readjobfile {filename} {before loading} {not found}
+%D \readlocfile {filename} {before loading} {not found}
+%D \readfixfile {filename} {before loading} {not found}
+%D \readsysfile {directory} {filename} {before loading} {not found}
+%D \stoptyping
+
+%D \macros
+%D {readjobfile,readlocfile,readsysfile,readfixfile}
+%D
+%D The next four alternatives can be used for opening files
+%D for reading on a line||by||line basis. These commands get
+%D an extra argument, the filetag. Explicit closing is done
+%D in the normal way by \type{\closein}.
+
+\def\doopenin#1#2%
+ {\sanitizefilename#2\to\readfilename
+ \checkfilename\readfilename
+ \ifcase\kindoffile
+ \advance\readlevel\plusone
+ \openinputfile{#1}\readfilename
+ \ifeof#1% \relax
+ \ifnum\readlevel>\maxreadlevel % \relax
+ \else
+ \closeinputfile#1% \relax
+ \doopenin{#1}{\pathplusfile\f!parentpath{#2}}%
+ \fi
+ \fi
+ \fi}
+
+\def\openjobin#1#2%
+ {\readlevel\zerocount
+ \doopenin{#1}{\pathplusfile\f!currentpath{#2}}}
+
+\def\opensysin % #1#2%
+ {\readlevel\maxreadlevel
+ \doopenin} % {#1}{#2}}
+
+\def\openlocin#1#2%
+ {\readlevel\maxreadlevel
+ \doopenin{#1}{\pathplusfile\f!currentpath{#2}}}
+
+\def\openfixin#1#2#3%
+ {\readlevel\maxreadlevel
+ \doopenin{#1}{\pathplusfile{#2}{#3}}}
+
+%D \macros
+%D {doiffileelse,doiflocfileelse}
+%D
+%D The next alternative only looks if a file is present. No
+%D loading is done. This one obeys the standard \TEX\
+%D implementation method.
+%D
+%D \starttyping
+%D \doiffileelse {filename} {found} {not found}
+%D \stoptyping
+%D
+%D \starttyping
+%D \doiflocfileelse {filename} {before loading} {not found}
+%D \stoptyping
+
+\def\doiffileelse {\doiffileexistselse}
+\def\doiffile #1{\doiffileexistselse{#1}\firstofoneargument\gobbleoneargument}
+\def\doifnotfile #1{\doiffileexistselse{#1}\gobbleoneargument\firstofoneargument}
+
+\def\doiflocfileelse#1%
+ {\makelocreadfilename{#1}%
+ \doiffileelse\readfilename}
+
+\def\makelocreadfilename#1%
+ {\sanitizefilename#1\to\readfilename
+ \checkfilename\readfilename
+ \ifcase\kindoffile
+ \edef\readfilename{\pathplusfile\f!currentpath{#1}}%
+ \fi}
+
+%D \macros
+%D {doonlyonce, doinputonce, doendinputonce}
+%D
+%D Especially macropackages need only be loaded once.
+%D Repetitive loading not only costs time, relocating registers
+%D often leads to abortion of the processing because \TEX's
+%D capacity is limited. One can prevent multiple execution and
+%D loading by using one of both:
+%D
+%D \starttyping
+%D \doonlyonce{actions}
+%D \doinputonce{filename}
+%D \doendinputonce{filename}
+%D \stoptyping
+%D
+%D This command obeys the standard method for locating files.
+
+\long\def\doonlyonce#1%
+ {\doifundefinedelse{@@@#1@@@}
+ {\letgvalue{@@@#1@@@}\empty
+ \firstofoneargument}
+ {\gobbleoneargument}}
+
+\def\doinputonce#1%
+% {\doonlyonce{#1}{\doiffileelse{#1}{\normalinput#1\relax}\donothing}}
+ {\doonlyonce{#1}{\doiffileelse{#1}{\inputgivenfile{#1}}\donothing}}
+
+\def\doendinputonce#1%
+ {\doifdefined{@@@#1@@@}\endinput}
+
+\def\forgetdoingonce#1%
+ {\global\letbeundefined{@@@#1@@@}}
+
+%D \macros
+%D {doifparentfileelse}
+%D
+%D The test \type{\doifelse{\jobname}{filename}} does not give
+%D the desired result, simply because \type{\jobname} expands
+%D to characters with \CATCODE~12, while the characters in
+%D \type{filename} have \CATCODE~11. So we can better use:
+%D
+%D \starttyping
+%D \doifparentfileelse{filename}{yes}{no}
+%D \stoptyping
+%D
+%D Since \TEXEXEC\ (and thereby \CONTEXT) supports renaming of
+%D the outputfile, we also need to check on that alternative
+%D name.
+
+\ifx\outputfilename\undefined \def\outputfilename{\jobname} \fi
+
+\def\doifparentfileelse#1%
+ {\doifsamestringelse{#1}{\jobname }\firstoftwoarguments
+ {\doifsamestringelse{#1}{\jobname.\c!tex}\firstoftwoarguments
+ {\doifsamestringelse{#1}{\outputfilename}\firstoftwoarguments\secondoftwoarguments}}}
+
+\def\normalless {<} % geen \let !
+\def\normalmore {>} % geen \let !
+\def\normalequal {=} % geen \let !
+\def\normaldblquote{"} % geen \let !
+
+\newcount\readingfilelevel
+
+\def\popfilecharacter#1#2%
+ {\ifnum\catcode`#1=\@@other \ifnum#2=\@@other \else
+ %\message{[popping catcode #1 to #2]}%
+ \catcode`#1=#2\relax
+ \fi \fi}
+
+\ifx\\\undefined \let\\\relax \fi
+
+%D This changing catcodes is a direct result from the fact
+%D that we support some long standing conventions with
+%D regards to active characters (german ", polish /,
+%D french : and ;).
+
+%D We need to redo this: catcode sets and such
+
+\newtoks \everystartreadingfile
+\newtoks \everystopreadingfile
+
+\def\startreadingfile% beter een every en \setnormalcatcodes
+ {\global\advance\readingfilelevel\plusone
+ \the\everystartreadingfile
+ \beginrestorecatcodes
+ \setcatcodetable\prtcatcodes}
+
+\def\stopreadingfile
+ {\endrestorecatcodes
+ \the\everystopreadingfile
+ \global\advance\readingfilelevel\minusone}
+
+\let\normalstartreadingfile\startreadingfile
+\let\normalstopreadingfile \stopreadingfile
+
+%D \macros
+%D {splitfilename}
+%D
+%D I should have made this one sooner. This macro was first needed when
+%D ran into graphic with a period in the pathpart.
+%D
+%D \startbuffer
+%D \def\showfilesplit
+%D {\bgroup \tttf
+%D \hbox{(full: \splitofffull)}\space
+%D \hbox{(path: \splitoffpath)}\space
+%D \hbox{(base: \splitoffbase)}\space
+%D \hbox{(name: \splitoffname)}\space
+%D \hbox{(type: \splitofftype)}\space
+%D \egroup}
+%D
+%D \splitfilename{c:/aa/bb/cc/dd.ee.ff} \showfilesplit \endgraf
+%D \splitfilename{c:/aa/bb/cc/dd.ee} \showfilesplit \endgraf
+%D \splitfilename{c:/aa/bb/cc/dd} \showfilesplit \endgraf
+%D
+%D \splitfilename{dd.ee.ff} \showfilesplit \endgraf
+%D \splitfilename{dd.ee} \showfilesplit \endgraf
+%D \splitfilename{dd} \showfilesplit \endgraf
+%D \stopbuffer
+%D
+%D \start \typebuffer \getbuffer \stop
+
+\def\splitoffroot{.} \chardef\splitoffkind\zerocount
+
+\let\splitofffull\empty
+\let\splitoffpath\empty
+\let\splitoffbase\empty
+\let\splitoffname\empty
+\let\splitofftype\empty
+
% \def\splitfilename#1%
% {\edef\splitofffull{#1}% normally outside this call: \sanitizefilename#1\to\sanitizedfilename
% \greedysplitstring\splitofffull\at/\to\splitoffpath\and\splitoffbase
@@ -91,9 +705,4 @@
\let\splitoffpath\empty
\greedysplitstring\splitofffull\at.\to\splitoffname\and\splitofftype}
-\def\doifparentfileelse#1%
- {\doifsamestringelse{#1}{\jobname }\firstoftwoarguments
- {\doifsamestringelse{#1}{\jobname.\c!tex}\firstoftwoarguments
- {\doifsamestringelse{#1}{\outputfilename}\firstoftwoarguments\secondoftwoarguments}}}
-
\protect \endinput
diff --git a/tex/context/base/supp-fil.mkiv b/tex/context/base/supp-fil.mkiv
index 586004259..caeaa67cd 100644
--- a/tex/context/base/supp-fil.mkiv
+++ b/tex/context/base/supp-fil.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=supp-fil,
-%D version=2006.09.18,
+%D version=1995.10.10,
%D title=\CONTEXT\ Support Macros,
%D subtitle=Files,
%D author=Hans Hagen,
@@ -9,24 +9,610 @@
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details
+%C details.
-% \input supp-fil.mkii \endinput
+%D \TEX\ operates on files, so one wouldn't wonder that there
+%D is a separate module for file support. In \CONTEXT\ files
+%D are used for several purposes:
+%D
+%D \startitemize[packed]
+%D \item general textual input
+%D \item logging status information
+%D \item saving registers, lists and references
+%D \item buffering defered textual input
+%D \stopitemize
+%D
+%D When dealing with files we can load them as a whole, using
+%D the \type{\input} primitive or load them on a line||by||line
+%D basis, using \type{\read}. Writing is always done line by
+%D line, using \type{\write}.
+
+\writestatus{loading}{ConTeXt Support Macros / Files}
\registerctxluafile{supp-fil}{1.001}
-% \def\sanitizefilename#1\to#2%
-% {\edef#2{\ctxlua{support.thesanitizedfilename("\luaescapestring{#1}")}}}
-% \def\checkfilename #1{\ctxlua{support.checkfilename("\luaescapestring{#1}")}}
-% \def\splitfilename #1{\ctxlua{support.splitfilename("\luaescapestring{#1}")}}
-% \def\splitfiletype #1{\ctxlua{support.splitfiletype("\luaescapestring{#1}")}}
-% \def\doifparentfileelse#1{\ctxlua{support.doifparentfileelse("\luaescapestring{#1}")}}
+\unprotect
+
+\ifx\undefined\f!pathseparator
+ \def\f!pathseparator{/}
+ \def\f!currentpath {.}
+ \def\f!parentpath {..}
+\fi
+
+% \def\openinputfile #1#2{\immediate\openin #1="#2"\relax} \def\closeinputfile #1{\immediate\closein #1}
+% \def\openoutputfile#1#2{\immediate\openout#1="#2"\relax} \def\closeoutputfile#1{\immediate\closeout#1}
+
+\def\openinputfile #1#2{\immediate\openin #1=#2\relax} \def\closeinputfile #1{\immediate\closein #1}
+\def\openoutputfile#1#2{\immediate\openout#1=#2\relax} \def\closeoutputfile#1{\immediate\closeout#1}
+
+%D \macros
+%D {pushendofline,popendofline}
+%D
+%D When we are loading files in the middle of the typesetting
+%D process, for instance when we load references, we have to be
+%D sure that the reading process does not generate so called
+%D 'spurious spaces'. This can be prevented by assigning the
+%D line ending character the \CATCODE\ comment. This is
+%D accomplished by
+%D
+%D \starttyping
+%D \pushendofline
+%D ... reading ...
+%D \popendofline
+%D \stoptyping
+%D
+%D Just to be sure, we save the current meaning of \type{^^M}
+%D in \type{\poppedendofline}.
+
+\newcount \endoflinelevel
+
+\ifx\newlinecode\undefined \chardef\newlinecode=`\^^M \fi
+
+\def\pushendofline
+ {\advance\endoflinelevel\plusone
+ \expandafter\chardef\csname :eol:\number\endoflinelevel\endcsname\catcode\newlinecode
+ \catcode\newlinecode\@@comment\relax}
+
+\def\popendofline
+ {\catcode\newlinecode\csname :eol:\number\endoflinelevel\endcsname
+ \advance\endoflinelevel\minusone}
+
+\def\restoreendofline
+ {\catcode\newlinecode\@@endofline}
+
+%D \macros
+%D {scratchread, scratchwrite}
+%D
+%D We define a scratch file for reading. Keep in mind that
+%D the number of files is limited to~16, so use this one when
+%D possible. We also define a scratch output file.
+
+\ifx\undefined\scratchread \newread \scratchread \fi
+\ifx\undefined\scratchwrite \newwrite\scratchwrite \fi
+
+%D \macros
+%D {unlinkfile}
+%D
+%D Sometimes we want to make sure a file is deleted, so here
+%D is a macro that does the job. It's named after the \PERL\
+%D one.
+
+\def\unlinkfile#1{\ctxlua{os.remove([[#1]])}}
+
+%D \macros
+%D {writeln}
+%D
+%D This saves a few tokens:
+
+\def\writeln#1{\write#1{}}
+
+\def\doiffileexistselse #1{\ctxlua{support.doiffileexistelse([[#1]])}}
+\def\lastfoundexistingfile {\ctxlua{support.lastexistingfile()}}
+
+%D \macros
+%D {doprocessfile,fileline,fileprocessedtrue,dofinishfile}
+%D
+%D The next macro offers a framework for processing files on a
+%D line by line basis.
+%D
+%D \starttyping
+%D \doprocessfile \identifier {name} \action
+%D \stoptyping
+%D
+%D The first argument can for instance be \type{\scratchread}.
+%D The action must do something with \type{\fileline}, which
+%D holds the current line. One can halfway step out using
+%D \type{\dofinishfile} and ise \type{\iffileprocessed} to
+%D see if indeed some content was found.
+
+\newif\iffileprocessed
+
+\let\fileline\empty
+
+\def\doprocessfile#1#2#3%
+ {\openinputfile{#1}{#2}%
+ \ifeof#1%
+ \fileprocessedfalse
+ \closeinputfile#1%
+ \else
+ \fileprocessedtrue
+ \gdef\dofinishfile
+ {\closeinputfile#1%
+ \global\let\doprocessline\relax}%
+ \gdef\doprocessline
+ {\ifeof#1%
+ \expandafter\dofinishfile
+ \else
+ \global\read#1 to \fileline
+ #3\relax
+ \expandafter\doprocessline
+ \fi}%
+ \expandafter\doprocessline
+ \fi}
+
+%D \macros
+%D {pathplusfile,assignfullfilename,sanitizefilename}
+%D
+%D Use \type{\pathplusfile} to compose a full file name, like
+%D in:
+%D
+%D \starttyping
+%D \pathplusfile{path}{file}
+%D \stoptyping
+%D
+%D By default, this expands into {\tt \pathplusfile{path}{file}}.
+
+\def\pathplusfile#1#2{#1\f!pathseparator#2}
+
+%D This one constructs a filename from a (possible empty)
+%D path and filename.
+
+\def\assignfullfilename#1#2\to#3%
+ {\doifelsenothing{#1}
+ {\edef#3{#2}}
+ {\edef#3{#1\f!pathseparator#2}}}
\def\sanitizefilename#1\to#2{\edef#2{\ctxlua{support.thesanitizedfilename([[#1]])}}}
-\def\checkfilename #1{\ctxlua{support.checkfilename([[#1]])}}
-\def\splitfilename #1{\ctxlua{support.splitfilename([[#1]])}}
-\def\splitfiletype #1{\ctxlua{support.splitfiletype([[#1]])}}
-\def\doifparentfileelse #1{\ctxlua{support.doifparentfileelse([[#1]])}}
-\def\doiffileexistselse #1{\ctxlua{support.doiffileexistelse([[#1]])}}
-\endinput
+%D NEW:
+
+\chardef\kindoffile=0 % 0=normal 1=full path spec (or http) / set at the lua end
+
+\def\checkfilename#1{\ctxlua{support.checkfilename([[#1]])}}
+
+%D \macros
+%D {input, normalinput}
+%D
+%D Sometimes we run into troubles when \type {\input} wants to get
+%D expanded, e.g. in a \type {\write} (which happens in the metafun
+%D manual when we permit long MP lines). So, instead of fixing that,
+%D we go for a redefinition of \type {\input}. Of course it's better
+%D to use \type {\readfile} or \type {\processfile}.
+
+\unexpanded\def\input{\normalinput}
+
+\def\inputgivenfile#1{\normalinput"#1"\relax}
+
+%D \macros
+%D {readfile,ReadFile,maxreadlevel}
+%D
+%D One cannot be sure if a file exists. When no file can be
+%D found, the \type{\input} primitive gives an error message
+%D and switches to interactive mode. The macro \type{\readfile}
+%D takes care of non||existing files. This macro has two faces.
+%D
+%D \starttyping
+%D \ReadFile {filename}
+%D \readfile {filename} {before loading} {not found}
+%D \stoptyping
+%D
+%D Many \TEX\ implementations have laid out some strategy for
+%D locating files. This can lead to unexpected results,
+%D especially when one loads files that are not found in the
+%D current directory. Let's give an example of this. In
+%D \CONTEXT\ illustrations can be defined in an external file.
+%D The resizing macro first looks if an illustration is defined
+%D in the local definitions file. When no such file is found,
+%D it searches for a global file and when this file is not
+%D found either, the illustration itself is scanned for
+%D dimensions. One can imagine what happens if an adapted,
+%D localy stored illustration, is scaled according to
+%D dimensions stored somewhere else.
+%D
+%D When some \TEX\ implementation starts looking for a file, it
+%D normally first looks in the current directory. When no file
+%D is found, \TEX\ starts searching on the path where format
+%D and|/|or style files are stored. Depending on the implementation
+%D this can considerably slow down processing speed.
+%D
+%D In \CONTEXT, we support a project||wise ordening of files.
+%D In such an approach it seems feasible to store common files
+%D in a lower directory. When for instance searching for a
+%D general layout file, we therefore have to backtrack.
+%D
+%D These three considerations have lead to a more advanced
+%D approach for loading files.
+%D
+%D We first present an earlier implementation of
+%D \type{\readfile}. This command backtracks parent
+%D directories, upto a predefined level. Users can change this
+%D level, but we default to~3.
+%D
+%D \starttyping
+%D \def\maxreadlevel {3}
+%D \stoptyping
+%D
+%D This is a pseudo \COUNTER.
+%D
+%D We use \type{\normalinput} instead of \type{\input}
+%D because we want to be able to redefine the original
+%D \type{\input} when needed, for instance when loading third
+%D party libraries.
+
+\newevery \everybeforereadfile \EveryBeforeReadFile
+\newevery \everyafterreadfile \EveryAfterReadFile
+
+\let \everyreadfile \everybeforereadfile
+
+\newif\iftracefiles
+
+\newcount\readlevel
+
+\def\maxreadlevel{3}
+
+\newconditional\trackfilenames
+\let\trackedfilename\empty
+
+% We need to postpone loading, else we got frozen type-* files and so when
+% a format is generated on a source path.
+
+\def\doreadfile#1#2#3#4%
+ {\sanitizefilename#2\to\readfilename
+ \ifx\readfilename\empty
+ % silently ignore
+ \else
+ \let\trackedfilename\readfilename
+ \ifconditional\trackfilenames
+ \doifundefinedelse{fn..\trackedfilename}\donetrue\donefalse
+ \else
+ \donetrue
+ \fi
+ \ifdone
+ \checkfilename\readfilename
+ \ifcase\kindoffile
+ \iftracefiles\writestatus\m!systems{searching for \readfilename\space on #1}\fi
+ % not a full path or url, check for existence
+ \doifelsenothing{#1}
+ {\def\next{\redoreadfile\readfilename{#3}{#4}}}%
+ {\def\next{\redoreadfile{\pathplusfile{#1}{\readfilename}}{#3}{#4}}}%
+ \else
+ % a full path or url, no further checking done
+ \doiffileexistselse\readfilename
+ {\iftracefiles\writestatus\m!systems{located \readfilename}\fi
+ \def\next{#3\dodoreadfile}}%
+ {\iftracefiles\writestatus\m!systems{not found \readfilename}\fi
+ \def\next{#4}}%
+ \fi
+ \else
+ \edef\readfilename{\getvalue{fn..\readfilename}}%
+ \iftracefiles\writestatus\m!systems{already located \readfilename}\fi
+ \def\next{#3\dodoreadfile}%
+ \fi
+ \expandafter\next
+ \fi}
+
+\def\redoreadfile#1#2#3%
+ {\doiffileexistselse{#1}%
+ {\edef\readfilename{#1}%
+ \iftracefiles\writestatus\m!systems{#1 located}\fi
+ \def\next{#2\dodoreadfile}}%
+ {\iftracefiles\writestatus\m!systems{cannot locate #1}\fi
+ \advance\readlevel\minusone
+ \ifnum\readlevel>\zerocount
+ \edef\readfilename{\pathplusfile{\f!parentpath}{\readfilename}}%
+ \def\next{\redoreadfile\readfilename{#2}{#3}}%
+ \else
+ \def\next{#3}%
+ \fi}%
+ \next}
+
+\def\dodoreadfile % we provide hooks, for instance for \enableXML
+ {\ifconditional\trackfilenames
+ \setxvalue{fn..\trackedfilename}{\readfilename}%
+ \fi
+ \the\everybeforereadfile
+ \relax\inputgivenfile\readfilename\relax
+ \the\everyafterreadfile}
+
+% too less:
+%
+% \unexpanded\def\readfile% #1%
+% {\readlevel\maxreadlevel
+% \doreadfile\empty} % {#1}
+%
+% too much:
+%
+% \unexpanded\def\readfile#1#2#3%
+% {\readlocfile{#1}{#2}
+% {\readjobfile{#1}{#2}
+% {\readsysfile{#1}{#2}{#3}}}}
+%
+% just ok:
+
+\unexpanded\def\readfile#1#2#3%
+ {\readlocfile{#1}{#2}{\readsysfile{#1}{#2}{#3}}}
+
+\def\readtexfile#1#2#3%
+ {\pushcatcodetable \catcodetable \ctxcatcodes
+ \readfile{#1}{#2}{#3}%
+ \popcatcodetable}
+
+\def\readxmlfile#1#2#3%
+ {\pushcatcodetable \catcodetable \xmlcatcodes
+ \readfile{#1}{#2}{#3}%
+ \popcatcodetable}
+
+\unexpanded\def\ReadFile#1%
+ {\readfile{#1}\donothing\donothing}
+
+%D \macros
+%D {readjobfile,readlocfile,readsysfile,
+%D readfixfile,readsetfile}
+%D
+%D This implementation honnors the third situation, but we
+%D still can get unwanted files loaded and/or can get involved
+%D in extensive searching.
+%D
+%D Due to different needs, we decided to offer four alternative
+%D loading commands. With \type{\readjobfile} we load a local
+%D file and do no backtracking, while \type{\readlocfile}
+%D backtracks~\number\readlevel\ directories, including the current
+%D one.
+
+\unexpanded\def\readjobfile % #1% current path, no backtracking
+ {\readlevel\zerocount
+ \doreadfile\f!currentpath} % {#1}}
+
+\unexpanded\def\readlocfile % #1% current path, backtracking
+ {\readlevel\maxreadlevel
+ \doreadfile\f!currentpath} % {#1}}
+
+%D System files can be anywhere and therefore
+%D \type{\readsysfile} is not bound to the current directory
+%D and obeys the \TEX\ implementation.
+
+\unexpanded\def\readsysfile % #1% current path, obeys tex search
+ {\readlevel\zerocount
+ \doreadfile\empty} % {#1}}
+
+%D Of the last two, \type{\readfixfile} searches on the
+%D directory specified and backtracks too, while
+%D \type{\readsetfile} does only search on the specified path.
+
+\unexpanded\def\readfixfile % #1#2% specified path, backtracking
+ {\readlevel\maxreadlevel
+ \doreadfile} % {#1}{#2}}
+
+\unexpanded\def\readsetfile % #1#2% specified path, no backtracking
+ {\readlevel\zerocount
+ \doreadfile} % {#1}{#2}}
+
+%D After having defined this commands, we reconsidered the
+%D previously defined \type{\readfile}. This time we more or
+%D less impose the search order.
+
+\unexpanded\def\readfile#1#2#3%
+ {\readlocfile{#1}{#2}
+ {\readjobfile{#1}{#2}
+ {\readsysfile{#1}{#2}{#3}}}}
+
+%D So now we've got ourselves five file loading commands:
+%D
+%D \starttyping
+%D \readfile {filename} {before loading} {not found}
+%D
+%D \readjobfile {filename} {before loading} {not found}
+%D \readlocfile {filename} {before loading} {not found}
+%D \readfixfile {filename} {before loading} {not found}
+%D \readsysfile {directory} {filename} {before loading} {not found}
+%D \stoptyping
+
+%D \macros
+%D {readjobfile,readlocfile,readsysfile,readfixfile}
+%D
+%D The next four alternatives can be used for opening files
+%D for reading on a line||by||line basis. These commands get
+%D an extra argument, the filetag. Explicit closing is done
+%D in the normal way by \type{\closein}.
+
+\def\doopenin#1#2%
+ {\sanitizefilename#2\to\readfilename
+ \checkfilename\readfilename
+ \ifcase\kindoffile
+ \advance\readlevel\plusone
+ \openinputfile{#1}\readfilename
+ \ifeof#1% \relax
+ \ifnum\readlevel>\maxreadlevel % \relax
+ \else
+ \closeinputfile#1% \relax
+ \doopenin{#1}{\pathplusfile\f!parentpath{#2}}%
+ \fi
+ \fi
+ \fi}
+
+\def\openjobin#1#2%
+ {\readlevel\zerocount
+ \doopenin{#1}{\pathplusfile\f!currentpath{#2}}}
+
+\def\opensysin % #1#2%
+ {\readlevel\maxreadlevel
+ \doopenin} % {#1}{#2}}
+
+\def\openlocin#1#2%
+ {\readlevel\maxreadlevel
+ \doopenin{#1}{\pathplusfile\f!currentpath{#2}}}
+
+\def\openfixin#1#2#3%
+ {\readlevel\maxreadlevel
+ \doopenin{#1}{\pathplusfile{#2}{#3}}}
+
+%D \macros
+%D {doiffileelse,doiflocfileelse}
+%D
+%D The next alternative only looks if a file is present. No
+%D loading is done. This one obeys the standard \TEX\
+%D implementation method.
+%D
+%D \starttyping
+%D \doiffileelse {filename} {found} {not found}
+%D \stoptyping
+%D
+%D \starttyping
+%D \doiflocfileelse {filename} {before loading} {not found}
+%D \stoptyping
+
+\def\doiffileelse {\doiffileexistselse}
+\def\doiffile #1{\doiffileexistselse{#1}\firstofoneargument\gobbleoneargument}
+\def\doifnotfile #1{\doiffileexistselse{#1}\gobbleoneargument\firstofoneargument}
+
+\def\doiflocfileelse#1%
+ {\makelocreadfilename{#1}%
+ \doiffileelse\readfilename}
+
+\def\makelocreadfilename#1%
+ {\sanitizefilename#1\to\readfilename
+ \checkfilename\readfilename
+ \ifcase\kindoffile
+ \edef\readfilename{\pathplusfile\f!currentpath{#1}}%
+ \fi}
+
+%D \macros
+%D {doonlyonce, doinputonce, doendinputonce}
+%D
+%D Especially macropackages need only be loaded once.
+%D Repetitive loading not only costs time, relocating registers
+%D often leads to abortion of the processing because \TEX's
+%D capacity is limited. One can prevent multiple execution and
+%D loading by using one of both:
+%D
+%D \starttyping
+%D \doonlyonce{actions}
+%D \doinputonce{filename}
+%D \doendinputonce{filename}
+%D \stoptyping
+%D
+%D This command obeys the standard method for locating files.
+
+\long\def\doonlyonce#1%
+ {\doifundefinedelse{@@@#1@@@}
+ {\letgvalue{@@@#1@@@}\empty
+ \firstofoneargument}
+ {\gobbleoneargument}}
+
+\def\doinputonce#1%
+ {\doonlyonce{#1}{\doiffileelse{#1}{\inputgivenfile{#1}}\donothing}}
+
+\def\doendinputonce#1%
+ {\doifdefined{@@@#1@@@}\endinput}
+
+\def\forgetdoingonce#1%
+ {\global\letbeundefined{@@@#1@@@}}
+
+%D \macros
+%D {doifparentfileelse}
+%D
+%D The test \type{\doifelse{\jobname}{filename}} does not give
+%D the desired result, simply because \type{\jobname} expands
+%D to characters with \CATCODE~12, while the characters in
+%D \type{filename} have \CATCODE~11. So we can better use:
+%D
+%D \starttyping
+%D \doifparentfileelse{filename}{yes}{no}
+%D \stoptyping
+%D
+%D Since \TEXEXEC\ (and thereby \CONTEXT) supports renaming of
+%D the outputfile, we also need to check on that alternative
+%D name.
+
+\ifx\outputfilename\undefined \def\outputfilename{\jobname} \fi
+
+\def\doifparentfileelse#1{\ctxlua{support.doifparentfileelse([[#1]])}}
+
+\def\normalless {<} % geen \let !
+\def\normalmore {>} % geen \let !
+\def\normalequal {=} % geen \let !
+\def\normaldblquote{"} % geen \let !
+
+\newcount\readingfilelevel
+
+\def\popfilecharacter#1#2%
+ {\ifnum\catcode`#1=\@@other \ifnum#2=\@@other \else
+ %\message{[popping catcode #1 to #2]}%
+ \catcode`#1=#2\relax
+ \fi \fi}
+
+\ifx\\\undefined \let\\\relax \fi
+
+%D This changing catcodes is a direct result from the fact
+%D that we support some long standing conventions with
+%D regards to active characters (german ", polish /,
+%D french : and ;).
+
+%D We need to redo this: catcode sets and such
+
+\newtoks \everystartreadingfile
+\newtoks \everystopreadingfile
+
+\def\startreadingfile% beter een every en \setnormalcatcodes
+ {\global\advance\readingfilelevel\plusone
+ \the\everystartreadingfile
+ \beginrestorecatcodes
+ \setcatcodetable\prtcatcodes}
+
+\def\stopreadingfile
+ {\endrestorecatcodes
+ \the\everystopreadingfile
+ \global\advance\readingfilelevel\minusone}
+
+\let\normalstartreadingfile\startreadingfile
+\let\normalstopreadingfile \stopreadingfile
+
+%D \macros
+%D {splitfilename}
+%D
+%D I should have made this one sooner. This macro was first needed when
+%D ran into graphic with a period in the pathpart.
+%D
+%D \startbuffer
+%D \def\showfilesplit
+%D {\bgroup \tttf
+%D \hbox{(full: \splitofffull)}\space
+%D \hbox{(path: \splitoffpath)}\space
+%D \hbox{(base: \splitoffbase)}\space
+%D \hbox{(name: \splitoffname)}\space
+%D \hbox{(type: \splitofftype)}\space
+%D \egroup}
+%D
+%D \splitfilename{c:/aa/bb/cc/dd.ee.ff} \showfilesplit \endgraf
+%D \splitfilename{c:/aa/bb/cc/dd.ee} \showfilesplit \endgraf
+%D \splitfilename{c:/aa/bb/cc/dd} \showfilesplit \endgraf
+%D
+%D \splitfilename{dd.ee.ff} \showfilesplit \endgraf
+%D \splitfilename{dd.ee} \showfilesplit \endgraf
+%D \splitfilename{dd} \showfilesplit \endgraf
+%D \stopbuffer
+%D
+%D \start \typebuffer \getbuffer \stop
+
+\def\splitoffroot{.} \chardef\splitoffkind\zerocount
+
+\let\splitofffull\empty
+\let\splitoffpath\empty
+\let\splitoffbase\empty
+\let\splitoffname\empty
+\let\splitofftype\empty
+
+\def\splitfilename#1{\ctxlua{support.splitfilename([[#1]])}}
+\def\splitfiletype#1{\ctxlua{support.splitfiletype([[#1]])}}
+
+\protect \endinput
diff --git a/tex/context/base/supp-fil.tex b/tex/context/base/supp-fil.tex
deleted file mode 100644
index 4d31bfd28..000000000
--- a/tex/context/base/supp-fil.tex
+++ /dev/null
@@ -1,655 +0,0 @@
-%D \module
-%D [ file=supp-fil,
-%D version=1995.10.10,
-%D title=\CONTEXT\ Support Macros,
-%D subtitle=Files,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 \TEX\ operates on files, so one wouldn't wonder that there
-%D is a separate module for file support. In \CONTEXT\ files
-%D are used for several purposes:
-%D
-%D \startitemize[packed]
-%D \item general textual input
-%D \item logging status information
-%D \item saving registers, lists and references
-%D \item buffering defered textual input
-%D \stopitemize
-%D
-%D When dealing with files we can load them as a whole, using
-%D the \type{\input} primitive or load them on a line||by||line
-%D basis, using \type{\read}. Writing is always done line by
-%D line, using \type{\write}.
-
-\writestatus{loading}{Context Support Macros / Files}
-
-\unprotect
-
-\ifx\undefined\f!pathseparator
- \def\f!pathseparator{/}
- \def\f!currentpath {.}
- \def\f!parentpath {..}
-\fi
-
-%D \macros
-%D {normalwrite, normalimmediate}
-%D
-%D We save a few primitives first.
-
-\let\normalwrite \write
-\let\normalimmediate\immediate
-
-% \def\openinputfile #1#2{\immediate\openin #1="#2"\relax} \def\closeinputfile #1{\immediate\closein #1}
-% \def\openoutputfile#1#2{\immediate\openout#1="#2"\relax} \def\closeoutputfile#1{\immediate\closeout#1}
-
-\def\openinputfile #1#2{\immediate\openin #1=#2\relax} \def\closeinputfile #1{\immediate\closein #1}
-\def\openoutputfile#1#2{\immediate\openout#1=#2\relax} \def\closeoutputfile#1{\immediate\closeout#1}
-
-%D \macros
-%D {pushendofline,popendofline}
-%D
-%D When we are loading files in the middle of the typesetting
-%D process, for instance when we load references, we have to be
-%D sure that the reading process does not generate so called
-%D 'spurious spaces'. This can be prevented by assigning the
-%D line ending character the \CATCODE\ comment. This is
-%D accomplished by
-%D
-%D \starttyping
-%D \pushendofline
-%D ... reading ...
-%D \popendofline
-%D \stoptyping
-%D
-%D Just to be sure, we save the current meaning of \type{^^M}
-%D in \type{\poppedendofline}.
-
-% \chardef\poppedendofline\catcode`\^^M
-%
-% \def\pushendofline
-% {\chardef\poppedendofline\catcode`\^^M\relax
-% \catcode`\^^M\@@comment\relax}
-%
-% \def\popendofline
-% {\catcode`\^^M\poppedendofline}
-%
-% support for nested usage:
-
-\newcount \endoflinelevel
-
-\ifx\newlinecode\undefined \chardef\newlinecode=`\^^M \fi
-
-\def\pushendofline
- {\advance\endoflinelevel\plusone
- \expandafter\chardef\csname :eol:\number\endoflinelevel\endcsname\catcode\newlinecode
- \catcode\newlinecode\@@comment\relax}
-
-\def\popendofline
- {\catcode\newlinecode\csname :eol:\number\endoflinelevel\endcsname
- \advance\endoflinelevel\minusone}
-
-\def\restoreendofline
- {\catcode\newlinecode\@@endofline}
-
-%D \macros
-%D {scratchread, scratchwrite}
-%D
-%D We define a scratch file for reading. Keep in mind that
-%D the number of files is limited to~16, so use this one when
-%D possible. We also define a scratch output file.
-
-\ifx\undefined\scratchread \newread \scratchread \fi
-\ifx\undefined\scratchwrite \newwrite\scratchwrite \fi
-
-%D \macros
-%D {unlinkfile}
-%D
-%D Sometimes we want to make sure a file is deleted, so here
-%D is a macro that does the job. It's named after the \PERL\
-%D one.
-
-\def\unlinkfile#1%
- {\openoutputfile \scratchwrite{#1}%
- \closeoutputfile\scratchwrite}
-
-%D \macros
-%D {writeln}
-%D
-%D This saves a few tokens:
-
-\def\writeln#1{\write#1{}}
-
-\def\doiffileexistselse#1%
- {\doifelsenothing{#1}
- {\secondoftwoarguments}
- {\openinputfile\scratchread{#1}%
- \ifeof\scratchread
- \closeinputfile\scratchread
- \expandafter\secondoftwoarguments
- \else
- \closeinputfile\scratchread
- \expandafter\firstoftwoarguments
- \fi}}
-
-%D \macros
-%D {doprocessfile,fileline,fileprocessedtrue,dofinishfile}
-%D
-%D The next macro offers a framework for processing files on a
-%D line by line basis.
-%D
-%D \starttyping
-%D \doprocessfile \identifier {name} \action
-%D \stoptyping
-%D
-%D The first argument can for instance be \type{\scratchread}.
-%D The action must do something with \type{\fileline}, which
-%D holds the current line. One can halfway step out using
-%D \type{\dofinishfile} and ise \type{\iffileprocessed} to
-%D see if indeed some content was found.
-
-\newif\iffileprocessed
-
-\let\fileline\empty
-
-\def\doprocessfile#1#2#3%
- {\openinputfile{#1}{#2}%
- \ifeof#1%
- \fileprocessedfalse
- \closeinputfile#1%
- \else
- \fileprocessedtrue
- \gdef\dofinishfile
- {\closeinputfile#1%
- \global\let\doprocessline\relax}%
- \gdef\doprocessline
- {\ifeof#1%
- \expandafter\dofinishfile
- \else
- \global\read#1 to \fileline
- #3\relax
- \expandafter\doprocessline
- \fi}%
- \expandafter\doprocessline
- \fi}
-
-%D \macros
-%D {pathplusfile,assignfullfilename,sanitizefilename}
-%D
-%D Use \type{\pathplusfile} to compose a full file name, like
-%D in:
-%D
-%D \starttyping
-%D \pathplusfile{path}{file}
-%D \stoptyping
-%D
-%D By default, this expands into {\tt \pathplusfile{path}{file}}.
-
-\def\pathplusfile#1#2{#1\f!pathseparator#2}
-
-%D This one constructs a filename from a (possible empty)
-%D path and filename.
-
-\def\assignfullfilename#1#2\to#3%
- {\doifelsenothing{#1}
- {\edef#3{#2}}
- {\edef#3{#1\f!pathseparator#2}}}
-
-\def\sanitizefilename#1\to#2{\def#2{#1}} % overloaded in mk
-
-%D NEW:
-
-\chardef\kindoffile=0 % 0=normal 1=full path spec (or http)
-
-\def\checkfilename{\chardef\kindoffile\zerocount} % overloaded in mk
-
-%D \macros
-%D {input, normalinput}
-%D
-%D Sometimes we run into troubles when \type {\input} wants to get
-%D expanded, e.g. in a \type {\write} (which happens in the metafun
-%D manual when we permit long MP lines). So, instead of fixing that,
-%D we go for a redefinition of \type {\input}. Of course it's better
-%D to use \type {\readfile} or \type {\processfile}.
-
-\ifx\normalinput\undefined \let\normalinput\input \fi
-
-\unexpanded\def\input{\normalinput}
-
-\def\inputgivenfile#1{\normalinput"#1"\relax}
-
-%D \macros
-%D {readfile,ReadFile,maxreadlevel}
-%D
-%D One cannot be sure if a file exists. When no file can be
-%D found, the \type{\input} primitive gives an error message
-%D and switches to interactive mode. The macro \type{\readfile}
-%D takes care of non||existing files. This macro has two faces.
-%D
-%D \starttyping
-%D \ReadFile {filename}
-%D \readfile {filename} {before loading} {not found}
-%D \stoptyping
-%D
-%D Many \TEX\ implementations have laid out some strategy for
-%D locating files. This can lead to unexpected results,
-%D especially when one loads files that are not found in the
-%D current directory. Let's give an example of this. In
-%D \CONTEXT\ illustrations can be defined in an external file.
-%D The resizing macro first looks if an illustration is defined
-%D in the local definitions file. When no such file is found,
-%D it searches for a global file and when this file is not
-%D found either, the illustration itself is scanned for
-%D dimensions. One can imagine what happens if an adapted,
-%D localy stored illustration, is scaled according to
-%D dimensions stored somewhere else.
-%D
-%D When some \TEX\ implementation starts looking for a file, it
-%D normally first looks in the current directory. When no file
-%D is found, \TEX\ starts searching on the path where format
-%D and|/|or style files are stored. Depending on the implementation
-%D this can considerably slow down processing speed.
-%D
-%D In \CONTEXT, we support a project||wise ordening of files.
-%D In such an approach it seems feasible to store common files
-%D in a lower directory. When for instance searching for a
-%D general layout file, we therefore have to backtrack.
-%D
-%D These three considerations have lead to a more advanced
-%D approach for loading files.
-%D
-%D We first present an earlier implementation of
-%D \type{\readfile}. This command backtracks parent
-%D directories, upto a predefined level. Users can change this
-%D level, but we default to~3.
-%D
-%D \starttyping
-%D \def\maxreadlevel {3}
-%D \stoptyping
-%D
-%D This is a pseudo \COUNTER.
-%D
-%D We use \type{\normalinput} instead of \type{\input}
-%D because we want to be able to redefine the original
-%D \type{\input} when needed, for instance when loading third
-%D party libraries.
-
-\newevery \everybeforereadfile \EveryBeforeReadFile
-\newevery \everyafterreadfile \EveryAfterReadFile
-
-\let \everyreadfile \everybeforereadfile
-
-\newif\iftracefiles
-
-\newcount\readlevel
-
-\def\maxreadlevel{3}
-
-\newconditional\trackfilenames
-
-% We need to postpone loading, else we got frozen type-* files and so when
-% a format is generated on a source path.
-
-\appendtoks \settrue\trackfilenames \to \everyjob
-
-\let\trackedfilename\empty
-
-\def\doreadfile#1#2#3#4%
- {\sanitizefilename#2\to\readfilename
- \ifx\readfilename\empty
- % silently ignore
- \else
- \let\trackedfilename\readfilename
- \ifconditional\trackfilenames
- \doifundefinedelse{fn..\trackedfilename}\donetrue\donefalse
- \else
- \donetrue
- \fi
- \ifdone
- \checkfilename\readfilename
- \ifcase\kindoffile
- \iftracefiles\writestatus\m!systems{searching for \readfilename\space on #1}\fi
- % not a full path or url, check for existence
- \doifelsenothing{#1}
- {\def\next{\redoreadfile\readfilename{#3}{#4}}}%
- {\def\next{\redoreadfile{\pathplusfile{#1}{\readfilename}}{#3}{#4}}}%
- \else
- % a full path or url, no further checking done
- \doiffileexistselse\readfilename
- {\iftracefiles\writestatus\m!systems{located \readfilename}\fi
- \def\next{#3\dodoreadfile}}%
- {\iftracefiles\writestatus\m!systems{not found \readfilename}\fi
- \def\next{#4}}%
- \fi
- \else
- \edef\readfilename{\getvalue{fn..\readfilename}}%
- \iftracefiles\writestatus\m!systems{already located \readfilename}\fi
- \def\next{#3\dodoreadfile}%
- \fi
- \expandafter\next
- \fi}
-
-\def\redoreadfile#1#2#3%
- {\doiffileexistselse{#1}%
- {\edef\readfilename{#1}%
- \iftracefiles\writestatus\m!systems{#1 located}\fi
- \def\next{#2\dodoreadfile}}%
- {\iftracefiles\writestatus\m!systems{cannot locate #1}\fi
- \advance\readlevel\minusone
- \ifnum\readlevel>\zerocount
- \edef\readfilename{\pathplusfile{\f!parentpath}{\readfilename}}%
- \def\next{\redoreadfile\readfilename{#2}{#3}}%
- \else
- \def\next{#3}%
- \fi}%
- \next}
-
-\def\dodoreadfile % we provide hooks, for instance for \enableXML
- {\ifconditional\trackfilenames
- \setxvalue{fn..\trackedfilename}{\readfilename}%
- \fi
- \the\everybeforereadfile
-% \normalinput\readfilename\relax
- \relax\inputgivenfile\readfilename\relax
- \the\everyafterreadfile}
-
-% too less:
-%
-% \unexpanded\def\readfile% #1%
-% {\readlevel\maxreadlevel
-% \doreadfile\empty} % {#1}
-%
-% too much:
-%
-% \unexpanded\def\readfile#1#2#3%
-% {\readlocfile{#1}{#2}
-% {\readjobfile{#1}{#2}
-% {\readsysfile{#1}{#2}{#3}}}}
-%
-% just ok:
-
-\unexpanded\def\readfile#1#2#3%
- {\readlocfile{#1}{#2}{\readsysfile{#1}{#2}{#3}}}
-
-\def\readtexfile#1#2#3%
- {\pushcatcodetable \catcodetable \ctxcatcodes
- \readfile{#1}{#2}{#3}%
- \popcatcodetable}
-
-\def\readxmlfile#1#2#3%
- {\pushcatcodetable \catcodetable \xmlcatcodes
- \readfile{#1}{#2}{#3}%
- \popcatcodetable}
-
-\unexpanded\def\ReadFile#1%
- {\readfile{#1}\donothing\donothing}
-
-%D \macros
-%D {readjobfile,readlocfile,readsysfile,
-%D readfixfile,readsetfile}
-%D
-%D This implementation honnors the third situation, but we
-%D still can get unwanted files loaded and/or can get involved
-%D in extensive searching.
-%D
-%D Due to different needs, we decided to offer four alternative
-%D loading commands. With \type{\readjobfile} we load a local
-%D file and do no backtracking, while \type{\readlocfile}
-%D backtracks~\number\readlevel\ directories, including the current
-%D one.
-
-\unexpanded\def\readjobfile % #1% current path, no backtracking
- {\readlevel\zerocount
- \doreadfile\f!currentpath} % {#1}}
-
-\unexpanded\def\readlocfile % #1% current path, backtracking
- {\readlevel\maxreadlevel
- \doreadfile\f!currentpath} % {#1}}
-
-%D System files can be anywhere and therefore
-%D \type{\readsysfile} is not bound to the current directory
-%D and obeys the \TEX\ implementation.
-
-\unexpanded\def\readsysfile % #1% current path, obeys tex search
- {\readlevel\zerocount
- \doreadfile\empty} % {#1}}
-
-%D Of the last two, \type{\readfixfile} searches on the
-%D directory specified and backtracks too, while
-%D \type{\readsetfile} does only search on the specified path.
-
-\unexpanded\def\readfixfile % #1#2% specified path, backtracking
- {\readlevel\maxreadlevel
- \doreadfile} % {#1}{#2}}
-
-\unexpanded\def\readsetfile % #1#2% specified path, no backtracking
- {\readlevel\zerocount
- \doreadfile} % {#1}{#2}}
-
-%D After having defined this commands, we reconsidered the
-%D previously defined \type{\readfile}. This time we more or
-%D less impose the search order.
-
-\unexpanded\def\readfile#1#2#3%
- {\readlocfile{#1}{#2}
- {\readjobfile{#1}{#2}
- {\readsysfile{#1}{#2}{#3}}}}
-
-%D So now we've got ourselves five file loading commands:
-%D
-%D \starttyping
-%D \readfile {filename} {before loading} {not found}
-%D
-%D \readjobfile {filename} {before loading} {not found}
-%D \readlocfile {filename} {before loading} {not found}
-%D \readfixfile {filename} {before loading} {not found}
-%D \readsysfile {directory} {filename} {before loading} {not found}
-%D \stoptyping
-
-%D \macros
-%D {readjobfile,readlocfile,readsysfile,readfixfile}
-%D
-%D The next four alternatives can be used for opening files
-%D for reading on a line||by||line basis. These commands get
-%D an extra argument, the filetag. Explicit closing is done
-%D in the normal way by \type{\closein}.
-
-\def\doopenin#1#2%
- {\sanitizefilename#2\to\readfilename
- \checkfilename\readfilename
- \ifcase\kindoffile
- \advance\readlevel\plusone
- \openinputfile{#1}\readfilename
- \ifeof#1% \relax
- \ifnum\readlevel>\maxreadlevel % \relax
- \else
- \closeinputfile#1% \relax
- \doopenin{#1}{\pathplusfile\f!parentpath{#2}}%
- \fi
- \fi
- \fi}
-
-\def\openjobin#1#2%
- {\readlevel\zerocount
- \doopenin{#1}{\pathplusfile\f!currentpath{#2}}}
-
-\def\opensysin % #1#2%
- {\readlevel\maxreadlevel
- \doopenin} % {#1}{#2}}
-
-\def\openlocin#1#2%
- {\readlevel\maxreadlevel
- \doopenin{#1}{\pathplusfile\f!currentpath{#2}}}
-
-\def\openfixin#1#2#3%
- {\readlevel\maxreadlevel
- \doopenin{#1}{\pathplusfile{#2}{#3}}}
-
-%D \macros
-%D {doiffileelse,doiflocfileelse}
-%D
-%D The next alternative only looks if a file is present. No
-%D loading is done. This one obeys the standard \TEX\
-%D implementation method.
-%D
-%D \starttyping
-%D \doiffileelse {filename} {found} {not found}
-%D \stoptyping
-%D
-%D \starttyping
-%D \doiflocfileelse {filename} {before loading} {not found}
-%D \stoptyping
-
-\def\doiffileelse {\doiffileexistselse}
-\def\doiffile #1{\doiffileexistselse{#1}\firstofoneargument\gobbleoneargument}
-\def\doifnotfile #1{\doiffileexistselse{#1}\gobbleoneargument\firstofoneargument}
-
-\def\doiflocfileelse#1%
- {\makelocreadfilename{#1}%
- \doiffileelse\readfilename}
-
-\def\makelocreadfilename#1%
- {\sanitizefilename#1\to\readfilename
- \checkfilename\readfilename
- \ifcase\kindoffile
- \edef\readfilename{\pathplusfile\f!currentpath{#1}}%
- \fi}
-
-%D \macros
-%D {doonlyonce, doinputonce, doendinputonce}
-%D
-%D Especially macropackages need only be loaded once.
-%D Repetitive loading not only costs time, relocating registers
-%D often leads to abortion of the processing because \TEX's
-%D capacity is limited. One can prevent multiple execution and
-%D loading by using one of both:
-%D
-%D \starttyping
-%D \doonlyonce{actions}
-%D \doinputonce{filename}
-%D \doendinputonce{filename}
-%D \stoptyping
-%D
-%D This command obeys the standard method for locating files.
-
-\long\def\doonlyonce#1%
- {\doifundefinedelse{@@@#1@@@}
- {\letgvalue{@@@#1@@@}\empty
- \firstofoneargument}
- {\gobbleoneargument}}
-
-\def\doinputonce#1%
-% {\doonlyonce{#1}{\doiffileelse{#1}{\normalinput#1\relax}\donothing}}
- {\doonlyonce{#1}{\doiffileelse{#1}{\inputgivenfile{#1}}\donothing}}
-
-\def\doendinputonce#1%
- {\doifdefined{@@@#1@@@}\endinput}
-
-\def\forgetdoingonce#1%
- {\global\letbeundefined{@@@#1@@@}}
-
-%D \macros
-%D {doifparentfileelse}
-%D
-%D The test \type{\doifelse{\jobname}{filename}} does not give
-%D the desired result, simply because \type{\jobname} expands
-%D to characters with \CATCODE~12, while the characters in
-%D \type{filename} have \CATCODE~11. So we can better use:
-%D
-%D \starttyping
-%D \doifparentfileelse{filename}{yes}{no}
-%D \stoptyping
-%D
-%D Since \TEXEXEC\ (and thereby \CONTEXT) supports renaming of
-%D the outputfile, we also need to check on that alternative
-%D name.
-
-\ifx\outputfilename\undefined \def\outputfilename{\jobname} \fi
-
-\let\doifparentfileelse\gobblethreearguments % defined in mk
-
-\def\normalless {<} % geen \let !
-\def\normalmore {>} % geen \let !
-\def\normalequal {=} % geen \let !
-\def\normaldblquote{"} % geen \let !
-
-\newcount\readingfilelevel
-
-\def\popfilecharacter#1#2%
- {\ifnum\catcode`#1=\@@other \ifnum#2=\@@other \else
- %\message{[popping catcode #1 to #2]}%
- \catcode`#1=#2\relax
- \fi \fi}
-
-\ifx\\\undefined \let\\\relax \fi
-
-%D This changing catcodes is a direct result from the fact
-%D that we support some long standing conventions with
-%D regards to active characters (german ", polish /,
-%D french : and ;).
-
-%D We need to redo this: catcode sets and such
-
-\newtoks \everystartreadingfile
-\newtoks \everystopreadingfile
-
-\def\startreadingfile% beter een every en \setnormalcatcodes
- {\global\advance\readingfilelevel\plusone
- \the\everystartreadingfile
- \beginrestorecatcodes
- \setcatcodetable\prtcatcodes}
-
-\def\stopreadingfile
- {\endrestorecatcodes
- \the\everystopreadingfile
- \global\advance\readingfilelevel\minusone}
-
-\let\normalstartreadingfile\startreadingfile
-\let\normalstopreadingfile \stopreadingfile
-
-%D \macros
-%D {splitfilename}
-%D
-%D I should have made this one sooner. This macro was first needed when
-%D ran into graphic with a period in the pathpart.
-%D
-%D \startbuffer
-%D \def\showfilesplit
-%D {\bgroup \tttf
-%D \hbox{(full: \splitofffull)}\space
-%D \hbox{(path: \splitoffpath)}\space
-%D \hbox{(base: \splitoffbase)}\space
-%D \hbox{(name: \splitoffname)}\space
-%D \hbox{(type: \splitofftype)}\space
-%D \egroup}
-%D
-%D \splitfilename{c:/aa/bb/cc/dd.ee.ff} \showfilesplit \endgraf
-%D \splitfilename{c:/aa/bb/cc/dd.ee} \showfilesplit \endgraf
-%D \splitfilename{c:/aa/bb/cc/dd} \showfilesplit \endgraf
-%D
-%D \splitfilename{dd.ee.ff} \showfilesplit \endgraf
-%D \splitfilename{dd.ee} \showfilesplit \endgraf
-%D \splitfilename{dd} \showfilesplit \endgraf
-%D \stopbuffer
-%D
-%D \start \typebuffer \getbuffer \stop
-
-\def\splitoffroot{.} \chardef\splitoffkind\zerocount
-
-\let\splitofffull\empty
-\let\splitoffpath\empty
-\let\splitoffbase\empty
-\let\splitoffname\empty
-\let\splitofftype\empty
-
-\let\splitfilename\gobbleoneargument % defined in mk
-\let\splitfiletype\gobbleoneargument % defined in mk
-
-\loadmarkfile{supp-fil}
-
-\protect \endinput
diff --git a/tex/context/base/supp-fun.tex b/tex/context/base/supp-fun.tex
index fdeb5bbe8..6b2643703 100644
--- a/tex/context/base/supp-fun.tex
+++ b/tex/context/base/supp-fun.tex
@@ -22,7 +22,7 @@
\ifx \undefined \writestatus \input supp-mis.tex \relax \fi
-\writestatus{loading}{Context Support Macros / Fun Stuff}
+\writestatus{loading}{ConTeXt Support Macros / Fun Stuff}
\ifx\definefont\undefined
\def\definedfont[#1]{\font\temp#1\relax\temp}
@@ -346,8 +346,8 @@
\forgetall
\bgroup
#1%
- \setbox0\box\voidb@x
- \setbox2\box\voidb@x
+ \setbox0\emptybox
+ \setbox2\emptybox
\def\grabfirstline##1 %
{\setbox2\hbox
{\ifvoid0
@@ -356,8 +356,8 @@
\unhcopy0\ {#4{##1}}%
\fi}%
\ifdim\wd2=\zeropoint
- \setbox0\box\voidb@x
- \setbox2\box\voidb@x
+ \setbox0\emptybox
+ \setbox2\emptybox
\@EA\grabfirstline
\else\ifdim\wd2>\hsize
\hbox to \hsize{\strut\unhbox0}#2\egroup
diff --git a/tex/context/base/supp-ini.tex b/tex/context/base/supp-ini.tex
deleted file mode 100644
index afa8b12d9..000000000
--- a/tex/context/base/supp-ini.tex
+++ /dev/null
@@ -1,18 +0,0 @@
-%D \module
-%D [ file=supp-ini,
-%D version=1995.10.10,
-%D title=\CONTEXT\ Support ystem Macros,
-%D subtitle=Initializations,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Support Macros / Initializations}
-
-\unprotect
-
-\protect \endinput
diff --git a/tex/context/base/supp-lan.tex b/tex/context/base/supp-lan.tex
index 87bf4c3fb..8d781546f 100644
--- a/tex/context/base/supp-lan.tex
+++ b/tex/context/base/supp-lan.tex
@@ -31,7 +31,7 @@
\unprotect
-\writestatus{loading}{Context Support Macros / Language Options}
+\writestatus{loading}{ConTeXt Support Macros / Language Options}
%D \CONTEXT\ originates in the wish to typeset educational
%D materials, especially in a technical environment. In
@@ -872,7 +872,7 @@
\ifx\hspaceamount\undefined
- \def\hspaceamount#1#2{\kern.16667em}
+ \def\hspaceamount#1#2{16667em}
\fi
diff --git a/tex/context/base/supp-mat.tex b/tex/context/base/supp-mat.tex
index 3215a132b..1a51164e6 100644
--- a/tex/context/base/supp-mat.tex
+++ b/tex/context/base/supp-mat.tex
@@ -15,7 +15,7 @@
%D a support module. There is nothing spectacular here. It may move
%D back to math-ini.
-\writestatus{loading}{Context Support Macros / Math}
+\writestatus{loading}{ConTeXt Support Macros / Math}
\unprotect
@@ -195,6 +195,13 @@
%D \TEX provides no primitive to force in cramped math mode. Here is
%D a macro that does so. It is based on a solution by Don Knuth (\useurl
%D {http://www.ctan.org/tex-archive/digests/tex-implementors/042}).
+%D
+%D \startbuffer
+%D \ruledhbox{$\left\{{x^2\over y^2}\right\}$}
+%D \ruledhbox{$\cramped{\left\{ {x^2\over y^2}\right\}}$}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
\def\cramped
{\mathpalette\docramped}
@@ -209,7 +216,7 @@
% \def\docramped#1#2%
% {\setbox\scratchbox\hbox
% {\nulldelimiterspace\zeropoint
-% $\m@th#1\radical\zerocount{#2}$}%
+% $\mathsurround\zeropoint#1\radical\zerocount{#2}$}%
% \ifx#1\displaystyle
% \scratchdimen\fontdimen8\textfont3
% \advance\scratchdimen .25\fontdimen5\textfont2
@@ -229,7 +236,7 @@
{\begingroup % added HH, made even more cramped
\setbox\scratchbox\hbox
{\nulldelimiterspace\zeropoint
- $\m@th#1\radical\zerocount{#2}$}%
+ $\mathsurround\zeropoint#1\radical\zerocount{#2}$}%
\ht\scratchbox-\dimexpr
\ifx#1\displaystyle
\fontdimen8\textfont3
diff --git a/tex/context/base/supp-mis.tex b/tex/context/base/supp-mis.tex
index 57661e591..5b45d8b9d 100644
--- a/tex/context/base/supp-mis.tex
+++ b/tex/context/base/supp-mis.tex
@@ -80,7 +80,6 @@
%D Outside \CONTEXT\ we will not be \ETEX||aware.
\long\def\beginETEX #1\endETEX {}
-\long\def\beginOMEGA#1\endOMEGA{}
\let\beginTEX\relax \let\endTEX\relax
@@ -99,7 +98,7 @@
%D Let's see if it works.
-\writestatus{loading}{Context Support Macros / Miscellaneous (2004.10.26)}
+\writestatus{loading}{ConTeXt Support Macros / Miscellaneous (2004.10.26)}
%D \macros
%D {protect,unprotect}
diff --git a/tex/context/base/supp-mpe.tex b/tex/context/base/supp-mpe.tex
index 35a940edc..67b27919c 100644
--- a/tex/context/base/supp-mpe.tex
+++ b/tex/context/base/supp-mpe.tex
@@ -41,7 +41,7 @@
\ifx\writestatus\undefined
\immediate\write16{[Loading MPS to PDF extensions.]}
\else
- \writestatus{loading}{Context Support Macros / MPS extensions}
+ \writestatus{loading}{ConTeXt Support Macros / MPS extensions}
\fi
%D We implement extensions by using the \METAPOST\ special
diff --git a/tex/context/base/supp-mps.tex b/tex/context/base/supp-mps.tex
index 83deb4678..9864cd9a1 100644
--- a/tex/context/base/supp-mps.tex
+++ b/tex/context/base/supp-mps.tex
@@ -11,6 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+%D Forget about generic modules \unknown\ ...
+
+\ifx \undefined \contextversion \endinput \fi
+
%D \METAPOST\ is John Hobbys alternative for \METAFONT\ and
%D produces superior \POSTSCRIPT\ code. In this module we
%D integrate \METAPOST\ support int \CONTEXT. We offer two
@@ -36,11 +40,7 @@
%D
%D Ok then, let's start:
-\ifx \undefined \writestatus \input supp-mis.tex \relax \fi
-\ifx \undefined \letterhash \else \input supp-ini.tex \relax \fi
-\ifx \undefined \startMPgraphic \else \expandafter \endinput \fi
-
-\writestatus{loading}{Context Support Macros / MetaPost Inclusion}
+\writestatus{loading}{ConTeXt Support Macros / MetaPost Inclusion}
\unprotect
@@ -514,7 +514,7 @@
\newtoks\MPTEXgraphicchecks
\long\def\writecheckedMPgraphic#1%
- {\ifgrTEXgraphic
+ {\ifforceMPTEXgraphic
\global\MPTEXgraphictrue
\else
\global\MPTEXgraphicfalse
@@ -861,7 +861,9 @@
%D \stoptyping
\def\translateMPinput#1%
- {\xdef\MPinputtranslation{\letterpercent -translate-file=#1\space}}
+% {\xdef\MPinputtranslation{\letterpercent -translate-file=#1\space}} % at some point
+% {\xdef\MPinputtranslation{\letterpercent --8bit}} % some time later
+ {\globallet\MPinputtranslation\empty} % the new mpost is 8 bit clean
%D \macros
%D {setMPrandomseed}
@@ -2123,9 +2125,9 @@
%D away once the version supporting \type {--8bit} is
%D widespread.
-\beginXETEX
- \let\obeyMPlines\relax
- \longMPlinesfalse % alas
-\endXETEX
+\ifnum\texengine=\xetexengine
+ \let\obeyMPlines\relax
+ \longMPlinesfalse % alas
+\fi
\protect \endinput
diff --git a/tex/context/base/supp-mrk.tex b/tex/context/base/supp-mrk.tex
index eb03b5251..eb1865471 100644
--- a/tex/context/base/supp-mrk.tex
+++ b/tex/context/base/supp-mrk.tex
@@ -31,25 +31,7 @@
%D direct calls. The \TEX\ based multiple marks needs to store
%D the mark data but \ETEX\ uses a different approach.
-\writestatus{loading}{Context Support Macros / Marks}
-
-\let\normalmark = \mark
-\let\normaltopmark = \topmark
-\let\normalbotmark = \botmark
-\let\normalfirstmark = \firstmark
-\let\normalsplitbotmark = \splitbotmark
-\let\normalsplitfirstmark = \splitfirstmark
-
-\beginETEX \marks cum suis
-
-\let\normalmarks = \marks
-\let\normaltopmarks = \topmarks
-\let\normalbotmarks = \botmarks
-\let\normalfirstmarks = \firstmarks
-\let\normalsplitbotmarks = \splitbotmarks
-\let\normalsplitfirstmarks = \splitfirstmarks
-
-\endETEX
+\writestatus{loading}{ConTeXt Support Macros / Marks}
\unprotect
@@ -290,13 +272,6 @@
%D found, this macro is reassigned and from then on serves
%D in building the new list.
-% Although the next couple of macros are already defined
-% in syst-gen.tex, we repeat them here.
-
-\let\normalfi \fi % replaces \@fi
-\let\normalelse \else % replaces \@else
-\let\normalor \or % replaces \@or
-
% Hm, resetting \!!toksa got lost and took me a half a day to
% trace down ([] showed up in the pagebody); I really have
% to clean up this messy module (write it from scratch).
diff --git a/tex/context/base/supp-num.tex b/tex/context/base/supp-num.tex
index eb2cf49ea..130fd3938 100644
--- a/tex/context/base/supp-num.tex
+++ b/tex/context/base/supp-num.tex
@@ -2,7 +2,7 @@
%D [ file=supp-num,
%D version=1998.05.15,
%D title=\CONTEXT\ Support Macros,
-%D subtitle=Number (Digit) Handling,
+%D subtitle=Numbers,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Support Macros / Number (Digit) Handling}
+\writestatus{loading}{ConTeXt Support Macros / Numbers}
\unprotect
@@ -96,14 +96,12 @@
\ifx\mbox\undefined \let\mbox\normalhbox \fi
% \unexpanded\def\digits
-% {\bgroup\let~@\doifnextcharelse\bgroup\dodigits\grabdigit}
+% {\bgroup\let~@\doifnextbgroupelse\dodigits\grabdigit}
\unexpanded\def\digits
{\bgroup
\let~@%
- \doifnextcharelse\bgroup
- \dodigits
- {\doifnextcharelse\normalmathshift\domathdigits\grabdigit}}
+ \doifnextbgroupelse\dodigits{\doifnextcharelse\normalmathshift\domathdigits\grabdigit}}
\def\dodigits#1%
{\grabdigit#1\relax}
@@ -197,10 +195,23 @@
%D Although we could do with one pass, a second pass for
%D handling the stored sequence is more readable.
-\def\dohandledigits
- {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded
- \expandafter\handletokens\collecteddigits\with\scandigits
- \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+\startmode[mkiv]
+
+ \def\dohandledigits
+ {\mathcode`\,="003B \mathcode`\.="003A % pretty hard coded
+ \expandafter\handletokens\collecteddigits\with\scandigits
+ \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+
+\stopmode
+
+\startnotmode[mkiv]
+
+ \def\dohandledigits
+ {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded
+ \expandafter\handletokens\collecteddigits\with\scandigits
+ \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+
+\stopnotmode
\def\doscandigit#1%
{\ifcase\skipdigit\@EA\hbox\else\@EA\hphantom\fi\bgroup
diff --git a/tex/context/base/supp-pat.tex b/tex/context/base/supp-pat.tex
index 6c11c1d92..d91083076 100644
--- a/tex/context/base/supp-pat.tex
+++ b/tex/context/base/supp-pat.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=supp-pat,
%D version=2005.02.12,
-%D title=\CONTEXT\ Language Macros,
-%D subtitle=Loading (Generic) Patterns,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Patterns,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -32,7 +32,7 @@
\ifx\writestatus\undefined \else
- \writestatus{loading}{Context Language Macros / Loading Generic Patterns}
+ \writestatus{loading}{ConTeXt Support Macros / Patterns}
\fi
diff --git a/tex/context/base/supp-pdf.tex b/tex/context/base/supp-pdf.tex
index 95730939d..c54b0c6bc 100644
--- a/tex/context/base/supp-pdf.tex
+++ b/tex/context/base/supp-pdf.tex
@@ -14,7 +14,7 @@
\ifx\writestatus\undefined
\immediate\write16{[Loading MPS to PDF converter (version 2006.09.02).]}
\else
- \writestatus{loading}{Context Support Macros / PDF}
+ \writestatus{loading}{ConTeXt Support Macros / PDF}
\fi
%D This module is not optimized because it is used outside
diff --git a/tex/context/base/supp-ran.lua b/tex/context/base/supp-ran.lua
new file mode 100644
index 000000000..9e4330f57
--- /dev/null
+++ b/tex/context/base/supp-ran.lua
@@ -0,0 +1,46 @@
+if not modules then modules = { } end modules ['supp-ran'] = {
+ version = 1.001,
+ comment = "companion to supp-ran.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- We cannot ask for the current seed, so we need some messy hack
+-- here.
+
+commands = commands or { }
+
+local texwrite, random, seed, last = tex.write, math.random, false, 1
+
+function commands.getrandomcounta(min,max)
+ last = random(min,max)
+ texwrite(last)
+end
+
+function commands.getrandomcountb(min,max)
+ last = random(min,max)/65536
+ texwrite(last)
+end
+
+function commands.setrandomseed(n)
+ last = n
+ math.randomseed(n)
+end
+
+function commands.getrandomseed(n)
+ texwrite(last)
+end
+
+function commands.freezerandomseed()
+ if seed == false then
+ seed = last
+ end
+end
+
+function commands.defrostrandomseed()
+ if seed ~= false then
+ math.randomseed(last)
+ seed = false
+ end
+end
diff --git a/tex/context/base/supp-ran.tex b/tex/context/base/supp-ran.mkii
index 8c76ab443..d595fffaf 100644
--- a/tex/context/base/supp-ran.tex
+++ b/tex/context/base/supp-ran.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Third Party Macros / Random Number Generation}
+\writestatus{loading}{ConTeXt Support Macros / Random Number Generation}
%D \macros
%D {getrandomcount, getrandomdimen,
@@ -46,72 +46,36 @@
%D \getrandomseed\randomseed
%D \stoptyping
-\ifx\nextrandom\undefined
+\input thrd-ran.tex
- \readfile{random.tex}
- {\writestatus{loading}{Donald Arseneau's 'random.tex' (found)}}
- {\writestatus{loading}{Donald Arseneau's 'random.tex' (not found)}}
+\ifx\uniformdeviate\undefined
-\fi
-
-\ifx\nextrandom\undefined
-
- \writestatus{loading}{using fake randomizer}
-
- \newcount\randomi
-
- \def\setrandim#1#2#3{\scratchdimen #2\relax#1\scratchdimen }
- \def\setrannum#1#2#3{\scratchcounter#2\relax#1\scratchcounter}
-
- \let\nextrandom\relax
-
-\fi
+ \let\verynormalnextrandom\nextrandom
-\ifx\nextrandom\undefined \endinput \fi
-
-\ifx\normaluniformdeviate\undefined
-
- \let\verynormalnextrandom\nextrandom
-
- \def\normalnextrandom
- {\bgroup
- \let\time \normaltime
- \let\day \normalday
- \let\month\normalmonth
- \let\year \normalyear
- \verynormalnextrandom
- \egroup}
+ \def\normalnextrandom
+ {\bgroup
+ \let\time \normaltime
+ \let\day \normalday
+ \let\month\normalmonth
+ \let\year \normalyear
+ \verynormalnextrandom
+ \egroup}
\else
- % Yet untested.
-
- \writestatus{loading}{using tex's built in randomizer (overloading macro)}
+ \writestatus{loading}{using TeX's built in randomizer (overloading macro)}
- % For the meaning of the magic number, see \type {thrd-ran.tex}.
-
- % \def\normalnextrandom
- % {\setrandomseed\randomi
- % \global\randomi\normaluniformdeviate2147483647\relax}
-
- % Taco suggested to use the following alternative because \type
- % {\normaluniformdeviate} can return a zero (as expected) while
- % Donalds's alternative has a minimum of~1.
-
- \beginTEX
- \def\nextrandom
- {\normalsetrandomseed\randomi
- \global\randomi\normaluniformdeviate2147483646%
- \global\advance\randomi\plusone}
- \endTEX
+ % For the meaning of the magic number, see \type {thrd-ran.tex}.
+ %
+ % Taco suggested to use the following alternative because \type
+ % {\uniformdeviate} can return a zero (as expected) while
+ % Donalds Arseneau's alternative has a minimum of~1.
- \beginETEX \numexpr
\def\nextrandom
- {\normalsetrandomseed\randomi
+ {\normalsetrandomseed\randomi\relax
\global\randomi\numexpr\normaluniformdeviate2147483646+1\relax}
- \endETEX
- \let\normalnextrandom\nextrandom
+ \let\normalnextrandom\nextrandom
\fi
diff --git a/tex/context/base/supp-ran.mkiv b/tex/context/base/supp-ran.mkiv
new file mode 100644
index 000000000..9d429598f
--- /dev/null
+++ b/tex/context/base/supp-ran.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=supp-ran,
+%D version=2008-10-31,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Random Number Generation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Support Macros / Random Number Generation}
+
+%D This module is downward compatible in the sense that we've kept
+%D the user interface (which uses intermediate variables).
+
+\registerctxluafile{supp-ran}{1.001}
+
+\def\getrandomcount #1#2#3{#1=\ctxlua{commands.getrandomcounta(\number#2,\number#3)}}
+\def\getrandomdimen #1#2#3{#1=\ctxlua{commands.getrandomcounta(\number\dimexpr#2,\number\dimexpr#3)}\scaledpoint}
+\def\getrandomnumber#1#2#3{\edef#1{\ctxlua{commands.getrandomcounta(\number#2,\number#3)}}}
+\def\getrandomfloat #1#2#3{\edef#1{\ctxlua{commands.getrandomcountb(\number\dimexpr#2\points,\number\dimexpr#3\points)}}}
+\def\setrandomseed #1{\ctxlua{commands.setrandomseed(\number#1)}}
+\def\getrandomseed {\ctxlua{commands.getrandomseed()}}
+\def\freezerandomseed {\ctxlua{commands.freezerandomseed()}}
+\def\defrostrandomseed {\ctxlua{commands.defrostrandomseed()}}
+
+\endinput
diff --git a/tex/context/base/supp-spe.tex b/tex/context/base/supp-spe.tex
index d84859b59..8cb8e2ac1 100644
--- a/tex/context/base/supp-spe.tex
+++ b/tex/context/base/supp-spe.tex
@@ -8,60 +8,60 @@
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
-%D This module implements some \type{\special} manipulation
-%D macros. I needed these when I implemented the code that
-%D handles the conversion of \TPIC\ specials to \PDF\ code.
+%D This module implements some \type{\special} manipulation
+%D macros. I needed these when I implemented the code that
+%D handles the conversion of \TPIC\ specials to \PDF\ code.
\ifx \undefined \writestatus \input supp-mis.tex \relax \fi
\ifx \undefined \redefinespecial \else \expandafter \endinput \fi
-\writestatus{loading}{Context Support Macros / Specials}
+\writestatus{loading}{ConTeXt Support Macros / Specials}
\unprotect
%D When interpreting specials we need to do some basic scanning.
-%D For the moment we distinguish between three cases. We need
-%D
+%D For the moment we distinguish between three cases. We need
+%D
%D \starttyping
%D \special{tag: arguments}
%D \special{tag arguments}
%D \special{tag}
%D \stoptyping
-%D
-%D We cannot be sure that the first case isn't
-%D
+%D
+%D We cannot be sure that the first case isn't
+%D
%D \starttyping
%D \special{tag:arguments}
%D \stoptyping
-%D
-%D So we have to take care of that one too.
+%D
+%D So we have to take care of that one too.
%D \macros
%D {redefinespecial}
-%D
-%D Specials that are to be interpreted are defined with
+%D
+%D Specials that are to be interpreted are defined with
%D commands like:
-%D
+%D
%D \startbuffer[tmp-1]
%D \redefinespecial a: \using#1\endspecial%
%D {let's execute special 'a:' using '#1'}
-%D
+%D
%D \redefinespecial a \using#1\endspecial%
%D {let's execute special 'a' using '#1'}
-%D
+%D
%D \redefinespecial a \using#1\endspecial%
%D {let's execute special 'a' using nothing}
%D \stopbuffer
%D
%D \typebuffer[tmp-1]
-%D
-%D The first two always take an argument, the last one not.
-%D The definition of this redefinition macro is not that
-%D complex. The names are internally tagged with \type{\@rds@}
-%D which saves both time and space.
+%D
+%D The first two always take an argument, the last one not.
+%D The definition of this redefinition macro is not that
+%D complex. The names are internally tagged with \type{\@rds@}
+%D which saves both time and space.
\def\@rds@{@rds@}
@@ -70,14 +70,14 @@
%D \macros
%D {mimmickspecials}
%D
-%D Mimmicking specials is activated by saying:
+%D Mimmicking specials is activated by saying:
%D
%D \starttyping
%D \mimmickspecials
%D \stoptyping
%D
-%D This commands redefines the \PLAIN\ \TEX\ primitive
-%D \type{\special}.
+%D This commands redefines the \PLAIN\ \TEX\ primitive
+%D \type{\special}.
\def\mimmickspecials
{\let\special\domimmickspecial}
@@ -85,7 +85,7 @@
%D The special mimmicking macro first looks if it can find an
%D colon terminated tag, next it searches for a tag that end
%D with a space. If both cannot find, the tag itself is treated
-%D without argument.
+%D without argument.
\def\domimmickspecial#1%
{\domimmickcolonspecial#1:\relax/:\relax/\end}
@@ -107,25 +107,25 @@
\def\dodomimmickspecial#1\using#2\endspecial
{\expandafter\ifx\csname\@rds@#1\endcsname\relax % \doifdefinedelse
\defaultspecial{#1 #2}%
- \else
- %\message{[mimmick special #1 with #2]}%
+ \else
+ %\message{[mimmick special #1 with #2]}%
\getvalue{\@rds@#1}\using#2\endspecial
\fi}
-%D Now let's show that things work the way we want, using the
+%D Now let's show that things work the way we want, using the
%D previous definitions of tag~a.
-%D
+%D
%D \startbuffer[tmp-2]
%D \mimmickspecials
%D \special{a: 1 2 3 4 5}
%D \special{a: 1 2 3 4 5}
%D \special{a}
%D \stopbuffer
-%D
+%D
%D \typebuffer[tmp-2]
-%D
+%D
%D Which results in:
-%D
+%D
%D \startlines
%D \getbuffer[tmp-1]
%D \getbuffer[tmp-2]
@@ -133,11 +133,11 @@
%D \macros
%D {mimmickspecial}
-%D
-%D When needed, one can call a mimmicked special directly by
-%D saying for instance:
-%D
-%D \starttyping
+%D
+%D When needed, one can call a mimmicked special directly by
+%D saying for instance:
+%D
+%D \starttyping
%D \mimmickspecial a: \using...\endspecial
%D \stoptyping
%D
@@ -147,18 +147,18 @@
%D \macros
%D {normalspecial,defaultspecial}
-%D
-%D Unknown specials are passed to the default special handler.
+%D
+%D Unknown specials are passed to the default special handler.
%D One can for instance ignore all further specials by saying
%D \type{\normalspecial}:
-%D
+%D
%D \starttyping
%D \def\defaultspecial#1{}
%D \stoptyping
-%D
-%D But here we default to idle.
+%D
+%D But here we default to idle.
-\let\normalspecial =\special
-\let\defaultspecial=\special
+\let\normalspecial \special
+\let\defaultspecial\special
-\protect \endinput
+\protect \endinput
diff --git a/tex/context/base/supp-tpi.tex b/tex/context/base/supp-tpi.tex
index e4bc5cc72..ac38ea392 100644
--- a/tex/context/base/supp-tpi.tex
+++ b/tex/context/base/supp-tpi.tex
@@ -19,14 +19,16 @@
%D \type{supp-spe} as well as the \METAPOST\ run||time support
%D implemented in \type{supp-mps}.
-\beginLUATEX \endinput \endLUATEX % to be sure, we don't want to load the following
+\ifnum\texengine=\luatexengine
+ \endinput
+\fi
\ifx\undefined\writestatus \input supp-mis \relax \fi
\ifx\undefined\mimmickspecials \input supp-spe \relax \fi
\ifx\undefined\MPgraphicbox \input supp-mps \relax \fi
\ifx\undefined\dogetEPSboundingbox \input supp-eps \relax \fi
-\writestatus{loading}{Context Support Macros / TPIC Conversion}
+\writestatus{loading}{ConTeXt Support Macros / TPIC Conversion}
%D Beware: we haven't activated both mechanism yet. This is
%D to be done in the calling module.
diff --git a/tex/context/base/supp-vis.tex b/tex/context/base/supp-vis.tex
index 1c3daf1e1..82ada9202 100644
--- a/tex/context/base/supp-vis.tex
+++ b/tex/context/base/supp-vis.tex
@@ -11,18 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\ifx\contextversion\undefined
-
- \let \normalunexpanded \unexpanded
- \let \unexpanded \protected
-
-\fi
-
-\ifx\unexpanded\undefined
-
- \let\unexpanded\relax
-
-\fi
+% no longer generic, who cares ...
%D \gdef\ShowBufferedExample% private typeseting macro
%D {\startlinecorrection
@@ -91,7 +80,7 @@
%D That's why we've implemented a mechanism that shows some of
%D the inner secrets of \TEX.
-\writestatus{loading}{Context Support Macros / Visualization}
+\writestatus{loading}{ConTeXt Support Macros / Visualization}
%D In this module we are going to redefine some \TEX\
%D primitives and \PLAIN\ macro's. Their original meaning is
@@ -159,10 +148,7 @@
%D baseline behavior. Especially \type{\vtop}'s need our
%D special attention.
-\ifx \normalhbox \undefined \let \normalhbox = \hbox \fi
-\ifx \normalvbox \undefined \let \normalvbox = \vbox \fi
-\ifx \normalvtop \undefined \let \normalvtop = \vtop \fi
-\ifx \normalvcenter \undefined \let \normalvcenter = \vcenter \fi
+% already saved
%D \macros
%D {normalhskip,
@@ -171,8 +157,7 @@
%D Next come the flexible skips, which come in two flavors
%D too. Like boxes these are handled with \TEX\ primitives.
-\let\normalhskip = \hskip
-\let\normalvskip = \vskip
+% already saved
%D \macros
%D {normalpenalty,
@@ -182,8 +167,7 @@
%D primitives. This means that when making them visible, we
%D have to take the current mode into account.
-\let\normalpenalty = \penalty
-\let\normalkern = \kern
+% already saved
%D \macros
%D {normalhglue,
@@ -193,8 +177,8 @@
%D As we will see, their definitions make the implementation of
%D their visible counterparts a bit more \TeX{}nical.
-\let\normalhglue = \hglue
-\let\normalvglue = \vglue
+\let\normalhglue = \hglue
+\let\normalvglue = \vglue
%D \macros
%D {normalmkern,
@@ -206,8 +190,7 @@
%D with other dimensions. As a result, the visual appearance
%D of these primitives is kept primitive too.
-\let\normalmkern = \mkern
-\let\normalmskip = \mskip
+% already saved
%D \macros
%D {hfilneg,
@@ -231,12 +214,7 @@
%D The positive stretch primitives are used independant and in
%D combination with \type{\leaders}.
-\let\normalhss = \hss
-\let\normalhfil = \hfil
-\let\normalhfill = \hfill
-\let\normalvss = \vss
-\let\normalvfil = \vfil
-\let\normalvfill = \vfill
+% already saved
%D \macros
%D {normalhfilneg,normalhfillneg,
@@ -247,9 +225,7 @@
%D in standard \TEX\ documentation. They can nevertheless be
%D used at will.
-\let\normalhfilneg = \hfilneg
\let\normalhfillneg = \hfillneg
-\let\normalvfilneg = \vfilneg
\let\normalvfillneg = \vfillneg
%D Visualization is not always wanted. Instead of turning this
@@ -1927,10 +1903,4 @@
%D lines in this two column index don't allign, then this is
%D due to some still unknown interference.
-\ifx\contextversion\undefined
-
- \let \unexpanded \normalunexpanded
-
-\fi
-
\endinput
diff --git a/tex/context/base/symb-ini.tex b/tex/context/base/symb-ini.tex
index 3cf50e411..291e22790 100644
--- a/tex/context/base/symb-ini.tex
+++ b/tex/context/base/symb-ini.tex
@@ -15,50 +15,10 @@
%D {core-con} module. I decided to move them here when
%D symbolsets saw the light. Let their light shine.
-\writestatus{loading}{Context Symbol Libraries / Initialization}
+\writestatus{loading}{ConTeXt Symbol Libraries / Initialization}
\unprotect
-\startmessages dutch library: symbols
- title: symbolen
- 1: symboolset -- wordt geladen
-\stopmessages
-
-\startmessages english library: symbols
- title: symbols
- 1: loading symbolset --
-\stopmessages
-
-\startmessages german library: symbols
- title: Symbole
- 1: Lade Symboldatei --
-\stopmessages
-
-\startmessages czech library: symbols
- title: symboly
- 1: nacita se soubor symbolu --
-\stopmessages
-
-\startmessages italian library: symbols
- title: simboli
- 1: caricamento gruppo di simboli --
-\stopmessages
-
-\startmessages norwegian library: symbols
- title: symboler
- 1: leser inn symbolsett --
-\stopmessages
-
-\startmessages romanian library: symbols
- title: simboluri
- 1: se incarca setul de simboluri --
-\stopmessages
-
-\startmessages french library: symbols
- title: symboles
- 1: chargement du jeu de symbole --
-\stopmessages
-
%D \macros
%D {definesymbol, symbol}
%D
diff --git a/tex/context/base/symb-jmn.tex b/tex/context/base/symb-jmn.tex
index 21a0d1562..392cac552 100644
--- a/tex/context/base/symb-jmn.tex
+++ b/tex/context/base/symb-jmn.tex
@@ -146,7 +146,6 @@
\stopsymbolset
-
% 1 left : 065 067 073 075
% 2 left : 128 132 144 148
% 3 left : 129 133 145 149
diff --git a/tex/context/base/symb-mis.tex b/tex/context/base/symb-mis.tex
index c63053abb..d108b8902 100644
--- a/tex/context/base/symb-mis.tex
+++ b/tex/context/base/symb-mis.tex
@@ -16,7 +16,7 @@
%D We predefine some common symbols and conversions that will
%D be understood by many commands.
-% \mathematics no longer needed
+% \mathematics no longer needed, although only math fonts might have these
\definesymbol [\v!none] []
\definesymbol [bullet] [\mathematics{\bullet}]
@@ -24,7 +24,6 @@
\definesymbol [star] [\mathematics{\star}]
\definesymbol [triangle] [\mathematics{\triangleright}]
\definesymbol [circle] [\mathematics{\circ}]
-%definesymbol [medcircle] [\hbox{\setsmallbodyfont\raise\onepoint\hbox{\mathematics{\bigcirc}}}]
\definesymbol [square] [\mathematics{\square}]
\definesymbol [diamond] [\mathematics{\diamond}]
@@ -32,7 +31,6 @@
\definesymbol [medcircle] [\hbox{\raise.1ex\hbox{\mathematics{\scriptstyle \bigcirc}}}]
\definesymbol [bigcircle] [\mathematics{\bigcirc}]
-
\definesymbol [1] [{\symbol[bullet]}]
\definesymbol [2] [{\symbol[dash]}]
\definesymbol [3] [{\symbol[star]}]
@@ -113,9 +111,6 @@
\def\gonowherecharacter
{\mathematics{\bullet}}
-%\def\gotosomewherecharacter% {} permits ^\...
-% {{\hbox{\hsmash{\gobackwardcharacter}\goforwardcharacter}}}
-
\def\gotosomewherecharacter
{{\hbox{\hsmash{\symbol[\v!previous]}\symbol[\v!next]}}}
diff --git a/tex/context/base/syst-aux.tex b/tex/context/base/syst-aux.tex
new file mode 100644
index 000000000..3b9d6803f
--- /dev/null
+++ b/tex/context/base/syst-aux.tex
@@ -0,0 +1,6841 @@
+%D \module
+%D [ file=syst-gen,
+%D version=1996.03.20,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=General,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 of the macros will move to syst-obs as they might become
+%D obsolete once we've redone the bibliography module. Of course
+%D the handy helpers will stay.
+
+%D This is a stripped down combination of:
+%D
+%D \startitemize
+%D \item \type {syst-gen.tex}
+%D \item \type {syst-ext.tex}
+%D \item \type {syst-new.tex}
+%D \stopitemize
+%D
+%D We keep them around (for \MKII) so you can find comments,
+%D experiences, intermediate versions and cleaner variants
+%D there (and also non-\ETEX\ variants).
+%D
+%D Contrary to the older files, we now assume that this one
+%D is used in \CONTEXT\ and therefore we might also assume that
+%D some basic functionality is available.
+%D
+%D Some of the macros here are used in the bibliography module. They
+%D will be moved to a separate syst module some once the bib module
+%D is made \MKIV.
+
+\unprotect
+
+\let\reportprotectionstate\relax
+
+%D \macros
+%D {doifolderversionelse}
+%D
+%D We start with a macro specially for Aditya who wants to be able
+%D to use development versions of \MKIV\ for real documents.
+%D
+%D \starttyping
+%D \doifolderversionelse\contextversion{2001.02.03}{yes}{no}
+%D \doifolderversionelse\contextversion{3001.02.03}{yes}{no}
+%D \stoptyping
+%D
+%D The \type {yyyy.mm.dd} syntax is rather strict.
+
+\def\@@versiontonumber#1.#2.#3#4#5\relax
+ {\numexpr#1*\plustenthousand+#2*\plushundred+#3#4\relax}
+
+\def\doifolderversionelse#1#2%
+ {\normalexpanded{\noexpand\ifnum\noexpand\@@versiontonumber#1\relax<\noexpand\@@versiontonumber#2\relax}\relax
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {normalspace}
+%D
+%D There is already \type{\space} but just to be sure we also
+%D provide:
+
+\def\normalspace{ }
+
+%D \macros
+%D {!!count, !!toks, !!dimen, !!box,
+%D !!width, !!height, !!depth, !!string, !!done}
+%D
+%D We define some more \COUNTERS\ and \DIMENSIONS. We also
+%D define some shortcuts to the local scatchregisters~0, 2, 4,
+%D 6 and~8.
+
+\newcount\!!counta \newtoks\!!toksa \newdimen\!!dimena \newbox\!!boxa
+\newcount\!!countb \newtoks\!!toksb \newdimen\!!dimenb \newbox\!!boxb
+\newcount\!!countc \newtoks\!!toksc \newdimen\!!dimenc \newbox\!!boxc
+\newcount\!!countd \newtoks\!!toksd \newdimen\!!dimend \newbox\!!boxd
+\newcount\!!counte \newtoks\!!tokse \newdimen\!!dimene \newbox\!!boxe
+\newcount\!!countf \newtoks\!!toksf \newdimen\!!dimenf \newbox\!!boxf
+ \newdimen\!!dimeng
+ \newdimen\!!dimenh
+ \newdimen\!!dimeni
+ \newdimen\!!dimenj
+ \newdimen\!!dimenk
+
+\let\!!stringa\empty \let\!!stringb\empty \let\!!stringc\empty
+\let\!!stringd\empty \let\!!stringe\empty \let\!!stringf\empty
+
+\newdimen\!!widtha \newdimen\!!heighta \newdimen\!!deptha
+\newdimen\!!widthb \newdimen\!!heightb \newdimen\!!depthb
+\newdimen\!!widthc \newdimen\!!heightc \newdimen\!!depthc
+\newdimen\!!widthd \newdimen\!!heightd \newdimen\!!depthd
+
+\newif\if!!donea \newif\if!!doneb \newif\if!!donec
+\newif\if!!doned \newif\if!!donee \newif\if!!donef
+
+\def\!!zerocount {0} % alongside \zerocount
+\def\!!minusone {-1} % alongside \minusone
+\def\!!plusone {1} % alongside \plusone
+
+\ifdefined\data \else \let\data \relax \fi % dep checker
+
+%D \macros
+%D {s!,c!,e!,p!,v!,@@,??}
+%D
+%D To save memory, we use constants (sometimes called
+%D variables). Redefining these constants can have disastrous
+%D results.
+
+\def\v!prefix! {v!} \def\c!prefix! {c!}
+\def\s!prefix! {s!} \def\p!prefix! {p!}
+
+\def\s!next {next} \def\s!default {default}
+\def\s!dummy {dummy} \def\s!unknown {unknown}
+
+\def\s!do {do} \def\s!dodo {dodo}
+
+\def\s!complex {complex} \def\s!start {start}
+\def\s!simple {simple} \def\s!stop {stop}
+
+\def\s!empty {empty}
+
+%D \macros
+%D {@EA,@EAEA,@EAEAEA,@EAEAEAEAEAEA,expanded,startexpanded}
+%D
+%D When in unprotected mode, to be entered with
+%D \type{\unprotect}, one can use \type{\@EA} as equivalent
+%D of \type{\expandafter}.
+
+\let\@NX\noexpand
+\let\@EA\expandafter
+
+\def\@EAEA {\expandafter\expandafter}
+\def\@EAEAEA{\expandafter\expandafter\expandafter}
+
+\def\@EAEAEAEAEAEA{\expandafter\@EAEAEA\expandafter}
+
+%D Sometimes we pass macros as arguments to commands that
+%D don't expand them before interpretation. Such commands can
+%D be enclosed with \type{\expanded}, like:
+%D
+%D \starttyping
+%D \expanded{\setupsomething[\alfa]}
+%D \stoptyping
+%D
+%D Such situations occur for instance when \type{\alfa} is a
+%D commalist or when data stored in macros is fed to index of
+%D list commands. If needed, one should use \type{\noexpand}
+%D inside the argument. Later on we will meet some more clever
+%D alternatives to this command.
+
+\long\def\@@expanded{} % always long; global (less restores)
+
+\long\def\expanded#1%
+ {\long\xdef\@@expanded{\noexpand#1}\@@expanded}
+
+%D Beware, the next one has no \type {\noexpand} before its
+%D argument.
+
+\long\def\startexpanded#1\stopexpanded % see x-fo for example
+ {\long\xdef\@@expanded{#1}\@@expanded}
+
+%D Recent \TEX's have a primitive \expanded
+
+% \long\def\expanded
+% {\normalexpanded\bgroup\noexpand\gobblenexttoken}
+
+%D \macros
+%D {safeexpanded,everysafeexpanded}
+%D
+%D In addition we provide:
+
+\newtoks\everysafeexpanded
+
+\long\def\safeexpanded#1% why the \noexpand
+ {\begingroup
+ \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#1}%
+ \endgroup
+ \@@expanded}
+
+\def\safeedef#1#2%
+ {\begingroup
+ \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}%
+ \endgroup
+ \let#1\@@expanded}
+
+\def\safexdef#1#2%
+ {\begingroup
+ \the\everysafeexpanded\long\xdef\@@expanded{\noexpand#2}%
+ \endgroup
+ \global\let#1\@@expanded}
+
+%D You can append protective measures to the token register if
+%D needed, as we will do later.
+
+%D \macros
+%D {expandoneargafter,expandtwoargsafter}
+%D
+%D These two commands make macros more readable by hiding a
+%D lot of \type {\expandafter}'s. They expand the arguments
+%D after the first command.
+%D
+%D \starttyping
+%D \expandoneargafter \command{\abc}
+%D \expandtwoargsafter\command{\abc}{\def}
+%D \stoptyping
+%D
+%D These commands expect the arguments to be macros.
+
+\def\expandoneargafter #1{\@EA#1\@EA}
+\def\expandtwoargsafter#1#2{\@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA#2\@EA}\@EA}
+
+%D These two do a full expansion:
+
+\def\fullexpandoneargafter #1#2{\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded}
+\def\fullexpandtwoargsafter#1#2#3{\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded}
+
+%D \macros
+%D {gobbleoneargument,gobble...arguments}
+%D
+%D The next set of macros just do nothing, except that they
+%D get rid of a number of arguments.
+
+\long\def\gobbleoneargument #1{}
+\long\def\gobbletwoarguments #1#2{}
+\long\def\gobblethreearguments #1#2#3{}
+\long\def\gobblefourarguments #1#2#3#4{}
+\long\def\gobblefivearguments #1#2#3#4#5{}
+\long\def\gobblesixarguments #1#2#3#4#5#6{}
+\long\def\gobblesevenarguments #1#2#3#4#5#6#7{}
+\long\def\gobbleeightarguments #1#2#3#4#5#6#7#8{}
+\long\def\gobbleninearguments #1#2#3#4#5#6#7#8#9{}
+\long\def\gobbletenarguments #1{\gobbleninearguments}
+
+%D \macros
+%D {doifnextcharelse}
+%D
+%D When we started using \TEX\ in the late eighties, our
+%D first experiences with programming concerned a simple shell
+%D around \LATEX. The commands probably use most at \PRAGMA,
+%D are the itemizing ones. One of those few shell commands took
+%D care of an optional argument, that enabled us to specify
+%D what kind of item symbol we wanted. Without understanding
+%D anything we were able to locate a \LATEX\ macro that could
+%D be used to inspect the next character.
+%D
+%D It's this macro that the ancester of the next one presented
+%D here. It executes one of two actions, dependant of the next
+%D character. Disturbing spaces and line endings, which are
+%D normally interpreted as spaces too, are skipped.
+%D
+%D \starttyping
+%D \doifnextcharelse {karakter} {then ...} {else ...}
+%D \stoptyping
+%D
+%D This macro differs from the original in the use of \type
+%D {\localnext} because we don't want clashes with \type
+%D {\next}.
+
+\long\def\doifnextcharelse#1#2#3% #1 should not be {} !
+ {\let\charactertoken=#1% = needed here
+ \def\!!stringa{#2}%
+ \def\!!stringb{#3}%
+ \futurelet\nexttoken\inspectnextcharacter}
+
+\def\inspectnextcharacter
+ {\ifx\nexttoken\blankspace
+ \@EA\reinspectnextcharacter
+ \else
+ \@EA\inspectnextcharacterindeed
+ \fi}
+\def\inspectnextcharacterindeed
+ {\ifx\nexttoken\charactertoken
+ \@EA\!!stringa
+ \else
+ \@EA\!!stringb
+ \fi}
+
+%D Because we will mostly use this macro for testing if the next
+%D character is \type {[}, we also make a slightly faster variant
+%D as it is not uncommon to have tens of thousands of calls to this
+%D test in a run. Of course it also is more convenient to read a
+%D trace then.
+
+\let\nextoptionalcharactertoken=[
+
+\long\def\doifnextoptionalelse#1#2%
+ {\def\nextoptionalcommandyes{#1}%
+ \def\nextoptionalcommandnop{#2}%
+ \futurelet\nexttoken\inspectnextoptionalcharacter}
+
+\def\inspectnextoptionalcharacter
+ {\ifx\nexttoken\blankspace
+ \@EA\reinspectnextoptionalcharacter
+ \else
+ \@EA\inspectnextoptionalcharacterindeed
+ \fi}
+\def\inspectnextoptionalcharacterindeed
+ {\ifx\nexttoken\nextoptionalcharactertoken
+ \@EA\nextoptionalcommandyes
+ \else
+ \@EA\nextoptionalcommandnop
+ \fi}
+
+\let\nextbgroupcharactertoken\bgroup
+
+\long\def\doifnextbgroupelse#1#2%
+ {\def\nextbgroupcommandyes{#1}%
+ \def\nextbgroupcommandnop{#2}%
+ \futurelet\nexttoken\inspectnextbgroupcharacter}
+
+\def\inspectnextbgroupcharacter
+ {\ifx\nexttoken\blankspace
+ \@EA\reinspectnextbgroupcharacter
+ \else
+ \@EA\inspectnextbgroupcharacterindeed
+ \fi}
+\def\inspectnextbgroupcharacterindeed
+ {\ifx\nexttoken\nextbgroupcharactertoken
+ \@EA\nextbgroupcommandyes
+ \else
+ \@EA\nextbgroupcommandnop
+ \fi}
+
+%D This macro uses some auxiliary macros. Although we were able
+%D to program quite complicated things, I only understood these
+%D after rereading the \TEX book. The trick is in using a
+%D command with a one character name. Such commands differ from
+%D the longer ones in the fact that trailing spaces are {\em
+%D not} skipped. This enables us to indirectly define a long
+%D named macro that gobbles a space.
+%D
+%D In the first line we define \type{\blankspace}. Next we
+%D make \type{\:} equivalent to \type{\reinspect...}. This
+%D one||character command is expanded before the next
+%D \type{\def} comes into action. This way the space after
+%D \type{\:} becomes a delimiter of the longer named
+%D \type{\reinspectnextcharacter}.
+
+\let\next\:
+
+\def\:{\let\blankspace= } \:
+
+\def\:{\reinspectnextcharacter}
+\expandafter\def\: {\futurelet\nexttoken\inspectnextcharacter}
+
+\def\:{\reinspectnextoptionalcharacter}
+\expandafter\def\: {\futurelet\nexttoken\inspectnextoptionalcharacter}
+
+\def\:{\reinspectnextbgroupcharacter}
+\expandafter\def\: {\futurelet\nexttoken\inspectnextbgroupcharacter}
+
+\let\:\next
+
+%D \macros
+%D {setvalue,setgvalue,setevalue,setxvalue,
+%D letvalue,letgvalue,getvalue,resetvalue,
+%D undefinevalue,ignorevalue}
+%D
+%D \TEX's primitive \type{\csname} can be used to construct
+%D all kind of commands that cannot be defined with
+%D \type{\def} and \type{\let}. Every macro programmer sooner
+%D or later wants macros like these.
+%D
+%D \starttyping
+%D \setvalue {name}{...} = \def\name{...}
+%D \setgvalue {name}{...} = \gdef\name{...}
+%D \setevalue {name}{...} = \edef\name{...}
+%D \setxvalue {name}{...} = \xdef\name{...}
+%D \letvalue {name}=\... = \let\name=\...
+%D \letgvalue {name}=\... = \global\let\name=\...
+%D \getvalue {name} = \name
+%D \resetvalue {name} = \def\name{}
+%D \stoptyping
+%D
+%D As we will see, \CONTEXT\ uses these commands many times,
+%D which is mainly due to its object oriented and parameter
+%D driven character.
+
+\def\setvalue #1{\expandafter \def\csname#1\endcsname}
+\def\setgvalue #1{\expandafter\gdef\csname#1\endcsname}
+\def\setevalue #1{\expandafter\edef\csname#1\endcsname}
+\def\setxvalue #1{\expandafter\xdef\csname#1\endcsname}
+\def\getvalue #1{\csname#1\endcsname}
+\def\letvalue #1{\expandafter\let\csname#1\endcsname}
+\def\letgvalue #1{\global\expandafter\let\csname#1\endcsname}
+\def\resetvalue #1{\expandafter\let\csname#1\endcsname\empty}
+\def\undefinevalue#1{\expandafter\let\csname#1\endcsname\undefined}
+\def\ignorevalue#1#2{\expandafter\let\csname#1\endcsname\empty}
+
+%D \macros
+%D {globallet,glet}
+%D
+%D In \CONTEXT\ of May 2000 using \type {\globallet}
+%D instead of the two tokens will save us some
+%D $300\times4=1200$ bytes of format file on a 32~bit
+%D system. So:
+
+\def\globallet{\global\let} \let\glet\globallet
+
+%D \macros
+%D {donottest,unexpanded}
+%D
+%D When expansion of a macro gives problems, we can precede it
+%D by \type{\donottest}. It seems that protection is one of the
+%D burdens of developers of packages, so maybe that's why in
+%D \ETEX\ protection is solved in a more robust way.
+%D
+%D Because we use thi smodule onl in \MKIV, we have removed the
+%D old protection code.
+%D
+%D \starttyping
+%D \unexpanded\def\somecommand{... ... ...}
+%D \stoptyping
+
+\let \donottest \firstofoneargument % we need to weed
+\let \honorunexpanded \empty % we need to weed
+\let \forceunexpanded \empty % we need to weed
+\let \resetunexpanded \empty % we need to weed
+
+\let \unexpanded \normalprotected
+
+%D \macros
+%D {doifundefined,doifdefined,
+%D doifundefinedelse,doifdefinedelse,
+%D doifalldefinedelse}
+%D
+%D The standard way of testing if a macro is defined is
+%D comparing its meaning with another undefined one, usually
+%D \type{\undefined}. To garantee correct working of the next
+%D set of macros, \type{\undefined} may never be defined!
+%D
+%D \starttyping
+%D \doifundefined {string} {...}
+%D \doifdefined {string} {...}
+%D \doifundefinedelse {string} {then ...} {else ...}
+%D \doifdefinedelse {string} {then ...} {else ...}
+%D \doifalldefinedelse {commalist} {then ...} {else ...}
+%D \stoptyping
+%D
+%D Every macroname that \TEX\ builds gets an entry in the hash
+%D table, which is of limited size. It is expected that e-\TeX\
+%D will offer a less memory||consuming alternative.
+
+%D Although it will probably never be a big problem, it is good
+%D to be aware of the difference between testing on a macro
+%D name to be build by using \type{\csname} and
+%D \type{\endcsname} and testing the \type{\name} directly.
+%D
+%D \starttyping
+%D \expandafter\ifx\csname NameA\endcsname\relax ... \else ... \fi
+%D
+%D \ifundefined\NameB ... \else ... \fi
+%D \stoptyping
+
+\def\ifundefined#1% ongelukkige naam .. obsolete
+ {\unless\ifcsname#1\endcsname}
+
+% \def\p!doifundefined#1%
+% {\edef\p!defined{#1}%
+% \unless\ifcsname\detokenize\@EA{\p!defined}\endcsname}
+
+% \def\doifundefinedelse#1%
+% {\edef\p!defined{#1}%
+% \ifcsname\detokenize\@EA{\p!defined}\endcsname
+% \expandafter\secondoftwoarguments
+% \else
+% \expandafter\firstoftwoarguments
+% \fi}
+
+% \def\doifdefinedelse#1%
+% {\edef\p!defined{#1}%
+% \ifcsname\detokenize\@EA{\p!defined}\endcsname
+% \expandafter\firstoftwoarguments
+% \else
+% \expandafter\secondoftwoarguments
+% \fi}
+
+% \def\doifundefined#1%
+% {\edef\p!defined{#1}%
+% \ifcsname\detokenize\@EA{\p!defined}\endcsname
+% \expandafter\gobbleoneargument
+% \else
+% \expandafter\firstofoneargument
+% \fi}
+
+% \def\doifdefined#1%
+% {\edef\p!defined{#1}%
+% \ifcsname\detokenize\@EA{\p!defined}\endcsname
+% \expandafter\firstofoneargument
+% \else
+% \expandafter\gobbleoneargument
+% \fi}
+
+\ifdefined\suppressifcsnameerror
+
+ \suppressifcsnameerror\plusone
+
+ \def\doifundefinedelse#1%
+ {\ifcsname#1\endcsname
+ \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments
+ \fi}
+
+ \def\doifdefinedelse#1%
+ {\ifcsname#1\endcsname
+ \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments
+ \fi}
+
+ \def\doifundefined#1%
+ {\ifcsname#1\endcsname
+ \@EA\gobbleoneargument\else\@EA\firstofoneargument
+ \fi}
+
+ \def\doifdefined#1%
+ {\ifcsname#1\endcsname
+ \@EA\firstofoneargument\else\@EA\gobbleoneargument
+ \fi}
+
+\else
+
+ \def\doifundefinedelse#1%
+ {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname
+ \@EA\secondoftwoarguments\else\@EA\firstoftwoarguments
+ \fi}
+
+ \def\doifdefinedelse#1%
+ {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname
+ \@EA\firstoftwoarguments\else\@EA\secondoftwoarguments
+ \fi}
+
+ \def\doifundefined#1%
+ {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname
+ \@EA\gobbleoneargument\else\@EA\firstofoneargument
+ \fi}
+
+ \def\doifdefined#1%
+ {\ifcsname\detokenize\@EA{\normalexpanded{#1}}\endcsname
+ \@EA\firstofoneargument\else\@EA\gobbleoneargument
+ \fi}
+
+\fi
+
+%D \macros
+%D {letbeundefined}
+%D
+%D Testing for being undefined comes down to testing on \type
+%D {\relax} when we use \type {\csname}, but when using \type
+%D {\ifx}, we test on being \type {\undefined}! In \ETEX\ we
+%D have \type {\ifcsname} and that way of testing on existance
+%D is not the same as the one described here. Therefore we
+%D introduce:
+
+\def\letbeundefined#1% potential stack buildup when used \global
+ {\expandafter\let\csname#1\endcsname\undefined}
+
+\def\localundefine#1% conditional
+ {\ifcsname#1\endcsname\expandafter\let\csname#1\endcsname\undefined\fi}
+
+\def\globalundefine#1% conditional
+ {\ifcsname#1\endcsname\expandafter\global\let\csname#1\endcsname\undefined\fi}
+
+%D Beware, being \type {\undefined} in \ETEX\ means that the macro
+%D {\em is} defined!
+
+%D When we were developing the scientific units module, we
+%D encountered different behavior in text and math mode, which
+%D was due to this grouping subtilities. We therefore decided
+%D to use \type{\begingroup} instead of \type{\bgroup}.
+
+\def\docheckonedefined#1%
+ {\ifcsname#1\endcsname\else
+ \donefalse
+ \expandafter\quitcommalist % added
+ \fi}
+
+\def\doifalldefinedelse#1%
+ {\begingroup
+ \donetrue \processcommalist[#1]\docheckonedefined
+ \ifdone
+ \endgroup\expandafter\firstoftwoarguments
+ \else
+ \endgroup\expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doif,doifelse,doifnot,
+%D donottest}
+%D
+%D Programming in \TEX\ differs from programming in procedural
+%D languages like \MODULA. This means that one --- well, let me
+%D speek for myself --- tries to do the things in the well
+%D known way. Therefore the next set of \type{\ifthenelse}
+%D commands were between the first ones we needed. A few years
+%D later, the opposite became true: when programming in
+%D \MODULA, I sometimes miss handy things like grouping,
+%D runtime redefinition, expansion etc. While \MODULA\ taught
+%D me to structure, \TEX\ taught me to think recursive.
+%D
+%D \starttyping
+%D \doif {string1} {string2} {...}
+%D \doifnot {string1} {string2} {...}
+%D \doifelse {string1} {string2} {then ...}{else ...}
+%D \stoptyping
+%D
+%D When expansion gives problems, we can precede the
+%D troublemaker with \type{\donottest}.
+
+\long\def\doif#1#2%
+ {\edef\!!stringa{#1}\edef\!!stringb{#2}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\long\def\doifnot#1#2%
+ {\edef\!!stringa{#1}\edef\!!stringb{#2}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\long\def\doifelse#1#2%
+ {\edef\!!stringa{#1}\edef\!!stringb{#2}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doifempty,doifemptyelse,doifnotempty}
+%D
+%D We complete our set of conditionals with:
+%D
+%D \starttyping
+%D \doifempty {string} {...}
+%D \doifnotempty {string} {...}
+%D \doifemptyelse {string} {then ...} {else ...}
+%D \stoptyping
+%D
+%D This time, the string is not expanded.
+
+\long\def\doifemptyelse#1%
+ {\def\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\long\def\doifempty#1%
+ {\def\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\long\def\doifnotempty#1%
+ {\def\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+%D \macros
+%D {doifinset,doifnotinset,doifinsetelse}
+%D
+%D We can check if a string is present in a comma separated
+%D set of strings. Depending on the result, some action is
+%D taken.
+%D
+%D \starttyping
+%D \doifinset {string} {string,...} {...}
+%D \doifnotinset {string} {string,...} {...}
+%D \doifinsetelse {string} {string,...} {then ...} {else ...}
+%D \stoptyping
+
+% !0nop=\doifinsetelse{ccc}{,}{yes}{nop}
+% !0nop=\doifinsetelse{ccc}{,,}{yes}{nop}
+% !0nop=\doifinsetelse{ccc}{,,,}{yes}{nop}
+
+% !1nop=\doifinsetelse{}{}{yes}{nop}
+% !2yes=\doifinsetelse{aaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop}
+% !3nop=\doifinsetelse{aaa}{bbb}{yes}{nop}
+% !4yes=\doifinsetelse{aaa}{aaa}{yes}{nop}
+% !5nop=\doifinsetelse{aaaa}{bbb,ccc,ddd,aaa,eee}{yes}{nop}
+% !6nop=\doifinsetelse{}{}{yes}{nop}
+% !7nop=\doifinsetelse{}{aaa}{yes}{nop}
+% !8nop=\doifinsetelse{aaa}{}{yes}{nop}
+
+% !1=\doifinset{}{}{yes}
+% !2yes=\doifinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes}
+% !3=\doifinset{aaa}{bbb}{yes}
+% !4yes=\doifinset{aaa}{aaa}{yes}
+% !5=\doifinset{}{}{yes}
+% !6=\doifinset{aaa}{}{yes}
+
+% !1yes=\doifnotinset{}{}{yes}
+% !2=\doifnotinset{aaa}{bbb,ccc,ddd,aaa,eee}{yes}
+% !3yes=\doifnotinset{aaa}{bbb}{yes}
+% !4=\doifnotinset{aaa}{aaa}{yes}
+% !5yes=\doifnotinset{}{}{yes}
+% !6yes=\doifnotinset{aaa}{}{yes}
+
+\def\rightoptionalbracket{]}
+
+\long\def\doquitifiteminsetelse#1],\relax{\firstoftwoarguments}
+\long\def\doquitifiteminset #1],\relax{\firstofoneargument}
+\long\def\doquitifitemnotinset #1],\relax{\gobbleoneargument}
+
+\long\def\redoifinsetelse{\expandafter\docheckifiteminsetelse\!!stringb,],\relax}
+\long\def\redoifinset {\expandafter\docheckifiteminset \!!stringb,],\relax}
+\long\def\redoifnotinset {\expandafter\docheckifitemnotinset \!!stringb,],\relax}
+
+\long\def\doifinsetelse#1% make this two step too
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\thirdofthreearguments
+ \else
+ \expandafter\dodoifinsetelse
+ \fi}
+\long\def\dodoifinsetelse#1%
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\empty
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\redoifinsetelse
+ \fi}
+
+\long\def\doifinset#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\gobbletwoarguments
+ \else
+ \expandafter\dodoifinset
+ \fi}
+\long\def\dodoifinset#1%
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\redoifinset
+ \fi}
+
+\long\def\doifnotinset#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\dodoifnotinset
+ \fi}
+\long\def\dodoifnotinset#1%
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\redoifnotinset % ...]{true}
+ \fi}
+
+\def\docheckifiteminsetelse#1,#2% #2 eats up preceding space
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\empty
+ \expandafter\docheckifiteminsetelse
+ \else
+ \expandafter\dodocheckifiteminsetelse
+ \fi#2}
+\def\dodocheckifiteminsetelse
+ {\ifx\!!stringb\rightoptionalbracket
+ \expandafter\thirdofthreearguments
+ \else
+ \expandafter\dododocheckifiteminsetelse
+ \fi}
+\def\dododocheckifiteminsetelse
+ {\ifx\!!stringa\!!stringb
+ \expandafter\doquitifiteminsetelse
+ \else
+ \expandafter\docheckifiteminsetelse
+ \fi}
+
+\def\docheckifiteminset#1,#2% #2 eats up preceding space
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\empty
+ \expandafter\docheckifiteminset
+ \else
+ \expandafter\dodocheckifiteminset
+ \fi#2}
+\def\dodocheckifiteminset
+ {\ifx\!!stringb\rightoptionalbracket
+ \expandafter\gobbletwoarguments
+ \else
+ \expandafter\dododocheckifiteminset
+ \fi}
+\def\dododocheckifiteminset
+ {\ifx\!!stringa\!!stringb
+ \expandafter\doquitifiteminset
+ \else
+ \expandafter\docheckifiteminset
+ \fi}
+
+\def\docheckifitemnotinset#1,#2% #2 eats up preceding space
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\empty
+ \expandafter\docheckifitemnotinset
+ \else
+ \expandafter\dodocheckifitemnotinset
+ \fi#2}
+\def\dodocheckifitemnotinset
+ {\ifx\!!stringb\rightoptionalbracket
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\dododocheckifitemnotinset
+ \fi}
+\def\dododocheckifitemnotinset
+ {\ifx\!!stringa\!!stringb
+ \expandafter\doquitifitemnotinset
+ \else
+ \expandafter\docheckifitemnotinset
+ \fi}
+
+%D \macros
+%D {doifcommon,doifnotcommon,doifcommonelse}
+%D
+%D Probably the most time consuming tests are those that test
+%D for overlap in sets of strings.
+%D
+%D \starttyping
+%D \doifcommon {string,...} {string,...} {...}
+%D \doifnotcommon {string,...} {string,...} {...}
+%D \doifcommonelse {string,...} {string,...} {then ...} {else ...}
+%D \stoptyping
+
+% !1yes=\doifcommonelse{aaa,bbb,ccc}{aaa,bbb,ccc}{yes}{nop}
+% !2nop=\doifcommonelse{aaa,bbb,ccc}{ddd,eee,fff}{yes}{nop}
+% !3nop=\doifcommonelse{aaa}{ddd,eee,fff}{yes}{nop}
+% !4yes=\doifcommonelse{aaa}{aaa}{yes}{nop}
+% !5nop=\doifcommonelse{bbb}{aaa}{yes}{nop}
+% !6nop=\doifcommonelse{}{aaa,bbb,ccc}{yes}{nop}
+% !7nop=\doifcommonelse{aaa,bbb,ccc}{}{yes}{nop}
+% !8nop=\doifcommonelse{}{}{yes}{nop}
+
+% !9nop=\doifcommonelse{,,}{,,}{yes}{nop}
+% !9yes=\doifcommonelse{,a,}{,a,}{yes}{nop}
+% !9yes=\doifcommonelse{,,a,}{,a,}{yes}{nop}
+% !9yes=\doifcommonelse{,a,}{,,a,}{yes}{nop}
+% !9yes=\doifcommonelse{,a,}{,,,a,}{yes}{nop}
+% !9yes=\doifcommonelse{,,a,}{,,,a,}{yes}{nop}
+
+% \def\p!doifcommonelse#1#2#3#4%
+% {\donefalse
+% \def\p!docommoncheck##1{\doifinset{##1}{#4}\donetrue\ifdone\quitcommalist\fi}%
+% \processcommalist[#3]\p!docommoncheck
+% \ifdone\expandafter#1\else\expandafter#2\fi}
+%
+% \def\doifcommonelse
+% {\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments}
+%
+% \def\doifcommon
+% {\p!doifcommonelse\firstofoneargument \gobbleoneargument}
+%
+% \def\doifnotcommon
+% {\p!doifcommonelse\gobbleoneargument \firstofoneargument}
+
+\long\def\doquitifcommonelse#1],\relax#2],\relax{\firstoftwoarguments}
+
+\long\def\doquitifcommonelsenop{\secondoftwoarguments}
+
+\def\docheckifcommonelseone#1,#2%
+ {\edef\!!stringc{#1}%
+ \ifx\!!stringc\rightoptionalbracket
+ \expandafter\thirdofthreearguments
+ \else
+ \expandafter\p!docommoncheck
+ \fi#2}
+
+\def\docheckifcommonelsetwo#1,#2% we can do an empty #1 check too
+ {\edef\commalistelement{#1}%
+ \ifx\commalistelement\rightoptionalbracket
+ \expandafter\redocheckifcommonelseone
+ \else
+ \expandafter\dodocheckifcommonelsetwo
+ \fi#2}
+
+\def\dodocheckifcommonelsetwo
+ {\ifx\commalistelement\empty
+ \expandafter\docheckifcommonelsetwo
+ \else
+ \expandafter\dododocheckifcommonelsetwo
+ \fi}
+
+\def\dododocheckifcommonelsetwo
+ {\ifx\!!stringc\commalistelement
+ \expandafter\doquitifcommonelse
+ \else
+ \expandafter\docheckifcommonelsetwo
+ \fi}
+
+\def\redocheckifcommonelseone#1{\docheckifcommonelseone}
+
+\def\p!doifcommonelse#1#2#3#4%
+ {\edef\!!stringa{#3}%
+ \edef\!!stringb{#4}%
+ \ifx\!!stringa\empty
+ \expandafter\secondoftwoarguments
+ \else\ifx\!!stringb\empty
+ \expandafter\expandafter\expandafter\secondoftwoarguments
+ \else
+ \expandafter\expandafter\expandafter\pp!doifcommonelse
+ \fi\fi
+ #1#2}
+
+% \def\p!doifcommonelse#1#2#3%
+% {\edef\!!stringa{#3}%
+% \ifx\!!stringa\empty
+% \expandafter\secondofthreearguments
+% \else
+% \expandafter\p!dodoifcommonelse
+% \fi
+% #1#2} % #4
+
+% \def\p!dodoifcommonelse#1#2#3%
+% {\edef\!!stringb{#3}%
+% \ifx\!!stringb\empty
+% \expandafter\secondoftwoarguments
+% \else
+% \expandafter\pp!doifcommonelse
+% \fi#1#2}
+
+\def\pp!doifcommonelse
+ {\def\p!docommoncheck{\expandafter\docheckifcommonelsetwo\!!stringb,],\relax}%
+ \expandafter\docheckifcommonelseone\!!stringa,],\relax}
+
+\def\doifcommonelse{\p!doifcommonelse\firstoftwoarguments\secondoftwoarguments}
+\def\doifcommon {\p!doifcommonelse\firstofoneargument \gobbleoneargument }
+\def\doifnotcommon {\p!doifcommonelse\gobbleoneargument \firstofoneargument }
+
+%D \macros
+%D {processcommalist,processcommacommand,quitcommalist,
+%D processcommalistwithparameters}
+%D
+%D We've already seen some macros that take care of comma
+%D separated lists. Such list can be processed with
+%D
+%D \starttyping
+%D \processcommalist[string,string,...]\commando
+%D \stoptyping
+%D
+%D The user supplied command \type{\commando} receives one
+%D argument: the string. This command permits nesting and
+%D spaces after commas are skipped. Empty sets are no problem.
+%D
+%D \startbuffer
+%D \def\dosomething#1{(#1)}
+%D
+%D 1: \processcommalist [\hbox{$a,b,c,d,e,f$}] \dosomething \par
+%D 2: \processcommalist [{a,b,c,d,e,f}] \dosomething \par
+%D 3: \processcommalist [{a,b,c},d,e,f] \dosomething \par
+%D 4: \processcommalist [a,b,{c,d,e},f] \dosomething \par
+%D 5: \processcommalist [a{b,c},d,e,f] \dosomething \par
+%D 6: \processcommalist [{a,b}c,d,e,f] \dosomething \par
+%D 7: \processcommalist [] \dosomething \par
+%D 8: \processcommalist [{[}] \dosomething \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Before we show the result, we present the macro's:
+
+\newcount\commalevel
+
+\def\dododoprocesscommaitem
+ {\csname\s!next\the\commalevel\endcsname}
+
+% \def\dodoprocesscommaitem
+% {\ifx\nexttoken\blankspace
+% \@EA\redoprocesscommaitem
+% \else\ifx\nexttoken]%
+% \@EAEAEA\gobbleoneargument
+% \else
+% \@EAEAEA\dododoprocesscommaitem
+% \fi\fi}
+
+\def\dodoprocesscommaitem
+ {\ifx\nexttoken\blankspace
+ \@EA\redoprocesscommaitem
+ \else
+ \@EA\dodoprocesscommaitemindeed
+ \fi}
+\def\dodoprocesscommaitemindeed
+ {\ifx\nexttoken]%
+ \@EA\gobbleoneargument
+ \else
+ \@EA\dododoprocesscommaitem
+ \fi}
+
+\def\doprocesscommaitem
+ {\futurelet\nexttoken\dodoprocesscommaitem}
+
+%D Empty arguments are not processed. Empty items (\type{,,})
+%D however are treated. We have to check for the special case
+%D \type{[{a,b,c}]}.
+
+\def\processcommalist[%
+ {\futurelet\nexttoken\docheckcommaitem}
+
+\def\docheckcommaitem
+ {\ifx\nexttoken]%
+ \expandafter\gobblethreearguments
+ \else
+ \expandafter\doprocesscommalist
+ \fi
+ \relax} % this one preserved the next {}
+
+\def\doprocesscommalist#1]#2%
+ {\global\advance\commalevel \plusone
+ \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,%
+ {#2{##1}\doprocesscommaitem}%
+ \@EA\dodoprocesscommaitem\gobbleoneargument#1,]\relax
+ \global\advance\commalevel \minusone }
+
+%D One way of quitting a commalist halfway is:
+
+\def\quitcommalist
+ {\begingroup\let\doprocesscommaitem\doquitcommalist}
+
+\def\doquitcommalist#1]%
+ {\endgroup}
+
+\def\quitprevcommalist
+ {\begingroup\let\doprocesscommaitem\doquitprevcommalist}
+
+\def\doquitprevcommalist#1]%
+ {\let\doprocesscommaitem\doquitcommalist}
+
+%D The hack we used for checking the next character
+%D \type {\doifnextcharelse} is also used here.
+
+\def\:{\redoprocesscommaitem}
+
+\expandafter\def\: {\futurelet\nexttoken\dodoprocesscommaitem}
+
+%D The previous examples lead to:
+%D
+%D \getbuffer
+
+%D When a list is saved in a macro, we can use a construction
+%D like:
+%D
+%D \starttyping
+%D \expandafter\processcommalist\expandafter[\list]\command
+%D \stoptyping
+%D
+%D Such solutions suit most situations, but we wanted a bit
+%D more.
+%D
+%D \starttyping
+%D \processcommacommand[string,\stringset,string]\commando
+%D \stoptyping
+%D
+%D where \type{\stringset} is a predefined set, like:
+%D
+%D \starttyping
+%D \def\first{aap,noot,mies}
+%D \def\second{laatste}
+%D
+%D \processcommacommand[\first]\message
+%D \processcommacommand[\first,second,third]\message
+%D \processcommacommand[\first,between,\second]\message
+%D \stoptyping
+%D
+%D Commands that are part of the list are expanded, so the
+%D use of this macro has its limits.
+
+% \def\processcommacommand[#1]%
+% {\expanded{\processcommalist[#1]}}
+
+\def\processcommacommand[#1]%
+ {\expandafter\processcommalist\expandafter[\normalexpanded{#1}]}
+
+%D The argument to \type{\command} is not delimited. Because
+%D we often use \type{[]} as delimiters, we also have:
+%D
+%D \starttyping
+%D \processcommalistwithparameters[string,string,...]\command
+%D \stoptyping
+%D
+%D where \type{\command} looks like:
+%D
+%D \starttyping
+%D \def\command[#1]{... #1 ...}
+%D \stoptyping
+
+\def\processcommalistwithparameters[#1]#2%
+ {\def\docommand##1{#2[##1]}%
+ \processcommalist[#1]\docommand}
+
+%D \macros
+%D {processaction,
+%D processfirstactioninset,
+%D processallactionsinset}
+%D
+%D \CONTEXT\ makes extensive use of a sort of case or switch
+%D command. Depending of the presence of one or more provided
+%D items, some actions is taken. These macros can be nested
+%D without problems.
+%D
+%D \starttyping
+%D \processaction [x] [a=>\a,b=>\b,c=>\c]
+%D \processfirstactioninset [x,y,z] [a=>\a,b=>\b,c=>\c]
+%D \processallactionsinset [x,y,z] [a=>\a,b=>\b,c=>\c]
+%D \stoptyping
+%D
+%D We can supply both a \type{default} action and an action
+%D to be undertaken when an \type{unknown} value is met:
+%D
+%D \starttyping
+%D \processallactionsinset
+%D [x,y,z]
+%D [ a=>\a,
+%D b=>\b,
+%D c=>\c,
+%D default=>\default,
+%D unknown=>\unknown{... \commalistelement ...}]
+%D \stoptyping
+%D
+%D When \type{#1} is empty, this macro scans list \type{#2} for
+%D the keyword \type{default} and executed the related action
+%D if present. When \type{#1} is non empty and not in the list,
+%D the action related to \type{unknown} is executed. Both
+%D keywords must be at the end of list \type{#2}. Afterwards,
+%D the actually found keyword is available in
+%D \type{\commalistelement}. An advanced example of the use of
+%D this macro can be found in \PPCHTEX, where we completely
+%D rely on \TEX\ for interpreting user supplied keywords like
+%D \type{SB}, \type{SB1..6}, \type{SB125} etc.
+
+\newcount\processlevel
+
+\def\p!compareprocessactionA[#1=>#2][#3]%
+ {\edef\!!stringb{#1}%
+ \ifx\!!stringb\s!default
+ \let\commalistelement\empty
+ #2%
+ \fi}
+
+% met \quitcommalist tot meer dan 25\% sneller
+
+\def\p!compareprocessactionB[#1=>#2][#3]%
+ {\expandedaction\!!stringb{#1}%
+ \ifx\!!stringa\!!stringb
+ \def\commalistelement{#3}%
+ #2%
+ \expandafter\quitcommalist
+ \else
+ \edef\!!stringb{#1}%
+ \ifx\!!stringb\s!unknown
+ \def\commalistelement{#3}% beware of loops
+ #2%
+ \fi
+ \fi}
+
+\def\processaction[#1]#2[%
+ {\expandedaction\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \let\p!compareprocessaction\p!compareprocessactionA
+ \else
+ \let\p!compareprocessaction\p!compareprocessactionB
+ \fi
+ \def\p!doprocessaction##1%
+ {\p!compareprocessaction[##1][#1]}%
+ \processnextcommalist\relax\expandactions\p!doprocessaction[}
+
+\def\p!compareprocessactionC[#1=>#2][#3]%
+ {\expandedaction\!!stringa{#1}%
+ \expandedaction\!!stringb{#3}%
+ \ifx\!!stringa\!!stringb
+ \def\commalistelement{#3}%
+ #2%
+ \expandafter\quitprevcommalist
+ \else
+ \edef\!!stringa{#1}%
+ \ifx\!!stringa\s!unknown
+ \def\commalistelement{#3}%
+ #2%
+ \fi
+ \fi}
+
+\def\processfirstactioninset[#1]%
+ {\expandedaction\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\processaction
+ \else
+ \expandafter\processfirstactionsinsetindeed
+ \fi
+ [#1]}
+
+\def\processfirstactionsinsetindeed[#1]#2[#3]%
+ {\def\p!doprocessaction##1%
+ {\def\p!dodoprocessaction####1%
+ {\p!compareprocessactionC[####1][##1]}%
+ \processcommalist[#3]\p!dodoprocessaction}%
+ \processcommalist[#1]\p!doprocessaction
+ \expandactions}
+
+\def\p!compareprocessactionD[#1=>#2][#3]%
+ {\expandedaction\!!stringa{#1}%
+ \expandedaction\!!stringb{#3}%
+ \ifx\!!stringa\!!stringb
+ \def\commalistelement{#3}%
+ #2%
+ \expandafter\quitcommalist
+ \else
+ \edef\!!stringa{#1}%
+ \ifx\!!stringa\s!unknown
+ \def\commalistelement{#3}%
+ #2%
+ \fi
+ \fi}
+
+\def\doprocessallactionsinset
+ {\csname\s!do\the\processlevel\endcsname}
+
+\def\processallactionsinset[#1]%
+ {\expandedaction\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\processaction
+ \else
+ \expandafter\processallactionsinsetindeed
+ \fi
+ [#1]}
+
+\def\processallactionsinsetindeed[#1]#2[#3]%
+ {\advance\processlevel \plusone
+ \expandafter\def\csname\s!do\the\processlevel\endcsname##1%
+ {\def\p!dodoprocessaction####1%
+ {\p!compareprocessactionD[####1][##1]}%
+ \processcommalist[#3]\p!dodoprocessaction}%
+ \processcommalist[#1]\doprocessallactionsinset
+ \advance\processlevel \minusone
+ \expandactions}
+
+%D These macros use:
+
+\def\processnextcommalist#1#2#3[#4#5]%
+ {#1%
+ \let\nexttoken#4%
+ \global\advance\commalevel \plusone
+ \long\expandafter\def\csname\s!next\the\commalevel\endcsname##1,%
+ {#3{##1}\doprocesscommaitem}%
+ \dodoprocesscommaitem#4#5,]\relax
+ \global\advance\commalevel \minusone
+ #2}
+
+%D \macros
+%D {unexpandedprocessaction,
+%D unexpandedprocessfirstactioninset,
+%D unexpandedprocessallactionsinset}
+%D
+%D Now what are those expansion commands doing there. Well,
+%D sometimes we want to compare actions that may consist off
+%D commands (i.e. are no constants). In such occasions we can
+%D use the a bit slower alternatives:
+
+\def\unexpandedprocessfirstactioninset{\dontexpandactions\processfirstactioninset}
+\def\unexpandedprocessaction {\dontexpandactions\processaction}
+\def\unexpandedprocessallactionsinset {\dontexpandactions\processallactionsinset}
+
+%D By default we expand actions:
+
+\def\expandactions{\let\expandedaction\edef} \expandactions
+
+%D But when needed we convert the strings to meaningful
+%D sequences of characters.
+
+\def\unexpandedaction#1>{}
+
+\def\noexpandedaction#1#2%
+ {\def\@@convertedargument{#2}%
+ \@EA\edef\@EA#1\@EA{\@EA\unexpandedaction\meaning\@@convertedargument}}
+
+\def\dontexpandactions
+ {\let\expandedaction\noexpandedaction}
+
+%D \macros
+%D {getfirstcharacter, firstcharacter, remainingcharacters, doiffirstcharacter}
+%D
+%D Sometimes the action to be undertaken depends on the
+%D next character. This macro get this character and puts it in
+%D \type{\firstcharacter}.
+%D
+%D \starttyping
+%D \getfirstcharacter {string}
+%D \stoptyping
+%D
+%D A two step expansion is used to prevent problems with
+%D complicated arguments, for instance arguments that
+%D consist of two or more expandable tokens.
+
+\def\dogetfirstcharacter#1#2\relax
+ {\def\firstcharacter{#1}%
+ \def\remainingcharacters{#2}}
+
+\def\getfirstcharacter#1%
+ {\edef\!!stringa{#1}%
+ \expandafter\dogetfirstcharacter\!!stringa\relax}
+
+\def\doiffirstcharelse#1#2% char string
+% kort (maar onleesbaar)
+% {\expanded{\dogetfirstcharacter#2}\\\doifelse{#1}\firstcharacter}
+% korter (en begrijpelijk))
+ {\getfirstcharacter{#2}\doifelse{#1}\firstcharacter}
+% snel (maar zelden gebruikt, dus niet zo belangrijk)
+% {\getfirstcharacter{#2}%
+% \edef\!!stringa{#1}%
+% \ifx\!!stringa\firstcharacter
+% \expandafter\firstoftwoarguments
+% \else
+% \expandafter\secondoftwoarguments
+% \fi}
+
+%D \macros
+%D {doifinstringelse, doifincsnameelse}
+%D
+%D We can check for the presence of a substring in a given
+%D sequence of characters.
+%D
+%D \starttyping
+%D \doifinsetelse {substring} {string} {then ...} {else ...}
+%D \stoptyping
+
+\long\def\doifinstringelse#1%
+ {\edef\@@@instring{#1}% expand #1 here
+ \ifx\@@@instring\empty
+ \@EA\thirdofthreearguments
+ \else
+ \@EA\dodoifinstringelse
+ \fi}
+
+\long\def\dodoifinstringelse#1%
+ {\p!doifinstringelse\@@@instring{#1}%
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\long\def\doifinstring#1%%
+ {\edef\@@@instring{#1}% expand #1 here
+ \ifx\@@@instring\empty
+ \@EA\gobbletwoarguments
+ \else
+ \@EA\dodoifinstring
+ \fi}
+
+\long\def\dodoifinstring#1%
+ {\p!doifinstringelse\@@@instring{#1}%
+ \@EA\firstofoneargument
+ \else
+ \@EA\gobbleoneargument
+ \fi}
+
+\long\def\doifnotinstring#1%%
+ {\edef\@@@instring{#1}% expand #1 here
+ \ifx\@@@instring\empty
+ \@EA\gobbletwoarguments
+ \else
+ \@EA\dodoifnotinstring
+ \fi}
+
+\long\def\dodoifnotinstring#1%
+ {\p!doifinstringelse\@@@instring{#1}%
+ \@EA\gobbleoneargument
+ \else
+ \@EA\firstofoneargument
+ \fi}
+
+% replaces prev
+
+% \long\def\p!doifinstringelse#1#2% ##2 can be {abc}
+% {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here
+% \expanded{\pp!doifinstringelse#2#1}@@\war} % expand #2 here
+
+\long\def\p!doifinstringelse#1#2% ##2 can be {abc}
+ {\long\@EA\def\@EA\pp!doifinstringelse\@EA##\@EA1#1##2##3\war{\unless\if##2@}% expand #1 here
+ \expandafter\pp!doifinstringelse\normalexpanded{#2#1}@@\war} % expand #2 here
+
+% faster but at some costs
+%
+% \def\setp!doifinstringelse#1#2% ##2 can be {abc}
+% {\long\expandafter\gdef\csname @diie:#1\@EA\endcsname\@EA##\@EA1#1##2##3\war{\unless\if##2@}}% expand #1 here
+%
+% \long\def\p!doifinstringelse#1#2% ##2 can be {abc}
+% {\ifcsname @diie:#1\endcsname \else
+% \setp!doifinstringelse{#1}{#2}%
+% \fi
+% \csname @diie:#1\expandafter\endcsname\normalexpanded{#2#1}@@\war} % expand #2 here
+
+%D The next alternative proved to be upto twice as fast on
+%D tasks like checking reserved words in pretty verbatim
+%D typesetting! This is mainly due to the fact that passing
+%D (expanded) strings is much slower that passing a macro.
+%D
+%D \starttyping
+%D \doifincsnameelse {substring} {\string} {then ...} {else ...}
+%D \stoptyping
+%D
+%D Where \type{\doifinstringelse} does as much expansion as
+%D possible, the latter alternative does minimal (one level)
+%D expansion.
+
+\long\def\p!doifincsnameelse#1#2%
+ {\long\def\pp!doifincsnameelse##1#1##2##3\war
+ {\unless\if##2@}%
+ \@EA\pp!doifincsnameelse#2#1@@\war}
+
+\long\def\doifincsnameelse#1#2% % #3#4%
+ {\edef\@@@instring{#1}%
+ \@EA\p!doifincsnameelse\@EA{\@@@instring}{#2}% % #3\else#4\fi}
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doifnumberelse}
+%D
+%D The next macro executes a command depending of the outcome
+%D of a test on numerals. This is probably one of the fastest
+%D test possible, exept from a less robust 10||step
+%D \type{\if}||ladder or some tricky \type{\lcode} checking.
+%D
+%D \starttyping
+%D \doifnumberelse {string} {then ...} {else ...}
+%D \stoptyping
+%D
+%D The macro accepts \type{123}, \type{abc}, \type{{}},
+%D \type{\getal} and \type{\the\count...}. This macro is a
+%D rather dirty one.
+
+\long\def\doifnumberelse#1% does not accept counters
+ {\ifcase0\ifcase1#1\or\or\or\or\or\or\or\or\or\else1\fi\space
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+%D \macros
+%D {makerawcommalist,
+%D rawdoinsetelse,
+%D rawprocesscommalist,
+%D rawprocessaction}
+%D
+%D Some of the commands mentioned earlier are effective but
+%D slow. When one is desperately in need of faster alternatives
+%D and when the conditions are predictable safe, the \type{\raw}
+%D alternatives come into focus. A major drawback is that
+%D they do not take \type{\c!constants} into account, simply
+%D because no expansion is done. This is no problem with
+%D \type{\rawprocesscommalist}, because this macro does not
+%D compare anything. Expandable macros are permitted as search
+%D string.
+%D
+%D \starttyping
+%D \makerawcommalist[string,string,...]\stringlist
+%D \rawdoifinsetelse{string}{string,...}{...}{...}
+%D \rawprocesscommalist[string,string,...]\commando
+%D \rawprocessaction[x][a=>\a,b=>\b,c=>\c]
+%D \stoptyping
+%D
+%D Spaces embedded in the list, for instance after commas,
+%D spoil the search process. The gain in speed depends on the
+%D length of the argument (the longer the argument, the less
+%D we gain).
+
+\def\makerawcommalist[#1]#2% use \processnext ... here
+ {\def\domakerawcommalist##1% we don't expand ##1
+ {\ifx#2\empty
+ \def#2{##1}%
+ \else
+ \@EA\def\@EA#2\@EA{#2,##1}%
+ \fi}%
+ \let#2\empty
+ \processcommalist[#1]\domakerawcommalist}
+
+\def\rawprocesscommaitem#1,#2% #2 eats up preceding space
+ {\if]#1\else
+ \csname\s!next\the\commalevel\endcsname{#1}%
+ \expandafter\rawprocesscommaitem
+ \fi#2}
+
+\def\rawprocesscommalist[#1]#2% accepteert ook [\cs]
+ {\global\advance\commalevel \plusone
+ \expandafter\let\csname\s!next\the\commalevel\endcsname#2%
+ \expandafter\rawprocesscommaitem#1,],% \relax
+ \global\advance\commalevel \minusone }
+
+\def\rawprocesscommacommand[#1]% not really needed
+ {\expanded{\rawprocesscommalist[#1]}}
+
+% \def\rawdoifinsetelse#1#2{\doifinstringelse{,#1,}{,#2,}}
+% \def\rawdoifinset #1#2{\doifinstring {,#1,}{,#2,}}
+
+\def\@@rawempty{,,}
+
+\long\def\rawdoifinsetelse#1%
+ {\edef\@@@instring{,#1,}% expand #1 here
+ \ifx\@@@instring\@@rawempty
+ \@EA\thirdofthreearguments
+ \else
+ \@EA\rawdodoifinsetelse
+ \fi}
+
+\long\def\rawdodoifinsetelse#1%
+ {\p!doifinstringelse\@@@instring{,#1,}%
+ \@EA\firstoftwoarguments
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
+\long\def\rawdoifinset#1%
+ {\edef\@@@instring{,#1,}% expand #1 here
+ \ifx\@@@instring\@@rawempty
+ \@EA\gobbletwoarguments
+ \else
+ \@EA\rawdodoifinset
+ \fi}
+
+\long\def\rawdodoifinset#1%%
+ {\p!doifinstringelse\@@@instring{,#1,}%
+ \@EA\firstofoneargument
+ \else
+ \@EA\gobbleoneargument
+ \fi}
+
+%D Some more raw material:
+
+\def\p!rawprocessaction[#1][#2]%
+ {\def\pp!rawprocessaction##1,#1=>##2,##3\war%
+ {\if##3@\else
+ \def\!!processaction{##2}%
+ \fi}%
+ \pp!rawprocessaction,#2,#1=>,@\war}
+
+\def\rawprocessaction[#1]#2[#3]%
+ {\edef\!!stringa{#1}%
+ \edef\!!stringb{undefined}% better \!!undefined
+ \let\!!processaction\!!stringb
+ \ifx\!!stringa\empty
+ \@EA\p!rawprocessaction\@EA[\s!default][#3]%
+ \else
+ \expandafter\p!rawprocessaction\expandafter[\!!stringa][#3]%
+ \ifx\!!processaction\!!stringb
+ \@EA\p!rawprocessaction\@EA[\s!unknown][#3]%
+ \fi
+ \fi
+ \ifx\!!processaction\!!stringb
+ \else
+ \!!processaction
+ \fi}
+
+%D When we process the list \type{a,b,c,d,e}, the raw routine
+%D takes over 30\% less time, when we feed $20+$ character
+%D strings we gain about 20\%. Alternatives which use
+%D \type{\futurelet} perform worse. Part of the speedup is
+%D due to the \type{\let} and \type{\expandafter} in the test.
+
+%D \macros
+%D {dosetvalue,dosetevalue,dosetgvalue,docopyvalue,doresetvalue,
+%D dogetvalue}
+%D
+%D When we are going to do assignments, we have to take
+%D multi||linguality into account. For the moment we keep
+%D things simple and single||lingual.
+%D
+%D \starttyping
+%D \dosetvalue {label} {variable} {value}
+%D \dosetevalue {label} {variable} {value}
+%D \dosetgvalue {label} {variable} {value}
+%D \docopyvalue {to label} {from label} {variable}
+%D \doresetvalue {label} {variable}
+%D \stoptyping
+%D
+%D These macros are in fact auxiliary ones and are not meant
+%D for use outside the assignment macros.
+
+\def\dosetvalue#1#2% #3
+ {\@EA\def\csname#1#2\endcsname} % {#3}}
+
+\def\dosetevalue#1#2% #3
+ {\@EA\edef\csname#1#2\endcsname} % {#3}}
+
+\def\dosetgvalue#1#2% #3
+ {\@EA\gdef\csname#1#2\endcsname} % {#3}}
+
+\def\doresetvalue#1#2%
+ {\@EA\let\csname#1#2\endcsname\empty}
+
+\def\doignorevalue#1#2#3%
+ {\@EA\let\csname#1#2\endcsname\empty}
+
+\def\docopyvalue#1#2#3%
+ {\@EA\def\csname#1#3\endcsname{\csname#2#3\endcsname}}
+
+%D \macros
+%D {doassign,undoassign,doassignempty}
+%D
+%D Assignments are the backbone of \CONTEXT. Abhorred by the
+%D concept of style file hacking, we took a considerable effort
+%D in building a parameterized system. Unfortunately there is a
+%D price to pay in terms of speed. Compared to other packages
+%D and taking the functionality of \CONTEXT\ into account, the
+%D total size of the format file is still very acceptable. Now
+%D how are these assignments done.
+%D
+%D Assignments can be realized with:
+%D
+%D \starttyping
+%D \doassign[label][variable=value]
+%D \undoassign[label][variable=value]
+%D \stoptyping
+%D
+%D and:
+%D
+%D \starttyping
+%D \doassignempty[label][variable=value]
+%D \stoptyping
+%D
+%D Assignments like \type{\doassign} are compatible with:
+%D
+%D \starttyping
+%D \def\labelvariable{value}
+%D \stoptyping
+%D
+%D We do check for the presence of an \type{=} and loudly
+%D complain of it's missed. We will redefine this macro later
+%D on, when a more advanced message mechanism is implemented.
+
+\newif\iferrorisfatal
+
+\def\waitonfatalerror
+ {\iferrorisfatal\wait\fi}
+
+\def\showassignerror#1#2%
+ {\writestatus{setup}{missing or ungrouped '=' after '#1' in line #2}%
+ \waitonfatalerror}
+
+\def\doassignempty[#1][#2=#3]%
+ {\ifcsname#1#2\endcsname\else\dosetvalue{#1}{#2}{#3}\fi}
+
+%D \macros
+%D {getparameters,geteparameters,getgparameters,
+%D forgetparameters}
+%D
+%D Using the assignment commands directly is not our
+%D ideal of user friendly interfacing, so we take some further
+%D steps.
+%D
+%D \starttyping
+%D \getparameters [label] [...=...,...=...]
+%D \forgetparameters [label] [...=...,...=...]
+%D \stoptyping
+%D
+%D Again, the label identifies the category a variable
+%D belongs to. The second argument can be a comma separated
+%D list of assignments.
+%D
+%D \starttyping
+%D \getparameters
+%D [demo]
+%D [alfa=1,
+%D beta=2]
+%D \stoptyping
+%D
+%D is equivalent to
+%D
+%D \starttyping
+%D \def\demoalfa{1}
+%D \def\demobeta{2}
+%D \stoptyping
+%D
+%D
+%D In the pre||multi||lingual stadium \CONTEXT\ took the next
+%D approach. With
+%D
+%D \starttyping
+%D \def\??demo {@@demo}
+%D \def\!!alfa {alfa}
+%D \def\!!beta {beta}
+%D \stoptyping
+%D
+%D calling
+%D
+%D \starttyping
+%D \getparameters
+%D [\??demo]
+%D [\!!alfa=1,
+%D \!!beta=2]
+%D \stoptyping
+%D
+%D lead to:
+%D
+%D \starttyping
+%D \def\@@demoalfa{1}
+%D \def\@@demobeta{2}
+%D \stoptyping
+%D
+%D Because we want to be able to distinguish the \type{!!}
+%D pre||tagged user supplied variables from internal
+%D counterparts, we will introduce a slightly different tag in
+%D the multi||lingual modules. There we will use \type{c!} or
+%D \type{v!}, depending on the context.
+%D
+%D By calling \type{\p!doassign} directly, we save ourselves
+%D some argument passing and gain some speed. Whatever
+%D optimizations we do, this command will always be one of the
+%D bigger bottlenecks.
+%D
+%D The alternative \type{\geteparameters} --- it's funny to
+%D see that this alternative saw the light so lately --- can be
+%D used to do expanded assigments.
+
+\let\currentvalue\empty
+
+\def\getparameters {\dogetparameters\dosetvalue}
+\def\geteparameters {\dogetparameters\dosetevalue}
+\def\getgparameters {\dogetparameters\dosetgvalue}
+\def\forgetparameters{\dogetparameters\doignorevalue}
+
+\let\getexpandedparameters=\geteparameters
+
+% \def\dogetparameters#1[#2]#3[#4%
+% {\if\noexpand#4]%
+% \expandafter\gobbleoneargument
+% \else
+% \def\p!dogetparameter{\p!doassign#1#2}%
+% \expandafter\xdogetparameters
+% \fi#4}
+
+\def\dogetparameters#1[#2]#3[#4%
+ {\if\noexpand#4]%
+ \expandafter\gobbleoneargument
+ \else
+ \let\setsomevalue#1%
+ \def\p!dogetparameter{\p!doassign#2}%
+ \expandafter\xdogetparameters
+ \fi#4}
+
+\def\xdogetparameters#1]%
+ {\xprocesscommaitem#1,],\@relax@}
+
+\long\def\xprocesscommaitem#1,#2% #2 takes space before ,
+ {\if,#1,% dirty trick for testing #1=empty
+ \@EA\xprocesscommaitem
+ \else\if]#1%
+ \@EAEAEA\gobbleoneargument
+ \else
+ \p!dogetparameter\@relax@#1==\empty\@relax@
+ \@EAEAEA\xprocesscommaitem
+ \fi\fi#2}
+
+\def\xshowassignerror#1#2#3%
+ {\showassignerror{#2}{\the\inputlineno\space(#1)}}
+
+% \def\p!n!doassign#1#2\@relax@#3=#4=#5#6\@relax@
+% {\ifx\empty#3\empty
+% \@EA\xshowassignerror
+% \else\ifx#5\empty
+% \@EAEAEA\xshowassignerror
+% \else
+% \@EAEAEA#1%
+% \fi\fi
+% {#2}{#3}{#4}}
+
+% \def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@
+% {\ifx\empty#3\empty
+% \@EA\xshowassignerror
+% \else\ifx#5\empty
+% \@EAEAEA\xshowassignerror
+% \else
+% \ifcsname#2#3\endcsname
+% \@EA\let\@EA\currentvalue\csname#2#3\endcsname
+% \else
+% \let\currentvalue\empty
+% \fi
+% \@EAEAEA#1%
+% \fi\fi
+% {#2}{#3}{#4}}
+
+\def\p!n!doassign#1\@relax@#2=#3=#4#5\@relax@
+ {\ifx\empty#2\empty
+ \@EA\xshowassignerror
+ \else\ifx#4\empty
+ \@EAEAEA\xshowassignerror
+ \else
+ \@EAEAEA\setsomevalue
+ \fi\fi
+ {#1}{#2}{#3}}
+
+
+\def\p!e!doassign#1\@relax@#2=#3=#4#5\@relax@
+ {\ifx\empty#2\empty
+ \@EA\xshowassignerror
+ \else\ifx#4\empty
+ \@EAEAEA\xshowassignerror
+ \else
+ \ifcsname#1#2\endcsname
+ \@EA\let\@EA\currentvalue\csname#1#2\endcsname
+ \else
+ \let\currentvalue\empty
+ \fi
+ \@EAEAEA\setsomevalue
+ \fi\fi
+ {#1}{#2}{#3}}
+
+\let\p!doassign\p!n!doassign
+
+% \def\doassign [#1][#2]{\p!doassign\dosetvalue #1\@relax@#2==\empty\@relax@}
+% \def\doeassign [#1][#2]{\p!doassign\dosetevalue #1\@relax@#2==\empty\@relax@}
+% \def\undoassign[#1][#2]{\p!doassign\doresetvalue#1\@relax@#2==\empty\@relax@}
+
+\def\doassign [#1][#2]{\let\setsomevalue\dosetvalue \p!doassign#1\@relax@#2==\empty\@relax@}
+\def\doeassign [#1][#2]{\let\setsomevalue\dosetevalue \p!doassign#1\@relax@#2==\empty\@relax@}
+\def\undoassign[#1][#2]{\let\setsomevalue\doresetvalue\p!doassign#1\@relax@#2==\empty\@relax@}
+
+%D \macros{currentvalue}
+%D
+%D Just in case a \type{\getparameter} argument itself ends up
+%D inside a \type{\write} or other expandable location, our
+%D new macro needs a default value.
+%D
+%D \starttyping
+%D \getparameters[xxx][aaa=bbb]\par
+%D \getparameters[xxx][=bbb]\par
+%D \getparameters[xxx][aaa=]\par
+%D \getparameters[xxx][=]\par
+%D \getparameters[xxx][aaa]\par
+%D \stoptyping
+
+%D \macros {expandparameters}
+%D
+%D Example usage:
+%D
+%D \startbuffer
+%D \getparameters[taco][name=taco]
+%D \convertcommand\taconame\to\ascii \ascii
+%D \expandparameters \getparameters[taco][name=\currentvalue\space hoekwater]
+%D \convertcommand\taconame\to\ascii \ascii
+%D \getparameters[taco][name=\currentvalue\space hoekwater]
+%D \convertcommand\taconame\to\ascii \ascii
+%D \stopbuffer
+%D
+%D \typebuffer
+%D \startlines
+%D \getbuffer
+%D \stoplines
+
+%D Here we hook in the code (beware, this is the optimized get **):
+
+\def\xdoget@n@parameters#1]%
+ {\xprocesscommaitem#1,],\@relax@}
+
+\def\xdoget@e@parameters#1]%
+ {\let\dosetnvalue\dosetvalue
+ \let\dosetvalue\dosetevalue
+ \let\p!doassign\p!e!doassign
+ \xprocesscommaitem#1,],\@relax@
+ \let\p!doassign\p!n!doassign
+ \let\dosetvalue\dosetnvalue
+ \let\xdogetparameters\xdoget@n@parameters
+ \let\currentvalue\empty}
+
+\let\xdogetparameters\xdoget@n@parameters % **
+
+\def\expandparameters{\let\xdogetparameters\xdoget@e@parameters}
+
+%D \macros
+%D {getemptyparameters}
+%D
+%D Sometimes we explicitly want variables to default to an
+%D empty string, so we welcome:
+%D
+%D \starttyping
+%D \getemptyparameters [label] [...=...,...=...]
+%D \stoptyping
+
+\def\getemptyparameters[#1]#2[#3]%
+ {\def\p!dogetemptyparameter##1{\doassignempty[#1][##1]}%
+ \processcommalist[#3]\p!dogetemptyparameter}
+
+%D \macros
+%D {copyparameters}
+%D
+%D Some \CONTEXT\ commands take their default setups from
+%D others. All commands that are able to provide backgounds
+%D or rules around some content, for instance default to the
+%D standard command for ruled boxes. Is situations like this
+%D we can use:
+%D
+%D \starttyping
+%D \copyparameters [to-label] [from-label] [name1,name2,...]
+%D \stoptyping
+%D
+%D For instance
+%D
+%D \starttyping
+%D \copyparameters
+%D [internal][external]
+%D [alfa,beta]
+%D \stoptyping
+%D
+%D Leads to:
+%D
+%D \starttyping
+%D \def\internalalfa {\externalalfa}
+%D \def\internalbeta {\externalbeta}
+%D \stoptyping
+%D
+%D By using \type{\docopyvalue} we've prepared this command
+%D for use in a multi||lingual environment.
+
+\def\copyparameters[#1]#2[#3]#4[#5]%
+ {\doifnot{#1}{#3}
+ {\def\docopyparameter{\docopyvalue{#1}{#3}}% ##1
+ \processcommalist[#5]\docopyparameter}}
+
+%D \macros
+%D {ifparameters,checkparameters}
+%D
+%D A slightly different one is \type{\checkparameters}, which
+%D also checks on the presence of a~\type{=}.
+%D
+%D The boolean \type{\ifparameters} can be used afterwards.
+%D Combining both in one \type{\if}||macro would lead to
+%D problems with nested \type{\if}'s.
+%D
+%D \starttyping
+%D \checkparameters[argument]
+%D \stoptyping
+
+\newif\ifparameters
+
+\def\p!checkparameters#1=#2#3\war%
+ {\if#2@\parametersfalse\else\parameterstrue\fi}
+
+\def\checkparameters[#1]%
+ {\p!checkparameters#1=@@\war}
+
+%D \macros
+%D {getfromcommalist,getfromcommacommand,
+%D commalistelement,
+%D getcommalistsize,getcommacommandsize}
+%D
+%D It's possible to get an element from a commalist or a
+%D command representing a commalist.
+%D
+%D \starttyping
+%D \getfromcommalist [string] [n]
+%D \getfromcommacommand [string,\strings,string,...] [n]
+%D \stoptyping
+%D
+%D The difference betwee the two of them is the same as the
+%D difference between \type{\processcomma...}. The found string
+%D is stored in \type{\commalistelement}.
+%D
+%D We can calculate the size of a comma separated list by
+%D using:
+%D
+%D \starttyping
+%D \getcommalistsize [string,string,...]
+%D \getcommacommandsize [string,\strings,string,...]
+%D \stoptyping
+%D
+%D Afterwards, the length is available in the macro
+%D \type{\commalistsize} (not a \COUNTER).
+
+\newcount\commalistcounter
+
+\def\commalistsize{0}
+
+\def\p!dogetcommalistsize#1%
+ {\advance\commalistcounter\plusone}
+
+\def\getcommalistsize#1]% don't loose [{#1}]
+ {\commalistcounter\zerocount
+ \processcommalist#1]\p!dogetcommalistsize % was [{#1}]
+ \edef\commalistsize{\the\commalistcounter}}
+
+\def\getcommacommandsize[#1]%
+ {\edef\commacommand{#1}%
+ \scratchtoks\expandafter{\expandafter[\commacommand]}%
+ \expandafter\getcommalistsize\the\scratchtoks }
+
+% to be tested first
+%
+% \def\getcommacommandsize[#1]%
+% {\expanded{\getcommalistsize[#1]}}
+
+% \def\p!dogetfromcommalist#1%
+% {\advance\commalistcounter \minusone
+% \ifcase\commalistcounter
+% \def\commalistelement{#1}%
+% \begingroup\def\doprocesscommaitem##1]{\endgroup}%
+% \fi}
+
+\def\p!dogetfromcommalist#1%
+ {\advance\commalistcounter \minusone
+ \ifcase\commalistcounter
+ \def\commalistelement{#1}%
+ \expandafter\quitcommalist
+ \fi}
+
+\def\getfromcommalist[#1]#2[#3]%
+ {\let\commalistelement\empty
+ \commalistcounter#3\relax
+ \processcommalist[#1]\p!dogetfromcommalist}
+
+\def\getfromcommacommand[#1]%
+ {\expanded{\getfromcommalist[#1]}}
+
+%D Watertight (and efficient) solutions are hard to find, due
+%D to the handling of braces during parameters passing and
+%D scanning. Nevertheless:
+%D
+%D \startbuffer
+%D \def\dosomething#1{(#1=\commalistsize) }
+%D
+%D \getcommalistsize [\hbox{$a,b,c,d,e,f$}] \dosomething 1
+%D \getcommalistsize [{a,b,c,d,e,f}] \dosomething 1
+%D \getcommalistsize [{a,b,c},d,e,f] \dosomething 4
+%D \getcommalistsize [a,b,{c,d,e},f] \dosomething 4
+%D \getcommalistsize [a{b,c},d,e,f] \dosomething 4
+%D \getcommalistsize [{a,b}c,d,e,f] \dosomething 4
+%D \getcommalistsize [] \dosomething 0
+%D \getcommalistsize [{[}] \dosomething 1
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D reports:
+%D
+%D \getbuffer
+
+%D \macros
+%D {dogetcommalistelement,dogetcommacommandelement}
+%D
+%D For low level (fast) purposes, we can also use the next
+%D alternative, which can handle 8~elements at most.
+%D
+%D \starttyping
+%D \dogetcommalistelement1\from a,b,c\to\commalistelement
+%D \stoptyping
+
+\def\dodogetcommalistelement#1\from#2,#3,#4,#5,#6,#7,#8\to#9%
+ {\edef#9{\ifcase#1\relax\or#2\or#3\or#4\or#5\or#6\or#7\or#8\fi}}
+
+\def\dogetcommalistelement#1\from#2\to%
+ {\dodogetcommalistelement#1\from#2,,,,,,\to}
+
+% check sources
+
+\def\dogetcommacommandelement#1\from#2\to%
+ {\@EA\dodogetcommalistelement\@EA#1\@EA\from#2,,,,,,\to}
+
+%D \macros
+%D {dosingleargument,dodoubleargument,dotripleargument,
+%D doquadrupleargument,doquintupleargument,dosixtupleargument,
+%D doseventupleargument}
+%D
+%D When working with delimited arguments, spaces and
+%D lineendings can interfere. The next set of macros uses
+%D \TEX' internal scanner for grabbing everything between
+%D arguments. Forgive me the funny names.
+%D
+%D \starttyping
+%D \dosingleargument\commando = \commando[#1]
+%D \dodoubleargument\commando = \commando[#1][#2]
+%D \dotripleargument\commando = \commando[#1][#2][#3]
+%D \doquadrupleargument\commando = \commando[#1][#2][#3][#4]
+%D \doquintupleargument\commando = \commando[#1][#2][#3][#4][#5]
+%D \dosixtupleargument\commando = \commando[#1][#2][#3][#4][#5][#6]
+%D \doseventupleargument\command = \commando[#1][#2][#3][#4][#5][#6][#7]
+%D \stoptyping
+%D
+%D These macros are used in the following way:
+%D
+%D \starttyping
+%D \def\dosetupsomething[#1][#2]%
+%D {... #1 ... #2 ...}
+%D
+%D \def\setupsomething
+%D {\dodoubleargument\dosetupsomething}
+%D \stoptyping
+%D
+%D The implementation can be surprisingly simple and needs no
+%D further explanation, like:
+%D
+%D \starttyping
+%D \def\dosingleargument#1[#2]%
+%D {#1[#2]}
+%D \def\dotripleargument#1[#2]#3[#4]#5[#6]%
+%D {#1[#2][#4][#6]}
+%D \def\doquintupleargument#1%
+%D {\def\dodoquintupleargument[##1]##2[##3]##4[##5]##6[##7]##8[##9]%
+%D {#1[##1][##3][##5][##7][##9]}%
+%D \dodoquintupleargument}
+%D \stoptyping
+%D
+%D Because \TEX\ accepts 9~arguments at most, we have to use
+%D two||step solution when getting five or more arguments.
+%D
+%D When developing more and more of the real \CONTEXT, we
+%D started using some alternatives that provided empty
+%D arguments (in fact optional ones) whenever the user failed
+%D to supply them. Because this more complicated macros enable
+%D us to do some checking, we reimplemented the non||empty
+%D ones.
+
+\def\dosingleargument {\let\expectedarguments\plusone \dosingleempty }
+\def\dodoubleargument {\let\expectedarguments\plustwo \dodoubleempty }
+\def\dotripleargument {\let\expectedarguments\plusthree \dotripleempty }
+\def\doquadrupleargument {\let\expectedarguments\plusfour \doquadrupleempty }
+\def\doquintupleargument {\let\expectedarguments\plusfive \doquintupleempty }
+\def\dosixtupleargument {\let\expectedarguments\plussix \dosixtupleempty }
+\def\doseventupleargument{\let\expectedarguments\plusseven \doseventupleempty}
+
+%D \macros
+%D {iffirstagument,ifsecondargument,ifthirdargument,
+%D iffourthargument,iffifthargument,ifsixthargument,
+%D ifseventhargument}
+%D
+%D We use some signals for telling the calling macros if all
+%D wanted arguments are indeed supplied by the user.
+
+\newif\iffirstargument
+\newif\ifsecondargument
+\newif\ifthirdargument
+\newif\iffourthargument
+\newif\iffifthargument
+\newif\ifsixthargument
+\newif\ifseventhargument
+
+%D \macros
+%D {dosingleempty,dodoubleempty,dotripleempty,
+%D doquadrupleempty,doquintupleempty,dosixtupeempty,
+%D doseventupleempty}
+%D
+%D The empty argument supplying macros mentioned before, look
+%D like:
+%D
+%D \starttyping
+%D \dosingleempty \command
+%D \dodoubleempty \command
+%D \dotripleempty \command
+%D \doquadrupleempty \command
+%D \doquintupleempty \command
+%D \dosixtupleempty \command
+%D \doseventupleempty\command
+%D \stoptyping
+%D
+%D So \type{\dodoubleempty} leades to:
+%D
+%D \starttyping
+%D \command[#1][#2]
+%D \command[#1][]
+%D \command[][]
+%D \stoptyping
+%D
+%D Depending of the generousity of the user. Afterwards one can
+%D use the \type{\if...argument} boolean. For novice: watch
+%D the stepwise doubling of \type{#}'s
+
+% idea: \ignorespaces afterwards
+
+\chardef\noexpectedarguments=0
+\chardef\expectedarguments =0
+
+\def\showargumenterror#1#2%
+ {\writestatus{systems}{\number#1 argument(s) expected in line #2}}
+
+\def\doshowargumenterror
+ {\ifnum\expectedarguments>\noexpectedarguments
+ \showargumenterror{\number\expectedarguments}{\number\inputlineno}%
+ \fi
+ \noshowargumenterror}
+
+\def\noshowargumenterror
+ {\let\expectedarguments\noexpectedarguments}
+
+\long\def\dogetargument#1#2#3#4%
+ {\let\charactertoken=#1%
+ \def\!!stringa{\noshowargumenterror#3\dodogetargument}%
+ \def\!!stringb{\doshowargumenterror#4\dodogetargument#1#2}%
+ \futurelet\nexttoken\inspectnextcharacter}
+
+\def\getsingleempty#1#2#3%
+ {\def\dodogetargument%
+ {#3}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\getdoubleempty#1#2#3%
+ {\def\dodogetargument#1##1#2%
+ {\def\dodogetargument%
+ {#3#1{##1}#2}%
+ \dogetargument#1#2\secondargumenttrue\secondargumentfalse}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\gettripleempty#1#2#3%
+ {\def\dodogetargument#1##1#2%
+ {\def\dodogetargument#1####1#2%
+ {\def\dodogetargument%
+ {#3#1{##1}#2%
+ #1{####1}#2}%
+ \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}%
+ \dogetargument#1#2\secondargumenttrue\secondargumentfalse}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\getquadrupleempty#1#2#3%
+ {\def\dodogetargument#1##1#2%
+ {\def\dodogetargument#1####1#2%
+ {\def\dodogetargument#1########1#2%
+ {\def\dodogetargument%
+ {#3#1{##1}#2%
+ #1{####1}#2%
+ #1{########1}#2}%
+ \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}%
+ \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}%
+ \dogetargument#1#2\secondargumenttrue\secondargumentfalse}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\getquintupleempty#1#2#3%
+ {\def\dodogetargument#1##1#2%
+ {\def\dodogetargument#1####1#2%
+ {\def\dodogetargument#1########1#2%
+ {\def\dodogetargument#1################1#2%
+ {\def\dodogetargument%
+ {#3#1{##1}#2%
+ #1{####1}#2%
+ #1{########1}#2%
+ #1{################1}#2}%
+ \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}%
+ \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}%
+ \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}%
+ \dogetargument#1#2\secondargumenttrue\secondargumentfalse}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\getsixtupleempty#1#2#3%
+ {\def\dodogetargument#1##1#2%
+ {\def\dodogetargument#1####1#2%
+ {\def\dodogetargument#1########1#2%
+ {\def\dodogetargument#1################1#2%
+ {\def\dodogetargument#1################################1#2%
+ {\def\dodogetargument%
+ {#3#1{##1}#2%
+ #1{####1}#2%
+ #1{########1}#2%
+ #1{################1}#2%
+ #1{################################1}#2}%
+ \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}%
+ \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}%
+ \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}%
+ \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}%
+ \dogetargument#1#2\secondargumenttrue\secondargumentfalse}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\getseventupleempty#1#2#3%
+ {\def\dodogetargument#1##1#2%
+ {\def\dodogetargument#1####1#2%
+ {\def\dodogetargument#1########1#2%
+ {\def\dodogetargument#1################1#2%
+ {\def\dodogetargument#1################################1#2%
+ {\def\dodogetargument#1################################%
+ ################################1#2%
+ {\def\dodogetargument%
+ {#3#1{##1}#2%
+ #1{####1}#2%
+ #1{########1}#2%
+ #1{################1}#2%
+ #1{################################1}#2%
+ #1{################################%
+ ################################1}#2}%
+ \dogetargument#1#2\seventhargumenttrue\seventhargumentfalse}%
+ \dogetargument#1#2\sixthargumenttrue\sixthargumentfalse}%
+ \dogetargument#1#2\fifthargumenttrue\fifthargumentfalse}%
+ \dogetargument#1#2\fourthargumenttrue\fourthargumentfalse}%
+ \dogetargument#1#2\thirdargumenttrue\thirdargumentfalse}%
+ \dogetargument#1#2\secondargumenttrue\secondargumentfalse}%
+ \dogetargument#1#2\firstargumenttrue\firstargumentfalse}
+
+\def\dosingleempty {\getsingleempty []}
+\def\dodoubleempty {\getdoubleempty []}
+\def\dotripleempty {\gettripleempty []}
+\def\doquadrupleempty {\getquadrupleempty []}
+\def\doquintupleempty {\getquintupleempty []}
+\def\dosixtupleempty {\getsixtupleempty []}
+\def\doseventupleempty{\getseventupleempty[]}
+
+%D Because some of these are called quite often, we will now
+%D replace the more general version by alternatives tuned for
+%D speed.
+
+\def\dosingleempty#1%
+ {\noshowargumenterror % \relax % prevents lookahead, brr
+ \doifnextoptionalelse
+ {\firstargumenttrue#1}
+ {\dosinglefakeempty#1}}
+
+\def\dodoubleempty#1%
+ {\noshowargumenterror % \relax % prevents lookahead, brr
+ \doifnextoptionalelse
+ {\dodoubletestempty#1}
+ {\dodoublefakeempty#1}}
+
+\def\dotripleempty#1%
+ {\noshowargumenterror % \relax % prevents lookahead, brr
+ \doifnextoptionalelse
+ {\dotripletestempty#1}
+ {\dotriplefakeempty#1}}
+
+\def\dosinglefakeempty#1%
+ {\firstargumentfalse#1[]}
+
+\def\dodoublefakeempty#1%
+ {\firstargumentfalse\secondargumentfalse#1[][]}
+
+\def\dotriplefakeempty#1%
+ {\firstargumentfalse\secondargumentfalse\thirdargumentfalse#1[][][]}
+
+\long\def\dodoubletestempty#1[#2]%
+ {\firstargumenttrue
+ \doifnextoptionalelse
+ {\secondargumenttrue #1[{#2}]}
+ {\secondargumentfalse#1[{#2}][]}}
+
+\long\def\dotripletestempty#1[#2]%
+ {\firstargumenttrue
+ \doifnextoptionalelse
+ {\dotripletestemptyx #1[{#2}]}
+ {\secondargumentfalse
+ \thirdargumentfalse #1[{#2}][][]}}
+
+\long\def\dotripletestemptyx#1[#2][#3]%
+ {\secondargumenttrue
+ \doifnextoptionalelse
+ {\thirdargumenttrue #1[{#2}][{#3}]}
+ {\thirdargumentfalse#1[{#2}][{#3}][]}}
+
+%D \macros
+%D {strippedcsname}
+%D
+%D The next macro can be very useful when using \type{\csname}
+%D like in:
+%D
+%D \starttyping
+%D \csname if\strippedcsname\something\endcsname
+%D \stoptyping
+%D
+%D This expands to \type{\ifsomething}.
+
+\def\strippedcsname
+ {\expandafter\gobbleoneargument\string}
+
+%D \macros
+%D {complexorsimple,complexorsimpleempty}
+%D
+%D Setups can be optional. A command expecting a setup is
+%D prefixed by \type{\complex}, a command without one gets the
+%D prefix \type{\simple}. Commands like this can be defined by:
+%D
+%D \starttyping
+%D \complexorsimple\command
+%D \stoptyping
+%D
+%D When \type{\command} is followed by a \type{[setup]}, then
+%D
+%D \starttyping
+%D \complexcommand [setup]
+%D \stoptyping
+%D
+%D executes, else we get
+%D
+%D \starttyping
+%D \simplecommand
+%D \stoptyping
+%D
+%D An alternative for \type{\complexorsimple} is:
+%D
+%D \starttyping
+%D \complexorsimpleempty {command}
+%D \stoptyping
+%D
+%D Depending on the presence of \type{[setup]}, this one
+%D leads to one of:
+%D
+%D \starttyping
+%D \complexcommando [setup]
+%D \complexcommando []
+%D \stoptyping
+%D
+%D Many \CONTEXT\ commands started as complex or simple ones,
+%D but changed into more versatile (more object oriented) ones
+%D using the \type{\get..argument} commands.
+
+\def\complexorsimple#1%
+ {% \relax % prevents lookahead, brrr
+ \doifnextoptionalelse
+ {\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname}
+ {\firstargumentfalse\csname\s!simple \strippedcsname#1\endcsname}}
+
+\def\complexorsimpleempty#1%
+ {% \relax % prevents lookahead, brrr
+ \doifnextoptionalelse
+ {\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname}
+ {\firstargumentfalse\csname\s!complex\strippedcsname#1\endcsname[]}}
+
+%D \macros
+%D {definecomplexorsimple,definecomplexorsimpleempty}
+%D
+%D The previous commands are used that often that we found it
+%D worthwile to offer two more alternatives. Watch the build
+%D in protection.
+
+\def\docomplexorsimple#1#2%
+ {\doifnextoptionalelse{\firstargumenttrue#1}{\firstargumentfalse#2}}
+
+\def\docomplexorsimpleempty#1%
+ {\doifnextoptionalelse{\firstargumenttrue#1}{\firstargumentfalse#1[]}}
+
+\def\definecomplexorsimple#1%
+ {\unexpanded\edef#1%
+ {\noexpand\docomplexorsimple
+ \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname
+ \@EA\noexpand\csname\s!simple \strippedcsname#1\endcsname}}
+
+\def\definecomplexorsimpleempty#1%
+ {\unexpanded\edef#1%
+ {\noexpand\docomplexorsimpleempty
+ \@EA\noexpand\csname\s!complex\strippedcsname#1\endcsname}}
+
+%D These commands are called as:
+%D
+%D \starttyping
+%D \definecomplexorsimple\command
+%D \stoptyping
+%D
+%D Of course, we must have available
+%D
+%D \starttyping
+%D \def\complexcommand[#1]{...}
+%D \def\simplecommand {...}
+%D \stoptyping
+%D
+%D Using this construction saves a few string now and then.
+
+%D \macros
+%D {dosinglegroupempty,dodoublegroupempty,dotriplegroupempty,
+%D doquadruplegroupempty, doquintuplegroupempty}
+%D
+%D We've already seen some commands that take care of
+%D optional arguments between \type{[]}. The next two commands
+%D handle the ones with \type{{}}. They are called as:
+%D
+%D \starttyping
+%D \dosinglegroupempty \ineedONEargument
+%D \dodoublegroupempty \ineedTWOarguments
+%D \dotriplegroupempty \ineedTHREEarguments
+%D \doquadruplegroupempty \ineedFOURarguments
+%D \doquintuplegroupempty \ineedFIVEarguments
+%D \stoptyping
+
+%D We can add additional definitions later when we have defined
+%D \type {\appendtoks}.
+
+\def \permitspacesbetweengroups{\let\@@permitspacesbetweengroups\zerocount}
+\def\dontpermitspacesbetweengroups{\let\@@permitspacesbetweengroups\plusone}
+
+\dontpermitspacesbetweengroups
+
+%D We can avoid the nasty if handling in \type {syst-gen} by splitting
+%D the lot in pieces so that we have no nested \type {\nextarguments}
+%D potentially being an \type {conditional} token. Okay, these macros
+%D are not called that often but it saves crap when tracing.
+
+\def\dogetgroupargument#1#2%
+ {\let\dogroupargumentyes#1%
+ \let\dogroupargumentnop#2%
+ \futurelet\nextargument\dodogetgroupargument}
+
+\def\dodogetgroupargument
+ {\ifx\nextargument\bgroup
+ \expandafter\dodogetgroupargumentA
+ \else
+ \expandafter\dodogetgroupargumentB
+ \fi}
+
+\def\dodogetgroupargumentA
+ {\noshowargumenterror
+ \dogroupargumentyes\dodogetargument}
+
+\def\dodogetgroupargumentB
+ {\ifcase\@@permitspacesbetweengroups
+ \expandafter\dodogetgroupargumentC
+ \else
+ \expandafter\dodogetgroupargumentD
+ \fi}
+
+\def\dodogetgroupargumentC
+ {\ifx\nextargument\lineending
+ \expandafter\dodogetgroupargumentE
+ \else
+ \expandafter\dodogetgroupargumentF
+ \fi}
+
+\def\dodogetgroupargumentD
+ {\doshowargumenterror
+ \dogroupargumentnop\dodogetargument{}}
+
+\def\dodogetgroupargumentE
+ {\begingroup\def\\ {\endgroup\dogetgroupargument\dogroupargumentyes\dogroupargumentnop}\\}
+
+\def\dodogetgroupargumentF
+ {\ifx\nextargument\blankspace
+ \expandafter\dodogetgroupargumentE % G
+ \else
+ \expandafter\dodogetgroupargumentD % H
+ \fi}
+
+\def\dogetgroupargument#1#2%
+ {\let\dogroupargumentyes#1%
+ \let\dogroupargumentnop#2%
+ \futurelet\nextargument\dodogetgroupargument}
+
+\def\dosinglegroupempty#1%
+ {\def\dodogetargument%
+ {\dontpermitspacesbetweengroups
+ #1}%
+ \dogetgroupargument\firstargumenttrue\firstargumentfalse}
+
+\def\dodoublegroupempty#1%
+ {\def\dodogetargument##1%
+ {\def\dodogetargument%
+ {\dontpermitspacesbetweengroups
+ #1{##1}}%
+ \dogetgroupargument\secondargumenttrue\secondargumentfalse}%
+ \dogetgroupargument\firstargumenttrue\firstargumentfalse}
+
+\def\dotriplegroupempty#1%
+ {\def\dodogetargument##1%
+ {\def\dodogetargument####1%
+ {\def\dodogetargument%
+ {\dontpermitspacesbetweengroups
+ #1{##1}{####1}}%
+ \dogetgroupargument\thirdargumenttrue\thirdargumentfalse}%
+ \dogetgroupargument\secondargumenttrue\secondargumentfalse}%
+ \dogetgroupargument\firstargumenttrue\firstargumentfalse}
+
+\def\doquadruplegroupempty#1%
+ {\def\dodogetargument##1%
+ {\def\dodogetargument####1%
+ {\def\dodogetargument########1%
+ {\def\dodogetargument%
+ {\dontpermitspacesbetweengroups
+ #1{##1}{####1}{########1}}%
+ \dogetgroupargument\fourthargumenttrue\fourthargumentfalse}%
+ \dogetgroupargument\thirdargumenttrue\thirdargumentfalse}%
+ \dogetgroupargument\secondargumenttrue\secondargumentfalse}%
+ \dogetgroupargument\firstargumenttrue\firstargumentfalse}
+
+\def\doquintuplegroupempty#1%
+ {\def\dodogetargument##1%
+ {\def\dodogetargument####1%
+ {\def\dodogetargument########1%
+ {\def\dodogetargument################1%
+ {\def\dodogetargument%
+ {\dontpermitspacesbetweengroups
+ #1{##1}{####1}{########1}{################1}}%
+ \dogetgroupargument\fifthargumenttrue\fifthargumentfalse}%
+ \dogetgroupargument\fourthargumenttrue\fourthargumentfalse}%
+ \dogetgroupargument\thirdargumenttrue\thirdargumentfalse}%
+ \dogetgroupargument\secondargumenttrue\secondargumentfalse}%
+ \dogetgroupargument\firstargumenttrue\firstargumentfalse}
+
+%D These macros can explictly take care of spaces, which means
+%D that the next definition and calls are valid:
+%D
+%D \starttyping
+%D \def\test#1#2#3{[#1#2#3]}
+%D
+%D \dotriplegroupempty\test {a}{b}{c}
+%D \dotriplegroupempty\test {a}{b}
+%D \dotriplegroupempty\test {a}
+%D \dotriplegroupempty\test
+%D \dotriplegroupempty\test {a} {b} {c}
+%D \dotriplegroupempty\test {a} {b}
+%D \dotriplegroupempty\test
+%D {a}
+%D {b}
+%D \stoptyping
+%D
+%D And alike.
+
+%D \macros
+%D {firstofoneargument, firstoftwoarguments, firstofthreearguments
+%D secondoftwoarguments, secondofthreearguments,
+%D thirdofthreearguments}
+%D
+%D The next six macros (dedicated to Taco) can conveniently
+%D used to select arguments. Their names explain their
+%D functionality.
+
+\long\def\firstofoneargument #1{#1}
+
+\long\def\firstoftwoarguments #1#2{#1}
+\long\def\secondoftwoarguments #1#2{#2}
+
+\long\def\firstofthreearguments #1#2#3{#1}
+\long\def\secondofthreearguments #1#2#3{#2}
+\long\def\thirdofthreearguments #1#2#3{#3}
+
+\long\def\firstoffourarguments #1#2#3#4{#1}
+\long\def\secondoffourarguments #1#2#3#4{#2}
+\long\def\thirdoffourarguments #1#2#3#4{#3}
+\long\def\fourthoffourarguments #1#2#3#4{#4}
+
+\long\def\firstoffivearguments #1#2#3#4#5{#1}
+\long\def\secondoffivearguments #1#2#3#4#5{#2}
+\long\def\thirdoffivearguments #1#2#3#4#5{#3}
+\long\def\fourthoffivearguments #1#2#3#4#5{#4}
+\long\def\fifthoffivearguments #1#2#3#4#5{#5}
+
+\long\def\firstofsixarguments #1#2#3#4#5#6{#1}
+\long\def\secondofsixarguments#1#2#3#4#5#6{#2}
+\long\def\thirdofsixarguments #1#2#3#4#5#6{#3}
+\long\def\fourthofsixarguments#1#2#3#4#5#6{#4}
+\long\def\fifthofsixarguments #1#2#3#4#5#6{#5}
+\long\def\sixthofsixarguments #1#2#3#4#5#6{#6}
+
+%D \macros
+%D {globalletempty,letempty,letvalueempty,letgvalueempty}
+%D
+%D Trivial:
+
+\def\letempty #1{\let#1\empty}
+\def\globalletempty#1{\global\let#1\empty}
+
+\def\letvalueempty #1{\expandafter\let\csname#1\endcsname\empty}
+\def\letgvalueempty#1{\global\expandafter\let\csname#1\endcsname\empty}
+
+%D \macros
+%D {wait}
+%D
+%D The next macro hardly needs explanation. Because no
+%D nesting is to be expected, we can reuse \type{\wait} within
+%D \type{\wait} itself.
+
+\def\wait
+ {\begingroup
+ \read16 to \wait
+ \endgroup}
+
+%D \macros
+%D {writestring,writeline,writebanner,
+%D writestatus,statuswidth,normalwritestatus}
+%D
+%D Maybe one didn't notice, but we've already introduced a
+%D macro for showing messages. In the multi||lingual modules,
+%D we will also introduce a mechanism for message passing. For
+%D the moment we stick to the core macros:
+%D
+%D \starttyping
+%D \writestring {string}
+%D \writeline
+%D \writestatus {category} {message}
+%D \stoptyping
+%D
+%D Messages are formatted. One can provide the maximum with
+%D of the identification string with the macro \type
+%D {\statuswidth}.
+
+\chardef\statuswidth=15
+\chardef\statuswrite=16
+
+\ifdefined\writestring \else
+
+ \newtoks\everywritestring
+
+ \def\writedirect {\immediate\write\statuswrite}
+ \def\writeline {\writedirect{}}
+ \def\writestring#1{\begingroup\the\everywritestring\writedirect{#1}\endgroup}
+
+\fi
+
+\def\normalwritestatus#1#2%
+ {\writestring{\expandafter\dosplitstatus\expandafter\statuswidth#1%
+ \space\space\space\space\space\space\space
+ \space\space\space\space\space\space\space
+ \space\space\space\space\space\space\end
+ \space:\space#2}}
+
+\def\dosplitstatus#1#2%
+ {\ifcase#1 \expandafter\nosplitstatus\fi#2%
+ \expandafter\dosplitstatus\expandafter{\the\numexpr#1+\minusone\relax}}
+
+\def\nosplitstatus#1\end
+ {}
+
+%D \macros
+%D {debuggerinfo}
+%D
+%D For debugging purposes we can enhance macros with the
+%D next alternative. Here \type{debuggerinfo} stands for both
+%D a macro accepting two arguments and a boolean (in fact a
+%D few macro's too).
+
+\newif\ifdebuggerinfo
+
+\def\debuggerinfo#1#2%
+ {\ifdebuggerinfo
+ \writestatus{debugger}{#1:: #2}%
+ \fi}
+
+\ifdefined\writestatus \else \let\writestatus\normalwritestatus \fi
+\ifdefined\writebanner \else \def\writebanner{\writestring} \fi
+
+% % % % % % % % % % % % % % % % % % % % % % % %
+
+%D \macros
+%D {rawgetparameters}
+%D
+%D A raw and dirty alternative for \type {\getparameters}; no
+%D checking is done!
+
+\def\rawsetparameter#1=#2,%
+ {\if]#1\else
+ \expandafter\def\csname\rawparameterprefix#1\endcsname{#2}%
+ \expandafter\rawsetparameter
+ \fi}
+
+\def\rawgetparameters[#1][#2% some 5-10% faster
+ {\ifx#2]% test is needed, else bomb on [#1][]
+ \expandafter\gobbleoneargument
+ \else
+ \def\rawparameterprefix{#1}%
+ \expandafter\dorawgetparameters
+ \fi#2}
+
+\def\dorawgetparameters#1]%
+ {\expandafter\rawsetparameter#1,]=,}
+
+%D \macros
+%D {doglobal,
+%D redoglobal,dodoglobal,resetglobal}
+%D
+%D The two macros \type {\redoglobal} and \type{\dodoglobal} are
+%D used in this and some other modules to enforce a user
+%D specified \type {\doglobal} action. The last and often only
+%D global assignment in a macro is done with
+%D \type {\dodoglobal}, but all preceding ones with
+%D \type {\redoglobal}. When using only alternatives, one can
+%D reset this mechanism with \type {\resetglobal}.
+
+\def\resetglobal
+ {\let\redoglobal\relax
+ \let\dodoglobal\relax}
+
+\resetglobal
+
+\def\doglobal
+ {\ifx\redoglobal\relax
+ \let\redoglobal\global
+ \let\dodoglobal\@@dodoglobal
+ \fi}
+
+\def\@@dodoglobal
+ {\resetglobal\global}
+
+\def\saveglobal
+ {\let\@@dodoglobal\dodoglobal
+ \let\@@redoglobal\redoglobal}
+
+\def\restoreglobal
+ {\let\redoglobal\@@redoglobal
+ \let\dodoglobal\@@dodoglobal}
+
+%D A very useful application of this macro is \type {\newif},
+%D \TEX's fake boolean type. Not being a primitive,
+%D \type {\global} hopelessly fails here. But a slight
+%D adaption of Knuth's original macro permits:
+%D
+%D \starttyping
+%D \doglobal\newif\iftest
+%D \stoptyping
+%D
+%D Of course one can still say:
+%D
+%D \starttyping
+%D \global\testtrue
+%D \global\testfalse
+%D \stoptyping
+%D
+%D Apart from the prefixes, a few more \type{\expandafters}
+%D are needed:
+
+\def\newif#1%
+ {\scratchcounter\escapechar
+ \escapechar\minusone
+ \expandafter\expandafter\expandafter
+ \redoglobal\expandafter\expandafter\expandafter
+ \edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}%
+ \expandafter\expandafter\expandafter
+ \redoglobal\expandafter\expandafter\expandafter
+ \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}%
+ \dodoglobal\@if#1{false}%
+ \escapechar\scratchcounter}
+
+%D Also new:
+
+\def\define#1%
+ {\ifdefined#1%
+ \message{[\noexpand#1is already defined]}%
+ \expandafter\def\expandafter\gobbleddefinition
+ \else
+ \expandafter\def
+ \fi#1}
+
+\def\redefine#1%
+ {\ifdefined#1%
+ \message{[\noexpand#1is redefined]}%
+ \fi
+ \def#1}
+
+% \define\hans{hans}
+% \redefine\hans{hans}
+% \define\hans#1[]#2#3{hans}
+
+%D The next variant fits nicely in the setups syntax:
+%D
+%D \starttyping
+%D \starttexdefinition bagger [#1] #2
+%D oeps
+%D #1
+%D oeps
+%D \stoptexdefinition
+%D
+%D \bagger [a] {b}
+%D \stoptyping
+
+\bgroup \obeylines
+
+\gdef\starttexdefinition%
+ {\bgroup%
+ \obeylines%
+ \dostarttexdefinition}
+
+\gdef\dostarttexdefinition #1 #2
+ {\catcode13=\@@ignore%
+ \dodostarttexdefinition{#1}{#2}}%
+
+\long\gdef\dodostarttexdefinition#1#2#3\stoptexdefinition%
+ {\egroup%
+ \long\setvalue{#1}#2{#3}}
+
+\egroup
+
+%D \macros
+%D {newcounter,
+%D increment,decrement}
+%D
+%D Unfortunately the number of \COUNTERS\ in \TEX\ is limited,
+%D but fortunately we can store numbers in a macro. We can
+%D increment such pseudo \COUNTERS\ with \type{\increment}.
+%D
+%D \starttyping
+%D \increment(\counter,20)
+%D \increment(\counter,-4)
+%D \increment(\counter)
+%D \increment\counter
+%D \stoptyping
+%D
+%D After this sequence of commands, the value of
+%D \type{\counter} is 20, 16, 17 and~18. Of course there is
+%D also the complementary command \type{\decrement}.
+%D
+%D Global assignments are possible too, using \type{\doglobal}:
+%D
+%D \starttyping
+%D \doglobal\increment\counter
+%D \stoptyping
+%D
+%D When \type{\counter} is undefined, it's value is initialized
+%D at~0. It is nevertheless better to define a \COUNTER\
+%D explicitly. One reason could be that the \COUNTER\ can be
+%D part of a test with \type{\ifnum} and this conditional does
+%D not accept undefined macro's. The \COUNTER\ in our example
+%D can for instance be defined with:
+%D
+%D \starttyping
+%D \newcounter\counter
+%D \stoptyping
+%D
+%D The command \type{\newcounter} must not be confused with
+%D \type{\newcount}! Of course this mechanism is much slower
+%D than using \TEX's \COUNTERS\ directly. In practice
+%D \COUNTERS\ (and therefore our pseudo counters too) are
+%D seldom the bottleneck in the processing of a text. Apart
+%D from some other incompatilities we want to mention a pitfal
+%D when using \type{\ifnum}.
+%D
+%D \starttyping
+%D \ifnum\normalcounter=\pseudocounter \doif \else \doelse \fi
+%D \ifnum\pseudocounter=\normalcounter \doif \else \doelse \fi
+%D \stoptyping
+%D
+%D In the first test, \TEX\ continues it's search for the
+%D second number after reading \type{\pseudocounter}, while
+%D in the second test, it stops reading after having
+%D encountered a real one. Tests like the first one therefore
+%D can give unexpected results, for instance execution
+%D of \type{\doif} even if both numbers are unequal.
+
+\def\zerocountervalue{0}
+
+\def\newcounter#1%
+ {\dodoglobal\let#1\zerocountervalue}
+
+%D Nowadays we don't mind a few more tokens if we can gain a
+%D bit of speed.
+
+\def\doincrement#1%
+ {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\plusone \relax}}
+\def\dodecrement#1%
+ {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+\minusone\relax}}
+
+\def\dododoincrement#1,#2)%
+ {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi+#2\relax}}
+\def\dodododecrement#1,#2)%
+ {\dodoglobal\edef#1{\the\numexpr\ifdefined#1\ifx#1\relax\else#1\fi\fi-#2\relax}}
+
+\def\dodoincrement(#1%
+ {\doifnextcharelse,{\dododoincrement#1}{\dododoincrement#1,\plusone}}
+\def\dododecrement(#1%
+ {\doifnextcharelse,{\dodododecrement#1}{\dodododecrement#1,\plusone}}
+
+\def\fastincrement#1{\dodoglobal\edef#1{\the\numexpr#1+\plusone \relax}}
+\def\fastdecrement#1{\dodoglobal\edef#1{\the\numexpr#1+\minusone\relax}}
+
+\def\increment{\doifnextcharelse(\dodoincrement\doincrement}
+\def\decrement{\doifnextcharelse(\dododecrement\dodecrement}
+
+\def\incrementvalue#1{\expandafter\increment\csname#1\endcsname}
+\def\decrementvalue#1{\expandafter\decrement\csname#1\endcsname}
+
+%D \macros
+%D {newsignal}
+%D
+%D When writing advanced macros, we cannot do without
+%D signaling. A signal is a small (invisible) kern or penalty
+%D that signals the next macro that something just happened.
+%D This macro can take any action depending on the previous
+%D signal. Signals must be unique and the next macro takes care
+%D of that.
+%D
+%D \starttyping
+%D \newsignal\somesignal
+%D \stoptyping
+%D
+%D Signals old dimensions and can be used in skips, kerns and
+%D tests like \type{\ifdim}.
+
+\newdimen\maximumsignal % step is about 0.00025pt
+
+\def\newsignal#1%
+ {\ifdefined#1\else
+ \advance\maximumsignal 2sp % to be save in rounding
+ \edef#1{\the\maximumsignal}%
+ \fi}
+
+\let\newskimen\newdimen % it's all etex or later now
+
+%D \macros
+%D {strippedcsname}
+%D
+%D The next macro can be very useful when using \type{\csname}
+%D like in:
+%D
+%D \starttyping
+%D \csname if\strippedcsname\something\endcsname
+%D \stoptyping
+
+\ifdefined\letterbackslash \else
+ {\catcode`.=0 .catcode`.\ 12 .xdef.letterbackslash{.string\}} % hack
+\fi
+
+\def\strippedcsname#1% this permits \strippedcsname{\xxx} and \strippedcsname{xxx}
+ {\expandafter\dostrippedcsname\string#1}
+
+\def\dostrippedcsname#1%
+ {\if\noexpand#1\letterbackslash\else#1\fi}
+
+%D \macros
+%D {savenormalmeaning}
+%D
+%D We will use this one in:
+
+\def\savenormalmeaning#1%
+ {\ifcsname normal\strippedcsname#1\endcsname \else
+ \letvalue{normal\strippedcsname#1}#1%
+ \fi}
+
+%D \macros
+%D {newconditional,
+%D settrue, setfalse,
+%D ifconditional}
+%D
+%D \TEX's lacks boolean variables, although the \PLAIN\ format
+%D implements \type{\newif}. The main disadvantage of this
+%D scheme is that it takes three hash table entries. A more
+%D memory saving alternative is presented here. A conditional
+%D is defined by:
+%D
+%D \starttyping
+%D \newconditional\doublesided
+%D \setfalse
+%D \stoptyping
+%D Setting a conditional is done by \type{\settrue} and
+%D \type{\setfalse}:
+%D
+%D \starttyping
+%D \settrue\doublesided
+%D \setfalse
+%D \stoptyping
+%D while testing is accomplished by:
+%D
+%D \starttyping
+%D \ifconditional\doublesided ... \else ... \fi
+%D \setfalse
+%D \stoptyping
+%D We cannot use the simple scheme:
+%D
+%D \starttyping
+%D \def\settrue#1{\let#1=\iftrue}
+%D \def\settrue#1{\let#1=\iffalse}
+%D \stoptyping
+%D
+%D Such an implementation gives problems with nested
+%D conditionals. The next implementation is abaou as fast
+%D and just as straightforward:
+
+% \def\settrue #1{\chardef#1\zerocount}
+% \def\setfalse#1{\chardef#1\plusone}
+
+\def\settrue #1{\let#1\zerocount}
+\def\setfalse#1{\let#1\plusone}
+
+\let\newconditional = \setfalse
+\let\ifconditional = \ifcase
+
+%D \macros
+%D {ifzeropt}
+%D
+%D The next macro is both cosmetic and byte saving. It is
+%D pretty \type{\if}||safe too. It can be used in cases
+%D like:
+%D
+%D \starttyping
+%D \ifzeropt \somedimen ... \else ... \fi
+%D \stoptyping
+
+\let\ifzeropt\ifcase
+
+%D \macros
+%D {dorecurse,recurselevel,recursedepth,
+%D dostepwiserecurse,
+%D for}
+%D
+%D \TEX\ does not offer us powerfull for||loop mechanisms. On
+%D the other hand its recursion engine is quite unique. We
+%D therefore identify the for||looping macros by this method.
+%D The most simple alternative is the one that only needs a
+%D number.
+%D
+%D \starttyping
+%D \dorecurse {n} {whatever we want}
+%D \stoptyping
+%D
+%D This macro can be nested without problems and therefore be
+%D used in situations where \PLAIN\ \TEX's \type{\loop} macro
+%D ungracefully fails. The current value of the counter is
+%D available in \type{\recurselevel}, before as well as after
+%D the \typ{whatever we wat} stuff.
+%D
+%D \starttyping
+%D \dorecurse % inner loop
+%D {10}
+%D {\recurselevel: % outer value
+%D \dorecurse % inner loop
+%D {\recurselevel} % outer value
+%D {\recurselevel} % inner value
+%D \dorecurse % inner loop
+%D {\recurselevel} % outer value
+%D {\recurselevel} % inner value
+%D \endgraf}
+%D \stoptyping
+%D
+%D In this example the first, second and fourth
+%D \type{\recurselevel} concern the outer loop, while the third
+%D and fifth one concern the inner loop. The depth of the
+%D nesting is available for inspection in \type{\recursedepth}.
+%D
+%D Both \type{\recurselevel} and \type{\recursedepth} are
+%D macros. The real \COUNTERS\ are hidden from the user because
+%D we don't want any interference.
+
+\newcount\outerrecurse
+\newcount\innerrecurse
+
+\def\recursedepth{\the\outerrecurse}
+\def\recurselevel{0}
+
+\let\nextrecurse\relax
+
+\def\@@irecurse{@@ir@@} % ecurse} % stepper
+\def\@@arecurse{@@ar@@} % ecurse} % action
+
+\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#4}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \ifnum#3>0\relax
+ \ifnum#2<#1\relax
+ \let\nextrecurse\exitstepwiserecurse
+ \else
+ \let\nextrecurse\dodostepwiserecurse
+ \fi
+ \else
+ \ifnum#3<0\relax
+ \ifnum#1<#2\relax
+ \let\nextrecurse\exitstepwiserecurse
+ \else
+ \let\nextrecurse\dodostepwisereverse
+ \fi
+ \else
+ \let\nextrecurse\exitstepwiserecurse
+ \fi
+ \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}}
+
+\long\def\dodostepwiserecurse#1#2#3% from to step
+ {\ifnum#1>#2\relax
+ \@EA\nodostepwiserecurse
+ \else
+ \def\recurselevel{#1}%
+ \@EAEAEA\redostepwiserecurse\@EA
+ \fi\@EA{\the\numexpr\recurselevel+#3\relax}{#2}{#3}}
+
+\def\expandrecursecontent
+ {\csname\@@arecurse\recursedepth\endcsname}
+
+\def\redostepwiserecurse
+ {\expandrecursecontent\dodostepwiserecurse}
+
+\long\def\dodostepwisereverse#1#2#3% from to step
+ {\ifnum#1<#2\relax
+ \@EA\nodostepwiserecurse
+ \else
+ \def\recurselevel{#1}%
+ \@EAEAEA\redostepwisereverse\@EA
+ \fi\@EA{\the\numexpr\recurselevel#3\relax}{#2}{#3}}
+
+\long\def\dodostepwisereverse#1#2#3% from to step
+ {\ifnum#1<#2\relax
+ \@EA\nodostepwiserecurse
+ \else
+ \def\recurselevel{#1}%
+ \innerrecurse#1\relax
+ \advance\innerrecurse#3\relax
+ \@EAEAEA\redostepwisereverse\@EA
+ \fi\@EA{\the\innerrecurse}{#2}{#3}}
+
+\def\redostepwisereverse
+ {\expandrecursecontent\dodostepwisereverse}
+
+\def\exitstepwiserecurse
+ {\nodostepwiserecurse\relax}
+
+\def\nodostepwiserecurse#1#2#3#4%
+ {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname
+ \global\advance\outerrecurse \minusone}
+
+\def\nonostepwiserecurse#1#2#3%
+ {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname
+ \global\advance\outerrecurse \minusone}
+
+\def\dorecurse#1%
+ {\dostepwiserecurse1{#1}1}
+
+%D As we can see here, the simple command \type{\dorecurse} is
+%D a special case of the more general:
+%D
+%D \starttyping
+%D \dostepwiserecurse {from} {to} {step} {action}
+%D \stoptyping
+%D
+%D This commands accepts positive and negative steps. Illegal
+%D values are handles as good as possible and the macro accepts
+%D numbers and \COUNTERS.
+%D
+%D \starttyping
+%D \dostepwiserecurse {1} {10} {2} {...}
+%D \dostepwiserecurse {10} {1} {-2} {...}
+%D \stoptyping
+%D
+%D Because the simple case is used often, we implement it
+%D more efficiently:
+
+\long\def\dorecurse#1%
+ {\ifcase#1\relax
+ \expandafter\gobbletwoarguments
+ \or
+ \expandafter\ydorecurse
+ \else
+ \expandafter\xdorecurse
+ \fi{#1}}
+
+\long\def\xdorecurse#1#2%
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#2}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \@EA\dodorecurse\@EA1\@EA{\number#1}}
+
+\long\def\ydorecurse#1#2%
+ {\global\advance\outerrecurse \plusone
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \let\recurselevel\!!plusone
+ #2%
+ \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname
+ \global\advance\outerrecurse \minusone}
+
+\long\def\dodorecurse#1#2% from to
+ {\ifnum#1>#2\relax
+ \@EA\nodorecurse
+ \else
+ \def\recurselevel{#1}%
+ \@EAEAEA\redorecurse
+ \fi\@EA{\the\numexpr\recurselevel+\plusone\relax}{#2}}
+
+\long\def\dodorecurse#1#2% from to
+ {\ifnum#1>#2\relax
+ \@EA\nodorecurse
+ \else
+ \def\recurselevel{#1}%
+ \innerrecurse#1\advance\innerrecurse\plusone
+ \@EAEAEA\redorecurse
+ \fi\@EA{\the\innerrecurse}{#2}}
+
+\def\redorecurse
+ {\expandrecursecontent\dodorecurse}
+
+\def\nodorecurse#1#2#3%
+ {\@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname
+ \global\advance\outerrecurse \minusone }
+
+%D \macros
+%D {doloop,exitloop}
+%D
+%D Sometimes loops are not determined by counters, but by
+%D (a combinations of) conditions. We therefore implement a
+%D straightforward loop, which can only be left when we
+%D explictly exit it. Nesting is supported. First we present
+%D a more extensive alternative.
+%D
+%D \starttyping
+%D \doloop
+%D {Some kind of typesetting punishment \par
+%D \ifnum\pageno>100 \exitloop \fi}
+%D \stoptyping
+%D
+%D When needed, one can call for \type{\looplevel} and
+%D \type{\loopdepth}.
+
+\let\endofloop\donothing
+
+\long\def\doloop#1%
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname{#1}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \let\endofloop\dodoloop
+ \dodoloop1} % no \plusone else \recurselevel wrong
+
+\long\def\dodoloop#1%
+ {\def\recurselevel{#1}%
+ \@EA\redoloop\@EA{\the\numexpr\recurselevel+\plusone\relax}}
+
+\def\redoloop
+ {\expandrecursecontent\endofloop}
+
+\def\nodoloop#1%
+ {\let\endofloop\dodoloop % new, permits nested \doloop's
+ \@EA\let\@EA\recurselevel\csname\@@irecurse\recursedepth\endcsname
+ \global\advance\outerrecurse\minusone}
+
+\def\exitloop % \exitloop quits at end
+ {\let\endofloop\nodoloop}
+
+\long\def\exitloopnow#1\endofloop % \exitloopnow quits directly
+ {\nodoloop}
+
+%D The loop is executed at least once, so beware of situations
+%D like:
+%D
+%D \starttyping
+%D \doloop {\exitloop some commands}
+%D \stoptyping
+%D
+%D It's just a matter of putting the text into the \type{\if}
+%D statement that should be there anyway, like in:
+%D
+%D \starttyping
+%D \doloop {\ifwhatever \exitloop \else some commands\fi}
+%D \stoptyping
+%D
+%D You can also quit a loop immediately, by using \type
+%D {\exitloopnow} instead. Beware, this is more sensitive
+%D for conditional errors.
+
+%D Krzysztof Leszczynski suggested to provide access to the level by
+%D means of a \type {#1}. I decided to pass the more frquently used
+%D level as \type {#1} and the less favoured depth as \type {#2}. The
+%D intended usage is:
+%D
+%D \starttyping
+%D \dorecurse{3}{\definesymbol[test-#1][xx-#1]}
+%D
+%D \def\test{\dorecurse{3}{\definesymbol[test-##1][xx-##1]}} \test
+%D
+%D \symbol[test-1]\quad\symbol[test-2]\quad\symbol[test-3]
+%D \stoptyping
+%D
+%D Since the hashed arguments are expanded, we don't need tricky
+%D expansion here.
+%D
+%D \starttyping
+%D \dorecurse{3}{\expanded{\definesymbol[test-\recurselevel][xx-\recurselevel]}}
+%D \stoptyping
+
+\def\expandrecursecontent
+ {\csname\@@arecurse\recursedepth\@EA\@EA\@EA\endcsname\@EA\@EA\@EA{\@EA\recurselevel\@EA}\@EA{\recursedepth}}
+
+\long\def\xdorecurse#1#2%
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#2}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \@EA\dodorecurse\@EA1\@EA{\number#1}}
+
+\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \ifnum#3>0\relax
+ \ifnum#2<#1\relax
+ \let\nextrecurse\exitstepwiserecurse
+ \else
+ \let\nextrecurse\dodostepwiserecurse
+ \fi
+ \else
+ \ifnum#3<0\relax
+ \ifnum#1<#2\relax
+ \let\nextrecurse\exitstepwiserecurse
+ \else
+ \let\nextrecurse\dodostepwisereverse
+ \fi
+ \else
+ \let\nextrecurse\exitstepwiserecurse
+ \fi
+ \fi\expanded{\nextrecurse{\number#1}{\number#2}{\number#3}}}
+
+\long\def\doloop#1%
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#1}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \let\endofloop\dodoloop
+ \dodoloop1} % no \plusone else \recurselevel wrong
+
+% EXPERIMENT
+
+% faster
+
+\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \ifnum#3>\zerocount
+ \ifnum#2<#1\relax
+ \let\nextrecurse\exitstepwiserecurse
+ \else
+ \let\nextrecurse\dodostepwiserecurse
+ \fi
+ \else
+ \ifnum#3<\zerocount
+ \ifnum#1<#2\relax
+ \let\nextrecurse\exitstepwiserecurse
+ \else
+ \let\nextrecurse\dodostepwisereverse
+ \fi
+ \else
+ \let\nextrecurse\exitstepwiserecurse
+ \fi
+ \fi
+ \expandafter\nextrecurse\normalexpanded{{\number#1}{\number#2}{\number#3}}}
+
+% slightly faster
+
+\long\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4
+ {\global\advance\outerrecurse \plusone
+ \long\global\@EA\def\csname\@@arecurse\recursedepth\endcsname##1##2{#4}%
+ \global\@EA\let\csname\@@irecurse\recursedepth\endcsname\recurselevel
+ \csname @swr%
+ \ifnum#3>\zerocount
+ \ifnum#2<#1\else d\fi
+ \else\ifnum#3<\zerocount
+ \ifnum#1<#2\else r\fi
+ \fi\fi
+ \expandafter\endcsname\normalexpanded{{\number#1}{\number#2}{\number#3}}}
+
+\let\@swr \exitstepwiserecurse
+\let\@swrd\dodostepwiserecurse
+\let\@swrr\dodostepwisereverse
+
+%D For special purposes:
+
+\newcount\fastrecursecounter
+\newcount\lastrecursecounter
+\newcount\steprecursecounter
+
+\def\dofastrecurse#1#2#3#4%
+ {\def\fastrecursebody{#4}%
+ \fastrecursecounter#1\relax
+ \lastrecursecounter#2\relax
+ \steprecursecounter#3\relax
+ \def\recurselevel{\number\fastrecursecounter}%
+ \dodofastrecurse}
+
+\def\dodofastrecurse
+ {\ifnum\fastrecursecounter>\lastrecursecounter\else
+ \fastrecursebody
+ \advance\fastrecursecounter\steprecursecounter
+ \expandafter\dodofastrecurse
+ \fi}
+
+%D This alternative looks a bit different and uses a
+%D pseudo counter. When this macro is nested, we have to use
+%D different counters. This time we use keywords.
+%D
+%D \starttyping
+%D \def\alfa{2} \def\beta{100} \def\gamma{3}
+%D
+%D \for \n=55 \to 100 \step 1 \do {... \n ...}
+%D \for \n=\alfa \to \beta \step \gamma \do {... \n ...}
+%D \for \n=\n \to 120 \step 1 \do {... \n ...}
+%D \for \n=120 \to 100 \step -3 \do {... \n ...}
+%D \for \n=55 \to 100 \step 2 \do {... \n ...}
+%D \stoptyping
+%D
+%D Only in the third example we need to predefine \type{\n}.
+%D The use of \type{\od} as a dilimiter would have made nested
+%D use more problematic.
+
+%D Don't use this one, it's kind of obsolete.
+
+\def\for#1=#2\to#3\step#4\do#5%
+ {\dostepwiserecurse{#2}{#3}{#4}
+ {\let#1\recurselevel#5\let#1\recurselevel}}
+
+%D \macros
+%D {newevery,everyline,EveryLine,EveryPar}
+%D
+%D Lets skip to something quite different. It's common use
+%D to use \type {\everypar} for special purposes. In \CONTEXT\
+%D we use this primitive for locating sidefloats. This means
+%D that when user assignments to \type {\everypar} can interfere
+%D with those of the package. We therefore introduce
+%D \type {\EveryPar}.
+%D
+%D The same goes for \type {\EveryLine}. Because \TEX\ offers
+%D no \type {\everyline} primitive, we have to call for
+%D \type {\everyline} when we are working on a line by line
+%D basis. Just by calling \type {\EveryPar{}} and
+%D \type {\EveryLine{}} we restore the old situation.
+
+% \dorecurse{2}{
+% \expanded{\everypar{before \recurselevel\space}}
+% \EveryPar{x } [before \recurselevel\space x] \par
+% \EveryPar{y } [before \recurselevel\space y] \par
+% \EveryPar{} [before \recurselevel] \par
+% \EveryPar{x } \EveryPar{y } \EveryPar{} [before \recurselevel] \par
+% \EveryPar{y } \everypar{before } [before] \par
+% }
+
+% retrofit this into mkii
+
+\def\dowithevery#1%
+ {\expandafter\removetoks\expandafter\the\csname t\strippedcsname#1\endcsname\from#1%
+ \expandafter\appendtoks\expandafter\the\csname t\strippedcsname#1\endcsname\to #1%
+ \csname t\strippedcsname#1\endcsname}
+
+\def\newevery#1#2%
+ {\newtoks#1% we test for redefinition elsewhere
+ \ifx#2\relax\else\ifdefined#2\else
+ \expandafter\newtoks\csname t\strippedcsname#1\endcsname
+ \def#2{\dowithevery#1}%
+ \fi\fi}
+
+%D This one permits definitions like:
+
+\newevery \everypar \EveryPar % we get a warning which is ok
+\newevery \everyline \EveryLine
+
+%D and how about:
+
+\newevery \neverypar \NeveryPar
+
+%D Which we're going to use indeed! When the second argument
+%D equals \type {\relax}, the first token list is created
+%D unless it is already defined.
+
+%D Technically spoken we could have used the method we are
+%D going to present in the visual debugger. First we save
+%D the primitive \type{\everypar}:
+%D
+%D \starttyping
+%D \let\normaleverypar=\everypar
+%D \stoptyping
+%D
+%D Next we allocate a \TOKENLIST\ named \type{\everypar},
+%D which means that \type{\everypar} is no longer a primitive
+%D but something like \type{\toks44}.
+%D
+%D \starttyping
+%D \newtoks\everypar
+%D \stoptyping
+%D
+%D Because \TEX\ now executes \type{\normaleverypar} instead
+%D of \type{\everypar}, we are ready to assign some tokens to
+%D this internally known and used \TOKENLIST.
+%D
+%D \starttyping
+%D \normaleverypar={all the things the system wants to do \the\everypar}
+%D \stoptyping
+%D
+%D Where the user can provide his own tokens to be expanded
+%D every time he expects them to expand.
+%D
+%D \starttyping
+%D \everypar={something the user wants to do}
+%D \stoptyping
+%D
+%D We don't use this method because it undoubtly leads to
+%D confusing situations, especially when other packages are
+%D used, but it's this kind of tricks that make \TEX\ so
+%D powerful.
+
+%D \macros
+%D {convertargument,convertcommand,convertvalue}
+%D
+%D Some persistent experimenting led us to the next macro. This
+%D macro converts a parameter or an expanded macro to it's
+%D textual meaning.
+%D
+%D \starttyping
+%D \convertargument ... \to \command
+%D \stoptyping
+%D
+%D For example,
+%D
+%D \starttyping
+%D \convertargument{one \two \three{four}}\to\ascii
+%D \stoptyping
+%D
+%D The resulting macro \type{\ascii} can be written to a file
+%D or the terminal without problems. In \CONTEXT\ we use this
+%D macro for generating registers and tables of contents.
+%D
+%D The second conversion alternative accepts a command:
+%D
+%D \starttyping
+%D \convertcommand\command\to\ascii
+%D \stoptyping
+%D
+%D Both commands accept the prefix \type{\doglobal} for global
+%D assignments.
+
+\def\convertvalue#1\to
+ {\expandafter\convertcommand\csname#1\endcsname\to}
+
+\def\defconvertedvalue#1#2% less sensitive for \to
+ {\@EA\defconvertedcommand\@EA#1\csname#2\endcsname}
+
+%D \macros
+%D {doifassignmentelse}
+%D
+%D A lot of \CONTEXT\ commands take optional arguments, for
+%D instance:
+%D
+%D \starttyping
+%D \dothisorthat[alfa,beta]
+%D \dothisorthat[first=foo,second=bar]
+%D \dothisorthat[alfa,beta][first=foo,second=bar]
+%D \stoptyping
+%D
+%D Although a combined solution is possible, we prefer a
+%D seperation. The next command takes care of propper
+%D handling of such multi||faced commands.
+%D
+%D \starttyping
+%D \doifassignmentelse {...} {then ...} {else ...}
+%D \stoptyping
+
+% \def\doifassignmentelse#1%
+% {\convertargument#1\to\ascii
+% \doifinstringelse=\ascii}
+
+% \def\doifassignmentelse#1%
+% {\edef\ascii{\detokenize{#1}}%
+% \ifx\ascii\empty
+% \expandafter\secondoftwoarguments
+% \else
+% \expandafter\docheckifassignmentelse
+% \fi}
+
+% \long\def\dodoifassignmentelse
+% {\expandafter\dododoifnotassignmentelse\ascii=@@\@end@
+% \expandafter\secondoftwoarguments
+% \else
+% \expandafter\firstoftwoarguments
+% \fi}
+
+\long\def\docheckifassignmentelse#1=#2#3\@end@{\if#2@}%
+
+\long\def\doifassignmentelse#1%
+ {\expandafter\docheckifassignmentelse\detokenize{#1}=@@\@end@
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+% D \macros
+% D {convertasciiafter}
+% D
+% D Sometimes we need to convert an argument to a string (letters
+% D only), for instance when we compare it with another string:
+% D
+% D \starttyping
+% D \convertasciiafter\doifinstringelse{em}{\ascii}{...}
+% D \stoptyping
+%
+% \def\convertasciiafter#1#2%
+% {\@EA#1\@EA{\detokenize{#2}}}
+
+%D In \ETEX\ we can use \type {\detokenize} and gain some
+%D speed, but in general far less that 1\% for \type
+%D {\convertargument} and nil for \type {\convertcommand}.
+%D This macro is more robust than the pure \TEX\ one,
+%D something I found out when primitives like \type
+%D {\jobname} were fed (or something undefined).
+
+\long\def\convertargument#1\to#2{\dodoglobal\edef#2{\detokenize{#1}}}
+\long\def\convertcommand #1\to#2{\dodoglobal\edef#2{\@EA\detokenize\@EA{#1}}} % hm, only second is also ok
+
+\long\def\defconvertedargument #1#2{\edef#1{\detokenize {#2}}}
+\long\def\defconvertedcommand #1#2{\edef#1{\detokenize\@EA{#2}}}
+\long\def\edefconvertedargument#1#2{\edef#1{#2}%
+ \edef#1{\detokenize\@EA{#1}}}
+\long\def\gdefconvertedargument#1#2{\xdef#1{\detokenize {#2}}}
+\long\def\gdefconvertedcommand #1#2{\xdef#1{\detokenize\@EA{#2}}}
+\long\def\xdefconvertedargument#1#2{\xdef#1{#2}%
+ \xdef#1{\detokenize\@EA{#1}}}
+
+%D When you try to convert a primitive command, you'll find
+%D out that the \ETEX\ method fails on for instance \type
+%D {\jobname} in the sense that it returns the filename
+%D instead of just \type {\jobname}. So far this does not
+%D give real problems.
+
+%D This is typically a macro that one comes to after reading
+%D the \TEX book carefully. Even then, the definite solution
+%D was found after rereading the \TEX book. The first
+%D implementation was:
+%D
+%D \starttyping
+%D \def\doconvertargument#1->#2\\\\{#2}
+%D \stoptyping
+%D
+%D The \type{-}, the delimiter \type{\\\\} and the the second
+%D argument are completely redundant.
+
+%D \macros
+%D {showvalue,showargument}
+%D
+%D Two handy macros for testing purposes only:
+
+\def\showvalue#1%
+ {\expandafter\show\csname#1\endcsname}
+
+\def\showvalue#1%
+ {\ifcsname#1\endcsname
+ \expandafter\show\csname#1\endcsname
+ \else
+ \show\undefined
+ \fi}
+
+%D \macros
+%D {doifmeaningelse}
+%D
+%D We can use both commands in testing, but alas, not all
+%D meanings expand to something \type {->}. This is no problem
+%D in the \ETEX\ implementation, but since we want
+%D compatibility, we need:
+%D
+%D \starttyping
+%D \doifmeaningelse {\next} {\something} {true} {false}
+%D \stoptyping
+%D
+%D Watch the one level expansion of the second argument.
+
+\def\doifmeaningelse#1#2%
+ {\edef\!!stringa{\meaning#1}%
+ \def \!!stringb{#2}%
+ \edef\!!stringb{\meaning\!!stringb}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doifsamestringselse,doifsamestring,doifnotsamestring}
+%D
+%D The next comparison macro converts the arguments into
+%D expanded strings. This command can be used to compare for
+%D instance \type {\jobname} with a name stored in a macro.
+%D
+%D \starttyping
+%D \doifelse {\jobname}{oeps}{YES}{NO}
+%D \doifsamestringelse{\jobname}{oeps}{YES}{NO}
+%D \stoptyping
+
+% \def\@@doifsamestringelse#1#2#3#4%
+% {\edef\!!stringa{#3}\convertcommand\!!stringa\to\!!stringa
+% \edef\!!stringb{#4}\convertcommand\!!stringb\to\!!stringb
+% \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi}
+
+\def\@@doifsamestringelse#1#2#3#4%
+ {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#3}}}%
+ \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#4}}}%
+ \ifx\!!stringa\!!stringb\expandafter#1\else\expandafter#2\fi}
+
+\def\doifsamestringelse{\@@doifsamestringelse\firstoftwoarguments\secondoftwoarguments}
+\def\doifsamestring {\@@doifsamestringelse\firstofoneargument\gobbleoneargument}
+\def\doifnotsamestring {\@@doifsamestringelse\gobbleoneargument\firstofoneargument}
+
+%D \macros
+%D {ExpandFirstAfter,ExpandSecondAfter,ExpandBothAfter}
+%D
+%D These three commands support expansion of arguments before
+%D executing the commands that uses them. We can best
+%D illustrate this with an example.
+%D
+%D \starttyping
+%D \def\first {alfa,beta,gamma}
+%D \def\second {alfa,epsilon,zeta}
+%D
+%D \ExpandFirstAfter \doifcommon {\first} {alfa} {\message{OK}}
+%D \ExpandSecondAfter \doifcommon {alfa} {\second} {\message{OK}}
+%D \ExpandBothAfter \doifcommon {\first} {\second} {\message{OK}}
+%D
+%D \ExpandFirstAfter\processcommalist[\first]\message
+%D
+%D \ExpandAfter \doifcommon {\first} {alfa} {\message{OK}}
+%D \stoptyping
+%D
+%D The first three calls result in the threefold message
+%D \type{OK}, the fourth one shows the three elements of
+%D \type{\first}. The command \type{\ExpandFirstAfter} takes
+%D care of (first) arguments that are delimited by \type{[ ]},
+%D but the faster \type{\ExpandAfter} does not.
+
+\def\simpleExpandFirstAfter#1%
+ {\long\xdef\@@expanded{\noexpand\ExpandCommand{#1}}\@@expanded}
+
+\def\complexExpandFirstAfter[#1]%
+ {\long\xdef\@@expanded{\noexpand\ExpandCommand[#1]}\@@expanded}
+
+\def\ExpandFirstAfter#1%
+ {\let\ExpandCommand#1%
+ \doifnextoptionalelse\complexExpandFirstAfter\simpleExpandFirstAfter}
+
+\def\ExpandSecondAfter#1#2#3%
+ {\scratchtoks{#2}%
+ \long\xdef\@@expanded{\noexpand#1{\the\scratchtoks}{#3}}\@@expanded}
+
+\def\ExpandBothAfter#1#2#3%
+ {\long\xdef\@@expanded{\noexpand#1{#2}{#3}}\@@expanded}
+
+\def\ExpandAfter#1#2%
+ {\long\xdef\@@expanded{\noexpand#1{#2}}\@@expanded}
+
+%D Now we can for instance define \type{\ifinstringelse} as:
+
+\def\ifinstringelse
+ {\ExpandBothAfter\p!doifinstringelse}
+
+%D \macros
+%D {ConvertToConstant,ConvertConstantAfter}
+%D
+%D When comparing arguments with a constant, we can get into
+%D trouble when this argument consists of tricky expandable
+%D commands. One solution for this is converting the
+%D argument to a string of unexpandable characters. To make
+%D comparison possible, we have to convert the constant too
+%D
+%D \starttyping
+%D \ConvertToConstant\doifelse {...} {...} {then ...} {else ...}
+%D \stoptyping
+%D
+%D This construction is only needed when the first argument
+%D can give troubles. Misuse can slow down processing.
+%D
+%D \starttyping
+%D \ConvertToConstant\doifelse{\c!alfa} {\c!alfa}{...}{...}
+%D \ConvertToConstant\doifelse{alfa} {\c!alfa}{...}{...}
+%D \ConvertToConstant\doifelse{alfa} {alfa} {...}{...}
+%D \ConvertToConstant\doifelse{alfa \alfa test}{\c!alfa}{...}{...}
+%D \stoptyping
+%D
+%D In examples~2 and~3 both arguments equal, in~1 and~4
+%D they differ.
+
+\long\def\ConvertToConstant#1#2#3%
+ {\edef\!!stringa{\expandafter\detokenize\expandafter{#2}}%
+ \edef\!!stringb{\expandafter\detokenize\expandafter{#3}}%
+ #1{\!!stringa}{\!!stringb}}
+
+%D When the argument \type{#1} consists of commands, we had
+%D better use
+%D
+%D \starttyping
+%D \ConvertConstantAfter\processaction[#1][...]
+%D \ConvertConstantAfter\doifelse{#1}{\v!something}{}{}
+%D \stoptyping
+%D
+%D This commands accepts things like:
+%D
+%D \starttyping
+%D \v!constant
+%D constant
+%D \hbox to \hsize{\rubish}
+%D \stoptyping
+%D
+%D As we will see in the core modules, this macro permits
+%D constructions like:
+%D
+%D \starttyping
+%D \setupfootertexts[...][...]
+%D \setupfootertexts[margin][...][...]
+%D \setupfootertexts[\v!margin][...][...]
+%D \stoptyping
+%D
+%D where \type{...} can be anything legally \TEX.
+
+\def\CheckConstantAfter#1#2%
+ {\@EA\convertargument\v!prefix!\to\ascii
+ \convertargument#1\to#2\relax
+ \doifinstringelse\ascii{#2}
+ {\expandafter\convertargument#1\to#2}
+ {}}
+
+\def\ConvertConstantAfter#1#2#3%
+ {\CheckConstantAfter{#2}\asciia
+ \CheckConstantAfter{#3}\asciib
+ #1{\asciia}{\asciib}}
+
+%D \macros
+%D {assignifempty}
+%D
+%D We can assign a default value to an empty macro using:
+%D
+%D \starttyping
+%D \assignifempty \macros {default value}
+%D \stoptyping
+%D
+%D We don't explicitly test if the macro is defined.
+
+\def\assignifempty#1#2% can be sped up
+ {\doifsomething{#1}{\def#1{#2}}} % {\doifnot{#1}{}{\def#1{#2}}}
+
+%D \macros
+%D {gobbleuntil,grabuntil,gobbleuntilrelax,
+%D processbetween,processuntil}
+%D
+%D In \TEX\ gobbling usually stand for skipping arguments, so
+%D here are our gobbling macros.
+%D
+%D In \CONTEXT\ we use a lot of \type{\start}||\type{\stop}
+%D like constructions. Sometimes, the \type{\stop} is used as a
+%D hard coded delimiter like in:
+%D
+%D \starttyping
+%D \def\startcommand#1\stopcommand%
+%D {... #1 ...}
+%D \stoptyping
+%D
+%D In many cases the \type{\start}||\type{\stop} pair is
+%D defined at format generation time or during a job. This
+%D means that we cannot hardcode the \type{\stop} criterium.
+%D Only after completely understanding \type{\csname} and
+%D \type{\expandafter} I was able to to implement a solution,
+%D starting with:
+%D
+%D \starttyping
+%D \grabuntil{stop}\command
+%D \stoptyping
+%D
+%D This commands executes, after having encountered
+%D \type {\stop} the command \type {\command}. This command
+%D receives as argument the text preceding the \type {\stop}.
+%D This means that:
+%D
+%D \starttyping
+%D \def\starthello%
+%D {\grabuntil{stophello}\message}
+%D
+%D \starthello Hello world!\stophello
+%D \stoptyping
+%D
+%D results in: \type{\message{Hello world!}}.
+
+\def\dograbuntil#1#2%
+ {\long\def\next##1#1{#2{##1}}\next}
+
+\def\grabuntil#1%
+ {\expandafter\dograbuntil\expandafter{\csname#1\endcsname}}
+
+%D The next command build on this mechanism:
+%D
+%D \starttyping
+%D \processbetween{string}\command
+%D \stoptyping
+%D
+%D Here:
+%D
+%D \starttyping
+%D \processbetween{hello}\message
+%D \starthello Hello again!\stophello
+%D \stoptyping
+%D
+%D leads to: \type{\message{Hello again!}}. The command
+%D
+%D \starttyping
+%D \gobbleuntil{sequence}
+%D \stoptyping
+%D
+%D is related to these commands. This one simply throws away
+%D everything preceding \type{\command}.
+
+\long\def\processbetween#1#2%
+ {\setvalue{\s!start#1}{\grabuntil{\s!stop#1}{#2}}}
+
+\def\gobbleuntil#1%
+ {\long\def\next##1#1{}\next}
+
+\def\gobbleuntilrelax#1\relax
+ {}
+
+%D The next one simply expands the pickup up tokens.
+%D
+%D \starttyping
+%D \processuntil{sequence}
+%D \stoptyping
+
+\def\processuntil#1%
+ {\long\def\next##1#1{##1}\next}
+
+%D \macros
+%D {groupedcommand}
+%D
+%D Commands often manipulate argument as in:
+%D
+%D \starttyping
+%D \def\doezomaarwat#1{....#1....}
+%D \stoptyping
+%D
+%D A disadvantage of this approach is that the tokens that
+%D form \type{#1} are fixed the the moment the argument is read
+%D in. Normally this is no problem, but for instance verbatim
+%D environments adapt the \CATCODES\ of characters and therefore
+%D are not always happy with already fixed tokens.
+%D
+%D Another problem arises when the argument is grouped not by
+%D \type{{}} but by \type{\bgroup} and \type{\egroup}. Such an
+%D argument fails, because the \type{\bgroup} is een as the
+%D argument (which is quite normal).
+%D
+%D The next macro offers a solution for both unwanted
+%D situations:
+%D
+%D \starttyping
+%D \groupedcommand {before} {after}
+%D \stoptyping
+%D
+%D Which can be used like:
+%D
+%D \starttyping
+%D \def\cite%
+%D {\groupedcommand{\rightquote\rightquote}{\leftquote\leftquote}}
+%D \stoptyping
+%D
+%D This command is equivalent to, but more 'robust' than:
+%D
+%D \starttyping
+%D \def\cite#1%
+%D {\rightquote\rightquote#1\leftquote\leftquote}
+%D \stoptyping
+%D
+%D \starttyping
+%D \def\rightword%
+%D {\groupedcommand{\hfill\hbox}{\parfillskip\!!zeropoint}}
+%D
+%D .......... \rightword{the right way}
+%D \stoptyping
+%D
+%D Here \TEX\ typesets \type{\bf the right way} unbreakable
+%D at the end of the line. The solution mentioned before does
+%D not work here. We also handle
+%D
+%D \starttyping
+%D to be \bold{bold} or not, that's the question
+%D \stoptyping
+%D
+%D and
+%D
+%D \starttyping
+%D to be {\bold bold} or not, that's the question
+%D \stoptyping
+%D
+%D This alternative checks for a \type{\bgroup} token first.
+%D The internal alternative does not accept the box handling
+%D mentioned before, but further nesting works all right. The
+%D extra \type{\bgroup}||\type{\egroup} is needed to keep
+%D \type{\AfterGroup} both into sight and local.
+
+\long\def\HandleGroup#1#2%
+ {\bgroup
+ \long\def\BeforeGroup{\bgroup#1\bgroup\aftergroup\AfterGroup}%
+ \long\def\AfterGroup {#2\egroup\egroup}%
+ \afterassignment\BeforeGroup
+ \let\next=}
+
+\long\def\HandleSimpleGroup#1#2% no inner group (so no kerning interference)
+ {\bgroup
+ %long\def\BeforeGroup{\bgroup#1\aftergroup\AfterGroup}% interferes
+ \long\def\BeforeGroup{\bgroup\aftergroup\AfterGroup#1}%
+ \long\def\AfterGroup {#2\egroup}%
+ \afterassignment\BeforeGroup
+ \let\next=}
+
+\long\def\HandleNoGroup#1#2%
+ {\long\def\AfterGroup{#2\egroup}%
+ \bgroup\aftergroup\AfterGroup#1}
+
+%D I considered it a nuisance that
+%D
+%D \starttyping
+%D \color[green]
+%D {as grass}
+%D \stoptyping
+%D
+%D was not interpreted as one would expect. This is due to the
+%D fact that \type{\futurelet} obeys blank spaces, and a
+%D line||ending token is treated as a blank space. So the final
+%D implementation became:
+
+\long\unexpanded\def\groupedcommand#1#2%
+ {\doifnextbgroupelse{\HandleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}}
+
+\long\unexpanded\def\simplegroupedcommand#1#2%
+ {\doifnextbgroupelse{\HandleSimpleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}}
+
+%D Users should be aware of the fact that grouping can
+%D interfere with ones paragraph settings that are executed
+%D after the paragraph is closed. One should therefore
+%D explictly close the paragraph with \type{\par}, else the
+%D settings will be forgotten and not applied. So it's:
+%D
+%D \starttyping
+%D \def\BoldRaggedCenter%
+%D {\groupedcommand{\raggedcenter\bf}{\par}}
+%D \stoptyping
+
+%D \macros
+%D {checkdefined}
+%D
+%D The bigger the system, the greater the change that
+%D user defined commands collide with those that are part of
+%D the system. The next macro gives a warning when a command is
+%D already defined. We considered blocking the definition, but
+%D this is not always what we want.
+%D
+%D \starttyping
+%D \checkdefined {category} {class} {command}
+%D \stoptyping
+%D
+%D The user is warned with the suggestion to use
+%D \type{CAPITALS}. This suggestion is feasible, because
+%D \CONTEXT only defines lowcased macros.
+
+\def\showdefinederror#1#2%
+ {\writestatus\m!systems{#1 #2 replaces a macro, use CAPITALS!}}
+
+\def\checkdefined#1#2#3%
+ {\doifdefined{#3}{\showdefinederror{#2}{#3}}}
+
+%D \macros
+%D {GotoPar,GetPar}
+%D
+%D Typesetting a paragraph in a special way can be done by
+%D first grabbing the contents of the paragraph and processing
+%D this contents grouped. The next macro for instance typesets
+%D a paragraph in boldface.
+%D
+%D \starttyping
+%D \def\remark#1\par%
+%D {\bgroup\bf#1\egroup}
+%D \stoptyping
+%D
+%D This macro has to be called like
+%D
+%D \starttyping
+%D \remark some text ... ending with \par
+%D \stoptyping
+%D
+%D Instead of \type{\par} we can of course use an empty line.
+%D When we started typesetting with \TEX, we already had
+%D produced lots of text in plain \ASCII. In producing such
+%D simple formatted texts, we adopted an open layout, and when
+%D switching to \TEX, we continued this open habit. Although
+%D \TEX\ permits a cramped and badly formatted source, it adds
+%D to confusion and sometimes introduces errors. So we prefer:
+%D
+%D \starttyping
+%D \remark
+%D
+%D some text ... ending with an empty line
+%D \stoptyping
+%D
+%D We are going to implement a mechanism that allows such open
+%D specifications. The definition of the macro handling
+%D \type{\remark} becomes:
+%D
+%D \starttyping
+%D \def\remark%
+%D {\BeforePar{\bgroup\bf}%
+%D \AfterPar{\egroup}%
+%D \GetPar}
+%D \stoptyping
+%D
+%D A macro like \type{\GetPar} can be defined in several
+%D ways. The recent version, the fourth one in a row,
+%D originally was far more complicated, but some functionality
+%D has been moved to other macros.
+%D
+%D We start with the more simple but in some cases more
+%D appropriate alternative is \type{\GotoPar}. This one leaves
+%D \type{\par} unchanged and is therefore more robust. On the
+%D other hand, \type{\AfterPar} is not supported.
+
+\newtoks\BeforePar
+\newtoks\AfterPar
+
+\let\endoflinetoken=^^M
+
+\def\redowithpar\par
+ {\doifnextcharelse\par\redowithpar\dodowithpar}%
+
+\def\dowithpar#1#2%
+ {\def\dodowithpar##1\par{#1##1#2}%
+ \redowithpar\par}
+
+\def\redogotopar\par
+ {\doifnextcharelse\par\redogotopar\dodogotopar}%
+
+\def\dogotopar#1%
+ {\def\dodogotopar{#1}%
+ \redogotopar\par}
+
+\def\GetPar
+ {\expanded
+ {\dowithpar
+ {\the\BeforePar
+ \BeforePar\emptytoks}
+ {\the\AfterPar
+ \BeforePar\emptytoks
+ \AfterPar\emptytoks}}}
+
+\def\GotoPar
+ {\expanded
+ {\dogotopar
+ {\the\BeforePar
+ \BeforePar\emptytoks}}}
+
+%D \macros
+%D {dowithpargument,dowithwargument}
+%D
+%D The next macros are a variation on \type{\GetPar}. When
+%D macros expect an argument, it interprets a grouped sequence
+%D of characters a one token. While this adds to robustness and
+%D less ambiguous situations, we sometimes want to be a bit
+%D more flexible, or at least want to be a bit more tolerant
+%D to user input.
+%D
+%D We start with a commands that acts on paragraphs. This
+%D command is called as:
+%D
+%D \starttyping
+%D \dowithpargument\command
+%D \dowithpargument{\command ... }
+%D \stoptyping
+%D
+%D In \CONTEXT\ we use this one to read in the titles of
+%D chapters, sections etc. The commands responsible for these
+%D activities accept several alternative ways of argument
+%D passing. In these examples, the \type{\par} can be omitted
+%D when an empty line is present.
+%D
+%D \starttyping
+%D \command{...}
+%D \command ... \par
+%D \command
+%D {...}
+%D \command
+%D ... \par
+%D \stoptyping
+
+\def\dowithpargument#1%
+ {\def\nextpar##1 \par{#1{##1}}%
+ \def\nextarg##1{#1{##1}}%
+ \doifnextbgroupelse\nextarg{\doifnextcharelse\par{#1{}}\nextpar}}
+
+%D The \type{p} in the previous command stands for paragraph.
+%D When we want to act upon words we can use the \type{w}
+%D alternative.
+%D
+%D \starttyping
+%D \dowithwargument\command
+%D \dowithwargument{... \command ...}
+%D \stoptyping
+%D
+%D The main difference bwteen two alternatives is in the
+%D handling of \type{\par}'s. This time the space token acts
+%D as a delimiter.
+%D
+%D \starttyping
+%D \command{...}
+%D \command ...
+%D \command
+%D {...}
+%D \command
+%D ...
+%D \stoptyping
+
+\def\dowithwargument#1%
+ {\def\nextwar##1 {#1{##1}}%
+ \def\nextarg##1{#1{##1}}%
+ \doifnextbgroupelse\nextarg\nextwar}
+
+%D \macros
+%D {dorepeat,dorepeatwithcommand}
+%D
+%D When doing repetitive tasks, we stromgly advice to use
+%D \type{\dorecurse}. The next alternative however, suits
+%D better some of the \CONTEXT\ interface commands.
+%D
+%D \starttyping
+%D \dorepeat[n*\command]
+%D \stoptyping
+%D
+%D The value of the used \COUNTER\ can be called within
+%D \type{\command} by \type{\repeater}.
+%D
+%D A slightly different alternative is:
+%D
+%D \starttyping
+%D \dorepeatwithcommand[n*{...}]\command
+%D \stoptyping
+%D
+%D When we call for something like:
+%D
+%D \starttyping
+%D \dorepeatwithcommand[3*{Hello}]\message
+%D \stoptyping
+%D
+%D we get ourselves three \type{\message{Hello}} messages in
+%D a row. In both commands, the \type{n*} is optional. When this
+%D specification is missing, the command executes once.
+
+% this one is obsolete:
+
+\def\dorepeat[#1]%
+ {\dodorepeat#1*\empty*\relax}
+
+\long\def\dodorepeat#1*#2#3*#4\relax
+ {\ifx#2\empty#1\else\dorecurse{#1}{#2#3}\fi}
+
+\def\repeater
+ {\recurselevel}
+
+% this one will be kept
+
+\def\dorepeatwithcommand[#1]%
+ {\dodorepeatwithcommand#1*\empty*\relax}
+
+\long\def\dodorepeatwithcommand#1*#2#3*#4\relax#5%
+ {\ifx#2\empty\redorepeatwithcommand[#1]#5\else\dododorepeatwithcommand{#1}{#2}{#3}#5\fi}
+
+\long\def\dododorepeatwithcommand#1#2#3#4%
+ {\ifx#2\empty % redundant but gives cleaner extensions
+ #4{#1}%
+ \else\ifnum#1<\zerocount
+ \bgroup\scratchcounter#1%
+ \expanded{\egroup\noexpand\dorecurse{\number-\scratchcounter}}{#4{-#2#3}}%
+ \else\ifx#2+%
+ \dorecurse{#1}{#4{#3}}%
+ \else
+ \dorecurse{#1}{#4{#2#3}}%
+ \fi\fi\fi}
+
+\def\redorepeatwithcommand[#1]#2%
+ {#2{#1}}
+
+%D The extension hook permits something like:
+%D
+%D \starttyping
+%D \bgroup
+%D
+%D \catcode`\*=\@@superscript
+%D
+%D \gdef\redorepeatwithcommand[#1]%
+%D {\redodorepeatwithcommand#1*\empty*\relax}
+%D
+%D \long\gdef\redodorepeatwithcommand#1*#2#3*#4\relax#5%
+%D {\dododorepeatwithcommand{#1}{#2}{#3}#5}
+%D
+%D \egroup
+%D \stoptyping
+%D
+%D although one may wonder if changing the catcode of \type {*} is wise.
+
+%D \macros
+%D {normalbgroup,normalgroup}
+%D
+%D No comment.
+
+\let\normalbgroup\bgroup
+\let\normalegroup\egroup
+
+%D \macros
+%D {doifstringinstringelse}
+%D
+%D The next macro is meant for situations where both strings
+%D are macros. This save some unneeded expansion.
+%D
+%D \starttyping
+%D \long\def\doifstringinstringelse#1#2%
+%D {\p!doifinstringelse#1#2%
+%D \@EA\firstoftwoarguments
+%D \else
+%D \@EA\secondoftwoarguments
+%D \fi}
+%D \stoptyping
+%D
+%D A bit faster is:
+
+\def\pp!doifstringinstringelse#1%
+ {\if#1@%
+ \@EA\secondoftwoarguments
+ \else
+ \@EA\firstoftwoarguments
+ \fi}
+
+\long\def\doifstringinstringelse#1#2%
+ {\long\@EA\def\@EA\p!doifstringinstringelse\@EA##\@EA1#1##2##3\war
+ {\pp!doifstringinstringelse##2}%
+ \@EA\@EA\@EA\p!doifstringinstringelse\@EA#2#1@@\war}
+
+%D \macros
+%D {appendtoks,prependtoks,appendtoksonce,prependtoksonce,
+%D doifintokselse,flushtoks,dotoks}
+%D
+%D We use \TOKENLISTS\ sparsely within \CONTEXT, because the
+%D comma separated lists are more suitable for the user
+%D interface. Nevertheless we have:
+%D
+%D \starttyping
+%D (\doglobal) \appendtoks ... \to\tokenlist
+%D (\doglobal) \prependtoks ... \to\tokenlist
+%D (\doglobal) \flushtoks\tokenlist
+%D \dotoks\tokenlist
+%D \stoptyping
+%D
+%D Er worden eerst enkele klad||registers gedefinieerd. These
+%D macros are clones of the ones implemented in page~378 of
+%D Knuth's \TeX book.
+
+\newtoks\@@scratchtoks
+
+\def\appendtoks {\doappendtoks \relax}
+\def\prependtoks {\doprependtoks \relax}
+\def\appendtoksonce {\doappendtoksonce \relax}
+\def\prependtoksonce{\doprependtoksonce\relax}
+
+\def\dodoappendtoks
+ {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@toks\the\@@scratchtoks}}
+
+\def\dodoprependtoks
+ {\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@scratchtoks\the\@@toks}}
+
+\long\def\doappendtoks#1\to#2%
+ {\def\@@toks{#2}%
+ \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoappendtoks}
+
+\long\def\doprependtoks#1\to#2%
+ {\def\@@toks{#2}%
+ \@@scratchtoks\@EA{\gobbleoneargument#1}\dodoprependtoks}
+
+\long\def\doappendtoksonce#1\to#2%
+ {\def\@@toks{#2}%
+ \@@scratchtoks\@EA{\gobbleoneargument#1}%
+ \doifintokselse\@@scratchtoks\@@toks\donothing\dodoappendtoks}
+
+\long\def\doprependtoksonce#1\to#2%
+ {\def\@@toks{#2}%
+ \@@scratchtoks\@EA{\gobbleoneargument#1}%
+ \doifintokselse\@@scratchtoks\@@toks\donothing\dodoprependtoks}
+
+%D The test macro:
+
+\def\doifintokselse#1#2% #1 en #2 zijn toks
+ {\edef\asciia{\detokenize\expandafter{\the#1}}%
+ \edef\asciib{\detokenize\expandafter{\the#2}}%
+ \doifstringinstringelse\asciia\asciib}
+
+%D A nice one too:
+
+% {\scratchtoks{abc} \removetoks b\from\scratchtoks [\the\scratchtoks]}
+% {\scratchtoks{abc} \removetoks x\from\scratchtoks [\the\scratchtoks]}
+% {\scratchtoks{} \removetoks x\from\scratchtoks [\the\scratchtoks]}
+% {\scratchtoks{xaa} \removetoks x\from\scratchtoks [\the\scratchtoks]}
+% {\scratchtoks{a\relax b} \removetoks \relax\from\scratchtoks [\showthe\scratchtoks]}
+
+\def\removetoks#1\from#2%
+ {\def\doremovetoks##1#1##2\empty\empty\empty##3\\%
+ {\def\!!stringa{##3}%
+ \ifx\!!stringa\empty#2{##1}\else#2{##1##2}\fi}%
+ \expandafter\doremovetoks\the#2\empty\empty\empty#1\empty\empty\empty\\}
+
+%D Also:
+
+\def\appendetoks #1\to{\normalexpanded{\noexpand\appendtoks #1}\to}
+\def\prependetoks#1\to{\normalexpanded{\noexpand\prependtoks#1}\to}
+
+%D Hm.
+
+\def\flushtoks#1% nb: can reassing to #1 again, hence the indirectness
+ {\@@scratchtoks#1\relax
+ \dodoglobal#1\emptytoks
+ \the\@@scratchtoks\relax}
+
+\let\dotoks\the
+
+%D \macros
+%D {makecounter,pluscounter,minuscounter,
+%D resetcounter,setcounter,countervalue}
+%D
+%D Declaring, setting and resetting \COUNTERS\ can be done
+%D with the next set of commands.
+%D
+%D \starttyping
+%D \makecounter {name}
+%D \pluscounter {name}
+%D \minuscounter {name}
+%D \resetcounter {name}
+%D \setcounter {name} {value}
+%D \countervalue {name}
+%D \stoptyping
+
+\def\makecounter#1%
+ {\global\@EA\let\csname#1\endcsname\zerocountervalue} % see earlier
+
+\def\countervalue#1%
+ {\ifcsname#1\endcsname\csname#1\endcsname\fi}
+
+\def\pluscounter#1%
+ {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname+\plusone\relax}}
+
+\def\minuscounter#1%
+ {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname#1\endcsname-\plusone\relax}}
+
+\def\resetcounter#1%
+ {\global\@EA\let\csname#1\endcsname\zerocountervalue}
+
+\def\setcounter#1#2%
+ {\@EA\xdef\csname#1\endcsname{\the\numexpr#2\relax}}
+
+\def\savecounter#1%
+ {\@EA\xdef\csname ! #1 !\endcsname{\the\numexpr\csname#1\endcsname\relax}}
+
+\def\restorecounter#1%
+ {\@EA\xdef\csname#1\endcsname{\the\numexpr\csname ! #1 !\endcsname\relax}}
+
+%D \macros
+%D {beforesplitstring,aftersplitstring}
+%D
+%D These both commands split a string at a given point in two
+%D parts, so \type{x.y} becomes \type{x} or \type{y}.
+%D
+%D \starttyping
+%D \beforesplitstring test.tex\at.\to\filename
+%D \aftersplitstring test.tex\at.\to\extension
+%D \stoptyping
+%D
+%D The first routine looks (and is indeed) a bit simpler than
+%D the second one. The alternative looking more or less like
+%D the first one did not always give the results we needed.
+%D Both implementations show some insight in the manipulation
+%D of arguments.
+
+\def\beforesplitstring#1\at#2\to#3%
+ {\def\dosplitstring##1#2##2#2##3\\%
+ {\def#3{##1}}%
+ \@EA\dosplitstring#1#2#2\\}
+
+\def\aftersplitstring#1\at#2\to#3%
+ {\def\dosplitstring##1#2##2@@@##3\\%
+ {\def#3{##2}}%
+ \@EA\dosplitstring#1@@@#2@@@\\}
+
+%D \macros
+%D {splitstring,greedysplitstring}
+%D
+%D A bonus macro.
+
+\def\splitstring#1\at#2\to#3\and#4%
+ {\def\dosplitstring##1#2##2\empty\empty\empty##3\\%
+ {\def#3{##1}%
+ \def\dosplitstring{##3}%
+ \ifx\dosplitstring\empty
+ \let#4\empty
+ \else
+ \def#4{##2}%
+ \fi}%
+ \@EA\dosplitstring#1\empty\empty\empty#2\empty\empty\empty\\}
+
+\def\greedysplitstring#1\at#2\to#3\and#4%
+ {\edef\asciib{#1}%
+ \let\asciic\asciib
+ \let#3\empty
+ \let#4\empty
+ \doloop
+ {\expandafter\splitstring\asciib\at#2\to\asciia\and\asciib
+ \ifx\asciib\empty
+ \exitloop
+ \else
+ % not \edef#3{\ifx#3\empty\else#3#2\fi\asciia} else
+ % /root/path fails because then #3==empty
+ \edef#3{\ifcase\recurselevel\or\else#3#2\fi\asciia}%
+ \let#4\asciib
+ \fi}%
+ \ifx#3\empty\let#3\asciic\fi}
+
+%D \macros
+%D {beforetestandsplitstring,
+%D aftertestandsplitstring,
+%D testandsplitstring}
+
+\def\beforetestandsplitstring#1\at#2\to#3%
+ {\def\dosplitstring##1#2##2#2##3##4\\%
+ {\ifx##3\empty\let#3\empty\else\def#3{##1}\fi}%
+ \@EA\dosplitstring#1#2#2\empty\\}
+
+\def\aftertestandsplitstring#1\at#2\to#3%
+ {\def\dosplitstring ##1#2##2@@@##3##4\\%
+ {\ifx##3\empty\let#3\empty\else\def#3{##2}\fi}%
+ \@EA\dosplitstring #1@@@#2@@@\empty\\}
+
+\def\testandsplitstring#1\at#2\to#3\and#4%
+ {\def\dosplitstring##1#2##2#2##3##4\\%
+ {\ifx##3\empty\let#3\empty\let#4\empty\else\def#3{##1}\def#4{##2}\fi}%
+ \@EA\dosplitstring#1#2#2\empty\\}
+
+%D \macros
+%D {removesubstring}
+%D
+%D A first application of the two routines defined above is:
+%D
+%D \starttyping
+%D \removesubstring-\from first-last\to\nothyphenated
+%D \stoptyping
+%D
+%D Which in terms of \TEX\ looks like:
+
+\def\removesubstring#1\from#2\to#3%
+ {\splitstring#2\to\!!stringa\and\!!stringb
+ \dodoglobal#3{\!!stringa\!!stringb}}
+
+%D \macros
+%D {appendtocommalist,prependtocommalist,
+%D addtocommalist,removefromcommalist}
+%D
+%D When working with comma separated lists, one sooner or
+%D later want the tools to append or remove items from such a
+%D list. When we add an item, we first check if it's already
+%D there. This means that every item in the list is unique.
+%D
+%D \starttyping
+%D \addtocommalist {alfa} \name
+%D \addtocommalist {beta} \name
+%D \addtocommalist {gamma} \name
+%D \removefromcommalist {beta} \name
+%D \stoptyping
+%D
+%D These commands can be prefixed with \type{\doglobal}. The
+%D implementation of the second command is more complecated,
+%D because we have to take leading spaces into account. Keep in
+%D mind that users may provide lists with spaces after the
+%D commas. When one item is left, we also have to get rid of
+%D trailing spaces.
+%D
+%D \starttyping
+%D \def\words{alfa, beta, gamma, delta}
+%D \def\words{alfa,beta,gamma,delta}
+%D \stoptyping
+%D
+%D Removing an item takes more time than adding one.
+%D
+%D A fast appending alternative, without any testing, is
+%D also provided:
+%D
+%D \starttyping
+%D \appendtocommalist {something} \name
+%D \prependtocommalist {something} \name
+%D \stoptyping
+%D
+%D This can be implemented as follows:
+%D
+%D \starttyping
+%D \def\appendtocommalist#1#2%
+%D {\ifx#2\empty
+%D \dodoglobal\edef#2{#1}%
+%D \else % no test on empty
+%D \dodoglobal\edef#2{#2,#1}%
+%D \fi}
+%D
+%D \def\prependtocommalist#1#2%
+%D {\ifx#2\empty
+%D \dodoglobal\edef#2{#1}%
+%D \else % no test on empty
+%D \dodoglobal\edef#2{#1,#2}%
+%D \fi}
+%D \stoptyping
+%D
+%D The faster alternatives are:
+
+\def\appendtocommalist#1#2%
+ {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}
+
+\def\prependtocommalist#1#2%
+ {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}
+
+\def\addtocommalist#1#2% {item} \cs
+ {\rawdoifinsetelse{#1}#2\resetglobal
+ {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}}
+
+\def\pretocommalist#1#2% {item} \cs
+ {\rawdoifinsetelse{#1}#2\resetglobal
+ {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}}
+
+\def\robustdoifinsetelse#1#2%
+ {\edef\!!stringa{\detokenize\expandafter{\normalexpanded{#1}}}%
+ \edef\!!stringb{\detokenize\expandafter{\normalexpanded{#2}}}%
+ \rawdoifinsetelse\!!stringa\!!stringb}
+
+\def\robustaddtocommalist#1#2% {item} \cs
+ {\robustdoifinsetelse{#1}#2\resetglobal
+ {\dodoglobal\edef#2{\ifx#2\empty\else#2,\fi#1}}}
+
+\def\robustpretocommalist#1#2% {item} \cs
+ {\robustdoifinsetelse{#1}#2\resetglobal
+ {\dodoglobal\edef#2{#1\ifx#2\empty\else,#2\fi}}}
+
+\def\xsplitstring#1#2% \cs {str}
+ {\def\dosplitstring##1,#2,##2,#2,##3\\%
+ {\edef\!!stringa{\bcleanedupcommalist##1\empty\empty\relax}%
+ \edef\!!stringb{\acleanedupcommalist##2,,\relax}}%
+ \@EA\dosplitstring\@EA,#1,,#2,,#2,\\}
+
+\def\bcleanedupcommalist#1#2#3\relax{\if#1,\else#1\fi\if#2,\else#2\fi#3}
+\def\bcleanedupcommalist#1#2\relax{\if#1,\else#1\fi#2}
+\def\acleanedupcommalist#1,,#2\relax{#1}
+
+\def\removefromcommalist#1#2% to be sped up
+ {\rawdoifinsetelse{#1}#2%
+ {\normalexpanded{\noexpand\xsplitstring\noexpand#2{#1}}%
+ \dodoglobal\edef#2%
+ {\ifx\!!stringa\empty
+ \!!stringb
+ \else
+ \!!stringa\ifx\!!stringb\empty\else,\!!stringb\fi
+ \fi}}
+ \resetglobal}
+
+%D \macros
+%D {substituteincommalist}
+%D
+%D Slow but seldom used, so for the moment we stick to this
+%D implementation.
+%D
+%D \starttyping
+%D \substituteincommalist{old}{new}{list}
+%D \stoptyping
+
+\def\substituteincommalist#1#2#3% old, new, list (slooow)
+ {\edef\!!stringb{#1}%
+ \edef\!!stringd{#2}%
+ \let\!!stringa#3%
+ \let#3\empty
+ \def\dosubstituteincommalist##1%
+ {\edef\!!stringc{##1}%
+ \ifx\!!stringb\!!stringc
+ \ifx\!!stringd\empty\else
+ \edef#3{#3\ifx#3\empty\else,\fi\!!stringd}%
+ \fi
+ \def\docommand####1{\edef#3{#3,####1}}%
+ \else
+ \edef#3{#3\ifx#3\empty\else,\fi##1}%
+ \fi}%
+ \@EA\rawprocesscommacommand\@EA[\!!stringa]\dosubstituteincommalist}
+
+%D A not so useful macro:
+
+\def\dodofrontstrip[#1#2]#3%
+ {\ifx#1\space
+ \def#3{#2}%
+ \else
+ \def#3{#1#2}%
+ \fi}
+
+\def\dofrontstrip#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty \else
+ \@EA\dodofrontstrip\@EA[#1]#1%
+ \fi}
+
+%D \macros
+%D {replaceincommalist}
+%D
+%D The next macro can be used to replace an indexed element
+%D in a commalist:
+%D
+%D \starttyping
+%D \replaceincommalist\MyList{2}
+%D \stoptyping
+%D
+%D Element~2 will be replaced by the current meaning of the macro
+%D \type {\newcommalistelement}. The old meaning is saved in
+%D \type {\commalistelement}. The replacement honors grouped items,
+%D like in:
+%D
+%D \starttyping
+%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3}
+%D \def\MyList{a,b,c,d,e,f} \replaceincommalist\MyList{3}
+%D \def\MyList{a,{b,c},d,e,f} \replaceincommalist\MyList{3}
+%D \def\MyList{a,b,c,{d,e,f}} \replaceincommalist\MyList{3}
+%D \stoptyping
+
+\let\newcommalistelement\empty
+
+\def\replaceincommalist#1#2% #1 = commalistelement #2 = position starts at 1
+ {\def\doreplaceincommalist##1%
+ {\ifnum\commalistcounter=#2\relax
+ \ifx\newcommalistelement\empty\else
+ \ifx\newcommalist\empty
+ \let\newcommalist\newcommalistelement
+ \else
+ \@EA\@EA\@EA\def\@EA\@EA\@EA\newcommalist\@EA\@EA\@EA
+ {\@EA\newcommalist\@EA,\newcommalistelement}%
+ \fi
+ \fi
+ \def\commalistelement{##1}%
+ \else
+ \ifx\newcommalist\empty
+ \ifx\nexttoken\bgroup % is known -)
+ \def\newcommalist{{##1}}%
+ \else
+ \def\newcommalist{##1}%
+ \fi
+ \else
+ \ifx\nexttoken\bgroup % is known -)
+ \@EA\def\@EA\newcommalist\@EA{\newcommalist,{##1}}%
+ \else
+ \@EA\def\@EA\newcommalist\@EA{\newcommalist,##1}%
+ \fi
+ \fi
+ \fi
+ \advance\commalistcounter\plusone}%
+ \let\commalistelement\empty
+ \let\newcommalist\empty
+ \commalistcounter\plusone
+ \@EA\processcommalist\@EA[#1]\doreplaceincommalist
+ \dodoglobal\let#1\newcommalist}
+
+%D \macros
+%D {globalprocesscommalist}
+%D
+%D The commalist processing commands are characterized by the
+%D fact that the way they handle expansion as well as the fact
+%D that they can be nested. This makes them kind of useless for
+%D handling comma lists in alignments. In these situations the
+%D next macro can be of use.
+
+\def\globalprocesscommaitem#1,%
+ {\if]#1\else
+ \globalcommacommand{#1}%
+ \expandafter\globalprocesscommaitem
+ \fi}
+
+\def\globalprocesscommalist[#1]#2%
+ {\global\let\globalcommacommand#2%
+ \expandafter\globalprocesscommaitem#1,],}
+
+%D \macros
+%D {withoutpt,PtToCm,
+%D numberofpoints,dimensiontocount}
+%D
+%D We can convert point into centimeters with:
+%D
+%D \starttyping
+%D \PtToCm{dimension}
+%D \stoptyping
+
+{\catcode`\.=\@@other
+ \catcode`\p=\@@other
+ \catcode`\t=\@@other
+ \gdef\WITHOUTPT#1pt{#1}}
+
+\def\withoutpt#1%
+ {\expandafter\WITHOUTPT#1}
+
+%D The capitals are needed because \type{p} and \type{t} have
+%D \CATCODE~12, while macronames only permit tokens with the
+%D \CATCODE~11. As a result we cannot use the \type{.group}
+%D primitives. Those who want to know more about this kind of
+%D manipulations, we advice to study the \TEX book in detail.
+%D Because this macro does not do any assignment, we can use it
+%D in the following way too.
+
+\def\PtToCm#1%
+ {\withoutpt\the\dimexpr0.0351459804\dimexpr#1\relax\relax cm}
+
+%D We also support:
+%D
+%D \starttyping
+%D \numberofpoints {dimension}
+%D \dimensiontocount {dimension} {\count}
+%D \stoptyping
+%D
+%D Both macros return a rounded number.
+
+% \dimensiontocount{10.49pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.49pt}
+% \dimensiontocount{10.51pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.51pt}
+
+\def\dimensiontocount#1#2{#2\numexpr\dimexpr#1\relax/\maxcard\relax}
+\def\numberofpoints #1{\the\numexpr\dimexpr#1\relax/\maxcard\relax}
+
+%D \macros
+%D {swapdimens,swapmacros}
+%D
+%D Simple but effective are the next two macros. There name
+%D exactly states their purpose. The \type{\scratchdimen} and
+%D \type{\!!stringa} can only be swapped when being the first
+%D argument.
+
+\def\swapdimens#1#2%
+ {\scratchdimen #1\redoglobal #1#2\dodoglobal #2\scratchdimen}
+
+\def\swapmacros#1#2%
+ {\let\!!stringa#1\redoglobal\let#1#2\dodoglobal\let#2\!!stringa}
+
+%D \macros
+%D {pushmacro,popmacro}
+%D
+%D Premature and a bit of beta, we offer:
+%D
+%D \starttyping
+%D \pushmacro\macro
+%D \popmacro\macro
+%D \stoptyping
+%D
+%D Beware: global!
+
+\def\@sl@{@sl@}
+\def\@sg@{@sg@}
+
+\let\@@pushedmacro\empty
+
+\def\globalpushmacro#1%
+ {\xdef\@@pushedmacro{\string#1}%
+ \ifcsname\@sg@\@@pushedmacro\endcsname \else
+ \@EA\newcount\csname\@sg@\@@pushedmacro\endcsname
+ \fi
+ \global\advance\csname\@sg@\@@pushedmacro\endcsname \plusone
+ \global\@EA\let\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1}
+
+\def\globalpopmacro#1%
+ {\xdef\@@pushedmacro{\string#1}%
+ \global\@EA\let\@EA#1\csname\the\csname\@sg@\@@pushedmacro\endcsname\@@pushedmacro\endcsname
+ \global\advance\csname\@sg@\@@pushedmacro\endcsname \minusone}
+
+\def\localpushmacro#1% this one can be used to push a value over an \egroup
+ {\xdef\@@pushedmacro{\string#1}%
+ \ifcsname\@sl@\@@pushedmacro\endcsname \else
+ \@EA\newcount\csname\@sl@\@@pushedmacro\endcsname
+ \fi
+ \global\advance\csname\@sl@\@@pushedmacro\endcsname \plusone
+ \global\@EA\let\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname#1}
+
+\def\localpopmacro#1%
+ {\xdef\@@pushedmacro{\string#1}%
+ \@EA\let\@EA#1\csname\the\csname\@sl@\@@pushedmacro\endcsname\@@pushedmacro\endcsname
+ \global\advance\csname\@sl@\@@pushedmacro\endcsname \minusone }
+
+\let\pushmacro\localpushmacro
+\let\popmacro \localpopmacro
+
+%D \macros
+%D {setlocalhsize}
+%D
+%D Sometimes we need to work with the \type{\hsize} that is
+%D corrected for indentation and left and right skips. The
+%D corrected value is available in \type{\localhsize}, which
+%D needs to be calculated with \type{\setlocalhsize} first.
+%D
+%D \starttyping
+%D \setlocalhsize \hbox to \localhsize{...}
+%D \setlocalhsize[-1em] \hbox to \localhsize{...}
+%D \setlocalhsize[.5ex] \hbox to \localhsize{...}
+%D \stoptyping
+%D
+%D These examples show us that an optional can be used. The
+%D value provided is added to \type{\localhsize}.
+
+\newdimen\localhsize
+
+\def\complexsetlocalhsize[#1]% don't change !
+ {\localhsize\hsize
+ \ifnum\hangafter<\zerocount
+ \advance\localhsize\ifdim\hangindent>\zeropoint-\fi\hangindent
+ \fi
+ \advance\localhsize -\leftskip
+ \advance\localhsize -\rightskip
+ \advance\localhsize #1\relax}
+
+\def\simplesetlocalhsize
+ {\complexsetlocalhsize[\zeropoint]}
+
+\definecomplexorsimple\setlocalhsize
+
+%D \macros
+%D {doifvalue,doifnotvalue,doifelsevalue,
+%D doifnothing,doifsomething,doifelsenothing,
+%D doifvaluenothing,doifvaluesomething,doifelsevaluenothing}
+%D
+%D These long named \type{\if} commands can be used to access
+%D macros (or variables) that are normally accessed by using
+%D \type{\getvalue}. Using these alternatives safes us three
+%D tokens per call. Anyone familiar with the not||values
+%D ones, can derive their meaning from the definitions.
+
+ \def\doifvalue#1{\doif {\csname#1\endcsname}}
+ \def\doifnotvalue#1{\doifnot {\csname#1\endcsname}}
+ \def\doifelsevalue#1{\doifelse{\csname#1\endcsname}}
+
+ \def\doifnothing#1{\doif {#1}{}}
+ \def\doifsomething#1{\doifnot {#1}{}}
+ \def\doifelsenothing#1{\doifelse{#1}{}}
+
+ \def\doifvaluenothing#1{\doif {\csname#1\endcsname}{}}
+ \def\doifvaluesomething#1{\doifnot {\csname#1\endcsname}{}}
+\def\doifelsevaluenothing#1{\doifelse{\csname#1\endcsname}{}}
+
+%D Faster but spoiling inheritance (copying parameters):
+%D
+%D \starttyping
+%D \def\doifelsevaluesomething#1#2#3%
+%D {\expandafter\ifx\csname#1\endcsname\empty#3\else#2\fi}
+%D
+%D \def\doifvaluesomething#1#2%
+%D {\expandafter\ifx\csname#1\endcsname\empty\else#2\fi}
+%D
+%D \def\doifvaluenothing#1#2%
+%D {\expandafter\ifx\csname#1\endcsname\empty#2\fi}
+%D \stoptyping
+%D
+%D Slightly more efficient:
+
+ \def\doifnothing{\doif \empty}
+ \def\doifsomething{\doifnot \empty}
+\def\doifelsenothing{\doifelse\empty}
+
+%D The somewhat faster alternatives are:
+
+\long\def\doifvalue#1#2%
+ {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\long\def\doifnotvalue#1#2%
+ {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\long\def\doifelsevalue#1#2%
+ {\edef\!!stringa{\csname#1\endcsname}\edef\!!stringb{#2}%
+ \ifx\!!stringa\!!stringb
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\long\def\doifnothing#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\long\def\doifsomething#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\long\def\doifelsenothing#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\long\def\doifsomethingelse#1%
+ {\edef\!!stringa{#1}%
+ \ifx\!!stringa\empty
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+\long\def\doifvaluenothing#1%
+ {\edef\!!stringa{\csname#1\endcsname}%
+ \ifx\!!stringa\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\long\def\doifvaluesomething#1%
+ {\edef\!!stringa{\csname#1\endcsname}%
+ \ifx\!!stringa\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\long\def\doifelsevaluenothing#1%
+ {\edef\!!stringa{\csname#1\endcsname}%
+ \ifx\!!stringa\empty
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D \macros
+%D {doifemptyelsevalue, doifemptyvalue, doifnotemptyvalue}
+%D
+%D Also handy:
+
+\def\doifemptyelsevalue#1%
+ {\@EA\ifx\csname#1\endcsname\empty
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\doifemptyvalue#1%
+ {\@EA\ifx\csname#1\endcsname\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\doifnotemptyvalue#1%
+ {\@EA\ifx\csname#1\endcsname\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+%D \macros
+%D {doifallcommonelse}
+%D
+%D A complete match of two sets can be tested with
+%D \type {\doifallcommonelse}, where the first two
+%D arguments are sets.
+
+\def\@@doifallcommonelse#1#2#3#4% slow
+ {\def\p!docommoncheck##1%
+ {\doifnotinset{##1}{#4}\donefalse
+ \ifdone\else\expandafter\quitcommalist\fi}%
+ \donetrue
+ \processcommalist[#3]\p!docommoncheck
+ \ifdone\expandafter#1\else\expandafter#2\fi}
+
+\def\doifallcommonelse
+ {\@@doifallcommonelse\firstoftwoarguments\secondoftwoarguments}
+
+\def\doifallcommon
+ {\@@doifallcommonelse\firstofonearguments\gobbleoneargument}
+
+\def\doifnotallcommon
+ {\@@doifallcommonelse\gobbleoneargument\firstofonearguments}
+
+%D \macros
+%D {DOIF,DOIFELSE,DOIFNOT}
+%D
+%D \TEX\ is case sensitive. When comparing arguments, this
+%D feature sometimes is less desirable, for instance when we
+%D compare filenames. The next three alternatives upcase their
+%D arguments before comparing them.
+%D
+%D \starttyping
+%D \DOIF {string1} {string2} {...}
+%D \DOIFNOT {string1} {string2} {...}
+%D \DOIFELSE {string1} {string2} {then ...}{else ...}
+%D \stoptyping
+%D
+%D We have to use a two||step implementation, because the
+%D expansion has to take place outside \type{\uppercase}.
+
+\def\p!DOIF#1#2%
+ {\uppercase{\ifinstringelse{$#1$}{$#2$}}%
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\def\p!DOIFNOT#1#2%
+ {\uppercase{\ifinstringelse{$#1$}{$#2$}}%
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+\def\p!DOIFELSE#1#2%
+ {\uppercase{\ifinstringelse{$#1$}{$#2$}}%
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\p!DOIFINSTRINGELSE#1#2%
+ {\uppercase{\ifinstringelse{#1}{#2}}%
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\DOIF {\ExpandBothAfter\p!DOIF}
+\def\DOIFNOT {\ExpandBothAfter\p!DOIFNOT}
+\def\DOIFELSE {\ExpandBothAfter\p!DOIFELSE}
+\def\DOIFINSTRINGELSE {\ExpandBothAfter\p!DOIFINSTRINGELSE}
+
+%D \macros
+%D {dosingleargumentwithset,
+%D dodoubleargumentwithset,dodoubleemptywithset,
+%D dotripleargumentwithset,dotripleemptywithset}
+%D
+%D These maybe too mysterious macros enable us to handle more
+%D than one setup at once.
+%D
+%D \starttyping
+%D \dosingleargumentwithset \command[#1]
+%D \dodoubleargumentwithset \command[#1][#2]
+%D \dotripleargumentwithset \command[#1][#2][#3]
+%D \dodoubleemptywithset \command[#1][#2]
+%D \dotripleemptywithset \command[#1][#2][#3]
+%D \stoptyping
+%D
+%D The first macro calls \type{\command[##1]} for each string
+%D in the set~\type{#1}. The second one calls for
+%D \type{\commando[##1][#2]} and the third, well one may guess.
+%D These commands support constructions like:
+%D
+%D \starttyping
+%D \def\dodefinesomething[#1][#2]%
+%D {\getparameters[\??xx#1][#2]}
+%D
+%D \def\definesomething%
+%D {\dodoubleargumentwithset\dodefinesomething}
+%D \stoptyping
+%D
+%D Which accepts calls like:
+%D
+%D \starttyping
+%D \definesomething[alfa,beta,...][variable=...,...]
+%D \stoptyping
+%D
+%D Now a whole bunch of variables like \type{\@@xxalfavariable}
+%D and \type{\@@xxbetavariable} is defined.
+
+\def\dodoublewithset[#1][#2]%
+ {\doifsomething{#1}
+ {\def\@@dodowithsetcommand##1{\@@dowithsetcommand[##1][#2]}%
+ \processcommalist[#1]\@@dodowithsetcommand}}
+
+\def\dotriplewithset[#1][#2][#3]%
+ {\doifsomething{#1}
+ {\def\@@dodowithsetcommand##1{\@@dowithsetcommand[##1][#2][#3]}%
+ \processcommalist[#1]\@@dodowithsetcommand}}
+
+\def\dodoubleemptywithset #1{\let\@@dowithsetcommand#1\dodoubleempty \dodoublewithset} % \command
+\def\dodoubleargumentwithset#1{\let\@@dowithsetcommand#1\dodoubleargument\dodoublewithset} % \command
+
+\def\dotripleemptywithset #1{\let\@@dowithsetcommand#1\dotripleempty \dotriplewithset} % \command
+\def\dotripleargumentwithset#1{\let\@@dowithsetcommand#1\dotripleargument\dotriplewithset} % \command
+
+%D \macros
+%D {stripcharacters,stripspaces}
+%D
+%D The next command was needed first when we implemented
+%D the \CONTEXT\ interactivity macros. When we use labeled
+%D destinations, we often cannot use all the characters we
+%D want. We therefore strip some of the troublemakers, like
+%D spaces, from the labels before we write them to the
+%D \DVI||file, which passes them to for instance a PostScript
+%D file.
+%D
+%D \starttyping
+%D \stripspaces\from\one\to\two
+%D \stoptyping
+%D
+%D Both the old string \type{\one} and the new one \type{\two}
+%D are expanded. This command is a special case of:
+%D
+%D \starttyping
+%D \stripcharacter\char\from\one\to\two
+%D \stoptyping
+%D
+%D As we can see below, spaces following a control sequence are
+%D to enclosed in \type{{}}.
+
+\def\stripcharacter#1\from#2\to#3%
+ {\def\dostripcharacter##1#1##2\end
+ {\edef\!!strippedstring{\!!strippedstring##1}%
+ \doifnotempty{##2}{\dostripcharacter##2\end}}%
+ \let\!!strippedstring\empty
+ \edef\!!stringa{#2}%
+ \@EA\dostripcharacter\!!stringa#1\end
+ \dodoglobal\let#3\!!strippedstring}
+
+\def\stripspaces\from#1\to#2% will become \unspacestring#1\from#2
+ {\stripcharacter{ }\from#1\to#2}
+
+%D \macros
+%D {unspacestring}
+%D
+%D The next macro does the same but is more compatible with other macros,
+%D like \type {\convert...}.
+
+\def\unspacestring#1\to#2%
+ {\stripcharacter{ }\from#1\to#2}
+
+%D \macros
+%D {executeifdefined}
+%D
+%D \CONTEXT\ uses one auxiliary file for all data concerning
+%D tables of contents, references, two||pass optimizations,
+%D sorted lists etc. This file is loaded as many times as
+%D needed. During such a pass we skip the commands thate are of
+%D no use at that moment. Because we don't want to come into
+%D trouble with undefined auxiliary commands, we call the
+%D macros in a way similar to \type{\getvalue}. The next macro
+%D take care of such executions and when not defined, gobbles
+%D the unwanted arguments.
+%D
+%D \starttyping
+%D \executeifdefined{name}\gobbleoneargument
+%D \stoptyping
+%D
+%D We can of course gobble more arguments using the
+%D appropriate gobbling command.
+
+\newif\ifexecuted % general purpose
+
+\def\executeifdefined#1% #2 / never change this one again
+ {\ifcsname#1\endcsname
+ \csname#1\expandafter\expandafter\expandafter\endcsname\expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+%D This one also has the advantage that it is fully
+%D expandable and that it can be used after an assignment.
+
+%D \macros
+%D {doifsomespaceelse}
+%D
+%D The next command checks a string on the presence of a space
+%D and executed a command accordingly.
+%D
+%D \starttyping
+%D \doifsomespaceelse {tekst} {then ...} {else ...}
+%D \stoptyping
+%D
+%D We use this command in \CONTEXT\ for determing if an
+%D argument must be broken into words when made interactive.
+%D Watch the use of \type{\noexpand}.
+
+%D Is this one still needed?
+
+\def\p!doifsomespaceelse#1 #2#3\war{\if\noexpand#2@}
+
+\long\def\doifsomespaceelse#1% % #2#3%
+ {\p!doifsomespaceelse#1 @ @\war % #3\else#2\fi}
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+%D \macros
+%D {adaptdimension,balancedimensions}
+%D
+%D Again we introduce some macros that are closely related to
+%D an interface aspect of \CONTEXT. The first command can be
+%D used to adapt a \DIMENSION.
+%D
+%D \starttyping
+%D \adaptdimension {dimension} {value}
+%D \stoptyping
+%D
+%D When the value is preceed by a \type{+} or minus, the
+%D dimension is advanced accordingly, otherwise it gets the
+%D value.
+
+\def\doadaptdimension#1#2\\#3\\%
+ {\if#1+%
+ \dodoglobal\advance
+ \else\if#1-%
+ \dodoglobal\advance
+ \else
+ \dodoglobal
+ \fi\fi
+ #3 #1#2\relax}
+
+\def\adaptdimension#1#2%
+ {\expandafter\doadaptdimension#2\\#1\\}
+
+%D A second command takes two \DIMENSIONS. Both are adapted,
+%D depending on the sign of the given value.
+%D maat. This time we take the value as it is, and don't look
+%D explicitly at the preceding sign.
+%D
+%D \starttyping
+%D \balancedimensions {dimension 1} {dimension 2} {value}
+%D \stoptyping
+%D
+%D When a positive value is given, the first dimension is
+%D incremented, the second ond is decremented. A negative value
+%D has the opposite result.
+
+\def\balancedimensions#1#2#3%
+ {\scratchdimen#3\relax
+ \redoglobal\advance#1 \scratchdimen
+ \dodoglobal\advance#2 -\scratchdimen}
+
+%D Both commands can be preceded by \type{\doglobal}. Here we
+%D use \type{\redo} first, because \type{\dodo} resets the
+%D global character.
+
+%D \macros
+%D {processseparatedlist}
+%D
+%D Maybe a bit late, but here is a more general version of the
+%D \type{\processcommalist} command. This time we don't handle
+%D nesting but accept arbitrary seperators.
+%D
+%D \starttyping
+%D \processseparatedlist[list][separator]\command
+%D \stoptyping
+%D
+%D One can think of things like:
+%D
+%D \starttyping
+%D \processseparatedlist[alfa+beta+gamma][+]\message
+%D \stoptyping
+%D
+%D We want to handle all situations, like:
+%D
+%D \startbuffer
+%D \processseparatedlist[{aap noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
+%D \processseparatedlist[{aap} {noot}][ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
+%D \processseparatedlist[aap {noot}] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
+%D \processseparatedlist[aap noot] [ ]{\def\xxx} \convertcommand\xxx\to\ascii {\tttf\ascii}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D Therefore we smuggle a \type {\relax} in front of the
+%D argument, which we remove afterwards.
+
+\def\doprocessseparatedlist#1]#2[#3]#4%
+ {\def\dodoprocessseparatedlist##1##2#3%
+ {\def\!!stringa{##2}% suggested by VZ
+ \if]##1%
+ \let\dodoprocessseparatedlist\relax
+ \else\ifx\blankspace\!!stringa
+ #4{##1}%
+ \else\if]##2%
+ \let\dodoprocessseparatedlist\relax
+ \else
+ #4{##1##2}%
+ \fi\fi\fi
+ \dodoprocessseparatedlist}%
+ \@EA\dodoprocessseparatedlist\gobbleoneargument#1#3]#3}
+
+\def\processseparatedlist[%
+ {\doprocessseparatedlist\relax}
+
+%D \macros
+%D {processlist}
+%D
+%D An even more general list processing macro is the
+%D following one:
+%D
+%D \starttyping
+%D \processlist{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 \processlist(){=>}\docommand(a=>b=>c=>d)
+%D \stoptyping
+
+\long\def\processlist#1#2#3#4% no blank skipping !
+ {\def\doprocesslist##1#2%
+ {\def\dodoprocesslist####1####2#3%
+ {\ifx#2####1%
+ \let\dodoprocesslist\relax
+ \else\ifx#2####2%
+ \let\dodoprocesslist\relax
+ \else
+ #4{####1####2}%
+ \fi\fi
+ \dodoprocesslist}%
+ \expandafter\dodoprocesslist\gobbleoneargument##1#3#2#3}%
+ \def\dodoprocesslist#1%
+ {\doprocesslist\relax}%
+ \dodoprocesslist}
+
+%D \macros
+%D {processassignlist}
+%D
+%D Is possible to combine an assignment list with one
+%D containing keywords. Assignments are treated accordingly,
+%D keywords are treated by \type{\command}.
+%D
+%D \starttyping
+%D \processassignlist[...=...,...=...,...]\commando
+%D \stoptyping
+%D
+%D This command can be integrated in \type{\getparameters}, but
+%D we decided best not to do so.
+
+\def\processassignlist#1[#2]#3%
+ {\def\p!dodogetparameter[##1=##2=##3]%
+ {\doifnot{##3}\relax{#3{##1}}}%
+ \def\p!dogetparameter##1%
+ {\p!dodogetparameter[##1==\relax]}%
+ \processcommalist[#2]\p!dogetparameter}
+
+%D \macros
+%D {untextargument
+%D untexcommand}
+%D
+%D When manipulating data(bases) and for instance generating
+%D index entries, the next three macros can be of help:
+%D
+%D \starttyping
+%D \untextargument{...}\to\name
+%D \untexcommand {...}\to\name
+%D \stoptyping
+%D
+%D They remove braces and backslashes and give us something to
+%D sort.
+
+\def\untexsomething
+ {\begingroup
+ \catcode`\{=\@@ignore
+ \catcode`\}=\@@ignore
+ \escapechar\minusone
+ \dountexsomething}
+
+\long\def\dountexsomething#1#2\to#3%
+ {\doglobal#1#2\to\untexedargument
+ \endgroup
+ \let#3\untexedargument}
+
+\def\untexargument{\untexsomething\convertargument}
+\def\untexcommand {\untexsomething\convertcommand}
+
+%D \macros
+%D {ScaledPointsToBigPoints,ScaledPointsToWholeBigPoints}
+%D
+%D One characteristic of \POSTSCRIPT\ and \PDF\ is that both
+%D used big points (\TEX's bp). The next macros convert points
+%D and scaled points into big points.
+%D
+%D \starttyping
+%D \ScaledPointsToBigPoints {number} \target
+%D \ScaledPointsToWholeBigPoints {number} \target
+%D \stoptyping
+%D
+%D The magic factor $72/72.27$ can be found in most \TEX\
+%D related books.
+
+% \PointsToBigPoints{10.53940pt}\test \test
+% \PointsToBigPoints{10.53941pt}\test \test
+% \PointsToBigPoints{10.53942pt}\test \test
+
+% \PointsToWholeBigPoints{10.53940pt}\test \test
+% \PointsToWholeBigPoints{10.53941pt}\test \test
+% \PointsToWholeBigPoints{10.53942pt}\test \test
+
+\def\PointsToBigPoints#1#2%
+ {\edef#2{\withoutpt\the\dimexpr.996264\dimexpr#1\relax\relax}}
+
+\def\PointsToWholeBigPoints#1#2%
+ {\edef#2{\the\numexpr\dimexpr.996264\dimexpr#1\relax\relax/\maxcard\relax}}
+
+\def\ScaledPointsToBigPoints #1{\PointsToBigPoints {\number#1\scaledpoint}}
+\def\ScaledPointsToWholeBigPoints#1{\PointsToWholeBigPoints{\number#1\scaledpoint}}
+
+%D \macros
+%D {PointsToReal}
+%D
+%D Points can be stripped from their suffix by using
+%D \type{\withoutpt}. The next macro enveloppes this macro.
+%D
+%D \starttyping
+%D \PointsToReal {dimension} \target
+%D \stoptyping
+
+\def\PointsToReal#1#2%
+ {\scratchdimen#1%
+ \edef#2{\withoutpt\the\scratchdimen}}
+
+%D \macros
+%D {dontleavehmode}
+%D
+%D Sometimes when we enter a paragraph with some command, the
+%D first token gets the whole first line. We can prevent this
+%D by saying:
+%D
+%D \starttyping
+%D \dontleavehmode
+%D \stoptyping
+%D
+%D This command is used in for instance the language module
+%D \type{lang-ini}. The first version was:
+%D
+%D \starttyping
+%D \def\dontleavehmode{\ifhmode\else\ifmmode\else$ $\fi\fi}
+%D \stoptyping
+%D
+%D Next, Taco came with a better alternative (using mathsurround):
+%D
+%D \starttyping
+%D \def\dontleavehmode
+%D {\ifhmode\else \ifmmode\else
+%D {\mathsurround\zeropoint\everymath\emptytoks$ $}%
+%D \fi \fi}
+%D \stoptyping
+%D
+%D And finaly we got the following alternative, one that avoids
+%D interfering grouping at the cost of a box.
+
+\newbox\@@dlhbox
+
+\unexpanded \def\dontleavehmode
+ {\ifhmode\else \ifmmode\else
+ \setbox\@@dlhbox\hbox{\mathsurround\zeropoint\everymath\emptytoks$ $}\unhbox\@@dlhbox
+ \fi \fi}
+
+%D But, if you run a recent version of \TEX, we can use the new
+%D primitive:
+
+\ifdefined\normalquitvmode \let\dontleavehmode\normalquitvmode \fi
+
+%D \macros
+%D {uppercasestring,lowercasestring}
+%D
+%D The names tell what they do:
+%D
+%D \starttyping
+%D \uppercasestring somestring\to\somestring
+%D \lowercasestring somestring\to\somestring
+%D \stoptyping
+%D
+%D the first argument may be a \type{\macro}.
+
+\def\uppercasestring#1\to#2% first @EA redundant
+ {\uppercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}}
+
+\def\lowercasestring#1\to#2% first @EA redundant
+ {\lowercase\@EA{\@EA\dodoglobal\@EA\edef\@EA#2\@EA{\normalexpanded{#1}}}}
+
+%D \macros
+%D {handletokens}
+%D
+%D With the next macro we enter a critical area of macro
+%D expansion. What we want is a macro that looks like:
+%D
+%D \starttyping
+%D \handletokens some tokens\with \somemacro
+%D \stoptyping
+%D
+%D A bonus example:
+%D
+%D \starttyping
+%D \hbox{\handletokens tekst en meer tekst\with\ruledhbox}
+%D
+%D \def\weetikveel#1{\if#1\blankspace\space\else\ruledhbox{#1}\fi}
+%D
+%D \hbox{\handletokens tekst en meer tekst\with\weetikveel}
+%D \stoptyping
+
+%D \macros
+%D {counttoken,counttokens}
+%D
+%D For the few occasions that we want to know the number of
+%D specific tokens in a string, we can use:
+%D
+%D \starttyping
+%D \counttoken token\in string\to \somecount
+%D \counttokens string\to \somecount
+%D \stoptyping
+%D
+%D This macro, that for instance is used in \type{cont-tab},
+%D takes a real counter. The macro can be preceded by \type
+%D {\doglobal}.
+
+\def\counttoken#1\in#2\to#3%
+ {\scratchcounter\zerocount
+ \def\!!stringa{#1}%
+ \def\!!stringb{\end}%
+ \def\docounttoken##1% obeys {}
+ {\def\!!stringc{##1}%
+ \ifx\!!stringb\!!stringc \else
+ \ifx\!!stringa\!!stringc
+ \advance\scratchcounter\plusone
+ \fi
+ \expandafter\docounttoken
+ \fi}%
+ \docounttoken#2\end
+ \dodoglobal#3\scratchcounter}
+
+\def\counttokens#1\to#2%
+ {\scratchcounter\zerocount
+ \def\docounttoken##1{\advance\scratchcounter\plusone}%
+ \handletokens#1\with\docounttoken
+ \dodoglobal#2\scratchcounter}
+
+%D \macros
+%D {splitofftokens}
+%D
+%D Running this one not always gives the expected results.
+%D Consider for instance the macro for which I originally
+%D wrote this token handler.
+
+\long\def\splitofftokens#1\from#2\to#3% slow but hardly used
+ {\ifnum#1>\zerocount
+ \scratchcounter#1\relax
+ \def\dosplitofftokens##1%
+ {\ifnum\scratchcounter>\zerocount
+ \advance\scratchcounter \minusone
+ \edef#3{#3##1}%
+ \fi}%
+ % \let#3\empty % #3 can be #2, so:
+ \@EA\let\@EA#3\@EA\empty
+ \@EA\handletokens#2\with\dosplitofftokens
+ \else
+ \edef#3{#2}%
+ \fi}
+
+%D This macro can be called like:
+%D
+%D \startbuffer[example]
+%D \splitofftokens10\from01234567 890123456789\to\test [\test]
+%D \stopbuffer
+%D
+%D However, the characters that we expect to find in
+%D \type{\test} just don't show up there. The reason for this
+%D is not that logical but follows from \TEX's sometimes
+%D mysterious way of expanding. Look at this:
+%D
+%D \startbuffer[next]
+%D \def\next{a} \edef\test{\next} [\test]
+%D \let\next=b \edef\test{\test\next} [\test]
+%D \let\next=c \edef\test{\next} [\test]
+%D \let\next=d \edef\test{\test\next} [\test]
+%D \let\next=e \@EA\edef\@EA\test\@EA{\test\next} [\test]
+%D \stopbuffer
+%D
+%D \typebuffer[next]
+%D
+%D Careful reading shows that inside an \type{\edef} macro's
+%D that are \type{\let} are not expanded!
+%D
+%D \unprotect\getbuffer[next]\protect
+%D
+%D That's why we finally end up with a macro that looks
+%D ahead by using an assignment, this time by using \type
+%D {\futurelet}, and grabbing an argument as well. That
+%D way we can handle the sentinal, a blank space and grouped
+%D tokens.
+
+\def\dohandletokens % \nexthandledtoken is part of interface
+ {\futurelet\nexthandledtoken\dodohandletokens}
+
+\long\def\handletokens#1\with#2%
+ {\gdef\dododohandletokens{#2}% permits more complex #2's
+ \dohandletokens#1\end}
+
+\def\dodohandletokens
+ {\ifx\nexthandledtoken\blankspace
+ \expandafter\dodohandletokensone
+ \else\ifx\nexthandledtoken\end
+ \expandafter\expandafter\expandafter\gobbletwoarguments % also gobble the \end
+ \else
+ \expandafter\expandafter\expandafter\dodohandletokenstwo
+ \fi\fi *}
+
+\def\dodohandletokensone * %
+ {\dododohandletokens{ }\dohandletokens}
+
+\long\def\dodohandletokenstwo *#1%
+ {\dododohandletokens{#1}\dohandletokens}
+
+%D This macro is tested on:
+%D
+%D \def\xxx#1{[#1]}
+%D
+%D \startlines
+%D \handletokens abc\with\xxx
+%D \handletokens a b c\with\xxx
+%D \handletokens a b c\with\xxx
+%D \handletokens a{bc}d\with\xxx
+%D \handletokens a\space bc \with\xxx
+%D \stoplines
+%D
+%D And our previous example shows up as:
+%D
+%D \getbuffer[example]
+
+%D \macros
+%D {iftrialtypesetting, ifvisible}
+%D
+%D The next boolean is at first sight a strange one. Sometimes
+%D one does a trial typesetting run, for instance to determine
+%D dimensions. Some mechanisms, like object inclusion, can fail
+%D on such trials. Temporary setting the next boolean to true,
+%D helps a lot. The second boolena can be used to inhibit
+%D processing completely.
+
+\newif\iftrialtypesetting \trialtypesettingfalse
+\newif\ifvisible \visibletrue
+
+%D \macros
+%D {startlocal, startglobal}
+%D
+%D The next four macros are rather self explaining:
+%D
+%D \starttyping
+%D \startlocal
+%D whatever assignments
+%D \stoplocal
+%D
+%D \startglobal
+%D whatever assignments
+%D \stopglobal
+%D \stoptyping
+%D
+%D These macros are meant for those who know the difference
+%D between local and global assignments and are aware of the
+%D possible unwanted side effect
+
+\def\dostartglobaldefs#1#2%
+ {\scratchcounter\globaldefs
+ \ifnum\globaldefs#1\zerocount
+ \globaldefs-\globaldefs
+ \fi
+ \advance\globaldefs#2\plusone
+ \expandafter\chardef\csname@gd@\the\globaldefs\endcsname\scratchcounter}
+
+\def\dostopglobaldefs
+ {\globaldefs\ifcsname @gd@\the\globaldefs\endcsname\zerocount}
+
+\def\startlocal {\dostartglobaldefs>-}
+\def\stoplocal {\dostopglobaldefs}
+\def\startglobal {\dostartglobaldefs<+}
+\def\stopglobal {\dostopglobaldefs}
+
+%D \macros
+%D {twodigitrounding}
+%D
+%D When using \type {\special}s or \type {\pdfliteral}s, it
+%D sometimes makes sense to limit the precission. The next
+%D macro rounds a real number to two digits. It takes one
+%D argument and only works in \ETEX.
+
+\def\dointegerrounding #1.#2\relax {#1}
+\def\doonedigitrounding #1.#2#3\relax {\ifx#2*#1\else#1.#2\fi}
+\def\dotwodigitrounding #1.#2#3#4\relax {\ifx#2*#1\else#1.#2#3\fi}
+\def\dothreedigitrounding#1.#2#3#4#5\relax{\ifx#2*#1\else#1.#2#3#4\fi}
+
+\def\integerrounding#1%
+ {\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.5\points \relax .\relax}
+\def\onedigitrounding#1%
+ {\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.05\points \relax 00.*0\relax}
+\def\twodigitrounding#1%
+ {\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.005\points \relax 000.*00\relax}
+\def\threedigitrounding#1%
+ {\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax0000.*00\relax}
+
+%D \macros
+%D {processcontent}
+%D
+%D This is the first occasion where \TEX\ and \ETEX\ are no
+%D longer compatible, although in many cases things go ok.
+%D Beware of verbatim, i.e. catcode changes.
+%D
+%D \starttyping
+%D \def\starthans%
+%D {\processcontent{stophans}\test{\message{\test}\wait}}
+%D \stoptyping
+%D
+%D This macro is first used in the tabulation macros.
+
+\def\processcontent#1%
+ {\begingroup\@EA\doprocesscontent\csname#1\endcsname}
+
+\def\doprocesscontent#1#2#3%
+ {\long\def\doprocesscontent##1#1%
+ {\endgroup\long\def#2{##1}#3}%
+ \doprocesscontent}
+
+%D \macros
+%D {dogobblesingleempty, dogobbledoubleempty}
+%D
+%D These two macros savely grab and dispose two arguments.
+
+\def\dogobblesingleempty{\dosingleempty\dodogobblesingleempty}
+\def\dogobbledoubleempty{\dodoubleempty\dodogobbledoubleempty}
+
+\def\dodogobblesingleempty [#1]{}
+\def\dodogobbledoubleempty[#1][#2]{}
+
+\let\gobblesingleempty\dogobblesingleempty % also used
+\let\gobbledoubleempty\dogobbledoubleempty % also used
+
+%D \macros
+%D {sortcommalist,sortcommacommand,
+%D donumericcompare,comparedresult}
+%D
+%D Sometimes we need to sort a commalist, so here is Taco's
+%D solution. This will in many cases be a list that is stored
+%D in a \type{\csname}, so both commalist and commacommands are
+%D supported. The sorting algorithm is very simple, so the list
+%D should not be too long or sorting will be very slow.
+%D
+%D \starttyping
+%D \sortcommalist[10,2,4,5,6,1,2,3,4,10,20]\donumericcompare
+%D
+%D \def\test{10,2,4,5,6,1,2,3,4,10,20}
+%D
+%D \sortcommacommand[\test]\donumericcompare
+%D \stoptyping
+%D
+%D In both cases, the result is available in the macro \type
+%D {\sortedcommalist}.
+%D
+%D Parameter \type{#2} is a macro that should accept two
+%D parameters, and it has to decide which one is larger, by
+%D setting the counter \type{\comparedresult} to~0 (for equal),
+%D 1~(if it's first argument is larger), or~2 (if it's second
+%D argument is larger).
+%D
+%D As said, these macro are largely written by Taco, and are
+%D (maybe therefore) also the first application of \type
+%D {\replaceincommalist}.
+
+\newcount\comparedresult
+
+\def\sortcommacommand[#1]%
+ {\@EA\sortcommalist\@EA[#1]}
+
+\def\sortcommalist[#1]#2%
+ {\getcommalistsize[#1]%
+ \ifnum\commalistsize>1
+ \let\sortedcommalist\empty
+ \let\comparecommand#2%
+ \processcommalist[#1]\dosortcommacommand
+ \else
+ \def\sortedcommalist{#1}%
+ \fi}
+
+\def\dosortcommacommand#1%
+ {\ifx\sortedcommalist\empty
+ \def\sortedcommalist{#1}%
+ \else
+ \def\!!tempa{#1}%
+ \ifx\!!tempa\empty\else
+ \scratchcounter\plusone
+ \@EA\getcommalistsize\@EA[\sortedcommalist]%
+ \@EA\processcommalist\@EA[\sortedcommalist]\docompareitems
+ \fi
+ \fi}
+
+%D All those \type{\expandafter}'s are there because I do not
+%D want to use \type{\edef}.
+
+\def\docompareitems#1%
+ {\doifnotempty{#1}
+ {\@EA\comparecommand\@EA{\!!tempa}{#1}\relax
+ %\ifcase\compareresult % equal
+ \ifnum\comparedresult<2
+ \ifnum\scratchcounter=\commalistsize
+ \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist
+ \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}%
+ \fi
+ %\or % new element larger
+ % \ifnum\scratchcounter=\commalistsize
+ % \@EA\@EA\@EA\def\@EA\@EA\@EA\sortedcommalist
+ % \@EA\@EA\@EA{\@EA\sortedcommalist\@EA,\!!tempa}%
+ % \fi
+ \else % old element larger
+ \@EA\def\@EA\newcommalistelement\@EA{\!!tempa,#1}%
+ \replaceincommalist\sortedcommalist\scratchcounter
+ \expandafter\quitcommalist
+ \fi}%
+ \advance\scratchcounter \plusone} % bug, was \minusone
+
+%D The macro \type{\donumericcompare} considers everything
+%D that is not a number to be larger than any number.
+
+% 0: both are equal, 1: #1 is larger, 2: #2 is larger
+
+\def\thenumericcompare#1#2% no \relax es inside hee
+ {\doifnumberelse{#1}
+ {\doifnumberelse{#2}{\ifnum#1>#2 \plusone\else\ifnum#1<#2 \plustwo\else\zerocount\fi\fi}\plustwo}
+ \plusone}
+
+\def\donumericcompare
+ {\comparedresult\thenumericcompare}
+
+%D \macros
+%D {@True, @False, @Not, @And}
+%D
+%D Some predicate logic functions, used in for instance the
+%D math module.
+
+\def\@True {00}
+\def\@False {01}
+\def\@Not #1{0\ifcase#11 \or\@EA 1\else \@EA 0\fi}
+\def\@And #1#2{0\ifcase#1#2 \@EA 0\else \@EA 1\fi}
+
+%D \macros
+%D {setdimensionwithunit, freezedimensionwithunit}
+%D
+%D The next assignments are all valid:
+%D
+%D \starttyping
+%D \setdimensionwithunit\scratchdimen{10} {cm}
+%D \setdimensionwithunit\scratchdimen{10cm}{cm}
+%D \setdimensionwithunit\scratchdimen{10cm}{}
+%D \freezedimensionwithunit\SomeWidth{\textwidth}
+%D \freezedimensionwithunit\SomeDepth{\dp\strutbox}
+%D \stoptyping
+%D
+%D As an alternative for the next macro we can use a global
+%D assignment inside a box. The \type{\empty}'s permits
+%D gobbling while preventing spurious \type{\relax}'s.
+
+\def\setdimensionwithunit#1#2#3% number unit dimension / nice trick
+ {\afterassignment\gobblefourarguments#1=#2#3pt\relax\empty\empty\empty\empty}
+
+\def\freezedimensionwithunit#1#2%
+ {\setdimensionwithunit\scratchdimen#1{#2}\edef#1{\the\scratchdimen}}
+
+%D \macros
+%D {doifsometokselse}
+%D
+%D Not that fast I guess, but here's a way to test for token
+%D registers being empty.
+
+\def\doifsometokselse#1% % #2#3%
+ {\edef\!!stringa{\the#1}%
+ \ifx\!!stringa\empty % #3\else#2\fi}
+ \expandafter\secondoftwoarguments
+ \else
+ \expandafter\firstoftwoarguments
+ \fi}
+
+%D \macros
+%D {startstrictinspectnextcharacter}
+%D
+%D This one if for Taco's bibliography module:
+
+\let\normalinspectnextcharacter\inspectnextcharacter
+
+\def\strictinspectnextcharacter% no user macro !
+ {\ifx\nexttoken\charactertoken
+ \expandafter\!!stringa
+ \else
+ \expandafter\!!stringb
+ \fi}
+
+% better: push/pop
+
+\def\startstrictinspectnextcharacter
+ {\let\inspectnextcharacter\strictinspectnextcharacter}
+
+\def\stopstrictinspectnextcharacter
+ {\let\inspectnextcharacter\normalinspectnextcharacter}
+
+%D \macros
+%D {gobblespacetokens}
+%D
+%D This macro needs a speed-up!
+
+%\def\gobblespacetokens
+% {\doifnextcharelse\empty\donothing\donothing} % no {}\do\do !
+
+\def\gobblespacetokens
+ {\afterassignment\nexttoken\let\nexttoken=}
+
+%D \macros
+%D {verbatimargument}
+%D
+%D As the name says, this macro converts its argument to a
+%D (rather safe) string.
+
+\let\verbatimstring\detokenize
+
+%D These are needed in ordinal number conversions:
+
+\def\lastdigit#1%
+ {\@EA\thelastdigit\number#1\relax}
+
+\def\thelastdigit#1#2%
+ {\ifx#2\relax#1\else\@EA\thelastdigit\@EA#2\fi}
+
+\def\lasttwodigits#1%
+ {\@EA\thelasttwodigits\@EA0\number#1\relax}
+
+\def\thelasttwodigits#1#2#3% 0 dig ... \relax
+ {\ifx#3\relax#1#2\else\@EA\thelasttwodigits\@EA#2\@EA#3\fi}
+
+%D \macros
+%D {serializecommalist}
+%D
+%D Concatenate commalists:
+
+\def\serializecommalist[#1]%
+ {\let\serializedcommalist\empty
+ \def\docommand##1{\edef\serializedcommalist{\serializedcommalist##1}}%
+ \processcommacommand[#1]\docommand}
+
+%D \macros
+%D {purenumber}
+%D
+%D Sometimes we need control over when \TEX\ stops reading a
+%D number, especially in full expandable macros where using
+%D \type {\relax} would lead to disasters.
+%D
+%D \starttyping
+%D \ifodd\purenumber{...}\space ... \else ... \fi
+%D \stoptyping
+%D
+%D Here we use a space as number delimiter in combination
+%D with a space- and relax-less \type {\purenumber}. This
+%D macro works ok with \type {\the}, \type {\number} as well
+%D as \ETEX's \type {\numexpr}.
+
+\def\purenumber#1{\@EA\firstofoneargument\@EA{\number#1}}
+
+%D \macros
+%D {filterfromvalue}
+%D
+%D \starttyping
+%D \setvalue{xx}{{A}{B}{C}}
+%D
+%D \filterfromvalue{xx}{3}{3}
+%D \filterfromvalue{xx}{3}{2}
+%D \filterfromvalue{xx}{3}{1}
+%D \stoptyping
+%D
+%D An alternative is to store 'max' in the list, say:
+%D
+%D \starttyping
+%D \setvalue{xx}{3{A}{B}{C}}
+%D
+%D \filterfromvalues{3}{xx}{3}
+%D \filterfromvalues{3}{xx}{2}
+%D \filterfromvalues{3}{xx}{1}
+%D \stoptyping
+%D
+%D I'll implement this when I'm in \quotation {writing dirty
+%D macros mood}.
+
+\def\dofilterfromstr#1#2% max n % no need to be fast
+ {\expandafter \expandafter \expandafter \strippedcsname
+ \ifcase#1\or \ifcase#2\or
+ \firstofoneargument \else
+ \gobbleoneargument \fi
+ \or \ifcase#2\or
+ \firstoftwoarguments \or
+ \secondoftwoarguments \else
+ \gobbletwoarguments \fi
+ \or \ifcase#2\or
+ \firstofthreearguments \or
+ \secondofthreearguments \or
+ \thirdofthreearguments \else
+ \gobblethreearguments \fi
+ \or \ifcase#2\or
+ \firstoffourarguments \or
+ \secondoffourarguments \or
+ \thirdoffourarguments \or
+ \fourthoffourarguments \else
+ \gobblefourarguments \fi
+ \or \ifcase#2\or
+ \firstoffivearguments \or
+ \secondoffivearguments \or
+ \thirdoffivearguments \or
+ \fourthoffivearguments \or
+ \fifthoffivearguments \else
+ \gobblefivearguments \fi
+ \fi}
+
+\def\filterfromvalue#1#2#3% value max n
+ {\@EA\@EAEAEA\csname % we use the fact that an
+ \@EA\ifx\csname#1\endcsname\relax % undefined cs has become \relax
+ \strippedcsname\gobbleoneargument % which we then gobble here
+ \else
+ \dofilterfromstr{#2}{#3}%
+ \fi
+ \endcsname\csname#1\endcsname}
+
+\def\filterfromnext#1#2% max n {..}{..}{..}{..}
+ {\csname\dofilterfromstr{#1}{#2}\endcsname}
+
+%D \macros
+%D {definemeasure}
+%D
+%D \starttyping
+%D \definemeasure[mywidth][\dimexpr(\textwidth-1cm)]
+%D
+%D ... \measure{mywidth} ...
+%D \stoptyping
+
+\def\??dm{@@dm} % brrr
+
+\def\definemeasure
+ {\dodoubleargument\dodefinemeasure}
+
+\def\dodefinemeasure[#1][#2]%
+ {\expandafter\def\csname\??dm#1\endcsname{#2}}
+
+% #2 could be omitted, but we want to support spaces
+%
+% \setmeasure {x} {1cm}
+% \setmeasure {xx} {1cm}
+% \setmeasure {xxx}{1cm}
+
+\def\setmeasure #1#2{\expandafter\def \csname\??dm#1\endcsname{#2}} % quick way
+\def\setemeasure#1#2{\expandafter\edef\csname\??dm#1\endcsname{#2}} % quick way
+\def\setgmeasure#1#2{\expandafter\gdef\csname\??dm#1\endcsname{#2}} % quick way
+\def\setxmeasure#1#2{\expandafter\xdef\csname\??dm#1\endcsname{#2}} % quick way
+
+\def\measure#1%
+ {\ifcsname\??dm#1\endcsname\csname\??dm#1\endcsname\else\zeropoint\fi}
+
+%D \macros
+%D {doifdimensionelse}
+%D
+%D This is a dirty one: we simply append a unit and discard it when needed.
+
+\def\doifdimensionelse#1%
+ {\afterassignment\dodoifdimensionelse\scratchdimen#1pt\relax}
+
+\def\dodoifdimensionelse#1%
+ {\ifx#1\relax
+ \expandafter\secondoftwoarguments
+ \else % #1=p ... t\relax
+ \expandafter\thirdoffourarguments
+ \fi}
+
+%D \macros
+%D {comparedimension,comparedimensioneps}
+%D
+%D This is a dirty one: we simply append a unit and discard it when needed.
+
+\newdimen\roundingeps \roundingeps=10sp
+
+\def\comparedimension#1#2%
+ {\chardef\compresult
+ \ifdim#1<#2%
+ \zerocount
+ \else\ifdim#1<#2%
+ \plusone
+ \else
+ \plustwo
+ \fi\fi}
+
+\def\comparedimensioneps#1#2% todo: use eps feature
+ {\chardef\compresult
+ \ifdim\dimexpr#1-#2\relax<\roudingeps
+ \zerocount
+ \else\ifdim\dimexpr#2-#1\relax<\roudingeps
+ \zerocount
+ \else\ifdim#1<#2%
+ \plusone
+ \else
+ \plustwo
+ \fi\fi\fi}
+
+% % % % % % % % % % % % % % % % % % % % % %
+
+% pretty ugly but fast
+
+% \copycsname xxx\endcsname\csname ..\endcsname
+
+\def\copycsname{\@EA\@EA\@EA\let\@EA\@EA\csname}
+
+% \letcscsname \crap \csname ..\endcsname
+% \letcsnamecs \csname ..\endcsname\crap
+% \letcsnamecsname\csname ..\endcsname\csname ..\endcsname
+
+\def\letcscsname {\@EA\let\@EA}
+\def\letcsnamecs {\@EA\let}
+\def\letcsnamecsname{\@EA\@EA\@EA\let\@EA\@EA}
+
+% another one, add an item to a commalist
+
+\def\addvalue#1#2% cs item
+ {\ifcsname#1\endcsname\else\expandafter\let\csname#1\endcsname\empty\fi
+ \normalexpanded{\noexpand\addtocommalist{#2}\@EA\noexpand\csname#1\endcsname}}
+
+\def\unspaced#1%
+ {\dounspaced#1\end}
+
+\def\dounspaced#1%
+ {\ifx#1\end
+ \@EA\gobbleoneargument
+ \else
+ \ifx#1\blankspace\else#1\fi
+ \fi
+ \dounspaced}
+
+\def\unspaceargument#1\to#2%
+ {\scratchcounter\catcode32\relax
+ \catcode32\@@ignore\scantextokens{\edef#2{#1}}%
+ \catcode32\scratchcounter}
+
+\def\unspaceafter#1#2%
+ {\unspaceargument#2\to\ascii
+ \expandafter#1\expandafter{\ascii}}
+
+% sometimes handy:
+
+\def\doifhasspaceelse#1%
+ {\edef\!!stringa{#1}%
+ \normalexpanded{\noexpand\dodoifhasspaceelse#1\space}\empty\relax}
+
+\def\dodoifhasspaceelse#1 #2#3\relax % \space\empty\relax
+ {\ifx\!!stringa\space
+ \@EA\firstoftwoarguments
+ \else\ifx#2\empty
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \@EAEAEA\firstoftwoarguments
+ \fi\fi}
+
+% this will replace loadfile once and alike !!! todo
+
+\def\@flg@{@flg@}
+
+\def\setflag #1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\zerocount}
+\def\resetflag#1{\@EA\dodoglobal\@EA\let\csname\@flg@#1\endcsname\plusone}
+
+\let\ifflagged\ifcase
+
+\def\flag#1{\csname\@flg@#1\endcsname}
+
+\def\doifelseflagged#1%
+ {\@EA\ifx\csname\@flg@#1\endcsname\relax
+ \@EA\secondoftwoarguments
+ \else\ifcase\csname\@flg@#1\endcsname
+ \@EAEAEA\firstoftwoarguments
+ \else
+ \@EAEAEA\secondoftwoarguments
+ \fi\fi}
+
+\def\doifnotflagged#1%
+ {\@EA\ifx\csname\@flg@#1\endcsname\relax
+ \@EA\firstofoneargument
+ \else\ifcase\csname\@flg@#1\endcsname
+ \@EAEAEA\gobbleoneargument
+ \else
+ \@EAEAEA\firstofoneargument
+ \fi\fi}
+
+\def\inheritparameter[#1]#2[#3]#4[#5]% tag tokey fromkey % [bypasses k!prefix]
+ {\@EA\def\csname#1#3\@EA\endcsname\@EA{\csname#1#5\endcsname}}
+
+% \buildarray[test][aa,bb,cc,dd,ee,ff]
+% \setarrayelement{test}{1}{qq}
+% \arrayelement{test}{1}
+% \arraylength{test}
+%
+% \def\buildarray[#1][#2]%
+% {\scratchcounter=0
+% \def\docommand##1%
+% {\advance\scratchcounter by 1
+% \setvalue{@@aa#1\the\scratchcounter}{##1}}%
+% \processcommalist[#2]\docommand
+% \setevalue{@@aa#1}{\the\scratchcounter}}%
+%
+% \def\setarrayelement#1#2{\setvalue{@@aa#1#2}}
+% \def\arrayelement #1#2{\getvalue{@@aa#1#2}}
+% \def\arraylength #1{\getvalue{@@aa#1}}
+
+% \newsignal\junksignal
+%
+% \def\setjunksignal%
+% {\ifhmode
+% \hskip\junksignal
+% \let\removejunkspaces\doremovejunkspaces
+% \else
+% \let\removejunkspaces\relax
+% \fi}
+%
+% \def\doremovejunkspaces%
+% {\doloop{\ifdim\lastskip=\junksignal\unskip\else\exitloop\fi}}
+
+\def\dodoifnonzeropositiveelse#1#2\end % #3#4%
+ {\ifx#1\relax
+ \ifcase\scratchcounter
+ \endgroup
+ \@EAEAEA\secondoftwoarguments
+ \else
+ \endgroup
+ \@EAEAEA\firstoftwoarguments
+ \fi
+ \else
+ \endgroup
+ \@EA\secondoftwoarguments
+ \fi}
+
+\def\doifnonzeropositiveelse#1%
+ {\begingroup\afterassignment\dodoifnonzeropositiveelse\scratchcounter=0#1\relax\empty\end}
+
+% here ?
+
+\def\dosetrawvalue #1#2#3{\@EA \def\csname#1#2\endcsname{#3}}
+\def\dosetrawevalue#1#2#3{\@EA\edef\csname#1#2\endcsname{#3}}
+\def\dosetrawgvalue#1#2#3{\@EA\gdef\csname#1#2\endcsname{#3}}
+\def\dosetrawxvalue#1#2#3{\@EA\xdef\csname#1#2\endcsname{#3}}
+
+\def\getrawparameters {\dogetparameters\dosetrawvalue }
+\def\getraweparameters {\dogetparameters\dosetrawevalue}
+\def\getrawgparameters {\dogetparameters\dosetrawgvalue}
+\def\getrawxparameters {\dogetparameters\dosetrawxvalue}
+
+\def\globalgetrawparameters{\dogetparameters\dosetrawgvalue} % obsolete
+
+\def\splitskip#1%
+ {\scratchskip#1\relax
+ \dimen0\scratchskip
+ \dimen2\gluestretch\scratchskip
+ \dimen4\glueshrink\scratchskip}
+
+\newcount\modcounter
+
+\def\dosetmodulo#1#2#3%
+ {\modcounter#1\divide\modcounter#2\multiply\modcounter#2%
+ #3#1\advance#3-\modcounter}
+
+\def\dosetdivision#1#2#3%
+ {#3#1\divide#3 #2\relax}
+
+\def\DoMod#1by#2to#3{\dosetmodulo {#1}{#2}{#3}}
+\def\DoDiv#1by#2to#3{\dosetdivision{#1}{#2}{#3}}
+
+\def\dounprotected#1\par
+ {#1\protect}
+
+\def\unprotected
+ {\unprotect\dounprotected}
+
+% awaiting the definitive implementation
+
+\ifdefined\resettimer \else
+ \let\resettimer \relax
+ \newcount\elapsedtime
+\fi
+
+\newcount\featuretest
+
+\def\testfeature#1#2%
+ {\def\dotestfeature
+ {\advance\featuretest \plusone
+ \ifnum\featuretest>#1\else#2\expandafter\dotestfeature\fi}%
+ \retestfeature}
+
+\def\retestfeature % timer support is new per 10/5/2005
+ {\bgroup
+ \ifcase\interactionmode\let\wait\relax\fi
+ \writestatus\m!systems{starting feature test}\wait
+ \resettimer
+ \featuretest\zerocount \dotestfeature
+ \writestatus\m!systems{feature test done (\elapsedseconds s)}%
+ \wait
+ \egroup}
+
+\def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax}
+
+\def\showtimer#1%
+ {\writestatus{runtime}{\elapsedseconds\space s / #1}}
+
+\def\testfeatureonce#1#2%
+ {\let\wait\relax\testfeature{#1}{#2}\end}
+
+%D \macros
+%D {freezedimenmacro}
+%D
+%D This macro is use as:
+%D
+%D \starttyping
+%D \freezedimenmacro\leftmargindistance
+%D \stoptyping
+
+\def\freezedimenmacro#1%
+ {\edef#1{\the\dimexpr#1}}
+
+%D The next macro negates a macro (dimension or number, or actually, whatever.
+%D It's a typical example of \type {\if} usage:
+%D
+%D \starttyping
+%D \if-\whatever \else-\whatever\fi => else => -whatever
+%D \if--\whatever\else-\whatever\fi => then => whatever
+%D \stoptyping
+
+\def\negated#1{\if-#1\else-#1\fi} % does only work in macros or text
+
+% This permits things like ^\index{hans}^, where hans is
+% duplicated in the text.
+
+\newif\ifduplicate
+
+\bgroup
+
+\gdef\checkduplication % in line with Knuth
+ {\ifmmode\expandafter^\else\expandafter\startduplication\fi}
+
+\gdef\insideduplication
+ {\ifmmode\expandafter^\else\expandafter\egroup\fi}
+
+\catcode`\^=\@@active
+
+\gdef\enableduplication
+ {\catcode`\^=\@@active \let^\checkduplication}
+
+\gdef\disableduplication
+ {\catcode`\^=\@@superscript}
+
+\gdef\startduplication
+ {\bgroup \duplicatetrue \let^\insideduplication}
+
+\egroup
+
+\def\gobbleassigndimen#1\\{}
+
+\def\assigndimen#1#2%
+ {\afterassignment\gobbleassigndimen#1=#2\!!zeropoint\\}
+
+\def\setusage#1%
+ {\@EA\let\csname#1\endcsname\iftrue}
+
+\def\resetusage#1%
+ {\@EA\let\csname#1\endcsname\iffalse}
+
+\def\ifusage#1%
+ {\ifcsname#1\endcsname\else
+ \resetusage{#1}%
+ \fi
+ \csname#1\endcsname}
+
+%D Very handy, more efficient than \type{{}}, and more readable
+%D than \type {\empty}.
+
+\let\donothing\empty
+
+% The following macros are used in XML handling.
+
+\long\setvalue{@u@s@"}#1#2"{#2} \long\setvalue{@g@s@"}#1#2"{\scratchtoks{#2}}
+\long\setvalue{@u@s@'}#1#2'{#2} \long\setvalue{@g@s@'}#1#2'{\scratchtoks{#2}}
+\long\setvalue{@u@s@ }#1#2 {#2} \long\setvalue{@g@s@ }#1#2 {\scratchtoks{#2}}
+
+\long\def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1}
+\long\def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1}
+
+\def\dowithgrabbedstring#1%
+ {\def\@@dowithgrabbedstring{#1}%
+ \afterassignment\@@dowithgrabbedstring\grabstring}
+
+\def\expifequalelse#1#2%
+ {\@@ifequal#1\relax\relax\@@and#2\relax\relax\@@then}
+
+\def\@@ifequal#1#2\@@and#3%
+ {\ifx#1\relax
+ \ifx#3\relax
+ \@EAEAEA\@@if@@equal@@true
+ \else
+ \@EAEAEA\@@if@@equal@@false
+ \fi
+ \else
+ \ifx#3\relax
+ \@EAEAEAEAEAEA\@@if@@equal@@false
+ \else\ifx#1#3%
+ % go on
+ \else
+ \@EAEAEAEAEAEA\@@if@@equal@@false
+ \fi\fi
+ \fi
+ \@@ifequal#2\@@and}
+
+\long\def\@@if@@equal@@true #1\@@then#2#3{#2}
+\long\def\@@if@@equal@@false#1\@@then#2#3{#3}
+
+%D new stuff :
+
+\def\partialexpanded#1%
+ {\let\@@notexpanded\noexpand
+ \long\xdef\@@expanded{\noexpand#1}%
+ \let\@@notexpanded\empty
+ \@@expanded}
+
+\def\appended#1#2#3{\@EA#1\@EA#2\@EA{#2#3}}
+\def\appendvalue #1{\@EA\appended\@EA \def\csname#1\endcsname}
+\def\appendgvalue#1{\@EA\appended\@EA\gdef\csname#1\endcsname}
+
+\def\prepended#1#2#3{\scratchtoks{#3}\@EA\@EA\@EA#1\@EA\@EA\@EA#2\@EA\@EA\@EA{\@EA\the\@EA\scratchtoks#2}}
+\def\prependvalue #1{\@EA\prepended\@EA \def\csname#1\endcsname}
+\def\prependgvalue#1{\@EA\prepended\@EA\gdef\csname#1\endcsname}
+
+%D \macros
+%D {compresscommacommandnrs,compresscommalistnrs,compressedcommalistnrs,
+%D compresscommacommand,compresscommalist,compressedcommalist,
+%D reversecommacommand,reversecommalist,reversedcommalist}
+%D
+%D The following two list processing macros are needed by Taco's
+%D bibliography module. The numbers compressor converts the
+%D list in a list of ranges. The normal compressor remove duplicate
+%D and empty entries.
+
+\def\compresscommalistnrs[#1]%
+ {\let\compressedlist\empty
+ \!!counta\maxdimen
+ \!!countb\maxdimen
+ \processcommalist[#1]\docompresslistnrs
+ \ifnum\!!counta=\maxdimen\else\dodocompresslistnrs\fi}
+
+\def\compresscommacommandnrs[#1]%
+ {\normalexpanded{\noexpand\compresscommalistnrs[#1]}}
+
+\def\docompresslistnrs#1%
+ {\edef\commalistelement{#1}%
+ \ifx\commalistelement\empty\else
+ \ifnum\!!counta=\maxdimen
+ \!!counta\commalistelement\relax
+ \!!countb\!!counta
+ \else
+ \advance\!!countb\plusone
+ \ifnum\commalistelement>\!!countb
+ \advance\!!countb\minusone
+ \dodocompresslistnrs
+ \!!counta\commalistelement\relax
+ \!!countb\!!counta
+ \fi
+ \fi
+ \fi}
+
+\def\dodocompresslistnrs
+ {\edef\compressedlist
+ {\ifx\compressedlist\empty\else\compressedlist,\fi
+ {\the\!!counta}{\ifnum\!!countb>\!!counta\the\!!countb\fi}}}
+
+%D \def\test#1{{\tttf#1->\compresscommalistnrs[#1]\defconvertedcommand\ascii\compressedlist\ascii}}
+%D \startlines
+%D \test{}
+%D \test{1}
+%D \test{1,3}
+%D \test{1,3,4}
+%D \test{1,3,3,4,5}
+%D \test{1,3,3,4,5,8}
+%D \test{1,3,3,4,5,5,8,10}
+%D \test{1,3,4,5,8,10,11}
+%D \test{1,,3,,4,,5,,8,,10,,11,}
+%D \stoplines
+
+\def\compresscommalist[#1]%
+ {\let\compressedlist\empty
+ \let\!!stringa\empty
+ \processcommalist[#1]\docompresslist}
+
+\def\compresscommacommand[#1]%
+ {\normalexpanded{\noexpand\compresscommalist[#1]}}
+
+\def\docompresslist#1%
+ {\edef\commalistelement{#1}%
+ \ifx\commalistelement\empty \else
+ \ifx\!!stringa\commalistelement \else
+ \ifx\compressedlist\empty
+ \def\compressedlist{#1}%
+ \else
+ \appended\def\compressedlist{,#1}%
+ \fi
+ \let\!!stringa\commalistelement
+ \fi
+ \fi}
+
+%D \def\test#1{{\tttf#1->\compresscommalist[#1]\defconvertedcommand\ascii\compressedlist\ascii}}
+%D \startlines
+%D \test{}
+%D \test{1}
+%D \test{1,3}
+%D \test{1,3,4}
+%D \test{1,3,3,4,5}
+%D \test{1,3,3,4,5,8}
+%D \test{1,3,3,4,5,5,8,10}
+%D \test{1,3,4,5,8,10,11}
+%D \test{1,,3,,4,,5,,8,,10,,11,}
+%D \stoplines
+
+\def\reversecommalist[#1]%
+ {\let\reversedlist\empty
+ \processcommalist[#1]\doreverselist}
+
+\def\doreverselist#1%
+ {\ifx\reversedlist\empty
+ \def\reversedlist{#1}%
+ \else
+ \prepended\def\reversedlist{#1,}%
+ \fi}
+
+\def\reversecommacommand[#1]%
+ {\normalexpanded{\noexpand\reversecommalist[#1]}}
+
+%D \def\test#1{{\tttf#1->\reversecommalist[#1]\defconvertedcommand\ascii\reversedlist\ascii}}
+%D \startlines
+%D \test{}
+%D \test{1}
+%D \test{1,3}
+%D \test{1,3,4}
+%D \test{1,3,3,4,5}
+%D \test{1,3,3,4,5,8}
+%D \test{1,3,3,4,5,5,8,10}
+%D \test{1,3,4,5,8,10,11}
+%D \test{1,,3,,4,,5,,8,,10,,11,}
+%D \stoplines
+
+%D \macros
+%D {stripstring}
+%D
+%D Needed in bookmarks:
+%D
+%D \starttyping
+%D {\sanitizePDFdocencoding test \CONTEXT\ test \to\oeps\stripstring\oeps\tttf[\oeps]}
+%D \stoptyping
+
+\def\stripstring#1% #1 is \cs
+ {\edef\cs{\ctxlua
+ {tex.sprint(tex.vrbcatcodes,string.strip(\!!bs\detokenize\expandafter{#1}\!!es))}}}
+
+%D \macros
+%D {dowithrange}
+%D
+%D This one is for Mojca Miklavec, who made me aware of the fact that
+%D \type {page-imp.tex} was not the best place to hide it.
+
+\def\dowithrange#1#2% #2 takes number
+ {\splitstring#1\at:\to\fromrange\and\torange
+ \ifx\torange\empty\let\torange\fromrange\fi
+ \dostepwiserecurse\fromrange\torange1{#2{\recurselevel}}}
+
+%D \macros {uncompresslist}
+%D
+%D When given a list like \type{1,4-7,9} as argument, this macro
+%D will store the expanded commalist in \type{\uncompressedlist}.
+%D
+%D \startbuffer
+%D \def\MojcaHasToDoTheTasks[#1]#2%
+%D {{\uncompresslist[#1]%
+%D \def\processitem##1{I have to do ##1 #2\par}%
+%D \processcommacommand[\uncompressedlist]\processitem}}
+%D
+%D \MojcaHasToDoTheTasks [1-4,7,9-11] {until tomorrow}
+%D \stopbuffer
+%D
+%D Here is an example of how to use \type {\uncompresslist}:
+%D \typebuffer
+%D
+%D The output of this is:
+%D
+%D \getbuffer
+
+\def\uncompresslist[#1]% by TH
+ {\let\uncompressedlist\empty
+ \def\docompressedlistitem##1-##2-%
+ {\@EA\dorecurse\@EA
+ {\the\numexpr1+##2-##1\relax}%
+ {\@EA\appendtocommalist\@EA{\the\numexpr##1-1+####1\relax}\uncompressedlist}}%
+ \def\douncompresslist##1%
+ {\doifinstringelse{-}{##1}
+ {\docompressedlistitem##1-}
+ {\appendtocommalist{##1}\uncompressedlist}}%
+ \processcommalist[#1]\douncompresslist}
+
+%D \macros
+%D {ignoreimplicitspaces}
+%D
+%D \startbuffer
+%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignorespaces}
+%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b}
+%D \def\whatever[#1]{\expanded{\definedfont[#1 at 12pt]}\ignoreimplicitspaces}
+%D {a\whatever[Serif]b a\whatever[Serif] b a\whatever[Serif]\space b}
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\ignoreimplicitspaces
+ {\doifnextcharelse\relax\relax\relax}
+
+% new
+%
+% \startnointerference
+% all kind of code
+% \stopnointerference
+
+\newbox\nointerferencebox
+
+\def\startnointerference % not even grouped !
+ {\setbox\nointerferencebox\vbox
+ \bgroup}
+
+\def\stopnointerference
+ {\egroup
+ \setbox\nointerferencebox\emptybox}
+
+% \def\appendtovaluelist#1#2%
+% {\ifcsname#1\endcsname
+% \expandafter\ifx\csname#1\endcsname\empty
+% \expandafter\def\csname#1\endcsname{#2}%
+% \else
+% \expandafter\def\csname#1\expandafter\expandafter\expandafter\endcsname
+% \expandafter\expandafter\expandafter{\csname#1\endcsname,#2}%
+% \fi
+% \else
+% \expandafter\def\csname#1\endcsname{#2}%
+% \fi}
+%
+% or
+%
+% \def\appendtovaluelist#1%
+% {\ifcsname#1\endcsname
+% \expandafter\ifx\csname#1\endcsname\empty
+% \expandafter\noappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname
+% \else
+% \expandafter\doappendtovaluelist\csname#1\expandafter\expandafter\expandafter\endcsname
+% \fi
+% \else
+% \expandafter\noappendtovaluelist\csname#1\expandafter\endcsname
+% \fi}
+
+% \def\doappendtovaluelist#1#2{\expandafter\def\expandafter#1\expandafter{#1,#2}}
+% \def\noappendtovaluelist#1#2{\def#1{#2}}
+
+% \appendtovaluelist{mylist}{aap}
+% \appendtovaluelist{mylist}{noot}
+% \appendtovaluelist{mylist}{mies}
+
+% \showvalue{mylist}
+
+\protect \endinput
diff --git a/tex/context/base/syst-cat.mkii b/tex/context/base/syst-cat.mkii
deleted file mode 100644
index 614610258..000000000
--- a/tex/context/base/syst-cat.mkii
+++ /dev/null
@@ -1,61 +0,0 @@
-%D \module
-%D [ file=syst-cat,
-%D version=2006.09.18,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Catcode Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\newcatcodetable#1%
- {\global\advance\cctdefcounter\plusone
- \global\mathchardef#1\cctdefcounter
- \expandafter\xdef\csname @@ccn:\number\cctdefcounter\endcsname{\string#1}% logging
- \expandafter\newtoks\csname @@cct:\number\cctdefcounter\endcsname}
-
-\mathchardef\currentcatcodetable\zerocount
-
-\newtoks \setdefaultlowercatcodes
-\newtoks \setdefaultuppercatcodes
-
-\def\next#1% we don't have a proper loop defined yet
- {\edef\nextnext{#1{\the#1\catcode\the\cctcountera\space\ifnum\catcode\cctcountera=11 11\else12\fi}}%
- \nextnext\ifnum\cctcountera<\cctcounterb \advance\cctcountera\plusone \expandafter\next\expandafter#1\fi}
-
-\cctcountera 0 \cctcounterb 127 \next\setdefaultlowercatcodes
-\cctcountera 128 \cctcounterb 255 \next\setdefaultuppercatcodes
-
-% \chardef\activehackcode=`~
-
-% \def\next#1% we don't have a proper loop defined yet
-% {\catcode\cctcountera 13
-% \cctcounterc\uccode\activehackcode
-% \uccode\activehackcode\cctcountera
-% \catcode\uccode\activehackcode 13
-% \uppercase{\edef~{\detokenize{~}}}%
-% \uccode\activehackcode\cctcounterc
-% \ifnum\cctcountera<\cctcounterb \advance\cctcountera\plusone \expandafter\next\expandafter#1\fi}
-
-% \cctcountera 128 \cctcounterb 255 \next\setdefaultuppercatcodes
-
-\recatcodeuppercharactersfalse
-
-\def\catcodetable#1%
- {\mathchardef\currentcatcodetable#1%
- \the\setdefaultlowercatcodes
- \ifrecatcodeuppercharacters\the\setdefaultuppercatcodes\fi
- \the\csname @@cct:\number#1\endcsname}
-
-\long\def\startcatcodetable#1#2\stopcatcodetable
- {\global\csname @@cct:\number#1\endcsname{#2}}
-
-\long\def\startextendcatcodetable#1#2\stopextendcatcodetable
- {\global\csname @@cct:\number#1\endcsname\expandafter{\the\csname @@cct:\number#1\endcsname#2}}
-
-\protect \endinput
diff --git a/tex/context/base/syst-cat.mkiv b/tex/context/base/syst-cat.mkiv
deleted file mode 100644
index b387eb2ed..000000000
--- a/tex/context/base/syst-cat.mkiv
+++ /dev/null
@@ -1,124 +0,0 @@
-%D \module
-%D [ file=syst-cat,
-%D version=2006.09.18,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Catcode Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\newcatcodetable#1%
- {\global\advance\cctdefcounter\plusone
- \expandafter\xdef\csname @@ccn:\number\cctdefcounter\endcsname{\string#1}% logging
- \global\mathchardef#1\cctdefcounter}
-
-\newcatcodetable \scratchcatcodetable \initcatcodetable\scratchcatcodetable
-
-\ifx\nilcatcodes \undefined \newcatcodetable \nilcatcodes \fi
-\ifx\texcatcodes \undefined \newcatcodetable \texcatcodes \fi
-\ifx\ctxcatcodes \undefined \newcatcodetable \ctxcatcodes \fi
-\ifx\notcatcodes \undefined \newcatcodetable \notcatcodes \fi
-\ifx\mthcatcodes \undefined \newcatcodetable \mthcatcodes \fi % brrr
-\ifx\vrbcatcodes \undefined \newcatcodetable \vrbcatcodes \fi
-\ifx\prtcatcodes \undefined \newcatcodetable \prtcatcodes \fi
-\ifx\xmlcatcodesn\undefined \newcatcodetable \xmlcatcodesn \fi % normal
-\ifx\xmlcatcodese\undefined \newcatcodetable \xmlcatcodese \fi % entitle
-\ifx\xmlcatcodesr\undefined \newcatcodetable \xmlcatcodesr \fi % reduce
-\ifx\typcatcodesa\undefined \newcatcodetable \typcatcodesa \fi % { }
-\ifx\typcatcodesb\undefined \newcatcodetable \typcatcodesb \fi % < >
-
-\newtoks \setdefaultcatcodes
-
-\setdefaultcatcodes
- {\catcode`\\ 12
- \catcode`\^^M 12
- \catcode`\ 12
- \catcode`\% 12
- \catcode127 12 }
-
-\long\def\startcatcodetable#1#2\stopcatcodetable
- {\bgroup
- \catcodetable\scratchcatcodetable
- \the\setdefaultcatcodes
- #2%
- \savecatcodetable#1\relax
- \egroup}
-
-\newcatcodetable\dummycatcodes
-
-% \long\def\startextendcatcodetable#1#2\stopextendcatcodetable
-% {\bgroup
-% \catcodetable#1\relax
-% #2%
-% \savecatcodetable\dummycatcodes
-% \catcodetable\dummycatcodes
-% \savecatcodetable#1\relax
-% \egroup}
-
-\long\def\startextendcatcodetable#1#2\stopextendcatcodetable
- {\bgroup
- \catcodetable#1\relax
- \globaldefs\plusone
- #2%
- \globaldefs\zerocount
- \egroup}
-
-% ==
-%
-% \long\def\startextendcatcodetable#1#2\stopextendcatcodetable
-% {\bgroup
-% \scratchcounter\the\catcodetable
-% \catcodetable #1 #2
-% \catcodetable\scratchcounter
-% \egroup}
-
-\def\letcatcodecommand
- {\afterassignment\letcatcodecommanda\cctcountera}
-
-\def\letcatcodecommanda
- {\afterassignment\letcatcodecommandb\cctcounterb}
-
-% construct the definition in lua
-%
-% \def\letcatcodecommandb
-% {\scratchcounter\catcode\cctcounterb \catcode\cctcounterb=13
-% \directlua\CTXlua{tex.print(tex.texcatcodes,"\\xdef " .. string.char(\number\cctcounterb)
-% .. "{\\noexpand\\catcodecommand{\number\cctcounterb}}")}%
-% \catcode\cctcounterb\scratchcounter
-% \expandafter\let\csname cc:\number\cctcountera:\number\cctcounterb\endcsname}
-%
-% or less messy:
-%
-% \def\letcatcodecommandb
-% {\chardef\savedcctcode\catcode\cctcounterb
-% \catcode\cctcounterb=13
-% \expandafter\edef\directlua\CTXlua{tex.sprint(tex.texcatcodes,string.char(\number\cctcounterb))}%
-% {\noexpand\catcodecommand{\number\cctcounterb}}%
-% \catcode\cctcounterb\savedcctcode
-% \expandafter\let\csname cc:\number\cctcountera:\number\cctcounterb\endcsname}
-
-\let\currentcatcodetable\catcodetable
-
-\startruntimectxluacode
- tex.nilcatcodes = \number\nilcatcodes ;
- tex.texcatcodes = \number\texcatcodes ;
- tex.ctxcatcodes = \number\ctxcatcodes ;
- tex.notcatcodes = \number\notcatcodes ;
- tex.mthcatcodes = \number\mthcatcodes ;
- tex.vrbcatcodes = \number\vrbcatcodes ;
- tex.prtcatcodes = \number\prtcatcodes ;
- tex.xmlcatcodes = \number\xmlcatcodesn ;
- tex.xmlcatcodesn = \number\xmlcatcodesn ; % normal
- tex.xmlcatcodese = \number\xmlcatcodese ; % entitle
- tex.xmlcatcodesr = \number\xmlcatcodesr ; % reduce
- tex.typcatcodesa = \number\typcatcodesa ; % { }
- tex.typcatcodesb = \number\typcatcodesb ; % < >
-\stopruntimectxluacode
-
-\protect \endinput
diff --git a/tex/context/base/syst-cat.tex b/tex/context/base/syst-cat.tex
deleted file mode 100644
index c7fe7142f..000000000
--- a/tex/context/base/syst-cat.tex
+++ /dev/null
@@ -1,517 +0,0 @@
-%D \module
-%D [ file=syst-cat,
-%D version=2006.09.18,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Catcode Handling,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 A long standing wish has been the availability of catcode
-%D arrays. Because traditional \TEX\ does ot provide this we
-%D implement a fake method in the Mark II file.
-
-\ifx\zerocount\undefined \chardef \zerocount= 0 \fi
-\ifx\plusone \undefined \chardef \plusone = 1 \fi
-\ifx\minusone \undefined \newcount\minusone \minusone =-1 \fi
-
-\newif \ifrecatcodeuppercharacters % only used in good old tex
-
-% \newcount\cctdefcounter \cctdefcounter\plusone % 0 = signal
-\newcount\cctdefcounter \cctdefcounter\zerocount % 0 = signal, so advance before allocate
-
-\newcount\cctcountera
-\newcount\cctcounterb
-\newcount\cctcounterc
-
-\loadmarkfile{syst-cat}
-
-%D The next command can be defined in a cleaner way in the
-%D Mk IV file but we want to have a fast one with a minimal
-%D chance for interference.
-
-\chardef\activehackcode=`\~
-
-%D Once a catcode is assigned, the next assignments will happen faster.
-
-% (expandable) let
-
-\def\letcatcodecommand {\afterassignment\letcatcodecommanda\cctcountera}
-\def\letcatcodecommanda{\afterassignment\letcatcodecommandb\cctcounterb}
-
-\def\letcatcodecommandb % each time
- {\ifcsname CCL:\number\cctcountera:\number\cctcounterb\endcsname
- \csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
- \else
- \expandafter\letcatcodecommandc
- \fi}
-
-\def\letcatcodecommandc % only first time
- {\expandafter\gdef\csname CCL:\number\cctcountera:\number\cctcounterb\expandafter\endcsname\expandafter
- {\expandafter\let\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname}%
- \reinstatecatcodecommanda
- \csname CCL:\number\cctcountera:\number\cctcounterb\endcsname}
-
-% expandable def
-
-\def\defcatcodecommand {\afterassignment\defcatcodecommanda\cctcountera}
-\def\defcatcodecommanda{\afterassignment\defcatcodecommandb\cctcounterb}
-
-\def\defcatcodecommandb % each time
- {\ifcsname CCD:\number\cctcountera:\number\cctcounterb\endcsname
- \csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
- \else
- \expandafter\defcatcodecommandc
- \fi}
-
-\def\defcatcodecommandc % only first time
- {\expandafter\gdef\csname CCD:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
- \expandafter##\expandafter1\expandafter
- {\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}%
- \reinstatecatcodecommanda
- \csname CCD:\number\cctcountera:\number\cctcounterb\endcsname}
-
-% un expandable def (e.g. used for discretionaries)
-
-\def\uedcatcodecommand {\afterassignment\uedcatcodecommanda\cctcountera}
-\def\uedcatcodecommanda{\afterassignment\uedcatcodecommandb\cctcounterb}
-
-\def\uedcatcodecommandb % each time
- {\ifcsname CCU:\number\cctcountera:\number\cctcounterb\endcsname
- \csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
- \else
- \expandafter\uedcatcodecommandc
- \fi}
-
-\def\uedcatcodecommandc % only first time
- {\expandafter\gdef\csname CCU:\number\cctcountera:\number\cctcounterb\expandafter\endcsname
- \expandafter##\expandafter1\expandafter
- {\expandafter\unexpanded\expandafter\def\csname CCC:\number\cctcountera:\number\cctcounterb\endcsname{##1}}%
- \reinstatecatcodecommanda
- \csname CCU:\number\cctcountera:\number\cctcounterb\endcsname}
-
-\def\reinstatecatcodecommand{\afterassignment\reinstatecatcodecommanda\cctcounterb}
-
-\def\reinstatecatcodecommanda % can be used when a direct definition has been done
- {\bgroup % and the selector has been lost
- \uccode\activehackcode\cctcounterb
- \catcode\uccode\activehackcode13
- \uppercase{\xdef~{\noexpand\catcodecommand{\number\cctcounterb}}}%
- \egroup}
-
-\chardef\defaultcatcodetable\zerocount
-
-\def\catcodecommand#1%
- {\csname CCC:\number
- \ifcsname CCC:\number\currentcatcodetable:\number#1\endcsname
- \currentcatcodetable \else \defaultcatcodetable
- \fi
- :\number#1\endcsname}
-
-%D Here we define some catcode regimes:
-
-\ifx\nilcatcodes \undefined \newcatcodetable \nilcatcodes \fi
-\ifx\texcatcodes \undefined \newcatcodetable \texcatcodes \fi
-\ifx\ctxcatcodes \undefined \newcatcodetable \ctxcatcodes \fi
-\ifx\notcatcodes \undefined \newcatcodetable \notcatcodes \fi
-\ifx\vrbcatcodes \undefined \newcatcodetable \vrbcatcodes \fi
-\ifx\prtcatcodes \undefined \newcatcodetable \prtcatcodes \fi
-\ifx\mthcatcodes \undefined \newcatcodetable \mthcatcodes \fi % math, not used, too tricky
-\ifx\xmlcatcodesn\undefined \newcatcodetable \xmlcatcodesn \fi % normal
-\ifx\xmlcatcodese\undefined \newcatcodetable \xmlcatcodese \fi % entitle
-\ifx\xmlcatcodesr\undefined \newcatcodetable \xmlcatcodesr \fi % reduce
-\ifx\typcatcodesa\undefined \newcatcodetable \typcatcodesa \fi % { }
-\ifx\typcatcodesb\undefined \newcatcodetable \typcatcodesb \fi % < >
-
-% was redefined in core-job anyway: \catcode`\^^L = 13 % ascii form-feed
-
-\startcatcodetable \nilcatcodes
- \catcode`\^^I = 10 % ascii tab is a blank space
- \catcode`\^^M = 5 % ascii return is end-line
- \catcode`\^^L = 5 % ascii form-feed
- \catcode`\ = 10 % ascii space is blank space
- \catcode`\^^Z = 9 % ascii eof is ignored
-\stopcatcodetable
-
-\startcatcodetable \vrbcatcodes % probably less needed
- \catcode`\^^I = 12
- \catcode`\^^M = 12
- \catcode`\^^L = 12
- \catcode`\ = 12
- \catcode`\^^Z = 12
-\stopcatcodetable
-
-\startcatcodetable \typcatcodesa
- \catcode`\^^I = 12
- \catcode`\^^M = 12
- \catcode`\^^L = 12
- \catcode`\ = 12
- \catcode`\^^Z = 12
- \catcode`\{ = 1
- \catcode`\} = 2
-\stopcatcodetable
-
-\startcatcodetable \typcatcodesb
- \catcode`\^^I = 12
- \catcode`\^^M = 12
- \catcode`\^^L = 12
- \catcode`\ = 12
- \catcode`\^^Z = 12
- \catcode`\< = 1
- \catcode`\> = 2
-\stopcatcodetable
-
-\startcatcodetable \texcatcodes
- \catcode`\^^I = 10
- \catcode`\^^M = 5
- \catcode`\^^L = 5
- \catcode`\ = 10
- \catcode`\^^Z = 9
- \catcode`\\ = 0
- \catcode`\{ = 1
- \catcode`\} = 2
- \catcode`\$ = 3
- \catcode`\& = 4
- \catcode`\# = 6
- \catcode`\^ = 7
- \catcode`\_ = 8
- \catcode`\% = 14
-\stopcatcodetable
-
-\startcatcodetable \ctxcatcodes
- \catcode`\^^I = 10
- \catcode`\^^M = 5
-% \catcode`\^^J = 10 % new
- \catcode`\^^L = 5
- \catcode`\ = 10
- \catcode`\^^Z = 9
- \catcode`\\ = 0
- \catcode`\{ = 1
- \catcode`\} = 2
- \catcode`\$ = 3
- \catcode`\& = 4
- \catcode`\# = 6
- \catcode`\^ = 7
- \catcode`\_ = 8
- \catcode`\% = 14
- \catcode`\~ = 13
- \catcode`\| = 13
-\stopcatcodetable
-
-\startcatcodetable \notcatcodes
- \catcode`\^^I = 10 % ascii tab is a blank space
- \catcode`\^^M = 5 % ascii return is end-line
- \catcode`\^^L = 5 % ascii form-feed
- \catcode`\ = 10 % ascii space is blank space
- \catcode`\^^Z = 9 % ascii eof is ignored
- \catcode`\~ = 12
- \catcode`\# = 12 % probably too much, in principle
- \catcode`\$ = 12 % nilcatcodes would be ok too
- \catcode`\% = 12
- \catcode`\^ = 12
- \catcode`\& = 12
- \catcode`\_ = 12
- \catcode`\< = 12
- \catcode`\> = 12
- \catcode`\{ = 12
- \catcode`\} = 12
- \catcode`\" = 12
- \catcode`\' = 12
- \catcode`\/ = 12
- \catcode`\\ = 12
- \catcode`\| = 12
-\stopcatcodetable
-
-\startcatcodetable \mthcatcodes
- \catcode`\^^I = 10
- \catcode`\^^M = 5
- %\catcode`\^^J = 10 % new
- \catcode`\^^L = 5
- \catcode`\ = 10
- \catcode`\^^Z = 9
- \catcode`\\ = 0
- \catcode`\{ = 1
- \catcode`\} = 2
- \catcode`\$ = 3
- \catcode`\& = 4
- \catcode`\# = 6
- \catcode`\^ = 7
- \catcode`\_ = 8
- \catcode`\% = 14
- %\catcode`\~ = 13
- %\catcode`\| = 13
-\stopcatcodetable
-
-\startcatcodetable \prtcatcodes
- \catcode`\^^I = 10
- \catcode`\^^M = 5
- \catcode`\^^L = 5
- \catcode`\ = 10
- \catcode`\^^Z = 9
- \catcode`\\ = 0
- \catcode`\{ = 1
- \catcode`\} = 2
- \catcode`\$ = 3
- \catcode`\& = 4
- \catcode`\# = 6
- \catcode`\^ = 7
- \catcode`\_ = 8
- \catcode`\% = 14
- \catcode`\@ = 11
- \catcode`\! = 11
- \catcode`\? = 11
- \catcode`\~ = 13
- \catcode`\| = 13
-\stopcatcodetable
-
-\startcatcodetable \xmlcatcodesn
- \catcode`\^^I = 10 % ascii tab is a blank space
- \catcode`\^^M = 5 % ascii return is end-line
- \catcode`\^^L = 5 % ascii form-feed
- \catcode`\ = 10 % ascii space is blank space
- \catcode`\^^Z = 9 % ascii eof is ignored
- \catcode`\& = 13 % entity
- \catcode`\< = 13 % element
- \catcode`\> = 12
- \catcode`\" = 12 % probably not needed any more
- \catcode`\/ = 12 % probably not needed any more
- \catcode`\' = 12 % probably not needed any more
- \catcode`\~ = 12 % probably not needed any more
- \catcode`\# = 12 % probably not needed any more
- \catcode`\\ = 12 % probably not needed any more
-\stopcatcodetable
-
-\startcatcodetable \xmlcatcodese
- \catcode`\^^I = 10 % ascii tab is a blank space
- \catcode`\^^M = 5 % ascii return is end-line
- \catcode`\^^L = 5 % ascii form-feed
- \catcode`\ = 10 % ascii space is blank space
- \catcode`\^^Z = 9 % ascii eof is ignored
- \catcode`\& = 13 % entity
- \catcode`\< = 13 % element
- \catcode`\> = 12
- \catcode`\# = 13
- \catcode`\$ = 13
- \catcode`\% = 13
- \catcode`\\ = 13
- \catcode`\^ = 13
- \catcode`\_ = 13
- \catcode`\{ = 13
- \catcode`\} = 13
- \catcode`\| = 13
- \catcode`\~ = 13
-\stopcatcodetable
-
-\startcatcodetable \xmlcatcodesr
- \catcode`\^^I = 10 % ascii tab is a blank space
- \catcode`\^^M = 5 % ascii return is end-line
- \catcode`\^^L = 5 % ascii form-feed
- \catcode`\ = 10 % ascii space is blank space
- \catcode`\^^Z = 9 % ascii eof is ignored
- \catcode`\& = 13 % entity
- \catcode`\< = 13 % element
- \catcode`\> = 12
- \catcode`\# = 13
- \catcode`\$ = 13
- \catcode`\% = 13
- \catcode`\\ = 13
- \catcode`\^ = 13
- \catcode`\_ = 13
- \catcode`\{ = 13
- \catcode`\} = 13
- \catcode`\| = 13
- \catcode`\~ = 13
-\stopcatcodetable
-
-\letcatcodecommand \ctxcatcodes `\| \relax
-\letcatcodecommand \ctxcatcodes `\~ \relax
-
-%letcatcodecommand \prtcatcodes `\| \relax % falls back on ctx
-%letcatcodecommand \prtcatcodes `\~ \relax % falls back on ctx
-
-\letcatcodecommand \xmlcatcodesn `\& \relax
-\letcatcodecommand \xmlcatcodesn `\< \relax
-
-\letcatcodecommand \xmlcatcodese `\& \relax
-\letcatcodecommand \xmlcatcodese `\< \relax
-
-\letcatcodecommand \xmlcatcodesr `\& \relax
-\letcatcodecommand \xmlcatcodesr `\< \relax
-
-\letcatcodecommand \xmlcatcodese `\# \relax
-\letcatcodecommand \xmlcatcodese `\$ \relax
-\letcatcodecommand \xmlcatcodese `\% \relax
-\letcatcodecommand \xmlcatcodese `\\ \relax
-\letcatcodecommand \xmlcatcodese `\^ \relax
-\letcatcodecommand \xmlcatcodese `\_ \relax
-\letcatcodecommand \xmlcatcodese `\{ \relax
-\letcatcodecommand \xmlcatcodese `\} \relax
-\letcatcodecommand \xmlcatcodese `\| \relax
-\letcatcodecommand \xmlcatcodese `\~ \relax
-
-\letcatcodecommand \xmlcatcodesr `\# \relax
-\letcatcodecommand \xmlcatcodesr `\$ \relax
-\letcatcodecommand \xmlcatcodesr `\% \relax
-\letcatcodecommand \xmlcatcodesr `\\ \relax
-\letcatcodecommand \xmlcatcodesr `\^ \relax
-\letcatcodecommand \xmlcatcodesr `\_ \relax
-\letcatcodecommand \xmlcatcodesr `\{ \relax
-\letcatcodecommand \xmlcatcodesr `\} \relax
-\letcatcodecommand \xmlcatcodesr `\| \relax
-\letcatcodecommand \xmlcatcodesr `\~ \relax
-
- \catcodetable \ctxcatcodes
-\let\defaultcatcodetable\ctxcatcodes
-\let\xmlcatcodes \xmlcatcodesn
-
-%D \macros
-%D {restorecatcodes,
-%D beginrestorecatcodes,endrestorecatcodes}
-%D
-%D We're not finished dealing \CATCODES\ yet. In \CONTEXT\ we
-%D use only one auxiliary file, which deals with tables of
-%D contents, registers, two pass tracking, references etc. This
-%D file, as well as files concerning graphics, is processed when
-%D needed, which can be in the mid of typesetting verbatim.
-%D However, when reading in data in verbatim mode, we should
-%D temporary restore the normal \CATCODES, and that's exactly
-%D what the next macros do. Saving the catcodes can be
-%D disabled by saying \type{\localcatcodestrue}.
-
-\let\savedcatcodetable\relax
-
-\newcount\catcoderestorelevel
-
-\def\pushcatcodetable
- {\advance\catcoderestorelevel\plusone
- \tracepushcatcodetable
- \expandafter\mathchardef\csname scct:\number\catcoderestorelevel\endcsname\currentcatcodetable}
-
-% \def\popcatcodetable
-% {\expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname
-% \tracepopcatcodetable
-% \advance\catcoderestorelevel\minusone}
-
-\def\popcatcodetable
- {\ifcase\catcoderestorelevel
- \immediate\write16{}%
- \immediate\write16{Fatal error: catcode push/pop mismatch. Fix this!}\wait\end
- \immediate\write16{}%
- \else
- \expandafter\catcodetable\csname scct:\number\catcoderestorelevel\endcsname
- \tracepopcatcodetable
- \advance\catcoderestorelevel\minusone
- \fi}
-
-\def\restorecatcodes % takes previous level
- {\ifnum\catcoderestorelevel>\plusone
- \expandafter\catcodetable\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname
- \fi}
-
-\newtoks\everycatcodetable
-
-\def\setcatcodetable#1%
- {\catcodetable#1%
- \the\everycatcodetable
- \tracesetcatcodetable}
-
-\def\dotracecatcodetable#1{\immediate\write16{[#1]}}
-
-\def\tracecatcodetables
- {\def\tracesetcatcodetable {\dotracecatcodetable{set \catcodetablename\space at \number\catcoderestorelevel}}%
- \def\tracepushcatcodetable{\dotracecatcodetable{push \catcodetablename\space from \catcodetableprev\space at \number\catcoderestorelevel}}%
- \def\tracepopcatcodetable {\dotracecatcodetable{pop \catcodetablename\space to \catcodetableprev\space at \number\catcoderestorelevel}}}
-
-\def\catcodetableprev
- {\ifnum\numexpr\catcoderestorelevel-1\relax>\zerocount
- \csname @@ccn:\number\csname scct:\number\numexpr\catcoderestorelevel-1\relax\endcsname\endcsname
- \else
- -%
- \fi}
-
-\def\catcodetablename
- {\ifnum\currentcatcodetable>\zerocount
- \csname @@ccn:\number\currentcatcodetable\endcsname
- \else
- -%
- \fi}
-
-\ifx\empty\undefined \def\empty{} \fi
-
-\let\tracesetcatcodetable \empty
-\let\tracepushcatcodetable\empty
-\let\tracepopcatcodetable \empty
-
-% \def\beginrestorecatcodes{\pushcatcodetable\catcodetable\ctxcatcodes}
-% \def\endrestorecatcodes {\popcatcodetable}
-
-\def\beginrestorecatcodes{\pushcatcodetable}
-\def\endrestorecatcodes {\popcatcodetable}
-
-\def\unprotect {\pushcatcodetable\setcatcodetable\prtcatcodes}
-\def\protect {\popcatcodetable}
-
-%D \macros
-%D {installactivecharacter}
-
-\def\installactivecharacter#1 %
- {\edef\temp{\detokenize{#1}}%
- \cctcounterc\expandafter`\temp\relax % relax needed
- \expandafter\startextendcatcodetable
- \expandafter\ctxcatcodes\expandafter\catcode\the\cctcounterc=13
- \stopextendcatcodetable
- \letcatcodecommand \ctxcatcodes \cctcounterc \temp \relax
- \ifnum\currentcatcodetable=\ctxcatcodes \setcatcodetable\ctxcatcodes \fi}
-
-%D \macros
-%D {defineactivecharacter}
-%D
-%D Use this one with care, esp in combination with catcode
-%D vectors. There are better ways now.
-
-\chardef\activehackcode=`~
-
-% \def\defineactivecharacter #1 #2%
-% {\cctcounterc\uccode\activehackcode
-% \uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1}\empty`#1%
-% \catcode\uccode\activehackcode13
-% \uppercase{\def\next{~}}%
-% \uccode\activehackcode\cctcounterc
-% \expandafter\expandafter\expandafter\def\expandafter\next\expandafter
-% {\expandafter\dohandleactivecharacter\next{#2}}}
-%
-% \defineactivecharacter "0EFFF {oeps} \utfchar{0xEFFF}
-
-\def\defineactivecharacter #1#2 #3%
- {\cctcounterc\uccode\activehackcode
- \if#1"\uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1#2}\empty #1#2\else
- \uccode\activehackcode\expandafter\doifnumberelse\expandafter{\string#1#2}\empty`#1#2\fi
- \catcode\uccode\activehackcode13
- \uppercase{\def\next{~}}%
- \uccode\activehackcode\cctcounterc
- \expandafter\expandafter\expandafter\def\expandafter\next\expandafter
- {\expandafter\dohandleactivecharacter\next{#3}}}
-
-\chardef\activecharactermode\plusone % overloading still backward compatible
-
-\def\dodohandleactivecharacter#1#2{#2}
-\def\donthandleactivecharacter#1#2{\noexpand#1}
-
-\def\dohandleactivecharacter
- {\ifcase\activecharactermode
- \expandafter\donthandleactivecharacter
- \else
- \expandafter\dodohandleactivecharacter
- \fi}
-
-\def\makecharacteractive #1 {\catcode`#1\active}
-
-%D Handy for debugging:
-
-% \tracecatcodetables
-
-\endinput
diff --git a/tex/context/base/syst-con.lua b/tex/context/base/syst-con.lua
index 5e916575f..b2f6c42af 100644
--- a/tex/context/base/syst-con.lua
+++ b/tex/context/base/syst-con.lua
@@ -13,23 +13,13 @@ converters = converters or { }
the top of <l n='luatex'/>'s char range but outside the unicode range.</p>
--ldx]]--
-do
- local char, texsprint, format = unicode.utf8.char, tex.sprint, string.format
+local char, texsprint, format = unicode.utf8.char, tex.sprint, string.format
- function converters.hexstringtonumber(n) texsprint(tonumber(n,16)) end
- function converters.octstringtonumber(n) texsprint(tonumber(n, 8)) end
- function converters.rawcharacter (n) texsprint(char(0x110000+n)) end
-
- function converters.lchexnumber (n) texsprint(format("%x" ,n)) end
- function converters.uchexnumber (n) texsprint(format("%X" ,n)) end
- function converters.lchexnumbers (n) texsprint(format("%02x",n)) end
- function converters.uchexnumbers (n) texsprint(format("%02X",n)) end
- function converters.octnumber (n) texsprint(format("%03o",n)) end
-
- function converters.lchexnumber (n) texsprint(("%x" ):format(n)) end
- function converters.uchexnumber (n) texsprint(("%X" ):format(n)) end
- function converters.lchexnumbers (n) texsprint(("%02x"):format(n)) end
- function converters.uchexnumbers (n) texsprint(("%02X"):format(n)) end
- function converters.octnumber (n) texsprint(("%03o"):format(n)) end
-
-end
+function converters.hexstringtonumber(n) texsprint(tonumber(n,16)) end
+function converters.octstringtonumber(n) texsprint(tonumber(n, 8)) end
+function converters.rawcharacter (n) texsprint(char(0x110000+n)) end
+function converters.lchexnumber (n) texsprint(format("%x" ,n)) end
+function converters.uchexnumber (n) texsprint(format("%X" ,n)) end
+function converters.lchexnumbers (n) texsprint(format("%02x",n)) end
+function converters.uchexnumbers (n) texsprint(format("%02X",n)) end
+function converters.octnumber (n) texsprint(format("%03o",n)) end
diff --git a/tex/context/base/syst-con.mkii b/tex/context/base/syst-con.mkii
index d5d044f31..877aad32a 100644
--- a/tex/context/base/syst-con.mkii
+++ b/tex/context/base/syst-con.mkii
@@ -11,8 +11,43 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\writestatus{loading}{ConTeXt System Macros / Conversions}
+
\unprotect
+%D When the number of conversions grew, it did no longer make
+%D sense to spread them over multiple files. So, instead of
+%D defining these in \type {font-ini}, we now have a dedicated
+%D module.
+
+\catcode127=12 % other, just to be sure
+
+%D \macros
+%D {lchexnumber,uchexnumber,lchexnumbers,uchexnumbers}
+%D
+%D In addition to the uppercase hex conversion, as needed in
+%D math families, we occasionally need a lowercase one, for
+%D instance when we want to compose gbsong fontnames.
+%D
+%D The ugly indirectness is needed to get rid of \TEX\
+%D induced spaces and \type {\relax}'s.
+%D
+%D \starttyping
+%D [\uchexnumber{0}]
+%D [\uchexnumber\scratchcounter]
+%D [\uchexnumber\zerocount]
+%D [\uchexnumber{\number0}]
+%D [\uchexnumber{\number\scratchcounter}]
+%D [\uchexnumber{\number\zerocount}]
+%D [\uchexnumber{\the\scratchcounter}]
+%D [\uchexnumber{\the\zerocount}]
+%D [\expandafter\uchexnumber\expandafter{\number0}]
+%D [\expandafter\uchexnumber\expandafter{\number\scratchcounter}]
+%D [\expandafter\uchexnumber\expandafter{\number\zerocount}]
+%D [\expandafter\uchexnumber\expandafter{\the\scratchcounter}]
+%D [\expandafter\uchexnumber\expandafter{\the\zerocount}]
+%D \stoptyping
+%D
%D These macros may look slow but are actually rather fast due to
%D the fact that \TEX\ handles conditional pretty fast. We need
%D a two step approach in order to stay relax clean in fully
@@ -64,6 +99,18 @@
E0\or E1\or E2\or E3\or E4\or E5\or E6\or E7\or E8\or E9\or EA\or EB\or EC\or ED\or EE\or EF\or
F0\or F1\or F2\or F3\or F4\or F5\or F6\or F7\or F8\or F9\or FA\or FB\or FC\or FD\or FE\or FF\fi}
+\def\lchexnumber #1{\@EA\dolchexnumber \number#1\relax}
+\def\uchexnumber #1{\@EA\douchexnumber \number#1\relax}
+\def\lchexnumbers#1{\@EA\dolchexnumbers\number#1\relax}
+\def\uchexnumbers#1{\@EA\douchexnumbers\number#1\relax}
+
+\let\hexnumber\uchexnumber
+
+%D \macros
+%D {octnumber}
+%D
+%D For unicode remapping purposes, we need octal numbers.
+
\def\dooctnumber#1\relax
{\ifcase#1
000\or 001\or 002\or 003\or 004\or 005\or 006\or 007\or
@@ -99,13 +146,55 @@
360\or 361\or 362\or 363\or 364\or 365\or 366\or 367\or
370\or 371\or 372\or 373\or 374\or 375\or 376\or 377\fi}
-\def\lchexnumber #1{\@EA\dolchexnumber \number#1\relax}
-\def\uchexnumber #1{\@EA\douchexnumber \number#1\relax}
-\def\lchexnumbers#1{\@EA\dolchexnumbers\number#1\relax}
-\def\uchexnumbers#1{\@EA\douchexnumbers\number#1\relax}
-\def\octnumber #1{\@EA\dooctnumber \number#1\relax}
-
-%D No beauty but ok:
+\def\octnumber#1{\@EA\dooctnumber\number#1\relax}
+
+%D \macros
+%D {twodigits, threedigits}
+%D
+%D These macros provides two or three digits always:
+
+\def\twodigits #1{\ifnum #1<10 0\fi\number#1}
+\def\threedigits#1{\ifnum#1<100 \ifnum#1<10 0\fi0\fi\number#1}
+
+%D \macros{modulonumber}
+%D
+%D In the conversion macros described in \type {core-con} we
+%D need a wrap||around method. The following solution is
+%D provided by Taco.
+%D
+%D The \type {modulonumber} macro expands to the mathematical
+%D modulo of a positive integer. It is crucial for it's
+%D application that this macro is fully exandable.
+%D
+%D The expression inside the \type {\numexpr} itself is
+%D somewhat bizarre because \ETEX\ uses a rounding
+%D division instead of truncation. If \ETEX's division
+%D would have behaved like \TEX's normal\type{\divide}, then
+%D the expression could have been somewhat simpler, like
+%D \type {#2-(#2/#1)*#1}. This works just as well, but a bit
+%D more complex.
+
+\def\modulonumber#1#2%
+ {\the\numexpr#2-((((#2+(#1/2))/#1)-1)*#1)\relax}
+
+%D \macros{modulatednumber}
+%D
+%D Modulo numbers run from zero to one less than the limit,
+%D but for conversion sets, we need a value between 1 and the
+%D limit. The \type{\modulatednumber} arranges that. This
+%D macro also needs to be fully expandable, resulting in
+%D two \type{\numexpr}s.
+
+\def\modulatednumber#1#2%
+ {\ifnum\the\numexpr\modulonumber{#1}{#2}\relax=0 #1%
+ \else \the\numexpr\modulonumber{#1}{#2}\relax \fi}
+
+%D \macros
+%D {hexstringtonumber}
+%D
+%D This macro converts a two character hexadecimal number into
+%D a decimal number, thereby taking care of lowercase characters
+%D as well.
\dostepwiserecurse{0}{9}{1}{\setevalue{@@uc@@\recurselevel}{\recurselevel}}
@@ -122,10 +211,16 @@
\def\dohexstringtonumber#1#2% FF
{"\csname @@uc@@#1\endcsname\csname @@uc@@#2\endcsname}
+%D \macros
+%D {rawcharacter}
+%D
%D The next conversion macro produces raw characters. We have to
%D construct the macro in a special way to avoid problems with
%D characters with special meanings. So, we revert to the
%D lowercase conversion trick to bypass \TEX's input parser.
+%D
+%D This macro can be used to produce proper 8 bit characters
+%D that we sometimes need in backends and round||trips.
\bgroup
diff --git a/tex/context/base/syst-con.mkiv b/tex/context/base/syst-con.mkiv
index 2f84395f0..f7d4150a6 100644
--- a/tex/context/base/syst-con.mkiv
+++ b/tex/context/base/syst-con.mkiv
@@ -1,6 +1,6 @@
%D \module
%D [ file=syst-con,
-%D version=2006.09.16,
+%D version=2006.09.16, % real old stuff ... 2000.12.10
%D title=\CONTEXT\ System Macros,
%D subtitle=Conversions,
%D author=Hans Hagen,
@@ -15,13 +15,131 @@
\unprotect
-\def\lchexnumber #1{\ctxlua{converters.lchexnumber(\number#1)}}
-\def\uchexnumber #1{\ctxlua{converters.uchexnumber(\number#1)}}
-\def\lchexnumbers #1{\ctxlua{converters.lchexnumbers(\number#1)}}
-\def\uchexnumbers #1{\ctxlua{converters.uchexnumbers(\number#1)}}
-\def\octnumber #1{\ctxlua{converters.octnumber(\number#1)}}
+%D When the number of conversions grew, it did no longer make
+%D sense to spread them over multiple files. So, instead of
+%D defining these in \type {font-ini}, we now have a dedicated
+%D module.
+
+%D \macros
+%D {lchexnumber,uchexnumber,lchexnumbers,uchexnumbers}
+%D
+%D In addition to the uppercase hex conversion, as needed in
+%D math families, we occasionally need a lowercase one, for
+%D instance when we want to compose gbsong fontnames.
+%D
+%D The ugly indirectness is needed to get rid of \TEX\
+%D induced spaces and \type {\relax}'s.
+%D
+%D \starttyping
+%D [\uchexnumber{0}]
+%D [\uchexnumber\scratchcounter]
+%D [\uchexnumber\zerocount]
+%D [\uchexnumber{\number0}]
+%D [\uchexnumber{\number\scratchcounter}]
+%D [\uchexnumber{\number\zerocount}]
+%D [\uchexnumber{\the\scratchcounter}]
+%D [\uchexnumber{\the\zerocount}]
+%D [\expandafter\uchexnumber\expandafter{\number0}]
+%D [\expandafter\uchexnumber\expandafter{\number\scratchcounter}]
+%D [\expandafter\uchexnumber\expandafter{\number\zerocount}]
+%D [\expandafter\uchexnumber\expandafter{\the\scratchcounter}]
+%D [\expandafter\uchexnumber\expandafter{\the\zerocount}]
+%D \stoptyping
+
+\def\lchexnumber #1{\ctxlua{converters.lchexnumber(\number#1)}}
+\def\uchexnumber #1{\ctxlua{converters.uchexnumber(\number#1)}}
+\def\lchexnumbers#1{\ctxlua{converters.lchexnumbers(\number#1)}}
+\def\uchexnumbers#1{\ctxlua{converters.uchexnumbers(\number#1)}}
+
+\let\hexnumber\uchexnumber
+
+%D \macros
+%D {octnumber}
+%D
+%D For unicode remapping purposes, we need octal numbers.
+
+\def\octnumber#1{\ctxlua{converters.octnumber(\number#1)}}
+
+%D \macros
+%D {hexstringtonumber,octstringtonumber}
+%D
+%D This macro converts a two character hexadecimal number into
+%D a decimal number, thereby taking care of lowercase characters
+%D as well.
+
\def\hexstringtonumber#1{\ctxlua{converters.hexstringtonumber("#1")}}
\def\octstringtonumber#1{\ctxlua{converters.octstringtonumber("#1")}}
-\def\rawcharacter #1{\ctxlua{converters.rawcharacter(\number#1)}}
+
+%D \macros
+%D {rawcharacter}
+%D
+%D This macro can be used to produce proper 8 bit characters
+%D that we sometimes need in backends and round||trips.
+
+\def\rawcharacter#1{\ctxlua{converters.rawcharacter(\number#1)}}
+
+%D \macros
+%D {twodigits, threedigits}
+%D
+%D These macros provides two or three digits always:
+
+\def\twodigits #1{\ifnum #1<10 0\fi\number#1}
+\def\threedigits#1{\ifnum#1<100 \ifnum#1<10 0\fi0\fi\number#1}
+
+%D \macros{modulonumber}
+%D
+%D In the conversion macros described in \type {core-con} we
+%D need a wrap||around method. The following solution is
+%D provided by Taco.
+%D
+%D The \type {modulonumber} macro expands to the mathematical
+%D modulo of a positive integer. It is crucial for it's
+%D application that this macro is fully exandable.
+%D
+%D The expression inside the \type {\numexpr} itself is
+%D somewhat bizarre because \ETEX\ uses a rounding
+%D division instead of truncation. If \ETEX's division
+%D would have behaved like \TEX's normal\type{\divide}, then
+%D the expression could have been somewhat simpler, like
+%D \type {#2-(#2/#1)*#1}. This works just as well, but a bit
+%D more complex.
+
+\def\modulonumber#1#2%
+ {\the\numexpr#2-((((#2+(#1/2))/#1)-1)*#1)\relax}
+
+%D \macros{modulatednumber}
+%D
+%D Modulo numbers run from zero to one less than the limit,
+%D but for conversion sets, we need a value between 1 and the
+%D limit. The \type{\modulatednumber} arranges that. This
+%D macro also needs to be fully expandable, resulting in
+%D two \type{\numexpr}s.
+
+\def\modulatednumber#1#2%
+ {\ifnum\the\numexpr\modulonumber{#1}{#2}\relax=0 #1%
+ \else \the\numexpr\modulonumber{#1}{#2}\relax \fi}
+
+%D \macros
+%D {realnumber} % used?
+
+\def\realnumber#1{\withoutpt\the\dimexpr#1\s!pt\relax} % brrr
+
+%D \macros
+%D {setcalculatedsin,setcalculatedcos,setcalculatedtan}
+%D
+%D This saves some 2K in the format. At some point we will redo the
+%D code that calls this. Beware: in \MKII\ this is a separate module.
+
+% \let\calculatesin\gobbleoneargument
+% \let\calculatecos\gobbleoneargument
+% \let\calculatetan\gobbleoneargument
+
+% \def\calculatedsin#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.sin(#1))}}
+% \def\calculatedcos#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.cos(#1))}}
+% \def\calculatedtan#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.tan(#1))}}
+
+\def\setcalculatedsin#1#2{\edef#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.sind(#2))}}}
+\def\setcalculatedcos#1#2{\edef#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.cosd(#2))}}}
+\def\setcalculatedtan#1#2{\edef#1{\ctxlua{tex.sprint(tex.ctxcatcodes,math.tand(#2))}}}
\protect \endinput
diff --git a/tex/context/base/syst-con.tex b/tex/context/base/syst-con.tex
deleted file mode 100644
index 653d68928..000000000
--- a/tex/context/base/syst-con.tex
+++ /dev/null
@@ -1,144 +0,0 @@
-%D \module
-%D [ file=syst-con,
-%D version=2000.12.10, % actually very old -)
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Conversions,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 System Macro's / Conversions}
-
-\unprotect
-
-%D When the number of conversions grew, it did no longer make
-%D sense to spread them over multiple files. So, instead of
-%D defining these in \type {font-ini}, we now have a dedicated
-%D module.
-
-\catcode127=12 % other, just to be sure
-
-%D \macros
-%D {lchexnumber,uchexnumber,lchexnumbers,uchexnumbers}
-%D
-%D In addition to the uppercase hex conversion, as needed in
-%D math families, we occasionally need a lowercase one, for
-%D instance when we want to compose gbsong fontnames.
-%D
-%D The ugly indirectness is needed to get rid of \TEX\
-%D induced spaces and \type {\relax}'s.
-%D
-%D \starttyping
-%D [\uchexnumber{0}]
-%D [\uchexnumber\scratchcounter]
-%D [\uchexnumber\zerocount]
-%D [\uchexnumber{\number0}]
-%D [\uchexnumber{\number\scratchcounter}]
-%D [\uchexnumber{\number\zerocount}]
-%D [\uchexnumber{\the\scratchcounter}]
-%D [\uchexnumber{\the\zerocount}]
-%D [\expandafter\uchexnumber\expandafter{\number0}]
-%D [\expandafter\uchexnumber\expandafter{\number\scratchcounter}]
-%D [\expandafter\uchexnumber\expandafter{\number\zerocount}]
-%D [\expandafter\uchexnumber\expandafter{\the\scratchcounter}]
-%D [\expandafter\uchexnumber\expandafter{\the\zerocount}]
-%D \stoptyping
-
-\let\lchexnumber \gobbleoneargument
-\let\uchexnumber \gobbleoneargument
-\let\lchexnumbers\gobbleoneargument
-\let\uchexnumbers\gobbleoneargument
-
-%D \macros
-%D {octnumber}
-%D
-%D For unicode remapping purposes, we need octal numbers.
-
-\let\octnumber\gobbleoneargument
-
-%D \macros
-%D {hexstringtonumber}
-%D
-%D This macro converts a two character hexadecimal number into
-%D a decimal number, thereby taking care of lowercase characters
-%D as well.
-
-\let\hexstringtonumber\gobbleoneargument
-
-%D \macros
-%D {rawcharacter}
-%D
-%D This macro can be used to produce proper 8 bit characters
-%D that we sometimes need in backends and round||trips.
-
-\let\rawcharacter\gobbleoneargument
-
-%D \macros
-%D {twodigits, threedigits}
-%D
-%D These macros provides two or three digits always:
-
-\def\twodigits #1{\ifnum #1<10 0\fi\number#1}
-\def\threedigits#1{\ifnum#1<100 \ifnum#1<10 0\fi0\fi\number#1}
-
-%D \macros{modulonumber}
-%D
-%D In the conversion macros described in \type {core-con} we
-%D need a wrap||around method. The following solution is
-%D provided by Taco.
-%D
-%D The \type {modulonumber} macro expands to the mathematical
-%D modulo of a positive integer. It is crucial for it's
-%D application that this macro is fully exandable.
-%D
-%D The expression inside the \type {\numexpr} itself is
-%D somewhat bizarre because \ETEX\ uses a rounding
-%D division instead of truncation. If \ETEX's division
-%D would have behaved like \TEX's normal\type{\divide}, then
-%D the expression could have been somewhat simpler, like
-%D \type {#2-(#2/#1)*#1}. This works just as well, but a bit
-%D more complex.
-
-\beginETEX
-
-\def\modulonumber#1#2%
- {\the\numexpr#2-((((#2+(#1/2))/#1)-1)*#1)\relax}
-
-\endETEX
-
-%D \macros{modulatednumber}
-%D
-%D Modulo numbers run from zero to one less than the limit,
-%D but for conversion sets, we need a value between 1 and the
-%D limit. The \type{\modulatednumber} arranges that. This
-%D macro also needs to be fully expandable, resulting in
-%D two \type{\numexpr}s.
-
-\beginETEX
-
-\def\modulatednumber#1#2%
- {\ifnum\the\numexpr\modulonumber{#1}{#2}\relax=0 #1%
- \else \the\numexpr\modulonumber{#1}{#2}\relax \fi}
-
-\endETEX
-
-%D When not running \ETEX\ you're left with the maximum:
-
-\beginTEX
-
-\def\modulatednumber#1#2%
- {\ifnum#2>#1 #1\else#2\fi}
-
-\endTEX
-
-%D Plugins
-
-\loadmarkfile{syst-con}
-
-\let\hexnumber\uchexnumber
-
-\protect \endinput
diff --git a/tex/context/base/syst-etx.tex b/tex/context/base/syst-etx.tex
deleted file mode 100644
index 6ccfa25e0..000000000
--- a/tex/context/base/syst-etx.tex
+++ /dev/null
@@ -1,298 +0,0 @@
-%D \module
-%D [ file=syst-etx,
-%D version=1999.03.17, % some time ...
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Efficient \PLAIN\ \TEX\ loading,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 prepares \CONTEXT\ for \ETEX. We don't use
-%D the definition files that come with this useful \TEX\
-%D extension, but implement our own alternatives.
-
-%D \CONTEXT\ was one of the first systems that had support for \ETEX\
-%D built in. In the process we found out that the extensions were not
-%D as bug free as the rest of \TEX. Especially the bugs in \type
-%D {lastnode}, flushing of token lists with an index in the extension
-%D range, and spurious box behaviour of boxes adressed in the extended
-%D box space made us a bit careful. It's hard to to track down such
-%D bugs, especially if one has a mind set of \TEX\ being bug free. If
-%D you encounter unexpected behaviour let me know. Currently the
-%D scantokens mechanism can handle only one||liners, but Taco will
-%D provide an alternative some day.
-%D
-%D \starttyping
-%D \bgroup
-%D \lccode`a=12\lowercase{\xdef\whatever{a}}\egroup
-%D \def\whatever{test \whatever test}
-%D \scantokens\expandafter{\whatever}
-%D \egroup
-%D \stoptyping
-
-\unprotect
-
-%D \ETEX\ has a not so handy way of telling you the version number,
-%D i.e. the revision number has a period in it:
-
-\long\def\gobbleoneargument#1{}
-
-\beginETEX
- \mathchardef\etexversion=\numexpr\eTeXversion*100+\expandafter\gobbleoneargument\eTeXrevision\relax
-\endETEX
-
-\beginTEX
- \mathchardef\etexversion=0
-\endTEX
-
-%D Constants to be used with \type {\grouptype}.
-
-\chardef\@@bottomlevelgroup = 0
-\chardef\@@simplegroup = 1
-\chardef\@@hboxgroup = 2
-\chardef\@@adjustedhboxgroup = 3
-\chardef\@@vboxgroup = 4
-\chardef\@@vtopgroup = 5
-\chardef\@@aligngroup = 6
-\chardef\@@noaligngroup = 7
-\chardef\@@outputgroup = 8
-\chardef\@@mathgroup = 9
-\chardef\@@discretionarygroup = 10
-\chardef\@@insertgroup = 11
-\chardef\@@vcentergroup = 12
-\chardef\@@mathchoicegroup = 13
-\chardef\@@semisimplegroup = 14
-\chardef\@@mathshiftgroup = 15
-\chardef\@@mathleftgroup = 16
-
-\chardef\@@vadjustgroup = \@@insertgroup
-
-%D Constants to be used with \type {\interactionmode}.
-
-\chardef\@@batchmode = 0
-\chardef\@@nonstopmode = 1
-\chardef\@@scrollmode = 2
-\chardef\@@errorstopmode = 3
-
-%D Constants to be used with \type {\lastnodetype}.
-
-\chardef\@@charnode = 0
-\chardef\@@hlistnode = 1
-\chardef\@@vlistnode = 2
-\chardef\@@rulenode = 3
-\chardef\@@insertnode = 4
-\chardef\@@marknode = 5
-\chardef\@@adjustnode = 6
-\chardef\@@ligaturenode = 7
-\chardef\@@discretionarynode = 8
-\chardef\@@whatsitnode = 9
-\chardef\@@mathnode = 10
-\chardef\@@gluenode = 11
-\chardef\@@kernnode = 12
-\chardef\@@penaltynode = 13
-\chardef\@@unsetnode = 14
-\chardef\@@mathsnode = 15
-
-%D Constants to be used with \type {\iftype}.
-
-\chardef\@@charif = 1
-\chardef\@@catif = 2
-\chardef\@@numif = 3
-\chardef\@@dimif = 4
-\chardef\@@oddif = 5
-\chardef\@@vmodeif = 6
-\chardef\@@hmodeif = 7
-\chardef\@@mmodeif = 8
-\chardef\@@innerif = 9
-\chardef\@@voidif = 10
-\chardef\@@hboxif = 11
-\chardef\@@vboxif = 12
-\chardef\@@xif = 13
-\chardef\@@eofif = 14
-\chardef\@@trueif = 15
-\chardef\@@falseif = 16
-\chardef\@@caseif = 17
-\chardef\@@definedif = 18
-\chardef\@@csnameif = 19
-\chardef\@@fontcharif = 20
-
-%D Just in case we are not using \ETEX, we define some out of
-%D range constants.
-
-\beginTEX
-
-\chardef\grouptype = 255
-\chardef\interactionmode = 255
-\chardef\nodetype = 255
-\chardef\iftype = 255
-
-\endTEX
-
-%D Of course we want even bigger log files, so we copied this
-%D from the \ETEX\ source files.
-
-\beginETEX \tracing...
-
-\def\tracingall
- {\tracingonline \@ne
- \tracingcommands \thr@@
- \tracingstats \tw@
- \tracingpages \@ne
- \tracingoutput \@ne
- \tracinglostchars \tw@
- \tracingmacros \tw@
- \tracingparagraphs\@ne
- \tracingrestores \@ne
- \showboxbreadth \maxdimen
- \showboxdepth \maxdimen
- \tracinggroups \@ne
- \tracingifs \@ne
- \tracingscantokens\@ne
- \tracingnesting \@ne
- \tracingassigns \tw@
- \errorstopmode}
-
-\def\loggingall
- {\tracingall
- \tracingonline \z@}
-
-\def\tracingnone
- {\tracingassigns \z@
- \tracingnesting \z@
- \tracingscantokens\z@
- \tracingifs \z@
- \tracinggroups \z@
- \showboxdepth \thr@@
- \showboxbreadth 5
- \tracingrestores \z@
- \tracingparagraphs\z@
- \tracingmacros \z@
- \tracinglostchars \@ne
- \tracingoutput \z@
- \tracingpages \z@
- \tracingstats \z@
- \tracingcommands \z@
- \tracingonline \z@ }
-
-\endETEX
-
-%D Just to be sure:
-
-\ifx\eTeX\undefined
-
- \def\eTeX{$\varepsilon$-\TeX}
-
-\fi
-
-%D In \ETEX\ we have lots of registers, so we redefine a few
-%D low level macros. We reserve some extra space for inserts
-%D and as soon as we near the end of the first register
-%D memory bank (often some 10 less than 255), we switch to the
-%D slower range \type {\@@medallocation}||\type {\@@maxallocation}.
-
-\beginETEX \new...
-
-%D First we redefine the plain \TEX\ register allocation macros.
-
-\def\newcount {\myalloc@0\count \countdef \@@maxallocation}
-\def\newdimen {\myalloc@1\dimen \dimendef \@@maxallocation}
-\def\newskip {\myalloc@2\skip \skipdef \@@maxallocation}
-\def\newmuskip {\myalloc@3\muskip \muskipdef \@@maxallocation}
-\def\newbox {\myalloc@4\box \mathchardef\@@maxallocation}
-\def\newtoks {\myalloc@5\toks \toksdef \@@maxallocation}
-\def\newread {\myalloc@6\read \chardef \@@minallocation}
-\def\newwrite {\myalloc@7\write \chardef \@@minallocation}
-\def\newmarks {\myalloc@8\marks \mathchardef\@@maxallocation}
-\def\newlanguage{\myalloc@9\language\chardef \@@minallocation}
-
-\def\topofboxstack{\number\count24 }
-
-%D Since in \CONTEXT\ we only have one math family left we
-%D redefine \type {\newfam}.
-
-\def\newfam#1{\chardef#1=15 }
-
-%D Therefore we should reset the related counter.
-
-\count18=1
-
-%D We use some constants in the tests.
-
-\mathchardef\@@minallocation = 16
-\mathchardef\@@medallocation = 256
-\mathchardef\@@maxallocation = 32767
-
-%D I cannot imagine that more than~8 extra insert classes
-%D are needed, but, for critical editions, we may need many
-%D more, so:
-
-\chardef\@@insallocation = 32
-
-%D However, there's a bug in \ETEX\ versions smaller than 2.2,
-%D so we need to play safe:
-
-\ifnum\etexversion<202 \chardef\@@insallocation=8 \fi
-
-%D My low level allocation macro now comes down to:
-
-\def\myalloc@#1#2#3#4#5%
- {\global\advance\count1#1by\@ne
- \ifnum\count1#1>\@@medallocation \else
- \ifnum\count1#1<\numexpr\@@medallocation-\@@insallocation\relax\else
- \global\count1#1=\numexpr\@@medallocation+\@ne\relax % \wait
- \fi
- \fi
- \ifnum\count1#1>#4%
- \global\count1#1=#4%
- \errmessage{No room for (\string#2) \string#5}%
- \fi
- \allocationnumber=\count1#1%
- \global#3#5=\allocationnumber
- \wlog{\string#5=\string#2\the\allocationnumber}}
-
-\def\newinsert#1%
- {\ifnum\insc@unt>\numexpr\@@medallocation-\@@insallocation\relax
- \global\advance\insc@unt by\m@ne
- \allocationnumber=\insc@unt
- \global\chardef#1=\allocationnumber
- \wlog{\string#1=\string\insert\the\allocationnumber}%
- \else
- \errmessage{No room for a new insert \string#1 (\number\insc@unt)}%
- \fi}
-
-\endETEX
-
-%D These macros can be checked by tests like:
-%D
-%D \starttyping
-%D \let\wlog\message \dorecurse{1000}{\newcount\dummy}
-%D \stoptyping
-
-%D A few bonus bindings.
-
-\ifx\normalprotected \undefined \let\normalprotected \protected \fi
-\ifx\normalunexpanded\undefined \let\normalunexpanded\unexpanded \fi
-\ifx\normalexpanded \undefined \let\normalexpanded \expanded \fi
-
-%D \macros
-%D {begcsname}
-%D
-%D Handy for \ETEX-only usage:
-
-\beginETEX \ifcsname
-
- \def\begcsname#1\endcsname{\ifcsname#1\endcsname\csname#1\endcsname\fi}
-
-\endETEX
-
-\beginTEX
-
- \def\begcsname#1\endcsname{\csname#1\endcsname}
-
-\endTEX
-
-\protect \endinput
diff --git a/tex/context/base/syst-ext.tex b/tex/context/base/syst-ext.tex
index 5d3afce3a..bd1c02050 100644
--- a/tex/context/base/syst-ext.tex
+++ b/tex/context/base/syst-ext.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context System Macro's / Extras}
+\writestatus{loading}{ConTeXt System Macros / Extras}
%D In this second system module, we continue the definition of
%D some handy commands.
@@ -110,8 +110,8 @@
%D are needed:
\def\newif#1%
- {\count@\escapechar
- \escapechar\m@ne
+ {\scratchcounter\escapechar
+ \escapechar\minusone
\expandafter\expandafter\expandafter
\redoglobal\expandafter\expandafter\expandafter
\edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}%
@@ -119,7 +119,7 @@
\redoglobal\expandafter\expandafter\expandafter
\edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}%
\dodoglobal\@if#1{false}%
- \escapechar\count@}
+ \escapechar\scratchcounter}
%D Also new:
@@ -437,7 +437,7 @@
%D Slower but better:
\ifx\letterbackslash\undefined
- {\catcode`.=0 .catcode`.\ 12 .xdef.letterbackslash{.string\}} % hack
+ {\catcode`.=0 .catcode`.\ 12 .xdef.letterbackslash{.string\}} % hack
\fi
\def\strippedcsname#1% this permits \strippedcsname{\xxx} and \strippedcsname{xxx}
@@ -1013,6 +1013,27 @@
\let\endofloop\dodoloop
\dodoloop1} % no \plusone else \recurselevel wrong
+%D For special purposes:
+
+\newcount\fastrecursecounter
+\newcount\lastrecursecounter
+\newcount\steprecursecounter
+
+\def\dofastrecurse#1#2#3#4%
+ {\def\fastrecursebody{#4}%
+ \fastrecursecounter#1\relax
+ \lastrecursecounter#2\relax
+ \steprecursecounter#3\relax
+ \def\recurselevel{\number\fastrecursecounter}%
+ \dodofastrecurse}
+
+\def\dodofastrecurse
+ {\ifnum\fastrecursecounter>\lastrecursecounter\else
+ \fastrecursebody
+ \advance\fastrecursecounter\steprecursecounter
+ \expandafter\dodofastrecurse
+ \fi}
+
%D This alternative looks a bit different and uses a
%D pseudo counter. When this macro is nested, we have to use
%D different counters. This time we use keywords.
@@ -1073,6 +1094,7 @@
%D \def\EveryLine%
%D {\afterassignment\doEveryLine\scratchtoks}
%D \stoptyping
+%D
%D The real implementation is a bit more complicated but we
%D prefer something more versatile.
@@ -1471,7 +1493,7 @@
\def\ExpandFirstAfter#1%
{\let\ExpandCommand#1%
- \doifnextcharelse[\complexExpandFirstAfter\simpleExpandFirstAfter}
+ \doifnextoptionalelse\complexExpandFirstAfter\simpleExpandFirstAfter}
\def\ExpandSecondAfter#1#2#3%
{\scratchtoks{#2}%
@@ -1832,12 +1854,10 @@
% compatible ?
\long\unexpanded\def\groupedcommand#1#2%
- {\doifnextcharelse\bgroup
- {\HandleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}}
+ {\doifnextbgroupelse{\HandleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}}
\long\unexpanded\def\simplegroupedcommand#1#2%
- {\doifnextcharelse\bgroup
- {\HandleSimpleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}}
+ {\doifnextbgroupelse{\HandleSimpleGroup{#1}{#2}}{\HandleNoGroup{#1}{#2}}}
%D Users should be aware of the fact that grouping can
%D interfere with ones paragraph settings that are executed
@@ -2069,7 +2089,7 @@
%D \def\dowithpargument#1%
%D {\def\nextpar##1 \par{#1{##1}}%
%D \def\nextarg##1{#1{##1}}%
-%D \doifnextcharelse{\bgroup}
+%D \doifnextcharelse\bgroup
%D {\nextarg}
%D {\nextpar}}
%D \stoptyping
@@ -2081,7 +2101,7 @@
%\def\dowithpargument#1%
% {\def\nextpar##1 \par{#1{##1}}%
% \def\nextarg##1{#1{##1}}%
-% \doifnextcharelse{\bgroup}
+% \doifnextcharelse\bgroup
% {\nextarg}
% {\doifnextcharelse{\par}
% {#1{}}
@@ -2090,7 +2110,7 @@
\def\dowithpargument#1%
{\def\nextpar##1 \par{#1{##1}}%
\def\nextarg##1{#1{##1}}%
- \doifnextcharelse\bgroup\nextarg{\doifnextcharelse\par{#1{}}\nextpar}}
+ \doifnextbgroupelse\nextarg{\doifnextcharelse\par{#1{}}\nextpar}}
%D The \type{p} in the previous command stands for paragraph.
%D When we want to act upon words we can use the \type{w}
@@ -2133,14 +2153,14 @@
%\def\dowithwargument#1%
% {\def\nextwar##1 {#1{##1}}%
% \def\nextarg##1{#1{##1}}%
-% \doifnextcharelse{\bgroup}
+% \doifnextcharelse\bgroup
% {\nextarg}
% {\nextwar}}
\def\dowithwargument#1%
{\def\nextwar##1 {#1{##1}}%
\def\nextarg##1{#1{##1}}%
- \doifnextcharelse\bgroup\nextarg\nextwar}
+ \doifnextbgroupelse\nextarg\nextwar}
%D \macros
%D {dorepeat,dorepeatwithcommand}
@@ -2368,6 +2388,8 @@
% A slightly (but in the case of large arguments
% significantly) faster alternative is given below:
+\newtoks\@@toks
+
\def\dodoappendtoks
{\dodoglobal\@@toks\@EAEAEA{\@EA\the\@EA\@@toks\the\@@scratchtoks}}
@@ -3016,8 +3038,7 @@
\expandafter\globalprocesscommaitem#1,],}
%D \macros
-%D {withoutunit,withoutpt,
-%D PtToCm,
+%D {withoutpt,PtToCm,
%D numberofpoints,dimensiontocount}
%D
%D We can convert point into centimeters with:
@@ -3025,24 +3046,6 @@
%D \starttyping
%D \PtToCm{dimension}
%D \stoptyping
-%D
-%D Splitting the value and the unit is done by:
-
-\def\withoutunit#1#2%
- {\begingroup
- \scratchdimen#1\relax
- \@EA\convertargument\the\scratchdimen\to\asciia
- \@EA\convertargument#2\to\asciib
- %\@EA\@EA\@EA\beforesplitstring\@EA\asciia\@EA\at\asciib\to\!!stringa
- \@EA\beforesplitstring\@EA\asciia\@EA\at\asciib\to\!!stringa
- \!!stringa
- \endgroup}
-
-\def\withoutpt#1{\withoutunit{#1}{pt}}
-\def\withoutcm#1{\withoutunit{#1}{cm}}
-
-%D A bit faster and more robust alternative is one that
-%D manipulates the \CATCODES.
{\catcode`\.=\@@other
\catcode`\p=\@@other
@@ -3076,18 +3079,11 @@
%D
%D Both macros return a rounded number.
-% todo: etex version
+% \dimensiontocount{10.49pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.49pt}
+% \dimensiontocount{10.51pt}\scratchcounter \the\scratchcounter / \numberofpoints{10.51pt}
-\def\numberofpoints#1%
- {\scratchdimen#1%
- \advance\scratchdimen .5pt
- \withoutpt\the\scratchdimen}
-
-\def\dimensiontocount#1#2%
- {\scratchdimen#1%
- \advance\scratchdimen .5pt
- #2\scratchdimen
- \divide#2 \maxcard}
+\def\dimensiontocount#1#2{#2\numexpr\dimexpr#1\relax/\maxcard\relax}
+\def\numberofpoints #1{\the\numexpr\dimexpr#1\relax/\maxcard\relax}
%D \macros
%D {swapdimens,swapmacros}
@@ -3946,7 +3942,7 @@
% %D handle the special case.
%
% \def\dohonorgroupedargument#1[%
-% {\doifnextcharelse\bgroup{\dodohonorgroupedargument#1}{#1[}}
+% {\doifnextbgroupelse{\dodohonorgroupedargument#1}{#1[}}
%
% \def\dodohonorgroupedargument#1#2%
% {#1[{{#2}}}
@@ -4470,24 +4466,43 @@
\beginTEX
- \let\integerrounding \firstofoneargument
- \let\onedigitrounding\firstofoneargument
- \let\twodigitrounding\firstofoneargument
+ \let\integerrounding \firstofoneargument
+ \let\onedigitrounding \firstofoneargument
+ \let\twodigitrounding \firstofoneargument
+ \let\threedigitrounding\firstofoneargument
\endTEX
\beginETEX \dimexpr
- \def\dointegerrounding #1.#2\relax {#1}
- \def\doonedigitrounding#1.#2#3\relax {\ifx#2*#1\else#1.#2\fi}
- \def\dotwodigitrounding#1.#2#3#4\relax{\ifx#2*#1\else#1.#2#3\fi}
+ \def\dointegerrounding #1.#2\relax {#1}
+ \def\doonedigitrounding #1.#2#3\relax {\ifx#2*#1\else#1.#2\fi}
+ \def\dotwodigitrounding #1.#2#3#4\relax {\ifx#2*#1\else#1.#2#3\fi}
+ \def\dothreedigitrounding#1.#2#3#4#5\relax{\ifx#2*#1\else#1.#2#3#4\fi}
\def\integerrounding#1%
- {\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.5\points\relax.\relax}
+ {\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.5\points \relax .\relax}
\def\onedigitrounding#1%
- {\@EA\@EA\@EA\doonedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.05\points\relax00.*0\relax}
+ {\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.05\points \relax 00.*0\relax}
\def\twodigitrounding#1%
- {\@EA\@EA\@EA\dotwodigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.005\points\relax000.*00\relax}
+ {\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr#1\points+.005\points \relax 000.*00\relax}
+ \def\threedigitrounding#1%
+ {\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax0000.*00\relax}
+
+% \def\dointegerrounding #1.#2\relax {#1}
+% \def\doonedigitrounding #1.#2#3\relax {#1.#2}
+% \def\dotwodigitrounding #1.#2#3#4\relax {#1.#2#3}
+% \def\dothreedigitrounding#1.#2#3#4#5\relax{#1.#2#3#4}
+
+% \def\integerrounding #1{\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr #1\points+.5\points\relax \relax}
+% \def\onedigitrounding #1{\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr #1\points+.05\points\relax 0\relax}
+% \def\twodigitrounding #1{\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr #1\points+.005\points\relax 00\relax}
+% \def\threedigitrounding#1{\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1\points+.0005\points\relax000\relax}
+
+% \def\integerroundeddimen #1{\@EA\@EA\@EA\dointegerrounding \@EA\WITHOUTPT\the\dimexpr #1+.5\points\relax \relax}
+% \def\onedigitroundeddimen #1{\@EA\@EA\@EA\doonedigitrounding \@EA\WITHOUTPT\the\dimexpr #1+.05\points\relax 0\relax}
+% \def\twodigitroundeddimen #1{\@EA\@EA\@EA\dotwodigitrounding \@EA\WITHOUTPT\the\dimexpr #1+.005\points\relax 00\relax}
+% \def\threedigitroundeddimen#1{\@EA\@EA\@EA\dothreedigitrounding\@EA\WITHOUTPT\the\dimexpr#1+.0005\points\relax000\relax}
\endETEX
@@ -4642,44 +4657,6 @@
{\comparedresult\plusone}}
%D \macros
-%D {@saveprimitive}
-%D
-%D The next definition originates in the \type {amsgen} package. In
-%D case some preceding package redefined a primitive that we also
-%D want to redefine, we had better do some checking to make sure
-%D that we are able to save the primitive meaning for internal use.
-%D Primitive control sequences can be distinguished by the fact that
-%D \type {\string} and \type {\meaning} return the same information.
-
-\def\@saveprimitive#1#2%
- {\begingroup
- \edef\@tempa{\string#1}%
- \edef\@tempb{\meaning#1}%
- \ifx\@tempa\@tempb
- \global\let#2#1%
- %\debuggerinfo{prim}{Saving \string#1 as \string#2}%
- \else
- \edef\@tempb{\meaning#2}%
- %\ifx\@tempa\@tempb
- % \debuggerinfo{prim}{Saving \string#1 as \string#2}%
- %\else
- % \debuggerinfo{prim}{Can't define \string#2 properly;
- % primitive \noexpand#1 is no longer primitive}%
- %\fi
- \fi
- \endgroup}
-
-\def\saveprimitive#1%
- {\begingroup
- \@EA\edef\@EA\@tempa\@EA{\@EA\gobbleoneargument\string#1}%
- \@EA\let\csname normal\@tempa\endcsname\relax
- \@EA\@saveprimitive\@EA#1\csname normal\@tempa\endcsname
- \endgroup }
-
-%D In this macro, the message only shows up when the debugging
-%D is turned on.
-
-%D \macros
%D {@True, @False, @Not, @And}
%D
%D Some predicate logic functions, used in for instance the
diff --git a/tex/context/base/syst-fnt.mkii b/tex/context/base/syst-fnt.mkii
new file mode 100644
index 000000000..66439c194
--- /dev/null
+++ b/tex/context/base/syst-fnt.mkii
@@ -0,0 +1,46 @@
+%D \module
+%D [ file=syst-fnt,
+%D version=2006.08.11,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Font Things,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% formal names cf the tb \& tbt
+
+\unprotect
+
+\def\fontslantperpoint {\fontdimen\plusone }
+\def\fontinterwordspace {\fontdimen\plustwo }
+\def\fontinterwordstretch{\fontdimen\plusthree}
+\def\fontinterwordshrink {\fontdimen\plusfour }
+\def\fontexheight {\fontdimen\plusfive }
+\def\fontemwidth {\fontdimen\plussix }
+\def\fontextraspace {\fontdimen\plusseven}
+
+\def\slantperpoint {\fontdimen\plusone \font}
+\def\interwordspace {\fontdimen\plustwo \font}
+\def\interwordstretch {\fontdimen\plusthree\font}
+\def\interwordshrink {\fontdimen\plusfour \font}
+\def\exheight {\fontdimen\plusfive \font}
+\def\emwidth {\fontdimen\plussix \font}
+\def\extraspace {\fontdimen\plusseven\font}
+
+\def\mathsupdisplay {\fontdimen13 }
+\def\mathsupnormal {\fontdimen14 }
+\def\mathsupcramped {\fontdimen15 }
+\def\mathsubnormal {\fontdimen16 }
+\def\mathsubcombined {\fontdimen17 }
+\def\mathaxisheight {\fontdimen22 }
+
+\def\currentspaceskip {\interwordspace\!!plus\interwordstretch\!!minus\interwordshrink\relax}
+
+\def\mathstacktotal {\dimexpr\fontdimen10\scriptfont\plustwo+\fontdimen12\scriptfont\plustwo\relax}
+\def\mathstackvgap {\plusthree\fontdimen8\scriptfont\plusthree}
+
+\protect \endinput
diff --git a/tex/context/base/syst-fnt.mkiv b/tex/context/base/syst-fnt.mkiv
new file mode 100644
index 000000000..8ba0dd2a3
--- /dev/null
+++ b/tex/context/base/syst-fnt.mkiv
@@ -0,0 +1,46 @@
+%D \module
+%D [ file=syst-fnt,
+%D version=2006.08.11,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Font Things,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% formal names cf the tb \& tbt
+
+\unprotect
+
+\def\fontslantperpoint {\fontdimen\plusone }
+\def\fontinterwordspace {\fontdimen\plustwo }
+\def\fontinterwordstretch{\fontdimen\plusthree}
+\def\fontinterwordshrink {\fontdimen\plusfour }
+\def\fontexheight {\fontdimen\plusfive }
+\def\fontemwidth {\fontdimen\plussix }
+\def\fontextraspace {\fontdimen\plusseven}
+
+\def\slantperpoint {\fontdimen\plusone \font}
+\def\interwordspace {\fontdimen\plustwo \font}
+\def\interwordstretch {\fontdimen\plusthree\font}
+\def\interwordshrink {\fontdimen\plusfour \font}
+\def\exheight {\fontdimen\plusfive \font}
+\def\emwidth {\fontdimen\plussix \font}
+\def\extraspace {\fontdimen\plusseven\font}
+
+\def\mathsupdisplay {\fontdimen13 } % to be remapped
+\def\mathsupnormal {\fontdimen14 } % to be remapped
+\def\mathsupcramped {\fontdimen15 } % to be remapped
+\def\mathsubnormal {\fontdimen16 } % to be remapped
+\def\mathsubcombined {\fontdimen17 } % to be remapped
+\def\mathaxisheight {\fontdimen22 } % to be remapped
+
+\def\currentspaceskip {\interwordspace\!!plus\interwordstretch\!!minus\interwordshrink\relax}
+
+\def\mathstacktotal {\dimexpr\Umathstacknumup\scriptstyle+\Umathstackdenomdown\scriptstyle\relax}
+\def\mathstackvgap {\Umathstackvgap\scriptstyle}
+
+\protect \endinput
diff --git a/tex/context/base/syst-fnt.tex b/tex/context/base/syst-fnt.tex
deleted file mode 100644
index 7ffc6464e..000000000
--- a/tex/context/base/syst-fnt.tex
+++ /dev/null
@@ -1,43 +0,0 @@
-%D \module
-%D [ file=syst-fnt,
-%D version=2006.08.11,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Font Things,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% formal names cf the tb \& tbt
-
-\unprotect
-
-\def\fontslantperpoint {\fontdimen1 }
-\def\fontinterwordspace {\fontdimen2 }
-\def\fontinterwordstretch{\fontdimen3 }
-\def\fontinterwordshrink {\fontdimen4 }
-\def\fontexheight {\fontdimen5 }
-\def\fontemwidth {\fontdimen6 }
-\def\fontextraspace {\fontdimen7 }
-
-\def\slantperpoint {\fontdimen1\font}
-\def\interwordspace {\fontdimen2\font}
-\def\interwordstretch {\fontdimen3\font}
-\def\interwordshrink {\fontdimen4\font}
-\def\exheight {\fontdimen5\font}
-\def\emwidth {\fontdimen6\font}
-\def\extraspace {\fontdimen7\font}
-
-\def\mathsupdisplay {\fontdimen13 }
-\def\mathsupnormal {\fontdimen14 }
-\def\mathsupcramped {\fontdimen15 }
-\def\mathsubnormal {\fontdimen16 }
-\def\mathsubcombined {\fontdimen17 }
-\def\mathaxisheight {\fontdimen22 }
-
-\def\currentspaceskip {\interwordspace\!!plus\interwordstretch\!!minus\interwordshrink\relax}
-
-\protect \endinput
diff --git a/tex/context/base/syst-gen.tex b/tex/context/base/syst-gen.tex
index 78311de38..993512b74 100644
--- a/tex/context/base/syst-gen.tex
+++ b/tex/context/base/syst-gen.tex
@@ -123,7 +123,7 @@
%D defined.
%D
%D \starttyping
-%D \writestatus{laden}{Context Systeem Macro's (a)}
+%D \writestatus{laden}{Context Systeem Macros (a)}
%D \stoptyping
%D The next few macros are needed in case this module is
@@ -132,10 +132,6 @@
\ifx\beginTEX\undefined
\let\beginTEX\relax\let\endTEX\relax
\long\def\beginETEX #1\endETEX {}
- \long\def\beginOMEGA #1\endOMEGA{}
-% \long\def\onlyTEX #1{#1}
-% \long\def\onlyETEX #1{}
-% \long\def\onlyOMEGA#1{}
\fi
%D \macros
@@ -311,6 +307,9 @@
\newabove \newtoks \scratchtoks \newabove \newtoks \globalscratchtoks
\newbox \scratchbox \newbox \globalscratchbox
+\newdimen\scratchdimenone \newbox\scratchboxone \newcount\scratchcounterone
+\newdimen\scratchdimentwo \newbox\scratchboxtwo \newcount\scratchcountertwo
+
%D \macros
%D {ifdone}
@@ -361,23 +360,21 @@
%D Beware: we don't reuse plain counters, too dangerous
%D when <= 20 (e.g. in supp-pdf this messed up things).
-\newdimen \zeropoint
-\newcount \zerocount
-\newcount \minusone
- \minusone = -1
-\newcount \minustwo
- \minustwo = -2
-
-\chardef \plusone = 1
-\chardef \plustwo = 2
-\chardef \plusthree = 3
-\chardef \plusfour = 4
-\chardef \plusfive = 5
-
-\mathchardef \plusten = 10
-\mathchardef \plushundred = 100
-\mathchardef \plusthousand = 1000
-\mathchardef \plustenthousand = 10000
+\ifx\undefined\zeroskip \newskip \zeroskip \fi
+\ifx\undefined\zeropoint \newdimen \zeropoint \fi
+\ifx\undefined\zerocount \newcount \zerocount \fi
+\ifx\undefined\minusone \newcount \minusone \fi \minusone = -1
+\ifx\undefined\minustwo \newcount \minustwo \fi \minustwo = -2
+\ifx\undefined\plusone \chardef \plusone = 1 \fi
+\ifx\undefined\plustwo \chardef \plustwo = 2 \fi
+\ifx\undefined\plusthree \chardef \plusthree = 3 \fi
+\ifx\undefined\plusfour \chardef \plusfour = 4 \fi
+\ifx\undefined\plusfive \chardef \plusfive = 5 \fi
+\ifx\undefined\plusten \mathchardef \plusten = 10 \fi
+\ifx\undefined\plushundred \mathchardef \plushundred = 100 \fi
+\ifx\undefined\plusthousand \mathchardef \plusthousand = 1000 \fi
+\ifx\undefined\plustenthousand \mathchardef \plustenthousand = 10000 \fi
+\ifx\undefined\plustwentythousand \mathchardef \plustwentythousand = 20000 \fi
%D \macros
%D {s!,c!,e!,p!,v!,@@,??}
@@ -397,6 +394,8 @@
\def\s!complex {complex} \def\s!start {start}
\def\s!simple {simple} \def\s!stop {stop}
+\def\s!empty {empty}
+
%D \macros
%D {@EA,@EAEA,@EAEAEA,@EAEAEAEAEAEA,expanded,startexpanded}
%D
@@ -544,10 +543,43 @@
\@EAEAEA\!!stringb
\fi\fi}
-%\let\endoflinetoken=^^M
-%
-%\long\def\reinspectaftercharacter#1%
-% {\futurelet\nexttoken\inspectnextcharacter}
+%D Because we will mostly use this macro for testing if the next
+%D character is \type {[}, we also make a slightly faster variant
+%D as it is not uncommon to have tens of thousands of calls to this
+%D test in a run. Of course it also is more convenient to read a
+%D trace then.
+
+\let\nextoptionalcharactertoken=[
+
+\long\def\doifnextoptionalelse#1#2%
+ {\def\nextoptionalcommandyes{#1}%
+ \def\nextoptionalcommandnop{#2}%
+ \futurelet\nexttoken\inspectnextoptionalcharacter}
+
+\def\inspectnextoptionalcharacter
+ {\ifx\nexttoken\blankspace
+ \@EA\reinspectnextoptionalcharacter
+ \else\ifx\nexttoken\nextoptionalcharactertoken
+ \@EAEAEA\nextoptionalcommandyes
+ \else
+ \@EAEAEA\nextoptionalcommandnop
+ \fi\fi}
+
+\let\nextbgroupcharactertoken\bgroup
+
+\long\def\doifnextbgroupelse#1#2%
+ {\def\nextbgroupcommandyes{#1}%
+ \def\nextbgroupcommandnop{#2}%
+ \futurelet\nexttoken\inspectnextbgroupcharacter}
+
+\def\inspectnextbgroupcharacter
+ {\ifx\nexttoken\blankspace
+ \@EA\reinspectnextbgroupcharacter
+ \else\ifx\nexttoken\nextbgroupcharactertoken
+ \@EAEAEA\nextbgroupcommandyes
+ \else
+ \@EAEAEA\nextbgroupcommandnop
+ \fi\fi}
%D This macro uses some auxiliary macros. Although we were able
%D to program quite complicated things, I only understood these
@@ -579,9 +611,14 @@
\def\:{\let\blankspace= } \:
\def\:{\reinspectnextcharacter}
-
\expandafter\def\: {\futurelet\nexttoken\inspectnextcharacter}
+\def\:{\reinspectnextoptionalcharacter}
+\expandafter\def\: {\futurelet\nexttoken\inspectnextoptionalcharacter}
+
+\def\:{\reinspectnextbgroupcharacter}
+\expandafter\def\: {\futurelet\nexttoken\inspectnextbgroupcharacter}
+
\let\:\next
%D \macros
@@ -963,6 +1000,11 @@
\def\letbeundefined#1% potential stack buildup when used \global
{\expandafter\let\csname#1\endcsname\undefined}
+\def\localundefine#1% conditional
+ {\ifcsname#1\endcsname\expandafter\let\csname#1\endcsname\undefined\fi}
+\def\globalundefine#1% conditional
+ {\ifcsname#1\endcsname\expandafter\global\let\csname#1\endcsname\undefined\fi}
+
\endETEX
%D Beware, being \type {\undefined} in \ETEX\ means that the macro
@@ -1604,6 +1646,8 @@
% \expandafter\firstofoneargument
% \fi}
+% todo: use dedicated done
+
\def\p!dodocommoncheck#1%
{\edef\!!stringb{#1}%
\ifx\!!stringa\!!stringb
@@ -2331,6 +2375,14 @@
%D run time, simply because the less tokens we pass, the faster
%D \TEX\ runs. So finally the definition became:
+% \long\def\rawdoifinstringelse#1#2% ##2 can be {abc}
+% {\long\def\pp!doifinstringelse##1#1##2##3\war{\if##2@}%
+% \pp!doifinstringelse#2#1@@\war
+% \expandafter\secondoftwoarguments
+% \else
+% \expandafter\firstoftwoarguments
+% \fi}
+
\long\def\doifinstringelse#1%
{\edef\@@@instring{#1}% expand #1 here
\ifx\@@@instring\empty
@@ -3033,30 +3085,55 @@
\let\currentvalue\empty
-\def\p!n!doassign#1#2\@relax@#3=#4=#5#6\@relax@% normal
- {\ifx#5\empty
+% \def\p!n!doassign#1#2\@relax@#3=#4=#5#6\@relax@% normal
+% {\ifx#5\empty
+% \@EA\xshowassignerror
+% \else\ifx#5=%
+% \@EAEAEA#1%
+% \else
+% \@EAEAEA\xshowassignerror
+% \fi\fi
+% {#2}{#3}{#4}}
+
+\def\p!n!doassign#1#2\@relax@#3=#4=#5#6\@relax@
+ {\ifx\empty#3\empty
\@EA\xshowassignerror
- \else\ifx#5=%
- \@EAEAEA#1%
- \else
+ \else\ifx#5\empty
\@EAEAEA\xshowassignerror
+ \else
+ \@EAEAEA#1%
\fi\fi
{#2}{#3}{#4}}
\beginTEX
+% \def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@
+% {\ifx#5\empty
+% \@EA\xshowassignerror
+% \else\ifx#5=%
+% \@EA\ifx\csname#2#3\endcsname\relax
+% \let\currentvalue\empty
+% \else
+% \@EA\let\@EA\currentvalue\csname#2#3\endcsname
+% \fi
+% \@EAEAEA#1%
+% \else
+% \@EAEAEA\xshowassignerror
+% \fi\fi
+% {#2}{#3}{#4}}
+
\def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@
- {\ifx#5\empty
+ {\ifx\empty#3\empty
\@EA\xshowassignerror
- \else\ifx#5=%
+ \else\ifx#5\empty
+ \@EAEAEA\xshowassignerror
+ \else
\@EA\ifx\csname#2#3\endcsname\relax
\let\currentvalue\empty
\else
\@EA\let\@EA\currentvalue\csname#2#3\endcsname
\fi
\@EAEAEA#1%
- \else
- \@EAEAEA\xshowassignerror
\fi\fi
{#2}{#3}{#4}}
@@ -3064,18 +3141,33 @@
\beginETEX
+% \def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@
+% {\ifx#5\empty
+% \@EA\xshowassignerror
+% \else\ifx#5=%
+% \ifcsname#2#3\endcsname
+% \@EA\let\@EA\currentvalue\csname#2#3\endcsname
+% \else
+% \let\currentvalue\empty
+% \fi
+% \@EAEAEA#1%
+% \else
+% \@EAEAEA\xshowassignerror
+% \fi\fi
+% {#2}{#3}{#4}}
+
\def\p!e!doassign#1#2\@relax@#3=#4=#5#6\@relax@
- {\ifx#5\empty
+ {\ifx\empty#3\empty
\@EA\xshowassignerror
- \else\ifx#5=%
+ \else\ifx#5\empty
+ \@EAEAEA\xshowassignerror
+ \else
\ifcsname#2#3\endcsname
\@EA\let\@EA\currentvalue\csname#2#3\endcsname
\else
\let\currentvalue\empty
\fi
\@EAEAEA#1%
- \else
- \@EAEAEA\xshowassignerror
\fi\fi
{#2}{#3}{#4}}
@@ -3464,7 +3556,7 @@
\chardef\expectedarguments =0
\def\showargumenterror#1#2%
- {\writestatus{system}{#1 argument(s) expected in line #2}}
+ {\writestatus{systems}{#1 argument(s) expected in line #2}}
% \long\def\dogetargument#1#2#3#4% redefined in mult-ini
% {\doifnextcharelse{#1}
@@ -3608,19 +3700,19 @@
\def\dosingleempty#1%
{\noshowargumenterror % \relax % prevents lookahead, brr
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\firstargumenttrue#1}
{\dosinglefakeempty#1}}
\def\dodoubleempty#1%
{\noshowargumenterror % \relax % prevents lookahead, brr
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\dodoubletestempty#1}
{\dodoublefakeempty#1}}
\def\dotripleempty#1%
{\noshowargumenterror % \relax % prevents lookahead, brr
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\dotripletestempty#1}
{\dotriplefakeempty#1}}
@@ -3635,20 +3727,20 @@
\long\def\dodoubletestempty#1[#2]%
{\firstargumenttrue
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\secondargumenttrue #1[{#2}]}
{\secondargumentfalse#1[{#2}][]}}
\long\def\dotripletestempty#1[#2]%
{\firstargumenttrue
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\dotripletestemptyx #1[{#2}]}
{\secondargumentfalse
\thirdargumentfalse #1[{#2}][][]}}
\long\def\dotripletestemptyx#1[#2][#3]%
{\secondargumenttrue
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\thirdargumenttrue #1[{#2}][{#3}]}
{\thirdargumentfalse#1[{#2}][{#3}][]}}
@@ -3736,13 +3828,13 @@
\def\complexorsimple#1%
{% \relax % prevents lookahead, brrr
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname}
{\firstargumentfalse\csname\s!simple \strippedcsname#1\endcsname}}
\def\complexorsimpleempty#1%
{% \relax % prevents lookahead, brrr
- \doifnextcharelse[%
+ \doifnextoptionalelse
{\firstargumenttrue \csname\s!complex\strippedcsname#1\endcsname}
{\firstargumentfalse\csname\s!complex\strippedcsname#1\endcsname[]}}
@@ -3793,10 +3885,10 @@
% faster, since no \strippedcsname needed in call, but more spacy
\def\docomplexorsimple#1#2%
- {\doifnextcharelse[{\firstargumenttrue#1}{\firstargumentfalse#2}}
+ {\doifnextoptionalelse{\firstargumenttrue#1}{\firstargumentfalse#2}}
\def\docomplexorsimpleempty#1%
- {\doifnextcharelse[{\firstargumenttrue#1}{\firstargumentfalse#1[]}}
+ {\doifnextoptionalelse{\firstargumenttrue#1}{\firstargumentfalse#1[]}}
\def\definecomplexorsimple#1%
{\unexpanded\edef#1%
@@ -3926,35 +4018,6 @@
%D \type {\if} and friends, in practice we will use a
%D slightly more complicated macro.
-\let\normalif \if
-\let\normalifcat \ifcat
-\let\normalifnum \ifnum
-\let\normalifdim \ifdim
-\let\normalifodd \ifodd
-\let\normalifvmode \ifvmode
-\let\normalifhmode \ifhmode
-\let\normalifmmode \ifmmode
-\let\normalifinner \ifinner
-\let\normalifvoid \ifvoid
-\let\normalifhbox \ifhbox
-\let\normalifvbox \ifvbox
-\let\normalifx \ifx
-\let\normalifeof \ifeof
-\let\normaliftrue \iftrue
-\let\normaliffalse \iffalse
-\let\normalifcase \ifcase
-\let\normalifdefined \ifdefined
-\let\normalifcsname \ifcsname
-\let\normaliffontchar \iffontchar
-\let\normalifincsname \ifincsname
-\let\normalifprimitive\ifprimitive
-\let\normalifabsnum \ifabsnum
-\let\normalifabsdim \ifabsdim
-
-\let\normalelse \else
-\let\normalor \or
-\let\normalfi \fi
-
\newtoks \everyrobusttest
\everyrobusttest
@@ -4000,34 +4063,65 @@
\dontpermitspacesbetweengroups
+% \def\dogetgroupargument#1#2%
+% {\def\nextnextargument%
+% {\normalifx\nextargument\bgroup
+% \endrobusttest
+% \noshowargumenterror
+% \def\nextargument{#1\dodogetargument}%
+% \normalelse
+% \normalifcase\@@permitspacesbetweengroups
+% \normalifx\nextargument\lineending
+% \endrobusttest
+% \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument#1#2}\\}%
+% \normalelse\normalifx\nextargument\blankspace
+% \endrobusttest
+% \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument#1#2}\\}%
+% \normalelse
+% \endrobusttest
+% \doshowargumenterror
+% \def\nextargument{#2\dodogetargument{}}%
+% \normalfi\normalfi
+% \normalelse
+% \endrobusttest
+% \doshowargumenterror
+% \def\nextargument{#2\dodogetargument{}}%
+% \normalfi
+% \normalfi
+% \nextargument}%
+% \beginrobusttest
+% \futurelet\nextargument\nextnextargument}
+
+\def\dodogetgroupargument
+ {\normalifx\nextargument\bgroup
+ \endrobusttest
+ \noshowargumenterror
+ \def\nextargument{\dogroupargumentyes\dodogetargument}%
+ \normalelse
+ \normalifcase\@@permitspacesbetweengroups
+ \normalifx\nextargument\lineending
+ \endrobusttest
+ \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument\dogroupargumentyes\dogroupargumentnop}\\}%
+ \normalelse\normalifx\nextargument\blankspace
+ \endrobusttest
+ \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument\dogroupargumentyes\dogroupargumentnop}\\}%
+ \normalelse
+ \endrobusttest
+ \doshowargumenterror
+ \def\nextargument{\dogroupargumentnop\dodogetargument{}}%
+ \normalfi\normalfi
+ \normalelse
+ \endrobusttest
+ \doshowargumenterror
+ \def\nextargument{\dogroupargumentnop\dodogetargument{}}%
+ \normalfi
+ \normalfi
+ \nextargument}%
+
\def\dogetgroupargument#1#2%
- {\def\nextnextargument%
- {\normalifx\nextargument\bgroup
- \endrobusttest
- \noshowargumenterror
- \def\nextargument{#1\dodogetargument}%
- \normalelse
- \normalifcase\@@permitspacesbetweengroups
- \normalifx\nextargument\lineending
- \endrobusttest
- \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument#1#2}\\}%
- \normalelse\normalifx\nextargument\blankspace
- \endrobusttest
- \def\nextargument{\begingroup\def\\ {\endgroup\dogetgroupargument#1#2}\\}%
- \normalelse
- \endrobusttest
- \doshowargumenterror
- \def\nextargument{#2\dodogetargument{}}%
- \normalfi\normalfi
- \normalelse
- \endrobusttest
- \doshowargumenterror
- \def\nextargument{#2\dodogetargument{}}%
- \normalfi
- \normalfi
- \nextargument}%
- \beginrobusttest
- \futurelet\nextargument\nextnextargument}
+ {\let\dogroupargumentyes#1%
+ \let\dogroupargumentnop#2%
+ \beginrobusttest\futurelet\nextargument\dodogetgroupargument}
\def\dosinglegroupempty#1%
{\def\dodogetargument%
@@ -4107,21 +4201,32 @@
%D used to select arguments. Their names explain their
%D functionality.
-\long\def\firstofoneargument #1{#1}
-\long\def\firstoftwoarguments #1#2{#1}
-\long\def\firstofthreearguments #1#2#3{#1}
-\long\def\firstoffourarguments #1#2#3#4{#1}
-\long\def\firstoffivearguments #1#2#3#4#5{#1}
-\long\def\secondoftwoarguments #1#2{#2}
-\long\def\secondofthreearguments #1#2#3{#2}
-\long\def\secondoffourarguments #1#2#3#4{#2}
-\long\def\secondoffivearguments #1#2#3#4#5{#2}
-\long\def\thirdofthreearguments #1#2#3{#3}
-\long\def\thirdoffourarguments #1#2#3#4{#3}
-\long\def\thirdoffivearguments #1#2#3#4#5{#3}
-\long\def\fourthoffourarguments #1#2#3#4{#4}
-\long\def\fourthoffivearguments #1#2#3#4#5{#4}
-\long\def\fifthoffivearguments #1#2#3#4#5{#5}
+\long\def\firstofoneargument#1{#1}
+
+\long\def\firstoftwoarguments #1#2{#1}
+\long\def\secondoftwoarguments#1#2{#2}
+
+\long\def\firstofthreearguments #1#2#3{#1}
+\long\def\secondofthreearguments#1#2#3{#2}
+\long\def\thirdofthreearguments #1#2#3{#3}
+
+\long\def\firstoffourarguments #1#2#3#4{#1}
+\long\def\secondoffourarguments#1#2#3#4{#2}
+\long\def\thirdoffourarguments #1#2#3#4{#3}
+\long\def\fourthoffourarguments#1#2#3#4{#4}
+
+\long\def\firstoffivearguments #1#2#3#4#5{#1}
+\long\def\secondoffivearguments#1#2#3#4#5{#2}
+\long\def\thirdoffivearguments #1#2#3#4#5{#3}
+\long\def\fourthoffivearguments#1#2#3#4#5{#4}
+\long\def\fifthoffivearguments #1#2#3#4#5{#5}
+
+\long\def\firstofsixarguments #1#2#3#4#5#6{#1}
+\long\def\secondofsixarguments#1#2#3#4#5#6{#2}
+\long\def\thirdofsixarguments #1#2#3#4#5#6{#3}
+\long\def\fourthofsixarguments#1#2#3#4#5#6{#4}
+\long\def\fifthofsixarguments #1#2#3#4#5#6{#5}
+\long\def\sixthofsixarguments #1#2#3#4#5#6{#6}
%D \macros
%D {globalletempty,letempty,letvalueempty,letgvalueempty}
@@ -4301,10 +4406,13 @@
%D Finally we do what from now on will be done at the top of
%D the files: we tell the user what we are loading.
-\ifx\writestatus\undefined \let\writestatus\normalwritestatus \fi
-\ifx\writebanner\undefined \def\writebanner{\writestring} \fi
+% \ifx\writestatus\undefined \let\writestatus\normalwritestatus \fi
+% \ifx\writebanner\undefined \def\writebanner{\writestring} \fi
+
+\let\writestatus\normalwritestatus
+\def\writebanner{\writestring}
-\writestatus{loading}{Context System Macros / General}
+\writestatus{loading}{ConTeXt System Macros / General}
%D Well, the real final command is the one that resets the
%D unprotected characters \type{@}, \type{?} and \type{!}.
diff --git a/tex/context/base/syst-ini.tex b/tex/context/base/syst-ini.tex
new file mode 100644
index 000000000..c334b1cf6
--- /dev/null
+++ b/tex/context/base/syst-ini.tex
@@ -0,0 +1,879 @@
+%D \module
+%D [ file=syst-ini,
+%D version=2008.11.04, % 2001.11.16, % 1999.03.17, % an oldie: 1995.10.10
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Bootstrapping \TEX,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 used to load plain \TEX\ in a special way, but redefining
+%D a couple of primitives so that for instance font loading was
+%D ignored. For those interested, this loader is found in
+%D \type {syst-tex.tex}. Some of the comment's are Don Knuth's
+%D and more of it can be found in the plain \TEX\ format.
+
+%D Characters can have special states, that can be triggered
+%D by setting their category coded. Some are preset, others
+%D are to be set as soon as possible, otherwise we cannot
+%D define any useful macros.
+
+%catcode`\^^@ = 9 % ascii null is ignored
+%catcode`\\ = 0 % backslash is TeX escape character
+
+\catcode`\{ = 1 % left brace is begin-group character
+\catcode`\} = 2 % right brace is end-group character
+\catcode`\$ = 3 % dollar sign is math shift
+\catcode`\& = 4 % ampersand is alignment tab
+\catcode`\# = 6 % hash mark is macro parameter character
+\catcode`\^ = 7 % circumflex and uparrow are for superscripts
+\catcode`\_ = 8 % underline and downarrow are for subscripts
+\catcode`\^^I = 10 % ascii tab is a blank space
+
+%catcode`\^^M = 5 % ascii return is end-line
+%catcode`\% = 14 % percent sign is comment character
+%catcode`\ = 10 % ascii space is blank space
+%catcode`\^^? = 15 % ascii delete is invalid
+
+\catcode`\~ = 13 % tilde is active
+\catcode`\^^L = 13 % ascii form-feed
+
+%catcode`\A = 11
+%.......
+%catcode`\Z = 11
+
+%catcode`\a = 11
+%.......
+%catcode`\z = 11
+
+\chardef\active = 13
+
+\def ^^L{\par}
+\def\^^M{\ } % control <return> = control <space>
+\def\^^I{\ } % same for <tab>
+
+%D In \CONTEXT, we simply ignore end||of||file tokens:
+
+\catcode`\^^Z=9
+
+%D It makes sense to know what engine we're running so let's
+%D try to deduce it.
+
+\chardef\unknownengine = 0
+\chardef\pdftexengine = 1
+\chardef\xetexengine = 2
+\chardef\luatexengine = 3
+
+\ifx\directlua\undefined
+ \ifx\XeTeXversion\undefined
+ \ifx\pdftexversion\undefined
+ \let\texengine\unknownengine
+ \else
+ \let\texengine\pdftexengine
+ \fi
+ \else
+ \let\texengine\xetexengine
+ \fi
+\else
+ \let\texengine\luatexengine
+\fi
+
+\ifnum\texengine=\unknownengine
+ \immediate\write16{>>>}
+ \immediate\write16{>>> only pdftex, xetex and luatex are supported}
+ \immediate\write16{>>>}
+ \let\dump\relax
+ \expandafter\end
+\fi
+
+% todo: pdfsave pdfrestore pdfcolor... don't initialize them
+
+\ifnum\texengine=\luatexengine
+ \directlua 0 { % this info is stored in the format
+ if lua.name then
+ lua.name[0] = "main ctx instance"
+ end
+ if tex.extraprimitives then
+ local core = tex.extraprimitives('core')
+ local btex = tex.extraprimitives('tex')
+ local etex = tex.extraprimitives('etex')
+ local pdftex = tex.extraprimitives('pdftex')
+ local luatex = tex.extraprimitives('luatex')
+ local omega = {
+ "textdir", "pagedir", "mathdir", "pardir", "bodydir",
+ "leftghost", "rightghost", "localleftbox", "localrightbox",
+ "localinterlinepenalty", "localbrokenpenalty",
+ }
+ local aleph = {
+ "boxdir", "pagebottomoffset", "pagerightoffset",
+ }
+ for _, subset in pairs { etex, pdftex, luatex, omega, aleph } do
+ tex.enableprimitives('',subset)
+ end
+ for _, subset in pairs { core, btex, etex, pdftex, luatex, omega, aleph } do
+ tex.enableprimitives('normal',subset)
+ end
+ end
+ }
+\fi
+
+%D \ETEX\ has a not so handy way of telling you the version number,
+%D i.e. the revision number has a period in it:
+
+\long\def\gobbleoneargument#1{} % will be defined later on anyway
+
+\mathchardef\etexversion =
+ \numexpr\eTeXversion*100+\expandafter\gobbleoneargument\eTeXrevision\relax
+
+%D First we define a simplified version of the \CONTEXT\
+%D protection mechanism.
+
+\def\unprotect{\catcode`@=11 }
+\def\protect {\catcode`@=12 }
+
+\unprotect
+
+%D Some pretty important definitions:
+
+\let\bgroup={
+\let\egroup=}
+
+%D Allocation of registers is done slightly different than in plain
+%D \TEX. First of all we use different reserved counters. We also
+%D don't implement a family handler because users are not supposed
+%D to implement their own math. We reserve the lowest 31 registers
+%D for scratch purposes. Keep in mind that in the core engine
+%D some registers are reserved: counters 0 upto 9, and counter 255.
+%D
+%D As with plain \TEX\ we recommend that macro designers always use
+%D \type {\global} assignments with respect to registers numbered 1,
+%D 3, 5 \unknown\ 31, and always non||\type {\global} assignments
+%D with respect to registers 0, 2, 4, \unknown\ 30. This will prevent
+%D \quote {save stack buildup} that might otherwise occur.
+%D
+%D We reserve some registers for special (management) purposes:
+
+\countdef \minallocatedregister = 52 \minallocatedregister = 256
+\countdef \maxallocatedregister = 53 \maxallocatedregister = 32767
+\countdef \minallocatediochannel = 54 \minallocatediochannel = -1
+\countdef \maxallocatediochannel = 55 \maxallocatediochannel = 16
+\countdef \minallocatedlanguage = 56 \minallocatedlanguage = 0
+\countdef \maxallocatedlanguage = 57 \maxallocatedlanguage = 255
+\countdef \maxallocatedinsert = 58 \maxallocatedinsert = 254
+\countdef \minallocatedinsert = 59 \minallocatedinsert = 128
+\countdef \minallocatedfamily = 60 \minallocatedfamily = 128
+\countdef \maxallocatedfamily = 61 \maxallocatedfamily = 255
+
+\countdef \lastallocatedcount = 32 \lastallocatedcount = \minallocatedregister
+\countdef \lastallocateddimen = 33 \lastallocateddimen = \minallocatedregister
+\countdef \lastallocatedskip = 34 \lastallocatedskip = \minallocatedregister
+\countdef \lastallocatedmuskip = 35 \lastallocatedmuskip = \minallocatedregister
+\countdef \lastallocatedbox = 36 \lastallocatedbox = \minallocatedregister
+\countdef \lastallocatedtoks = 37 \lastallocatedtoks = \minallocatedregister
+\countdef \lastallocatedread = 38 \lastallocatedread = \minallocatediochannel
+\countdef \lastallocatedwrite = 39 \lastallocatedwrite = \minallocatediochannel
+\countdef \lastallocatedmarks = 40 \lastallocatedmarks = \minallocatedregister
+\countdef \lastallocatedlanguage = 41 \lastallocatedlanguage = \minallocatedlanguage
+\countdef \lastallocatedinsertion = 42 \lastallocatedinsertion = \minallocatedinsert
+\countdef \lastallocatedfamily = 43 \lastallocatedfamily = \minallocatedfamily
+\countdef \lastallocatedattribute = 44 \lastallocatedattribute = \minallocatedregister
+
+\countdef \mincountervalue = 125 \mincountervalue = -"7FFFFFFF
+\countdef \maxcountervalue = 126 \maxcountervalue = "7FFFFFFF
+\countdef \minusone = 127 \minusone = -1
+\chardef \zerocount = 0
+\chardef \plusone = 1
+
+\chardef \normalpagebox = 255 % hardcoded in the engine
+
+% A few traditional allocations:
+
+\countdef \count@ = 255 % hm, used in \newif
+\dimendef \dimen@ = 0
+\dimendef \dimen@i = 1 % global only
+\dimendef \dimen@ii = 2
+
+%D So, effectively we start allocating from 256 and upwards. The
+%D inserts sit in the range 128 upto 254. Page numbers use the
+%D counters 0 upto 9 and the pagebox is 255. Users can use the
+%D scratch registers upto 31 without problem but all others are
+%D reserved.
+
+\def\wlog#1{} % \def\wlog{\immediate\write\minusone} % write on log file (only)
+
+%D The allocators share a common helper macro.
+
+\def\newcount {\allocateregister\lastallocatedcount \count \countdef \maxallocatedregister}
+\def\newdimen {\allocateregister\lastallocateddimen \dimen \dimendef \maxallocatedregister}
+\def\newskip {\allocateregister\lastallocatedskip \skip \skipdef \maxallocatedregister}
+\def\newmuskip {\allocateregister\lastallocatedmuskip \muskip \muskipdef \maxallocatedregister}
+\def\newbox {\allocateregister\lastallocatedbox \box \mathchardef\maxallocatedregister}
+\def\newtoks {\allocateregister\lastallocatedtoks \toks \toksdef \maxallocatedregister}
+\def\newread {\allocateregister\lastallocatedread \read \chardef \maxallocatediochannel}
+\def\newwrite {\allocateregister\lastallocatedwrite \write \chardef \maxallocatediochannel}
+\def\newmarks {\allocateregister\lastallocatedmarks \marks \mathchardef\maxallocatedregister}
+\def\newlanguage{\allocateregister\lastallocatedlanguage \language\chardef \maxallocatedlanguage}
+\def\newinsert {\allocateregister\lastallocatedinsertion\insert \chardef \maxallocatedinsert}
+\def\newfamily {\allocateregister\lastallocatedfamily \fam \chardef \maxallocatedfamily}
+
+\let\newfam\newfamily
+
+% %D The next definitions are really needed (in \CONTEXT):
+
+%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}}
+\newlinechar=10 \edef\outputnewlinechar{^^J}
+
+%D One reason to start high with allocation is that it permits us to
+%D allocate consecutive ranges more easily, for instance in \MPLIB\
+%D we want to allocate a continuous range of boxes. It also permits us
+%D to do a proper upward allocation for inserts. The current code
+%D evolved from code that dealt with older engines but as all engines
+%D now provide many registers we removed all traces.
+
+\def\writestatus#1#2{\immediate\write16{#1: #2}} \def\space { }
+
+\def\allocateregisteryes#1#2#3#4#5% last class method max name
+ {\ifnum#1<#4\relax
+ \global\advance#1\plusone
+ \global#3#5=#1\relax
+ \else
+ \writestatus{warning}{no room for \string#2\space \string#5\space (max: \number#4)}%
+ \fi}
+
+\def\allocateregisternop#1#2#3#4#5% last class method max name
+ {\writestatus{warning}{\string#2 \string#5 is already defined (\string\relax\space it first)}}
+
+\def\allocateregister#1#2#3#4#5% last class method max name
+ {\ifx#5\undefined
+ \expandafter\allocateregisteryes
+ \else\ifx#5\relax
+ \expandafter\expandafter\expandafter\allocateregisteryes
+ \else
+ \expandafter\expandafter\expandafter\allocateregisternop
+ \fi\fi
+ #1#2#3#4#5}
+
+%D Since the number of chars exceed 256 now, we can use \type
+%D {\chardef} instead of the more limited \type {\mathchardef}.
+
+\ifnum\texengine>\pdftexengine
+ \def\newbox {\allocateregister\lastallocatedbox \box \chardef\maxallocatedregister}
+ \def\newmarks{\allocateregister\lastallocatedmarks\marks\chardef\maxallocatedregister}
+\fi
+
+%D Attributes are something very \LUATEX. In \CONTEXT\ you are not
+%D supposed to use the attributes directly but always allocate then
+%D first. For instance attribute~0 is reserved for special purposes
+%D (this might change).
+
+\ifnum\texengine=\luatexengine
+ \let\attributeunsetvalue\mincountervalue % used to be \minusone
+ \def\newattribute{\allocateregister\lastallocatedattribute\attribute\attributedef\maxallocatedregister}
+\fi
+
+%D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a
+%D trick to force strings instead of tokens that take more memory.
+%D It's a trick to trick to force strings.
+
+\def\newhelp#1#2{\newtoks#1#1\expandafter{\csname#2\endcsname}}
+
+%D \macros
+%D {scratchcounter,
+%D scratchdimen,scratchskip,scratchmuskip,
+%D scratchbox,
+%D scratchtoks}
+%D
+%D We now define a few scratch registers, so that successive
+%D loads at least have some available.
+
+\newcount \scratchcounter \newcount \globalscratchcounter
+\newdimen \scratchdimen \newdimen \globalscratchdimen
+\newskip \scratchskip \newskip \globalscratchskip
+\newmuskip \scratchmuskip \newmuskip \globalscratchmuskip
+\newtoks \scratchtoks \newtoks \globalscratchtoks
+\newbox \scratchbox \newbox \globalscratchbox
+
+\newcount\scratchcounterone \newcount\scratchcountertwo \newcount\scratchcounterthree
+\newdimen \scratchdimenone \newdimen \scratchdimentwo \newdimen \scratchdimenthree
+\newdimen \scratchskipone \newdimen \scratchskiptwo \newdimen \scratchskipthree
+\newbox \scratchmuskipone \newbox \scratchmuskiptwo \newbox \scratchmuskipthree
+\newtoks \scratchtoksone \newtoks \scratchtokstwo \newtoks \scratchtoksthree
+\newbox \scratchboxone \newbox \scratchboxtwo \newbox \scratchboxthree
+
+%D More allocations:
+
+\newskip \zeroskip \zeroskip = 0pt plus 0pt minus 0pt
+\newdimen\zeropoint \zeropoint = 0pt
+\newdimen\onepoint \onepoint = 1pt
+\newdimen\maxdimen \maxdimen = 16383.99999pt
+\newdimen\onebasepoint \onebasepoint = 1bp
+\chardef \scaledpoint = 1
+\newdimen\thousandpoint\thousandpoint= 1000pt
+
+\let\points\onepoint
+
+\newtoks \emptytoks
+
+%D And even more:
+
+%newcount \minusone \minusone = -1
+\newcount \minustwo \minustwo = -2
+%chardef \zerocount = 0
+%chardef \plusone = 1
+\chardef \plustwo = 2
+\chardef \plusthree = 3
+\chardef \plusfour = 4
+\chardef \plusfive = 5
+\chardef \plussix = 6
+\chardef \plusseven = 7
+\chardef \pluseight = 8
+\chardef \plusnine = 9
+\chardef \plusten = 10
+\chardef \plussixteen = 16
+\chardef \plushundred = 100
+\chardef \pluscxxvii = 127
+\chardef \pluscxxviii = 128
+\chardef \pluscclv = 255
+
+\ifnum\texengine=\luatexengine
+ \chardef \pluscclvi = 256
+ \chardef \plusthousand = 1000
+ \chardef \plustenthousand = 10000
+ \chardef \plustwentythousand = 20000
+ \chardef \medcard = 32768
+ \chardef \maxcard = 65536 % pdftex has less mathchars
+\else
+ \mathchardef\pluscclvi = 256
+ \mathchardef\plusthousand = 1000
+ \mathchardef\plustenthousand = 10000
+ \mathchardef\plustwentythousand = 20000
+ \newcount \medcard \medcard = 32768 % pdftex has less mathchars
+ \newcount \maxcard \maxcard = 65536 % pdftex has less mathchars
+\fi
+
+%D We prefer the more readable variant than in plain
+%D \TEX. User should only use \type {\emptybox}:
+
+\newbox\voidbox
+
+\def\emptybox {\box \voidbox}
+\def\unvoidbox{\unhbox\voidbox}
+
+\let\leavevmode\unvoidbox % we prefer to use \dontleavehmode
+
+%D Some expected plain variants follow. We don't reuse registers
+%D because we don't want clashes.
+
+\newdimen\p@ \p@ \onepoint
+\newcount\m@ne \m@ne \minusone
+\newdimen\z@ \z@ \zeropoint
+\let \@ne \plusone
+\let \tw@ \plustwo
+\let \thr@@ \plusthree
+\let \sixt@@n \sixteen
+\let \@cclv \pluscclv
+\let \@cclvi \pluscclvi
+\newbox \voidb@x
+\newtoks \toks@
+
+%D We define \type {\newif} a la plain \TEX, but will
+%D redefine it later. As Knuth says:
+%D
+%D \startnarrower
+%D And here's a different sort of allocation: for example,
+%D
+%D \starttyping
+%D \newif\iffoo
+%D \stoptyping
+%D
+%D creates \type {\footrue}, \type {\foofalse} to go
+%D with \type {\iffoo}.
+%D \stopnarrower
+
+\def\newif#1%
+ {\count@\escapechar
+ \escapechar\minusone
+ \expandafter\expandafter\expandafter\def\@if #1{true}{\let#1\iftrue }%
+ \expandafter\expandafter\expandafter\def\@if#1{false}{\let#1\iffalse}%
+ \@if#1{false}% the condition starts out false
+ \escapechar\count@}
+
+\def\@if#1#2%
+ {\csname\expandafter\if@\string#1#2\endcsname}
+
+\bgroup % `if' is required
+
+ \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}
+
+\egroup
+
+%D Let's test this one:
+
+\newif\ifdone
+
+%D \macros
+%D {@@escape,@@begingroup,@@endgroup,@@mathshift,@@alignment,
+%D @@endofline,@@parameter,@@superscript,@@subscript,
+%D @@ignore,@@space,@@letter,@@other,@@active,@@comment}
+%D
+%D In \CONTEXT\ we sometimes manipulate the \CATCODES\ of certain
+%D characters. Because we are not that good at remembering numbers,
+%D we introduce some symbolic names.
+
+\chardef\@@escape = 0
+\chardef\@@begingroup = 1
+\chardef\@@endgroup = 2
+\chardef\@@mathshift = 3
+\chardef\@@alignment = 4
+\chardef\@@endofline = 5
+\chardef\@@parameter = 6
+\chardef\@@superscript = 7
+\chardef\@@subscript = 8
+\chardef\@@ignore = 9
+\chardef\@@space = 10
+\chardef\@@letter = 11
+\chardef\@@other = 12 \chardef\other = 12
+\chardef\@@active = 13 \chardef\active = 13
+\chardef\@@comment = 14
+
+%D Constants to be used with \type {\grouptype}.
+
+\chardef\@@bottomlevelgroup = 0
+\chardef\@@simplegroup = 1
+\chardef\@@hboxgroup = 2
+\chardef\@@adjustedhboxgroup = 3
+\chardef\@@vboxgroup = 4
+\chardef\@@vtopgroup = 5
+\chardef\@@aligngroup = 6
+\chardef\@@noaligngroup = 7
+\chardef\@@outputgroup = 8
+\chardef\@@mathgroup = 9
+\chardef\@@discretionarygroup = 10
+\chardef\@@insertgroup = 11
+\chardef\@@vcentergroup = 12
+\chardef\@@mathchoicegroup = 13
+\chardef\@@semisimplegroup = 14
+\chardef\@@mathshiftgroup = 15
+\chardef\@@mathleftgroup = 16
+
+\chardef\@@vadjustgroup = \@@insertgroup
+
+%D Constants to be used with \type {\interactionmode}.
+
+\chardef\@@batchmode = 0
+\chardef\@@nonstopmode = 1
+\chardef\@@scrollmode = 2
+\chardef\@@errorstopmode = 3
+
+%D Constants to be used with \type {\lastnodetype}.
+
+\chardef\@@charnode = 0
+\chardef\@@hlistnode = 1
+\chardef\@@vlistnode = 2
+\chardef\@@rulenode = 3
+\chardef\@@insertnode = 4
+\chardef\@@marknode = 5
+\chardef\@@adjustnode = 6
+\chardef\@@ligaturenode = 7
+\chardef\@@discretionarynode = 8
+\chardef\@@whatsitnode = 9
+\chardef\@@mathnode = 10
+\chardef\@@gluenode = 11
+\chardef\@@kernnode = 12
+\chardef\@@penaltynode = 13
+\chardef\@@unsetnode = 14
+\chardef\@@mathsnode = 15
+
+%D Constants to be used with \type {\currentiftype}.
+
+\chardef\@@charif = 1
+\chardef\@@catif = 2
+\chardef\@@numif = 3
+\chardef\@@dimif = 4
+\chardef\@@oddif = 5
+\chardef\@@vmodeif = 6
+\chardef\@@hmodeif = 7
+\chardef\@@mmodeif = 8
+\chardef\@@innerif = 9
+\chardef\@@voidif = 10
+\chardef\@@hboxif = 11
+\chardef\@@vboxif = 12
+\chardef\@@xif = 13
+\chardef\@@eofif = 14
+\chardef\@@trueif = 15
+\chardef\@@falseif = 16
+\chardef\@@caseif = 17
+\chardef\@@definedif = 18
+\chardef\@@csnameif = 19
+\chardef\@@fontcharif = 20
+
+%D Of course we want even bigger log files, so we copied this
+%D from the \ETEX\ source files.
+%D
+%D When watching such logs, beware of nasty side effects of
+%D \type {\scantokens}, as in:
+%D
+%D \starttyping
+%D \bgroup
+%D \lccode`a=12\lowercase{\xdef\whatever{a}}\egroup
+%D \def\whatever{test \whatever test}
+%D \scantokens\expandafter{\whatever}
+%D \egroup
+%D \stoptyping
+%D
+%D In \LUATEX\ we have ways around this.
+
+\def\tracingall
+ {\tracingonline \plusone
+ \tracingcommands \plusthree
+ \tracingstats \plustwo
+ \tracingpages \plusone
+ \tracingoutput \plusone
+ \tracinglostchars \plustwo
+ \tracingmacros \plustwo
+ \tracingparagraphs\plusone
+ \tracingrestores \plusone
+ \showboxbreadth \maxdimen
+ \showboxdepth \maxdimen
+ \tracinggroups \plusone
+ \tracingifs \plusone
+ \tracingscantokens\plusone
+ \tracingnesting \plusone
+ \tracingassigns \plustwo
+ \errorstopmode}
+
+\def\loggingall
+ {\tracingall
+ \tracingonline \zerocount}
+
+\def\tracingnone
+ {\tracingassigns \zerocount
+ \tracingnesting \zerocount
+ \tracingscantokens\zerocount
+ \tracingifs \zerocount
+ \tracinggroups \zerocount
+ \showboxdepth \plusthree
+ \showboxbreadth \plusfive
+ \tracingrestores \zerocount
+ \tracingparagraphs\zerocount
+ \tracingmacros \zerocount
+ \tracinglostchars \plusone
+ \tracingoutput \zerocount
+ \tracingpages \zerocount
+ \tracingstats \zerocount
+ \tracingcommands \zerocount
+ \tracingonline \zerocount}
+
+%D Just for tracing purposes we set:
+
+\tracingstats\plusone
+
+%D Here we also save \input, more will be saved later.
+
+\ifdefined\normalinput \else \let\normalinput\input \fi
+
+%D We don't like outer commands, and we always want access
+%D to the original \type {\input} primitive.
+
+\let\normalouter\outer \def\outer{} % no longer \relax
+
+%D To circumvent dependencies, we can postpone certain
+%D initializations to dumping time, by appending them to the
+%D \type {\everydump} token register.
+
+\ifdefined\normaldump \else \let\normaldump\dump \fi
+
+\newtoks\everydump
+
+\def\dump{\the\everydump\normaldump}
+
+%D The same applies for the startup actions.
+
+\ifdefined\normaleveryjob \else \let\normaleveryjob\everyjob \fi
+
+\let\everyjob\relax \newtoks\everyjob
+
+\normaleveryjob{\the\everyjob}
+
+\def\appendtotoks #1{\def\temp{#1}\afterassignment\doappendtotoks \scratchtoks=}
+\def\prependtotoks#1{\def\temp{#1}\afterassignment\doprependtotoks\scratchtoks=}
+
+\def\doappendtotoks {\expandafter\expandafter\expandafter{\expandafter\the\expandafter\temp\the\scratchtoks}}
+\def\doprependtotoks{\expandafter\expandafter\expandafter{\expandafter\the\expandafter\scratchtoks\the\temp}}
+
+%D \macros
+%D {begcsname}
+%D
+%D Handy for \ETEX-only usage (avoids making \type {\relax}'s:
+
+\def\begcsname#1\endcsname{\ifcsname#1\endcsname\csname#1\endcsname\fi}
+
+%D Now come a few macros that might be needed in successive loading:
+
+\let\endgraf\par
+\let\endline\cr
+
+\def\space{ }
+\def\empty{}
+\def\null {\hbox{}}
+
+%D The following two might be overloaded later on but some modules need
+%D then earlier. These functionality is reflected in the name and will not
+%D change.
+
+\bgroup
+ \catcode`\^^M=\active%
+ \gdef\obeylines{\catcode`\^^M\active \let^^M\par}%
+ \global\let^^M\par%
+\egroup
+
+\bgroup
+ \gdef\obeyspaces{\catcode`\ \active}%
+ \obeyspaces\global\let =\space%
+\egroup
+
+%D Also needed might be a simple loop structure and we borrow
+%D plain \TEX's one as it is often expected to be present and
+%D it is about the fastest you can get. Beware: this macro
+%D does not support nested loops. We use a namespace prefix
+%D \type {@@pln}.
+
+\long\def\loop#1\repeat{\long\def\@@plnbody{#1}\@@plniterate}
+
+%D The following makes \type {\loop} \unknown\ \type {\if}
+%D \unknown\ \type {\repeat} skippable (clever trick):
+
+\let\repeat\fi % so both \loop and \repeat are reserved words!
+
+%D The original (no \type {@@pln} there):
+%D
+%D \starttyping
+%D \def\@@plniterate{\@@plnbody\let\next\@@plniterate\else\let\next\relax\fi\next}
+%D \stoptyping
+%D
+%D A more efficient alternative:
+%D
+%D \starttyping
+%D \def\@@plniterate{\@@plnbody\expandafter\@@plniterate\else\expandafter\relax\fi}
+%D \stoptyping
+%D
+%D An even more efficient one:
+
+\def\@@plniterate{\@@plnbody\expandafter\@@plniterate\else\fi}
+
+%D We don't define a real output routine yet but at least get rid
+%D of pages:
+
+\output{\shipout\box\normalpagebox}
+
+%D Although we don't add pagenumbers yet we alias the default
+%D register used for counting pages:
+
+\countdef\pageno=0 \pageno=1 % first page is number 1
+
+%D Beside the raw counter \type {\pageno} the \type {\folio}
+%D macro provides the value.
+
+\def\folio{\the\pageno} % kind of expected and therefore reserved
+
+%D The following registers are kind of standard and (for the moment)
+%D we define them here. This might change.
+
+\newskip \bigskipamount \bigskipamount = 12pt plus 4pt minus 4pt
+\newskip \medskipamount \medskipamount = 6pt plus 2pt minus 2pt
+\newskip \smallskipamount \smallskipamount = 3pt plus 1pt minus 1pt
+
+\baselineskip = 12pt
+\lineskip = 1pt
+\lineskiplimit = 0pt
+
+%D Again a few kind-of-extensions the core:
+
+\newskip \hideskip \hideskip = -1000pt plus 1fill
+\newskip \centering \centering = 0pt plus 1000pt minus 1000pt
+
+\def\hidewidth % for alignment entries that can stick out
+ {\hskip\hideskip}
+
+\def\ialign % initialized \halign
+ {\everycr{}%
+ \tabskip\zeroskip
+ \halign}
+
+\newcount \mscount
+
+\def\spanomit{\span\omit} % bypass error message
+
+\def\multispan#1%
+ {\omit
+ \mscount#1\relax
+ \loop
+ \ifnum\mscount>\plusone
+ \spanomit \advance\mscount\minusone
+ \repeat}
+
+%D The next section deals with selective definitions in
+%D later modules. One can of course use the \type {\texengine}
+%D number that we defined earlier instead.
+
+\bgroup \obeylines
+ \gdef\pickupSOMETEX#1%
+ {\expandafter\gdef\csname begin#1\endcsname{\bgroup\obeylines\dopickupSOMETEX{#1}}}
+ \gdef\dopickupSOMETEX#1#2
+ % {\egroup\immediate\write16{special code for #1 -> [line \the\inputlineno] \detokenize{#2}}}
+ {\egroup}
+\egroup
+
+\let\endTEX \relax \long\def\beginTEX #1\endTEX {}
+\let\endETEX \relax \long\def\beginETEX #1\endETEX {}
+\let\endXETEX \relax \long\def\beginXETEX #1\endXETEX {}
+\let\endLUATEX\relax \long\def\beginLUATEX#1\endLUATEX{}
+\let\endOLDTEX\relax \long\def\beginOLDTEX#1\endOLDTEX{}
+\let\endNEWTEX\relax \long\def\beginNEWTEX#1\endNEWTEX{}
+
+\pickupSOMETEX{ETEX}
+
+\ifnum\texengine=\xetexengine
+ \pickupSOMETEX{XETEX}
+\fi
+\ifnum\texengine=\luatexengine
+ \pickupSOMETEX{LUATEX}
+\fi
+\ifnum\texengine<\xetexengine
+ \pickupSOMETEX{OLDTEX}
+\else
+ \pickupSOMETEX{NEWTEX}
+\fi
+
+%D \macros
+%D {bindprimitive}
+%D
+%D We can remap primitives (which is needed because of changes in
+%D for instance \PDFTEX).
+
+\def\bindprimitive#1 #2 % new old
+ {\ifcsname#1\endcsname \else \ifcsname#2\endcsname
+ \expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname
+ \fi \fi}
+
+%D Because \XETEX\ also implements some \PDFTEX\ functionality, we take
+%D care of this here instead of a dedicated module. Later modules need
+%D to handle the undefined cases.
+
+%D These messy checks will disappear.
+
+% new after 1.10, watch the change in prefix
+
+\bindprimitive quitvmode ptexquitvmode
+\bindprimitive noligatures ptexnoligatures
+\bindprimitive setrandomseed ptexsetrandomseed
+\bindprimitive uniformdeviate ptexuniformdeviate
+
+\bindprimitive quitvmode pdfquitvmode
+\bindprimitive noligatures pdfnoligatures
+\bindprimitive setrandomseed pdfsetrandomseed
+\bindprimitive uniformdeviate pdfuniformdeviate
+
+\bindprimitive resettimer pdfresettimer
+\bindprimitive elapsedtime pdfelapsedtime
+
+% new per 1.40
+
+\bindprimitive ifprimitive ifpdfprimitive
+\bindprimitive primitive pdfprimitive
+\bindprimitive ifabsdim ifpdfabsdim
+\bindprimitive ifabsnum ifpdfabsnum
+
+\ifnum\texengine=\xetexengine \else % this test might disappear some day
+
+ \pdfminorversion \plusfive
+
+ \ifdefined\pdfcompresslevel \else \newcount\pdfcompresslevel \fi
+ \ifdefined\pdfobjcompresslevel \else \newcount\pdfobjcompresslevel \fi
+ \ifdefined\pdfgentounicode \else \newcount\pdfgentounicode \fi \pdfgentounicode\plusone
+
+ \def\nopdfcompression {\pdfobjcompresslevel\zerocount \pdfcompresslevel\zerocount}
+ \def\maximumpdfcompression{\pdfobjcompresslevel\plusone \pdfcompresslevel\plusnine }
+ \def\normalpdfcompression {\pdfobjcompresslevel\plusone \pdfcompresslevel\plusthree}
+
+ \normalpdfcompression
+
+ \let\normalsetrandomseed \setrandomseed
+ \let\normaluniformdeviate\uniformdeviate
+
+\fi
+
+%D Handy.
+
+\ifnum\texengine=\luatexengine
+ \ifdefined\suppresslongerror % for the moment test
+ \suppresslongerror\plusone
+ \fi
+\fi
+
+%D Basic status stuff.
+
+\newif\ifproductionrun
+
+%D We need to make sure that we start up in \DVI\ mode, so,
+%D after testing for running \PDFTEX, we default to \DVI.
+
+\ifx\pdftexversion\undefined \newcount\pdfoutput \fi \pdfoutput=0
+
+%D For those who expect this \unknown
+
+\ifx\fmtname \undefined \def\fmtname {ConTeXt Minimized Plain TeX} \fi
+\ifx\fmtversion\undefined \def\fmtversion{3.1415926} \fi
+
+\let\normalfmtversion\fmtversion
+
+%D A few bonus macros:
+
+\def\modulonumber#1#2{\the\numexpr#2-((((#2+(#1/2))/#1)-1)*#1)\relax}
+\def\dividonumber#1#2{\the\numexpr(#2-(#1/2))/#1\relax}
+
+\ifnum\texengine=\xetexengine
+ \edef\xetexversion {\numexpr\XeTeXversion*100+(\expandafter\gobbleoneargument\XeTeXrevision-5)/10\relax}
+ \edef\xetexrevision {\the\numexpr(\expandafter\gobbleoneargument\XeTeXrevision-50)/100\relax}
+\fi
+
+\ifcase\texengine
+ \def\texenginename {impossible}
+ \edef\texengineversion{0}
+\or
+ \def\texenginename {pdfTeX}
+ \edef\texengineversion{\dividonumber{100}\pdftexversion.\modulonumber{100}\pdftexversion.\pdftexrevision}
+\or
+ \def\texenginename {XeTeX}
+ \edef\texengineversion{\dividonumber{100}\xetexversion .\modulonumber{100}\xetexversion .\xetexrevision}
+\or
+ \def\texenginename {LuaTeX}
+ \edef\texengineversion{\dividonumber{100}\luatexversion.\modulonumber{100}\luatexversion.\luatexrevision}
+\else
+ \def\texenginename {impossible}
+ \edef\texengineversion{0}
+\fi
+
+%D While cleaning this code up a bit I was listening to Heather
+%D Nova's \CD\ Redbird. The first song on that \CD\ ends with
+%D a few lines suitable for ending this initialization module:
+%D
+%D \startlines
+%D And there's so much I can do for you
+%D Given time I know that I can prove
+%D Now my world is opened up to you
+%D Come inside
+%D
+%D Welcome to my life
+%D Welcome to my world
+%D Come inside
+%D \stoplines
+%D
+%D So let's see what \TEX\ can do now that we've opened up
+%D the basic machinery.
+
+\protect \endinput
diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua
new file mode 100644
index 000000000..e3d3ce01a
--- /dev/null
+++ b/tex/context/base/syst-lua.lua
@@ -0,0 +1,91 @@
+if not modules then modules = { } end modules ['syst-lua'] = {
+ version = 1.001,
+ comment = "companion to syst-lua.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local texsprint, texprint, texwrite, texiowrite_nl = tex.sprint, tex.print, tex.write, texio.write_nl
+local format = string.format
+
+local ctxcatcodes = tex.ctxcatcodes
+
+commands = commands or { } cs = commands -- shorter
+
+ctx = ctx or { } -- special context namespace, code might move from there
+
+function commands.writestatus(a,b,c,...)
+ if c then
+ texiowrite_nl(format("%-16s: %s\n",a,format(b,c,...)))
+ else
+ texiowrite_nl(format("%-16s: %s\n",a,b)) -- b can have %'s
+ end
+end
+
+function commands.doifelse(b)
+ if b then -- faster with if than with expression
+ texsprint(ctxcatcodes,"\\firstoftwoarguments")
+ else
+ texsprint(ctxcatcodes,"\\secondoftwoarguments")
+ end
+end
+function commands.doif(b)
+ if b then
+ texsprint(ctxcatcodes,"\\firstofoneargument")
+ else
+ texsprint(ctxcatcodes,"\\gobbleoneargument")
+ end
+end
+function commands.doifnot(b)
+ if b then
+ texsprint(ctxcatcodes,"\\gobbleoneargument")
+ else
+ texsprint(ctxcatcodes,"\\firstofoneargument")
+ end
+end
+
+commands.testcase = commands.doifelse
+
+function commands.boolcase(b)
+ if b then texwrite(1) else texwrite(0) end
+end
+
+function commands.doifelsespaces(str)
+ return commands.doifelse(str:find("^ +$"))
+end
+
+local s = lpeg.Ct(lpeg.splitat(","))
+local h = { }
+
+function commands.doifcommonelse(a,b)
+ local ha = h[a]
+ local hb = h[b]
+ if not ha then ha = s:match(a) h[a] = ha end
+ if not hb then hb = s:match(b) h[b] = hb end
+ for i=1,#ha do
+ for j=1,#hb do
+ if ha[i] == hb[j] then
+ return commands.testcase(true)
+ end
+ end
+ end
+ return commands.testcase(false)
+end
+
+function commands.doifinsetelse(a,b)
+ local hb = h[b]
+ if not hb then hb = s:match(b) h[b] = hb end
+ for i=1,#hb do
+ if a == hb[i] then
+ return commands.testcase(true)
+ end
+ end
+ return commands.testcase(false)
+end
+
+function commands. def (cs,value) texsprint(ctxcatcodes,format( "\\def\\%s{%s}",cs,value)) end
+function commands.edef (cs,value) texsprint(ctxcatcodes,format("\\edef\\%s{%s}",cs,value)) end
+function commands.gdef (cs,value) texsprint(ctxcatcodes,format("\\gdef\\%s{%s}",cs,value)) end
+function commands.xdef (cs,value) texsprint(ctxcatcodes,format("\\xdef\\%s{%s}",cs,value)) end
+function commands.chardef(cs,value) texsprint(ctxcatcodes,format("\\chardef\\%s=%s\\relax",cs,value)) end
diff --git a/tex/context/base/syst-lua.tex b/tex/context/base/syst-lua.tex
new file mode 100644
index 000000000..40cd9f756
--- /dev/null
+++ b/tex/context/base/syst-lua.tex
@@ -0,0 +1,37 @@
+%D \module
+%D [ file=syst-lua,
+%D version=2008.01.25,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=Helper macros based on \LUA,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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{syst-lua}{1.001}
+
+\unprotect
+
+\def\expdoifelse#1#2{\ctxlua{commands.doifelse(\!!bs#1\!!es==\!!bs#2\!!es)}}
+\def\expdoif #1#2{\ctxlua{commands.doif (\!!bs#1\!!es==\!!bs#2\!!es)}}
+\def\expdoifnot #1#2{\ctxlua{commands.doifnot (\!!bs#1\!!es==\!!bs#2\!!es)}}
+
+% \testfeatureonce{100000}{\doifelse{hello world}{here i am}{}} % 0.3
+% \testfeatureonce{100000}{\expandabledoifelse{hello world}{here i am}{}} % 1.5
+
+\def\expdoifcommonelse#1#2{\ctxlua{commands.doifcommonelse("#1","#2")}}
+\def\expdoifinsetelse #1#2{\ctxlua{commands.doifinsetelse("#1","#2")}}
+
+% we define these here, just in case ...
+
+\def\luastringsep{===} % this permits \typefile{self} otherwise nested b/e sep problems
+
+\edef\!!bs{[\luastringsep[}
+\edef\!!es{]\luastringsep]}
+
+\def\writestatus#1#2{\ctxlua{commands.writestatus(\!!bs#1\!!es,\!!bs#2\!!es)}}
+
+\protect \endinput
diff --git a/tex/context/base/syst-mtx.tex b/tex/context/base/syst-mtx.tex
deleted file mode 100644
index e2a978671..000000000
--- a/tex/context/base/syst-mtx.tex
+++ /dev/null
@@ -1,80 +0,0 @@
-%D \module
-%D [ file=syst-mtx,
-%D version=2006.08.11,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=\METATEX\ specifics,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\directlua\undefined \endinput \fi
-
-\unprotect
-
-\ifnum\contextmarkmode=2
-
- \input enco-utf.tex
-
- % patch needed for turkish
-
- \setcclcuc 201C 201C 201C
- \setcclcuc 201D 201D 201D
-
-\fi
-
-
-%D Since the number of chars exceed 256 now, we can use \type
-%D {\chardef} instead of the more limited \type {\mathchardef}.
-
-\def\newcount {\myalloc@0\count \countdef \@@maxallocation}
-\def\newdimen {\myalloc@1\dimen \dimendef \@@maxallocation}
-\def\newskip {\myalloc@2\skip \skipdef \@@maxallocation}
-\def\newmuskip {\myalloc@3\muskip \muskipdef \@@maxallocation}
-\def\newbox {\myalloc@4\box \chardef \@@maxallocation}
-\def\newtoks {\myalloc@5\toks \toksdef \@@maxallocation}
-\def\newread {\myalloc@6\read \chardef \@@minallocation}
-\def\newwrite {\myalloc@7\write \chardef \@@minallocation}
-\def\newmarks {\myalloc@8\marks \chardef \@@maxallocation}
-\def\newlanguage{\myalloc@9\language\chardef \@@minallocation}
-
-\def\newfam#1{\chardef#1=15 }
-
-\def\topofboxstack{\number\count24 }
-
-\count18=1
-
-\mathchardef\@@minallocation = 16
-\mathchardef\@@medallocation = 256
-\mathchardef\@@maxallocation = 32767
-\chardef \@@insallocation = 128 % was 32, but if we want continuous ranges (mplib) we need to pass 256 soon 32
-
-\def\myalloc@#1#2#3#4#5%
- {\global\advance\count1#1by\@ne
- \ifnum\count1#1>\@@medallocation \else
- \ifnum\count1#1<\numexpr\@@medallocation-\@@insallocation\relax\else
- \global\count1#1=\numexpr\@@medallocation+\@ne\relax % \wait
- \fi
- \fi
- \ifnum\count1#1>#4%
- \global\count1#1=#4%
- \errmessage{No room for (\string#2) \string#5}%
- \fi
- \allocationnumber=\count1#1%
- \global#3#5=\allocationnumber
- \wlog{\string#5=\string#2\the\allocationnumber}}
-
-\def\newinsert#1%
- {\ifnum\insc@unt>\numexpr\@@medallocation-\@@insallocation\relax
- \global\advance\insc@unt by\m@ne
- \allocationnumber=\insc@unt
- \global\chardef#1=\allocationnumber
- \wlog{\string#1=\string\insert\the\allocationnumber}%
- \else
- \errmessage{No room for a new insert \string#1 (\number\insc@unt)}%
- \fi}
-
-\protect \endinput
diff --git a/tex/context/base/syst-new.tex b/tex/context/base/syst-new.tex
index 92d1ea192..53ba18ffd 100644
--- a/tex/context/base/syst-new.tex
+++ b/tex/context/base/syst-new.tex
@@ -814,25 +814,6 @@
\def\ignoreimplicitspaces
{\doifnextcharelse\relax\relax\relax}
-%D \macros
-%D {newconstant}
-
-\beginETEX
-
-\def\newconstant#1%
- {\def\donewconstant{\xdef#1{\numexpr\the\scratchcounter\relax}}%
- \afterassignment\donewconstant\scratchcounter}
-
-\endETEX
-
-\beginTEX
-
-\def\newconstant#1%
- {\def\donewconstant{\xdef#1{\the\scratchcounter\space}}
- \afterassignment\donewconstant\scratchcounter}
-
-\endTEX
-
% new
%
% \startnointerference
@@ -847,7 +828,7 @@
\def\stopnointerference
{\egroup
- \setbox\nointerferencebox\box\voidb@x}
+ \setbox\nointerferencebox\emptybox}
\protect \endinput
diff --git a/tex/context/base/syst-omg.tex b/tex/context/base/syst-omg.tex
deleted file mode 100644
index 01f140dac..000000000
--- a/tex/context/base/syst-omg.tex
+++ /dev/null
@@ -1,79 +0,0 @@
-%D \module
-%D [ file=syst-omg,
-%D version=2000.09.09,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=A couple of Omega goodies,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 become obsolete as soon as Omega
-%D supports \ETEX\ functionality.
-
-\ifx\OmegaVersion\undefined \endinput \fi
-
-\unprotect
-
-\def\newcount {\myalloc@0\count \countdef \@@maxallocation}
-\def\newdimen {\myalloc@1\dimen \dimendef \@@maxallocation}
-\def\newskip {\myalloc@2\skip \skipdef \@@maxallocation}
-\def\newmuskip {\myalloc@3\muskip \muskipdef \@@maxallocation}
-\def\newbox {\myalloc@4\box \mathchardef\@@maxallocation}
-\def\newtoks {\myalloc@5\toks \toksdef \@@maxallocation}
-\def\newread {\myalloc@6\read \chardef \@@minallocation}
-\def\newwrite {\myalloc@7\write \chardef \@@minallocation}
-\def\newmarks {\myalloc@8\marks \mathchardef\@@maxallocation}
-\def\newlanguage{\myalloc@9\language\chardef \@@minallocation}
-
-\def\newfam#1{\chardef#1=15 }
-
-\def\topofboxstack{\number\count24 }
-
-\count18=1
-
-\mathchardef\@@minallocation = 16
-\mathchardef\@@medallocation = 256
-\mathchardef\@@maxallocation = 32767
-\chardef \@@insallocation = 32
-
-\def\myalloc@#1#2#3#4#5%
- {\global\advance\count1#1by\@ne
- \ifnum\count1#1>\@@medallocation \else
- \ifnum\count1#1<\numexpr\@@medallocation-\@@insallocation\relax\else
- \global\count1#1=\numexpr\@@medallocation+\@ne\relax % \wait
- \fi
- \fi
- \ifnum\count1#1>#4%
- \global\count1#1=#4%
- \errmessage{No room for (\string#2) \string#5}%
- \fi
- \allocationnumber=\count1#1%
- \global#3#5=\allocationnumber
- \wlog{\string#5=\string#2\the\allocationnumber}}
-
-\def\newinsert#1%
- {\ifnum\insc@unt>\numexpr\@@medallocation-\@@insallocation\relax
- \global\advance\insc@unt by\m@ne
- \allocationnumber=\insc@unt
- \global\chardef#1=\allocationnumber
- \wlog{\string#1=\string\insert\the\allocationnumber}%
- \else
- \errmessage{No room for a new insert \string#1 (\number\insc@unt)}%
- \fi}
-
-%D We need to catch a (rather crappy) automatic OMEGA
-%D mechanism. Unfortunately loading of the SGML vectors
-%D happens automatically without control over the regime
-%D under which it takes place.
-
-\ifx\SGMLFontEntity\undefined \else
-
- \errmessage{This version of Omega is way to buggy (+ \string\SGMLFontEntity\space mess)!}
-
-\fi
-
-\protect \endinput
diff --git a/tex/context/base/syst-pdt.tex b/tex/context/base/syst-pdt.tex
deleted file mode 100644
index e241a9a2b..000000000
--- a/tex/context/base/syst-pdt.tex
+++ /dev/null
@@ -1,50 +0,0 @@
-%D \module
-%D [ file=syst-pdt,
-%D version=2006.08.11,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=\PDFTEX\ specifics,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\pdftexversion\undefined \endinput \fi
-
-\unprotect
-
-% new after 1.10, watch the change in prefix
-
-\bindprimitive quitvmode ptexquitvmode
-\bindprimitive noligatures ptexnoligatures
-\bindprimitive setrandomseed ptexsetrandomseed
-\bindprimitive uniformdeviate ptexuniformdeviate
-
-\bindprimitive quitvmode pdfquitvmode
-\bindprimitive noligatures pdfnoligatures
-\bindprimitive setrandomseed pdfsetrandomseed
-\bindprimitive uniformdeviate pdfuniformdeviate
-
-\bindprimitive resettimer pdfresettimer
-\bindprimitive elapsedtime pdfelapsedtime
-
-% new per 1.40
-
-\bindprimitive ifprimitive ifpdfprimitive
-\bindprimitive primitive pdfprimitive
-\bindprimitive ifabsdim ifpdfabsdim
-\bindprimitive ifabsnum ifpdfabsnum
-
-\def\nopdfcompression {\pdfobjcompresslevel 0 \pdfcompresslevel 0 }
-\def\maximumpdfcompression{\pdfobjcompresslevel 1 \pdfcompresslevel 9 }
-\def\normalpdfcompression {\pdfobjcompresslevel 1 \pdfcompresslevel 3 }
-
-\ifx\pdfobjcompresslevel\undefined \newcount\pdfobjcompresslevel \fi \normalpdfcompression
-\ifx\pdfgentounicode \undefined \newcount\pdfgentounicode \fi \pdfgentounicode=1
-
-\let\normalquitvmode \quitvmode
-\let\normalnoligatures\noligatures
-
-\protect
diff --git a/tex/context/base/syst-pln.tex b/tex/context/base/syst-pln.tex
index 9582c6508..f2b6129ff 100644
--- a/tex/context/base/syst-pln.tex
+++ b/tex/context/base/syst-pln.tex
@@ -11,259 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D We used to load plain \TEX\ in a special way, but redefining
-%D a couple of primitives so that for instance font loading was
-%D ignored. For those interested, this loader is found in
-%D \type {syst-tex.tex}.
-
-%D This is a stripped down version of plain \TEX. We need this
-%D module to get started. Whole sections are missing here,
-%D like font loading and math. Thise are taken care of in
-%D dedicated modules. A few definitions are added (and
-%D marked as such).
-
-%D Characters can have special states, that can be triggered
-%D by setting their category coded. Some are preset, others
-%D are to be set as soon as possible, otherwise we cannot
-%D define any useful macros.
-
-%catcode`\^^@ = 9 % ascii null is ignored
-%catcode`\\ = 0 % backslash is TeX escape character
-
-\catcode`\{ = 1 % left brace is begin-group character
-\catcode`\} = 2 % right brace is end-group character
-\catcode`\$ = 3 % dollar sign is math shift
-\catcode`\& = 4 % ampersand is alignment tab
-\catcode`\# = 6 % hash mark is macro parameter character
-\catcode`\^ = 7 % circumflex and uparrow are for superscripts
-\catcode`\_ = 8 % underline and downarrow are for subscripts
-\catcode`\^^I = 10 % ascii tab is a blank space
-
-%catcode`\^^M = 5 % ascii return is end-line
-%catcode`\% = 14 % percent sign is comment character
-%catcode`\ = 10 % ascii space is blank space
-%catcode`\^^? = 15 % ascii delete is invalid
-
-\catcode`\~ = 13 % tilde is active
-\catcode`\^^L = 13 % ascii form-feed
-
-%catcode`\A = 11
-%.......
-%catcode`\Z = 11
-
-%catcode`\a = 11
-%.......
-%catcode`\z = 11
-
-\chardef\active = 13
-
-\def ^^L{\par}
-\def\^^M{\ } % control <return> = control <space>
-\def\^^I{\ } % same for <tab>
-
-%D In \CONTEXT, we simply ignore end||of||file tokens:
-
-\catcode`\^^Z=9
-
-%D First we define a simplified version of the \CONTEXT\
-%D protection mechanism.
-
-\def\unprotect{\catcode`@=11 }
-\def\protect {\catcode`@=12 }
-
\unprotect
-%D We do not set up mathcodes here, but postpone that to the
-%D math modules.
-
-\mathcode`\ = "8000 % \space
-\mathcode`\' = "8000 % ^\prime
-\mathcode`\_ = "8000 % \_
-\mathcode`\^^? = "1273 % \smallint
-
-\sfcode`\)=0
-\sfcode`\'=0
-\sfcode`\]=0
-
-\chardef\@ne = 1
-\chardef\tw@ = 2
-\chardef\thr@@ = 3
-\chardef\sixt@@n = 16
-\chardef\@cclv = 255
-
-\mathchardef\@cclvi = 256
-\mathchardef\@m = 1000
-\mathchardef\@M = 10000
-\mathchardef\@MM = 20000
-
-%D Pretty important definitions:
-
-\let\bgroup={
-\let\egroup=}
-
-%D In plain \TEX\ the following explanation about the register
-%D allocation mechanism is given:
-%D
-%D \startnarrower
-%D The following counters are reserved:
-%D
-%D \starttabulate
-%D \NC 0--9 \NC page numbering \NC \NR
-%D \NC 10 \NC count allocation \NC \NR
-%D \NC 11 \NC dimen allocation \NC \NR
-%D \NC 12 \NC skip allocation \NC \NR
-%D \NC 13 \NC muskip allocation \NC \NR
-%D \NC 14 \NC box allocation \NC \NR
-%D \NC 15 \NC toks allocation \NC \NR
-%D \NC 16 \NC read file allocation \NC \NR
-%D \NC 17 \NC write file allocation \NC \NR
-%D \NC 18 \NC math family allocation \NC \NR
-%D \NC 19 \NC language allocation \NC \NR
-%D \NC 20 \NC insert allocation \NC \NR
-%D \NC 21 \NC the most recently allocated number \NC \NR
-%D \NC 22 \NC constant $-1$ \NC \NR
-%D \stoptabulate
-%D
-%D New counters are allocated starting with 23, 24, etc. Other
-%D registers are allocated starting with 10. This leaves 0
-%D through 9 for the user to play with safely, except that
-%D counts 0 to 9 are considered to be the page and subpage
-%D numbers (since they are displayed during output). In this
-%D scheme, \type {\count10} always contains the number of the
-%D highest||numbered counter that has been allocated, \type
-%D {\count14} the highest||numbered box, etc. Inserts are given
-%D numbers 254, 253, etc., since they require a \type
-%D {\count}, \type {\dimen}, \type {\skip}, and \type {\box}
-%D all with the same number; \type {\count20} contains the
-%D lowest-numbered insert that has been allocated. Of course,
-%D \type {\box255} is reserved for \type {\output}; \type
-%D {\count255}, \type {\dimen255}, and \type {\skip255} can be
-%D used freely.
-%D
-%D It is recommended that macro designers always use \type
-%D {\globa}l assignments with respect to registers numbered 1,
-%D 3, 5, 7, 9, and always non||\type {\global} assignments
-%D with respect to registers 0, 2, 4, 6, 8, 255. This will
-%D prevent \quote {save stack buildup} that might otherwise
-%D occur.
-%D \stopnarrower
-%D
-%D We will overload some macros in \ETEX\ mode.
-
-\count10 = 22 % allocates \count registers 23, 24, ...
-\count11 = 9 % allocates \dimen registers 10, 11, ...
-\count12 = 9 % allocates \skip registers 10, 11, ...
-\count13 = 9 % allocates \muskip registers 10, 11, ...
-\count14 = 9 % allocates \box registers 10, 11, ...
-\count15 = 9 % allocates \toks registers 10, 11, ...
-\count16 = -1 % allocates input streams 0, 1, ...
-\count17 = -1 % allocates output streams 0, 1, ...
-\count18 = 3 % allocates math families 4, 5, ...
-\count19 = 0 % allocates \language codes 1, 2, ...
-\count20 =255 % allocates insertion classes 254, 253, ...
-
-\countdef\insc@unt = 20 % the insertion counter
-\countdef\allocationnumber= 21 % the most recent allocation
-\countdef\m@ne = 22 % a handy constant
- \m@ne = -1
-
-\def\wlog{\immediate\write\m@ne} % write on log file (only)
-
-%D \startnarrower
-%D Here are abbreviations for the names of scratch registers
-%D that don't need to be allocated.
-%D \stopnarrower
-
-\countdef \count@ = 255
-\dimendef \dimen@ = 0
-\dimendef \dimen@i = 1 % global only
-\dimendef \dimen@ii = 2
-\skipdef \skip@ = 0
-\toksdef \toks@ = 0
-
-%D \startnarrower
-%D Now, we define \type {\newcount}, \type {\newbox}, etc. so
-%D that you can say \newcount\foo and \type {\foo} will be
-%D defined (with \type {\countdef}) to be the next counter. To
-%D find out which counter \type {\foo} is, you can look at
-%D \type {\allocationnumber}. Since there's no \type {\boxdef}
-%D command, \type {\chardef} is used to define a \type
-%D {\newbox}, \type {\newinsert}, \type {\newfam}, and so on.
-%D \stopnarrower
-
-\def\newcount {\alloc@0\count \countdef \insc@unt}
-\def\newdimen {\alloc@1\dimen \dimendef \insc@unt}
-\def\newskip {\alloc@2\skip \skipdef \insc@unt}
-\def\newmuskip {\alloc@3\muskip \muskipdef\@cclvi }
-\def\newbox {\alloc@4\box \chardef \insc@unt}
-\def\newtoks {\alloc@5\toks \toksdef \@cclvi }
-\def\newread {\alloc@6\read \chardef \sixt@@n }
-\def\newwrite {\alloc@7\write \chardef \sixt@@n }
-\def\newfam {\alloc@8\fam \chardef \sixt@@n }
-\def\newlanguage{\alloc@9\language\chardef \@cclvi }
-
-\def\newhelp#1#2{\newtoks#1#1\expandafter{\csname#2\endcsname}}
-
-\def\alloc@#1#2#3#4#5%
- {\global\advance\count1#1by\@ne
- \ch@ck#1#4#2% make sure there's still room
- \allocationnumber=\count1#1%
- \global#3#5=\allocationnumber
- \wlog{\string#5=\string#2\the\allocationnumber}}
-
-\def\newinsert#1%
- {\global\advance\insc@unt by\m@ne
- \ch@ck0\insc@unt\count
- \ch@ck1\insc@unt\dimen
- \ch@ck2\insc@unt\skip
- \ch@ck4\insc@unt\box
- \allocationnumber=\insc@unt
- \global\chardef#1=\allocationnumber
- \wlog{\string#1=\string\insert\the\allocationnumber}}
-
-\def\ch@ck#1#2#3%
- {\ifnum\count1#1<#2\else
- \errmessage{No room for a new #3}
- \fi}
-
-\newdimen\maxdimen \maxdimen = 16383.99999pt
-\newskip \hideskip \hideskip = -1000pt plus 1fill
-\newskip \centering \centering = 0pt plus 1000pt minus 1000pt
-\newdimen\p@ \p@ = 1pt
-\newdimen\z@ \z@ = 0pt
-\newskip \z@skip \z@skip = 0pt plus 0pt minus 0pt
-\newbox \voidb@x % permanently void box register
-
-%D We define \type {\newif} a la plain \TEX, but will
-%D redefine it later. As Knuth says:
-%D
-%D \startnarrower
-%D And here's a different sort of allocation: for example,
-%D
-%D \starttyping
-%D \newif\iffoo
-%D \stoptyping
-%D
-%D creates \type {\footrue}, \type {\foofalse} to go
-%D with \type {\iffoo}.
-%D \stopnarrower
-
-\def\newif#1%
- {\count@\escapechar
- \escapechar\m@ne
- \expandafter\expandafter\expandafter\def\@if #1{true}{\let#1\iftrue }%
- \expandafter\expandafter\expandafter\def\@if#1{false}{\let#1\iffalse}%
- \@if#1{false}% the condition starts out false
- \escapechar\count@}
-
-\def\@if#1#2%
- {\csname\expandafter\if@\string#1#2\endcsname}
-
-\bgroup % `if' is required
-
- \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}
-
-\egroup
+%D This module set a couple of variables to the plain \TEX\
+%D values. Later they might be overloaded.
%D Build||in numeric variables.
@@ -297,7 +48,7 @@
%mag = 1000
%maxdeadcycles = 25
%month = 0
-\newlinechar = -1
+%newlinechar = -1 % commented i.e. no plain value
%outputpenalty = 0
%pausing = 0
%postdisplaypenalty = 0
@@ -323,14 +74,6 @@
\widowpenalty = 150
%year = 0
-%D Extra numeric variables.
-
-\newcount \interdisplaylinepenalty
-\newcount \interfootnotelinepenalty
-
-\interdisplaylinepenalty = 100
-\interfootnotelinepenalty = 100
-
%D Build in dimension variables.
\abovedisplayshortskip = 0pt plus 3pt
@@ -372,251 +115,4 @@
\vsize = 8.9in
%xspaceskip = 0pt
-%D Extra dimension parameters.
-
-\newskip \bigskipamount \bigskipamount = 12pt plus 4pt minus 4pt
-\newskip \medskipamount \medskipamount = 6pt plus 2pt minus 2pt
-\newskip \smallskipamount \smallskipamount = 3pt plus 1pt minus 1pt
-
-\newskip \normalbaselineskip \normalbaselineskip = 12pt
-\newskip \normallineskip \normallineskip = 1pt
-\newdimen \normallineskiplimit \normallineskiplimit = 0pt
-
-\newdimen \jot \jot = 3pt
-
-%D The following shortcuts are rather standard:
-
-\def\lq{`}
-\def\rq{'}
-
-\def\lbrack{[}
-\def\rbrack{]}
-
-\let\endgraf\par
-\let\endline\cr
-
-\def\space{ }
-\def\empty{}
-\def\null {\hbox{}}
-
-%D The next loop construct is about the fastest you can get.
-%D Beware: this macro does not support nested loops. We use
-%D a namespace prefix \type {@@pln}.
-
-\long\def\loop#1\repeat{\long\def\@@plnbody{#1}\@@plniterate}
-
-%D The following makes \type {\loop} \unknown\ \type {\if}
-%D \unknown\ \type {\repeat} skippable (clever trick):
-
-\let\repeat=\fi
-
-%D The original (no \type {@@pln} there):
-%D
-%D \starttyping
-%D \def\@@plniterate{\@@plnbody\let\next\@@plniterate\else\let\next\relax\fi\next}
-%D \stoptyping
-%D
-%D A more efficient alternative:
-%D
-%D \starttyping
-%D \def\@@plniterate{\@@plnbody\expandafter\@@plniterate\else\expandafter\relax\fi}
-%D \stoptyping
-%D
-%D An even more efficient one:
-
-\def\@@plniterate{\@@plnbody\expandafter\@@plniterate\else\fi}
-
-%D Counter 0 is normally used as page counter:
-
-\countdef\pageno=0 \pageno=1 % first page is number 1
-
-%D Beside the raw counter \type {\pageno} the \type {\folio}
-%D macro provides the value.
-
-\def\folio{\the\pageno}
-
-%D Indeed, we don't define a real output routine yet:
-
-\output{\box255}
-
-%D We don't support \type {\magnification} and just consume
-%D the value.
-
-\let\magnification\count@
-
-%D The following macro will be overloaded in \ETEX.
-
-\def\tracingall
- {\tracingonline \@ne
- \tracingcommands \tw@
- \tracingstats \tw@
- \tracingpages \@ne
- \tracingoutput \@ne
- \tracinglostchars \@ne
- \tracingmacros \tw@
- \tracingparagraphs\@ne
- \tracingrestores \@ne
- \showboxbreadth \maxdimen
- \showboxdepth \maxdimen
- \errorstopmode}
-
-%D Some users expect this macro to be present. This one
-%D sends the hyphenated word to the terminal.
-
-\def\showhyphens#1%
- {\setbox0\vbox
- {\parfillskip\z@skip
- \hsize\maxdimen\tenrm
- \pretolerance\m@ne
- \tolerance\m@ne
- \hbadness0
- \showboxdepth0
- \ #1}}
-
-%D The following bunch of macros deals with basic alignment.
-%D We just include them here so that they can be used if
-%D needed. Normally, \CONTEXT\ users will fall back on one of
-%D the three table environments.
-
-\newcount \mscount
-\newif \ifus@
-\newif \if@cr
-\newbox \tabs
-\newbox \tabsyet
-\newbox \tabsdone
-
-\def\hidewidth % for alignment entries that can stick out
- {\hskip\hideskip}
-
-\def\ialign % initialized \halign
- {\everycr{}
- \tabskip\z@skip
- \halign}
-
-\def\multispan#1%
- {\omit
- \mscount#1\relax
- \loop
- \ifnum\mscount>\@ne \sp@n
- \repeat}
-
-\def\sp@n
- {\span
- \omit
- \advance\mscount\m@ne}
-
-% begin of tab code
-
-\def\cleartabs
- {\global\setbox\tabsyet\null
- \setbox\tabs\null}
-
-\def\settabs
- {\setbox\tabs\null
- \futurelet\next\sett@b}
-
-\def\sett@b
- {\ifx\next\+%
- \def\nxt{\afterassignment\s@tt@b\let\nxt}%
- \else
- \let\nxt\s@tcols
- \fi
- \let\next\relax
- \nxt}
-
-\def\s@tt@b
- {\let\nxt\relax
- \us@false\m@ketabbox}
-
-\def\tabalign
- {\us@true\m@ketabbox}
-
-\let\+\tabalign % no outer here
-
-\def\s@tcols#1\columns
- {\count@#1%
- \dimen@\hsize
- \loop
- \ifnum\count@>\z@ \@nother
- \repeat}
-
-\def\@nother
- {\dimen@ii\dimen@
- \divide\dimen@ii\count@
- \setbox\tabs\hbox{\hbox to\dimen@ii{}\unhbox\tabs}%
- \advance\dimen@-\dimen@ii
- \advance\count@\m@ne}
-
-\def\m@ketabbox
- {\begingroup
- \global\setbox\tabsyet\copy\tabs
- \global\setbox\tabsdone\null
- \def\cr
- {\@crtrue\crcr\egroup\egroup
- \ifus@\unvbox\z@\lastbox\fi\endgroup
- \setbox\tabs\hbox{\unhbox\tabsyet\unhbox\tabsdone}}%
- \setbox\z@\vbox\bgroup\@crfalse
- \ialign\bgroup&\t@bbox##\t@bb@x\crcr}
-
-\def\t@bbox
- {\setbox\z@\hbox\bgroup}
-
-\def\t@bb@x
- {\if@cr
- \egroup % now \box\z@ holds the column
- \else
- \hss\egroup
- \global\setbox\tabsyet\hbox
- {\unhbox\tabsyet\global\setbox\@ne\lastbox}% now \box\@ne holds its size
- \ifvoid\@ne
- \global\setbox\@ne\hbox to\wd\z@{}%
- \else
- \setbox\z@\hbox to\wd\@ne{\unhbox\z@}%
- \fi
- \global\setbox\tabsdone\hbox{\box\@ne\unhbox\tabsdone}%
- \fi
- \box\z@}
-
-% end to tab code
-
-%D Useful, used too, but sometimes dangerous:
-
-\def\leavevmode{\unhbox\voidb@x}
-
-%D We will overload these, but may need them beforehand:
-
-\bgroup
- \catcode`\^^M=\active%
- \gdef\obeylines{\catcode`\^^M\active \let^^M\par}%
- \global\let^^M\par%
-\egroup
-
-\def\obeyspaces{\catcode`\ \active}
-
-{\obeyspaces\global\let =\space}
-
-%D Useful and expected:
-
-\def~{\penalty\@M \ } % tie
-
-\chardef\%=`\%
-\chardef\&=`\&
-\chardef\#=`\#
-\chardef\$=`\$
-
-%def\_{\leavevmode \kern.06em \vbox{\hrule width.3em}}
-\def\_{\dontleavehmode \kern.06em \vbox{\hrule width.3em}}
-
-%D Replaced later on:
-
-\def\line {\hbox to\hsize}
-\def\leftline #1{\line{#1\hss}}
-\def\rightline #1{\line{\hss#1}}
-\def\centerline#1{\line{\hss#1\hss}}
-
-%D Let's end in the plain way:
-
-\ifx\fmtname \undefined \def\fmtname {ConTeXt Minimized Plain TeX} \fi
-\ifx\fmtversion\undefined \def\fmtversion{3.1415926} \fi
-
\protect \endinput
diff --git a/tex/context/base/syst-prm.tex b/tex/context/base/syst-prm.tex
deleted file mode 100644
index dc259dff7..000000000
--- a/tex/context/base/syst-prm.tex
+++ /dev/null
@@ -1,227 +0,0 @@
-%D \module
-%D [ file=syst-prm,
-%D version=1999.03.17,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Primitive Behavior,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Saved primitives are preceded by \type {\normal}, as in:
-
-\let\normalfmtversion\fmtversion
-
-%D When applicable, we also load the \ETEX\ source and
-%D definition files.
-
-\bgroup \obeylines
-
-\ifx\eTeXversion\undefined
-
- \long\gdef\beginETEX#1\endETEX%
- {}
-
- \gdef\beginTEX%
- {\bgroup\obeylines\dobeginTEX}
-
- \gdef\dobeginTEX#1
- {\egroup}
-
- \global\let\endTEX\relax
-
-\else
-
- \long\gdef\beginTEX#1\endTEX%
- {}
-
- \gdef\beginETEX%
- {\bgroup\obeylines\dobeginETEX}
-
-% \gdef\dobeginETEX#1
-% {\egroup\immediate\write16%
-% {system (E-TEX) : [line \the\inputlineno] \detokenize{#1}}}
-
- \gdef\dobeginETEX#1
- {\egroup}
-
- \global\let\endETEX\relax
-
-\fi
-
-\ifx\OmegaVersion\undefined
-
- \long\gdef\beginOMEGA#1\endOMEGA%
- {}
-
-\else
-
- \gdef\beginOMEGA%
- {\bgroup\obeylines\dobeginOMEGA}
-
- \ifx\detokenize\undefined
-
- \gdef\dobeginOMEGA#1
- {\egroup\immediate\write16%
- {system (OMEGA) : [line \the\inputlineno] \string#1 }} % we assume an argument
-
- \else
-
- \gdef\dobeginOMEGA#1
- {\egroup\immediate\write16%
- {system (OMEGA) : [line \the\inputlineno] \detokenize{#1}}} % we assume aleph
-
- \fi
-
- \global\let\endOMEGA\relax
-
-\fi
-
-\ifx\XeTeXversion\undefined
-
- \long\gdef\beginXETEX#1\endXETEX%
- {}
-
-\else
-
- \gdef\beginXETEX%
- {\bgroup\obeylines\dobeginXETEX}
-
- \gdef\dobeginXETEX#1
- {\egroup\immediate\write16%
- {system (XETEX) : [line \the\inputlineno] \detokenize{#1}}}
-
- \global\let\endXETEX\relax
-
-\fi
-
-\ifx\directlua\undefined
-
- \long\gdef\beginLUATEX#1\endLUATEX%
- {}
-
-\else
-
- \gdef\beginLUATEX%
- {\bgroup\obeylines\dobeginLUATEX}
-
- \gdef\dobeginLUATEX#1
- {\egroup\immediate\write16%
- {system (LUATEX) : [line \the\inputlineno] \detokenize{#1}}}
-
- \global\let\endLUATEX\relax
-
-\fi
-
-% traditional tex's vs de utf tex's
-
-\ifx\XeTeXversion\undefined \ifx\directlua\undefined
-
- \gdef\beginOLDTEX%
- {\bgroup\obeylines\dobeginOLDTEX}
-
- \gdef\dobeginOLDTEX#1
- {\egroup\immediate\write16%
- {system (OLDTEX) : [line \the\inputlineno] \detokenize{#1}}}
-
- \global\let\endOLDTEX\relax
-
- \long\gdef\beginNEWTEX#1\endNEWTEX%
- {}
-
-\fi \fi \ifx\beginOLDTEX\undefined
-
- \long\gdef\beginOLDTEX#1\endOLDTEX%
- {}
-
- \gdef\beginNEWTEX%
- {\bgroup\obeylines\dobeginNEWTEX}
-
- \gdef\dobeginNEWTEX#1
- {\egroup\immediate\write16%
- {system (NEWTEX) : [line \the\inputlineno] \detokenize{#1}}}
-
- \global\let\endNEWTEX\relax
-
-\fi
-
-\egroup
-
-%D Let's get rid of this one:
-
-\def\wlog#1{}
-
-%D Just for tracing purposes we set:
-
-\tracingstats=1
-
-%D We don't like outer commands, and we always want access
-%D to the original \type {\input} primitive.
-
-\let\normalouter = \outer \let\outer\relax
-\let\normalinput = \input
-
-%D We need to make sure that we start up in \DVI\ mode, so,
-%D after testing for running \PDFTEX, we default to \DVI.
-
-\ifx\pdftexversion\undefined \newcount\pdfoutput \fi \pdfoutput=0
-
-%D To circumvent dependencies, we can postpone certain
-%D initializations to dumping time, by appending them to the
-%D \type {\everydump} token register.
-
-\newtoks \everydump
-
-\let\normaldump \dump
-
-\def\dump{\the\everydump\normaldump}
-
-%D \macros
-%D {bindprimitive}
-
-\beginTEX
-
-\def\bindprimitive#1 #2 % new old
- {\expandafter\ifx\csname#1\endcsname\relax \expandafter\ifx\csname#2\endcsname\relax \else
- \expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname
- \fi\fi}
-
-\endTEX
-
-\beginETEX
-
-\def\bindprimitive#1 #2 % new old
- {\ifcsname#1\endcsname \else\ifcsname#2\endcsname
- \expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname
- \fi\fi}
-
-\endETEX
-
-% %D Ligature prevention (for instance, ec encoding has ligatures
-% %D in mono spaced fonts). Alas, we need to do some testing in order
-% %D to get to the ptex'd one.
-
-% \def\checkpdftexprimitive #1
-% {\expandafter\ifx\csname #1\endcsname\relax
-% \expandafter\ifx\csname pdf#1\endcsname\relax
-% \expandafter\ifx\csname ptex#1\endcsname\relax
-% \expandafter\let\csname normal#1\endcsname \undefined \else
-% \expandafter\let\csname normal#1\expandafter\endcsname\csname ptex#1\endcsname \fi \else
-% \expandafter\let\csname normal#1\expandafter\endcsname\csname pdf#1\endcsname \fi \else
-% \expandafter\let\csname normal#1\expandafter\endcsname\csname #1\endcsname \fi}
-
-% \checkpdftexprimitive quitvmode
-% \checkpdftexprimitive noligatures
-% \checkpdftexprimitive setrandomseed
-% \checkpdftexprimitive uniformdeviate
-
-%D We preserve \TEX's ending:
-
-\ifx\normalend\undefined \let\normalend\end \fi
-
-\protect \endinput
diff --git a/tex/context/base/syst-rtp.tex b/tex/context/base/syst-rtp.tex
deleted file mode 100644
index 958265f13..000000000
--- a/tex/context/base/syst-rtp.tex
+++ /dev/null
@@ -1,22 +0,0 @@
-%D \module
-%D [ file=syst-rtp, % copied from core-job
-%D version=1997.03.31,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Run Time Processes,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 Core Macros / Run Time Processes}
-
-\unprotect
-
-\let\executesystemcommand\gobbleoneargument
-
-\loadmarkfile{syst-rtp}
-
-\protect \endinput
diff --git a/tex/context/base/syst-str.mkii b/tex/context/base/syst-str.mkii
index e50df0103..3e6d043e3 100644
--- a/tex/context/base/syst-str.mkii
+++ b/tex/context/base/syst-str.mkii
@@ -64,7 +64,12 @@
\the\withuppercharacters
\relax}
-%D The string macros:
+%D I got tired of making dedicated clean up macros using the
+%D same mechanism again and again, so now we have:
+%D
+%D \starttyping
+%D \def\xxxx{abc.d} \replacecharacters\xxxx{a.}{-} \xxxx
+%D \stoptyping
\def\replacecharacters#1#2#3% macro characters replacement
{\bgroup
diff --git a/tex/context/base/syst-str.mkiv b/tex/context/base/syst-str.mkiv
index db3389ec0..57d76dc03 100644
--- a/tex/context/base/syst-str.mkiv
+++ b/tex/context/base/syst-str.mkiv
@@ -13,8 +13,17 @@
\unprotect
+% nb: these macros might go away !
+%
% todo: escape special chars in expr (\luaescapeexpression)
+%D I got tired of making dedicated clean up macros using the
+%D same mechanism again and again, so now we have:
+%D
+%D \starttyping
+%D \def\xxxx{abc.d} \replacecharacters\xxxx{a.}{-} \xxxx
+%D \stoptyping
+
\def\replacecharacters#1#2#3% macro characters replacement
{\dodoglobal\edef#1{\ctxlua{tex.sprint((string.gsub(\!!bs#1\!!es,\!!bs#2\!!es,"#3")))}}}
diff --git a/tex/context/base/syst-str.tex b/tex/context/base/syst-str.tex
deleted file mode 100644
index 15db004a3..000000000
--- a/tex/context/base/syst-str.tex
+++ /dev/null
@@ -1,40 +0,0 @@
-%D \module
-%D [ file=syst-str,
-%D version=2006.09.18,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=String Processing,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 System Macro's / Strings}
-
-%D These macros were defined elsewhere but for practical reasons
-%D we moved them here. This way we can more easily provide Mk IV
-%D support.
-
-\unprotect
-
-%D I got tired of making dedicated clean up macros using the
-%D same mechanism again and again, so now we have:
-%D
-%D \starttyping
-%D \def\xxxx{abc.d} \replacecharacters\xxxx{a.}{-} \xxxx
-%D \stoptyping
-
-\let\replacecharacters\gobblethreearguments % macro characters replacement
-
-%D Hm?
-
-\def\separatestring #1\to#2{}
-\def\unspacefilename#1\to#2{}
-
-%D Plugins:
-
-\loadmarkfile{syst-str}
-
-\protect \endinput
diff --git a/tex/context/base/syst-var.tex b/tex/context/base/syst-var.tex
deleted file mode 100644
index 8753017b5..000000000
--- a/tex/context/base/syst-var.tex
+++ /dev/null
@@ -1,18 +0,0 @@
-%D \module
-%D [ file=syst-var,
-%D version=2005.07.04, % moved code
-%D title=\CONTEXT\ System Macros,
-%D subtitle=Variables,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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 System Macro's / Variables}
-
-% will be used some day
-
-\endinput
diff --git a/tex/context/base/syst-xtx.tex b/tex/context/base/syst-xtx.tex
deleted file mode 100644
index a10173117..000000000
--- a/tex/context/base/syst-xtx.tex
+++ /dev/null
@@ -1,36 +0,0 @@
-%D \module
-%D [ file=syst-xtx,
-%D version=2004.09.11,
-%D title=\CONTEXT\ System Macros,
-%D subtitle=\XETEX\ specifics,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
-%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\XeTeXversion\undefined \endinput \fi
-
-\unprotect
-
-%D For the moment, the only thing needed is to load are the
-%D mappings from lower to uppercase characters.
-
-\input enco-utf.tex
-
-% patch needed for turkish
-
-\setcclcucx 201C 201C 201C
-\setcclcucx 201D 201D 201D
-
-% patch needed for greek
-
-% \setcclcucx 1FFD 1FFD 1FFD
-
-\ifx\XeTeXuseglyphmetrics\undefined \else
- \XeTeXuseglyphmetrics=1
-\fi
-
-\protect \endinput
diff --git a/tex/context/base/core-ltb.tex b/tex/context/base/tabl-ltb.tex
index 3ebd16379..e45fb1bc1 100644
--- a/tex/context/base/core-ltb.tex
+++ b/tex/context/base/tabl-ltb.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=core-ltb,
%D version=2002.10.31,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Table Macros,
%D subtitle=Line Tables,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -55,7 +55,7 @@
% - clip on prev run
% - flush real widths
-\writestatus{loading}{Context Core Macros / Line Tables}
+\writestatus{loading}{ConTeXt Table Macros / Line Tables}
\unprotect
diff --git a/tex/context/base/core-ntb.tex b/tex/context/base/tabl-ntb.mkii
index 5bfba05ad..1f9a9d574 100644
--- a/tex/context/base/core-ntb.tex
+++ b/tex/context/base/tabl-ntb.mkii
@@ -1,7 +1,7 @@
%D \module
%D [ file=core-ntb,
%D version=2000.04.18,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Table Macros,
%D subtitle=Natural Tables,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -23,7 +23,7 @@
% optie=rek beschrijven
-\writestatus{loading}{Context Core Macros / Natural Tables}
+\writestatus{loading}{ConTeXt Table Macros / Natural Tables}
%D As always, this is the nth version. Much time went in
%D trying to speed up the many cell calculations, some
@@ -461,7 +461,6 @@
\def\parseTR[#1][#2]% [#2] is dummy that kills spaces / no #3 argument
{\currentcol\zerocount
\advance\maximumrow\plusone
- \let\eTR\relax % handy in \expanded
\iffirstargument\setTABLEparameters[\c!y\number\maximumrow][#1]\fi}
\def\settblref#1#2{\expandafter\xdef\csname\@@tblprefix\number#1:\number#2:x\endcsname}
@@ -637,16 +636,17 @@
% to be done: head <raw> foot, dus state var
-\long\def\bTABLEhead{\dosingleempty\doTABLEhead}
-\long\def\bTABLEnext{\dosingleempty\doTABLEnext}
-\long\def\bTABLEbody{\dosingleempty\doTABLEbody}
-\long\def\bTABLEfoot{\dosingleempty\doTABLEfoot}
+\unexpanded\def\bTABLEhead{\dosingleempty\doTABLEhead} \let\eTABLEhead\relax
+\unexpanded\def\bTABLEnext{\dosingleempty\doTABLEnext} \let\eTABLEnext\relax
+\unexpanded\def\bTABLEbody{\dosingleempty\doTABLEbody} \let\eTABLEbody\relax
+\unexpanded\def\bTABLEfoot{\dosingleempty\doTABLEfoot} \let\eTABLEfoot\relax
\long\def\doTABLEhead[#1]#2\eTABLEhead{\appendtoks\doTABLEsection[#1]{#2}\to\TBLhead}
\long\def\doTABLEnext[#1]#2\eTABLEnext{\appendtoks\doTABLEsection[#1]{#2}\to\TBLnext}
\long\def\doTABLEbody[#1]#2\eTABLEbody{\appendtoks\doTABLEsection[#1]{#2}\to\TBLbody}
\long\def\doTABLEfoot[#1]#2\eTABLEfoot{\appendtoks\doTABLEsection[#1]{#2}\to\TBLfoot}
+
\long\def\doTABLEsection[#1]#2%
{\def\setupTBLsection{\getparameters[\@@tbl\@@tbl][#1]}%
#2%
@@ -698,17 +698,22 @@
\maximumrowspan\plusone
\maximumcol\zerocount
\maximumrow\zerocount
- \def\bTR{\dodoubleempty\parseTR}%
- \def\bTD{\dodoubleempty\parseTD}%
- \def\bTH{\dodoubleempty\parseTH}%
- \def\bTN{\dodoubleempty\parseTN}}
+ \let\bTR\dobTR
+ \let\bTD\dobTD
+ \let\bTH\dobTH
+ \let\bTN\dobTN}
+
+\unexpanded\def\dobTR{\dodoubleempty\parseTR}
+\unexpanded\def\dobTD{\dodoubleempty\parseTD}
+\unexpanded\def\dobTH{\dodoubleempty\parseTH}
+\unexpanded\def\dobTN{\dodoubleempty\parseTN}
% permits \expanded{\bTD ... \eTD}
-\unexpanded\def\eTR{}
-\unexpanded\def\eTD{}
-\unexpanded\def\eTH{}
-\unexpanded\def\eTN{}
+\unexpanded\def\eTR{\ignorespaces}
+\unexpanded\def\eTD{\ignorespaces}
+\unexpanded\def\eTH{\ignorespaces}
+\unexpanded\def\eTN{\ignorespaces}
\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode
{% tricky and dirty order -)
@@ -1478,15 +1483,21 @@
\presetlocalframed % breedte hoogte diepte offset
[\@@tbl\@@tbl]% % achtergrond, achtergrondraster, achtergrondkleur
% not ok yet
- \setupTABLE
- [\c!frameoffset=.5\linewidth,
+ \setupTABLE [%
+ \c!frameoffset=.5\linewidth,
\c!backgroundoffset=\v!frame,
\c!framecolor=\s!black,
+ \c!width=fit,
+ \c!height=fit,
+\c!autowidth=\v!yes,
+% \c!rulethickness=\linewidth,
+% \c!strut=\v!no,
+\c!strut=\v!yes, % needed for mathml, but ... maybe we need another resetTABLEmode
+\c!autostrut=\v!no,
\c!color=,
\c!style=,
\c!headstyle=,
\c!headcolor=,
- \c!strut=\v!no,
\c!aligncharacter=\v!no,
\c!alignmentcharacter={,},
\c!maxwidth=8em]%
diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv
new file mode 100644
index 000000000..ca932a5d9
--- /dev/null
+++ b/tex/context/base/tabl-ntb.mkiv
@@ -0,0 +1,1571 @@
+%D \module
+%D [ file=core-ntb,
+%D version=2000.04.18,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Natural Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 unfinished, preliminary module. At least two
+%D runs are needed to get the table fixed. Ugly code.
+
+% todo: special parsetb for argless variant
+% todo: protect \tbl...
+% todo: tblnx also count
+% todo: get rid of recurse
+% todo: fast if
+% todo: avoid halign (just do it manual) and thereby globals
+
+% optie=rek beschrijven
+
+\writestatus{loading}{ConTeXt Table Macros / Natural Tables}
+
+%D As always, this is the nth version. Much time went in
+%D trying to speed up the many cell calculations, some
+%D optimizations were rejected in order not to complicate this
+%D module too much (and in order to prevail extensibility).
+
+% shapebox fails here in mkii
+%
+% \setupcolors[state=start]
+% \bTABLE
+% \bTR [align=middle]\bTH Range\eTH{}\bTH Value\eTH{}\eTR
+% \bTR \bTD \type{<} 12\eTD{}\bTD 3\eTD{}\eTR
+% \bTR \bTD 12--16\eTD{}\bTD 2\eTD{}\eTR
+% \bTR \bTD \type{>}16\eTD{}\bTD 1\eTD{}\eTR
+% \eTABLE
+
+% \starttext
+% \placefigure[left]{}{}
+% \startlinecorrection \dontleavehmode \bTABLE
+% \bTR \bTD oeps \eTD \eTR
+% \eTABLE
+% \stoplinecorrection
+% \placefigure[right]{}{}
+% \startlinecorrection \dontleavehmode \bTABLE
+% \bTR \bTD oeps \eTD \eTR
+% \eTABLE
+% \stoplinecorrection
+% \stoptext
+
+%D To Do:
+%D
+%D \starttyping
+%D splitsen = ja | herhaal => als nofTH>1 then ja als herhaal
+%D \stoptyping
+
+%D To Do:
+%D
+%D \starttyping
+%D break over pagina
+%D kop herhalen
+%D reset settings
+%D
+%D \setupTABLE [c|column|x] [nx|odd|even|first|last][a=b]
+%D \setupTABLE [r|row |y] [nx|odd|even|first|last][a=b]
+%D \setupTABLE [nx|odd|even|first|last][ny|odd|even|first|last][a=b]
+%D \setupTABLE [nx|odd|even|first|last] [a=b]
+%D \setupTABLE [a=b]
+%D
+%D \bTH \eTH
+%D \stoptyping
+
+% the section setup does not work yet, data needs to be stored,
+% i.e.each row should know if it's a head/body/foot, and there
+% should be \setupTABLE[head]... and alike
+
+\unprotect
+
+%D A simple way to force equal line spacing is to say:
+%D
+%D \starttyping
+%D \def\bTBLCELL{\begstrut}
+%D \def\eTBLCELL{\endstrut}
+%D \stoptyping
+%D
+%D The next alternative also takes care of preceding and following
+%D white space.
+%D
+%D \startbuffer
+%D \bTABLE[left={(},right={)},top=\startnarrower,bottom=\stopnarrower]
+%D \bTR \bTD something \eTD \eTR
+%D \eTABLE
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\def\bTBLCELL % why not \doinhibitblank
+ {\inhibitblank
+ \doconvertfont\tbltblstyle\empty
+ \everypar{\tbltblleft\delayedbegstrut}}
+
+\def\eTBLCELL
+ {\ifhmode
+ \delayedendstrut
+ \tbltblright
+ \par % added 13/4/2006
+ \else
+ % not sure yet:\tbltblright
+ \par
+ \ifdim\prevdepth<\zeropoint % =-1000pt ?
+ \vskip-\strutdp
+ \else
+ \removebottomthings
+ \fi
+ \fi}
+
+\newcount\currenttbl
+
+\def\@@tbl{tbl} \def\tblcell{1} \def\tblnone{2}
+
+\def\@@tblprefix{tbl:} \let\@@rawtblprefix\@@tblprefix
+
+%D This should be done more efficient: soon
+
+% \let as well as \expandafter\edef's
+
+\newcounter\TBLlevel
+
+\def\@@tblprefix{\@@tbl:\ifnum\TBLlevel>1 :\TBLlevel:\fi}
+
+% \def\tblsetprefix % not yet used, figure out when .. may interfere with setup
+% {\edef\@@tblprefix{\@@tbl:\ifnum\TBLlevel>1 :\TBLlevel:\fi}}
+
+\def\settblnob#1{\expandafter\let\csname\@@tblprefix\number#1:b\endcsname\plusone}
+\def\gettblnob#1{\ifcsname\@@tblprefix\number#1:b\endcsname\plusone\else\zerocount\fi}
+
+\def\settbltag#1#2{\expandafter\edef\csname\@@tblprefix\number#1:\number#2:s\endcsname}
+\def\settblcol#1#2{\expandafter\edef\csname\@@tblprefix\number#1:\number#2:c\endcsname}
+\def\settblrow#1#2{\expandafter\edef\csname\@@tblprefix\number#1:\number#2:r\endcsname}
+
+\def\lettbltag#1#2{\expandafter\let\csname\@@tblprefix\number#1:\number#2:s\endcsname}
+\def\lettblcol#1#2{\expandafter\let\csname\@@tblprefix\number#1:\number#2:c\endcsname}
+\def\lettblrow#1#2{\expandafter\let\csname\@@tblprefix\number#1:\number#2:r\endcsname}
+
+\def\settblwd#1#2{\expandafter\xdef\csname\@@tblprefix\number#1:\number#2:wd\endcsname} % global !
+\def\settblht#1#2{\expandafter\xdef\csname\@@tblprefix\number#1:\number#2:ht\endcsname} % global !
+\def\lettblwd#1#2{\global\expandafter\let\csname\@@tblprefix\number#1:\number#2:wd\endcsname} % global !
+\def\lettblht#1#2{\global\expandafter\let\csname\@@tblprefix\number#1:\number#2:ht\endcsname} % global !
+
+\def\gettbltag#1#2{\csname\@@tblprefix\number#1:\number#2:s\endcsname}
+\def\gettblcol#1#2{\csname\@@tblprefix\number#1:\number#2:c\endcsname}
+\def\gettblrow#1#2{\csname\@@tblprefix\number#1:\number#2:r\endcsname}
+
+\def\gettblwd #1#2{\csname\@@tblprefix\number#1:\number#2:wd\endcsname}
+\def\gettblht #1#2{\csname\@@tblprefix\number#1:\number#2:ht\endcsname}
+
+\def\settblwid#1{\expandafter\xdef\csname\@@tblprefix\number#1:w\endcsname} % {#2} global !
+\def\settblhei#1{\expandafter\xdef\csname\@@tblprefix\number#1:h\endcsname} % {#2} global !
+\def\settbldis#1{\expandafter\xdef\csname\@@tblprefix\number#1:d\endcsname} % {#2} global !
+\def\settblaut#1{\expandafter\xdef\csname\@@tblprefix\number#1:a\endcsname} % {#2} global !
+
+\def\lettblwid#1{\global\expandafter\let\csname\@@tblprefix\number#1:w\endcsname} % {#2} global !
+\def\lettblhei#1{\global\expandafter\let\csname\@@tblprefix\number#1:h\endcsname} % {#2} global !
+\def\lettbldis#1{\global\expandafter\let\csname\@@tblprefix\number#1:d\endcsname} % {#2} global !
+\def\lettblaut#1{\global\expandafter\let\csname\@@tblprefix\number#1:a\endcsname} % {#2} global !
+
+\def\gettblwid#1{\ifcsname\@@tblprefix\number#1:w\endcsname\csname\@@tblprefix\number#1:w\endcsname\else\zeropoint\fi}
+\def\gettblhei#1{\ifcsname\@@tblprefix\number#1:h\endcsname\csname\@@tblprefix\number#1:h\endcsname\else\zeropoint\fi}
+\def\gettbldis#1{\ifcsname\@@tblprefix\number#1:d\endcsname\csname\@@tblprefix\number#1:d\endcsname\else\zeropoint\fi}
+\def\gettblaut#1{\csname \@@tblprefix\number#1:a\endcsname}
+
+\def\doiftbltag #1#2{\ifcsname\@@tblprefix\number#1:\number#2:s\endcsname\@EA\firstofoneargument \else\@EA\gobbleoneargument \fi}
+\def\doifnottbltag #1#2{\ifcsname\@@tblprefix\number#1:\number#2:s\endcsname\@EA\gobbleoneargument \else\@EA\firstofoneargument \fi}
+\def\doifelsetbltag#1#2{\ifcsname\@@tblprefix\number#1:\number#2:s\endcsname\@EA\firstoftwoarguments\else\@EA\secondoftwoarguments\fi}
+\def\doiftblrow #1#2{\ifcsname\@@tblprefix\number#1:\number#2:r\endcsname\@EA\firstofoneargument \else\@EA\gobbleoneargument \fi}
+\def\doiftblcol #1#2{\ifcsname\@@tblprefix\number#1:\number#2:c\endcsname\@EA\firstofoneargument \else\@EA\gobbleoneargument \fi}
+\def\doifnottblcol #1#2{\ifcsname\@@tblprefix\number#1:\number#2:c\endcsname\@EA\gobbleoneargument \else\@EA\firstofoneargument \fi}
+
+\def\tbltagstate#1#2{\ifcsname\@@tblprefix\number#1:\number#2:s\endcsname\zerocount\else\plusone\fi}
+\def\tblrowstate#1#2{\ifcsname\@@tblprefix\number#1:\number#2:r\endcsname\zerocount\else\plusone\fi}
+\def\tblcolstate#1#2{\ifcsname\@@tblprefix\number#1:\number#2:c\endcsname\zerocount\else\plusone\fi}
+
+\def\settblspn #1{\expandafter\let\csname\@@tblprefix\number#1:s\endcsname \!!plusone}
+\def\doifelsetblspn#1{\doifelse {\csname\@@tblprefix\number#1:s\endcsname}\!!plusone}
+% \def\doifelsetblspn#1{\@EA\ifx\csname\@@tblprefix\number#1:s\endcsname\plusone\@EA\firstoftwoarguments\else\@EA\secondoftwoarguments\fi}
+
+\def\settblspn #1{\setvalue {\@@tblprefix\number#1:s}{1}}
+\def\doifelsetblspn#1{\doifelsevalue{\@@tblprefix\number#1:s}{1}}
+
+\long\def\settbltxt#1#2#3%
+ {\long\@EA\def\csname\@@tblprefix\number#1:\number#2:t\@EA\endcsname\@EA{\@EA\def\@EA\TBLlevel\@EA{\TBLlevel}#3}}
+
+\def\gettbltxt#1#2%
+ {\csname\@@tblprefix\number#1:\number#2:t\endcsname}
+
+\newtoks\tbltoks
+\newtoks\tblrowtoks
+
+\let\pushTBLparameters\relax
+\let\popTBLparameters \relax
+
+\newif\ifsqueezeTBLspan \squeezeTBLspantrue % spans one column cell over multi column par cells
+\newif\ifautosqueezeTBLspan \autosqueezeTBLspantrue % unless explicit widths are given
+\newif\ifautoTBLspread \autoTBLspreadfalse
+\newif\ifautoTBLhsize \autoTBLhsizetrue
+\newif\ifautoTBLrowspan \autoTBLrowspantrue
+\newif\ifautoTBLemptycell \autoTBLemptycelltrue
+\newif\ifautoTBLcheckwidth \autoTBLcheckwidthtrue
+\newif\ifappendTBLsetups \appendTBLsetupstrue
+\newif\ifenableTBLbreak \enableTBLbreakfalse
+\newif\ifmultipleTBLheads \multipleTBLheadsfalse
+
+\newif\iftraceTABLE \traceTABLEfalse
+
+\def\noftblheadlines{0}
+\def\noftblnextlines{0}
+\def\noftblhdnxlines{0}
+
+\long\def\handleTBLcell#1#2[#3]{}
+
+\long\def\bTC#1\eTC{\bTD#1\eTD}
+\long\def\bTX#1\eTX{\bTD#1\eTD}
+\long\def\bTY#1\eTY{\bTR#1\eTR}
+
+\let\getTABLEparameters\getparameters
+
+\unexpanded\def\setupTABLE
+ {\dotripleempty\dosetupTABLE}
+
+\def\dosetupTABLE[#1][#2][#3]%
+ {\ifthirdargument
+ \processaction
+ [#1]
+ [ \v!row=>{\dosetupTABLExy[\c!y][#2][#3]},%
+ \v!column=>{\dosetupTABLExy[\c!x][#2][#3]},%
+ r=>{\dosetupTABLExy[\c!y][#2][#3]},%
+ c=>{\dosetupTABLExy[\c!x][#2][#3]},%
+ y=>{\dosetupTABLExy[\c!y][#2][#3]},%
+ x=>{\dosetupTABLExy[\c!x][#2][#3]},%
+ \v!start=>{\dosetupTABLExy[#1][#2][#3]},%
+ \v!header=>{\dosetupTABLExy[#1][#2][#3]},%
+ \s!unknown=>{\dosetupTABLEzz[#1][#2][#3]}]%
+ \else\ifsecondargument
+ \processaction
+ [#1]
+ [ \v!row=>{\dosetupTABLExy[\c!y][\v!each][#2]},%
+ \v!column=>{\dosetupTABLExy[\c!x][\v!each][#2]},%
+ r=>{\dosetupTABLExy[\c!y][\v!each][#2]},%
+ c=>{\dosetupTABLExy[\c!x][\v!each][#2]},%
+ y=>{\dosetupTABLExy[\c!y][\v!each][#2]},%
+ x=>{\dosetupTABLExy[\c!x][\v!each][#2]},%
+ \v!start=>{\dosetupTABLExy[#1][\v!each][#2]},%
+ \v!header=>{\dosetupTABLExy[#1][\v!each][#2]},%
+ \s!unknown=>{\dosetupTABLEzz[\c!x][#1][#2]}]%
+ \else
+ \getparameters[\@@tbl\@@tbl][#1]%
+ \fi\fi}
+
+\def\dosetupTABLExy[#1][#2][#3]%
+ {\def\dodosetupTABLE##1{\setTABLEparameters[#1##1][#3]}%
+ \processcommalist[#2]\dodosetupTABLE}
+
+\def\dosetupTABLEzz[#1][#2][#3]%
+ {\def\dodosetupTABLE##1%
+ {\def\dododosetupTABLE####1{\setTABLEparameters[\c!x##1\c!y####1][#3]}%
+ \processcommalist[#2]\dododosetupTABLE}%
+ \processcommalist[#1]\dodosetupTABLE}
+
+\def\nopTABLEparameters[#1][#2]%
+ {\letvalue{\@@tblprefix#1}\empty}
+
+\def\setTABLEparameters[#1][#2]%
+ {\pushTBLparameters
+ \ifappendTBLsetups
+ \doifdefinedelse{\@@tblprefix#1}
+ {\def\getTABLEparameters[##1][##2]%
+ {\setvalue{\@@tblprefix#1}{\getTABLEparameters[\@@tbl\@@tbl][##2,#2]}}%
+ \getvalue{\@@tblprefix#1}%
+ \let\getTABLEparameters\getparameters}
+ {\setvalue{\@@tblprefix#1}{\getTABLEparameters[\@@tbl\@@tbl][#2]}}%
+ \else
+ \setvalue{\@@tblprefix#1}{\getTABLEparameters[\@@tbl\@@tbl][#2]}%
+ \fi
+ \popTBLparameters}
+
+\let\setupTBLsection\relax
+
+% % \setupTABLE [y] [first][background=color,backgroundcolor=blue,frame=off,bottomframe=on,topframe=on,framecolor=white]
+% \setupTABLE [first][first][backgroundcorner=2,corner=10,frame=on]
+% \setupTABLE [last] [first][backgroundcorner=4,corner=12,frame=on]
+%
+% \setupTABLE [row] [each] [background=color,backgroundcolor=blue,frame=on,framecolor=white]
+% \setupTABLE [first][2] [corner=8]
+% \setupTABLE [last] [2] [corner=5]
+% \setupTABLE [first][last] [corner=7]
+% \setupTABLE [last] [last] [corner=6]
+%
+% \startTEXpage
+% \bTABLE[frame=off,align=middle]
+% \bTR \bTD one \eTD \bTD two \eTD \bTD three \eTD \eTR
+% \bTR \bTD first \eTD \bTD second \eTD \bTD third \eTD \eTR
+% \bTR \bTD alpha \eTD \bTD beta \eTD \bTD gamma \eTD \eTR
+% \eTABLE
+% \stopTEXpage
+%
+% \setupTABLE [first] [two][corner=2] % special case
+% \setupTABLE [last] [two][corner=4] % special case
+%
+% % % \setupTABLE [one] [first] ... special case of span
+%
+% \startTEXpage
+% \bTABLE[frame=off,align=middle]
+% \bTR \bTD one \eTD \bTD two \eTD \bTD three \eTD \eTR
+% \bTR \bTD first \eTD \bTD second \eTD \bTD third \eTD \eTR
+% \eTABLE
+% \stopTEXpage
+
+\def\setupTBLcell#1#2% cell over col over row
+ {\setupTBLsection % already forgotten
+ \edef\positiverow{\number#1}%
+ \edef\positivecol{\number#2}%
+ \edef\negativerow{\the\numexpr-\maximumrow+#1+\minusone\relax}%
+ \edef\negativecol{\the\numexpr-\maximumcol+#2+\minusone\relax}%
+ % each each
+ \csname\@@tblprefix\c!x\v!each\c!y\v!each\endcsname
+ \csname\@@tblprefix\c!y\v!each\endcsname
+ \csname\@@tblprefix\c!x\v!each\endcsname
+ % odd even
+ \csname\@@tblprefix\c!y\v!oddeven\positiverow\endcsname
+ \csname\@@tblprefix\c!x\v!oddeven\positivecol\endcsname
+ \csname\@@tblprefix\c!x\v!oddeven\positivecol\c!y\v!oddeven\positiverow\endcsname
+ % row/col number combinations
+ \ifcsname\@@tblprefix\c!y\positiverow\endcsname\csname\@@tblprefix\c!y\positiverow\endcsname\fi
+ \ifcsname\@@tblprefix\c!y\negativerow\endcsname\csname\@@tblprefix\c!y\negativerow\endcsname\fi
+ \csname\@@tbl\@@tbl\c!extras\endcsname
+ \@EA\let\csname\@@tbl\@@tbl\c!extras\endcsname\relax % new, see x-fo
+ \ifcsname\@@tblprefix\c!x\positivecol\endcsname\csname\@@tblprefix\c!x\positivecol\endcsname\fi
+ \ifcsname\@@tblprefix\c!x\negativecol\endcsname\csname\@@tblprefix\c!x\negativecol\endcsname\fi
+ \csname\@@tbl\@@tbl\c!extras\endcsname
+ \@EA\let\csname\@@tbl\@@tbl\c!extras\endcsname\relax % new, see x-fo
+ % first/last combinations
+ \ifnum\positiverow=\plusone
+ \csname\@@tblprefix\c!y\v!first\endcsname
+ \ifcsname\@@tblprefix\c!x\positivecol\c!y\v!first\endcsname\csname\@@tblprefix\c!x\positivecol\c!y\v!first\endcsname\fi
+ \fi
+ \ifnum\positivecol=\plusone
+ \csname\@@tblprefix\c!x\v!first\endcsname
+ \ifcsname\@@tblprefix\c!x\v!first\c!y\positiverow\endcsname\csname\@@tblprefix\c!x\v!first\c!y\positiverow\endcsname\fi
+ \fi
+ \ifnum\positiverow=\maximumrow\relax
+ \csname\@@tblprefix\c!y\v!last\endcsname
+ \ifcsname\@@tblprefix\c!x\positivecol\c!y\v!last\endcsname\csname\@@tblprefix\c!x\positivecol\c!y\v!last\endcsname\fi
+ \fi
+ \ifnum\positivecol=\maximumcol\relax
+ \csname\@@tblprefix\c!x\v!last\endcsname
+ \ifcsname\@@tblprefix\c!x\v!last\c!y\positiverow\endcsname\csname\@@tblprefix\c!x\v!last\c!y\positiverow\endcsname\fi
+ \fi
+ \ifnum\positiverow=\maximumrow\relax \ifnum\positivecol=\maximumcol\relax
+ \csname\@@tblprefix\c!x\v!last\c!y\v!last\endcsname
+ \fi\fi
+ \ifnum\positiverow=\plusone \ifnum\positivecol=\plusone
+ \csname\@@tblprefix\c!x\v!first\c!y\v!first\endcsname
+ \fi\fi
+ \ifnum\positiverow=\plusone \ifnum\positivecol=\maximumcol\relax
+ \csname\@@tblprefix\c!x\v!last\c!y\v!first\endcsname
+ \fi\fi
+ \ifnum\positiverow=\maximumrow\relax \ifnum\positivecol=\plusone
+ \csname\@@tblprefix\c!x\v!first\c!y\v!last\endcsname
+ \fi\fi
+ % special case: two rows and last row : two&first and two&last (round corners)
+ \ifnum\maximumrow=\plustwo\relax
+ \ifnum\positiverow=\maximumrow\relax \ifnum\positivecol=\plusone
+ \csname\@@tblprefix\c!x\v!first\c!y\v!two\endcsname
+ \fi\fi
+ \ifnum\positiverow=\maximumrow\relax \ifnum\positivecol=\maximumcol\relax
+ \csname\@@tblprefix\c!x\v!last\c!y\v!two\endcsname
+ \fi\fi
+ \fi
+ \ifnum\gettblcol\positiverow\positivecol=\maximumcol\relax % top span over whole width
+ \ifnum\positiverow=\plusone
+ \csname\@@tblprefix\c!x\v!one\c!y\v!first\endcsname
+ \fi
+ \ifnum\positiverow=\maximumrow\relax
+ \csname\@@tblprefix\c!x\v!one\c!y\v!last\endcsname
+ \fi
+ \fi
+ % header things
+ \ifnum#1>\noftblhdnxlines\else
+ \ifcsname\@@tblprefix\v!header\v!each \endcsname\csname\@@tblprefix\v!header\v!each \endcsname\fi
+ \ifcsname\@@tblprefix\v!header\positivecol\endcsname\csname\@@tblprefix\v!header\positivecol\endcsname\fi
+ \fi
+ % explicit cells
+ \ifcsname\@@tblprefix\c!x\positivecol\c!y\positiverow\endcsname\csname\@@tblprefix\c!x\positivecol\c!y\positiverow\endcsname\fi
+ \ifcsname\@@tblprefix\c!x\negativecol\c!y\negativerow\endcsname\csname\@@tblprefix\c!x\negativecol\c!y\negativerow\endcsname\fi
+ % local
+ \ifcsname\@@tblprefix\c!y++\positiverow\endcsname\csname\@@tblprefix\c!y++\positiverow\endcsname\fi
+ % done
+ \global\letcscsname\@@tblsplitafter\csname\@@tbl\@@tbl\c!after\endcsname
+ \relax}
+
+% we cannot use +n (checking on number/last/first would slow down too much)
+%
+% \setupTABLE[r] [2][color=red]
+% \setupTABLE[r] [-2][color=red]
+% \setupTABLE[c] [2][color=green]
+% \setupTABLE[c] [-2][color=green]
+% \setupTABLE[4] [4][color=blue]
+% \setupTABLE[-4][-4][color=blue]
+%
+% \bTABLE
+% \dorecurse{10}{\bTR \dorecurse{6}{\bTD xxx \eTD} \eTR}
+% \eTABLE
+
+\globallet\@@tblsplitafter\relax
+
+% split + page:
+%
+% \bTABLE[split=yes]
+% \bTR \bTD left \eTD\bTD right \eTD\eTR
+% \bTR[after=\page] \bTD left \eTD\bTD right \eTD\eTR
+% \bTR \bTD left \eTD\bTD right \eTD\eTR
+% \eTABLE
+
+% todo: protect counters
+
+\newcount\row \newcount\col
+\newcount\xrow \newcount\xcol
+\newcount\xxrow \newcount\xxcol
+\newcount\maximumrow \newcount\maximumcol \newcount\maximumrowspan
+ \newcount\currentcol
+\newcount\tblspn
+
+\def\parseTR[#1][#2]% [#2] is dummy that kills spaces / no #3 argument
+ {\currentcol\zerocount
+ \advance\maximumrow\plusone
+ \iffirstargument
+ \setvalue{\@@tblprefix\c!y++\number\maximumrow}{\getparameters[\@@tbl\@@tbl][#1]}% maybe also in mkii
+ \fi}
+
+\def\settblref#1#2{\expandafter\xdef\csname\@@tblprefix\number#1:\number#2:x\endcsname}
+\def\gettblref#1#2{\ifcsname\@@tblprefix\number#1:\number#2:x\endcsname\csname\@@tblprefix\number#1:\number#2:x\endcsname\fi}
+
+\long\def\parseTD[#1][#2]#3\eTD % [#2] is dummy that kills spaces
+ {\def\tblny{\tblnr}%
+ \def\tblnx{\tblnc}%
+ \let\tblnc\plusone
+ \let\tblnr\plusone
+ \let\tbln\currentcol
+ \let\tblm\empty
+ \iffirstargument
+ \getparameters[\@@tbl][#1]%
+ \fi
+ % goto first cell % NEW, n/m=cellnumber
+ \edef\@@tblnindeed{\csname\@@tbl\c!n\endcsname}%
+ \ifx\@@tblnindeed\empty
+ \global\advance\tblspn\tblnx\relax
+ \else\ifnum\@@tblnindeed=\currentcol\else
+ \scratchcounter\numexpr\@@tblnindeed-\currentcol+\minusone-\tblspn\relax
+ \ifnum\scratchcounter>\zerocount
+ \normalexpanded{\noexpand\parseTD[\c!nx=\the\scratchcounter,\c!n=,\c!m=,*sq=\v!no][]}\eTD
+ \fi
+ % can also be made faster
+ \getparameters[\@@tbl][\c!ny=\tblnr,\c!nx=\tblnc,nc=1,nr=1,#1,\c!n=,\c!m=]%
+ \fi\fi
+ \edef\@@tblmindeed{\csname\@@tbl\c!m\endcsname}%
+ \ifx\@@tblmindeed\empty \else
+ \ifnum\@@tblmindeed=\currentcol \else
+ \scratchcounter\numexpr\@@tblmindeed-\currentcol+\minusone-\tblspn\relax
+ \dorecurse\scratchcounter{\normalexpanded{\noexpand\parseTD[\c!n=,\c!m=][]}\eTD}%
+ % can be sped up
+ \getparameters[\@@tbl][\c!ny=\tblnr,\c!nx=\tblnc,nc=1,nr=1,#1,\c!n=,\c!m=]% kind of double, see prev
+ \fi
+ \fi
+ \doloop % skip over columns that result from earlier span
+ {\advance\currentcol\plusone
+ \doifnottbltag\maximumrow\currentcol\exitloop}%
+ % == \def\next{\advance\currentcol\plusone\doiftbltag\maximumrow\currentcol\next}\next
+ % fill r*c cells and set span
+ \ifnum\tblnx=\plusone
+ \ifnum\tblny=\plusone
+ \ifnum\currentcol>\maximumcol\relax
+ \maximumcol\currentcol
+ \fi
+ \else
+ \presetTBLcell
+ \fi
+ \else
+ \presetTBLcell
+ \fi
+ % set values
+ \lettbltag\maximumrow\currentcol\tblcell
+ \settblcol\maximumrow\currentcol{\number\tblnx}%
+ \settblrow\maximumrow\currentcol{\number\tblny}%
+ \settblref\maximumrow\currentcol{\ifcsname\@@tbl\c!action\endcsname\csname\@@tbl\c!action\endcsname\fi}%
+ % save text
+ \edef\celltag{{\number\maximumrow}{\number\currentcol}}%
+ \@EA\settbltxt\@EA\maximumrow\@EA\currentcol\@EA{\@EA\handleTBLcell\celltag[#1]{#3}}}
+
+\def\presetTBLcell
+ {\row\maximumrow
+ \col\currentcol
+ \dorecurse\tblny
+ {\col\currentcol
+ \settblcol\row\col{\number\tblnx}%
+ \ifnum\tblnx>\maximumrowspan\relax
+ \maximumrowspan\tblnx
+ \fi
+ \dorecurse\tblnx
+ {\lettbltag\row\col\tblnone
+ \advance\col\plusone}%
+ \advance\row\plusone}%
+ % check max column
+ \advance\col\minusone
+ \ifnum\col>\maximumcol\relax
+ \maximumcol\col
+ \fi}
+
+%D The usage of n and m:
+%D
+%D \startbuffer
+%D \bTABLE[width=3em]
+%D \bTR\bTD d1 \eTD\bTD[n=2] d2 \eTD\bTD[n=5] d5 \eTD\bTD[n=7] d7 \eTD\eTR
+%D \bTR\bTD f1 \eTD\bTD[n=4] f4 \eTD\bTD[n=5] f5 \eTD\bTD[n=7] f7 \eTD\eTR
+%D \eTABLE
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \bTABLE[width=3em]
+%D \bTR\bTD d1 \eTD\bTD[m=2] d2 \eTD\bTD[m=5] d5 \eTD\bTD[m=7] d7 \eTD\eTR
+%D \bTR\bTD f1 \eTD\bTD[m=4] f4 \eTD\bTD[m=5] f5 \eTD\bTD[m=7] f7 \eTD\eTR
+%D \eTABLE
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+%D
+%D \startbuffer
+%D \bTABLE[frame=on]
+%D \bTR \bTH[nc=3] One \eTH \bTH[m=4] Four \eTH\eTR
+%D \bTR \bTD a \eTD\bTD b \eTD\bTD c \eTD\bTD d \eTD\eTR
+%D \eTABLE
+%D
+%D \bTABLE[frame=on]
+%D \bTR \bTH[nr=2] One \eTH \bTH[m=3] Three \eTH\eTR
+%D \bTR \bTD[m=3] a \eTD\bTD b \eTD\bTD c \eTD\bTD d \eTD\eTR
+%D \bTR \bTD[m=3] a \eTD\bTD b \eTD\bTD c \eTD\bTD d \eTD\eTR
+%D \eTABLE
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+\long\def\parseTH[#1]#2\eTH
+ {\parseTD[#1,\c!color=\tbltblheadcolor,\c!style=\tbltblheadstyle,\c!aligncharacter=\v!no]#2\eTD}
+
+%D new
+
+\long\def\parseTN[#1]#2\eTN
+ {\parseTD[#1]\digits#2\relax\eTD}
+
+%D Vit Zyka needed the option to create a distance between columns, so I
+%D added support for individual column distances.
+%D
+%D \startbuffer
+%D % \setupTABLE[c][each][distance=2em]
+%D \setupTABLE[c][1][distance=2em]
+%D \setupTABLE[c][2][distance=3em]
+%D
+%D \bTABLE
+%D \bTR \bTD test \eTD \bTD test \eTD \bTD test \eTD \eTR
+%D \bTR \bTD[nx=2] test \eTD \bTD test \eTD \eTR
+%D \bTR \bTD test \eTD \bTD[nx=2] test \eTD \eTR
+%D \eTABLE
+%D
+%D \bTABLE[option=stretch]
+%D \bTR \bTD test \eTD \bTD test \eTD \bTD test \eTD \eTR
+%D \bTR \bTD[nx=2] test \eTD \bTD test \eTD \eTR
+%D \bTR \bTD test \eTD \bTD[nx=2] test \eTD \eTR
+%D \eTABLE
+%D \stopbuffer
+%D
+%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection
+%D
+%D and he provided patches for the global left and right margin distances
+%D as well as the columndistance (although i changed the names -). Here
+%D is his testcase:
+%D
+%D \startbuffer
+%D \framed[offset=overlay]\bgroup
+%D \setupTABLE[column][2][align=left]%
+%D \setupTABLE[column][3][align=right]%
+%D \bTABLE[columndistance=2cm,leftmargindistance=.3cm,rightmargindistance=.5cm]
+%D \bTR \bTH[nc=3] Table head\eTH \eTR
+%D \bTR \bTD[nc=2] AB\eTD \bTD C\eTD \eTR
+%D \bTR \bTD[nc=2,align=left] AB\eTD \bTD C\eTD \eTR
+%D \bTR \bTD[nc=2,align=middle] AB\eTD \bTD C\eTD \eTR
+%D \bTR \bTD A\eTD \bTD B\eTD \bTD C\eTD \eTR
+%D \bTR \bTD Aa\eTD \bTD Bb\eTD \bTD Cccc\eTD \eTR
+%D \bTR \bTD[nc=3,align=middle] ABC\eTD \eTR
+%D \eTABLE
+%D \egroup
+%D \stopbuffer
+%D
+%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection
+
+\newtoks\TBLhead
+\newtoks\TBLnext
+\newtoks\TBLbody
+\newtoks\TBLfoot
+
+% to be done: head <raw> foot, dus state var
+
+\unexpanded\def\bTABLEhead{\dosingleempty\doTABLEhead} \let\eTABLEhead\relax
+\unexpanded\def\bTABLEnext{\dosingleempty\doTABLEnext} \let\eTABLEnext\relax
+\unexpanded\def\bTABLEbody{\dosingleempty\doTABLEbody} \let\eTABLEbody\relax
+\unexpanded\def\bTABLEfoot{\dosingleempty\doTABLEfoot} \let\eTABLEfoot\relax
+
+\long\def\doTABLEhead[#1]#2\eTABLEhead{\appendtoks\doTABLEsection[#1]{#2}\to\TBLhead}
+\long\def\doTABLEnext[#1]#2\eTABLEnext{\appendtoks\doTABLEsection[#1]{#2}\to\TBLnext}
+\long\def\doTABLEbody[#1]#2\eTABLEbody{\appendtoks\doTABLEsection[#1]{#2}\to\TBLbody}
+\long\def\doTABLEfoot[#1]#2\eTABLEfoot{\appendtoks\doTABLEsection[#1]{#2}\to\TBLfoot}
+
+\long\def\doTABLEsection[#1]#2%
+ {\def\setupTBLsection{\getparameters[\@@tbl\@@tbl][#1]}%
+ #2%
+ \let\setupTBLsection\relax}
+
+\let\pushTBL\relax
+\let\popTBL \relax
+
+\chardef\tblpass=0
+
+\def\presetallTABLEparameters% each odd|even level / can be sped up but only once per table
+ {\executeifdefined{\@@rawtblprefix\v!start\v!each}\relax
+ \executeifdefined{\@@rawtblprefix\v!start\v!oddeven\TBLlevel}\relax
+ \executeifdefined{\@@rawtblprefix\v!start\number\TBLlevel}\relax}
+
+\def\bTABLE
+ {\dosingleempty\dobTABLE}
+
+\def\dobTABLE[#1]%
+ {\pushTBL
+ % box not here
+ \bgroup
+ \TBLhead\emptytoks
+ \TBLnext\emptytoks
+ \TBLbody\emptytoks
+ \TBLfoot\emptytoks
+ \ifhmode\kern\zeropoint\fi % blocks \removeunwantedspaces: check this on icare handelingsschema
+ \resetcharacteralign % new
+ \getparameters
+ [\@@tbl\@@tbl]
+ [\c!align={\v!right,\v!broad,\v!high},#1]%
+ \hsize\tbltbltextwidth
+ \processaction
+ [\tbltblsplit]
+ [ \v!yes=>\enableTBLbreaktrue,
+ \v!repeat=>\enableTBLbreaktrue\multipleTBLheadstrue,
+ \v!auto=>\ifinsidesplitfloat\enableTBLbreaktrue\fi]
+ \processaction
+ [\tbltblheader]
+ [\v!repeat=>\multipleTBLheadstrue]%
+ \localcolortrue
+ \presetallTABLEparameters
+ \ExpandFirstAfter\processallactionsinset
+ [\tbltbloption]
+ [\v!stretch=>\autoTBLspreadtrue]%
+ \linewidth\tbltblrulethickness % needs to be frozen
+ \dontcomplain
+ \currentcol\zerocount
+ \maximumrowspan\plusone
+ \maximumcol\zerocount
+ \maximumrow\zerocount
+ \let\bTR\dobTR
+ \let\bTD\dobTD
+ \let\bTH\dobTH
+ \let\bTN\dobTN}
+
+\unexpanded\def\dobTR{\dodoubleempty\parseTR}
+\unexpanded\def\dobTD{\dodoubleempty\parseTD}
+\unexpanded\def\dobTH{\dodoubleempty\parseTH}
+\unexpanded\def\dobTN{\dodoubleempty\parseTN}
+
+% permits \expanded{\bTD ... \eTD}
+
+\unexpanded\def\eTR{\ignorespaces} % handy in case we use a macro to generate rows
+\unexpanded\def\eTD{\ignorespaces}
+\unexpanded\def\eTH{\ignorespaces}
+\unexpanded\def\eTN{\ignorespaces}
+
+\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode
+ {% tricky and dirty order -)
+ \doifsometokselse\TBLhead % slow, better a flag
+ {\the\TBLhead
+ \edef\noftblheadlines{\number\maximumrow}%
+ \doifsometokselse\TBLnext
+ {\the\TBLnext
+ \edef\noftblnextlines{\number\numexpr\maximumrow-\noftblheadlines\relax}}%
+ {\let\noftblnextlines\zerocount}% was 1
+ \edef\noftblhdnxlines{\number\maximumrow}}
+ {\let\noftblheadlines\zerocount % was 1
+ \let\noftblnextlines\zerocount
+ \let\noftblhdnxlines\zerocount}%
+ \the\TBLbody
+ \the\TBLfoot
+ \removeunwantedspaces % only if hmode
+ % finish cells
+ \dorecurse\maximumrow
+ {\row\recurselevel\relax
+ \dorecurse\maximumcol
+ {\col\recurselevel\relax
+ \doifnottbltag\row\col
+ {\xxcol\col
+ \xxrow\row
+ \xrow\row
+ \doloop
+ {\xcol\col
+ \doloop
+ {\doifelsetbltag\xrow\xcol \exitloop
+ {\advance\xcol\plusone
+ \ifnum\xcol>\maximumcol\relax \exitloop \fi}}%
+ \doifelsetbltag\xrow\xcol \exitloop
+ {\xxrow\xrow \xxcol\xcol \advance\xrow\plusone
+ \ifnum\xrow>\maximumrow \exitloop \fi}}%
+ \ifnum\xxrow>\maximumrow\xxrow\maximumrow\fi
+ \ifnum\xxcol>\maximumcol\xxcol\maximumcol\fi
+ \xxrow\numexpr\xxrow-\row+\plusone\relax
+ \xxcol\numexpr\xxcol-\col+\plusone\relax
+ \xrow\row
+ \dorecurse\xxrow
+ {\xcol\col \settblcol\xrow\xcol{\number\xxcol}%
+ \dorecurse\xxcol
+ {\lettbltag\xrow\xcol\tblnone \advance\xcol\plusone}%
+ \advance\xrow\plusone}%
+ \lettbltag\row\col\tblcell
+ \settblcol\row\col{\the\xxcol}%
+ \settblrow\row\col{\the\xxrow}%
+ \ifautoTBLemptycell
+ \edef\celltag{{\number\row}{\number\col}}%
+ \@EA\settbltxt\@EA\row\@EA\col\@EA{\@EA\handleTBLcell\celltag[]{\strut}}%
+ \fi}}}%
+ % to be sure
+ \dorecurse\maximumrow
+ {\row\recurselevel\relax
+ \dorecurse\maximumcol
+ {\col\recurselevel\relax
+ \doiftblrow\row\col
+ {\scratchcounter\numexpr\maximumrow-\row+\plusone\relax
+ \ifnum\gettblrow\row\col>\scratchcounter
+ \settblrow\row\col{\the\scratchcounter}%
+ \fi}%
+ \lettblht\row\col\zeropoint
+ \lettblwd\row\col\zeropoint
+ \doifnottblcol\row\col{\lettblcol\row\col\zerocount}%
+ \doifnottbltag\row\col{\lettbltag\row\col\tblnone}}}%
+ % check and do
+ \ifcase\maximumcol\else
+ \startTBLprocessing
+ \begTBL
+ \dorecurse\maximumrow
+ {\bTBL
+ \row\recurselevel\relax
+ \dorecurse\maximumcol
+ {\col\recurselevel\relax
+ \normalexpanded{\noexpand\doTBL{\number\row}{\number\col}}}%
+ \eTBL}%
+ \removeunwantedspaces % only if hmode
+ \endTBL
+ \stopTBLprocessing
+ % wrong ! ! ! better to have an auto-offset-overlay
+ % \ifnum\TBLlevel>1
+ % \vskip-\strutdp
+ % \fi
+ \fi
+ \egroup
+ \popTBL}
+
+\let\startTBLprocessing\relax
+\let\stopTBLprocessing \relax
+
+\newcount\prelocatedTBLrows % \prelocateTBLrows{1000} may speed up large tables
+
+\def\bTBL{\tblrowtoks\emptytoks}
+\def\eTBL{\tbltoks\@EA\@EA\@EA{\@EA\the\@EA\tbltoks\@EA\begintblrow\the\tblrowtoks\endtblrow}}%
+
+\def\prelocateTBLerror
+ {\writestatus\m!systems{fatal error: use \string\prelocateTBLrows\space to increase table memory (now: \number\prelocatedTBLrows)}}
+
+\def\prelocateTBLrows#1% we start at zero so we have one to much, better play safe anyway
+ {\dostepwiserecurse\prelocatedTBLrows{#1}\plusone{\expandafter\newtoks\csname tbl:\recurselevel\endcsname}%
+ \def\bTBL
+ {\ifnum\tblrow<\prelocatedTBLrows\relax
+ \@EA\let\@EA\tblrowtoks\csname tbl:\the\tblrow\endcsname\tblrowtoks\emptytoks
+ \else
+ \prelocateTBLerror
+ \fi}%
+ \def\eTBL
+ {\tbltoks\@EA\@EA\@EA{\@EA\the\@EA\tbltoks\@EA\begintblrow\@EA\the\csname tbl:\the\tblrow\endcsname\endtblrow}}%
+ \global\prelocatedTBLrows#1\relax}
+
+% \prelocateTBLrows{1000} % may speed up large tables
+
+% We use aligments to handle the empty (skipped) columns, so
+% that we don't have to (re|)|calculate these.
+
+\def\skiptblcol
+ {\global\advance\tblcol\plusone}
+
+\def\nexttblcol
+ {\global\advance\tblcol\plusone
+ \kern\tbltblcolumndistance
+ &}
+
+\def\spantblcol
+ {\span}
+
+\newcount\tblrow
+\newcount\tblcol
+
+\let\savedtblrow\!!zerocount
+\let\savedtblcol\!!zerocount
+
+\def\begintblrow
+ {\noalign
+ {\global\advance\tblrow\plusone
+ \global\tblcol\zerocount
+ \global\tblspn\zerocount}%
+ \nexttblcol
+ \kern\dimexpr\tbltblleftmargindistance-\tbltblcolumndistance\relax}
+
+\def\endtblrow
+ {\kern\dimexpr\tbltblrightmargindistance-\tbltblcolumndistance\relax
+ \crcr
+ \noalign
+ {\nointerlineskip
+ \ifnum\gettblnob\tblrow=\zerocount
+ \allowbreak
+ \fi
+ \bgroup % protect local vars
+ \@@tblsplitafter
+ \egroup
+ \bgroup % protect local vars
+ \scratchcounter\numexpr\tblrow+\plusone\relax
+ \ifnum\scratchcounter>\noftblhdnxlines\relax
+ \ifnum\scratchcounter<\maximumrow\relax
+ \doifsomething\tbltblspaceinbetween{\blank[\tbltblspaceinbetween]}%
+ \fi
+ \fi
+ \egroup}}
+
+\def\begintbl
+ {\global\tblspn\zerocount
+ \global\tblcol\zerocount
+ \global\tblrow\zerocount
+ \global\advance\tblrow\minusone
+ \tabskip\zeropoint
+ \halign\bgroup
+ \registerparoptions % new
+ \ignorespaces##\unskip&&\ignorespaces##\unskip\cr}
+
+\def\endtbl
+ {\egroup}
+
+\setvalue{\tblnone TBL}#1#2%
+ {\spanTBL{#1}{#2}}
+
+\setvalue{\tblcell TBL}#1#2%
+ {\tblrowtoks\expandafter{\the\tblrowtoks\makeTBL #1 #2 }% space delimited -> less tokens
+ \spanTBL{#1}{#2}}
+
+\def\spanTBL#1#2%
+ {\scratchcounter\gettblcol{#1}{#2}\relax
+ \ifnum\scratchcounter>\zerocount
+ \advance\scratchcounter \minusone
+ \dorecurse\scratchcounter{\tblrowtoks\expandafter{\the\tblrowtoks\spantblcol}}%
+ \dorecurse\scratchcounter{\tblrowtoks\expandafter{\the\tblrowtoks\skiptblcol}}%
+ \tblrowtoks\expandafter{\the\tblrowtoks\nexttblcol}%
+ \fi}
+
+\def\doTBL#1#2%
+ {\csname\gettbltag{#1}{#2}TBL\endcsname{#1}{#2}}
+
+\def\begTBL
+ {\global\tblspn\zerocount
+ \global\tblrow\zerocount
+ \global\tblcol\zerocount
+ \chardef\tblpass\zerocount
+ \tbltoks\emptytoks}
+
+\def\flushtbltoks{\begintbl\the\tbltoks\endtbl}
+
+\def\domakeTBLone#1 #2 %
+ {\gettbltxt{#1}{#2}}%
+
+\def\domakeTBLtwo#1 #2 % meer in cellD
+ {\scratchdimen\zeropoint
+ \scratchcounter\tblcol
+ \!!counta\gettblcol{#1}{#2}\relax
+ \dorecurse\!!counta
+ {\advance\scratchdimen\dimexpr\gettblwid\scratchcounter+\tbltblcolumndistance\relax
+ \ifnum\recurselevel<\!!counta \advance\scratchdimen \gettbldis\scratchcounter\fi
+ \advance\scratchcounter\plusone}%
+ \edef\widthTBL{\the\dimexpr\scratchdimen-\tbltblcolumndistance\relax}%
+ \setbox\scratchbox\hbox{\gettbltxt{#1}{#2}}%
+ \settblht{#1}{#2}{\the\ht\scratchbox}%
+ \settblwd{#1}{#2}{\the\wd\scratchbox}%
+ \ifdim\ht\scratchbox>\gettblhei{#1}\relax
+ \settblhei{#1}{\the\ht\scratchbox}%
+ \fi}%
+
+\def\domakeTBLthree#1 #2 %
+ {% height
+ \!!counta \gettblcol{#1}{#2}\relax
+ \!!countb \gettblrow{#1}{#2}\relax
+ \!!heighta\gettblht {#1}{#2}\relax
+ \scratchdimen\zeropoint
+ \ifnum\!!counta=\maximumcol\relax
+ % case: nc=maxcolumns
+ \else
+ \scratchcounter#1\relax
+ \dorecurse\!!countb
+ {\advance\scratchdimen
+ \gettblhei\scratchcounter
+ \advance\scratchcounter\plusone}%
+ \ifdim\scratchdimen<\!!heighta\relax
+ \scratchdimen\!!heighta
+ \fi
+ \fi
+ \edef\heightTBL{\the\scratchdimen}%
+ % width
+ \scratchdimen\zeropoint
+ \scratchcounter\tblcol
+ \dorecurse\!!counta
+ {\advance\scratchdimen\dimexpr\gettblwid\scratchcounter+\tbltblcolumndistance\relax
+ \ifnum\recurselevel<\!!counta \advance\scratchdimen \gettbldis\scratchcounter\fi
+ \advance\scratchcounter\plusone}%
+ \edef\widthTBL{\the\dimexpr\scratchdimen-\tbltblcolumndistance\relax}%
+ % cell
+ \setbox\scratchbox\hbox{\gettbltxt{#1}{#2}}%
+ \ifnum\!!counta=\maximumcol\relax
+ % case: nc=maxcolumns
+ \else
+ \scratchdimen\gettblhei{#1}%
+ \setbox\scratchbox\hbox
+ {\lower\ht\scratchbox\hbox{\raise\scratchdimen\box\scratchbox}}%
+ \ht\scratchbox\scratchdimen
+ \fi
+ \dp\scratchbox\zeropoint
+ \edef\!!stringa{\gettblref{#1}{#2}}%
+ \ifx\!!stringa\empty
+ \box\scratchbox
+ \else
+ \normalexpanded{\noexpand\gotobox{\box\scratchbox}[\!!stringa]}%
+ \fi
+ \box\scratchbox}
+
+\def\inTBLcell#1#2% hm, do we need #1 #2 ? we use tblcol anyway
+ {\ExpandBothAfter\doifinsetelse\localwidth{\v!fit,\v!broad} % user set
+ {}
+ {\scratchdimen\gettblaut\tblcol\relax
+ \ifdim\localwidth>\scratchdimen
+ \settblaut\tblcol{\the\dimexpr\localwidth\relax}%
+ \fi}}%
+
+\def\endTBL
+ {\setbox\scratchbox\hbox
+ {\localframed
+ [\@@tbl\@@tbl]
+ [\c!frame=\v!off,\c!background=,\c!align=\v!no]
+ {\strut}}%
+ \edef\minimalcellheight{\the\ht\scratchbox}%
+ \dorecurse\maximumcol
+ {\lettblaut\recurselevel\zeropoint
+ % new
+ \xcol\recurselevel\relax
+ \dorecurse\maximumrow
+ {\lettblwd\recurselevel\xcol\zeropoint
+ \lettblht\recurselevel\xcol\zeropoint}%
+ % till here
+ \lettblwid\recurselevel\zeropoint
+ \lettbldis\recurselevel\zeropoint}%
+ \dorecurse\maximumrow
+ {\lettblhei\recurselevel\maxdimen}%
+ \chardef\tblpass\plusone
+ \let\makeTBL\domakeTBLone
+ \let\handleTBLcell\dohandleTBLcellA
+ \setbox0\vbox{\trialtypesettingtrue \flushtbltoks}%
+% \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}%
+ \lettbldis\maximumcol\zeropoint
+ \ifautoTBLspread
+ % experimental, stretch non fixed cells to \hsize
+ \checktblwidthsone % trial run
+ \checktblwidthstwo % real run
+ \stretchtblwidths
+ \let\handleTBLcell\dohandleTBLcellB
+ \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}%
+ \else\ifdim\wd0>\hsize
+ \ifautoTBLhsize
+ \checktblwidthsone % trial run
+ \checktblwidthstwo % real run
+ \let\handleTBLcell\dohandleTBLcellB
+ \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}%
+ \fi
+ \else\ifautoTBLrowspan\ifnum\maximumrowspan>1 % max ?
+ % added jan 2002 because nx=* did no longer work
+ \edef\savedhsize{\the\hsize}%
+ \hsize\wd0\relax % new per 17/04/2006
+ \checktblwidthsone % trial run
+ \checktblwidthstwo % real run
+ \hsize\savedhsize
+ %
+ \let\handleTBLcell\dohandleTBLcellC
+ \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}%
+ \fi\fi\fi\fi
+ \let\handleTBLcell\dohandleTBLcellD
+ \chardef\tblpass\plustwo
+ \let\makeTBL\domakeTBLtwo
+ \setbox\scratchbox\vbox{\trialtypesettingtrue \flushtbltoks}%
+ \checktblheightsone
+ \checktblheightstwo
+ \let\handleTBLcell\dohandleTBLcellE
+ \chardef\tblpass\plusthree
+ \let\makeTBL\domakeTBLthree
+ \ifnum\TBLlevel>\plusone
+ \@EA\notsplittblbox
+ \else\ifenableTBLbreak
+ \@EAEAEA\splittblbox
+ \else
+ \@EAEAEA\notsplittblbox
+ \fi\fi{\flushtbltoks}}
+
+\def\stretchtblwidths % more variants, e.g. a max to \dimend
+ {\ifcase\maximumcol\else % else division by zero
+ \!!dimend\zeropoint
+ \!!dimene\hsize
+ \dorecurse\maximumcol
+ {\advance\!!dimend\dimexpr\gettblwid\recurselevel+\tbltblcolumndistance\relax
+ \advance\!!dimene-\gettbldis\recurselevel}%
+ \advance\!!dimend\dimexpr-\tbltblcolumndistance+\tbltblleftmargindistance+\tbltblrightmargindistance\relax
+ % distribute width (stretch)
+ \ifdim\!!dimend<\!!dimene
+ \advance\!!dimend-\!!dimene
+ \!!dimend-\!!dimend
+ \divide\!!dimend\maximumcol
+ \dorecurse\maximumcol
+ {\settblwid\recurselevel{\the\dimexpr\gettblwid\recurselevel+\!!dimend\relax}}%
+ \fi
+ \fi}
+
+\newbox\finaltblbox
+
+\def\notsplittblbox#1%
+ {\setbox\finaltblbox\vbox{#1}%
+ \postprocessTABLEbox\finaltblbox
+ \beforeTABLEbox
+ \box\finaltblbox
+ \afterTABLEbox}
+
+\def\splittblbox#1%
+ {\ifinsidesplitfloat
+ \donetrue
+ \else\ifinsidefloat
+ \donefalse
+ \else
+ \donetrue
+ \fi\fi
+ \ifdone
+ \executeifdefined{dosplittblbox\tbltblsplitmethod}\dosplittblbox{#1}%
+ \else
+ \notsplittblbox{#1}%
+ \fi}
+
+\newbox\TABLEsplitbox % public, don't change
+
+\let\extratblsplitheight\zeropoint % additional space taken by before/afterTABLEsplitbox
+
+\def\dosplittblbox#1%
+ {\resettsplit
+ \def\tsplitminimumfreelines{2}%
+ \def\tsplitminimumfreespace{\dimexpr\extratblsplitheight+\tbltblsplitoffset\relax}%
+ \def\tsplitbeforeresult {\beforeTABLEsplitbox}%
+ \def\tsplitafterresult {\afterTABLEsplitbox}%
+ \def\tsplitafter {\@@tblsplitafter}%
+ \setbox\tsplitcontent\vbox{#1}%
+ \ifmultipleTBLheads
+ \dorecurse\noftblheadlines
+ {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight
+ \setbox\tsplithead\vbox{\unvcopy\tsplithead\unvcopy\scratchbox}}%
+ \dorecurse\noftblnextlines
+ {\setbox\scratchbox\vsplit\tsplitcontent to \lineheight
+ \setbox\tsplitnext\vbox{\unvcopy\tsplitnext\unvcopy\scratchbox}}%
+ \fi
+ \doifsomething\tbltblspaceinbetween
+ {\def\tsplitinbetween{\blank[\tbltblspaceinbetween]}}%
+ \def\postprocesstsplit{\postprocessTABLEsplitbox{\box\tsplitresult}}%
+ \handletsplit}
+
+% ! ! ! ! TODO: naast \postprocessTABLEsplitbox ook evt \postprocessTABLEbox voor niet split
+
+\let\postprocessTABLEsplitbox\gobbleoneargument
+\let\postprocessTABLEbox \gobbleoneargument
+
+\let\beforeTABLEsplitbox\relax
+\let\afterTABLEsplitbox \relax
+\let\beforeTABLEbox \relax
+\let\afterTABLEbox \relax
+
+\def\checktblwidthsone{\dochecktblwidths0} % 0 = trial run
+\def\checktblwidthstwo{\dochecktblwidths1} % 1 = real run
+
+\def\dochecktblwidths#1%
+ {\iftraceTABLE\showtblwids{B#1}\fi
+ \!!counta\zerocount
+ \!!dimena\dimexpr\hsize-\tbltblleftmargindistance-\tbltblrightmargindistance-\tbltblcolumndistance\relax
+ \dorecurse\maximumcol
+ {\scratchdimen\gettblaut\recurselevel\relax
+ \advance\!!dimena-\gettbldis\recurselevel\relax
+ \ifdim\scratchdimen>\zeropoint\relax
+ \advance\!!dimena -\scratchdimen
+ \else
+ \scratchdimen\gettblwid\recurselevel\relax
+ \ifdim\scratchdimen>\tbltblmaxwidth\relax
+ \ifcase#1\else\lettblwid\recurselevel\zeropoint\fi
+ \advance\!!counta \plusone
+ \else
+ \ifdim\scratchdimen>\zeropoint\relax
+ \advance\!!dimena -\scratchdimen
+ \else
+ % eigenlijk moet dit alleen als de kolom wordt overspannen door een
+ % vorige, maw extra dubbele loop en status var
+ \advance\!!counta \plusone
+ \fi
+ \fi
+ \fi}%
+ \ifcase\!!counta \else \divide\!!dimena \!!counta \fi
+ \dorecurse\maximumcol
+ {\scratchdimen\gettblwid\recurselevel\relax
+ \ifcase#1\relax
+ \ifdim\scratchdimen<\!!dimena % take natural width
+ \settblaut\recurselevel{\the\scratchdimen}%
+ \fi
+ \else
+ \ifdim\scratchdimen=\zeropoint % auto set width
+ \settblwid\recurselevel{\the\!!dimena}%
+ \fi
+ \fi}%
+ \iftraceTABLE\showtblwids{E#1}\fi}
+
+\newcount\xrowTBL
+\newcount\xcolTBL
+\newcount\xxrowTBL
+
+% dikke arg naar recurse wegwerken
+
+\def\dochecktblheightsone
+ {\!!countb\gettblrow\xrowTBL\xcolTBL\relax
+ % check row span
+ \ifnum\!!countb>\plusone
+ % current height in row
+ \dimen0=\gettblht\xrowTBL\xcolTBL
+ % find nearest height in row
+ \dimen2=\zeropoint
+ \dorecurse\maximumcol
+ {\ifnum\recurselevel=\xcolTBL\else
+ \doiftblrow\xrowTBL\recurselevel
+ {\!!countc=\gettblrow\xrowTBL\recurselevel\relax
+ \ifnum\!!countc=\plusone
+ \dimen4=\gettblht\xrowTBL\recurselevel\relax
+ \ifdim\dimen2<\dimen4
+ \dimen2=\dimen4
+ \fi
+ \fi}%
+ \fi}%
+ \xxrowTBL\xrowTBL
+ % calculate cummulative height
+ \dimen4=\dimen2
+ \!!countc\xrowTBL
+ \advance\!!countc\minusone
+ \dorecurse\!!countb
+ {\ifnum\xxrowTBL=\xrowTBL\else
+ \advance\dimen4 \gettblhei\xxrowTBL
+ \fi
+ \ifnum\recurselevel=\!!countb\else
+ \settblnob\!!countc
+ \advance\!!countc\plusone
+ \fi
+ \advance\xxrowTBL\plusone}%
+ % distribute overshoot equally
+ \ifdim\dimen4<\dimen0
+ \advance\dimen0 -\dimen4
+ \divide\dimen0 \!!countb
+ \xxrowTBL\xrowTBL
+ \settblhei\xrowTBL{\the\dimen2}%
+ \dorecurse\!!countb
+ {\dorecurse\maximumcol
+ {\ifnum\recurselevel=\xcolTBL\else
+ \scratchdimen\dimexpr\gettblht\xxrowTBL\recurselevel+\dimen0\relax
+ \settblht\xxrowTBL\recurselevel{\the\scratchdimen}%
+ \ifdim\gettblhei\xxrowTBL<\scratchdimen
+ \settblhei\xxrowTBL{\the\scratchdimen}%
+ \fi
+ \fi}%
+ \advance\xxrowTBL\plusone}%
+ \else\ifdim\dimen4>\dimen0
+ \settblhei\xrowTBL{\the\dimen2}%
+ \fi\fi
+ \fi}
+
+\def\checktblheightsone
+ {\dorecurse\maximumrow
+ {\xrowTBL\recurselevel\relax
+ \dorecurse\maximumcol
+ {\xcolTBL\recurselevel\relax
+ \doiftblrow\xrowTBL\xcolTBL\dochecktblheightsone}}}
+
+\def\checktblheightstwo
+ {}
+
+\def\showtblwids#1%
+ {\vbox
+ {\forgetall\tttf[#1]\dorecurse\maximumcol
+ {\scratchdimen\gettblwid\recurselevel\relax
+ [\recurselevel:\the\scratchdimen]}}}
+
+\def\TBLcharalign
+ {\doifelse\tbltblaligncharacter\v!yes
+ \doTBLcharalign\gobbleoneargument}
+
+\long\def\doTBLcharalign#1#2% column data
+ {\edef\alignmentclass{#1}%
+ \edef\alignmentcharacter{\tbltblalignmentcharacter}%
+ \ifcase\tblpass\or
+ \setfirstpasscharacteralign\checkalignment{#2}% {\strut#2\unskip}%
+ \fi % force hsize, so always a second
+ \setsecondpasscharacteralign \checkalignment{#2}% {\strut#2\unskip}%
+ \ignorespaces}
+
+% new, needed for icare first col of 'doeltabel', experimental
+
+\long\def\dohandleTBLcellA#1#2[#3]#4% grouping added ! ! !
+ {\bgroup
+ \setupTBLcell{#1}{#2}%
+ \setbox\scratchbox\hbox
+ {\scratchdimen\tbltbldistance\relax
+ \ifdim\scratchdimen>\gettbldis{#2}\relax
+ \settbldis{#2}{\the\scratchdimen}%
+ \fi
+ \localframed
+ [\@@tbl\@@tbl]
+ [#3,\c!background=,\c!frame=\v!off]% 25% faster
+ {\bTBLCELL\TBLcharalign{#2}{#4}\eTBLCELL\inTBLcell{#1}{#2}}}%
+ \scratchdimen\gettblwid\tblcol\relax
+ \ifdim\wd\scratchbox>\scratchdimen
+ \ifsqueezeTBLspan
+ \ifautosqueezeTBLspan
+ \doifinsetelse\tbltblwidth{\v!fit,\v!fixed,\v!broad,\v!local}
+ \donetrue \donefalse
+ \else
+ \donetrue
+ \fi
+ \ifdone % brr, 0
+ \ifnum\number\gettblcol{#1}{#2}>\plusone \settblspn\tblcol\fi
+ \fi
+ \fi
+ \doifelsetblspn\tblcol
+ \donothing
+ {\ifdim\gettblwid\tblcol<\wd\scratchbox
+ \settblwid\tblcol{\the\wd\scratchbox}%
+ \fi}% auto set
+ \fi
+ \scratchcounter\numexpr\tblrow+\plusone\relax
+ \scratchdimen\gettblhei\scratchcounter\relax
+ \ifdim\ht\scratchbox<\scratchdimen
+ \settblhei\scratchcounter{\the\ht\scratchbox}% auto set
+ \fi
+ \settblht{#1}{#2}{\the\ht\scratchbox}%
+ \settblwd{#1}{#2}{\the\wd\scratchbox}%
+ \ifautoTBLcheckwidth
+ \ifdim\wd\scratchbox<.75\hsize
+ \ifdim\ht\scratchbox>2\openlineheight % honor width since this
+ \scratchdimen\gettblaut\tblcol\relax % can be a figure or so
+ \ifdim\scratchdimen=\zeropoint
+ % side effect: when width is set to 0pt,
+ % we can force a span that fits the sum of spans widths
+ \settblaut\tblcol{\the\scratchdimen}%
+ \else\ifdim\wd\scratchbox>\scratchdimen
+ % unless span
+ \settblaut\tblcol{\the\wd\scratchbox}%
+ % to be translated
+ \writestatus\m!TABLE
+ {no auto width in (\number#1,\number#2)\space\the\wd\scratchbox/\the\hsize}%
+ \fi\fi
+ \fi
+ \fi
+ \fi
+ \setbox2\null
+ \wd2\wd\scratchbox \ht2\ht\scratchbox \dp2\dp\scratchbox
+ \box2
+ \egroup}
+
+\long\def\dohandleTBLcellBC#1#2#3[#4]#5%
+ {\setbox\scratchbox\hbox
+ {\setupTBLcell{#2}{#3}%
+ \localframed
+ [\@@tbl\@@tbl]
+ [#4,#1,\c!frame=\v!off,\c!background=]
+ {\bTBLCELL#5\eTBLCELL}}%
+ \setbox2\null
+ \wd2\wd\scratchbox \ht2\ht\scratchbox \dp2\dp\scratchbox
+ \ifautoTBLrowspan
+ \scratchcounter\numexpr\tblrow+\plusone\relax
+ \doiftblrow\scratchcounter\tblcol
+ {\scratchdimen\gettblhei\scratchcounter\relax % moved inside test
+ \ifnum\gettblrow\scratchcounter\tblcol>\plusone \ifdim\ht\scratchbox>\scratchdimen
+ \scratchdimen-\scratchdimen \advance\scratchdimen -\ht\scratchbox
+ \ht2\scratchdimen
+ \fi \fi}%
+ \fi
+ \box2 }
+
+\long\def\dohandleTBLcellB#1#2[#3]#4%
+ {\scratchdimen\gettblaut\tblcol\relax
+ \ifdim\scratchdimen>\zeropoint\relax
+ \let\tblwidthkey\c!width
+ \edef\tblwidth{\the\scratchdimen}%
+ \else
+ \scratchdimen\gettblwid\tblcol\relax
+ \ifdim\scratchdimen>\zeropoint\relax
+ \ifnum\gettblcol{#1}{#2}=\maximumcol\relax
+ \scratchdimen\hsize
+ \fi
+ \let\tblwidthkey\c!width
+ \edef\tblwidth{\the\scratchdimen}%
+ \else
+ \let\tblwidthkey\s!unknown
+ \let\tblwidth\zeropoint
+ \fi
+ \fi
+ \dohandleTBLcellBC{\tblwidthkey=\tblwidth}{#1}{#2}[#3]{\TBLcharalign{#2}{#4}}}
+
+\long\def\dohandleTBLcellC
+ {\dohandleTBLcellBC{}}
+
+\long\def\dohandleTBLcellD#1#2[#3]#4%
+ {\setupTBLcell{#1}{#2}%
+ \bgroup
+ \localframed
+ [\@@tbl\@@tbl]
+ [#3,\c!width=\widthTBL,\c!background=,\c!frame=\v!off]% 25% faster
+ {\bTBLCELL\TBLcharalign{#2}{#4}\eTBLCELL}%
+ \egroup}
+
+\long\def\dohandleTBLcellE#1#2[#3]#4%
+ {\setupTBLcell{#1}{#2}%
+ \getparameters[\@@tbl\@@tbl][#3]% to get the color right, the way we
+ \color % handle color here prevents interference due to whatsit nodes
+ [\tbltblcolor] % as well as permits local colors to take precedence
+ {\ifdim\heightTBL=\zeropoint\relax % case: nc=maxcolumns
+ \localframed
+ [\@@tbl\@@tbl]
+ [\c!color=,\c!width=\widthTBL]
+ {\bTBLCELL\TBLcharalign{#2}{#4}\eTBLCELL}%
+ \else
+ \localframed
+ [\@@tbl\@@tbl]
+ [\c!color=,\c!width=\widthTBL,\c!height=\heightTBL]
+ {\bTBLCELL\TBLcharalign{#2}{#4}\eTBLCELL}%
+ \fi}%
+ \hskip\gettbldis{#2}}
+
+\presetlocalframed
+ [\@@tbl\@@tbl]
+
+\setupTABLE [%
+ \c!frameoffset=.5\linewidth,
+ \c!backgroundoffset=\v!frame,
+ \c!framecolor=\s!black,
+ \c!width=\v!fit,
+ \c!height=\v!fit,
+ \c!autowidth=\v!yes,
+ \c!rulethickness=\linewidth,
+ \c!strut=\v!yes,
+ \c!autostrut=\v!no,
+ %
+ \c!color=,
+ \c!style=,
+ \c!headstyle=\v!bold,
+ \c!headcolor=,
+ \c!aligncharacter=\v!no,
+ \c!alignmentcharacter={,},
+ \c!option=, % \v!stretch
+ \c!header=,
+ \c!spaceinbetween=,
+ \c!maxwidth=8em,
+ \c!textwidth=\hsize,
+ \c!split=\v!auto,
+ \c!splitoffset=0pt,
+ \c!distance=\zeropoint, % individual column
+ \c!columndistance=\zeropoint, % each column (whole table)
+ \c!leftmargindistance=\zeropoint, % whole table
+ \c!rightmargindistance=\zeropoint,% whole table
+ \c!left=,
+ \c!right=,
+ \c!splitmethod=a%
+]
+
+%D We have already prepared the previous macros for nesting,
+%D so we only have to pop in the right ones:
+
+%D New:
+
+\def\pushTBLparameters
+ {\globalpushmacro\TBLlevel
+ \ifcase\tblpass
+ % we're just after \bTABLE
+ \else\ifnum\TBLlevel>\zerocount
+ \doglobal\increment\TBLlevel\relax
+ \fi\fi}
+
+\def\popTBLparameters
+ {\globalpopmacro\TBLlevel}
+
+\def\pushTBL
+ {\ifnum\TBLlevel=\zerocount
+ \global\advance\currenttbl\plusone
+ \fi
+ \doglobal\increment\TBLlevel\relax
+ \ifnum\TBLlevel>\plusone
+ \resetallTABLEparameters
+ % we need a proper count push/pop
+ \xdef\savedtblrow{\the\tblrow}\globalpushmacro\savedtblrow
+ \xdef\savedtblcol{\the\tblcol}\globalpushmacro\savedtblcol
+ \else
+ \global\intabletrue
+ \fi}
+
+\def\popTBL
+ {\ifnum\TBLlevel>\plusone
+ \globalpopmacro\savedtblrow\global\tblrow\savedtblrow
+ \globalpopmacro\savedtblcol\global\tblcol\savedtblcol
+ \else
+ \global\intablefalse
+ \fi
+ \doglobal\decrement\TBLlevel\relax}
+
+% \bgroup
+% \setupTABLE[column][1][aligncharacter=yes, alignmentcharacter={,}]
+% \bTABLE
+% \bTR \bTD 1,2 \eTD \bTD 2 \eTD \eTR
+% \bTR \bTD 11,2 \eTD \bTD
+% {\setupTABLE[column][1][aligncharacter=yes, alignmentcharacter={,}]
+% \bTABLE
+% \bTR \bTD 1,2 \eTD \bTD 2 \eTD \eTR
+% \bTR \bTD 11,22 \eTD \bTD 2 \eTD \eTR
+% \bTR \bTD 11,2 \eTD \bTD 2 \eTD \eTR \eTABLE} \eTD \eTR
+% \bTR \bTD 11,22 \eTD \bTD 2 \eTD \eTR
+% \eTABLE
+% \egroup
+
+\newconditional\resetTABLEmode \settrue\resetTABLEmode
+
+\def\resetallTABLEparameters% moet genest wel werken
+ {\ifnum\TBLlevel>\plusone % in ieder geval
+ \ifconditional\resetTABLEmode
+% \presetlocalframed % breedte hoogte diepte offset
+% [\@@tbl\@@tbl]% % achtergrond, achtergrondraster, achtergrondkleur
+ % not ok yet
+ \setupTABLE [%
+ \c!frameoffset=.5\linewidth,
+ \c!backgroundoffset=\v!frame,
+ \c!framecolor=\s!black,
+ \c!width=fit,
+ \c!height=fit,
+\c!autowidth=\v!yes,
+% \c!rulethickness=\linewidth,
+ \c!strut=\v!no,
+\c!strut=\v!yes, % needed for mathml, but ... maybe we need another resetTABLEmode
+\c!autostrut=\v!no,
+ \c!color=,
+ \c!style=,
+ \c!headstyle=,
+ \c!headcolor=,
+ \c!aligncharacter=\v!no,
+ \c!alignmentcharacter={,},
+ \c!maxwidth=8em]%
+ \else
+ \setupTABLE
+ [\c!width=\v!fit,
+ \c!height=\v!fit]%
+ \fi
+ \fi}
+
+%D Spacing:
+%
+% \starttabulate
+% \NC text \NC text \NC \NR
+% \TB[small]
+% \NC text \NC text \NC \NR
+% \TB[4*big]
+% \NC text \NC text \NC \NR
+% \stoptabulate
+%
+% \starttable[|||]
+% \VL text \VL text \VL \AR
+% \TB[small]
+% \VL text \VL text \VL \AR
+% \TB[4*big]
+% \VL text \VL text \VL \AR
+% \stoptable
+
+\def\complexTableTB[#1]{\TABLEnoalign{\blank[#1]}}
+\def\simpleTableTB {\TABLEnoalign{\blank}}
+
+\def\TabulateTB
+ {\complexorsimpleTable{TB}}
+
+\def\doTableinterline% #1
+ {\ifnum\currentTABLEcolumn>\maxTABLEcolumn
+ \chuckTABLEautorow
+ \else\ifnum\currentTABLEcolumn=\zerocount
+ \TABLEnoalign
+ {\globalletempty\checkTABLEautorow
+ \globalletempty\chuckTABLEautorow}%
+ \else
+ \setTABLEerror\TABLEmissingcolumn
+ \handleTABLEerror
+ \fi\fi
+ \complexorsimpleTable} % {#1}
+
+\def\TableHL{\doTableinterline{HL}}
+\def\TableTB{\doTableinterline{TB}}
+
+\appendtoks\let\TB\TableTB \to\everytable
+\appendtoks\let\TB\TabulateTB\to\everytabulate % strange place
+
+\appendtoks \chardef\recodeverbatimmode\plustwo \to \everytable
+
+% new (for Olivier Turlier)
+%
+% \defineTABLEsetup [xx] [foregroundcolor=red]
+%
+% \bTABLE
+% \bTR \bTD oeps \eTD \bTD oeps \eTD \eTR
+% \bTR \bTDs[xx] oeps \eTDs \bTD oeps \eTD \eTR
+% \bTRs[xx] \bTD oeps \eTD \bTD oeps \eTD \eTRs
+% \eTABLE
+
+\def\defineTABLEsetup
+ {\dodoubleargument\dodefineTABLEsetup}
+
+\def\dodefineTABLEsetup[#1][#2]%
+ {\setvalue{\@@tbl:set:#1}{#2}}
+
+\long\def\bTDs[#1]#2\eTDs
+ {\doifdefinedelse{\@@tbl:set:#1}
+ {\@EA\@EA\@EA\bTD\@EA\@EA\@EA[\csname\@@tbl:set:#1\endcsname]#2\eTD}
+ {\bTD[]#2\eTD}}
+
+\long\def\bTRs[#1]#2\eTRs
+ {\doifdefinedelse{\@@tbl:set:#1}
+ {\@EA\@EA\@EA\bTR\@EA\@EA\@EA[\csname\@@tbl:set:#1\endcsname]#2\eTR}
+ {\bTR[]#2\eTR}}
+
+\protect \endinput
+
+% todo: mode: first|next (of niets)
diff --git a/tex/context/base/tabl-nte.tex b/tex/context/base/tabl-nte.tex
new file mode 100644
index 000000000..cde64a033
--- /dev/null
+++ b/tex/context/base/tabl-nte.tex
@@ -0,0 +1,107 @@
+%D \module
+%D [ file=core-nte,
+%D version=2009.03.08,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Natural Tables Extensions,
+%D author=Hans Hagen \& Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%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 Table Module / Natural Tables Extensions}
+
+\unprotect
+
+%D This module is suggested by Wolfgang Schuster who also prototyped
+%D it and came up with the rationale:
+%D
+%D This module provides an easy way to use natural in a similiar
+%D way as the older table module (based on the \TABLE\ macros) and
+%D the newer tabulate module.
+%D
+%D You can see the advantage in the following table, once created
+%D with the new macros and once with the normal macros provided
+%D with the natural table module.
+%D
+%D Let us start with the original macros:
+%D
+%D \starttyping
+%D \bTABLE
+%D \bTR
+%D \bTD Text 1 \eTD
+%D \bTD Text 2 \eTD
+%D \eTR
+%D \bTR
+%D \bTD Text 3 \eTD
+%D \bTD Text 4 \eTD
+%D \eTR
+%D \eTABLE
+%D \stoptyping
+%D
+%D Watch how the new macros use less code:
+%D
+%D \starttyping
+%D \startTABLE
+%D \NC Text 1 \NC Text 2 \NC\NR
+%D \NC Text 3 \NC Text 4 \NC\NR
+%D \stopTABLE
+%D \stoptyping
+%D
+%D The actual code differs from the prototype that it does not need
+%D to collect whole rows and parse them but looks ahead instead.
+
+\def\startTABLE
+ {\dosingleempty\dostartTABLE}
+
+\def\dostartTABLE[#1]%
+ {\bgroup
+ \bTABLE[#1]%
+ \let\NC\doTABLENC
+ \let\NR\doTABLENR
+ \let\bTR\relax
+ \let\bTD\relax
+ \let\bTH\relax
+ \let\bTN\relax}
+
+\def\stopTABLE
+ {\eTABLE
+ \egroup}
+
+\newconditional\inTABLEnc
+
+\unexpanded\def\doTABLENR
+ {\eTR
+ \setfalse\inTABLEnc}
+
+\unexpanded\def\doTABLENC
+ {\futurelet\next\dodoTABLENC}
+
+\def\dodoTABLENC
+ {\ifx\next\doTABLENR \else
+ \expandafter\dododoTABLENC
+ \fi}
+
+% \long\def\dododoTABLENC#1\NC
+% {\ifconditional\inTABLEnc\else\settrue\inTABLEnc\parseTR[][]\fi
+% \parseTD[][]#1\eTD\NC}
+
+\long\def\dododoTABLENC#1\NC
+ {\ifconditional\inTABLEnc\else\settrue\inTABLEnc\parseTR[][]\fi
+ \dodoubleempty\parseTD#1\eTD\NC}
+
+%D The related structure commands are also available:
+
+\unexpanded\def\startTABLEhead{\dosingleempty\dostartTABLEhead} \let\stopTABLEhead\relax
+\unexpanded\def\startTABLEnext{\dosingleempty\dostartTABLEnext} \let\stopTABLEnext\relax
+\unexpanded\def\startTABLEbody{\dosingleempty\dostartTABLEbody} \let\stopTABLEbody\relax
+\unexpanded\def\startTABLEfoot{\dosingleempty\dostartTABLEfoot} \let\stopTABLEfoot\relax
+
+\long\def\dostartTABLEhead[#1]#2\stopTABLEhead{\appendtoks\doTABLEsection[#1]{#2}\to\TBLhead}
+\long\def\dostartTABLEnext[#1]#2\stopTABLEnext{\appendtoks\doTABLEsection[#1]{#2}\to\TBLnext}
+\long\def\dostartTABLEbody[#1]#2\stopTABLEbody{\appendtoks\doTABLEsection[#1]{#2}\to\TBLbody}
+\long\def\dostartTABLEfoot[#1]#2\stopTABLEfoot{\appendtoks\doTABLEsection[#1]{#2}\to\TBLfoot}
+
+\protect \endinput
diff --git a/tex/context/base/tabl-pln.tex b/tex/context/base/tabl-pln.tex
new file mode 100644
index 000000000..39bb50f23
--- /dev/null
+++ b/tex/context/base/tabl-pln.tex
@@ -0,0 +1,91 @@
+%D The following bunch of macros come from plain \TEX\ by
+%D Don Knuth and deal with basic alignment. We just include
+%D them here so that they can be used if needed. Normally,
+%D \CONTEXT\ users will fall back on one of the three table
+%D environments.
+%D
+%D The hidden names are somewhat adapted and we use other
+%D local variables.
+
+\writestatus{loading}{ConTeXt Table Macros / Plain Tabular}
+
+\unprotect
+
+\newif \if@@plnusetab
+\newif \if@@plncr
+\newbox \@@plntabs
+\newbox \@@plntabsyet
+\newbox \@@plntabsdone
+\newdimen \@@plntabdimen
+
+\def\cleartabs % visible
+ {\global\setbox\@@plntabsyet\null
+ \setbox\@@plntabs\null}
+
+\def\settabs % visible
+ {\setbox\@@plntabs\null
+ \futurelet\next\@@plnsettabs}
+
+\def\tabalign % visible
+ {\@@plnusetabtrue\@@plnmaketabbox}
+
+\let\+\tabalign % no outer here (can be overloaded)
+
+\def\@@plnsettabs
+ {\ifx\next\+%
+ \def\nxt{\afterassignment\@@plnsettab\let\nxt}%
+ \else
+ \let\nxt\@@plnsetcols
+ \fi
+ \let\next\relax
+ \nxt}
+
+\def\@@plnsettab
+ {\let\nxt\relax
+ \@@plnusetabfalse\@@plnmaketabbox}
+
+\def\@@plnsetcols#1\columns
+ {\scratchcounter#1%
+ \@@plntabdimen\hsize
+ \loop
+ \ifnum\scratchcounter>\zerocount \@nother
+ \repeat}
+
+\def\@nother
+ {\scratchdimen\@@plntabdimen
+ \divide\scratchdimen\scratchcounter
+ \setbox\@@plntabs\hbox{\hbox to\scratchdimen{}\unhbox\@@plntabs}%
+ \advance\@@plntabdimen-\scratchdimen
+ \advance\scratchcounter\minusone}
+
+\def\@@plnmaketabbox
+ {\begingroup
+ \global\setbox\@@plntabsyet\copy\@@plntabs
+ \global\setbox\@@plntabsdone\null
+ \def\cr
+ {\@@plncrtrue\crcr\egroup\egroup
+ \if@@plnusetab\unvbox\zerocount\lastbox\fi\endgroup
+ \setbox\@@plntabs\hbox{\unhbox\@@plntabsyet\unhbox\@@plntabsdone}}%
+ \setbox\zerocount\vbox\bgroup\@@plncrfalse
+ \ialign\bgroup&\@@plnbegintabbox##\@@plnendtabbox\crcr}
+
+\def\@@plnbegintabbox
+ {\setbox\zerocount\hbox\bgroup}
+
+\def\@@plnendtabbox
+ {\if@@plncr
+ \egroup % now \box\zerocount holds the column
+ \else
+ \hss\egroup
+ \global\setbox\@@plntabsyet\hbox
+ {\unhbox\@@plntabsyet\global\setbox\plusone\lastbox}% now \box\plusone holds its size
+ \ifvoid\plusone
+ \global\setbox\plusone\hbox to\wd\zerocount{}%
+ \else
+ \setbox\zerocount\hbox to\wd\plusone{\unhbox\zerocount}%
+ \fi
+ \global\setbox\@@plntabsdone\hbox{\box\plusone\unhbox\@@plntabsdone}%
+ \fi
+ \box\zerocount}
+
+\protect \endinput
diff --git a/tex/context/base/core-tab.tex b/tex/context/base/tabl-tab.tex
index 2e843eae8..361369ea2 100644
--- a/tex/context/base/core-tab.tex
+++ b/tex/context/base/tabl-tab.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=core-tab,
%D version=1997.10.10,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Table Macros,
%D subtitle=\TABLE\ Embedding,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / TaBlE Embedding}
+\writestatus{loading}{ConTeXt Table Macros / TaBlE Embedding}
% By now it makes more sense to merge the patches into the original
% and clean that one up too.
@@ -462,6 +462,8 @@
\def\BeginTableParBox#1%
{\setbox\scratchbox\vtop\bgroup % \setbox added
\hsize#1\relax
+ \dontcomplain
+ \restoretablelineskips
\normalbaselines
\let~\!ttTie
\let\-\!ttDH
@@ -469,18 +471,18 @@
\the\EveryTableParBox}
\def\EndTableParBox
- {\removelastskip % itemize or so
+ {\removelastskip % itemize or so
\endgraf
- \ifnum\prevgraf>\zerocount % we want at least
- \verticalstrut \nowhitespace \vskip-\struttotal% one line of text
+ \ifnum\prevgraf>\zerocount % we want at least
+ \verticalstrut \nowhitespace \vskip-\struttotal % one line of text
\egroup
- \ifdim\dp\scratchbox>\lineheight % see (*) for an
- \getnoflines{\dp\scratchbox}% % example of where
- \dp\scratchbox\zeropoint % saving can go
- \setbox\scratchbox % terrible wrong
+ \ifdim\dp\scratchbox>\lineheight % see (*) for an
+ \getnoflines{\dp\scratchbox}% % example of where
+ \dp\scratchbox\zeropoint % saving can go
+ \setbox\scratchbox % terrible wrong
\vtop to \noflines\lineheight{\box\scratchbox}%
- \fi % esp between rows
- \else % of paragraphs
+ \fi % esp between rows
+ \else % of paragraphs
\egroup
\fi
% \getboxheight\scratchdimen\of\box\scratchbox\relax% compensate for
@@ -698,10 +700,10 @@
\ifx\!ttemp\empty
\!taDimenC\zeropoint
\else
- \setbox0\hbox{\m@th #1,#3#1}%
+ \setbox0\hbox{\mathsurround\zeropoint #1,#3#1}%
\!taDimenC\wd0
\fi
- \setbox0\hbox{\m@th #1#2#1}%
+ \setbox0\hbox{\mathsurround\zeropoint #1#2#1}%
\!thToksEdef\!taDataColumnTemplate
={\noexpand\!tqSetQuantityItem{\the\wd0 }{\the\!taDimenC}{#1}%
\the\!taDataColumnTemplate}%
@@ -714,8 +716,8 @@
\def\!tqSetQuantityItemA #1#2#3#4,#5,#6!%
{\def\!ttemp{#6}%
- \hbox to #1{\hss\m@th#3#4#3}%
- \hbox to #2{\ifx\!ttemp\empty\else\m@th#3,#5#3\fi\hss}}
+ \hbox to #1{\hss\mathsurround\zeropoint#3#4#3}%
+ \hbox to #2{\ifx\!ttemp\empty\else\mathsurround\zeropoint#3,#5#3\fi\hss}}
%D Here ends the Q||extension. Did you watch the clever use
%D of aftergroup in \type{\!tqConvertCode}.
@@ -916,7 +918,7 @@
\advance\mscount \mscount
\!thLoop
\ifnum\mscount>\plusone
- \sp@n % from Plain (\span\omit \advance\mscount\m@ne)
+ \spanomit \advance\mscount\minusone
\repeat
\span}%
\fi % added
@@ -980,7 +982,7 @@
{\doifelsenothing\@@tiframe
{\ifinsidefloat\else\startbaselinecorrection\fi}
{\startframedcontent[\@@tiframe]}%
- \postponefootnotes
+ \postponenotes
\firststagestartTABLE}}
\def\stoptable
@@ -1223,6 +1225,7 @@
\ifconditional\tablerepeattail\else\insertTABLEtail\fi
\finishTABLE
\egroup
+\dontcomplain
\dosplittablebox\tablecontentbox
\flushnotes
\egroup}
@@ -1661,7 +1664,12 @@
\egroup
\def\!ttDoHalign
- {\baselineskip \zeropoint
+ {\edef\restoretablelineskips
+ {\baselineskip \the\baselineskip
+ \lineskiplimit\the\lineskiplimit
+ \lineskip \the\lineskip
+ \tabskip \the\tabskip}%
+ \baselineskip \zeropoint
\lineskiplimit\zeropoint
\lineskip \zeropoint
\tabskip \zeropoint
diff --git a/tex/context/base/core-tbl.tex b/tex/context/base/tabl-tbl.tex
index a5d5a37da..bc57a3abd 100644
--- a/tex/context/base/core-tbl.tex
+++ b/tex/context/base/tabl-tbl.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=core-tbl,
%D version=1998.11.03,
-%D title=\CONTEXT\ Core Macros,
+%D title=\CONTEXT\ Table Macros,
%D subtitle=Text Flow Tabulation,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Core Macros / Tabulation}
+\writestatus{loading}{ConTeXt Table Macros / Tabulation}
% \processbetween gebruiken in head/tail macros
@@ -205,7 +205,7 @@
\def\initializetablebox#1% also used elsewhere
{\ifcsname\@@tabbox@@\number#1\endcsname
- \global\setbox\csname\@@tabbox@@\number#1\endcsname\box\voidb@x
+ \global\setbox\csname\@@tabbox@@\number#1\endcsname\emptybox
\else
\expandafter\newbox\csname\@@tabbox@@\number#1\endcsname
\fi}
@@ -348,10 +348,10 @@
\let\nextnext\relax % == \expandafter\gobbleoneargument
\else
\let\nextnext\settabulatepreamble
- \ifx x\next \chardef\tabulatealign\zerocount % internal
- \else\ifx l\next \chardef\tabulatealign\plusone
- \else\ifx r\next \chardef\tabulatealign\plustwo
- \else\ifx c\next \chardef\tabulatealign\plusthree
+ \ifx x\next \let\tabulatealign\zerocount % internal
+ \else\ifx l\next \let\tabulatealign\plusone
+ \else\ifx r\next \let\tabulatealign\plustwo
+ \else\ifx c\next \let\tabulatealign\plusthree
\else\ifx p\next \let\nextnext\gettabulateparagraph
\else\ifx s\next \let\nextnext\gettabulatesetups
\else\ifx w\next \let\nextnext\gettabulatewidth
@@ -436,17 +436,17 @@
\settabulatepreamble}
\def\gettabulatewidth
- {\chardef\tabulatemodus\zerocount
- \chardef\tabulatedimen\zerocount
+ {\let\tabulatemodus\zerocount
+ \let\tabulatedimen\zerocount
\doifnextcharelse(\dogettabulatewidth\settabulatepreamble}
\def\gettabulateparagraph
{\doifnextcharelse{(}
- {\chardef\tabulatemodus\plusone
- \chardef\tabulatedimen\plusone
+ {\let\tabulatemodus\plusone
+ \let\tabulatedimen\plusone
\dogettabulatewidth}
- {\chardef\tabulatemodus\plustwo
- \chardef\tabulatedimen\zerocount
+ {\let\tabulatemodus\plustwo
+ \let\tabulatedimen\zerocount
\settabulatepreamble}}
% \def\dogettabulatewidth(#1)%
@@ -458,7 +458,7 @@
% \def\dogettabulatewidth(#1)%
% {\doifelse{#1}\v!passend
-% {\chardef\tabulatemodus\plusthree}
+% {\let\tabulatemodus\plusthree}
% {\tabulatewidth#1\relax}%
% \ifnum\tabulatedimen=\plusone
% \global\advance\tabulatepwidth\tabulatewidth
@@ -478,8 +478,8 @@
\def\dogettabulatewidth(#1)%
{\processallactionsinset
[#1]%
- [ \v!fit=>\chardef\tabulatemodus\plusthree,
- \v!fixed=>\chardef\tabulatemodus\plusthree
+ [ \v!fit=>\let\tabulatemodus\plusthree,
+ \v!fixed=>\let\tabulatemodus\plusthree
\tabulatenopbreaktrue,
\s!unknown=>\tabulatewidth#1\relax]%
\ifnum\tabulatedimen=\plusone
@@ -494,14 +494,14 @@
\def\tabulateraggedcenter{\ifnum\tabulatetype=\plusone \else\raggedcenter\fi}
\def\tabulateraggedleft {\ifnum\tabulatetype=\plusone \else\raggedleft \fi}
\def\tabulatenotragged {\ifnum\tabulatetype=\plusone \else\notragged \fi}
-\def\tabulatehss {\ifnum\tabulatetype=\plusone \else\hss \fi}
+\def\tabulatehss {\ifnum\tabulatetype=\plusone \else\hss \fi} % never change this to a fill
\bgroup \catcode`\|=\@@other
\gdef\nexttabulate#1|%
- {\chardef\tabulatealign\@@tabulatealign
- \chardef\tabulatemodus\zerocount
- \chardef\tabulatedimen\zerocount
+ {\let\tabulatealign\@@tabulatealign
+ \let\tabulatemodus\zerocount
+ \let\tabulatedimen\zerocount
\tabulatebefore \emptytoks
\tabulateafter \emptytoks
\tabulatebmath \emptytoks
@@ -730,8 +730,8 @@
% An example of its usage:
-\appendtoks \optimizeverbatimfalse \to \everytabulate
-\appendtoks \chardef\recodeverbatimmode\plustwo \to \everytabulate
+\appendtoks \optimizeverbatimfalse \to \everytabulate
+\appendtoks \let\recodeverbatimmode\plustwo \to \everytabulate
% A status variable:
@@ -762,10 +762,9 @@
\v!no=>\splittabulatefalse,
\v!auto=>\ifinsidefloat\ifinsidesplitfloat\else\splittabulatefalse\fi\fi]%
\doifvaluesomething{\??tt\currenttabulate\c!bodyfont}
- {\expanded{\switchtobodyfont
- [\tabulateparameter\c!bodyfont]}}%
- \postponefootnotes % new, to be tested / will be configurable
- \chardef\tabulatepass\plusone
+ {\expanded{\switchtobodyfont[\tabulateparameter\c!bodyfont]}}%
+ \postponenotes % new, to be tested / will be configurable
+ \let\tabulatepass\plusone
\widowpenalty\zerocount % otherwise lines are not broken
\clubpenalty \zerocount % but overlap in funny ways
\the\everytabulate
@@ -990,8 +989,8 @@
\chardef\tabulaterepeathead\executeifdefined{\??tt:\c!header:\tabulateparameter\c!header}\zerocount
% \processaction
% [\tabulateparameter\c!header]
-% [\v!repeat=>\chardef\tabulaterepeathead\plusone,
-% \v!text=>\chardef\tabulaterepeathead\plustwo]%
+% [\v!repeat=>\let\tabulaterepeathead\plusone,
+% \v!text=>\let\tabulaterepeathead\plustwo]%
\fi
\unexpanded \def\NC{\tabulatenormalcolumn0}%
\unexpanded \def\RC{\tabulatenormalcolumn1}%
@@ -1062,7 +1061,7 @@
% \dorecurse\tabulatecolumns % can be made faster
% {\doifundefinedelse{\@@tabbox@@\recurselevel}
% {\expandafter\newbox\csname\@@tabbox@@\recurselevel\endcsname}%
- % {\global\setbox\csname\@@tabbox@@\recurselevel\endcsname\box\voidb@x}}%
+ % {\global\setbox\csname\@@tabbox@@\recurselevel\endcsname\emptybox}}%
\initializetableboxes\tabulatecolumns
\appendtoks&##\to\!!toksa
\appendtoks\global\advance\tabulatecolumn\plusone\to\!!toksa
@@ -1235,7 +1234,7 @@
\verticalstrut
\vskip-\struttotal}%
\fi}}%
- \chardef\tabulatepass\plustwo
+ \let\tabulatepass\plustwo
%
\ifcase\tabulaterepeathead
\ifinsidesplitfloat
diff --git a/tex/context/base/core-tsp.tex b/tex/context/base/tabl-tsp.tex
index e9f0e7d58..49bb7ad90 100644
--- a/tex/context/base/core-tsp.tex
+++ b/tex/context/base/tabl-tsp.tex
@@ -1,8 +1,8 @@
%D \module
-%D [ file=core-tsp,
+%D [ file=tabl-tsp,
%D version=2000.10.20,
-%D title=\CONTEXT\ Core Macros,
-%D subtitle=Splitting Tables,
+%D title=\CONTEXT\ Table Macros,
+%D subtitle=Splitting,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context OTR Macros / Floating Bodies}
+\writestatus{loading}{ConTeXt Table Macros / Splitting}
%D The code in this file is move here from other places.
diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua
new file mode 100644
index 000000000..0049cf512
--- /dev/null
+++ b/tex/context/base/task-ini.lua
@@ -0,0 +1,45 @@
+if not modules then modules = { } end modules ['task-ini'] = {
+ version = 1.001,
+ comment = "companion to task-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this is a temporary solution, we need to isolate some modules and then
+-- the load order can determine the trickery to be applied to node lists
+
+tasks.appendaction("processors", "normalizers", "fonts.collections.process", nil)
+tasks.appendaction("processors", "normalizers", "fonts.checkers.missing", nil)
+
+tasks.appendaction("processors", "characters", "chars.handle_mirroring", nil, "notail")
+tasks.appendaction("processors", "characters", "chars.handle_casing", nil, "notail")
+tasks.appendaction("processors", "characters", "chars.handle_breakpoints", nil, "notail")
+tasks.appendaction("processors", "characters", "scripts.preprocess", nil, "notail") -- this will be more generalized
+
+tasks.appendaction("processors", "words", "kernel.hyphenation", nil)
+tasks.appendaction("processors", "words", "languages.words.check", nil, "notail")
+
+tasks.appendaction("processors", "fonts", "nodes.process_characters", nil, "notail")
+tasks.appendaction("processors", "fonts", "nodes.inject_kerns", nil, "nohead")
+tasks.appendaction("processors", "fonts", "nodes.protect_glyphs", nil, "nohead")
+tasks.appendaction("processors", "fonts", "kernel.ligaturing", nil)
+tasks.appendaction("processors", "fonts", "kernel.kerning", nil)
+
+tasks.appendaction("processors", "lists", "lists.handle_spacing", nil, "notail")
+tasks.appendaction("processors", "lists", "lists.handle_kerning", nil, "notail")
+
+tasks.appendaction("shipouts", "normalizers", "nodes.cleanup_page", nil, "notail")
+
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_color", nil, "notail")
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_transparency", nil, "notail")
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_overprint", nil, "notail")
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_negative", nil, "notail")
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_effect", nil, "notail")
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer", nil, "notail")
+
+tasks.appendaction("math", "normalizers", "noads.relocate_characters", nil, "nohead")
+tasks.appendaction("math", "normalizers", "noads.resize_characters", nil, "nohead")
+tasks.appendaction("math", "normalizers", "noads.respace_characters", nil, "nohead")
+
+tasks.appendaction("math", "builders", "noads.mlist_to_hlist", nil, "notail")
diff --git a/tex/context/base/task-ini.tex b/tex/context/base/task-ini.tex
new file mode 100644
index 000000000..ef32ee87d
--- /dev/null
+++ b/tex/context/base/task-ini.tex
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=task-ini,
+%D version=2007.06.06,
+%D title=\CONTEXT\ Task Handler,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA-ADE]
+%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 Task Handler / initialization}
+
+\unprotect
+
+%D Maybe we will make things configureable (speed up and such).
+
+\registerctxluafile{task-ini}{1.001}
+
+\protect \endinput
diff --git a/tex/context/base/thrd-ran.tex b/tex/context/base/thrd-ran.tex
index 7a186204b..276a4f624 100644
--- a/tex/context/base/thrd-ran.tex
+++ b/tex/context/base/thrd-ran.tex
@@ -50,7 +50,7 @@
% \catcode`\@=11
%
% \def\nextrandom{\begingroup
-% \ifnum\randomi<\@ne % then initialize with time
+% \ifnum\randomi<\plusone % then initialize with time
% \global\randomi\time
% \global\multiply\randomi388 \global\advance\randomi\year
% \global\multiply\randomi31 \global\advance\randomi\day
@@ -115,7 +115,7 @@
\newcount\randomi % the random number seed (while executing)
\newcount\ranval
-\ifx\m!systems\undefined \def\m!systems{system} \fi
+\ifx\m!systems\undefined \def\m!systems{systems} \fi
\def\nextrandom
{\begingroup
diff --git a/tex/context/base/thrd-tab.tex b/tex/context/base/thrd-tab.tex
index 8ca90665e..dd3838ce2 100644
--- a/tex/context/base/thrd-tab.tex
+++ b/tex/context/base/thrd-tab.tex
@@ -442,17 +442,17 @@
% DO VCS
\def\!thDoVCS#1{%
- \setbox\z@\hbox{#1}%
+ \setbox\zerocount\hbox{#1}%
\!thFinishVCS}
% DO MATH VCS
\def\!thDoMathVCS#1#2{%
- \setbox\z@\hbox{$\m@th#1{#2}$}%
+ \setbox\zerocount\hbox{$\mathsurround\zeropoint#1{#2}$}%
\!thFinishVCS}
% FINISH VCS
\def\!thFinishVCS{%
- \vbox to\z@{\vss\box\z@\vss}}
+ \vbox to\zeropoint{\vss\box\zerocount\vss}}
% ***************************************************************
@@ -505,20 +505,20 @@
% DO SIMPLE RAISE
\def\!thDoSimpleRaise#1{%
- \setbox\z@\hbox{\raise \!taDimenA\hbox{#1}}%
+ \setbox\zerocount\hbox{\raise \!taDimenA\hbox{#1}}%
\!thFinishRaise} % From Plain TeX: \ht0=0pt \dp0=0pt \box0
% DO MATH RAISE
\def\!thDoMathRaise#1#2{%
- \setbox\z@\hbox{\raise \!taDimenA\hbox{$\m@th#1{#2}$}}%
+ \setbox\zerocount\hbox{\raise \!taDimenA\hbox{$\mathsurround\zeropoint#1{#2}$}}%
\!thFinishRaise}
% FINISH RAISE. This is the same as Plain's \finsm@sh; some macro
% packages redefine \finsm@sh.
\def\!thFinishRaise{%
- \ht\z@\z@
- \dp\z@\z@
- \box\z@}
+ \ht\zerocount\zeropoint
+ \dp\zerocount\zeropoint
+ \box\zerocount}
% ***************************************************************
@@ -1481,10 +1481,10 @@
\ifx\!ttemp\empty
\!taDimenC=0pt
\else
- \setbox0=\hbox{\m@th #1.#3#1}%
+ \setbox0=\hbox{\mathsurround\zeropoint #1.#3#1}%
\!taDimenC=\wd0
\fi
- \setbox0 =\hbox{\m@th #1#2#1}%
+ \setbox0 =\hbox{\mathsurround\zeropoint #1#2#1}%
\!thToksEdef\!taDataColumnTemplate={%
\noexpand\!tnSetNumericItem
{\the\wd0 }%
@@ -1499,11 +1499,11 @@
\def\!tnSetNumericItemA #1#2#3#4.#5.#6!{%
\def\!ttemp{#6}%
- \hbox to #1{\hss \m@th #3#4#3}%
+ \hbox to #1{\hss \mathsurround\zeropoint #3#4#3}%
\hbox to #2{%
\ifx\!ttemp\empty
\else
- \m@th #3.#5#3%
+ \mathsurround\zeropoint #3.#5#3%
\fi
\hss}}
@@ -1563,25 +1563,25 @@
\def\!TsEnlargeOther#1{%
\ifhmode
- \setbox\z@=\hbox{#1%
+ \setbox\zerocount\hbox{#1%
\xdef\!TsSpaceFactor{\spacefactor=\the\spacefactor}}%
\else
- \setbox\z@=\hbox{#1}%
+ \setbox\zerocount\hbox{#1}%
\fi
\!TsFinishEnlarge}
\def\!TsEnlargeMath#1#2{%
- \setbox\z@=\hbox{$\m@th#1{#2}$}%
+ \setbox\zerocount\hbox{$\mathsurround\zeropoint#1{#2}$}%
\!TsFinishEnlarge}
\def\!TsFinishEnlarge{%
- \dimen@=\ht\z@
+ \dimen@\ht\zerocount
\advance \dimen@ \!taDimenA
- \ht\z@=\dimen@
- \dimen@=\dp\z@
+ \ht\zerocount\dimen@
+ \dimen@\dp\zerocount
\advance \dimen@ \!taDimenB
- \dp\z@=\dimen@
- \box\z@ \!TsSpaceFactor{}}
+ \dp\zerocount\dimen@
+ \box\zerocount \!TsSpaceFactor{}}
% ENLARGE BY MULTIPLES OF StrutUnit
@@ -1883,15 +1883,17 @@
% USE
% \use <number> spans the next <number> data columns.
+
\def\!ttuse#1{%
- \ifnum #1>\@ne
+ \ifnum #1>\plusone
\omit
\mscount=#1 % \mscount is in Plain
- \advance\mscount by \m@ne
+ \advance\mscount by \minusone
\advance\mscount by \mscount
\!thLoop
- \ifnum\mscount>\@ne
- \sp@n % from Plain (\span\omit \advance\mscount\m@ne)
+ \ifnum\mscount>\plusone
+ % \sp@n: from plain
+ \spanomit \advance\mscount\minusone
\repeat
\span
\fi}
diff --git a/tex/context/base/thrd-trg.tex b/tex/context/base/thrd-trg.tex
index dda81a8af..c0106f5a3 100644
--- a/tex/context/base/thrd-trg.tex
+++ b/tex/context/base/thrd-trg.tex
@@ -10,7 +10,7 @@
%
% so we need:
-\def\realnumber#1{\withoutpt\the\dimexpr#1\s!pt\relax} % brrr
+\def\realnumber#1{\withoutpt\the\dimexpr#1\points\relax} % brrr
\chardef \@iv = 4
\chardef \@xc = 90 % was \nin@ty
@@ -95,6 +95,13 @@
\def\calculatedcos#1{\executeifdefined{cos \realnumber{#1}}\!!plusone }
\def\calculatedtan#1{\executeifdefined{tan \realnumber{#1}}\!!zerocount}
+%D The following permits cleaner overloading (\MKIV\ will only have
+%D these):
+
+\def\setcalculatedsin#1#2{\calculatesin{#2}\edef#1{\calculatedsin{#2}}}
+\def\setcalculatedcos#1#2{\calculatecos{#2}\edef#1{\calculatedcos{#2}}}
+\def\setcalculatedtan#1#2{\calculatetan{#2}\edef#1{\calculatedtan{#2}}}
+
%D A few values are predefined, although, on todays systems there
%D is no real reason for that. I've added the 270 ones and changed
%D the -90 tan. Also, I prefer text (\type {\!!..} instead of
diff --git a/tex/context/base/toks-ini.lua b/tex/context/base/toks-ini.lua
index 46cf17080..1313b04a2 100644
--- a/tex/context/base/toks-ini.lua
+++ b/tex/context/base/toks-ini.lua
@@ -5,15 +5,16 @@ if not modules then modules = { } end modules ['toks-ini'] = {
license = "see context related readme files"
}
-local format, texsprint = string.format, tex.sprint
+local utf = unicode.utf8
+local format, gsub, texsprint = string.format, string.gsub, tex.sprint
-utf = utf or unicode.utf8 -- todo: local
+local ctxcatcodes = tex.ctxcatcodes
--[[ldx--
-<p>This code is experimental.</p>
+<p>This code is experimental and needs a cleanup. The visualizers will move to
+a module.</p>
--ldx]]--
-
-- 1 = command, 2 = modifier (char), 3 = controlsequence id
--
-- callback.register('token_filter', token.get_next)
@@ -196,14 +197,13 @@ function collectors.trace()
end
collectors.show_methods.a = function(data) -- no need to store the table, just pass directly
- local ct = tex.ctxcatcodes
local template = "\\NC %s\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR "
- texsprint(ct, "\\starttabulate[|T|Tr|cT|Tr|T|]")
- texsprint(ct, template:format("cmd","chr","","id","name"))
- texsprint(ct, "\\HL")
+ texsprint(ctxcatcodes, "\\starttabulate[|T|Tr|cT|Tr|T|]")
+ texsprint(ctxcatcodes, format(template,"cmd","chr","","id","name"))
+ texsprint(ctxcatcodes, "\\HL")
for _,v in pairs(data) do
local cmd, chr, id, cs, sym = v[1], v[2], v[3], "", ""
- local name = (token.command_name(v) or ""):gsub("_","\\_")
+ local name = gsub(token.command_name(v) or "","_","\\_")
if id > 0 then
cs = token.csname_name(v) or ""
if cs ~= "" then cs = "\\string " .. cs end
@@ -214,27 +214,26 @@ collectors.show_methods.a = function(data) -- no need to store the table, just p
sym = "\\char " .. chr
end
if tonumber(chr) < 0 then
- texsprint(ct, template:format(name, "", sym, id, cs))
+ texsprint(ctxcatcodes, format(template, name, "", sym, id, cs))
else
- texsprint(ct, template:format(name, chr, sym, id, cs))
+ texsprint(ctxcatcodes, format(template, name, chr, sym, id, cs))
end
end
- texsprint(ct, "\\stoptabulate")
+ texsprint(ctxcatcodes, "\\stoptabulate")
end
collectors.show_methods.b_c = function(data,swap) -- no need to store the table, just pass directly
- local ct = tex.ctxcatcodes
local template = "\\NC %s\\NC %s\\NC %s\\NC\\NR"
if swap then
- texsprint(ct, "\\starttabulate[|Tl|Tl|Tr|]")
+ texsprint(ctxcatcodes, "\\starttabulate[|Tl|Tl|Tr|]")
else
- texsprint(ct, "\\starttabulate[|Tl|Tr|Tl|]")
+ texsprint(ctxcatcodes, "\\starttabulate[|Tl|Tr|Tl|]")
end
- texsprint(ct, template:format("cmd","chr","name"))
- texsprint(ct, "\\HL")
+ texsprint(ctxcatcodes, format(template,"cmd","chr","name"))
+ texsprint(ctxcatcodes, "\\HL")
for _,v in pairs(data) do
local cmd, chr, id, cs, sym = v[1], v[2], v[3], "", ""
- local name = (token.command_name(v) or ""):gsub("_","\\_")
+ local name = gsub(token.command_name(v) or "","_","\\_")
if id > 0 then
cs = token.csname_name(v) or ""
end
@@ -248,14 +247,14 @@ collectors.show_methods.b_c = function(data,swap) -- no need to store the table,
end
end
if swap then
- texsprint(ct, template:format(name, sym, chr))
+ texsprint(ctxcatcodes, format(template, name, sym, chr))
elseif tonumber(chr) < 0 then
- texsprint(ct, template:format(name, "", sym))
+ texsprint(ctxcatcodes, format(template, name, "", sym))
else
- texsprint(ct, template:format(name, chr, sym))
+ texsprint(ctxcatcodes, format(template, name, chr, sym))
end
end
- texsprint(ct, "\\stoptabulate")
+ texsprint(ctxcatcodes, "\\stoptabulate")
end
-- Even more experimental ...
diff --git a/tex/context/base/toks-ini.tex b/tex/context/base/toks-ini.tex
index 90311eb13..932c05f32 100644
--- a/tex/context/base/toks-ini.tex
+++ b/tex/context/base/toks-ini.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=toks-ini,
%D version=2007.03.03,
-%D title=\CONTEXT\ Character Macros,
-%D subtitle=Token Support (Initialization),
+%D title=\CONTEXT\ Token Support,
+%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Token Support (initialization)}
+\writestatus{loading}{ConTeXt Token Support / Initialization}
\registerctxluafile{toks-ini}{1.001}
diff --git a/tex/context/base/luat-deb.lua b/tex/context/base/trac-deb.lua
index a32d923bd..f476169c3 100644
--- a/tex/context/base/luat-deb.lua
+++ b/tex/context/base/trac-deb.lua
@@ -1,10 +1,11 @@
--- filename : luat-deb.lua
--- comment : companion to luat-deb.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['trac-deb'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['luat-deb'] = 1.001
if not lmx then lmx = { } end
if not lmx.variables then lmx.variables = { } end
@@ -21,6 +22,9 @@ lmx.variables['color-background-two'] = lmx.variables['color-background-blue'
lmx.variables['title-default'] = 'ConTeXt Status Information'
lmx.variables['title'] = lmx.variables['title-default']
+lmx.htmfile = function(name) return environment.jobname .. "-status.html" end
+lmx.lmxfile = function(name) return resolvers.find_file(name,'tex') end
+
if not tracers then tracers = { } end
if not tracers.list then tracers.list = { } end
if not tracers.strings then tracers.strings = { } end
@@ -133,9 +137,6 @@ function tracers.showerror()
end
function tracers.overloaderror()
---~ callback.register('show_error_hook', function(identifier, filename, linenumber)
---~ tracers.showerror(identifier, filename, linenumber)
---~ end )
callback.register('show_error_hook', tracers.showerror)
end
@@ -152,3 +153,54 @@ tracers.list['context'] = {
'd:lineheight',
'c:realpageno', 'c:pageno', 'c:subpageno'
}
+
+-- dumping the hash
+
+-- \starttext
+-- \ctxlua{tracers.dump_hash()}
+-- \stoptext
+
+local saved = { }
+
+function tracers.save_hash()
+ saved = tex.hashtokens()
+end
+
+function tracers.dump_hash(filename,delta)
+ filename = filename or tex.jobname .. "-hash.log"
+ local list = { }
+ local hash = tex.hashtokens()
+ local command_name = token.command_name
+ for name, token in pairs(hash) do
+ if not delta or not saved[name] then
+ -- token: cmd, chr, csid -- combination cmd,chr determines name
+ local kind = command_name(token)
+ local dk = list[kind]
+ if not dk then
+ -- a bit funny names but this sorts better (easier to study)
+ dk = { names = { }, found = 0, code = token[1] }
+ list[kind] = dk
+ end
+ dk.names[name] = { token[2], token[3] }
+ dk.found = dk.found + 1
+ end
+ end
+ io.savedata(filename,table.serialize(list,true))
+end
+
+function tracers.register_dump_hash(delta)
+ if delta then
+ tracers.save_hash()
+ end
+ main.register_stop_actions(1,function() tracers.dump_hash(nil,true) end) -- at front
+end
+
+-- trackers (maybe group the show by class)
+
+function trackers.show()
+ commands.writestatus("","")
+ for k,v in ipairs(trackers.list()) do
+ commands.writestatus("tracker",v)
+ end
+ commands.writestatus("","")
+end
diff --git a/tex/context/base/luat-deb.tex b/tex/context/base/trac-deb.tex
index 55686ac11..870c452ad 100644
--- a/tex/context/base/luat-deb.tex
+++ b/tex/context/base/trac-deb.tex
@@ -1,8 +1,8 @@
%D \module
-%D [ file=luat-deb,
+%D [ file=trac-deb,
%D version=2005.11.06,
-%D title=\CONTEXT\ Communication Macros,
-%D subtitle=Initialization,
+%D title=\CONTEXT\ Tracing Macros,
+%D subtitle=Debugger,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,24 +11,15 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Communication Support (initialization)}
+\writestatus{loading}{ConTeXt Tracing Macros / Debugger}
-\registerctxluafile{luat-deb}{1.001}
-
-\startruntimeluacode
- \ctxlua {
- lmx.htmfile = function(name) return environment.jobname .. "-status.html" end
- lmx.lmxfile = function(name) return environment.texfile(name) end
- }
-\stopruntimeluacode
+\registerctxluafile{trac-deb}{1.001}
\def\showdebuginfo{\ctxlua{tracers.showdebuginfo()}}
\def\overloaderror{\ctxlua{tracers.overloaderror()}}
\def\breakpoint{\showdebuginfo\wait}
-\registerctxluafile{luat-tra}{1.001}
-
\appendtoks
\ctxlua {
if debugger.tracing() then
@@ -46,4 +37,7 @@
}%
\to \everybye
-\endinput
+\def\showtrackers {\ctxlua{trackers.show()}}
+\def\resettrackers {\ctxlua{trackers.reset()}}
+\def\enabletrackers [#1]{\ctxlua{trackers.enable("#1")}}
+\def\disabletrackers[#1]{\ctxlua{trackers.disable("#1")}}
diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua
new file mode 100644
index 000000000..41a9e7b48
--- /dev/null
+++ b/tex/context/base/trac-inf.lua
@@ -0,0 +1,149 @@
+if not modules then modules = { } end modules ['trac-inf'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+
+local statusinfo, n, registered = { }, 0, { }
+
+statistics = statistics or { }
+
+statistics.enable = true
+statistics.threshold = 0.05
+
+-- timing functions
+
+local clock = os.gettimeofday or os.clock
+
+function statistics.hastimer(instance)
+ return instance and instance.starttime
+end
+
+function statistics.starttiming(instance)
+ if instance then
+ local it = instance.timing
+ if not it then
+ it = 0
+ end
+ if it == 0 then
+ instance.starttime = clock()
+ if not instance.loadtime then
+ instance.loadtime = 0
+ end
+ end
+ instance.timing = it + 1
+ end
+end
+
+function statistics.stoptiming(instance, report)
+ if instance then
+ local it = instance.timing
+ if it > 1 then
+ instance.timing = it - 1
+ else
+ local starttime = instance.starttime
+ if starttime then
+ local stoptime = clock()
+ local loadtime = stoptime - starttime
+ instance.stoptime = stoptime
+ instance.loadtime = instance.loadtime + loadtime
+ if report then
+ statistics.report("load time %0.3f",loadtime)
+ end
+ instance.timing = 0
+ return loadtime
+ end
+ end
+ end
+ return 0
+end
+
+function statistics.elapsedtime(instance)
+ return format("%0.3f",(instance and instance.loadtime) or 0)
+end
+
+function statistics.elapsedindeed(instance)
+ local t = (instance and instance.loadtime) or 0
+ return t > statistics.threshold
+end
+
+-- general function
+
+function statistics.register(tag,fnc)
+ if statistics.enable and type(fnc) == "function" then
+ local rt = registered[tag] or (#statusinfo + 1)
+ statusinfo[rt] = { tag, fnc }
+ registered[tag] = rt
+ if #tag > n then n = #tag end
+ end
+end
+
+function statistics.show(reporter)
+ if statistics.enable then
+ if not reporter then reporter = function(tag,data,n) texio.write_nl(tag .. " " .. data) end end
+ -- this code will move
+ local register = statistics.register
+ register("luatex banner", function()
+ return string.lower(status.banner)
+ end)
+ register("control sequences", function()
+ return format("%s of %s", status.cs_count, status.hash_size+status.hash_extra)
+ end)
+ register("callbacks", function()
+ local total, indirect = status.callbacks or 0, status.indirect_callbacks or 0
+ return format("direct: %s, indirect: %s, total: %s", total-indirect, indirect, total)
+ end)
+ register("current memory usage", statistics.memused)
+ register("runtime",statistics.runtime)
+-- --
+ for i=1,#statusinfo do
+ local s = statusinfo[i]
+ local r = s[2]()
+ if r then
+ reporter(s[1],r,n)
+ end
+ end
+ statistics.enable = false
+ end
+end
+
+function statistics.show_job_stat(tag,data,n)
+ texio.write_nl(format("%-15s: %s - %s","mkiv lua stats",tag:rpadd(n," "),data))
+end
+
+function statistics.memused() -- no math.round yet -)
+ local round = math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000), round(status.luastate_bytes/1000000))
+end
+
+if statistics.runtime then
+ -- already loaded and set
+elseif luatex and luatex.starttime then
+ statistics.starttime = luatex.starttime
+ statistics.loadtime = 0
+ statistics.timing = 0
+else
+ statistics.starttiming(statistics)
+end
+
+function statistics.runtime()
+ statistics.stoptiming(statistics)
+ return statistics.formatruntime(statistics.elapsedtime(statistics))
+end
+
+function statistics.formatruntime(runtime)
+ return format("%s seconds", statistics.elapsedtime(statistics))
+end
+
+function statistics.timed(action,report)
+ local timer = { }
+ report = report or logs.simple
+ statistics.starttiming(timer)
+ action()
+ statistics.stoptiming(timer)
+ report("total runtime: %s",statistics.elapsedtime(timer))
+end
diff --git a/tex/context/base/luat-lmx.lua b/tex/context/base/trac-lmx.lua
index b9bab7df1..07f5ae291 100644
--- a/tex/context/base/luat-lmx.lua
+++ b/tex/context/base/trac-lmx.lua
@@ -1,14 +1,16 @@
--- filename : luat-lmx.lua
--- comment : companion to luat-lmx.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['trac-lmx'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-if not versions then versions = { } end versions['luat-mlx'] = 1.001
+local gsub, format, concat = string.gsub, string.format, table.concat
-- we can now use l-xml, and we can also use lpeg
-lmx = { }
+lmx = lmx or { }
lmx.escapes = {
['&'] = '&amp;',
@@ -27,26 +29,32 @@ lmx.variables['title'] = lmx.variables['title-default']
-- demonstrates: local, *all, gsub using tables, nil or value, loadstring
function lmx.loadedfile(filename)
- return input.texdatablob(filename)
+ return io.loaddata(resolvers.find_file(filename))
end
lmx.converting = false
+local templates = { }
+
function lmx.convert(template,result) -- todo: use lpeg instead
if not lmx.converting then -- else, if error then again tex error and loop
- local data = input.texdatablob(template)
- local f = false
- if result then
- f = io.open(result,"w")
- function lmx.print(str) f:write(str) end
- else
- lmx.print = io.write
+ local data = templates[template]
+ if not data then
+ data = lmx.loadedfile(template)
+ templates[template] = data
+ end
+ local text = { }
+ function lmx.print(...)
+ text[#text+1] = concat({...})
end
function lmx.variable(str)
return lmx.variables[str] or ""
end
function lmx.escape(str)
- return string.gsub(str:gsub('&','&amp;'),'[<>"]',lmx.escapes)
+ str = tostring(str)
+ str = gsub(str,'&','&amp;')
+ str = gsub(str,'[<>"]',lmx.escapes)
+ return str
end
function lmx.type(str)
if str then lmx.print("<tt>" .. lmx.escape(str) .. "</tt>") end
@@ -57,41 +65,44 @@ function lmx.convert(template,result) -- todo: use lpeg instead
function lmx.tv(str)
lmx.type(lmx.variable(str))
end
- data = data:gsub("<%?lmx%-include%s+(.-)%s-%?>", function(filename)
+ data = gsub(data,"<%?lmx%-include%s+(.-)%s-%?>", function(filename)
return lmx.loadedfile(filename)
end)
local definitions = { }
- data = data:gsub("<%?lmx%-define%-begin%s+(%S-)%s-%?>(.-)<%?lmx%-define%-end%s-%?>", function(tag,content)
+ data = gsub(data,"<%?lmx%-define%-begin%s+(%S-)%s-%?>(.-)<%?lmx%-define%-end%s-%?>", function(tag,content)
definitions[tag] = content
return ""
end)
- data = data:gsub("<%?lmx%-resolve%s+(%S-)%s-%?>", function(tag)
+ data = gsub(data,"<%?lmx%-resolve%s+(%S-)%s-%?>", function(tag)
return definitions[tag] or ""
end)
- data = data:gsub("%c%s-(<%?lua .-%?>)%s-%c", function(lua)
+ data = gsub(data,"%c%s-(<%?lua .-%?>)%s-%c", function(lua)
return "\n" .. lua .. " "
end)
- data = string.gsub(data .. "<?lua ?>","(.-)<%?lua%s+(.-)%?>", function(txt, lua)
- txt = txt:gsub("%c+", "\\n")
- txt = txt:gsub('"' , '\\"')
- txt = txt:gsub("'" , "\\'")
- -- txt = string.gsub(txt, "([\'\"])", { ["'"] = '\\"', ['"'] = "\\'" } )
+ data = gsub(data .. "<?lua ?>","(.-)<%?lua%s+(.-)%?>", function(txt, lua)
+ txt = gsub(txt,"%c+", "\\n")
+ txt = gsub(txt,'"' , '\\"')
+ txt = gsub(txt,"'" , "\\'")
+ -- txt = gsub(txt,"([\'\"])", { ["'"] = '\\"', ['"'] = "\\'" } )
return "p(\"" .. txt .. "\")\n" .. lua .. "\n"
end)
lmx.converting = true
data = "local p,v,e,t,pv,tv = lmx.print,lmx.variable,lmx.escape,lmx.type,lmx.pv,lmx.tv " .. data
assert(loadstring(data))()
lmx.converting = false
- if f then
- f:close()
+ text = concat(text)
+ if result then
+ io.savedata(result,text)
+ else
+ return text
end
end
end
-- these can be overloaded; we assume that the os handles filename associations
-lmx.lmxfile = function(filename) return filename end
-lmx.htmfile = function(filename) return filename end
+lmx.lmxfile = function(filename) return filename end
+lmx.htmfile = function(filename) return filename end
if os.platform == "windows" then
lmx.popupfile = function(filename) os.execute("start " .. filename) end
@@ -99,14 +110,20 @@ else
lmx.popupfile = function(filename) os.execute(filename) end
end
-function lmx.show(name)
+function lmx.make(name)
local lmxfile = lmx.lmxfile(name)
local htmfile = lmx.htmfile(name)
if lmxfile == htmfile then
- htmfile = string.gsub(lmxfile, "%.%a+$", "html")
+ htmfile = gsub(lmxfile, "%.%a+$", "html")
end
lmx.convert(lmxfile, htmfile)
+ return htmfile
+end
+
+function lmx.show(name)
+ local htmfile = lmx.make(name)
lmx.popupfile(htmfile)
+ return htmfile
end
-- kind of private
diff --git a/tex/context/base/luat-lmx.tex b/tex/context/base/trac-lmx.tex
index cc7fa448f..a47d2b8bb 100644
--- a/tex/context/base/luat-lmx.tex
+++ b/tex/context/base/trac-lmx.tex
@@ -1,8 +1,8 @@
%D \module
-%D [ file=luat-lmx,
+%D [ file=trac-lmx,
%D version=2005.09.02,
-%D title=\CONTEXT\ Lua Macros,
-%D subtitle=LMX Support,
+%D title=\CONTEXT\ Tracing Macros,
+%D subtitle=LMX,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright=PRAGMA]
@@ -11,6 +11,6 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Lua Support Macros (lmx)}
+\writestatus{loading}{ConTeXt Tracing Macros / LMX}
-\registerctxluafile{luat-lmx}{1.001}
+\registerctxluafile{trac-lmx}{1.001}
diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua
new file mode 100644
index 000000000..1fb25c5c7
--- /dev/null
+++ b/tex/context/base/trac-log.lua
@@ -0,0 +1,285 @@
+if not modules then modules = { } end modules ['luat-log'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this is old code that needs an overhaul
+
+local write_nl, write, format = texio.write_nl or print, texio.write or io.write, string.format
+
+if texlua then
+ write_nl = print
+ write = io.write
+end
+
+--[[ldx--
+<p>This is a prelude to a more extensive logging module. For the sake
+of parsing log files, in addition to the standard logging we will
+provide an <l n='xml'/> structured file. Actually, any logging that
+is hooked into callbacks will be \XML\ by default.</p>
+--ldx]]--
+
+logs = logs or { }
+logs.xml = logs.xml or { }
+logs.tex = logs.tex or { }
+
+--[[ldx--
+<p>This looks pretty ugly but we need to speed things up a bit.</p>
+--ldx]]--
+
+logs.moreinfo = [[
+more information about ConTeXt and the tools that come with it can be found at:
+
+maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
+webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
+wiki : http://contextgarden.net
+]]
+
+logs.levels = {
+ ['error'] = 1,
+ ['warning'] = 2,
+ ['info'] = 3,
+ ['debug'] = 4,
+}
+
+logs.functions = {
+ 'report', 'start', 'stop', 'push', 'pop', 'line', 'direct',
+ 'start_run', 'stop_run',
+ 'start_page_number', 'stop_page_number',
+ 'report_output_pages', 'report_output_log',
+ 'report_tex_stat', 'report_job_stat',
+ 'show_open', 'show_close', 'show_load',
+}
+
+logs.tracers = {
+}
+
+logs.level = 0
+logs.mode = string.lower((os.getenv("MTX.LOG.MODE") or os.getenv("MTX_LOG_MODE") or "tex"))
+
+function logs.set_level(level)
+ logs.level = logs.levels[level] or level
+end
+
+function logs.set_method(method)
+ for _, v in next, logs.functions do
+ logs[v] = logs[method][v] or function() end
+ end
+end
+
+-- tex logging
+
+function logs.tex.report(category,fmt,...) -- new
+ if fmt then
+ write_nl(category .. " | " .. format(fmt,...))
+ else
+ write_nl(category .. " |")
+ end
+end
+
+function logs.tex.line(fmt,...) -- new
+ if fmt then
+ write_nl(format(fmt,...))
+ else
+ write_nl("")
+ end
+end
+
+local texcount = tex and tex.count
+
+function logs.tex.start_page_number()
+ local real, user, sub = texcount[0], texcount[1], texcount[2]
+ if real > 0 then
+ if user > 0 then
+ if sub > 0 then
+ write(format("[%s.%s.%s",real,user,sub))
+ else
+ write(format("[%s.%s",real,user))
+ end
+ else
+ write(format("[%s",real))
+ end
+ else
+ write("[-")
+ end
+end
+
+function logs.tex.stop_page_number()
+ write("]")
+end
+
+logs.tex.report_job_stat = statistics.show_job_stat
+
+-- xml logging
+
+function logs.xml.report(category,fmt,...) -- new
+ if fmt then
+ write_nl(format("<r category='%s'>%s</r>",category,format(fmt,...)))
+ else
+ write_nl(format("<r category='%s'/>",category))
+ end
+end
+function logs.xml.line(fmt,...) -- new
+ if fmt then
+ write_nl(format("<r>%s</r>",format(fmt,...)))
+ else
+ write_nl("<r/>")
+ end
+end
+
+function logs.xml.start() if logs.level > 0 then tw("<%s>" ) end end
+function logs.xml.stop () if logs.level > 0 then tw("</%s>") end end
+function logs.xml.push () if logs.level > 0 then tw("<!-- ") end end
+function logs.xml.pop () if logs.level > 0 then tw(" -->" ) end end
+
+function logs.xml.start_run()
+ write_nl("<?xml version='1.0' standalone='yes'?>")
+ write_nl("<job>") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng'
+ write_nl("")
+end
+
+function logs.xml.stop_run()
+ write_nl("</job>")
+end
+
+function logs.xml.start_page_number()
+ write_nl(format("<p real='%s' page='%s' sub='%s'", texcount[0], texcount[1], texcount[2]))
+end
+
+function logs.xml.stop_page_number()
+ write("/>")
+ write_nl("")
+end
+
+function logs.xml.report_output_pages(p,b)
+ write_nl(format("<v k='pages' v='%s'/>", p))
+ write_nl(format("<v k='bytes' v='%s'/>", b))
+ write_nl("")
+end
+
+function logs.xml.report_output_log()
+end
+
+function logs.xml.report_tex_stat(k,v)
+ texiowrite_nl("log","<v k='"..k.."'>"..tostring(v).."</v>")
+end
+
+local level = 0
+
+function logs.xml.show_open(name)
+ level = level + 1
+ texiowrite_nl(format("<f l='%s' n='%s'>",level,name))
+end
+
+function logs.xml.show_close(name)
+ texiowrite("</f> ")
+ level = level - 1
+end
+
+function logs.xml.show_load(name)
+ texiowrite_nl(format("<f l='%s' n='%s'/>",level+1,name))
+end
+
+--
+
+local name, banner = 'report', 'context'
+
+local function report(category,fmt,...)
+ if fmt then
+ write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
+ elseif category then
+ write_nl(format("%s | %s",name,category))
+ else
+ write_nl(format("%s |",name))
+ end
+end
+
+local function simple(fmt,...)
+ if fmt then
+ write_nl(format("%s | %s",name,format(fmt,...)))
+ else
+ write_nl(format("%s |",name))
+ end
+end
+
+function logs.setprogram(_name_,_banner_,_verbose_)
+ name, banner = _name_, _banner_
+ if _verbose_ then
+ trackers.enable("resolvers.verbose")
+ end
+ logs.set_method("tex")
+ logs.report = report -- also used in libraries
+ logs.simple = simple -- only used in scripts !
+ if utils then
+ utils.report = simple
+ end
+ logs.verbose = _verbose_
+end
+
+function logs.setverbose(what)
+ if what then
+ trackers.enable("resolvers.verbose")
+ else
+ trackers.disable("resolvers.verbose")
+ end
+ logs.verbose = what or false
+end
+
+function logs.extendbanner(_banner_,_verbose_)
+ banner = banner .. " | ".. _banner_
+ if _verbose_ ~= nil then
+ logs.setverbose(what)
+ end
+end
+
+logs.verbose = false
+logs.report = logs.tex.report
+logs.simple = logs.tex.report
+
+function logs.reportlines(str) -- todo: <lines></lines>
+ for line in str:gmatch("(.-)[\n\r]") do
+ logs.report(line)
+ end
+end
+
+function logs.reportline() -- for scripts too
+ logs.report()
+end
+
+logs.simpleline = logs.reportline
+
+function logs.help(message,option)
+ logs.report(banner)
+ logs.reportline()
+ logs.reportlines(message)
+ local moreinfo = logs.moreinfo or ""
+ if moreinfo ~= "" and option ~= "nomoreinfo" then
+ logs.reportline()
+ logs.reportlines(moreinfo)
+ end
+end
+
+logs.set_level('error')
+logs.set_method('tex')
+
+function logs.system(whereto,process,jobname,category,...)
+ for i=1,10 do
+ local f = io.open(whereto,"a")
+ if f then
+ f:write(format("%s %s => %s => %s => %s\r",os.date("%d/%m/%y %H:%m:%S"),process,jobname,category,format(...)))
+ f:close()
+ break
+ else
+ sleep(0.1)
+ end
+ end
+end
+
+--~ local syslogname = "oeps.xxx"
+--~
+--~ for i=1,10 do
+--~ logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123")
+--~ end
diff --git a/tex/context/base/trac-tim.lua b/tex/context/base/trac-tim.lua
new file mode 100644
index 000000000..82c03f4c7
--- /dev/null
+++ b/tex/context/base/trac-tim.lua
@@ -0,0 +1,163 @@
+if not modules then modules = { } end modules ['trac-tim'] = {
+ version = 1.001,
+ comment = "companion to m-timing.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+goodies = goodies or { }
+goodies.progress = goodies.progress or { }
+
+local progress = goodies.progress
+
+progress = progress or { }
+
+progress.defaultfilename = ((tex and tex.jobname) or "whatever") .. "-luatex-progress"
+
+local params = {
+ "cs_count",
+ "dyn_used",
+ "elapsed_time",
+ "luabytecode_bytes",
+ "luastate_bytes",
+ "max_buf_stack",
+ "obj_ptr",
+ "pdf_mem_ptr",
+ "pdf_mem_size",
+ "pdf_os_cntr",
+ "pool_ptr",
+ "str_ptr",
+}
+
+-- storage
+
+local last = os.clock()
+local data = { }
+
+function progress.save()
+ local f = io.open((name or progress.defaultfilename) .. ".lut","w")
+ if f then
+ f:write(table.serialize(data,true))
+ f:close()
+ data = { }
+ end
+end
+
+function progress.store()
+ local c = os.clock()
+ local t = {
+ elapsed_time = c - last,
+ node_memory = nodes.usage(),
+ }
+ for k, v in pairs(params) do
+ if status[v] then t[v] = status[v] end
+ end
+ data[#data+1] = t
+ last = c
+end
+
+-- conversion
+
+local processed = { }
+
+function progress.bot(name,tag)
+ local d = progress.convert(name)
+ return d.bot[tag] or 0
+end
+function progress.top(name,tag)
+ local d = progress.convert(name)
+ return d.top[tag] or 0
+end
+function progress.pages(name,tag)
+ local d = progress.convert(name)
+ return d.pages or 0
+end
+function progress.path(name,tag)
+ local d = progress.convert(name)
+ return d.paths[tag] or "origin"
+end
+function progress.nodes(name)
+ local d = progress.convert(name)
+ return d.names or { }
+end
+function progress.parameters(name)
+ local d = progress.convert(name)
+ return params -- shared
+end
+
+function progress.convert(name)
+ name = ((name ~= "") and name) or progress.defaultfilename
+ if not processed[name] then
+ local names, top, bot, pages, paths, keys = { }, { }, { }, 0, { }, { }
+ local data = io.loaddata(name .. ".lut")
+ if data then data = loadstring(data) end
+ if data then data = data() end
+ if data then
+ pages = #data
+ if pages > 1 then
+ local factor = 100
+ for k,v in ipairs(data) do
+ for k,v in pairs(v.node_memory) do
+ keys[k] = true
+ end
+ end
+ for k,v in ipairs(data) do
+ local m = v.node_memory
+ for k, _ in pairs(keys) do
+ if not m[k] then m[k] = 0 end
+ end
+ end
+ local function path(tag,subtag)
+ local b, t, s = nil, nil, { }
+ for k,v in ipairs(data) do
+ local v = (subtag and v[tag][subtag]) or v[tag]
+ if v then
+ v = tonumber(v)
+ if b then
+ if v > t then t = v end
+ if v < b then b = v end
+ else
+ t = v
+ b = v
+ end
+ s[k] = v
+ else
+ s[k] = 0
+ end
+ end
+ local tagname = subtag or tag
+ top[tagname] = (string.format("%.3f",t)):gsub("%.000$","")
+ bot[tagname] = (string.format("%.3f",b)):gsub("%.000$","")
+ local delta = t-b
+ if delta == 0 then
+ delta = 1
+ else
+ delta = factor/delta
+ end
+ for k, v in ipairs(s) do
+ s[k] = "(" .. k .. "," .. (v-b)*delta .. ")"
+ end
+ paths[tagname] = table.concat(s,"--")
+ end
+ for _, tag in pairs(params) do
+ path(tag)
+ end
+ for tag, _ in pairs(keys) do
+ path("node_memory",tag)
+ names[#names+1] = tag
+ end
+ pages = pages - 1
+ end
+ end
+ table.sort(names)
+ processed[name] = {
+ names = names,
+ top = top,
+ bot = bot,
+ pages = pages,
+ paths = paths,
+ }
+ end
+ return processed[name]
+end
diff --git a/tex/context/base/luat-tra.lua b/tex/context/base/trac-tra.lua
index 5314b48c6..8a51d33b9 100644
--- a/tex/context/base/luat-tra.lua
+++ b/tex/context/base/trac-tra.lua
@@ -1,21 +1,21 @@
--- filename : luat-tra.lua
--- comment : companion to luat-lib.tex
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['trac-tra'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
-- the <anonymous> tag is kind of generic and used for functions that are not
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
-if not versions then versions = { } end versions['luat-tra'] = 1.001
-
-debugger = { }
+debugger = debugger or { }
local counters = { }
-local names = { }
-local getinfo = debug.getinfo
-local format = string.format
+local names = { }
+local getinfo = debug.getinfo
+local format, find, lower, gmatch = string.format, string.find, string.lower, string.gmatch
-- one
@@ -143,3 +143,79 @@ end
--~ print("")
--~ debugger.showstats(print,3)
+trackers = trackers or { }
+
+local data, done = { }, { }
+
+local function set(what,value)
+ for w in gmatch(lower(what),"[^, ]+") do
+ for d, f in next, data do
+ if done[d] then
+ -- prevent recursion due to wildcards
+ elseif find(d,w) then
+ done[d] = true
+ for i=1,#f do
+ f[i](value)
+ end
+ end
+ end
+ end
+end
+
+local function reset()
+ for d, f in next, data do
+ for i=1,#f do
+ f[i](false)
+ end
+ end
+end
+
+function trackers.register(what,...)
+ what = lower(what)
+ local w = data[what]
+ if not w then
+ w = { }
+ data[what] = w
+ end
+ for _, fnc in next, { ... } do
+ local typ = type(fnc)
+ if typ == "function" then
+ w[#w+1] = fnc
+ elseif typ == "string" then
+ w[#w+1] = function(value) set(fnc,value,nesting) end
+ end
+ end
+end
+
+function trackers.enable(what)
+ done = { }
+ set(what,true)
+end
+
+function trackers.disable(what)
+ done = { }
+ if not what or what == "" then
+ trackers.reset(what)
+ else
+ set(what,false)
+ end
+end
+
+function trackers.reset(what)
+ done = { }
+ reset()
+end
+
+function trackers.list() -- pattern
+ local list = table.sortedkeys(data)
+ local user, system = { }, { }
+ for l=1,#list do
+ local what = list[l]
+ if find(what,"^%*") then
+ system[#system+1] = what
+ else
+ user[#user+1] = what
+ end
+ end
+ return user, system
+end
diff --git a/tex/context/base/type-cow.tex b/tex/context/base/type-cow.tex
index bda8489a5..507386443 100644
--- a/tex/context/base/type-cow.tex
+++ b/tex/context/base/type-cow.tex
@@ -70,14 +70,14 @@
\definetypeface [cow] [rm][serif][cow] [default][encoding=default]
\definetypeface [cow] [ss][serif][cow] [default][encoding=default]
\definetypeface [cow] [mm][math] [cow] [default][encoding=default]
- \definetypeface [cow] [tt][mono] [modern][default][encoding=default,rscale=.85]
+ \definetypeface [cow] [tt][mono] [modern][default][encoding=default,rscale=0.85]
\stoptypescript
\starttypescript [sheep] [default]
\definetypeface [sheep][rm][serif][sheep] [default][encoding=default]
\definetypeface [sheep][ss][serif][sheep] [default][encoding=default]
\definetypeface [sheep][mm][math] [sheep] [default][encoding=default]
- \definetypeface [sheep][tt][mono] [modern][default][encoding=default,rscale=.85]
+ \definetypeface [sheep][tt][mono] [modern][default][encoding=default,rscale=0.85]
\stoptypescript
\stoptypescriptcollection
diff --git a/tex/context/base/type-gyr.tex b/tex/context/base/type-gyr.tex
deleted file mode 100644
index ee21cc784..000000000
--- a/tex/context/base/type-gyr.tex
+++ /dev/null
@@ -1,252 +0,0 @@
-%D \module
-%D [ file=type-gyr,
-%D version=2006.06.28,
-%D title=\CONTEXT\ Typescript Macros,
-%D subtitle=TeXGyre Collection,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright=PRAGMA]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% \beginNEWTEX already-otf-gyre
-% \endinput
-% \endNEWTEX
-
-%D These definitions will eventually replace the ones in \type {type-one}!
-
-% \usetypescriptfile[type-gyr]
-% \definetypeface[pagella][rm][serif][pagella][default][encoding=t5]
-% \setupbodyfont[pagella]
-% \starttext
-% \startlines
-% hello world 123
-% {hello \Var[sc] world 123}
-% {\it hello \Var[sc]world \Var[reset] 123}
-% {\bf hello \Var[osf] {\Var[reset] world} 123}
-% {\bi hello world \Var[osf]123}
-% {\sc hello \Var[sc] world \Var[reset] 123}
-% \stoplines
-% \showfont[SerifItalicCaps]
-% \stoptext
-
-% Beware, because tetex demanded a different map file naming scheme, we ship
-% alternatively named files as well, just to make sure that older installations
-% still work (where users may load their own instances). In due time we will
-% follow that scheme (well, in due time we will drop map files anyway).
-
-\starttypescriptcollection[gyre]
-
-%D First we define the new ones. Watch how we use the systematic name composition.
-
-\definetypescriptprefix [n:pagella] [TeXGyrePagella]
-\definetypescriptprefix [n:termes] [TeXGyreTermes]
-\definetypescriptprefix [n:heros] [TeXGyreHeros]
-\definetypescriptprefix [n:bonum] [TeXGyreBonum]
-\definetypescriptprefix [n:schola] [TeXGyreSchola]
-\definetypescriptprefix [n:adventor][TeXGyreAdventor]
-\definetypescriptprefix [n:cursor] [TeXGyreCursor]
-
-\definetypescriptprefix [f:pagella] [pl]
-\definetypescriptprefix [f:termes] [tm]
-\definetypescriptprefix [f:heros] [hv]
-\definetypescriptprefix [f:bonum] [bk]
-\definetypescriptprefix [f:schola] [cs]
-\definetypescriptprefix [f:adventor][ag]
-\definetypescriptprefix [f:cursor] [cr]
-
-\starttypescript [serif,sans,mono] [pagella,termes,heros,bonum,schola,adventor,cursor] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}r] [encoding=\typescriptthree]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}ri] [encoding=\typescriptthree]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}b] [encoding=\typescriptthree]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}bi] [encoding=\typescriptthree]
-
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Caps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}r-sc] [encoding=\typescriptthree]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}ri-sc] [encoding=\typescriptthree]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldCaps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}b-sc] [encoding=\typescriptthree]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}bi-sc] [encoding=\typescriptthree]
-
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Slanted] [\typescriptprefix{n:\typescripttwo}-Italic]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldSlanted] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
-
- \loadmapfile[q\typescriptprefix{f:\typescripttwo}-\typescriptthree.map]
-\stoptypescript
-
-\starttypescript [serif] [pagella,termes,bonum,schola] [name]
- \definefontsynonym [Serif] [\typescriptprefix{n:\typescripttwo}-Regular]
- \definefontsynonym [SerifItalic] [\typescriptprefix{n:\typescripttwo}-Italic]
- \definefontsynonym [SerifBold] [\typescriptprefix{n:\typescripttwo}-Bold]
- \definefontsynonym [SerifBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
- \definefontsynonym [SerifCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
- \definefontsynonym [SerifSlanted] [\typescriptprefix{n:\typescripttwo}-Slanted]
- \definefontsynonym [SerifBoldSlanted] [\typescriptprefix{n:\typescripttwo}-BoldSlanted]
-
- \definefontvariant [Serif][osf][Caps]
- \definefontvariant [Serif][sc] [Caps]
-
- \definefontsynonym [SerifRegular] [\typescriptprefix{n:\typescripttwo}-Regular]
- \definefontsynonym [SerifRegularCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
- \definefontsynonym [SerifItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
- \definefontsynonym [SerifBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps]
- \definefontsynonym [SerifBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
- \definefontsynonym [SerifCapsCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
- \definefontsynonym [SerifSlantedCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
- \definefontsynonym [SerifBoldSlantedCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
-\stoptypescript
-
-\starttypescript [sans] [heros,adventor] [name]
- \definefontsynonym [Sans] [\typescriptprefix{n:\typescripttwo}-Regular]
- \definefontsynonym [SansItalic] [\typescriptprefix{n:\typescripttwo}-Italic]
- \definefontsynonym [SansBold] [\typescriptprefix{n:\typescripttwo}-Bold]
- \definefontsynonym [SansBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
- \definefontsynonym [SansCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
- \definefontsynonym [SansSlanted] [\typescriptprefix{n:\typescripttwo}-Slanted]
- \definefontsynonym [SansBoldSlanted] [\typescriptprefix{n:\typescripttwo}-BoldSlanted]
-
- \definefontvariant [Sans][osf][Caps]
- \definefontvariant [Sans][sc] [Caps]
-
- \definefontsynonym [SansRegular] [\typescriptprefix{n:\typescripttwo}-Regular]
- \definefontsynonym [SansRegularCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
- \definefontsynonym [SansItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
- \definefontsynonym [SansBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps]
- \definefontsynonym [SansBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
- \definefontsynonym [SansCapsCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
- \definefontsynonym [SansSlantedCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
- \definefontsynonym [SansBoldSlantedCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
-\stoptypescript
-
-%D Here we overload the older (URW) fonts.
-
-% TeXGyrePagella
-%
-% qplr TeXGyrePagella-Regular
-% qplri TeXGyrePagella-Italic
-% qplb TeXGyrePagella-Bold
-% qplbi TeXGyrePagella-BoldItalic
-
-\starttypescript [serif] [palatino] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [Palatino] [\typescriptthree-qplr] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-Italic] [\typescriptthree-qplri] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-Bold] [\typescriptthree-qplb] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-BoldItalic] [\typescriptthree-qplbi] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-Caps] [\typescriptthree-qplr-sc] [encoding=\typescriptthree]
-
- \definefontsynonym [Palatino-Slanted] [Palatino-Italic]
- \definefontsynonym [Palatino-BoldSlanted] [Palatino-BoldItalic]
-
- \loadmapfile[qpl-\typescriptthree.map]
- \unloadmapfile[\typescriptthree-urw-palatino.map]
-\stoptypescript
-
-% TeXGyreTermes
-%
-% qtmr TeXGyreTermes-Regular
-% qtmri TeXGyreTermes-Italic
-% qtmb TeXGyreTermes-Bold
-% qtmbi TeXGyreTermes-BoldItalic
-
-\starttypescript [serif] [times] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [Times-Roman] [\typescriptthree-qtmr] [encoding=\typescriptthree]
- \definefontsynonym [Times-Italic] [\typescriptthree-qtmri] [encoding=\typescriptthree]
- \definefontsynonym [Times-Bold] [\typescriptthree-qtmb] [encoding=\typescriptthree]
- \definefontsynonym [Times-BoldItalic] [\typescriptthree-qtmbi] [encoding=\typescriptthree]
- \definefontsynonym [Times-Caps] [\typescriptthree-qtmr-sc] [encoding=\typescriptthree]
-
- \definefontsynonym [Times-Slanted] [Times-Italic]
- \definefontsynonym [Times-BoldSlanted] [Times-BoldItalic]
-
- \loadmapfile[qtm-\typescriptthree.map]
- \unloadmapfile[\typescriptthree-urw-times.map]
-\stoptypescript
-
-% TeXGyreHeros
-%
-% qtmr TeXGyreHeros-Regular
-% qtmri TeXGyreHeros-Italic
-% qtmb TeXGyreHeros-Bold
-% qtmbi TeXGyreHeros-BoldItalic
-
-\starttypescript [sans] [heros,helvetica] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [Helvetica] [\typescriptthree-qhvr] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-Oblique] [\typescriptthree-qhvri] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-Bold] [\typescriptthree-qhvb] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-BoldOblique] [\typescriptthree-qhvbi] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-Caps] [\typescriptthree-qhvr-sc] [encoding=\typescriptthree]
-
- \loadmapfile[qhv-\typescriptthree.map]
- \unloadmapfile[\typescriptthree-urw-helvetica.map]
-\stoptypescript
-
-% TeXGyreCursor
-%
-% qcrr TeXGyreCursor-Regular
-% qcrri TeXGyreCursor-Italic
-% qcrb TeXGyreCursor-Bold
-% qcrbi TeXGyreCursor-BoldItalic
-
-\starttypescript [mono] [cursor,courier] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [Courier] [\typescriptthree-qcrr] [encoding=\typescriptthree]
- \definefontsynonym [Courier-Bold] [\typescriptthree-qcrri] [encoding=\typescriptthree]
- \definefontsynonym [Courier-Oblique] [\typescriptthree-qcrb] [encoding=\typescriptthree]
- \definefontsynonym [Courier-BoldOblique] [\typescriptthree-qcrbi] [encoding=\typescriptthree]
- \fakecontrolspace
-
- \loadmapfile[qcr-\typescriptthree.map]
- \unloadmapfile[\typescriptthree-urw-courier.map]
-\stoptypescript
-
-% TeXGyreBonum
-%
-% qtmr TeXGyreBonum-Regular
-% qtmri TeXGyreBonum-Italic
-% qtmb TeXGyreBonum-Bold
-% qtmbi TeXGyreBonum-BoldItalic
-
-\starttypescript [serif] [bookman] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [Bookman-Light] [\typescriptthree-qbkr] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-LightItalic] [\typescriptthree-qbkri] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-DemiBold] [\typescriptthree-qbkb] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-DemiBoldItalic] [\typescriptthree-qbkbi] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-Light-Caps] [\typescriptthree-qbkr-sc] [encoding=\typescriptthree]
-
- \definefontsynonym [Bookman-LightSlanted] [Bookman-LightItalic]
- \definefontsynonym [Bookman-DemiBoldSlanted] [Bookman-DemiBoldItalic]
-
- \loadmapfile[qbk-\typescriptthree.map]
- \unloadmapfile[\typescriptthree-urw-bookman.map]
-\stoptypescript
-
-% TeXGyreScola
-%
-% qcsr TeXGyreSchola-Regular
-% qcsri TeXGyreSchola-Italic
-% qcsb TeXGyreSchola-Bold
-% qcsbi TeXGyreSchola-BoldItalic
-
-\starttypescript [serif] [schoolbook] [ec,texnansi,cs,el,qx,rm,t5,t2a,t2b,t2c,l7x]
- \definefontsynonym [Schoolbook-Roman] [\typescriptthree-qcsr] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-Italic] [\typescriptthree-qcsri] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-Bold] [\typescriptthree-qcsb] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-BoldItalic] [\typescriptthree-qcsbi] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-Roman-Caps] [\typescriptthree-qcsr-sc] [encoding=\typescriptthree]
-
- \definefontsynonym [Schoolbook-Slanted] [Schoolbook-Italic]
- \definefontsynonym [Schoolbook-BoldSlanted] [Schoolbook-BoldItalic]
-
- \loadmapfile[qcs-\typescriptthree.map]
- \unloadmapfile[\typescriptthree-urw-ncntrsbk.map]
-\stoptypescript
-
-% TeXGyreAdventor
-%
-% qagr TeXGyreAdventor-Regular
-% qagri TeXGyreAdventor-Italic
-% qagb TeXGyreAdventor-Bold
-% qagbi TeXGyreAdventor-BoldItalic
-
-% not previously defined
-
-\stoptypescriptcollection
diff --git a/tex/context/base/type-ini.tex b/tex/context/base/type-ini.mkii
index 17b1c2088..fa7b7934f 100644
--- a/tex/context/base/type-ini.tex
+++ b/tex/context/base/type-ini.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Typescript Macros (ini)}
+\writestatus{loading}{ConTeXt Typescript Macros / Initialization}
%D The default fontclass is empty. We could demand always using fontclasses,
%D and then make the calling macros simplier (always assume fontclass) but
@@ -76,35 +76,17 @@
{\splitfiletype{#1}%
\addtocommalist\splitoffname\typescriptfiles}}
-% \usetypescriptfile[\f!typeprefix exa] % some examples
-% \usetypescriptfile[\f!typeprefix syn] % font file synonyms
-% \usetypescriptfile[\f!typeprefix enc] % files and encodings
-% %usetypescriptfile[\f!typeprefix dis] % funny name remappings, obsolete
-% \usetypescriptfile[\f!typeprefix siz] % specific font sizes
-% \usetypescriptfile[\f!typeprefix map] % pdftex mapping
-% \usetypescriptfile[\f!typeprefix spe] % special macros
-% \usetypescriptfile[\f!typeprefix akb] % adobe karl berry names
-%
-% \beginXETEX \font
-% \usetypescriptfile[\f!typeprefix xtx] % xetex definitions
-% \endXETEX
-
\usetypescriptfile[\f!typeprefix tmf]
\usetypescriptfile[\f!typeprefix siz]
-\beginOLDTEX \font
+\ifnum\texengine=\xetexengine
+ \usetypescriptfile[\f!typeprefix otf]
+ \usetypescriptfile[\f!typeprefix xtx]
+\else
\usetypescriptfile[\f!typeprefix one]
%usetypescriptfile[\f!typeprefix gyr] % to be merged into one
\usetypescriptfile[\f!typeprefix akb] % will go away when gyre is merged
-\endOLDTEX
-
-\beginNEWTEX \font
- \usetypescriptfile[\f!typeprefix otf]
-\endNEWTEX
-
-\beginXETEX \font
- \usetypescriptfile[\f!typeprefix xtx]
-\endXETEX
+\fi
\usetypescriptfile[\f!typeprefix loc]
@@ -184,11 +166,9 @@
\@EAEAEA\newtoks\loadedtypescripts
\bgroup
\long\def\starttypescript##1\stoptypescript
- {\global\loadedtypescripts\@EA{\the\loadedtypescripts
- \starttypescript##1\stoptypescript}}%
+ {\global\loadedtypescripts\@EA{\the\loadedtypescripts\starttypescript##1\stoptypescript}}%
\long\def\starttypescriptcollection##1\stoptypescriptcollection
- {\global\loadedtypescripts\@EA{\the\loadedtypescripts
- \starttypescriptcollection##1\stoptypescriptcollection}}%
+ {\global\loadedtypescripts\@EA{\the\loadedtypescripts\starttypescriptcollection##1\stoptypescriptcollection}}%
\startreadingfile
\pushendofline
\unprotect
@@ -217,6 +197,75 @@
\setfalse\quittingtypescript
\fi}
+% % not faster, unless maybe toks
+%
+% \newcount\nofloadedtypescripts
+%
+% \def\startloadedtypescript
+% {\dotripleempty\dostartloadedtypescript}
+%
+% \let\stoploadedtypescript\relax
+%
+% \long\def\dostartloadedtypescript[#1][#2][#3]#4\stoptypescript
+% {\global\advance\nofloadedtypescripts\plusone
+% \long\setgvalue{\??ts=>\the\nofloadedtypescripts}{#4}%
+% \edef\temp%
+% {\iffirstargument [#1]\fi
+% \ifsecondargument[#2]\fi
+% \ifthirdargument [#3]\fi
+% \noexpand\csname\??ts=>\the\nofloadedtypescripts\noexpand\endcsname}%
+% \global\loadedtypescripts\@EA\@EA\@EA{\@EA\the\@EA\loadedtypescripts\@EA\starttypescript\temp\stoptypescript}}
+%
+% \def\startloadedtypescriptcollection
+% {\dosingleempty\dostartloadedtypescriptcollection}
+%
+% \def\dostartloadedtypescriptcollection[#1]{}
+% \def\stoploadedtypescriptcollection {}
+%
+% \def\dododousetypescript#1%
+% {\setfalse\quittingtypescript
+% \pushmacro\currenttypefile
+% \def\currenttypefile{#1}%
+% \ifconditional\preloadingtypescripts
+% % load files once, and use saved data
+% \def\loadedtypescripts{\csname\??ts:\c!file:#1\endcsname}%
+% \@EAEAEA\ifx\loadedtypescripts\relax
+% \@EAEAEA\newtoks\loadedtypescripts
+% \bgroup
+% %
+% \let\starttypescript \startloadedtypescript
+% \let\stoptypescript \stoploadedtypescript
+% \let\starttypescriptcollection\startloadedtypescriptcollection
+% \let\stoptypescriptcollection \stoploadedtypescriptcollection
+% %
+% \startreadingfile
+% \pushendofline
+% \unprotect
+% \readfile\currenttypefile\donothing\donothing
+% \protect
+% \popendofline
+% \stopreadingfile
+% \egroup
+% \fi
+% %\message{[\space\currenttypefile}%
+% \the\loadedtypescripts
+% %\message{\ifconditional\quittingtypescript quit\space\fi]}%
+% \else
+% % process files each time
+% \startreadingfile
+% \pushendofline
+% \unprotect
+% \readfile\currenttypefile\donothing\donothing
+% \protect
+% \popendofline
+% \stopreadingfile
+% \fi
+% \popmacro\currenttypefile
+% \ifconditional\quittingtypescript
+% \quitcommalist
+% \setfalse\quittingtypescript
+% \fi}
+
\def\usetypescriptonce
{\dotripleempty\dousetypescriptonce}
@@ -278,7 +327,7 @@
\let\typescripttwo \@@typescripttwo
\let\typescriptthree\@@typescriptthree
\let\typescriptmatch\empty
- \doifnextcharelse[\dostarttypescriptone\dostarttypescriptall}
+ \doifnextoptionalelse\dostarttypescriptone\dostarttypescriptall}
\long\def\dostarttypescriptall
{\iffirsttypescriptpass
@@ -309,10 +358,10 @@
{\dochecktypescript\@@typescriptthree\typescriptthree\redostarttypescriptthree}
\long\def\redostarttypescriptone
- {\doifnextcharelse[\dostarttypescripttwo\dostarttypescriptyes}
+ {\doifnextoptionalelse\dostarttypescripttwo\dostarttypescriptyes}
\long\def\redostarttypescripttwo
- {\doifnextcharelse[\dostarttypescriptthree\dostarttypescriptyes}
+ {\doifnextoptionalelse\dostarttypescriptthree\dostarttypescriptyes}
\long\def\redostarttypescriptthree
{\dostarttypescriptyes}
@@ -411,10 +460,6 @@
\def\doregisterloadedmapfile#1%
{\immediatewriteutilitycommand{\usedmapfile{=}{#1}}}
-\beginLUATEX
- \let\doregisterloadedmapfile\gobbleoneargument
-\endLUATEX
-
\def\doloadfontmapfile#1%
{\ifundefined{#1\c!state}%
\writestatus\m!fonts{using map file: #1}%
@@ -512,7 +557,7 @@
{\dodoubleargument\dodefinetypescriptprefix}
\def\dodefinetypescriptprefix[#1][#2]%
- {\setvalue{\??ts::#1}{#2}}
+ {\setgvalue{\??ts::#1}{#2}} % made global
% without testing:
%
@@ -577,40 +622,15 @@
\getparameters[\??tf#1#2][#3]%
\fi\fi\fi}
-% eventually we will split this module (no time now)
-
-% hm, math needs encoding
-
-% \beginLUATEX
-% \def\dodefinetypeface[#1][#2][#3][#4][#5][#6]%
-% {\dododefinetypeface[#1][#2]%
-% \iffifthargument % sixth is optional
-% % we need to expand since in #6 there can be a \typescripttwo
-% \expanded{\getparameters[\??ts][\s!rscale=\plusone,\s!features=,\s!fallbacks=,\s!text=,#6]}% \geteparameters
-% \pushmacro\relativefontsize
-% \pushmacro\fontclass
-% \let\relativefontsize\@@tsrscale
-% \setcurrentfontclass{#1}%
-% \letvalue{\fontclass\s!features }\@@tsfeatures % new per 16/6/2007
-% \letvalue{\fontclass\s!fallbacks}\@@tsfallbacks % new per 12/10/2008
-% \saverelativefontsize{#2}\relativefontsize % fall back
-% \savemathtextstyle\@@tstext % math text style (new per 28/4/2006)
-% \iftracetypescripts\writestatus\m!fonts{define: [#1] [#2] [#3] [#4]}\fi
-% \usetypescript[#3][#4][\t!name,\t!default,\t!special]%
-% \usetypescript[#3][#5][\t!size]%
-% \popmacro\fontclass
-% \popmacro\relativefontsize
-% \else\iffourthargument
-% \definetypeface[#1][#2][#3][#4][\s!default]%
-% \else\ifthirdargument
-% \getparameters[\??tf#1#2][#3]%
-% \fi\fi\fi}
-% \endLUATEX
-
\def\dododefinetypeface[#1][#2]% saveguard against redefinition
{\doifsomething{#1}
- {\doifundefined{\??tf#1\s!default}{\setgvalue{\??tf#1\s!default}{#2}}%
- \doifundefined{#1}{\unexpanded\setgvalue{#1}{\switchtotypeface[#1][#2]}}}}
+ {\ifcsname\??tf#1\s!default\endcsname \else
+ \registerfontclass{#1}%
+ \setgvalue{\??tf#1\s!default}{#2}%
+ \fi
+ \ifcsname#1\endcsname \else
+ \unexpanded\setgvalue{#1}{\switchtotypeface[#1][#2]}%
+ \fi}}
\def\setuptypeface% [class] [settings]
{\doquadrupleempty\doswitchtotypeface[\setupbodyfont][\fontclass]}
@@ -697,7 +717,13 @@
% new and obeying fontclasses (but still obsolete)
\def\doreadfontdefinitionfile#1#2% #1 = set/switch state
- {\ifundefined{\??tf#2\c!default}%
+ {\ifcsname\??tf#2\c!default\endcsname
+ \ifcase#1\relax
+ \switchtotypeface[#2]%
+ \else
+ \setuptypeface[#2]%
+ \fi
+ \else
\pushmacro\starttypescript
\scratchtoks\emptytoks
% locate downward compatibility definitions, one argument !
@@ -708,11 +734,7 @@
\stopreadingfile
\popmacro\starttypescript
\the\scratchtoks
- \else\ifcase#1\relax
- \switchtotypeface[#2]%
- \else
- \setuptypeface[#2]%
- \fi\fi}
+ \fi}
\fetchruntimecommand \typetypescript {\f!typeprefix\s!run}
diff --git a/tex/context/base/type-ini.mkiv b/tex/context/base/type-ini.mkiv
new file mode 100644
index 000000000..42c45bdaa
--- /dev/null
+++ b/tex/context/base/type-ini.mkiv
@@ -0,0 +1,705 @@
+%D \module
+%D [ file=type-ini,
+%D version=2001.03.05,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Typescript Macros / Initialization}
+
+%D The default fontclass is empty. We could demand always using fontclasses,
+%D and then make the calling macros simplier (always assume fontclass) but
+%D apart from downward compatibility issues, it would make global, class
+%D spanning definitions a pain. Some day we will introduce a default class.
+
+% torture test : proper typefaces (and namespace)
+%
+% \starttext
+% \usetypescript[modern][default] default: \setupbodyfont[modern] \eacute \eogonek \zcaron \acircumflexgrave
+% \usetypescript[modern][texnansi] texnansi: \setupbodyfont[modern] \eacute \eogonek \zcaron \acircumflexgrave
+% \usetypescript[modern][ec] ec: \setupbodyfont[modern] \eacute \eogonek \zcaron \acircumflexgrave
+% \usetypescript[modern][qx] qx: \setupbodyfont[modern] \eacute \eogonek \zcaron \acircumflexgrave
+% \usetypescript[modern][t5] t5: \setupbodyfont[modern] \eacute \eogonek \zcaron \acircumflexgrave
+% \stoptext
+%
+% torture test : no typeface, just definitions
+%
+% \starttext
+% {\setupbodyfont[reset] \setupbodyfont[cmr] cmr: \eacute \eogonek \zcaron \acircumflexgrave \endgraf}
+% {\setupbodyfont[reset] \setupbodyfont[plr] plr: \eacute \eogonek \zcaron \acircumflexgrave \endgraf}
+% {\setupbodyfont[reset] \setupbodyfont[csr] csr: \eacute \eogonek \zcaron \acircumflexgrave \endgraf}
+% {\setupbodyfont[reset] \setupbodyfont[vnr] vnr: \eacute \eogonek \zcaron \acircumflexgrave \endgraf}
+% {\setupbodyfont[reset] \setupbodyfont[aer] aer: \eacute \eogonek \zcaron \acircumflexgrave \endgraf}
+% \stoptext
+
+% \usetypescript [modern] [texnansi]
+%
+% normal : 1450 ms
+% exa quit : 1300 ms (150 ms)
+% preload : 825 ms (635 ms) (40-50%)
+%
+% \usetypescript [modern] [texnansi]
+% \usetypescript [palatino][texnansi]
+% \usetypescript [times] [texnansi]
+%
+% normal : 3200 ms
+% exa quit : 2700 ms ( 500 ms)
+% preload : 1300 ms (1900 ms) (60-70%)
+
+% \usetypescript [modern][\defaultencoding]
+% \usetypescript [map] [latin-modern-os] [\defaultencoding]
+% \setupbodyfont[modern]
+% test 1234 test
+
+\unprotect
+
+\def\starttypescriptcollection
+ {\dosingleempty\dostarttypescriptcollection}
+
+\def\dostarttypescriptcollection[#1]%
+ {}
+
+\def\stoptypescriptcollection
+ {}
+
+\let\typescriptfiles\empty
+
+\unexpanded\def\usetypescriptfile[#1]%
+ {\doifelse{#1}\v!reset
+ {\let\typescriptfiles\empty}
+ {\splitfiletype{#1}%
+ \addtocommalist\splitoffname\typescriptfiles}}
+
+% \usetypescriptfile[\f!typeprefix exa] % some examples
+% \usetypescriptfile[\f!typeprefix syn] % font file synonyms
+% \usetypescriptfile[\f!typeprefix enc] % files and encodings
+% %usetypescriptfile[\f!typeprefix dis] % funny name remappings, obsolete
+% \usetypescriptfile[\f!typeprefix siz] % specific font sizes
+% \usetypescriptfile[\f!typeprefix map] % pdftex mapping
+% \usetypescriptfile[\f!typeprefix spe] % special macros
+% \usetypescriptfile[\f!typeprefix akb] % adobe karl berry names
+
+\usetypescriptfile[\f!typeprefix tmf]
+\usetypescriptfile[\f!typeprefix siz]
+\usetypescriptfile[\f!typeprefix otf]
+\usetypescriptfile[\f!typeprefix loc]
+
+% SO FAR
+
+\let\currenttypescripts\empty
+
+\newif\iftypescriptfound
+
+\let\@@typescriptone \empty \let\typescriptone \empty
+\let\@@typescripttwo \empty \let\typescripttwo \empty
+\let\@@typescriptthree\empty \let\typescriptthree\empty
+
+% method 2 is for Hans van der Meer
+
+\newtoks\documenttypescripts
+
+\chardef\typescriptmethod\plusone % 1: empty==all==true 2: empty==false
+\chardef\typescriptstate \plustwo % 1: process 2: store
+
+\unexpanded\def\usetypescript {\let\typescriptmethod\plusone\dotripleempty\dousetypescript}
+\unexpanded\def\usetypescriptexact{\let\typescriptmethod\plustwo\dotripleempty\dousetypescript}
+
+\def\dousetypescript[#1][#2][#3]%
+ {\normalexpanded{\noexpand\dodousetypescript[#1][#2][#3]}}
+
+\def\dodousetypescript[#1][#2][#3]% also loads type-loc, a user file
+ {\pushmacro\@@typescriptone \edef\@@typescriptone {\truetypescript{#1}}%
+ \pushmacro\@@typescripttwo \edef\@@typescripttwo {\truetypescript{#2}}%
+ \pushmacro\@@typescriptthree\edef\@@typescriptthree{\truetypescript{#3}}%
+ \pushmacro\typescriptone
+ \pushmacro\typescripttwo
+ \pushmacro\typescriptthree
+ \pushmacro\typescriptmethod
+ \pushmacro\typescriptstate \let\typescriptstate\plusone % process
+ \pushmacro\stoptypescript
+ \typescriptfoundfalse
+ \iftracetypescripts\writestatus\m!fonts{request: [\@@typescriptone] [\@@typescripttwo] [\@@typescriptthree]}\fi
+ \processcommacommand[\typescriptfiles]\dododousetypescript
+ \the\documenttypescripts
+ \firsttypescriptpassfalse % testen
+ \popmacro\stoptypescript
+ \popmacro\typescriptstate
+ \popmacro\typescriptmethod
+ \popmacro\typescriptthree
+ \popmacro\typescripttwo
+ \popmacro\typescriptone
+ \popmacro\@@typescriptthree
+ \popmacro\@@typescripttwo
+ \popmacro\@@typescriptone}
+
+% simple version:
+%
+% \def\dododousetypescript#1%
+% {\startreadingfile
+% \pushmacro\currenttypefile
+% \def\currenttypefile{#1}%
+% \def\currenttypefile{#1}%
+% \readfile\currenttypefile\donothing\donothing
+% \popmacro\currenttypefile
+% \stopreadingfile}
+%
+% tricky version:
+
+\newconditional\preloadingtypescripts
+
+\def\preloadtypescripts{\ifproductionrun\settrue\preloadingtypescripts\fi}
+
+\long\def\xxstarttypescript#1\stoptypescript
+ {\global\loadedtypescripts\@EA{\the\loadedtypescripts\starttypescript#1\stoptypescript}}
+
+\long\def\xxstarttypescriptcollection#1\stoptypescriptcollection
+ {\global\loadedtypescripts\@EA{\the\loadedtypescripts\starttypescriptcollection#1\stoptypescriptcollection}}
+
+\def\dododousetypescript#1%
+ {\setfalse\quittingtypescript
+ \pushmacro\currenttypefile
+ \def\currenttypefile{#1}%
+ \ifconditional\preloadingtypescripts
+ % load files once, and use saved data
+ \def\loadedtypescripts{\csname\??ts:\c!file:#1\endcsname}%
+ \@EAEAEA\ifx\loadedtypescripts\relax
+ \@EAEAEA\newtoks\loadedtypescripts
+ \bgroup
+ \let\starttypescript\xxstarttypescript
+ \let\starttypescriptcollection\xxstarttypescriptcollection
+ \startreadingfile
+ \pushendofline
+ \unprotect
+ \readfile\currenttypefile\donothing\donothing
+ \protect
+ \popendofline
+ \stopreadingfile
+ \egroup
+ \fi
+ %\message{[\space\currenttypefile}%
+ \the\loadedtypescripts
+ %\message{\ifconditional\quittingtypescript quit\space\fi]}%
+ \else
+ % process files each time
+ \startreadingfile
+ \pushendofline
+ \unprotect
+ \readfile\currenttypefile\donothing\donothing
+ \protect
+ \popendofline
+ \stopreadingfile
+ \fi
+ \popmacro\currenttypefile
+ \ifconditional\quittingtypescript
+ \quitcommalist
+ \setfalse\quittingtypescript
+ \fi}
+
+% % not faster, unless maybe toks
+%
+% \newcount\nofloadedtypescripts
+%
+% \def\startloadedtypescript
+% {\dotripleempty\dostartloadedtypescript}
+%
+% \let\stoploadedtypescript\relax
+%
+% \long\def\dostartloadedtypescript[#1][#2][#3]#4\stoptypescript
+% {\global\advance\nofloadedtypescripts\plusone
+% \long\setgvalue{\??ts=>\the\nofloadedtypescripts}{#4}%
+% \edef\temp%
+% {\iffirstargument [#1]\fi
+% \ifsecondargument[#2]\fi
+% \ifthirdargument [#3]\fi
+% \noexpand\csname\??ts=>\the\nofloadedtypescripts\noexpand\endcsname}%
+% \global\loadedtypescripts\@EA\@EA\@EA{\@EA\the\@EA\loadedtypescripts\@EA\starttypescript\temp\stoptypescript}}
+%
+% \def\startloadedtypescriptcollection
+% {\dosingleempty\dostartloadedtypescriptcollection}
+%
+% \def\dostartloadedtypescriptcollection[#1]{}
+% \def\stoploadedtypescriptcollection {}
+%
+% \def\dododousetypescript#1%
+% {\setfalse\quittingtypescript
+% \pushmacro\currenttypefile
+% \def\currenttypefile{#1}%
+% \ifconditional\preloadingtypescripts
+% % load files once, and use saved data
+% \def\loadedtypescripts{\csname\??ts:\c!file:#1\endcsname}%
+% \@EAEAEA\ifx\loadedtypescripts\relax
+% \@EAEAEA\newtoks\loadedtypescripts
+% \bgroup
+% %
+% \let\starttypescript \startloadedtypescript
+% \let\stoptypescript \stoploadedtypescript
+% \let\starttypescriptcollection\startloadedtypescriptcollection
+% \let\stoptypescriptcollection \stoploadedtypescriptcollection
+% %
+% \startreadingfile
+% \pushendofline
+% \unprotect
+% \readfile\currenttypefile\donothing\donothing
+% \protect
+% \popendofline
+% \stopreadingfile
+% \egroup
+% \fi
+% %\message{[\space\currenttypefile}%
+% \the\loadedtypescripts
+% %\message{\ifconditional\quittingtypescript quit\space\fi]}%
+% \else
+% % process files each time
+% \startreadingfile
+% \pushendofline
+% \unprotect
+% \readfile\currenttypefile\donothing\donothing
+% \protect
+% \popendofline
+% \stopreadingfile
+% \fi
+% \popmacro\currenttypefile
+% \ifconditional\quittingtypescript
+% \quitcommalist
+% \setfalse\quittingtypescript
+% \fi}
+
+\def\usetypescriptonce
+ {\dotripleempty\dousetypescriptonce}
+
+\def\dousetypescriptonce[#1][#2][#3]%
+ {\doifelseflagged{ts:#1:#2:#3}%
+ {\writestatus\m!fonts{once (#1) (#2) (#3)}}
+ {\setflag{ts:#1:#2:#3}%
+ \normalexpanded{\noexpand\dodousetypescript[#1][#2][#3]}}}
+
+% \definetypescriptsynonym[lbr][cmr]
+
+\def\definetypescriptsynonym
+ {\dodoubleempty\dodefinetypescriptsynonym}
+
+\def\dodefinetypescriptsynonym[#1][#2]%
+ {\ifsecondargument\setevalue{\??tm#1}{#2}\fi}
+
+\def\truetypescript#1%
+ {\ifcsname\??tm#1\endcsname
+ \@EA\truetypescript\csname\??tm#1\endcsname\else#1%
+ \fi}
+
+% script [serif] [default] [size]
+% script [serif] [computer-modern] [size]
+% script [serif] [computer-modern] [ec]
+% script [serif] [computer-modern] [name]
+% script [serif] [computer-modern] [special]
+
+% todo, make firsttypescriptpass conditional
+
+\newif\iffirsttypescriptpass \firsttypescriptpasstrue
+
+\prependtoks\firsttypescriptpasstrue\to\everyjob
+
+\def\typescript@@all{all}
+
+\newif\iftracetypescripts
+
+\def\starttypescript
+ {\ifcase\typescriptstate
+ % 0 = skip
+ \@EA\gobbleuntil\@EA\stoptypescript
+ \or
+ % 1 = process
+ \expandafter\dostarttypescript
+ \or
+ % 2 = store
+ \expandafter\nostarttypescript
+ \else
+ % ? = skip
+ \@EA\gobbleuntil\@EA\stoptypescript
+ \fi}
+
+\long\def\nostarttypescript#1\stoptypescript
+ {\appendtoks\starttypescript#1\stoptypescript\to\documenttypescripts}
+
+\def\dostarttypescript
+ {\let\typescriptone \@@typescriptone
+ \let\typescripttwo \@@typescripttwo
+ \let\typescriptthree\@@typescriptthree
+ \let\typescriptmatch\empty
+ \doifnextoptionalelse\dostarttypescriptone\dostarttypescriptall}
+
+\long\def\dostarttypescriptall
+ {\iffirsttypescriptpass
+ \expandafter\doprocesstypescript
+ \else
+ % skip this since it may do unwanted resets, like
+ % setting symbolic font names to unknown, especially
+ % in run time user type scripts
+ \expandafter\noprocesstypescript
+ \fi}
+
+\long\def\dostarttypescriptyes
+ {\ifdone
+ \typescriptfoundtrue
+ \iftracetypescripts\writestatus\m!fonts{match:\ifx\currenttypefile\relax\space *\fi \typescriptmatch}\fi
+ \expandafter\doprocesstypescript
+ \else
+ \expandafter\noprocesstypescript
+ \fi}
+
+\long\def\dostarttypescriptone
+ {\dochecktypescript\@@typescriptone\typescriptone\redostarttypescriptone}
+
+\long\def\dostarttypescripttwo
+ {\dochecktypescript\@@typescripttwo\typescripttwo\redostarttypescripttwo}
+
+\long\def\dostarttypescriptthree
+ {\dochecktypescript\@@typescriptthree\typescriptthree\redostarttypescriptthree}
+
+\long\def\redostarttypescriptone
+ {\doifnextoptionalelse\dostarttypescripttwo\dostarttypescriptyes}
+
+\long\def\redostarttypescripttwo
+ {\doifnextoptionalelse\dostarttypescriptthree\dostarttypescriptyes}
+
+\long\def\redostarttypescriptthree
+ {\dostarttypescriptyes}
+
+\def\doprocesstypescript
+ {\pushmacro\fontclass}
+
+\def\stoptypescript
+ {\popmacro\fontclass}
+
+\long\def\noprocesstypescript#1\stoptypescript
+ {}
+
+\let\typescriptmatch\empty
+
+\def\dochecktypescript#1#2#3[#4]% script use value next
+ {\donefalse
+ \def\@@typescriptcheck{#4}%
+ \ifx\@@typescriptcheck\empty % no longer needed / met
+ \ifcase\typescriptmethod\or\donetrue\fi
+ \else\ifx#1\typescript@@all
+ \donetrue
+ \else\ifx\@@typescriptcheck\typescript@@all
+ \donetrue
+ \else\ifx#1\@@typescriptcheck % saves 10% trace so probably faster too
+ \donetrue
+ \let#2\@@typescriptcheck
+ \else
+ \normalexpanded{\noexpand\doifcommonelse{\@@typescriptcheck}{#1}}\donetrue\donefalse
+ \ifdone
+ \let#2\commalistelement
+ \fi
+ \fi\fi\fi\fi
+ \ifdone
+ \edef\typescriptmatch{\typescriptmatch\space[#4]}%
+ \expandafter#3%
+ \else
+ \expandafter\noprocesstypescript
+ \fi}
+
+%D Yet another speed up: when issued inside typescript, the call
+%D
+%D \starttyping
+%D \quittypescriptscanning
+%D \stoptyping
+%D
+%D quits further loading. For an example, see type-exa:
+
+\newconditional\quittingtypescript \setfalse\quittingtypescript
+
+\def\quittypescriptscanning{\settrue\quittingtypescript}
+
+% status
+%
+% 1 loaded
+% 2 reported
+% 3 preloaded
+
+% flags ipv \c!state, more flag values
+
+\def\dopreloadmapfile#1%
+ {\splitfiletype{#1}%
+ \writestatus\m!fonts{assuming map file: \splitoffname}%
+ \setxvalue{\splitoffname \c!state}{3}%
+ \doglobal\removefromcommalist\splitoffname\allfontmapsfiles}
+
+\def\preloadmapfile[#1]{\processcommacommand[#1]\dopreloadmapfile}
+\def\loadmapfile [#1]{\processcommacommand[#1]\loadthemapfile}
+\def\unloadmapfile [#1]{\processcommacommand[#1]\unloadthemapfile}
+
+% too soon, no driver known, \ifproductionrun \loadallfontmapfiles \fi
+
+\def\loadthemapfile#1%
+ {\splitfiletype{#1}%
+ \doglobal\addtocommalist\splitoffname\allfontmapsfiles}
+
+\def\unloadthemapfile#1%
+ {\splitfiletype{#1}%
+ \doglobal\removefromcommalist\splitoffname\allfontmapsfiles}
+
+\let\usedmapfile \gobbletwoarguments
+\let\usedmapline \gobbletwoarguments
+\let\doregisterloadedmapfile\gobbleoneargument
+
+\def\doloadfontmapfile#1%
+ {\ifcsname#1\c!state\endcsname\else
+ \writestatus\m!fonts{using map file: #1}%
+ \doregisterloadedmapfile{#1}%
+ \doloadmapfile{=}{#1.\f!fontmapextension}% +/add =/replace -/remove
+ \setxvalue{#1\c!state}{1}%
+ \fi}
+
+\def\doreportfontmapfile#1%
+ {\ifcsname#1\c!state\endcsname\else
+ \writestatus\m!fonts{needs map file: #1}%
+ \setxvalue{#1\c!state}{2}%
+ \fi}
+
+\def\loadallfontmapfiles
+ {%\message{[\allfontmapsfiles]}%
+ \ifconditional\resettingmapfile
+ \writestatus\m!fonts{resetting map file list}%
+ \doresetmapfilelist
+ \global\setfalse\resettingmapfile
+ \fi
+ \ifx\allfontmapsfiles\empty \else
+ \ifautoloadmapfiles
+ \processcommacommand[\allfontmapsfiles]\doloadfontmapfile
+ \else
+ \processcommacommand[\allfontmapsfiles]\doreportfontmapfile
+ \fi
+ \forgetmapfiles
+ \fi}
+
+\def\loadmapline
+ {\dodoubleempty\dodoloadmapline}
+
+\def\dodoloadmapline[#1][#2]%
+ {\loadallfontmapfiles % ! ! !
+ \ifsecondargument
+ \immediatewriteutilitycommand{\usedmapline{#1}{#2}}%
+ \doloadmapline{#1}{#2}% special
+ \else
+ \loadmapline[=][#1]%
+ %\immediatewriteutilitycommand{\usedmapline{=}{#2}}%
+ %\doloadmapline{=}{#1}% special
+ \fi}
+
+% since this is driver dependent, and since we may set map files
+% before an output format is defined, we need to postpone it; we
+% cannot use starttext as hook because an output switch can be part
+% of a style; an alternative is to no longer permit driver switching
+% after the first \starttext, but that will break compatibility
+% because \startcomponent ... \environment ... is pretty legal.
+
+% the map directives need to end up in the right place in the stream
+
+% hm, the timing of when pdftex needs the map file info keeps changing;
+% it's really time to move to map line support
+
+% \appendtoks \loadallfontmapfiles \to \everyPDFximage
+% \appendtoks \loadallfontmapfiles \to \everystarttext
+% \appendtoks \loadallfontmapfiles \to \everybeforepagebody
+
+\everybeforeshipout \expandafter
+ {\expandafter\appendtoks
+ \expandafter\loadallfontmapfiles
+ \expandafter\to
+ \expandafter\pageboundsettings
+ \the\everybeforeshipout}
+
+\newif\ifautoloadmapfiles
+
+\let\allfontmapsfiles\empty
+
+\def\forgetmapfiles
+ {\globallet\allfontmapsfiles\empty}
+
+\newconditional\resettingmapfile
+
+\def\resetmapfiles
+ {\global\settrue\resettingmapfile}
+
+\def\disablemapfiles
+ {\resetmapfiles
+ \forgetmapfiles}
+
+%D A handy shortcut:
+
+% \definetypescriptprefix[serif][Serif]
+% \definetypescriptprefix[sans] [Sans]
+% \definetypescriptprefix[mono] [Mono]
+%
+%\starttypescript [serif,sans,mono] [handling,hanging,hz] [pure,normal,hz,quality]
+% \setupfontsynonym [\typescriptprefix\typescriptone] [handling=\typescriptthree]
+% \stoptypescript
+
+\def\definetypescriptprefix
+ {\dodoubleargument\dodefinetypescriptprefix}
+
+\def\dodefinetypescriptprefix[#1][#2]%
+ {\setgvalue{\??ts::#1}{#2}} % made global
+
+% without testing:
+%
+% \def\typescriptprefix#1%
+% {\csname\??ts::#1\endcsname}
+%
+% with testing:
+
+\def\typescriptprefix#1%
+ {\executeifdefined{\??ts::#1}{#1}}
+
+% defining typefaces:
+%
+% \definetypeface [#1:joke] [#2:rm]
+% \definetypeface [#1:joke] [#2:rm] [#3:...]
+% \definetypeface [#1:joke] [#2:rm] [#3:serif] [#4:lucida] [#5:size] [#6:...]
+
+\def\definetypeface
+ {\dosixtupleargument\dodefinetypeface}
+
+\def\tsvar#1#2% \executeifdefined{\??ts#1}{#2}
+ {\@EA\ifx\csname\??ts#1\endcsname\empty
+ #2%
+ \else
+ \csname\??ts#1\endcsname
+ \fi}
+
+% #1=main #2=rm #3=serif #4=fontname #5=size #6=settings
+
+\def\typefaceencoding{\defaultencoding}
+
+% we can use \rawgetparameters or \rawgeteparameters
+
+\ifx\mkdodefinetypeface\undefined
+ \let\mkdodefinetypeface\gobblefivearguments
+\fi
+
+\def\dodefinetypeface[#1][#2][#3][#4][#5][#6]%
+ {\dododefinetypeface[#1][#2]%
+ \iffifthargument % sixth is optional
+ % we need to expand since in #6 there can be a \typescripttwo
+ \normalexpanded{\noexpand\getparameters[\??ts][\s!rscale=\plusone,\s!encoding=\defaultencoding,\s!features=,\s!fallbacks=,\s!text=,#6]}% \geteparameters
+ \pushmacro\relativefontsize
+ \pushmacro\typefaceencoding
+ \pushmacro\fontclass
+ \let\relativefontsize\@@tsrscale
+ \let\typefaceencoding\@@tsencoding
+ \setcurrentfontclass{#1}%
+ \letvalue{\fontclass\s!features }\@@tsfeatures % new per 16/6/2007
+ \letvalue{\fontclass\s!fallbacks}\@@tsfallbacks % new per 12/10/2008
+ \saverelativefontsize{#2}\relativefontsize % fall back
+ \savemathtextstyle\@@tstext % math text style (new per 28/4/2006)
+ \iftracetypescripts\writestatus\m!fonts{define: [#1] [#2] [#3] [#4] / \typefaceencoding}\fi
+% \usetypescript[#3,\t!map][#4][\t!name,\t!default,\typefaceencoding,\t!special]% map is needed for backward cmp
+ \usetypescript[#3][#4][\t!name,\t!default,\typefaceencoding]% typefaceencoding=empty forces [#3][#4]
+ \usetypescript[#3][#5][\t!size]%
+ \popmacro\fontclass
+ \popmacro\typefaceencoding
+ \popmacro\relativefontsize
+ \else\iffourthargument
+ \definetypeface[#1][#2][#3][#4][\s!default]%
+ \else\ifthirdargument
+ \getparameters[\??tf#1#2][#3]%
+ \fi\fi\fi}
+
+\def\dododefinetypeface[#1][#2]% saveguard against redefinition
+ {\doifsomething{#1}
+ {\ifcsname\??tf#1\s!default\endcsname \else
+ \registerfontclass{#1}%
+ \setgvalue{\??tf#1\s!default}{#2}%
+ \fi
+ \ifcsname#1\endcsname \else
+ \unexpanded\setgvalue{#1}{\switchtotypeface[#1][#2]}%
+ \fi}}
+
+\def\setuptypeface% [class] [settings]
+ {\doquadrupleempty\doswitchtotypeface[\setupbodyfont][\fontclass]}
+
+\unexpanded\def\switchtotypeface% [class] [settings]
+ {\doquadrupleempty\doswitchtotypeface[\switchtobodyfont][\globalfontclass]}
+
+\def\doswitchtotypeface[#1][#2][#3][#4]%
+ {%\doifinsetelse{\s!default,\v!reset}{#3}
+ % {\setcurrentfontclass\empty}
+ % {\setcurrentfontclass{#3}}%
+ \setcurrentfontclass{#3}%
+ \let\globalfontclass#2%
+ \iffourthargument
+ #1[#4]%
+ \else\ifx\fontclass\empty
+ #1[\c!rm]%
+ \else
+ \doifdefinedelse{\??tf\fontclass\s!default}
+ {#1[\getvalue{\??tf\fontclass\s!default}]}
+ {#1[\c!rm]}%
+ \fi \fi
+ \ifmmode\mr\else\tf\fi} % needed ?
+
+\def\usetypefile[#1]% recurses on path !
+ {\readfile{\f!typeprefix#1}\donothing\donothing}
+
+%D For Taco:
+%D
+%D \starttyping
+%D \inherittypeface[palatino][rm][postscript]
+%D \inherittypeface[palatino][rm][\fontclass]
+%D \inherittypeface[palatino][rm] % == \fontclass
+%D \inherittypeface[palatino] % == [rm,ss,tt,mm]
+%D \stoptyping
+
+\def\inherittypeface
+ {\dotripleempty\doinherittypeface}
+
+\def\doinherittypeface[#1][#2][#3]%
+ {\doifelsenothing{#2}
+ {\doinherittypeface[#1][\c!rm,\c!ss,\c!tt,\c!mm][\fontclass]}
+ {\doifnot{#1}{#3}
+ {\def\docommand##1{\setevalue{#1-##1}{#3}}%
+ \processcommalist[#2]\docommand}}}
+
+%D This hook sinto the font mechanism with:
+
+\def\checkfontclass#1%
+ {\edef\fontclass{\executeifdefined{\fontclass-#1}{\fontclass}}}
+
+%D For backward compatibility we reimplement the font file
+%D loading macro.
+
+\ifx\normaldoreadfontdefinitionfile\undefined
+ \let\normaldoreadfontdefinitionfile\doreadfontdefinitionfile
+\fi
+
+\def\doreadfontdefinitionfile#1#2% #1 = set/switch state
+ {\ifcsname\??tf#2\c!default\endcsname
+ \ifcase#1\relax
+ \switchtotypeface[#2]%
+ \else
+ \setuptypeface[#2]%
+ \fi
+ \else
+ \pushmacro\starttypescript
+ \scratchtoks\emptytoks
+ % locate downward compatibility definitions, one argument !
+ \long\def\starttypescript[##1]##2\stoptypescript
+ {\doif{##1}{#2}{\scratchtoks{##2}}}
+ \startreadingfile
+ \readfile{\f!typeprefix pre}\donothing\donothing
+ \stopreadingfile
+ \popmacro\starttypescript
+ \the\scratchtoks
+ \fi}
+
+\fetchruntimecommand \typetypescript {\f!typeprefix\s!run}
+
+\protect \endinput
diff --git a/tex/context/base/type-mac.mkii b/tex/context/base/type-mac.mkii
new file mode 100644
index 000000000..feedcd43d
--- /dev/null
+++ b/tex/context/base/type-mac.mkii
@@ -0,0 +1,220 @@
+%D \module
+%D [ file=type-mac,
+%D version=2009.03.10,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Mac OS X Definitions,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright=Wolfgang Schuster]
+%C
+%C This module is part of the \CONTEXT\ macro||package. See
+%C mreadme.pdf for details.
+
+\definetypescriptprefix [f:andalemono] [Andale Mono]
+\definetypescriptprefix [f:chalkboard] [Chalkboard]
+\definetypescriptprefix [f:cochin] [Cochin]
+\definetypescriptprefix [f:comicsans] [Comic Sans MS]
+\definetypescriptprefix [f:couriernew] [Courier New]
+\definetypescriptprefix [f:georgia] [Georgia]
+\definetypescriptprefix [f:lucidagrande] [Lucida Grande]
+\definetypescriptprefix [f:monaco] [Monaco]
+\definetypescriptprefix [f:tahoma] [Tahoma]
+\definetypescriptprefix [f:timesnewroman] [Times New Roman]
+\definetypescriptprefix [f:trebuchet] [Trebuchet MS]
+\definetypescriptprefix [f:verdana] [Verdana]
+
+% American Typewriter
+
+\starttypescript [serif] [americantypewriter-light-condensed,americantypewriter-condensed,americantypewriter-light,americantypewriter]
+ \definefontsynonym [AmericanTypewriter-Light] [name:American Typewriter Light] [features=default]
+ \definefontsynonym [AmericanTypewriter-Regular] [name:American Typewriter] [features=default]
+ \definefontsynonym [AmericanTypewriter-Bold] [name:American Typewriter Bold] [features=default]
+ \definefontsynonym [AmericanTypewriter-LightCond] [name:American Typewriter Condensed Light] [features=default]
+ \definefontsynonym [AmericanTypewriter-Condensed] [name:American Typewriter Condensed] [features=default]
+ \definefontsynonym [AmericanTypewriter-BoldCond] [name:American Typewriter Condensed Bold] [features=default]
+\stoptypescript
+
+% Arial / Arial Narrow / Arial Rounded / Arial Unicode
+
+\starttypescript [sans] [arial-narrow,arial-condensed,arial,arial-rounded,arial-unicode]
+ \definefontsynonym [Arial-Condensed] [name:Arial Narrow] [features=default]
+ \definefontsynonym [Arial-ItalicCond] [name:Arial Narrow Italic] [features=default]
+ \definefontsynonym [Arial-BoldCond] [name:Arial Narrow Bold] [features=default]
+ \definefontsynonym [Arial-BoldItalicCond] [name:Arial Narrow Bold Italic] [features=default]
+ \definefontsynonym [Arial-Regular] [name:Arial] [features=default]
+ \definefontsynonym [Arial-Italic] [name:Arial Italic] [features=default]
+ \definefontsynonym [Arial-Bold] [name:Arial Bold] [features=default]
+ \definefontsynonym [Arial-BoldItalic] [name:Arial Bold Italic] [features=default]
+ \definefontsynonym [Arial-Black] [name:Arial Black] [features=default]
+ \definefontsynonym [Arial-Unicode] [name:Arial Unicode MS] [features=default]
+ \definefontsynonym [Arial-Rounded] [name:Arial Rounded MT Bold] [features=default]
+\stoptypescript
+
+% Baskerville
+
+\starttypescript [serif] [baskerville]
+ \definefontsynonym [Baskerville-Regular] [name:Baskerville] [features=default]
+ \definefontsynonym [Baskerville-Italic] [name:Baskerville Italic] [features=default]
+ \definefontsynonym [Baskerville-Medium] [name:Baskerville SemiBold] [features=default]
+ \definefontsynonym [Baskerville-MediumItalic] [name:Baskerville SemiBold Italic] [features=default]
+ \definefontsynonym [Baskerville-Bold] [name:Baskerville Bold] [features=default]
+ \definefontsynonym [Baskerville-BoldItalic] [name:Baskerville Bold Italic] [features=default]
+\stoptypescript
+
+% Big Caslon
+
+\starttypescript [serif] [caslon,bigcaslon]
+ \definefontsynonym [BigCaslon-Medium] [name:Big Caslon Medium] [features=default]
+\stoptypescript
+
+% Copperplate
+
+\starttypescript [sans] [copperplate-light,copperplate]
+ \definefontsynonym [Copperplate-Light] [name:Copperplate Light] [features=default]
+ \definefontsynonym [Copperplate-Regular] [name:Copperplate] [features=default]
+ \definefontsynonym [Copperplate-Bold] [name:Copperplate Bold] [features=default]
+\stoptypescript
+
+% Futura
+
+\starttypescript [sans] [futura-condensed,futura]
+ \definefontsynonym [Futura-MediumCond] [name:Futura Condensed Medium] [features=default]
+ \definefontsynonym [Futura-Medium] [name:Futura Medium] [features=default]
+ \definefontsynonym [Futura-MediumItalic] [name:Futura Medium Italic] [features=default]
+ \definefontsynonym [Futura-BoldCond] [name:Futura Condensed ExtraBold] [features=default]
+\stoptypescript
+
+% Gill Sans
+
+\starttypescript [sans] [gillsans-light,gillsans]
+ \definefontsynonym [GillSans-Light] [name:Gill Sans Light] [features=default]
+ \definefontsynonym [GillSans-LightItalic] [name:Gill Sans Light Italic] [features=default]
+ \definefontsynonym [GillSans-Regular] [name:Gill Sans] [features=default]
+ \definefontsynonym [GillSans-Italic] [name:Gill Sans Italic] [features=default]
+ \definefontsynonym [GillSans-Bold] [name:Gill Sans Bold] [features=default]
+ \definefontsynonym [GillSans-BoldItalic] [name:Gill Sans Bold Italic] [features=default]
+\stoptypescript
+
+% Helvetica Neuse
+
+\starttypescript [sans] [helvetica-neue-ultralight,helvetica-neue-light,helvetica-neue,helvetica-neue-boldcondensed]
+ \definefontsynonym [HelveticaNeue-UltraLight] [name:Helvetica Neue UltraLight] [features=default]
+ \definefontsynonym [HelveticaNeue-UltraLightItalic] [name:Helvetica Neue UltraLight Italic] [features=default]
+ \definefontsynonym [HelveticaNeue-Light] [name:Helvetica Neue Light] [features=default]
+ \definefontsynonym [HelveticaNeue-LightItalic] [name:Helvetica Neue Light Italic] [features=default]
+ \definefontsynonym [HelveticaNeue-Regular] [name:Helvetica Neue] [features=default]
+ \definefontsynonym [HelveticaNeue-Italic] [name:Helvetica Neue Italic] [features=default]
+ \definefontsynonym [HelveticaNeue-Bold] [name:Helvetica Neue Bold] [features=default]
+ \definefontsynonym [HelveticaNeue-BoldItalic] [name:Helvetica Neue Bold Italic] [features=default]
+ \definefontsynonym [HelveticaNeue-BoldCond] [name:Helvetica Neue Condensed Bold] [features=default]
+ \definefontsynonym [HelveticaNeue-BlackCond] [name:Helvetica Neue Condensed Black] [features=default]
+\stoptypescript
+
+% Hiragino Mincho
+
+\starttypescript [serif] [hiragino-mincho]
+ \definefontsynonym [HiraginoMinchoPro-Regular] [name:Hiragino Mincho Pro W3] [features=japanese]
+ \definefontsynonym [HiraginoMinchoPro-Bold] [name:Hiragino Mincho Pro W6] [features=japanese]
+ \definefontsynonym [HiraginoMinchoProN-Regular] [name:Hiragino Mincho ProN W3] [features=japanese]
+ \definefontsynonym [HiraginoMinchoProN-Bold] [name:Hiragino Mincho ProN W6] [features=japanese]
+\stoptypescript
+
+% Hiragino Maru
+
+\starttypescript [sans] [hiragino-maru]
+ \definefontsynonym [HiraginoMaruGothicPro-Regular] [name:Hiragino Maru Gothic Pro W4] [features=japanese]
+ \definefontsynonym [HiraginoMaruGothicProN-Regular] [name:Hiragino Maru Gothic ProN W4] [features=japanese]
+\stoptypescript
+
+% Hiragino Kaku
+
+\starttypescript [sans] [hiragino-kaku]
+ \definefontsynonym [HiraginoKakuGothicPro-Regular] [name:Hiragino Kaku Gothic Pro W3] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicPro-Bold] [name:Hiragino Kaku Gothic Pro W6] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicStd-Black] [name:Hiragino Kaku Gothic Std W8] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicProN-Regular] [name:Hiragino Kaku Gothic Pron W3] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicProN-Bold] [name:Hiragino Kaku Gothic ProN W6] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicStdN-Black] [name:Hiragino Kaku Gothic StdN W8] [features=japanese]
+\stoptypescript
+
+% Hoefler Text
+
+\starttypescript [serif] [hoefler]
+ \definefontsynonym [HoeflerText-Regular] [name:Hoefler Text] [features=default]
+ \definefontsynonym [HoeflerText-Italic] [name:Hoefler Text Italic] [features=default]
+ \definefontsynonym [HoeflerText-Black] [name:Hoefler Text Black] [features=default]
+ \definefontsynonym [HoeflerText-BlackItalic] [name:Hoefler Text Black Italic] [features=default]
+ \definefontsynonym [HoeflerText-Ornaments] [name:Hoefler Text Ornaments] [features=default]
+\stoptypescript
+
+% Impact
+
+\starttypescript [sans] [impact]
+ \definefontsynonym [Impact-Regular] [name:Impact] [features=default]
+\stoptypescript
+
+% Andale Mono / Monaco
+
+\starttypescript [mono] [andalemono,monaco]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+\stoptypescript
+
+% Optima
+
+\starttypescript [sans] [optima,optima-bold]
+ \definefontsynonym [Optima-Regular] [name:Optima Regular] [features=default]
+ \definefontsynonym [Optima-Italic] [name:Optima Italic] [features=default]
+ \definefontsynonym [Optima-Bold] [name:Optima Bold] [features=default]
+ \definefontsynonym [Optima-BoldItalic] [name:Optima Bold Italic] [features=default]
+ \definefontsynonym [Optima-Black] [name:Optima ExtraBlack] [features=default]
+\stoptypescript
+
+% Papyrus
+
+\starttypescript [sans] [papyrus]
+ \definefontsynonym [Papyrus-Regular] [name:Papyrus] [features=default]
+ \definefontsynonym [Papyrus-Condensed] [name:Papyrus Condensed] [features=default]
+\stoptypescript
+
+% STFangsong
+
+\starttypescript [serif] [stfangsong]
+ \definefontsynonym [STFangsong-Regular] [name:STFangsong] [features=chinese]
+\stoptypescript
+
+% STHeiti
+
+\starttypescript [sans] [stheiti]
+ \definefontsynonym [STXihei-Light] [name:STHeiti Light] [features=chinese]
+ \definefontsynonym [STHeiti-Regular] [name:STHeiti Regular] [features=chinese]
+\stoptypescript
+
+% STKaiti
+
+\starttypescript [serif] [stkaiti]
+ \definefontsynonym [STKaiti-Regular] [name:STKaiti] [features=chinese]
+\stoptypescript
+
+% STSong
+
+\starttypescript [serif] [stsong]
+ \definefontsynonym [STSong-Regular] [name:STSong] [features=chinese]
+\stoptypescript
+
+% Chalkboard / Comic Sans / Tahoma
+
+\starttypescript [sans] [chalkboard,comicsans,lucidagrande,tahoma]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [name:\typescriptprefix{f:\typescripttwo} Bold] [features=default]
+\stoptypescript
+
+% Cochin / Courier New / Georgia / Times New Roman / Trebuchet / Verdana
+
+\starttypescript [serif,sans,mono] [cochin,georgia,timesnewroman,trebuchet,verdana,couriernew]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [name:\typescriptprefix{f:\typescripttwo} Italic] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [name:\typescriptprefix{f:\typescripttwo} Bold] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [name:\typescriptprefix{f:\typescripttwo} Bold Italic] [features=default]
+\stoptypescript
+
+\endinput
diff --git a/tex/context/base/type-mac.mkiv b/tex/context/base/type-mac.mkiv
new file mode 100644
index 000000000..10a415883
--- /dev/null
+++ b/tex/context/base/type-mac.mkiv
@@ -0,0 +1,220 @@
+%D \module
+%D [ file=type-mac,
+%D version=2009.03.10,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Mac OS X Definitions,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright=Wolfgang Schuster]
+%C
+%C This module is part of the \CONTEXT\ macro||package. See
+%C mreadme.pdf for details.
+
+\definetypescriptprefix [f:andalemono] [andalemono]
+\definetypescriptprefix [f:chalkboard] [chalkboard]
+\definetypescriptprefix [f:cochin] [cochin]
+\definetypescriptprefix [f:comicsans] [comicsansms]
+\definetypescriptprefix [f:couriernew] [couriernew]
+\definetypescriptprefix [f:georgia] [georgia]
+\definetypescriptprefix [f:lucidagrande] [lucidagrande]
+\definetypescriptprefix [f:monaco] [monaco]
+\definetypescriptprefix [f:tahoma] [tahoma]
+\definetypescriptprefix [f:timesnewroman] [timesnewroman]
+\definetypescriptprefix [f:trebuchet] [trebuchetms]
+\definetypescriptprefix [f:verdana] [verdana]
+
+% American Typewriter
+
+\starttypescript [serif] [americantypewriter-light-condensed,americantypewriter-condensed,americantypewriter-light,americantypewriter]
+ \definefontsynonym [AmericanTypewriter-Light] [name:americantypewriterlight] [features=default]
+ \definefontsynonym [AmericanTypewriter-Regular] [name:americantypewriter] [features=default]
+ \definefontsynonym [AmericanTypewriter-Bold] [name:americantypewriterbold] [features=default]
+ \definefontsynonym [AmericanTypewriter-LightCond] [name:americantypewritercondensedlight] [features=default]
+ \definefontsynonym [AmericanTypewriter-Condensed] [name:americantypewritercondensed] [features=default]
+ \definefontsynonym [AmericanTypewriter-BoldCond] [name:americantypewritercondensedbold] [features=default]
+\stoptypescript
+
+% Arial / Arial Narrow / Arial Rounded / Arial Unicode
+
+\starttypescript [sans] [arial-narrow,arial-condensed,arial,arial-rounded,arial-unicode]
+ \definefontsynonym [Arial-Condensed] [name:arialnarrow] [features=default]
+ \definefontsynonym [Arial-ItalicCond] [name:arialnarrowitalic] [features=default]
+ \definefontsynonym [Arial-BoldCond] [name:arialnarrowbold] [features=default]
+ \definefontsynonym [Arial-BoldItalicCond] [name:arialnarrowbolditalic] [features=default]
+ \definefontsynonym [Arial-Regular] [name:arial] [features=default]
+ \definefontsynonym [Arial-Italic] [name:arialitalic] [features=default]
+ \definefontsynonym [Arial-Bold] [name:arialbold] [features=default]
+ \definefontsynonym [Arial-BoldItalic] [name:arialbolditalic] [features=default]
+ \definefontsynonym [Arial-Black] [name:arialblack] [features=default]
+ \definefontsynonym [Arial-Unicode] [name:arialunicodems] [features=default]
+ \definefontsynonym [Arial-Rounded] [name:arialroundedmtbold] [features=default]
+\stoptypescript
+
+% Baskerville
+
+\starttypescript [serif] [baskerville]
+ \definefontsynonym [Baskerville-Regular] [name:baskerville] [features=default]
+ \definefontsynonym [Baskerville-Italic] [name:baskervilleitalic] [features=default]
+ \definefontsynonym [Baskerville-Medium] [name:baskervillesemibold] [features=default]
+ \definefontsynonym [Baskerville-MediumItalic] [name:baskervillesemibolditalic] [features=default]
+ \definefontsynonym [Baskerville-Bold] [name:baskervillebold] [features=default]
+ \definefontsynonym [Baskerville-BoldItalic] [name:baskervillebolditalic] [features=default]
+\stoptypescript
+
+% Big Caslon
+
+\starttypescript [serif] [caslon,bigcaslon]
+ \definefontsynonym [BigCaslon-Medium] [name:bigcaslonmedium] [features=default]
+\stoptypescript
+
+% Copperplate
+
+\starttypescript [sans] [copperplate-light,copperplate]
+ \definefontsynonym [Copperplate-Light] [name:copperplatelight] [features=default]
+ \definefontsynonym [Copperplate-Regular] [name:copperplate] [features=default]
+ \definefontsynonym [Copperplate-Bold] [name:copperplatebold] [features=default]
+\stoptypescript
+
+% Futura
+
+\starttypescript [sans] [futura-condensed,futura]
+ \definefontsynonym [Futura-MediumCond] [name:futuracondensedmedium] [features=default]
+ \definefontsynonym [Futura-Medium] [name:futuramedium] [features=default]
+ \definefontsynonym [Futura-MediumItalic] [name:futuramediumitalic] [features=default]
+ \definefontsynonym [Futura-BoldCond] [name:futuracondensedextrabold] [features=default]
+\stoptypescript
+
+% Gill Sans
+
+\starttypescript [sans] [gillsans-light,gillsans]
+ \definefontsynonym [GillSans-Light] [name:gillsanslight] [features=default]
+ \definefontsynonym [GillSans-LightItalic] [name:gillsanslightitalic] [features=default]
+ \definefontsynonym [GillSans-Regular] [name:gillsans] [features=default]
+ \definefontsynonym [GillSans-Italic] [name:gillsansitalic] [features=default]
+ \definefontsynonym [GillSans-Bold] [name:gillsansbold] [features=default]
+ \definefontsynonym [GillSans-BoldItalic] [name:gillsansbolditalic] [features=default]
+\stoptypescript
+
+% Helvetica Neuse
+
+\starttypescript [sans] [helvetica-neue-ultralight,helvetica-neue-light,helvetica-neue,helvetica-neue-boldcondensed]
+ \definefontsynonym [HelveticaNeue-UltraLight] [name:helveticaneueultralight] [features=default]
+ \definefontsynonym [HelveticaNeue-UltraLightItalic] [name:helveticaneueultralightitalic] [features=default]
+ \definefontsynonym [HelveticaNeue-Light] [name:helveticaneuelight] [features=default]
+ \definefontsynonym [HelveticaNeue-LightItalic] [name:helveticaneuelightitalic] [features=default]
+ \definefontsynonym [HelveticaNeue-Regular] [name:helveticaneue] [features=default]
+ \definefontsynonym [HelveticaNeue-Italic] [name:helveticaneueitalic] [features=default]
+ \definefontsynonym [HelveticaNeue-Bold] [name:helveticaneuebold] [features=default]
+ \definefontsynonym [HelveticaNeue-BoldItalic] [name:helveticaneuebolditalic] [features=default]
+ \definefontsynonym [HelveticaNeue-BoldCond] [name:helveticaneuecondensedbold] [features=default]
+ \definefontsynonym [HelveticaNeue-BlackCond] [name:helveticaneuecondensedblack] [features=default]
+\stoptypescript
+
+% Hiragino Mincho
+
+\starttypescript [serif] [hiragino-mincho]
+ \definefontsynonym [HiraginoMinchoPro-Regular] [name:hiraminprow3] [features=japanese]
+ \definefontsynonym [HiraginoMinchoPro-Bold] [name:hiraminprow6] [features=japanese]
+ \definefontsynonym [HiraginoMinchoProN-Regular] [name:hiraminpronw3] [features=japanese]
+ \definefontsynonym [HiraginoMinchoProN-Bold] [name:hiraminpronw6] [features=japanese]
+\stoptypescript
+
+% Hiragino Maru
+
+\starttypescript [sans] [hiragino-maru]
+ \definefontsynonym [HiraginoMaruGothicPro-Regular] [name:hiramaruprow4] [features=japanese]
+ \definefontsynonym [HiraginoMaruGothicProN-Regular] [name:hiramarupronw4] [features=japanese]
+\stoptypescript
+
+% Hiragino Kaku
+
+\starttypescript [sans] [hiragino-kaku]
+ \definefontsynonym [HiraginoKakuGothicPro-Regular] [name:hirakakuprow3] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicPro-Bold] [name:hirakakuprow6] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicStd-Black] [name:hirakakustdw8] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicProN-Regular] [name:hirakakupronw3] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicProN-Bold] [name:hirakakupronw6] [features=japanese]
+ \definefontsynonym [HiraginoKakuGothicStdN-Black] [name:hirakakustdnw8] [features=japanese]
+\stoptypescript
+
+% Hoefler Text
+
+\starttypescript [serif] [hoefler]
+ \definefontsynonym [HoeflerText-Regular] [name:hoeflertext] [features=default]
+ \definefontsynonym [HoeflerText-Italic] [name:hoeflertextitalic] [features=default]
+ \definefontsynonym [HoeflerText-Black] [name:hoeflertextblack] [features=default]
+ \definefontsynonym [HoeflerText-BlackItalic] [name:hoeflertextblackitalic] [features=default]
+ \definefontsynonym [HoeflerText-Ornaments] [name:hoeflertextornaments] [features=default]
+\stoptypescript
+
+% Impact
+
+\starttypescript [sans] [impact]
+ \definefontsynonym [Impact-Regular] [name:impact] [features=default]
+\stoptypescript
+
+% Andale Mono / Monaco
+
+\starttypescript [mono] [andalemono,monaco]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+\stoptypescript
+
+% Optima
+
+\starttypescript [sans] [optima,optima-bold]
+ \definefontsynonym [Optima-Regular] [name:optimaregular] [features=default]
+ \definefontsynonym [Optima-Italic] [name:optimaitalic] [features=default]
+ \definefontsynonym [Optima-Bold] [name:optimabold] [features=default]
+ \definefontsynonym [Optima-BoldItalic] [name:optimabolditalic] [features=default]
+ \definefontsynonym [Optima-Black] [name:optimaextrablack] [features=default]
+\stoptypescript
+
+% Papyrus
+
+\starttypescript [sans] [papyrus]
+ \definefontsynonym [Papyrus-Regular] [name:papyrus] [features=default]
+ \definefontsynonym [Papyrus-Condensed] [name:papyruscondensed] [features=default]
+\stoptypescript
+
+% STFangsong
+
+\starttypescript [serif] [stfangsong]
+ \definefontsynonym [STFangsong-Regular] [name:stfangsong] [features=chinese]
+\stoptypescript
+
+% STHeiti
+
+\starttypescript [sans] [stheiti]
+ \definefontsynonym [STXihei-Light] [name:stxihei] [features=chinese]
+ \definefontsynonym [STHeiti-Regular] [name:stheiti] [features=chinese]
+\stoptypescript
+
+% STKaiti
+
+\starttypescript [serif] [stkaiti]
+ \definefontsynonym [STKaiti-Regular] [name:stkaiti] [features=chinese]
+\stoptypescript
+
+% STSong
+
+\starttypescript [serif] [stsong]
+ \definefontsynonym [STSong-Regular] [name:stsong] [features=chinese]
+\stoptypescript
+
+% Chalkboard / Comic Sans / Tahoma
+
+\starttypescript [sans] [chalkboard,comicsans,tahoma]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [name:\typescriptprefix{f:\typescripttwo}bold] [features=default]
+\stoptypescript
+
+% Cochin / Courier New / Georgia / Times New Roman / Trebuchet / Verdana
+
+\starttypescript [serif,sans,mono] [cochin,georgia,timesnewroman,trebuchet,verdana,couriernew]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [name:\typescriptprefix{f:\typescripttwo}italic] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [name:\typescriptprefix{f:\typescripttwo}bold] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [name:\typescriptprefix{f:\typescripttwo}bolditalic] [features=default]
+\stoptypescript
+
+\endinput
diff --git a/tex/context/base/type-mac.tex b/tex/context/base/type-mac.tex
new file mode 100644
index 000000000..04ac6139b
--- /dev/null
+++ b/tex/context/base/type-mac.tex
@@ -0,0 +1,434 @@
+%D \module
+%D [ file=type-mac,
+%D version=2009.03.10,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Mac OS X Definitions,
+%D author=Wolfgang Schuster,
+%D date=\currentdate,
+%D copyright=Wolfgang Schuster]
+%C
+%C This module is part of the \CONTEXT\ macro||package. See
+%C mreadme.pdf for details.
+
+\starttypescriptcollection [macosx]
+
+\definetypescriptprefix [n:andalemono] [AndaleMono]
+\definetypescriptprefix [n:chalkboard] [Chalkboard]
+\definetypescriptprefix [n:cochin] [Cochin]
+\definetypescriptprefix [n:comicsans] [ComicSans]
+\definetypescriptprefix [n:couriernew] [CourierNew]
+\definetypescriptprefix [n:georgia] [Georgia]
+\definetypescriptprefix [n:lucidagrande] [LucidaGrande]
+\definetypescriptprefix [n:monaco] [Monaco]
+\definetypescriptprefix [n:tahoma] [Tahoma]
+\definetypescriptprefix [n:timesnewroman] [TimesNewRoman]
+\definetypescriptprefix [n:trebuchet] [Trebuchet]
+\definetypescriptprefix [n:verdana] [Verdana]
+
+% American Typewriter
+
+\starttypescript [serif] [americantypewriter-light-condensed]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [AmericanTypewriter-LightCond] [features=default]
+ \definefontsynonym [SerifBold] [AmericanTypewriter-Condensed] [features=default]
+\stoptypescript
+
+\starttypescript [serif] [americantypewriter-condensed]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [AmericanTypewriter-Condensed] [features=default]
+ \definefontsynonym [SerifBold] [AmericanTypewriter-BoldCond] [features=default]
+\stoptypescript
+
+\starttypescript [serif] [americantypewriter-light]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [AmericanTypewriter-Light] [features=default]
+ \definefontsynonym [SerifBold] [AmericanTypewriter-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [serif] [americantypewriter]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [AmericanTypewriter-Regular] [features=default]
+ \definefontsynonym [SerifBold] [AmericanTypewriter-Bold] [features=default]
+\stoptypescript
+
+\starttypescript [americantypewriter-light-condensed,americantypewriter-condensed,americantypewriter-light,americantypewriter]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Arial / Arial Narrow / Arial Rounded / Arial Unicode
+
+\starttypescript [sans] [arial-narrow,arial-condensed]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Arial-Condensed] [features=default]
+ \definefontsynonym [SansItalic] [Arial-ItalicCond] [features=default]
+ \definefontsynonym [SansBold] [Arial-BoldCond] [features=default]
+ \definefontsynonym [SansBoldItalic] [Arial-BoldItalicCond] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [arial]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Arial-Regular] [features=default]
+ \definefontsynonym [SansItalic] [Arial-Italic] [features=default]
+ \definefontsynonym [SansBold] [Arial-Bold] [features=default]
+ \definefontsynonym [SansBoldItalic] [Arial-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [arial-rounded]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Arial-Rounded] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [arial-unicode]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Arial-Unicode] [features=default]
+\stoptypescript
+
+\starttypescript [arial-narrow,arial-condensed,arial,arial-rounded,arial-unicode]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Baskerville
+
+\starttypescript [serif] [baskerville]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [Baskerville-Regular] [features=default]
+ \definefontsynonym [SerifItalic] [Baskerville-Italic] [features=default]
+ \definefontsynonym [SerifBold] [Baskerville-Medium] [features=default]
+ \definefontsynonym [SerifBoldItalic] [Baskerville-MediumItalic] [features=default]
+\stoptypescript
+
+\starttypescript [baskerville]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Big Caslon
+
+\starttypescript [serif] [caslon,bigcaslon]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [BigCaslon-Medium] [features=default]
+\stoptypescript
+
+\starttypescript [caslon,bigcaslon]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Copperplate
+
+\starttypescript [sans] [copperplate-light]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Copperplate-Light] [features=default]
+ \definefontsynonym [SansBold] [Copperplate-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [copperplate]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Copperplate-Regular] [features=default]
+ \definefontsynonym [SansBold] [Copperplate-Bold] [features=default]
+\stoptypescript
+
+\starttypescript [copperplate-light,copperplate]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Courier New
+
+\starttypescript [mono] [couriernew]
+ \setups[font:fallback:mono]
+ \definefontsynonym [Mono] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
+ \definefontsynonym [MonoItalic] [\typescriptprefix{n:\typescripttwo}-Italic] [features=default]
+ \definefontsynonym [MonoBold] [\typescriptprefix{n:\typescripttwo}-Bold] [features=default]
+ \definefontsynonym [MonoBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [couriernew]
+ \definetypeface [\typescriptone] [tt] [mono] [\typescriptone] [default]
+\stoptypescript
+
+% Futura
+
+\starttypescript [sans] [futura-condensed]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Futura-MediumCond] [features=default]
+ \definefontsynonym [SansBold] [Futura-BoldCond] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [futura]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Futura-Medium] [features=default]
+ \definefontsynonym [SansItalic] [Futura-MediumItalic] [features=default]
+\stoptypescript
+
+\starttypescript [futura-condensed,futura]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Gill Sans
+
+\starttypescript [sans] [gillsans-light]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [GillSans-Light] [features=default]
+ \definefontsynonym [SansItalic] [GillSans-LightItalic] [features=default]
+ \definefontsynonym [SansBold] [GillSans-Regular] [features=default]
+ \definefontsynonym [SansBoldItalic] [GillSans-Italic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [gillsans]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [GillSans-Regular] [features=default]
+ \definefontsynonym [SansItalic] [GillSans-Italic] [features=default]
+ \definefontsynonym [SansBold] [GillSans-Bold] [features=default]
+ \definefontsynonym [SansBoldItalic] [GillSans-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [gillsans-light,gillsans]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Helvetica Neuse
+
+\starttypescript [sans] [helvetica-neue-ultralight]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [HelveticaNeue-UltraLight] [features=default]
+ \definefontsynonym [SansItalic] [HelveticaNeue-UltraLightItalic] [features=default]
+ \definefontsynonym [SansBold] [HelveticaNeue-Light] [features=default]
+ \definefontsynonym [SansBoldItalic] [HelveticaNeue-LightItalic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [helvetica-neue-light]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [HelveticaNeue-Light] [features=default]
+ \definefontsynonym [SansItalic] [HelveticaNeue-LightItalic] [features=default]
+ \definefontsynonym [SansBold] [HelveticaNeue-Regular] [features=default]
+ \definefontsynonym [SansBoldItalic] [HelveticaNeue-Italic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [helvetica-neue]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [HelveticaNeue-Regular] [features=default]
+ \definefontsynonym [SansItalic] [HelveticaNeue-Italic] [features=default]
+ \definefontsynonym [SansBold] [HelveticaNeue-Bold] [features=default]
+ \definefontsynonym [SansBoldItalic] [HelveticaNeue-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [helvetica-neue-boldcondensed]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [HelveticaNeue-BoldCond] [features=default]
+ \definefontsynonym [SansBold] [HelveticaNeue-BlackCond] [features=default]
+\stoptypescript
+
+\starttypescript [helvetica-neue-ultralight,helvetica-neue-light,helvetica-neue,helvetica-neue-boldcondensed]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Hiragino Mincho
+
+\starttypescript [serif] [hiragino-mincho]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [HiraginoMinchoPro-Regular] [features=japanese]
+ \definefontsynonym [SerifBold] [HiraginoMinchoPro-Bold] [features=japanese]
+\stoptypescript
+
+% \starttypescript [serif] [hiragino-mincho]
+% \setups[font:fallback:serif]
+% \definefontsynonym [Serif] [HiraginoMinchoProN-Regular] [features=japanese]
+% \definefontsynonym [SerifBold] [HiraginoMinchoProN-Bold] [features=japanese]
+% \stoptypescript
+
+\starttypescript [hiragino-mincho]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Hiragino Maru
+
+\starttypescript [sans] [hiragino-maru]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [HiraginoMaruGothicPro-Regular] [features=japanese]
+\stoptypescript
+
+% \starttypescript [sans] [hiragino-maru]
+% \setups[font:fallback:sans]
+% \definefontsynonym [Sans] [HiraginoMaruGothicProN-Regular] [features=japanese]
+% \stoptypescript
+
+\starttypescript [hiragino-maru]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Hiragino Kaku
+
+\starttypescript [sans] [hiragino-kaku]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [HiraginoKakuGothicPro-Regular] [features=japanese]
+ \definefontsynonym [SansBold] [HiraginoKakuGothicPro-Bold] [features=japanese]
+\stoptypescript
+
+% \starttypescript [sans] [hiragino-kaku]
+% \setups[font:fallback:sans]
+% \definefontsynonym [Sans] [HiraginoKakuGothicProN-Regular] [features=japanese]
+% \definefontsynonym [SansBold] [HiraginoKakuGothicProN-Bold] [features=japanese]
+% \stoptypescript
+
+\starttypescript [hiragino-kaku]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Hoefler Text
+
+\starttypescript [serif] [hoefler]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [HoeflerText-Regular] [features=default]
+ \definefontsynonym [SerifItalic] [HoeflerText-Italic] [features=default]
+ \definefontsynonym [SerifBold] [HoeflerText-Black] [features=default]
+ \definefontsynonym [SerifBoldItalic] [HoeflerText-BlackItalic] [features=default]
+\stoptypescript
+
+\starttypescript [hoefler]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Impact
+
+\starttypescript [sans] [impact]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Impact-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [impact]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Andale Mono / Monaco
+
+\starttypescript [mono] [andalemono,monaco]
+ \setups[font:fallback:mono]
+ \definefontsynonym [Mono] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [andalemono,monaco]
+ \definetypeface [\typescriptone] [tt] [mono] [\typescriptone] [default]
+\stoptypescript
+
+% Optima
+
+\starttypescript [sans] [optima]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Optima-Regular] [features=default]
+ \definefontsynonym [SansItalic] [Optima-Italic] [features=default]
+ \definefontsynonym [SansBold] [Optima-Bold] [features=default]
+ \definefontsynonym [SansBoldItalic] [Optima-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [optima-bold]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Optima-Bold] [features=default]
+ \definefontsynonym [SansItalic] [Optima-BoldItalic] [features=default]
+ \definefontsynonym [SansBold] [Optima-Black] [features=default]
+\stoptypescript
+
+\starttypescript [optima,optima-bold]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Papyrus
+
+\starttypescript [sans] [papyrus]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [Papyrus-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [papyrus]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% STFangsong
+
+\starttypescript [serif] [stfangsong]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Serif] [STFangsong-Regular] [features=chinese]
+\stoptypescript
+
+\starttypescript [stfangsong]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% STHeiti
+
+\starttypescript [sans] [stheiti]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [STXihei-Light] [features=chinese]
+ \definefontsynonym [SansBold] [STKaiti-Regular] [features=chinese]
+\stoptypescript
+
+\starttypescript [stheiti]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% STKaiti
+
+\starttypescript [serif] [stkaiti]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Serif] [STKaiti-Regular] [features=chinese]
+\stoptypescript
+
+\starttypescript [stkaiti]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% STSong
+
+\starttypescript [serif] [stsong]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Serif] [STSong-Regular] [features=chinese]
+\stoptypescript
+
+\starttypescript [stsong]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Chalkboard / Comic Sans / Tahoma
+
+\starttypescript [sans] [chalkboard,comicsans,lucidagrande,tahoma]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
+ \definefontsynonym [SansBold] [\typescriptprefix{n:\typescripttwo}-Bold] [features=default]
+\stoptypescript
+
+\starttypescript [chalkboard,comicsans,tahoma]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+% Cochin / Georgia / Times New Roman
+
+\starttypescript [serif] [cochin,georgia,timesnewroman]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
+ \definefontsynonym [SerifItalic] [\typescriptprefix{n:\typescripttwo}-Italic] [features=default]
+ \definefontsynonym [SerifBold] [\typescriptprefix{n:\typescripttwo}-Bold] [features=default]
+ \definefontsynonym [SerifBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [cochin,georgia,timesnewroman]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+% Trebuchet / Verdana
+
+\starttypescript [sans] [trebuchet,verdana]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
+ \definefontsynonym [SansItalic] [\typescriptprefix{n:\typescripttwo}-Italic] [features=default]
+ \definefontsynonym [SansBold] [\typescriptprefix{n:\typescripttwo}-Bold] [features=default]
+ \definefontsynonym [SansBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [trebuchet,verdana]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+\stoptypescriptcollection
+
+% XeTeX / LuaTeX font names
+
+\loadmarkfile{type-mac}
+
+\endinput
diff --git a/tex/context/base/type-map.tex b/tex/context/base/type-map.tex
index 37eef0ed5..5a581a78b 100644
--- a/tex/context/base/type-map.tex
+++ b/tex/context/base/type-map.tex
@@ -28,7 +28,7 @@
\loadmapfile[original-ams-base.map]
%loadmapfile[original-ams-cmr.map]
\loadmapfile[original-ams-euler.map]
- \loadmapfile[original-public-lm.map]
+ %loadmapfile[original-public-lm.map]
\stoptypescript
% This is the base map file, load it to be sure.
@@ -47,7 +47,7 @@
% cmr and related
\starttypescript [map] [cmr,lm,lmr]
- \loadmapfile[original-public-lm.map]
+ %loadmapfile[original-public-lm.map]
\loadmapfile[original-ams-base.map]
\loadmapfile[original-ams-euler.map]
\stoptypescript
@@ -145,34 +145,34 @@
\loadmapfile[kurier-ex.map]
\stoptypescript
-\starttypescript [map] [bookman] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-bookman.map]
-\stoptypescript
+% \starttypescript [map] [bookman] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-bookman.map]
+% \stoptypescript
-\starttypescript [map] [courier] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-courier.map]
-\stoptypescript
+% \starttypescript [map] [courier] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-courier.map]
+% \stoptypescript
-\starttypescript [map] [helvetica] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-helvetica.map]
-\stoptypescript
+% \starttypescript [map] [helvetica] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-helvetica.map]
+% \stoptypescript
-\starttypescript [map] [palatino] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-palatino.map]
- %loadmapfile[\typescriptthree-public-pfl.map]
-\stoptypescript
+% \starttypescript [map] [palatino] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-palatino.map]
+% %loadmapfile[\typescriptthree-public-pfl.map]
+% \stoptypescript
-\starttypescript [map] [times] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-times.map]
-\stoptypescript
+% \starttypescript [map] [times] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-times.map]
+% \stoptypescript
-\starttypescript [map] [chancery] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-zapfchan.map]
-\stoptypescript
+% \starttypescript [map] [chancery] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-zapfchan.map]
+% \stoptypescript
-\starttypescript [map] [schoolbook] [ec,texnansi,t5,8r]
- \loadmapfile[\typescriptthree-urw-ncntrsbk.map]
-\stoptypescript
+% \starttypescript [map] [schoolbook] [ec,texnansi,t5,8r]
+% \loadmapfile[\typescriptthree-urw-ncntrsbk.map]
+% \stoptypescript
% once i can be sure that the map files are in the tree, i will
% use those instead of original (too many variants anyway)
diff --git a/tex/context/base/type-one.tex b/tex/context/base/type-one.tex
index 5ca09b30a..b456d7e64 100644
--- a/tex/context/base/type-one.tex
+++ b/tex/context/base/type-one.tex
@@ -58,30 +58,27 @@
\quittypescriptscanning
\stoptypescript
-\starttypescript [postscript] [texnansi,ec,qx,t5,uc,8r]
+\starttypescript [postscript] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
\definetypeface [postscript] [rm] [serif] [times] [default] [encoding=\typescripttwo]
- \definetypeface [postscript] [ss] [sans] [helvetica] [default] [rscale=.9,encoding=\typescripttwo]
- \definetypeface [postscript] [tt] [mono] [courier] [default] [rscale=1.1,encoding=\typescripttwo]
- \definetypeface [postscript] [mm] [math] [times] [default]
- \usemathcollection[default]
+ \definetypeface [postscript] [ss] [sans] [helvetica] [default] [encoding=\typescripttwo,rscale=0.9]
+ \definetypeface [postscript] [tt] [mono] [courier] [default] [encoding=\typescripttwo,rscale=1.1]
+ \definetypeface [postscript] [mm] [math] [times] [default] [encoding=\typescripttwo]
\quittypescriptscanning
\stoptypescript
-\starttypescript [times] [texnansi,ec,qx,8r,t5,uc]
- \definetypeface [times] [rm] [serif] [times] [default] [encoding=\typescripttwo]
- \definetypeface [times] [ss] [sans] [helvetica] [default] [encoding=\typescripttwo,rscale=0.9]
- \definetypeface [times] [tt] [mono] [modern] [default] [encoding=\typescripttwo,rscale=1.05]
- \definetypeface [times] [mm] [math] [times] [default] [encoding=\typescripttwo]
- \usemathcollection[default]
+\starttypescript [times,termes] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [ss] [sans] [helvetica] [default] [encoding=\typescripttwo,rscale=0.9]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo,rscale=1.05]
+ \definetypeface [\typescriptone] [mm] [math] [times] [default] [encoding=\typescripttwo]
\quittypescriptscanning
\stoptypescript
-\starttypescript [palatino] [texnansi,ec,qx,8r,t5,uc]
- \definetypeface [palatino] [rm] [serif] [palatino] [default] [encoding=\typescripttwo]
- \definetypeface [palatino] [ss] [sans] [modern] [default] [encoding=\typescripttwo,rscale=1.075]
- \definetypeface [palatino] [tt] [mono] [modern] [default] [encoding=\typescripttwo,rscale=1.075]
- \definetypeface [palatino] [mm] [math] [palatino] [default] [encoding=default]
- \usemathcollection[default]
+\starttypescript [palatino,pagella] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [encoding=\typescripttwo,rscale=1.075]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo,rscale=1.075]
+ \definetypeface [\typescriptone] [mm] [math] [palatino] [default] [encoding=default]
\quittypescriptscanning
\stoptypescript
@@ -90,7 +87,6 @@
\definetypeface [fourier] [ss] [sans] [modern] [default] [encoding=ec,rscale=1.07]
\definetypeface [fourier] [tt] [mono] [modern] [default] [encoding=ec,rscale=1.07]
\definetypeface [fourier] [mm] [math] [fourier] [default] [encoding=default]
- \usemathcollection[fou]
\quittypescriptscanning
\stoptypescript
@@ -117,7 +113,7 @@
\quittypescriptscanning
\stoptypescript
-\starttypescript [antykwa-torunska] [texnansi,ec,8r,uc,t2a]
+\starttypescript [antykwa-torunska] [texnansi,ec,8r,uc,t5,t2a]
\definetypeface[antykwa][rm][serif][antykwa-torunska] [default][encoding=\typescripttwo]
\definetypeface[antykwa][ss][sans] [modern] [default][encoding=\typescripttwo,rscale=1.05]
\definetypeface[antykwa][tt][mono] [modern] [default][encoding=\typescripttwo,rscale=1.1]
@@ -125,6 +121,30 @@
\quittypescriptscanning
\stoptypescript
+\starttypescript [schoolbook,schola] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [encoding=default]
+ \quittypescriptscanning
+\stoptypescript
+
+\starttypescript [bookman,bonum] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [encoding=default]
+ \quittypescriptscanning
+\stoptypescript
+
+\starttypescript [chancery,chorus] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [encoding=default]
+ \quittypescriptscanning
+\stoptypescript
+
\starttypescript [iwona,iwona-light,iwona-heavy,iwona-medium] [texnansi,ec,8r,uc,t2a]
\definetypeface[\typescriptone][ss][sans] [\typescriptone] [default][encoding=\typescripttwo]
\definetypeface[\typescriptone][rm][serif][modern] [default][encoding=\typescripttwo]
@@ -133,6 +153,30 @@
\quittypescriptscanning
\stoptypescript
+\starttypescript [helvetica,heros] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [rm] [serif] [modern] [default] [encoding=\typescripttwo,rscale=1.15]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo,rscale=1.15]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [encoding=default,rscale=1.15]
+ \quittypescriptscanning
+\stoptypescript
+
+\starttypescript [avantgarde,adventor] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [ss] [sans] [adventor] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [rm] [serif] [modern] [default] [encoding=\typescripttwo,rscale=1.15]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [encoding=\typescripttwo,rscale=1.15]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [encoding=default]
+ \quittypescriptscanning
+\stoptypescript
+
+\starttypescript [courier,cursor] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definetypeface [\typescriptone] [tt] [mono] [\typescriptone] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [rm] [serif] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [encoding=\typescripttwo]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [encoding=default]
+ \quittypescriptscanning
+\stoptypescript
+
\stoptypescriptcollection
\starttypescriptcollection[typeone]
@@ -143,9 +187,7 @@
\stoptypescript
\starttypescript[all][modern,latin-modern][all]
-
% fallbacks, no math in latin modern
-
\definefontsynonym[lmdunh10][cmdunh10]
\definefontsynonym[lmff10] [cmff10]
\definefontsynonym[lmfi10] [cmfi10]
@@ -153,7 +195,6 @@
\definefontsynonym[lmtex10] [cmtex10]
\definefontsynonym[lmtex8] [cmtex8]
\definefontsynonym[lmtex9] [cmtex9]
-
\loadmapfile[original-public-lm.map]
\stoptypescript
@@ -192,7 +233,6 @@
\definefontsynonym [LMRoman10-Dunhill] [\typescriptthree-lmdunh10] [encoding=\typescriptthree]
\definefontsynonym [LMRoman10-DunhillOblique] [\typescriptthree-lmduno10] [encoding=\typescriptthree]
-
\loadmapfile[lm-\typescriptthree.map]
\stoptypescript
@@ -215,7 +255,6 @@
\definefontsynonym [LMSansQuotation8-Bold] [\typescriptthree-lmssqbx8] [encoding=\typescriptthree]
\definefontsynonym [LMSansQuotation8-Oblique] [\typescriptthree-lmssqo8] [encoding=\typescriptthree]
\definefontsynonym [LMSansQuotation8-BoldOblique] [\typescriptthree-lmssqbo8] [encoding=\typescriptthree]
-
\loadmapfile[lm-\typescriptthree.map]
\stoptypescript
@@ -234,16 +273,13 @@
\definefontsynonym [LMTypewriter10-LightCondensedOblique] [\typescriptthree-lmtlco10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriter10-Dark] [\typescriptthree-lmtk10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriter10-DarkOblique] [\typescriptthree-lmtko10] [encoding=\typescriptthree]
-
\definefontsynonym [LMTypewriter10-Unslanted] [\typescriptthree-lmu10] [encoding=\typescriptthree]
-
\definefontsynonym [LMTypewriterVarWd10-Regular] [\typescriptthree-lmvtt10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriterVarWd10-Oblique] [\typescriptthree-lmvtto10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriterVarWd10-Light] [\typescriptthree-lmvtl10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriterVarWd10-LightOblique] [\typescriptthree-lmvtlo10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriterVarWd10-Dark] [\typescriptthree-lmvtk10] [encoding=\typescriptthree]
\definefontsynonym [LMTypewriterVarWd10-DarkOblique] [\typescriptthree-lmvtko10] [encoding=\typescriptthree]
-
\loadmapfile[lm-\typescriptthree.map]
\stoptypescript
@@ -283,7 +319,7 @@
\definefontsynonym [LMMathItalic5-BoldItalic] [lmmib5]
\definefontsynonym [LMMathItalic7-BoldItalic] [lmmib7]
\definefontsynonym [LMMathItalic10-BoldItalic] [lmmib10]
-
+ \usemathcollection[default]
\loadmapfile[lm-math.map]
\loadmapfile[lm-rm.map]
\stoptypescript
@@ -589,7 +625,7 @@
\definefontsynonym [Euler-Extension] [zeuex10]
\definefontsynonym [Euler-Symbol] [zeusm10]
\definefontsynonym [Euler-Fraktur] [eufm10]
-
+ \usemathcollection[eul]
\loadmapfile[original-ams-euler.map]
\stoptypescript
@@ -598,15 +634,16 @@
\definefontsynonym [Euler-Extension] [zeuex10]
\definefontsynonym [Euler-Symbol-Bold] [zeusb10]
\definefontsynonym [Euler-Fraktur-Bold] [eufb10]
-
+ \usemathcollection[eul]
\loadmapfile[original-ams-euler.map]
\stoptypescript
% AMS (AMS)
\starttypescript [math] [modern,computer-modern,latin-modern,ams] [default]
- \definefontsynonym [AMS-SymbolA] [msam10]
- \definefontsynonym [AMS-SymbolB] [msbm10]
+ \definefontsynonym [AMS-SymbolA] [msam10]
+ \definefontsynonym [AMS-SymbolB] [msbm10]
+ \usemathcollection[default]
\stoptypescript
% Fourier (Utopia)
@@ -617,7 +654,7 @@
\definefontsynonym [Fourier-Math-Letters-Italic] [futmii]
\definefontsynonym [Fourier-Math-Symbols] [futsy]
\definefontsynonym [Fourier-Math-Extension] [fourier-mex]
-
+ \usemathcollection[fou]
\loadmapfile[fourier.map]
\stoptypescript
@@ -630,7 +667,6 @@
\definefontsynonym [Fourier-BoldSlanted] [futbo8t] [encoding=ec]
\definefontsynonym [Fourier-BoldItalic] [futbi8t] [encoding=ec]
\definefontsynonym [Fourier-BoldCaps] [futbc8t] [encoding=ec]
-
\definefontsynonym [Fourier-Regular-Expert] [futr9e] [encoding=ec]
\definefontsynonym [Fourier-Slanted-Expert] [futro9e] [encoding=ec]
\definefontsynonym [Fourier-Italic-Expert] [futri9e] [encoding=ec]
@@ -643,7 +679,6 @@
\definefontsynonym [Fourier-BoldSlanted-Expert] [futbo9e] [encoding=ec]
\definefontsynonym [Fourier-BoldItalic-Expert] [futbi9e] [encoding=ec]
\definefontsynonym [Fourier-Black-Expert] [futc9e] [encoding=ec]
-
\definefontsynonym [Fourier-Regular-OldStyle] [futr9d] [encoding=ec]
\definefontsynonym [Fourier-Slanted-OldStyle] [futro9d] [encoding=ec]
\definefontsynonym [Fourier-Italic-OldStyle] [futri9d] [encoding=ec]
@@ -656,97 +691,10 @@
\definefontsynonym [Fourier-BoldSlanted-OldStyle] [futbo9d] [encoding=ec]
\definefontsynonym [Fourier-BoldItalic-OldStyle] [futbi9d] [encoding=ec]
\definefontsynonym [Fourier-Black-OldStyle] [futc9d] [encoding=ec]
-
\loadmapfile[fourier.map]
\loadmapfile[fourier-utopia-expert.map]
\stoptypescript
-% Courier (URW)
-
-\starttypescript [mono] [courier] [qx]
- \definefontsynonym [qx-ucrr8a] [qcrr] [encoding=qx]
- \definefontsynonym [qx-ucrb8a] [qcrb] [encoding=qx]
- \definefontsynonym [qx-ucrro8a] [qcrri] [encoding=qx]
- \definefontsynonym [qx-ucrbo8a] [qcrbi] [encoding=qx]
-\stoptypescript
-
-\starttypescript [mono] [courier] [texnansi,ec,8r,t5]
- \definefontsynonym [Courier] [\typescriptthree-ucrr8a] [encoding=\typescriptthree]
- \definefontsynonym [Courier-Bold] [\typescriptthree-ucrb8a] [encoding=\typescriptthree]
- \definefontsynonym [Courier-Oblique] [\typescriptthree-ucrro8a] [encoding=\typescriptthree]
- \definefontsynonym [Courier-BoldOblique] [\typescriptthree-ucrbo8a] [encoding=\typescriptthree]
-
- \loadmapfile[\typescriptthree-urw-courier.map]
-\stoptypescript
-
-% Helvetica (URW)
-
-\starttypescript [sans] [helvetica] [qx]
- \definefontsynonym [qx-uhvr8a] [qhvr] [encoding=qx]
- \definefontsynonym [qx-uhvri8a] [qhvri] [encoding=qx]
- \definefontsynonym [qx-uhvro8a] [qhvri] [encoding=qx]
- \definefontsynonym [qx-uhvb8a] [qhvb] [encoding=qx]
- \definefontsynonym [qx-uhvbi8a] [qhvbi] [encoding=qx]
- \definefontsynonym [qx-uhvbo8a] [qhvbi] [encoding=qx]
-\stoptypescript
-
-\starttypescript [sans] [helvetica] [texnansi,ec,8r,t5]
- \definefontsynonym [Helvetica] [\typescriptthree-uhvr8a] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-Italic] [\typescriptthree-uhvri8a] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-Oblique] [\typescriptthree-uhvro8a] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-Bold] [\typescriptthree-uhvb8a] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-BoldItalic] [\typescriptthree-uhvbi8a] [encoding=\typescriptthree]
- \definefontsynonym [Helvetica-BoldOblique] [\typescriptthree-uhvbo8a] [encoding=\typescriptthree]
-
- \loadmapfile[\typescriptthree-urw-helvetica.map]
-\stoptypescript
-
-% Times Roman (URW)
-
-\starttypescript [serif] [times] [qx]
- \definefontsynonym [qx-utmr8a] [qtmr] [encoding=qx]
- \definefontsynonym [qx-utmri8a] [qtmri] [encoding=qx]
- \definefontsynonym [qx-utmb8a] [qtmb] [encoding=qx]
- \definefontsynonym [qx-utmbi8a] [qtmbi] [encoding=qx]
- \definefontsynonym [qx-utmr8a-slanted-167] [qtmri] [encoding=qx]
- \definefontsynonym [qx-utmb8a-slanted-167] [qtmbi] [encoding=qx]
-\stoptypescript
-
-\starttypescript [serif] [times] [texnansi,ec,8r,t5]
- \definefontsynonym [Times-Roman] [\typescriptthree-utmr8a] [encoding=\typescriptthree]
- \definefontsynonym [Times-Italic] [\typescriptthree-utmri8a] [encoding=\typescriptthree]
- \definefontsynonym [Times-Bold] [\typescriptthree-utmb8a] [encoding=\typescriptthree]
- \definefontsynonym [Times-BoldItalic] [\typescriptthree-utmbi8a] [encoding=\typescriptthree]
- \definefontsynonym [Times-Slanted] [\typescriptthree-utmr8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Times-BoldSlanted] [\typescriptthree-utmb8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Times-Caps] [Times-Roman]
- \definefontsynonym [Times] [Times-Roman]
-
- \loadmapfile[\typescriptthree-urw-times.map]
-\stoptypescript
-
-% Math Times (tx)
-
-\starttypescript [math] [times] [all]
- \definefontsynonym [Times-Roman-Upright] [txr]
- \definefontsynonym [Times-Roman-Italic] [txi]
- \definefontsynonym [Times-Roman-Slanted] [txsl]
- \definefontsynonym [Times-Roman-Caps] [txsc]
- \definefontsynonym [Times-Companion-Upright] [tcxr]
- \definefontsynonym [Times-Companion-Italic] [tcxi]
- \definefontsynonym [Times-Companion-Slanted] [tcxsl]
- \definefontsynonym [Times-Math-Italic] [txmi]
- \definefontsynonym [Times-Math-Symbols] [txsy]
- \definefontsynonym [Times-Math-Extension] [txex]
- \definefontsynonym [Times-Math-SymbolsA] [txsya]
- \definefontsynonym [Times-Math-SymbolsB] [txsyb]
- \definefontsynonym [Times-Math-SymbolsC] [txsyc]
- \definefontsynonym [Times-Math-Italic-A] [txmia]
- \definefontsynonym [Times-Math-Extension-A] [txexa]
-
- \loadmapfile[original-youngryu-tx.map]
-\stoptypescript
-
% Antykwa Torunska (GUST)
% \starttypescript [serif] [antykwa-torunska] [texnansi,ec,8r]
@@ -772,7 +720,6 @@
\definefontsynonym [AntykwaTorunska-CondLightItalic][\typescriptthree-anttcli] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondMedium] [\typescriptthree-anttcm] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondMedItalic] [\typescriptthree-anttcmi] [encoding=\typescriptthree]
-
\loadmapfile[antt-\typescriptthree.map]
\stoptypescript
@@ -793,7 +740,6 @@
\definefontsynonym [AntykwaTorunska-CondLightItalicCap][\typescriptthree-anttclicap] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondMediumCap] [\typescriptthree-anttcmcap] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondMedItalicCap] [\typescriptthree-anttcmicap] [encoding=\typescriptthree]
-
\loadmapfile[antt-\typescriptthree.map]
\stoptypescript
@@ -817,7 +763,6 @@
\definefontsynonym [AntykwaTorunska-CondMedItalicCap] [\typescriptthree-anttcmi] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondCap] [\typescriptthree-anttcr] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondItalicCap] [\typescriptthree-anttcri] [encoding=\typescriptthree]
-
\loadmapfile[antt-\typescriptthree.map]
\stoptypescript
@@ -838,7 +783,6 @@
\definefontsynonym [AntykwaTorunska-CondMedItalicCap] [\typescriptthree-anttcmi] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondCap] [\typescriptthree-anttcr] [encoding=\typescriptthree]
\definefontsynonym [AntykwaTorunska-CondItalicCap] [\typescriptthree-anttcri] [encoding=\typescriptthree]
-
\loadmapfile[antt-\typescriptthree.map]
\stoptypescript
@@ -874,6 +818,7 @@
\stoptypescript
\starttypescript [math] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond] [default]
+ \usemathcollection[default]
\loadmapfile[antt-rm.map]
\loadmapfile[antt-mi.map]
\loadmapfile[antt-sy.map]
@@ -887,7 +832,6 @@
\definefontsynonym [AntykwaPoltawskiego-Bold] [\typescriptthree-antpb] [encoding=\typescriptthree]
\definefontsynonym [AntykwaPoltawskiego-Italic] [\typescriptthree-antpri] [encoding=\typescriptthree]
\definefontsynonym [AntykwaPoltawskiego-BoldItalic] [\typescriptthree-antpbi] [encoding=\typescriptthree]
-
\loadmapfile[\typescriptthree-public-antp.map]
\stoptypescript
@@ -896,7 +840,6 @@
% maybe this will change in Iwona-Math-Letters and Iwona-Math-Letters-Italic
\starttypescript [sans] [iwona-light,iwona,iwona-medium,iwona-heavy,iwona-light-cond,iwona-cond,iwona-medium-cond,iwona-heavy-cond] [texnansi,ec,el,qx,t5]
-
\definefontsynonym[Iwona-Regular] [\typescriptthree-iwonar] [encoding=\typescriptthree]
\definefontsynonym[Iwona-Italic] [\typescriptthree-iwonari] [encoding=\typescriptthree]
\definefontsynonym[Iwona-Bold] [\typescriptthree-iwonab] [encoding=\typescriptthree]
@@ -907,7 +850,6 @@
\definefontsynonym[Iwona-Medium-Italic] [\typescriptthree-iwonami] [encoding=\typescriptthree]
\definefontsynonym[Iwona-Heavy-Regular] [\typescriptthree-iwonah] [encoding=\typescriptthree]
\definefontsynonym[Iwona-Heavy-Italic] [\typescriptthree-iwonahi] [encoding=\typescriptthree]
-
\definefontsynonym[Iwona-CapsRegular] [\typescriptthree-iwonarcap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsItalic] [\typescriptthree-iwonaricap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsBold] [\typescriptthree-iwonabcap] [encoding=\typescriptthree]
@@ -918,7 +860,6 @@
\definefontsynonym[Iwona-CapsMedium-Italic] [\typescriptthree-iwonamicap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsHeavy-Regular] [\typescriptthree-iwonahcap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsHeavy-Italic] [\typescriptthree-iwonahicap] [encoding=\typescriptthree]
-
\definefontsynonym[Iwona-CondRegular] [\typescriptthree-iwonacr] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CondItalic] [\typescriptthree-iwonacri] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CondBold] [\typescriptthree-iwonacb] [encoding=\typescriptthree]
@@ -929,7 +870,6 @@
\definefontsynonym[Iwona-CondMedium-Italic] [\typescriptthree-iwonacmi] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CondHeavy-Regular] [\typescriptthree-iwonach] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CondHeavy-Italic] [\typescriptthree-iwonachi] [encoding=\typescriptthree]
-
\definefontsynonym[Iwona-CapsCondRegular] [\typescriptthree-iwonacrcap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsCondItalic] [\typescriptthree-iwonacricap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsCondBold] [\typescriptthree-iwonacbcap] [encoding=\typescriptthree]
@@ -940,7 +880,6 @@
\definefontsynonym[Iwona-CapsCondMedium-Italic] [\typescriptthree-iwonacmicap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsCondHeavy-Regular] [\typescriptthree-iwonachcap] [encoding=\typescriptthree]
\definefontsynonym[Iwona-CapsCondHeavy-Italic] [\typescriptthree-iwonachicap] [encoding=\typescriptthree]
-
\loadmapfile[iwona-\typescriptthree.map]
\stoptypescript
@@ -973,6 +912,7 @@
\stoptypescript
\starttypescript [math] [iwona,iwona-light,iwona-medium,iwona-heavy] [default]
+ \usemathcollection[default]
\loadmapfile[iwona-rm.map]
\loadmapfile[iwona-mi.map]
\loadmapfile[iwona-sy.map]
@@ -981,21 +921,6 @@
% Kurier (JMN)
-% \starttypescript [sans] [kurier-light,kurier,kurier-medium] [texnansi,ec,qx,t5]
-% \definefontsynonym[Kurier-Regular] [\typescriptthree-kurierr] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Italic] [\typescriptthree-kurierri] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Bold] [\typescriptthree-kurierb] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-BoldItalic] [\typescriptthree-kurierbi] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Light-Regular] [\typescriptthree-kurierl] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Light-Italic] [\typescriptthree-kurierli] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Medium-Regular][\typescriptthree-kurierm] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Medium-Italic] [\typescriptthree-kuriermi] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Heavy-Regular] [\typescriptthree-kurierh] [encoding=\typescriptthree]
-% \definefontsynonym[Kurier-Heavy-Italic] [\typescriptthree-kurierhi] [encoding=\typescriptthree]
-
-% \loadmapfile[kurier-\typescriptthree.map]
-% \stoptypescript
-
\starttypescript [sans] [kurier-light,kurier,kurier-medium] [texnansi,ec,qx,t5]
\definefontsynonym[Kurier-Regular] [\typescriptthree-kurierr] [encoding=\typescriptthree]
\definefontsynonym[Kurier-Italic] [\typescriptthree-kurierri] [encoding=\typescriptthree]
@@ -1008,7 +933,6 @@
\definefontsynonym[Kurier-MediumItalic] [\typescriptthree-kuriermi] [encoding=\typescriptthree]
\definefontsynonym[Kurier-Heavy] [\typescriptthree-kurierh] [encoding=\typescriptthree]
\definefontsynonym[Kurier-HeavyItalic] [\typescriptthree-kurierhi] [encoding=\typescriptthree]
-
\loadmapfile[kurier-\typescriptthree.map]
\stoptypescript
@@ -1034,54 +958,105 @@
\stoptypescript
\starttypescript [math] [kurier,kurier-light,kurier-medium] [default]
+ \usemathcollection[default]
\loadmapfile[kurier-rm.map]
\loadmapfile[kurier-mi.map]
\loadmapfile[kurier-sy.map]
\loadmapfile[kurier-ex.map]
\stoptypescript
-% Palatino (URW)
-
-\starttypescript [serif] [palatino] [qx]
- \definefontsynonym [qx-uplr8a] [qplr] [encoding=qx]
- \definefontsynonym [qx-uplri8a] [qplri] [encoding=qx]
- \definefontsynonym [qx-uplb8a] [qplb] [encoding=qx]
- \definefontsynonym [qx-uplbi8a] [qplbi] [encoding=qx]
- \definefontsynonym [qx-uplr8a-slanted-167] [qplri] [encoding=qx]
- \definefontsynonym [qx-uplb8a-slanted-167] [qplbi] [encoding=qx]
- \definefontsynonym [qx-uplr8a-capitalized-800] [qplr] [encoding=qx]
+\starttypescript [kurier-light,kurier,kurier-medium] [texnansi,ec,qx,t5]
+ \definetypeface[\typescriptone][ss][sans] [\typescriptone] [default][encoding=\typescripttwo]
+ \definetypeface[\typescriptone][rm][serif][modern] [default][encoding=\typescripttwo]
+ \definetypeface[\typescriptone][tt][mono] [modern] [default][encoding=\typescripttwo,rscale=1.05]
+ \definetypeface[\typescriptone][mm][math] [\typescriptone] [default][encoding=\typescripttwo,text=ss]
+ \quittypescriptscanning
\stoptypescript
-\starttypescript [serif] [palatino] [texnansi,ec,8r,t5]
- \definefontsynonym [Palatino] [\typescriptthree-uplr8a] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-Italic] [\typescriptthree-uplri8a] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-Bold] [\typescriptthree-uplb8a] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-BoldItalic] [\typescriptthree-uplbi8a] [encoding=\typescriptthree]
+% Utopia (Adobe)
- \definefontsynonym [Palatino-Slanted] [\typescriptthree-uplr8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-BoldSlanted] [\typescriptthree-uplb8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Palatino-Caps] [\typescriptthree-uplr8a-capitalized-800] [encoding=\typescriptthree]
+\starttypescript [serif] [utopia] [ec,texnansi]
+ \definefontsynonym [Utopia-Regular] [\typescriptthree-putr8a] [encoding=\typescriptthree]
+ \definefontsynonym [Utopia-Italic] [\typescriptthree-putri8a] [encoding=\typescriptthree]
+ \definefontsynonym [Utopia-Bold] [\typescriptthree-putb8a] [encoding=\typescriptthree]
+ \definefontsynonym [Utopia-BoldItalic] [\typescriptthree-putbi8a] [encoding=\typescriptthree]
+ \definefontsynonym [Utopia-Slanted] [\typescriptthree-putr8a-slanted-167] [encoding=\typescriptthree]
+ \definefontsynonym [Utopia-BoldSlanted] [\typescriptthree-putb8a-slanted-167] [encoding=\typescriptthree]
+ \definefontsynonym [Utopia-Regular-Caps][\typescriptthree-putr8a-capitalized-800] [encoding=\typescriptthree]
+ \loadmapfile[\typescriptthree-adobe-utopia.map]
+\stoptypescript
- \loadmapfile[\typescriptthree-urw-palatino.map]
+% Charter (Bitstream)
+
+\starttypescript [serif] [charter] [ec,texnansi,8r]
+ \definefontsynonym [Charter-Roman] [\typescriptthree-bchr8a] [encoding=\typescriptthree]
+ \definefontsynonym [Charter-Italic] [\typescriptthree-bchri8a] [encoding=\typescriptthree]
+ \definefontsynonym [Charter-Bold] [\typescriptthree-bchb8a] [encoding=\typescriptthree]
+ \definefontsynonym [Charter-BoldItalic] [\typescriptthree-bchbi8a] [encoding=\typescriptthree]
+ \definefontsynonym [Charter-Slanted] [\typescriptthree-bchr8a-slanted-167] [encoding=\typescriptthree]
+ \definefontsynonym [Charter-BoldSlanted][\typescriptthree-bchb8a-slanted-167] [encoding=\typescriptthree]
+ \definefontsynonym [Charter-Roman-Caps] [\typescriptthree-bchr8a-capitalized-800] [encoding=\typescriptthree]
+ \loadmapfile[\typescriptthree-bitstrea-charter.map]
\stoptypescript
-% bonus definitions
+% Whatever else we need:
+
+\starttypescript
+ \definefontsynonym [ZapfDingbats] [uzdr]
+ \definefontsynonym [RalfSmithFormalScript] [rsfs10]
+ \definefontsynonym [MartinVogel] [fmvr8x]
+\stoptypescript
-% when these fonts are in tex live ...
%
-% \definefontsynonym [Palatino-Caps] [TeXPalladioL-SC] [encoding=\typescriptthree]
+% TeXGyre
+%
+% We now use tex-gyre fonts by default ...
+
+\definetypescriptprefix [f:pagella] [pl] \definetypescriptprefix [f:palatino] [pl]
+\definetypescriptprefix [f:termes] [tm] \definetypescriptprefix [f:times] [tm]
+\definetypescriptprefix [f:heros] [hv] \definetypescriptprefix [f:helvetica] [hv]
+\definetypescriptprefix [f:bonum] [bk] \definetypescriptprefix [f:bookman] [bk]
+\definetypescriptprefix [f:schola] [cs] \definetypescriptprefix [f:schoolbook] [cs]
+\definetypescriptprefix [f:adventor][ag] %definetypescriptprefix [f:adventor] [ag]
+\definetypescriptprefix [f:cursor] [cr] \definetypescriptprefix [f:courier] [cr]
+\definetypescriptprefix [f:chorus] [zc] \definetypescriptprefix [f:chancery] [zc] % not the full set
-\starttypescript [serif] [palatino] [ec,texnansi,8r]
+\starttypescript [serif,sans,mono] [pagella,palatino,termes,times,adventor,bonum,bookman,cursor,courier,heros,helvetica,schola,schoolbook] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}r] [encoding=\typescriptthree]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}ri] [encoding=\typescriptthree]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}b] [encoding=\typescriptthree]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}bi] [encoding=\typescriptthree]
+ \loadmapfile[q\typescriptprefix{f:\typescripttwo}-\typescriptthree.map]
+\stoptypescript
- \definefontsynonym[TeXPalladioL-BoldItalicOsF][\typescriptthree-fplbij8a][encoding=\typescriptthree]
- \definefontsynonym[TeXPalladioL-BoldOsF] [\typescriptthree-fplbj8a] [encoding=\typescriptthree]
- \definefontsynonym[TeXPalladioL-SC] [\typescriptthree-fplrc8a] [encoding=\typescriptthree]
- \definefontsynonym[TeXPalladioL-ItalicOsF] [\typescriptthree-fplrij8a][encoding=\typescriptthree]
+\starttypescript [serif,sans,mono] [pagella,palatino,termes,times,adventor,bonum,bookman,cursor,courier,heros,helvetica,schola,schoolbook] [ec,texnansi,cs,qx,rm,t5,l7x]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Caps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}r-sc] [encoding=\typescriptthree]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}ri-sc] [encoding=\typescriptthree]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldCaps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}b-sc] [encoding=\typescriptthree]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [\typescriptthree-q\typescriptprefix{f:\typescripttwo}bi-sc] [encoding=\typescriptthree]
+ \loadmapfile[q\typescriptprefix{f:\typescripttwo}-\typescriptthree.map]
+\stoptypescript
- \loadmapfile[\typescriptthree-urw-palatino.map]
+\starttypescript [serif] [chorus,chancery] [ec,texnansi,cs,qx,rm,t5,t2a,t2b,t2c,l7x]
+ \definefontsynonym [TeXGyreChorus-MediumItalic] [\typescriptthree-qzcmi] [encoding=\typescriptthree]
+ \loadmapfile[qzc-\typescriptthree.map]
\stoptypescript
-% Palatino Math (PX)
+% bonus definitions
+
+% when these fonts are in tex live ...
+%
+% \definefontsynonym [Palatino-Caps] [TeXPalladioL-SC] [encoding=\typescriptthree]
+%
+% \starttypescript [serif] [palatino] [ec,texnansi]
+% \definefontsynonym[TeXPalladioL-BoldItalicOsF][\typescriptthree-fplbij8a][encoding=\typescriptthree]
+% \definefontsynonym[TeXPalladioL-BoldOsF] [\typescriptthree-fplbj8a] [encoding=\typescriptthree]
+% \definefontsynonym[TeXPalladioL-SC] [\typescriptthree-fplrc8a] [encoding=\typescriptthree]
+% \definefontsynonym[TeXPalladioL-ItalicOsF] [\typescriptthree-fplrij8a][encoding=\typescriptthree]
+% \loadmapfile[\typescriptthree-urw-palatino.map]
+% \stoptypescript
+
+% Palatino Math (px)
\starttypescript [math] [palatino] [all]
\definefontsynonym [Palatino-Roman-Upright] [pxr]
@@ -1099,93 +1074,110 @@
\definefontsynonym [Palatino-Math-SymbolsC] [pxsyc]
\definefontsynonym [Palatino-Math-Italic-A] [pxmia]
\definefontsynonym [Palatino-Math-Extension-A] [pxexa]
-
+ \usemathcollection[default]
\loadmapfile[original-youngryu-px.map]
\stoptypescript
-% Bookman (URW)
+% Times Math (tx)
-\starttypescript [serif] [bookman] [qx]
- \definefontsynonym [qx-ubkl8a] [qbkr] [encoding=qx]
- \definefontsynonym [qx-ubkli8a] [qbkri] [encoding=qx]
- \definefontsynonym [qx-ubkd8a] [qbkb] [encoding=qx]
- \definefontsynonym [qx-ubkdi8a] [qbkbi] [encoding=qx]
- \definefontsynonym [qx-ubkl8a-slanted-167] [qbkri] [encoding=qx]
- \definefontsynonym [qx-ubkd8a-slanted-167] [qbkbi] [encoding=qx]
- \definefontsynonym [qx-ubkl8a-capitalized-800] [qbkr] [encoding=qx]
+\starttypescript [math] [times] [all]
+ \definefontsynonym [Times-Roman-Upright] [txr]
+ \definefontsynonym [Times-Roman-Italic] [txi]
+ \definefontsynonym [Times-Roman-Slanted] [txsl]
+ \definefontsynonym [Times-Roman-Caps] [txsc]
+ \definefontsynonym [Times-Companion-Upright] [tcxr]
+ \definefontsynonym [Times-Companion-Italic] [tcxi]
+ \definefontsynonym [Times-Companion-Slanted] [tcxsl]
+ \definefontsynonym [Times-Math-Italic] [txmi]
+ \definefontsynonym [Times-Math-Symbols] [txsy]
+ \definefontsynonym [Times-Math-Extension] [txex]
+ \definefontsynonym [Times-Math-SymbolsA] [txsya]
+ \definefontsynonym [Times-Math-SymbolsB] [txsyb]
+ \definefontsynonym [Times-Math-SymbolsC] [txsyc]
+ \definefontsynonym [Times-Math-Italic-A] [txmia]
+ \definefontsynonym [Times-Math-Extension-A] [txexa]
+ \usemathcollection[default]
+ \loadmapfile[original-youngryu-tx.map]
\stoptypescript
-\starttypescript [serif] [bookman] [ec,texnansi,8r,t5]
- \definefontsynonym [Bookman-Light] [\typescriptthree-ubkl8a] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-LightItalic] [\typescriptthree-ubkli8a] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-DemiBold] [\typescriptthree-ubkd8a] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-DemiBoldItalic] [\typescriptthree-ubkdi8a] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-LightSlanted] [\typescriptthree-ubkl8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-DemiBoldSlanted] [\typescriptthree-ubkd8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Bookman-Light-Caps] [\typescriptthree-ubkl8a-capitalized-800] [encoding=\typescriptthree]
+%D These are just fallbacks in case anyone stil uses the old names (might also be removed?).
- \loadmapfile[\typescriptthree-urw-bookman.map]
+%
+% TeXGyrePagella
+%
+\starttypescript [serif] [palatino]
+ \definefontsynonym [Palatino] [TeXGyrePagella-Regular]
+ \definefontsynonym [Palatino-Italic] [TeXGyrePagella-Italic]
+ \definefontsynonym [Palatino-Bold] [TeXGyrePagella-Bold]
+ \definefontsynonym [Palatino-BoldItalic] [TeXGyrePagella-BoldItalic]
+ \definefontsynonym [Palatino-Slanted] [TeXGyrePagella-Italic]
+ \definefontsynonym [Palatino-BoldSlanted] [TeXGyrePagella-BoldItalic]
+ \definefontsynonym [Palatino-Caps] [TeXGyrePagella-Caps]
\stoptypescript
-
-% Chancery (URW)
-
-\starttypescript [calligraphy] [chancery] [qx]
- \definefontsynonym [qx-uzcmi8a] [qzcmi] [encoding=qx]
+%
+% TeXGyreTermes
+%
+\starttypescript [serif] [times]
+ \definefontsynonym [Times-Roman] [TeXGyreTermes-Regular]
+ \definefontsynonym [Times-Italic] [TeXGyreTermes-Italic]
+ \definefontsynonym [Times-Bold] [TeXGyreTermes-Bold]
+ \definefontsynonym [Times-BoldItalic] [TeXGyreTermes-BoldItalic]
+ \definefontsynonym [Times-Slanted] [TeXGyreTermes-Italic]
+ \definefontsynonym [Times-BoldSlanted] [TeXGyreTermes-BoldItalic]
+ \definefontsynonym [Times-Caps] [TeXGyreTermes-Caps]
\stoptypescript
-
-\starttypescript [calligraphy] [chancery] [ec,texnansi,8r]
- \definefontsynonym [Chancery] [\typescriptthree-uzcmi8a] [encoding=\typescriptthree]
- \loadmapfile[\typescriptthree-urw-zapfchan.map]
+%
+% TeXGyreHeros
+%
+\starttypescript [sans] [helvetica]
+ \definefontsynonym [Helvetica] [TeXGyreHeros-Regular]
+ \definefontsynonym [Helvetica-Oblique] [TeXGyreHeros-Italic]
+ \definefontsynonym [Helvetica-Bold] [TeXGyreHeros-Bold]
+ \definefontsynonym [Helvetica-BoldOblique] [TeXGyreHeros-BoldItalic]
+ \definefontsynonym [Helvetica-Caps] [TeXGyreHeros-Caps]
\stoptypescript
-
-% New Century Schoolbook (URW)
-
-\starttypescript [serif] [schoolbook] [ec,texnansi,8r,t5]
- \definefontsynonym [Schoolbook-Roman] [\typescriptthree-uncr8a] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-Italic] [\typescriptthree-uncri8a] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-Bold] [\typescriptthree-uncb8a] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-BoldItalic] [\typescriptthree-uncbi8a] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-RomanSlanted] [\typescriptthree-uncr8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-BoldSlanted] [\typescriptthree-uncb8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Schoolbook-Roman-Caps] [\typescriptthree-uncr8a-capitalized-800] [encoding=\typescriptthree]
-
- \loadmapfile[\typescriptthree-urw-ncntrsbk.map]
+%
+% TeXGyreBonum
+%
+\starttypescript [serif] [bookman]
+ \definefontsynonym [Bookman-Light] [TeXGyreBonum-Regular]
+ \definefontsynonym [Bookman-LightItalic] [TeXGyreBonum-Italic]
+ \definefontsynonym [Bookman-DemiBold] [TeXGyreBonum-Bold]
+ \definefontsynonym [Bookman-DemiBoldItalic] [TeXGyreBonum-BoldItalic]
+ \definefontsynonym [Bookman-LightSlanted] [TeXGyreBonum-Italic]
+ \definefontsynonym [Bookman-DemiBoldSlanted] [TeXGyreBonum-BoldItalic]
+ \definefontsynonym [Bookman-Light-Caps] [TeXGyreBonum-Caps]
\stoptypescript
-
-% Utopia (Adobe)
-
-\starttypescript [serif] [utopia] [ec,texnansi]
- \definefontsynonym [Utopia-Regular] [\typescriptthree-putr8a] [encoding=\typescriptthree]
- \definefontsynonym [Utopia-Italic] [\typescriptthree-putri8a] [encoding=\typescriptthree]
- \definefontsynonym [Utopia-Bold] [\typescriptthree-putb8a] [encoding=\typescriptthree]
- \definefontsynonym [Utopia-BoldItalic] [\typescriptthree-putbi8a] [encoding=\typescriptthree]
- \definefontsynonym [Utopia-Slanted] [\typescriptthree-putr8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Utopia-BoldSlanted] [\typescriptthree-putb8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Utopia-Regular-Caps][\typescriptthree-putr8a-capitalized-800] [encoding=\typescriptthree]
-
- \loadmapfile[\typescriptthree-adobe-utopia.map]
+%
+% TeXGyreScola
+%
+\starttypescript [serif] [schoolbook]
+ \definefontsynonym [Schoolbook-Roman] [TeXGyreScola-Regular]
+ \definefontsynonym [Schoolbook-Italic] [TeXGyreScola-Italic]
+ \definefontsynonym [Schoolbook-Bold] [TeXGyreScola-Bold]
+ \definefontsynonym [Schoolbook-BoldItalic] [TeXGyreScola-BoldItalic]
+ \definefontsynonym [Schoolbook-Slanted] [TeXGyreScola-Italic]
+ \definefontsynonym [Schoolbook-BoldSlanted] [TeXGyreScola-BoldItalic]
+ \definefontsynonym [Schoolbook-Roman-Caps] [TeXGyreScola-Caps]
\stoptypescript
-
-% Charter (Bitstream)
-
-\starttypescript [serif] [charter] [ec,texnansi,8r]
- \definefontsynonym [Charter-Roman] [\typescriptthree-bchr8a] [encoding=\typescriptthree]
- \definefontsynonym [Charter-Italic] [\typescriptthree-bchri8a] [encoding=\typescriptthree]
- \definefontsynonym [Charter-Bold] [\typescriptthree-bchb8a] [encoding=\typescriptthree]
- \definefontsynonym [Charter-BoldItalic] [\typescriptthree-bchbi8a] [encoding=\typescriptthree]
- \definefontsynonym [Charter-Slanted] [\typescriptthree-bchr8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Charter-BoldSlanted][\typescriptthree-bchb8a-slanted-167] [encoding=\typescriptthree]
- \definefontsynonym [Charter-Roman-Caps] [\typescriptthree-bchr8a-capitalized-800] [encoding=\typescriptthree]
-
- \loadmapfile[\typescriptthree-bitstrea-charter.map]
+%
+% TeXGyreAdventor
+%
+%
+% TeXGyreCursor
+%
+\starttypescript [mono] [courier]
+ \definefontsynonym [Courier] [TeXGyreCursor-Regular]
+ \definefontsynonym [Courier-Bold] [TeXGyreCursor-Bold]
+ \definefontsynonym [Courier-Oblique] [TeXGyreCursor-Italic]
+ \definefontsynonym [Courier-BoldOblique] [TeXGyreCursor-BoldItalic]
+ \fakecontrolspace
\stoptypescript
-
-% Whatever else we need:
-
-\starttypescript
- \definefontsynonym [ZapfDingbats] [uzdr]
- \definefontsynonym [RalfSmithFormalScript] [rsfs10]
- \definefontsynonym [MartinVogel] [fmvr8x]
+%
+% TeXGyreChorus
+%
+\starttypescript [calligraphy] [chancery]
+ \definefontsynonym [Chancery] [TeXGyreChorus-MediumItalic]
\stoptypescript
\stoptypescriptcollection
diff --git a/tex/context/base/type-otf.mkii b/tex/context/base/type-otf.mkii
new file mode 100644
index 000000000..869555688
--- /dev/null
+++ b/tex/context/base/type-otf.mkii
@@ -0,0 +1,535 @@
+%D \module
+%D [ file=type-otf,
+%D version=2007.07.30,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Opentype Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Actually, \LUATEX\ does not need all these definitions since it can
+%D consult its database. However, here we use the names that we used
+%D in good old \TEX, and these may differ a bit. Here we also see
+%D some oldstyle definitions which normally are done with features.
+
+% if a fontname equals the filename, then use
+%
+% \setupfontsynonym [LMRoman10-DemiOblique] [features=default] % file is lowercase, so fails
+% \definefontsynonym [LMRoman10-DemiOblique] [name:LMRoman10-DemiOblique] [features=default]
+% \definefontsynonym [LMRoman10-DemiOblique] [lmroman10-demioblique] [features=default]
+
+\starttypescriptcollection[opentype]
+
+%D The names have changed (again) ... but I will not change the symbolic names
+%D any more. Filename changes will be catched in luatex (fallbacks) but not in
+%D other tex's.
+
+\starttypescript [serif] [modern,latin-modern]
+ \definefontsynonym [LMRoman5-Regular] [file:lmroman5-regular] [features=default]
+ \definefontsynonym [LMRoman6-Regular] [file:lmroman6-regular] [features=default]
+ \definefontsynonym [LMRoman7-Regular] [file:lmroman7-regular] [features=default]
+ \definefontsynonym [LMRoman8-Regular] [file:lmroman8-regular] [features=default]
+ \definefontsynonym [LMRoman9-Regular] [file:lmroman9-regular] [features=default]
+ \definefontsynonym [LMRoman10-Regular] [file:lmroman10-regular] [features=default]
+ \definefontsynonym [LMRoman12-Regular] [file:lmroman12-regular] [features=default]
+ \definefontsynonym [LMRoman17-Regular] [file:lmroman17-regular] [features=default]
+ \definefontsynonym [LMRoman5-Bold] [file:lmroman5-bold] [features=default]
+ \definefontsynonym [LMRoman6-Bold] [file:lmroman6-bold] [features=default]
+ \definefontsynonym [LMRoman7-Bold] [file:lmroman7-bold] [features=default]
+ \definefontsynonym [LMRoman8-Bold] [file:lmroman8-bold] [features=default]
+ \definefontsynonym [LMRoman9-Bold] [file:lmroman9-bold] [features=default]
+ \definefontsynonym [LMRoman10-Bold] [file:lmroman10-bold] [features=default]
+ \definefontsynonym [LMRoman12-Bold] [file:lmroman12-bold] [features=default]
+ \definefontsynonym [LMRoman7-Italic] [file:lmroman7-italic] [features=default]
+ \definefontsynonym [LMRoman8-Italic] [file:lmroman8-italic] [features=default]
+ \definefontsynonym [LMRoman9-Italic] [file:lmroman9-italic] [features=default]
+ \definefontsynonym [LMRoman10-Italic] [file:lmroman10-italic] [features=default]
+ \definefontsynonym [LMRoman12-Italic] [file:lmroman12-italic] [features=default]
+ \definefontsynonym [LMRoman10-BoldItalic] [file:lmroman10-bolditalic] [features=default]
+ \definefontsynonym [LMRoman8-Oblique] [file:lmromanslant8-regular] [features=default]
+ \definefontsynonym [LMRoman9-Oblique] [file:lmromanslant9-regular] [features=default]
+ \definefontsynonym [LMRoman10-Oblique] [file:lmromanslant10-regular][features=default]
+ \definefontsynonym [LMRoman12-Oblique] [file:lmromanslant12-regular][features=default]
+ \definefontsynonym [LMRoman17-Oblique] [file:lmromanslant17-regular][features=default]
+ \definefontsynonym [LMRoman10-BoldOblique] [file:lmromanslant10-bold] [features=default]
+ \definefontsynonym [LMRoman10-Demi] [file:lmromandemi10-regular] [features=default]
+ \definefontsynonym [LMRoman10-DemiOblique] [file:lmromandemi10-oblique] [features=default]
+ \definefontsynonym [LMRoman10-CapsRegular] [file:lmromancaps10-regular] [features=default] % features=smallcaps?
+ \definefontsynonym [LMRoman10-CapsOblique] [file:lmromancaps10-oblique] [features=default]
+
+ \definefontsynonym [LMRoman10-Dunhill] [file:lmromandunh10-regular] [features=default]
+ \definefontsynonym [LMRoman10-DunhillOblique] [file:lmromandunh10-oblique] [features=default]
+ \definefontsynonym [LMRoman10-Unslanted] [file:lmromanunsl10-regular] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [modern,latin-modern]
+ \definefontsynonym [LMSans8-Regular] [file:lmsans8-regular] [features=default]
+ \definefontsynonym [LMSans9-Regular] [file:lmsans9-regular] [features=default]
+ \definefontsynonym [LMSans10-Regular] [file:lmsans10-regular] [features=default]
+ \definefontsynonym [LMSans12-Regular] [file:lmsans12-regular] [features=default]
+ \definefontsynonym [LMSans17-Regular] [file:lmsans17-regular] [features=default]
+ \definefontsynonym [LMSans10-Bold] [file:lmsans10-bold] [features=default]
+ \definefontsynonym [LMSans8-Oblique] [file:lmsans8-oblique] [features=default]
+ \definefontsynonym [LMSans9-Oblique] [file:lmsans9-oblique] [features=default]
+ \definefontsynonym [LMSans10-Oblique] [file:lmsans10-oblique] [features=default]
+ \definefontsynonym [LMSans12-Oblique] [file:lmsans12-oblique] [features=default]
+ \definefontsynonym [LMSans17-Oblique] [file:lmsans17-oblique] [features=default]
+ \definefontsynonym [LMSans10-BoldOblique] [file:lmsans10-boldoblique] [features=default]
+
+ \definefontsynonym [LMSans10-DemiCondensed] [file:lmsansdemicond10-regular] [features=default]
+ \definefontsynonym [LMSans10-DemiCondensedOblique] [file:lmsansdemicond10-oblique] [features=default]
+
+ \definefontsynonym [LMSansQuotation8-Regular] [file:lmsansquot8-regular] [features=default]
+ \definefontsynonym [LMSansQuotation8-Bold] [file:lmsansquot8-bold] [features=default]
+ \definefontsynonym [LMSansQuotation8-Oblique] [file:lmsansquot8-oblique] [features=default]
+ \definefontsynonym [LMSansQuotation8-BoldOblique] [file:lmsansquot8-boldoblique] [features=default]
+\stoptypescript
+
+\starttypescript [mono] [modern,latin-modern,modern-vari,latin-modern-vari,modern-cond,latin-modern-cond]
+ \definefontsynonym [LMTypewriter8-Regular] [file:lmmono8-regular] [features=none]
+ \definefontsynonym [LMTypewriter9-Regular] [file:lmmono9-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-Regular] [file:lmmono10-regular] [features=none]
+ \definefontsynonym [LMTypewriter12-Regular] [file:lmmono12-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-Italic] [file:lmmono10-italic] [features=none]
+ \definefontsynonym [LMTypewriter10-Oblique] [file:lmmonoslant10-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-CapsRegular] [file:lmmonocaps10-regular] [features=none] % features=smallcaps?
+ \definefontsynonym [LMTypewriter10-CapsOblique] [file:lmmonocaps10-oblique] [features=none]
+
+ \definefontsynonym [LMTypewriter10-Light] [file:lmmonolt10-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-LightOblique] [file:lmmonolt10-oblique] [features=none]
+ \definefontsynonym [LMTypewriter10-LightCondensed] [file:lmmonoltcond10-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-LightCondensedOblique] [file:lmmonoltcond10-oblique] [features=none]
+
+ \definefontsynonym [LMTypewriter10-Dark] [file:lmmonolt10-bold] [features=none]
+ \definefontsynonym [LMTypewriter10-DarkOblique] [file:lmmonolt10-boldoblique] [features=none]
+
+ \definefontsynonym [LMTypewriterVarWd10-Regular] [file:lmmonoproplt10-regular] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-Oblique] [file:lmmonoproplt10-oblique] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-Light] [file:lmmonoprop10-regular] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-LightOblique] [file:lmmonoprop10-oblique] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-Dark] [file:lmmonoproplt10-bold] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-DarkOblique] [file:lmmonoproplt10-boldoblique] [features=default]
+\stoptypescript
+
+\starttypescript [math] [modern,latin-modern]
+ \definefontsynonym [LMMathRoman5-Regular] [rm-lmr5]
+ \definefontsynonym [LMMathRoman6-Regular] [rm-lmr6]
+ \definefontsynonym [LMMathRoman7-Regular] [rm-lmr7]
+ \definefontsynonym [LMMathRoman8-Regular] [rm-lmr8]
+ \definefontsynonym [LMMathRoman9-Regular] [rm-lmr9]
+ \definefontsynonym [LMMathRoman10-Regular] [rm-lmr10]
+ \definefontsynonym [LMMathRoman12-Regular] [rm-lmr12]
+ \definefontsynonym [LMMathRoman17-Regular] [rm-lmr17]
+ \definefontsynonym [LMMathRoman5-Bold] [rm-lmbx5]
+ \definefontsynonym [LMMathRoman6-Bold] [rm-lmbx6]
+ \definefontsynonym [LMMathRoman7-Bold] [rm-lmbx7]
+ \definefontsynonym [LMMathRoman8-Bold] [rm-lmbx8]
+ \definefontsynonym [LMMathRoman9-Bold] [rm-lmbx9]
+ \definefontsynonym [LMMathRoman10-Bold] [rm-lmbx10]
+ \definefontsynonym [LMMathRoman12-Bold] [rm-lmbx12]
+ \definefontsynonym [LMMathSymbols5-BoldItalic] [lmbsy5]
+ \definefontsynonym [LMMathSymbols7-BoldItalic] [lmbsy7]
+ \definefontsynonym [LMMathSymbols10-BoldItalic][lmbsy10]
+ \definefontsynonym [LMMathSymbols5-Italic] [lmsy5]
+ \definefontsynonym [LMMathSymbols6-Italic] [lmsy6]
+ \definefontsynonym [LMMathSymbols7-Italic] [lmsy7]
+ \definefontsynonym [LMMathSymbols8-Italic] [lmsy8]
+ \definefontsynonym [LMMathSymbols9-Italic] [lmsy9]
+ \definefontsynonym [LMMathSymbols10-Italic] [lmsy10]
+ \definefontsynonym [LMMathExtension10-Regular] [lmex10]
+ \definefontsynonym [LMMathItalic5-Italic] [lmmi5]
+ \definefontsynonym [LMMathItalic6-Italic] [lmmi6]
+ \definefontsynonym [LMMathItalic7-Italic] [lmmi7]
+ \definefontsynonym [LMMathItalic8-Italic] [lmmi8]
+ \definefontsynonym [LMMathItalic9-Italic] [lmmi9]
+ \definefontsynonym [LMMathItalic10-Italic] [lmmi10]
+ \definefontsynonym [LMMathItalic12-Italic] [lmmi12]
+ \definefontsynonym [LMMathItalic5-BoldItalic] [lmmib5]
+ \definefontsynonym [LMMathItalic7-BoldItalic] [lmmib7]
+ \definefontsynonym [LMMathItalic10-BoldItalic] [lmmib10]
+
+ \loadmapfile[lm-math.map]
+ \loadmapfile[lm-rm.map]
+\stoptypescript
+
+\starttypescript [math] [modern,computer-modern,latin-modern]
+ \definefontsynonym [ComputerModernMath-Roman] [rm-lmr10]
+ \definefontsynonym [ComputerModernMath-Extension] [lmex10]
+ \definefontsynonym [ComputerModernMath-Italic] [lmmi10]
+ \definefontsynonym [ComputerModernMath-Symbol] [lmsy10]
+\stoptypescript
+
+\starttypescript [boldmath,bfmath] [modern,computer-modern,latin-modern]
+ \definefontsynonym [ComputerModernMath-Roman-Bold] [rm-lmb10]
+ \definefontsynonym [ComputerModernMath-Extension] [lmex10]
+ \definefontsynonym [ComputerModernMath-Italic-Bold] [lmmib10]
+ \definefontsynonym [ComputerModernMath-Symbol-Bold] [lmbsy10]
+\stoptypescript
+
+% Computer Concrete (AMS)
+
+\starttypescript [serif] [concrete]
+ \definefontsynonym [ComputerConcrete] [ccr10]
+ \definefontsynonym [ComputerConcrete-Italic] [ccti10]
+ \definefontsynonym [ComputerConcrete-Slanted] [ccsl10]
+ \definefontsynonym [ComputerConcrete-Bold] [ComputerConcrete]
+ \definefontsynonym [ComputerConcrete-BoldItalic] [ComputerConcrete-Italic]
+ \definefontsynonym [ComputerConcrete-BoldSlanted] [ComputerConcrete-Slanted]
+ \definefontsynonym [ComputerConcrete-Caps] [cccsc10]
+\stoptypescript
+
+% Euler (AMS)
+
+\starttypescript [math] [euler]
+ \definefontsynonym [Euler-Roman] [zeurm10]
+ \definefontsynonym [Euler-Extension] [zeuex10]
+ \definefontsynonym [Euler-Symbol] [zeusm10]
+ \definefontsynonym [Euler-Fraktur] [eufm10]
+
+ \loadmapfile[original-ams-euler.map]
+\stoptypescript
+
+\starttypescript [boldmath,bfmath] [euler]
+ \definefontsynonym [Euler-Roman-Bold] [zeurb10]
+ \definefontsynonym [Euler-Extension] [zeuex10]
+ \definefontsynonym [Euler-Symbol-Bold] [zeusb10]
+ \definefontsynonym [Euler-Fraktur-Bold] [eufb10]
+
+ \loadmapfile[original-ams-euler.map]
+\stoptypescript
+
+% AMS (AMS)
+
+\starttypescript [math] [modern,computer-modern,latin-modern,ams]
+ \definefontsynonym [AMS-SymbolA] [msam10]
+ \definefontsynonym [AMS-SymbolB] [msbm10]
+\stoptypescript
+
+% TeXGyre
+
+\definetypescriptprefix [f:pagella] [pagella] \definetypescriptprefix [f:palatino] [pagella]
+\definetypescriptprefix [f:termes] [termes] \definetypescriptprefix [f:times] [termes]
+\definetypescriptprefix [f:heros] [heros] \definetypescriptprefix [f:helvetica] [heros]
+\definetypescriptprefix [f:bonum] [bonum] \definetypescriptprefix [f:bookman] [bonum]
+\definetypescriptprefix [f:schola] [schola] \definetypescriptprefix [f:schoolbook] [schola]
+\definetypescriptprefix [f:adventor][adventor] %definetypescriptprefix [f:adventor] [adventor]
+\definetypescriptprefix [f:cursor] [cursor] \definetypescriptprefix [f:courier] [cursor]
+\definetypescriptprefix [f:chorus] [chorus] \definetypescriptprefix [f:chancery] [chorus] % not the full set
+
+% name definitions & prefixes
+% \starttypescript [serif,sans,mono] [adventor,bonum,cursor,heros,pagella,palatino,schola,termes]
+% \starttypescript [serif] [pagella,palatino,termes,times,bonum,bookman,schola,schoolbook] [name]
+
+\starttypescript [serif,sans,mono] [adventor,bonum,bookman,cursor,courier,heros,helvetica,pagella,palatino,schola,schoolbook,termes,times]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Caps] [file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [features=smallcaps]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [features=smallcaps]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [features=smallcaps]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [features=smallcaps]
+\stoptypescript
+
+\starttypescript [serif,calligraphy] [chorus,chancery]
+ \definefontsynonym [TeXGyreChorus-MediumItalic] [file:texgyrechorus-mediumitalic] [features=default]
+\stoptypescript
+
+% Times Math (tx)
+
+\starttypescript [math] [times] [all]
+ \definefontsynonym [Times-Roman-Upright] [txr]
+ \definefontsynonym [Times-Roman-Italic] [txi]
+ \definefontsynonym [Times-Roman-Slanted] [txsl]
+ \definefontsynonym [Times-Roman-Caps] [txsc]
+ \definefontsynonym [Times-Companion-Upright] [tcxr]
+ \definefontsynonym [Times-Companion-Italic] [tcxi]
+ \definefontsynonym [Times-Companion-Slanted] [tcxsl]
+ \definefontsynonym [Times-Math-Italic] [txmi]
+ \definefontsynonym [Times-Math-Symbols] [txsy]
+ \definefontsynonym [Times-Math-Extension] [txex]
+ \definefontsynonym [Times-Math-SymbolsA] [txsya]
+ \definefontsynonym [Times-Math-SymbolsB] [txsyb]
+ \definefontsynonym [Times-Math-SymbolsC] [txsyc]
+ \definefontsynonym [Times-Math-Italic-A] [txmia]
+ \definefontsynonym [Times-Math-Extension-A] [txexa]
+
+ \loadmapfile[original-youngryu-tx.map]
+ \usemathcollection[default]
+\stoptypescript
+
+% Palatino Math (px)
+
+\starttypescript [math] [palatino] [all]
+ \definefontsynonym [Palatino-Roman-Upright] [pxr]
+ \definefontsynonym [Palatino-Roman-Italic] [pxi]
+ \definefontsynonym [Palatino-Roman-Slanted] [pxsl]
+ \definefontsynonym [Palatino-Roman-Caps] [pxsc]
+ \definefontsynonym [Palatino-Companion-Upright] [pcxr]
+ \definefontsynonym [Palatino-Companion-Italic] [pcxi]
+ \definefontsynonym [Palatino-Companion-Slanted] [pcxsl]
+ \definefontsynonym [Palatino-Math-Italic] [pxmi]
+ \definefontsynonym [Palatino-Math-Symbols] [pxsy]
+ \definefontsynonym [Palatino-Math-Extension] [pxex]
+ \definefontsynonym [Palatino-Math-SymbolsA] [pxsya]
+ \definefontsynonym [Palatino-Math-SymbolsB] [pxsyb]
+ \definefontsynonym [Palatino-Math-SymbolsC] [pxsyc]
+ \definefontsynonym [Palatino-Math-Italic-A] [pxmia]
+ \definefontsynonym [Palatino-Math-Extension-A] [pxexa]
+
+ \loadmapfile[original-youngryu-px.map]
+ \usemathcollection[default]
+\stoptypescript
+
+% Antykwa Torunska (GUST)
+
+\starttypescript [serif] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond]
+ \definefontsynonym [AntykwaTorunska-Regular] [file:AntykwaTorunska-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-Italic] [file:AntykwaTorunska-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-Bold] [file:AntykwaTorunska-Bold] [features=default]
+ \definefontsynonym [AntykwaTorunska-BoldItalic] [file:AntykwaTorunska-BoldItalic] [features=default]
+ \definefontsynonym [AntykwaTorunska-Light] [file:AntykwaTorunskaLight-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-LightItalic] [file:AntykwaTorunskaLight-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-Medium] [file:AntykwaTorunskaMed-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-MedItalic] [file:AntykwaTorunskaMed-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondRegular] [file:AntykwaTorunskaCond-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondItalic] [file:AntykwaTorunskaCond-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondBold] [file:AntykwaTorunskaCond-Bold] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondBoldItalic] [file:AntykwaTorunskaCond-BoldItalic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondLight] [file:AntykwaTorunskaCondLight-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondLightItalic] [file:AntykwaTorunskaCondLight-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondMedium] [file:AntykwaTorunskaCondMed-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondMedItalic] [file:AntykwaTorunskaCondMed-Italic] [features=default]
+
+ \definefontsynonym [AntykwaTorunska-Cap] [file:AntykwaTorunska-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-ItalicCap] [file:AntykwaTorunska-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-BoldCap] [file:AntykwaTorunska-Bold] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-BoldItalicCap] [file:AntykwaTorunska-BoldItalic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-LightCap] [file:AntykwaTorunskaLight-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-LightItalicCap] [file:AntykwaTorunskaLight-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-MediumCap] [file:AntykwaTorunskaMed-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-MedItalicCap] [file:AntykwaTorunskaMed-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondCap] [file:AntykwaTorunskaCond-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondItalicCap] [file:AntykwaTorunskaCond-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondBoldCap] [file:AntykwaTorunskaCond-Bold] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondBoldItalicCap] [file:AntykwaTorunskaCond-BoldItalic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondLightCap] [file:AntykwaTorunskaCondLight-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondLightItalicCap][file:AntykwaTorunskaCondLight-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondMediumCap] [file:AntykwaTorunskaCondMed-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondMedItalicCap] [file:AntykwaTorunskaCondMed-Italic] [features=smallcaps]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-Regular] [rm-anttr]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-Italic] [mi-anttri]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-Regular] [sy-anttrz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-Regular] [ex-anttr]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska-light] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-Light] [rm-anttl]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-LightItalic] [mi-anttli]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-Light] [sy-anttlz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-Light] [ex-anttl]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska-cond] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondRegular] [rm-anttcr]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondItalic] [mi-anttcri]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-CondRegular] [sy-anttcrz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-CondRegular] [ex-anttcr]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska-lightcond] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondLight] [rm-anttcl]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondLightItalic] [mi-anttcli]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-CondLight] [sy-anttclz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-CondLight] [ex-anttcl]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond]
+ \usemathcollection[default]
+ \loadmapfile[antt-rm.map]
+ \loadmapfile[antt-mi.map]
+ \loadmapfile[antt-sy.map]
+ \loadmapfile[antt-ex.map]
+\stoptypescript
+
+% Antykwa Poltawskiego (GUST)
+
+\starttypescript [serif] [antykwa-poltawskiego]
+ \definefontsynonym [AntykwaPoltawskiego-Regular] [antpr]
+ \definefontsynonym [AntykwaPoltawskiego-Bold] [antpb]
+ \definefontsynonym [AntykwaPoltawskiego-Italic] [antpri]
+ \definefontsynonym [AntykwaPoltawskiego-BoldItalic] [antpbi]
+\stoptypescript
+
+% Iwona (JMN)
+
+% maybe this will change in Iwona-Math-Letters and Iwona-Math-Letters-Italic
+
+% These names are a depressing mess. They have changed over time and are
+% still not consistent. I'd expect Bold-Regular and Bold-Italic.
+
+\starttypescript [sans] [iwona-light,iwona,iwona-medium,iwona-heavy,iwona-light-cond,iwona-cond,iwona-medium-cond,iwona-heavy-cond]
+
+ \definefontsynonym [Iwona-Regular] [file:Iwona-Regular] [features=default]
+ \definefontsynonym [Iwona-Italic] [file:Iwona-Italic] [features=default]
+ \definefontsynonym [Iwona-Bold] [file:Iwona-Bold] [features=default]
+ \definefontsynonym [Iwona-BoldItalic] [file:Iwona-BoldItalic] [features=default]
+ \definefontsynonym [Iwona-Light-Regular] [file:IwonaLight-Regular] [features=default]
+ \definefontsynonym [Iwona-Light-Italic] [file:IwonaLight-Italic] [features=default]
+ \definefontsynonym [Iwona-Medium-Regular] [file:IwonaMedium-Regular] [features=default]
+ \definefontsynonym [Iwona-Medium-Italic] [file:IwonaMedium-Italic] [features=default]
+ \definefontsynonym [Iwona-Heavy-Regular] [file:IwonaHeavy-Regular] [features=default]
+ \definefontsynonym [Iwona-Heavy-Italic] [file:IwonaHeavy-Italic] [features=default]
+
+ \definefontsynonym [Iwona-CapsRegular] [file:Iwona-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsItalic] [file:Iwona-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsBold] [file:Iwona-Bold] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsBoldItalic] [file:Iwona-BoldItalic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsLight] [file:IwonaLight-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsLight-Italic] [file:IwonaLight-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsMedium] [file:IwonaMedium-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsMedium-Italic] [file:IwonaMedium-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsHeavy] [file:IwonaHeavy-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsHeavy-Italic] [file:IwonaHeavy-Italic] [features=smallcaps]
+
+ \definefontsynonym [Iwona-CondRegular] [file:IwonaCond-Regular] [features=default]
+ \definefontsynonym [Iwona-CondItalic] [file:IwonaCond-Italic] [features=default]
+ \definefontsynonym [Iwona-CondBold] [file:IwonaCond-Bold] [features=default]
+ \definefontsynonym [Iwona-CondBoldItalic] [file:IwonaCond-BoldItalic] [features=default]
+ \definefontsynonym [Iwona-CondLight-Regular] [file:IwonaCondLight-Regular] [features=default]
+ \definefontsynonym [Iwona-CondLight-Italic] [file:IwonaCondLight-Italic] [features=default]
+ \definefontsynonym [Iwona-CondMedium-Regular] [file:IwonaCondMedium-Regular] [features=default]
+ \definefontsynonym [Iwona-CondMedium-Italic] [file:IwonaCondMedium-Italic] [features=default]
+ \definefontsynonym [Iwona-CondHeavy-Regular] [file:IwonaCondHeavy-Regular] [features=default]
+ \definefontsynonym [Iwona-CondHeavy-Italic] [file:IwonaCondHeavy-Italic] [features=default]
+
+ \definefontsynonym [Iwona-CapsCondRegular] [file:IwonaCond-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondItalic] [file:IwonaCond-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondBold] [file:IwonaCond-Bold] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondBoldItalic] [file:IwonaCond-BoldItalic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondLight-Regular] [file:IwonaCondLight-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondLight-Italic] [file:IwonaCondLight-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondMedium-Regular][file:IwonaCondMedium-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondMedium-Italic] [file:IwonaCondMedium-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondHeavy-Regular] [file:IwonaCondHeavy-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondHeavy-Italic] [file:IwonaCondHeavy-Italic] [features=smallcaps]
+
+\stoptypescript
+
+\starttypescript [math] [iwona] [default]
+ \definefontsynonym [Iwona-Math-Letters-Regular] [rm-iwonar]
+ \definefontsynonym [Iwona-Math-Letters-Italic] [mi-iwonari]
+ \definefontsynonym [Iwona-Math-Symbols-Regular] [sy-iwonarz]
+ \definefontsynonym [Iwona-Math-Extension-Regular] [ex-iwonar]
+\stoptypescript
+
+\starttypescript [math] [iwona-light] [default]
+ \definefontsynonym [Iwona-Math-Letters-Light-Regular] [rm-iwonal]
+ \definefontsynonym [Iwona-Math-Letters-Light-Italic] [mi-iwonali]
+ \definefontsynonym [Iwona-Math-Symbols-Light] [sy-iwonalz]
+ \definefontsynonym [Iwona-Math-Extension-Light] [ex-iwonal]
+\stoptypescript
+
+\starttypescript [math] [iwona-medium] [default]
+ \definefontsynonym [Iwona-Math-Letters-Medium-Regular][rm-iwonam]
+ \definefontsynonym [Iwona-Math-Letters-Medium-Italic] [mi-iwonami]
+ \definefontsynonym [Iwona-Math-Symbols-Medium] [sy-iwonamz]
+ \definefontsynonym [Iwona-Math-Extension-Medium] [ex-iwonam]
+\stoptypescript
+
+\starttypescript [math] [iwona-heavy] [default]
+ \definefontsynonym [Iwona-Math-Letters-Heavy-Regular] [rm-iwonah]
+ \definefontsynonym [Iwona-Math-Letters-Heavy-Italic] [mi-iwonahi]
+ \definefontsynonym [Iwona-Math-Symbols-Heavy] [sy-iwonahz]
+ \definefontsynonym [Iwona-Math-Extension-Heavy] [ex-iwonah]
+\stoptypescript
+
+\starttypescript [math] [iwona,iwona-light,iwona-medium,iwona-heavy] [default]
+ \usemathcollection[default]
+ \loadmapfile[iwona-rm.map]
+ \loadmapfile[iwona-mi.map]
+ \loadmapfile[iwona-sy.map]
+ \loadmapfile[iwona-ex.map]
+\stoptypescript
+
+% Kurier (JMN) / no open type fonts
+
+\starttypescript [sans] [kurier-light,kurier,kurier-medium]
+ \definefontsynonym[Kurier-Light] [kurierl]
+ \definefontsynonym[Kurier-Regular] [kurierr]
+ \definefontsynonym[Kurier-Medium] [kurierm]
+ \definefontsynonym[Kurier-Bold] [kurierb]
+ \definefontsynonym[Kurier-Heavy] [kurierh]
+ \definefontsynonym[Kurier-LightItalic] [kurierli]
+ \definefontsynonym[Kurier-Italic] [kurierri]
+ \definefontsynonym[Kurier-MediumItalic] [kuriermi]
+ \definefontsynonym[Kurier-BoldItalic] [kurierbi]
+ \definefontsynonym[Kurier-HeavyItalic] [kurierhi]
+\stoptypescript
+
+\starttypescript [math] [kurier] [default]
+ \definefontsynonym [Kurier-Math-Letters-Regular] [rm-kurierr]
+ \definefontsynonym [Kurier-Math-Letters-Italic] [mi-kurierri]
+ \definefontsynonym [Kurier-Math-Symbols-Regular] [sy-kurierrz]
+ \definefontsynonym [Kurier-Math-Extension-Regular] [ex-kurierr]
+\stoptypescript
+
+\starttypescript [math] [kurier-light] [default]
+ \definefontsynonym [Kurier-Math-Letters-Light-Regular] [rm-kurierl]
+ \definefontsynonym [Kurier-Math-Letters-Light-Italic] [mi-kurierli]
+ \definefontsynonym [Kurier-Math-Symbols-Light] [sy-kurierlz]
+ \definefontsynonym [Kurier-Math-Extension-Light] [ex-kurierl]
+\stoptypescript
+
+\starttypescript [math] [kurier-medium] [default]
+ \definefontsynonym [Kurier-Math-Letters-Medium-Regular] [rm-kurierm]
+ \definefontsynonym [Kurier-Math-Letters-Medium-Italic] [mi-kuriermi]
+ \definefontsynonym [Kurier-Math-Symbols-Medium-Regular] [sy-kuriermz]
+ \definefontsynonym [Kurier-Math-Extension-Medium] [ex-kurierm]
+\stoptypescript
+
+\starttypescript [math] [kurier,kurier-light,kurier-medium] [default]
+ \loadmapfile[kurier-rm.map]
+ \loadmapfile[kurier-mi.map]
+ \loadmapfile[kurier-sy.map]
+ \loadmapfile[kurier-ex.map]
+\stoptypescript
+
+\starttypescript [iwona,iwona-light,iwona-medium,iwona-heavy]
+ \definetypeface[\typescriptone][ss][sans] [\typescriptone] [default]
+ \definetypeface[\typescriptone][rm][serif][modern] [default]
+ \definetypeface[\typescriptone][tt][mono] [modern] [default][rscale=1.05]
+ \definetypeface[\typescriptone][mm][math] [\typescriptone] [default][text=ss]
+ \quittypescriptscanning
+\stoptypescript
+
+% Whatever else we need:
+
+\starttypescript
+ \definefontsynonym [ZapfDingbats] [uzdr]
+ \definefontsynonym [RalfSmithFormalScript] [rsfs10]
+ \definefontsynonym [MartinVogel] [fmvr8x]
+\stoptypescript
+
+% Temp here
+
+\starttypescript [serif] [charter]
+ \definefontsynonym [Charter-Roman] [name:CharterBT-Roman] % or: [bchr8a]
+ \definefontsynonym [Charter-Italic] [name:CharterBT-Italic] % or: [bchri8a]
+ \definefontsynonym [Charter-Bold] [name:CharterBT-Bold] % or: [bchb8a]
+ \definefontsynonym [Charter-BoldItalic] [name:CharterBT-BoldItalic] % or: [bchbi8a]
+ \definefontsynonym [Charter-Slanted] [name:CharterBT-Italic] % or: [bchri8a]
+ \definefontsynonym [Charter-BoldSlanted] [name:CharterBT-BoldItalic] % or: [bchbi8a]
+ \definefontsynonym [Charter-Roman-Caps] [Charter-Roman] % not present
+\stoptypescript
+
+\stoptypescriptcollection
+
+\endinput
diff --git a/tex/context/base/type-otf.mkiv b/tex/context/base/type-otf.mkiv
new file mode 100644
index 000000000..09ec22856
--- /dev/null
+++ b/tex/context/base/type-otf.mkiv
@@ -0,0 +1,628 @@
+%D \module
+%D [ file=type-otf,
+%D version=2007.07.30,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Opentype Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 Actually, \LUATEX\ does not need all these definitions since it can
+%D consult its database. However, here we use the names that we used
+%D in good old \TEX, and these may differ a bit. Here we also see
+%D some oldstyle definitions which normally are done with features.
+
+% if a fontname equals the filename, then use
+%
+% \setupfontsynonym [LMRoman10-DemiOblique] [features=default] % file is lowercase, so fails
+% \definefontsynonym [LMRoman10-DemiOblique] [name:LMRoman10-DemiOblique] [features=default]
+% \definefontsynonym [LMRoman10-DemiOblique] [lmroman10-demioblique] [features=default]
+
+\starttypescriptcollection[opentype]
+
+%D The names have changed (again) ... but I will not change the symbolic names
+%D any more. Filename changes will be catched in luatex (fallbacks) but not in
+%D other tex's.
+
+\starttypescript [serif] [modern,latin-modern]
+ \definefontsynonym [LMRoman5-Regular] [file:lmroman5-regular] [features=default]
+ \definefontsynonym [LMRoman6-Regular] [file:lmroman6-regular] [features=default]
+ \definefontsynonym [LMRoman7-Regular] [file:lmroman7-regular] [features=default]
+ \definefontsynonym [LMRoman8-Regular] [file:lmroman8-regular] [features=default]
+ \definefontsynonym [LMRoman9-Regular] [file:lmroman9-regular] [features=default]
+ \definefontsynonym [LMRoman10-Regular] [file:lmroman10-regular] [features=default]
+ \definefontsynonym [LMRoman12-Regular] [file:lmroman12-regular] [features=default]
+ \definefontsynonym [LMRoman17-Regular] [file:lmroman17-regular] [features=default]
+ \definefontsynonym [LMRoman5-Bold] [file:lmroman5-bold] [features=default]
+ \definefontsynonym [LMRoman6-Bold] [file:lmroman6-bold] [features=default]
+ \definefontsynonym [LMRoman7-Bold] [file:lmroman7-bold] [features=default]
+ \definefontsynonym [LMRoman8-Bold] [file:lmroman8-bold] [features=default]
+ \definefontsynonym [LMRoman9-Bold] [file:lmroman9-bold] [features=default]
+ \definefontsynonym [LMRoman10-Bold] [file:lmroman10-bold] [features=default]
+ \definefontsynonym [LMRoman12-Bold] [file:lmroman12-bold] [features=default]
+ \definefontsynonym [LMRoman7-Italic] [file:lmroman7-italic] [features=default]
+ \definefontsynonym [LMRoman8-Italic] [file:lmroman8-italic] [features=default]
+ \definefontsynonym [LMRoman9-Italic] [file:lmroman9-italic] [features=default]
+ \definefontsynonym [LMRoman10-Italic] [file:lmroman10-italic] [features=default]
+ \definefontsynonym [LMRoman12-Italic] [file:lmroman12-italic] [features=default]
+ \definefontsynonym [LMRoman10-BoldItalic] [file:lmroman10-bolditalic] [features=default]
+ \definefontsynonym [LMRoman8-Oblique] [file:lmromanslant8-regular] [features=default]
+ \definefontsynonym [LMRoman9-Oblique] [file:lmromanslant9-regular] [features=default]
+ \definefontsynonym [LMRoman10-Oblique] [file:lmromanslant10-regular][features=default]
+ \definefontsynonym [LMRoman12-Oblique] [file:lmromanslant12-regular][features=default]
+ \definefontsynonym [LMRoman17-Oblique] [file:lmromanslant17-regular][features=default]
+ \definefontsynonym [LMRoman10-BoldOblique] [file:lmromanslant10-bold] [features=default]
+ \definefontsynonym [LMRoman10-Demi] [file:lmromandemi10-regular] [features=default]
+ \definefontsynonym [LMRoman10-DemiOblique] [file:lmromandemi10-oblique] [features=default]
+ \definefontsynonym [LMRoman10-CapsRegular] [file:lmromancaps10-regular] [features=default] % features=smallcaps?
+ \definefontsynonym [LMRoman10-CapsOblique] [file:lmromancaps10-oblique] [features=default]
+
+ \definefontsynonym [LMRoman10-Dunhill] [file:lmromandunh10-regular] [features=default]
+ \definefontsynonym [LMRoman10-DunhillOblique] [file:lmromandunh10-oblique] [features=default]
+ \definefontsynonym [LMRoman10-Unslanted] [file:lmromanunsl10-regular] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [modern,latin-modern]
+ \definefontsynonym [LMSans8-Regular] [file:lmsans8-regular] [features=default]
+ \definefontsynonym [LMSans9-Regular] [file:lmsans9-regular] [features=default]
+ \definefontsynonym [LMSans10-Regular] [file:lmsans10-regular] [features=default]
+ \definefontsynonym [LMSans12-Regular] [file:lmsans12-regular] [features=default]
+ \definefontsynonym [LMSans17-Regular] [file:lmsans17-regular] [features=default]
+ \definefontsynonym [LMSans10-Bold] [file:lmsans10-bold] [features=default]
+ \definefontsynonym [LMSans8-Oblique] [file:lmsans8-oblique] [features=default]
+ \definefontsynonym [LMSans9-Oblique] [file:lmsans9-oblique] [features=default]
+ \definefontsynonym [LMSans10-Oblique] [file:lmsans10-oblique] [features=default]
+ \definefontsynonym [LMSans12-Oblique] [file:lmsans12-oblique] [features=default]
+ \definefontsynonym [LMSans17-Oblique] [file:lmsans17-oblique] [features=default]
+ \definefontsynonym [LMSans10-BoldOblique] [file:lmsans10-boldoblique] [features=default]
+
+ \definefontsynonym [LMSans10-DemiCondensed] [file:lmsansdemicond10-regular] [features=default]
+ \definefontsynonym [LMSans10-DemiCondensedOblique] [file:lmsansdemicond10-oblique] [features=default]
+
+ \definefontsynonym [LMSansQuotation8-Regular] [file:lmsansquot8-regular] [features=default]
+ \definefontsynonym [LMSansQuotation8-Bold] [file:lmsansquot8-bold] [features=default]
+ \definefontsynonym [LMSansQuotation8-Oblique] [file:lmsansquot8-oblique] [features=default]
+ \definefontsynonym [LMSansQuotation8-BoldOblique] [file:lmsansquot8-boldoblique] [features=default]
+\stoptypescript
+
+\starttypescript [mono] [modern,latin-modern,modern-vari,latin-modern-vari,modern-cond,latin-modern-cond]
+ \definefontsynonym [LMTypewriter8-Regular] [file:lmmono8-regular] [features=none]
+ \definefontsynonym [LMTypewriter9-Regular] [file:lmmono9-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-Regular] [file:lmmono10-regular] [features=none]
+ \definefontsynonym [LMTypewriter12-Regular] [file:lmmono12-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-Italic] [file:lmmono10-italic] [features=none]
+ \definefontsynonym [LMTypewriter10-Oblique] [file:lmmonoslant10-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-CapsRegular] [file:lmmonocaps10-regular] [features=none] % features=smallcaps?
+ \definefontsynonym [LMTypewriter10-CapsOblique] [file:lmmonocaps10-oblique] [features=none]
+
+ \definefontsynonym [LMTypewriter10-Light] [file:lmmonolt10-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-LightOblique] [file:lmmonolt10-oblique] [features=none]
+ \definefontsynonym [LMTypewriter10-LightCondensed] [file:lmmonoltcond10-regular] [features=none]
+ \definefontsynonym [LMTypewriter10-LightCondensedOblique] [file:lmmonoltcond10-oblique] [features=none]
+
+ \definefontsynonym [LMTypewriter10-Dark] [file:lmmonolt10-bold] [features=none]
+ \definefontsynonym [LMTypewriter10-DarkOblique] [file:lmmonolt10-boldoblique] [features=none]
+
+ \definefontsynonym [LMTypewriterVarWd10-Regular] [file:lmmonoproplt10-regular] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-Oblique] [file:lmmonoproplt10-oblique] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-Light] [file:lmmonoprop10-regular] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-LightOblique] [file:lmmonoprop10-oblique] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-Dark] [file:lmmonoproplt10-bold] [features=default]
+ \definefontsynonym [LMTypewriterVarWd10-DarkOblique] [file:lmmonoproplt10-boldoblique] [features=default]
+\stoptypescript
+
+% \starttypescript [math] [modern,latin-modern]
+% \definefontsynonym [LMMathRoman5-Regular] [rm-lmr5]
+% \definefontsynonym [LMMathRoman6-Regular] [rm-lmr6]
+% \definefontsynonym [LMMathRoman7-Regular] [rm-lmr7]
+% \definefontsynonym [LMMathRoman8-Regular] [rm-lmr8]
+% \definefontsynonym [LMMathRoman9-Regular] [rm-lmr9]
+% \definefontsynonym [LMMathRoman10-Regular] [rm-lmr10]
+% \definefontsynonym [LMMathRoman12-Regular] [rm-lmr12]
+% \definefontsynonym [LMMathRoman17-Regular] [rm-lmr17]
+% \definefontsynonym [LMMathRoman5-Bold] [rm-lmbx5]
+% \definefontsynonym [LMMathRoman6-Bold] [rm-lmbx6]
+% \definefontsynonym [LMMathRoman7-Bold] [rm-lmbx7]
+% \definefontsynonym [LMMathRoman8-Bold] [rm-lmbx8]
+% \definefontsynonym [LMMathRoman9-Bold] [rm-lmbx9]
+% \definefontsynonym [LMMathRoman10-Bold] [rm-lmbx10]
+% \definefontsynonym [LMMathRoman12-Bold] [rm-lmbx12]
+% \definefontsynonym [LMMathSymbols5-BoldItalic] [lmbsy5]
+% \definefontsynonym [LMMathSymbols7-BoldItalic] [lmbsy7]
+% \definefontsynonym [LMMathSymbols10-BoldItalic][lmbsy10]
+% \definefontsynonym [LMMathSymbols5-Italic] [lmsy5]
+% \definefontsynonym [LMMathSymbols6-Italic] [lmsy6]
+% \definefontsynonym [LMMathSymbols7-Italic] [lmsy7]
+% \definefontsynonym [LMMathSymbols8-Italic] [lmsy8]
+% \definefontsynonym [LMMathSymbols9-Italic] [lmsy9]
+% \definefontsynonym [LMMathSymbols10-Italic] [lmsy10]
+% \definefontsynonym [LMMathExtension10-Regular] [lmex10]
+% \definefontsynonym [LMMathItalic5-Italic] [lmmi5]
+% \definefontsynonym [LMMathItalic6-Italic] [lmmi6]
+% \definefontsynonym [LMMathItalic7-Italic] [lmmi7]
+% \definefontsynonym [LMMathItalic8-Italic] [lmmi8]
+% \definefontsynonym [LMMathItalic9-Italic] [lmmi9]
+% \definefontsynonym [LMMathItalic10-Italic] [lmmi10]
+% \definefontsynonym [LMMathItalic12-Italic] [lmmi12]
+% \definefontsynonym [LMMathItalic5-BoldItalic] [lmmib5]
+% \definefontsynonym [LMMathItalic7-BoldItalic] [lmmib7]
+% \definefontsynonym [LMMathItalic10-BoldItalic] [lmmib10]
+% \loadmapfile[lm-math.map]
+% \loadmapfile[lm-rm.map]
+% \stoptypescript
+
+% \starttypescript [math] [modern,computer-modern,latin-modern]
+% \definefontsynonym [ComputerModernMath-Roman] [rm-lmr10]
+% \definefontsynonym [ComputerModernMath-Extension] [lmex10]
+% \definefontsynonym [ComputerModernMath-Italic] [lmmi10]
+% \definefontsynonym [ComputerModernMath-Symbol] [lmsy10]
+% \stoptypescript
+
+% \starttypescript [boldmath,bfmath] [modern,computer-modern,latin-modern]
+% \definefontsynonym [ComputerModernMath-Roman-Bold] [rm-lmb10]
+% \definefontsynonym [ComputerModernMath-Extension] [lmex10]
+% \definefontsynonym [ComputerModernMath-Italic-Bold] [lmmib10]
+% \definefontsynonym [ComputerModernMath-Symbol-Bold] [lmbsy10]
+% \stoptypescript
+
+\starttypescript [math] [modern,latin-modern,computer-modern]
+ \definefontsynonym[LMMathRoman5-Regular] [LMMath5-Regular@lmroman5-math]
+ \definefontsynonym[LMMathRoman6-Regular] [LMMath6-Regular@lmroman6-math]
+ \definefontsynonym[LMMathRoman7-Regular] [LMMath7-Regular@lmroman7-math]
+ \definefontsynonym[LMMathRoman8-Regular] [LMMath8-Regular@lmroman8-math]
+ \definefontsynonym[LMMathRoman9-Regular] [LMMath9-Regular@lmroman9-math]
+ \definefontsynonym[LMMathRoman10-Regular][LMMath10-Regular@lmroman10-math]
+ \definefontsynonym[LMMathRoman12-Regular][LMMath12-Regular@lmroman12-math]
+ \definefontsynonym[LMMathRoman17-Regular][LMMath17-Regular@lmroman17-math]
+
+% \definefontsynonym[LMMathRoman-Regular] [LMMath10-Regular@lmroman10-math]
+
+ \definefontsynonym[MathRoman] [LMMath10-Regular@lmroman10-math]
+
+ \definefontsynonym[xcmr12][LMMath12-Regular@lmroman12-math]
+ \definefontsynonym[xcmr10][LMMath10-Regular@lmroman10-math]
+ \definefontsynonym[xcmr9] [LMMath9-Regular@lmroman9-math]
+ \definefontsynonym[xcmr8] [LMMath8-Regular@lmroman8-math]
+ \definefontsynonym[xcmr7] [LMMath7-Regular@lmroman7-math]
+ \definefontsynonym[xcmr6] [LMMath6-Regular@lmroman6-math]
+ \definefontsynonym[xcmr5] [LMMath5-Regular@lmroman5-math]
+
+ \loadmapfile[lm-math.map]
+ \loadmapfile[lm-rm.map]
+\stoptypescript
+
+% Euler (AMS)
+
+\starttypescript [math] [euler]
+ \definefontsynonym [Euler-Roman] [zeurm10]
+ \definefontsynonym [Euler-Extension] [zeuex10]
+ \definefontsynonym [Euler-Symbol] [zeusm10]
+ \definefontsynonym [Euler-Fraktur] [eufm10]
+
+ \loadmapfile[original-ams-euler.map]
+\stoptypescript
+
+\starttypescript [boldmath,bfmath] [euler]
+ \definefontsynonym [Euler-Roman-Bold] [zeurb10]
+ \definefontsynonym [Euler-Extension] [zeuex10]
+ \definefontsynonym [Euler-Symbol-Bold] [zeusb10]
+ \definefontsynonym [Euler-Fraktur-Bold] [eufb10]
+
+ \loadmapfile[original-ams-euler.map]
+\stoptypescript
+
+% AMS (AMS)
+
+\starttypescript [math] [modern,computer-modern,latin-modern,ams]
+ \definefontsynonym [AMS-SymbolA] [msam10]
+ \definefontsynonym [AMS-SymbolB] [msbm10]
+\stoptypescript
+
+% TeXGyre
+
+\definetypescriptprefix [f:pagella] [pagella] \definetypescriptprefix [f:palatino] [pagella]
+\definetypescriptprefix [f:termes] [termes] \definetypescriptprefix [f:times] [termes]
+\definetypescriptprefix [f:heros] [heros] \definetypescriptprefix [f:helvetica] [heros]
+\definetypescriptprefix [f:bonum] [bonum] \definetypescriptprefix [f:bookman] [bonum]
+\definetypescriptprefix [f:schola] [schola] \definetypescriptprefix [f:schoolbook] [schola]
+\definetypescriptprefix [f:adventor][adventor] %definetypescriptprefix [f:adventor] [adventor]
+\definetypescriptprefix [f:cursor] [cursor] \definetypescriptprefix [f:courier] [cursor]
+\definetypescriptprefix [f:chorus] [chorus] \definetypescriptprefix [f:chancery] [chorus] % not the full set
+
+% name definitions & prefixes
+% \starttypescript [serif,sans,mono] [adventor,bonum,cursor,heros,pagella,palatino,schola,termes]
+% \starttypescript [serif] [pagella,palatino,termes,times,bonum,bookman,schola,schoolbook] [name]
+
+\starttypescript [serif,sans,mono] [adventor,bonum,bookman,cursor,courier,heros,helvetica,pagella,palatino,schola,schoolbook,termes,times]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [features=default]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Caps] [file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [features=smallcaps]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [features=smallcaps]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [features=smallcaps]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [features=smallcaps]
+\stoptypescript
+
+\starttypescript [serif,calligraphy] [chorus,chancery]
+ \definefontsynonym [TeXGyreChorus-MediumItalic] [file:texgyrechorus-mediumitalic] [features=default]
+\stoptypescript
+
+% Times Math (tx)
+
+% \starttypescript [math] [times] [all]
+% \definefontsynonym [Times-Roman-Upright] [txr]
+% \definefontsynonym [Times-Roman-Italic] [txi]
+% \definefontsynonym [Times-Roman-Slanted] [txsl]
+% \definefontsynonym [Times-Roman-Caps] [txsc]
+% \definefontsynonym [Times-Companion-Upright] [tcxr]
+% \definefontsynonym [Times-Companion-Italic] [tcxi]
+% \definefontsynonym [Times-Companion-Slanted] [tcxsl]
+% \definefontsynonym [Times-Math-Italic] [txmi]
+% \definefontsynonym [Times-Math-Symbols] [txsy]
+% \definefontsynonym [Times-Math-Extension] [txex]
+% \definefontsynonym [Times-Math-SymbolsA] [txsya]
+% \definefontsynonym [Times-Math-SymbolsB] [txsyb]
+% \definefontsynonym [Times-Math-SymbolsC] [txsyc]
+% \definefontsynonym [Times-Math-Italic-A] [txmia]
+% \definefontsynonym [Times-Math-Extension-A] [txexa]
+% \loadmapfile[original-youngryu-tx.map]
+% \usemathcollection[default]
+% \stoptypescript
+
+\starttypescript [math][times][all]
+ \definefontsynonym[MathRoman][txmath@tx-math]
+ \loadmapfile[original-youngryu-tx.map]
+\stoptypescript
+
+% Palatino Math (px)
+
+% \starttypescript [math] [palatino] [all]
+% \definefontsynonym [Palatino-Roman-Upright] [pxr]
+% \definefontsynonym [Palatino-Roman-Italic] [pxi]
+% \definefontsynonym [Palatino-Roman-Slanted] [pxsl]
+% \definefontsynonym [Palatino-Roman-Caps] [pxsc]
+% \definefontsynonym [Palatino-Companion-Upright] [pcxr]
+% \definefontsynonym [Palatino-Companion-Italic] [pcxi]
+% \definefontsynonym [Palatino-Companion-Slanted] [pcxsl]
+% \definefontsynonym [Palatino-Math-Italic] [pxmi]
+% \definefontsynonym [Palatino-Math-Symbols] [pxsy]
+% \definefontsynonym [Palatino-Math-Extension] [pxex]
+% \definefontsynonym [Palatino-Math-SymbolsA] [pxsya]
+% \definefontsynonym [Palatino-Math-SymbolsB] [pxsyb]
+% \definefontsynonym [Palatino-Math-SymbolsC] [pxsyc]
+% \definefontsynonym [Palatino-Math-Italic-A] [pxmia]
+% \definefontsynonym [Palatino-Math-Extension-A] [pxexa]
+% \loadmapfile[original-youngryu-px.map]
+% \usemathcollection[default]
+% \stoptypescript
+
+\starttypescript [math][palatino][all]
+ \definefontsynonym[MathRoman][pxmath@px-math]
+ \loadmapfile[original-youngryu-px.map]
+\stoptypescript
+
+% Antykwa Torunska (GUST)
+
+\starttypescript [serif] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond]
+ \definefontsynonym [AntykwaTorunska-Regular] [file:AntykwaTorunska-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-Italic] [file:AntykwaTorunska-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-Bold] [file:AntykwaTorunska-Bold] [features=default]
+ \definefontsynonym [AntykwaTorunska-BoldItalic] [file:AntykwaTorunska-BoldItalic] [features=default]
+ \definefontsynonym [AntykwaTorunska-Light] [file:AntykwaTorunskaLight-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-LightItalic] [file:AntykwaTorunskaLight-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-Medium] [file:AntykwaTorunskaMed-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-MedItalic] [file:AntykwaTorunskaMed-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondRegular] [file:AntykwaTorunskaCond-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondItalic] [file:AntykwaTorunskaCond-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondBold] [file:AntykwaTorunskaCond-Bold] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondBoldItalic] [file:AntykwaTorunskaCond-BoldItalic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondLight] [file:AntykwaTorunskaCondLight-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondLightItalic] [file:AntykwaTorunskaCondLight-Italic] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondMedium] [file:AntykwaTorunskaCondMed-Regular] [features=default]
+ \definefontsynonym [AntykwaTorunska-CondMedItalic] [file:AntykwaTorunskaCondMed-Italic] [features=default]
+
+ \definefontsynonym [AntykwaTorunska-Cap] [file:AntykwaTorunska-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-ItalicCap] [file:AntykwaTorunska-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-BoldCap] [file:AntykwaTorunska-Bold] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-BoldItalicCap] [file:AntykwaTorunska-BoldItalic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-LightCap] [file:AntykwaTorunskaLight-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-LightItalicCap] [file:AntykwaTorunskaLight-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-MediumCap] [file:AntykwaTorunskaMed-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-MedItalicCap] [file:AntykwaTorunskaMed-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondCap] [file:AntykwaTorunskaCond-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondItalicCap] [file:AntykwaTorunskaCond-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondBoldCap] [file:AntykwaTorunskaCond-Bold] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondBoldItalicCap] [file:AntykwaTorunskaCond-BoldItalic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondLightCap] [file:AntykwaTorunskaCondLight-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondLightItalicCap][file:AntykwaTorunskaCondLight-Italic] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondMediumCap] [file:AntykwaTorunskaCondMed-Regular] [features=smallcaps]
+ \definefontsynonym [AntykwaTorunska-CondMedItalicCap] [file:AntykwaTorunskaCondMed-Italic] [features=smallcaps]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-Regular] [rm-anttr]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-Italic] [mi-anttri]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-Regular] [sy-anttrz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-Regular] [ex-anttr]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska-light] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-Light] [rm-anttl]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-LightItalic] [mi-anttli]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-Light] [sy-anttlz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-Light] [ex-anttl]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska-cond] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondRegular] [rm-anttcr]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondItalic] [mi-anttcri]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-CondRegular] [sy-anttcrz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-CondRegular] [ex-anttcr]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska-lightcond] [default]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondLight] [rm-anttcl]
+ \definefontsynonym [AntykwaTorunska-Math-Letters-CondLightItalic] [mi-anttcli]
+ \definefontsynonym [AntykwaTorunska-Math-Symbols-CondLight] [sy-anttclz]
+ \definefontsynonym [AntykwaTorunska-Math-Extension-CondLight] [ex-anttcl]
+\stoptypescript
+
+\starttypescript [math] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond]
+ \usemathcollection[default]
+ \loadmapfile[antt-rm.map]
+ \loadmapfile[antt-mi.map]
+ \loadmapfile[antt-sy.map]
+ \loadmapfile[antt-ex.map]
+\stoptypescript
+
+% Antykwa Poltawskiego (GUST)
+
+\starttypescript [serif] [antykwa-poltawskiego]
+ \definefontsynonym [AntykwaPoltawskiego-Regular] [antpr]
+ \definefontsynonym [AntykwaPoltawskiego-Bold] [antpb]
+ \definefontsynonym [AntykwaPoltawskiego-Italic] [antpri]
+ \definefontsynonym [AntykwaPoltawskiego-BoldItalic] [antpbi]
+\stoptypescript
+
+% Iwona (JMN)
+
+% maybe this will change in Iwona-Math-Letters and Iwona-Math-Letters-Italic
+
+% These names are a depressing mess. They have changed over time and are
+% still not consistent. I'd expect Bold-Regular and Bold-Italic.
+
+\starttypescript [sans] [iwona-light,iwona,iwona-medium,iwona-heavy,iwona-light-cond,iwona-cond,iwona-medium-cond,iwona-heavy-cond]
+
+ \definefontsynonym [Iwona-Regular] [file:Iwona-Regular] [features=default]
+ \definefontsynonym [Iwona-Italic] [file:Iwona-Italic] [features=default]
+ \definefontsynonym [Iwona-Bold] [file:Iwona-Bold] [features=default]
+ \definefontsynonym [Iwona-BoldItalic] [file:Iwona-BoldItalic] [features=default]
+ \definefontsynonym [Iwona-Light-Regular] [file:IwonaLight-Regular] [features=default]
+ \definefontsynonym [Iwona-Light-Italic] [file:IwonaLight-Italic] [features=default]
+ \definefontsynonym [Iwona-Medium-Regular] [file:IwonaMedium-Regular] [features=default]
+ \definefontsynonym [Iwona-Medium-Italic] [file:IwonaMedium-Italic] [features=default]
+ \definefontsynonym [Iwona-Heavy-Regular] [file:IwonaHeavy-Regular] [features=default]
+ \definefontsynonym [Iwona-Heavy-Italic] [file:IwonaHeavy-Italic] [features=default]
+
+ \definefontsynonym [Iwona-CapsRegular] [file:Iwona-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsItalic] [file:Iwona-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsBold] [file:Iwona-Bold] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsBoldItalic] [file:Iwona-BoldItalic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsLight] [file:IwonaLight-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsLight-Italic] [file:IwonaLight-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsMedium] [file:IwonaMedium-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsMedium-Italic] [file:IwonaMedium-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsHeavy] [file:IwonaHeavy-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsHeavy-Italic] [file:IwonaHeavy-Italic] [features=smallcaps]
+
+ \definefontsynonym [Iwona-CondRegular] [file:IwonaCond-Regular] [features=default]
+ \definefontsynonym [Iwona-CondItalic] [file:IwonaCond-Italic] [features=default]
+ \definefontsynonym [Iwona-CondBold] [file:IwonaCond-Bold] [features=default]
+ \definefontsynonym [Iwona-CondBoldItalic] [file:IwonaCond-BoldItalic] [features=default]
+ \definefontsynonym [Iwona-CondLight-Regular] [file:IwonaCondLight-Regular] [features=default]
+ \definefontsynonym [Iwona-CondLight-Italic] [file:IwonaCondLight-Italic] [features=default]
+ \definefontsynonym [Iwona-CondMedium-Regular] [file:IwonaCondMedium-Regular] [features=default]
+ \definefontsynonym [Iwona-CondMedium-Italic] [file:IwonaCondMedium-Italic] [features=default]
+ \definefontsynonym [Iwona-CondHeavy-Regular] [file:IwonaCondHeavy-Regular] [features=default]
+ \definefontsynonym [Iwona-CondHeavy-Italic] [file:IwonaCondHeavy-Italic] [features=default]
+
+ \definefontsynonym [Iwona-CapsCondRegular] [file:IwonaCond-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondItalic] [file:IwonaCond-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondBold] [file:IwonaCond-Bold] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondBoldItalic] [file:IwonaCond-BoldItalic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondLight-Regular] [file:IwonaCondLight-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondLight-Italic] [file:IwonaCondLight-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondMedium-Regular][file:IwonaCondMedium-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondMedium-Italic] [file:IwonaCondMedium-Italic] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondHeavy-Regular] [file:IwonaCondHeavy-Regular] [features=smallcaps]
+ \definefontsynonym [Iwona-CapsCondHeavy-Italic] [file:IwonaCondHeavy-Italic] [features=smallcaps]
+
+\stoptypescript
+
+% \starttypescript [math] [iwona] [default]
+% \definefontsynonym [Iwona-Math-Letters-Regular] [rm-iwonar]
+% \definefontsynonym [Iwona-Math-Letters-Italic] [mi-iwonari]
+% \definefontsynonym [Iwona-Math-Symbols-Regular] [sy-iwonarz]
+% \definefontsynonym [Iwona-Math-Extension-Regular] [ex-iwonar]
+% \stoptypescript
+
+% \starttypescript [math] [iwona-light] [default]
+% \definefontsynonym [Iwona-Math-Letters-Light-Regular] [rm-iwonal]
+% \definefontsynonym [Iwona-Math-Letters-Light-Italic] [mi-iwonali]
+% \definefontsynonym [Iwona-Math-Symbols-Light] [sy-iwonalz]
+% \definefontsynonym [Iwona-Math-Extension-Light] [ex-iwonal]
+% \stoptypescript
+
+% \starttypescript [math] [iwona-medium] [default]
+% \definefontsynonym [Iwona-Math-Letters-Medium-Regular][rm-iwonam]
+% \definefontsynonym [Iwona-Math-Letters-Medium-Italic] [mi-iwonami]
+% \definefontsynonym [Iwona-Math-Symbols-Medium] [sy-iwonamz]
+% \definefontsynonym [Iwona-Math-Extension-Medium] [ex-iwonam]
+% \stoptypescript
+
+% \starttypescript [math] [iwona-heavy] [default]
+% \definefontsynonym [Iwona-Math-Letters-Heavy-Regular] [rm-iwonah]
+% \definefontsynonym [Iwona-Math-Letters-Heavy-Italic] [mi-iwonahi]
+% \definefontsynonym [Iwona-Math-Symbols-Heavy] [sy-iwonahz]
+% \definefontsynonym [Iwona-Math-Extension-Heavy] [ex-iwonah]
+% \stoptypescript
+
+% [all] is redundant
+
+\starttypescript [math][iwona][all]
+ \definefontsynonym[MathRoman][iwonamath@iwona-math]
+\stoptypescript
+\starttypescript [math][iwona-light][all]
+ \definefontsynonym[MathRoman][iwonalightmath@iwona-light-math]
+\stoptypescript
+\starttypescript [math][iwona-medium][all]
+ \definefontsynonym[MathRoman][iwonamediummath@iwona-medium-math]
+\stoptypescript
+\starttypescript [math][iwona-heavy][all]
+ \definefontsynonym[MathRoman][iwonaheavymath@iwona-heavy-math]
+\stoptypescript
+
+\starttypescript [math] [iwona,iwona-light,iwona-medium,iwona-heavy] [all]
+ \loadmapfile[iwona-rm.map]
+ \loadmapfile[iwona-mi.map]
+ \loadmapfile[iwona-sy.map]
+ \loadmapfile[iwona-ex.map]
+\stoptypescript
+
+% Kurier (JMN) / no open type fonts
+
+\starttypescript [sans] [kurier-light,kurier,kurier-medium]
+ \definefontsynonym[Kurier-Light] [kurierl]
+ \definefontsynonym[Kurier-Regular] [kurierr]
+ \definefontsynonym[Kurier-Medium] [kurierm]
+ \definefontsynonym[Kurier-Bold] [kurierb]
+ \definefontsynonym[Kurier-Heavy] [kurierh]
+ \definefontsynonym[Kurier-LightItalic] [kurierli]
+ \definefontsynonym[Kurier-Italic] [kurierri]
+ \definefontsynonym[Kurier-MediumItalic] [kuriermi]
+ \definefontsynonym[Kurier-BoldItalic] [kurierbi]
+ \definefontsynonym[Kurier-HeavyItalic] [kurierhi]
+\stoptypescript
+
+\starttypescript [math] [kurier] [default]
+ \definefontsynonym [Kurier-Math-Letters-Regular] [rm-kurierr]
+ \definefontsynonym [Kurier-Math-Letters-Italic] [mi-kurierri]
+ \definefontsynonym [Kurier-Math-Symbols-Regular] [sy-kurierrz]
+ \definefontsynonym [Kurier-Math-Extension-Regular] [ex-kurierr]
+\stoptypescript
+
+\starttypescript [math] [kurier-light] [default]
+ \definefontsynonym [Kurier-Math-Letters-Light-Regular] [rm-kurierl]
+ \definefontsynonym [Kurier-Math-Letters-Light-Italic] [mi-kurierli]
+ \definefontsynonym [Kurier-Math-Symbols-Light] [sy-kurierlz]
+ \definefontsynonym [Kurier-Math-Extension-Light] [ex-kurierl]
+\stoptypescript
+
+\starttypescript [math] [kurier-medium] [default]
+ \definefontsynonym [Kurier-Math-Letters-Medium-Regular] [rm-kurierm]
+ \definefontsynonym [Kurier-Math-Letters-Medium-Italic] [mi-kuriermi]
+ \definefontsynonym [Kurier-Math-Symbols-Medium-Regular] [sy-kuriermz]
+ \definefontsynonym [Kurier-Math-Extension-Medium] [ex-kurierm]
+\stoptypescript
+
+\starttypescript [math] [kurier,kurier-light,kurier-medium] [default]
+ \loadmapfile[kurier-rm.map]
+ \loadmapfile[kurier-mi.map]
+ \loadmapfile[kurier-sy.map]
+ \loadmapfile[kurier-ex.map]
+\stoptypescript
+
+\starttypescript [iwona,iwona-light,iwona-medium,iwona-heavy]
+ \definetypeface[\typescriptone][ss][sans] [\typescriptone] [default]
+ \definetypeface[\typescriptone][rm][serif][modern] [default]
+ \definetypeface[\typescriptone][tt][mono] [modern] [default][rscale=1.05]
+ \definetypeface[\typescriptone][mm][math] [\typescriptone] [default][text=ss]
+ \quittypescriptscanning
+\stoptypescript
+
+% Whatever else we need:
+
+\starttypescript
+ \definefontsynonym [ZapfDingbats] [uzdr]
+ \definefontsynonym [RalfSmithFormalScript] [rsfs10]
+ \definefontsynonym [MartinVogel] [fmvr8x]
+\stoptypescript
+
+% Temp here
+
+\starttypescript [serif] [charter]
+ \definefontsynonym [Charter-Roman] [name:CharterBT-Roman] % or: [bchr8a]
+ \definefontsynonym [Charter-Italic] [name:CharterBT-Italic] % or: [bchri8a]
+ \definefontsynonym [Charter-Bold] [name:CharterBT-Bold] % or: [bchb8a]
+ \definefontsynonym [Charter-BoldItalic] [name:CharterBT-BoldItalic] % or: [bchbi8a]
+ \definefontsynonym [Charter-Slanted] [name:CharterBT-Italic] % or: [bchri8a]
+ \definefontsynonym [Charter-BoldSlanted] [name:CharterBT-BoldItalic] % or: [bchbi8a]
+ \definefontsynonym [Charter-Roman-Caps] [Charter-Roman] % not present
+\stoptypescript
+
+% new
+
+% cambria.ttc cambriab.ttf cambriai.ttf cambriaz.ttf
+
+\starttypescript [math] [cambria] [name]
+ \definefontsynonym [MathRoman] [name:cambriamath] [features=math\mathsizesuffix]
+\stoptypescript
+\starttypescript [math] [cambria-x] [name]
+ \definefontsynonym [MathRoman] [name:cambriamath] [features=math]
+\stoptypescript
+\starttypescript [math] [cambria-y] [name]
+ \definefontsynonym [MathRoman] [name:cambriamath] [features=math-nostack\mathsizesuffix]
+\stoptypescript
+
+\starttypescript [serif] [cambria] [name]
+ \usetypescript[fallback:serif]
+ \definefontsynonym [Serif] [name:cambria] [features=default]
+ \definefontsynonym [SerifBold] [name:cambriabold] [features=default]
+ \definefontsynonym [SerifItalic] [name:cambriaitalic] [features=default]
+ \definefontsynonym [SerifBoldItalic] [name:cambriabolditalic] [features=default]
+\stoptypescript
+
+\starttypescript [cambria]
+ \definetypeface [cambria] [rm] [serif] [cambria] [default]
+ \definetypeface [cambria] [tt] [mono] [modern] [default]
+ \definetypeface [cambria] [mm] [math] [cambria] [default]
+\stoptypescript
+
+\starttypescript [cambria-x]
+ \definetypeface [cambria-x] [rm] [serif] [cambria] [default]
+ \definetypeface [cambria-x] [tt] [mono] [modern] [default]
+ \definetypeface [cambria-x] [mm] [math] [cambria-x] [default]
+\stoptypescript
+
+\starttypescript [cambria-y]
+ \definetypeface [cambria-y] [rm] [serif] [cambria] [default]
+ \definetypeface [cambria-y] [tt] [mono] [modern] [default]
+ \definetypeface [cambria-y] [mm] [math] [cambria-y] [default]
+\stoptypescript
+
+% math times
+
+\starttypescript [math] [mathtimes] [all]
+ \definefontsynonym[MathRoman][mathtimes@mathtimes-math]
+ \loadmapfile[mathtime.map]
+% \pdfmapline{=mtsyn < mtsyn.pfb}
+% \pdfmapline{=mtmiz < mtmiz.pfb}
+% \pdfmapline{=mtex < mtex.pfb}
+\stoptypescript
+
+\starttypescript [mathtimes]
+ \definetypeface [mathtimes] [rm] [serif] [times] [default]
+ \definetypeface [mathtimes] [ss] [sans] [helvetica] [default] [rscale=0.9]
+ \definetypeface [mathtimes] [tt] [mono] [modern] [default] [rscale=1.05]
+ \definetypeface [mathtimes] [mm] [math] [mathtimes] [default]
+ \quittypescriptscanning
+\stoptypescript
+
+\stoptypescriptcollection
+
+\endinput
diff --git a/tex/context/base/type-otf.tex b/tex/context/base/type-otf.tex
index 29dee2e74..720ffbaf9 100644
--- a/tex/context/base/type-otf.tex
+++ b/tex/context/base/type-otf.tex
@@ -26,6 +26,16 @@
\quittypescriptscanning
\stoptypescript
+% faster
+%
+% \starttypescript [fallback]
+% \definetypeface [] [rm] [serif] [modern] [default]
+% \definetypeface [] [ss] [sans] [modern] [default]
+% \definetypeface [] [tt] [mono] [modern] [default]
+% \definetypeface [] [mm] [math] [modern] [default]
+% \quittypescriptscanning
+% \stoptypescript
+
\starttypescript [modern]
\definetypeface [modern] [rm] [serif] [modern] [computer-modern]
\definetypeface [modern] [ss] [sans] [modern] [computer-modern]
@@ -44,25 +54,25 @@
\starttypescript [postscript]
\definetypeface [postscript] [rm] [serif] [times] [default]
- \definetypeface [postscript] [ss] [sans] [helvetica] [default] [rscale=.9]
+ \definetypeface [postscript] [ss] [sans] [helvetica] [default] [rscale=0.9]
\definetypeface [postscript] [tt] [mono] [courier] [default] [rscale=1.1]
\definetypeface [postscript] [mm] [math] [times] [default]
\quittypescriptscanning
\stoptypescript
-\starttypescript [times]
- \definetypeface [times] [rm] [serif] [times] [default]
- \definetypeface [times] [ss] [sans] [helvetica] [default] [rscale=0.9]
- \definetypeface [times] [tt] [mono] [modern] [default] [rscale=1.05]
- \definetypeface [times] [mm] [math] [times] [default]
+\starttypescript [times,termes]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [helvetica] [default] [rscale=0.9]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [rscale=1.05]
+ \definetypeface [\typescriptone] [mm] [math] [times] [default]
\quittypescriptscanning
\stoptypescript
-\starttypescript [palatino]
- \definetypeface [palatino] [rm] [serif] [palatino] [default]
- \definetypeface [palatino] [ss] [sans] [modern] [default] [rscale=1.075]
- \definetypeface [palatino] [tt] [mono] [modern] [default] [rscale=1.075]
- \definetypeface [palatino] [mm] [math] [palatino] [default]
+\starttypescript [palatino,pagella]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [rscale=1.075]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [rscale=1.075]
+ \definetypeface [\typescriptone] [mm] [math] [palatino] [default]
\quittypescriptscanning
\stoptypescript
@@ -82,685 +92,64 @@
\quittypescriptscanning
\stoptypescript
-\starttypescript [iwona,iwona-light,iwona-heavy,iwona-medium]
- \definetypeface[\typescriptone][ss][sans] [\typescriptone] [default]
- \definetypeface[\typescriptone][rm][serif][modern] [default]
- \definetypeface[\typescriptone][tt][mono] [modern] [default]
- \definetypeface[\typescriptone][mm][math] [\typescriptone] [default][text=ss]
+\starttypescript [schoolbook,schola]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default]
\quittypescriptscanning
\stoptypescript
-\stoptypescriptcollection
-
-% if a fontname equals the filename, then use
-%
-% \setupfontsynonym [LMRoman10-DemiOblique] [features=default] % file is lowercase, so fails
-% \definefontsynonym [LMRoman10-DemiOblique] [name:LMRoman10-DemiOblique] [features=default]
-% \definefontsynonym [LMRoman10-DemiOblique] [lmroman10-demioblique] [features=default]
-
-\starttypescriptcollection[opentype]
-
-%D The names have changed (again) ... but I will not change the symbolic names
-%D any more. Filename changes will be catched in luatex (fallbacks) but not in
-%D other tex's.
-
-\starttypescript [serif] [modern,latin-modern]
- \definefontsynonym [LMRoman5-Regular] [file:lmroman5-regular] [features=default]
- \definefontsynonym [LMRoman6-Regular] [file:lmroman6-regular] [features=default]
- \definefontsynonym [LMRoman7-Regular] [file:lmroman7-regular] [features=default]
- \definefontsynonym [LMRoman8-Regular] [file:lmroman8-regular] [features=default]
- \definefontsynonym [LMRoman9-Regular] [file:lmroman9-regular] [features=default]
- \definefontsynonym [LMRoman10-Regular] [file:lmroman10-regular] [features=default]
- \definefontsynonym [LMRoman12-Regular] [file:lmroman12-regular] [features=default]
- \definefontsynonym [LMRoman17-Regular] [file:lmroman17-regular] [features=default]
- \definefontsynonym [LMRoman5-Bold] [file:lmroman5-bold] [features=default]
- \definefontsynonym [LMRoman6-Bold] [file:lmroman6-bold] [features=default]
- \definefontsynonym [LMRoman7-Bold] [file:lmroman7-bold] [features=default]
- \definefontsynonym [LMRoman8-Bold] [file:lmroman8-bold] [features=default]
- \definefontsynonym [LMRoman9-Bold] [file:lmroman9-bold] [features=default]
- \definefontsynonym [LMRoman10-Bold] [file:lmroman10-bold] [features=default]
- \definefontsynonym [LMRoman12-Bold] [file:lmroman12-bold] [features=default]
- \definefontsynonym [LMRoman7-Italic] [file:lmroman7-italic] [features=default]
- \definefontsynonym [LMRoman8-Italic] [file:lmroman8-italic] [features=default]
- \definefontsynonym [LMRoman9-Italic] [file:lmroman9-italic] [features=default]
- \definefontsynonym [LMRoman10-Italic] [file:lmroman10-italic] [features=default]
- \definefontsynonym [LMRoman12-Italic] [file:lmroman12-italic] [features=default]
- \definefontsynonym [LMRoman10-BoldItalic] [file:lmroman10-bolditalic] [features=default]
- \definefontsynonym [LMRoman8-Oblique] [file:lmromanslant8-regular] [features=default]
- \definefontsynonym [LMRoman9-Oblique] [file:lmromanslant9-regular] [features=default]
- \definefontsynonym [LMRoman10-Oblique] [file:lmromanslant10-regular][features=default]
- \definefontsynonym [LMRoman12-Oblique] [file:lmromanslant12-regular][features=default]
- \definefontsynonym [LMRoman17-Oblique] [file:lmromanslant17-regular][features=default]
- \definefontsynonym [LMRoman10-BoldOblique] [file:lmromanslant10-bold] [features=default]
- \definefontsynonym [LMRoman10-Demi] [file:lmromandemi10-regular] [features=default]
- \definefontsynonym [LMRoman10-DemiOblique] [file:lmromandemi10-oblique] [features=default]
- \definefontsynonym [LMRoman10-CapsRegular] [file:lmromancaps10-regular] [features=default] % features=smallcaps?
- \definefontsynonym [LMRoman10-CapsOblique] [file:lmromancaps10-oblique] [features=default]
-
- \definefontsynonym [LMRoman10-Dunhill] [file:lmromandunh10-regular] [features=default]
- \definefontsynonym [LMRoman10-DunhillOblique] [file:lmromandunh10-oblique] [features=default]
- \definefontsynonym [LMRoman10-Unslanted] [file:lmromanunsl10-regular] [features=default]
-\stoptypescript
-
-\starttypescript [sans] [modern,latin-modern]
- \definefontsynonym [LMSans8-Regular] [file:lmsans8-regular] [features=default]
- \definefontsynonym [LMSans9-Regular] [file:lmsans9-regular] [features=default]
- \definefontsynonym [LMSans10-Regular] [file:lmsans10-regular] [features=default]
- \definefontsynonym [LMSans12-Regular] [file:lmsans12-regular] [features=default]
- \definefontsynonym [LMSans17-Regular] [file:lmsans17-regular] [features=default]
- \definefontsynonym [LMSans10-Bold] [file:lmsans10-bold] [features=default]
- \definefontsynonym [LMSans8-Oblique] [file:lmsans8-oblique] [features=default]
- \definefontsynonym [LMSans9-Oblique] [file:lmsans9-oblique] [features=default]
- \definefontsynonym [LMSans10-Oblique] [file:lmsans10-oblique] [features=default]
- \definefontsynonym [LMSans12-Oblique] [file:lmsans12-oblique] [features=default]
- \definefontsynonym [LMSans17-Oblique] [file:lmsans17-oblique] [features=default]
- \definefontsynonym [LMSans10-BoldOblique] [file:lmsans10-boldoblique] [features=default]
-
- \definefontsynonym [LMSans10-DemiCondensed] [file:lmsansdemicond10-regular] [features=default]
- \definefontsynonym [LMSans10-DemiCondensedOblique] [file:lmsansdemicond10-oblique] [features=default]
-
- \definefontsynonym [LMSansQuotation8-Regular] [file:lmsansquot8-regular] [features=default]
- \definefontsynonym [LMSansQuotation8-Bold] [file:lmsansquot8-bold] [features=default]
- \definefontsynonym [LMSansQuotation8-Oblique] [file:lmsansquot8-oblique] [features=default]
- \definefontsynonym [LMSansQuotation8-BoldOblique] [file:lmsansquot8-boldoblique] [features=default]
-\stoptypescript
-
-\starttypescript [mono] [modern,latin-modern,modern-vari,latin-modern-vari,modern-cond,latin-modern-cond]
- \definefontsynonym [LMTypewriter8-Regular] [file:lmmono8-regular]
- \definefontsynonym [LMTypewriter9-Regular] [file:lmmono9-regular]
- \definefontsynonym [LMTypewriter10-Regular] [file:lmmono10-regular]
- \definefontsynonym [LMTypewriter12-Regular] [file:lmmono12-regular]
- \definefontsynonym [LMTypewriter10-Italic] [file:lmmono10-italic]
- \definefontsynonym [LMTypewriter10-Oblique] [file:lmmonoslant10-regular]
- \definefontsynonym [LMTypewriter10-CapsRegular] [file:lmmonocaps10-regular] % features=smallcaps?
- \definefontsynonym [LMTypewriter10-CapsOblique] [file:lmmonocaps10-oblique]
-
- \definefontsynonym [LMTypewriter10-Light] [file:lmmonolt10-regular]
- \definefontsynonym [LMTypewriter10-LightOblique] [file:lmmonolt10-oblique]
- \definefontsynonym [LMTypewriter10-LightCondensed] [file:lmmonoltcond10-regular]
- \definefontsynonym [LMTypewriter10-LightCondensedOblique] [file:lmmonoltcond10-oblique]
-
- \definefontsynonym [LMTypewriter10-Dark] [file:lmmonolt10-bold]
- \definefontsynonym [LMTypewriter10-DarkOblique] [file:lmmonolt10-boldoblique]
-
- \definefontsynonym [LMTypewriterVarWd10-Regular] [file:lmmonoproplt10-regular] [features=default]
- \definefontsynonym [LMTypewriterVarWd10-Oblique] [file:lmmonoproplt10-oblique] [features=default]
- \definefontsynonym [LMTypewriterVarWd10-Light] [file:lmmonoprop10-regular] [features=default]
- \definefontsynonym [LMTypewriterVarWd10-LightOblique] [file:lmmonoprop10-oblique] [features=default]
- \definefontsynonym [LMTypewriterVarWd10-Dark] [file:lmmonoproplt10-bold] [features=default]
- \definefontsynonym [LMTypewriterVarWd10-DarkOblique] [file:lmmonoproplt10-boldoblique] [features=default]
-\stoptypescript
-
-\starttypescript [math] [modern,latin-modern]
- \definefontsynonym [LMMathRoman5-Regular] [rm-lmr5]
- \definefontsynonym [LMMathRoman6-Regular] [rm-lmr6]
- \definefontsynonym [LMMathRoman7-Regular] [rm-lmr7]
- \definefontsynonym [LMMathRoman8-Regular] [rm-lmr8]
- \definefontsynonym [LMMathRoman9-Regular] [rm-lmr9]
- \definefontsynonym [LMMathRoman10-Regular] [rm-lmr10]
- \definefontsynonym [LMMathRoman12-Regular] [rm-lmr12]
- \definefontsynonym [LMMathRoman17-Regular] [rm-lmr17]
- \definefontsynonym [LMMathRoman5-Bold] [rm-lmbx5]
- \definefontsynonym [LMMathRoman6-Bold] [rm-lmbx6]
- \definefontsynonym [LMMathRoman7-Bold] [rm-lmbx7]
- \definefontsynonym [LMMathRoman8-Bold] [rm-lmbx8]
- \definefontsynonym [LMMathRoman9-Bold] [rm-lmbx9]
- \definefontsynonym [LMMathRoman10-Bold] [rm-lmbx10]
- \definefontsynonym [LMMathRoman12-Bold] [rm-lmbx12]
- \definefontsynonym [LMMathSymbols5-BoldItalic] [lmbsy5]
- \definefontsynonym [LMMathSymbols7-BoldItalic] [lmbsy7]
- \definefontsynonym [LMMathSymbols10-BoldItalic][lmbsy10]
- \definefontsynonym [LMMathSymbols5-Italic] [lmsy5]
- \definefontsynonym [LMMathSymbols6-Italic] [lmsy6]
- \definefontsynonym [LMMathSymbols7-Italic] [lmsy7]
- \definefontsynonym [LMMathSymbols8-Italic] [lmsy8]
- \definefontsynonym [LMMathSymbols9-Italic] [lmsy9]
- \definefontsynonym [LMMathSymbols10-Italic] [lmsy10]
- \definefontsynonym [LMMathExtension10-Regular] [lmex10]
- \definefontsynonym [LMMathItalic5-Italic] [lmmi5]
- \definefontsynonym [LMMathItalic6-Italic] [lmmi6]
- \definefontsynonym [LMMathItalic7-Italic] [lmmi7]
- \definefontsynonym [LMMathItalic8-Italic] [lmmi8]
- \definefontsynonym [LMMathItalic9-Italic] [lmmi9]
- \definefontsynonym [LMMathItalic10-Italic] [lmmi10]
- \definefontsynonym [LMMathItalic12-Italic] [lmmi12]
- \definefontsynonym [LMMathItalic5-BoldItalic] [lmmib5]
- \definefontsynonym [LMMathItalic7-BoldItalic] [lmmib7]
- \definefontsynonym [LMMathItalic10-BoldItalic] [lmmib10]
-
- \loadmapfile[lm-math.map]
- \loadmapfile[lm-rm.map]
-\stoptypescript
-
-\starttypescript [math] [modern,computer-modern,latin-modern]
- \definefontsynonym [ComputerModernMath-Roman] [rm-lmr10]
- \definefontsynonym [ComputerModernMath-Extension] [lmex10]
- \definefontsynonym [ComputerModernMath-Italic] [lmmi10]
- \definefontsynonym [ComputerModernMath-Symbol] [lmsy10]
-\stoptypescript
-
-\starttypescript [boldmath,bfmath] [modern,computer-modern,latin-modern]
- \definefontsynonym [ComputerModernMath-Roman-Bold] [rm-lmb10]
- \definefontsynonym [ComputerModernMath-Extension] [lmex10]
- \definefontsynonym [ComputerModernMath-Italic-Bold] [lmmib10]
- \definefontsynonym [ComputerModernMath-Symbol-Bold] [lmbsy10]
-\stoptypescript
-
-% Computer Concrete (AMS)
-
-\starttypescript [serif] [concrete]
- \definefontsynonym [ComputerConcrete] [ccr10]
- \definefontsynonym [ComputerConcrete-Italic] [ccti10]
- \definefontsynonym [ComputerConcrete-Slanted] [ccsl10]
- \definefontsynonym [ComputerConcrete-Bold] [ComputerConcrete]
- \definefontsynonym [ComputerConcrete-BoldItalic] [ComputerConcrete-Italic]
- \definefontsynonym [ComputerConcrete-BoldSlanted] [ComputerConcrete-Slanted]
- \definefontsynonym [ComputerConcrete-Caps] [cccsc10]
-\stoptypescript
-
-% Euler (AMS)
-
-\starttypescript [math] [euler]
- \definefontsynonym [Euler-Roman] [zeurm10]
- \definefontsynonym [Euler-Extension] [zeuex10]
- \definefontsynonym [Euler-Symbol] [zeusm10]
- \definefontsynonym [Euler-Fraktur] [eufm10]
-
- \loadmapfile[original-ams-euler.map]
-\stoptypescript
-
-\starttypescript [boldmath,bfmath] [euler]
- \definefontsynonym [Euler-Roman-Bold] [zeurb10]
- \definefontsynonym [Euler-Extension] [zeuex10]
- \definefontsynonym [Euler-Symbol-Bold] [zeusb10]
- \definefontsynonym [Euler-Fraktur-Bold] [eufb10]
-
- \loadmapfile[original-ams-euler.map]
-\stoptypescript
-
-% AMS (AMS)
-
-\starttypescript [math] [modern,computer-modern,latin-modern,ams]
- \definefontsynonym [AMS-SymbolA] [msam10]
- \definefontsynonym [AMS-SymbolB] [msbm10]
-\stoptypescript
-
-% TeXGyre
-
-\definetypescriptprefix [n:pagella] [TeXGyrePagella] \definetypescriptprefix [f:pagella] [pagella]
-\definetypescriptprefix [n:termes] [TeXGyreTermes] \definetypescriptprefix [f:termes] [termes]
-\definetypescriptprefix [n:heros] [TeXGyreHeros] \definetypescriptprefix [f:heros] [heros]
-\definetypescriptprefix [n:bonum] [TeXGyreBonum] \definetypescriptprefix [f:bonum] [bonum]
-\definetypescriptprefix [n:schola] [TeXGyreSchola] \definetypescriptprefix [f:schola] [schola]
-\definetypescriptprefix [n:adventor][TeXGyreAdventor] \definetypescriptprefix [f:adventor][adventor]
-\definetypescriptprefix [n:cursor] [TeXGyreCursor] \definetypescriptprefix [f:cursor] [cursor]
-\definetypescriptprefix [n:chorus] [TeXGyreChorus] \definetypescriptprefix [f:chorus] [chorus] % not the full set
-
-\starttypescript [serif,sans,mono] [adventor,bonum,cursor,heros,pagella,schola,termes]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [features=default]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [features=default]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [features=default]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [features=default]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Caps] [file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [features=oldstyle]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [features=oldstyle]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [features=oldstyle]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [features=oldstyle]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Slanted] [\typescriptprefix{n:\typescripttwo}-Italic] [features=default]
- \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldSlanted] [\typescriptprefix{n:\typescripttwo}-BoldItalic] [features=default]
-\stoptypescript
-
-\starttypescript [serif] [pagella,termes,bonum,schola,chorus] [name]
- \definefontsynonym [Serif] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
- \definefontsynonym [SerifItalic] [\typescriptprefix{n:\typescripttwo}-Italic] [features=default]
- \definefontsynonym [SerifBold] [\typescriptprefix{n:\typescripttwo}-Bold] [features=default]
- \definefontsynonym [SerifBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic] [features=default]
- \definefontsynonym [SerifCaps] [\typescriptprefix{n:\typescripttwo}-Caps] [features=smallcaps]
- \definefontsynonym [SerifSlanted] [\typescriptprefix{n:\typescripttwo}-Slanted] [features=default]
- \definefontsynonym [SerifBoldSlanted] [\typescriptprefix{n:\typescripttwo}-BoldSlanted] [features=default]
-
- \definefontvariant [Serif][osf][Caps]
- \definefontvariant [Serif][sc] [Caps]
-
- \definefontsynonym [SerifRegular] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
- \definefontsynonym [SerifRegularCaps] [\typescriptprefix{n:\typescripttwo}-Caps] [features=smallcaps]
- \definefontsynonym [SerifItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [features=smallcaps]
- \definefontsynonym [SerifBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps] [features=smallcaps]
- \definefontsynonym [SerifBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [features=smallcaps]
- \definefontsynonym [SerifCapsCaps] [\typescriptprefix{n:\typescripttwo}-Caps] [features=smallcaps]
- \definefontsynonym [SerifSlantedCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [features=smallcaps]
- \definefontsynonym [SerifBoldSlantedCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [features=smallcaps]
-\stoptypescript
-
-\starttypescript [sans] [heros,adventor] [name]
- \definefontsynonym [Sans] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
- \definefontsynonym [SansItalic] [\typescriptprefix{n:\typescripttwo}-Italic] [features=default]
- \definefontsynonym [SansBold] [\typescriptprefix{n:\typescripttwo}-Bold] [features=default]
- \definefontsynonym [SansBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic] [features=default]
- \definefontsynonym [SansCaps] [\typescriptprefix{n:\typescripttwo}-Caps] [features=smallcaps]
- \definefontsynonym [SansSlanted] [\typescriptprefix{n:\typescripttwo}-Slanted] [features=default]
- \definefontsynonym [SansBoldSlanted] [\typescriptprefix{n:\typescripttwo}-BoldSlanted] [features=default]
-
- \definefontvariant [Sans][osf][Caps]
- \definefontvariant [Sans][sc] [Caps]
-
- \definefontsynonym [SansRegular] [\typescriptprefix{n:\typescripttwo}-Regular] [features=default]
- \definefontsynonym [SansRegularCaps] [\typescriptprefix{n:\typescripttwo}-Caps] [features=smallcaps]
- \definefontsynonym [SansItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [features=smallcaps]
- \definefontsynonym [SansBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps] [features=smallcaps]
- \definefontsynonym [SansBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [features=smallcaps]
- \definefontsynonym [SansCapsCaps] [\typescriptprefix{n:\typescripttwo}-Caps] [features=smallcaps]
- \definefontsynonym [SansSlantedCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps] [features=smallcaps]
- \definefontsynonym [SansBoldSlantedCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [features=smallcaps]
-\stoptypescript
-
-\starttypescript [mono] [cursor] [name]
- \definefontsynonym [Mono] [\typescriptprefix{n:\typescripttwo}-Regular]
- \definefontsynonym [MonoItalic] [\typescriptprefix{n:\typescripttwo}-Italic]
- \definefontsynonym [MonoBold] [\typescriptprefix{n:\typescripttwo}-Bold]
- \definefontsynonym [MonoBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
- \definefontsynonym [MonoSlanted] [MonoItalic]
- \definefontsynonym [MonoBoldSlanted] [MonoBoldItalic]
-\stoptypescript
-
-%D Here we overload the older (URW) fonts.
-
-% TeXGyrePagella
-%
-% qplr TeXGyrePagella-Regular
-% qplri TeXGyrePagella-Italic
-% qplb TeXGyrePagella-Bold
-% qplbi TeXGyrePagella-BoldItalic
-
-\starttypescript [serif] [palatino,pagella]
- \definefontsynonym [Palatino] [file:texgyrepagella-regular] [features=default]
- \definefontsynonym [Palatino-Italic] [file:texgyrepagella-italic] [features=default]
- \definefontsynonym [Palatino-Bold] [file:texgyrepagella-bold] [features=default]
- \definefontsynonym [Palatino-BoldItalic] [file:texgyrepagella-bolditalic] [features=default]
- \definefontsynonym [Palatino-Caps] [file:texgyrepagella-regular] [features=smallcaps]
- \definefontsynonym [Palatino-Slanted] [Palatino-Italic]
- \definefontsynonym [Palatino-BoldSlanted] [Palatino-BoldItalic]
-\stoptypescript
-
-% TeXGyreTermes
-%
-% qtmr TeXGyreTermes-Regular
-% qtmri TeXGyreTermes-Italic
-% qtmb TeXGyreTermes-Bold
-% qtmbi TeXGyreTermes-BoldItalic
-
-\starttypescript [serif] [times]
- \definefontsynonym [Times-Roman] [file:texgyretermes-regular] [features=default]
- \definefontsynonym [Times-Italic] [file:texgyretermes-italic] [features=default]
- \definefontsynonym [Times-Bold] [file:texgyretermes-bold] [features=default]
- \definefontsynonym [Times-BoldItalic] [file:texgyretermes-bolditalic] [features=default]
- \definefontsynonym [Times-Caps] [file:texgyretermes-regular] [features=smallcaps]
- \definefontsynonym [Times-Slanted] [Times-Italic]
- \definefontsynonym [Times-BoldSlanted] [Times-BoldItalic]
-\stoptypescript
-
-% TeXGyreHeros
-%
-% qtmr TeXGyreHeros-Regular
-% qtmri TeXGyreHeros-Italic
-% qtmb TeXGyreHeros-Bold
-% qtmbi TeXGyreHeros-BoldItalic
-
-\starttypescript [sans] [helvetica]
- \definefontsynonym [Helvetica] [file:texgyreheros-regular] [features=default]
- \definefontsynonym [Helvetica-Oblique] [file:texgyreheros-italic] [features=default]
- \definefontsynonym [Helvetica-Bold] [file:texgyreheros-bold] [features=default]
- \definefontsynonym [Helvetica-BoldOblique] [file:texgyreheros-bolditalic] [features=default]
- \definefontsynonym [Helvetica-Caps] [file:texgyreheros-regular] [features=smallcaps]
-\stoptypescript
-
-% TeXGyreBonum
-%
-% qtmr TeXGyreBonum-Regular
-% qtmri TeXGyreBonum-Italic
-% qtmb TeXGyreBonum-Bold
-% qtmbi TeXGyreBonum-BoldItalic
-
-\starttypescript [serif] [bookman]
- \definefontsynonym [Bookman-Light] [file:texgyrebonum-regular] [features=default]
- \definefontsynonym [Bookman-LightItalic] [file:texgyrebonum-italic] [features=default]
- \definefontsynonym [Bookman-DemiBold] [file:texgyrebonum-bold] [features=default]
- \definefontsynonym [Bookman-DemiBoldItalic] [file:texgyrebonum-bolditalic] [features=default]
- \definefontsynonym [Bookman-Light-Caps] [file:texgyrebonum-regular] [features=smallcaps]
- \definefontsynonym [Bookman-LightSlanted] [Bookman-LightItalic] [features=default]
- \definefontsynonym [Bookman-DemiBoldSlanted] [Bookman-DemiBoldItalic] [features=default]
-\stoptypescript
-
-% TeXGyreScola
-%
-% qcsr TeXGyreSchola-Regular
-% qcsri TeXGyreSchola-Italic
-% qcsb TeXGyreSchola-Bold
-% qcsbi TeXGyreSchola-BoldItalic
-
-\starttypescript [serif] [schoolbook]
- \definefontsynonym [Schoolbook-Roman] [file:texgyreschola-regular] [features=default]
- \definefontsynonym [Schoolbook-Italic] [file:texgyreschola-italic] [features=default]
- \definefontsynonym [Schoolbook-Bold] [file:texgyreschola-bold] [features=default]
- \definefontsynonym [Schoolbook-BoldItalic] [file:texgyreschola-bolditalic] [features=default]
- \definefontsynonym [Schoolbook-Roman-Caps] [file:texgyreschola-regular] [features=smallcaps]
- \definefontsynonym [Schoolbook-Slanted] [Schoolbook-Italic] [features=default]
- \definefontsynonym [Schoolbook-BoldSlanted] [Schoolbook-BoldItalic] [features=default]
-\stoptypescript
-
-% TeXGyreAdventor
-%
-% qagr TeXGyreAdventor-Regular
-% qagri TeXGyreAdventor-Italic
-% qagb TeXGyreAdventor-Bold
-% qagbi TeXGyreAdventor-BoldItalic
-
-% TeXGyreCursor
-%
-% crgr TeXGyreCursor-Regular
-% crgri TeXGyreCursor-Italic
-% crgb TeXGyreCursor-Bold
-% crgbi TeXGyreCursor-BoldItalic
-
-\starttypescript [mono] [courier] [name]
- \definefontsynonym [Courier] [file:texgyrecursor-regular] [features=default]
- \definefontsynonym [Courier-Bold] [file:texgyrecursor-bold] [features=default]
- \definefontsynonym [Courier-Oblique] [file:texgyrecursor-italic] [features=default]
- \definefontsynonym [Courier-BoldOblique] [file:texgyrecursor-bolditalic] [features=default]
- \fakecontrolspace
-\stoptypescript
-
-% TeXGyreChorus
-%
-% qzcr TeXGyreChorus-Regular
-
-\starttypescript [calligraphy] [chancery]
- \definefontsynonym [Chancery] [file:texgyrechorus-mediumitalic] [features=default]
- \definefontsynonym [texgyrechorus-regular] [file:texgyrechorus-mediumitalic]
-\stoptypescript
-
-% Math Times (tx)
-
-\starttypescript [math] [times] [all]
- \definefontsynonym [Times-Roman-Upright] [txr]
- \definefontsynonym [Times-Roman-Italic] [txi]
- \definefontsynonym [Times-Roman-Slanted] [txsl]
- \definefontsynonym [Times-Roman-Caps] [txsc]
- \definefontsynonym [Times-Companion-Upright] [tcxr]
- \definefontsynonym [Times-Companion-Italic] [tcxi]
- \definefontsynonym [Times-Companion-Slanted] [tcxsl]
- \definefontsynonym [Times-Math-Italic] [txmi]
- \definefontsynonym [Times-Math-Symbols] [txsy]
- \definefontsynonym [Times-Math-Extension] [txex]
- \definefontsynonym [Times-Math-SymbolsA] [txsya]
- \definefontsynonym [Times-Math-SymbolsB] [txsyb]
- \definefontsynonym [Times-Math-SymbolsC] [txsyc]
- \definefontsynonym [Times-Math-Italic-A] [txmia]
- \definefontsynonym [Times-Math-Extension-A] [txexa]
-
- \loadmapfile[original-youngryu-tx.map]
- \usemathcollection[default]
-\stoptypescript
-
-% Palatino Math (PX)
-
-\starttypescript [math] [palatino] [all]
- \definefontsynonym [Palatino-Roman-Upright] [pxr]
- \definefontsynonym [Palatino-Roman-Italic] [pxi]
- \definefontsynonym [Palatino-Roman-Slanted] [pxsl]
- \definefontsynonym [Palatino-Roman-Caps] [pxsc]
- \definefontsynonym [Palatino-Companion-Upright] [pcxr]
- \definefontsynonym [Palatino-Companion-Italic] [pcxi]
- \definefontsynonym [Palatino-Companion-Slanted] [pcxsl]
- \definefontsynonym [Palatino-Math-Italic] [pxmi]
- \definefontsynonym [Palatino-Math-Symbols] [pxsy]
- \definefontsynonym [Palatino-Math-Extension] [pxex]
- \definefontsynonym [Palatino-Math-SymbolsA] [pxsya]
- \definefontsynonym [Palatino-Math-SymbolsB] [pxsyb]
- \definefontsynonym [Palatino-Math-SymbolsC] [pxsyc]
- \definefontsynonym [Palatino-Math-Italic-A] [pxmia]
- \definefontsynonym [Palatino-Math-Extension-A] [pxexa]
-
- \loadmapfile[original-youngryu-px.map]
- \usemathcollection[default]
-\stoptypescript
-
-% Antykwa Torunska (GUST)
-
-\starttypescript [serif] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond]
- \definefontsynonym [AntykwaTorunska-Regular] [file:AntykwaTorunska-Regular] [features=default]
- \definefontsynonym [AntykwaTorunska-Italic] [file:AntykwaTorunska-Italic] [features=default]
- \definefontsynonym [AntykwaTorunska-Bold] [file:AntykwaTorunska-Bold] [features=default]
- \definefontsynonym [AntykwaTorunska-BoldItalic] [file:AntykwaTorunska-BoldItalic] [features=default]
- \definefontsynonym [AntykwaTorunska-Light] [file:AntykwaTorunskaLight-Regular] [features=default]
- \definefontsynonym [AntykwaTorunska-LightItalic] [file:AntykwaTorunskaLight-Italic] [features=default]
- \definefontsynonym [AntykwaTorunska-Medium] [file:AntykwaTorunskaMed-Regular] [features=default]
- \definefontsynonym [AntykwaTorunska-MedItalic] [file:AntykwaTorunskaMed-Italic] [features=default]
- \definefontsynonym [AntykwaTorunska-CondRegular] [file:AntykwaTorunskaCond-Regular] [features=default]
- \definefontsynonym [AntykwaTorunska-CondItalic] [file:AntykwaTorunskaCond-Italic] [features=default]
- \definefontsynonym [AntykwaTorunska-CondBold] [file:AntykwaTorunskaCond-Bold] [features=default]
- \definefontsynonym [AntykwaTorunska-CondBoldItalic] [file:AntykwaTorunskaCond-BoldItalic] [features=default]
- \definefontsynonym [AntykwaTorunska-CondLight] [file:AntykwaTorunskaCondLight-Regular] [features=default]
- \definefontsynonym [AntykwaTorunska-CondLightItalic] [file:AntykwaTorunskaCondLight-Italic] [features=default]
- \definefontsynonym [AntykwaTorunska-CondMedium] [file:AntykwaTorunskaCondMed-Regular] [features=default]
- \definefontsynonym [AntykwaTorunska-CondMedItalic] [file:AntykwaTorunskaCondMed-Italic] [features=default]
-
- \definefontsynonym [AntykwaTorunska-Cap] [file:AntykwaTorunska-Regular] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-ItalicCap] [file:AntykwaTorunska-Italic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-BoldCap] [file:AntykwaTorunska-Bold] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-BoldItalicCap] [file:AntykwaTorunska-BoldItalic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-LightCap] [file:AntykwaTorunskaLight-Regular] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-LightItalicCap] [file:AntykwaTorunskaLight-Italic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-MediumCap] [file:AntykwaTorunskaMed-Regular] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-MedItalicCap] [file:AntykwaTorunskaMed-Italic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondCap] [file:AntykwaTorunskaCond-Regular] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondItalicCap] [file:AntykwaTorunskaCond-Italic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondBoldCap] [file:AntykwaTorunskaCond-Bold] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondBoldItalicCap] [file:AntykwaTorunskaCond-BoldItalic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondLightCap] [file:AntykwaTorunskaCondLight-Regular] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondLightItalicCap][file:AntykwaTorunskaCondLight-Italic] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondMediumCap] [file:AntykwaTorunskaCondMed-Regular] [features=smallcaps]
- \definefontsynonym [AntykwaTorunska-CondMedItalicCap] [file:AntykwaTorunskaCondMed-Italic] [features=smallcaps]
-\stoptypescript
-
-\starttypescript [math] [antykwa-torunska] [default]
- \definefontsynonym [AntykwaTorunska-Math-Letters-Regular] [rm-anttr]
- \definefontsynonym [AntykwaTorunska-Math-Letters-Italic] [mi-anttri]
- \definefontsynonym [AntykwaTorunska-Math-Symbols-Regular] [sy-anttrz]
- \definefontsynonym [AntykwaTorunska-Math-Extension-Regular] [ex-anttr]
-\stoptypescript
-
-\starttypescript [math] [antykwa-torunska-light] [default]
- \definefontsynonym [AntykwaTorunska-Math-Letters-Light] [rm-anttl]
- \definefontsynonym [AntykwaTorunska-Math-Letters-LightItalic] [mi-anttli]
- \definefontsynonym [AntykwaTorunska-Math-Symbols-Light] [sy-anttlz]
- \definefontsynonym [AntykwaTorunska-Math-Extension-Light] [ex-anttl]
-\stoptypescript
-
-\starttypescript [math] [antykwa-torunska-cond] [default]
- \definefontsynonym [AntykwaTorunska-Math-Letters-CondRegular] [rm-anttcr]
- \definefontsynonym [AntykwaTorunska-Math-Letters-CondItalic] [mi-anttcri]
- \definefontsynonym [AntykwaTorunska-Math-Symbols-CondRegular] [sy-anttcrz]
- \definefontsynonym [AntykwaTorunska-Math-Extension-CondRegular] [ex-anttcr]
-\stoptypescript
-
-\starttypescript [math] [antykwa-torunska-lightcond] [default]
- \definefontsynonym [AntykwaTorunska-Math-Letters-CondLight] [rm-anttcl]
- \definefontsynonym [AntykwaTorunska-Math-Letters-CondLightItalic] [mi-anttcli]
- \definefontsynonym [AntykwaTorunska-Math-Symbols-CondLight] [sy-anttclz]
- \definefontsynonym [AntykwaTorunska-Math-Extension-CondLight] [ex-anttcl]
-\stoptypescript
-
-\starttypescript [math] [antykwa-torunska,antykwa-torunska-light,antykwa-torunska-cond,antykwa-torunska-lightcond]
- \usemathcollection[default]
- \loadmapfile[antt-rm.map]
- \loadmapfile[antt-mi.map]
- \loadmapfile[antt-sy.map]
- \loadmapfile[antt-ex.map]
-\stoptypescript
-
-% Antykwa Poltawskiego (GUST)
-
-\starttypescript [serif] [antykwa-poltawskiego]
- \definefontsynonym [AntykwaPoltawskiego-Regular] [antpr]
- \definefontsynonym [AntykwaPoltawskiego-Bold] [antpb]
- \definefontsynonym [AntykwaPoltawskiego-Italic] [antpri]
- \definefontsynonym [AntykwaPoltawskiego-BoldItalic] [antpbi]
-\stoptypescript
-
-% Iwona (JMN)
-
-% maybe this will change in Iwona-Math-Letters and Iwona-Math-Letters-Italic
-
-% These names are a depressing mess. They have changed over time and are
-% still not consistent. I'd expect Bold-Regular and Bold-Italic.
-
-\starttypescript [sans] [iwona-light,iwona,iwona-medium,iwona-heavy,iwona-light-cond,iwona-cond,iwona-medium-cond,iwona-heavy-cond]
-
- \definefontsynonym [Iwona-Regular] [file:Iwona-Regular] [features=default]
- \definefontsynonym [Iwona-Italic] [file:Iwona-Italic] [features=default]
- \definefontsynonym [Iwona-Bold] [file:Iwona-Bold] [features=default]
- \definefontsynonym [Iwona-BoldItalic] [file:Iwona-BoldItalic] [features=default]
- \definefontsynonym [Iwona-Light-Regular] [file:IwonaLight-Regular] [features=default]
- \definefontsynonym [Iwona-Light-Italic] [file:IwonaLight-Italic] [features=default]
- \definefontsynonym [Iwona-Medium-Regular] [file:IwonaMedium-Regular] [features=default]
- \definefontsynonym [Iwona-Medium-Italic] [file:IwonaMedium-Italic] [features=default]
- \definefontsynonym [Iwona-Heavy-Regular] [file:IwonaHeavy-Regular] [features=default]
- \definefontsynonym [Iwona-Heavy-Italic] [file:IwonaHeavy-Italic] [features=default]
-
- \definefontsynonym [Iwona-CapsRegular] [file:Iwona-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsItalic] [file:Iwona-Italic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsBold] [file:Iwona-Bold] [features=smallcaps]
- \definefontsynonym [Iwona-CapsBoldItalic] [file:Iwona-BoldItalic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsLight] [file:IwonaLight-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsLight-Italic] [file:IwonaLight-Italic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsMedium] [file:IwonaMedium-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsMedium-Italic] [file:IwonaMedium-Italic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsHeavy] [file:IwonaHeavy-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsHeavy-Italic] [file:IwonaHeavy-Italic] [features=smallcaps]
-
- \definefontsynonym [Iwona-CondRegular] [file:IwonaCond-Regular] [features=default]
- \definefontsynonym [Iwona-CondItalic] [file:IwonaCond-Italic] [features=default]
- \definefontsynonym [Iwona-CondBold] [file:IwonaCond-Bold] [features=default]
- \definefontsynonym [Iwona-CondBoldItalic] [file:IwonaCond-BoldItalic] [features=default]
- \definefontsynonym [Iwona-CondLight-Regular] [file:IwonaCondLight-Regular] [features=default]
- \definefontsynonym [Iwona-CondLight-Italic] [file:IwonaCondLight-Italic] [features=default]
- \definefontsynonym [Iwona-CondMedium-Regular] [file:IwonaCondMedium-Regular] [features=default]
- \definefontsynonym [Iwona-CondMedium-Italic] [file:IwonaCondMedium-Italic] [features=default]
- \definefontsynonym [Iwona-CondHeavy-Regular] [file:IwonaCondHeavy-Regular] [features=default]
- \definefontsynonym [Iwona-CondHeavy-Italic] [file:IwonaCondHeavy-Italic] [features=default]
-
- \definefontsynonym [Iwona-CapsCondRegular] [file:IwonaCond-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondItalic] [file:IwonaCond-Italic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondBold] [file:IwonaCond-Bold] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondBoldItalic] [file:IwonaCond-BoldItalic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondLight-Regular] [file:IwonaCondLight-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondLight-Italic] [file:IwonaCondLight-Italic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondMedium-Regular][file:IwonaCondMedium-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondMedium-Italic] [file:IwonaCondMedium-Italic] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondHeavy-Regular] [file:IwonaCondHeavy-Regular] [features=smallcaps]
- \definefontsynonym [Iwona-CapsCondHeavy-Italic] [file:IwonaCondHeavy-Italic] [features=smallcaps]
-
-\stoptypescript
-
-\starttypescript [math] [iwona] [default]
- \definefontsynonym [Iwona-Math-Letters-Regular] [rm-iwonar]
- \definefontsynonym [Iwona-Math-Letters-Italic] [mi-iwonari]
- \definefontsynonym [Iwona-Math-Symbols-Regular] [sy-iwonarz]
- \definefontsynonym [Iwona-Math-Extension-Regular] [ex-iwonar]
-\stoptypescript
-
-\starttypescript [math] [iwona-light] [default]
- \definefontsynonym [Iwona-Math-Letters-Light-Regular] [rm-iwonal]
- \definefontsynonym [Iwona-Math-Letters-Light-Italic] [mi-iwonali]
- \definefontsynonym [Iwona-Math-Symbols-Light] [sy-iwonalz]
- \definefontsynonym [Iwona-Math-Extension-Light] [ex-iwonal]
-\stoptypescript
-
-\starttypescript [math] [iwona-medium] [default]
- \definefontsynonym [Iwona-Math-Letters-Medium-Regular][rm-iwonam]
- \definefontsynonym [Iwona-Math-Letters-Medium-Italic] [mi-iwonami]
- \definefontsynonym [Iwona-Math-Symbols-Medium] [sy-iwonamz]
- \definefontsynonym [Iwona-Math-Extension-Medium] [ex-iwonam]
-\stoptypescript
-
-\starttypescript [math] [iwona-heavy] [default]
- \definefontsynonym [Iwona-Math-Letters-Heavy-Regular] [rm-iwonah]
- \definefontsynonym [Iwona-Math-Letters-Heavy-Italic] [mi-iwonahi]
- \definefontsynonym [Iwona-Math-Symbols-Heavy] [sy-iwonahz]
- \definefontsynonym [Iwona-Math-Extension-Heavy] [ex-iwonah]
-\stoptypescript
-
-\starttypescript [math] [iwona,iwona-light,iwona-medium,iwona-heavy] [default]
- \usemathcollection[default]
- \loadmapfile[iwona-rm.map]
- \loadmapfile[iwona-mi.map]
- \loadmapfile[iwona-sy.map]
- \loadmapfile[iwona-ex.map]
-\stoptypescript
-
-% Kurier (JMN) / no open type fonts
-
-\starttypescript [sans] [kurier-light,kurier,kurier-medium]
- \definefontsynonym[Kurier-Light] [kurierl]
- \definefontsynonym[Kurier-Regular] [kurierr]
- \definefontsynonym[Kurier-Medium] [kurierm]
- \definefontsynonym[Kurier-Bold] [kurierb]
- \definefontsynonym[Kurier-Heavy] [kurierh]
- \definefontsynonym[Kurier-LightItalic] [kurierli]
- \definefontsynonym[Kurier-Italic] [kurierri]
- \definefontsynonym[Kurier-MediumItalic] [kuriermi]
- \definefontsynonym[Kurier-BoldItalic] [kurierbi]
- \definefontsynonym[Kurier-HeavyItalic] [kurierhi]
-\stoptypescript
-
-\starttypescript [math] [kurier] [default]
- \definefontsynonym [Kurier-Math-Letters-Regular] [rm-kurierr]
- \definefontsynonym [Kurier-Math-Letters-Italic] [mi-kurierri]
- \definefontsynonym [Kurier-Math-Symbols-Regular] [sy-kurierrz]
- \definefontsynonym [Kurier-Math-Extension-Regular] [ex-kurierr]
+\starttypescript [bookman,bonum]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default]
+ \quittypescriptscanning
\stoptypescript
-\starttypescript [math] [kurier-light] [default]
- \definefontsynonym [Kurier-Math-Letters-Light-Regular] [rm-kurierl]
- \definefontsynonym [Kurier-Math-Letters-Light-Italic] [mi-kurierli]
- \definefontsynonym [Kurier-Math-Symbols-Light] [sy-kurierlz]
- \definefontsynonym [Kurier-Math-Extension-Light] [ex-kurierl]
+\starttypescript [chancery,chorus]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default]
+ \quittypescriptscanning
\stoptypescript
-\starttypescript [math] [kurier-medium] [default]
- \definefontsynonym [Kurier-Math-Letters-Medium-Regular] [rm-kurierm]
- \definefontsynonym [Kurier-Math-Letters-Medium-Italic] [mi-kuriermi]
- \definefontsynonym [Kurier-Math-Symbols-Medium-Regular] [sy-kuriermz]
- \definefontsynonym [Kurier-Math-Extension-Medium] [ex-kurierm]
+\starttypescript [iwona,iwona-light,iwona-heavy,iwona-medium]
+ \definetypeface[\typescriptone][ss][sans] [\typescriptone] [default]
+ \definetypeface[\typescriptone][rm][serif][modern] [default]
+ \definetypeface[\typescriptone][tt][mono] [modern] [default]
+ \definetypeface[\typescriptone][mm][math] [\typescriptone] [default][text=ss]
+ \quittypescriptscanning
\stoptypescript
-\starttypescript [math] [kurier,kurier-light,kurier-medium] [default]
- \loadmapfile[kurier-rm.map]
- \loadmapfile[kurier-mi.map]
- \loadmapfile[kurier-sy.map]
- \loadmapfile[kurier-ex.map]
+\starttypescript [helvetica,heros]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [rm] [serif] [modern] [default] [rscale=1.15]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [rscale=1.15]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default] [rscale=1.15]
+ \quittypescriptscanning
\stoptypescript
-% Whatever else we need:
-
-\starttypescript
- \definefontsynonym [ZapfDingbats] [uzdr]
- \definefontsynonym [RalfSmithFormalScript] [rsfs10]
- \definefontsynonym [MartinVogel] [fmvr8x]
+\starttypescript [avantgarde,adventor]
+ \definetypeface [\typescriptone] [ss] [sans] [adventor] [default]
+ \definetypeface [\typescriptone] [rm] [serif] [modern] [default] [rscale=1.15]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [rscale=1.15]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default]
+ \quittypescriptscanning
\stoptypescript
-% Temp here
-
-\starttypescript [serif] [charter]
- \definefontsynonym [Charter-Roman] [name:CharterBT-Roman] % or: [bchr8a]
- \definefontsynonym [Charter-Italic] [name:CharterBT-Italic] % or: [bchri8a]
- \definefontsynonym [Charter-Bold] [name:CharterBT-Bold] % or: [bchb8a]
- \definefontsynonym [Charter-BoldItalic] [name:CharterBT-BoldItalic] % or: [bchbi8a]
- \definefontsynonym [Charter-Slanted] [name:CharterBT-Italic] % or: [bchri8a]
- \definefontsynonym [Charter-BoldSlanted] [name:CharterBT-BoldItalic] % or: [bchbi8a]
- \definefontsynonym [Charter-Roman-Caps] [Charter-Roman] % not present
+\starttypescript [courier,cursor]
+ \definetypeface [\typescriptone] [tt] [mono] [\typescriptone] [default]
+ \definetypeface [\typescriptone] [rm] [serif] [modern] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default]
+ \definetypeface [\typescriptone] [mm] [math] [modern] [default]
+ \quittypescriptscanning
\stoptypescript
\stoptypescriptcollection
+\loadmarkfile{type-otf}
+
\endinput
diff --git a/tex/context/base/type-siz.mkii b/tex/context/base/type-siz.mkii
new file mode 100644
index 000000000..0ad737cf2
--- /dev/null
+++ b/tex/context/base/type-siz.mkii
@@ -0,0 +1,583 @@
+%D \module
+%D [ file=type-siz,
+%D version=2001.04.12,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Sizing scripts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\starttypescriptcollection[size-mkii]
+
+% todo: instead of assuming designsize we will set it explicitly (saves these
+% -1000 problems at the lua end)
+
+% cmr
+
+\starttypescript [serif] [computer-modern] [size]
+
+ \definebodyfont [12pt] [rm]
+ [tf=cmr12,
+ bf=cmbx12,
+ it=cmti12,
+ sl=cmsl12,
+ bi=cmbxti10 at 12pt,
+ bs=cmbxsl10 at 12pt,
+ sc=cmcsc10 at 12pt]
+
+ \definebodyfont [11pt] [rm]
+ [tf=cmr10 at 11pt,
+ bf=cmbx10 at 11pt,
+ sl=cmsl10 at 11pt,
+ it=cmti10 at 11pt,
+ bi=cmbxti10 at 11pt,
+ bs=cmbxsl10 at 11pt,
+ sc=cmcsc10 at 11pt]
+
+ \definebodyfont [10pt] [rm]
+ [tf=cmr10,
+ bf=cmbx10,
+ it=cmti10,
+ sl=cmsl10,
+ bi=cmbxti10,
+ bs=cmbxsl10,
+ sc=cmcsc10]
+
+ \definebodyfont [9pt] [rm]
+ [tf=cmr9,
+ bf=cmbx9,
+ it=cmti9,
+ sl=cmsl9,
+ bi=cmbxti10 at 9pt,
+ bs=cmbxsl10 at 9pt,
+ sc=cmcsc10 at 9pt]
+
+ \definebodyfont [8pt] [rm]
+ [tf=cmr8,
+ bf=cmbx8,
+ it=cmti8,
+ sl=cmsl8,
+ bi=cmbxti10 at 8pt,
+ bs=cmbxsl10 at 8pt,
+ sc=cmcsc10 at 8pt]
+
+ \definebodyfont [7pt] [rm]
+ [tf=cmr7,
+ bf=cmbx7,
+ it=cmti10 at 7pt,
+ sl=cmsl10 at 7pt,
+ bi=cmbxti10 at 7pt,
+ bs=cmbxsl10 at 7pt,
+ sc=cmcsc10 at 7pt]
+
+ \definebodyfont [6pt] [rm]
+ [tf=cmr6,
+ bf=cmbx6,
+ it=cmti10 at 6pt,
+ sl=cmsl10 at 6pt,
+ bi=cmbxti10 at 6pt,
+ bs=cmbxsl10 at 6pt,
+ sc=cmcsc10 at 6pt]
+
+ \definebodyfont [5pt] [rm]
+ [tf=cmr5,
+ bf=cmbx5,
+ it=cmti10 at 5pt,
+ sl=cmsl10 at 5pt,
+ bi=cmbxti10 at 5pt,
+ bs=cmbxsl10 at 5pt,
+ sc=cmcsc10 at 5pt]
+
+ \definebodyfont [4pt] [rm]
+ [tf=cmr10 at 4pt,
+ bf=cmbx10 at 4pt,
+ it=cmti10 at 4pt,
+ sl=cmsl10 at 4pt,
+ bi=cmbxti10 at 4pt,
+ bs=cmbxsl10 at 4pt,
+ sc=cmr10 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [rm]
+ [tf=cmr12 sa 1,
+ bf=cmbx12 sa 1,
+ it=cmti12 sa 1,
+ sl=cmsl12 sa 1,
+ bi=cmbxti10 sa 1,
+ bs=cmbxsl10 sa 1,
+ sc=cmcsc10 sa 1]
+
+\stoptypescript
+
+\starttypescript [sans] [computer-modern] [size]
+
+ \definebodyfont [12pt] [ss]
+ [tf=cmss12,
+ bf=cmssbx10 at 12pt,
+ it=cmssi12,
+ sl=cmssi12,
+ bi=cmssbx10 at 12pt,
+ bs=cmssbx10 at 12pt,
+ sc=cmss10 at 12pt]
+
+ \definebodyfont [11pt] [ss]
+ [tf=cmss10 at 11pt,
+ bf=cmssbx10 at 11pt,
+ it=cmssi10 at 11pt,
+ sl=cmssi10 at 11pt,
+ bi=cmssbx10 at 11pt,
+ bs=cmssbx10 at 11pt,
+ sc=cmss10 at 11pt]
+
+ \definebodyfont [10pt] [ss]
+ [tf=cmss10,
+ bf=cmssbx10,
+ it=cmssi10,
+ sl=cmssi10,
+ bi=cmssbx10,
+ bs=cmssbx10,
+ sc=cmss10]
+
+ \definebodyfont [9pt] [ss]
+ [tf=cmss9,
+ bf=cmssbx10 at 9pt,
+ it=cmssi9,
+ sl=cmssi9,
+ bi=cmssbx10 at 9pt,
+ bs=cmssbx10 at 9pt,
+ sc=cmss9]
+
+ \definebodyfont [8pt] [ss]
+ [tf=cmss8,
+ bf=cmssbx10 at 8pt,
+ it=cmssi8,
+ sl=cmssi8,
+ bi=cmssbx10 at 8pt,
+ bs=cmssbx10 at 8pt,
+ sc=cmss8]
+
+ \definebodyfont [7pt] [ss]
+ [tf=cmss10 at 7pt,
+ bf=cmssbx10 at 7pt,
+ it=cmssi10 at 7pt,
+ sl=cmssi10 at 7pt,
+ bs=cmssbx10 at 7pt,
+ bi=cmssbx10 at 7pt,
+ sc=cmss10 at 7pt]
+
+ \definebodyfont [6pt] [ss]
+ [tf=cmss10 at 6pt,
+ bf=cmssbx10 at 6pt,
+ it=cmssi10 at 6pt,
+ sl=cmssi10 at 6pt,
+ bs=cmssbx10 at 6pt,
+ bi=cmssbx10 at 6pt,
+ sc=cmss10 at 6pt]
+
+ \definebodyfont [5pt] [ss]
+ [tf=cmss10 at 5pt,
+ bf=cmssbx10 at 5pt,
+ it=cmssi10 at 5pt,
+ sl=cmssi10 at 5pt,
+ bs=cmssbx10 at 5pt,
+ bi=cmssbx10 at 5pt,
+ sc=cmss10 at 5pt]
+
+ \definebodyfont [4pt] [ss]
+ [tf=cmss10 at 4pt,
+ bf=cmssbx10 at 4pt,
+ it=cmssi10 at 4pt,
+ sl=cmssi10 at 4pt,
+ bs=cmssbx10 at 4pt,
+ bi=cmssbx10 at 4pt,
+ sc=cmss10 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [ss]
+ [tf=cmss12 sa 1,
+ bf=cmssbx10 sa 1,
+ it=cmssi12 sa 1,
+ sl=cmssi12 sa 1,
+ bi=cmssbx10 sa 1,
+ bs=cmssbx10 sa 1,
+ sc=cmss12 sa 1]
+
+\stoptypescript
+
+\starttypescript [mono] [computer-modern] [size]
+
+ \definebodyfont [12pt] [tt]
+ [tf=cmtt12,
+ sl=cmsltt10 at 12pt,
+ it=cmitt10 at 12pt,
+ sc=cmtcsc10 at 12pt]
+
+ \definebodyfont [9pt] [tt]
+ [tf=cmtt9,
+ sl=cmsltt10 at 9pt,
+ it=cmitt10 at 9pt,
+ sc=cmtcsc10 at 9pt]
+
+ \definebodyfont [8pt] [tt]
+ [tf=cmtt8,
+ sl=cmsltt10 at 8pt,
+ it=cmitt10 at 8pt,
+ sc=cmtcsc10 at 8pt]
+
+ \definebodyfont [11pt,10pt,7pt,6pt,5pt,4pt] [tt]
+ [tf=cmtt10 sa 1,
+ sl=cmsltt10 sa 1,
+ it=cmitt10 sa 1,
+ sc=cmtcsc10 sa 1]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [tt]
+ [tf=cmtt12 sa 1,
+ sl=cmsltt10 sa 1,
+ it=cmitt10 sa 1,
+ sc=cmtcsc10 sa 1]
+
+\stoptypescript
+
+\starttypescript [math] [modern,computer-modern,latin-modern] [size]
+
+ % hack to prevent mapping of filenames, watch the space! before
+ % latin modern came aroudn we needed this trick to make sure that
+ % we loaded the raw cmr12 etc instead of the ones mapped onto
+ % an encoding
+
+ % \definefontsynonym[xcmr12][cmr12 ]
+ % \definefontsynonym[xcmr10][cmr10 ]
+ % \definefontsynonym[xcmr9] [cmr9 ]
+ % \definefontsynonym[xcmr8] [cmr8 ]
+ % \definefontsynonym[xcmr7] [cmr7 ]
+ % \definefontsynonym[xcmr6] [cmr6 ]
+ % \definefontsynonym[xcmr5] [cmr5 ]
+
+ \definebodyfont [12pt] [mm]
+ [mr=xcmr12,
+ ex=cmex10 at 12pt,
+ mi=cmmi12,
+ sy=cmsy10 at 12pt]
+
+ \definebodyfont [11pt] [mm]
+ [mr=xcmr10 at 11pt,
+ ex=cmex10 at 11pt,
+ mi=cmmi10 at 11pt,
+ sy=cmsy10 at 11pt]
+
+ \definebodyfont [10pt] [mm]
+ [mr=xcmr10,
+ ex=cmex10,
+ mi=cmmi10,
+ sy=cmsy10]
+
+ \definebodyfont [9pt] [mm]
+ [mr=xcmr9,
+ ex=cmex10 at 9pt,
+ mi=cmmi9,
+ sy=cmsy9]
+
+ \definebodyfont [8pt] [mm]
+ [mr=xcmr8,
+ ex=cmex10 at 8pt,
+ mi=cmmi8,
+ sy=cmsy8]
+
+ \definebodyfont [7pt] [mm]
+ [mr=xcmr7,
+ ex=cmex10 at 7pt,
+ mi=cmmi7,
+ sy=cmsy7]
+
+ \definebodyfont [6pt] [mm]
+ [mr=xcmr6,
+ ex=cmex10 at 6pt,
+ mi=cmmi6,
+ sy=cmsy6]
+
+ \definebodyfont [5pt] [mm]
+ [mr=xcmr5,
+ ex=cmex10 at 5pt,
+ mi=cmmi5,
+ sy=cmsy5]
+
+ \definebodyfont [4pt] [mm]
+ [mr=xcmr5 at 4pt,
+ ex=cmex10 at 4pt,
+ mi=cmmi5 at 4pt,
+ sy=cmsy5 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
+ [mr=xcmr12 sa 1,
+ ex=cmex10 sa 1,
+ mi=cmmi12 sa 1,
+ sy=cmsy10 sa 1]
+
+\stoptypescript
+
+\starttypescript [boldmath] [modern,computer-modern,latin-modern] [size]
+
+% hack to prevent mapping of filenames, watch the space!
+
+ \definefontsynonym[xcmb12][cmbx12 ]
+ \definefontsynonym[xcmb10][cmbx10 ]
+ \definefontsynonym[xcmb9] [cmbx9 ]
+ \definefontsynonym[xcmb8] [cmbx8 ]
+ \definefontsynonym[xcmb7] [cmbx7 ]
+ \definefontsynonym[xcmb6] [cmbx6 ]
+ \definefontsynonym[xcmb5] [cmbx5 ]
+
+ \definebodyfont [12pt] [mm]
+ [mr=xcmb12,
+ ex=cmex10 at 12pt,
+ mi=cmmib10 at 12pt,
+ sy=cmbsy10 at 12pt]
+
+ \definebodyfont [11pt] [mm]
+ [mr=xcmb10 at 11pt,
+ ex=cmex10 at 11pt,
+ mi=cmmib10 at 11pt,
+ sy=cmbsy10 at 11pt]
+
+ \definebodyfont [10pt] [mm]
+ [mr=xcmb10,
+ ex=cmex10,
+ mi=cmmib10,
+ sy=cmbsy10]
+
+ \definebodyfont [9pt] [mm]
+ [mr=xcmb9,
+ ex=cmex10 at 9pt,
+ mi=cmmib10 at 9pt,
+ sy=cmbsy10 at 9pt]
+
+ \definebodyfont [8pt] [mm]
+ [mr=xcmb8,
+ ex=cmex10 at 8pt,
+ mi=cmmib7 at 8pt,
+ sy=cmbsy7 at 8pt]
+
+ \definebodyfont [7pt] [mm]
+ [mr=xcmb7,
+ ex=cmex10 at 7pt,
+ mi=cmmib7,
+ sy=cmbsy7]
+
+ \definebodyfont [6pt] [mm]
+ [mr=xcmb6,
+ ex=cmex10 at 6pt,
+ mi=cmmib5 at 6pt,
+ sy=cmbsy5 at 6pt]
+
+ \definebodyfont [5pt] [mm]
+ [mr=xcmb5,
+ ex=cmex10 at 5pt,
+ mi=cmmib5,
+ sy=cmbsy5]
+
+ \definebodyfont [4pt] [mm]
+ [mr=xcmb5 at 4pt,
+ ex=cmex10 at 4pt,
+ mi=cmmib5 at 4pt,
+ sy=cmbsy5 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
+ [mr=xcmb12 sa 1,
+ ex=cmex10 sa 1,
+ mi=cmmib10 sa 1,
+ sy=cmbsy10 sa 1]
+
+\stoptypescript
+
+\starttypescript [bfmath] [modern,computer-modern,latin-modern] [size]
+
+% hack to prevent mapping of filenames, watch the space!
+
+ \definefontsynonym[xcmb12][cmbx12 ]
+ \definefontsynonym[xcmb10][cmbx10 ]
+ \definefontsynonym[xcmb9] [cmbx9 ]
+ \definefontsynonym[xcmb8] [cmbx8 ]
+ \definefontsynonym[xcmb7] [cmbx7 ]
+ \definefontsynonym[xcmb6] [cmbx6 ]
+ \definefontsynonym[xcmb5] [cmbx5 ]
+
+ \definebodyfont [12pt] [mm]
+ [mrbf=xcmb12,
+ exbf=cmex10 at 12pt,
+ mibf=cmmib10 at 12pt,
+ sybf=cmbsy10 at 12pt]
+
+ \definebodyfont [11pt] [mm]
+ [mrbf=xcmb10 at 11pt,
+ exbf=cmex10 at 11pt,
+ mibf=cmmib10 at 11pt,
+ sybf=cmbsy10 at 11pt]
+
+ \definebodyfont [10pt] [mm]
+ [mrbf=xcmb10,
+ exbf=cmex10,
+ mibf=cmmib10,
+ sybf=cmbsy10]
+
+ \definebodyfont [9pt] [mm]
+ [mrbf=xcmb9,
+ exbf=cmex10 at 9pt,
+ mibf=cmmib10 at 9pt,
+ sybf=cmbsy10 at 9pt]
+
+ \definebodyfont [8pt] [mm]
+ [mrbf=xcmb8,
+ exbf=cmex10 at 8pt,
+ mibf=cmmib7 at 8pt,
+ sybf=cmbsy7 at 8pt]
+
+ \definebodyfont [7pt] [mm]
+ [mrbf=xcmb7,
+ exbf=cmex10 at 7pt,
+ mibf=cmmib7,
+ sybf=cmbsy7]
+
+ \definebodyfont [6pt] [mm]
+ [mrbf=xcmb6,
+ exbf=cmex10 at 6pt,
+ mibf=cmmib5 at 6pt,
+ sybf=cmbsy5 at 6pt]
+
+ \definebodyfont [5pt] [mm]
+ [mrbf=xcmb5,
+ exbf=cmex10 at 5pt,
+ mibf=cmmib5,
+ sybf=cmbsy5]
+
+ \definebodyfont [4pt] [mm]
+ [mrbf=xcmb5 at 4pt,
+ exbf=cmex10 at 4pt,
+ mibf=cmmib5 at 4pt,
+ sybf=cmbsy5 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
+ [mrbf=xcmb12 sa 1,
+ exbf=cmex10 sa 1,
+ mibf=cmmib10 sa 1,
+ sybf=cmbsy10 sa 1]
+
+\stoptypescript
+
+\starttypescript [serif] [concrete] [size]
+
+ \definebodyfont [10pt,11pt,12pt,14.4pt,17.3pt] [rm]
+ [tf=ccr10 sa 1,
+ it=ccti10 sa 1,
+ sl=ccsl10 sa 1,
+ sc=cccsc10 sa 1]
+
+ \definebodyfont [5pt,6pt,7pt,8pt,9pt] [rm]
+ [it=ccr9 sa 1,
+ sl=ccr9 sa 1,
+ sc=ccr9 sa 1]
+
+ \definebodyfont [9pt] [rm] [tf=ccr9]
+ \definebodyfont [8pt] [rm] [tf=ccr8]
+ \definebodyfont [7pt] [rm] [tf=ccr7]
+ \definebodyfont [6pt] [rm] [tf=ccr6]
+ \definebodyfont [5pt] [rm] [tf=ccr5]
+
+\stoptypescript
+
+\starttypescript [math] [euler] [size]
+
+ \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
+ [mr=zeurm10 sa 1,
+ ex=zeuex10 sa 1,
+ sy=zeusm10 sa 1,
+ mi=eufm10 sa 1]
+
+ \definebodyfont [6pt,7pt,8pt] [mm]
+ [mr=zeurm7 sa 1,
+ sy=zeusm7 sa 1,
+ mi=eufm7 sa 1,
+ ex=zeuex10 sa 1]
+
+ \definebodyfont [5pt] [mm]
+ [mr=zeurm5,
+ sy=zeusm5,
+ mi=eufm5,
+ ex=zeuex10 at 5pt]
+
+\stoptypescript
+
+\starttypescript [bfmath] [euler] [size]
+
+ \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
+ [mrbf=zeurb10 sa 1,
+ exbf=zeuex10 sa 1,
+ sybf=zeusb10 sa 1,
+ mibf=eufb10 sa 1]
+
+ \definebodyfont [6pt,7pt,8pt] [mm]
+ [mrbf=zeurb7 sa 1,
+ sybf=zeusb7 sa 1,
+ mibf=eufb7 sa 1,
+ exbf=zeuex10 sa 1]
+
+ \definebodyfont [5pt] [mm]
+ [mrbf=zeurb5,
+ sybf=zeusb5,
+ mibf=eufb5,
+ exbf=zeuex10 at 5pt]
+
+\stoptypescript
+
+\starttypescript [boldmath] [euler] [size]
+
+ \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
+ [mr=zeurb10 sa 1,
+ ex=zeuex10 sa 1,
+ sy=zeusb10 sa 1,
+ mi=eufb10 sa 1]
+
+ \definebodyfont [6pt,7pt,8pt] [mm]
+ [mr=zeurb7 sa 1,
+ sy=zeusb7 sa 1,
+ mi=eufb7 sa 1,
+ ex=zeuex10 sa 1]
+
+ \definebodyfont [5pt] [mm]
+ [mr=zeurb5,
+ sy=zeusb5,
+ mi=eufb5,
+ ex=zeuex10 at 5pt]
+
+\stoptypescript
+
+\starttypescript [math] [modern,computer-modern,latin-modern,ams] [size]
+ \definebodyfont [17.3pt,14.4pt,12pt,11pt,10pt,9pt] [mm]
+ [ma=msam10 sa 1,
+ mb=msbm10 sa 1]
+ \definebodyfont [8pt,7pt] [mm]
+ [ma=msam7 sa 1,
+ mb=msbm7 sa 1]
+ \definebodyfont [6pt,5pt,4pt] [mm]
+ [ma=msam5 sa 1,
+ mb=msbm5 sa 1]
+\stoptypescript
+
+\starttypescript [math] [times] [size]
+
+ \mapfontsize [5pt] [6.0pt]
+ \mapfontsize [6pt] [6.8pt]
+ \mapfontsize [7pt] [7.6pt]
+ \mapfontsize [8pt] [8.4pt]
+ \mapfontsize [9pt] [9.2pt]
+ \mapfontsize [10pt] [10pt]
+ \mapfontsize [11pt] [10.8pt]
+ \mapfontsize [12pt] [11.6pt]
+ \mapfontsize [14.4pt] [13.2pt]
+
+\stoptypescript
+
+\stoptypescriptcollection
+
+\endinput
diff --git a/tex/context/base/type-siz.mkiv b/tex/context/base/type-siz.mkiv
new file mode 100644
index 000000000..2c234e86a
--- /dev/null
+++ b/tex/context/base/type-siz.mkiv
@@ -0,0 +1,375 @@
+%D \module
+%D [ file=type-siz,
+%D version=2001.04.12,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=Sizing scripts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\starttypescriptcollection[size-mkiv]
+
+% todo: instead of assuming designsize we will set it explicitly (saves these
+% -1000 problems at the lua end)
+
+% cmr
+
+\starttypescript [serif] [computer-modern] [size]
+
+ \definebodyfont [12pt] [rm]
+ [tf=cmr12,
+ bf=cmbx12,
+ it=cmti12,
+ sl=cmsl12,
+ bi=cmbxti10 at 12pt,
+ bs=cmbxsl10 at 12pt,
+ sc=cmcsc10 at 12pt]
+
+ \definebodyfont [11pt] [rm]
+ [tf=cmr10 at 11pt,
+ bf=cmbx10 at 11pt,
+ sl=cmsl10 at 11pt,
+ it=cmti10 at 11pt,
+ bi=cmbxti10 at 11pt,
+ bs=cmbxsl10 at 11pt,
+ sc=cmcsc10 at 11pt]
+
+ \definebodyfont [10pt] [rm]
+ [tf=cmr10,
+ bf=cmbx10,
+ it=cmti10,
+ sl=cmsl10,
+ bi=cmbxti10,
+ bs=cmbxsl10,
+ sc=cmcsc10]
+
+ \definebodyfont [9pt] [rm]
+ [tf=cmr9,
+ bf=cmbx9,
+ it=cmti9,
+ sl=cmsl9,
+ bi=cmbxti10 at 9pt,
+ bs=cmbxsl10 at 9pt,
+ sc=cmcsc10 at 9pt]
+
+ \definebodyfont [8pt] [rm]
+ [tf=cmr8,
+ bf=cmbx8,
+ it=cmti8,
+ sl=cmsl8,
+ bi=cmbxti10 at 8pt,
+ bs=cmbxsl10 at 8pt,
+ sc=cmcsc10 at 8pt]
+
+ \definebodyfont [7pt] [rm]
+ [tf=cmr7,
+ bf=cmbx7,
+ it=cmti10 at 7pt,
+ sl=cmsl10 at 7pt,
+ bi=cmbxti10 at 7pt,
+ bs=cmbxsl10 at 7pt,
+ sc=cmcsc10 at 7pt]
+
+ \definebodyfont [6pt] [rm]
+ [tf=cmr6,
+ bf=cmbx6,
+ it=cmti10 at 6pt,
+ sl=cmsl10 at 6pt,
+ bi=cmbxti10 at 6pt,
+ bs=cmbxsl10 at 6pt,
+ sc=cmcsc10 at 6pt]
+
+ \definebodyfont [5pt] [rm]
+ [tf=cmr5,
+ bf=cmbx5,
+ it=cmti10 at 5pt,
+ sl=cmsl10 at 5pt,
+ bi=cmbxti10 at 5pt,
+ bs=cmbxsl10 at 5pt,
+ sc=cmcsc10 at 5pt]
+
+ \definebodyfont [4pt] [rm]
+ [tf=cmr10 at 4pt,
+ bf=cmbx10 at 4pt,
+ it=cmti10 at 4pt,
+ sl=cmsl10 at 4pt,
+ bi=cmbxti10 at 4pt,
+ bs=cmbxsl10 at 4pt,
+ sc=cmr10 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [rm]
+ [tf=cmr12 sa 1,
+ bf=cmbx12 sa 1,
+ it=cmti12 sa 1,
+ sl=cmsl12 sa 1,
+ bi=cmbxti10 sa 1,
+ bs=cmbxsl10 sa 1,
+ sc=cmcsc10 sa 1]
+
+\stoptypescript
+
+\starttypescript [sans] [computer-modern] [size]
+
+ \definebodyfont [12pt] [ss]
+ [tf=cmss12,
+ bf=cmssbx10 at 12pt,
+ it=cmssi12,
+ sl=cmssi12,
+ bi=cmssbx10 at 12pt,
+ bs=cmssbx10 at 12pt,
+ sc=cmss10 at 12pt]
+
+ \definebodyfont [11pt] [ss]
+ [tf=cmss10 at 11pt,
+ bf=cmssbx10 at 11pt,
+ it=cmssi10 at 11pt,
+ sl=cmssi10 at 11pt,
+ bi=cmssbx10 at 11pt,
+ bs=cmssbx10 at 11pt,
+ sc=cmss10 at 11pt]
+
+ \definebodyfont [10pt] [ss]
+ [tf=cmss10,
+ bf=cmssbx10,
+ it=cmssi10,
+ sl=cmssi10,
+ bi=cmssbx10,
+ bs=cmssbx10,
+ sc=cmss10]
+
+ \definebodyfont [9pt] [ss]
+ [tf=cmss9,
+ bf=cmssbx10 at 9pt,
+ it=cmssi9,
+ sl=cmssi9,
+ bi=cmssbx10 at 9pt,
+ bs=cmssbx10 at 9pt,
+ sc=cmss9]
+
+ \definebodyfont [8pt] [ss]
+ [tf=cmss8,
+ bf=cmssbx10 at 8pt,
+ it=cmssi8,
+ sl=cmssi8,
+ bi=cmssbx10 at 8pt,
+ bs=cmssbx10 at 8pt,
+ sc=cmss8]
+
+ \definebodyfont [7pt] [ss]
+ [tf=cmss10 at 7pt,
+ bf=cmssbx10 at 7pt,
+ it=cmssi10 at 7pt,
+ sl=cmssi10 at 7pt,
+ bs=cmssbx10 at 7pt,
+ bi=cmssbx10 at 7pt,
+ sc=cmss10 at 7pt]
+
+ \definebodyfont [6pt] [ss]
+ [tf=cmss10 at 6pt,
+ bf=cmssbx10 at 6pt,
+ it=cmssi10 at 6pt,
+ sl=cmssi10 at 6pt,
+ bs=cmssbx10 at 6pt,
+ bi=cmssbx10 at 6pt,
+ sc=cmss10 at 6pt]
+
+ \definebodyfont [5pt] [ss]
+ [tf=cmss10 at 5pt,
+ bf=cmssbx10 at 5pt,
+ it=cmssi10 at 5pt,
+ sl=cmssi10 at 5pt,
+ bs=cmssbx10 at 5pt,
+ bi=cmssbx10 at 5pt,
+ sc=cmss10 at 5pt]
+
+ \definebodyfont [4pt] [ss]
+ [tf=cmss10 at 4pt,
+ bf=cmssbx10 at 4pt,
+ it=cmssi10 at 4pt,
+ sl=cmssi10 at 4pt,
+ bs=cmssbx10 at 4pt,
+ bi=cmssbx10 at 4pt,
+ sc=cmss10 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [ss]
+ [tf=cmss12 sa 1,
+ bf=cmssbx10 sa 1,
+ it=cmssi12 sa 1,
+ sl=cmssi12 sa 1,
+ bi=cmssbx10 sa 1,
+ bs=cmssbx10 sa 1,
+ sc=cmss12 sa 1]
+
+\stoptypescript
+
+\starttypescript [mono] [computer-modern] [size]
+
+ \definebodyfont [12pt] [tt]
+ [tf=cmtt12,
+ sl=cmsltt10 at 12pt,
+ it=cmitt10 at 12pt,
+ sc=cmtcsc10 at 12pt]
+
+ \definebodyfont [9pt] [tt]
+ [tf=cmtt9,
+ sl=cmsltt10 at 9pt,
+ it=cmitt10 at 9pt,
+ sc=cmtcsc10 at 9pt]
+
+ \definebodyfont [8pt] [tt]
+ [tf=cmtt8,
+ sl=cmsltt10 at 8pt,
+ it=cmitt10 at 8pt,
+ sc=cmtcsc10 at 8pt]
+
+ \definebodyfont [11pt,10pt,7pt,6pt,5pt,4pt] [tt]
+ [tf=cmtt10 sa 1,
+ sl=cmsltt10 sa 1,
+ it=cmitt10 sa 1,
+ sc=cmtcsc10 sa 1]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [tt]
+ [tf=cmtt12 sa 1,
+ sl=cmsltt10 sa 1,
+ it=cmitt10 sa 1,
+ sc=cmtcsc10 sa 1]
+
+\stoptypescript
+
+\starttypescript [math] [modern,computer-modern,latin-modern] [size]
+
+ \definebodyfont [12pt] [mm]
+ [mr=xcmr12]
+
+ \definebodyfont [11pt] [mm]
+ [mr=xcmr10 at 11pt]
+
+ \definebodyfont [10pt] [mm]
+ [mr=xcmr10]
+
+ \definebodyfont [9pt] [mm]
+ [mr=xcmr9]
+
+ \definebodyfont [8pt] [mm]
+ [mr=xcmr8]
+
+ \definebodyfont [7pt] [mm]
+ [mr=xcmr7]
+
+ \definebodyfont [6pt] [mm]
+ [mr=xcmr6]
+
+ \definebodyfont [5pt] [mm]
+ [mr=xcmr5]
+
+ \definebodyfont [4pt] [mm]
+ [mr=xcmr5 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
+ [mr=xcmr12 sa 1]
+
+\stoptypescript
+
+\starttypescript [boldmath] [modern,computer-modern,latin-modern] [size]
+
+ \definebodyfont [12pt] [mm] [mr=xcmb12]
+ \definebodyfont [11pt] [mm] [mr=xcmb10 at 11pt]
+ \definebodyfont [10pt] [mm] [mr=xcmb10]
+ \definebodyfont [9pt] [mm] [mr=xcmb9]
+ \definebodyfont [8pt] [mm] [mr=xcmb8]
+ \definebodyfont [7pt] [mm] [mr=xcmb7]
+ \definebodyfont [6pt] [mm] [mr=xcmb6]
+ \definebodyfont [5pt] [mm] [mr=xcmb5]
+ \definebodyfont [4pt] [mm] [mr=xcmb5 at 4pt]
+
+ \definebodyfont [14.4pt,17.3pt,20.7pt] [mm] [mr=xcmb12 sa 1]
+
+\stoptypescript
+
+\starttypescript [math] [euler] [size]
+
+ \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
+ [mr=zeurm10 sa 1,
+ ex=zeuex10 sa 1,
+ sy=zeusm10 sa 1,
+ mi=eufm10 sa 1]
+
+ \definebodyfont [6pt,7pt,8pt] [mm]
+ [mr=zeurm7 sa 1,
+ sy=zeusm7 sa 1,
+ mi=eufm7 sa 1,
+ ex=zeuex10 sa 1]
+
+ \definebodyfont [5pt] [mm]
+ [mr=zeurm5,
+ sy=zeusm5,
+ mi=eufm5,
+ ex=zeuex10 at 5pt]
+
+\stoptypescript
+
+\starttypescript [bfmath] [euler] [size]
+
+ \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
+ [mrbf=zeurb10 sa 1,
+ exbf=zeuex10 sa 1,
+ sybf=zeusb10 sa 1,
+ mibf=eufb10 sa 1]
+
+ \definebodyfont [6pt,7pt,8pt] [mm]
+ [mrbf=zeurb7 sa 1,
+ sybf=zeusb7 sa 1,
+ mibf=eufb7 sa 1,
+ exbf=zeuex10 sa 1]
+
+ \definebodyfont [5pt] [mm]
+ [mrbf=zeurb5,
+ sybf=zeusb5,
+ mibf=eufb5,
+ exbf=zeuex10 at 5pt]
+
+\stoptypescript
+
+\starttypescript [boldmath] [euler] [size]
+
+ \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
+ [mr=zeurb10 sa 1,
+ ex=zeuex10 sa 1,
+ sy=zeusb10 sa 1,
+ mi=eufb10 sa 1]
+
+ \definebodyfont [6pt,7pt,8pt] [mm]
+ [mr=zeurb7 sa 1,
+ sy=zeusb7 sa 1,
+ mi=eufb7 sa 1,
+ ex=zeuex10 sa 1]
+
+ \definebodyfont [5pt] [mm]
+ [mr=zeurb5,
+ sy=zeusb5,
+ mi=eufb5,
+ ex=zeuex10 at 5pt]
+
+\stoptypescript
+
+\starttypescript [math] [times] [size]
+
+ \mapfontsize [5pt] [6.0pt]
+ \mapfontsize [6pt] [6.8pt]
+ \mapfontsize [7pt] [7.6pt]
+ \mapfontsize [8pt] [8.4pt]
+ \mapfontsize [9pt] [9.2pt]
+ \mapfontsize [10pt] [10pt]
+ \mapfontsize [11pt] [10.8pt]
+ \mapfontsize [12pt] [11.6pt]
+ \mapfontsize [14.4pt] [13.2pt]
+
+\stoptypescript
+
+\stoptypescriptcollection
+
+\endinput
diff --git a/tex/context/base/type-siz.tex b/tex/context/base/type-siz.tex
index c5a8753ca..56b54b301 100644
--- a/tex/context/base/type-siz.tex
+++ b/tex/context/base/type-siz.tex
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% we need to use proper verbose names, which saves us a resolve
+
\unprotect
\starttypescriptcollection[size]
@@ -168,688 +170,10 @@
[mm] [default]
\stoptypescript
-% todo: instead of assuming designsize we will set it explicitly (saves these
-% -1000 problems at the lua end)
-
-% cmr
-
-\starttypescript [serif] [computer-modern] [size]
-
- \definebodyfont [12pt] [rm]
- [tf=cmr12,
- bf=cmbx12,
- it=cmti12,
- sl=cmsl12,
- bi=cmbxti10 at 12pt,
- bs=cmbxsl10 at 12pt,
- sc=cmcsc10 at 12pt]
-
- \definebodyfont [11pt] [rm]
- [tf=cmr10 at 11pt,
- bf=cmbx10 at 11pt,
- sl=cmsl10 at 11pt,
- it=cmti10 at 11pt,
- bi=cmbxti10 at 11pt,
- bs=cmbxsl10 at 11pt,
- sc=cmcsc10 at 11pt]
-
- \definebodyfont [10pt] [rm]
- [tf=cmr10,
- bf=cmbx10,
- it=cmti10,
- sl=cmsl10,
- bi=cmbxti10,
- bs=cmbxsl10,
- sc=cmcsc10]
-
- \definebodyfont [9pt] [rm]
- [tf=cmr9,
- bf=cmbx9,
- it=cmti9,
- sl=cmsl9,
- bi=cmbxti10 at 9pt,
- bs=cmbxsl10 at 9pt,
- sc=cmcsc10 at 9pt]
-
- \definebodyfont [8pt] [rm]
- [tf=cmr8,
- bf=cmbx8,
- it=cmti8,
- sl=cmsl8,
- bi=cmbxti10 at 8pt,
- bs=cmbxsl10 at 8pt,
- sc=cmcsc10 at 8pt]
-
- \definebodyfont [7pt] [rm]
- [tf=cmr7,
- bf=cmbx7,
- it=cmti10 at 7pt,
- sl=cmsl10 at 7pt,
- bi=cmbxti10 at 7pt,
- bs=cmbxsl10 at 7pt,
- sc=cmcsc10 at 7pt]
-
- \definebodyfont [6pt] [rm]
- [tf=cmr6,
- bf=cmbx6,
- it=cmti10 at 6pt,
- sl=cmsl10 at 6pt,
- bi=cmbxti10 at 6pt,
- bs=cmbxsl10 at 6pt,
- sc=cmcsc10 at 6pt]
-
- \definebodyfont [5pt] [rm]
- [tf=cmr5,
- bf=cmbx5,
- it=cmti10 at 5pt,
- sl=cmsl10 at 5pt,
- bi=cmbxti10 at 5pt,
- bs=cmbxsl10 at 5pt,
- sc=cmcsc10 at 5pt]
-
- \definebodyfont [4pt] [rm]
- [tf=cmr10 at 4pt,
- bf=cmbx10 at 4pt,
- it=cmti10 at 4pt,
- sl=cmsl10 at 4pt,
- bi=cmbxti10 at 4pt,
- bs=cmbxsl10 at 4pt,
- sc=cmr10 at 4pt]
-
- \definebodyfont [14.4pt,17.3pt,20.7pt] [rm]
- [tf=cmr12 sa 1,
- bf=cmbx12 sa 1,
- it=cmti12 sa 1,
- sl=cmsl12 sa 1,
- bi=cmbxti10 sa 1,
- bs=cmbxsl10 sa 1,
- sc=cmcsc10 sa 1]
-
-\stoptypescript
-
-\starttypescript [sans] [computer-modern] [size]
-
- \definebodyfont [12pt] [ss]
- [tf=cmss12,
- bf=cmssbx10 at 12pt,
- it=cmssi12,
- sl=cmssi12,
- bi=cmssbx10 at 12pt,
- bs=cmssbx10 at 12pt,
- sc=cmss10 at 12pt]
-
- \definebodyfont [11pt] [ss]
- [tf=cmss10 at 11pt,
- bf=cmssbx10 at 11pt,
- it=cmssi10 at 11pt,
- sl=cmssi10 at 11pt,
- bi=cmssbx10 at 11pt,
- bs=cmssbx10 at 11pt,
- sc=cmss10 at 11pt]
-
- \definebodyfont [10pt] [ss]
- [tf=cmss10,
- bf=cmssbx10,
- it=cmssi10,
- sl=cmssi10,
- bi=cmssbx10,
- bs=cmssbx10,
- sc=cmss10]
-
- \definebodyfont [9pt] [ss]
- [tf=cmss9,
- bf=cmssbx10 at 9pt,
- it=cmssi9,
- sl=cmssi9,
- bi=cmssbx10 at 9pt,
- bs=cmssbx10 at 9pt,
- sc=cmss9]
-
- \definebodyfont [8pt] [ss]
- [tf=cmss8,
- bf=cmssbx10 at 8pt,
- it=cmssi8,
- sl=cmssi8,
- bi=cmssbx10 at 8pt,
- bs=cmssbx10 at 8pt,
- sc=cmss8]
-
- \definebodyfont [7pt] [ss]
- [tf=cmss10 at 7pt,
- bf=cmssbx10 at 7pt,
- it=cmssi10 at 7pt,
- sl=cmssi10 at 7pt,
- bs=cmssbx10 at 7pt,
- bi=cmssbx10 at 7pt,
- sc=cmss10 at 7pt]
-
- \definebodyfont [6pt] [ss]
- [tf=cmss10 at 6pt,
- bf=cmssbx10 at 6pt,
- it=cmssi10 at 6pt,
- sl=cmssi10 at 6pt,
- bs=cmssbx10 at 6pt,
- bi=cmssbx10 at 6pt,
- sc=cmss10 at 6pt]
-
- \definebodyfont [5pt] [ss]
- [tf=cmss10 at 5pt,
- bf=cmssbx10 at 5pt,
- it=cmssi10 at 5pt,
- sl=cmssi10 at 5pt,
- bs=cmssbx10 at 5pt,
- bi=cmssbx10 at 5pt,
- sc=cmss10 at 5pt]
-
- \definebodyfont [4pt] [ss]
- [tf=cmss10 at 4pt,
- bf=cmssbx10 at 4pt,
- it=cmssi10 at 4pt,
- sl=cmssi10 at 4pt,
- bs=cmssbx10 at 4pt,
- bi=cmssbx10 at 4pt,
- sc=cmss10 at 4pt]
-
- \definebodyfont [14.4pt,17.3pt,20.7pt] [ss]
- [tf=cmss12 sa 1,
- bf=cmssbx10 sa 1,
- it=cmssi12 sa 1,
- sl=cmssi12 sa 1,
- bi=cmssbx10 sa 1,
- bs=cmssbx10 sa 1,
- sc=cmss12 sa 1]
-
-\stoptypescript
-
-\starttypescript [mono] [computer-modern] [size]
-
- \definebodyfont [12pt] [tt]
- [tf=cmtt12,
- sl=cmsltt10 at 12pt,
- it=cmitt10 at 12pt,
- sc=cmtcsc10 at 12pt]
-
- \definebodyfont [9pt] [tt]
- [tf=cmtt9,
- sl=cmsltt10 at 9pt,
- it=cmitt10 at 9pt,
- sc=cmtcsc10 at 9pt]
-
- \definebodyfont [8pt] [tt]
- [tf=cmtt8,
- sl=cmsltt10 at 8pt,
- it=cmitt10 at 8pt,
- sc=cmtcsc10 at 8pt]
-
- \definebodyfont [11pt,10pt,7pt,6pt,5pt,4pt] [tt]
- [tf=cmtt10 sa 1,
- sl=cmsltt10 sa 1,
- it=cmitt10 sa 1,
- sc=cmtcsc10 sa 1]
-
- \definebodyfont [14.4pt,17.3pt,20.7pt] [tt]
- [tf=cmtt12 sa 1,
- sl=cmsltt10 sa 1,
- it=cmitt10 sa 1,
- sc=cmtcsc10 sa 1]
-
-\stoptypescript
-
-\starttypescript [math] [modern,computer-modern,latin-modern] [size]
-
- % hack to prevent mapping of filenames, watch the space! before
- % latin modern came aroudn we needed this trick to make sure that
- % we loaded the raw cmr12 etc instead of the ones mapped onto
- % an encoding
-
- % \definefontsynonym[xcmr12][cmr12 ]
- % \definefontsynonym[xcmr10][cmr10 ]
- % \definefontsynonym[xcmr9] [cmr9 ]
- % \definefontsynonym[xcmr8] [cmr8 ]
- % \definefontsynonym[xcmr7] [cmr7 ]
- % \definefontsynonym[xcmr6] [cmr6 ]
- % \definefontsynonym[xcmr5] [cmr5 ]
-
- \definebodyfont [12pt] [mm]
- [mr=xcmr12,
- ex=cmex10 at 12pt,
- mi=cmmi12,
- sy=cmsy10 at 12pt]
-
- \definebodyfont [11pt] [mm]
- [mr=xcmr10 at 11pt,
- ex=cmex10 at 11pt,
- mi=cmmi10 at 11pt,
- sy=cmsy10 at 11pt]
-
- \definebodyfont [10pt] [mm]
- [mr=xcmr10,
- ex=cmex10,
- mi=cmmi10,
- sy=cmsy10]
-
- \definebodyfont [9pt] [mm]
- [mr=xcmr9,
- ex=cmex10 at 9pt,
- mi=cmmi9,
- sy=cmsy9]
-
- \definebodyfont [8pt] [mm]
- [mr=xcmr8,
- ex=cmex10 at 8pt,
- mi=cmmi8,
- sy=cmsy8]
-
- \definebodyfont [7pt] [mm]
- [mr=xcmr7,
- ex=cmex10 at 7pt,
- mi=cmmi7,
- sy=cmsy7]
-
- \definebodyfont [6pt] [mm]
- [mr=xcmr6,
- ex=cmex10 at 6pt,
- mi=cmmi6,
- sy=cmsy6]
-
- \definebodyfont [5pt] [mm]
- [mr=xcmr5,
- ex=cmex10 at 5pt,
- mi=cmmi5,
- sy=cmsy5]
-
- \definebodyfont [4pt] [mm]
- [mr=xcmr5 at 4pt,
- ex=cmex10 at 4pt,
- mi=cmmi5 at 4pt,
- sy=cmsy5 at 4pt]
-
- \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
- [mr=xcmr12 sa 1,
- ex=cmex10 sa 1,
- mi=cmmi12 sa 1,
- sy=cmsy10 sa 1]
-
-\stoptypescript
-
-\starttypescript [boldmath] [modern,computer-modern,latin-modern] [size]
-
-% hack to prevent mapping of filenames, watch the space!
-
- \definefontsynonym[xcmb12][cmbx12 ]
- \definefontsynonym[xcmb10][cmbx10 ]
- \definefontsynonym[xcmb9] [cmbx9 ]
- \definefontsynonym[xcmb8] [cmbx8 ]
- \definefontsynonym[xcmb7] [cmbx7 ]
- \definefontsynonym[xcmb6] [cmbx6 ]
- \definefontsynonym[xcmb5] [cmbx5 ]
-
- \definebodyfont [12pt] [mm]
- [mr=xcmb12,
- ex=cmex10 at 12pt,
- mi=cmmib10 at 12pt,
- sy=cmbsy10 at 12pt]
-
- \definebodyfont [11pt] [mm]
- [mr=xcmb10 at 11pt,
- ex=cmex10 at 11pt,
- mi=cmmib10 at 11pt,
- sy=cmbsy10 at 11pt]
-
- \definebodyfont [10pt] [mm]
- [mr=xcmb10,
- ex=cmex10,
- mi=cmmib10,
- sy=cmbsy10]
-
- \definebodyfont [9pt] [mm]
- [mr=xcmb9,
- ex=cmex10 at 9pt,
- mi=cmmib10 at 9pt,
- sy=cmbsy10 at 9pt]
-
- \definebodyfont [8pt] [mm]
- [mr=xcmb8,
- ex=cmex10 at 8pt,
- mi=cmmib7 at 8pt,
- sy=cmbsy7 at 8pt]
-
- \definebodyfont [7pt] [mm]
- [mr=xcmb7,
- ex=cmex10 at 7pt,
- mi=cmmib7,
- sy=cmbsy7]
-
- \definebodyfont [6pt] [mm]
- [mr=xcmb6,
- ex=cmex10 at 6pt,
- mi=cmmib5 at 6pt,
- sy=cmbsy5 at 6pt]
-
- \definebodyfont [5pt] [mm]
- [mr=xcmb5,
- ex=cmex10 at 5pt,
- mi=cmmib5,
- sy=cmbsy5]
-
- \definebodyfont [4pt] [mm]
- [mr=xcmb5 at 4pt,
- ex=cmex10 at 4pt,
- mi=cmmib5 at 4pt,
- sy=cmbsy5 at 4pt]
-
- \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
- [mr=xcmb12 sa 1,
- ex=cmex10 sa 1,
- mi=cmmib10 sa 1,
- sy=cmbsy10 sa 1]
-
-\stoptypescript
-
-\starttypescript [bfmath] [modern,computer-modern,latin-modern] [size]
-
-% hack to prevent mapping of filenames, watch the space!
-
- \definefontsynonym[xcmb12][cmbx12 ]
- \definefontsynonym[xcmb10][cmbx10 ]
- \definefontsynonym[xcmb9] [cmbx9 ]
- \definefontsynonym[xcmb8] [cmbx8 ]
- \definefontsynonym[xcmb7] [cmbx7 ]
- \definefontsynonym[xcmb6] [cmbx6 ]
- \definefontsynonym[xcmb5] [cmbx5 ]
-
- \definebodyfont [12pt] [mm]
- [mrbf=xcmb12,
- exbf=cmex10 at 12pt,
- mibf=cmmib10 at 12pt,
- sybf=cmbsy10 at 12pt]
-
- \definebodyfont [11pt] [mm]
- [mrbf=xcmb10 at 11pt,
- exbf=cmex10 at 11pt,
- mibf=cmmib10 at 11pt,
- sybf=cmbsy10 at 11pt]
-
- \definebodyfont [10pt] [mm]
- [mrbf=xcmb10,
- exbf=cmex10,
- mibf=cmmib10,
- sybf=cmbsy10]
-
- \definebodyfont [9pt] [mm]
- [mrbf=xcmb9,
- exbf=cmex10 at 9pt,
- mibf=cmmib10 at 9pt,
- sybf=cmbsy10 at 9pt]
-
- \definebodyfont [8pt] [mm]
- [mrbf=xcmb8,
- exbf=cmex10 at 8pt,
- mibf=cmmib7 at 8pt,
- sybf=cmbsy7 at 8pt]
-
- \definebodyfont [7pt] [mm]
- [mrbf=xcmb7,
- exbf=cmex10 at 7pt,
- mibf=cmmib7,
- sybf=cmbsy7]
-
- \definebodyfont [6pt] [mm]
- [mrbf=xcmb6,
- exbf=cmex10 at 6pt,
- mibf=cmmib5 at 6pt,
- sybf=cmbsy5 at 6pt]
-
- \definebodyfont [5pt] [mm]
- [mrbf=xcmb5,
- exbf=cmex10 at 5pt,
- mibf=cmmib5,
- sybf=cmbsy5]
-
- \definebodyfont [4pt] [mm]
- [mrbf=xcmb5 at 4pt,
- exbf=cmex10 at 4pt,
- mibf=cmmib5 at 4pt,
- sybf=cmbsy5 at 4pt]
-
- \definebodyfont [14.4pt,17.3pt,20.7pt] [mm]
- [mrbf=xcmb12 sa 1,
- exbf=cmex10 sa 1,
- mibf=cmmib10 sa 1,
- sybf=cmbsy10 sa 1]
-
-\stoptypescript
-
-\starttypescript [serif] [concrete] [size]
-
- \definebodyfont [10pt,11pt,12pt,14.4pt,17.3pt] [rm]
- [tf=ccr10 sa 1,
- it=ccti10 sa 1,
- sl=ccsl10 sa 1,
- sc=cccsc10 sa 1]
-
- \definebodyfont [5pt,6pt,7pt,8pt,9pt] [rm]
- [it=ccr9 sa 1,
- sl=ccr9 sa 1,
- sc=ccr9 sa 1]
-
- \definebodyfont [9pt] [rm] [tf=ccr9]
- \definebodyfont [8pt] [rm] [tf=ccr8]
- \definebodyfont [7pt] [rm] [tf=ccr7]
- \definebodyfont [6pt] [rm] [tf=ccr6]
- \definebodyfont [5pt] [rm] [tf=ccr5]
-
-\stoptypescript
-
-% \starttypescript [serif] [fourier] [size] % experimental
-
-% \definebodyfont
-% [17.3pt,14.4pt,12pt,11pt,10pt,9pt,8pt,7pt,6pt,5pt,4pt]
-% [rm]
-% [bc=SerifBoldCaps sa 1,
-% bca=SerifBoldCaps sa a,
-% bcb=SerifBoldCaps sa b,
-% bcc=SerifBoldCaps sa c,
-% bcd=SerifBoldCaps sa d,
-% bcx=SerifBoldCaps sa x,
-% bcxx=SerifBoldCaps sa xx]
-
-% \stoptypescript
-
-% \starttypescript [serif] [fourier-expert] [size] % experimental
-
-% \definebodyfont
-% [17.3pt,14.4pt,12pt,11pt,10pt,9pt,8pt,7pt,6pt,5pt,4pt]
-% [rm]
-% [tf=Serif-Expert sa 1,
-% it=SerifItalic-Expert sa 1,
-% sl=SerifSlanted-Expert sa 1,
-% sc=SerifCaps-Expert sa 1,
-% db=SerifSemiBold-Expert sa 1,
-% dba=SerifSemiBold-Expert sa a,
-% dbb=SerifSemiBold-Expert sa b,
-% dbc=SerifSemiBold-Expert sa c,
-% dbd=SerifSemiBold-Expert sa d,
-% dbx=SerifSemiBold-Expert sa x,
-% dbxx=SerifSemiBold-Expert sa xx,
-% di=SerifSemiItalic-Expert sa 1,
-% dia=SerifSemiItalic-Expert sa a,
-% dib=SerifSemiItalic-Expert sa b,
-% dic=SerifSemiItalic-Expert sa c,
-% did=SerifSemiItalic-Expert sa d,
-% dix=SerifSemiItalic-Expert sa x,
-% dixx=SerifSemiItalic-Expert sa xx,
-% ds=SerifSemiSlanted-Expert sa 1,
-% dsa=SerifSemiSlanted-Expert sa a,
-% dsb=SerifSemiSlanted-Expert sa b,
-% dsc=SerifSemiSlanted-Expert sa c,
-% dsd=SerifSemiSlanted-Expert sa d,
-% dsx=SerifSemiSlanted-Expert sa x,
-% dsxx=SerifSemiSlanted-Expert sa xx,
-% dc=SerifSemiCaps-Expert sa 1,
-% dca=SerifSemiCaps-Expert sa a,
-% dcb=SerifSemiCaps-Expert sa b,
-% dcc=SerifSemiCaps-Expert sa c,
-% dcd=SerifSemiCaps-Expert sa d,
-% dcx=SerifSemiCaps-Expert sa x,
-% dcxx=SerifSemiCaps-Expert sa xx,
-% bf=SerifBold-Expert sa 1,
-% bi=SerifBoldItalic-Expert sa 1,
-% bs=SerifBoldSlanted-Expert sa 1,
-% eb=SerifBlack-Expert sa 1,
-% eba=SerifBlack-Expert sa a,
-% ebb=SerifBlack-Expert sa b,
-% ebc=SerifBlack-Expert sa c,
-% ebd=SerifBlack-Expert sa d,
-% ebx=SerifBlack-Expert sa x,
-% ebxx=SerifBlack-Expert sa xx]
-
-% \stoptypescript
-
-% \starttypescript [serif] [fourier-oldstyle] [size] % experimental
-
-% \definebodyfont
-% [17.3pt,14.4pt,12pt,11pt,10pt,9pt,8pt,7pt,6pt,5pt,4pt]
-% [rm]
-% [tf=Serif-OldStyle sa 1,
-% it=SerifItalic-OldStyle sa 1,
-% sl=SerifSlanted-OldStyle sa 1,
-% sc=SerifCaps-OldStyle sa 1,
-% db=SerifSemiBold-OldStyle sa 1,
-% dba=SerifSemiBold-OldStyle sa a,
-% dbb=SerifSemiBold-OldStyle sa b,
-% dbc=SerifSemiBold-OldStyle sa c,
-% dbd=SerifSemiBold-OldStyle sa d,
-% dbx=SerifSemiBold-OldStyle sa x,
-% dbxx=SerifSemiBold-OldStyle sa xx,
-% di=SerifSemiItalic-OldStyle sa 1,
-% dia=SerifSemiItalic-OldStyle sa a,
-% dib=SerifSemiItalic-OldStyle sa b,
-% dic=SerifSemiItalic-OldStyle sa c,
-% did=SerifSemiItalic-OldStyle sa d,
-% dix=SerifSemiItalic-OldStyle sa x,
-% dixx=SerifSemiItalic-OldStyle sa xx,
-% ds=SerifSemiSlanted-OldStyle sa 1,
-% dsa=SerifSemiSlanted-OldStyle sa a,
-% dsb=SerifSemiSlanted-OldStyle sa b,
-% dsc=SerifSemiSlanted-OldStyle sa c,
-% dsd=SerifSemiSlanted-OldStyle sa d,
-% dsx=SerifSemiSlanted-OldStyle sa x,
-% dsxx=SerifSemiSlanted-OldStyle sa xx,
-% dc=SerifSemiCaps-OldStyle sa 1,
-% dca=SerifSemiCaps-OldStyle sa a,
-% dcb=SerifSemiCaps-OldStyle sa b,
-% dcc=SerifSemiCaps-OldStyle sa c,
-% dcd=SerifSemiCaps-OldStyle sa d,
-% dcx=SerifSemiCaps-OldStyle sa x,
-% dcxx=SerifSemiCaps-OldStyle sa xx,
-% eb=SerifBlack-OldStyle sa 1,
-% eba=SerifBlack-OldStyle sa a,
-% ebb=SerifBlack-OldStyle sa b,
-% ebc=SerifBlack-OldStyle sa c,
-% ebd=SerifBlack-OldStyle sa d,
-% ebx=SerifBlack-OldStyle sa x,
-% ebxx=SerifBlack-OldStyle sa xx,
-% bf=SerifBold-OldStyle sa 1,
-% bi=SerifBoldItalic-OldStyle sa 1,
-% bs=SerifBoldSlanted-OldStyle sa 1]
-
-% \stoptypescript
-
-\starttypescript [math] [euler] [size]
-
- \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
- [mr=zeurm10 sa 1,
- ex=zeuex10 sa 1,
- sy=zeusm10 sa 1,
- mi=eufm10 sa 1]
-
- \definebodyfont [6pt,7pt,8pt] [mm]
- [mr=zeurm7 sa 1,
- sy=zeusm7 sa 1,
- mi=eufm7 sa 1,
- ex=zeuex10 sa 1]
-
- \definebodyfont [5pt] [mm]
- [mr=zeurm5,
- sy=zeusm5,
- mi=eufm5,
- ex=zeuex10 at 5pt]
-
-\stoptypescript
-
-\starttypescript [bfmath] [euler] [size]
-
- \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
- [mrbf=zeurb10 sa 1,
- exbf=zeuex10 sa 1,
- sybf=zeusb10 sa 1,
- mibf=eufb10 sa 1]
-
- \definebodyfont [6pt,7pt,8pt] [mm]
- [mrbf=zeurb7 sa 1,
- sybf=zeusb7 sa 1,
- mibf=eufb7 sa 1,
- exbf=zeuex10 sa 1]
-
- \definebodyfont [5pt] [mm]
- [mrbf=zeurb5,
- sybf=zeusb5,
- mibf=eufb5,
- exbf=zeuex10 at 5pt]
-
-\stoptypescript
-
-\starttypescript [boldmath] [euler] [size]
-
- \definebodyfont [9pt,10pt,11pt,12pt,14.4pt,17.3pt,20.7pt] [mm]
- [mr=zeurb10 sa 1,
- ex=zeuex10 sa 1,
- sy=zeusb10 sa 1,
- mi=eufb10 sa 1]
-
- \definebodyfont [6pt,7pt,8pt] [mm]
- [mr=zeurb7 sa 1,
- sy=zeusb7 sa 1,
- mi=eufb7 sa 1,
- ex=zeuex10 sa 1]
-
- \definebodyfont [5pt] [mm]
- [mr=zeurb5,
- sy=zeusb5,
- mi=eufb5,
- ex=zeuex10 at 5pt]
-
-\stoptypescript
-
-\starttypescript [math] [modern,computer-modern,latin-modern,ams] [size]
- \definebodyfont [17.3pt,14.4pt,12pt,11pt,10pt,9pt] [mm]
- [ma=msam10 sa 1,
- mb=msbm10 sa 1]
- \definebodyfont [8pt,7pt] [mm]
- [ma=msam7 sa 1,
- mb=msbm7 sa 1]
- \definebodyfont [6pt,5pt,4pt] [mm]
- [ma=msam5 sa 1,
- mb=msbm5 sa 1]
-\stoptypescript
-
-% math times
-
-\starttypescript [math] [times] [size]
+\stoptypescriptcollection
- \mapfontsize [5pt] [6.0pt]
- \mapfontsize [6pt] [6.8pt]
- \mapfontsize [7pt] [7.6pt]
- \mapfontsize [8pt] [8.4pt]
- \mapfontsize [9pt] [9.2pt]
- \mapfontsize [10pt] [10pt]
- \mapfontsize [11pt] [10.8pt]
- \mapfontsize [12pt] [11.6pt]
- \mapfontsize [14.4pt] [13.2pt]
+\protect
-\stoptypescript
-
-\stoptypescriptcollection
+\loadmarkfile{type-siz}
-\protect \endinput
+\endinput
diff --git a/tex/context/base/type-syn.tex b/tex/context/base/type-syn.tex
index b7e9335df..554694c6e 100644
--- a/tex/context/base/type-syn.tex
+++ b/tex/context/base/type-syn.tex
@@ -13,7 +13,6 @@
\starttypescriptcollection[synonyms]
-
% Computer Modern Roman : Donald Knuth
% Latin Modern: LM Font Revision Team
diff --git a/tex/context/base/type-tmf.tex b/tex/context/base/type-tmf.tex
index ec3178a34..c2deb8187 100644
--- a/tex/context/base/type-tmf.tex
+++ b/tex/context/base/type-tmf.tex
@@ -90,16 +90,6 @@
% maybe we can by now just use: (to be tested first)
-% \starttypescript [math] [modern,computer-modern,latin-modern] [name]
-% \definefontsynonym[xcmr12][LMRoman-Regular12]
-% \definefontsynonym[xcmr10][LMRoman-Regular10]
-% \definefontsynonym[xcmr9] [LMRoman-Regular9]
-% \definefontsynonym[xcmr8] [LMRoman-Regular8]
-% \definefontsynonym[xcmr7] [LMRoman-Regular7]
-% \definefontsynonym[xcmr6] [LMRoman-Regular6]
-% \definefontsynonym[xcmr5] [LMRoman-Regular5]
-% \stoptypescript
-
\starttypescript [math] [modern,computer-modern,latin-modern] [name]
\definefontsynonym[xcmr12][rm-lmr12]
\definefontsynonym[xcmr10][rm-lmr10]
@@ -1085,6 +1075,99 @@
\definefontsynonym [SerifCapsOsF] [TeXPalladioL-SC]
\stoptypescript
+% TeXGyre
+
+% name definitions & prefixes
+
+\definetypescriptprefix [n:pagella] [TeXGyrePagella] \definetypescriptprefix [n:palatino] [TeXGyrePagella]
+\definetypescriptprefix [n:termes] [TeXGyreTermes] \definetypescriptprefix [n:times] [TeXGyreTermes]
+\definetypescriptprefix [n:heros] [TeXGyreHeros] \definetypescriptprefix [n:helvetica] [TeXGyreHeros]
+\definetypescriptprefix [n:bonum] [TeXGyreBonum] \definetypescriptprefix [n:bookman] [TeXGyreBonum]
+\definetypescriptprefix [n:schola] [TeXGyreSchola] \definetypescriptprefix [n:schoolbook] [TeXGyreSchola]
+\definetypescriptprefix [n:adventor] [TeXGyreAdventor] %definetypescriptprefix [n:adventor] [TeXGyreAdventor]
+\definetypescriptprefix [n:cursor] [TeXGyreCursor] \definetypescriptprefix [n:courier] [TeXGyreCursor]
+\definetypescriptprefix [n:chorus] [TeXGyreChorus] \definetypescriptprefix [n:chancery] [TeXGyreChorus] % not the full set
+
+\starttypescript [serif] [pagella,palatino,termes,times,bonum,bookman,schola,schoolbook] [name]
+ \definefontsynonym [Serif] [\typescriptprefix{n:\typescripttwo}-Regular]
+ \definefontsynonym [SerifItalic] [\typescriptprefix{n:\typescripttwo}-Italic]
+ \definefontsynonym [SerifBold] [\typescriptprefix{n:\typescripttwo}-Bold]
+ \definefontsynonym [SerifBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
+ \definefontsynonym [SerifSlanted] [SerifItalic]
+ \definefontsynonym [SerifBoldSlanted] [SerifBoldItalic]
+ \definefontsynonym [SerifCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
+
+ \definefontvariant [Serif][osf][Caps]
+ \definefontvariant [Serif][sc] [Caps]
+
+ \definefontsynonym [SerifRegular] [Serif]
+ \definefontsynonym [SerifRegularCaps] [SerifCaps]
+ \definefontsynonym [SerifItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
+ \definefontsynonym [SerifBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps]
+ \definefontsynonym [SerifBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
+ \definefontsynonym [SerifSlantedCaps] [SerifItalicCaps]
+ \definefontsynonym [SerifBoldSlantedCaps] [SerifBoldItalicCaps]
+ \definefontsynonym [SerifCapsCaps] [SerifCaps]
+\stoptypescript
+
+\starttypescript [serif] [chorus,chancery] [name]
+ \definefontsynonym [SerifMediumItalic] [TeXGyreChorus-MediumItalic]
+ \definefontsynonym [Serif] [SerifMediumItalic]
+ \definefontsynonym [SerifItalic] [SerifMediumItalic]
+ \definefontsynonym [SerifBold] [SerifMediumItalic]
+ \definefontsynonym [SerifBoldItalic] [SerifMediumItalic]
+ \definefontsynonym [SerifSlanted] [SerifMediumItalic]
+ \definefontsynonym [SerifBoldSlanted] [SerifMediumItalic]
+ \definefontsynonym [SerifCaps] [SerifMediumItalic]
+\stoptypescript
+
+\starttypescript [calligraphy] [chorus,chancery] [name]
+ \definefontsynonym [Calligraphy] [TeXGyreChorus-MediumItalic]
+\stoptypescript
+
+\starttypescript [sans] [heros,helvetica,adventor] [name]
+ \definefontsynonym [Sans] [\typescriptprefix{n:\typescripttwo}-Regular]
+ \definefontsynonym [SansItalic] [\typescriptprefix{n:\typescripttwo}-Italic]
+ \definefontsynonym [SansBold] [\typescriptprefix{n:\typescripttwo}-Bold]
+ \definefontsynonym [SansBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
+ \definefontsynonym [SansSlanted] [SansItalic]
+ \definefontsynonym [SansBoldSlanted] [SansBoldItalic]
+ \definefontsynonym [SansCaps] [\typescriptprefix{n:\typescripttwo}-Caps]
+
+ \definefontvariant [Sans][osf][Caps]
+ \definefontvariant [Sans][sc] [Caps]
+
+ \definefontsynonym [SansRegular] [Sans]
+ \definefontsynonym [SansRegularCaps] [SansCaps]
+ \definefontsynonym [SansItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
+ \definefontsynonym [SansBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps]
+ \definefontsynonym [SansBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
+ \definefontsynonym [SansSlantedCaps] [SansItalicCaps]
+ \definefontsynonym [SansBoldSlantedCaps] [SansBoldItalicCaps]
+ \definefontsynonym [SansCapsCaps] [SansCaps]
+\stoptypescript
+
+\starttypescript [mono] [cursor,courier] [name]
+ \definefontsynonym [Mono] [\typescriptprefix{n:\typescripttwo}-Regular]
+ \definefontsynonym [MonoItalic] [\typescriptprefix{n:\typescripttwo}-Italic]
+ \definefontsynonym [MonoBold] [\typescriptprefix{n:\typescripttwo}-Bold]
+ \definefontsynonym [MonoBoldItalic] [\typescriptprefix{n:\typescripttwo}-BoldItalic]
+ \definefontsynonym [MonoSlanted] [MonoItalic]
+ \definefontsynonym [MonoBoldSlanted] [MonoBoldItalic]
+
+ \definefontvariant [Mono][osf][Caps]
+ \definefontvariant [Mono][sc] [Caps]
+
+ \definefontsynonym [MonoRegular] [Mono]
+ \definefontsynonym [MonoRegularCaps] [MonoCaps]
+ \definefontsynonym [MonoItalicCaps] [\typescriptprefix{n:\typescripttwo}-ItalicCaps]
+ \definefontsynonym [MonoBoldCaps] [\typescriptprefix{n:\typescripttwo}-BoldCaps]
+ \definefontsynonym [MonoBoldItalicCaps] [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps]
+ \definefontsynonym [MonoSlantedCaps] [MonoItalicCaps]
+ \definefontsynonym [MonoBoldSlantedCaps] [MonoBoldItalicCaps]
+ \definefontsynonym [MonoCapsCaps] [MonoCaps]
+\stoptypescript
+
\stoptypescriptcollection
\endinput
diff --git a/tex/context/base/type-win.tex b/tex/context/base/type-win.tex
new file mode 100644
index 000000000..bae89471f
--- /dev/null
+++ b/tex/context/base/type-win.tex
@@ -0,0 +1,120 @@
+%D \module
+%D [ file=type-win,
+%D version=2009.03.10,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=MS Windows Definitions,
+%D author=Vyatcheslav Yatskovsky,
+%D date=\currentdate,
+%D copyright=Vyatcheslav Yatskovsky]
+%C
+%C This module is part of the \CONTEXT\ macro||package. See
+%C mreadme.pdf for details.
+
+\starttypescriptcollection[windows]
+
+\starttypescript [serif] [georgia,palatino,times]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [\typescripttwo-Regular] [features=default]
+ \definefontsynonym [SerifBold] [\typescripttwo-Bold] [features=default]
+ \definefontsynonym [SerifItalic] [\typescripttwo-Italic] [features=default]
+ \definefontsynonym [SerifBoldItalic] [\typescripttwo-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [serif] [sylfaen]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [\typescripttwo-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [arial,trebuchet,verdana]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [\typescripttwo-Regular] [features=default]
+ \definefontsynonym [SansBold] [\typescripttwo-Bold] [features=default]
+ \definefontsynonym [SansItalic] [\typescripttwo-Italic] [features=default]
+ \definefontsynonym [SansBoldItalic] [\typescripttwo-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [arialblack,impact,lucidasans,microsans]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [\typescripttwo-Regular] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [comic,tahoma]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [\typescripttwo-Regular] [features=default]
+ \definefontsynonym [SansBold] [\typescripttwo-Bold] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [franklin]
+ \setups[font:fallback:sans]
+ \definefontsynonym [Sans] [\typescripttwo-Regular] [features=default]
+ \definefontsynonym [SansItalic] [\typescripttwo-Italic] [features=default]
+\stoptypescript
+
+\starttypescript [mono] [courier]
+ \setups[font:fallback:mono]
+ \definefontsynonym [Mono] [\typescripttwo-Regular] [features=default]
+ \definefontsynonym [MonoBold] [\typescripttwo-Bold] [features=default]
+ \definefontsynonym [MonoItalic] [\typescripttwo-Italic] [features=default]
+ \definefontsynonym [MonoBoldItalic] [\typescripttwo-BoldItalic] [features=default]
+\stoptypescript
+
+\starttypescript [mono] [lucidaconsole]
+ \setups[font:fallback:mono]
+ \definefontsynonym [Mono] [\typescripttwo-Regular] [features=default]
+\stoptypescript
+
+
+\definetypescriptprefix [f:arial] [Arial]
+\definetypescriptprefix [f:arialblack] [Arial Black]
+\definetypescriptprefix [f:comic] [Comic Sans MS]
+\definetypescriptprefix [f:courier] [Courier New]
+\definetypescriptprefix [f:franklin] [Franklin Gothic Medium]
+\definetypescriptprefix [f:georgia] [Georgia]
+\definetypescriptprefix [f:impact] [Impact]
+\definetypescriptprefix [f:lucidaconsole] [Lucida Console]
+\definetypescriptprefix [f:lucidasans] [Lucida Sans Unicode]
+\definetypescriptprefix [f:microsans] [Microsoft Sans Serif]
+\definetypescriptprefix [f:palatino] [Palatino Linotype]
+\definetypescriptprefix [f:sylfaen] [Sylfaen]
+\definetypescriptprefix [f:tahoma] [Tahoma]
+\definetypescriptprefix [f:times] [Times New Roman]
+\definetypescriptprefix [f:trebuchet] [Trebuchet MS]
+\definetypescriptprefix [f:verdana] [Verdana]
+
+\starttypescript [serif] [georgia,palatino,sylfaen,times]
+ \definefontsynonym [\typescripttwo-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescripttwo-Bold] [name:\typescriptprefix{f:\typescripttwo} Bold] [features=default]
+ \definefontsynonym [\typescripttwo-Italic] [name:\typescriptprefix{f:\typescripttwo} Italic] [features=default]
+ \definefontsynonym [\typescripttwo-BoldItalic] [name:\typescriptprefix{f:\typescripttwo} Bold Italic] [features=default]
+\stoptypescript
+
+\starttypescript [sans] [arial,arialblack,comic,franklin,impact,lucidasans,microsans,tahoma,trebuchet,verdana]
+ \definefontsynonym [\typescripttwo-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescripttwo-Bold] [name:\typescriptprefix{f:\typescripttwo} Bold] [features=default]
+ \definefontsynonym [\typescripttwo-Italic] [name:\typescriptprefix{f:\typescripttwo} Italic] [features=default]
+ \definefontsynonym [\typescripttwo-BoldItalic] [name:\typescriptprefix{f:\typescripttwo} Bold Italic] [features=default]
+\stoptypescript
+
+\starttypescript [mono] [courier,lucidaconsole]
+ \definefontsynonym [\typescripttwo-Regular] [name:\typescriptprefix{f:\typescripttwo}] [features=default]
+ \definefontsynonym [\typescripttwo-Bold] [name:\typescriptprefix{f:\typescripttwo} Bold] [features=default]
+ \definefontsynonym [\typescripttwo-Italic] [name:\typescriptprefix{f:\typescripttwo} Italic] [features=default]
+ \definefontsynonym [\typescripttwo-BoldItalic] [name:\typescriptprefix{f:\typescripttwo} Bold Italic] [features=default]
+\stoptypescript
+
+
+\starttypescript [georgia,palatino,sylfaen,times]
+ \definetypeface [\typescriptone] [rm] [serif] [\typescriptone] [default]
+\stoptypescript
+
+\starttypescript [arial,arialblack,comic,franklin,impact,lucidasans,microsans,tahoma,trebuchet,verdana]
+ \definetypeface [\typescriptone] [ss] [sans] [\typescriptone] [default]
+\stoptypescript
+
+\starttypescript [courier,lucidaconsole]
+ \definetypeface [\typescriptone] [tt] [mono] [\typescriptone] [default]
+\stoptypescript
+
+\stoptypescriptcollection
+
+\endinput
diff --git a/tex/context/base/type-xtx.tex b/tex/context/base/type-xtx.tex
index 32ff858d1..450beb6f2 100644
--- a/tex/context/base/type-xtx.tex
+++ b/tex/context/base/type-xtx.tex
@@ -36,7 +36,7 @@
%D
%D \starttyping
%D \definetypeface[basic][rm][Xserif][Baskerville]
-%D \definetypeface[basic][ss][Xsans] [Optima Regular][default][features=default,rscale=.87]
+%D \definetypeface[basic][ss][Xsans] [Optima Regular][default][features=default,rscale=0.87]
%D \definetypeface[basic][tt][Xmono] [Courier] [default]
%D \stoptyping
%D
diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua
new file mode 100644
index 000000000..d01b9d653
--- /dev/null
+++ b/tex/context/base/typo-brk.lua
@@ -0,0 +1,186 @@
+if not modules then modules = { } end modules ['typo-brk'] = {
+ version = 1.001,
+ comment = "companion to typo-brk.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this code dates from the beginning and is kind of experimental; it
+-- will be optimized and improved soon
+
+local next, type = next, type
+local format = string.format
+
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local set_attribute = node.set_attribute
+local copy_node = node.copy
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local make_penalty_node = nodes.penalty
+local make_glue_node = nodes.glue
+local make_disc_node = nodes.disc
+
+local glyph = node.id("glyph")
+local kern = node.id("kern")
+
+breakpoints = breakpoints or { }
+breakpoints.mapping = breakpoints.mapping or { }
+breakpoints.methods = breakpoints.methods or { }
+breakpoints.enabled = false
+
+storage.register("breakpoints/mapping", breakpoints.mapping, "breakpoints.mapping")
+
+local mapping = breakpoints.mapping
+
+function breakpoints.setreplacement(id,char,kind,before,after,language)
+ local map = mapping[id]
+ if not map then
+ map = { }
+ mapping[id] = map
+ end
+ local cmap = map[char]
+ if not cmap then
+ cmap = { }
+ map[char] = cmap
+ end
+ cmap[language or ""] = { kind or 1, before or 1, after or 1 }
+end
+
+breakpoints.methods[1] = function(head,start)
+ if start.prev and start.next then
+ insert_node_before(head,start,make_penalty_node(10000))
+ insert_node_before(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_penalty_node(0))
+ end
+ return head, start
+end
+breakpoints.methods[2] = function(head,start) -- ( => (-
+ if start.prev and start.next then
+ local tmp = start
+ start = make_disc_node()
+ start.prev, start.next = tmp.prev, tmp.next
+ tmp.prev.next, tmp.next.prev = start, start
+ tmp.prev, tmp.next = nil, nil
+ start.replace = tmp
+ local tmp, hyphen = copy_node(tmp), copy_node(tmp)
+ hyphen.char = languages.prehyphenchar(tmp.lang)
+ tmp.next, hyphen.prev = hyphen, tmp
+ start.post = tmp
+ insert_node_before(head,start,make_penalty_node(10000))
+ insert_node_before(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_penalty_node(10000))
+ end
+ return head, start
+end
+breakpoints.methods[3] = function(head,start) -- ) => -)
+ if start.prev and start.next then
+ local tmp = start
+ start = make_disc_node()
+ start.prev, start.next = tmp.prev, tmp.next
+ tmp.prev.next, tmp.next.prev = start, start
+ tmp.prev, tmp.next = nil, nil
+ start.replace = tmp
+ local tmp, hyphen = copy_node(tmp), copy_node(tmp)
+ hyphen.char = languages.prehyphenchar(tmp.lang)
+ tmp.prev, hyphen.next = hyphen, tmp
+ start.pre = hyphen
+ insert_node_before(head,start,make_penalty_node(10000))
+ insert_node_before(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_penalty_node(10000))
+ end
+ return head, start
+end
+breakpoints.methods[4] = function(head,start) -- - => - - -
+ if start.prev and start.next then
+ local tmp = start
+ start = make_disc_node()
+ start.prev, start.next = tmp.prev, tmp.next
+ tmp.prev.next, tmp.next.prev = start, start
+ tmp.prev, tmp.next = nil, nil
+ -- maybe prehyphenchar etc
+ start.pre = copy_node(tmp)
+ start.post = copy_node(tmp)
+ start.replace = tmp
+ insert_node_before(head,start,make_penalty_node(10000))
+ insert_node_before(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_glue_node(0))
+ insert_node_after(head,start,make_penalty_node(10000))
+ end
+ return head, start
+end
+
+function breakpoints.process(namespace,attribute,head)
+ local done, numbers = false, languages.numbers
+ local start, n = head, 0
+ while start do
+ local id = start.id
+ if id == glyph then
+ local attr = has_attribute(start,attribute)
+ if attr and attr > 0 then
+ unset_attribute(start,attribute) -- maybe test for subtype > 256 (faster)
+ -- look ahead and back n chars
+ local map = mapping[attr]
+ if map then
+ local cmap = map[start.char]
+ if cmap then
+ local smap = cmap[numbers[start.lang]] or cmap[""]
+ if smap then
+ if n >= smap[2] then
+ local m = smap[3]
+ local next = start.next
+ while next do -- gamble on same attribute
+ local id = next.id
+ if id == glyph then -- gamble on same attribute
+ if map[next.char] then
+ break
+ elseif m == 1 then
+ local method = breakpoints.methods[smap[1]]
+ if method then
+ head, start = method(head,start)
+ done = true
+ end
+ break
+ else
+ m = m - 1
+ next = next.next
+ end
+ elseif id == kern and next.subtype == 0 then
+ next = next.next
+ -- ignore intercharacter kerning, will go way
+ else
+ -- we can do clever and set n and jump ahead but ... not now
+ break
+ end
+ end
+ end
+ n = 0
+ else
+ n = n + 1
+ end
+ else
+ n = n + 1
+ end
+ else
+ n = 0
+ end
+ end
+ elseif id == kern and start.subtype == 0 then
+ -- ignore intercharacter kerning, will go way
+ else
+ n = 0
+ end
+ start = start.next
+ end
+ return head, done
+end
+
+chars.handle_breakpoints = nodes.install_attribute_handler {
+ name = "breakpoint",
+ namespace = breakpoints,
+ processor = breakpoints.process,
+ }
diff --git a/tex/context/base/typo-brk.tex b/tex/context/base/typo-brk.tex
new file mode 100644
index 000000000..90561fc9e
--- /dev/null
+++ b/tex/context/base/typo-brk.tex
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=typo-brk,
+%D version=2009.03.27, % code moved from core-spa.mkiv
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Breakpoints,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Typesetting Macros / Breakpoints}
+
+\unprotect
+
+\registerctxluafile{typo-brk}{1.001}
+
+\definesystemattribute[breakpoint]
+
+% compound stuff (under construction)
+
+\newbox\breakpointbox
+
+\definesystemvariable {bp} % BreakPoint
+
+\exhyphenchar=\minusone % we use a different order then base tex, so we really need this
+
+\newcount \maxbreakpointsid
+
+\def\definebreakpoints
+ {\dosingleargument\dodefinebreakpoints}
+
+\def\dodefinebreakpoints[#1]%
+ {\ifcsname\??bp:#1\endcsname \else
+ \global\advance\maxbreakpointsid\plusone
+ \setxvalue{\??bp:#1}{\the\maxbreakpointsid}%
+ \fi}
+
+\def\installbreakpoint
+ {\dotripleempty\doinstallbreakpoint}
+
+% hm, we cannot prebuild lists, font dependent
+
+\def\doinstallbreakpoint[#1][#2][#3]%
+ {\ifcsname\??bp:#1\endcsname
+ \begingroup
+ \getparameters[\??bp][\c!type=1,\c!nleft=3,\c!nright=3,\s!language=,#3]%
+ \ctxlua{breakpoints.setreplacement(\csname\??bp:#1\endcsname,#2,\@@bptype,\@@bpnleft,\@@bpnright,"\@@bplanguage")}%
+ \endgroup
+ \fi}
+
+\def\setbreakpoints
+ {\ctxlua{breakpoints.enabled=true}%
+ \gdef\setbreakpoints[##1]{\dosetattribute{breakpoint}{\csname\??bp:##1\endcsname}}%
+ \setbreakpoints}
+
+\letvalue{\??bp:\s!reset}\attributeunsetvalue
+
+\definebreakpoints[compound]
+
+\installbreakpoint [compound] [\number`+] [\c!left=3,\c!right=3,\c!type=1]
+\installbreakpoint [compound] [\number`-] [\c!left=3,\c!right=3,\c!type=1]
+\installbreakpoint [compound] [\number`/] [\c!left=3,\c!right=3,\c!type=1]
+\installbreakpoint [compound] [\number`(] [\c!left=3,\c!right=3,\c!type=2]
+\installbreakpoint [compound] [\number`)] [\c!left=3,\c!right=3,\c!type=3]
+
+% \mainlanguage[czech]
+% \installbreakpoint [compound] [\number`-] [language=cs,left=3,right=3,type=4]
+% \setbreakpoints[compound]
+% \start \hsize 1mm test-test \par \stop
+
+% \setbreakpoints[compound]
+
+\protect \endinput
+
diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua
new file mode 100644
index 000000000..b6eedb330
--- /dev/null
+++ b/tex/context/base/typo-cap.lua
@@ -0,0 +1,203 @@
+if not modules then modules = { } end modules ['typo-cap'] = {
+ version = 1.001,
+ comment = "companion to typo-cap.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+local format, insert = string.format, table.insert
+
+local trace_casing = false trackers.register("nodes.casing", function(v) trace_casing = v end)
+
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local set_attribute = node.set_attribute
+local traverse_id = node.traverse_id
+
+local glyph = node.id("glyph")
+local kern = node.id("kern")
+
+local fontdata = fonts.ids
+local chardata = characters.data
+
+cases = cases or { }
+cases.enabled = false
+cases.actions = { }
+
+local actions = cases.actions
+local lastfont = nil
+
+-- we use char0 as placeholder for the larger font
+
+local function helper(start, code, codes, special, attribute, once)
+ local char = start.char
+ local dc = chardata[char]
+ if dc then
+ local fnt = start.font
+ if special then
+ if start.char == 0 then
+ lastfont = fnt
+ local prev, next = start.prev, start.next
+ prev.next = next
+ if next then
+ next.prev = prev
+ end
+ return prev, true
+ elseif lastfont and start.prev.id ~= glyph then
+ fnt = lastfont
+ start.font = lastfont
+ end
+ end
+ local ifc = fontdata[fnt].characters
+ local ucs = dc[codes]
+ if ucs then
+ local ok = true
+ for i=1,#ucs do
+ ok = ok and ifc[ucs[i]]
+ end
+ if ok then
+ local prev, original = start, start
+ for i=1,#ucs do
+ local chr = ucs[i]
+ prev = start
+ if i == 1 then
+ start.char = chr
+ else
+ local g = copy_node(original)
+ g.char = chr
+ local next = start.next
+ g.prev = start
+ if next then
+ g.next = next
+ start.next = g
+ next.prev = g
+ end
+ start = g
+ end
+ end
+ if once then lastfont = nil end
+ return prev, true
+ end
+ if once then lastfont = nil end
+ return start, false
+ end
+ local uc = dc[code]
+ if uc and ifc[uc] then
+ start.char = uc
+ if once then lastfont = nil end
+ return start, true
+ end
+ end
+ if once then lastfont = nil end
+ return start, false
+end
+
+actions[1] = function(start,attribute)
+ lastfont = nil
+ return helper(start,'uccode','uccodes')
+end
+
+actions[2] = function(start,attribute)
+ lastfont = nil
+ return helper(start,'lccode','lccodes')
+end
+
+actions[3] = function(start,attribute)
+ lastfont = nil
+ local prev = start.prev
+ if prev and prev.id == kern and prev.subtype == 0 then
+ prev = prev.prev
+ end
+ if not prev or prev.id ~= glyph then
+ --- only the first character is treated
+ for n in traverse_id(glyph,start.next) do
+ if has_attribute(n,attribute) then
+ unset_attribute(n,attribute)
+ end
+ end
+ return helper(start,'uccode','uccodes')
+ else
+ return start, false
+ end
+end
+
+actions[4] = function(start,attribute)
+ lastfont = nil
+ local prev = start.prev
+ if prev and prev.id == kern and prev.subtype == 0 then
+ prev = prev.prev
+ end
+ if not prev or prev.id ~= glyph then
+ return helper(start,'uccode','uccodes')
+ else
+ return start, false
+ end
+end
+
+actions[5] = function(start,attribute) -- 3
+ return helper(start,'uccode','uccodes',true,attribute,true)
+end
+
+actions[6] = function(start,attribute) -- 4
+ return helper(start,'uccode','uccodes',true,attribute,false)
+end
+
+actions[8] = function(start)
+ lastfont = nil
+ local ch = start.char
+ local mr = math.random
+ local tfm = fontdata[start.font].characters
+ if chardata[ch].lccode then
+ while true do
+ local d = chardata[mr(1,0xFFFF)]
+ if d then
+ local uc = d.uccode
+ if uc and tfm[uc] then
+ start.char = uc
+ return start, true
+ end
+ end
+ end
+ elseif chardata[ch].uccode then
+ while true do
+ local d = chardata[mr(1,0xFFFF)]
+ if d then
+ local lc = d.lccode
+ if lc and tfm[lc] then
+ start.char = lc
+ return start, true
+ end
+ end
+ end
+ else
+ return start, false
+ end
+end
+
+-- node.traverse_id_attr
+
+function cases.process(namespace,attribute,head) -- not real fast but also not used on much data
+ lastfont = nil
+ local done = false
+ for start in traverse_id(glyph,head) do
+ local attr = has_attribute(start,attribute)
+ if attr and attr > 0 then
+ unset_attribute(start,attribute)
+ local action = actions[attr]
+ if action then
+ local _, ok = action(start,attribute)
+ done = done and ok
+ end
+ end
+ end
+ lastfont = nil
+ return head, done
+end
+
+chars.handle_casing = nodes.install_attribute_handler {
+ name = "case",
+ namespace = cases,
+ processor = cases.process,
+}
diff --git a/tex/context/base/typo-cap.tex b/tex/context/base/typo-cap.tex
new file mode 100644
index 000000000..49ca64957
--- /dev/null
+++ b/tex/context/base/typo-cap.tex
@@ -0,0 +1,214 @@
+%D \module
+%D [ file=typo-cap,
+%D version=2009.03.27, % code moved from core-spa.mkiv
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Mirroring,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Typesetting Macros / Caps}
+
+\unprotect
+
+\registerctxluafile{typo-cap}{1.001}
+
+\definesystemattribute[case]
+
+%D \macros
+%D {Word, Words, WORD, WORDS, doprocesswords}
+%D
+%D This is probably not the right place to present the next set
+%D of macros.
+%D
+%D \starttyping
+%D \Word {far too many words}
+%D \Words{far too many words}
+%D \WORD {far too many words}
+%D \WORDS{far too many words}
+%D \stoptyping
+%D
+%D \typebuffer
+%D
+%D This calls result in:
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D \showsetup{Word}
+%D \showsetup{Words}
+%D \showsetup{WORD}
+%D \showsetup{WORDS}
+
+% \def\doprocesswords#1 #2\od
+% {\ConvertToConstant\doifnot{#1}{}
+% {\processword{#1} %
+% \doprocesswords#2 \od}}
+%
+% \def\processwords#1%
+% {\doprocesswords#1 \od\unskip}
+%
+% \let\processword\relax
+
+% test \WORD{test TEST \TeX} test
+% test \word{test TEST \TeX} test
+% test \Word{test TEST \TeX} test
+
+\def\setcharactercasing
+ {\ctxlua{cases.enabled=true}%
+ \gdef\setcharactercasing[##1]{\dosetattribute{case}{\number##1}}%
+ \setcharactercasing}
+
+\unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\plusone ]}{}}
+\unexpanded\def\word {\groupedcommand{\setcharactercasing[\plustwo ]}{}}
+\unexpanded\def\Word {\groupedcommand{\setcharactercasing[\plusthree]}{}}
+\unexpanded\def\Words{\groupedcommand{\setcharactercasing[\plusfour ]}{}}
+
+\let\WORDS\WORD
+\let\words\word
+
+%D \macros
+%D {kap,KAP,Kap,Kaps,nokap,userealcaps,usepseudocaps}
+%D
+%D We already introduced \type{\cap} as way to capitalize
+%D words. This command comes in several versions:
+%D
+%D \startbuffer
+%D \cap {let's put on a \cap{cap}}
+%D \cap {let's put on a \nocap{cap}}
+%D \CAP {let's put on a \\{cap}}
+%D \Cap {let's put on a \\{cap}}
+%D \Caps{let's put on a cap}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Note the use of \type{\nocap}, \type{\\} and the nested
+%D \type{\cap}.
+%D
+%D \startvoorbeeld
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D \stopvoorbeeld
+%D
+%D These macros show te main reason why we introduced the
+%D smaller \type{\tx} and \type{\txx}.
+%D
+%D \starttyping
+%D \cap\romannumerals{1995}
+%D \stoptyping
+%D
+%D This at first sight unusual capitilization is completely
+%D legal.
+%D
+%D \showsetup{smallcapped}
+%D \showsetup{notsmallcapped}
+%D \showsetup{CAPPED}
+%D \showsetup{SmallCapped}
+%D \showsetup{SmallCaps}
+%D
+%D The difference between pseudo and real caps is demonstrated
+%D below:
+%D
+%D \startbuffer
+%D \usepseudocaps \cap{Hans Hagen}
+%D \userealcaps \cap{Hans Hagen}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer
+%D
+%D The \type {\bgroup} trickery below is needed because of
+%D \type {\groupedcommand}.
+
+\let\disablepseudocaps\relax % maybe used elsewhere
+
+\newconditional\pseudocapsenabled
+
+\def\usepseudocaps{\settrue \pseudocapsenabled}
+\def\userealcaps {\setfalse\pseudocapsenabled}
+
+\usepseudocaps
+
+% we use char0 as placeholder for the larger font
+
+\unexpanded\def\pseudosmallcapped{\groupedcommand{\setcharactercasing[\plusone ]\char\zerocount\tx}{}} % all upper
+\unexpanded\def\pseudoSmallcapped{\groupedcommand{\setcharactercasing[\plusfive]\char\zerocount\tx}{}} % one upper + font
+\unexpanded\def\pseudoSmallCapped{\groupedcommand{\setcharactercasing[\plussix ]\char\zerocount\tx}{}} % some upper + font
+
+\unexpanded\def\realsmallcapped {\groupedcommand{\sc\setcharactercasing[\plusone ]}{}} % all lower
+\unexpanded\def\realSmallcapped {\groupedcommand{\sc\setcharactercasing[\plusthree]}{}} % one upper + font
+\unexpanded\def\realSmallCapped {\groupedcommand{\sc\setcharactercasing[\plusfour ]}{}} % some upper
+
+\unexpanded\def\dohandlesmallcaps
+ {\ifconditional\pseudocapsenabled
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\unexpanded\def\smallcapped{\dohandlesmallcaps\pseudosmallcapped\realsmallcapped}
+\unexpanded\def\Smallcapped{\dohandlesmallcaps\pseudoSmallcapped\realSmallcapped}
+\unexpanded\def\SmallCapped{\dohandlesmallcaps\pseudoSmallCapped\realSmallCapped}
+
+\unexpanded\def\autocap{\ifmmode\expandafter\normalcap\else\expandafter\smallcapped\fi}
+
+\appendtoks
+ \let\normalcap\cap % mathmode cap
+ \let\cap\autocap
+\to \everydump
+
+\let\kap\cap % for old times sake
+\let\Caps\SmallCapped % for old times sake
+
+\let\normalsmallcapped\smallcapped
+\let\normalWORD \WORD
+\let\normalword \word
+
+%D \macros
+%D {setupcapitals}
+%D
+%D By default we use pseudo small caps in titles. This can be
+%D set up with:
+%D
+%D \showsetup{setupcapitals}
+
+\let\normalsmallcapped\smallcapped
+
+\def\setupcapitals
+ {\dosingleempty\dosetupcapitals}
+
+\def\dosetupcapitals[#1]%
+ {\getparameters[\??kk][#1]%
+ \doifelse\@@kktitle\v!yes
+ {\definealternativestyle[\v!capital][\normalsmallcapped][\normalsmallcapped]%
+ \definealternativestyle[\v!smallcaps][\sc][\sc]}
+ {\definealternativestyle[\v!capital][\normalsmallcapped][\normalWORD]%
+ \definealternativestyle[\v!smallcaps][\sc][\normalWORD]}%
+ \doifelse\@@kksc\v!yes\userealcaps\usepseudocaps}
+
+\let\uppercased\normalWORD
+\let\lowercased\normalword
+
+\setupcapitals
+ [\c!title=\v!yes,
+ \c!sc=\v!no]
+
+% \definestartstop is not yet in available at core-spa time
+%
+% \startrandomized \input tufte \stoprandomized
+%
+% \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=]
+
+\def\randomizetext{\groupedcommand{\dosetattribute{case}{8}}{}}
+
+\protect \endinput
diff --git a/tex/context/base/typo-ini.tex b/tex/context/base/typo-ini.tex
index e249b51e0..1317021ef 100644
--- a/tex/context/base/typo-ini.tex
+++ b/tex/context/base/typo-ini.tex
@@ -18,7 +18,7 @@
%D typographic extensions in modules. The first language that
%D demands this is Chinese, and more will follow.
-\writestatus{loading}{Context Typographic Macros (ini)}
+\writestatus{loading}{ConTeXt Typographic Macros / Initialization}
\unprotect
diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua
new file mode 100644
index 000000000..598db6c27
--- /dev/null
+++ b/tex/context/base/typo-krn.lua
@@ -0,0 +1,218 @@
+if not modules then modules = { } end modules ['typo-krn'] = {
+ version = 1.001,
+ comment = "companion to typo-krn.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utf = unicode.utf8
+
+local next, type = next, type
+local utfchar = utf.char
+
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local slide_node_list = node.slide
+local free_node = node.free
+local copy_node = node.copy
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local make_glue_spec = nodes.glue_spec
+local make_kern_node = nodes.kern
+
+local glyph = node.id("glyph")
+local kern = node.id("kern")
+local disc = node.id('disc')
+local glue = node.id('glue')
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+
+local fontdata = fonts.ids
+local chardata = characters.data
+
+kerns = kerns or { }
+kerns.mapping = kerns.mapping or { }
+kerns.enabled = false
+
+storage.register("kerns/mapping", kerns.mapping, "kerns.mapping")
+
+function kerns.setspacing(id,factor)
+ kerns.mapping[id] = factor
+end
+
+-- one must use liga=no and mode=base and kern=yes
+-- use more helpers
+-- make sure it runs after all others
+-- there will be a width adaptor field in nodes so this will change
+-- todo: interchar kerns / disc nodes / can be made faster
+-- todo: cache quad and so
+
+local mapping = kerns.mapping
+
+local function process(namespace,attribute,head,force)
+ local scale = tex.scale
+ local start, done, lastfont = head, false, nil
+ while start do
+ -- faster to test for attr first
+ local attr = force or has_attribute(start,attribute)
+ if attr and attr > 0 then
+ unset_attribute(start,attribute)
+ local krn = mapping[attr]
+ if krn and krn ~= 0 then
+ local id = start.id
+ if id == glyph then
+ lastfont = start.font
+ local c = start.components
+ if c then
+ local s = start
+ local tail = slide_node_list(c)
+ if s.prev then
+ s.prev.next = c
+ c.prev = s.prev
+ else
+ head = c
+ end
+ if s.next then
+ s.next.prev = tail
+ end
+ tail.next = s.next
+ start = c
+ start.attr = s.attr
+ s.attr = nil
+ s.components = nil
+ free_node(s)
+ done = true
+ end
+ local prev = start.prev
+ if prev then
+ local pid = prev.id
+ if not pid then
+ -- nothing
+ elseif pid == kern and prev.subtype == 0 then
+ prev.subtype = 1
+ prev.kern = prev.kern + scale(fontdata[lastfont].parameters.quad,krn)
+ done = true
+ elseif pid == glyph then
+ -- fontdata access can be done more efficient
+ if prev.font == lastfont then
+ local prevchar, lastchar = prev.char, start.char
+ local tfm = fontdata[lastfont].characters[prevchar]
+ local ickern = tfm.kerns
+ if ickern and ickern[lastchar] then
+ krn = scale(ickern[lastchar]+fontdata[lastfont].parameters.quad,krn)
+ else
+ krn = scale(fontdata[lastfont].parameters.quad,krn)
+ end
+ else
+ krn = scale(fontdata[lastfont].parameters.quad,krn)
+ end
+ insert_node_before(head,start,make_kern_node(krn))
+ done = true
+ elseif pid == disc then
+ -- a bit too complicated, we can best not copy and just calculate
+ -- but we could have multiple glyphs involved so ...
+ local disc = prev -- disc
+ local pre, post, replace = disc.pre, disc.post, disc.replace
+ if pre then -- must pair with start.prev
+ -- this one happens in most cases
+ local before = copy_node(disc.prev)
+ pre.prev = before
+ before.next = pre
+ before.prev = nil
+ pre = process(namespace,attribute,before,attr)
+ pre = pre.next
+ pre.prev = nil
+ disc.pre = pre
+ free_node(before)
+ end
+ if post then -- must pair with start
+ local after = copy_node(disc.next)
+ local tail = slide_node_list(post)
+ tail.next = after
+ after.prev = tail
+ after.next = nil
+ post = process(namespace,attribute,post,attr)
+ tail.next = nil
+ disc.post = post
+ free_node(after)
+ end
+ if replace then -- must pair with start and start.prev
+ local before = copy_node(disc.prev)
+ local after = copy_node(disc.next)
+ local tail = slide_node_list(replace)
+ replace.prev = before
+ before.next = replace
+ before.prev = nil
+ tail.next = after
+ after.prev = tail
+ after.next = nil
+ replace = process(namespace,attribute,before,attr)
+ replace = replace.next
+ replace.prev = nil
+ tail.next = nil
+ disc.replace = replace
+ free_node(after)
+ free_node(before)
+ else
+ if disc.prev.font == lastfont then
+ local prevchar, lastchar = disc.prev.char, start.char
+ local tfm = fontdata[lastfont].characters[prevchar]
+ local ickern = tfm.kerns
+ if ickern and ickern[lastchar] then
+ krn = scale(ickern[lastchar]+fontdata[lastfont].parameters.quad,krn)
+ else
+ krn = scale(fontdata[lastfont].parameters.quad,krn)
+ end
+ else
+ krn = scale(fontdata[lastfont].parameters.quad,krn)
+ end
+ disc.replace = make_kern_node(krn)
+ end
+ end
+ end
+ elseif id == glue and start.subtype == 0 then
+ local s = start.spec
+ local w = s.width
+ if w > 0 then
+ local width, stretch, shrink = w+2*scale(w,krn), s.stretch, s.shrink
+ start.spec = make_glue_spec(width,scale(stretch,width/w),scale(shrink,width/w))
+ -- local width, stretch, shrink = w+2*w*krn, s.stretch, s.shrink
+ -- start.spec = make_glue_spec(width,stretch*width/w,shrink*width/w))
+ done = true
+ end
+ elseif false and id == kern and start.subtype == 0 then -- handle with glyphs
+ local sk = start.kern
+ if sk > 0 then
+ -- start.kern = scale(sk,krn)
+ start.kern = sk*krn
+ done = true
+ end
+ elseif lastfont and (id == hlist or id == vlist) then -- todo: lookahead
+ if start.prev then
+ insert_node_before(head,start,make_kern_node(scale(fontdata[lastfont].parameters.quad,krn)))
+ done = true
+ end
+ if start.next then
+ insert_node_after(head,start,make_kern_node(scale(fontdata[lastfont].parameters.quad,krn)))
+ done = true
+ end
+ end
+ end
+ end
+ if start then
+ start = start.next
+ end
+ end
+ return head, done
+end
+
+kerns.process = function(namespace,attribute,head)
+ return process(namespace,attribute,head) -- no direct map, because else fourth argument is tail == true
+end
+
+lists.handle_kerning = nodes.install_attribute_handler {
+ name = "kern",
+ namespace = kerns,
+ processor = kerns.process,
+}
diff --git a/tex/context/base/typo-krn.tex b/tex/context/base/typo-krn.tex
new file mode 100644
index 000000000..e2f10d806
--- /dev/null
+++ b/tex/context/base/typo-krn.tex
@@ -0,0 +1,59 @@
+%D \module
+%D [ file=typo-krn,
+%D version=2009.03.27, % code moved from core-spa.mkiv
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Spacing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Typesetting Macros / Kerning}
+
+\unprotect
+
+\registerctxluafile{typo-krn}{1.001}
+
+\definesystemattribute[kern]
+
+% more
+%
+% {\setcharacterkerning[extrakerning]\input davis\relax}
+
+\newcount \maxcharacterkerningid
+
+\def\definecharacterkerning
+ {\dosingleargument\dodefinecharacterkerning}
+
+\def\dodefinecharacterkerning[#1]%
+ {\ifcsname\??ck#1\endcsname \else
+ \global\advance\maxcharacterkerningid\plusone
+ \setxvalue{\??ck:#1}{\the\maxcharacterkerningid}%
+ \fi}
+
+\def\setupcharacterkerning
+ {\dodoubleargument\dosetupcharacterkerning}
+
+\def\dosetupcharacterkerning[#1][#2]%
+ {\ifcsname\??ck:#1\endcsname
+ \begingroup
+ \getparameters[\??ck][\c!factor=0,#2]%
+ \ctxlua{kerns.setspacing(\getvalue{\??ck:#1},\@@ckfactor)}%
+ \endgroup
+ \fi}
+
+\def\setcharacterkerning
+ {\ctxlua{kerns.enabled=true}%
+ \gdef\setcharacterkerning[##1]{\dosetattribute{kern}{\csname\??ck:##1\endcsname}}%
+ \setcharacterkerning}
+
+\letvalue{\??ck:\s!reset}\attributeunsetvalue
+
+\definecharacterkerning[extrakerning]
+
+\setupcharacterkerning[extrakerning][\c!factor=.125]
+
+\protect \endinput
diff --git a/tex/context/base/typo-mir.lua b/tex/context/base/typo-mir.lua
new file mode 100644
index 000000000..fb575d093
--- /dev/null
+++ b/tex/context/base/typo-mir.lua
@@ -0,0 +1,409 @@
+if not modules then modules = { } end modules ['typo-mir'] = {
+ version = 1.001,
+ comment = "companion to typo-mir.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utf = unicode.utf8
+
+local next, type = next, type
+local format, insert = string.format, table.insert
+local utfchar = utf.char
+
+-- vertical space handler
+
+local trace_mirroring = false trackers.register("nodes.mirroring", function(v) trace_mirroring = v end)
+
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local set_attribute = node.set_attribute
+local traverse_id = node.traverse_id
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local remove_node = nodes.remove
+
+local glyph = node.id("glyph")
+local whatsit = node.id("whatsit")
+local mthnode = node.id('math')
+
+local fontdata = fonts.ids
+local chardata = characters.data
+
+--~ Analysis by Idris:
+--~
+--~ 1. Assuming the reading- vs word-order distinction (bidi-char types) is governing;
+--~ 2. Assuming that 'ARAB' represents an actual arabic string in raw input order, not word-order;
+--~ 3. Assuming that 'BARA' represent the correct RL word order;
+--~
+--~ Then we have, with input: LATIN ARAB
+--~
+--~ \textdir TLT LATIN ARAB => LATIN BARA
+--~ \textdir TRT LATIN ARAB => LATIN BARA
+--~ \textdir TRT LRO LATIN ARAB => LATIN ARAB
+--~ \textdir TLT LRO LATIN ARAB => LATIN ARAB
+--~ \textdir TLT RLO LATIN ARAB => NITAL ARAB
+--~ \textdir TRT RLO LATIN ARAB => NITAL ARAB
+
+-- elseif d == "es" then -- European Number Separator
+-- elseif d == "et" then -- European Number Terminator
+-- elseif d == "cs" then -- Common Number Separator
+-- elseif d == "nsm" then -- Non-Spacing Mark
+-- elseif d == "bn" then -- Boundary Neutral
+-- elseif d == "b" then -- Paragraph Separator
+-- elseif d == "s" then -- Segment Separator
+-- elseif d == "ws" then -- Whitespace
+-- elseif d == "on" then -- Other Neutrals
+
+mirror = mirror or { }
+mirror.enabled = false
+mirror.strip = false
+
+local state = attributes.private('state')
+local mirrora = attributes.private('mirror')
+
+local directions = characters.directions -- maybe make a special mirror table
+
+-- todo: delayed inserts here
+-- todo: get rid of local functions here
+
+-- beware, math adds whatsits afterwards so that will mess things up
+
+local skipmath = true
+
+local finish, autodir, embedded, override, done = nil, 0, 0, 0, false
+local list, glyphs = nil, false
+local finished, finidir, finipos = nil, nil, 1
+local head, current, inserted = nil, nil, nil
+
+local function finish_auto_before()
+ head, inserted = insert_node_before(head,current,nodes.textdir("-"..finish))
+ finished, finidir = inserted, finish
+ if trace_mirroring then
+ insert(list,#list,format("finish %s",finish))
+ finipos = #list-1
+ end
+ finish, autodir, done = nil, 0, true
+end
+
+local function finish_auto_after()
+ head, current = insert_node_after(head,current,nodes.textdir("-"..finish))
+ finished, finidir = current, finish
+ if trace_mirroring then
+ list[#list+1] = format("finish %s",finish)
+ finipos = #list
+ end
+ finish, autodir, done = nil, 0, true
+end
+
+local function force_auto_left_before()
+ if finish then
+ finish_auto_before()
+ end
+ if embedded >= 0 then
+ finish, autodir, done = "TLT", 1, true
+ else
+ finish, autodir, done = "TRT", -1, true
+ end
+ if finidir == finish then
+ remove_node(head,finished,true)
+ if trace_mirroring then
+ list[finipos] = list[finipos].." (deleted)"
+ insert(list,#list,format("start %s (deleted)",finish))
+ end
+ else
+ head, inserted = insert_node_before(head,current,nodes.textdir("+"..finish))
+ if trace_mirroring then
+ insert(list,#list,format("start %s",finish))
+ end
+ end
+end
+
+local function force_auto_right_before()
+ if finish then
+ finish_auto_before()
+ end
+ if embedded <= 0 then
+ finish, autodir, done = "TRT", -1, true
+ else
+ finish, autodir, done = "TLT", 1, true
+ end
+ if finidir == finish then
+ remove_node(head,finished,true)
+ if trace_mirroring then
+ list[finipos] = list[finipos].." (deleted)"
+ insert(list,#list,format("start %s (deleted)",finish))
+ end
+ else
+ head, inserted = insert_node_before(head,current,nodes.textdir("+"..finish))
+ if trace_mirroring then
+ insert(list,#list,format("start %s",finish))
+ end
+ end
+end
+
+function mirror.process(namespace,attribute,start) -- todo: make faster
+ if not start.next then
+ return start, false
+ end
+ head, current, inserted = start, start, nil
+ finish, autodir, embedded, override, done = nil, 0, 0, 0, false
+ list, glyphs = trace_mirroring and { }, false
+ finished, finidir, finipos = nil, nil, 1
+ local stack, top, obsolete = { }, 0, { }
+ local lro, rlo, prevattr, inmath = false, false, 0, false
+ while current do
+ local id = current.id
+ if skipmath and id == mthnode then
+ local subtype = current.subtype
+ if subtype == 0 then
+ -- begin math
+ inmath = true
+ elseif subtype == 1 then
+ inmath = false
+ else
+ -- todo
+ end
+ current = current.next
+ elseif inmath then
+ current = current.next
+ else
+ local attr = has_attribute(current,attribute)
+ if attr and attr > 0 then
+ unset_attribute(current,attribute) -- slow, needed?
+ --~ set_attribute(current,attribute,0) -- might be faster
+ if attr == 1 then
+ -- bidi parsing mode
+ elseif attr ~= prevattr then
+ -- no pop, grouped driven (2=normal,3=lro,4=rlo)
+ if attr == 3 then
+ if trace_mirroring then
+ list[#list+1] = format("override right -> left (lro) (bidi=%s)",attr)
+ end
+ lro, rlo = true, false
+ elseif attr == 4 then
+ if trace_mirroring then
+ list[#list+1] = format("override left -> right (rlo) (bidi=%s)",attr)
+ end
+ lro, rlo = false, true
+ else
+ if trace_mirroring and
+ current ~= head then list[#list+1] = format("override reset (bidi=%s)",attr)
+ end
+ lro, rlo = false, false
+ end
+ prevattr = attr
+ end
+ end
+ if id == glyph then
+ glyphs = true
+ if attr and attr > 0 then
+ local char = current.char
+ local d = directions[char]
+ if rlo or override > 0 then
+ if d == "l" then
+ if trace_mirroring then
+ list[#list+1] = format("char %s (%s / U+%04X) of class %s overidden to r (bidi=%s)",utfchar(char),char,char,d,attr)
+ end
+ d = "r"
+ elseif trace_mirroring then
+ if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
+ list[#list+1] = format("override char of class %s (bidi=%s)",d,attr)
+ else -- todo: rle lre
+ list[#list+1] = format("char %s (%s / U+%04X) of class %s (bidi=%s)",utfchar(char),char,char,d,attr)
+ end
+ end
+ elseif lro or override < 0 then
+ if d == "r" or d == "al" then
+ set_attribute(current,state,4) -- maybe better have a special bidi attr value -> override (9) -> todo
+ if trace_mirroring then
+ list[#list+1] = format("char %s (%s / U+%04X) of class %s overidden to l (bidi=%s) (state=isol)",utfchar(char),char,char,d,attr)
+ end
+ d = "l"
+ elseif trace_mirroring then
+ if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
+ list[#list+1] = format("override char of class %s (bidi=%s)",d,attr)
+ else -- todo: rle lre
+ list[#list+1] = format("char %s (%s / U+%04X) of class %s (bidi=%s)",utfchar(char),char,char,d,attr)
+ end
+ end
+ elseif trace_mirroring then
+ if d == "lro" or d == "rlo" or d == "pdf" then -- else side effects on terminal
+ list[#list+1] = format("override char of class %s (bidi=%s)",d,attr)
+ else -- todo: rle lre
+ list[#list+1] = format("char %s (%s / U+%04X) of class %s (bidi=%s)",utfchar(char),char,char,d,attr)
+ end
+ end
+ if d == "on" then
+ local mirror = chardata[char].mirror -- maybe make a special mirror table
+ if mirror and fontdata[current.font].characters[mirror] then
+ -- todo: set attribute
+ if autodir < 0 then
+ current.char = mirror
+ done = true
+ --~ elseif left or autodir > 0 then
+ --~ if not is_right(current.prev) then
+ --~ current.char = mirror
+ --~ done = true
+ --~ end
+ end
+ end
+ elseif d == "l" or d == "en" then -- european number
+ if autodir <= 0 then
+ force_auto_left_before()
+ end
+ elseif d == "r" or d == "al" or d == "an" then -- arabic left, arabic number
+ if autodir >= 0 then
+ force_auto_right_before()
+ end
+ elseif d == "lro" then -- Left-to-Right Override -> right becomes left
+ if trace_mirroring then
+ list[#list+1] = "override right -> left"
+ end
+ top = top + 1
+ stack[top] = { override, embedded }
+ override = -1
+ obsolete[#obsolete+1] = current
+ elseif d == "rlo" then -- Right-to-Left Override -> left becomes right
+ if trace_mirroring then
+ list[#list+1] = "override left -> right"
+ end
+ top = top + 1
+ stack[top] = { override, embedded }
+ override = 1
+ obsolete[#obsolete+1] = current
+ elseif d == "lre" then -- Left-to-Right Embedding -> TLT
+ if trace_mirroring then
+ list[#list+1] = "embedding left -> right"
+ end
+ top = top + 1
+ stack[top] = { override, embedded }
+ embedded = 1
+ obsolete[#obsolete+1] = current
+ elseif d == "rle" then -- Right-to-Left Embedding -> TRT
+ if trace_mirroring then
+ list[#list+1] = "embedding right -> left"
+ end
+ top = top + 1
+ stack[top] = { override, embedded }
+ embedded = 1
+ obsolete[#obsolete+1] = current
+ elseif d == "pdf" then -- Pop Directional Format
+ -- override = 0
+ if top > 0 then
+ local s = stack[top]
+ override, embedded = s[1], s[2]
+ top = top - 1
+ if trace_mirroring then
+ list[#list+1] = format("state: override: %s, embedded: %s, autodir: %s",override,embedded,autodir)
+ end
+ else
+ if trace_mirroring then
+ list[#list+1] = "pop (error, too many pops)"
+ end
+ end
+ obsolete[#obsolete+1] = current
+ end
+ else
+ if trace_mirroring then
+ local char = current.char
+ local d = directions[char]
+ list[#list+1] = format("char %s (%s / U+%04X) of class %s (no bidi)",utfchar(char),char,char,d)
+ end
+ end
+ elseif id == whatsit then
+ if finish then
+ finish_auto_before()
+ end
+ local subtype = current.subtype
+ if subtype == 6 then
+ local dir = current.dir
+ local d = dir:sub(2,2)
+ if dir:find(".R.") then
+ autodir = -1
+ else
+ autodir = 1
+ end
+ embeddded = autodir
+ if trace_mirroring then
+ list[#list+1] = format("pardir %s",dir)
+ end
+ elseif subtype == 7 then
+ local dir = current.dir
+ local sign = dir:sub(1,1)
+ local dire = dir:sub(3,3)
+ if dire == "R" then
+ if sign == "+" then
+ finish, autodir = "TRT", -1
+ else
+ finish, autodir = nil, 0
+ end
+ else
+ if sign == "+" then
+ finish, autodir = "TLT", 1
+ else
+ finish, autodir = nil, 0
+ end
+ end
+ if trace_mirroring then
+ list[#list+1] = format("textdir %s",dir)
+ end
+ end
+ else
+ if trace_mirroring then
+ list[#list+1] = format("node %s (subtype %s)",node.type(id),current.subtype)
+ end
+ if finish then
+ finish_auto_before()
+ end
+ end
+ local cn = current.next
+ if not cn then
+ if finish then
+ finish_auto_after()
+ end
+ end
+ current = cn
+ end
+ end
+ if trace_mirroring and glyphs then
+ logs.report("bidi","start log")
+ for i=1,#list do
+ logs.report("bidi","%02i: %s",i,list[i])
+ end
+ logs.report("bidi","stop log")
+ end
+ if done and mirror.strip then
+ local n = #obsolete
+ if n > 0 then
+ for i=1,n do
+ remove_node(head,obsolete[i],true)
+ end
+ logs.report("bidi","%s character nodes removed",n)
+ end
+ end
+ return head, done
+end
+
+--~ local function is_right(n) -- keep !
+--~ if n then
+--~ local id = n.id
+--~ if id == glyph then
+--~ local attr = has_attribute(n,attribute)
+--~ if attr and attr > 0 then
+--~ local d = directions[n.char]
+--~ if d == "r" or d == "al" then -- override
+--~ return true
+--~ end
+--~ end
+--~ end
+--~ end
+--~ return false
+--~ end
+
+chars.handle_mirroring = nodes.install_attribute_handler {
+ name = "mirror",
+ namespace = mirror,
+ processor = mirror.process,
+}
diff --git a/tex/context/base/typo-mir.tex b/tex/context/base/typo-mir.tex
new file mode 100644
index 000000000..fe9d793e0
--- /dev/null
+++ b/tex/context/base/typo-mir.tex
@@ -0,0 +1,144 @@
+%D \module
+%D [ file=typo-mir,
+%D version=2009.03.27, % code moved from core-spa.mkiv
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Mirroring,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Typesetting Macros / Mirroring}
+
+\unprotect
+
+\registerctxluafile{typo-mir}{1.001}
+
+\definesystemattribute[mirror]
+
+% experimental mirroring
+
+\def\setcharactermirroring
+ {\ctxlua{mirror.enabled=true}%
+ \gdef\setcharactermirroring[##1]{\dosetattribute{mirror}{\number##1}}%
+ \setcharactermirroring}
+
+\def\resetcharactermirroring
+ {\doresetattribute{mirror}}
+
+\newtoks\everysetupdirections
+
+\def\setupdirections[#1]% there will be more like setting up directions themselves
+ {\getparameters[\??di][#1]%
+ \the\everysetupdirections}
+
+\chardef\directionsbidimode=0
+
+\letvalue{\??di:bidi:\v!off }\zerocount
+\letvalue{\??di:bidi:\v!global}\plusone
+\letvalue{\??di:bidi:\v!local }\plustwo
+\letvalue{\??di:bidi:\v!on }\plustwo
+
+\appendtoks
+ \chardef\directionsbidimode\executeifdefined{\??di:bidi:\@@dibidi}\zerocount\relax
+ \ifcase\directionsbidimode
+ \resetcharactermirroring
+ \or
+ \setcharactermirroring[1]% global, chars
+ \or
+ \setcharactermirroring[2]% local, attributes
+ \or
+ \setcharactermirroring[1]% default
+ \fi
+\to \everysetupdirections
+
+% bidi: local=obey grouping, global=ignore grouping (unicode has no grouping)
+
+\setupdirections % maybe start/stop
+ [bidi=\v!off]
+
+\unexpanded\def\bidilre{\utfchar{"0x202A}}
+\unexpanded\def\bidirle{\utfchar{"0x202B}}
+\unexpanded\def\bidipop{\utfchar{"0x202C}}
+\unexpanded\def\bidilro{\utfchar{"0x202D}}
+\unexpanded\def\bidirlo{\utfchar{"0x202E}}
+
+\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi}
+\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi}
+\unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setcharactermirroring[3]\fi}
+\unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setcharactermirroring[4]\fi}
+
+% for the moment: \setcharactermirroring[\plusone]
+
+\protect \endinput
+
+% bidi test
+
+\definefontfeature
+ [arab]
+ [mode=node,language=dflt,script=arab,
+ init=yes,medi=yes,fina=yes,isol=yes,
+ liga=yes,dlig=yes,rlig=yes,clig=yes,
+ mark=yes,mkmk=yes,kern=yes,curs=yes]
+
+\font\Arabic=arabtype*arab at 20pt
+
+\def\LATIN{LATIN} {\setcharactermirroring[1]} % enable this
+\def\ARAB {محمد}
+
+\startluacode
+ function document.split_tokens(str)
+ for s in str:bytes() do
+ tex.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s))
+ end
+ end
+\stopluacode
+
+\def\biditest#1#2#3% font text raw
+ {\dontleavehmode\hbox
+ {\framed[offset=overlay]{\tttf#2}\quad
+ \ctxlua{mirror.trace = true}%
+ \framed[offset=overlay]{#1#3}\quad
+ \ctxlua{mirror.trace = false}
+ \tttf\ctxlua{document.split_tokens([[\detokenize{#3}]])}}}
+
+\startbuffer[bidi-sample]
+\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par
+\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par
+\biditest\Arabic{LATIN ARAB}{\textdir TLT{\bidilro \LATIN\ \ARAB}}\par % right -> left
+\biditest\Arabic{LATIN ARAB}{\textdir TRT{\bidilro \LATIN\ \ARAB}}\par % right -> left
+\biditest\Arabic{BARA NITAL}{\textdir TLT{\bidirlo \LATIN\ \ARAB}}\par % left -> right
+\biditest\Arabic{BARA NITAL}{\textdir TRT{\bidirlo \LATIN\ \ARAB}}\par % left -> right
+\stopbuffer
+
+\startbuffer[bidi-sample]
+\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par
+\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par
+\biditest\Arabic{LATIN ARAB}{\textdir TLT\bidilro \LATIN\ \ARAB}\par % right -> left
+\biditest\Arabic{LATIN ARAB}{\textdir TRT\bidilro \LATIN\ \ARAB}\par % right -> left
+\biditest\Arabic{BARA NITAL}{\textdir TLT\bidirlo \LATIN\ \ARAB}\par % left -> right
+\biditest\Arabic{BARA NITAL}{\textdir TRT\bidirlo \LATIN\ \ARAB}\par % left -> right
+\stopbuffer
+
+\startbuffer[bidi-setup]
+\setupdirections[bidi=off]
+\stopbuffer
+
+{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
+
+\startbuffer[bidi-setup]
+\setupdirections[bidi=global]
+\stopbuffer
+
+{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
+
+\startbuffer[bidi-setup]
+\setupdirections[bidi=local]
+\stopbuffer
+
+{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]}
+
+\stoptext
diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua
new file mode 100644
index 000000000..c134fc281
--- /dev/null
+++ b/tex/context/base/typo-spa.lua
@@ -0,0 +1,149 @@
+if not modules then modules = { } end modules ['typo-spa'] = {
+ version = 1.001,
+ comment = "companion to typo-spa.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utf = unicode.utf8
+
+local next, type = next, type
+local utfchar = utf.char
+
+local trace_hspacing = false trackers.register("nodes.hspacing", function(v) trace_hspacing = v end)
+
+local has_attribute = node.has_attribute
+local unset_attribute = node.unset_attribute
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+local remove_node = nodes.remove
+local make_penalty_node = nodes.penalty
+local make_glue_node = nodes.glue
+local glyph = node.id("glyph")
+local fontdata = fonts.ids
+
+spacings = spacings or { }
+spacings.mapping = spacings.mapping or { }
+spacings.enabled = false
+
+storage.register("spacings/mapping", spacings.mapping, "spacings.mapping")
+
+function spacings.setspacing(id,char,left,right,alternative)
+ local mapping = spacings.mapping[id]
+ if not mapping then
+ mapping = { }
+ spacings.mapping[id] = mapping
+ end
+ local map = mapping[char]
+ if not map then
+ map = { }
+ mapping[char] = map
+ end
+ map.left, map.right, map.alternative = left, right, alternative
+end
+
+function spacings.process(namespace,attribute,head)
+ local done, mapping = false, spacings.mapping
+ local start = head
+ -- head is always begin of par (whatsit), so we have at least two prev nodes
+ -- penalty followed by glue
+ while start do
+ if start.id == glyph then
+ local attr = has_attribute(start,attribute)
+ if attr and attr > 0 then
+ local map = mapping[attr]
+ if map then
+ map = map[start.char]
+ unset_attribute(start,attribute)
+ if map then
+ local left, right, alternative = map.left, map.right, map.alternative
+ local quad = fontdata[start.font].parameters.quad
+ local prev = start.prev
+ if left and left ~= 0 and prev then
+ local ok = false
+ if alternative == 1 then
+ local somespace = nodes.somespace(prev,true)
+ if somespace then
+ local prevprev = prev.prev
+ local somepenalty = nodes.somepenalty(prevprev,10000)
+ if somepenalty then
+ if trace_hspacing then
+ logs.report("spacing","removing penalty and space before %s", utfchar(start.char))
+ end
+ head, _ = remove_node(head,prev,true)
+ head, _ = remove_node(head,prevprev,true)
+ else
+ local somespace = nodes.somespace(prev,true)
+ if somespace then
+ if trace_hspacing then
+ logs.report("spacing","removing space before %s", utfchar(start.char))
+ end
+ head, _ = remove_node(head,prev,true)
+ end
+ end
+ end
+ ok = true
+ else
+ ok = not (nodes.somespace(prev,true) and nodes.somepenalty(prev.prev,true)) or nodes.somespace(prev,true)
+ end
+ if ok then
+ if trace_hspacing then
+ logs.report("spacing","inserting penalty and space before %s", utfchar(start.char))
+ end
+ insert_node_before(head,start,make_penalty_node(10000))
+ insert_node_before(head,start,make_glue_node(tex.scale(quad,left)))
+ done = true
+ end
+ end
+ local next = start.next
+ if right and right ~= 0 and next then
+ local ok = false
+ if alternative == 1 then
+ local somepenalty = nodes.somepenalty(next,10000)
+ if somepenalty then
+ local nextnext = next.next
+ local somespace = nodes.somespace(nextnext,true)
+ if somespace then
+ if trace_hspacing then
+ logs.report("spacing","removing penalty and space after %s", utfchar(start.char))
+ end
+ head, _ = remove_node(head,next,true)
+ head, _ = remove_node(head,nextnext,true)
+ end
+ else
+ local somespace = nodes.somespace(next,true)
+ if somespace then
+ if trace_hspacing then
+ logs.report("spacing","removing space after %s", utfchar(start.char))
+ end
+ head, _ = remove_node(head,next,true)
+ end
+ end
+ ok = true
+ else
+ ok = not (nodes.somepenalty(next,10000) and nodes.somespace(next.next,true)) or nodes.somespace(next,true)
+ end
+ if ok then
+ if trace_hspacing then
+ logs.report("spacing","inserting penalty and space after %s", utfchar(start.char))
+ end
+ insert_node_after(head,start,make_glue_node(tex.scale(quad,right)))
+ insert_node_after(head,start,make_penalty_node(10000))
+ done = true
+ end
+ end
+ end
+ end
+ end
+ end
+ start = start.next
+ end
+ return head, done
+end
+
+lists.handle_spacing = nodes.install_attribute_handler {
+ name = "spacing",
+ namespace = spacings,
+ processor = spacings.process,
+}
diff --git a/tex/context/base/typo-spa.tex b/tex/context/base/typo-spa.tex
new file mode 100644
index 000000000..d1b855edd
--- /dev/null
+++ b/tex/context/base/typo-spa.tex
@@ -0,0 +1,69 @@
+%D \module
+%D [ file=typo-spa,
+%D version=2009.03.27, % code moved from cors-spa.mkiv
+%D title=\CONTEXT\ Typesetting Macros,
+%D subtitle=Spacing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%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 Typesetting Macros / Spacing}
+
+\unprotect
+
+\registerctxluafile{typo-spa}{1.001}
+
+\definesystemattribute[spacing]
+
+% experimental spacing
+%
+% test: oeps {\setcharacterspacing[frenchpunctuation]x: xx \bfd x: xx} oeps: test
+
+\newcount \maxcharacterspacingid
+
+\def\definecharacterspacing[#1]%
+ {\ifcsname\??ch#1\endcsname \else
+ \global\advance\maxcharacterspacingid\plusone
+ \setxvalue{\??ch:#1}{\the\maxcharacterspacingid}%
+ \fi}
+
+\def\setupcharacterspacing
+ {\dotripleargument\dosetupcharacterspacing}
+
+\def\dosetupcharacterspacing[#1][#2][#3]%
+ {\ifcsname\??ch:#1\endcsname
+ \begingroup % for the moment we use modes, in ordere to avoid interface translation
+ \getparameters[\??ch][\c!left=0,\c!right=0,\c!alternative=0,#3]%
+ \ctxlua{spacings.setspacing(\getvalue{\??ch:#1},\number#2,\@@chleft,\@@chright,\@@chalternative)}%
+ \endgroup
+ \fi}
+
+\def\setcharacterspacing
+ {\ctxlua{spacings.enabled=true}%
+ \gdef\setcharacterspacing[##1]{\dosetattribute{spacing}{\csname\??ch:##1\endcsname}}%
+ \setcharacterspacing}
+
+\def\resetcharacterspacing
+ {\doresetattribute{spacing}}
+
+\letvalue{\??ch:\s!reset}\attributeunsetvalue
+
+% \setcharacterspacing[frenchpunctuation]
+% «\type{bla}»\crlf « \type{bla}»\crlf
+% «bla »\crlf « bla»\crlf « bla »\crlf
+% bla: bla\crlf bla : bla
+
+\definecharacterspacing [frenchpunctuation] % name may change / unit is em
+
+\setupcharacterspacing [frenchpunctuation] ["003A] [\c!left =.25,\c!alternative=1] % : % strip preceding space(char)
+\setupcharacterspacing [frenchpunctuation] ["003B] [\c!left =.25,\c!alternative=1] % ; % strip preceding space(char)
+\setupcharacterspacing [frenchpunctuation] ["003F] [\c!left =.25,\c!alternative=1] % ? % strip preceding space(char)
+\setupcharacterspacing [frenchpunctuation] ["0021] [\c!left =.25,\c!alternative=1] % ! % strip preceding space(char)
+\setupcharacterspacing [frenchpunctuation] ["00AB] [\c!right=.25,\c!alternative=1] % guillemotleft/leftguillemot % strip following space(char)
+\setupcharacterspacing [frenchpunctuation] ["00BB] [\c!left =.25,\c!alternative=1] % guillemotright/rightguillemot % strip preceding space(char)
+
+\protect \endinput
diff --git a/tex/context/base/unic-035.tex b/tex/context/base/unic-035.tex
new file mode 100644
index 000000000..272799512
--- /dev/null
+++ b/tex/context/base/unic-035.tex
@@ -0,0 +1,32 @@
+%D \module
+%D [ file=unic-035,
+%D version=2009.05.25,
+%D title=\CONTEXT\ \UNICODE\ Macros,
+%D subtitle=Vector 35,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+
+\unprotect
+
+\startunicodevector 35
+ \expandafter\strippedcsname
+ \ifcase\numexpr#1\relax
+ \varnothing \or % DIAMETER SIGN
+ \unknownchar \or % ELECTRIC ARROW
+ \unknownchar \or % HOUSE
+ \unknownchar \or % UP ARROWHEAD
+ \unknownchar \or % DOWN ARROWHEAD
+ \unknownchar \or % PROJECTIVE
+ \unknownchar \or % PERSPECTIVE
+ \unknownchar \or % WAVY LINE
+ \lceil \or % LEFT CEILING
+ \rceil \or % RIGHT CEILING
+ \lfloor \or % LEFT FLOOR
+ \rfloor \or % RIGHT FLOOR
+ \unknownchar \else
+ \unknownchar %
+ \fi
+\stopunicodevector
+
+\protect \endinput
diff --git a/tex/context/base/unic-exp.tex b/tex/context/base/unic-exp.tex
index 7d7f9f0c5..027aedab8 100644
--- a/tex/context/base/unic-exp.tex
+++ b/tex/context/base/unic-exp.tex
@@ -2,7 +2,7 @@
%D [ file=unic-exp,
%D version=2002.12.05,
%D title=\CONTEXT\ \UNICODE\ Support,
-%D subtitle=\UNICODE\ vector expansion,
+%D subtitle=Expansion,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context UNICODE Macros (expansion)}
+\writestatus{loading}{ConTeXt Unicode Support / Expansion)}
%D \macros
%D {expandunivector}
diff --git a/tex/context/base/unic-ini.mkii b/tex/context/base/unic-ini.mkii
index 27ef38620..0e4d9d391 100644
--- a/tex/context/base/unic-ini.mkii
+++ b/tex/context/base/unic-ini.mkii
@@ -2,7 +2,7 @@
%D [ file=unic-ini,
%D version=2002.12.03,
%D title=\CONTEXT\ \UNICODE\ Support,
-%D subtitle=\UNICODE\ \& UTF-8 support,
+%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context UNICODE Macros (ini)}
+\writestatus{loading}{ConTeXt Unicode Support / Initialization}
%D Sorry, we only support his in \ETEX.
@@ -725,9 +725,9 @@
\def\numbertohexstring#1{0x\uchexnumbers{\utfdiv{#1}}\uchexnumbers{\utfmod{#1}}}
-\beginXETEX
+\ifnum\texengine=\xetexengine
\let\numbertoutf\numbertohexstring
-\endXETEX
+\fi
\def\uchartoutf#1#2%
{\expandafter\numbertoutf\expandafter{\the\numexpr#1*\utf@h+#2\relax}}
@@ -767,7 +767,7 @@
%D Well, let's at least preload a few familiar ones. Here we
%D also load the \UTF\ regime.
-\useunicodevector[0,1,2,3,4,5,30,31,32,33,34,37,39,251]
+\useunicodevector[0,1,2,3,4,5,30,31,32,33,34,35,37,39,251]
\useunicodevector[cjk]
\useregime[utf]
diff --git a/tex/context/base/unic-ini.mkiv b/tex/context/base/unic-ini.mkiv
index a174f7a39..8b0c819d9 100644
--- a/tex/context/base/unic-ini.mkiv
+++ b/tex/context/base/unic-ini.mkiv
@@ -11,23 +11,14 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context UNICODE Macros (ini)}
+\writestatus{loading}{ConTeXt Unicode Support / Initialization}
%D Much of this is not needed at all in \LUATEX\ and we can save some
%D 50K on the compressed format.
\unprotect
-\def\keeputfcharacters {}
-\def\registerprivateunicodechar#1 {}
-\def\defineunicodecommand #1 #2{}
-\def\doifunicodevector #1{\firstofoneargument}
-\def\useunicodevector [#1]{}
-\def\startunicodevector #1\stopunicodevector{}
-\def\unicodeinfoline #1#2#3{}
-\def\cleanunicodechar #1{#1}
-\def\unicodeunknowncharacter {\unknownchar}
-
+\let \keeputfcharacters\relax
\chardef\utfunicodetracer \zerocount
\chardef\utfunicommandmode\zerocount
@@ -39,10 +30,4 @@
\ifx\zwnbsp\undefined \let\zwnbsp\relax \fi % zerowidthnonbreakablespace
-\def\showunicodevector[#1]{}
-\def\showunicodetable [#1]{}
-
-% \fetchruntimecommand \showunicodevector {\f!unicprefix\s!run}
-% \fetchruntimecommand \showunicodetable {\f!unicprefix\s!run}
-
\protect \endinput
diff --git a/tex/context/base/verb-c.tex b/tex/context/base/verb-c.tex
index d2f708a8d..1ecb0afc2 100644
--- a/tex/context/base/verb-c.tex
+++ b/tex/context/base/verb-c.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Support Macros / Pretty C Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty C Verbatim}
% HH:
%
diff --git a/tex/context/base/verb-eif.tex b/tex/context/base/verb-eif.tex
index 16ee611e1..5904abc6e 100644
--- a/tex/context/base/verb-eif.tex
+++ b/tex/context/base/verb-eif.tex
@@ -8,13 +8,13 @@
%D copyright={Berend de Boer \& 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.
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
% This module will be cleaned up a bit in the process of more
% flexible verbatim options.
-\writestatus{loading}{Context Support Macros / Pretty EIFFEL Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty EIFFEL Verbatim}
%D \startbuffer
%D \startEIFFEL
@@ -32,7 +32,7 @@
%D
%D end
%D \stopEIFFEL
-%D \stopbuffer
+%D \stopbuffer
%D
%D
%D If a variable in a comment is quoted with `..', it is typeset
@@ -41,18 +41,18 @@
%D \startbuffer
%D \startEIFFEL
%D class TEST
-%D
+%D
%D feature
-%D
+%D
%D say (something: STRING) is
%D -- say `something' to stdout
%D do
%D print (something)
%D end
-%D
+%D
%D end -- class TEST
%D \stopEIFFEL
-%D \stopbuffer
+%D \stopbuffer
%D
%D
%D Recommended, OOSC2 style setting is:
@@ -71,7 +71,7 @@
%D \EIFFEL\ has only the one line comment sequence \type{--}.
\gdef\EIFsetspecials%
- {\PLsetspecials
+ {\PLsetspecials
\setpretty`\#=32
\setpretty`\{=33 \setpretty`\}=33
\setpretty`\[=33 \setpretty`\]=33 \setpretty`\(=33 \setpretty`\)=33
@@ -80,7 +80,7 @@
\setpretty`\==33 \setpretty`\~=33 \setpretty`\<=33 \setpretty`\>=33
\setpretty`\-=33 \setpretty`\+=33 \setpretty`\/=33 \setpretty`\*=33
\setpretty`\^=33
- \setpretty`\%=41 \setpretty`\-=45
+ \setpretty`\%=41 \setpretty`\-=45
\setpretty`\`=81 \setpretty`\'=82 }
\gdef\EIFsethandlers%
@@ -119,7 +119,7 @@
{\endPLtypesix
\ifinPLcomment
\getpretty{#1}%
- \else
+ \else
{\prettynaturalfont\/%
\beginofpretty[\!!prettythree]\getpretty{#1}\endofpretty}%
\fi}
@@ -208,4 +208,4 @@
\useprettyidentifiers \EIFvariables \EIFsetspecials
not-yet-defined
-\protect \endinput
+\protect \endinput
diff --git a/tex/context/base/verb-ini.tex b/tex/context/base/verb-ini.tex
index 27c30d20e..4726d0eac 100644
--- a/tex/context/base/verb-ini.tex
+++ b/tex/context/base/verb-ini.tex
@@ -41,7 +41,7 @@
%D \TEX\ supposed to do when it encounters a \type{$} or an
%D \type{#}? This module deals with these matters.
-\writestatus{loading}{Context Verbatim Macros / Initialization}
+\writestatus{loading}{ConTeXt Verbatim Macros / Initialization}
%D The verbatim environment has some features, like coloring
%D \TEX\ text, seldom found in other environments. Especially
diff --git a/tex/context/base/verb-js.tex b/tex/context/base/verb-js.tex
index e8c2e6b5d..3d1b69f8b 100644
--- a/tex/context/base/verb-js.tex
+++ b/tex/context/base/verb-js.tex
@@ -8,26 +8,26 @@
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
-\writestatus{loading}{Context Support Macros / Pretty JavaScript Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty JavaScript Verbatim}
%D In \CONTEXT\ we support \JAVASCRIPT\ inclusion in \PDF\
%D documents and thereby enter the field of authoring. Of
%D course we also want to pretty print such scripts, that look
-%D like:
-%D
+%D like:
+%D
%D \startJS
-%D alfa = beta*2 ; // both alfa and beta are numbers // indeed
+%D alfa = beta*2 ; // both alfa and beta are numbers // indeed
%D if (odd(alfa))
-%D { do_something() }
+%D { do_something() }
%D else
%D { do_nothing() } /* As we can see /* in this example */ there
%D how_about(alfa) ; is no fi needed. Also no semicolons are
%D or_about(beta) ; needed after a right brace. */
%D \stopJS
-%D
+%D
%D Because \JAVASCRIPT\ looks much like \PERL, we will use
%D a slightly adapted \PERL\ visualization. First we load the
%D \PERL\ module:
@@ -168,4 +168,4 @@
\useprettyidentifiers \JSvariables \JSsetspecials
not-yet-defined
-\protect \endinput
+\protect \endinput
diff --git a/tex/context/base/verb-jv.tex b/tex/context/base/verb-jv.tex
index d55394d2c..197b37ee7 100644
--- a/tex/context/base/verb-jv.tex
+++ b/tex/context/base/verb-jv.tex
@@ -8,19 +8,19 @@
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
-\writestatus{loading}{Context Support Macros / Pretty Java Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty Java Verbatim}
%D This module differs from the \JAVASCRIPT\ driver in its
%D handling of comments. We also need a few more handlers: one
%D for \type {//} and \type {/*} and one for \type {*/} as
-%D well as the \JAVA doc trigger \type {/**}.
+%D well as the \JAVA doc trigger \type {/**}.
%D We build this driver on top of the \PERL\ one. Since this
-%D driver looks much like the \JAVASCRIPT\ one, we don't
-%D comment it extensively.
+%D driver looks much like the \JAVASCRIPT\ one, we don't
+%D comment it extensively.
\ifx\undefined\setupprettyPLtype \input verb-pl \relax \fi
@@ -32,14 +32,14 @@
{\PLsetspecials
\setpretty`\#=32
\setpretty`\%=41
- \setpretty`\-=45
+ \setpretty`\-=45
\setpretty`\/=43
\setpretty`\*=44 }
\gdef\JVsethandlers
{\PLsethandlers
\installprettyhandler 43 \JVtypefourthree
- \installprettyhandler 44 \JVtypefourfour
+ \installprettyhandler 44 \JVtypefourfour
\installprettyhandler 45 \JVtypefourfive }
\gdef\JVsetcontrols
@@ -128,7 +128,7 @@
\global\advance\JVcommentlevel -1
\ifcase\JVcommentlevel \global\inPLcommentfalse \fi
\else
- \ifPLdocdone
+ \ifPLdocdone
\getpretty{#1}%
\else
\beginofpretty[\!!prettyone]\getpretty{#1}\endofpretty
@@ -150,7 +150,7 @@
\expandafter#2%
\fi}
-\gdef\JVtypefourfive % permit - in javadoc @tags
+\gdef\JVtypefourfive % permit - in javadoc @tags
{\ifinPLdoc
\@EA\PLtypesixtwo
\else
@@ -164,35 +164,35 @@
int interface long native new null package private protected
public return short static strictfp super switch synchronized
this throw throws transient true try void volatile while
-
+
\useprettyidentifiers \JVvariables \JVsetspecials
- @author @docRoot @deprecated @exception @inheritDoc @link
- @linkplain @param @return @see @serial @serialData @serialField
- @since @throws @value @version
-
-%D The \JAVA doc feature was requested by Robert F.~Beeger,
-%D who also provided this test class:
-%D
-%D \startJV
+ @author @docRoot @deprecated @exception @inheritDoc @link
+ @linkplain @param @return @see @serial @serialData @serialField
+ @since @throws @value @version
+
+%D The \JAVA doc feature was requested by Robert F.~Beeger,
+%D who also provided this test class:
+%D
+%D \startJV
%D package de.jwamalpha.handling.web.rbdipl;
-%D
+%D
%D import java.io.IOException;
%D import java.io.PrintWriter;
%D import javax.servlet.http.HttpServlet;
%D import javax.servlet.http.HttpServletRequest;
%D import javax.servlet.http.HttpServletResponse;
%D import javax.servlet.ServletException;
-%D
+%D
%D /**
%D * The simple login servlet
%D *
%D * @author Robert F. Beeger
%D * @version 1.0
%D */
-%D
+%D
%D public class LoginServlet extends HttpServlet
%D {
-%D //
+%D //
%D // public interface
%D //
%D /**
@@ -217,6 +217,6 @@
%D writer.flush();
%D }
%D }
-%D \stopJV
+%D \stopJV
-\protect \endinput
+\protect \endinput
diff --git a/tex/context/base/verb-lua.lua b/tex/context/base/verb-lua.lua
index ba0e24460..9ba22c1f2 100644
--- a/tex/context/base/verb-lua.lua
+++ b/tex/context/base/verb-lua.lua
@@ -6,6 +6,12 @@
-- BROKEN : result is now table
+local utf = unicode.utf8
+
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+
+local ctxcatcodes = tex.ctxcatcodes
+
if not buffers then buffers = { } end
if not buffers.visualizers then buffers.visualizers = { } end
if not buffers.visualizers.lua then buffers.visualizers.lua = { } end
@@ -146,7 +152,7 @@ function buffers.visualizers.lua.flush_line(str, nested)
--~ end
--~ end
--~ -- bla bla1 bla.bla
---~ for c in code:utfcharacters() do
+--~ for c in utfcharacters(code) do
--~ if instr then
--~ if c == s then
--~ if inesc then
@@ -205,6 +211,6 @@ function buffers.visualizers.lua.flush_line(str, nested)
--~ else
--~ state, result = buffers.finish_state(state,result)
--~ end
---~ tex.sprint(tex.ctxcatcodes,result)
+--~ tex.sprint(ctxcatcodes,result)
return "not yet finished"
end
diff --git a/tex/context/base/verb-mp.lua b/tex/context/base/verb-mp.lua
index 1182888b0..4ff957b41 100644
--- a/tex/context/base/verb-mp.lua
+++ b/tex/context/base/verb-mp.lua
@@ -4,6 +4,10 @@
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
+local utf = unicode.utf8
+
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+
if not buffers then buffers = { } end
if not buffers.visualizers then buffers.visualizers = { } end
if not buffers.visualizers.mp then buffers.visualizers.mp = { } end
@@ -177,7 +181,7 @@ function buffers.visualizers.mp.flush_line_(str,nested)
local byte, find = utf.byte, utf.find
local finish, change = buffers.finish_state, buffers.change_state
buffers.currentcolors = buffers.visualizers.mp.colors
- for c in str:utfcharacters() do
+ for c in utfcharacters(str) do
if incomment then
result[#result+1] = buffers.escaped_chr(c)
elseif c == '%' then
diff --git a/tex/context/base/verb-mp.tex b/tex/context/base/verb-mp.tex
index 318da96bf..7affaf0c4 100644
--- a/tex/context/base/verb-mp.tex
+++ b/tex/context/base/verb-mp.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Support Macros / Pretty METAPOST Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty METAPOST Verbatim}
% bug: in mp-char.mp the char should not be highlighted
diff --git a/tex/context/base/verb-pas.tex b/tex/context/base/verb-pas.tex
index b7b041700..0c9850abf 100644
--- a/tex/context/base/verb-pas.tex
+++ b/tex/context/base/verb-pas.tex
@@ -14,7 +14,7 @@
% This module will be cleaned up a bit in the process of more
% flexible verbatim options.
-\writestatus{loading}{Context Support Macros / Pretty PASCAL Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty PASCAL Verbatim}
%D Typeset Pascal(-like) code:
%D
@@ -87,14 +87,14 @@
\PASsetspecials
\PLsetdiagnostics}
-
% the // and /* comments
\gdef\PAStypefourthree%
{\handlenextnextpretty\doPAStypefourthree\PLtypefourtwo}
\gdef\doPAStypefourthree#1#2%
- {\ifinPLcomment
+ {\endPLtypesix
+ \ifinPLcomment
\let\next=\PLtypefourtwo
\else
\ifinPLsingle
diff --git a/tex/context/base/verb-pl.tex b/tex/context/base/verb-pl.tex
index cbe82d49f..47ce9a54f 100644
--- a/tex/context/base/verb-pl.tex
+++ b/tex/context/base/verb-pl.tex
@@ -8,46 +8,46 @@
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
-\writestatus{loading}{Context Support Macros / Pretty PERL Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty PERL Verbatim}
-%D When I rewrote \TEXUTIL\ in \PERL\ I decided to write a
-%D pretty \PERL\ interpreter too. In fact, this was the main
-%D reason for rewriting the pretty verbatim mechanisms to
-%D handle more that \TEX.
+%D When I rewrote \TEXUTIL\ in \PERL\ I decided to write a
+%D pretty \PERL\ interpreter too. In fact, this was the main
+%D reason for rewriting the pretty verbatim mechanisms to
+%D handle more that \TEX.
%D
-%D \startPL
+%D \startPL
%D $alfa = $beta{gamma};
-%D if ($alfa="delta")
+%D if ($alfa="delta")
%D { print "epsilon" }
%D \stopPL
-%D
-%D When looking at the macros, watch the \type{\doglobal}'s!
-%D They're something \CONTEXT\ specific.
+%D
+%D When looking at the macros, watch the \type{\doglobal}'s!
+%D They're something \CONTEXT\ specific.
\unprotect
%D \macros
%D {prettyPLvariables}
%D
-%D Identifiers and system variables get a special treatment.
-%D One can disable this option for the variables by resetting
+%D Identifiers and system variables get a special treatment.
+%D One can disable this option for the variables by resetting
%D the next switch.
-\doglobal\newif\ifprettyPLvariables
+\doglobal\newif\ifprettyPLvariables
\global\prettyPLvariablestrue
-%D As said before, the global assignment is needed in
-%D \CONTEXT\ (for once||only loading on demand).
+%D As said before, the global assignment is needed in
+%D \CONTEXT\ (for once||only loading on demand).
\doglobal\newif\ifinPLsingle
\doglobal\newif\ifinPLdouble
\doglobal\newif\ifinPLcomment
-\doglobal\newif\ifinPLdoc % only used in java filter
-\doglobal\newif\ifPLdocdone % only used in java filter
+\doglobal\newif\ifinPLdoc % only used in java filter
+\doglobal\newif\ifPLdocdone % only used in java filter
\doglobal\newif\ifPLverbose
\newcount\PLverboseskipped
@@ -56,7 +56,7 @@
{\ifnum\PLverboseskipped>0
\obeyedspace
\advance\PLverboseskipped -1
- \@EA\PLverbosecorrection
+ \@EA\PLverbosecorrection
\fi}
\gdef\PLsetcontrols%
@@ -73,7 +73,7 @@
\global\inPLcommentfalse}%
\def\obeyedline%
{\PLverbosefalse
- \PLverboseskipped=0
+ \PLverboseskipped=0
\PLdocdonefalse
\oldobeyedline}%
\let\obeytabs=\ignoretabs}
@@ -189,7 +189,7 @@
% \beginofpretty[\!!prettytwo]\getpretty{#1}\endofpretty
% \fi\fi\fi}
-\gdef\PLtypetwo#1%
+\gdef\PLtypetwo#1%
{\endPLtypesix
\ifinPLdoc
\xdef\PLsequence{\PLsequence\getpretty{#1}}%
@@ -352,7 +352,7 @@
\global\let\PLprefix\empty
\fi}
-\gdef\doendPLtypesix#1%
+\gdef\doendPLtypesix#1%
{\doifprettyidentifierelse{\PLsequence}{\PLverboses}
{\PLverbosetrue\PLverboseskipped=3 }
{\doifprettyidentifierelse{\PLsequence}{\PLidentifiers}
@@ -369,7 +369,7 @@
\PLsequence
\fi}}}
-\gdef\doendPLtypesixvar#1%
+\gdef\doendPLtypesixvar#1%
{\doifprettyidentifierelse{\PLprefix\PLsequence}{\PLvariables}
{\beginofpretty[#1]%
{\prettyvariablefont\PLsequence}%
@@ -398,7 +398,7 @@
% \xdef\PLsequence{\PLsequence\getpretty{#1}}%
% \fi\fi\fi}
-\gdef\PLtypesixtwo#1%
+\gdef\PLtypesixtwo#1%
{\ifinPLdoc
\xdef\PLsequence{\PLsequence\getpretty{#1}}%
\else\ifinPLcomment
@@ -468,7 +468,7 @@
\else
\global\inPLcommenttrue
\PLverbosecorrection
- \ifnaturaltextext % non tested yet
+ \ifnaturaltextext % non tested yet
\let\next\naturaltextext
\else
\def\next{\beginofpretty[\!!prettythree]\getpretty{#1}\endofpretty}%
@@ -537,11 +537,11 @@
&GetOptions
%D A funny hack. When prefixes by \type{TEX}, a \type{\csname}
-%D is typeset as \TEX\ sequence.
+%D is typeset as \TEX\ sequence.
\useprettyidentifiers \PLverboses \PLsetspecials
TEX
-\protect
+\protect
-\endinput
+\endinput
diff --git a/tex/context/base/verb-sql.tex b/tex/context/base/verb-sql.tex
index ddac5cd25..a00841d73 100644
--- a/tex/context/base/verb-sql.tex
+++ b/tex/context/base/verb-sql.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Support Macros / Pretty SQL Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty SQL Verbatim}
%D \quotation {He, I want pretty pretting too!}, Berend cried out
%D one day, \quotation {But now for \SQL.}. This query language
diff --git a/tex/context/base/verb-tex.lua b/tex/context/base/verb-tex.lua
index ad72fb211..98e6eccb4 100644
--- a/tex/context/base/verb-tex.lua
+++ b/tex/context/base/verb-tex.lua
@@ -4,6 +4,10 @@
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
+local utf = unicode.utf8
+
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+
if not buffers then buffers = { } end
if not buffers.visualizers then buffers.visualizers = { } end
if not buffers.visualizers.tex then buffers.visualizers.tex = { } end
@@ -32,7 +36,7 @@ function buffers.visualizers.tex.flush_line(str,nested)
local byte, find = utf.byte, utf.find
local finish, change = buffers.finish_state, buffers.change_state
buffers.currentcolors = buffers.visualizers.tex.colors
- for c in str:utfcharacters() do
+ for c in utfcharacters(str) do
if c == " " then
if escaping then
result[#result+1] = " "
diff --git a/tex/context/base/verb-tex.tex b/tex/context/base/verb-tex.tex
index a70edd353..75e99fcef 100644
--- a/tex/context/base/verb-tex.tex
+++ b/tex/context/base/verb-tex.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context Support Macros / Pretty TEX Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty TEX Verbatim}
%D The original module \type{supp-ver} had the \TEX\
%D interpreter built in. The current implementation is more
diff --git a/tex/context/base/verb-xml.tex b/tex/context/base/verb-xml.tex
index 7b0237315..dbf6635f6 100644
--- a/tex/context/base/verb-xml.tex
+++ b/tex/context/base/verb-xml.tex
@@ -14,7 +14,7 @@
% This module will be cleaned up a bit in the process of more
% flexible verbatim options.
-\writestatus{loading}{Context Support Macros / Pretty XML Verbatim}
+\writestatus{loading}{ConTeXt Verbatim Macros / Pretty XML Verbatim}
\unprotect
diff --git a/tex/context/base/x-calcmath.lua b/tex/context/base/x-calcmath.lua
index 24ef130be..fcb6b7470 100644
--- a/tex/context/base/x-calcmath.lua
+++ b/tex/context/base/x-calcmath.lua
@@ -6,58 +6,60 @@ if not modules then modules = { } end modules ['x-calcmath'] = {
license = "see context related readme files"
}
+local format, lower, upper, gsub = string.format, string.lower, string.upper, string.gsub
tex = tex or { }
texsprint = tex.sprint or function(catcodes,str) print(str) end
--- ancient stuff, pre-lpeg so i need to redo it
-
calcmath = { }
-calcmath.list_1 = {
+local list_1 = {
"median", "min", "max", "round", "ln", "log",
"sin", "cos", "tan", "sinh", "cosh", "tanh"
}
-calcmath.list_2 = {
+local list_2 = {
"int", "sum", "prod"
}
-calcmath.list_3 = {
+local list_3 = {
"f", "g"
}
-calcmath.list_4 = {
+local list_4 = {
"pi", "inf"
}
-calcmath.list_1_1 = { }
-calcmath.list_2_1 = { }
-calcmath.list_2_2 = { }
-calcmath.list_2_3 = { }
-calcmath.list_4_1 = { }
+local list_1_1 = { }
+local list_2_1 = { }
+local list_2_2 = { }
+local list_2_3 = { }
+local list_4_1 = { }
-calcmath.frozen = false -- we can add stuff and unfreeze
+local frozen = false
-function calcmath.freeze()
- for _,v in ipairs(calcmath.list_1) do
- calcmath.list_1_1[v] = "\\".. v:upper() .." "
+local function freeze()
+ for k=1,#list_1 do
+ local v = list_1[k]
+ list_1_1[v] = "\\".. upper(v) .." "
end
- for _,v in ipairs(calcmath.list_2) do
- calcmath.list_2_1[v .. "%((.-),(.-),(.-)%)"] = "\\" .. v:upper() .. "^{%1}_{%2}{%3}"
- calcmath.list_2_2[v .. "%((.-),(.-)%)"] = "\\" .. v:upper() .. "^{%1}{%2}"
- calcmath.list_2_3[v .. "%((.-)%)"] = "\\" .. v:upper() .. "{%1}"
+ 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 _,v in ipairs(calcmath.list_4) do
- calcmath.list_4_1[v] = "\\" .. v:upper()
+ for k=1,#list_4 do
+ local v = list_4[k]
+ list_4_1[v] = "\\" .. upper(v)
end
- calcmath.frozen = true
+ frozen = true
end
-calcmath.entities = {
+local entities = {
['gt'] = '>',
['lt'] = '<',
}
-calcmath.symbols = {
+local symbols = {
["<="] = "\\LE ",
[">="] = "\\GE ",
["=<"] = "\\LE ",
@@ -68,120 +70,19 @@ calcmath.symbols = {
["="] = "\\EQ ",
}
---~ function calcmath.nsub(str,tag,pre,post)
---~ return (string.gsub(str, tag .. "(%b())", function(body)
---~ return pre .. calcmath.nsub(string.sub(body,2,-2),tag,pre,post) .. post
---~ end))
---~ end
-
---~ function calcmath.tex(str,mode)
---~ if not calcmath.frozen then calcmath.freeze() end
---~ local n = 0
---~ local ssub = string.gsub
---~ local nsub = calcmath.nsub
---~ local strp = string.sub
---~ -- crap
---~ str = ssub(str,"%s+" , ' ')
---~ -- xml
---~ str = ssub(str,"&(.-);", calcmath.entities)
---~ -- ...E...
---~ str = ssub(str,"([%-%+]?[%d%.%+%-]+)E([%-%+]?[%d%.]+)", "{\\SCINOT{%1}{%2}}")
---~ -- ^-..
---~ str = ssub(str, "%^([%-%+]*%d+)", "^{%1}")
---~ -- ^(...)
---~ str = nsub(str, "%^", "^{", "}")
---~ -- 1/x^2
---~ repeat
---~ str, n = ssub(str, "([%d%w%.]+)/([%d%w%.]+%^{[%d%w%.]+})", "\\frac{%1}{%2}")
---~ until n == 0
---~ -- todo: autoparenthesis
---~ -- int(a,b,c)
---~ for k,v in pairs(calcmath.list_2_1) do -- for i=1,...
---~ repeat str, n = ssub(str, k, v) until n == 0
---~ end
---~ -- int(a,b)
---~ for k,v in pairs(calcmath.list_2_2) do
---~ repeat str, n = ssub(str, k, v) until n == 0
---~ end
---~ -- int(a)
---~ for k,v in pairs(calcmath.list_2_3) do
---~ repeat str, n = ssub(str, k, v) until n == 0
---~ end
---~ -- sin(x) => {\\sin(x)}
---~ for k,v in pairs(calcmath.list_1_1) do
---~ repeat str, n = ssub(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 = ssub(str, "(%b())/(%b())", function(a,b)
---~ return "\\FRAC{" .. strp(a,2,-2) .. "}{" .. strp(b,2,-2) .. "}"
---~ end )
---~ until n == 0
---~ -- (1+x)/x => \\FRAC{1+x}{x}
---~ repeat
---~ str, n = ssub(str, "(%b())/([%+%-]?[%.%d%w]+)", function(a,b)
---~ return "\\FRAC{" .. strp(a,2,-2) .. "}{" .. b .. "}"
---~ end )
---~ until n == 0
---~ -- 1/(1+x) => \\FRAC{1}{1+x}
---~ repeat
---~ str, n = ssub(str, "([%.%d%w]+)/(%b())", function(a,b)
---~ return "\\FRAC{" .. a .. "}{" .. strp(b,2,-2) .. "}"
---~ end )
---~ until n == 0
---~ -- 1/x => \\FRAC{1}{x}
---~ repeat
---~ str, n = ssub(str, "([%.%d%w]+)/([%+%-]?[%.%d%w]+)", "\\FRAC{%1}{%2}")
---~ until n == 0
---~ -- times
---~ str = ssub(str, "%*", " ")
---~ -- symbols -- we can use a table substitution here
---~ str = ssub(str, "([<>=][<>=]*)", calcmath.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 = ssub(str, "D([xy])", "\\FRAC{{\\RM d}%1}{{\\RM d}x}")
---~ -- f/g
---~ for k,v in pairs(calcmath.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 pairs(calcmath.list_4_1) do
---~ str = ssub(str, k, v)
---~ end
---~ -- parenthesis (optional)
---~ if mode == 2 then
---~ str = ssub(str, "%(", "\\left\(")
---~ str = ssub(str, "%)", "\\right\)")
---~ end
---~ -- csnames
---~ str = ssub(str, "(\\[A-Z]+)", function(a) return a:lower() end)
---~ -- report
---~ texsprint(tex.texcatcodes,str)
---~ end
-
--- 5% faster
-
-function calcmath.nsub(str,tag,pre,post)
+local function nsub(str,tag,pre,post)
return (str:gsub(tag .. "(%b())", function(body)
- return pre .. calcmath.nsub(body:sub(2,-2),tag,pre,post) .. post
+ return pre .. nsub(body:sub(2,-2),tag,pre,post) .. post
end))
end
-function calcmath.totex(str,mode) -- 5% faster
- if not calcmath.frozen then calcmath.freeze() end
+function calcmath.totex(str,mode)
+ if not frozen then freeze() end
local n = 0
- local nsub = calcmath.nsub
-- crap
str = str:gsub("%s+" , ' ')
-- xml
- str = str:gsub("&(.-);", calcmath.entities)
+ str = str:gsub("&(.-);", entities)
-- ...E...
str = str:gsub("([%-%+]?[%d%.%+%-]+)E([%-%+]?[%d%.]+)", "{\\SCINOT{%1}{%2}}")
-- ^-..
@@ -194,19 +95,19 @@ function calcmath.totex(str,mode) -- 5% faster
until n == 0
-- todo: autoparenthesis
-- int(a,b,c)
- for k,v in pairs(calcmath.list_2_1) do
- repeat str, n = str:gsub(k, v) until n == 0
+ for k, v in next, list_2_1 do
+ repeat str, n = str:gsub(k,v) until n == 0
end
-- int(a,b)
- for k,v in pairs(calcmath.list_2_2) do
+ for k, v in next, list_2_2 do
repeat str, n = str:gsub(k, v) until n == 0
end
-- int(a)
- for k,v in pairs(calcmath.list_2_3) do
+ for k, v in next, list_2_3 do
repeat str, n = str:gsub(k, v) until n == 0
end
-- sin(x) => {\\sin(x)}
- for k,v in pairs(calcmath.list_1_1) do
+ for k, v in next, list_1_1 do
repeat str, n = str:gsub(k, v) until n == 0
end
-- mean
@@ -236,7 +137,7 @@ function calcmath.totex(str,mode) -- 5% faster
-- times
str = str:gsub("%*", " ")
-- symbols -- we can use a table substitution here
- str = str:gsub("([<>=][<>=]*)", calcmath.symbols)
+ str = str:gsub("([<>=][<>=]*)", symbols)
-- functions
str = nsub(str, "sqrt", "\\SQRT{", "}")
str = nsub(str, "exp", "e^{", "}")
@@ -245,12 +146,12 @@ function calcmath.totex(str,mode) -- 5% faster
str = nsub(str, "D", "{\\FRAC{\\MBOX{d}}{\\MBOX{d}x}{(", ")}}")
str = str:gsub("D([xy])", "\\FRAC{{\\RM d}%1}{{\\RM d}x}")
-- f/g
- for k,v in pairs(calcmath.list_3) do -- todo : prepare k,v
+ 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 pairs(calcmath.list_4_1) do
+ for k,v in next, list_4_1 do
str = str:gsub(k, v)
end
-- parenthesis (optional)
@@ -259,7 +160,9 @@ function calcmath.totex(str,mode) -- 5% faster
str = str:gsub("%)", "\\right\)")
end
-- csnames
- str = str:gsub("(\\[A-Z]+)", function(a) return a:lower() end)
+ str = str:gsub("(\\[A-Z]+)", lower)
+ -- trace
+--~ print(str)
-- report
return str
end
@@ -299,7 +202,6 @@ if false then
local real = Cc("real") * C(real_x) * space
local float = Cc("float") * C(real_x) * lpeg.P("E") * lpeg.C(number_x) * space
local identifier = Cc("identifier") * C(R("az","AZ")^1) * space
- -- compareop = Cc("compare") * C(P("<") + P("=") + P(">") + P(">=") + P("<=") + P("&gt;")/">" + P("&lt;")/"<") * space
local compareop = P("<") + P("=") + P(">") + P(">=") + P("<=") + P("&gt;") + P("&lt;")
local factorop = Cc("factor") * C(S("+-^,") + compareop ) * space
local termop = Cc("term") * C(S("*/")) * space
@@ -310,7 +212,6 @@ if false then
local grammar = P {
"expression",
- --~ comparison = Ct(V("expression") * (compareop * V("expression"))^0),
expression = Ct(V("factor" ) * (factorop * V("factor" ))^0),
factor = Ct(V("term" ) * (termop * V("term" ))^0),
term = Ct(
@@ -323,8 +224,6 @@ if false then
local parser = space * grammar * -1
- local format = string.format
-
function totex(t)
if t then
local one, two, three = t[1], t[2], t[3]
@@ -423,9 +322,13 @@ if false then
return parser:match(str)
end
- function calcmath.totex(str)
+ function calcmath.tex(str)
str = totex(parser:match(str))
+ print(str)
return (str == "" and "[error]") or str
end
end
+
+--~ compareop = Cc("compare") * C(P("<") + P("=") + P(">") + P(">=") + P("<=") + P("&gt;")/">" + P("&lt;")/"<") * space
+--~ comparison = Ct(V("expression") * (compareop * V("expression"))^0),
diff --git a/tex/context/base/x-cals.mkiv b/tex/context/base/x-cals.mkiv
index daa9f2477..3d2644045 100644
--- a/tex/context/base/x-cals.mkiv
+++ b/tex/context/base/x-cals.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (cals tables)}
+\writestatus{loading}{ConTeXt XML Macros / Cals Tables}
\startluacode
do
@@ -103,12 +103,11 @@ do
sum = sum + v
end
end
--- local delta = sum - tex.hsize:todimen()
-local hsize = tex.hsize
-if type(hsize) == "string" then
- hsize = hsize:todimen()
-end
-local delta = sum - hsize
+ local hsize = tex.hsize
+ if type(hsize) == "string" then
+ hsize = hsize:todimen()
+ end
+ local delta = sum - hsize
if shrink_widths and delta > 0 then
adapt(shrink_widths,w,delta,sum,n,"shrink")
elseif stretch_widths and delta < 0 then
@@ -201,6 +200,7 @@ local delta = sum - hsize
for r, d, k in xml.elements(lxml.id(root),tgroupspec) do
local tgroup = d[k]
+ texsprint(tex.ctxcatcodes, "\\directsetup{cals:table:before}")
lxml.directives.before(root,"cdx") -- "cals:table"
texsprint(tex.ctxcatcodes, "\\bgroup")
lxml.directives.setup(root,"cdx") -- "cals:table"
@@ -211,6 +211,7 @@ local delta = sum - hsize
texsprint(tex.ctxcatcodes, "\\eTABLE")
texsprint(tex.ctxcatcodes, "\\egroup")
lxml.directives.after(root,"cdx") -- "cals:table"
+ texsprint(tex.ctxcatcodes, "\\directsetup{cals:table:after}")
end
end
diff --git a/tex/context/base/x-chemml.mkiv b/tex/context/base/x-chemml.mkiv
index 372165092..e0da353fc 100644
--- a/tex/context/base/x-chemml.mkiv
+++ b/tex/context/base/x-chemml.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (chemml mkiv)}
+\writestatus{loading}{ConTeXt XML Macros / Chemistry}
\usemodule[pictex,chemic] % someday we will do structural fomulas in mp
diff --git a/tex/context/base/x-ct.mkiv b/tex/context/base/x-ct.mkiv
index cf7bb64fb..17ea25408 100644
--- a/tex/context/base/x-ct.mkiv
+++ b/tex/context/base/x-ct.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (context)}
+\writestatus{loading}{ConTeXt XML Macros / Basics}
\startluacode
do
diff --git a/tex/context/base/x-fo.tex b/tex/context/base/x-fo.tex
index 396225546..1f9e55259 100644
--- a/tex/context/base/x-fo.tex
+++ b/tex/context/base/x-fo.tex
@@ -26,7 +26,9 @@
% beware: aftergroup vs egroup/endgroup
-\input xtag-run
+\useXMLfilter[prs,run]
+
+% \input xtag-run
\unprotect
@@ -3369,7 +3371,7 @@ text-indent=0pt, % yes
\setbox \FOitembox \iftracingFO \ruledvtop \else \vtop \fi \bgroup
\forgetall
- \postponefootnotes
+ \postponenotes
\hsize\FOlistitemlabelhsize
\directsetup{fo:list-item-label:setup}
\XMLflush{fo:list-item-label}
@@ -3508,7 +3510,7 @@ text-indent=0pt, % yes
\startsetups fo:marker:process
- \doifmarkingelse{fo:\XMLop{marker-class-name}}
+ \doifelsemarking{fo:\XMLop{marker-class-name}}
{} {\definerawmarking[fo:\XMLop{marker-class-name}]}
\expanded{\marking[fo:\XMLop{marker-class-name}]{\XMLflushself}}
diff --git a/tex/context/base/x-mathml.lua b/tex/context/base/x-mathml.lua
index 0e279dfe8..aa2e4e716 100644
--- a/tex/context/base/x-mathml.lua
+++ b/tex/context/base/x-mathml.lua
@@ -6,19 +6,29 @@ if not modules then modules = { } end modules ['x-mathml'] = {
license = "see context related readme files"
}
+local utf = unicode.utf8
+
lxml = lxml or { }
lxml.mml = lxml.mml or { }
local texsprint = tex.sprint
local format = string.format
-local utfchar = unicode.utf8.char
+local lower = string.lower
+local utfchar = utf.char
+local utffind = utf.find
local xmlsprint = xml.sprint
local xmlcprint = xml.cprint
+local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
+
-- an alternative is to remap to private codes, where we can have
-- different properties .. to be done; this will move and become
-- generic
+-- todo: handle opening/closing mo's here ... presentation mml is such a mess ...
+
+local doublebar = utfchar(0x2016)
+
local n_replacements = {
-- [" "] = utfchar(0x2002), -- "&textspace;" -> tricky, no &; in mkiv
["."] = "{.}",
@@ -26,12 +36,30 @@ local n_replacements = {
[" "] = "",
}
+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",
+}
+
local o_replacements = { -- in main table
["@l"] = "\\mmlleftdelimiter.",
["@r"] = "\\mmlrightdelimiter.",
["{"] = "\\mmlleftdelimiter\\lbrace",
["}"] = "\\mmlrightdelimiter\\rbrace",
--- ["|"] = "\\mmlmiddledelimiter\\vert",
+ ["|"] = "\\mmlleftorrightdelimiter\\vert",
+ [doublebar] = "\\mmlleftorrightdelimiter\\Vert",
["("] = "\\mmlleftdelimiter(",
[")"] = "\\mmlrightdelimiter)",
["["] = "\\mmlleftdelimiter[",
@@ -48,9 +76,9 @@ local o_replacements = { -- in main table
[" "] = "",
["°"] = "^\\circ", -- hack
-[utf.char(0xF103C)] = "\\mmlleftdelimiter<",
-[utf.char(0xF1026)] = "\\mmlchar{38}",
-[utf.char(0xF103E)] = "\\mmlleftdelimiter>",
+ [utfchar(0xF103C)] = "\\mmlleftdelimiter<",
+ [utfchar(0xF1026)] = "\\mmlchar{38}",
+ [utfchar(0xF103E)] = "\\mmlleftdelimiter>",
}
@@ -424,6 +452,10 @@ function lxml.mml.checked_operator(str)
texsprint(tex.ctxcatcodes,(utf.gsub(str,".",o_replacements)))
end
+function lxml.mml.stripped(str)
+ tex.sprint(tex.ctxcatcodes,str:strip())
+end
+
function lxml.mml.mn(id,pattern)
-- maybe at some point we need to interpret the number, but
-- currently we assume an upright font
@@ -453,13 +485,24 @@ function lxml.mml.mi(id,pattern)
end
end
+function table.keys_as_string(t)
+ local k = { }
+ for k,_ in pairs(t) do
+ k[#k+1] = k
+ end
+ return concat(k,"")
+end
+
+--~ local leftdelimiters = "[" .. table.keys_as_string(l_replacements) .. "]"
+--~ local rightdelimiters = "[" .. table.keys_as_string(r_replacements) .. "]"
+
function lxml.mml.mfenced(id,pattern) -- multiple separators
id = lxml.id(id)
local left, right, separators = id.at.open or "(", id.at.close or ")", id.at.separators or ","
- local l, r = left:find("[%(%{%<%[]"), right:find("[%)%}%>%]]")
+ local l, r = l_replacements[left], r_replacements[right]
texsprint(tex.ctxcatcodes,"\\enabledelimiter")
if l then
- texsprint(tex.ctxcatcodes,o_replacements[left])
+ texsprint(tex.ctxcatcodes,l_replacements[left] or o_replacements[left] or "")
else
texsprint(tex.ctxcatcodes,o_replacements["@l"])
texsprint(tex.ctxcatcodes,left)
@@ -481,6 +524,8 @@ function lxml.mml.mfenced(id,pattern) -- multiple separators
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
@@ -492,7 +537,7 @@ function lxml.mml.mfenced(id,pattern) -- multiple separators
end
texsprint(tex.ctxcatcodes,"\\enabledelimiter")
if r then
- texsprint(tex.ctxcatcodes,o_replacements[right])
+ texsprint(tex.ctxcatcodes,r_replacements[right] or o_replacements[right] or "")
else
texsprint(tex.ctxcatcodes,right)
texsprint(tex.ctxcatcodes,o_replacements["@r"])
@@ -578,7 +623,7 @@ function lxml.mml.mcolumn(root)
local tag = dk.tg
if tag == "mi" or tag == "mn" or tag == "mo" or tag == "mtext" then
local str = xml.content(dk)
- for s in str:utfcharacters() do -- utf.gmatch(str,".") btw, the gmatch was bugged
+ for s in utfcharacters(str) do -- utf.gmatch(str,".") btw, the gmatch was bugged
m[#m+1] = { tag, s }
end
if tag == "mn" then
@@ -589,7 +634,7 @@ function lxml.mml.mcolumn(root)
end
elseif tag == "mspace" or tag == "mline" then
local str = dk.at.spacing or ""
- for s in str:utfcharacters() do -- utf.gmatch(str,".") btw, the gmatch was bugged
+ for s in utfcharacters(str) do -- utf.gmatch(str,".") btw, the gmatch was bugged
m[#m+1] = { tag, s }
end
elseif tag == "mline" then
@@ -653,7 +698,7 @@ function lxml.mml.mcolumn(root)
--~ end
chr = "\\hrulefill"
elseif tag == "mspace" then
- chr = "\\mmlmcolumndigitspace" -- utf.char(0x2007)
+ chr = "\\mmlmcolumndigitspace" -- utfchar(0x2007)
end
if j == numbers + 1 then
tex.sprint(tex.ctxcatcodes,"&")
@@ -666,6 +711,8 @@ function lxml.mml.mcolumn(root)
tex.sprint(tex.ctxcatcodes,"\\egroup")
end
+local spacesplitter = lpeg.Ct(lpeg.splitat(" "))
+
function lxml.mml.mtable(root)
root = lxml.id(root)
@@ -675,9 +722,9 @@ function lxml.mml.mtable(root)
local rowalign = at.rowalign
local columnalign = at.columnalign
local frame = at.frame
- local rowaligns = rowalign and rowalign :split(" ") -- we have a faster one
- local columnaligns = columnalign and columnalign:split(" ") -- we have a faster one
- local frames = frame and frame :split(" ") -- we have a faster one
+ local rowaligns = rowalign and spacesplitter:match(rowalign)
+ local columnaligns = columnalign and spacesplitter:match(columnalign)
+ local frames = frame and spacesplitter:match(frame)
local framespacing = at.framespacing or "0pt"
local framespacing = at.framespacing or "-\\ruledlinewidth" -- make this an option
@@ -722,7 +769,7 @@ end
function lxml.mml.csymbol(root)
root = lxml.id(root)
local encoding = root.at.encoding or ""
- local hash = url.hashed((root.at.definitionUrl or ""):lower())
+ local hash = url.hashed(lower(root.at.definitionUrl or ""))
local full = hash.original or ""
local base = hash.path or ""
local text = string.strip(xml.content(root) or "")
diff --git a/tex/context/base/x-mathml.mkiv b/tex/context/base/x-mathml.mkiv
index e5f39975c..6630a4901 100644
--- a/tex/context/base/x-mathml.mkiv
+++ b/tex/context/base/x-mathml.mkiv
@@ -15,7 +15,7 @@
% This module is under construction and will be cleaned up.
-\writestatus{loading}{Context XML Macros (MathML Renderer)}
+\writestatus{loading}{ConTeXt XML Macros / MathML Renderer}
\unprotect
@@ -66,15 +66,24 @@
\startformula\MMLhack\xmlfirst{#1}{/mml:math}\stopformula
\stopxmlsetups
+\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
-\setfalse\mmlignoredelimiter
-
-\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\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}
\def\mmlchar#1{\char#1 } % used in lua code
@@ -93,7 +102,7 @@
%D some namespace limitations. Here we do it the \MKV\ way.
\def\widevec#1%
- {\vbox{\m@th\ialign{##\crcr
+ {\vbox{\mathsurround\zeropoint\ialign{##\crcr
\rightarrowfill\crcr\noalign{\nointerlineskip}%
$\hfil\displaystyle{#1}\hfil$\crcr}}}
@@ -1778,8 +1787,10 @@
\xmlmapvalue {mml} {sans-serif-bold-italic} {\ss\bi}
\xmlmapvalue {mml} {monospace} {\tt}
+% todo: displaystyle=true/false (or whatever else shows up)
+
\starttexdefinition setmmlmathstyle #1
- \xmlval {mml} {\xmlatt{#1}{mathvariant}} \mmmr
+ \xmlval {mml} {\xmlatt{#1}{mathvariant}} \empty % was: \mmmr
\stoptexdefinition
\starttexdefinition applymmlmathcolor #1#2
@@ -1802,7 +1813,7 @@
\fi
\stoptexdefinition
-\newsignal\mmltextsignal
+\newsignal\mmltextsignal % not used
\starttexdefinition applymmlsometext #1#2
\applymmlmathbackground {#1} {
@@ -1862,23 +1873,6 @@
\ctxlua{lxml.mml.mfenced("#1","/*")}
\stopxmlsetups
-% \startxmlsetups mml:menclose % notation=.....
-% \edef\mmlmenclosenotation{\xmlattdef{#1}{notation}{longdiv}}
-% \doifelse \mmlmenclosenotation {longdiv} {
-% \overline{\left)\strut\xmlflush{#1}\right.}
-% } {
-% \doifelse \mmlmenclosenotation {actuarial} {
-% \overline{\left.\strut\xmlflush{#1}\right|}
-% } {
-% \doifelse \mmlmenclosenotation {radical} {
-% \sqrt{\xmlflush{#1}}
-% } {
-% \xmlflush{#1}
-% }
-% }
-% }
-% \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}]
@@ -1951,23 +1945,26 @@
\doifelse \mmlmenclosenotation {mml:enclose:radical} {
\sqrt{\xmlflush{#1}}
} {
- \framed
- [frame=off,background={\mmlmenclosenotation}]
- {$
- \expanded{\doifinsetelse {mml:enclose:longdiv} {\mmlmenclosenotation}} {
- \overline{\left)\strut\xmlflush{#1}\right.}
- } {
- \expanded{\doifinsetelse {mml:enclose:actuarial} {\mmlmenclosenotation}} {
- \overline{\left.\strut\xmlflush{#1}\right|}
+ % todo: no framed when longdiv, actuarial or radical ? spec ?
+ \vcenter {
+ \framed
+ [frame=off,strut=no,background={\mmlmenclosenotation}] % offset is kind of undefined
+ {$
+ \expanded{\doifinsetelse {mml:enclose:longdiv} {\mmlmenclosenotation}} {
+ \overline{\left)\strut\xmlflush{#1}\right.}
} {
- \expanded{\doifinsetelse {mml:enclose:radical} {\mmlmenclosenotation}} {
- \sqrt{\xmlflush{#1}}
+ \expanded{\doifinsetelse {mml:enclose:actuarial} {\mmlmenclosenotation}} {
+ \overline{\left.\strut\xmlflush{#1}\right|}
} {
- \xmlflush{#1}
+ \expanded{\doifinsetelse {mml:enclose:radical} {\mmlmenclosenotation}} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ \xmlflush{#1}
+ }
}
}
- }
- $}
+ $}
+ }
}
}
}
@@ -2020,9 +2017,20 @@
\endgroup
\stopxmlsetups
+\setupMMLappearance[text][\c!alternative=\v!a] % a=normal, b=keep spaces
+
\startxmlsetups mml:mtext
\domathtext {
- \applymmlsometext{#1}{\xmlflush{#1}}
+ \applymmlsometext{#1}{
+ \doifelse\MMLscriptsalternative\v!a {
+ %\ctxlua{lxml.mml.stripped(\!!bs\xmlflush{#1}\!!es)}
+ \ignorespaces
+ \xmlflush{#1}
+ \unskip
+ } {
+ \xmlflush{#1}
+ }
+ }
}
\stopxmlsetups
diff --git a/tex/context/base/x-newcml.tex b/tex/context/base/x-newcml.tex
index c5f999615..76d69ed51 100644
--- a/tex/context/base/x-newcml.tex
+++ b/tex/context/base/x-newcml.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=x-newmml,
%D version=2006.04.09, % reimplementation
-%D title=\CONTEXT\ XML Modules,
-%D subtitle=ChemML renderer,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=ChemML,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA ADE}]
@@ -14,7 +14,9 @@
%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 (chem ml)}
+\writestatus{loading}{ConTeXt XML Macros / ChemML}
+
+\useXMLfilter[stk]
\unprotect
diff --git a/tex/context/base/x-newmme.tex b/tex/context/base/x-newmme.tex
index 5a7705963..5e17ea7a4 100644
--- a/tex/context/base/x-newmme.tex
+++ b/tex/context/base/x-newmme.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=m-newmme,
%D version=2005.06.10, % 1999.12.20,
-%D title=\CONTEXT\ XML Modules,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=MathML Entities,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (MathML Entities)}
+\writestatus{loading}{ConTeXt XML Macros / MathML Entities}
\unprotect
diff --git a/tex/context/base/x-newmml.mkii b/tex/context/base/x-newmml.mkii
index f4847eeb9..17eda5276 100644
--- a/tex/context/base/x-newmml.mkii
+++ b/tex/context/base/x-newmml.mkii
@@ -1,8 +1,8 @@
%D \module
%D [ file=x-newmml,
%D version=2005.06.10, % 1999.12.20,
-%D title=\CONTEXT\ XML Modules,
-%D subtitle=MathML Renderer,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=MathML,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA ADE}]
@@ -17,6 +17,8 @@
%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}
@@ -28,7 +30,7 @@
%D Then we start defining the rendering macros:
-\writestatus{loading}{Context XML Macros (MathML Renderer)}
+\writestatus{loading}{ConTeXt XML Macros / MathML}
\startmodule [mathml]
@@ -570,7 +572,7 @@
{{\bbd#1}}
\def\widevec#1%
- {\vbox{\m@th\ialign{##\crcr
+ {\vbox{\mathsurround\zeropoint\ialign{##\crcr
\rightarrowfill\crcr\noalign{\nointerlineskip}%
$\hfil\displaystyle{#1}\hfil$\crcr}}}
@@ -1960,9 +1962,6 @@
{\getXMLentity\flattenedXMLcontent}
{\ignorespaces#1\removeunwantedspaces}}
-\let\normalright=\right
-\let\normalleft =\left
-
\def\doMMLleft #1{\pushmacro\left \let\left \empty\normalleft #1\popmacro\left}
\def\doMMLright#1{\pushmacro\right\let\right\empty\normalright#1\popmacro\right}
@@ -2267,9 +2266,9 @@
\startsetups mmp:mover:stop
\stopsavingXMLelements
- \mathop{\vbox{\m@th\ialign{\hss##\hss\crcr\noalign{\kern3\p@}%
+ \mathop{\vbox{\mathsurround\zeropoint\ialign{\hss##\hss\crcr\noalign{\kern3\points}%
\disabledelimiter\doMMLfiller{\getXMLstackdata\plustwo}
- \crcr\noalign{\kern3\p@\nointerlineskip}%
+ \crcr\noalign{\kern3\points\nointerlineskip}%
\disabledelimiter\doMMLfiller{\getXMLstackdata\plusone}
\crcr}}}
\limits
@@ -2283,11 +2282,11 @@
\startsetups mmp:munder:stop
\stopsavingXMLelements
- \mathop{\vtop{\m@th\ialign{\hss##\hss\crcr
+ \mathop{\vtop{\mathsurround\zeropoint\ialign{\hss##\hss\crcr
\disabledelimiter\doMMLfiller{\getXMLstackdata\plusone}
- \crcr\noalign{\kern3\p@\nointerlineskip}%
+ \crcr\noalign{\kern3\points\nointerlineskip}%
\disabledelimiter\doMMLfiller{\getXMLstackdata\plustwo}
- \crcr\noalign{\kern3\p@}}}}
+ \crcr\noalign{\kern3\points}}}}
\limits
\endgroup
\stopsetups
diff --git a/tex/context/base/x-newmml.tex b/tex/context/base/x-newmml.tex
index f08e91b26..9eb994021 100644
--- a/tex/context/base/x-newmml.tex
+++ b/tex/context/base/x-newmml.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=x-newmml,
%D version=2005.06.10, % 1999.12.20,
-%D title=\CONTEXT\ XML Modules,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=MathML Renderer,
%D author=Hans Hagen,
%D date=\currentdate,
diff --git a/tex/context/base/x-newmmo.tex b/tex/context/base/x-newmmo.tex
index 076f3f82c..c3b56cc16 100644
--- a/tex/context/base/x-newmmo.tex
+++ b/tex/context/base/x-newmmo.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=x-newmmo,
%D version=2006.05.17,
-%D title=\CONTEXT\ XML Modules,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=MathML Renderer/Open Math Extensions,
%D author=Hans Hagen,
%D date=\currentdate,
diff --git a/tex/context/base/x-newpml.tex b/tex/context/base/x-newpml.tex
index 30b520610..d69231e3f 100644
--- a/tex/context/base/x-newpml.tex
+++ b/tex/context/base/x-newpml.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (units)}
+\writestatus{loading}{ConTeXt XML Macros / Units}
\usemodule[newmml]
diff --git a/tex/context/base/x-set-02.tex b/tex/context/base/x-set-02.tex
index da531f6cb..bb0b7583c 100644
--- a/tex/context/base/x-set-02.tex
+++ b/tex/context/base/x-set-02.tex
@@ -12,14 +12,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D This file is obsolete.
-
\unprotect \bgroup \catcode`\<=\@@other
\def\setinterfacecomponent#1#2#3%
- {\doifelse{#3}\nointerfaceobject
- {\setgvalue{\string<#1\string:#2\string>}{#2}}
- {\setgvalue{\string<#1\string:#2\string>}{#3}}}
+ {\setgvalue{\string<#1\string:#2\string>}{#3}}
\gdef\getinterfacecomponent#1#2%
{\executeifdefined{\string<#1\string:#2\string>}{#2}}
@@ -29,9 +25,6 @@
\def\setinterfaceelement {\setinterfacecomponent{string}} % element
\def\setinterfacecommand {\setinterfacecomponent{string}} % command
-\input mult-con.tex
-\input mult-com.tex
-
-% we need to replace the y! by just the name
+\input mult-\userinterfacetag
\egroup \protect \endinput
diff --git a/tex/context/base/x-set-11.mkii b/tex/context/base/x-set-11.mkii
index 397c2c71c..434b18647 100644
--- a/tex/context/base/x-set-11.mkii
+++ b/tex/context/base/x-set-11.mkii
@@ -31,7 +31,7 @@
\defineXMLenvironmentsave [cd:define] [name=]
{}
- {\setevalue{cd:def:\XMLop{name}}{\XMLflush{cd:define}}}
+ {\setxvalue{cd:def:\XMLop{name}}{\XMLflush{cd:define}}}
\defineXMLsingular [cd:resolve] [name=]
{\getvalue{cd:def:\XMLop{name}}}
diff --git a/tex/context/base/x-set-11.mkiv b/tex/context/base/x-set-11.mkiv
index dcfef384f..499d531e5 100644
--- a/tex/context/base/x-set-11.mkiv
+++ b/tex/context/base/x-set-11.mkiv
@@ -11,7 +11,7 @@
}
function document.setups.load(filename)
- filename = input.find_file(filename) or ""
+ filename = resolvers.find_file(filename) or ""
if filename ~= "" and not document.setups.loaded[filename] then
local loaded = xml.load(filename)
if loaded then
diff --git a/tex/context/base/x-set-11.tex b/tex/context/base/x-set-11.tex
index 19ce18a75..6fcc7f934 100644
--- a/tex/context/base/x-set-11.tex
+++ b/tex/context/base/x-set-11.tex
@@ -571,7 +571,7 @@
\blank[\v!halfline]
\ignorespaces}
-\defineXMLenvironmentsave [cd:keywords]
+\defineXMLenvironmentsave [cd:keywords] [optional=no]
{}
{\startfirstSETUPcolumn{\showSETUPnumber}%
\doifelseXMLempty{cd:keywords}
diff --git a/tex/context/base/xetx-chr.tex b/tex/context/base/xetx-chr.tex
new file mode 100644
index 000000000..31f15a0cb
--- /dev/null
+++ b/tex/context/base/xetx-chr.tex
@@ -0,0 +1,1167 @@
+% filename : xetx-chr.tex
+% comment : generated by mtxrun --script chars --xtx
+% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+% copyright: PRAGMA ADE / ConTeXt Development Team
+% license : see context related readme files
+
+% named characters mapped onto utf (\\char is needed for accents)
+
+\def\textbackslash {\char"0005C } % REVERSE SOLIDUS: \
+\def\textasciicircum {\char"0005E } % CIRCUMFLEX ACCENT: ^
+\def\textunderscore {\char"0005F } % LOW LINE: _
+\def\textgrave {\char"00060 } % GRAVE ACCENT: `
+\def\idotaccent {\char"00069 } % LATIN SMALL LETTER I: i
+\def\textbraceleft {\char"0007B } % LEFT CURLY BRACKET: {
+\def\textbar {\char"0007C } % VERTICAL LINE: |
+\def\textbraceright {\char"0007D } % RIGHT CURLY BRACKET: }
+\def\textasciitilde {\char"0007E } % TILDE: ~
+\def\nobreakspace {\char"000A0 } % NO-BREAK SPACE:  
+\def\exclamdown {\char"000A1 } % INVERTED EXCLAMATION MARK: ¡
+\def\textcent {\char"000A2 } % CENT SIGN: ¢
+\def\textsterling {\char"000A3 } % POUND SIGN: £
+\def\textcurrency {\char"000A4 } % CURRENCY SIGN: ¤
+\def\textyen {\char"000A5 } % YEN SIGN: ¥
+\def\textbrokenbar {\char"000A6 } % BROKEN BAR: ¦
+\def\sectionmark {\char"000A7 } % SECTION SIGN: §
+\def\textdiaeresis {\char"000A8 } % DIAERESIS: ¨
+\def\copyright {\char"000A9 } % COPYRIGHT SIGN: ©
+\def\ordfeminine {\char"000AA } % FEMININE ORDINAL INDICATOR: ª
+\def\leftguillemot {\char"000AB } % LEFT-POINTING DOUBLE ANGLE QUOTATION MARK: «
+\def\textlognot {\char"000AC } % NOT SIGN: ¬
+\def\softhyphen {\char"000AD } % SOFT HYPHEN: ­
+\def\registered {\char"000AE } % REGISTERED SIGN: ®
+\def\textmacron {\char"000AF } % MACRON: ¯
+\def\textdegree {\char"000B0 } % DEGREE SIGN: °
+\def\textpm {\char"000B1 } % PLUS-MINUS SIGN: ±
+\def\twosuperior {\char"000B2 } % SUPERSCRIPT TWO: ²
+\def\threesuperior {\char"000B3 } % SUPERSCRIPT THREE: ³
+\def\textacute {\char"000B4 } % ACUTE ACCENT: ´
+\def\textmu {\char"000B5 } % MICRO SIGN: µ
+\def\paragraphmark {\char"000B6 } % PILCROW SIGN: ¶
+\def\periodcentered {\char"000B7 } % MIDDLE DOT: ·
+\def\textcedilla {\char"000B8 } % CEDILLA: ¸
+\def\onesuperior {\char"000B9 } % SUPERSCRIPT ONE: ¹
+\def\ordmasculine {\char"000BA } % MASCULINE ORDINAL INDICATOR: º
+\def\rightguillemot {\char"000BB } % RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK: »
+\def\onequarter {\char"000BC } % VULGAR FRACTION ONE QUARTER: ¼
+\def\onehalf {\char"000BD } % VULGAR FRACTION ONE HALF: ½
+\def\threequarter {\char"000BE } % VULGAR FRACTION THREE QUARTERS: ¾
+\def\questiondown {\char"000BF } % INVERTED QUESTION MARK: ¿
+\def\Agrave {\char"000C0 } % LATIN CAPITAL LETTER A WITH GRAVE: À
+\def\Aacute {\char"000C1 } % LATIN CAPITAL LETTER A WITH ACUTE: Á
+\def\Acircumflex {\char"000C2 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX: Â
+\def\Atilde {\char"000C3 } % LATIN CAPITAL LETTER A WITH TILDE: Ã
+\def\Adiaeresis {\char"000C4 } % LATIN CAPITAL LETTER A WITH DIAERESIS: Ä
+\def\Aring {\char"000C5 } % LATIN CAPITAL LETTER A WITH RING ABOVE: Å
+\def\AEligature {\char"000C6 } % LATIN CAPITAL LETTER AE: Æ
+\def\Ccedilla {\char"000C7 } % LATIN CAPITAL LETTER C WITH CEDILLA: Ç
+\def\Egrave {\char"000C8 } % LATIN CAPITAL LETTER E WITH GRAVE: È
+\def\Eacute {\char"000C9 } % LATIN CAPITAL LETTER E WITH ACUTE: É
+\def\Ecircumflex {\char"000CA } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX: Ê
+\def\Ediaeresis {\char"000CB } % LATIN CAPITAL LETTER E WITH DIAERESIS: Ë
+\def\Igrave {\char"000CC } % LATIN CAPITAL LETTER I WITH GRAVE: Ì
+\def\Iacute {\char"000CD } % LATIN CAPITAL LETTER I WITH ACUTE: Í
+\def\Icircumflex {\char"000CE } % LATIN CAPITAL LETTER I WITH CIRCUMFLEX: Î
+\def\Idiaeresis {\char"000CF } % LATIN CAPITAL LETTER I WITH DIAERESIS: Ï
+\def\Eth {\char"000D0 } % LATIN CAPITAL LETTER ETH: Ð
+\def\Ntilde {\char"000D1 } % LATIN CAPITAL LETTER N WITH TILDE: Ñ
+\def\Ograve {\char"000D2 } % LATIN CAPITAL LETTER O WITH GRAVE: Ò
+\def\Oacute {\char"000D3 } % LATIN CAPITAL LETTER O WITH ACUTE: Ó
+\def\Ocircumflex {\char"000D4 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX: Ô
+\def\Otilde {\char"000D5 } % LATIN CAPITAL LETTER O WITH TILDE: Õ
+\def\Odiaeresis {\char"000D6 } % LATIN CAPITAL LETTER O WITH DIAERESIS: Ö
+\def\textmultiply {\char"000D7 } % MULTIPLICATION SIGN: ×
+\def\Ostroke {\char"000D8 } % LATIN CAPITAL LETTER O WITH STROKE: Ø
+\def\Ugrave {\char"000D9 } % LATIN CAPITAL LETTER U WITH GRAVE: Ù
+\def\Uacute {\char"000DA } % LATIN CAPITAL LETTER U WITH ACUTE: Ú
+\def\Ucircumflex {\char"000DB } % LATIN CAPITAL LETTER U WITH CIRCUMFLEX: Û
+\def\Udiaeresis {\char"000DC } % LATIN CAPITAL LETTER U WITH DIAERESIS: Ü
+\def\Yacute {\char"000DD } % LATIN CAPITAL LETTER Y WITH ACUTE: Ý
+\def\Thorn {\char"000DE } % LATIN CAPITAL LETTER THORN: Þ
+\def\ssharp {\char"000DF } % LATIN SMALL LETTER SHARP S: ß
+\def\agrave {\char"000E0 } % LATIN SMALL LETTER A WITH GRAVE: à
+\def\aacute {\char"000E1 } % LATIN SMALL LETTER A WITH ACUTE: á
+\def\acircumflex {\char"000E2 } % LATIN SMALL LETTER A WITH CIRCUMFLEX: â
+\def\atilde {\char"000E3 } % LATIN SMALL LETTER A WITH TILDE: ã
+\def\adiaeresis {\char"000E4 } % LATIN SMALL LETTER A WITH DIAERESIS: ä
+\def\aring {\char"000E5 } % LATIN SMALL LETTER A WITH RING ABOVE: å
+\def\aeligature {\char"000E6 } % LATIN SMALL LETTER AE: æ
+\def\ccedilla {\char"000E7 } % LATIN SMALL LETTER C WITH CEDILLA: ç
+\def\egrave {\char"000E8 } % LATIN SMALL LETTER E WITH GRAVE: è
+\def\eacute {\char"000E9 } % LATIN SMALL LETTER E WITH ACUTE: é
+\def\ecircumflex {\char"000EA } % LATIN SMALL LETTER E WITH CIRCUMFLEX: ê
+\def\ediaeresis {\char"000EB } % LATIN SMALL LETTER E WITH DIAERESIS: ë
+\def\igrave {\char"000EC } % LATIN SMALL LETTER I WITH GRAVE: ì
+\def\iacute {\char"000ED } % LATIN SMALL LETTER I WITH ACUTE: í
+\def\icircumflex {\char"000EE } % LATIN SMALL LETTER I WITH CIRCUMFLEX: î
+\def\idiaeresis {\char"000EF } % LATIN SMALL LETTER I WITH DIAERESIS: ï
+\def\ntilde {\char"000F1 } % LATIN SMALL LETTER N WITH TILDE: ñ
+\def\ograve {\char"000F2 } % LATIN SMALL LETTER O WITH GRAVE: ò
+\def\oacute {\char"000F3 } % LATIN SMALL LETTER O WITH ACUTE: ó
+\def\ocircumflex {\char"000F4 } % LATIN SMALL LETTER O WITH CIRCUMFLEX: ô
+\def\otilde {\char"000F5 } % LATIN SMALL LETTER O WITH TILDE: õ
+\def\odiaeresis {\char"000F6 } % LATIN SMALL LETTER O WITH DIAERESIS: ö
+\def\textdiv {\char"000F7 } % DIVISION SIGN: ÷
+\def\ostroke {\char"000F8 } % LATIN SMALL LETTER O WITH STROKE: ø
+\def\ugrave {\char"000F9 } % LATIN SMALL LETTER U WITH GRAVE: ù
+\def\uacute {\char"000FA } % LATIN SMALL LETTER U WITH ACUTE: ú
+\def\ucircumflex {\char"000FB } % LATIN SMALL LETTER U WITH CIRCUMFLEX: û
+\def\udiaeresis {\char"000FC } % LATIN SMALL LETTER U WITH DIAERESIS: ü
+\def\yacute {\char"000FD } % LATIN SMALL LETTER Y WITH ACUTE: ý
+\def\thorn {\char"000FE } % LATIN SMALL LETTER THORN: þ
+\def\ydiaeresis {\char"000FF } % LATIN SMALL LETTER Y WITH DIAERESIS: ÿ
+\def\Amacron {\char"00100 } % LATIN CAPITAL LETTER A WITH MACRON: Ā
+\def\amacron {\char"00101 } % LATIN SMALL LETTER A WITH MACRON: ā
+\def\Abreve {\char"00102 } % LATIN CAPITAL LETTER A WITH BREVE: Ă
+\def\abreve {\char"00103 } % LATIN SMALL LETTER A WITH BREVE: ă
+\def\Aogonek {\char"00104 } % LATIN CAPITAL LETTER A WITH OGONEK: Ą
+\def\aogonek {\char"00105 } % LATIN SMALL LETTER A WITH OGONEK: ą
+\def\Cacute {\char"00106 } % LATIN CAPITAL LETTER C WITH ACUTE: Ć
+\def\cacute {\char"00107 } % LATIN SMALL LETTER C WITH ACUTE: ć
+\def\Ccircumflex {\char"00108 } % LATIN CAPITAL LETTER C WITH CIRCUMFLEX: Ĉ
+\def\ccircumflex {\char"00109 } % LATIN SMALL LETTER C WITH CIRCUMFLEX: ĉ
+\def\Cdotaccent {\char"0010A } % LATIN CAPITAL LETTER C WITH DOT ABOVE: Ċ
+\def\cdotaccent {\char"0010B } % LATIN SMALL LETTER C WITH DOT ABOVE: ċ
+\def\Ccaron {\char"0010C } % LATIN CAPITAL LETTER C WITH CARON: Č
+\def\ccaron {\char"0010D } % LATIN SMALL LETTER C WITH CARON: č
+\def\Dcaron {\char"0010E } % LATIN CAPITAL LETTER D WITH CARON: Ď
+\def\dcaron {\char"0010F } % LATIN SMALL LETTER D WITH CARON: ď
+\def\Dstroke {\char"00110 } % LATIN CAPITAL LETTER D WITH STROKE: Đ
+\def\dstroke {\char"00111 } % LATIN SMALL LETTER D WITH STROKE: đ
+\def\Emacron {\char"00112 } % LATIN CAPITAL LETTER E WITH MACRON: Ē
+\def\emacron {\char"00113 } % LATIN SMALL LETTER E WITH MACRON: ē
+\def\Ebreve {\char"00114 } % LATIN CAPITAL LETTER E WITH BREVE: Ĕ
+\def\ebreve {\char"00115 } % LATIN SMALL LETTER E WITH BREVE: ĕ
+\def\Edotaccent {\char"00116 } % LATIN CAPITAL LETTER E WITH DOT ABOVE: Ė
+\def\edotaccent {\char"00117 } % LATIN SMALL LETTER E WITH DOT ABOVE: ė
+\def\Eogonek {\char"00118 } % LATIN CAPITAL LETTER E WITH OGONEK: Ę
+\def\eogonek {\char"00119 } % LATIN SMALL LETTER E WITH OGONEK: ę
+\def\Ecaron {\char"0011A } % LATIN CAPITAL LETTER E WITH CARON: Ě
+\def\ecaron {\char"0011B } % LATIN SMALL LETTER E WITH CARON: ě
+\def\Gcircumflex {\char"0011C } % LATIN CAPITAL LETTER G WITH CIRCUMFLEX: Ĝ
+\def\gcircumflex {\char"0011D } % LATIN SMALL LETTER G WITH CIRCUMFLEX: ĝ
+\def\Gbreve {\char"0011E } % LATIN CAPITAL LETTER G WITH BREVE: Ğ
+\def\gbreve {\char"0011F } % LATIN SMALL LETTER G WITH BREVE: ğ
+\def\Gdotaccent {\char"00120 } % LATIN CAPITAL LETTER G WITH DOT ABOVE: Ġ
+\def\gdotaccent {\char"00121 } % LATIN SMALL LETTER G WITH DOT ABOVE: ġ
+\def\Gcommaaccent {\char"00122 } % LATIN CAPITAL LETTER G WITH CEDILLA: Ģ
+\def\gcommaaccent {\char"00123 } % LATIN SMALL LETTER G WITH CEDILLA: ģ
+\def\Hcircumflex {\char"00124 } % LATIN CAPITAL LETTER H WITH CIRCUMFLEX: Ĥ
+\def\hcircumflex {\char"00125 } % LATIN SMALL LETTER H WITH CIRCUMFLEX: ĥ
+\def\Hstroke {\char"00126 } % LATIN CAPITAL LETTER H WITH STROKE: Ħ
+\def\hstroke {\char"00127 } % LATIN SMALL LETTER H WITH STROKE: ħ
+\def\Itilde {\char"00128 } % LATIN CAPITAL LETTER I WITH TILDE: Ĩ
+\def\itilde {\char"00129 } % LATIN SMALL LETTER I WITH TILDE: ĩ
+\def\Imacron {\char"0012A } % LATIN CAPITAL LETTER I WITH MACRON: Ī
+\def\imacron {\char"0012B } % LATIN SMALL LETTER I WITH MACRON: ī
+\def\Ibreve {\char"0012C } % LATIN CAPITAL LETTER I WITH BREVE: Ĭ
+\def\ibreve {\char"0012D } % LATIN SMALL LETTER I WITH BREVE: ĭ
+\def\Iogonek {\char"0012E } % LATIN CAPITAL LETTER I WITH OGONEK: Į
+\def\iogonek {\char"0012F } % LATIN SMALL LETTER I WITH OGONEK: į
+\def\Idotaccent {\char"00130 } % LATIN CAPITAL LETTER I WITH DOT ABOVE: İ
+\def\dotlessi {\char"00131 } % LATIN SMALL LETTER DOTLESS I: ı
+\def\IJligature {\char"00132 } % LATIN CAPITAL LIGATURE IJ: IJ
+\def\ijligature {\char"00133 } % LATIN SMALL LIGATURE IJ: ij
+\def\Jcircumflex {\char"00134 } % LATIN CAPITAL LETTER J WITH CIRCUMFLEX: Ĵ
+\def\jcircumflex {\char"00135 } % LATIN SMALL LETTER J WITH CIRCUMFLEX: ĵ
+\def\Kcommaaccent {\char"00136 } % LATIN CAPITAL LETTER K WITH CEDILLA: Ķ
+\def\kcommaaccent {\char"00137 } % LATIN SMALL LETTER K WITH CEDILLA: ķ
+\def\kkra {\char"00138 } % LATIN SMALL LETTER KRA: ĸ
+\def\Lacute {\char"00139 } % LATIN CAPITAL LETTER L WITH ACUTE: Ĺ
+\def\lacute {\char"0013A } % LATIN SMALL LETTER L WITH ACUTE: ĺ
+\def\Lcommaaccent {\char"0013B } % LATIN CAPITAL LETTER L WITH CEDILLA: Ļ
+\def\lcommaaccent {\char"0013C } % LATIN SMALL LETTER L WITH CEDILLA: ļ
+\def\Lcaron {\char"0013D } % LATIN CAPITAL LETTER L WITH CARON: Ľ
+\def\lcaron {\char"0013E } % LATIN SMALL LETTER L WITH CARON: ľ
+\def\Ldotmiddle {\char"0013F } % LATIN CAPITAL LETTER L WITH MIDDLE DOT: Ŀ
+\def\ldotmiddle {\char"00140 } % LATIN SMALL LETTER L WITH MIDDLE DOT: ŀ
+\def\Lstroke {\char"00141 } % LATIN CAPITAL LETTER L WITH STROKE: Ł
+\def\lstroke {\char"00142 } % LATIN SMALL LETTER L WITH STROKE: ł
+\def\Nacute {\char"00143 } % LATIN CAPITAL LETTER N WITH ACUTE: Ń
+\def\nacute {\char"00144 } % LATIN SMALL LETTER N WITH ACUTE: ń
+\def\Ncommaaccent {\char"00145 } % LATIN CAPITAL LETTER N WITH CEDILLA: Ņ
+\def\ncommaaccent {\char"00146 } % LATIN SMALL LETTER N WITH CEDILLA: ņ
+\def\Ncaron {\char"00147 } % LATIN CAPITAL LETTER N WITH CARON: Ň
+\def\ncaron {\char"00148 } % LATIN SMALL LETTER N WITH CARON: ň
+\def\napostrophe {\char"00149 } % LATIN SMALL LETTER N PRECEDED BY APOSTROPHE: ʼn
+\def\Neng {\char"0014A } % LATIN CAPITAL LETTER ENG: Ŋ
+\def\neng {\char"0014B } % LATIN SMALL LETTER ENG: ŋ
+\def\Omacron {\char"0014C } % LATIN CAPITAL LETTER O WITH MACRON: Ō
+\def\omacron {\char"0014D } % LATIN SMALL LETTER O WITH MACRON: ō
+\def\Obreve {\char"0014E } % LATIN CAPITAL LETTER O WITH BREVE: Ŏ
+\def\obreve {\char"0014F } % LATIN SMALL LETTER O WITH BREVE: ŏ
+\def\Ohungarumlaut {\char"00150 } % LATIN CAPITAL LETTER O WITH DOUBLE ACUTE: Ő
+\def\ohungarumlaut {\char"00151 } % LATIN SMALL LETTER O WITH DOUBLE ACUTE: ő
+\def\OEligature {\char"00152 } % LATIN CAPITAL LIGATURE OE: Œ
+\def\oeligature {\char"00153 } % LATIN SMALL LIGATURE OE: œ
+\def\Racute {\char"00154 } % LATIN CAPITAL LETTER R WITH ACUTE: Ŕ
+\def\racute {\char"00155 } % LATIN SMALL LETTER R WITH ACUTE: ŕ
+\def\Rcommaaccent {\char"00156 } % LATIN CAPITAL LETTER R WITH CEDILLA: Ŗ
+\def\rcommaaccent {\char"00157 } % LATIN SMALL LETTER R WITH CEDILLA: ŗ
+\def\Rcaron {\char"00158 } % LATIN CAPITAL LETTER R WITH CARON: Ř
+\def\rcaron {\char"00159 } % LATIN SMALL LETTER R WITH CARON: ř
+\def\Sacute {\char"0015A } % LATIN CAPITAL LETTER S WITH ACUTE: Ś
+\def\sacute {\char"0015B } % LATIN SMALL LETTER S WITH ACUTE: ś
+\def\Scircumflex {\char"0015C } % LATIN CAPITAL LETTER S WITH CIRCUMFLEX: Ŝ
+\def\scircumflex {\char"0015D } % LATIN SMALL LETTER S WITH CIRCUMFLEX: ŝ
+\def\Scedilla {\char"0015E } % LATIN CAPITAL LETTER S WITH CEDILLA: Ş
+\def\scedilla {\char"0015F } % LATIN SMALL LETTER S WITH CEDILLA: ş
+\def\Scaron {\char"00160 } % LATIN CAPITAL LETTER S WITH CARON: Š
+\def\scaron {\char"00161 } % LATIN SMALL LETTER S WITH CARON: š
+\def\Tcedilla {\char"00162 } % LATIN CAPITAL LETTER T WITH CEDILLA: Ţ
+\def\tcedilla {\char"00163 } % LATIN SMALL LETTER T WITH CEDILLA: ţ
+\def\Tcaron {\char"00164 } % LATIN CAPITAL LETTER T WITH CARON: Ť
+\def\tcaron {\char"00165 } % LATIN SMALL LETTER T WITH CARON: ť
+\def\Tstroke {\char"00166 } % LATIN CAPITAL LETTER T WITH STROKE: Ŧ
+\def\tstroke {\char"00167 } % LATIN SMALL LETTER T WITH STROKE: ŧ
+\def\Utilde {\char"00168 } % LATIN CAPITAL LETTER U WITH TILDE: Ũ
+\def\utilde {\char"00169 } % LATIN SMALL LETTER U WITH TILDE: ũ
+\def\Umacron {\char"0016A } % LATIN CAPITAL LETTER U WITH MACRON: Ū
+\def\umacron {\char"0016B } % LATIN SMALL LETTER U WITH MACRON: ū
+\def\Ubreve {\char"0016C } % LATIN CAPITAL LETTER U WITH BREVE: Ŭ
+\def\ubreve {\char"0016D } % LATIN SMALL LETTER U WITH BREVE: ŭ
+\def\Uring {\char"0016E } % LATIN CAPITAL LETTER U WITH RING ABOVE: Ů
+\def\uring {\char"0016F } % LATIN SMALL LETTER U WITH RING ABOVE: ů
+\def\Uhungarumlaut {\char"00170 } % LATIN CAPITAL LETTER U WITH DOUBLE ACUTE: Ű
+\def\uhungarumlaut {\char"00171 } % LATIN SMALL LETTER U WITH DOUBLE ACUTE: ű
+\def\Uogonek {\char"00172 } % LATIN CAPITAL LETTER U WITH OGONEK: Ų
+\def\uogonek {\char"00173 } % LATIN SMALL LETTER U WITH OGONEK: ų
+\def\Wcircumflex {\char"00174 } % LATIN CAPITAL LETTER W WITH CIRCUMFLEX: Ŵ
+\def\wcircumflex {\char"00175 } % LATIN SMALL LETTER W WITH CIRCUMFLEX: ŵ
+\def\Ycircumflex {\char"00176 } % LATIN CAPITAL LETTER Y WITH CIRCUMFLEX: Ŷ
+\def\ycircumflex {\char"00177 } % LATIN SMALL LETTER Y WITH CIRCUMFLEX: ŷ
+\def\Ydiaeresis {\char"00178 } % LATIN CAPITAL LETTER Y WITH DIAERESIS: Ÿ
+\def\Zacute {\char"00179 } % LATIN CAPITAL LETTER Z WITH ACUTE: Ź
+\def\zacute {\char"0017A } % LATIN SMALL LETTER Z WITH ACUTE: ź
+\def\Zdotaccent {\char"0017B } % LATIN CAPITAL LETTER Z WITH DOT ABOVE: Ż
+\def\zdotaccent {\char"0017C } % LATIN SMALL LETTER Z WITH DOT ABOVE: ż
+\def\Zcaron {\char"0017D } % LATIN CAPITAL LETTER Z WITH CARON: Ž
+\def\zcaron {\char"0017E } % LATIN SMALL LETTER Z WITH CARON: ž
+\def\slong {\char"0017F } % LATIN SMALL LETTER LONG S: ſ
+\def\bstroke {\char"00180 } % LATIN SMALL LETTER B WITH STROKE: ƀ
+\def\Bhook {\char"00181 } % LATIN CAPITAL LETTER B WITH HOOK: Ɓ
+\def\Chook {\char"00187 } % LATIN CAPITAL LETTER C WITH HOOK: Ƈ
+\def\chook {\char"00188 } % LATIN SMALL LETTER C WITH HOOK: ƈ
+\def\Dafrican {\char"00189 } % LATIN CAPITAL LETTER AFRICAN D: Ɖ
+\def\Dhook {\char"0018A } % LATIN CAPITAL LETTER D WITH HOOK: Ɗ
+\def\Schwa {\char"0018F } % LATIN CAPITAL LETTER SCHWA: Ə
+\def\Fhook {\char"00191 } % LATIN CAPITAL LETTER F WITH HOOK: Ƒ
+\def\fhook {\char"00192 } % LATIN SMALL LETTER F WITH HOOK: ƒ
+\def\Ghook {\char"00193 } % LATIN CAPITAL LETTER G WITH HOOK: Ɠ
+\def\Istroke {\char"00197 } % LATIN CAPITAL LETTER I WITH STROKE: Ɨ
+\def\Khook {\char"00198 } % LATIN CAPITAL LETTER K WITH HOOK: Ƙ
+\def\khook {\char"00199 } % LATIN SMALL LETTER K WITH HOOK: ƙ
+\def\lbar {\char"0019A } % LATIN SMALL LETTER L WITH BAR: ƚ
+\def\Ohorn {\char"001A0 } % LATIN CAPITAL LETTER O WITH HORN: Ơ
+\def\ohorn {\char"001A1 } % LATIN SMALL LETTER O WITH HORN: ơ
+\def\Phook {\char"001A4 } % LATIN CAPITAL LETTER P WITH HOOK: Ƥ
+\def\phook {\char"001A5 } % LATIN SMALL LETTER P WITH HOOK: ƥ
+\def\Thook {\char"001AC } % LATIN CAPITAL LETTER T WITH HOOK: Ƭ
+\def\thook {\char"001AD } % LATIN SMALL LETTER T WITH HOOK: ƭ
+\def\Uhorn {\char"001AF } % LATIN CAPITAL LETTER U WITH HORN: Ư
+\def\uhorn {\char"001B0 } % LATIN SMALL LETTER U WITH HORN: ư
+\def\Uhook {\char"001B2 } % LATIN CAPITAL LETTER V WITH HOOK: Ʋ
+\def\Yhook {\char"001B3 } % LATIN CAPITAL LETTER Y WITH HOOK: Ƴ
+\def\yhook {\char"001B4 } % LATIN SMALL LETTER Y WITH HOOK: ƴ
+\def\Zstroke {\char"001B5 } % LATIN CAPITAL LETTER Z WITH STROKE: Ƶ
+\def\zstroke {\char"001B6 } % LATIN SMALL LETTER Z WITH STROKE: ƶ
+\def\DZcaronligature {\char"001C4 } % LATIN CAPITAL LETTER DZ WITH CARON: DŽ
+\def\Dzcaronligature {\char"001C5 } % LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON: Dž
+\def\dzcaronligature {\char"001C6 } % LATIN SMALL LETTER DZ WITH CARON: dž
+\def\LJligature {\char"001C7 } % LATIN CAPITAL LETTER LJ: LJ
+\def\Ljligature {\char"001C8 } % LATIN CAPITAL LETTER L WITH SMALL LETTER J: Lj
+\def\ljligature {\char"001C9 } % LATIN SMALL LETTER LJ: lj
+\def\NJligature {\char"001CA } % LATIN CAPITAL LETTER NJ: NJ
+\def\Njligature {\char"001CB } % LATIN CAPITAL LETTER N WITH SMALL LETTER J: Nj
+\def\njligature {\char"001CC } % LATIN SMALL LETTER NJ: nj
+\def\Acaron {\char"001CD } % LATIN CAPITAL LETTER A WITH CARON: Ǎ
+\def\acaron {\char"001CE } % LATIN SMALL LETTER A WITH CARON: ǎ
+\def\Icaron {\char"001CF } % LATIN CAPITAL LETTER I WITH CARON: Ǐ
+\def\icaron {\char"001D0 } % LATIN SMALL LETTER I WITH CARON: ǐ
+\def\Ocaron {\char"001D1 } % LATIN CAPITAL LETTER O WITH CARON: Ǒ
+\def\ocaron {\char"001D2 } % LATIN SMALL LETTER O WITH CARON: ǒ
+\def\Ucaron {\char"001D3 } % LATIN CAPITAL LETTER U WITH CARON: Ǔ
+\def\ucaron {\char"001D4 } % LATIN SMALL LETTER U WITH CARON: ǔ
+\def\Udiaeresismacron {\char"001D5 } % LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON: Ǖ
+\def\udiaeresismacron {\char"001D6 } % LATIN SMALL LETTER U WITH DIAERESIS AND MACRON: ǖ
+\def\Udiaeresisacute {\char"001D7 } % LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE: Ǘ
+\def\udiaeresisacute {\char"001D8 } % LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE: ǘ
+\def\Udiaeresiscaron {\char"001D9 } % LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON: Ǚ
+\def\udiaeresiscaron {\char"001DA } % LATIN SMALL LETTER U WITH DIAERESIS AND CARON: ǚ
+\def\Udiaeresisgrave {\char"001DB } % LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE: Ǜ
+\def\udiaeresisgrave {\char"001DC } % LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE: ǜ
+\def\Adiaeresismacron {\char"001DE } % LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON: Ǟ
+\def\adiaeresismacron {\char"001DF } % LATIN SMALL LETTER A WITH DIAERESIS AND MACRON: ǟ
+\def\Adotaccentmacron {\char"001E0 } % LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON: Ǡ
+\def\adotaccentmacron {\char"001E1 } % LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON: ǡ
+\def\AEmacron {\char"001E2 } % LATIN CAPITAL LETTER AE WITH MACRON: Ǣ
+\def\aemacron {\char"001E3 } % LATIN SMALL LETTER AE WITH MACRON: ǣ
+\def\Gstroke {\char"001E4 } % LATIN CAPITAL LETTER G WITH STROKE: Ǥ
+\def\gstroke {\char"001E5 } % LATIN SMALL LETTER G WITH STROKE: ǥ
+\def\Gcaron {\char"001E6 } % LATIN CAPITAL LETTER G WITH CARON: Ǧ
+\def\gcaron {\char"001E7 } % LATIN SMALL LETTER G WITH CARON: ǧ
+\def\Kcaron {\char"001E8 } % LATIN CAPITAL LETTER K WITH CARON: Ǩ
+\def\kcaron {\char"001E9 } % LATIN SMALL LETTER K WITH CARON: ǩ
+\def\Oogonek {\char"001EA } % LATIN CAPITAL LETTER O WITH OGONEK: Ǫ
+\def\oogonek {\char"001EB } % LATIN SMALL LETTER O WITH OGONEK: ǫ
+\def\Oogonekmacron {\char"001EC } % LATIN CAPITAL LETTER O WITH OGONEK AND MACRON: Ǭ
+\def\oogonekmacron {\char"001ED } % LATIN SMALL LETTER O WITH OGONEK AND MACRON: ǭ
+\def\jcaron {\char"001F0 } % LATIN SMALL LETTER J WITH CARON: ǰ
+\def\DZligature {\char"001F1 } % LATIN CAPITAL LETTER DZ: DZ
+\def\Dzligature {\char"001F2 } % LATIN CAPITAL LETTER D WITH SMALL LETTER Z: Dz
+\def\dzligature {\char"001F3 } % LATIN SMALL LETTER DZ: dz
+\def\Gacute {\char"001F4 } % LATIN CAPITAL LETTER G WITH ACUTE: Ǵ
+\def\gacute {\char"001F5 } % LATIN SMALL LETTER G WITH ACUTE: ǵ
+\def\Ngrave {\char"001F8 } % LATIN CAPITAL LETTER N WITH GRAVE: Ǹ
+\def\ngrave {\char"001F9 } % LATIN SMALL LETTER N WITH GRAVE: ǹ
+\def\Aringacute {\char"001FA } % LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE: Ǻ
+\def\aringacute {\char"001FB } % LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE: ǻ
+\def\AEacute {\char"001FC } % LATIN CAPITAL LETTER AE WITH ACUTE: Ǽ
+\def\aeacute {\char"001FD } % LATIN SMALL LETTER AE WITH ACUTE: ǽ
+\def\Ostrokeacute {\char"001FE } % LATIN CAPITAL LETTER O WITH STROKE AND ACUTE: Ǿ
+\def\ostrokeacute {\char"001FF } % LATIN SMALL LETTER O WITH STROKE AND ACUTE: ǿ
+\def\Adoublegrave {\char"00200 } % LATIN CAPITAL LETTER A WITH DOUBLE GRAVE: Ȁ
+\def\adoublegrave {\char"00201 } % LATIN SMALL LETTER A WITH DOUBLE GRAVE: ȁ
+\def\Ainvertedbreve {\char"00202 } % LATIN CAPITAL LETTER A WITH INVERTED BREVE: Ȃ
+\def\ainvertedbreve {\char"00203 } % LATIN SMALL LETTER A WITH INVERTED BREVE: ȃ
+\def\Edoublegrave {\char"00204 } % LATIN CAPITAL LETTER E WITH DOUBLE GRAVE: Ȅ
+\def\edoublegrave {\char"00205 } % LATIN SMALL LETTER E WITH DOUBLE GRAVE: ȅ
+\def\Einvertedbreve {\char"00206 } % LATIN CAPITAL LETTER E WITH INVERTED BREVE: Ȇ
+\def\einvertedbreve {\char"00207 } % LATIN SMALL LETTER E WITH INVERTED BREVE: ȇ
+\def\Idoublegrave {\char"00208 } % LATIN CAPITAL LETTER I WITH DOUBLE GRAVE: Ȉ
+\def\idoublegrave {\char"00209 } % LATIN SMALL LETTER I WITH DOUBLE GRAVE: ȉ
+\def\Iinvertedbreve {\char"0020A } % LATIN CAPITAL LETTER I WITH INVERTED BREVE: Ȋ
+\def\iinvertedbreve {\char"0020B } % LATIN SMALL LETTER I WITH INVERTED BREVE: ȋ
+\def\Odoublegrave {\char"0020C } % LATIN CAPITAL LETTER O WITH DOUBLE GRAVE: Ȍ
+\def\odoublegrave {\char"0020D } % LATIN SMALL LETTER O WITH DOUBLE GRAVE: ȍ
+\def\Oinvertedbreve {\char"0020E } % LATIN CAPITAL LETTER O WITH INVERTED BREVE: Ȏ
+\def\oinvertedbreve {\char"0020F } % LATIN SMALL LETTER O WITH INVERTED BREVE: ȏ
+\def\Rdoublegrave {\char"00210 } % LATIN CAPITAL LETTER R WITH DOUBLE GRAVE: Ȑ
+\def\rdoublegrave {\char"00211 } % LATIN SMALL LETTER R WITH DOUBLE GRAVE: ȑ
+\def\Rinvertedbreve {\char"00212 } % LATIN CAPITAL LETTER R WITH INVERTED BREVE: Ȓ
+\def\rinvertedbreve {\char"00213 } % LATIN SMALL LETTER R WITH INVERTED BREVE: ȓ
+\def\Udoublegrave {\char"00214 } % LATIN CAPITAL LETTER U WITH DOUBLE GRAVE: Ȕ
+\def\udoublegrave {\char"00215 } % LATIN SMALL LETTER U WITH DOUBLE GRAVE: ȕ
+\def\Uinvertedbreve {\char"00216 } % LATIN CAPITAL LETTER U WITH INVERTED BREVE: Ȗ
+\def\uinvertedbreve {\char"00217 } % LATIN SMALL LETTER U WITH INVERTED BREVE: ȗ
+\def\Scommaaccent {\char"00218 } % LATIN CAPITAL LETTER S WITH COMMA BELOW: Ș
+\def\scommaaccent {\char"00219 } % LATIN SMALL LETTER S WITH COMMA BELOW: ș
+\def\Tcommaaccent {\char"0021A } % LATIN CAPITAL LETTER T WITH COMMA BELOW: Ț
+\def\tcommaaccent {\char"0021B } % LATIN SMALL LETTER T WITH COMMA BELOW: ț
+\def\Hcaron {\char"0021E } % LATIN CAPITAL LETTER H WITH CARON: Ȟ
+\def\hcaron {\char"0021F } % LATIN SMALL LETTER H WITH CARON: ȟ
+\def\dcurl {\char"00221 } % LATIN SMALL LETTER D WITH CURL: ȡ
+\def\Zhook {\char"00224 } % LATIN CAPITAL LETTER Z WITH HOOK: Ȥ
+\def\zhook {\char"00225 } % LATIN SMALL LETTER Z WITH HOOK: ȥ
+\def\Adotaccent {\char"00226 } % LATIN CAPITAL LETTER A WITH DOT ABOVE: Ȧ
+\def\adotaccent {\char"00227 } % LATIN SMALL LETTER A WITH DOT ABOVE: ȧ
+\def\Ecedilla {\char"00228 } % LATIN CAPITAL LETTER E WITH CEDILLA: Ȩ
+\def\ecedilla {\char"00229 } % LATIN SMALL LETTER E WITH CEDILLA: ȩ
+\def\Odiaeresismacron {\char"0022A } % LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON: Ȫ
+\def\odiaeresismacron {\char"0022B } % LATIN SMALL LETTER O WITH DIAERESIS AND MACRON: ȫ
+\def\Otildemacron {\char"0022C } % LATIN CAPITAL LETTER O WITH TILDE AND MACRON: Ȭ
+\def\otildemacron {\char"0022D } % LATIN SMALL LETTER O WITH TILDE AND MACRON: ȭ
+\def\Odotaccent {\char"0022E } % LATIN CAPITAL LETTER O WITH DOT ABOVE: Ȯ
+\def\odotaccent {\char"0022F } % LATIN SMALL LETTER O WITH DOT ABOVE: ȯ
+\def\Odotaccentmacron {\char"00230 } % LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON: Ȱ
+\def\odotaccentmacron {\char"00231 } % LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON: ȱ
+\def\Ymacron {\char"00232 } % LATIN CAPITAL LETTER Y WITH MACRON: Ȳ
+\def\ymacron {\char"00233 } % LATIN SMALL LETTER Y WITH MACRON: ȳ
+\def\lcurl {\char"00234 } % LATIN SMALL LETTER L WITH CURL: ȴ
+\def\ncurl {\char"00235 } % LATIN SMALL LETTER N WITH CURL: ȵ
+\def\tcurl {\char"00236 } % LATIN SMALL LETTER T WITH CURL: ȶ
+\def\dotlessj {\char"00237 } % LATIN SMALL LETTER DOTLESS J: ȷ
+\def\Astroke {\char"0023A } % LATIN CAPITAL LETTER A WITH STROKE: Ⱥ
+\def\Cstroke {\char"0023B } % LATIN CAPITAL LETTER C WITH STROKE: Ȼ
+\def\cstroke {\char"0023C } % LATIN SMALL LETTER C WITH STROKE: ȼ
+\def\Lbar {\char"0023D } % LATIN CAPITAL LETTER L WITH BAR: Ƚ
+\def\bhook {\char"00253 } % LATIN SMALL LETTER B WITH HOOK: ɓ
+\def\ccurl {\char"00255 } % LATIN SMALL LETTER C WITH CURL: ɕ
+\def\dtail {\char"00256 } % LATIN SMALL LETTER D WITH TAIL: ɖ
+\def\dhook {\char"00257 } % LATIN SMALL LETTER D WITH HOOK: ɗ
+\def\schwa {\char"00259 } % LATIN SMALL LETTER SCHWA: ə
+\def\schwahook {\char"0025A } % LATIN SMALL LETTER SCHWA WITH HOOK: ɚ
+\def\dotlessjstroke {\char"0025F } % LATIN SMALL LETTER DOTLESS J WITH STROKE: ɟ
+\def\textcircumflex {\char"002C6 } % MODIFIER LETTER CIRCUMFLEX ACCENT: ˆ
+\def\textcaron {\char"002C7 } % CARON: ˇ
+\def\textbreve {\char"002D8 } % BREVE: ˘
+\def\textdotaccent {\char"002D9 } % DOT ABOVE: ˙
+\def\textring {\char"002DA } % RING ABOVE: ˚
+\def\textogonek {\char"002DB } % OGONEK: ˛
+\def\texttilde {\char"002DC } % SMALL TILDE: ˜
+\def\texthungarumlaut {\char"002DD } % DOUBLE ACUTE ACCENT: ˝
+\def\textbottomdot {\char"00323 } % COMBINING DOT BELOW: ̣
+\def\textbottomcomma {\char"00326 } % COMBINING COMMA BELOW: ̦
+\def\greektonos {\char"00384 } % GREEK TONOS: ΄
+\def\greekdialytikatonos {\char"00385 } % GREEK DIALYTIKA TONOS: ΅
+\def\greekAlphatonos {\char"00386 } % GREEK CAPITAL LETTER ALPHA WITH TONOS: Ά
+\def\greekEpsilontonos {\char"00388 } % GREEK CAPITAL LETTER EPSILON WITH TONOS: Έ
+\def\greekEtatonos {\char"00389 } % GREEK CAPITAL LETTER ETA WITH TONOS: Ή
+\def\greekIotatonos {\char"0038A } % GREEK CAPITAL LETTER IOTA WITH TONOS: Ί
+\def\greekOmicrontonos {\char"0038C } % GREEK CAPITAL LETTER OMICRON WITH TONOS: Ό
+\def\greekUpsilontonos {\char"0038E } % GREEK CAPITAL LETTER UPSILON WITH TONOS: Ύ
+\def\greekOmegatonos {\char"0038F } % GREEK CAPITAL LETTER OMEGA WITH TONOS: Ώ
+\def\greekiotadialytikatonos {\char"00390 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS: ΐ
+\def\greekAlpha {\char"00391 } % GREEK CAPITAL LETTER ALPHA: Α
+\def\greekBeta {\char"00392 } % GREEK CAPITAL LETTER BETA: Β
+\def\greekGamma {\char"00393 } % GREEK CAPITAL LETTER GAMMA: Γ
+\def\greekDelta {\char"00394 } % GREEK CAPITAL LETTER DELTA: Δ
+\def\greekEpsilon {\char"00395 } % GREEK CAPITAL LETTER EPSILON: Ε
+\def\greekZeta {\char"00396 } % GREEK CAPITAL LETTER ZETA: Ζ
+\def\greekEta {\char"00397 } % GREEK CAPITAL LETTER ETA: Η
+\def\greekTheta {\char"00398 } % GREEK CAPITAL LETTER THETA: Θ
+\def\greekIota {\char"00399 } % GREEK CAPITAL LETTER IOTA: Ι
+\def\greekKappa {\char"0039A } % GREEK CAPITAL LETTER KAPPA: Κ
+\def\greekLambda {\char"0039B } % GREEK CAPITAL LETTER LAMDA: Λ
+\def\greekMu {\char"0039C } % GREEK CAPITAL LETTER MU: Μ
+\def\greekNu {\char"0039D } % GREEK CAPITAL LETTER NU: Ν
+\def\greekXi {\char"0039E } % GREEK CAPITAL LETTER XI: Ξ
+\def\greekOmicron {\char"0039F } % GREEK CAPITAL LETTER OMICRON: Ο
+\def\greekPi {\char"003A0 } % GREEK CAPITAL LETTER PI: Π
+\def\greekRho {\char"003A1 } % GREEK CAPITAL LETTER RHO: Ρ
+\def\greekSigma {\char"003A3 } % GREEK CAPITAL LETTER SIGMA: Σ
+\def\greekTau {\char"003A4 } % GREEK CAPITAL LETTER TAU: Τ
+\def\greekUpsilon {\char"003A5 } % GREEK CAPITAL LETTER UPSILON: Υ
+\def\greekPhi {\char"003A6 } % GREEK CAPITAL LETTER PHI: Φ
+\def\greekChi {\char"003A7 } % GREEK CAPITAL LETTER CHI: Χ
+\def\greekPsi {\char"003A8 } % GREEK CAPITAL LETTER PSI: Ψ
+\def\greekOmega {\char"003A9 } % GREEK CAPITAL LETTER OMEGA: Ω
+\def\greekIotadialytika {\char"003AA } % GREEK CAPITAL LETTER IOTA WITH DIALYTIKA: Ϊ
+\def\greekUpsilondialytika {\char"003AB } % GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA: Ϋ
+\def\greekalphatonos {\char"003AC } % GREEK SMALL LETTER ALPHA WITH TONOS: ά
+\def\greekepsilontonos {\char"003AD } % GREEK SMALL LETTER EPSILON WITH TONOS: έ
+\def\greeketatonos {\char"003AE } % GREEK SMALL LETTER ETA WITH TONOS: ή
+\def\greekiotatonos {\char"003AF } % GREEK SMALL LETTER IOTA WITH TONOS: ί
+\def\greekupsilondialytikatonos {\char"003B0 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS: ΰ
+\def\greekalpha {\char"003B1 } % GREEK SMALL LETTER ALPHA: α
+\def\greekbeta {\char"003B2 } % GREEK SMALL LETTER BETA: β
+\def\greekgamma {\char"003B3 } % GREEK SMALL LETTER GAMMA: γ
+\def\greekdelta {\char"003B4 } % GREEK SMALL LETTER DELTA: δ
+\def\greekepsilon {\char"003B5 } % GREEK SMALL LETTER EPSILON: ε
+\def\greekzeta {\char"003B6 } % GREEK SMALL LETTER ZETA: ζ
+\def\greeketa {\char"003B7 } % GREEK SMALL LETTER ETA: η
+\def\greektheta {\char"003B8 } % GREEK SMALL LETTER THETA: θ
+\def\greekiota {\char"003B9 } % GREEK SMALL LETTER IOTA: ι
+\def\greekkappa {\char"003BA } % GREEK SMALL LETTER KAPPA: κ
+\def\greeklambda {\char"003BB } % GREEK SMALL LETTER LAMDA: λ
+\def\greekmu {\char"003BC } % GREEK SMALL LETTER MU: μ
+\def\greeknu {\char"003BD } % GREEK SMALL LETTER NU: ν
+\def\greekxi {\char"003BE } % GREEK SMALL LETTER XI: ξ
+\def\greekomicron {\char"003BF } % GREEK SMALL LETTER OMICRON: ο
+\def\greekpi {\char"003C0 } % GREEK SMALL LETTER PI: π
+\def\greekrho {\char"003C1 } % GREEK SMALL LETTER RHO: ρ
+\def\greekfinalsigma {\char"003C2 } % GREEK SMALL LETTER FINAL SIGMA: ς
+\def\greeksigma {\char"003C3 } % GREEK SMALL LETTER SIGMA: σ
+\def\greektau {\char"003C4 } % GREEK SMALL LETTER TAU: τ
+\def\greekupsilon {\char"003C5 } % GREEK SMALL LETTER UPSILON: υ
+\def\greekphi {\char"003C6 } % GREEK SMALL LETTER PHI: φ
+\def\greekchi {\char"003C7 } % GREEK SMALL LETTER CHI: χ
+\def\greekpsi {\char"003C8 } % GREEK SMALL LETTER PSI: ψ
+\def\greekomega {\char"003C9 } % GREEK SMALL LETTER OMEGA: ω
+\def\greekiotadialytika {\char"003CA } % GREEK SMALL LETTER IOTA WITH DIALYTIKA: ϊ
+\def\greekupsilondiaeresis {\char"003CB } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA: ϋ
+\def\greekomicrontonos {\char"003CC } % GREEK SMALL LETTER OMICRON WITH TONOS: ό
+\def\greekupsilontonos {\char"003CD } % GREEK SMALL LETTER UPSILON WITH TONOS: ύ
+\def\greekomegatonos {\char"003CE } % GREEK SMALL LETTER OMEGA WITH TONOS: ώ
+\def\greekthetaalt {\char"003D1 } % GREEK THETA SYMBOL: ϑ
+\def\greekphialt {\char"003D5 } % GREEK PHI SYMBOL: ϕ
+\def\greekpialt {\char"003D6 } % GREEK PI SYMBOL: ϖ
+\def\greekkoppa {\char"003D9 } % GREEK SMALL LETTER ARCHAIC KOPPA: ϙ
+\def\greekstigma {\char"003DB } % GREEK SMALL LETTER STIGMA: ϛ
+\def\greekdigamma {\char"003DD } % GREEK SMALL LETTER DIGAMMA: ϝ
+\def\greeknumkoppa {\char"003DF } % GREEK SMALL LETTER KOPPA: ϟ
+\def\greeksampi {\char"003E1 } % GREEK SMALL LETTER SAMPI: ϡ
+\def\greekrhoalt {\char"003F1 } % GREEK RHO SYMBOL: ϱ
+\def\greeksigmalunate {\char"003F2 } % GREEK LUNATE SIGMA SYMBOL: ϲ
+\def\greekepsilonalt {\char"003F5 } % GREEK LUNATE EPSILON SYMBOL: ϵ
+\def\greekSigmalunate {\char"003F9 } % GREEK CAPITAL LUNATE SIGMA SYMBOL: Ϲ
+\def\cyrillicEgrave {\char"00400 } % CYRILLIC CAPITAL LETTER IE WITH GRAVE: Ѐ
+\def\cyrillicYO {\char"00401 } % CYRILLIC CAPITAL LETTER IO: Ё
+\def\cyrillicDJE {\char"00402 } % CYRILLIC CAPITAL LETTER DJE: Ђ
+\def\cyrillicGJE {\char"00403 } % CYRILLIC CAPITAL LETTER GJE: Ѓ
+\def\cyrillicIE {\char"00404 } % CYRILLIC CAPITAL LETTER UKRAINIAN IE: Є
+\def\cyrillicDZE {\char"00405 } % CYRILLIC CAPITAL LETTER DZE: Ѕ
+\def\cyrillicII {\char"00406 } % CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I: І
+\def\cyrillicYI {\char"00407 } % CYRILLIC CAPITAL LETTER YI: Ї
+\def\cyrillicJE {\char"00408 } % CYRILLIC CAPITAL LETTER JE: Ј
+\def\cyrillicLJE {\char"00409 } % CYRILLIC CAPITAL LETTER LJE: Љ
+\def\cyrillicNJE {\char"0040A } % CYRILLIC CAPITAL LETTER NJE: Њ
+\def\cyrillicTSHE {\char"0040B } % CYRILLIC CAPITAL LETTER TSHE: Ћ
+\def\cyrillicKJE {\char"0040C } % CYRILLIC CAPITAL LETTER KJE: Ќ
+\def\cyrillicIgrave {\char"0040D } % CYRILLIC CAPITAL LETTER I WITH GRAVE: Ѝ
+\def\cyrillicUSHRT {\char"0040E } % CYRILLIC CAPITAL LETTER SHORT U: Ў
+\def\cyrillicDZHE {\char"0040F } % CYRILLIC CAPITAL LETTER DZHE: Џ
+\def\cyrillicA {\char"00410 } % CYRILLIC CAPITAL LETTER A: А
+\def\cyrillicB {\char"00411 } % CYRILLIC CAPITAL LETTER BE: Б
+\def\cyrillicV {\char"00412 } % CYRILLIC CAPITAL LETTER VE: В
+\def\cyrillicG {\char"00413 } % CYRILLIC CAPITAL LETTER GHE: Г
+\def\cyrillicD {\char"00414 } % CYRILLIC CAPITAL LETTER DE: Д
+\def\cyrillicE {\char"00415 } % CYRILLIC CAPITAL LETTER IE: Е
+\def\cyrillicZH {\char"00416 } % CYRILLIC CAPITAL LETTER ZHE: Ж
+\def\cyrillicZ {\char"00417 } % CYRILLIC CAPITAL LETTER ZE: З
+\def\cyrillicI {\char"00418 } % CYRILLIC CAPITAL LETTER I: И
+\def\cyrillicISHRT {\char"00419 } % CYRILLIC CAPITAL LETTER SHORT I: Й
+\def\cyrillicK {\char"0041A } % CYRILLIC CAPITAL LETTER KA: К
+\def\cyrillicL {\char"0041B } % CYRILLIC CAPITAL LETTER EL: Л
+\def\cyrillicM {\char"0041C } % CYRILLIC CAPITAL LETTER EM: М
+\def\cyrillicN {\char"0041D } % CYRILLIC CAPITAL LETTER EN: Н
+\def\cyrillicO {\char"0041E } % CYRILLIC CAPITAL LETTER O: О
+\def\cyrillicP {\char"0041F } % CYRILLIC CAPITAL LETTER PE: П
+\def\cyrillicR {\char"00420 } % CYRILLIC CAPITAL LETTER ER: Р
+\def\cyrillicS {\char"00421 } % CYRILLIC CAPITAL LETTER ES: С
+\def\cyrillicT {\char"00422 } % CYRILLIC CAPITAL LETTER TE: Т
+\def\cyrillicU {\char"00423 } % CYRILLIC CAPITAL LETTER U: У
+\def\cyrillicF {\char"00424 } % CYRILLIC CAPITAL LETTER EF: Ф
+\def\cyrillicH {\char"00425 } % CYRILLIC CAPITAL LETTER HA: Х
+\def\cyrillicC {\char"00426 } % CYRILLIC CAPITAL LETTER TSE: Ц
+\def\cyrillicCH {\char"00427 } % CYRILLIC CAPITAL LETTER CHE: Ч
+\def\cyrillicSH {\char"00428 } % CYRILLIC CAPITAL LETTER SHA: Ш
+\def\cyrillicSHCH {\char"00429 } % CYRILLIC CAPITAL LETTER SHCHA: Щ
+\def\cyrillicHRDSN {\char"0042A } % CYRILLIC CAPITAL LETTER HARD SIGN: Ъ
+\def\cyrillicERY {\char"0042B } % CYRILLIC CAPITAL LETTER YERU: Ы
+\def\cyrillicSFTSN {\char"0042C } % CYRILLIC CAPITAL LETTER SOFT SIGN: Ь
+\def\cyrillicEREV {\char"0042D } % CYRILLIC CAPITAL LETTER E: Э
+\def\cyrillicYU {\char"0042E } % CYRILLIC CAPITAL LETTER YU: Ю
+\def\cyrillicYA {\char"0042F } % CYRILLIC CAPITAL LETTER YA: Я
+\def\cyrillica {\char"00430 } % CYRILLIC SMALL LETTER A: а
+\def\cyrillicb {\char"00431 } % CYRILLIC SMALL LETTER BE: б
+\def\cyrillicv {\char"00432 } % CYRILLIC SMALL LETTER VE: в
+\def\cyrillicg {\char"00433 } % CYRILLIC SMALL LETTER GHE: г
+\def\cyrillicd {\char"00434 } % CYRILLIC SMALL LETTER DE: д
+\def\cyrillice {\char"00435 } % CYRILLIC SMALL LETTER IE: е
+\def\cyrilliczh {\char"00436 } % CYRILLIC SMALL LETTER ZHE: ж
+\def\cyrillicz {\char"00437 } % CYRILLIC SMALL LETTER ZE: з
+\def\cyrillici {\char"00438 } % CYRILLIC SMALL LETTER I: и
+\def\cyrillicishrt {\char"00439 } % CYRILLIC SMALL LETTER SHORT I: й
+\def\cyrillick {\char"0043A } % CYRILLIC SMALL LETTER KA: к
+\def\cyrillicl {\char"0043B } % CYRILLIC SMALL LETTER EL: л
+\def\cyrillicm {\char"0043C } % CYRILLIC SMALL LETTER EM: м
+\def\cyrillicn {\char"0043D } % CYRILLIC SMALL LETTER EN: н
+\def\cyrillico {\char"0043E } % CYRILLIC SMALL LETTER O: о
+\def\cyrillicp {\char"0043F } % CYRILLIC SMALL LETTER PE: п
+\def\cyrillicr {\char"00440 } % CYRILLIC SMALL LETTER ER: р
+\def\cyrillics {\char"00441 } % CYRILLIC SMALL LETTER ES: с
+\def\cyrillict {\char"00442 } % CYRILLIC SMALL LETTER TE: т
+\def\cyrillicu {\char"00443 } % CYRILLIC SMALL LETTER U: у
+\def\cyrillicf {\char"00444 } % CYRILLIC SMALL LETTER EF: ф
+\def\cyrillich {\char"00445 } % CYRILLIC SMALL LETTER HA: х
+\def\cyrillicc {\char"00446 } % CYRILLIC SMALL LETTER TSE: ц
+\def\cyrillicch {\char"00447 } % CYRILLIC SMALL LETTER CHE: ч
+\def\cyrillicsh {\char"00448 } % CYRILLIC SMALL LETTER SHA: ш
+\def\cyrillicshch {\char"00449 } % CYRILLIC SMALL LETTER SHCHA: щ
+\def\cyrillichrdsn {\char"0044A } % CYRILLIC SMALL LETTER HARD SIGN: ъ
+\def\cyrillicery {\char"0044B } % CYRILLIC SMALL LETTER YERU: ы
+\def\cyrillicsftsn {\char"0044C } % CYRILLIC SMALL LETTER SOFT SIGN: ь
+\def\cyrillicerev {\char"0044D } % CYRILLIC SMALL LETTER E: э
+\def\cyrillicyu {\char"0044E } % CYRILLIC SMALL LETTER YU: ю
+\def\cyrillicya {\char"0044F } % CYRILLIC SMALL LETTER YA: я
+\def\cyrillicegrave {\char"00450 } % CYRILLIC SMALL LETTER IE WITH GRAVE: ѐ
+\def\cyrillicyo {\char"00451 } % CYRILLIC SMALL LETTER IO: ё
+\def\cyrillicdje {\char"00452 } % CYRILLIC SMALL LETTER DJE: ђ
+\def\cyrillicgje {\char"00453 } % CYRILLIC SMALL LETTER GJE: ѓ
+\def\cyrillicie {\char"00454 } % CYRILLIC SMALL LETTER UKRAINIAN IE: є
+\def\cyrillicdze {\char"00455 } % CYRILLIC SMALL LETTER DZE: ѕ
+\def\cyrillicii {\char"00456 } % CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I: і
+\def\cyrillicyi {\char"00457 } % CYRILLIC SMALL LETTER YI: ї
+\def\cyrillicje {\char"00458 } % CYRILLIC SMALL LETTER JE: ј
+\def\cyrilliclje {\char"00459 } % CYRILLIC SMALL LETTER LJE: љ
+\def\cyrillicnje {\char"0045A } % CYRILLIC SMALL LETTER NJE: њ
+\def\cyrillictshe {\char"0045B } % CYRILLIC SMALL LETTER TSHE: ћ
+\def\cyrillickje {\char"0045C } % CYRILLIC SMALL LETTER KJE: ќ
+\def\cyrillicigrave {\char"0045D } % CYRILLIC SMALL LETTER I WITH GRAVE: ѝ
+\def\cyrillicushrt {\char"0045E } % CYRILLIC SMALL LETTER SHORT U: ў
+\def\cyrillicdzhe {\char"0045F } % CYRILLIC SMALL LETTER DZHE: џ
+\def\cyrillicOMEGA {\char"00460 } % CYRILLIC CAPITAL LETTER OMEGA: Ѡ
+\def\cyrillicomega {\char"00461 } % CYRILLIC SMALL LETTER OMEGA: ѡ
+\def\cyrillicYAT {\char"00462 } % CYRILLIC CAPITAL LETTER YAT: Ѣ
+\def\cyrillicyat {\char"00463 } % CYRILLIC SMALL LETTER YAT: ѣ
+\def\cyrillicEiotified {\char"00464 } % CYRILLIC CAPITAL LETTER IOTIFIED E: Ѥ
+\def\cyrilliceiotified {\char"00465 } % CYRILLIC SMALL LETTER IOTIFIED E: ѥ
+\def\cyrillicLITTLEYUS {\char"00466 } % CYRILLIC CAPITAL LETTER LITTLE YUS: Ѧ
+\def\cyrilliclittleyus {\char"00467 } % CYRILLIC SMALL LETTER LITTLE YUS: ѧ
+\def\cyrillicLITTLEYUSiotified {\char"00468 } % CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS: Ѩ
+\def\cyrilliclittleyusiotified {\char"00469 } % CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS: ѩ
+\def\cyrillicBIGYUS {\char"0046A } % CYRILLIC CAPITAL LETTER BIG YUS: Ѫ
+\def\cyrillicbigyus {\char"0046B } % CYRILLIC SMALL LETTER BIG YUS: ѫ
+\def\cyrillicBIGYUSiotified {\char"0046C } % CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS: Ѭ
+\def\cyrillicbigyusiotified {\char"0046D } % CYRILLIC SMALL LETTER IOTIFIED BIG YUS: ѭ
+\def\cyrillicKSI {\char"0046E } % CYRILLIC CAPITAL LETTER KSI: Ѯ
+\def\cyrillicksi {\char"0046F } % CYRILLIC SMALL LETTER KSI: ѯ
+\def\cyrillicPSI {\char"00470 } % CYRILLIC CAPITAL LETTER PSI: Ѱ
+\def\cyrillicpsi {\char"00471 } % CYRILLIC SMALL LETTER PSI: ѱ
+\def\cyrillicFITA {\char"00472 } % CYRILLIC CAPITAL LETTER FITA: Ѳ
+\def\cyrillicfita {\char"00473 } % CYRILLIC SMALL LETTER FITA: ѳ
+\def\cyrillicIZHITSA {\char"00474 } % CYRILLIC CAPITAL LETTER IZHITSA: Ѵ
+\def\cyrillicizhitsa {\char"00475 } % CYRILLIC SMALL LETTER IZHITSA: ѵ
+\def\cyrillicIZHITSAdoublegrave {\char"00476 } % CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT: Ѷ
+\def\cyrillicizhitsadoublegrave {\char"00477 } % CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT: ѷ
+\def\cyrillicUK {\char"00478 } % CYRILLIC CAPITAL LETTER UK: Ѹ
+\def\cyrillicuk {\char"00479 } % CYRILLIC SMALL LETTER UK: ѹ
+\def\cyrillicOMEGAround {\char"0047A } % CYRILLIC CAPITAL LETTER ROUND OMEGA: Ѻ
+\def\cyrillicomegaround {\char"0047B } % CYRILLIC SMALL LETTER ROUND OMEGA: ѻ
+\def\cyrillicOMEGAtitlo {\char"0047C } % CYRILLIC CAPITAL LETTER OMEGA WITH TITLO: Ѽ
+\def\cyrillicomegatitlo {\char"0047D } % CYRILLIC SMALL LETTER OMEGA WITH TITLO: ѽ
+\def\cyrillicOT {\char"0047E } % CYRILLIC CAPITAL LETTER OT: Ѿ
+\def\cyrillicot {\char"0047F } % CYRILLIC SMALL LETTER OT: ѿ
+\def\cyrillicKOPPA {\char"00480 } % CYRILLIC CAPITAL LETTER KOPPA: Ҁ
+\def\cyrillickoppa {\char"00481 } % CYRILLIC SMALL LETTER KOPPA: ҁ
+\def\cyrillicTITLO {\char"00483 } % COMBINING CYRILLIC TITLO: ҃
+\def\cyrillicPALATALIZATION {\char"00484 } % COMBINING CYRILLIC PALATALIZATION: ҄
+\def\cyrillicDASIAPNEUMATA {\char"00485 } % COMBINING CYRILLIC DASIA PNEUMATA: ҅
+\def\cyrillicPSILIPNEUMATA {\char"00486 } % COMBINING CYRILLIC PSILI PNEUMATA: ҆
+\def\cyrillicISHRTtail {\char"0048A } % CYRILLIC CAPITAL LETTER SHORT I WITH TAIL: Ҋ
+\def\cyrillicishrttail {\char"0048B } % CYRILLIC SMALL LETTER SHORT I WITH TAIL: ҋ
+\def\cyrillicSEMISOFT {\char"0048C } % CYRILLIC CAPITAL LETTER SEMISOFT SIGN: Ҍ
+\def\cyrillicsemisoft {\char"0048D } % CYRILLIC SMALL LETTER SEMISOFT SIGN: ҍ
+\def\cyrillicERtick {\char"0048E } % CYRILLIC CAPITAL LETTER ER WITH TICK: Ҏ
+\def\cyrillicertick {\char"0048F } % CYRILLIC SMALL LETTER ER WITH TICK: ҏ
+\def\cyrillicGHEupturn {\char"00490 } % CYRILLIC CAPITAL LETTER GHE WITH UPTURN: Ґ
+\def\cyrillicgheupturn {\char"00491 } % CYRILLIC SMALL LETTER GHE WITH UPTURN: ґ
+\def\cyrillicGHEstroke {\char"00492 } % CYRILLIC CAPITAL LETTER GHE WITH STROKE: Ғ
+\def\cyrillicghestroke {\char"00493 } % CYRILLIC SMALL LETTER GHE WITH STROKE: ғ
+\def\cyrillicGHEmidhook {\char"00494 } % CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK: Ҕ
+\def\cyrillicghemidhook {\char"00495 } % CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK: ҕ
+\def\cyrillicZHEdescender {\char"00496 } % CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER: Җ
+\def\cyrilliczhedescender {\char"00497 } % CYRILLIC SMALL LETTER ZHE WITH DESCENDER: җ
+\def\cyrillicZDSC {\char"00498 } % CYRILLIC CAPITAL LETTER ZE WITH DESCENDER: Ҙ
+\def\cyrilliczdsc {\char"00499 } % CYRILLIC SMALL LETTER ZE WITH DESCENDER: ҙ
+\def\cyrillicKADC {\char"0049A } % CYRILLIC CAPITAL LETTER KA WITH DESCENDER: Қ
+\def\cyrillickadc {\char"0049B } % CYRILLIC SMALL LETTER KA WITH DESCENDER: қ
+\def\cyrillicKAvertstroke {\char"0049C } % CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE: Ҝ
+\def\cyrillickavertstroke {\char"0049D } % CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE: ҝ
+\def\cyrillicKAstroke {\char"0049E } % CYRILLIC CAPITAL LETTER KA WITH STROKE: Ҟ
+\def\cyrillickastroke {\char"0049F } % CYRILLIC SMALL LETTER KA WITH STROKE: ҟ
+\def\cyrillicKAbashkir {\char"004A0 } % CYRILLIC CAPITAL LETTER BASHKIR KA: Ҡ
+\def\cyrillickabashkir {\char"004A1 } % CYRILLIC SMALL LETTER BASHKIR KA: ҡ
+\def\cyrillicENDC {\char"004A2 } % CYRILLIC CAPITAL LETTER EN WITH DESCENDER: Ң
+\def\cyrillicendc {\char"004A3 } % CYRILLIC SMALL LETTER EN WITH DESCENDER: ң
+\def\cyrillicENGHE {\char"004A4 } % CYRILLIC CAPITAL LIGATURE EN GHE: Ҥ
+\def\cyrillicenghe {\char"004A5 } % CYRILLIC SMALL LIGATURE EN GHE: ҥ
+\def\cyrillicPEmidhook {\char"004A6 } % CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK: Ҧ
+\def\cyrillicpemidhook {\char"004A7 } % CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK: ҧ
+\def\cyrillicHA {\char"004A8 } % CYRILLIC CAPITAL LETTER ABKHASIAN HA: Ҩ
+\def\cyrillicha {\char"004A9 } % CYRILLIC SMALL LETTER ABKHASIAN HA: ҩ
+\def\cyrillicSDSC {\char"004AA } % CYRILLIC CAPITAL LETTER ES WITH DESCENDER: Ҫ
+\def\cyrillicsdsc {\char"004AB } % CYRILLIC SMALL LETTER ES WITH DESCENDER: ҫ
+\def\cyrillicTEDC {\char"004AC } % CYRILLIC CAPITAL LETTER TE WITH DESCENDER: Ҭ
+\def\cyrillictedc {\char"004AD } % CYRILLIC SMALL LETTER TE WITH DESCENDER: ҭ
+\def\cyrillicYstr {\char"004AE } % CYRILLIC CAPITAL LETTER STRAIGHT U: Ү
+\def\cyrillicystr {\char"004AF } % CYRILLIC SMALL LETTER STRAIGHT U: ү
+\def\cyrillicYstrstroke {\char"004B0 } % CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE: Ұ
+\def\cyrillicystrstroke {\char"004B1 } % CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE: ұ
+\def\cyrillicHADC {\char"004B2 } % CYRILLIC CAPITAL LETTER HA WITH DESCENDER: Ҳ
+\def\cyrillichadc {\char"004B3 } % CYRILLIC SMALL LETTER HA WITH DESCENDER: ҳ
+\def\cyrillicTETSE {\char"004B4 } % CYRILLIC CAPITAL LIGATURE TE TSE: Ҵ
+\def\cyrillictetse {\char"004B5 } % CYRILLIC SMALL LIGATURE TE TSE: ҵ
+\def\cyrillicCHEDC {\char"004B6 } % CYRILLIC CAPITAL LETTER CHE WITH DESCENDER: Ҷ
+\def\cyrillicchedc {\char"004B7 } % CYRILLIC SMALL LETTER CHE WITH DESCENDER: ҷ
+\def\cyrillicCHEvertstroke {\char"004B8 } % CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE: Ҹ
+\def\cyrillicchevertstroke {\char"004B9 } % CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE: ҹ
+\def\cyrillicSHHA {\char"004BA } % CYRILLIC CAPITAL LETTER SHHA: Һ
+\def\cyrillicshha {\char"004BB } % CYRILLIC SMALL LETTER SHHA: һ
+\def\cyrillicCHEabkhasian {\char"004BC } % CYRILLIC CAPITAL LETTER ABKHASIAN CHE: Ҽ
+\def\cyrilliccheabkhasian {\char"004BD } % CYRILLIC SMALL LETTER ABKHASIAN CHE: ҽ
+\def\cyrillicCHEDCabkhasian {\char"004BE } % CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER: Ҿ
+\def\cyrillicchedcabkhasian {\char"004BF } % CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER: ҿ
+\def\cyrillicPALOCHKA {\char"004C0 } % CYRILLIC LETTER PALOCHKA: Ӏ
+\def\cyrillicZHEbreve {\char"004C1 } % CYRILLIC CAPITAL LETTER ZHE WITH BREVE: Ӂ
+\def\cyrilliczhebreve {\char"004C2 } % CYRILLIC SMALL LETTER ZHE WITH BREVE: ӂ
+\def\cyrillicKAhook {\char"004C3 } % CYRILLIC CAPITAL LETTER KA WITH HOOK: Ӄ
+\def\cyrillickahook {\char"004C4 } % CYRILLIC SMALL LETTER KA WITH HOOK: ӄ
+\def\cyrillicELtail {\char"004C5 } % CYRILLIC CAPITAL LETTER EL WITH TAIL: Ӆ
+\def\cyrilliceltail {\char"004C6 } % CYRILLIC SMALL LETTER EL WITH TAIL: ӆ
+\def\cyrillicENhook {\char"004C7 } % CYRILLIC CAPITAL LETTER EN WITH HOOK: Ӈ
+\def\cyrillicenhook {\char"004C8 } % CYRILLIC SMALL LETTER EN WITH HOOK: ӈ
+\def\cyrillicENtail {\char"004C9 } % CYRILLIC CAPITAL LETTER EN WITH TAIL: Ӊ
+\def\cyrillicentail {\char"004CA } % CYRILLIC SMALL LETTER EN WITH TAIL: ӊ
+\def\cyrillicCHEkhakassian {\char"004CB } % CYRILLIC CAPITAL LETTER KHAKASSIAN CHE: Ӌ
+\def\cyrillicchekhakassian {\char"004CC } % CYRILLIC SMALL LETTER KHAKASSIAN CHE: ӌ
+\def\cyrillicEMtail {\char"004CD } % CYRILLIC CAPITAL LETTER EM WITH TAIL: Ӎ
+\def\cyrillicemtail {\char"004CE } % CYRILLIC SMALL LETTER EM WITH TAIL: ӎ
+\def\cyrillicAbreve {\char"004D0 } % CYRILLIC CAPITAL LETTER A WITH BREVE: Ӑ
+\def\cyrillicabreve {\char"004D1 } % CYRILLIC SMALL LETTER A WITH BREVE: ӑ
+\def\cyrillicAdiaeresis {\char"004D2 } % CYRILLIC CAPITAL LETTER A WITH DIAERESIS: Ӓ
+\def\cyrillicadiaeresis {\char"004D3 } % CYRILLIC SMALL LETTER A WITH DIAERESIS: ӓ
+\def\cyrillicAE {\char"004D4 } % CYRILLIC CAPITAL LIGATURE A IE: Ӕ
+\def\cyrillicae {\char"004D5 } % CYRILLIC SMALL LIGATURE A IE: ӕ
+\def\cyrillicEbreve {\char"004D6 } % CYRILLIC CAPITAL LETTER IE WITH BREVE: Ӗ
+\def\cyrillicebreve {\char"004D7 } % CYRILLIC SMALL LETTER IE WITH BREVE: ӗ
+\def\cyrillicSCHWA {\char"004D8 } % CYRILLIC CAPITAL LETTER SCHWA: Ә
+\def\cyrillicschwa {\char"004D9 } % CYRILLIC SMALL LETTER SCHWA: ә
+\def\cyrillicSCHWAdiaeresis {\char"004DA } % CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS: Ӛ
+\def\cyrillicschwadiaeresis {\char"004DB } % CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS: ӛ
+\def\cyrillicZHEdiaeresis {\char"004DC } % CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS: Ӝ
+\def\cyrilliczhediaeresis {\char"004DD } % CYRILLIC SMALL LETTER ZHE WITH DIAERESIS: ӝ
+\def\cyrillicZEdiaeresis {\char"004DE } % CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS: Ӟ
+\def\cyrilliczediaeresis {\char"004DF } % CYRILLIC SMALL LETTER ZE WITH DIAERESIS: ӟ
+\def\cyrillicDZEabkhasian {\char"004E0 } % CYRILLIC CAPITAL LETTER ABKHASIAN DZE: Ӡ
+\def\cyrillicdzeabkhasian {\char"004E1 } % CYRILLIC SMALL LETTER ABKHASIAN DZE: ӡ
+\def\cyrillicImacron {\char"004E2 } % CYRILLIC CAPITAL LETTER I WITH MACRON: Ӣ
+\def\cyrillicimacron {\char"004E3 } % CYRILLIC SMALL LETTER I WITH MACRON: ӣ
+\def\cyrillicIdiaeresis {\char"004E4 } % CYRILLIC CAPITAL LETTER I WITH DIAERESIS: Ӥ
+\def\cyrillicidiaeresis {\char"004E5 } % CYRILLIC SMALL LETTER I WITH DIAERESIS: ӥ
+\def\cyrillicOdiaeresis {\char"004E6 } % CYRILLIC CAPITAL LETTER O WITH DIAERESIS: Ӧ
+\def\cyrillicodiaeresis {\char"004E7 } % CYRILLIC SMALL LETTER O WITH DIAERESIS: ӧ
+\def\cyrillicObarred {\char"004E8 } % CYRILLIC CAPITAL LETTER BARRED O: Ө
+\def\cyrillicobarred {\char"004E9 } % CYRILLIC SMALL LETTER BARRED O: ө
+\def\cyrillicObarreddiaeresis {\char"004EA } % CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS: Ӫ
+\def\cyrillicobarreddiaeresis {\char"004EB } % CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS: ӫ
+\def\cyrillicEdiaeresis {\char"004EC } % CYRILLIC CAPITAL LETTER E WITH DIAERESIS: Ӭ
+\def\cyrillicediaeresis {\char"004ED } % CYRILLIC SMALL LETTER E WITH DIAERESIS: ӭ
+\def\cyrillicUmacron {\char"004EE } % CYRILLIC CAPITAL LETTER U WITH MACRON: Ӯ
+\def\cyrillicumacron {\char"004EF } % CYRILLIC SMALL LETTER U WITH MACRON: ӯ
+\def\cyrillicUdiaeresis {\char"004F0 } % CYRILLIC CAPITAL LETTER U WITH DIAERESIS: Ӱ
+\def\cyrillicudiaeresis {\char"004F1 } % CYRILLIC SMALL LETTER U WITH DIAERESIS: ӱ
+\def\cyrillicUdoubleacute {\char"004F2 } % CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE: Ӳ
+\def\cyrillicudoubleacute {\char"004F3 } % CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE: ӳ
+\def\cyrillicCHEdiaeresis {\char"004F4 } % CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS: Ӵ
+\def\cyrillicchediaeresis {\char"004F5 } % CYRILLIC SMALL LETTER CHE WITH DIAERESIS: ӵ
+\def\cyrillicYERUdiaeresis {\char"004F8 } % CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS: Ӹ
+\def\cyrillicyerudiaeresis {\char"004F9 } % CYRILLIC SMALL LETTER YERU WITH DIAERESIS: ӹ
+\def\hebrewAlef {\char"005D0 } % HEBREW LETTER ALEF: א
+\def\hebrewBet {\char"005D1 } % HEBREW LETTER BET: ב
+\def\hebrewGimel {\char"005D2 } % HEBREW LETTER GIMEL: ג
+\def\hebrewDalet {\char"005D3 } % HEBREW LETTER DALET: ד
+\def\hebrewHe {\char"005D4 } % HEBREW LETTER HE: ה
+\def\hebrewVav {\char"005D5 } % HEBREW LETTER VAV: ו
+\def\hebrewZayin {\char"005D6 } % HEBREW LETTER ZAYIN: ז
+\def\hebrewHet {\char"005D7 } % HEBREW LETTER HET: ח
+\def\hebrewTet {\char"005D8 } % HEBREW LETTER TET: ט
+\def\hebrewYod {\char"005D9 } % HEBREW LETTER YOD: י
+\def\hebrewKaffinal {\char"005DA } % HEBREW LETTER FINAL KAF: ך
+\def\hebrewKaf {\char"005DB } % HEBREW LETTER KAF: כ
+\def\hebrewLamed {\char"005DC } % HEBREW LETTER LAMED: ל
+\def\hebrewMemfinal {\char"005DD } % HEBREW LETTER FINAL MEM: ם
+\def\hebrewMem {\char"005DE } % HEBREW LETTER MEM: מ
+\def\hebrewNunfinal {\char"005DF } % HEBREW LETTER FINAL NUN: ן
+\def\hebrewNun {\char"005E0 } % HEBREW LETTER NUN: נ
+\def\hebrewSamekh {\char"005E1 } % HEBREW LETTER SAMEKH: ס
+\def\hebrewAyin {\char"005E2 } % HEBREW LETTER AYIN: ע
+\def\hebrewPefinal {\char"005E3 } % HEBREW LETTER FINAL PE: ף
+\def\hebrewPe {\char"005E4 } % HEBREW LETTER PE: פ
+\def\hebrewTsadifinal {\char"005E5 } % HEBREW LETTER FINAL TSADI: ץ
+\def\hebrewTsadi {\char"005E6 } % HEBREW LETTER TSADI: צ
+\def\hebrewQof {\char"005E7 } % HEBREW LETTER QOF: ק
+\def\hebrewResh {\char"005E8 } % HEBREW LETTER RESH: ר
+\def\hebrewShin {\char"005E9 } % HEBREW LETTER SHIN: ש
+\def\hebrewTav {\char"005EA } % HEBREW LETTER TAV: ת
+\def\Adotbelow {\char"01EA0 } % LATIN CAPITAL LETTER A WITH DOT BELOW: Ạ
+\def\adotbelow {\char"01EA1 } % LATIN SMALL LETTER A WITH DOT BELOW: ạ
+\def\Ahook {\char"01EA2 } % LATIN CAPITAL LETTER A WITH HOOK ABOVE: Ả
+\def\ahook {\char"01EA3 } % LATIN SMALL LETTER A WITH HOOK ABOVE: ả
+\def\Acircumflexacute {\char"01EA4 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE: Ấ
+\def\acircumflexacute {\char"01EA5 } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE: ấ
+\def\Acircumflexgrave {\char"01EA6 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE: Ầ
+\def\acircumflexgrave {\char"01EA7 } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE: ầ
+\def\Acircumflexhook {\char"01EA8 } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE: Ẩ
+\def\acircumflexhook {\char"01EA9 } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE: ẩ
+\def\Acircumflextilde {\char"01EAA } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE: Ẫ
+\def\acircumflextilde {\char"01EAB } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE: ẫ
+\def\Acircumflexdotbelow {\char"01EAC } % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW: Ậ
+\def\acircumflexdotbelow {\char"01EAD } % LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW: ậ
+\def\Abreveacute {\char"01EAE } % LATIN CAPITAL LETTER A WITH BREVE AND ACUTE: Ắ
+\def\abreveacute {\char"01EAF } % LATIN SMALL LETTER A WITH BREVE AND ACUTE: ắ
+\def\Abrevegrave {\char"01EB0 } % LATIN CAPITAL LETTER A WITH BREVE AND GRAVE: Ằ
+\def\abrevegrave {\char"01EB1 } % LATIN SMALL LETTER A WITH BREVE AND GRAVE: ằ
+\def\Abrevehook {\char"01EB2 } % LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE: Ẳ
+\def\abrevehook {\char"01EB3 } % LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE: ẳ
+\def\Abrevetilde {\char"01EB4 } % LATIN CAPITAL LETTER A WITH BREVE AND TILDE: Ẵ
+\def\abrevetilde {\char"01EB5 } % LATIN SMALL LETTER A WITH BREVE AND TILDE: ẵ
+\def\Abrevedotbelow {\char"01EB6 } % LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW: Ặ
+\def\abrevedotbelow {\char"01EB7 } % LATIN SMALL LETTER A WITH BREVE AND DOT BELOW: ặ
+\def\Edotbelow {\char"01EB8 } % LATIN CAPITAL LETTER E WITH DOT BELOW: Ẹ
+\def\edotbelow {\char"01EB9 } % LATIN SMALL LETTER E WITH DOT BELOW: ẹ
+\def\Ehook {\char"01EBA } % LATIN CAPITAL LETTER E WITH HOOK ABOVE: Ẻ
+\def\ehook {\char"01EBB } % LATIN SMALL LETTER E WITH HOOK ABOVE: ẻ
+\def\Etilde {\char"01EBC } % LATIN CAPITAL LETTER E WITH TILDE: Ẽ
+\def\etilde {\char"01EBD } % LATIN SMALL LETTER E WITH TILDE: ẽ
+\def\Ecircumflexacute {\char"01EBE } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE: Ế
+\def\ecircumflexacute {\char"01EBF } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE: ế
+\def\Ecircumflexgrave {\char"01EC0 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE: Ề
+\def\ecircumflexgrave {\char"01EC1 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE: ề
+\def\Ecircumflexhook {\char"01EC2 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE: Ể
+\def\ecircumflexhook {\char"01EC3 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE: ể
+\def\Ecircumflextilde {\char"01EC4 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE: Ễ
+\def\ecircumflextilde {\char"01EC5 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE: ễ
+\def\Ecircumflexdotbelow {\char"01EC6 } % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW: Ệ
+\def\ecircumflexdotbelow {\char"01EC7 } % LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW: ệ
+\def\Ihook {\char"01EC8 } % LATIN CAPITAL LETTER I WITH HOOK ABOVE: Ỉ
+\def\ihook {\char"01EC9 } % LATIN SMALL LETTER I WITH HOOK ABOVE: ỉ
+\def\Idotbelow {\char"01ECA } % LATIN CAPITAL LETTER I WITH DOT BELOW: Ị
+\def\idotbelow {\char"01ECB } % LATIN SMALL LETTER I WITH DOT BELOW: ị
+\def\Odotbelow {\char"01ECC } % LATIN CAPITAL LETTER O WITH DOT BELOW: Ọ
+\def\odotbelow {\char"01ECD } % LATIN SMALL LETTER O WITH DOT BELOW: ọ
+\def\Ohook {\char"01ECE } % LATIN CAPITAL LETTER O WITH HOOK ABOVE: Ỏ
+\def\ohook {\char"01ECF } % LATIN SMALL LETTER O WITH HOOK ABOVE: ỏ
+\def\Ocircumflexacute {\char"01ED0 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE: Ố
+\def\ocircumflexacute {\char"01ED1 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE: ố
+\def\Ocircumflexgrave {\char"01ED2 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE: Ồ
+\def\ocircumflexgrave {\char"01ED3 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE: ồ
+\def\Ocircumflexhook {\char"01ED4 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE: Ổ
+\def\ocircumflexhook {\char"01ED5 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE: ổ
+\def\Ocircumflextilde {\char"01ED6 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE: Ỗ
+\def\ocircumflextilde {\char"01ED7 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE: ỗ
+\def\Ocircumflexdotbelow {\char"01ED8 } % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW: Ộ
+\def\ocircumflexdotbelow {\char"01ED9 } % LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW: ộ
+\def\Ohornacute {\char"01EDA } % LATIN CAPITAL LETTER O WITH HORN AND ACUTE: Ớ
+\def\ohornacute {\char"01EDB } % LATIN SMALL LETTER O WITH HORN AND ACUTE: ớ
+\def\Ohorngrave {\char"01EDC } % LATIN CAPITAL LETTER O WITH HORN AND GRAVE: Ờ
+\def\ohorngrave {\char"01EDD } % LATIN SMALL LETTER O WITH HORN AND GRAVE: ờ
+\def\Ohornhook {\char"01EDE } % LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE: Ở
+\def\ohornhook {\char"01EDF } % LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE: ở
+\def\Ohorntilde {\char"01EE0 } % LATIN CAPITAL LETTER O WITH HORN AND TILDE: Ỡ
+\def\ohorntilde {\char"01EE1 } % LATIN SMALL LETTER O WITH HORN AND TILDE: ỡ
+\def\Ohorndotbelow {\char"01EE2 } % LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW: Ợ
+\def\ohorndotbelow {\char"01EE3 } % LATIN SMALL LETTER O WITH HORN AND DOT BELOW: ợ
+\def\Udotbelow {\char"01EE4 } % LATIN CAPITAL LETTER U WITH DOT BELOW: Ụ
+\def\udotbelow {\char"01EE5 } % LATIN SMALL LETTER U WITH DOT BELOW: ụ
+\def\Uhook {\char"01EE6 } % LATIN CAPITAL LETTER U WITH HOOK ABOVE: Ủ
+\def\uhook {\char"01EE7 } % LATIN SMALL LETTER U WITH HOOK ABOVE: ủ
+\def\Uhornacute {\char"01EE8 } % LATIN CAPITAL LETTER U WITH HORN AND ACUTE: Ứ
+\def\uhornacute {\char"01EE9 } % LATIN SMALL LETTER U WITH HORN AND ACUTE: ứ
+\def\Uhorngrave {\char"01EEA } % LATIN CAPITAL LETTER U WITH HORN AND GRAVE: Ừ
+\def\uhorngrave {\char"01EEB } % LATIN SMALL LETTER U WITH HORN AND GRAVE: ừ
+\def\Uhornhook {\char"01EEC } % LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE: Ử
+\def\uhornhook {\char"01EED } % LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE: ử
+\def\Uhorntilde {\char"01EEE } % LATIN CAPITAL LETTER U WITH HORN AND TILDE: Ữ
+\def\uhorntilde {\char"01EEF } % LATIN SMALL LETTER U WITH HORN AND TILDE: ữ
+\def\Uhorndotbelow {\char"01EF0 } % LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW: Ự
+\def\uhorndotbelow {\char"01EF1 } % LATIN SMALL LETTER U WITH HORN AND DOT BELOW: ự
+\def\Ygrave {\char"01EF2 } % LATIN CAPITAL LETTER Y WITH GRAVE: Ỳ
+\def\ygrave {\char"01EF3 } % LATIN SMALL LETTER Y WITH GRAVE: ỳ
+\def\Ydotbelow {\char"01EF4 } % LATIN CAPITAL LETTER Y WITH DOT BELOW: Ỵ
+\def\ydotbelow {\char"01EF5 } % LATIN SMALL LETTER Y WITH DOT BELOW: ỵ
+\def\Yhook {\char"01EF6 } % LATIN CAPITAL LETTER Y WITH HOOK ABOVE: Ỷ
+\def\yhook {\char"01EF7 } % LATIN SMALL LETTER Y WITH HOOK ABOVE: ỷ
+\def\Ytilde {\char"01EF8 } % LATIN CAPITAL LETTER Y WITH TILDE: Ỹ
+\def\ytilde {\char"01EF9 } % LATIN SMALL LETTER Y WITH TILDE: ỹ
+\def\greekalphapsili {\char"01F00 } % GREEK SMALL LETTER ALPHA WITH PSILI: ἀ
+\def\greekalphadasia {\char"01F01 } % GREEK SMALL LETTER ALPHA WITH DASIA: ἁ
+\def\greekalphapsilivaria {\char"01F02 } % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA: ἂ
+\def\greekalphadasiavaria {\char"01F03 } % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA: ἃ
+\def\greekalphapsilitonos {\char"01F04 } % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA: ἄ
+\def\greekalphadasiatonos {\char"01F05 } % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA: ἅ
+\def\greekalphapsiliperispomeni {\char"01F06 } % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI: ἆ
+\def\greekalphadasiaperispomeni {\char"01F07 } % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI: ἇ
+\def\greekAlphapsili {\char"01F08 } % GREEK CAPITAL LETTER ALPHA WITH PSILI: Ἀ
+\def\greekAlphadasia {\char"01F09 } % GREEK CAPITAL LETTER ALPHA WITH DASIA: Ἁ
+\def\greekAlphapsilivaria {\char"01F0A } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA: Ἂ
+\def\greekAlphadasiavaria {\char"01F0B } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA: Ἃ
+\def\greekAlphapsilitonos {\char"01F0C } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA: Ἄ
+\def\greekAlphadasiatonos {\char"01F0D } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA: Ἅ
+\def\greekAlphapsiliperispomeni {\char"01F0E } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI: Ἆ
+\def\greekAlphadasiaperispomeni {\char"01F0F } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI: Ἇ
+\def\greekepsilonpsili {\char"01F10 } % GREEK SMALL LETTER EPSILON WITH PSILI: ἐ
+\def\greekepsilondasia {\char"01F11 } % GREEK SMALL LETTER EPSILON WITH DASIA: ἑ
+\def\greekepsilonpsilivaria {\char"01F12 } % GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA: ἒ
+\def\greekepsilondasiavaria {\char"01F13 } % GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA: ἓ
+\def\greekepsilonpsilitonos {\char"01F14 } % GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA: ἔ
+\def\greekepsilondasiatonos {\char"01F15 } % GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA: ἕ
+\def\greekEpsilonpsili {\char"01F18 } % GREEK CAPITAL LETTER EPSILON WITH PSILI: Ἐ
+\def\greekEpsilondasia {\char"01F19 } % GREEK CAPITAL LETTER EPSILON WITH DASIA: Ἑ
+\def\greekEpsilonpsilivaria {\char"01F1A } % GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA: Ἒ
+\def\greekEpsilondasiavaria {\char"01F1B } % GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA: Ἓ
+\def\greekEpsilonpsilitonos {\char"01F1C } % GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA: Ἔ
+\def\greekEpsilondasiatonos {\char"01F1D } % GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA: Ἕ
+\def\greeketapsili {\char"01F20 } % GREEK SMALL LETTER ETA WITH PSILI: ἠ
+\def\greeketadasia {\char"01F21 } % GREEK SMALL LETTER ETA WITH DASIA: ἡ
+\def\greeketapsilivaria {\char"01F22 } % GREEK SMALL LETTER ETA WITH PSILI AND VARIA: ἢ
+\def\greeketadasiavaria {\char"01F23 } % GREEK SMALL LETTER ETA WITH DASIA AND VARIA: ἣ
+\def\greeketapsilitonos {\char"01F24 } % GREEK SMALL LETTER ETA WITH PSILI AND OXIA: ἤ
+\def\greeketadasiatonos {\char"01F25 } % GREEK SMALL LETTER ETA WITH DASIA AND OXIA: ἥ
+\def\greeketapsiliperispomeni {\char"01F26 } % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI: ἦ
+\def\greeketadasiaperispomeni {\char"01F27 } % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI: ἧ
+\def\greekEtapsili {\char"01F28 } % GREEK CAPITAL LETTER ETA WITH PSILI: Ἠ
+\def\greekEtadasia {\char"01F29 } % GREEK CAPITAL LETTER ETA WITH DASIA: Ἡ
+\def\greekEtapsilivaria {\char"01F2A } % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA: Ἢ
+\def\greekEtadasiavaria {\char"01F2B } % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA: Ἣ
+\def\greekEtapsilitonos {\char"01F2C } % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA: Ἤ
+\def\greekEtadasiatonos {\char"01F2D } % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA: Ἥ
+\def\greekEtapsiliperispomeni {\char"01F2E } % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI: Ἦ
+\def\greekEtadasiaperispomeni {\char"01F2F } % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI: Ἧ
+\def\greekiotapsili {\char"01F30 } % GREEK SMALL LETTER IOTA WITH PSILI: ἰ
+\def\greekiotadasia {\char"01F31 } % GREEK SMALL LETTER IOTA WITH DASIA: ἱ
+\def\greekiotapsilivaria {\char"01F32 } % GREEK SMALL LETTER IOTA WITH PSILI AND VARIA: ἲ
+\def\greekiotadasiavaria {\char"01F33 } % GREEK SMALL LETTER IOTA WITH DASIA AND VARIA: ἳ
+\def\greekiotapsilitonos {\char"01F34 } % GREEK SMALL LETTER IOTA WITH PSILI AND OXIA: ἴ
+\def\greekiotadasiatonos {\char"01F35 } % GREEK SMALL LETTER IOTA WITH DASIA AND OXIA: ἵ
+\def\greekiotapsiliperispomeni {\char"01F36 } % GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI: ἶ
+\def\greekiotadasiaperispomeni {\char"01F37 } % GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI: ἷ
+\def\greekIotapsili {\char"01F38 } % GREEK CAPITAL LETTER IOTA WITH PSILI: Ἰ
+\def\greekIotadasia {\char"01F39 } % GREEK CAPITAL LETTER IOTA WITH DASIA: Ἱ
+\def\greekIotapsilivaria {\char"01F3A } % GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA: Ἲ
+\def\greekIotadasiavaria {\char"01F3B } % GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA: Ἳ
+\def\greekIotapsilitonos {\char"01F3C } % GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA: Ἴ
+\def\greekIotadasiatonos {\char"01F3D } % GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA: Ἵ
+\def\greekIotapsiliperispomeni {\char"01F3E } % GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI: Ἶ
+\def\greekIotadasiaperispomeni {\char"01F3F } % GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI: Ἷ
+\def\greekomicronpsili {\char"01F40 } % GREEK SMALL LETTER OMICRON WITH PSILI: ὀ
+\def\greekomicrondasia {\char"01F41 } % GREEK SMALL LETTER OMICRON WITH DASIA: ὁ
+\def\greekomicronpsilivaria {\char"01F42 } % GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA: ὂ
+\def\greekomicrondasiavaria {\char"01F43 } % GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA: ὃ
+\def\greekomicronpsilitonos {\char"01F44 } % GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA: ὄ
+\def\greekomicrondasiatonos {\char"01F45 } % GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA: ὅ
+\def\greekOmicronpsili {\char"01F48 } % GREEK CAPITAL LETTER OMICRON WITH PSILI: Ὀ
+\def\greekOmicrondasia {\char"01F49 } % GREEK CAPITAL LETTER OMICRON WITH DASIA: Ὁ
+\def\greekOmicronpsilivaria {\char"01F4A } % GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA: Ὂ
+\def\greekOmicrondasiavaria {\char"01F4B } % GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA: Ὃ
+\def\greekOmicronpsilitonos {\char"01F4C } % GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA: Ὄ
+\def\greekOmicrondasiatonos {\char"01F4D } % GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA: Ὅ
+\def\greekupsilonpsili {\char"01F50 } % GREEK SMALL LETTER UPSILON WITH PSILI: ὐ
+\def\greekupsilondasia {\char"01F51 } % GREEK SMALL LETTER UPSILON WITH DASIA: ὑ
+\def\greekupsilonpsilivaria {\char"01F52 } % GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA: ὒ
+\def\greekupsilondasiavaria {\char"01F53 } % GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA: ὓ
+\def\greekupsilonpsilitonos {\char"01F54 } % GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA: ὔ
+\def\greekupsilondasiatonos {\char"01F55 } % GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA: ὕ
+\def\greekupsilonpsiliperispomeni {\char"01F56 } % GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI: ὖ
+\def\greekupsilondasiaperispomeni {\char"01F57 } % GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI: ὗ
+\def\greekUpsilondasia {\char"01F59 } % GREEK CAPITAL LETTER UPSILON WITH DASIA: Ὑ
+\def\greekUpsilondasiavaria {\char"01F5B } % GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA: Ὓ
+\def\greekUpsilondasiatonos {\char"01F5D } % GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA: Ὕ
+\def\greekUpsilondasiaperispomeni {\char"01F5F } % GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI: Ὗ
+\def\greekomegapsili {\char"01F60 } % GREEK SMALL LETTER OMEGA WITH PSILI: ὠ
+\def\greekomegadasia {\char"01F61 } % GREEK SMALL LETTER OMEGA WITH DASIA: ὡ
+\def\greekomegapsilivaria {\char"01F62 } % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA: ὢ
+\def\greekomegadasiavaria {\char"01F63 } % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA: ὣ
+\def\greekomegapsilitonos {\char"01F64 } % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA: ὤ
+\def\greekomegadasiatonos {\char"01F65 } % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA: ὥ
+\def\greekomegapsiliperispomeni {\char"01F66 } % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI: ὦ
+\def\greekomegadasiaperispomeni {\char"01F67 } % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI: ὧ
+\def\greekOmegapsili {\char"01F68 } % GREEK CAPITAL LETTER OMEGA WITH PSILI: Ὠ
+\def\greekOmegadasia {\char"01F69 } % GREEK CAPITAL LETTER OMEGA WITH DASIA: Ὡ
+\def\greekOmegapsilivaria {\char"01F6A } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA: Ὢ
+\def\greekOmegadasiavaria {\char"01F6B } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA: Ὣ
+\def\greekOmegapsilitonos {\char"01F6C } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA: Ὤ
+\def\greekOmegadasiatonos {\char"01F6D } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA: Ὥ
+\def\greekOmegapsiliperispomeni {\char"01F6E } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI: Ὦ
+\def\greekOmegadasiaperispomeni {\char"01F6F } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI: Ὧ
+\def\greekalphavaria {\char"01F70 } % GREEK SMALL LETTER ALPHA WITH VARIA: ὰ
+\def\greekalphaoxia {\char"01F71 } % GREEK SMALL LETTER ALPHA WITH OXIA: ά
+\def\greekepsilonvaria {\char"01F72 } % GREEK SMALL LETTER EPSILON WITH VARIA: ὲ
+\def\greekepsilonoxia {\char"01F73 } % GREEK SMALL LETTER EPSILON WITH OXIA: έ
+\def\greeketavaria {\char"01F74 } % GREEK SMALL LETTER ETA WITH VARIA: ὴ
+\def\greeketaoxia {\char"01F75 } % GREEK SMALL LETTER ETA WITH OXIA: ή
+\def\greekiotavaria {\char"01F76 } % GREEK SMALL LETTER IOTA WITH VARIA: ὶ
+\def\greekiotaoxia {\char"01F77 } % GREEK SMALL LETTER IOTA WITH OXIA: ί
+\def\greekomicronvaria {\char"01F78 } % GREEK SMALL LETTER OMICRON WITH VARIA: ὸ
+\def\greekomicronoxia {\char"01F79 } % GREEK SMALL LETTER OMICRON WITH OXIA: ό
+\def\greekupsilonvaria {\char"01F7A } % GREEK SMALL LETTER UPSILON WITH VARIA: ὺ
+\def\greekupsilonoxia {\char"01F7B } % GREEK SMALL LETTER UPSILON WITH OXIA: ύ
+\def\greekomegavaria {\char"01F7C } % GREEK SMALL LETTER OMEGA WITH VARIA: ὼ
+\def\greekomegaoxia {\char"01F7D } % GREEK SMALL LETTER OMEGA WITH OXIA: ώ
+\def\greekalphaiotasubpsili {\char"01F80 } % GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI: ᾀ
+\def\greekalphaiotasubdasia {\char"01F81 } % GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI: ᾁ
+\def\greekalphaiotasubpsilivaria {\char"01F82 } % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI: ᾂ
+\def\greekalphaiotasubdasiavaria {\char"01F83 } % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI: ᾃ
+\def\greekalphaiotasubpsilitonos {\char"01F84 } % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI: ᾄ
+\def\greekalphaiotasubdasiatonos {\char"01F85 } % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI: ᾅ
+\def\greekalphaiotasubpsiliperispomeni{\char"01F86 } % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI: ᾆ
+\def\greekalphaiotasubdasiaperispomeni{\char"01F87 } % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI: ᾇ
+\def\greekAlphaiotasubpsili {\char"01F88 } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI: ᾈ
+\def\greekAlphaiotasubdasia {\char"01F89 } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI: ᾉ
+\def\greekAlphaiotasubpsilivaria {\char"01F8A } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI: ᾊ
+\def\greekAlphaiotasubdasiavaria {\char"01F8B } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI: ᾋ
+\def\greekAlphaiotasubpsilitonos {\char"01F8C } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI: ᾌ
+\def\greekAlphaiotasubdasiatonos {\char"01F8D } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI: ᾍ
+\def\greekAlphaiotasubpsiliperispomeni{\char"01F8E } % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI: ᾎ
+\def\greekAlphaiotasubdasiaperispomeni{\char"01F8F } % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI: ᾏ
+\def\greeketaiotasubpsili {\char"01F90 } % GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI: ᾐ
+\def\greeketaiotasubdasia {\char"01F91 } % GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI: ᾑ
+\def\greeketaiotasubpsilivaria {\char"01F92 } % GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI: ᾒ
+\def\greeketaiotasubdasiavaria {\char"01F93 } % GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI: ᾓ
+\def\greeketaiotasubpsilitonos {\char"01F94 } % GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI: ᾔ
+\def\greeketaiotasubdasiatonos {\char"01F95 } % GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI: ᾕ
+\def\greeketaiotasubpsiliperispomeni {\char"01F96 } % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI: ᾖ
+\def\greeketaiotasubdasiaperispomeni {\char"01F97 } % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI: ᾗ
+\def\greekEtaiotasubpsili {\char"01F98 } % GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI: ᾘ
+\def\greekEtaiotasubdasia {\char"01F99 } % GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI: ᾙ
+\def\greekEtaiotasubpsilivaria {\char"01F9A } % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI: ᾚ
+\def\greekEtaiotasubdasiavaria {\char"01F9B } % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI: ᾛ
+\def\greekEtaiotasubpsilitonos {\char"01F9C } % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI: ᾜ
+\def\greekEtaiotasubdasiatonos {\char"01F9D } % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI: ᾝ
+\def\greekEtaiotasubpsiliperispomeni {\char"01F9E } % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI: ᾞ
+\def\greekEtaiotasubdasiaperispomeni {\char"01F9F } % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI: ᾟ
+\def\greekomegaiotasubpsili {\char"01FA0 } % GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI: ᾠ
+\def\greekomegaiotasubdasia {\char"01FA1 } % GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI: ᾡ
+\def\greekomegaiotasubpsilivaria {\char"01FA2 } % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI: ᾢ
+\def\greekomegaiotasubdasiavaria {\char"01FA3 } % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI: ᾣ
+\def\greekomegaiotasubpsilitonos {\char"01FA4 } % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI: ᾤ
+\def\greekomegaiotasubdasiatonos {\char"01FA5 } % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI: ᾥ
+\def\greekomegaiotasubpsiliperispomeni{\char"01FA6 } % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI: ᾦ
+\def\greekomegaiotasubdasiaperispomeni{\char"01FA7 } % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI: ᾧ
+\def\greekOmegaiotasubpsili {\char"01FA8 } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI: ᾨ
+\def\greekOmegaiotasubdasia {\char"01FA9 } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI: ᾩ
+\def\greekOmegaiotasubpsilivaria {\char"01FAA } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI: ᾪ
+\def\greekOmegaiotasubdasiavaria {\char"01FAB } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI: ᾫ
+\def\greekOmegaiotasubpsilitonos {\char"01FAC } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI: ᾬ
+\def\greekOmegaiotasubdasiatonos {\char"01FAD } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI: ᾭ
+\def\greekOmegaiotasubpsiliperispomeni{\char"01FAE } % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI: ᾮ
+\def\greekOmegaiotasubdasiaperispomeni{\char"01FAF } % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI: ᾯ
+\def\greekalphavrachy {\char"01FB0 } % GREEK SMALL LETTER ALPHA WITH VRACHY: ᾰ
+\def\greekalphamacron {\char"01FB1 } % GREEK SMALL LETTER ALPHA WITH MACRON: ᾱ
+\def\greekalphaiotasubvaria {\char"01FB2 } % GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI: ᾲ
+\def\greekalphaiotasub {\char"01FB3 } % GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI: ᾳ
+\def\greekalphaiotasubtonos {\char"01FB4 } % GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI: ᾴ
+\def\greekalphaperispomeni {\char"01FB6 } % GREEK SMALL LETTER ALPHA WITH PERISPOMENI: ᾶ
+\def\greekalphaiotasubperispomeni {\char"01FB7 } % GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI: ᾷ
+\def\greekAlphavrachy {\char"01FB8 } % GREEK CAPITAL LETTER ALPHA WITH VRACHY: Ᾰ
+\def\greekAlphamacron {\char"01FB9 } % GREEK CAPITAL LETTER ALPHA WITH MACRON: Ᾱ
+\def\greekAlphavaria {\char"01FBA } % GREEK CAPITAL LETTER ALPHA WITH VARIA: Ὰ
+\def\greekAlphatonos {\char"01FBB } % GREEK CAPITAL LETTER ALPHA WITH OXIA: Ά
+\def\greekAlphaiotasub {\char"01FBC } % GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI: ᾼ
+\def\greekCoronis {\char"01FBD } % GREEK KORONIS: ᾽
+\def\greekprosgegrammeni {\char"01FBE } % GREEK PROSGEGRAMMENI: ι
+\def\greekpsili {\char"01FBF } % GREEK PSILI: ᾿
+\def\greekperispomeni {\char"01FC0 } % GREEK PERISPOMENI: ῀
+\def\greekdialytikaperispomeni {\char"01FC1 } % GREEK DIALYTIKA AND PERISPOMENI: ῁
+\def\greeketaiotasubvaria {\char"01FC2 } % GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI: ῂ
+\def\greeketaiotasub {\char"01FC3 } % GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI: ῃ
+\def\greeketaiotasubtonos {\char"01FC4 } % GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI: ῄ
+\def\greeketaperispomeni {\char"01FC6 } % GREEK SMALL LETTER ETA WITH PERISPOMENI: ῆ
+\def\greeketaiotasubperispomeni {\char"01FC7 } % GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI: ῇ
+\def\greekEpsilonvaria {\char"01FC8 } % GREEK CAPITAL LETTER EPSILON WITH VARIA: Ὲ
+\def\greekEpsilontonos {\char"01FC9 } % GREEK CAPITAL LETTER EPSILON WITH OXIA: Έ
+\def\greekEtavaria {\char"01FCA } % GREEK CAPITAL LETTER ETA WITH VARIA: Ὴ
+\def\greekEtatonos {\char"01FCB } % GREEK CAPITAL LETTER ETA WITH OXIA: Ή
+\def\greekEtaiotasub {\char"01FCC } % GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI: ῌ
+\def\greekpsilivaria {\char"01FCD } % GREEK PSILI AND VARIA: ῍
+\def\greekpsilitonos {\char"01FCE } % GREEK PSILI AND OXIA: ῎
+\def\greekpsiliperispomeni {\char"01FCF } % GREEK PSILI AND PERISPOMENI: ῏
+\def\greekiotavrachy {\char"01FD0 } % GREEK SMALL LETTER IOTA WITH VRACHY: ῐ
+\def\greekiotamacron {\char"01FD1 } % GREEK SMALL LETTER IOTA WITH MACRON: ῑ
+\def\greekiotadialytikavaria {\char"01FD2 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA: ῒ
+\def\greekiotadialytikatonos {\char"01FD3 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA: ΐ
+\def\greekiotaperispomeni {\char"01FD6 } % GREEK SMALL LETTER IOTA WITH PERISPOMENI: ῖ
+\def\greekiotadialytikaperispomeni {\char"01FD7 } % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI: ῗ
+\def\greekIotavrachy {\char"01FD8 } % GREEK CAPITAL LETTER IOTA WITH VRACHY: Ῐ
+\def\greekIotamacron {\char"01FD9 } % GREEK CAPITAL LETTER IOTA WITH MACRON: Ῑ
+\def\greekIotavaria {\char"01FDA } % GREEK CAPITAL LETTER IOTA WITH VARIA: Ὶ
+\def\greekIotatonos {\char"01FDB } % GREEK CAPITAL LETTER IOTA WITH OXIA: Ί
+\def\greekdasiavaria {\char"01FDD } % GREEK DASIA AND VARIA: ῝
+\def\greekdasiatonos {\char"01FDE } % GREEK DASIA AND OXIA: ῞
+\def\greekdasiaperispomeni {\char"01FDF } % GREEK DASIA AND PERISPOMENI: ῟
+\def\greekupsilonvrachy {\char"01FE0 } % GREEK SMALL LETTER UPSILON WITH VRACHY: ῠ
+\def\greekupsilonmacron {\char"01FE1 } % GREEK SMALL LETTER UPSILON WITH MACRON: ῡ
+\def\greekupsilondialytikavaria {\char"01FE2 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA: ῢ
+\def\greekupsilondialytikatonos {\char"01FE3 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA: ΰ
+\def\greekrhopsili {\char"01FE4 } % GREEK SMALL LETTER RHO WITH PSILI: ῤ
+\def\greekrhodasia {\char"01FE5 } % GREEK SMALL LETTER RHO WITH DASIA: ῥ
+\def\greekupsilonperispomeni {\char"01FE6 } % GREEK SMALL LETTER UPSILON WITH PERISPOMENI: ῦ
+\def\greekupsilondialytikaperispomeni {\char"01FE7 } % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI: ῧ
+\def\greekUpsilonvrachy {\char"01FE8 } % GREEK CAPITAL LETTER UPSILON WITH VRACHY: Ῠ
+\def\greekUpsilonmacron {\char"01FE9 } % GREEK CAPITAL LETTER UPSILON WITH MACRON: Ῡ
+\def\greekUpsilonvaria {\char"01FEA } % GREEK CAPITAL LETTER UPSILON WITH VARIA: Ὺ
+\def\greekUpsilontonos {\char"01FEB } % GREEK CAPITAL LETTER UPSILON WITH OXIA: Ύ
+\def\greekRhodasia {\char"01FEC } % GREEK CAPITAL LETTER RHO WITH DASIA: Ῥ
+\def\greekdialytikavaria {\char"01FED } % GREEK DIALYTIKA AND VARIA: ῭
+\def\greekdialytikatonos {\char"01FEE } % GREEK DIALYTIKA AND OXIA: ΅
+\def\greekvaria {\char"01FEF } % GREEK VARIA: `
+\def\greekomegaiotasubvaria {\char"01FF2 } % GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI: ῲ
+\def\greekomegaiotasub {\char"01FF3 } % GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI: ῳ
+\def\greekomegaiotasubtonos {\char"01FF4 } % GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI: ῴ
+\def\greekomegaperispomeni {\char"01FF6 } % GREEK SMALL LETTER OMEGA WITH PERISPOMENI: ῶ
+\def\greekomegaiotasubperispomeni {\char"01FF7 } % GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI: ῷ
+\def\greekOmicronvaria {\char"01FF8 } % GREEK CAPITAL LETTER OMICRON WITH VARIA: Ὸ
+\def\greekOmicrontonos {\char"01FF9 } % GREEK CAPITAL LETTER OMICRON WITH OXIA: Ό
+\def\greekOmegavaria {\char"01FFA } % GREEK CAPITAL LETTER OMEGA WITH VARIA: Ὼ
+\def\greekOmegatonos {\char"01FFB } % GREEK CAPITAL LETTER OMEGA WITH OXIA: Ώ
+\def\greekOmegaiotasub {\char"01FFC } % GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI: ῼ
+\def\greekoxia {\char"01FFD } % GREEK OXIA: ´
+\def\greekdasia {\char"01FFE } % GREEK DASIA: ῾
+\def\enspace {\char"02002 } % EN SPACE:  
+\def\emspace {\char"02003 } % EM SPACE:  
+\def\threeperemspace {\char"02004 } % THREE-PER-EM SPACE:  
+\def\fourperemspace {\char"02005 } % FOUR-PER-EM SPACE:  
+\def\sixperemspace {\char"02006 } % SIX-PER-EM SPACE:  
+\def\figurespace {\char"02007 } % FIGURE SPACE:  
+\def\punctuationspace {\char"02008 } % PUNCTUATION SPACE:  
+\def\thinspace {\char"02009 } % THIN SPACE:  
+\def\figurespace {\char"0200A } % HAIR SPACE:  
+\def\zerowidthspace {\char"0200B } % ZERO WIDTH SPACE: ​
+\def\textminus {\char"02012 } % FIGURE DASH: ‒
+\def\endash {\char"02013 } % EN DASH: –
+\def\emdash {\char"02014 } % EM DASH: —
+\def\texthorizontalbar {\char"02015 } % HORIZONTAL BAR: ―
+\def\quoteleft {\char"02018 } % LEFT SINGLE QUOTATION MARK: ‘
+\def\quoteright {\char"02019 } % RIGHT SINGLE QUOTATION MARK: ’
+\def\quotesinglebase {\char"0201A } % SINGLE LOW-0x0009 QUOTATION MARK: ‚
+\def\quotedblleft {\char"0201C } % LEFT DOUBLE QUOTATION MARK: “
+\def\quotedblright {\char"0201D } % RIGHT DOUBLE QUOTATION MARK: ”
+\def\quotedblbase {\char"0201E } % DOUBLE LOW-0x0009 QUOTATION MARK: „
+\def\textdag {\char"02020 } % DAGGER: †
+\def\textddag {\char"02021 } % DOUBLE DAGGER: ‡
+\def\textbullet {\char"02022 } % BULLET: •
+\def\textellipsis {\char"02026 } % HORIZONTAL ELLIPSIS: …
+\def\narrownobreakspace {\char"0202F } % NARROW NO-BREAK SPACE:  
+\def\perthousand {\char"02030 } % PER MILLE SIGN: ‰
+\def\guilsingleleft {\char"02039 } % SINGLE LEFT-POINTING ANGLE QUOTATION MARK: ‹
+\def\guilsingleright {\char"0203A } % SINGLE RIGHT-POINTING ANGLE QUOTATION MARK: ›
+\def\textfraction {\char"02044 } % FRACTION SLASH: ⁄
+\def\medspace {\char"0205F } % MEDIUM MATHEMATICAL SPACE:  
+\def\textdong {\char"020AB } % DONG SIGN: ₫
+\def\texteuro {\char"020AC } % EURO SIGN: €
+\def\textcelsius {\char"02103 } % DEGREE CELSIUS: ℃
+\def\textnumero {\char"02116 } % NUMERO SIGN: №
+\def\textcircledP {\char"02117 } % SOUND RECORDING COPYRIGHT: ℗
+\def\trademark {\char"02122 } % TRADE MARK SIGN: ™
+\def\textounce {\char"02125 } % OUNCE SIGN: ℥
+\def\textohm {\char"02126 } % OHM SIGN: Ω
+\def\textmho {\char"02127 } % INVERTED OHM SIGN: ℧
+\def\textkelvin {\char"0212A } % KELVIN SIGN: K
+\def\textAngstrom {\char"0212B } % ANGSTROM SIGN: Å
+\def\onethird {\char"02153 } % VULGAR FRACTION ONE THIRD: ⅓
+\def\twothirds {\char"02154 } % VULGAR FRACTION TWO THIRDS: ⅔
+\def\onefifth {\char"02155 } % VULGAR FRACTION ONE FIFTH: ⅕
+\def\twofifths {\char"02156 } % VULGAR FRACTION TWO FIFTHS: ⅖
+\def\threefifths {\char"02157 } % VULGAR FRACTION THREE FIFTHS: ⅗
+\def\fourfifths {\char"02158 } % VULGAR FRACTION FOUR FIFTHS: ⅘
+\def\onesixth {\char"02159 } % VULGAR FRACTION ONE SIXTH: ⅙
+\def\fivesixths {\char"0215A } % VULGAR FRACTION FIVE SIXTHS: ⅚
+\def\oneeighth {\char"0215B } % VULGAR FRACTION ONE EIGHTH: ⅛
+\def\threeeighths {\char"0215C } % VULGAR FRACTION THREE EIGHTHS: ⅜
+\def\fiveeighths {\char"0215D } % VULGAR FRACTION FIVE EIGHTHS: ⅝
+\def\seveneighths {\char"0215E } % VULGAR FRACTION SEVEN EIGHTHS: ⅞
+\def\romanI {\char"02160 } % ROMAN NUMERAL ONE: Ⅰ
+\def\romanII {\char"02161 } % ROMAN NUMERAL TWO: Ⅱ
+\def\romanIII {\char"02162 } % ROMAN NUMERAL THREE: Ⅲ
+\def\romanIV {\char"02163 } % ROMAN NUMERAL FOUR: Ⅳ
+\def\romanV {\char"02164 } % ROMAN NUMERAL FIVE: Ⅴ
+\def\romanVI {\char"02165 } % ROMAN NUMERAL SIX: Ⅵ
+\def\romanVII {\char"02166 } % ROMAN NUMERAL SEVEN: Ⅶ
+\def\romanVIII {\char"02167 } % ROMAN NUMERAL EIGHT: Ⅷ
+\def\romanIX {\char"02168 } % ROMAN NUMERAL NINE: Ⅸ
+\def\romanX {\char"02169 } % ROMAN NUMERAL TEN: Ⅹ
+\def\romanXI {\char"0216A } % ROMAN NUMERAL ELEVEN: Ⅺ
+\def\romanXII {\char"0216B } % ROMAN NUMERAL TWELVE: Ⅻ
+\def\romanL {\char"0216C } % ROMAN NUMERAL FIFTY: Ⅼ
+\def\romanC {\char"0216D } % ROMAN NUMERAL ONE HUNDRED: Ⅽ
+\def\romanD {\char"0216E } % ROMAN NUMERAL FIVE HUNDRED: Ⅾ
+\def\romanM {\char"0216F } % ROMAN NUMERAL ONE THOUSAND: Ⅿ
+\def\romani {\char"02170 } % SMALL ROMAN NUMERAL ONE: ⅰ
+\def\romanii {\char"02171 } % SMALL ROMAN NUMERAL TWO: ⅱ
+\def\romaniii {\char"02172 } % SMALL ROMAN NUMERAL THREE: ⅲ
+\def\romaniv {\char"02173 } % SMALL ROMAN NUMERAL FOUR: ⅳ
+\def\romanv {\char"02174 } % SMALL ROMAN NUMERAL FIVE: ⅴ
+\def\romanvi {\char"02175 } % SMALL ROMAN NUMERAL SIX: ⅵ
+\def\romanvii {\char"02176 } % SMALL ROMAN NUMERAL SEVEN: ⅶ
+\def\romanviii {\char"02177 } % SMALL ROMAN NUMERAL EIGHT: ⅷ
+\def\romanix {\char"02178 } % SMALL ROMAN NUMERAL NINE: ⅸ
+\def\romanx {\char"02179 } % SMALL ROMAN NUMERAL TEN: ⅹ
+\def\romanxi {\char"0217A } % SMALL ROMAN NUMERAL ELEVEN: ⅺ
+\def\romanxii {\char"0217B } % SMALL ROMAN NUMERAL TWELVE: ⅻ
+\def\romanl {\char"0217C } % SMALL ROMAN NUMERAL FIFTY: ⅼ
+\def\romanc {\char"0217D } % SMALL ROMAN NUMERAL ONE HUNDRED: ⅽ
+\def\romand {\char"0217E } % SMALL ROMAN NUMERAL FIVE HUNDRED: ⅾ
+\def\romanm {\char"0217F } % SMALL ROMAN NUMERAL ONE THOUSAND: ⅿ
+\def\carriagereturn {\char"021B5 } % DOWNWARDS ARROW WITH CORNER LEFTWARDS: ↵
+\def\ideographicspace {\char"03000 } % IDEOGRAPHIC SPACE:  
+\def\ideographichalffillspace {\char"0303F } % IDEOGRAPHIC HALF FILL SPACE: 〿
+\def\ffligature {\char"0FB00 } % LATIN SMALL LIGATURE FF: ff
+\def\filigature {\char"0FB01 } % LATIN SMALL LIGATURE FI: fi
+\def\flligature {\char"0FB02 } % LATIN SMALL LIGATURE FL: fl
+\def\ffiligature {\char"0FB03 } % LATIN SMALL LIGATURE FFI: ffi
+\def\fflligature {\char"0FB04 } % LATIN SMALL LIGATURE FFL: ffl
+\def\stligature {\char"0FB06 } % LATIN SMALL LIGATURE ST: st
+\def\zerowidthnobreakspace {\char"0FEFF } % ZERO WIDTH NO-BREAK SPACE: 
+
+\endinput
diff --git a/tex/context/base/xetx-cls.tex b/tex/context/base/xetx-cls.tex
new file mode 100644
index 000000000..6ce696f71
--- /dev/null
+++ b/tex/context/base/xetx-cls.tex
@@ -0,0 +1,378 @@
+% filename : xetx-cls.tex
+% comment : generated by mtxrun --script chars --xtx
+% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+% copyright: PRAGMA ADE / ConTeXt Development Team
+% license : see context related readme files
+
+% some character classes for xetex; seems to be rather hard coded, these numbers
+% and also a mix of several classes; here we do linebreaks
+
+\defineXTXcharinjectionclass[lb:cl]
+\defineXTXcharinjectionclass[lb:ex]
+\defineXTXcharinjectionclass[lb:ns]
+\defineXTXcharinjectionclass[lb:id]
+\defineXTXcharinjectionclass[lb:op]
+\defineXTXcharinjectionclass[lb:cm]
+\defineXTXcharinjectionclass[lb:is]
+
+\dofastrecurse{"00000}{"00008}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0000E}{"0001F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00021}{lb:ex}
+\dosetXTXcharacterclass{"00028}{lb:op}
+\dosetXTXcharacterclass{"00029}{lb:cl}
+\dosetXTXcharacterclass{"0002C}{lb:is}
+\dosetXTXcharacterclass{"0002E}{lb:is}
+\dofastrecurse{"0003A}{"0003B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:is}}
+\dosetXTXcharacterclass{"0003F}{lb:ex}
+\dosetXTXcharacterclass{"0005B}{lb:op}
+\dosetXTXcharacterclass{"0005D}{lb:cl}
+\dosetXTXcharacterclass{"0007B}{lb:op}
+\dosetXTXcharacterclass{"0007D}{lb:cl}
+\dofastrecurse{"0007F}{"00084}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00086}{"0009F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00300}{"0034E}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00350}{"0035B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00363}{"0036F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"0037E}{lb:is}
+\dofastrecurse{"00483}{"00489}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00589}{lb:is}
+\dofastrecurse{"00591}{"005BD}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"005BF}{lb:cm}
+\dofastrecurse{"005C1}{"005C2}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"005C4}{"005C5}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"005C6}{lb:ex}
+\dosetXTXcharacterclass{"005C7}{lb:cm}
+\dosetXTXcharacterclass{"0060C}{lb:ex}
+\dosetXTXcharacterclass{"0060D}{lb:is}
+\dofastrecurse{"00610}{"00615}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0061B}{"0061F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dofastrecurse{"0064B}{"0065E}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"0066A}{lb:ex}
+\dosetXTXcharacterclass{"00670}{lb:cm}
+\dosetXTXcharacterclass{"006D4}{lb:ex}
+\dofastrecurse{"006D6}{"006DC}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"006DE}{"006E4}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"006E7}{"006E8}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"006EA}{"006ED}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00711}{lb:cm}
+\dofastrecurse{"00730}{"0074A}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"007A6}{"007B0}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"007EB}{"007F3}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"007F8}{lb:is}
+\dosetXTXcharacterclass{"007F9}{lb:ex}
+\dofastrecurse{"00901}{"00903}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"0093C}{lb:cm}
+\dofastrecurse{"0093E}{"0094D}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00951}{"00954}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00962}{"00963}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00981}{"00983}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"009BC}{lb:cm}
+\dofastrecurse{"009BE}{"009CD}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"009D7}{lb:cm}
+\dofastrecurse{"009E2}{"009E3}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00A01}{"00A03}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00A3C}{"00A4D}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00A70}{"00A71}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00A81}{"00A83}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00ABC}{lb:cm}
+\dofastrecurse{"00ABE}{"00ACD}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00AE2}{"00AE3}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00B01}{"00B03}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00B3C}{lb:cm}
+\dofastrecurse{"00B3E}{"00B57}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00B82}{lb:cm}
+\dofastrecurse{"00BBE}{"00BD7}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00C01}{"00C03}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00C3E}{"00C56}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00C82}{"00C83}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00CBC}{lb:cm}
+\dofastrecurse{"00CBE}{"00CD6}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00CE2}{"00CE3}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00D02}{"00D03}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00D3E}{"00D57}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00D82}{"00D83}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00DCA}{"00DF3}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00F0D}{"00F11}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dosetXTXcharacterclass{"00F14}{lb:ex}
+\dofastrecurse{"00F18}{"00F19}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00F35}{lb:cm}
+\dosetXTXcharacterclass{"00F37}{lb:cm}
+\dosetXTXcharacterclass{"00F39}{lb:cm}
+\dosetXTXcharacterclass{"00F3A}{lb:op}
+\dosetXTXcharacterclass{"00F3B}{lb:cl}
+\dosetXTXcharacterclass{"00F3C}{lb:op}
+\dosetXTXcharacterclass{"00F3D}{lb:cl}
+\dofastrecurse{"00F3E}{"00F3F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00F71}{"00F7E}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00F80}{"00F84}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00F86}{"00F87}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"00F90}{"00FBC}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"00FC6}{lb:cm}
+\dosetXTXcharacterclass{"0135F}{lb:cm}
+\dosetXTXcharacterclass{"0169B}{lb:op}
+\dosetXTXcharacterclass{"0169C}{lb:cl}
+\dofastrecurse{"01712}{"01714}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01732}{"01734}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01752}{"01753}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01772}{"01773}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"017D6}{lb:ns}
+\dofastrecurse{"0180B}{"0180D}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"018A9}{lb:cm}
+\dofastrecurse{"01920}{"0193B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01944}{"01945}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dofastrecurse{"01A17}{"01A1B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01B00}{"01B04}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01B34}{"01B44}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01B6B}{"01B73}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"01DC0}{"01DFF}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0200C}{"0200F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"0201A}{lb:op}
+\dosetXTXcharacterclass{"0201E}{lb:op}
+\dofastrecurse{"0202A}{"0202E}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0203C}{"0203D}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dosetXTXcharacterclass{"02044}{lb:is}
+\dosetXTXcharacterclass{"02045}{lb:op}
+\dosetXTXcharacterclass{"02046}{lb:cl}
+\dofastrecurse{"02047}{"02049}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"0206A}{"0206F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"0207D}{lb:op}
+\dosetXTXcharacterclass{"0207E}{lb:cl}
+\dosetXTXcharacterclass{"0208D}{lb:op}
+\dosetXTXcharacterclass{"0208E}{lb:cl}
+\dofastrecurse{"020D0}{"020EF}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"02329}{lb:op}
+\dosetXTXcharacterclass{"0232A}{lb:cl}
+\dofastrecurse{"02762}{"02763}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dosetXTXcharacterclass{"02768}{lb:op}
+\dosetXTXcharacterclass{"02769}{lb:cl}
+\dosetXTXcharacterclass{"0276A}{lb:op}
+\dosetXTXcharacterclass{"0276B}{lb:cl}
+\dosetXTXcharacterclass{"0276C}{lb:op}
+\dosetXTXcharacterclass{"0276D}{lb:cl}
+\dosetXTXcharacterclass{"0276E}{lb:op}
+\dosetXTXcharacterclass{"0276F}{lb:cl}
+\dosetXTXcharacterclass{"02770}{lb:op}
+\dosetXTXcharacterclass{"02771}{lb:cl}
+\dosetXTXcharacterclass{"02772}{lb:op}
+\dosetXTXcharacterclass{"02773}{lb:cl}
+\dosetXTXcharacterclass{"02774}{lb:op}
+\dosetXTXcharacterclass{"02775}{lb:cl}
+\dosetXTXcharacterclass{"027C5}{lb:op}
+\dosetXTXcharacterclass{"027C6}{lb:cl}
+\dosetXTXcharacterclass{"027E6}{lb:op}
+\dosetXTXcharacterclass{"027E7}{lb:cl}
+\dosetXTXcharacterclass{"027E8}{lb:op}
+\dosetXTXcharacterclass{"027E9}{lb:cl}
+\dosetXTXcharacterclass{"027EA}{lb:op}
+\dosetXTXcharacterclass{"027EB}{lb:cl}
+\dosetXTXcharacterclass{"02983}{lb:op}
+\dosetXTXcharacterclass{"02984}{lb:cl}
+\dosetXTXcharacterclass{"02985}{lb:op}
+\dosetXTXcharacterclass{"02986}{lb:cl}
+\dosetXTXcharacterclass{"02987}{lb:op}
+\dosetXTXcharacterclass{"02988}{lb:cl}
+\dosetXTXcharacterclass{"02989}{lb:op}
+\dosetXTXcharacterclass{"0298A}{lb:cl}
+\dosetXTXcharacterclass{"0298B}{lb:op}
+\dosetXTXcharacterclass{"0298C}{lb:cl}
+\dosetXTXcharacterclass{"0298D}{lb:op}
+\dosetXTXcharacterclass{"0298E}{lb:cl}
+\dosetXTXcharacterclass{"0298F}{lb:op}
+\dosetXTXcharacterclass{"02990}{lb:cl}
+\dosetXTXcharacterclass{"02991}{lb:op}
+\dosetXTXcharacterclass{"02992}{lb:cl}
+\dosetXTXcharacterclass{"02993}{lb:op}
+\dosetXTXcharacterclass{"02994}{lb:cl}
+\dosetXTXcharacterclass{"02995}{lb:op}
+\dosetXTXcharacterclass{"02996}{lb:cl}
+\dosetXTXcharacterclass{"02997}{lb:op}
+\dosetXTXcharacterclass{"02998}{lb:cl}
+\dosetXTXcharacterclass{"029D8}{lb:op}
+\dosetXTXcharacterclass{"029D9}{lb:cl}
+\dosetXTXcharacterclass{"029DA}{lb:op}
+\dosetXTXcharacterclass{"029DB}{lb:cl}
+\dosetXTXcharacterclass{"029FC}{lb:op}
+\dosetXTXcharacterclass{"029FD}{lb:cl}
+\dofastrecurse{"02E80}{"03000}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"03001}{"03002}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cl}}
+\dofastrecurse{"03003}{"03004}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"03005}{lb:ns}
+\dofastrecurse{"03006}{"03007}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"03008}{lb:op}
+\dosetXTXcharacterclass{"03009}{lb:cl}
+\dosetXTXcharacterclass{"0300A}{lb:op}
+\dosetXTXcharacterclass{"0300B}{lb:cl}
+\dosetXTXcharacterclass{"0300C}{lb:op}
+\dosetXTXcharacterclass{"0300D}{lb:cl}
+\dosetXTXcharacterclass{"0300E}{lb:op}
+\dosetXTXcharacterclass{"0300F}{lb:cl}
+\dosetXTXcharacterclass{"03010}{lb:op}
+\dosetXTXcharacterclass{"03011}{lb:cl}
+\dofastrecurse{"03012}{"03013}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"03014}{lb:op}
+\dosetXTXcharacterclass{"03015}{lb:cl}
+\dosetXTXcharacterclass{"03016}{lb:op}
+\dosetXTXcharacterclass{"03017}{lb:cl}
+\dosetXTXcharacterclass{"03018}{lb:op}
+\dosetXTXcharacterclass{"03019}{lb:cl}
+\dosetXTXcharacterclass{"0301A}{lb:op}
+\dosetXTXcharacterclass{"0301B}{lb:cl}
+\dosetXTXcharacterclass{"0301C}{lb:ns}
+\dosetXTXcharacterclass{"0301D}{lb:op}
+\dofastrecurse{"0301E}{"0301F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cl}}
+\dofastrecurse{"03020}{"03029}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"0302A}{"0302F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"03030}{"0303A}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"0303B}{"0303C}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"0303D}{"0303F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"03041}{lb:ns}
+\dosetXTXcharacterclass{"03042}{lb:id}
+\dosetXTXcharacterclass{"03043}{lb:ns}
+\dosetXTXcharacterclass{"03044}{lb:id}
+\dosetXTXcharacterclass{"03045}{lb:ns}
+\dosetXTXcharacterclass{"03046}{lb:id}
+\dosetXTXcharacterclass{"03047}{lb:ns}
+\dosetXTXcharacterclass{"03048}{lb:id}
+\dosetXTXcharacterclass{"03049}{lb:ns}
+\dofastrecurse{"0304A}{"03062}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"03063}{lb:ns}
+\dofastrecurse{"03064}{"03082}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"03083}{lb:ns}
+\dosetXTXcharacterclass{"03084}{lb:id}
+\dosetXTXcharacterclass{"03085}{lb:ns}
+\dosetXTXcharacterclass{"03086}{lb:id}
+\dosetXTXcharacterclass{"03087}{lb:ns}
+\dofastrecurse{"03088}{"0308D}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0308E}{lb:ns}
+\dofastrecurse{"0308F}{"03094}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"03095}{"03096}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"03099}{"0309A}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0309B}{"0309E}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dosetXTXcharacterclass{"0309F}{lb:id}
+\dofastrecurse{"030A0}{"030A1}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dosetXTXcharacterclass{"030A2}{lb:id}
+\dosetXTXcharacterclass{"030A3}{lb:ns}
+\dosetXTXcharacterclass{"030A4}{lb:id}
+\dosetXTXcharacterclass{"030A5}{lb:ns}
+\dosetXTXcharacterclass{"030A6}{lb:id}
+\dosetXTXcharacterclass{"030A7}{lb:ns}
+\dosetXTXcharacterclass{"030A8}{lb:id}
+\dosetXTXcharacterclass{"030A9}{lb:ns}
+\dofastrecurse{"030AA}{"030C2}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"030C3}{lb:ns}
+\dofastrecurse{"030C4}{"030E2}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"030E3}{lb:ns}
+\dosetXTXcharacterclass{"030E4}{lb:id}
+\dosetXTXcharacterclass{"030E5}{lb:ns}
+\dosetXTXcharacterclass{"030E6}{lb:id}
+\dosetXTXcharacterclass{"030E7}{lb:ns}
+\dofastrecurse{"030E8}{"030ED}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"030EE}{lb:ns}
+\dofastrecurse{"030EF}{"030F4}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"030F5}{"030F6}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"030F7}{"030FA}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"030FB}{"030FE}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"030FF}{"031CF}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"031F0}{"031FF}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"03200}{"03400}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"04E00}{"0A014}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0A015}{lb:ns}
+\dofastrecurse{"0A016}{"0A4C6}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0A802}{lb:cm}
+\dosetXTXcharacterclass{"0A806}{lb:cm}
+\dosetXTXcharacterclass{"0A80B}{lb:cm}
+\dofastrecurse{"0A823}{"0A827}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0A876}{"0A877}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dofastrecurse{"0F900}{"0FAD9}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FB1E}{lb:cm}
+\dosetXTXcharacterclass{"0FD3E}{lb:op}
+\dosetXTXcharacterclass{"0FD3F}{lb:cl}
+\dofastrecurse{"0FE00}{"0FE0F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dosetXTXcharacterclass{"0FE10}{lb:is}
+\dofastrecurse{"0FE11}{"0FE12}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cl}}
+\dofastrecurse{"0FE13}{"0FE14}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:is}}
+\dofastrecurse{"0FE15}{"0FE16}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dosetXTXcharacterclass{"0FE17}{lb:op}
+\dosetXTXcharacterclass{"0FE18}{lb:cl}
+\dofastrecurse{"0FE20}{"0FE23}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"0FE30}{"0FE34}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FE35}{lb:op}
+\dosetXTXcharacterclass{"0FE36}{lb:cl}
+\dosetXTXcharacterclass{"0FE37}{lb:op}
+\dosetXTXcharacterclass{"0FE38}{lb:cl}
+\dosetXTXcharacterclass{"0FE39}{lb:op}
+\dosetXTXcharacterclass{"0FE3A}{lb:cl}
+\dosetXTXcharacterclass{"0FE3B}{lb:op}
+\dosetXTXcharacterclass{"0FE3C}{lb:cl}
+\dosetXTXcharacterclass{"0FE3D}{lb:op}
+\dosetXTXcharacterclass{"0FE3E}{lb:cl}
+\dosetXTXcharacterclass{"0FE3F}{lb:op}
+\dosetXTXcharacterclass{"0FE40}{lb:cl}
+\dosetXTXcharacterclass{"0FE41}{lb:op}
+\dosetXTXcharacterclass{"0FE42}{lb:cl}
+\dosetXTXcharacterclass{"0FE43}{lb:op}
+\dosetXTXcharacterclass{"0FE44}{lb:cl}
+\dofastrecurse{"0FE45}{"0FE46}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FE47}{lb:op}
+\dosetXTXcharacterclass{"0FE48}{lb:cl}
+\dofastrecurse{"0FE49}{"0FE4F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FE50}{lb:cl}
+\dosetXTXcharacterclass{"0FE51}{lb:id}
+\dosetXTXcharacterclass{"0FE52}{lb:cl}
+\dofastrecurse{"0FE54}{"0FE55}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"0FE56}{"0FE57}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ex}}
+\dosetXTXcharacterclass{"0FE58}{lb:id}
+\dosetXTXcharacterclass{"0FE59}{lb:op}
+\dosetXTXcharacterclass{"0FE5A}{lb:cl}
+\dosetXTXcharacterclass{"0FE5B}{lb:op}
+\dosetXTXcharacterclass{"0FE5C}{lb:cl}
+\dosetXTXcharacterclass{"0FE5D}{lb:op}
+\dosetXTXcharacterclass{"0FE5E}{lb:cl}
+\dofastrecurse{"0FE5F}{"0FE68}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FE6B}{lb:id}
+\dosetXTXcharacterclass{"0FF01}{lb:ex}
+\dofastrecurse{"0FF02}{"0FF03}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"0FF06}{"0FF07}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FF08}{lb:op}
+\dosetXTXcharacterclass{"0FF09}{lb:cl}
+\dofastrecurse{"0FF0A}{"0FF0B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FF0C}{lb:cl}
+\dosetXTXcharacterclass{"0FF0D}{lb:id}
+\dosetXTXcharacterclass{"0FF0E}{lb:cl}
+\dofastrecurse{"0FF0F}{"0FF19}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"0FF1A}{"0FF1B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"0FF1C}{"0FF1E}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FF1F}{lb:ex}
+\dofastrecurse{"0FF20}{"0FF3A}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FF3B}{lb:op}
+\dosetXTXcharacterclass{"0FF3C}{lb:id}
+\dosetXTXcharacterclass{"0FF3D}{lb:cl}
+\dofastrecurse{"0FF3E}{"0FF5A}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dosetXTXcharacterclass{"0FF5B}{lb:op}
+\dosetXTXcharacterclass{"0FF5C}{lb:id}
+\dosetXTXcharacterclass{"0FF5D}{lb:cl}
+\dosetXTXcharacterclass{"0FF5E}{lb:id}
+\dosetXTXcharacterclass{"0FF5F}{lb:op}
+\dofastrecurse{"0FF60}{"0FF61}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cl}}
+\dosetXTXcharacterclass{"0FF62}{lb:op}
+\dofastrecurse{"0FF63}{"0FF64}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cl}}
+\dosetXTXcharacterclass{"0FF65}{lb:ns}
+\dofastrecurse{"0FF67}{"0FF70}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"0FF9E}{"0FF9F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:ns}}
+\dofastrecurse{"0FFE2}{"0FFE4}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"0FFF9}{"0FFFB}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"10A01}{"10A0F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"10A38}{"10A3F}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"1D165}{"1D169}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"1D16D}{"1D182}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"1D185}{"1D18B}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"1D1AA}{"1D1AD}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"1D242}{"1D244}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+\dofastrecurse{"20000}{"2FA1D}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"E0001}{"E01EF}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:cm}}
+
+\dofastrecurse{"03400}{"04DB5}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"04E00}{"09FBB}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+\dofastrecurse{"20000}{"2A6D6}{1}{\dosetXTXcharacterclass\fastrecursecounter{lb:id}}
+
+\endinput
diff --git a/tex/context/base/xetx-ini.tex b/tex/context/base/xetx-ini.tex
new file mode 100644
index 000000000..db3cccabd
--- /dev/null
+++ b/tex/context/base/xetx-ini.tex
@@ -0,0 +1,132 @@
+%D \module
+%D [ file=xetx-ini,
+%D version=2004.09.11,
+%D title=\CONTEXT\ System Macros,
+%D subtitle=\XETEX\ Initializations,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%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 moved some code around and now have reorganized the xetex
+%D code in the \type {xetx} module namespace.
+
+\unprotect
+
+%D Some defaults.
+
+\ifdefined\XeTeXuseglyphmetrics
+ \XeTeXuseglyphmetrics\plusone
+\fi
+
+%D Character classes.
+
+\newcount\nofXTXcharinjections
+
+\def\defineXTXcharinjectionclass[#1]%
+ {\global\advance\nofXTXcharinjections\plusone
+ \setxvalue{@xtx@cc@#1}{\number\nofXTXcharinjections}}
+
+\setxvalue{@xtx@cc@\s!default}{0}
+
+\def\getXTXcharinjectionclass#1%
+ {\csname @xtx@cc@\ifcsname @xtx@cc@#1\endcsname#1\else\s!default\fi\endcsname}
+
+\let\currentXTXcharinjection\s!default
+
+\def\startXTXcharinjecxtions[#1]%
+ {\pushmacro\currentXTXcharinjection
+ \def\currentXTXcharinjection{#1}}
+
+\def\stopXTXcharinjections
+ {\popmacro\currentXTXcharinjection}
+
+\def\defineXTXcharinjection #1 #2 %
+ {\doifnumberelse{#1}{\edef\XTXclassone{\number#1}}{\edef\XTXclassone{\getXTXcharinjectionclas{#1}}}%
+ \doifnumberelse{#2}{\edef\XTXclasstwo{\number#2}}{\edef\XTXclasstwo{\getXTXcharinjectionclas{#2}}}%
+ \expanded{\dodefineXTXcharinjection{\XTXclassone}{\XTXclasstwo}}}
+
+\def\setXTXcharcodes #1 #2 #3 % encoding syntax
+ {\catcode#1=11 \lccode #1=#2 \uccode #1=#3 }
+
+\def\dosetXTXcharcodes#1#2#3% compact syntax
+ {\catcode#1=11 \lccode #1=#2 \uccode #1=#3 }
+
+\ifdefined\XeTeXinterchartoks
+
+ \long\def\dodefineXTXcharinjection#1#2#3%
+ {\XeTeXinterchartoks #1 #2 {\XTXcharinjection{#1}{#2}}%
+ \setvalue{@xtx@ch@\currentXTXcharinjection @#1@#2@}{#3}}
+
+ \def\setXTXcharacterclass #1 #2 %
+ {\doifnumberelse{#2}
+ {\XeTeXcharclass#1=#2\relax}
+ {\XeTeXcharclass#1=\getXTXcharinjectionclass{#2}\relax}}
+
+ \def\dosetXTXcharacterclass#1% #2 fast one
+ {\XeTeXcharclass#1=\getXTXcharinjectionclass}
+
+\else
+
+ \long\def\dodefineXTXcharinjection#1#2#3%
+ {\setvalue{@xtx@ch@\currentXTXcharinjection @#1@#2@}{#3}}
+
+ \def\setXTXcharacterclass #1 #2 %
+ {}
+
+\fi
+
+\chardef\XTXcharinjectionsmode=1
+
+\letvalue{@xtx@ch@\s!empty}\empty
+
+\def\XTXcharinjection#1#2%
+ {\csname @xtx@ch@%
+ \ifcase\XTXcharinjectionsmode
+ \s!empty
+ \or
+ \ifcsname @xtx@ch@\currentXTXcharinjection @#1@#2@\endcsname \currentXTXcharinjection @#1@#2@\fi
+ \or
+ \ifcsname @xtx@ch@\currentXTXcharinjection @#1@#2@\endcsname \currentXTXcharinjection @#1@#2@\else
+ \ifcsname @xtx@ch@\s!default @#1@#2@\endcsname \s!default @#1@#2@\else
+ \s!empty
+ \fi\fi
+ \else
+ \s!empty
+ \fi
+ \endcsname}
+
+\def\enableXTXcharinjections[#1]%
+ {\def\currentXTXcharinjection{#1}}
+
+\protect \endinput
+
+\starttext
+
+\startXTXcharinjecxtions[default]
+ \defineXTXcharinjection 10 40 {[default]}
+\stopXTXcharinjections
+
+\startXTXcharinjecxtions[whatever]
+ \defineXTXcharinjection 20 40 {[whatever]}
+\stopXTXcharinjections
+
+\chardef\XTXcharinjectionsmode=0
+
+\enableXTXcharinjections[default] A\XTXcharinjection{10}{40}B\XTXcharinjection{20}{40}C
+\enableXTXcharinjections[whatever] A\XTXcharinjection{10}{40}B\XTXcharinjection{20}{40}C
+
+\chardef\XTXcharinjectionsmode=1
+
+\enableXTXcharinjections[default] A\XTXcharinjection{10}{40}B\XTXcharinjection{20}{40}C
+\enableXTXcharinjections[whatever] A\XTXcharinjection{10}{40}B\XTXcharinjection{20}{40}C
+
+\chardef\XTXcharinjectionsmode=2
+
+\enableXTXcharinjections[default] A\XTXcharinjection{10}{40}B\XTXcharinjection{20}{40}C
+\enableXTXcharinjections[whatever] A\XTXcharinjection{10}{40}B\XTXcharinjection{20}{40}C
+
+\stoptext
diff --git a/tex/context/base/xetx-utf.tex b/tex/context/base/xetx-utf.tex
new file mode 100644
index 000000000..79bd00745
--- /dev/null
+++ b/tex/context/base/xetx-utf.tex
@@ -0,0 +1,1989 @@
+% filename : xetx-utf.tex
+% comment : generated by mtxrun --script chars --xtx
+% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+% copyright: PRAGMA ADE / ConTeXt Development Team
+% license : see context related readme files
+
+% lc/uc/catcode mappings
+
+\setXTXcharcodes "00041 "00061 "00041 % LATIN CAPITAL LETTER A
+\setXTXcharcodes "00042 "00062 "00042 % LATIN CAPITAL LETTER B
+\setXTXcharcodes "00043 "00063 "00043 % LATIN CAPITAL LETTER C
+\setXTXcharcodes "00044 "00064 "00044 % LATIN CAPITAL LETTER D
+\setXTXcharcodes "00045 "00065 "00045 % LATIN CAPITAL LETTER E
+\setXTXcharcodes "00046 "00066 "00046 % LATIN CAPITAL LETTER F
+\setXTXcharcodes "00047 "00067 "00047 % LATIN CAPITAL LETTER G
+\setXTXcharcodes "00048 "00068 "00048 % LATIN CAPITAL LETTER H
+\setXTXcharcodes "00049 "00069 "00049 % LATIN CAPITAL LETTER I
+\setXTXcharcodes "0004A "0006A "0004A % LATIN CAPITAL LETTER J
+\setXTXcharcodes "0004B "0006B "0004B % LATIN CAPITAL LETTER K
+\setXTXcharcodes "0004C "0006C "0004C % LATIN CAPITAL LETTER L
+\setXTXcharcodes "0004D "0006D "0004D % LATIN CAPITAL LETTER M
+\setXTXcharcodes "0004E "0006E "0004E % LATIN CAPITAL LETTER N
+\setXTXcharcodes "0004F "0006F "0004F % LATIN CAPITAL LETTER O
+\setXTXcharcodes "00050 "00070 "00050 % LATIN CAPITAL LETTER P
+\setXTXcharcodes "00051 "00071 "00051 % LATIN CAPITAL LETTER Q
+\setXTXcharcodes "00052 "00072 "00052 % LATIN CAPITAL LETTER R
+\setXTXcharcodes "00053 "00073 "00053 % LATIN CAPITAL LETTER S
+\setXTXcharcodes "00054 "00074 "00054 % LATIN CAPITAL LETTER T
+\setXTXcharcodes "00055 "00075 "00055 % LATIN CAPITAL LETTER U
+\setXTXcharcodes "00056 "00076 "00056 % LATIN CAPITAL LETTER V
+\setXTXcharcodes "00057 "00077 "00057 % LATIN CAPITAL LETTER W
+\setXTXcharcodes "00058 "00078 "00058 % LATIN CAPITAL LETTER X
+\setXTXcharcodes "00059 "00079 "00059 % LATIN CAPITAL LETTER Y
+\setXTXcharcodes "0005A "0007A "0005A % LATIN CAPITAL LETTER Z
+\setXTXcharcodes "00061 "00061 "00041 % LATIN SMALL LETTER A
+\setXTXcharcodes "00062 "00062 "00042 % LATIN SMALL LETTER B
+\setXTXcharcodes "00063 "00063 "00043 % LATIN SMALL LETTER C
+\setXTXcharcodes "00064 "00064 "00044 % LATIN SMALL LETTER D
+\setXTXcharcodes "00065 "00065 "00045 % LATIN SMALL LETTER E
+\setXTXcharcodes "00066 "00066 "00046 % LATIN SMALL LETTER F
+\setXTXcharcodes "00067 "00067 "00047 % LATIN SMALL LETTER G
+\setXTXcharcodes "00068 "00068 "00048 % LATIN SMALL LETTER H
+\setXTXcharcodes "00069 "00069 "00049 % LATIN SMALL LETTER I
+\setXTXcharcodes "0006A "0006A "0004A % LATIN SMALL LETTER J
+\setXTXcharcodes "0006B "0006B "0004B % LATIN SMALL LETTER K
+\setXTXcharcodes "0006C "0006C "0004C % LATIN SMALL LETTER L
+\setXTXcharcodes "0006D "0006D "0004D % LATIN SMALL LETTER M
+\setXTXcharcodes "0006E "0006E "0004E % LATIN SMALL LETTER N
+\setXTXcharcodes "0006F "0006F "0004F % LATIN SMALL LETTER O
+\setXTXcharcodes "00070 "00070 "00050 % LATIN SMALL LETTER P
+\setXTXcharcodes "00071 "00071 "00051 % LATIN SMALL LETTER Q
+\setXTXcharcodes "00072 "00072 "00052 % LATIN SMALL LETTER R
+\setXTXcharcodes "00073 "00073 "00053 % LATIN SMALL LETTER S
+\setXTXcharcodes "00074 "00074 "00054 % LATIN SMALL LETTER T
+\setXTXcharcodes "00075 "00075 "00055 % LATIN SMALL LETTER U
+\setXTXcharcodes "00076 "00076 "00056 % LATIN SMALL LETTER V
+\setXTXcharcodes "00077 "00077 "00057 % LATIN SMALL LETTER W
+\setXTXcharcodes "00078 "00078 "00058 % LATIN SMALL LETTER X
+\setXTXcharcodes "00079 "00079 "00059 % LATIN SMALL LETTER Y
+\setXTXcharcodes "0007A "0007A "0005A % LATIN SMALL LETTER Z
+\setXTXcharcodes "000AA "000AA "000AA % FEMININE ORDINAL INDICATOR
+\setXTXcharcodes "000B5 "000B5 "0039C % MICRO SIGN
+\setXTXcharcodes "000BA "000BA "000BA % MASCULINE ORDINAL INDICATOR
+\setXTXcharcodes "000C0 "000E0 "000C0 % LATIN CAPITAL LETTER A WITH GRAVE
+\setXTXcharcodes "000C1 "000E1 "000C1 % LATIN CAPITAL LETTER A WITH ACUTE
+\setXTXcharcodes "000C2 "000E2 "000C2 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+\setXTXcharcodes "000C3 "000E3 "000C3 % LATIN CAPITAL LETTER A WITH TILDE
+\setXTXcharcodes "000C4 "000E4 "000C4 % LATIN CAPITAL LETTER A WITH DIAERESIS
+\setXTXcharcodes "000C5 "000E5 "000C5 % LATIN CAPITAL LETTER A WITH RING ABOVE
+\setXTXcharcodes "000C6 "000E6 "000C6 % LATIN CAPITAL LETTER AE
+\setXTXcharcodes "000C7 "000E7 "000C7 % LATIN CAPITAL LETTER C WITH CEDILLA
+\setXTXcharcodes "000C8 "000E8 "000C8 % LATIN CAPITAL LETTER E WITH GRAVE
+\setXTXcharcodes "000C9 "000E9 "000C9 % LATIN CAPITAL LETTER E WITH ACUTE
+\setXTXcharcodes "000CA "000EA "000CA % LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+\setXTXcharcodes "000CB "000EB "000CB % LATIN CAPITAL LETTER E WITH DIAERESIS
+\setXTXcharcodes "000CC "000EC "000CC % LATIN CAPITAL LETTER I WITH GRAVE
+\setXTXcharcodes "000CD "000ED "000CD % LATIN CAPITAL LETTER I WITH ACUTE
+\setXTXcharcodes "000CE "000EE "000CE % LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+\setXTXcharcodes "000CF "000EF "000CF % LATIN CAPITAL LETTER I WITH DIAERESIS
+\setXTXcharcodes "000D0 "000F0 "000D0 % LATIN CAPITAL LETTER ETH
+\setXTXcharcodes "000D1 "000F1 "000D1 % LATIN CAPITAL LETTER N WITH TILDE
+\setXTXcharcodes "000D2 "000F2 "000D2 % LATIN CAPITAL LETTER O WITH GRAVE
+\setXTXcharcodes "000D3 "000F3 "000D3 % LATIN CAPITAL LETTER O WITH ACUTE
+\setXTXcharcodes "000D4 "000F4 "000D4 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+\setXTXcharcodes "000D5 "000F5 "000D5 % LATIN CAPITAL LETTER O WITH TILDE
+\setXTXcharcodes "000D6 "000F6 "000D6 % LATIN CAPITAL LETTER O WITH DIAERESIS
+\setXTXcharcodes "000D8 "000F8 "000D8 % LATIN CAPITAL LETTER O WITH STROKE
+\setXTXcharcodes "000D9 "000F9 "000D9 % LATIN CAPITAL LETTER U WITH GRAVE
+\setXTXcharcodes "000DA "000FA "000DA % LATIN CAPITAL LETTER U WITH ACUTE
+\setXTXcharcodes "000DB "000FB "000DB % LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+\setXTXcharcodes "000DC "000FC "000DC % LATIN CAPITAL LETTER U WITH DIAERESIS
+\setXTXcharcodes "000DD "000FD "000DD % LATIN CAPITAL LETTER Y WITH ACUTE
+\setXTXcharcodes "000DE "000FE "000DE % LATIN CAPITAL LETTER THORN
+\setXTXcharcodes "000DF "000DF "000DF % LATIN SMALL LETTER SHARP S
+\setXTXcharcodes "000E0 "000E0 "000C0 % LATIN SMALL LETTER A WITH GRAVE
+\setXTXcharcodes "000E1 "000E1 "000C1 % LATIN SMALL LETTER A WITH ACUTE
+\setXTXcharcodes "000E2 "000E2 "000C2 % LATIN SMALL LETTER A WITH CIRCUMFLEX
+\setXTXcharcodes "000E3 "000E3 "000C3 % LATIN SMALL LETTER A WITH TILDE
+\setXTXcharcodes "000E4 "000E4 "000C4 % LATIN SMALL LETTER A WITH DIAERESIS
+\setXTXcharcodes "000E5 "000E5 "000C5 % LATIN SMALL LETTER A WITH RING ABOVE
+\setXTXcharcodes "000E6 "000E6 "000C6 % LATIN SMALL LETTER AE
+\setXTXcharcodes "000E7 "000E7 "000C7 % LATIN SMALL LETTER C WITH CEDILLA
+\setXTXcharcodes "000E8 "000E8 "000C8 % LATIN SMALL LETTER E WITH GRAVE
+\setXTXcharcodes "000E9 "000E9 "000C9 % LATIN SMALL LETTER E WITH ACUTE
+\setXTXcharcodes "000EA "000EA "000CA % LATIN SMALL LETTER E WITH CIRCUMFLEX
+\setXTXcharcodes "000EB "000EB "000CB % LATIN SMALL LETTER E WITH DIAERESIS
+\setXTXcharcodes "000EC "000EC "000CC % LATIN SMALL LETTER I WITH GRAVE
+\setXTXcharcodes "000ED "000ED "000CD % LATIN SMALL LETTER I WITH ACUTE
+\setXTXcharcodes "000EE "000EE "000CE % LATIN SMALL LETTER I WITH CIRCUMFLEX
+\setXTXcharcodes "000EF "000EF "000CF % LATIN SMALL LETTER I WITH DIAERESIS
+\setXTXcharcodes "000F0 "000F0 "000D0 % LATIN SMALL LETTER ETH
+\setXTXcharcodes "000F1 "000F1 "000D1 % LATIN SMALL LETTER N WITH TILDE
+\setXTXcharcodes "000F2 "000F2 "000D2 % LATIN SMALL LETTER O WITH GRAVE
+\setXTXcharcodes "000F3 "000F3 "000D3 % LATIN SMALL LETTER O WITH ACUTE
+\setXTXcharcodes "000F4 "000F4 "000D4 % LATIN SMALL LETTER O WITH CIRCUMFLEX
+\setXTXcharcodes "000F5 "000F5 "000D5 % LATIN SMALL LETTER O WITH TILDE
+\setXTXcharcodes "000F6 "000F6 "000D6 % LATIN SMALL LETTER O WITH DIAERESIS
+\setXTXcharcodes "000F8 "000F8 "000D8 % LATIN SMALL LETTER O WITH STROKE
+\setXTXcharcodes "000F9 "000F9 "000D9 % LATIN SMALL LETTER U WITH GRAVE
+\setXTXcharcodes "000FA "000FA "000DA % LATIN SMALL LETTER U WITH ACUTE
+\setXTXcharcodes "000FB "000FB "000DB % LATIN SMALL LETTER U WITH CIRCUMFLEX
+\setXTXcharcodes "000FC "000FC "000DC % LATIN SMALL LETTER U WITH DIAERESIS
+\setXTXcharcodes "000FD "000FD "000DD % LATIN SMALL LETTER Y WITH ACUTE
+\setXTXcharcodes "000FE "000FE "000DE % LATIN SMALL LETTER THORN
+\setXTXcharcodes "000FF "000FF "00178 % LATIN SMALL LETTER Y WITH DIAERESIS
+\setXTXcharcodes "00100 "00101 "00100 % LATIN CAPITAL LETTER A WITH MACRON
+\setXTXcharcodes "00101 "00101 "00100 % LATIN SMALL LETTER A WITH MACRON
+\setXTXcharcodes "00102 "00103 "00102 % LATIN CAPITAL LETTER A WITH BREVE
+\setXTXcharcodes "00103 "00103 "00102 % LATIN SMALL LETTER A WITH BREVE
+\setXTXcharcodes "00104 "00105 "00104 % LATIN CAPITAL LETTER A WITH OGONEK
+\setXTXcharcodes "00105 "00105 "00104 % LATIN SMALL LETTER A WITH OGONEK
+\setXTXcharcodes "00106 "00107 "00106 % LATIN CAPITAL LETTER C WITH ACUTE
+\setXTXcharcodes "00107 "00107 "00106 % LATIN SMALL LETTER C WITH ACUTE
+\setXTXcharcodes "00108 "00109 "00108 % LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+\setXTXcharcodes "00109 "00109 "00108 % LATIN SMALL LETTER C WITH CIRCUMFLEX
+\setXTXcharcodes "0010A "0010B "0010A % LATIN CAPITAL LETTER C WITH DOT ABOVE
+\setXTXcharcodes "0010B "0010B "0010A % LATIN SMALL LETTER C WITH DOT ABOVE
+\setXTXcharcodes "0010C "0010D "0010C % LATIN CAPITAL LETTER C WITH CARON
+\setXTXcharcodes "0010D "0010D "0010C % LATIN SMALL LETTER C WITH CARON
+\setXTXcharcodes "0010E "0010F "0010E % LATIN CAPITAL LETTER D WITH CARON
+\setXTXcharcodes "0010F "0010F "0010E % LATIN SMALL LETTER D WITH CARON
+\setXTXcharcodes "00110 "00111 "00110 % LATIN CAPITAL LETTER D WITH STROKE
+\setXTXcharcodes "00111 "00111 "00110 % LATIN SMALL LETTER D WITH STROKE
+\setXTXcharcodes "00112 "00113 "00112 % LATIN CAPITAL LETTER E WITH MACRON
+\setXTXcharcodes "00113 "00113 "00112 % LATIN SMALL LETTER E WITH MACRON
+\setXTXcharcodes "00114 "00115 "00114 % LATIN CAPITAL LETTER E WITH BREVE
+\setXTXcharcodes "00115 "00115 "00114 % LATIN SMALL LETTER E WITH BREVE
+\setXTXcharcodes "00116 "00117 "00116 % LATIN CAPITAL LETTER E WITH DOT ABOVE
+\setXTXcharcodes "00117 "00117 "00116 % LATIN SMALL LETTER E WITH DOT ABOVE
+\setXTXcharcodes "00118 "00119 "00118 % LATIN CAPITAL LETTER E WITH OGONEK
+\setXTXcharcodes "00119 "00119 "00118 % LATIN SMALL LETTER E WITH OGONEK
+\setXTXcharcodes "0011A "0011B "0011A % LATIN CAPITAL LETTER E WITH CARON
+\setXTXcharcodes "0011B "0011B "0011A % LATIN SMALL LETTER E WITH CARON
+\setXTXcharcodes "0011C "0011D "0011C % LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+\setXTXcharcodes "0011D "0011D "0011C % LATIN SMALL LETTER G WITH CIRCUMFLEX
+\setXTXcharcodes "0011E "0011F "0011E % LATIN CAPITAL LETTER G WITH BREVE
+\setXTXcharcodes "0011F "0011F "0011E % LATIN SMALL LETTER G WITH BREVE
+\setXTXcharcodes "00120 "00121 "00120 % LATIN CAPITAL LETTER G WITH DOT ABOVE
+\setXTXcharcodes "00121 "00121 "00120 % LATIN SMALL LETTER G WITH DOT ABOVE
+\setXTXcharcodes "00122 "00123 "00122 % LATIN CAPITAL LETTER G WITH CEDILLA
+\setXTXcharcodes "00123 "00123 "00122 % LATIN SMALL LETTER G WITH CEDILLA
+\setXTXcharcodes "00124 "00125 "00124 % LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+\setXTXcharcodes "00125 "00125 "00124 % LATIN SMALL LETTER H WITH CIRCUMFLEX
+\setXTXcharcodes "00126 "00127 "00126 % LATIN CAPITAL LETTER H WITH STROKE
+\setXTXcharcodes "00127 "00127 "00126 % LATIN SMALL LETTER H WITH STROKE
+\setXTXcharcodes "00128 "00129 "00128 % LATIN CAPITAL LETTER I WITH TILDE
+\setXTXcharcodes "00129 "00129 "00128 % LATIN SMALL LETTER I WITH TILDE
+\setXTXcharcodes "0012A "0012B "0012A % LATIN CAPITAL LETTER I WITH MACRON
+\setXTXcharcodes "0012B "0012B "0012A % LATIN SMALL LETTER I WITH MACRON
+\setXTXcharcodes "0012C "0012D "0012C % LATIN CAPITAL LETTER I WITH BREVE
+\setXTXcharcodes "0012D "0012D "0012C % LATIN SMALL LETTER I WITH BREVE
+\setXTXcharcodes "0012E "0012F "0012E % LATIN CAPITAL LETTER I WITH OGONEK
+\setXTXcharcodes "0012F "0012F "0012E % LATIN SMALL LETTER I WITH OGONEK
+\setXTXcharcodes "00130 "00069 "00130 % LATIN CAPITAL LETTER I WITH DOT ABOVE
+\setXTXcharcodes "00131 "00131 "00049 % LATIN SMALL LETTER DOTLESS I
+\setXTXcharcodes "00132 "00133 "00132 % LATIN CAPITAL LIGATURE IJ
+\setXTXcharcodes "00133 "00133 "00132 % LATIN SMALL LIGATURE IJ
+\setXTXcharcodes "00134 "00135 "00134 % LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+\setXTXcharcodes "00135 "00135 "00134 % LATIN SMALL LETTER J WITH CIRCUMFLEX
+\setXTXcharcodes "00136 "00137 "00136 % LATIN CAPITAL LETTER K WITH CEDILLA
+\setXTXcharcodes "00137 "00137 "00136 % LATIN SMALL LETTER K WITH CEDILLA
+\setXTXcharcodes "00138 "00138 "00138 % LATIN SMALL LETTER KRA
+\setXTXcharcodes "00139 "0013A "00139 % LATIN CAPITAL LETTER L WITH ACUTE
+\setXTXcharcodes "0013A "0013A "00139 % LATIN SMALL LETTER L WITH ACUTE
+\setXTXcharcodes "0013B "0013C "0013B % LATIN CAPITAL LETTER L WITH CEDILLA
+\setXTXcharcodes "0013C "0013C "0013B % LATIN SMALL LETTER L WITH CEDILLA
+\setXTXcharcodes "0013D "0013E "0013D % LATIN CAPITAL LETTER L WITH CARON
+\setXTXcharcodes "0013E "0013E "0013D % LATIN SMALL LETTER L WITH CARON
+\setXTXcharcodes "0013F "00140 "0013F % LATIN CAPITAL LETTER L WITH MIDDLE DOT
+\setXTXcharcodes "00140 "00140 "0013F % LATIN SMALL LETTER L WITH MIDDLE DOT
+\setXTXcharcodes "00141 "00142 "00141 % LATIN CAPITAL LETTER L WITH STROKE
+\setXTXcharcodes "00142 "00142 "00141 % LATIN SMALL LETTER L WITH STROKE
+\setXTXcharcodes "00143 "00144 "00143 % LATIN CAPITAL LETTER N WITH ACUTE
+\setXTXcharcodes "00144 "00144 "00143 % LATIN SMALL LETTER N WITH ACUTE
+\setXTXcharcodes "00145 "00146 "00145 % LATIN CAPITAL LETTER N WITH CEDILLA
+\setXTXcharcodes "00146 "00146 "00145 % LATIN SMALL LETTER N WITH CEDILLA
+\setXTXcharcodes "00147 "00148 "00147 % LATIN CAPITAL LETTER N WITH CARON
+\setXTXcharcodes "00148 "00148 "00147 % LATIN SMALL LETTER N WITH CARON
+\setXTXcharcodes "00149 "00149 "00149 % LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+\setXTXcharcodes "0014A "0014B "0014A % LATIN CAPITAL LETTER ENG
+\setXTXcharcodes "0014B "0014B "0014A % LATIN SMALL LETTER ENG
+\setXTXcharcodes "0014C "0014D "0014C % LATIN CAPITAL LETTER O WITH MACRON
+\setXTXcharcodes "0014D "0014D "0014C % LATIN SMALL LETTER O WITH MACRON
+\setXTXcharcodes "0014E "0014F "0014E % LATIN CAPITAL LETTER O WITH BREVE
+\setXTXcharcodes "0014F "0014F "0014E % LATIN SMALL LETTER O WITH BREVE
+\setXTXcharcodes "00150 "00151 "00150 % LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+\setXTXcharcodes "00151 "00151 "00150 % LATIN SMALL LETTER O WITH DOUBLE ACUTE
+\setXTXcharcodes "00152 "00153 "00152 % LATIN CAPITAL LIGATURE OE
+\setXTXcharcodes "00153 "00153 "00152 % LATIN SMALL LIGATURE OE
+\setXTXcharcodes "00154 "00155 "00154 % LATIN CAPITAL LETTER R WITH ACUTE
+\setXTXcharcodes "00155 "00155 "00154 % LATIN SMALL LETTER R WITH ACUTE
+\setXTXcharcodes "00156 "00157 "00156 % LATIN CAPITAL LETTER R WITH CEDILLA
+\setXTXcharcodes "00157 "00157 "00156 % LATIN SMALL LETTER R WITH CEDILLA
+\setXTXcharcodes "00158 "00159 "00158 % LATIN CAPITAL LETTER R WITH CARON
+\setXTXcharcodes "00159 "00159 "00158 % LATIN SMALL LETTER R WITH CARON
+\setXTXcharcodes "0015A "0015B "0015A % LATIN CAPITAL LETTER S WITH ACUTE
+\setXTXcharcodes "0015B "0015B "0015A % LATIN SMALL LETTER S WITH ACUTE
+\setXTXcharcodes "0015C "0015D "0015C % LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+\setXTXcharcodes "0015D "0015D "0015C % LATIN SMALL LETTER S WITH CIRCUMFLEX
+\setXTXcharcodes "0015E "0015F "0015E % LATIN CAPITAL LETTER S WITH CEDILLA
+\setXTXcharcodes "0015F "0015F "0015E % LATIN SMALL LETTER S WITH CEDILLA
+\setXTXcharcodes "00160 "00161 "00160 % LATIN CAPITAL LETTER S WITH CARON
+\setXTXcharcodes "00161 "00161 "00160 % LATIN SMALL LETTER S WITH CARON
+\setXTXcharcodes "00162 "00163 "00162 % LATIN CAPITAL LETTER T WITH CEDILLA
+\setXTXcharcodes "00163 "00163 "00162 % LATIN SMALL LETTER T WITH CEDILLA
+\setXTXcharcodes "00164 "00165 "00164 % LATIN CAPITAL LETTER T WITH CARON
+\setXTXcharcodes "00165 "00165 "00164 % LATIN SMALL LETTER T WITH CARON
+\setXTXcharcodes "00166 "00167 "00166 % LATIN CAPITAL LETTER T WITH STROKE
+\setXTXcharcodes "00167 "00167 "00166 % LATIN SMALL LETTER T WITH STROKE
+\setXTXcharcodes "00168 "00169 "00168 % LATIN CAPITAL LETTER U WITH TILDE
+\setXTXcharcodes "00169 "00169 "00168 % LATIN SMALL LETTER U WITH TILDE
+\setXTXcharcodes "0016A "0016B "0016A % LATIN CAPITAL LETTER U WITH MACRON
+\setXTXcharcodes "0016B "0016B "0016A % LATIN SMALL LETTER U WITH MACRON
+\setXTXcharcodes "0016C "0016D "0016C % LATIN CAPITAL LETTER U WITH BREVE
+\setXTXcharcodes "0016D "0016D "0016C % LATIN SMALL LETTER U WITH BREVE
+\setXTXcharcodes "0016E "0016F "0016E % LATIN CAPITAL LETTER U WITH RING ABOVE
+\setXTXcharcodes "0016F "0016F "0016E % LATIN SMALL LETTER U WITH RING ABOVE
+\setXTXcharcodes "00170 "00171 "00170 % LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+\setXTXcharcodes "00171 "00171 "00170 % LATIN SMALL LETTER U WITH DOUBLE ACUTE
+\setXTXcharcodes "00172 "00173 "00172 % LATIN CAPITAL LETTER U WITH OGONEK
+\setXTXcharcodes "00173 "00173 "00172 % LATIN SMALL LETTER U WITH OGONEK
+\setXTXcharcodes "00174 "00175 "00174 % LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+\setXTXcharcodes "00175 "00175 "00174 % LATIN SMALL LETTER W WITH CIRCUMFLEX
+\setXTXcharcodes "00176 "00177 "00176 % LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+\setXTXcharcodes "00177 "00177 "00176 % LATIN SMALL LETTER Y WITH CIRCUMFLEX
+\setXTXcharcodes "00178 "000FF "00178 % LATIN CAPITAL LETTER Y WITH DIAERESIS
+\setXTXcharcodes "00179 "0017A "00179 % LATIN CAPITAL LETTER Z WITH ACUTE
+\setXTXcharcodes "0017A "0017A "00179 % LATIN SMALL LETTER Z WITH ACUTE
+\setXTXcharcodes "0017B "0017C "0017B % LATIN CAPITAL LETTER Z WITH DOT ABOVE
+\setXTXcharcodes "0017C "0017C "0017B % LATIN SMALL LETTER Z WITH DOT ABOVE
+\setXTXcharcodes "0017D "0017E "0017D % LATIN CAPITAL LETTER Z WITH CARON
+\setXTXcharcodes "0017E "0017E "0017D % LATIN SMALL LETTER Z WITH CARON
+\setXTXcharcodes "0017F "0017F "00053 % LATIN SMALL LETTER LONG S
+\setXTXcharcodes "00180 "00180 "00243 % LATIN SMALL LETTER B WITH STROKE
+\setXTXcharcodes "00181 "00253 "00181 % LATIN CAPITAL LETTER B WITH HOOK
+\setXTXcharcodes "00182 "00183 "00182 % LATIN CAPITAL LETTER B WITH TOPBAR
+\setXTXcharcodes "00183 "00183 "00182 % LATIN SMALL LETTER B WITH TOPBAR
+\setXTXcharcodes "00184 "00185 "00184 % LATIN CAPITAL LETTER TONE SIX
+\setXTXcharcodes "00185 "00185 "00184 % LATIN SMALL LETTER TONE SIX
+\setXTXcharcodes "00186 "00254 "00186 % LATIN CAPITAL LETTER OPEN O
+\setXTXcharcodes "00187 "00188 "00187 % LATIN CAPITAL LETTER C WITH HOOK
+\setXTXcharcodes "00188 "00188 "00187 % LATIN SMALL LETTER C WITH HOOK
+\setXTXcharcodes "00189 "00256 "00189 % LATIN CAPITAL LETTER AFRICAN D
+\setXTXcharcodes "0018A "00257 "0018A % LATIN CAPITAL LETTER D WITH HOOK
+\setXTXcharcodes "0018B "0018C "0018B % LATIN CAPITAL LETTER D WITH TOPBAR
+\setXTXcharcodes "0018C "0018C "0018B % LATIN SMALL LETTER D WITH TOPBAR
+\setXTXcharcodes "0018D "0018D "0018D % LATIN SMALL LETTER TURNED DELTA
+\setXTXcharcodes "0018E "001DD "0018E % LATIN CAPITAL LETTER REVERSED E
+\setXTXcharcodes "0018F "00259 "0018F % LATIN CAPITAL LETTER SCHWA
+\setXTXcharcodes "00190 "0025B "00190 % LATIN CAPITAL LETTER OPEN E
+\setXTXcharcodes "00191 "00192 "00191 % LATIN CAPITAL LETTER F WITH HOOK
+\setXTXcharcodes "00192 "00192 "00191 % LATIN SMALL LETTER F WITH HOOK
+\setXTXcharcodes "00193 "00260 "00193 % LATIN CAPITAL LETTER G WITH HOOK
+\setXTXcharcodes "00194 "00263 "00194 % LATIN CAPITAL LETTER GAMMA
+\setXTXcharcodes "00195 "00195 "001F6 % LATIN SMALL LETTER HV
+\setXTXcharcodes "00196 "00269 "00196 % LATIN CAPITAL LETTER IOTA
+\setXTXcharcodes "00197 "00268 "00197 % LATIN CAPITAL LETTER I WITH STROKE
+\setXTXcharcodes "00198 "00199 "00198 % LATIN CAPITAL LETTER K WITH HOOK
+\setXTXcharcodes "00199 "00199 "00198 % LATIN SMALL LETTER K WITH HOOK
+\setXTXcharcodes "0019A "0019A "0023D % LATIN SMALL LETTER L WITH BAR
+\setXTXcharcodes "0019B "0019B "0019B % LATIN SMALL LETTER LAMBDA WITH STROKE
+\setXTXcharcodes "0019C "0026F "0019C % LATIN CAPITAL LETTER TURNED M
+\setXTXcharcodes "0019D "00272 "0019D % LATIN CAPITAL LETTER N WITH LEFT HOOK
+\setXTXcharcodes "0019E "0019E "00220 % LATIN SMALL LETTER N WITH LONG RIGHT LEG
+\setXTXcharcodes "0019F "00275 "0019F % LATIN CAPITAL LETTER O WITH MIDDLE TILDE
+\setXTXcharcodes "001A0 "001A1 "001A0 % LATIN CAPITAL LETTER O WITH HORN
+\setXTXcharcodes "001A1 "001A1 "001A0 % LATIN SMALL LETTER O WITH HORN
+\setXTXcharcodes "001A2 "001A3 "001A2 % LATIN CAPITAL LETTER OI
+\setXTXcharcodes "001A3 "001A3 "001A2 % LATIN SMALL LETTER OI
+\setXTXcharcodes "001A4 "001A5 "001A4 % LATIN CAPITAL LETTER P WITH HOOK
+\setXTXcharcodes "001A5 "001A5 "001A4 % LATIN SMALL LETTER P WITH HOOK
+\setXTXcharcodes "001A6 "00280 "001A6 % LATIN LETTER YR
+\setXTXcharcodes "001A7 "001A8 "001A7 % LATIN CAPITAL LETTER TONE TWO
+\setXTXcharcodes "001A8 "001A8 "001A7 % LATIN SMALL LETTER TONE TWO
+\setXTXcharcodes "001A9 "00283 "001A9 % LATIN CAPITAL LETTER ESH
+\setXTXcharcodes "001AA "001AA "001AA % LATIN LETTER REVERSED ESH LOOP
+\setXTXcharcodes "001AB "001AB "001AB % LATIN SMALL LETTER T WITH PALATAL HOOK
+\setXTXcharcodes "001AC "001AD "001AC % LATIN CAPITAL LETTER T WITH HOOK
+\setXTXcharcodes "001AD "001AD "001AC % LATIN SMALL LETTER T WITH HOOK
+\setXTXcharcodes "001AE "00288 "001AE % LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
+\setXTXcharcodes "001AF "001B0 "001AF % LATIN CAPITAL LETTER U WITH HORN
+\setXTXcharcodes "001B0 "001B0 "001AF % LATIN SMALL LETTER U WITH HORN
+\setXTXcharcodes "001B1 "0028A "001B1 % LATIN CAPITAL LETTER UPSILON
+\setXTXcharcodes "001B2 "0028B "001B2 % LATIN CAPITAL LETTER V WITH HOOK
+\setXTXcharcodes "001B3 "001B4 "001B3 % LATIN CAPITAL LETTER Y WITH HOOK
+\setXTXcharcodes "001B4 "001B4 "001B3 % LATIN SMALL LETTER Y WITH HOOK
+\setXTXcharcodes "001B5 "001B6 "001B5 % LATIN CAPITAL LETTER Z WITH STROKE
+\setXTXcharcodes "001B6 "001B6 "001B5 % LATIN SMALL LETTER Z WITH STROKE
+\setXTXcharcodes "001B7 "00292 "001B7 % LATIN CAPITAL LETTER EZH
+\setXTXcharcodes "001B8 "001B9 "001B8 % LATIN CAPITAL LETTER EZH REVERSED
+\setXTXcharcodes "001B9 "001B9 "001B8 % LATIN SMALL LETTER EZH REVERSED
+\setXTXcharcodes "001BA "001BA "001BA % LATIN SMALL LETTER EZH WITH TAIL
+\setXTXcharcodes "001BC "001BD "001BC % LATIN CAPITAL LETTER TONE FIVE
+\setXTXcharcodes "001BD "001BD "001BC % LATIN SMALL LETTER TONE FIVE
+\setXTXcharcodes "001BE "001BE "001BE % LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE
+\setXTXcharcodes "001BF "001BF "001F7 % LATIN LETTER WYNN
+\setXTXcharcodes "001C4 "001C6 "001C5 % LATIN CAPITAL LETTER DZ WITH CARON
+\setXTXcharcodes "001C5 "001C6 "001C4 % LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+\setXTXcharcodes "001C6 "001C6 "001C4 % LATIN SMALL LETTER DZ WITH CARON
+\setXTXcharcodes "001C7 "001C9 "001C8 % LATIN CAPITAL LETTER LJ
+\setXTXcharcodes "001C8 "001C9 "001C7 % LATIN CAPITAL LETTER L WITH SMALL LETTER J
+\setXTXcharcodes "001C9 "001C9 "001C7 % LATIN SMALL LETTER LJ
+\setXTXcharcodes "001CA "001CC "001CB % LATIN CAPITAL LETTER NJ
+\setXTXcharcodes "001CB "001CC "001CA % LATIN CAPITAL LETTER N WITH SMALL LETTER J
+\setXTXcharcodes "001CC "001CC "001CA % LATIN SMALL LETTER NJ
+\setXTXcharcodes "001CD "001CE "001CD % LATIN CAPITAL LETTER A WITH CARON
+\setXTXcharcodes "001CE "001CE "001CD % LATIN SMALL LETTER A WITH CARON
+\setXTXcharcodes "001CF "001D0 "001CF % LATIN CAPITAL LETTER I WITH CARON
+\setXTXcharcodes "001D0 "001D0 "001CF % LATIN SMALL LETTER I WITH CARON
+\setXTXcharcodes "001D1 "001D2 "001D1 % LATIN CAPITAL LETTER O WITH CARON
+\setXTXcharcodes "001D2 "001D2 "001D1 % LATIN SMALL LETTER O WITH CARON
+\setXTXcharcodes "001D3 "001D4 "001D3 % LATIN CAPITAL LETTER U WITH CARON
+\setXTXcharcodes "001D4 "001D4 "001D3 % LATIN SMALL LETTER U WITH CARON
+\setXTXcharcodes "001D5 "001D6 "001D5 % LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+\setXTXcharcodes "001D6 "001D6 "001D5 % LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+\setXTXcharcodes "001D7 "001D8 "001D7 % LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+\setXTXcharcodes "001D8 "001D8 "001D7 % LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+\setXTXcharcodes "001D9 "001DA "001D9 % LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+\setXTXcharcodes "001DA "001DA "001D9 % LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+\setXTXcharcodes "001DB "001DC "001DB % LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+\setXTXcharcodes "001DC "001DC "001DB % LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+\setXTXcharcodes "001DD "001DD "0018E % LATIN SMALL LETTER TURNED E
+\setXTXcharcodes "001DE "001DF "001DE % LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
+\setXTXcharcodes "001DF "001DF "001DE % LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
+\setXTXcharcodes "001E0 "001E1 "001E0 % LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
+\setXTXcharcodes "001E1 "001E1 "001E0 % LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
+\setXTXcharcodes "001E2 "001E3 "001E2 % LATIN CAPITAL LETTER AE WITH MACRON
+\setXTXcharcodes "001E3 "001E3 "001E2 % LATIN SMALL LETTER AE WITH MACRON
+\setXTXcharcodes "001E4 "001E5 "001E4 % LATIN CAPITAL LETTER G WITH STROKE
+\setXTXcharcodes "001E5 "001E5 "001E4 % LATIN SMALL LETTER G WITH STROKE
+\setXTXcharcodes "001E6 "001E7 "001E6 % LATIN CAPITAL LETTER G WITH CARON
+\setXTXcharcodes "001E7 "001E7 "001E6 % LATIN SMALL LETTER G WITH CARON
+\setXTXcharcodes "001E8 "001E9 "001E8 % LATIN CAPITAL LETTER K WITH CARON
+\setXTXcharcodes "001E9 "001E9 "001E8 % LATIN SMALL LETTER K WITH CARON
+\setXTXcharcodes "001EA "001EB "001EA % LATIN CAPITAL LETTER O WITH OGONEK
+\setXTXcharcodes "001EB "001EB "001EA % LATIN SMALL LETTER O WITH OGONEK
+\setXTXcharcodes "001EC "001ED "001EC % LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
+\setXTXcharcodes "001ED "001ED "001EC % LATIN SMALL LETTER O WITH OGONEK AND MACRON
+\setXTXcharcodes "001EE "001EF "001EE % LATIN CAPITAL LETTER EZH WITH CARON
+\setXTXcharcodes "001EF "001EF "001EE % LATIN SMALL LETTER EZH WITH CARON
+\setXTXcharcodes "001F0 "001F0 "001F0 % LATIN SMALL LETTER J WITH CARON
+\setXTXcharcodes "001F1 "001F3 "001F2 % LATIN CAPITAL LETTER DZ
+\setXTXcharcodes "001F2 "001F3 "001F1 % LATIN CAPITAL LETTER D WITH SMALL LETTER Z
+\setXTXcharcodes "001F3 "001F3 "001F1 % LATIN SMALL LETTER DZ
+\setXTXcharcodes "001F4 "001F5 "001F4 % LATIN CAPITAL LETTER G WITH ACUTE
+\setXTXcharcodes "001F5 "001F5 "001F4 % LATIN SMALL LETTER G WITH ACUTE
+\setXTXcharcodes "001F6 "00195 "001F6 % LATIN CAPITAL LETTER HWAIR
+\setXTXcharcodes "001F7 "001BF "001F7 % LATIN CAPITAL LETTER WYNN
+\setXTXcharcodes "001F8 "001F9 "001F8 % LATIN CAPITAL LETTER N WITH GRAVE
+\setXTXcharcodes "001F9 "001F9 "001F8 % LATIN SMALL LETTER N WITH GRAVE
+\setXTXcharcodes "001FA "001FB "001FA % LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
+\setXTXcharcodes "001FB "001FB "001FA % LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
+\setXTXcharcodes "001FC "001FD "001FC % LATIN CAPITAL LETTER AE WITH ACUTE
+\setXTXcharcodes "001FD "001FD "001FC % LATIN SMALL LETTER AE WITH ACUTE
+\setXTXcharcodes "001FE "001FF "001FE % LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
+\setXTXcharcodes "001FF "001FF "001FE % LATIN SMALL LETTER O WITH STROKE AND ACUTE
+\setXTXcharcodes "00200 "00201 "00200 % LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
+\setXTXcharcodes "00201 "00201 "00200 % LATIN SMALL LETTER A WITH DOUBLE GRAVE
+\setXTXcharcodes "00202 "00203 "00202 % LATIN CAPITAL LETTER A WITH INVERTED BREVE
+\setXTXcharcodes "00203 "00203 "00202 % LATIN SMALL LETTER A WITH INVERTED BREVE
+\setXTXcharcodes "00204 "00205 "00204 % LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
+\setXTXcharcodes "00205 "00205 "00204 % LATIN SMALL LETTER E WITH DOUBLE GRAVE
+\setXTXcharcodes "00206 "00207 "00206 % LATIN CAPITAL LETTER E WITH INVERTED BREVE
+\setXTXcharcodes "00207 "00207 "00206 % LATIN SMALL LETTER E WITH INVERTED BREVE
+\setXTXcharcodes "00208 "00209 "00208 % LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
+\setXTXcharcodes "00209 "00209 "00208 % LATIN SMALL LETTER I WITH DOUBLE GRAVE
+\setXTXcharcodes "0020A "0020B "0020A % LATIN CAPITAL LETTER I WITH INVERTED BREVE
+\setXTXcharcodes "0020B "0020B "0020A % LATIN SMALL LETTER I WITH INVERTED BREVE
+\setXTXcharcodes "0020C "0020D "0020C % LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
+\setXTXcharcodes "0020D "0020D "0020C % LATIN SMALL LETTER O WITH DOUBLE GRAVE
+\setXTXcharcodes "0020E "0020F "0020E % LATIN CAPITAL LETTER O WITH INVERTED BREVE
+\setXTXcharcodes "0020F "0020F "0020E % LATIN SMALL LETTER O WITH INVERTED BREVE
+\setXTXcharcodes "00210 "00211 "00210 % LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
+\setXTXcharcodes "00211 "00211 "00210 % LATIN SMALL LETTER R WITH DOUBLE GRAVE
+\setXTXcharcodes "00212 "00213 "00212 % LATIN CAPITAL LETTER R WITH INVERTED BREVE
+\setXTXcharcodes "00213 "00213 "00212 % LATIN SMALL LETTER R WITH INVERTED BREVE
+\setXTXcharcodes "00214 "00215 "00214 % LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
+\setXTXcharcodes "00215 "00215 "00214 % LATIN SMALL LETTER U WITH DOUBLE GRAVE
+\setXTXcharcodes "00216 "00217 "00216 % LATIN CAPITAL LETTER U WITH INVERTED BREVE
+\setXTXcharcodes "00217 "00217 "00216 % LATIN SMALL LETTER U WITH INVERTED BREVE
+\setXTXcharcodes "00218 "00219 "00218 % LATIN CAPITAL LETTER S WITH COMMA BELOW
+\setXTXcharcodes "00219 "00219 "00218 % LATIN SMALL LETTER S WITH COMMA BELOW
+\setXTXcharcodes "0021A "0021B "0021A % LATIN CAPITAL LETTER T WITH COMMA BELOW
+\setXTXcharcodes "0021B "0021B "0021A % LATIN SMALL LETTER T WITH COMMA BELOW
+\setXTXcharcodes "0021C "0021D "0021C % LATIN CAPITAL LETTER YOGH
+\setXTXcharcodes "0021D "0021D "0021C % LATIN SMALL LETTER YOGH
+\setXTXcharcodes "0021E "0021F "0021E % LATIN CAPITAL LETTER H WITH CARON
+\setXTXcharcodes "0021F "0021F "0021E % LATIN SMALL LETTER H WITH CARON
+\setXTXcharcodes "00220 "0019E "00220 % LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
+\setXTXcharcodes "00221 "00221 "00221 % LATIN SMALL LETTER D WITH CURL
+\setXTXcharcodes "00222 "00223 "00222 % LATIN CAPITAL LETTER OU
+\setXTXcharcodes "00223 "00223 "00222 % LATIN SMALL LETTER OU
+\setXTXcharcodes "00224 "00225 "00224 % LATIN CAPITAL LETTER Z WITH HOOK
+\setXTXcharcodes "00225 "00225 "00224 % LATIN SMALL LETTER Z WITH HOOK
+\setXTXcharcodes "00226 "00227 "00226 % LATIN CAPITAL LETTER A WITH DOT ABOVE
+\setXTXcharcodes "00227 "00227 "00226 % LATIN SMALL LETTER A WITH DOT ABOVE
+\setXTXcharcodes "00228 "00229 "00228 % LATIN CAPITAL LETTER E WITH CEDILLA
+\setXTXcharcodes "00229 "00229 "00228 % LATIN SMALL LETTER E WITH CEDILLA
+\setXTXcharcodes "0022A "0022B "0022A % LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
+\setXTXcharcodes "0022B "0022B "0022A % LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
+\setXTXcharcodes "0022C "0022D "0022C % LATIN CAPITAL LETTER O WITH TILDE AND MACRON
+\setXTXcharcodes "0022D "0022D "0022C % LATIN SMALL LETTER O WITH TILDE AND MACRON
+\setXTXcharcodes "0022E "0022F "0022E % LATIN CAPITAL LETTER O WITH DOT ABOVE
+\setXTXcharcodes "0022F "0022F "0022E % LATIN SMALL LETTER O WITH DOT ABOVE
+\setXTXcharcodes "00230 "00231 "00230 % LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
+\setXTXcharcodes "00231 "00231 "00230 % LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
+\setXTXcharcodes "00232 "00233 "00232 % LATIN CAPITAL LETTER Y WITH MACRON
+\setXTXcharcodes "00233 "00233 "00232 % LATIN SMALL LETTER Y WITH MACRON
+\setXTXcharcodes "00234 "00234 "00234 % LATIN SMALL LETTER L WITH CURL
+\setXTXcharcodes "00235 "00235 "00235 % LATIN SMALL LETTER N WITH CURL
+\setXTXcharcodes "00236 "00236 "00236 % LATIN SMALL LETTER T WITH CURL
+\setXTXcharcodes "00237 "00237 "00237 % LATIN SMALL LETTER DOTLESS J
+\setXTXcharcodes "00238 "00238 "00238 % LATIN SMALL LETTER DB DIGRAPH
+\setXTXcharcodes "00239 "00239 "00239 % LATIN SMALL LETTER QP DIGRAPH
+\setXTXcharcodes "0023A "02C65 "0023A % LATIN CAPITAL LETTER A WITH STROKE
+\setXTXcharcodes "0023B "0023C "0023B % LATIN CAPITAL LETTER C WITH STROKE
+\setXTXcharcodes "0023C "0023C "0023B % LATIN SMALL LETTER C WITH STROKE
+\setXTXcharcodes "0023D "0019A "0023D % LATIN CAPITAL LETTER L WITH BAR
+\setXTXcharcodes "0023E "02C66 "0023E % LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
+\setXTXcharcodes "0023F "0023F "0023F % LATIN SMALL LETTER S WITH SWASH TAIL
+\setXTXcharcodes "00240 "00240 "00240 % LATIN SMALL LETTER Z WITH SWASH TAIL
+\setXTXcharcodes "00241 "00242 "00241 % LATIN CAPITAL LETTER GLOTTAL STOP
+\setXTXcharcodes "00242 "00242 "00241 % LATIN SMALL LETTER GLOTTAL STOP
+\setXTXcharcodes "00243 "00180 "00243 % LATIN CAPITAL LETTER B WITH STROKE
+\setXTXcharcodes "00244 "00289 "00244 % LATIN CAPITAL LETTER U BAR
+\setXTXcharcodes "00245 "0028C "00245 % LATIN CAPITAL LETTER TURNED V
+\setXTXcharcodes "00246 "00247 "00246 % LATIN CAPITAL LETTER E WITH STROKE
+\setXTXcharcodes "00247 "00247 "00246 % LATIN SMALL LETTER E WITH STROKE
+\setXTXcharcodes "00248 "00249 "00248 % LATIN CAPITAL LETTER J WITH STROKE
+\setXTXcharcodes "00249 "00249 "00248 % LATIN SMALL LETTER J WITH STROKE
+\setXTXcharcodes "0024A "0024B "0024A % LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
+\setXTXcharcodes "0024B "0024B "0024A % LATIN SMALL LETTER Q WITH HOOK TAIL
+\setXTXcharcodes "0024C "0024D "0024C % LATIN CAPITAL LETTER R WITH STROKE
+\setXTXcharcodes "0024D "0024D "0024C % LATIN SMALL LETTER R WITH STROKE
+\setXTXcharcodes "0024E "0024F "0024E % LATIN CAPITAL LETTER Y WITH STROKE
+\setXTXcharcodes "0024F "0024F "0024E % LATIN SMALL LETTER Y WITH STROKE
+\setXTXcharcodes "00250 "00250 "00250 % LATIN SMALL LETTER TURNED A
+\setXTXcharcodes "00251 "00251 "00251 % LATIN SMALL LETTER ALPHA
+\setXTXcharcodes "00252 "00252 "00252 % LATIN SMALL LETTER TURNED ALPHA
+\setXTXcharcodes "00253 "00253 "00181 % LATIN SMALL LETTER B WITH HOOK
+\setXTXcharcodes "00254 "00254 "00186 % LATIN SMALL LETTER OPEN O
+\setXTXcharcodes "00255 "00255 "00255 % LATIN SMALL LETTER C WITH CURL
+\setXTXcharcodes "00256 "00256 "00189 % LATIN SMALL LETTER D WITH TAIL
+\setXTXcharcodes "00257 "00257 "0018A % LATIN SMALL LETTER D WITH HOOK
+\setXTXcharcodes "00258 "00258 "00258 % LATIN SMALL LETTER REVERSED E
+\setXTXcharcodes "00259 "00259 "0018F % LATIN SMALL LETTER SCHWA
+\setXTXcharcodes "0025A "0025A "0025A % LATIN SMALL LETTER SCHWA WITH HOOK
+\setXTXcharcodes "0025B "0025B "00190 % LATIN SMALL LETTER OPEN E
+\setXTXcharcodes "0025C "0025C "0025C % LATIN SMALL LETTER REVERSED OPEN E
+\setXTXcharcodes "0025D "0025D "0025D % LATIN SMALL LETTER REVERSED OPEN E WITH HOOK
+\setXTXcharcodes "0025E "0025E "0025E % LATIN SMALL LETTER CLOSED REVERSED OPEN E
+\setXTXcharcodes "0025F "0025F "0025F % LATIN SMALL LETTER DOTLESS J WITH STROKE
+\setXTXcharcodes "00260 "00260 "00193 % LATIN SMALL LETTER G WITH HOOK
+\setXTXcharcodes "00261 "00261 "00261 % LATIN SMALL LETTER SCRIPT G
+\setXTXcharcodes "00262 "00262 "00262 % LATIN LETTER SMALL CAPITAL G
+\setXTXcharcodes "00263 "00263 "00194 % LATIN SMALL LETTER GAMMA
+\setXTXcharcodes "00264 "00264 "00264 % LATIN SMALL LETTER RAMS HORN
+\setXTXcharcodes "00265 "00265 "00265 % LATIN SMALL LETTER TURNED H
+\setXTXcharcodes "00266 "00266 "00266 % LATIN SMALL LETTER H WITH HOOK
+\setXTXcharcodes "00267 "00267 "00267 % LATIN SMALL LETTER HENG WITH HOOK
+\setXTXcharcodes "00268 "00268 "00197 % LATIN SMALL LETTER I WITH STROKE
+\setXTXcharcodes "00269 "00269 "00196 % LATIN SMALL LETTER IOTA
+\setXTXcharcodes "0026A "0026A "0026A % LATIN LETTER SMALL CAPITAL I
+\setXTXcharcodes "0026B "0026B "02C62 % LATIN SMALL LETTER L WITH MIDDLE TILDE
+\setXTXcharcodes "0026C "0026C "0026C % LATIN SMALL LETTER L WITH BELT
+\setXTXcharcodes "0026D "0026D "0026D % LATIN SMALL LETTER L WITH RETROFLEX HOOK
+\setXTXcharcodes "0026E "0026E "0026E % LATIN SMALL LETTER LEZH
+\setXTXcharcodes "0026F "0026F "0019C % LATIN SMALL LETTER TURNED M
+\setXTXcharcodes "00270 "00270 "00270 % LATIN SMALL LETTER TURNED M WITH LONG LEG
+\setXTXcharcodes "00271 "00271 "00271 % LATIN SMALL LETTER M WITH HOOK
+\setXTXcharcodes "00272 "00272 "0019D % LATIN SMALL LETTER N WITH LEFT HOOK
+\setXTXcharcodes "00273 "00273 "00273 % LATIN SMALL LETTER N WITH RETROFLEX HOOK
+\setXTXcharcodes "00274 "00274 "00274 % LATIN LETTER SMALL CAPITAL N
+\setXTXcharcodes "00275 "00275 "0019F % LATIN SMALL LETTER BARRED O
+\setXTXcharcodes "00276 "00276 "00276 % LATIN LETTER SMALL CAPITAL OE
+\setXTXcharcodes "00277 "00277 "00277 % LATIN SMALL LETTER CLOSED OMEGA
+\setXTXcharcodes "00278 "00278 "00278 % LATIN SMALL LETTER PHI
+\setXTXcharcodes "00279 "00279 "00279 % LATIN SMALL LETTER TURNED R
+\setXTXcharcodes "0027A "0027A "0027A % LATIN SMALL LETTER TURNED R WITH LONG LEG
+\setXTXcharcodes "0027B "0027B "0027B % LATIN SMALL LETTER TURNED R WITH HOOK
+\setXTXcharcodes "0027C "0027C "0027C % LATIN SMALL LETTER R WITH LONG LEG
+\setXTXcharcodes "0027D "0027D "02C64 % LATIN SMALL LETTER R WITH TAIL
+\setXTXcharcodes "0027E "0027E "0027E % LATIN SMALL LETTER R WITH FISHHOOK
+\setXTXcharcodes "0027F "0027F "0027F % LATIN SMALL LETTER REVERSED R WITH FISHHOOK
+\setXTXcharcodes "00280 "00280 "001A6 % LATIN LETTER SMALL CAPITAL R
+\setXTXcharcodes "00281 "00281 "00281 % LATIN LETTER SMALL CAPITAL INVERTED R
+\setXTXcharcodes "00282 "00282 "00282 % LATIN SMALL LETTER S WITH HOOK
+\setXTXcharcodes "00283 "00283 "001A9 % LATIN SMALL LETTER ESH
+\setXTXcharcodes "00284 "00284 "00284 % LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK
+\setXTXcharcodes "00285 "00285 "00285 % LATIN SMALL LETTER SQUAT REVERSED ESH
+\setXTXcharcodes "00286 "00286 "00286 % LATIN SMALL LETTER ESH WITH CURL
+\setXTXcharcodes "00287 "00287 "00287 % LATIN SMALL LETTER TURNED T
+\setXTXcharcodes "00288 "00288 "001AE % LATIN SMALL LETTER T WITH RETROFLEX HOOK
+\setXTXcharcodes "00289 "00289 "00244 % LATIN SMALL LETTER U BAR
+\setXTXcharcodes "0028A "0028A "001B1 % LATIN SMALL LETTER UPSILON
+\setXTXcharcodes "0028B "0028B "001B2 % LATIN SMALL LETTER V WITH HOOK
+\setXTXcharcodes "0028C "0028C "00245 % LATIN SMALL LETTER TURNED V
+\setXTXcharcodes "0028D "0028D "0028D % LATIN SMALL LETTER TURNED W
+\setXTXcharcodes "0028E "0028E "0028E % LATIN SMALL LETTER TURNED Y
+\setXTXcharcodes "0028F "0028F "0028F % LATIN LETTER SMALL CAPITAL Y
+\setXTXcharcodes "00290 "00290 "00290 % LATIN SMALL LETTER Z WITH RETROFLEX HOOK
+\setXTXcharcodes "00291 "00291 "00291 % LATIN SMALL LETTER Z WITH CURL
+\setXTXcharcodes "00292 "00292 "001B7 % LATIN SMALL LETTER EZH
+\setXTXcharcodes "00293 "00293 "00293 % LATIN SMALL LETTER EZH WITH CURL
+\setXTXcharcodes "00295 "00295 "00295 % LATIN LETTER PHARYNGEAL VOICED FRICATIVE
+\setXTXcharcodes "00296 "00296 "00296 % LATIN LETTER INVERTED GLOTTAL STOP
+\setXTXcharcodes "00297 "00297 "00297 % LATIN LETTER STRETCHED C
+\setXTXcharcodes "00298 "00298 "00298 % LATIN LETTER BILABIAL CLICK
+\setXTXcharcodes "00299 "00299 "00299 % LATIN LETTER SMALL CAPITAL B
+\setXTXcharcodes "0029A "0029A "0029A % LATIN SMALL LETTER CLOSED OPEN E
+\setXTXcharcodes "0029B "0029B "0029B % LATIN LETTER SMALL CAPITAL G WITH HOOK
+\setXTXcharcodes "0029C "0029C "0029C % LATIN LETTER SMALL CAPITAL H
+\setXTXcharcodes "0029D "0029D "0029D % LATIN SMALL LETTER J WITH CROSSED-TAIL
+\setXTXcharcodes "0029E "0029E "0029E % LATIN SMALL LETTER TURNED K
+\setXTXcharcodes "0029F "0029F "0029F % LATIN LETTER SMALL CAPITAL L
+\setXTXcharcodes "002A0 "002A0 "002A0 % LATIN SMALL LETTER Q WITH HOOK
+\setXTXcharcodes "002A1 "002A1 "002A1 % LATIN LETTER GLOTTAL STOP WITH STROKE
+\setXTXcharcodes "002A2 "002A2 "002A2 % LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE
+\setXTXcharcodes "002A3 "002A3 "002A3 % LATIN SMALL LETTER DZ DIGRAPH
+\setXTXcharcodes "002A4 "002A4 "002A4 % LATIN SMALL LETTER DEZH DIGRAPH
+\setXTXcharcodes "002A5 "002A5 "002A5 % LATIN SMALL LETTER DZ DIGRAPH WITH CURL
+\setXTXcharcodes "002A6 "002A6 "002A6 % LATIN SMALL LETTER TS DIGRAPH
+\setXTXcharcodes "002A7 "002A7 "002A7 % LATIN SMALL LETTER TESH DIGRAPH
+\setXTXcharcodes "002A8 "002A8 "002A8 % LATIN SMALL LETTER TC DIGRAPH WITH CURL
+\setXTXcharcodes "002A9 "002A9 "002A9 % LATIN SMALL LETTER FENG DIGRAPH
+\setXTXcharcodes "002AA "002AA "002AA % LATIN SMALL LETTER LS DIGRAPH
+\setXTXcharcodes "002AB "002AB "002AB % LATIN SMALL LETTER LZ DIGRAPH
+\setXTXcharcodes "002AC "002AC "002AC % LATIN LETTER BILABIAL PERCUSSIVE
+\setXTXcharcodes "002AD "002AD "002AD % LATIN LETTER BIDENTAL PERCUSSIVE
+\setXTXcharcodes "002AE "002AE "002AE % LATIN SMALL LETTER TURNED H WITH FISHHOOK
+\setXTXcharcodes "002AF "002AF "002AF % LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
+\setXTXcharcodes "0037B "0037B "003FD % GREEK SMALL REVERSED LUNATE SIGMA SYMBOL
+\setXTXcharcodes "0037C "0037C "003FE % GREEK SMALL DOTTED LUNATE SIGMA SYMBOL
+\setXTXcharcodes "0037D "0037D "003FF % GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
+\setXTXcharcodes "00386 "003AC "00386 % GREEK CAPITAL LETTER ALPHA WITH TONOS
+\setXTXcharcodes "00388 "003AD "00388 % GREEK CAPITAL LETTER EPSILON WITH TONOS
+\setXTXcharcodes "00389 "003AE "00389 % GREEK CAPITAL LETTER ETA WITH TONOS
+\setXTXcharcodes "0038A "003AF "0038A % GREEK CAPITAL LETTER IOTA WITH TONOS
+\setXTXcharcodes "0038C "003CC "0038C % GREEK CAPITAL LETTER OMICRON WITH TONOS
+\setXTXcharcodes "0038E "003CD "0038E % GREEK CAPITAL LETTER UPSILON WITH TONOS
+\setXTXcharcodes "0038F "003CE "0038F % GREEK CAPITAL LETTER OMEGA WITH TONOS
+\setXTXcharcodes "00390 "00390 "00390 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+\setXTXcharcodes "00391 "003B1 "00391 % GREEK CAPITAL LETTER ALPHA
+\setXTXcharcodes "00392 "003B2 "00392 % GREEK CAPITAL LETTER BETA
+\setXTXcharcodes "00393 "003B3 "00393 % GREEK CAPITAL LETTER GAMMA
+\setXTXcharcodes "00394 "003B4 "00394 % GREEK CAPITAL LETTER DELTA
+\setXTXcharcodes "00395 "003B5 "00395 % GREEK CAPITAL LETTER EPSILON
+\setXTXcharcodes "00396 "003B6 "00396 % GREEK CAPITAL LETTER ZETA
+\setXTXcharcodes "00397 "003B7 "00397 % GREEK CAPITAL LETTER ETA
+\setXTXcharcodes "00398 "003B8 "00398 % GREEK CAPITAL LETTER THETA
+\setXTXcharcodes "00399 "003B9 "00399 % GREEK CAPITAL LETTER IOTA
+\setXTXcharcodes "0039A "003BA "0039A % GREEK CAPITAL LETTER KAPPA
+\setXTXcharcodes "0039B "003BB "0039B % GREEK CAPITAL LETTER LAMDA
+\setXTXcharcodes "0039C "003BC "0039C % GREEK CAPITAL LETTER MU
+\setXTXcharcodes "0039D "003BD "0039D % GREEK CAPITAL LETTER NU
+\setXTXcharcodes "0039E "003BE "0039E % GREEK CAPITAL LETTER XI
+\setXTXcharcodes "0039F "003BF "0039F % GREEK CAPITAL LETTER OMICRON
+\setXTXcharcodes "003A0 "003C0 "003A0 % GREEK CAPITAL LETTER PI
+\setXTXcharcodes "003A1 "003C1 "003A1 % GREEK CAPITAL LETTER RHO
+\setXTXcharcodes "003A3 "003C3 "003A3 % GREEK CAPITAL LETTER SIGMA
+\setXTXcharcodes "003A4 "003C4 "003A4 % GREEK CAPITAL LETTER TAU
+\setXTXcharcodes "003A5 "003C5 "003A5 % GREEK CAPITAL LETTER UPSILON
+\setXTXcharcodes "003A6 "003C6 "003A6 % GREEK CAPITAL LETTER PHI
+\setXTXcharcodes "003A7 "003C7 "003A7 % GREEK CAPITAL LETTER CHI
+\setXTXcharcodes "003A8 "003C8 "003A8 % GREEK CAPITAL LETTER PSI
+\setXTXcharcodes "003A9 "003C9 "003A9 % GREEK CAPITAL LETTER OMEGA
+\setXTXcharcodes "003AA "003CA "003AA % GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+\setXTXcharcodes "003AB "003CB "003AB % GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+\setXTXcharcodes "003AC "003AC "00386 % GREEK SMALL LETTER ALPHA WITH TONOS
+\setXTXcharcodes "003AD "003AD "00388 % GREEK SMALL LETTER EPSILON WITH TONOS
+\setXTXcharcodes "003AE "003AE "00389 % GREEK SMALL LETTER ETA WITH TONOS
+\setXTXcharcodes "003AF "003AF "0038A % GREEK SMALL LETTER IOTA WITH TONOS
+\setXTXcharcodes "003B0 "003B0 "003B0 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+\setXTXcharcodes "003B1 "003B1 "00391 % GREEK SMALL LETTER ALPHA
+\setXTXcharcodes "003B2 "003B2 "00392 % GREEK SMALL LETTER BETA
+\setXTXcharcodes "003B3 "003B3 "00393 % GREEK SMALL LETTER GAMMA
+\setXTXcharcodes "003B4 "003B4 "00394 % GREEK SMALL LETTER DELTA
+\setXTXcharcodes "003B5 "003B5 "00395 % GREEK SMALL LETTER EPSILON
+\setXTXcharcodes "003B6 "003B6 "00396 % GREEK SMALL LETTER ZETA
+\setXTXcharcodes "003B7 "003B7 "00397 % GREEK SMALL LETTER ETA
+\setXTXcharcodes "003B8 "003B8 "00398 % GREEK SMALL LETTER THETA
+\setXTXcharcodes "003B9 "003B9 "00399 % GREEK SMALL LETTER IOTA
+\setXTXcharcodes "003BA "003BA "0039A % GREEK SMALL LETTER KAPPA
+\setXTXcharcodes "003BB "003BB "0039B % GREEK SMALL LETTER LAMDA
+\setXTXcharcodes "003BC "003BC "0039C % GREEK SMALL LETTER MU
+\setXTXcharcodes "003BD "003BD "0039D % GREEK SMALL LETTER NU
+\setXTXcharcodes "003BE "003BE "0039E % GREEK SMALL LETTER XI
+\setXTXcharcodes "003BF "003BF "0039F % GREEK SMALL LETTER OMICRON
+\setXTXcharcodes "003C0 "003C0 "003A0 % GREEK SMALL LETTER PI
+\setXTXcharcodes "003C1 "003C1 "003A1 % GREEK SMALL LETTER RHO
+\setXTXcharcodes "003C2 "003C2 "003A3 % GREEK SMALL LETTER FINAL SIGMA
+\setXTXcharcodes "003C3 "003C3 "003A3 % GREEK SMALL LETTER SIGMA
+\setXTXcharcodes "003C4 "003C4 "003A4 % GREEK SMALL LETTER TAU
+\setXTXcharcodes "003C5 "003C5 "003A5 % GREEK SMALL LETTER UPSILON
+\setXTXcharcodes "003C6 "003C6 "003A6 % GREEK SMALL LETTER PHI
+\setXTXcharcodes "003C7 "003C7 "003A7 % GREEK SMALL LETTER CHI
+\setXTXcharcodes "003C8 "003C8 "003A8 % GREEK SMALL LETTER PSI
+\setXTXcharcodes "003C9 "003C9 "003A9 % GREEK SMALL LETTER OMEGA
+\setXTXcharcodes "003CA "003CA "003AA % GREEK SMALL LETTER IOTA WITH DIALYTIKA
+\setXTXcharcodes "003CB "003CB "003AB % GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+\setXTXcharcodes "003CC "003CC "0038C % GREEK SMALL LETTER OMICRON WITH TONOS
+\setXTXcharcodes "003CD "003CD "0038E % GREEK SMALL LETTER UPSILON WITH TONOS
+\setXTXcharcodes "003CE "003CE "0038F % GREEK SMALL LETTER OMEGA WITH TONOS
+\setXTXcharcodes "003D0 "003D0 "00392 % GREEK BETA SYMBOL
+\setXTXcharcodes "003D1 "003D1 "00398 % GREEK THETA SYMBOL
+\setXTXcharcodes "003D2 "003D2 "003D2 % GREEK UPSILON WITH HOOK SYMBOL
+\setXTXcharcodes "003D3 "003D3 "003D3 % GREEK UPSILON WITH ACUTE AND HOOK SYMBOL
+\setXTXcharcodes "003D4 "003D4 "003D4 % GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL
+\setXTXcharcodes "003D5 "003D5 "003A6 % GREEK PHI SYMBOL
+\setXTXcharcodes "003D6 "003D6 "003A0 % GREEK PI SYMBOL
+\setXTXcharcodes "003D7 "003D7 "003D7 % GREEK KAI SYMBOL
+\setXTXcharcodes "003D8 "003D9 "003D8 % GREEK LETTER ARCHAIC KOPPA
+\setXTXcharcodes "003D9 "003D9 "003D8 % GREEK SMALL LETTER ARCHAIC KOPPA
+\setXTXcharcodes "003DA "003DB "003DA % GREEK LETTER STIGMA
+\setXTXcharcodes "003DB "003DB "003DA % GREEK SMALL LETTER STIGMA
+\setXTXcharcodes "003DC "003DD "003DC % GREEK LETTER DIGAMMA
+\setXTXcharcodes "003DD "003DD "003DC % GREEK SMALL LETTER DIGAMMA
+\setXTXcharcodes "003DE "003DF "003DE % GREEK LETTER KOPPA
+\setXTXcharcodes "003DF "003DF "003DE % GREEK SMALL LETTER KOPPA
+\setXTXcharcodes "003E0 "003E1 "003E0 % GREEK LETTER SAMPI
+\setXTXcharcodes "003E1 "003E1 "003E0 % GREEK SMALL LETTER SAMPI
+\setXTXcharcodes "003E2 "003E3 "003E2 % COPTIC CAPITAL LETTER SHEI
+\setXTXcharcodes "003E3 "003E3 "003E2 % COPTIC SMALL LETTER SHEI
+\setXTXcharcodes "003E4 "003E5 "003E4 % COPTIC CAPITAL LETTER FEI
+\setXTXcharcodes "003E5 "003E5 "003E4 % COPTIC SMALL LETTER FEI
+\setXTXcharcodes "003E6 "003E7 "003E6 % COPTIC CAPITAL LETTER KHEI
+\setXTXcharcodes "003E7 "003E7 "003E6 % COPTIC SMALL LETTER KHEI
+\setXTXcharcodes "003E8 "003E9 "003E8 % COPTIC CAPITAL LETTER HORI
+\setXTXcharcodes "003E9 "003E9 "003E8 % COPTIC SMALL LETTER HORI
+\setXTXcharcodes "003EA "003EB "003EA % COPTIC CAPITAL LETTER GANGIA
+\setXTXcharcodes "003EB "003EB "003EA % COPTIC SMALL LETTER GANGIA
+\setXTXcharcodes "003EC "003ED "003EC % COPTIC CAPITAL LETTER SHIMA
+\setXTXcharcodes "003ED "003ED "003EC % COPTIC SMALL LETTER SHIMA
+\setXTXcharcodes "003EE "003EF "003EE % COPTIC CAPITAL LETTER DEI
+\setXTXcharcodes "003EF "003EF "003EE % COPTIC SMALL LETTER DEI
+\setXTXcharcodes "003F0 "003F0 "0039A % GREEK KAPPA SYMBOL
+\setXTXcharcodes "003F1 "003F1 "003A1 % GREEK RHO SYMBOL
+\setXTXcharcodes "003F2 "003F2 "003F9 % GREEK LUNATE SIGMA SYMBOL
+\setXTXcharcodes "003F3 "003F3 "003F3 % GREEK LETTER YOT
+\setXTXcharcodes "003F4 "003B8 "003F4 % GREEK CAPITAL THETA SYMBOL
+\setXTXcharcodes "003F5 "003F5 "00395 % GREEK LUNATE EPSILON SYMBOL
+\setXTXcharcodes "003F7 "003F8 "003F7 % GREEK CAPITAL LETTER SHO
+\setXTXcharcodes "003F8 "003F8 "003F7 % GREEK SMALL LETTER SHO
+\setXTXcharcodes "003F9 "003F2 "003F9 % GREEK CAPITAL LUNATE SIGMA SYMBOL
+\setXTXcharcodes "003FA "003FB "003FA % GREEK CAPITAL LETTER SAN
+\setXTXcharcodes "003FB "003FB "003FA % GREEK SMALL LETTER SAN
+\setXTXcharcodes "003FC "003FC "003FC % GREEK RHO WITH STROKE SYMBOL
+\setXTXcharcodes "003FD "0037B "003FD % GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
+\setXTXcharcodes "003FE "0037C "003FE % GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
+\setXTXcharcodes "003FF "0037D "003FF % GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+\setXTXcharcodes "00400 "00450 "00400 % CYRILLIC CAPITAL LETTER IE WITH GRAVE
+\setXTXcharcodes "00401 "00451 "00401 % CYRILLIC CAPITAL LETTER IO
+\setXTXcharcodes "00402 "00452 "00402 % CYRILLIC CAPITAL LETTER DJE
+\setXTXcharcodes "00403 "00453 "00403 % CYRILLIC CAPITAL LETTER GJE
+\setXTXcharcodes "00404 "00454 "00404 % CYRILLIC CAPITAL LETTER UKRAINIAN IE
+\setXTXcharcodes "00405 "00455 "00405 % CYRILLIC CAPITAL LETTER DZE
+\setXTXcharcodes "00406 "00456 "00406 % CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+\setXTXcharcodes "00407 "00457 "00407 % CYRILLIC CAPITAL LETTER YI
+\setXTXcharcodes "00408 "00458 "00408 % CYRILLIC CAPITAL LETTER JE
+\setXTXcharcodes "00409 "00459 "00409 % CYRILLIC CAPITAL LETTER LJE
+\setXTXcharcodes "0040A "0045A "0040A % CYRILLIC CAPITAL LETTER NJE
+\setXTXcharcodes "0040B "0045B "0040B % CYRILLIC CAPITAL LETTER TSHE
+\setXTXcharcodes "0040C "0045C "0040C % CYRILLIC CAPITAL LETTER KJE
+\setXTXcharcodes "0040D "0045D "0040D % CYRILLIC CAPITAL LETTER I WITH GRAVE
+\setXTXcharcodes "0040E "0045E "0040E % CYRILLIC CAPITAL LETTER SHORT U
+\setXTXcharcodes "0040F "0045F "0040F % CYRILLIC CAPITAL LETTER DZHE
+\setXTXcharcodes "00410 "00430 "00410 % CYRILLIC CAPITAL LETTER A
+\setXTXcharcodes "00411 "00431 "00411 % CYRILLIC CAPITAL LETTER BE
+\setXTXcharcodes "00412 "00432 "00412 % CYRILLIC CAPITAL LETTER VE
+\setXTXcharcodes "00413 "00433 "00413 % CYRILLIC CAPITAL LETTER GHE
+\setXTXcharcodes "00414 "00434 "00414 % CYRILLIC CAPITAL LETTER DE
+\setXTXcharcodes "00415 "00435 "00415 % CYRILLIC CAPITAL LETTER IE
+\setXTXcharcodes "00416 "00436 "00416 % CYRILLIC CAPITAL LETTER ZHE
+\setXTXcharcodes "00417 "00437 "00417 % CYRILLIC CAPITAL LETTER ZE
+\setXTXcharcodes "00418 "00438 "00418 % CYRILLIC CAPITAL LETTER I
+\setXTXcharcodes "00419 "00439 "00419 % CYRILLIC CAPITAL LETTER SHORT I
+\setXTXcharcodes "0041A "0043A "0041A % CYRILLIC CAPITAL LETTER KA
+\setXTXcharcodes "0041B "0043B "0041B % CYRILLIC CAPITAL LETTER EL
+\setXTXcharcodes "0041C "0043C "0041C % CYRILLIC CAPITAL LETTER EM
+\setXTXcharcodes "0041D "0043D "0041D % CYRILLIC CAPITAL LETTER EN
+\setXTXcharcodes "0041E "0043E "0041E % CYRILLIC CAPITAL LETTER O
+\setXTXcharcodes "0041F "0043F "0041F % CYRILLIC CAPITAL LETTER PE
+\setXTXcharcodes "00420 "00440 "00420 % CYRILLIC CAPITAL LETTER ER
+\setXTXcharcodes "00421 "00441 "00421 % CYRILLIC CAPITAL LETTER ES
+\setXTXcharcodes "00422 "00442 "00422 % CYRILLIC CAPITAL LETTER TE
+\setXTXcharcodes "00423 "00443 "00423 % CYRILLIC CAPITAL LETTER U
+\setXTXcharcodes "00424 "00444 "00424 % CYRILLIC CAPITAL LETTER EF
+\setXTXcharcodes "00425 "00445 "00425 % CYRILLIC CAPITAL LETTER HA
+\setXTXcharcodes "00426 "00446 "00426 % CYRILLIC CAPITAL LETTER TSE
+\setXTXcharcodes "00427 "00447 "00427 % CYRILLIC CAPITAL LETTER CHE
+\setXTXcharcodes "00428 "00448 "00428 % CYRILLIC CAPITAL LETTER SHA
+\setXTXcharcodes "00429 "00449 "00429 % CYRILLIC CAPITAL LETTER SHCHA
+\setXTXcharcodes "0042A "0044A "0042A % CYRILLIC CAPITAL LETTER HARD SIGN
+\setXTXcharcodes "0042B "0044B "0042B % CYRILLIC CAPITAL LETTER YERU
+\setXTXcharcodes "0042C "0044C "0042C % CYRILLIC CAPITAL LETTER SOFT SIGN
+\setXTXcharcodes "0042D "0044D "0042D % CYRILLIC CAPITAL LETTER E
+\setXTXcharcodes "0042E "0044E "0042E % CYRILLIC CAPITAL LETTER YU
+\setXTXcharcodes "0042F "0044F "0042F % CYRILLIC CAPITAL LETTER YA
+\setXTXcharcodes "00430 "00430 "00410 % CYRILLIC SMALL LETTER A
+\setXTXcharcodes "00431 "00431 "00411 % CYRILLIC SMALL LETTER BE
+\setXTXcharcodes "00432 "00432 "00412 % CYRILLIC SMALL LETTER VE
+\setXTXcharcodes "00433 "00433 "00413 % CYRILLIC SMALL LETTER GHE
+\setXTXcharcodes "00434 "00434 "00414 % CYRILLIC SMALL LETTER DE
+\setXTXcharcodes "00435 "00435 "00415 % CYRILLIC SMALL LETTER IE
+\setXTXcharcodes "00436 "00436 "00416 % CYRILLIC SMALL LETTER ZHE
+\setXTXcharcodes "00437 "00437 "00417 % CYRILLIC SMALL LETTER ZE
+\setXTXcharcodes "00438 "00438 "00418 % CYRILLIC SMALL LETTER I
+\setXTXcharcodes "00439 "00439 "00419 % CYRILLIC SMALL LETTER SHORT I
+\setXTXcharcodes "0043A "0043A "0041A % CYRILLIC SMALL LETTER KA
+\setXTXcharcodes "0043B "0043B "0041B % CYRILLIC SMALL LETTER EL
+\setXTXcharcodes "0043C "0043C "0041C % CYRILLIC SMALL LETTER EM
+\setXTXcharcodes "0043D "0043D "0041D % CYRILLIC SMALL LETTER EN
+\setXTXcharcodes "0043E "0043E "0041E % CYRILLIC SMALL LETTER O
+\setXTXcharcodes "0043F "0043F "0041F % CYRILLIC SMALL LETTER PE
+\setXTXcharcodes "00440 "00440 "00420 % CYRILLIC SMALL LETTER ER
+\setXTXcharcodes "00441 "00441 "00421 % CYRILLIC SMALL LETTER ES
+\setXTXcharcodes "00442 "00442 "00422 % CYRILLIC SMALL LETTER TE
+\setXTXcharcodes "00443 "00443 "00423 % CYRILLIC SMALL LETTER U
+\setXTXcharcodes "00444 "00444 "00424 % CYRILLIC SMALL LETTER EF
+\setXTXcharcodes "00445 "00445 "00425 % CYRILLIC SMALL LETTER HA
+\setXTXcharcodes "00446 "00446 "00426 % CYRILLIC SMALL LETTER TSE
+\setXTXcharcodes "00447 "00447 "00427 % CYRILLIC SMALL LETTER CHE
+\setXTXcharcodes "00448 "00448 "00428 % CYRILLIC SMALL LETTER SHA
+\setXTXcharcodes "00449 "00449 "00429 % CYRILLIC SMALL LETTER SHCHA
+\setXTXcharcodes "0044A "0044A "0042A % CYRILLIC SMALL LETTER HARD SIGN
+\setXTXcharcodes "0044B "0044B "0042B % CYRILLIC SMALL LETTER YERU
+\setXTXcharcodes "0044C "0044C "0042C % CYRILLIC SMALL LETTER SOFT SIGN
+\setXTXcharcodes "0044D "0044D "0042D % CYRILLIC SMALL LETTER E
+\setXTXcharcodes "0044E "0044E "0042E % CYRILLIC SMALL LETTER YU
+\setXTXcharcodes "0044F "0044F "0042F % CYRILLIC SMALL LETTER YA
+\setXTXcharcodes "00450 "00450 "00400 % CYRILLIC SMALL LETTER IE WITH GRAVE
+\setXTXcharcodes "00451 "00451 "00401 % CYRILLIC SMALL LETTER IO
+\setXTXcharcodes "00452 "00452 "00402 % CYRILLIC SMALL LETTER DJE
+\setXTXcharcodes "00453 "00453 "00403 % CYRILLIC SMALL LETTER GJE
+\setXTXcharcodes "00454 "00454 "00404 % CYRILLIC SMALL LETTER UKRAINIAN IE
+\setXTXcharcodes "00455 "00455 "00405 % CYRILLIC SMALL LETTER DZE
+\setXTXcharcodes "00456 "00456 "00406 % CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+\setXTXcharcodes "00457 "00457 "00407 % CYRILLIC SMALL LETTER YI
+\setXTXcharcodes "00458 "00458 "00408 % CYRILLIC SMALL LETTER JE
+\setXTXcharcodes "00459 "00459 "00409 % CYRILLIC SMALL LETTER LJE
+\setXTXcharcodes "0045A "0045A "0040A % CYRILLIC SMALL LETTER NJE
+\setXTXcharcodes "0045B "0045B "0040B % CYRILLIC SMALL LETTER TSHE
+\setXTXcharcodes "0045C "0045C "0040C % CYRILLIC SMALL LETTER KJE
+\setXTXcharcodes "0045D "0045D "0040D % CYRILLIC SMALL LETTER I WITH GRAVE
+\setXTXcharcodes "0045E "0045E "0040E % CYRILLIC SMALL LETTER SHORT U
+\setXTXcharcodes "0045F "0045F "0040F % CYRILLIC SMALL LETTER DZHE
+\setXTXcharcodes "00460 "00461 "00460 % CYRILLIC CAPITAL LETTER OMEGA
+\setXTXcharcodes "00461 "00461 "00460 % CYRILLIC SMALL LETTER OMEGA
+\setXTXcharcodes "00462 "00463 "00462 % CYRILLIC CAPITAL LETTER YAT
+\setXTXcharcodes "00463 "00463 "00462 % CYRILLIC SMALL LETTER YAT
+\setXTXcharcodes "00464 "00465 "00464 % CYRILLIC CAPITAL LETTER IOTIFIED E
+\setXTXcharcodes "00465 "00465 "00464 % CYRILLIC SMALL LETTER IOTIFIED E
+\setXTXcharcodes "00466 "00467 "00466 % CYRILLIC CAPITAL LETTER LITTLE YUS
+\setXTXcharcodes "00467 "00467 "00466 % CYRILLIC SMALL LETTER LITTLE YUS
+\setXTXcharcodes "00468 "00469 "00468 % CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
+\setXTXcharcodes "00469 "00469 "00468 % CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS
+\setXTXcharcodes "0046A "0046B "0046A % CYRILLIC CAPITAL LETTER BIG YUS
+\setXTXcharcodes "0046B "0046B "0046A % CYRILLIC SMALL LETTER BIG YUS
+\setXTXcharcodes "0046C "0046D "0046C % CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
+\setXTXcharcodes "0046D "0046D "0046C % CYRILLIC SMALL LETTER IOTIFIED BIG YUS
+\setXTXcharcodes "0046E "0046F "0046E % CYRILLIC CAPITAL LETTER KSI
+\setXTXcharcodes "0046F "0046F "0046E % CYRILLIC SMALL LETTER KSI
+\setXTXcharcodes "00470 "00471 "00470 % CYRILLIC CAPITAL LETTER PSI
+\setXTXcharcodes "00471 "00471 "00470 % CYRILLIC SMALL LETTER PSI
+\setXTXcharcodes "00472 "00473 "00472 % CYRILLIC CAPITAL LETTER FITA
+\setXTXcharcodes "00473 "00473 "00472 % CYRILLIC SMALL LETTER FITA
+\setXTXcharcodes "00474 "00475 "00474 % CYRILLIC CAPITAL LETTER IZHITSA
+\setXTXcharcodes "00475 "00475 "00474 % CYRILLIC SMALL LETTER IZHITSA
+\setXTXcharcodes "00476 "00477 "00476 % CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+\setXTXcharcodes "00477 "00477 "00476 % CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+\setXTXcharcodes "00478 "00479 "00478 % CYRILLIC CAPITAL LETTER UK
+\setXTXcharcodes "00479 "00479 "00478 % CYRILLIC SMALL LETTER UK
+\setXTXcharcodes "0047A "0047B "0047A % CYRILLIC CAPITAL LETTER ROUND OMEGA
+\setXTXcharcodes "0047B "0047B "0047A % CYRILLIC SMALL LETTER ROUND OMEGA
+\setXTXcharcodes "0047C "0047D "0047C % CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
+\setXTXcharcodes "0047D "0047D "0047C % CYRILLIC SMALL LETTER OMEGA WITH TITLO
+\setXTXcharcodes "0047E "0047F "0047E % CYRILLIC CAPITAL LETTER OT
+\setXTXcharcodes "0047F "0047F "0047E % CYRILLIC SMALL LETTER OT
+\setXTXcharcodes "00480 "00481 "00480 % CYRILLIC CAPITAL LETTER KOPPA
+\setXTXcharcodes "00481 "00481 "00480 % CYRILLIC SMALL LETTER KOPPA
+\setXTXcharcodes "0048A "0048B "0048A % CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
+\setXTXcharcodes "0048B "0048B "0048A % CYRILLIC SMALL LETTER SHORT I WITH TAIL
+\setXTXcharcodes "0048C "0048D "0048C % CYRILLIC CAPITAL LETTER SEMISOFT SIGN
+\setXTXcharcodes "0048D "0048D "0048C % CYRILLIC SMALL LETTER SEMISOFT SIGN
+\setXTXcharcodes "0048E "0048F "0048E % CYRILLIC CAPITAL LETTER ER WITH TICK
+\setXTXcharcodes "0048F "0048F "0048E % CYRILLIC SMALL LETTER ER WITH TICK
+\setXTXcharcodes "00490 "00491 "00490 % CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+\setXTXcharcodes "00491 "00491 "00490 % CYRILLIC SMALL LETTER GHE WITH UPTURN
+\setXTXcharcodes "00492 "00493 "00492 % CYRILLIC CAPITAL LETTER GHE WITH STROKE
+\setXTXcharcodes "00493 "00493 "00492 % CYRILLIC SMALL LETTER GHE WITH STROKE
+\setXTXcharcodes "00494 "00495 "00494 % CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
+\setXTXcharcodes "00495 "00495 "00494 % CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK
+\setXTXcharcodes "00496 "00497 "00496 % CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
+\setXTXcharcodes "00497 "00497 "00496 % CYRILLIC SMALL LETTER ZHE WITH DESCENDER
+\setXTXcharcodes "00498 "00499 "00498 % CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
+\setXTXcharcodes "00499 "00499 "00498 % CYRILLIC SMALL LETTER ZE WITH DESCENDER
+\setXTXcharcodes "0049A "0049B "0049A % CYRILLIC CAPITAL LETTER KA WITH DESCENDER
+\setXTXcharcodes "0049B "0049B "0049A % CYRILLIC SMALL LETTER KA WITH DESCENDER
+\setXTXcharcodes "0049C "0049D "0049C % CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
+\setXTXcharcodes "0049D "0049D "0049C % CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
+\setXTXcharcodes "0049E "0049F "0049E % CYRILLIC CAPITAL LETTER KA WITH STROKE
+\setXTXcharcodes "0049F "0049F "0049E % CYRILLIC SMALL LETTER KA WITH STROKE
+\setXTXcharcodes "004A0 "004A1 "004A0 % CYRILLIC CAPITAL LETTER BASHKIR KA
+\setXTXcharcodes "004A1 "004A1 "004A0 % CYRILLIC SMALL LETTER BASHKIR KA
+\setXTXcharcodes "004A2 "004A3 "004A2 % CYRILLIC CAPITAL LETTER EN WITH DESCENDER
+\setXTXcharcodes "004A3 "004A3 "004A2 % CYRILLIC SMALL LETTER EN WITH DESCENDER
+\setXTXcharcodes "004A4 "004A5 "004A4 % CYRILLIC CAPITAL LIGATURE EN GHE
+\setXTXcharcodes "004A5 "004A5 "004A4 % CYRILLIC SMALL LIGATURE EN GHE
+\setXTXcharcodes "004A6 "004A7 "004A6 % CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
+\setXTXcharcodes "004A7 "004A7 "004A6 % CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK
+\setXTXcharcodes "004A8 "004A9 "004A8 % CYRILLIC CAPITAL LETTER ABKHASIAN HA
+\setXTXcharcodes "004A9 "004A9 "004A8 % CYRILLIC SMALL LETTER ABKHASIAN HA
+\setXTXcharcodes "004AA "004AB "004AA % CYRILLIC CAPITAL LETTER ES WITH DESCENDER
+\setXTXcharcodes "004AB "004AB "004AA % CYRILLIC SMALL LETTER ES WITH DESCENDER
+\setXTXcharcodes "004AC "004AD "004AC % CYRILLIC CAPITAL LETTER TE WITH DESCENDER
+\setXTXcharcodes "004AD "004AD "004AC % CYRILLIC SMALL LETTER TE WITH DESCENDER
+\setXTXcharcodes "004AE "004AF "004AE % CYRILLIC CAPITAL LETTER STRAIGHT U
+\setXTXcharcodes "004AF "004AF "004AE % CYRILLIC SMALL LETTER STRAIGHT U
+\setXTXcharcodes "004B0 "004B1 "004B0 % CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
+\setXTXcharcodes "004B1 "004B1 "004B0 % CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
+\setXTXcharcodes "004B2 "004B3 "004B2 % CYRILLIC CAPITAL LETTER HA WITH DESCENDER
+\setXTXcharcodes "004B3 "004B3 "004B2 % CYRILLIC SMALL LETTER HA WITH DESCENDER
+\setXTXcharcodes "004B4 "004B5 "004B4 % CYRILLIC CAPITAL LIGATURE TE TSE
+\setXTXcharcodes "004B5 "004B5 "004B4 % CYRILLIC SMALL LIGATURE TE TSE
+\setXTXcharcodes "004B6 "004B7 "004B6 % CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
+\setXTXcharcodes "004B7 "004B7 "004B6 % CYRILLIC SMALL LETTER CHE WITH DESCENDER
+\setXTXcharcodes "004B8 "004B9 "004B8 % CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
+\setXTXcharcodes "004B9 "004B9 "004B8 % CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
+\setXTXcharcodes "004BA "004BB "004BA % CYRILLIC CAPITAL LETTER SHHA
+\setXTXcharcodes "004BB "004BB "004BA % CYRILLIC SMALL LETTER SHHA
+\setXTXcharcodes "004BC "004BD "004BC % CYRILLIC CAPITAL LETTER ABKHASIAN CHE
+\setXTXcharcodes "004BD "004BD "004BC % CYRILLIC SMALL LETTER ABKHASIAN CHE
+\setXTXcharcodes "004BE "004BF "004BE % CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
+\setXTXcharcodes "004BF "004BF "004BE % CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER
+\setXTXcharcodes "004C0 "004CF "004C0 % CYRILLIC LETTER PALOCHKA
+\setXTXcharcodes "004C1 "004C2 "004C1 % CYRILLIC CAPITAL LETTER ZHE WITH BREVE
+\setXTXcharcodes "004C2 "004C2 "004C1 % CYRILLIC SMALL LETTER ZHE WITH BREVE
+\setXTXcharcodes "004C3 "004C4 "004C3 % CYRILLIC CAPITAL LETTER KA WITH HOOK
+\setXTXcharcodes "004C4 "004C4 "004C3 % CYRILLIC SMALL LETTER KA WITH HOOK
+\setXTXcharcodes "004C5 "004C6 "004C5 % CYRILLIC CAPITAL LETTER EL WITH TAIL
+\setXTXcharcodes "004C6 "004C6 "004C5 % CYRILLIC SMALL LETTER EL WITH TAIL
+\setXTXcharcodes "004C7 "004C8 "004C7 % CYRILLIC CAPITAL LETTER EN WITH HOOK
+\setXTXcharcodes "004C8 "004C8 "004C7 % CYRILLIC SMALL LETTER EN WITH HOOK
+\setXTXcharcodes "004C9 "004CA "004C9 % CYRILLIC CAPITAL LETTER EN WITH TAIL
+\setXTXcharcodes "004CA "004CA "004C9 % CYRILLIC SMALL LETTER EN WITH TAIL
+\setXTXcharcodes "004CB "004CC "004CB % CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
+\setXTXcharcodes "004CC "004CC "004CB % CYRILLIC SMALL LETTER KHAKASSIAN CHE
+\setXTXcharcodes "004CD "004CE "004CD % CYRILLIC CAPITAL LETTER EM WITH TAIL
+\setXTXcharcodes "004CE "004CE "004CD % CYRILLIC SMALL LETTER EM WITH TAIL
+\setXTXcharcodes "004CF "004CF "004C0 % CYRILLIC SMALL LETTER PALOCHKA
+\setXTXcharcodes "004D0 "004D1 "004D0 % CYRILLIC CAPITAL LETTER A WITH BREVE
+\setXTXcharcodes "004D1 "004D1 "004D0 % CYRILLIC SMALL LETTER A WITH BREVE
+\setXTXcharcodes "004D2 "004D3 "004D2 % CYRILLIC CAPITAL LETTER A WITH DIAERESIS
+\setXTXcharcodes "004D3 "004D3 "004D2 % CYRILLIC SMALL LETTER A WITH DIAERESIS
+\setXTXcharcodes "004D4 "004D5 "004D4 % CYRILLIC CAPITAL LIGATURE A IE
+\setXTXcharcodes "004D5 "004D5 "004D4 % CYRILLIC SMALL LIGATURE A IE
+\setXTXcharcodes "004D6 "004D7 "004D6 % CYRILLIC CAPITAL LETTER IE WITH BREVE
+\setXTXcharcodes "004D7 "004D7 "004D6 % CYRILLIC SMALL LETTER IE WITH BREVE
+\setXTXcharcodes "004D8 "004D9 "004D8 % CYRILLIC CAPITAL LETTER SCHWA
+\setXTXcharcodes "004D9 "004D9 "004D8 % CYRILLIC SMALL LETTER SCHWA
+\setXTXcharcodes "004DA "004DB "004DA % CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
+\setXTXcharcodes "004DB "004DB "004DA % CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS
+\setXTXcharcodes "004DC "004DD "004DC % CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
+\setXTXcharcodes "004DD "004DD "004DC % CYRILLIC SMALL LETTER ZHE WITH DIAERESIS
+\setXTXcharcodes "004DE "004DF "004DE % CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
+\setXTXcharcodes "004DF "004DF "004DE % CYRILLIC SMALL LETTER ZE WITH DIAERESIS
+\setXTXcharcodes "004E0 "004E1 "004E0 % CYRILLIC CAPITAL LETTER ABKHASIAN DZE
+\setXTXcharcodes "004E1 "004E1 "004E0 % CYRILLIC SMALL LETTER ABKHASIAN DZE
+\setXTXcharcodes "004E2 "004E3 "004E2 % CYRILLIC CAPITAL LETTER I WITH MACRON
+\setXTXcharcodes "004E3 "004E3 "004E2 % CYRILLIC SMALL LETTER I WITH MACRON
+\setXTXcharcodes "004E4 "004E5 "004E4 % CYRILLIC CAPITAL LETTER I WITH DIAERESIS
+\setXTXcharcodes "004E5 "004E5 "004E4 % CYRILLIC SMALL LETTER I WITH DIAERESIS
+\setXTXcharcodes "004E6 "004E7 "004E6 % CYRILLIC CAPITAL LETTER O WITH DIAERESIS
+\setXTXcharcodes "004E7 "004E7 "004E6 % CYRILLIC SMALL LETTER O WITH DIAERESIS
+\setXTXcharcodes "004E8 "004E9 "004E8 % CYRILLIC CAPITAL LETTER BARRED O
+\setXTXcharcodes "004E9 "004E9 "004E8 % CYRILLIC SMALL LETTER BARRED O
+\setXTXcharcodes "004EA "004EB "004EA % CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
+\setXTXcharcodes "004EB "004EB "004EA % CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS
+\setXTXcharcodes "004EC "004ED "004EC % CYRILLIC CAPITAL LETTER E WITH DIAERESIS
+\setXTXcharcodes "004ED "004ED "004EC % CYRILLIC SMALL LETTER E WITH DIAERESIS
+\setXTXcharcodes "004EE "004EF "004EE % CYRILLIC CAPITAL LETTER U WITH MACRON
+\setXTXcharcodes "004EF "004EF "004EE % CYRILLIC SMALL LETTER U WITH MACRON
+\setXTXcharcodes "004F0 "004F1 "004F0 % CYRILLIC CAPITAL LETTER U WITH DIAERESIS
+\setXTXcharcodes "004F1 "004F1 "004F0 % CYRILLIC SMALL LETTER U WITH DIAERESIS
+\setXTXcharcodes "004F2 "004F3 "004F2 % CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
+\setXTXcharcodes "004F3 "004F3 "004F2 % CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE
+\setXTXcharcodes "004F4 "004F5 "004F4 % CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
+\setXTXcharcodes "004F5 "004F5 "004F4 % CYRILLIC SMALL LETTER CHE WITH DIAERESIS
+\setXTXcharcodes "004F6 "004F7 "004F6 % CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
+\setXTXcharcodes "004F7 "004F7 "004F6 % CYRILLIC SMALL LETTER GHE WITH DESCENDER
+\setXTXcharcodes "004F8 "004F9 "004F8 % CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
+\setXTXcharcodes "004F9 "004F9 "004F8 % CYRILLIC SMALL LETTER YERU WITH DIAERESIS
+\setXTXcharcodes "004FA "004FB "004FA % CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
+\setXTXcharcodes "004FB "004FB "004FA % CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK
+\setXTXcharcodes "004FC "004FD "004FC % CYRILLIC CAPITAL LETTER HA WITH HOOK
+\setXTXcharcodes "004FD "004FD "004FC % CYRILLIC SMALL LETTER HA WITH HOOK
+\setXTXcharcodes "004FE "004FF "004FE % CYRILLIC CAPITAL LETTER HA WITH STROKE
+\setXTXcharcodes "004FF "004FF "004FE % CYRILLIC SMALL LETTER HA WITH STROKE
+\setXTXcharcodes "00500 "00501 "00500 % CYRILLIC CAPITAL LETTER KOMI DE
+\setXTXcharcodes "00501 "00501 "00500 % CYRILLIC SMALL LETTER KOMI DE
+\setXTXcharcodes "00502 "00503 "00502 % CYRILLIC CAPITAL LETTER KOMI DJE
+\setXTXcharcodes "00503 "00503 "00502 % CYRILLIC SMALL LETTER KOMI DJE
+\setXTXcharcodes "00504 "00505 "00504 % CYRILLIC CAPITAL LETTER KOMI ZJE
+\setXTXcharcodes "00505 "00505 "00504 % CYRILLIC SMALL LETTER KOMI ZJE
+\setXTXcharcodes "00506 "00507 "00506 % CYRILLIC CAPITAL LETTER KOMI DZJE
+\setXTXcharcodes "00507 "00507 "00506 % CYRILLIC SMALL LETTER KOMI DZJE
+\setXTXcharcodes "00508 "00509 "00508 % CYRILLIC CAPITAL LETTER KOMI LJE
+\setXTXcharcodes "00509 "00509 "00508 % CYRILLIC SMALL LETTER KOMI LJE
+\setXTXcharcodes "0050A "0050B "0050A % CYRILLIC CAPITAL LETTER KOMI NJE
+\setXTXcharcodes "0050B "0050B "0050A % CYRILLIC SMALL LETTER KOMI NJE
+\setXTXcharcodes "0050C "0050D "0050C % CYRILLIC CAPITAL LETTER KOMI SJE
+\setXTXcharcodes "0050D "0050D "0050C % CYRILLIC SMALL LETTER KOMI SJE
+\setXTXcharcodes "0050E "0050F "0050E % CYRILLIC CAPITAL LETTER KOMI TJE
+\setXTXcharcodes "0050F "0050F "0050E % CYRILLIC SMALL LETTER KOMI TJE
+\setXTXcharcodes "00510 "00511 "00510 % CYRILLIC CAPITAL LETTER REVERSED ZE
+\setXTXcharcodes "00511 "00511 "00510 % CYRILLIC SMALL LETTER REVERSED ZE
+\setXTXcharcodes "00512 "00513 "00512 % CYRILLIC CAPITAL LETTER EL WITH HOOK
+\setXTXcharcodes "00513 "00513 "00512 % CYRILLIC SMALL LETTER EL WITH HOOK
+\setXTXcharcodes "00531 "00561 "00531 % ARMENIAN CAPITAL LETTER AYB
+\setXTXcharcodes "00532 "00562 "00532 % ARMENIAN CAPITAL LETTER BEN
+\setXTXcharcodes "00533 "00563 "00533 % ARMENIAN CAPITAL LETTER GIM
+\setXTXcharcodes "00534 "00564 "00534 % ARMENIAN CAPITAL LETTER DA
+\setXTXcharcodes "00535 "00565 "00535 % ARMENIAN CAPITAL LETTER ECH
+\setXTXcharcodes "00536 "00566 "00536 % ARMENIAN CAPITAL LETTER ZA
+\setXTXcharcodes "00537 "00567 "00537 % ARMENIAN CAPITAL LETTER EH
+\setXTXcharcodes "00538 "00568 "00538 % ARMENIAN CAPITAL LETTER ET
+\setXTXcharcodes "00539 "00569 "00539 % ARMENIAN CAPITAL LETTER TO
+\setXTXcharcodes "0053A "0056A "0053A % ARMENIAN CAPITAL LETTER ZHE
+\setXTXcharcodes "0053B "0056B "0053B % ARMENIAN CAPITAL LETTER INI
+\setXTXcharcodes "0053C "0056C "0053C % ARMENIAN CAPITAL LETTER LIWN
+\setXTXcharcodes "0053D "0056D "0053D % ARMENIAN CAPITAL LETTER XEH
+\setXTXcharcodes "0053E "0056E "0053E % ARMENIAN CAPITAL LETTER CA
+\setXTXcharcodes "0053F "0056F "0053F % ARMENIAN CAPITAL LETTER KEN
+\setXTXcharcodes "00540 "00570 "00540 % ARMENIAN CAPITAL LETTER HO
+\setXTXcharcodes "00541 "00571 "00541 % ARMENIAN CAPITAL LETTER JA
+\setXTXcharcodes "00542 "00572 "00542 % ARMENIAN CAPITAL LETTER GHAD
+\setXTXcharcodes "00543 "00573 "00543 % ARMENIAN CAPITAL LETTER CHEH
+\setXTXcharcodes "00544 "00574 "00544 % ARMENIAN CAPITAL LETTER MEN
+\setXTXcharcodes "00545 "00575 "00545 % ARMENIAN CAPITAL LETTER YI
+\setXTXcharcodes "00546 "00576 "00546 % ARMENIAN CAPITAL LETTER NOW
+\setXTXcharcodes "00547 "00577 "00547 % ARMENIAN CAPITAL LETTER SHA
+\setXTXcharcodes "00548 "00578 "00548 % ARMENIAN CAPITAL LETTER VO
+\setXTXcharcodes "00549 "00579 "00549 % ARMENIAN CAPITAL LETTER CHA
+\setXTXcharcodes "0054A "0057A "0054A % ARMENIAN CAPITAL LETTER PEH
+\setXTXcharcodes "0054B "0057B "0054B % ARMENIAN CAPITAL LETTER JHEH
+\setXTXcharcodes "0054C "0057C "0054C % ARMENIAN CAPITAL LETTER RA
+\setXTXcharcodes "0054D "0057D "0054D % ARMENIAN CAPITAL LETTER SEH
+\setXTXcharcodes "0054E "0057E "0054E % ARMENIAN CAPITAL LETTER VEW
+\setXTXcharcodes "0054F "0057F "0054F % ARMENIAN CAPITAL LETTER TIWN
+\setXTXcharcodes "00550 "00580 "00550 % ARMENIAN CAPITAL LETTER REH
+\setXTXcharcodes "00551 "00581 "00551 % ARMENIAN CAPITAL LETTER CO
+\setXTXcharcodes "00552 "00582 "00552 % ARMENIAN CAPITAL LETTER YIWN
+\setXTXcharcodes "00553 "00583 "00553 % ARMENIAN CAPITAL LETTER PIWR
+\setXTXcharcodes "00554 "00584 "00554 % ARMENIAN CAPITAL LETTER KEH
+\setXTXcharcodes "00555 "00585 "00555 % ARMENIAN CAPITAL LETTER OH
+\setXTXcharcodes "00556 "00586 "00556 % ARMENIAN CAPITAL LETTER FEH
+\setXTXcharcodes "00561 "00561 "00531 % ARMENIAN SMALL LETTER AYB
+\setXTXcharcodes "00562 "00562 "00532 % ARMENIAN SMALL LETTER BEN
+\setXTXcharcodes "00563 "00563 "00533 % ARMENIAN SMALL LETTER GIM
+\setXTXcharcodes "00564 "00564 "00534 % ARMENIAN SMALL LETTER DA
+\setXTXcharcodes "00565 "00565 "00535 % ARMENIAN SMALL LETTER ECH
+\setXTXcharcodes "00566 "00566 "00536 % ARMENIAN SMALL LETTER ZA
+\setXTXcharcodes "00567 "00567 "00537 % ARMENIAN SMALL LETTER EH
+\setXTXcharcodes "00568 "00568 "00538 % ARMENIAN SMALL LETTER ET
+\setXTXcharcodes "00569 "00569 "00539 % ARMENIAN SMALL LETTER TO
+\setXTXcharcodes "0056A "0056A "0053A % ARMENIAN SMALL LETTER ZHE
+\setXTXcharcodes "0056B "0056B "0053B % ARMENIAN SMALL LETTER INI
+\setXTXcharcodes "0056C "0056C "0053C % ARMENIAN SMALL LETTER LIWN
+\setXTXcharcodes "0056D "0056D "0053D % ARMENIAN SMALL LETTER XEH
+\setXTXcharcodes "0056E "0056E "0053E % ARMENIAN SMALL LETTER CA
+\setXTXcharcodes "0056F "0056F "0053F % ARMENIAN SMALL LETTER KEN
+\setXTXcharcodes "00570 "00570 "00540 % ARMENIAN SMALL LETTER HO
+\setXTXcharcodes "00571 "00571 "00541 % ARMENIAN SMALL LETTER JA
+\setXTXcharcodes "00572 "00572 "00542 % ARMENIAN SMALL LETTER GHAD
+\setXTXcharcodes "00573 "00573 "00543 % ARMENIAN SMALL LETTER CHEH
+\setXTXcharcodes "00574 "00574 "00544 % ARMENIAN SMALL LETTER MEN
+\setXTXcharcodes "00575 "00575 "00545 % ARMENIAN SMALL LETTER YI
+\setXTXcharcodes "00576 "00576 "00546 % ARMENIAN SMALL LETTER NOW
+\setXTXcharcodes "00577 "00577 "00547 % ARMENIAN SMALL LETTER SHA
+\setXTXcharcodes "00578 "00578 "00548 % ARMENIAN SMALL LETTER VO
+\setXTXcharcodes "00579 "00579 "00549 % ARMENIAN SMALL LETTER CHA
+\setXTXcharcodes "0057A "0057A "0054A % ARMENIAN SMALL LETTER PEH
+\setXTXcharcodes "0057B "0057B "0054B % ARMENIAN SMALL LETTER JHEH
+\setXTXcharcodes "0057C "0057C "0054C % ARMENIAN SMALL LETTER RA
+\setXTXcharcodes "0057D "0057D "0054D % ARMENIAN SMALL LETTER SEH
+\setXTXcharcodes "0057E "0057E "0054E % ARMENIAN SMALL LETTER VEW
+\setXTXcharcodes "0057F "0057F "0054F % ARMENIAN SMALL LETTER TIWN
+\setXTXcharcodes "00580 "00580 "00550 % ARMENIAN SMALL LETTER REH
+\setXTXcharcodes "00581 "00581 "00551 % ARMENIAN SMALL LETTER CO
+\setXTXcharcodes "00582 "00582 "00552 % ARMENIAN SMALL LETTER YIWN
+\setXTXcharcodes "00583 "00583 "00553 % ARMENIAN SMALL LETTER PIWR
+\setXTXcharcodes "00584 "00584 "00554 % ARMENIAN SMALL LETTER KEH
+\setXTXcharcodes "00585 "00585 "00555 % ARMENIAN SMALL LETTER OH
+\setXTXcharcodes "00586 "00586 "00556 % ARMENIAN SMALL LETTER FEH
+\setXTXcharcodes "00587 "00587 "00587 % ARMENIAN SMALL LIGATURE ECH YIWN
+\setXTXcharcodes "010A0 "02D00 "010A0 % GEORGIAN CAPITAL LETTER AN
+\setXTXcharcodes "010A1 "02D01 "010A1 % GEORGIAN CAPITAL LETTER BAN
+\setXTXcharcodes "010A2 "02D02 "010A2 % GEORGIAN CAPITAL LETTER GAN
+\setXTXcharcodes "010A3 "02D03 "010A3 % GEORGIAN CAPITAL LETTER DON
+\setXTXcharcodes "010A4 "02D04 "010A4 % GEORGIAN CAPITAL LETTER EN
+\setXTXcharcodes "010A5 "02D05 "010A5 % GEORGIAN CAPITAL LETTER VIN
+\setXTXcharcodes "010A6 "02D06 "010A6 % GEORGIAN CAPITAL LETTER ZEN
+\setXTXcharcodes "010A7 "02D07 "010A7 % GEORGIAN CAPITAL LETTER TAN
+\setXTXcharcodes "010A8 "02D08 "010A8 % GEORGIAN CAPITAL LETTER IN
+\setXTXcharcodes "010A9 "02D09 "010A9 % GEORGIAN CAPITAL LETTER KAN
+\setXTXcharcodes "010AA "02D0A "010AA % GEORGIAN CAPITAL LETTER LAS
+\setXTXcharcodes "010AB "02D0B "010AB % GEORGIAN CAPITAL LETTER MAN
+\setXTXcharcodes "010AC "02D0C "010AC % GEORGIAN CAPITAL LETTER NAR
+\setXTXcharcodes "010AD "02D0D "010AD % GEORGIAN CAPITAL LETTER ON
+\setXTXcharcodes "010AE "02D0E "010AE % GEORGIAN CAPITAL LETTER PAR
+\setXTXcharcodes "010AF "02D0F "010AF % GEORGIAN CAPITAL LETTER ZHAR
+\setXTXcharcodes "010B0 "02D10 "010B0 % GEORGIAN CAPITAL LETTER RAE
+\setXTXcharcodes "010B1 "02D11 "010B1 % GEORGIAN CAPITAL LETTER SAN
+\setXTXcharcodes "010B2 "02D12 "010B2 % GEORGIAN CAPITAL LETTER TAR
+\setXTXcharcodes "010B3 "02D13 "010B3 % GEORGIAN CAPITAL LETTER UN
+\setXTXcharcodes "010B4 "02D14 "010B4 % GEORGIAN CAPITAL LETTER PHAR
+\setXTXcharcodes "010B5 "02D15 "010B5 % GEORGIAN CAPITAL LETTER KHAR
+\setXTXcharcodes "010B6 "02D16 "010B6 % GEORGIAN CAPITAL LETTER GHAN
+\setXTXcharcodes "010B7 "02D17 "010B7 % GEORGIAN CAPITAL LETTER QAR
+\setXTXcharcodes "010B8 "02D18 "010B8 % GEORGIAN CAPITAL LETTER SHIN
+\setXTXcharcodes "010B9 "02D19 "010B9 % GEORGIAN CAPITAL LETTER CHIN
+\setXTXcharcodes "010BA "02D1A "010BA % GEORGIAN CAPITAL LETTER CAN
+\setXTXcharcodes "010BB "02D1B "010BB % GEORGIAN CAPITAL LETTER JIL
+\setXTXcharcodes "010BC "02D1C "010BC % GEORGIAN CAPITAL LETTER CIL
+\setXTXcharcodes "010BD "02D1D "010BD % GEORGIAN CAPITAL LETTER CHAR
+\setXTXcharcodes "010BE "02D1E "010BE % GEORGIAN CAPITAL LETTER XAN
+\setXTXcharcodes "010BF "02D1F "010BF % GEORGIAN CAPITAL LETTER JHAN
+\setXTXcharcodes "010C0 "02D20 "010C0 % GEORGIAN CAPITAL LETTER HAE
+\setXTXcharcodes "010C1 "02D21 "010C1 % GEORGIAN CAPITAL LETTER HE
+\setXTXcharcodes "010C2 "02D22 "010C2 % GEORGIAN CAPITAL LETTER HIE
+\setXTXcharcodes "010C3 "02D23 "010C3 % GEORGIAN CAPITAL LETTER WE
+\setXTXcharcodes "010C4 "02D24 "010C4 % GEORGIAN CAPITAL LETTER HAR
+\setXTXcharcodes "010C5 "02D25 "010C5 % GEORGIAN CAPITAL LETTER HOE
+\setXTXcharcodes "01D00 "01D00 "01D00 % LATIN LETTER SMALL CAPITAL A
+\setXTXcharcodes "01D01 "01D01 "01D01 % LATIN LETTER SMALL CAPITAL AE
+\setXTXcharcodes "01D02 "01D02 "01D02 % LATIN SMALL LETTER TURNED AE
+\setXTXcharcodes "01D03 "01D03 "01D03 % LATIN LETTER SMALL CAPITAL BARRED B
+\setXTXcharcodes "01D04 "01D04 "01D04 % LATIN LETTER SMALL CAPITAL C
+\setXTXcharcodes "01D05 "01D05 "01D05 % LATIN LETTER SMALL CAPITAL D
+\setXTXcharcodes "01D06 "01D06 "01D06 % LATIN LETTER SMALL CAPITAL ETH
+\setXTXcharcodes "01D07 "01D07 "01D07 % LATIN LETTER SMALL CAPITAL E
+\setXTXcharcodes "01D08 "01D08 "01D08 % LATIN SMALL LETTER TURNED OPEN E
+\setXTXcharcodes "01D09 "01D09 "01D09 % LATIN SMALL LETTER TURNED I
+\setXTXcharcodes "01D0A "01D0A "01D0A % LATIN LETTER SMALL CAPITAL J
+\setXTXcharcodes "01D0B "01D0B "01D0B % LATIN LETTER SMALL CAPITAL K
+\setXTXcharcodes "01D0C "01D0C "01D0C % LATIN LETTER SMALL CAPITAL L WITH STROKE
+\setXTXcharcodes "01D0D "01D0D "01D0D % LATIN LETTER SMALL CAPITAL M
+\setXTXcharcodes "01D0E "01D0E "01D0E % LATIN LETTER SMALL CAPITAL REVERSED N
+\setXTXcharcodes "01D0F "01D0F "01D0F % LATIN LETTER SMALL CAPITAL O
+\setXTXcharcodes "01D10 "01D10 "01D10 % LATIN LETTER SMALL CAPITAL OPEN O
+\setXTXcharcodes "01D11 "01D11 "01D11 % LATIN SMALL LETTER SIDEWAYS O
+\setXTXcharcodes "01D12 "01D12 "01D12 % LATIN SMALL LETTER SIDEWAYS OPEN O
+\setXTXcharcodes "01D13 "01D13 "01D13 % LATIN SMALL LETTER SIDEWAYS O WITH STROKE
+\setXTXcharcodes "01D14 "01D14 "01D14 % LATIN SMALL LETTER TURNED OE
+\setXTXcharcodes "01D15 "01D15 "01D15 % LATIN LETTER SMALL CAPITAL OU
+\setXTXcharcodes "01D16 "01D16 "01D16 % LATIN SMALL LETTER TOP HALF O
+\setXTXcharcodes "01D17 "01D17 "01D17 % LATIN SMALL LETTER BOTTOM HALF O
+\setXTXcharcodes "01D18 "01D18 "01D18 % LATIN LETTER SMALL CAPITAL P
+\setXTXcharcodes "01D19 "01D19 "01D19 % LATIN LETTER SMALL CAPITAL REVERSED R
+\setXTXcharcodes "01D1A "01D1A "01D1A % LATIN LETTER SMALL CAPITAL TURNED R
+\setXTXcharcodes "01D1B "01D1B "01D1B % LATIN LETTER SMALL CAPITAL T
+\setXTXcharcodes "01D1C "01D1C "01D1C % LATIN LETTER SMALL CAPITAL U
+\setXTXcharcodes "01D1D "01D1D "01D1D % LATIN SMALL LETTER SIDEWAYS U
+\setXTXcharcodes "01D1E "01D1E "01D1E % LATIN SMALL LETTER SIDEWAYS DIAERESIZED U
+\setXTXcharcodes "01D1F "01D1F "01D1F % LATIN SMALL LETTER SIDEWAYS TURNED M
+\setXTXcharcodes "01D20 "01D20 "01D20 % LATIN LETTER SMALL CAPITAL V
+\setXTXcharcodes "01D21 "01D21 "01D21 % LATIN LETTER SMALL CAPITAL W
+\setXTXcharcodes "01D22 "01D22 "01D22 % LATIN LETTER SMALL CAPITAL Z
+\setXTXcharcodes "01D23 "01D23 "01D23 % LATIN LETTER SMALL CAPITAL EZH
+\setXTXcharcodes "01D24 "01D24 "01D24 % LATIN LETTER VOICED LARYNGEAL SPIRANT
+\setXTXcharcodes "01D25 "01D25 "01D25 % LATIN LETTER AIN
+\setXTXcharcodes "01D26 "01D26 "01D26 % GREEK LETTER SMALL CAPITAL GAMMA
+\setXTXcharcodes "01D27 "01D27 "01D27 % GREEK LETTER SMALL CAPITAL LAMDA
+\setXTXcharcodes "01D28 "01D28 "01D28 % GREEK LETTER SMALL CAPITAL PI
+\setXTXcharcodes "01D29 "01D29 "01D29 % GREEK LETTER SMALL CAPITAL RHO
+\setXTXcharcodes "01D2A "01D2A "01D2A % GREEK LETTER SMALL CAPITAL PSI
+\setXTXcharcodes "01D2B "01D2B "01D2B % CYRILLIC LETTER SMALL CAPITAL EL
+\setXTXcharcodes "01D62 "01D62 "01D62 % LATIN SUBSCRIPT SMALL LETTER I
+\setXTXcharcodes "01D63 "01D63 "01D63 % LATIN SUBSCRIPT SMALL LETTER R
+\setXTXcharcodes "01D64 "01D64 "01D64 % LATIN SUBSCRIPT SMALL LETTER U
+\setXTXcharcodes "01D65 "01D65 "01D65 % LATIN SUBSCRIPT SMALL LETTER V
+\setXTXcharcodes "01D66 "01D66 "01D66 % GREEK SUBSCRIPT SMALL LETTER BETA
+\setXTXcharcodes "01D67 "01D67 "01D67 % GREEK SUBSCRIPT SMALL LETTER GAMMA
+\setXTXcharcodes "01D68 "01D68 "01D68 % GREEK SUBSCRIPT SMALL LETTER RHO
+\setXTXcharcodes "01D69 "01D69 "01D69 % GREEK SUBSCRIPT SMALL LETTER PHI
+\setXTXcharcodes "01D6A "01D6A "01D6A % GREEK SUBSCRIPT SMALL LETTER CHI
+\setXTXcharcodes "01D6B "01D6B "01D6B % LATIN SMALL LETTER UE
+\setXTXcharcodes "01D6C "01D6C "01D6C % LATIN SMALL LETTER B WITH MIDDLE TILDE
+\setXTXcharcodes "01D6D "01D6D "01D6D % LATIN SMALL LETTER D WITH MIDDLE TILDE
+\setXTXcharcodes "01D6E "01D6E "01D6E % LATIN SMALL LETTER F WITH MIDDLE TILDE
+\setXTXcharcodes "01D6F "01D6F "01D6F % LATIN SMALL LETTER M WITH MIDDLE TILDE
+\setXTXcharcodes "01D70 "01D70 "01D70 % LATIN SMALL LETTER N WITH MIDDLE TILDE
+\setXTXcharcodes "01D71 "01D71 "01D71 % LATIN SMALL LETTER P WITH MIDDLE TILDE
+\setXTXcharcodes "01D72 "01D72 "01D72 % LATIN SMALL LETTER R WITH MIDDLE TILDE
+\setXTXcharcodes "01D73 "01D73 "01D73 % LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE
+\setXTXcharcodes "01D74 "01D74 "01D74 % LATIN SMALL LETTER S WITH MIDDLE TILDE
+\setXTXcharcodes "01D75 "01D75 "01D75 % LATIN SMALL LETTER T WITH MIDDLE TILDE
+\setXTXcharcodes "01D76 "01D76 "01D76 % LATIN SMALL LETTER Z WITH MIDDLE TILDE
+\setXTXcharcodes "01D77 "01D77 "01D77 % LATIN SMALL LETTER TURNED G
+\setXTXcharcodes "01D79 "01D79 "01D79 % LATIN SMALL LETTER INSULAR G
+\setXTXcharcodes "01D7A "01D7A "01D7A % LATIN SMALL LETTER TH WITH STRIKETHROUGH
+\setXTXcharcodes "01D7B "01D7B "01D7B % LATIN SMALL CAPITAL LETTER I WITH STROKE
+\setXTXcharcodes "01D7C "01D7C "01D7C % LATIN SMALL LETTER IOTA WITH STROKE
+\setXTXcharcodes "01D7D "01D7D "02C63 % LATIN SMALL LETTER P WITH STROKE
+\setXTXcharcodes "01D7E "01D7E "01D7E % LATIN SMALL CAPITAL LETTER U WITH STROKE
+\setXTXcharcodes "01D7F "01D7F "01D7F % LATIN SMALL LETTER UPSILON WITH STROKE
+\setXTXcharcodes "01D80 "01D80 "01D80 % LATIN SMALL LETTER B WITH PALATAL HOOK
+\setXTXcharcodes "01D81 "01D81 "01D81 % LATIN SMALL LETTER D WITH PALATAL HOOK
+\setXTXcharcodes "01D82 "01D82 "01D82 % LATIN SMALL LETTER F WITH PALATAL HOOK
+\setXTXcharcodes "01D83 "01D83 "01D83 % LATIN SMALL LETTER G WITH PALATAL HOOK
+\setXTXcharcodes "01D84 "01D84 "01D84 % LATIN SMALL LETTER K WITH PALATAL HOOK
+\setXTXcharcodes "01D85 "01D85 "01D85 % LATIN SMALL LETTER L WITH PALATAL HOOK
+\setXTXcharcodes "01D86 "01D86 "01D86 % LATIN SMALL LETTER M WITH PALATAL HOOK
+\setXTXcharcodes "01D87 "01D87 "01D87 % LATIN SMALL LETTER N WITH PALATAL HOOK
+\setXTXcharcodes "01D88 "01D88 "01D88 % LATIN SMALL LETTER P WITH PALATAL HOOK
+\setXTXcharcodes "01D89 "01D89 "01D89 % LATIN SMALL LETTER R WITH PALATAL HOOK
+\setXTXcharcodes "01D8A "01D8A "01D8A % LATIN SMALL LETTER S WITH PALATAL HOOK
+\setXTXcharcodes "01D8B "01D8B "01D8B % LATIN SMALL LETTER ESH WITH PALATAL HOOK
+\setXTXcharcodes "01D8C "01D8C "01D8C % LATIN SMALL LETTER V WITH PALATAL HOOK
+\setXTXcharcodes "01D8D "01D8D "01D8D % LATIN SMALL LETTER X WITH PALATAL HOOK
+\setXTXcharcodes "01D8E "01D8E "01D8E % LATIN SMALL LETTER Z WITH PALATAL HOOK
+\setXTXcharcodes "01D8F "01D8F "01D8F % LATIN SMALL LETTER A WITH RETROFLEX HOOK
+\setXTXcharcodes "01D90 "01D90 "01D90 % LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK
+\setXTXcharcodes "01D91 "01D91 "01D91 % LATIN SMALL LETTER D WITH HOOK AND TAIL
+\setXTXcharcodes "01D92 "01D92 "01D92 % LATIN SMALL LETTER E WITH RETROFLEX HOOK
+\setXTXcharcodes "01D93 "01D93 "01D93 % LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK
+\setXTXcharcodes "01D94 "01D94 "01D94 % LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK
+\setXTXcharcodes "01D95 "01D95 "01D95 % LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK
+\setXTXcharcodes "01D96 "01D96 "01D96 % LATIN SMALL LETTER I WITH RETROFLEX HOOK
+\setXTXcharcodes "01D97 "01D97 "01D97 % LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK
+\setXTXcharcodes "01D98 "01D98 "01D98 % LATIN SMALL LETTER ESH WITH RETROFLEX HOOK
+\setXTXcharcodes "01D99 "01D99 "01D99 % LATIN SMALL LETTER U WITH RETROFLEX HOOK
+\setXTXcharcodes "01D9A "01D9A "01D9A % LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
+\setXTXcharcodes "01E00 "01E01 "01E00 % LATIN CAPITAL LETTER A WITH RING BELOW
+\setXTXcharcodes "01E01 "01E01 "01E00 % LATIN SMALL LETTER A WITH RING BELOW
+\setXTXcharcodes "01E02 "01E03 "01E02 % LATIN CAPITAL LETTER B WITH DOT ABOVE
+\setXTXcharcodes "01E03 "01E03 "01E02 % LATIN SMALL LETTER B WITH DOT ABOVE
+\setXTXcharcodes "01E04 "01E05 "01E04 % LATIN CAPITAL LETTER B WITH DOT BELOW
+\setXTXcharcodes "01E05 "01E05 "01E04 % LATIN SMALL LETTER B WITH DOT BELOW
+\setXTXcharcodes "01E06 "01E07 "01E06 % LATIN CAPITAL LETTER B WITH LINE BELOW
+\setXTXcharcodes "01E07 "01E07 "01E06 % LATIN SMALL LETTER B WITH LINE BELOW
+\setXTXcharcodes "01E08 "01E09 "01E08 % LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
+\setXTXcharcodes "01E09 "01E09 "01E08 % LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
+\setXTXcharcodes "01E0A "01E0B "01E0A % LATIN CAPITAL LETTER D WITH DOT ABOVE
+\setXTXcharcodes "01E0B "01E0B "01E0A % LATIN SMALL LETTER D WITH DOT ABOVE
+\setXTXcharcodes "01E0C "01E0D "01E0C % LATIN CAPITAL LETTER D WITH DOT BELOW
+\setXTXcharcodes "01E0D "01E0D "01E0C % LATIN SMALL LETTER D WITH DOT BELOW
+\setXTXcharcodes "01E0E "01E0F "01E0E % LATIN CAPITAL LETTER D WITH LINE BELOW
+\setXTXcharcodes "01E0F "01E0F "01E0E % LATIN SMALL LETTER D WITH LINE BELOW
+\setXTXcharcodes "01E10 "01E11 "01E10 % LATIN CAPITAL LETTER D WITH CEDILLA
+\setXTXcharcodes "01E11 "01E11 "01E10 % LATIN SMALL LETTER D WITH CEDILLA
+\setXTXcharcodes "01E12 "01E13 "01E12 % LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E13 "01E13 "01E12 % LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E14 "01E15 "01E14 % LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+\setXTXcharcodes "01E15 "01E15 "01E14 % LATIN SMALL LETTER E WITH MACRON AND GRAVE
+\setXTXcharcodes "01E16 "01E17 "01E16 % LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
+\setXTXcharcodes "01E17 "01E17 "01E16 % LATIN SMALL LETTER E WITH MACRON AND ACUTE
+\setXTXcharcodes "01E18 "01E19 "01E18 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E19 "01E19 "01E18 % LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E1A "01E1B "01E1A % LATIN CAPITAL LETTER E WITH TILDE BELOW
+\setXTXcharcodes "01E1B "01E1B "01E1A % LATIN SMALL LETTER E WITH TILDE BELOW
+\setXTXcharcodes "01E1C "01E1D "01E1C % LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
+\setXTXcharcodes "01E1D "01E1D "01E1C % LATIN SMALL LETTER E WITH CEDILLA AND BREVE
+\setXTXcharcodes "01E1E "01E1F "01E1E % LATIN CAPITAL LETTER F WITH DOT ABOVE
+\setXTXcharcodes "01E1F "01E1F "01E1E % LATIN SMALL LETTER F WITH DOT ABOVE
+\setXTXcharcodes "01E20 "01E21 "01E20 % LATIN CAPITAL LETTER G WITH MACRON
+\setXTXcharcodes "01E21 "01E21 "01E20 % LATIN SMALL LETTER G WITH MACRON
+\setXTXcharcodes "01E22 "01E23 "01E22 % LATIN CAPITAL LETTER H WITH DOT ABOVE
+\setXTXcharcodes "01E23 "01E23 "01E22 % LATIN SMALL LETTER H WITH DOT ABOVE
+\setXTXcharcodes "01E24 "01E25 "01E24 % LATIN CAPITAL LETTER H WITH DOT BELOW
+\setXTXcharcodes "01E25 "01E25 "01E24 % LATIN SMALL LETTER H WITH DOT BELOW
+\setXTXcharcodes "01E26 "01E27 "01E26 % LATIN CAPITAL LETTER H WITH DIAERESIS
+\setXTXcharcodes "01E27 "01E27 "01E26 % LATIN SMALL LETTER H WITH DIAERESIS
+\setXTXcharcodes "01E28 "01E29 "01E28 % LATIN CAPITAL LETTER H WITH CEDILLA
+\setXTXcharcodes "01E29 "01E29 "01E28 % LATIN SMALL LETTER H WITH CEDILLA
+\setXTXcharcodes "01E2A "01E2B "01E2A % LATIN CAPITAL LETTER H WITH BREVE BELOW
+\setXTXcharcodes "01E2B "01E2B "01E2A % LATIN SMALL LETTER H WITH BREVE BELOW
+\setXTXcharcodes "01E2C "01E2D "01E2C % LATIN CAPITAL LETTER I WITH TILDE BELOW
+\setXTXcharcodes "01E2D "01E2D "01E2C % LATIN SMALL LETTER I WITH TILDE BELOW
+\setXTXcharcodes "01E2E "01E2F "01E2E % LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
+\setXTXcharcodes "01E2F "01E2F "01E2E % LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
+\setXTXcharcodes "01E30 "01E31 "01E30 % LATIN CAPITAL LETTER K WITH ACUTE
+\setXTXcharcodes "01E31 "01E31 "01E30 % LATIN SMALL LETTER K WITH ACUTE
+\setXTXcharcodes "01E32 "01E33 "01E32 % LATIN CAPITAL LETTER K WITH DOT BELOW
+\setXTXcharcodes "01E33 "01E33 "01E32 % LATIN SMALL LETTER K WITH DOT BELOW
+\setXTXcharcodes "01E34 "01E35 "01E34 % LATIN CAPITAL LETTER K WITH LINE BELOW
+\setXTXcharcodes "01E35 "01E35 "01E34 % LATIN SMALL LETTER K WITH LINE BELOW
+\setXTXcharcodes "01E36 "01E37 "01E36 % LATIN CAPITAL LETTER L WITH DOT BELOW
+\setXTXcharcodes "01E37 "01E37 "01E36 % LATIN SMALL LETTER L WITH DOT BELOW
+\setXTXcharcodes "01E38 "01E39 "01E38 % LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
+\setXTXcharcodes "01E39 "01E39 "01E38 % LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
+\setXTXcharcodes "01E3A "01E3B "01E3A % LATIN CAPITAL LETTER L WITH LINE BELOW
+\setXTXcharcodes "01E3B "01E3B "01E3A % LATIN SMALL LETTER L WITH LINE BELOW
+\setXTXcharcodes "01E3C "01E3D "01E3C % LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E3D "01E3D "01E3C % LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E3E "01E3F "01E3E % LATIN CAPITAL LETTER M WITH ACUTE
+\setXTXcharcodes "01E3F "01E3F "01E3E % LATIN SMALL LETTER M WITH ACUTE
+\setXTXcharcodes "01E40 "01E41 "01E40 % LATIN CAPITAL LETTER M WITH DOT ABOVE
+\setXTXcharcodes "01E41 "01E41 "01E40 % LATIN SMALL LETTER M WITH DOT ABOVE
+\setXTXcharcodes "01E42 "01E43 "01E42 % LATIN CAPITAL LETTER M WITH DOT BELOW
+\setXTXcharcodes "01E43 "01E43 "01E42 % LATIN SMALL LETTER M WITH DOT BELOW
+\setXTXcharcodes "01E44 "01E45 "01E44 % LATIN CAPITAL LETTER N WITH DOT ABOVE
+\setXTXcharcodes "01E45 "01E45 "01E44 % LATIN SMALL LETTER N WITH DOT ABOVE
+\setXTXcharcodes "01E46 "01E47 "01E46 % LATIN CAPITAL LETTER N WITH DOT BELOW
+\setXTXcharcodes "01E47 "01E47 "01E46 % LATIN SMALL LETTER N WITH DOT BELOW
+\setXTXcharcodes "01E48 "01E49 "01E48 % LATIN CAPITAL LETTER N WITH LINE BELOW
+\setXTXcharcodes "01E49 "01E49 "01E48 % LATIN SMALL LETTER N WITH LINE BELOW
+\setXTXcharcodes "01E4A "01E4B "01E4A % LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E4B "01E4B "01E4A % LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E4C "01E4D "01E4C % LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
+\setXTXcharcodes "01E4D "01E4D "01E4C % LATIN SMALL LETTER O WITH TILDE AND ACUTE
+\setXTXcharcodes "01E4E "01E4F "01E4E % LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
+\setXTXcharcodes "01E4F "01E4F "01E4E % LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
+\setXTXcharcodes "01E50 "01E51 "01E50 % LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
+\setXTXcharcodes "01E51 "01E51 "01E50 % LATIN SMALL LETTER O WITH MACRON AND GRAVE
+\setXTXcharcodes "01E52 "01E53 "01E52 % LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
+\setXTXcharcodes "01E53 "01E53 "01E52 % LATIN SMALL LETTER O WITH MACRON AND ACUTE
+\setXTXcharcodes "01E54 "01E55 "01E54 % LATIN CAPITAL LETTER P WITH ACUTE
+\setXTXcharcodes "01E55 "01E55 "01E54 % LATIN SMALL LETTER P WITH ACUTE
+\setXTXcharcodes "01E56 "01E57 "01E56 % LATIN CAPITAL LETTER P WITH DOT ABOVE
+\setXTXcharcodes "01E57 "01E57 "01E56 % LATIN SMALL LETTER P WITH DOT ABOVE
+\setXTXcharcodes "01E58 "01E59 "01E58 % LATIN CAPITAL LETTER R WITH DOT ABOVE
+\setXTXcharcodes "01E59 "01E59 "01E58 % LATIN SMALL LETTER R WITH DOT ABOVE
+\setXTXcharcodes "01E5A "01E5B "01E5A % LATIN CAPITAL LETTER R WITH DOT BELOW
+\setXTXcharcodes "01E5B "01E5B "01E5A % LATIN SMALL LETTER R WITH DOT BELOW
+\setXTXcharcodes "01E5C "01E5D "01E5C % LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
+\setXTXcharcodes "01E5D "01E5D "01E5C % LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
+\setXTXcharcodes "01E5E "01E5F "01E5E % LATIN CAPITAL LETTER R WITH LINE BELOW
+\setXTXcharcodes "01E5F "01E5F "01E5E % LATIN SMALL LETTER R WITH LINE BELOW
+\setXTXcharcodes "01E60 "01E61 "01E60 % LATIN CAPITAL LETTER S WITH DOT ABOVE
+\setXTXcharcodes "01E61 "01E61 "01E60 % LATIN SMALL LETTER S WITH DOT ABOVE
+\setXTXcharcodes "01E62 "01E63 "01E62 % LATIN CAPITAL LETTER S WITH DOT BELOW
+\setXTXcharcodes "01E63 "01E63 "01E62 % LATIN SMALL LETTER S WITH DOT BELOW
+\setXTXcharcodes "01E64 "01E65 "01E64 % LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
+\setXTXcharcodes "01E65 "01E65 "01E64 % LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
+\setXTXcharcodes "01E66 "01E67 "01E66 % LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
+\setXTXcharcodes "01E67 "01E67 "01E66 % LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
+\setXTXcharcodes "01E68 "01E69 "01E68 % LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
+\setXTXcharcodes "01E69 "01E69 "01E68 % LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
+\setXTXcharcodes "01E6A "01E6B "01E6A % LATIN CAPITAL LETTER T WITH DOT ABOVE
+\setXTXcharcodes "01E6B "01E6B "01E6A % LATIN SMALL LETTER T WITH DOT ABOVE
+\setXTXcharcodes "01E6C "01E6D "01E6C % LATIN CAPITAL LETTER T WITH DOT BELOW
+\setXTXcharcodes "01E6D "01E6D "01E6C % LATIN SMALL LETTER T WITH DOT BELOW
+\setXTXcharcodes "01E6E "01E6F "01E6E % LATIN CAPITAL LETTER T WITH LINE BELOW
+\setXTXcharcodes "01E6F "01E6F "01E6E % LATIN SMALL LETTER T WITH LINE BELOW
+\setXTXcharcodes "01E70 "01E71 "01E70 % LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E71 "01E71 "01E70 % LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E72 "01E73 "01E72 % LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
+\setXTXcharcodes "01E73 "01E73 "01E72 % LATIN SMALL LETTER U WITH DIAERESIS BELOW
+\setXTXcharcodes "01E74 "01E75 "01E74 % LATIN CAPITAL LETTER U WITH TILDE BELOW
+\setXTXcharcodes "01E75 "01E75 "01E74 % LATIN SMALL LETTER U WITH TILDE BELOW
+\setXTXcharcodes "01E76 "01E77 "01E76 % LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E77 "01E77 "01E76 % LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
+\setXTXcharcodes "01E78 "01E79 "01E78 % LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
+\setXTXcharcodes "01E79 "01E79 "01E78 % LATIN SMALL LETTER U WITH TILDE AND ACUTE
+\setXTXcharcodes "01E7A "01E7B "01E7A % LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
+\setXTXcharcodes "01E7B "01E7B "01E7A % LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
+\setXTXcharcodes "01E7C "01E7D "01E7C % LATIN CAPITAL LETTER V WITH TILDE
+\setXTXcharcodes "01E7D "01E7D "01E7C % LATIN SMALL LETTER V WITH TILDE
+\setXTXcharcodes "01E7E "01E7F "01E7E % LATIN CAPITAL LETTER V WITH DOT BELOW
+\setXTXcharcodes "01E7F "01E7F "01E7E % LATIN SMALL LETTER V WITH DOT BELOW
+\setXTXcharcodes "01E80 "01E81 "01E80 % LATIN CAPITAL LETTER W WITH GRAVE
+\setXTXcharcodes "01E81 "01E81 "01E80 % LATIN SMALL LETTER W WITH GRAVE
+\setXTXcharcodes "01E82 "01E83 "01E82 % LATIN CAPITAL LETTER W WITH ACUTE
+\setXTXcharcodes "01E83 "01E83 "01E82 % LATIN SMALL LETTER W WITH ACUTE
+\setXTXcharcodes "01E84 "01E85 "01E84 % LATIN CAPITAL LETTER W WITH DIAERESIS
+\setXTXcharcodes "01E85 "01E85 "01E84 % LATIN SMALL LETTER W WITH DIAERESIS
+\setXTXcharcodes "01E86 "01E87 "01E86 % LATIN CAPITAL LETTER W WITH DOT ABOVE
+\setXTXcharcodes "01E87 "01E87 "01E86 % LATIN SMALL LETTER W WITH DOT ABOVE
+\setXTXcharcodes "01E88 "01E89 "01E88 % LATIN CAPITAL LETTER W WITH DOT BELOW
+\setXTXcharcodes "01E89 "01E89 "01E88 % LATIN SMALL LETTER W WITH DOT BELOW
+\setXTXcharcodes "01E8A "01E8B "01E8A % LATIN CAPITAL LETTER X WITH DOT ABOVE
+\setXTXcharcodes "01E8B "01E8B "01E8A % LATIN SMALL LETTER X WITH DOT ABOVE
+\setXTXcharcodes "01E8C "01E8D "01E8C % LATIN CAPITAL LETTER X WITH DIAERESIS
+\setXTXcharcodes "01E8D "01E8D "01E8C % LATIN SMALL LETTER X WITH DIAERESIS
+\setXTXcharcodes "01E8E "01E8F "01E8E % LATIN CAPITAL LETTER Y WITH DOT ABOVE
+\setXTXcharcodes "01E8F "01E8F "01E8E % LATIN SMALL LETTER Y WITH DOT ABOVE
+\setXTXcharcodes "01E90 "01E91 "01E90 % LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
+\setXTXcharcodes "01E91 "01E91 "01E90 % LATIN SMALL LETTER Z WITH CIRCUMFLEX
+\setXTXcharcodes "01E92 "01E93 "01E92 % LATIN CAPITAL LETTER Z WITH DOT BELOW
+\setXTXcharcodes "01E93 "01E93 "01E92 % LATIN SMALL LETTER Z WITH DOT BELOW
+\setXTXcharcodes "01E94 "01E95 "01E94 % LATIN CAPITAL LETTER Z WITH LINE BELOW
+\setXTXcharcodes "01E95 "01E95 "01E94 % LATIN SMALL LETTER Z WITH LINE BELOW
+\setXTXcharcodes "01E96 "01E96 "01E96 % LATIN SMALL LETTER H WITH LINE BELOW
+\setXTXcharcodes "01E97 "01E97 "01E97 % LATIN SMALL LETTER T WITH DIAERESIS
+\setXTXcharcodes "01E98 "01E98 "01E98 % LATIN SMALL LETTER W WITH RING ABOVE
+\setXTXcharcodes "01E99 "01E99 "01E99 % LATIN SMALL LETTER Y WITH RING ABOVE
+\setXTXcharcodes "01E9A "01E9A "01E9A % LATIN SMALL LETTER A WITH RIGHT HALF RING
+\setXTXcharcodes "01E9B "01E9B "01E60 % LATIN SMALL LETTER LONG S WITH DOT ABOVE
+\setXTXcharcodes "01EA0 "01EA1 "01EA0 % LATIN CAPITAL LETTER A WITH DOT BELOW
+\setXTXcharcodes "01EA1 "01EA1 "01EA0 % LATIN SMALL LETTER A WITH DOT BELOW
+\setXTXcharcodes "01EA2 "01EA3 "01EA2 % LATIN CAPITAL LETTER A WITH HOOK ABOVE
+\setXTXcharcodes "01EA3 "01EA3 "01EA2 % LATIN SMALL LETTER A WITH HOOK ABOVE
+\setXTXcharcodes "01EA4 "01EA5 "01EA4 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
+\setXTXcharcodes "01EA5 "01EA5 "01EA4 % LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
+\setXTXcharcodes "01EA6 "01EA7 "01EA6 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
+\setXTXcharcodes "01EA7 "01EA7 "01EA6 % LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
+\setXTXcharcodes "01EA8 "01EA9 "01EA8 % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+\setXTXcharcodes "01EA9 "01EA9 "01EA8 % LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+\setXTXcharcodes "01EAA "01EAB "01EAA % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
+\setXTXcharcodes "01EAB "01EAB "01EAA % LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
+\setXTXcharcodes "01EAC "01EAD "01EAC % LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+\setXTXcharcodes "01EAD "01EAD "01EAC % LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+\setXTXcharcodes "01EAE "01EAF "01EAE % LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
+\setXTXcharcodes "01EAF "01EAF "01EAE % LATIN SMALL LETTER A WITH BREVE AND ACUTE
+\setXTXcharcodes "01EB0 "01EB1 "01EB0 % LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
+\setXTXcharcodes "01EB1 "01EB1 "01EB0 % LATIN SMALL LETTER A WITH BREVE AND GRAVE
+\setXTXcharcodes "01EB2 "01EB3 "01EB2 % LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
+\setXTXcharcodes "01EB3 "01EB3 "01EB2 % LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
+\setXTXcharcodes "01EB4 "01EB5 "01EB4 % LATIN CAPITAL LETTER A WITH BREVE AND TILDE
+\setXTXcharcodes "01EB5 "01EB5 "01EB4 % LATIN SMALL LETTER A WITH BREVE AND TILDE
+\setXTXcharcodes "01EB6 "01EB7 "01EB6 % LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
+\setXTXcharcodes "01EB7 "01EB7 "01EB6 % LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
+\setXTXcharcodes "01EB8 "01EB9 "01EB8 % LATIN CAPITAL LETTER E WITH DOT BELOW
+\setXTXcharcodes "01EB9 "01EB9 "01EB8 % LATIN SMALL LETTER E WITH DOT BELOW
+\setXTXcharcodes "01EBA "01EBB "01EBA % LATIN CAPITAL LETTER E WITH HOOK ABOVE
+\setXTXcharcodes "01EBB "01EBB "01EBA % LATIN SMALL LETTER E WITH HOOK ABOVE
+\setXTXcharcodes "01EBC "01EBD "01EBC % LATIN CAPITAL LETTER E WITH TILDE
+\setXTXcharcodes "01EBD "01EBD "01EBC % LATIN SMALL LETTER E WITH TILDE
+\setXTXcharcodes "01EBE "01EBF "01EBE % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
+\setXTXcharcodes "01EBF "01EBF "01EBE % LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
+\setXTXcharcodes "01EC0 "01EC1 "01EC0 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
+\setXTXcharcodes "01EC1 "01EC1 "01EC0 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
+\setXTXcharcodes "01EC2 "01EC3 "01EC2 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+\setXTXcharcodes "01EC3 "01EC3 "01EC2 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+\setXTXcharcodes "01EC4 "01EC5 "01EC4 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
+\setXTXcharcodes "01EC5 "01EC5 "01EC4 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
+\setXTXcharcodes "01EC6 "01EC7 "01EC6 % LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+\setXTXcharcodes "01EC7 "01EC7 "01EC6 % LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+\setXTXcharcodes "01EC8 "01EC9 "01EC8 % LATIN CAPITAL LETTER I WITH HOOK ABOVE
+\setXTXcharcodes "01EC9 "01EC9 "01EC8 % LATIN SMALL LETTER I WITH HOOK ABOVE
+\setXTXcharcodes "01ECA "01ECB "01ECA % LATIN CAPITAL LETTER I WITH DOT BELOW
+\setXTXcharcodes "01ECB "01ECB "01ECA % LATIN SMALL LETTER I WITH DOT BELOW
+\setXTXcharcodes "01ECC "01ECD "01ECC % LATIN CAPITAL LETTER O WITH DOT BELOW
+\setXTXcharcodes "01ECD "01ECD "01ECC % LATIN SMALL LETTER O WITH DOT BELOW
+\setXTXcharcodes "01ECE "01ECF "01ECE % LATIN CAPITAL LETTER O WITH HOOK ABOVE
+\setXTXcharcodes "01ECF "01ECF "01ECE % LATIN SMALL LETTER O WITH HOOK ABOVE
+\setXTXcharcodes "01ED0 "01ED1 "01ED0 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+\setXTXcharcodes "01ED1 "01ED1 "01ED0 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
+\setXTXcharcodes "01ED2 "01ED3 "01ED2 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
+\setXTXcharcodes "01ED3 "01ED3 "01ED2 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
+\setXTXcharcodes "01ED4 "01ED5 "01ED4 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+\setXTXcharcodes "01ED5 "01ED5 "01ED4 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+\setXTXcharcodes "01ED6 "01ED7 "01ED6 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
+\setXTXcharcodes "01ED7 "01ED7 "01ED6 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
+\setXTXcharcodes "01ED8 "01ED9 "01ED8 % LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+\setXTXcharcodes "01ED9 "01ED9 "01ED8 % LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+\setXTXcharcodes "01EDA "01EDB "01EDA % LATIN CAPITAL LETTER O WITH HORN AND ACUTE
+\setXTXcharcodes "01EDB "01EDB "01EDA % LATIN SMALL LETTER O WITH HORN AND ACUTE
+\setXTXcharcodes "01EDC "01EDD "01EDC % LATIN CAPITAL LETTER O WITH HORN AND GRAVE
+\setXTXcharcodes "01EDD "01EDD "01EDC % LATIN SMALL LETTER O WITH HORN AND GRAVE
+\setXTXcharcodes "01EDE "01EDF "01EDE % LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
+\setXTXcharcodes "01EDF "01EDF "01EDE % LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
+\setXTXcharcodes "01EE0 "01EE1 "01EE0 % LATIN CAPITAL LETTER O WITH HORN AND TILDE
+\setXTXcharcodes "01EE1 "01EE1 "01EE0 % LATIN SMALL LETTER O WITH HORN AND TILDE
+\setXTXcharcodes "01EE2 "01EE3 "01EE2 % LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
+\setXTXcharcodes "01EE3 "01EE3 "01EE2 % LATIN SMALL LETTER O WITH HORN AND DOT BELOW
+\setXTXcharcodes "01EE4 "01EE5 "01EE4 % LATIN CAPITAL LETTER U WITH DOT BELOW
+\setXTXcharcodes "01EE5 "01EE5 "01EE4 % LATIN SMALL LETTER U WITH DOT BELOW
+\setXTXcharcodes "01EE6 "01EE7 "01EE6 % LATIN CAPITAL LETTER U WITH HOOK ABOVE
+\setXTXcharcodes "01EE7 "01EE7 "01EE6 % LATIN SMALL LETTER U WITH HOOK ABOVE
+\setXTXcharcodes "01EE8 "01EE9 "01EE8 % LATIN CAPITAL LETTER U WITH HORN AND ACUTE
+\setXTXcharcodes "01EE9 "01EE9 "01EE8 % LATIN SMALL LETTER U WITH HORN AND ACUTE
+\setXTXcharcodes "01EEA "01EEB "01EEA % LATIN CAPITAL LETTER U WITH HORN AND GRAVE
+\setXTXcharcodes "01EEB "01EEB "01EEA % LATIN SMALL LETTER U WITH HORN AND GRAVE
+\setXTXcharcodes "01EEC "01EED "01EEC % LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
+\setXTXcharcodes "01EED "01EED "01EEC % LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
+\setXTXcharcodes "01EEE "01EEF "01EEE % LATIN CAPITAL LETTER U WITH HORN AND TILDE
+\setXTXcharcodes "01EEF "01EEF "01EEE % LATIN SMALL LETTER U WITH HORN AND TILDE
+\setXTXcharcodes "01EF0 "01EF1 "01EF0 % LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
+\setXTXcharcodes "01EF1 "01EF1 "01EF0 % LATIN SMALL LETTER U WITH HORN AND DOT BELOW
+\setXTXcharcodes "01EF2 "01EF3 "01EF2 % LATIN CAPITAL LETTER Y WITH GRAVE
+\setXTXcharcodes "01EF3 "01EF3 "01EF2 % LATIN SMALL LETTER Y WITH GRAVE
+\setXTXcharcodes "01EF4 "01EF5 "01EF4 % LATIN CAPITAL LETTER Y WITH DOT BELOW
+\setXTXcharcodes "01EF5 "01EF5 "01EF4 % LATIN SMALL LETTER Y WITH DOT BELOW
+\setXTXcharcodes "01EF6 "01EF7 "01EF6 % LATIN CAPITAL LETTER Y WITH HOOK ABOVE
+\setXTXcharcodes "01EF7 "01EF7 "01EF6 % LATIN SMALL LETTER Y WITH HOOK ABOVE
+\setXTXcharcodes "01EF8 "01EF9 "01EF8 % LATIN CAPITAL LETTER Y WITH TILDE
+\setXTXcharcodes "01EF9 "01EF9 "01EF8 % LATIN SMALL LETTER Y WITH TILDE
+\setXTXcharcodes "01F00 "01F00 "01F08 % GREEK SMALL LETTER ALPHA WITH PSILI
+\setXTXcharcodes "01F01 "01F01 "01F09 % GREEK SMALL LETTER ALPHA WITH DASIA
+\setXTXcharcodes "01F02 "01F02 "01F0A % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA
+\setXTXcharcodes "01F03 "01F03 "01F0B % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA
+\setXTXcharcodes "01F04 "01F04 "01F0C % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA
+\setXTXcharcodes "01F05 "01F05 "01F0D % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA
+\setXTXcharcodes "01F06 "01F06 "01F0E % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F07 "01F07 "01F0F % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F08 "01F00 "01F08 % GREEK CAPITAL LETTER ALPHA WITH PSILI
+\setXTXcharcodes "01F09 "01F01 "01F09 % GREEK CAPITAL LETTER ALPHA WITH DASIA
+\setXTXcharcodes "01F0A "01F02 "01F0A % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+\setXTXcharcodes "01F0B "01F03 "01F0B % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+\setXTXcharcodes "01F0C "01F04 "01F0C % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+\setXTXcharcodes "01F0D "01F05 "01F0D % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+\setXTXcharcodes "01F0E "01F06 "01F0E % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F0F "01F07 "01F0F % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F10 "01F10 "01F18 % GREEK SMALL LETTER EPSILON WITH PSILI
+\setXTXcharcodes "01F11 "01F11 "01F19 % GREEK SMALL LETTER EPSILON WITH DASIA
+\setXTXcharcodes "01F12 "01F12 "01F1A % GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA
+\setXTXcharcodes "01F13 "01F13 "01F1B % GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA
+\setXTXcharcodes "01F14 "01F14 "01F1C % GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA
+\setXTXcharcodes "01F15 "01F15 "01F1D % GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+\setXTXcharcodes "01F18 "01F10 "01F18 % GREEK CAPITAL LETTER EPSILON WITH PSILI
+\setXTXcharcodes "01F19 "01F11 "01F19 % GREEK CAPITAL LETTER EPSILON WITH DASIA
+\setXTXcharcodes "01F1A "01F12 "01F1A % GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+\setXTXcharcodes "01F1B "01F13 "01F1B % GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+\setXTXcharcodes "01F1C "01F14 "01F1C % GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+\setXTXcharcodes "01F1D "01F15 "01F1D % GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+\setXTXcharcodes "01F20 "01F20 "01F28 % GREEK SMALL LETTER ETA WITH PSILI
+\setXTXcharcodes "01F21 "01F21 "01F29 % GREEK SMALL LETTER ETA WITH DASIA
+\setXTXcharcodes "01F22 "01F22 "01F2A % GREEK SMALL LETTER ETA WITH PSILI AND VARIA
+\setXTXcharcodes "01F23 "01F23 "01F2B % GREEK SMALL LETTER ETA WITH DASIA AND VARIA
+\setXTXcharcodes "01F24 "01F24 "01F2C % GREEK SMALL LETTER ETA WITH PSILI AND OXIA
+\setXTXcharcodes "01F25 "01F25 "01F2D % GREEK SMALL LETTER ETA WITH DASIA AND OXIA
+\setXTXcharcodes "01F26 "01F26 "01F2E % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F27 "01F27 "01F2F % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F28 "01F20 "01F28 % GREEK CAPITAL LETTER ETA WITH PSILI
+\setXTXcharcodes "01F29 "01F21 "01F29 % GREEK CAPITAL LETTER ETA WITH DASIA
+\setXTXcharcodes "01F2A "01F22 "01F2A % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+\setXTXcharcodes "01F2B "01F23 "01F2B % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+\setXTXcharcodes "01F2C "01F24 "01F2C % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+\setXTXcharcodes "01F2D "01F25 "01F2D % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+\setXTXcharcodes "01F2E "01F26 "01F2E % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F2F "01F27 "01F2F % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F30 "01F30 "01F38 % GREEK SMALL LETTER IOTA WITH PSILI
+\setXTXcharcodes "01F31 "01F31 "01F39 % GREEK SMALL LETTER IOTA WITH DASIA
+\setXTXcharcodes "01F32 "01F32 "01F3A % GREEK SMALL LETTER IOTA WITH PSILI AND VARIA
+\setXTXcharcodes "01F33 "01F33 "01F3B % GREEK SMALL LETTER IOTA WITH DASIA AND VARIA
+\setXTXcharcodes "01F34 "01F34 "01F3C % GREEK SMALL LETTER IOTA WITH PSILI AND OXIA
+\setXTXcharcodes "01F35 "01F35 "01F3D % GREEK SMALL LETTER IOTA WITH DASIA AND OXIA
+\setXTXcharcodes "01F36 "01F36 "01F3E % GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F37 "01F37 "01F3F % GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F38 "01F30 "01F38 % GREEK CAPITAL LETTER IOTA WITH PSILI
+\setXTXcharcodes "01F39 "01F31 "01F39 % GREEK CAPITAL LETTER IOTA WITH DASIA
+\setXTXcharcodes "01F3A "01F32 "01F3A % GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+\setXTXcharcodes "01F3B "01F33 "01F3B % GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+\setXTXcharcodes "01F3C "01F34 "01F3C % GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+\setXTXcharcodes "01F3D "01F35 "01F3D % GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+\setXTXcharcodes "01F3E "01F36 "01F3E % GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F3F "01F37 "01F3F % GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F40 "01F40 "01F48 % GREEK SMALL LETTER OMICRON WITH PSILI
+\setXTXcharcodes "01F41 "01F41 "01F49 % GREEK SMALL LETTER OMICRON WITH DASIA
+\setXTXcharcodes "01F42 "01F42 "01F4A % GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA
+\setXTXcharcodes "01F43 "01F43 "01F4B % GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA
+\setXTXcharcodes "01F44 "01F44 "01F4C % GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA
+\setXTXcharcodes "01F45 "01F45 "01F4D % GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+\setXTXcharcodes "01F48 "01F40 "01F48 % GREEK CAPITAL LETTER OMICRON WITH PSILI
+\setXTXcharcodes "01F49 "01F41 "01F49 % GREEK CAPITAL LETTER OMICRON WITH DASIA
+\setXTXcharcodes "01F4A "01F42 "01F4A % GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+\setXTXcharcodes "01F4B "01F43 "01F4B % GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+\setXTXcharcodes "01F4C "01F44 "01F4C % GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+\setXTXcharcodes "01F4D "01F45 "01F4D % GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+\setXTXcharcodes "01F50 "01F50 "01F50 % GREEK SMALL LETTER UPSILON WITH PSILI
+\setXTXcharcodes "01F51 "01F51 "01F59 % GREEK SMALL LETTER UPSILON WITH DASIA
+\setXTXcharcodes "01F52 "01F52 "01F52 % GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
+\setXTXcharcodes "01F53 "01F53 "01F5B % GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA
+\setXTXcharcodes "01F54 "01F54 "01F54 % GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
+\setXTXcharcodes "01F55 "01F55 "01F5D % GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA
+\setXTXcharcodes "01F56 "01F56 "01F56 % GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F57 "01F57 "01F5F % GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F59 "01F51 "01F59 % GREEK CAPITAL LETTER UPSILON WITH DASIA
+\setXTXcharcodes "01F5B "01F53 "01F5B % GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+\setXTXcharcodes "01F5D "01F55 "01F5D % GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+\setXTXcharcodes "01F5F "01F57 "01F5F % GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F60 "01F60 "01F68 % GREEK SMALL LETTER OMEGA WITH PSILI
+\setXTXcharcodes "01F61 "01F61 "01F69 % GREEK SMALL LETTER OMEGA WITH DASIA
+\setXTXcharcodes "01F62 "01F62 "01F6A % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA
+\setXTXcharcodes "01F63 "01F63 "01F6B % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA
+\setXTXcharcodes "01F64 "01F64 "01F6C % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA
+\setXTXcharcodes "01F65 "01F65 "01F6D % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA
+\setXTXcharcodes "01F66 "01F66 "01F6E % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F67 "01F67 "01F6F % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F68 "01F60 "01F68 % GREEK CAPITAL LETTER OMEGA WITH PSILI
+\setXTXcharcodes "01F69 "01F61 "01F69 % GREEK CAPITAL LETTER OMEGA WITH DASIA
+\setXTXcharcodes "01F6A "01F62 "01F6A % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+\setXTXcharcodes "01F6B "01F63 "01F6B % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+\setXTXcharcodes "01F6C "01F64 "01F6C % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+\setXTXcharcodes "01F6D "01F65 "01F6D % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+\setXTXcharcodes "01F6E "01F66 "01F6E % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+\setXTXcharcodes "01F6F "01F67 "01F6F % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+\setXTXcharcodes "01F70 "01F70 "01FBA % GREEK SMALL LETTER ALPHA WITH VARIA
+\setXTXcharcodes "01F71 "01F71 "01FBB % GREEK SMALL LETTER ALPHA WITH OXIA
+\setXTXcharcodes "01F72 "01F72 "01FC8 % GREEK SMALL LETTER EPSILON WITH VARIA
+\setXTXcharcodes "01F73 "01F73 "01FC9 % GREEK SMALL LETTER EPSILON WITH OXIA
+\setXTXcharcodes "01F74 "01F74 "01FCA % GREEK SMALL LETTER ETA WITH VARIA
+\setXTXcharcodes "01F75 "01F75 "01FCB % GREEK SMALL LETTER ETA WITH OXIA
+\setXTXcharcodes "01F76 "01F76 "01FDA % GREEK SMALL LETTER IOTA WITH VARIA
+\setXTXcharcodes "01F77 "01F77 "01FDB % GREEK SMALL LETTER IOTA WITH OXIA
+\setXTXcharcodes "01F78 "01F78 "01FF8 % GREEK SMALL LETTER OMICRON WITH VARIA
+\setXTXcharcodes "01F79 "01F79 "01FF9 % GREEK SMALL LETTER OMICRON WITH OXIA
+\setXTXcharcodes "01F7A "01F7A "01FEA % GREEK SMALL LETTER UPSILON WITH VARIA
+\setXTXcharcodes "01F7B "01F7B "01FEB % GREEK SMALL LETTER UPSILON WITH OXIA
+\setXTXcharcodes "01F7C "01F7C "01FFA % GREEK SMALL LETTER OMEGA WITH VARIA
+\setXTXcharcodes "01F7D "01F7D "01FFB % GREEK SMALL LETTER OMEGA WITH OXIA
+\setXTXcharcodes "01F80 "01F80 "01F88 % GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+\setXTXcharcodes "01F81 "01F81 "01F89 % GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F82 "01F82 "01F8A % GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F83 "01F83 "01F8B % GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F84 "01F84 "01F8C % GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F85 "01F85 "01F8D % GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F86 "01F86 "01F8E % GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01F87 "01F87 "01F8F % GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01F88 "01F80 "01F88 % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+\setXTXcharcodes "01F89 "01F81 "01F89 % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F8A "01F82 "01F8A % GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F8B "01F83 "01F8B % GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F8C "01F84 "01F8C % GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F8D "01F85 "01F8D % GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F8E "01F86 "01F8E % GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+\setXTXcharcodes "01F8F "01F87 "01F8F % GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+\setXTXcharcodes "01F90 "01F90 "01F98 % GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+\setXTXcharcodes "01F91 "01F91 "01F99 % GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F92 "01F92 "01F9A % GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F93 "01F93 "01F9B % GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F94 "01F94 "01F9C % GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F95 "01F95 "01F9D % GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01F96 "01F96 "01F9E % GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01F97 "01F97 "01F9F % GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01F98 "01F90 "01F98 % GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+\setXTXcharcodes "01F99 "01F91 "01F99 % GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F9A "01F92 "01F9A % GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F9B "01F93 "01F9B % GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F9C "01F94 "01F9C % GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F9D "01F95 "01F9D % GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01F9E "01F96 "01F9E % GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+\setXTXcharcodes "01F9F "01F97 "01F9F % GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+\setXTXcharcodes "01FA0 "01FA0 "01FA8 % GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA1 "01FA1 "01FA9 % GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA2 "01FA2 "01FAA % GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA3 "01FA3 "01FAB % GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA4 "01FA4 "01FAC % GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA5 "01FA5 "01FAD % GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA6 "01FA6 "01FAE % GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA7 "01FA7 "01FAF % GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01FA8 "01FA0 "01FA8 % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+\setXTXcharcodes "01FA9 "01FA1 "01FA9 % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01FAA "01FA2 "01FAA % GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01FAB "01FA3 "01FAB % GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01FAC "01FA4 "01FAC % GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01FAD "01FA5 "01FAD % GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+\setXTXcharcodes "01FAE "01FA6 "01FAE % GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+\setXTXcharcodes "01FAF "01FA7 "01FAF % GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+\setXTXcharcodes "01FB0 "01FB0 "01FB8 % GREEK SMALL LETTER ALPHA WITH VRACHY
+\setXTXcharcodes "01FB1 "01FB1 "01FB9 % GREEK SMALL LETTER ALPHA WITH MACRON
+\setXTXcharcodes "01FB2 "01FB2 "01FB2 % GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FB3 "01FB3 "01FBC % GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+\setXTXcharcodes "01FB4 "01FB4 "01FB4 % GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FB6 "01FB6 "01FB6 % GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+\setXTXcharcodes "01FB7 "01FB7 "01FB7 % GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01FB8 "01FB0 "01FB8 % GREEK CAPITAL LETTER ALPHA WITH VRACHY
+\setXTXcharcodes "01FB9 "01FB1 "01FB9 % GREEK CAPITAL LETTER ALPHA WITH MACRON
+\setXTXcharcodes "01FBA "01F70 "01FBA % GREEK CAPITAL LETTER ALPHA WITH VARIA
+\setXTXcharcodes "01FBB "01F71 "01FBB % GREEK CAPITAL LETTER ALPHA WITH OXIA
+\setXTXcharcodes "01FBC "01FB3 "01FBC % GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+\setXTXcharcodes "01FBE "01FBE "00399 % GREEK PROSGEGRAMMENI
+\setXTXcharcodes "01FC2 "01FC2 "01FC2 % GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FC3 "01FC3 "01FCC % GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+\setXTXcharcodes "01FC4 "01FC4 "01FC4 % GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FC6 "01FC6 "01FC6 % GREEK SMALL LETTER ETA WITH PERISPOMENI
+\setXTXcharcodes "01FC7 "01FC7 "01FC7 % GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01FC8 "01F72 "01FC8 % GREEK CAPITAL LETTER EPSILON WITH VARIA
+\setXTXcharcodes "01FC9 "01F73 "01FC9 % GREEK CAPITAL LETTER EPSILON WITH OXIA
+\setXTXcharcodes "01FCA "01F74 "01FCA % GREEK CAPITAL LETTER ETA WITH VARIA
+\setXTXcharcodes "01FCB "01F75 "01FCB % GREEK CAPITAL LETTER ETA WITH OXIA
+\setXTXcharcodes "01FCC "01FC3 "01FCC % GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+\setXTXcharcodes "01FD0 "01FD0 "01FD8 % GREEK SMALL LETTER IOTA WITH VRACHY
+\setXTXcharcodes "01FD1 "01FD1 "01FD9 % GREEK SMALL LETTER IOTA WITH MACRON
+\setXTXcharcodes "01FD2 "01FD2 "01FD2 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+\setXTXcharcodes "01FD3 "01FD3 "01FD3 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+\setXTXcharcodes "01FD6 "01FD6 "01FD6 % GREEK SMALL LETTER IOTA WITH PERISPOMENI
+\setXTXcharcodes "01FD7 "01FD7 "01FD7 % GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+\setXTXcharcodes "01FD8 "01FD0 "01FD8 % GREEK CAPITAL LETTER IOTA WITH VRACHY
+\setXTXcharcodes "01FD9 "01FD1 "01FD9 % GREEK CAPITAL LETTER IOTA WITH MACRON
+\setXTXcharcodes "01FDA "01F76 "01FDA % GREEK CAPITAL LETTER IOTA WITH VARIA
+\setXTXcharcodes "01FDB "01F77 "01FDB % GREEK CAPITAL LETTER IOTA WITH OXIA
+\setXTXcharcodes "01FE0 "01FE0 "01FE8 % GREEK SMALL LETTER UPSILON WITH VRACHY
+\setXTXcharcodes "01FE1 "01FE1 "01FE9 % GREEK SMALL LETTER UPSILON WITH MACRON
+\setXTXcharcodes "01FE2 "01FE2 "01FE2 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+\setXTXcharcodes "01FE3 "01FE3 "01FE3 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+\setXTXcharcodes "01FE4 "01FE4 "01FE4 % GREEK SMALL LETTER RHO WITH PSILI
+\setXTXcharcodes "01FE5 "01FE5 "01FEC % GREEK SMALL LETTER RHO WITH DASIA
+\setXTXcharcodes "01FE6 "01FE6 "01FE6 % GREEK SMALL LETTER UPSILON WITH PERISPOMENI
+\setXTXcharcodes "01FE7 "01FE7 "01FE7 % GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+\setXTXcharcodes "01FE8 "01FE0 "01FE8 % GREEK CAPITAL LETTER UPSILON WITH VRACHY
+\setXTXcharcodes "01FE9 "01FE1 "01FE9 % GREEK CAPITAL LETTER UPSILON WITH MACRON
+\setXTXcharcodes "01FEA "01F7A "01FEA % GREEK CAPITAL LETTER UPSILON WITH VARIA
+\setXTXcharcodes "01FEB "01F7B "01FEB % GREEK CAPITAL LETTER UPSILON WITH OXIA
+\setXTXcharcodes "01FEC "01FE5 "01FEC % GREEK CAPITAL LETTER RHO WITH DASIA
+\setXTXcharcodes "01FF2 "01FF2 "01FF2 % GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FF3 "01FF3 "01FFC % GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+\setXTXcharcodes "01FF4 "01FF4 "01FF4 % GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+\setXTXcharcodes "01FF6 "01FF6 "01FF6 % GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+\setXTXcharcodes "01FF7 "01FF7 "01FF7 % GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
+\setXTXcharcodes "01FF8 "01F78 "01FF8 % GREEK CAPITAL LETTER OMICRON WITH VARIA
+\setXTXcharcodes "01FF9 "01F79 "01FF9 % GREEK CAPITAL LETTER OMICRON WITH OXIA
+\setXTXcharcodes "01FFA "01F7C "01FFA % GREEK CAPITAL LETTER OMEGA WITH VARIA
+\setXTXcharcodes "01FFB "01F7D "01FFB % GREEK CAPITAL LETTER OMEGA WITH OXIA
+\setXTXcharcodes "01FFC "01FF3 "01FFC % GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+\setXTXcharcodes "02071 "02071 "02071 % SUPERSCRIPT LATIN SMALL LETTER I
+\setXTXcharcodes "0207F "0207F "0207F % SUPERSCRIPT LATIN SMALL LETTER N
+\setXTXcharcodes "02102 "02102 "02102 % DOUBLE-STRUCK CAPITAL C
+\setXTXcharcodes "02107 "02107 "02107 % EULER CONSTANT
+\setXTXcharcodes "0210A "0210A "0210A % SCRIPT SMALL G
+\setXTXcharcodes "0210B "0210B "0210B % SCRIPT CAPITAL H
+\setXTXcharcodes "0210C "0210C "0210C % BLACK-LETTER CAPITAL H
+\setXTXcharcodes "0210D "0210D "0210D % DOUBLE-STRUCK CAPITAL H
+\setXTXcharcodes "0210E "0210E "0210E % PLANCK CONSTANT
+\setXTXcharcodes "0210F "0210F "0210F % PLANCK CONSTANT OVER TWO PI
+\setXTXcharcodes "02110 "02110 "02110 % SCRIPT CAPITAL I
+\setXTXcharcodes "02111 "02111 "02111 % BLACK-LETTER CAPITAL I
+\setXTXcharcodes "02112 "02112 "02112 % SCRIPT CAPITAL L
+\setXTXcharcodes "02113 "02113 "02113 % SCRIPT SMALL L
+\setXTXcharcodes "02115 "02115 "02115 % DOUBLE-STRUCK CAPITAL N
+\setXTXcharcodes "02119 "02119 "02119 % DOUBLE-STRUCK CAPITAL P
+\setXTXcharcodes "0211A "0211A "0211A % DOUBLE-STRUCK CAPITAL Q
+\setXTXcharcodes "0211B "0211B "0211B % SCRIPT CAPITAL R
+\setXTXcharcodes "0211C "0211C "0211C % BLACK-LETTER CAPITAL R
+\setXTXcharcodes "0211D "0211D "0211D % DOUBLE-STRUCK CAPITAL R
+\setXTXcharcodes "02124 "02124 "02124 % DOUBLE-STRUCK CAPITAL Z
+\setXTXcharcodes "02126 "003C9 "02126 % OHM SIGN
+\setXTXcharcodes "02128 "02128 "02128 % BLACK-LETTER CAPITAL Z
+\setXTXcharcodes "0212A "0006B "0212A % KELVIN SIGN
+\setXTXcharcodes "0212B "000E5 "0212B % ANGSTROM SIGN
+\setXTXcharcodes "0212C "0212C "0212C % SCRIPT CAPITAL B
+\setXTXcharcodes "0212D "0212D "0212D % BLACK-LETTER CAPITAL C
+\setXTXcharcodes "0212F "0212F "0212F % SCRIPT SMALL E
+\setXTXcharcodes "02130 "02130 "02130 % SCRIPT CAPITAL E
+\setXTXcharcodes "02131 "02131 "02131 % SCRIPT CAPITAL F
+\setXTXcharcodes "02132 "0214E "02132 % TURNED CAPITAL F
+\setXTXcharcodes "02133 "02133 "02133 % SCRIPT CAPITAL M
+\setXTXcharcodes "02134 "02134 "02134 % SCRIPT SMALL O
+\setXTXcharcodes "02139 "02139 "02139 % INFORMATION SOURCE
+\setXTXcharcodes "0213C "0213C "0213C % DOUBLE-STRUCK SMALL PI
+\setXTXcharcodes "0213D "0213D "0213D % DOUBLE-STRUCK SMALL GAMMA
+\setXTXcharcodes "0213E "0213E "0213E % DOUBLE-STRUCK CAPITAL GAMMA
+\setXTXcharcodes "0213F "0213F "0213F % DOUBLE-STRUCK CAPITAL PI
+\setXTXcharcodes "02145 "02145 "02145 % DOUBLE-STRUCK ITALIC CAPITAL D
+\setXTXcharcodes "02146 "02146 "02146 % DOUBLE-STRUCK ITALIC SMALL D
+\setXTXcharcodes "02147 "02147 "02147 % DOUBLE-STRUCK ITALIC SMALL E
+\setXTXcharcodes "02148 "02148 "02148 % DOUBLE-STRUCK ITALIC SMALL I
+\setXTXcharcodes "02149 "02149 "02149 % DOUBLE-STRUCK ITALIC SMALL J
+\setXTXcharcodes "0214E "0214E "02132 % TURNED SMALL F
+\setXTXcharcodes "02183 "02184 "02183 % ROMAN NUMERAL REVERSED ONE HUNDRED
+\setXTXcharcodes "02184 "02184 "02183 % LATIN SMALL LETTER REVERSED C
+\setXTXcharcodes "02C00 "02C30 "02C00 % GLAGOLITIC CAPITAL LETTER AZU
+\setXTXcharcodes "02C01 "02C31 "02C01 % GLAGOLITIC CAPITAL LETTER BUKY
+\setXTXcharcodes "02C02 "02C32 "02C02 % GLAGOLITIC CAPITAL LETTER VEDE
+\setXTXcharcodes "02C03 "02C33 "02C03 % GLAGOLITIC CAPITAL LETTER GLAGOLI
+\setXTXcharcodes "02C04 "02C34 "02C04 % GLAGOLITIC CAPITAL LETTER DOBRO
+\setXTXcharcodes "02C05 "02C35 "02C05 % GLAGOLITIC CAPITAL LETTER YESTU
+\setXTXcharcodes "02C06 "02C36 "02C06 % GLAGOLITIC CAPITAL LETTER ZHIVETE
+\setXTXcharcodes "02C07 "02C37 "02C07 % GLAGOLITIC CAPITAL LETTER DZELO
+\setXTXcharcodes "02C08 "02C38 "02C08 % GLAGOLITIC CAPITAL LETTER ZEMLJA
+\setXTXcharcodes "02C09 "02C39 "02C09 % GLAGOLITIC CAPITAL LETTER IZHE
+\setXTXcharcodes "02C0A "02C3A "02C0A % GLAGOLITIC CAPITAL LETTER INITIAL IZHE
+\setXTXcharcodes "02C0B "02C3B "02C0B % GLAGOLITIC CAPITAL LETTER I
+\setXTXcharcodes "02C0C "02C3C "02C0C % GLAGOLITIC CAPITAL LETTER DJERVI
+\setXTXcharcodes "02C0D "02C3D "02C0D % GLAGOLITIC CAPITAL LETTER KAKO
+\setXTXcharcodes "02C0E "02C3E "02C0E % GLAGOLITIC CAPITAL LETTER LJUDIJE
+\setXTXcharcodes "02C0F "02C3F "02C0F % GLAGOLITIC CAPITAL LETTER MYSLITE
+\setXTXcharcodes "02C10 "02C40 "02C10 % GLAGOLITIC CAPITAL LETTER NASHI
+\setXTXcharcodes "02C11 "02C41 "02C11 % GLAGOLITIC CAPITAL LETTER ONU
+\setXTXcharcodes "02C12 "02C42 "02C12 % GLAGOLITIC CAPITAL LETTER POKOJI
+\setXTXcharcodes "02C13 "02C43 "02C13 % GLAGOLITIC CAPITAL LETTER RITSI
+\setXTXcharcodes "02C14 "02C44 "02C14 % GLAGOLITIC CAPITAL LETTER SLOVO
+\setXTXcharcodes "02C15 "02C45 "02C15 % GLAGOLITIC CAPITAL LETTER TVRIDO
+\setXTXcharcodes "02C16 "02C46 "02C16 % GLAGOLITIC CAPITAL LETTER UKU
+\setXTXcharcodes "02C17 "02C47 "02C17 % GLAGOLITIC CAPITAL LETTER FRITU
+\setXTXcharcodes "02C18 "02C48 "02C18 % GLAGOLITIC CAPITAL LETTER HERU
+\setXTXcharcodes "02C19 "02C49 "02C19 % GLAGOLITIC CAPITAL LETTER OTU
+\setXTXcharcodes "02C1A "02C4A "02C1A % GLAGOLITIC CAPITAL LETTER PE
+\setXTXcharcodes "02C1B "02C4B "02C1B % GLAGOLITIC CAPITAL LETTER SHTA
+\setXTXcharcodes "02C1C "02C4C "02C1C % GLAGOLITIC CAPITAL LETTER TSI
+\setXTXcharcodes "02C1D "02C4D "02C1D % GLAGOLITIC CAPITAL LETTER CHRIVI
+\setXTXcharcodes "02C1E "02C4E "02C1E % GLAGOLITIC CAPITAL LETTER SHA
+\setXTXcharcodes "02C1F "02C4F "02C1F % GLAGOLITIC CAPITAL LETTER YERU
+\setXTXcharcodes "02C20 "02C50 "02C20 % GLAGOLITIC CAPITAL LETTER YERI
+\setXTXcharcodes "02C21 "02C51 "02C21 % GLAGOLITIC CAPITAL LETTER YATI
+\setXTXcharcodes "02C22 "02C52 "02C22 % GLAGOLITIC CAPITAL LETTER SPIDERY HA
+\setXTXcharcodes "02C23 "02C53 "02C23 % GLAGOLITIC CAPITAL LETTER YU
+\setXTXcharcodes "02C24 "02C54 "02C24 % GLAGOLITIC CAPITAL LETTER SMALL YUS
+\setXTXcharcodes "02C25 "02C55 "02C25 % GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
+\setXTXcharcodes "02C26 "02C56 "02C26 % GLAGOLITIC CAPITAL LETTER YO
+\setXTXcharcodes "02C27 "02C57 "02C27 % GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
+\setXTXcharcodes "02C28 "02C58 "02C28 % GLAGOLITIC CAPITAL LETTER BIG YUS
+\setXTXcharcodes "02C29 "02C59 "02C29 % GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
+\setXTXcharcodes "02C2A "02C5A "02C2A % GLAGOLITIC CAPITAL LETTER FITA
+\setXTXcharcodes "02C2B "02C5B "02C2B % GLAGOLITIC CAPITAL LETTER IZHITSA
+\setXTXcharcodes "02C2C "02C5C "02C2C % GLAGOLITIC CAPITAL LETTER SHTAPIC
+\setXTXcharcodes "02C2D "02C5D "02C2D % GLAGOLITIC CAPITAL LETTER TROKUTASTI A
+\setXTXcharcodes "02C2E "02C5E "02C2E % GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
+\setXTXcharcodes "02C30 "02C30 "02C00 % GLAGOLITIC SMALL LETTER AZU
+\setXTXcharcodes "02C31 "02C31 "02C01 % GLAGOLITIC SMALL LETTER BUKY
+\setXTXcharcodes "02C32 "02C32 "02C02 % GLAGOLITIC SMALL LETTER VEDE
+\setXTXcharcodes "02C33 "02C33 "02C03 % GLAGOLITIC SMALL LETTER GLAGOLI
+\setXTXcharcodes "02C34 "02C34 "02C04 % GLAGOLITIC SMALL LETTER DOBRO
+\setXTXcharcodes "02C35 "02C35 "02C05 % GLAGOLITIC SMALL LETTER YESTU
+\setXTXcharcodes "02C36 "02C36 "02C06 % GLAGOLITIC SMALL LETTER ZHIVETE
+\setXTXcharcodes "02C37 "02C37 "02C07 % GLAGOLITIC SMALL LETTER DZELO
+\setXTXcharcodes "02C38 "02C38 "02C08 % GLAGOLITIC SMALL LETTER ZEMLJA
+\setXTXcharcodes "02C39 "02C39 "02C09 % GLAGOLITIC SMALL LETTER IZHE
+\setXTXcharcodes "02C3A "02C3A "02C0A % GLAGOLITIC SMALL LETTER INITIAL IZHE
+\setXTXcharcodes "02C3B "02C3B "02C0B % GLAGOLITIC SMALL LETTER I
+\setXTXcharcodes "02C3C "02C3C "02C0C % GLAGOLITIC SMALL LETTER DJERVI
+\setXTXcharcodes "02C3D "02C3D "02C0D % GLAGOLITIC SMALL LETTER KAKO
+\setXTXcharcodes "02C3E "02C3E "02C0E % GLAGOLITIC SMALL LETTER LJUDIJE
+\setXTXcharcodes "02C3F "02C3F "02C0F % GLAGOLITIC SMALL LETTER MYSLITE
+\setXTXcharcodes "02C40 "02C40 "02C10 % GLAGOLITIC SMALL LETTER NASHI
+\setXTXcharcodes "02C41 "02C41 "02C11 % GLAGOLITIC SMALL LETTER ONU
+\setXTXcharcodes "02C42 "02C42 "02C12 % GLAGOLITIC SMALL LETTER POKOJI
+\setXTXcharcodes "02C43 "02C43 "02C13 % GLAGOLITIC SMALL LETTER RITSI
+\setXTXcharcodes "02C44 "02C44 "02C14 % GLAGOLITIC SMALL LETTER SLOVO
+\setXTXcharcodes "02C45 "02C45 "02C15 % GLAGOLITIC SMALL LETTER TVRIDO
+\setXTXcharcodes "02C46 "02C46 "02C16 % GLAGOLITIC SMALL LETTER UKU
+\setXTXcharcodes "02C47 "02C47 "02C17 % GLAGOLITIC SMALL LETTER FRITU
+\setXTXcharcodes "02C48 "02C48 "02C18 % GLAGOLITIC SMALL LETTER HERU
+\setXTXcharcodes "02C49 "02C49 "02C19 % GLAGOLITIC SMALL LETTER OTU
+\setXTXcharcodes "02C4A "02C4A "02C1A % GLAGOLITIC SMALL LETTER PE
+\setXTXcharcodes "02C4B "02C4B "02C1B % GLAGOLITIC SMALL LETTER SHTA
+\setXTXcharcodes "02C4C "02C4C "02C1C % GLAGOLITIC SMALL LETTER TSI
+\setXTXcharcodes "02C4D "02C4D "02C1D % GLAGOLITIC SMALL LETTER CHRIVI
+\setXTXcharcodes "02C4E "02C4E "02C1E % GLAGOLITIC SMALL LETTER SHA
+\setXTXcharcodes "02C4F "02C4F "02C1F % GLAGOLITIC SMALL LETTER YERU
+\setXTXcharcodes "02C50 "02C50 "02C20 % GLAGOLITIC SMALL LETTER YERI
+\setXTXcharcodes "02C51 "02C51 "02C21 % GLAGOLITIC SMALL LETTER YATI
+\setXTXcharcodes "02C52 "02C52 "02C22 % GLAGOLITIC SMALL LETTER SPIDERY HA
+\setXTXcharcodes "02C53 "02C53 "02C23 % GLAGOLITIC SMALL LETTER YU
+\setXTXcharcodes "02C54 "02C54 "02C24 % GLAGOLITIC SMALL LETTER SMALL YUS
+\setXTXcharcodes "02C55 "02C55 "02C25 % GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL
+\setXTXcharcodes "02C56 "02C56 "02C26 % GLAGOLITIC SMALL LETTER YO
+\setXTXcharcodes "02C57 "02C57 "02C27 % GLAGOLITIC SMALL LETTER IOTATED SMALL YUS
+\setXTXcharcodes "02C58 "02C58 "02C28 % GLAGOLITIC SMALL LETTER BIG YUS
+\setXTXcharcodes "02C59 "02C59 "02C29 % GLAGOLITIC SMALL LETTER IOTATED BIG YUS
+\setXTXcharcodes "02C5A "02C5A "02C2A % GLAGOLITIC SMALL LETTER FITA
+\setXTXcharcodes "02C5B "02C5B "02C2B % GLAGOLITIC SMALL LETTER IZHITSA
+\setXTXcharcodes "02C5C "02C5C "02C2C % GLAGOLITIC SMALL LETTER SHTAPIC
+\setXTXcharcodes "02C5D "02C5D "02C2D % GLAGOLITIC SMALL LETTER TROKUTASTI A
+\setXTXcharcodes "02C5E "02C5E "02C2E % GLAGOLITIC SMALL LETTER LATINATE MYSLITE
+\setXTXcharcodes "02C60 "02C61 "02C60 % LATIN CAPITAL LETTER L WITH DOUBLE BAR
+\setXTXcharcodes "02C61 "02C61 "02C60 % LATIN SMALL LETTER L WITH DOUBLE BAR
+\setXTXcharcodes "02C62 "0026B "02C62 % LATIN CAPITAL LETTER L WITH MIDDLE TILDE
+\setXTXcharcodes "02C63 "01D7D "02C63 % LATIN CAPITAL LETTER P WITH STROKE
+\setXTXcharcodes "02C64 "0027D "02C64 % LATIN CAPITAL LETTER R WITH TAIL
+\setXTXcharcodes "02C65 "02C65 "0023A % LATIN SMALL LETTER A WITH STROKE
+\setXTXcharcodes "02C66 "02C66 "0023E % LATIN SMALL LETTER T WITH DIAGONAL STROKE
+\setXTXcharcodes "02C67 "02C68 "02C67 % LATIN CAPITAL LETTER H WITH DESCENDER
+\setXTXcharcodes "02C68 "02C68 "02C67 % LATIN SMALL LETTER H WITH DESCENDER
+\setXTXcharcodes "02C69 "02C6A "02C69 % LATIN CAPITAL LETTER K WITH DESCENDER
+\setXTXcharcodes "02C6A "02C6A "02C69 % LATIN SMALL LETTER K WITH DESCENDER
+\setXTXcharcodes "02C6B "02C6C "02C6B % LATIN CAPITAL LETTER Z WITH DESCENDER
+\setXTXcharcodes "02C6C "02C6C "02C6B % LATIN SMALL LETTER Z WITH DESCENDER
+\setXTXcharcodes "02C74 "02C74 "02C74 % LATIN SMALL LETTER V WITH CURL
+\setXTXcharcodes "02C75 "02C76 "02C75 % LATIN CAPITAL LETTER HALF H
+\setXTXcharcodes "02C76 "02C76 "02C75 % LATIN SMALL LETTER HALF H
+\setXTXcharcodes "02C77 "02C77 "02C77 % LATIN SMALL LETTER TAILLESS PHI
+\setXTXcharcodes "02C80 "02C81 "02C80 % COPTIC CAPITAL LETTER ALFA
+\setXTXcharcodes "02C81 "02C81 "02C80 % COPTIC SMALL LETTER ALFA
+\setXTXcharcodes "02C82 "02C83 "02C82 % COPTIC CAPITAL LETTER VIDA
+\setXTXcharcodes "02C83 "02C83 "02C82 % COPTIC SMALL LETTER VIDA
+\setXTXcharcodes "02C84 "02C85 "02C84 % COPTIC CAPITAL LETTER GAMMA
+\setXTXcharcodes "02C85 "02C85 "02C84 % COPTIC SMALL LETTER GAMMA
+\setXTXcharcodes "02C86 "02C87 "02C86 % COPTIC CAPITAL LETTER DALDA
+\setXTXcharcodes "02C87 "02C87 "02C86 % COPTIC SMALL LETTER DALDA
+\setXTXcharcodes "02C88 "02C89 "02C88 % COPTIC CAPITAL LETTER EIE
+\setXTXcharcodes "02C89 "02C89 "02C88 % COPTIC SMALL LETTER EIE
+\setXTXcharcodes "02C8A "02C8B "02C8A % COPTIC CAPITAL LETTER SOU
+\setXTXcharcodes "02C8B "02C8B "02C8A % COPTIC SMALL LETTER SOU
+\setXTXcharcodes "02C8C "02C8D "02C8C % COPTIC CAPITAL LETTER ZATA
+\setXTXcharcodes "02C8D "02C8D "02C8C % COPTIC SMALL LETTER ZATA
+\setXTXcharcodes "02C8E "02C8F "02C8E % COPTIC CAPITAL LETTER HATE
+\setXTXcharcodes "02C8F "02C8F "02C8E % COPTIC SMALL LETTER HATE
+\setXTXcharcodes "02C90 "02C91 "02C90 % COPTIC CAPITAL LETTER THETHE
+\setXTXcharcodes "02C91 "02C91 "02C90 % COPTIC SMALL LETTER THETHE
+\setXTXcharcodes "02C92 "02C93 "02C92 % COPTIC CAPITAL LETTER IAUDA
+\setXTXcharcodes "02C93 "02C93 "02C92 % COPTIC SMALL LETTER IAUDA
+\setXTXcharcodes "02C94 "02C95 "02C94 % COPTIC CAPITAL LETTER KAPA
+\setXTXcharcodes "02C95 "02C95 "02C94 % COPTIC SMALL LETTER KAPA
+\setXTXcharcodes "02C96 "02C97 "02C96 % COPTIC CAPITAL LETTER LAULA
+\setXTXcharcodes "02C97 "02C97 "02C96 % COPTIC SMALL LETTER LAULA
+\setXTXcharcodes "02C98 "02C99 "02C98 % COPTIC CAPITAL LETTER MI
+\setXTXcharcodes "02C99 "02C99 "02C98 % COPTIC SMALL LETTER MI
+\setXTXcharcodes "02C9A "02C9B "02C9A % COPTIC CAPITAL LETTER NI
+\setXTXcharcodes "02C9B "02C9B "02C9A % COPTIC SMALL LETTER NI
+\setXTXcharcodes "02C9C "02C9D "02C9C % COPTIC CAPITAL LETTER KSI
+\setXTXcharcodes "02C9D "02C9D "02C9C % COPTIC SMALL LETTER KSI
+\setXTXcharcodes "02C9E "02C9F "02C9E % COPTIC CAPITAL LETTER O
+\setXTXcharcodes "02C9F "02C9F "02C9E % COPTIC SMALL LETTER O
+\setXTXcharcodes "02CA0 "02CA1 "02CA0 % COPTIC CAPITAL LETTER PI
+\setXTXcharcodes "02CA1 "02CA1 "02CA0 % COPTIC SMALL LETTER PI
+\setXTXcharcodes "02CA2 "02CA3 "02CA2 % COPTIC CAPITAL LETTER RO
+\setXTXcharcodes "02CA3 "02CA3 "02CA2 % COPTIC SMALL LETTER RO
+\setXTXcharcodes "02CA4 "02CA5 "02CA4 % COPTIC CAPITAL LETTER SIMA
+\setXTXcharcodes "02CA5 "02CA5 "02CA4 % COPTIC SMALL LETTER SIMA
+\setXTXcharcodes "02CA6 "02CA7 "02CA6 % COPTIC CAPITAL LETTER TAU
+\setXTXcharcodes "02CA7 "02CA7 "02CA6 % COPTIC SMALL LETTER TAU
+\setXTXcharcodes "02CA8 "02CA9 "02CA8 % COPTIC CAPITAL LETTER UA
+\setXTXcharcodes "02CA9 "02CA9 "02CA8 % COPTIC SMALL LETTER UA
+\setXTXcharcodes "02CAA "02CAB "02CAA % COPTIC CAPITAL LETTER FI
+\setXTXcharcodes "02CAB "02CAB "02CAA % COPTIC SMALL LETTER FI
+\setXTXcharcodes "02CAC "02CAD "02CAC % COPTIC CAPITAL LETTER KHI
+\setXTXcharcodes "02CAD "02CAD "02CAC % COPTIC SMALL LETTER KHI
+\setXTXcharcodes "02CAE "02CAF "02CAE % COPTIC CAPITAL LETTER PSI
+\setXTXcharcodes "02CAF "02CAF "02CAE % COPTIC SMALL LETTER PSI
+\setXTXcharcodes "02CB0 "02CB1 "02CB0 % COPTIC CAPITAL LETTER OOU
+\setXTXcharcodes "02CB1 "02CB1 "02CB0 % COPTIC SMALL LETTER OOU
+\setXTXcharcodes "02CB2 "02CB3 "02CB2 % COPTIC CAPITAL LETTER DIALECT-P ALEF
+\setXTXcharcodes "02CB3 "02CB3 "02CB2 % COPTIC SMALL LETTER DIALECT-P ALEF
+\setXTXcharcodes "02CB4 "02CB5 "02CB4 % COPTIC CAPITAL LETTER OLD COPTIC AIN
+\setXTXcharcodes "02CB5 "02CB5 "02CB4 % COPTIC SMALL LETTER OLD COPTIC AIN
+\setXTXcharcodes "02CB6 "02CB7 "02CB6 % COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
+\setXTXcharcodes "02CB7 "02CB7 "02CB6 % COPTIC SMALL LETTER CRYPTOGRAMMIC EIE
+\setXTXcharcodes "02CB8 "02CB9 "02CB8 % COPTIC CAPITAL LETTER DIALECT-P KAPA
+\setXTXcharcodes "02CB9 "02CB9 "02CB8 % COPTIC SMALL LETTER DIALECT-P KAPA
+\setXTXcharcodes "02CBA "02CBB "02CBA % COPTIC CAPITAL LETTER DIALECT-P NI
+\setXTXcharcodes "02CBB "02CBB "02CBA % COPTIC SMALL LETTER DIALECT-P NI
+\setXTXcharcodes "02CBC "02CBD "02CBC % COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
+\setXTXcharcodes "02CBD "02CBD "02CBC % COPTIC SMALL LETTER CRYPTOGRAMMIC NI
+\setXTXcharcodes "02CBE "02CBF "02CBE % COPTIC CAPITAL LETTER OLD COPTIC OOU
+\setXTXcharcodes "02CBF "02CBF "02CBE % COPTIC SMALL LETTER OLD COPTIC OOU
+\setXTXcharcodes "02CC0 "02CC1 "02CC0 % COPTIC CAPITAL LETTER SAMPI
+\setXTXcharcodes "02CC1 "02CC1 "02CC0 % COPTIC SMALL LETTER SAMPI
+\setXTXcharcodes "02CC2 "02CC3 "02CC2 % COPTIC CAPITAL LETTER CROSSED SHEI
+\setXTXcharcodes "02CC3 "02CC3 "02CC2 % COPTIC SMALL LETTER CROSSED SHEI
+\setXTXcharcodes "02CC4 "02CC5 "02CC4 % COPTIC CAPITAL LETTER OLD COPTIC SHEI
+\setXTXcharcodes "02CC5 "02CC5 "02CC4 % COPTIC SMALL LETTER OLD COPTIC SHEI
+\setXTXcharcodes "02CC6 "02CC7 "02CC6 % COPTIC CAPITAL LETTER OLD COPTIC ESH
+\setXTXcharcodes "02CC7 "02CC7 "02CC6 % COPTIC SMALL LETTER OLD COPTIC ESH
+\setXTXcharcodes "02CC8 "02CC9 "02CC8 % COPTIC CAPITAL LETTER AKHMIMIC KHEI
+\setXTXcharcodes "02CC9 "02CC9 "02CC8 % COPTIC SMALL LETTER AKHMIMIC KHEI
+\setXTXcharcodes "02CCA "02CCB "02CCA % COPTIC CAPITAL LETTER DIALECT-P HORI
+\setXTXcharcodes "02CCB "02CCB "02CCA % COPTIC SMALL LETTER DIALECT-P HORI
+\setXTXcharcodes "02CCC "02CCD "02CCC % COPTIC CAPITAL LETTER OLD COPTIC HORI
+\setXTXcharcodes "02CCD "02CCD "02CCC % COPTIC SMALL LETTER OLD COPTIC HORI
+\setXTXcharcodes "02CCE "02CCF "02CCE % COPTIC CAPITAL LETTER OLD COPTIC HA
+\setXTXcharcodes "02CCF "02CCF "02CCE % COPTIC SMALL LETTER OLD COPTIC HA
+\setXTXcharcodes "02CD0 "02CD1 "02CD0 % COPTIC CAPITAL LETTER L-SHAPED HA
+\setXTXcharcodes "02CD1 "02CD1 "02CD0 % COPTIC SMALL LETTER L-SHAPED HA
+\setXTXcharcodes "02CD2 "02CD3 "02CD2 % COPTIC CAPITAL LETTER OLD COPTIC HEI
+\setXTXcharcodes "02CD3 "02CD3 "02CD2 % COPTIC SMALL LETTER OLD COPTIC HEI
+\setXTXcharcodes "02CD4 "02CD5 "02CD4 % COPTIC CAPITAL LETTER OLD COPTIC HAT
+\setXTXcharcodes "02CD5 "02CD5 "02CD4 % COPTIC SMALL LETTER OLD COPTIC HAT
+\setXTXcharcodes "02CD6 "02CD7 "02CD6 % COPTIC CAPITAL LETTER OLD COPTIC GANGIA
+\setXTXcharcodes "02CD7 "02CD7 "02CD6 % COPTIC SMALL LETTER OLD COPTIC GANGIA
+\setXTXcharcodes "02CD8 "02CD9 "02CD8 % COPTIC CAPITAL LETTER OLD COPTIC DJA
+\setXTXcharcodes "02CD9 "02CD9 "02CD8 % COPTIC SMALL LETTER OLD COPTIC DJA
+\setXTXcharcodes "02CDA "02CDB "02CDA % COPTIC CAPITAL LETTER OLD COPTIC SHIMA
+\setXTXcharcodes "02CDB "02CDB "02CDA % COPTIC SMALL LETTER OLD COPTIC SHIMA
+\setXTXcharcodes "02CDC "02CDD "02CDC % COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
+\setXTXcharcodes "02CDD "02CDD "02CDC % COPTIC SMALL LETTER OLD NUBIAN SHIMA
+\setXTXcharcodes "02CDE "02CDF "02CDE % COPTIC CAPITAL LETTER OLD NUBIAN NGI
+\setXTXcharcodes "02CDF "02CDF "02CDE % COPTIC SMALL LETTER OLD NUBIAN NGI
+\setXTXcharcodes "02CE0 "02CE1 "02CE0 % COPTIC CAPITAL LETTER OLD NUBIAN NYI
+\setXTXcharcodes "02CE1 "02CE1 "02CE0 % COPTIC SMALL LETTER OLD NUBIAN NYI
+\setXTXcharcodes "02CE2 "02CE3 "02CE2 % COPTIC CAPITAL LETTER OLD NUBIAN WAU
+\setXTXcharcodes "02CE3 "02CE3 "02CE2 % COPTIC SMALL LETTER OLD NUBIAN WAU
+\setXTXcharcodes "02CE4 "02CE4 "02CE4 % COPTIC SYMBOL KAI
+\setXTXcharcodes "02D00 "02D00 "010A0 % GEORGIAN SMALL LETTER AN
+\setXTXcharcodes "02D01 "02D01 "010A1 % GEORGIAN SMALL LETTER BAN
+\setXTXcharcodes "02D02 "02D02 "010A2 % GEORGIAN SMALL LETTER GAN
+\setXTXcharcodes "02D03 "02D03 "010A3 % GEORGIAN SMALL LETTER DON
+\setXTXcharcodes "02D04 "02D04 "010A4 % GEORGIAN SMALL LETTER EN
+\setXTXcharcodes "02D05 "02D05 "010A5 % GEORGIAN SMALL LETTER VIN
+\setXTXcharcodes "02D06 "02D06 "010A6 % GEORGIAN SMALL LETTER ZEN
+\setXTXcharcodes "02D07 "02D07 "010A7 % GEORGIAN SMALL LETTER TAN
+\setXTXcharcodes "02D08 "02D08 "010A8 % GEORGIAN SMALL LETTER IN
+\setXTXcharcodes "02D09 "02D09 "010A9 % GEORGIAN SMALL LETTER KAN
+\setXTXcharcodes "02D0A "02D0A "010AA % GEORGIAN SMALL LETTER LAS
+\setXTXcharcodes "02D0B "02D0B "010AB % GEORGIAN SMALL LETTER MAN
+\setXTXcharcodes "02D0C "02D0C "010AC % GEORGIAN SMALL LETTER NAR
+\setXTXcharcodes "02D0D "02D0D "010AD % GEORGIAN SMALL LETTER ON
+\setXTXcharcodes "02D0E "02D0E "010AE % GEORGIAN SMALL LETTER PAR
+\setXTXcharcodes "02D0F "02D0F "010AF % GEORGIAN SMALL LETTER ZHAR
+\setXTXcharcodes "02D10 "02D10 "010B0 % GEORGIAN SMALL LETTER RAE
+\setXTXcharcodes "02D11 "02D11 "010B1 % GEORGIAN SMALL LETTER SAN
+\setXTXcharcodes "02D12 "02D12 "010B2 % GEORGIAN SMALL LETTER TAR
+\setXTXcharcodes "02D13 "02D13 "010B3 % GEORGIAN SMALL LETTER UN
+\setXTXcharcodes "02D14 "02D14 "010B4 % GEORGIAN SMALL LETTER PHAR
+\setXTXcharcodes "02D15 "02D15 "010B5 % GEORGIAN SMALL LETTER KHAR
+\setXTXcharcodes "02D16 "02D16 "010B6 % GEORGIAN SMALL LETTER GHAN
+\setXTXcharcodes "02D17 "02D17 "010B7 % GEORGIAN SMALL LETTER QAR
+\setXTXcharcodes "02D18 "02D18 "010B8 % GEORGIAN SMALL LETTER SHIN
+\setXTXcharcodes "02D19 "02D19 "010B9 % GEORGIAN SMALL LETTER CHIN
+\setXTXcharcodes "02D1A "02D1A "010BA % GEORGIAN SMALL LETTER CAN
+\setXTXcharcodes "02D1B "02D1B "010BB % GEORGIAN SMALL LETTER JIL
+\setXTXcharcodes "02D1C "02D1C "010BC % GEORGIAN SMALL LETTER CIL
+\setXTXcharcodes "02D1D "02D1D "010BD % GEORGIAN SMALL LETTER CHAR
+\setXTXcharcodes "02D1E "02D1E "010BE % GEORGIAN SMALL LETTER XAN
+\setXTXcharcodes "02D1F "02D1F "010BF % GEORGIAN SMALL LETTER JHAN
+\setXTXcharcodes "02D20 "02D20 "010C0 % GEORGIAN SMALL LETTER HAE
+\setXTXcharcodes "02D21 "02D21 "010C1 % GEORGIAN SMALL LETTER HE
+\setXTXcharcodes "02D22 "02D22 "010C2 % GEORGIAN SMALL LETTER HIE
+\setXTXcharcodes "02D23 "02D23 "010C3 % GEORGIAN SMALL LETTER WE
+\setXTXcharcodes "02D24 "02D24 "010C4 % GEORGIAN SMALL LETTER HAR
+\setXTXcharcodes "02D25 "02D25 "010C5 % GEORGIAN SMALL LETTER HOE
+\setXTXcharcodes "0FB00 "0FB00 "0FB00 % LATIN SMALL LIGATURE FF
+\setXTXcharcodes "0FB01 "0FB01 "0FB01 % LATIN SMALL LIGATURE FI
+\setXTXcharcodes "0FB02 "0FB02 "0FB02 % LATIN SMALL LIGATURE FL
+\setXTXcharcodes "0FB03 "0FB03 "0FB03 % LATIN SMALL LIGATURE FFI
+\setXTXcharcodes "0FB04 "0FB04 "0FB04 % LATIN SMALL LIGATURE FFL
+\setXTXcharcodes "0FB05 "0FB05 "0FB05 % LATIN SMALL LIGATURE LONG S T
+\setXTXcharcodes "0FB06 "0FB06 "0FB06 % LATIN SMALL LIGATURE ST
+\setXTXcharcodes "0FB13 "0FB13 "0FB13 % ARMENIAN SMALL LIGATURE MEN NOW
+\setXTXcharcodes "0FB14 "0FB14 "0FB14 % ARMENIAN SMALL LIGATURE MEN ECH
+\setXTXcharcodes "0FB15 "0FB15 "0FB15 % ARMENIAN SMALL LIGATURE MEN INI
+\setXTXcharcodes "0FB16 "0FB16 "0FB16 % ARMENIAN SMALL LIGATURE VEW NOW
+\setXTXcharcodes "0FB17 "0FB17 "0FB17 % ARMENIAN SMALL LIGATURE MEN XEH
+\setXTXcharcodes "0FF21 "0FF41 "0FF21 % FULLWIDTH LATIN CAPITAL LETTER A
+\setXTXcharcodes "0FF22 "0FF42 "0FF22 % FULLWIDTH LATIN CAPITAL LETTER B
+\setXTXcharcodes "0FF23 "0FF43 "0FF23 % FULLWIDTH LATIN CAPITAL LETTER C
+\setXTXcharcodes "0FF24 "0FF44 "0FF24 % FULLWIDTH LATIN CAPITAL LETTER D
+\setXTXcharcodes "0FF25 "0FF45 "0FF25 % FULLWIDTH LATIN CAPITAL LETTER E
+\setXTXcharcodes "0FF26 "0FF46 "0FF26 % FULLWIDTH LATIN CAPITAL LETTER F
+\setXTXcharcodes "0FF27 "0FF47 "0FF27 % FULLWIDTH LATIN CAPITAL LETTER G
+\setXTXcharcodes "0FF28 "0FF48 "0FF28 % FULLWIDTH LATIN CAPITAL LETTER H
+\setXTXcharcodes "0FF29 "0FF49 "0FF29 % FULLWIDTH LATIN CAPITAL LETTER I
+\setXTXcharcodes "0FF2A "0FF4A "0FF2A % FULLWIDTH LATIN CAPITAL LETTER J
+\setXTXcharcodes "0FF2B "0FF4B "0FF2B % FULLWIDTH LATIN CAPITAL LETTER K
+\setXTXcharcodes "0FF2C "0FF4C "0FF2C % FULLWIDTH LATIN CAPITAL LETTER L
+\setXTXcharcodes "0FF2D "0FF4D "0FF2D % FULLWIDTH LATIN CAPITAL LETTER M
+\setXTXcharcodes "0FF2E "0FF4E "0FF2E % FULLWIDTH LATIN CAPITAL LETTER N
+\setXTXcharcodes "0FF2F "0FF4F "0FF2F % FULLWIDTH LATIN CAPITAL LETTER O
+\setXTXcharcodes "0FF30 "0FF50 "0FF30 % FULLWIDTH LATIN CAPITAL LETTER P
+\setXTXcharcodes "0FF31 "0FF51 "0FF31 % FULLWIDTH LATIN CAPITAL LETTER Q
+\setXTXcharcodes "0FF32 "0FF52 "0FF32 % FULLWIDTH LATIN CAPITAL LETTER R
+\setXTXcharcodes "0FF33 "0FF53 "0FF33 % FULLWIDTH LATIN CAPITAL LETTER S
+\setXTXcharcodes "0FF34 "0FF54 "0FF34 % FULLWIDTH LATIN CAPITAL LETTER T
+\setXTXcharcodes "0FF35 "0FF55 "0FF35 % FULLWIDTH LATIN CAPITAL LETTER U
+\setXTXcharcodes "0FF36 "0FF56 "0FF36 % FULLWIDTH LATIN CAPITAL LETTER V
+\setXTXcharcodes "0FF37 "0FF57 "0FF37 % FULLWIDTH LATIN CAPITAL LETTER W
+\setXTXcharcodes "0FF38 "0FF58 "0FF38 % FULLWIDTH LATIN CAPITAL LETTER X
+\setXTXcharcodes "0FF39 "0FF59 "0FF39 % FULLWIDTH LATIN CAPITAL LETTER Y
+\setXTXcharcodes "0FF3A "0FF5A "0FF3A % FULLWIDTH LATIN CAPITAL LETTER Z
+\setXTXcharcodes "0FF41 "0FF41 "0FF21 % FULLWIDTH LATIN SMALL LETTER A
+\setXTXcharcodes "0FF42 "0FF42 "0FF22 % FULLWIDTH LATIN SMALL LETTER B
+\setXTXcharcodes "0FF43 "0FF43 "0FF23 % FULLWIDTH LATIN SMALL LETTER C
+\setXTXcharcodes "0FF44 "0FF44 "0FF24 % FULLWIDTH LATIN SMALL LETTER D
+\setXTXcharcodes "0FF45 "0FF45 "0FF25 % FULLWIDTH LATIN SMALL LETTER E
+\setXTXcharcodes "0FF46 "0FF46 "0FF26 % FULLWIDTH LATIN SMALL LETTER F
+\setXTXcharcodes "0FF47 "0FF47 "0FF27 % FULLWIDTH LATIN SMALL LETTER G
+\setXTXcharcodes "0FF48 "0FF48 "0FF28 % FULLWIDTH LATIN SMALL LETTER H
+\setXTXcharcodes "0FF49 "0FF49 "0FF29 % FULLWIDTH LATIN SMALL LETTER I
+\setXTXcharcodes "0FF4A "0FF4A "0FF2A % FULLWIDTH LATIN SMALL LETTER J
+\setXTXcharcodes "0FF4B "0FF4B "0FF2B % FULLWIDTH LATIN SMALL LETTER K
+\setXTXcharcodes "0FF4C "0FF4C "0FF2C % FULLWIDTH LATIN SMALL LETTER L
+\setXTXcharcodes "0FF4D "0FF4D "0FF2D % FULLWIDTH LATIN SMALL LETTER M
+\setXTXcharcodes "0FF4E "0FF4E "0FF2E % FULLWIDTH LATIN SMALL LETTER N
+\setXTXcharcodes "0FF4F "0FF4F "0FF2F % FULLWIDTH LATIN SMALL LETTER O
+\setXTXcharcodes "0FF50 "0FF50 "0FF30 % FULLWIDTH LATIN SMALL LETTER P
+\setXTXcharcodes "0FF51 "0FF51 "0FF31 % FULLWIDTH LATIN SMALL LETTER Q
+\setXTXcharcodes "0FF52 "0FF52 "0FF32 % FULLWIDTH LATIN SMALL LETTER R
+\setXTXcharcodes "0FF53 "0FF53 "0FF33 % FULLWIDTH LATIN SMALL LETTER S
+\setXTXcharcodes "0FF54 "0FF54 "0FF34 % FULLWIDTH LATIN SMALL LETTER T
+\setXTXcharcodes "0FF55 "0FF55 "0FF35 % FULLWIDTH LATIN SMALL LETTER U
+\setXTXcharcodes "0FF56 "0FF56 "0FF36 % FULLWIDTH LATIN SMALL LETTER V
+\setXTXcharcodes "0FF57 "0FF57 "0FF37 % FULLWIDTH LATIN SMALL LETTER W
+\setXTXcharcodes "0FF58 "0FF58 "0FF38 % FULLWIDTH LATIN SMALL LETTER X
+\setXTXcharcodes "0FF59 "0FF59 "0FF39 % FULLWIDTH LATIN SMALL LETTER Y
+\setXTXcharcodes "0FF5A "0FF5A "0FF3A % FULLWIDTH LATIN SMALL LETTER Z
+
+\dofastrecurse{"03400}{"04DB5}{1}{\dosetXTXcharcodes\recurselevel\recurselevel\recurselevel}
+\dofastrecurse{"04E00}{"09FBB}{1}{\dosetXTXcharcodes\recurselevel\recurselevel\recurselevel}
+\dofastrecurse{"0AC00}{"0D7A3}{1}{\dosetXTXcharcodes\recurselevel\recurselevel\recurselevel}
+\dofastrecurse{"20000}{"2A6D6}{1}{\dosetXTXcharcodes\recurselevel\recurselevel\recurselevel}
+
+% patch needed for turkish
+
+\setXTXcharcodes "201C "201C "201C
+\setXTXcharcodes "201D "201D "201D
+
+\endinput
diff --git a/tex/context/base/xtag-cml.tex b/tex/context/base/xtag-cml.tex
index 203218ceb..6da7fd26f 100644
--- a/tex/context/base/xtag-cml.tex
+++ b/tex/context/base/xtag-cml.tex
@@ -2,6 +2,8 @@
% will be rewritten avoiding the mapper
+\useXMLfilter[map]
+
\unprotect
\def\setupCMLappearance[#1]{\dodoubleargument\getparameters[@@CML#1]}
diff --git a/tex/context/base/xtag-ent.tex b/tex/context/base/xtag-ent.tex
index a34fbab28..f4c3e4b06 100644
--- a/tex/context/base/xtag-ent.tex
+++ b/tex/context/base/xtag-ent.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-ent,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=A bunch of Entities,
%D author=Hans Hagen,
%D date=\currentdate,
diff --git a/tex/context/base/xtag-exp.tex b/tex/context/base/xtag-exp.tex
index af49782d9..72e956199 100644
--- a/tex/context/base/xtag-exp.tex
+++ b/tex/context/base/xtag-exp.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-exp,
%D version=2001.08.20,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=Expansion Related Things,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=Expansion,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (expansion)}
+\writestatus{loading}{ConTeXt XML Macros / Expansion}
\unprotect
diff --git a/tex/context/base/xtag-ext.tex b/tex/context/base/xtag-ext.tex
index a0f43ff4e..1a9e3e058 100644
--- a/tex/context/base/xtag-ext.tex
+++ b/tex/context/base/xtag-ext.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-ext,
%D version=2001.03.21,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Extra Macros,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (extras)}
+\writestatus{loading}{ConTeXt XML Macros / Extras}
\unprotect
diff --git a/tex/context/base/xtag-hyp.tex b/tex/context/base/xtag-hyp.tex
index 821705f7b..573b546c7 100644
--- a/tex/context/base/xtag-hyp.tex
+++ b/tex/context/base/xtag-hyp.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-hyp,
%D version=2003.11.24,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=hyphenation support,
+%D title=\CONTEXT\ XML MAcros,
+%D subtitle=Hyphenation,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (hyphenation)}
+\writestatus{loading}{ConTeXt XML Macros / Hyphenation}
%D This filter is kind of obsolete, since \UTF\ is not
%D limited to \XML. So, here we only enable \UTF\ support.
diff --git a/tex/context/base/xtag-ini.mkii b/tex/context/base/xtag-ini.mkii
deleted file mode 100644
index 994ff6d9e..000000000
--- a/tex/context/base/xtag-ini.mkii
+++ /dev/null
@@ -1,6 +0,0 @@
-\def\mksetXMLtokensreduction % mkii
- {\ifcase\XMLtokensreduction
- \setcatcodetable\xmlcatcodese \or
- \setcatcodetable\xmlcatcodesr \else
- \setcatcodetable\xmlcatcodesn
- \fi}
diff --git a/tex/context/base/xtag-ini.mkiv b/tex/context/base/xtag-ini.mkiv
deleted file mode 100644
index 974f0439b..000000000
--- a/tex/context/base/xtag-ini.mkiv
+++ /dev/null
@@ -1,2 +0,0 @@
-\def\mksetXMLtokensreduction % mkiv
- {\setcatcodetable\xmlcatcodesn}
diff --git a/tex/context/base/xtag-ini.tex b/tex/context/base/xtag-ini.tex
index ca1fa9a05..495f4ea07 100644
--- a/tex/context/base/xtag-ini.tex
+++ b/tex/context/base/xtag-ini.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-ini,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Initialization,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (initialization)}
+\writestatus{loading}{ConTeXt XML Macros / Initialization}
%D Beware: don't rely on \longempty things, since this may
%D change!
@@ -35,8 +35,6 @@
% csnames
% XMLelse -> elseXML
-\loadmarkfile{xtag-ini}
-
%D Remark: some hard coded character things will be replaced
%D by named glyphs as soon as the upgraded encoding modules
%D are released. At that moment, unicode support will be
@@ -417,6 +415,22 @@
% we speed things up by explicitly setting the active char's < &
+\doifmodeelse {mkiv} {
+
+ \def\mksetXMLtokensreduction % mkiv
+ {\setcatcodetable\xmlcatcodesn}
+
+} {
+
+ \def\mksetXMLtokensreduction % mkii
+ {\ifcase\XMLtokensreduction
+ \setcatcodetable\xmlcatcodese \or
+ \setcatcodetable\xmlcatcodesr \else
+ \setcatcodetable\xmlcatcodesn
+ \fi}
+
+}
+
\bgroup \catcode`\<=13 \catcode`\&=13
\gdef\enableXML
@@ -1427,7 +1441,7 @@
%\unexpanded\def\getXMLentity#1%
% {\csname\@@XMLentity:#1\endcsname}
-\newif\ifautoXMLentities % fall back on context commands
+\doifundefined{autoXMLentitiestrue}{\expandafter\newif\csname ifautoXMLentities\endcsname} % fall back on context commands
\def\expandedXMLentity#1%
{\ifcsname\@@XMLentity:#1\endcsname \@EA \execXMLentity
diff --git a/tex/context/base/xtag-map.tex b/tex/context/base/xtag-map.tex
index af6ca6112..f8471d6a7 100644
--- a/tex/context/base/xtag-map.tex
+++ b/tex/context/base/xtag-map.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-map,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Remapping,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -16,7 +16,7 @@
%D We also need something that lets content as-is, like for
%D instance XML embedded in a chemical caption.
-\writestatus{loading}{Context XML Macros (remapping)}
+\writestatus{loading}{ConTeXt XML Macros / Remapping}
%D A fundamental characteristic of \TEX\ is that much
%D processing depends on picking up one or more arguments and
diff --git a/tex/context/base/xtag-mmc.tex b/tex/context/base/xtag-mmc.tex
index d4ee14c59..27e2c42ea 100644
--- a/tex/context/base/xtag-mmc.tex
+++ b/tex/context/base/xtag-mmc.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-mmc,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=Math ML,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=Content MathML,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (content math ml)}
+\writestatus{loading}{ConTeXt XML Macros / Content MathML}
% this is the first, experimental, shabby implementation, as
% always, the third will do -)
@@ -113,7 +113,7 @@ complex-cartesian=>\let\next\MMLccartesian,
{{\bbd#1}}
\def\widevec#1%
- {\vbox{\m@th\ialign{##\crcr
+ {\vbox{\mathsurround\zeropoint\ialign{##\crcr
\rightarrowfill\crcr\noalign{\nointerlineskip}%
$\hfil\displaystyle{#1}\hfil$\crcr}}}
diff --git a/tex/context/base/xtag-mml.tex b/tex/context/base/xtag-mml.tex
index e627e05b0..051d15b00 100644
--- a/tex/context/base/xtag-mml.tex
+++ b/tex/context/base/xtag-mml.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-mml,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=Math ML,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=MathML,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,11 +11,13 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (math ml)}
+\writestatus{loading}{ConTeXt XML Macros / MathML}
% I will reimplement this one without mapping since we now have more
% tricks available
+\useXMLfilter[map]
+
%\enablemathpunctuation
% First some general formula element definitions.
diff --git a/tex/context/base/xtag-mmp.tex b/tex/context/base/xtag-mmp.tex
index 01328cd40..ef1479ee6 100644
--- a/tex/context/base/xtag-mmp.tex
+++ b/tex/context/base/xtag-mmp.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-mmp,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=Math ML,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=Presentation MathML,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% \points should become \bodyfontsize
+
% under reconstruction
%
% \starttext
@@ -31,18 +33,18 @@
% \def\doMMLpUNDER
% {\doifelse{\XMLpar{munder}{accent}{}}{true}
% {\secondXMLRelement\firstXMLRelement}
-% {\mathop{\vtop{\m@th\ialign{\hss##\hss\crcr
+% {\mathop{\vtop{\mathsurround\zeropoint\ialign{\hss##\hss\crcr
% \disabledelimiter\doMMLfiller\firstXMLRelement
-% \crcr\noalign{\kern3\p@\nointerlineskip}%
+% \crcr\noalign{\kern3\points\nointerlineskip}%
% \disabledelimiter\doMMLfiller\secondXMLRelement
-% \crcr\noalign{\kern3\p@}}}}\limits}}
+% \crcr\noalign{\kern3\points}}}}\limits}}
%
% \def\doMMLpOVER
% {\doifelse{\XMLpar{mover}{accent}{}}{true}
% {\secondXMLRelement\firstXMLRelement}
-% {\mathop{\vbox{\m@th\ialign{\hss##\hss\crcr\noalign{\kern3\p@}%
+% {\mathop{\vbox{\mathsurround\zeropoint\ialign{\hss##\hss\crcr\noalign{\kern3\points}%
% \disabledelimiter\doMMLfiller\secondXMLRelement
-% \crcr\noalign{\kern3\p@\nointerlineskip}%
+% \crcr\noalign{\kern3\points\nointerlineskip}%
% \disabledelimiter\doMMLfiller\firstXMLRelement
% \crcr}}}\limits}}
%
@@ -53,7 +55,7 @@
%
% \stoptext
-\writestatus{loading}{Context XML Macros (presentational math ml)}
+\writestatus{loading}{ConTeXt XML Macros / Presentational MathML}
\unprotect
@@ -90,9 +92,6 @@
\remapXMLsequence [mfenced] [CPA] \MMLpFENCED
-\let\normalright=\right
-\let\normalleft =\left
-
\def\doMMLleft #1{\pushmacro\left \let\left \empty\normalleft #1\popmacro\left}
\def\doMMLright#1{\pushmacro\right\let\right\empty\normalright#1\popmacro\right}
@@ -304,16 +303,16 @@
\dodoMMLfiller}
\def\doMMLpUNDER
- {\mathop{\vtop{\m@th\ialign{\hss##\hss\crcr
+ {\mathop{\vtop{\mathsurround\zeropoint\ialign{\hss##\hss\crcr
\disabledelimiter\doMMLfiller\firstXMLRelement
- \crcr\noalign{\kern3\p@\nointerlineskip}%
+ \crcr\noalign{\kern3\points\nointerlineskip}%
\disabledelimiter\doMMLfiller\secondXMLRelement
- \crcr\noalign{\kern3\p@}}}}\limits}
+ \crcr\noalign{\kern3\points}}}}\limits}
\def\doMMLpOVER
- {\mathop{\vbox{\m@th\ialign{\hss##\hss\crcr\noalign{\kern3\p@}%
+ {\mathop{\vbox{\mathsurround\zeropoint\ialign{\hss##\hss\crcr\noalign{\kern3\points}%
\disabledelimiter\doMMLfiller\secondXMLRelement
- \crcr\noalign{\kern3\p@\nointerlineskip}%
+ \crcr\noalign{\kern3\points\nointerlineskip}%
\disabledelimiter\doMMLfiller\firstXMLRelement
\crcr}}}\limits}
diff --git a/tex/context/base/xtag-pml.tex b/tex/context/base/xtag-pml.tex
index b11d3d68d..53d22c52a 100644
--- a/tex/context/base/xtag-pml.tex
+++ b/tex/context/base/xtag-pml.tex
@@ -11,11 +11,12 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (phys ml)}
+\writestatus{loading}{ConTeXt XML Macros / PhysML}
%D This is a reimplmentation of the old filter. This module
%D runs on top of the mathml and units modules.
+\useXMLfilter[map]
\useXMLfilter[mml,mmp,mmc]
\defineXMLargument [phys] \doXMLphys
diff --git a/tex/context/base/xtag-pmu.tex b/tex/context/base/xtag-pmu.tex
index 0b9509f13..b913475f5 100644
--- a/tex/context/base/xtag-pmu.tex
+++ b/tex/context/base/xtag-pmu.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-pmu,
%D version=2001.06.10,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Units,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (units)}
+\writestatus{loading}{ConTeXt XML Macros / Units}
%D Quick and dirty in||line units:
%D
diff --git a/tex/context/base/xtag-pre.tex b/tex/context/base/xtag-pre.tex
index 173e7d298..3f1d4dca0 100644
--- a/tex/context/base/xtag-pre.tex
+++ b/tex/context/base/xtag-pre.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-pre,
%D version=2000.12.20,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Predefined Things,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (predefined)}
+\writestatus{loading}{ConTeXt XML Macros / Predefined}
%D Here we predefine some escapes, processing instructions,
%D entities and other handy things.
diff --git a/tex/context/base/xtag-prs.tex b/tex/context/base/xtag-prs.tex
index b3eb681fc..02bdcf21c 100644
--- a/tex/context/base/xtag-prs.tex
+++ b/tex/context/base/xtag-prs.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-prs,
%D version=2004.08.18,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Parsing,
%D author=Hans Hagen,
%D date=\currentdate,
diff --git a/tex/context/base/xtag-raw.tex b/tex/context/base/xtag-raw.tex
index 8c190d943..e6dfdea41 100644
--- a/tex/context/base/xtag-raw.tex
+++ b/tex/context/base/xtag-raw.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-raw,
%D version=2002.03.21,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=reducing specials,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=Raw Specials,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (raw specials)}
+\writestatus{loading}{ConTeXt XML Macros / Raw Specials}
%D Some day this module will be obsolete.
diff --git a/tex/context/base/xtag-rng.tex b/tex/context/base/xtag-rng.tex
index 524bba2d1..254282424 100644
--- a/tex/context/base/xtag-rng.tex
+++ b/tex/context/base/xtag-rng.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-rng,
%D version=2002.10.29,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=Relax NG,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=Relax NG,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,18 +11,18 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\unprotect
+\unprotect
%D The following commands picks up a named block from the
-%D given file and pretty prints it.
+%D given file and pretty prints it.
%D
-%D \starttyping
+%D \starttyping
%D \showRNGcomponent [eximple.rng] [request]
%D \stoptyping
%D
%D If needed, you adapt the colors used by redefining the
-%D \type {xtag} color palet.
+%D \type {xtag} color palet.
\fetchruntimecommand\showRNGcomponent {\f!xtagprefix\s!run}
-\protect \endinput
+\protect \endinput
diff --git a/tex/context/base/xtag-run.tex b/tex/context/base/xtag-run.tex
index 8075bfbe4..9a4603731 100644
--- a/tex/context/base/xtag-run.tex
+++ b/tex/context/base/xtag-run.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-run,
%D version=2001.01.10,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Visualization,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -13,7 +13,7 @@
% TODO: make this mkiv compliant, catcode tables etc
-\writestatus{loading}{Context XML Macros (visualization)}
+\writestatus{loading}{ConTeXt XML Macros / Visualization}
\unprotect
diff --git a/tex/context/base/xtag-stk.tex b/tex/context/base/xtag-stk.tex
index b5fcb7e9d..e126ae5c7 100644
--- a/tex/context/base/xtag-stk.tex
+++ b/tex/context/base/xtag-stk.tex
@@ -1,7 +1,7 @@
%D \module
%D [ file=xtag-exp,
%D version=2006.01.19,
-%D title=\CONTEXT\ XML Support,
+%D title=\CONTEXT\ XML Macros,
%D subtitle=Stacking Data,
%D author=Hans Hagen,
%D date=\currentdate,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (stacks)}
+\writestatus{loading}{ConTeXt XML Macros / Stacks}
%D This module is experimental. Don't use it (yet). It needs a
%D clean-up. The stack handler is used in the third MathML renderer.
diff --git a/tex/context/base/xtag-utf.tex b/tex/context/base/xtag-utf.tex
index b978c3339..fec84d279 100644
--- a/tex/context/base/xtag-utf.tex
+++ b/tex/context/base/xtag-utf.tex
@@ -1,8 +1,8 @@
%D \module
%D [ file=xtag-utf,
%D version=2002.06.24,
-%D title=\CONTEXT\ XML Support,
-%D subtitle=UTF-8 support,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=UTF,
%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{Context XML Macros (UTF-8)}
+\writestatus{loading}{ConTeXt XML Macros / UTF}
%D This filter is kind of obsolete, since \UTF\ is not
%D limited to \XML. So, here we only enable \UTF\ support.
diff --git a/tex/context/bib/bibl-apa-fr.tex b/tex/context/bib/bibl-apa-fr.tex
index d2a1efb8a..654a36441 100644
--- a/tex/context/bib/bibl-apa-fr.tex
+++ b/tex/context/bib/bibl-apa-fr.tex
@@ -108,7 +108,7 @@
\def\insertchap#1#2#3%
{\insertchapter
- {#1\insertbibtype{}{\ }{chapter\ }}{#2}%
+ {#1\insertbibtype{}{\ }{chapitre\ }}{#2}%
{#3}}
\def\insertpublisher#1#2#3%
diff --git a/tex/context/bib/bibl-apa.tex b/tex/context/bib/bibl-apa.tex
index c6085c3c3..20bbccb95 100644
--- a/tex/context/bib/bibl-apa.tex
+++ b/tex/context/bib/bibl-apa.tex
@@ -154,7 +154,7 @@
{\insertcrossref{In }{}{}}%
\insertvolume
{\bgroup \it, }
- {\insertissue{\egroup\/(}{)}{}\insertpages{, }{.}{.}}
+ {\egroup\insertissue{\/(}{)}{}\insertpages{, }{.}{.}}
{\insertpages{, pp. }{.}{.}}%
\insertnote{ }{.}{}%
\insertcomment{}{.}{}%
@@ -283,7 +283,7 @@
\insertchap{\unskip, }{ }{ }%
\insertpages{\unskip, pages~}{. }{\unskip. }%
\insertedition{ }{ edition}{}%
- \insertpublisher{. }{.}{.}%
+ \insertpublisher{ }{.}{.}%
}%
{In \insertcrossref{}{}{}%
\insertchap{\unskip, }{ }{ }%
@@ -381,7 +381,7 @@
\insertauthors{}{ }{}%
\insertpubyear{(}{). }{}%
\inserttitle{\bgroup }{\egroup \insertseries{ (}{)}{}. }{}%
- \insertpublisher{ }{.}{.}%
+% \insertpublisher{ }{.}{.}%
\insertpages{ }{p. }{}%
\insertbibtype{(}{)}{}%
\insertnote{ }{.}{}%
diff --git a/tex/context/bib/t-bib.mkii b/tex/context/bib/t-bib.mkii
new file mode 100644
index 000000000..ac3494725
--- /dev/null
+++ b/tex/context/bib/t-bib.mkii
@@ -0,0 +1,5 @@
+% some code will move here
+
+\unprotect
+
+\protect \endinput
diff --git a/tex/context/bib/t-bib.mkiv b/tex/context/bib/t-bib.mkiv
new file mode 100644
index 000000000..4316d380e
--- /dev/null
+++ b/tex/context/bib/t-bib.mkiv
@@ -0,0 +1,64 @@
+%D Note by HH:
+%D
+%D We use a still somewhat experimental extension to the list
+%D mechanism. Eventually the bibtex module will use the bibl loader
+%D and access the data by means of lpath expressions. In that case we
+%D don't need to process the bibliography but still need to track
+%D usage as done here.
+
+\unprotect
+
+\startluacode
+local list = { }
+
+bibtexhacks = {
+ reset = function() list = { } end,
+ add = function(str) list[#list+1] = str end,
+ flush = function() tex.sprint(table.concat(list,",")) end,
+}
+\stopluacode
+
+\unprotect
+
+% HACK WILL GO:
+
+\def\namedlistparameter#1#2{\csname\dolistparameter{\??li#1}#2\endcsname}
+
+% TILL HERE
+
+\let\bibrefprefixcounter\!!plusone
+\def\bibrefprefix {\bibrefprefixcounter:}
+\let\preparebibrefprefix\relax
+\let\preparebibreflist \gobbleoneargument
+\let\bibreflist \empty
+
+\setuplist[pubs][\c!state=\s!start]
+
+\installstructurelistprocessor{pubs:userdata}
+ {\ctxlua{bibtexhacks.add(structure.lists.uservalue("\currentlist",\currentlistindex,"bibref"))}}
+
+\def\docitation#1%
+ {\expanded{\writedatatolist[pubs][bibref=#1]}}
+
+\def\filllocalpublist
+ {\edef\currentlist{pubs}%
+ \doif{\listparameter\c!criterium}{cite}{\setuplist[pubs][\c!criterium=\v!here]}%
+ \ctxlua{bibtexhacks.reset()}%
+ \placestructurelist{pubs}{\listparameter\c!criterium}{\listparameter\c!number}%
+ \edef\localpublist{\ctxlua{bibtexhacks.flush()}}}
+
+\def\gotobiblink#1[#2]{\doifreferencefoundelse{\bibrefprefix#2}{\goto{#1}[\bibrefprefix#2]}{\unknownreference{#2}}}
+\def\atbiblink [#1]{\doifreferencefoundelse{\bibrefprefix#1}{\at [\bibrefprefix#1]}{\unknownreference{#1}}}
+\def\inbiblink [#1]{\doifreferencefoundelse{\bibrefprefix#1}{\at [\bibrefprefix#1]}{\unknownreference{#1}}}
+
+\ifdefined\normaldodoplacepublications \else % just in case we load twice
+
+ \let\normaldodoplacepublications\dodoplacepublications
+
+ \def\dodoplacepublications
+ {\normaldodoplacepublications
+ \doglobal\increment\bibrefprefixcounter}
+
+\fi
+
+\protect \endinput
diff --git a/tex/context/bib/t-bib.tex b/tex/context/bib/t-bib.tex
index 2cf79c3be..35a3de6ca 100644
--- a/tex/context/bib/t-bib.tex
+++ b/tex/context/bib/t-bib.tex
@@ -1,6 +1,6 @@
%D \module
%D [ file=t-bib,
-%D version=2008.10.23,
+%D version=2009.04.27,
%D title=\CONTEXT\ Publication Module,
%D subtitle=Publications,
%D author=Taco Hoekwater,
@@ -34,7 +34,7 @@
%D \item added headtext for it (23/11/2005)
%D \item make \type{\cite[url]} and \type{\cite[doi]} interactive (23/11/2005)
%D \item make right-aligned labels in the list work even when autohang=no
-%D \item use 'et al.' instead of 'et.al.'. Pointed out by Peter Mnster (30/12/2005)
+%D \item use 'et al.' instead of 'et.al.'. Pointed out by Peter M�nster (30/12/2005)
%D \item added headtext for cz (31/12/2005)
%D \item Keep whitespace after \type{\cite} with single argument (31/12/2005)
%D \item Fix broken \type{\cite{}} support (31/12/2005)
@@ -104,7 +104,7 @@
%D Thomas Schmitz (15/9/2006)
%D \item Removed some spurious spaces pointed out by willi egger (19/9/2006)
%D \item Add configuration of bibtex executable name (4/11/2006)
-%D \item Fix numbering=short and numbering=bib (spotted by Matthias Wchter) (4/11/2006)
+%D \item Fix numbering=short and numbering=bib (spotted by Matthias W�chter) (4/11/2006)
%D \item third attempt to get a correct release (5/11/2006)
%D \item fix a few missing dots in bibl-num.tex (7/12/2006)
%D \item Patch for DOI's by Tobias Burnus (17/4/2007)
@@ -116,6 +116,23 @@
%D \item Patch from Matthias W\"achter that allows arbitrary .bst
%D files to be used with \tex{setupbibtex} (25/9/2008)
%D \item Extended for the new multilingual setups for the Oct 2008 current of ConTeXt (23/10/2008)
+%D \item Multilingual setups needed another fix (27/10/2008)
+%D \item Two fixes for bibl-apa by Michael Green (27/10/2008)
+%D \item Catalan translation of 'References' (10/11/2008)
+%D \item 'chapter' -> 'chapitre' in bibl-apa-fr (27/11/2008)
+%D \item Run bibtex via os.execute in mkiv modee (01/12/2008)
+%D \item Small correction in bibl-apa's placement of volume
+%D information in articles (05/01/2009)
+%D \item Handle multi-author (more than two) cases in \type{\cite}
+%D (02/03/2009)
+%D \item Suppress a syntax error in \type{cont-xp} mode. The output is
+%D probably not right, though (02/03/2009)
+%D \item Added a \tex{loadmarkfile} at the end, and two new files
+%D from Hans. The \type{t-bib.mkiv} is needed to make the module
+%D work with the new structure code (17/04/2009)
+%D \item Added a patch to \type{t-bib.mkiv} from Hans to make the
+%D cross referencing between multiple citations an
+%D bibliographies work (27/04/2009)
%D \stopitemize
%D
%D \subject{WISHLIST}
@@ -129,13 +146,22 @@
\unprotect
-%D start with a temp hack the file will still work with pre-Oct 20078
+%D start with a temp hack the file will still work with pre-Oct 2008
%D versions of ConTeXt:
\def\startinterface #1
{\doifnot{#1}{all}{\doifnotinset\currentinterface{#1}{\gobbleuntil\stopinterface}}}
+\let\checksetvalue\gobbletwoarguments
+
+
+%\defineinterfacevariable {title} {title}
+%\defineinterfacevariable {short} {short}
+%\defineinterfacevariable {cite} {cite}
+%\defineinterfacevariable {bbl} {bbl}
+%\defineinterfacevariable {bib} {bib}
+%\defineinterfacevariable {author} {author}
%D A few new shortcuts:
@@ -300,6 +326,7 @@
\setupheadtext[it][pubs=Bibliografia]
\setupheadtext[sl][pubs=Literatura]
\setupheadtext[fr][pubs=Bibliographie]
+\setupheadtext[ca][pubs=Referències]
%D \macros{bibdoif,bibdoifnot,bibdoifelse}
%D
@@ -380,7 +407,9 @@
\write \scratchwrite {\string\bibdata{\@@pbdatabase}}%
\closeout\scratchwrite
\showmessage\m!bib{3}{}%
- \expanded{\installprogram{\@@pbbibtex\space\jobname}}}}
+ \doifmodeelse{*mkiv}
+ {\ctxlua{os.execute('\@@pbbibtex\space\jobname')}}
+ {\expanded{\installprogram{\@@pbbibtex\space\jobname}}}}}
%D \macros{ifsortbycite,iftypesetall,ifautohang,ifbibcitecompress}
%D
@@ -915,9 +944,11 @@
\fi
\def\filllocalpublist%
- {\let\dosetfilterlevel\patcheddosetfilterlevel
- \dosettoclevel\??li{pubs}%
- \let\dosetfilterlevel\normaldosetfilterlevel
+ {\doifdefinedelse{\alltoclevels}
+ {\let\dosetfilterlevel\patcheddosetfilterlevel
+ \dosettoclevel\??li{pubs}%
+ \let\dosetfilterlevel\normaldosetfilterlevel }%
+ {\dosettoclevel\??li{pubs}}%
\global\let\glocalpublist\empty
\doloop
{\doifdefinedelse
@@ -1375,11 +1406,32 @@
\or
\expanded{\docurrentbibauthor#1}%
\else
- % this can't happen/
- \def\currentbibauthor{}%
+ \handlemultiplebibauthors{\commalistsize}{#1}%
\fi }
+\newcount\citescratchcounter
+
+\def\handlemultiplebibauthors#1#2%
+ {\citescratchcounter 0
+ \def\currentbibauthor{}%
+ \def\bibprocessauthoritem##1%
+ {\advance\citescratchcounter1
+ \ifnum \citescratchcounter=#1\relax
+ \edef\currentbibauthor{\currentbibauthor##1}%
+ \else \ifnum\numexpr\citescratchcounter+1 = #1\relax
+ \edef\currentbibauthor{\currentbibauthor ##1\bibalternative{andtext}}%
+ \else
+ \edef\currentbibauthor{\currentbibauthor ##1\bibalternative{namesep}}%
+ \fi
+ \fi }%
+ \processcommalist[#2]\bibprocessauthoritem }
+
+
+\setupcite
+ [author,authoryear,authoryears]
+ [\c!namesep={, }]
+
%D This discovery of authoretallimit is not the best one,
%D but it will do for now.
@@ -1858,6 +1910,8 @@
\setuppublications
[\v!month\v!conversion=,\c!alternative=apa]
+\loadmarkfile{t-bib}
+
\preloadbiblist
\protect \endinput
diff --git a/tex/context/config/cont-usr.tex b/tex/context/config/cont-usr.tex
index dab420e3e..5a3070362 100644
--- a/tex/context/config/cont-usr.tex
+++ b/tex/context/config/cont-usr.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\writestatus{loading}{User Settings}
+\writestatus{loading}{ConTeXt User Settings}
\unprotect
diff --git a/tex/context/interface/cont-cs.xml b/tex/context/interface/cont-cs.xml
index a0095af10..d53a71a6f 100644
--- a/tex/context/interface/cont-cs.xml
+++ b/tex/context/interface/cont-cs.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="nastavzakladnifont" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="nastavzakladnifont" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="nastavzakladnifont" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="nastavmeziradkovoumezeru"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="prizpusobive"/>
</cd:parameter>
+ <cd:parameter name="metoda">
+ <cd:constant type="normalni"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="tolerantni"/>
<cd:constant type="velmitolerantni"/>
<cd:constant type="natahnout"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="definujsynonumumfontu"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-cz.xml b/tex/context/interface/cont-cz.xml
deleted file mode 100644
index d1b2de2ee..000000000
--- a/tex/context/interface/cont-cz.xml
+++ /dev/null
@@ -1,10033 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><!-- versions:
-
- comment : user interface definitions of ConTeXt
-
- authors : Hans Hagen, Taco Hoekwater, Patrick Gundlach
-
- versions : 2004.11.17 : initial version
- 2006.08.02 : define + resolve
-
--->
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2006.08.02">
-
- <cd:define name="align">
- <cd:constant type="uvnitr"/>
- <cd:constant type="vnejsi"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="flushleft"/>
- <cd:constant type="flushright"/>
- <cd:constant type="nastred"/>
- <cd:constant type="center"/>
- <cd:constant type="normalni"/>
- <cd:constant type="ne"/>
- <cd:constant type="ano"/>
- </cd:define>
-
- <cd:define name="symalign">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="flushleft"/>
- <cd:constant type="flushright"/>
- <cd:constant type="nastred"/>
- <cd:constant type="center"/>
- </cd:define>
-
- <cd:define name="indenting">
- <cd:constant type="nikdy"/>
- <cd:constant type="zadny"/>
- <cd:constant type="ne"/>
- <cd:constant type="ne"/>
- <cd:constant type="ano"/>
- <cd:constant type="vzdy"/>
- <cd:constant type="prvni"/>
- <cd:constant type="dalsi"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="normalni"/>
- <cd:constant type="liche"/>
- <cd:constant type="sude"/>
- <cd:constant type="cd:dimension"/>
- </cd:define>
-
- <cd:define name="indentnext">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:define>
-
- <cd:define name="style">
- <cd:constant type="normalni"/>
- <cd:constant type="tucne"/>
- <cd:constant type="sklonene"/>
- <cd:constant type="tucnesklonene"/>
- <cd:constant type="opis"/>
- <cd:constant type="kap"/>
- <cd:constant type="small..."/>
- <cd:constant type="cd:command"/>
- </cd:define>
-
- <cd:define name="language">
- <cd:constant type="nl"/>
- <cd:constant type="fr"/>
- <cd:constant type="en"/>
- <cd:constant type="uk"/>
- <cd:constant type="de"/>
- <cd:constant type="es"/>
- <cd:constant type="cz"/>
- <cd:constant type=".."/>
- </cd:define>
-
- <cd:define name="texts">
- <cd:constant type="cd:text"/>
- <cd:constant type="cd:section"/>
- <cd:constant type="datum"/>
- <cd:constant type="cd:mark"/>
- <cd:constant type="cislostranky"/>
- </cd:define>
-
- <cd:define name="layout-h">
- <cd:constant type="text" default="yes"/>
- <cd:constant type="marginalie"/>
- <cd:constant type="hrana"/>
- </cd:define>
-
- <cd:define name="layout-v">
- <cd:constant type="vrsek"/>
- <cd:constant type="zahlavi"/>
- <cd:constant type="text" default="yes"/>
- <cd:constant type="upati"/>
- <cd:constant type="spodek"/>
- </cd:define>
-
- <cd:define name="bodyfont">
- <cd:constant type="5pt"/>
- <cd:constant type="..."/>
- <cd:constant type="12pt"/>
- <cd:constant type="male"/>
- <cd:constant type="velke"/>
- </cd:define>
-
- <cd:command name="installlanguage" file="lang-ini.tex" category="language">
- <cd:sequence>
- <cd:string value="instalacejazyka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="mezerovani">
- <cd:constant type="zhustene" default="yes"/>
- <cd:constant type="siroky"/>
- </cd:parameter>
- <cd:parameter name="lefthyphenmin">
- <cd:constant type="cd:number" default="2"/>
- </cd:parameter>
- <cd:parameter name="righthyphenmin">
- <cd:constant type="cd:number" default="2"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="vetavlevo">
- <cd:constant type="cd:command" default="---"/>
- </cd:parameter>
- <cd:parameter name="vetavpravo">
- <cd:constant type="cd:command" default="---"/>
- </cd:parameter>
- <cd:parameter name="podvetavlevo">
- <cd:constant type="cd:command" default="---"/>
- </cd:parameter>
- <cd:parameter name="podvetavpravo">
- <cd:constant type="cd:command" default="---"/>
- </cd:parameter>
- <cd:parameter name="citovatvlevo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="citovatvpravo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="citacevlevo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="citacevpravo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="leftspeech">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="middlespeech">
- <cd:constant type="cd:command" default=""/>
- </cd:parameter>
- <cd:parameter name="rightspeech">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="limittext">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="datum">
- <cd:constant type="cd:text"/> <!-- TODO -->
- </cd:parameter>
- <cd:parameter name="compoundhyphen">
- <cd:constant type="cd:command" default="\compoundhyphen"/>
- </cd:parameter>
- <cd:parameter name="leftcompoundhyphen">
- <cd:constant type="cd:command" default="\compoundhyphen"/>
- </cd:parameter>
- <cd:parameter name="rightcompoundhyphen">
- <cd:constant type="cd:command" default=""/>
- </cd:parameter>
- <cd:parameter name="implicitni">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplanguage" file="lang-ini.tex" category="language">
- <cd:sequence>
- <cd:string value="nastavjazyk"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:resolve name="language"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="instalacejazyka" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="language" file="lang-ini.tex" category="language">
- <cd:sequence>
- <cd:string value="jazyk"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:resolve name="language"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="mainlanguage" file="lang-ini.tex" category="language">
- <cd:sequence>
- <cd:string value="hlavnijazyk"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:resolve name="language"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="translate" file="lang-lab.tex" category="language">
- <cd:sequence>
- <cd:string value="prelozit"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="cd:name">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useencoding" file="enco-ini.tex" category="encoding"> <!-- engine="pdftex" -->
- <cd:sequence>
- <cd:string value="uzijkodovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usespecials" file="spec-ini.tex">
- <cd:sequence>
- <cd:string value="uzijspeciality"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="reset"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineoutput" file="spec-ini.tex">
- <cd:sequence>
- <cd:string value="definujvystup"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupoutput" file="spec-ini.tex">
- <cd:sequence>
- <cd:string value="nastavvystup"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definebodyfontenvironment" file="font-ini.tex" category="fonts">
- <cd:sequence>
- <cd:string value="definujprostredizakladnihofontu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes"> <!-- it's possible to use 1+2+3, 2+3, what about 1+2? -->
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="no"> <!-- have to force no, otherwise \showsetup is wrong ! -->
- <cd:constant type="5pt"/> <!-- TODO: maybe <cd:resolve name="bodyfont"/> -->
- <cd:constant type="..."/>
- <cd:constant type="12pt"/>
- <cd:constant type="implicitni"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:parameter name="text">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="script">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="scriptscript">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="x">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="xx">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="male">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="velky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="meziradkovamezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="em">
- <cd:resolve name="style"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbodyfontenvironment" file="font-ini.tex" category="fonts">
- <cd:sequence>
- <cd:string value="nastavprostredizakladnihofontu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes"> <!-- same as definebodyfontenvironment; you can define the whole commant to inherit, not only parameters-->
- <cd:inherit name="definujprostredizakladnihofontu" n="1"/>
- </cd:keywords>
- <cd:keywords n="2" optional="no">
- <cd:inherit name="definujprostredizakladnihofontu" n="2" optional="no"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="definujprostredizakladnihofontu" n="3"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showbodyfontenvironment" file="font-run.tex" category="fonts"> <!-- and debug -->
- <cd:sequence>
- <cd:string value="ukazpostredizakladnihofontu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:inherit name="nastavzakladnifont" n="1"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definebodyfont" file="font-ini.tex" category="fonts">
- <cd:sequence>
- <cd:string value="definujzakladnifont"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes"> <!-- <cd:constant type="implicitni"/> -->
- <cd:resolve name="bodyfont"/> <!-- TODO: check this -->
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="rm"/>
- <cd:constant type="ss"/>
- <cd:constant type="tt"/>
- <cd:constant type="mm"/>
- <cd:constant type="hw"/>
- <cd:constant type="cg"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:parameter name="tf">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="bf">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="sl">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="it">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="bs">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="bi">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="sc">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="ex">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="mi">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="sy">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="ma">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="mb">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="mc">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showbodyfont" file="font-run.tex" category="fonts"> <!-- visual debugging -->
- <cd:sequence>
- <cd:string value="ukazzakladnifont"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:inherit name="nastavzakladnifont" n="1"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbodyfont" file="font-run.tex" category="fonts">
- <cd:sequence>
- <cd:string value="nastavzakladnifont"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes"> <!-- TODO: many missing, maybe also <cd:resolve name="bodyfont"/> -->
- <cd:constant type="cd:name"/>
- <cd:constant type="serif"/>
- <cd:constant type="pravidelne"/>
- <cd:constant type="antikva"/>
- <cd:constant type="sans"/>
- <cd:constant type="podpora"/>
- <cd:constant type="bezserifu"/>
- <cd:constant type="mono"/>
- <cd:constant type="opis"/>
- <cd:constant type="strojopis"/>
- <cd:constant type="rukopisne"/>
- <cd:constant type="kaligraficke"/>
- <cd:constant type="5pt"/>
- <cd:constant type="..."/>
- <cd:constant type="12pt"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="switchtobodyfont" file="font-ini.tex" category="fonts">
- <cd:sequence>
- <cd:string value="prepninazakladnifont"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:resolve name="bodyfont"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definefont" file="font-ini.tex" category="fonts">
- <cd:sequence>
- <cd:string value="definujfont"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcolor" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="nastavbarvu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcolors" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="nastavbarvy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- <cd:constant type="globalne"/>
- <cd:constant type="lokalne"/>
- </cd:parameter>
- <cd:parameter name="konverze">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="vzdy"/>
- </cd:parameter>
- <cd:parameter name="redukce">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="rgb">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="cmyk">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="mpcmyk">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="mpspot">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="barvatextu">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="split">
- <cd:constant type="c"/>
- <cd:constant type="m"/>
- <cd:constant type="y"/>
- <cd:constant type="k"/>
- <cd:constant type="p"/>
- <cd:constant type="s"/>
- <cd:constant type="ne"/>
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="kriterium">
- <cd:constant type="vse"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definecolor" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="definujbarvu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="r">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="g">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="b">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="c">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="m">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="y">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="k">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="s">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="h">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="t">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="a">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="p">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="e">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="color" type="environment" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="barva"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="color" file="colo-ini.tex">
- <cd:sequence>
- <cd:string value="barva"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="graycolor" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="sedabarva"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showcolor" file="colo-run.tex" category="colors"> <!-- and debug -->
- <cd:sequence>
- <cd:string value="ukazbarvu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definepalet" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="definujpaletu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="cd:name">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppalet" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="nastavpaletu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definecolorgroup" file="colo-ini.tex" category="colors">
- <cd:sequence>
- <cd:string value="definujskupinubarev"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="rgb" default="yes"/>
- <cd:constant type="cmyk"/>
- <cd:constant type="seda"/>
- <cd:constant type="s"/>
- </cd:keywords>
- <cd:triplet n="3" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showpalet" file="colo-run.tex" category="colors"> <!-- and debug -->
- <cd:sequence>
- <cd:string value="ukazpaletu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="horizontalne"/>
- <cd:constant type="vertikalne"/>
- <cd:constant type="jmeno"/>
- <cd:constant type="hodnota"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showcolorgroup" file="colo-run.tex" category="colors"> <!-- and debug-->
- <cd:sequence>
- <cd:string value="ukazskupinubarev"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="horizontalne"/>
- <cd:constant type="vertikalne"/>
- <cd:constant type="jmeno"/>
- <cd:constant type="hodnota"/>
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="comparepalet" file="colo-run.tex" category="colors"> <!-- and debug? -->
- <cd:sequence>
- <cd:string value="porovnejpaletu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="comparecolorgroup" file="colo-run.tex" category="colors">
- <cd:sequence>
- <cd:string value="porovnejskupinubarev"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showmakeup" file="supp-vis.tex" category="debug">
- <cd:sequence>
- <cd:string value="ukazupravu"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="definetype" file="core-ver.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="definetype"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavtype" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptype" file="core-ver.tex" category="verbatim"> <!-- TODO -->
- <cd:sequence>
- <cd:string value="nastavtype"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="mezera">
- <cd:constant type="zap"/>
- <cd:constant type="vyp" default="yes"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="sklonene"/>
- <cd:constant type="normalni"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name" default=""/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="type" file="verb-ini.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="opis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="typ" file="core-ver.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="pis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="tex" file="core-ver.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="tex"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <!-- cd:command name="arg" file="core-ver.tex"> command broken
- <cd:sequence>
- <cd:string value="arg"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content/>
- </cd:arguments>
-</cd:command -->
-
- <cd:command name="definetyping" file="core-ver.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="definujopis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:inherit name="nastavopis" n="1"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavopis" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptyping" file="core-ver.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="nastavopis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="soubor"/>
- <cd:constant type="typing"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="mezera">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="sklonene"/>
- <cd:constant type="normalni"/>
- <cd:constant type="prikazy"/>
- <cd:constant type="barevne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="iprikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vprikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="cprikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command" default="\blank"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command" default="\blank"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="standardni"/>
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="sudamarginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="lichyokraj">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="prazdny">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="standardni"/>
- <cd:constant type="pulradku"/>
- <cd:constant type="radek"/>
- </cd:parameter>
- <cd:parameter name="escape">
- <cd:constant type="cd:character"/>
- </cd:parameter>
- <cd:parameter name="mezera">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="tab">
- <cd:constant type="cd:number"/>
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="odsadpristi">
- <cd:resolve name="indentnext"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="paleta">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="radky">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="hyphenated"/>
- </cd:parameter>
- <cd:parameter name="prazdne">
- <cd:constant type="ano"/>
- <cd:constant type="vse"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="cislovani">
- <cd:constant type="radek"/>
- <cd:constant type="soubor"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="typing" type="environment" generated="yes" file="verb-ini.tex"
- category="verbatim">
- <cd:sequence>
- <cd:variable value="typing"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="typefile" file="verb-ini.tex" category="verbatim">
- <cd:sequence>
- <cd:string value="opissoubor"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfootnotes" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="nastavpoznamkypodcarou"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- </cd:parameter>
- <cd:parameter name="zpusob">
- <cd:constant type="bytext"/>
- <cd:constant type="bycd:section"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="stranka"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="sloupce"/>
- <cd:constant type="firstcolumn"/>
- <cd:constant type="lastcolumn"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="linka">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostsloupcu">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostokraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ciselnyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="textovyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="split">
- <cd:constant type="tolerantni"/>
- <cd:constant type="striktni"/>
- <cd:constant type="velmistriktni"/>
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="styltextu">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barvatextu">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="interakce">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="faktor">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfootnotedefinition" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="nastavdefinicipoznamekpodcarou"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:inherit name="nastavpopisy" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="footnote" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="poznamkapodcarou"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="footnotetext" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="footnotetext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="note" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="poznamka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" interactive="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="localfootnotes" type="environment" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="localfootnotes"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="placelocalfootnotes" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="umistilokalnipoznamkypodcarou"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavpoznamkypodcarou" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placefootnotes" file="core-not.tex" category="footnotes">
- <cd:sequence>
- <cd:string value="umistipoznamkypodcarou"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavpoznamkypodcarou" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupunderbar" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="nastavpodtrzeni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="alternativa">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="c"/>
- </cd:parameter>
- <cd:parameter name="tloustkalinky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsetspodku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsetvrsku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barvalinky">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="underbar" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="podtrzeno"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="underbars" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="podtrzeni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="overbar" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="nadtrzeno"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="overbars" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="nadtrzeni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="overstrike" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="preskrtnuto"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="overstrikes" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="preskrtnuti"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="romannumerals" file="core-con.tex">
- <cd:sequence>
- <cd:string value="rimskecislice"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Romannumerals" file="core-con.tex">
- <cd:sequence>
- <cd:string value="Rimskecislice"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="numbers" file="core-con.tex">
- <cd:sequence>
- <cd:string value="cisla"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="character" file="core-con.tex">
- <cd:sequence>
- <cd:string value="znak"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Character" file="core-con.tex">
- <cd:sequence>
- <cd:string value="Znak"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="characters" file="core-con.tex">
- <cd:sequence>
- <cd:string value="znaky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Characters" file="core-con.tex">
- <cd:sequence>
- <cd:string value="Znaky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="mediaeval" file="core-con.tex">
- <cd:sequence>
- <cd:string value="mediaeval"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="month" file="core-con.tex">
- <cd:sequence>
- <cd:string value="mesic"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="MONTH" file="core-con.tex">
- <cd:sequence>
- <cd:string value="MESIC"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="weekday" file="core-con.tex">
- <cd:sequence>
- <cd:string value="vsedniden"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="WEEKDAY" file="core-con.tex">
- <cd:sequence>
- <cd:string value="VSEDNIDEN"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcapitals" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="nastavkapitalky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="titul">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="sc">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="cap" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="cap"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nocap" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="nocap"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="CAP" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="CAP"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Cap" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="Cap"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Caps" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="Caps"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="WORD" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="SLOVO"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="WORDS" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="SLOVA"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Word" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="Slovo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="Words" file="core-fnt.tex" category="Fonts">
- <cd:sequence>
- <cd:string value="Slova"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="stretched" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="roztazene"/>
- </cd:sequence>
- <cd:arguments>
- <cd:word n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definesymbol" file="symb-ini.tex">
- <cd:sequence>
- <cd:string value="definujsymbol"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definefiguresymbol" file="symb-ini.tex">
- <cd:sequence>
- <cd:string value="definujobrazeksymbol"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="nastavexterniobrazy" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="symbol" file="symb-ini.tex">
- <cd:sequence>
- <cd:string value="symbol"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="symbolset" type="environment" file="symb-ini.tex" category="symbols">
- <cd:sequence>
- <cd:string value="symbolset"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsymbolset" file="symb-ini.tex" category="symbols">
- <cd:sequence>
- <cd:string value="nastavsadusymbolu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usesymbols" file="symb-ini.tex" category="symbols">
- <cd:sequence>
- <cd:string value="uzijsymbol"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showsymbolset" file="symb-run.tex" category="symbols"> <!-- and symbols -->
- <cd:sequence>
- <cd:string value="ukazsadusymbolu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineconversion" file="core-con.tex">
- <cd:sequence>
- <cd:string value="definujkonverzi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:command"/>
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="convertnumber" file="core-con.tex">
- <cd:sequence>
- <cd:string value="konvertujcislo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupheadtext" file="lang-lab.tex">
- <cd:sequence>
- <cd:string value="nastavtexthlavicky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="language"/>
- </cd:keywords>
- <cd:assignments n="2">
- <cd:parameter name="cd:name">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplabeltext" file="lang-lab.tex">
- <cd:sequence>
- <cd:string value="nastavtextpopisku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="language"/>
- </cd:keywords>
- <cd:assignments n="2">
- <cd:parameter name="cd:name">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="headtext" file="lang-lab.tex">
- <cd:sequence>
- <cd:string value="texthlavicky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="labeltext" file="lang-lab.tex">
- <cd:sequence>
- <cd:string value="textpopisku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupmarginrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavmarginalnilinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1">
- <cd:parameter name="uroven">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="tloustkalinky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="marginrule" type="environment" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="marginalnilinka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="marginrule" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="marginalnilinka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplinewidth" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavsirkucary"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:dimension"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupframed" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavoramovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/> <!-- defines a command with that name -->
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="vyska">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="fixne"/>
- <cd:constant type="lokalne"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="autosirka">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="sila"/>
- </cd:parameter>
- <cd:parameter name="offset">
- <cd:constant type="zadny"/>
- <cd:constant type="prekryv"/>
- <cd:constant type="implicitni"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="podlehloubky"/>
- <cd:constant type="visici"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="nivy"/>
- <cd:constant type="nizko"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="nastred"/>
- <cd:constant type="spodek"/>
- <cd:constant type="drzet"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="zadny"/>
- <cd:constant type="prazdne"/>
- </cd:parameter>
- <cd:parameter name="strut">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="globalne"/>
- <cd:constant type="lokalne"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="spodek">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vrsek">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="ramecek">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- <cd:constant type="zadny"/>
- <cd:constant type="prekryv"/>
- </cd:parameter>
- <cd:parameter name="rameceknahore">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="ramecekdole">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="ramecekvlevo">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="ramecekvpravo">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="offsetramecku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="hloubkaramecku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="rohramecku">
- <cd:constant type="zaobleny"/>
- <cd:constant type="pravouhly"/>
- </cd:parameter>
- <cd:parameter name="polomerramecku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barvaramecku">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="pozadi">
- <cd:constant type="rastr"/>
- <cd:constant type="barevne"/>
- <cd:constant type="zadny"/>
- <cd:constant type="popredi"/>
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="rastrpozadi">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="barvapozadi">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="offsetpozadi">
- <cd:constant type="ramecek"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="hloubkapozadi">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="rohpozadi">
- <cd:constant type="zaobleny"/>
- <cd:constant type="pravouhly"/>
- </cd:parameter>
- <cd:parameter name="polomerpozadi">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="roh">
- <cd:constant type="zaobleny"/>
- <cd:constant type="pravouhly"/>
- </cd:parameter>
- <cd:parameter name="polomer">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="prazdne">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="foregroundcolor">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="foregroundstyle">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="tloustkalinky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="framed" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="oramovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inframed" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="zaramovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="thinrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="tenkelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes">
- <cd:inherit name="nastavtenkelinky" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupthinrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavtenkelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1">
- <cd:parameter name="meziradkovamezera">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="barvapozadi">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="c"/>
- <cd:constant type="d"/>
- </cd:parameter>
- <cd:parameter name="tloustkalinky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="pozadi">
- <cd:constant type="barevne"/>
- </cd:parameter>
- <cd:parameter name="barvapozadi">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="hairline" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="vlasovalinka"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="thinrule" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="tenkalinka"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="defineframedtext" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="definujoramovanytext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavoramovanetexty" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineframed" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="definujoramovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavoramovanetexty" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupframedtexts" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavoramovanetexty"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vnitrni">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="korekceradku">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="korekcehloubky">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="standardni"/>
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="odsazovani">
- <cd:resolve name="indenting"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="framedtext" type="environment" generated="yes" file="core-rul.tex">
- <cd:sequence>
- <cd:variable value="oramovanytext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="zadny"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavoramovanetexty" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="framedtext" generated="yes" file="core-rul.tex">
- <cd:sequence>
- <cd:variable value="oramovanytext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavoramovanetexty" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="background" type="environment" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="pozadi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="background" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="pozadi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbackground" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavpozadi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="levyoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pravyoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsetvrsku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsetspodku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fillinrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="vyplnovelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavvyplnovelinky" n="1"/>
- </cd:assignments>
- <cd:content n="2"/>
- <cd:content n="3" optional="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fillintext" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="vyplnenytext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavvyplnovelinky" n="1"/>
- </cd:assignments>
- <cd:content n="2"/>
- <cd:content n="3" optional="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfillinrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavvyplnovelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="meziradkovamezera">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fillinline" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="vyplnovyradek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavvyplnoveradky" n="1"/>
- </cd:assignments>
- <cd:nothing n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfillinlines" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavvyplnoveradky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptextrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavtextovelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="naokraji"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barvalinky">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="textrule" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="textovalinka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- </cd:keywords>
- <cd:content n="2" optional="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="textrule" type="environment" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="textovalinka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- </cd:keywords>
- <cd:content n="2" optional="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="blackrule" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="cernalinka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavcernelinky" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="blackrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="cernelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:inherit name="nastavcernelinky" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupblackrules" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavcernelinky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension" default="1em"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension" default="1ex"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="a" default="yes"/>
- <cd:constant type="b"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension" default=".25ex"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number" default="3"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name" default=""/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineoverlay" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="definujprekryv"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:command"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usemodule" file="core-fil.tex"> <!-- TODO -->
- <cd:sequence>
- <cd:string value="uzijmodul"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="reset" file="core-num.tex">
- <cd:sequence>
- <cd:string value="reset"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <!-- <cd:command name="donttest">
- <cd:sequence>
- <cd:string value="zadnytest"/>
- </cd:sequence>
-</cd:command> -->
-
- <cd:command name="localenvironment" type="environment" file="core-job.tex">
- <cd:sequence>
- <cd:string value="localenvironment"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupsystem" file="core-sys.tex">
- <cd:sequence>
- <cd:string value="nastavsystem"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="rozliseni">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="soubor">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="adresar">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="nahodne">
- <cd:constant type="normalni"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usedirectory" file="core-job.mkii"> <!-- usepath, todo: more than one file -->
- <cd:sequence>
- <cd:string value="usedirectory"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- <cd:constant type="reset"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="low" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="nizky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="high" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="vysoky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="lohi" file="core-fnt.tex">
- <cd:sequence>
- <cd:string value="nivy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showframe" file="page-run.tex">
- <cd:sequence>
- <cd:string value="ukazramecek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- <cd:constant type="marginalie"/>
- <cd:constant type="hrana"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="leftaligned" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zarovnanovlevo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="rightaligned" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zarovnanovpravo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="midaligned" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zarovnanonastred"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="wordright" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="slovovpravo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inmargin" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="naokraj"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inothermargin" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="nadruhyokraj"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inleft" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="vlevo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inright" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="vpravo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="ininner" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="ininner"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inouter" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="inouter"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="column" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="sloupec"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="showstruts" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="ukazpodpery"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="showsetups" file="page-run.tex">
- <cd:sequence>
- <cd:string value="ukaznastaveni"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="showlayout" file="page-run.tex">
- <cd:sequence>
- <cd:string value="ukazvzhled"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="margintext" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="marginalnitext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="nizko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupmarginblocks" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="nastavmarginalniblok"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="naokraji"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="vrsek">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="spodek">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="marginblock" type="environment" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="marginblock"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="part" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="part"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="title" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="title"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="chapter" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="chapter"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="section" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="section"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="subsection" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="subsection"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="subsubsection" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="subsubsection"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="subject" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="subject"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="subsubject" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="subsubject"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="subsubsubject" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="subsubsubject"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="appendix" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="appendix"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="in" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="tref"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="yes"/>
- <cd:content n="2" interactive="yes"/>
- <cd:reference n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="at" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="pref"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="yes"/>
- <cd:content n="2" interactive="yes"/>
- <cd:reference n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="about" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="oref"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="yes"/>
- <cd:reference n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="somewhere" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="nekde"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- <cd:reference n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="atpage" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="nastrane"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="ref" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="ref"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="t"/>
- <cd:constant type="p"/>
- <cd:constant type="r"/>
- <cd:constant type="s"/>
- <cd:constant type="e"/>
- </cd:keywords>
- <cd:reference n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="textreference" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="odkaznatext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="pagereference" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="odkaznastranu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="reference" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="odkaz"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usereferences" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="uzijodkazy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definereference" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="definujodkaz"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:reference n="2" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definereferenceformat" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="definujformatodkazu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="vlevo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="popisek">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="hl" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="hl"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="vl" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="vl"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="godown" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="jdidolu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:dimension"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="whitespace" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="bilemisto"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="nowhitespace" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zadnebilemisto"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="crlf" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="crlf"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="space" file="syst-pln.tex">
- <cd:sequence>
- <cd:string value="mezera"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="fixedspaces" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="tvrdemezery"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="emptylines" file="page-lin.tex">
- <cd:sequence>
- <cd:string value="emptylines"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nospace" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zadnamezera"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="packed" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zhustene"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupdescriptions" file="core-des.tex">
- <cd:sequence>
- <cd:string value="nastavpopisy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/> <!-- TODO: style=normal -->
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name" default=""/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="cd:dimension" default="8em"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="vzor">
- <cd:constant type="cd:text" default=""/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="closesymbol">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="closecommand">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="closesymbol">
- <cd:constant type="cd:text" default=""/>
- </cd:parameter>
- <cd:parameter name="titleleft">
- <cd:constant type="cd:text" default="("/>
- </cd:parameter>
- <cd:parameter name="titleright">
- <cd:constant type="cd:text" default=")"/>
- </cd:parameter>
- <cd:parameter name="vzdalenosttitulek">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="styltitulek">
- <cd:resolve name="style"/> <!-- TODO: default=bold -->
- </cd:parameter>
- <cd:parameter name="barvatitulek">
- <cd:constant type="cd:name" default=""/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="standardni"/>
- <cd:constant type="ano"/>
- <cd:constant type="ne" default="yes"/> <!-- TODO: this is default; conflicting syntax? -->
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo" default="yes"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="semknuto"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="visici"/>
- </cd:parameter>
- <cd:parameter name="stylhlavicky">
- <cd:resolve name="style"/> <!-- TODO: default=bold -->
- </cd:parameter>
- <cd:parameter name="barvahlavicky">
- <cd:constant type="cd:name" default=""/>
- </cd:parameter>
- <cd:parameter name="headcommand">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="zaveseni">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command" default="\blank"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command" default="\blank"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command" default="\blank"/>
- </cd:parameter>
- <cd:parameter name="odsadpristi">
- <cd:resolve name="indentnext"/> <!-- default=yes -->
- </cd:parameter>
- <cd:parameter name="odsazovani">
- <cd:resolve name="indenting"/> <!-- default=never -->
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupenumerations" file="core-des.tex">
- <cd:sequence>
- <cd:string value="nastavvycty"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavpopisy" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineenumeration" file="core-des.tex">
- <cd:sequence>
- <cd:string value="definujvycet"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="nastavvycty" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="enumeration" generated="yes" file="core-des.tex">
- <cd:sequence>
- <cd:variable value="vycet"/>
- </cd:sequence>
- <cd:arguments>
- <cd:nothing n="1" interactive="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="enumeration" type="environment" generated="yes" file="core-des.tex">
- <cd:sequence>
- <cd:variable value="vycet"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="definedescription" file="core-des.tex">
- <cd:sequence>
- <cd:string value="definujpopis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavpopisy" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="description" generated="yes" file="core-des.tex">
- <cd:sequence>
- <cd:variable value="popis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:nothing n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="description" type="environment" generated="yes" file="core-des.tex">
- <cd:sequence>
- <cd:variable value="popis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupindentations" file="core-des.tex">
- <cd:sequence>
- <cd:string value="nastavodsazeni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylhlavicky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="vzor">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineindenting" file="core-des.tex">
- <cd:sequence>
- <cd:string value="definujodsazovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavodsazeni" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="indentation" generated="yes" file="core-spa.tex">
- <cd:sequence>
- <cd:variable value="indentation"/>
- </cd:sequence>
- <cd:arguments>
- <cd:nothing n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definelabel" file="core-des.tex">
- <cd:sequence>
- <cd:string value="definujpopisek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="text">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="naokraji"/>
- <cd:constant type="dotextu"/>
- </cd:parameter>
- <cd:parameter name="zpusob">
- <cd:constant type="bytext"/>
- <cd:constant type="bycd:section"/>
- </cd:parameter>
- <cd:parameter name="dobloku">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="stylhlavicky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barvahlavicky">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="labeling" generated="yes" file="core-des.tex">
- <cd:sequence>
- <cd:variable value="labeling"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcolumns" file="page-mul.tex">
- <cd:sequence>
- <cd:string value="nastavsloupce"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes"> <!-- no idea why it is optional -->
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="nvrsek">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="linka">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/> <!-- default and unknown missing -->
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="tolerance">
- <cd:constant type="velmistriktni"/>
- <cd:constant type="striktni"/>
- <cd:constant type="tolerantni"/>
- <cd:constant type="velmitolerantni"/>
- <cd:constant type="natahnout"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="rovnovaha">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:constant type="text"/>
- <!-- cd:constant type="yes"/ -->
- <!-- cd:constant type="no"/ -->
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="prazdny">
- <cd:constant type="fixne"/>
- <cd:constant type="pulradku"/>
- <cd:constant type="radek"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="velke"/>
- <cd:constant type="stredni"/>
- <cd:constant type="male"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="pozadi"/>
- </cd:parameter>
- <cd:parameter name="smer">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="columns" type="environment" file="page-mul.tex">
- <cd:sequence>
- <cd:string value="columns"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavsloupce" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definetext" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="definujtext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="zahlavi"/>
- <cd:constant type="upati"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="4" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="5" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupheader" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavzahlavi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text" default="yes"/>
- <cd:constant type="marginalie"/>
- <cd:constant type="hrana"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="status">
- <cd:constant type="normalni"/>
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="zadny"/>
- <cd:constant type="zadneznaceni"/>
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="strut">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylvlevo">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylvpravo">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="sirkavlevo">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirkavpravo">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfooter" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavupati"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:inherit name="nastavzahlavi" n="1"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavzahlavi" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptext" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavtext"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:inherit name="nastavzahlavi" n="1"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavzahlavi" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptop" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavhorejsek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:inherit name="nastavzahlavi" n="1"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavzahlavi" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbottom" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavspodek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:inherit name="nastavzahlavi" n="1"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavzahlavi" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="noheaderandfooterlines" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="zadnezahlaviaupati"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="notopandbottomlines" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="zadnehorniadolniradky"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupheadertexts" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavtextyzahlavi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:resolve name="texts"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfootertexts" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavtextyupati"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:resolve name="texts"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptexttexts" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavtexttexty"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:resolve name="texts"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptoptexts" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavhornitexty"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:resolve name="texts"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbottomtexts" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="nastavdolnitexty"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:resolve name="texts"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="settextcontent" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="settextcontent"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:resolve name="layout-v"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="3" optional="yes">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="4" optional="yes">
- <cd:resolve name="texts"/>
- </cd:keywords>
- <cd:keywords n="5" optional="yes">
- <cd:resolve name="texts"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="resettextcontent" file="page-txt.tex">
- <cd:sequence>
- <cd:string value="resettextcontent"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:resolve name="layout-v"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:resolve name="layout-h"/>
- </cd:keywords>
- <cd:keywords n="3" optional="yes">
- <cd:constant type="lefttext"/>
- <cd:constant type="middletext"/>
- <cd:constant type="righttext"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definemarking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="definujznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="couplemarking" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="propojeneznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="decouplemarking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="rozpojeneznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="resetmarking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="resetznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupmarking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="nastavznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="expanzen">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="marking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="znaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="getmarking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="ziskejznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="prvni"/>
- <cd:constant type="posledni"/>
- <cd:constant type="predchozi"/>
- <cd:constant type="obe"/>
- <cd:constant type="vse"/>
- <cd:constant type="aktualni"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nomarking" file="core-mar.tex">
- <cd:sequence>
- <cd:string value="zadneznaceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplayout" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="nastavvzhled"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="nastred"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="nastred"/>
- </cd:parameter>
- <cd:parameter name="zpetnamezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="svrchnimezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="levyokraj">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pravyokraj">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="zahlavi">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="upati">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vrsek">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="spodek">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="levahrana">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pravahrana">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostzahlavi">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostupati">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostvrsku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostspodku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostlevehookraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostpravehookraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostlevehrany">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostpravehrany">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="horoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsethlavicky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="znaceni">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- <cd:constant type="barevne"/>
- <cd:constant type="rastr"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="spodek"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="jednostranne"/>
- <cd:constant type="dvoustranny"/>
- </cd:parameter>
- <cd:parameter name="meritko">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="nx">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ny">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="dx">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="dy">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="radky">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="sloupce">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostsloupcu">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="mrizka">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="bottomspace">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="cutspace">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="textdistance">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirkatextu">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="textmargin">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="clipoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="papir">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="adaptlayout" file="page-lay.tex">
- <cd:sequence>
- <cd:string value="prizpusobvzhled"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="radky">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showgrid" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="ukazmrizku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="reset"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="zadny"/>
- <cd:constant type="vse"/>
- <cd:constant type="radky"/>
- <cd:constant type="ramecek"/>
- <cd:constant type="nonumber"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vlevo"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placeongrid" file="core-grd.tex">
- <cd:sequence>
- <cd:string value="umistinamrizku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:inherit name="premistinamrizku" n="1"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="moveongrid" file="core-grd.tex">
- <cd:sequence>
- <cd:string value="premistinamrizku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="standardni" default="yes"/> <!-- also 'normal', 'yes' and 'force' -->
- <cd:constant type="vrsek"/>
- <cd:constant type="obe"/>
- <cd:constant type="spodek"/>
- <cd:constant type="-top"/>
- <cd:constant type="-both"/>
- <cd:constant type="-bottom"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="nastred"/>
- <cd:constant type="nizko"/>
- <cd:constant type="stranka"/>
- <cd:constant type="siroky"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="podlehloubky"/>
- <cd:constant type="radek"/>
- <cd:constant type="reset"/>
- <cd:constant type="zadny"/>
- <cd:constant type="cd:dimension"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="project" type="environment" file="core-job.tex">
- <cd:sequence>
- <cd:string value="projekt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:file n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="environment" type="environment" file="core-job.tex">
- <cd:sequence>
- <cd:string value="prostredi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:file n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="product" type="environment" file="core-job.tex">
- <cd:sequence>
- <cd:string value="produkt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:file n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="component" type="environment" file="core-job.tex">
- <cd:sequence>
- <cd:string value="komponenta"/>
- </cd:sequence>
- <cd:arguments>
- <cd:file n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nomorefiles" file="core-job.tex">
- <cd:sequence>
- <cd:string value="zadnedalsisoubory"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupinterlinespace" variant="1" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="nastavmeziradkovoumezeru"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="reset"/>
- <cd:constant type="male" default="yes"/>
- <cd:constant type="stredni"/>
- <cd:constant type="auto"/>
- <cd:constant type="velke"/>
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
- <!-- attached a 2 to make this definition usable with \showsetup -->
- <cd:sequence>
- <cd:string value="nastavmeziradkovoumezeru"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="vyska">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="radek">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vrsek">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="spodek">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppagenumbering" file="page-num.tex">
- <cd:sequence>
- <cd:string value="nastavcislovanistran"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="alternativa">
- <cd:constant type="jednostranne"/>
- <cd:constant type="dvoustranny"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="zahlavi"/>
- <cd:constant type="upati"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="marginalie"/>
- <cd:constant type="textovahrana"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="zpusob">
- <cd:constant type="bytext"/>
- <cd:constant type="bycd:section"/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="oddelovaccisla">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="oddelovactextu">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="cd:sectionnumber">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="strut">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupnarrower" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="nastavzuzeni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="vlevo">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stredni">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="define" file="syst-ext.tex">
- <cd:sequence>
- <cd:string value="definuj"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- <cd:csname n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usecommands" file="core-sys.tex">
- <cd:sequence>
- <cd:string value="uzijprikazy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definestartstop" file="core-sys.tex">
- <cd:sequence>
- <cd:string value="definujstartstop"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="prikazy">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupheads" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="nastavnadpisy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="cislooddilu">
- <cd:constant type="ano"/>
- <cd:constant type="cd:number"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="normalni"/>
- <cd:constant type="marginalie"/>
- <cd:constant type="nastred"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="odstavec"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="predel">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="zarovnejtitul">
- <cd:constant type="ano"/>
- <cd:constant type="plvouciobjekt"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="tolerance">
- <cd:constant type="velmistriktni"/>
- <cd:constant type="striktni"/>
- <cd:constant type="tolerantni"/>
- <cd:constant type="velmitolerantni"/>
- <cd:constant type="natahnout"/>
- </cd:parameter>
- <cd:parameter name="odsadpristi">
- <cd:resolve name="indentnext"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:twoarguments"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcaptions" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="nastavpopisky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="zadny"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="nizko"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="lefthanging"/>
- <cd:constant type="righthanging"/>
- <cd:constant type="levyokraj"/>
- <cd:constant type="pravyokraj"/>
- <cd:constant type="innermargin"/>
- <cd:constant type="outermargin"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="max"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="minsirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stylhlavicky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="cislo">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- </cd:parameter>
- <cd:parameter name="zpusob">
- <cd:constant type="bytext"/>
- <cd:constant type="bycd:section"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="predel">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcaption" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="nastavpopisek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavpopisky" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfloats" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="nastavplvouciobjekty"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="nastred"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="mezerapred">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="mezeraza">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="bocnimezerapred">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="bocnimezeraza">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="odsadpristi">
- <cd:resolve name="indentnext"/>
- </cd:parameter>
- <cd:parameter name="nvrsek">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="nspodek">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="nradky">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="implicitni">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="tolerance">
- <cd:constant type="0"/>
- <cd:constant type="1"/>
- <cd:constant type="2"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostlevehookraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostpravehookraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sidealign">
- <cd:constant type="normalni"/>
- <cd:constant type="radek"/>
- </cd:parameter>
- <cd:parameter name="cislovani">
- <cd:constant type="ano"/>
- <cd:constant type="nocheck"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfloatsplitting" file="core-tsp.tex">
- <cd:sequence>
- <cd:string value="nastavdeleniplvoucichobjektu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- </cd:parameter>
- <cd:parameter name="radky">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="splitfloat" file="core-tsp.tex">
- <cd:sequence>
- <cd:string value="rozdelplvouciobjekt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavdeleniplvoucichobjektu" n="1"/>
- </cd:assignments>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupoppositeplacing" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="nastavumisteniprotejsku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="opposite" type="environment" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="opposite"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setuphyphenmark" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavdelitko"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1">
- <cd:parameter name="znak">
- <cd:constant type="--"/>
- <cd:constant type="---"/>
- <cd:constant type="-"/>
- <cd:constant type="~"/>
- <cd:constant type="("/>
- <cd:constant type=")"/>
- <cd:constant type="="/>
- <cd:constant type="/"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppositioning" file="page-lyr.tex">
- <cd:sequence>
- <cd:string value="nastavumistovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="prekryv"/>
- </cd:parameter>
- <cd:parameter name="jednotka">
- <cd:constant type="cm"/>
- <cd:constant type="pt"/>
- <cd:constant type="em"/>
- <cd:constant type="mm"/>
- <cd:constant type="ex"/>
- <cd:constant type="es"/>
- <cd:constant type="in"/>
- </cd:parameter>
- <cd:parameter name="faktor">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="meritko">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="offset">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="xkrok">
- <cd:constant type="absolutni"/>
- <cd:constant type="relativni"/>
- </cd:parameter>
- <cd:parameter name="ykrok">
- <cd:constant type="absolutni"/>
- <cd:constant type="relativni"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="positioning" type="environment" file="page-lyr.tex">
- <cd:sequence>
- <cd:string value="positioning"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="grid" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="mrizka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="x">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="y">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="nx">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ny">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="dx">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="dy">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="xkrok">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ykrok">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="offset">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="faktor">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="meritko">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="jednotka">
- <cd:constant type="cm"/>
- <cd:constant type="pt"/>
- <cd:constant type="em"/>
- <cd:constant type="mm"/>
- <cd:constant type="ex"/>
- <cd:constant type="es"/>
- <cd:constant type="in"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="page" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="strana"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="ano" default="yes"/>
- <cd:constant type="zlom"/>
- <cd:constant type="ne"/>
- <cd:constant type="nastaveni"/>
- <cd:constant type="vysokapriorita"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="zablokovat"/>
- <cd:constant type="posledni"/>
- <cd:constant type="ctyrnasobny"/>
- <cd:constant type="sude"/>
- <cd:constant type="liche"/>
- <cd:constant type="prazdny"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="reset"/>
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupreferencing" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="nastavodkazovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="cd:sectionnumber">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="prefix">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="interakce">
- <cd:constant type="popisek"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="vse"/>
- <cd:constant type="symbol"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="konverzesouboru">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="male"/>
- <cd:constant type="velke"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="autofile">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="stranka"/>
- </cd:parameter>
- <cd:parameter name="globalne">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupurl" file="core-ref.tex" category="references">
- <cd:sequence>
- <cd:string value="nastavurl"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="urlalternativa">
- <cd:constant type="zadny"/>
- <cd:constant type="obe"/>
- <cd:constant type="pred"/>
- <cd:constant type="po"/>
- </cd:parameter>
- <cd:parameter name="prostorurl">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="writetoreferencelist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="zapisdoseznamuodkazu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placereferencelist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="placereferencelist"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definereferencelist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="definujseznamodkazu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavseznamodkazu" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupreferencelist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="nastavseznamodkazu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="kriterium">
- <cd:constant type="cd:section"/>
- <cd:constant type="lokalne"/>
- <cd:constant type="predchozi"/>
- <cd:constant type="vse"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="writetolist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="zapisdoseznamu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:section"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="writebetweenlist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="zapismeziseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:section"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nolist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="zadnyseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="listsymbol" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="listsymbol"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placelist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="umistiseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="determinelistcharacteristics" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="stanovcharakteristickuseznamu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placecombinedlist" variant="1" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="umistikombinovanyseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavkombinovanyseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definelist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="definujseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes"> <!-- inherits from -->
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="nastavseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="nastavseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="c"/>
- <cd:constant type="..."/>
- <cd:constant type="zadny"/>
- <cd:constant type="prikaz"/>
- </cd:parameter>
- <cd:parameter name="propojeni">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="kriterium">
- <cd:constant type="cd:section"/>
- <cd:constant type="lokalne"/>
- <cd:constant type="predchozi"/>
- <cd:constant type="aktualni"/>
- <cd:constant type="vse"/>
- </cd:parameter>
- <cd:parameter name="hranicestranky">
- <cd:constant type="cd:list"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylcisla">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="styltextu">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylstranky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:threearguments"/>
- </cd:parameter>
- <cd:parameter name="ciselnyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="textovyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="strankovyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="interakce">
- <cd:constant type="cd:sectionnumber"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="cislostranky"/>
- <cd:constant type="vse"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="popisek">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="prefix">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="cislostranky">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="cislonadpisu">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="cd:sectionnumber">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="zarovnejtitul">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="predel">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="symbol">
- <cd:constant type="zadny"/>
- <cd:constant type="1"/>
- <cd:constant type="2"/>
- <cd:constant type="3"/>
- <cd:constant type="..."/>
- </cd:parameter>
- <cd:parameter name="expanzen">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prikaz"/>
- </cd:parameter>
- <cd:parameter name="maxsirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplistalternative" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="setuplistalternative"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="no">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="c"/>
- <!-- cd:constant type="cd:name"/ -->
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="prikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="natahnout">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definecombinedlist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="definujkombinovanyseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:list"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="nastavkombinovanyseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcombinedlist" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="nastavkombinovanyseznam"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="uroven">
- <cd:constant type="1"/>
- <cd:constant type="2"/>
- <cd:constant type="3"/>
- <cd:constant type="4"/>
- <cd:constant type="cd:section"/>
- <cd:constant type="aktualni"/>
- </cd:parameter>
- <cd:inherit name="nastavseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placecombinedlist" variant="2" generated="yes" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="umisti"/>
- <cd:variable value="combinedlist"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavkombinovanyseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="completecombinedlist" generated="yes" file="core-lst.tex">
- <cd:sequence>
- <cd:string value="uplny"/>
- <cd:variable value="combinedlist"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavkombinovanyseznam" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupnumbering" file="core-num.tex">
- <cd:sequence>
- <cd:string value="nastavcislovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="zpusob">
- <cd:constant type="bytext"/>
- <cd:constant type="bycd:section"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupformulas" file="core-mat.tex">
- <cd:sequence>
- <cd:string value="nastavrovnice"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="nastred"/>
- </cd:parameter>
- <cd:parameter name="strut">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="standardni"/>
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:constant type="flushleft"/>
- <cd:constant type="flushright"/>
- <cd:constant type="nastred"/>
- <cd:constant type="center"/>
- </cd:parameter>
- <cd:parameter name="levyokraj">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pravyokraj">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="odsadpristi">
- <cd:resolve name="indentnext"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="mezerapred">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="publication" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="publikace"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppublications" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavpublikace"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="alternativa">
- <cd:constant type="apa"/>
- <cd:constant type="normalni"/>
- </cd:parameter>
- <cd:inherit name="nastavvycty" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplines" file="page-lin.tex">
- <cd:sequence>
- <cd:string value="nastavradky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="odsazovani">
- <cd:resolve name="indenting"/>
- </cd:parameter>
- <cd:parameter name="mezera">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="lines" type="environment">
- <cd:sequence>
- <cd:string value="lines"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupparagraphnumbering" file="page-lin.tex">
- <cd:sequence>
- <cd:string value="nastavcislovaniodstavcu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- <cd:constant type="reset"/>
- <cd:constant type="radek"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplinenumbering" file="page-lin.tex">
- <cd:sequence>
- <cd:string value="nastavcislovaniradku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="start">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="krok">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="dotextu"/>
- <cd:constant type="naokraji"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="prefix">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="odkazujici">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="linenumbering" type="environment" file="page-lin.tex"> <!-- mkii/mkiv -->
- <cd:sequence>
- <cd:string value="linenumbering"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="pokracovat"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="line" type="environment">
- <cd:sequence>
- <cd:string value="line"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="someline" file="page-lin.tex">
- <cd:sequence>
- <cd:string value="nejakyradek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="inline" file="page-lin.tex">
- <cd:sequence>
- <cd:string value="vradku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupinmargin" file="page-mar.tex">
- <cd:sequence>
- <cd:string value="nastavmarginalie"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="cd:number"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="obe"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="radek">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="oddelovac">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stack">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppagenumber" file="page-num.tex">
- <cd:sequence>
- <cd:string value="nastavcislostrany"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="cislo">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- <cd:constant type="drzet"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsubpagenumber" file="page-num.tex">
- <cd:sequence>
- <cd:string value="nastavpodcislostrany"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="zpusob">
- <cd:constant type="bytext"/>
- <cd:constant type="bycd:section"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupblank" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="nastavpreskok"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="normalni" default="yes"/>
- <cd:constant type="implicitni"/>
- <cd:constant type="standardni"/>
- <cd:constant type="radek"/>
- <cd:constant type="pulradku"/>
- <cd:constant type="cd:dimension"/>
- <cd:constant type="velke"/>
- <cd:constant type="stredni"/>
- <cd:constant type="male"/>
- <cd:constant type="fixne"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="globalne"/>
- <cd:constant type="neznamy"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineblank" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="definujpreskok"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:inherit name="nastavpreskok" n="1"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definepapersize" file="page-lay.tex">
- <cd:sequence>
- <cd:string value="definujvelikostpapiru"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="meritko">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppaper" file="page-lay.tex">
- <cd:sequence>
- <cd:string value="setuppaper"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="papir">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="nx">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ny">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="svrchnimezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="zpetnamezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="max"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuppapersize" file="page-lay.tex">
- <cd:sequence>
- <cd:string value="nastavvelikostpapiru"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="A3"/>
- <cd:constant type="A4" default="yes"/>
- <cd:constant type="A5"/>
- <cd:constant type="A6"/>
- <cd:constant type="letter"/>
- <cd:constant type="..."/>
- <cd:constant type="CD"/>
- <cd:constant type="cd:name"/>
- <cd:constant type="nasirku"/>
- <cd:constant type="zrcadleno"/>
- <cd:constant type="otoceno"/>
- <cd:constant type="90"/>
- <cd:constant type="180"/>
- <cd:constant type="270"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="negativ"/>
- <cd:inherit name="nastavvelikostpapiru" n="1"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuparranging" file="page-imp.tex">
- <cd:sequence>
- <cd:string value="nastavusporadani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="zablokovat"/>
- <cd:constant type="2*16"/>
- <cd:constant type="2*8"/>
- <cd:constant type="2*4"/>
- <cd:constant type="2*2"/>
- <cd:constant type="2**2"/>
- <cd:constant type="2*2*4"/>
- <cd:constant type="2*4*2"/>
- <cd:constant type="2UP"/>
- <cd:constant type="2DOWN"/>
- <cd:constant type="2SIDE"/>
- <cd:constant type="2TOP"/>
- <cd:constant type="zrcadleno"/>
- <cd:constant type="otoceno"/>
- <cd:constant type="dvoustranny"/>
- <cd:constant type="negativ"/>
- <cd:constant type="pozadi"/>
- <cd:constant type="90"/>
- <cd:constant type="180"/>
- <cd:constant type="270"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showprint" file="page-run.tex"> <!-- page-lay.tex -->
- <cd:sequence>
- <cd:string value="ukazvytisk"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:inherit name="nastavvelikostpapiru" n="1"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:inherit name="nastavvelikostpapiru" n="2"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:inherit name="nastavvzhled" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definelogo" file="page-log.tex">
- <cd:sequence>
- <cd:string value="definujlogo"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="vrsek"/>
- <cd:constant type="zahlavi"/>
- <cd:constant type="upati"/>
- <cd:constant type="spodek"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="zadny"/>
- <cd:constant type="stranka"/>
- <cd:constant type="levahrana"/>
- <cd:constant type="levyokraj"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="pravyokraj"/>
- <cd:constant type="pravahrana"/>
- </cd:keywords>
- <cd:assignments n="4" list="yes">
- <cd:parameter name="prikaz">
- <cd:constant type="cd:command"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placelogos" file="page-log.tex">
- <cd:sequence>
- <cd:string value="umistiloga"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupwhitespace">
- <cd:sequence>
- <cd:string value="nastavbilamista"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="zadny" default="yes"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="radek"/>
- <cd:constant type="fixne"/>
- <cd:constant type="fixuj"/>
- <cd:constant type="cd:dimension"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupindenting">
- <cd:sequence>
- <cd:string value="nastavodsazovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:resolve name="indenting"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definesectionblock" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="definujbloksekce"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:inherit name="nastavbloksekce" n="1"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavbloksekce" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsectionblock" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="nastavbloksekce"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="cislo">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="ano"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definesection" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="definujsekci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsection" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="nastavsekci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:parameter name="konverze">
- <cd:constant type="cisla"/>
- <cd:constant type="pismena"/>
- <cd:constant type="Pismena"/>
- <cd:constant type="rimskecislice"/>
- <cd:constant type="Rimskecislice"/>
- </cd:parameter>
- <cd:parameter name="predchozicislo">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuphead" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="nastavnadpis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:section"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="styltextu">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylcisla">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="barvatextu">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="barvacisla">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="cislo">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="vlastnicislo">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="ano"/>
- </cd:parameter>
- <cd:parameter name="pokracovat">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="zahlavi">
- <cd:constant type="zadny"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="zadneznaceni"/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="zadny"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="zadneznaceni"/>
- </cd:parameter>
- <cd:parameter name="upati">
- <cd:constant type="zadny"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="zadneznaceni"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="normalni"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="nastred"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="zaveseni">
- <cd:constant type="zadny"/>
- <cd:constant type="siroky"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="radek"/>
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:twoarguments"/>
- </cd:parameter>
- <cd:parameter name="ciselnyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="textovyprikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="deepnumbercommand">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="deeptextcommand">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="prefix">
- <cd:constant type="+"/>
- <cd:constant type="-"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="umistihlavicku">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prazdne"/>
- </cd:parameter>
- <cd:parameter name="zvysujicicislo">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="cd:list"/>
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="resetnumber">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="soubor">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="expanzen">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prikaz"/>
- </cd:parameter>
- <cd:parameter name="textmarginalie">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:inherit name="nastavnadpisy" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupheadnumber" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="nastavcislonadpisu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:section"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:number"/>
- <cd:constant type="+cd:number"/>
- <cd:constant type="-cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="headnumber">
- <cd:sequence>
- <cd:string value="cislonadpisu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:section"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="determineheadnumber" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="stanovcislonadpisu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:section"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="currentheadnumber" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="aktualnicislonadpisu"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="nextsection" generated="yes" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="dalsi"/>
- <cd:variable value="sekce"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="definehead" file="core-sec.tex">
- <cd:sequence>
- <cd:string value="definujnadpis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:section"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupitemgroup" file="core-itm.tex">
- <cd:sequence>
- <cd:string value="setupitemgroup"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:number"/>
- <cd:constant type="kazdy"/>
- </cd:keywords>
- <cd:keywords n="3" optional="yes" list="yes">
- <cd:constant type="standardni" default="yes"/>
- <cd:constant type="siroky"/>
- <cd:constant type="semknuto"/>
- <cd:constant type="zhustene"/>
- <cd:constant type="rozbalene"/>
- <cd:constant type="zadnabila"/>
- <cd:constant type="pred"/>
- <cd:constant type="po"/>
- <cd:constant type="predel"/>
- <cd:constant type="spojeno"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="autouvod"/>
- <cd:constant type="uvolnene"/>
- <cd:constant type="opakovat"/>
- <cd:constant type="cd:section"/>
- <cd:constant type="odstavec"/>
- <cd:constant type="dotextu"/>
- <cd:constant type="nahodny"/>
- <cd:constant type="reverse"/>
- </cd:keywords>
- <cd:assignments n="4" optional="yes" list="yes">
- <cd:parameter name="marginalie">
- <cd:constant type="ne"/>
- <cd:constant type="standardni"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="levyokraj">
- <cd:constant type="ne"/>
- <cd:constant type="standardni"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pravyokraj">
- <cd:constant type="ne"/>
- <cd:constant type="standardni"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="faktor">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="polozky">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="start">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="predhlavickou">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pohlavicce">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="stylhlavicky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylsnacky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylsymboly">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="predel">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="symbol">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="symzarovnani">
- <cd:resolve name="symalign"/>
- </cd:parameter>
- <cd:parameter name="odsadpristi">
- <cd:resolve name="indentnext"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="itemgroup" type="environment" generated="yes" file="core-itm.tex">
- <cd:sequence>
- <cd:variable value="itemgroup"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="a"/>
- <cd:constant type="A"/>
- <cd:constant type="KA"/>
- <cd:constant type="n"/>
- <cd:constant type="N"/>
- <cd:constant type="m"/>
- <cd:constant type="r"/>
- <cd:constant type="R"/>
- <cd:constant type="KR"/>
- <cd:constant type="cd:number"/>
- <cd:constant type="pokracovat"/>
- <cd:constant type="standardni" default="yes"/>
- <cd:constant type="siroky"/>
- <cd:constant type="semknuto"/>
- <cd:constant type="zhustene"/>
- <cd:constant type="predel"/>
- <cd:constant type="spojeno"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="uvod"/>
- <cd:constant type="sloupce"/>
- <cd:constant type="text"/>
- <cd:constant type="odstavec"/>
- <cd:constant type="opakovat"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="setupitemgroup" n="4"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="item" file="core-itm.tex">
- <cd:sequence>
- <cd:string value="polozka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="noitem" file="core-itm.tex">
- <cd:sequence>
- <cd:string value="polozka"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="but">
- <cd:sequence>
- <cd:string value="spodek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" interactive="exclusive"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="its">
- <cd:sequence>
- <cd:string value="pol"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="ran">
- <cd:sequence>
- <cd:string value="ran"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="head">
- <cd:sequence>
- <cd:string value="nadpis"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="mar">
- <cd:sequence>
- <cd:string value="okr"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="sub">
- <cd:sequence>
- <cd:string value="sub"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="sym" file="core-itm.tex">
- <cd:sequence>
- <cd:string value="sym"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nop">
- <cd:sequence>
- <cd:string value="nop"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="defineregister" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="definujrejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:singular"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:plural"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupregister" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="nastavrejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:singular"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="rovnovaha">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylstranky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="styltextu">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="indikator">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="propojeni">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="cd:sectionnumber">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="kriterium">
- <cd:constant type="cd:section"/>
- <cd:constant type="lokalne"/>
- <cd:constant type="vse"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="symbol">
- <cd:constant type="1"/>
- <cd:constant type="2"/>
- <cd:constant type="..."/>
- <cd:constant type="n"/>
- <cd:constant type="a"/>
- <cd:constant type="..."/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="interakce">
- <cd:constant type="cislostranky"/>
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="expanzen">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prikaz"/>
- </cd:parameter>
- <cd:parameter name="odkazujici">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="maxsirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="neznamyodkaz">
- <cd:constant type="prazdne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="A"/>
- <cd:constant type="B"/>
- </cd:parameter>
- <cd:parameter name="prefix">
- <cd:constant type="obe"/>
- <cd:constant type="prvni"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="compress">
- <cd:constant type="ne"/>
- <cd:constant type="ano"/>
- </cd:parameter>
- <cd:parameter name="deeptextcommand">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="register" generated="yes" file="core-reg.tex">
- <cd:sequence>
- <cd:variable value="rejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:index n="2" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="startregister" generated="yes" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="start"/>
- <cd:variable value="rejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:index n="2" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="writetoregister" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="zapisdorejstriku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:singular"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:index n="3" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="coupledregister" generated="yes">
- <cd:sequence>
- <cd:string value="propojene"/>
- <cd:variable value="rejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:index n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="coupleregister" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="propojenyrejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placeregister" variant="1" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="umistirejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavrejstrik" n="3"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="seeregister" generated="yes">
- <cd:sequence>
- <cd:string value="viz"/>
- <cd:variable value="rejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:content n="2"/>
- <cd:index n="3" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="completeregister" generated="yes" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="uplny"/>
- <cd:variable value="rejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="yes" optional="yes" list="yes">
- <cd:inherit name="nastavrejstrik" n="3"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placeregister" variant="2" generated="yes" file="core-reg.tex">
- <cd:sequence>
- <cd:string value="umisti"/>
- <cd:variable value="rejstrik"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="yes" optional="yes" list="yes">
- <cd:inherit name="nastavrejstrik" n="3"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definesynonyms" file="core-syn.tex">
- <cd:sequence>
- <cd:string value="definujsynonyma"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:singular"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:plural"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:command"/>
- </cd:keywords>
- <cd:keywords n="4" optional="yes">
- <cd:constant type="cd:command"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsynonyms" file="core-syn.tex">
- <cd:sequence>
- <cd:string value="nastavsynonyma"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="styltextu">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="stylsynonyma">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="semknuto"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="kriterium">
- <cd:constant type="vse"/>
- <cd:constant type="uzito"/>
- </cd:parameter>
- <cd:parameter name="konverze">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="expanzen">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prikaz"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:threearguments"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="synonym" generated="yes">
- <cd:sequence>
- <cd:variable value="synonym"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="completelistofsynonyms" generated="yes">
- <cd:sequence>
- <cd:string value="completelistof"/>
- <cd:variable value="synonyms"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="placelistofsynonyms" generated="yes">
- <cd:sequence>
- <cd:string value="placelistof"/>
- <cd:variable value="synonyms"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="loadsynonyms" generated="yes">
- <cd:sequence>
- <cd:string value="nacist"/>
- <cd:variable value="synonyms"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="definesorting" file="core-syn.tex">
- <cd:sequence>
- <cd:string value="definujtrideni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:singular"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:plural"/>
- </cd:keywords>
- <cd:keywords n="3" optional="yes">
- <cd:constant type="cd:command"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsorting" file="core-syn.tex">
- <cd:sequence>
- <cd:string value="nastavtrideni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:oneargument"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="kriterium">
- <cd:constant type="vse"/>
- <cd:constant type="uzito"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="expanzen">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prikaz"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="sort" generated="yes">
- <cd:sequence>
- <cd:variable value="sort"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="completelistofsorts" generated="yes">
- <cd:sequence>
- <cd:string value="completelistof"/>
- <cd:variable value="sorts"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="placelistofsorts" generated="yes">
- <cd:sequence>
- <cd:string value="placelistof"/>
- <cd:variable value="sorts"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="loadsorts" generated="yes">
- <cd:sequence>
- <cd:string value="nacist"/>
- <cd:variable value="sorts"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="definemakeup" file="page-mak.tex">
- <cd:sequence>
- <cd:string value="definujupravu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:inherit name="nastavupravu" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="makeup" type="environment">
- <cd:sequence>
- <cd:string value="zlom"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavupravu" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupmakeup" file="page-mak.tex">
- <cd:sequence>
- <cd:string value="nastavupravu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="voffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="hoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="vlevo"/>
- <cd:constant type="ano"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="prikazy">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="oboustranne">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="prazdne"/>
- </cd:parameter>
- <cd:parameter name="statuszahlavi">
- <cd:constant type="normalni"/>
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="zadny"/>
- <cd:constant type="zadneznaceni"/>
- </cd:parameter>
- <cd:parameter name="statusupati">
- <cd:constant type="normalni"/>
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="zadny"/>
- <cd:constant type="zadneznaceni"/>
- </cd:parameter>
- <cd:parameter name="statustextu">
- <cd:constant type="normalni"/>
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="zadny"/>
- <cd:constant type="zadneznaceni"/>
- </cd:parameter>
- <cd:parameter name="statusvrsku">
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- </cd:parameter>
- <cd:parameter name="statusspodku">
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- </cd:parameter>
- <cd:parameter name="pagestate">
- <cd:constant type="stop"/>
- <cd:constant type="start"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="namemakeup" type="environment" generated="yes">
- <cd:sequence>
- <cd:variable value="jmeno"/>
- <cd:string value="zlom"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="version">
- <cd:sequence>
- <cd:string value="verze"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="finalni" default="yes"/>
- <cd:constant type="koncept"/>
- <cd:constant type="docasne"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="currentdate">
- <cd:sequence>
- <cd:string value="aktualnidatum"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:inherit name="datum" n="2"/> <!-- or vice versa :) -->
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="date" file="core-con.tex">
- <cd:sequence>
- <cd:string value="datum"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes"> <!-- if not given, current date is used -->
- <cd:parameter name="d">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="m">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="y">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="den"/>
- <cd:constant type="mesic"/>
- <cd:constant type="rok"/>
- <cd:constant type="vsedniden"/>
- <cd:constant type="d"/>
- <cd:constant type="m"/>
- <cd:constant type="y"/> <!-- also j -->
- <cd:constant type="w"/>
- <cd:constant type="dd"/>
- <cd:constant type="mm"/>
- <cd:constant type="yy"/> <!-- also jj -->
- <cd:constant type="mezera"/>
- <cd:constant type="--"/>
- <cd:constant type="day+"/>
- <cd:constant type="d+"/>
- <cd:constant type="dd+"/>
- <cd:constant type="znacka"/>
- <cd:constant type="cd:text"/> <!-- any other text -->
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="referraldate" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="odkaznadatum"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="indenting" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="odsazovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:resolve name="indenting"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="noindenting" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zadneodsazovani"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="blank" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="preskoc"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke" default="yes"/>
- <cd:constant type="zadnabila"/>
- <cd:constant type="zpet"/>
- <cd:constant type="bily"/>
- <cd:constant type="zablokovat"/>
- <cd:constant type="sila"/>
- <cd:constant type="reset"/>
- <cd:constant type="radek"/>
- <cd:constant type="pulradku"/>
- <cd:constant type="cd:formula"/>
- <cd:constant type="fixne"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="zadny"/>
- <cd:constant type="vzdy"/>
- <cd:constant type="vnejsi"/>
- <cd:constant type="spojeno"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="packed" type="environment" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="zhustene"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="prazdny"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="unpacked" type="environment">
- <cd:sequence>
- <cd:string value="unpacked"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="linecorrection" type="environment">
- <cd:sequence>
- <cd:string value="linecorrection"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="correctwhitespace" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="korekcebilehomista"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="postponing" type="environment">
- <cd:sequence>
- <cd:string value="postponing"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="local" type="environment">
- <cd:sequence>
- <cd:string value="lokalne"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="narrower" type="environment">
- <cd:sequence>
- <cd:string value="narrower"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred" default="yes"/>
- <cd:constant type="vpravo"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="hiding" type="environment">
- <cd:sequence>
- <cd:string value="hiding"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupalign" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="nastavzarovnani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="sirka"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="uvnitr"/>
- <cd:constant type="vnejsi"/>
- <cd:constant type="siroce"/>
- <cd:constant type="siroky"/>
- <cd:constant type="vyska"/>
- <cd:constant type="spodek"/>
- <cd:constant type="radek"/>
- <cd:constant type="reset"/>
- <cd:constant type="visici"/>
- <cd:constant type="nothanging"/>
- <cd:constant type="hyphenated"/>
- <cd:constant type="nothyphenated"/>
- <cd:constant type="lesshyphenation"/>
- <cd:constant type="morehyphenation"/>
- <cd:constant type="novy"/>
- <cd:constant type="old"/>
- <cd:constant type="normalni"/>
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- <cd:constant type="flushleft"/>
- <cd:constant type="flushright"/>
- <cd:constant type="flushouter"/>
- <cd:constant type="flushinner"/>
- <cd:constant type="center"/>
- <cd:constant type="hz"/>
- <cd:constant type="nohz"/>
- <cd:constant type="mezerovani"/>
- <cd:constant type="nospacing"/>
- <cd:constant type="tolerantni"/>
- <cd:constant type="velmitolerantni"/>
- <cd:constant type="natahnout"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
-
- <cd:command name="alignment" type="environment" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="alignment"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:inherit name="nastavzarovnani" n="1"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupspacing">
- <cd:sequence>
- <cd:string value="nastavradkovani"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="siroky"/>
- <cd:constant type="zhustene"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptolerance" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="nastavtoleranci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="horizontalne"/>
- <cd:constant type="vertikalne"/>
- <cd:constant type="natahnout"/>
- <cd:constant type="mezera"/>
- <cd:constant type="velmistriktni" default="yes"/>
- <cd:constant type="striktni"/>
- <cd:constant type="tolerantni"/>
- <cd:constant type="velmitolerantni"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="pagetype" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="typstrany"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="processpage" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="zpracujstranu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="ano" default="yes"/>
- <cd:constant type="ne"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="couplepage" file="page-ini.tex">
- <cd:sequence>
- <cd:string value="parovastrana"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="volba">
- <cd:constant type="dvoustranny"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="position" file="page-lyr.tex">
- <cd:sequence>
- <cd:string value="pozice"/>
- </cd:sequence>
- <cd:arguments>
- <cd:position n="1" list="yes"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupscreens" file="core-rul.tex">
- <cd:sequence>
- <cd:string value="nastavrastr"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="metoda">
- <cd:constant type="tecka"/>
- <cd:constant type="linka"/>
- <cd:constant type="externi"/>
- </cd:parameter>
- <cd:parameter name="rozliseni">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="faktor">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="rastr">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbackgrounds" file="page-bck.tex">
- <cd:sequence>
- <cd:string value="nastavpozadi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vrsek"/>
- <cd:constant type="zahlavi"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="upati"/>
- <cd:constant type="spodek"/>
- <cd:constant type="stranka"/>
- <cd:constant type="papir"/>
- <cd:constant type="levastranka"/>
- <cd:constant type="pravastranka"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="levahrana"/>
- <cd:constant type="levyokraj"/>
- <cd:constant type="cd:text"/>
- <cd:constant type="pravyokraj"/>
- <cd:constant type="pravahrana"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- <cd:constant type="cd:repeat"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="buffer" type="environment" generated="yes" file="core-buf.tex">
- <cd:sequence>
- <cd:variable value="buffer"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="buffer" type="environment" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="buffer"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="getbuffer">
- <cd:sequence>
- <cd:string value="ziskejbuffer"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="typebuffer" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="typebuffer"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definebuffer" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="definujbuffer"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbuffer" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="nastavbuffer"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="odstavec">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineblock" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="definujblok"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="nomoreblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="zadnedalsibloky"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="hideblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="schovejbloky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="keepblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="zachovejbloky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="vse"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="uzijbloky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="processblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="zpracujbloky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="bypassblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="bypassblocks"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="forceblocks">
- <cd:sequence>
- <cd:string value="forceblocks"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="selectblocks" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="vyberbloky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes">
- <cd:parameter name="kriterium">
- <cd:constant type="vse"/>
- <cd:constant type="cd:section"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupblock" file="core-buf.tex">
- <cd:sequence>
- <cd:string value="nastavblok"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vnitrni">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="soubor">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="formula" type="environment" generated="yes">
- <cd:sequence>
- <cd:variable value="rovnice"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="mathematics" file="supp-mat.tex">
- <cd:sequence>
- <cd:string value="matematika"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placeformula" file="core-mat.tex">
- <cd:sequence>
- <cd:string value="umistirovnici"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2" optional="yes"/>
- <cd:displaymath n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placesubformula" file="core-mat.tex">
- <cd:sequence>
- <cd:string value="umistipodrovnici"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" optional="yes" list="yes"/>
- <cd:content n="2" optional="yes"/>
- <cd:displaymath n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placefloat" generated="yes" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="umisti"/>
- <cd:variable value="plvouciobjekt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="zde" default="yes"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="marginalie"/>
- <cd:constant type="levyokraj"/>
- <cd:constant type="pravyokraj"/>
- <cd:constant type="levahrana"/>
- <cd:constant type="pravahrana"/>
- <cd:constant type="innermargin"/>
- <cd:constant type="outermargin"/>
- <cd:constant type="inneredge"/>
- <cd:constant type="outeredge"/>
- <cd:constant type="uvnitr"/>
- <cd:constant type="vnejsi"/>
- <cd:constant type="radek"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="nizko"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="stranka"/>
- <cd:constant type="levastranka"/>
- <cd:constant type="pravastranka"/>
- <cd:constant type="naproti"/>
- <cd:constant type="vzdy"/>
- <cd:constant type="auto"/>
- <cd:constant type="sila"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="reset"/>
- <cd:constant type="radek"/>
- <cd:constant type="vyska"/>
- <cd:constant type="podlehloubky"/>
- <cd:constant type="split"/>
- <cd:constant type="90"/>
- <cd:constant type="180"/>
- <cd:constant type="270"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes" list="yes"/>
- <cd:content n="3"/>
- <cd:content n="4"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="reservefloat" generated="yes">
- <cd:sequence>
- <cd:string value="rezervovat"/>
- <cd:variable value="plvouciobjekt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="ramecek">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- </cd:assignments>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:reference n="3" optional="yes" list="yes"/>
- <cd:content n="4"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definefloat" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="definujplvouciobjekt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:singular"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:plural"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfloat" file="page-flt.tex">
- <cd:sequence>
- <cd:string value="nastavplvouciobjekt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="maxvyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="maxsirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="minsirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="implicitni">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="hranicestranky">
- <cd:constant type="cd:list"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostlevehookraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenostpravehookraje">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="floattext" type="environment" generated="yes">
- <cd:sequence>
- <cd:variable value="plvouciobjekt"/>
- <cd:string value="text"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="nastred"/>
- <cd:constant type="nizko"/>
- <cd:constant type="offset"/>
- <cd:constant type="vysoko"/>
- </cd:keywords>
- <cd:reference n="2" optional="yes"/>
- <cd:content n="3"/>
- <cd:content n="4"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placelistoffloats" generated="yes">
- <cd:sequence>
- <cd:string value="placelistof"/>
- <cd:variable value="floats"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="completelistoffloats" generated="yes">
- <cd:sequence>
- <cd:string value="completelistof"/>
- <cd:variable value="floats"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="referral" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="odkaz"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="bet">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="ken">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="dat">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="van">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="aan">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="ref">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="selectpaper">
- <cd:sequence>
- <cd:string value="vyberpapir"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="rodina">
- <cd:constant type="1"/>
- <cd:constant type="2"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="couplepaper">
- <cd:sequence>
- <cd:string value="dvoustrannypapir"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="chem" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="chem"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fraction" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="zlomek"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="periods" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="tecky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="items">
- <cd:sequence>
- <cd:string value="polozky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavpolozky" n="1"/>
- </cd:assignments>
- <cd:content n="2" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupitems" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavpolozky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="naokraji"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- </cd:parameter>
- <cd:parameter name="symbol">
- <cd:constant type="1"/>
- <cd:constant type="2"/>
- <cd:constant type="..."/>
- <cd:constant type="n"/>
- <cd:constant type="a"/>
- <cd:constant type="..."/>
- <cd:constant type="cd:text"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- <cd:constant type="neznamy"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="quotation" type="environment" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="citace"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="nastred" default="yes"/>
- <cd:constant type="vpravo"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="quotation" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="citace"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="quote" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="citovat"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupquote" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavcitaci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="cd:text"/>
- <cd:constant type="marginalie"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineparagraphs" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="definujodstavce"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="linka">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="prizpusobive"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vnitrni">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="tolerance">
- <cd:constant type="velmistriktni"/>
- <cd:constant type="striktni"/>
- <cd:constant type="tolerantni"/>
- <cd:constant type="velmitolerantni"/>
- <cd:constant type="natahnout"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="paragraph" generated="yes">
- <cd:sequence>
- <cd:variable value="odstavec"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="paragraph" type="environment" generated="yes">
- <cd:sequence>
- <cd:variable value="odstavec"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupparagraphs" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavodstavce"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:number"/>
- <cd:constant type="kazdy"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="tolerance">
- <cd:constant type="velmistriktni"/>
- <cd:constant type="striktni"/>
- <cd:constant type="tolerantni"/>
- <cd:constant type="velmitolerantni"/>
- <cd:constant type="natahnout"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vnitrni">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="prikaz">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="linka">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptab" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavtab"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="vzor">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stylhlavicky">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="tab">
- <cd:sequence>
- <cd:string value="tab"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:nothing n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="document" type="environment">
- <cd:sequence>
- <cd:string value="document"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="labels">
- <cd:sequence>
- <cd:string value="popisky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definetabulate" file="core-tbl.tex">
- <cd:sequence>
- <cd:string value="definujtabelaci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="tabulate" type="environment" generated="yes">
- <cd:sequence>
- <cd:variable value="tabelator"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavexterniobrazy" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptabulate" file="core-tbl.tex">
- <cd:sequence>
- <cd:string value="nastavtabelaci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="jednotka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="odsazovani">
- <cd:resolve name="indenting"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vnitrni">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="EQ">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="barvalinky">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="tloustkalinky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="prazdny"/>
- <cd:constant type="mrizka"/>
- <cd:constant type="podlehloubky"/>
- <cd:constant type="cd:dimension"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- <cd:parameter name="linka">
- <cd:constant type="normalni"/>
- <cd:constant type="radek"/>
- </cd:parameter>
- <cd:parameter name="split">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuptables" file="core-tab.tex">
- <cd:sequence>
- <cd:string value="nastavtabulky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="vzdalenost">
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- <cd:parameter name="HL">
- <cd:constant type="cd:number"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="VL">
- <cd:constant type="cd:number"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:number"/>
- <cd:constant type="strut"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:number"/>
- <cd:constant type="strut"/>
- </cd:parameter>
- <cd:parameter name="tloustkalinky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barvalinky">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="prikazy">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="pozadi">
- <cd:constant type="rastr"/>
- <cd:constant type="barevne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="rastrpozadi">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="barvapozadi">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="table" type="environment">
- <cd:sequence>
- <cd:string value="table"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="tables" type="environment">
- <cd:sequence>
- <cd:string value="tables"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definetabletemplate" file="core-tab.tex">
- <cd:sequence>
- <cd:string value="definujsablonutabulky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="3" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="4" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useexternalfiles" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="uzijexternisoubory"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- <cd:parameter name="soubor">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useexternalfile" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="uzijexternisoubor"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- <cd:assignments n="4" list="yes">
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useexternalfigure" file="core-fig.tex">
- <cd:sequence>
- <cd:string value="uzijexterniobraz"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- <cd:keywords n="3" optional="yes">
- <cd:constant type="cd:name"/> <!-- parent -->
- </cd:keywords>
- <cd:assignments n="4" optional="yes" list="yes">
- <cd:inherit name="nastavexterniobrazy" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="externalfigure" file="core-fig.tex">
- <cd:sequence>
- <cd:string value="externiobraz"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavexterniobrazy" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupexternalfigures" file="core-fig.tex">
- <cd:sequence>
- <cd:string value="nastavexterniobrazy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1">
- <cd:parameter name="meritko">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ymeritko">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ymeritko">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="faktor">
- <cd:constant type="max"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- </cd:parameter>
- <cd:parameter name="sfaktor">
- <cd:constant type="cd:number"/>
- <cd:constant type="max"/>
- <cd:constant type="siroky"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="vfaktor">
- <cd:constant type="cd:number"/>
- <cd:constant type="max"/>
- <cd:constant type="siroky"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="ramecek">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="prednastaveni">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="obrazovka">
- <cd:constant type="cd:file"/>
- </cd:parameter>
- <cd:parameter name="nahled">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="opakovat">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="objekt">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="typ">
- <cd:constant type="eps"/>
- <cd:constant type="mps"/>
- <cd:constant type="pdf"/>
- <cd:constant type="tif"/>
- <cd:constant type="png"/>
- <cd:constant type="jpg"/>
- <cd:constant type="mov"/>
- <cd:constant type="cd:tex"/>
- </cd:parameter>
- <cd:parameter name="metoda">
- <cd:constant type="eps"/>
- <cd:constant type="mps"/>
- <cd:constant type="pdf"/>
- <cd:constant type="tif"/>
- <cd:constant type="png"/>
- <cd:constant type="jpg"/>
- <cd:constant type="mov"/>
- <cd:constant type="cd:tex"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="ramecek"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="test"/>
- </cd:parameter>
- <cd:parameter name="ramecky">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="ymax">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="xmax">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="adresar">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="lokalne"/>
- <cd:constant type="globalne"/>
- <cd:constant type="implicitni"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="maxsirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="maxvyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="konverze">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="prefix">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showexternalfigures" file="core-fig.tex">
- <cd:sequence>
- <cd:string value="ukazexterniobrazy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:parameter name="alternativa">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="c"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useexternalsoundtrack" file="core-fig.tex">
- <cd:sequence>
- <cd:string value="uzijexternizvuk"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="name" file="syst-gen.tex">
- <cd:sequence>
- <cd:string value="name"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="legend" type="environment">
- <cd:sequence>
- <cd:string value="legend"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="dve"/>
- </cd:keywords>
- <cd:tex n="2" command="leg"/>
- <cd:nothing n="3"/>
- <cd:nothing n="4" separator="backslash"/>
- <cd:nothing n="5" separator="backslash"/>
- <cd:tex n="6" separator="backslash" command="leg"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fact" type="environment">
- <cd:sequence>
- <cd:string value="fakt"/>
- </cd:sequence>
- <cd:arguments>
- <cd:tex n="1" command="fact"/>
- <cd:nothing n="2"/>
- <cd:nothing n="3" separator="backslash"/>
- <cd:nothing n="4" separator="backslash"/>
- <cd:tex n="5" separator="backslash" command="fact"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="rotate" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="otocit"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavotoceni" n="1"/>
- </cd:assignments>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuprotate" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavotoceni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="rotace">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="normalni"/>
- <cd:constant type="vysoko"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="siroky"/>
- <cd:constant type="podlehloubky"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="mirror" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="zrcadlit"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="scale" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="meritko"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:parameter name="sx">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="sy">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- </cd:assignments>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupcombinations" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="nastavspojeni"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vrsek"/>
- <cd:constant type="nastred"/>
- <cd:constant type="spodek"/>
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="combination" type="environment">
- <cd:sequence>
- <cd:string value="combination"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:matrix"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placesidebyside" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="umistivedlesebe"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placeontopofeachother" file="core-mis.tex">
- <cd:sequence>
- <cd:string value="umistinadsebe"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="overlay" type="environment">
- <cd:sequence>
- <cd:string value="overlay"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="overview" type="environment">
- <cd:sequence>
- <cd:string value="overview"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupinteractionscreen" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavinterakcniobrazovku"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="max"/>
- </cd:parameter>
- <cd:parameter name="zpetnamezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="svrchnimezera">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="horoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsethlavicky">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="max"/>
- <cd:constant type="prizpusobive"/>
- <cd:constant type="dvoustranny"/>
- <cd:constant type="zalozka"/>
- </cd:parameter>
- <cd:parameter name="prodleva">
- <cd:constant type="cd:number"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="screen" file="core-int.tex">
- <cd:sequence>
- <cd:string value="obrazovka"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setuppagetransitions" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavprechodstrany"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="reset"/>
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupinteraction" file="core-nav.tex">
- <cd:sequence>
- <cd:string value="nastavinterakci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="menu">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- <cd:parameter name="stranka">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="klik">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="split">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="obrazovka">
- <cd:constant type="novy"/>
- </cd:parameter>
- <cd:parameter name="otevriakci">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="zavriakci">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="akceotevrenistranky">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="akcezavrenistranky">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="pocitat">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="strut">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="kontrastnibarva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="sadasymbolu">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="titul">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="podtitulek">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="autor">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="datum">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="keyword">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <!-- maybe this will move elsewhere -->
- <cd:parameter name="fieldlayer">
- <cd:constant type="auto"/>
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupinteractionmenu" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavinterakcnimenu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vlevo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="vpravo">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="stredni">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- <cd:constant type="zadny"/>
- <cd:constant type="lokalne"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="kontrastnibarva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="prekryv"/>
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="stejnastranka">
- <cd:constant type="ano"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="ne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="neznamyodkaz">
- <cd:constant type="ano"/>
- <cd:constant type="prazdne"/>
- <cd:constant type="ne"/>
- <cd:constant type="zadny"/>
- </cd:parameter>
- <cd:parameter name="levyoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pravyoffset">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsetvrsku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="offsetspodku">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="position">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/> <!-- maybe not all parameters from framed -->
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineinteractionmenu" variant="1" file="core-int.tex">
- <cd:sequence>
- <cd:string value="definujinterakcnimenu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive" list="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavinterakcnimenu" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineinteractionmenu" variant="2" file="core-int.tex">
- <cd:sequence>
- <cd:string value="definujinterakcnimenu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="nastavinterakcnimenu" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="interactionmenu" type="environment">
- <cd:sequence>
- <cd:string value="interaktivnimenu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="disableinteractionmenu" file="core-int.tex">
- <cd:sequence>
- <cd:string value="zablokujinterakcnimenu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="vrsek"/>
- <cd:constant type="spodek"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:reference n="2" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useexternaldocument" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="uzijexternidokument"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="soubor"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="useURL" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="uzijURL"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="soubor"/>
- </cd:keywords>
- <cd:keywords n="4">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="coupledocument" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="propojenydokument"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="soubor"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="from" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="zref"/>
- </cd:sequence>
- <cd:arguments>
- <cd:reference n="1" interactive="exclusive"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="interactionbar">
- <cd:sequence>
- <cd:string value="interakcnilista"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:inherit name="nastavinterakcnilistu" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="interactionbuttons" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="interakcnitlacitka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" optional="yes" list="yes">
- <cd:inherit name="nastavinterakcnilistu" n="1"/>
- </cd:assignments>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupinteractionbar" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavinterakcnilistu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="alternativa">
- <cd:constant type="a"/>
- <cd:constant type="b"/>
- <cd:constant type="c"/>
- <cd:constant type="d"/>
- <cd:constant type="e"/>
- <cd:constant type="f"/>
- <cd:constant type="g"/>
- </cd:parameter>
- <cd:parameter name="symbol">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="vyska"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="vyska"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="hloubka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="krok">
- <cd:constant type="cd:number"/>
- <cd:constant type="male"/>
- <cd:constant type="stredni"/>
- <cd:constant type="velke"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="synchronize" file="core-int.tex">
- <cd:sequence>
- <cd:string value="synchronizovat"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="synchronization" type="environment">
- <cd:sequence>
- <cd:string value="synchronization"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupsynchronizationbar" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavsynchronizacnilistu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="alternativa">
- <cd:constant type="stranka"/>
- <cd:constant type="lokalne"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- <cd:constant type="vyska"/>
- <cd:constant type="prizpusobive"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="synchronizationbar" file="core-int.tex">
- <cd:sequence>
- <cd:string value="synchronizacnilista"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="alternativa">
- <cd:constant type="stranka"/>
- <cd:constant type="lokalne"/>
- </cd:parameter>
- <cd:inherit name="nastavsynchronizacnilistu" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupsynchronization" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavsynchronizaci"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineprofile" file="core-int.tex">
- <cd:sequence>
- <cd:string value="definujprofil"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupprofiles" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavprofily"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="volba">
- <cd:constant type="test"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="profile" type="environment">
- <cd:sequence>
- <cd:string value="profile"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="followprofile" file="core-int.tex">
- <cd:sequence>
- <cd:string value="dodrzujprofil"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="exclusive"/>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placebookmarks" file="core-int.tex">
- <cd:sequence>
- <cd:string value="umistizalozky"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- <cd:constant type="vse"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="bookmark" file="core-int.tex">
- <cd:sequence>
- <cd:string value="zalozka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="version" type="environment">
- <cd:sequence>
- <cd:string value="verze"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive" list="yes">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupversions" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavverze"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="cislo">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="markversion" file="core-int.tex">
- <cd:sequence>
- <cd:string value="oznacverzi"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="selectversion" file="core-int.tex">
- <cd:sequence>
- <cd:string value="vyberverzi"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="defineversion" file="core-int.tex">
- <cd:sequence>
- <cd:string value="definujverzi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:number"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="followversion" file="core-int.tex">
- <cd:sequence>
- <cd:string value="dodrzujverzi"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="exclusive"/>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="followprofileversion" file="core-int.tex">
- <cd:sequence>
- <cd:string value="dodrzujverziprofilu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="exclusive"/>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="defineprogram" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="definujprogram"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupprograms" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="nastavprogramy"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" list="yes">
- <cd:parameter name="adresar">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="program" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="program"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="figure" type="environment">
- <cd:sequence>
- <cd:string value="figure"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" interactive="exclusive">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:file"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:parameter name="faktor">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ramecek">
- <cd:constant type="zap"/>
- <cd:constant type="vyp"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <!-- referring*figure skipped -->
-
- <!-- marking*figure skipped -->
-
- <!-- remark skipped -->
-
- <cd:command name="goto" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="jdina"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="exclusive"/>
- <cd:content n="2" interactive="exclusive"/>
- <cd:reference n="3" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="gotobox" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="jdinabox"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1" interactive="exclusive"/>
- <cd:reference n="2" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="button" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="tlacitko"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" interactive="exclusive" optional="yes" list="yes">
- <cd:inherit name="nastavtlacitka" n="1"/>
- </cd:assignments>
- <cd:content n="2"/>
- <cd:reference n="3" list="yes"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupbuttons" file="core-ref.tex">
- <cd:sequence>
- <cd:string value="nastavtlacitka"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <!-- menubutton skipped -->
-
- <cd:command name="setupcomment" file="core-int.tex">
- <cd:sequence>
- <cd:string value="nastavkomentar"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="titul">
- <cd:constant type="cd:text"/>
- </cd:parameter>
- <cd:parameter name="mezera">
- <cd:constant type="ano"/>
- <cd:constant type="ne"/>
- </cd:parameter>
- <cd:parameter name="symbol">
- <cd:constant type="normalni"/>
- <cd:constant type="Novy"/>
- <cd:constant type="Bublinka"/>
- <cd:constant type="Pridavek"/>
- <cd:constant type="Napoveda"/>
- <cd:constant type="Odstavec"/>
- <cd:constant type="Klavesa"/>
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="max"/>
- <cd:constant type="buffer"/>
- </cd:parameter>
- <cd:parameter name="marginalie">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="comment" type="environment">
- <cd:sequence>
- <cd:string value="komentar"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavkomentar" n="1"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="comment">
- <cd:sequence>
- <cd:string value="komentar"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="2" optional="yes" list="yes">
- <cd:inherit name="nastavkomentar" n="1"/>
- </cd:assignments>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definefield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="definujpole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1"> <!-- name -->
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2"> <!-- type -->
- <cd:constant type="text"/>
- <cd:constant type="radek"/> <!-- equal to text -->
- <cd:constant type="push"/>
- <cd:constant type="check"/>
- <cd:constant type="radio"/>
- <cd:constant type="combo"/>
- <cd:constant type="choice"/> <!-- equal to combo -->
- <cd:constant type="popup"/> <!-- equal to combo -->
- </cd:keywords>
- <cd:keywords n="3"> <!-- group -->
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="4" list="yes"> <!-- optional for text? -->
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="5" optional="yes"> <!-- default -->
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definesubfield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="definujpodpole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="3" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="copyfield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="kopirujpole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="clonefield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="klonujpole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="4" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="field" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="pole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fitfield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="prizpusobivepole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fillinfield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="vyplnovepole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="tooltip" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="bublinkovanapoveda"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes">
- <cd:constant type="vlevo"/>
- <cd:constant type="vpravo"/>
- <cd:constant type="nastred"/>
- </cd:keywords>
- <cd:content n="2"/>
- <cd:content n="3"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="showfields" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="ukazpole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="logfields" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="zaznamovepole"/>
- </cd:sequence>
- </cd:command>
-
- <cd:command name="setupfield" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="nastavpole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="popisek"/>
- <cd:constant type="horizontalne"/>
- <cd:constant type="vertikalne"/>
- <cd:constant type="ramecek"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:inherit name="nastavvsechnapole" n="2"/>
- </cd:assignments>
- <cd:assignments n="4" list="yes"> </cd:assignments>
- <cd:assignments n="5" list="yes"> </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupfields" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="nastavvsechnapole"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1" list="yes"> <!-- TODO: if it's reset, only a single argument, no list -->
- <cd:constant type="reset"/>
- <cd:constant type="popisek"/>
- <cd:constant type="horizontalne"/>
- <cd:constant type="vertikalne"/>
- <cd:constant type="ramecek"/>
- </cd:keywords>
- <cd:assignments n="2" list="yes">
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="pred">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="po">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="barva">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="pismeno">
- <cd:resolve name="style"/>
- </cd:parameter>
- <cd:parameter name="zarovnani">
- <cd:resolve name="align"/>
- </cd:parameter>
- <cd:parameter name="volba">
- <cd:constant type="pouzeprocteni"/>
- <cd:constant type="pozadovane"/>
- <cd:constant type="chranene"/>
- <cd:constant type="tridene"/>
- <cd:constant type="nedostupne"/>
- <cd:constant type="skryte"/>
- <cd:constant type="tisknutelne"/>
- </cd:parameter>
- <cd:parameter name="klikuvnitr">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="klikvne">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="oblastuvnitr">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="oblastvne">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="klavesapo">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="formatovat">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="validovat">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="pocitat">
- <cd:constant type="cd:reference"/>
- </cd:parameter>
- <cd:parameter name="offsetpole">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="barvarameckupole">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="barvapozadipole">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:inherit name="nastavoramovani" n="2"/>
- </cd:assignments>
- <cd:assignments n="3" list="yes">
- <cd:inherit name="nastavvsechnapole" n="2"/>
- </cd:assignments>
- <cd:assignments n="4" list="yes">
- <cd:inherit name="nastavvsechnapole" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupforms" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="setupforms"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="metoda">
- <cd:constant type="HTML"/>
- <cd:constant type="FDF"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definefieldstack" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="definujzasobnikpoli"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" list="yes">
- <cd:inherit name="nastavvsechnapole" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="fieldstack" file="core-fld.tex">
- <cd:sequence>
- <cd:string value="zasobnikpoli"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes" list="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" optional="yes" list="yes">
- <cd:inherit name="nastavvsechnapole" n="2"/>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="clip" file="core-trf.tex">
- <cd:sequence>
- <cd:string value="orez"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" optional="yes" list="yes">
- <cd:inherit name="nastavorez" n="1"/>
- </cd:assignments>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupclipping" file="core-trf.tex">
- <cd:sequence>
- <cd:string value="nastavorez"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="status">
- <cd:constant type="start"/>
- <cd:constant type="stop"/>
- </cd:parameter>
- <cd:parameter name="n">
- <cd:constant type="cd:number" default="1"/>
- </cd:parameter>
- <cd:parameter name="nx">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="ny">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="x">
- <cd:constant type="cd:number" default="1"/>
- </cd:parameter>
- <cd:parameter name="y">
- <cd:constant type="cd:number" default="1"/>
- </cd:parameter>
- <cd:parameter name="sx">
- <cd:constant type="cd:number" default="1"/>
- </cd:parameter>
- <cd:parameter name="sy">
- <cd:constant type="cd:number" default="1"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="hoffset">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="voffset">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="offset">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="levyoffset">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="pravyoffset">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="offsetvrsku">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="offsetspodku">
- <cd:constant type="cd:dimension" default="0pt"/>
- </cd:parameter>
- <cd:parameter name="mp">
- <cd:constant type="cd:name" default=""/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="placelegend">
- <cd:sequence>
- <cd:string value="umistilegendu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:content n="1"/>
- <cd:content n="2"/>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setuplegend">
- <cd:sequence>
- <cd:string value="nastavlegendu"/>
- </cd:sequence>
- <cd:arguments>
- <cd:assignments n="1" list="yes">
- <cd:parameter name="n">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="vzdalenost">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="mezi">
- <cd:constant type="cd:command"/>
- </cd:parameter>
- <cd:parameter name="sirka">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="vyska">
- <cd:constant type="cd:dimension"/>
- </cd:parameter>
- <cd:parameter name="misto">
- <cd:constant type="vpravo"/>
- <cd:constant type="spodek"/>
- </cd:parameter>
- <cd:parameter name="zakladnifont">
- <cd:resolve name="bodyfont"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="setupstrut" file="core-spa.tex">
- <cd:sequence>
- <cd:string value="setupstrut"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="ano" default="yes"/>
- <cd:constant type="ne"/>
- <cd:constant type="kap"/>
- <cd:constant type="cd:text"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usetypescriptfile" file="type-ini.tex">
- <cd:sequence>
- <cd:string value="usetypescriptfile"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="usetypescript" file="type-ini.tex">
- <cd:sequence>
- <cd:string value="usetypescript"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definetypeface" file="type-ini.tex">
- <cd:sequence>
- <cd:string value="definetypeface"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="2">
- <cd:constant type="rm"/>
- <cd:constant type="ss"/>
- <cd:constant type="tt"/>
- <cd:constant type="mm"/>
- <cd:constant type="hw"/>
- <cd:constant type="cg"/>
- </cd:keywords>
- <cd:keywords n="3">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="4">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:keywords n="5" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="6" optional="yes">
- <cd:parameter name="features">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="rscale">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="encoding">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="text">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
- <cd:command name="definefontfeature" file="type-ini.tex">
- <cd:sequence>
- <cd:string value="definefontfeature"/>
- </cd:sequence>
- <cd:arguments>
- <cd:keywords n="1">
- <cd:constant type="cd:text"/>
- </cd:keywords>
- <cd:keywords n="2" optional="yes">
- <cd:constant type="cd:name"/>
- </cd:keywords>
- <cd:assignments n="3" optional="no">
- <cd:parameter name="compose">
- <cd:constant type="ne" default="yes"/>
- <cd:constant type="ano"/>
- </cd:parameter>
- <cd:parameter name="mode">
- <cd:constant type="node"/>
- <cd:constant type="base" default="yes"/>
- </cd:parameter>
- <cd:parameter name="tlig">
- <cd:constant type="ne" default="yes"/>
- <cd:constant type="ano"/>
- </cd:parameter>
- <cd:parameter name="trep">
- <cd:constant type="ne" default="yes"/>
- <cd:constant type="ano"/>
- </cd:parameter>
- <cd:parameter name="script">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="language">
- <cd:constant type="cd:name"/>
- </cd:parameter>
- <cd:parameter name="..tag.."> <!-- can't use &gt; here, \showsetup gives an error -->
- <cd:constant type="ne" default="yes"/>
- <cd:constant type="ano"/>
- </cd:parameter>
- </cd:assignments>
- </cd:arguments>
- </cd:command>
-
-
-</cd:interface>
diff --git a/tex/context/interface/cont-de.xml b/tex/context/interface/cont-de.xml
index 6f3927090..73c823766 100644
--- a/tex/context/interface/cont-de.xml
+++ b/tex/context/interface/cont-de.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="stellefliesstextein" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="stellefliesstextein" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="stellefliesstextein" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="stellezeilenabstandein"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="passend"/>
</cd:parameter>
+ <cd:parameter name="methode">
+ <cd:constant type="normal"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="tolerant"/>
<cd:constant type="sehrtolerant"/>
<cd:constant type="strecken"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="defineschriftsynonym"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-en.xml b/tex/context/interface/cont-en.xml
index d4c9283d9..1484bab20 100644
--- a/tex/context/interface/cont-en.xml
+++ b/tex/context/interface/cont-en.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="setupbodyfont" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="setupbodyfont" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="setupbodyfont" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="setupinterlinespace"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="fit"/>
</cd:parameter>
+ <cd:parameter name="method">
+ <cd:constant type="normal"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="tolerant"/>
<cd:constant type="verytolerant"/>
<cd:constant type="stretch"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="definefontsynonym"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-fr.xml b/tex/context/interface/cont-fr.xml
index 291574bff..0f07b22ee 100644
--- a/tex/context/interface/cont-fr.xml
+++ b/tex/context/interface/cont-fr.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="reglepolicecorps" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="reglepolicecorps" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="reglepolicecorps" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="regleespacementinterligne"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="adapte"/>
</cd:parameter>
+ <cd:parameter name="methode">
+ <cd:constant type="normal"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="tolerant"/>
<cd:constant type="trestolerant"/>
<cd:constant type="etire"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="definitsynonymepolice"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-it.xml b/tex/context/interface/cont-it.xml
index c59511b61..34b703d58 100644
--- a/tex/context/interface/cont-it.xml
+++ b/tex/context/interface/cont-it.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="impostafontdeltesto" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="impostafontdeltesto" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="impostafontdeltesto" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="impostainterlinea"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="adatta"/>
</cd:parameter>
+ <cd:parameter name="metodo">
+ <cd:constant type="normale"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="tollerante"/>
<cd:constant type="moltotollerante"/>
<cd:constant type="dilata"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="definiscisinonimofont"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-nl.xml b/tex/context/interface/cont-nl.xml
index 9daaadbd5..127c076f5 100644
--- a/tex/context/interface/cont-nl.xml
+++ b/tex/context/interface/cont-nl.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="stelkorpsin" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="stelkorpsin" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="stelkorpsin" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="stelinterliniein"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="passend"/>
</cd:parameter>
+ <cd:parameter name="methode">
+ <cd:constant type="normaal"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="soepel"/>
<cd:constant type="zeersoepel"/>
<cd:constant type="rek"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="gebruiktypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="gebruiktypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="definieerfontsynoniem"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-pe.xml b/tex/context/interface/cont-pe.xml
index 4dcda95ed..a91800797 100644
--- a/tex/context/interface/cont-pe.xml
+++ b/tex/context/interface/cont-pe.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="بارگذاری‌قلم‌متن" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="بارگذاری‌قلم‌متن" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="بارگذاری‌قلم‌متن" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="بارگذاری‌فاصله‌بین‌خط"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="بیشترین"/>
<cd:constant type="پرکردن"/>
</cd:parameter>
+ <cd:parameter name="روش">
+ <cd:constant type="نرمال"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="بردبار"/>
<cd:constant type="خیلی‌بردبار"/>
<cd:constant type="بکش"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="استفاده‌پرونده‌دستخط‌تایپ"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="استفاده‌دستخط‌تایپ"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="تعریف‌مترادف‌قلم"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/cont-ro.xml b/tex/context/interface/cont-ro.xml
index 67d25d6f7..442fb18e1 100644
--- a/tex/context/interface/cont-ro.xml
+++ b/tex/context/interface/cont-ro.xml
@@ -441,12 +441,12 @@
</cd:sequence>
<cd:arguments>
<cd:keywords n="1">
- <cd:constant type="cd:name"/>
+ <cd:constant type="cd:name"/>
</cd:keywords>
<cd:keywords n="2">
<cd:inherit name="seteazafonttext" n="2"/>
</cd:keywords>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:inherit name="seteazafonttext" n="3"/>
</cd:keywords>
</cd:arguments>
@@ -463,7 +463,7 @@
<cd:keywords n="2">
<cd:inherit name="seteazafonttext" n="2"/>
</cd:keywords>
- <cd:keywords n="3">
+ <cd:keywords n="3">
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -4096,7 +4096,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
+ <cd:command name="setupinterlinespace2" variant="2" file="core-spa.tex">
<!-- attached a 2 to make this definition usable with \showsetup -->
<cd:sequence>
<cd:string value="seteazaspatiuinterliniar"/>
@@ -5647,6 +5647,10 @@
<cd:constant type="max"/>
<cd:constant type="ajustat"/>
</cd:parameter>
+ <cd:parameter name="metoda">
+ <cd:constant type="normal"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7083,6 +7087,8 @@
<cd:constant type="tolerant"/>
<cd:constant type="foartetolerant"/>
<cd:constant type="dilatat"/>
+ <cd:constant type="lefttoright"/>
+ <cd:constant type="righttoleft"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -9986,7 +9992,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescriptfile" file="type-ini.tex">
+ <cd:command name="usetypescriptfile" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescriptfile"/>
</cd:sequence>
@@ -9997,7 +10003,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="usetypescript" file="type-ini.tex">
+ <cd:command name="usetypescript" file="type-ini.tex">
<cd:sequence>
<cd:string value="usetypescript"/>
</cd:sequence>
@@ -10014,7 +10020,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definetypeface" file="type-ini.tex">
+ <cd:command name="definetypeface" file="type-ini.tex">
<cd:sequence>
<cd:string value="definetypeface"/>
</cd:sequence>
@@ -10056,7 +10062,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontfeature" file="type-ini.tex">
+ <cd:command name="definefontfeature" file="type-ini.tex">
<cd:sequence>
<cd:string value="definefontfeature"/>
</cd:sequence>
@@ -10098,7 +10104,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefonthandling" file="hand-ini.mkii">
+ <cd:command name="definefonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="definefonthandling"/>
</cd:sequence>
@@ -10138,7 +10144,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfonthandling" file="hand-ini.mkii">
+ <cd:command name="setupfonthandling" file="hand-ini.mkii">
<cd:sequence>
<cd:string value="setupfonthandling"/>
</cd:sequence>
@@ -10152,7 +10158,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="definefontsynonym" file="font-ini.tex">
+ <cd:command name="definefontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="definestesinonimfont"/>
</cd:sequence>
@@ -10180,7 +10186,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupfontsynonym" file="font-ini.tex">
+ <cd:command name="setupfontsynonym" file="font-ini.tex">
<cd:sequence>
<cd:string value="setupfontsynonym"/>
</cd:sequence>
@@ -10199,7 +10205,7 @@
<cd:string value="mapfontsize"/>
</cd:sequence>
<cd:arguments>
- <cd:keywords n="1">
+ <cd:keywords n="1">
<cd:constant type="cd:dimension"/>
</cd:keywords>
<cd:keywords n="2">
diff --git a/tex/context/interface/keys-cs.xml b/tex/context/interface/keys-cs.xml
index 25200070e..bbbfdaf48 100644
--- a/tex/context/interface/keys-cs.xml
+++ b/tex/context/interface/keys-cs.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='po'/>
<cd:variable name='all' value='vse'/>
<cd:variable name='always' value='vzdy'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='dodatky'/>
<cd:variable name='appendix' value='dodatek'/>
<cd:variable name='april' value='duben'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='lefthanging'/>
<cd:variable name='leftmargin' value='levyokraj'/>
<cd:variable name='leftpage' value='levastranka'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legenda'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='radek'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normalni'/>
<cd:variable name='nospacing' value='nospacing'/>
<cd:variable name='not' value='ne'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='nothanging'/>
<cd:variable name='nothyphenated' value='nothyphenated'/>
<cd:variable name='november' value='listopad'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='righthanging'/>
<cd:variable name='rightmargin' value='pravyokraj'/>
<cd:variable name='rightpage' value='pravastranka'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='antikva'/>
<cd:variable name='romannumerals' value='rimskecislice'/>
<cd:variable name='rotate' value='otoc'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='podpodpodpodtema'/>
<cd:variable name='subsubsubsubsubsection' value='podpodpodpodpodsekce'/>
<cd:variable name='subsubsubsubsubsubject' value='podpodpodpodpodtema'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='podpodpodpodpodpodsekce'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='podpodpodpodpodpodtema'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='podpodpodpodpodpodpodsekce'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='podpodpodpodpodpodpodtema'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='podpodpodpodpodpodpodpodsekce'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='podpodpodpodpodpodpodpodtema'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='podpodpodpodpodpodpodpodpodsekce'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='podpodpodpodpodpodpodpodpodtema'/>
<cd:variable name='sunday' value='nedele'/>
<cd:variable name='support' value='podpora'/>
<cd:variable name='sym' value='sym'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='zakladnifont'/>
<cd:constant name='bookmark' value='zalozka'/>
<cd:constant name='bottom' value='spodek'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='vzdalenostspodku'/>
<cd:constant name='bottomframe' value='ramecekdole'/>
<cd:constant name='bottomoffset' value='offsetspodku'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='component'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='compress'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='pokracovat'/>
<cd:constant name='contrastcolor' value='kontrastnibarva'/>
<cd:constant name='controls' value='controls'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='fieldlayer'/>
<cd:constant name='fieldoffset' value='offsetpole'/>
<cd:constant name='file' value='soubor'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='zaostreni'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusout'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='vyska'/>
<cd:constant name='hfactor' value='vfaktor'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
<cd:constant name='horoffset' value='horoffset'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='cislo'/>
<cd:constant name='numbercolor' value='barvacisla'/>
<cd:constant name='numbercommand' value='ciselnyprikaz'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='numberdistance'/>
<cd:constant name='numbering' value='cislovani'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='oddelovaccisla'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='stylcisla'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='hranicestranky'/>
<cd:constant name='pagecolor' value='barvastranky'/>
<cd:constant name='pagecommand' value='strankovyprikaz'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='cislostranky'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='pagestate'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='stylstranky'/>
<cd:constant name='palet' value='paleta'/>
<cd:constant name='paper' value='papir'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='predelmista'/>
<cd:constant name='position' value='position'/>
<cd:constant name='prefix' value='prefix'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='prednastaveni'/>
<cd:constant name='preview' value='nahled'/>
<cd:constant name='previous' value='predchozi'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='redukce'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='odkaz'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='odkazujici'/>
<cd:constant name='regionin' value='oblastuvnitr'/>
<cd:constant name='regionout' value='oblastvne'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='tloustkalinky'/>
<cd:constant name='samepage' value='stejnastranka'/>
<cd:constant name='sample' value='vzor'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='meritko'/>
<cd:constant name='scope' value='rozsah'/>
<cd:constant name='screen' value='rastr'/>
<cd:constant name='section' value='oddil'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='cislooddilu'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='oddelovac'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='setups'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language cs -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='zacatek'/>
<cd:element name='complete' value='uplny'/>
<cd:element name='coupled' value='propojene'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='settextcontent'/>
<cd:command name='settextvariable' value='settextvariable'/>
<cd:command name='setupalign' value='nastavzarovnani'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='nastavusporadani'/>
<cd:command name='setupbackground' value='nastavpozadi'/>
<cd:command name='setupbackgrounds' value='nastavpozadi'/>
diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml
index 44945cd74..2c28adcb6 100644
--- a/tex/context/interface/keys-de.xml
+++ b/tex/context/interface/keys-de.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='nach'/>
<cd:variable name='all' value='alles'/>
<cd:variable name='always' value='immer'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='anhaenge'/>
<cd:variable name='appendix' value='anhang'/>
<cd:variable name='april' value='April'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='lefthanging'/>
<cd:variable name='leftmargin' value='linkerrand'/>
<cd:variable name='leftpage' value='linkerseite'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legende'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='zeile'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='nospacing'/>
<cd:variable name='not' value='nicht'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='nothanging'/>
<cd:variable name='nothyphenated' value='nothyphenated'/>
<cd:variable name='november' value='November'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='righthanging'/>
<cd:variable name='rightmargin' value='rechterrand'/>
<cd:variable name='rightpage' value='rechterseite'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='antiqua'/>
<cd:variable name='romannumerals' value='roemischezahlen'/>
<cd:variable name='rotate' value='drehe'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='unterunterunterunterthema'/>
<cd:variable name='subsubsubsubsubsection' value='unterunterunterunterunterabsatz'/>
<cd:variable name='subsubsubsubsubsubject' value='unterunterunterunterunterthema'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='unterunterunterunterunterunterabsatz'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='unterunterunterunterunterunterthema'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='unterunterunterunterunterunterunterabsatz'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='unterunterunterunterunterunterunterthema'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='unterunterunterunterunterunterunterunterabsatz'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='unterunterunterunterunterunterunterunterthema'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='unterunterunterunterunterunterunterunterunterabsatz'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='unterunterunterunterunterunterunterunterunterthema'/>
<cd:variable name='sunday' value='sonntag'/>
<cd:variable name='support' value='support'/>
<cd:variable name='sym' value='sym'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='fliesstext'/>
<cd:constant name='bookmark' value='bookmark'/>
<cd:constant name='bottom' value='unten'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='abstandunten'/>
<cd:constant name='bottomframe' value='untenrahmen'/>
<cd:constant name='bottomoffset' value='untenoffset'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='component'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='compress'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='fortsetzen'/>
<cd:constant name='contrastcolor' value='kontrastfarbe'/>
<cd:constant name='controls' value='controls'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='fieldlayer'/>
<cd:constant name='fieldoffset' value='feldoffset'/>
<cd:constant name='file' value='datei'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='focus'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusout'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='hoehe'/>
<cd:constant name='hfactor' value='hfaktor'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
<cd:constant name='horoffset' value='rumpfabstand'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='nummer'/>
<cd:constant name='numbercolor' value='nummernfarbe'/>
<cd:constant name='numbercommand' value='nummerbefehl'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='numberdistance'/>
<cd:constant name='numbering' value='nummerierung'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='nummernseperator'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='nummernstil'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='seitenbegrenzung'/>
<cd:constant name='pagecolor' value='seitenfarbe'/>
<cd:constant name='pagecommand' value='seitenbefehl'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='seitennummer'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='pagestate'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='seitenstil'/>
<cd:constant name='palet' value='palette'/>
<cd:constant name='paper' value='papier'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='setzetrenner'/>
<cd:constant name='position' value='position'/>
<cd:constant name='prefix' value='prefix'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='voreinstellung'/>
<cd:constant name='preview' value='vorschau'/>
<cd:constant name='previous' value='vorige'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='reduktion'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='referenz'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='referieren'/>
<cd:constant name='regionin' value='regionin'/>
<cd:constant name='regionout' value='regionaus'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='liniendicke'/>
<cd:constant name='samepage' value='selbeseite'/>
<cd:constant name='sample' value='muster'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='format'/>
<cd:constant name='scope' value='bereich'/>
<cd:constant name='screen' value='raster'/>
<cd:constant name='section' value='abschnitt'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='abschnittsnummer'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='seperator'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='setups'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language de -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='anfang'/>
<cd:element name='complete' value='vollende'/>
<cd:element name='coupled' value='verknuepft'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='settext'/>
<cd:command name='settextvariable' value='settextvariable'/>
<cd:command name='setupalign' value='stelleausrichtungein'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='stelleanordnenein'/>
<cd:command name='setupbackground' value='stellehintergrundein'/>
<cd:command name='setupbackgrounds' value='stellehintergruendeein'/>
diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml
index 4bc9311e7..db9181646 100644
--- a/tex/context/interface/keys-en.xml
+++ b/tex/context/interface/keys-en.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='after'/>
<cd:variable name='all' value='all'/>
<cd:variable name='always' value='always'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='appendices'/>
<cd:variable name='appendix' value='appendix'/>
<cd:variable name='april' value='April'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='lefthanging'/>
<cd:variable name='leftmargin' value='leftmargin'/>
<cd:variable name='leftpage' value='leftpage'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legend'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='line'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='nospacing'/>
<cd:variable name='not' value='not'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='nothanging'/>
<cd:variable name='nothyphenated' value='nothyphenated'/>
<cd:variable name='november' value='November'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='righthanging'/>
<cd:variable name='rightmargin' value='rightmargin'/>
<cd:variable name='rightpage' value='rightpage'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='roman'/>
<cd:variable name='romannumerals' value='romannumerals'/>
<cd:variable name='rotate' value='rotate'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='subsubsubsubsubject'/>
<cd:variable name='subsubsubsubsubsection' value='subsubsubsubsubsection'/>
<cd:variable name='subsubsubsubsubsubject' value='subsubsubsubsubsubject'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='subsubsubsubsubsubsection'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='subsubsubsubsubsubsubject'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsection'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubject'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsubsection'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubsubject'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsubsubsection'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubsubsubject'/>
<cd:variable name='sunday' value='sunday'/>
<cd:variable name='support' value='support'/>
<cd:variable name='sym' value='sym'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='bodyfont'/>
<cd:constant name='bookmark' value='bookmark'/>
<cd:constant name='bottom' value='bottom'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='bottomdistance'/>
<cd:constant name='bottomframe' value='bottomframe'/>
<cd:constant name='bottomoffset' value='bottomoffset'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='component'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='compress'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='continue'/>
<cd:constant name='contrastcolor' value='contrastcolor'/>
<cd:constant name='controls' value='controls'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='fieldlayer'/>
<cd:constant name='fieldoffset' value='fieldoffset'/>
<cd:constant name='file' value='file'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='focus'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusout'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='height'/>
<cd:constant name='hfactor' value='hfactor'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
<cd:constant name='horoffset' value='horoffset'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='number'/>
<cd:constant name='numbercolor' value='numbercolor'/>
<cd:constant name='numbercommand' value='numbercommand'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='numberdistance'/>
<cd:constant name='numbering' value='numbering'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='numberseparator'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='numberstyle'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='pageboundaries'/>
<cd:constant name='pagecolor' value='pagecolor'/>
<cd:constant name='pagecommand' value='pagecommand'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='pagenumber'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='pagestate'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='pagestyle'/>
<cd:constant name='palet' value='palet'/>
<cd:constant name='paper' value='paper'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='placestopper'/>
<cd:constant name='position' value='position'/>
<cd:constant name='prefix' value='prefix'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='preset'/>
<cd:constant name='preview' value='preview'/>
<cd:constant name='previous' value='previous'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='reduction'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='reference'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='referencing'/>
<cd:constant name='regionin' value='regionin'/>
<cd:constant name='regionout' value='regionout'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='rulethickness'/>
<cd:constant name='samepage' value='samepage'/>
<cd:constant name='sample' value='sample'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='scale'/>
<cd:constant name='scope' value='scope'/>
<cd:constant name='screen' value='screen'/>
<cd:constant name='section' value='section'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='sectionnumber'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='separator'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='setups'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language en -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='begin'/>
<cd:element name='complete' value='complete'/>
<cd:element name='coupled' value='coupled'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='settextcontent'/>
<cd:command name='settextvariable' value='settextvariable'/>
<cd:command name='setupalign' value='setupalign'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='setuparranging'/>
<cd:command name='setupbackground' value='setupbackground'/>
<cd:command name='setupbackgrounds' value='setupbackgrounds'/>
diff --git a/tex/context/interface/keys-fr.xml b/tex/context/interface/keys-fr.xml
index 8815a94bf..faf884c38 100644
--- a/tex/context/interface/keys-fr.xml
+++ b/tex/context/interface/keys-fr.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='apres'/>
<cd:variable name='all' value='tout'/>
<cd:variable name='always' value='toujours'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='annexes'/>
<cd:variable name='appendix' value='annexe'/>
<cd:variable name='april' value='avril'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='lefthanging'/>
<cd:variable name='leftmargin' value='margegauche'/>
<cd:variable name='leftpage' value='pagegauche'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legende'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='ligne'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='sansespacement'/>
<cd:variable name='not' value='pas'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='nonsuspendu'/>
<cd:variable name='nothyphenated' value='nothyphenated'/>
<cd:variable name='november' value='novembre'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='righthanging'/>
<cd:variable name='rightmargin' value='margedroite'/>
<cd:variable name='rightpage' value='pagedroite'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='roman'/>
<cd:variable name='romannumerals' value='chiffresromains'/>
<cd:variable name='rotate' value='oriente'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='soussoussoussoussujet'/>
<cd:variable name='subsubsubsubsubsection' value='soussoussoussoussoussection'/>
<cd:variable name='subsubsubsubsubsubject' value='soussoussoussoussoussujet'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='soussoussoussoussoussoussection'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='soussoussoussoussoussoussujet'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='soussoussoussoussoussoussoussection'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='soussoussoussoussoussoussoussujet'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='soussoussoussoussoussoussoussoussection'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='soussoussoussoussoussoussoussoussujet'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='soussoussoussoussoussoussoussoussoussection'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='soussoussoussoussoussoussoussoussoussujet'/>
<cd:variable name='sunday' value='dimanche'/>
<cd:variable name='support' value='support'/>
<cd:variable name='sym' value='sym'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='policecorps'/>
<cd:constant name='bookmark' value='marquepage'/>
<cd:constant name='bottom' value='inf'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='distanceinf'/>
<cd:constant name='bottomframe' value='cadreinf'/>
<cd:constant name='bottomoffset' value='decalageinf'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='composant'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='compress'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='continue'/>
<cd:constant name='contrastcolor' value='coleurcontraste'/>
<cd:constant name='controls' value='controles'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='calquechamp'/>
<cd:constant name='fieldoffset' value='offsetchamp'/>
<cd:constant name='file' value='fichier'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='focus'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusout'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='hauteur'/>
<cd:constant name='hfactor' value='facteurhauteur'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='decalagehauteur'/>
<cd:constant name='horoffset' value='horoffset'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='numero'/>
<cd:constant name='numbercolor' value='couleurnumero'/>
<cd:constant name='numbercommand' value='commandenumero'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='numberdistance'/>
<cd:constant name='numbering' value='numerotation'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='separateurnumbero'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='stylenumero'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='limitespage'/>
<cd:constant name='pagecolor' value='couleurpage'/>
<cd:constant name='pagecommand' value='commandepage'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='numeropage'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='etatpage'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='stylepage'/>
<cd:constant name='palet' value='palette'/>
<cd:constant name='paper' value='papier'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='emplacementstopper'/>
<cd:constant name='position' value='position'/>
<cd:constant name='prefix' value='prefixe'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='prereglage'/>
<cd:constant name='preview' value='previsualisation'/>
<cd:constant name='previous' value='precedent'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='reduction'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='reference'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='referencing'/>
<cd:constant name='regionin' value='entreregion'/>
<cd:constant name='regionout' value='regionexterieure'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='epaisseurligne'/>
<cd:constant name='samepage' value='memepage'/>
<cd:constant name='sample' value='echantillon'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='echelle'/>
<cd:constant name='scope' value='scope'/>
<cd:constant name='screen' value='ecran'/>
<cd:constant name='section' value='section'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='numerosection'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='separateur'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='reglages'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language fr -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='debut'/>
<cd:element name='complete' value='complete'/>
<cd:element name='coupled' value='couple'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='settext'/>
<cd:command name='settextvariable' value='affectevariabletexte'/>
<cd:command name='setupalign' value='reglealignement'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='reglearrangement'/>
<cd:command name='setupbackground' value='reglearriereplan'/>
<cd:command name='setupbackgrounds' value='reglearriereplans'/>
diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml
index 885fddb28..69dcdfbe0 100644
--- a/tex/context/interface/keys-it.xml
+++ b/tex/context/interface/keys-it.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='dopo'/>
<cd:variable name='all' value='tutti'/>
<cd:variable name='always' value='sempre'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='appendici'/>
<cd:variable name='appendix' value='appendice'/>
<cd:variable name='april' value='aprile'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='lefthanging'/>
<cd:variable name='leftmargin' value='marginesinistro'/>
<cd:variable name='leftpage' value='paginasinistra'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legenda'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='riga'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normale'/>
<cd:variable name='nospacing' value='nospacing'/>
<cd:variable name='not' value='non'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='nonsospeso'/>
<cd:variable name='nothyphenated' value='nonsillabato'/>
<cd:variable name='november' value='novembre'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='righthanging'/>
<cd:variable name='rightmargin' value='marginedestro'/>
<cd:variable name='rightpage' value='paginadestra'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='roman'/>
<cd:variable name='romannumerals' value='numeriromani'/>
<cd:variable name='rotate' value='ruota'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='sottosottosottosottoargomento'/>
<cd:variable name='subsubsubsubsubsection' value='sottosottosottosottosottocapoverso'/>
<cd:variable name='subsubsubsubsubsubject' value='sottosottosottosottosottoargomento'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='sottosottosottosottosottosottocapoverso'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='sottosottosottosottosottosottoargomento'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='sottosottosottosottosottosottosottocapoverso'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='sottosottosottosottosottosottosottoargomento'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='sottosottosottosottosottosottosottosottocapoverso'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='sottosottosottosottosottosottosottosottoargomento'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='sottosottosottosottosottosottosottosottosottocapoverso'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='sottosottosottosottosottosottosottosottosottoargomento'/>
<cd:variable name='sunday' value='domenica'/>
<cd:variable name='support' value='supporto'/>
<cd:variable name='sym' value='sim'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='fonttesto'/>
<cd:constant name='bookmark' value='segnalibro'/>
<cd:constant name='bottom' value='fondo'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='distanzafondo'/>
<cd:constant name='bottomframe' value='cornicefondo'/>
<cd:constant name='bottomoffset' value='offsetfondo'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='component'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='compress'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='continua'/>
<cd:constant name='contrastcolor' value='colorecontrasto'/>
<cd:constant name='controls' value='controlli'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='fieldlayer'/>
<cd:constant name='fieldoffset' value='offsetcampo'/>
<cd:constant name='file' value='file'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='focus'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusout'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='altezza'/>
<cd:constant name='hfactor' value='hfactor'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
<cd:constant name='horoffset' value='horoffset'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='numero'/>
<cd:constant name='numbercolor' value='colorenumero'/>
<cd:constant name='numbercommand' value='comandonumero'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='numberdistance'/>
<cd:constant name='numbering' value='numerazione'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='separatorenumero'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='stilenumero'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='limitipagina'/>
<cd:constant name='pagecolor' value='colorepagina'/>
<cd:constant name='pagecommand' value='comandopagina'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='numeropagina'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='statopagina'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='stilepagina'/>
<cd:constant name='palet' value='tavolozza'/>
<cd:constant name='paper' value='carta'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='mettistopper'/>
<cd:constant name='position' value='posizione'/>
<cd:constant name='prefix' value='prefisso'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='preimpostato'/>
<cd:constant name='preview' value='anteprima'/>
<cd:constant name='previous' value='precedente'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='riduzione'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='riferimento'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='referencing'/>
<cd:constant name='regionin' value='entraregione'/>
<cd:constant name='regionout' value='esciregione'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='spessorelinea'/>
<cd:constant name='samepage' value='stessapagina'/>
<cd:constant name='sample' value='campione'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='scala'/>
<cd:constant name='scope' value='scope'/>
<cd:constant name='screen' value='schermo'/>
<cd:constant name='section' value='sezione'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='numerosezione'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='separatore'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='setups'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language it -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='inizio'/>
<cd:element name='complete' value='completo'/>
<cd:element name='coupled' value='accoppiato'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='settext'/>
<cd:command name='settextvariable' value='setvariabiletesto'/>
<cd:command name='setupalign' value='impostaallineamento'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='impostaparranging'/>
<cd:command name='setupbackground' value='impostasfondo'/>
<cd:command name='setupbackgrounds' value='impostasfondi'/>
diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml
index deee34508..32e60c364 100644
--- a/tex/context/interface/keys-nl.xml
+++ b/tex/context/interface/keys-nl.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='na'/>
<cd:variable name='all' value='alles'/>
<cd:variable name='always' value='altijd'/>
+ <cd:variable name='answerarea' value='antwoordgebied'/>
<cd:variable name='appendices' value='bijlagen'/>
<cd:variable name='appendix' value='bijlage'/>
<cd:variable name='april' value='april'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='linkshangend'/>
<cd:variable name='leftmargin' value='linkermarge'/>
<cd:variable name='leftpage' value='linkerpagina'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legenda'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='regel'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normaal'/>
<cd:variable name='nospacing' value='geenspatiering'/>
<cd:variable name='not' value='niet'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='niethangend'/>
<cd:variable name='nothyphenated' value='nietafgebroken'/>
<cd:variable name='november' value='november'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='rechtshangend'/>
<cd:variable name='rightmargin' value='rechtermarge'/>
<cd:variable name='rightpage' value='rechterpagina'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='romaan'/>
<cd:variable name='romannumerals' value='romeins'/>
<cd:variable name='rotate' value='roteer'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='subsubsubsubonderwerp'/>
<cd:variable name='subsubsubsubsubsection' value='subsubsubsubsubparagraaf'/>
<cd:variable name='subsubsubsubsubsubject' value='subsubsubsubsubonderwerp'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='subsubsubsubsubsubparagraaf'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='subsubsubsubsubsubonderwerp'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubparagraaf'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubonderwerp'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsubparagraaf'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubonderwerp'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsubsubparagraaf'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubsubonderwerp'/>
<cd:variable name='sunday' value='zondag'/>
<cd:variable name='support' value='support'/>
<cd:variable name='sym' value='sym'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='korps'/>
<cd:constant name='bookmark' value='bookmark'/>
<cd:constant name='bottom' value='onder'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='onderafstand'/>
<cd:constant name='bottomframe' value='onderkader'/>
<cd:constant name='bottomoffset' value='onderoffset'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='component'/>
<cd:constant name='compoundhyphen' value='koppelteken'/>
<cd:constant name='compress' value='comprimeren'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='doorgaan'/>
<cd:constant name='contrastcolor' value='contrastkleur'/>
<cd:constant name='controls' value='sturing'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='veldlaag'/>
<cd:constant name='fieldoffset' value='veldoffset'/>
<cd:constant name='file' value='file'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='focus'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusuit'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='hoogte'/>
<cd:constant name='hfactor' value='hfactor'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
<cd:constant name='horoffset' value='rugoffset'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='nummer'/>
<cd:constant name='numbercolor' value='nummerkleur'/>
<cd:constant name='numbercommand' value='nummercommando'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='nummerafstand'/>
<cd:constant name='numbering' value='nummeren'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='nummerscheider'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='nummerletter'/>
<cd:constant name='numberwidth' value='nummerbreedte'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='paginaovergangen'/>
<cd:constant name='pagecolor' value='paginakleur'/>
<cd:constant name='pagecommand' value='paginacommando'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='paginanummer'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='paginastatus'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='paginaletter'/>
<cd:constant name='palet' value='palet'/>
<cd:constant name='paper' value='papier'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='plaatsafsluiter'/>
<cd:constant name='position' value='positie'/>
<cd:constant name='prefix' value='prefix'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='preset'/>
<cd:constant name='preview' value='preview'/>
<cd:constant name='previous' value='vorige'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='reductie'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='verwijzing'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='refereren'/>
<cd:constant name='regionin' value='gebiedin'/>
<cd:constant name='regionout' value='gebieduit'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='lijndikte'/>
<cd:constant name='samepage' value='zelfdepagina'/>
<cd:constant name='sample' value='monster'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='schaal'/>
<cd:constant name='scope' value='scope'/>
<cd:constant name='screen' value='raster'/>
<cd:constant name='section' value='sectie'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='sectienummer'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='scheider'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='setups'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language nl -->
<cd:elements>
+ <cd:element name='answerlines' value='antwoordregels'/>
+ <cd:element name='answerspace' value='antwoordruimte'/>
<cd:element name='begin' value='beginvan'/>
<cd:element name='complete' value='volledige'/>
<cd:element name='coupled' value='gekoppelde'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='steltekstinhoudin'/>
<cd:command name='settextvariable' value='kentekstvariabeletoe'/>
<cd:command name='setupalign' value='steluitlijnenin'/>
+ <cd:command name='setupanswerarea' value='stelantwoordgebiedin'/>
<cd:command name='setuparranging' value='stelarrangerenin'/>
<cd:command name='setupbackground' value='stelachtergrondin'/>
<cd:command name='setupbackgrounds' value='stelachtergrondenin'/>
diff --git a/tex/context/interface/keys-pe.xml b/tex/context/interface/keys-pe.xml
index 0ac2bc83c..34acdeecc 100644
--- a/tex/context/interface/keys-pe.xml
+++ b/tex/context/interface/keys-pe.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='بعداز'/>
<cd:variable name='all' value='همه'/>
<cd:variable name='always' value='همواره'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='پیوستها'/>
<cd:variable name='appendix' value='پیوست'/>
<cd:variable name='april' value='آوریل'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='آویزان‌چپ'/>
<cd:variable name='leftmargin' value='حاشیه‌چپ'/>
<cd:variable name='leftpage' value='صفحه‌چپ'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='راهنما'/>
<cd:variable name='lesshyphenation' value='شکست‌کلمات‌کمتر'/>
<cd:variable name='line' value='خط'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='نرمال'/>
<cd:variable name='nospacing' value='بدون‌فضاگذاری'/>
<cd:variable name='not' value='بدون'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='بدون‌آویزان‌کردن'/>
<cd:variable name='nothyphenated' value='بدون‌شکست'/>
<cd:variable name='november' value='نوامبر'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='آویزان‌کردن‌راست'/>
<cd:variable name='rightmargin' value='حاشیه‌راست'/>
<cd:variable name='rightpage' value='صفحه‌راست'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='رومن'/>
<cd:variable name='romannumerals' value='شماره‌لاتین'/>
<cd:variable name='rotate' value='دوران'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='زیرزیرزیرزیرموضوع'/>
<cd:variable name='subsubsubsubsubsection' value='زیرزیرزیرزیرزیربخش'/>
<cd:variable name='subsubsubsubsubsubject' value='زیرزیرزیرزیرزیرموضوع'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='زیرزیرزیرزیرزیرزیربخش'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='زیرزیرزیرزیرزیرزیرموضوع'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='زیرزیرزیرزیرزیرزیرزیربخش'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='زیرزیرزیرزیرزیرزیرزیرموضوع'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='زیرزیرزیرزیرزیرزیرزیرزیربخش'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='زیرزیرزیرزیرزیرزیرزیرزیرموضوع'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='زیرزیرزیرزیرزیرزیرزیرزیرزیربخش'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='زیرزیرزیرزیرزیرزیرزیرزیرزیرموضوع'/>
<cd:variable name='sunday' value='یک‌شنبه'/>
<cd:variable name='support' value='حمایت'/>
<cd:variable name='sym' value='نم'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='قلم‌بدنه'/>
<cd:constant name='bookmark' value='چوبخط'/>
<cd:constant name='bottom' value='پایین'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='فاصله‌پایین'/>
<cd:constant name='bottomframe' value='قالب‌پایین'/>
<cd:constant name='bottomoffset' value='آفست‌پایین'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='مولفه'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='فشردن'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='ادامه'/>
<cd:constant name='contrastcolor' value='contrastcolor'/>
<cd:constant name='controls' value='کنترلها'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='لایه‌میدان'/>
<cd:constant name='fieldoffset' value='آفست‌میدان'/>
<cd:constant name='file' value='پرونده'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='تمرکز'/>
<cd:constant name='focusin' value='تمرکزدرون'/>
<cd:constant name='focusout' value='تمرکزبیرون'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='ارتفاع'/>
<cd:constant name='hfactor' value='عامل‌ارتفاع'/>
<cd:constant name='hfil' value='پرکردن‌ارتفاع'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='آفست‌ا'/>
<cd:constant name='horoffset' value='آفست‌افق'/>
<cd:constant name='hyphen' value='شکستن'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='شماره'/>
<cd:constant name='numbercolor' value='رنگ‌شماره'/>
<cd:constant name='numbercommand' value='فرمان‌شماره'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='فاصله‌شماره'/>
<cd:constant name='numbering' value='شماره‌گذاری'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='جداکننده‌شماره'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='سبک‌شماره'/>
<cd:constant name='numberwidth' value='عرض‌شماره'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='مرزهای‌صفحه'/>
<cd:constant name='pagecolor' value='رنگ‌صفحه'/>
<cd:constant name='pagecommand' value='فرمان‌صفحه'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='شماره‌صفحه'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='وضعیت‌صفحه'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='سبک‌صفحه'/>
<cd:constant name='palet' value='لوح'/>
<cd:constant name='paper' value='برگ'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='بگذارایست'/>
<cd:constant name='position' value='موقعیت'/>
<cd:constant name='prefix' value='پیشوند'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='preset'/>
<cd:constant name='preview' value='پیش‌دید'/>
<cd:constant name='previous' value='قبلی'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='کاهش'/>
<cd:constant name='ref' value='رج'/>
<cd:constant name='reference' value='مرجع'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='مراجعه'/>
<cd:constant name='regionin' value='ناحیه‌درون'/>
<cd:constant name='regionout' value='ناحیه‌بیرون'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='ضخامت‌خط'/>
<cd:constant name='samepage' value='همان‌صفحه'/>
<cd:constant name='sample' value='نمونه'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='مقیاس'/>
<cd:constant name='scope' value='طرح'/>
<cd:constant name='screen' value='پرده'/>
<cd:constant name='section' value='بخش'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='شماره‌بخش'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='جداکننده'/>
<cd:constant name='set' value='قراربده'/>
<cd:constant name='setups' value='بارگذاریها'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language pe -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='عنصرها'/>
<cd:element name='complete' value='کامل'/>
<cd:element name='coupled' value='مزدوج'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='تعیین‌محتوای‌متن'/>
<cd:command name='settextvariable' value='تعیین‌متغیر‌متن'/>
<cd:command name='setupalign' value='بارگذاری‌تنظیم'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='بارگذاری‌ترتیب'/>
<cd:command name='setupbackground' value='بارگذاری‌پس‌زمینه'/>
<cd:command name='setupbackgrounds' value='بارگذاری‌پس‌زمینه‌ها'/>
diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml
index a93a06957..77ed534ab 100644
--- a/tex/context/interface/keys-ro.xml
+++ b/tex/context/interface/keys-ro.xml
@@ -71,6 +71,7 @@
<cd:variable name='after' value='dupa'/>
<cd:variable name='all' value='tot'/>
<cd:variable name='always' value='totdeauna'/>
+ <cd:variable name='answerarea' value='answerarea'/>
<cd:variable name='appendices' value='apendixuri'/>
<cd:variable name='appendix' value='apendix'/>
<cd:variable name='april' value='aprilie'/>
@@ -240,6 +241,7 @@
<cd:variable name='lefthanging' value='lefthanging'/>
<cd:variable name='leftmargin' value='marginestanga'/>
<cd:variable name='leftpage' value='paginastanga'/>
+ <cd:variable name='lefttoright' value='lefttoright'/>
<cd:variable name='legend' value='legenda'/>
<cd:variable name='lesshyphenation' value='lesshyphenation'/>
<cd:variable name='line' value='linie'/>
@@ -298,6 +300,7 @@
<cd:variable name='normal' value='normal'/>
<cd:variable name='nospacing' value='nospacing'/>
<cd:variable name='not' value='nu'/>
+ <cd:variable name='note' value='note'/>
<cd:variable name='nothanging' value='nothanging'/>
<cd:variable name='nothyphenated' value='nedespsilabe'/>
<cd:variable name='november' value='noiembrie'/>
@@ -362,6 +365,7 @@
<cd:variable name='righthanging' value='righthanging'/>
<cd:variable name='rightmargin' value='marginedreapta'/>
<cd:variable name='rightpage' value='paginadreapta'/>
+ <cd:variable name='righttoleft' value='righttoleft'/>
<cd:variable name='roman' value='roman'/>
<cd:variable name='romannumerals' value='numereromane'/>
<cd:variable name='rotate' value='rotit'/>
@@ -431,6 +435,14 @@
<cd:variable name='subsubsubsubsubject' value='subsubsubsubsubiect'/>
<cd:variable name='subsubsubsubsubsection' value='subsubsubsubsubsectiune'/>
<cd:variable name='subsubsubsubsubsubject' value='subsubsubsubsubsubiect'/>
+ <cd:variable name='subsubsubsubsubsubsection' value='subsubsubsubsubsubsectiune'/>
+ <cd:variable name='subsubsubsubsubsubsubject' value='subsubsubsubsubsubsubiect'/>
+ <cd:variable name='subsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsectiune'/>
+ <cd:variable name='subsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubiect'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsubsectiune'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubsubiect'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsection' value='subsubsubsubsubsubsubsubsubsectiune'/>
+ <cd:variable name='subsubsubsubsubsubsubsubsubsubject' value='subsubsubsubsubsubsubsubsubsubiect'/>
<cd:variable name='sunday' value='duminica'/>
<cd:variable name='support' value='suport'/>
<cd:variable name='sym' value='sym'/>
@@ -526,6 +538,8 @@
<cd:constant name='bodyfont' value='fonttext'/>
<cd:constant name='bookmark' value='semncarte'/>
<cd:constant name='bottom' value='jos'/>
+ <cd:constant name='bottomafter' value='bottomafter'/>
+ <cd:constant name='bottombefore' value='bottombefore'/>
<cd:constant name='bottomdistance' value='distantajos'/>
<cd:constant name='bottomframe' value='framejos'/>
<cd:constant name='bottomoffset' value='offsetjos'/>
@@ -553,6 +567,7 @@
<cd:constant name='component' value='component'/>
<cd:constant name='compoundhyphen' value='compoundhyphen'/>
<cd:constant name='compress' value='compress'/>
+ <cd:constant name='connector' value='connector'/>
<cd:constant name='continue' value='continua'/>
<cd:constant name='contrastcolor' value='culoarecontrast'/>
<cd:constant name='controls' value='controale'/>
@@ -599,6 +614,7 @@
<cd:constant name='fieldlayer' value='fieldlayer'/>
<cd:constant name='fieldoffset' value='offsetcamp'/>
<cd:constant name='file' value='fisier'/>
+ <cd:constant name='filtercommand' value='filtercommand'/>
<cd:constant name='focus' value='focus'/>
<cd:constant name='focusin' value='focusin'/>
<cd:constant name='focusout' value='focusout'/>
@@ -632,6 +648,7 @@
<cd:constant name='height' value='inaltime'/>
<cd:constant name='hfactor' value='hfactor'/>
<cd:constant name='hfil' value='hfil'/>
+ <cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
<cd:constant name='horoffset' value='offsetoriz'/>
<cd:constant name='hyphen' value='hyphen'/>
@@ -720,9 +737,17 @@
<cd:constant name='number' value='numar'/>
<cd:constant name='numbercolor' value='culoarenumar'/>
<cd:constant name='numbercommand' value='comandanumar'/>
+ <cd:constant name='numberconversion' value='numberconversion'/>
+ <cd:constant name='numberconversionset' value='numberconversionset'/>
<cd:constant name='numberdistance' value='numberdistance'/>
<cd:constant name='numbering' value='numerotare'/>
+ <cd:constant name='numberorder' value='numberorder'/>
+ <cd:constant name='numberprefix' value='numberprefix'/>
+ <cd:constant name='numbersegments' value='numbersegments'/>
<cd:constant name='numberseparator' value='separatornumar'/>
+ <cd:constant name='numberseparatorset' value='numberseparatorset'/>
+ <cd:constant name='numberset' value='numberset'/>
+ <cd:constant name='numberstopper' value='numberstopper'/>
<cd:constant name='numberstyle' value='stilnumar'/>
<cd:constant name='numberwidth' value='numberwidth'/>
<cd:constant name='nx' value='nx'/>
@@ -742,8 +767,22 @@
<cd:constant name='pageboundaries' value='marginipagina'/>
<cd:constant name='pagecolor' value='culoarepagina'/>
<cd:constant name='pagecommand' value='comandapagina'/>
+ <cd:constant name='pageconversion' value='pageconversion'/>
+ <cd:constant name='pageconversionset' value='pageconversionset'/>
<cd:constant name='pagenumber' value='numarpagina'/>
+ <cd:constant name='pageprefix' value='pageprefix'/>
+ <cd:constant name='pageprefixconnector' value='pageprefixconnector'/>
+ <cd:constant name='pageprefixconversion' value='pageprefixconversion'/>
+ <cd:constant name='pageprefixconversionset' value='pageprefixconversionset'/>
+ <cd:constant name='pageprefixsegments' value='pageprefixsegments'/>
+ <cd:constant name='pageprefixseparatorset' value='pageprefixseparatorset'/>
+ <cd:constant name='pageprefixset' value='pageprefixset'/>
+ <cd:constant name='pageprefixstopper' value='pageprefixstopper'/>
+ <cd:constant name='pagesegments' value='pagesegments'/>
+ <cd:constant name='pageseparatorset' value='pageseparatorset'/>
+ <cd:constant name='pageset' value='pageset'/>
<cd:constant name='pagestate' value='pagestate'/>
+ <cd:constant name='pagestopper' value='pagestopper'/>
<cd:constant name='pagestyle' value='stilpagina'/>
<cd:constant name='palet' value='paleta'/>
<cd:constant name='paper' value='hartie'/>
@@ -753,6 +792,13 @@
<cd:constant name='placestopper' value='punestopper'/>
<cd:constant name='position' value='pozitie'/>
<cd:constant name='prefix' value='prefix'/>
+ <cd:constant name='prefixconnector' value='prefixconnector'/>
+ <cd:constant name='prefixconversion' value='prefixconversion'/>
+ <cd:constant name='prefixconversionset' value='prefixconversionset'/>
+ <cd:constant name='prefixsegments' value='prefixsegments'/>
+ <cd:constant name='prefixseparatorset' value='prefixseparatorset'/>
+ <cd:constant name='prefixset' value='prefixset'/>
+ <cd:constant name='prefixstopper' value='prefixstopper'/>
<cd:constant name='preset' value='preset'/>
<cd:constant name='preview' value='previzualizare'/>
<cd:constant name='previous' value='precendent'/>
@@ -763,6 +809,7 @@
<cd:constant name='reduction' value='reducere'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='reference' value='referinta'/>
+ <cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='referinta'/>
<cd:constant name='regionin' value='regiuneintrare'/>
<cd:constant name='regionout' value='regiuneiesire'/>
@@ -794,11 +841,18 @@
<cd:constant name='rulethickness' value='grosimerigla'/>
<cd:constant name='samepage' value='aceeasipagina'/>
<cd:constant name='sample' value='exemplu'/>
+ <cd:constant name='saveinlist' value='saveinlist'/>
<cd:constant name='scale' value='scala'/>
<cd:constant name='scope' value='scop'/>
<cd:constant name='screen' value='ecran'/>
<cd:constant name='section' value='sectiune'/>
+ <cd:constant name='sectionconversion' value='sectionconversion'/>
+ <cd:constant name='sectionconversionset' value='sectionconversionset'/>
<cd:constant name='sectionnumber' value='numarsectiune'/>
+ <cd:constant name='sectionsegments' value='sectionsegments'/>
+ <cd:constant name='sectionseparatorset' value='sectionseparatorset'/>
+ <cd:constant name='sectionset' value='sectionset'/>
+ <cd:constant name='sectionstopper' value='sectionstopper'/>
<cd:constant name='separator' value='separator'/>
<cd:constant name='set' value='set'/>
<cd:constant name='setups' value='setups'/>
@@ -901,6 +955,8 @@
<!-- definitions for interface elements for language ro -->
<cd:elements>
+ <cd:element name='answerlines' value='answerlines'/>
+ <cd:element name='answerspace' value='answerspace'/>
<cd:element name='begin' value='inceput'/>
<cd:element name='complete' value='complet'/>
<cd:element name='coupled' value='cuplat'/>
@@ -1289,6 +1345,7 @@
<cd:command name='settextcontent' value='settextcontent'/>
<cd:command name='settextvariable' value='setvariabilatext'/>
<cd:command name='setupalign' value='seteazaalinierea'/>
+ <cd:command name='setupanswerarea' value='setupanswerarea'/>
<cd:command name='setuparranging' value='seteazaaranjareapag'/>
<cd:command name='setupbackground' value='seteazafundal'/>
<cd:command name='setupbackgrounds' value='seteazafundaluri'/>
diff --git a/tex/context/interface/t-bib.xml b/tex/context/interface/t-bib.xml
index 93cf9f285..faa728fa6 100644
--- a/tex/context/interface/t-bib.xml
+++ b/tex/context/interface/t-bib.xml
@@ -199,6 +199,9 @@
<cd:parameter name="otherstext">
<cd:constant type="cd:text"/>
</cd:parameter>
+ <cd:parameter name="namesep">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
<cd:parameter name="pubsep">
<cd:constant type="cd:text"/>
</cd:parameter>
diff --git a/tex/context/patterns/lang-de.hyp b/tex/context/patterns/lang-de.hyp
index 23691aeb2..15485d1e1 100644
--- a/tex/context/patterns/lang-de.hyp
+++ b/tex/context/patterns/lang-de.hyp
@@ -2,7 +2,7 @@
% for comment and copyright, see ./lang-de.rme
-% used:
+% used:
\hyphenation{
-} \ No newline at end of file
+}
diff --git a/tex/context/patterns/lang-de.pat b/tex/context/patterns/lang-de.pat
index 2058b3e72..836fa7080 100644
--- a/tex/context/patterns/lang-de.pat
+++ b/tex/context/patterns/lang-de.pat
@@ -7,50 +7,53 @@
\patterns{
.a6
.ab3b
+.aben2
.ab5l
.abo4
.ab3ol
.ab1or
+.ab5r
.ab3s
.ag4r
.ag2u
-.aid4
+.aid2
.ai2s
.al3br
.al2e
.al3l4en
.al3ph
+.al4tei
.alt3s
.amt4
-.amts3
+.amt6s3
.an3alg
.an3d
.ang4
.an1gl
-.ang6s2
+.angs4
.angst3
.an3k
.an3s
.an4si.
.ans2p
.an3z
-.ao5
.ap3s2
.ar3k2a
.ar4m3ac
-.ar2s
+.ar4s
.ar4t3ei
-.ata1
+.as1t
+.as4ta
.au3d
.au2f5
.au4s1
.ausch3
-.au6stes
-.ax2
-.ä6
-.äm3
+.aus5s
+.ä4
+.äm5
.ät2s
.b6
+.bau1s
.be3erb
.bei6ge.
.be3ra
@@ -62,18 +65,21 @@
.bo4s3k
.c4
.ch2
+.con3
.d4
.dab6
.da2r1
.dar3in
-.dar2m1
+.dar2m
.da4te.
.da4tes
.de4al
.de1i
.de3o2
.de3r4en
+.de1s
.de3sk
+.de3s2t
.deut2
.dien4
.do3b
@@ -90,121 +96,114 @@
.ei5ner
.ei5nes
.ei4sp
-.ei4s1t
+.ei4st
.ei2tr
.el2bi
+.elb3s
+.els7t
.em3m2
.en1
.en4d3er
.en4d3r
-.enn4
+.enn2
.en4t3
-.epi1
.er4dei
.er4der
.er1e
.er1i
-.ers2
.er8stein
+.es3k
.es3p
-.es2t
-.est4e
-.et2s
+.es1ta
+.es5t4e
+.es1th
+.es3tr
+.et4s
.eu3
.eug4
.ext4
.f6
-.fa2c
-.fe6sta
+.fi3est
.fi4le.
.fi4len
+.fin6s
.fi2s
.frau3
-.fs2
-.fus2
+.fs4
.fu2sc
-.g6
-.gang5
-.ga2t
+.g4
+.ga4t
.gd2
.gel2d
.ge5nar
.ge3ne
.ge3r2a
.ge3r2e
-.ge5s4
-.ge7sta
+.ge3s4a
.ge1u
-.grif8fes
-.gros2
+.gros4
.gs2
-.gus2
-.guss3
+.gus4s3
.gu4ter
.h4
.ha3bi
.haft5s
-.hal4s
-.hal3te
+.hal5te
.haup4
-.hau2t1
+.hau4t1
.he2
+.he3cke
.he3ri
.he6r5inn
.he5xe
+.his1
.ho4met
.i6
.ia4
-.il3
-.illu5
.im2a
.in3
.ink4
.inu3
-.is4a
+.is2a
+.is3tr
.jor5
-.k4
+.k6
.ka2b5l
.ka2i
.kamp2
-.ka4t3io
-.ken6num
-.ker5s
+.ka6t3io
.ki4e
.klan4
.ks2
.kü1b
.l4
.la3b
-.lat5s
.le4a
-.lea7se
.le5ni
+.lib6
.lo4g3in
.lo3ver
-.lu4str
.m4
.ma3d
.ma3ge
.ma3le
-.ma4str
+.ma4st
.me3l4a
.me3ne
.men8schw
.ment2
-.mi2sc
+.mi2s
.mi4t
.n4
-.näs1c
+.näs3c
+.ne6s
.nich2
.ni4e
-.ni3ka
.nob4
-.no2c
.no2th
-.nul2
-.nus6
+.nus4
.o6
+.oa3
.ob1a
.obe2
.oben3
@@ -212,10 +211,12 @@
.ob3l
.oper4
.or2a
-.ort4
+.ort2
+.ort6s
.orts3e
.oste2
-.ost7ende
+.os4tel
+.os8t7ende
.oste6r5e
.ost3r
.ozo4
@@ -228,35 +229,35 @@
.pf6
.ph4
.poka2
-.po4str
+.po4st
.ps2
-.pu3s
-.r4
-.reb5s2
+.r6
+.reb3s2
.re3cha
.rein4t
.reli1
.reli3e
+.res4tr
.rich5t6e
.ro3be
.ro2h
-.ro3m
-.rom4a
-.rö4s1c
+.ro3m2a
+.rö4s
+.rös3c
.rut2
.ru3th
.rü1b
+.rü6cker
.s6
-.sa2c
-.sali1
+.sali3e
.sch4
-.sen3s
+.sen5s
.ser2u
.se2t
.sha2
.si2e
.sim3p4
-.si2te
+.si4te
.ski1e
.spra2
.st6
@@ -269,15 +270,18 @@
.te2e
.tehe3
.te3no
-.te6ster
+.te4st
.th4
.ti4a
.ti2s
+.ti3ta
.to2n
.to4ni
+.ton3s
.to4pl
+.to4st
.to2w
-.tri3e4s
+.tri3es
.ts2
.tu3ra
.tu3ri
@@ -292,9 +296,11 @@
.unen2
.un3g
.uni4t
+.un3s
+.un5s4t
.ur1
.urin4
-.ur3o2m
+.ur5o2m
.uro2p
.ur3s2
.ut2a
@@ -303,16 +309,19 @@
.v2
.ve5n2e
.ve4r
+.vol2
.vo4r
.w2
.wah2
.wah4l
-.wa5re
+.wa3re
.we2
+.weg3
.welt3
.wi4e
.wor2
.wor6t5en
+.wor4tu
.wun4sc
.x4
.xe3
@@ -320,11 +329,13 @@
.ya4l
.z2
.zah2n
+.za4s
.zi2e
-.zin4st
+.zin6s5t
.zuch2
+.zwe4
6a.
-2aa
+4aa
a1ab
aa2be
aa1c
@@ -348,20 +359,22 @@ ab1ar
ab1auf
ab1ä
ab2äu
-3abd
+1abd
a1be
ab1eb
abe1e
+abei3
ab1eil
4a3bel
abe2la
+abe4na
2aber
+a3beri
ab1erk
ab1err
ab1erz
ab3esse
-ab1eß
-2abet
+4abet
2abew
1abf
3abfi
@@ -388,44 +401,42 @@ a2bo.
ab4of
3a2bon
ab3r
-ab5re
+ab5rec
1abs
2abs.
abs2a
2absar
-ab5s2i
-ab5sp
-abs4t6
+ab3s2i
+ab3sp
+abst6
2abst.
-ab7sta
-ab7ste
+ab5sta
+ab5ste
ab3sz
1abtei
2a1bu
ab3ur
2abü
-ab5üb
-3abw
+ab3üb
+1abw
2aby
1abz
2ac.
a2ce.
a1cem
-a3cet
ach1a
ach3ak
-a3chal
+a1chal
ach3au
a1che
a2ch1e2c
ach1ei
-a3chen
-a3cher.
a4cherf
ach3erw
a3ches
4achf
a1chi
+a3chis
ach5l
ach5m
ach3n
@@ -437,7 +448,6 @@ ach1ö
ach3r
ach3spr
ach3su
-a4cht
ach6t5erg
ach4th
ach2t1o
@@ -447,14 +457,14 @@ ach3ü
4achv
2ach3w
ac1in
-4ack.
+2ack.
+a1ckar
ack2en
-ackmu6
-ackmus3
+a3cki
+a4ckin
ack2se
ack3sl
-ack7sta4
-a3co
+ack5sta4
acon4n
2acu
a1ç
@@ -465,32 +475,34 @@ a4d1ac
ad1ama
a2d1an
3a4d5ap
-a3dar
+a3dar3
3a2dä
ade4al
adefi4
ad1ein
ade1ra
-4ades4
-ade3sp
+4ades
+ade3s2p
ades6s
4adi
adi3en
ad2ob
+ado3c
a2dr
ad5rah
4ad3rec
ad4res
ad5ru
-ads2
+ad1s2
ad3sä
ad3sp
+ad3st
ad3sz
-ad2t1
+ad4t1
adt3a
2ae
a1e2b
-a1ec
+a1e2c
a1e2d
a1ei
a1el.
@@ -502,7 +514,8 @@ ae2o3
a1e2p
ae1r
3a2er2o
-a3estri
+a1e2s1
+aes3t
a1e2x
a2f1a
a3fah
@@ -515,7 +528,7 @@ a2f1ec
a2fent
af1erl
af4f5l
-2afi
+2a3fi
2af3l
af3ra
af3rä
@@ -524,15 +537,19 @@ af3rö
af3ru
af3s2a
af2sp
-afs2t
+afs4t
+af3ste
+2aft
af2t1a
+af3tab
+af2tei
af4t3erl
af2t3r
-aft5re
+af4t5re
af2tur
a2f1ur
a1g
-4aga
+2aga
ag1a2b
ag3a2d
ag1ar
@@ -546,8 +563,9 @@ age2nu
age2se
age4si
age4s3p
-ages5s
+ages3s
a4g5esse
+age4s3ti
ag3gl
2agi
3a2git
@@ -569,14 +587,17 @@ a2g3re
a2g3ri
ag4ro
a3gru
-ag4s
+2ags
agsa2
-ag7sat
-ag5säu
-ag6s3p
+ag4sam
+ag4set
+ag6s5p
ag7spi
-ag5sta
-ag5ste
+ag3sta
+ag3ste
+ags4tei
+2agt
+2agu
a2g1und
2ah.
2a1ha
@@ -599,8 +620,9 @@ a2h1ö
ahr1a
ah3re
ah4rei
+ahre6s3
ah1ri
-2ah2s
+2ahs
aht3sp
a1hu
ah1w
@@ -608,12 +630,12 @@ a1hy
2ai
ai1a
aib3l
-aids1t
ai1er
aif2
ai3g4
-a1ik.
+a3ik.
ai3ku
+a2il
ai2lo
a1ind
ai3n4e
@@ -623,21 +645,20 @@ ai2nu
ai3o
ai2sa
a3isch.
-ai3s2e
-ai5se.
-ais4se
-ais5st
+ai5s2e
+ais3s
a2it
a3iv.
a3ivl
a3ivs
a1j
+aje4
2ak.
a2kad
-2a3kam
+2akam
2akar
ak4at
-aka4ta
+aka2ta
2akb
2akc
2akd
@@ -645,7 +666,7 @@ aka4ta
a2kef
a2kes
a2keu
-4a1ki
+2a1ki
2ak3l
ak4la
ak4li
@@ -657,16 +678,15 @@ ak3res
2aks
ak3sh
2akta
-akt2an
+ak3t2an
2aktb
-ak3te
-ak4tei
+ak5ten
2aktik
akt2o
ak4t5r
ak5t6ri
2aktst
-a1ku
+2a1ku
a2kun
4a3kü
1akz
@@ -706,9 +726,12 @@ al2b3l
al2boh
al2br
alb3ru
+alb3s
al2da
al2dä
al3dri
+alds2
+ald3st
al3du
2ale
3a2l1e2b
@@ -717,7 +740,6 @@ a4l1eh
a2l1ei
a4lein
a2l1el
-ale2n
al3ends
a2leng
al2ent
@@ -735,8 +757,8 @@ al3eta
al3eth
a4l1eu
3alex
+al1exi
al2gli
-1algo
2ali
ali4e3ne
ali4nal
@@ -745,19 +767,18 @@ a2l1ins
a2linv
al2k1ar
1alkoh
-alk5s2
+alk3s4
al2lan
al2l3a6r
-al4län
+al2lau
al4lec
al3lend
all5erfa
al3les
alli5er.
alli7ers.
-2allo
+2alo
a2l1ob
-2alog
alo2ga
al1ope
al1orc
@@ -768,10 +789,11 @@ al2ös
al3skl
al3sp
al4spal
+al5s6terb
al2ta
+al3tam
alt3eig
-al2te4l
-al3ter
+al4te4l
al4t3erf
al2tö
al2tri
@@ -800,28 +822,28 @@ a3mie
a3mil
2a3mir
amit2a
-ami3te
-am2mac
+ami5ti
2ammal
am2min
-am4mod
-am2mus
+ammu2
2amo
a2mö
+2amp
amp2f3a2
am3pr
-2ams
+am2s
am3sa
-am4sc
am3so
-1amt.
+am3sp
+am3str
+3amt.
am2t1a
am2t1ä
-am2tel
+am4tel
am4t3ern
am2to
am2tö
-am2t3r
+am4t3r
am2tu
4amu
am3unt
@@ -833,21 +855,21 @@ anadi3
a3nak
2anan
an3ara
-2anas
+2anas2
2anat
an1äs
1anb
-an3cht
+3anbr
+an5cht
4and.
an5de6s
-an2dex
+an2d1ex
2ando
an4d5rü
and4sas
-and6s5paß
an2d1ur
4ane
-an3ec
+an3e4c
a3nee
an3eif
an1e2k
@@ -869,9 +891,10 @@ an2glä
ang5le.
2ango
ang3ra
-1angri
4angs.
-ang6s3po
+ang5sc
+ang6s5po
+1anh
4a3ni
ani3els
ani5ers.
@@ -887,7 +910,7 @@ ank3ra
ank3rä
ank5ti
an2ky
-3anl
+1anl
2anmu
2ann
3an3na
@@ -896,18 +919,19 @@ an5n4e
an3od
an1or
a1nö
-3anr
-anrö5
+1anr
2ans.
3ansä
1ansc
-an3s2en
-an2seu
-2ansk
+an5se
+ans2en
+an6seu
an3skr
an2s1pa
1anspr
-an5s2te
+an3s2t
+an5stei
+an5str
an3s2z
2ant.
ant2a
@@ -919,7 +943,7 @@ an3th
ant2he
1anthr
2anto
-3antr
+1antr
an2tro
3antw
4a3nu
@@ -932,16 +956,15 @@ a1nü
3anzah
3anzei
anz5erst
-4anzg
an2z1i4n
3anzu
3anzü
an2zw
-ao1i4
+ao1i
a1op
a1or
-a1o2s
-aot4
+a1o4s5
+aot2
a3ot.
ao3ts
a1ö
@@ -949,13 +972,14 @@ a1p
2ap.
4apa
2ape
-3a2pé
+a2pé
ap2fa
a3pfl
a3phä
ap1hel
2a2p3l
ap2n
+apo1s
a2pot
ap3pl
2apr
@@ -963,7 +987,7 @@ ap3pl
2ar.
2a1ra
a3ra.
-ar2a1b4
+ar2ab4
ar3abt
ara3d2
a2r3al
@@ -971,6 +995,7 @@ ar1ang
ar1ans
ar3anz
a2r3app
+ara4st
a2r1au
a1rä
2arb.
@@ -985,7 +1010,6 @@ ar2b5l
2arbr
ar2bre
2arbs2
-arb5se
arb3sp
2arbt
2arbu
@@ -999,7 +1023,7 @@ a2rea
are5b
a2ref
ar1eff
-are3g
+a4re3g
ar1ehr
a2rein
a5ren
@@ -1029,7 +1053,7 @@ ar1ins
ar1int
a3riu
2ark
-ark3amt
+ark5amt
ar2k1ar
ark3aue
ar2kl
@@ -1037,16 +1061,17 @@ ark3lag
ar2kor
ark1r
ar4kri
-arks4
+arks2
ark3sa
ark3sh
ar4les
2arma
arm2ä
+arm3erk
arm2or
2arn
ar5n2e
-4a1ro
+2a1ro
ar1ob
ar3o2d
a3rodo
@@ -1061,12 +1086,15 @@ ar2r3ad
arre4n
ar2rh
arr3he
-2ars
+2ar2s
+ar3sa
ar4schl
ar4schr
-ar3se
+ar5se
ar3s2h
ars3k
+ar3sta
+ar3su
ar2tau
1artd
ar4t3erl
@@ -1074,8 +1102,7 @@ art2ho
artin2
2arto
ar2t3r
-ar3tres
-4arts
+2arts
2a1ru
ar1ums
ar3ü
@@ -1087,33 +1114,25 @@ ar2zä
1arzt
ar2z1w
2as
-as2a
-as3ab
-as1ala
+as2al
+as3ala
a4s3au
-asaus1
a2s1ä
-a2sca
+a6sca
a4schec
asch3la
a2schm
-4a3se
-a4seb
+4as2e
+a2seb
ase3le
aseli5
-a4s1e2m
-a5s2en
-as2er
-a5s2es
-a4sex
+a2s3e2m
+a3ses
4ash
a3s2hi
a5si.
-4a5sis
-asi4st
+4asis
a3skop
-as3m
-aso1
as1o2f
a3sol
a3som
@@ -1125,54 +1144,52 @@ as3pe
as2ph
as2po
as2pu
-as3s4a
-as4sä
-as3se
-as4sei
+as3s2a
+as5se
+as6sei
asse3le
as3s2i
-as3so
+as5so
as2s1p
-as4st
-as6s1to
-as5str
-4asta
-as2te
-as3tec
-a4s3tep
-as4ti
-as2to
-4as2tr
+as2st
+ass3ti
+as4sto
+as3str
+a2st
+4a4s1ta
+a5s4tas
+as2tau
+a5stä
+as3te
+as3ti
+4a3str
ast3rau
-a4st3rä
-a4st3re
-a4strol
-a2stum
-a3su
+ast3rä
+as4t3re
a2sü
3asy
+a1ß
aße2
2a1t
-4ata
+4ata1
a2t1ab
ata2be
-at2a1f
+at2af
at4a5g
at1akt
-ata1la
a3tam
at1apf
-a5tas
a2t1au2
-a5tau.
+a3tau.
at1än
at2c
-4ate
-a2teb
+4a3te
+a4teb
at1eig
a4teli
-a2tep
-a2tew
+a4tep
+ater3st
+a4tew
4atf
4atg
at2he
@@ -1182,7 +1199,6 @@ a4thr
at1int
3atm
4atmus
-a3to.
ato4man
a2t1ort
a2t1ö
@@ -1194,29 +1210,25 @@ at3re
at3rom
at2s
at3sc
-at5sche
-at5schü
-ats1e
at4set
-ats1in
ats1p
-at4st
-at5stä
3attac
att3ang
at2t1au
at2tei
at5thä
+att3rau
+at4t3rä
atts4
-at3tu
4atu
a3tub
atu4n
atu3ren
atu4rer
at3w
+4atz
atz1er
-at2z1i
+at2z1in
atzt2
atz3th
a2u
@@ -1235,7 +1247,7 @@ aue2b
aue3re
au5erein
au5erl
-aue2s
+aue4s
au3et
au2fa
auf1an
@@ -1248,13 +1260,13 @@ au2fo
2aug
au3g6e
4augeh
-2auh
2au1i
au2is
4auj
au2kl
aule2s
aul3ese
+aul4s
au3lü
4aum
au2mal
@@ -1263,7 +1275,8 @@ au2mau
au2mer
au2m1o
aum3p2
-aum5str
+aums2
+aum3st
aum3sz
4au3n2
au4nio
@@ -1275,21 +1288,18 @@ aup2
2au3r2
au2s1ah
ausan8ne.
-2au2sc
+4au2sc
au3schl
au3schw
+2ause
aus3erp
au4s3erw
au2so
au2sp
-auss4
-aus7sa
+aus3s4
3aussag
aus4se.
-aus3so
-au4st
-au6stec
-aus3tie
+au2st
aus3tri
2aut.
au3tan
@@ -1297,9 +1307,8 @@ au2tä
aut1äu
2aute
au4t3erh
-au3tes
3auto
-2auts
+2auts4
aut5st
2aux
auz2w
@@ -1308,16 +1317,17 @@ auz2w
av4a
ava3t
a2vr
-av2s
2a1w
awi3e
a1x
-ax2am
+ax2a
+ax3an
ax2e
-axi4s
2a1ya
a1yeu
+ays2
aysi1e
+ay3ste
2a1z
az4a
azo3
@@ -1332,27 +1342,27 @@ az2u
äch3l
ä2chr
äch2sp
+äch4st
ä1chu
+ä1ck
ä1d
-ä2da
-ä2d1ia
+ä3di
+ä4d1ia
+ä3do
ä2d3r
-äd2s
-2ä1e
+2ä3e
äf2fl
äf5l
äf3r
äf2s
-äft4s
+äft4s3
ä1g
äge1i
+äges4
ä2g3l
ä3g2n
ä2g3r
-äg4s2
-äg5sa
-äg5ste
-äg5str
+äg3s2tr
1ä2gy
äh1a
2ä3he
@@ -1364,10 +1374,10 @@ az2u
2ähm
äh5ne
äh5ri
-2äh2s
+2ähs
2äht4
äh3tr
-ä1hu
+ä3hu
äh1w
ä1im
ä1is.
@@ -1383,37 +1393,35 @@ az2u
äle3ru
äl2l1a
äl2p3
-äl2s
-äl3se
+äl2sc
ä1lu
ä3me
ämi3en
2äml
-äm4ma
-äm2s
ämt2e
2än.
än2dr
-2äne
+2ä3ne
äne2n1
än2f3
2änge
än2gl
än2gr
-äng5se
-äng5ste
+äng3se
2ä3ni
än5k2e
än2k3l
än2kr
+änk2s
än5n4e2
2äns
-än4s1c
+än4s3c
änse3h
ä1on
ä1pa
äp2pr
-äp4s1c
+äp4s3c
+äp2st
1äq
ä2r3a2
är4af
@@ -1427,61 +1435,57 @@ az2u
ä1ri
är1int
är2k5l
-ärme5s
+ärk2s
är1o2
ä1rö
ärse2
-är2seb
-är4si
+är6si
+är2st
ärt4e
-ärt4s3
+ärt2s3
ä1ru
är3ü
är2z1w
äs2a
-ä3s4e
+äs4e
äse3g
äse3re
äser4ei
äse4ren
äse3r2i
äse3t
-ä3si
äskop2
ä3s2kr
ä2s1p
-äs4s1c
-äs3se
+äs4s3c
äs4s3erk
-äs6st
-äs2te
-ä4str
+äs4st
+ä4s3t
+äs5ti
+äs4tr
ä3su
ä1ß
äß1erk
2ät
-ä2t3a2
+ä4t3a2
ä3te
äte1i
äte2n
-ä2th
ät2ha
-ä1ti
ä1to
ät1ob
ät3r
ät2sä
ät4schl
ät4schr
-äts1ei
ät2s1i
äts3l
ät3so
äts1p
-ät4st
-äts3te
+ät2st
+äts3ti
ät2tr
-ä1tu
+ä3tu
ät5ze
äu2br
äu1c
@@ -1492,26 +1496,27 @@ az2u
2äul
2äum
äu2ma
-äum4s
+äum2s
äums1p
ä2u3n2
2äu5r
2ä3us.
äu2sc
+äu6schä
äu4schm
-äu3se
+äu5se
ä1usg
ä1usk
ä1usn
äu2sp
-äus4s1c
+äus4s3c
1äuß
äu2tr
4ä1v
1äx
ä1z
â1t
-4b.
+6b.
1ba
2babs
ba3char
@@ -1522,8 +1527,7 @@ backs4
3bah
bah2nu
bah5re
-bai1
-bais2
+bais4
ba2ka
ba2k3er
ba2k1i
@@ -1531,9 +1535,8 @@ bak5l
ba2kra
3bal
ba1la
-bal4leh
+bal4l3eh
bal6lerg
-bal6lig
bal3th
2b1am
ban2a
@@ -1552,22 +1555,19 @@ bar3b
b2ard
bar3de
ba2rei
-ba3r2en
+bar2en
bar3zw
3bas
-ba7sa
+ba5sa
ba2sc
-ba6str
+ba4st
ba2to
-ba3tor
bau3b
bau3g
-bau3s2k
-bau3sp
-bau5str
+bau3s
+bau1s2k
ba1yo
-3b2äc
-bä1ch
+3b2ä1c
1bäe
1b2är
1b2äs
@@ -1575,10 +1575,10 @@ bä1ch
b1äug
bäu3s
4b1b
-b5ba
-bbau3sc
+b3ba
+bben3s2
bbe4p
-b5bi
+b3bi
bb5ler
b2bli
bb3lin
@@ -1587,16 +1587,18 @@ b3blö
bbru2
bb2s
bbu1
-2b5c
+b7by
+2b3c
2b5d
+bde1st
+bdo3
bdu3s
1be.
3be3a
be5an
be4au.
b2ebe
-1bec
-be1ch
+1be1c
be2del
bedi4
be1eh
@@ -1615,18 +1617,16 @@ be1ind
be1in4h
bei3sc
beis2e
-bei5st
+bei3st
beit2s
3bek
be3las
-be5le
be3lec
be3lei
-be6l1en
-be6let
+be2l1en
+be2let
be3li
-bel5la
-bel5li
+bel3la
bel3sp
bel3sz
belt4
@@ -1634,17 +1634,18 @@ bel3ta
bel3tr
1bem
1ben.
-be4na
+be3na
+be4nal
ben3ar
+be4nau
be3ne
ben4erg
-be4nerl
be4ners
ben3g
be3ni
-ben2se
+ben4se
ben2sp
-ben2su
+ben4su
ben4th
3b2enti
b1ents
@@ -1666,21 +1667,21 @@ ber3iss
ber3na
b1ernt
be1rop
-ber5st4a
+ber3st4a
ber3th
be3rum
-1be3s
-be4s1er
-be4sk
-be5slo
+1be1s
+be3sa
+be2s1er
+be3slo
+be3spo
+be3spr
bes5s4e
b3esst.
bes3sz
-bes2t
+bes2to2
be4s3tol
-be4stor
-be4sum
-be1s2ze
+be3s4ze
3bet
be2tap
be3tha
@@ -1690,20 +1691,19 @@ be1ur
1bez
2b5f4
bfal2
-bfrä5
-4b5g4
-bga4s1
-bgas3t
+4b3g4
+b5ga
bge3
bge5n
-bge5s
-2b5h
+bges4
+2b3h
1bi
bi1ak
bibe4
bi2e
bi3ens
bi3ent
+bie2s
bi3k2a
bi2ke.
bi2kes
@@ -1719,47 +1719,44 @@ bi3n2e
bi2o3
bi3on
biri1
-bi3se
+bi5se
bi2sol
-bis4s1c
-bi2s1t
-bi4stü
+bis4s3c
+bi4st
bi2t
b2i3ta
bi3te
-bi3ti
bi3to
bi3tr
-bit5st
-2bitu
-bi3tum
-b2i3tus
+bit3st
+2bi4tu
+bi5tum
+b2i5tus
biz2
bi3za
4b3j
bjek4to
-2b5k2
+2b3k4
b2l2
2bl.
-b4la.
bla3b6
4b5lad
b6lanc
6blasser
b6latt
b3law
-1ble.
-3ble2a
+3b4le2a
b3leb
2b5leg
b3leh
2b3leid
b5lein
+blei3sc
ble3l
-1b4lem
+b4lem
b4ler
b5lese
-ble3sz
+ble5sz
3b4let
2b3lich
3blick
@@ -1771,15 +1768,17 @@ b4lit
b6loc
b5lok
2b3lun
+blu4ter
3blü
-2b5m
-4b5n2
-bni4
-bnis1
+2b3m
+6b3n2
+bni2
+bnis3
1bo
bo5as
bo2b3l
bo3b4r
+bo2c
bo3ch2
bo3d2
bo2e3i
@@ -1797,6 +1796,7 @@ bo4rä
bor2d1i
bor2d3r
bo2rei
+bor2s
b1ort
bor4tei
bor2t3r
@@ -1806,20 +1806,20 @@ bo4s3p
3bot
bote5n4e
bo3th
-bot4st
+bot2st
bö2b3
2b3öf
bö3sc
-2b5p2
+2b3p2
bpa4g
-2b5q
+2b3q
b2r4
2br.
b4ra.
2b3rad
-b4rah
-b4ra3k
-bra5st4
+b6rah
+b6ra3k
+bra1st4
2bre.
6b5rechte
2b3ref
@@ -1828,39 +1828,45 @@ b3reif
b3rek
3brem
2b3rep
-b6rer
-2b3riem
+b4rer
+b4ri
+2b5riem
bri2er
-2brig
-b4rio
-bro1
+2b5rig
+b5ris
b5roh
2b3rol
b4ruc
-bru6s
brust1
4b1s
bs3ad
+bs1an
b3sand
bs3ar
-b5sat2
+bsat2
b3sä
-b5sc
-b6schan
+b4sär
+b3sc
+b4schan
b7schl
+bs4cu
b3se
b5se.
bs1e2b
-bs1ein
b5sel.
bs1ele
bse2n
+b5sen.
bs1ent
bs1er
-bs3e4r3in
+bs5e4r3in
b5ses
b5set
-bsi2t
+bs1ex
+bsi4t
+bs5ko
+bs2ku
+b4sl
b2s1of
bs1op
bso2r
@@ -1868,42 +1874,44 @@ b2sö
bs1par
bs2pl
b3s2pu
-bs3s2
+bs5s2
bs2t
bst1a2b
bst1ac
bst1ak
bst3ank
-b5stä
bs3tät
+bs4tem
bst1er
-b4stern
bst1h
-bs3tip
-b5stra
-b4s3trä
+b3sto
+b2s3trä
bs3treu
b3stu
-bs3ty
+b3stü
+b4stüb
b2s1un
-bs3w
4b1t
-b5ta
+b3ta
btal3
-bta4st3r
+bta4s
+btast3r
b3tä
b5te
b2t1h
+b3ti
bti2s
b3to
-b5tr
-b5tu
+b3tr
+bts2
+b3tu
btü1
b2u
bu2chi
bu2e3
bu2f
bu5li
+bul2la
2b3umk
bu3na
bunde6s
@@ -1915,8 +1923,6 @@ bus3cha
bu3se
bu4s1er
bus1p
-bu6sterm
-bu4s1tr
bus1u
bu3ße
1b2ü
@@ -1925,18 +1931,19 @@ büge4
bügel3e
2b3v
2b5w
-bwa5re
-1by1
+1by
+by1a
by3p
-by2t
-by3th
-2b5z2
+by4t
+by5th
+2b3z2
+b5ze
bzei2t1
2c.
1c4a
-2ca1b4
+2ca1b
ca1ch
-cae3
+ca2e3
3caf
ca3g4
ca1h
@@ -1949,7 +1956,8 @@ ca3pel
3car
car3n
carri1
-ca3s4a3
+ca3s2a3
+ca4st
ca3th
ca1y2
cä3
@@ -1968,14 +1976,15 @@ cen3ta
ce3n1u
1cer
ce1ro
-ce5sh
+ce3sh
+ce1st
1cet
-4ceta
+2ceta
cet3am
ce3ty
ce1u
1cé
-c1f
+2c1f
c4h
4ch.
2chab
@@ -1983,30 +1992,29 @@ ch3abi
ch1ah
ch1ak
ch2anb
-3chanc
+5chanc
ch1ang
ch3anst
-2chanz
-1chao
+4chanz
+3chao
ch1ap
-2char.
+4char.
ch3arm.
3charta
cha2sc
chasi1
-1chato
+3chato
+4chatu
ch1ärm
ch1äs
1châ
2chb
-2chc
+4chc
2chd
ch3e4ben
ch3echt
-1chef
-3chef.
+3chef
che2fe
-3chefs
4chei
ch1eim
che4ler
@@ -2015,16 +2023,17 @@ che4ler
cher3a
che3rei
6chergeb
+2cherö
ch1ess
2ch3eta
-ch1ex
+2ch1ex
1ché
2chf
2chg
2chh
ch1ia
-1chia.
-1chias
+3chia.
+3chias
6chind
3chines
ch1inf
@@ -2040,72 +2049,103 @@ ch3lein
2ch2m
ch4mu
2chn4
+2chob
+cho6cker
cho2f
ch1off
ch1oh
ch1orc
2chp
ch2r2
-2chre
-chre5s
+4chre
ch3rh
3chron
4chs
-2cht
-ch5tes
+4cht
2chuf
2chuh
2chum
2ch1unf
-chus4si
-2chü
+2chunt
+4chü
2chv
2chw
2chz
1ci
ci1c
-cil3l
ci2s
c1j
-2c4k
+c4k
+4ck.
ck1a
-ck3aa
-ck3am
-ck3an
+3cka.
+ck5aa
+2ckac
+2ckal
+ck5am
+2ck3an
cka4r1
+2ckau
ck1ä
+4ckb
+2ckc
+2ckd
+1cke
+3cked
+4ckeff
+4ckeh
ck1ehe
-ck3ei
-ck3ense
+4ck3ei
+3ckel
+3cken
+4ck3ense
ck1ent
+4ckentw
cke2ra
cke5reig
-ck1err
+4ckerhö
+4ckerke
+2ckero
+2ck1err
cke2s
-ck1ese
-ck1id
+2ck1ese
+2ckex
+4ckf
+4ckg
+2ckh
+1cki
+2ck1id
ck1im
ck1in
-ck5l
-ck3n
-ck1o2
+3ckis
+2ckk
+2ck5l
+2ckm
+2ck3n
+2ck1o2
ck1ö
-ck5r
+2ckp
+2ck5r
+4cks
ck3spo
-ck5ste
-ck4stro
-ck3t2e
+4ckt
+ck5t2e
ck3ther
-ck1um
-ck1up
+3cku
+4ck1um3
+4ckunt
+4ck1up
+2ckv
+4ckw
+1cky
+4ckz
3c6l2
-clet2
+clet4
clo1c
c2m
-1co
-3coa
-3coc
-co1ch
+3co
+co2c
+co3ch
co2d
co4der.
co3di
@@ -2123,27 +2163,30 @@ co1ra
co4re
cor5t
cos4
-co4st
-co2te
+co4te
+cô4
2cp
-c1q
+2c1q
c4r2
cre2
cre4mes
cry2
-2cs2
-c2si
+2c2s
+cs2a
+c3se
cst4
+c3s2tr
2c1t
cte3e
-cti4
-ction5
+c3ti4
+c3to
ctur6
-1cu
+3cu
cu2p3
cup1e
cussi4
1cy
+2cz
4d.
3da.
da1a
@@ -2161,10 +2204,10 @@ da3dr
da1er
2d1af
d1ag
-dagi4o
+dagi4
dah3l
da1ho
-3d4ai4
+3d4ai
da1in
da1is
da1l2a
@@ -2175,7 +2218,6 @@ da1lö
2d1amma
2d1ammä
damo3
-d2amp
damp7f8erf
2d1amt
d2an.
@@ -2196,21 +2238,22 @@ d2aph
4dapp
da2r3a
2darb6
-dar3bl
3d2arl
dar2ma
dar2m1i
da2ro
2darr
+dar3s
2dart
d1artg
da2ru
d2arw
+das4
da3s2h
+da5s2t
3dat
da3ta
dat2e4
-da3tei
4d3atl
4datm
3dau3e4
@@ -2219,26 +2262,27 @@ da3tei
2d1äh
2d1ämt
2d1änd
-2d1äng5
+2d1äng
2d1äp
2d1ärz
dä2um
dä1us
-2d7b
+2d7b6
dbu2
2d1c
4d3d2
+ddar2
ddar4m
d5de
1de
de3am
de3an
de3as
-de5a2t
-de3b4
+de5a4t
+de3b6
4d1e4ben
-3dec
-de1ch
+3de1c
+de2cka
deco3
de1e2
2d1eff
@@ -2250,7 +2294,6 @@ de3ho
d2eic
3d2e1im
de2l1a4g
-delat5
de4l3aug
de4l1än
del1ec
@@ -2260,37 +2303,38 @@ de3l2ei
de2len
2d1elfm
3delik
-del4la
delle2
+del4leb
del4lei
-del2lö
de2l1ob
de3lor
de2lö
-del2s1e
+del2s5e
del2so
del2s1p
+del5ster
delt4
del3ta
-del3te
del3tr
de6ments
2d1emp
d2en.
+dend2
+dend4s
de4n3end
den3g
de2ni
den4k5li
-4densem
+den3sc
den4sen
-den6s5tau
+dens5tau
den3th
2dentw
de2ob
2deol
de1on
deo4no
-depi4so
+depi2
d4er.
de1rad
de2r3ap
@@ -2302,7 +2346,6 @@ de3r4erb
de3r4erf
de4r3ero
4d3erhöh
-d4eri
de5ric
de3rik
4d3erklä
@@ -2311,6 +2354,7 @@ de2rop
d3ersat
dert2a
der6t5end
+dert2s
de3ru
de4ruh
de4rum
@@ -2324,14 +2368,17 @@ de3se
des1en
des1in
des1o
-des3p
-des5s4
+des1p
+des3pot
+des3s4
+des5se
dest5alt
de5stang
-de5ste
-de6s3tei
-de5sti
-de7stin
+de5star
+de5stat
+de7stel
+de4sto
+de3str
dest5rat
de5stri
de5stro
@@ -2345,12 +2392,14 @@ de2xis
2dexp
2d3f
2d1g
+dga2
d2ge.
d3gem
dge2ta
dge6t5e
d3gl
2d1h2
+dhas2
d2his
d3hu
1di
@@ -2366,16 +2415,16 @@ dich3te
di2de
di2e
di3e2d
-die5ner
+die3ner
di3eni
di3ens.
dienst5r
-die4s1c
+die4s3c
die2t5
-dige6s
+dige4s
di3gn
di3ka
-dil4s1
+dil2s3
2d1imb
din2a
2d1ind
@@ -2395,7 +2444,10 @@ di2ris
2d1irl
2d1isr
dist4
+di4ste
di2ta
+di3te
+di4tei
di4teng
di4t3erl
di4t3erm
@@ -2403,6 +2455,7 @@ di4t3ers
di2t3r
di2tu
diz2
+di3zi
2d1j
2d1k4
4d1l
@@ -2422,7 +2475,8 @@ d1o2be
dob4l
3dobr
3doby
-do1chi
+do2c
+do3chi
3dog
do3ha
3dok
@@ -2430,7 +2484,7 @@ dol3l2
do2mar
3don
do5n4a
-doni1
+doni1e
do2o
4d1opf
d2opp
@@ -2446,9 +2500,10 @@ do2rie
d2orp
d2os.
do3sp
-dos3s4
+dos3s
dost3
-do6sta
+do4sta
+do3str
3dot
dot4h
do3un
@@ -2457,12 +2512,13 @@ do1y2
d1öf
d1öl1
3dör
-dö4s1c
+dö4s3c
2d3p2
2d1q
d2r4
3d4ra.
2d3rad
+drag4
d4rah
2d5rahm
3d4ram
@@ -2497,18 +2553,16 @@ d3rieg
d4rif
d3rind
3drisc
-2driß
3d4rit
4dritu
2drob
d3roc
2d3rod
d4roi
-dro3ma
2d3rot
d3rou
2d3rov
-drö4s1
+drö4s3
3d4ru
d5rub
4d5ruf
@@ -2516,20 +2570,21 @@ d5rub
4d5rut
3d4rü
drü1b
-2d1s
+drü5cke
+2ds
ds3ab
-d4s1amt
+d4s3amt
d2s3an
ds3assi
-d2sau2
+d2s1au2
d2s1än
4dsb
d4schin
d2s1e2b
d3sec
d2s1ef
-d3s2eig
-d2s1ein
+d5s4eig
+d2sein
d2s1eng
d2s1ent
d2s1erf
@@ -2541,12 +2596,12 @@ d4s1eta
d3s2ha
ds3han
d3sho
+ds3hu
d2s1im
ds2inf
d3s2kan
d3skul
4dsl
-ds3m
d2s1op
dso2r
ds1ori
@@ -2557,28 +2612,33 @@ d2s1pä
d3s2po
d4spro
dss2
-ds5st
+ds3st
dst4
-d4s1tab
+d2s1tab
d4s3täti
-d6stea
-ds2til
-d5stip
-d4s1tis
-d2stod
+d5stei
+d5stell
+d3s4tern
+ds1th
+d1s2ti
+ds4til
+d3stip
+d1str
d5stre
+ds2tri
+d1s2tu
ds1ums
d2sun
+d1sy
ds2zen
4dt
d1ta
dt3a2d
d1tä
-d1te
-d3tea
+d5tea
dte5na
dt3ha
-d1ti
+d3ti
d1to4
d1tö
dt3r
@@ -2589,7 +2649,6 @@ dt5sc
dt3sp
dt5str
dt3t
-d1tu
d1tü
1du
du1alv
@@ -2599,7 +2658,7 @@ du3e
du2f
2d1ufe
2d1uh
-du1i4
+du1i
3dum.
d1umb
2dumd
@@ -2618,33 +2677,39 @@ dun3d
dun3ke
dun2kl
2dunr
+dun2st
2dunt
du1os
dup4
-dur2c
+dur2
2d1url
-3dus
-du2sc
+3du2s
du3scha
+du3se
+dus1t
2düb
3düf
3dün
3dür
+dürn3
2d1v2
2d1w
+dwa4
dwa2l
-dwe4s
+dwes4
dwest1
dy3n
2d1z
-6e.
+4e.
2e1a
e3a2b
+ea2c
eadli4
e2ag4
ea2ge
ea3gl
eakt4
+eak3to
e2al
e3al.
e3alb
@@ -2665,7 +2730,6 @@ eam3a
e4ame
eam1o
eam3to
-eam3tu
ea2na
e5and
e4ano
@@ -2678,9 +2742,7 @@ e4are
e5a6rene
e3arm
e3art
-ea6se.
-eas5s
-ea4st
+eas3s
e4at.
eat4e2
eate4r
@@ -2692,7 +2754,6 @@ eau3b
e3au2f
e3aug
e3ä4
-eäng5
e1b
2eba
e3b2ak
@@ -2700,7 +2761,7 @@ eba3ra
ebe2i
eb4en
e3beng
-eben4s3e
+eben6s5e
2ebet
2ebl
eb5ler
@@ -2714,23 +2775,22 @@ ebö4s
e3bra
eb3rei
eb2s
-eb6sche
+ebs1au
eb4se2
ebs1i
ebs1o
ebs1p
ebs3pa
-eb6stät
-eb4stec
-ebs3tei
+eb4stät
+ebs5tem
ebs3th
ebs3ti
-ebs3tot
+eb3str
ebs1u
e3bu
ebu2t1
eb3üb
-2eca
+2e3ca
e1ce
ech1ä
2e3che
@@ -2749,19 +2809,22 @@ e1chu
ech1uh
ech3w
eci6a
+e1cka
eck3se
2eckt
2ecl
-e1cr
+2eco
+e5cr
+ecs1
2ect
e1d
ed4dr
ed4e
-ede4c
e3dei
ede3n2e
+eden2s
eden4se
-eden4s3p
+edens3p
ede2r
ed2ge
edi4a
@@ -2771,29 +2834,29 @@ ed3s2ä
ed2s1es
ed2s1o
ed2s1p
-ed5sta
-ed4s1tr
+ed2s1tr
ed2su
e3dy
-4ee
+6ee
ee5a2
eeb4l
ee2ce
ee1ch
+ee2cho
+ee2ck
eede3
-eeds2
+eed3s2
ee1e
ee3ei
e1eff
-eef5s
+eef3s
eeg4
e1ei2
eei3e
ee1im
ee3ing
-eei3se
eel2e
-e1elek
+e1e2lek
ee3len
e1emp
e1en
@@ -2806,23 +2869,25 @@ e1e2pi
e2e1ra
e1erbt
e1erd
-eerde3c
ee3r2e
ee4r3eng
-eere4s5
+eere4s
ee4ret
e2e1ro
-ee1r2ö5
+ee1r2ö
eer3öf
eert2
e1ertr
e2erü
e1erz
-ee5sh
+ees2
+ee3sh
+ees3k
ee3st
ee2tat
ee2th
ee1u2
+eewa4r
e1e2x
e1f
2ef.
@@ -2859,7 +2924,7 @@ ef1rol
ef3rom
ef3rot
efs2
-ef7sc
+ef5sc
ef3so
ef3sp
ef2tan
@@ -2871,21 +2936,22 @@ e1g
e3ge
ege4n1a
ege2ra
-ege4s3to
-ege4str
ege1u
-eg3la
eg4li
eg3lo
eg3lu
e2gn
eg3ni
-eg6sal
-egser1
-eg3spe
-egst6
-eg6sto
+eg4sal
+eg6ser1
+egs2pe
+egs2t6
+eg1ste
+eg4sto
+eg1str
+egs3trä
2e3gu
+egus1
2e1ha
eh1ach
eh3aka
@@ -2899,6 +2965,7 @@ ehen2t3
1e2hep
ehe1ra
eher4an
+ehe3str
e3h2i
eh3int
eh1lam
@@ -2916,17 +2983,15 @@ e1ho
e3hol
ehr1a
ehr1ä
-ehr3ec
+ehr3e2c
eh2r3ei
eh1ri
eh1ro
ehr1ob
ehr1of
-eh2s2
-eh3se
+ehr5sch
+ehs2
eh3sh
-eh3si
-eh3so
eh3sp
eh3te
e1hu
@@ -2939,10 +3004,9 @@ e1hy
2ei3a2
4eib
ei2b3l
-eibu2t
+eibu4t
ei4b3ute
ei2cho
-eichs7test
eich5te
e2id
ei2d1a
@@ -2953,7 +3017,8 @@ ei3dra
ei1e
ei3el
2eien
-eie4s
+eien3st
+ei3erv
ei3et
1eifr
ei3g2a
@@ -3016,15 +3081,13 @@ ei2sä
ei4s3erw
ei3sp
eis2pe
-ei4str
-ei2sum
+ei3sto
ei2ta
2eitä
-ei3ten
-ei2t1h
+eit1h
ei2tro
eit3t2
-eit3um
+ei4t3um
2eiu
2e1j
e1k
@@ -3040,16 +3103,18 @@ ek4l
ek5lip
ek4n
2ek2o
+ek3s4t
2ekt
ekt4ant
ekt3erf
ekt3erg
ek4t3erz
-ekt2o
+ek3t2o
e3k2w
2e1la
e3lab
el3aben
+ela2c
el1af
el3agi
ela2h
@@ -3062,12 +3127,13 @@ e2l3anz
el1ap
e2l1a2r
el5ari
+ela4s
el3asi
el3asp
e3law
2e1lä
-elb4
1elbis
+elb4l
el2da
eld5erst
eld3erw
@@ -3075,7 +3141,8 @@ el3des
el3dr
elds2
e5le.
-elea4
+elea2
+ele4c
2elei
e3leie
e6l5eier.
@@ -3104,6 +3171,7 @@ e3let.
e2l3e4ta
2elev
ele2x
+el1exi
el3fe
elf3ein
elf4l
@@ -3114,16 +3182,15 @@ e3lie
e2lim
eli4n
el1ita
-elks2
-el3l2a
-el4läu
+ell2a
+el3lan
el5le.
ell3ebe
el4l3ein
ell3eis
el3les
-el2lic
-el3l2in
+el5lin
+ell5sp
elm2a
2eln
el5na
@@ -3141,20 +3208,20 @@ e1lö
el2san
el2ser
el2spr
+els6tern
el2su
el2ta
-el3t2ak
+el3tak
elte2k
elt3eng
-el3tes
-elt3in
+el4t3in
el2to2
el2t3r
el3tri
el3tro
elts2
elt3sk
-elt3sp
+elt5sp
2e1lu
e2l1um
e3lung
@@ -3167,7 +3234,8 @@ el3zwe
2ema
e2m3ad
ema2k
-e2m1anf
+em1anf
+e3mann
em1ans
3emanz
e5mä
@@ -3176,13 +3244,13 @@ em4d3a2
eme4n
emen4t3h
e2m1erw
+eme2s
3e2meti
em1ex
em1im
em1int
-emi3te
+emi5ti
2emm
-em2map
emma3u
e3mon
e2mop
@@ -3197,7 +3265,7 @@ em3t2
e2na
4ena.
e4na2b
-2e5nac
+2e3nac
e3nad
e4naf
4enah
@@ -3207,6 +3275,7 @@ ena3l2i
4en1am
en4ame
e4nand
+e5nann
en3anz
en1ap
e4nar
@@ -3221,16 +3290,18 @@ e3näc
en1är
en1äu
en2ce
-en4d3ess
+en3del
+end3ess
en3do
end4ort
end3ras
-end5si
+end7si
end3s2p
end3sz
en3dum
2ene
-en1ec
+en1e2c
+ene4ck
e2nef
en1ehr
en3ei.
@@ -3243,7 +3314,6 @@ e5n4entr
en1epo
4ener.
e4n1erd
-e4nerf
3e2n3erg
e4n3erh
4e3neri
@@ -3256,12 +3326,10 @@ en1ers
e2n3ert
e2n3eru
e4n1erw
-en3erwe
-e6n3erz
+en3erz
e4n3ess
en3eta
en3eth
-ene3tr
en1eup
e4nex
en3fa
@@ -3272,8 +3340,8 @@ en5g2i
en2gl
en3glo
1engp
-eng5s
-eng7sc
+eng5sc
+eng3se
2eni
e3nic
e4n1id
@@ -3287,8 +3355,8 @@ e5nit
en3k2ü
e2n1ob
enob4le
-e2n1oh
-e3nol
+e2n3oh
+e3n4ol
eno2ma
en1on
e2n1op
@@ -3303,19 +3371,17 @@ e6nr
en2san
en5sche
en7schen
-en2seb
+en4seb
1ensem
ens3eng
en3sho
en2sid
-en3ska
+en3s2ka
en3s2po
enst5alt
en4s3tät
-en6s5test
4ensto
-en7stric
-ens5trie
+en3stoc
en5t4ag
en3tanz
1entd
@@ -3368,9 +3434,9 @@ e3ord
eorgi1
e3ort
e3orw
-eos2
+eo3s2
e3os.
-eo5st
+eo1st
eo3ul
e1o2v
e1ö2
@@ -3381,13 +3447,13 @@ e3p2f6
1episo
ep3le
e2poc
-epor5te
ep2pa
ep4pl
ep2pr
ept2
ep3ta
ep4tal
+ep5ti
e1q
er1a
e5ra.
@@ -3447,7 +3513,7 @@ erd3erw
4e5re.
e3rech
er3echs
-er1eck
+er1e4ck
ere4dit
er1eff
er1e2h
@@ -3483,7 +3549,6 @@ e2r1erw
4eres
e5res.
er1ess
-er1eß
er3e4ti
er1eul
ere3us
@@ -3493,16 +3558,18 @@ er3fä
3ergebn
4ergehä
erg3ise
+erg3s4
e2r3h
3erhab
-2e1ri
+4e1ri
e2riat
e3rib
-4e3rie
+6e3rie
eri5e4n3
+erien5e
e5rif
erik6
-4e3rin.
+6e3rin.
er1inb
er1ind
e4r1ini
@@ -3512,8 +3579,8 @@ e4r1int
e3rio
er1ita
2erkol
-erk3te
-erk3tr
+erk5te
+erk5tr
4erl.
3erlebn
4erln
@@ -3521,7 +3588,7 @@ erm2
er3ma
erm3ers
er3nan
-er2n1os
+er2n1o4s
e1ro.
er3oa
er1ob
@@ -3541,18 +3608,19 @@ e1row
e1roz
er1ö2
e1röh
-2erök
-erö4s
+4erök
er5p
er3ra
+er5rä
2errü
er3sa
-ers4au
-er3se
-er5s2i
+ers2au
+er5sen
+er7s2i
er3sk
er3smo
er3sn
+er3sum
er3s2z
ert3abe
ert2ak
@@ -3565,7 +3633,6 @@ ert3ins
er3to
erts2e
2e1ru
-eruf6s
er1uhr
er1u2m
er1uns
@@ -3574,35 +3641,36 @@ er1uz
e1rü
er3ü2b
e5rüg
+2erv
3erweck
6erweis
2erzy
-es2a
e4s3ab
+es4ach
es3ad
es3ak
-es3alt
-es3ar
-e5s4as
+e5s4a4s
+es3aus
es3av
+esä2c
2esb
e3sc
es3cap
-es4ce
+e5s4ce
esch4
e6schan
esch2n
-e4sco
e6scu
es1ebe
es3ehr
-es1ein
+es3ein
es1eis
es1eta
es3eva
2esf
-6e4sh
+6esh
es2har
+es3he
es2hu
e3sid
e5sie
@@ -3611,71 +3679,71 @@ es1ini
es3int
e3sir
e7sis
-e5sit
-es5ke
+es3ke
es3ki
+es3kl
+es3ku
e4s3ky
-e4sl
-es2log
-2e4sm
-e4sn
+es3l
+es4log
+2esm
e3sof
e3sol
eso2r
es2ort
es4pei
-e3s4pek
-e5spi
+e3spek
es2po
-e5s4por
-es2pr
+e5spor
e5s4pra
2esr
-es6saa
1essay
-es3sec
+es3sc
+es5sec
+6essem
ess4e3re
es4s3erg
-es4sit
2esso
es2sof
es2sp
ess1pa
-es4st
+es2st
ess3tie
-es5str
-es5su
-e2st
-estab6b
+es3str
+e5staa
+e2stab
+estab4b
est1ak
+e3star
e4starb
-es6tau
-es7taum
-es2te
-es6te.
+es2tau
+es3taum
+e3stec
est5eink
-e7stel
-e4st3eng
-e4st3erh
-e7stern
-e7sters
-e4st3ess
-es4ti
-es5tip
+e5stel
+es4t3eng
+es4t3erh
+es4t3ess
+e1stil
estmo6de
-est3o4ri
+est3ori
+e1s2tr
es3trop
-e3stu
-es4tü
+e1s2tu
+es3tus
+e3s4tü
e2s1um
+es3ums
es1ur
+es3w
e3sy
+es3z
+e1ß
eße3r2e
2et
e1ta
eta3b6
et1am
-etari1
et4at
e1tä
et1äh
@@ -3696,6 +3764,8 @@ eti2ta
e3to
eto4b
e4t1of
+etons4
+eto4s
e1tö
4e1tr
e4t3raum
@@ -3703,23 +3773,25 @@ et3rec
e2t3res
et4ri
et4ro
+et2s
+et3sc
+et5schu
etsch3w
+et3se
et3so
et3sp
+et3sto
+et3str
et3su
et2ta2
et4tang
ett3au
-et2tä
et2tei
ette4n1
ett1h
et4t3r
ett3sz
-et2t1um
-et2tur
-et2tü
-e1tu
+et4t1um
et1ups
e1tü
et4z3ent
@@ -3727,7 +3799,7 @@ et3zo
eu1a
eu3ere
eu3erz
-eu2e5sc
+eu2esc
eu2ga
eug6er
eug3l
@@ -3741,26 +3813,26 @@ e1um
e3um.
e3umb
e3uml
-e3um6s
+e3um4s
eums1p
eum5st
-eum7str
2eun
eu3n2e
e3ung
eu4nio
-eun3ka
eu1o2
eu3p
eu2rau
eu3r2e
eur4er
-1eu3ro1
+1eu3ro
eu4sk
eu3sp
e4ust4
+eu1str
2eut
-eu3te
+eu5te
+eu3to
2eux
eu2zw
e3ü
@@ -3768,7 +3840,6 @@ e3ü
4eve
e2vela
e2vent
-ev2s
e1w
2e3wa
ewa3s
@@ -3780,24 +3851,25 @@ ew3et.
e3wir
ewi2s
e3wit
+e5wo
ew2s
2ex.
+1exam
ex3at
1e6xem
e4x1er
e2x1in
-1exis
3exp
2ext.
-ex2tin
-2exu
-2e1xy
+e1xy
2ey
ey4n
+ey3st
e1z
-e5z2a
+e3z2a
e2z1enn
e3zi
+ezin4
ezi2s
é1b
é1c
@@ -3817,17 +3889,16 @@ ezi2s
è1n
è1r
ê1p
+ê4t
6f.
1fa
3fa.
-fa1b4
+fa1b
fa2ben
-f3abf
-fab5s
3fac
-fa3che.
-fa3chem
+fa4cheb
fa2ch1i
+fa2cho
2fad
fa2da
3fa1e
@@ -3838,13 +3909,11 @@ fa2ke
f2al
fa1l2a
fal2kl
-fal6lenk
fal6l5erk
-fal2li
fal2s
+fal3te
falt4s
fal2z1
-3fam
2fanb
fan3da
2fanf
@@ -3856,13 +3925,14 @@ fan2gr
2f1ap
far2b3r
3fari
+farr3s
3f2art
fa5ru
f1arz
3fas
-fa3s4a
+fa3s2a
+fa5se
fa3sh
-3faß
2fat
fa2to5
2f1auf
@@ -3882,7 +3952,9 @@ fä2ßer
f3ds
1fe
3fe.
+fe4c
f2ech
+fe5che
4f3eck
fe2dr
fe2ei
@@ -3890,7 +3962,6 @@ fe1em
f4eie
4feinh
fei2nu
-fei5st
fek2ta
3fel
fe2l1a
@@ -3898,12 +3969,9 @@ fel4dr
fel5eise
4f1e2lek
fe2l1er
-fel5lä
fe2l1o
fel4soh
fel3to
-fel3tr
-fel3tu
3f2em.
2femi
fem4m
@@ -3915,8 +3983,7 @@ fe2ni
fe2no
fen3sa
fen7sc
-fens2t2
-fen5ste
+fenst2
f1ent
f2er.
fe1r2a
@@ -3933,10 +4000,10 @@ f4erpa
f2ers.
f2ert
f1erw
-fes2t
+fe2s
fe4st1a
-fe4st3ei
-fe4str
+fes3tat
+fest3ei
2f3e4ta
3fete
fet4t1a
@@ -3945,10 +4012,8 @@ fet4t1a
4fexp
3fez
1fé
-6f1f
-ff2ab
+4f1f
ff1ar
-ff2arb
ff3at
ff1au
ff2e
@@ -3960,7 +4025,6 @@ ffe2m
ff3emi
f5fen
f5fer
-f2fetz
fff4
ffi3k
ff6lei
@@ -3978,10 +4042,12 @@ ff3sho
fft2
fft3h
2f3g4
+fge1
2f1h
1fi
3fi.
fi3at
+fien3
fi1er2f
fi2ki
fi3kl
@@ -3996,18 +4062,20 @@ fi6lin
fil2ip
fin4a
fi3ni
+fin4s3
2f1int
fi3ol
fi2r
fi3ra
3fis
fi3s4a
-fi4scha
fisch3o
fi3so
fi5s2p
+fi4s3t
+fi3te
fi2t1o2
-fit5st
+fit3st
fi3tu
5fiz
2f1j
@@ -4035,11 +4103,12 @@ flug1a
f4lü
2f1m
2f3n2
-fni2
+fni2s
1fo
fob4l
2f1of
fo2na
+fon3st
fo2nu
2f1op
fo1ra
@@ -4048,17 +4117,17 @@ fo3rin
3form
for4m3a4g
forni7er.
-for4sta
+for4st
for2t
for4te
for4th
fort3r
for3tu
-fo5st
2fo2x
2f1öf
2f1ök
2f1öl
+förs3
2f3p2
fper1
2f1q
@@ -4068,7 +4137,6 @@ f5rad
fra4m
f3rand
1f4rän
-frä5st
2f5re.
f5ref
2freg
@@ -4082,30 +4150,30 @@ fri2e
2frig
fri3k
1f4ris
-fri6ster
-f4riß
f3roc
1f4ron
-fro2sc
+fro2s
fru2h
4fs
-f2san
+fs1all
+f2s1an
fs3ar
f2s3as
+fs1auf
f2saut
f3sc
-f4sce
f4schan
+f5schl
+fs4co
fs1e2b
fs3ehr
-fs1ein
f2s1em
f4s1ent
f2s1er
fse4t
f4s1eta
f3si
-f2si2d
+fsi2d
f2s1o2
fs3ol
f3span
@@ -4117,18 +4185,19 @@ f2s1pr
fs2pra
fs2pri
fs3s2
-fs1tak
-f4stas
-fs2tau
-fs1tät
+f1s2t
+fs3tak
+fs3tät
f4stäti
f4stech
+f3stei
f5stel
-f4stemp
-f4s1tis
-fst4r
+f3stern
+fs3th
+f3st4r
f4s3tres
-fs2tro
+fs4tro
+f3stü
f4s3tüte
f2s1un
f2sü
@@ -4147,7 +4216,8 @@ ft1e2h
ft1eig
ft1ein
ft1eis
-f2t1ent
+fte3ma
+f4t1ent
f2t3e4ti
f2t1h
f4t3hei
@@ -4158,13 +4228,14 @@ f2t3ro
ft3rö
f3t4ru
ft2s1
-ft4sa2
+ft4s3a2
ft3sc
+ft6sche
ftse2
-ft4stä
-ft5s4ten
-ft5s2ti
-ft3sü
+ft3st
+fts3tan
+ft4s3tä
+ft5sti
ft3t
ft1url
ft3z2
@@ -4177,14 +4248,12 @@ fun4ko
fun2k3r
2f1unm
2funt
-furch2
+furch4
fu4re.
fu5ru
-fus3se
-fus6senk
-fus4ser
-fuss1p
-fus4s1t
+fus2sa
+fus2s1p
+fus2st
fu2ß1er
3fut
1fü
@@ -4201,12 +4270,13 @@ fz4s
6g.
1ga
5ga.
+gabe4n
2gabf
-ga2b5l
-ga1b4r
+gab5l
+ga1br
ga3bu
2gabz
-ga1ch
+ga1c
ga3di
ga1e
ga1fl
@@ -4222,11 +4292,11 @@ g1anf
gan2g1a
4gangeb
gan2gr
-2g1anh
+2ganh
2g3anku
2ganl
+g3anla
3gano
-g4ant
2ganw
ga1ny
2g1arb
@@ -4236,18 +4306,15 @@ ga1ny
ga3r2o
g1arti
2garz
-ga2s
-gas3a
+ga2s1a
ga4sal
-ga3sc
-ga5se.
-gas1ei
-gas5s
-ga4sta
-gas3tan
-ga4st3el
-ga4stra
-gas1tu
+gas3ei
+ga2si
+ga2so
+gas3s
+ga4st
+gas4t3el
+gas4tra
ga3t2a
ga3th
2gatm
@@ -4260,10 +4327,9 @@ g2auk
1gä
2g1äp
g1ärz
-3gäs4
-gä5st
+3gäs
gä4u
-6g1b
+4g1b
g5be
gber2
g5bo
@@ -4290,21 +4356,20 @@ ge3a2
ge3ba
gebe4am
geb4r
-ge1c
+ge3c
ge3d
ge1e2
ge3ec
ge2es
gef4
-geg4l
ge3ha
ge1im
ge1ins
ge1inv
ge1ir
+ge2is
4geise
gei3sh
-gei4sta
g2el
gel6ders
ge3le
@@ -4313,9 +4378,9 @@ ge4less
ge3lor
gel3sa
gels2t
+gel3ste
gel3sz
gel3t2a
-gel3to
ge3lum
ge3lü
gel3z2
@@ -4332,8 +4397,9 @@ gen3eid
gen3ern
gen3g
gen3k
-genmes4
ge3nor
+gens3am
+gen7stern
gen3sz
g1entf
gen3th
@@ -4358,26 +4424,30 @@ ge1ro
ge1r2ö
ger4sto
3gerw
-g6es
+ges2
+ge5s4am
ges3auf
-ge5s2c
+ge5s4c
ges3elt
-ge2s1er
+ge2s3er
ge3ses
-ge3s2i
+ge3si
ge3sp
-gess2t
-ge3st
+ges4pi
+gess4t
+ge1st
+ge3ste
+ge5stei
+ges4tem
+ge4s3ter
get2a
-ge3tan
4getap
ge3t2u
ge1ul
-gewa5re
4g5ex
2g3f2
-2g1g
-gga2t
+4g1g
+gga4t
g5ge
gge2ne
g2g3l
@@ -4385,7 +4455,6 @@ gg4lo
g2g3n
gg4r
g3grä
-gg4s
2g1h
4gh.
3g2het
@@ -4418,6 +4487,7 @@ gi2o
gi3ro
2gisel
git2a
+gi3tu
gi2us
2g1j
2g5k
@@ -4428,13 +4498,9 @@ g2l
3glad
2g3lag
3glanz
-gla4s5ti
-gla4stu
3g4laub
2g3lauf
1glä
-3gläs
-g3läß
3glät
2gläuf
1gl4e
@@ -4455,11 +4521,12 @@ g3li
g4lia
2glib
3g4lid
-5g6lie
+5g4lie
2glif
1g4lik
g5lin
-1g6lio
+1g4lio
+gli2s
4glisc
1g4lit
1g4liz
@@ -4474,12 +4541,11 @@ g4lom
1g4lot
g3lö
2gls
-2glu2
-glu3te
+2glu
+glu2t
3glü
3gly
-2g1m2
-gmi3te
+4g1m2
gn2
4gn.
g2na
@@ -4493,7 +4559,7 @@ g5neh
g2nie
g2nif
g4nin
-4g5ni4s1
+4g5nis1
g2no
gno1r
2g3not
@@ -4511,7 +4577,7 @@ goa3li
go3be
2g1of
2g1oh
-go1i4
+go1i
gol2a
3gon
2g1ope
@@ -4519,6 +4585,7 @@ gol2a
3g2o1ra
3gos
go2si
+go3st
go3t2h
got6t5erg
3gou
@@ -4562,8 +4629,6 @@ gro3be
gron4
g4ros
gross5el
-gros8seri
-g4roß
gro4u
2g3röh
g4ruf
@@ -4575,135 +4640,116 @@ g4ruf
grü1b
2g3rüc
3g4rün
-4g2s
-gs1ac
+4g2s1
gs3ad
-gs1af
-gs1a2g
-g5sah
+g4sa2g
+g3s2ah
gs5a2k
-g5sal
-gs1ama
-gs1amb
+g3sal
+gs3ama
+gs3amb
gs3an
gs3ar
gs3as
g5sat
gs3aug
-gs1ä
-g7sät
-g5sc
+g5sät
+g3sc
+g6sca
+g6sce
gsch4
-g6schan
-g7schä
+g4schan
g6schef
-g7s2chi
-g7schl
-g7schö
-g7schu
-g7schü
-gs1cr
-gs1e2
-g5s2eil
-g5sel.
-g5seln
-gs3ene
-g4s3er
+gs4chi
+gs3cr
+gse2
+g3s2eil
+g3sel.
+g3seln
+g4s5er
gse4t
-gs1i
gsi2d
-g7sil
-gs3l
-gs1o2
+g5sil
+g4s3l
+gso2
g3sol
-g7soz
-gs1ö
-gs1p
-g5spek
+g5soz
+g3spek
gs2pi
-gs3pin
-g5s2por
-g4spu
-gs3s2
-g3st
-gs1ta
-g5s2tar
+gs6pie
+g4s3pin
+g5s4por
+gsrü2
+gs5s4
+g3star
+gs4tati
gst1au
-gs1tä
-g5ste.
-gs3teil
-g7stel
-g5sten
+g4stä
+g5stäm
+gs3te
+g3s4tel
gst3ent
-g5ster.
gst3err
-gs3test
gs4teu
-g5sti
-gs3tier
-gs1tis
-g5sto
-g6ston
-g6s1tor
-gs1tot
-g5stö
-gs1tr
-gst4ri
-gst3ros
-g5stuf
-g5stun
-gs1tü
+g3stir
+g3s2to
+g4s3tor
+gs2tö
+gs4tör
+g1stre
+gs4t3ros
+gs3trü
+g3stu
gs2tüc
-gs1u
-g5sub
-g5sy
-2g1t
+g4s5w
+g3sy
+2g1t2
g5te
-g2t1h
+g2t3h
g5ti
gti2m
-g5tr
-gt4se
+gts3
+gt3t
+gt3w
1gu
gu1an.
gu1ant
+gu1c
gu2e
-guet2
+guet4
2g1u2f
2g1uh
gu3ins
gu1is
gu5me
-3gumm
gun2e
2g1unf
g2ung.
-gunge2
+gunge6
4gungew
2g1ungl
-3g2uns
+3g2un4s
4gunt
gu3re
2g1url
-gu4s3a
+gu4s
+gus3a
+gu5sc
guschi5
-gus6saa
-gus6sam
-gus4st
-gu2ß1
+gu5se
+gus5se.
+gus2st
5gu2t1
-gu3te
1gü
2güb
gür1
-gü5st
+güs1
2g1v
4g5w
-gwa5re
1gy
gy3n
2g3z2
-6h.
+4h.
2ha.
hab2a
hab2e
@@ -4722,6 +4768,7 @@ ha3go
ha3ha
hai1es
h2aka
+haki3
ha1kl
4h2al.
ha1la
@@ -4731,10 +4778,12 @@ ha2lau
hal2ba
hal4bei
halb3r
-2hale
-hal4leh
+halb5s
+2ha3le
+ha3li
hal6lerf
h1alp
+hal4st
halt3r
h1amt
h2an.
@@ -4743,7 +4792,7 @@ h2and
h4ann
2hanr
2hant
-haos5
+ha3os
2hap
ha2pr
h4a3ra
@@ -4755,25 +4804,25 @@ har4mes
har5te
har4th
h1arti
-h2arts
2has.
-2ha3sa
-ha2ß1
+4ha3sa
+ha5sta
hau3f4li
2h1aufm
h1aukt
hau2sa
hau4sc
-hau6s3ti
+hau5stei
hau2ta
2hauto
hau2tr
h1äff
+3häp
h1ärz
hä6s5chen
-häu4s1c
+häu4s3c
hä1usp
-2h5b
+2h5b6
hba2r3a
2h1c
2h1d
@@ -4811,8 +4860,8 @@ heine2
hei4neh
h1eink
he3ism
-he3i4st
-heit4s3
+he3ist
+heit6s3
h1eiw
hekt5a
he2l3au
@@ -4832,13 +4881,14 @@ he3mi
h2en.
he6n3a2
he4nä
+hend4s
h4ene
he2n1e2b
hen3end
he2net
he2ni
he2no
-hen5st2
+henst2
h1ents
he2nu
hen3z
@@ -4866,12 +4916,12 @@ h1erö
hert2
her3th
her2z1w
-hes4t
+he2s3tr
he2tap
heter2
he3th
he5ti
-he3t4s
+he3t6s
he2u
heu3g
he3x
@@ -4882,6 +4932,8 @@ he1y2
hfel2l1
hfi2s
2h5g2
+hge1
+hgin4s
2h1h
2hi.
2hi2a
@@ -4892,22 +4944,21 @@ hi2e
hi3ens
hie4r3in
hif3f6r
-h2ig
hi2kr
h2il
-hi4l5a4
+hi2l5a4
hil2fr
hi2n
hi3nel
hin2en
hi5n4i
hi3no
-hin2t3a
+hin4t3a
2hio
hi4on
hi3or
hi3os
-2hi2p
+4hi2p
hi3pe
hip1h
hip1i
@@ -4920,7 +4971,9 @@ hi3ro
his2a
hi4se
hi5s2p
-hi3ti
+hi4st
+hi1th
+hi5ti
h1j
2h1k4
2hl
@@ -4932,7 +4985,6 @@ h5land
hl3anz
hl1ar
h3las
-h3laß
h3lat
h3laug
h3laut
@@ -4940,7 +4992,6 @@ h3law
h3läd
hl1är
h3läs
-h3läß
h3läu
hlb4
hl3d4
@@ -4970,8 +5021,7 @@ h2li
h3lic
h3lik
hl1ind
-h3list
-hl3l2
+hll2
hlm2
h2lo
h5loc
@@ -4988,11 +5038,11 @@ hl2ser
hl3sku
hl3slo
hl3sp
-hl2sto
hlt2
h3luf
h3luk
h3lüf
+hlzu5
2h1m
h2ma
h4mab
@@ -5007,8 +5057,7 @@ h4mäu
h3me.
hme1e
hme1in
-h3meist
-hmen2s
+hmen4s
hmen6sc
hme2ra
h2mi
@@ -5057,17 +5106,22 @@ hn3k4
h3nof
hn3s2k
hn4th
+hnts2
h2nul
hn1unf
h3nunge
ho3be
ho2bl
ho2c
-hoch5
+ho4ch5
+ho3ck
+ho4cka
+ho7cker.
hoe4
ho2ef
ho4fa
ho2f3r
+hohen3
hol1au
ho2l1ei
hol3g4
@@ -5082,32 +5136,30 @@ ho2mec
ho2med
ho5mu
h2on
+hon3str
2hoo
2hop
ho1ra
hor3d
h1org
-ho5ri
ho3sl
ho4sp
ho4st
-ho6sta
-ho5ste
-2hot.
+4hot.
ho5th
-2hot3s2
-1hou
+4hot3s2
+1hou2
3hov
-2ho2w
+4ho2w
how1e
h1o2x
ho1y2
-hô1
1hö
hö2c
+hö3ck
h2ör
hö4s
-hös1c
+hös3c
h1öst
2h3p2
h1q
@@ -5134,14 +5186,12 @@ h3rep
h4r3erla
h3rerle
h6rerleb
-h3re4s5
-hre6su
+h3re4s1
hre2t
h2r3eta
h3rev
hrf2
hrg4
-hrga4
h3ric
hri4e
h3riesl
@@ -5154,29 +5204,27 @@ h2rob
h3roh
h3rol
h4rom
-hro3man
h4ron
h2ror
h3rou
-hr2s3ac
+hr2s1ac
hr2s3an
-hrs3au
-hr5sch
+hrs1au
+hr4se
hr2s1en
hr2ser
-hr4set
-hr4s1in
+hr2set
+hr6s1in
hrs3k
-hr2s1of
+hr4s1of
hrst2
hr2su
-hr6sw
+hr4sw
hr4tab
hr2tan
hr2t3ri
hr2tro
hrt2se
-hrt4ste
h1ru
h3ruh
hr1ums
@@ -5185,17 +5233,20 @@ h3rü
hr3üb
h2ry
hrz2
-4h1s
+4hs
h2s1ach
-h2san
-h2sau
-h3sc
+h2s1an
+h2s1au
h4schan
-hs1ec
+hs1e4c
+hs2ei
hs3eins
-hs1eis
-h2s1erl
-h3s2ex
+hs3eis
+h3sel
+h3sen
+h3ser
+h4s1erl
+h3sex
h2s1ing
hs3l
h2s1of
@@ -5204,26 +5255,23 @@ h2sper
h3s2por
h2sprä
hs3s2
-h4stal
+h2stal
hst3alt
-h4starb
-h4stau
-h4stäl
-h5ste.
-h5stem
-h5sten
-h4sterm
-h2steu
-h4s1tie
-h4stin
-h4s1tor
+h2stau
+h1stec
+h3s4terb
+hs1the
+h1s2ti
+h2s3tie
+hs4tief
+h2stor
+h1s2tr
hst3ran
-h4st3ri
-h2s1tu
-h3stun
+hst3ri
+h1stun
h2s1un
hs2ung
-h3sy
+h1sy
4h1t
h2t1a
htab2s
@@ -5231,28 +5279,26 @@ h3t4akt.
h3takts
h3t2al
h4t3alt
+h4tam
ht3a4n
ht5ane
h3t4ank
-h3tas
h4t3ass
h4tasy
ht3a2t
h2t1är
h5te.
-h2t1ec
+h2t1e4c
h3tech
h2t1ef
ht1e2h
h3teha
-h3tehä
h2teif
h4t1eim
ht1ein
h2t1eis
h4t3elit
-h2temp
-h3ten
+h4temp
h4tentf
h4t3ents
ht3erfo
@@ -5260,45 +5306,40 @@ ht3erfü
h2t1erh
h2t1erk
ht4erko
-ht3erre
+h4t3erre
ht3ersc
h6t5erspa
h4t3erst
h2t1erz
hte2s
-h2t3ese
-h6t3ess
+h4t3ese
+h4t3ess
h5tet
-h2t1eu
+ht1eu
h2t1ex
h2t1h
h3ti
h4t1in
hti2s
-htni4
h2t3oly
h2top
-h2torg
h2tö
h3töp
-ht3rak
+h4t3rak
ht3rand
h2t3rat
ht3raus
+h4tref
ht4ri
h2t5rin
h2t3rol
h2t3ros
-ht3roß
h2t3rö
h2t3ru
h2t3rü
ht2sen
-ht4s3ess
ht3spri
ht4stab
-ht4ster
-hts2ti
ht4s3tur
ht4s3tür
ht3t
@@ -5310,13 +5351,15 @@ htwa5re
ht3z4
hu2b
hub1a
-hu4bei
+hu4b3ei
hu4b1en
hub3l
-hub3r
+hub5r
+hu1c
hu2h1a
hu2h1i
-huk3t4
+huko3
+huk3t6
hu2l3a
hu2lä
hu2l3ei
@@ -5325,7 +5368,6 @@ hu4lent
hu2ler
hu2let
hu2l1in
-hul3l
hu2lo
hu3ma
h1ums
@@ -5339,6 +5381,7 @@ hur3g
hu3sa
hu2sc
hu2so
+hus4sa
hu2tab
hu3t2h
hu2ti
@@ -5352,12 +5395,13 @@ h4übs
hüf2
hüh3
hühne4
+hüs3
2h1v
hvi2
hvil4
2hw
h2wal
-hwa5re
+hwas7
hwe1c
h1weib
h1wet
@@ -5368,13 +5412,12 @@ h1z
hz4s
2i.
2ia.
-i4aa
ia1b4
iab5s
2iac
i5ad.
i3adn
-ia1f4l
+iaf4l
i4a3g
i3ak.
i1akt
@@ -5397,7 +5440,7 @@ i3alh
i3a2lia
i3alj
i3al3k2
-i5al5l
+i5al3l
i3alm
i3aln
ia2lor
@@ -5409,7 +5452,6 @@ ia2lu
i3alv
i3alw
i3al3z2
-iam4
2ian
i5an.
i1ana
@@ -5426,34 +5468,37 @@ ia3p2f
ia1q
i3ar
ia2ra
+iard2
2i3as
i5as.
i4asc
ia3sh
i4asi
i4a3sp
-ia4st4
-ia5str
+iast4
+ia5sta
+ia1str
i5at.
-ia6ta
+ia4ta
i3at2h
1iatr
i3ats
i3au
ia3un
-iaus1
2iav
i1äm
+iär2
i1är.
i1ärs
i3ät.
-i3ät3s4
+iä5te
+i3ät3s
i1b
i2b1ar
i2b1auf
ib2bl
i2b1ei
-ibe6n1
+ibe4n1
ibi4k
i3b4la
i3b4le
@@ -5463,16 +5508,17 @@ ib3ren
ib2s
ib3sa
ib3sp
+ib3sta
ib4ste
i2bunk
i2b3unt
-ibus1c
-ibwa5
+ibus3
2ic
ich1a
ich3ä
i1che
ich3ei
+i3cher
i1chi
i2chin
ich3l
@@ -5483,7 +5529,9 @@ i2ch3r
ich2t3r
i1chu
ich3w
-ick2e
+i2cka
+i3ck2e
+icks2
i1cr
i5cu
i1d
@@ -5514,6 +5562,7 @@ ieb4sto
ieb4str
ie1c
ie2cho
+ie4ck
ied3g
ie2dr
ie1e2
@@ -5524,12 +5573,11 @@ ie3fer
ief3f4
ie2f3l
ie2f1r
-ie2g7l
+ie2g5l
ie3g4n
ie2g3r
ieg4ra
-iegs1c
-ieg4st
+iegs3c
ie3her
i1ei
ie2l1a2
@@ -5547,7 +5595,6 @@ iel3sp
iel3sz
ielt4
iel3ta
-iel3to
i1en
i3en.
i3ena
@@ -5556,7 +5603,8 @@ i3e4nä
i3end
ie2n1e2b
ien2er
-ie6nerg
+ie4nerg
+ie3nern
i3enf
i3en3g
i3enh
@@ -5568,9 +5616,9 @@ i3e2no
i3enö
i3enp
i3enr
-iens2
-ien3se
-ien6sto
+ien5s2e
+ien2st
+iens4tr
ienst5rä
ien3sz
i3env
@@ -5587,15 +5635,16 @@ ier4ert
ie4r3erz
ie3res
i3ereu
-i4eri
-ier3k4
+ier3k2
i1ern
i3ern.
ier5ni
iers2e
ier4s3eh
-ier5sta
-i3e4stas
+ier7sei
+ier3sta
+ier3ste
+iesen3s4
ie3su
ie2t1a
ie4tei
@@ -5604,24 +5653,22 @@ ie4t3ert
ie2th
iet3ho
ie4t1o
-ie2t3ö6
-iet2se
+ie2t3ö2
+iet4se
i3ett
ieu2e
ie1un
i1eura
-iewa5r
i1ex
-2if
-if1an
+4if
i2f1arm
-if1au
+if3au
i3fe
i5f2en
+ifen3st
if1erg
if1erh
-if2fa
-if6feste
+ife4s
if2fl
i3fi
if3l
@@ -5645,9 +5692,9 @@ if2top
if2t3ri
ift3sp
ift3sz
-i1g
+2i1g
ig2ab
-iga1i
+iga3i
i2g1ang
ig1art
iga5s
@@ -5665,21 +5712,22 @@ ig4le
ig5lein
i4gli
ig1lu
-2igm
ig4na
i4gnä
i3g4neu
ig4no
i3g4ra
-ig6sal
-ig3sau
-ig3sä
+ig4sal
+ig5sä
ig4se
ig3so
-ig6sti
-ig6s1to
-ig6stö
+ig3spr
+ig3s4tei
+ig4s3to
+ig4stö
+ig3str
ig4stre
+ig5stu
2i1h
i2h1am
i2h1ar
@@ -5690,20 +5738,20 @@ ih3l
ih3m
ih3n
ih1r
-ih2s
i2h1um
ihu3s
ih1w
2i1i4
i2i5a4
+i3ig
i3in
i2is.
i2i5t
i1j
i1k
i4k3a4k
-ik3amt
-i4kanl
+ik5amt
+i4k3anl
i2k1ano
ik3ansa
i2k3anz
@@ -5726,16 +5774,17 @@ i3k4la
i3k4lä
ik1lö
i2k3n
-ik2o3p4
+ik2o3p6
ikot3t
ik3ra
ik3rä
ik3re
i3kri
+ik1s
ik3so
iks2p
ik3s2z
-ik3t2e
+ikt2e
ikt3erk
ik2t3r
i2kun
@@ -5747,7 +5796,6 @@ i2l1ak
i2l3a4m
il1ans
il3asp
-i3lat
i2l1au
il4aufb
il5aus
@@ -5759,10 +5807,9 @@ il3de
il4d3ent
ild2er
il2d1o
-il1ec
+il1e4c
ile2h
il1ehe
-ileid4
il1ein
i2l1el
i3len
@@ -5774,16 +5821,15 @@ il2f3l
il2f3re
ilf4s
ilg4r
-ili5en
+ili5en3
iliga2
ili4g3ab
i2l1ind
i2l1ip
i3lip.
i3lips
-il3l4a
-il4lad
-il2leg
+il3l2a
+ill4an
il3l2er
il5l2i
il2mak
@@ -5809,7 +5855,6 @@ i2manw
i2m1arm
ima2tr
ima4tur
-1imbi
i2m1ele
i2m1elf
i2m1erf
@@ -5818,25 +5863,21 @@ i2meti
im1ex
2imi
i2m1inf
-iming7
i2m1ins
-imi3te
-immei4
im4m3ent
3immo
-imni4
im1org
1impo
imp2s
im3pse
1impu
-im4str
+im2str
2imt
2imu
im3unt
2in.
2ina
-in1ac
+in1a4c
in3ad
in2af
in3a2m
@@ -5847,12 +5888,10 @@ ina4s
in3asi
inasy3
i2n3au
-inaus1
in1äs
in1äu
in3dau
in4dene
-indes4t
1index
in3do
2indr
@@ -5875,58 +5914,60 @@ in3erz
i2n1eu
ine3un
ine2x
+inf4
1info.
4inga
ing1af
in2g1a4g
-ings2c
-ing7sch
-ing3ska
-ing5ste
+ing5sc
1inhab
2inhar
2inhau
-2inhe
+4inhe
i3ni3d
2inig
in3ins
in2ir
2inis
+ini5se
i3nitz
3inkarn
-ink4st
+ink4ste
2inn.
in4n3erm
2innl
-inn6sta
1innta
2ino
in3od
in3ole
in3ols
in1or
-ino5st
+inos2
+ino3st
ino3t
i1nö
in1ö2d
2inp
2inr
+ins2
2ins.
-ins2am
+ins4am
+ins3än
insch4
in7schl
-in2seb
-in3sel
+in4seb
2insen
+ins3erg
ins3ert
in3skan
+in5spe
+in3st
3instal
in4s3tät
-in5sto
-in3s2u
+in5s4tr
+in5su
1insuf
-in4s3um
-ins2z
+in6s3um
in3sze
1integ
in3t2h
@@ -5951,17 +5992,16 @@ io2i3d
i4ok4
io3kr
i3ol.
-i3om.
-i3oms
+i5om.
+i5oms
ion4
i3on.
io3na
ional3a
io4n5au
ion5d
-i3ons1
+i3ons3
ion6sc
-ions3p
io2nu
i2ony
i2o1p
@@ -5980,7 +6020,7 @@ i2os2
i3os.
io3sh
io3sp
-io5st
+io3st
i3ot.
i3ots
i2ov
@@ -5991,6 +6031,7 @@ i3ön
i1ös.
2ip.
i1pa
+ip4an
i1pä
i1pe
ipen3
@@ -6000,13 +6041,13 @@ iph4
2i1pi
ipi3el
ipi3en
+ipi2s
ip4l
i1pr
2ips
-ip3ta
2i1pu
i1q
-i1r2a
+i1r6a
i3ra.
1irak
i3ras
@@ -6022,7 +6063,6 @@ ir2g5l
irg6s
ir2he
i1r2i
-iri3a
2irig
2irk
ir2k5l
@@ -6038,26 +6078,24 @@ ir2no
i1ro
1i2ron
iro2s
-iro5st
i1rö
irpla4
-ir4rei
-ir2s
-ir3sh
-irt4st
+ir4s
+ir5se
+ir5sh
+irt2st
i1ru
iru2s1
-i1s
i3sac
-i4s1amt
+i4s3amt
+is1an
is2ap
is3are
-i2sau
+i2s1au
is1än
2isb
i2sca
isch3ar
-is2che
i4sch3e4h
i4sch3ei
isch6er
@@ -6068,39 +6106,35 @@ i2schm
isch3ob
isch3re
isch3ru
-i4schwa
-i6schwir
-i4schwo
-i4sch3wu
-is1chy
-i2s1cr
-2ise
-i3sec
+isch3wu
+is3chy
+i2s3cr
+2i3se
ise3e
ise3ha
ise5hi
ise3il
-is1ein
ise3inf
i4seint
ise2n
ise4nal
is2end
ise1ra
-i2s1erm
+i4s1erm
iser2u
-i2s1ess
+i4s1ess
is4et
i4s5etat
+i4sex
isi2a
i2s1id
is3la
-is3m
+ismu2
i2s1of
iso2n
iso6nend
is1op
-3i2sot
+5i2sot
i2sp
is1pa
i4spar
@@ -6111,35 +6145,38 @@ i4spl
i4spo
i4spro
is3sa
-is6saa
-is4s3ac
+is4s1ac
is4sau
-is3sä
is4s3che
-is4st
+is2st
iss1tr
-is2sum
-ist2a
-i4st3ab
-i4staf
-i4stam
-is2te4n
-is2ter
-is2ti
-ist3re
-is2tro
-is1trü
-i2stur
+i2st
+is1t2a
+is2t3ab
+is2tat
+is3tec
+i3stel
+iste4n
+is1th
+i1stil
+is1to
+is2toc
+is1tr
+is2t3re
+i3stru
+i3stü
isum3p
i2sü
+i1sy
+i1ß
i2ß1ers
+ißler3
2it.
i1ta
it1ab.
it1ac
i3tak
ital1a
-ital3l
it1alt
it1am
it1ang
@@ -6152,33 +6189,30 @@ i4t1ax
2i3tä
i4t1äs
ität4
-2i1te
-it1eig
+2ite
+i2t1eig
it1ein
6i3tel
ite2n
iten3g
itens2
+iten3st
i2t1epo
-i2tex
+i4tex
it1he
i5thr
it1hu
-i1ti
+i3ti
1itia
-i2t1id
+i4t1id
1itii
iti4kan
-i2t1in
-i3tis
-i3tiv
+i4t1in
i1to
-i3to.
i5toc
i2t1of
i1tö
i1tr
-i5tra.
it3raf
it3rah
i2t3ran
@@ -6190,39 +6224,34 @@ it3ric
it3rom
i3tru
it3run
-it4s1ag
+it4s3ag
it2sä
it2s1e2
-it4s3er1
+it6s5er1
its1pe
it4staf
-it4stec
-it4s3tem
-its3tes
-it4sti
-it4sto
-it4str
-it2teb
-it4temp
+its3tie
+it2sto
+it2str
+it3te
+it4teb
itt3hä
it2tr
-i1tu
it1uh
i2t1um
i2tuns
itu5re.
it1urg
-itut4
+itut6
i1tü
i3tül
i3ty
2itz
it4z3erg
-2i1u6
-ium1
+2i1u4
ium3a
+ium1i
i3un
-ius1t
i1ü
2i1v
iv1ak
@@ -6237,7 +6266,6 @@ i3vol
i2vr
i2v1ur
2i1w
-iwa5r
iwur2
ix2em
i3xi
@@ -6259,28 +6287,33 @@ iz3th
i2z1w
í1l
2j.
+ja1c
jahr3ei
jahr4s
ja3la3
ja3ne
jani1
ja5sa
+ja3st
2jat
je2a
-jean4s
+jean6s
+je1c
je2g5
jek4ter
jekto2
jek4tr
je3na
je2p
-je3s
+jes1t
je2t
jet1a
jet3h
jet3r
+jet3st
jet5t
jet1u4
+je5v
jit3
ji2v
j2o
@@ -6290,20 +6323,23 @@ job3r
jo2i
joni1
jo1ra
-jord4
+jord2
jo2sc
jou2
jou4l
+joy3
4jö
2js
j2u
ju2bl
+juden3
jugen6
jugend5
ju2k
-jung7s
+jung5s4
jur2o
-ju3te1
+ju2s
+jute1
2j1v
4k.
1ka
@@ -6318,14 +6354,13 @@ ka1bl
2kablä
kab4le
2k3a2bo
-ka3b6r
+ka3b4r
4k3abs
2k1abt
ka1c
2kada
ka3dab
2k3adr
-ka1e
ka1f4l
ka1fr
kaf3t
@@ -6334,19 +6369,18 @@ ka1in
ka3ka
kaken4
ka1la
-2kala.
ka2lan
kal3bl
ka3lei
ka3len.
ka4lens
-kal3eri
+kal5eri
kal2ka
kal2kr
2kall
kal4tr
-k2am
-k3a2ma
+3k4am
+4k5a2ma
ka3mar
kamme2
ka4n3a4s
@@ -6365,6 +6399,7 @@ kan4th
k4anz.
ka2o
2kapf
+3kara
2karb
k1arc
k2ard
@@ -6376,13 +6411,14 @@ kari3es
kar4p3
k2ar3ta
2karti
-kar3to
karu2
k2arw
-ka5se
+3kas
+ka3se
kasi1
ka4sp
-ka3ta
+kas3s
+ka4s1t
ka3th
ka2t3r
2katt
@@ -6390,7 +6426,6 @@ kau4f1o
4kaufr
kauf4sp
2kaus
-kau5st
kau3t4
2kauto
1kä
@@ -6398,16 +6433,16 @@ kau3t4
2käh
k1ämi
kär2
-kä4s1c
+kä4s3c
kä5se
-kä3th
+kä1th
2k1b4
k5be
kbo4n
2k3c
2k3d
kdamp2
-2kec
+2ke1c
ke3d
k3eff
kefi4
@@ -6416,13 +6451,11 @@ ke2gl
ke2he.
kehr4s
kehrs3o
-ke2i
2k1eic
2k1eig
2kein
-ke3ind
+ke1ind
2k1eise
-keit4s
ke2la
kel1ac
ke3lag
@@ -6432,13 +6465,10 @@ kel3b
2k1e2lek
ke2len
2ke3let
-kel3s2k
+kel3sk
2k1emp
ken3a
4kengag
-kens2k
-ken5st
-ken7s4te
ken3sz
k2ente
k3enten
@@ -6473,10 +6503,11 @@ keu6schl
2k5f
kfi2s
2k1g4
+kge1
2k1h4
kho3m
ki3a6
-ki1ch
+ki1c
ki2d
ki3da
2k1ide
@@ -6486,7 +6517,6 @@ ki2el
kie2l3o
ki2en
kif4
-kif2a
ki1fl
ki1fr
ki3k4
@@ -6505,6 +6535,7 @@ kin3sh
ki3o
3kirc
ki5s2p
+kis2to
2kiz
ki3zi
2k5j
@@ -6561,15 +6592,16 @@ kol4k5
3kom
ko2min
ko4mu
-k2on
-kon3d
-ko3n2e
+k2on3
+ko3n4e
+kon4i
kons4
ko3nu
2kop.
ko1pe
kop4f3en
kopf5err
+kop2t
ko3r2a
4k1orc
kor6derg
@@ -6577,6 +6609,8 @@ ko3ri
kor3m
3kort
k2os
+ko3str
+3kot
ko3ta
kots2
kot3sp
@@ -6609,14 +6643,14 @@ k3reih
k3ries
2krip
k4ron
-kro5st
+kro3st
2kruf
krü1b
4ks
-ks1amt
-k2san
-k2sau
-ks2än
+ks3amt
+k2s1an
+k2s1au
+ks4än
ksch4
ks1e2b
k2s1em
@@ -6624,23 +6658,28 @@ k2sent
ks1erl
k2s1ers
k2s1erw
+ks1ex
k2s1id
k2s1in
k2s1o2
k3sof
-k5son
ks1pa
k3spe
ks2por
ks3s2
-kst4
+ks2t4
k5stab
ks3tanz
kstat4
-k4s1tis
-k4s1tor
-k4strä
-k2s1tum
+k1ste
+k5stei
+k6steil
+k1sti
+k2stor
+k1str
+k2strä
+k1stu
+k2stum
k2s1u
k1sy
ks2zen
@@ -6657,17 +6696,19 @@ kt5a4re
k5tat
k2t1au
ktä3s
+k3te
kte3en
-k2t1ei
-k2temp
-k2tent
+k4t1ei
+k4temp
+k4tent
k4t3erfo
-k2t1erh
+k4t1erh
k5ters.
-k2tex
+k4tex
k2t1h
k2t1id
-k2t1im
+ktien3
+kt1im
k2t1ing
kt1ins
k2t1of
@@ -6680,27 +6721,28 @@ k3t4ra
kt5ras
kt5rau
kt4ro
+ktro5s
kt3run
kts4
kt3se
kt3sp
-kt5st
+kt3st
kt3su
-kt3sz
+kt3s2z
kt3t2
k2tuns
kt3z
ku1c
-kuh5
+kuh3
2k1uhr
ku3la
ku3l2e
ku3l2i
-2kulp
+4kulp
2k3uml
-kum2s
+kum2s1
k2u3n2a
-kun6s
+kun6s4
kunst3
2kunt
2k1up.
@@ -6709,22 +6751,20 @@ kuri2e
kuri4er
ku2ro
kur4sp
-kur4s3t
kur4zen
ku4schl
ku2so
ku2sp
-ku5s4t
+ku2s1t
ku2su
-ku2ß
1kü
2küb
kü1bel
kü1c
-kür2s
+kür4s
2k1v
2k1w
-kwa5re
+3kys
ky3t
2k5z2
6l.
@@ -6734,9 +6774,11 @@ la3ba
4labb
4la2ben
3labi
-6l1abl
+4l1abl
3la3b2o
3l2a1b4r
+lab5re
+lab6ri
4l3abs
4labw
la1ce
@@ -6745,11 +6787,10 @@ la3den
la3d2i
l3adl
4ladm
-4l3adr
+2l3adr
5ladu
l3adv
1la1e
-laf3ta
la2ga
la3ge
lag5eis
@@ -6757,10 +6798,9 @@ la2gn
lago4
la4g1ob
la2gr
-lag5se
+lahn3
2la1ho
1lai
-lai4s1t
1laj
la3ke
la2k1i
@@ -6772,11 +6812,10 @@ la1k4l
l2a3ma
l2ami
la3min
-lam4ma
3lammf
l4amp
2l1amt
-lamt4s
+lamt6s
la4mun
la2na
la3nac
@@ -6790,12 +6829,13 @@ lan6d5erz
land5inn
lan2dr
2l1anf
-lang5s2
-l1anh
+lang3s4
4lanl
+l3anli
2l3ann
l1anp
2lans
+4lansä
4lanw
lanz1w
3lao
@@ -6808,37 +6848,30 @@ la2r1ei
la6rene
l4ar3g
lar3ini
+lar3st
2l1art
lar3th
l3arti
la3ru
-la5se
+la3se
2lash
la2so
2la4sp
5lasseri
5lassern
5lassers
-la4sta
-la5ste
-las3tei
+la4st
last1o
-la4str
-las3tur
-la4stü
-la2ß
-laß3th
lat2a
-la3te
la4tel
-4l3ath
+2l3ath
la2t3ra
lat4s
2latta
lat4tan
lat4t3in
lat4t3r
-laub4se
+laub6se
lau4fer
lau4fo
l2aufz
@@ -6846,10 +6879,10 @@ l1ausg
2l1ausl
2l1ausr
2l1auss
-lau5str
l1ausz
2lauto
2law
+lawa4
1lax
la3xa
lä1c
@@ -6858,7 +6891,7 @@ lä1c
3länd
lär2m1a
l1ärz
-lä4s1c
+lä4s3c
4lät
4läub
4läuc
@@ -6871,12 +6904,11 @@ lb3af
lb3am
lb3ang
lb3arb
-lb5b
+lb3b
l2b3ede
-lbe4n
l4b3eta
l2b3id
-l2b5ins
+l2b3ins
lb4lat
l3blä
lb3le
@@ -6884,14 +6916,18 @@ l2b5li
l3blo
lb3ohn
l4bre.
-lb3rit
+lb5rit
lb4ro
l3brü
-lb5sa
-lb5sp
+lbs4
+lb3sa
+lb4sk
+lb3sp
+lbs6t
lbst1e
-l2b5uf
-lb5v
+lb4sto
+lb4stu
+l2b3uf
4l1c
l3che
l5chi
@@ -6899,10 +6935,9 @@ lch3l
lch3r
lch3ü
lch1w
-l3co
4l1d
ld3a2b
-ld1ack
+ld1a2ck
l4d3ad
lda2g
l2d1ak
@@ -6925,7 +6960,6 @@ l3dern
l2d1erp
l2d1e4se
l2dex
-ldi2c
l2d1id
l2d1im
ldo2r
@@ -6943,15 +6977,14 @@ ld1rö
ld3sa
ld3ska
ld3sp
-lds2t
+ld1st
ld1t4
l2d1um
l2dü
1le
3le.
le3ar
-lea5s
-3le3ba
+le3ba
leben4s3
le2bl
2lec
@@ -6967,7 +7000,8 @@ le3f4a
le2g3as
le2gä
le2g5l
-3le3gr
+le3gr
+legs4
3lehr
leh3r4e
3lei.
@@ -6979,10 +7013,14 @@ l2ein.
l2eind
l2eine
l2eint
+lei2s
+lei3so
leis6s5er
l4eist
+lei3su
l2eit
lei8t7ersc
+leit3st
lekt2a
2lektr
3lela
@@ -6999,8 +7037,6 @@ le2m1o2
l2en.
le4nad
le4nä
-4lendet
-2lendu
3lene
le4n3end
4lenerg
@@ -7010,7 +7046,7 @@ le3ni
len3kl
2l1enni
l2e2no
-len5st
+len3st
len3sz
2l1ents
4lentw
@@ -7028,7 +7064,7 @@ ler5b6
4l3ereig
le4r3eim
le4rers
-2l1erfo
+l1erfo
l2erfr
l2erfü
3lergeh
@@ -7044,23 +7080,27 @@ le1ro
3l2erra
l4ers.
lers4k
+ler3ste
le2ru
le3rung
l1erz
l2erza
+les4am
les4e
2lesel
-le3ser
-le5sh
+le5ser
+le3sh
lesi1
le3s2k
-les7sa
+les2t
leste3
4lesw
2lesy
+le4sz
le2tat
2le3th
2leto
+let4tu
le2u
4leud
2leuro
@@ -7070,6 +7110,7 @@ le2u
3lexd
le5xe
le2xis
+3ley
2l1f
l3fa
l5fah
@@ -7081,9 +7122,8 @@ lf3lo
l3flu
lf3ram
lf2s
-lfs1e
lfs3tau
-lfs1tr
+lfs3tr
lf2tr
lf4u
lfur1
@@ -7093,14 +7133,11 @@ l2geti
lg3lo
lg3re
l3gro
-lg4sc
-lg6st
-2l1h2
+2l1h
l3he
3lhi.
1li
3li.
-l4ia
li1ac
li1ak
li3bi
@@ -7116,12 +7153,12 @@ liebe4s
lie2n
li3ene
li5enp
-lie4s1c
+lie4s3c
+lie2st
li3fa
li4fe
5lig
li3g4n
-lig3s2
li3ke
li3ki
li3kli
@@ -7144,7 +7181,7 @@ li4neh
li2nep
li4nes
2l1inf
-ling6s
+ling4s
2l1inh
li5ni
2l1i6nit
@@ -7158,8 +7195,7 @@ l2insc
l1inv
4linz
li2o
-lion5s
-li2p5a
+li2p3a
5lipt
3lis.
li3s2a
@@ -7168,13 +7204,15 @@ li4schu
2l1isl
2l1i2so
liss4
+3list
li2tal
li3te
li1t2h
lits2
-lit5st
+lit3st
lit3sz
-li2tur
+li3tu
+li4tur
3liu
2lixi
li2za
@@ -7182,11 +7220,13 @@ lizei5
4l3j
2l1k
lk1alp
-l3k4an
+l3k2an
l3kar.
lk1arm
+l3ke
lken3t
l2kep
+lkir5
lk3lo
l3k6lu
lk3nu
@@ -7194,33 +7234,31 @@ lkor2b1
l3k4ra
lk3ro
l2k3ru
-lk4s1
-lk5sä
-lk5ste
+lk2s3
+lk3sä
+lk4stä
l3k2ü
lkü1b
-2l1l
+4l1l
ll1abb
ll1abe
-ll5aben
+ll3aben
ll1abt
l3labu
ll1aff
ll1akt
l3l2al
-l4l3a4m
+l2l3a4m
l2l3anz
l3lap
ll1arm
-l4l3art
-l2l1au
-ll4aufe
+ll3art
+ll1au
ll3aug
-l4l3aus
+l2l3aus
l2l1äm
llb4
ll3d
-l2leb
l3lec
ll1ech
l2l1ef
@@ -7228,34 +7266,38 @@ ll1eim
llei4ne
l3l2em
l3len.
-lle6n1a
+lle4n1a
ll3endl
ll3endu
llen3g
l3ler.
lle2r3a
+l3lere
l4l3ergo
ll3ernt
l2lerz
ll2es
llg4
-l6lieg
+ll1imb
ll1imp
l2l1ind
lli5ne
l2l1ins
+ll3l4
ll5m
-l2l1ob
+l2l1ob6
l2l1of
ll1opf
l2l1o2r
l2l3ou
ll1ov
+l3low
l4l1öf
-ll3ö6se
+ll3ö2se
ll3sh
ll3s2k
-ll4s3tor
+ll3sp
+ll4spr
llt4
ll3th
llti2m
@@ -7264,8 +7306,9 @@ llt5s2
ll1ur
l3lus
llust6
+llus5tr
ll3z2
-4l1m
+2l1m
lm3a2b
lm1aka
l2m1arc
@@ -7280,6 +7323,8 @@ lm1orc
l2möl
lm3p
lmpf4
+lm1s2t
+lm3ste
lm3sz
lm3th
4ln
@@ -7295,7 +7340,7 @@ l1nü
2lobj
2lo2bl
l2obr
-lo3b4ri
+lo3bri
lof4
4l1o2fe
lo1fl
@@ -7307,8 +7352,8 @@ lo2k3r
lol2a
l3oly
lo2min
-l4on
lo4n1o
+lon3st
lo2o
2lope
2lopf
@@ -7323,12 +7368,10 @@ lo3ro
3los.
lo4sa
3lose
-los3se
+los5se
lost4
-lo4steu
-lo4s3to
-lo4s3tr
-lo2ßu
+lo4ste
+los1tr
lo2ta
lo3th
loti4o
@@ -7342,6 +7385,7 @@ lö3du
l3öhr
2l1öl
5lösc
+5lösu
4löß
2l1p
lpe2n3
@@ -7354,29 +7398,28 @@ lp3t4
lque3r
2l5r2
lrat6s
-lro3m
lru3t2
lrü1b
-4l1s
-l3s2ac
+4ls
+l3sac
l2s3a2d
-l7s2al
-l4s1amb
-l2sann
+l5s2al
+l4s3amb
+ls3amp
+ls1anf
+ls1ang
+l2s1ann
l3sare
-l2sau2
+l2s1au2
l4schin
-l5se.
l2s1e2b
ls1ec
-ls1ein
l2s1em
ls3ere
ls1erg
ls1erl
l2s1ers
l2s1erw
-l5ses
l3sex
l4sha
lsho2
@@ -7386,66 +7429,66 @@ ls3ohne
l4s3ort.
ls2pi
l3s2po
+l3spri
l3s2pu
ls3s2
lst2a
l5s2taf
ls3täti
+l1stec
l5stei
l5stel
-l5ster
-l4s1tis
-l4stit
+l5steu
+l1sti
+ls2tie
+l2stit
+ls2tol
+l1s2tr
+l1s2tu
ls1um
l3sur
-l3sus
+l1sy
ls2zen
-6l1t
+4l1t
lt1ac
lt1ak
lt1am
-l3tami
-l3tan.
+l4tame
lt3and
lt1ang
l3tar
lt1art
-l3tas
l3tat
l4t3ato
lt1au
-l3te.
l5tef
lt1eh
lt1ein
l2t1eis
lte5lei
-l3t2en
-l5ten.
+lt2en
lter3a
l3t4erg
lt2erö
lter4sp
-l2t3esk
-lte5str
-l3tet.
+l4t3es3k
+lte3str
lt3e2th
-l2t1eu
+lt1eu
l2t1h
l4t5hei
l3thu
+l3ti
ltimo4
l2tob
l3toc
lt1of
-l3ton
l2t1op
l2t1o2ri
lto3we
lt1öl
lt1ös
lt3öt
-lt4rak
ltra1l
l3trä
lt3räu
@@ -7456,11 +7499,10 @@ lt3ros
l2t3rö
lt5sc
lt2se
-lts1ei
lt3spa
lt3spr
+lt4spre
lt4stab
-lt5ste
lt4stoc
lt3t
lt1uh
@@ -7495,6 +7537,7 @@ lu2go
lu2g3r
lug3sa
lug3sp
+lugs4t
lu2gu
2l1uh
lu1id.
@@ -7518,33 +7561,33 @@ l1urn
l1urt
2luse
lu2sp
-lus4sä
+lus4s3a
+lus2s3c
lus4ser
-lus4si
lus2s1o
-lus2s3p
-lus6st
-lus8suc
-5lus2t
-lu4st3a
-lu6stä
+lus4s3p
+lus4st
+5lu4st
+lus2t3a
lust3re
lu2s1u
-lu2ß1
lu2t1a
+lu2tä
lut3erg
+lu5terk
lut1o2f
lu2top
-lu2t5r
+lu4t5r
3lux
2lüb
5lüd
lüh1l
+lü2s
2l1v
+l3vo
l2vr
2l3w
l5wa
-lwa5re
1ly
ly1ar
ly3c
@@ -7564,7 +7607,6 @@ l2zö
lzt2
lz3th
l2z1u4fe
-lzug4s
l2z1w
lz2wec
6m.
@@ -7581,7 +7623,6 @@ ma3da
ma3de
ma4d2s
ma1e
-ma2es
ma1f
2m1agg
magi5er.
@@ -7592,7 +7633,7 @@ ma5g6n
ma3ha
mah4ler
mah3li
-mai4se
+mai6se
2m1akt
ma1la
ma2l1ak
@@ -7604,7 +7645,7 @@ mal3d
mali3er
mal3lo
2mallt
-malu2
+malu4
ma2l3ut
mam3m
2m1anal
@@ -7618,14 +7659,13 @@ man3ers
ma2net
mang2
2mangr
+m2anh
2manl
m4ann
-2mans
-2mantw
manu3
2manz
ma2or
-m4app
+5m4app
2m1arb
mar3g2
ma3ri
@@ -7638,15 +7678,15 @@ mar5te
ma3ru
3m4as
ma3s2p
-mas4t
+ma3sto
+ma1s2tr
3maß
m4at
ma2tan
ma2tä
mat4c
-ma2tel
+ma4tel
ma4t3erd
-mats2
mat3se
mat3sp
3maue
@@ -7663,11 +7703,12 @@ mä1i2
m1ärg
mät4
mä1tr
-mäu4s1c
+mäu4s3c
2m1b4
mb2a
mbe2e
-m3br
+mbe4n
+m3b6r
2m3c
2m1d
md1ar
@@ -7680,7 +7721,7 @@ mdu3s
meb6
me1c
medi3
-medi5e6
+medi5e4
medien3
2medy
me1ef
@@ -7690,13 +7731,14 @@ mega5
2m1eif
m2eil
me1i2so
-m2eist
+3meist
2mej
me3lant
3meld
me2lek
-melet2
+melet4
2m1elf.
+mell2
melt4
6m5eltern
mel3tr
@@ -7708,10 +7750,13 @@ men3au
m3endl
men3gl
me3nor
-men4sk
-men2so
+men4s3k
+men4so
+men3st
men3ta
+men6tanz
4m3entn
+ment6sc
4mentw
me1o
2me3ou
@@ -7729,18 +7774,15 @@ mer2kl
me3run
mer3z4en
3mes
-me2s3a
+me2s1a
me2sä
mes2e
-4me5sh
+4me3sh
4mes2sa
-mes6sig
mes2s1o
mess1p
meste2
-me4str
4mesu
-3me2ß1
me3t4a
mete2
me3th
@@ -7750,13 +7792,14 @@ meu1
2m3f
mfi4l
4m1g2
+mge1
2m1h
1mi
3mi.
mi1ak
mi3an
mibi3e
-mi1ch
+mi1c
mi3da
mie3dr
mi2e1i
@@ -7773,45 +7816,45 @@ min5de
min2e
mi3neu
min2ga
+mings4
+ming3st
mi3ni
mi3n2o
3miri
3mirs
-mir3sc
+mir5sc
3mirw
mi2sa
mise1
mi3sp
-mis2s1c
-mis6st
-mi2ß1
+mis2s3c
+mi4ste
3mi2t1
-mi3te.
mit3es
mit3h
-mi3ti
-mit5s2
+mit3s4
+mit5sa
mi5tsu
4mitz
2m1j
-6m1k4
+2m1k4
m3ka
mk5re.
-6m1l
+2m1l
m3la
m3le
m5li
mlö3
-4m1m
+2m1m
mma4ge.
m2m1ak
m2m1al
m2m1ang
-mm1ans
+m2m1ans
mm1anz
+mma3s4t
m2m1au
m2m1ei
-mmeis3t
mme4lin
mme4na
mme2ra
@@ -7823,9 +7866,9 @@ mm1inh
mm1ins
mm1int
mmi3sc
+mmi3s2t
+mm3m2
mm3p
-mm2s2
-mm3si
mm3sp
m2m3um
mmül2
@@ -7837,7 +7880,7 @@ mo4a3
2mobj
3mod
mo2dr
-2mog.
+4mog.
mo2gal
3moh
mo2i
@@ -7849,7 +7892,8 @@ mo5m4e
m2on
mo3ne
mo4n1er
-mon3su
+mons1
+mon5su
3mo2o
2mo1pe
mo2per
@@ -7858,8 +7902,11 @@ mo1r4a
mor5ar
2morc
mor4d3a
+morgens6
mo4sk
mo3sp
+mo5s2ta
+mo3to
m1o2x
mo1y
1mö
@@ -7879,32 +7926,35 @@ mp3lu
mp3ta
2m1q
4m3r
-4m1s
+4ms
msa3l
-m2san
+m2s1an
ms3and
m4sap
ms3as
-m5sat
-m2sau
-m3sc
-m5sche
-m4sco
-m2s1ef
-ms1erf
+m2s1au
+m3se
+m4s1ef
ms1erw
+m4s1ex
ms1ini
mso2r
ms1ori
m2spä
ms2po
ms3s2
-m4stal
-m4strä
-m3stu
+m6stag
+m2stal
+ms2tau
+m1stec
+m1s2ti
+ms2to
+m1s2tr
+m2strä
+m1s2tu
+m3s2tü
ms1um
m2sü
-m3süc
m3sy
ms2ze
4m1t
@@ -7919,24 +7969,26 @@ m2t1erf
m2t1erg
m2t1erl
m2t1ers
-m2t1ert
-m2t3eta
-m2t1eu
+m4t1ert
+m4t3eta
+mt1eu
m2t1h
mt5ho
-m2t1im
-m2t1ins
+m3ti
+m4t1im
+m4t1ins
mt1int
mti2s
mt1ös
mt2s
mt3sc
-mt7sco
+mt5sco
mts1e
mt3s2ka
mts1p
mt3spa
mt3st
+mts3ti
mt3t
mt1um
mtu3re
@@ -7944,6 +7996,7 @@ mt1urt
mt3z2
1m2u
mu1a
+mu3cke
2m3uh
mu3la
2muls
@@ -7956,19 +8009,17 @@ mu3ne
4m3ungeb
m4unk
mu3no
+mu3ra
mur3ma
mu3ru2
mu4r1uf
-mu4s1a
+mu4s3a
mu2s1o
mu2sp
-mus4st
-mu6s1to
-mu4str
+mu2s1t
mu2su
-mu2t1au
-mut4s3
-mut5sc
+mut1au
+mut2s3
1mü
2müb
3mün
@@ -7976,11 +8027,12 @@ mut5sc
2m1v
mvol2l1
2m1w2
+mwa4
mwel4
-1my3
-my4an
+1my
+my4s3
+my3t
2m1z
-mzug4
6n.
1na
5na.
@@ -7990,8 +8042,10 @@ na3ber
4nabw
na2c
nach1
+na3chen
nachs2
5nachw
+na3cke
4n3add
4n3adr
na1e
@@ -8031,22 +8085,23 @@ n4am.
5nami
na3m4n
3namo
-nam2s
-2n3amt
-namt4s
+n3amp
+nam4sp
+4n3amt
+namt6s
n1an
+4nan.
4na2na
4n3anb
n2anc
4n3ang4
4nani
4nank
-4nanl
-5nann
+4n3anl
na3no
-4nanr
-2n3ans
-4nantr
+4n3anr
+4n3ans
+4n3antr
2n3anw
n1ar
5n4ar.
@@ -8062,17 +8117,16 @@ na3ru
3nas
na4schw
4n3asp
+na5sta
4nasy
-nasyl2
-3naß
3nat
5nat.
5nate
na3t2h
-5nats
+5nats1
nat4sa
-nat6s3c
-nat5st
+nat6sc
+nat3st
4natt
n1au
4nauf
@@ -8086,7 +8140,7 @@ nau3sc
n3ausl
4n3auss
4n3ausw
-nau3te
+nau5te
navi5er.
navi5ers
1nä
@@ -8096,17 +8150,14 @@ n2äc
n1ähn
2n1ä2m
2n3än
-näng5
+när4s1
n1ärz
-2nä2s
+2näs
nä4sc
-3näß
2näu
5nä1um
-4n7b4
-nbau3sc
+4n7b6
nbe2in
-nbe5n
nber2e
4n1c
nc5ab
@@ -8116,8 +8167,9 @@ n3ces.
n3che
nch3m
n3chu
+n2ck
n5cu
-6n1d
+4n1d
nd1ab
n3daf
nd2ag
@@ -8130,22 +8182,26 @@ nd1arb
nd3arr
nda3ru
n2d1au
+n3de.
nde4al.
nde3alt
nd1ei
nd3ei.
ndel4st
+n3den.
n4d3ents
nde3o
n5der.
n5deri
nde4rob
-n3de4s
+nder5ste
+nde4s
ndes1e
-ndni4
+ndo1c
n3dol
nd1op
n2d1or
+ndo3st
nd3rat
nd3räu
n2d3re
@@ -8158,8 +8214,8 @@ n4d5run
nd2sor
nd2spr
nds3tau
-nd5ste
-nd2sum
+nd3te
+nd1th
nd1t4r
n2dum
nd2ums
@@ -8177,8 +8233,9 @@ ne2bl
2n1ebn
2nec
3neca
-2ne2e
-nee1i4
+4nech
+2ne2e1
+nee3i4
ne3ein
ne3en
nee3t
@@ -8194,6 +8251,7 @@ n3ehe
n2eid
6neif
3neigt
+5neigu
4nein
6n3eing
6n3eink
@@ -8231,10 +8289,10 @@ nen3ei
ne4nene
ne2ni
nen3k
+5nenn
ne2no
-nen5s4e
+nen7s4e
nen3sk
-nen5st
5n2en5t2a
n1entb
4n3entl
@@ -8258,7 +8316,7 @@ ne2r3ap
ne2rau
4n3erbi
2n1erf
-6n3erfo
+4n3erfo
nerfor4
4n3erfü
n1erg
@@ -8269,7 +8327,6 @@ n1erk
n3ermä
ner4mit
2nermo
-3nern.
4n3ernt
ne1rös
n2ers.
@@ -8278,13 +8335,12 @@ ner8schle
3n4ert.
4n3ertr
ne2rup
-n2erv
4n1erz
3n2es
n4es.
ne3san
ne2sä
-nes2c
+nes4c
nesi1e
nes2k
ne3ska
@@ -8292,7 +8348,8 @@ ne2s1o
ne2s1p
4n3essi
5nest
-nes3tei
+ne2ste
+nes3ti
net1ak
net1an
ne2tap
@@ -8301,6 +8358,7 @@ net1au
ne2th
net3ha
ne2tre
+nett6sc
2n3e2tu
net2zi
ne2u
@@ -8318,7 +8376,8 @@ nfi3le
nf3läd
nf3lin
n3f2o
-nf4r
+nfo3s
+nf3st
nft2o
nft4s3
4ng
@@ -8349,10 +8408,11 @@ ng5ho
ng5hu
n2g1i2d
ng4lad
+n3gläs
ng3lein
ng3lo
ng3lu
-n4g5m
+ng5m
ng3ne
n2g1or
ng3rat
@@ -8360,11 +8420,11 @@ ng3räu
ng3rein
ng3rev
ng3roc
-ng4s
-ng6s1c
-ngs3e4h
-ng3send
-ngs3pa
+ng4sau
+ng4s3c
+ng4s3e4h
+ng5stel
+ng5stö
ng3ts
n2gue
n2gum
@@ -8384,7 +8444,7 @@ nib3b
ni3de.
ni3di
ni3dr
-n2ie
+n4ie
nie3b
nie3fr
ni1el
@@ -8398,6 +8458,7 @@ nifi3
nig2a
4n3i2gel
ni2g3r
+nig4sp
3nik
nik1al
ni2kä
@@ -8408,11 +8469,11 @@ ni2kr
n2imm
nim2o
4n3imp
-3nin.
+3n4in.
nin2a
4n3ind
2ninf
-3n2ing6
+3n2ing4
4n3inh
nin1i
4n1ins
@@ -8423,28 +8484,25 @@ ni2ob
ni5ok
ni3ol
ni3os
-3n2is
+3n4is
ni4schw
-nis1e
+ni4s1e
+ni5se.
niso2
nis1p
-nis5s2
-nis3sz
-ni2stu
+nis3s2
+nis3tr
ni2s1u
2nit
-ni3ta
ni1th
-ni2ti
-ni3to
+ni4ti
ni3t4r
nit2s
ni3tsc
-nit4tec
-nitt6sa
+nitt4sa
ni3tu
3niu
-3ni3v
+3niv
3nix
2n1j
4n1k
@@ -8456,10 +8514,10 @@ nk1apf
nk1arb
nk1arm
nk3arti
-nk1au6s
+nk1aus
nk1äh
n2k1är
-nk1ec
+nk1e2c
nk1ein
n4k3erfa
nk1inh
@@ -8483,10 +8541,10 @@ n4kre.
nk3rede
n3kri
nk3ro
-nk2sal
+nk2s1al
+nks2ei
nk2spa
nk3spo
-nk5sti
nk3s2z
nk2ta
nk3ti
@@ -8514,14 +8572,18 @@ n4n3er4wa
nn3er2z
nne2s
nnes1e
+nne4st
n5neu
nn3f
nn3g
n3ni
+nnis3t
nno3b
nn1o2r
-nn5se
+nn5sc
nn3s2p
+nn3ste
+nns2tr
nn4th
n4n1uf
n2n1unf
@@ -8537,12 +8599,13 @@ no1c
no3dr
2n1of
4n3o2fe
+n4oi
2nole
no2leu
-n4om
nom4e
n2on.
no3n4a
+non3s
3n2opa
2nopt
2nor
@@ -8558,14 +8621,14 @@ n1ort
3n2os.
no5se
no3sh
-3n2oste
+3n2o3ste
n1osth
-nost4r
+no3st4r
no5tab
no2tä
no4t1ei
-no2t1el
-no2t3in
+no4t1el
+no4t3in
no2t1op
no2tr
3nov
@@ -8577,16 +8640,25 @@ n1ök
4n1öl
4n5p2
npa4g
+npir5
+npro3
npsy3
2n1q
4n3r2
nre3sz
-nrö4s1
+nrö4s3
n5ru
4n1s
+ns3ab
n2s3a2d
-n2sall
+ns3ak
+n2s1all
+ns1an
n3sand
+ns3ans
+ns3art
+ns1au
+ns3auf
n2s1än
n2s1äus
n5sche.
@@ -8596,61 +8668,81 @@ n6schlic
n5schr
n6schro
nsch7werd
+n3se
ns1e2b
-n3sec
+ns3ebe
ns1e2d
nseh5ere
nseh3i
-n3senk
+n5senk
nsen4sp
-n2s1ent
-n2s1ep
+n4s1ent
+n4s1ep
ns1erf
-n2s1erg
-n2s1erk
-n2s1erö
-n2s1ers
-n2s1erw
-n2s1erz
+n4s1erg
+ns3erh
+n4s1erk
+n4s1erö
+n4s1ers
+n4s3erw
+n4s1erz
nse2t
n4s1eta
-n3sex
+ns3h
nsho2f
+n3sil
n2simp
n2s1ini
-nsi2te
+ns3int
+nsi4te
ns2kal
-n2s1op
+ns3ko
+ns3ku
+ns3ky
+ns3l
+n3so
+ns3ob
+n4s1op
n4s3ort.
-n2spat
+ns3park
ns4pei
-n3spek
+n3s4pek
+ns3ph
ns2pi
n2sprä
n4s3prie
n4spro
+nsrü2
ns3s2
nst1ak
-n6stat.
-n6s3tate
-n4stau
-n5s2te.
-n4stech
+n3star
+n4s3tate
+ns2tau
+n2ste
+n3stei
nst3eif
-n5stel
-ns4tem.
-n5s4ten.
-n4stent
-ns2ter
-n5s4tes.
+n3stel
+n4stem
+n5stemm
+ns4tent
+n3step
+n5s6terbe
+n5s6terne
+n5s6terns
n5steu
-n4stor
+ns2tie
+ns2to
n4strac
+n4strie
+ns2tu
nst4ü
nstü1b
+n4sty
+n3su
ns2um
-n2s1un
+n4s1un
ns2unr
+n3sy
ns3zi
4n1t
nt3abs
@@ -8696,33 +8788,35 @@ nt1ho
n3thol
n5thr
n5t4hu
+n3ti
+nti3c
nti3k4l
-n2tinf
-n2t1inh
+n4tinf
+n4t1inh
ntini1
-n5tit
+n5ti1t
ntmo2
n5to
nto5me
nton4s1
+ntons3c
n3tö
nt3rec
n5tree
nt3reif
n5t4rep
-nt4rig
n2t3rin
n5trop
n2t3rü
+n4ts
nt3sa
nt3s2o
nt3s2p
nt4s3par
-nts2t
-nt4sto
+nt2sto
nt3t
n3tu
-ntum2
+ntum4
nt3z2
1nu
nu1a
@@ -8730,7 +8824,7 @@ nu4ale
nu3ar
nu3as
nubi3
-2nuc
+2nu1c
3nue
nu2es
nu3et
@@ -8760,10 +8854,8 @@ nu3sc
nu3se
nu3sl
nu3spo
-nu6s1t
-nu2ß
nu2ta
-nu3te
+nu5te
nu2t3r
5nü.
2nü2b
@@ -8773,11 +8865,8 @@ nür1c
4n1v2
n3ver
n3vi
-nvol7ler
4n1w
n3wa
-nwa5re
-2nx
1ny.
1nyh
2nymu
@@ -8786,9 +8875,9 @@ n1yo
1nys
1nyw
4n1z
-nza2
n2zad
-n2z1ag
+n2z1a2g
+nz3am
n2zan
n2z1ar
n2z1au
@@ -8799,12 +8888,10 @@ n4zense
n4zentz
nz3erwe
nzi2ga
-n2zinh
nz1ini
nz1of
n2z1or
nz3th
-nzug4
n2z1wa
n2z1wä
nz1wer
@@ -8824,16 +8911,15 @@ oa3de
o4ah
o4a3i
oa3ke
-oak5l
+oa4k5l
o4a3la
o4a3mi
oanne4
o4ar
-o4a3s
-3oase
-o5a4si
+o4as
+3oa3se
+o5asi
o4at
-oa3te
o1b
ob2al
o3bar
@@ -8843,7 +8929,7 @@ ob2e
2o3be.
ob3ein
2oben
-oben3se
+oben5se
o2ber
obe4ris
obe6sp
@@ -8855,16 +8941,17 @@ o2b5li
1obm
2obo
o2b3re
-ob2s2
-ob3sh
+ob6ris
+ob2s
+ob3s2h
ob3sk
ob3so
-ob3sp
-ob4sta
-ob3sü
+ob3s2p
+ob3str
2o3bu
2o3bü
2oc
+o3ca
o1ce
och1a
ocha2b
@@ -8883,10 +8970,13 @@ och3to
o1chu
ochu2f
och3w
-ock2e
+o3ci
+o1ck
+o2ckar
+o3ck2e
+o3cki
ock3sz
-o3co
-o1cr
+o3cr
o1ç
2o1d
o3dar
@@ -8911,7 +9001,7 @@ o3et.
o3ets
o1ë
2ofa
-of1ac
+of1a2c
of1am
of1au
o2f1ei
@@ -8920,10 +9010,8 @@ o3fer
ofes3
of2f1a
of2f1in
-of2fir
1offiz
of2f3l
-of2fo
of2f3r
offs2
of2fu
@@ -8935,14 +9023,15 @@ of1la
o1f1r
of3ra
of3rä
-of4s1a
-of2se
-of2sp
-of2s1u
+of2s
+of4s3a
+of3sä
+of3st
+ofs1u
2oft
of2tei
of3th
-2o1g
+4o1g
o2g1ab
oga3d
og1ala
@@ -8957,10 +9046,8 @@ og3ins
o2gl
o3glo
o3g6n
-ogoi5
-og4s2
-og5sp
-og5ste
+ogs4
+og3sp
o1ha
o1hä
o1he
@@ -8985,9 +9072,10 @@ ohl3erh
oh5les
oh3li
oh3lo
-ohls2
+ohls2e
oh2lu
oh3m
+2ohn
ohn3a
oh2ni
oh2n1o
@@ -8997,10 +9085,10 @@ oh1o2p
o2h1ö
ohr1a
oh4rin
+oh1s
oh3ta
o1hu
oh1w
-ohwa5
2o1hy
2oi
o1i2d
@@ -9012,9 +9100,8 @@ o4i3ne
oi4r
o2isc
o3isch.
-oi5se
o1ism
-oi4st
+oi1th
2o1j
2o1k
oka3i
@@ -9025,18 +9112,22 @@ o3ki
oki4o
ok3lau
ok3lä
+okna3
ok2s1p
-okt4
+ok3t4
2ol
o1la
o2l1ak
ol2ar
ol1auf
o1lä
+4olc
ol4dam
ol4d5r
+oldwa5s
ol1eie
ol1eis
+ole3s
ol1ex
o1lé
ol4fa
@@ -9048,19 +9139,17 @@ olge4ne
ol2gl
ol2gr
ol2i
+olib6
oli5en
oli5f
-oli3tu
+oli5tu
ol2kl
ol2k3r
-ol2lad
ol2lak
-oll3ans
-ol2las
-ol2läd
-ol4l1ec
+ol2lau
+ol4l1e2c
ol2l1ei
-ol2l1el
+oll1el
oll5ends
ol4l3erk
oll5erwe
@@ -9073,17 +9162,17 @@ olo3p2
ol1ort
o1lö
ol2pr
-ols2
-ol4str
+ol2str
o1lu
ol2z1a
ol6z3ern
ol2zin
-2om
+4om
oma4ner
om2anw
om1art
o2m1au
+o3me.
o2meb
ome3c
o2m1ei
@@ -9095,12 +9184,10 @@ o2mep
o2meru
om1erz
omie4t1
-omil3l
o2m1ind
om1ing
o3mini
om1int
-omi3te
om3ma
om3me
omme4r
@@ -9109,6 +9196,7 @@ om3pf
omp6l
oms2
om3sp
+om1st
o4m3un
o5m4ung
omy1
@@ -9120,22 +9208,24 @@ o3nal
on3ap
o2n3ar
on4are
+on4at
on3aus
2o3nä
onbe3
2onc
2one
on4eh
-one2n1
+on4e2n1
onen3g
+onens2
o2n1erb
on1erd
on1erö
o3nett
on5f
-ong4
+4ong4
on3gl
-ong7sc
+ong5sc
ong5st
4o3ni
o5ni.
@@ -9144,20 +9234,22 @@ o4ni4kr
o4n1im
on3ing
on5k4
-onli4n
+onli4
onlo2c
on3nan
o3no3
o4noke
on1orc
-ons1a2
-ons3as
-on2seb
+on4os
+on2s
+ons3a2
+on3sch
+on4seb
onse2l
-onsi2d
-ons3l
+onsi2
ons1p
-on3t2a
+ont2a
+ont3ant
on6t5end
ont5erw
on2t1ri
@@ -9166,6 +9258,7 @@ on5v
1ony
on5z
o1ñ
+oof4
oo2k
ook3l
o1op
@@ -9173,12 +9266,13 @@ o1or
oor3f
oo4sk
oo2tr
-oot4st
+oot2st
2o1ö
o1pa
opa1b4
o2p3ad
op1akt
+opa5st
o1pä
o1ped
o1pei
@@ -9225,7 +9319,7 @@ o2ranh
orani1
or3arb
o1ras
-or3att
+or3au
o3r2ä
or3änd
or3ät
@@ -9233,7 +9327,7 @@ or2bar
or1c
2orca
or2ce
-2or2da
+4or2da
ord1am
ord3ele
or4d3eng
@@ -9242,10 +9336,11 @@ or2d1ir
1ordn
or2do
2ords
+ord3s2t
2ordw
4ore
ore4a
-o2r1eck
+o2r1e2ck
o5ree
o2r1ef
ore2h
@@ -9255,7 +9350,7 @@ o2r1er
or3eth
2orf
or2fle
-or3g4a
+or3ga
2orget
or3g2h
2orgia
@@ -9265,18 +9360,18 @@ or3gle
o1ri
2o3ric
o3rier
-4o5ril
+4oril
4orin
or1ins
2orit
-o5riz
or3k2a
or4k3ar
-ork1s
+ork2s
2orm
or2mor
or3na
or3n2o
+orn3st
2o1ro
or3oly
oro3n4a
@@ -9284,24 +9379,25 @@ oro3n4a
2orq
2orr
or3rh
-2ors4
+2ors2
or5sa
+ors4c
orsch5li
or3sh
or3sz
or2ta
or3tad
or4t1ak
-ort3an
+or4t3an
ort1au
ort3eig
ort3ein
+or4tem
or4t3ent
or4t3ere
or4t3erf
or4t5ev
or4the
-or3ti
or4tin
ort3ins
or4t3off
@@ -9310,7 +9406,7 @@ or4t3rau
or4t3räu
ort3re
ort3ric
-ort3sc
+ort5sch
or2t1um
o3ru
or2uf
@@ -9319,16 +9415,15 @@ o5rus
or3ü
2orw
o2rya
-o1s
o3s2a
os3ad
os4an
-os2c
-2o3s2e
+osa3s
+os4co
+2o3se
ose3ei
-o4s3ei
+o4s1ei
ose2n
-o2sé
o3s2hi
o3sho
2osi
@@ -9342,38 +9437,38 @@ os2lo
o2s1p
o4sper
o3s2po
-os2s3a
-os2sä
-os2seg
-os2sei
+os2sa
+oss3and
+os4sä
+os5se.
+os4sei
oss3enk
-os3sent
+os5sent
oss3enz
-os2seu
os4s3o
os4s3p
-os6st
+os4st
oss1ta
-oss1to
oss1tr
-os2t
-o4s4t1a
+o2st
+os4t1a
+os5ta.
osta2b
-o5stal.
-o4sterd
+os5tali
+os5tarr
+os2tau
oster3e
-ost5er6we
-ost3h
-o5stie
-o4stin
-ost1ob
-os3ton.
-o5stons
-o4st3rä
+os6t5er6we
+ost1h
+os3til
+os1to
+os2t1ob
+ost3rä
ost3re
ost3rot
ost1uf
osu4
+o1sy
o3s2ze
o2ß1el
o2ß1enk
@@ -9381,30 +9476,28 @@ o2ß1enz
oße2r
o2ß3ere
o2ß1erf
-oß3th
2o1t
ota3m
o3tark
o2t1au
ot3aug
-otau6s
ot1är
-4ote
-o2teb
-o3te1i
+4o3te
+o4teb
+ote1i
ote3i6n
ote4l1a
ot4em3
otemp2
-o2t1erw
+o4t1erw
4oth
ot2he
ot3hel
o4t1hi
ot1hos
o4thr
-ot2i
-o2t3i2m
+o3t2i
+o4t3i2m
o4tl
otli4
4oto
@@ -9417,9 +9510,7 @@ ot3rut
ots1p
ot4spa
ot3spe
-ots2t
-ot5stra
-ots3tri
+ot3stra
ot2tau
ot3te
ot4t3erk
@@ -9436,22 +9527,19 @@ o3uh
ou4le.
o3um
o3unds
-oung5
oun4ge.
-oung7s2
-ouri4e
+ouri4
our6ne.
+our3st
ou3s2i
-ou5s2t
-ou3te
outu4
2o1ü
o1v
+ove3s
oviso3
2o3vo
2ow
o1wa
-owa5re
o1wä
o1we
o3wec
@@ -9465,6 +9553,8 @@ o1xo
o2xu
1oxy
o1yo
+oys2
+oy3st
2o1z2
oz4e
o3zi
@@ -9474,15 +9564,14 @@ ozon3a
öbe4li
ö2ble
ö2b3r
-2öc
-ö1ch
+öb2s5
+2ö1c
ö4ch3l
ö2chr
-öchs2t
-öch4str
-ö4cht4
+öch2s
+öchs4tu
+öcht4
ö1d
-ödel5l
ödi3en
ö2du
ö1e
@@ -9499,13 +9588,11 @@ ozon3a
öh3l2e
öh3m
öh1ri
-öh2s
ö1hu
ö2k
ö3ke
-öko5
+öko3
ök3r
-ök2s
ö6l
3öl.
öl1a
@@ -9516,24 +9603,25 @@ ozon3a
öl1im
öl1in
öl2k5l
-öl5la
+öl3la
öl4nar
öl1o2
-öls2
öl3sa
-öl3sz
+öl3s2z
öl1u
öl2ung
öl3z2w
-öm2s
2ön
ön3d
ön2e
ö3ni
+ön2s
+ön3sc
öo1
ö1pe
öpf3l
-ör3a
+öp2s3t
+ör3a2
ör1c
örden3
ör2dr
@@ -9550,22 +9638,22 @@ ozon3a
ör1o2
örs2e
ör3sk
+ör2st
ör2tr
ö1ru6
ö2r1une
-ö1s
ö2sa
ö2sc
ö4sch3ei
ösch3m
-2ö5se
-ö6s1ei
+2öse
+ö2s1ei
ö2sp
-ös4s1c
-ös4st
-ös2t
-ö4sta
-ö5stet
+ös4s3c
+ös2st
+ö2st
+ös3te
+ös1tr
ö1ß
2ö1t
ö2t3a
@@ -9578,7 +9666,7 @@ ozon3a
öwe4
ö1z
öze3
-özes4
+özes2
4p.
1pa.
1paa
@@ -9590,13 +9678,12 @@ pa3g2
pa1ho
1pak
pa1kl
-pak2to
1pa1la
pala3t
1palä
pa5li
2palt
-p4an
+p2an
pa2nar
pan3d
pan4ds
@@ -9605,13 +9692,15 @@ pa2neu
pan3k4
2panl
3pano
+pans4
pan3sl
3panz4
-1pap
+3pap
papie8r7end
-1parad
+3parad
pa2r3af
par3akt
+pa5reg
2par2er
2parg
1park.
@@ -9625,8 +9714,14 @@ pa2ro
1partn
1party
par3z2
-pa3s2p
-pa2ßu
+pa4s
+pa5sa
+pa5sc
+pa5se
+pa5si
+pa5s2p
+pa5str
+2paß
p4at
pa5ta
pat4c
@@ -9636,27 +9731,29 @@ pat2e2
1pau3
p1auf
pa3uni
+pau4st
+pä2
1päc
+pä3cke
1päd
+pä3de
1pärc
+pä3ß
pä4t1e2h
pä4t3ent
pät1h
-pä2to
-pät5s
+pät3s
2p1b
-pbe1
2p3c
4p1d
-pda2
+pda4
1pe.
pe4a2
pea4r
1ped4a
-peed3
+peed1
2pef
pei1
-4peic
pe1im
3peit
2pek
@@ -9667,36 +9764,31 @@ pel5d
pe2let
pe3lin
pe4l3ink
-pel5lä
-pel3l4e
-pel3li
-pel3to
+pell4e
1pem
pena6
pe3n4al
pen3da
pe4nen
1penn
-pens2
3pensi
1pensu
pe2nu
pen3z2
pe1ra
per4an
+pere2
1perle
per6na
perne4
-per4ra
-perr3an
-per2rä
-per4rie
+per4r3a
5pers
-perwa6
+perwa4
pe3sa
pes4e
pese2n
-pes5s4
+pes5s2
+pe2st
3pet
1pé
2pf
@@ -9742,13 +9834,13 @@ pf3th
pgra2
1ph
4ph.
+ph2a
2phab
2phä
2phb
4phd
2p1hei
-phen3d4
-phen3s
+phen3
2ph1ers
2phf
4phg
@@ -9766,18 +9858,20 @@ ph4r
phu4s
4p1hü
2phz
-pi4a5
+pi4a3
+pia5l
+pia5s
pi3chl
p4id
pie3fr
pi2el
pie4la
-5pi2er
+3pi2er
1pil
pil4zer
pi2na
pin2e
-ping5s
+ping3s
3pinse
pi2n1u
pi2o
@@ -9787,9 +9881,8 @@ pi2pe
pi5ri
1pis
2piso
-pis2t
-pi5sto
pit2a
+pi1th
pit2s
pi2z1in
p1je
@@ -9810,10 +9903,9 @@ p4leg
p5lic
p5lif
4plig
+p4lis
p4lo
-plü2
2p1m
-pma1
2p1n
1p2o
po3b4
@@ -9821,11 +9913,11 @@ po1c
2p3oh
po2i
po3id
+3poin
3pol
po2lau
po5li
po3ly
-pont4
po1ob
po2p1ak
po2p1ar
@@ -9837,15 +9929,19 @@ po1rau
2porn
por5s
por4tri
-po5s4e
+po5s2e
po3sp
+po4sta
post3ag
po4stä
-po4st3ei
+post3ei
+po4sti
+po3s4tr
post3ra
po3ta
3pote
pot2h
+3poti
po2t1u
po2w
po1x
@@ -9853,9 +9949,10 @@ pö2bl
pö2c
4p1p
p2p1ab
-pp5anl
+pp3anl
p3pe
ppe1e
+ppe4ler
ppe2n1
pp1f4
p2p1h
@@ -9867,11 +9964,11 @@ pp4li
p2p3ra
p2p3re
p2pri
-pps2
pp3sa
pp3sp
ppt2
pp3ta
+pp3to
p2r2
3prak
3prax
@@ -9887,32 +9984,32 @@ pre2e1
3preis
2p3rer
3pres
-1preß
pri4e
1prinz
2prit
-1p4ro1
+1p4ro
3prob
pro3be
2proc
3prod
3prog
3proj
+pro3st
3proto
1prüf
2prün
2ps
4ps.
-ps4an
+ps2an
p3s2h
4psi
p2s1id
p2s1ö
-ps2t
-p5ste
-p4st3r
-p2stu
-ps3tur
+ps2po
+p3stea
+p1s2ti
+pst3r
+ps2tu
3psy
ps2ze
2p1t
@@ -9932,7 +10029,8 @@ p4t1erw
p4t1erz
p5tes
p2t1h
-pt1in
+p3ti
+p4t1in
pto5me
p2tos
p2t3r
@@ -9944,7 +10042,6 @@ pt3st
pt3su
pt3t
pt1um
-p3tung
pt1urs
p2tü
3p2ty
@@ -9958,12 +10055,14 @@ pul4sp
1pulv
1pum
1pun
-2pund
+4pund
pun2s
2punt
1pup
pu3ri
-pu2sc
+pur3st
+pu2s
+pu4s3t
1put
3put2s
3putz
@@ -9971,19 +10070,18 @@ pu2sc
2pül
2p1v
2p1w
-3py1
-py3t
+pwa4r
+3py3
4p1z
q2u4
3quen
que3rel
1queu
-qui5s
6r.
1ra.
ra2ab
-2r3aac
-r3aal
+2r5aac
+r5aal
ra1ar
r1ab
ra2bar
@@ -9993,15 +10091,19 @@ ra3ber
2rabf
2rabg
r4abi
-ra1b4le
+ra1bl
+rab4le
+ra2bli
+rab5r
2rabs
2rabt
-2rabw
+2r3abw
1raby
ra1ce
2r1acet
ra3che.
ra4cheb
+ra3chen
ra3chet
rach4t3r
ra2chu
@@ -10013,7 +10115,7 @@ ra2dam
ra3di
3radle
ra4d3r
-rad3t
+rad5t
1rae
ra1er
r2af
@@ -10063,8 +10165,9 @@ ram6m5ers
ram4m3u
r3amn
ram2p3l
+ram3ste
2r3amt
-ramt4s
+ramt6s
r2an.
4ranc
r2and
@@ -10075,7 +10178,7 @@ ran4d3er
4r5anei
2r3anf
1rangi
-4ranl
+4r3anl
2r1anm
r1anp
2ranr
@@ -10100,7 +10203,6 @@ ra4schl
r4at.
ra2ta
ra2t1ä
-ra3te
2ratm
rat4r
2ratta
@@ -10118,12 +10220,10 @@ ra3umsa
2rausg
rau4sp
raus5se
-raus3tr
+rau4sti
raut5s
1raü
r2ax
-raxis1
-räch4s
r2äd
4räf
4räg
@@ -10134,8 +10234,7 @@ r2äd
2r1är
rä3ra
r3ärz
-rä4s1c
-rä4st
+rä4s3c
3rätse
rä2u
4räut
@@ -10160,27 +10259,29 @@ r2b5le.
rb5ler
rb2o
rb3res
-rb4ri
+rb6ri
rb2s
+rbs1a
rb4sei
rb4ser
rb3ska
rbs1o
-rb6stä
-rb5ste
+rb4stä
+rb3str
4rc
r1ce
+rcha2
r1che.
r1chen
r1chi
rch3l
-rch5lö
rch3m
rch3r
-rchs2
+rch1s4
rch3sp
rch3ta
rch1w
+r2ck1
r1cr
r1ç
2r1d
@@ -10197,25 +10298,23 @@ r2d1elb
rde7me
r3den
rde5nar
-rdend4
rden4gl
rde3r2e
r4d3ernt
-rdes4
rde3sp
-rdga4
+rde3sta
rdi3a2
rdi5a6l
r2d1inn
r2d1it
rd1os
-rdo4st
rd1ös
rd3rat
rd3rau
+rd1st
rdt4
+rd1th
rd1tr
-rdwe5ste
1re
3re.
re3ad
@@ -10232,6 +10331,7 @@ re2bü
rech3ar
4rechs
2reck.
+re2cka
3reda
4redd
3rede.
@@ -10242,8 +10342,9 @@ re3er
4reff
3refl
3refo
-3refr
+3refro
3reg
+5reg.
rege4l3ä
re2gl
4reh
@@ -10265,7 +10366,6 @@ rein6sta
rein8s7tre
re1in2v
2reis.
-reis5tro
2reiwe
re2ke
re3la
@@ -10290,7 +10390,6 @@ re4n3end
ren4gl
2rengp
re2ni
-ren4nes
2r1entl
2r1ents
2rentw
@@ -10338,16 +10437,15 @@ r1er5t
2r1erz
3r2es.
re2sa
-res3au
+res1au
3rese
3resol
re3sp
2ress
ress2e
res6s5erw
-re4stu
+re2stu
3resu
-4re2ß1
re2thy
re2u
reu3g2
@@ -10358,27 +10456,26 @@ re3uni
r1e2w
rewa4
re3we
-re3wo
4r3e2x1
3rez
4rezi
1ré
2r1f
-rfall6s
rf1ält
r2fent
r3f2es
rfi4le.
+rfin6s
rf3lic
rf3lin
r3flü
r3fre
-rf2sa
-rf2s1ä
-rf2se
+rf2s
+rfs1ä
rf3sen
rf4s1id
rfs3pr
+rf3sto
rf2ta
rf3tau
rf3t4r
@@ -10388,7 +10485,6 @@ rg2ab
r2g1ah
r2g1ak
rg2an
-rga5ste
r3ge
rge4an
rge2bl
@@ -10397,7 +10493,6 @@ rg5e4tap
r4geto
rgi4sel
r2glan
-rgleich8s
r2gleu
r2glig
rg3lo
@@ -10411,7 +10506,8 @@ r2g3res
rg3ret
rg3rin
rg3s2p
-rgs2t
+rg3str
+rgt4
rg3th
r1h4
2rh.
@@ -10435,10 +10531,9 @@ ri1cha
rich3te
4rick
rid2
-ri2dan
+ri2d3an
2ridol
r2ie
-rieb4st
ri1el
ri3els
riene4
@@ -10447,29 +10542,30 @@ rie2nu
ri1er.
ri4e3re
ri3ers.
-ri3e4sti
+ri3esti
rie5te
ri1eu
-ri2fa
+ri2f1a
ri4f1ei
ri4fer
ri2f1o
ri2f5r
+rif3st
rif4ter
-3r2ig
+3rig
ri4g5ene
+4rigg
5rigj
rig1l
4rigr
-rigs2
r2ik
ri4k5l
ri5kle
ri3ma
r2imb
2rimp
-rim4s
-rim6sc
+rim2s
+rim4sc
rin4a
2rind
ri5n4e
@@ -10502,22 +10598,22 @@ ri3so
ri4s3p
3riss
ris4sa
-rist5ers
-ristes4
-3ri2ß1
+ri4st
+ris6t5ers
r2it
r3i2tal
-ri3ti
-rit4r
+riten3
+ri5ti
+ri3t4r
5ritu
ri2x1
-4riz
1rí
2r1j
2r1k
rk1all
rk1aus
rk1äh
+rke2s
r3kla
r5klau
rk3li
@@ -10531,11 +10627,12 @@ r2k3rea
r3kri
rk3rin
rk2s1e
+rk3sen
rk3shi
rk2sp
rkstati6
rk4stec
-rks1ti
+rks3ti
rk2ta
rk4t3eng
rk4t3erf
@@ -10544,43 +10641,41 @@ rk4t3erw
rk2tin
rk2t1o2
rkto4b
-rk2t3r
+rk4t3r
+rk5tra
r2k1uh
rk2um
rku4n
rk1uni
-rku6s5t
2r1l
r3la
r3le
rle2a
r3l2i
-rlös5s
+rli2s
+rlon3
+rlös3s
rl2s1p
-rl4s1to
+rl2sto
rl3th
-rlu4str
4r1m
r2m1ald
-rm1ans
+r2m1ans
rm3anz
r4m3a2p
-r5mapp
rm1aus
rm3d
r3me.
r2m1ef
rmen4sc
r2meo
-rm2es
r2mide
r2m1im
-rmi3te
rm1ope
rm1o2ri
+rmo3s
rm3sa
-rms2t
-rm5sta
+rm3sta
rmt2
rmt3h
rm3ums
@@ -10595,8 +10690,9 @@ rn3are
rn5ari
r2n3au
rn4aue
+rnd4
rn3do
-rn3d4r
+rn3dr
r3ne
r5ne.
rn3e4ben
@@ -10612,7 +10708,7 @@ r4nerg
rn4erhi
r4nerk
r4n1ert
-r5nes
+r5ne2s
rn4e2t
r4nex
rn3g2
@@ -10636,7 +10732,7 @@ ro4bei
2robj
1robo
2robs
-ro1ch
+ro1c
3rock.
r4o3de
r4odo
@@ -10648,36 +10744,41 @@ roh5n
3r2ohr
3roi
ro3in
+ro1ir
ro3le
-rol3l4en
+roll4en
2roly
ro2mad
ro2mer
4romm
r2on
+ronen3
3ronn
rons2
+ron3sp
+ron3str
ron4tan
ro1ny
ro1pe
2ropf
ro3ph
+rop2s
r1or
-r2ora
-ror3al
+r2or3a
ro2rat
+ro1rau
ro2rei
ro2r1o
ror5th
-ro3sé
+ro1sé
ro3sh
ro3s2i
ro5sk
ro3smo
ro3sp
-ros4s1c
-ros4sie
-ro4str
+ros4s3c
+ro4ste
+4roß
ro2ßu
ro2tho
ro2tri
@@ -10700,6 +10801,7 @@ rö7le
r1ör
r2ös.
rö3sc
+rö3se
3rötu
2r3p2
r5pa
@@ -10708,47 +10810,51 @@ rpe2re
rpe4r3in
rpf4
r4pli
-rpo4str
+rpo4st
+rpro1
r4ps
rp3se
-r4p3t
+r4pt
r1q
4r1r
rr2a
r3rar
-r5räh
rr1äm
rrb2
rr1c
r3r2e
rrer4
+rre2st
r4rew
rr2h
rr3hö
-r5ries
rri3k
rr2na
rr2o
r2r3ob
rro3m
+rr2st
r3ru
r5rü
rrü1b
4r1s
-rs2a
-r4s3ab
+r4sab
r2s3a2d
rsa4ler
r2s3amp
r4s3amt
-r4s3ang
-rs3anp
-r4s3ar
-rsch2e
+r4s1ang
+rs1anp
+r4sar
+r3sc
+r5sch2e
r6scherl
rsch4l
-rs1ebe
-r2s1ein
+r5schu
+r3se
+r5sei
+r6sein
+r5sel
rse3le
rse2n
rs2end
@@ -10759,7 +10865,7 @@ rs1ers
rs1erz
rs1eta
r3sho
-r3si
+r5si
rs2ka
r5skal
r5skan
@@ -10771,24 +10877,30 @@ r4skr
r4sku
rs3l
rs4no
-r2s1op
+r3so
+r4s1op
r4s3ort.
r3s2p
r4s3ph
-rs5s2
+rs3s2
+rs2t
r4stant
-rs2tau
-rs2te
rst5eing
-r4st3erw
-rs2th
-r4stin
+rs4temp
+r3sterb
+rst3erw
+r3stie
+r2stin
rst3ing
-r5s2tob
-r4s1tot
+r3sto
+r4stot
+r3str
r4st3ran
-r5s2wi
-6r1t
+r3stu
+r3stü
+r3s2wi
+r3sy
+4r1t
r3tab
rt1ac
r2tad
@@ -10799,10 +10911,8 @@ r4t1alm
rtals1
rt1am
rt1an
-rt3anz
rt1ar
rt3a6re
-r3tas
r3tat
r2t3att
rt1auf
@@ -10812,10 +10922,12 @@ r5te.
rtee2
rt2ei
rtei3la
+rtei3s2
rte5m4e
rte2n1
r7ten.
-r5ter.
+rtens2
+rten3st
rte1ra
rte4ran
rt3erei
@@ -10826,7 +10938,6 @@ r5terli
r4t3ernä
rter4re
r4t3ersc
-rtes2
rte3sk
r2th
rt1he
@@ -10835,36 +10946,38 @@ r3tho
rt1hol
r3thu
r3thy
+r3ti
r4t1id
r4t1ima
rt1int
-rt5le
rto3p
r2t1o2r
+r4trak
rt3rec
-r4treis
r2t3res
+rtrü2
rt4sam
-rt5scha
+rt3sch
+rt7scha
rts1eh
-rts1ei
rt3spe
rtt4
r2t1urt
r3tün
-rt5w
+rt3w
r3ty
rt3z2
ru1a
ru3a2r
rube2
+ru3cker
+ru4cku
ru3de
rude2a
ru2dr
3ruf
ru2fa
ruf4s
-ruf5sc
4rug
2ruhr
5ruin
@@ -10904,13 +11017,15 @@ r3ur1e
5ru3ro
ru2si
rus2s1p
-rus6st
+rus4st
+ru4st
+ru5s2ta
ru2th
rut1he
ru2t1o2
ru2t3r
rut2s
-4ruz
+6ruz
ru2z1w
r2ü
4rüb
@@ -10920,15 +11035,13 @@ rü1ch
4rümm
2r1v
rve4n1e
-rv2s
2r1w
-rwa5re
4r1x
1ry
ry2c
ry3t
2r1z
-rz1ac
+rz1a2c
rz2ach
rz2an
r2z1ar
@@ -10950,27 +11063,27 @@ rzu3g2u
rz1urs
r3z2wä
r3z2wec
-8s.
+6s.
1sa
5sa.
-5s4aa
+5saa
2s1ab
sa2be
3sabet
sa1b4le
4sabs
-sa3che
-sacho6
-sa3cr
+sa2chi
+sa2cho2
+sa1cr
2sada
s3adm
2s3adr
sa3fa
sa4fe
-4s3aff
+4s1aff
sa1f4r
3sag
-s3a2gr
+s1a2gr
5s4ai
sa1ik
sail4
@@ -10978,63 +11091,57 @@ sail4
sa2ka
3saki
s4akr
-4s3akt
-3sal.
+4sakt
+3s2al.
3s2a1la
sal3erb
sa2l1id
-s1all
5s4alo
sal2se
-6s1alt
+4s1alt
5s4alz
-3sam
-5sam.
-5same
+3s2am
s3ameri
-5samf
-5samk
5s4amm
6s5amma
-4s1amn
+4s3amn
4samp
-5sams
-5samu
-s1an
-3s4an.
-2s3a2na
-2s3anb
+3s2an.
+2s1a2na
+2sanb
s2an2c
s2and
san4d3ri
-5sang.
+3sang.
2s3anh
-3sani
-2sanl
-2s3ans
+5sani
+2s3anl
+2s1ans
san4sk
san3sp
-4s3anw
+4sanw
2s3anz
2s1ap
sa2po
3sapr
2s1ar
-3s4ar.
+3sar.
3sara
-4s5arb
+4s3arb
3s2ard
3sari
-s3arl
s3arm
s3arr
-3s4ars
-4s3art
+3sars
+4sart
+s3arz
s3a4sp
+sa3stu
6s5asy
+s2aß
3sat
sat2a
-5sa3te
+5sate
4s3ath
4s3atl
4satm
@@ -11043,57 +11150,54 @@ sa3ts
5satz
sat4z3en
sat4zer
-s1au
3sau.
3saue
2sauf
-4s5aufb
+4s3aufb
3saug
sau2gr
3saum
+5saur
sauri1
-2s3aus
-4s5ausb
-3s4ause
-s3auß
+2s1aus
+4s3ausb
+3sause
+s3ausf
+s3ausg
+s1auß
sa2vo
-3sax
+3s2ax
3say
1sä
-3säb
3säc
s3ähn
3säle
s1ält
2s1äm
-2s1änd
+2s3änd
3sänge
2s1är
-sä2s
3sät
3säul
2säuß
-6s3b4
+4s5b6
sba4n
sber2
sbe3re
-sby3
-1sc
+sby5
+1s2c
2sc.
-s2ca
-2scam
6scar
-2s1ce
+4s3ce
6sch.
-7s2ch2al
+2schak
+5s4ch2al
4schanc
-7schanz
+5schanz
6schao
-s2chau
-s2chä
-3schäd
+5s4chä
4schb
-2schc
+4schc
3sche
4schef
sch3ei.
@@ -11103,65 +11207,70 @@ sch5erla
4schess
4schex
4schf
-2schg
-2schh
+4schg
+4schh
3schi
+7schic
schi4e
s4chim
4schiru
4schk
+s4chl
4schle.
6schlein
sch6lit
4schn.
-s2chö
-2schp
-2schq
+5s4chö
+6schöl
+4schp
4schre.
sch5rom
-6schs4
-sch3sk
-sch5ste
-sch5sti
+6schs
+schs4e
+sch3s2k
+sch3sti
6scht
sch3t4a
sch5te
3s4chu
4schunt
sch2up
-2schv
+5schü
+4schv
4schwet
-2schz
-s2ci
+4schz
2scj
-6scl
-6sco
-7s2cop
+4scl
+4sco
+5s4cop
2scs
2scu
-4s1d
-s3da
+4s3d
sda3me
-s3do
+sde3s
+sdi1st
1se
-3se.
se3a
se4al
se5al.
se5at.
-2s1e2ben
+4s1e2ben
se3b4r
2sec
4s1echo
-4s1echt
-3secl
-3seco
-2sede
-5see
+sech2s
+s1echt
+se2ck
+5secl
+5seco
+4sede
+7see
se1ec
se2e1i4
+see3ig
se1er
2s1eff
+3seg
se2gal
se2gl
seg4r
@@ -11175,27 +11284,26 @@ se4hin
seh1l
seh1ra
seh3re
-seh3s
+seh1s
se2hü
2s3ei.
3sei3b
-2s1eig
-5s4ein.
-2s1einb
-s1eind
+4s3eig
+s1ein
+7s4ein.
+4seinb
sei5n4e
-2seing
-2s1einh
-4s1eink
-4seinl
-2s1einn
-2seinr
-s3einsa
-s3einsä
-4s3einst
-2s1einw
-2seis
-7s4eit
+4seing
+2s3einh
+4s3eink
+2seinl
+4s3einn
+4seinr
+s4eins.
+4seinst
+2seinw
+4seis
+7s2eit
5s2ek
s2el.
se2l1a2
@@ -11203,7 +11311,7 @@ se3lad
sela4g
se3lam
sel1ec
-2selem
+4selem
se2ler
sel3erl
sel3ers
@@ -11212,27 +11320,26 @@ se4l1ö
s2els
sel3sz
sel3tr
-3sem.
-se3ma
-2s1emp
-5s2en.
+5sem.
+s4e3ma
+4s1emp
+s2en.
3sena
se4nag
se3nal
-2s1endl
+4s1endl
se4ners
sen3gl
-7seni
+5s4eni
sen3ob
3s2ens
-sen6stri
s2ent.
-2s1entf
-6s3entg
+4s1entf
+2s3entg
s2enti
4s3ents
-2sentw
-4sentz
+4sentw
+2sentz
se2n1u
seo2r
4s1e2pos
@@ -11245,77 +11352,81 @@ s3ereig
se4r3eim
se4r3enk
ser2er
-2s3erfo
+4s3erfo
s2erfr
-4s3erfü
+6s3erfü
ser3g
s1ergä
s2ergr
-2s1erh
-3seri
+4s1erh
+5seri
s1erkl
s1ernä
-2s3ernt
+4s3ernt
se1rot
-2s3eröf
s2ers.
s4ert.
ser3the
seru2
se4r1uf
se3rum
-5s6erv
+7s6erv
5ses.
se3su
3set
s3eta
-4se2tap
+4s5e4tap
se2tat
4s3e2th
-5setz
-3seum
se1u4n
-2s1ex
-se2xe
+2sex
+4sexa
+s1e2xe
4sexp
sex3t
-6s3f
+4s3f
sfal6l5er
+s5fi
sfi3le
+s5fü
4s3g4
-sges4
-sge3sa
+sge3s4a
2s1h
3sha.
sha2k
4shan
+1shas
+s3hä
3shi.
3shid
1shi4r
sh3n
+s3hoc
4shof
-3shop
-sho6r
-5show
+3s4hop
+sho4r
+3show
+s3hö
sh4r
-s3hü
1si
si3ach.
5siak
si1am.
-2siat
si3b4
3si1c
s1ideo
s2ido
3s2ie
+siege4s
si3ene
si3err
+sie2s
3si1f4
-5s2ig
-si2g1a
+5sig
+si2g1a2
si3g4n
si2g3r
+sig4s
si2k1ab
si4k3ere
si4k3erl
@@ -11328,37 +11439,37 @@ si2ku
si5l2e
3silo
2s1imm
+3sin.
si3n4a
2s1ind
-4s1inf
+6s1inf
sin2g1a
sin3gh
sin3g4l
sin2gr
-sing5sa
-4s1inh
-sin1i1
-3sinn.
-3sinnl
+sing3sa
+6s1inh
+sin1i
+sini1e
2s1inq
2s1ins
2s1int
-4s1inv
+6s1inv
3s4io
si3od
si3os
-3s2is
+5s2is
si2sa
si4schu
-si2s1e
+si4s1e
si2s1o
sis1p
-sis5s
-si2stu
-3s2it
+sis3s
+7s2it
si2tau
+si3te
si2t3r
-sit5s
+sit3s
si3tu
5siu
si2va
@@ -11368,18 +11479,24 @@ six3
2s1k4
4sk.
s3kad
-4s3kam
-4skanz
-4s3kas
+s2kala
+4skam
+4s3kanz
+s3kar
+4skas
ska4te.
ska4tes
+s3kä
4skb
4ske
3s2ki.
3s2kik
4skir
+ski3s
3skiz
s3klas
+s3kn
+skna3
4skom
4skor
4skö
@@ -11388,8 +11505,9 @@ s3kra
4sk5t
3skulp
2s1l2
-3slal
+3s4lal
4slan
+s3lä
sl3b
s5le
s5li
@@ -11397,8 +11515,7 @@ s5li
s3lo.
slo3be
s3loe
-2s1m2
-s3mu
+2s3m2
2s3n2
4sna
sna1b4
@@ -11407,10 +11524,13 @@ sni3er.
sni3ers
4s5not
4snö
+s5ny
1so
3so.
3so4a
-2s1o2b
+4s1o2b
+6sobj
+so1c
so3et
3soft
3sog
@@ -11418,7 +11538,7 @@ so3gl
so2h
s1ohe
so3hi
-6s5ohng
+4s5ohng
so3ho
2s1ohr
3sol.
@@ -11437,13 +11557,12 @@ s1opf
3sor.
so1ral
s1orc
-2s1ord
+4s3ord
so2rei
so3ren
-2s1orga
-2s1o2rie
+4s1orga
+4s1o2rie
so2r1o
-5sorp
3sors
so4ru
3s2os
@@ -11456,11 +11575,13 @@ so3unt
3sov
s1o2ve
s1ox
+s4oz
1sö
+sö2c
sö2f
2s1ök
2söl
-s1ö4s
+s1ös
1sp2
4sp.
4spaa
@@ -11471,14 +11592,14 @@ spani7er.
4spano
4spap
4spara
-2sparo
spar5sc
-3s4paß
+3spaß
+2spat
2spau
s2paz
-4spär
+2spär
2sped
-s2pee
+3s2pee
3s2pei
4spel
2s1peri
@@ -11492,11 +11613,11 @@ s2pee
3sphä
s3phe
3spi
-5s4pi4e
+5s2pi4e
7spiel
spier4
spi2k
-6s3pil
+4s3pil
4spip
4s3pis
2spl
@@ -11511,15 +11632,13 @@ spi2k
4s3pok
4spol
4s3pos
-s2pott
4spr.
-3s2prac
+s2prac
4sprax
4spräm
4spräs
5s4prec
2spred
-4sprei
4spres
2spro
4sprob
@@ -11528,296 +11647,292 @@ s2pott
2sprüf
3sprün
4s3ps
-2spun
+4spun
2spup
5s2pur
4sput
3spü
4spy
2s1q
-6s3r4
+4s3r4
srat6s
sret3
-sro3m
srö4s
-srös1c
+srös3c
srü2d
-6s1s
-ss2a
-ss3ab
-ssa3be
+4s1s
ssa3bo
-ss1ack
-ss4ag
-ss3aj
-s3s4al
-s4s5ala
-s4s5alb
-ss4am
-s4s5ang
-ss3ano
-s4s5anz
-s3s4as
-ss3auf
-ss2ä
-ss1ech
-ss1eck
-ssee2
-s2s1ega
+ss1a2ck
+ss1aj
+s3sal
+s4s3ala
+s4s1alb
+s4s1amt
+s4s3ang
+ss1ano
+s4s3ans
+s4sanz
+s3sas2
+ss3att
+ss1au
+s3s2ä
+s3se
+s4s1ec
+sse4ck
+s4s1ega
sse3ha
-ss1ein
sse3inf
sse3int
ss1eis
+s5sen.
ss2er
-s3ser.
sse6r5att
-s3serh
ss3erhö
+s4s3erö
s4s3erse
s5s4es
ss4et
sse3ta
+ss5g
+s5sie
s3skala
+ss3la
ss1off
-s4s1op
+s6s1op
s2s1ori
s3spe
s3s2po
ss5re
-ss3s2
-s5st2a
-s7stad
-s5stä
-ss1t6e
-s4ste.
-s5stel
-ss2th
-s5stil
-ss1tis
-s5sto
-s5stu
-s5stü
+ss3s4
+s3st2a
+s5stad
+sst6e
+ss3tec
+s3stel
+ss2ti
+s3stip
+s3sto
+s3stu
+ss2tur
+s3stü
ss1ums
-ss2zen
-1st
-6st.
-3sta
-s4ta.
-5staa
-4stabb
-4stabh
-4stabl
-stab6s
-4stabt
-4stabz
-5s4tad
-6stada
-6stadr
+4st.
+1sta
+2sta.
+3staa
+stab4s
+3s2tad
5staff
-6stag
-5stah
-4stak
-4stal.
-5sta5li
-4stalk
+4stag
+3stah
+2stak
+s5tal.
+sta5li
+2stalk
st1alp
st3ami
-4stamt
+4stan.
st3ana
-5stand
-4stanl
-6stann
-4stanw
-5star.
-5stars
-5st2art
-sta2s
+3s4tand
+2stani
+4stann
+2stans
+s3tans.
+2stanw
+s2tar
+3s4tar.
+3s4tars
+st2art
+2sta2s
st3a4si
-5stat
+3stat
4stat.
-s2tati
-5stau.
-5staub
-4st1auf
-4staum
+3stau.
+2st1auf
+2staum
5staur
-4staus
-5staus.
-4stax
+2staus
+3staus.
+2stax
3stä
4stäg
4stält
-4stämt
-5stär
-2stäti
5stätt
-4stäus
4stb
2stc
st3ch
2std
-3ste
-4stea
-5stean
-7steck
-4stee
+4ste.
+2stea
+s2tec
+3steck
+1s2teg
ste2g5r
-ste2i
-5s4teig
-6steil
-s4tein
+3steh
+1s2te2i
+3steig
+2steil
4steing
-s2tel
-s3telem
+1s2tel
+2stel.
+2stele
stel4l3ä
+2stels
+2stem
+4stem.
ste4mar
-4stempf
-4st3ends
+4sten
+s4t3ends
ste2ne
-st3engl
-st4ens
-6st3entf
-4stentw
-4stepi
-5st6erb
-st2erg
-5sterj
-s2tern
-s2ters
-6st3ese
-4stesse
-ste4stä
-4stests
-5steß
-s2teu
+s4t3engl
+s5t4ens
+s4t3entf
+s2tep
+2ster
+6ster.
+s3tera
+st6erb
+4sterk
+3sternc
+s3ters
+4stes
+s4t3ese
+stes6se.
+ste4st
+2stet
+4stet.
+3s4tett
+3steu
+5steue
4steuf
st3ev
-6stex
-4stf
-4stg
-6sth
+4stex
+2stf
+2stg
+4sth
st3ha
-st1hi
+s2t1hi
st3ho
st1hu
-3sti
-5stic
-5stif
-5stil.
-5stile
-5stim
-4stinf
+2stia
+2stib
+2stie.
+1s2tiel
+2stien
+3s2tif
+5stift
+4stig
+2stik
+3s2til
+3s4tim
st1ins
st1int
-4stip
-sti2r
+2stio
+2stip
+1s2tir
+2stis
st3iso
+1stitu
+2stiv
2stj
4stk
-4stl
+4s4tl
st5le
4stm
-4stn
-3sto
-4stob
-7stock
+2stn
+1sto
+4sto.
4stod
-5s4to3de
-5stof
-4st3om
+sto3de
+s2toff
+s2t5om
4ston
-4stopo
-4storg
-sto5rin
+2stopo
+2stor.
+2store
+2storg
+2stori
+2s3tose
+stos2t
+3stoß
4stou
-s4tow
+4stow
+4stoz
3stö
4stöch
-7s2tör
-4s3töt
+4stön
+4stöt
4stp
2stq
-3str
-5s2traf
-4strag
-5strah
+2strad
+5straf
+2strag
+3s2trah
6strai
-5s2tral
+4strak
+4stral
4strans
5s2tras
-7straß
-6sträg
+5straß
+4sträg
4sträne
-4stre.
-4strech
4stref
5streif
st3renn
-4strev
-4stri.
-5s4tria
-4strib
-6strig
-stri2k
-2strin
-2stris
-4strisi
-4stroc
-5s2trof
-5s2trok
+s2tric
+2s2trig
+3s2tri2k
+s2trip
+2s3tris
st3roll
-stro4ma
-s2tros
-5s2trö
-5struk
-s2trum
+stro2m
+2strop
+1stru
+4strua
+3struk
4st3run
-4strup
-6st3s4
+4st3s4
st1sk
st1sl
st1sz
2st3t2
5stub
-6stuc
-5s2tud
-2stue
+4stuc
+5stud
+4stue
+3stuf
3stuh
-4stuk
-4stumr
-stum4s
-4stumz
-s2tu4n
-6stun.
-2stunf
-3stung
-2st1uni
-2s3tuns
-2stunt
+stum2s
+stu4n
+4stun.
+3stund
+s2t1uni
+4s3tuns
+4stunt
stu5re
st1url
-2sturn
-2st1urt
-3st2ü
+4sturn
+stur4s
+4st1urt
+2stus
+1st2ü
+3stüc
4stüch
-s2tück
-4stür.
-s2tüt
-2stüte
-6stv
+3stüh
+2stür.
+3s2tüt
+4stv
4stw
-2sty
-3styl
+5styl
4st3z2
1su
-su1an5
+su1an
3su2b5
su4ba
-6su3bi
-7su1c
+4su3bi
+5su1c
2s1u2f
-2s1uh
+4s1uh
3sui
su1is
su3it.
@@ -11828,130 +11943,125 @@ su2mau
3sume
su2m1el
su6m5ents
-s3umfa
+2sumf
s3umfe
+2sumk
+2suml
3summ
sumo2
su2m1or
+2sums
s3umsa
s3umst
su4n
-3sun.
+5sun.
sun6derh
s1unf
2s1uni
-4s3unt
-3s2up
+6s3unt
+5s2up
su2ra
2s1url
s1urt
-su2s1
+3su2s1
su3sa
su3sh
su3si
-sus3s
+3suv
1sü
-4sü2b
+2s3ü2b
+3süc
3sü2d1
-5sün
-4s1v
-4s1w
-swa5re
+3sün
+4s3v
+s5va
+2s1w
+s3wa
+s3we
sweh2
-6s3wie
-6s3wil
+4s3wie
+4s3wil
s3wir
s3wis
s2y
3sy.
-sy2l1
+sy2l
sy4n1
-1sys
-sy5st
+1sys5
sy3t
2s1z
-4s3za
+s3za
4s3zei
3s2zena
-5s2zene
+5s4zene
4s3zent
s2zes
-s2zeß
s2zis
-s3zö
4s3zu
+s3zü
s3zw
2ß.
-ß3a2
-ß1ä
-ß1b
-2ß1c
-ß1d
+2ß3a2
+2ß1b
+4ß1c
+2ß1d
1ße
2ß1ec
2ß1e2g
2ß1ei
-ße2l
-ßel1a
-ße3lu
+ße2l1a
ßen3a
+ßene4
ßen3g
ße2ni
-ßen5st
+ßen3st
ßen3sz
ße2nu
ße3rin
3ß2ers.
-ße2t
-ß1ex
-ß1f
-ß3g2
+2ß1f
+2ß5g2
ßge2bl
2ß1h
1ßi
-ßi2g1a
+ßi2g1a2
+ßig4s
2ß1in
ß1j
2ß1k4
+ßkir5
2ß1l
-ß3la
2ß1m
-ß5n2
+2ß5n2
ß1o2
-ß1ö
-ß3p2
-ß1q
+2ß3p2
2ß3r2
2ß3s2
ßst2
2ß1t
-ß2t1h
-ßts4
-1ßu4
-ß1uf
-2ß1um
-ß1uni
-ß1ü
+ß3ti
+1ßu
+2ß1um1
+2ß1ü
2ß1v
2ß1w
-ßwa5r
-ßwa3s
+ßwa3
2ß1z
-6t.
+4t.
3ta.
2taa
-tab4
+3taan
2tab.
-ta2b5an
+ta2b1an
2t1abb
-1tabel
+3tabel
4taben
ta4bend
-2tabf
+4tabf
4tabg
4tabh
4tabk
-ta1bl
+ta1b4l
1table
2tabn
4tabs
@@ -11959,12 +12069,15 @@ ta1bl
ta2bü
2tabw
4tabz
+ta1c
tach3te
t3ada
tadi3
t3adr
+1taf.
1taf2e
3tafel
+4taff
t1afg
t1af4r
3t2ag
@@ -11973,11 +12086,11 @@ ta2ga
ta2g5ei
4t3agent
ta3ges
-ta3gl
+2ta3gl
ta3gn
4t3a4go
-tag6s
-tag7sc
+tag4s
+tag5sc
tah4
tah3le
tahl5sk
@@ -11987,11 +12100,11 @@ tai2l
ta1ins
tai4r
ta1ir.
-4t3a2ka
+4t1a2ka
ta3kes
3takr
ta2kro
-tak2ta
+tak4ta
3taktb
3t2aktu
3t2al.
@@ -11999,44 +12112,47 @@ ta1lag
ta1lak
1talbu
tal3d
-3t4ale
+1t4ale
ta3len
ta4lens
-tal4leg
+1talia
+5talis
tal2lö
+1talo
ta2l1op
ta3lum
2ta2m
3tam.
ta3ma
+3tame
3tamg
ta3mo
-t1ampl
+t3ampl
t1amt
-t2an.
+3t2an.
t1a2na
ta4nat
-4tanb
-t2and
+2t2and
tan3da
tand4st
ta3ne
4t1anf
+3tanis
t2ank
tan4kl
tan3kr
-2tanl
+4tanl
2t1anme
4t1anna
1tanne
t1ans
-4t3ansi
+1tans.
+2t3ansi
2t3ansp
ta4nu
2tanwa
2tanwä
t4anz.
-4tanzei
tan6zerh
t1anzu
ta3or
@@ -12046,6 +12162,7 @@ ta2pes
t4ar.
2t1arb
t1arc
+3tard
ta6rens
3ta3ri
2tark
@@ -12054,15 +12171,20 @@ ta6rens
t3arti
ta2ru
2t1arz
+3tas
+1tas.
ta3sa
1ta3sc
+2ta3se
4t3asp
-1tas2t
+1tast
+ta3sta
+ta1str
1tat.
ta2tan
-tat1ei
-ta2tem
-ta2t1er
+ta4t1ei
+ta4tem
+ta4t1er
ta2th
tat3he
t3atl
@@ -12073,15 +12195,14 @@ ta2t1um
tau4fer
tau3f4li
2taufw
-1taug
t1auk
2taur
1taus
-2taus.
t1ausb
+3tausc
tau6schw
t1ausd
-3t2ause
+3tause
t1ausf
t3ausg
t1ausk
@@ -12090,112 +12211,135 @@ t1ausr
2t3auss
t1ausü
4t1ausw
+1tav
ta3va
3tax
ta3xi
+1taz
tä1c
1täg
2tägy
2täh
-3täle
4t1ält
2täm
t1ämt
t1ängs
-1tänz
+3tänz
t2är.
tä2ru
tä2s4
-tä4st
-2tätt
+4tätt
t1äug
1täu3s
4täx
1tà
-2t5b
+4t3b
tbe3r2e
tblock7en
-2t1c
+4t1c
t3cha
t3che
tch2i
tch3l
t2chu
tch1w
+t2ck
t3cr
2t3d4
tdun2
tdu3s
-1te2a4
+1te
+3te.
+te2a2
+2teak
te3al
+3team
te3an
+5teba
5t4ebb
2t1e2ben
-1t2ech
-te1cha
+t2ech
+te5cha
3techn
-2teck
+4teck
+te2cka
+te2cki
3tee
te1ele
te1em
te2e4n1
te1erw
4tefe
-2teff
+4teff
te2fl
teg4
teg3re
2teh
te3han
+3tehä
+5tei.
t2eie
-2teig
-1teil
-3teiln
-3teilz
+3teil
+4teilhe
2tein
-tein3ec
+tein3e4c
t3einge
t3einla
4t1einn
4teinr
+4teinz
t1eis.
t1eisb
-tei5st
-tek3te
-te2la4
+tek5te
+5tel.
+3te2la
te4l1ab
tel1ac
te3lan
tel1au
+3telb
+3tele
tel1e2b
tel1ec
-3telef
-3teleg
+5telef
te4l1eh
-1te3lem
+te3lem
tel1en
te3lep
te3lex
+3telf
4t1elf.
+3telg
tel1in
te2lit
+3telk
t4ell
tel3l2e
+5teln
te2lo
te2l1ö
+3telp
+5tels
tel3s2k
+3telt4
tel3ta
-tel3t4r
+3tem
+5tem.
+te2man
te2m1ei
te2mi
te3mis
-4temo
+4temm
+2temme
te2m1o2r
-3temper
-1tempo
+5temper
+4tempf
+tem1st
te4m3u
-t6en.
+3ten
+5t6en.
te4n3a2
+te5nac
t4enb
ten3da
6t5endf
@@ -12214,9 +12358,10 @@ t2enl
t2enm
t2eno
t2ens
+tens2e
4t3ensem
ten3si
-ten5st
+tens3th
t1entb
4tentd
t1entn
@@ -12227,7 +12372,7 @@ ten3zw
te2o
te3ob
t1e2pi
-t6er.
+5t6er.
te1raf
ter3am
te3ran.
@@ -12235,32 +12380,35 @@ te2r3as
t2erb
6t5erbs
6t5erbt
-t3erde.
+4t3erde.
+3tere.
te2r1e2b
te4r3eif
te2rel
+3terem
+3teren
ter3end
-t4erfr
+3terer
+3teres
+5t4erfr
4terfül
ter3g
t6ergru
-2t1ergu
-2tergü
te3ria
ter3k4
-t2erka
+3t2erka
4t3erklä
+3terkr
t4erli
4t1erlö
t4erlu
-1term
+3term
ter4mer
-3termi
ter4n3ar
t3erneu
t1erö
+3terr
ter4re.
-1terro
t6ers.
t6erscha
ter4ser
@@ -12268,37 +12416,43 @@ ter4sk
terst4
t4erst.
t4erste
-t4ersti
+5t4ersti
+ter5sto
ter5str
-t4erstu
-tert4a
-teru2
+5t4erstu
+3tert2
+3teru2
te4r1uf
ter3z2a
-4t1erzb
-t2es
-tes3ac
+2t1erzb
+3t2es
+tesa2
+tes1ac
te2sel
-3tesse.
tes3si
-tes2t
+5te2st
+tes3tan
tes3tät
-te4st3ei
-te7ster.
-te4str
-1tests
-te4stu
+test3ei
+tes6terg
te2su
+3tet
te2tat
+4teth
+4teti
6tetl
+2teu
3teuf
+3teum
te1un
+3teur.
teu2r5a4
t5euro
te2vi
-1te2x
+5tewo
+te2x
te3xa
-t1exe
+2t1exe
4t1exi
4texp
3text
@@ -12306,7 +12460,7 @@ t1exe
1té
2t3f
tfi4l
-2t1g4
+4t1g4
tg2a
t3ge
tger2
@@ -12320,10 +12474,9 @@ t3hap
t2har
4t3hau
4t1hä
-4thc
-1the
+2thc
t2he.
-3thea
+3t4hea
4theb
t2hec
2t1hei
@@ -12332,14 +12485,13 @@ t1hel
3t2hem
5thema
5theme
+1then
3theo
t2hera
t1herd
-2t1herr
+t1herr
t1herz
-t2hes
-3these
-1thi.
+1these
3thia
2t1hil
t1him
@@ -12355,7 +12507,6 @@ t2hol.
4tholz
t2hon
4t3hot
-thou4
4t3hö
2thp
3thr2
@@ -12365,77 +12516,86 @@ thou4
4thun
t1hü
2thv
+1ti
ti2a
ti3a2m
ti3an
tib4
+3tibe
+3tibl
+2tic
ti1ce
-ti3chr
ti4d3end
t2ie
tie3br
-5tief.
-tieg6
+3tief.
+2tieg4
+2tieh
ti1el
ti2el.
ti3e2n1
ti2er
-1tierr
-2tieß
+3tiera
+4tieß
ti3et
ti1eu
-5tif.
+3tif.
ti3fa
-tif3f
ti1fr
-tihi4
-ti2kam
+3tig
+3tik
+ti4kam
ti3k2an
ti2kr
-ti2la
-ti3las
+tik5t
ti2lei
til1ep
-1tilg
+3tilg
ti3lo
ti4lö
tilt4
ti2lu
+2tim
ti2mag
tim2m1a
4t1imp
+5tin.
ti3na
t1inb
4t1ind
ti5n4e
-t1inf
+2t1inf
tin2g1a
tin2g3l
tings2
-ting5st
+ting3st
t1init
4t1inj
tin2k3l
t2inn
+3tins.
4t1inse
4tint
4t1inv
-3tio
+5tio
ti3or
-3tiö
3tip.
ti3pl
-1tipp
-1tips
+3tipp
+3tips
+ti2rak
ti1rh
-t2is
+5t2is
tisch3w
-ti2sei
+ti4sei
ti2sol
t4it
3tite
-5titel
-tium4
+tit2h
+2ti3tu
+tiu6
+tium2
+5tiv
ti2van
ti2vel
ti4v3erl
@@ -12444,8 +12604,6 @@ ti4v1r
ti2za
2t1j
2t3k4
-tklat5
-t5kr
tkü1b
2t3l2
tl4e
@@ -12453,37 +12611,44 @@ tle2r5a
4t5li
tli5f
tlings3
-tli5s
-t5lo
tlö3s
-2t5m2
+2t1m2
+t5ma
tmen2s
tmen6t
+tmin4s
tmo4des
t3mu
tmüll4s3
2t5n4
tna5me
-tnes6
+tnes4
+3to.
+toa4
to5ar
-to5a4t
+to5at
1tob
to3be
2tobj
tob4l
-to1ch
+to2c
+to3ch
3tocht
+to6ckent
3tod
tode4
-to2d1er
-tode6s1
+4to2d1er
+tode6s
to4d1u
-tok4
+1tok4
+1tol
to3la
+3tole
+2tolz
tome2
to4men
2tomg
-1ton
+3ton
to5nik
to3ny
3too
@@ -12494,70 +12659,81 @@ t3opfer
to3phe
to2pl
1topo
+2topp
+1tor
+3tor.
to1ra
to2rau
to4rän
4torc
t1ord
-1tore.
+3tore
to2r1el
to3ren
-t1org
+2t1org
t3orga
3torh
tor3int
to2rö
-1tort
+3tors
t1ort.
to4ru
-to7sc
-to5se
+2tory
+to5sc
+1to5se
to4sk
-to3s2p
-tost4
-to5sta
-1toten
+to5s2p
+2toss
+1to3st4
+2toß
+3to5te
to2tho
-3t4ou
+1totr
+5t4ou
touil4
to3un
3tow
-tö2c
-1töch
+1toz
+3töch
2t1öf
2t1ök
3tön
-tö4s
+tör3ste
t1öst
1töt
4t3p2
-t5pf4
+tpf4
2t1q
t2r4
2tr.
+5tra.
tra3bl
-t4rac
-1trach
+1t4rac
+3trach
tra3cha
t3rad.
tra4dem
-1trag
-3tragö
+3trag
2t3rahm
5t4rai
+3trak
+3tral
3t4ran.
2trand
3trank
t3rann
-3trans
+5trans
t3rase
t3rasi
+tra4st
2traß
1traum
-1träc
+3träc
t3räd
-1träg
-1träne
+3träg
+3träne
+2träs
+2träß
4t5re.
2treb
2trec
@@ -12565,66 +12741,74 @@ t3rech
t4reck
2t3red
t4ree
-1tref
-2trefe
-2trefo
+3tref
+4trefe
+4trefo
2treg
t4rei.
-1t4reib
+3t4reib
+2treic
2treif
t3reig
2t3reih
t3rein
-t3reis
+2t3reis
+4treit
t3reiz
2t3rek
2t3rel
t4rem
t4ren.
-1trend
+3trend
+4trendi
t3rent
2trepe
2trepo
-1trepp
t4rer
-t4res.
-1t4ret
+3t4res.
+t4ret
tre2t5r
t4reu
+3treuh
t3rev
2trez
5t4ré
2t3rh
-1trib
+1tri
t4riche
-3trieb.
-3triebs
+3trieb
tri4er
+3trigg
t3rind
tri3ni
3trio
t4rip
-1triu
trizi1
+1tro.
tro3b
-1troc
-t4roi
+1troe
+3t4roi
tro2ke
+2trom.
tro2mi
+2troml
+1tron
2t3roo
t4rop
3tropf
-2troß
+1tros
+3troy
t3röc
3trög
+1trös
2tröt
+1trua
3trug
2truk
trum2
trums1
-1trunk
+3trunk
3t4rup
-t3ruß
trü1be
trü1bu
2t3rüc
@@ -12632,39 +12816,41 @@ trü1bu
try1
2ts
4ts.
-t2sa
+t2s1a
t4s3ab
-t5s2ac
+t5s4ac
ts3ad
t3saf
-ts1ah
-ts1al
-t4s1amt
+ts2ag
+t4s3amt6
t4s3ar
ts3as
t4sau
t5sau.
t2s1än
-ts2c
+t2sca
t4schar
-tsch2e
+t5sch2e
tsch4li
t4schro
+ts4cor
t2s1e2b
-t3seg
+tse4c
+ts1eck
t4s3e4h
t3seil
t4seind
-ts3einl
ts1em
tse2n
+t3sen.
ts1eng
t2s1ent
t2s1er
+t4s3esse
+ts1ex
t2s1i2d
ts1ini
t2s1ir
-t7sit
t3skala
ts3kr
t2s1o2
@@ -12682,42 +12868,38 @@ t3spek
ts2pi
t3s2pon
t3s2por
-ts5s2
-ts1tak
-ts2tat
+ts3s2
+t1s2t
+ts3taf
+ts3tak
ts3täti
-t4s1tep
-t5s4ter.
-t4sterm
-t5stero
-ts3terr
-t5s4tes.
+ts3tep
+t3stero
t5steu
-ts1tie
-t4s3tis
+ts3th
+ts4til
t6stit
-ts2to
ts3toc
ts3tor
-t4s3trad
-t4strau
-t4s1trä
-t4s1tri
-ts2tro
-t4strop
+ts3trad
+t4s3trau
+t2s3trä
+t2s3tri
+t3strö
ts3trü
+t3stu
+t3stü
t2s1u
1tsub
t3sy
4t1t
tt1ab
tt3ad
-ttag7ess
t2t1ak
t3tal
t3tan
+t4tanb
tt1art
-tta5st
tt1auf
tt1ebe
tt1eif
@@ -12726,7 +12908,6 @@ tt1eis
t3te2l
tte4la
tte4l1o
-t3t2er
tte2s
tte4s1ä
t2teti
@@ -12735,7 +12916,9 @@ tt3ha
tt2häu
tt1ho
tt1hu
+t3ti
t3tra
+t2trau
t3trä
t3t4ro
tt5rom
@@ -12746,30 +12929,33 @@ tt3sec
tt5se5h
tt3sel
tts1p
-tt4s3tem
-tt4ster
-tt4sti
+tt2s3ti
ttt4
-t2tuc
+t3tu
tt3z2
+1tu
tu1alm
tu3an
2tub
-1tuc
+3tuch
tu2chi
-1tue
+2tud
+3tue
tue3re
tu3et
+2tuf
tuf2e
tu3fen
t1u2fer
2tuh
-tu2k
+2tu2k
tu3ka
t1ukr
tu3la
-t2um.
+3t2um.
+5tume
2tumf
+2tumg
2tumk
tum2si
tum2so
@@ -12779,14 +12965,14 @@ tum2so
2tund
3tu3ne
2t1unf
+3tung
t1unga
tun2gl
-tung8s
+tung6s
2tunif
2t1u4nio
-3tunn
-1tuns
2tunt
+3tuö
t1up.
tu2ra
tur3a4g
@@ -12799,7 +12985,7 @@ tu2r1er
tur3ere
tu4res
tu2r3e4t
-1turn
+3turn
tu2ro
tu3rol
tur3s2
@@ -12809,58 +12995,61 @@ tu2sa
tu4schl
tu4so
tu3ta
-tuts3c
2tüb
t3übe
-1tüch
-tück4s
+3tüch
+tück2s
1tüf
+1tüm
1tür.
tür1c
1türe
1türg
-1türs
+1tür3s
3tüten
2t1v
t5vo
4t1w
+twa4r
twi4e
1ty
2tyl
ty4le
+3typ
ty2pa
+ty3st
2t1z
t2z1a2
tz3an
tz3as
t2z1ä
t5ze.
-t2z1ec
+t2z1e4c
t2z1eie
t2z1eis
tze4n
tz4ene
tz3ents
t2z1erl
-t3ze4s
+t3ze2s
tz1imp
+tz1ind
tz1int
t2zo
tz1of
t3zon
tz1or
-tz2tin
+tz4tin
t2z1w
2u.
u3a2b
-u1a4c
+u1a2c
ua3d
uad4r
u1al.
u3alet
u1alf
-ual3l
-ua2lo
+u3a2lo
u1alr
u1als
ual3t
@@ -12880,7 +13069,6 @@ u1äm
u1äu
2u1b
u3be
-ub3ein
ub6i
ub3lic
ub5los
@@ -12888,21 +13076,20 @@ u3blö
ub3lu
u2bop
ub3rä
-ub3rit
+ub5rit
ub2sa
ub2s1o
ub2spa
ub3um
u2b3üb
-2uc
-u1ce4
-uces3
+4uc
+u1ce2
u2ch1a
u3cha.
uch3an
uch1ä
u1che
-u2ch1ec
+u2ch1e2c
uch1ei
u3ches
u1chi
@@ -12913,28 +13100,30 @@ uch5m
uch3n
u2ch3r
uch2so
+uch4spr
uchst4
-uch5str
uch4tor
uch2t3r
u1chu
uch3ü
uch3w
+u2ckem
+u4ckent
uck2er
-uck3erl
+u4ck3erl
+u2cki
uck4sta
u1cr
2u1d
u5d2a
+udens2
ude3r2e
-ude5sa
udi3en
uditi4
u4don
ud3ra
-ud2s
-ud3sc
u1e
+ue4ck
u2ed
ue2en
u2eg
@@ -12954,10 +13143,11 @@ u5eremp
u5erent
ue4rerg
uer3g2
-u3erinf
-u3erint
+u5erinf
+u5erint
uerk4
uer4ne
+uern3s4t
uer3o
u3err
uert2
@@ -12965,13 +13155,11 @@ u3erum
u3erunf
u3erunt
u3erur
+u3erv
uer3z
-ue4s
-ue5se
-ue5sp
ue2ta
ue4tek
-uet2s
+uet4s
uf3ad
u3fah
uf1ak
@@ -12986,7 +13174,6 @@ u3fen.
u2fent
u2f1erh
uf2ern
-u2f1eß
2uff
uf3fe
uff4l
@@ -12997,12 +13184,8 @@ uf1ori
u1fö
uf3r
uf5sä
-uf4s3tem
-ufs3ten
-uf4ster
uft1eb
-uf3ten
-uft3s2
+uft3s4
uft5sa
2u1g
u4gabte
@@ -13017,6 +13200,7 @@ u2g5ent
ug5erf
ug5erl
uge7sc
+ugge4st
ug3hu
u2g1l
ug3lä
@@ -13031,25 +13215,25 @@ u4g3reis
ug3ro
ug3rum
ug3rüs
-ug3sau
-ug7sc
+ug5sc
ug3s2e
ug3si
ug3spa
ug4spr
ugs2t
-ugs3te
+ug5stä
+ug3str
ugut2
u2gü
u1h
2uh.
uhe1ra
+uhe1s4
+uhe3st
uh1la
uh1lä
uh3ma
-uh5me6
-uh3mi
-uh3na
+uh5me4
uhr1a
uhr3er
uh1ri
@@ -13059,17 +13243,16 @@ uhr3tr
uh2ru
uh1w
4ui
-ui2c
+ui2ch
u1ie
ui1em
-u1ig
-u2ige
+u3ig
+u4ige
u3in.
-ui5ne
u3isch.
u3ischs
uisi4n
-ui4st
+ui4s3t
u1j
ukä2
u3käu
@@ -13080,7 +13263,6 @@ u3kla
ukle1i
u3klo
u3klö
-u3ko
u5kö
u1k4r
uk2ta
@@ -13092,6 +13274,7 @@ u1l
ul1ab
ul1am
ul2ar
+ula2s
ul1äm
ulb4
uld2se
@@ -13100,9 +13283,10 @@ ule4n
ul1erf
ul1erh
ul1erw
-ules3a
+ules1a
ule2t
ul3eta
+ul3fe
ulg4
uli2k
uli5ne
@@ -13110,17 +13294,17 @@ ul1ins
ul3ka
ul2kn
ull2a
-ul3len
ul2les
-ul2lö
+ull1s
ulm3ein
ulo2i
ul1or
ulö3s
ul2p1h
-ul2s1a
+ul2sa
+ul2sei
ul3sp
-uls2t
+ulsu3
uls3z
ul4tar
ul2tau
@@ -13129,9 +13313,10 @@ ul2tri
u2lü
ulz2
ul3zw
-u2m1a2k
+u2m3a2k
um1all
um2an
+uman4s
um1anz
um1ar
um1aus
@@ -13158,9 +13343,10 @@ um2pl
ump3le
1umr
1umsat
-um2ser
+um4ser
um2sim
um2s1pe
+um1st
um2su
umt2
um3th
@@ -13209,14 +13395,14 @@ un1gl
un2g1r
ung3ra
ung3ri
-ung6s1
+ung4s3
u3ni
un1ide
1u4nif
un1in
un1ir
2unis
-un3isl
+un5isl
1u4niv
un2k1a
un2kn
@@ -13229,6 +13415,7 @@ unk4t3r
un2n3a2d
un5n4e
un3no
+unn3s
un1o
uno4r
un2os
@@ -13236,10 +13423,11 @@ un2os
uns2
2uns.
unsch5el
-un3se
+un5se
1unsi
un3sk
un3sp
+un2stu
1unt
un3ta
unte2
@@ -13268,12 +13456,13 @@ up2pr
u1pr
up1ru
up1sl
-upt3a2
+up4t3a2
upt3erg
upt1o
+up4tr
u1pu
u1q
-2ur.
+4ur.
u1ra
u3ra.
u3raba
@@ -13300,8 +13489,9 @@ urb2
ur3ba
ur2ble
urch1
-urch5s
-ur3d2i
+urch3s
+urd2
+ur3di
2ure
ur1eff
ure3g
@@ -13315,6 +13505,8 @@ ur1erw
urg2a
ur2gri
urgros4
+urgs2
+urg3st
u1r2i
uri2c
u2r3im
@@ -13323,42 +13515,49 @@ ur1ini
ur3ins
ur1int
ur3inv
+urk2s
1urlau
+urm2a
+urm3ang
2u1ro
-uro5st
+uro3st
u1rö
2urr
+ur3sac
ur2san
-urs3au
-ur2sei
-ur2ser
-ur4sin
+urs1au
+ur6sei
+ur4ser
+ur6sin
+ur2st
ur5st4r
-ur6sw
-urt4
-ur5te
+ur4sw
+urt2
+ur5t4e
ur3th
u1ru
+urü2
ur2za
ur2zä
ur2zi
ur2zo
ur2z1w
u4saf
+us1an
us4ann
-u2sau
+u2s1au
u6schent
usch5wer
us1ec
u2s1ei
u3seid
-u7sep
+u5sep
use1ra
u2serp
us4et
usi3er.
usi5ers.
-us3li
+u3sik
us3oc
u3soh
u3sol
@@ -13372,70 +13571,55 @@ u3spek
us1pic
u5s2piz
us2por
-us2sac
-us6sat
-us2sei
-us3sel
+us4sei
usse4n
uss5erfa
uss3erk
-us5sers
-us2sez
-us2sir
+uss5ersu
+us4sez
+us2sof
uss3tät
-us2sü
-u4st1a2b
-u5stal
-us2tat
-u5stä
-u5ste
-us2ten
-us2ter
-us2th
-u5stis
-u5stop
-us1tor
-u4strä
-u5s4trop
-u5stu
-u6s1tur
-u5stüc
+ust1a2b
+u3stal
+u3stel
+us1tr
+us4tris
+u3stu
+u4stun
+u4stur
us2ur
u2sü
u1sy
-u4sz
-uß3et
-u2ß1u
+u1ß
+ußen3
2u1t
u3taf
ut1alt
ut1a4m
-u2tanz
u2t1ap
u2t3ar
ut1är
u3tät
-u3te.
-u2t1e4g
+u3te
+u5te.
+u4t1e4g
ute2l
ut2em
ute2n1
-u3ten.
uten3e
-u2tent
-u5ter.
+u4tent
ute5r4er
-u4t3ersa
-u3tet
-u2tev
+u5tern
+ut3ersa
+u5tet
+u4tev
u4t1ex
u2t1hi
u2t1ho
u2t1hu
uti2q
-u3to.
uto4ber
-uto3c
+uto5c
uto3n4
ut1opf
u2tops
@@ -13446,6 +13630,7 @@ ut3rü
ut5sa
ut2s1ä
ut4schl
+ut6schö
ut3sp
ut4spa
ut3te
@@ -13467,46 +13652,50 @@ u1x2
ux3t
u1ya
u1z
-uze4
+uze2
uz3ot
uz1we
uz3z4
1üb
2übd
-übe4
-über1
+übe2
+übe3c
+übe4r1
ü2b5l
-3üb3r
+3üb5r
+üb2st
3übu
2üc
ü1che
üch3l
-üch4s1c
+üch4s3c
üch5t4e
ück1er
-ück3e4ri
+ück5e4ri
+ü4ckers
+ück4spe
ü4d3a4
-üdau5
ü3den.
üden4g
ü3d2ens
üd1o4
-üd1ö4
+üd1ö
ü4d5r
-üd3s
+üd3s2
üdsa1
üd1t4
-ü4f3a
+ü2f3a
ü2f1ei
ü2f1erg
üf2fl
ü2f1i
üf3l
-üf3te
ü1g
+ü3ge
ü2g3l
ü2gn
üg3s
+üg4st
üh1a
ü1he
ü2h1ei
@@ -13514,6 +13703,7 @@ uz3z4
ü2h1erk
ü2h1erz
üh1i
+ühla2
ühl1ac
ühl1ag
üh5l2e
@@ -13526,13 +13716,12 @@ uz3z4
ühr5ei.
üh5ro
ühr5ta
-ühs2
-üh3sp
-üh3stu
-üh3te
+üh1s
+üh3s2p
+üh5te
ü1hu
üh1w
-ü1k2
+ü1k
2ül
ül1a
ül2c
@@ -13543,17 +13732,25 @@ uz3z4
ül4lö
ü1lu
ü4ment
+2ün
ü2n1a
ün2c
ün2da
ün2dr
+ünd1s
ün2f1
ün4f3ei
ün3fl
ün4fli
-ünf5r
+ünf3r
ün2g3l
-üng5s
+ünn4s
+ün2s
+ün3sc
+ün3sp
+ün4st
+ün5sta
+ün5str
ün3th
ün2za
ü1pe
@@ -13565,37 +13762,34 @@ uz3z4
ür4f3r
ür4g5eng
ü1ri
-ü1r2o1
+ü1r2o
üro3b
ü3rofe
-ür4ster
-ür5sti
+üro1r
+üro3st
+ürr2
+ür2s
+ürs3tin
ürt2h
ür3the
ü1ru
-üs2a
ü2schl
üse3h
üse3l
-üs4sa
-üs4s1c
-üs3se
-üs4st
-ü4sta
+üs4s3c
+üs5se
+üs2st
+ü2st
üste3ne
-ü4str
ü1ß
ü1ta
ü2t1al
-ü1te
-ü1ti
üt3r
üt2s1
üt2tr
-ü1tu
ü1v
ü1z
-4v.
+2v.
3va.
2v1ab
va3c
@@ -13603,21 +13797,22 @@ va3ge
val2s
2vang
2v1arb
+va3st
v4at
va2t3a6
+va4tei
va2t3h
va4t1in
vati8ons.
va2t3r
-vat5s4
+vat3s2
vat3t
va2t1u
-vat3z
2v1au
-vä1
2v1b
2v1d
ve2
+3vea
ve3ar
ve3b
ve3c
@@ -13625,7 +13820,8 @@ ve3d
ve3g
ve3h
veit4
-veits1
+veits3
+vek3
ve3la
ve4l1au
ve3le
@@ -13656,12 +13852,11 @@ verg4
ve3ri
ve5ris
ve5rit
-ver5sta
-ve3s
+ver3st
2vesc
-2vese
-ve4s1p
-ves2t
+2ve3se
+ves1p
+ves3ti
ve3ta
vete1
vete3r
@@ -13678,6 +13873,7 @@ vi3an
vi4a3t
vi4c
vi3de
+vid3s2t
vie2h3a
vi2el
vi2er
@@ -13687,7 +13883,6 @@ vi3ka
vi2l1a
vi2leh
vi2l1in
-vil3l
2v1i2m
vi4na
vin2s
@@ -13695,8 +13890,8 @@ vin2s
3vio
vi3sa
vise4
-vi3s2o
-vis2u
+vi5s2o
+vi3s2u
vize5
2v1k
2v1l2
@@ -13704,9 +13899,9 @@ vize5
2v1n
2v1ob
vo2gu
-vol6l5end
-vol6lerw
-vol2li
+voll1a
+voll5end
+von3
2v1op
vo2r1
vor3a
@@ -13715,14 +13910,15 @@ vor3g
vo3ri
vo5rig
vor3o
-vorö4
3voy
+vö2c
2v1p
v3pf
v1ra
3vri
v1ro
-2v1s
+2vs
+vs2e
v3s2z
2v1t
2vumf
@@ -13732,10 +13928,11 @@ v3s2z
4w.
w2a
wab2bl
+wa5che
wa3d
waffe2
1wag
-wa3ge
+wa5ge
wa2g5n
wa2gr
wa3gra
@@ -13746,49 +13943,58 @@ wai2b
1wal
3wald
wal4da
-wal2to
walt4st
+wa5na
+wang6s
+wan4s
wa2p
-wa4r
-wa5ra
-1wa3r2e
+wa2r
+wa3ra
+1war2e
ware1i
-wa5ri
+wa3ri
+war3ste
wart4e
-wa5ru
+wa3ru
1wa2s
wa3sa
+wa3se
wa3sh
wa3si
-was5s4
+wass4
+was7se
1wäh
1wäl
-wäm3
1wäs
-wäs2c
+wäs4c
wä5sche
+wäs5se
w1b
2w1c
w1d
weat3
we3be
4webeb
+we3cke
+we5cke.
+we5cken.
+we5ckes
we3d
we2e2
weed1
we2fl
3weg
-we2g5a
+we2g1a
we2g5l
we4g3r
-wegs2
+wegs4
weg3sp
1weh
we3he
wei4bl
2weie
weis4s3p
-wei5str
+wei3str
wei3ße
wei4tr
weit3s
@@ -13815,43 +14021,39 @@ we4r1io
1werke
wer2kl
wer2ku
-wer4sta
-wer2ta
+wer2s
+wer2t3a
wer4tei
wer6t5erm
wer4to
1werts
-1we5se
-wesen4s3
+1we3se
we3si
we2s1p
-wes2t
-we4st1a
-we4st3ei
-we5sten.
-we5stens
-we6steu
-we6sti
-we4st1o2
-we4stö
-we4st3r
-we4stu
-wet2s
+we4st
+west1a
+west3ei
+wes2t1o2
+west3r
+wes4tu
+wet4s
+wet4ta
wett3s
2w1g
-w3ho
+w5ho
+wi3cka
3wid
wi2e
wie3l
wie5ne
-wie4st
+wie2st
wi3k2
+wim2ma
wim4m3u
-win4d3ec
+win4d3e4c
win2dr
win2e
win8n7ersc
-win4num
wi4r
1wirt
wi5s4e
@@ -13862,7 +14064,6 @@ wi3th
2wk
2w1l
2w1m
-2wn
wn3sh
1wo1c
wo2cha
@@ -13871,7 +14072,6 @@ woche4
woh4l
1wolf
wolf4s
-wol4la
wol4ler
wor3a
wo2r3i
@@ -13885,25 +14085,30 @@ wör3the
1wr
w1ro
2ws
-w3s2k
+w3s4k
+w1s2t
2w1t
-wti2
+w3ti2
w2u
1wuc
-wuls2
+wul2
+wul3se
wun2s
4wur.
wur2fa
+wur4s
1wurst
-wus4
-1wu2t1
+wus2
+wus3te
+1wu4t1
1wüh
-wüs4
+wül2
+wün3
2w1w
6x.
x1a
1xa.
-2xab
+2x3ab
1xad
1xae
xa1fl
@@ -13912,6 +14117,7 @@ xa4m
xa3me
xa5mer
2xan
+x4anz
3xas
2x1b
x1c
@@ -13925,7 +14131,7 @@ x1em
7x2em.
xemp6
3x2en
-xens2
+xens4
xen3sa
x2er.
5xere
@@ -13934,6 +14140,7 @@ xers2
2x3eu
2x1f
2x1g
+xge1
2x3h
1xi
xib4
@@ -13947,18 +14154,18 @@ xie3l
xi3g4
xi2lo
xi2l1u
-xins2
xin3sk
-x2is
-xi2s1e
-xi2s1o2
-xis5s
-xi5stä
-xi2su
+x2i2s1
+xi3sc
+xi4se
+xiso2
+xis3s
+xis2tä
x1i2tu
x1j
x1k4
2x3l
+xlib6
x1m
2x1n
x1or
@@ -13969,13 +14176,13 @@ x1r
4x1t
x2t1a
xt3an
-x3t4as
+xt4as
x2t1ä
x3tät
+xtblo4
x2t1e2d
x2t1ei
-x3teil
-x2tent
+x4tent
x2t1erf
xtra1b6
x2t3ran
@@ -13985,7 +14192,7 @@ x3tur
1xu
xu1a
x1u4n
-xu2s
+xu2s1
x1v
2x1w
1xy.
@@ -13998,6 +14205,7 @@ y1a2m
yan2g
y3ät
y1b
+yb6r
y1c
y2chi
y3chis
@@ -14007,9 +14215,9 @@ y3d4r
y1e
y2ef
yen4n
-y2es2
+y2es
ye3sp
-y3e4st
+y3est
ye2th
y1f
y1g
@@ -14023,15 +14231,17 @@ yk5s
y1l
yl3a2m
y3lant.
-y3l4ante
+y3lante
yl3c
y5len
y5ler
yli4n
yloni1
+yls2
+yl1st
y2l1u
-yma2t
-ym3p2
+yma4t
+ym3p4
ympi3e
y2ne
y2n3o
@@ -14043,7 +14253,7 @@ y1ont
y3ou
y1p
ypa2
-yp5an
+yp3an
ype2
yper3t
y3ph
@@ -14055,19 +14265,16 @@ y1r
y3r2e
y3ri
yri1e
-y3ro
-y1s2
-y5sc
-y3sh
-ys3k
-y3sp
-ys3s
-yst4
-y3sty
-y3sz
+y5s4c
+y1sé
+ys2h
+y3s2p
+y2st4
+ys1tr
+y3s2ty
+y3s2z
y1t
y2t2h
-yto5s
yu2r
yure3
y1v
@@ -14076,47 +14283,46 @@ y1y
y1z2
6z.
2z3a2b
-za1cha
-za1chä
+za1c
z3a2d
za3de
2z1af
za3gr
3z2ah
2z3a2k
-za3li
2z1all
2z1am
z3ambik
3zambiq
z1an
+za2na
2z3anf
3zani
+z3anl
3zar.
2z1arb
3za3re
z1arm
-3za3ro
-za5st4
+3zaro
+za3st4
2z3at
3zaub
z1au2f
z3aug
3zaun
-za3v
zä2
2z1äc
3z2äh
2z1äm
-zäng5
z1ärg
z1ärm
-4z3b4
+4z3b6
zbü1b
zbübe5
4z3c
2z3d
zdä1
+zdi1st
1ze
ze3a
2zeck
@@ -14125,8 +14331,8 @@ ze1e
zei3la
zeile4
2z1ein
-zei5s2
-zei3sk
+zei3s2
+zei5sp
zeist4
zeit1a
zei4tak
@@ -14138,19 +14344,15 @@ ze4l1a2
zel3ad
zel1er
zel1in
-zel5l4a
-zel5lä
-zel4leh
-zel4lin
-zel3spr
+zel5la
zel3sz
zel3th
zelu2
ze5m4e
2z1emp
5zen.
-ze6n1ac
-zen3s2e
+ze4n1ac
+zen5s2e
zen2ta
5zentr
zent3sk
@@ -14184,13 +14386,12 @@ zer6t5rau
3zerza
z1erzi
ze2sä
-ze5sc
ze2s1i
ze3sku
-ze2s3p
-zes4ser
-zes1tr
-ze2ß1
+ze2sp
+zes6s5end
+ze2st
+zes3tr
ze2tr
2z1ex
2z3f
@@ -14198,19 +14399,18 @@ ze2tr
zger2a
2z1h
z2hen
-3zi.
+zhir5
+zi3alo
zid5r
zi1erh
zi1es.
-3z2ig
+zig4s
zil2e
-zil3l
-z2imm
2zimp
3zine
zin4er
2z1inf
-z1inh
+2z1inh
zin4ser
4zinsuf
2z1inv
@@ -14219,7 +14419,7 @@ zi3op
zirk4
zirk6s
zi3s2z
-zit2h
+zi1t2h
2z1j
2z3k4
zkü1b
@@ -14227,6 +14427,7 @@ zkü1b
z3la
2z1m
2z3n2
+znei3
2zob
2zof
z1oh
@@ -14250,19 +14451,21 @@ zö7li
z2t1au
z3te
z4tehe
+zte3ma
zte3o
-zte5str
+zte3str
z2t1h
z4t3hei
z3t2her
zt3ho
+z3ti
zt1ins
zt3rec
-zt3s2
+zt3s
zu1
zu3a
zub4
-zu2c
+zu5cke
zud4
zu3f4
zu2g1ar
@@ -14285,7 +14488,7 @@ zu3r2a
2z1url
2zurs
2z1urt
-zu3s2
+zu3s4
zu3t
zuz2
2züb
@@ -14309,8 +14512,9 @@ z2wit
z1wur
2z1wü
zy1ank
-6z1z
+4z1z
z3z4a
z3zi
+zzi3s2
z3zo
-zzoll2} \ No newline at end of file
+zzoll2}
diff --git a/tex/context/patterns/lang-de.rme b/tex/context/patterns/lang-de.rme
index 3997cda14..8bfa03fdb 100644
--- a/tex/context/patterns/lang-de.rme
+++ b/tex/context/patterns/lang-de.rme
@@ -1,13 +1,13 @@
% generated by mtxrun --script pattern --convert
-% dehypht-x-2008-06-18.pat
+% dehyphn-x-2008-06-18.pat
-\message{German Hyphenation Patterns (Traditional Orthography) `dehypht-x' 2008-06-18 (WL)}
+\message{German Hyphenation Patterns (Reformed Orthography, 2006) `dehyphn-x' 2008-06-18 (WL)}
-% TeX-Trennmuster für die traditionelle deutsche Rechtschreibung
+% TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung
%
%
-% Copyright (C) 2008 Werner Lemberg <wl@gnu.org>
+% Copyright (C) 2007, 2008 Werner Lemberg <wl@gnu.org>
%
% This program can be redistributed and/or modified under the terms
% of the LaTeX Project Public License Distributed from CTAN
diff --git a/tex/context/patterns/lang-deo.hyp b/tex/context/patterns/lang-deo.hyp
index deff1a4bc..0ca53c25f 100644
--- a/tex/context/patterns/lang-deo.hyp
+++ b/tex/context/patterns/lang-deo.hyp
@@ -2,7 +2,7 @@
% for comment and copyright, see ./lang-deo.rme
-% used:
+% used:
\hyphenation{
-} \ No newline at end of file
+}
diff --git a/tex/context/patterns/lang-deo.pat b/tex/context/patterns/lang-deo.pat
index d97382d21..a82b144ce 100644
--- a/tex/context/patterns/lang-deo.pat
+++ b/tex/context/patterns/lang-deo.pat
@@ -7,53 +7,50 @@
\patterns{
.a6
.ab3b
-.aben2
.ab5l
.abo4
.ab3ol
.ab1or
-.ab5r
.ab3s
.ag4r
.ag2u
-.aid2
+.aid4
.ai2s
.al3br
.al2e
.al3l4en
.al3ph
-.al4tei
.alt3s
.amt4
-.amt6s3
+.amts3
.an3alg
.an3d
.ang4
.an1gl
-.angs4
+.ang6s2
.angst3
.an3k
.an3s
.an4si.
.ans2p
.an3z
+.ao5
.ap3s2
.ar3k2a
.ar4m3ac
-.ar4s
+.ar2s
.ar4t3ei
-.as1t
-.as4ta
+.ata1
.au3d
.au2f5
.au4s1
.ausch3
-.aus5s
-.ä4
-.äm5
+.au6stes
+.ax2
+.ä6
+.äm3
.ät2s
.b6
-.bau1s
.be3erb
.bei6ge.
.be3ra
@@ -65,21 +62,18 @@
.bo4s3k
.c4
.ch2
-.con3
.d4
.dab6
.da2r1
.dar3in
-.dar2m
+.dar2m1
.da4te.
.da4tes
.de4al
.de1i
.de3o2
.de3r4en
-.de1s
.de3sk
-.de3s2t
.deut2
.dien4
.do3b
@@ -96,114 +90,121 @@
.ei5ner
.ei5nes
.ei4sp
-.ei4st
+.ei4s1t
.ei2tr
.el2bi
-.elb3s
-.els7t
.em3m2
.en1
.en4d3er
.en4d3r
-.enn2
+.enn4
.en4t3
+.epi1
.er4dei
.er4der
.er1e
.er1i
+.ers2
.er8stein
-.es3k
.es3p
-.es1ta
-.es5t4e
-.es1th
-.es3tr
-.et4s
+.es2t
+.est4e
+.et2s
.eu3
.eug4
.ext4
.f6
-.fi3est
+.fa2c
+.fe6sta
.fi4le.
.fi4len
-.fin6s
.fi2s
.frau3
-.fs4
+.fs2
+.fus2
.fu2sc
-.g4
-.ga4t
+.g6
+.gang5
+.ga2t
.gd2
.gel2d
.ge5nar
.ge3ne
.ge3r2a
.ge3r2e
-.ge3s4a
+.ge5s4
+.ge7sta
.ge1u
-.gros4
+.grif8fes
+.gros2
.gs2
-.gus4s3
+.gus2
+.guss3
.gu4ter
.h4
.ha3bi
.haft5s
-.hal5te
+.hal4s
+.hal3te
.haup4
-.hau4t1
+.hau2t1
.he2
-.he3cke
.he3ri
.he6r5inn
.he5xe
-.his1
.ho4met
.i6
.ia4
+.il3
+.illu5
.im2a
.in3
.ink4
.inu3
-.is2a
-.is3tr
+.is4a
.jor5
-.k6
+.k4
.ka2b5l
.ka2i
.kamp2
-.ka6t3io
+.ka4t3io
+.ken6num
+.ker5s
.ki4e
.klan4
.ks2
.kü1b
.l4
.la3b
+.lat5s
.le4a
+.lea7se
.le5ni
-.lib6
.lo4g3in
.lo3ver
+.lu4str
.m4
.ma3d
.ma3ge
.ma3le
-.ma4st
+.ma4str
.me3l4a
.me3ne
.men8schw
.ment2
-.mi2s
+.mi2sc
.mi4t
.n4
-.näs3c
-.ne6s
+.näs1c
.nich2
.ni4e
+.ni3ka
.nob4
+.no2c
.no2th
-.nus4
+.nul2
+.nus6
.o6
-.oa3
.ob1a
.obe2
.oben3
@@ -211,12 +212,10 @@
.ob3l
.oper4
.or2a
-.ort2
-.ort6s
+.ort4
.orts3e
.oste2
-.os4tel
-.os8t7ende
+.ost7ende
.oste6r5e
.ost3r
.ozo4
@@ -229,35 +228,35 @@
.pf6
.ph4
.poka2
-.po4st
+.po4str
.ps2
-.r6
-.reb3s2
+.pu3s
+.r4
+.reb5s2
.re3cha
.rein4t
.reli1
.reli3e
-.res4tr
.rich5t6e
.ro3be
.ro2h
-.ro3m2a
-.rö4s
-.rös3c
+.ro3m
+.rom4a
+.rö4s1c
.rut2
.ru3th
.rü1b
-.rü6cker
.s6
-.sali3e
+.sa2c
+.sali1
.sch4
-.sen5s
+.sen3s
.ser2u
.se2t
.sha2
.si2e
.sim3p4
-.si4te
+.si2te
.ski1e
.spra2
.st6
@@ -270,18 +269,15 @@
.te2e
.tehe3
.te3no
-.te4st
+.te6ster
.th4
.ti4a
.ti2s
-.ti3ta
.to2n
.to4ni
-.ton3s
.to4pl
-.to4st
.to2w
-.tri3es
+.tri3e4s
.ts2
.tu3ra
.tu3ri
@@ -296,11 +292,9 @@
.unen2
.un3g
.uni4t
-.un3s
-.un5s4t
.ur1
.urin4
-.ur5o2m
+.ur3o2m
.uro2p
.ur3s2
.ut2a
@@ -309,19 +303,16 @@
.v2
.ve5n2e
.ve4r
-.vol2
.vo4r
.w2
.wah2
.wah4l
-.wa3re
+.wa5re
.we2
-.weg3
.welt3
.wi4e
.wor2
.wor6t5en
-.wor4tu
.wun4sc
.x4
.xe3
@@ -329,13 +320,11 @@
.ya4l
.z2
.zah2n
-.za4s
.zi2e
-.zin6s5t
+.zin4st
.zuch2
-.zwe4
6a.
-4aa
+2aa
a1ab
aa2be
aa1c
@@ -359,22 +348,20 @@ ab1ar
ab1auf
ab1ä
ab2äu
-1abd
+3abd
a1be
ab1eb
abe1e
-abei3
ab1eil
4a3bel
abe2la
-abe4na
2aber
-a3beri
ab1erk
ab1err
ab1erz
ab3esse
-4abet
+ab1eß
+2abet
2abew
1abf
3abfi
@@ -401,42 +388,44 @@ a2bo.
ab4of
3a2bon
ab3r
-ab5rec
+ab5re
1abs
2abs.
abs2a
2absar
-ab3s2i
-ab3sp
-abst6
+ab5s2i
+ab5sp
+abs4t6
2abst.
-ab5sta
-ab5ste
+ab7sta
+ab7ste
ab3sz
1abtei
2a1bu
ab3ur
2abü
-ab3üb
-1abw
+ab5üb
+3abw
2aby
1abz
2ac.
a2ce.
a1cem
+a3cet
ach1a
ach3ak
-a1chal
+a3chal
ach3au
a1che
a2ch1e2c
ach1ei
+a3chen
+a3cher.
a4cherf
ach3erw
a3ches
4achf
a1chi
-a3chis
ach5l
ach5m
ach3n
@@ -448,6 +437,7 @@ ach1ö
ach3r
ach3spr
ach3su
+a4cht
ach6t5erg
ach4th
ach2t1o
@@ -457,14 +447,14 @@ ach3ü
4achv
2ach3w
ac1in
-2ack.
-a1ckar
+4ack.
ack2en
-a3cki
-a4ckin
+ackmu6
+ackmus3
ack2se
ack3sl
-ack5sta4
+ack7sta4
+a3co
acon4n
2acu
a1ç
@@ -475,34 +465,32 @@ a4d1ac
ad1ama
a2d1an
3a4d5ap
-a3dar3
+a3dar
3a2dä
ade4al
adefi4
ad1ein
ade1ra
-4ades
-ade3s2p
+4ades4
+ade3sp
ades6s
4adi
adi3en
ad2ob
-ado3c
a2dr
ad5rah
4ad3rec
ad4res
ad5ru
-ad1s2
+ads2
ad3sä
ad3sp
-ad3st
ad3sz
-ad4t1
+ad2t1
adt3a
2ae
a1e2b
-a1e2c
+a1ec
a1e2d
a1ei
a1el.
@@ -514,8 +502,7 @@ ae2o3
a1e2p
ae1r
3a2er2o
-a1e2s1
-aes3t
+a3estri
a1e2x
a2f1a
a3fah
@@ -528,7 +515,7 @@ a2f1ec
a2fent
af1erl
af4f5l
-2a3fi
+2afi
2af3l
af3ra
af3rä
@@ -537,19 +524,15 @@ af3rö
af3ru
af3s2a
af2sp
-afs4t
-af3ste
-2aft
+afs2t
af2t1a
-af3tab
-af2tei
af4t3erl
af2t3r
-af4t5re
+aft5re
af2tur
a2f1ur
a1g
-2aga
+4aga
ag1a2b
ag3a2d
ag1ar
@@ -563,9 +546,8 @@ age2nu
age2se
age4si
age4s3p
-ages3s
+ages5s
a4g5esse
-age4s3ti
ag3gl
2agi
3a2git
@@ -587,17 +569,14 @@ a2g3re
a2g3ri
ag4ro
a3gru
-2ags
+ag4s
agsa2
-ag4sam
-ag4set
-ag6s5p
+ag7sat
+ag5säu
+ag6s3p
ag7spi
-ag3sta
-ag3ste
-ags4tei
-2agt
-2agu
+ag5sta
+ag5ste
a2g1und
2ah.
2a1ha
@@ -620,9 +599,8 @@ a2h1ö
ahr1a
ah3re
ah4rei
-ahre6s3
ah1ri
-2ahs
+2ah2s
aht3sp
a1hu
ah1w
@@ -630,12 +608,12 @@ a1hy
2ai
ai1a
aib3l
+aids1t
ai1er
aif2
ai3g4
-a3ik.
+a1ik.
ai3ku
-a2il
ai2lo
a1ind
ai3n4e
@@ -645,20 +623,21 @@ ai2nu
ai3o
ai2sa
a3isch.
-ai5s2e
-ais3s
+ai3s2e
+ai5se.
+ais4se
+ais5st
a2it
a3iv.
a3ivl
a3ivs
a1j
-aje4
2ak.
a2kad
-2akam
+2a3kam
2akar
ak4at
-aka2ta
+aka4ta
2akb
2akc
2akd
@@ -666,7 +645,7 @@ aka2ta
a2kef
a2kes
a2keu
-2a1ki
+4a1ki
2ak3l
ak4la
ak4li
@@ -678,15 +657,16 @@ ak3res
2aks
ak3sh
2akta
-ak3t2an
+akt2an
2aktb
-ak5ten
+ak3te
+ak4tei
2aktik
akt2o
ak4t5r
ak5t6ri
2aktst
-2a1ku
+a1ku
a2kun
4a3kü
1akz
@@ -726,12 +706,9 @@ al2b3l
al2boh
al2br
alb3ru
-alb3s
al2da
al2dä
al3dri
-alds2
-ald3st
al3du
2ale
3a2l1e2b
@@ -740,6 +717,7 @@ a4l1eh
a2l1ei
a4lein
a2l1el
+ale2n
al3ends
a2leng
al2ent
@@ -757,8 +735,8 @@ al3eta
al3eth
a4l1eu
3alex
-al1exi
al2gli
+1algo
2ali
ali4e3ne
ali4nal
@@ -767,18 +745,19 @@ a2l1ins
a2linv
al2k1ar
1alkoh
-alk3s4
+alk5s2
al2lan
al2l3a6r
-al2lau
+al4län
al4lec
al3lend
all5erfa
al3les
alli5er.
alli7ers.
-2alo
+2allo
a2l1ob
+2alog
alo2ga
al1ope
al1orc
@@ -789,11 +768,10 @@ al2ös
al3skl
al3sp
al4spal
-al5s6terb
al2ta
-al3tam
alt3eig
-al4te4l
+al2te4l
+al3ter
al4t3erf
al2tö
al2tri
@@ -822,28 +800,28 @@ a3mie
a3mil
2a3mir
amit2a
-ami5ti
+ami3te
+am2mac
2ammal
am2min
-ammu2
+am4mod
+am2mus
2amo
a2mö
-2amp
amp2f3a2
am3pr
-am2s
+2ams
am3sa
+am4sc
am3so
-am3sp
-am3str
-3amt.
+1amt.
am2t1a
am2t1ä
-am4tel
+am2tel
am4t3ern
am2to
am2tö
-am4t3r
+am2t3r
am2tu
4amu
am3unt
@@ -855,21 +833,21 @@ anadi3
a3nak
2anan
an3ara
-2anas2
+2anas
2anat
an1äs
1anb
-3anbr
-an5cht
+an3cht
4and.
an5de6s
-an2d1ex
+an2dex
2ando
an4d5rü
and4sas
+and6s5paß
an2d1ur
4ane
-an3e4c
+an3ec
a3nee
an3eif
an1e2k
@@ -891,10 +869,9 @@ an2glä
ang5le.
2ango
ang3ra
+1angri
4angs.
-ang5sc
-ang6s5po
-1anh
+ang6s3po
4a3ni
ani3els
ani5ers.
@@ -910,7 +887,7 @@ ank3ra
ank3rä
ank5ti
an2ky
-1anl
+3anl
2anmu
2ann
3an3na
@@ -919,19 +896,18 @@ an5n4e
an3od
an1or
a1nö
-1anr
+3anr
+anrö5
2ans.
3ansä
1ansc
-an5se
-ans2en
-an6seu
+an3s2en
+an2seu
+2ansk
an3skr
an2s1pa
1anspr
-an3s2t
-an5stei
-an5str
+an5s2te
an3s2z
2ant.
ant2a
@@ -943,7 +919,7 @@ an3th
ant2he
1anthr
2anto
-1antr
+3antr
an2tro
3antw
4a3nu
@@ -956,15 +932,16 @@ a1nü
3anzah
3anzei
anz5erst
+4anzg
an2z1i4n
3anzu
3anzü
an2zw
-ao1i
+ao1i4
a1op
a1or
-a1o4s5
-aot2
+a1o2s
+aot4
a3ot.
ao3ts
a1ö
@@ -972,14 +949,13 @@ a1p
2ap.
4apa
2ape
-a2pé
+3a2pé
ap2fa
a3pfl
a3phä
ap1hel
2a2p3l
ap2n
-apo1s
a2pot
ap3pl
2apr
@@ -987,7 +963,7 @@ ap3pl
2ar.
2a1ra
a3ra.
-ar2ab4
+ar2a1b4
ar3abt
ara3d2
a2r3al
@@ -995,7 +971,6 @@ ar1ang
ar1ans
ar3anz
a2r3app
-ara4st
a2r1au
a1rä
2arb.
@@ -1010,6 +985,7 @@ ar2b5l
2arbr
ar2bre
2arbs2
+arb5se
arb3sp
2arbt
2arbu
@@ -1023,7 +999,7 @@ a2rea
are5b
a2ref
ar1eff
-a4re3g
+are3g
ar1ehr
a2rein
a5ren
@@ -1053,7 +1029,7 @@ ar1ins
ar1int
a3riu
2ark
-ark5amt
+ark3amt
ar2k1ar
ark3aue
ar2kl
@@ -1061,17 +1037,16 @@ ark3lag
ar2kor
ark1r
ar4kri
-arks2
+arks4
ark3sa
ark3sh
ar4les
2arma
arm2ä
-arm3erk
arm2or
2arn
ar5n2e
-2a1ro
+4a1ro
ar1ob
ar3o2d
a3rodo
@@ -1086,15 +1061,12 @@ ar2r3ad
arre4n
ar2rh
arr3he
-2ar2s
-ar3sa
+2ars
ar4schl
ar4schr
-ar5se
+ar3se
ar3s2h
ars3k
-ar3sta
-ar3su
ar2tau
1artd
ar4t3erl
@@ -1102,7 +1074,8 @@ art2ho
artin2
2arto
ar2t3r
-2arts
+ar3tres
+4arts
2a1ru
ar1ums
ar3ü
@@ -1114,25 +1087,33 @@ ar2zä
1arzt
ar2z1w
2as
-as2al
-as3ala
+as2a
+as3ab
+as1ala
a4s3au
+asaus1
a2s1ä
-a6sca
+a2sca
a4schec
asch3la
a2schm
-4as2e
-a2seb
+4a3se
+a4seb
ase3le
aseli5
-a2s3e2m
-a3ses
+a4s1e2m
+a5s2en
+as2er
+a5s2es
+a4sex
4ash
a3s2hi
a5si.
-4asis
+4a5sis
+asi4st
a3skop
+as3m
+aso1
as1o2f
a3sol
a3som
@@ -1144,52 +1125,54 @@ as3pe
as2ph
as2po
as2pu
-as3s2a
-as5se
-as6sei
+as3s4a
+as4sä
+as3se
+as4sei
asse3le
as3s2i
-as5so
+as3so
as2s1p
-as2st
-ass3ti
-as4sto
-as3str
-a2st
-4a4s1ta
-a5s4tas
-as2tau
-a5stä
-as3te
-as3ti
-4a3str
+as4st
+as6s1to
+as5str
+4asta
+as2te
+as3tec
+a4s3tep
+as4ti
+as2to
+4as2tr
ast3rau
-ast3rä
-as4t3re
+a4st3rä
+a4st3re
+a4strol
+a2stum
+a3su
a2sü
3asy
-a1ß
aße2
2a1t
-4ata1
+4ata
a2t1ab
ata2be
-at2af
+at2a1f
at4a5g
at1akt
+ata1la
a3tam
at1apf
+a5tas
a2t1au2
-a3tau.
+a5tau.
at1än
at2c
-4a3te
-a4teb
+4ate
+a2teb
at1eig
a4teli
-a4tep
-ater3st
-a4tew
+a2tep
+a2tew
4atf
4atg
at2he
@@ -1199,6 +1182,7 @@ a4thr
at1int
3atm
4atmus
+a3to.
ato4man
a2t1ort
a2t1ö
@@ -1210,25 +1194,29 @@ at3re
at3rom
at2s
at3sc
+at5sche
+at5schü
+ats1e
at4set
+ats1in
ats1p
+at4st
+at5stä
3attac
att3ang
at2t1au
at2tei
at5thä
-att3rau
-at4t3rä
atts4
+at3tu
4atu
a3tub
atu4n
atu3ren
atu4rer
at3w
-4atz
atz1er
-at2z1in
+at2z1i
atzt2
atz3th
a2u
@@ -1247,7 +1235,7 @@ aue2b
aue3re
au5erein
au5erl
-aue4s
+aue2s
au3et
au2fa
auf1an
@@ -1260,13 +1248,13 @@ au2fo
2aug
au3g6e
4augeh
+2auh
2au1i
au2is
4auj
au2kl
aule2s
aul3ese
-aul4s
au3lü
4aum
au2mal
@@ -1275,8 +1263,7 @@ au2mau
au2mer
au2m1o
aum3p2
-aums2
-aum3st
+aum5str
aum3sz
4au3n2
au4nio
@@ -1288,18 +1275,21 @@ aup2
2au3r2
au2s1ah
ausan8ne.
-4au2sc
+2au2sc
au3schl
au3schw
-2ause
aus3erp
au4s3erw
au2so
au2sp
-aus3s4
+auss4
+aus7sa
3aussag
aus4se.
-au2st
+aus3so
+au4st
+au6stec
+aus3tie
aus3tri
2aut.
au3tan
@@ -1307,8 +1297,9 @@ au2tä
aut1äu
2aute
au4t3erh
+au3tes
3auto
-2auts4
+2auts
aut5st
2aux
auz2w
@@ -1317,17 +1308,16 @@ auz2w
av4a
ava3t
a2vr
+av2s
2a1w
awi3e
a1x
-ax2a
-ax3an
+ax2am
ax2e
+axi4s
2a1ya
a1yeu
-ays2
aysi1e
-ay3ste
2a1z
az4a
azo3
@@ -1342,27 +1332,27 @@ az2u
äch3l
ä2chr
äch2sp
-äch4st
ä1chu
-ä1ck
ä1d
-ä3di
-ä4d1ia
-ä3do
+ä2da
+ä2d1ia
ä2d3r
-2ä3e
+äd2s
+2ä1e
äf2fl
äf5l
äf3r
äf2s
-äft4s3
+äft4s
ä1g
äge1i
-äges4
ä2g3l
ä3g2n
ä2g3r
-äg3s2tr
+äg4s2
+äg5sa
+äg5ste
+äg5str
1ä2gy
äh1a
2ä3he
@@ -1374,10 +1364,10 @@ az2u
2ähm
äh5ne
äh5ri
-2ähs
+2äh2s
2äht4
äh3tr
-ä3hu
+ä1hu
äh1w
ä1im
ä1is.
@@ -1393,35 +1383,37 @@ az2u
äle3ru
äl2l1a
äl2p3
-äl2sc
+äl2s
+äl3se
ä1lu
ä3me
ämi3en
2äml
+äm4ma
+äm2s
ämt2e
2än.
än2dr
-2ä3ne
+2äne
äne2n1
än2f3
2änge
än2gl
än2gr
-äng3se
+äng5se
+äng5ste
2ä3ni
än5k2e
än2k3l
än2kr
-änk2s
än5n4e2
2äns
-än4s3c
+än4s1c
änse3h
ä1on
ä1pa
äp2pr
-äp4s3c
-äp2st
+äp4s1c
1äq
ä2r3a2
är4af
@@ -1435,57 +1427,61 @@ az2u
ä1ri
är1int
är2k5l
-ärk2s
+ärme5s
är1o2
ä1rö
ärse2
-är6si
-är2st
+är2seb
+är4si
ärt4e
-ärt2s3
+ärt4s3
ä1ru
är3ü
är2z1w
äs2a
-äs4e
+ä3s4e
äse3g
äse3re
äser4ei
äse4ren
äse3r2i
äse3t
+ä3si
äskop2
ä3s2kr
ä2s1p
-äs4s3c
+äs4s1c
+äs3se
äs4s3erk
-äs4st
-ä4s3t
-äs5ti
-äs4tr
+äs6st
+äs2te
+ä4str
ä3su
ä1ß
äß1erk
2ät
-ä4t3a2
+ä2t3a2
ä3te
äte1i
äte2n
+ä2th
ät2ha
+ä1ti
ä1to
ät1ob
ät3r
ät2sä
ät4schl
ät4schr
+äts1ei
ät2s1i
äts3l
ät3so
äts1p
-ät2st
-äts3ti
+ät4st
+äts3te
ät2tr
-ä3tu
+ä1tu
ät5ze
äu2br
äu1c
@@ -1496,27 +1492,26 @@ az2u
2äul
2äum
äu2ma
-äum2s
+äum4s
äums1p
ä2u3n2
2äu5r
2ä3us.
äu2sc
-äu6schä
äu4schm
-äu5se
+äu3se
ä1usg
ä1usk
ä1usn
äu2sp
-äus4s3c
+äus4s1c
1äuß
äu2tr
4ä1v
1äx
ä1z
â1t
-6b.
+4b.
1ba
2babs
ba3char
@@ -1527,7 +1522,8 @@ backs4
3bah
bah2nu
bah5re
-bais4
+bai1
+bais2
ba2ka
ba2k3er
ba2k1i
@@ -1535,8 +1531,9 @@ bak5l
ba2kra
3bal
ba1la
-bal4l3eh
+bal4leh
bal6lerg
+bal6lig
bal3th
2b1am
ban2a
@@ -1555,19 +1552,22 @@ bar3b
b2ard
bar3de
ba2rei
-bar2en
+ba3r2en
bar3zw
3bas
-ba5sa
+ba7sa
ba2sc
-ba4st
+ba6str
ba2to
+ba3tor
bau3b
bau3g
-bau3s
-bau1s2k
+bau3s2k
+bau3sp
+bau5str
ba1yo
-3b2ä1c
+3b2äc
+bä1ch
1bäe
1b2är
1b2äs
@@ -1575,10 +1575,10 @@ ba1yo
b1äug
bäu3s
4b1b
-b3ba
-bben3s2
+b5ba
+bbau3sc
bbe4p
-b3bi
+b5bi
bb5ler
b2bli
bb3lin
@@ -1587,18 +1587,16 @@ b3blö
bbru2
bb2s
bbu1
-b7by
-2b3c
+2b5c
2b5d
-bde1st
-bdo3
bdu3s
1be.
3be3a
be5an
be4au.
b2ebe
-1be1c
+1bec
+be1ch
be2del
bedi4
be1eh
@@ -1617,16 +1615,18 @@ be1ind
be1in4h
bei3sc
beis2e
-bei3st
+bei5st
beit2s
3bek
be3las
+be5le
be3lec
be3lei
-be2l1en
-be2let
+be6l1en
+be6let
be3li
-bel3la
+bel5la
+bel5li
bel3sp
bel3sz
belt4
@@ -1634,18 +1634,17 @@ bel3ta
bel3tr
1bem
1ben.
-be3na
-be4nal
+be4na
ben3ar
-be4nau
be3ne
ben4erg
+be4nerl
be4ners
ben3g
be3ni
-ben4se
+ben2se
ben2sp
-ben4su
+ben2su
ben4th
3b2enti
b1ents
@@ -1667,21 +1666,21 @@ ber3iss
ber3na
b1ernt
be1rop
-ber3st4a
+ber5st4a
ber3th
be3rum
-1be1s
-be3sa
-be2s1er
-be3slo
-be3spo
-be3spr
+1be3s
+be4s1er
+be4sk
+be5slo
bes5s4e
b3esst.
bes3sz
-bes2to2
+bes2t
be4s3tol
-be3s4ze
+be4stor
+be4sum
+be1s2ze
3bet
be2tap
be3tha
@@ -1691,19 +1690,20 @@ be1ur
1bez
2b5f4
bfal2
-4b3g4
-b5ga
+bfrä5
+4b5g4
+bga4s1
+bgas3t
bge3
bge5n
-bges4
-2b3h
+bge5s
+2b5h
1bi
bi1ak
bibe4
bi2e
bi3ens
bi3ent
-bie2s
bi3k2a
bi2ke.
bi2kes
@@ -1719,44 +1719,47 @@ bi3n2e
bi2o3
bi3on
biri1
-bi5se
+bi3se
bi2sol
-bis4s3c
-bi4st
+bis4s1c
+bi2s1t
+bi4stü
bi2t
b2i3ta
bi3te
+bi3ti
bi3to
bi3tr
-bit3st
-2bi4tu
-bi5tum
-b2i5tus
+bit5st
+2bitu
+bi3tum
+b2i3tus
biz2
bi3za
4b3j
bjek4to
-2b3k4
+2b5k2
b2l2
2bl.
+b4la.
bla3b6
4b5lad
b6lanc
6blasser
b6latt
b3law
-3b4le2a
+1ble.
+3ble2a
b3leb
2b5leg
b3leh
2b3leid
b5lein
-blei3sc
ble3l
-b4lem
+1b4lem
b4ler
b5lese
-ble5sz
+ble3sz
3b4let
2b3lich
3blick
@@ -1768,17 +1771,15 @@ b4lit
b6loc
b5lok
2b3lun
-blu4ter
3blü
-2b3m
-6b3n2
-bni2
-bnis3
+2b5m
+4b5n2
+bni4
+bnis1
1bo
bo5as
bo2b3l
bo3b4r
-bo2c
bo3ch2
bo3d2
bo2e3i
@@ -1796,7 +1797,6 @@ bo4rä
bor2d1i
bor2d3r
bo2rei
-bor2s
b1ort
bor4tei
bor2t3r
@@ -1806,20 +1806,20 @@ bo4s3p
3bot
bote5n4e
bo3th
-bot2st
+bot4st
bö2b3
2b3öf
bö3sc
-2b3p2
+2b5p2
bpa4g
-2b3q
+2b5q
b2r4
2br.
b4ra.
2b3rad
-b6rah
-b6ra3k
-bra1st4
+b4rah
+b4ra3k
+bra5st4
2bre.
6b5rechte
2b3ref
@@ -1828,45 +1828,39 @@ b3reif
b3rek
3brem
2b3rep
-b4rer
-b4ri
-2b5riem
+b6rer
+2b3riem
bri2er
-2b5rig
-b5ris
+2brig
+b4rio
+bro1
b5roh
2b3rol
b4ruc
+bru6s
brust1
4b1s
bs3ad
-bs1an
b3sand
bs3ar
-bsat2
+b5sat2
b3sä
-b4sär
-b3sc
-b4schan
+b5sc
+b6schan
b7schl
-bs4cu
b3se
b5se.
bs1e2b
+bs1ein
b5sel.
bs1ele
bse2n
-b5sen.
bs1ent
bs1er
-bs5e4r3in
+bs3e4r3in
b5ses
b5set
-bs1ex
-bsi4t
-bs5ko
-bs2ku
-b4sl
+bsi2t
b2s1of
bs1op
bso2r
@@ -1874,44 +1868,42 @@ b2sö
bs1par
bs2pl
b3s2pu
-bs5s2
+bs3s2
bs2t
bst1a2b
bst1ac
bst1ak
bst3ank
+b5stä
bs3tät
-bs4tem
bst1er
+b4stern
bst1h
-b3sto
-b2s3trä
+bs3tip
+b5stra
+b4s3trä
bs3treu
b3stu
-b3stü
-b4stüb
+bs3ty
b2s1un
+bs3w
4b1t
-b3ta
+b5ta
btal3
-bta4s
-btast3r
+bta4st3r
b3tä
b5te
b2t1h
-b3ti
bti2s
b3to
-b3tr
-bts2
-b3tu
+b5tr
+b5tu
btü1
b2u
bu2chi
bu2e3
bu2f
bu5li
-bul2la
2b3umk
bu3na
bunde6s
@@ -1923,6 +1915,8 @@ bus3cha
bu3se
bu4s1er
bus1p
+bu6sterm
+bu4s1tr
bus1u
bu3ße
1b2ü
@@ -1931,19 +1925,18 @@ büge4
bügel3e
2b3v
2b5w
-1by
-by1a
+bwa5re
+1by1
by3p
-by4t
-by5th
-2b3z2
-b5ze
+by2t
+by3th
+2b5z2
bzei2t1
2c.
1c4a
-2ca1b
+2ca1b4
ca1ch
-ca2e3
+cae3
3caf
ca3g4
ca1h
@@ -1956,8 +1949,7 @@ ca3pel
3car
car3n
carri1
-ca3s2a3
-ca4st
+ca3s4a3
ca3th
ca1y2
cä3
@@ -1976,15 +1968,14 @@ cen3ta
ce3n1u
1cer
ce1ro
-ce3sh
-ce1st
+ce5sh
1cet
-2ceta
+4ceta
cet3am
ce3ty
ce1u
1cé
-2c1f
+c1f
c4h
4ch.
2chab
@@ -1992,29 +1983,30 @@ ch3abi
ch1ah
ch1ak
ch2anb
-5chanc
+3chanc
ch1ang
ch3anst
-4chanz
-3chao
+2chanz
+1chao
ch1ap
-4char.
+2char.
ch3arm.
3charta
cha2sc
chasi1
-3chato
-4chatu
+1chato
ch1ärm
ch1äs
1châ
2chb
-4chc
+2chc
2chd
ch3e4ben
ch3echt
-3chef
+1chef
+3chef.
che2fe
+3chefs
4chei
ch1eim
che4ler
@@ -2023,17 +2015,16 @@ che4ler
cher3a
che3rei
6chergeb
-2cherö
ch1ess
2ch3eta
-2ch1ex
+ch1ex
1ché
2chf
2chg
2chh
ch1ia
-3chia.
-3chias
+1chia.
+1chias
6chind
3chines
ch1inf
@@ -2049,103 +2040,72 @@ ch3lein
2ch2m
ch4mu
2chn4
-2chob
-cho6cker
cho2f
ch1off
ch1oh
ch1orc
2chp
ch2r2
-4chre
+2chre
+chre5s
ch3rh
3chron
4chs
-4cht
+2cht
+ch5tes
2chuf
2chuh
2chum
2ch1unf
-2chunt
-4chü
+chus4si
+2chü
2chv
2chw
2chz
1ci
ci1c
+cil3l
ci2s
c1j
-c4k
-4ck.
+2c4k
ck1a
-3cka.
-ck5aa
-2ckac
-2ckal
-ck5am
-2ck3an
+ck3aa
+ck3am
+ck3an
cka4r1
-2ckau
ck1ä
-4ckb
-2ckc
-2ckd
-1cke
-3cked
-4ckeff
-4ckeh
ck1ehe
-4ck3ei
-3ckel
-3cken
-4ck3ense
+ck3ei
+ck3ense
ck1ent
-4ckentw
cke2ra
cke5reig
-4ckerhö
-4ckerke
-2ckero
-2ck1err
+ck1err
cke2s
-2ck1ese
-2ckex
-4ckf
-4ckg
-2ckh
-1cki
-2ck1id
+ck1ese
+ck1id
ck1im
ck1in
-3ckis
-2ckk
-2ck5l
-2ckm
-2ck3n
-2ck1o2
+ck5l
+ck3n
+ck1o2
ck1ö
-2ckp
-2ck5r
-4cks
+ck5r
ck3spo
-4ckt
-ck5t2e
+ck5ste
+ck4stro
+ck3t2e
ck3ther
-3cku
-4ck1um3
-4ckunt
-4ck1up
-2ckv
-4ckw
-1cky
-4ckz
+ck1um
+ck1up
3c6l2
-clet4
+clet2
clo1c
c2m
-3co
-co2c
-co3ch
+1co
+3coa
+3coc
+co1ch
co2d
co4der.
co3di
@@ -2163,30 +2123,27 @@ co1ra
co4re
cor5t
cos4
-co4te
-cô4
+co4st
+co2te
2cp
-2c1q
+c1q
c4r2
cre2
cre4mes
cry2
-2c2s
-cs2a
-c3se
+2cs2
+c2si
cst4
-c3s2tr
2c1t
cte3e
-c3ti4
-c3to
+cti4
+ction5
ctur6
-3cu
+1cu
cu2p3
cup1e
cussi4
1cy
-2cz
4d.
3da.
da1a
@@ -2204,10 +2161,10 @@ da3dr
da1er
2d1af
d1ag
-dagi4
+dagi4o
dah3l
da1ho
-3d4ai
+3d4ai4
da1in
da1is
da1l2a
@@ -2218,6 +2175,7 @@ da1lö
2d1amma
2d1ammä
damo3
+d2amp
damp7f8erf
2d1amt
d2an.
@@ -2238,22 +2196,21 @@ d2aph
4dapp
da2r3a
2darb6
+dar3bl
3d2arl
dar2ma
dar2m1i
da2ro
2darr
-dar3s
2dart
d1artg
da2ru
d2arw
-das4
da3s2h
-da5s2t
3dat
da3ta
dat2e4
+da3tei
4d3atl
4datm
3dau3e4
@@ -2262,27 +2219,26 @@ dat2e4
2d1äh
2d1ämt
2d1änd
-2d1äng
+2d1äng5
2d1äp
2d1ärz
dä2um
dä1us
-2d7b6
+2d7b
dbu2
2d1c
4d3d2
-ddar2
ddar4m
d5de
1de
de3am
de3an
de3as
-de5a4t
-de3b6
+de5a2t
+de3b4
4d1e4ben
-3de1c
-de2cka
+3dec
+de1ch
deco3
de1e2
2d1eff
@@ -2294,6 +2250,7 @@ de3ho
d2eic
3d2e1im
de2l1a4g
+delat5
de4l3aug
de4l1än
del1ec
@@ -2303,38 +2260,37 @@ de3l2ei
de2len
2d1elfm
3delik
+del4la
delle2
-del4leb
del4lei
+del2lö
de2l1ob
de3lor
de2lö
-del2s5e
+del2s1e
del2so
del2s1p
-del5ster
delt4
del3ta
+del3te
del3tr
de6ments
2d1emp
d2en.
-dend2
-dend4s
de4n3end
den3g
de2ni
den4k5li
-den3sc
+4densem
den4sen
-dens5tau
+den6s5tau
den3th
2dentw
de2ob
2deol
de1on
deo4no
-depi2
+depi4so
d4er.
de1rad
de2r3ap
@@ -2346,6 +2302,7 @@ de3r4erb
de3r4erf
de4r3ero
4d3erhöh
+d4eri
de5ric
de3rik
4d3erklä
@@ -2354,7 +2311,6 @@ de2rop
d3ersat
dert2a
der6t5end
-dert2s
de3ru
de4ruh
de4rum
@@ -2368,17 +2324,14 @@ de3se
des1en
des1in
des1o
-des1p
-des3pot
-des3s4
-des5se
+des3p
+des5s4
dest5alt
de5stang
-de5star
-de5stat
-de7stel
-de4sto
-de3str
+de5ste
+de6s3tei
+de5sti
+de7stin
dest5rat
de5stri
de5stro
@@ -2392,14 +2345,12 @@ de2xis
2dexp
2d3f
2d1g
-dga2
d2ge.
d3gem
dge2ta
dge6t5e
d3gl
2d1h2
-dhas2
d2his
d3hu
1di
@@ -2415,16 +2366,16 @@ dich3te
di2de
di2e
di3e2d
-die3ner
+die5ner
di3eni
di3ens.
dienst5r
-die4s3c
+die4s1c
die2t5
-dige4s
+dige6s
di3gn
di3ka
-dil2s3
+dil4s1
2d1imb
din2a
2d1ind
@@ -2444,10 +2395,7 @@ di2ris
2d1irl
2d1isr
dist4
-di4ste
di2ta
-di3te
-di4tei
di4teng
di4t3erl
di4t3erm
@@ -2455,7 +2403,6 @@ di4t3ers
di2t3r
di2tu
diz2
-di3zi
2d1j
2d1k4
4d1l
@@ -2475,8 +2422,7 @@ d1o2be
dob4l
3dobr
3doby
-do2c
-do3chi
+do1chi
3dog
do3ha
3dok
@@ -2484,7 +2430,7 @@ dol3l2
do2mar
3don
do5n4a
-doni1e
+doni1
do2o
4d1opf
d2opp
@@ -2500,10 +2446,9 @@ do2rie
d2orp
d2os.
do3sp
-dos3s
+dos3s4
dost3
-do4sta
-do3str
+do6sta
3dot
dot4h
do3un
@@ -2512,13 +2457,12 @@ do1y2
d1öf
d1öl1
3dör
-dö4s3c
+dö4s1c
2d3p2
2d1q
d2r4
3d4ra.
2d3rad
-drag4
d4rah
2d5rahm
3d4ram
@@ -2553,16 +2497,18 @@ d3rieg
d4rif
d3rind
3drisc
+2driß
3d4rit
4dritu
2drob
d3roc
2d3rod
d4roi
+dro3ma
2d3rot
d3rou
2d3rov
-drö4s3
+drö4s1
3d4ru
d5rub
4d5ruf
@@ -2570,21 +2516,20 @@ d5rub
4d5rut
3d4rü
drü1b
-drü5cke
-2ds
+2d1s
ds3ab
-d4s3amt
+d4s1amt
d2s3an
ds3assi
-d2s1au2
+d2sau2
d2s1än
4dsb
d4schin
d2s1e2b
d3sec
d2s1ef
-d5s4eig
-d2sein
+d3s2eig
+d2s1ein
d2s1eng
d2s1ent
d2s1erf
@@ -2596,12 +2541,12 @@ d4s1eta
d3s2ha
ds3han
d3sho
-ds3hu
d2s1im
ds2inf
d3s2kan
d3skul
4dsl
+ds3m
d2s1op
dso2r
ds1ori
@@ -2612,33 +2557,28 @@ d2s1pä
d3s2po
d4spro
dss2
-ds3st
+ds5st
dst4
-d2s1tab
+d4s1tab
d4s3täti
-d5stei
-d5stell
-d3s4tern
-ds1th
-d1s2ti
-ds4til
-d3stip
-d1str
+d6stea
+ds2til
+d5stip
+d4s1tis
+d2stod
d5stre
-ds2tri
-d1s2tu
ds1ums
d2sun
-d1sy
ds2zen
4dt
d1ta
dt3a2d
d1tä
-d5tea
+d1te
+d3tea
dte5na
dt3ha
-d3ti
+d1ti
d1to4
d1tö
dt3r
@@ -2649,6 +2589,7 @@ dt5sc
dt3sp
dt5str
dt3t
+d1tu
d1tü
1du
du1alv
@@ -2658,7 +2599,7 @@ du3e
du2f
2d1ufe
2d1uh
-du1i
+du1i4
3dum.
d1umb
2dumd
@@ -2677,39 +2618,33 @@ dun3d
dun3ke
dun2kl
2dunr
-dun2st
2dunt
du1os
dup4
-dur2
+dur2c
2d1url
-3du2s
+3dus
+du2sc
du3scha
-du3se
-dus1t
2düb
3düf
3dün
3dür
-dürn3
2d1v2
2d1w
-dwa4
dwa2l
-dwes4
+dwe4s
dwest1
dy3n
2d1z
-4e.
+6e.
2e1a
e3a2b
-ea2c
eadli4
e2ag4
ea2ge
ea3gl
eakt4
-eak3to
e2al
e3al.
e3alb
@@ -2730,6 +2665,7 @@ eam3a
e4ame
eam1o
eam3to
+eam3tu
ea2na
e5and
e4ano
@@ -2742,7 +2678,9 @@ e4are
e5a6rene
e3arm
e3art
-eas3s
+ea6se.
+eas5s
+ea4st
e4at.
eat4e2
eate4r
@@ -2754,6 +2692,7 @@ eau3b
e3au2f
e3aug
e3ä4
+eäng5
e1b
2eba
e3b2ak
@@ -2761,7 +2700,7 @@ eba3ra
ebe2i
eb4en
e3beng
-eben6s5e
+eben4s3e
2ebet
2ebl
eb5ler
@@ -2775,22 +2714,23 @@ ebö4s
e3bra
eb3rei
eb2s
-ebs1au
+eb6sche
eb4se2
ebs1i
ebs1o
ebs1p
ebs3pa
-eb4stät
-ebs5tem
+eb6stät
+eb4stec
+ebs3tei
ebs3th
ebs3ti
-eb3str
+ebs3tot
ebs1u
e3bu
ebu2t1
eb3üb
-2e3ca
+2eca
e1ce
ech1ä
2e3che
@@ -2809,22 +2749,19 @@ e1chu
ech1uh
ech3w
eci6a
-e1cka
eck3se
2eckt
2ecl
-2eco
-e5cr
-ecs1
+e1cr
2ect
e1d
ed4dr
ed4e
+ede4c
e3dei
ede3n2e
-eden2s
eden4se
-edens3p
+eden4s3p
ede2r
ed2ge
edi4a
@@ -2834,29 +2771,29 @@ ed3s2ä
ed2s1es
ed2s1o
ed2s1p
-ed2s1tr
+ed5sta
+ed4s1tr
ed2su
e3dy
-6ee
+4ee
ee5a2
eeb4l
ee2ce
ee1ch
-ee2cho
-ee2ck
eede3
-eed3s2
+eeds2
ee1e
ee3ei
e1eff
-eef3s
+eef5s
eeg4
e1ei2
eei3e
ee1im
ee3ing
+eei3se
eel2e
-e1e2lek
+e1elek
ee3len
e1emp
e1en
@@ -2869,25 +2806,23 @@ e1e2pi
e2e1ra
e1erbt
e1erd
+eerde3c
ee3r2e
ee4r3eng
-eere4s
+eere4s5
ee4ret
e2e1ro
-ee1r2ö
+ee1r2ö5
eer3öf
eert2
e1ertr
e2erü
e1erz
-ees2
-ee3sh
-ees3k
+ee5sh
ee3st
ee2tat
ee2th
ee1u2
-eewa4r
e1e2x
e1f
2ef.
@@ -2924,7 +2859,7 @@ ef1rol
ef3rom
ef3rot
efs2
-ef5sc
+ef7sc
ef3so
ef3sp
ef2tan
@@ -2936,22 +2871,21 @@ e1g
e3ge
ege4n1a
ege2ra
+ege4s3to
+ege4str
ege1u
+eg3la
eg4li
eg3lo
eg3lu
e2gn
eg3ni
-eg4sal
-eg6ser1
-egs2pe
-egs2t6
-eg1ste
-eg4sto
-eg1str
-egs3trä
+eg6sal
+egser1
+eg3spe
+egst6
+eg6sto
2e3gu
-egus1
2e1ha
eh1ach
eh3aka
@@ -2965,7 +2899,6 @@ ehen2t3
1e2hep
ehe1ra
eher4an
-ehe3str
e3h2i
eh3int
eh1lam
@@ -2983,15 +2916,17 @@ e1ho
e3hol
ehr1a
ehr1ä
-ehr3e2c
+ehr3ec
eh2r3ei
eh1ri
eh1ro
ehr1ob
ehr1of
-ehr5sch
-ehs2
+eh2s2
+eh3se
eh3sh
+eh3si
+eh3so
eh3sp
eh3te
e1hu
@@ -3004,9 +2939,10 @@ e1hy
2ei3a2
4eib
ei2b3l
-eibu4t
+eibu2t
ei4b3ute
ei2cho
+eichs7test
eich5te
e2id
ei2d1a
@@ -3017,8 +2953,7 @@ ei3dra
ei1e
ei3el
2eien
-eien3st
-ei3erv
+eie4s
ei3et
1eifr
ei3g2a
@@ -3081,13 +3016,15 @@ ei2sä
ei4s3erw
ei3sp
eis2pe
-ei3sto
+ei4str
+ei2sum
ei2ta
2eitä
-eit1h
+ei3ten
+ei2t1h
ei2tro
eit3t2
-ei4t3um
+eit3um
2eiu
2e1j
e1k
@@ -3103,18 +3040,16 @@ ek4l
ek5lip
ek4n
2ek2o
-ek3s4t
2ekt
ekt4ant
ekt3erf
ekt3erg
ek4t3erz
-ek3t2o
+ekt2o
e3k2w
2e1la
e3lab
el3aben
-ela2c
el1af
el3agi
ela2h
@@ -3127,13 +3062,12 @@ e2l3anz
el1ap
e2l1a2r
el5ari
-ela4s
el3asi
el3asp
e3law
2e1lä
+elb4
1elbis
-elb4l
el2da
eld5erst
eld3erw
@@ -3141,8 +3075,7 @@ el3des
el3dr
elds2
e5le.
-elea2
-ele4c
+elea4
2elei
e3leie
e6l5eier.
@@ -3171,7 +3104,6 @@ e3let.
e2l3e4ta
2elev
ele2x
-el1exi
el3fe
elf3ein
elf4l
@@ -3182,15 +3114,16 @@ e3lie
e2lim
eli4n
el1ita
-ell2a
-el3lan
+elks2
+el3l2a
+el4läu
el5le.
ell3ebe
el4l3ein
ell3eis
el3les
-el5lin
-ell5sp
+el2lic
+el3l2in
elm2a
2eln
el5na
@@ -3208,20 +3141,20 @@ e1lö
el2san
el2ser
el2spr
-els6tern
el2su
el2ta
-el3tak
+el3t2ak
elte2k
elt3eng
-el4t3in
+el3tes
+elt3in
el2to2
el2t3r
el3tri
el3tro
elts2
elt3sk
-elt5sp
+elt3sp
2e1lu
e2l1um
e3lung
@@ -3234,8 +3167,7 @@ el3zwe
2ema
e2m3ad
ema2k
-em1anf
-e3mann
+e2m1anf
em1ans
3emanz
e5mä
@@ -3244,13 +3176,13 @@ em4d3a2
eme4n
emen4t3h
e2m1erw
-eme2s
3e2meti
em1ex
em1im
em1int
-emi5ti
+emi3te
2emm
+em2map
emma3u
e3mon
e2mop
@@ -3265,7 +3197,7 @@ em3t2
e2na
4ena.
e4na2b
-2e3nac
+2e5nac
e3nad
e4naf
4enah
@@ -3275,7 +3207,6 @@ ena3l2i
4en1am
en4ame
e4nand
-e5nann
en3anz
en1ap
e4nar
@@ -3290,18 +3221,16 @@ e3näc
en1är
en1äu
en2ce
-en3del
-end3ess
+en4d3ess
en3do
end4ort
end3ras
-end7si
+end5si
end3s2p
end3sz
en3dum
2ene
-en1e2c
-ene4ck
+en1ec
e2nef
en1ehr
en3ei.
@@ -3314,6 +3243,7 @@ e5n4entr
en1epo
4ener.
e4n1erd
+e4nerf
3e2n3erg
e4n3erh
4e3neri
@@ -3326,10 +3256,12 @@ en1ers
e2n3ert
e2n3eru
e4n1erw
-en3erz
+en3erwe
+e6n3erz
e4n3ess
en3eta
en3eth
+ene3tr
en1eup
e4nex
en3fa
@@ -3340,8 +3272,8 @@ en5g2i
en2gl
en3glo
1engp
-eng5sc
-eng3se
+eng5s
+eng7sc
2eni
e3nic
e4n1id
@@ -3355,8 +3287,8 @@ e5nit
en3k2ü
e2n1ob
enob4le
-e2n3oh
-e3n4ol
+e2n1oh
+e3nol
eno2ma
en1on
e2n1op
@@ -3371,17 +3303,19 @@ e6nr
en2san
en5sche
en7schen
-en4seb
+en2seb
1ensem
ens3eng
en3sho
en2sid
-en3s2ka
+en3ska
en3s2po
enst5alt
en4s3tät
+en6s5test
4ensto
-en3stoc
+en7stric
+ens5trie
en5t4ag
en3tanz
1entd
@@ -3434,9 +3368,9 @@ e3ord
eorgi1
e3ort
e3orw
-eo3s2
+eos2
e3os.
-eo1st
+eo5st
eo3ul
e1o2v
e1ö2
@@ -3447,13 +3381,13 @@ e3p2f6
1episo
ep3le
e2poc
+epor5te
ep2pa
ep4pl
ep2pr
ept2
ep3ta
ep4tal
-ep5ti
e1q
er1a
e5ra.
@@ -3513,7 +3447,7 @@ erd3erw
4e5re.
e3rech
er3echs
-er1e4ck
+er1eck
ere4dit
er1eff
er1e2h
@@ -3549,6 +3483,7 @@ e2r1erw
4eres
e5res.
er1ess
+er1eß
er3e4ti
er1eul
ere3us
@@ -3558,18 +3493,16 @@ er3fä
3ergebn
4ergehä
erg3ise
-erg3s4
e2r3h
3erhab
-4e1ri
+2e1ri
e2riat
e3rib
-6e3rie
+4e3rie
eri5e4n3
-erien5e
e5rif
erik6
-6e3rin.
+4e3rin.
er1inb
er1ind
e4r1ini
@@ -3579,8 +3512,8 @@ e4r1int
e3rio
er1ita
2erkol
-erk5te
-erk5tr
+erk3te
+erk3tr
4erl.
3erlebn
4erln
@@ -3588,7 +3521,7 @@ erm2
er3ma
erm3ers
er3nan
-er2n1o4s
+er2n1os
e1ro.
er3oa
er1ob
@@ -3608,19 +3541,18 @@ e1row
e1roz
er1ö2
e1röh
-4erök
+2erök
+erö4s
er5p
er3ra
-er5rä
2errü
er3sa
-ers2au
-er5sen
-er7s2i
+ers4au
+er3se
+er5s2i
er3sk
er3smo
er3sn
-er3sum
er3s2z
ert3abe
ert2ak
@@ -3633,6 +3565,7 @@ ert3ins
er3to
erts2e
2e1ru
+eruf6s
er1uhr
er1u2m
er1uns
@@ -3641,36 +3574,35 @@ er1uz
e1rü
er3ü2b
e5rüg
-2erv
3erweck
6erweis
2erzy
+es2a
e4s3ab
-es4ach
es3ad
es3ak
-e5s4a4s
-es3aus
+es3alt
+es3ar
+e5s4as
es3av
-esä2c
2esb
e3sc
es3cap
-e5s4ce
+es4ce
esch4
e6schan
esch2n
+e4sco
e6scu
es1ebe
es3ehr
-es3ein
+es1ein
es1eis
es1eta
es3eva
2esf
-6esh
+6e4sh
es2har
-es3he
es2hu
e3sid
e5sie
@@ -3679,71 +3611,71 @@ es1ini
es3int
e3sir
e7sis
-es3ke
+e5sit
+es5ke
es3ki
-es3kl
-es3ku
e4s3ky
-es3l
-es4log
-2esm
+e4sl
+es2log
+2e4sm
+e4sn
e3sof
e3sol
eso2r
es2ort
es4pei
-e3spek
+e3s4pek
+e5spi
es2po
-e5spor
+e5s4por
+es2pr
e5s4pra
2esr
+es6saa
1essay
-es3sc
-es5sec
-6essem
+es3sec
ess4e3re
es4s3erg
+es4sit
2esso
es2sof
es2sp
ess1pa
-es2st
+es4st
ess3tie
-es3str
-e5staa
-e2stab
-estab4b
+es5str
+es5su
+e2st
+estab6b
est1ak
-e3star
e4starb
-es2tau
-es3taum
-e3stec
+es6tau
+es7taum
+es2te
+es6te.
est5eink
-e5stel
-es4t3eng
-es4t3erh
-es4t3ess
-e1stil
+e7stel
+e4st3eng
+e4st3erh
+e7stern
+e7sters
+e4st3ess
+es4ti
+es5tip
estmo6de
-est3ori
-e1s2tr
+est3o4ri
es3trop
-e1s2tu
-es3tus
-e3s4tü
+e3stu
+es4tü
e2s1um
-es3ums
es1ur
-es3w
e3sy
-es3z
-e1ß
eße3r2e
2et
e1ta
eta3b6
et1am
+etari1
et4at
e1tä
et1äh
@@ -3764,8 +3696,6 @@ eti2ta
e3to
eto4b
e4t1of
-etons4
-eto4s
e1tö
4e1tr
e4t3raum
@@ -3773,25 +3703,23 @@ et3rec
e2t3res
et4ri
et4ro
-et2s
-et3sc
-et5schu
etsch3w
-et3se
et3so
et3sp
-et3sto
-et3str
et3su
et2ta2
et4tang
ett3au
+et2tä
et2tei
ette4n1
ett1h
et4t3r
ett3sz
-et4t1um
+et2t1um
+et2tur
+et2tü
+e1tu
et1ups
e1tü
et4z3ent
@@ -3799,7 +3727,7 @@ et3zo
eu1a
eu3ere
eu3erz
-eu2esc
+eu2e5sc
eu2ga
eug6er
eug3l
@@ -3813,26 +3741,26 @@ e1um
e3um.
e3umb
e3uml
-e3um4s
+e3um6s
eums1p
eum5st
+eum7str
2eun
eu3n2e
e3ung
eu4nio
+eun3ka
eu1o2
eu3p
eu2rau
eu3r2e
eur4er
-1eu3ro
+1eu3ro1
eu4sk
eu3sp
e4ust4
-eu1str
2eut
-eu5te
-eu3to
+eu3te
2eux
eu2zw
e3ü
@@ -3840,6 +3768,7 @@ e3ü
4eve
e2vela
e2vent
+ev2s
e1w
2e3wa
ewa3s
@@ -3851,25 +3780,24 @@ ew3et.
e3wir
ewi2s
e3wit
-e5wo
ew2s
2ex.
-1exam
ex3at
1e6xem
e4x1er
e2x1in
+1exis
3exp
2ext.
-e1xy
+ex2tin
+2exu
+2e1xy
2ey
ey4n
-ey3st
e1z
-e3z2a
+e5z2a
e2z1enn
e3zi
-ezin4
ezi2s
é1b
é1c
@@ -3889,16 +3817,17 @@ ezi2s
è1n
è1r
ê1p
-ê4t
6f.
1fa
3fa.
-fa1b
+fa1b4
fa2ben
+f3abf
+fab5s
3fac
-fa4cheb
+fa3che.
+fa3chem
fa2ch1i
-fa2cho
2fad
fa2da
3fa1e
@@ -3909,11 +3838,13 @@ fa2ke
f2al
fa1l2a
fal2kl
+fal6lenk
fal6l5erk
+fal2li
fal2s
-fal3te
falt4s
fal2z1
+3fam
2fanb
fan3da
2fanf
@@ -3925,14 +3856,13 @@ fan2gr
2f1ap
far2b3r
3fari
-farr3s
3f2art
fa5ru
f1arz
3fas
-fa3s2a
-fa5se
+fa3s4a
fa3sh
+3faß
2fat
fa2to5
2f1auf
@@ -3952,9 +3882,7 @@ fä2ßer
f3ds
1fe
3fe.
-fe4c
f2ech
-fe5che
4f3eck
fe2dr
fe2ei
@@ -3962,6 +3890,7 @@ fe1em
f4eie
4feinh
fei2nu
+fei5st
fek2ta
3fel
fe2l1a
@@ -3969,9 +3898,12 @@ fel4dr
fel5eise
4f1e2lek
fe2l1er
+fel5lä
fe2l1o
fel4soh
fel3to
+fel3tr
+fel3tu
3f2em.
2femi
fem4m
@@ -3983,7 +3915,8 @@ fe2ni
fe2no
fen3sa
fen7sc
-fenst2
+fens2t2
+fen5ste
f1ent
f2er.
fe1r2a
@@ -4000,10 +3933,10 @@ f4erpa
f2ers.
f2ert
f1erw
-fe2s
+fes2t
fe4st1a
-fes3tat
-fest3ei
+fe4st3ei
+fe4str
2f3e4ta
3fete
fet4t1a
@@ -4012,8 +3945,10 @@ fet4t1a
4fexp
3fez
1fé
-4f1f
+6f1f
+ff2ab
ff1ar
+ff2arb
ff3at
ff1au
ff2e
@@ -4025,6 +3960,7 @@ ffe2m
ff3emi
f5fen
f5fer
+f2fetz
fff4
ffi3k
ff6lei
@@ -4042,12 +3978,10 @@ ff3sho
fft2
fft3h
2f3g4
-fge1
2f1h
1fi
3fi.
fi3at
-fien3
fi1er2f
fi2ki
fi3kl
@@ -4062,20 +3996,18 @@ fi6lin
fil2ip
fin4a
fi3ni
-fin4s3
2f1int
fi3ol
fi2r
fi3ra
3fis
fi3s4a
+fi4scha
fisch3o
fi3so
fi5s2p
-fi4s3t
-fi3te
fi2t1o2
-fit3st
+fit5st
fi3tu
5fiz
2f1j
@@ -4103,12 +4035,11 @@ flug1a
f4lü
2f1m
2f3n2
-fni2s
+fni2
1fo
fob4l
2f1of
fo2na
-fon3st
fo2nu
2f1op
fo1ra
@@ -4117,17 +4048,17 @@ fo3rin
3form
for4m3a4g
forni7er.
-for4st
+for4sta
for2t
for4te
for4th
fort3r
for3tu
+fo5st
2fo2x
2f1öf
2f1ök
2f1öl
-förs3
2f3p2
fper1
2f1q
@@ -4137,6 +4068,7 @@ f5rad
fra4m
f3rand
1f4rän
+frä5st
2f5re.
f5ref
2freg
@@ -4150,30 +4082,30 @@ fri2e
2frig
fri3k
1f4ris
+fri6ster
+f4riß
f3roc
1f4ron
-fro2s
+fro2sc
fru2h
4fs
-fs1all
-f2s1an
+f2san
fs3ar
f2s3as
-fs1auf
f2saut
f3sc
+f4sce
f4schan
-f5schl
-fs4co
fs1e2b
fs3ehr
+fs1ein
f2s1em
f4s1ent
f2s1er
fse4t
f4s1eta
f3si
-fsi2d
+f2si2d
f2s1o2
fs3ol
f3span
@@ -4185,19 +4117,18 @@ f2s1pr
fs2pra
fs2pri
fs3s2
-f1s2t
-fs3tak
-fs3tät
+fs1tak
+f4stas
+fs2tau
+fs1tät
f4stäti
f4stech
-f3stei
f5stel
-f3stern
-fs3th
-f3st4r
+f4stemp
+f4s1tis
+fst4r
f4s3tres
-fs4tro
-f3stü
+fs2tro
f4s3tüte
f2s1un
f2sü
@@ -4216,8 +4147,7 @@ ft1e2h
ft1eig
ft1ein
ft1eis
-fte3ma
-f4t1ent
+f2t1ent
f2t3e4ti
f2t1h
f4t3hei
@@ -4228,14 +4158,13 @@ f2t3ro
ft3rö
f3t4ru
ft2s1
-ft4s3a2
+ft4sa2
ft3sc
-ft6sche
ftse2
-ft3st
-fts3tan
-ft4s3tä
-ft5sti
+ft4stä
+ft5s4ten
+ft5s2ti
+ft3sü
ft3t
ft1url
ft3z2
@@ -4248,12 +4177,14 @@ fun4ko
fun2k3r
2f1unm
2funt
-furch4
+furch2
fu4re.
fu5ru
-fus2sa
-fus2s1p
-fus2st
+fus3se
+fus6senk
+fus4ser
+fuss1p
+fus4s1t
fu2ß1er
3fut
1fü
@@ -4270,13 +4201,12 @@ fz4s
6g.
1ga
5ga.
-gabe4n
2gabf
-gab5l
-ga1br
+ga2b5l
+ga1b4r
ga3bu
2gabz
-ga1c
+ga1ch
ga3di
ga1e
ga1fl
@@ -4292,11 +4222,11 @@ g1anf
gan2g1a
4gangeb
gan2gr
-2ganh
+2g1anh
2g3anku
2ganl
-g3anla
3gano
+g4ant
2ganw
ga1ny
2g1arb
@@ -4306,15 +4236,18 @@ ga1ny
ga3r2o
g1arti
2garz
-ga2s1a
+ga2s
+gas3a
ga4sal
-gas3ei
-ga2si
-ga2so
-gas3s
-ga4st
-gas4t3el
-gas4tra
+ga3sc
+ga5se.
+gas1ei
+gas5s
+ga4sta
+gas3tan
+ga4st3el
+ga4stra
+gas1tu
ga3t2a
ga3th
2gatm
@@ -4327,9 +4260,10 @@ g2auk
1gä
2g1äp
g1ärz
-3gäs
+3gäs4
+gä5st
gä4u
-4g1b
+6g1b
g5be
gber2
g5bo
@@ -4356,20 +4290,21 @@ ge3a2
ge3ba
gebe4am
geb4r
-ge3c
+ge1c
ge3d
ge1e2
ge3ec
ge2es
gef4
+geg4l
ge3ha
ge1im
ge1ins
ge1inv
ge1ir
-ge2is
4geise
gei3sh
+gei4sta
g2el
gel6ders
ge3le
@@ -4378,9 +4313,9 @@ ge4less
ge3lor
gel3sa
gels2t
-gel3ste
gel3sz
gel3t2a
+gel3to
ge3lum
ge3lü
gel3z2
@@ -4397,9 +4332,8 @@ gen3eid
gen3ern
gen3g
gen3k
+genmes4
ge3nor
-gens3am
-gen7stern
gen3sz
g1entf
gen3th
@@ -4424,30 +4358,26 @@ ge1ro
ge1r2ö
ger4sto
3gerw
-ges2
-ge5s4am
+g6es
ges3auf
-ge5s4c
+ge5s2c
ges3elt
-ge2s3er
+ge2s1er
ge3ses
-ge3si
+ge3s2i
ge3sp
-ges4pi
-gess4t
-ge1st
-ge3ste
-ge5stei
-ges4tem
-ge4s3ter
+gess2t
+ge3st
get2a
+ge3tan
4getap
ge3t2u
ge1ul
+gewa5re
4g5ex
2g3f2
-4g1g
-gga4t
+2g1g
+gga2t
g5ge
gge2ne
g2g3l
@@ -4455,6 +4385,7 @@ gg4lo
g2g3n
gg4r
g3grä
+gg4s
2g1h
4gh.
3g2het
@@ -4487,7 +4418,6 @@ gi2o
gi3ro
2gisel
git2a
-gi3tu
gi2us
2g1j
2g5k
@@ -4498,9 +4428,13 @@ g2l
3glad
2g3lag
3glanz
+gla4s5ti
+gla4stu
3g4laub
2g3lauf
1glä
+3gläs
+g3läß
3glät
2gläuf
1gl4e
@@ -4521,12 +4455,11 @@ g3li
g4lia
2glib
3g4lid
-5g4lie
+5g6lie
2glif
1g4lik
g5lin
-1g4lio
-gli2s
+1g6lio
4glisc
1g4lit
1g4liz
@@ -4541,11 +4474,12 @@ g4lom
1g4lot
g3lö
2gls
-2glu
-glu2t
+2glu2
+glu3te
3glü
3gly
-4g1m2
+2g1m2
+gmi3te
gn2
4gn.
g2na
@@ -4559,7 +4493,7 @@ g5neh
g2nie
g2nif
g4nin
-4g5nis1
+4g5ni4s1
g2no
gno1r
2g3not
@@ -4577,7 +4511,7 @@ goa3li
go3be
2g1of
2g1oh
-go1i
+go1i4
gol2a
3gon
2g1ope
@@ -4585,7 +4519,6 @@ gol2a
3g2o1ra
3gos
go2si
-go3st
go3t2h
got6t5erg
3gou
@@ -4629,6 +4562,8 @@ gro3be
gron4
g4ros
gross5el
+gros8seri
+g4roß
gro4u
2g3röh
g4ruf
@@ -4640,116 +4575,135 @@ g4ruf
grü1b
2g3rüc
3g4rün
-4g2s1
+4g2s
+gs1ac
gs3ad
-g4sa2g
-g3s2ah
+gs1af
+gs1a2g
+g5sah
gs5a2k
-g3sal
-gs3ama
-gs3amb
+g5sal
+gs1ama
+gs1amb
gs3an
gs3ar
gs3as
g5sat
gs3aug
-g5sät
-g3sc
-g6sca
-g6sce
+gs1ä
+g7sät
+g5sc
gsch4
-g4schan
+g6schan
+g7schä
g6schef
-gs4chi
-gs3cr
-gse2
-g3s2eil
-g3sel.
-g3seln
-g4s5er
+g7s2chi
+g7schl
+g7schö
+g7schu
+g7schü
+gs1cr
+gs1e2
+g5s2eil
+g5sel.
+g5seln
+gs3ene
+g4s3er
gse4t
+gs1i
gsi2d
-g5sil
-g4s3l
-gso2
+g7sil
+gs3l
+gs1o2
g3sol
-g5soz
-g3spek
+g7soz
+gs1ö
+gs1p
+g5spek
gs2pi
-gs6pie
-g4s3pin
-g5s4por
-gsrü2
-gs5s4
-g3star
-gs4tati
+gs3pin
+g5s2por
+g4spu
+gs3s2
+g3st
+gs1ta
+g5s2tar
gst1au
-g4stä
-g5stäm
-gs3te
-g3s4tel
+gs1tä
+g5ste.
+gs3teil
+g7stel
+g5sten
gst3ent
+g5ster.
gst3err
+gs3test
gs4teu
-g3stir
-g3s2to
-g4s3tor
-gs2tö
-gs4tör
-g1stre
-gs4t3ros
-gs3trü
-g3stu
+g5sti
+gs3tier
+gs1tis
+g5sto
+g6ston
+g6s1tor
+gs1tot
+g5stö
+gs1tr
+gst4ri
+gst3ros
+g5stuf
+g5stun
+gs1tü
gs2tüc
-g4s5w
-g3sy
-2g1t2
+gs1u
+g5sub
+g5sy
+2g1t
g5te
-g2t3h
+g2t1h
g5ti
gti2m
-gts3
-gt3t
-gt3w
+g5tr
+gt4se
1gu
gu1an.
gu1ant
-gu1c
gu2e
-guet4
+guet2
2g1u2f
2g1uh
gu3ins
gu1is
gu5me
+3gumm
gun2e
2g1unf
g2ung.
-gunge6
+gunge2
4gungew
2g1ungl
-3g2un4s
+3g2uns
4gunt
gu3re
2g1url
-gu4s
-gus3a
-gu5sc
+gu4s3a
guschi5
-gu5se
-gus5se.
-gus2st
+gus6saa
+gus6sam
+gus4st
+gu2ß1
5gu2t1
+gu3te
1gü
2güb
gür1
-güs1
+gü5st
2g1v
4g5w
+gwa5re
1gy
gy3n
2g3z2
-4h.
+6h.
2ha.
hab2a
hab2e
@@ -4768,7 +4722,6 @@ ha3go
ha3ha
hai1es
h2aka
-haki3
ha1kl
4h2al.
ha1la
@@ -4778,12 +4731,10 @@ ha2lau
hal2ba
hal4bei
halb3r
-halb5s
-2ha3le
-ha3li
+2hale
+hal4leh
hal6lerf
h1alp
-hal4st
halt3r
h1amt
h2an.
@@ -4792,7 +4743,7 @@ h2and
h4ann
2hanr
2hant
-ha3os
+haos5
2hap
ha2pr
h4a3ra
@@ -4804,25 +4755,25 @@ har4mes
har5te
har4th
h1arti
+h2arts
2has.
-4ha3sa
-ha5sta
+2ha3sa
+ha2ß1
hau3f4li
2h1aufm
h1aukt
hau2sa
hau4sc
-hau5stei
+hau6s3ti
hau2ta
2hauto
hau2tr
h1äff
-3häp
h1ärz
hä6s5chen
-häu4s3c
+häu4s1c
hä1usp
-2h5b6
+2h5b
hba2r3a
2h1c
2h1d
@@ -4860,8 +4811,8 @@ heine2
hei4neh
h1eink
he3ism
-he3ist
-heit6s3
+he3i4st
+heit4s3
h1eiw
hekt5a
he2l3au
@@ -4881,14 +4832,13 @@ he3mi
h2en.
he6n3a2
he4nä
-hend4s
h4ene
he2n1e2b
hen3end
he2net
he2ni
he2no
-henst2
+hen5st2
h1ents
he2nu
hen3z
@@ -4916,12 +4866,12 @@ h1erö
hert2
her3th
her2z1w
-he2s3tr
+hes4t
he2tap
heter2
he3th
he5ti
-he3t6s
+he3t4s
he2u
heu3g
he3x
@@ -4932,8 +4882,6 @@ he1y2
hfel2l1
hfi2s
2h5g2
-hge1
-hgin4s
2h1h
2hi.
2hi2a
@@ -4944,21 +4892,22 @@ hi2e
hi3ens
hie4r3in
hif3f6r
+h2ig
hi2kr
h2il
-hi2l5a4
+hi4l5a4
hil2fr
hi2n
hi3nel
hin2en
hi5n4i
hi3no
-hin4t3a
+hin2t3a
2hio
hi4on
hi3or
hi3os
-4hi2p
+2hi2p
hi3pe
hip1h
hip1i
@@ -4971,9 +4920,7 @@ hi3ro
his2a
hi4se
hi5s2p
-hi4st
-hi1th
-hi5ti
+hi3ti
h1j
2h1k4
2hl
@@ -4985,6 +4932,7 @@ h5land
hl3anz
hl1ar
h3las
+h3laß
h3lat
h3laug
h3laut
@@ -4992,6 +4940,7 @@ h3law
h3läd
hl1är
h3läs
+h3läß
h3läu
hlb4
hl3d4
@@ -5021,7 +4970,8 @@ h2li
h3lic
h3lik
hl1ind
-hll2
+h3list
+hl3l2
hlm2
h2lo
h5loc
@@ -5038,11 +4988,11 @@ hl2ser
hl3sku
hl3slo
hl3sp
+hl2sto
hlt2
h3luf
h3luk
h3lüf
-hlzu5
2h1m
h2ma
h4mab
@@ -5057,7 +5007,8 @@ h4mäu
h3me.
hme1e
hme1in
-hmen4s
+h3meist
+hmen2s
hmen6sc
hme2ra
h2mi
@@ -5106,22 +5057,17 @@ hn3k4
h3nof
hn3s2k
hn4th
-hnts2
h2nul
hn1unf
h3nunge
ho3be
ho2bl
ho2c
-ho4ch5
-ho3ck
-ho4cka
-ho7cker.
+hoch5
hoe4
ho2ef
ho4fa
ho2f3r
-hohen3
hol1au
ho2l1ei
hol3g4
@@ -5136,30 +5082,32 @@ ho2mec
ho2med
ho5mu
h2on
-hon3str
2hoo
2hop
ho1ra
hor3d
h1org
+ho5ri
ho3sl
ho4sp
ho4st
-4hot.
+ho6sta
+ho5ste
+2hot.
ho5th
-4hot3s2
-1hou2
+2hot3s2
+1hou
3hov
-4ho2w
+2ho2w
how1e
h1o2x
ho1y2
+hô1
1hö
hö2c
-hö3ck
h2ör
hö4s
-hös3c
+hös1c
h1öst
2h3p2
h1q
@@ -5186,12 +5134,14 @@ h3rep
h4r3erla
h3rerle
h6rerleb
-h3re4s1
+h3re4s5
+hre6su
hre2t
h2r3eta
h3rev
hrf2
hrg4
+hrga4
h3ric
hri4e
h3riesl
@@ -5204,27 +5154,29 @@ h2rob
h3roh
h3rol
h4rom
+hro3man
h4ron
h2ror
h3rou
-hr2s1ac
+hr2s3ac
hr2s3an
-hrs1au
-hr4se
+hrs3au
+hr5sch
hr2s1en
hr2ser
-hr2set
-hr6s1in
+hr4set
+hr4s1in
hrs3k
-hr4s1of
+hr2s1of
hrst2
hr2su
-hr4sw
+hr6sw
hr4tab
hr2tan
hr2t3ri
hr2tro
hrt2se
+hrt4ste
h1ru
h3ruh
hr1ums
@@ -5233,20 +5185,17 @@ h3rü
hr3üb
h2ry
hrz2
-4hs
+4h1s
h2s1ach
-h2s1an
-h2s1au
+h2san
+h2sau
+h3sc
h4schan
-hs1e4c
-hs2ei
+hs1ec
hs3eins
-hs3eis
-h3sel
-h3sen
-h3ser
-h4s1erl
-h3sex
+hs1eis
+h2s1erl
+h3s2ex
h2s1ing
hs3l
h2s1of
@@ -5255,23 +5204,26 @@ h2sper
h3s2por
h2sprä
hs3s2
-h2stal
+h4stal
hst3alt
-h2stau
-h1stec
-h3s4terb
-hs1the
-h1s2ti
-h2s3tie
-hs4tief
-h2stor
-h1s2tr
+h4starb
+h4stau
+h4stäl
+h5ste.
+h5stem
+h5sten
+h4sterm
+h2steu
+h4s1tie
+h4stin
+h4s1tor
hst3ran
-hst3ri
-h1stun
+h4st3ri
+h2s1tu
+h3stun
h2s1un
hs2ung
-h1sy
+h3sy
4h1t
h2t1a
htab2s
@@ -5279,26 +5231,28 @@ h3t4akt.
h3takts
h3t2al
h4t3alt
-h4tam
ht3a4n
ht5ane
h3t4ank
+h3tas
h4t3ass
h4tasy
ht3a2t
h2t1är
h5te.
-h2t1e4c
+h2t1ec
h3tech
h2t1ef
ht1e2h
h3teha
+h3tehä
h2teif
h4t1eim
ht1ein
h2t1eis
h4t3elit
-h4temp
+h2temp
+h3ten
h4tentf
h4t3ents
ht3erfo
@@ -5306,40 +5260,45 @@ ht3erfü
h2t1erh
h2t1erk
ht4erko
-h4t3erre
+ht3erre
ht3ersc
h6t5erspa
h4t3erst
h2t1erz
hte2s
-h4t3ese
-h4t3ess
+h2t3ese
+h6t3ess
h5tet
-ht1eu
+h2t1eu
h2t1ex
h2t1h
h3ti
h4t1in
hti2s
+htni4
h2t3oly
h2top
+h2torg
h2tö
h3töp
-h4t3rak
+ht3rak
ht3rand
h2t3rat
ht3raus
-h4tref
ht4ri
h2t5rin
h2t3rol
h2t3ros
+ht3roß
h2t3rö
h2t3ru
h2t3rü
ht2sen
+ht4s3ess
ht3spri
ht4stab
+ht4ster
+hts2ti
ht4s3tur
ht4s3tür
ht3t
@@ -5351,15 +5310,13 @@ htwa5re
ht3z4
hu2b
hub1a
-hu4b3ei
+hu4bei
hu4b1en
hub3l
-hub5r
-hu1c
+hub3r
hu2h1a
hu2h1i
-huko3
-huk3t6
+huk3t4
hu2l3a
hu2lä
hu2l3ei
@@ -5368,6 +5325,7 @@ hu4lent
hu2ler
hu2let
hu2l1in
+hul3l
hu2lo
hu3ma
h1ums
@@ -5381,7 +5339,6 @@ hur3g
hu3sa
hu2sc
hu2so
-hus4sa
hu2tab
hu3t2h
hu2ti
@@ -5395,13 +5352,12 @@ h4übs
hüf2
hüh3
hühne4
-hüs3
2h1v
hvi2
hvil4
2hw
h2wal
-hwas7
+hwa5re
hwe1c
h1weib
h1wet
@@ -5412,12 +5368,13 @@ h1z
hz4s
2i.
2ia.
+i4aa
ia1b4
iab5s
2iac
i5ad.
i3adn
-iaf4l
+ia1f4l
i4a3g
i3ak.
i1akt
@@ -5440,7 +5397,7 @@ i3alh
i3a2lia
i3alj
i3al3k2
-i5al3l
+i5al5l
i3alm
i3aln
ia2lor
@@ -5452,6 +5409,7 @@ ia2lu
i3alv
i3alw
i3al3z2
+iam4
2ian
i5an.
i1ana
@@ -5468,37 +5426,34 @@ ia3p2f
ia1q
i3ar
ia2ra
-iard2
2i3as
i5as.
i4asc
ia3sh
i4asi
i4a3sp
-iast4
-ia5sta
-ia1str
+ia4st4
+ia5str
i5at.
-ia4ta
+ia6ta
i3at2h
1iatr
i3ats
i3au
ia3un
+iaus1
2iav
i1äm
-iär2
i1är.
i1ärs
i3ät.
-iä5te
-i3ät3s
+i3ät3s4
i1b
i2b1ar
i2b1auf
ib2bl
i2b1ei
-ibe4n1
+ibe6n1
ibi4k
i3b4la
i3b4le
@@ -5508,17 +5463,16 @@ ib3ren
ib2s
ib3sa
ib3sp
-ib3sta
ib4ste
i2bunk
i2b3unt
-ibus3
+ibus1c
+ibwa5
2ic
ich1a
ich3ä
i1che
ich3ei
-i3cher
i1chi
i2chin
ich3l
@@ -5529,9 +5483,7 @@ i2ch3r
ich2t3r
i1chu
ich3w
-i2cka
-i3ck2e
-icks2
+ick2e
i1cr
i5cu
i1d
@@ -5562,7 +5514,6 @@ ieb4sto
ieb4str
ie1c
ie2cho
-ie4ck
ied3g
ie2dr
ie1e2
@@ -5573,11 +5524,12 @@ ie3fer
ief3f4
ie2f3l
ie2f1r
-ie2g5l
+ie2g7l
ie3g4n
ie2g3r
ieg4ra
-iegs3c
+iegs1c
+ieg4st
ie3her
i1ei
ie2l1a2
@@ -5595,6 +5547,7 @@ iel3sp
iel3sz
ielt4
iel3ta
+iel3to
i1en
i3en.
i3ena
@@ -5603,8 +5556,7 @@ i3e4nä
i3end
ie2n1e2b
ien2er
-ie4nerg
-ie3nern
+ie6nerg
i3enf
i3en3g
i3enh
@@ -5616,9 +5568,9 @@ i3e2no
i3enö
i3enp
i3enr
-ien5s2e
-ien2st
-iens4tr
+iens2
+ien3se
+ien6sto
ienst5rä
ien3sz
i3env
@@ -5635,16 +5587,15 @@ ier4ert
ie4r3erz
ie3res
i3ereu
-ier3k2
+i4eri
+ier3k4
i1ern
i3ern.
ier5ni
iers2e
ier4s3eh
-ier7sei
-ier3sta
-ier3ste
-iesen3s4
+ier5sta
+i3e4stas
ie3su
ie2t1a
ie4tei
@@ -5653,22 +5604,24 @@ ie4t3ert
ie2th
iet3ho
ie4t1o
-ie2t3ö2
-iet4se
+ie2t3ö6
+iet2se
i3ett
ieu2e
ie1un
i1eura
+iewa5r
i1ex
-4if
+2if
+if1an
i2f1arm
-if3au
+if1au
i3fe
i5f2en
-ifen3st
if1erg
if1erh
-ife4s
+if2fa
+if6feste
if2fl
i3fi
if3l
@@ -5692,9 +5645,9 @@ if2top
if2t3ri
ift3sp
ift3sz
-2i1g
+i1g
ig2ab
-iga3i
+iga1i
i2g1ang
ig1art
iga5s
@@ -5712,22 +5665,21 @@ ig4le
ig5lein
i4gli
ig1lu
+2igm
ig4na
i4gnä
i3g4neu
ig4no
i3g4ra
-ig4sal
-ig5sä
+ig6sal
+ig3sau
+ig3sä
ig4se
ig3so
-ig3spr
-ig3s4tei
-ig4s3to
-ig4stö
-ig3str
+ig6sti
+ig6s1to
+ig6stö
ig4stre
-ig5stu
2i1h
i2h1am
i2h1ar
@@ -5738,20 +5690,20 @@ ih3l
ih3m
ih3n
ih1r
+ih2s
i2h1um
ihu3s
ih1w
2i1i4
i2i5a4
-i3ig
i3in
i2is.
i2i5t
i1j
i1k
i4k3a4k
-ik5amt
-i4k3anl
+ik3amt
+i4kanl
i2k1ano
ik3ansa
i2k3anz
@@ -5774,17 +5726,16 @@ i3k4la
i3k4lä
ik1lö
i2k3n
-ik2o3p6
+ik2o3p4
ikot3t
ik3ra
ik3rä
ik3re
i3kri
-ik1s
ik3so
iks2p
ik3s2z
-ikt2e
+ik3t2e
ikt3erk
ik2t3r
i2kun
@@ -5796,6 +5747,7 @@ i2l1ak
i2l3a4m
il1ans
il3asp
+i3lat
i2l1au
il4aufb
il5aus
@@ -5807,9 +5759,10 @@ il3de
il4d3ent
ild2er
il2d1o
-il1e4c
+il1ec
ile2h
il1ehe
+ileid4
il1ein
i2l1el
i3len
@@ -5821,15 +5774,16 @@ il2f3l
il2f3re
ilf4s
ilg4r
-ili5en3
+ili5en
iliga2
ili4g3ab
i2l1ind
i2l1ip
i3lip.
i3lips
-il3l2a
-ill4an
+il3l4a
+il4lad
+il2leg
il3l2er
il5l2i
il2mak
@@ -5855,6 +5809,7 @@ i2manw
i2m1arm
ima2tr
ima4tur
+1imbi
i2m1ele
i2m1elf
i2m1erf
@@ -5863,21 +5818,25 @@ i2meti
im1ex
2imi
i2m1inf
+iming7
i2m1ins
+imi3te
+immei4
im4m3ent
3immo
+imni4
im1org
1impo
imp2s
im3pse
1impu
-im2str
+im4str
2imt
2imu
im3unt
2in.
2ina
-in1a4c
+in1ac
in3ad
in2af
in3a2m
@@ -5888,10 +5847,12 @@ ina4s
in3asi
inasy3
i2n3au
+inaus1
in1äs
in1äu
in3dau
in4dene
+indes4t
1index
in3do
2indr
@@ -5914,60 +5875,58 @@ in3erz
i2n1eu
ine3un
ine2x
-inf4
1info.
4inga
ing1af
in2g1a4g
-ing5sc
+ings2c
+ing7sch
+ing3ska
+ing5ste
1inhab
2inhar
2inhau
-4inhe
+2inhe
i3ni3d
2inig
in3ins
in2ir
2inis
-ini5se
i3nitz
3inkarn
-ink4ste
+ink4st
2inn.
in4n3erm
2innl
+inn6sta
1innta
2ino
in3od
in3ole
in3ols
in1or
-inos2
-ino3st
+ino5st
ino3t
i1nö
in1ö2d
2inp
2inr
-ins2
2ins.
-ins4am
-ins3än
+ins2am
insch4
in7schl
-in4seb
+in2seb
+in3sel
2insen
-ins3erg
ins3ert
in3skan
-in5spe
-in3st
3instal
in4s3tät
-in5s4tr
-in5su
+in5sto
+in3s2u
1insuf
-in6s3um
+in4s3um
+ins2z
in3sze
1integ
in3t2h
@@ -5992,16 +5951,17 @@ io2i3d
i4ok4
io3kr
i3ol.
-i5om.
-i5oms
+i3om.
+i3oms
ion4
i3on.
io3na
ional3a
io4n5au
ion5d
-i3ons3
+i3ons1
ion6sc
+ions3p
io2nu
i2ony
i2o1p
@@ -6020,7 +5980,7 @@ i2os2
i3os.
io3sh
io3sp
-io3st
+io5st
i3ot.
i3ots
i2ov
@@ -6031,7 +5991,6 @@ i3ön
i1ös.
2ip.
i1pa
-ip4an
i1pä
i1pe
ipen3
@@ -6041,13 +6000,13 @@ iph4
2i1pi
ipi3el
ipi3en
-ipi2s
ip4l
i1pr
2ips
+ip3ta
2i1pu
i1q
-i1r6a
+i1r2a
i3ra.
1irak
i3ras
@@ -6063,6 +6022,7 @@ ir2g5l
irg6s
ir2he
i1r2i
+iri3a
2irig
2irk
ir2k5l
@@ -6078,24 +6038,26 @@ ir2no
i1ro
1i2ron
iro2s
+iro5st
i1rö
irpla4
-ir4s
-ir5se
-ir5sh
-irt2st
+ir4rei
+ir2s
+ir3sh
+irt4st
i1ru
iru2s1
+i1s
i3sac
-i4s3amt
-is1an
+i4s1amt
is2ap
is3are
-i2s1au
+i2sau
is1än
2isb
i2sca
isch3ar
+is2che
i4sch3e4h
i4sch3ei
isch6er
@@ -6106,35 +6068,39 @@ i2schm
isch3ob
isch3re
isch3ru
-isch3wu
-is3chy
-i2s3cr
-2i3se
+i4schwa
+i6schwir
+i4schwo
+i4sch3wu
+is1chy
+i2s1cr
+2ise
+i3sec
ise3e
ise3ha
ise5hi
ise3il
+is1ein
ise3inf
i4seint
ise2n
ise4nal
is2end
ise1ra
-i4s1erm
+i2s1erm
iser2u
-i4s1ess
+i2s1ess
is4et
i4s5etat
-i4sex
isi2a
i2s1id
is3la
-ismu2
+is3m
i2s1of
iso2n
iso6nend
is1op
-5i2sot
+3i2sot
i2sp
is1pa
i4spar
@@ -6145,38 +6111,35 @@ i4spl
i4spo
i4spro
is3sa
-is4s1ac
+is6saa
+is4s3ac
is4sau
+is3sä
is4s3che
-is2st
+is4st
iss1tr
-i2st
-is1t2a
-is2t3ab
-is2tat
-is3tec
-i3stel
-iste4n
-is1th
-i1stil
-is1to
-is2toc
-is1tr
-is2t3re
-i3stru
-i3stü
+is2sum
+ist2a
+i4st3ab
+i4staf
+i4stam
+is2te4n
+is2ter
+is2ti
+ist3re
+is2tro
+is1trü
+i2stur
isum3p
i2sü
-i1sy
-i1ß
i2ß1ers
-ißler3
2it.
i1ta
it1ab.
it1ac
i3tak
ital1a
+ital3l
it1alt
it1am
it1ang
@@ -6189,30 +6152,33 @@ i4t1ax
2i3tä
i4t1äs
ität4
-2ite
-i2t1eig
+2i1te
+it1eig
it1ein
6i3tel
ite2n
iten3g
itens2
-iten3st
i2t1epo
-i4tex
+i2tex
it1he
i5thr
it1hu
-i3ti
+i1ti
1itia
-i4t1id
+i2t1id
1itii
iti4kan
-i4t1in
+i2t1in
+i3tis
+i3tiv
i1to
+i3to.
i5toc
i2t1of
i1tö
i1tr
+i5tra.
it3raf
it3rah
i2t3ran
@@ -6224,34 +6190,39 @@ it3ric
it3rom
i3tru
it3run
-it4s3ag
+it4s1ag
it2sä
it2s1e2
-it6s5er1
+it4s3er1
its1pe
it4staf
-its3tie
-it2sto
-it2str
-it3te
-it4teb
+it4stec
+it4s3tem
+its3tes
+it4sti
+it4sto
+it4str
+it2teb
+it4temp
itt3hä
it2tr
+i1tu
it1uh
i2t1um
i2tuns
itu5re.
it1urg
-itut6
+itut4
i1tü
i3tül
i3ty
2itz
it4z3erg
-2i1u4
+2i1u6
+ium1
ium3a
-ium1i
i3un
+ius1t
i1ü
2i1v
iv1ak
@@ -6266,6 +6237,7 @@ i3vol
i2vr
i2v1ur
2i1w
+iwa5r
iwur2
ix2em
i3xi
@@ -6287,33 +6259,28 @@ iz3th
i2z1w
í1l
2j.
-ja1c
jahr3ei
jahr4s
ja3la3
ja3ne
jani1
ja5sa
-ja3st
2jat
je2a
-jean6s
-je1c
+jean4s
je2g5
jek4ter
jekto2
jek4tr
je3na
je2p
-jes1t
+je3s
je2t
jet1a
jet3h
jet3r
-jet3st
jet5t
jet1u4
-je5v
jit3
ji2v
j2o
@@ -6323,23 +6290,20 @@ job3r
jo2i
joni1
jo1ra
-jord2
+jord4
jo2sc
jou2
jou4l
-joy3
4jö
2js
j2u
ju2bl
-juden3
jugen6
jugend5
ju2k
-jung5s4
+jung7s
jur2o
-ju2s
-jute1
+ju3te1
2j1v
4k.
1ka
@@ -6354,13 +6318,14 @@ ka1bl
2kablä
kab4le
2k3a2bo
-ka3b4r
+ka3b6r
4k3abs
2k1abt
ka1c
2kada
ka3dab
2k3adr
+ka1e
ka1f4l
ka1fr
kaf3t
@@ -6369,18 +6334,19 @@ ka1in
ka3ka
kaken4
ka1la
+2kala.
ka2lan
kal3bl
ka3lei
ka3len.
ka4lens
-kal5eri
+kal3eri
kal2ka
kal2kr
2kall
kal4tr
-3k4am
-4k5a2ma
+k2am
+k3a2ma
ka3mar
kamme2
ka4n3a4s
@@ -6399,7 +6365,6 @@ kan4th
k4anz.
ka2o
2kapf
-3kara
2karb
k1arc
k2ard
@@ -6411,14 +6376,13 @@ kari3es
kar4p3
k2ar3ta
2karti
+kar3to
karu2
k2arw
-3kas
-ka3se
+ka5se
kasi1
ka4sp
-kas3s
-ka4s1t
+ka3ta
ka3th
ka2t3r
2katt
@@ -6426,6 +6390,7 @@ kau4f1o
4kaufr
kauf4sp
2kaus
+kau5st
kau3t4
2kauto
1kä
@@ -6433,16 +6398,16 @@ kau3t4
2käh
k1ämi
kär2
-kä4s3c
+kä4s1c
kä5se
-kä1th
+kä3th
2k1b4
k5be
kbo4n
2k3c
2k3d
kdamp2
-2ke1c
+2kec
ke3d
k3eff
kefi4
@@ -6451,11 +6416,13 @@ ke2gl
ke2he.
kehr4s
kehrs3o
+ke2i
2k1eic
2k1eig
2kein
-ke1ind
+ke3ind
2k1eise
+keit4s
ke2la
kel1ac
ke3lag
@@ -6465,10 +6432,13 @@ kel3b
2k1e2lek
ke2len
2ke3let
-kel3sk
+kel3s2k
2k1emp
ken3a
4kengag
+kens2k
+ken5st
+ken7s4te
ken3sz
k2ente
k3enten
@@ -6503,11 +6473,10 @@ keu6schl
2k5f
kfi2s
2k1g4
-kge1
2k1h4
kho3m
ki3a6
-ki1c
+ki1ch
ki2d
ki3da
2k1ide
@@ -6517,6 +6486,7 @@ ki2el
kie2l3o
ki2en
kif4
+kif2a
ki1fl
ki1fr
ki3k4
@@ -6535,7 +6505,6 @@ kin3sh
ki3o
3kirc
ki5s2p
-kis2to
2kiz
ki3zi
2k5j
@@ -6592,16 +6561,15 @@ kol4k5
3kom
ko2min
ko4mu
-k2on3
-ko3n4e
-kon4i
+k2on
+kon3d
+ko3n2e
kons4
ko3nu
2kop.
ko1pe
kop4f3en
kopf5err
-kop2t
ko3r2a
4k1orc
kor6derg
@@ -6609,8 +6577,6 @@ ko3ri
kor3m
3kort
k2os
-ko3str
-3kot
ko3ta
kots2
kot3sp
@@ -6643,14 +6609,14 @@ k3reih
k3ries
2krip
k4ron
-kro3st
+kro5st
2kruf
krü1b
4ks
-ks3amt
-k2s1an
-k2s1au
-ks4än
+ks1amt
+k2san
+k2sau
+ks2än
ksch4
ks1e2b
k2s1em
@@ -6658,28 +6624,23 @@ k2sent
ks1erl
k2s1ers
k2s1erw
-ks1ex
k2s1id
k2s1in
k2s1o2
k3sof
+k5son
ks1pa
k3spe
ks2por
ks3s2
-ks2t4
+kst4
k5stab
ks3tanz
kstat4
-k1ste
-k5stei
-k6steil
-k1sti
-k2stor
-k1str
-k2strä
-k1stu
-k2stum
+k4s1tis
+k4s1tor
+k4strä
+k2s1tum
k2s1u
k1sy
ks2zen
@@ -6696,19 +6657,17 @@ kt5a4re
k5tat
k2t1au
ktä3s
-k3te
kte3en
-k4t1ei
-k4temp
-k4tent
+k2t1ei
+k2temp
+k2tent
k4t3erfo
-k4t1erh
+k2t1erh
k5ters.
-k4tex
+k2tex
k2t1h
k2t1id
-ktien3
-kt1im
+k2t1im
k2t1ing
kt1ins
k2t1of
@@ -6721,28 +6680,27 @@ k3t4ra
kt5ras
kt5rau
kt4ro
-ktro5s
kt3run
kts4
kt3se
kt3sp
-kt3st
+kt5st
kt3su
-kt3s2z
+kt3sz
kt3t2
k2tuns
kt3z
ku1c
-kuh3
+kuh5
2k1uhr
ku3la
ku3l2e
ku3l2i
-4kulp
+2kulp
2k3uml
-kum2s1
+kum2s
k2u3n2a
-kun6s4
+kun6s
kunst3
2kunt
2k1up.
@@ -6751,20 +6709,22 @@ kuri2e
kuri4er
ku2ro
kur4sp
+kur4s3t
kur4zen
ku4schl
ku2so
ku2sp
-ku2s1t
+ku5s4t
ku2su
+ku2ß
1kü
2küb
kü1bel
kü1c
-kür4s
+kür2s
2k1v
2k1w
-3kys
+kwa5re
ky3t
2k5z2
6l.
@@ -6774,11 +6734,9 @@ la3ba
4labb
4la2ben
3labi
-4l1abl
+6l1abl
3la3b2o
3l2a1b4r
-lab5re
-lab6ri
4l3abs
4labw
la1ce
@@ -6787,10 +6745,11 @@ la3den
la3d2i
l3adl
4ladm
-2l3adr
+4l3adr
5ladu
l3adv
1la1e
+laf3ta
la2ga
la3ge
lag5eis
@@ -6798,9 +6757,10 @@ la2gn
lago4
la4g1ob
la2gr
-lahn3
+lag5se
2la1ho
1lai
+lai4s1t
1laj
la3ke
la2k1i
@@ -6812,10 +6772,11 @@ la1k4l
l2a3ma
l2ami
la3min
+lam4ma
3lammf
l4amp
2l1amt
-lamt6s
+lamt4s
la4mun
la2na
la3nac
@@ -6829,13 +6790,12 @@ lan6d5erz
land5inn
lan2dr
2l1anf
-lang3s4
+lang5s2
+l1anh
4lanl
-l3anli
2l3ann
l1anp
2lans
-4lansä
4lanw
lanz1w
3lao
@@ -6848,30 +6808,37 @@ la2r1ei
la6rene
l4ar3g
lar3ini
-lar3st
2l1art
lar3th
l3arti
la3ru
-la3se
+la5se
2lash
la2so
2la4sp
5lasseri
5lassern
5lassers
-la4st
+la4sta
+la5ste
+las3tei
last1o
+la4str
+las3tur
+la4stü
+la2ß
+laß3th
lat2a
+la3te
la4tel
-2l3ath
+4l3ath
la2t3ra
lat4s
2latta
lat4tan
lat4t3in
lat4t3r
-laub6se
+laub4se
lau4fer
lau4fo
l2aufz
@@ -6879,10 +6846,10 @@ l1ausg
2l1ausl
2l1ausr
2l1auss
+lau5str
l1ausz
2lauto
2law
-lawa4
1lax
la3xa
lä1c
@@ -6891,7 +6858,7 @@ lä1c
3länd
lär2m1a
l1ärz
-lä4s3c
+lä4s1c
4lät
4läub
4läuc
@@ -6904,11 +6871,12 @@ lb3af
lb3am
lb3ang
lb3arb
-lb3b
+lb5b
l2b3ede
+lbe4n
l4b3eta
l2b3id
-l2b3ins
+l2b5ins
lb4lat
l3blä
lb3le
@@ -6916,18 +6884,14 @@ l2b5li
l3blo
lb3ohn
l4bre.
-lb5rit
+lb3rit
lb4ro
l3brü
-lbs4
-lb3sa
-lb4sk
-lb3sp
-lbs6t
+lb5sa
+lb5sp
lbst1e
-lb4sto
-lb4stu
-l2b3uf
+l2b5uf
+lb5v
4l1c
l3che
l5chi
@@ -6935,9 +6899,10 @@ lch3l
lch3r
lch3ü
lch1w
+l3co
4l1d
ld3a2b
-ld1a2ck
+ld1ack
l4d3ad
lda2g
l2d1ak
@@ -6960,6 +6925,7 @@ l3dern
l2d1erp
l2d1e4se
l2dex
+ldi2c
l2d1id
l2d1im
ldo2r
@@ -6977,14 +6943,15 @@ ld1rö
ld3sa
ld3ska
ld3sp
-ld1st
+lds2t
ld1t4
l2d1um
l2dü
1le
3le.
le3ar
-le3ba
+lea5s
+3le3ba
leben4s3
le2bl
2lec
@@ -7000,8 +6967,7 @@ le3f4a
le2g3as
le2gä
le2g5l
-le3gr
-legs4
+3le3gr
3lehr
leh3r4e
3lei.
@@ -7013,14 +6979,10 @@ l2ein.
l2eind
l2eine
l2eint
-lei2s
-lei3so
leis6s5er
l4eist
-lei3su
l2eit
lei8t7ersc
-leit3st
lekt2a
2lektr
3lela
@@ -7037,6 +6999,8 @@ le2m1o2
l2en.
le4nad
le4nä
+4lendet
+2lendu
3lene
le4n3end
4lenerg
@@ -7046,7 +7010,7 @@ le3ni
len3kl
2l1enni
l2e2no
-len3st
+len5st
len3sz
2l1ents
4lentw
@@ -7064,7 +7028,7 @@ ler5b6
4l3ereig
le4r3eim
le4rers
-l1erfo
+2l1erfo
l2erfr
l2erfü
3lergeh
@@ -7080,27 +7044,23 @@ le1ro
3l2erra
l4ers.
lers4k
-ler3ste
le2ru
le3rung
l1erz
l2erza
-les4am
les4e
2lesel
-le5ser
-le3sh
+le3ser
+le5sh
lesi1
le3s2k
-les2t
+les7sa
leste3
4lesw
2lesy
-le4sz
le2tat
2le3th
2leto
-let4tu
le2u
4leud
2leuro
@@ -7110,7 +7070,6 @@ le2u
3lexd
le5xe
le2xis
-3ley
2l1f
l3fa
l5fah
@@ -7122,8 +7081,9 @@ lf3lo
l3flu
lf3ram
lf2s
+lfs1e
lfs3tau
-lfs3tr
+lfs1tr
lf2tr
lf4u
lfur1
@@ -7133,11 +7093,14 @@ l2geti
lg3lo
lg3re
l3gro
-2l1h
+lg4sc
+lg6st
+2l1h2
l3he
3lhi.
1li
3li.
+l4ia
li1ac
li1ak
li3bi
@@ -7153,12 +7116,12 @@ liebe4s
lie2n
li3ene
li5enp
-lie4s3c
-lie2st
+lie4s1c
li3fa
li4fe
5lig
li3g4n
+lig3s2
li3ke
li3ki
li3kli
@@ -7181,7 +7144,7 @@ li4neh
li2nep
li4nes
2l1inf
-ling4s
+ling6s
2l1inh
li5ni
2l1i6nit
@@ -7195,7 +7158,8 @@ l2insc
l1inv
4linz
li2o
-li2p3a
+lion5s
+li2p5a
5lipt
3lis.
li3s2a
@@ -7204,15 +7168,13 @@ li4schu
2l1isl
2l1i2so
liss4
-3list
li2tal
li3te
li1t2h
lits2
-lit3st
+lit5st
lit3sz
-li3tu
-li4tur
+li2tur
3liu
2lixi
li2za
@@ -7220,13 +7182,11 @@ lizei5
4l3j
2l1k
lk1alp
-l3k2an
+l3k4an
l3kar.
lk1arm
-l3ke
lken3t
l2kep
-lkir5
lk3lo
l3k6lu
lk3nu
@@ -7234,31 +7194,33 @@ lkor2b1
l3k4ra
lk3ro
l2k3ru
-lk2s3
-lk3sä
-lk4stä
+lk4s1
+lk5sä
+lk5ste
l3k2ü
lkü1b
-4l1l
+2l1l
ll1abb
ll1abe
-ll3aben
+ll5aben
ll1abt
l3labu
ll1aff
ll1akt
l3l2al
-l2l3a4m
+l4l3a4m
l2l3anz
l3lap
ll1arm
-ll3art
-ll1au
+l4l3art
+l2l1au
+ll4aufe
ll3aug
-l2l3aus
+l4l3aus
l2l1äm
llb4
ll3d
+l2leb
l3lec
ll1ech
l2l1ef
@@ -7266,38 +7228,34 @@ ll1eim
llei4ne
l3l2em
l3len.
-lle4n1a
+lle6n1a
ll3endl
ll3endu
llen3g
l3ler.
lle2r3a
-l3lere
l4l3ergo
ll3ernt
l2lerz
ll2es
llg4
-ll1imb
+l6lieg
ll1imp
l2l1ind
lli5ne
l2l1ins
-ll3l4
ll5m
-l2l1ob6
+l2l1ob
l2l1of
ll1opf
l2l1o2r
l2l3ou
ll1ov
-l3low
l4l1öf
-ll3ö2se
+ll3ö6se
ll3sh
ll3s2k
-ll3sp
-ll4spr
+ll4s3tor
llt4
ll3th
llti2m
@@ -7306,9 +7264,8 @@ llt5s2
ll1ur
l3lus
llust6
-llus5tr
ll3z2
-2l1m
+4l1m
lm3a2b
lm1aka
l2m1arc
@@ -7323,8 +7280,6 @@ lm1orc
l2möl
lm3p
lmpf4
-lm1s2t
-lm3ste
lm3sz
lm3th
4ln
@@ -7340,7 +7295,7 @@ l1nü
2lobj
2lo2bl
l2obr
-lo3bri
+lo3b4ri
lof4
4l1o2fe
lo1fl
@@ -7352,8 +7307,8 @@ lo2k3r
lol2a
l3oly
lo2min
+l4on
lo4n1o
-lon3st
lo2o
2lope
2lopf
@@ -7368,10 +7323,12 @@ lo3ro
3los.
lo4sa
3lose
-los5se
+los3se
lost4
-lo4ste
-los1tr
+lo4steu
+lo4s3to
+lo4s3tr
+lo2ßu
lo2ta
lo3th
loti4o
@@ -7385,7 +7342,6 @@ lö3du
l3öhr
2l1öl
5lösc
-5lösu
4löß
2l1p
lpe2n3
@@ -7398,28 +7354,29 @@ lp3t4
lque3r
2l5r2
lrat6s
+lro3m
lru3t2
lrü1b
-4ls
-l3sac
+4l1s
+l3s2ac
l2s3a2d
-l5s2al
-l4s3amb
-ls3amp
-ls1anf
-ls1ang
-l2s1ann
+l7s2al
+l4s1amb
+l2sann
l3sare
-l2s1au2
+l2sau2
l4schin
+l5se.
l2s1e2b
ls1ec
+ls1ein
l2s1em
ls3ere
ls1erg
ls1erl
l2s1ers
l2s1erw
+l5ses
l3sex
l4sha
lsho2
@@ -7429,66 +7386,66 @@ ls3ohne
l4s3ort.
ls2pi
l3s2po
-l3spri
l3s2pu
ls3s2
lst2a
l5s2taf
ls3täti
-l1stec
l5stei
l5stel
-l5steu
-l1sti
-ls2tie
-l2stit
-ls2tol
-l1s2tr
-l1s2tu
+l5ster
+l4s1tis
+l4stit
ls1um
l3sur
-l1sy
+l3sus
ls2zen
-4l1t
+6l1t
lt1ac
lt1ak
lt1am
-l4tame
+l3tami
+l3tan.
lt3and
lt1ang
l3tar
lt1art
+l3tas
l3tat
l4t3ato
lt1au
+l3te.
l5tef
lt1eh
lt1ein
l2t1eis
lte5lei
-lt2en
+l3t2en
+l5ten.
lter3a
l3t4erg
lt2erö
lter4sp
-l4t3es3k
-lte3str
+l2t3esk
+lte5str
+l3tet.
lt3e2th
-lt1eu
+l2t1eu
l2t1h
l4t5hei
l3thu
-l3ti
ltimo4
l2tob
l3toc
lt1of
+l3ton
l2t1op
l2t1o2ri
lto3we
lt1öl
lt1ös
lt3öt
+lt4rak
ltra1l
l3trä
lt3räu
@@ -7499,10 +7456,11 @@ lt3ros
l2t3rö
lt5sc
lt2se
+lts1ei
lt3spa
lt3spr
-lt4spre
lt4stab
+lt5ste
lt4stoc
lt3t
lt1uh
@@ -7537,7 +7495,6 @@ lu2go
lu2g3r
lug3sa
lug3sp
-lugs4t
lu2gu
2l1uh
lu1id.
@@ -7561,33 +7518,33 @@ l1urn
l1urt
2luse
lu2sp
-lus4s3a
-lus2s3c
+lus4sä
lus4ser
+lus4si
lus2s1o
-lus4s3p
-lus4st
-5lu4st
-lus2t3a
+lus2s3p
+lus6st
+lus8suc
+5lus2t
+lu4st3a
+lu6stä
lust3re
lu2s1u
+lu2ß1
lu2t1a
-lu2tä
lut3erg
-lu5terk
lut1o2f
lu2top
-lu4t5r
+lu2t5r
3lux
2lüb
5lüd
lüh1l
-lü2s
2l1v
-l3vo
l2vr
2l3w
l5wa
+lwa5re
1ly
ly1ar
ly3c
@@ -7607,6 +7564,7 @@ l2zö
lzt2
lz3th
l2z1u4fe
+lzug4s
l2z1w
lz2wec
6m.
@@ -7623,6 +7581,7 @@ ma3da
ma3de
ma4d2s
ma1e
+ma2es
ma1f
2m1agg
magi5er.
@@ -7633,7 +7592,7 @@ ma5g6n
ma3ha
mah4ler
mah3li
-mai6se
+mai4se
2m1akt
ma1la
ma2l1ak
@@ -7645,7 +7604,7 @@ mal3d
mali3er
mal3lo
2mallt
-malu4
+malu2
ma2l3ut
mam3m
2m1anal
@@ -7659,13 +7618,14 @@ man3ers
ma2net
mang2
2mangr
-m2anh
2manl
m4ann
+2mans
+2mantw
manu3
2manz
ma2or
-5m4app
+m4app
2m1arb
mar3g2
ma3ri
@@ -7678,15 +7638,15 @@ mar5te
ma3ru
3m4as
ma3s2p
-ma3sto
-ma1s2tr
+mas4t
3maß
m4at
ma2tan
ma2tä
mat4c
-ma4tel
+ma2tel
ma4t3erd
+mats2
mat3se
mat3sp
3maue
@@ -7703,12 +7663,11 @@ mä1i2
m1ärg
mät4
mä1tr
-mäu4s3c
+mäu4s1c
2m1b4
mb2a
mbe2e
-mbe4n
-m3b6r
+m3br
2m3c
2m1d
md1ar
@@ -7721,7 +7680,7 @@ mdu3s
meb6
me1c
medi3
-medi5e4
+medi5e6
medien3
2medy
me1ef
@@ -7731,14 +7690,13 @@ mega5
2m1eif
m2eil
me1i2so
-3meist
+m2eist
2mej
me3lant
3meld
me2lek
-melet4
+melet2
2m1elf.
-mell2
melt4
6m5eltern
mel3tr
@@ -7750,13 +7708,10 @@ men3au
m3endl
men3gl
me3nor
-men4s3k
-men4so
-men3st
+men4sk
+men2so
men3ta
-men6tanz
4m3entn
-ment6sc
4mentw
me1o
2me3ou
@@ -7774,15 +7729,18 @@ mer2kl
me3run
mer3z4en
3mes
-me2s1a
+me2s3a
me2sä
mes2e
-4me3sh
+4me5sh
4mes2sa
+mes6sig
mes2s1o
mess1p
meste2
+me4str
4mesu
+3me2ß1
me3t4a
mete2
me3th
@@ -7792,14 +7750,13 @@ meu1
2m3f
mfi4l
4m1g2
-mge1
2m1h
1mi
3mi.
mi1ak
mi3an
mibi3e
-mi1c
+mi1ch
mi3da
mie3dr
mi2e1i
@@ -7816,45 +7773,45 @@ min5de
min2e
mi3neu
min2ga
-mings4
-ming3st
mi3ni
mi3n2o
3miri
3mirs
-mir5sc
+mir3sc
3mirw
mi2sa
mise1
mi3sp
-mis2s3c
-mi4ste
+mis2s1c
+mis6st
+mi2ß1
3mi2t1
+mi3te.
mit3es
mit3h
-mit3s4
-mit5sa
+mi3ti
+mit5s2
mi5tsu
4mitz
2m1j
-2m1k4
+6m1k4
m3ka
mk5re.
-2m1l
+6m1l
m3la
m3le
m5li
mlö3
-2m1m
+4m1m
mma4ge.
m2m1ak
m2m1al
m2m1ang
-m2m1ans
+mm1ans
mm1anz
-mma3s4t
m2m1au
m2m1ei
+mmeis3t
mme4lin
mme4na
mme2ra
@@ -7866,9 +7823,9 @@ mm1inh
mm1ins
mm1int
mmi3sc
-mmi3s2t
-mm3m2
mm3p
+mm2s2
+mm3si
mm3sp
m2m3um
mmül2
@@ -7880,7 +7837,7 @@ mo4a3
2mobj
3mod
mo2dr
-4mog.
+2mog.
mo2gal
3moh
mo2i
@@ -7892,8 +7849,7 @@ mo5m4e
m2on
mo3ne
mo4n1er
-mons1
-mon5su
+mon3su
3mo2o
2mo1pe
mo2per
@@ -7902,11 +7858,8 @@ mo1r4a
mor5ar
2morc
mor4d3a
-morgens6
mo4sk
mo3sp
-mo5s2ta
-mo3to
m1o2x
mo1y
1mö
@@ -7926,35 +7879,32 @@ mp3lu
mp3ta
2m1q
4m3r
-4ms
+4m1s
msa3l
-m2s1an
+m2san
ms3and
m4sap
ms3as
-m2s1au
-m3se
-m4s1ef
+m5sat
+m2sau
+m3sc
+m5sche
+m4sco
+m2s1ef
+ms1erf
ms1erw
-m4s1ex
ms1ini
mso2r
ms1ori
m2spä
ms2po
ms3s2
-m6stag
-m2stal
-ms2tau
-m1stec
-m1s2ti
-ms2to
-m1s2tr
-m2strä
-m1s2tu
-m3s2tü
+m4stal
+m4strä
+m3stu
ms1um
m2sü
+m3süc
m3sy
ms2ze
4m1t
@@ -7969,26 +7919,24 @@ m2t1erf
m2t1erg
m2t1erl
m2t1ers
-m4t1ert
-m4t3eta
-mt1eu
+m2t1ert
+m2t3eta
+m2t1eu
m2t1h
mt5ho
-m3ti
-m4t1im
-m4t1ins
+m2t1im
+m2t1ins
mt1int
mti2s
mt1ös
mt2s
mt3sc
-mt5sco
+mt7sco
mts1e
mt3s2ka
mts1p
mt3spa
mt3st
-mts3ti
mt3t
mt1um
mtu3re
@@ -7996,7 +7944,6 @@ mt1urt
mt3z2
1m2u
mu1a
-mu3cke
2m3uh
mu3la
2muls
@@ -8009,17 +7956,19 @@ mu3ne
4m3ungeb
m4unk
mu3no
-mu3ra
mur3ma
mu3ru2
mu4r1uf
-mu4s3a
+mu4s1a
mu2s1o
mu2sp
-mu2s1t
+mus4st
+mu6s1to
+mu4str
mu2su
-mut1au
-mut2s3
+mu2t1au
+mut4s3
+mut5sc
1mü
2müb
3mün
@@ -8027,12 +7976,11 @@ mut2s3
2m1v
mvol2l1
2m1w2
-mwa4
mwel4
-1my
-my4s3
-my3t
+1my3
+my4an
2m1z
+mzug4
6n.
1na
5na.
@@ -8042,10 +7990,8 @@ na3ber
4nabw
na2c
nach1
-na3chen
nachs2
5nachw
-na3cke
4n3add
4n3adr
na1e
@@ -8085,23 +8031,22 @@ n4am.
5nami
na3m4n
3namo
-n3amp
-nam4sp
-4n3amt
-namt6s
+nam2s
+2n3amt
+namt4s
n1an
-4nan.
4na2na
4n3anb
n2anc
4n3ang4
4nani
4nank
-4n3anl
+4nanl
+5nann
na3no
-4n3anr
-4n3ans
-4n3antr
+4nanr
+2n3ans
+4nantr
2n3anw
n1ar
5n4ar.
@@ -8117,16 +8062,17 @@ na3ru
3nas
na4schw
4n3asp
-na5sta
4nasy
+nasyl2
+3naß
3nat
5nat.
5nate
na3t2h
-5nats1
+5nats
nat4sa
-nat6sc
-nat3st
+nat6s3c
+nat5st
4natt
n1au
4nauf
@@ -8140,7 +8086,7 @@ nau3sc
n3ausl
4n3auss
4n3ausw
-nau5te
+nau3te
navi5er.
navi5ers
1nä
@@ -8150,14 +8096,17 @@ n2äc
n1ähn
2n1ä2m
2n3än
-när4s1
+näng5
n1ärz
-2näs
+2nä2s
nä4sc
+3näß
2näu
5nä1um
-4n7b6
+4n7b4
+nbau3sc
nbe2in
+nbe5n
nber2e
4n1c
nc5ab
@@ -8167,9 +8116,8 @@ n3ces.
n3che
nch3m
n3chu
-n2ck
n5cu
-4n1d
+6n1d
nd1ab
n3daf
nd2ag
@@ -8182,26 +8130,22 @@ nd1arb
nd3arr
nda3ru
n2d1au
-n3de.
nde4al.
nde3alt
nd1ei
nd3ei.
ndel4st
-n3den.
n4d3ents
nde3o
n5der.
n5deri
nde4rob
-nder5ste
-nde4s
+n3de4s
ndes1e
-ndo1c
+ndni4
n3dol
nd1op
n2d1or
-ndo3st
nd3rat
nd3räu
n2d3re
@@ -8214,8 +8158,8 @@ n4d5run
nd2sor
nd2spr
nds3tau
-nd3te
-nd1th
+nd5ste
+nd2sum
nd1t4r
n2dum
nd2ums
@@ -8233,9 +8177,8 @@ ne2bl
2n1ebn
2nec
3neca
-4nech
-2ne2e1
-nee3i4
+2ne2e
+nee1i4
ne3ein
ne3en
nee3t
@@ -8251,7 +8194,6 @@ n3ehe
n2eid
6neif
3neigt
-5neigu
4nein
6n3eing
6n3eink
@@ -8289,10 +8231,10 @@ nen3ei
ne4nene
ne2ni
nen3k
-5nenn
ne2no
-nen7s4e
+nen5s4e
nen3sk
+nen5st
5n2en5t2a
n1entb
4n3entl
@@ -8316,7 +8258,7 @@ ne2r3ap
ne2rau
4n3erbi
2n1erf
-4n3erfo
+6n3erfo
nerfor4
4n3erfü
n1erg
@@ -8327,6 +8269,7 @@ n1erk
n3ermä
ner4mit
2nermo
+3nern.
4n3ernt
ne1rös
n2ers.
@@ -8335,12 +8278,13 @@ ner8schle
3n4ert.
4n3ertr
ne2rup
+n2erv
4n1erz
3n2es
n4es.
ne3san
ne2sä
-nes4c
+nes2c
nesi1e
nes2k
ne3ska
@@ -8348,8 +8292,7 @@ ne2s1o
ne2s1p
4n3essi
5nest
-ne2ste
-nes3ti
+nes3tei
net1ak
net1an
ne2tap
@@ -8358,7 +8301,6 @@ net1au
ne2th
net3ha
ne2tre
-nett6sc
2n3e2tu
net2zi
ne2u
@@ -8376,8 +8318,7 @@ nfi3le
nf3läd
nf3lin
n3f2o
-nfo3s
-nf3st
+nf4r
nft2o
nft4s3
4ng
@@ -8408,11 +8349,10 @@ ng5ho
ng5hu
n2g1i2d
ng4lad
-n3gläs
ng3lein
ng3lo
ng3lu
-ng5m
+n4g5m
ng3ne
n2g1or
ng3rat
@@ -8420,11 +8360,11 @@ ng3räu
ng3rein
ng3rev
ng3roc
-ng4sau
-ng4s3c
-ng4s3e4h
-ng5stel
-ng5stö
+ng4s
+ng6s1c
+ngs3e4h
+ng3send
+ngs3pa
ng3ts
n2gue
n2gum
@@ -8444,7 +8384,7 @@ nib3b
ni3de.
ni3di
ni3dr
-n4ie
+n2ie
nie3b
nie3fr
ni1el
@@ -8458,7 +8398,6 @@ nifi3
nig2a
4n3i2gel
ni2g3r
-nig4sp
3nik
nik1al
ni2kä
@@ -8469,11 +8408,11 @@ ni2kr
n2imm
nim2o
4n3imp
-3n4in.
+3nin.
nin2a
4n3ind
2ninf
-3n2ing4
+3n2ing6
4n3inh
nin1i
4n1ins
@@ -8484,25 +8423,28 @@ ni2ob
ni5ok
ni3ol
ni3os
-3n4is
+3n2is
ni4schw
-ni4s1e
-ni5se.
+nis1e
niso2
nis1p
-nis3s2
-nis3tr
+nis5s2
+nis3sz
+ni2stu
ni2s1u
2nit
+ni3ta
ni1th
-ni4ti
+ni2ti
+ni3to
ni3t4r
nit2s
ni3tsc
-nitt4sa
+nit4tec
+nitt6sa
ni3tu
3niu
-3niv
+3ni3v
3nix
2n1j
4n1k
@@ -8514,10 +8456,10 @@ nk1apf
nk1arb
nk1arm
nk3arti
-nk1aus
+nk1au6s
nk1äh
n2k1är
-nk1e2c
+nk1ec
nk1ein
n4k3erfa
nk1inh
@@ -8541,10 +8483,10 @@ n4kre.
nk3rede
n3kri
nk3ro
-nk2s1al
-nks2ei
+nk2sal
nk2spa
nk3spo
+nk5sti
nk3s2z
nk2ta
nk3ti
@@ -8572,18 +8514,14 @@ n4n3er4wa
nn3er2z
nne2s
nnes1e
-nne4st
n5neu
nn3f
nn3g
n3ni
-nnis3t
nno3b
nn1o2r
-nn5sc
+nn5se
nn3s2p
-nn3ste
-nns2tr
nn4th
n4n1uf
n2n1unf
@@ -8599,13 +8537,12 @@ no1c
no3dr
2n1of
4n3o2fe
-n4oi
2nole
no2leu
+n4om
nom4e
n2on.
no3n4a
-non3s
3n2opa
2nopt
2nor
@@ -8621,14 +8558,14 @@ n1ort
3n2os.
no5se
no3sh
-3n2o3ste
+3n2oste
n1osth
-no3st4r
+nost4r
no5tab
no2tä
no4t1ei
-no4t1el
-no4t3in
+no2t1el
+no2t3in
no2t1op
no2tr
3nov
@@ -8640,25 +8577,16 @@ n1ök
4n1öl
4n5p2
npa4g
-npir5
-npro3
npsy3
2n1q
4n3r2
nre3sz
-nrö4s3
+nrö4s1
n5ru
4n1s
-ns3ab
n2s3a2d
-ns3ak
-n2s1all
-ns1an
+n2sall
n3sand
-ns3ans
-ns3art
-ns1au
-ns3auf
n2s1än
n2s1äus
n5sche.
@@ -8668,81 +8596,61 @@ n6schlic
n5schr
n6schro
nsch7werd
-n3se
ns1e2b
-ns3ebe
+n3sec
ns1e2d
nseh5ere
nseh3i
-n5senk
+n3senk
nsen4sp
-n4s1ent
-n4s1ep
+n2s1ent
+n2s1ep
ns1erf
-n4s1erg
-ns3erh
-n4s1erk
-n4s1erö
-n4s1ers
-n4s3erw
-n4s1erz
+n2s1erg
+n2s1erk
+n2s1erö
+n2s1ers
+n2s1erw
+n2s1erz
nse2t
n4s1eta
-ns3h
+n3sex
nsho2f
-n3sil
n2simp
n2s1ini
-ns3int
-nsi4te
+nsi2te
ns2kal
-ns3ko
-ns3ku
-ns3ky
-ns3l
-n3so
-ns3ob
-n4s1op
+n2s1op
n4s3ort.
-ns3park
+n2spat
ns4pei
-n3s4pek
-ns3ph
+n3spek
ns2pi
n2sprä
n4s3prie
n4spro
-nsrü2
ns3s2
nst1ak
-n3star
-n4s3tate
-ns2tau
-n2ste
-n3stei
+n6stat.
+n6s3tate
+n4stau
+n5s2te.
+n4stech
nst3eif
-n3stel
-n4stem
-n5stemm
-ns4tent
-n3step
-n5s6terbe
-n5s6terne
-n5s6terns
+n5stel
+ns4tem.
+n5s4ten.
+n4stent
+ns2ter
+n5s4tes.
n5steu
-ns2tie
-ns2to
+n4stor
n4strac
-n4strie
-ns2tu
nst4ü
nstü1b
-n4sty
-n3su
ns2um
-n4s1un
+n2s1un
ns2unr
-n3sy
ns3zi
4n1t
nt3abs
@@ -8788,35 +8696,33 @@ nt1ho
n3thol
n5thr
n5t4hu
-n3ti
-nti3c
nti3k4l
-n4tinf
-n4t1inh
+n2tinf
+n2t1inh
ntini1
-n5ti1t
+n5tit
ntmo2
n5to
nto5me
nton4s1
-ntons3c
n3tö
nt3rec
n5tree
nt3reif
n5t4rep
+nt4rig
n2t3rin
n5trop
n2t3rü
-n4ts
nt3sa
nt3s2o
nt3s2p
nt4s3par
-nt2sto
+nts2t
+nt4sto
nt3t
n3tu
-ntum4
+ntum2
nt3z2
1nu
nu1a
@@ -8824,7 +8730,7 @@ nu4ale
nu3ar
nu3as
nubi3
-2nu1c
+2nuc
3nue
nu2es
nu3et
@@ -8854,8 +8760,10 @@ nu3sc
nu3se
nu3sl
nu3spo
+nu6s1t
+nu2ß
nu2ta
-nu5te
+nu3te
nu2t3r
5nü.
2nü2b
@@ -8865,8 +8773,11 @@ nür1c
4n1v2
n3ver
n3vi
+nvol7ler
4n1w
n3wa
+nwa5re
+2nx
1ny.
1nyh
2nymu
@@ -8875,9 +8786,9 @@ n1yo
1nys
1nyw
4n1z
+nza2
n2zad
-n2z1a2g
-nz3am
+n2z1ag
n2zan
n2z1ar
n2z1au
@@ -8888,10 +8799,12 @@ n4zense
n4zentz
nz3erwe
nzi2ga
+n2zinh
nz1ini
nz1of
n2z1or
nz3th
+nzug4
n2z1wa
n2z1wä
nz1wer
@@ -8911,15 +8824,16 @@ oa3de
o4ah
o4a3i
oa3ke
-oa4k5l
+oak5l
o4a3la
o4a3mi
oanne4
o4ar
-o4as
-3oa3se
-o5asi
+o4a3s
+3oase
+o5a4si
o4at
+oa3te
o1b
ob2al
o3bar
@@ -8929,7 +8843,7 @@ ob2e
2o3be.
ob3ein
2oben
-oben5se
+oben3se
o2ber
obe4ris
obe6sp
@@ -8941,17 +8855,16 @@ o2b5li
1obm
2obo
o2b3re
-ob6ris
-ob2s
-ob3s2h
+ob2s2
+ob3sh
ob3sk
ob3so
-ob3s2p
-ob3str
+ob3sp
+ob4sta
+ob3sü
2o3bu
2o3bü
2oc
-o3ca
o1ce
och1a
ocha2b
@@ -8970,13 +8883,10 @@ och3to
o1chu
ochu2f
och3w
-o3ci
-o1ck
-o2ckar
-o3ck2e
-o3cki
+ock2e
ock3sz
-o3cr
+o3co
+o1cr
o1ç
2o1d
o3dar
@@ -9001,7 +8911,7 @@ o3et.
o3ets
o1ë
2ofa
-of1a2c
+of1ac
of1am
of1au
o2f1ei
@@ -9010,8 +8920,10 @@ o3fer
ofes3
of2f1a
of2f1in
+of2fir
1offiz
of2f3l
+of2fo
of2f3r
offs2
of2fu
@@ -9023,15 +8935,14 @@ of1la
o1f1r
of3ra
of3rä
-of2s
-of4s3a
-of3sä
-of3st
-ofs1u
+of4s1a
+of2se
+of2sp
+of2s1u
2oft
of2tei
of3th
-4o1g
+2o1g
o2g1ab
oga3d
og1ala
@@ -9046,8 +8957,10 @@ og3ins
o2gl
o3glo
o3g6n
-ogs4
-og3sp
+ogoi5
+og4s2
+og5sp
+og5ste
o1ha
o1hä
o1he
@@ -9072,10 +8985,9 @@ ohl3erh
oh5les
oh3li
oh3lo
-ohls2e
+ohls2
oh2lu
oh3m
-2ohn
ohn3a
oh2ni
oh2n1o
@@ -9085,10 +8997,10 @@ oh1o2p
o2h1ö
ohr1a
oh4rin
-oh1s
oh3ta
o1hu
oh1w
+ohwa5
2o1hy
2oi
o1i2d
@@ -9100,8 +9012,9 @@ o4i3ne
oi4r
o2isc
o3isch.
+oi5se
o1ism
-oi1th
+oi4st
2o1j
2o1k
oka3i
@@ -9112,22 +9025,18 @@ o3ki
oki4o
ok3lau
ok3lä
-okna3
ok2s1p
-ok3t4
+okt4
2ol
o1la
o2l1ak
ol2ar
ol1auf
o1lä
-4olc
ol4dam
ol4d5r
-oldwa5s
ol1eie
ol1eis
-ole3s
ol1ex
o1lé
ol4fa
@@ -9139,17 +9048,19 @@ olge4ne
ol2gl
ol2gr
ol2i
-olib6
oli5en
oli5f
-oli5tu
+oli3tu
ol2kl
ol2k3r
+ol2lad
ol2lak
-ol2lau
-ol4l1e2c
+oll3ans
+ol2las
+ol2läd
+ol4l1ec
ol2l1ei
-oll1el
+ol2l1el
oll5ends
ol4l3erk
oll5erwe
@@ -9162,17 +9073,17 @@ olo3p2
ol1ort
o1lö
ol2pr
-ol2str
+ols2
+ol4str
o1lu
ol2z1a
ol6z3ern
ol2zin
-4om
+2om
oma4ner
om2anw
om1art
o2m1au
-o3me.
o2meb
ome3c
o2m1ei
@@ -9184,10 +9095,12 @@ o2mep
o2meru
om1erz
omie4t1
+omil3l
o2m1ind
om1ing
o3mini
om1int
+omi3te
om3ma
om3me
omme4r
@@ -9196,7 +9109,6 @@ om3pf
omp6l
oms2
om3sp
-om1st
o4m3un
o5m4ung
omy1
@@ -9208,24 +9120,22 @@ o3nal
on3ap
o2n3ar
on4are
-on4at
on3aus
2o3nä
onbe3
2onc
2one
on4eh
-on4e2n1
+one2n1
onen3g
-onens2
o2n1erb
on1erd
on1erö
o3nett
on5f
-4ong4
+ong4
on3gl
-ong5sc
+ong7sc
ong5st
4o3ni
o5ni.
@@ -9234,22 +9144,20 @@ o4ni4kr
o4n1im
on3ing
on5k4
-onli4
+onli4n
onlo2c
on3nan
o3no3
o4noke
on1orc
-on4os
-on2s
-ons3a2
-on3sch
-on4seb
+ons1a2
+ons3as
+on2seb
onse2l
-onsi2
+onsi2d
+ons3l
ons1p
-ont2a
-ont3ant
+on3t2a
on6t5end
ont5erw
on2t1ri
@@ -9258,7 +9166,6 @@ on5v
1ony
on5z
o1ñ
-oof4
oo2k
ook3l
o1op
@@ -9266,13 +9173,12 @@ o1or
oor3f
oo4sk
oo2tr
-oot2st
+oot4st
2o1ö
o1pa
opa1b4
o2p3ad
op1akt
-opa5st
o1pä
o1ped
o1pei
@@ -9319,7 +9225,7 @@ o2ranh
orani1
or3arb
o1ras
-or3au
+or3att
o3r2ä
or3änd
or3ät
@@ -9327,7 +9233,7 @@ or2bar
or1c
2orca
or2ce
-4or2da
+2or2da
ord1am
ord3ele
or4d3eng
@@ -9336,11 +9242,10 @@ or2d1ir
1ordn
or2do
2ords
-ord3s2t
2ordw
4ore
ore4a
-o2r1e2ck
+o2r1eck
o5ree
o2r1ef
ore2h
@@ -9350,7 +9255,7 @@ o2r1er
or3eth
2orf
or2fle
-or3ga
+or3g4a
2orget
or3g2h
2orgia
@@ -9360,18 +9265,18 @@ or3gle
o1ri
2o3ric
o3rier
-4oril
+4o5ril
4orin
or1ins
2orit
+o5riz
or3k2a
or4k3ar
-ork2s
+ork1s
2orm
or2mor
or3na
or3n2o
-orn3st
2o1ro
or3oly
oro3n4a
@@ -9379,25 +9284,24 @@ oro3n4a
2orq
2orr
or3rh
-2ors2
+2ors4
or5sa
-ors4c
orsch5li
or3sh
or3sz
or2ta
or3tad
or4t1ak
-or4t3an
+ort3an
ort1au
ort3eig
ort3ein
-or4tem
or4t3ent
or4t3ere
or4t3erf
or4t5ev
or4the
+or3ti
or4tin
ort3ins
or4t3off
@@ -9406,7 +9310,7 @@ or4t3rau
or4t3räu
ort3re
ort3ric
-ort5sch
+ort3sc
or2t1um
o3ru
or2uf
@@ -9415,15 +9319,16 @@ o5rus
or3ü
2orw
o2rya
+o1s
o3s2a
os3ad
os4an
-osa3s
-os4co
-2o3se
+os2c
+2o3s2e
ose3ei
-o4s1ei
+o4s3ei
ose2n
+o2sé
o3s2hi
o3sho
2osi
@@ -9437,38 +9342,38 @@ os2lo
o2s1p
o4sper
o3s2po
-os2sa
-oss3and
-os4sä
-os5se.
-os4sei
+os2s3a
+os2sä
+os2seg
+os2sei
oss3enk
-os5sent
+os3sent
oss3enz
+os2seu
os4s3o
os4s3p
-os4st
+os6st
oss1ta
+oss1to
oss1tr
-o2st
-os4t1a
-os5ta.
+os2t
+o4s4t1a
osta2b
-os5tali
-os5tarr
-os2tau
+o5stal.
+o4sterd
oster3e
-os6t5er6we
-ost1h
-os3til
-os1to
-os2t1ob
-ost3rä
+ost5er6we
+ost3h
+o5stie
+o4stin
+ost1ob
+os3ton.
+o5stons
+o4st3rä
ost3re
ost3rot
ost1uf
osu4
-o1sy
o3s2ze
o2ß1el
o2ß1enk
@@ -9476,28 +9381,30 @@ o2ß1enz
oße2r
o2ß3ere
o2ß1erf
+oß3th
2o1t
ota3m
o3tark
o2t1au
ot3aug
+otau6s
ot1är
-4o3te
-o4teb
-ote1i
+4ote
+o2teb
+o3te1i
ote3i6n
ote4l1a
ot4em3
otemp2
-o4t1erw
+o2t1erw
4oth
ot2he
ot3hel
o4t1hi
ot1hos
o4thr
-o3t2i
-o4t3i2m
+ot2i
+o2t3i2m
o4tl
otli4
4oto
@@ -9510,7 +9417,9 @@ ot3rut
ots1p
ot4spa
ot3spe
-ot3stra
+ots2t
+ot5stra
+ots3tri
ot2tau
ot3te
ot4t3erk
@@ -9527,19 +9436,22 @@ o3uh
ou4le.
o3um
o3unds
+oung5
oun4ge.
-ouri4
+oung7s2
+ouri4e
our6ne.
-our3st
ou3s2i
+ou5s2t
+ou3te
outu4
2o1ü
o1v
-ove3s
oviso3
2o3vo
2ow
o1wa
+owa5re
o1wä
o1we
o3wec
@@ -9553,8 +9465,6 @@ o1xo
o2xu
1oxy
o1yo
-oys2
-oy3st
2o1z2
oz4e
o3zi
@@ -9564,14 +9474,15 @@ ozon3a
öbe4li
ö2ble
ö2b3r
-öb2s5
-2ö1c
+2öc
+ö1ch
ö4ch3l
ö2chr
-öch2s
-öchs4tu
-öcht4
+öchs2t
+öch4str
+ö4cht4
ö1d
+ödel5l
ödi3en
ö2du
ö1e
@@ -9588,11 +9499,13 @@ ozon3a
öh3l2e
öh3m
öh1ri
+öh2s
ö1hu
ö2k
ö3ke
-öko3
+öko5
ök3r
+ök2s
ö6l
3öl.
öl1a
@@ -9603,25 +9516,24 @@ ozon3a
öl1im
öl1in
öl2k5l
-öl3la
+öl5la
öl4nar
öl1o2
+öls2
öl3sa
-öl3s2z
+öl3sz
öl1u
öl2ung
öl3z2w
+öm2s
2ön
ön3d
ön2e
ö3ni
-ön2s
-ön3sc
öo1
ö1pe
öpf3l
-öp2s3t
-ör3a2
+ör3a
ör1c
örden3
ör2dr
@@ -9638,22 +9550,22 @@ ozon3a
ör1o2
örs2e
ör3sk
-ör2st
ör2tr
ö1ru6
ö2r1une
+ö1s
ö2sa
ö2sc
ö4sch3ei
ösch3m
-2öse
-ö2s1ei
+2ö5se
+ö6s1ei
ö2sp
-ös4s3c
-ös2st
-ö2st
-ös3te
-ös1tr
+ös4s1c
+ös4st
+ös2t
+ö4sta
+ö5stet
ö1ß
2ö1t
ö2t3a
@@ -9666,7 +9578,7 @@ ozon3a
öwe4
ö1z
öze3
-özes2
+özes4
4p.
1pa.
1paa
@@ -9678,12 +9590,13 @@ pa3g2
pa1ho
1pak
pa1kl
+pak2to
1pa1la
pala3t
1palä
pa5li
2palt
-p2an
+p4an
pa2nar
pan3d
pan4ds
@@ -9692,15 +9605,13 @@ pa2neu
pan3k4
2panl
3pano
-pans4
pan3sl
3panz4
-3pap
+1pap
papie8r7end
-3parad
+1parad
pa2r3af
par3akt
-pa5reg
2par2er
2parg
1park.
@@ -9714,14 +9625,8 @@ pa2ro
1partn
1party
par3z2
-pa4s
-pa5sa
-pa5sc
-pa5se
-pa5si
-pa5s2p
-pa5str
-2paß
+pa3s2p
+pa2ßu
p4at
pa5ta
pat4c
@@ -9731,29 +9636,27 @@ pat2e2
1pau3
p1auf
pa3uni
-pau4st
-pä2
1päc
-pä3cke
1päd
-pä3de
1pärc
-pä3ß
pä4t1e2h
pä4t3ent
pät1h
-pät3s
+pä2to
+pät5s
2p1b
+pbe1
2p3c
4p1d
-pda4
+pda2
1pe.
pe4a2
pea4r
1ped4a
-peed1
+peed3
2pef
pei1
+4peic
pe1im
3peit
2pek
@@ -9764,31 +9667,36 @@ pel5d
pe2let
pe3lin
pe4l3ink
-pell4e
+pel5lä
+pel3l4e
+pel3li
+pel3to
1pem
pena6
pe3n4al
pen3da
pe4nen
1penn
+pens2
3pensi
1pensu
pe2nu
pen3z2
pe1ra
per4an
-pere2
1perle
per6na
perne4
-per4r3a
+per4ra
+perr3an
+per2rä
+per4rie
5pers
-perwa4
+perwa6
pe3sa
pes4e
pese2n
-pes5s2
-pe2st
+pes5s4
3pet
1pé
2pf
@@ -9834,13 +9742,13 @@ pf3th
pgra2
1ph
4ph.
-ph2a
2phab
2phä
2phb
4phd
2p1hei
-phen3
+phen3d4
+phen3s
2ph1ers
2phf
4phg
@@ -9858,20 +9766,18 @@ ph4r
phu4s
4p1hü
2phz
-pi4a3
-pia5l
-pia5s
+pi4a5
pi3chl
p4id
pie3fr
pi2el
pie4la
-3pi2er
+5pi2er
1pil
pil4zer
pi2na
pin2e
-ping3s
+ping5s
3pinse
pi2n1u
pi2o
@@ -9881,8 +9787,9 @@ pi2pe
pi5ri
1pis
2piso
+pis2t
+pi5sto
pit2a
-pi1th
pit2s
pi2z1in
p1je
@@ -9903,9 +9810,10 @@ p4leg
p5lic
p5lif
4plig
-p4lis
p4lo
+plü2
2p1m
+pma1
2p1n
1p2o
po3b4
@@ -9913,11 +9821,11 @@ po1c
2p3oh
po2i
po3id
-3poin
3pol
po2lau
po5li
po3ly
+pont4
po1ob
po2p1ak
po2p1ar
@@ -9929,19 +9837,15 @@ po1rau
2porn
por5s
por4tri
-po5s2e
+po5s4e
po3sp
-po4sta
post3ag
po4stä
-post3ei
-po4sti
-po3s4tr
+po4st3ei
post3ra
po3ta
3pote
pot2h
-3poti
po2t1u
po2w
po1x
@@ -9949,10 +9853,9 @@ pö2bl
pö2c
4p1p
p2p1ab
-pp3anl
+pp5anl
p3pe
ppe1e
-ppe4ler
ppe2n1
pp1f4
p2p1h
@@ -9964,11 +9867,11 @@ pp4li
p2p3ra
p2p3re
p2pri
+pps2
pp3sa
pp3sp
ppt2
pp3ta
-pp3to
p2r2
3prak
3prax
@@ -9984,32 +9887,32 @@ pre2e1
3preis
2p3rer
3pres
+1preß
pri4e
1prinz
2prit
-1p4ro
+1p4ro1
3prob
pro3be
2proc
3prod
3prog
3proj
-pro3st
3proto
1prüf
2prün
2ps
4ps.
-ps2an
+ps4an
p3s2h
4psi
p2s1id
p2s1ö
-ps2po
-p3stea
-p1s2ti
-pst3r
-ps2tu
+ps2t
+p5ste
+p4st3r
+p2stu
+ps3tur
3psy
ps2ze
2p1t
@@ -10029,8 +9932,7 @@ p4t1erw
p4t1erz
p5tes
p2t1h
-p3ti
-p4t1in
+pt1in
pto5me
p2tos
p2t3r
@@ -10042,6 +9944,7 @@ pt3st
pt3su
pt3t
pt1um
+p3tung
pt1urs
p2tü
3p2ty
@@ -10055,14 +9958,12 @@ pul4sp
1pulv
1pum
1pun
-4pund
+2pund
pun2s
2punt
1pup
pu3ri
-pur3st
-pu2s
-pu4s3t
+pu2sc
1put
3put2s
3putz
@@ -10070,18 +9971,19 @@ pu4s3t
2pül
2p1v
2p1w
-pwa4r
-3py3
+3py1
+py3t
4p1z
q2u4
3quen
que3rel
1queu
+qui5s
6r.
1ra.
ra2ab
-2r5aac
-r5aal
+2r3aac
+r3aal
ra1ar
r1ab
ra2bar
@@ -10091,19 +9993,15 @@ ra3ber
2rabf
2rabg
r4abi
-ra1bl
-rab4le
-ra2bli
-rab5r
+ra1b4le
2rabs
2rabt
-2r3abw
+2rabw
1raby
ra1ce
2r1acet
ra3che.
ra4cheb
-ra3chen
ra3chet
rach4t3r
ra2chu
@@ -10115,7 +10013,7 @@ ra2dam
ra3di
3radle
ra4d3r
-rad5t
+rad3t
1rae
ra1er
r2af
@@ -10165,9 +10063,8 @@ ram6m5ers
ram4m3u
r3amn
ram2p3l
-ram3ste
2r3amt
-ramt6s
+ramt4s
r2an.
4ranc
r2and
@@ -10178,7 +10075,7 @@ ran4d3er
4r5anei
2r3anf
1rangi
-4r3anl
+4ranl
2r1anm
r1anp
2ranr
@@ -10203,6 +10100,7 @@ ra4schl
r4at.
ra2ta
ra2t1ä
+ra3te
2ratm
rat4r
2ratta
@@ -10220,10 +10118,12 @@ ra3umsa
2rausg
rau4sp
raus5se
-rau4sti
+raus3tr
raut5s
1raü
r2ax
+raxis1
+räch4s
r2äd
4räf
4räg
@@ -10234,7 +10134,8 @@ r2äd
2r1är
rä3ra
r3ärz
-rä4s3c
+rä4s1c
+rä4st
3rätse
rä2u
4räut
@@ -10259,29 +10160,27 @@ r2b5le.
rb5ler
rb2o
rb3res
-rb6ri
+rb4ri
rb2s
-rbs1a
rb4sei
rb4ser
rb3ska
rbs1o
-rb4stä
-rb3str
+rb6stä
+rb5ste
4rc
r1ce
-rcha2
r1che.
r1chen
r1chi
rch3l
+rch5lö
rch3m
rch3r
-rch1s4
+rchs2
rch3sp
rch3ta
rch1w
-r2ck1
r1cr
r1ç
2r1d
@@ -10298,23 +10197,25 @@ r2d1elb
rde7me
r3den
rde5nar
+rdend4
rden4gl
rde3r2e
r4d3ernt
+rdes4
rde3sp
-rde3sta
+rdga4
rdi3a2
rdi5a6l
r2d1inn
r2d1it
rd1os
+rdo4st
rd1ös
rd3rat
rd3rau
-rd1st
rdt4
-rd1th
rd1tr
+rdwe5ste
1re
3re.
re3ad
@@ -10331,7 +10232,6 @@ re2bü
rech3ar
4rechs
2reck.
-re2cka
3reda
4redd
3rede.
@@ -10342,9 +10242,8 @@ re3er
4reff
3refl
3refo
-3refro
+3refr
3reg
-5reg.
rege4l3ä
re2gl
4reh
@@ -10366,6 +10265,7 @@ rein6sta
rein8s7tre
re1in2v
2reis.
+reis5tro
2reiwe
re2ke
re3la
@@ -10390,6 +10290,7 @@ re4n3end
ren4gl
2rengp
re2ni
+ren4nes
2r1entl
2r1ents
2rentw
@@ -10437,15 +10338,16 @@ r1er5t
2r1erz
3r2es.
re2sa
-res1au
+res3au
3rese
3resol
re3sp
2ress
ress2e
res6s5erw
-re2stu
+re4stu
3resu
+4re2ß1
re2thy
re2u
reu3g2
@@ -10456,26 +10358,27 @@ re3uni
r1e2w
rewa4
re3we
+re3wo
4r3e2x1
3rez
4rezi
1ré
2r1f
+rfall6s
rf1ält
r2fent
r3f2es
rfi4le.
-rfin6s
rf3lic
rf3lin
r3flü
r3fre
-rf2s
-rfs1ä
+rf2sa
+rf2s1ä
+rf2se
rf3sen
rf4s1id
rfs3pr
-rf3sto
rf2ta
rf3tau
rf3t4r
@@ -10485,6 +10388,7 @@ rg2ab
r2g1ah
r2g1ak
rg2an
+rga5ste
r3ge
rge4an
rge2bl
@@ -10493,6 +10397,7 @@ rg5e4tap
r4geto
rgi4sel
r2glan
+rgleich8s
r2gleu
r2glig
rg3lo
@@ -10506,8 +10411,7 @@ r2g3res
rg3ret
rg3rin
rg3s2p
-rg3str
-rgt4
+rgs2t
rg3th
r1h4
2rh.
@@ -10531,9 +10435,10 @@ ri1cha
rich3te
4rick
rid2
-ri2d3an
+ri2dan
2ridol
r2ie
+rieb4st
ri1el
ri3els
riene4
@@ -10542,30 +10447,29 @@ rie2nu
ri1er.
ri4e3re
ri3ers.
-ri3esti
+ri3e4sti
rie5te
ri1eu
-ri2f1a
+ri2fa
ri4f1ei
ri4fer
ri2f1o
ri2f5r
-rif3st
rif4ter
-3rig
+3r2ig
ri4g5ene
-4rigg
5rigj
rig1l
4rigr
+rigs2
r2ik
ri4k5l
ri5kle
ri3ma
r2imb
2rimp
-rim2s
-rim4sc
+rim4s
+rim6sc
rin4a
2rind
ri5n4e
@@ -10598,22 +10502,22 @@ ri3so
ri4s3p
3riss
ris4sa
-ri4st
-ris6t5ers
+rist5ers
+ristes4
+3ri2ß1
r2it
r3i2tal
-riten3
-ri5ti
-ri3t4r
+ri3ti
+rit4r
5ritu
ri2x1
+4riz
1rí
2r1j
2r1k
rk1all
rk1aus
rk1äh
-rke2s
r3kla
r5klau
rk3li
@@ -10627,12 +10531,11 @@ r2k3rea
r3kri
rk3rin
rk2s1e
-rk3sen
rk3shi
rk2sp
rkstati6
rk4stec
-rks3ti
+rks1ti
rk2ta
rk4t3eng
rk4t3erf
@@ -10641,41 +10544,43 @@ rk4t3erw
rk2tin
rk2t1o2
rkto4b
-rk4t3r
-rk5tra
+rk2t3r
r2k1uh
rk2um
rku4n
rk1uni
+rku6s5t
2r1l
r3la
r3le
rle2a
r3l2i
-rli2s
-rlon3
-rlös3s
+rlös5s
rl2s1p
-rl2sto
+rl4s1to
rl3th
+rlu4str
4r1m
r2m1ald
-r2m1ans
+rm1ans
rm3anz
r4m3a2p
+r5mapp
rm1aus
rm3d
r3me.
r2m1ef
rmen4sc
r2meo
+rm2es
r2mide
r2m1im
+rmi3te
rm1ope
rm1o2ri
-rmo3s
rm3sa
-rm3sta
+rms2t
+rm5sta
rmt2
rmt3h
rm3ums
@@ -10690,9 +10595,8 @@ rn3are
rn5ari
r2n3au
rn4aue
-rnd4
rn3do
-rn3dr
+rn3d4r
r3ne
r5ne.
rn3e4ben
@@ -10708,7 +10612,7 @@ r4nerg
rn4erhi
r4nerk
r4n1ert
-r5ne2s
+r5nes
rn4e2t
r4nex
rn3g2
@@ -10732,7 +10636,7 @@ ro4bei
2robj
1robo
2robs
-ro1c
+ro1ch
3rock.
r4o3de
r4odo
@@ -10744,41 +10648,36 @@ roh5n
3r2ohr
3roi
ro3in
-ro1ir
ro3le
-roll4en
+rol3l4en
2roly
ro2mad
ro2mer
4romm
r2on
-ronen3
3ronn
rons2
-ron3sp
-ron3str
ron4tan
ro1ny
ro1pe
2ropf
ro3ph
-rop2s
r1or
-r2or3a
+r2ora
+ror3al
ro2rat
-ro1rau
ro2rei
ro2r1o
ror5th
-ro1sé
+ro3sé
ro3sh
ro3s2i
ro5sk
ro3smo
ro3sp
-ros4s3c
-ro4ste
-4roß
+ros4s1c
+ros4sie
+ro4str
ro2ßu
ro2tho
ro2tri
@@ -10801,7 +10700,6 @@ rö7le
r1ör
r2ös.
rö3sc
-rö3se
3rötu
2r3p2
r5pa
@@ -10810,51 +10708,47 @@ rpe2re
rpe4r3in
rpf4
r4pli
-rpo4st
-rpro1
+rpo4str
r4ps
rp3se
-r4pt
+r4p3t
r1q
4r1r
rr2a
r3rar
+r5räh
rr1äm
rrb2
rr1c
r3r2e
rrer4
-rre2st
r4rew
rr2h
rr3hö
+r5ries
rri3k
rr2na
rr2o
r2r3ob
rro3m
-rr2st
r3ru
r5rü
rrü1b
4r1s
-r4sab
+rs2a
+r4s3ab
r2s3a2d
rsa4ler
r2s3amp
r4s3amt
-r4s1ang
-rs1anp
-r4sar
-r3sc
-r5sch2e
+r4s3ang
+rs3anp
+r4s3ar
+rsch2e
r6scherl
rsch4l
-r5schu
-r3se
-r5sei
-r6sein
-r5sel
+rs1ebe
+r2s1ein
rse3le
rse2n
rs2end
@@ -10865,7 +10759,7 @@ rs1ers
rs1erz
rs1eta
r3sho
-r5si
+r3si
rs2ka
r5skal
r5skan
@@ -10877,30 +10771,24 @@ r4skr
r4sku
rs3l
rs4no
-r3so
-r4s1op
+r2s1op
r4s3ort.
r3s2p
r4s3ph
-rs3s2
-rs2t
+rs5s2
r4stant
+rs2tau
+rs2te
rst5eing
-rs4temp
-r3sterb
-rst3erw
-r3stie
-r2stin
+r4st3erw
+rs2th
+r4stin
rst3ing
-r3sto
-r4stot
-r3str
+r5s2tob
+r4s1tot
r4st3ran
-r3stu
-r3stü
-r3s2wi
-r3sy
-4r1t
+r5s2wi
+6r1t
r3tab
rt1ac
r2tad
@@ -10911,8 +10799,10 @@ r4t1alm
rtals1
rt1am
rt1an
+rt3anz
rt1ar
rt3a6re
+r3tas
r3tat
r2t3att
rt1auf
@@ -10922,12 +10812,10 @@ r5te.
rtee2
rt2ei
rtei3la
-rtei3s2
rte5m4e
rte2n1
r7ten.
-rtens2
-rten3st
+r5ter.
rte1ra
rte4ran
rt3erei
@@ -10938,6 +10826,7 @@ r5terli
r4t3ernä
rter4re
r4t3ersc
+rtes2
rte3sk
r2th
rt1he
@@ -10946,38 +10835,36 @@ r3tho
rt1hol
r3thu
r3thy
-r3ti
r4t1id
r4t1ima
rt1int
+rt5le
rto3p
r2t1o2r
-r4trak
rt3rec
+r4treis
r2t3res
-rtrü2
rt4sam
-rt3sch
-rt7scha
+rt5scha
rts1eh
+rts1ei
rt3spe
rtt4
r2t1urt
r3tün
-rt3w
+rt5w
r3ty
rt3z2
ru1a
ru3a2r
rube2
-ru3cker
-ru4cku
ru3de
rude2a
ru2dr
3ruf
ru2fa
ruf4s
+ruf5sc
4rug
2ruhr
5ruin
@@ -11017,15 +10904,13 @@ r3ur1e
5ru3ro
ru2si
rus2s1p
-rus4st
-ru4st
-ru5s2ta
+rus6st
ru2th
rut1he
ru2t1o2
ru2t3r
rut2s
-6ruz
+4ruz
ru2z1w
r2ü
4rüb
@@ -11035,13 +10920,15 @@ rü1ch
4rümm
2r1v
rve4n1e
+rv2s
2r1w
+rwa5re
4r1x
1ry
ry2c
ry3t
2r1z
-rz1a2c
+rz1ac
rz2ach
rz2an
r2z1ar
@@ -11063,27 +10950,27 @@ rzu3g2u
rz1urs
r3z2wä
r3z2wec
-6s.
+8s.
1sa
5sa.
-5saa
+5s4aa
2s1ab
sa2be
3sabet
sa1b4le
4sabs
-sa2chi
-sa2cho2
-sa1cr
+sa3che
+sacho6
+sa3cr
2sada
s3adm
2s3adr
sa3fa
sa4fe
-4s1aff
+4s3aff
sa1f4r
3sag
-s1a2gr
+s3a2gr
5s4ai
sa1ik
sail4
@@ -11091,57 +10978,63 @@ sail4
sa2ka
3saki
s4akr
-4sakt
-3s2al.
+4s3akt
+3sal.
3s2a1la
sal3erb
sa2l1id
+s1all
5s4alo
sal2se
-4s1alt
+6s1alt
5s4alz
-3s2am
+3sam
+5sam.
+5same
s3ameri
+5samf
+5samk
5s4amm
6s5amma
-4s3amn
+4s1amn
4samp
-3s2an.
-2s1a2na
-2sanb
+5sams
+5samu
+s1an
+3s4an.
+2s3a2na
+2s3anb
s2an2c
s2and
san4d3ri
-3sang.
+5sang.
2s3anh
-5sani
-2s3anl
-2s1ans
+3sani
+2sanl
+2s3ans
san4sk
san3sp
-4sanw
+4s3anw
2s3anz
2s1ap
sa2po
3sapr
2s1ar
-3sar.
+3s4ar.
3sara
-4s3arb
+4s5arb
3s2ard
3sari
+s3arl
s3arm
s3arr
-3sars
-4sart
-s3arz
+3s4ars
+4s3art
s3a4sp
-sa3stu
6s5asy
-s2aß
3sat
sat2a
-5sate
+5sa3te
4s3ath
4s3atl
4satm
@@ -11150,54 +11043,57 @@ sa3ts
5satz
sat4z3en
sat4zer
+s1au
3sau.
3saue
2sauf
-4s3aufb
+4s5aufb
3saug
sau2gr
3saum
-5saur
sauri1
-2s1aus
-4s3ausb
-3sause
-s3ausf
-s3ausg
-s1auß
+2s3aus
+4s5ausb
+3s4ause
+s3auß
sa2vo
-3s2ax
+3sax
3say
1sä
+3säb
3säc
s3ähn
3säle
s1ält
2s1äm
-2s3änd
+2s1änd
3sänge
2s1är
+sä2s
3sät
3säul
2säuß
-4s5b6
+6s3b4
sba4n
sber2
sbe3re
-sby5
-1s2c
+sby3
+1sc
2sc.
+s2ca
+2scam
6scar
-4s3ce
+2s1ce
6sch.
-2schak
-5s4ch2al
+7s2ch2al
4schanc
-5schanz
+7schanz
6schao
-5s4chä
+s2chau
+s2chä
+3schäd
4schb
-4schc
+2schc
3sche
4schef
sch3ei.
@@ -11207,70 +11103,65 @@ sch5erla
4schess
4schex
4schf
-4schg
-4schh
+2schg
+2schh
3schi
-7schic
schi4e
s4chim
4schiru
4schk
-s4chl
4schle.
6schlein
sch6lit
4schn.
-5s4chö
-6schöl
-4schp
+s2chö
+2schp
+2schq
4schre.
sch5rom
-6schs
-schs4e
-sch3s2k
-sch3sti
+6schs4
+sch3sk
+sch5ste
+sch5sti
6scht
sch3t4a
sch5te
3s4chu
4schunt
sch2up
-5schü
-4schv
+2schv
4schwet
-4schz
+2schz
+s2ci
2scj
-4scl
-4sco
-5s4cop
+6scl
+6sco
+7s2cop
2scs
2scu
-4s3d
+4s1d
+s3da
sda3me
-sde3s
-sdi1st
+s3do
1se
+3se.
se3a
se4al
se5al.
se5at.
-4s1e2ben
+2s1e2ben
se3b4r
2sec
4s1echo
-sech2s
-s1echt
-se2ck
-5secl
-5seco
-4sede
-7see
+4s1echt
+3secl
+3seco
+2sede
+5see
se1ec
se2e1i4
-see3ig
se1er
2s1eff
-3seg
se2gal
se2gl
seg4r
@@ -11284,26 +11175,27 @@ se4hin
seh1l
seh1ra
seh3re
-seh1s
+seh3s
se2hü
2s3ei.
3sei3b
-4s3eig
-s1ein
-7s4ein.
-4seinb
+2s1eig
+5s4ein.
+2s1einb
+s1eind
sei5n4e
-4seing
-2s3einh
-4s3eink
-2seinl
-4s3einn
-4seinr
-s4eins.
-4seinst
-2seinw
-4seis
-7s2eit
+2seing
+2s1einh
+4s1eink
+4seinl
+2s1einn
+2seinr
+s3einsa
+s3einsä
+4s3einst
+2s1einw
+2seis
+7s4eit
5s2ek
s2el.
se2l1a2
@@ -11311,7 +11203,7 @@ se3lad
sela4g
se3lam
sel1ec
-4selem
+2selem
se2ler
sel3erl
sel3ers
@@ -11320,26 +11212,27 @@ se4l1ö
s2els
sel3sz
sel3tr
-5sem.
-s4e3ma
-4s1emp
-s2en.
+3sem.
+se3ma
+2s1emp
+5s2en.
3sena
se4nag
se3nal
-4s1endl
+2s1endl
se4ners
sen3gl
-5s4eni
+7seni
sen3ob
3s2ens
+sen6stri
s2ent.
-4s1entf
-2s3entg
+2s1entf
+6s3entg
s2enti
4s3ents
-4sentw
-2sentz
+2sentw
+4sentz
se2n1u
seo2r
4s1e2pos
@@ -11352,81 +11245,77 @@ s3ereig
se4r3eim
se4r3enk
ser2er
-4s3erfo
+2s3erfo
s2erfr
-6s3erfü
+4s3erfü
ser3g
s1ergä
s2ergr
-4s1erh
-5seri
+2s1erh
+3seri
s1erkl
s1ernä
-4s3ernt
+2s3ernt
se1rot
+2s3eröf
s2ers.
s4ert.
ser3the
seru2
se4r1uf
se3rum
-7s6erv
+5s6erv
5ses.
se3su
3set
s3eta
-4s5e4tap
+4se2tap
se2tat
4s3e2th
+5setz
+3seum
se1u4n
-2sex
-4sexa
-s1e2xe
+2s1ex
+se2xe
4sexp
sex3t
-4s3f
+6s3f
sfal6l5er
-s5fi
sfi3le
-s5fü
4s3g4
-sge3s4a
+sges4
+sge3sa
2s1h
3sha.
sha2k
4shan
-1shas
-s3hä
3shi.
3shid
1shi4r
sh3n
-s3hoc
4shof
-3s4hop
-sho4r
-3show
-s3hö
+3shop
+sho6r
+5show
sh4r
+s3hü
1si
si3ach.
5siak
si1am.
+2siat
si3b4
3si1c
s1ideo
s2ido
3s2ie
-siege4s
si3ene
si3err
-sie2s
3si1f4
-5sig
-si2g1a2
+5s2ig
+si2g1a
si3g4n
si2g3r
-sig4s
si2k1ab
si4k3ere
si4k3erl
@@ -11439,37 +11328,37 @@ si2ku
si5l2e
3silo
2s1imm
-3sin.
si3n4a
2s1ind
-6s1inf
+4s1inf
sin2g1a
sin3gh
sin3g4l
sin2gr
-sing3sa
-6s1inh
-sin1i
-sini1e
+sing5sa
+4s1inh
+sin1i1
+3sinn.
+3sinnl
2s1inq
2s1ins
2s1int
-6s1inv
+4s1inv
3s4io
si3od
si3os
-5s2is
+3s2is
si2sa
si4schu
-si4s1e
+si2s1e
si2s1o
sis1p
-sis3s
-7s2it
+sis5s
+si2stu
+3s2it
si2tau
-si3te
si2t3r
-sit3s
+sit5s
si3tu
5siu
si2va
@@ -11479,24 +11368,18 @@ six3
2s1k4
4sk.
s3kad
-s2kala
-4skam
-4s3kanz
-s3kar
-4skas
+4s3kam
+4skanz
+4s3kas
ska4te.
ska4tes
-s3kä
4skb
4ske
3s2ki.
3s2kik
4skir
-ski3s
3skiz
s3klas
-s3kn
-skna3
4skom
4skor
4skö
@@ -11505,9 +11388,8 @@ s3kra
4sk5t
3skulp
2s1l2
-3s4lal
+3slal
4slan
-s3lä
sl3b
s5le
s5li
@@ -11515,7 +11397,8 @@ s5li
s3lo.
slo3be
s3loe
-2s3m2
+2s1m2
+s3mu
2s3n2
4sna
sna1b4
@@ -11524,13 +11407,10 @@ sni3er.
sni3ers
4s5not
4snö
-s5ny
1so
3so.
3so4a
-4s1o2b
-6sobj
-so1c
+2s1o2b
so3et
3soft
3sog
@@ -11538,7 +11418,7 @@ so3gl
so2h
s1ohe
so3hi
-4s5ohng
+6s5ohng
so3ho
2s1ohr
3sol.
@@ -11557,12 +11437,13 @@ s1opf
3sor.
so1ral
s1orc
-4s3ord
+2s1ord
so2rei
so3ren
-4s1orga
-4s1o2rie
+2s1orga
+2s1o2rie
so2r1o
+5sorp
3sors
so4ru
3s2os
@@ -11575,13 +11456,11 @@ so3unt
3sov
s1o2ve
s1ox
-s4oz
1sö
-sö2c
sö2f
2s1ök
2söl
-s1ös
+s1ö4s
1sp2
4sp.
4spaa
@@ -11592,14 +11471,14 @@ spani7er.
4spano
4spap
4spara
+2sparo
spar5sc
-3spaß
-2spat
+3s4paß
2spau
s2paz
-2spär
+4spär
2sped
-3s2pee
+s2pee
3s2pei
4spel
2s1peri
@@ -11613,11 +11492,11 @@ s2paz
3sphä
s3phe
3spi
-5s2pi4e
+5s4pi4e
7spiel
spier4
spi2k
-4s3pil
+6s3pil
4spip
4s3pis
2spl
@@ -11632,13 +11511,15 @@ spi2k
4s3pok
4spol
4s3pos
+s2pott
4spr.
-s2prac
+3s2prac
4sprax
4spräm
4spräs
5s4prec
2spred
+4sprei
4spres
2spro
4sprob
@@ -11647,292 +11528,296 @@ s2prac
2sprüf
3sprün
4s3ps
-4spun
+2spun
2spup
5s2pur
4sput
3spü
4spy
2s1q
-4s3r4
+6s3r4
srat6s
sret3
+sro3m
srö4s
-srös3c
+srös1c
srü2d
-4s1s
+6s1s
+ss2a
+ss3ab
+ssa3be
ssa3bo
-ss1a2ck
-ss1aj
-s3sal
-s4s3ala
-s4s1alb
-s4s1amt
-s4s3ang
-ss1ano
-s4s3ans
-s4sanz
-s3sas2
-ss3att
-ss1au
-s3s2ä
-s3se
-s4s1ec
-sse4ck
-s4s1ega
+ss1ack
+ss4ag
+ss3aj
+s3s4al
+s4s5ala
+s4s5alb
+ss4am
+s4s5ang
+ss3ano
+s4s5anz
+s3s4as
+ss3auf
+ss2ä
+ss1ech
+ss1eck
+ssee2
+s2s1ega
sse3ha
+ss1ein
sse3inf
sse3int
ss1eis
-s5sen.
ss2er
+s3ser.
sse6r5att
+s3serh
ss3erhö
-s4s3erö
s4s3erse
s5s4es
ss4et
sse3ta
-ss5g
-s5sie
s3skala
-ss3la
ss1off
-s6s1op
+s4s1op
s2s1ori
s3spe
s3s2po
ss5re
-ss3s4
-s3st2a
-s5stad
-sst6e
-ss3tec
-s3stel
-ss2ti
-s3stip
-s3sto
-s3stu
-ss2tur
-s3stü
+ss3s2
+s5st2a
+s7stad
+s5stä
+ss1t6e
+s4ste.
+s5stel
+ss2th
+s5stil
+ss1tis
+s5sto
+s5stu
+s5stü
ss1ums
-4st.
-1sta
-2sta.
-3staa
-stab4s
-3s2tad
+ss2zen
+1st
+6st.
+3sta
+s4ta.
+5staa
+4stabb
+4stabh
+4stabl
+stab6s
+4stabt
+4stabz
+5s4tad
+6stada
+6stadr
5staff
-4stag
-3stah
-2stak
-s5tal.
-sta5li
-2stalk
+6stag
+5stah
+4stak
+4stal.
+5sta5li
+4stalk
st1alp
st3ami
-4stan.
+4stamt
st3ana
-3s4tand
-2stani
-4stann
-2stans
-s3tans.
-2stanw
-s2tar
-3s4tar.
-3s4tars
-st2art
-2sta2s
+5stand
+4stanl
+6stann
+4stanw
+5star.
+5stars
+5st2art
+sta2s
st3a4si
-3stat
+5stat
4stat.
-3stau.
-2st1auf
-2staum
+s2tati
+5stau.
+5staub
+4st1auf
+4staum
5staur
-2staus
-3staus.
-2stax
+4staus
+5staus.
+4stax
3stä
4stäg
4stält
+4stämt
+5stär
+2stäti
5stätt
+4stäus
4stb
2stc
st3ch
2std
-4ste.
-2stea
-s2tec
-3steck
-1s2teg
+3ste
+4stea
+5stean
+7steck
+4stee
ste2g5r
-3steh
-1s2te2i
-3steig
-2steil
+ste2i
+5s4teig
+6steil
+s4tein
4steing
-1s2tel
-2stel.
-2stele
+s2tel
+s3telem
stel4l3ä
-2stels
-2stem
-4stem.
ste4mar
-4sten
-s4t3ends
+4stempf
+4st3ends
ste2ne
-s4t3engl
-s5t4ens
-s4t3entf
-s2tep
-2ster
-6ster.
-s3tera
-st6erb
-4sterk
-3sternc
-s3ters
-4stes
-s4t3ese
-stes6se.
-ste4st
-2stet
-4stet.
-3s4tett
-3steu
-5steue
+st3engl
+st4ens
+6st3entf
+4stentw
+4stepi
+5st6erb
+st2erg
+5sterj
+s2tern
+s2ters
+6st3ese
+4stesse
+ste4stä
+4stests
+5steß
+s2teu
4steuf
st3ev
-4stex
-2stf
-2stg
-4sth
+6stex
+4stf
+4stg
+6sth
st3ha
-s2t1hi
+st1hi
st3ho
st1hu
-2stia
-2stib
-2stie.
-1s2tiel
-2stien
-3s2tif
-5stift
-4stig
-2stik
-3s2til
-3s4tim
+3sti
+5stic
+5stif
+5stil.
+5stile
+5stim
+4stinf
st1ins
st1int
-2stio
-2stip
-1s2tir
-2stis
+4stip
+sti2r
st3iso
-1stitu
-2stiv
2stj
4stk
-4s4tl
+4stl
st5le
4stm
-2stn
-1sto
-4sto.
+4stn
+3sto
+4stob
+7stock
4stod
-sto3de
-s2toff
-s2t5om
+5s4to3de
+5stof
+4st3om
4ston
-2stopo
-2stor.
-2store
-2storg
-2stori
-2s3tose
-stos2t
-3stoß
+4stopo
+4storg
+sto5rin
4stou
-4stow
-4stoz
+s4tow
3stö
4stöch
-4stön
-4stöt
+7s2tör
+4s3töt
4stp
2stq
-2strad
-5straf
-2strag
-3s2trah
+3str
+5s2traf
+4strag
+5strah
6strai
-4strak
-4stral
+5s2tral
4strans
5s2tras
-5straß
-4sträg
+7straß
+6sträg
4sträne
+4stre.
+4strech
4stref
5streif
st3renn
-s2tric
-2s2trig
-3s2tri2k
-s2trip
-2s3tris
+4strev
+4stri.
+5s4tria
+4strib
+6strig
+stri2k
+2strin
+2stris
+4strisi
+4stroc
+5s2trof
+5s2trok
st3roll
-stro2m
-2strop
-1stru
-4strua
-3struk
+stro4ma
+s2tros
+5s2trö
+5struk
+s2trum
4st3run
-4st3s4
+4strup
+6st3s4
st1sk
st1sl
st1sz
2st3t2
5stub
-4stuc
-5stud
-4stue
-3stuf
+6stuc
+5s2tud
+2stue
3stuh
-stum2s
-stu4n
-4stun.
-3stund
-s2t1uni
-4s3tuns
-4stunt
+4stuk
+4stumr
+stum4s
+4stumz
+s2tu4n
+6stun.
+2stunf
+3stung
+2st1uni
+2s3tuns
+2stunt
stu5re
st1url
-4sturn
-stur4s
-4st1urt
-2stus
-1st2ü
-3stüc
+2sturn
+2st1urt
+3st2ü
4stüch
-3stüh
-2stür.
-3s2tüt
-4stv
+s2tück
+4stür.
+s2tüt
+2stüte
+6stv
4stw
-5styl
+2sty
+3styl
4st3z2
1su
-su1an
+su1an5
3su2b5
su4ba
-4su3bi
-5su1c
+6su3bi
+7su1c
2s1u2f
-4s1uh
+2s1uh
3sui
su1is
su3it.
@@ -11943,125 +11828,130 @@ su2mau
3sume
su2m1el
su6m5ents
-2sumf
+s3umfa
s3umfe
-2sumk
-2suml
3summ
sumo2
su2m1or
-2sums
s3umsa
s3umst
su4n
-5sun.
+3sun.
sun6derh
s1unf
2s1uni
-6s3unt
-5s2up
+4s3unt
+3s2up
su2ra
2s1url
s1urt
-3su2s1
+su2s1
su3sa
su3sh
su3si
-3suv
+sus3s
1sü
-2s3ü2b
-3süc
+4sü2b
3sü2d1
-3sün
-4s3v
-s5va
-2s1w
-s3wa
-s3we
+5sün
+4s1v
+4s1w
+swa5re
sweh2
-4s3wie
-4s3wil
+6s3wie
+6s3wil
s3wir
s3wis
s2y
3sy.
-sy2l
+sy2l1
sy4n1
-1sys5
+1sys
+sy5st
sy3t
2s1z
-s3za
+4s3za
4s3zei
3s2zena
-5s4zene
+5s2zene
4s3zent
s2zes
+s2zeß
s2zis
+s3zö
4s3zu
-s3zü
s3zw
2ß.
-2ß3a2
-2ß1b
-4ß1c
-2ß1d
+ß3a2
+ß1ä
+ß1b
+2ß1c
+ß1d
1ße
2ß1ec
2ß1e2g
2ß1ei
-ße2l1a
+ße2l
+ßel1a
+ße3lu
ßen3a
-ßene4
ßen3g
ße2ni
-ßen3st
+ßen5st
ßen3sz
ße2nu
ße3rin
3ß2ers.
-2ß1f
-2ß5g2
+ße2t
+ß1ex
+ß1f
+ß3g2
ßge2bl
2ß1h
1ßi
-ßi2g1a2
-ßig4s
+ßi2g1a
2ß1in
ß1j
2ß1k4
-ßkir5
2ß1l
+ß3la
2ß1m
-2ß5n2
+ß5n2
ß1o2
-2ß3p2
+ß1ö
+ß3p2
+ß1q
2ß3r2
2ß3s2
ßst2
2ß1t
-ß3ti
-1ßu
-2ß1um1
-2ß1ü
+ß2t1h
+ßts4
+1ßu4
+ß1uf
+2ß1um
+ß1uni
+ß1ü
2ß1v
2ß1w
-ßwa3
+ßwa5r
+ßwa3s
2ß1z
-4t.
+6t.
3ta.
2taa
-3taan
+tab4
2tab.
-ta2b1an
+ta2b5an
2t1abb
-3tabel
+1tabel
4taben
ta4bend
-4tabf
+2tabf
4tabg
4tabh
4tabk
-ta1b4l
+ta1bl
1table
2tabn
4tabs
@@ -12069,15 +11959,12 @@ ta1b4l
ta2bü
2tabw
4tabz
-ta1c
tach3te
t3ada
tadi3
t3adr
-1taf.
1taf2e
3tafel
-4taff
t1afg
t1af4r
3t2ag
@@ -12086,11 +11973,11 @@ ta2ga
ta2g5ei
4t3agent
ta3ges
-2ta3gl
+ta3gl
ta3gn
4t3a4go
-tag4s
-tag5sc
+tag6s
+tag7sc
tah4
tah3le
tahl5sk
@@ -12100,11 +11987,11 @@ tai2l
ta1ins
tai4r
ta1ir.
-4t1a2ka
+4t3a2ka
ta3kes
3takr
ta2kro
-tak4ta
+tak2ta
3taktb
3t2aktu
3t2al.
@@ -12112,47 +11999,44 @@ ta1lag
ta1lak
1talbu
tal3d
-1t4ale
+3t4ale
ta3len
ta4lens
-1talia
-5talis
+tal4leg
tal2lö
-1talo
ta2l1op
ta3lum
2ta2m
3tam.
ta3ma
-3tame
3tamg
ta3mo
-t3ampl
+t1ampl
t1amt
-3t2an.
+t2an.
t1a2na
ta4nat
-2t2and
+4tanb
+t2and
tan3da
tand4st
ta3ne
4t1anf
-3tanis
t2ank
tan4kl
tan3kr
-4tanl
+2tanl
2t1anme
4t1anna
1tanne
t1ans
-1tans.
-2t3ansi
+4t3ansi
2t3ansp
ta4nu
2tanwa
2tanwä
t4anz.
+4tanzei
tan6zerh
t1anzu
ta3or
@@ -12162,7 +12046,6 @@ ta2pes
t4ar.
2t1arb
t1arc
-3tard
ta6rens
3ta3ri
2tark
@@ -12171,20 +12054,15 @@ ta6rens
t3arti
ta2ru
2t1arz
-3tas
-1tas.
ta3sa
1ta3sc
-2ta3se
4t3asp
-1tast
-ta3sta
-ta1str
+1tas2t
1tat.
ta2tan
-ta4t1ei
-ta4tem
-ta4t1er
+tat1ei
+ta2tem
+ta2t1er
ta2th
tat3he
t3atl
@@ -12195,14 +12073,15 @@ ta2t1um
tau4fer
tau3f4li
2taufw
+1taug
t1auk
2taur
1taus
+2taus.
t1ausb
-3tausc
tau6schw
t1ausd
-3tause
+3t2ause
t1ausf
t3ausg
t1ausk
@@ -12211,135 +12090,112 @@ t1ausr
2t3auss
t1ausü
4t1ausw
-1tav
ta3va
3tax
ta3xi
-1taz
tä1c
1täg
2tägy
2täh
+3täle
4t1ält
2täm
t1ämt
t1ängs
-3tänz
+1tänz
t2är.
tä2ru
tä2s4
-4tätt
+tä4st
+2tätt
t1äug
1täu3s
4täx
1tà
-4t3b
+2t5b
tbe3r2e
tblock7en
-4t1c
+2t1c
t3cha
t3che
tch2i
tch3l
t2chu
tch1w
-t2ck
t3cr
2t3d4
tdun2
tdu3s
-1te
-3te.
-te2a2
-2teak
+1te2a4
te3al
-3team
te3an
-5teba
5t4ebb
2t1e2ben
-t2ech
-te5cha
+1t2ech
+te1cha
3techn
-4teck
-te2cka
-te2cki
+2teck
3tee
te1ele
te1em
te2e4n1
te1erw
4tefe
-4teff
+2teff
te2fl
teg4
teg3re
2teh
te3han
-3tehä
-5tei.
t2eie
-3teil
-4teilhe
+2teig
+1teil
+3teiln
+3teilz
2tein
-tein3e4c
+tein3ec
t3einge
t3einla
4t1einn
4teinr
-4teinz
t1eis.
t1eisb
-tek5te
-5tel.
-3te2la
+tei5st
+tek3te
+te2la4
te4l1ab
tel1ac
te3lan
tel1au
-3telb
-3tele
tel1e2b
tel1ec
-5telef
+3telef
+3teleg
te4l1eh
-te3lem
+1te3lem
tel1en
te3lep
te3lex
-3telf
4t1elf.
-3telg
tel1in
te2lit
-3telk
t4ell
tel3l2e
-5teln
te2lo
te2l1ö
-3telp
-5tels
tel3s2k
-3telt4
tel3ta
-3tem
-5tem.
-te2man
+tel3t4r
te2m1ei
te2mi
te3mis
-4temm
-2temme
+4temo
te2m1o2r
-5temper
-4tempf
-tem1st
+3temper
+1tempo
te4m3u
-3ten
-5t6en.
+t6en.
te4n3a2
-te5nac
t4enb
ten3da
6t5endf
@@ -12358,10 +12214,9 @@ t2enl
t2enm
t2eno
t2ens
-tens2e
4t3ensem
ten3si
-tens3th
+ten5st
t1entb
4tentd
t1entn
@@ -12372,7 +12227,7 @@ ten3zw
te2o
te3ob
t1e2pi
-5t6er.
+t6er.
te1raf
ter3am
te3ran.
@@ -12380,35 +12235,32 @@ te2r3as
t2erb
6t5erbs
6t5erbt
-4t3erde.
-3tere.
+t3erde.
te2r1e2b
te4r3eif
te2rel
-3terem
-3teren
ter3end
-3terer
-3teres
-5t4erfr
+t4erfr
4terfül
ter3g
t6ergru
+2t1ergu
+2tergü
te3ria
ter3k4
-3t2erka
+t2erka
4t3erklä
-3terkr
t4erli
4t1erlö
t4erlu
-3term
+1term
ter4mer
+3termi
ter4n3ar
t3erneu
t1erö
-3terr
ter4re.
+1terro
t6ers.
t6erscha
ter4ser
@@ -12416,43 +12268,37 @@ ter4sk
terst4
t4erst.
t4erste
-5t4ersti
-ter5sto
+t4ersti
ter5str
-5t4erstu
-3tert2
-3teru2
+t4erstu
+tert4a
+teru2
te4r1uf
ter3z2a
-2t1erzb
-3t2es
-tesa2
-tes1ac
+4t1erzb
+t2es
+tes3ac
te2sel
+3tesse.
tes3si
-5te2st
-tes3tan
+tes2t
tes3tät
-test3ei
-tes6terg
+te4st3ei
+te7ster.
+te4str
+1tests
+te4stu
te2su
-3tet
te2tat
-4teth
-4teti
6tetl
-2teu
3teuf
-3teum
te1un
-3teur.
teu2r5a4
t5euro
te2vi
-5tewo
-te2x
+1te2x
te3xa
-2t1exe
+t1exe
4t1exi
4texp
3text
@@ -12460,7 +12306,7 @@ te3xa
1té
2t3f
tfi4l
-4t1g4
+2t1g4
tg2a
t3ge
tger2
@@ -12474,9 +12320,10 @@ t3hap
t2har
4t3hau
4t1hä
-2thc
+4thc
+1the
t2he.
-3t4hea
+3thea
4theb
t2hec
2t1hei
@@ -12485,13 +12332,14 @@ t1hel
3t2hem
5thema
5theme
-1then
3theo
t2hera
t1herd
-t1herr
+2t1herr
t1herz
-1these
+t2hes
+3these
+1thi.
3thia
2t1hil
t1him
@@ -12507,6 +12355,7 @@ t2hol.
4tholz
t2hon
4t3hot
+thou4
4t3hö
2thp
3thr2
@@ -12516,86 +12365,77 @@ t2hon
4thun
t1hü
2thv
-1ti
ti2a
ti3a2m
ti3an
tib4
-3tibe
-3tibl
-2tic
ti1ce
+ti3chr
ti4d3end
t2ie
tie3br
-3tief.
-2tieg4
-2tieh
+5tief.
+tieg6
ti1el
ti2el.
ti3e2n1
ti2er
-3tiera
-4tieß
+1tierr
+2tieß
ti3et
ti1eu
-3tif.
+5tif.
ti3fa
+tif3f
ti1fr
-3tig
-3tik
-ti4kam
+tihi4
+ti2kam
ti3k2an
ti2kr
-tik5t
+ti2la
+ti3las
ti2lei
til1ep
-3tilg
+1tilg
ti3lo
ti4lö
tilt4
ti2lu
-2tim
ti2mag
tim2m1a
4t1imp
-5tin.
ti3na
t1inb
4t1ind
ti5n4e
-2t1inf
+t1inf
tin2g1a
tin2g3l
tings2
-ting3st
+ting5st
t1init
4t1inj
tin2k3l
t2inn
-3tins.
4t1inse
4tint
4t1inv
-5tio
+3tio
ti3or
+3tiö
3tip.
ti3pl
-3tipp
-3tips
-ti2rak
+1tipp
+1tips
ti1rh
-5t2is
+t2is
tisch3w
-ti4sei
+ti2sei
ti2sol
t4it
3tite
-tit2h
-2ti3tu
-tiu6
-tium2
-5tiv
+5titel
+tium4
ti2van
ti2vel
ti4v3erl
@@ -12604,6 +12444,8 @@ ti4v1r
ti2za
2t1j
2t3k4
+tklat5
+t5kr
tkü1b
2t3l2
tl4e
@@ -12611,44 +12453,37 @@ tle2r5a
4t5li
tli5f
tlings3
+tli5s
+t5lo
tlö3s
-2t1m2
-t5ma
+2t5m2
tmen2s
tmen6t
-tmin4s
tmo4des
t3mu
tmüll4s3
2t5n4
tna5me
-tnes4
-3to.
-toa4
+tnes6
to5ar
-to5at
+to5a4t
1tob
to3be
2tobj
tob4l
-to2c
-to3ch
+to1ch
3tocht
-to6ckent
3tod
tode4
-4to2d1er
-tode6s
+to2d1er
+tode6s1
to4d1u
-1tok4
-1tol
+tok4
to3la
-3tole
-2tolz
tome2
to4men
2tomg
-3ton
+1ton
to5nik
to3ny
3too
@@ -12659,81 +12494,70 @@ t3opfer
to3phe
to2pl
1topo
-2topp
-1tor
-3tor.
to1ra
to2rau
to4rän
4torc
t1ord
-3tore
+1tore.
to2r1el
to3ren
-2t1org
+t1org
t3orga
3torh
tor3int
to2rö
-3tors
+1tort
t1ort.
to4ru
-2tory
-to5sc
-1to5se
+to7sc
+to5se
to4sk
-to5s2p
-2toss
-1to3st4
-2toß
-3to5te
+to3s2p
+tost4
+to5sta
+1toten
to2tho
-1totr
-5t4ou
+3t4ou
touil4
to3un
3tow
-1toz
-3töch
+tö2c
+1töch
2t1öf
2t1ök
3tön
-tör3ste
+tö4s
t1öst
1töt
4t3p2
-tpf4
+t5pf4
2t1q
t2r4
2tr.
-5tra.
tra3bl
-1t4rac
-3trach
+t4rac
+1trach
tra3cha
t3rad.
tra4dem
-3trag
+1trag
+3tragö
2t3rahm
5t4rai
-3trak
-3tral
3t4ran.
2trand
3trank
t3rann
-5trans
+3trans
t3rase
t3rasi
-tra4st
2traß
1traum
-3träc
+1träc
t3räd
-3träg
-3träne
-2träs
-2träß
+1träg
+1träne
4t5re.
2treb
2trec
@@ -12741,74 +12565,66 @@ t3rech
t4reck
2t3red
t4ree
-3tref
-4trefe
-4trefo
+1tref
+2trefe
+2trefo
2treg
t4rei.
-3t4reib
-2treic
+1t4reib
2treif
t3reig
2t3reih
t3rein
-2t3reis
-4treit
+t3reis
t3reiz
2t3rek
2t3rel
t4rem
t4ren.
-3trend
-4trendi
+1trend
t3rent
2trepe
2trepo
+1trepp
t4rer
-3t4res.
-t4ret
+t4res.
+1t4ret
tre2t5r
t4reu
-3treuh
t3rev
2trez
5t4ré
2t3rh
-1tri
+1trib
t4riche
-3trieb
+3trieb.
+3triebs
tri4er
-3trigg
t3rind
tri3ni
3trio
t4rip
+1triu
trizi1
-1tro.
tro3b
-1troe
-3t4roi
+1troc
+t4roi
tro2ke
-2trom.
tro2mi
-2troml
-1tron
2t3roo
t4rop
3tropf
-1tros
-3troy
+2troß
t3röc
3trög
-1trös
2tröt
-1trua
3trug
2truk
trum2
trums1
-3trunk
+1trunk
3t4rup
+t3ruß
trü1be
trü1bu
2t3rüc
@@ -12816,41 +12632,39 @@ trü1bu
try1
2ts
4ts.
-t2s1a
+t2sa
t4s3ab
-t5s4ac
+t5s2ac
ts3ad
t3saf
-ts2ag
-t4s3amt6
+ts1ah
+ts1al
+t4s1amt
t4s3ar
ts3as
t4sau
t5sau.
t2s1än
-t2sca
+ts2c
t4schar
-t5sch2e
+tsch2e
tsch4li
t4schro
-ts4cor
t2s1e2b
-tse4c
-ts1eck
+t3seg
t4s3e4h
t3seil
t4seind
+ts3einl
ts1em
tse2n
-t3sen.
ts1eng
t2s1ent
t2s1er
-t4s3esse
-ts1ex
t2s1i2d
ts1ini
t2s1ir
+t7sit
t3skala
ts3kr
t2s1o2
@@ -12868,38 +12682,42 @@ t3spek
ts2pi
t3s2pon
t3s2por
-ts3s2
-t1s2t
-ts3taf
-ts3tak
+ts5s2
+ts1tak
+ts2tat
ts3täti
-ts3tep
-t3stero
+t4s1tep
+t5s4ter.
+t4sterm
+t5stero
+ts3terr
+t5s4tes.
t5steu
-ts3th
-ts4til
+ts1tie
+t4s3tis
t6stit
+ts2to
ts3toc
ts3tor
-ts3trad
-t4s3trau
-t2s3trä
-t2s3tri
-t3strö
+t4s3trad
+t4strau
+t4s1trä
+t4s1tri
+ts2tro
+t4strop
ts3trü
-t3stu
-t3stü
t2s1u
1tsub
t3sy
4t1t
tt1ab
tt3ad
+ttag7ess
t2t1ak
t3tal
t3tan
-t4tanb
tt1art
+tta5st
tt1auf
tt1ebe
tt1eif
@@ -12908,6 +12726,7 @@ tt1eis
t3te2l
tte4la
tte4l1o
+t3t2er
tte2s
tte4s1ä
t2teti
@@ -12916,9 +12735,7 @@ tt3ha
tt2häu
tt1ho
tt1hu
-t3ti
t3tra
-t2trau
t3trä
t3t4ro
tt5rom
@@ -12929,33 +12746,30 @@ tt3sec
tt5se5h
tt3sel
tts1p
-tt2s3ti
+tt4s3tem
+tt4ster
+tt4sti
ttt4
-t3tu
+t2tuc
tt3z2
-1tu
tu1alm
tu3an
2tub
-3tuch
+1tuc
tu2chi
-2tud
-3tue
+1tue
tue3re
tu3et
-2tuf
tuf2e
tu3fen
t1u2fer
2tuh
-2tu2k
+tu2k
tu3ka
t1ukr
tu3la
-3t2um.
-5tume
+t2um.
2tumf
-2tumg
2tumk
tum2si
tum2so
@@ -12965,14 +12779,14 @@ tum2so
2tund
3tu3ne
2t1unf
-3tung
t1unga
tun2gl
-tung6s
+tung8s
2tunif
2t1u4nio
+3tunn
+1tuns
2tunt
-3tuö
t1up.
tu2ra
tur3a4g
@@ -12985,7 +12799,7 @@ tu2r1er
tur3ere
tu4res
tu2r3e4t
-3turn
+1turn
tu2ro
tu3rol
tur3s2
@@ -12995,61 +12809,58 @@ tu2sa
tu4schl
tu4so
tu3ta
+tuts3c
2tüb
t3übe
-3tüch
-tück2s
+1tüch
+tück4s
1tüf
-1tüm
1tür.
tür1c
1türe
1türg
-1tür3s
+1türs
3tüten
2t1v
t5vo
4t1w
-twa4r
twi4e
1ty
2tyl
ty4le
-3typ
ty2pa
-ty3st
2t1z
t2z1a2
tz3an
tz3as
t2z1ä
t5ze.
-t2z1e4c
+t2z1ec
t2z1eie
t2z1eis
tze4n
tz4ene
tz3ents
t2z1erl
-t3ze2s
+t3ze4s
tz1imp
-tz1ind
tz1int
t2zo
tz1of
t3zon
tz1or
-tz4tin
+tz2tin
t2z1w
2u.
u3a2b
-u1a2c
+u1a4c
ua3d
uad4r
u1al.
u3alet
u1alf
-u3a2lo
+ual3l
+ua2lo
u1alr
u1als
ual3t
@@ -13069,6 +12880,7 @@ u1äm
u1äu
2u1b
u3be
+ub3ein
ub6i
ub3lic
ub5los
@@ -13076,20 +12888,21 @@ u3blö
ub3lu
u2bop
ub3rä
-ub5rit
+ub3rit
ub2sa
ub2s1o
ub2spa
ub3um
u2b3üb
-4uc
-u1ce2
+2uc
+u1ce4
+uces3
u2ch1a
u3cha.
uch3an
uch1ä
u1che
-u2ch1e2c
+u2ch1ec
uch1ei
u3ches
u1chi
@@ -13100,30 +12913,28 @@ uch5m
uch3n
u2ch3r
uch2so
-uch4spr
uchst4
+uch5str
uch4tor
uch2t3r
u1chu
uch3ü
uch3w
-u2ckem
-u4ckent
uck2er
-u4ck3erl
-u2cki
+uck3erl
uck4sta
u1cr
2u1d
u5d2a
-udens2
ude3r2e
+ude5sa
udi3en
uditi4
u4don
ud3ra
+ud2s
+ud3sc
u1e
-ue4ck
u2ed
ue2en
u2eg
@@ -13143,11 +12954,10 @@ u5eremp
u5erent
ue4rerg
uer3g2
-u5erinf
-u5erint
+u3erinf
+u3erint
uerk4
uer4ne
-uern3s4t
uer3o
u3err
uert2
@@ -13155,11 +12965,13 @@ u3erum
u3erunf
u3erunt
u3erur
-u3erv
uer3z
+ue4s
+ue5se
+ue5sp
ue2ta
ue4tek
-uet4s
+uet2s
uf3ad
u3fah
uf1ak
@@ -13174,6 +12986,7 @@ u3fen.
u2fent
u2f1erh
uf2ern
+u2f1eß
2uff
uf3fe
uff4l
@@ -13184,8 +12997,12 @@ uf1ori
u1fö
uf3r
uf5sä
+uf4s3tem
+ufs3ten
+uf4ster
uft1eb
-uft3s4
+uf3ten
+uft3s2
uft5sa
2u1g
u4gabte
@@ -13200,7 +13017,6 @@ u2g5ent
ug5erf
ug5erl
uge7sc
-ugge4st
ug3hu
u2g1l
ug3lä
@@ -13215,25 +13031,25 @@ u4g3reis
ug3ro
ug3rum
ug3rüs
-ug5sc
+ug3sau
+ug7sc
ug3s2e
ug3si
ug3spa
ug4spr
ugs2t
-ug5stä
-ug3str
+ugs3te
ugut2
u2gü
u1h
2uh.
uhe1ra
-uhe1s4
-uhe3st
uh1la
uh1lä
uh3ma
-uh5me4
+uh5me6
+uh3mi
+uh3na
uhr1a
uhr3er
uh1ri
@@ -13243,16 +13059,17 @@ uhr3tr
uh2ru
uh1w
4ui
-ui2ch
+ui2c
u1ie
ui1em
-u3ig
-u4ige
+u1ig
+u2ige
u3in.
+ui5ne
u3isch.
u3ischs
uisi4n
-ui4s3t
+ui4st
u1j
ukä2
u3käu
@@ -13263,6 +13080,7 @@ u3kla
ukle1i
u3klo
u3klö
+u3ko
u5kö
u1k4r
uk2ta
@@ -13274,7 +13092,6 @@ u1l
ul1ab
ul1am
ul2ar
-ula2s
ul1äm
ulb4
uld2se
@@ -13283,10 +13100,9 @@ ule4n
ul1erf
ul1erh
ul1erw
-ules1a
+ules3a
ule2t
ul3eta
-ul3fe
ulg4
uli2k
uli5ne
@@ -13294,17 +13110,17 @@ ul1ins
ul3ka
ul2kn
ull2a
+ul3len
ul2les
-ull1s
+ul2lö
ulm3ein
ulo2i
ul1or
ulö3s
ul2p1h
-ul2sa
-ul2sei
+ul2s1a
ul3sp
-ulsu3
+uls2t
uls3z
ul4tar
ul2tau
@@ -13313,10 +13129,9 @@ ul2tri
u2lü
ulz2
ul3zw
-u2m3a2k
+u2m1a2k
um1all
um2an
-uman4s
um1anz
um1ar
um1aus
@@ -13343,10 +13158,9 @@ um2pl
ump3le
1umr
1umsat
-um4ser
+um2ser
um2sim
um2s1pe
-um1st
um2su
umt2
um3th
@@ -13395,14 +13209,14 @@ un1gl
un2g1r
ung3ra
ung3ri
-ung4s3
+ung6s1
u3ni
un1ide
1u4nif
un1in
un1ir
2unis
-un5isl
+un3isl
1u4niv
un2k1a
un2kn
@@ -13415,7 +13229,6 @@ unk4t3r
un2n3a2d
un5n4e
un3no
-unn3s
un1o
uno4r
un2os
@@ -13423,11 +13236,10 @@ un2os
uns2
2uns.
unsch5el
-un5se
+un3se
1unsi
un3sk
un3sp
-un2stu
1unt
un3ta
unte2
@@ -13456,13 +13268,12 @@ up2pr
u1pr
up1ru
up1sl
-up4t3a2
+upt3a2
upt3erg
upt1o
-up4tr
u1pu
u1q
-4ur.
+2ur.
u1ra
u3ra.
u3raba
@@ -13489,9 +13300,8 @@ urb2
ur3ba
ur2ble
urch1
-urch3s
-urd2
-ur3di
+urch5s
+ur3d2i
2ure
ur1eff
ure3g
@@ -13505,8 +13315,6 @@ ur1erw
urg2a
ur2gri
urgros4
-urgs2
-urg3st
u1r2i
uri2c
u2r3im
@@ -13515,49 +13323,42 @@ ur1ini
ur3ins
ur1int
ur3inv
-urk2s
1urlau
-urm2a
-urm3ang
2u1ro
-uro3st
+uro5st
u1rö
2urr
-ur3sac
ur2san
-urs1au
-ur6sei
-ur4ser
-ur6sin
-ur2st
+urs3au
+ur2sei
+ur2ser
+ur4sin
ur5st4r
-ur4sw
-urt2
-ur5t4e
+ur6sw
+urt4
+ur5te
ur3th
u1ru
-urü2
ur2za
ur2zä
ur2zi
ur2zo
ur2z1w
u4saf
-us1an
us4ann
-u2s1au
+u2sau
u6schent
usch5wer
us1ec
u2s1ei
u3seid
-u5sep
+u7sep
use1ra
u2serp
us4et
usi3er.
usi5ers.
-u3sik
+us3li
us3oc
u3soh
u3sol
@@ -13571,55 +13372,70 @@ u3spek
us1pic
u5s2piz
us2por
-us4sei
+us2sac
+us6sat
+us2sei
+us3sel
usse4n
uss5erfa
uss3erk
-uss5ersu
-us4sez
-us2sof
+us5sers
+us2sez
+us2sir
uss3tät
-ust1a2b
-u3stal
-u3stel
-us1tr
-us4tris
-u3stu
-u4stun
-u4stur
+us2sü
+u4st1a2b
+u5stal
+us2tat
+u5stä
+u5ste
+us2ten
+us2ter
+us2th
+u5stis
+u5stop
+us1tor
+u4strä
+u5s4trop
+u5stu
+u6s1tur
+u5stüc
us2ur
u2sü
u1sy
-u1ß
-ußen3
+u4sz
+uß3et
+u2ß1u
2u1t
u3taf
ut1alt
ut1a4m
+u2tanz
u2t1ap
u2t3ar
ut1är
u3tät
-u3te
-u5te.
-u4t1e4g
+u3te.
+u2t1e4g
ute2l
ut2em
ute2n1
+u3ten.
uten3e
-u4tent
+u2tent
+u5ter.
ute5r4er
-u5tern
-ut3ersa
-u5tet
-u4tev
+u4t3ersa
+u3tet
+u2tev
u4t1ex
u2t1hi
u2t1ho
u2t1hu
uti2q
+u3to.
uto4ber
-uto5c
+uto3c
uto3n4
ut1opf
u2tops
@@ -13630,7 +13446,6 @@ ut3rü
ut5sa
ut2s1ä
ut4schl
-ut6schö
ut3sp
ut4spa
ut3te
@@ -13652,50 +13467,46 @@ u1x2
ux3t
u1ya
u1z
-uze2
+uze4
uz3ot
uz1we
uz3z4
1üb
2übd
-übe2
-übe3c
-übe4r1
+übe4
+über1
ü2b5l
-3üb5r
-üb2st
+3üb3r
3übu
2üc
ü1che
üch3l
-üch4s3c
+üch4s1c
üch5t4e
ück1er
-ück5e4ri
-ü4ckers
-ück4spe
+ück3e4ri
ü4d3a4
+üdau5
ü3den.
üden4g
ü3d2ens
üd1o4
-üd1ö
+üd1ö4
ü4d5r
-üd3s2
+üd3s
üdsa1
üd1t4
-ü2f3a
+ü4f3a
ü2f1ei
ü2f1erg
üf2fl
ü2f1i
üf3l
+üf3te
ü1g
-ü3ge
ü2g3l
ü2gn
üg3s
-üg4st
üh1a
ü1he
ü2h1ei
@@ -13703,7 +13514,6 @@ uz3z4
ü2h1erk
ü2h1erz
üh1i
-ühla2
ühl1ac
ühl1ag
üh5l2e
@@ -13716,12 +13526,13 @@ uz3z4
ühr5ei.
üh5ro
ühr5ta
-üh1s
-üh3s2p
-üh5te
+ühs2
+üh3sp
+üh3stu
+üh3te
ü1hu
üh1w
-ü1k
+ü1k2
2ül
ül1a
ül2c
@@ -13732,25 +13543,17 @@ uz3z4
ül4lö
ü1lu
ü4ment
-2ün
ü2n1a
ün2c
ün2da
ün2dr
-ünd1s
ün2f1
ün4f3ei
ün3fl
ün4fli
-ünf3r
+ünf5r
ün2g3l
-ünn4s
-ün2s
-ün3sc
-ün3sp
-ün4st
-ün5sta
-ün5str
+üng5s
ün3th
ün2za
ü1pe
@@ -13762,34 +13565,37 @@ uz3z4
ür4f3r
ür4g5eng
ü1ri
-ü1r2o
+ü1r2o1
üro3b
ü3rofe
-üro1r
-üro3st
-ürr2
-ür2s
-ürs3tin
+ür4ster
+ür5sti
ürt2h
ür3the
ü1ru
+üs2a
ü2schl
üse3h
üse3l
-üs4s3c
-üs5se
-üs2st
-ü2st
+üs4sa
+üs4s1c
+üs3se
+üs4st
+ü4sta
üste3ne
+ü4str
ü1ß
ü1ta
ü2t1al
+ü1te
+ü1ti
üt3r
üt2s1
üt2tr
+ü1tu
ü1v
ü1z
-2v.
+4v.
3va.
2v1ab
va3c
@@ -13797,22 +13603,21 @@ va3ge
val2s
2vang
2v1arb
-va3st
v4at
va2t3a6
-va4tei
va2t3h
va4t1in
vati8ons.
va2t3r
-vat3s2
+vat5s4
vat3t
va2t1u
+vat3z
2v1au
+vä1
2v1b
2v1d
ve2
-3vea
ve3ar
ve3b
ve3c
@@ -13820,8 +13625,7 @@ ve3d
ve3g
ve3h
veit4
-veits3
-vek3
+veits1
ve3la
ve4l1au
ve3le
@@ -13852,11 +13656,12 @@ verg4
ve3ri
ve5ris
ve5rit
-ver3st
+ver5sta
+ve3s
2vesc
-2ve3se
-ves1p
-ves3ti
+2vese
+ve4s1p
+ves2t
ve3ta
vete1
vete3r
@@ -13873,7 +13678,6 @@ vi3an
vi4a3t
vi4c
vi3de
-vid3s2t
vie2h3a
vi2el
vi2er
@@ -13883,6 +13687,7 @@ vi3ka
vi2l1a
vi2leh
vi2l1in
+vil3l
2v1i2m
vi4na
vin2s
@@ -13890,8 +13695,8 @@ vin2s
3vio
vi3sa
vise4
-vi5s2o
-vi3s2u
+vi3s2o
+vis2u
vize5
2v1k
2v1l2
@@ -13899,9 +13704,9 @@ vize5
2v1n
2v1ob
vo2gu
-voll1a
-voll5end
-von3
+vol6l5end
+vol6lerw
+vol2li
2v1op
vo2r1
vor3a
@@ -13910,15 +13715,14 @@ vor3g
vo3ri
vo5rig
vor3o
+vorö4
3voy
-vö2c
2v1p
v3pf
v1ra
3vri
v1ro
-2vs
-vs2e
+2v1s
v3s2z
2v1t
2vumf
@@ -13928,11 +13732,10 @@ v3s2z
4w.
w2a
wab2bl
-wa5che
wa3d
waffe2
1wag
-wa5ge
+wa3ge
wa2g5n
wa2gr
wa3gra
@@ -13943,58 +13746,49 @@ wai2b
1wal
3wald
wal4da
+wal2to
walt4st
-wa5na
-wang6s
-wan4s
wa2p
-wa2r
-wa3ra
-1war2e
+wa4r
+wa5ra
+1wa3r2e
ware1i
-wa3ri
-war3ste
+wa5ri
wart4e
-wa3ru
+wa5ru
1wa2s
wa3sa
-wa3se
wa3sh
wa3si
-wass4
-was7se
+was5s4
1wäh
1wäl
+wäm3
1wäs
-wäs4c
+wäs2c
wä5sche
-wäs5se
w1b
2w1c
w1d
weat3
we3be
4webeb
-we3cke
-we5cke.
-we5cken.
-we5ckes
we3d
we2e2
weed1
we2fl
3weg
-we2g1a
+we2g5a
we2g5l
we4g3r
-wegs4
+wegs2
weg3sp
1weh
we3he
wei4bl
2weie
weis4s3p
-wei3str
+wei5str
wei3ße
wei4tr
weit3s
@@ -14021,39 +13815,43 @@ we4r1io
1werke
wer2kl
wer2ku
-wer2s
-wer2t3a
+wer4sta
+wer2ta
wer4tei
wer6t5erm
wer4to
1werts
-1we3se
+1we5se
+wesen4s3
we3si
we2s1p
-we4st
-west1a
-west3ei
-wes2t1o2
-west3r
-wes4tu
-wet4s
-wet4ta
+wes2t
+we4st1a
+we4st3ei
+we5sten.
+we5stens
+we6steu
+we6sti
+we4st1o2
+we4stö
+we4st3r
+we4stu
+wet2s
wett3s
2w1g
-w5ho
-wi3cka
+w3ho
3wid
wi2e
wie3l
wie5ne
-wie2st
+wie4st
wi3k2
-wim2ma
wim4m3u
-win4d3e4c
+win4d3ec
win2dr
win2e
win8n7ersc
+win4num
wi4r
1wirt
wi5s4e
@@ -14064,6 +13862,7 @@ wi3th
2wk
2w1l
2w1m
+2wn
wn3sh
1wo1c
wo2cha
@@ -14072,6 +13871,7 @@ woche4
woh4l
1wolf
wolf4s
+wol4la
wol4ler
wor3a
wo2r3i
@@ -14085,30 +13885,25 @@ wör3the
1wr
w1ro
2ws
-w3s4k
-w1s2t
+w3s2k
2w1t
-w3ti2
+wti2
w2u
1wuc
-wul2
-wul3se
+wuls2
wun2s
4wur.
wur2fa
-wur4s
1wurst
-wus2
-wus3te
-1wu4t1
+wus4
+1wu2t1
1wüh
-wül2
-wün3
+wüs4
2w1w
6x.
x1a
1xa.
-2x3ab
+2xab
1xad
1xae
xa1fl
@@ -14117,7 +13912,6 @@ xa4m
xa3me
xa5mer
2xan
-x4anz
3xas
2x1b
x1c
@@ -14131,7 +13925,7 @@ x1em
7x2em.
xemp6
3x2en
-xens4
+xens2
xen3sa
x2er.
5xere
@@ -14140,7 +13934,6 @@ xers2
2x3eu
2x1f
2x1g
-xge1
2x3h
1xi
xib4
@@ -14154,18 +13947,18 @@ xie3l
xi3g4
xi2lo
xi2l1u
+xins2
xin3sk
-x2i2s1
-xi3sc
-xi4se
-xiso2
-xis3s
-xis2tä
+x2is
+xi2s1e
+xi2s1o2
+xis5s
+xi5stä
+xi2su
x1i2tu
x1j
x1k4
2x3l
-xlib6
x1m
2x1n
x1or
@@ -14176,13 +13969,13 @@ x1r
4x1t
x2t1a
xt3an
-xt4as
+x3t4as
x2t1ä
x3tät
-xtblo4
x2t1e2d
x2t1ei
-x4tent
+x3teil
+x2tent
x2t1erf
xtra1b6
x2t3ran
@@ -14192,7 +13985,7 @@ x3tur
1xu
xu1a
x1u4n
-xu2s1
+xu2s
x1v
2x1w
1xy.
@@ -14205,7 +13998,6 @@ y1a2m
yan2g
y3ät
y1b
-yb6r
y1c
y2chi
y3chis
@@ -14215,9 +14007,9 @@ y3d4r
y1e
y2ef
yen4n
-y2es
+y2es2
ye3sp
-y3est
+y3e4st
ye2th
y1f
y1g
@@ -14231,17 +14023,15 @@ yk5s
y1l
yl3a2m
y3lant.
-y3lante
+y3l4ante
yl3c
y5len
y5ler
yli4n
yloni1
-yls2
-yl1st
y2l1u
-yma4t
-ym3p4
+yma2t
+ym3p2
ympi3e
y2ne
y2n3o
@@ -14253,7 +14043,7 @@ y1ont
y3ou
y1p
ypa2
-yp3an
+yp5an
ype2
yper3t
y3ph
@@ -14265,16 +14055,19 @@ y1r
y3r2e
y3ri
yri1e
-y5s4c
-y1sé
-ys2h
-y3s2p
-y2st4
-ys1tr
-y3s2ty
-y3s2z
+y3ro
+y1s2
+y5sc
+y3sh
+ys3k
+y3sp
+ys3s
+yst4
+y3sty
+y3sz
y1t
y2t2h
+yto5s
yu2r
yure3
y1v
@@ -14283,46 +14076,47 @@ y1y
y1z2
6z.
2z3a2b
-za1c
+za1cha
+za1chä
z3a2d
za3de
2z1af
za3gr
3z2ah
2z3a2k
+za3li
2z1all
2z1am
z3ambik
3zambiq
z1an
-za2na
2z3anf
3zani
-z3anl
3zar.
2z1arb
3za3re
z1arm
-3zaro
-za3st4
+3za3ro
+za5st4
2z3at
3zaub
z1au2f
z3aug
3zaun
+za3v
zä2
2z1äc
3z2äh
2z1äm
+zäng5
z1ärg
z1ärm
-4z3b6
+4z3b4
zbü1b
zbübe5
4z3c
2z3d
zdä1
-zdi1st
1ze
ze3a
2zeck
@@ -14331,8 +14125,8 @@ ze1e
zei3la
zeile4
2z1ein
-zei3s2
-zei5sp
+zei5s2
+zei3sk
zeist4
zeit1a
zei4tak
@@ -14344,15 +14138,19 @@ ze4l1a2
zel3ad
zel1er
zel1in
-zel5la
+zel5l4a
+zel5lä
+zel4leh
+zel4lin
+zel3spr
zel3sz
zel3th
zelu2
ze5m4e
2z1emp
5zen.
-ze4n1ac
-zen5s2e
+ze6n1ac
+zen3s2e
zen2ta
5zentr
zent3sk
@@ -14386,12 +14184,13 @@ zer6t5rau
3zerza
z1erzi
ze2sä
+ze5sc
ze2s1i
ze3sku
-ze2sp
-zes6s5end
-ze2st
-zes3tr
+ze2s3p
+zes4ser
+zes1tr
+ze2ß1
ze2tr
2z1ex
2z3f
@@ -14399,18 +14198,19 @@ ze2tr
zger2a
2z1h
z2hen
-zhir5
-zi3alo
+3zi.
zid5r
zi1erh
zi1es.
-zig4s
+3z2ig
zil2e
+zil3l
+z2imm
2zimp
3zine
zin4er
2z1inf
-2z1inh
+z1inh
zin4ser
4zinsuf
2z1inv
@@ -14419,7 +14219,7 @@ zi3op
zirk4
zirk6s
zi3s2z
-zi1t2h
+zit2h
2z1j
2z3k4
zkü1b
@@ -14427,7 +14227,6 @@ zkü1b
z3la
2z1m
2z3n2
-znei3
2zob
2zof
z1oh
@@ -14451,21 +14250,19 @@ zö7li
z2t1au
z3te
z4tehe
-zte3ma
zte3o
-zte3str
+zte5str
z2t1h
z4t3hei
z3t2her
zt3ho
-z3ti
zt1ins
zt3rec
-zt3s
+zt3s2
zu1
zu3a
zub4
-zu5cke
+zu2c
zud4
zu3f4
zu2g1ar
@@ -14488,7 +14285,7 @@ zu3r2a
2z1url
2zurs
2z1urt
-zu3s4
+zu3s2
zu3t
zuz2
2züb
@@ -14512,9 +14309,8 @@ z2wit
z1wur
2z1wü
zy1ank
-4z1z
+6z1z
z3z4a
z3zi
-zzi3s2
z3zo
-zzoll2} \ No newline at end of file
+zzoll2}
diff --git a/tex/context/patterns/lang-deo.rme b/tex/context/patterns/lang-deo.rme
index 8bfa03fdb..3997cda14 100644
--- a/tex/context/patterns/lang-deo.rme
+++ b/tex/context/patterns/lang-deo.rme
@@ -1,13 +1,13 @@
% generated by mtxrun --script pattern --convert
-% dehyphn-x-2008-06-18.pat
+% dehypht-x-2008-06-18.pat
-\message{German Hyphenation Patterns (Reformed Orthography, 2006) `dehyphn-x' 2008-06-18 (WL)}
+\message{German Hyphenation Patterns (Traditional Orthography) `dehypht-x' 2008-06-18 (WL)}
-% TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung
+% TeX-Trennmuster für die traditionelle deutsche Rechtschreibung
%
%
-% Copyright (C) 2007, 2008 Werner Lemberg <wl@gnu.org>
+% Copyright (C) 2008 Werner Lemberg <wl@gnu.org>
%
% This program can be redistributed and/or modified under the terms
% of the LaTeX Project Public License Distributed from CTAN
diff --git a/tex/context/patterns/lang-uk.hyp b/tex/context/patterns/lang-uk.hyp
new file mode 100644
index 000000000..faa79bb74
--- /dev/null
+++ b/tex/context/patterns/lang-uk.hyp
@@ -0,0 +1,8 @@
+% generated by mtxrun --script pattern --convert
+
+% for comment and copyright, see e:/tmp/patterns/lang-uk.rme
+
+% used:
+
+\hyphenation{
+} \ No newline at end of file
diff --git a/tex/context/patterns/lang-uk.pat b/tex/context/patterns/lang-uk.pat
new file mode 100644
index 000000000..2a876540e
--- /dev/null
+++ b/tex/context/patterns/lang-uk.pat
@@ -0,0 +1,1905 @@
+% generated by mtxrun --script pattern --convert
+
+% for comment and copyright, see e:/tmp/patterns/lang-uk.rme
+
+% used: а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ь ю я є і ї ґ
+
+\patterns{
+2а1
+а3а
+а3е
+а3і
+а3о
+а3у
+а3ю
+а3я
+а3є
+а3ї
+2е1
+е3а
+е3е
+е3і
+е3о
+е3у
+е3ю
+е3я
+е3є
+е3ї
+2и1
+и3а
+и3е
+и3і
+и3о
+и3у
+и3ю
+и3я
+и3є
+и3ї
+2і1
+і3а
+і3е
+і3и
+і3о
+і3у
+і3ю
+і3я
+і3є
+і3ї
+2о1
+о3а
+о3е
+о3і
+о3о
+о3у
+о3ю
+о3я
+о3є
+о3ї
+2у1
+у3а
+у3е
+у3і
+у3о
+у3у
+у3ю
+у3я
+у3є
+у3ї
+2ю1
+ю3а
+ю3е
+ю3і
+ю3о
+ю3у
+ю3ю
+ю3я
+ю3є
+ю3ї
+2я1
+я3а
+я3е
+я3о
+я3у
+я3ю
+я3я
+я3є
+я3ї
+2є1
+є3у
+є3ю
+є3є
+є3ї
+2ї1
+ї3е
+ї3о
+ї3ю
+2б1к
+2б1п
+2б1с
+2б1т
+2б1ф
+2б1х
+2б1ц
+2б1ч
+2б1ш
+2б1щ
+2в1б
+2в1г
+2в1д
+2в1ж
+2в1з
+2в1к
+2в1л
+2в1м
+2в1н
+2в1п
+2в1р
+2в1с
+2в1т
+2в1ф
+2в1х
+2в1ц
+2в1ч
+2в1ш
+2в1щ
+2в1й
+2г1к
+2г1п
+2г1с
+2г1т
+2г1ф
+2г1ц
+2г1ч
+2г1ш
+2д1к
+2д1п
+2д1с
+2д1т
+2д1ф
+2д1х
+2д1ц
+2д1ч
+2д1ш
+2д1щ
+2ж1к
+2ж1п
+2ж1с
+2ж1т
+2ж1ф
+2ж1х
+2ж1ц
+2ж1ч
+2ж1ш
+2з1к
+2з1п
+2з1с
+2з1т
+2з1ф
+2з1х
+2з1ц
+2з1ч
+2з1ш
+2з1щ
+2к1б
+2к1г
+2к1д
+2к1з
+2л1б
+2л1в
+2л1г
+2л1ґ
+2л1д
+2л1ж
+2л1з
+2л1к
+2л1м
+2л1н
+2л1п
+2л1р
+2л1с
+2л1т
+2л1ф
+2л1х
+2л1ц
+2л1ч
+2м1б
+2м1в
+2м1г
+2м1д
+2м1ж
+2м1з
+2м1к
+2м1л
+2м1н
+2м1п
+2м1р
+2м1с
+2м1т
+2м1ф
+2м1х
+2м1ц
+2м1ч
+2м1ш
+2м1щ
+2н1б
+2н1в
+2н1г
+2н1д
+2н1ж
+2н1з
+2н1к
+2н1л
+2н1м
+2н1п
+2н1р
+2н1с
+2н1т
+2н1ф
+2н1х
+2н1ц
+2н1ч
+2н1ш
+2н1щ
+2п1б
+2п1д
+2п1з
+2р1б
+2р1в
+2р1г
+2р1ґ
+2р1д
+2р1ж
+2р1з
+2р1к
+2р1л
+2р1м
+2р1н
+2р1п
+2р1с
+2р1т
+2р1ф
+2р1х
+2р1ц
+2р1ч
+2р1ш
+2р1щ
+2р1й
+2с1б
+2с1г
+2с1д
+2т1б
+2т1г
+2т1д
+2т1ж
+2т1з
+2ф1б
+2ф1г
+2ф1з
+2х1г
+2х1д
+2ц1б
+2ц1г
+2ц1д
+2ц1з
+2ч1б
+2ч1д
+2ч1ж
+2ш1б
+2ш1г
+2й1б
+2й1в
+2й1г
+2й1д
+2й1ж
+2й1з
+2й1к
+2й1л
+2й1м
+2й1н
+2й1п
+2й1р
+2й1с
+2й1т
+2й1ф
+2й1х
+2й1ц
+2й1ч
+2й1ш
+2й1щ
+2дь1к
+2дь1с
+2дь1т
+2дь1ц
+2зь1к
+2зь1с
+2зь1т
+2ль1б
+2ль1в
+2ль1г
+2ль1д
+2ль1ж
+2ль1з
+2ль1к
+2ль1м
+2ль1н
+2ль1п
+2ль1р
+2ль1с
+2ль1т
+2ль1ф
+2ль1х
+2ль1ц
+2ль1ч
+2ль1ш
+2ль1щ
+2ль1й
+2нь1б
+2нь1г
+2нь1з
+2нь1к
+2нь1л
+2нь1м
+2нь1с
+2нь1т
+2нь1х
+2нь1ц
+2нь1ч
+2нь1ш
+2нь1й
+2рь1к
+2рь1ц
+2сь1б
+2сь1д
+2ть1б
+2к1сп
+2к1ст
+2к1ськ
+2п1сп
+2п1ст
+2п1ськ
+2с1пк
+2с1пп
+2с1пс
+2с1пт
+2с1пх
+2с1пч
+2с1ськ
+2с1тк
+2с1тп
+2с1тс
+2с1тсь
+2с1тт
+2с1тф
+2с1тц
+2с1шт
+2сь1кк
+2сь1кс
+2сь1кт
+2т1ск
+2т1сп
+2т1ст
+2т1ськ
+2т1шк
+2ф1сп
+2ф1ст
+2ф1ськ
+2ф1шт
+2х1ст
+2х1ськ
+2ц1ст
+2ц1шк
+2ш1тк
+2ш1тсь
+2б1б
+2в1в
+2г1г
+2ґ1ґ
+2д1д
+2ж1ж
+2з1з
+2к1к
+2л1л
+2м1м
+2н1н
+2п1п
+2р1р
+2с1с
+2т1т
+2ф1ф
+2х1х
+2ц1ц
+2ч1ч
+2ш1ш
+2щ1щ
+2й1й
+3ння
+3ття
+3ттю
+3лля
+3ллє
+3ллю
+3ддя
+д4ж
+д4з
+а2й
+е2й
+и2й
+і2й
+о2й
+у2й
+ю2й
+я2й
+є2й
+ї2й
+3й6о
+ь6о
+6ь
+.бд6
+.бр6
+.вб6
+.вг6
+.вд6
+.вж6
+.вз6
+.вз6д6
+.вк6
+.вл6
+.вм6
+.вп6
+.вп6х6
+.вс6
+.вс6т6
+.вт6
+.вш6к6
+.дж6
+.дз6
+.дл6
+.дс6
+.зб6
+.зг6
+.зд6
+.зд6з6
+.зл6
+.зс6
+.зс6к6
+.зс6т6
+.зч6
+.зш6
+.зш6к6
+.зґ6
+.йш6
+.кл6
+.кп6
+.кс6
+.кх6
+.кш6
+.лк6с6
+.лс6
+.ль6
+.мс6
+.мф6
+.нб6
+.пр6
+.пс6
+.пх6
+.рт6
+.ск6
+.ск6л6
+.сл6
+.сп6
+.сп6л6
+.сп6х6
+.ст6
+.сх6
+.сх6л6
+.тк6
+.тр6
+.тх6
+.ть6
+.фл6
+.хл6
+.ць6
+.чх6
+.шк6
+.шл6
+.шп6
+.шт6
+6бв.
+6бз.
+6бй.
+6бл.
+6б6ль.
+6бн.
+6бр.
+6бс.
+6б6ст.
+6б6с6тв.
+6б6с6тр.
+6б6с6ьк.
+6б6ць.
+6вб.
+6вв.
+6вд.
+6в6др.
+6в6дь.
+6вж.
+6вз.
+6в6зь.
+6вй.
+6вк.
+6вл.
+6в6ль.
+6вм.
+6вн.
+6вп.
+6вр.
+6вс.
+6в6с6тв.
+6в6с6ть.
+6в6сь.
+6в6с6ьк.
+6вт.
+6вх.
+6в6ць.
+6вч.
+6вш.
+6вщ.
+6гв.
+6гг.
+6гд.
+6гл.
+6г6ль.
+6гм.
+6гн.
+6гр.
+6гс.
+6г6с6тв.
+6г6сь.
+6гт.
+6дж.
+6дз.
+6д6зь.
+6дл.
+6дм.
+6дн.
+6др.
+6д6с6тв.
+6д6с6ьк.
+6дт.
+6дь.
+6д6ь6сь.
+6жб.
+6жв.
+6ж6дь.
+6ж6сь.
+6зв.
+6зг.
+6зд.
+6з6дв.
+6з6дн.
+6з6дь.
+6зк.
+6зл.
+6зм.
+6зн.
+6з6нь.
+6зр.
+6з6сь.
+6зь.
+6з6ьб.
+6з6ьк.
+6йб.
+6йв.
+6йг.
+6йд.
+6йз.
+6йк.
+6й6кл.
+6йл.
+6й6ль.
+6йм.
+6й6мс.
+6йн.
+6й6нс.
+6йп.
+6йр.
+6йс.
+6й6ст.
+6й6с6тв.
+6й6с6тр.
+6й6сь.
+6й6с6ьк.
+6йт.
+6й6тс.
+6йф.
+6йх.
+6йц.
+6йч.
+6йш.
+6кв.
+6кк.
+6кл.
+6к6ль.
+6кр.
+6кс.
+6к6ст.
+6к6сь.
+6кт.
+6к6тр.
+6кх.
+6кш.
+6лб.
+6лг.
+6лд.
+6лк.
+6лл.
+6л6ль.
+6лм.
+6л6мс.
+6лн.
+6лп.
+6лс.
+6лт.
+6л6хв.
+6ль.
+6л6ьб.
+6л6ьв.
+6л6ьг.
+6л6ьд.
+6л6ь6дс.
+6л6ьз.
+6л6ьк.
+6л6ьм.
+6л6ьн.
+6л6ьп.
+6л6ьс.
+6л6ь6ств.
+6л6ь6сь.
+6л6ь6ськ.
+6л6ьт.
+6л6ь6тр.
+6л6ьф.
+6л6ьх.
+6л6ьц.
+6л6ьч.
+6л6ьш.
+6л6ьщ.
+6мб.
+6м6б6ль.
+6м6бр.
+6мг.
+6мж.
+6мк.
+6мл.
+6м6ль.
+6мм.
+6мн.
+6мп.
+6мр.
+6мс.
+6м6с6тв.
+6м6сь.
+6м6с6ьк.
+6мт.
+6мф.
+6мх.
+6мш.
+6нв.
+6нг.
+6н6гл.
+6н6г6ль.
+6н6гр.
+6н6гс.
+6нд.
+6н6дж.
+6н6дз.
+6н6дп.
+6н6др.
+6нж.
+6нз.
+6нк.
+6н6кс.
+6н6кт.
+6нм.
+6нн.
+6нр.
+6нс.
+6н6ск.
+6н6ст.
+6н6с6тв.
+6н6с6тр.
+6н6с6ьк.
+6н6с6ькй.
+6нт.
+6н6тк.
+6н6тр.
+6н6т6ств.
+6н6ть.
+6нф.
+6нх.
+6нц.
+6н6ць.
+6нч.
+6нш.
+6нь.
+6н6ьб.
+6н6ьг.
+6н6ьк.
+6н6ь6сь.
+6пд.
+6пл.
+6пр.
+6пс.
+6п6с6тв.
+6п6сь.
+6пт.
+6п6тр.
+6пф.
+6пц.
+6рб.
+6рв.
+6рг.
+6рд.
+6р6дв.
+6р6дж.
+6р6дь.
+6рж.
+6рз.
+6р6зн.
+6р6зь.
+6рк.
+6р6кс.
+6р6кт.
+6рл.
+6р6ль.
+6р6л6ьз.
+6рм.
+6рн.
+6р6нс.
+6р6н6ст.
+6р6нь.
+6рп.
+6рр.
+6рс.
+6р6ср.
+6р6ст.
+6р6с6тв.
+6р6с6ть.
+6р6сь.
+6р6с6ьк.
+6рт.
+6р6тв.
+6р6тр.
+6р6ть.
+6рф.
+6рх.
+6рц.
+6р6ць.
+6рч.
+6рш.
+6рщ.
+6р6щ6сь.
+6рь.
+6с6дп.
+6с6д6рп.
+6ск.
+6сл.
+6с6ль.
+6см.
+6сн.
+6сп.
+6сс.
+6ст.
+6с6тв.
+6с6тй.
+6с6тм.
+6с6тр.
+6с6т6рь.
+6с6ть.
+6с6ць.
+6сь.
+6с6ьб.
+6с6ьк.
+6с6ьм.
+6тв.
+6т6вт.
+6т6зт.
+6тл.
+6т6ль.
+6тм.
+6т6мр.
+6тр.
+6тс.
+6т6с6тв.
+6т6с6ьк.
+6тт.
+6тц.
+6тч.
+6ть.
+6т6ь6сь.
+6фм.
+6фр.
+6ф6с6тв.
+6фт.
+6ф6ть.
+6фф.
+6фь.
+6хв.
+6хм.
+6хн.
+6хр.
+6хт.
+6хш.
+6ц6тв.
+6ць.
+6ц6ьк.
+6чб.
+6чм.
+6чн.
+6чт.
+6шв.
+6ш6ль.
+6шм.
+6шн.
+6ш6нл.
+6ш6сь.
+6шт.
+6ш6тв.
+6щ6сь.
+.бе4з3
+.безу4
+.бе5з4о3д
+.без5о4соб
+.безві4д3
+.без3ро4з3
+виї4
+.ві5д4ом
+.ві5д4озв
+.ві5д4ун
+віду4ч
+.ві5д4а
+.ві5д4ер
+.ві5д4і
+.ві4д3
+.мі4ж3
+безві4д3
+ові4д3
+ді4єві4д3
+за4вві4д3
+неві4д3
+про4ф3ві4д3
+спе4ц3ві4д3
+співві4д3
+те4х3ві4д3
+.пере4д3бач
+.пере4д3виб
+.пере4д3г
+.пере4д3д
+.пере4д3м
+.пере4д3ост
+.пере4д3пла
+.пере4д3пок
+.пере4д3р
+.пере4д3св
+.пере4д3умов
+.пере4д3усі
+.пере4д3фр
+.пере4д3ч
+.пере3
+.пона4д3
+.пона5д4і
+.пона5д4и
+.пона5д4я
+3п4ре
+3п4ри
+приї4
+3п4ро
+3п4рі
+.пі5д4о
+.пі5д4і
+.пі4д3
+.пі5д4е
+.пі5д4и
+.пі5д4у
+.пі4в3
+.спі4в3
+.напі4в3
+.ро5з4і
+.ро5з4е
+ро5з4йом
+.ро5з4а
+.ро4з3
+.чере4з3
+оо4б
+ооб3м
+ооб3ро
+за5о4р
+до5о4р
+по5о4р
+пере5о4р
+пі6д5о4р
+бе4з5і4дей
+за3ю4ш
+за3я4ло
+коу4роч
+зу4роч
+наду4роч
+позау4роч
+поу4роч
+приу4роч
+на4й3у4бог
+нао4р
+прио4р
+неу4к
+3в4б4лаг
+3в4к4лад
+3в4п4лив
+3в4п4равн
+3в4р4одлив
+3в4т4рут
+3в4т4руч
+3з4б4рой
+3з4б4рою
+3з4б4роє
+3й4ш4л
+3м4к4не
+3м4к4ну
+3м4к4ні
+3п4с4ков
+3с4к4лад
+3с4к4ле
+3с4к4лит
+3с4к4ло
+3с4к4рипт
+3с4п4лав
+3с4п4лат
+3с4п4лач
+3с4п4рав
+3с4п4ритн
+3с4п4рият
+3с4п4ромо
+3с4т4вор
+3с4т4ражд
+3с4т4рах
+3с4т4риб
+3с4т4риж
+3с4т4рой
+3с4т4рок
+3с4т4ром
+3с4т4роф
+3с4т4роч
+3с4т4рою
+3с4т4роя
+3с4т4роє
+3с4т4рої
+3с4т4рукт
+3с4т4рукц
+3с4т4рій
+3с4т4ріл
+3с4т4річ
+3т4к4нен
+3т4ь4мар
+3т4ь4мяні
+3у4п4рав
+3блаж
+3ближ
+3близ
+3блиск
+3блок
+3блоці
+3бран
+3брати
+3брест
+3бризк
+3британ
+3бруд
+3в4бив
+3в4веден
+3в4дал
+3в4довз
+3в4довол
+3в4живан
+3в4лад
+3в4ласн
+3в4лашт
+3в4лов
+3в4певн
+3в4поряд
+3в4разлив
+3в4рожай
+3в4сюд
+3в4тіл
+3глад
+3глиб
+3глин
+3глоб
+3глуз
+3глуш
+3гляд
+3глян
+3гнан
+3гнил
+3гноз
+3гнучк
+3грав
+3град
+3грай
+3грам
+3гран
+3грати
+3граф
+3граш
+3граю
+3грає
+3грес
+3грець
+3гроб
+3грож
+3гроз
+3громад
+3груван
+3грунт
+3груп
+3грів
+3гріт
+3гріш
+3г4ідро
+3д4ан
+3д4бав
+3д4бал
+3д4бан
+3д4бат
+3д4бає
+3двиг
+3двою
+3двоє
+3двій
+3двір
+3двічі
+3драж
+3дром
+3друж
+3друк
+3дряп
+3дріб
+3дріма
+3жвав
+3жміть
+3жріть
+3з4бага
+3з4баланс
+3з4був
+3з4бут
+3зваж
+3зван
+3звед
+3звел
+3звест
+3звись
+3звич
+3звищ
+3зворуш
+3звук
+3звуч
+3звіт
+3з4год
+3з4дат
+3з4довж
+3з4доров
+3з4дійсн
+3змін
+3зйом
+3зміш
+3знав
+3знай
+3знак
+3знал
+3знан
+3знат
+3знаход
+3знач
+3знаю
+3знає
+3зниж
+3знім
+3зрозум
+3зрюв
+3зрів
+3зріл
+3зрін
+3з4чеп
+3й4ма
+3й4менн
+3й4мищ
+3й4мовірн
+3й4му.
+3й4муть
+3й4міть
+3й4шов
+3м4нож
+3м4ріть
+3м4щен
+3п4сов
+3п4сон
+3п4сув
+3р4вав
+3р4вати
+3р4віть
+3с4кид
+3с4кок
+3с4коп
+3с4кор
+3с4короч
+3с4коч
+3с4кіль
+3с4кіпл
+3с4пад
+3с4пект
+3с4перм
+3с4пин
+3с4повід
+3с4пожив
+3с4постер
+3с4пі
+3с4піть
+3с4піш
+3с4табіл
+3с4тав
+3с4тад
+3с4таз
+3с4тайн
+3с4тал
+3с4тан
+3с4тар
+3с4тара
+3с4тат
+3с4тач
+3с4тає
+3с4теп
+3с4тереж
+3с4теріг
+3с4тиг
+3с4тиж
+3с4тисл
+3с4титу
+3с4товб
+3с4той
+3с4торон
+3с4торін
+3с4тосо
+3с4тосу
+3с4тою
+3с4тоян
+3с4туп
+3с4тяг
+3с4тіб
+3с4тій
+3с4тіль
+3с4тір
+3с4фер
+3с4хил
+3с4хов
+3с4хід
+3т4кан
+3х4то
+3ш4код
+3ш4кол
+3ш4кідл
+3ш4кіл
+3ш4кір
+3ш4таб
+3ш4туч
+3ґрунт
+3а4вторит
+3а4гент
+3а4грес
+3а4декват
+3а4дитив
+3а4зарт
+3а4ктив
+3а4ктуал
+3а4курат
+3а4куст
+3а4кцепт
+3а4кциз
+3а4лергі
+3а4матор
+3а4наліз
+3а4натом
+3а4парат
+3а4пеляц
+3а4постол
+3а4птеч
+3а4ргумен
+3а4ромат
+3а4соці
+3а4спект
+3а4тлет
+3а4халі
+3е4колог
+3е4коном
+3е4легант
+3е4лектр
+3е4лемент
+3е4моці
+3е4мігр
+3е4нерг
+3е4стакад
+3е4стет
+3е4тап
+3о4береж
+3о4бира
+3о4борон
+3о4бід
+3о4біц
+3о4даль
+3о4дяг
+3о4збро
+3о4крем
+3о4перат
+3о4плат
+3о4птим
+3о4пуст
+3о4пуше
+3о4пуще
+3о4рдинац
+3о4ренд
+3о4соб
+3о4сяжн
+3о4холо
+3о4хорон
+3о4хоч
+3о4чисн
+3о4чищ
+3у4ваг
+3у4важ
+3у4гав
+3у4згод
+3у4клад
+3у4компл
+3у4крупн
+3у4люблен
+3у4мит
+3у4міл
+3у4перед
+3у4разлив
+3у4рбан
+3у4рочист
+3у4ряд
+3у4рядов
+3у4спіш
+3у4станов
+3у4стпіш
+3у4сувати
+3у4твор
+3у4тробн
+3я4дерн
+3я4зик
+3я4кіс
+3я4рус
+3я4скрав
+3є4д3н
+3є4дин
+3є4писк
+3є4рей
+3і4зотоп
+3і4люстр
+3і4мовір
+3і4нтенс
+3і4нформ
+3і4ніціат
+3і4снув
+3ї4ждж
+3ї4зд
+3ї4ст
+3ї4хав
+3ї4хат
+.заї4к
+.заї4ц
+.заї4ч
+.наї4д
+аві4а
+авої4д
+ае4тил
+альбі5он
+ахої4д
+ауді4о
+ай4с3берг
+бактері4о
+ба4с3енер
+ба4с3антра
+.бе5зе.
+бей4сбол
+бе5кон
+бйор4нс
+бі4о3
+бо4г3дан
+бран4д
+брі4дж3порт
+без5і4мен
+бо4є3гол
+бо4є3гот
+бо4є3зап
+бо4є3здат
+бо4є3комп
+бо4є3пост
+бо4є3прип
+бори4с5п
+4в3антрац
+вер4х3н
+ви3й4д
+вина3й4д
+ви3й4т
+вина3й4т
+від7зна
+ві5д4ен
+ві5д4е4о
+ві5д4ом
+від5о4браж
+від5о4браз
+во4с5ко
+водо5с4ток
+водо5з4бір
+воль4т3метр
+воль4т3ампер
+ге2ть3ман
+ге4о
+го4с4п5роз
+гі4д5ро5мет
+4д7зем
+дер4ж5а4том
+дер4ж5а4дм
+дер4ж5бюдж
+дер4ж5вид
+дер4ж5дум
+дер4ж5замов
+дер4ж5ком
+дер4ж5нафт
+дер4ж5реєс
+дер4ж3без
+дер4ж3резерв
+дер4ж5стр
+дер4ж5служ
+двох4а5том
+джен4тль
+дисбаланс
+ди4с3гарм
+ди4с3квал
+ди4с3комф
+ди4с3конт
+ди4с3кред
+ди4с3крет
+ди4с3крец
+ди4с3крим
+ди4с3кусі
+ди4с3куту
+ди4с3лок
+ди4с3парит
+ди4с3перс
+ди4с3петч
+ди4с3пле
+ди4с3плей
+ди4с3пози
+ди4с3проп
+ди4с3пут
+ди4с3тил
+ди4с3триб
+ди4с3троф
+ди4с3функц
+ді3й4т
+ді3й4д
+д4ні3п4р
+.дої4в
+.дої4л
+.дої5ль
+дої4д
+дої4м
+дої4х
+дої4ж
+дої4ст
+до3з4вол
+до3з4віл
+дорого5в4каз
+еу4стр
+ео4сві
+енерго3з4береж
+енерго3з4беріг
+ек2с1к
+ек2с1п
+ек2с1т
+ек2с1ц
+єв4р3атом
+єпі4с5коп
+єпи4с5коп
+за4п3част
+заї4д
+заї4ж
+заї4з
+заї4л
+заї4м
+заї4х
+зе4кономити
+зна3й4д
+зна3й4т
+зо4ка
+зо4ке
+зо4ки
+зо4ку
+зо4кі
+игої4д
+ий4ти
+іе4тил
+і4л3е4тил
+ій4ти
+інфор4м3аген
+йо4сві
+каза4х3стан
+квої4д
+корої4д
+квар4т3плат
+киї4венер
+кон4трре
+кон4тр3арг
+жко4м5а4том
+кому4ненерг
+мі4н5е4ко
+мі4н5е4нер
+мо4к5рий
+на3б4лиз
+на3в4ряд
+на3в4ча
+на3з4в
+на4д7з4в
+наї4вс
+наї4вш
+наї4ж
+наї4з
+наї4л
+наї4м
+наї4с
+наї4х
+на4й3а
+на4й3е
+на4й3обереж
+на4й7о4бер
+на4й7о4гид
+на4й7о4гол
+на4й7о4гряд
+на4й7о4пук
+на4й7о4хай
+на4й3масл
+на4й3спри
+на4й3якіс
+на3в4чен
+на3в4чіть
+не3в4том
+не3д4бан
+на3д4бан
+не3з4вич
+не3з4важ
+нео4пал
+недої4
+неї4ст
+на5п4лив
+ні4т5рат
+оної4д
+оо4пал
+ео4пал
+обі3д4ран
+обі3й4д
+обі3й4т
+об5у4мов
+онаї4д
+оо4сві
+оо4к
+оу4стр
+оа4том
+об4лдер4ж
+об4л3а4дмін
+переї4д
+переї4ж
+переї4з
+переї4л
+переї4с
+переї4х
+пере5п4лив
+пере3й4д
+пре4й4с
+пере3й4т
+перег4ній
+перед5о4бід
+пере3в4том
+пере4д5см
+перед5у4мов
+під5о4дин
+пів5о4с4тр
+пі5в4ень
+по3б4лизу
+по3в4тор
+поч4не
+поч4ни
+поч4ну
+поя4в
+по3в4чен
+по3в4чіть
+по3д4роб
+по3д4раз
+по3д4во
+по5ж4ніть
+по5з4бав
+.пої4
+пої4д
+прої4
+пої4зд
+по4с4т5радян
+по4с4т5кому
+по4с4т3декр
+по4с4т3контра
+по4с4т3менопауз
+по4с4тприват
+по4с4т3раді
+по4с4т5соці
+пос4т3кап
+пос4т3ком
+пос4т3нат
+пос4т3проц
+пос4т3соц
+пос4т3фікс
+при3й4т
+про3с4тирад
+про4ф3с
+полі4т5екон
+пор4т3н
+пор4т3рет
+пор4т3фел
+при3й4д
+при4нцип
+про4ект3н
+про3б4лем
+про4м3май
+пр4о5плат
+раді4о
+рай3в4но
+ро4з5д4во
+ро4з5мінний
+роз5у4чен
+роз5і4мен
+роз5вант
+роз5вин
+роз5вит
+ро4з5діл
+ро4з5гор
+ро4з5вер
+ро4з5чеп
+руко5с4тиск
+ро5з4ум
+ро4з3гром
+ро4з3лив
+рмої4д
+сан4к4т3
+сеї4д
+серцеї4д
+спе4ц3кур
+спе4ц3мон
+спе4цпр
+спе4ц3с
+спор4т3вир
+спор4т3зал
+спор4т3ком
+спор4т3клуб
+спор4т3май
+спор4т4с3ме
+сор4тн
+3с4промож
+сь4квуг
+стат5упр
+тор4г3пред
+тран4с3
+тур4к3мен
+цук3ро
+у4к4р
+укр3а4вт
+укр3а4гр
+укр3е4кс
+укр3і4н4банк
+убої4д
+чорно3б4рив
+цен4т4р3енерг
+ясої4д
+ви3у4ч
+за3у4ч
+на3у4ч
+недо3у4ч
+не3у4ч
+під3у4ч
+пед3у4чи
+пере3у4ч
+само3у4ч
+вия4в
+зая4в
+ная4в
+уя4в
+во4євод
+во4єнач
+сво4єчас
+сво4єкорис
+сво4єрід
+хво4є3г4риз
+гелі4о
+ді4о
+еті4о
+мі4о
+і4он
+полі4о
+соці4о
+фізі4о
+хімі4о
+гоме4о
+ді4алог
+ді4оген
+дея4к
+оо4динок
+ао4пік
+ао4ха
+ео4ха
+зо6о
+ка5нал
+оі4зол
+міжу4соб
+мете4о
+абия4к
+нія4к
+вия4сн
+най3я4сн
+нея4сн
+поя4сн
+проя4сн
+ро5з4ора.
+ро5з4о5рам
+ро5з4орах
+ро5з4ори
+ро5з4оро
+ро5з4ору
+ро5з4оря
+ро5з4орю
+ро5з4орі
+ро6з5о4ри.
+розо4ра
+розо4ре
+розо4реш
+розо4рн
+напоу4м
+неа4би
+ео4цін
+оо4цін
+доу4к
+доу4м
+ео4бур
+ео4голош
+ео4зор
+бальне4о
+не4оліт
+не4омальт
+не4оклас
+не4окомун
+не4оландш
+не4олог
+не4олібер
+не4онац
+не4офіт
+нею4н
+нея4к
+нея4рок
+но4к3а4ут
+пі5в4оні
+піво4с
+пале4о
+па4н3о4тець
+.пе4ом.
+д3у4сім
+п4о5бере
+ао4хот
+ое4ко
+ео4хот
+ео4щад
+ао4щад
+оо4чищ
+поя4с
+те4одоліт
+те4олог
+те4ософ
+оо4біг
+оу4сун
+оу4ком
+пів3о4вал
+а3у4дар
+о3у4дар
+з3у4дар
+в3у4дар
+контр3у4дар
+о3о4кисл
+и3о4кисл
+ень7о4кисл
+е3о4кисл
+х3о4кисл
+и3і4стор
+о3і4стор
+і3і4стор
+а3і4стор
+я3і4стор
+е3і4стор
+наді4стор
+най3і4стор
+пів3і4стор
+перед3і4стор
+пост3і4стор
+ар4т3афіш
+ар4т3взвод
+ар4т3десант
+ар4т3кафе
+ар4т3майс
+ар4т3медіа
+ар4т3мейс
+ар4т3мін
+ар4т3о4бстр
+ар4т3о4дин
+ар4т3о4збр
+ар4т3під
+ар4т3рин
+ар4т3у4стан
+ар4т3факт
+ар4т3хім
+ар4т3центр
+наді4стот
+найі4стот
+еі4стот
+оі4стот
+ау4т3екол
+оо4чист
+з3а4кт
+оа4кт
+еа4кт
+гіпер3а4кт
+найа4кт
+піва4кт
+ао4браз
+ео4браз
+оо4браз
+граф3о4браз
+най3о4браз
+супер3о4браз
+ар4т3мейст
+баге4р3мейст
+бале4т3мейст
+бран4д3мейст
+ва4ль4д3мейст
+ве4ль4т3мейст
+го4ф3мейст
+гро4с3мейст
+декре4т3мейст
+до4к3мейст
+капе4ль3мейст
+кварти4р3мейст
+конце4р4т3мейст
+кра4н3мейст
+полі4ц3мейст
+по4ш4т3мейст
+фо4р4с4т3мейст
+хо4р3мейст
+шапі4т3мейст
+шта4л3мейст
+єге4р3мейст
+иа4варі
+яа4варі
+оа4варі
+еа4варі
+беза4варі
+між3а4варі
+над3а4варі
+пост3а4варі
+напів3а4варі
+перед3а4варі
+супер3а4варі
+аа4дрес
+еа4дрес
+оа4дрес
+іа4дрес
+без3а4дрес
+ае4фект
+ее4фект
+ое4фект
+най3е4фект
+супер3е4фект
+ое4місі
+ие4місі
+яе4місі
+ее4місі
+безе4місі
+гіпер3е4місі
+еу4бог
+й3у4бог
+ий4ня
+зай4ня
+здій4ня
+най4ня
+обій4ня
+перей4ня
+підій4ня
+прий4м
+пій4м
+дій4ма
+вий4м
+най4ма
+зай4м
+д4о3й4м
+обой4м
+прой4м
+обій4м
+перей4м
+безу4гл
+безу4пин
+бло4к3пост
+.блі4ц3ана
+.блі4ц3криг
+.блі4ц3опит
+.блі4ц3торг
+.блі4ц3тур
+.блі4ц3і4спит
+о3а4наліз
+бак3а4наліз
+ц3а4наліз
+ген3а4наліз
+з3а4наліз
+м3а4наліз
+нт3а4наліз
+між3а4наліз
+полі3а4наліз
+ре3а4наліз
+оу4год
+ау4год
+еу4год
+пів3у4год
+роз3у4год
+гос4п3у4год
+ео4пис
+оо4пис
+ао4пис
+бо4р4т3мех
+бо4р4т3о4пер
+бо4р4т3про
+бо4р4т3рад
+бо4р4т3і4нж
+оа4каці
+оу4с
+оо4держ
+оа4на
+біблі4о
+.на3в4ч
+.ви3в4ч
+.до3в4ч
+.за3в4ч
+.по3в4ч
+.при3в4ч
+ана3в4ч
+ена3в4ч
+мона3в4ч
+жона3в4ч
+іона3в4ч
+ови3в4ч
+еви3в4ч
+едо3в4ч
+оза3в4ч
+по3в4ча
+.ом4рі
+е3м4рій
+.ви3м4р
+.віді3м4р
+.зав3м4р
+.за3м4р
+.зі3м4р
+.на3м4р
+.пере3м4р
+.по3м4р
+.при3м4р
+.роз3м4р
+.ум4ри
+.ум4рі
+.ум4ру
+.ум4ре
+во4станнє
+най3о4станн
+перед3о4станн
+ие4стет
+ое4стет
+ее4стет
+й3е4стет
+пан3е4стет
+пар3е4стет
+оо4ктан
+іо4ктан
+оо4плачув
+ео4плачув
+перед3о4пла
+виу4ди
+о3в4каз
+е3в4каз} \ No newline at end of file
diff --git a/tex/context/patterns/lang-uk.rme b/tex/context/patterns/lang-uk.rme
new file mode 100644
index 000000000..9d6e5ee88
--- /dev/null
+++ b/tex/context/patterns/lang-uk.rme
@@ -0,0 +1,70 @@
+% generated by mtxrun --script pattern --convert
+
+% This file is part of hyph-utf8 package and resulted from
+% semi-manual conversions of hyphenation patterns into UTF-8 in June 2008.
+%
+% Source: TODO:WRITEME (yyyy-mm-dd)
+% Author: Maksym Polyakov <polyama at auburn.edu>, <mpoliak at i.com.ua>
+%
+% The above mentioned file should become obsolete,
+% and the author of the original file should preferaby modify this file instead.
+%
+% Modificatios were needed in order to support native UTF-8 engines,
+% but functionality (hopefully) didn't change in any way, at least not intentionally.
+% This file is no longer stand-alone; at least for 8-bit engines
+% you probably want to use loadhyph-foo.tex (which will load this file) instead.
+%
+% Modifications were done by Jonathan Kew, Mojca Miklavec & Arthur Reutenauer
+% with help & support from:
+% - Karl Berry, who gave us free hands and all resources
+% - Taco Hoekwater, with useful macros
+% - Hans Hagen, who did the unicodifisation of patterns already long before
+% and helped with testing, suggestions and bug reports
+% - Norbert Preining, who tested & integrated patterns into TeX Live
+%
+% However, the "copyright/copyleft" owner of patterns remains the original author.
+%
+% The copyright statement of this file is thus:
+%
+% Do with this file whatever needs to be done in future for the sake of
+% "a better world" as long as you respect the copyright of original file.
+% If you're the original author of patterns or taking over a new revolution,
+% plese remove all of the TUG comments & credits that we added here -
+% you are the Queen / the King, we are only the servants.
+%
+% If you want to change this file, rather than uploading directly to CTAN,
+% we would be grateful if you could send it to us (http://tug.org/tex-hyphen)
+% or ask for credentials for SVN repository and commit it yourself;
+% we will then upload the whole "package" to CTAN.
+%
+% Before a new "pattern-revolution" starts,
+% please try to follow some guidelines if possible:
+%
+% - \lccode is *forbidden*, and I really mean it
+% - all the patterns should be in UTF-8
+% - the only "allowed" TeX commands in this file are: \patterns, \hyphenation,
+% and if you really cannot do without, also \input and \message
+% - in particular, please no \catcode or \lccode changes,
+% they belong to loadhyph-foo.tex,
+% and no \lefthyphenmin and \righthyphenmin,
+% they have no influence here and belong elsewhere
+% - \begingroup and/or \endinput is not needed
+% - feel free to do whatever you want inside comments
+%
+% We know that TeX is extremely powerful, but give a stupid parser
+% at least a chance to read your patterns.
+%
+% For more unformation see
+%
+% http://tug.org/tex-hyphen
+%
+%------------------------------------------------------------------------------
+%
+% Ukrainian hyphenation patterns in LCY (cp866nav) encoding.
+% Copyright 1998-2001 Maksym Polyakov.
+% Released 2001/05/10.
+% This file can be redistributed and/or modified
+% under the terms of the LaTeX Project Public License (lppl).
+% Please, send bug reports via e-mail:
+% polyama@auburn.edu
+% mpoliak@i.com.ua \ No newline at end of file
diff --git a/tex/context/test/context-test.tex b/tex/context/test/context-test.tex
new file mode 100644
index 000000000..3cf002baf
--- /dev/null
+++ b/tex/context/test/context-test.tex
@@ -0,0 +1,27 @@
+\starttext
+
+\startmode[mkiv]
+
+ \startluacode
+ tex.sprint("hello")
+ \stopluacode
+
+ \startMPcode
+ draw textext("hello") rotated 45 ;
+ \stopMPcode
+
+ \framed{hello}
+
+\stopmode
+
+\startnotmode[mkiv]
+
+ \startMPcode
+ draw textext("hello") rotated -45 ;
+ \stopMPcode
+
+ \framed{hello}
+
+\stopnotmode
+
+\stoptext
diff --git a/tex/context/user/cont-sys.rme b/tex/context/user/cont-sys.rme
index 335a7d984..11c0141e7 100644
--- a/tex/context/user/cont-sys.rme
+++ b/tex/context/user/cont-sys.rme
@@ -14,8 +14,8 @@
\unprotect
% Speed up typescript loading, but at the cost of much memory:
-%
-% \preloadtypescripts
+
+\preloadtypescripts
% If you want another default font:
%
@@ -121,7 +121,6 @@
% When you have your own fonts installed, you may want to predefine:
%
% \usetypescriptfile[type-buy]
-% \usetypescriptfile [type-gyr]
% Some styles default to Lucida Bright. You can overload
% Lucida by Times cum suis. Watch out, the pos collection
@@ -158,8 +157,8 @@
% Enabling run time \METAPOST\ (also enable \write18 in
% texmf.cnf):
-% \runMPgraphicstrue
-% \runMPTEXgraphicstrue
+\runMPgraphicstrue
+\runMPTEXgraphicstrue
% This saves some runtime, but needs a format, which you can
% make with 'texexec --make --alone metafun'. Make sure that
diff --git a/tex/generic/context/luatex-basics.tex b/tex/generic/context/luatex-basics.tex
new file mode 100644
index 000000000..8308204d5
--- /dev/null
+++ b/tex/generic/context/luatex-basics.tex
@@ -0,0 +1,21 @@
+%D \module
+%D [ file=luatex-basics,
+%D version=2009.12.01,
+%D title=\LUATEX\ Support Macros,
+%D subtitle=Attribute Allocation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=public domain]
+
+%D As soon as we feel the need this file will file will contain an extension
+%D to the standard plain register allocation. For the moment we stick to a
+%D rather dumb attribute allocator. We start at 256 because we don't want
+%D any interference with the attributes used in the font handler.
+
+\newcount \lastallocatedattribute \lastallocatedattribute=255
+
+\def\newattribute#1%
+ {\global\advance\lastallocatedattribute 1
+ \attributedef#1\lastallocatedattribute}
+
+\endinput
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua
new file mode 100644
index 000000000..15d12a584
--- /dev/null
+++ b/tex/generic/context/luatex-fonts-merged.lua
@@ -0,0 +1,11070 @@
+-- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua
+-- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua
+-- merge date : 05/28/09 11:25:26
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-string'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local sub, gsub, find, match, gmatch, format, char, byte, rep = string.sub, string.gsub, string.find, string.match, string.gmatch, string.format, string.char, string.byte, string.rep
+
+if not string.split then
+
+ -- this will be overloaded by a faster lpeg variant
+
+ function string:split(pattern)
+ if #self > 0 then
+ local t = { }
+ for s in gmatch(self..pattern,"(.-)"..pattern) do
+ t[#t+1] = s
+ end
+ return t
+ else
+ return { }
+ end
+ end
+
+end
+
+local chr_to_esc = {
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+ ["^"] = "%^", ["$"] = "%$",
+ ["["] = "%[", ["]"] = "%]",
+ ["("] = "%(", [")"] = "%)",
+ ["{"] = "%{", ["}"] = "%}"
+}
+
+string.chr_to_esc = chr_to_esc
+
+function string:esc() -- variant 2
+ return (gsub(self,"(.)",chr_to_esc))
+end
+
+function string:unquote()
+ return (gsub(self,"^([\"\'])(.*)%1$","%2"))
+end
+
+function string:quote() -- we could use format("%q")
+ return '"' .. self:unquote() .. '"'
+end
+
+function string:count(pattern) -- variant 3
+ local n = 0
+ for _ in gmatch(self,pattern) do
+ n = n + 1
+ end
+ return n
+end
+
+function string:limit(n,sentinel)
+ if #self > n then
+ sentinel = sentinel or " ..."
+ return sub(self,1,(n-#sentinel)) .. sentinel
+ else
+ return self
+ end
+end
+
+function string:strip()
+ return (gsub(self,"^%s*(.-)%s*$", "%1"))
+end
+
+function string:is_empty()
+ return not find(find,"%S")
+end
+
+function string:enhance(pattern,action)
+ local ok, n = true, 0
+ while ok do
+ ok = false
+ self = gsub(self,pattern, function(...)
+ ok, n = true, n + 1
+ return action(...)
+ end)
+ end
+ return self, n
+end
+
+local chr_to_hex, hex_to_chr = { }, { }
+
+for i=0,255 do
+ local c, h = char(i), format("%02X",i)
+ chr_to_hex[c], hex_to_chr[h] = h, c
+end
+
+function string:to_hex()
+ return (gsub(self or "","(.)",chr_to_hex))
+end
+
+function string:from_hex()
+ return (gsub(self or "","(..)",hex_to_chr))
+end
+
+if not string.characters then
+
+ local function nextchar(str, index)
+ index = index + 1
+ return (index <= #str) and index or nil, str:sub(index,index)
+ end
+ function string:characters()
+ return nextchar, self, 0
+ end
+ local function nextbyte(str, index)
+ index = index + 1
+ return (index <= #str) and index or nil, byte(str:sub(index,index))
+ end
+ function string:bytes()
+ return nextbyte, self, 0
+ end
+
+end
+
+-- we can use format for this (neg n)
+
+function string:rpadd(n,chr)
+ local m = n-#self
+ if m > 0 then
+ return self .. self.rep(chr or " ",m)
+ else
+ return self
+ end
+end
+
+function string:lpadd(n,chr)
+ local m = n-#self
+ if m > 0 then
+ return self.rep(chr or " ",m) .. self
+ else
+ return self
+ end
+end
+
+string.padd = string.rpadd
+
+function is_number(str) -- tonumber
+ return find(str,"^[%-%+]?[%d]-%.?[%d+]$") == 1
+end
+
+--~ print(is_number("1"))
+--~ print(is_number("1.1"))
+--~ print(is_number(".1"))
+--~ print(is_number("-0.1"))
+--~ print(is_number("+0.1"))
+--~ print(is_number("-.1"))
+--~ print(is_number("+.1"))
+
+function string:split_settings() -- no {} handling, see l-aux for lpeg variant
+ if find(self,"=") then
+ local t = { }
+ for k,v in gmatch(self,"(%a+)=([^%,]*)") do
+ t[k] = v
+ end
+ return t
+ else
+ return nil
+ end
+end
+
+local patterns_escapes = {
+ ["-"] = "%-",
+ ["."] = "%.",
+ ["+"] = "%+",
+ ["*"] = "%*",
+ ["%"] = "%%",
+ ["("] = "%)",
+ [")"] = "%)",
+ ["["] = "%[",
+ ["]"] = "%]",
+}
+
+function string:pattesc()
+ return (gsub(self,".",patterns_escapes))
+end
+
+function string:tohash()
+ local t = { }
+ for s in gmatch(self,"([^, ]+)") do -- lpeg
+ t[s] = true
+ end
+ return t
+end
+
+local pattern = lpeg.Ct(lpeg.C(1)^0)
+
+function string:totable()
+ return pattern:match(self)
+end
+
+--~ for _, str in ipairs {
+--~ "1234567123456712345671234567",
+--~ "a\tb\tc",
+--~ "aa\tbb\tcc",
+--~ "aaa\tbbb\tccc",
+--~ "aaaa\tbbbb\tcccc",
+--~ "aaaaa\tbbbbb\tccccc",
+--~ "aaaaaa\tbbbbbb\tcccccc",
+--~ } do print(string.tabtospace(str)) end
+
+function string.tabtospace(str,tab)
+ -- we don't handle embedded newlines
+ while true do
+ local s = find(str,"\t")
+ if s then
+ if not tab then tab = 7 end -- only when found
+ local d = tab-(s-1)%tab
+ if d > 0 then
+ str = gsub(str,"\t",rep(" ",d),1)
+ else
+ str = gsub(str,"\t","",1)
+ end
+ else
+ break
+ end
+ end
+ return str
+end
+
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-lpeg'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+
+--~ l-lpeg.lua :
+
+--~ lpeg.digit = lpeg.R('09')^1
+--~ lpeg.sign = lpeg.S('+-')^1
+--~ lpeg.cardinal = lpeg.P(lpeg.sign^0 * lpeg.digit^1)
+--~ lpeg.integer = lpeg.P(lpeg.sign^0 * lpeg.digit^1)
+--~ lpeg.float = lpeg.P(lpeg.sign^0 * lpeg.digit^0 * lpeg.P('.') * lpeg.digit^1)
+--~ lpeg.number = lpeg.float + lpeg.integer
+--~ lpeg.oct = lpeg.P("0") * lpeg.R('07')^1
+--~ lpeg.hex = lpeg.P("0x") * (lpeg.R('09') + lpeg.R('AF'))^1
+--~ lpeg.uppercase = lpeg.P("AZ")
+--~ lpeg.lowercase = lpeg.P("az")
+
+--~ lpeg.eol = lpeg.S('\r\n\f')^1 -- includes formfeed
+--~ lpeg.space = lpeg.S(' ')^1
+--~ lpeg.nonspace = lpeg.P(1-lpeg.space)^1
+--~ lpeg.whitespace = lpeg.S(' \r\n\f\t')^1
+--~ lpeg.nonwhitespace = lpeg.P(1-lpeg.whitespace)^1
+
+local hash = { }
+
+function lpeg.anywhere(pattern) --slightly adapted from website
+ return P { P(pattern) + 1 * lpeg.V(1) }
+end
+
+function lpeg.startswith(pattern) --slightly adapted
+ return P(pattern)
+end
+
+function lpeg.splitter(pattern, action)
+ return (((1-P(pattern))^1)/action+1)^0
+end
+
+-- variant:
+
+--~ local parser = lpeg.Ct(lpeg.splitat(newline))
+
+local crlf = P("\r\n")
+local cr = P("\r")
+local lf = P("\n")
+local space = S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto)
+local newline = crlf + cr + lf
+local spacing = space^0 * newline
+
+local empty = spacing * Cc("")
+local nonempty = Cs((1-spacing)^1) * spacing^-1
+local content = (empty + nonempty)^1
+
+local capture = Ct(content^0)
+
+function string:splitlines()
+ return capture:match(self)
+end
+
+lpeg.linebyline = content -- better make a sublibrary
+
+--~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more
+--~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more
+--~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps
+--~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps
+
+local splitters_s, splitters_m = { }, { }
+
+local function splitat(separator,single)
+ local splitter = (single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator = P(separator)
+ if single then
+ local other, any = C((1 - separator)^0), P(1)
+ splitter = other * (separator * C(any^0) + "")
+ splitters_s[separator] = splitter
+ else
+ local other = C((1 - separator)^0)
+ splitter = other * (separator * other)^0
+ splitters_m[separator] = splitter
+ end
+ end
+ return splitter
+end
+
+lpeg.splitat = splitat
+
+local cache = { }
+
+function string:split(separator)
+ local c = cache[separator]
+ if not c then
+ c = Ct(splitat(separator))
+ cache[separator] = c
+ end
+ return c:match(self)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-boolean'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+boolean = boolean or { }
+
+local type, tonumber = type, tonumber
+
+function boolean.tonumber(b)
+ if b then return 1 else return 0 end
+end
+
+function toboolean(str,tolerant)
+ if tolerant then
+ local tstr = type(str)
+ if tstr == "string" then
+ return str == "true" or str == "yes" or str == "on" or str == "1" or str == "t"
+ elseif tstr == "number" then
+ return tonumber(str) ~= 0
+ elseif tstr == "nil" then
+ return false
+ else
+ return str
+ end
+ elseif str == "true" then
+ return true
+ elseif str == "false" then
+ return false
+ else
+ return str
+ end
+end
+
+function string.is_boolean(str)
+ if type(str) == "string" then
+ if str == "true" or str == "yes" or str == "on" or str == "t" then
+ return true
+ elseif str == "false" or str == "no" or str == "off" or str == "f" then
+ return false
+ end
+ end
+ return nil
+end
+
+function boolean.alwaystrue()
+ return true
+end
+
+function boolean.falsetrue()
+ return false
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-math'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local floor, sin, cos, tan = math.floor, math.sin, math.cos, math.tan
+
+if not math.round then
+ function math.round(x)
+ return floor(x + 0.5)
+ end
+end
+
+if not math.div then
+ function math.div(n,m)
+ return floor(n/m)
+ end
+end
+
+if not math.mod then
+ function math.mod(n,m)
+ return n % m
+ end
+end
+
+local pipi = 2*math.pi/360
+
+function math.sind(d)
+ return sin(d*pipi)
+end
+
+function math.cosd(d)
+ return cos(d*pipi)
+end
+
+function math.tand(d)
+ return tan(d*pipi)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-table'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+table.join = table.concat
+
+local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
+local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local getmetatable, setmetatable = getmetatable, setmetatable
+local type, next, tostring, ipairs = type, next, tostring, ipairs
+
+function table.strip(tab)
+ local lst = { }
+ for i=1,#tab do
+ local s = gsub(tab[i],"^%s*(.-)%s*$","%1")
+ if s == "" then
+ -- skip this one
+ else
+ lst[#lst+1] = s
+ end
+ end
+ return lst
+end
+
+local function sortedkeys(tab)
+ local srt, kind = { }, 0 -- 0=unknown 1=string, 2=number 3=mixed
+ for key,_ in next, tab do
+ srt[#srt+1] = key
+ if kind == 3 then
+ -- no further check
+ else
+ local tkey = type(key)
+ if tkey == "string" then
+ -- if kind == 2 then kind = 3 else kind = 1 end
+ kind = (kind == 2 and 3) or 1
+ elseif tkey == "number" then
+ -- if kind == 1 then kind = 3 else kind = 2 end
+ kind = (kind == 1 and 3) or 2
+ else
+ kind = 3
+ end
+ end
+ end
+ if kind == 0 or kind == 3 then
+ sort(srt,function(a,b) return (tostring(a) < tostring(b)) end)
+ else
+ sort(srt)
+ end
+ return srt
+end
+
+local function sortedhashkeys(tab) -- fast one
+ local srt = { }
+ for key,_ in next, tab do
+ srt[#srt+1] = key
+ end
+ sort(srt)
+ return srt
+end
+
+table.sortedkeys = sortedkeys
+table.sortedhashkeys = sortedhashkeys
+
+function table.sortedpairs(t)
+ local s = sortedhashkeys(t) -- maybe just sortedkeys
+ local n = 0
+ local function kv(s)
+ n = n + 1
+ local k = s[n]
+ return k, t[k]
+ end
+ return kv, s
+end
+
+function table.append(t, list)
+ for _,v in next, list do
+ insert(t,v)
+ end
+end
+
+function table.prepend(t, list)
+ for k,v in next, list do
+ insert(t,k,v)
+ end
+end
+
+function table.merge(t, ...) -- first one is target
+ t = t or {}
+ local lst = {...}
+ for i=1,#lst do
+ for k, v in next, lst[i] do
+ t[k] = v
+ end
+ end
+ return t
+end
+
+function table.merged(...)
+ local tmp, lst = { }, {...}
+ for i=1,#lst do
+ for k, v in next, lst[i] do
+ tmp[k] = v
+ end
+ end
+ return tmp
+end
+
+function table.imerge(t, ...)
+ local lst = {...}
+ for i=1,#lst do
+ local nst = lst[i]
+ for j=1,#nst do
+ t[#t+1] = nst[j]
+ end
+ end
+ return t
+end
+
+function table.imerged(...)
+ local tmp, lst = { }, {...}
+ for i=1,#lst do
+ local nst = lst[i]
+ for j=1,#nst do
+ tmp[#tmp+1] = nst[j]
+ end
+ end
+ return tmp
+end
+
+local function fastcopy(old) -- fast one
+ if old then
+ local new = { }
+ for k,v in next, old do
+ if type(v) == "table" then
+ new[k] = fastcopy(v) -- was just table.copy
+ else
+ new[k] = v
+ end
+ end
+ -- optional second arg
+ local mt = getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ return new
+ else
+ return { }
+ end
+end
+
+local function copy(t, tables) -- taken from lua wiki, slightly adapted
+ tables = tables or { }
+ local tcopy = {}
+ if not tables[t] then
+ tables[t] = tcopy
+ end
+ for i,v in next, t do -- brrr, what happens with sparse indexed
+ if type(i) == "table" then
+ if tables[i] then
+ i = tables[i]
+ else
+ i = copy(i, tables)
+ end
+ end
+ if type(v) ~= "table" then
+ tcopy[i] = v
+ elseif tables[v] then
+ tcopy[i] = tables[v]
+ else
+ tcopy[i] = copy(v, tables)
+ end
+ end
+ local mt = getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
+end
+
+table.fastcopy = fastcopy
+table.copy = copy
+
+-- rougly: copy-loop : unpack : sub == 0.9 : 0.4 : 0.45 (so in critical apps, use unpack)
+
+function table.sub(t,i,j)
+ return { unpack(t,i,j) }
+end
+
+function table.replace(a,b)
+ for k,v in next, b do
+ a[k] = v
+ end
+end
+
+-- slower than #t on indexed tables (#t only returns the size of the numerically indexed slice)
+
+function table.is_empty(t)
+ return not t or not next(t)
+end
+
+function table.one_entry(t)
+ local n = next(t)
+ return n and not next(t,n)
+end
+
+function table.starts_at(t)
+ return ipairs(t,1)(t,0)
+end
+
+function table.tohash(t,value)
+ local h = { }
+ if t then
+ if value == nil then value = true end
+ for _, v in next, t do -- no ipairs here
+ h[v] = value
+ end
+ end
+ return h
+end
+
+function table.fromhash(t)
+ local h = { }
+ for k, v in next, t do -- no ipairs here
+ if v then h[#h+1] = k end
+ end
+ return h
+end
+
+--~ print(table.serialize(t), "\n")
+--~ print(table.serialize(t,"name"), "\n")
+--~ print(table.serialize(t,false), "\n")
+--~ print(table.serialize(t,true), "\n")
+--~ print(table.serialize(t,"name",true), "\n")
+--~ print(table.serialize(t,"name",true,true), "\n")
+
+table.serialize_functions = true
+table.serialize_compact = true
+table.serialize_inline = true
+
+local noquotes, hexify, handle, reduce, compact, inline, functions
+
+local reserved = table.tohash { -- intercept a language flaw, no reserved words as key
+ 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
+ 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
+}
+
+local function simple_table(t)
+ if #t > 0 then
+ local n = 0
+ for _,v in next, t do
+ n = n + 1
+ end
+ if n == #t then
+ local tt = { }
+ for i=1,#t do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "number" then
+ if hexify then
+ tt[#tt+1] = format("0x%04X",v)
+ else
+ tt[#tt+1] = tostring(v) -- tostring not needed
+ end
+ elseif tv == "boolean" then
+ tt[#tt+1] = tostring(v)
+ elseif tv == "string" then
+ tt[#tt+1] = format("%q",v)
+ else
+ tt = nil
+ break
+ end
+ end
+ return tt
+ end
+ end
+ return nil
+end
+
+-- Because this is a core function of mkiv I moved some function calls
+-- inline.
+--
+-- twice as fast in a test:
+--
+-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+
+local function do_serialize(root,name,depth,level,indexed)
+ if level > 0 then
+ depth = depth .. " "
+ if indexed then
+ handle(format("%s{",depth))
+ elseif name then
+ --~ handle(format("%s%s={",depth,key(name)))
+ if type(name) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s[0x%04X]={",depth,name))
+ else
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif noquotes and not reserved[name] and find(name,"^%a[%w%_]*$") then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ else
+ handle(format("%s{",depth))
+ end
+ end
+ if root and next(root) then
+ local first, last = nil, 0 -- #root cannot be trusted here
+ if compact then
+ -- NOT: for k=1,#root do (we need to quit at nil)
+ for k,v in ipairs(root) do -- can we use next?
+ if not first then first = k end
+ last = last + 1
+ end
+ end
+ local sk = sortedkeys(root)
+ for i=1,#sk do
+ local k = sk[i]
+ local v = root[k]
+ --~ if v == root then
+ -- circular
+ --~ else
+ local t = type(v)
+ if compact and first and type(k) == "number" and k >= first and k <= last then
+ if t == "number" then
+ if hexify then
+ handle(format("%s 0x%04X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif t == "string" then
+ if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ handle(format("%s %s,",depth,v))
+ else
+ handle(format("%s %q,",depth,v))
+ end
+ elseif t == "table" then
+ if not next(v) then
+ handle(format("%s {},",depth))
+ elseif inline then -- and #t > 0
+ local st = simple_table(v)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif t == "boolean" then
+ handle(format("%s %s,",depth,tostring(v)))
+ elseif t == "function" then
+ if functions then
+ handle(format('%s loadstring(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
+ end
+ elseif k == "__p__" then -- parent
+ if false then
+ handle(format("%s __p__=nil,",depth))
+ end
+ elseif t == "number" then
+ --~ if hexify then
+ --~ handle(format("%s %s=0x%04X,",depth,key(k),v))
+ --~ else
+ --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ end
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ if hexify then
+ handle(format("%s %s=0x%04X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
+ else
+ if hexify then
+ handle(format("%s [%q]=0x%04X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
+ end
+ elseif t == "string" then
+ if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ --~ handle(format("%s %s=%s,",depth,key(k),v))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%s,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%s,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
+ else
+ --~ handle(format("%s %s=%q,",depth,key(k),v))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
+ end
+ elseif t == "table" then
+ if not next(v) then
+ --~ handle(format("%s %s={},",depth,key(k)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st = simple_table(v)
+ if st then
+ --~ handle(format("%s %s={ %s },",depth,key(k),concat(st,", ")))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ elseif t == "boolean" then
+ --~ handle(format("%s %s=%s,",depth,key(k),tostring(v)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%s,",depth,k,tostring(v)))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%s,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%s,",depth,k,tostring(v)))
+ end
+ elseif t == "function" then
+ if functions then
+ --~ handle(format('%s %s=loadstring(%q),',depth,key(k),dump(v)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=loadstring(%q),",depth,k,dump(v)))
+ else
+ handle(format("%s [%s]=loadstring(%q),",depth,k,dump(v)))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=loadstring(%q),",depth,k,dump(v)))
+ else
+ handle(format("%s [%q]=loadstring(%q),",depth,k,dump(v)))
+ end
+ end
+ else
+ --~ handle(format("%s %s=%q,",depth,key(k),tostring(v)))
+ if type(k) == "number" then -- or find(k,"^%d+$") then
+ if hexify then
+ handle(format("%s [0x%04X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
+ end
+ --~ end
+ end
+ end
+ if level > 0 then
+ handle(format("%s},",depth))
+ end
+end
+
+-- replacing handle by a direct t[#t+1] = ... (plus test) is not much
+-- faster (0.03 on 1.00 for zapfino.tma)
+
+local function serialize(root,name,_handle,_reduce,_noquotes,_hexify)
+ noquotes = _noquotes
+ hexify = _hexify
+ handle = _handle or print
+ reduce = _reduce or false
+ compact = table.serialize_compact
+ inline = compact and table.serialize_inline
+ functions = table.serialize_functions
+ local tname = type(name)
+ if tname == "string" then
+ if name == "return" then
+ handle("return {")
+ else
+ handle(name .. "={")
+ end
+ elseif tname == "number" then
+ if hexify then
+ handle(format("[0x%04X]={",name))
+ else
+ handle("[" .. name .. "]={")
+ end
+ elseif tname == "boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root and next(root) then
+ do_serialize(root,name,"",0,indexed)
+ end
+ handle("}")
+end
+
+--~ name:
+--~
+--~ true : return { }
+--~ false : { }
+--~ nil : t = { }
+--~ string : string = { }
+--~ 'return' : return { }
+--~ number : [number] = { }
+
+function table.serialize(root,name,reduce,noquotes,hexify)
+ local t = { }
+ local function flush(s)
+ t[#t+1] = s
+ end
+ serialize(root,name,flush,reduce,noquotes,hexify)
+ return concat(t,"\n")
+end
+
+function table.tohandle(handle,root,name,reduce,noquotes,hexify)
+ serialize(root,name,handle,reduce,noquotes,hexify)
+end
+
+-- sometimes tables are real use (zapfino extra pro is some 85M) in which
+-- case a stepwise serialization is nice; actually, we could consider:
+--
+-- for line in table.serializer(root,name,reduce,noquotes) do
+-- ...(line)
+-- end
+--
+-- so this is on the todo list
+
+table.tofile_maxtab = 2*1024
+
+function table.tofile(filename,root,name,reduce,noquotes,hexify)
+ local f = io.open(filename,'w')
+ if f then
+ local maxtab = table.tofile_maxtab
+ if maxtab > 1 then
+ local t = { }
+ local function flush(s)
+ t[#t+1] = s
+ if #t > maxtab then
+ f:write(concat(t,"\n"),"\n") -- hm, write(sometable) should be nice
+ t = { }
+ end
+ end
+ serialize(root,name,flush,reduce,noquotes,hexify)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(root,name,flush,reduce,noquotes,hexify)
+ end
+ f:close()
+ end
+end
+
+local function flatten(t,f,complete)
+ for i=1,#t do
+ local v = t[i]
+ if type(v) == "table" then
+ if complete or type(v[1]) == "table" then
+ flatten(v,f,complete)
+ else
+ f[#f+1] = v
+ end
+ else
+ f[#f+1] = v
+ end
+ end
+end
+
+function table.flatten(t)
+ local f = { }
+ flatten(t,f,true)
+ return f
+end
+
+function table.unnest(t) -- bad name
+ local f = { }
+ flatten(t,f,false)
+ return f
+end
+
+table.flatten_one_level = table.unnest
+
+-- the next three may disappear
+
+function table.remove_value(t,value) -- todo: n
+ if value then
+ for i=1,#t do
+ if t[i] == value then
+ remove(t,i)
+ -- remove all, so no: return
+ end
+ end
+ end
+end
+
+function table.insert_before_value(t,value,str)
+ if str then
+ if value then
+ for i=1,#t do
+ if t[i] == value then
+ insert(t,i,str)
+ return
+ end
+ end
+ end
+ insert(t,1,str)
+ elseif value then
+ insert(t,1,value)
+ end
+end
+
+function table.insert_after_value(t,value,str)
+ if str then
+ if value then
+ for i=1,#t do
+ if t[i] == value then
+ insert(t,i+1,str)
+ return
+ end
+ end
+ end
+ t[#t+1] = str
+ elseif value then
+ t[#t+1] = value
+ end
+end
+
+local function are_equal(a,b,n,m) -- indexed
+ if #a == #b then
+ n = n or 1
+ m = m or #a
+ for i=n,m do
+ local ai, bi = a[i], b[i]
+ if ai==bi then
+ -- same
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+ else
+ return false
+ end
+end
+
+local function identical(a,b) -- assumes same structure
+ for ka, va in next, a do
+ local vb = b[k]
+ if va == vb then
+ -- same
+ elseif type(va) == "table" and type(vb) == "table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
+ end
+ return true
+end
+
+table.are_equal = are_equal
+table.identical = identical
+
+-- maybe also make a combined one
+
+function table.compact(t)
+ if t then
+ for k,v in next, t do
+ if not next(v) then
+ t[k] = nil
+ end
+ end
+ end
+end
+
+function table.contains(t, v)
+ if t then
+ for i=1, #t do
+ if t[i] == v then
+ return i
+ end
+ end
+ end
+ return false
+end
+
+function table.count(t)
+ local n, e = 0, next(t)
+ while e do
+ n, e = n + 1, next(t,e)
+ end
+ return n
+end
+
+function table.swapped(t)
+ local s = { }
+ for k, v in next, t do
+ s[v] = k
+ end
+ return s
+end
+
+--~ function table.are_equal(a,b)
+--~ return table.serialize(a) == table.serialize(b)
+--~ end
+
+function table.clone(t,p) -- t is optional or nil or table
+ if not p then
+ t, p = { }, t or { }
+ elseif not t then
+ t = { }
+ end
+ setmetatable(t, { __index = function(_,key) return p[key] end })
+ return t
+end
+
+function table.hexed(t,seperator)
+ local tt = { }
+ for i=1,#t do tt[i] = format("0x%04X",t[i]) end
+ return concat(tt,seperator or " ")
+end
+
+function table.reverse_hash(h)
+ local r = { }
+ for k,v in next, h do
+ r[v] = lower(gsub(k," ",""))
+ end
+ return r
+end
+
+function table.reverse(t)
+ local tt = { }
+ if #t > 0 then
+ for i=#t,1,-1 do
+ tt[#tt+1] = t[i]
+ end
+ end
+ return tt
+end
+
+--~ function table.keys(t)
+--~ local k = { }
+--~ for k,_ in next, t do
+--~ k[#k+1] = k
+--~ end
+--~ return k
+--~ end
+
+--~ function table.keys_as_string(t)
+--~ local k = { }
+--~ for k,_ in next, t do
+--~ k[#k+1] = k
+--~ end
+--~ return concat(k,"")
+--~ end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-file'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- needs a cleanup
+
+file = file or { }
+
+local concat = table.concat
+local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub
+
+function file.removesuffix(filename)
+ return (gsub(filename,"%.[%a%d]+$",""))
+end
+
+function file.addsuffix(filename, suffix)
+ if not find(filename,"%.[%a%d]+$") then
+ return filename .. "." .. suffix
+ else
+ return filename
+ end
+end
+
+function file.replacesuffix(filename, suffix)
+ return (gsub(filename,"%.[%a%d]+$","")) .. "." .. suffix
+end
+
+function file.dirname(name,default)
+ return match(name,"^(.+)[/\\].-$") or (default or "")
+end
+
+function file.basename(name)
+ return match(name,"^.+[/\\](.-)$") or name
+end
+
+function file.nameonly(name)
+ return (gsub(match(name,"^.+[/\\](.-)$") or name,"%..*$",""))
+end
+
+function file.extname(name)
+ return match(name,"^.+%.([^/\\]-)$") or ""
+end
+
+file.suffix = file.extname
+
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
+function file.join(...)
+ local pth = concat({...},"/")
+ pth = gsub(pth,"\\","/")
+ local a, b = match(pth,"^(.*://)(.*)$")
+ if a and b then
+ return a .. gsub(b,"//+","/")
+ end
+ a, b = match(pth,"^(//)(.*)$")
+ if a and b then
+ return a .. gsub(b,"//+","/")
+ end
+ return (gsub(pth,"//+","/"))
+end
+
+function file.iswritable(name)
+ local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
+ return a and a.permissions:sub(2,2) == "w"
+end
+
+function file.isreadable(name)
+ local a = lfs.attributes(name)
+ return a and a.permissions:sub(1,1) == "r"
+end
+
+file.is_readable = file.isreadable
+file.is_writable = file.iswritable
+
+-- todo: lpeg
+
+function file.split_path(str)
+ local t = { }
+ str = gsub(str,"\\", "/")
+ str = gsub(str,"(%a):([;/])", "%1\001%2")
+ for name in gmatch(str,"([^;:]+)") do
+ if name ~= "" then
+ t[#t+1] = gsub(name,"\001",":")
+ end
+ end
+ return t
+end
+
+function file.join_path(tab)
+ return concat(tab,io.pathseparator) -- can have trailing //
+end
+
+function file.collapse_path(str)
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ str = gsub(str,"^%./","")
+ str = gsub(str,"/%.$","")
+ if str == "" then str = "." end
+ return str
+end
+
+--~ print(file.collapse_path("a/./b/.."))
+--~ print(file.collapse_path("a/aa/../b/bb"))
+--~ print(file.collapse_path("a/../.."))
+--~ print(file.collapse_path("a/.././././b/.."))
+--~ print(file.collapse_path("a/./././b/.."))
+--~ print(file.collapse_path("a/b/c/../.."))
+
+function file.robustname(str)
+ return (gsub(str,"[^%a%d%/%-%.\\]+","-"))
+end
+
+file.readdata = io.loaddata
+file.savedata = io.savedata
+
+function file.copy(oldname,newname)
+ file.savedata(newname,io.loaddata(oldname))
+end
+
+-- lpeg variants, slightly faster, not always
+
+--~ local period = lpeg.P(".")
+--~ local slashes = lpeg.S("\\/")
+--~ local noperiod = 1-period
+--~ local noslashes = 1-slashes
+--~ local name = noperiod^1
+
+--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.C(noperiod^1) * -1
+
+--~ function file.extname(name)
+--~ return pattern:match(name) or ""
+--~ end
+
+--~ local pattern = lpeg.Cs(((period * noperiod^1 * -1)/"" + 1)^1)
+
+--~ function file.removesuffix(name)
+--~ return pattern:match(name)
+--~ end
+
+--~ local pattern = (noslashes^0 * slashes)^1 * lpeg.C(noslashes^1) * -1
+
+--~ function file.basename(name)
+--~ return pattern:match(name) or name
+--~ end
+
+--~ local pattern = (noslashes^0 * slashes)^1 * lpeg.Cp() * noslashes^1 * -1
+
+--~ function file.dirname(name)
+--~ local p = pattern:match(name)
+--~ if p then
+--~ return name:sub(1,p-2)
+--~ else
+--~ return ""
+--~ end
+--~ end
+
+--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1
+
+--~ function file.addsuffix(name, suffix)
+--~ local p = pattern:match(name)
+--~ if p then
+--~ return name
+--~ else
+--~ return name .. "." .. suffix
+--~ end
+--~ end
+
+--~ local pattern = (noslashes^0 * slashes)^0 * (noperiod^1 * period)^1 * lpeg.Cp() * noperiod^1 * -1
+
+--~ function file.replacesuffix(name,suffix)
+--~ local p = pattern:match(name)
+--~ if p then
+--~ return name:sub(1,p-2) .. "." .. suffix
+--~ else
+--~ return name .. "." .. suffix
+--~ end
+--~ end
+
+--~ local pattern = (noslashes^0 * slashes)^0 * lpeg.Cp() * ((noperiod^1 * period)^1 * lpeg.Cp() + lpeg.P(true)) * noperiod^1 * -1
+
+--~ function file.nameonly(name)
+--~ local a, b = pattern:match(name)
+--~ if b then
+--~ return name:sub(a,b-2)
+--~ elseif a then
+--~ return name:sub(a)
+--~ else
+--~ return name
+--~ end
+--~ end
+
+--~ local test = file.extname
+--~ local test = file.basename
+--~ local test = file.dirname
+--~ local test = file.addsuffix
+--~ local test = file.replacesuffix
+--~ local test = file.nameonly
+
+--~ print(1,test("./a/b/c/abd.def.xxx","!!!"))
+--~ print(2,test("./../b/c/abd.def.xxx","!!!"))
+--~ print(3,test("a/b/c/abd.def.xxx","!!!"))
+--~ print(4,test("a/b/c/def.xxx","!!!"))
+--~ print(5,test("a/b/c/def","!!!"))
+--~ print(6,test("def","!!!"))
+--~ print(7,test("def.xxx","!!!"))
+
+--~ local tim = os.clock() for i=1,250000 do local ext = test("abd.def.xxx","!!!") end print(os.clock()-tim)
+
+-- also rewrite previous
+
+local letter = lpeg.R("az","AZ") + lpeg.S("_-+")
+local separator = lpeg.P("://")
+
+local qualified = lpeg.P(".")^0 * lpeg.P("/") + letter*lpeg.P(":") + letter^1*separator + letter^1 * lpeg.P("/")
+local rootbased = lpeg.P("/") + letter*lpeg.P(":")
+
+-- ./name ../name /name c: :// name/name
+
+function file.is_qualified_path(filename)
+ return qualified:match(filename)
+end
+
+function file.is_rootbased_path(filename)
+ return rootbased:match(filename)
+end
+
+local slash = lpeg.S("\\/")
+local period = lpeg.P(".")
+local drive = lpeg.C(lpeg.R("az","AZ")) * lpeg.P(":")
+local path = lpeg.C(((1-slash)^0 * slash)^0)
+local suffix = period * lpeg.C(lpeg.P(1-period)^0 * lpeg.P(-1))
+local base = lpeg.C((1-suffix)^0)
+
+local pattern = (drive + lpeg.Cc("")) * (path + lpeg.Cc("")) * (base + lpeg.Cc("")) * (suffix + lpeg.Cc(""))
+
+function file.splitname(str) -- returns drive, path, base, suffix
+ return pattern:match(str)
+end
+
+-- function test(t) for k, v in pairs(t) do print(v, "=>", file.splitname(v)) end end
+--
+-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
+-- test { "c:", "c:aa", "c:aa/bb", "c:aa/bb/cc", "c:aa/bb/cc.dd", "c:aa/bb/cc.dd.ee" }
+-- test { "/aa", "/aa/bb", "/aa/bb/cc", "/aa/bb/cc.dd", "/aa/bb/cc.dd.ee" }
+-- test { "aa", "aa/bb", "aa/bb/cc", "aa/bb/cc.dd", "aa/bb/cc.dd.ee" }
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['l-io'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local byte = string.byte
+
+if string.find(os.getenv("PATH"),";") then
+ io.fileseparator, io.pathseparator = "\\", ";"
+else
+ io.fileseparator, io.pathseparator = "/" , ":"
+end
+
+function io.loaddata(filename,textmode)
+ local f = io.open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local data = f:read('*all')
+ -- garbagecollector.check(data)
+ f:close()
+ return data
+ else
+ return nil
+ end
+end
+
+function io.savedata(filename,data,joiner)
+ local f = io.open(filename,"wb")
+ if f then
+ if type(data) == "table" then
+ f:write(table.join(data,joiner or ""))
+ elseif type(data) == "function" then
+ data(f)
+ else
+ f:write(data)
+ end
+ f:close()
+ return true
+ else
+ return false
+ end
+end
+
+function io.exists(filename)
+ local f = io.open(filename)
+ if f == nil then
+ return false
+ else
+ assert(f:close())
+ return true
+ end
+end
+
+function io.size(filename)
+ local f = io.open(filename)
+ if f == nil then
+ return 0
+ else
+ local s = f:seek("end")
+ assert(f:close())
+ return s
+ end
+end
+
+function io.noflines(f)
+ local n = 0
+ for _ in f:lines() do
+ n = n + 1
+ end
+ f:seek('set',0)
+ return n
+end
+
+local nextchar = {
+ [ 4] = function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2] = function(f)
+ return f:read(1,1)
+ end,
+ [ 1] = function(f)
+ return f:read(1)
+ end,
+ [-2] = function(f)
+ local a, b = f:read(1,1)
+ return b, a
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ return d, c, b, a
+ end
+}
+
+function io.characters(f,n)
+ if f then
+ return nextchar[n or 1], f
+ else
+ return nil, nil
+ end
+end
+
+local nextbyte = {
+ [4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(a), byte(b), byte(c), byte(d)
+ else
+ return nil, nil, nil, nil
+ end
+ end,
+ [2] = function(f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(a), byte(b)
+ else
+ return nil, nil
+ end
+ end,
+ [1] = function (f)
+ local a = f:read(1)
+ if a then
+ return byte(a)
+ else
+ return nil
+ end
+ end,
+ [-2] = function (f)
+ local a, b = f:read(1,1)
+ if b then
+ return byte(b), byte(a)
+ else
+ return nil, nil
+ end
+ end,
+ [-4] = function(f)
+ local a, b, c, d = f:read(1,1,1,1)
+ if d then
+ return byte(d), byte(c), byte(b), byte(a)
+ else
+ return nil, nil, nil, nil
+ end
+ end
+}
+
+function io.bytes(f,n)
+ if f then
+ return nextbyte[n or 1], f
+ else
+ return nil, nil
+ end
+end
+
+function io.ask(question,default,options)
+ while true do
+ io.write(question)
+ if options then
+ io.write(string.format(" [%s]",table.concat(options,"|")))
+ end
+ if default then
+ io.write(string.format(" [%s]",default))
+ end
+ io.write(string.format(" "))
+ local answer = io.read()
+ answer = answer:gsub("^%s*(.*)%s*$","%1")
+ if answer == "" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for _,v in pairs(options) do
+ if v == answer then
+ return answer
+ end
+ end
+ local pattern = "^" .. answer
+ for _,v in pairs(options) do
+ if v:find(pattern) then
+ return v
+ end
+ end
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['luat-dum'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local dummyfunction = function() end
+
+statistics = {
+ register = dummyfunction,
+ starttiming = dummyfunction,
+ stoptiming = dummyfunction,
+}
+trackers = {
+ register = dummyfunction,
+ enable = dummyfunction,
+ disable = dummyfunction,
+}
+storage = {
+ register = dummyfunction,
+ shared = { },
+}
+logs = {
+ report = dummyfunction,
+ simple = dummyfunction,
+}
+tasks = {
+ new = dummyfunction,
+ actions = dummyfunction,
+ appendaction = dummyfunction,
+ prependaction = dummyfunction,
+}
+
+-- we need to cheat a bit here
+
+texconfig.kpse_init = true
+
+resolvers = resolvers or { } -- no fancy file helpers used
+
+local remapper = {
+ otf = "opentype fonts",
+ ttf = "truetype fonts",
+ ttc = "truetype fonts",
+ cid = "other text files", -- will become "cid files"
+}
+
+function resolvers.find_file(name,kind)
+ name = string.gsub(name,"\\","\/")
+ kind = string.lower(kind)
+ return kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or "tex")
+end
+
+function resolvers.findbinfile(name,kind)
+ if not kind or kind == "" then
+ kind = file.extname(name) -- string.match(name,"%.([^%.]-)$")
+ end
+ return resolvers.find_file(name,(kind and remapper[kind]) or kind)
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['data-con'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, lower, gsub = string.format, string.lower, string.gsub
+
+local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end)
+local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
+local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
+local trace_verbose = false trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v trackers.enable("resolvers.verbose") end)
+
+--[[ldx--
+<p>Once we found ourselves defining similar cache constructs
+several times, containers were introduced. Containers are used
+to collect tables in memory and reuse them when possible based
+on (unique) hashes (to be provided by the calling function).</p>
+
+<p>Caching to disk is disabled by default. Version numbers are
+stored in the saved table which makes it possible to change the
+table structures without bothering about the disk cache.</p>
+
+<p>Examples of usage can be found in the font related code.</p>
+--ldx]]--
+
+containers = containers or { }
+
+containers.usecache = true
+
+local function report(container,tag,name)
+ if trace_cache or trace_containers then
+ logs.report(format("%s cache",container.subcategory),"%s: %s",tag,name or 'invalid')
+ end
+end
+
+local allocated = { }
+
+-- tracing
+
+function containers.define(category, subcategory, version, enabled)
+ return function()
+ if category and subcategory then
+ local c = allocated[category]
+ if not c then
+ c = { }
+ allocated[category] = c
+ end
+ local s = c[subcategory]
+ if not s then
+ s = {
+ category = category,
+ subcategory = subcategory,
+ storage = { },
+ enabled = enabled,
+ version = version or 1.000,
+ trace = false,
+ path = caches and caches.setpath and caches.setpath(category,subcategory),
+ }
+ c[subcategory] = s
+ end
+ return s
+ else
+ return nil
+ end
+ end
+end
+
+function containers.is_usable(container, name)
+ return container.enabled and caches and caches.iswritable(container.path, name)
+end
+
+function containers.is_valid(container, name)
+ if name and name ~= "" then
+ local storage = container.storage[name]
+ return storage and not table.is_empty(storage) and storage.cache_version == container.version
+ else
+ return false
+ end
+end
+
+function containers.read(container,name)
+ if container.enabled and caches and not container.storage[name] and containers.usecache then
+ container.storage[name] = caches.loaddata(container.path,name)
+ if containers.is_valid(container,name) then
+ report(container,"loaded",name)
+ else
+ container.storage[name] = nil
+ end
+ end
+ if container.storage[name] then
+ report(container,"reusing",name)
+ end
+ return container.storage[name]
+end
+
+function containers.write(container, name, data)
+ if data then
+ data.cache_version = container.version
+ if container.enabled and caches then
+ local unique, shared = data.unique, data.shared
+ data.unique, data.shared = nil, nil
+ caches.savedata(container.path, name, data)
+ report(container,"saved",name)
+ data.unique, data.shared = unique, shared
+ end
+ report(container,"stored",name)
+ container.storage[name] = data
+ end
+ return data
+end
+
+function containers.content(container,name)
+ return container.storage[name]
+end
+
+function containers.cleanname(name)
+ return (gsub(lower(name),"[^%w%d]+","-"))
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['node-ini'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Most of the code that had accumulated here is now separated in
+modules.</p>
+--ldx]]--
+
+-- this module is being reconstructed
+
+local utf = unicode.utf8
+local next, type = next, type
+local format, concat, match, utfchar = string.format, table.concat, string.match, utf.char
+
+local chardata = characters and characters.data
+
+--[[ldx--
+<p>We start with a registration system for atributes so that we can use the
+symbolic names later on.</p>
+--ldx]]--
+
+attributes = attributes or { }
+
+attributes.names = attributes.names or { }
+attributes.numbers = attributes.numbers or { }
+attributes.list = attributes.list or { }
+attributes.unsetvalue = -0x7FFFFFFF
+
+storage.register("attributes/names", attributes.names, "attributes.names")
+storage.register("attributes/numbers", attributes.numbers, "attributes.numbers")
+storage.register("attributes/list", attributes.list, "attributes.list")
+
+local names, numbers, list = attributes.names, attributes.numbers, attributes.list
+
+function attributes.define(name,number) -- at the tex end
+ if not numbers[name] then
+ numbers[name], names[number], list[number] = number, name, { }
+ end
+end
+
+--[[ldx--
+<p>We can use the attributes in the range 127-255 (outside user space). These
+are only used when no attribute is set at the \TEX\ end which normally
+happens in <l n='context'/>.</p>
+--ldx]]--
+
+storage.shared.attributes_last_private = storage.shared.attributes_last_private or 127
+
+function attributes.private(name) -- at the lua end (hidden from user)
+ local number = numbers[name]
+ if not number then
+ local last = storage.shared.attributes_last_private or 127
+ if last < 255 then
+ last = last + 1
+ storage.shared.attributes_last_private = last
+ end
+ number = last
+ numbers[name], names[number], list[number] = number, name, { }
+ end
+ return number
+end
+
+--[[ldx--
+<p>Access to nodes is what gives <l n='luatex'/> its power. Here we
+implement a few helper functions. These functions are rather optimized.</p>
+--ldx]]--
+
+--[[ldx--
+<p>When manipulating node lists in <l n='context'/>, we will remove
+nodes and insert new ones. While node access was implemented, we did
+quite some experiments in order to find out if manipulating nodes
+in <l n='lua'/> was feasible from the perspective of performance.</p>
+
+<p>First of all, we noticed that the bottleneck is more with excessive
+callbacks (some gets called very often) and the conversion from and to
+<l n='tex'/>'s datastructures. However, at the <l n='lua'/> end, we
+found that inserting and deleting nodes in a table could become a
+bottleneck.</p>
+
+<p>This resulted in two special situations in passing nodes back to
+<l n='tex'/>: a table entry with value <type>false</type> is ignored,
+and when instead of a table <type>true</type> is returned, the
+original table is used.</p>
+
+<p>Insertion is handled (at least in <l n='context'/> as follows. When
+we need to insert a node at a certain position, we change the node at
+that position by a dummy node, tagged <type>inline</type> which itself
+has_attribute the original node and one or more new nodes. Before we pass
+back the list we collapse the list. Of course collapsing could be built
+into the <l n='tex'/> engine, but this is a not so natural extension.</p>
+
+<p>When we collapse (something that we only do when really needed), we
+also ignore the empty nodes. [This is obsolete!]</p>
+--ldx]]--
+
+nodes = nodes or { }
+
+local hlist = node.id('hlist')
+local vlist = node.id('vlist')
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local penalty = node.id('penalty')
+local kern = node.id('kern')
+local whatsit = node.id('whatsit')
+
+local traverse_id = node.traverse_id
+local traverse = node.traverse
+local slide_nodes = node.slide
+local free_node = node.free
+local remove_node = node.remove
+
+function nodes.remove(head, current, free_too)
+ local t = current
+ head, current = remove_node(head,current)
+ if t then
+ if free_too then
+ free_node(t)
+ t = nil
+ else
+ t.next, t.prev = nil, nil
+ end
+ end
+ return head, current, t
+end
+
+function nodes.delete(head,current)
+ return nodes.remove(head,current,true)
+end
+
+nodes.before = node.insert_before -- broken
+nodes.after = node.insert_after
+
+-- we need to test this, as it might be fixed
+
+function nodes.before(h,c,n)
+ if c then
+ if c == h then
+ n.next = h
+ n.prev = nil
+ h.prev = n
+ else
+ local cp = c.prev
+ n.next = c
+ n.prev = cp
+ if cp then
+ cp.next = n
+ end
+ c.prev = n
+ return h, n
+ end
+ end
+ return n, n
+end
+
+function nodes.after(h,c,n)
+ if c then
+ local cn = c.next
+ if cn then
+ n.next = cn
+ cn.prev = n
+ else
+ n.next = nil
+ end
+ c.next = n
+ n.prev = c
+ return h, n
+ end
+ return n, n
+end
+
+function nodes.replace(head,current,new)
+ if current and next then
+ local p, n = current.prev, current.next
+ new.prev, new.next = p, n
+ if p then
+ p.next = new
+ else
+ head = new
+ end
+ if n then
+ n.prev = new
+ end
+ free_node(current)
+ end
+ return head, current
+end
+
+-- will move
+
+local function count(stack,flat)
+ local n = 0
+ while stack do
+ local id = stack.id
+ if not flat and id == hlist or id == vlist then
+ local list = stack.list
+ if list then
+ n = n + 1 + count(list) -- self counts too
+ else
+ n = n + 1
+ end
+ else
+ n = n + 1
+ end
+ stack = stack.next
+ end
+ return n
+end
+
+nodes.count = count
+
+-- new
+
+function attributes.ofnode(n)
+ local a = n.attr
+ if a then
+ local names = attributes.names
+ a = a.next
+ while a do
+ local number, value = a.number, a.value
+ texio.write_nl(format("%s : attribute %3i, value %4i, name %s",tostring(n),number,value,names[number] or '?'))
+ a = a.next
+ end
+ end
+end
+
+local left, space = lpeg.P("<"), lpeg.P(" ")
+
+nodes.filterkey = left * (1-left)^0 * left * space^0 * lpeg.C((1-space)^0)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['node-res'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local gmatch, format = string.gmatch, string.format
+local copy_node, free_node, new_node = node.copy, node.free, node.new
+
+--[[ldx--
+<p>The next function is not that much needed but in <l n='context'/> we use
+for debugging <l n='luatex'/> node management.</p>
+--ldx]]--
+
+nodes = nodes or { }
+
+local reserved = { }
+
+function nodes.register(n)
+ reserved[#reserved+1] = n
+ return n
+end
+
+function nodes.cleanup_reserved(nofboxes) -- todo
+ nodes.tracers.steppers.reset() -- todo: make a registration subsystem
+ local nr, nl = #reserved, 0
+ for i=1,nr do
+ free_node(reserved[i])
+ end
+ if nofboxes then
+ local tb = tex.box
+ for i=0,nofboxes do
+ local l = tb[i]
+ if l then
+ free_node(tb[i])
+ nl = nl + 1
+ end
+ end
+ end
+ reserved = { }
+ return nr, nl, nofboxes -- can be nil
+end
+
+function nodes.usage()
+ local t = { }
+ for n, tag in gmatch(status.node_mem_usage,"(%d+) ([a-z_]+)") do
+ t[tag] = n
+ end
+ return t
+end
+
+local pdfliteral = nodes.register(new_node("whatsit",8)) pdfliteral.mode = 1
+local disc = nodes.register(new_node("disc"))
+local kern = nodes.register(new_node("kern",1))
+local penalty = nodes.register(new_node("penalty"))
+local glue = nodes.register(new_node("glue"))
+local glue_spec = nodes.register(new_node("glue_spec"))
+local glyph = nodes.register(new_node("glyph",0))
+local textdir = nodes.register(new_node("whatsit",7))
+
+function nodes.glyph(fnt,chr)
+ local n = copy_node(glyph)
+ if fnt then n.font = fnt end
+ if chr then n.char = chr end
+ return n
+end
+function nodes.penalty(p)
+ local n = copy_node(penalty)
+ n.penalty = p
+ return n
+end
+function nodes.kern(k)
+ local n = copy_node(kern)
+ n.kern = k
+ return n
+end
+function nodes.glue(width,stretch,shrink)
+ local n, s = copy_node(glue), copy_node(glue_spec)
+ s.width, s.stretch, s.shrink = width, stretch, shrink
+ n.spec = s
+ return n
+end
+function nodes.glue_spec(width,stretch,shrink)
+ local s = copy_node(glue_spec)
+ s.width, s.stretch, s.shrink = width, stretch, shrink
+ return s
+end
+function nodes.disc()
+ return copy_node(disc)
+end
+function nodes.pdfliteral(str)
+ local t = copy_node(pdfliteral)
+ t.data = str
+ return t
+end
+function nodes.textdir(dir)
+ local t = copy_node(textdir)
+ t.dir = dir
+ return t
+end
+
+statistics.register("cleaned up reserved nodes", function()
+ return format("%s nodes, %s lists of %s", nodes.cleanup_reserved(tex.count["lastallocatedbox"]))
+end) -- \topofboxstack
+
+statistics.register("node memory usage", function() -- comes after cleanup !
+ return status.node_mem_usage
+end)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['node-inj'] = {
+ version = 1.001,
+ comment = "companion to node-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- tricky ... fonts.ids is not yet defined .. to be solved (maybe general tex ini)
+
+-- This is very experimental (this will change when we have luatex > .50 and
+-- a few pending thingies are available. Also, Idris needs to make a few more
+-- test fonts.
+
+local next = next
+
+local trace_injections = false trackers.register("nodes.injections", function(v) trace_injections = v end)
+
+fonts = fonts or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+
+local fontdata = fonts.ids
+
+local glyph = node.id('glyph')
+local kern = node.id('kern')
+
+local traverse_id = node.traverse_id
+local has_attribute = node.has_attribute
+local set_attribute = node.set_attribute
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+
+local newkern = nodes.kern
+
+local markbase = attributes.private('markbase')
+local markmark = attributes.private('markmark')
+local markdone = attributes.private('markdone')
+local cursbase = attributes.private('cursbase')
+local curscurs = attributes.private('curscurs')
+local cursdone = attributes.private('cursdone')
+local kernpair = attributes.private('kernpair')
+
+local cursives = { }
+local marks = { }
+local kerns = { }
+
+-- currently we do gpos/kern in a bit inofficial way but when we
+-- have the extra fields in glyphnodes to manipulate ht/dp/wd
+-- explicitly i will provide an alternative; also, we can share
+-- tables
+
+function nodes.set_cursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext)
+ local dx, dy = factor*(exit[1]-entry[1]), factor*(exit[2]-entry[2])
+ local ws, wn = tfmstart.width, tfmnext.width
+ local bound = #cursives + 1
+ set_attribute(start,cursbase,bound)
+ set_attribute(nxt,curscurs,bound)
+ cursives[bound] = { rlmode, dx, dy, ws, wn }
+ return dx, dy, bound
+end
+
+function nodes.set_pair(current,factor,rlmode,spec,tfmchr)
+ local x, y, w, h = factor*spec[1], factor*spec[2], factor*spec[3], factor*spec[4]
+ -- dy = y - h
+ if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then
+ local bound = has_attribute(current,kernpair)
+ if bound then
+ local kb = kerns[bound]
+ kb[2], kb[3], kb[4], kb[5] = kb[2] + x, kb[3] + y, kb[4] + w, kb[5] + h
+ else
+ bound = #kerns + 1
+ set_attribute(current,kernpair,bound)
+ kerns[bound] = { rlmode, x, y, w, h }
+ end
+ return x, y, w, h, bound
+ end
+ return x, y, w, h -- no bound
+end
+
+function nodes.set_kern(current,factor,rlmode,x,tfmchr)
+ local dx = factor*x
+ if dx ~= 0 then
+ local bound = #kerns + 1
+ set_attribute(current,kernpair,bound)
+ kerns[bound] = { rlmode, dx }
+ end
+ return dx, bound
+end
+
+function nodes.set_mark(start,base,factor,rlmode,ba,ma,index) --ba=baseanchor, ma=markanchor
+ local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2])
+ local bound = has_attribute(base,markbase)
+ if bound then
+ local mb = marks[bound]
+ if mb then
+ if not index then index = #mb + 1 end
+ mb[index] = { dx, dy }
+ set_attribute(start,markmark,bound)
+ set_attribute(start,markdone,index)
+ return dx, dy, bound
+ else
+ logs.report("nodes mark", "possible problem, U+%04X is base without data (id: %s)",base.char,bound)
+ end
+ end
+ index = index or 1
+ bound = #marks + 1
+ set_attribute(base,markbase,bound)
+ set_attribute(start,markmark,bound)
+ set_attribute(start,markdone,index)
+ marks[bound] = { [index] = { dx, dy } }
+ return dx, dy, bound
+end
+
+function nodes.trace_injection(head)
+ local function dir(n)
+ return (n<0 and "r-to-l") or (n>0 and "l-to-r") or ("unset")
+ end
+ local function report(...)
+ logs.report("nodes finisher",...)
+ end
+ report("begin run")
+ for n in traverse_id(glyph,head) do
+ if n.subtype < 256 then
+ local kp = has_attribute(n,kernpair)
+ local mb = has_attribute(n,markbase)
+ local mm = has_attribute(n,markmark)
+ local md = has_attribute(n,markdone)
+ local cb = has_attribute(n,cursbase)
+ local cc = has_attribute(n,curscurs)
+ report("char U+%05X, font=%s",n.char,n.font)
+ if kp then
+ local k = kerns[kp]
+ if k[3] then
+ report(" pairkern: dir=%s, x=%s, y=%s, w=%s, h=%s",dir(k[1]),k[2],k[3],k[4],k[5])
+ else
+ report(" kern: dir=%s, dx=%s",dir(k[1]),k[2])
+ end
+ end
+ if mb then
+ report(" markbase: bound=%s",mb)
+ end
+ if mm then
+ local m = marks[mm]
+ if mb then
+ local m = m[mb]
+ if m then
+ report(" markmark: bound=%s, index=%s, dx=%s, dy=%s",mm,j,m[1],m[2])
+ else
+ report(" markmark: bound=%s, missing index",mm)
+ end
+ else
+ m = m[1]
+ report(" markmark: bound=%s, dx=%s, dy=%s",mm,m[1],m[2])
+ end
+ end
+ if cb then
+ report(" cursbase: bound=%s",cb)
+ end
+ if cc then
+ local c = cursives[cc]
+ report(" curscurs: bound=%s, dir=%s, dx=%s, dy=%s",cc,dir(c[1]),c[2],c[3])
+ end
+ end
+ end
+ report("end run")
+end
+
+-- todo: reuse tables (i.e. no collection), but will be extra fields anyway
+
+function nodes.inject_kerns(head,tail,keep)
+ if trace_injections then
+ nodes.trace_injection(head)
+ end
+ local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns)
+ if has_marks or has_cursives then
+ -- in the future variant we will not copy items but refs to tables
+ local done, ky, rl, valid, cx, wx = false, { }, { }, { }, { }, { }
+ for n in traverse_id(glyph,head) do
+ if n.subtype < 256 then
+ valid[#valid+1] = n
+ if has_kerns then -- move outside loop
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ local x, y, w, h = kk[2], kk[3], kk[4], kk[5]
+ local dy = y - h
+ if dy ~= 0 then
+ ky[n] = dy
+ end
+ if w ~= 0 or x ~= 0 then
+ wx[n] = kk
+ end
+ rl[n] = kk[1] -- could move in test
+ end
+ end
+ end
+ end
+ end
+ if #valid > 0 then
+ -- we can assume done == true because we have cursives and marks
+ local cx = { }
+ if has_kerns and next(ky) then
+ for n, k in next, ky do
+ n.yoffset = k
+ end
+ end
+ -- todo: reuse t and use maxt
+ if has_cursives then
+ local n_cursbase, n_curscurs, p_cursbase, n, p, nf, tm = nil, nil, nil, nil, nil, nil, nil
+ -- since we need valid[n+1] we can also use a "while true do"
+ local t, d, maxt = { }, { }, 0
+ for i=1,#valid do -- valid == glyphs
+ n = valid[i]
+ if n.font ~= nf then
+ nf = n.font
+ tm = fontdata[nf].marks
+ -- maybe flush
+ maxt = 0
+ end
+ if not tm[n.char] then
+ n_cursbase = has_attribute(n,cursbase)
+ n_curscurs = has_attribute(n,curscurs)
+ if p_cursbase then
+ if p_cursbase == n_curscurs then
+ local c = cursives[n_curscurs]
+ if c then
+ local rlmode, dx, dy, ws, wn = c[1], c[2], c[3], c[4], c[5]
+ if rlmode >= 0 then
+ dx = dx - ws
+ else
+ dx = dx + wn
+ end
+ if dx ~= 0 then
+ cx[n] = dx
+ rl[n] = rlmode
+ end
+ -- if rlmode and rlmode < 0 then
+ dy = -dy
+ -- end
+ maxt = maxt + 1
+ t[maxt] = p
+ d[maxt] = dy
+ else
+ maxt = 0
+ end
+ end
+ elseif maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = t[i].yoffset + ny
+ end
+ maxt = 0
+ end
+ if not n_cursbase and maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ p_cursbase, p = n_cursbase, n
+ end
+ end
+ if maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ if not keep then
+ cursives = { }
+ end
+ end
+ if has_marks then
+ local p_markbase, n_markmark = nil, nil
+ for i=1,#valid do
+ local p = valid[i]
+ p_markbase = has_attribute(p,markbase)
+ if p_markbase then
+ local mrks = marks[p_markbase]
+ for n in traverse_id(glyph,p.next) do
+ n_markmark = has_attribute(n,markmark)
+ if p_markbase == n_markmark then
+ local index = has_attribute(n,markdone) or 1
+ local d = mrks[index]
+ if d then
+ -- local rlmode = d[3] -- not used
+ -- if rlmode and rlmode < 0 then
+ -- n.xoffset = p.xoffset + d[1]
+ -- else
+ n.xoffset = p.xoffset - d[1]
+ -- end
+ n.yoffset = p.yoffset + d[2]
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ if not keep then
+ marks = { }
+ end
+ end
+ -- todo : combine
+ if next(wx) then
+ for n, k in next, wx do
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, w = k[1], k[2] or 0, k[4] or 0
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ if next(cx) then
+ for n, k in next, cx do
+ if k ~= 0 then
+ local rln = rl[n]
+ if rln and rln < 0 then
+ insert_node_before(head,n,newkern(-k))
+ else
+ insert_node_before(head,n,newkern(k))
+ end
+ end
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ elseif not keep then
+ kerns, cursives, marks = { }, { }, { }
+ end
+ elseif has_kerns then
+ -- we assume done is true because there are kerns
+ for n in traverse_id(glyph,head) do
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, y, w = kk[1], kk[2] or 0, kk[3] or 0, kk[4] or 0
+ if y ~= 0 then
+ n.yoffset = y -- todo: h ?
+ end
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ end
+ return head, false
+end
+
+-- -- -- KEEP OLD ONE, THE NEXT IS JUST OPTIMIZED -- -- --
+
+function nodes.XXXXXXXxinject_kerns(head,tail,keep)
+ if trace_injections then
+ nodes.trace_injection(head)
+ end
+ local has_marks, has_cursives, has_kerns = next(marks), next(cursives), next(kerns)
+ if has_marks or has_cursives then
+ -- in the future variant we will not copy items but refs to tables
+ local done, ky, valid, cx, wx = false, { }, { }, { }, { }
+ for n in traverse_id(glyph,head) do
+ if n.subtype < 256 then
+ valid[#valid+1] = n
+ if has_kerns then -- move outside loop
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ local x, y, w, h = kk[2], kk[3], kk[4], kk[5]
+ local dy = y - h
+ if dy ~= 0 then
+ ky[n] = dy
+ end
+ if w ~= 0 or x ~= 0 then
+ wx[n] = kk
+ end
+ end
+ end
+ end
+ end
+ end
+ if #valid > 0 then
+ -- we can assume done == true because we have cursives and marks
+ local cx = { }
+ if has_kerns and next(ky) then
+ for n, k in next, ky do
+ n.yoffset = k
+ end
+ end
+ -- todo: reuse t and use maxt
+ if has_cursives then
+ local n_cursbase, n_curscurs, p_cursbase, n, p, nf, tm = nil, nil, nil, nil, nil, nil, nil
+ -- since we need valid[n+1] we can also use a "while true do"
+ local t, d, maxt = { }, { }, 0
+ for i=1,#valid do -- valid == glyphs
+ n = valid[i]
+ if n.font ~= nf then
+ nf = n.font
+ tm = fontdata[nf].marks
+ -- maybe flush
+ maxt = 0
+ end
+ if not tm[n.char] then
+ n_cursbase = has_attribute(n,cursbase)
+ n_curscurs = has_attribute(n,curscurs)
+ if p_cursbase then
+ if p_cursbase == n_curscurs then
+ local c = cursives[n_curscurs]
+ if c then
+ local rlmode, dx, dy, ws, wn = c[1], c[2], c[3], c[4], c[5]
+ if rlmode >= 0 then
+ dx = dx - ws
+ else
+ dx = dx + wn
+ end
+ if dx ~= 0 then
+if rlmode < 0 then
+ cx[n] = -dx
+else
+ cx[n] = dx
+end
+ end
+ -- if rlmode and rlmode < 0 then
+ dy = -dy
+ -- end
+ maxt = maxt + 1
+ t[maxt] = p
+ d[maxt] = dy
+ else
+ maxt = 0
+ end
+ end
+ elseif maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = t[i].yoffset + ny
+ end
+ maxt = 0
+ end
+ if not n_cursbase and maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ p_cursbase, p = n_cursbase, n
+ end
+ end
+ if maxt > 0 then
+ local ny = n.yoffset
+ for i=maxt,1,-1 do
+ ny = ny + d[i]
+ t[i].yoffset = ny
+ end
+ maxt = 0
+ end
+ if not keep then
+ cursives = { }
+ end
+ end
+ if has_marks then
+ local p_markbase, n_markmark = nil, nil
+ for i=1,#valid do
+ local p = valid[i]
+ p_markbase = has_attribute(p,markbase)
+ if p_markbase then
+ local mrks = marks[p_markbase]
+ for n in traverse_id(glyph,p.next) do
+ n_markmark = has_attribute(n,markmark)
+ if p_markbase == n_markmark then
+ local index = has_attribute(n,markdone) or 1
+ local d = mrks[index]
+ if d then
+ local d1, d2 = d[1], d[2]
+ if d1 ~= 0 then
+ n.xoffset = p.xoffset - d[1]
+ end
+ if d2 ~= 0 then
+ n.yoffset = p.yoffset + d[2]
+ end
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ if not keep then
+ marks = { }
+ end
+ end
+ -- todo : combine
+ if next(wx) then
+ for n, k in next, wx do
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, w = k[1], k[2] or 0, k[4] or 0
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ if next(cx) then
+ for n, k in next, cx do
+ insert_node_before(head,n,newkern(k))
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ elseif not keep then
+ kerns, cursives, marks = { }, { }, { }
+ end
+ elseif has_kerns then
+ -- we assume done is true because there are kerns
+ for n in traverse_id(glyph,head) do
+ local k = has_attribute(n,kernpair)
+ if k then
+ local kk = kerns[k]
+ if kk then
+ -- only w can be nil, can be sped up when w == nil
+ local rl, x, y, w = kk[1], kk[2] or 0, kk[3] or 0, kk[4] or 0
+ if y ~= 0 then
+ n.yoffset = y -- todo: h ?
+ end
+ local wx = w - x
+ if rl < 0 then
+ if wx ~= 0 then
+ insert_node_before(head,n,newkern(wx))
+ end
+ if x ~= 0 then
+ insert_node_after (head,n,newkern(x))
+ end
+ else
+ -- if wx ~= 0 then
+ -- insert_node_after(head,n,newkern(wx))
+ -- end
+ if x ~= 0 then
+ insert_node_before(head,n,newkern(x))
+ end
+ end
+ end
+ end
+ end
+ if not keep then
+ kerns = { }
+ end
+ return head, true
+ end
+ return head, false
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['node-fnt'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+
+local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end)
+
+local glyph = node.id('glyph')
+
+local traverse_id = node.traverse_id
+local has_attribute = node.has_attribute
+
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+
+fonts = fonts or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+
+local fontdata = fonts.ids
+
+-- some tests with using an array of dynamics[id] and processes[id] demonstrated
+-- that there was nothing to gain (unless we also optimize other parts)
+--
+-- maybe getting rid of the intermediate shared can save some time
+
+-- potential speedup: check for subtype < 256 so that we can remove that test
+-- elsewhere, danger: injected nodes will not be dealt with but that does not
+-- happen often; we could consider processing sublists but that might need mor
+-- checking later on; the current approach also permits variants
+
+if tex.attribute[0] < 0 then
+
+ texio.write_nl("log","!")
+ texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+ texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+ texio.write_nl("log","! purposed so setting them at the TeX end might break the font handler.")
+ texio.write_nl("log","!")
+
+ tex.attribute[0] = 0 -- else no features
+
+end
+
+function nodes.process_characters(head)
+ -- either next or not, but definitely no already processed list
+ starttiming(nodes)
+ local usedfonts, attrfonts, done = { }, { }, false
+ local a, u, prevfont, prevattr = 0, 0, nil, 0
+ for n in traverse_id(glyph,head) do
+ local font, attr = n.font, has_attribute(n,0) -- zero attribute is reserved for fonts, preset to 0 is faster (first match)
+ if attr and attr > 0 then
+ if font ~= prevfont or attr ~= prevattr then
+ local used = attrfonts[font]
+ if not used then
+ used = { }
+ attrfonts[font] = used
+ end
+ if not used[attr] then
+ -- we do some testing outside the function
+ local tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ if shared then
+ local dynamics = shared.dynamics
+ if dynamics then
+ local d = shared.set_dynamics(font,dynamics,attr) -- still valid?
+ if d then
+ used[attr] = d
+ a = a + 1
+ end
+ end
+ end
+ end
+ prevfont, prevattr = font, attr
+ end
+ elseif font ~= prevfont then
+ prevfont, prevattr = font, 0
+ local used = usedfonts[font]
+ if not used then
+ local tfmdata = fontdata[font]
+ if tfmdata then
+ local shared = tfmdata.shared -- we need to check shared, only when same features
+ if shared then
+ local processors = shared.processes
+ if processors and #processors > 0 then
+ usedfonts[font] = processors
+ u = u + 1
+ end
+ end
+ else
+ -- probably nullfont
+ end
+ end
+ else
+ prevattr = attr
+ end
+ end
+ -- we could combine these and just make the attribute nil
+ if u == 1 then
+ local font, processors = next(usedfonts)
+ local n = #processors
+ if n > 0 then
+ local h, d = processors[1](head,font,false)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,0) -- false)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ elseif u > 0 then
+ for font, processors in next, usedfonts do
+ local n = #processors
+ local h, d = processors[1](head,font,false)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,0) -- false)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ end
+ if a == 1 then
+ local font, dynamics = next(attrfonts)
+ for attribute, processors in next, dynamics do -- attr can switch in between
+ local n = #processors
+ local h, d = processors[1](head,font,attribute)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,attribute)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ elseif a > 0 then
+ for font, dynamics in next, attrfonts do
+ for attribute, processors in next, dynamics do -- attr can switch in between
+ local n = #processors
+ local h, d = processors[1](head,font,attribute)
+ head, done = h or head, done or d
+ if n > 1 then
+ for i=2,n do
+ local h, d = processors[i](head,font,attribute)
+ head, done = h or head, done or d
+ end
+ end
+ end
+ end
+ end
+ stoptiming(nodes)
+ if trace_characters then
+ nodes.report(head,done)
+ end
+ return head, true
+end
+
+if node.protect_glyphs then
+
+ nodes.protect_glyphs = node.protect_glyphs
+ nodes.unprotect_glyphs = node.unprotect_glyphs
+
+else do
+
+ -- initial value subtype : X000 0001 = 1 = 0x01 = char
+ --
+ -- expected before linebreak : X000 0000 = 0 = 0x00 = glyph
+ -- X000 0010 = 2 = 0x02 = ligature
+ -- X000 0100 = 4 = 0x04 = ghost
+ -- X000 1010 = 10 = 0x0A = leftboundary lig
+ -- X001 0010 = 18 = 0x12 = rightboundary lig
+ -- X001 1010 = 26 = 0x1A = both boundaries lig
+ -- X000 1100 = 12 = 0x1C = leftghost
+ -- X001 0100 = 20 = 0x14 = rightghost
+
+
+ function nodes.protect_glyphs(head)
+ local done = false
+ for g in traverse_id(glyph,head) do
+ local s = g.subtype
+ if s == 1 then
+ done, g.subtype = true, 256
+ elseif s <= 256 then
+ done, g.subtype = true, 256 + s
+ end
+ end
+ return done
+ end
+
+ function nodes.unprotect_glyphs(head)
+ local done = false
+ for g in traverse_id(glyph,head) do
+ local s = g.subtype
+ if s > 256 then
+ done, g.subtype = true, s - 256
+ end
+ end
+ return done
+ end
+
+end end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['node-dum'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+nodes = nodes or { }
+
+function nodes.simple_font_dummy(head,tail)
+ return tail
+end
+
+function nodes.simple_font_handler(head)
+ local tail = node.slide(head)
+-- lang.hyphenate(head,tail)
+ head = nodes.process_characters(head,tail)
+ nodes.inject_kerns(head)
+ nodes.protect_glyphs(head)
+ tail = node.ligaturing(head,tail)
+ tail = node.kerning(head,tail)
+ return head
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-ini'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Not much is happening here.</p>
+--ldx]]--
+
+local utf = unicode.utf8
+
+if not fontloader then fontloader = fontforge end
+
+fontloader.totable = fontloader.to_table
+
+-- vtf comes first
+-- fix comes last
+
+fonts = fonts or { }
+fonts.ids = fonts.ids or { } -- aka fontdata
+fonts.tfm = fonts.tfm or { }
+
+fonts.mode = 'base'
+fonts.private = 0xF0000 -- 0x10FFFF
+fonts.verbose = false -- more verbose cache tables
+
+fonts.methods = fonts.methods or {
+ base = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
+ node = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
+}
+
+fonts.initializers = fonts.initializers or {
+ base = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } },
+ node = { tfm = { }, afm = { }, otf = { }, vtf = { }, fix = { } }
+}
+
+fonts.triggers = fonts.triggers or {
+ 'mode',
+ 'language',
+ 'script',
+ 'strategy',
+}
+
+fonts.processors = fonts.processors or {
+}
+
+fonts.manipulators = fonts.manipulators or {
+}
+
+fonts.define = fonts.define or { }
+fonts.define.specify = fonts.define.specify or { }
+fonts.define.specify.synonyms = fonts.define.specify.synonyms or { }
+
+-- tracing
+
+fonts.color = fonts.color or { }
+
+local attribute = attributes.private('color')
+local mapping = (attributes and attributes.list[attribute]) or { }
+
+local set_attribute = node.set_attribute
+local unset_attribute = node.unset_attribute
+
+function fonts.color.set(n,c)
+ local mc = mapping[c]
+ if not mc then
+ unset_attribute(n,attribute)
+ else
+ set_attribute(n,attribute,mc)
+ end
+end
+function fonts.color.reset(n)
+ unset_attribute(n,attribute)
+end
+
+-- this will change ...
+
+function fonts.show_char_data(n)
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata then
+ if type(n) == "string" then
+ n = utf.byte(n)
+ end
+ local chr = tfmdata.characters[n]
+ if chr then
+ texio.write_nl(table.serialize(chr,string.format("U_%04X",n)))
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-tfm'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utf = unicode.utf8
+
+local next, format, match, lower = next, string.format, string.match, string.lower
+local concat, sortedkeys, utfbyte, serialize = table.concat, table.sortedkeys, utf.byte, table.serialize
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+local trace_scaling = false trackers.register("fonts.scaling" , function(v) trace_scaling = v end)
+
+-- tfmdata has also fast access to indices and unicodes
+-- to be checked: otf -> tfm -> tfmscaled
+--
+-- watch out: no negative depths and negative eights permitted in regular fonts
+
+--[[ldx--
+<p>Here we only implement a few helper functions.</p>
+--ldx]]--
+
+fonts = fonts or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+
+local tfm = fonts.tfm
+
+fonts.loaded = fonts.loaded or { }
+fonts.dontembed = fonts.dontembed or { }
+fonts.triggers = fonts.triggers or { } -- brrr
+fonts.initializers = fonts.initializers or { }
+fonts.initializers.common = fonts.initializers.common or { }
+
+local fontdata = fonts.ids
+local glyph = node.id('glyph')
+local set_attribute = node.set_attribute
+
+--[[ldx--
+<p>The next function encapsulates the standard <l n='tfm'/> loader as
+supplied by <l n='luatex'/>.</p>
+--ldx]]--
+
+tfm.resolve_vf = true -- false
+tfm.share_base_kerns = false -- true (.5 sec slower on mk but brings down mem from 410M to 310M, beware: then script/lang share too)
+tfm.mathactions = { }
+
+function tfm.enhance(tfmdata,specification)
+ local name, size = specification.name, specification.size
+ local encoding, filename = match(name,"^(.-)%-(.*)$") -- context: encoding-name.*
+ if filename and encoding and fonts.enc.known[encoding] then
+ local data = fonts.enc.load(encoding)
+ if data then
+ local characters = tfmdata.characters
+ tfmdata.encoding = encoding
+ local vector = data.vector
+ local original = { }
+ for k, v in next, characters do
+ v.name = vector[k]
+ v.index = k
+ original[k] = v
+ end
+ for k,v in next, data.unicodes do
+ if k ~= v then
+ if trace_defining then
+ logs.report("define font","mapping %s onto %s",k,v)
+ end
+ characters[k] = original[v]
+ end
+ end
+ end
+ end
+end
+
+function tfm.read_from_tfm(specification)
+ local fname, tfmdata = specification.filename or "", nil
+ if fname ~= "" then
+ if trace_defining then
+ logs.report("define font","loading tfm file %s at size %s",fname,specification.size)
+ end
+ tfmdata = font.read_tfm(fname,specification.size) -- not cached, fast enough
+ if tfmdata then
+ tfmdata.descriptions = tfmdata.descriptions or { }
+ if tfm.resolve_vf then
+ fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here
+ fname = resolvers.findbinfile(specification.name, 'ovf')
+ if fname and fname ~= "" then
+ local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough
+ if vfdata then
+ local chars = tfmdata.characters
+ for k,v in next, vfdata.characters do
+ chars[k].commands = v.commands
+ end
+ tfmdata.type = 'virtual'
+ tfmdata.fonts = vfdata.fonts
+ end
+ end
+ end
+ tfm.enhance(tfmdata,specification)
+ end
+ elseif trace_defining then
+ logs.report("define font","loading tfm with name %s fails",specification.name)
+ end
+ return tfmdata
+end
+
+--[[ldx--
+<p>We need to normalize the scale factor (in scaled points). This has to
+do with the fact that <l n='tex'/> uses a negative multiple of 1000 as
+a signal for a font scaled based on the design size.</p>
+--ldx]]--
+
+local factors = {
+ pt = 65536.0,
+ bp = 65781.8,
+}
+
+function tfm.setfactor(f)
+ tfm.factor = factors[f or 'pt'] or factors.pt
+end
+
+tfm.setfactor()
+
+function tfm.scaled(scaledpoints, designsize) -- handles designsize in sp as well
+ if scaledpoints < 0 then
+ if designsize then
+ if designsize > tfm.factor then -- or just 1000 / when? mp?
+ return (- scaledpoints/1000) * designsize -- sp's
+ else
+ return (- scaledpoints/1000) * designsize * tfm.factor
+ end
+ else
+ return (- scaledpoints/1000) * 10 * tfm.factor
+ end
+ else
+ return scaledpoints
+ end
+end
+
+--[[ldx--
+<p>Before a font is passed to <l n='tex'/> we scale it. Here we also need
+to scale virtual characters.</p>
+--ldx]]--
+
+function tfm.get_virtual_id(tfmdata)
+ -- since we don't know the id yet, we use 0 as signal
+ if not tfmdata.fonts then
+ tfmdata.type = "virtual"
+ tfmdata.fonts = { { id = 0 } }
+ return 1
+ else
+ tfmdata.fonts[#tfmdata.fonts+1] = { id = 0 }
+ return #tfmdata.fonts
+ end
+end
+
+function tfm.check_virtual_id(tfmdata, id)
+ if tfmdata and tfmdata.type == "virtual" then
+ if not tfmdata.fonts or #tfmdata.fonts == 0 then
+ tfmdata.type, tfmdata.fonts = "real", nil
+ else
+ local vfonts = tfmdata.fonts
+ for f=1,#vfonts do
+ local fnt = vfonts[f]
+ if fnt.id and fnt.id == 0 then
+ fnt.id = id
+ end
+ end
+ end
+ end
+end
+
+--[[ldx--
+<p>Beware, the boundingbox is passed as reference so we may not overwrite it
+in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
+excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p>
+--ldx]]--
+
+fonts.trace_scaling = false
+
+-- the following hack costs a bit of runtime but safes memory
+--
+-- basekerns are scaled and will be hashed by table id
+-- sharedkerns are unscaled and are be hashed by concatenated indexes
+
+function tfm.check_base_kerns(tfmdata)
+ if tfm.share_base_kerns then
+ local sharedkerns = tfmdata.sharedkerns
+ if sharedkerns then
+ local basekerns = { }
+ tfmdata.basekerns = basekerns
+ return sharedkerns, basekerns
+ end
+ end
+ return nil, nil
+end
+
+function tfm.prepare_base_kerns(tfmdata)
+ if tfm.share_base_kerns and not tfmdata.sharedkerns then
+ local sharedkerns = { }
+ tfmdata.sharedkerns = sharedkerns
+ for u, chr in next, tfmdata.characters do
+ local kerns = chr.kerns
+ if kerns then
+ local hash = concat(sortedkeys(kerns), " ")
+ local base = sharedkerns[hash]
+ if not base then
+ sharedkerns[hash] = kerns
+ else
+ chr.kerns = base
+ end
+ end
+ end
+ end
+end
+
+-- we can have cache scaled characters when we are in node mode and don't have
+-- protruding and expansion: hash == fullname @ size @ protruding @ expansion
+-- but in practice (except from mk) the otf hash will be enough already so it
+-- makes no sense to mess up the code now
+
+local charactercache = { }
+
+-- The scaler is only used for otf and afm and virtual fonts. If
+-- a virtual font has italic correction make sur eto set the
+-- has_italic flag. Some more flags will be added in the future.
+
+function tfm.do_scale(tfmtable, scaledpoints)
+ tfm.prepare_base_kerns(tfmtable) -- optimalization
+ if scaledpoints < 0 then
+ scaledpoints = (- scaledpoints/1000) * tfmtable.designsize -- already in sp
+ end
+ local delta = scaledpoints/(tfmtable.units or 1000) -- brr, some open type fonts have 2048
+ local t = { }
+ -- unicoded unique descriptions shared cidinfo characters changed parameters indices
+ for k,v in next, tfmtable do
+ if type(v) == "table" then
+ -- print(k)
+ else
+ t[k] = v
+ end
+ end
+ -- status
+ local isvirtual = tfmtable.type == "virtual" or tfmtable.virtualized
+ local hasmath = tfmtable.math_parameters ~= nil or tfmtable.MathConstants ~= nil
+ local nodemode = tfmtable.mode == "node"
+ local hasquality = tfmtable.auto_expand or tfmtable.auto_protrude
+ local hasitalic = tfmtable.has_italic
+ --
+ t.parameters = { }
+ t.characters = { }
+ t.MathConstants = { }
+ -- fast access
+ local descriptions = tfmtable.descriptions or { }
+ t.unicodes = tfmtable.unicodes
+ t.indices = tfmtable.indices
+ t.marks = tfmtable.marks
+ t.descriptions = descriptions
+ if tfmtable.fonts then
+ t.fonts = table.fastcopy(tfmtable.fonts) -- hm also at the end
+ end
+ local tp = t.parameters
+ local mp = t.math_parameters
+ local tfmp = tfmtable.parameters -- let's check for indexes
+ --
+ tp.slant = (tfmp.slant or tfmp[1] or 0)
+ tp.space = (tfmp.space or tfmp[2] or 0)*delta
+ tp.space_stretch = (tfmp.space_stretch or tfmp[3] or 0)*delta
+ tp.space_shrink = (tfmp.space_shrink or tfmp[4] or 0)*delta
+ tp.x_height = (tfmp.x_height or tfmp[5] or 0)*delta
+ tp.quad = (tfmp.quad or tfmp[6] or 0)*delta
+ tp.extra_space = (tfmp.extra_space or tfmp[7] or 0)*delta
+ local protrusionfactor = (tp.quad ~= 0 and 1000/tp.quad) or 0
+ local tc = t.characters
+ local characters = tfmtable.characters
+ local nameneeded = not tfmtable.shared.otfdata --hack
+ local changed = tfmtable.changed or { } -- for base mode
+ local ischanged = not table.is_empty(changed)
+ local indices = tfmtable.indices
+ local luatex = tfmtable.luatex
+ local tounicode = luatex and luatex.tounicode
+ local defaultwidth = luatex and luatex.defaultwidth or 0
+ local defaultheight = luatex and luatex.defaultheight or 0
+ local defaultdepth = luatex and luatex.defaultdepth or 0
+ -- experimental, sharing kerns (unscaled and scaled) saves memory
+ local sharedkerns, basekerns = tfm.check_base_kerns(tfmtable)
+ -- loop over descriptions (afm and otf have descriptions, tfm not)
+ -- there is no need (yet) to assign a value to chr.tonunicode
+ local scaledwidth = defaultwidth * delta
+ local scaledheight = defaultheight * delta
+ local scaleddepth = defaultdepth * delta
+ local stackmath = tfmtable.ignore_stack_math ~= true
+ for k,v in next, characters do
+ local chr, description, index
+ if ischanged then
+ -- basemode hack
+ local c = changed[k]
+ if c then
+ description = descriptions[c] or v
+ v = characters[c] or v
+ index = (indices and indices[c]) or c
+ else
+ description = descriptions[k] or v
+ index = (indices and indices[k]) or k
+ end
+ else
+ description = descriptions[k] or v
+ index = (indices and indices[k]) or k
+ end
+ local width = description.width
+ local height = description.height
+ local depth = description.depth
+ if width then width = delta*width else width = scaledwidth end
+ if height then height = delta*height else height = scaledheight end
+ -- if depth then depth = delta*depth else depth = scaleddepth end
+ if depth and depth ~= 0 then
+ depth = delta*depth
+ if nameneeded then
+ chr = {
+ name = description.name,
+ index = index,
+ height = height,
+ depth = depth,
+ width = width,
+ }
+ else
+ chr = {
+ index = index,
+ height = height,
+ depth = depth,
+ width = width,
+ }
+ end
+ else
+ -- this saves a little bit of memory time and memory, esp for big cjk fonts
+ if nameneeded then
+ chr = {
+ name = description.name,
+ index = index,
+ height = height,
+ width = width,
+ }
+ else
+ chr = {
+ index = index,
+ height = height,
+ width = width,
+ }
+ end
+ end
+ -- if trace_scaling then
+ -- logs.report("define font","t=%s, u=%s, i=%s, n=%s c=%s",k,chr.tounicode or k,description.index,description.name or '-',description.class or '-')
+ -- end
+ if tounicode then
+ local tu = tounicode[index]
+ if tu then
+ chr.tounicode = tu
+ end
+ end
+ if hasquality then
+ local ve = v.expansion_factor
+ if ve then
+ chr.expansion_factor = ve*1000 -- expansionfactor, hm, can happen elsewhere
+ end
+ local vl = v.left_protruding
+ if vl then
+ chr.left_protruding = protrusionfactor*width*vl
+ end
+ local vr = v.right_protruding
+ if vr then
+ chr.right_protruding = protrusionfactor*width*vr
+ end
+ end
+ -- todo: hasitalic
+ if hasitalic then
+ local vi = description.italic or v.italic
+ if vi and vi ~= 0 then
+ chr.italic = vi*delta
+ end
+ end
+ -- to be tested
+ if hasmath then
+ -- todo, just operate on descriptions.math
+ local vn = v.next
+ if vn then
+ chr.next = vn
+ else
+ local vv = v.vert_variants
+ if vv then
+ local t = { }
+ for i=1,#vv do
+ local vvi = vv[i]
+ t[i] = {
+ ["start"] = (vvi["start"] or 0)*delta,
+ ["end"] = (vvi["end"] or 0)*delta,
+ ["advance"] = (vvi["advance"] or 0)*delta,
+ ["extender"] = vvi["extender"],
+ ["glyph"] = vvi["glyph"],
+ }
+ end
+ chr.vert_variants = t
+ else
+ local hv = v.horiz_variants
+ if hv then
+ local t = { }
+ for i=1,#hv do
+ local hvi = hv[i]
+ t[i] = {
+ ["start"] = (hvi["start"] or 0)*delta,
+ ["end"] = (hvi["end"] or 0)*delta,
+ ["advance"] = (hvi["advance"] or 0)*delta,
+ ["extender"] = hvi["extender"],
+ ["glyph"] = hvi["glyph"],
+ }
+ end
+ chr.horiz_variants = t
+ end
+ end
+ end
+ local vt = description.top_accent
+ if vt then
+ chr.top_accent = delta*vt
+ end
+ if stackmath then
+ local mk = v.mathkerns
+ if mk then
+ local kerns = { }
+ -- for k, v in next, mk do
+ -- local kk = { }
+ -- for i=1,#v do
+ -- local vi = v[i]
+ -- kk[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ -- end
+ -- kerns[k] = kk
+ -- end
+ local v = mk.top_right if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.top_right = k end
+ local v = mk.top_left if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.top_left = k end
+ local v = mk.bottom_left if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.bottom_left = k end
+ local v = mk.bottom_right if v then local k = { } for i=1,#v do local vi = v[i]
+ k[i] = { height = delta*vi.height, kern = delta*vi.kern }
+ end kerns.bottom_right = k end
+ chr.mathkern = kerns -- singular
+ end
+ end
+ end
+ if not nodemode then
+ local vk = v.kerns
+ if vk then
+ if sharedkerns then
+ local base = basekerns[vk] -- hashed by table id, not content
+ if not base then
+ base = {}
+ for k,v in next, vk do base[k] = v*delta end
+ basekerns[vk] = base
+ end
+ chr.kerns = base
+ else
+ local tt = {}
+ for k,v in next, vk do tt[k] = v*delta end
+ chr.kerns = tt
+ end
+ end
+ local vl = v.ligatures
+ if vl then
+ if true then
+ chr.ligatures = vl -- shared
+ else
+ local tt = { }
+ for i,l in next, vl do
+ tt[i] = l
+ end
+ chr.ligatures = tt
+ end
+ end
+ end
+ if isvirtual then
+ local vc = v.commands
+ if vc then
+ -- we assume non scaled commands here
+ local ok = false
+ for i=1,#vc do
+ local key = vc[i][1]
+ if key == "right" or key == "down" then
+ ok = true
+ break
+ end
+ end
+ if ok then
+ local tt = { }
+ for i=1,#vc do
+ local ivc = vc[i]
+ local key = ivc[1]
+ if key == "right" or key == "down" then
+ tt[#tt+1] = { key, ivc[2]*delta }
+ else -- not comment
+ tt[#tt+1] = ivc -- shared since in cache and untouched
+ end
+ end
+ chr.commands = tt
+ else
+ chr.commands = vc
+ end
+ end
+ end
+ tc[k] = chr
+ end
+ -- t.encodingbytes, t.filename, t.fullname, t.name: elsewhere
+ t.size = scaledpoints
+ t.factor = delta
+ if t.fonts then
+ t.fonts = table.fastcopy(t.fonts) -- maybe we virtualize more afterwards
+ end
+ if hasmath then
+ -- mathematics.extras.copy(t) -- can be done elsewhere if needed
+ local ma = tfm.mathactions
+ for i=1,#ma do
+ ma[i](t,tfmtable,delta)
+ end
+ end
+ -- needed for \high cum suis
+ local tpx = tp.x_height
+ if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
+ if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
+ if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
+ if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
+ if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
+ if not tp[22] then tp[22] = 0 end -- mathaxisheight
+ if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
+ t.tounicode = 1
+ -- we have t.name=metricfile and t.fullname=RealName and t.filename=diskfilename
+ -- when collapsing fonts, luatex looks as both t.name and t.fullname as ttc files
+ -- can have multiple subfonts
+--~ collectgarbage("collect")
+ return t, delta
+end
+
+--[[ldx--
+<p>The reason why the scaler is split, is that for a while we experimented
+with a helper function. However, in practice the <l n='api'/> calls are too slow to
+make this profitable and the <l n='lua'/> based variant was just faster. A days
+wasted day but an experience richer.</p>
+--ldx]]--
+
+tfm.auto_cleanup = true
+
+local lastfont = nil
+
+-- we can get rid of the tfm instance when we have fast access to the
+-- scaled character dimensions at the tex end, e.g. a fontobject.width
+--
+-- flushing the kern and ligature tables from memory saves a lot (only
+-- base mode) but it complicates vf building where the new characters
+-- demand this data
+
+--~ for id, f in pairs(fonts.ids) do -- or font.fonts
+--~ local ffi = font.fonts[id]
+--~ f.characters = ffi.characters
+--~ f.kerns = ffi.kerns
+--~ f.ligatures = ffi.ligatures
+--~ end
+
+function tfm.cleanup_table(tfmdata) -- we need a cleanup callback, now we miss the last one
+ if tfm.auto_cleanup then -- ok, we can hook this into everyshipout or so ... todo
+ if tfmdata.type == 'virtual' or tfmdata.virtualized then
+ for k, v in next, tfmdata.characters do
+ if v.commands then v.commands = nil end
+ end
+ end
+ end
+end
+
+function tfm.cleanup(tfmdata) -- we need a cleanup callback, now we miss the last one
+end
+
+function tfm.scale(tfmtable, scaledpoints)
+ local t, factor = tfm.do_scale(tfmtable, scaledpoints)
+ t.factor = factor
+ t.ascender = factor*(tfmtable.ascender or 0)
+ t.descender = factor*(tfmtable.descender or 0)
+ t.shared = tfmtable.shared or { }
+ t.unique = table.fastcopy(tfmtable.unique or {})
+--~ print("scaling", t.name, t.factor) -- , tfm.hash_features(tfmtable.specification))
+ tfm.cleanup(t)
+ return t
+end
+
+--[[ldx--
+<p>Analyzers run per script and/or language and are needed in order to
+process features right.</p>
+--ldx]]--
+
+fonts.analyzers = fonts.analyzers or { }
+fonts.analyzers.aux = fonts.analyzers.aux or { }
+fonts.analyzers.methods = fonts.analyzers.methods or { }
+fonts.analyzers.initializers = fonts.analyzers.initializers or { }
+
+-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
+-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze
+
+-- an example analyzer (should move to font-ota.lua)
+
+local state = attributes.private('state')
+
+function fonts.analyzers.aux.setstate(head,font)
+ local tfmdata = fontdata[font]
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local first, last, current, n, done = nil, nil, head, 0, false -- maybe make n boolean
+ while current do
+ if current.id == glyph and current.font == font then
+ local d = descriptions[current.char]
+ if d then
+ if d.class == "mark" then
+ done = true
+ set_attribute(current,state,5) -- mark
+ elseif n == 0 then
+ first, last, n = current, current, 1
+ set_attribute(current,state,1) -- init
+ else
+ last, n = current, n+1
+ set_attribute(current,state,2) -- medi
+ end
+ else -- finish
+ if first and first == last then
+ set_attribute(last,state,4) -- isol
+ elseif last then
+ set_attribute(last,state,3) -- fina
+ end
+ first, last, n = nil, nil, 0
+ end
+ else -- finish
+ if first and first == last then
+ set_attribute(last,state,4) -- isol
+ elseif last then
+ set_attribute(last,state,3) -- fina
+ end
+ first, last, n = nil, nil, 0
+ end
+ current = current.next
+ end
+ if first and first == last then
+ set_attribute(last,state,4) -- isol
+ elseif last then
+ set_attribute(last,state,3) -- fina
+ end
+ return head, done
+end
+
+function tfm.replacements(tfm,value)
+ -- tfm.characters[0x0022] = table.fastcopy(tfm.characters[0x201D])
+ -- tfm.characters[0x0027] = table.fastcopy(tfm.characters[0x2019])
+ -- tfm.characters[0x0060] = table.fastcopy(tfm.characters[0x2018])
+ -- tfm.characters[0x0022] = tfm.characters[0x201D]
+ tfm.characters[0x0027] = tfm.characters[0x2019]
+ -- tfm.characters[0x0060] = tfm.characters[0x2018]
+end
+
+-- auto complete font with missing composed characters
+
+table.insert(fonts.manipulators,"compose")
+
+function fonts.initializers.common.compose(tfmdata,value)
+ if value then
+ fonts.vf.aux.compose_characters(tfmdata)
+ end
+end
+
+-- tfm features, experimental
+
+tfm.features = tfm.features or { }
+tfm.features.list = tfm.features.list or { }
+tfm.features.default = tfm.features.default or { }
+
+function tfm.enhance(tfmdata,specification)
+ -- we don't really share tfm data because we always reload
+ -- but this is more in sycn with afm and such
+ local features = (specification.features and specification.features.normal ) or { }
+ tfmdata.shared = tfmdata.shared or { }
+ tfmdata.shared.features = features
+ -- tfmdata.shared.tfmdata = tfmdata -- circular
+tfmdata.filename = specification.name
+ if not features.encoding then
+ local name, size = specification.name, specification.size
+ local encoding, filename = match(name,"^(.-)%-(.*)$") -- context: encoding-name.*
+ if filename and encoding and fonts.enc.known[encoding] then
+ features.encoding = encoding
+ end
+ end
+ tfm.set_features(tfmdata)
+end
+
+function tfm.set_features(tfmdata)
+ -- todo: no local functions
+ local shared = tfmdata.shared
+-- local tfmdata = shared.tfmdata
+ local features = shared.features
+ if not table.is_empty(features) then
+ local mode = tfmdata.mode or fonts.mode
+ local fi = fonts.initializers[mode]
+ if fi and fi.tfm then
+ local function initialize(list) -- using tex lig and kerning
+ if list then
+ for i=1,#list do
+ local f = list[i]
+ local value = features[f]
+ if value and fi.tfm[f] then -- brr
+ if tfm.trace_features then
+ logs.report("define tfm","initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown',tfmdata.name or 'unknown')
+ end
+ fi.tfm[f](tfmdata,value)
+ mode = tfmdata.mode or fonts.mode
+ fi = fonts.initializers[mode]
+ end
+ end
+ end
+ end
+ initialize(fonts.triggers)
+ initialize(tfm.features.list)
+ initialize(fonts.manipulators)
+ end
+ local fm = fonts.methods[mode]
+ if fm and fm.tfm then
+ local function register(list) -- node manipulations
+ if list then
+ for i=1,#list do
+ local f = list[i]
+ if features[f] and fm.tfm[f] then -- brr
+ if not shared.processors then -- maybe also predefine
+ shared.processors = { fm.tfm[f] }
+ else
+ shared.processors[#shared.processors+1] = fm.tfm[f]
+ end
+ end
+ end
+ end
+ end
+ register(tfm.features.list)
+ end
+ end
+end
+
+function tfm.features.register(name,default)
+ tfm.features.list[#tfm.features.list+1] = name
+ tfm.features.default[name] = default
+end
+
+function tfm.reencode(tfmdata,encoding)
+ if encoding and fonts.enc.known[encoding] then
+ local data = fonts.enc.load(encoding)
+ if data then
+ local characters, original, vector = tfmdata.characters, { }, data.vector
+ tfmdata.encoding = encoding -- not needed
+ for k, v in next, characters do
+ v.name, v.index, original[k] = vector[k], k, v
+ end
+ for k,v in next, data.unicodes do
+ if k ~= v then
+ if trace_defining then
+ logs.report("define font","reencoding U+%04X to U+%04X",k,v)
+ end
+ characters[k] = original[v]
+ end
+ end
+ end
+ end
+end
+
+tfm.features.register('reencode')
+
+fonts.initializers.base.tfm.reencode = tfm.reencode
+fonts.initializers.node.tfm.reencode = tfm.reencode
+
+fonts.enc = fonts.enc or { }
+fonts.enc.remappings = fonts.enc.remappings or { }
+
+function tfm.remap(tfmdata,remapping)
+ local vector = remapping and fonts.enc.remappings[remapping]
+ if vector then
+ local characters, original = tfmdata.characters, { }
+ for k, v in next, characters do
+ original[k], characters[k] = v, nil
+ end
+ for k,v in next, vector do
+ if k ~= v then
+ if trace_defining then
+ logs.report("define font","remapping U+%04X to U+%04X",k,v)
+ end
+ local c = original[k]
+ characters[v] = c
+ c.index = k
+ end
+ end
+ tfmdata.encodingbytes = 2
+ tfmdata.format = 'type1'
+ end
+end
+
+tfm.features.register('remap')
+
+fonts.initializers.base.tfm.remap = tfm.remap
+fonts.initializers.node.tfm.remap = tfm.remap
+
+-- status info
+
+statistics.register("fonts load time", function()
+ if statistics.elapsedindeed(fonts) then
+ return format("%s seconds",statistics.elapsedtime(fonts))
+ end
+end)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-cid'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (cidmaps)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, match = string.format, string.match
+local tonumber = tonumber
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+fonts = fonts or { }
+fonts.cid = fonts.cid or { }
+fonts.cid.map = fonts.cid.map or { }
+fonts.cid.max = fonts.cid.max or 10
+
+
+-- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap
+--
+-- 18964 18964 (leader)
+-- 0 /.notdef
+-- 1..95 0020
+-- 99 3000
+
+local number = lpeg.C(lpeg.R("09","af","AF")^1)
+local space = lpeg.S(" \n\r\t")
+local spaces = space^0
+local period = lpeg.P(".")
+local periods = period * period
+local name = lpeg.P("/") * lpeg.C((1-space)^1)
+
+local unicodes, names = { }, { }
+
+local function do_one(a,b)
+ unicodes[tonumber(a)] = tonumber(b,16)
+end
+
+local function do_range(a,b,c)
+ c = tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i] = c
+ c = c + 1
+ end
+end
+
+local function do_name(a,b)
+ names[tonumber(a)] = b
+end
+
+local grammar = lpeg.P { "start",
+ start = number * spaces * number * lpeg.V("series"),
+ series = (spaces * (lpeg.V("one") + lpeg.V("range") + lpeg.V("named")) )^1,
+ one = (number * spaces * number) / do_one,
+ range = (number * periods * number * spaces * number) / do_range,
+ named = (number * spaces * name) / do_name
+}
+
+function fonts.cid.load(filename)
+ local data = io.loaddata(filename)
+ if data then
+ unicodes, names = { }, { }
+ grammar:match(data)
+ local supplement, registry, ordering = match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement = supplement,
+ registry = registry,
+ ordering = ordering,
+ filename = filename,
+ unicodes = unicodes,
+ names = names
+ }
+ else
+ return nil
+ end
+end
+
+local template = "%s-%s-%s.cidmap"
+
+local function locate(registry,ordering,supplement)
+ local filename = string.lower(format(template,registry,ordering,supplement))
+ local cidmap = fonts.cid.map[filename]
+ if not cidmap then
+ if trace_loading then
+ logs.report("load otf","checking cidmap, registry: %s, ordering: %s, supplement: %s, filename: %s",registry,ordering,supplement,filename)
+ end
+ local fullname = resolvers.find_file(filename,'cid') or ""
+ if fullname ~= "" then
+ cidmap = fonts.cid.load(fullname)
+ if cidmap then
+ if trace_loading then
+ logs.report("load otf","using cidmap file %s",filename)
+ end
+ fonts.cid.map[filename] = cidmap
+ return cidmap
+ end
+ end
+ end
+ return cidmap
+end
+
+function fonts.cid.getmap(registry,ordering,supplement)
+ -- cf Arthur R. we can safely scan upwards since cids are downward compatible
+ local supplement = tonumber(supplement)
+ if trace_loading then
+ logs.report("load otf","needed cidmap, registry: %s, ordering: %s, supplement: %s",registry,ordering,supplement)
+ end
+ local cidmap = locate(registry,ordering,supplement)
+ if not cidmap then
+ local cidnum = nil
+ -- next highest (alternatively we could start high)
+ if supplement < fonts.cid.max then
+ for supplement=supplement+1,fonts.cid.max do
+ local c = locate(registry,ordering,supplement)
+ if c then
+ cidmap, cidnum = c, supplement
+ break
+ end
+ end
+ end
+ -- next lowest (least worse fit)
+ if not cidmap and supplement > 0 then
+ for supplement=supplement-1,0,-1 do
+ local c = locate(registry,ordering,supplement)
+ if c then
+ cidmap, cidnum = c, supplement
+ break
+ end
+ end
+ end
+ -- prevent further lookups
+ if cidmap and cidnum > 0 then
+ for s=0,cidnum-1 do
+ filename = format(template,registry,ordering,s)
+ if not fonts.cid.map[filename] then
+ fonts.cid.map[filename] = cidmap -- copy of ref
+ end
+ end
+ end
+ end
+ return cidmap
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-otf'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (tables)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+local gsub, lower = string.gsub, string.lower
+
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+
+local otf = fonts.otf
+
+otf.tables = otf.tables or { }
+otf.meanings = otf.meanings or { }
+
+otf.tables.scripts = {
+ ['dflt'] = 'Default',
+
+ ['arab'] = 'Arabic',
+ ['armn'] = 'Armenian',
+ ['bali'] = 'Balinese',
+ ['beng'] = 'Bengali',
+ ['bopo'] = 'Bopomofo',
+ ['brai'] = 'Braille',
+ ['bugi'] = 'Buginese',
+ ['buhd'] = 'Buhid',
+ ['byzm'] = 'Byzantine Music',
+ ['cans'] = 'Canadian Syllabics',
+ ['cher'] = 'Cherokee',
+ ['copt'] = 'Coptic',
+ ['cprt'] = 'Cypriot Syllabary',
+ ['cyrl'] = 'Cyrillic',
+ ['deva'] = 'Devanagari',
+ ['dsrt'] = 'Deseret',
+ ['ethi'] = 'Ethiopic',
+ ['geor'] = 'Georgian',
+ ['glag'] = 'Glagolitic',
+ ['goth'] = 'Gothic',
+ ['grek'] = 'Greek',
+ ['gujr'] = 'Gujarati',
+ ['guru'] = 'Gurmukhi',
+ ['hang'] = 'Hangul',
+ ['hani'] = 'CJK Ideographic',
+ ['hano'] = 'Hanunoo',
+ ['hebr'] = 'Hebrew',
+ ['ital'] = 'Old Italic',
+ ['jamo'] = 'Hangul Jamo',
+ ['java'] = 'Javanese',
+ ['kana'] = 'Hiragana and Katakana',
+ ['khar'] = 'Kharosthi',
+ ['khmr'] = 'Khmer',
+ ['knda'] = 'Kannada',
+ ['lao' ] = 'Lao',
+ ['latn'] = 'Latin',
+ ['limb'] = 'Limbu',
+ ['linb'] = 'Linear B',
+ ['math'] = 'Mathematical Alphanumeric Symbols',
+ ['mlym'] = 'Malayalam',
+ ['mong'] = 'Mongolian',
+ ['musc'] = 'Musical Symbols',
+ ['mymr'] = 'Myanmar',
+ ['nko' ] = "N'ko",
+ ['ogam'] = 'Ogham',
+ ['orya'] = 'Oriya',
+ ['osma'] = 'Osmanya',
+ ['phag'] = 'Phags-pa',
+ ['phnx'] = 'Phoenician',
+ ['runr'] = 'Runic',
+ ['shaw'] = 'Shavian',
+ ['sinh'] = 'Sinhala',
+ ['sylo'] = 'Syloti Nagri',
+ ['syrc'] = 'Syriac',
+ ['tagb'] = 'Tagbanwa',
+ ['tale'] = 'Tai Le',
+ ['talu'] = 'Tai Lu',
+ ['taml'] = 'Tamil',
+ ['telu'] = 'Telugu',
+ ['tfng'] = 'Tifinagh',
+ ['tglg'] = 'Tagalog',
+ ['thaa'] = 'Thaana',
+ ['thai'] = 'Thai',
+ ['tibt'] = 'Tibetan',
+ ['ugar'] = 'Ugaritic Cuneiform',
+ ['xpeo'] = 'Old Persian Cuneiform',
+ ['xsux'] = 'Sumero-Akkadian Cuneiform',
+ ['yi' ] = 'Yi'
+}
+
+otf.tables.languages = {
+ ['dflt'] = 'Default',
+
+ ['aba'] = 'Abaza',
+ ['abk'] = 'Abkhazian',
+ ['ady'] = 'Adyghe',
+ ['afk'] = 'Afrikaans',
+ ['afr'] = 'Afar',
+ ['agw'] = 'Agaw',
+ ['als'] = 'Alsatian',
+ ['alt'] = 'Altai',
+ ['amh'] = 'Amharic',
+ ['ara'] = 'Arabic',
+ ['ari'] = 'Aari',
+ ['ark'] = 'Arakanese',
+ ['asm'] = 'Assamese',
+ ['ath'] = 'Athapaskan',
+ ['avr'] = 'Avar',
+ ['awa'] = 'Awadhi',
+ ['aym'] = 'Aymara',
+ ['aze'] = 'Azeri',
+ ['bad'] = 'Badaga',
+ ['bag'] = 'Baghelkhandi',
+ ['bal'] = 'Balkar',
+ ['bau'] = 'Baule',
+ ['bbr'] = 'Berber',
+ ['bch'] = 'Bench',
+ ['bcr'] = 'Bible Cree',
+ ['bel'] = 'Belarussian',
+ ['bem'] = 'Bemba',
+ ['ben'] = 'Bengali',
+ ['bgr'] = 'Bulgarian',
+ ['bhi'] = 'Bhili',
+ ['bho'] = 'Bhojpuri',
+ ['bik'] = 'Bikol',
+ ['bil'] = 'Bilen',
+ ['bkf'] = 'Blackfoot',
+ ['bli'] = 'Balochi',
+ ['bln'] = 'Balante',
+ ['blt'] = 'Balti',
+ ['bmb'] = 'Bambara',
+ ['bml'] = 'Bamileke',
+ ['bos'] = 'Bosnian',
+ ['bre'] = 'Breton',
+ ['brh'] = 'Brahui',
+ ['bri'] = 'Braj Bhasha',
+ ['brm'] = 'Burmese',
+ ['bsh'] = 'Bashkir',
+ ['bti'] = 'Beti',
+ ['cat'] = 'Catalan',
+ ['ceb'] = 'Cebuano',
+ ['che'] = 'Chechen',
+ ['chg'] = 'Chaha Gurage',
+ ['chh'] = 'Chattisgarhi',
+ ['chi'] = 'Chichewa',
+ ['chk'] = 'Chukchi',
+ ['chp'] = 'Chipewyan',
+ ['chr'] = 'Cherokee',
+ ['chu'] = 'Chuvash',
+ ['cmr'] = 'Comorian',
+ ['cop'] = 'Coptic',
+ ['cos'] = 'Corsican',
+ ['cre'] = 'Cree',
+ ['crr'] = 'Carrier',
+ ['crt'] = 'Crimean Tatar',
+ ['csl'] = 'Church Slavonic',
+ ['csy'] = 'Czech',
+ ['dan'] = 'Danish',
+ ['dar'] = 'Dargwa',
+ ['dcr'] = 'Woods Cree',
+ ['deu'] = 'German',
+ ['dgr'] = 'Dogri',
+ ['div'] = 'Divehi',
+ ['djr'] = 'Djerma',
+ ['dng'] = 'Dangme',
+ ['dnk'] = 'Dinka',
+ ['dri'] = 'Dari',
+ ['dun'] = 'Dungan',
+ ['dzn'] = 'Dzongkha',
+ ['ebi'] = 'Ebira',
+ ['ecr'] = 'Eastern Cree',
+ ['edo'] = 'Edo',
+ ['efi'] = 'Efik',
+ ['ell'] = 'Greek',
+ ['eng'] = 'English',
+ ['erz'] = 'Erzya',
+ ['esp'] = 'Spanish',
+ ['eti'] = 'Estonian',
+ ['euq'] = 'Basque',
+ ['evk'] = 'Evenki',
+ ['evn'] = 'Even',
+ ['ewe'] = 'Ewe',
+ ['fan'] = 'French Antillean',
+ ['far'] = 'Farsi',
+ ['fin'] = 'Finnish',
+ ['fji'] = 'Fijian',
+ ['fle'] = 'Flemish',
+ ['fne'] = 'Forest Nenets',
+ ['fon'] = 'Fon',
+ ['fos'] = 'Faroese',
+ ['fra'] = 'French',
+ ['fri'] = 'Frisian',
+ ['frl'] = 'Friulian',
+ ['fta'] = 'Futa',
+ ['ful'] = 'Fulani',
+ ['gad'] = 'Ga',
+ ['gae'] = 'Gaelic',
+ ['gag'] = 'Gagauz',
+ ['gal'] = 'Galician',
+ ['gar'] = 'Garshuni',
+ ['gaw'] = 'Garhwali',
+ ['gez'] = "Ge'ez",
+ ['gil'] = 'Gilyak',
+ ['gmz'] = 'Gumuz',
+ ['gon'] = 'Gondi',
+ ['grn'] = 'Greenlandic',
+ ['gro'] = 'Garo',
+ ['gua'] = 'Guarani',
+ ['guj'] = 'Gujarati',
+ ['hai'] = 'Haitian',
+ ['hal'] = 'Halam',
+ ['har'] = 'Harauti',
+ ['hau'] = 'Hausa',
+ ['haw'] = 'Hawaiin',
+ ['hbn'] = 'Hammer-Banna',
+ ['hil'] = 'Hiligaynon',
+ ['hin'] = 'Hindi',
+ ['hma'] = 'High Mari',
+ ['hnd'] = 'Hindko',
+ ['ho'] = 'Ho',
+ ['hri'] = 'Harari',
+ ['hrv'] = 'Croatian',
+ ['hun'] = 'Hungarian',
+ ['hye'] = 'Armenian',
+ ['ibo'] = 'Igbo',
+ ['ijo'] = 'Ijo',
+ ['ilo'] = 'Ilokano',
+ ['ind'] = 'Indonesian',
+ ['ing'] = 'Ingush',
+ ['inu'] = 'Inuktitut',
+ ['iri'] = 'Irish',
+ ['irt'] = 'Irish Traditional',
+ ['isl'] = 'Icelandic',
+ ['ism'] = 'Inari Sami',
+ ['ita'] = 'Italian',
+ ['iwr'] = 'Hebrew',
+ ['jan'] = 'Japanese',
+ ['jav'] = 'Javanese',
+ ['jii'] = 'Yiddish',
+ ['jud'] = 'Judezmo',
+ ['jul'] = 'Jula',
+ ['kab'] = 'Kabardian',
+ ['kac'] = 'Kachchi',
+ ['kal'] = 'Kalenjin',
+ ['kan'] = 'Kannada',
+ ['kar'] = 'Karachay',
+ ['kat'] = 'Georgian',
+ ['kaz'] = 'Kazakh',
+ ['keb'] = 'Kebena',
+ ['kge'] = 'Khutsuri Georgian',
+ ['kha'] = 'Khakass',
+ ['khk'] = 'Khanty-Kazim',
+ ['khm'] = 'Khmer',
+ ['khs'] = 'Khanty-Shurishkar',
+ ['khv'] = 'Khanty-Vakhi',
+ ['khw'] = 'Khowar',
+ ['kik'] = 'Kikuyu',
+ ['kir'] = 'Kirghiz',
+ ['kis'] = 'Kisii',
+ ['kkn'] = 'Kokni',
+ ['klm'] = 'Kalmyk',
+ ['kmb'] = 'Kamba',
+ ['kmn'] = 'Kumaoni',
+ ['kmo'] = 'Komo',
+ ['kms'] = 'Komso',
+ ['knr'] = 'Kanuri',
+ ['kod'] = 'Kodagu',
+ ['koh'] = 'Korean Old Hangul',
+ ['kok'] = 'Konkani',
+ ['kon'] = 'Kikongo',
+ ['kop'] = 'Komi-Permyak',
+ ['kor'] = 'Korean',
+ ['koz'] = 'Komi-Zyrian',
+ ['kpl'] = 'Kpelle',
+ ['kri'] = 'Krio',
+ ['krk'] = 'Karakalpak',
+ ['krl'] = 'Karelian',
+ ['krm'] = 'Karaim',
+ ['krn'] = 'Karen',
+ ['krt'] = 'Koorete',
+ ['ksh'] = 'Kashmiri',
+ ['ksi'] = 'Khasi',
+ ['ksm'] = 'Kildin Sami',
+ ['kui'] = 'Kui',
+ ['kul'] = 'Kulvi',
+ ['kum'] = 'Kumyk',
+ ['kur'] = 'Kurdish',
+ ['kuu'] = 'Kurukh',
+ ['kuy'] = 'Kuy',
+ ['kyk'] = 'Koryak',
+ ['lad'] = 'Ladin',
+ ['lah'] = 'Lahuli',
+ ['lak'] = 'Lak',
+ ['lam'] = 'Lambani',
+ ['lao'] = 'Lao',
+ ['lat'] = 'Latin',
+ ['laz'] = 'Laz',
+ ['lcr'] = 'L-Cree',
+ ['ldk'] = 'Ladakhi',
+ ['lez'] = 'Lezgi',
+ ['lin'] = 'Lingala',
+ ['lma'] = 'Low Mari',
+ ['lmb'] = 'Limbu',
+ ['lmw'] = 'Lomwe',
+ ['lsb'] = 'Lower Sorbian',
+ ['lsm'] = 'Lule Sami',
+ ['lth'] = 'Lithuanian',
+ ['ltz'] = 'Luxembourgish',
+ ['lub'] = 'Luba',
+ ['lug'] = 'Luganda',
+ ['luh'] = 'Luhya',
+ ['luo'] = 'Luo',
+ ['lvi'] = 'Latvian',
+ ['maj'] = 'Majang',
+ ['mak'] = 'Makua',
+ ['mal'] = 'Malayalam Traditional',
+ ['man'] = 'Mansi',
+ ['map'] = 'Mapudungun',
+ ['mar'] = 'Marathi',
+ ['maw'] = 'Marwari',
+ ['mbn'] = 'Mbundu',
+ ['mch'] = 'Manchu',
+ ['mcr'] = 'Moose Cree',
+ ['mde'] = 'Mende',
+ ['men'] = "Me'en",
+ ['miz'] = 'Mizo',
+ ['mkd'] = 'Macedonian',
+ ['mle'] = 'Male',
+ ['mlg'] = 'Malagasy',
+ ['mln'] = 'Malinke',
+ ['mlr'] = 'Malayalam Reformed',
+ ['mly'] = 'Malay',
+ ['mnd'] = 'Mandinka',
+ ['mng'] = 'Mongolian',
+ ['mni'] = 'Manipuri',
+ ['mnk'] = 'Maninka',
+ ['mnx'] = 'Manx Gaelic',
+ ['moh'] = 'Mohawk',
+ ['mok'] = 'Moksha',
+ ['mol'] = 'Moldavian',
+ ['mon'] = 'Mon',
+ ['mor'] = 'Moroccan',
+ ['mri'] = 'Maori',
+ ['mth'] = 'Maithili',
+ ['mts'] = 'Maltese',
+ ['mun'] = 'Mundari',
+ ['nag'] = 'Naga-Assamese',
+ ['nan'] = 'Nanai',
+ ['nas'] = 'Naskapi',
+ ['ncr'] = 'N-Cree',
+ ['ndb'] = 'Ndebele',
+ ['ndg'] = 'Ndonga',
+ ['nep'] = 'Nepali',
+ ['new'] = 'Newari',
+ ['ngr'] = 'Nagari',
+ ['nhc'] = 'Norway House Cree',
+ ['nis'] = 'Nisi',
+ ['niu'] = 'Niuean',
+ ['nkl'] = 'Nkole',
+ ['nko'] = "N'ko",
+ ['nld'] = 'Dutch',
+ ['nog'] = 'Nogai',
+ ['nor'] = 'Norwegian',
+ ['nsm'] = 'Northern Sami',
+ ['nta'] = 'Northern Tai',
+ ['nto'] = 'Esperanto',
+ ['nyn'] = 'Nynorsk',
+ ['oci'] = 'Occitan',
+ ['ocr'] = 'Oji-Cree',
+ ['ojb'] = 'Ojibway',
+ ['ori'] = 'Oriya',
+ ['oro'] = 'Oromo',
+ ['oss'] = 'Ossetian',
+ ['paa'] = 'Palestinian Aramaic',
+ ['pal'] = 'Pali',
+ ['pan'] = 'Punjabi',
+ ['pap'] = 'Palpa',
+ ['pas'] = 'Pashto',
+ ['pgr'] = 'Polytonic Greek',
+ ['pil'] = 'Pilipino',
+ ['plg'] = 'Palaung',
+ ['plk'] = 'Polish',
+ ['pro'] = 'Provencal',
+ ['ptg'] = 'Portuguese',
+ ['qin'] = 'Chin',
+ ['raj'] = 'Rajasthani',
+ ['rbu'] = 'Russian Buriat',
+ ['rcr'] = 'R-Cree',
+ ['ria'] = 'Riang',
+ ['rms'] = 'Rhaeto-Romanic',
+ ['rom'] = 'Romanian',
+ ['roy'] = 'Romany',
+ ['rsy'] = 'Rusyn',
+ ['rua'] = 'Ruanda',
+ ['rus'] = 'Russian',
+ ['sad'] = 'Sadri',
+ ['san'] = 'Sanskrit',
+ ['sat'] = 'Santali',
+ ['say'] = 'Sayisi',
+ ['sek'] = 'Sekota',
+ ['sel'] = 'Selkup',
+ ['sgo'] = 'Sango',
+ ['shn'] = 'Shan',
+ ['sib'] = 'Sibe',
+ ['sid'] = 'Sidamo',
+ ['sig'] = 'Silte Gurage',
+ ['sks'] = 'Skolt Sami',
+ ['sky'] = 'Slovak',
+ ['sla'] = 'Slavey',
+ ['slv'] = 'Slovenian',
+ ['sml'] = 'Somali',
+ ['smo'] = 'Samoan',
+ ['sna'] = 'Sena',
+ ['snd'] = 'Sindhi',
+ ['snh'] = 'Sinhalese',
+ ['snk'] = 'Soninke',
+ ['sog'] = 'Sodo Gurage',
+ ['sot'] = 'Sotho',
+ ['sqi'] = 'Albanian',
+ ['srb'] = 'Serbian',
+ ['srk'] = 'Saraiki',
+ ['srr'] = 'Serer',
+ ['ssl'] = 'South Slavey',
+ ['ssm'] = 'Southern Sami',
+ ['sur'] = 'Suri',
+ ['sva'] = 'Svan',
+ ['sve'] = 'Swedish',
+ ['swa'] = 'Swadaya Aramaic',
+ ['swk'] = 'Swahili',
+ ['swz'] = 'Swazi',
+ ['sxt'] = 'Sutu',
+ ['syr'] = 'Syriac',
+ ['tab'] = 'Tabasaran',
+ ['taj'] = 'Tajiki',
+ ['tam'] = 'Tamil',
+ ['tat'] = 'Tatar',
+ ['tcr'] = 'TH-Cree',
+ ['tel'] = 'Telugu',
+ ['tgn'] = 'Tongan',
+ ['tgr'] = 'Tigre',
+ ['tgy'] = 'Tigrinya',
+ ['tha'] = 'Thai',
+ ['tht'] = 'Tahitian',
+ ['tib'] = 'Tibetan',
+ ['tkm'] = 'Turkmen',
+ ['tmn'] = 'Temne',
+ ['tna'] = 'Tswana',
+ ['tne'] = 'Tundra Nenets',
+ ['tng'] = 'Tonga',
+ ['tod'] = 'Todo',
+ ['trk'] = 'Turkish',
+ ['tsg'] = 'Tsonga',
+ ['tua'] = 'Turoyo Aramaic',
+ ['tul'] = 'Tulu',
+ ['tuv'] = 'Tuvin',
+ ['twi'] = 'Twi',
+ ['udm'] = 'Udmurt',
+ ['ukr'] = 'Ukrainian',
+ ['urd'] = 'Urdu',
+ ['usb'] = 'Upper Sorbian',
+ ['uyg'] = 'Uyghur',
+ ['uzb'] = 'Uzbek',
+ ['ven'] = 'Venda',
+ ['vit'] = 'Vietnamese',
+ ['wa' ] = 'Wa',
+ ['wag'] = 'Wagdi',
+ ['wcr'] = 'West-Cree',
+ ['wel'] = 'Welsh',
+ ['wlf'] = 'Wolof',
+ ['xbd'] = 'Tai Lue',
+ ['xhs'] = 'Xhosa',
+ ['yak'] = 'Yakut',
+ ['yba'] = 'Yoruba',
+ ['ycr'] = 'Y-Cree',
+ ['yic'] = 'Yi Classic',
+ ['yim'] = 'Yi Modern',
+ ['zhh'] = 'Chinese Hong Kong',
+ ['zhp'] = 'Chinese Phonetic',
+ ['zhs'] = 'Chinese Simplified',
+ ['zht'] = 'Chinese Traditional',
+ ['znd'] = 'Zande',
+ ['zul'] = 'Zulu'
+}
+
+otf.tables.features = {
+ ['aalt'] = 'Access All Alternates',
+ ['abvf'] = 'Above-Base Forms',
+ ['abvm'] = 'Above-Base Mark Positioning',
+ ['abvs'] = 'Above-Base Substitutions',
+ ['afrc'] = 'Alternative Fractions',
+ ['akhn'] = 'Akhands',
+ ['blwf'] = 'Below-Base Forms',
+ ['blwm'] = 'Below-Base Mark Positioning',
+ ['blws'] = 'Below-Base Substitutions',
+ ['c2pc'] = 'Petite Capitals From Capitals',
+ ['c2sc'] = 'Small Capitals From Capitals',
+ ['calt'] = 'Contextual Alternates',
+ ['case'] = 'Case-Sensitive Forms',
+ ['ccmp'] = 'Glyph Composition/Decomposition',
+ ['cjct'] = 'Conjunct Forms',
+ ['clig'] = 'Contextual Ligatures',
+ ['cpsp'] = 'Capital Spacing',
+ ['cswh'] = 'Contextual Swash',
+ ['curs'] = 'Cursive Positioning',
+ ['dflt'] = 'Default Processing',
+ ['dist'] = 'Distances',
+ ['dlig'] = 'Discretionary Ligatures',
+ ['dnom'] = 'Denominators',
+ ['dtls'] = 'Dotless Forms', -- math
+ ['expt'] = 'Expert Forms',
+ ['falt'] = 'Final glyph Alternates',
+ ['fin2'] = 'Terminal Forms #2',
+ ['fin3'] = 'Terminal Forms #3',
+ ['fina'] = 'Terminal Forms',
+ ['flac'] = 'Flattened Accents Over Capitals', -- math
+ ['frac'] = 'Fractions',
+ ['fwid'] = 'Full Width',
+ ['half'] = 'Half Forms',
+ ['haln'] = 'Halant Forms',
+ ['halt'] = 'Alternate Half Width',
+ ['hist'] = 'Historical Forms',
+ ['hkna'] = 'Horizontal Kana Alternates',
+ ['hlig'] = 'Historical Ligatures',
+ ['hngl'] = 'Hangul',
+ ['hojo'] = 'Hojo Kanji Forms',
+ ['hwid'] = 'Half Width',
+ ['init'] = 'Initial Forms',
+ ['isol'] = 'Isolated Forms',
+ ['ital'] = 'Italics',
+ ['jalt'] = 'Justification Alternatives',
+ ['jp04'] = 'JIS2004 Forms',
+ ['jp78'] = 'JIS78 Forms',
+ ['jp83'] = 'JIS83 Forms',
+ ['jp90'] = 'JIS90 Forms',
+ ['kern'] = 'Kerning',
+ ['lfbd'] = 'Left Bounds',
+ ['liga'] = 'Standard Ligatures',
+ ['ljmo'] = 'Leading Jamo Forms',
+ ['lnum'] = 'Lining Figures',
+ ['locl'] = 'Localized Forms',
+ ['mark'] = 'Mark Positioning',
+ ['med2'] = 'Medial Forms #2',
+ ['medi'] = 'Medial Forms',
+ ['mgrk'] = 'Mathematical Greek',
+ ['mkmk'] = 'Mark to Mark Positioning',
+ ['mset'] = 'Mark Positioning via Substitution',
+ ['nalt'] = 'Alternate Annotation Forms',
+ ['nlck'] = 'NLC Kanji Forms',
+ ['nukt'] = 'Nukta Forms',
+ ['numr'] = 'Numerators',
+ ['onum'] = 'Old Style Figures',
+ ['opbd'] = 'Optical Bounds',
+ ['ordn'] = 'Ordinals',
+ ['ornm'] = 'Ornaments',
+ ['palt'] = 'Proportional Alternate Width',
+ ['pcap'] = 'Petite Capitals',
+ ['pnum'] = 'Proportional Figures',
+ ['pref'] = 'Pre-base Forms',
+ ['pres'] = 'Pre-base Substitutions',
+ ['pstf'] = 'Post-base Forms',
+ ['psts'] = 'Post-base Substitutions',
+ ['pwid'] = 'Proportional Widths',
+ ['qwid'] = 'Quarter Widths',
+ ['rand'] = 'Randomize',
+ ['rkrf'] = 'Rakar Forms',
+ ['rlig'] = 'Required Ligatures',
+ ['rphf'] = 'Reph Form',
+ ['rtbd'] = 'Right Bounds',
+ ['rtla'] = 'Right-To-Left Alternates',
+ ['ruby'] = 'Ruby Notation Forms',
+ ['salt'] = 'Stylistic Alternates',
+ ['sinf'] = 'Scientific Inferiors',
+ ['size'] = 'Optical Size',
+ ['smcp'] = 'Small Capitals',
+ ['smpl'] = 'Simplified Forms',
+ ['ss01'] = 'Stylistic Set 1',
+ ['ss02'] = 'Stylistic Set 2',
+ ['ss03'] = 'Stylistic Set 3',
+ ['ss04'] = 'Stylistic Set 4',
+ ['ss05'] = 'Stylistic Set 5',
+ ['ss06'] = 'Stylistic Set 6',
+ ['ss07'] = 'Stylistic Set 7',
+ ['ss08'] = 'Stylistic Set 8',
+ ['ss09'] = 'Stylistic Set 9',
+ ['ss10'] = 'Stylistic Set 10',
+ ['ss11'] = 'Stylistic Set 11',
+ ['ss12'] = 'Stylistic Set 12',
+ ['ss13'] = 'Stylistic Set 13',
+ ['ss14'] = 'Stylistic Set 14',
+ ['ss15'] = 'Stylistic Set 15',
+ ['ss16'] = 'Stylistic Set 16',
+ ['ss17'] = 'Stylistic Set 17',
+ ['ss18'] = 'Stylistic Set 18',
+ ['ss19'] = 'Stylistic Set 19',
+ ['ss20'] = 'Stylistic Set 20',
+ ['ssty'] = 'Script Style', -- math
+ ['subs'] = 'Subscript',
+ ['sups'] = 'Superscript',
+ ['swsh'] = 'Swash',
+ ['titl'] = 'Titling',
+ ['tjmo'] = 'Trailing Jamo Forms',
+ ['tnam'] = 'Traditional Name Forms',
+ ['tnum'] = 'Tabular Figures',
+ ['trad'] = 'Traditional Forms',
+ ['twid'] = 'Third Widths',
+ ['unic'] = 'Unicase',
+ ['valt'] = 'Alternate Vertical Metrics',
+ ['vatu'] = 'Vattu Variants',
+ ['vert'] = 'Vertical Writing',
+ ['vhal'] = 'Alternate Vertical Half Metrics',
+ ['vjmo'] = 'Vowel Jamo Forms',
+ ['vkna'] = 'Vertical Kana Alternates',
+ ['vkrn'] = 'Vertical Kerning',
+ ['vpal'] = 'Proportional Alternate Vertical Metrics',
+ ['vrt2'] = 'Vertical Rotation',
+ ['zero'] = 'Slashed Zero',
+
+ ['trep'] = 'Traditional TeX Replacements',
+ ['tlig'] = 'Traditional TeX Ligatures',
+}
+
+otf.tables.baselines = {
+ ['hang'] = 'Hanging baseline',
+ ['icfb'] = 'Ideographic character face bottom edge baseline',
+ ['icft'] = 'Ideographic character face tope edige baseline',
+ ['ideo'] = 'Ideographic em-box bottom edge baseline',
+ ['idtp'] = 'Ideographic em-box top edge baseline',
+ ['math'] = 'Mathmatical centered baseline',
+ ['romn'] = 'Roman baseline'
+}
+
+-- can be sped up by local tables
+
+function otf.tables.to_tag(id)
+ return stringformat("%4s",lower(id))
+end
+
+local function resolve(tab,id)
+ if tab and id then
+ id = lower(id)
+ return tab[id] or tab[gsub(id," ","")] or tab['dflt'] or ''
+ else
+ return "unknown"
+ end
+end
+
+function otf.meanings.script(id)
+ return resolve(otf.tables.scripts,id)
+end
+function otf.meanings.language(id)
+ return resolve(otf.tables.languages,id)
+end
+function otf.meanings.feature(id)
+ return resolve(otf.tables.features,id)
+end
+function otf.meanings.baseline(id)
+ return resolve(otf.tables.baselines,id)
+end
+
+otf.tables.to_scripts = table.reverse_hash(otf.tables.scripts )
+otf.tables.to_languages = table.reverse_hash(otf.tables.languages)
+otf.tables.to_features = table.reverse_hash(otf.tables.features )
+
+local scripts = otf.tables.scripts
+local languages = otf.tables.languages
+local features = otf.tables.features
+
+local to_scripts = otf.tables.to_scripts
+local to_languages = otf.tables.to_languages
+local to_features = otf.tables.to_features
+
+function otf.meanings.normalize(features)
+ local h = { }
+ for k,v in next, features do
+ k = lower(k)
+ if k == "language" or k == "lang" then
+ v = gsub(lower(v),"[^a-z0-9%-]","")
+ k = language
+ if not languages[v] then
+ h.language = to_languages[v] or "dflt"
+ else
+ h.language = v
+ end
+ elseif k == "script" then
+ v = gsub(lower(v),"[^a-z0-9%-]","")
+ if not scripts[v] then
+ h.script = to_scripts[v] or "dflt"
+ else
+ h.script = v
+ end
+ else
+ if type(v) == "string" then
+ local b = v:is_boolean()
+ if type(b) == "nil" then
+ v = tonumber(v) or lower(v)
+ else
+ v = b
+ end
+ end
+ h[to_features[k] or k] = v
+ end
+ end
+ return h
+end
+
+-- When I feel the need ...
+
+--~ otf.tables.aat = {
+--~ [ 0] = {
+--~ name = "allTypographicFeaturesType",
+--~ [ 0] = "allTypeFeaturesOnSelector",
+--~ [ 1] = "allTypeFeaturesOffSelector",
+--~ },
+--~ [ 1] = {
+--~ name = "ligaturesType",
+--~ [0 ] = "requiredLigaturesOnSelector",
+--~ [1 ] = "requiredLigaturesOffSelector",
+--~ [2 ] = "commonLigaturesOnSelector",
+--~ [3 ] = "commonLigaturesOffSelector",
+--~ [4 ] = "rareLigaturesOnSelector",
+--~ [5 ] = "rareLigaturesOffSelector",
+--~ [6 ] = "logosOnSelector ",
+--~ [7 ] = "logosOffSelector ",
+--~ [8 ] = "rebusPicturesOnSelector",
+--~ [9 ] = "rebusPicturesOffSelector",
+--~ [10] = "diphthongLigaturesOnSelector",
+--~ [11] = "diphthongLigaturesOffSelector",
+--~ [12] = "squaredLigaturesOnSelector",
+--~ [13] = "squaredLigaturesOffSelector",
+--~ [14] = "abbrevSquaredLigaturesOnSelector",
+--~ [15] = "abbrevSquaredLigaturesOffSelector",
+--~ },
+--~ [ 2] = {
+--~ name = "cursiveConnectionType",
+--~ [ 0] = "unconnectedSelector",
+--~ [ 1] = "partiallyConnectedSelector",
+--~ [ 2] = "cursiveSelector ",
+--~ },
+--~ [ 3] = {
+--~ name = "letterCaseType",
+--~ [ 0] = "upperAndLowerCaseSelector",
+--~ [ 1] = "allCapsSelector ",
+--~ [ 2] = "allLowerCaseSelector",
+--~ [ 3] = "smallCapsSelector ",
+--~ [ 4] = "initialCapsSelector",
+--~ [ 5] = "initialCapsAndSmallCapsSelector",
+--~ },
+--~ [ 4] = {
+--~ name = "verticalSubstitutionType",
+--~ [ 0] = "substituteVerticalFormsOnSelector",
+--~ [ 1] = "substituteVerticalFormsOffSelector",
+--~ },
+--~ [ 5] = {
+--~ name = "linguisticRearrangementType",
+--~ [ 0] = "linguisticRearrangementOnSelector",
+--~ [ 1] = "linguisticRearrangementOffSelector",
+--~ },
+--~ [ 6] = {
+--~ name = "numberSpacingType",
+--~ [ 0] = "monospacedNumbersSelector",
+--~ [ 1] = "proportionalNumbersSelector",
+--~ },
+--~ [ 7] = {
+--~ name = "appleReserved1Type",
+--~ },
+--~ [ 8] = {
+--~ name = "smartSwashType",
+--~ [ 0] = "wordInitialSwashesOnSelector",
+--~ [ 1] = "wordInitialSwashesOffSelector",
+--~ [ 2] = "wordFinalSwashesOnSelector",
+--~ [ 3] = "wordFinalSwashesOffSelector",
+--~ [ 4] = "lineInitialSwashesOnSelector",
+--~ [ 5] = "lineInitialSwashesOffSelector",
+--~ [ 6] = "lineFinalSwashesOnSelector",
+--~ [ 7] = "lineFinalSwashesOffSelector",
+--~ [ 8] = "nonFinalSwashesOnSelector",
+--~ [ 9] = "nonFinalSwashesOffSelector",
+--~ },
+--~ [ 9] = {
+--~ name = "diacriticsType",
+--~ [ 0] = "showDiacriticsSelector",
+--~ [ 1] = "hideDiacriticsSelector",
+--~ [ 2] = "decomposeDiacriticsSelector",
+--~ },
+--~ [10] = {
+--~ name = "verticalPositionType",
+--~ [ 0] = "normalPositionSelector",
+--~ [ 1] = "superiorsSelector ",
+--~ [ 2] = "inferiorsSelector ",
+--~ [ 3] = "ordinalsSelector ",
+--~ },
+--~ [11] = {
+--~ name = "fractionsType",
+--~ [ 0] = "noFractionsSelector",
+--~ [ 1] = "verticalFractionsSelector",
+--~ [ 2] = "diagonalFractionsSelector",
+--~ },
+--~ [12] = {
+--~ name = "appleReserved2Type",
+--~ },
+--~ [13] = {
+--~ name = "overlappingCharactersType",
+--~ [ 0] = "preventOverlapOnSelector",
+--~ [ 1] = "preventOverlapOffSelector",
+--~ },
+--~ [14] = {
+--~ name = "typographicExtrasType",
+--~ [0 ] = "hyphensToEmDashOnSelector",
+--~ [1 ] = "hyphensToEmDashOffSelector",
+--~ [2 ] = "hyphenToEnDashOnSelector",
+--~ [3 ] = "hyphenToEnDashOffSelector",
+--~ [4 ] = "unslashedZeroOnSelector",
+--~ [5 ] = "unslashedZeroOffSelector",
+--~ [6 ] = "formInterrobangOnSelector",
+--~ [7 ] = "formInterrobangOffSelector",
+--~ [8 ] = "smartQuotesOnSelector",
+--~ [9 ] = "smartQuotesOffSelector",
+--~ [10] = "periodsToEllipsisOnSelector",
+--~ [11] = "periodsToEllipsisOffSelector",
+--~ },
+--~ [15] = {
+--~ name = "mathematicalExtrasType",
+--~ [ 0] = "hyphenToMinusOnSelector",
+--~ [ 1] = "hyphenToMinusOffSelector",
+--~ [ 2] = "asteriskToMultiplyOnSelector",
+--~ [ 3] = "asteriskToMultiplyOffSelector",
+--~ [ 4] = "slashToDivideOnSelector",
+--~ [ 5] = "slashToDivideOffSelector",
+--~ [ 6] = "inequalityLigaturesOnSelector",
+--~ [ 7] = "inequalityLigaturesOffSelector",
+--~ [ 8] = "exponentsOnSelector",
+--~ [ 9] = "exponentsOffSelector",
+--~ },
+--~ [16] = {
+--~ name = "ornamentSetsType",
+--~ [ 0] = "noOrnamentsSelector",
+--~ [ 1] = "dingbatsSelector ",
+--~ [ 2] = "piCharactersSelector",
+--~ [ 3] = "fleuronsSelector ",
+--~ [ 4] = "decorativeBordersSelector",
+--~ [ 5] = "internationalSymbolsSelector",
+--~ [ 6] = "mathSymbolsSelector",
+--~ },
+--~ [17] = {
+--~ name = "characterAlternativesType",
+--~ [ 0] = "noAlternatesSelector",
+--~ },
+--~ [18] = {
+--~ name = "designComplexityType",
+--~ [ 0] = "designLevel1Selector",
+--~ [ 1] = "designLevel2Selector",
+--~ [ 2] = "designLevel3Selector",
+--~ [ 3] = "designLevel4Selector",
+--~ [ 4] = "designLevel5Selector",
+--~ },
+--~ [19] = {
+--~ name = "styleOptionsType",
+--~ [ 0] = "noStyleOptionsSelector",
+--~ [ 1] = "displayTextSelector",
+--~ [ 2] = "engravedTextSelector",
+--~ [ 3] = "illuminatedCapsSelector",
+--~ [ 4] = "titlingCapsSelector",
+--~ [ 5] = "tallCapsSelector ",
+--~ },
+--~ [20] = {
+--~ name = "characterShapeType",
+--~ [0 ] = "traditionalCharactersSelector",
+--~ [1 ] = "simplifiedCharactersSelector",
+--~ [2 ] = "jis1978CharactersSelector",
+--~ [3 ] = "jis1983CharactersSelector",
+--~ [4 ] = "jis1990CharactersSelector",
+--~ [5 ] = "traditionalAltOneSelector",
+--~ [6 ] = "traditionalAltTwoSelector",
+--~ [7 ] = "traditionalAltThreeSelector",
+--~ [8 ] = "traditionalAltFourSelector",
+--~ [9 ] = "traditionalAltFiveSelector",
+--~ [10] = "expertCharactersSelector",
+--~ },
+--~ [21] = {
+--~ name = "numberCaseType",
+--~ [ 0] = "lowerCaseNumbersSelector",
+--~ [ 1] = "upperCaseNumbersSelector",
+--~ },
+--~ [22] = {
+--~ name = "textSpacingType",
+--~ [ 0] = "proportionalTextSelector",
+--~ [ 1] = "monospacedTextSelector",
+--~ [ 2] = "halfWidthTextSelector",
+--~ [ 3] = "normallySpacedTextSelector",
+--~ },
+--~ [23] = {
+--~ name = "transliterationType",
+--~ [ 0] = "noTransliterationSelector",
+--~ [ 1] = "hanjaToHangulSelector",
+--~ [ 2] = "hiraganaToKatakanaSelector",
+--~ [ 3] = "katakanaToHiraganaSelector",
+--~ [ 4] = "kanaToRomanizationSelector",
+--~ [ 5] = "romanizationToHiraganaSelector",
+--~ [ 6] = "romanizationToKatakanaSelector",
+--~ [ 7] = "hanjaToHangulAltOneSelector",
+--~ [ 8] = "hanjaToHangulAltTwoSelector",
+--~ [ 9] = "hanjaToHangulAltThreeSelector",
+--~ },
+--~ [24] = {
+--~ name = "annotationType",
+--~ [ 0] = "noAnnotationSelector",
+--~ [ 1] = "boxAnnotationSelector",
+--~ [ 2] = "roundedBoxAnnotationSelector",
+--~ [ 3] = "circleAnnotationSelector",
+--~ [ 4] = "invertedCircleAnnotationSelector",
+--~ [ 5] = "parenthesisAnnotationSelector",
+--~ [ 6] = "periodAnnotationSelector",
+--~ [ 7] = "romanNumeralAnnotationSelector",
+--~ [ 8] = "diamondAnnotationSelector",
+--~ },
+--~ [25] = {
+--~ name = "kanaSpacingType",
+--~ [ 0] = "fullWidthKanaSelector",
+--~ [ 1] = "proportionalKanaSelector",
+--~ },
+--~ [26] = {
+--~ name = "ideographicSpacingType",
+--~ [ 0] = "fullWidthIdeographsSelector",
+--~ [ 1] = "proportionalIdeographsSelector",
+--~ },
+--~ [103] = {
+--~ name = "cjkRomanSpacingType",
+--~ [ 0] = "halfWidthCJKRomanSelector",
+--~ [ 1] = "proportionalCJKRomanSelector",
+--~ [ 2] = "defaultCJKRomanSelector",
+--~ [ 3] = "fullWidthCJKRomanSelector",
+--~ },
+--~ }
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-otf'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utf = unicode.utf8
+
+local concat, getn, utfbyte = table.concat, table.getn, utf.byte
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+
+local trace_private = false trackers.register("otf.private", function(v) trace_private = v end)
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+local trace_features = false trackers.register("otf.features", function(v) trace_features = v end)
+local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end)
+local trace_sequences = false trackers.register("otf.sequences", function(v) trace_sequences = v end)
+local trace_math = false trackers.register("otf.math", function(v) trace_math = v end)
+
+--~ trackers.enable("otf.loading")
+
+local zwnj = 0x200C
+local zwj = 0x200D
+
+--[[ldx--
+<p>The fontforge table has organized lookups in a certain way. A first implementation
+of this code was organized featurewise: information related to features was
+collected and processing boiled down to a run over the features. The current
+implementation honors the order in the main feature table. Since we can reorder this
+table as we want, we can eventually support several models of processing. We kept
+the static as well as dynamic feature processing, because it had proved to be
+rather useful. The formerly three loop variants have beem discarded but will
+reapear at some time.</p>
+
+<itemize>
+<item>we loop over all lookups</item>
+<item>for each lookup we do a run over the list of glyphs</item>
+<item>but we only process them for features that are enabled</item>
+<item>if we're dealing with a contextual lookup, we loop over all contexts</item>
+<item>in that loop we quit at a match and then process the list of sublookups</item>
+<item>we always continue after the match</item>
+</itemize>
+
+<p>In <l n='context'/> we do this for each font that is used in a list, so in
+practice we have quite some nested loops.</p>
+
+<p>We process the whole list and then consult the glyph nodes. An alternative approach
+is to collect strings of characters using the same font including spaces (because some
+lookups involve spaces). However, we then need to reconstruct the list which is no fun.
+Also, we need to carry quite some information, like attributes, so eventually we don't
+gain much (if we gain something at all).</p>
+
+<p>Another consideration has been to operate on sublists (subhead, subtail) but again
+this would complicate matters as we then neext to keep track of a changing subhead
+and subtail. On the other hand, this might save some runtime. The number of changes
+involved is not that large. This only makes sense when we have many fonts in a list
+and don't change to frequently.</p>
+--ldx]]--
+
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+fonts.tfm = fonts.tfm or { }
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local fontdata = fonts.ids
+
+otf.tables = otf.tables or { } -- defined in font-ott.lua
+otf.meanings = otf.meanings or { } -- defined in font-ott.lua
+otf.tables.features = otf.tables.features or { } -- defined in font-ott.lua
+otf.tables.languages = otf.tables.languages or { } -- defined in font-ott.lua
+otf.tables.scripts = otf.tables.scripts or { } -- defined in font-ott.lua
+
+otf.features = otf.features or { }
+otf.features.list = otf.features.list or { }
+otf.features.default = otf.features.default or { }
+
+otf.enhancers = otf.enhancers or { }
+otf.glists = { "gsub", "gpos" }
+
+otf.version = 2.626 -- beware: also sync font-mis.lua
+otf.pack = true -- beware: also sync font-mis.lua
+otf.syncspace = true
+otf.notdef = false
+otf.cache = containers.define("fonts", "otf", otf.version, true)
+otf.cleanup_aat = false -- only context
+
+--[[ldx--
+<p>We start with a lot of tables and related functions.</p>
+--ldx]]--
+
+otf.tables.global_fields = table.tohash {
+ "lookups",
+ "glyphs",
+ "subfonts",
+ "luatex",
+ "pfminfo",
+ "cidinfo",
+ "tables",
+ "names",
+ "unicodes",
+ "names",
+ "anchor_classes",
+ "kern_classes",
+ "gpos",
+ "gsub"
+}
+
+otf.tables.valid_fields = {
+ "anchor_classes",
+ "ascent",
+ "cache_version",
+ "cidinfo",
+ "copyright",
+ "creationtime",
+ "descent",
+ "design_range_bottom",
+ "design_range_top",
+ "design_size",
+ "encodingchanged",
+ "extrema_bound",
+ "familyname",
+ "fontname",
+ "fontstyle_id",
+ "fontstyle_name",
+ "fullname",
+ "glyphs",
+ "hasvmetrics",
+ "head_optimized_for_cleartype",
+ "horiz_base",
+ "issans",
+ "isserif",
+ "italicangle",
+ "kerns",
+ "lookups",
+ -- "luatex",
+ "macstyle",
+ "modificationtime",
+ "onlybitmaps",
+ "origname",
+ "os2_version",
+ "pfminfo",
+ "private",
+ "serifcheck",
+ "sfd_version",
+ -- "size",
+ "strokedfont",
+ "strokewidth",
+ "subfonts",
+ "table_version",
+ -- "tables",
+ -- "ttf_tab_saved",
+ "ttf_tables",
+ "uni_interp",
+ "uniqueid",
+ "units_per_em",
+ "upos",
+ "use_typo_metrics",
+ "uwidth",
+ "validation_state",
+ "verbose",
+ "version",
+ "vert_base",
+ "weight",
+ "weight_width_slope_only",
+ "xuid",
+}
+
+--[[ldx--
+<p>Here we go.</p>
+--ldx]]--
+
+local function load_featurefile(ff,featurefile)
+ if featurefile then
+ featurefile = resolvers.find_file(file.addsuffix(featurefile,'fea')) -- "FONTFEATURES"
+ if featurefile and featurefile ~= "" then
+ if trace_loading then
+ logs.report("load otf", "featurefile: %s", featurefile)
+ end
+ fontloader.apply_featurefile(ff, featurefile)
+ end
+ end
+end
+
+function otf.enhance(name,data,filename,verbose)
+ local enhancer = otf.enhancers[name]
+ if enhancer then
+ if (verbose ~= nil and verbose) or trace_loading then
+ logs.report("load otf","enhance: %s",name)
+ end
+ enhancer(data,filename)
+ end
+end
+
+local enhancers = {
+ -- pack and unpack are handled separately; they might even be moved
+ -- away from the enhancers namespace
+ "patch bugs",
+ "merge cid fonts", "prepare unicode", "cleanup ttf tables", "compact glyphs", "reverse coverage",
+ "cleanup aat", "enrich with features", "add some missing characters",
+ "reorganize kerns", -- moved here
+ "flatten glyph lookups", "flatten anchor tables", "flatten feature tables",
+ "prepare luatex tables",
+ "analyse features", "rehash features",
+ "analyse anchors", "analyse marks", "analyse unicodes", "analyse subtables",
+ "check italic correction","check math",
+ "share widths",
+ "strip not needed data",
+ "migrate metadata",
+}
+
+function otf.load(filename,format,sub,featurefile)
+ local name = file.basename(file.removesuffix(filename))
+ if featurefile then
+ name = name .. "@" .. file.removesuffix(file.basename(featurefile))
+ end
+ if sub == "" then sub = false end
+ local hash = name
+ if sub then
+ hash = hash .. "-" .. sub
+ end
+ hash = containers.cleanname(hash)
+ local data = containers.read(otf.cache(), hash)
+ local size = lfs.attributes(filename,"size") or 0
+ if not data or data.verbose ~= fonts.verbose or data.size ~= size then
+ logs.report("load otf","loading: %s",filename)
+ local ff, messages
+ if sub then
+ ff, messages = fontloader.open(filename,sub)
+ else
+ ff, messages = fontloader.open(filename)
+ end
+ if trace_loading and messages and #messages > 0 then
+ for m=1,#messages do
+ logs.report("load otf","warning: %s",messages[m])
+ end
+ end
+ if ff then
+ load_featurefile(ff,featurefile)
+ data = fontloader.to_table(ff)
+ fontloader.close(ff)
+ if data then
+ logs.report("load otf","file size: %s", size)
+ logs.report("load otf","enhancing ...")
+ for e=1,#enhancers do
+ otf.enhance(enhancers[e],data,filename)
+ end
+ if otf.pack and not fonts.verbose then
+ otf.enhance("pack",data,filename)
+ end
+ data.size = size
+ data.verbose = fonts.verbose
+ logs.report("load otf","saving in cache: %s",filename)
+ data = containers.write(otf.cache(), hash, data)
+ collectgarbage("collect")
+ data = containers.read(otf.cache(), hash) -- this frees the old table and load the sparse one
+ collectgarbage("collect")
+ else
+ logs.report("load otf","loading failed (table conversion error)")
+ end
+ else
+ logs.report("load otf","loading failed (file read error)")
+ end
+ end
+ if data then
+ otf.enhance("unpack",data,filename,false) -- no message here
+ otf.add_dimensions(data)
+ if trace_sequences then
+ otf.show_feature_order(data,filename)
+ end
+ end
+ return data
+end
+
+function otf.add_dimensions(data)
+ -- todo: forget about the width if it's the defaultwidth (saves mem)
+ -- we could also build the marks hash here (instead of storing it)
+ if data then
+ local force = otf.notdef
+ local luatex = data.luatex
+ local defaultwidth = luatex.defaultwidth or 0
+ local defaultheight = luatex.defaultheight or 0
+ local defaultdepth = luatex.defaultdepth or 0
+ for _, d in next, data.glyphs do
+ local bb, wd = d.boundingbox, d.width
+ if not wd then
+ d.width = defaultwidth
+ elseif wd ~= 0 and d.class == "mark" then
+ d.width = -wd
+ end
+ if force and not d.name then
+ d.name = ".notdef"
+ end
+ if bb then
+ local ht, dp = bb[4], -bb[2]
+ if ht == 0 or ht < 0 then
+ -- no need to set it and no negative heights, nil == 0
+ else
+ d.height = ht
+ end
+ if dp == 0 or dp < 0 then
+ -- no negative depths and no negative depths, nil == 0
+ else
+ d.depth = dp
+ end
+ end
+ end
+ end
+end
+
+function otf.show_feature_order(otfdata,filename)
+ local sequences = otfdata.luatex.sequences
+ if sequences and #sequences > 0 then
+ if trace_loading then
+ logs.report("otf check","font %s has %s sequences",filename,#sequences)
+ logs.report("otf check"," ")
+ end
+ for nos=1,#sequences do
+ local sequence = sequences[nos]
+ local typ = sequence.type or "no-type"
+ local name = sequence.name or "no-name"
+ local subtables = sequence.subtables or { "no-subtables" }
+ local features = sequence.features
+ if trace_loading then
+ logs.report("otf check","%3i %-15s %-20s [%s]",nos,name,typ,concat(subtables,","))
+ end
+ if features then
+ for feature, scripts in next, features do
+ local tt = { }
+ for script, languages in next, scripts do
+ local ttt = { }
+ for language, _ in next, languages do
+ ttt[#ttt+1] = language
+ end
+ tt[#tt+1] = format("[%s: %s]",script,concat(ttt," "))
+ end
+ if trace_loading then
+ logs.report("otf check"," %s: %s",feature,concat(tt," "))
+ end
+ end
+ end
+ end
+ if trace_loading then
+ logs.report("otf check","\n")
+ end
+ elseif trace_loading then
+ logs.report("otf check","font %s has no sequences",filename)
+ end
+end
+
+-- todo: normalize, design_size => designsize
+
+otf.enhancers["prepare luatex tables"] = function(data,filename)
+ data.luatex = data.luatex or { }
+ local luatex = data.luatex
+ luatex.filename = filename
+ luatex.version = otf.version
+ luatex.creator = "context mkiv"
+end
+
+otf.enhancers["cleanup aat"] = function(data,filename)
+ if otf.cleanup_aat then
+ end
+end
+
+local function analyze_features(g, features)
+ if g then
+ local t, done = { }, { }
+ for k=1,#g do
+ local f = features or g[k].features
+ if f then
+ for k=1,#f do
+ -- scripts and tag
+ local tag = f[k].tag
+ if not done[tag] then
+ t[#t+1] = tag
+ done[tag] = true
+ end
+ end
+ end
+ end
+ if #t > 0 then
+ return t
+ end
+ end
+ return nil
+end
+
+otf.enhancers["analyse features"] = function(data,filename)
+ -- local luatex = data.luatex
+ -- luatex.gposfeatures = analyze_features(data.gpos)
+ -- luatex.gsubfeatures = analyze_features(data.gsub)
+end
+
+otf.enhancers["rehash features"] = function(data,filename)
+ local features = { }
+ data.luatex.features = features
+ for k, what in next, otf.glists do
+ local dw = data[what]
+ if dw then
+ local f = { }
+ features[what] = f
+ for i=1,#dw do
+ local d= dw[i]
+ local dfeatures = d.features
+ if dfeatures then
+ for i=1,#dfeatures do
+ local df = dfeatures[i]
+ local tag = strip(lower(df.tag))
+ local ft = f[tag] if not ft then ft = {} f[tag] = ft end
+ local dscripts = df.scripts
+ for script, languages in next, dscripts do
+ script = strip(lower(script))
+ local fts = ft[script] if not fts then fts = {} ft[script] = fts end
+ for i=1,#languages do
+ fts[strip(lower(languages[i]))] = true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["analyse anchors"] = function(data,filename)
+ local classes = data.anchor_classes
+ local luatex = data.luatex
+ local anchor_to_lookup, lookup_to_anchor = { }, { }
+ luatex.anchor_to_lookup, luatex.lookup_to_anchor = anchor_to_lookup, lookup_to_anchor
+ if classes then
+ for c=1,#classes do
+ local class = classes[c]
+ local anchor = class.name
+ local lookups = class.lookup
+ if type(lookups) ~= "table" then
+ lookups = { lookups }
+ end
+ local a = anchor_to_lookup[anchor]
+ if not a then a = { } anchor_to_lookup[anchor] = a end
+ for l=1,#lookups do
+ local lookup = lookups[l]
+ local l = lookup_to_anchor[lookup]
+ if not l then l = { } lookup_to_anchor[lookup] = l end
+ l[anchor] = true
+ a[lookup] = true
+ end
+ end
+ end
+end
+
+otf.enhancers["analyse marks"] = function(data,filename)
+ local glyphs = data.glyphs
+ local marks = { }
+ data.luatex.marks = marks
+ for unicode, index in next, data.luatex.indices do
+ local glyph = glyphs[index]
+ if glyph.class == "mark" then
+ marks[unicode] = true
+ end
+ end
+end
+
+local other = lpeg.C((1 - lpeg.S("_."))^0)
+local ligsplitter = lpeg.Ct(other * (lpeg.P("_") * other)^0)
+
+--~ print(splitter:match("this"))
+--~ print(splitter:match("this.that"))
+--~ print(splitter:match("such_so_more"))
+--~ print(splitter:match("such_so_more.that"))
+
+otf.enhancers["analyse unicodes"] = function(data,filename)
+ local unicodes = data.luatex.unicodes
+ -- we need to move this code
+ unicodes['space'] = unicodes['space'] or 32 -- handly later on
+ unicodes['hyphen'] = unicodes['hyphen'] or 45 -- handly later on
+ unicodes['zwj'] = unicodes['zwj'] or zwj -- handly later on
+ unicodes['zwnj'] = unicodes['zwnj'] or zwnj -- handly later on
+ -- the tounicode mapping is sparse and only needed for alternatives
+ local tounicode, originals, ns, nl, private, unknown = { }, { }, 0, 0, fonts.private, format("%04X",utfbyte("?"))
+ data.luatex.tounicode, data.luatex.originals = tounicode, originals
+ for index, glyph in next, data.glyphs do
+ local name, unic = glyph.name, glyph.unicode or -1 -- play safe
+ if unic == -1 or unic >= private or (unic >= 0xE000 and unic <= 0xF8FF) or unic == 0xFFFE or unic == 0xFFFF then
+ -- a.whatever or a_b_c.whatever or a_b_c
+ local split = ligsplitter:match(name)
+ if #split == 0 then
+ -- skip
+ elseif #split == 1 then
+ local u = unicodes[split[1]]
+ if u then
+ if type(u) == "table" then
+ u = u[1]
+ end
+ if u < 0x10000 then
+ originals[index], tounicode[index] = u, format("%04X",u)
+ else
+ originals[index], tounicode[index] = u, format("%04X%04X",u/1024+0xD800,u%1024+0xDC00)
+ end
+ ns = ns + 1
+ else
+ originals[index], tounicode[index] = 0xFFFD, "FFFD"
+ end
+ else
+ local as = { }
+ for l=1,#split do
+ local u = unicodes[split[l]]
+ if not u then
+ as[l], split[l] = 0xFFFD, "FFFD"
+ else
+ if type(u) == "table" then
+ u = u[1]
+ end
+ if u < 0x10000 then
+ as[l], split[l] = u, format("%04X",u)
+ else
+ as[l], split[l] = u, format("%04X%04X",u/1024+0xD800,u%1024+0xDC00)
+ end
+ end
+ end
+ split = concat(split)
+ if split ~= "" then
+ originals[index], tounicode[index] = as, split
+ nl = nl + 1
+ else
+ originals[index], tounicode[index] = 0xFFFD, "FFFD"
+ end
+ end
+ end
+ end
+ if trace_loading and (ns > 0 or nl > 0) then
+ logs.report("load otf","enhance: %s tounicode entries added (%s ligatures)",nl+ns, ns)
+ end
+end
+
+otf.enhancers["analyse subtables"] = function(data,filename)
+ data.luatex = data.luatex or { }
+ local luatex = data.luatex
+ local sequences = { }
+ local lookups = { }
+ luatex.sequences = sequences
+ luatex.lookups = lookups
+ for _, g in next, { data.gsub, data.gpos } do
+ for k=1,#g do
+ local gk = g[k]
+
+local typ = gk.type
+if typ == "gsub_contextchain" or typ == "gpos_contextchain" then
+ gk.chain = 1
+elseif typ == "gsub_reversecontextchain" or typ == "gpos_reversecontextchain" then
+ gk.chain = -1
+else
+ gk.chain = 0
+end
+
+ local features = gk.features
+ if features then
+ sequences[#sequences+1] = gk
+ -- scripts, tag, ismac
+ local t = { }
+ for f=1,#features do
+ local feature = features[f]
+ local hash = { }
+ -- only script and langs matter
+ for s, languages in next, feature.scripts do
+ s = lower(s)
+ local h = hash[s]
+ if not h then h = { } hash[s] = h end
+ for l=1,#languages do
+ h[strip(lower(languages[l]))] = true
+ end
+ end
+ t[feature.tag] = hash
+ end
+ gk.features = t
+ else
+ lookups[gk.name] = gk
+ gk.name = nil
+ end
+ local subtables = gk.subtables
+ if subtables then
+ local t = { }
+ for s=1,#subtables do
+ local subtable = subtables[s]
+ local name = subtable.name
+ t[#t+1] = name
+ end
+ gk.subtables = t
+ end
+ local flags = gk.flags
+ if flags then
+ gk.flags = { -- forcing false packs nicer
+ (flags.ignorecombiningmarks and "mark") or false,
+ (flags.ignoreligatures and "ligature") or false,
+ (flags.ignorebaseglyphs and "base") or false,
+ flags.r2l or false
+ }
+ end
+ end
+ end
+end
+
+otf.enhancers["merge cid fonts"] = function(data,filename)
+ -- we can also move the names to data.luatex.names which might
+ -- save us some more memory (at the cost of harder tracing)
+ if data.subfonts and table.is_empty(data.glyphs) then
+ local cidinfo = data.cidinfo
+ local verbose = fonts.verbose
+ if cidinfo.registry then
+ local cidmap = fonts.cid.getmap and fonts.cid.getmap(cidinfo.registry,cidinfo.ordering,cidinfo.supplement)
+ if cidmap then
+ local glyphs, uni_to_int, int_to_uni, nofnames, nofunicodes = { }, { }, { }, 0, 0
+ local unicodes, names = cidmap.unicodes, cidmap.names
+ for n, subfont in next, data.subfonts do
+ for index, g in next, subfont.glyphs do
+ if not next(g) then
+ -- dummy entry
+ else
+ local unicode, name = unicodes[index], names[index]
+ g.cidindex = n
+ g.boundingbox = g.boundingbox -- or zerobox
+ g.name = g.name or name or "unknown"
+ if unicode then
+ uni_to_int[unicode] = index
+ int_to_uni[index] = unicode
+ nofunicodes = nofunicodes + 1
+ g.unicode = unicode
+ elseif name then
+ nofnames = nofnames + 1
+ g.unicode = -1
+ end
+ glyphs[index] = g
+ end
+ end
+ subfont.glyphs = nil
+ end
+ if trace_loading then
+ logs.report("load otf","cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes, nofnames, nofunicodes+nofnames)
+ end
+ data.glyphs = glyphs
+ data.map = data.map or { }
+ data.map.map = uni_to_int
+ data.map.backmap = int_to_uni
+ elseif trace_loading then
+ logs.report("load otf","unable to remap cid font, missing cid file for %s",filename)
+ end
+ elseif trace_loading then
+ logs.report("load otf","font %s has no glyphs",filename)
+ end
+ end
+end
+
+otf.enhancers["prepare unicode"] = function(data,filename)
+ local luatex = data.luatex
+ if not luatex then luatex = { } data.luatex = luatex end
+ local indices, unicodes, multiples, internals = { }, { }, { }, { }
+ local glyphs = data.glyphs
+ local mapmap = data.map
+ if not mapmap then
+ logs.report("load otf","no map in %s",filename)
+ mapmap = { }
+ data.map = { map = mapmap }
+ elseif not mapmap.map then
+ logs.report("load otf","no unicode map in %s",filename)
+ mapmap = { }
+ data.map.map = mapmap
+ else
+ mapmap = mapmap.map
+ end
+ local criterium = fonts.private
+ local private = fonts.private
+ for index, glyph in next, glyphs do
+ if index > 0 then
+ local name = glyph.name
+ if name then
+ local unicode = glyph.unicode
+ if unicode == -1 or unicode >= criterium then
+ glyph.unicode = private
+ indices[private] = index
+ unicodes[name] = private
+ internals[index] = true
+ if trace_private then
+ logs.report("load otf","enhance: glyph %s at index U+%04X is moved to private unicode slot U+%04X",name,index,private)
+ end
+ private = private + 1
+ else
+ indices[unicode] = index
+ unicodes[name] = unicode
+ end
+ end
+ end
+ end
+ -- beware: the indeces table is used to initialize the tfm table
+ for unicode, index in next, mapmap do
+ if not internals[index] then
+ local name = glyphs[index].name
+ if name then
+ local un = unicodes[name]
+ if not un then
+ unicodes[name] = unicode -- or 0
+ elseif type(un) == "number" then
+ if un ~= unicode then
+ multiples[#multiples+1] = name
+ unicodes[name] = { un, unicode }
+ indices[unicode] = index
+ end
+ else
+ local ok = false
+ for u=1,#un do
+ if un[u] == unicode then
+ ok = true
+ break
+ end
+ end
+ if not ok then
+ multiples[#multiples+1] = name
+ un[#un+1] = unicode
+ indices[unicode] = index
+ end
+ end
+ end
+ end
+ end
+ if trace_loading then
+ if #multiples > 0 then
+ logs.report("load otf","%s glyph are reused: %s",#multiples, concat(multiples," "))
+ else
+ logs.report("load otf","no glyph are reused")
+ end
+ end
+ luatex.indices = indices
+ luatex.unicodes = unicodes
+ luatex.private = private
+end
+
+otf.enhancers["cleanup ttf tables"] = function(data,filename)
+ local ttf_tables = data.ttf_tables
+ if ttf_tables then
+ for k=1,#ttf_tables do
+ if ttf_tables[k].data then ttf_tables[k].data = "deleted" end
+ end
+ end
+ data.ttf_tab_saved = nil
+end
+
+otf.enhancers["compact glyphs"] = function(data,filename)
+ table.compact(data.glyphs) -- needed?
+ if data.subfonts then
+ for _, subfont in next, data.subfonts do
+ table.compact(subfont.glyphs) -- needed?
+ end
+ end
+end
+
+otf.enhancers["reverse coverage"] = function(data,filename)
+ -- we prefer the before lookups in a normal order
+ if data.lookups then
+ for _, v in next, data.lookups do
+ if v.rules then
+ for _, vv in next, v.rules do
+ local c = vv.coverage
+ if c and c.before then
+ c.before = table.reverse(c.before)
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["check italic correction"] = function(data,filename)
+ local glyphs = data.glyphs
+ local ok = false
+ for index, glyph in next, glyphs do
+ local ic = glyph.italic_correction
+ if ic then
+ if ic ~= 0 then
+ glyph.italic = ic
+ end
+ glyph.italic_correction = nil
+ ok = true
+ end
+ end
+ -- we can use this to avoid calculations
+ otf.tables.valid_fields[#otf.tables.valid_fields+1] = "has_italic"
+ data.has_italic = true
+end
+
+otf.enhancers["check math"] = function(data,filename)
+ if data.math then
+ -- we move the math stuff into a math subtable because we then can
+ -- test faster in the tfm copy
+ local glyphs = data.glyphs
+ local unicodes = data.luatex.unicodes
+ for index, glyph in next, glyphs do
+ local mk = glyph.mathkern
+ local hv = glyph.horiz_variants
+ local vv = glyph.vert_variants
+ if mk or hv or vv then
+ local math = { }
+ glyph.math = math
+ if mk then
+ for k, v in next, mk do
+ if not next(v) then
+ mk[k] = nil
+ end
+ end
+ math.kerns = mk
+ glyph.mathkern = nil
+ end
+ if hv then
+ math.horiz_variants = hv.variants
+ local p = hv.parts
+ if p then
+ if #p>0 then
+ for i=1,#p do
+ local pi = p[i]
+ pi.glyph = unicodes[pi.component] or 0
+ end
+ math.horiz_parts = p
+ end
+ end
+ local ic = hv.italic_correction
+ if ic and ic ~= 0 then
+ math.horiz_italic_correction = ic
+ end
+ glyph.horiz_variants = nil
+ end
+ if vv then
+ local uc = unicodes[index]
+ math.vert_variants = vv.variants
+ local p = vv.parts
+ if p then
+ if #p>0 then
+ for i=1,#p do
+ local pi = p[i]
+ pi.glyph = unicodes[pi.component] or 0
+ end
+ math.vert_parts = p
+ end
+ end
+ local ic = vv.italic_correction
+ if ic and ic ~= 0 then
+ math.vert_italic_correction = ic
+ end
+ glyph.vert_variants = nil
+ end
+ local ic = glyph.italic_correction
+ if ic then
+ if ic ~= 0 then
+ math.italic_correction = ic
+ end
+ glyph.italic_correction = nil
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["share widths"] = function(data,filename)
+ local glyphs = data.glyphs
+ local widths = { }
+ for index, glyph in next, glyphs do
+ local width = glyph.width
+ widths[width] = (widths[width] or 0) + 1
+ end
+ -- share width for cjk fonts
+ local wd, most = 0, 1
+ for k,v in next, widths do
+ if v > most then
+ wd, most = k, v
+ end
+ end
+ if most > 1000 then
+ if trace_loading then
+ logs.report("load otf", "most common width: %s (%s times), sharing (cjk font)",wd,most)
+ end
+ for k, v in next, glyphs do
+ if v.width == wd then
+ v.width = nil
+ end
+ end
+ data.luatex.defaultwidth = wd
+ end
+end
+
+-- kern: ttf has a table with kerns
+
+otf.enhancers["reorganize kerns"] = function(data,filename)
+ local glyphs, mapmap, unicodes = data.glyphs, data.luatex.indices, data.luatex.unicodes
+ local mkdone = false
+ for index, glyph in next, data.glyphs do
+ if glyph.kerns then
+ local mykerns = { }
+ for k,v in next, glyph.kerns do
+ local vc, vo, vl = v.char, v.off, v.lookup
+ if vc and vo and vl then -- brrr, wrong! we miss the non unicode ones
+ local uvc = unicodes[vc]
+ if not uvc then
+ if trace_loading then
+ logs.report("load otf","problems with unicode %s of kern %s at glyph %s",vc,k,index)
+ end
+ else
+ if type(vl) ~= "table" then
+ vl = { vl }
+ end
+ for l=1,#vl do
+ local vll = vl[l]
+ local mkl = mykerns[vll]
+ if not mkl then
+ mkl = { }
+ mykerns[vll] = mkl
+ end
+ if type(uvc) == "table" then
+ for u=1,#uvc do
+ mkl[uvc[u]] = vo
+ end
+ else
+ mkl[uvc] = vo
+ end
+ end
+ end
+ end
+ end
+ glyph.mykerns = mykerns
+ glyph.kerns = nil -- saves space and time
+ mkdone = true
+ end
+ end
+ if trace_loading and mkdone then
+ logs.report("load otf", "replacing 'kerns' tables by 'mykerns' tables")
+ end
+ if data.kerns then
+ if trace_loading then
+ logs.report("load otf", "removing global 'kern' table")
+ end
+ data.kerns = nil
+ end
+ local dgpos = data.gpos
+ if dgpos then
+ for gp=1,#dgpos do
+ local gpos = dgpos[gp]
+ local subtables = gpos.subtables
+ if subtables then
+ for s=1,#subtables do
+ local subtable = subtables[s]
+ local kernclass = subtable.kernclass -- name is inconsistent with anchor_classes
+ if kernclass then
+ for k=1,#kernclass do
+ local kcl = kernclass[k]
+ local firsts, seconds, offsets, lookups = kcl.firsts, kcl.seconds, kcl.offsets, kcl.lookup -- singular
+ if type(lookups) ~= "table" then
+ lookups = { lookups }
+ end
+ for l=1,#lookups do
+ local lookup = lookups[l]
+ local maxfirsts, maxseconds = getn(firsts), getn(seconds)
+ if trace_loading then
+ logs.report("load otf", "adding kernclass %s with %s times %s pairs",lookup, maxfirsts, maxseconds)
+ end
+ for fk, fv in next, firsts do
+ for first in gmatch(fv,"[^ ]+") do
+ local first_unicode = unicodes[first]
+ if type(first_unicode) == "number" then
+ first_unicode = { first_unicode }
+ end
+ for f=1,#first_unicode do
+ local glyph = glyphs[mapmap[first_unicode[f]]]
+ if glyph then
+ local mykerns = glyph.mykerns
+ if not mykerns then
+ mykerns = { } -- unicode indexed !
+ glyph.mykerns = mykerns
+ end
+ local lookupkerns = mykerns[lookup]
+ if not lookupkerns then
+ lookupkerns = { }
+ mykerns[lookup] = lookupkerns
+ end
+ for sk, sv in next, seconds do
+ local offset = offsets[(fk-1) * maxseconds + sk]
+ --~ local offset = offsets[sk] -- (fk-1) * maxseconds + sk]
+ for second in gmatch(sv,"[^ ]+") do
+ local second_unicode = unicodes[second]
+ if type(second_unicode) == "number" then
+ lookupkerns[second_unicode] = offset
+ else
+ for s=1,#second_unicode do
+ lookupkerns[second_unicode[s]] = offset
+ end
+ end
+ end
+ end
+ elseif trace_loading then
+ logs.report("load otf", "no glyph data for U+%04X", first_unicode[f])
+ end
+ end
+ end
+ end
+ end
+ end
+ subtable.comment = "The kernclass table is merged into mykerns in the indexed glyph tables."
+ subtable.kernclass = { }
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["strip not needed data"] = function(data,filename)
+ local verbose = fonts.verbose
+ local int_to_uni = data.luatex.unicodes
+ for k, v in next, data.glyphs do
+ local d = v.dependents
+ if d then v.dependents = nil end
+ local a = v.altuni
+ if a then v.altuni = nil end
+ if verbose then
+ local code = int_to_uni[k]
+ -- looks like this is done twice ... bug?
+ if code then
+ local vu = v.unicode
+ if not vu then
+ v.unicode = code
+ elseif type(vu) == "table" then
+ if vu[#vu] == code then
+ -- weird
+ else
+ vu[#vu+1] = code
+ end
+ elseif vu ~= code then
+ v.unicode = { vu, code }
+ end
+ end
+ else
+ v.unicode = nil
+ v.index = nil
+ end
+ end
+ data.luatex.comment = "Glyph tables have their original index. When present, mykern tables are indexed by unicode."
+ data.map = nil
+ data.names = nil -- funny names for editors
+ data.glyphcnt = nil
+ data.glyphmax = nil
+ if true then
+ data.gpos = nil
+ data.gsub = nil
+ data.anchor_classes = nil
+ end
+end
+
+otf.enhancers["migrate metadata"] = function(data,filename)
+ local global_fields = otf.tables.global_fields
+ local metadata = { }
+ for k,v in next, data do
+ if not global_fields[k] then
+ metadata[k] = v
+ data[k] = nil
+ end
+ end
+ data.metadata = metadata
+ -- goodies
+ local pfminfo = data.pfminfo
+ metadata.isfixedpitch = metadata.isfixedpitch or (pfminfo.panose and pfminfo.panose["proportion"] == "Monospaced")
+ metadata.charwidth = pfminfo and pfminfo.avgwidth
+end
+
+otf.enhancers["flatten glyph lookups"] = function(data,filename)
+ for k, v in next, data.glyphs do
+ if v.lookups then
+ for kk, vv in next, v.lookups do
+ for kkk=1,#vv do
+ local vvv = vv[kkk]
+ local s = vvv.specification
+ if s then
+ local t = vvv.type
+ if t == "ligature" then
+ vv[kkk] = { "ligature", s.components, s.char }
+ elseif t == "alternate" then
+ vv[kkk] = { "alternate", s.components }
+ elseif t == "substitution" then
+ vv[kkk] = { "substitution", s.variant }
+ elseif t == "multiple" then
+ vv[kkk] = { "multiple", s.components }
+ elseif t == "position" then
+ vv[kkk] = { "position", { s.x or 0, s.y or 0, s.h or 0, s.v or 0 } }
+ elseif t == "pair" then
+ local one, two, paired = s.offsets[1], s.offsets[2], s.paired or ""
+ if one then
+ if two then
+ vv[kkk] = { "pair", paired, { one.x or 0, one.y or 0, one.h or 0, one.v or 0 }, { two.x or 0, two.y or 0, two.h or 0, two.v or 0 } }
+ else
+ vv[kkk] = { "pair", paired, { one.x or 0, one.y or 0, one.h or 0, one.v or 0 } }
+ end
+ else
+ if two then
+ vv[kkk] = { "pair", paired, { }, { two.x or 0, two.y or 0, two.h or 0, two.v or 0} } -- maybe nil instead of { }
+ else
+ vv[kkk] = { "pair", paired }
+ end
+ end
+ else
+ if trace_loading then
+ logs.report("load otf", "flattening needed, report to context list")
+ end
+ for a, b in next, s do
+ if trace_loading and vvv[a] then
+ logs.report("load otf", "flattening conflict, report to context list")
+ end
+ vvv[a] = b
+ end
+ vvv.specification = nil
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["flatten anchor tables"] = function(data,filename)
+ for k, v in next, data.glyphs do
+ if v.anchors then
+ for kk, vv in next, v.anchors do
+ for kkk, vvv in next, vv do
+ if vvv.x or vvv.y then
+ vv[kkk] = { vvv.x or 0, vvv.y or 0 }
+ else
+ for kkkk=1,#vvv do
+ local vvvv = vvv[kkkk]
+ vvv[kkkk] = { vvvv.x or 0, vvvv.y or 0 }
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers["flatten feature tables"] = function(data,filename)
+ -- is this needed? do we still use them at all?
+ for _, tag in next, otf.glists do
+ if data[tag] then
+ if trace_loading then
+ logs.report("load otf", "flattening %s table", tag)
+ end
+ for k, v in next, data[tag] do
+ local features = v.features
+ if features then
+ for kk=1,#features do
+ local vv = features[kk]
+ local t = { }
+ local scripts = vv.scripts
+ for kkk=1,#scripts do
+ local vvv = scripts[kkk]
+ t[vvv.script] = vvv.langs
+ end
+ vv.scripts = t
+ end
+ end
+ end
+ end
+ end
+end
+
+otf.enhancers.patches = otf.enhancers.patches or { }
+
+otf.enhancers["patch bugs"] = function(data,filename)
+ local basename = file.basename(lower(filename))
+ for pattern, action in next, otf.enhancers.patches do
+ if find(basename,pattern) then
+ action(data,filename)
+ end
+ end
+end
+
+-- tex features
+
+fonts.otf.enhancers["enrich with features"] = function(data,filename)
+ -- later, ctx only
+end
+
+function otf.features.register(name,default)
+ otf.features.list[#otf.features.list+1] = name
+ otf.features.default[name] = default
+end
+
+function otf.set_features(tfmdata,features)
+ local processes = { }
+ if not table.is_empty(features) then
+ local lists = {
+ fonts.triggers,
+ fonts.processors,
+ fonts.manipulators,
+ }
+ local mode = tfmdata.mode or fonts.mode -- or features.mode
+ local initializers = fonts.initializers
+ local fi = initializers[mode]
+ if fi then
+ local fiotf = fi.otf
+ if fiotf then
+ local done = { }
+ for l=1,4 do
+ local list = lists[l]
+ if list then
+ for i=1,#list do
+ local f = list[i]
+ local value = features[f]
+ if value and fiotf[f] then -- brr
+ if not done[f] then -- so, we can move some to triggers
+ if trace_features then
+ logs.report("define otf","initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown', tfmdata.fullname or 'unknown')
+ end
+ fiotf[f](tfmdata,value) -- can set mode (no need to pass otf)
+ mode = tfmdata.mode or fonts.mode -- keep this, mode can be set local !
+ local im = initializers[mode]
+ if im then
+ fiotf = initializers[mode].otf
+ end
+ done[f] = true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ local fm = fonts.methods[mode]
+ if fm then
+ local fmotf = fm.otf
+ if fmotf then
+ for l=1,4 do
+ local list = lists[l]
+ if list then
+ for i=1,#list do
+ local f = list[i]
+ if fmotf[f] then -- brr
+ if trace_features then
+ logs.report("define otf","installing feature handler %s for mode %s for font %s",f,mode or 'unknown', tfmdata.fullname or 'unknown')
+ end
+ processes[#processes+1] = fmotf[f]
+ end
+ end
+ end
+ end
+ end
+ else
+ -- message
+ end
+ end
+ return processes, features
+end
+
+function otf.otf_to_tfm(specification)
+ local name = specification.name
+ local sub = specification.sub
+ local filename = specification.filename
+ local format = specification.format
+ local features = specification.features.normal
+ local cache_id = specification.hash
+ local tfmdata = containers.read(tfm.cache(),cache_id)
+--~ print(cache_id)
+ if not tfmdata then
+ local otfdata = otf.load(filename,format,sub,features and features.featurefile)
+ if not table.is_empty(otfdata) then
+ otfdata.shared = otfdata.shared or {
+ featuredata = { },
+ anchorhash = { },
+ initialized = false,
+ }
+ tfmdata = otf.copy_to_tfm(otfdata,cache_id)
+ if not table.is_empty(tfmdata) then
+ tfmdata.unique = tfmdata.unique or { }
+ tfmdata.shared = tfmdata.shared or { } -- combine
+ local shared = tfmdata.shared
+ shared.otfdata = otfdata
+ shared.features = features -- default
+ shared.dynamics = { }
+ shared.processes = { }
+ shared.set_dynamics = otf.set_dynamics -- fast access and makes other modules independent
+ -- this will be done later anyway, but it's convenient to have
+ -- them already for fast access
+ tfmdata.luatex = otfdata.luatex
+ tfmdata.indices = otfdata.luatex.indices
+ tfmdata.unicodes = otfdata.luatex.unicodes
+ tfmdata.marks = otfdata.luatex.marks
+ tfmdata.originals = otfdata.luatex.originals
+ tfmdata.changed = { }
+ tfmdata.has_italic = otfdata.metadata.has_italic
+ if not tfmdata.language then tfmdata.language = 'dflt' end
+ if not tfmdata.script then tfmdata.script = 'dflt' end
+ shared.processes, shared.features = otf.set_features(tfmdata,fonts.define.check(features,otf.features.default))
+ end
+ end
+ containers.write(tfm.cache(),cache_id,tfmdata)
+ end
+ return tfmdata
+end
+
+--~ {
+--~ ['boundingbox']={ 95, -458, 733, 1449 },
+--~ ['class']="base",
+--~ ['name']="braceleft",
+--~ ['unicode']=123,
+--~ ['vert_variants']={
+--~ ['italic_correction']=0,
+--~ ['parts']={
+--~ { ['component']="uni23A9", ['endConnectorLength']=1000, ['fullAdvance']=2546, ['is_extender']=0, ['startConnectorLength']=0, }, -- bot
+--~ { ['component']="uni23AA", ['endConnectorLength']=2500, ['fullAdvance']=2501, ['is_extender']=1, ['startConnectorLength']=2500, }, -- rep
+--~ { ['component']="uni23A8", ['endConnectorLength']=1000, ['fullAdvance']=4688, ['is_extender']=0, ['startConnectorLength']=1000, }, -- mid
+--~ { ['component']="uni23AA", ['endConnectorLength']=2500, ['fullAdvance']=2501, ['is_extender']=1, ['startConnectorLength']=2500, }, -- rep
+--~ { ['component']="uni23A7", ['endConnectorLength']=0, ['fullAdvance']=2546, ['is_extender']=0, ['startConnectorLength']=1000, }, -- top
+--~ },
+--~ ['variants']="braceleft braceleft.vsize1 braceleft.vsize2 braceleft.vsize3 braceleft.vsize4 braceleft.vsize5 braceleft.vsize6 braceleft.vsize7",
+--~ },
+--~ ['width']=793,
+--~ },
+
+-- the first version made a top/mid/not extensible table, now we just pass on the variants data
+-- and deal with it in the tfm scaler (there is no longer an extensible table anyway)
+
+-- we cannot share descriptions as virtual fonts might extend them (ok, we could
+-- use a cache with a hash
+
+function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder the tma to unicode (nasty due to one->many)
+ if data then
+ local glyphs, pfminfo, metadata = data.glyphs or { }, data.pfminfo or { }, data.metadata or { }
+ local luatex = data.luatex
+ local unicodes = luatex.unicodes -- names to unicodes
+ local indices = luatex.indices
+ local characters, parameters, math_parameters, descriptions = { }, { }, { }, { }
+ local tfm = {
+ characters = characters,
+ parameters = parameters,
+ math_parameters = math_parameters,
+ descriptions = descriptions,
+ indices = indices,
+ unicodes = unicodes,
+ }
+ -- indices maps from unicodes to indices
+ for u, i in next, indices do
+ characters[u] = { } -- we need this because for instance we add protruding info
+ descriptions[u] = glyphs[i]
+ end
+ -- math
+ if metadata.math then
+ -- parameters
+ for name, value in next, metadata.math do
+ math_parameters[name] = value
+ end
+ -- we could use a subset
+ for u, char in next, characters do
+ local d = descriptions[u]
+ local m = d.math
+ -- we have them shared because that packs nicer
+ -- we could prepare the variants and keep 'm in descriptions
+ if m then
+ local variants = m.horiz_variants
+ if variants then
+ local c = char
+ for n in variants:gmatch("[^ ]+") do
+ local un = unicodes[n]
+ if un and u ~= un then
+ c.next = un
+ c = characters[un]
+ end
+ end
+ c.horiz_variants = m.horiz_parts
+ else
+ local variants = m.vert_variants
+ if variants then
+ local c = char
+ for n in variants:gmatch("[^ ]+") do
+ local un = unicodes[n]
+ if un and u ~= un then
+ c.next = un
+ c = characters[un]
+ end
+ end
+ c.vert_variants = m.vert_parts
+ end
+ end
+ local kerns = m.kerns
+ if kerns then
+ char.mathkerns = kerns
+ end
+ end
+ end
+ end
+ -- end math
+ local designsize = metadata.designsize or metadata.design_size or 100
+ if designsize == 0 then
+ designsize = 100
+ end
+ local spaceunits = 500
+ tfm.units = metadata.units_per_em or 1000
+ -- we need a runtime lookup because of running from cdrom or zip, brrr
+ tfm.filename = resolvers.findbinfile(luatex.filename,"") or luatex.filename
+ tfm.fullname = metadata.fontname or metadata.fullname
+ tfm.encodingbytes = 2
+ tfm.cidinfo = data.cidinfo
+ tfm.cidinfo.registry = tfm.cidinfo.registry or ""
+ tfm.type = "real"
+ tfm.stretch = 0 -- stretch
+ tfm.slant = 0 -- slant
+ tfm.direction = 0
+ tfm.boundarychar_label = 0
+ tfm.boundarychar = 65536
+ tfm.designsize = (designsize/10)*65536
+ tfm.spacer = "500 units"
+ local endash, emdash = 0x20, 0x2014 -- unicodes['space'], unicodes['emdash']
+ if metadata.isfixedpitch then
+ if descriptions[endash] then
+ spaceunits, tfm.spacer = descriptions[endash].width, "space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits, tfm.spacer = descriptions[emdash].width, "emdash"
+ end
+ if not spaceunits and metadata.charwidth then
+ spaceunits, tfm.spacer = metadata.charwidth, "charwidth"
+ end
+ else
+ if descriptions[endash] then
+ spaceunits, tfm.spacer = descriptions[endash].width, "space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits, tfm.spacer = descriptions[emdash].width/2, "emdash/2"
+ end
+ if not spaceunits and metadata.charwidth then
+ spaceunits, tfm.spacer = metadata.charwidth, "charwidth"
+ end
+ end
+ spaceunits = tonumber(spaceunits) or tfm.units/2 -- 500 -- brrr
+ parameters.slant = 0
+ parameters.space = spaceunits -- 3.333 (cmr10)
+ parameters.space_stretch = tfm.units/2 -- 500 -- 1.666 (cmr10)
+ parameters.space_shrink = 1*tfm.units/3 -- 333 -- 1.111 (cmr10)
+ parameters.x_height = 2*tfm.units/5 -- 400
+ parameters.quad = tfm.units -- 1000
+ if spaceunits < 2*tfm.units/5 then
+ -- todo: warning
+ end
+ local italicangle = metadata.italicangle
+ tfm.ascender = math.abs(metadata.ascent or 0)
+ tfm.descender = math.abs(metadata.descent or 0)
+ if italicangle then -- maybe also in afm _
+ tfm.italicangle = italicangle
+ parameters.slant = parameters.slant - math.round(math.tan(italicangle*math.pi/180))
+ end
+ if metadata.isfixedpitch then
+ parameters.space_stretch = 0
+ parameters.space_shrink = 0
+ elseif otf.syncspace then --
+ parameters.space_stretch = spaceunits/2
+ parameters.space_shrink = spaceunits/3
+ end
+ parameters.extra_space = parameters.space_shrink -- 1.111 (cmr10)
+ if pfminfo.os2_xheight and pfminfo.os2_xheight > 0 then
+ parameters.x_height = pfminfo.os2_xheight
+ else
+ local x = 0x78 -- unicodes['x']
+ if x then
+ local x = descriptions[x]
+ if x then
+ parameters.x_height = x.height
+ end
+ end
+ end
+ -- [6]
+ return tfm
+ else
+ return nil
+ end
+end
+
+otf.features.register('mathsize')
+
+function tfm.read_from_open_type(specification)
+ local tfmtable = otf.otf_to_tfm(specification)
+ if tfmtable then
+ local otfdata = tfmtable.shared.otfdata
+ tfmtable.name = specification.name
+ tfmtable.sub = specification.sub
+ local s = specification.size
+ local m = otfdata.metadata.math
+ if m then
+ local f = specification.features
+ if f then
+ local f = f.normal
+ if f and f.mathsize then
+ local mathsize = specification.mathsize or 0
+ if mathsize == 2 then
+ local p = m.ScriptPercentScaleDown
+ if p then
+ local ps = p * specification.textsize / 100
+ if trace_math then
+ logs.report("define font","asked script size: %s, used: %s (%2.2f %%)",s,ps,(ps/s)*100)
+ end
+ s = ps
+ end
+ elseif mathsize == 3 then
+ local p = m.ScriptScriptPercentScaleDown
+ if p then
+ local ps = p * specification.textsize / 100
+ if trace_math then
+ logs.report("define font","asked scriptscript size: %s, used: %s (%2.2f %%)",s,ps,(ps/s)*100)
+ end
+ s = ps
+ end
+ end
+ end
+ end
+ end
+ tfmtable = tfm.scale(tfmtable,s)
+ -- here we resolve the name; file can be relocated, so this info is not in the cache
+ local filename = (otfdata and otfdata.luatex and otfdata.luatex.filename) or specification.filename
+ if not filename then
+ -- try to locate anyway and set otfdata.luatex.filename
+ end
+ if filename then
+ tfmtable.encodingbytes = 2
+ tfmtable.filename = resolvers.findbinfile(filename,"") or filename
+ tfmtable.fullname = otfdata.metadata.fontname or otfdata.metadata.fullname
+ local order = otfdata and otfdata.metadata.order2
+ if order == 0 then
+ tfmtable.format = 'opentype'
+ elseif order == 1 then
+ tfmtable.format = 'truetype'
+ else
+ tfmtable.format = specification.format
+ end
+ tfmtable.name = tfmtable.filename or tfmtable.fullname
+ end
+ fonts.logger.save(tfmtable,file.extname(specification.filename),specification)
+ end
+ return tfmtable
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-otd'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end)
+
+fonts = fonts or { }
+fonts.otf = fonts.otf or { }
+
+local otf = fonts.otf
+local fontdata = fonts.ids
+
+otf.features = otf.features or { }
+otf.features.default = otf.features.default or { }
+
+local context_setups = fonts.define.specify.context_setups
+local context_numbers = fonts.define.specify.context_numbers
+
+local a_to_script = { } otf.a_to_script = a_to_script
+local a_to_language = { } otf.a_to_language = a_to_language
+
+function otf.set_dynamics(font,dynamics,attribute)
+ features = context_setups[context_numbers[attribute]] -- can be moved to caller
+ if features then
+ local script = features.script or 'dflt'
+ local language = features.language or 'dflt'
+ local ds = dynamics[script]
+ if not ds then
+ ds = { }
+ dynamics[script] = ds
+ end
+ local dsl = ds[language]
+ if not dsl then
+ dsl = { }
+ ds[language] = dsl
+ end
+ local dsla = dsl[attribute]
+ if dsla then
+ -- if trace_dynamics then
+ -- logs.report("otf define","using dynamics %s: attribute %s, script %s, language %s",context_numbers[attribute],attribute,script,language)
+ -- end
+ return dsla
+ else
+ local tfmdata = fontdata[font]
+ a_to_script [attribute] = script
+ a_to_language[attribute] = language
+ -- we need to save some values
+ local saved = {
+ script = tfmdata.script,
+ language = tfmdata.language,
+ mode = tfmdata.mode,
+ features = tfmdata.shared.features
+ }
+ tfmdata.mode = "node"
+ tfmdata.language = language
+ tfmdata.script = script
+ tfmdata.shared.features = { }
+ -- end of save
+ dsla = otf.set_features(tfmdata,fonts.define.check(features,otf.features.default))
+ if trace_dynamics then
+ logs.report("otf define","setting dynamics %s: attribute %s, script %s, language %s",context_numbers[attribute],attribute,script,language)
+ end
+ -- we need to restore some values
+ tfmdata.script = saved.script
+ tfmdata.language = saved.language
+ tfmdata.mode = saved.mode
+ tfmdata.shared.features = saved.features
+ -- end of restore
+ dynamics[script][language][attribute] = dsla -- cache
+ return dsla
+ end
+ end
+ return nil -- { }
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-oti'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- i need to check features=yes|no also in relation to hashing
+
+local lower = string.lower
+
+local otf = fonts.otf
+
+otf.default_language = 'latn'
+otf.default_script = 'dflt'
+
+local languages = otf.tables.languages
+local scripts = otf.tables.scripts
+
+function otf.features.language(tfmdata,value)
+ if value then
+ value = lower(value)
+ if languages[value] then
+ tfmdata.language = value
+ end
+ end
+end
+
+function otf.features.script(tfmdata,value)
+ if value then
+ value = lower(value)
+ if scripts[value] then
+ tfmdata.script = value
+ end
+ end
+end
+
+function otf.features.mode(tfmdata,value)
+ if value then
+ tfmdata.mode = lower(value)
+ end
+end
+
+fonts.initializers.base.otf.language = otf.features.language
+fonts.initializers.base.otf.script = otf.features.script
+fonts.initializers.base.otf.mode = otf.features.mode
+fonts.initializers.base.otf.method = otf.features.mode
+
+fonts.initializers.node.otf.language = otf.features.language
+fonts.initializers.node.otf.script = otf.features.script
+fonts.initializers.node.otf.mode = otf.features.mode
+fonts.initializers.node.otf.method = otf.features.mode
+
+otf.features.register("features",true) -- we always do features
+table.insert(fonts.processors,"features") -- we need a proper function for doing this
+
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-otb'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local concat = table.concat
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end)
+local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end)
+local trace_multiples = false trackers.register("otf.multiples", function(v) trace_multiples = v end)
+local trace_alternatives = false trackers.register("otf.alternatives", function(v) trace_alternatives = v end)
+local trace_ligatures = false trackers.register("otf.ligatures", function(v) trace_ligatures = v end)
+local trace_kerns = false trackers.register("otf.kerns", function(v) trace_kerns = v end)
+local trace_preparing = false trackers.register("otf.preparing", function(v) trace_preparing = v end)
+
+local wildcard = "*"
+local default = "dflt"
+
+local split_at_space = lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway
+
+local pcache, fcache = { }, { } -- could be weak
+
+local function gref(descriptions,n)
+ if type(n) == "number" then
+ local name = descriptions[n].name
+ if name then
+ return format("U+%04X (%s)",n,name)
+ else
+ return format("U+%04X")
+ end
+ elseif n then
+ local num, nam = { }, { }
+ for i=1,#n do
+ local ni = n[i]
+ num[i] = format("U+%04X",ni)
+ nam[i] = descriptions[ni].name or "?"
+ end
+ return format("%s (%s)",concat(num," "), concat(nam," "))
+ else
+ return "?"
+ end
+end
+
+local function cref(kind,lookupname)
+ if lookupname then
+ return format("feature %s, lookup %s",kind,lookupname)
+ else
+ return format("feature %s",kind)
+ end
+end
+
+local function resolve_ligatures(tfmdata,ligatures,kind)
+ kind = kind or "unknown"
+ local unicodes = tfmdata.unicodes
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local changed = tfmdata.changed
+ local done = { }
+ while true do
+ local ok = false
+ for k,v in next, ligatures do
+ local lig = v[1]
+ if not done[lig] then
+ local ligs = split_at_space:match(lig)
+ if #ligs == 2 then
+ local uc = v[2]
+ local c, f, s = characters[uc], ligs[1], ligs[2]
+ local uft, ust = unicodes[f] or 0, unicodes[s] or 0
+ if not uft or not ust then
+ logs.report("define otf","%s: unicode problem with base ligature %s = %s + %s",cref(kind),gref(descriptions,uc),gref(descriptions,uft),gref(descriptions,ust))
+ -- some kind of error
+ else
+ if type(uft) == "number" then uft = { uft } end
+ if type(ust) == "number" then ust = { ust } end
+ for ufi=1,#uft do
+ local uf = uft[ufi]
+ for usi=1,#ust do
+ local us = ust[usi]
+ if changed[uf] or changed[us] then
+ if trace_baseinit and trace_ligatures then
+ logs.report("define otf","%s: base ligature %s + %s ignored",cref(kind),gref(descriptions,uf),gref(descriptions,us))
+ end
+ else
+ local first, second = characters[uf], us
+ if first and second then
+ local t = first.ligatures
+ if not t then
+ t = { }
+ first.ligatures = t
+ end
+ if type(uc) == "number" then
+ t[second] = { type = 0, char = uc }
+ else
+ t[second] = { type = 0, char = uc[1] } -- can this still happen?
+ end
+ if trace_baseinit and trace_ligatures then
+ logs.report("define otf","%s: base ligature %s + %s => %s",cref(kind),gref(descriptions,uf),gref(descriptions,us),gref(descriptions,uc))
+ end
+ end
+ end
+ end
+ end
+ end
+ ok, done[lig] = true, descriptions[uc].name
+ end
+ end
+ end
+ if ok then
+ -- done has "a b c" = "a_b_c" and ligatures the already set ligatures: "a b" = 123
+ -- and here we add extras (f i i = fi + i and alike)
+ --
+ -- we could use a hash for fnc and pattern
+ --
+ -- this might be interfering !
+ for d,n in next, done do
+ local pattern = pcache[d] if not pattern then pattern = "^(" .. d .. ") " pcache[d] = pattern end
+ local fnc = fcache[n] if not fnc then fnc = function() return n .. " " end fcache[n] = fnc end
+ for k,v in next, ligatures do
+ v[1] = gsub(v[1],pattern,fnc)
+ end
+ end
+ else
+ break
+ end
+ end
+end
+
+local function collect_lookups(otfdata,kind,script,language)
+ -- maybe store this in the font
+ local sequences = otfdata.luatex.sequences
+ if sequences then
+ local featuremap, featurelist = { }, { }
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local features = sequence.features
+ features = features and features[kind]
+ features = features and (features[script] or features[default] or features[wildcard])
+ features = features and (features[language] or features[default] or features[wildcard])
+ if features then
+ local subtables = sequence.subtables
+ if subtables then
+ for s=1,#subtables do
+ local ss = subtables[s]
+ if not featuremap[s] then
+ featuremap[ss] = true
+ featurelist[#featurelist+1] = ss
+ end
+ end
+ end
+ end
+ end
+ if #featurelist > 0 then
+ return featuremap, featurelist
+ end
+ end
+ return nil, nil
+end
+
+local splitter = lpeg.splitat(" ")
+
+function prepare_base_substitutions(tfmdata,kind,value) -- we can share some code with the node features
+ if value then
+ local otfdata = tfmdata.shared.otfdata
+ local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
+ if validlookups then
+ local ligatures = { }
+ local unicodes = tfmdata.unicodes -- names to unicodes
+ local indices = tfmdata.indices
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local changed = tfmdata.changed
+ for k,c in next, characters do
+ local glyph = descriptions[k]
+ local lookups = glyph.lookups
+ if lookups then
+ for l=1,#lookuplist do
+ local lookup = lookuplist[l]
+ local ps = lookups[lookup]
+ if ps then
+ for i=1,#ps do
+ local p = ps[i]
+ local t = p[1]
+ if t == 'substitution' then
+ local pv = p[2] -- p.variant
+ if pv then
+ local upv = unicodes[pv]
+ if upv then
+ if type(upv) == "table" then
+ upv = upv[1]
+ end
+ if characters[upv] then
+ if trace_baseinit and trace_singles then
+ logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv))
+ end
+ changed[k] = upv
+ end
+ end
+ end
+ elseif t == 'alternate' then
+ local pc = p[2] -- p.components
+ if pc then
+ -- a bit optimized ugliness
+ if value == 1 then
+ pc = splitter:match(pc)
+ elseif value == 2 then
+ local a, b = splitter:match(pc)
+ pc = b or a
+ else
+ pc = { splitter:match(pc) }
+ pc = pc[value] or pc[#pc]
+ end
+ if pc then
+ local upc = unicodes[pc]
+ if upc then
+ if type(upc) == "table" then
+ upc = upc[1]
+ end
+ if characters[upc] then
+ if trace_baseinit and trace_alternatives then
+ logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc))
+ end
+ changed[k] = upc
+ end
+ end
+ end
+ end
+ elseif t == 'ligature' and not changed[k] then
+ local pc = p[2]
+ if pc then
+ if trace_baseinit and trace_ligatures then
+ local upc = { splitter:match(pc) }
+ for i=1,#upc do upc[i] = unicodes[upc[i]] end
+ -- we assume that it's no table
+ logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k))
+ end
+ ligatures[#ligatures+1] = { pc, k }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ resolve_ligatures(tfmdata,ligatures,kind)
+ end
+ else
+ tfmdata.ligatures = tfmdata.ligatures or { } -- left over from what ?
+ end
+end
+
+local function prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns, currently all
+ if value then
+ local otfdata = tfmdata.shared.otfdata
+ local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
+ if validlookups then
+ local unicodes = tfmdata.unicodes -- names to unicodes
+ local indices = tfmdata.indices
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ for u, chr in next, characters do
+ local d = descriptions[u]
+ if d then
+ local dk = d.mykerns
+ if dk then
+ local t, done = chr.kerns or { }, false
+ for l=1,#lookuplist do
+ local lookup = lookuplist[l]
+ local kerns = dk[lookup]
+ if kerns then
+ for k, v in next, kerns do
+ if v ~= 0 and not t[k] then -- maybe no 0 test here
+ t[k], done = v, true
+ if trace_baseinit and trace_kerns then
+ logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v)
+ end
+ end
+ end
+ end
+ end
+ if done then
+ chr.kerns = t -- no empty assignments
+ end
+ -- elseif d.kerns then
+ -- logs.report("define otf","%s: invalid mykerns for %s",cref(kind),gref(descriptions,u))
+ end
+ end
+ end
+ end
+ end
+end
+
+-- In principle we could register each feature individually which was
+-- what we did in earlier versions. However, after the rewrite it
+-- made more sense to collect them in an overall features initializer
+-- just as with the node variant. There it was needed because we need
+-- to do complete mixed runs and not run featurewise (as we did before).
+
+local supported_gsub = {
+ 'liga','dlig','rlig','hlig',
+ 'pnum','onum','tnum','lnum',
+ 'zero',
+ 'smcp','cpsp','c2sc','ornm','aalt',
+ 'hwid','fwid',
+ 'ssty', -- math
+}
+
+local supported_gpos = {
+ 'kern'
+}
+
+function otf.features.register_base_substitution(tag)
+ supported_gsub[#supported_gsub+1] = tag
+end
+function otf.features.register_base_kern(tag)
+ supported_gsub[#supported_gpos+1] = tag
+end
+
+local basehash, basehashes = { }, 1
+
+function fonts.initializers.base.otf.features(tfmdata,value)
+ if true then -- value then
+ -- not shared
+ local t = trace_preparing and os.clock()
+ local features = tfmdata.shared.features
+ if features then
+ local h = { }
+ for f=1,#supported_gsub do
+ local feature = supported_gsub[f]
+ prepare_base_substitutions(tfmdata,feature,features[feature])
+ h[#h+1] = feature
+ end
+ for f=1,#supported_gpos do
+ local feature = supported_gpos[f]
+ prepare_base_kerns(tfmdata,feature,features[feature])
+ h[#h+1] = feature
+ end
+ local hash = concat(h," ")
+ local base = basehash[hash]
+ if not base then
+ basehashes = basehashes + 1
+ base = basehashes
+ basehash[hash] = base
+ end
+ -- We need to make sure that luatex sees the difference between
+ -- base fonts that have different glyphs in the same slots in fonts
+ -- that have the same fullname (or filename). LuaTeX will merge fonts
+ -- eventually (and subset later on). If needed we can use a more
+ -- verbose name as long as we don't use <()<>[]{}/%> and the length
+ -- is < 128.
+ tfmdata.fullname = tfmdata.fullname .. base
+ end
+ if trace_preparing then
+ logs.report("otf define","preparation time is %0.3f seconds for %s",os.clock()-t,tfmdata.fullname or "?")
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-otn'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this is still somewhat preliminary and it will get better in due time;
+-- much functionality could only be implemented thanks to the husayni font
+-- of Idris Samawi Hamid to who we dedicate this module.
+
+-- we can use more lpegs when lpeg is extended with function args and so
+-- resolving to unicode does not gain much
+
+-- in retrospect it always looks easy but believe it or not, it took a lot
+-- of work to get proper open type support done: buggy fonts, fuzzy specs,
+-- special made testfonts, many skype sessions between taco, idris and me,
+-- torture tests etc etc ... unfortunately the code does not show how much
+-- time it took ...
+
+-- todo:
+--
+-- kerning is probably not yet ok for latin around dics nodes
+-- extension infrastructure (for usage out of context)
+-- sorting features according to vendors/renderers
+-- alternative loop quitters
+-- check cursive and r2l
+-- find out where ignore-mark-classes went
+-- remove unused tables
+-- slide tail (always glue at the end so only needed once
+-- default features (per language, script)
+-- cleanup kern(class) code, remove double info
+-- handle positions (we need example fonts)
+-- handle gpos_single (we might want an extra width field in glyph nodes because adding kerns might interfere)
+
+--[[ldx--
+<p>This module is a bit more split up that I'd like but since we also want to test
+with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/>
+and discussion about improvements and functionality mostly happens on the
+<l n='context'/> mailing list.</p>
+
+<p>The specification of OpenType is kind of vague. Apart from a lack of a proper
+free specifications there's also the problem that Microsoft and Adobe
+may have their own interpretation of how and in what order to apply features.
+In general the Microsoft website has more detailed specifications and is a
+better reference. There is also some information in the FontForge help files.</p>
+
+<p>Because there is so much possible, fonts might contain bugs and/or be made to
+work with certain rederers. These may evolve over time which may have the side
+effect that suddenly fonts behave differently.</p>
+
+<p>After a lot of experiments (mostly by Taco, me and Idris) we're now at yet another
+implementation. Of course all errors are mine and of course the code can be
+improved. There are quite some optimizations going on here and processing speed
+is currently acceptable. Not all functions are implemented yet, often because I
+lack the fonts for testing. Many scripts are not yet supported either, but I will
+look into them as soon as <l n='context'/> users ask for it.</p>
+
+<p>Because there are different interpretations possible, I will extend the code
+with more (configureable) variants. I can also add hooks for users so that they can
+write their own extensions.</p>
+
+<p>Glyphs are indexed not by unicode but in their own way. This is because there is no
+relationship with unicode at all, apart from the fact that a font might cover certain
+ranges of characters. One character can have multiple shapes. However, at the
+<l n='tex'/> end we use unicode so and all extra glyphs are mapped into a private
+space. This is needed because we need to access them and <l n='tex'/> has to include
+then in the output eventually.</p>
+
+<p>The raw table as it coms from <l n='fontforge'/> gets reorganized in to fit out needs.
+In <l n='context'/> that table is packed (similar tables are shared) and cached on disk
+so that successive runs can use the optimized table (after loading the table is
+unpacked). The flattening code used later is a prelude to an even more compact table
+format (and as such it keeps evolving).</p>
+
+<p>This module is sparsely documented because it is a moving target. The table format
+of the reader changes and we experiment a lot with different methods for supporting
+features.</p>
+
+<p>As with the <l n='afm'/> code, we may decide to store more information in the
+<l n='otf'/> table.</p>
+
+<p>Incrementing the version number will force a re-cache. We jump the number by one
+when there's a fix in the <l n='fontforge'/> library or <l n='lua'/> code that
+results in different tables.</p>
+--ldx]]--
+
+-- action handler chainproc chainmore comment
+--
+-- gsub_single ok ok ok
+-- gsub_multiple ok ok not implemented yet
+-- gsub_alternate ok ok not implemented yet
+-- gsub_ligature ok ok ok
+-- gsub_context ok --
+-- gsub_contextchain ok --
+-- gsub_reversecontextchain ok --
+-- chainsub -- ok
+-- reversesub -- ok
+-- gpos_mark2base ok ok
+-- gpos_mark2ligature ok ok
+-- gpos_mark2mark ok ok
+-- gpos_cursive ok untested
+-- gpos_single ok ok
+-- gpos_pair ok ok
+-- gpos_context ok --
+-- gpos_contextchain ok --
+--
+-- actions:
+--
+-- handler : actions triggered by lookup
+-- chainproc : actions triggered by contextual lookup
+-- chainmore : multiple substitutions triggered by contextual lookup (e.g. fij -> f + ij)
+--
+-- remark: the 'not implemented yet' variants will be done when we have fonts that use them
+-- remark: we need to check what to do with discretionaries
+
+local concat = table.concat
+local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
+local type, next, tonumber, tostring = type, next, tonumber, tostring
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local trace_lookups = false trackers.register("otf.lookups", function(v) trace_lookups = v end)
+local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end)
+local trace_multiples = false trackers.register("otf.multiples", function(v) trace_multiples = v end)
+local trace_alternatives = false trackers.register("otf.alternatives", function(v) trace_alternatives = v end)
+local trace_ligatures = false trackers.register("otf.ligatures", function(v) trace_ligatures = v end)
+local trace_contexts = false trackers.register("otf.contexts", function(v) trace_contexts = v end)
+local trace_marks = false trackers.register("otf.marks", function(v) trace_marks = v end)
+local trace_kerns = false trackers.register("otf.kerns", function(v) trace_kerns = v end)
+local trace_cursive = false trackers.register("otf.cursive", function(v) trace_cursive = v end)
+local trace_preparing = false trackers.register("otf.preparing", function(v) trace_preparing = v end)
+local trace_bugs = false trackers.register("otf.bugs", function(v) trace_bugs = v end)
+local trace_details = false trackers.register("otf.details", function(v) trace_details = v end)
+local trace_applied = false trackers.register("otf.applied", function(v) trace_applied = v end)
+local trace_steps = false trackers.register("otf.steps", function(v) trace_steps = v end)
+
+trackers.register("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end)
+trackers.register("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end)
+
+trackers.register("otf.replacements", "otf.singles,otf.multiples,otf.alternatives,otf.ligatures")
+trackers.register("otf.positions","otf.marks,otf.kerns,otf.cursive")
+trackers.register("otf.actions","otf.replacements,otf.positions")
+trackers.register("otf.injections","nodes.injections")
+
+trackers.register("*otf.sample","otf.steps,otf.actions,otf.analyzing")
+
+local insert_node_after = node.insert_after
+local delete_node = nodes.delete
+local copy_node = node.copy
+local slide_node_list = node.slide
+local set_attribute = node.set_attribute
+local has_attribute = node.has_attribute
+
+local zwnj = 0x200C
+local zwj = 0x200D
+local wildcard = "*"
+local default = "dflt"
+
+local split_at_space = lpeg.Ct(lpeg.splitat(" ")) -- no trailing or multiple spaces anyway
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local kern = node.id('kern')
+local disc = node.id('disc')
+local whatsit = node.id('whatsit')
+
+local state = attributes.private('state')
+local markbase = attributes.private('markbase')
+local markmark = attributes.private('markmark')
+local markdone = attributes.private('markdone')
+local cursbase = attributes.private('cursbase')
+local curscurs = attributes.private('curscurs')
+local cursdone = attributes.private('cursdone')
+local kernpair = attributes.private('kernpair')
+
+local set_mark = nodes.set_mark
+local set_cursive = nodes.set_cursive
+local set_kern = nodes.set_kern
+local set_pair = nodes.set_pair
+
+local markonce = true
+local cursonce = true
+local kernonce = true
+
+local fontdata = fonts.ids
+
+otf.features.process = { }
+
+-- we share some vars here, after all, we have no nested lookups and
+-- less code
+
+local tfmdata = false
+local otfdata = false
+local characters = false
+local descriptions = false
+local marks = false
+local indices = false
+local unicodes = false
+local currentfont = false
+local lookuptable = false
+local anchorlookups = false
+local handlers = { }
+local rlmode = 0
+local featurevalue = false
+
+-- we cheat a bit and assume that a font,attr combination are kind of ranged
+
+local context_setups = fonts.define.specify.context_setups
+local context_numbers = fonts.define.specify.context_numbers
+local context_merged = fonts.define.specify.context_merged
+
+-- we cannot optimize with "start = first_character(head)" because then we don't
+-- know which rlmode we're in which messes up cursive handling later on
+--
+-- head is always a whatsit so we can safely assume that head is not changed
+
+local special_attributes = {
+ init = 1,
+ medi = 2,
+ fina = 3,
+ isol = 4
+}
+
+-- we use this for special testing and documentation
+
+local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end
+local registerstep = (nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end
+local registermessage = (nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf direct",...)
+end
+local function logwarning(...)
+ logs.report("otf direct",...)
+end
+
+local function gref(n)
+ if type(n) == "number" then
+ local description = descriptions[n]
+ local name = description and description.name
+ if name then
+ return format("U+%04X (%s)",n,name)
+ else
+ return format("U+%04X",n)
+ end
+ elseif not n then
+ return "<error in tracing>"
+ else
+ local num, nam = { }, { }
+ for i=1,#n do
+ local ni = n[i]
+ num[#num+1] = format("U+%04X",ni)
+ local dni = descriptions[ni]
+ nam[#num] = (dni and dni.name) or "?"
+ end
+ return format("%s (%s)",concat(num," "), concat(nam," "))
+ end
+end
+
+local function cref(kind,chainname,chainlookupname,lookupname,index)
+ if index then
+ return format("feature %s, chain %s, sub %s, lookup %s, index %s",kind,chainname,chainlookupname,lookupname,index)
+ elseif lookupname then
+ return format("feature %s, chain %s, sub %s, lookup %s",kind,chainname or "?",chainlookupname or "?",lookupname)
+ elseif chainlookupname then
+ return format("feature %s, chain %s, sub %s",kind,chainname or "?",chainlookupname)
+ elseif chainname then
+ return format("feature %s, chain %s",kind,chainname)
+ else
+ return format("feature %s",kind)
+ end
+end
+
+local function pref(kind,lookupname)
+ return format("feature %s, lookup %s",kind,lookupname)
+end
+
+-- we can assume that languages that use marks are not hyphenated
+-- we can also assume that at most one discretionary is present
+
+local function markstoligature(kind,lookupname,start,stop,char)
+ local n = copy_node(start)
+ local keep = start
+ local current
+ current, start = insert_node_after(start,start,n)
+ local snext = stop.next
+ current.next = snext
+ if snext then
+ snext.prev = current
+ end
+ start.prev, stop.next = nil, nil
+ current.char, current.subtype, current.components = char, 2, start
+ return keep
+end
+
+local function toligature(kind,lookupname,start,stop,char,markflag,discfound) -- brr head
+ if start ~= stop then
+ if discfound then
+ local lignode = copy_node(start)
+ lignode.font = start.font
+ lignode.char = char
+ lignode.subtype = 2
+ start = node.do_ligature_n(start, stop, lignode)
+ if start.id == disc then
+ local prev = start.prev
+ start = start.next
+ end
+ else -- start is the ligature
+ local deletemarks = markflag ~= "mark"
+ local n = copy_node(start)
+ local current
+ current, start = insert_node_after(start,start,n)
+ local snext = stop.next
+ current.next = snext
+ if snext then
+ snext.prev = current
+ end
+ start.prev, stop.next = nil, nil
+ current.char, current.subtype, current.components = char, 2, start
+ local head = current
+ if deletemarks then
+ if trace_marks then
+ while start do
+ if marks[start.char] then
+ logwarning("%s: remove mark %s",pref(kind,lookupname),gref(start.char))
+ end
+ start = start.next
+ end
+ end
+ else
+ local i = 0
+ while start do
+ if marks[start.char] then
+ set_attribute(start,markdone,i)
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
+ end
+ head, current = insert_node_after(head,current,copy_node(start))
+ else
+ i = i + 1
+ end
+ start = start.next
+ end
+ start = current.next
+ while start and start.id == glyph do
+ if marks[start.char] then
+ set_attribute(start,markdone,i)
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(start.char),i)
+ end
+ else
+ break
+ end
+ start = start.next
+ end
+ end
+ return head
+ end
+ else
+ start.char = char
+ end
+ return start
+end
+
+function handlers.gsub_single(start,kind,lookupname,replacement)
+ if trace_singles then
+ logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement))
+ end
+ start.char = replacement
+ return start, true
+end
+
+local function alternative_glyph(start,alternatives,kind,chainname,chainlookupname,lookupname) -- chainname and chainlookupname optional
+ local value, choice, n = featurevalue or tfmdata.shared.features[kind], nil, #alternatives -- global value, brrr
+ if value == "random" then
+ local r = math.random(1,n)
+ value, choice = format("random, choice %s",r), alternatives[r]
+ elseif value == "first" then
+ value, choice = format("first, choice %s",1), alternatives[1]
+ elseif value == "last" then
+ value, choice = format("last, choice %s",n), alternatives[n]
+ elseif type(value) ~= "number" then
+ value, choice = "default, choice 1", alternatives[1]
+ elseif value > n then
+ value, choice = format("no %s variants, taking %s",value,n), alternatives[n]
+ elseif value == 0 then
+ value, choice = format("choice %s (no change)",value), start.char
+ elseif value < 1 then
+ value, choice = format("no %s variants, taking %s",value,1), alternatives[1]
+ else
+ value, choice = format("choice %s",value), alternatives[value]
+ end
+ if not choice then
+ logwarning("%s: no variant %s for %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(start.char))
+ choice, value = start.char, format("no replacement instead of %s",value)
+ end
+ return choice, value
+end
+
+function handlers.gsub_alternate(start,kind,lookupname,alternative,sequence)
+ local choice, index = alternative_glyph(start,alternative,kind,lookupname)
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %s (%s)",pref(kind,lookupname),gref(start.char),gref(choice),index)
+ end
+ start.char = choice
+ return start, true
+end
+
+function handlers.gsub_multiple(start,kind,lookupname,multiple)
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple))
+ end
+ start.char = multiple[1]
+ if #multiple > 1 then
+ for k=2,#multiple do
+ local n = copy_node(start)
+ n.char = multiple[k]
+ local sn = start.next
+ n.next = sn
+ n.prev = start
+ if sn then
+ sn.prev = n
+ end
+ start.next = n
+ start = n
+ end
+ end
+ return start, true
+end
+
+function handlers.gsub_ligature(start,kind,lookupname,ligature,sequence) --or maybe pass lookup ref
+ local s, stop, discfound = start.next, nil, false
+ if marks[start.char] then
+ while s do
+ local id = s.id
+ if id == glyph and s.subtype<256 then
+ if s.font == currentfont then
+ local char = s.char
+ local lg = ligature[1][char]
+ if not lg then
+ break
+ else
+ stop = s
+ ligature = lg
+ s = s.next
+ end
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if stop and ligature[2] then
+ if trace_ligatures then
+ local startchar, stopchar = start.char, stop.char
+ start = markstoligature(kind,lookupname,start,stop,ligature[2])
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = markstoligature(kind,lookupname,start,stop,ligature[2])
+ end
+ return start, true
+ end
+ else
+ local skipmark = sequence.flags[1]
+ while s do
+ local id = s.id
+ if id == glyph and s.subtype<256 then
+ if s.font == currentfont then
+ local char = s.char
+ if skipmark and marks[char] then
+ s = s.next
+ else
+ local lg = ligature[1][char]
+ if not lg then
+ break
+ else
+ stop = s
+ ligature = lg
+ s = s.next
+ end
+ end
+ else
+ break
+ end
+ elseif id == disc then
+ discfound = true
+ s = s.next
+ else
+ break
+ end
+ end
+ if stop and ligature[2] then
+ if trace_ligatures then
+ local startchar, stopchar = start.char, stop.char
+ start = toligature(kind,lookupname,start,stop,ligature[2],skipmark,discfound)
+ logprocess("%s: replacing %s upto %s by ligature %s",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
+ else
+ start = toligature(kind,lookupname,start,stop,ligature[2],skipmark,discfound)
+ end
+ return start, true
+ end
+ end
+ return start, false
+end
+
+--[[ldx--
+<p>We get hits on a mark, but we're not sure if the it has to be applied so
+we need to explicitly test for basechar, baselig and basemark entries.</p>
+--ldx]]--
+
+function handlers.gpos_mark2base(start,kind,lookupname,markanchors,sequence)
+ local markchar = start.char
+ if marks[markchar] then
+ local base = start.prev -- [glyph] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+ end
+ end
+ end
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
+ end
+ if baseanchors then
+ local baseanchors = baseanchors['basechar']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)",
+ pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s, no matching anchors for mark %s and base %s",pref(kind,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ fonts.register_message(currentfont,basechar,"no base anchors")
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char",pref(kind,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function handlers.gpos_mark2ligature(start,kind,lookupname,markanchors,sequence)
+ -- check chainpos variant
+ local markchar = start.char
+ if marks[markchar] then
+ local base = start.prev -- [glyph] [optional marks] [start=mark]
+ local index = 1
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ else
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+ end
+ end
+ end
+ local i = has_attribute(start,markdone)
+ if i then index = i end
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
+ if baseanchors then
+ local baseanchors = baseanchors['baselig']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ ba = ba[index]
+ if ba then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma,index)
+ if trace_marks then
+ logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)",
+ pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s",pref(kind,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ fonts.register_message(currentfont,basechar,"no base anchors")
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char",pref(kind,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function handlers.gpos_mark2mark(start,kind,lookupname,markanchors,sequence)
+ local markchar = start.char
+ if marks[markchar] then
+--~ local alreadydone = markonce and has_attribute(start,markmark)
+--~ if not alreadydone then
+ local base = start.prev -- [glyph] [basemark] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go
+ local basechar = base.char
+ local baseanchors = descriptions[basechar]
+ if baseanchors then
+ baseanchors = baseanchors.anchors
+ if baseanchors then
+ baseanchors = baseanchors['basemark']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)",
+ pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start,true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and basemark %s",pref(kind,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(basechar))
+ fonts.register_message(currentfont,basechar,"no base anchors")
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark",pref(kind,lookupname))
+ end
+--~ elseif trace_marks and trace_details then
+--~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone)
+--~ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(kind,lookupname),gref(markchar))
+ end
+ return start,false
+end
+
+function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to be checked
+ local alreadydone = cursonce and has_attribute(start,cursbase)
+ if not alreadydone then
+ local done = false
+ local startchar = start.char
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar))
+ end
+ else
+ local nxt = start.next
+ while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do
+ local nextchar = nxt.char
+ if marks[nextchar] then
+ -- should not happen (maybe warning)
+ nxt = nxt.next
+ else
+ local entryanchors = descriptions[nextchar]
+ if entryanchors then
+ entryanchors = entryanchors.anchors
+ if entryanchors then
+ entryanchors = entryanchors['centry']
+ if entryanchors then
+ local al = anchorlookups[lookupname]
+ for anchor, entry in next, entryanchors do
+ if al[anchor] then
+ local exit = exitanchors[anchor]
+ if exit then
+ local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ end
+ done = true
+ break
+ end
+ end
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(startchar))
+ fonts.register_message(currentfont,startchar,"no entry anchors")
+ end
+ break
+ end
+ end
+ end
+ return start, done
+ else
+ if trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
+ end
+ return start, false
+ end
+end
+
+function handlers.gpos_single(start,kind,lookupname,kerns,sequence)
+ local startchar = start.char
+ local dx, dy = set_pair(start,tfmdata.factor,rlmode,kerns,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting single %s by (%s,%s)",pref(kind,lookupname),gref(startchar),dx,dy)
+ end
+ return start, false
+end
+
+function handlers.gpos_pair(start,kind,lookupname,kerns,sequence)
+ -- todo: kerns in disc nodes: pre, post, replace -> loop over disc too
+ -- todo: kerns in components of ligatures
+ local snext = start.next
+ if not snext then
+ return start, false
+ else
+ local prev, done = start, false
+ local factor = tfmdata.factor
+ while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do
+ local nextchar = snext.char
+local krn = kerns[nextchar]
+ if not krn and marks[nextchar] then
+ prev = snext
+ snext = snext.next
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ -- skip
+ elseif type(krn) == "table" then
+ if krn[1] == "pair" then
+ local a, b = krn[3], krn[4]
+ if a and #a > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(start,factor,rlmode,a,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b and #b > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(snext,factor,rlmode,b,characters[nextchar])
+ if trace_kerns then
+ logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ else
+ logs.report("%s: check this out (old kern stuff)",pref(kind,lookupname))
+ local a, b = krn[3], krn[7]
+ if a and a ~= 0 then
+ local k = set_kern(snext,factor,rlmode,a)
+ if trace_kerns then
+ logprocess("%s: inserting first kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar))
+ end
+ end
+ if b and b ~= 0 then
+ logwarning("%s: ignoring second kern xoff %s",pref(kind,lookupname),b*factor)
+ end
+ end
+ done = true
+ elseif krn ~= 0 then
+ local k = set_kern(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar))
+ end
+ done = true
+ end
+ break
+ end
+ end
+ return start, done
+ end
+end
+
+--[[ldx--
+<p>I will implement multiple chain replacements once I run into a font that uses
+it. It's not that complex to handle.</p>
+--ldx]]--
+
+local chainmores = { }
+local chainprocs = { }
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf subchain",...)
+end
+local function logwarning(...)
+ logs.report("otf subchain",...)
+end
+
+-- ['coverage']={
+-- ['after']={ "r" },
+-- ['before']={ "q" },
+-- ['current']={ "a", "b", "c" },
+-- },
+-- ['lookups']={ "ls_l_1", "ls_l_1", "ls_l_1" },
+
+function chainmores.chainsub(start,stop,kind,chainname,currentcontext,cache,lookuplist,chainlookupname,n)
+ logprocess("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+
+-- handled later:
+--
+-- function chainmores.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- return chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- end
+
+function chainmores.gsub_multiple(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+ logprocess("%s: gsub_multiple not yet supported",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+function chainmores.gsub_alternate(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+ logprocess("%s: gsub_alternate not yet supported",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+
+-- handled later:
+--
+-- function chainmores.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- return chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,n)
+-- end
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf chain",...)
+end
+local function logwarning(...)
+ logs.report("otf chain",...)
+end
+
+-- We could share functions but that would lead to extra function calls with many
+-- arguments, redundant tests and confusing messages.
+
+function chainprocs.chainsub(start,stop,kind,chainname,currentcontext,cache,lookuplist,chainlookupname)
+ logwarning("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname))
+ return start, false
+end
+
+-- The reversesub is a special case, which is why we need to store the replacements
+-- in a bit weird way. There is no lookup and the replacement comes from the lookup
+-- itself. It is meant mostly for dealing with Urdu.
+
+function chainprocs.reversesub(start,stop,kind,chainname,currentcontext,cache,replacements)
+ local char = start.char
+ local replacement = replacements[char]
+ if replacement then
+ if trace_singles then
+ logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement))
+ end
+ start.char = replacement
+ return start, true
+ else
+ return start, false
+ end
+end
+
+--[[ldx--
+<p>This chain stuff is somewhat tricky since we can have a sequence of actions to be
+applied: single, alternate, multiple or ligature where ligature can be an invalid
+one in the sense that it will replace multiple by one but not neccessary one that
+looks like the combination (i.e. it is the counterpart of multiple then). For
+example, the following is valid:</p>
+
+<typing>
+<line>xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx</line>
+</typing>
+
+<p>Therefore we we don't really do the replacement here already unless we have the
+single lookup case. The efficiency of the replacements can be improved by deleting
+as less as needed but that would also mke the code even more messy.</p>
+--ldx]]--
+
+local function delete_till_stop(start,stop,ignoremarks)
+ if start ~= stop then
+ -- todo keep marks
+ local done = false
+ while not done do
+ done = start == stop
+ delete_node(start,start.next)
+ end
+ end
+end
+
+--[[ldx--
+<p>Here we replace start by a single variant, First we delete the rest of the
+match.</p>
+--ldx]]--
+
+function chainprocs.gsub_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex)
+ -- todo: marks ?
+ if not chainindex then
+ delete_till_stop(start,stop) -- ,currentlookup.flags[1])
+ end
+ local current = start
+ local subtables = currentlookup.subtables
+ while current do
+ if current.id == glyph then
+ local currentchar = current.char
+ local lookupname = subtables[1]
+ local replacement = cache.gsub_single[lookupname]
+ if not replacement then
+ if trace_bugs then
+ logwarning("%s: no single hits",cref(kind,chainname,chainlookupname,lookupname,chainindex))
+ end
+ else
+ replacement = replacement[currentchar]
+ if not replacement then
+ if trace_bugs then
+ logwarning("%s: no single for %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar))
+ end
+ else
+ if trace_singles then
+ logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement))
+ end
+ current.char = replacement
+ end
+ end
+ return start, true
+ elseif current == stop then
+ break
+ else
+ current = current.next
+ end
+ end
+ return start, false
+end
+
+chainmores.gsub_single = chainprocs.gsub_single
+
+--[[ldx--
+<p>Here we replace start by a sequence of new glyphs. First we delete the rest of
+the match.</p>
+--ldx]]--
+
+function chainprocs.gsub_multiple(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ delete_till_stop(start,stop)
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local replacements = cache.gsub_multiple[lookupname]
+ if not replacements then
+ if trace_bugs then
+ logwarning("%s: no multiple hits",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ else
+ replacements = replacements[startchar]
+ if not replacements then
+ if trace_bugs then
+ logwarning("%s: no multiple for %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar))
+ end
+ else
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple characters %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar),gref(replacements))
+ end
+ local sn = start.next
+ for k=1,#replacements do
+ if k == 1 then
+ start.char = replacements[k]
+ else
+ local n = copy_node(start) -- maybe delete the components and such
+ n.char = replacements[k]
+ n.next, n.prev = sn, start
+ if sn then
+ sn.prev = n
+ end
+ start.next, start = n, n
+ end
+ end
+ return start, true
+ end
+ end
+ return start, false
+end
+
+--[[ldx--
+<p>Here we replace start by new glyph. First we delete the rest of the match.</p>
+--ldx]]--
+
+function chainprocs.gsub_alternate(start,stop,kind,lookupname,currentcontext,cache,currentlookup)
+ -- todo: marks ?
+ delete_till_stop(start,stop)
+ local current = start
+ local subtables = currentlookup.subtables
+ while current do
+ if current.id == glyph then
+ local currentchar = current.char
+ local lookupname = subtables[1]
+ local alternatives = cache.gsub_alternate[lookupname]
+ if not alternatives then
+ if trace_bugs then
+ logwarning("%s: no alternative hits",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ else
+ alternatives = alternatives[currentchar]
+ if not alternatives then
+ if trace_bugs then
+ logwarning("%s: no alternative for %s",cref(kind,chainname,chainlookupname,lookupname),gref(currentchar))
+ end
+ else
+ local choice, index = alternative_glyph(current,alternatives,kind,chainname,chainlookupname,lookupname)
+ current.char = choice
+ if trace_alternatives then
+ logprocess("%s: replacing single %s by alternative %s (%s)",cref(kind,chainname,chainlookupname,lookupname),index,gref(currentchar),gref(choice),index)
+ end
+ end
+ end
+ return start, true
+ elseif current == stop then
+ break
+ else
+ current = current.next
+ end
+ end
+ return start, false
+end
+
+--[[ldx--
+<p>When we replace ligatures we use a helper that handles the marks. I might change
+this function (move code inline and handle the marks by a separate function). We
+assume rather stupid ligatures (no complex disc nodes).</p>
+--ldx]]--
+
+function chainprocs.gsub_ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname,chainindex)
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local ligatures = cache.gsub_ligature[lookupname]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligature hits",cref(kind,chainname,chainlookupname,lookupname,chainindex))
+ end
+ else
+ ligatures = ligatures[startchar]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
+ end
+ else
+ local s, discfound, last, nofreplacements = start.next, false, stop, 0
+ while s do
+ local id = s.id
+ if id == disc then
+ s = s.next
+ discfound = true
+ else
+ local schar = s.char
+ if marks[schar] then -- marks
+ s = s.next
+ else
+ local lg = ligatures[1][schar]
+ if not lg then
+ break
+ else
+ ligatures, last, nofreplacements = lg, s, nofreplacements + 1
+ if s == stop then
+ break
+ else
+ s = s.next
+ end
+ end
+ end
+ end
+ end
+ local l2 = ligatures[2]
+ if l2 then
+ if chainindex then
+ stop = last
+ end
+ if trace_ligatures then
+ if start == stop then
+ logprocess("%s: replacing character %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2))
+ else
+ logprocess("%s: replacing character %s upto %s by ligature %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2))
+ end
+ end
+ start = toligature(kind,lookup,start,stop,l2,currentlookup.flags[1],discfound)
+ return start, true, nofreplacements
+ elseif trace_bugs then
+ if start == stop then
+ logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
+ else
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char))
+ end
+ end
+ end
+ end
+ return start, false, 0
+end
+
+chainmores.gsub_ligature = chainprocs.gsub_ligature
+
+function chainprocs.gpos_mark2base(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local markchar = start.char
+ if marks[markchar] then
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = cache.gpos_mark2base[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = start.prev -- [glyph] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",pref(kind,lookupname),gref(markchar))
+ end
+ return start, false
+ end
+ end
+ end
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ local baseanchors = baseanchors['basechar']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%s,%s)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s, no matching anchors for mark %s and base %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function chainprocs.gpos_mark2ligature(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local markchar = start.char
+ if marks[markchar] then
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = cache.gpos_mark2ligature[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = start.prev -- [glyph] [optional marks] [start=mark]
+ local index = 1
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ local basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ while true do
+ base = base.prev
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then
+ basechar = base.char
+ if marks[basechar] then
+ index = index + 1
+ else
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s",cref(kind,chainname,chainlookupname,lookupname),markchar)
+ end
+ return start, false
+ end
+ end
+ end
+ -- todo: like marks a ligatures hash
+ local i = has_attribute(start,markdone)
+ if i then index = i end
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ local baseanchors = baseanchors['baselig']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ ba = ba[index]
+ if ba then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma,index)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%s,%s)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s",cref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("feature %s, lookup %s: prev node is no char",kind,lookupname)
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
+ end
+ return start, false
+end
+
+function chainprocs.gpos_mark2mark(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local markchar = start.char
+ if marks[markchar] then
+--~ local alreadydone = markonce and has_attribute(start,markmark)
+--~ if not alreadydone then
+ -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = cache.gpos_mark2mark[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = start.prev -- [glyph] [basemark] [start=mark]
+ if base and base.id == glyph and base.subtype<256 and base.font == currentfont then -- subtype test can go
+ local basechar = base.char
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ baseanchors = baseanchors['basemark']
+ if baseanchors then
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = set_mark(start,base,tfmdata.factor,rlmode,ba,ma)
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%s,%s)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return start, true
+ end
+ end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
+ end
+ end
+ end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
+--~ elseif trace_marks and trace_details then
+--~ logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone)
+--~ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
+ end
+ return start, false
+end
+
+-- ! ! ! untested ! ! !
+
+function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ local alreadydone = cursonce and has_attribute(start,cursbase)
+ if not alreadydone then
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local exitanchors = cache.gpos_cursive[lookupname]
+ if exitanchors then
+ exitanchors = exitanchors[startchar]
+ end
+ if exitanchors then
+ local done = false
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar))
+ end
+ else
+ local nxt = start.next
+ while not done and nxt and nxt.id == glyph and nxt.subtype<256 and nxt.font == currentfont do
+ local nextchar = nxt.char
+ if marks[nextchar] then
+ -- should not happen (maybe warning)
+ nxt = nxt.next
+ else
+ local entryanchors = descriptions[nextchar]
+ if entryanchors then
+ entryanchors = entryanchors.anchors
+ if entryanchors then
+ entryanchors = entryanchors['centry']
+ if entryanchors then
+ local al = anchorlookups[lookupname]
+ for anchor, entry in next, entryanchors do
+ if al[anchor] then
+ local exit = exitanchors[anchor]
+ if exit then
+ local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ end
+ done = true
+ break
+ end
+ end
+ end
+ end
+ end
+ else -- if trace_bugs then
+ -- logwarning("%s: char %s is missing in font",pref(kind,lookupname),gref(startchar))
+ fonts.register_message(currentfont,startchar,"no entry anchors")
+ end
+ break
+ end
+ end
+ end
+ return start, done
+ else
+ if trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
+ end
+ return start, false
+ end
+ end
+ return start, false
+end
+
+function chainprocs.gpos_single(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+ -- untested
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local kerns = cache.gpos_single[lookupname]
+ if kerns then
+ kerns = kerns[startchar]
+ if kerns then
+ local dx, dy = set_pair(start,tfmdata.factor,rlmode,kerns,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting single %s by (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy)
+ end
+ end
+ end
+ return start, false
+end
+
+-- when machines become faster i will make a shared function
+
+function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,currentlookup,chainlookupname)
+-- logwarning("%s: gpos_pair not yet supported",cref(kind,chainname,chainlookupname))
+ local snext = start.next
+ if snext then
+ local startchar = start.char
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local kerns = cache.gpos_pair[lookupname]
+ if kerns then
+ kerns = kerns[startchar]
+ if kerns then
+ local prev, done = start, false
+ local factor = tfmdata.factor
+ while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do
+ local nextchar = snext.char
+local krn = kerns[nextchar]
+ if not krn and marks[nextchar] then
+ prev = snext
+ snext = snext.next
+ else
+--~ local krn = kerns[nextchar]
+ if not krn then
+ -- skip
+ elseif type(krn) == "table" then
+ if krn[1] == "pair" then
+ local a, b = krn[3], krn[4]
+ if a and #a > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(start,factor,rlmode,a,characters[startchar])
+ if trace_kerns then
+ logprocess("%s: shifting first of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b and #b > 0 then
+ local startchar = start.char
+ local x, y, w, h = set_pair(snext,factor,rlmode,b,characters[nextchar])
+ if trace_kerns then
+ logprocess("%s: shifting second of pair %s and %s by (%s,%s) and correction (%s,%s)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ else
+ logs.report("%s: check this out (old kern stuff)",cref(kind,chainname,chainlookupname))
+ local a, b = krn[3], krn[7]
+ if a and a ~= 0 then
+ local k = set_kern(snext,factor,rlmode,a)
+ if trace_kerns then
+ logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar))
+ end
+ end
+ if b and b ~= 0 then
+ logwarning("%s: ignoring second kern xoff %s",cref(kind,chainname,chainlookupname),b*factor)
+ end
+ end
+ done = true
+ elseif krn ~= 0 then
+ local k = set_kern(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar))
+ end
+ done = true
+ end
+ break
+ end
+ end
+ return start, done
+ end
+ end
+ end
+ return start, false
+end
+
+-- what pointer to return, spec says stop
+-- to be discussed ... is bidi changer a space?
+-- elseif char == zwnj and sequence[n][32] then -- brrr
+
+-- somehow l or f is global
+-- we don't need to pass the currentcontext, saves a bit
+-- make a slow variant then can be activated but with more tracing
+
+local function normal_handle_contextchain(start,kind,chainname,contexts,sequence,cache)
+ -- local rule, lookuptype, sequence, f, l, lookups = ck[1], ck[2] ,ck[3], ck[4], ck[5], ck[6]
+ local flags, done = sequence.flags, false
+ local skipmark, skipligature, skipbase = flags[1], flags[2], flags[3]
+ local someskip = skipmark or skipligature or skipbase -- could be stored in flags for a fast test (hm, flags could be false !)
+ for k=1,#contexts do
+ local match, current, last = true, start, start
+ local ck = contexts[k]
+ local sequence = ck[3]
+ local s = #sequence
+ if s == 1 then
+ -- never happens
+ match = current.id == glyph and current.subtype<256 and current.font == currentfont and sequence[1][current.char]
+ else
+ -- todo: better space check (maybe check for glue)
+ local f, l = ck[4], ck[5]
+ if f == l then
+ -- already a hit
+ match = true
+ else
+ -- no need to test first hit (to be optimized)
+ local n = f + 1
+ last = last.next
+ -- we cannot optimize for n=2 because there can be disc nodes
+ -- if not someskip and n == l then
+ -- -- n=2 and no skips then faster loop
+ -- match = last and last.id == glyph and last.subtype<256 and last.font == currentfont and sequence[n][last.char]
+ -- else
+ while n <= l do
+ if last then
+ local id = last.id
+ if id == glyph then
+ if last.subtype<256 and last.font == currentfont then
+ local char = last.char
+ local ccd = descriptions[char]
+ if ccd then
+ local class = ccd.class
+ if class == skipmark or class == skipligature or class == skipbase then
+--~ if someskip and class == skipmark or class == skipligature or class == skipbase then
+ -- skip 'm
+ last = last.next
+ elseif sequence[n][char] then
+ if n < l then
+ last = last.next
+ end
+ n = n + 1
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ elseif id == disc then -- what to do with kerns?
+ last = last.next
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ end
+ -- end
+ end
+ if match and f > 1 then
+ local prev = start.prev
+ if prev then
+ local n = f-1
+ while n >= 1 do
+ if prev then
+ local id = prev.id
+ if id == glyph then
+ if prev.subtype<256 and prev.font == currentfont then -- normal char
+ local char = prev.char
+ local ccd = descriptions[char]
+ if ccd then
+ local class = ccd.class
+ if class == skipmark or class == skipligature or class == skipbase then
+--~ if someskip and class == skipmark or class == skipligature or class == skipbase then
+ -- skip 'm
+ elseif sequence[n][char] then
+ n = n -1
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ elseif id == disc then
+ -- skip 'm
+ elseif sequence[n][32] then
+ n = n -1
+ else
+ match = false break
+ end
+ prev = prev.prev
+ elseif sequence[n][32] then
+ n = n -1
+ else
+ match = false break
+ end
+ end
+ elseif f == 2 then
+ match = sequence[1][32]
+ else
+ for n=f-1,1 do
+ if not sequence[n][32] then
+ match = false break
+ end
+ end
+ end
+ end
+ if match and s > l then
+ local current = last.next
+ if current then
+ -- removed optimiziation for s-l == 1, we have to deal with marks anyway
+ local n = l + 1
+ while n <= s do
+ if current then
+ local id = current.id
+ if id == glyph then
+ if current.subtype<256 and current.font == currentfont then -- normal char
+ local char = current.char
+ local ccd = descriptions[char]
+ if ccd then
+ local class = ccd.class
+ if class == skipmark or class == skipligature or class == skipbase then
+--~ if someskip and class == skipmark or class == skipligature or class == skipbase then
+ -- skip 'm
+ elseif sequence[n][char] then
+ n = n + 1
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ else
+ match = false break
+ end
+ elseif id == disc then
+ -- skip 'm
+ elseif sequence[n][32] then -- brrr
+ n = n + 1
+ else
+ match = false break
+ end
+ current = current.next
+ elseif sequence[n][32] then
+ n = n + 1
+ else
+ match = false break
+ end
+ end
+ elseif s-l == 1 then
+ match = sequence[s][32]
+ else
+ for n=l+1,s do
+ if not sequence[n][32] then
+ match = false break
+ end
+ end
+ end
+ end
+ end
+ if match then
+ -- ck == currentcontext
+ if trace_contexts then
+ local rule, lookuptype, sequence, f, l = ck[1], ck[2] ,ck[3], ck[4], ck[5]
+ local char = start.char
+ if ck[9] then
+ logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %s (%s=>%s)",cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10])
+ else
+ logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %s",cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype)
+ end
+ end
+ local chainlookups = ck[6]
+ if chainlookups then
+ local nofchainlookups = #chainlookups
+ -- we can speed this up if needed
+ if nofchainlookups == 1 then
+ local chainlookupname = chainlookups[1]
+ local chainlookup = lookuptable[chainlookupname]
+ local cp = chainprocs[chainlookup.type]
+ if cp then
+ start, done = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname)
+ else
+ logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
+ end
+ else
+ -- actually this needs a more complex treatment for which we will use chainmores
+ local i = 1
+ repeat
+ local chainlookupname = chainlookups[i]
+ local chainlookup = lookuptable[chainlookupname]
+ local cp = chainmores[chainlookup.type]
+ if cp then
+ local ok, n
+ start, ok, n = cp(start,last,kind,chainname,ck,cache,chainlookup,chainlookupname,i)
+ -- messy since last can be changed !
+ if ok then
+ done = true
+ start = start.next
+ if n then
+ -- skip next one(s) if ligature
+ i = i + n - 1
+ end
+ end
+ else
+ logprocess("%s: multiple subchains for %s are not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
+ end
+ i = i + 1
+ until i > nofchainlookups
+ end
+ else
+ local replacements = ck[7]
+ if replacements then
+ start, done = chainprocs.reversesub(start,last,kind,chainname,ck,cache,replacements)
+ else
+ done = true -- can be meant to be skipped
+ if trace_contexts then
+ logprocess("%s: skipping match",cref(kind,chainname))
+ end
+ end
+ end
+ end
+ end
+ return start, done
+end
+
+-- Because we want to keep this elsewhere (an because speed is less an issue) we
+-- pass the font id so that the verbose variant can access the relevant helper tables.
+
+local verbose_handle_contextchain = function(font,...)
+ logwarning("no verbose handler installed, reverting to 'normal'")
+ otf.setcontextchain()
+ return normal_handle_contextchain(...)
+end
+
+otf.chainhandlers = {
+ normal = normal_handle_contextchain,
+ verbose = verbose_handle_contextchain,
+}
+
+function otf.setcontextchain(method)
+ if not method or method == "normal" or not otf.chainhandlers[method] then
+ if handlers.contextchain then -- no need for a message while making the format
+ logwarning("installing normal contextchain handler")
+ end
+ handlers.contextchain = normal_handle_contextchain
+ else
+ logwarning("installing contextchain handler '%s'",method)
+ local handler = otf.chainhandlers[method]
+ handlers.contextchain = function(...)
+ return handler(currentfont,...)
+ end
+ end
+ handlers.gsub_context = handlers.contextchain
+ handlers.gsub_contextchain = handlers.contextchain
+ handlers.gsub_reversecontextchain = handlers.contextchain
+ handlers.gpos_contextchain = handlers.contextchain
+ handlers.gpos_context = handlers.contextchain
+end
+
+otf.setcontextchain()
+
+local missing = { } -- we only report once
+
+local function logprocess(...)
+ if trace_steps then
+ registermessage(...)
+ end
+ logs.report("otf process",...)
+end
+local function logwarning(...)
+ logs.report("otf process",...)
+end
+
+local function report_missing_cache(typ,lookup)
+ local f = missing[currentfont] if not f then f = { } missing[currentfont] = f end
+ local t = f[typ] if not t then t = { } f[typ] = t end
+ if not t[lookup] then
+ t[lookup] = true
+ logwarning("missing cache for lookup %s of type %s in font %s (%s)",lookup,typ,currentfont,tfmdata.fullname)
+ end
+end
+
+local resolved = { } -- we only resolve a font,script,language pair once
+
+function fonts.methods.node.otf.features(head,font,attr)
+ if trace_steps then
+ checkstep(head)
+ end
+ tfmdata = fontdata[font]
+ local shared = tfmdata.shared
+ otfdata = shared.otfdata
+ local luatex = otfdata.luatex
+ descriptions = tfmdata.descriptions
+ characters = tfmdata.characters
+ indices = tfmdata.indices
+ unicodes = tfmdata.unicodes
+ marks = tfmdata.marks
+ anchorlookups = luatex.lookup_to_anchor
+ currentfont = font
+ rlmode = 0
+ local featuredata = otfdata.shared.featuredata -- can be made local to closure
+ local sequences = luatex.sequences
+ lookuptable = luatex.lookups
+ local done = false
+ local script, language, s_enabled, a_enabled, dyn
+ local attribute_driven = attr and attr ~= 0
+ if attribute_driven then
+ local features = context_setups[context_numbers[attr]] -- could be a direct list
+ dyn = context_merged[attr] or 0
+ language, script = features.language or "dflt", features.script or "dflt"
+ a_enabled = features -- shared.features -- can be made local to the resolver
+ if dyn == 2 or dyn == -2 then
+ -- font based
+ s_enabled = shared.features
+ end
+ else
+ language, script = tfmdata.language or "dflt", tfmdata.script or "dflt"
+ s_enabled = shared.features -- can be made local to the resolver
+ dyn = 0
+ end
+ -- we can save some runtime by caching feature tests
+ local res = resolved[font] if not res then res = { } resolved[font] = res end
+ local rs = res [script] if not rs then rs = { } res [script] = rs end
+ local rl = rs [language] if not rl then rl = { } rs [language] = rl end
+ local ra = rl [attr] if ra == nil then ra = { } rl [attr] = ra end -- attr can be false
+ -- sequences always > 1 so no need for optimization
+ for s=1,#sequences do
+ local success = false
+ local sequence = sequences[s]
+ local r = ra[s] -- cache
+ if r == nil then
+ --
+ -- this bit will move to font-ctx and become a function
+ ---
+ local chain = sequence.chain or 0
+ local features = sequence.features
+ if not features then
+ -- indirect lookup, part of chain (todo: make this a separate table)
+ r = false -- { false, false, chain }
+ else
+ local valid, attribute, kind, what = false, false
+ for k,v in next, features do
+ -- we can quit earlier but for the moment we want the tracing
+ local s_e = s_enabled and s_enabled[k]
+ local a_e = a_enabled and a_enabled[k]
+ if s_e or a_e then
+ local l = v[script] or v[wildcard]
+ if l then
+ -- not l[language] or l[default] or l[wildcard] because we want tracing
+ -- only first attribute match check, so we assume simple fina's
+ -- default can become a font feature itself
+ if l[language] then
+--~ valid, what = true, language
+ valid, what = s_e or a_e, language
+ -- elseif l[default] then
+ -- valid, what = true, default
+ elseif l[wildcard] then
+--~ valid, what = true, wildcard
+ valid, what = s_e or a_e, wildcard
+ end
+ if valid then
+ kind, attribute = k, special_attributes[k] or false
+ if a_e and dyn < 0 then
+ valid = false
+ end
+ if trace_applied then
+ local typ, action = match(sequence.type,"(.*)_(.*)")
+ logs.report("otf node mode",
+ "%s font: %03i, dynamic: %03i, kind: %s, lookup: %3i, script: %-4s, language: %-4s (%-4s), type: %s, action: %s, name: %s",
+ (valid and "+") or "-",font,attr or 0,kind,s,script,language,what,typ,action,sequence.name)
+ end
+ break
+ end
+ end
+ end
+ end
+ if valid then
+ r = { valid, attribute, chain, kind }
+ else
+ r = false -- { valid, attribute, chain, "generic" } -- false anyway, could be flag instead of table
+ end
+ end
+ ra[s] = r
+ end
+featurevalue = r and r[1] -- toto: pass to function instead
+ if featurevalue then
+ local attribute, chain, typ, subtables = r[2], r[3], sequence.type, sequence.subtables
+ if chain < 0 then
+ -- this is a limited case, no special treatments like 'init' etc
+ local handler = handlers[typ]
+ local thecache = featuredata[typ] or { }
+ -- we need to get rid of this slide !
+ start = slide_node_list(head) -- slow (we can store tail because there's always a skip at the end): todo
+ while start do
+ local id = start.id
+ if id == glyph then
+--~ if start.subtype<256 and start.font == font and (not attr or has_attribute(start,0,attr)) then
+ if start.subtype<256 and start.font == font and has_attribute(start,0,attr) then
+ for i=1,#subtables do
+ local lookupname = subtables[i]
+ local lookupcache = thecache[lookupname]
+ if lookupcache then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ start, success = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,i)
+ if success then
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
+ end
+ end
+ if start then start = start.prev end
+ else
+ start = start.prev
+ end
+ else
+ start = start.prev
+ end
+ end
+ else
+ local handler = handlers[typ]
+ local ns = #subtables
+ local thecache = featuredata[typ] or { }
+ start = head -- local ?
+ rlmode = 0
+ if ns == 1 then
+ local lookupname = subtables[1]
+ local lookupcache = thecache[lookupname]
+ if not lookupcache then
+ report_missing_cache(typ,lookupname)
+ else
+ while start do
+ local id = start.id
+ if id == glyph then
+--~ if start.font == font and start.subtype<256 and (not attr or has_attribute(start,0,attr)) and (not attribute or has_attribute(start,state,attribute)) then
+ if start.font == font and start.subtype<256 and has_attribute(start,0,attr) and (not attribute or has_attribute(start,state,attribute)) then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ -- sequence kan weg
+ local ok
+ start, ok = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,1)
+ if ok then
+ success = true
+ end
+ end
+ if start then start = start.next end
+ else
+ start = start.next
+ end
+ -- elseif id == glue then
+ -- if p[5] then -- chain
+ -- local pc = pp[32]
+ -- if pc then
+ -- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
+ -- if ok then
+ -- done = true
+ -- end
+ -- if start then start = start.next end
+ -- else
+ -- start = start.next
+ -- end
+ -- else
+ -- start = start.next
+ -- end
+ elseif id == whatsit then
+ local subtype = start.subtype
+ if subtype == 7 then
+ local dir = start.dir
+ if dir == "+TRT" then
+ rlmode = -1
+ elseif dir == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ elseif subtype == 6 then
+ local dir = start.dir
+ if dir == "TRT" then
+ rlmode = -1
+ elseif dir == "TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ end
+ start = start.next
+ else
+ start = start.next
+ end
+ end
+
+ end
+ else
+ while start do
+ local id = start.id
+ if id == glyph then
+--~ if start.subtype<256 and start.font == font and (not attr or has_attribute(start,0,attr)) and (not attribute or has_attribute(start,state,attribute)) then
+ if start.subtype<256 and start.font == font and has_attribute(start,0,attr) and (not attribute or has_attribute(start,state,attribute)) then
+ for i=1,ns do
+ local lookupname = subtables[i]
+ local lookupcache = thecache[lookupname]
+ if lookupcache then
+ local lookupmatch = lookupcache[start.char]
+ if lookupmatch then
+ -- we could move all code inline but that makes things even more unreadable
+ local ok
+ start, ok = handler(start,r[4],lookupname,lookupmatch,sequence,featuredata,i)
+ if ok then
+ success = true
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
+ end
+ end
+ if start then start = start.next end
+ else
+ start = start.next
+ end
+ -- elseif id == glue then
+ -- if p[5] then -- chain
+ -- local pc = pp[32]
+ -- if pc then
+ -- start, ok = start, false -- p[1](start,kind,p[2],pc,p[3],p[4])
+ -- if ok then
+ -- done = true
+ -- end
+ -- if start then start = start.next end
+ -- else
+ -- start = start.next
+ -- end
+ -- else
+ -- start = start.next
+ -- end
+ elseif id == whatsit then
+ local subtype = start.subtype
+ if subtype == 7 then
+ local dir = start.dir
+ if dir == "+TRT" then
+ rlmode = -1
+ elseif dir == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ elseif subtype == 6 then
+ local dir = start.dir
+ if dir == "TRT" then
+ rlmode = -1
+ elseif dir == "TLT" then
+ rlmode = 1
+ else
+ rlmode = 0
+ end
+ end
+ start = start.next
+ else
+ start = start.next
+ end
+ end
+ end
+ end
+ if success then
+ done = true
+ end
+ if trace_steps then -- ?
+ registerstep(head)
+ end
+ end
+ end
+ return head, done
+end
+
+otf.features.prepare = { }
+
+-- we used to share code in the following functions but that costs a lot of
+-- memory due to extensive calls to functions (easily hundreds of thousands per
+-- document)
+
+local function split(replacement,original,cache,unicodes)
+ -- we can cache this too, but not the same
+ local o, t, n = { }, { }, 0
+ for s in gmatch(original,"[^ ]+") do
+ local us = unicodes[s]
+ if type(us) == "number" then
+ o[#o+1] = us
+ else
+ o[#o+1] = us[1]
+ end
+ end
+ for s in gmatch(replacement,"[^ ]+") do
+ n = n + 1
+ local us = unicodes[s]
+ if type(us) == "number" then
+ t[o[n]] = us
+ else
+ t[o[n]] = us[1]
+ end
+ end
+ return t
+end
+
+local function uncover(covers,result,cache,unicodes)
+ -- lpeg hardly faster (.005 sec on mk)
+ for n=1,#covers do
+ local c = covers[n]
+ local cc = cache[c]
+ if not cc then
+ local t = { }
+ for s in gmatch(c,"[^ ]+") do
+ local us = unicodes[s]
+ if type(us) == "number" then
+ t[us] = true
+ else
+ for i=1,#us do
+ t[us[i]] = true
+ end
+ end
+ end
+ cache[c] = t
+ result[#result+1] = t
+ else
+ result[#result+1] = cc
+ end
+ end
+end
+
+local function prepare_lookups(tfmdata)
+ local otfdata = tfmdata.shared.otfdata
+ local featuredata = otfdata.shared.featuredata
+ local anchor_to_lookup = otfdata.luatex.anchor_to_lookup
+ local lookup_to_anchor = otfdata.luatex.lookup_to_anchor
+ --
+ local multiple = featuredata.gsub_multiple
+ local alternate = featuredata.gsub_alternate
+ local single = featuredata.gsub_single
+ local ligature = featuredata.gsub_ligature
+ local pair = featuredata.gpos_pair
+ local position = featuredata.gpos_single
+ local kerns = featuredata.gpos_pair
+ local mark = featuredata.gpos_mark2mark
+ local cursive = featuredata.gpos_cursive
+ --
+ local unicodes = tfmdata.unicodes -- names to unicodes
+ local indices = tfmdata.indices
+ local descriptions = tfmdata.descriptions
+ --
+ -- we can change the otf table after loading but then we need to adapt base mode
+ -- as well (no big deal)
+ --
+ for unicode, glyph in next, descriptions do
+ local lookups = glyph.lookups
+ if lookups then
+ for lookup, whatever in next, lookups do
+ for i=1,#whatever do -- normaly one
+ local p = whatever[i]
+ local what = p[1]
+ if what == 'substitution' then
+ local old, new = unicode, unicodes[p[2]]
+ if type(new) == "table" then
+ new = new[1]
+ end
+ local s = single[lookup]
+ if not s then s = { } single[lookup] = s end
+ s[old] = new
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: substitution %s => %s",lookup,old,new)
+--~ end
+ break
+ elseif what == 'multiple' then
+ local old, new = unicode, { }
+ local m = multiple[lookup]
+ if not m then m = { } multiple[lookup] = m end
+ m[old] = new
+ for pc in gmatch(p[2],"[^ ]+") do
+ local upc = unicodes[pc]
+ if type(upc) == "number" then
+ new[#new+1] = upc
+ else
+ new[#new+1] = upc[1]
+ end
+ end
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: multiple %s => %s",lookup,old,concat(new," "))
+--~ end
+ break
+ elseif what == 'alternate' then
+ local old, new = unicode, { }
+ local a = alternate[lookup]
+ if not a then a = { } alternate[lookup] = a end
+ a[old] = new
+ for pc in gmatch(p[2],"[^ ]+") do
+ local upc = unicodes[pc]
+ if type(upc) == "number" then
+ new[#new+1] = upc
+ else
+ new[#new+1] = upc[1]
+ end
+ end
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: alternate %s => %s",lookup,old,concat(new,"|"))
+--~ end
+ break
+ elseif what == "ligature" then
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: ligature %s => %s",lookup,p[2],glyph.name)
+--~ end
+ local first = true
+ local t = ligature[lookup]
+ if not t then t = { } ligature[lookup] = t end
+ for s in gmatch(p[2],"[^ ]+") do
+ if first then
+ local u = unicodes[s]
+ if not u then
+ logs.report("define otf","lookup %s: ligature %s => %s ignored due to invalid unicode",lookup,p[2],glyph.name)
+ break
+ elseif type(u) == "number" then
+ if not t[u] then
+ t[u] = { { } }
+ end
+ t = t[u]
+ else
+ local tt = t
+ local tu
+ for i=1,#u do
+ local u = u[i]
+ if i==1 then
+ if not t[u] then
+ t[u] = { { } }
+ end
+ tu = t[u]
+ t = tu
+ else
+ if not t[u] then
+ tt[u] = tu
+ end
+ end
+ end
+ end
+ first = false
+ else
+ s = unicodes[s]
+ local t1 = t[1]
+ if not t1[s] then
+ t1[s] = { { } }
+ end
+ t = t1[s]
+ end
+ end
+ t[2] = unicode
+ elseif what == 'position' then
+ -- not used
+ local s = position[lookup]
+ if not s then s = { } position[lookup] = s end
+ s[unicode] = p[2] -- direct pointer to kern spec
+ elseif what == 'pair' then
+ local s = pair[lookup]
+ if not s then s = { } pair[lookup] = s end
+ local others = s[unicode]
+ if not others then others = { } s[unicode] = others end
+ -- todo: fast check for space
+ local two = p[2]
+ local upc = unicodes[two]
+ if not upc then
+ for pc in gmatch(two,"[^ ]+") do
+ local upc = unicodes[pc]
+ if type(upc) == "number" then
+ others[upc] = p -- direct pointer to main table
+ else
+ for i=1,#upc do
+ others[upc[i]] = p -- direct pointer to main table
+ end
+ end
+ end
+ elseif type(upc) == "number" then
+ others[upc] = p -- direct pointer to main table
+ else
+ for i=1,#upc do
+ others[upc[i]] = p -- direct pointer to main table
+ end
+ end
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: pair for U+%04X",lookup,unicode)
+--~ end
+ end
+ end
+ end
+ end
+ local list = glyph.mykerns
+ if list then
+ for lookup, krn in next, list do
+ local k = kerns[lookup]
+ if not k then k = { } kerns[lookup] = k end
+ k[unicode] = krn -- ref to glyph, saves lookup
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: kern for U+%04X",lookup,unicode)
+--~ end
+ end
+ end
+ local oanchor = glyph.anchors
+ if oanchor then
+ for typ, anchors in next, oanchor do -- types
+ if typ == "mark" then
+ for name, anchor in next, anchors do
+ local lookups = anchor_to_lookup[name]
+ if lookups then
+ for lookup, _ in next, lookups do
+ local f = mark[lookup]
+ if not f then f = { } mark[lookup] = f end
+ f[unicode] = anchors -- ref to glyph, saves lookup
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: mark anchor %s for U+%04X",lookup,name,unicode)
+--~ end
+ end
+ end
+ end
+ elseif typ == "cexit" then -- or entry?
+ for name, anchor in next, anchors do
+ local lookups = anchor_to_lookup[name]
+ if lookups then
+ for lookup, _ in next, lookups do
+ local f = cursive[lookup]
+ if not f then f = { } cursive[lookup] = f end
+ f[unicode] = anchors -- ref to glyph, saves lookup
+--~ if trace_lookups then
+--~ logs.report("define otf","lookup %s: exit anchor %s for U+%04X",lookup,name,unicode)
+--~ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+-- local cache = { }
+luatex = luatex or {} -- this has to change ... we need a better one
+
+function prepare_contextchains(tfmdata)
+ local otfdata = tfmdata.shared.otfdata
+ local lookups = otfdata.lookups
+ if lookups then
+ local featuredata = otfdata.shared.featuredata
+ local contextchain = featuredata.gsub_contextchain -- shared with gpos
+ local reversecontextchain = featuredata.gsub_reversecontextchain -- shared with gpos
+ local characters = tfmdata.characters
+ local unicodes = tfmdata.unicodes
+ local indices = tfmdata.indices
+ local cache = luatex.covers
+ if not cache then
+ cache = { }
+ luatex.covers = cache
+ end
+ --
+ for lookupname, lookupdata in next, otfdata.lookups do
+ local lookuptype = lookupdata.type
+ if not lookuptype then
+ logs.report("otf process","missing lookuptype for %s",lookupname)
+ else
+ local rules = lookupdata.rules
+ if rules then
+ local fmt = lookupdata.format
+ -- contextchain[lookupname][unicode]
+ if fmt == "coverage" then
+ if lookuptype ~= "chainsub" and lookuptype ~= "chainpos" then
+ logs.report("otf process","unsupported coverage %s for %s",lookuptype,lookupname)
+ else
+ local contexts = contextchain[lookupname]
+ if not contexts then
+ contexts = { }
+ contextchain[lookupname] = contexts
+ end
+ local t = { }
+ for nofrules=1,#rules do -- does #rules>1 happen often?
+ local rule = rules[nofrules]
+ local coverage = rule.coverage
+ if coverage and coverage.current then
+ local current, before, after, sequence = coverage.current, coverage.before, coverage.after, { }
+ if before then
+ uncover(before,sequence,cache,unicodes)
+ end
+ local start = #sequence + 1
+ uncover(current,sequence,cache,unicodes)
+ local stop = #sequence
+ if after then
+ uncover(after,sequence,cache,unicodes)
+ end
+ if sequence[1] then
+ t[#t+1] = { nofrules, lookuptype, sequence, start, stop, rule.lookups }
+ for unic, _ in next, sequence[start] do
+ local cu = contexts[unic]
+ if not cu then
+ contexts[unic] = t
+ end
+ end
+ end
+ end
+ end
+ end
+ elseif fmt == "reversecoverage" then
+ if lookuptype ~= "reversesub" then
+ logs.report("otf process","unsupported reverse coverage %s for %s",lookuptype,lookupname)
+ else
+ local contexts = reversecontextchain[lookupname]
+ if not contexts then
+ contexts = { }
+ reversecontextchain[lookupname] = contexts
+ end
+ local t = { }
+ for nofrules=1,#rules do
+ local rule = rules[nofrules]
+ local reversecoverage = rule.reversecoverage
+ if reversecoverage and reversecoverage.current then
+ local current, before, after, replacements, sequence = reversecoverage.current, reversecoverage.before, reversecoverage.after, reversecoverage.replacements, { }
+ if before then
+ uncover(before,sequence,cache,unicodes)
+ end
+ local start = #sequence + 1
+ uncover(current,sequence,cache,unicodes)
+ local stop = #sequence
+ if after then
+ uncover(after,sequence,cache,unicodes)
+ end
+ if replacements then
+ replacements = split(replacements,current[1],cache,unicodes)
+ end
+ if sequence[1] then
+ -- this is different from normal coverage, we assume only replacements
+ t[#t+1] = { nofrules, lookuptype, sequence, start, stop, rule.lookups, replacements }
+ for unic, _ in next, sequence[start] do
+ local cu = contexts[unic]
+ if not cu then
+ contexts[unic] = t
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+function fonts.initializers.node.otf.features(tfmdata,value)
+ if true then -- value then
+ if not tfmdata.shared.otfdata.shared.initialized then
+ local t = trace_preparing and os.clock()
+ local otfdata = tfmdata.shared.otfdata
+ local featuredata = otfdata.shared.featuredata
+ -- caches
+ featuredata.gsub_multiple = { }
+ featuredata.gsub_alternate = { }
+ featuredata.gsub_single = { }
+ featuredata.gsub_ligature = { }
+ featuredata.gsub_contextchain = { }
+ featuredata.gsub_reversecontextchain = { }
+ featuredata.gpos_pair = { }
+ featuredata.gpos_single = { }
+ featuredata.gpos_mark2base = { }
+ featuredata.gpos_mark2ligature = featuredata.gpos_mark2base
+ featuredata.gpos_mark2mark = featuredata.gpos_mark2base
+ featuredata.gpos_cursive = { }
+ featuredata.gpos_contextchain = featuredata.gsub_contextchain
+ featuredata.gpos_reversecontextchain = featuredata.gsub_reversecontextchain
+ --
+ prepare_contextchains(tfmdata)
+ prepare_lookups(tfmdata)
+ otfdata.shared.initialized = true
+ if trace_preparing then
+ logs.report("otf process","preparation time is %0.3f seconds for %s",os.clock()-t,tfmdata.fullname or "?")
+ end
+ end
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-ota'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (analysing)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this might become scrp-*.lua
+
+local type, tostring, match, format, concat = type, tostring, string.match, string.format, table.concat
+
+if not trackers then trackers = { register = function() end } end
+
+local trace_analyzing = false trackers.register("otf.analyzing", function(v) trace_analyzing = v end)
+local trace_cjk = false trackers.register("cjk.injections", function(v) trace_cjk = v end)
+
+trackers.register("cjk.analyzing","otf.analyzing")
+
+fonts = fonts or { }
+fonts.analyzers = fonts.analyzers or { }
+fonts.analyzers.initializers = fonts.analyzers.initializers or { node = { otf = { } } }
+fonts.analyzers.methods = fonts.analyzers.methods or { node = { otf = { } } }
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+local initializers = fonts.analyzers.initializers
+local methods = fonts.analyzers.methods
+
+local glyph = node.id('glyph')
+local glue = node.id('glue')
+local penalty = node.id('penalty')
+
+local set_attribute = node.set_attribute
+local has_attribute = node.has_attribute
+local traverse_id = node.traverse_id
+local delete_node = nodes.delete
+local replace_node = nodes.replace
+local insert_node_after = node.insert_after
+local insert_node_before = node.insert_before
+local traverse_node_list = node.traverse
+
+local fontdata = fonts.ids
+local state = attributes.private('state')
+
+local fcs = (fonts.color and fonts.color.set) or function() end
+local fcr = (fonts.color and fonts.color.reset) or function() end
+
+local a_to_script = otf.a_to_script
+local a_to_language = otf.a_to_language
+
+-- in the future we will use language/script attributes instead of the
+-- font related value, but then we also need dynamic features which is
+-- somewhat slower; and .. we need a chain of them
+
+
+function fonts.initializers.node.otf.analyze(tfmdata,value,attr)
+ if attr and attr > 0 then
+ script, language = a_to_script[attr], a_to_language[attr]
+ else
+ script, language = tfmdata.script, tfmdata.language
+ end
+ local action = initializers[script]
+ if action then
+ if type(action) == "function" then
+ return action(tfmdata,value)
+ else
+ local action = action[language]
+ if action then
+ return action(tfmdata,value)
+ end
+ end
+ end
+ return nil
+end
+
+function fonts.methods.node.otf.analyze(head,font,attr)
+ local tfmdata = fontdata[font]
+ local script, language
+ if attr and attr > 0 then
+ script, language = a_to_script[attr], a_to_language[attr]
+ else
+ script, language = tfmdata.script, tfmdata.language
+ end
+ local action = methods[script]
+ if action then
+ if type(action) == "function" then
+ return action(head,font,attr)
+ else
+ action = action[language]
+ if action then
+ return action(head,font,attr)
+ end
+ end
+ end
+ return head, false
+end
+
+otf.features.register("analyze",true) -- we always analyze
+table.insert(fonts.triggers,"analyze") -- we need a proper function for doing this
+
+-- latin
+
+fonts.analyzers.methods.latn = fonts.analyzers.aux.setstate
+
+-- this info eventually will go into char-def
+
+local zwnj = 0x200C
+local zwj = 0x200D
+
+local isol = {
+ [0x0600] = true, [0x0601] = true, [0x0602] = true, [0x0603] = true,
+ [0x0608] = true, [0x060B] = true, [0x0621] = true, [0x0674] = true,
+ [0x06DD] = true, [zwnj] = true,
+}
+
+local isol_fina = {
+ [0x0622] = true, [0x0623] = true, [0x0624] = true, [0x0625] = true,
+ [0x0627] = true, [0x0629] = true, [0x062F] = true, [0x0630] = true,
+ [0x0631] = true, [0x0632] = true, [0x0648] = true, [0x0671] = true,
+ [0x0672] = true, [0x0673] = true, [0x0675] = true, [0x0676] = true,
+ [0x0677] = true, [0x0688] = true, [0x0689] = true, [0x068A] = true,
+ [0x068B] = true, [0x068C] = true, [0x068D] = true, [0x068E] = true,
+ [0x068F] = true, [0x0690] = true, [0x0691] = true, [0x0692] = true,
+ [0x0693] = true, [0x0694] = true, [0x0695] = true, [0x0696] = true,
+ [0x0697] = true, [0x0698] = true, [0x0699] = true, [0x06C0] = true,
+ [0x06C3] = true, [0x06C4] = true, [0x06C5] = true, [0x06C6] = true,
+ [0x06C7] = true, [0x06C8] = true, [0x06C9] = true, [0x06CA] = true,
+ [0x06CB] = true, [0x06CD] = true, [0x06CF] = true, [0x06D2] = true,
+ [0x06D3] = true, [0x06D5] = true, [0x06EE] = true, [0x06EF] = true,
+ [0x0759] = true, [0x075A] = true, [0x075B] = true, [0x076B] = true,
+ [0x076C] = true, [0x0771] = true, [0x0773] = true, [0x0774] = true,
+ [0x0778] = true, [0x0779] = true,
+}
+
+local isol_fina_medi_init = {
+ [0x0626] = true, [0x0628] = true, [0x062A] = true, [0x062B] = true,
+ [0x062C] = true, [0x062D] = true, [0x062E] = true, [0x0633] = true,
+ [0x0634] = true, [0x0635] = true, [0x0636] = true, [0x0637] = true,
+ [0x0638] = true, [0x0639] = true, [0x063A] = true, [0x063B] = true,
+ [0x063C] = true, [0x063D] = true, [0x063E] = true, [0x063F] = true,
+ [0x0640] = true, [0x0641] = true, [0x0642] = true, [0x0643] = true,
+ [0x0644] = true, [0x0645] = true, [0x0646] = true, [0x0647] = true,
+ [0x0649] = true, [0x064A] = true, [0x066E] = true, [0x066F] = true,
+ [0x0678] = true, [0x0679] = true, [0x067A] = true, [0x067B] = true,
+ [0x067C] = true, [0x067D] = true, [0x067E] = true, [0x067F] = true,
+ [0x0680] = true, [0x0681] = true, [0x0682] = true, [0x0683] = true,
+ [0x0684] = true, [0x0685] = true, [0x0686] = true, [0x0687] = true,
+ [0x069A] = true, [0x069B] = true, [0x069C] = true, [0x069D] = true,
+ [0x069E] = true, [0x069F] = true, [0x06A0] = true, [0x06A1] = true,
+ [0x06A2] = true, [0x06A3] = true, [0x06A4] = true, [0x06A5] = true,
+ [0x06A6] = true, [0x06A7] = true, [0x06A8] = true, [0x06A9] = true,
+ [0x06AA] = true, [0x06AB] = true, [0x06AC] = true, [0x06AD] = true,
+ [0x06AE] = true, [0x06AF] = true, [0x06B0] = true, [0x06B1] = true,
+ [0x06B2] = true, [0x06B3] = true, [0x06B4] = true, [0x06B5] = true,
+ [0x06B6] = true, [0x06B7] = true, [0x06B8] = true, [0x06B9] = true,
+ [0x06BA] = true, [0x06BB] = true, [0x06BC] = true, [0x06BD] = true,
+ [0x06BE] = true, [0x06BF] = true, [0x06C1] = true, [0x06C2] = true,
+ [0x06CC] = true, [0x06CE] = true, [0x06D0] = true, [0x06D1] = true,
+ [0x06FA] = true, [0x06FB] = true, [0x06FC] = true, [0x06FF] = true,
+ [0x0750] = true, [0x0751] = true, [0x0752] = true, [0x0753] = true,
+ [0x0754] = true, [0x0755] = true, [0x0756] = true, [0x0757] = true,
+ [0x0758] = true, [0x075C] = true, [0x075D] = true, [0x075E] = true,
+ [0x075F] = true, [0x0760] = true, [0x0761] = true, [0x0762] = true,
+ [0x0763] = true, [0x0764] = true, [0x0765] = true, [0x0766] = true,
+ [0x0767] = true, [0x0768] = true, [0x0769] = true, [0x076A] = true,
+ [0x076D] = true, [0x076E] = true, [0x076F] = true, [0x0770] = true,
+ [0x0772] = true, [0x0775] = true, [0x0776] = true, [0x0777] = true,
+ [0x077A] = true, [0x077B] = true, [0x077C] = true, [0x077D] = true,
+ [0x077E] = true, [0x077F] = true, [zwj] = true,
+}
+
+local arab_warned = { }
+
+-- todo: gref
+
+local function warning(current,what)
+ local char = current.char
+ if not arab_warned[char] then
+ log.report("analyze","arab: character %s (U+%04X) has no %s class", char, char, what)
+ arab_warned[char] = true
+ end
+end
+
+function fonts.analyzers.methods.nocolor(head,font,attr)
+ for n in traverse_node_list(head,glyph) do
+ if not font or n.font == font then
+ fcr(n)
+ end
+ end
+ return head, true
+end
+
+otf.remove_joiners = false -- true -- for idris who want it as option
+
+local function finish(first,last)
+ if last then
+ if first == last then
+ local fc = first.char
+ if isol_fina_medi_init[fc] or isol_fina[fc] then
+ set_attribute(first,state,4) -- isol
+ if trace_analyzing then fcs(first,"font:isol") end
+ else
+ warning(first,"isol")
+ set_attribute(first,state,0) -- error
+ if trace_analyzing then fcr(first) end
+ end
+ else
+ local lc = last.char
+ if isol_fina_medi_init[lc] or isol_fina[lc] then -- why isol here ?
+ -- if laststate == 1 or laststate == 2 or laststate == 4 then
+ set_attribute(last,state,3) -- fina
+ if trace_analyzing then fcs(last,"font:fina") end
+ else
+ warning(last,"fina")
+ set_attribute(last,state,0) -- error
+ if trace_analyzing then fcr(last) end
+ end
+ end
+ first, last = nil, nil
+ elseif first then
+ -- first and last are either both set so we never com here
+ local fc = first.char
+ if isol_fina_medi_init[fc] or isol_fina[fc] then
+ set_attribute(first,state,4) -- isol
+ if trace_analyzing then fcs(first,"font:isol") end
+ else
+ warning(first,"isol")
+ set_attribute(first,state,0) -- error
+ if trace_analyzing then fcr(first) end
+ end
+ first = nil
+ end
+ return first, last
+end
+
+function fonts.analyzers.methods.arab(head,font,attr) -- maybe make a special version with no trace
+ local tfmdata = fontdata[font]
+ local marks = tfmdata.marks
+ local first, last, current, done = nil, nil, head, false
+ local joiners, nonjoiners
+ local removejoiners = tfmdata.remove_joiners -- or otf.remove_joiners
+ if removejoiners then
+ joiners, nonjoiners = { }, { }
+ end
+ while current do
+ if current.id == glyph and current.subtype<256 and current.font == font and not has_attribute(current,state) then
+ done = true
+ local char = current.char
+ if removejoiners then
+ if char == zwj then
+ joiners[#joiners+1] = current
+ elseif char == zwnj then
+ nonjoiners[#nonjoiners+1] = current
+ end
+ end
+ if marks[char] then
+ set_attribute(current,state,5) -- mark
+ if trace_analyzing then fcs(current,"font:mark") end
+ elseif isol[char] then -- can be zwj or zwnj too
+ first, last = finish(first,last)
+ set_attribute(current,state,4) -- isol
+ if trace_analyzing then fcs(current,"font:isol") end
+ first, last = nil, nil
+ elseif not first then
+ if isol_fina_medi_init[char] then
+ set_attribute(current,state,1) -- init
+ if trace_analyzing then fcs(current,"font:init") end
+ first, last = first or current, current
+ elseif isol_fina[char] then
+ set_attribute(current,state,4) -- isol
+ if trace_analyzing then fcs(current,"font:isol") end
+ first, last = nil, nil
+ else -- no arab
+ first, last = finish(first,last)
+ end
+ elseif isol_fina_medi_init[char] then
+ first, last = first or current, current
+ set_attribute(current,state,2) -- medi
+ if trace_analyzing then fcs(current,"font:medi") end
+ elseif isol_fina[char] then
+ if not has_attribute(last,state,1) then
+ -- tricky, we need to check what last may be !
+ set_attribute(last,state,2) -- medi
+ if trace_analyzing then fcs(last,"font:medi") end
+ end
+ set_attribute(current,state,3) -- fina
+ if trace_analyzing then fcs(current,"font:fina") end
+ first, last = nil, nil
+ elseif char >= 0x0600 and char <= 0x06FF then
+ if trace_analyzing then fcs(current,"font:rest") end
+ first, last = finish(first,last)
+ else --no
+ first, last = finish(first,last)
+ end
+ else
+ first, last = finish(first,last)
+ end
+ current = current.next
+ end
+ first, last = finish(first,last)
+ if removejoiners then
+ for i=1,#joiners do
+ head = delete_node(head,joiners[i])
+ end
+ for i=1,#nonjoiners do
+ head = replace_node(head,nonjoiners[i],nodes.glue(0)) -- or maybe a kern
+ end
+ end
+ return head, done
+end
+
+table.insert(fonts.manipulators,"joiners")
+
+function fonts.initializers.node.otf.joiners(tfmdata,value)
+ if value == "strip" then
+ tfmdata.remove_joiners = true
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-otc'] = {
+ version = 1.001,
+ comment = "companion to font-otf.lua (context)",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, insert = string.format, table.insert
+local type, next = type, next
+
+local ctxcatcodes = tex.ctxcatcodes
+
+-- we assume that the other otf stuff is loaded already
+
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+
+local otf = fonts.otf
+local tfm = fonts.tfm
+
+-- instead of "script = "DFLT", langs = { 'dflt' }" we now use wildcards (we used to
+-- have always); some day we can write a "force always when true" trick for other
+-- features as well
+
+local extra_lists = {
+ tlig = {
+ {
+ endash = "hyphen hyphen",
+ emdash = "hyphen hyphen hyphen",
+ -- quotedblleft = "quoteleft quoteleft",
+ -- quotedblright = "quoteright quoteright",
+ -- quotedblleft = "grave grave",
+ -- quotedblright = "quotesingle quotesingle",
+ -- quotedblbase = "comma comma",
+ },
+ },
+ trep = {
+ {
+ -- [0x0022] = 0x201D,
+ [0x0027] = 0x2019,
+ -- [0x0060] = 0x2018,
+ },
+ },
+ anum = {
+ { -- arabic
+ [0x0030] = 0x0660,
+ [0x0031] = 0x0661,
+ [0x0032] = 0x0662,
+ [0x0033] = 0x0663,
+ [0x0034] = 0x0664,
+ [0x0035] = 0x0665,
+ [0x0036] = 0x0666,
+ [0x0037] = 0x0667,
+ [0x0038] = 0x0668,
+ [0x0039] = 0x0669,
+ },
+ { -- persian
+ [0x0030] = 0x06F0,
+ [0x0031] = 0x06F1,
+ [0x0032] = 0x06F2,
+ [0x0033] = 0x06F3,
+ [0x0034] = 0x06F4,
+ [0x0035] = 0x06F5,
+ [0x0036] = 0x06F6,
+ [0x0037] = 0x06F7,
+ [0x0038] = 0x06F8,
+ [0x0039] = 0x06F9,
+ },
+ },
+}
+
+local extra_features = { -- maybe just 1..n so that we prescribe order
+ tlig = {
+ {
+ features = { { scripts = { { script = "*", langs = { "*" }, } }, tag = "tlig", comment = "added bij mkiv" }, },
+ name = "ctx_tlig_1",
+ subtables = { { name = "ctx_tlig_1_s" } },
+ type = "gsub_ligature",
+ flags = { },
+ },
+ },
+ trep = {
+ {
+ features = { { scripts = { { script = "*", langs = { "*" }, } }, tag = "trep", comment = "added bij mkiv" }, },
+ name = "ctx_trep_1",
+ subtables = { { name = "ctx_trep_1_s" } },
+ type = "gsub_single",
+ flags = { },
+ },
+ },
+ anum = {
+ {
+ features = { { scripts = { { script = "arab", langs = { "dflt", "FAR" }, } }, tag = "anum", comment = "added bij mkiv" }, },
+ name = "ctx_anum_1",
+ subtables = { { name = "ctx_anum_1_s" } },
+ type = "gsub_single",
+ flags = { },
+ },
+ {
+ features = { { scripts = { { script = "arab", langs = { "URD" }, } }, tag = "anum", comment = "added bij mkiv" }, },
+ name = "ctx_anum_2",
+ subtables = { { name = "ctx_anum_2_s" } },
+ type = "gsub_single",
+ flags = { },
+ },
+ },
+}
+
+fonts.otf.enhancers["add some missing characters"] = function(data,filename)
+ -- todo
+end
+
+fonts.otf.enhancers["enrich with features"] = function(data,filename)
+ -- could be done elsewhere (true can be #)
+ local used = { }
+ for i=1,#otf.glists do
+ local g = data[otf.glists[i]]
+ if g then
+ for i=1,#g do
+ local f = g[i].features
+ if f then
+ for i=1,#f do
+ local t = f[i].tag
+ if t then used[t] = true end
+ end
+ end
+ end
+ end
+ end
+ --
+ local glyphs = data.glyphs
+ local indices = data.map.map
+ data.gsub = data.gsub or { }
+ for kind, specifications in next, extra_features do
+ if not used[kind] then
+ local done = 0
+ for s=1,#specifications do
+ local added = false
+ local specification = specifications[s]
+ local list = extra_lists[kind][s]
+ local name = specification.name .. "_s"
+ if specification.type == "gsub_ligature" then
+ for unicode, index in next, indices do
+ local glyph = glyphs[index]
+ local ligature = list[glyph.name]
+ if ligature then
+ local o = glyph.lookups or { }
+ -- o[name] = { "ligature", ligature, glyph.name }
+ o[name] = {
+ {
+ ["type"] = "ligature",
+ ["specification"] = {
+ char = glyph.name,
+ components = ligature,
+ }
+ }
+ }
+ glyph.lookups, done, added = o, done+1, true
+ end
+ end
+ elseif specification.type == "gsub_single" then
+ for unicode, index in next, indices do
+ local glyph = glyphs[index]
+ local r = list[unicode]
+ if r then
+ local replacement = indices[r]
+ if replacement and glyphs[replacement] then
+ local o = glyph.lookups or { }
+ -- o[name] = { { "substitution", glyphs[replacement].name } }
+ o[name] = {
+ {
+ ["type"] = "substitution",
+ ["specification"] = {
+ variant = glyphs[replacement].name,
+ }
+ }
+ }
+ glyph.lookups, done, added = o, done+1, true
+ end
+ end
+ end
+ end
+ if added then
+ insert(data.gsub,s,table.fastcopy(specification)) -- right order
+ end
+ end
+ if done > 0 then
+ if trace_loading then
+ logs.report("load otf","enhance: registering %s feature (%s glyphs affected)",kind,done)
+ end
+ end
+ end
+ end
+end
+
+otf.tables.features['tlig'] = 'TeX Ligatures'
+otf.tables.features['trep'] = 'TeX Replacements'
+otf.tables.features['anum'] = 'Arabic Digits'
+
+otf.features.register_base_substitution('tlig')
+otf.features.register_base_substitution('trep')
+otf.features.register_base_substitution('anum')
+
+-- the functionality is defined elsewhere
+
+fonts.initializers.base.otf.equaldigits = fonts.initializers.common.equaldigits
+fonts.initializers.node.otf.equaldigits = fonts.initializers.common.equaldigits
+
+fonts.initializers.base.otf.lineheight = fonts.initializers.common.lineheight
+fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight
+
+fonts.initializers.base.otf.compose = fonts.initializers.common.compose
+fonts.initializers.node.otf.compose = fonts.initializers.common.compose
+
+-- bonus function
+
+function otf.name_to_slot(name) -- todo: afm en tfm
+ local tfmdata = fonts.ids[font.current()]
+ if tfmdata and tfmdata.shared then
+ local otfdata = tfmdata.shared.otfdata
+ local unicode = otfdata.luatex.unicodes[name]
+ if type(unicode) == "number" then
+ return unicode
+ else
+ return unicode[1]
+ end
+ end
+ return nil
+end
+
+function otf.char(n) -- todo: afm en tfm
+ if type(n) == "string" then
+ n = otf.name_to_slot(n)
+ end
+ if n then
+ tex.sprint(ctxcatcodes,format("\\char%s ",n))
+ end
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-def'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower
+local tostring, next = tostring, next
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading")
+trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*")
+
+--[[ldx--
+<p>Here we deal with defining fonts. We do so by intercepting the
+default loader that only handles <l n='tfm'/>.</p>
+--ldx]]--
+
+fonts = fonts or { }
+fonts.define = fonts.define or { }
+fonts.tfm = fonts.tfm or { }
+fonts.ids = fonts.ids or { }
+fonts.vf = fonts.vf or { }
+fonts.used = fonts.used or { }
+
+local tfm = fonts.tfm
+local vf = fonts.vf
+local define = fonts.define
+
+tfm.version = 1.01
+tfm.cache = containers.define("fonts", "tfm", tfm.version, false) -- better in font-tfm
+
+define.method = "afm or tfm" -- afm, tfm, afm or tfm, tfm or afm
+define.specify = fonts.define.specify or { }
+define.methods = fonts.define.methods or { }
+
+tfm.fonts = tfm.fonts or { }
+tfm.readers = tfm.readers or { }
+tfm.internalized = tfm.internalized or { } -- internal tex numbers
+
+tfm.readers.sequence = { 'otf', 'ttf', 'afm', 'tfm' }
+
+local readers = tfm.readers
+local sequence = readers.sequence
+
+--[[ldx--
+<p>We hardly gain anything when we cache the final (pre scaled)
+<l n='tfm'/> table. But it can be handy for debugging.</p>
+--ldx]]--
+
+fonts.version = 1.05
+fonts.cache = containers.define("fonts", "def", fonts.version, false)
+
+--[[ldx--
+<p>We can prefix a font specification by <type>name:</type> or
+<type>file:</type>. The first case will result in a lookup in the
+synonym table.</p>
+
+<typing>
+[ name: | file: ] identifier [ separator [ specification ] ]
+</typing>
+
+<p>The following function split the font specification into components
+and prepares a table that will move along as we proceed.</p>
+--ldx]]--
+
+-- beware, we discard additional specs
+--
+-- method:name method:name(sub) method:name(sub)*spec method:name*spec
+-- name name(sub) name(sub)*spec name*spec
+-- name@spec*oeps
+
+local splitter, specifiers = nil, ""
+
+function define.add_specifier(symbol)
+ specifiers = specifiers .. symbol
+ local left = lpeg.P("(")
+ local right = lpeg.P(")")
+ local colon = lpeg.P(":")
+ local method = lpeg.S(specifiers)
+ local lookup = lpeg.C(lpeg.P("file")+lpeg.P("name")) * colon -- hard test, else problems with : method
+ local sub = left * lpeg.C(lpeg.P(1-left-right-method)^1) * right
+--~ local specification = lpeg.C(method) * lpeg.C(lpeg.P(1-method)^1)
+ local specification = lpeg.C(method) * lpeg.C(lpeg.P(1)^1)
+ local name = lpeg.C((1-sub-specification)^1)
+ splitter = lpeg.P((lookup + lpeg.Cc("")) * name * (sub + lpeg.Cc("")) * (specification + lpeg.Cc("")))
+end
+
+function define.get_specification(str)
+ return splitter:match(str)
+end
+
+function define.register_split(symbol,action)
+ define.add_specifier(symbol)
+ define.specify[symbol] = action
+end
+
+function define.makespecification(specification, lookup, name, sub, method, detail, size)
+ size = size or 655360
+ if trace_defining then
+ logs.report("define font","%s -> lookup: %s, name: %s, sub: %s, method: %s, detail: %s",
+ specification, (lookup ~= "" and lookup) or "[file]", (name ~= "" and name) or "-",
+ (sub ~= "" and sub) or "-", (method ~= "" and method) or "-", (detail ~= "" and detail) or "-")
+ end
+--~ if specification.lookup then
+--~ lookup = specification.lookup -- can come from xetex [] syntax
+--~ specification.lookup = nil
+--~ end
+ if lookup ~= 'name' then -- for the moment only two lookups, maybe some day also system:
+ lookup = 'file'
+ end
+ local t = {
+ lookup = lookup, -- forced type
+ specification = specification, -- full specification
+ size = size, -- size in scaled points or -1000*n
+ name = name, -- font or filename
+ sub = sub, -- subfont (eg in ttc)
+ method = method, -- specification method
+ detail = detail, -- specification
+ resolved = "", -- resolved font name
+ forced = "", -- forced loader
+ features = { }, -- preprocessed features
+ }
+ return t
+end
+
+function define.analyze(specification, size)
+ -- can be optimized with locals
+ local lookup, name, sub, method, detail = define.get_specification(specification or "")
+ return define.makespecification(specification,lookup, name, sub, method, detail, size)
+end
+
+--[[ldx--
+<p>A unique hash value is generated by:</p>
+--ldx]]--
+
+local sortedhashkeys = table.sortedhashkeys
+
+function tfm.hash_features(specification)
+ local features = specification.features
+ if features then
+ local t = { }
+ local normal = features.normal
+ if normal and next(normal) then
+ local f = sortedhashkeys(normal)
+ for i=1,#f do
+ local v = f[i]
+ if v ~= "number" and v ~= "features" then -- i need to figure this out, features
+ t[#t+1] = v .. '=' .. tostring(normal[v])
+ end
+ end
+ end
+ local vtf = features.vtf
+ if vtf and next(vtf) then
+ local f = sortedhashkeys(vtf)
+ for i=1,#f do
+ local v = f[i]
+ t[#t+1] = v .. '=' .. tostring(vtf[v])
+ end
+ end
+--~ if specification.mathsize then
+--~ t[#t] = "mathsize=" .. specification.mathsize
+--~ end
+ if #t > 0 then
+ return concat(t,"+")
+ end
+ end
+ return "unknown"
+end
+
+fonts.designsizes = { }
+
+--[[ldx--
+<p>In principle we can share tfm tables when we are in node for a font, but then
+we need to define a font switch as an id/attr switch which is no fun, so in that
+case users can best use dynamic features ... so, we will not use that speedup. Okay,
+when we get rid of base mode we can optimize even further by sharing, but then we
+loose our testcases for <l n='luatex'/>.</p>
+--ldx]]--
+
+function tfm.hash_instance(specification,force)
+ local hash, size, fallbacks = specification.hash, specification.size, specification.fallbacks
+ if force or not hash then
+ hash = tfm.hash_features(specification)
+ specification.hash = hash
+ end
+ if size < 1000 and fonts.designsizes[hash] then
+ size = math.round(tfm.scaled(size, fonts.designsizes[hash]))
+ specification.size = size
+ end
+--~ local mathsize = specification.mathsize or 0
+--~ if mathsize > 0 then
+--~ local textsize = specification.textsize
+--~ if fallbacks then
+--~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks
+--~ else
+--~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]'
+--~ end
+--~ else
+ if fallbacks then
+ return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks
+ else
+ return hash .. ' @ ' .. tostring(size)
+ end
+--~ end
+end
+
+--[[ldx--
+<p>We can resolve the filename using the next function:</p>
+--ldx]]--
+
+function define.resolve(specification)
+ if not specification.resolved or specification.resolved == "" then -- resolved itself not per se in mapping hash
+ if specification.lookup == 'name' then
+ specification.resolved, specification.sub = fonts.names.resolve(specification.name,specification.sub)
+ if specification.resolved then
+ specification.forced = file.extname(specification.resolved)
+ specification.name = file.removesuffix(specification.resolved)
+ end
+ elseif specification.lookup == 'file' then
+ specification.forced = file.extname(specification.name)
+ specification.name = file.removesuffix(specification.name)
+ end
+ end
+ if specification.forced == "" then
+ specification.forced = nil
+ else
+ specification.forced = specification.forced
+ end
+--~ specification.hash = specification.name .. ' @ ' .. tfm.hash_features(specification)
+ specification.hash = lower(specification.name .. ' @ ' .. tfm.hash_features(specification))
+ if specification.sub and specification.sub ~= "" then
+ specification.hash = specification.sub .. ' @ ' .. specification.hash
+ end
+ return specification
+end
+
+--[[ldx--
+<p>The main read function either uses a forced reader (as determined by
+a lookup) or tries to resolve the name using the list of readers.</p>
+
+<p>We need to cache when possible. We do cache raw tfm data (from <l
+n='tfm'/>, <l n='afm'/> or <l n='otf'/>). After that we can cache based
+on specificstion (name) and size, that is, <l n='tex'/> only needs a number
+for an already loaded fonts. However, it may make sense to cache fonts
+before they're scaled as well (store <l n='tfm'/>'s with applied methods
+and features). However, there may be a relation between the size and
+features (esp in virtual fonts) so let's not do that now.</p>
+
+<p>Watch out, here we do load a font, but we don't prepare the
+specification yet.</p>
+--ldx]]--
+
+function tfm.read(specification)
+ local hash = tfm.hash_instance(specification)
+ local tfmtable = tfm.fonts[hash] -- hashes by size !
+ if not tfmtable then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmtable = readers[lower(forced)](specification)
+ if not tfmtable then
+ logs.report("define font","forced type %s of %s not found",forced,specification.name)
+ end
+ else
+ for s=1,#sequence do -- reader sequence
+ local reader = sequence[s]
+ if readers[reader] then -- not really needed
+ if trace_defining then
+ logs.report("define font","trying type %s for %s with file %s",reader,specification.name,specification.filename or "unknown")
+ end
+ tfmtable = readers[reader](specification)
+ if tfmtable then break end
+ end
+ end
+ end
+ if tfmtable then
+ if tfmtable.filename and fonts.dontembed[tfmtable.filename] then
+ tfmtable.embedding = "no"
+ else
+ tfmtable.embedding = "subset"
+ end
+ tfm.fonts[hash] = tfmtable
+ fonts.designsizes[specification.hash] = tfmtable.designsize -- we only know this for sure after loading once
+ --~ tfmtable.mode = specification.features.normal.mode or "base"
+ end
+ end
+ if not tfmtable then
+ logs.report("define font","font with name %s is not found",specification.name)
+ end
+ return tfmtable
+end
+
+--[[ldx--
+<p>For virtual fonts we need a slightly different approach:</p>
+--ldx]]--
+
+function tfm.read_and_define(name,size) -- no id
+ local specification = define.analyze(name,size)
+ local method = specification.method
+ if method and define.specify[method] then
+ specification = define.specify[method](specification)
+ end
+ specification = define.resolve(specification)
+ local hash = tfm.hash_instance(specification)
+ local id = define.registered(hash)
+ if not id then
+ local fontdata = tfm.read(specification)
+ if fontdata then
+ fontdata.hash = hash
+ id = font.define(fontdata)
+ define.register(fontdata,id)
+ tfm.cleanup_table(fontdata)
+ else
+ id = 0 -- signal
+ end
+ end
+ return fonts.ids[id], id
+end
+
+--[[ldx--
+<p>Next follow the readers. This code was written while <l n='luatex'/>
+evolved. Each one has its own way of dealing with its format.</p>
+--ldx]]--
+
+local function check_tfm(specification,fullname)
+ -- ofm directive blocks local path search unless set
+ fullname = resolvers.findbinfile(fullname, 'tfm') or "" -- just to be sure
+ if fullname ~= "" then
+ specification.filename, specification.format = fullname, "ofm"
+ return tfm.read_from_tfm(specification)
+ end
+end
+
+local function check_afm(specification,fullname)
+ fullname = resolvers.findbinfile(fullname, 'afm') or "" -- just to be sure
+ if fullname ~= "" then
+ specification.filename, specification.format = fullname, "afm"
+ return tfm.read_from_afm(specification)
+ end
+end
+
+function readers.tfm(specification)
+ local fullname, tfmtable = specification.filename or "", nil
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmtable = check_tfm(specification,specification.name .. "." .. forced)
+ end
+ if not tfmtable then
+ tfmtable = check_tfm(specification,specification.name)
+ end
+ else
+ tfmtable = check_tfm(specification,fullname)
+ end
+ return tfmtable
+end
+
+function readers.afm(specification,method)
+ local fullname, tfmtable = specification.filename or "", nil
+ if fullname == "" then
+ local forced = specification.forced or ""
+ if forced ~= "" then
+ tfmtable = check_afm(specification,specification.name .. "." .. forced)
+ end
+ if not tfmtable then
+ method = method or define.method or "afm or tfm"
+ if method == "tfm" then
+ tfmtable = check_tfm(specification,specification.name)
+ elseif method == "afm" then
+ tfmtable = check_afm(specification,specification.name)
+ elseif method == "tfm or afm" then
+ tfmtable = check_tfm(specification,specification.name) or check_afm(specification,specification.name)
+ else -- method == "afm or tfm" or method == "" then
+ tfmtable = check_afm(specification,specification.name) or check_tfm(specification,specification.name)
+ end
+ end
+ else
+ tfmtable = check_afm(specification,fullname)
+ end
+ return tfmtable
+end
+
+local function check_otf(specification,suffix,what)
+ local fullname, tfmtable = resolvers.findbinfile(specification.name,suffix) or "", nil
+ if fullname == "" then
+ local fb = fonts.names.old_to_new[specification.name]
+ if fb then
+ fullname = resolvers.findbinfile(fb,suffix) or ""
+ end
+ end
+ if fullname == "" then
+ local fb = fonts.names.new_to_old[specification.name]
+ if fb then
+ fullname = resolvers.findbinfile(fb,suffix) or ""
+ end
+ end
+ if fullname ~= "" then
+ specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then
+ tfmtable = tfm.read_from_open_type(specification) -- we need to do it for all matches / todo
+ end
+ return tfmtable
+end
+
+function readers.opentype(specification,suffix,what)
+ local forced = specification.forced or ""
+ if forced == "otf" then
+ return check_otf(specification,forced,"opentype")
+ elseif forced == "ttf" then
+ return check_otf(specification,forced,"truetype")
+ elseif forced == "ttf" then
+ return check_otf(specification,forced,"truetype")
+ else
+ return check_otf(specification,suffix,what)
+ end
+end
+
+function readers.otf(specification) return readers.opentype(specification,"otf","opentype") end
+function readers.ttf(specification) return readers.opentype(specification,"ttf","truetype") end
+function readers.ttc(specification) return readers.opentype(specification,"ttf","truetype") end -- !!
+
+--[[ldx--
+<p>We need to check for default features. For this we provide
+a helper function.</p>
+--ldx]]--
+
+function define.check(features,defaults) -- nb adapts features !
+ local done = false
+ if table.is_empty(features) then
+ features, done = table.fastcopy(defaults), true
+ else
+ for k,v in next, defaults do
+ if features[k] == nil then
+ features[k], done = v, true
+ end
+ end
+ end
+ return features, done -- done signals a change
+end
+
+--[[ldx--
+<p>So far the specifyers. Now comes the real definer. Here we cache
+based on id's. Here we also intercept the virtual font handler. Since
+it evolved stepwise I may rewrite this bit (combine code).</p>
+
+In the previously defined reader (the one resulting in a <l n='tfm'/>
+table) we cached the (scaled) instances. Here we cache them again, but
+this time based on id. We could combine this in one cache but this does
+not gain much. By the way, passing id's back to in the callback was
+introduced later in the development.</p>
+--ldx]]--
+
+define.last = nil
+
+function define.register(fontdata,id)
+ if fontdata and id then
+ local hash = fontdata.hash
+ if not tfm.internalized[hash] then
+ if trace_defining then
+ logs.report("define font","loading at 2 id %s, hash: %s",id or "?",hash or "?")
+ end
+ fonts.ids[id] = fontdata
+ tfm.internalized[hash] = id
+ end
+ end
+end
+
+function define.registered(hash)
+ local id = tfm.internalized[hash]
+ return id, id and fonts.ids[id]
+end
+
+local cache_them = false
+
+function tfm.make(specification)
+ -- currently fonts are scaled while constructing the font, so we
+ -- have to do scaling of commands in the vf at that point using
+ -- e.g. "local scale = g.factor or 1" after all, we need to work
+ -- with copies anyway and scaling needs to be done at some point;
+ -- however, when virtual tricks are used as feature (makes more
+ -- sense) we scale the commands in fonts.tfm.scale (and set the
+ -- factor there)
+ local fvm = define.methods[specification.features.vtf.preset]
+ if fvm then
+ return fvm(specification)
+ else
+ return nil
+ end
+end
+
+function define.read(specification,size,id) -- id can be optional, name can already be table
+ statistics.starttiming(fonts)
+ if type(specification) == "string" then
+ specification = define.analyze(specification,size)
+ end
+ local method = specification.method
+ if method and define.specify[method] then
+ specification = define.specify[method](specification)
+ end
+ specification = define.resolve(specification)
+ local hash = tfm.hash_instance(specification)
+ if cache_them then
+ local fontdata = containers.read(fonts.cache(),hash) -- for tracing purposes
+ end
+ local fontdata = define.registered(hash) -- id
+ if not fontdata then
+ if specification.features.vtf and specification.features.vtf.preset then
+ fontdata = tfm.make(specification)
+ else
+ fontdata = tfm.read(specification)
+ if fontdata then
+ tfm.check_virtual_id(fontdata)
+ end
+ end
+ if cache_them then
+ fontdata = containers.write(fonts.cache(),hash,fontdata) -- for tracing purposes
+ end
+ if fontdata then
+ fontdata.hash = hash
+ fontdata.cache = "no"
+ if id then
+ define.register(fontdata,id)
+ end
+ end
+ end
+ define.last = fontdata or id -- todo ! ! ! ! !
+ if not fontdata then
+ logs.report("define font", "unknown font %s, loading aborted",specification.name)
+ elseif trace_defining and type(fontdata) == "table" then
+ logs.report("define font","using %s font with id %s, n:%s s:%s b:%s e:%s p:%s f:%s",
+ fontdata.type or "unknown",
+ id or "?",
+ fontdata.name or "?",
+ fontdata.size or "default",
+ fontdata.encodingbytes or "?",
+ fontdata.encodingname or "unicode",
+ fontdata.fullname or "?",
+ file.basename(fontdata.filename or "?"))
+ end
+ statistics.stoptiming(fonts)
+ return fontdata
+end
+
+function vf.find(name)
+ name = file.removesuffix(file.basename(name))
+ if tfm.resolve_vf then
+ local format = fonts.logger.format(name)
+ if format == 'tfm' or format == 'ofm' then
+ if trace_defining then
+ logs.report("define font","locating vf for %s",name)
+ end
+ return resolvers.findbinfile(name,"ovf")
+ else
+ if trace_defining then
+ logs.report("define font","vf for %s is already taken care of",name)
+ end
+ return nil -- ""
+ end
+ else
+ if trace_defining then
+ logs.report("define font","locating vf for %s",name)
+ end
+ return resolvers.findbinfile(name,"ovf")
+ end
+end
+
+--[[ldx--
+<p>We overload both the <l n='tfm'/> and <l n='vf'/> readers.</p>
+--ldx]]--
+
+callback.register('define_font' , define.read)
+callback.register('find_vf_file', vf.find ) -- not that relevant any more
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-xtx'] = {
+ version = 1.001,
+ comment = "companion to font-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local texsprint, count = tex.sprint, tex.count
+local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower
+local tostring, next = tostring, next
+
+local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+
+--[[ldx--
+<p>Choosing a font by name and specififying its size is only part of the
+game. In order to prevent complex commands, <l n='xetex'/> introduced
+a method to pass feature information as part of the font name. At the
+risk of introducing nasty parsing and compatinility problems, this
+syntax was expanded over time.</p>
+
+<p>For the sake of users who have defined fonts using that syntax, we
+will support it, but we will provide additional methods as well.
+Normally users will not use this direct way, but use a more abstract
+interface.</p>
+
+<p>The next one is the official one. However, in the plain
+variant we need to support the crappy [] specification as
+well and that does not work too well with the general design
+of the specifier.</p>
+--ldx]]--
+
+--~ function fonts.define.specify.colonized(specification) -- xetex mode
+--~ local list = { }
+--~ if specification.detail and specification.detail ~= "" then
+--~ for v in gmatch(specification.detail,"%s*([^;]+)%s*") do
+--~ local a, b = match(v,"^(%S*)%s*=%s*(%S*)$")
+--~ if a and b then
+--~ list[a] = b:is_boolean()
+--~ if type(list[a]) == "nil" then
+--~ list[a] = b
+--~ end
+--~ else
+--~ local a, b = match(v,"^([%+%-]?)%s*(%S+)$")
+--~ if a and b then
+--~ list[b] = a ~= "-"
+--~ end
+--~ end
+--~ end
+--~ end
+--~ specification.features.normal = list
+--~ return specification
+--~ end
+
+--~ check("oeps/BI:+a;-b;c=d")
+--~ check("[oeps]/BI:+a;-b;c=d")
+--~ check("file:oeps/BI:+a;-b;c=d")
+--~ check("name:oeps/BI:+a;-b;c=d")
+
+local list = { }
+
+fonts.define.specify.colonized_default_lookup = "file"
+
+local function issome () list.lookup = fonts.define.specify.colonized_default_lookup end
+local function isfile () list.lookup = 'file' end
+local function isname () list.lookup = 'name' end
+local function thename(s) list.name = s end
+local function issub (v) list.sub = v end
+local function iscrap (s) list.crap = string.lower(s) end
+local function istrue (s) list[s] = 'yes' end
+local function isfalse(s) list[s] = 'no' end
+local function iskey (k,v) list[k] = v end
+
+local spaces = lpeg.P(" ")^0
+local namespec = (1-lpeg.S("/: ("))^0
+local crapspec = spaces * lpeg.P("/") * (((1-lpeg.P(":"))^0)/iscrap) * spaces
+local filename = (lpeg.P("file:")/isfile * (namespec/thename)) + (lpeg.P("[") * lpeg.P(true)/isname * (((1-lpeg.P("]"))^0)/thename) * lpeg.P("]"))
+local fontname = (lpeg.P("name:")/isname * (namespec/thename)) + lpeg.P(true)/issome * (namespec/thename)
+local sometext = (lpeg.R("az") + lpeg.R("AZ") + lpeg.R("09"))^1
+local truevalue = lpeg.P("+") * spaces * (sometext/istrue)
+local falsevalue = lpeg.P("-") * spaces * (sometext/isfalse)
+local keyvalue = (lpeg.C(sometext) * spaces * lpeg.P("=") * spaces * lpeg.C(sometext))/iskey
+local somevalue = sometext/istrue
+local subvalue = lpeg.P("(") * (lpeg.C(lpeg.P(1-lpeg.S("()"))^1)/issub) * lpeg.P(")") -- for Kim
+local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces
+local options = lpeg.P(":") * spaces * (lpeg.P(";")^0 * option)^0
+local pattern = (filename + fontname) * subvalue^0 * crapspec^0 * options^0
+
+function fonts.define.specify.colonized(specification) -- xetex mode
+ list = { }
+ pattern:match(specification.specification)
+ for k, v in next, list do
+ list[k] = v:is_boolean()
+ if type(list[a]) == "nil" then
+ list[k] = v
+ end
+ end
+ list.crap = nil -- style not supported, maybe some day
+ if list.name then
+ specification.name = list.name
+ list.name = nil
+ end
+ if list.lookup then
+ specification.lookup = list.lookup
+ list.lookup = nil
+ end
+ if list.sub then
+ specification.sub = list.sub
+ list.sub = nil
+ end
+ specification.features.normal = list
+ return specification
+end
+
+fonts.define.register_split(":", fonts.define.specify.colonized)
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
+if not modules then modules = { } end modules ['font-dum'] = {
+ version = 1.001,
+ comment = "companion to luatex-*.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+fonts = fonts or { }
+
+-- general
+
+fonts.otf.pack = false
+fonts.tfm.resolve_vf = false -- no sure about this
+
+-- readers
+
+fonts.tfm.readers = fonts.tfm.readers or { }
+fonts.tfm.readers.sequence = { 'otf', 'ttf', 'tfm' }
+fonts.tfm.readers.afm = nil
+
+-- define
+
+fonts.define = fonts.define or { }
+
+--~ fonts.define.method = "tfm"
+
+fonts.define.specify.colonized_default_lookup = "name"
+
+function fonts.define.get_specification(str)
+ return "", str, "", ":", str
+end
+
+-- logger
+
+fonts.logger = fonts.logger or { }
+
+function fonts.logger.save()
+end
+
+-- names
+
+fonts.names = fonts.names or { }
+
+fonts.names.basename = "luatex-fonts-names.lua"
+fonts.names.new_to_old = { }
+fonts.names.old_to_new = { }
+
+local data, loaded = nil, false
+
+function fonts.names.resolve(name,sub)
+ if not loaded then
+ local basename = fonts.names.basename
+ if basename and basename ~= "" then
+ for _, format in ipairs { "lua", "tex", "other text files" } do
+ local foundname = resolvers.find_file(basename,format) or ""
+ if foundname ~= "" then
+ data = dofile(foundname)
+ if data then
+ local d = { }
+ for k, v in pairs(data.mapping) do
+ local t = v[1]
+ if t == "ttf" or t == "otf" or t == "ttc" then
+ d[k] = v
+ end
+ end
+ data.mapping = d
+ end
+ break
+ end
+ end
+ end
+ loaded = true
+ end
+ if type(data) == "table" and data.version == 1.08 then
+ local condensed = string.gsub(name,"[^%a%d]","")
+ local found = data.mapping and data.mapping[condensed]
+ if found then
+ local filename, is_sub = found[3], found[4]
+ if is_sub then is_sub = found[2] end
+ return filename, is_sub
+ else
+ return name, false -- fallback to filename
+ end
+ end
+end
+
+-- For the moment we put this (adapted) pseudo feature here.
+
+table.insert(fonts.triggers,"itlc")
+
+local function itlc(tfmdata,value)
+ if value then
+ -- the magic 40 and it formula come from Dohyun Kim
+ local metadata = tfmdata.shared.otfdata.metadata
+ if metadata then
+ local italicangle = metadata.italicangle
+ if italicangle and italicangle ~= 0 then
+ local uwidth = (metadata.uwidth or 40)/2
+ for unicode, d in next, tfmdata.descriptions do
+ local it = d.boundingbox[3] - d.width + uwidth
+ if it ~= 0 then
+ d.italic = it
+ end
+ end
+ tfmdata.has_italic = true
+ end
+ end
+ end
+end
+
+fonts.initializers.base.otf.itlc = itlc
+fonts.initializers.node.otf.itlc = itlc
+
+end -- closure
diff --git a/tex/generic/context/luatex-fonts.lua b/tex/generic/context/luatex-fonts.lua
new file mode 100644
index 000000000..be565c7b3
--- /dev/null
+++ b/tex/generic/context/luatex-fonts.lua
@@ -0,0 +1,139 @@
+if not modules then modules = { } end modules ['luatex-fonts'] = {
+ version = 1.001,
+ comment = "companion to luatex-fonts.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- We keep track of load time by storing the current time. That
+-- way we cannot be accused of slowing down luading too much.
+
+local starttime = os.gettimeofday()
+
+-- As we don't use the ConTeXt file searching, we need to
+-- initialize the kpse library. As the progname can be anything
+-- we will temporary switch to the ConTeXt namespace if needed.
+-- Just adding the context paths to the path specification is
+-- somewhat faster
+
+-- kpse.set_program_name("luatex")
+
+local ctxkpse = nil
+local verbose = true
+
+local function loadmodule(name,continue)
+ local foundname = kpse.find_file(name,"tex") or ""
+ if not foundname then
+ if not ctxkpse then
+ ctxkpse = kpse.new("luatex","context")
+ end
+ foundname = ctxkpse:find_file(name,"tex") or ""
+ end
+ if foundname == "" then
+ if not continue then
+ texio.write_nl(string.format(" <luatex-fonts: unable to locate %s>",name))
+ os.exit()
+ end
+ else
+ if verbose then
+ texio.write(string.format(" <%s>",string.match(name,"([a-z%-]-%.[a-z]-)$"))) -- no file.basename yet
+ end
+ dofile(foundname)
+ end
+end
+
+loadmodule('luatex-fonts-merged.lua',true) -- you might comment this line
+
+if fonts then
+
+ -- We're using the merged version. That one could be outdated so
+ -- remove it from your system when you want to use the files from
+ -- from the ConTeXt tree, or keep your copy of the merged version
+ -- up to date.
+
+ texio.write_nl("log",[[
+
+I am using the merged version of 'luatex-fonts.lua' here. If
+you run into problems or experience unexpected behaviour, and
+if you have ConTeXt installed you can try to delete the file
+'luatex-font-merged.lua' as I might then use the possibly
+updated libraries. The merged version is not supported as it
+is a frozen instance.
+
+ ]])
+
+else
+
+ -- The following helpers are a bit overkill but I don't want to
+ -- mess up ConTeXt code for the sake of general generality. Around
+ -- version 1.0 there will be an official api defined.
+
+ loadmodule('l-string.lua')
+ loadmodule('l-lpeg.lua')
+ loadmodule('l-boolean.lua')
+ loadmodule('l-math.lua')
+ loadmodule('l-table.lua')
+ loadmodule('l-file.lua')
+ loadmodule('l-io.lua')
+
+ -- The following modules contain code that is either not used
+ -- at all outside ConTeXt or will fail when enabled due to
+ -- lack of other modules.
+
+ -- First we load a few helper modules. This is about the miminum
+ -- needed to let the font modules do theuir work.
+
+ loadmodule('luat-dum.lua') -- not used in context at all
+ loadmodule('data-con.lua') -- maybe some day we don't need this one
+
+ -- We do need some basic node support although the following
+ -- modules contain a little bit of code that is not used. It's
+ -- not worth weeding.
+
+ loadmodule('node-ini.lua')
+ loadmodule('node-res.lua') -- will be stripped
+ loadmodule('node-inj.lua') -- will be replaced (luatex > .50)
+ loadmodule('node-fnt.lua')
+ loadmodule('node-dum.lua')
+
+ -- Now come the font modules that deal with traditional TeX fonts
+ -- as well as open type fonts. We don't load the afm related code
+ -- from font-enc.lua and font-afm.lua as only ConTeXt deals with
+ -- it.
+ --
+ -- The font database file (if used at all) must be put someplace
+ -- visible for kpse and is not shared with ConTeXt. The mtx-fonts
+ -- script can be used to genate this file (using the --names
+ -- option).
+
+ loadmodule('font-ini.lua')
+ loadmodule('font-tfm.lua') -- will be split (we may need font-log)
+ loadmodule('font-cid.lua')
+ loadmodule('font-ott.lua') -- might be split
+ loadmodule('font-otf.lua')
+ loadmodule('font-otd.lua')
+ loadmodule('font-oti.lua')
+ loadmodule('font-otb.lua')
+ loadmodule('font-otn.lua')
+ loadmodule('font-ota.lua') -- might be split
+ loadmodule('font-otc.lua')
+ loadmodule('font-def.lua')
+ loadmodule('font-xtx.lua')
+ loadmodule('font-dum.lua')
+
+end
+
+-- In order to deal with the fonts we need to initialize some
+-- callbacks. One can overload them later on if needed.
+
+callback.register('ligaturing', nodes.simple_font_dummy)
+callback.register('kerning', nodes.simple_font_dummy)
+callback.register('pre_linebreak_filter', nodes.simple_font_handler)
+callback.register('hpack_filter', nodes.simple_font_handler)
+callback.register('define_font' , fonts.define.read)
+callback.register('find_vf_file', nil) -- reset to normal
+
+-- We're done.
+
+texio.write(string.format(" <luatex-fonts.lua loaded in %0.3f seconds>", os.gettimeofday()-starttime))
diff --git a/tex/generic/context/luatex-fonts.tex b/tex/generic/context/luatex-fonts.tex
new file mode 100644
index 000000000..644d168f5
--- /dev/null
+++ b/tex/generic/context/luatex-fonts.tex
@@ -0,0 +1,139 @@
+%D \module
+%D [ file=luatex-fonts,
+%D version=2009.12.01,
+%D title=\LUATEX\ Support Macros,
+%D subtitle=Generic \OPENTYPE\ Font Handler,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=public domain]
+
+%D \subject{Welcome}
+%D
+%D This file is one of a set of basic functionality enhancements
+%D for \LUATEX\ derived from the \CONTEXT\ \MKIV\ code base. Please
+%D don't polute the \type {luatex-*} namespace with code not coming
+%D from the \CONTEXT\ development team as we may add more files.
+%D
+%D As this is an experimental setup, it might not always work out as
+%D expected. Around \LUATEX\ version 0.50 we expect the code to be
+%D more or less okay.
+%D
+%D This file implements a basic font system for a bare \LUATEX\
+%D system. By default \LUATEX\ only knows about the classic \TFM\
+%D fonts but it can read other font formats and pass them to \LUA.
+%D With some glue code one can then construct a suitable \TFM\
+%D representation that \LUATEX\ can work with. For more advanced font
+%D support a bit more code is needed that needs to be hooked
+%D into the callback mechanism.
+%D
+%D This file is currently rather simple: it just loads the \LUA\ file
+%D with the same name. An example of a \type {luatex.tex} file that is
+%D just plain \TEX:
+%D
+%D \starttyping
+%D \catcode`\{=1 % left brace is begin-group character
+%D \catcode`\}=2 % right brace is end-group character
+%D
+%D \input plain
+%D
+%D \everyjob\expandafter{\the\everyjob\input luatex-fonts\relax}
+%D
+%D \dump
+%D \stoptyping
+%D
+%D We could load the \LUA\ file in \type {\everyjob} but maybe some
+%D day we need more here.
+%D
+%D When defining a font you can use two prefixes. A \type {file:}
+%D prefix forced a file search, while a \type {name:} prefix will
+%D result in consulting the names database. Such a database can be
+%D generated with:
+%D
+%D \starttyping
+%D mtxrun --usekpse --script fonts --names
+%D \stoptyping
+%D
+%D This will generate a file \type {luatex-fonts-names.lua} that has
+%D to be placed in a location where it can be found by \KPSE. Beware:
+%D the \type {--kpseonly} flag is only used outside \CONTEXT\ and
+%D provides very limited functionality, just enough for this task.
+%D
+%D The code loaded here does not come out of thin air, but is mostly
+%D shared with \CONTEXT, however, in that macropackage we go beyond
+%D what is provided here. When you use the code packaged here you
+%D need to keep a few things in mind:
+%D
+%D \startitemize
+%D
+%D \item This subsystem will be extended, improved etc. in about the
+%D same pace as \CONTEXT\ \MKIV. However, because \CONTEXT\ provides a
+%D rather high level of integration not all features will be supported
+%D in the same quality. Use \CONTEXT\ if you want more goodies.
+%D
+%D \item There is no official \API\ yet, which means that using
+%D functions implemented here is at your own risk, in the sense that
+%D names and namespaces might change. There will be a minimal \API\
+%D defined once \LUATEX\ version 1.0 is out. Instead of patching the
+%D files it's better to overload functions if needed.
+%D
+%D \item The modules are not stripped too much, which makes it
+%D possible to benefit from improvements in the code that take place
+%D in the perspective of \CONTEXT\ development. They might be split a
+%D bit more in due time so the baseline might become smaller.
+%D
+%D \item The code is maintained and tested by the \CONTEXT\
+%D development team. As such it might be better suited for this macro
+%D package and integration in other systems might demand some
+%D additional wrapping. Problems can be reported to the team but as we
+%D use \CONTEXT\ \MKIV\ as baseline, you'd better check if the problem
+%D is a general \CONTEXT\ problem too.
+%D
+%D \item The more high level support for features that is provided in
+%D \CONTEXT\ is not part of the code loaded here as it makes no sense
+%D elsewhere. Some experimental features are not part of this code
+%D either but some might show up later.
+%D
+%D \item Math font support will be added but only in its basic form
+%D once that the Latin Modern and \TEX\ Gyre math fonts are
+%D available.
+%D
+%D \item At this moment the more nifty speed-ups are not enabled
+%D because they work in tandem with the alternative file handling
+%D that \CONTEXT\ uses. Maybe around \LUATEX\ 1.0 we will bring some
+%D speedup into this code too (if it pays off at all).
+%D
+%D \item The code defines a few global tables. If this code is used
+%D in a larger perspective then you can best make sure that no
+%D conflicts occur. The \CONTEXT\ package expects users to work in
+%D their own namespace (\type {userdata}, \type {thirddata}, \type
+%D {moduledata} or \type {document}. The team takes all freedom to
+%D use any table at the global level but will not use tables that are
+%D named after macro packages. Later the \CONTEXT\ might operate in
+%D a more controlled namespace but it has a low priority.
+%D
+%D \item There is some tracing code present but this is not enabled
+%D and not supported outside \CONTEXT\ either as it integrates quite
+%D tightly into \CONTEXT. In case of problems you can use \CONTEXT\
+%D for tracking down problems.
+%D
+%D \item Patching the code in distributions is dangerous as it might
+%D fix your problem but introduce new ones for \CONTEXT. So, best keep
+%D the original code as it is.
+%D
+%D \item Attributes are (automatically) taken from the range 127-255 so
+%D you'd best not use these yourself.
+%D
+%D \stopitemize
+%D
+%D If this all sounds a bit tricky, keep in mind that it makes no sense
+%D for us to maintain multiple code bases and we happen to use \CONTEXT.
+%D
+%D For more details about how the font subsystem works we refer to
+%D publications in \TEX\ related journals, the \CONTEXT\ documentation,
+%D and the \CONTEXT\ wiki.
+
+\directlua {
+ dofile(kpse.find_file("luatex-fonts.lua","tex"))
+}
+
+\endinput
diff --git a/tex/generic/context/luatex-mplib.lua b/tex/generic/context/luatex-mplib.lua
new file mode 100644
index 000000000..6f9bdc7ef
--- /dev/null
+++ b/tex/generic/context/luatex-mplib.lua
@@ -0,0 +1,469 @@
+if not modules then modules = { } end modules ['supp-mpl'] = {
+ version = 1.001,
+ comment = "companion to supp-mpl.tex",
+ author = "Hans Hagen & Taco Hoekwater",
+ copyright = "ConTeXt Development Team",
+ license = "public domain",
+}
+
+--[[ldx--
+<p>This module is a stripped down version of libraries that are used
+by <l n='context'/>. It can be used in other macro packages and/or
+serve as an example. Embedding in a macro package is upto others and
+normally boils down to inputting <t>supp-mpl.tex</t>.</p>
+--ldx]]--
+
+if metapost and metapost.version then
+
+ --[[ldx--
+ <p>Let's silently quit and make sure that no one loads it
+ manually in <l n='context'/>.</p>
+ --ldx]]--
+
+else
+
+ local format, concat, abs = string.format, table.concat, math.abs
+
+ local mplib = require ('mplib')
+ local kpse = require ('kpse')
+
+ --[[ldx--
+ <p>We create a namespace and some variables to it. If a namespace is
+ already defined it wil not be initialized. This permits hooking
+ in code beforehand.</p>
+
+ <p>We don't make a format automatically. After all, distributions
+ might have their own preferences and normally a format (mem) file will
+ have some special place in the <l n='tex'/> tree. Also, there can already
+ be format files, different memort settings and other nasty pitfalls that
+ we don't want to interfere with. If you want, you can define a function
+ <t>metapost.make(name,mem_name) that does the job.</t></p>
+ --ldx]]--
+
+ metapost = metapost or { }
+ metapost.version = 1.00
+ metapost.showlog = metapost.showlog or false
+ metapost.lastlog = ""
+
+ --[[ldx--
+ <p>A few helpers, taken from <t>l-file.lua</t>.</p>
+ --ldx]]--
+
+ local file = file or { }
+
+ function file.replacesuffix(filename, suffix)
+ return (string.gsub(filename,"%.[%a%d]+$","")) .. "." .. suffix
+ end
+
+ function file.stripsuffix(filename)
+ return (string.gsub(filename,"%.[%a%d]+$",""))
+ end
+
+ --[[ldx--
+ <p>We use the <l n='kpse'/> library unless a finder is already
+ defined.</p>
+ --ldx]]--
+
+ local mpkpse = kpse.new("luatex","mpost")
+
+ metapost.finder = metapost.finder or function(name, mode, ftype)
+ if mode == "w" then
+ return name
+ else
+ return mpkpse:find_file(name,ftype)
+ end
+ end
+
+ --[[ldx--
+ <p>You can use your own reported if needed, as long as it handles multiple
+ arguments and formatted strings.</p>
+ --ldx]]--
+
+ metapost.report = metapost.report or function(...)
+ texio.write(format("<mplib: %s>",format(...)))
+ end
+
+ --[[ldx--
+ <p>The rest of this module is not documented. More info can be found in the
+ <l n='luatex'/> manual, articles in user group journals and the files that
+ ship with <l n='context'/>.</p>
+ --ldx]]--
+
+ function metapost.resetlastlog()
+ metapost.lastlog = ""
+ end
+
+ metapost.make = metapost.make or function(name,mem_name,dump)
+ if false then
+ metapost.report("no format %s made for %s",mem_name,name)
+ return false
+ else
+ local t = os.clock()
+ local mpx = mplib.new {
+ ini_version = true,
+ find_file = metapost.finder,
+ job_name = file.stripsuffix(name)
+ }
+ mpx:execute(string.format("input %s ;",name))
+ if dump then
+ mpx:execute("dump ;")
+ metapost.report("format %s made and dumped for %s in %0.3f seconds",mem_name,name,os.clock()-t)
+ else
+ metapost.report("%s read in %0.3f seconds",name,os.clock()-t)
+ end
+ return mpx
+ end
+ end
+
+ function metapost.load(name)
+ local mem_name = file.replacesuffix(name,"mem")
+ local mpx = mplib.new {
+ ini_version = false,
+ mem_name = mem_name,
+ find_file = metapost.finder
+ }
+ if not mpx and type(metapost.make) == "function" then
+ -- when i have time i'll locate the format and dump
+ mpx = metapost.make(name,mem_name)
+ end
+ if mpx then
+ metapost.report("using format %s",mem_name,false)
+ return mpx, nil
+ else
+ return nil, { status = 99, error = "out of memory or invalid format" }
+ end
+ end
+
+ function metapost.unload(mpx)
+ if mpx then
+ mpx:finish()
+ end
+ end
+
+ function metapost.reporterror(result)
+ if not result then
+ metapost.report("mp error: no result object returned")
+ elseif result.status > 0 then
+ local t, e, l = result.term, result.error, result.log
+ if t then
+ metapost.report("mp terminal: %s",t)
+ end
+ if e then
+ metapost.report("mp error: %s", e)
+ end
+ if not t and not e and l then
+ metapost.lastlog = metapost.lastlog .. "\n " .. l
+ metapost.report("mp log: %s",l)
+ else
+ metapost.report("mp error: unknown, no error, terminal or log messages")
+ end
+ else
+ return false
+ end
+ return true
+ end
+
+ function metapost.process(mpx, data)
+ local converted, result = false, {}
+ mpx = metapost.load(mpx)
+ if mpx and data then
+ local result = mpx:execute(data)
+ if not result then
+ metapost.report("mp error: no result object returned")
+ elseif result.status > 0 then
+ metapost.report("mp error: %s",(result.term or "no-term") .. "\n" .. (result.error or "no-error"))
+ elseif metapost.showlog then
+ metapost.lastlog = metapost.lastlog .. "\n" .. result.term
+ metapost.report("mp info: %s",result.term or "no-term")
+ elseif result.fig then
+ converted = metapost.convert(result)
+ else
+ metapost.report("mp error: unknown error, maybe no beginfig/endfig")
+ end
+ else
+ metapost.report("mp error: mem file not found")
+ end
+ return converted, result
+ end
+
+ local function getobjects(result,figure,f)
+ return figure:objects()
+ end
+
+ function metapost.convert(result, flusher)
+ metapost.flush(result, flusher)
+ return true -- done
+ end
+
+ --[[ldx--
+ <p>We removed some message and tracing code. We might even remove the flusher</p>
+ --ldx]]--
+
+ local function pdf_startfigure(n,llx,lly,urx,ury)
+ tex.sprint(format("\\startMPLIBtoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury))
+ end
+
+ local function pdf_stopfigure()
+ tex.sprint("\\stopMPLIBtoPDF")
+ end
+
+ function pdf_literalcode(fmt,...) -- table
+ tex.sprint(format("\\MPLIBtoPDF{%s}",format(fmt,...)))
+ end
+
+ function pdf_textfigure(font,size,text,width,height,depth)
+ text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost
+ tex.sprint(format("\\MPLIBtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-( 7200/ 7227)/65536*depth))
+ end
+
+ local bend_tolerance = 131/65536
+
+ local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
+
+ local function pen_characteristics(object)
+ if mplib.pen_info then
+ local t = mplib.pen_info(object)
+ rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty
+ divider = sx*sy - rx*ry
+ return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width
+ else
+ rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1
+ return false, 1
+ end
+ end
+
+ local function concat(px, py) -- no tx, ty here
+ return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider
+ end
+
+ local function curved(ith,pth)
+ local d = pth.left_x - ith.right_x
+ if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then
+ d = pth.left_y - ith.right_y
+ if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then
+ return false
+ end
+ end
+ return true
+ end
+
+ local function flushnormalpath(path,open)
+ local pth, ith
+ for i=1,#path do
+ pth = path[i]
+ if not ith then
+ pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord)
+ elseif curved(ith,pth) then
+ pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
+ else
+ pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord)
+ end
+ ith = pth
+ end
+ if not open then
+ local one = path[1]
+ if curved(pth,one) then
+ pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
+ else
+ pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
+ end
+ elseif #path == 1 then
+ -- special case .. draw point
+ local one = path[1]
+ pdf_literalcode("%f %f l",one.x_coord,one.y_coord)
+ end
+ return t
+ end
+
+ local function flushconcatpath(path,open)
+ pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty)
+ local pth, ith
+ for i=1,#path do
+ pth = path[i]
+ if not ith then
+ pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord))
+ elseif curved(ith,pth) then
+ local a, b = concat(ith.right_x,ith.right_y)
+ local c, d = concat(pth.left_x,pth.left_y)
+ pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord))
+ else
+ pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord))
+ end
+ ith = pth
+ end
+ if not open then
+ local one = path[1]
+ if curved(pth,one) then
+ local a, b = concat(pth.right_x,pth.right_y)
+ local c, d = concat(one.left_x,one.left_y)
+ pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord))
+ else
+ pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
+ end
+ elseif #path == 1 then
+ -- special case .. draw point
+ local one = path[1]
+ pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord))
+ end
+ return t
+ end
+
+ --[[ldx--
+ <p>Support for specials has been removed.</p>
+ --ldx]]--
+
+ function metapost.flush(result,flusher)
+ if result then
+ local figures = result.fig
+ if figures then
+ for f=1, #figures do
+ metapost.report("flushing figure %s",f)
+ local figure = figures[f]
+ local objects = getobjects(result,figure,f)
+ local fignum = tonumber((figure:filename()):match("([%d]+)$") or figure:charcode() or 0)
+ local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
+ local bbox = figure:boundingbox()
+ local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack
+ if urx < llx then
+ -- invalid
+ pdf_startfigure(fignum,0,0,0,0)
+ pdf_stopfigure()
+ else
+ pdf_startfigure(fignum,llx,lly,urx,ury)
+ pdf_literalcode("q")
+ if objects then
+ for o=1,#objects do
+ local object = objects[o]
+ local objecttype = object.type
+ if objecttype == "start_bounds" or objecttype == "stop_bounds" then
+ -- skip
+ elseif objecttype == "start_clip" then
+ pdf_literalcode("q")
+ flushnormalpath(object.path,t,false)
+ pdf_literalcode("W n")
+ elseif objecttype == "stop_clip" then
+ pdf_literalcode("Q")
+ miterlimit, linecap, linejoin, dashed = -1, -1, -1, false
+ elseif objecttype == "special" then
+ -- not supported
+ elseif objecttype == "text" then
+ local ot = object.transform -- 3,4,5,6,1,2
+ pdf_literalcode("q %f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2])
+ pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
+ pdf_literalcode("Q")
+ else
+ local cs = object.color
+ if cs and #cs > 0 then
+ pdf_literalcode(metapost.colorconverter(cs))
+ end
+ local ml = object.miterlimit
+ if ml and ml ~= miterlimit then
+ miterlimit = ml
+ pdf_literalcode("%f M",ml)
+ end
+ local lj = object.linejoin
+ if lj and lj ~= linejoin then
+ linejoin = lj
+ pdf_literalcode("%i j",lj)
+ end
+ local lc = object.linecap
+ if lc and lc ~= linecap then
+ linecap = lc
+ pdf_literalcode("%i J",lc)
+ end
+ local dl = object.dash
+ if dl then
+ local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset)
+ if d ~= dashed then
+ dashed = d
+ pdf_literalcode(dashed)
+ end
+ elseif dashed then
+ pdf_literalcode("[] 0 d")
+ dashed = false
+ end
+ local path = object.path
+ local transformed, penwidth = false, 1
+ local open = path and path[1].left_type and path[#path].right_type
+ local pen = object.pen
+ if pen then
+ if pen.type == 'elliptical' then
+ transformed, penwidth = pen_characteristics(object) -- boolean, value
+ pdf_literalcode("%f w",penwidth)
+ if objecttype == 'fill' then
+ objecttype = 'both'
+ end
+ else -- calculated by mplib itself
+ objecttype = 'fill'
+ end
+ end
+ if transformed then
+ pdf_literalcode("q")
+ end
+ if path then
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ if objecttype == "fill" then
+ pdf_literalcode("h f")
+ elseif objecttype == "outline" then
+ pdf_literalcode((open and "S") or "h S")
+ elseif objecttype == "both" then
+ pdf_literalcode("h B")
+ end
+ end
+ if transformed then
+ pdf_literalcode("Q")
+ end
+ local path = object.htap
+ if path then
+ if transformed then
+ pdf_literalcode("q")
+ end
+ if transformed then
+ flushconcatpath(path,open)
+ else
+ flushnormalpath(path,open)
+ end
+ if objecttype == "fill" then
+ pdf_literalcode("h f")
+ elseif objecttype == "outline" then
+ pdf_literalcode((open and "S") or "h S")
+ elseif objecttype == "both" then
+ pdf_literalcode("h B")
+ end
+ if transformed then
+ pdf_literalcode("Q")
+ end
+ end
+ if cr then
+ pdf_literalcode(cr)
+ end
+ end
+ end
+ end
+ pdf_literalcode("Q")
+ pdf_stopfigure()
+ end
+ end
+ end
+ end
+ end
+
+ function metapost.colorconverter(cr)
+ local n = #cr
+ if n == 4 then
+ local c, m, y, k = cr[1], cr[2], cr[3], cr[4]
+ return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G"
+ elseif n == 3 then
+ local r, g, b = cr[1], cr[2], cr[3]
+ return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G"
+ else
+ local s = cr[1]
+ return format("%.3f g %.3f G",s,s), "0 g 0 G"
+ end
+ end
+
+end
diff --git a/tex/generic/context/luatex-mplib.tex b/tex/generic/context/luatex-mplib.tex
new file mode 100644
index 000000000..206518d7d
--- /dev/null
+++ b/tex/generic/context/luatex-mplib.tex
@@ -0,0 +1,118 @@
+%D \module
+%D [ file=luatex-mplib,
+%D version=2009.12.01,
+%D title=\LUATEX\ Support Macros,
+%D subtitle=\METAPOST\ to \PDF\ conversion,
+%D author=Taco Hoekwater \& Hans Hagen,
+%D date=\currentdate,
+%D copyright=public domain]
+
+%D This is the companion to the \LUA\ module \type {supp-mpl.lua}. Further
+%D embedding is up to others. A simple example of usage in plain \TEX\ is:
+%D
+%D \starttyping
+%D \pdfoutput=1
+%D
+%D \input luatex-mplib.tex
+%D
+%D \setmplibformat{plain}
+%D
+%D \mplibcode
+%D beginfig(1);
+%D draw fullcircle
+%D scaled 10cm
+%D withcolor red
+%D withpen pencircle xscaled 4mm yscaled 2mm rotated 30 ;
+%D endfig;
+%D \endmplibcode
+%D
+%D \end
+%D \stoptyping
+
+\def\setmplibformat#1{\def\mplibformat{#1}}
+
+\def\setupmplibcatcodes
+ {\catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\^=12 \catcode`\~=12
+ \catcode`\_=12 \catcode`\%=12 \catcode`\&=12 \catcode`\$=12 }
+
+\def\mplibcode
+ {\bgroup
+ \setupmplibcatcodes
+ \domplibcode}
+
+\long\def\domplibcode#1\endmplibcode
+ {\egroup
+ \directlua{metapost.process('\mplibformat',[[#1]])}}
+
+%D We default to \type {plain} \METAPOST:
+
+\def\mplibformat{plain}
+
+%D We use a dedicated scratchbox:
+
+\ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi
+
+%D Now load the needed \LUA\ code.
+
+\directlua{dofile(kpse.find_file('luatex-mplib.lua'))}
+
+%D The following code takes care of encapsulating the literals:
+
+\def\startMPLIBtoPDF#1#2#3#4%
+ {\hbox\bgroup
+ \xdef\MPllx{#1}\xdef\MPlly{#2}%
+ \xdef\MPurx{#3}\xdef\MPury{#4}%
+ \xdef\MPwidth{\the\dimexpr#3bp-#1bp\relax}%
+ \xdef\MPheight{\the\dimexpr#4bp-#2bp\relax}%
+ \parskip0pt%
+ \leftskip0pt%
+ \parindent0pt%
+ \everypar{}%
+ \setbox\mplibscratchbox\vbox\bgroup
+ \noindent}
+
+\def\stopMPLIBtoPDF
+ {\egroup
+ \setbox\mplibscratchbox\hbox
+ {\hskip-\MPllx bp%
+ \raise-\MPlly bp%
+ \box\mplibscratchbox}%
+ \setbox\mplibscratchbox\vbox to \MPheight
+ {\vfill
+ \hsize\MPwidth
+ \wd\mplibscratchbox0pt%
+ \ht\mplibscratchbox0pt%
+ \dp\mplibscratchbox0pt%
+ \box\mplibscratchbox}%
+ \wd\mplibscratchbox\MPwidth
+ \ht\mplibscratchbox\MPheight
+ \box\mplibscratchbox
+ \egroup}
+
+%D The body of picture, except for text items, is taken care of by:
+
+\ifnum\pdfoutput>0
+ \let\MPLIBtoPDF\pdfliteral
+\else
+ \def\MPLIBtoPDF#1{\special{pdf:literal direct #1}} % not ok yet
+\fi
+
+%D Text items have a special handler:
+
+\def\MPLIBtextext#1#2#3#4#5%
+ {\begingroup
+ \setbox\mplibscratchbox\hbox
+ {\font\temp=#1 at #2bp%
+ \temp
+ #3}%
+ \setbox\mplibscratchbox\hbox
+ {\hskip#4 bp%
+ \raise#5 bp%
+ \box\mplibscratchbox}%
+ \wd\mplibscratchbox0pt%
+ \ht\mplibscratchbox0pt%
+ \dp\mplibscratchbox0pt%
+ \box\mplibscratchbox
+ \endgroup}
+
+\endinput
diff --git a/tex/generic/context/luatex-plain.tex b/tex/generic/context/luatex-plain.tex
new file mode 100644
index 000000000..ae2588327
--- /dev/null
+++ b/tex/generic/context/luatex-plain.tex
@@ -0,0 +1,25 @@
+%D \module
+%D [ file=luatex-basics,
+%D version=2009.12.01,
+%D title=\LUATEX\ Support Macros,
+%D subtitle=Attribute Allocation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=public domain]
+
+\input plain
+
+\directlua {tex.enableprimitives('', tex.extraprimitives())}
+
+\pdfoutput=1
+
+\everyjob \expandafter {%
+ \the\everyjob
+ \input luatex-basics\relax
+ \input luatex-fonts\relax
+ \input luatex-mplib\relax
+}
+
+\edef\fmtversion{\fmtversion+luatex}
+
+\dump
diff --git a/tex/generic/context/luatex-test.tex b/tex/generic/context/luatex-test.tex
new file mode 100644
index 000000000..1c423ec5b
--- /dev/null
+++ b/tex/generic/context/luatex-test.tex
@@ -0,0 +1,47 @@
+%D \module
+%D [ file=luatex-test,
+%D version=2009.12.01,
+%D title=\LUATEX\ Support Macros,
+%D subtitle=Simple Test File,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=public domain]
+
+%D See \type {luatex-plain.tex} (or on my machine \type {luatex.tex}
+%D for how to make a format.
+
+\pdfoutput=1
+
+\font\testa=file:lmroman10-regular at 12pt \testa \input tufte \par
+\font\testb=file:lmroman12-regular:+liga; at 24pt \testb effe flink fietsen \par
+\font\testc=file:lmroman12-regular:mode=node;+liga; at 24pt \testc effe flink fietsen \par
+\font\testd=name:lmroman10bold at 12pt \testd a bit bold \par
+
+\font\oeps=[lmroman12-regular]:+liga at 30pt \oeps crap
+\font\oeps=[lmroman12-regular] at 40pt \oeps more crap
+
+\font\oeps=cmr10
+
+\font\testx=ptmr8t \testx abc
+
+\font\cidtest=adobesongstd-light
+
+\font\mathtest=cambria(math) {\mathtest 123}
+
+% \font\testy=file:IranNastaliq.ttf:mode=node;script=arab;language=dflt;+calt;+ccmp;+init;+isol;+medi;+fina;+liga;+rlig;+kern;+mark;+mkmk at 14pt
+% \testy این یک متن نمونه است با قلم ذر که درست آمده است.
+% \font\testz=name:linlibertineo \testz
+
+\setmplibformat{plain}
+
+\mplibcode
+ beginfig(1) ;
+ draw fullcircle
+ scaled 10cm
+ withcolor red
+ withpen pencircle xscaled 4mm yscaled 2mm rotated 30 ;
+ endfig ;
+\endmplibcode
+
+\end
+
diff --git a/tex/generic/context/ppchtex.noc b/tex/generic/context/ppchtex.noc
index 3ab92d8f3..8819de024 100644
--- a/tex/generic/context/ppchtex.noc
+++ b/tex/generic/context/ppchtex.noc
@@ -32,7 +32,7 @@
\input supp-mis.tex \let\writestatus\undefined
\input syst-gen.tex
-\input syst-fnt.tex
+\input syst-fnt.mkii
%D after which we can go on with:
@@ -174,7 +174,7 @@
%D After those definitions we actually load \PPCHTEX:
-\input ppchtex.tex
+\input ppchtex.mkii
%D We also change some setup values. Let's hope that the next
%D setups forever suits \LATEX.